diff --git a/AStar.Dev.Web.slnx b/AStar.Dev.Web.slnx index 525ed3b..055a207 100644 --- a/AStar.Dev.Web.slnx +++ b/AStar.Dev.Web.slnx @@ -25,89 +25,43 @@ - - - - - - + + - - - - - - + + - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + - - - - - - - - - - - - - - - - - - - - - + + + + + + + - - - - - - - - - - - - - - - - - - + + + + + + + + + + @@ -115,86 +69,40 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + - - - - - - - - - - - - - - - + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + diff --git a/src/AStar.png b/src/AStar.png new file mode 100644 index 0000000..74b197e Binary files /dev/null and b/src/AStar.png differ diff --git a/src/LICENSE b/src/LICENSE new file mode 100644 index 0000000..0b1b024 --- /dev/null +++ b/src/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2024 AStar Development, Jason Barden + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/src/Readme.md b/src/Readme.md new file mode 100644 index 0000000..16dacd1 --- /dev/null +++ b/src/Readme.md @@ -0,0 +1 @@ +Update \ No newline at end of file diff --git a/src/aspire/AStar.Dev.Web.AppHost/AppHost.cs b/src/aspire/AStar.Dev.Web.AppHost/AppHost.cs index 6e28a96..5b92713 100644 --- a/src/aspire/AStar.Dev.Web.AppHost/AppHost.cs +++ b/src/aspire/AStar.Dev.Web.AppHost/AppHost.cs @@ -11,4 +11,4 @@ .WithReference(apiService) .WaitFor(apiService); -builder.Build().Run(); +await builder.Build().RunAsync(); diff --git a/src/astar.ico b/src/astar.ico new file mode 100644 index 0000000..38b6709 Binary files /dev/null and b/src/astar.ico differ diff --git a/src/modules/apis/AStar.Dev.Admin.Api/AStar.Dev.Admin.Api.csproj b/src/modules/apis/AStar.Dev.Admin.Api/AStar.Dev.Admin.Api.csproj index ff9415b..7f14344 100644 --- a/src/modules/apis/AStar.Dev.Admin.Api/AStar.Dev.Admin.Api.csproj +++ b/src/modules/apis/AStar.Dev.Admin.Api/AStar.Dev.Admin.Api.csproj @@ -10,15 +10,15 @@ - - + + - + - - + + diff --git a/src/modules/apis/AStar.Dev.Admin.Api/AStar.png b/src/modules/apis/AStar.Dev.Admin.Api/AStar.png index 8cac0a1..74b197e 100644 Binary files a/src/modules/apis/AStar.Dev.Admin.Api/AStar.png and b/src/modules/apis/AStar.Dev.Admin.Api/AStar.png differ diff --git a/src/modules/apis/AStar.Dev.Files.Api/AStar.Dev.Files.Api.csproj b/src/modules/apis/AStar.Dev.Files.Api/AStar.Dev.Files.Api.csproj index 1340744..0fe492e 100644 --- a/src/modules/apis/AStar.Dev.Files.Api/AStar.Dev.Files.Api.csproj +++ b/src/modules/apis/AStar.Dev.Files.Api/AStar.Dev.Files.Api.csproj @@ -10,24 +10,24 @@ - - - + + + all runtime; build; native; contentfiles; analyzers; buildtransitive - + - - - + + + - + diff --git a/src/modules/apis/AStar.Dev.Files.Api/AStar.png b/src/modules/apis/AStar.Dev.Files.Api/AStar.png index 8cac0a1..74b197e 100644 Binary files a/src/modules/apis/AStar.Dev.Files.Api/AStar.png and b/src/modules/apis/AStar.Dev.Files.Api/AStar.png differ diff --git a/src/modules/apis/AStar.Dev.Images.Api/AStar.Dev.Images.Api.csproj b/src/modules/apis/AStar.Dev.Images.Api/AStar.Dev.Images.Api.csproj index 9a78063..7da638f 100644 --- a/src/modules/apis/AStar.Dev.Images.Api/AStar.Dev.Images.Api.csproj +++ b/src/modules/apis/AStar.Dev.Images.Api/AStar.Dev.Images.Api.csproj @@ -10,14 +10,14 @@ - - - - + + + + - + diff --git a/src/modules/apis/AStar.Dev.Images.Api/AStar.png b/src/modules/apis/AStar.Dev.Images.Api/AStar.png index 8cac0a1..74b197e 100644 Binary files a/src/modules/apis/AStar.Dev.Images.Api/AStar.png and b/src/modules/apis/AStar.Dev.Images.Api/AStar.png differ diff --git a/src/modules/apis/AStar.Dev.ToDo.Api/AStar.Dev.ToDo.Api.csproj b/src/modules/apis/AStar.Dev.ToDo.Api/AStar.Dev.ToDo.Api.csproj index 5a0efd7..bfe2258 100644 --- a/src/modules/apis/AStar.Dev.ToDo.Api/AStar.Dev.ToDo.Api.csproj +++ b/src/modules/apis/AStar.Dev.ToDo.Api/AStar.Dev.ToDo.Api.csproj @@ -8,7 +8,7 @@ - + diff --git a/src/nuget-packages/AStar.Dev.Admin.Api.Client.Sdk/AStar.Dev.Admin.Api.Client.Sdk.csproj b/src/nuget-packages/AStar.Dev.Admin.Api.Client.Sdk/AStar.Dev.Admin.Api.Client.Sdk.csproj index 42b7405..3f5f240 100644 --- a/src/nuget-packages/AStar.Dev.Admin.Api.Client.Sdk/AStar.Dev.Admin.Api.Client.Sdk.csproj +++ b/src/nuget-packages/AStar.Dev.Admin.Api.Client.Sdk/AStar.Dev.Admin.Api.Client.Sdk.csproj @@ -33,13 +33,13 @@ - - - + + + - - + + diff --git a/src/nuget-packages/AStar.Dev.Admin.Api.Client.Sdk/AStar.png b/src/nuget-packages/AStar.Dev.Admin.Api.Client.Sdk/AStar.png index 8cac0a1..74b197e 100644 Binary files a/src/nuget-packages/AStar.Dev.Admin.Api.Client.Sdk/AStar.png and b/src/nuget-packages/AStar.Dev.Admin.Api.Client.Sdk/AStar.png differ diff --git a/src/nuget-packages/AStar.Dev.Api.Client.Sdk.Shared/AStar.Dev.Api.Client.Sdk.Shared.csproj b/src/nuget-packages/AStar.Dev.Api.Client.Sdk.Shared/AStar.Dev.Api.Client.Sdk.Shared.csproj index 0aed056..a1ec60a 100644 --- a/src/nuget-packages/AStar.Dev.Api.Client.Sdk.Shared/AStar.Dev.Api.Client.Sdk.Shared.csproj +++ b/src/nuget-packages/AStar.Dev.Api.Client.Sdk.Shared/AStar.Dev.Api.Client.Sdk.Shared.csproj @@ -30,8 +30,8 @@ - - + + diff --git a/src/nuget-packages/AStar.Dev.Api.Client.Sdk.Shared/AStar.png b/src/nuget-packages/AStar.Dev.Api.Client.Sdk.Shared/AStar.png index 8cac0a1..74b197e 100644 Binary files a/src/nuget-packages/AStar.Dev.Api.Client.Sdk.Shared/AStar.png and b/src/nuget-packages/AStar.Dev.Api.Client.Sdk.Shared/AStar.png differ diff --git a/src/nuget-packages/AStar.Dev.Api.HealthChecks/AStar.png b/src/nuget-packages/AStar.Dev.Api.HealthChecks/AStar.png index 8cac0a1..74b197e 100644 Binary files a/src/nuget-packages/AStar.Dev.Api.HealthChecks/AStar.png and b/src/nuget-packages/AStar.Dev.Api.HealthChecks/AStar.png differ diff --git a/src/nuget-packages/AStar.Dev.Api.Usage.Sdk/AStar.png b/src/nuget-packages/AStar.Dev.Api.Usage.Sdk/AStar.png new file mode 100644 index 0000000..74b197e Binary files /dev/null and b/src/nuget-packages/AStar.Dev.Api.Usage.Sdk/AStar.png differ diff --git a/src/nuget-packages/AStar.Dev.Api.Usage.Sdk/LICENSE b/src/nuget-packages/AStar.Dev.Api.Usage.Sdk/LICENSE new file mode 100644 index 0000000..0b1b024 --- /dev/null +++ b/src/nuget-packages/AStar.Dev.Api.Usage.Sdk/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2024 AStar Development, Jason Barden + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/src/nuget-packages/AStar.Dev.Api.Usage.Sdk/Readme.md b/src/nuget-packages/AStar.Dev.Api.Usage.Sdk/Readme.md new file mode 100644 index 0000000..16dacd1 --- /dev/null +++ b/src/nuget-packages/AStar.Dev.Api.Usage.Sdk/Readme.md @@ -0,0 +1 @@ +Update \ No newline at end of file diff --git a/src/nuget-packages/AStar.Dev.AspNet.Extensions/AStar.Dev.AspNet.Extensions.csproj b/src/nuget-packages/AStar.Dev.AspNet.Extensions/AStar.Dev.AspNet.Extensions.csproj index 5125461..523f589 100644 --- a/src/nuget-packages/AStar.Dev.AspNet.Extensions/AStar.Dev.AspNet.Extensions.csproj +++ b/src/nuget-packages/AStar.Dev.AspNet.Extensions/AStar.Dev.AspNet.Extensions.csproj @@ -7,13 +7,13 @@ - - + + - - + + diff --git a/src/nuget-packages/AStar.Dev.AspNet.Extensions/AStar.png b/src/nuget-packages/AStar.Dev.AspNet.Extensions/AStar.png index 8cac0a1..74b197e 100644 Binary files a/src/nuget-packages/AStar.Dev.AspNet.Extensions/AStar.png and b/src/nuget-packages/AStar.Dev.AspNet.Extensions/AStar.png differ diff --git a/src/nuget-packages/AStar.Dev.Files.Api.Client.SDK/AStar.Dev.Files.Api.Client.SDK.csproj b/src/nuget-packages/AStar.Dev.Files.Api.Client.SDK/AStar.Dev.Files.Api.Client.SDK.csproj index 283980c..47c3ca7 100644 --- a/src/nuget-packages/AStar.Dev.Files.Api.Client.SDK/AStar.Dev.Files.Api.Client.SDK.csproj +++ b/src/nuget-packages/AStar.Dev.Files.Api.Client.SDK/AStar.Dev.Files.Api.Client.SDK.csproj @@ -26,9 +26,9 @@ - - - + + + diff --git a/src/nuget-packages/AStar.Dev.Files.Api.Client.SDK/AStar.png b/src/nuget-packages/AStar.Dev.Files.Api.Client.SDK/AStar.png index 8cac0a1..74b197e 100644 Binary files a/src/nuget-packages/AStar.Dev.Files.Api.Client.SDK/AStar.png and b/src/nuget-packages/AStar.Dev.Files.Api.Client.SDK/AStar.png differ diff --git a/src/nuget-packages/AStar.Dev.Fluent.Assignments/AStar.png b/src/nuget-packages/AStar.Dev.Fluent.Assignments/AStar.png index 8cac0a1..74b197e 100644 Binary files a/src/nuget-packages/AStar.Dev.Fluent.Assignments/AStar.png and b/src/nuget-packages/AStar.Dev.Fluent.Assignments/AStar.png differ diff --git a/src/nuget-packages/AStar.Dev.Guard.Clauses/AStar.png b/src/nuget-packages/AStar.Dev.Guard.Clauses/AStar.png index 8cac0a1..74b197e 100644 Binary files a/src/nuget-packages/AStar.Dev.Guard.Clauses/AStar.png and b/src/nuget-packages/AStar.Dev.Guard.Clauses/AStar.png differ diff --git a/src/nuget-packages/AStar.Dev.Images.Api.Client.SDK/AStar.Dev.Images.Api.Client.SDK.csproj b/src/nuget-packages/AStar.Dev.Images.Api.Client.SDK/AStar.Dev.Images.Api.Client.SDK.csproj index 315031d..6c2f2ab 100644 --- a/src/nuget-packages/AStar.Dev.Images.Api.Client.SDK/AStar.Dev.Images.Api.Client.SDK.csproj +++ b/src/nuget-packages/AStar.Dev.Images.Api.Client.SDK/AStar.Dev.Images.Api.Client.SDK.csproj @@ -26,9 +26,9 @@ - - - + + + diff --git a/src/nuget-packages/AStar.Dev.Images.Api.Client.SDK/AStar.png b/src/nuget-packages/AStar.Dev.Images.Api.Client.SDK/AStar.png index 8cac0a1..74b197e 100644 Binary files a/src/nuget-packages/AStar.Dev.Images.Api.Client.SDK/AStar.png and b/src/nuget-packages/AStar.Dev.Images.Api.Client.SDK/AStar.png differ diff --git a/src/nuget-packages/AStar.Dev.Infrastructure.AdminDb/AStar.png b/src/nuget-packages/AStar.Dev.Infrastructure.AdminDb/AStar.png index 8cac0a1..74b197e 100644 Binary files a/src/nuget-packages/AStar.Dev.Infrastructure.AdminDb/AStar.png and b/src/nuget-packages/AStar.Dev.Infrastructure.AdminDb/AStar.png differ diff --git a/src/nuget-packages/AStar.Dev.Infrastructure.FilesDb/AStar.png b/src/nuget-packages/AStar.Dev.Infrastructure.FilesDb/AStar.png index 8cac0a1..74b197e 100644 Binary files a/src/nuget-packages/AStar.Dev.Infrastructure.FilesDb/AStar.png and b/src/nuget-packages/AStar.Dev.Infrastructure.FilesDb/AStar.png differ diff --git a/src/nuget-packages/AStar.Dev.Infrastructure.UsageDb/AStar.png b/src/nuget-packages/AStar.Dev.Infrastructure.UsageDb/AStar.png index 8cac0a1..74b197e 100644 Binary files a/src/nuget-packages/AStar.Dev.Infrastructure.UsageDb/AStar.png and b/src/nuget-packages/AStar.Dev.Infrastructure.UsageDb/AStar.png differ diff --git a/src/nuget-packages/AStar.Dev.Infrastructure.UsageDb/Data/ApiUsageContext.cs b/src/nuget-packages/AStar.Dev.Infrastructure.UsageDb/Data/ApiUsageContext.cs index 7ddf372..43e2c0d 100644 --- a/src/nuget-packages/AStar.Dev.Infrastructure.UsageDb/Data/ApiUsageContext.cs +++ b/src/nuget-packages/AStar.Dev.Infrastructure.UsageDb/Data/ApiUsageContext.cs @@ -24,7 +24,7 @@ public ApiUsageContext(ConnectionString connectionString) /// /// - public DbSet ApiUsage { get; set; } + public DbSet ApiUsage { get; set; } = null!; /// /// The overridden OnModelCreating method. diff --git a/src/nuget-packages/AStar.Dev.Infrastructure/AStar.png b/src/nuget-packages/AStar.Dev.Infrastructure/AStar.png index 8cac0a1..74b197e 100644 Binary files a/src/nuget-packages/AStar.Dev.Infrastructure/AStar.png and b/src/nuget-packages/AStar.Dev.Infrastructure/AStar.png differ diff --git a/src/nuget-packages/AStar.Dev.Logging.Extensions/AStar.png b/src/nuget-packages/AStar.Dev.Logging.Extensions/AStar.png index 8cac0a1..74b197e 100644 Binary files a/src/nuget-packages/AStar.Dev.Logging.Extensions/AStar.png and b/src/nuget-packages/AStar.Dev.Logging.Extensions/AStar.png differ diff --git a/src/nuget-packages/AStar.Dev.Technical.Debt.Reporting/AStar.png b/src/nuget-packages/AStar.Dev.Technical.Debt.Reporting/AStar.png index 8cac0a1..74b197e 100644 Binary files a/src/nuget-packages/AStar.Dev.Technical.Debt.Reporting/AStar.png and b/src/nuget-packages/AStar.Dev.Technical.Debt.Reporting/AStar.png differ diff --git a/src/nuget-packages/AStar.Dev.Test.Helpers.EndToEnd/AStar.png b/src/nuget-packages/AStar.Dev.Test.Helpers.EndToEnd/AStar.png index 8cac0a1..74b197e 100644 Binary files a/src/nuget-packages/AStar.Dev.Test.Helpers.EndToEnd/AStar.png and b/src/nuget-packages/AStar.Dev.Test.Helpers.EndToEnd/AStar.png differ diff --git a/src/nuget-packages/AStar.Dev.Test.Helpers.Integration/AStar.png b/src/nuget-packages/AStar.Dev.Test.Helpers.Integration/AStar.png index 8cac0a1..74b197e 100644 Binary files a/src/nuget-packages/AStar.Dev.Test.Helpers.Integration/AStar.png and b/src/nuget-packages/AStar.Dev.Test.Helpers.Integration/AStar.png differ diff --git a/src/nuget-packages/AStar.Dev.Test.Helpers.Unit/AStar.png b/src/nuget-packages/AStar.Dev.Test.Helpers.Unit/AStar.png index 8cac0a1..74b197e 100644 Binary files a/src/nuget-packages/AStar.Dev.Test.Helpers.Unit/AStar.png and b/src/nuget-packages/AStar.Dev.Test.Helpers.Unit/AStar.png differ diff --git a/src/nuget-packages/AStar.Dev.Test.Helpers/AStar.png b/src/nuget-packages/AStar.Dev.Test.Helpers/AStar.png index 8cac0a1..74b197e 100644 Binary files a/src/nuget-packages/AStar.Dev.Test.Helpers/AStar.png and b/src/nuget-packages/AStar.Dev.Test.Helpers/AStar.png differ diff --git a/src/nuget-packages/AStar.Dev.Usage.Api.Client.SDK/AStar.png b/src/nuget-packages/AStar.Dev.Usage.Api.Client.SDK/AStar.png index 8cac0a1..74b197e 100644 Binary files a/src/nuget-packages/AStar.Dev.Usage.Api.Client.SDK/AStar.png and b/src/nuget-packages/AStar.Dev.Usage.Api.Client.SDK/AStar.png differ diff --git a/src/services/AStar.Dev.FilesDb.MigrationService/AStar.Dev.FilesDb.MigrationService.csproj b/src/services/AStar.Dev.FilesDb.MigrationService/AStar.Dev.FilesDb.MigrationService.csproj new file mode 100644 index 0000000..2b6b1f0 --- /dev/null +++ b/src/services/AStar.Dev.FilesDb.MigrationService/AStar.Dev.FilesDb.MigrationService.csproj @@ -0,0 +1,20 @@ + + + + net10.0 + enable + enable + dotnet-AStar.Dev.FilesDb.MigrationService-52142518-78e8-4b1f-8a08-363d619e2970 + + + + + + + + + + + + + diff --git a/src/services/AStar.Dev.FilesDb.MigrationService/Program.cs b/src/services/AStar.Dev.FilesDb.MigrationService/Program.cs new file mode 100644 index 0000000..62286f9 --- /dev/null +++ b/src/services/AStar.Dev.FilesDb.MigrationService/Program.cs @@ -0,0 +1,15 @@ +using AStar.Dev.FilesDb.MigrationService; +using AStar.Dev.Infrastructure.FilesDb.Data; +using AStar.Dev.Web.Aspire.Common; +using AStar.Dev.Web.ServiceDefaults; + +HostApplicationBuilder builder = Host.CreateApplicationBuilder(args); +builder.AddServiceDefaults(); +builder.AddSqlServerDbContext(AspireConstants.Sql.FilesDb); +builder.Services.AddHostedService(); + +builder.Services.AddOpenTelemetry() + .WithTracing(tracing => tracing.AddSource(Worker.ActivitySourceName)); + +IHost host = builder.Build(); +await host.RunAsync(); diff --git a/src/services/AStar.Dev.FilesDb.MigrationService/Properties/launchSettings.json b/src/services/AStar.Dev.FilesDb.MigrationService/Properties/launchSettings.json new file mode 100644 index 0000000..2a81789 --- /dev/null +++ b/src/services/AStar.Dev.FilesDb.MigrationService/Properties/launchSettings.json @@ -0,0 +1,12 @@ +{ + "$schema": "https://json.schemastore.org/launchsettings.json", + "profiles": { + "AStar.Dev.FilesDb.MigrationService": { + "commandName": "Project", + "dotnetRunMessages": true, + "environmentVariables": { + "DOTNET_ENVIRONMENT": "Development" + } + } + } +} diff --git a/src/services/AStar.Dev.FilesDb.MigrationService/Worker.cs b/src/services/AStar.Dev.FilesDb.MigrationService/Worker.cs new file mode 100644 index 0000000..dd333e8 --- /dev/null +++ b/src/services/AStar.Dev.FilesDb.MigrationService/Worker.cs @@ -0,0 +1,85 @@ +using System.Diagnostics; +using AStar.Dev.Infrastructure.FilesDb.Data; +using AStar.Dev.Infrastructure.FilesDb.Models; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Storage; + +namespace AStar.Dev.FilesDb.MigrationService; + +public class Worker(IServiceProvider serviceProvider, IHostApplicationLifetime hostApplicationLifetime) : BackgroundService +{ + public const string ActivitySourceName = "Migrations"; + private static readonly ActivitySource ActivitySource = new(ActivitySourceName); + + protected override async Task ExecuteAsync(CancellationToken cancellationToken) + { + using Activity? activity = ActivitySource.StartActivity("Migrating database", ActivityKind.Client); + + try + { + using IServiceScope scope = serviceProvider.CreateScope(); + FilesContext dbContext = scope.ServiceProvider.GetRequiredService(); + + await EnsureDatabaseAsync(dbContext, cancellationToken); + await RunMigrationAsync(dbContext, cancellationToken); + await SeedDataAsync(dbContext, cancellationToken); + } + catch(Exception ex) + { + _ = (activity?.AddException(ex)); + } + + hostApplicationLifetime.StopApplication(); + } + + private static async Task EnsureDatabaseAsync(FilesContext dbContext, CancellationToken cancellationToken) + { + IRelationalDatabaseCreator dbCreator = dbContext.GetService(); + + IExecutionStrategy strategy = dbContext.Database.CreateExecutionStrategy(); + + await strategy.ExecuteAsync(async () => + { + if(!await dbCreator.ExistsAsync(cancellationToken)) await dbCreator.CreateAsync(cancellationToken); + }); + } + + private static async Task RunMigrationAsync(FilesContext dbContext, CancellationToken cancellationToken) + { + IExecutionStrategy strategy = dbContext.Database.CreateExecutionStrategy(); + + await strategy.ExecuteAsync(async () => + { + await dbContext.Database.MigrateAsync(cancellationToken); + }); + } + + private static async Task SeedDataAsync(FilesContext dbContext, CancellationToken cancellationToken) + { + var exists = dbContext.Files.Any(detail => detail.DirectoryName.Value == "mock" && detail.FileName.Value == "Fake"); + + if(exists) return; + + FileDetail firstTicket = new() + { + DirectoryName = new DirectoryName("mock"), + FileName = new FileName("Fake"), + ImageDetail = new ImageDetail(), + FileHandle = new FileHandle("Mock Handle"), + FileSize = 123, + IsImage = true, + FileAccessDetail = new FileAccessDetail { DetailsLastUpdated = DateTime.UtcNow, }, + }; + + IExecutionStrategy strategy = dbContext.Database.CreateExecutionStrategy(); + + await strategy.ExecuteAsync(async () => + { + await using IDbContextTransaction transaction = await dbContext.Database.BeginTransactionAsync(cancellationToken); + _ = await dbContext.Files.AddAsync(firstTicket, cancellationToken); + _ = await dbContext.SaveChangesAsync(cancellationToken); + await transaction.CommitAsync(cancellationToken); + }); + } +} diff --git a/src/services/AStar.Dev.FilesDb.MigrationService/appsettings.json b/src/services/AStar.Dev.FilesDb.MigrationService/appsettings.json new file mode 100644 index 0000000..b2dcdb6 --- /dev/null +++ b/src/services/AStar.Dev.FilesDb.MigrationService/appsettings.json @@ -0,0 +1,8 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.Hosting.Lifetime": "Information" + } + } +} diff --git a/src/services/AStar.Dev.Usage.Logger/AStar.Dev.Usage.Logger.csproj b/src/services/AStar.Dev.Usage.Logger/AStar.Dev.Usage.Logger.csproj new file mode 100644 index 0000000..ee062d8 --- /dev/null +++ b/src/services/AStar.Dev.Usage.Logger/AStar.Dev.Usage.Logger.csproj @@ -0,0 +1,40 @@ + + + + net10.0 + enable + enable + Linux + 464c1a20-14c6-4953-9009-5b4ea78f6b00 + + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + + + + + + + + + + + + + + + + + + + .dockerignore + + + + diff --git a/src/services/AStar.Dev.Usage.Logger/AStar.Dev.Usage.Logger.http b/src/services/AStar.Dev.Usage.Logger/AStar.Dev.Usage.Logger.http new file mode 100644 index 0000000..6181b62 --- /dev/null +++ b/src/services/AStar.Dev.Usage.Logger/AStar.Dev.Usage.Logger.http @@ -0,0 +1,6 @@ +@AStar.Dev.Usage.Logger_HostAddress = http://localhost:5149 + +GET {{AStar.Dev.Usage.Logger_HostAddress}}/weatherforecast/ +Accept: application/json + +### diff --git a/src/services/AStar.Dev.Usage.Logger/AStar.png b/src/services/AStar.Dev.Usage.Logger/AStar.png new file mode 100644 index 0000000..74b197e Binary files /dev/null and b/src/services/AStar.Dev.Usage.Logger/AStar.png differ diff --git a/src/services/AStar.Dev.Usage.Logger/AddEndpoints.cs b/src/services/AStar.Dev.Usage.Logger/AddEndpoints.cs new file mode 100644 index 0000000..73fa227 --- /dev/null +++ b/src/services/AStar.Dev.Usage.Logger/AddEndpoints.cs @@ -0,0 +1,32 @@ +using System.Reflection; + +namespace AStar.Dev.Usage.Logger; + +/// +/// The AddEndpoints class adds the AddApplicationEndpoints extension method to the +/// class +/// +public static class AddEndpoints +{ + /// + /// The AddApplicationEndpoints method uses reflection to add all the endpoints that implement the + /// interface + /// + /// If you have other endpoints to add, please use the standard Framework approach + /// + /// + /// The instance of to add the endpoints to + public static void AddApplicationEndpoints(this WebApplication app) + { + var currentAssembly = Assembly.GetExecutingAssembly(); + + IEnumerable endpoints = currentAssembly.GetTypes().Where(type => typeof(IEndpoint).IsAssignableFrom(type) + && type != typeof(IEndpoint) && type is { IsPublic: true, IsAbstract: false, }); + + foreach(Type endpoint in endpoints) + { + var instance = (IEndpoint)Activator.CreateInstance(endpoint, app)!; + instance.AddEndpoint(); + } + } +} diff --git a/src/services/AStar.Dev.Usage.Logger/Dockerfile b/src/services/AStar.Dev.Usage.Logger/Dockerfile new file mode 100644 index 0000000..e090878 --- /dev/null +++ b/src/services/AStar.Dev.Usage.Logger/Dockerfile @@ -0,0 +1,30 @@ +FROM mcr.microsoft.com/dotnet/aspnet:9.0 AS base +USER $APP_UID +WORKDIR /app +EXPOSE 8080 +EXPOSE 8081 + +FROM mcr.microsoft.com/dotnet/sdk:9.0 AS build +ARG BUILD_CONFIGURATION=Release +WORKDIR /src +COPY ["src/services/AStar.Dev.Usage.Logger/AStar.Dev.Usage.Logger.csproj", "src/services/AStar.Dev.Usage.Logger/"] +COPY ["src/nuget-packages/AStar.Dev.Api.Usage.Sdk/AStar.Dev.Api.Usage.Sdk.csproj", "src/nuget-packages/AStar.Dev.Api.Usage.Sdk/"] +COPY ["src/nuget-packages/AStar.Dev.Utilities/AStar.Dev.Utilities.csproj", "src/nuget-packages/AStar.Dev.Utilities/"] +COPY ["src/nuget-packages/AStar.Dev.AspNet.Extensions/AStar.Dev.AspNet.Extensions.csproj", "src/nuget-packages/AStar.Dev.AspNet.Extensions/"] +COPY ["src/nuget-packages/AStar.Dev.Api.HealthChecks/AStar.Dev.Api.HealthChecks.csproj", "src/nuget-packages/AStar.Dev.Api.HealthChecks/"] +COPY ["src/nuget-packages/AStar.Dev.Technical.Debt.Reporting/AStar.Dev.Technical.Debt.Reporting.csproj", "src/nuget-packages/AStar.Dev.Technical.Debt.Reporting/"] +COPY ["src/nuget-packages/AStar.Dev.Infrastructure/AStar.Dev.Infrastructure.csproj", "src/nuget-packages/AStar.Dev.Infrastructure/"] +COPY ["src/nuget-packages/AStar.Dev.Logging.Extensions/AStar.Dev.Logging.Extensions.csproj", "src/nuget-packages/AStar.Dev.Logging.Extensions/"] +RUN dotnet restore "src/services/AStar.Dev.Usage.Logger/AStar.Dev.Usage.Logger.csproj" +COPY . . +WORKDIR "/src/src/services/AStar.Dev.Usage.Logger" +RUN dotnet build "./AStar.Dev.Usage.Logger.csproj" -c $BUILD_CONFIGURATION -o /app/build + +FROM build AS publish +ARG BUILD_CONFIGURATION=Release +RUN dotnet publish "./AStar.Dev.Usage.Logger.csproj" -c $BUILD_CONFIGURATION -o /app/publish /p:UseAppHost=false + +FROM base AS final +WORKDIR /app +COPY --from=publish /app/publish . +ENTRYPOINT ["dotnet", "AStar.Dev.Usage.Logger.dll"] diff --git a/src/services/AStar.Dev.Usage.Logger/EndpointConstants.cs b/src/services/AStar.Dev.Usage.Logger/EndpointConstants.cs new file mode 100644 index 0000000..cbcf5a0 --- /dev/null +++ b/src/services/AStar.Dev.Usage.Logger/EndpointConstants.cs @@ -0,0 +1,22 @@ +namespace AStar.Dev.Usage.Logger; + +/// +/// The defines the endpoints available +/// +public static class EndpointConstants +{ + /// + /// Gets the Usage endpoint + /// + public const string UsageEndpoint = "usage"; + + /// + /// Gets the Usage Tag (used by Swagger) + /// + public const string UsageTag = "Usage"; + + /// + /// Gets the Usage Group Name (used by Swagger) + /// + public const string UsageGroupName = "Usage"; +} diff --git a/src/services/AStar.Dev.Usage.Logger/HalfSecondPeriodicTimer.cs b/src/services/AStar.Dev.Usage.Logger/HalfSecondPeriodicTimer.cs new file mode 100644 index 0000000..cd55f21 --- /dev/null +++ b/src/services/AStar.Dev.Usage.Logger/HalfSecondPeriodicTimer.cs @@ -0,0 +1,12 @@ +namespace AStar.Dev.Usage.Logger; + +public sealed class HalfSecondPeriodicTimer : IPeriodicTimer +{ + private readonly PeriodicTimer timer = new(TimeSpan.FromMilliseconds(500)); + + public async ValueTask WaitForNextTickAsync(CancellationToken cancellationToken = default) + => await timer.WaitForNextTickAsync(cancellationToken); + + public void Dispose() + => timer.Dispose(); +} diff --git a/src/services/AStar.Dev.Usage.Logger/IAssemblyMarker.cs b/src/services/AStar.Dev.Usage.Logger/IAssemblyMarker.cs new file mode 100644 index 0000000..8013b5b --- /dev/null +++ b/src/services/AStar.Dev.Usage.Logger/IAssemblyMarker.cs @@ -0,0 +1,7 @@ +namespace AStar.Dev.Usage.Logger; + +/// +/// The IAssemblyMarker interface is used where a class/interface is required to identify the assembly +/// No functionality is (nor should any be) defined by this marker interface +/// +public interface IAssemblyMarker; diff --git a/src/services/AStar.Dev.Usage.Logger/IEndpoint.cs b/src/services/AStar.Dev.Usage.Logger/IEndpoint.cs new file mode 100644 index 0000000..d9edf3f --- /dev/null +++ b/src/services/AStar.Dev.Usage.Logger/IEndpoint.cs @@ -0,0 +1,10 @@ +namespace AStar.Dev.Usage.Logger; + +/// +/// +public interface IEndpoint +{ + /// + /// + void AddEndpoint(); +} diff --git a/src/services/AStar.Dev.Usage.Logger/IPeriodicTimer.cs b/src/services/AStar.Dev.Usage.Logger/IPeriodicTimer.cs new file mode 100644 index 0000000..fe7c784 --- /dev/null +++ b/src/services/AStar.Dev.Usage.Logger/IPeriodicTimer.cs @@ -0,0 +1,6 @@ +namespace AStar.Dev.Usage.Logger; + +public interface IPeriodicTimer : IDisposable +{ + ValueTask WaitForNextTickAsync(CancellationToken cancellationToken = default); +} diff --git a/src/services/AStar.Dev.Usage.Logger/JsonSettings.cs b/src/services/AStar.Dev.Usage.Logger/JsonSettings.cs new file mode 100644 index 0000000..72c54c6 --- /dev/null +++ b/src/services/AStar.Dev.Usage.Logger/JsonSettings.cs @@ -0,0 +1,8 @@ +using System.Text.Json; + +namespace AStar.Dev.Usage.Logger; + +public static class JsonSettings +{ + public static JsonSerializerOptions Options => new() { PropertyNameCaseInsensitive = true, }; +} diff --git a/src/services/AStar.Dev.Usage.Logger/LICENSE b/src/services/AStar.Dev.Usage.Logger/LICENSE new file mode 100644 index 0000000..0b1b024 --- /dev/null +++ b/src/services/AStar.Dev.Usage.Logger/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2024 AStar Development, Jason Barden + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/src/services/AStar.Dev.Usage.Logger/ProcessUsageEventsService.cs b/src/services/AStar.Dev.Usage.Logger/ProcessUsageEventsService.cs new file mode 100644 index 0000000..ea80667 --- /dev/null +++ b/src/services/AStar.Dev.Usage.Logger/ProcessUsageEventsService.cs @@ -0,0 +1,100 @@ +using System.Text; +using System.Text.Json; +using AStar.Dev.Api.Usage.Sdk; +using AStar.Dev.Infrastructure.UsageDb.Data; +using AStar.Dev.Utilities; +using Microsoft.Extensions.Options; +using RabbitMQ.Client; +using RabbitMQ.Client.Events; + +namespace AStar.Dev.Usage.Logger; + +public sealed class ProcessUsageEventsService( + IOptions usageConfiguration, + IConnection connection, + ApiUsageContext apiUsageContext, + IPeriodicTimer timer, + ILogger logger) + : IHostedService +{ + public async Task StartAsync(CancellationToken cancellationToken) + { + logger.LogDebug("Entering the StartAsync method in ProcessUsageEventsService"); + + await ProcessEventsAsync(cancellationToken); + } + + public Task StopAsync(CancellationToken cancellationToken) + { + logger.LogDebug("Entering the StopAsync method in ProcessUsageEventsService"); + + return Task.CompletedTask; + } + + public async Task ProcessEventsAsync(CancellationToken stoppingToken) + { + try + { + logger.LogDebug("Entering the ProcessEvents method in ProcessUsageEventsService"); + ApiUsageConfiguration config = usageConfiguration.Value; + await using IChannel channel = await connection.CreateChannelAsync(cancellationToken: stoppingToken); + + _ = await channel.QueueDeclareAsync(config.QueueName, exclusive: false, durable: true, + autoDelete: false, arguments: null, cancellationToken: stoppingToken); + + await channel.BasicQosAsync(0, 1, false, stoppingToken); + + var consumer = new AsyncEventingBasicConsumer(channel); + + consumer.ReceivedAsync += async (model, eventArgs) => { await ProcessReceivedMessageAsync(eventArgs, stoppingToken); }; + + _ = await channel.BasicConsumeAsync(config.QueueName, true, consumer, stoppingToken); + + while(!stoppingToken.IsCancellationRequested && + await timer.WaitForNextTickAsync(stoppingToken)) + { + // No action required here, this just prevents the method exiting + } + } + catch(Exception ex) + { + logger.LogError(ex, "Error occured while processing usage events: {EventError}", ex.Message); + } + } + + private async Task ProcessReceivedMessageAsync(BasicDeliverEventArgs eventArgs, CancellationToken stoppingToken) + { + try + { + logger.LogDebug("Entering the ProcessReceivedMessageAsync method in ProcessUsageEventsService"); + + var body = eventArgs.Body.ToArray(); + var message = Encoding.UTF8.GetString(body); + ApiUsageEvent apiUsageEvent = JsonSerializer.Deserialize(message, JsonSettings.Options)!; + + var eventData = apiUsageEvent.ToJson(); + var exists = apiUsageContext.ApiUsage.Any(x => x.Id == apiUsageEvent.Id); + + if(!exists) + await SaveTheEventAsync(apiUsageEvent, stoppingToken); + else + logger.LogDebug("NOT Saving {Event} as it is already in the database", eventData); + } + catch(Exception ex) + { + logger.LogError(ex, "Error occured while processing usage events: {EventError}", ex.Message); + } + } + + private async Task SaveTheEventAsync(ApiUsageEvent apiUsageEvent, CancellationToken stoppingToken) + { + _ = apiUsageContext.ApiUsage.Add(apiUsageEvent); + + var result = await apiUsageContext.SaveChangesAsync(stoppingToken); + + if(result > 0) + logger.LogDebug("Saved {Event}", apiUsageEvent.ToJson()); + else + logger.LogWarning("Save {Event} did not update the database", apiUsageEvent.ToJson()); + } +} diff --git a/src/services/AStar.Dev.Usage.Logger/Program.cs b/src/services/AStar.Dev.Usage.Logger/Program.cs new file mode 100644 index 0000000..5f95c40 --- /dev/null +++ b/src/services/AStar.Dev.Usage.Logger/Program.cs @@ -0,0 +1,85 @@ +using System.IdentityModel.Tokens.Jwt; +using System.Text.Json.Serialization; +using AStar.Dev.Api.Usage.Sdk; +using AStar.Dev.Api.Usage.Sdk.Metrics; +using AStar.Dev.AspNet.Extensions.PipelineExtensions; +using AStar.Dev.AspNet.Extensions.RootEndpoint; +using AStar.Dev.AspNet.Extensions.ServiceCollectionExtensions; +using AStar.Dev.AspNet.Extensions.WebApplicationBuilderExtensions; +using AStar.Dev.Auth.Extensions; +using AStar.Dev.Infrastructure.Data; +using AStar.Dev.Infrastructure.UsageDb.Data; +using AStar.Dev.Logging.Extensions; +using AStar.Dev.Usage.Logger; +using AStar.Dev.Web.Aspire.Common; +using AStar.Dev.Web.ServiceDefaults; +using Microsoft.AspNetCore.Mvc; +using Serilog; +using JsonOptions = Microsoft.AspNetCore.Http.Json.JsonOptions; + +var applicationName = typeof(IAssemblyMarker).Assembly.GetName().Name!; + +try +{ + WebApplicationBuilder builder = WebApplication.CreateBuilder(args); + _ = builder.AddServiceDefaults(); + + _ = builder + .DisableServerHeader() + .AddSerilogLogging(Configuration.ExternalSettingsFile) + .Services.AddApiConfiguration(builder.Configuration); + + Log.Information("Starting {AppName}", applicationName); + IServiceCollection services = builder.Services; + + var connectionString = builder.Configuration.GetConnectionString("sqlServer")!; + + _ = builder.Services.AddScoped(); + _ = builder.Services.AddSingleton(_ => new ApiUsageContext(new ConnectionString { Value = connectionString, })); + _ = builder.Services.AddTransient(); + _ = builder.Services.Configure(options => options.ServicesStartConcurrently = true); + _ = builder.Services.AddHostedService(); + + _ = services.AddUsageServices(builder.Configuration, typeof(IAssemblyMarker).Assembly); + + JwtSecurityTokenHandler.DefaultMapInboundClaims = false; + + _ = services.Configure(options => + { + options.SerializerOptions.ReferenceHandler = ReferenceHandler.IgnoreCycles; + options.SerializerOptions.PropertyNameCaseInsensitive = true; + }); + + builder.AddRabbitMQClient(AspireConstants.Common.AstarMessaging); + + _ = services.AddSingleton(); + + WebApplication app = builder.Build() + .UseApiServices(); + + app.ConfigureRootPage(applicationName.Replace(".", " ")) + .UseMetrics(); + + app.AddApplicationEndpoints(); + + _ = app.MapGet("/process-events", + async ([FromServices] ProcessUsageEventsService process, CancellationToken stoppingToken) => + { + await process.ProcessEventsAsync(stoppingToken); + + return Results.Ok(); + }) + .WithName("ProcessEvents"); + + _ = app.MapDefaultEndpoints(); + + await app.RunAsync(); +} +catch(Exception ex) +{ + Log.Fatal(ex, "Fatal error occurred in {AppName}", applicationName); +} +finally +{ + await Log.CloseAndFlushAsync(); +} diff --git a/src/services/AStar.Dev.Usage.Logger/Properties/launchSettings.json b/src/services/AStar.Dev.Usage.Logger/Properties/launchSettings.json new file mode 100644 index 0000000..22ec040 --- /dev/null +++ b/src/services/AStar.Dev.Usage.Logger/Properties/launchSettings.json @@ -0,0 +1,15 @@ +{ + "$schema": "https://json.schemastore.org/launchsettings.json", + "profiles": { + "https": { + "commandName": "Project", + "dotnetRunMessages": true, + "launchBrowser": true, + "launchUrl": "swagger", + "applicationUrl": "https://localhost:7049;http://localhost:5149", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + } + } +} diff --git a/src/services/AStar.Dev.Usage.Logger/Readme.md b/src/services/AStar.Dev.Usage.Logger/Readme.md new file mode 100644 index 0000000..16dacd1 --- /dev/null +++ b/src/services/AStar.Dev.Usage.Logger/Readme.md @@ -0,0 +1 @@ +Update \ No newline at end of file diff --git a/src/services/AStar.Dev.Usage.Logger/Usage/GetAll/V1/ApiUsageEventDto.cs b/src/services/AStar.Dev.Usage.Logger/Usage/GetAll/V1/ApiUsageEventDto.cs new file mode 100644 index 0000000..125813f --- /dev/null +++ b/src/services/AStar.Dev.Usage.Logger/Usage/GetAll/V1/ApiUsageEventDto.cs @@ -0,0 +1,19 @@ +namespace AStar.Dev.Usage.Logger.Usage.GetAll.V1; + +/// +/// +/// +/// +/// +/// +/// +public record ApiUsageEventDto(string ApiName, string ApiEndpoint, string HttpMethod, double ElapsedMilliseconds, int StatusCode) +{ + /// + /// + public Guid Id { get; init; } = Guid.CreateVersion7(); + + /// + /// + public DateTime Timestamp { get; init; } = DateTime.UtcNow; +} diff --git a/src/services/AStar.Dev.Usage.Logger/Usage/GetAll/V1/GetAllApiUsageEventsEndpoint.cs b/src/services/AStar.Dev.Usage.Logger/Usage/GetAll/V1/GetAllApiUsageEventsEndpoint.cs new file mode 100644 index 0000000..997ecdc --- /dev/null +++ b/src/services/AStar.Dev.Usage.Logger/Usage/GetAll/V1/GetAllApiUsageEventsEndpoint.cs @@ -0,0 +1,60 @@ +using System.Security.Claims; +using Asp.Versioning.Builder; +using AStar.Dev.Api.Usage.Sdk; +using AStar.Dev.Infrastructure.UsageDb.Data; +using AStar.Dev.Logging.Extensions; +using AStar.Dev.Minimal.Api.Extensions; +using Microsoft.EntityFrameworkCore; + +namespace AStar.Dev.Usage.Logger.Usage.GetAll.V1; + +/// +/// The class contains the method +/// +/// The instance of to add the endpoint to +public sealed class GetAllApiUsageEventsEndpoint(WebApplication app) : IEndpoint +{ + /// + public void AddEndpoint() + { + IVersionedEndpointRouteBuilder versionedApi = app.NewVersionedApi(EndpointConstants.UsageGroupName); + + RouteGroupBuilder apiGroup = versionedApi + .MapGroup(EndpointConstants.UsageEndpoint) + .HasApiVersion(1.0); + + _ = apiGroup + .MapGet("/", + async (HttpContext context, ApiUsageContext usageContext, ILoggerAstar logger, CancellationToken cancellationToken) => await Handle(context.User, + usageContext, + logger, + cancellationToken)) + .AddBasicProduces>>() + .WithDescription("Gets all of the API Usage Metrics - no filter at the moment") + .WithSummary("Get all the API Usage Metrics") + + // .RequireAuthorization() + .WithTags(EndpointConstants.UsageTag); + } + + private async Task Handle(ClaimsPrincipal user, ApiUsageContext usageContext, ILoggerAstar logger, CancellationToken cancellationToken) + { + if(!user.Claims.FirstOrDefault(c => c.Type == "name")!.Value.Contains("Jason Barden")) + { + logger.LogDebug("Username: {Username}", user.Claims.Where(c => c.Type == "name")); + + return Results.Forbid(); + } + + List config = await usageContext + .ApiUsage.ToListAsync(cancellationToken); + + var groupedEvents = config + .GroupBy(x => x.ApiName) + .ToDictionary(grouping => grouping.Key, detail => detail.OrderBy(usage => usage.ApiEndpoint).ThenByDescending(s => s.Timestamp).Take(10)); + + logger.LogDebug("Total API Usage Events: {ApiUsageEventCount}", config.Count); + + return TypedResults.Ok(groupedEvents); + } +} diff --git a/src/services/AStar.Dev.Usage.Logger/appsettings.json b/src/services/AStar.Dev.Usage.Logger/appsettings.json new file mode 100644 index 0000000..050fda8 --- /dev/null +++ b/src/services/AStar.Dev.Usage.Logger/appsettings.json @@ -0,0 +1,33 @@ +{ + "AzureAd": { + "Instance": "https://login.microsoftonline.com/", + "Domain": "jasonbardenoutlook.onmicrosoft.com", + "TenantId": "bb7d94aa-36a9-4a59-a0c1-54a757c47ddf", + "ClientId": "54861ab2-fdb0-4e18-a073-c90e7bf9f0c5" + }, + "apiConfiguration": { + "openApiInfo": { + "title": "AStar Development - Usage Logger Api", + "description": "The AStar.Dev.Usage.Logger.Api containing the ...", + "contact": { + "name": "AStar Development", + "url": "https://github.com/astar-development", + "email": "astar-development@outlook.com" + }, + "license": { + "name": "MIT License", + "url": "https://opensource.org/licenses/MIT" + }, + "termsOfService": "https://github.com/astar-development" + } + }, + "apiUsageConfiguration": { + "hostName": "astar-dev-messaging-1aa4302b", + "userName": "user", + "queueName": "usage", + "password": "Password isn't this!" + }, + "ConnectionStrings": { + "sqlServer": "Data Source=Some Server, somewhere" + } +} diff --git a/src/services/AStar.Dev.Usage.Logger/astar-logging-settings.json b/src/services/AStar.Dev.Usage.Logger/astar-logging-settings.json new file mode 100644 index 0000000..eec4db6 --- /dev/null +++ b/src/services/AStar.Dev.Usage.Logger/astar-logging-settings.json @@ -0,0 +1,58 @@ +{ + "Serilog": { + "Enrich": [ + "FromLogContext", + "WithMachineName", + "WithSpan", + "WithExceptionDetails" + ], + "WriteTo": [ + { + "Name": "Seq", + "Args": { + "serverUrl": "http://seq:5341" + } + }, + { + "Name": "ApplicationInsights", + "Args": { + "telemetryConverter": "Serilog.Sinks.ApplicationInsights.TelemetryConverters.TraceTelemetryConverter, Serilog.Sinks.ApplicationInsights" + } + } + ], + "Properties": { + "ApplicationName": "AStar.Dev.Usage.API" + }, + "MinimumLevel": { + "Default": "Information", + "Override": { + "Microsoft.AspNetCore": "Warning", + "Microsoft.Identity.Web": "Warning", + "Microsoft.IdentityModel": "Warning", + "System.Net.Http": "Information", + "AStar": "Debug" + } + } + }, + "Logging": { + "Console": { + "FormatterName": "json", + "FormatterOptions": { + "SingleLine": true, + "IncludeScopes": true, + "TimestampFormat": "HH:mm:ss ", + "UseUtcTimestamp": true, + "JsonWriterOptions": { + "Indented": true + } + } + }, + "ApplicationInsights": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning", + "AStar": "Debug" + } + } + } +} diff --git a/src/services/AStar.Dev.Usage.Logger/astar.ico b/src/services/AStar.Dev.Usage.Logger/astar.ico new file mode 100644 index 0000000..38b6709 Binary files /dev/null and b/src/services/AStar.Dev.Usage.Logger/astar.ico differ diff --git a/src/services/AStar.Dev.Usage.Logger/wwwroot/swagger-ui/SwaggerDark.css b/src/services/AStar.Dev.Usage.Logger/wwwroot/swagger-ui/SwaggerDark.css new file mode 100644 index 0000000..e86f2c2 --- /dev/null +++ b/src/services/AStar.Dev.Usage.Logger/wwwroot/swagger-ui/SwaggerDark.css @@ -0,0 +1,1359 @@ +@media only screen and (prefers-color-scheme: dark) { + + a { + color: #8c8cfa; + } + + ::-webkit-scrollbar-track-piece { + background-color: rgba(255, 255, 255, .2) !important; + } + + ::-webkit-scrollbar-track { + background-color: rgba(255, 255, 255, .3) !important; + } + + ::-webkit-scrollbar-thumb { + background-color: rgba(255, 255, 255, .5) !important; + } + + embed[type="application/pdf"] { + filter: invert(90%); + } + + html { + background: #1f1f1f !important; + box-sizing: border-box; + filter: contrast(100%) brightness(100%) saturate(100%); + overflow-y: scroll; + } + + body { + background: #1f1f1f; + background-color: #1f1f1f; + background-image: none !important; + } + + button, input, select, textarea { + background-color: #1f1f1f; + color: #bfbfbf; + } + + font, html { + color: #bfbfbf; + } + + .swagger-ui, .swagger-ui section h3 { + color: #b5bac9; + } + + .swagger-ui a { + background-color: transparent; + } + + .swagger-ui mark { + background-color: #664b00; + color: #bfbfbf; + } + + .swagger-ui legend { + color: inherit; + } + + .swagger-ui .debug * { + outline: #e6da99 solid 1px; + } + + .swagger-ui .debug-white * { + outline: #fff solid 1px; + } + + .swagger-ui .debug-black * { + outline: #bfbfbf solid 1px; + } + + .swagger-ui .debug-grid { + background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAICAYAAADED76LAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyhpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuNi1jMTExIDc5LjE1ODMyNSwgMjAxNS8wOS8xMC0wMToxMDoyMCAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wTU09Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9tbS8iIHhtbG5zOnN0UmVmPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VSZWYjIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6MTRDOTY4N0U2N0VFMTFFNjg2MzZDQjkwNkQ4MjgwMEIiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6MTRDOTY4N0Q2N0VFMTFFNjg2MzZDQjkwNkQ4MjgwMEIiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENDIDIwMTUgKE1hY2ludG9zaCkiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDo3NjcyQkQ3NjY3QzUxMUU2QjJCQ0UyNDA4MTAwMjE3MSIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDo3NjcyQkQ3NzY3QzUxMUU2QjJCQ0UyNDA4MTAwMjE3MSIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/PsBS+GMAAAAjSURBVHjaYvz//z8DLsD4gcGXiYEAGBIKGBne//fFpwAgwAB98AaF2pjlUQAAAABJRU5ErkJggg==) 0 0; + } + + .swagger-ui .debug-grid-16 { + background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyhpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuNi1jMTExIDc5LjE1ODMyNSwgMjAxNS8wOS8xMC0wMToxMDoyMCAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wTU09Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9tbS8iIHhtbG5zOnN0UmVmPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VSZWYjIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6ODYyRjhERDU2N0YyMTFFNjg2MzZDQjkwNkQ4MjgwMEIiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6ODYyRjhERDQ2N0YyMTFFNjg2MzZDQjkwNkQ4MjgwMEIiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENDIDIwMTUgKE1hY2ludG9zaCkiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDo3NjcyQkQ3QTY3QzUxMUU2QjJCQ0UyNDA4MTAwMjE3MSIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDo3NjcyQkQ3QjY3QzUxMUU2QjJCQ0UyNDA4MTAwMjE3MSIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/PvCS01IAAABMSURBVHjaYmR4/5+BFPBfAMFm/MBgx8RAGWCn1AAmSg34Q6kBDKMGMDCwICeMIemF/5QawEipAWwUhwEjMDvbAWlWkvVBwu8vQIABAEwBCph8U6c0AAAAAElFTkSuQmCC) 0 0; + } + + .swagger-ui .debug-grid-8-solid { + background: url(data:image/jpeg;base64,/9j/4QAYRXhpZgAASUkqAAgAAAAAAAAAAAAAAP/sABFEdWNreQABAAQAAAAAAAD/4QMxaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wLwA8P3hwYWNrZXQgYmVnaW49Iu+7vyIgaWQ9Ilc1TTBNcENlaGlIenJlU3pOVGN6a2M5ZCI/PiA8eDp4bXBtZXRhIHhtbG5zOng9ImFkb2JlOm5zOm1ldGEvIiB4OnhtcHRrPSJBZG9iZSBYTVAgQ29yZSA1LjYtYzExMSA3OS4xNTgzMjUsIDIwMTUvMDkvMTAtMDE6MTA6MjAgICAgICAgICI+IDxyZGY6UkRGIHhtbG5zOnJkZj0iaHR0cDovL3d3dy53My5vcmcvMTk5OS8wMi8yMi1yZGYtc3ludGF4LW5zIyI+IDxyZGY6RGVzY3JpcHRpb24gcmRmOmFib3V0PSIiIHhtbG5zOnhtcD0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wLyIgeG1sbnM6eG1wTU09Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9tbS8iIHhtbG5zOnN0UmVmPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VSZWYjIiB4bXA6Q3JlYXRvclRvb2w9IkFkb2JlIFBob3Rvc2hvcCBDQyAyMDE1IChNYWNpbnRvc2gpIiB4bXBNTTpJbnN0YW5jZUlEPSJ4bXAuaWlkOkIxMjI0OTczNjdCMzExRTZCMkJDRTI0MDgxMDAyMTcxIiB4bXBNTTpEb2N1bWVudElEPSJ4bXAuZGlkOkIxMjI0OTc0NjdCMzExRTZCMkJDRTI0MDgxMDAyMTcxIj4gPHhtcE1NOkRlcml2ZWRGcm9tIHN0UmVmOmluc3RhbmNlSUQ9InhtcC5paWQ6QjEyMjQ5NzE2N0IzMTFFNkIyQkNFMjQwODEwMDIxNzEiIHN0UmVmOmRvY3VtZW50SUQ9InhtcC5kaWQ6QjEyMjQ5NzI2N0IzMTFFNkIyQkNFMjQwODEwMDIxNzEiLz4gPC9yZGY6RGVzY3JpcHRpb24+IDwvcmRmOlJERj4gPC94OnhtcG1ldGE+IDw/eHBhY2tldCBlbmQ9InIiPz7/7gAOQWRvYmUAZMAAAAAB/9sAhAAbGhopHSlBJiZBQi8vL0JHPz4+P0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHAR0pKTQmND8oKD9HPzU/R0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0f/wAARCAAIAAgDASIAAhEBAxEB/8QAWQABAQAAAAAAAAAAAAAAAAAAAAYBAQEAAAAAAAAAAAAAAAAAAAIEEAEBAAMBAAAAAAAAAAAAAAABADECA0ERAAEDBQAAAAAAAAAAAAAAAAARITFBUWESIv/aAAwDAQACEQMRAD8AoOnTV1QTD7JJshP3vSM3P//Z) 0 0 #1c1c21; + } + + .swagger-ui .debug-grid-16-solid { + background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAIAAACQkWg2AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyhpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuNi1jMTExIDc5LjE1ODMyNSwgMjAxNS8wOS8xMC0wMToxMDoyMCAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENDIDIwMTUgKE1hY2ludG9zaCkiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6NzY3MkJEN0U2N0M1MTFFNkIyQkNFMjQwODEwMDIxNzEiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6NzY3MkJEN0Y2N0M1MTFFNkIyQkNFMjQwODEwMDIxNzEiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDo3NjcyQkQ3QzY3QzUxMUU2QjJCQ0UyNDA4MTAwMjE3MSIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDo3NjcyQkQ3RDY3QzUxMUU2QjJCQ0UyNDA4MTAwMjE3MSIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/Pve6J3kAAAAzSURBVHjaYvz//z8D0UDsMwMjSRoYP5Gq4SPNbRjVMEQ1fCRDg+in/6+J1AJUxsgAEGAA31BAJMS0GYEAAAAASUVORK5CYII=) 0 0 #1c1c21; + } + + .swagger-ui .b--black { + border-color: #000; + } + + .swagger-ui .b--near-black { + border-color: #121212; + } + + .swagger-ui .b--dark-gray { + border-color: #333; + } + + .swagger-ui .b--mid-gray { + border-color: #545454; + } + + .swagger-ui .b--gray { + border-color: #787878; + } + + .swagger-ui .b--silver { + border-color: #999; + } + + .swagger-ui .b--light-silver { + border-color: #6e6e6e; + } + + .swagger-ui .b--moon-gray { + border-color: #4d4d4d; + } + + .swagger-ui .b--light-gray { + border-color: #2b2b2b; + } + + .swagger-ui .b--near-white { + border-color: #242424; + } + + .swagger-ui .b--white { + border-color: #1c1c21; + } + + .swagger-ui .b--white-90 { + border-color: rgba(28, 28, 33, .9); + } + + .swagger-ui .b--white-80 { + border-color: rgba(28, 28, 33, .8); + } + + .swagger-ui .b--white-70 { + border-color: rgba(28, 28, 33, .7); + } + + .swagger-ui .b--white-60 { + border-color: rgba(28, 28, 33, .6); + } + + .swagger-ui .b--white-50 { + border-color: rgba(28, 28, 33, .5); + } + + .swagger-ui .b--white-40 { + border-color: rgba(28, 28, 33, .4); + } + + .swagger-ui .b--white-30 { + border-color: rgba(28, 28, 33, .3); + } + + .swagger-ui .b--white-20 { + border-color: rgba(28, 28, 33, .2); + } + + .swagger-ui .b--white-10 { + border-color: rgba(28, 28, 33, .1); + } + + .swagger-ui .b--white-05 { + border-color: rgba(28, 28, 33, .05); + } + + .swagger-ui .b--white-025 { + border-color: rgba(28, 28, 33, .024); + } + + .swagger-ui .b--white-0125 { + border-color: rgba(28, 28, 33, .01); + } + + .swagger-ui .b--black-90 { + border-color: rgba(0, 0, 0, .9); + } + + .swagger-ui .b--black-80 { + border-color: rgba(0, 0, 0, .8); + } + + .swagger-ui .b--black-70 { + border-color: rgba(0, 0, 0, .7); + } + + .swagger-ui .b--black-60 { + border-color: rgba(0, 0, 0, .6); + } + + .swagger-ui .b--black-50 { + border-color: rgba(0, 0, 0, .5); + } + + .swagger-ui .b--black-40 { + border-color: rgba(0, 0, 0, .4); + } + + .swagger-ui .b--black-30 { + border-color: rgba(0, 0, 0, .3); + } + + .swagger-ui .b--black-20 { + border-color: rgba(0, 0, 0, .2); + } + + .swagger-ui .b--black-10 { + border-color: rgba(0, 0, 0, .1); + } + + .swagger-ui .b--black-05 { + border-color: rgba(0, 0, 0, .05); + } + + .swagger-ui .b--black-025 { + border-color: rgba(0, 0, 0, .024); + } + + .swagger-ui .b--black-0125 { + border-color: rgba(0, 0, 0, .01); + } + + .swagger-ui .b--dark-red { + border-color: #bc2f36; + } + + .swagger-ui .b--red { + border-color: #c83932; + } + + .swagger-ui .b--light-red { + border-color: #ab3c2b; + } + + .swagger-ui .b--orange { + border-color: #cc6e33; + } + + .swagger-ui .b--purple { + border-color: #5e2ca5; + } + + .swagger-ui .b--light-purple { + border-color: #672caf; + } + + .swagger-ui .b--dark-pink { + border-color: #ab2b81; + } + + .swagger-ui .b--hot-pink { + border-color: #c03086; + } + + .swagger-ui .b--pink { + border-color: #8f2464; + } + + .swagger-ui .b--light-pink { + border-color: #721d4d; + } + + .swagger-ui .b--dark-green { + border-color: #1c6e50; + } + + .swagger-ui .b--green { + border-color: #279b70; + } + + .swagger-ui .b--light-green { + border-color: #228762; + } + + .swagger-ui .b--navy { + border-color: #0d1d35; + } + + .swagger-ui .b--dark-blue { + border-color: #20497e; + } + + .swagger-ui .b--blue { + border-color: #4380d0; + } + + .swagger-ui .b--light-blue { + border-color: #20517e; + } + + .swagger-ui .b--lightest-blue { + border-color: #143a52; + } + + .swagger-ui .b--washed-blue { + border-color: #0c312d; + } + + .swagger-ui .b--washed-green { + border-color: #0f3d2c; + } + + .swagger-ui .b--washed-red { + border-color: #411010; + } + + .swagger-ui .b--transparent { + border-color: transparent; + } + + .swagger-ui .b--gold, .swagger-ui .b--light-yellow, .swagger-ui .b--washed-yellow, .swagger-ui .b--yellow { + border-color: #664b00; + } + + .swagger-ui .shadow-1 { + box-shadow: rgba(0, 0, 0, .2) 0 0 4px 2px; + } + + .swagger-ui .shadow-2 { + box-shadow: rgba(0, 0, 0, .2) 0 0 8px 2px; + } + + .swagger-ui .shadow-3 { + box-shadow: rgba(0, 0, 0, .2) 2px 2px 4px 2px; + } + + .swagger-ui .shadow-4 { + box-shadow: rgba(0, 0, 0, .2) 2px 2px 8px 0; + } + + .swagger-ui .shadow-5 { + box-shadow: rgba(0, 0, 0, .2) 4px 4px 8px 0; + } + + @media screen and (min-width: 30em) { + .swagger-ui .shadow-1-ns { + box-shadow: rgba(0, 0, 0, .2) 0 0 4px 2px; + } + + .swagger-ui .shadow-2-ns { + box-shadow: rgba(0, 0, 0, .2) 0 0 8px 2px; + } + + .swagger-ui .shadow-3-ns { + box-shadow: rgba(0, 0, 0, .2) 2px 2px 4px 2px; + } + + .swagger-ui .shadow-4-ns { + box-shadow: rgba(0, 0, 0, .2) 2px 2px 8px 0; + } + + .swagger-ui .shadow-5-ns { + box-shadow: rgba(0, 0, 0, .2) 4px 4px 8px 0; + } + } + + @media screen and (max-width: 60em) and (min-width: 30em) { + .swagger-ui .shadow-1-m { + box-shadow: rgba(0, 0, 0, .2) 0 0 4px 2px; + } + + .swagger-ui .shadow-2-m { + box-shadow: rgba(0, 0, 0, .2) 0 0 8px 2px; + } + + .swagger-ui .shadow-3-m { + box-shadow: rgba(0, 0, 0, .2) 2px 2px 4px 2px; + } + + .swagger-ui .shadow-4-m { + box-shadow: rgba(0, 0, 0, .2) 2px 2px 8px 0; + } + + .swagger-ui .shadow-5-m { + box-shadow: rgba(0, 0, 0, .2) 4px 4px 8px 0; + } + } + + @media screen and (min-width: 60em) { + .swagger-ui .shadow-1-l { + box-shadow: rgba(0, 0, 0, .2) 0 0 4px 2px; + } + + .swagger-ui .shadow-2-l { + box-shadow: rgba(0, 0, 0, .2) 0 0 8px 2px; + } + + .swagger-ui .shadow-3-l { + box-shadow: rgba(0, 0, 0, .2) 2px 2px 4px 2px; + } + + .swagger-ui .shadow-4-l { + box-shadow: rgba(0, 0, 0, .2) 2px 2px 8px 0; + } + + .swagger-ui .shadow-5-l { + box-shadow: rgba(0, 0, 0, .2) 4px 4px 8px 0; + } + } + + .swagger-ui .black-05 { + color: rgba(191, 191, 191, .05); + } + + .swagger-ui .bg-black-05 { + background-color: rgba(0, 0, 0, .05); + } + + .swagger-ui .black-90, .swagger-ui .hover-black-90:focus, .swagger-ui .hover-black-90:hover { + color: rgba(191, 191, 191, .9); + } + + .swagger-ui .black-80, .swagger-ui .hover-black-80:focus, .swagger-ui .hover-black-80:hover { + color: rgba(191, 191, 191, .8); + } + + .swagger-ui .black-70, .swagger-ui .hover-black-70:focus, .swagger-ui .hover-black-70:hover { + color: rgba(191, 191, 191, .7); + } + + .swagger-ui .black-60, .swagger-ui .hover-black-60:focus, .swagger-ui .hover-black-60:hover { + color: rgba(191, 191, 191, .6); + } + + .swagger-ui .black-50, .swagger-ui .hover-black-50:focus, .swagger-ui .hover-black-50:hover { + color: rgba(191, 191, 191, .5); + } + + .swagger-ui .black-40, .swagger-ui .hover-black-40:focus, .swagger-ui .hover-black-40:hover { + color: rgba(191, 191, 191, .4); + } + + .swagger-ui .black-30, .swagger-ui .hover-black-30:focus, .swagger-ui .hover-black-30:hover { + color: rgba(191, 191, 191, .3); + } + + .swagger-ui .black-20, .swagger-ui .hover-black-20:focus, .swagger-ui .hover-black-20:hover { + color: rgba(191, 191, 191, .2); + } + + .swagger-ui .black-10, .swagger-ui .hover-black-10:focus, .swagger-ui .hover-black-10:hover { + color: rgba(191, 191, 191, .1); + } + + .swagger-ui .hover-white-90:focus, .swagger-ui .hover-white-90:hover, .swagger-ui .white-90 { + color: rgba(255, 255, 255, .9); + } + + .swagger-ui .hover-white-80:focus, .swagger-ui .hover-white-80:hover, .swagger-ui .white-80 { + color: rgba(255, 255, 255, .8); + } + + .swagger-ui .hover-white-70:focus, .swagger-ui .hover-white-70:hover, .swagger-ui .white-70 { + color: rgba(255, 255, 255, .7); + } + + .swagger-ui .hover-white-60:focus, .swagger-ui .hover-white-60:hover, .swagger-ui .white-60 { + color: rgba(255, 255, 255, .6); + } + + .swagger-ui .hover-white-50:focus, .swagger-ui .hover-white-50:hover, .swagger-ui .white-50 { + color: rgba(255, 255, 255, .5); + } + + .swagger-ui .hover-white-40:focus, .swagger-ui .hover-white-40:hover, .swagger-ui .white-40 { + color: rgba(255, 255, 255, .4); + } + + .swagger-ui .hover-white-30:focus, .swagger-ui .hover-white-30:hover, .swagger-ui .white-30 { + color: rgba(255, 255, 255, .3); + } + + .swagger-ui .hover-white-20:focus, .swagger-ui .hover-white-20:hover, .swagger-ui .white-20 { + color: rgba(255, 255, 255, .2); + } + + .swagger-ui .hover-white-10:focus, .swagger-ui .hover-white-10:hover, .swagger-ui .white-10 { + color: rgba(255, 255, 255, .1); + } + + .swagger-ui .hover-moon-gray:focus, .swagger-ui .hover-moon-gray:hover, .swagger-ui .moon-gray { + color: #ccc; + } + + .swagger-ui .hover-light-gray:focus, .swagger-ui .hover-light-gray:hover, .swagger-ui .light-gray { + color: #ededed; + } + + .swagger-ui .hover-near-white:focus, .swagger-ui .hover-near-white:hover, .swagger-ui .near-white { + color: #f5f5f5; + } + + .swagger-ui .dark-red, .swagger-ui .hover-dark-red:focus, .swagger-ui .hover-dark-red:hover { + color: #e6999d; + } + + .swagger-ui .hover-red:focus, .swagger-ui .hover-red:hover, .swagger-ui .red { + color: #e69d99; + } + + .swagger-ui .hover-light-red:focus, .swagger-ui .hover-light-red:hover, .swagger-ui .light-red { + color: #e6a399; + } + + .swagger-ui .hover-orange:focus, .swagger-ui .hover-orange:hover, .swagger-ui .orange { + color: #e6b699; + } + + .swagger-ui .gold, .swagger-ui .hover-gold:focus, .swagger-ui .hover-gold:hover { + color: #e6d099; + } + + .swagger-ui .hover-yellow:focus, .swagger-ui .hover-yellow:hover, .swagger-ui .yellow { + color: #e6da99; + } + + .swagger-ui .hover-light-yellow:focus, .swagger-ui .hover-light-yellow:hover, .swagger-ui .light-yellow { + color: #ede6b6; + } + + .swagger-ui .hover-purple:focus, .swagger-ui .hover-purple:hover, .swagger-ui .purple { + color: #b99ae4; + } + + .swagger-ui .hover-light-purple:focus, .swagger-ui .hover-light-purple:hover, .swagger-ui .light-purple { + color: #bb99e6; + } + + .swagger-ui .dark-pink, .swagger-ui .hover-dark-pink:focus, .swagger-ui .hover-dark-pink:hover { + color: #e699cc; + } + + .swagger-ui .hot-pink, .swagger-ui .hover-hot-pink:focus, .swagger-ui .hover-hot-pink:hover, .swagger-ui .hover-pink:focus, .swagger-ui .hover-pink:hover, .swagger-ui .pink { + color: #e699c7; + } + + .swagger-ui .hover-light-pink:focus, .swagger-ui .hover-light-pink:hover, .swagger-ui .light-pink { + color: #edb6d5; + } + + .swagger-ui .dark-green, .swagger-ui .green, .swagger-ui .hover-dark-green:focus, .swagger-ui .hover-dark-green:hover, .swagger-ui .hover-green:focus, .swagger-ui .hover-green:hover { + color: #99e6c9; + } + + .swagger-ui .hover-light-green:focus, .swagger-ui .hover-light-green:hover, .swagger-ui .light-green { + color: #a1e8ce; + } + + .swagger-ui .hover-navy:focus, .swagger-ui .hover-navy:hover, .swagger-ui .navy { + color: #99b8e6; + } + + .swagger-ui .blue, .swagger-ui .dark-blue, .swagger-ui .hover-blue:focus, .swagger-ui .hover-blue:hover, .swagger-ui .hover-dark-blue:focus, .swagger-ui .hover-dark-blue:hover { + color: #99bae6; + } + + .swagger-ui .hover-light-blue:focus, .swagger-ui .hover-light-blue:hover, .swagger-ui .light-blue { + color: #a9cbea; + } + + .swagger-ui .hover-lightest-blue:focus, .swagger-ui .hover-lightest-blue:hover, .swagger-ui .lightest-blue { + color: #d6e9f5; + } + + .swagger-ui .hover-washed-blue:focus, .swagger-ui .hover-washed-blue:hover, .swagger-ui .washed-blue { + color: #f7fdfc; + } + + .swagger-ui .hover-washed-green:focus, .swagger-ui .hover-washed-green:hover, .swagger-ui .washed-green { + color: #ebfaf4; + } + + .swagger-ui .hover-washed-yellow:focus, .swagger-ui .hover-washed-yellow:hover, .swagger-ui .washed-yellow { + color: #fbf9ef; + } + + .swagger-ui .hover-washed-red:focus, .swagger-ui .hover-washed-red:hover, .swagger-ui .washed-red { + color: #f9e7e7; + } + + .swagger-ui .color-inherit, .swagger-ui .hover-inherit:focus, .swagger-ui .hover-inherit:hover { + color: inherit; + } + + .swagger-ui .bg-black-90, .swagger-ui .hover-bg-black-90:focus, .swagger-ui .hover-bg-black-90:hover { + background-color: rgba(0, 0, 0, .9); + } + + .swagger-ui .bg-black-80, .swagger-ui .hover-bg-black-80:focus, .swagger-ui .hover-bg-black-80:hover { + background-color: rgba(0, 0, 0, .8); + } + + .swagger-ui .bg-black-70, .swagger-ui .hover-bg-black-70:focus, .swagger-ui .hover-bg-black-70:hover { + background-color: rgba(0, 0, 0, .7); + } + + .swagger-ui .bg-black-60, .swagger-ui .hover-bg-black-60:focus, .swagger-ui .hover-bg-black-60:hover { + background-color: rgba(0, 0, 0, .6); + } + + .swagger-ui .bg-black-50, .swagger-ui .hover-bg-black-50:focus, .swagger-ui .hover-bg-black-50:hover { + background-color: rgba(0, 0, 0, .5); + } + + .swagger-ui .bg-black-40, .swagger-ui .hover-bg-black-40:focus, .swagger-ui .hover-bg-black-40:hover { + background-color: rgba(0, 0, 0, .4); + } + + .swagger-ui .bg-black-30, .swagger-ui .hover-bg-black-30:focus, .swagger-ui .hover-bg-black-30:hover { + background-color: rgba(0, 0, 0, .3); + } + + .swagger-ui .bg-black-20, .swagger-ui .hover-bg-black-20:focus, .swagger-ui .hover-bg-black-20:hover { + background-color: rgba(0, 0, 0, .2); + } + + .swagger-ui .bg-white-90, .swagger-ui .hover-bg-white-90:focus, .swagger-ui .hover-bg-white-90:hover { + background-color: rgba(28, 28, 33, .9); + } + + .swagger-ui .bg-white-80, .swagger-ui .hover-bg-white-80:focus, .swagger-ui .hover-bg-white-80:hover { + background-color: rgba(28, 28, 33, .8); + } + + .swagger-ui .bg-white-70, .swagger-ui .hover-bg-white-70:focus, .swagger-ui .hover-bg-white-70:hover { + background-color: rgba(28, 28, 33, .7); + } + + .swagger-ui .bg-white-60, .swagger-ui .hover-bg-white-60:focus, .swagger-ui .hover-bg-white-60:hover { + background-color: rgba(28, 28, 33, .6); + } + + .swagger-ui .bg-white-50, .swagger-ui .hover-bg-white-50:focus, .swagger-ui .hover-bg-white-50:hover { + background-color: rgba(28, 28, 33, .5); + } + + .swagger-ui .bg-white-40, .swagger-ui .hover-bg-white-40:focus, .swagger-ui .hover-bg-white-40:hover { + background-color: rgba(28, 28, 33, .4); + } + + .swagger-ui .bg-white-30, .swagger-ui .hover-bg-white-30:focus, .swagger-ui .hover-bg-white-30:hover { + background-color: rgba(28, 28, 33, .3); + } + + .swagger-ui .bg-white-20, .swagger-ui .hover-bg-white-20:focus, .swagger-ui .hover-bg-white-20:hover { + background-color: rgba(28, 28, 33, .2); + } + + .swagger-ui .bg-black, .swagger-ui .hover-bg-black:focus, .swagger-ui .hover-bg-black:hover { + background-color: #000; + } + + .swagger-ui .bg-near-black, .swagger-ui .hover-bg-near-black:focus, .swagger-ui .hover-bg-near-black:hover { + background-color: #121212; + } + + .swagger-ui .bg-dark-gray, .swagger-ui .hover-bg-dark-gray:focus, .swagger-ui .hover-bg-dark-gray:hover { + background-color: #333; + } + + .swagger-ui .bg-mid-gray, .swagger-ui .hover-bg-mid-gray:focus, .swagger-ui .hover-bg-mid-gray:hover { + background-color: #545454; + } + + .swagger-ui .bg-gray, .swagger-ui .hover-bg-gray:focus, .swagger-ui .hover-bg-gray:hover { + background-color: #787878; + } + + .swagger-ui .bg-silver, .swagger-ui .hover-bg-silver:focus, .swagger-ui .hover-bg-silver:hover { + background-color: #999; + } + + .swagger-ui .bg-white, .swagger-ui .hover-bg-white:focus, .swagger-ui .hover-bg-white:hover { + background-color: #1c1c21; + } + + .swagger-ui .bg-transparent, .swagger-ui .hover-bg-transparent:focus, .swagger-ui .hover-bg-transparent:hover { + background-color: transparent; + } + + .swagger-ui .bg-dark-red, .swagger-ui .hover-bg-dark-red:focus, .swagger-ui .hover-bg-dark-red:hover { + background-color: #bc2f36; + } + + .swagger-ui .bg-red, .swagger-ui .hover-bg-red:focus, .swagger-ui .hover-bg-red:hover { + background-color: #c83932; + } + + .swagger-ui .bg-light-red, .swagger-ui .hover-bg-light-red:focus, .swagger-ui .hover-bg-light-red:hover { + background-color: #ab3c2b; + } + + .swagger-ui .bg-orange, .swagger-ui .hover-bg-orange:focus, .swagger-ui .hover-bg-orange:hover { + background-color: #cc6e33; + } + + .swagger-ui .bg-gold, .swagger-ui .bg-light-yellow, .swagger-ui .bg-washed-yellow, .swagger-ui .bg-yellow, .swagger-ui .hover-bg-gold:focus, .swagger-ui .hover-bg-gold:hover, .swagger-ui .hover-bg-light-yellow:focus, .swagger-ui .hover-bg-light-yellow:hover, .swagger-ui .hover-bg-washed-yellow:focus, .swagger-ui .hover-bg-washed-yellow:hover, .swagger-ui .hover-bg-yellow:focus, .swagger-ui .hover-bg-yellow:hover { + background-color: #664b00; + } + + .swagger-ui .bg-purple, .swagger-ui .hover-bg-purple:focus, .swagger-ui .hover-bg-purple:hover { + background-color: #5e2ca5; + } + + .swagger-ui .bg-light-purple, .swagger-ui .hover-bg-light-purple:focus, .swagger-ui .hover-bg-light-purple:hover { + background-color: #672caf; + } + + .swagger-ui .bg-dark-pink, .swagger-ui .hover-bg-dark-pink:focus, .swagger-ui .hover-bg-dark-pink:hover { + background-color: #ab2b81; + } + + .swagger-ui .bg-hot-pink, .swagger-ui .hover-bg-hot-pink:focus, .swagger-ui .hover-bg-hot-pink:hover { + background-color: #c03086; + } + + .swagger-ui .bg-pink, .swagger-ui .hover-bg-pink:focus, .swagger-ui .hover-bg-pink:hover { + background-color: #8f2464; + } + + .swagger-ui .bg-light-pink, .swagger-ui .hover-bg-light-pink:focus, .swagger-ui .hover-bg-light-pink:hover { + background-color: #721d4d; + } + + .swagger-ui .bg-dark-green, .swagger-ui .hover-bg-dark-green:focus, .swagger-ui .hover-bg-dark-green:hover { + background-color: #1c6e50; + } + + .swagger-ui .bg-green, .swagger-ui .hover-bg-green:focus, .swagger-ui .hover-bg-green:hover { + background-color: #279b70; + } + + .swagger-ui .bg-light-green, .swagger-ui .hover-bg-light-green:focus, .swagger-ui .hover-bg-light-green:hover { + background-color: #228762; + } + + .swagger-ui .bg-navy, .swagger-ui .hover-bg-navy:focus, .swagger-ui .hover-bg-navy:hover { + background-color: #0d1d35; + } + + .swagger-ui .bg-dark-blue, .swagger-ui .hover-bg-dark-blue:focus, .swagger-ui .hover-bg-dark-blue:hover { + background-color: #20497e; + } + + .swagger-ui .bg-blue, .swagger-ui .hover-bg-blue:focus, .swagger-ui .hover-bg-blue:hover { + background-color: #4380d0; + } + + .swagger-ui .bg-light-blue, .swagger-ui .hover-bg-light-blue:focus, .swagger-ui .hover-bg-light-blue:hover { + background-color: #20517e; + } + + .swagger-ui .bg-lightest-blue, .swagger-ui .hover-bg-lightest-blue:focus, .swagger-ui .hover-bg-lightest-blue:hover { + background-color: #143a52; + } + + .swagger-ui .bg-washed-blue, .swagger-ui .hover-bg-washed-blue:focus, .swagger-ui .hover-bg-washed-blue:hover { + background-color: #0c312d; + } + + .swagger-ui .bg-washed-green, .swagger-ui .hover-bg-washed-green:focus, .swagger-ui .hover-bg-washed-green:hover { + background-color: #0f3d2c; + } + + .swagger-ui .bg-washed-red, .swagger-ui .hover-bg-washed-red:focus, .swagger-ui .hover-bg-washed-red:hover { + background-color: #411010; + } + + .swagger-ui .bg-inherit, .swagger-ui .hover-bg-inherit:focus, .swagger-ui .hover-bg-inherit:hover { + background-color: inherit; + } + + .swagger-ui .shadow-hover { + transition: all .5s cubic-bezier(.165, .84, .44, 1) 0s; + } + + .swagger-ui .shadow-hover::after { + border-radius: inherit; + box-shadow: rgba(0, 0, 0, .2) 0 0 16px 2px; + content: ""; + height: 100%; + left: 0; + opacity: 0; + position: absolute; + top: 0; + transition: opacity .5s cubic-bezier(.165, .84, .44, 1) 0s; + width: 100%; + z-index: -1; + } + + .swagger-ui .bg-animate, .swagger-ui .bg-animate:focus, .swagger-ui .bg-animate:hover { + transition: background-color .15s ease-in-out 0s; + } + + .swagger-ui .nested-links a { + color: #99bae6; + transition: color .15s ease-in 0s; + } + + .swagger-ui .nested-links a:focus, .swagger-ui .nested-links a:hover { + color: #a9cbea; + transition: color .15s ease-in 0s; + } + + .swagger-ui .opblock-tag { + border-bottom: 1px solid rgba(58, 64, 80, .3); + color: #b5bac9; + transition: all .2s ease 0s; + } + + .swagger-ui .opblock-tag svg, .swagger-ui section.models h4 svg { + transition: all .4s ease 0s; + } + + .swagger-ui .opblock { + border: 1px solid #000; + border-radius: 4px; + box-shadow: rgba(0, 0, 0, .19) 0 0 3px; + margin: 0 0 15px; + } + + .swagger-ui .opblock .tab-header .tab-item.active h4 span::after { + background: gray; + } + + .swagger-ui .opblock.is-open .opblock-summary { + border-bottom: 1px solid #000; + } + + .swagger-ui .opblock .opblock-section-header { + background: rgba(28, 28, 33, .8); + box-shadow: rgba(0, 0, 0, .1) 0 1px 2px; + } + + .swagger-ui .opblock .opblock-section-header > label > span { + padding: 0 10px 0 0; + } + + .swagger-ui .opblock .opblock-summary-method { + background: #000; + color: #fff; + text-shadow: rgba(0, 0, 0, .1) 0 1px 0; + } + + .swagger-ui .opblock.opblock-post { + background: rgba(72, 203, 144, .1); + border-color: #48cb90; + } + + .swagger-ui .opblock.opblock-post .opblock-summary-method, .swagger-ui .opblock.opblock-post .tab-header .tab-item.active h4 span::after { + background: #48cb90; + } + + .swagger-ui .opblock.opblock-post .opblock-summary { + border-color: #48cb90; + } + + .swagger-ui .opblock.opblock-put { + background: rgba(213, 157, 88, .1); + border-color: #d59d58; + } + + .swagger-ui .opblock.opblock-put .opblock-summary-method, .swagger-ui .opblock.opblock-put .tab-header .tab-item.active h4 span::after { + background: #d59d58; + } + + .swagger-ui .opblock.opblock-put .opblock-summary { + border-color: #d59d58; + } + + .swagger-ui .opblock.opblock-delete { + background: rgba(200, 50, 50, .1); + border-color: #c83232; + } + + .swagger-ui .opblock.opblock-delete .opblock-summary-method, .swagger-ui .opblock.opblock-delete .tab-header .tab-item.active h4 span::after { + background: #c83232; + } + + .swagger-ui .opblock.opblock-delete .opblock-summary { + border-color: #c83232; + } + + .swagger-ui .opblock.opblock-get { + background: rgba(42, 105, 167, .1); + border-color: #2a69a7; + } + + .swagger-ui .opblock.opblock-get .opblock-summary-method, .swagger-ui .opblock.opblock-get .tab-header .tab-item.active h4 span::after { + background: #2a69a7; + } + + .swagger-ui .opblock.opblock-get .opblock-summary { + border-color: #2a69a7; + } + + .swagger-ui .opblock.opblock-patch { + background: rgba(92, 214, 188, .1); + border-color: #5cd6bc; + } + + .swagger-ui .opblock.opblock-patch .opblock-summary-method, .swagger-ui .opblock.opblock-patch .tab-header .tab-item.active h4 span::after { + background: #5cd6bc; + } + + .swagger-ui .opblock.opblock-patch .opblock-summary { + border-color: #5cd6bc; + } + + .swagger-ui .opblock.opblock-head { + background: rgba(140, 63, 207, .1); + border-color: #8c3fcf; + } + + .swagger-ui .opblock.opblock-head .opblock-summary-method, .swagger-ui .opblock.opblock-head .tab-header .tab-item.active h4 span::after { + background: #8c3fcf; + } + + .swagger-ui .opblock.opblock-head .opblock-summary { + border-color: #8c3fcf; + } + + .swagger-ui .opblock.opblock-options { + background: rgba(36, 89, 143, .1); + border-color: #24598f; + } + + .swagger-ui .opblock.opblock-options .opblock-summary-method, .swagger-ui .opblock.opblock-options .tab-header .tab-item.active h4 span::after { + background: #24598f; + } + + .swagger-ui .opblock.opblock-options .opblock-summary { + border-color: #24598f; + } + + .swagger-ui .opblock.opblock-deprecated { + background: rgba(46, 46, 46, .1); + border-color: #2e2e2e; + opacity: .6; + } + + .swagger-ui .opblock.opblock-deprecated .opblock-summary-method, .swagger-ui .opblock.opblock-deprecated .tab-header .tab-item.active h4 span::after { + background: #2e2e2e; + } + + .swagger-ui .opblock.opblock-deprecated .opblock-summary { + border-color: #2e2e2e; + } + + .swagger-ui .filter .operation-filter-input { + border: 2px solid #2b3446; + } + + .swagger-ui .tab li:first-of-type::after { + background: rgba(0, 0, 0, .2); + } + + .swagger-ui .download-contents { + background: #7c8192; + color: #fff; + } + + .swagger-ui .scheme-container { + background: #1c1c21; + box-shadow: rgba(0, 0, 0, .15) 0 1px 2px 0; + } + + .swagger-ui .loading-container .loading::before { + animation: 1s linear 0s infinite normal none running rotation, .5s ease 0s 1 normal none running opacity; + border-color: rgba(0, 0, 0, .6) rgba(84, 84, 84, .1) rgba(84, 84, 84, .1); + } + + .swagger-ui .response-control-media-type--accept-controller select { + border-color: #196619; + } + + .swagger-ui .response-control-media-type__accept-message { + color: #99e699; + } + + .swagger-ui .version-pragma__message code { + background-color: #3b3b3b; + } + + .swagger-ui .btn { + background: 0 0; + border: 2px solid gray; + box-shadow: rgba(0, 0, 0, .1) 0 1px 2px; + color: #b5bac9; + } + + .swagger-ui .btn:hover { + box-shadow: rgba(0, 0, 0, .3) 0 0 5px; + } + + .swagger-ui .btn.authorize, .swagger-ui .btn.cancel { + background-color: transparent; + border-color: #a72a2a; + color: #e69999; + } + + .swagger-ui .btn.cancel:hover { + background-color: #a72a2a; + color: #fff; + } + + .swagger-ui .btn.authorize { + border-color: #48cb90; + color: #9ce3c3; + } + + .swagger-ui .btn.authorize svg { + fill: #9ce3c3; + } + + .btn.authorize.unlocked:hover { + background-color: #48cb90; + color: #fff; + } + + .btn.authorize.unlocked:hover svg { + fill: #fbfbfb; + } + + .swagger-ui .btn.execute { + background-color: #5892d5; + border-color: #5892d5; + color: #fff; + } + + .swagger-ui .copy-to-clipboard { + background: #7c8192; + } + + .swagger-ui .copy-to-clipboard button { + background: url("data:image/svg+xml;charset=utf-8,") 50% center no-repeat; + } + + .swagger-ui select { + background: url("data:image/svg+xml;charset=utf-8,") right 10px center/20px no-repeat #212121; + background: url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+CjxzdmcKICAgeG1sbnM6ZGM9Imh0dHA6Ly9wdXJsLm9yZy9kYy9lbGVtZW50cy8xLjEvIgogICB4bWxuczpjYz0iaHR0cDovL2NyZWF0aXZlY29tbW9ucy5vcmcvbnMjIgogICB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiCiAgIHhtbG5zOnN2Zz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciCiAgIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIKICAgeG1sbnM6c29kaXBvZGk9Imh0dHA6Ly9zb2RpcG9kaS5zb3VyY2Vmb3JnZS5uZXQvRFREL3NvZGlwb2RpLTAuZHRkIgogICB4bWxuczppbmtzY2FwZT0iaHR0cDovL3d3dy5pbmtzY2FwZS5vcmcvbmFtZXNwYWNlcy9pbmtzY2FwZSIKICAgaW5rc2NhcGU6dmVyc2lvbj0iMS4wICg0MDM1YTRmYjQ5LCAyMDIwLTA1LTAxKSIKICAgc29kaXBvZGk6ZG9jbmFtZT0iZG93bmxvYWQuc3ZnIgogICBpZD0ic3ZnNCIKICAgdmVyc2lvbj0iMS4xIgogICB2aWV3Qm94PSIwIDAgMjAgMjAiPgogIDxtZXRhZGF0YQogICAgIGlkPSJtZXRhZGF0YTEwIj4KICAgIDxyZGY6UkRGPgogICAgICA8Y2M6V29yawogICAgICAgICByZGY6YWJvdXQ9IiI+CiAgICAgICAgPGRjOmZvcm1hdD5pbWFnZS9zdmcreG1sPC9kYzpmb3JtYXQ+CiAgICAgICAgPGRjOnR5cGUKICAgICAgICAgICByZGY6cmVzb3VyY2U9Imh0dHA6Ly9wdXJsLm9yZy9kYy9kY21pdHlwZS9TdGlsbEltYWdlIiAvPgogICAgICA8L2NjOldvcms+CiAgICA8L3JkZjpSREY+CiAgPC9tZXRhZGF0YT4KICA8ZGVmcwogICAgIGlkPSJkZWZzOCIgLz4KICA8c29kaXBvZGk6bmFtZWR2aWV3CiAgICAgaW5rc2NhcGU6Y3VycmVudC1sYXllcj0ic3ZnNCIKICAgICBpbmtzY2FwZTp3aW5kb3ctbWF4aW1pemVkPSIxIgogICAgIGlua3NjYXBlOndpbmRvdy15PSItOSIKICAgICBpbmtzY2FwZTp3aW5kb3cteD0iLTkiCiAgICAgaW5rc2NhcGU6Y3k9IjEwIgogICAgIGlua3NjYXBlOmN4PSIxMCIKICAgICBpbmtzY2FwZTp6b29tPSI0MS41IgogICAgIHNob3dncmlkPSJmYWxzZSIKICAgICBpZD0ibmFtZWR2aWV3NiIKICAgICBpbmtzY2FwZTp3aW5kb3ctaGVpZ2h0PSIxMDAxIgogICAgIGlua3NjYXBlOndpbmRvdy13aWR0aD0iMTkyMCIKICAgICBpbmtzY2FwZTpwYWdlc2hhZG93PSIyIgogICAgIGlua3NjYXBlOnBhZ2VvcGFjaXR5PSIwIgogICAgIGd1aWRldG9sZXJhbmNlPSIxMCIKICAgICBncmlkdG9sZXJhbmNlPSIxMCIKICAgICBvYmplY3R0b2xlcmFuY2U9IjEwIgogICAgIGJvcmRlcm9wYWNpdHk9IjEiCiAgICAgYm9yZGVyY29sb3I9IiM2NjY2NjYiCiAgICAgcGFnZWNvbG9yPSIjZmZmZmZmIiAvPgogIDxwYXRoCiAgICAgc3R5bGU9ImZpbGw6I2ZmZmZmZiIKICAgICBpZD0icGF0aDIiCiAgICAgZD0iTTEzLjQxOCA3Ljg1OWEuNjk1LjY5NSAwIDAxLjk3OCAwIC42OC42OCAwIDAxMCAuOTY5bC0zLjkwOCAzLjgzYS42OTcuNjk3IDAgMDEtLjk3OSAwbC0zLjkwOC0zLjgzYS42OC42OCAwIDAxMC0uOTY5LjY5NS42OTUgMCAwMS45NzggMEwxMCAxMWwzLjQxOC0zLjE0MXoiIC8+Cjwvc3ZnPgo=) right 10px center/20px no-repeat #1c1c21; + border: 2px solid #41444e; + } + + .swagger-ui select[multiple] { + background: #212121; + } + + .swagger-ui button.invalid, .swagger-ui input[type=email].invalid, .swagger-ui input[type=file].invalid, .swagger-ui input[type=password].invalid, .swagger-ui input[type=search].invalid, .swagger-ui input[type=text].invalid, .swagger-ui select.invalid, .swagger-ui textarea.invalid { + background: #390e0e; + border-color: #c83232; + } + + .swagger-ui input[type=email], .swagger-ui input[type=file], .swagger-ui input[type=password], .swagger-ui input[type=search], .swagger-ui input[type=text], .swagger-ui textarea { + background: #1c1c21; + border: 1px solid #404040; + } + + .swagger-ui textarea { + background: rgba(28, 28, 33, .8); + color: #b5bac9; + } + + .swagger-ui input[disabled], .swagger-ui select[disabled] { + background-color: #1f1f1f; + color: #bfbfbf; + } + + .swagger-ui textarea[disabled] { + background-color: #41444e; + color: #fff; + } + + .swagger-ui select[disabled] { + border-color: #878787; + } + + .swagger-ui textarea:focus { + border: 2px solid #2a69a7; + } + + .swagger-ui .checkbox input[type=checkbox] + label > .item { + background: #303030; + box-shadow: #303030 0 0 0 2px; + } + + .swagger-ui .checkbox input[type=checkbox]:checked + label > .item { + background: url("data:image/svg+xml;charset=utf-8,") 50% center no-repeat #303030; + } + + .swagger-ui .dialog-ux .backdrop-ux { + background: rgba(0, 0, 0, .8); + } + + .swagger-ui .dialog-ux .modal-ux { + background: #1c1c21; + border: 1px solid #2e2e2e; + box-shadow: rgba(0, 0, 0, .2) 0 10px 30px 0; + } + + .swagger-ui .dialog-ux .modal-ux-header .close-modal { + background: 0 0; + } + + .swagger-ui .model .deprecated span, .swagger-ui .model .deprecated td { + color: #bfbfbf !important; + } + + .swagger-ui .model-toggle::after { + background: url("data:image/svg+xml;charset=utf-8,") 50% center/100% no-repeat; + } + + .swagger-ui .model-hint { + background: rgba(0, 0, 0, .7); + color: #ebebeb; + } + + .swagger-ui section.models { + border: 1px solid rgba(58, 64, 80, .3); + } + + .swagger-ui section.models.is-open h4 { + border-bottom: 1px solid rgba(58, 64, 80, .3); + } + + .swagger-ui section.models .model-container { + background: rgba(0, 0, 0, .05); + } + + .swagger-ui section.models .model-container:hover { + background: rgba(0, 0, 0, .07); + } + + .swagger-ui .model-box { + background: rgba(0, 0, 0, .1); + } + + .swagger-ui .prop-type { + color: #aaaad4; + } + + .swagger-ui table thead tr td, .swagger-ui table thead tr th { + border-bottom: 1px solid rgba(58, 64, 80, .2); + color: #b5bac9; + } + + .swagger-ui .parameter__name.required::after { + color: rgba(230, 153, 153, .6); + } + + .swagger-ui .topbar .download-url-wrapper .select-label { + color: #f0f0f0; + } + + .swagger-ui .topbar .download-url-wrapper .download-url-button { + background: #63a040; + color: #fff; + } + + .swagger-ui .info .title small { + background: #7c8492; + } + + .swagger-ui .info .title small.version-stamp { + background-color: #7a9b27; + } + + .swagger-ui .auth-container .errors { + background-color: #350d0d; + color: #b5bac9; + } + + .swagger-ui .errors-wrapper { + background: rgba(200, 50, 50, .1); + border: 2px solid #c83232; + } + + .swagger-ui .markdown code, .swagger-ui .renderedmarkdown code { + background: rgba(0, 0, 0, .05); + color: #c299e6; + } + + .swagger-ui .model-toggle:after { + background: url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+CjxzdmcKICAgeG1sbnM6ZGM9Imh0dHA6Ly9wdXJsLm9yZy9kYy9lbGVtZW50cy8xLjEvIgogICB4bWxuczpjYz0iaHR0cDovL2NyZWF0aXZlY29tbW9ucy5vcmcvbnMjIgogICB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiCiAgIHhtbG5zOnN2Zz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciCiAgIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIKICAgeG1sbnM6c29kaXBvZGk9Imh0dHA6Ly9zb2RpcG9kaS5zb3VyY2Vmb3JnZS5uZXQvRFREL3NvZGlwb2RpLTAuZHRkIgogICB4bWxuczppbmtzY2FwZT0iaHR0cDovL3d3dy5pbmtzY2FwZS5vcmcvbmFtZXNwYWNlcy9pbmtzY2FwZSIKICAgaW5rc2NhcGU6dmVyc2lvbj0iMS4wICg0MDM1YTRmYjQ5LCAyMDIwLTA1LTAxKSIKICAgc29kaXBvZGk6ZG9jbmFtZT0iZG93bmxvYWQyLnN2ZyIKICAgaWQ9InN2ZzQiCiAgIHZlcnNpb249IjEuMSIKICAgaGVpZ2h0PSIyNCIKICAgd2lkdGg9IjI0Ij4KICA8bWV0YWRhdGEKICAgICBpZD0ibWV0YWRhdGExMCI+CiAgICA8cmRmOlJERj4KICAgICAgPGNjOldvcmsKICAgICAgICAgcmRmOmFib3V0PSIiPgogICAgICAgIDxkYzpmb3JtYXQ+aW1hZ2Uvc3ZnK3htbDwvZGM6Zm9ybWF0PgogICAgICAgIDxkYzp0eXBlCiAgICAgICAgICAgcmRmOnJlc291cmNlPSJodHRwOi8vcHVybC5vcmcvZGMvZGNtaXR5cGUvU3RpbGxJbWFnZSIgLz4KICAgICAgPC9jYzpXb3JrPgogICAgPC9yZGY6UkRGPgogIDwvbWV0YWRhdGE+CiAgPGRlZnMKICAgICBpZD0iZGVmczgiIC8+CiAgPHNvZGlwb2RpOm5hbWVkdmlldwogICAgIGlua3NjYXBlOmN1cnJlbnQtbGF5ZXI9InN2ZzQiCiAgICAgaW5rc2NhcGU6d2luZG93LW1heGltaXplZD0iMSIKICAgICBpbmtzY2FwZTp3aW5kb3cteT0iLTkiCiAgICAgaW5rc2NhcGU6d2luZG93LXg9Ii05IgogICAgIGlua3NjYXBlOmN5PSIxMiIKICAgICBpbmtzY2FwZTpjeD0iMTIiCiAgICAgaW5rc2NhcGU6em9vbT0iMzQuNTgzMzMzIgogICAgIHNob3dncmlkPSJmYWxzZSIKICAgICBpZD0ibmFtZWR2aWV3NiIKICAgICBpbmtzY2FwZTp3aW5kb3ctaGVpZ2h0PSIxMDAxIgogICAgIGlua3NjYXBlOndpbmRvdy13aWR0aD0iMTkyMCIKICAgICBpbmtzY2FwZTpwYWdlc2hhZG93PSIyIgogICAgIGlua3NjYXBlOnBhZ2VvcGFjaXR5PSIwIgogICAgIGd1aWRldG9sZXJhbmNlPSIxMCIKICAgICBncmlkdG9sZXJhbmNlPSIxMCIKICAgICBvYmplY3R0b2xlcmFuY2U9IjEwIgogICAgIGJvcmRlcm9wYWNpdHk9IjEiCiAgICAgYm9yZGVyY29sb3I9IiM2NjY2NjYiCiAgICAgcGFnZWNvbG9yPSIjZmZmZmZmIiAvPgogIDxwYXRoCiAgICAgc3R5bGU9ImZpbGw6I2ZmZmZmZiIKICAgICBpZD0icGF0aDIiCiAgICAgZD0iTTEwIDZMOC41OSA3LjQxIDEzLjE3IDEybC00LjU4IDQuNTlMMTAgMThsNi02eiIgLz4KPC9zdmc+Cg==) 50% no-repeat; + } + + /* arrows for each operation and request are now white */ + .arrow, #large-arrow-up { + fill: #fff; + } + + #unlocked { + fill: #fff; + } + + ::-webkit-scrollbar-track { + background-color: #646464 !important; + } + + ::-webkit-scrollbar-thumb { + background-color: #242424 !important; + border: 2px solid #3e4346 !important; + } + + ::-webkit-scrollbar-button:vertical:start:decrement { + background: linear-gradient(130deg, #696969 40%, rgba(255, 0, 0, 0) 41%), linear-gradient(230deg, #696969 40%, transparent 41%), linear-gradient(0deg, #696969 40%, transparent 31%); + background-color: #b6b6b6; + } + + ::-webkit-scrollbar-button:vertical:end:increment { + background: linear-gradient(310deg, #696969 40%, transparent 41%), linear-gradient(50deg, #696969 40%, transparent 41%), linear-gradient(180deg, #696969 40%, transparent 31%); + background-color: #b6b6b6; + } + + ::-webkit-scrollbar-button:horizontal:end:increment { + background: linear-gradient(210deg, #696969 40%, transparent 41%), linear-gradient(330deg, #696969 40%, transparent 41%), linear-gradient(90deg, #696969 30%, transparent 31%); + background-color: #b6b6b6; + } + + ::-webkit-scrollbar-button:horizontal:start:decrement { + background: linear-gradient(30deg, #696969 40%, transparent 41%), linear-gradient(150deg, #696969 40%, transparent 41%), linear-gradient(270deg, #696969 30%, transparent 31%); + background-color: #b6b6b6; + } + + ::-webkit-scrollbar-button, ::-webkit-scrollbar-track-piece { + background-color: #3e4346 !important; + } + + .swagger-ui .black, .swagger-ui .checkbox, .swagger-ui .dark-gray, .swagger-ui .download-url-wrapper .loading, .swagger-ui .errors-wrapper .errors small, .swagger-ui .fallback, .swagger-ui .filter .loading, .swagger-ui .gray, .swagger-ui .hover-black:focus, .swagger-ui .hover-black:hover, .swagger-ui .hover-dark-gray:focus, .swagger-ui .hover-dark-gray:hover, .swagger-ui .hover-gray:focus, .swagger-ui .hover-gray:hover, .swagger-ui .hover-light-silver:focus, .swagger-ui .hover-light-silver:hover, .swagger-ui .hover-mid-gray:focus, .swagger-ui .hover-mid-gray:hover, .swagger-ui .hover-near-black:focus, .swagger-ui .hover-near-black:hover, .swagger-ui .hover-silver:focus, .swagger-ui .hover-silver:hover, .swagger-ui .light-silver, .swagger-ui .markdown pre, .swagger-ui .mid-gray, .swagger-ui .model .property, .swagger-ui .model .property.primitive, .swagger-ui .model-title, .swagger-ui .near-black, .swagger-ui .parameter__extension, .swagger-ui .parameter__in, .swagger-ui .prop-format, .swagger-ui .renderedmarkdown pre, .swagger-ui .response-col_links .response-undocumented, .swagger-ui .response-col_status .response-undocumented, .swagger-ui .silver, .swagger-ui section.models h4, .swagger-ui section.models h5, .swagger-ui span.token-not-formatted, .swagger-ui span.token-string, .swagger-ui table.headers .header-example, .swagger-ui table.model tr.description, .swagger-ui table.model tr.extension { + color: #bfbfbf; + } + + .swagger-ui .hover-white:focus, .swagger-ui .hover-white:hover, .swagger-ui .info .title small pre, .swagger-ui .topbar a, .swagger-ui .white { + color: #fff; + } + + .swagger-ui .bg-black-10, .swagger-ui .hover-bg-black-10:focus, .swagger-ui .hover-bg-black-10:hover, .swagger-ui .stripe-dark:nth-child(2n + 1) { + background-color: rgba(0, 0, 0, .1); + } + + .swagger-ui .bg-white-10, .swagger-ui .hover-bg-white-10:focus, .swagger-ui .hover-bg-white-10:hover, .swagger-ui .stripe-light:nth-child(2n + 1) { + background-color: rgba(28, 28, 33, .1); + } + + .swagger-ui .bg-light-silver, .swagger-ui .hover-bg-light-silver:focus, .swagger-ui .hover-bg-light-silver:hover, .swagger-ui .striped--light-silver:nth-child(2n + 1) { + background-color: #6e6e6e; + } + + .swagger-ui .bg-moon-gray, .swagger-ui .hover-bg-moon-gray:focus, .swagger-ui .hover-bg-moon-gray:hover, .swagger-ui .striped--moon-gray:nth-child(2n + 1) { + background-color: #4d4d4d; + } + + .swagger-ui .bg-light-gray, .swagger-ui .hover-bg-light-gray:focus, .swagger-ui .hover-bg-light-gray:hover, .swagger-ui .striped--light-gray:nth-child(2n + 1) { + background-color: #2b2b2b; + } + + .swagger-ui .bg-near-white, .swagger-ui .hover-bg-near-white:focus, .swagger-ui .hover-bg-near-white:hover, .swagger-ui .striped--near-white:nth-child(2n + 1) { + background-color: #242424; + } + + .swagger-ui .opblock-tag:hover, .swagger-ui section.models h4:hover { + background: rgba(0, 0, 0, .02); + } + + .swagger-ui .checkbox p, .swagger-ui .dialog-ux .modal-ux-content h4, .swagger-ui .dialog-ux .modal-ux-content p, .swagger-ui .dialog-ux .modal-ux-header h3, .swagger-ui .errors-wrapper .errors h4, .swagger-ui .errors-wrapper hgroup h4, .swagger-ui .info .base-url, .swagger-ui .info .title, .swagger-ui .info h1, .swagger-ui .info h2, .swagger-ui .info h3, .swagger-ui .info h4, .swagger-ui .info h5, .swagger-ui .info li, .swagger-ui .info p, .swagger-ui .info table, .swagger-ui .loading-container .loading::after, .swagger-ui .model, .swagger-ui .opblock .opblock-section-header h4, .swagger-ui .opblock .opblock-section-header > label, .swagger-ui .opblock .opblock-summary-description, .swagger-ui .opblock .opblock-summary-operation-id, .swagger-ui .opblock .opblock-summary-path, .swagger-ui .opblock .opblock-summary-path__deprecated, .swagger-ui .opblock-description-wrapper, .swagger-ui .opblock-description-wrapper h4, .swagger-ui .opblock-description-wrapper p, .swagger-ui .opblock-external-docs-wrapper, .swagger-ui .opblock-external-docs-wrapper h4, .swagger-ui .opblock-external-docs-wrapper p, .swagger-ui .opblock-tag small, .swagger-ui .opblock-title_normal, .swagger-ui .opblock-title_normal h4, .swagger-ui .opblock-title_normal p, .swagger-ui .parameter__name, .swagger-ui .parameter__type, .swagger-ui .response-col_links, .swagger-ui .response-col_status, .swagger-ui .responses-inner h4, .swagger-ui .responses-inner h5, .swagger-ui .scheme-container .schemes > label, .swagger-ui .scopes h2, .swagger-ui .servers > label, .swagger-ui .tab li, .swagger-ui label, .swagger-ui select, .swagger-ui table.headers td { + color: #b5bac9; + } + + .swagger-ui .download-url-wrapper .failed, .swagger-ui .filter .failed, .swagger-ui .model-deprecated-warning, .swagger-ui .parameter__deprecated, .swagger-ui .parameter__name.required span, .swagger-ui table.model tr.property-row .star { + color: #e69999; + } + + .swagger-ui .opblock-body pre.microlight, .swagger-ui textarea.curl { + background: #41444e; + border-radius: 4px; + color: #fff; + } + + .swagger-ui .expand-methods svg, .swagger-ui .expand-methods:hover svg { + fill: #bfbfbf; + } + + .swagger-ui .auth-container, .swagger-ui .dialog-ux .modal-ux-header { + border-bottom: 1px solid #2e2e2e; + } + + .swagger-ui .topbar .download-url-wrapper .select-label select, .swagger-ui .topbar .download-url-wrapper input[type=text] { + border: 2px solid #63a040; + } + + .swagger-ui .info a, .swagger-ui .info a:hover, .swagger-ui .scopes h2 a { + color: #99bde6; + } + + /* Dark Scrollbar */ + ::-webkit-scrollbar { + width: 14px; + height: 14px; + } + + ::-webkit-scrollbar-button { + background-color: #3e4346 !important; + } + + ::-webkit-scrollbar-track { + background-color: #646464 !important; + } + + ::-webkit-scrollbar-track-piece { + background-color: #3e4346 !important; + } + + ::-webkit-scrollbar-thumb { + height: 50px; + background-color: #242424 !important; + border: 2px solid #3e4346 !important; + } + + ::-webkit-scrollbar-corner { + } + + ::-webkit-resizer { + } + + ::-webkit-scrollbar-button:vertical:start:decrement { + background: linear-gradient(130deg, #696969 40%, rgba(255, 0, 0, 0) 41%), + linear-gradient(230deg, #696969 40%, rgba(0, 0, 0, 0) 41%), + linear-gradient(0deg, #696969 40%, rgba(0, 0, 0, 0) 31%); + background-color: #b6b6b6; + } + + ::-webkit-scrollbar-button:vertical:end:increment { + background: linear-gradient(310deg, #696969 40%, rgba(0, 0, 0, 0) 41%), + linear-gradient(50deg, #696969 40%, rgba(0, 0, 0, 0) 41%), + linear-gradient(180deg, #696969 40%, rgba(0, 0, 0, 0) 31%); + background-color: #b6b6b6; + } + + ::-webkit-scrollbar-button:horizontal:end:increment { + background: linear-gradient(210deg, #696969 40%, rgba(0, 0, 0, 0) 41%), + linear-gradient(330deg, #696969 40%, rgba(0, 0, 0, 0) 41%), + linear-gradient(90deg, #696969 30%, rgba(0, 0, 0, 0) 31%); + background-color: #b6b6b6; + } + + ::-webkit-scrollbar-button:horizontal:start:decrement { + background: linear-gradient(30deg, #696969 40%, rgba(0, 0, 0, 0) 41%), + linear-gradient(150deg, #696969 40%, rgba(0, 0, 0, 0) 41%), + linear-gradient(270deg, #696969 30%, rgba(0, 0, 0, 0) 31%); + background-color: #b6b6b6; + } +} \ No newline at end of file diff --git a/src/uis/AStar.Dev.Web/AStar.Dev.Web.csproj b/src/uis/AStar.Dev.Web/AStar.Dev.Web.csproj index f637845..43016ea 100644 --- a/src/uis/AStar.Dev.Web/AStar.Dev.Web.csproj +++ b/src/uis/AStar.Dev.Web/AStar.Dev.Web.csproj @@ -7,7 +7,7 @@ - + diff --git a/src/uis/AStar.Dev.Web/Services/FileClassificationsService.cs b/src/uis/AStar.Dev.Web/Services/FileClassificationsService.cs index 2145f97..ed235b3 100644 --- a/src/uis/AStar.Dev.Web/Services/FileClassificationsService.cs +++ b/src/uis/AStar.Dev.Web/Services/FileClassificationsService.cs @@ -1,8 +1,9 @@ -using AStar.Dev.Web.Models; +using AStar.Dev.Source.Generators.Attributes; +using AStar.Dev.Web.Models; namespace AStar.Dev.Web.Services; -//[Service] +[Service] public sealed class FileClassificationsService : IFileClassificationsService { /// diff --git a/src/uis/AStar.Dev.Web/WebApplicationBuilderExtensions.cs b/src/uis/AStar.Dev.Web/WebApplicationBuilderExtensions.cs index 75ca1dc..af27604 100644 --- a/src/uis/AStar.Dev.Web/WebApplicationBuilderExtensions.cs +++ b/src/uis/AStar.Dev.Web/WebApplicationBuilderExtensions.cs @@ -1,10 +1,4 @@ -// using Asp.Versioning; -// using AStar.Dev.AspNet.Extensions.Handlers; -// using AStar.Dev.Files.Classifications.Api; -// using AStar.Dev.Web.ServiceDefaults; - using AStar.Dev.Web.ServiceDefaults; -using AStar.Dev.Web.Services; using Azure.Monitor.OpenTelemetry.AspNetCore; using Microsoft.AspNetCore.Authentication.OpenIdConnect; using Microsoft.FluentUI.AspNetCore.Components; @@ -47,9 +41,7 @@ public static WebApplicationBuilder AddApplicationServices(this WebApplicationBu _ = builder.Services.AddControllersWithViews() .AddMicrosoftIdentityUI(); - _ = builder.Services.AddScoped(); - // _ = builder.AddFileClassificationsApplicationServices(); - // _ = builder.Services.AddExceptionHandler(); + _ = builder.Services.AddAnnotatedServices(); _ = builder.Services.AddProblemDetails(options => options.CustomizeProblemDetails = ctx => ctx.ProblemDetails.Extensions.Add("nodeId", Environment.MachineName)); diff --git a/test/modules/apis/AStar.Dev.Admin.Api.Tests.EndToEnd/AStar.Dev.Admin.Api.Tests.EndToEnd.csproj b/test/modules/apis/AStar.Dev.Admin.Api.Tests.EndToEnd/AStar.Dev.Admin.Api.Tests.EndToEnd.csproj index ec998b7..676c2ed 100644 --- a/test/modules/apis/AStar.Dev.Admin.Api.Tests.EndToEnd/AStar.Dev.Admin.Api.Tests.EndToEnd.csproj +++ b/test/modules/apis/AStar.Dev.Admin.Api.Tests.EndToEnd/AStar.Dev.Admin.Api.Tests.EndToEnd.csproj @@ -18,9 +18,9 @@ runtime; build; native; contentfiles; analyzers; buildtransitive - - - + + + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/test/modules/apis/AStar.Dev.Admin.Api.Tests.Integration/AStar.Dev.Admin.Api.Tests.Integration.csproj b/test/modules/apis/AStar.Dev.Admin.Api.Tests.Integration/AStar.Dev.Admin.Api.Tests.Integration.csproj index a85bf40..2315fb0 100644 --- a/test/modules/apis/AStar.Dev.Admin.Api.Tests.Integration/AStar.Dev.Admin.Api.Tests.Integration.csproj +++ b/test/modules/apis/AStar.Dev.Admin.Api.Tests.Integration/AStar.Dev.Admin.Api.Tests.Integration.csproj @@ -20,9 +20,9 @@ - - - + + + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/test/modules/apis/AStar.Dev.Files.Api.Tests.EndToEnd/AStar.Dev.Files.Api.Tests.EndToEnd.csproj b/test/modules/apis/AStar.Dev.Files.Api.Tests.EndToEnd/AStar.Dev.Files.Api.Tests.EndToEnd.csproj index 935701b..6021b77 100644 --- a/test/modules/apis/AStar.Dev.Files.Api.Tests.EndToEnd/AStar.Dev.Files.Api.Tests.EndToEnd.csproj +++ b/test/modules/apis/AStar.Dev.Files.Api.Tests.EndToEnd/AStar.Dev.Files.Api.Tests.EndToEnd.csproj @@ -17,10 +17,10 @@ all runtime; build; native; contentfiles; analyzers; buildtransitive - + - - + + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/test/modules/apis/AStar.Dev.Files.Api.Tests.Integration/AStar.Dev.Files.Api.Tests.Integration.csproj b/test/modules/apis/AStar.Dev.Files.Api.Tests.Integration/AStar.Dev.Files.Api.Tests.Integration.csproj index a9c236d..bb897a2 100644 --- a/test/modules/apis/AStar.Dev.Files.Api.Tests.Integration/AStar.Dev.Files.Api.Tests.Integration.csproj +++ b/test/modules/apis/AStar.Dev.Files.Api.Tests.Integration/AStar.Dev.Files.Api.Tests.Integration.csproj @@ -18,9 +18,9 @@ runtime; build; native; contentfiles; analyzers; buildtransitive - + - + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/test/modules/apis/AStar.Dev.Files.Api.Tests.Unit/AStar.Dev.Files.Api.Tests.Unit.csproj b/test/modules/apis/AStar.Dev.Files.Api.Tests.Unit/AStar.Dev.Files.Api.Tests.Unit.csproj index 7e0a1d0..eb2229d 100644 --- a/test/modules/apis/AStar.Dev.Files.Api.Tests.Unit/AStar.Dev.Files.Api.Tests.Unit.csproj +++ b/test/modules/apis/AStar.Dev.Files.Api.Tests.Unit/AStar.Dev.Files.Api.Tests.Unit.csproj @@ -18,8 +18,8 @@ runtime; build; native; contentfiles; analyzers; buildtransitive - - + + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/test/modules/apis/AStar.Dev.Images.Api.Tests.EndToEnd/AStar.Dev.Images.Api.Tests.EndToEnd.csproj b/test/modules/apis/AStar.Dev.Images.Api.Tests.EndToEnd/AStar.Dev.Images.Api.Tests.EndToEnd.csproj index 3280e19..9fa7789 100644 --- a/test/modules/apis/AStar.Dev.Images.Api.Tests.EndToEnd/AStar.Dev.Images.Api.Tests.EndToEnd.csproj +++ b/test/modules/apis/AStar.Dev.Images.Api.Tests.EndToEnd/AStar.Dev.Images.Api.Tests.EndToEnd.csproj @@ -17,10 +17,10 @@ all runtime; build; native; contentfiles; analyzers; buildtransitive - + - - + + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/test/modules/apis/AStar.Dev.Images.Api.Tests.Integration/AStar.Dev.Images.Api.Tests.Integration.csproj b/test/modules/apis/AStar.Dev.Images.Api.Tests.Integration/AStar.Dev.Images.Api.Tests.Integration.csproj index 30de97e..bd8fcac 100644 --- a/test/modules/apis/AStar.Dev.Images.Api.Tests.Integration/AStar.Dev.Images.Api.Tests.Integration.csproj +++ b/test/modules/apis/AStar.Dev.Images.Api.Tests.Integration/AStar.Dev.Images.Api.Tests.Integration.csproj @@ -18,9 +18,9 @@ runtime; build; native; contentfiles; analyzers; buildtransitive - + - + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/test/modules/apis/AStar.Dev.Images.Api.Tests.Unit/AStar.Dev.Images.Api.Tests.Unit.csproj b/test/modules/apis/AStar.Dev.Images.Api.Tests.Unit/AStar.Dev.Images.Api.Tests.Unit.csproj index 9d4a208..6c772fc 100644 --- a/test/modules/apis/AStar.Dev.Images.Api.Tests.Unit/AStar.Dev.Images.Api.Tests.Unit.csproj +++ b/test/modules/apis/AStar.Dev.Images.Api.Tests.Unit/AStar.Dev.Images.Api.Tests.Unit.csproj @@ -17,9 +17,9 @@ all runtime; build; native; contentfiles; analyzers; buildtransitive - + - + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/test/nuget-packages/AStar.Dev.Admin.Api.Client.Sdk.Tests.Unit/AStar.Dev.Admin.Api.Client.Sdk.Tests.Unit.csproj b/test/nuget-packages/AStar.Dev.Admin.Api.Client.Sdk.Tests.Unit/AStar.Dev.Admin.Api.Client.Sdk.Tests.Unit.csproj index 5c4ea77..5ee8549 100644 --- a/test/nuget-packages/AStar.Dev.Admin.Api.Client.Sdk.Tests.Unit/AStar.Dev.Admin.Api.Client.Sdk.Tests.Unit.csproj +++ b/test/nuget-packages/AStar.Dev.Admin.Api.Client.Sdk.Tests.Unit/AStar.Dev.Admin.Api.Client.Sdk.Tests.Unit.csproj @@ -18,8 +18,8 @@ runtime; build; native; contentfiles; analyzers; buildtransitive - - + + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/test/nuget-packages/AStar.Dev.Api.HealthChecks.Tests.Unit/AStar.Dev.Api.HealthChecks.Tests.Unit.csproj b/test/nuget-packages/AStar.Dev.Api.HealthChecks.Tests.Unit/AStar.Dev.Api.HealthChecks.Tests.Unit.csproj index 4bc1ecf..07a8ddf 100644 --- a/test/nuget-packages/AStar.Dev.Api.HealthChecks.Tests.Unit/AStar.Dev.Api.HealthChecks.Tests.Unit.csproj +++ b/test/nuget-packages/AStar.Dev.Api.HealthChecks.Tests.Unit/AStar.Dev.Api.HealthChecks.Tests.Unit.csproj @@ -18,8 +18,8 @@ runtime; build; native; contentfiles; analyzers; buildtransitive - - + + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/test/nuget-packages/AStar.Dev.AspNet.Extensions.Tests.Unit/AStar.Dev.AspNet.Extensions.Tests.Unit.csproj b/test/nuget-packages/AStar.Dev.AspNet.Extensions.Tests.Unit/AStar.Dev.AspNet.Extensions.Tests.Unit.csproj index 1d1050c..e6e38bc 100644 --- a/test/nuget-packages/AStar.Dev.AspNet.Extensions.Tests.Unit/AStar.Dev.AspNet.Extensions.Tests.Unit.csproj +++ b/test/nuget-packages/AStar.Dev.AspNet.Extensions.Tests.Unit/AStar.Dev.AspNet.Extensions.Tests.Unit.csproj @@ -18,10 +18,10 @@ runtime; build; native; contentfiles; analyzers; buildtransitive - - + + - + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/test/nuget-packages/AStar.Dev.Files.Api.Client.Sdk.Tests.Unit/AStar.Dev.Files.Api.Client.Sdk.Tests.Unit.csproj b/test/nuget-packages/AStar.Dev.Files.Api.Client.Sdk.Tests.Unit/AStar.Dev.Files.Api.Client.Sdk.Tests.Unit.csproj index ef3f3a5..85b4031 100644 --- a/test/nuget-packages/AStar.Dev.Files.Api.Client.Sdk.Tests.Unit/AStar.Dev.Files.Api.Client.Sdk.Tests.Unit.csproj +++ b/test/nuget-packages/AStar.Dev.Files.Api.Client.Sdk.Tests.Unit/AStar.Dev.Files.Api.Client.Sdk.Tests.Unit.csproj @@ -20,8 +20,8 @@ - - + + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/test/nuget-packages/AStar.Dev.Fluent.Assignments.Tests.Unit/AStar.Dev.Fluent.Assignments.Tests.Unit.csproj b/test/nuget-packages/AStar.Dev.Fluent.Assignments.Tests.Unit/AStar.Dev.Fluent.Assignments.Tests.Unit.csproj index 8531dea..69da98a 100644 --- a/test/nuget-packages/AStar.Dev.Fluent.Assignments.Tests.Unit/AStar.Dev.Fluent.Assignments.Tests.Unit.csproj +++ b/test/nuget-packages/AStar.Dev.Fluent.Assignments.Tests.Unit/AStar.Dev.Fluent.Assignments.Tests.Unit.csproj @@ -17,9 +17,9 @@ all runtime; build; native; contentfiles; analyzers; buildtransitive - + - + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/test/nuget-packages/AStar.Dev.Guard.Clauses.Tests.Unit/AStar.Dev.Guard.Clauses.Tests.Unit.csproj b/test/nuget-packages/AStar.Dev.Guard.Clauses.Tests.Unit/AStar.Dev.Guard.Clauses.Tests.Unit.csproj index 3c604a5..a120627 100644 --- a/test/nuget-packages/AStar.Dev.Guard.Clauses.Tests.Unit/AStar.Dev.Guard.Clauses.Tests.Unit.csproj +++ b/test/nuget-packages/AStar.Dev.Guard.Clauses.Tests.Unit/AStar.Dev.Guard.Clauses.Tests.Unit.csproj @@ -17,9 +17,9 @@ all runtime; build; native; contentfiles; analyzers; buildtransitive - + - + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/test/nuget-packages/AStar.Dev.Images.Api.Client.Sdk.Tests.Unit/AStar.Dev.Images.Api.Client.Sdk.Tests.Unit.csproj b/test/nuget-packages/AStar.Dev.Images.Api.Client.Sdk.Tests.Unit/AStar.Dev.Images.Api.Client.Sdk.Tests.Unit.csproj index c30e0c9..90c7c7c 100644 --- a/test/nuget-packages/AStar.Dev.Images.Api.Client.Sdk.Tests.Unit/AStar.Dev.Images.Api.Client.Sdk.Tests.Unit.csproj +++ b/test/nuget-packages/AStar.Dev.Images.Api.Client.Sdk.Tests.Unit/AStar.Dev.Images.Api.Client.Sdk.Tests.Unit.csproj @@ -18,9 +18,9 @@ runtime; build; native; contentfiles; analyzers; buildtransitive - + - + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/test/services/AStar.Dev.FilesDb.MigrationService.Tests.Unit/AStar.Dev.FilesDb.MigrationService.Tests.Unit.csproj b/test/services/AStar.Dev.FilesDb.MigrationService.Tests.Unit/AStar.Dev.FilesDb.MigrationService.Tests.Unit.csproj new file mode 100644 index 0000000..51dc826 --- /dev/null +++ b/test/services/AStar.Dev.FilesDb.MigrationService.Tests.Unit/AStar.Dev.FilesDb.MigrationService.Tests.Unit.csproj @@ -0,0 +1,35 @@ + + + + enable + enable + Exe + AStar.Dev.FilesDb.MigrationService.Tests.Unit + net10.0 + + + + + + + + + + + + + + + + + + + + + + diff --git a/test/services/AStar.Dev.FilesDb.MigrationService.Tests.Unit/UnitTest1.cs b/test/services/AStar.Dev.FilesDb.MigrationService.Tests.Unit/UnitTest1.cs new file mode 100644 index 0000000..1f25ec3 --- /dev/null +++ b/test/services/AStar.Dev.FilesDb.MigrationService.Tests.Unit/UnitTest1.cs @@ -0,0 +1,10 @@ +namespace AStar.Dev.FilesDb.MigrationService.Tests.Unit; + +public class UnitTest1 +{ + [Fact] + public void Test1() + { + Assert.True(true); + } +} diff --git a/test/services/AStar.Dev.FilesDb.MigrationService.Tests.Unit/xunit.runner.json b/test/services/AStar.Dev.FilesDb.MigrationService.Tests.Unit/xunit.runner.json new file mode 100644 index 0000000..86c7ea0 --- /dev/null +++ b/test/services/AStar.Dev.FilesDb.MigrationService.Tests.Unit/xunit.runner.json @@ -0,0 +1,3 @@ +{ + "$schema": "https://xunit.net/schema/current/xunit.runner.schema.json" +} diff --git a/test/services/AStar.Dev.Usage.Logger.Tests.Unit/AStar.Dev.Usage.Logger.Tests.Unit.csproj b/test/services/AStar.Dev.Usage.Logger.Tests.Unit/AStar.Dev.Usage.Logger.Tests.Unit.csproj new file mode 100644 index 0000000..2a4fcf2 --- /dev/null +++ b/test/services/AStar.Dev.Usage.Logger.Tests.Unit/AStar.Dev.Usage.Logger.Tests.Unit.csproj @@ -0,0 +1,35 @@ + + + + enable + enable + Exe + AStar.Dev.Usage.Logger.Tests.Unit + net10.0 + + + + + + + + + + + + + + + + + + + + + + diff --git a/test/services/AStar.Dev.Usage.Logger.Tests.Unit/UnitTest1.cs b/test/services/AStar.Dev.Usage.Logger.Tests.Unit/UnitTest1.cs new file mode 100644 index 0000000..c9b09b3 --- /dev/null +++ b/test/services/AStar.Dev.Usage.Logger.Tests.Unit/UnitTest1.cs @@ -0,0 +1,10 @@ +namespace AStar.Dev.Usage.Logger.Tests.Unit; + +public class UnitTest1 +{ + [Fact] + public void Test1() + { + Assert.True(true); + } +} diff --git a/test/services/AStar.Dev.Usage.Logger.Tests.Unit/xunit.runner.json b/test/services/AStar.Dev.Usage.Logger.Tests.Unit/xunit.runner.json new file mode 100644 index 0000000..86c7ea0 --- /dev/null +++ b/test/services/AStar.Dev.Usage.Logger.Tests.Unit/xunit.runner.json @@ -0,0 +1,3 @@ +{ + "$schema": "https://xunit.net/schema/current/xunit.runner.schema.json" +}