From 43ab722fdc5e873da8e42b45d19da656f32da059 Mon Sep 17 00:00:00 2001 From: myrmidex Date: Mon, 4 Aug 2025 22:13:04 +0200 Subject: [PATCH] Remove coverage reports --- backend/.gitignore | 1 + .../Commands/FetchNewArticlesCommand.php.html | 187 ----- .../Commands/SyncChannelPostsCommand.php.html | 209 ----- .../Console/Commands/dashboard.html | 294 ------- .../Console/Commands/index.html | 148 ---- .../Console/dashboard.html | 293 ------- .../Console/index.html | 119 --- .../Contracts/ArticleParserInterface.php.html | 108 --- .../HomepageParserInterface.php.html | 113 --- .../Contracts/dashboard.html | 284 ------- .../Contracts/index.html | 102 --- .../Enums/PlatformEnum.php.html | 94 --- .../Enums/dashboard.html | 284 ------- .../Enums/index.html | 89 --- .../Events/ArticleApproved.php.html | 169 ---- .../Events/ArticleReadyToPublish.php.html | 170 ---- .../Events/ExceptionLogged.php.html | 169 ---- .../Events/ExceptionOccurred.php.html | 174 ---- .../Events/NewArticleFetched.php.html | 169 ---- .../Events/dashboard.html | 290 ------- .../Events/index.html | 231 ------ .../Exceptions/ChannelException.php.html | 109 --- .../Exceptions/PlatformAuthException.php.html | 197 ----- .../Exceptions/PublishException.php.html | 235 ------ .../Exceptions/RoutingException.php.html | 109 --- .../RoutingMismatchException.php.html | 174 ---- .../Exceptions/dashboard.html | 295 ------- .../Exceptions/index.html | 201 ----- .../Api/V1/ArticlesController.php.html | 273 ------- .../Api/V1/AuthController.php.html | 333 -------- .../Api/V1/BaseController.php.html | 307 -------- .../Api/V1/DashboardController.php.html | 223 ------ .../Api/V1/FeedsController.php.html | 387 --------- .../Api/V1/LogsController.php.html | 198 ----- .../V1/PlatformAccountsController.php.html | 417 ---------- .../V1/PlatformChannelsController.php.html | 398 ---------- .../Api/V1/RoutingController.php.html | 430 ---------- .../Api/V1/SettingsController.php.html | 240 ------ .../Http/Controllers/Api/V1/dashboard.html | 365 --------- .../Http/Controllers/Api/V1/index.html | 374 --------- .../Http/Controllers/Api/dashboard.html | 364 --------- .../Http/Controllers/Api/index.html | 121 --- .../Controllers/ArticlesController.php.html | 234 ------ .../Http/Controllers/Controller.php.html | 109 --- .../Http/Controllers/FeedsController.php.html | 388 --------- .../Http/Controllers/LogsController.php.html | 170 ---- .../Controllers/OnboardingController.php.html | 443 ----------- .../PlatformAccountsController.php.html | 391 --------- .../PlatformChannelsController.php.html | 423 ---------- .../Controllers/RoutingController.php.html | 480 ------------ .../Controllers/SettingsController.php.html | 214 ----- .../Http/Controllers/dashboard.html | 439 ----------- .../Http/Controllers/index.html | 357 --------- .../Http/Middleware/HandleAppearance.php.html | 176 ----- .../Middleware/HandleInertiaRequests.php.html | 217 ----- .../Http/Middleware/dashboard.html | 290 ------- .../Http/Middleware/index.html | 148 ---- .../Http/Requests/StoreFeedRequest.php.html | 203 ----- .../Http/Requests/UpdateFeedRequest.php.html | 204 ----- .../Http/Requests/dashboard.html | 285 ------- .../Http/Requests/index.html | 148 ---- .../ArticlePublicationResource.php.html | 179 ----- .../Http/Resources/ArticleResource.php.html | 189 ----- .../Http/Resources/FeedResource.php.html | 184 ----- .../PlatformAccountResource.php.html | 184 ----- .../PlatformChannelResource.php.html | 184 ----- .../PlatformInstanceResource.php.html | 180 ----- .../Http/Resources/RouteResource.php.html | 182 ----- .../Http/Resources/dashboard.html | 295 ------- .../Http/Resources/index.html | 288 ------- .../Http/dashboard.html | 453 ----------- .../Http/index.html | 203 ----- .../Jobs/ArticleDiscoveryForFeedJob.php.html | 257 ------ .../Jobs/ArticleDiscoveryJob.php.html | 207 ----- .../Jobs/PublishToLemmyJob.php.html | 212 ----- .../Jobs/SyncChannelPostsJob.php.html | 352 --------- .../Jobs/dashboard.html | 308 -------- .../Jobs/index.html | 203 ----- .../Listeners/LogExceptionToDatabase.php.html | 179 ----- .../Listeners/PublishApprovedArticle.php.html | 179 ----- .../Listeners/PublishArticle.php.html | 213 ----- .../ValidateArticleListener.php.html | 201 ----- .../Listeners/dashboard.html | 299 ------- .../Listeners/index.html | 203 ----- .../LogLevelEnum.php.html | 177 ----- .../Models/Article.php.html | 522 ------------ .../Models/ArticlePublication.php.html | 196 ----- .../Models/Feed.php.html | 382 --------- .../Models/Keyword.php.html | 223 ------ .../Models/Language.php.html | 248 ------ .../Models/Log.php.html | 136 ---- .../Models/PlatformAccount.php.html | 384 --------- .../Models/PlatformChannel.php.html | 387 --------- .../Models/PlatformChannelPost.php.html | 255 ------ .../Models/PlatformInstance.php.html | 259 ------ .../Models/Route.php.html | 263 ------- .../Models/Setting.php.html | 360 --------- .../Models/User.php.html | 201 ----- .../Models/dashboard.html | 343 -------- .../Models/index.html | 440 ----------- .../Modules/Lemmy/LemmyRequest.php.html | 275 ------- .../Lemmy/Services/LemmyApiService.php.html | 438 ----------- .../Lemmy/Services/LemmyPublisher.php.html | 223 ------ .../Modules/Lemmy/Services/dashboard.html | 302 ------- .../Modules/Lemmy/Services/index.html | 149 ---- .../Modules/Lemmy/dashboard.html | 309 -------- .../Modules/Lemmy/index.html | 148 ---- .../Modules/dashboard.html | 308 -------- .../Modules/index.html | 119 --- .../Providers/AppServiceProvider.php.html | 260 ------ .../Providers/HorizonServiceProvider.php.html | 208 ----- .../Providers/dashboard.html | 290 ------- .../Providers/index.html | 147 ---- .../Services/Article/ArticleFetcher.php.html | 354 --------- .../Article/ValidationService.php.html | 228 ------ .../Services/Article/dashboard.html | 302 ------- .../Services/Article/index.html | 148 ---- .../Services/Auth/LemmyAuthService.php.html | 194 ----- .../Services/Auth/dashboard.html | 289 ------- .../Services/Auth/index.html | 120 --- .../Services/DashboardStatsService.php.html | 306 -------- .../Factories/ArticleParserFactory.php.html | 250 ------ .../Factories/HomepageParserFactory.php.html | 220 ------ .../Services/Factories/dashboard.html | 298 ------- .../Services/Factories/index.html | 148 ---- .../Services/Http/HttpFetcher.php.html | 256 ------ .../Services/Http/dashboard.html | 291 ------- .../Services/Http/index.html | 120 --- .../Services/Log/LogSaver.php.html | 306 -------- .../Services/Log/dashboard.html | 293 ------- .../Services/Log/index.html | 120 --- .../OnboardingRedirectService.php.html | 172 ---- .../Parsers/BelgaArticlePageParser.php.html | 351 --------- .../Parsers/BelgaArticleParser.php.html | 220 ------ .../Parsers/BelgaHomepageParser.php.html | 173 ---- .../BelgaHomepageParserAdapter.php.html | 247 ------ .../Parsers/VrtArticlePageParser.php.html | 333 -------- .../Parsers/VrtArticleParser.php.html | 220 ------ .../Parsers/VrtHomepageParser.php.html | 175 ----- .../Parsers/VrtHomepageParserAdapter.php.html | 247 ------ .../Services/Parsers/dashboard.html | 329 -------- .../Services/Parsers/index.html | 316 -------- .../ArticlePublishingService.php.html | 260 ------ .../Services/Publishing/dashboard.html | 291 ------- .../Services/Publishing/index.html | 120 --- .../RoutingValidationService.php.html | 184 ----- .../Services/SystemStatusService.php.html | 226 ------ .../Services/dashboard.html | 395 ---------- .../Services/index.html | 399 ---------- .../_css/bootstrap.min.css | 6 - .../_css/custom.css | 0 .../_css/nv.d3.min.css | 1 - .../_css/octicons.css | 5 - .../_css/style.css | 201 ----- .../_icons/file-code.svg | 1 - .../_icons/file-directory.svg | 1 - .../_js/bootstrap.bundle.min.js | 7 - .../coverage-report-controllers/_js/d3.min.js | 5 - .../coverage-report-controllers/_js/file.js | 53 -- .../_js/jquery.min.js | 2 - .../_js/nv.d3.min.js | 8 - .../dashboard.html | 717 ----------------- .../coverage-report-controllers/index.html | 424 ---------- .../Commands/FetchNewArticlesCommand.php.html | 187 ----- .../Commands/SyncChannelPostsCommand.php.html | 209 ----- .../Console/Commands/dashboard.html | 294 ------- .../Console/Commands/index.html | 148 ---- .../Console/dashboard.html | 293 ------- .../coverage-report-final/Console/index.html | 119 --- .../Contracts/ArticleParserInterface.php.html | 108 --- .../HomepageParserInterface.php.html | 113 --- .../Contracts/dashboard.html | 284 ------- .../Contracts/index.html | 102 --- .../Enums/PlatformEnum.php.html | 94 --- .../Enums/dashboard.html | 284 ------- .../coverage-report-final/Enums/index.html | 89 --- .../Events/ArticleApproved.php.html | 169 ---- .../Events/ArticleReadyToPublish.php.html | 170 ---- .../Events/ExceptionLogged.php.html | 169 ---- .../Events/ExceptionOccurred.php.html | 174 ---- .../Events/NewArticleFetched.php.html | 169 ---- .../Events/dashboard.html | 290 ------- .../coverage-report-final/Events/index.html | 231 ------ .../Exceptions/ChannelException.php.html | 109 --- .../Exceptions/PlatformAuthException.php.html | 197 ----- .../Exceptions/PublishException.php.html | 235 ------ .../Exceptions/RoutingException.php.html | 109 --- .../RoutingMismatchException.php.html | 174 ---- .../Exceptions/dashboard.html | 295 ------- .../Exceptions/index.html | 201 ----- .../Api/V1/ArticlesController.php.html | 273 ------- .../Api/V1/AuthController.php.html | 333 -------- .../Api/V1/BaseController.php.html | 307 -------- .../Api/V1/DashboardController.php.html | 223 ------ .../Api/V1/FeedsController.php.html | 387 --------- .../Api/V1/LogsController.php.html | 198 ----- .../V1/PlatformAccountsController.php.html | 417 ---------- .../V1/PlatformChannelsController.php.html | 398 ---------- .../Api/V1/RoutingController.php.html | 430 ---------- .../Api/V1/SettingsController.php.html | 240 ------ .../Http/Controllers/Api/V1/dashboard.html | 365 --------- .../Http/Controllers/Api/V1/index.html | 374 --------- .../Http/Controllers/Api/dashboard.html | 364 --------- .../Http/Controllers/Api/index.html | 121 --- .../Controllers/ArticlesController.php.html | 234 ------ .../Http/Controllers/Controller.php.html | 109 --- .../Http/Controllers/FeedsController.php.html | 388 --------- .../Http/Controllers/LogsController.php.html | 170 ---- .../Controllers/OnboardingController.php.html | 443 ----------- .../PlatformAccountsController.php.html | 391 --------- .../PlatformChannelsController.php.html | 423 ---------- .../Controllers/RoutingController.php.html | 480 ------------ .../Controllers/SettingsController.php.html | 214 ----- .../Http/Controllers/dashboard.html | 439 ----------- .../Http/Controllers/index.html | 357 --------- .../Http/Middleware/HandleAppearance.php.html | 176 ----- .../Middleware/HandleInertiaRequests.php.html | 217 ----- .../Http/Middleware/dashboard.html | 290 ------- .../Http/Middleware/index.html | 148 ---- .../Http/Requests/StoreFeedRequest.php.html | 203 ----- .../Http/Requests/UpdateFeedRequest.php.html | 204 ----- .../Http/Requests/dashboard.html | 285 ------- .../Http/Requests/index.html | 148 ---- .../ArticlePublicationResource.php.html | 179 ----- .../Http/Resources/ArticleResource.php.html | 189 ----- .../Http/Resources/FeedResource.php.html | 184 ----- .../PlatformAccountResource.php.html | 184 ----- .../PlatformChannelResource.php.html | 184 ----- .../PlatformInstanceResource.php.html | 180 ----- .../Http/Resources/RouteResource.php.html | 182 ----- .../Http/Resources/dashboard.html | 295 ------- .../Http/Resources/index.html | 288 ------- .../coverage-report-final/Http/dashboard.html | 453 ----------- backend/coverage-report-final/Http/index.html | 203 ----- .../Jobs/ArticleDiscoveryForFeedJob.php.html | 257 ------ .../Jobs/ArticleDiscoveryJob.php.html | 207 ----- .../Jobs/PublishToLemmyJob.php.html | 212 ----- .../Jobs/SyncChannelPostsJob.php.html | 352 --------- .../coverage-report-final/Jobs/dashboard.html | 308 -------- backend/coverage-report-final/Jobs/index.html | 203 ----- .../Listeners/LogExceptionToDatabase.php.html | 179 ----- .../Listeners/PublishApprovedArticle.php.html | 179 ----- .../Listeners/PublishArticle.php.html | 213 ----- .../ValidateArticleListener.php.html | 201 ----- .../Listeners/dashboard.html | 299 ------- .../Listeners/index.html | 203 ----- .../LogLevelEnum.php.html | 177 ----- .../Models/Article.php.html | 522 ------------ .../Models/ArticlePublication.php.html | 196 ----- .../Models/Feed.php.html | 382 --------- .../Models/Keyword.php.html | 223 ------ .../Models/Language.php.html | 248 ------ .../coverage-report-final/Models/Log.php.html | 136 ---- .../Models/PlatformAccount.php.html | 384 --------- .../Models/PlatformChannel.php.html | 387 --------- .../Models/PlatformChannelPost.php.html | 255 ------ .../Models/PlatformInstance.php.html | 259 ------ .../Models/Route.php.html | 263 ------- .../Models/Setting.php.html | 360 --------- .../Models/User.php.html | 201 ----- .../Models/dashboard.html | 334 -------- .../coverage-report-final/Models/index.html | 440 ----------- .../Modules/Lemmy/LemmyRequest.php.html | 275 ------- .../Lemmy/Services/LemmyApiService.php.html | 438 ----------- .../Lemmy/Services/LemmyPublisher.php.html | 223 ------ .../Modules/Lemmy/Services/dashboard.html | 302 ------- .../Modules/Lemmy/Services/index.html | 149 ---- .../Modules/Lemmy/dashboard.html | 309 -------- .../Modules/Lemmy/index.html | 148 ---- .../Modules/dashboard.html | 308 -------- .../coverage-report-final/Modules/index.html | 119 --- .../Providers/AppServiceProvider.php.html | 260 ------ .../Providers/HorizonServiceProvider.php.html | 208 ----- .../Providers/dashboard.html | 290 ------- .../Providers/index.html | 147 ---- .../Services/Article/ArticleFetcher.php.html | 354 --------- .../Article/ValidationService.php.html | 228 ------ .../Services/Article/dashboard.html | 302 ------- .../Services/Article/index.html | 148 ---- .../Services/Auth/LemmyAuthService.php.html | 194 ----- .../Services/Auth/dashboard.html | 289 ------- .../Services/Auth/index.html | 120 --- .../Services/DashboardStatsService.php.html | 306 -------- .../Factories/ArticleParserFactory.php.html | 250 ------ .../Factories/HomepageParserFactory.php.html | 220 ------ .../Services/Factories/dashboard.html | 298 ------- .../Services/Factories/index.html | 148 ---- .../Services/Http/HttpFetcher.php.html | 256 ------ .../Services/Http/dashboard.html | 291 ------- .../Services/Http/index.html | 120 --- .../Services/Log/LogSaver.php.html | 306 -------- .../Services/Log/dashboard.html | 293 ------- .../Services/Log/index.html | 120 --- .../OnboardingRedirectService.php.html | 172 ---- .../Parsers/BelgaArticlePageParser.php.html | 351 --------- .../Parsers/BelgaArticleParser.php.html | 220 ------ .../Parsers/BelgaHomepageParser.php.html | 173 ---- .../BelgaHomepageParserAdapter.php.html | 247 ------ .../Parsers/VrtArticlePageParser.php.html | 333 -------- .../Parsers/VrtArticleParser.php.html | 220 ------ .../Parsers/VrtHomepageParser.php.html | 175 ----- .../Parsers/VrtHomepageParserAdapter.php.html | 247 ------ .../Services/Parsers/dashboard.html | 329 -------- .../Services/Parsers/index.html | 316 -------- .../ArticlePublishingService.php.html | 260 ------ .../Services/Publishing/dashboard.html | 291 ------- .../Services/Publishing/index.html | 120 --- .../RoutingValidationService.php.html | 184 ----- .../Services/SystemStatusService.php.html | 226 ------ .../Services/dashboard.html | 395 ---------- .../coverage-report-final/Services/index.html | 399 ---------- .../_css/bootstrap.min.css | 6 - backend/coverage-report-final/_css/custom.css | 0 .../coverage-report-final/_css/nv.d3.min.css | 1 - .../coverage-report-final/_css/octicons.css | 5 - backend/coverage-report-final/_css/style.css | 201 ----- .../_icons/file-code.svg | 1 - .../_icons/file-directory.svg | 1 - .../_js/bootstrap.bundle.min.js | 7 - backend/coverage-report-final/_js/d3.min.js | 5 - backend/coverage-report-final/_js/file.js | 53 -- .../coverage-report-final/_js/jquery.min.js | 2 - .../coverage-report-final/_js/nv.d3.min.js | 8 - backend/coverage-report-final/dashboard.html | 708 ----------------- backend/coverage-report-final/index.html | 424 ---------- .../Commands/FetchNewArticlesCommand.php.html | 187 ----- .../Commands/SyncChannelPostsCommand.php.html | 209 ----- .../Console/Commands/dashboard.html | 294 ------- .../Console/Commands/index.html | 148 ---- .../Console/dashboard.html | 293 ------- .../Console/index.html | 119 --- .../Contracts/ArticleParserInterface.php.html | 108 --- .../HomepageParserInterface.php.html | 113 --- .../Contracts/dashboard.html | 284 ------- .../Contracts/index.html | 102 --- .../Enums/PlatformEnum.php.html | 94 --- .../Enums/dashboard.html | 284 ------- .../coverage-report-progress/Enums/index.html | 89 --- .../Events/ArticleApproved.php.html | 169 ---- .../Events/ArticleReadyToPublish.php.html | 170 ---- .../Events/ExceptionLogged.php.html | 169 ---- .../Events/ExceptionOccurred.php.html | 174 ---- .../Events/NewArticleFetched.php.html | 169 ---- .../Events/dashboard.html | 290 ------- .../Events/index.html | 231 ------ .../Exceptions/ChannelException.php.html | 109 --- .../Exceptions/PlatformAuthException.php.html | 197 ----- .../Exceptions/PublishException.php.html | 235 ------ .../Exceptions/RoutingException.php.html | 109 --- .../RoutingMismatchException.php.html | 174 ---- .../Exceptions/dashboard.html | 295 ------- .../Exceptions/index.html | 201 ----- .../Api/V1/ArticlesController.php.html | 273 ------- .../Api/V1/AuthController.php.html | 333 -------- .../Api/V1/BaseController.php.html | 307 -------- .../Api/V1/DashboardController.php.html | 223 ------ .../Api/V1/FeedsController.php.html | 387 --------- .../Api/V1/LogsController.php.html | 198 ----- .../V1/PlatformAccountsController.php.html | 417 ---------- .../V1/PlatformChannelsController.php.html | 398 ---------- .../Api/V1/RoutingController.php.html | 430 ---------- .../Api/V1/SettingsController.php.html | 240 ------ .../Http/Controllers/Api/V1/dashboard.html | 372 --------- .../Http/Controllers/Api/V1/index.html | 374 --------- .../Http/Controllers/Api/dashboard.html | 371 --------- .../Http/Controllers/Api/index.html | 121 --- .../Controllers/ArticlesController.php.html | 234 ------ .../Http/Controllers/Controller.php.html | 109 --- .../Http/Controllers/FeedsController.php.html | 388 --------- .../Http/Controllers/LogsController.php.html | 170 ---- .../Controllers/OnboardingController.php.html | 443 ----------- .../PlatformAccountsController.php.html | 391 --------- .../PlatformChannelsController.php.html | 423 ---------- .../Controllers/RoutingController.php.html | 480 ------------ .../Controllers/SettingsController.php.html | 214 ----- .../Http/Controllers/dashboard.html | 446 ----------- .../Http/Controllers/index.html | 357 --------- .../Http/Middleware/HandleAppearance.php.html | 176 ----- .../Middleware/HandleInertiaRequests.php.html | 217 ----- .../Http/Middleware/dashboard.html | 290 ------- .../Http/Middleware/index.html | 148 ---- .../Http/Requests/StoreFeedRequest.php.html | 203 ----- .../Http/Requests/UpdateFeedRequest.php.html | 204 ----- .../Http/Requests/dashboard.html | 293 ------- .../Http/Requests/index.html | 148 ---- .../ArticlePublicationResource.php.html | 179 ----- .../Http/Resources/ArticleResource.php.html | 189 ----- .../Http/Resources/FeedResource.php.html | 184 ----- .../PlatformAccountResource.php.html | 184 ----- .../PlatformChannelResource.php.html | 184 ----- .../PlatformInstanceResource.php.html | 180 ----- .../Http/Resources/RouteResource.php.html | 182 ----- .../Http/Resources/dashboard.html | 295 ------- .../Http/Resources/index.html | 288 ------- .../Http/dashboard.html | 468 ----------- .../coverage-report-progress/Http/index.html | 203 ----- .../Jobs/ArticleDiscoveryForFeedJob.php.html | 257 ------ .../Jobs/ArticleDiscoveryJob.php.html | 207 ----- .../Jobs/PublishToLemmyJob.php.html | 212 ----- .../Jobs/SyncChannelPostsJob.php.html | 352 --------- .../Jobs/dashboard.html | 308 -------- .../coverage-report-progress/Jobs/index.html | 203 ----- .../Listeners/LogExceptionToDatabase.php.html | 179 ----- .../Listeners/PublishApprovedArticle.php.html | 179 ----- .../Listeners/PublishArticle.php.html | 213 ----- .../ValidateArticleListener.php.html | 201 ----- .../Listeners/dashboard.html | 299 ------- .../Listeners/index.html | 203 ----- .../LogLevelEnum.php.html | 177 ----- .../Models/Article.php.html | 522 ------------ .../Models/ArticlePublication.php.html | 196 ----- .../Models/Feed.php.html | 382 --------- .../Models/Keyword.php.html | 223 ------ .../Models/Language.php.html | 248 ------ .../Models/Log.php.html | 136 ---- .../Models/PlatformAccount.php.html | 384 --------- .../Models/PlatformChannel.php.html | 387 --------- .../Models/PlatformChannelPost.php.html | 255 ------ .../Models/PlatformInstance.php.html | 259 ------ .../Models/Route.php.html | 263 ------- .../Models/Setting.php.html | 360 --------- .../Models/User.php.html | 201 ----- .../Models/dashboard.html | 352 --------- .../Models/index.html | 440 ----------- .../Modules/Lemmy/LemmyRequest.php.html | 275 ------- .../Lemmy/Services/LemmyApiService.php.html | 438 ----------- .../Lemmy/Services/LemmyPublisher.php.html | 223 ------ .../Modules/Lemmy/Services/dashboard.html | 302 ------- .../Modules/Lemmy/Services/index.html | 149 ---- .../Modules/Lemmy/dashboard.html | 309 -------- .../Modules/Lemmy/index.html | 148 ---- .../Modules/dashboard.html | 308 -------- .../Modules/index.html | 119 --- .../Providers/AppServiceProvider.php.html | 260 ------ .../Providers/HorizonServiceProvider.php.html | 208 ----- .../Providers/dashboard.html | 290 ------- .../Providers/index.html | 147 ---- .../Services/Article/ArticleFetcher.php.html | 354 --------- .../Article/ValidationService.php.html | 228 ------ .../Services/Article/dashboard.html | 302 ------- .../Services/Article/index.html | 148 ---- .../Services/Auth/LemmyAuthService.php.html | 194 ----- .../Services/Auth/dashboard.html | 289 ------- .../Services/Auth/index.html | 120 --- .../Services/DashboardStatsService.php.html | 306 -------- .../Factories/ArticleParserFactory.php.html | 250 ------ .../Factories/HomepageParserFactory.php.html | 220 ------ .../Services/Factories/dashboard.html | 298 ------- .../Services/Factories/index.html | 148 ---- .../Services/Http/HttpFetcher.php.html | 256 ------ .../Services/Http/dashboard.html | 291 ------- .../Services/Http/index.html | 120 --- .../Services/Log/LogSaver.php.html | 306 -------- .../Services/Log/dashboard.html | 293 ------- .../Services/Log/index.html | 120 --- .../OnboardingRedirectService.php.html | 172 ---- .../Parsers/BelgaArticlePageParser.php.html | 351 --------- .../Parsers/BelgaArticleParser.php.html | 220 ------ .../Parsers/BelgaHomepageParser.php.html | 173 ---- .../BelgaHomepageParserAdapter.php.html | 247 ------ .../Parsers/VrtArticlePageParser.php.html | 333 -------- .../Parsers/VrtArticleParser.php.html | 220 ------ .../Parsers/VrtHomepageParser.php.html | 175 ----- .../Parsers/VrtHomepageParserAdapter.php.html | 247 ------ .../Services/Parsers/dashboard.html | 329 -------- .../Services/Parsers/index.html | 316 -------- .../ArticlePublishingService.php.html | 260 ------ .../Services/Publishing/dashboard.html | 291 ------- .../Services/Publishing/index.html | 120 --- .../RoutingValidationService.php.html | 184 ----- .../Services/SystemStatusService.php.html | 226 ------ .../Services/dashboard.html | 395 ---------- .../Services/index.html | 399 ---------- .../_css/bootstrap.min.css | 6 - .../coverage-report-progress/_css/custom.css | 0 .../_css/nv.d3.min.css | 1 - .../_css/octicons.css | 5 - .../coverage-report-progress/_css/style.css | 201 ----- .../_icons/file-code.svg | 1 - .../_icons/file-directory.svg | 1 - .../_js/bootstrap.bundle.min.js | 7 - .../coverage-report-progress/_js/d3.min.js | 5 - backend/coverage-report-progress/_js/file.js | 53 -- .../_js/jquery.min.js | 2 - .../coverage-report-progress/_js/nv.d3.min.js | 8 - .../coverage-report-progress/dashboard.html | 741 ------------------ backend/coverage-report-progress/index.html | 424 ---------- .../Commands/FetchNewArticlesCommand.php.html | 187 ----- .../Commands/SyncChannelPostsCommand.php.html | 209 ----- .../Console/Commands/dashboard.html | 294 ------- .../Console/Commands/index.html | 148 ---- .../Console/dashboard.html | 293 ------- .../Console/index.html | 119 --- .../Contracts/ArticleParserInterface.php.html | 108 --- .../HomepageParserInterface.php.html | 113 --- .../Contracts/dashboard.html | 284 ------- .../Contracts/index.html | 102 --- .../Enums/PlatformEnum.php.html | 94 --- .../Enums/dashboard.html | 284 ------- .../Enums/index.html | 89 --- .../Events/ArticleApproved.php.html | 169 ---- .../Events/ArticleReadyToPublish.php.html | 170 ---- .../Events/ExceptionLogged.php.html | 169 ---- .../Events/ExceptionOccurred.php.html | 174 ---- .../Events/NewArticleFetched.php.html | 169 ---- .../Events/dashboard.html | 290 ------- .../Events/index.html | 231 ------ .../Exceptions/ChannelException.php.html | 109 --- .../Exceptions/PlatformAuthException.php.html | 197 ----- .../Exceptions/PublishException.php.html | 235 ------ .../Exceptions/RoutingException.php.html | 109 --- .../RoutingMismatchException.php.html | 174 ---- .../Exceptions/dashboard.html | 295 ------- .../Exceptions/index.html | 201 ----- .../Api/V1/ArticlesController.php.html | 273 ------- .../Api/V1/AuthController.php.html | 333 -------- .../Api/V1/BaseController.php.html | 307 -------- .../Api/V1/DashboardController.php.html | 223 ------ .../Api/V1/FeedsController.php.html | 387 --------- .../Api/V1/LogsController.php.html | 198 ----- .../V1/PlatformAccountsController.php.html | 417 ---------- .../V1/PlatformChannelsController.php.html | 398 ---------- .../Api/V1/RoutingController.php.html | 430 ---------- .../Api/V1/SettingsController.php.html | 240 ------ .../Http/Controllers/Api/V1/dashboard.html | 365 --------- .../Http/Controllers/Api/V1/index.html | 374 --------- .../Http/Controllers/Api/dashboard.html | 364 --------- .../Http/Controllers/Api/index.html | 121 --- .../Controllers/ArticlesController.php.html | 234 ------ .../Http/Controllers/Controller.php.html | 109 --- .../Http/Controllers/FeedsController.php.html | 388 --------- .../Http/Controllers/LogsController.php.html | 170 ---- .../Controllers/OnboardingController.php.html | 443 ----------- .../PlatformAccountsController.php.html | 391 --------- .../PlatformChannelsController.php.html | 423 ---------- .../Controllers/RoutingController.php.html | 480 ------------ .../Controllers/SettingsController.php.html | 214 ----- .../Http/Controllers/dashboard.html | 439 ----------- .../Http/Controllers/index.html | 357 --------- .../Http/Middleware/HandleAppearance.php.html | 176 ----- .../Middleware/HandleInertiaRequests.php.html | 217 ----- .../Http/Middleware/dashboard.html | 290 ------- .../Http/Middleware/index.html | 148 ---- .../Http/Requests/StoreFeedRequest.php.html | 203 ----- .../Http/Requests/UpdateFeedRequest.php.html | 204 ----- .../Http/Requests/dashboard.html | 285 ------- .../Http/Requests/index.html | 148 ---- .../ArticlePublicationResource.php.html | 179 ----- .../Http/Resources/ArticleResource.php.html | 189 ----- .../Http/Resources/FeedResource.php.html | 184 ----- .../PlatformAccountResource.php.html | 184 ----- .../PlatformChannelResource.php.html | 184 ----- .../PlatformInstanceResource.php.html | 180 ----- .../Http/Resources/RouteResource.php.html | 182 ----- .../Http/Resources/dashboard.html | 295 ------- .../Http/Resources/index.html | 288 ------- .../Http/dashboard.html | 453 ----------- .../Http/index.html | 203 ----- .../Jobs/ArticleDiscoveryForFeedJob.php.html | 257 ------ .../Jobs/ArticleDiscoveryJob.php.html | 207 ----- .../Jobs/PublishToLemmyJob.php.html | 212 ----- .../Jobs/SyncChannelPostsJob.php.html | 352 --------- .../Jobs/dashboard.html | 308 -------- .../Jobs/index.html | 203 ----- .../Listeners/LogExceptionToDatabase.php.html | 179 ----- .../Listeners/PublishApprovedArticle.php.html | 179 ----- .../Listeners/PublishArticle.php.html | 213 ----- .../ValidateArticleListener.php.html | 201 ----- .../Listeners/dashboard.html | 299 ------- .../Listeners/index.html | 203 ----- .../LogLevelEnum.php.html | 177 ----- .../Models/Article.php.html | 522 ------------ .../Models/ArticlePublication.php.html | 196 ----- .../Models/Feed.php.html | 382 --------- .../Models/Keyword.php.html | 223 ------ .../Models/Language.php.html | 248 ------ .../Models/Log.php.html | 136 ---- .../Models/PlatformAccount.php.html | 384 --------- .../Models/PlatformChannel.php.html | 387 --------- .../Models/PlatformChannelPost.php.html | 255 ------ .../Models/PlatformInstance.php.html | 259 ------ .../Models/Route.php.html | 263 ------- .../Models/Setting.php.html | 360 --------- .../Models/User.php.html | 201 ----- .../Models/dashboard.html | 343 -------- .../Models/index.html | 440 ----------- .../Modules/Lemmy/LemmyRequest.php.html | 275 ------- .../Lemmy/Services/LemmyApiService.php.html | 438 ----------- .../Lemmy/Services/LemmyPublisher.php.html | 223 ------ .../Modules/Lemmy/Services/dashboard.html | 302 ------- .../Modules/Lemmy/Services/index.html | 149 ---- .../Modules/Lemmy/dashboard.html | 309 -------- .../Modules/Lemmy/index.html | 148 ---- .../Modules/dashboard.html | 308 -------- .../Modules/index.html | 119 --- .../Providers/AppServiceProvider.php.html | 260 ------ .../Providers/HorizonServiceProvider.php.html | 208 ----- .../Providers/dashboard.html | 290 ------- .../Providers/index.html | 147 ---- .../Services/Article/ArticleFetcher.php.html | 354 --------- .../Article/ValidationService.php.html | 228 ------ .../Services/Article/dashboard.html | 302 ------- .../Services/Article/index.html | 148 ---- .../Services/Auth/LemmyAuthService.php.html | 194 ----- .../Services/Auth/dashboard.html | 289 ------- .../Services/Auth/index.html | 120 --- .../Services/DashboardStatsService.php.html | 306 -------- .../Factories/ArticleParserFactory.php.html | 250 ------ .../Factories/HomepageParserFactory.php.html | 220 ------ .../Services/Factories/dashboard.html | 298 ------- .../Services/Factories/index.html | 148 ---- .../Services/Http/HttpFetcher.php.html | 256 ------ .../Services/Http/dashboard.html | 291 ------- .../Services/Http/index.html | 120 --- .../Services/Log/LogSaver.php.html | 306 -------- .../Services/Log/dashboard.html | 293 ------- .../Services/Log/index.html | 120 --- .../OnboardingRedirectService.php.html | 172 ---- .../Parsers/BelgaArticlePageParser.php.html | 351 --------- .../Parsers/BelgaArticleParser.php.html | 220 ------ .../Parsers/BelgaHomepageParser.php.html | 173 ---- .../BelgaHomepageParserAdapter.php.html | 247 ------ .../Parsers/VrtArticlePageParser.php.html | 333 -------- .../Parsers/VrtArticleParser.php.html | 220 ------ .../Parsers/VrtHomepageParser.php.html | 175 ----- .../Parsers/VrtHomepageParserAdapter.php.html | 247 ------ .../Services/Parsers/dashboard.html | 329 -------- .../Services/Parsers/index.html | 316 -------- .../ArticlePublishingService.php.html | 260 ------ .../Services/Publishing/dashboard.html | 291 ------- .../Services/Publishing/index.html | 120 --- .../RoutingValidationService.php.html | 184 ----- .../Services/SystemStatusService.php.html | 226 ------ .../Services/dashboard.html | 395 ---------- .../Services/index.html | 399 ---------- .../_css/bootstrap.min.css | 6 - .../_css/custom.css | 0 .../_css/nv.d3.min.css | 1 - .../_css/octicons.css | 5 - .../_css/style.css | 201 ----- .../_icons/file-code.svg | 1 - .../_icons/file-directory.svg | 1 - .../_js/bootstrap.bundle.min.js | 7 - .../coverage-report-with-models/_js/d3.min.js | 5 - .../coverage-report-with-models/_js/file.js | 53 -- .../_js/jquery.min.js | 2 - .../_js/nv.d3.min.js | 8 - .../dashboard.html | 717 ----------------- .../coverage-report-with-models/index.html | 424 ---------- .../Commands/FetchNewArticlesCommand.php.html | 187 ----- .../Commands/SyncChannelPostsCommand.php.html | 209 ----- .../Console/Commands/dashboard.html | 294 ------- .../Console/Commands/index.html | 148 ---- .../coverage-report/Console/dashboard.html | 293 ------- backend/coverage-report/Console/index.html | 119 --- .../Contracts/ArticleParserInterface.php.html | 108 --- .../HomepageParserInterface.php.html | 113 --- .../coverage-report/Contracts/dashboard.html | 284 ------- backend/coverage-report/Contracts/index.html | 102 --- .../Enums/PlatformEnum.php.html | 94 --- backend/coverage-report/Enums/dashboard.html | 284 ------- backend/coverage-report/Enums/index.html | 89 --- .../Events/ArticleApproved.php.html | 169 ---- .../Events/ArticleReadyToPublish.php.html | 170 ---- .../Events/ExceptionLogged.php.html | 169 ---- .../Events/ExceptionOccurred.php.html | 174 ---- .../Events/NewArticleFetched.php.html | 169 ---- backend/coverage-report/Events/dashboard.html | 284 ------- backend/coverage-report/Events/index.html | 231 ------ .../Exceptions/ChannelException.php.html | 109 --- .../Exceptions/PlatformAuthException.php.html | 197 ----- .../Exceptions/PublishException.php.html | 235 ------ .../Exceptions/RoutingException.php.html | 109 --- .../RoutingMismatchException.php.html | 174 ---- .../coverage-report/Exceptions/dashboard.html | 295 ------- backend/coverage-report/Exceptions/index.html | 201 ----- .../Api/V1/ArticlesController.php.html | 273 ------- .../Api/V1/AuthController.php.html | 333 -------- .../Api/V1/BaseController.php.html | 307 -------- .../Api/V1/DashboardController.php.html | 223 ------ .../Api/V1/FeedsController.php.html | 387 --------- .../Api/V1/LogsController.php.html | 198 ----- .../V1/PlatformAccountsController.php.html | 417 ---------- .../V1/PlatformChannelsController.php.html | 398 ---------- .../Api/V1/RoutingController.php.html | 430 ---------- .../Api/V1/SettingsController.php.html | 240 ------ .../Http/Controllers/Api/V1/dashboard.html | 365 --------- .../Http/Controllers/Api/V1/index.html | 374 --------- .../Http/Controllers/Api/dashboard.html | 364 --------- .../Http/Controllers/Api/index.html | 121 --- .../Controllers/ArticlesController.php.html | 234 ------ .../Http/Controllers/Controller.php.html | 109 --- .../Http/Controllers/FeedsController.php.html | 388 --------- .../Http/Controllers/LogsController.php.html | 170 ---- .../Controllers/OnboardingController.php.html | 443 ----------- .../PlatformAccountsController.php.html | 391 --------- .../PlatformChannelsController.php.html | 423 ---------- .../Controllers/RoutingController.php.html | 480 ------------ .../Controllers/SettingsController.php.html | 214 ----- .../Http/Controllers/dashboard.html | 439 ----------- .../Http/Controllers/index.html | 357 --------- .../Http/Middleware/HandleAppearance.php.html | 176 ----- .../Middleware/HandleInertiaRequests.php.html | 217 ----- .../Http/Middleware/dashboard.html | 290 ------- .../Http/Middleware/index.html | 148 ---- .../Http/Requests/StoreFeedRequest.php.html | 203 ----- .../Http/Requests/UpdateFeedRequest.php.html | 204 ----- .../Http/Requests/dashboard.html | 285 ------- .../coverage-report/Http/Requests/index.html | 148 ---- .../ArticlePublicationResource.php.html | 179 ----- .../Http/Resources/ArticleResource.php.html | 189 ----- .../Http/Resources/FeedResource.php.html | 184 ----- .../PlatformAccountResource.php.html | 184 ----- .../PlatformChannelResource.php.html | 184 ----- .../PlatformInstanceResource.php.html | 180 ----- .../Http/Resources/RouteResource.php.html | 182 ----- .../Http/Resources/dashboard.html | 295 ------- .../coverage-report/Http/Resources/index.html | 288 ------- backend/coverage-report/Http/dashboard.html | 453 ----------- backend/coverage-report/Http/index.html | 203 ----- .../Jobs/ArticleDiscoveryForFeedJob.php.html | 257 ------ .../Jobs/ArticleDiscoveryJob.php.html | 207 ----- .../Jobs/PublishToLemmyJob.php.html | 212 ----- .../Jobs/SyncChannelPostsJob.php.html | 352 --------- backend/coverage-report/Jobs/dashboard.html | 301 ------- backend/coverage-report/Jobs/index.html | 203 ----- .../Listeners/LogExceptionToDatabase.php.html | 179 ----- .../Listeners/PublishApprovedArticle.php.html | 179 ----- .../Listeners/PublishArticle.php.html | 213 ----- .../ValidateArticleListener.php.html | 201 ----- .../coverage-report/Listeners/dashboard.html | 294 ------- backend/coverage-report/Listeners/index.html | 203 ----- backend/coverage-report/LogLevelEnum.php.html | 177 ----- .../coverage-report/Models/Article.php.html | 522 ------------ .../Models/ArticlePublication.php.html | 196 ----- backend/coverage-report/Models/Feed.php.html | 382 --------- .../coverage-report/Models/Keyword.php.html | 223 ------ .../coverage-report/Models/Language.php.html | 248 ------ backend/coverage-report/Models/Log.php.html | 136 ---- .../Models/PlatformAccount.php.html | 384 --------- .../Models/PlatformChannel.php.html | 387 --------- .../Models/PlatformChannelPost.php.html | 255 ------ .../Models/PlatformInstance.php.html | 259 ------ backend/coverage-report/Models/Route.php.html | 263 ------- .../coverage-report/Models/Setting.php.html | 360 --------- backend/coverage-report/Models/User.php.html | 201 ----- backend/coverage-report/Models/dashboard.html | 326 -------- backend/coverage-report/Models/index.html | 440 ----------- .../Modules/Lemmy/LemmyRequest.php.html | 275 ------- .../Lemmy/Services/LemmyApiService.php.html | 438 ----------- .../Lemmy/Services/LemmyPublisher.php.html | 223 ------ .../Modules/Lemmy/Services/dashboard.html | 302 ------- .../Modules/Lemmy/Services/index.html | 149 ---- .../Modules/Lemmy/dashboard.html | 309 -------- .../coverage-report/Modules/Lemmy/index.html | 148 ---- .../coverage-report/Modules/dashboard.html | 308 -------- backend/coverage-report/Modules/index.html | 119 --- .../Providers/AppServiceProvider.php.html | 260 ------ .../Providers/HorizonServiceProvider.php.html | 208 ----- .../coverage-report/Providers/dashboard.html | 290 ------- backend/coverage-report/Providers/index.html | 147 ---- .../Services/Article/ArticleFetcher.php.html | 354 --------- .../Article/ValidationService.php.html | 228 ------ .../Services/Article/dashboard.html | 301 ------- .../Services/Article/index.html | 148 ---- .../Services/Auth/LemmyAuthService.php.html | 194 ----- .../Services/Auth/dashboard.html | 289 ------- .../coverage-report/Services/Auth/index.html | 120 --- .../Services/DashboardStatsService.php.html | 306 -------- .../Factories/ArticleParserFactory.php.html | 250 ------ .../Factories/HomepageParserFactory.php.html | 220 ------ .../Services/Factories/dashboard.html | 296 ------- .../Services/Factories/index.html | 148 ---- .../Services/Http/HttpFetcher.php.html | 256 ------ .../Services/Http/dashboard.html | 289 ------- .../coverage-report/Services/Http/index.html | 120 --- .../Services/Log/LogSaver.php.html | 306 -------- .../Services/Log/dashboard.html | 290 ------- .../coverage-report/Services/Log/index.html | 120 --- .../OnboardingRedirectService.php.html | 172 ---- .../Parsers/BelgaArticlePageParser.php.html | 351 --------- .../Parsers/BelgaArticleParser.php.html | 220 ------ .../Parsers/BelgaHomepageParser.php.html | 173 ---- .../BelgaHomepageParserAdapter.php.html | 247 ------ .../Parsers/VrtArticlePageParser.php.html | 333 -------- .../Parsers/VrtArticleParser.php.html | 220 ------ .../Parsers/VrtHomepageParser.php.html | 175 ----- .../Parsers/VrtHomepageParserAdapter.php.html | 247 ------ .../Services/Parsers/dashboard.html | 325 -------- .../Services/Parsers/index.html | 316 -------- .../ArticlePublishingService.php.html | 260 ------ .../Services/Publishing/dashboard.html | 291 ------- .../Services/Publishing/index.html | 120 --- .../RoutingValidationService.php.html | 184 ----- .../Services/SystemStatusService.php.html | 226 ------ .../coverage-report/Services/dashboard.html | 383 --------- backend/coverage-report/Services/index.html | 399 ---------- .../coverage-report/_css/bootstrap.min.css | 6 - backend/coverage-report/_css/custom.css | 0 backend/coverage-report/_css/nv.d3.min.css | 1 - backend/coverage-report/_css/octicons.css | 5 - backend/coverage-report/_css/style.css | 201 ----- backend/coverage-report/_icons/file-code.svg | 1 - .../coverage-report/_icons/file-directory.svg | 1 - .../_js/bootstrap.bundle.min.js | 7 - backend/coverage-report/_js/d3.min.js | 5 - backend/coverage-report/_js/file.js | 53 -- backend/coverage-report/_js/jquery.min.js | 2 - backend/coverage-report/_js/nv.d3.min.js | 8 - backend/coverage-report/dashboard.html | 670 ---------------- backend/coverage-report/index.html | 424 ---------- 811 files changed, 1 insertion(+), 191868 deletions(-) delete mode 100644 backend/coverage-report-controllers/Console/Commands/FetchNewArticlesCommand.php.html delete mode 100644 backend/coverage-report-controllers/Console/Commands/SyncChannelPostsCommand.php.html delete mode 100644 backend/coverage-report-controllers/Console/Commands/dashboard.html delete mode 100644 backend/coverage-report-controllers/Console/Commands/index.html delete mode 100644 backend/coverage-report-controllers/Console/dashboard.html delete mode 100644 backend/coverage-report-controllers/Console/index.html delete mode 100644 backend/coverage-report-controllers/Contracts/ArticleParserInterface.php.html delete mode 100644 backend/coverage-report-controllers/Contracts/HomepageParserInterface.php.html delete mode 100644 backend/coverage-report-controllers/Contracts/dashboard.html delete mode 100644 backend/coverage-report-controllers/Contracts/index.html delete mode 100644 backend/coverage-report-controllers/Enums/PlatformEnum.php.html delete mode 100644 backend/coverage-report-controllers/Enums/dashboard.html delete mode 100644 backend/coverage-report-controllers/Enums/index.html delete mode 100644 backend/coverage-report-controllers/Events/ArticleApproved.php.html delete mode 100644 backend/coverage-report-controllers/Events/ArticleReadyToPublish.php.html delete mode 100644 backend/coverage-report-controllers/Events/ExceptionLogged.php.html delete mode 100644 backend/coverage-report-controllers/Events/ExceptionOccurred.php.html delete mode 100644 backend/coverage-report-controllers/Events/NewArticleFetched.php.html delete mode 100644 backend/coverage-report-controllers/Events/dashboard.html delete mode 100644 backend/coverage-report-controllers/Events/index.html delete mode 100644 backend/coverage-report-controllers/Exceptions/ChannelException.php.html delete mode 100644 backend/coverage-report-controllers/Exceptions/PlatformAuthException.php.html delete mode 100644 backend/coverage-report-controllers/Exceptions/PublishException.php.html delete mode 100644 backend/coverage-report-controllers/Exceptions/RoutingException.php.html delete mode 100644 backend/coverage-report-controllers/Exceptions/RoutingMismatchException.php.html delete mode 100644 backend/coverage-report-controllers/Exceptions/dashboard.html delete mode 100644 backend/coverage-report-controllers/Exceptions/index.html delete mode 100644 backend/coverage-report-controllers/Http/Controllers/Api/V1/ArticlesController.php.html delete mode 100644 backend/coverage-report-controllers/Http/Controllers/Api/V1/AuthController.php.html delete mode 100644 backend/coverage-report-controllers/Http/Controllers/Api/V1/BaseController.php.html delete mode 100644 backend/coverage-report-controllers/Http/Controllers/Api/V1/DashboardController.php.html delete mode 100644 backend/coverage-report-controllers/Http/Controllers/Api/V1/FeedsController.php.html delete mode 100644 backend/coverage-report-controllers/Http/Controllers/Api/V1/LogsController.php.html delete mode 100644 backend/coverage-report-controllers/Http/Controllers/Api/V1/PlatformAccountsController.php.html delete mode 100644 backend/coverage-report-controllers/Http/Controllers/Api/V1/PlatformChannelsController.php.html delete mode 100644 backend/coverage-report-controllers/Http/Controllers/Api/V1/RoutingController.php.html delete mode 100644 backend/coverage-report-controllers/Http/Controllers/Api/V1/SettingsController.php.html delete mode 100644 backend/coverage-report-controllers/Http/Controllers/Api/V1/dashboard.html delete mode 100644 backend/coverage-report-controllers/Http/Controllers/Api/V1/index.html delete mode 100644 backend/coverage-report-controllers/Http/Controllers/Api/dashboard.html delete mode 100644 backend/coverage-report-controllers/Http/Controllers/Api/index.html delete mode 100644 backend/coverage-report-controllers/Http/Controllers/ArticlesController.php.html delete mode 100644 backend/coverage-report-controllers/Http/Controllers/Controller.php.html delete mode 100644 backend/coverage-report-controllers/Http/Controllers/FeedsController.php.html delete mode 100644 backend/coverage-report-controllers/Http/Controllers/LogsController.php.html delete mode 100644 backend/coverage-report-controllers/Http/Controllers/OnboardingController.php.html delete mode 100644 backend/coverage-report-controllers/Http/Controllers/PlatformAccountsController.php.html delete mode 100644 backend/coverage-report-controllers/Http/Controllers/PlatformChannelsController.php.html delete mode 100644 backend/coverage-report-controllers/Http/Controllers/RoutingController.php.html delete mode 100644 backend/coverage-report-controllers/Http/Controllers/SettingsController.php.html delete mode 100644 backend/coverage-report-controllers/Http/Controllers/dashboard.html delete mode 100644 backend/coverage-report-controllers/Http/Controllers/index.html delete mode 100644 backend/coverage-report-controllers/Http/Middleware/HandleAppearance.php.html delete mode 100644 backend/coverage-report-controllers/Http/Middleware/HandleInertiaRequests.php.html delete mode 100644 backend/coverage-report-controllers/Http/Middleware/dashboard.html delete mode 100644 backend/coverage-report-controllers/Http/Middleware/index.html delete mode 100644 backend/coverage-report-controllers/Http/Requests/StoreFeedRequest.php.html delete mode 100644 backend/coverage-report-controllers/Http/Requests/UpdateFeedRequest.php.html delete mode 100644 backend/coverage-report-controllers/Http/Requests/dashboard.html delete mode 100644 backend/coverage-report-controllers/Http/Requests/index.html delete mode 100644 backend/coverage-report-controllers/Http/Resources/ArticlePublicationResource.php.html delete mode 100644 backend/coverage-report-controllers/Http/Resources/ArticleResource.php.html delete mode 100644 backend/coverage-report-controllers/Http/Resources/FeedResource.php.html delete mode 100644 backend/coverage-report-controllers/Http/Resources/PlatformAccountResource.php.html delete mode 100644 backend/coverage-report-controllers/Http/Resources/PlatformChannelResource.php.html delete mode 100644 backend/coverage-report-controllers/Http/Resources/PlatformInstanceResource.php.html delete mode 100644 backend/coverage-report-controllers/Http/Resources/RouteResource.php.html delete mode 100644 backend/coverage-report-controllers/Http/Resources/dashboard.html delete mode 100644 backend/coverage-report-controllers/Http/Resources/index.html delete mode 100644 backend/coverage-report-controllers/Http/dashboard.html delete mode 100644 backend/coverage-report-controllers/Http/index.html delete mode 100644 backend/coverage-report-controllers/Jobs/ArticleDiscoveryForFeedJob.php.html delete mode 100644 backend/coverage-report-controllers/Jobs/ArticleDiscoveryJob.php.html delete mode 100644 backend/coverage-report-controllers/Jobs/PublishToLemmyJob.php.html delete mode 100644 backend/coverage-report-controllers/Jobs/SyncChannelPostsJob.php.html delete mode 100644 backend/coverage-report-controllers/Jobs/dashboard.html delete mode 100644 backend/coverage-report-controllers/Jobs/index.html delete mode 100644 backend/coverage-report-controllers/Listeners/LogExceptionToDatabase.php.html delete mode 100644 backend/coverage-report-controllers/Listeners/PublishApprovedArticle.php.html delete mode 100644 backend/coverage-report-controllers/Listeners/PublishArticle.php.html delete mode 100644 backend/coverage-report-controllers/Listeners/ValidateArticleListener.php.html delete mode 100644 backend/coverage-report-controllers/Listeners/dashboard.html delete mode 100644 backend/coverage-report-controllers/Listeners/index.html delete mode 100644 backend/coverage-report-controllers/LogLevelEnum.php.html delete mode 100644 backend/coverage-report-controllers/Models/Article.php.html delete mode 100644 backend/coverage-report-controllers/Models/ArticlePublication.php.html delete mode 100644 backend/coverage-report-controllers/Models/Feed.php.html delete mode 100644 backend/coverage-report-controllers/Models/Keyword.php.html delete mode 100644 backend/coverage-report-controllers/Models/Language.php.html delete mode 100644 backend/coverage-report-controllers/Models/Log.php.html delete mode 100644 backend/coverage-report-controllers/Models/PlatformAccount.php.html delete mode 100644 backend/coverage-report-controllers/Models/PlatformChannel.php.html delete mode 100644 backend/coverage-report-controllers/Models/PlatformChannelPost.php.html delete mode 100644 backend/coverage-report-controllers/Models/PlatformInstance.php.html delete mode 100644 backend/coverage-report-controllers/Models/Route.php.html delete mode 100644 backend/coverage-report-controllers/Models/Setting.php.html delete mode 100644 backend/coverage-report-controllers/Models/User.php.html delete mode 100644 backend/coverage-report-controllers/Models/dashboard.html delete mode 100644 backend/coverage-report-controllers/Models/index.html delete mode 100644 backend/coverage-report-controllers/Modules/Lemmy/LemmyRequest.php.html delete mode 100644 backend/coverage-report-controllers/Modules/Lemmy/Services/LemmyApiService.php.html delete mode 100644 backend/coverage-report-controllers/Modules/Lemmy/Services/LemmyPublisher.php.html delete mode 100644 backend/coverage-report-controllers/Modules/Lemmy/Services/dashboard.html delete mode 100644 backend/coverage-report-controllers/Modules/Lemmy/Services/index.html delete mode 100644 backend/coverage-report-controllers/Modules/Lemmy/dashboard.html delete mode 100644 backend/coverage-report-controllers/Modules/Lemmy/index.html delete mode 100644 backend/coverage-report-controllers/Modules/dashboard.html delete mode 100644 backend/coverage-report-controllers/Modules/index.html delete mode 100644 backend/coverage-report-controllers/Providers/AppServiceProvider.php.html delete mode 100644 backend/coverage-report-controllers/Providers/HorizonServiceProvider.php.html delete mode 100644 backend/coverage-report-controllers/Providers/dashboard.html delete mode 100644 backend/coverage-report-controllers/Providers/index.html delete mode 100644 backend/coverage-report-controllers/Services/Article/ArticleFetcher.php.html delete mode 100644 backend/coverage-report-controllers/Services/Article/ValidationService.php.html delete mode 100644 backend/coverage-report-controllers/Services/Article/dashboard.html delete mode 100644 backend/coverage-report-controllers/Services/Article/index.html delete mode 100644 backend/coverage-report-controllers/Services/Auth/LemmyAuthService.php.html delete mode 100644 backend/coverage-report-controllers/Services/Auth/dashboard.html delete mode 100644 backend/coverage-report-controllers/Services/Auth/index.html delete mode 100644 backend/coverage-report-controllers/Services/DashboardStatsService.php.html delete mode 100644 backend/coverage-report-controllers/Services/Factories/ArticleParserFactory.php.html delete mode 100644 backend/coverage-report-controllers/Services/Factories/HomepageParserFactory.php.html delete mode 100644 backend/coverage-report-controllers/Services/Factories/dashboard.html delete mode 100644 backend/coverage-report-controllers/Services/Factories/index.html delete mode 100644 backend/coverage-report-controllers/Services/Http/HttpFetcher.php.html delete mode 100644 backend/coverage-report-controllers/Services/Http/dashboard.html delete mode 100644 backend/coverage-report-controllers/Services/Http/index.html delete mode 100644 backend/coverage-report-controllers/Services/Log/LogSaver.php.html delete mode 100644 backend/coverage-report-controllers/Services/Log/dashboard.html delete mode 100644 backend/coverage-report-controllers/Services/Log/index.html delete mode 100644 backend/coverage-report-controllers/Services/OnboardingRedirectService.php.html delete mode 100644 backend/coverage-report-controllers/Services/Parsers/BelgaArticlePageParser.php.html delete mode 100644 backend/coverage-report-controllers/Services/Parsers/BelgaArticleParser.php.html delete mode 100644 backend/coverage-report-controllers/Services/Parsers/BelgaHomepageParser.php.html delete mode 100644 backend/coverage-report-controllers/Services/Parsers/BelgaHomepageParserAdapter.php.html delete mode 100644 backend/coverage-report-controllers/Services/Parsers/VrtArticlePageParser.php.html delete mode 100644 backend/coverage-report-controllers/Services/Parsers/VrtArticleParser.php.html delete mode 100644 backend/coverage-report-controllers/Services/Parsers/VrtHomepageParser.php.html delete mode 100644 backend/coverage-report-controllers/Services/Parsers/VrtHomepageParserAdapter.php.html delete mode 100644 backend/coverage-report-controllers/Services/Parsers/dashboard.html delete mode 100644 backend/coverage-report-controllers/Services/Parsers/index.html delete mode 100644 backend/coverage-report-controllers/Services/Publishing/ArticlePublishingService.php.html delete mode 100644 backend/coverage-report-controllers/Services/Publishing/dashboard.html delete mode 100644 backend/coverage-report-controllers/Services/Publishing/index.html delete mode 100644 backend/coverage-report-controllers/Services/RoutingValidationService.php.html delete mode 100644 backend/coverage-report-controllers/Services/SystemStatusService.php.html delete mode 100644 backend/coverage-report-controllers/Services/dashboard.html delete mode 100644 backend/coverage-report-controllers/Services/index.html delete mode 100644 backend/coverage-report-controllers/_css/bootstrap.min.css delete mode 100644 backend/coverage-report-controllers/_css/custom.css delete mode 100644 backend/coverage-report-controllers/_css/nv.d3.min.css delete mode 100644 backend/coverage-report-controllers/_css/octicons.css delete mode 100644 backend/coverage-report-controllers/_css/style.css delete mode 100644 backend/coverage-report-controllers/_icons/file-code.svg delete mode 100644 backend/coverage-report-controllers/_icons/file-directory.svg delete mode 100644 backend/coverage-report-controllers/_js/bootstrap.bundle.min.js delete mode 100644 backend/coverage-report-controllers/_js/d3.min.js delete mode 100644 backend/coverage-report-controllers/_js/file.js delete mode 100644 backend/coverage-report-controllers/_js/jquery.min.js delete mode 100644 backend/coverage-report-controllers/_js/nv.d3.min.js delete mode 100644 backend/coverage-report-controllers/dashboard.html delete mode 100644 backend/coverage-report-controllers/index.html delete mode 100644 backend/coverage-report-final/Console/Commands/FetchNewArticlesCommand.php.html delete mode 100644 backend/coverage-report-final/Console/Commands/SyncChannelPostsCommand.php.html delete mode 100644 backend/coverage-report-final/Console/Commands/dashboard.html delete mode 100644 backend/coverage-report-final/Console/Commands/index.html delete mode 100644 backend/coverage-report-final/Console/dashboard.html delete mode 100644 backend/coverage-report-final/Console/index.html delete mode 100644 backend/coverage-report-final/Contracts/ArticleParserInterface.php.html delete mode 100644 backend/coverage-report-final/Contracts/HomepageParserInterface.php.html delete mode 100644 backend/coverage-report-final/Contracts/dashboard.html delete mode 100644 backend/coverage-report-final/Contracts/index.html delete mode 100644 backend/coverage-report-final/Enums/PlatformEnum.php.html delete mode 100644 backend/coverage-report-final/Enums/dashboard.html delete mode 100644 backend/coverage-report-final/Enums/index.html delete mode 100644 backend/coverage-report-final/Events/ArticleApproved.php.html delete mode 100644 backend/coverage-report-final/Events/ArticleReadyToPublish.php.html delete mode 100644 backend/coverage-report-final/Events/ExceptionLogged.php.html delete mode 100644 backend/coverage-report-final/Events/ExceptionOccurred.php.html delete mode 100644 backend/coverage-report-final/Events/NewArticleFetched.php.html delete mode 100644 backend/coverage-report-final/Events/dashboard.html delete mode 100644 backend/coverage-report-final/Events/index.html delete mode 100644 backend/coverage-report-final/Exceptions/ChannelException.php.html delete mode 100644 backend/coverage-report-final/Exceptions/PlatformAuthException.php.html delete mode 100644 backend/coverage-report-final/Exceptions/PublishException.php.html delete mode 100644 backend/coverage-report-final/Exceptions/RoutingException.php.html delete mode 100644 backend/coverage-report-final/Exceptions/RoutingMismatchException.php.html delete mode 100644 backend/coverage-report-final/Exceptions/dashboard.html delete mode 100644 backend/coverage-report-final/Exceptions/index.html delete mode 100644 backend/coverage-report-final/Http/Controllers/Api/V1/ArticlesController.php.html delete mode 100644 backend/coverage-report-final/Http/Controllers/Api/V1/AuthController.php.html delete mode 100644 backend/coverage-report-final/Http/Controllers/Api/V1/BaseController.php.html delete mode 100644 backend/coverage-report-final/Http/Controllers/Api/V1/DashboardController.php.html delete mode 100644 backend/coverage-report-final/Http/Controllers/Api/V1/FeedsController.php.html delete mode 100644 backend/coverage-report-final/Http/Controllers/Api/V1/LogsController.php.html delete mode 100644 backend/coverage-report-final/Http/Controllers/Api/V1/PlatformAccountsController.php.html delete mode 100644 backend/coverage-report-final/Http/Controllers/Api/V1/PlatformChannelsController.php.html delete mode 100644 backend/coverage-report-final/Http/Controllers/Api/V1/RoutingController.php.html delete mode 100644 backend/coverage-report-final/Http/Controllers/Api/V1/SettingsController.php.html delete mode 100644 backend/coverage-report-final/Http/Controllers/Api/V1/dashboard.html delete mode 100644 backend/coverage-report-final/Http/Controllers/Api/V1/index.html delete mode 100644 backend/coverage-report-final/Http/Controllers/Api/dashboard.html delete mode 100644 backend/coverage-report-final/Http/Controllers/Api/index.html delete mode 100644 backend/coverage-report-final/Http/Controllers/ArticlesController.php.html delete mode 100644 backend/coverage-report-final/Http/Controllers/Controller.php.html delete mode 100644 backend/coverage-report-final/Http/Controllers/FeedsController.php.html delete mode 100644 backend/coverage-report-final/Http/Controllers/LogsController.php.html delete mode 100644 backend/coverage-report-final/Http/Controllers/OnboardingController.php.html delete mode 100644 backend/coverage-report-final/Http/Controllers/PlatformAccountsController.php.html delete mode 100644 backend/coverage-report-final/Http/Controllers/PlatformChannelsController.php.html delete mode 100644 backend/coverage-report-final/Http/Controllers/RoutingController.php.html delete mode 100644 backend/coverage-report-final/Http/Controllers/SettingsController.php.html delete mode 100644 backend/coverage-report-final/Http/Controllers/dashboard.html delete mode 100644 backend/coverage-report-final/Http/Controllers/index.html delete mode 100644 backend/coverage-report-final/Http/Middleware/HandleAppearance.php.html delete mode 100644 backend/coverage-report-final/Http/Middleware/HandleInertiaRequests.php.html delete mode 100644 backend/coverage-report-final/Http/Middleware/dashboard.html delete mode 100644 backend/coverage-report-final/Http/Middleware/index.html delete mode 100644 backend/coverage-report-final/Http/Requests/StoreFeedRequest.php.html delete mode 100644 backend/coverage-report-final/Http/Requests/UpdateFeedRequest.php.html delete mode 100644 backend/coverage-report-final/Http/Requests/dashboard.html delete mode 100644 backend/coverage-report-final/Http/Requests/index.html delete mode 100644 backend/coverage-report-final/Http/Resources/ArticlePublicationResource.php.html delete mode 100644 backend/coverage-report-final/Http/Resources/ArticleResource.php.html delete mode 100644 backend/coverage-report-final/Http/Resources/FeedResource.php.html delete mode 100644 backend/coverage-report-final/Http/Resources/PlatformAccountResource.php.html delete mode 100644 backend/coverage-report-final/Http/Resources/PlatformChannelResource.php.html delete mode 100644 backend/coverage-report-final/Http/Resources/PlatformInstanceResource.php.html delete mode 100644 backend/coverage-report-final/Http/Resources/RouteResource.php.html delete mode 100644 backend/coverage-report-final/Http/Resources/dashboard.html delete mode 100644 backend/coverage-report-final/Http/Resources/index.html delete mode 100644 backend/coverage-report-final/Http/dashboard.html delete mode 100644 backend/coverage-report-final/Http/index.html delete mode 100644 backend/coverage-report-final/Jobs/ArticleDiscoveryForFeedJob.php.html delete mode 100644 backend/coverage-report-final/Jobs/ArticleDiscoveryJob.php.html delete mode 100644 backend/coverage-report-final/Jobs/PublishToLemmyJob.php.html delete mode 100644 backend/coverage-report-final/Jobs/SyncChannelPostsJob.php.html delete mode 100644 backend/coverage-report-final/Jobs/dashboard.html delete mode 100644 backend/coverage-report-final/Jobs/index.html delete mode 100644 backend/coverage-report-final/Listeners/LogExceptionToDatabase.php.html delete mode 100644 backend/coverage-report-final/Listeners/PublishApprovedArticle.php.html delete mode 100644 backend/coverage-report-final/Listeners/PublishArticle.php.html delete mode 100644 backend/coverage-report-final/Listeners/ValidateArticleListener.php.html delete mode 100644 backend/coverage-report-final/Listeners/dashboard.html delete mode 100644 backend/coverage-report-final/Listeners/index.html delete mode 100644 backend/coverage-report-final/LogLevelEnum.php.html delete mode 100644 backend/coverage-report-final/Models/Article.php.html delete mode 100644 backend/coverage-report-final/Models/ArticlePublication.php.html delete mode 100644 backend/coverage-report-final/Models/Feed.php.html delete mode 100644 backend/coverage-report-final/Models/Keyword.php.html delete mode 100644 backend/coverage-report-final/Models/Language.php.html delete mode 100644 backend/coverage-report-final/Models/Log.php.html delete mode 100644 backend/coverage-report-final/Models/PlatformAccount.php.html delete mode 100644 backend/coverage-report-final/Models/PlatformChannel.php.html delete mode 100644 backend/coverage-report-final/Models/PlatformChannelPost.php.html delete mode 100644 backend/coverage-report-final/Models/PlatformInstance.php.html delete mode 100644 backend/coverage-report-final/Models/Route.php.html delete mode 100644 backend/coverage-report-final/Models/Setting.php.html delete mode 100644 backend/coverage-report-final/Models/User.php.html delete mode 100644 backend/coverage-report-final/Models/dashboard.html delete mode 100644 backend/coverage-report-final/Models/index.html delete mode 100644 backend/coverage-report-final/Modules/Lemmy/LemmyRequest.php.html delete mode 100644 backend/coverage-report-final/Modules/Lemmy/Services/LemmyApiService.php.html delete mode 100644 backend/coverage-report-final/Modules/Lemmy/Services/LemmyPublisher.php.html delete mode 100644 backend/coverage-report-final/Modules/Lemmy/Services/dashboard.html delete mode 100644 backend/coverage-report-final/Modules/Lemmy/Services/index.html delete mode 100644 backend/coverage-report-final/Modules/Lemmy/dashboard.html delete mode 100644 backend/coverage-report-final/Modules/Lemmy/index.html delete mode 100644 backend/coverage-report-final/Modules/dashboard.html delete mode 100644 backend/coverage-report-final/Modules/index.html delete mode 100644 backend/coverage-report-final/Providers/AppServiceProvider.php.html delete mode 100644 backend/coverage-report-final/Providers/HorizonServiceProvider.php.html delete mode 100644 backend/coverage-report-final/Providers/dashboard.html delete mode 100644 backend/coverage-report-final/Providers/index.html delete mode 100644 backend/coverage-report-final/Services/Article/ArticleFetcher.php.html delete mode 100644 backend/coverage-report-final/Services/Article/ValidationService.php.html delete mode 100644 backend/coverage-report-final/Services/Article/dashboard.html delete mode 100644 backend/coverage-report-final/Services/Article/index.html delete mode 100644 backend/coverage-report-final/Services/Auth/LemmyAuthService.php.html delete mode 100644 backend/coverage-report-final/Services/Auth/dashboard.html delete mode 100644 backend/coverage-report-final/Services/Auth/index.html delete mode 100644 backend/coverage-report-final/Services/DashboardStatsService.php.html delete mode 100644 backend/coverage-report-final/Services/Factories/ArticleParserFactory.php.html delete mode 100644 backend/coverage-report-final/Services/Factories/HomepageParserFactory.php.html delete mode 100644 backend/coverage-report-final/Services/Factories/dashboard.html delete mode 100644 backend/coverage-report-final/Services/Factories/index.html delete mode 100644 backend/coverage-report-final/Services/Http/HttpFetcher.php.html delete mode 100644 backend/coverage-report-final/Services/Http/dashboard.html delete mode 100644 backend/coverage-report-final/Services/Http/index.html delete mode 100644 backend/coverage-report-final/Services/Log/LogSaver.php.html delete mode 100644 backend/coverage-report-final/Services/Log/dashboard.html delete mode 100644 backend/coverage-report-final/Services/Log/index.html delete mode 100644 backend/coverage-report-final/Services/OnboardingRedirectService.php.html delete mode 100644 backend/coverage-report-final/Services/Parsers/BelgaArticlePageParser.php.html delete mode 100644 backend/coverage-report-final/Services/Parsers/BelgaArticleParser.php.html delete mode 100644 backend/coverage-report-final/Services/Parsers/BelgaHomepageParser.php.html delete mode 100644 backend/coverage-report-final/Services/Parsers/BelgaHomepageParserAdapter.php.html delete mode 100644 backend/coverage-report-final/Services/Parsers/VrtArticlePageParser.php.html delete mode 100644 backend/coverage-report-final/Services/Parsers/VrtArticleParser.php.html delete mode 100644 backend/coverage-report-final/Services/Parsers/VrtHomepageParser.php.html delete mode 100644 backend/coverage-report-final/Services/Parsers/VrtHomepageParserAdapter.php.html delete mode 100644 backend/coverage-report-final/Services/Parsers/dashboard.html delete mode 100644 backend/coverage-report-final/Services/Parsers/index.html delete mode 100644 backend/coverage-report-final/Services/Publishing/ArticlePublishingService.php.html delete mode 100644 backend/coverage-report-final/Services/Publishing/dashboard.html delete mode 100644 backend/coverage-report-final/Services/Publishing/index.html delete mode 100644 backend/coverage-report-final/Services/RoutingValidationService.php.html delete mode 100644 backend/coverage-report-final/Services/SystemStatusService.php.html delete mode 100644 backend/coverage-report-final/Services/dashboard.html delete mode 100644 backend/coverage-report-final/Services/index.html delete mode 100644 backend/coverage-report-final/_css/bootstrap.min.css delete mode 100644 backend/coverage-report-final/_css/custom.css delete mode 100644 backend/coverage-report-final/_css/nv.d3.min.css delete mode 100644 backend/coverage-report-final/_css/octicons.css delete mode 100644 backend/coverage-report-final/_css/style.css delete mode 100644 backend/coverage-report-final/_icons/file-code.svg delete mode 100644 backend/coverage-report-final/_icons/file-directory.svg delete mode 100644 backend/coverage-report-final/_js/bootstrap.bundle.min.js delete mode 100644 backend/coverage-report-final/_js/d3.min.js delete mode 100644 backend/coverage-report-final/_js/file.js delete mode 100644 backend/coverage-report-final/_js/jquery.min.js delete mode 100644 backend/coverage-report-final/_js/nv.d3.min.js delete mode 100644 backend/coverage-report-final/dashboard.html delete mode 100644 backend/coverage-report-final/index.html delete mode 100644 backend/coverage-report-progress/Console/Commands/FetchNewArticlesCommand.php.html delete mode 100644 backend/coverage-report-progress/Console/Commands/SyncChannelPostsCommand.php.html delete mode 100644 backend/coverage-report-progress/Console/Commands/dashboard.html delete mode 100644 backend/coverage-report-progress/Console/Commands/index.html delete mode 100644 backend/coverage-report-progress/Console/dashboard.html delete mode 100644 backend/coverage-report-progress/Console/index.html delete mode 100644 backend/coverage-report-progress/Contracts/ArticleParserInterface.php.html delete mode 100644 backend/coverage-report-progress/Contracts/HomepageParserInterface.php.html delete mode 100644 backend/coverage-report-progress/Contracts/dashboard.html delete mode 100644 backend/coverage-report-progress/Contracts/index.html delete mode 100644 backend/coverage-report-progress/Enums/PlatformEnum.php.html delete mode 100644 backend/coverage-report-progress/Enums/dashboard.html delete mode 100644 backend/coverage-report-progress/Enums/index.html delete mode 100644 backend/coverage-report-progress/Events/ArticleApproved.php.html delete mode 100644 backend/coverage-report-progress/Events/ArticleReadyToPublish.php.html delete mode 100644 backend/coverage-report-progress/Events/ExceptionLogged.php.html delete mode 100644 backend/coverage-report-progress/Events/ExceptionOccurred.php.html delete mode 100644 backend/coverage-report-progress/Events/NewArticleFetched.php.html delete mode 100644 backend/coverage-report-progress/Events/dashboard.html delete mode 100644 backend/coverage-report-progress/Events/index.html delete mode 100644 backend/coverage-report-progress/Exceptions/ChannelException.php.html delete mode 100644 backend/coverage-report-progress/Exceptions/PlatformAuthException.php.html delete mode 100644 backend/coverage-report-progress/Exceptions/PublishException.php.html delete mode 100644 backend/coverage-report-progress/Exceptions/RoutingException.php.html delete mode 100644 backend/coverage-report-progress/Exceptions/RoutingMismatchException.php.html delete mode 100644 backend/coverage-report-progress/Exceptions/dashboard.html delete mode 100644 backend/coverage-report-progress/Exceptions/index.html delete mode 100644 backend/coverage-report-progress/Http/Controllers/Api/V1/ArticlesController.php.html delete mode 100644 backend/coverage-report-progress/Http/Controllers/Api/V1/AuthController.php.html delete mode 100644 backend/coverage-report-progress/Http/Controllers/Api/V1/BaseController.php.html delete mode 100644 backend/coverage-report-progress/Http/Controllers/Api/V1/DashboardController.php.html delete mode 100644 backend/coverage-report-progress/Http/Controllers/Api/V1/FeedsController.php.html delete mode 100644 backend/coverage-report-progress/Http/Controllers/Api/V1/LogsController.php.html delete mode 100644 backend/coverage-report-progress/Http/Controllers/Api/V1/PlatformAccountsController.php.html delete mode 100644 backend/coverage-report-progress/Http/Controllers/Api/V1/PlatformChannelsController.php.html delete mode 100644 backend/coverage-report-progress/Http/Controllers/Api/V1/RoutingController.php.html delete mode 100644 backend/coverage-report-progress/Http/Controllers/Api/V1/SettingsController.php.html delete mode 100644 backend/coverage-report-progress/Http/Controllers/Api/V1/dashboard.html delete mode 100644 backend/coverage-report-progress/Http/Controllers/Api/V1/index.html delete mode 100644 backend/coverage-report-progress/Http/Controllers/Api/dashboard.html delete mode 100644 backend/coverage-report-progress/Http/Controllers/Api/index.html delete mode 100644 backend/coverage-report-progress/Http/Controllers/ArticlesController.php.html delete mode 100644 backend/coverage-report-progress/Http/Controllers/Controller.php.html delete mode 100644 backend/coverage-report-progress/Http/Controllers/FeedsController.php.html delete mode 100644 backend/coverage-report-progress/Http/Controllers/LogsController.php.html delete mode 100644 backend/coverage-report-progress/Http/Controllers/OnboardingController.php.html delete mode 100644 backend/coverage-report-progress/Http/Controllers/PlatformAccountsController.php.html delete mode 100644 backend/coverage-report-progress/Http/Controllers/PlatformChannelsController.php.html delete mode 100644 backend/coverage-report-progress/Http/Controllers/RoutingController.php.html delete mode 100644 backend/coverage-report-progress/Http/Controllers/SettingsController.php.html delete mode 100644 backend/coverage-report-progress/Http/Controllers/dashboard.html delete mode 100644 backend/coverage-report-progress/Http/Controllers/index.html delete mode 100644 backend/coverage-report-progress/Http/Middleware/HandleAppearance.php.html delete mode 100644 backend/coverage-report-progress/Http/Middleware/HandleInertiaRequests.php.html delete mode 100644 backend/coverage-report-progress/Http/Middleware/dashboard.html delete mode 100644 backend/coverage-report-progress/Http/Middleware/index.html delete mode 100644 backend/coverage-report-progress/Http/Requests/StoreFeedRequest.php.html delete mode 100644 backend/coverage-report-progress/Http/Requests/UpdateFeedRequest.php.html delete mode 100644 backend/coverage-report-progress/Http/Requests/dashboard.html delete mode 100644 backend/coverage-report-progress/Http/Requests/index.html delete mode 100644 backend/coverage-report-progress/Http/Resources/ArticlePublicationResource.php.html delete mode 100644 backend/coverage-report-progress/Http/Resources/ArticleResource.php.html delete mode 100644 backend/coverage-report-progress/Http/Resources/FeedResource.php.html delete mode 100644 backend/coverage-report-progress/Http/Resources/PlatformAccountResource.php.html delete mode 100644 backend/coverage-report-progress/Http/Resources/PlatformChannelResource.php.html delete mode 100644 backend/coverage-report-progress/Http/Resources/PlatformInstanceResource.php.html delete mode 100644 backend/coverage-report-progress/Http/Resources/RouteResource.php.html delete mode 100644 backend/coverage-report-progress/Http/Resources/dashboard.html delete mode 100644 backend/coverage-report-progress/Http/Resources/index.html delete mode 100644 backend/coverage-report-progress/Http/dashboard.html delete mode 100644 backend/coverage-report-progress/Http/index.html delete mode 100644 backend/coverage-report-progress/Jobs/ArticleDiscoveryForFeedJob.php.html delete mode 100644 backend/coverage-report-progress/Jobs/ArticleDiscoveryJob.php.html delete mode 100644 backend/coverage-report-progress/Jobs/PublishToLemmyJob.php.html delete mode 100644 backend/coverage-report-progress/Jobs/SyncChannelPostsJob.php.html delete mode 100644 backend/coverage-report-progress/Jobs/dashboard.html delete mode 100644 backend/coverage-report-progress/Jobs/index.html delete mode 100644 backend/coverage-report-progress/Listeners/LogExceptionToDatabase.php.html delete mode 100644 backend/coverage-report-progress/Listeners/PublishApprovedArticle.php.html delete mode 100644 backend/coverage-report-progress/Listeners/PublishArticle.php.html delete mode 100644 backend/coverage-report-progress/Listeners/ValidateArticleListener.php.html delete mode 100644 backend/coverage-report-progress/Listeners/dashboard.html delete mode 100644 backend/coverage-report-progress/Listeners/index.html delete mode 100644 backend/coverage-report-progress/LogLevelEnum.php.html delete mode 100644 backend/coverage-report-progress/Models/Article.php.html delete mode 100644 backend/coverage-report-progress/Models/ArticlePublication.php.html delete mode 100644 backend/coverage-report-progress/Models/Feed.php.html delete mode 100644 backend/coverage-report-progress/Models/Keyword.php.html delete mode 100644 backend/coverage-report-progress/Models/Language.php.html delete mode 100644 backend/coverage-report-progress/Models/Log.php.html delete mode 100644 backend/coverage-report-progress/Models/PlatformAccount.php.html delete mode 100644 backend/coverage-report-progress/Models/PlatformChannel.php.html delete mode 100644 backend/coverage-report-progress/Models/PlatformChannelPost.php.html delete mode 100644 backend/coverage-report-progress/Models/PlatformInstance.php.html delete mode 100644 backend/coverage-report-progress/Models/Route.php.html delete mode 100644 backend/coverage-report-progress/Models/Setting.php.html delete mode 100644 backend/coverage-report-progress/Models/User.php.html delete mode 100644 backend/coverage-report-progress/Models/dashboard.html delete mode 100644 backend/coverage-report-progress/Models/index.html delete mode 100644 backend/coverage-report-progress/Modules/Lemmy/LemmyRequest.php.html delete mode 100644 backend/coverage-report-progress/Modules/Lemmy/Services/LemmyApiService.php.html delete mode 100644 backend/coverage-report-progress/Modules/Lemmy/Services/LemmyPublisher.php.html delete mode 100644 backend/coverage-report-progress/Modules/Lemmy/Services/dashboard.html delete mode 100644 backend/coverage-report-progress/Modules/Lemmy/Services/index.html delete mode 100644 backend/coverage-report-progress/Modules/Lemmy/dashboard.html delete mode 100644 backend/coverage-report-progress/Modules/Lemmy/index.html delete mode 100644 backend/coverage-report-progress/Modules/dashboard.html delete mode 100644 backend/coverage-report-progress/Modules/index.html delete mode 100644 backend/coverage-report-progress/Providers/AppServiceProvider.php.html delete mode 100644 backend/coverage-report-progress/Providers/HorizonServiceProvider.php.html delete mode 100644 backend/coverage-report-progress/Providers/dashboard.html delete mode 100644 backend/coverage-report-progress/Providers/index.html delete mode 100644 backend/coverage-report-progress/Services/Article/ArticleFetcher.php.html delete mode 100644 backend/coverage-report-progress/Services/Article/ValidationService.php.html delete mode 100644 backend/coverage-report-progress/Services/Article/dashboard.html delete mode 100644 backend/coverage-report-progress/Services/Article/index.html delete mode 100644 backend/coverage-report-progress/Services/Auth/LemmyAuthService.php.html delete mode 100644 backend/coverage-report-progress/Services/Auth/dashboard.html delete mode 100644 backend/coverage-report-progress/Services/Auth/index.html delete mode 100644 backend/coverage-report-progress/Services/DashboardStatsService.php.html delete mode 100644 backend/coverage-report-progress/Services/Factories/ArticleParserFactory.php.html delete mode 100644 backend/coverage-report-progress/Services/Factories/HomepageParserFactory.php.html delete mode 100644 backend/coverage-report-progress/Services/Factories/dashboard.html delete mode 100644 backend/coverage-report-progress/Services/Factories/index.html delete mode 100644 backend/coverage-report-progress/Services/Http/HttpFetcher.php.html delete mode 100644 backend/coverage-report-progress/Services/Http/dashboard.html delete mode 100644 backend/coverage-report-progress/Services/Http/index.html delete mode 100644 backend/coverage-report-progress/Services/Log/LogSaver.php.html delete mode 100644 backend/coverage-report-progress/Services/Log/dashboard.html delete mode 100644 backend/coverage-report-progress/Services/Log/index.html delete mode 100644 backend/coverage-report-progress/Services/OnboardingRedirectService.php.html delete mode 100644 backend/coverage-report-progress/Services/Parsers/BelgaArticlePageParser.php.html delete mode 100644 backend/coverage-report-progress/Services/Parsers/BelgaArticleParser.php.html delete mode 100644 backend/coverage-report-progress/Services/Parsers/BelgaHomepageParser.php.html delete mode 100644 backend/coverage-report-progress/Services/Parsers/BelgaHomepageParserAdapter.php.html delete mode 100644 backend/coverage-report-progress/Services/Parsers/VrtArticlePageParser.php.html delete mode 100644 backend/coverage-report-progress/Services/Parsers/VrtArticleParser.php.html delete mode 100644 backend/coverage-report-progress/Services/Parsers/VrtHomepageParser.php.html delete mode 100644 backend/coverage-report-progress/Services/Parsers/VrtHomepageParserAdapter.php.html delete mode 100644 backend/coverage-report-progress/Services/Parsers/dashboard.html delete mode 100644 backend/coverage-report-progress/Services/Parsers/index.html delete mode 100644 backend/coverage-report-progress/Services/Publishing/ArticlePublishingService.php.html delete mode 100644 backend/coverage-report-progress/Services/Publishing/dashboard.html delete mode 100644 backend/coverage-report-progress/Services/Publishing/index.html delete mode 100644 backend/coverage-report-progress/Services/RoutingValidationService.php.html delete mode 100644 backend/coverage-report-progress/Services/SystemStatusService.php.html delete mode 100644 backend/coverage-report-progress/Services/dashboard.html delete mode 100644 backend/coverage-report-progress/Services/index.html delete mode 100644 backend/coverage-report-progress/_css/bootstrap.min.css delete mode 100644 backend/coverage-report-progress/_css/custom.css delete mode 100644 backend/coverage-report-progress/_css/nv.d3.min.css delete mode 100644 backend/coverage-report-progress/_css/octicons.css delete mode 100644 backend/coverage-report-progress/_css/style.css delete mode 100644 backend/coverage-report-progress/_icons/file-code.svg delete mode 100644 backend/coverage-report-progress/_icons/file-directory.svg delete mode 100644 backend/coverage-report-progress/_js/bootstrap.bundle.min.js delete mode 100644 backend/coverage-report-progress/_js/d3.min.js delete mode 100644 backend/coverage-report-progress/_js/file.js delete mode 100644 backend/coverage-report-progress/_js/jquery.min.js delete mode 100644 backend/coverage-report-progress/_js/nv.d3.min.js delete mode 100644 backend/coverage-report-progress/dashboard.html delete mode 100644 backend/coverage-report-progress/index.html delete mode 100644 backend/coverage-report-with-models/Console/Commands/FetchNewArticlesCommand.php.html delete mode 100644 backend/coverage-report-with-models/Console/Commands/SyncChannelPostsCommand.php.html delete mode 100644 backend/coverage-report-with-models/Console/Commands/dashboard.html delete mode 100644 backend/coverage-report-with-models/Console/Commands/index.html delete mode 100644 backend/coverage-report-with-models/Console/dashboard.html delete mode 100644 backend/coverage-report-with-models/Console/index.html delete mode 100644 backend/coverage-report-with-models/Contracts/ArticleParserInterface.php.html delete mode 100644 backend/coverage-report-with-models/Contracts/HomepageParserInterface.php.html delete mode 100644 backend/coverage-report-with-models/Contracts/dashboard.html delete mode 100644 backend/coverage-report-with-models/Contracts/index.html delete mode 100644 backend/coverage-report-with-models/Enums/PlatformEnum.php.html delete mode 100644 backend/coverage-report-with-models/Enums/dashboard.html delete mode 100644 backend/coverage-report-with-models/Enums/index.html delete mode 100644 backend/coverage-report-with-models/Events/ArticleApproved.php.html delete mode 100644 backend/coverage-report-with-models/Events/ArticleReadyToPublish.php.html delete mode 100644 backend/coverage-report-with-models/Events/ExceptionLogged.php.html delete mode 100644 backend/coverage-report-with-models/Events/ExceptionOccurred.php.html delete mode 100644 backend/coverage-report-with-models/Events/NewArticleFetched.php.html delete mode 100644 backend/coverage-report-with-models/Events/dashboard.html delete mode 100644 backend/coverage-report-with-models/Events/index.html delete mode 100644 backend/coverage-report-with-models/Exceptions/ChannelException.php.html delete mode 100644 backend/coverage-report-with-models/Exceptions/PlatformAuthException.php.html delete mode 100644 backend/coverage-report-with-models/Exceptions/PublishException.php.html delete mode 100644 backend/coverage-report-with-models/Exceptions/RoutingException.php.html delete mode 100644 backend/coverage-report-with-models/Exceptions/RoutingMismatchException.php.html delete mode 100644 backend/coverage-report-with-models/Exceptions/dashboard.html delete mode 100644 backend/coverage-report-with-models/Exceptions/index.html delete mode 100644 backend/coverage-report-with-models/Http/Controllers/Api/V1/ArticlesController.php.html delete mode 100644 backend/coverage-report-with-models/Http/Controllers/Api/V1/AuthController.php.html delete mode 100644 backend/coverage-report-with-models/Http/Controllers/Api/V1/BaseController.php.html delete mode 100644 backend/coverage-report-with-models/Http/Controllers/Api/V1/DashboardController.php.html delete mode 100644 backend/coverage-report-with-models/Http/Controllers/Api/V1/FeedsController.php.html delete mode 100644 backend/coverage-report-with-models/Http/Controllers/Api/V1/LogsController.php.html delete mode 100644 backend/coverage-report-with-models/Http/Controllers/Api/V1/PlatformAccountsController.php.html delete mode 100644 backend/coverage-report-with-models/Http/Controllers/Api/V1/PlatformChannelsController.php.html delete mode 100644 backend/coverage-report-with-models/Http/Controllers/Api/V1/RoutingController.php.html delete mode 100644 backend/coverage-report-with-models/Http/Controllers/Api/V1/SettingsController.php.html delete mode 100644 backend/coverage-report-with-models/Http/Controllers/Api/V1/dashboard.html delete mode 100644 backend/coverage-report-with-models/Http/Controllers/Api/V1/index.html delete mode 100644 backend/coverage-report-with-models/Http/Controllers/Api/dashboard.html delete mode 100644 backend/coverage-report-with-models/Http/Controllers/Api/index.html delete mode 100644 backend/coverage-report-with-models/Http/Controllers/ArticlesController.php.html delete mode 100644 backend/coverage-report-with-models/Http/Controllers/Controller.php.html delete mode 100644 backend/coverage-report-with-models/Http/Controllers/FeedsController.php.html delete mode 100644 backend/coverage-report-with-models/Http/Controllers/LogsController.php.html delete mode 100644 backend/coverage-report-with-models/Http/Controllers/OnboardingController.php.html delete mode 100644 backend/coverage-report-with-models/Http/Controllers/PlatformAccountsController.php.html delete mode 100644 backend/coverage-report-with-models/Http/Controllers/PlatformChannelsController.php.html delete mode 100644 backend/coverage-report-with-models/Http/Controllers/RoutingController.php.html delete mode 100644 backend/coverage-report-with-models/Http/Controllers/SettingsController.php.html delete mode 100644 backend/coverage-report-with-models/Http/Controllers/dashboard.html delete mode 100644 backend/coverage-report-with-models/Http/Controllers/index.html delete mode 100644 backend/coverage-report-with-models/Http/Middleware/HandleAppearance.php.html delete mode 100644 backend/coverage-report-with-models/Http/Middleware/HandleInertiaRequests.php.html delete mode 100644 backend/coverage-report-with-models/Http/Middleware/dashboard.html delete mode 100644 backend/coverage-report-with-models/Http/Middleware/index.html delete mode 100644 backend/coverage-report-with-models/Http/Requests/StoreFeedRequest.php.html delete mode 100644 backend/coverage-report-with-models/Http/Requests/UpdateFeedRequest.php.html delete mode 100644 backend/coverage-report-with-models/Http/Requests/dashboard.html delete mode 100644 backend/coverage-report-with-models/Http/Requests/index.html delete mode 100644 backend/coverage-report-with-models/Http/Resources/ArticlePublicationResource.php.html delete mode 100644 backend/coverage-report-with-models/Http/Resources/ArticleResource.php.html delete mode 100644 backend/coverage-report-with-models/Http/Resources/FeedResource.php.html delete mode 100644 backend/coverage-report-with-models/Http/Resources/PlatformAccountResource.php.html delete mode 100644 backend/coverage-report-with-models/Http/Resources/PlatformChannelResource.php.html delete mode 100644 backend/coverage-report-with-models/Http/Resources/PlatformInstanceResource.php.html delete mode 100644 backend/coverage-report-with-models/Http/Resources/RouteResource.php.html delete mode 100644 backend/coverage-report-with-models/Http/Resources/dashboard.html delete mode 100644 backend/coverage-report-with-models/Http/Resources/index.html delete mode 100644 backend/coverage-report-with-models/Http/dashboard.html delete mode 100644 backend/coverage-report-with-models/Http/index.html delete mode 100644 backend/coverage-report-with-models/Jobs/ArticleDiscoveryForFeedJob.php.html delete mode 100644 backend/coverage-report-with-models/Jobs/ArticleDiscoveryJob.php.html delete mode 100644 backend/coverage-report-with-models/Jobs/PublishToLemmyJob.php.html delete mode 100644 backend/coverage-report-with-models/Jobs/SyncChannelPostsJob.php.html delete mode 100644 backend/coverage-report-with-models/Jobs/dashboard.html delete mode 100644 backend/coverage-report-with-models/Jobs/index.html delete mode 100644 backend/coverage-report-with-models/Listeners/LogExceptionToDatabase.php.html delete mode 100644 backend/coverage-report-with-models/Listeners/PublishApprovedArticle.php.html delete mode 100644 backend/coverage-report-with-models/Listeners/PublishArticle.php.html delete mode 100644 backend/coverage-report-with-models/Listeners/ValidateArticleListener.php.html delete mode 100644 backend/coverage-report-with-models/Listeners/dashboard.html delete mode 100644 backend/coverage-report-with-models/Listeners/index.html delete mode 100644 backend/coverage-report-with-models/LogLevelEnum.php.html delete mode 100644 backend/coverage-report-with-models/Models/Article.php.html delete mode 100644 backend/coverage-report-with-models/Models/ArticlePublication.php.html delete mode 100644 backend/coverage-report-with-models/Models/Feed.php.html delete mode 100644 backend/coverage-report-with-models/Models/Keyword.php.html delete mode 100644 backend/coverage-report-with-models/Models/Language.php.html delete mode 100644 backend/coverage-report-with-models/Models/Log.php.html delete mode 100644 backend/coverage-report-with-models/Models/PlatformAccount.php.html delete mode 100644 backend/coverage-report-with-models/Models/PlatformChannel.php.html delete mode 100644 backend/coverage-report-with-models/Models/PlatformChannelPost.php.html delete mode 100644 backend/coverage-report-with-models/Models/PlatformInstance.php.html delete mode 100644 backend/coverage-report-with-models/Models/Route.php.html delete mode 100644 backend/coverage-report-with-models/Models/Setting.php.html delete mode 100644 backend/coverage-report-with-models/Models/User.php.html delete mode 100644 backend/coverage-report-with-models/Models/dashboard.html delete mode 100644 backend/coverage-report-with-models/Models/index.html delete mode 100644 backend/coverage-report-with-models/Modules/Lemmy/LemmyRequest.php.html delete mode 100644 backend/coverage-report-with-models/Modules/Lemmy/Services/LemmyApiService.php.html delete mode 100644 backend/coverage-report-with-models/Modules/Lemmy/Services/LemmyPublisher.php.html delete mode 100644 backend/coverage-report-with-models/Modules/Lemmy/Services/dashboard.html delete mode 100644 backend/coverage-report-with-models/Modules/Lemmy/Services/index.html delete mode 100644 backend/coverage-report-with-models/Modules/Lemmy/dashboard.html delete mode 100644 backend/coverage-report-with-models/Modules/Lemmy/index.html delete mode 100644 backend/coverage-report-with-models/Modules/dashboard.html delete mode 100644 backend/coverage-report-with-models/Modules/index.html delete mode 100644 backend/coverage-report-with-models/Providers/AppServiceProvider.php.html delete mode 100644 backend/coverage-report-with-models/Providers/HorizonServiceProvider.php.html delete mode 100644 backend/coverage-report-with-models/Providers/dashboard.html delete mode 100644 backend/coverage-report-with-models/Providers/index.html delete mode 100644 backend/coverage-report-with-models/Services/Article/ArticleFetcher.php.html delete mode 100644 backend/coverage-report-with-models/Services/Article/ValidationService.php.html delete mode 100644 backend/coverage-report-with-models/Services/Article/dashboard.html delete mode 100644 backend/coverage-report-with-models/Services/Article/index.html delete mode 100644 backend/coverage-report-with-models/Services/Auth/LemmyAuthService.php.html delete mode 100644 backend/coverage-report-with-models/Services/Auth/dashboard.html delete mode 100644 backend/coverage-report-with-models/Services/Auth/index.html delete mode 100644 backend/coverage-report-with-models/Services/DashboardStatsService.php.html delete mode 100644 backend/coverage-report-with-models/Services/Factories/ArticleParserFactory.php.html delete mode 100644 backend/coverage-report-with-models/Services/Factories/HomepageParserFactory.php.html delete mode 100644 backend/coverage-report-with-models/Services/Factories/dashboard.html delete mode 100644 backend/coverage-report-with-models/Services/Factories/index.html delete mode 100644 backend/coverage-report-with-models/Services/Http/HttpFetcher.php.html delete mode 100644 backend/coverage-report-with-models/Services/Http/dashboard.html delete mode 100644 backend/coverage-report-with-models/Services/Http/index.html delete mode 100644 backend/coverage-report-with-models/Services/Log/LogSaver.php.html delete mode 100644 backend/coverage-report-with-models/Services/Log/dashboard.html delete mode 100644 backend/coverage-report-with-models/Services/Log/index.html delete mode 100644 backend/coverage-report-with-models/Services/OnboardingRedirectService.php.html delete mode 100644 backend/coverage-report-with-models/Services/Parsers/BelgaArticlePageParser.php.html delete mode 100644 backend/coverage-report-with-models/Services/Parsers/BelgaArticleParser.php.html delete mode 100644 backend/coverage-report-with-models/Services/Parsers/BelgaHomepageParser.php.html delete mode 100644 backend/coverage-report-with-models/Services/Parsers/BelgaHomepageParserAdapter.php.html delete mode 100644 backend/coverage-report-with-models/Services/Parsers/VrtArticlePageParser.php.html delete mode 100644 backend/coverage-report-with-models/Services/Parsers/VrtArticleParser.php.html delete mode 100644 backend/coverage-report-with-models/Services/Parsers/VrtHomepageParser.php.html delete mode 100644 backend/coverage-report-with-models/Services/Parsers/VrtHomepageParserAdapter.php.html delete mode 100644 backend/coverage-report-with-models/Services/Parsers/dashboard.html delete mode 100644 backend/coverage-report-with-models/Services/Parsers/index.html delete mode 100644 backend/coverage-report-with-models/Services/Publishing/ArticlePublishingService.php.html delete mode 100644 backend/coverage-report-with-models/Services/Publishing/dashboard.html delete mode 100644 backend/coverage-report-with-models/Services/Publishing/index.html delete mode 100644 backend/coverage-report-with-models/Services/RoutingValidationService.php.html delete mode 100644 backend/coverage-report-with-models/Services/SystemStatusService.php.html delete mode 100644 backend/coverage-report-with-models/Services/dashboard.html delete mode 100644 backend/coverage-report-with-models/Services/index.html delete mode 100644 backend/coverage-report-with-models/_css/bootstrap.min.css delete mode 100644 backend/coverage-report-with-models/_css/custom.css delete mode 100644 backend/coverage-report-with-models/_css/nv.d3.min.css delete mode 100644 backend/coverage-report-with-models/_css/octicons.css delete mode 100644 backend/coverage-report-with-models/_css/style.css delete mode 100644 backend/coverage-report-with-models/_icons/file-code.svg delete mode 100644 backend/coverage-report-with-models/_icons/file-directory.svg delete mode 100644 backend/coverage-report-with-models/_js/bootstrap.bundle.min.js delete mode 100644 backend/coverage-report-with-models/_js/d3.min.js delete mode 100644 backend/coverage-report-with-models/_js/file.js delete mode 100644 backend/coverage-report-with-models/_js/jquery.min.js delete mode 100644 backend/coverage-report-with-models/_js/nv.d3.min.js delete mode 100644 backend/coverage-report-with-models/dashboard.html delete mode 100644 backend/coverage-report-with-models/index.html delete mode 100644 backend/coverage-report/Console/Commands/FetchNewArticlesCommand.php.html delete mode 100644 backend/coverage-report/Console/Commands/SyncChannelPostsCommand.php.html delete mode 100644 backend/coverage-report/Console/Commands/dashboard.html delete mode 100644 backend/coverage-report/Console/Commands/index.html delete mode 100644 backend/coverage-report/Console/dashboard.html delete mode 100644 backend/coverage-report/Console/index.html delete mode 100644 backend/coverage-report/Contracts/ArticleParserInterface.php.html delete mode 100644 backend/coverage-report/Contracts/HomepageParserInterface.php.html delete mode 100644 backend/coverage-report/Contracts/dashboard.html delete mode 100644 backend/coverage-report/Contracts/index.html delete mode 100644 backend/coverage-report/Enums/PlatformEnum.php.html delete mode 100644 backend/coverage-report/Enums/dashboard.html delete mode 100644 backend/coverage-report/Enums/index.html delete mode 100644 backend/coverage-report/Events/ArticleApproved.php.html delete mode 100644 backend/coverage-report/Events/ArticleReadyToPublish.php.html delete mode 100644 backend/coverage-report/Events/ExceptionLogged.php.html delete mode 100644 backend/coverage-report/Events/ExceptionOccurred.php.html delete mode 100644 backend/coverage-report/Events/NewArticleFetched.php.html delete mode 100644 backend/coverage-report/Events/dashboard.html delete mode 100644 backend/coverage-report/Events/index.html delete mode 100644 backend/coverage-report/Exceptions/ChannelException.php.html delete mode 100644 backend/coverage-report/Exceptions/PlatformAuthException.php.html delete mode 100644 backend/coverage-report/Exceptions/PublishException.php.html delete mode 100644 backend/coverage-report/Exceptions/RoutingException.php.html delete mode 100644 backend/coverage-report/Exceptions/RoutingMismatchException.php.html delete mode 100644 backend/coverage-report/Exceptions/dashboard.html delete mode 100644 backend/coverage-report/Exceptions/index.html delete mode 100644 backend/coverage-report/Http/Controllers/Api/V1/ArticlesController.php.html delete mode 100644 backend/coverage-report/Http/Controllers/Api/V1/AuthController.php.html delete mode 100644 backend/coverage-report/Http/Controllers/Api/V1/BaseController.php.html delete mode 100644 backend/coverage-report/Http/Controllers/Api/V1/DashboardController.php.html delete mode 100644 backend/coverage-report/Http/Controllers/Api/V1/FeedsController.php.html delete mode 100644 backend/coverage-report/Http/Controllers/Api/V1/LogsController.php.html delete mode 100644 backend/coverage-report/Http/Controllers/Api/V1/PlatformAccountsController.php.html delete mode 100644 backend/coverage-report/Http/Controllers/Api/V1/PlatformChannelsController.php.html delete mode 100644 backend/coverage-report/Http/Controllers/Api/V1/RoutingController.php.html delete mode 100644 backend/coverage-report/Http/Controllers/Api/V1/SettingsController.php.html delete mode 100644 backend/coverage-report/Http/Controllers/Api/V1/dashboard.html delete mode 100644 backend/coverage-report/Http/Controllers/Api/V1/index.html delete mode 100644 backend/coverage-report/Http/Controllers/Api/dashboard.html delete mode 100644 backend/coverage-report/Http/Controllers/Api/index.html delete mode 100644 backend/coverage-report/Http/Controllers/ArticlesController.php.html delete mode 100644 backend/coverage-report/Http/Controllers/Controller.php.html delete mode 100644 backend/coverage-report/Http/Controllers/FeedsController.php.html delete mode 100644 backend/coverage-report/Http/Controllers/LogsController.php.html delete mode 100644 backend/coverage-report/Http/Controllers/OnboardingController.php.html delete mode 100644 backend/coverage-report/Http/Controllers/PlatformAccountsController.php.html delete mode 100644 backend/coverage-report/Http/Controllers/PlatformChannelsController.php.html delete mode 100644 backend/coverage-report/Http/Controllers/RoutingController.php.html delete mode 100644 backend/coverage-report/Http/Controllers/SettingsController.php.html delete mode 100644 backend/coverage-report/Http/Controllers/dashboard.html delete mode 100644 backend/coverage-report/Http/Controllers/index.html delete mode 100644 backend/coverage-report/Http/Middleware/HandleAppearance.php.html delete mode 100644 backend/coverage-report/Http/Middleware/HandleInertiaRequests.php.html delete mode 100644 backend/coverage-report/Http/Middleware/dashboard.html delete mode 100644 backend/coverage-report/Http/Middleware/index.html delete mode 100644 backend/coverage-report/Http/Requests/StoreFeedRequest.php.html delete mode 100644 backend/coverage-report/Http/Requests/UpdateFeedRequest.php.html delete mode 100644 backend/coverage-report/Http/Requests/dashboard.html delete mode 100644 backend/coverage-report/Http/Requests/index.html delete mode 100644 backend/coverage-report/Http/Resources/ArticlePublicationResource.php.html delete mode 100644 backend/coverage-report/Http/Resources/ArticleResource.php.html delete mode 100644 backend/coverage-report/Http/Resources/FeedResource.php.html delete mode 100644 backend/coverage-report/Http/Resources/PlatformAccountResource.php.html delete mode 100644 backend/coverage-report/Http/Resources/PlatformChannelResource.php.html delete mode 100644 backend/coverage-report/Http/Resources/PlatformInstanceResource.php.html delete mode 100644 backend/coverage-report/Http/Resources/RouteResource.php.html delete mode 100644 backend/coverage-report/Http/Resources/dashboard.html delete mode 100644 backend/coverage-report/Http/Resources/index.html delete mode 100644 backend/coverage-report/Http/dashboard.html delete mode 100644 backend/coverage-report/Http/index.html delete mode 100644 backend/coverage-report/Jobs/ArticleDiscoveryForFeedJob.php.html delete mode 100644 backend/coverage-report/Jobs/ArticleDiscoveryJob.php.html delete mode 100644 backend/coverage-report/Jobs/PublishToLemmyJob.php.html delete mode 100644 backend/coverage-report/Jobs/SyncChannelPostsJob.php.html delete mode 100644 backend/coverage-report/Jobs/dashboard.html delete mode 100644 backend/coverage-report/Jobs/index.html delete mode 100644 backend/coverage-report/Listeners/LogExceptionToDatabase.php.html delete mode 100644 backend/coverage-report/Listeners/PublishApprovedArticle.php.html delete mode 100644 backend/coverage-report/Listeners/PublishArticle.php.html delete mode 100644 backend/coverage-report/Listeners/ValidateArticleListener.php.html delete mode 100644 backend/coverage-report/Listeners/dashboard.html delete mode 100644 backend/coverage-report/Listeners/index.html delete mode 100644 backend/coverage-report/LogLevelEnum.php.html delete mode 100644 backend/coverage-report/Models/Article.php.html delete mode 100644 backend/coverage-report/Models/ArticlePublication.php.html delete mode 100644 backend/coverage-report/Models/Feed.php.html delete mode 100644 backend/coverage-report/Models/Keyword.php.html delete mode 100644 backend/coverage-report/Models/Language.php.html delete mode 100644 backend/coverage-report/Models/Log.php.html delete mode 100644 backend/coverage-report/Models/PlatformAccount.php.html delete mode 100644 backend/coverage-report/Models/PlatformChannel.php.html delete mode 100644 backend/coverage-report/Models/PlatformChannelPost.php.html delete mode 100644 backend/coverage-report/Models/PlatformInstance.php.html delete mode 100644 backend/coverage-report/Models/Route.php.html delete mode 100644 backend/coverage-report/Models/Setting.php.html delete mode 100644 backend/coverage-report/Models/User.php.html delete mode 100644 backend/coverage-report/Models/dashboard.html delete mode 100644 backend/coverage-report/Models/index.html delete mode 100644 backend/coverage-report/Modules/Lemmy/LemmyRequest.php.html delete mode 100644 backend/coverage-report/Modules/Lemmy/Services/LemmyApiService.php.html delete mode 100644 backend/coverage-report/Modules/Lemmy/Services/LemmyPublisher.php.html delete mode 100644 backend/coverage-report/Modules/Lemmy/Services/dashboard.html delete mode 100644 backend/coverage-report/Modules/Lemmy/Services/index.html delete mode 100644 backend/coverage-report/Modules/Lemmy/dashboard.html delete mode 100644 backend/coverage-report/Modules/Lemmy/index.html delete mode 100644 backend/coverage-report/Modules/dashboard.html delete mode 100644 backend/coverage-report/Modules/index.html delete mode 100644 backend/coverage-report/Providers/AppServiceProvider.php.html delete mode 100644 backend/coverage-report/Providers/HorizonServiceProvider.php.html delete mode 100644 backend/coverage-report/Providers/dashboard.html delete mode 100644 backend/coverage-report/Providers/index.html delete mode 100644 backend/coverage-report/Services/Article/ArticleFetcher.php.html delete mode 100644 backend/coverage-report/Services/Article/ValidationService.php.html delete mode 100644 backend/coverage-report/Services/Article/dashboard.html delete mode 100644 backend/coverage-report/Services/Article/index.html delete mode 100644 backend/coverage-report/Services/Auth/LemmyAuthService.php.html delete mode 100644 backend/coverage-report/Services/Auth/dashboard.html delete mode 100644 backend/coverage-report/Services/Auth/index.html delete mode 100644 backend/coverage-report/Services/DashboardStatsService.php.html delete mode 100644 backend/coverage-report/Services/Factories/ArticleParserFactory.php.html delete mode 100644 backend/coverage-report/Services/Factories/HomepageParserFactory.php.html delete mode 100644 backend/coverage-report/Services/Factories/dashboard.html delete mode 100644 backend/coverage-report/Services/Factories/index.html delete mode 100644 backend/coverage-report/Services/Http/HttpFetcher.php.html delete mode 100644 backend/coverage-report/Services/Http/dashboard.html delete mode 100644 backend/coverage-report/Services/Http/index.html delete mode 100644 backend/coverage-report/Services/Log/LogSaver.php.html delete mode 100644 backend/coverage-report/Services/Log/dashboard.html delete mode 100644 backend/coverage-report/Services/Log/index.html delete mode 100644 backend/coverage-report/Services/OnboardingRedirectService.php.html delete mode 100644 backend/coverage-report/Services/Parsers/BelgaArticlePageParser.php.html delete mode 100644 backend/coverage-report/Services/Parsers/BelgaArticleParser.php.html delete mode 100644 backend/coverage-report/Services/Parsers/BelgaHomepageParser.php.html delete mode 100644 backend/coverage-report/Services/Parsers/BelgaHomepageParserAdapter.php.html delete mode 100644 backend/coverage-report/Services/Parsers/VrtArticlePageParser.php.html delete mode 100644 backend/coverage-report/Services/Parsers/VrtArticleParser.php.html delete mode 100644 backend/coverage-report/Services/Parsers/VrtHomepageParser.php.html delete mode 100644 backend/coverage-report/Services/Parsers/VrtHomepageParserAdapter.php.html delete mode 100644 backend/coverage-report/Services/Parsers/dashboard.html delete mode 100644 backend/coverage-report/Services/Parsers/index.html delete mode 100644 backend/coverage-report/Services/Publishing/ArticlePublishingService.php.html delete mode 100644 backend/coverage-report/Services/Publishing/dashboard.html delete mode 100644 backend/coverage-report/Services/Publishing/index.html delete mode 100644 backend/coverage-report/Services/RoutingValidationService.php.html delete mode 100644 backend/coverage-report/Services/SystemStatusService.php.html delete mode 100644 backend/coverage-report/Services/dashboard.html delete mode 100644 backend/coverage-report/Services/index.html delete mode 100644 backend/coverage-report/_css/bootstrap.min.css delete mode 100644 backend/coverage-report/_css/custom.css delete mode 100644 backend/coverage-report/_css/nv.d3.min.css delete mode 100644 backend/coverage-report/_css/octicons.css delete mode 100644 backend/coverage-report/_css/style.css delete mode 100644 backend/coverage-report/_icons/file-code.svg delete mode 100644 backend/coverage-report/_icons/file-directory.svg delete mode 100644 backend/coverage-report/_js/bootstrap.bundle.min.js delete mode 100644 backend/coverage-report/_js/d3.min.js delete mode 100644 backend/coverage-report/_js/file.js delete mode 100644 backend/coverage-report/_js/jquery.min.js delete mode 100644 backend/coverage-report/_js/nv.d3.min.js delete mode 100644 backend/coverage-report/dashboard.html delete mode 100644 backend/coverage-report/index.html diff --git a/backend/.gitignore b/backend/.gitignore index 22d0d82f..a1601531 100644 --- a/backend/.gitignore +++ b/backend/.gitignore @@ -1 +1,2 @@ vendor +/coverage-report-* diff --git a/backend/coverage-report-controllers/Console/Commands/FetchNewArticlesCommand.php.html b/backend/coverage-report-controllers/Console/Commands/FetchNewArticlesCommand.php.html deleted file mode 100644 index b388feb4..00000000 --- a/backend/coverage-report-controllers/Console/Commands/FetchNewArticlesCommand.php.html +++ /dev/null @@ -1,187 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Console/Commands/FetchNewArticlesCommand.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 8
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
FetchNewArticlesCommand
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 8
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
12
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 handle
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 8
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
12
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Console\Commands;
4
5use App\Jobs\ArticleDiscoveryJob;
6use App\Models\Feed;
7use App\Models\Setting;
8use Illuminate\Console\Command;
9
10class FetchNewArticlesCommand extends Command
11{
12    protected $signature = 'article:refresh';
13
14    protected $description = 'Fetches latest articles';
15
16    public function handle(): int
17    {
18        if (!Setting::isArticleProcessingEnabled()) {
19            $this->info('Article processing is disabled. Article discovery skipped.');
20
21            return self::SUCCESS;
22        }
23
24        if (!Feed::where('is_active', true)->exists()) {
25            $this->info('No active feeds found. Article discovery skipped.');
26
27            return self::SUCCESS;
28        }
29
30        ArticleDiscoveryJob::dispatch();
31
32        return self::SUCCESS;
33    }
34}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:51:47 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-controllers/Console/Commands/SyncChannelPostsCommand.php.html b/backend/coverage-report-controllers/Console/Commands/SyncChannelPostsCommand.php.html deleted file mode 100644 index 4434a7b5..00000000 --- a/backend/coverage-report-controllers/Console/Commands/SyncChannelPostsCommand.php.html +++ /dev/null @@ -1,209 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Console/Commands/SyncChannelPostsCommand.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 8
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
SyncChannelPostsCommand
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 8
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
12
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 handle
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 5
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
6
 syncLemmy
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Console\Commands;
4
5use App\Jobs\SyncChannelPostsJob;
6use Illuminate\Console\Command;
7
8class SyncChannelPostsCommand extends Command
9{
10    protected $signature = 'channel:sync {platform=lemmy}';
11
12    protected $description = 'Manually sync channel posts for a platform';
13
14    public function handle(): int
15    {
16        $platform = $this->argument('platform');
17
18        if ($platform === 'lemmy') {
19            return $this->syncLemmy();
20        }
21
22        $this->error("Unsupported platform: {$platform}");
23
24        return self::FAILURE;
25    }
26
27    private function syncLemmy(): int
28    {
29        SyncChannelPostsJob::dispatchForAllActiveChannels();
30        $this->info('Successfully dispatched sync jobs for all active Lemmy channels');
31
32        return self::SUCCESS;
33    }
34}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:51:47 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-controllers/Console/Commands/dashboard.html b/backend/coverage-report-controllers/Console/Commands/dashboard.html deleted file mode 100644 index a681c967..00000000 --- a/backend/coverage-report-controllers/Console/Commands/dashboard.html +++ /dev/null @@ -1,294 +0,0 @@ - - - - - Dashboard for /var/www/html/backend/app/Console/Commands - - - - - - - -
-
-
-
- -
-
-
-
-
-
-
-

Classes

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
-
-
-

Insufficient Coverage

- -
-
-

Project Risks

- -
-
-
-
-

Methods

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
-
-
-

Insufficient Coverage

-
- - - - - - - - - - - - - -
MethodCoverage
handle0%
handle0%
syncLemmy0%
-
-
-
-

Project Risks

-
- - - - - - - - - - - - -
MethodCRAP
handle12
handle6
-
-
-
- -
- - - - - - diff --git a/backend/coverage-report-controllers/Console/Commands/index.html b/backend/coverage-report-controllers/Console/Commands/index.html deleted file mode 100644 index 79e34d55..00000000 --- a/backend/coverage-report-controllers/Console/Commands/index.html +++ /dev/null @@ -1,148 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Console/Commands - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 16
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
FetchNewArticlesCommand.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 8
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
SyncChannelPostsCommand.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 8
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- -
- - diff --git a/backend/coverage-report-controllers/Console/dashboard.html b/backend/coverage-report-controllers/Console/dashboard.html deleted file mode 100644 index 879ed358..00000000 --- a/backend/coverage-report-controllers/Console/dashboard.html +++ /dev/null @@ -1,293 +0,0 @@ - - - - - Dashboard for /var/www/html/backend/app/Console - - - - - - - -
-
-
-
- -
-
-
-
-
-
-
-

Classes

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
-
-
-

Insufficient Coverage

- -
-
-

Project Risks

- -
-
-
-
-

Methods

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
-
-
-

Insufficient Coverage

-
- - - - - - - - - - - - - -
MethodCoverage
handle0%
handle0%
syncLemmy0%
-
-
-
-

Project Risks

-
- - - - - - - - - - - - -
MethodCRAP
handle12
handle6
-
-
-
- -
- - - - - - diff --git a/backend/coverage-report-controllers/Console/index.html b/backend/coverage-report-controllers/Console/index.html deleted file mode 100644 index a83a4408..00000000 --- a/backend/coverage-report-controllers/Console/index.html +++ /dev/null @@ -1,119 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Console - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 16
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
Commands
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 16
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
-
- -
- - diff --git a/backend/coverage-report-controllers/Contracts/ArticleParserInterface.php.html b/backend/coverage-report-controllers/Contracts/ArticleParserInterface.php.html deleted file mode 100644 index 278294b7..00000000 --- a/backend/coverage-report-controllers/Contracts/ArticleParserInterface.php.html +++ /dev/null @@ -1,108 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Contracts/ArticleParserInterface.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
n/a
0 / 0
n/a
0 / 0
CRAP
n/a
0 / 0
-
- - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Contracts;
4
5interface ArticleParserInterface
6{
7    /**
8     * Check if this parser can handle the given URL
9     */
10    public function canParse(string $url): bool;
11
12    /**
13     * Extract article data from HTML
14     * @return array<string, mixed>
15     */
16    public function extractData(string $html): array;
17
18    /**
19     * Get the source name for this parser
20     */
21    public function getSourceName(): string;
22}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:51:47 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-controllers/Contracts/HomepageParserInterface.php.html b/backend/coverage-report-controllers/Contracts/HomepageParserInterface.php.html deleted file mode 100644 index e81b3bb7..00000000 --- a/backend/coverage-report-controllers/Contracts/HomepageParserInterface.php.html +++ /dev/null @@ -1,113 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Contracts/HomepageParserInterface.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
n/a
0 / 0
n/a
0 / 0
CRAP
n/a
0 / 0
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Contracts;
4
5interface HomepageParserInterface
6{
7    /**
8     * Check if this parser can handle the given homepage URL
9     */
10    public function canParse(string $url): bool;
11
12    /**
13     * Extract article URLs from homepage HTML
14     * @return array<int, string>
15     */
16    public function extractArticleUrls(string $html): array;
17
18    /**
19     * Get the homepage URL for this source
20     */
21    public function getHomepageUrl(): string;
22
23    /**
24     * Get the source name for this parser
25     */
26    public function getSourceName(): string;
27}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:51:47 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-controllers/Contracts/dashboard.html b/backend/coverage-report-controllers/Contracts/dashboard.html deleted file mode 100644 index 3760c4cd..00000000 --- a/backend/coverage-report-controllers/Contracts/dashboard.html +++ /dev/null @@ -1,284 +0,0 @@ - - - - - Dashboard for /var/www/html/backend/app/Contracts - - - - - - - -
-
-
-
- -
-
-
-
-
-
-
-

Classes

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
-
-
-

Insufficient Coverage

-
- - - - - - - - - - -
ClassCoverage
-
-
-
-

Project Risks

-
- - - - - - - - - - -
ClassCRAP
-
-
-
-
-
-

Methods

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
-
-
-

Insufficient Coverage

-
- - - - - - - - - - -
MethodCoverage
-
-
-
-

Project Risks

-
- - - - - - - - - - -
MethodCRAP
-
-
-
- -
- - - - - - diff --git a/backend/coverage-report-controllers/Contracts/index.html b/backend/coverage-report-controllers/Contracts/index.html deleted file mode 100644 index 0ce2a54f..00000000 --- a/backend/coverage-report-controllers/Contracts/index.html +++ /dev/null @@ -1,102 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Contracts - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
n/a
0 / 0
n/a
0 / 0
n/a
0 / 0
ArticleParserInterface.php
n/a
0 / 0
n/a
0 / 0
n/a
0 / 0
HomepageParserInterface.php
n/a
0 / 0
n/a
0 / 0
n/a
0 / 0
-
- -
- - diff --git a/backend/coverage-report-controllers/Enums/PlatformEnum.php.html b/backend/coverage-report-controllers/Enums/PlatformEnum.php.html deleted file mode 100644 index e26aff67..00000000 --- a/backend/coverage-report-controllers/Enums/PlatformEnum.php.html +++ /dev/null @@ -1,94 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Enums/PlatformEnum.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
n/a
0 / 0
n/a
0 / 0
CRAP
n/a
0 / 0
-
- - - - - - - - - - - - -
1<?php
2
3namespace App\Enums;
4
5enum PlatformEnum: string
6{
7    case LEMMY = 'lemmy';
8}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:51:47 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-controllers/Enums/dashboard.html b/backend/coverage-report-controllers/Enums/dashboard.html deleted file mode 100644 index d670b0b5..00000000 --- a/backend/coverage-report-controllers/Enums/dashboard.html +++ /dev/null @@ -1,284 +0,0 @@ - - - - - Dashboard for /var/www/html/backend/app/Enums - - - - - - - -
-
-
-
- -
-
-
-
-
-
-
-

Classes

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
-
-
-

Insufficient Coverage

-
- - - - - - - - - - -
ClassCoverage
-
-
-
-

Project Risks

-
- - - - - - - - - - -
ClassCRAP
-
-
-
-
-
-

Methods

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
-
-
-

Insufficient Coverage

-
- - - - - - - - - - -
MethodCoverage
-
-
-
-

Project Risks

-
- - - - - - - - - - -
MethodCRAP
-
-
-
- -
- - - - - - diff --git a/backend/coverage-report-controllers/Enums/index.html b/backend/coverage-report-controllers/Enums/index.html deleted file mode 100644 index e4322b61..00000000 --- a/backend/coverage-report-controllers/Enums/index.html +++ /dev/null @@ -1,89 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Enums - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
n/a
0 / 0
n/a
0 / 0
n/a
0 / 0
PlatformEnum.php
n/a
0 / 0
n/a
0 / 0
n/a
0 / 0
-
- -
- - diff --git a/backend/coverage-report-controllers/Events/ArticleApproved.php.html b/backend/coverage-report-controllers/Events/ArticleApproved.php.html deleted file mode 100644 index 506bcc9a..00000000 --- a/backend/coverage-report-controllers/Events/ArticleApproved.php.html +++ /dev/null @@ -1,169 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Events/ArticleApproved.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
CRAP
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
ArticleApproved
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
1
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
 __construct
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
1
-
- - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Events;
4
5use App\Models\Article;
6use Illuminate\Foundation\Events\Dispatchable;
7use Illuminate\Queue\SerializesModels;
8
9class ArticleApproved
10{
11    use Dispatchable, SerializesModels;
12
13    public function __construct(public Article $article)
14    {
15        //
16    }
17}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:51:47 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-controllers/Events/ArticleReadyToPublish.php.html b/backend/coverage-report-controllers/Events/ArticleReadyToPublish.php.html deleted file mode 100644 index 9cbc63ec..00000000 --- a/backend/coverage-report-controllers/Events/ArticleReadyToPublish.php.html +++ /dev/null @@ -1,170 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Events/ArticleReadyToPublish.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
ArticleReadyToPublish
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 __construct
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Events;
4
5use App\Models\Article;
6use Illuminate\Broadcasting\InteractsWithSockets;
7use Illuminate\Foundation\Events\Dispatchable;
8use Illuminate\Queue\SerializesModels;
9
10class ArticleReadyToPublish
11{
12    use Dispatchable, InteractsWithSockets, SerializesModels;
13
14    public function __construct(public Article $article)
15    {
16
17    }
18}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:51:47 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-controllers/Events/ExceptionLogged.php.html b/backend/coverage-report-controllers/Events/ExceptionLogged.php.html deleted file mode 100644 index e21e0fdb..00000000 --- a/backend/coverage-report-controllers/Events/ExceptionLogged.php.html +++ /dev/null @@ -1,169 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Events/ExceptionLogged.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
ExceptionLogged
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 __construct
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Events;
4
5use App\Models\Log;
6use Illuminate\Foundation\Events\Dispatchable;
7use Illuminate\Queue\SerializesModels;
8
9class ExceptionLogged
10{
11    use Dispatchable, SerializesModels;
12
13    public function __construct(
14        public Log $log
15    ) {
16    }
17}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:51:47 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-controllers/Events/ExceptionOccurred.php.html b/backend/coverage-report-controllers/Events/ExceptionOccurred.php.html deleted file mode 100644 index aceb5246..00000000 --- a/backend/coverage-report-controllers/Events/ExceptionOccurred.php.html +++ /dev/null @@ -1,174 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Events/ExceptionOccurred.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
ExceptionOccurred
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 __construct
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Events;
4
5use App\LogLevelEnum;
6use Illuminate\Foundation\Events\Dispatchable;
7use Illuminate\Queue\SerializesModels;
8use Throwable;
9
10class ExceptionOccurred
11{
12    use Dispatchable, SerializesModels;
13
14    public function __construct(
15        public Throwable $exception,
16        public LogLevelEnum $level,
17        public string $message,
18        /** @var array<string, mixed> */
19        public array $context = []
20    ) {
21    }
22}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:51:47 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-controllers/Events/NewArticleFetched.php.html b/backend/coverage-report-controllers/Events/NewArticleFetched.php.html deleted file mode 100644 index b5cbea15..00000000 --- a/backend/coverage-report-controllers/Events/NewArticleFetched.php.html +++ /dev/null @@ -1,169 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Events/NewArticleFetched.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
CRAP
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
NewArticleFetched
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
1
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
 __construct
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
1
-
- - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Events;
4
5use App\Models\Article;
6use Illuminate\Broadcasting\InteractsWithSockets;
7use Illuminate\Foundation\Events\Dispatchable;
8use Illuminate\Queue\SerializesModels;
9
10class NewArticleFetched
11{
12    use Dispatchable, InteractsWithSockets, SerializesModels;
13
14    public function __construct(public Article $article)
15    {
16    }
17}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:51:47 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-controllers/Events/dashboard.html b/backend/coverage-report-controllers/Events/dashboard.html deleted file mode 100644 index ef22fa27..00000000 --- a/backend/coverage-report-controllers/Events/dashboard.html +++ /dev/null @@ -1,290 +0,0 @@ - - - - - Dashboard for /var/www/html/backend/app/Events - - - - - - - -
-
-
-
- -
-
-
-
-
-
-
-

Classes

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
-
-
-

Insufficient Coverage

- -
-
-

Project Risks

-
- - - - - - - - - - -
ClassCRAP
-
-
-
-
-
-

Methods

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
-
-
-

Insufficient Coverage

-
- - - - - - - - - - - - - -
MethodCoverage
__construct0%
__construct0%
__construct0%
-
-
-
-

Project Risks

-
- - - - - - - - - - -
MethodCRAP
-
-
-
- -
- - - - - - diff --git a/backend/coverage-report-controllers/Events/index.html b/backend/coverage-report-controllers/Events/index.html deleted file mode 100644 index 187d0579..00000000 --- a/backend/coverage-report-controllers/Events/index.html +++ /dev/null @@ -1,231 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Events - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 40.00% covered (danger) -
-
-
40.00%
2 / 5
-
- 40.00% covered (danger) -
-
-
40.00%
2 / 5
-
- 40.00% covered (danger) -
-
-
40.00%
2 / 5
ArticleApproved.php
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
ArticleReadyToPublish.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
ExceptionLogged.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
ExceptionOccurred.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
NewArticleFetched.php
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
-
- -
- - diff --git a/backend/coverage-report-controllers/Exceptions/ChannelException.php.html b/backend/coverage-report-controllers/Exceptions/ChannelException.php.html deleted file mode 100644 index bc7489dc..00000000 --- a/backend/coverage-report-controllers/Exceptions/ChannelException.php.html +++ /dev/null @@ -1,109 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Exceptions/ChannelException.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
n/a
0 / 0
n/a
0 / 0
CRAP
n/a
0 / 0
ChannelException
n/a
0 / 0
n/a
0 / 0
0
n/a
0 / 0
-
- - - - - - - - - - - - - -
1<?php
2
3namespace App\Exceptions;
4
5use Exception;
6
7class ChannelException extends Exception
8{
9}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:51:47 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-controllers/Exceptions/PlatformAuthException.php.html b/backend/coverage-report-controllers/Exceptions/PlatformAuthException.php.html deleted file mode 100644 index 1d1e35d7..00000000 --- a/backend/coverage-report-controllers/Exceptions/PlatformAuthException.php.html +++ /dev/null @@ -1,197 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Exceptions/PlatformAuthException.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
PlatformAuthException
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
6
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 __construct
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 getPlatform
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Exceptions;
4
5use App\Enums\PlatformEnum;
6use Exception;
7
8class PlatformAuthException extends Exception
9{
10    public function __construct(
11        private readonly PlatformEnum $platform,
12        string $reason = 'Authentication failed'
13    ) {
14        $message = "Failed to authenticate with {$platform->value}: {$reason}";
15
16        parent::__construct($message);
17    }
18
19    public function getPlatform(): PlatformEnum
20    {
21        return $this->platform;
22    }
23}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:51:47 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-controllers/Exceptions/PublishException.php.html b/backend/coverage-report-controllers/Exceptions/PublishException.php.html deleted file mode 100644 index d7eb1575..00000000 --- a/backend/coverage-report-controllers/Exceptions/PublishException.php.html +++ /dev/null @@ -1,235 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Exceptions/PublishException.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 8
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
PublishException
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 8
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
30
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 __construct
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 6
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
12
 getArticle
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 getPlatform
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Exceptions;
4
5use App\Enums\PlatformEnum;
6use App\Models\Article;
7use Exception;
8use Throwable;
9
10class PublishException extends Exception
11{
12    public function __construct(
13        private readonly Article $article,
14        private readonly PlatformEnum|null $platform,
15        ?Throwable $previous = null
16    ) {
17        $message = "Failed to publish article #$article->id";
18
19        if ($this->platform) {
20            $message .= "  to $platform->value";
21        }
22
23        if ($previous) {
24            $message .= ": {$previous->getMessage()}";
25        }
26
27        parent::__construct($message, 0, $previous);
28    }
29
30    public function getArticle(): Article
31    {
32        return $this->article;
33    }
34
35    public function getPlatform(): ?PlatformEnum
36    {
37        return $this->platform;
38    }
39}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:51:47 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-controllers/Exceptions/RoutingException.php.html b/backend/coverage-report-controllers/Exceptions/RoutingException.php.html deleted file mode 100644 index 14925986..00000000 --- a/backend/coverage-report-controllers/Exceptions/RoutingException.php.html +++ /dev/null @@ -1,109 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Exceptions/RoutingException.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
n/a
0 / 0
n/a
0 / 0
CRAP
n/a
0 / 0
RoutingException
n/a
0 / 0
n/a
0 / 0
0
n/a
0 / 0
-
- - - - - - - - - - - - - -
1<?php
2
3namespace App\Exceptions;
4
5use Exception;
6
7class RoutingException extends Exception
8{
9}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:51:47 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-controllers/Exceptions/RoutingMismatchException.php.html b/backend/coverage-report-controllers/Exceptions/RoutingMismatchException.php.html deleted file mode 100644 index 1f18dad9..00000000 --- a/backend/coverage-report-controllers/Exceptions/RoutingMismatchException.php.html +++ /dev/null @@ -1,174 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Exceptions/RoutingMismatchException.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 8
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
RoutingMismatchException
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 8
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 __construct
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 8
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Exceptions;
4
5use App\Models\Feed;
6use App\Models\PlatformChannel;
7
8class RoutingMismatchException extends RoutingException
9{
10    public function __construct(Feed $feed, PlatformChannel $channel)
11    {
12        $message = sprintf(
13            "Language mismatch: Feed '%s' is in '%s' but channel '%s' is set to '%s'. Feed and channel languages must match for proper content routing.",
14            $feed->name,
15            $feed->language,
16            $channel->name,
17            $channel->language
18        );
19
20        parent::__construct($message);
21    }
22}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:51:47 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-controllers/Exceptions/dashboard.html b/backend/coverage-report-controllers/Exceptions/dashboard.html deleted file mode 100644 index d59d11c0..00000000 --- a/backend/coverage-report-controllers/Exceptions/dashboard.html +++ /dev/null @@ -1,295 +0,0 @@ - - - - - Dashboard for /var/www/html/backend/app/Exceptions - - - - - - - -
-
-
-
- -
-
-
-
-
-
-
-

Classes

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
-
-
-

Insufficient Coverage

- -
-
-

Project Risks

-
- - - - - - - - - - - -
ClassCRAP
App\Exceptions\PublishException30
-
-
-
-
-
-

Methods

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
-
-
-

Insufficient Coverage

-
- - - - - - - - - - - - - - - - -
MethodCoverage
__construct0%
getPlatform0%
__construct0%
getArticle0%
getPlatform0%
__construct0%
-
-
-
-

Project Risks

-
- - - - - - - - - - - -
MethodCRAP
__construct12
-
-
-
- -
- - - - - - diff --git a/backend/coverage-report-controllers/Exceptions/index.html b/backend/coverage-report-controllers/Exceptions/index.html deleted file mode 100644 index b3cf023e..00000000 --- a/backend/coverage-report-controllers/Exceptions/index.html +++ /dev/null @@ -1,201 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Exceptions - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 19
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 6
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
ChannelException.php
n/a
0 / 0
n/a
0 / 0
n/a
0 / 0
PlatformAuthException.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
PublishException.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 8
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
RoutingException.php
n/a
0 / 0
n/a
0 / 0
n/a
0 / 0
RoutingMismatchException.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 8
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- -
- - diff --git a/backend/coverage-report-controllers/Http/Controllers/Api/V1/ArticlesController.php.html b/backend/coverage-report-controllers/Http/Controllers/Api/V1/ArticlesController.php.html deleted file mode 100644 index bff91286..00000000 --- a/backend/coverage-report-controllers/Http/Controllers/Api/V1/ArticlesController.php.html +++ /dev/null @@ -1,273 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Http/Controllers/Api/V1/ArticlesController.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 87.88% covered (warning) -
-
-
87.88%
29 / 33
-
- 33.33% covered (danger) -
-
-
33.33%
1 / 3
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
ArticlesController
-
- 87.88% covered (warning) -
-
-
87.88%
29 / 33
-
- 33.33% covered (danger) -
-
-
33.33%
1 / 3
5.04
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 index
-
- 100.00% covered (success) -
-
-
100.00%
19 / 19
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
1
 approve
-
- 71.43% covered (warning) -
-
-
71.43%
5 / 7
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2.09
 reject
-
- 71.43% covered (warning) -
-
-
71.43%
5 / 7
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2.09
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Http\Controllers\Api\V1;
4
5use App\Http\Resources\ArticleResource;
6use App\Models\Article;
7use App\Models\Setting;
8use Illuminate\Http\JsonResponse;
9use Illuminate\Http\Request;
10
11class ArticlesController extends BaseController
12{
13    /**
14     * Display a listing of articles
15     */
16    public function index(Request $request): JsonResponse
17    {
18        $perPage = min($request->get('per_page', 15), 100); // Max 100 items per page
19        $articles = Article::with(['feed', 'articlePublication'])
20            ->orderBy('created_at', 'desc')
21            ->paginate($perPage);
22
23        $publishingApprovalsEnabled = Setting::isPublishingApprovalsEnabled();
24
25        return $this->sendResponse([
26            'articles' => ArticleResource::collection($articles->items()),
27            'pagination' => [
28                'current_page' => $articles->currentPage(),
29                'last_page' => $articles->lastPage(),
30                'per_page' => $articles->perPage(),
31                'total' => $articles->total(),
32                'from' => $articles->firstItem(),
33                'to' => $articles->lastItem(),
34            ],
35            'settings' => [
36                'publishing_approvals_enabled' => $publishingApprovalsEnabled,
37            ],
38        ]);
39    }
40
41    /**
42     * Approve an article
43     */
44    public function approve(Article $article): JsonResponse
45    {
46        try {
47            $article->approve('manual');
48            
49            return $this->sendResponse(
50                new ArticleResource($article->fresh(['feed', 'articlePublication'])),
51                'Article approved and queued for publishing.'
52            );
53        } catch (\Exception $e) {
54            return $this->sendError('Failed to approve article: ' . $e->getMessage(), [], 500);
55        }
56    }
57
58    /**
59     * Reject an article
60     */
61    public function reject(Article $article): JsonResponse
62    {
63        try {
64            $article->reject('manual');
65            
66            return $this->sendResponse(
67                new ArticleResource($article->fresh(['feed', 'articlePublication'])),
68                'Article rejected.'
69            );
70        } catch (\Exception $e) {
71            return $this->sendError('Failed to reject article: ' . $e->getMessage(), [], 500);
72        }
73    }
74}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:51:47 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-controllers/Http/Controllers/Api/V1/AuthController.php.html b/backend/coverage-report-controllers/Http/Controllers/Api/V1/AuthController.php.html deleted file mode 100644 index 1895b46d..00000000 --- a/backend/coverage-report-controllers/Http/Controllers/Api/V1/AuthController.php.html +++ /dev/null @@ -1,333 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Http/Controllers/Api/V1/AuthController.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 56
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 4
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
AuthController
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 56
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 4
132
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 login
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 21
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
30
 register
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 24
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
12
 logout
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 4
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
6
 me
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 7
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Http\Controllers\Api\V1;
4
5use App\Models\User;
6use Illuminate\Http\JsonResponse;
7use Illuminate\Http\Request;
8use Illuminate\Support\Facades\Auth;
9use Illuminate\Support\Facades\Hash;
10use Illuminate\Validation\ValidationException;
11
12class AuthController extends BaseController
13{
14    /**
15     * Login user and create token
16     */
17    public function login(Request $request): JsonResponse
18    {
19        try {
20            $request->validate([
21                'email' => 'required|email',
22                'password' => 'required',
23            ]);
24
25            $user = User::where('email', $request->email)->first();
26
27            if (!$user || !Hash::check($request->password, $user->password)) {
28                return $this->sendError('Invalid credentials', [], 401);
29            }
30
31            $token = $user->createToken('api-token')->plainTextToken;
32
33            return $this->sendResponse([
34                'user' => [
35                    'id' => $user->id,
36                    'name' => $user->name,
37                    'email' => $user->email,
38                ],
39                'token' => $token,
40                'token_type' => 'Bearer',
41            ], 'Login successful');
42        } catch (ValidationException $e) {
43            return $this->sendValidationError($e->errors());
44        } catch (\Exception $e) {
45            return $this->sendError('Login failed: ' . $e->getMessage(), [], 500);
46        }
47    }
48
49    /**
50     * Register a new user
51     */
52    public function register(Request $request): JsonResponse
53    {
54        try {
55            $validated = $request->validate([
56                'name' => 'required|string|max:255',
57                'email' => 'required|string|email|max:255|unique:users',
58                'password' => 'required|string|min:8|confirmed',
59            ]);
60
61            $user = User::create([
62                'name' => $validated['name'],
63                'email' => $validated['email'],
64                'password' => Hash::make($validated['password']),
65            ]);
66
67            $token = $user->createToken('api-token')->plainTextToken;
68
69            return $this->sendResponse([
70                'user' => [
71                    'id' => $user->id,
72                    'name' => $user->name,
73                    'email' => $user->email,
74                ],
75                'token' => $token,
76                'token_type' => 'Bearer',
77            ], 'Registration successful', 201);
78        } catch (ValidationException $e) {
79            return $this->sendValidationError($e->errors());
80        } catch (\Exception $e) {
81            return $this->sendError('Registration failed: ' . $e->getMessage(), [], 500);
82        }
83    }
84
85    /**
86     * Logout user (revoke token)
87     */
88    public function logout(Request $request): JsonResponse
89    {
90        try {
91            $request->user()->currentAccessToken()->delete();
92
93            return $this->sendResponse(null, 'Logged out successfully');
94        } catch (\Exception $e) {
95            return $this->sendError('Logout failed: ' . $e->getMessage(), [], 500);
96        }
97    }
98
99    /**
100     * Get current authenticated user
101     */
102    public function me(Request $request): JsonResponse
103    {
104        return $this->sendResponse([
105            'user' => [
106                'id' => $request->user()->id,
107                'name' => $request->user()->name,
108                'email' => $request->user()->email,
109            ],
110        ], 'User retrieved successfully');
111    }
112}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:51:47 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-controllers/Http/Controllers/Api/V1/BaseController.php.html b/backend/coverage-report-controllers/Http/Controllers/Api/V1/BaseController.php.html deleted file mode 100644 index b65d6899..00000000 --- a/backend/coverage-report-controllers/Http/Controllers/Api/V1/BaseController.php.html +++ /dev/null @@ -1,307 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Http/Controllers/Api/V1/BaseController.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 87.50% covered (warning) -
-
-
87.50%
14 / 16
-
- 60.00% covered (warning) -
-
-
60.00%
3 / 5
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
BaseController
-
- 87.50% covered (warning) -
-
-
87.50%
14 / 16
-
- 60.00% covered (warning) -
-
-
60.00%
3 / 5
6.07
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 sendResponse
-
- 100.00% covered (success) -
-
-
100.00%
6 / 6
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
1
 sendError
-
- 100.00% covered (success) -
-
-
100.00%
7 / 7
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
2
 sendValidationError
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
1
 sendNotFound
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 sendUnauthorized
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Http\Controllers\Api\V1;
4
5use App\Http\Controllers\Controller;
6use Illuminate\Http\JsonResponse;
7
8class BaseController extends Controller
9{
10    /**
11     * Success response method
12     */
13    public function sendResponse(mixed $result, string $message = 'Success', int $code = 200): JsonResponse
14    {
15        $response = [
16            'success' => true,
17            'data' => $result,
18            'message' => $message,
19        ];
20
21        return response()->json($response, $code);
22    }
23
24    /**
25     * Error response method
26     */
27    public function sendError(string $error, array $errorMessages = [], int $code = 400): JsonResponse
28    {
29        $response = [
30            'success' => false,
31            'message' => $error,
32        ];
33
34        if (!empty($errorMessages)) {
35            $response['errors'] = $errorMessages;
36        }
37
38        return response()->json($response, $code);
39    }
40
41    /**
42     * Validation error response method
43     */
44    public function sendValidationError(array $errors): JsonResponse
45    {
46        return $this->sendError('Validation failed', $errors, 422);
47    }
48
49    /**
50     * Not found response method
51     */
52    public function sendNotFound(string $message = 'Resource not found'): JsonResponse
53    {
54        return $this->sendError($message, [], 404);
55    }
56
57    /**
58     * Unauthorized response method
59     */
60    public function sendUnauthorized(string $message = 'Unauthorized'): JsonResponse
61    {
62        return $this->sendError($message, [], 401);
63    }
64}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:51:47 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-controllers/Http/Controllers/Api/V1/DashboardController.php.html b/backend/coverage-report-controllers/Http/Controllers/Api/V1/DashboardController.php.html deleted file mode 100644 index 4b16f8c2..00000000 --- a/backend/coverage-report-controllers/Http/Controllers/Api/V1/DashboardController.php.html +++ /dev/null @@ -1,223 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Http/Controllers/Api/V1/DashboardController.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 84.62% covered (warning) -
-
-
84.62%
11 / 13
-
- 50.00% covered (danger) -
-
-
50.00%
1 / 2
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
DashboardController
-
- 84.62% covered (warning) -
-
-
84.62%
11 / 13
-
- 50.00% covered (danger) -
-
-
50.00%
1 / 2
3.03
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 __construct
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
1
 stats
-
- 83.33% covered (warning) -
-
-
83.33%
10 / 12
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2.02
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Http\Controllers\Api\V1;
4
5use App\Models\Article;
6use App\Models\Feed;
7use App\Models\PlatformAccount;
8use App\Models\PlatformChannel;
9use App\Services\DashboardStatsService;
10use Illuminate\Http\JsonResponse;
11use Illuminate\Http\Request;
12
13class DashboardController extends BaseController
14{
15    public function __construct(
16        private DashboardStatsService $dashboardStatsService
17    ) {}
18
19    /**
20     * Get dashboard statistics
21     */
22    public function stats(Request $request): JsonResponse
23    {
24        $period = $request->get('period', 'today');
25        
26        try {
27            // Get article stats from service
28            $articleStats = $this->dashboardStatsService->getStats($period);
29            
30            // Get system stats
31            $systemStats = $this->dashboardStatsService->getSystemStats();
32            
33            // Get available periods
34            $availablePeriods = $this->dashboardStatsService->getAvailablePeriods();
35            
36            return $this->sendResponse([
37                'article_stats' => $articleStats,
38                'system_stats' => $systemStats,
39                'available_periods' => $availablePeriods,
40                'current_period' => $period,
41            ]);
42        } catch (\Exception $e) {
43            return $this->sendError('Failed to fetch dashboard stats: ' . $e->getMessage(), [], 500);
44        }
45    }
46}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:51:47 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-controllers/Http/Controllers/Api/V1/FeedsController.php.html b/backend/coverage-report-controllers/Http/Controllers/Api/V1/FeedsController.php.html deleted file mode 100644 index 916f2036..00000000 --- a/backend/coverage-report-controllers/Http/Controllers/Api/V1/FeedsController.php.html +++ /dev/null @@ -1,387 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Http/Controllers/Api/V1/FeedsController.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 76.00% covered (warning) -
-
-
76.00%
38 / 50
-
- 33.33% covered (danger) -
-
-
33.33%
2 / 6
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
FeedsController
-
- 76.00% covered (warning) -
-
-
76.00%
38 / 50
-
- 33.33% covered (danger) -
-
-
33.33%
2 / 6
15.34
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 index
-
- 100.00% covered (success) -
-
-
100.00%
7 / 7
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
1
 store
-
- 66.67% covered (warning) -
-
-
66.67%
8 / 12
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
3.33
 show
-
- 100.00% covered (success) -
-
-
100.00%
4 / 4
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
1
 update
-
- 63.64% covered (warning) -
-
-
63.64%
7 / 11
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
3.43
 destroy
-
- 71.43% covered (warning) -
-
-
71.43%
5 / 7
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2.09
 toggle
-
- 77.78% covered (warning) -
-
-
77.78%
7 / 9
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
3.10
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Http\Controllers\Api\V1;
4
5use App\Http\Requests\StoreFeedRequest;
6use App\Http\Requests\UpdateFeedRequest;
7use App\Http\Resources\FeedResource;
8use App\Models\Feed;
9use Illuminate\Http\JsonResponse;
10use Illuminate\Http\Request;
11use Illuminate\Validation\ValidationException;
12
13class FeedsController extends BaseController
14{
15    /**
16     * Display a listing of feeds
17     */
18    public function index(Request $request): JsonResponse
19    {
20        $feeds = Feed::orderBy('is_active', 'desc')
21            ->orderBy('name')
22            ->get();
23
24        return $this->sendResponse(
25            FeedResource::collection($feeds),
26            'Feeds retrieved successfully.'
27        );
28    }
29
30    /**
31     * Store a newly created feed
32     */
33    public function store(StoreFeedRequest $request): JsonResponse
34    {
35        try {
36            $validated = $request->validated();
37            $validated['is_active'] = $validated['is_active'] ?? true;
38
39            $feed = Feed::create($validated);
40
41            return $this->sendResponse(
42                new FeedResource($feed),
43                'Feed created successfully!',
44                201
45            );
46        } catch (ValidationException $e) {
47            return $this->sendValidationError($e->errors());
48        } catch (\Exception $e) {
49            return $this->sendError('Failed to create feed: ' . $e->getMessage(), [], 500);
50        }
51    }
52
53    /**
54     * Display the specified feed
55     */
56    public function show(Feed $feed): JsonResponse
57    {
58        return $this->sendResponse(
59            new FeedResource($feed),
60            'Feed retrieved successfully.'
61        );
62    }
63
64    /**
65     * Update the specified feed
66     */
67    public function update(UpdateFeedRequest $request, Feed $feed): JsonResponse
68    {
69        try {
70            $validated = $request->validated();
71            $validated['is_active'] = $validated['is_active'] ?? $feed->is_active;
72
73            $feed->update($validated);
74
75            return $this->sendResponse(
76                new FeedResource($feed->fresh()),
77                'Feed updated successfully!'
78            );
79        } catch (ValidationException $e) {
80            return $this->sendValidationError($e->errors());
81        } catch (\Exception $e) {
82            return $this->sendError('Failed to update feed: ' . $e->getMessage(), [], 500);
83        }
84    }
85
86    /**
87     * Remove the specified feed
88     */
89    public function destroy(Feed $feed): JsonResponse
90    {
91        try {
92            $feed->delete();
93
94            return $this->sendResponse(
95                null,
96                'Feed deleted successfully!'
97            );
98        } catch (\Exception $e) {
99            return $this->sendError('Failed to delete feed: ' . $e->getMessage(), [], 500);
100        }
101    }
102
103    /**
104     * Toggle feed active status
105     */
106    public function toggle(Feed $feed): JsonResponse
107    {
108        try {
109            $newStatus = !$feed->is_active;
110            $feed->update(['is_active' => $newStatus]);
111
112            $status = $newStatus ? 'activated' : 'deactivated';
113
114            return $this->sendResponse(
115                new FeedResource($feed->fresh()),
116                "Feed {$status} successfully!"
117            );
118        } catch (\Exception $e) {
119            return $this->sendError('Failed to toggle feed status: ' . $e->getMessage(), [], 500);
120        }
121    }
122}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:51:47 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-controllers/Http/Controllers/Api/V1/LogsController.php.html b/backend/coverage-report-controllers/Http/Controllers/Api/V1/LogsController.php.html deleted file mode 100644 index 635465d3..00000000 --- a/backend/coverage-report-controllers/Http/Controllers/Api/V1/LogsController.php.html +++ /dev/null @@ -1,198 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Http/Controllers/Api/V1/LogsController.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 19
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
LogsController
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 19
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
12
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 index
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 19
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
12
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Http\Controllers\Api\V1;
4
5use App\Models\Log;
6use Illuminate\Http\JsonResponse;
7use Illuminate\Http\Request;
8
9class LogsController extends BaseController
10{
11    /**
12     * Display a listing of logs
13     */
14    public function index(Request $request): JsonResponse
15    {
16        try {
17            $perPage = min($request->get('per_page', 20), 100);
18            $level = $request->get('level');
19            
20            $query = Log::orderBy('created_at', 'desc');
21            
22            if ($level) {
23                $query->where('level', $level);
24            }
25            
26            $logs = $query->paginate($perPage);
27
28            return $this->sendResponse([
29                'logs' => $logs->items(),
30                'pagination' => [
31                    'current_page' => $logs->currentPage(),
32                    'last_page' => $logs->lastPage(),
33                    'per_page' => $logs->perPage(),
34                    'total' => $logs->total(),
35                    'from' => $logs->firstItem(),
36                    'to' => $logs->lastItem(),
37                ],
38            ], 'Logs retrieved successfully.');
39        } catch (\Exception $e) {
40            return $this->sendError('Failed to retrieve logs: ' . $e->getMessage(), [], 500);
41        }
42    }
43}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:51:47 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-controllers/Http/Controllers/Api/V1/PlatformAccountsController.php.html b/backend/coverage-report-controllers/Http/Controllers/Api/V1/PlatformAccountsController.php.html deleted file mode 100644 index b7f80612..00000000 --- a/backend/coverage-report-controllers/Http/Controllers/Api/V1/PlatformAccountsController.php.html +++ /dev/null @@ -1,417 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Http/Controllers/Api/V1/PlatformAccountsController.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 73
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 6
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
PlatformAccountsController
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 73
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 6
210
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 index
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 8
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 store
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 30
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
20
 show
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 4
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 update
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 17
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
20
 destroy
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 7
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
6
 setActive
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 7
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
6
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Http\Controllers\Api\V1;
4
5use App\Enums\PlatformEnum;
6use App\Http\Resources\PlatformAccountResource;
7use App\Models\PlatformAccount;
8use App\Models\PlatformInstance;
9use Illuminate\Http\JsonResponse;
10use Illuminate\Http\Request;
11use Illuminate\Validation\ValidationException;
12
13class PlatformAccountsController extends BaseController
14{
15    /**
16     * Display a listing of platform accounts
17     */
18    public function index(): JsonResponse
19    {
20        $accounts = PlatformAccount::with(['platformInstance'])
21            ->orderBy('platform')
22            ->orderBy('created_at', 'desc')
23            ->get();
24
25        return $this->sendResponse(
26            PlatformAccountResource::collection($accounts),
27            'Platform accounts retrieved successfully.'
28        );
29    }
30
31    /**
32     * Store a newly created platform account
33     */
34    public function store(Request $request): JsonResponse
35    {
36        try {
37            $validated = $request->validate([
38                'platform' => 'required|in:lemmy,mastodon,reddit',
39                'instance_url' => 'required|url',
40                'username' => 'required|string|max:255',
41                'password' => 'required|string',
42                'settings' => 'nullable|array',
43            ]);
44
45            // Create or find platform instance
46            $platformEnum = PlatformEnum::from($validated['platform']);
47            $instance = PlatformInstance::firstOrCreate([
48                'platform' => $platformEnum,
49                'url' => $validated['instance_url'],
50            ], [
51                'name' => parse_url($validated['instance_url'], PHP_URL_HOST),
52                'description' => ucfirst($validated['platform']) . ' instance',
53                'is_active' => true,
54            ]);
55
56            $account = PlatformAccount::create($validated);
57
58            // If this is the first account for this platform, make it active
59            if (!PlatformAccount::where('platform', $validated['platform'])
60                ->where('is_active', true)
61                ->exists()) {
62                $account->setAsActive();
63            }
64
65            return $this->sendResponse(
66                new PlatformAccountResource($account->load('platformInstance')),
67                'Platform account created successfully!',
68                201
69            );
70        } catch (ValidationException $e) {
71            return $this->sendValidationError($e->errors());
72        } catch (\Exception $e) {
73            return $this->sendError('Failed to create platform account: ' . $e->getMessage(), [], 500);
74        }
75    }
76
77    /**
78     * Display the specified platform account
79     */
80    public function show(PlatformAccount $platformAccount): JsonResponse
81    {
82        return $this->sendResponse(
83            new PlatformAccountResource($platformAccount->load('platformInstance')),
84            'Platform account retrieved successfully.'
85        );
86    }
87
88    /**
89     * Update the specified platform account
90     */
91    public function update(Request $request, PlatformAccount $platformAccount): JsonResponse
92    {
93        try {
94            $validated = $request->validate([
95                'instance_url' => 'required|url',
96                'username' => 'required|string|max:255',
97                'password' => 'nullable|string',
98                'settings' => 'nullable|array',
99            ]);
100
101            // Don't update password if not provided
102            if (empty($validated['password'])) {
103                unset($validated['password']);
104            }
105
106            $platformAccount->update($validated);
107
108            return $this->sendResponse(
109                new PlatformAccountResource($platformAccount->fresh(['platformInstance'])),
110                'Platform account updated successfully!'
111            );
112        } catch (ValidationException $e) {
113            return $this->sendValidationError($e->errors());
114        } catch (\Exception $e) {
115            return $this->sendError('Failed to update platform account: ' . $e->getMessage(), [], 500);
116        }
117    }
118
119    /**
120     * Remove the specified platform account
121     */
122    public function destroy(PlatformAccount $platformAccount): JsonResponse
123    {
124        try {
125            $platformAccount->delete();
126
127            return $this->sendResponse(
128                null,
129                'Platform account deleted successfully!'
130            );
131        } catch (\Exception $e) {
132            return $this->sendError('Failed to delete platform account: ' . $e->getMessage(), [], 500);
133        }
134    }
135
136    /**
137     * Set platform account as active
138     */
139    public function setActive(PlatformAccount $platformAccount): JsonResponse
140    {
141        try {
142            $platformAccount->setAsActive();
143
144            return $this->sendResponse(
145                new PlatformAccountResource($platformAccount->fresh(['platformInstance'])),
146                "Set {$platformAccount->username}@{$platformAccount->instance_url} as active for {$platformAccount->platform->value}!"
147            );
148        } catch (\Exception $e) {
149            return $this->sendError('Failed to set platform account as active: ' . $e->getMessage(), [], 500);
150        }
151    }
152}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:51:47 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-controllers/Http/Controllers/Api/V1/PlatformChannelsController.php.html b/backend/coverage-report-controllers/Http/Controllers/Api/V1/PlatformChannelsController.php.html deleted file mode 100644 index 738002a6..00000000 --- a/backend/coverage-report-controllers/Http/Controllers/Api/V1/PlatformChannelsController.php.html +++ /dev/null @@ -1,398 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Http/Controllers/Api/V1/PlatformChannelsController.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 62
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 6
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
PlatformChannelsController
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 62
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 6
182
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 index
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 8
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 store
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 19
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
12
 show
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 4
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 update
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 15
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
12
 destroy
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 7
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
6
 toggle
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 9
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
12
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Http\Controllers\Api\V1;
4
5use App\Http\Resources\PlatformChannelResource;
6use App\Models\PlatformChannel;
7use Illuminate\Http\JsonResponse;
8use Illuminate\Http\Request;
9use Illuminate\Validation\ValidationException;
10
11class PlatformChannelsController extends BaseController
12{
13    /**
14     * Display a listing of platform channels
15     */
16    public function index(): JsonResponse
17    {
18        $channels = PlatformChannel::with(['platformInstance'])
19            ->orderBy('is_active', 'desc')
20            ->orderBy('name')
21            ->get();
22
23        return $this->sendResponse(
24            PlatformChannelResource::collection($channels),
25            'Platform channels retrieved successfully.'
26        );
27    }
28
29    /**
30     * Store a newly created platform channel
31     */
32    public function store(Request $request): JsonResponse
33    {
34        try {
35            $validated = $request->validate([
36                'platform_instance_id' => 'required|exists:platform_instances,id',
37                'channel_id' => 'required|string|max:255',
38                'name' => 'required|string|max:255',
39                'display_name' => 'nullable|string|max:255',
40                'description' => 'nullable|string',
41                'is_active' => 'boolean',
42            ]);
43
44            $validated['is_active'] = $validated['is_active'] ?? true;
45
46            $channel = PlatformChannel::create($validated);
47
48            return $this->sendResponse(
49                new PlatformChannelResource($channel->load('platformInstance')),
50                'Platform channel created successfully!',
51                201
52            );
53        } catch (ValidationException $e) {
54            return $this->sendValidationError($e->errors());
55        } catch (\Exception $e) {
56            return $this->sendError('Failed to create platform channel: ' . $e->getMessage(), [], 500);
57        }
58    }
59
60    /**
61     * Display the specified platform channel
62     */
63    public function show(PlatformChannel $channel): JsonResponse
64    {
65        return $this->sendResponse(
66            new PlatformChannelResource($channel->load('platformInstance')),
67            'Platform channel retrieved successfully.'
68        );
69    }
70
71    /**
72     * Update the specified platform channel
73     */
74    public function update(Request $request, PlatformChannel $channel): JsonResponse
75    {
76        try {
77            $validated = $request->validate([
78                'name' => 'required|string|max:255',
79                'display_name' => 'nullable|string|max:255',
80                'description' => 'nullable|string',
81                'is_active' => 'boolean',
82            ]);
83
84            $channel->update($validated);
85
86            return $this->sendResponse(
87                new PlatformChannelResource($channel->fresh(['platformInstance'])),
88                'Platform channel updated successfully!'
89            );
90        } catch (ValidationException $e) {
91            return $this->sendValidationError($e->errors());
92        } catch (\Exception $e) {
93            return $this->sendError('Failed to update platform channel: ' . $e->getMessage(), [], 500);
94        }
95    }
96
97    /**
98     * Remove the specified platform channel
99     */
100    public function destroy(PlatformChannel $channel): JsonResponse
101    {
102        try {
103            $channel->delete();
104
105            return $this->sendResponse(
106                null,
107                'Platform channel deleted successfully!'
108            );
109        } catch (\Exception $e) {
110            return $this->sendError('Failed to delete platform channel: ' . $e->getMessage(), [], 500);
111        }
112    }
113
114    /**
115     * Toggle platform channel active status
116     */
117    public function toggle(PlatformChannel $channel): JsonResponse
118    {
119        try {
120            $newStatus = !$channel->is_active;
121            $channel->update(['is_active' => $newStatus]);
122
123            $status = $newStatus ? 'activated' : 'deactivated';
124
125            return $this->sendResponse(
126                new PlatformChannelResource($channel->fresh(['platformInstance'])),
127                "Platform channel {$status} successfully!"
128            );
129        } catch (\Exception $e) {
130            return $this->sendError('Failed to toggle platform channel status: ' . $e->getMessage(), [], 500);
131        }
132    }
133}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:51:47 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-controllers/Http/Controllers/Api/V1/RoutingController.php.html b/backend/coverage-report-controllers/Http/Controllers/Api/V1/RoutingController.php.html deleted file mode 100644 index 168dd6ea..00000000 --- a/backend/coverage-report-controllers/Http/Controllers/Api/V1/RoutingController.php.html +++ /dev/null @@ -1,430 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Http/Controllers/Api/V1/RoutingController.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 80
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 6
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
RoutingController
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 80
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 6
306
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 index
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 8
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 store
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 18
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
12
 show
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 10
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
6
 update
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 18
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
20
 destroy
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 12
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
12
 toggle
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 14
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
20
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Http\Controllers\Api\V1;
4
5use App\Http\Resources\RouteResource;
6use App\Models\Feed;
7use App\Models\PlatformChannel;
8use App\Models\Route;
9use Illuminate\Http\JsonResponse;
10use Illuminate\Http\Request;
11use Illuminate\Validation\ValidationException;
12
13class RoutingController extends BaseController
14{
15    /**
16     * Display a listing of routing configurations
17     */
18    public function index(): JsonResponse
19    {
20        $routes = Route::with(['feed', 'platformChannel'])
21            ->orderBy('is_active', 'desc')
22            ->orderBy('priority', 'asc')
23            ->get();
24
25        return $this->sendResponse(
26            RouteResource::collection($routes),
27            'Routing configurations retrieved successfully.'
28        );
29    }
30
31    /**
32     * Store a newly created routing configuration
33     */
34    public function store(Request $request): JsonResponse
35    {
36        try {
37            $validated = $request->validate([
38                'feed_id' => 'required|exists:feeds,id',
39                'platform_channel_id' => 'required|exists:platform_channels,id',
40                'is_active' => 'boolean',
41                'priority' => 'nullable|integer|min:0',
42            ]);
43
44            $validated['is_active'] = $validated['is_active'] ?? true;
45            $validated['priority'] = $validated['priority'] ?? 0;
46
47            $route = Route::create($validated);
48
49            return $this->sendResponse(
50                new RouteResource($route->load(['feed', 'platformChannel'])),
51                'Routing configuration created successfully!',
52                201
53            );
54        } catch (ValidationException $e) {
55            return $this->sendValidationError($e->errors());
56        } catch (\Exception $e) {
57            return $this->sendError('Failed to create routing configuration: ' . $e->getMessage(), [], 500);
58        }
59    }
60
61    /**
62     * Display the specified routing configuration
63     */
64    public function show(Feed $feed, PlatformChannel $channel): JsonResponse
65    {
66        $route = Route::where('feed_id', $feed->id)
67            ->where('platform_channel_id', $channel->id)
68            ->with(['feed', 'platformChannel'])
69            ->first();
70
71        if (!$route) {
72            return $this->sendNotFound('Routing configuration not found.');
73        }
74
75        return $this->sendResponse(
76            new RouteResource($route),
77            'Routing configuration retrieved successfully.'
78        );
79    }
80
81    /**
82     * Update the specified routing configuration
83     */
84    public function update(Request $request, Feed $feed, PlatformChannel $channel): JsonResponse
85    {
86        try {
87            $route = Route::where('feed_id', $feed->id)
88                ->where('platform_channel_id', $channel->id)
89                ->first();
90
91            if (!$route) {
92                return $this->sendNotFound('Routing configuration not found.');
93            }
94
95            $validated = $request->validate([
96                'is_active' => 'boolean',
97                'priority' => 'nullable|integer|min:0',
98            ]);
99
100            $route->update($validated);
101
102            return $this->sendResponse(
103                new RouteResource($route->fresh(['feed', 'platformChannel'])),
104                'Routing configuration updated successfully!'
105            );
106        } catch (ValidationException $e) {
107            return $this->sendValidationError($e->errors());
108        } catch (\Exception $e) {
109            return $this->sendError('Failed to update routing configuration: ' . $e->getMessage(), [], 500);
110        }
111    }
112
113    /**
114     * Remove the specified routing configuration
115     */
116    public function destroy(Feed $feed, PlatformChannel $channel): JsonResponse
117    {
118        try {
119            $route = Route::where('feed_id', $feed->id)
120                ->where('platform_channel_id', $channel->id)
121                ->first();
122
123            if (!$route) {
124                return $this->sendNotFound('Routing configuration not found.');
125            }
126
127            $route->delete();
128
129            return $this->sendResponse(
130                null,
131                'Routing configuration deleted successfully!'
132            );
133        } catch (\Exception $e) {
134            return $this->sendError('Failed to delete routing configuration: ' . $e->getMessage(), [], 500);
135        }
136    }
137
138    /**
139     * Toggle routing configuration active status
140     */
141    public function toggle(Feed $feed, PlatformChannel $channel): JsonResponse
142    {
143        try {
144            $route = Route::where('feed_id', $feed->id)
145                ->where('platform_channel_id', $channel->id)
146                ->first();
147
148            if (!$route) {
149                return $this->sendNotFound('Routing configuration not found.');
150            }
151
152            $newStatus = !$route->is_active;
153            $route->update(['is_active' => $newStatus]);
154
155            $status = $newStatus ? 'activated' : 'deactivated';
156
157            return $this->sendResponse(
158                new RouteResource($route->fresh(['feed', 'platformChannel'])),
159                "Routing configuration {$status} successfully!"
160            );
161        } catch (\Exception $e) {
162            return $this->sendError('Failed to toggle routing configuration status: ' . $e->getMessage(), [], 500);
163        }
164    }
165}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:51:47 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-controllers/Http/Controllers/Api/V1/SettingsController.php.html b/backend/coverage-report-controllers/Http/Controllers/Api/V1/SettingsController.php.html deleted file mode 100644 index ed9addb2..00000000 --- a/backend/coverage-report-controllers/Http/Controllers/Api/V1/SettingsController.php.html +++ /dev/null @@ -1,240 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Http/Controllers/Api/V1/SettingsController.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 85.19% covered (warning) -
-
-
85.19%
23 / 27
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
SettingsController
-
- 85.19% covered (warning) -
-
-
85.19%
23 / 27
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
7.16
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 index
-
- 71.43% covered (warning) -
-
-
71.43%
5 / 7
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2.09
 update
-
- 90.00% covered (success) -
-
-
90.00%
18 / 20
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
5.03
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Http\Controllers\Api\V1;
4
5use App\Models\Setting;
6use Illuminate\Http\JsonResponse;
7use Illuminate\Http\Request;
8use Illuminate\Validation\ValidationException;
9
10class SettingsController extends BaseController
11{
12    /**
13     * Display current settings
14     */
15    public function index(): JsonResponse
16    {
17        try {
18            $settings = [
19                'article_processing_enabled' => Setting::isArticleProcessingEnabled(),
20                'publishing_approvals_enabled' => Setting::isPublishingApprovalsEnabled(),
21            ];
22
23            return $this->sendResponse($settings, 'Settings retrieved successfully.');
24        } catch (\Exception $e) {
25            return $this->sendError('Failed to retrieve settings: ' . $e->getMessage(), [], 500);
26        }
27    }
28
29    /**
30     * Update settings
31     */
32    public function update(Request $request): JsonResponse
33    {
34        try {
35            $validated = $request->validate([
36                'article_processing_enabled' => 'boolean',
37                'enable_publishing_approvals' => 'boolean',
38            ]);
39
40            if (isset($validated['article_processing_enabled'])) {
41                Setting::setArticleProcessingEnabled($validated['article_processing_enabled']);
42            }
43
44            if (isset($validated['enable_publishing_approvals'])) {
45                Setting::setPublishingApprovalsEnabled($validated['enable_publishing_approvals']);
46            }
47
48            $updatedSettings = [
49                'article_processing_enabled' => Setting::isArticleProcessingEnabled(),
50                'publishing_approvals_enabled' => Setting::isPublishingApprovalsEnabled(),
51            ];
52
53            return $this->sendResponse(
54                $updatedSettings,
55                'Settings updated successfully.'
56            );
57        } catch (ValidationException $e) {
58            return $this->sendValidationError($e->errors());
59        } catch (\Exception $e) {
60            return $this->sendError('Failed to update settings: ' . $e->getMessage(), [], 500);
61        }
62    }
63}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:51:47 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-controllers/Http/Controllers/Api/V1/dashboard.html b/backend/coverage-report-controllers/Http/Controllers/Api/V1/dashboard.html deleted file mode 100644 index 7099f00e..00000000 --- a/backend/coverage-report-controllers/Http/Controllers/Api/V1/dashboard.html +++ /dev/null @@ -1,365 +0,0 @@ - - - - - Dashboard for /var/www/html/backend/app/Http/Controllers/Api/V1 - - - - - - - -
-
-
-
- -
-
-
-
-
-
-
-

Classes

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
- -
-
-

Methods

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
-
-
-

Insufficient Coverage

-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
MethodCoverage
login0%
register0%
logout0%
me0%
sendNotFound0%
sendUnauthorized0%
index0%
index0%
store0%
show0%
update0%
destroy0%
setActive0%
index0%
store0%
show0%
update0%
destroy0%
toggle0%
index0%
store0%
show0%
update0%
destroy0%
toggle0%
update63%
store66%
approve71%
reject71%
destroy71%
index71%
toggle77%
stats83%
-
-
-
-

Project Risks

-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
MethodCRAP
login30
store20
update20
update20
toggle20
register12
index12
store12
update12
toggle12
store12
destroy12
logout6
destroy6
setActive6
destroy6
show6
update3
store3
toggle3
approve2
reject2
destroy2
index2
stats2
-
-
-
- -
- - - - - - diff --git a/backend/coverage-report-controllers/Http/Controllers/Api/V1/index.html b/backend/coverage-report-controllers/Http/Controllers/Api/V1/index.html deleted file mode 100644 index a43cec76..00000000 --- a/backend/coverage-report-controllers/Http/Controllers/Api/V1/index.html +++ /dev/null @@ -1,374 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Http/Controllers/Api/V1 - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 26.81% covered (danger) -
-
-
26.81%
115 / 429
-
- 17.07% covered (danger) -
-
-
17.07%
7 / 41
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 10
ArticlesController.php
-
- 87.88% covered (warning) -
-
-
87.88%
29 / 33
-
- 33.33% covered (danger) -
-
-
33.33%
1 / 3
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
AuthController.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 56
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 4
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
BaseController.php
-
- 87.50% covered (warning) -
-
-
87.50%
14 / 16
-
- 60.00% covered (warning) -
-
-
60.00%
3 / 5
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
DashboardController.php
-
- 84.62% covered (warning) -
-
-
84.62%
11 / 13
-
- 50.00% covered (danger) -
-
-
50.00%
1 / 2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
FeedsController.php
-
- 76.00% covered (warning) -
-
-
76.00%
38 / 50
-
- 33.33% covered (danger) -
-
-
33.33%
2 / 6
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
LogsController.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 19
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
PlatformAccountsController.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 73
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 6
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
PlatformChannelsController.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 62
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 6
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
RoutingController.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 80
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 6
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
SettingsController.php
-
- 85.19% covered (warning) -
-
-
85.19%
23 / 27
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- -
- - diff --git a/backend/coverage-report-controllers/Http/Controllers/Api/dashboard.html b/backend/coverage-report-controllers/Http/Controllers/Api/dashboard.html deleted file mode 100644 index 30845386..00000000 --- a/backend/coverage-report-controllers/Http/Controllers/Api/dashboard.html +++ /dev/null @@ -1,364 +0,0 @@ - - - - - Dashboard for /var/www/html/backend/app/Http/Controllers/Api - - - - - - - -
-
-
-
- -
-
-
-
-
-
-
-

Classes

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
- -
-
-

Methods

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
-
-
-

Insufficient Coverage

-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
MethodCoverage
login0%
register0%
logout0%
me0%
sendNotFound0%
sendUnauthorized0%
index0%
index0%
store0%
show0%
update0%
destroy0%
setActive0%
index0%
store0%
show0%
update0%
destroy0%
toggle0%
index0%
store0%
show0%
update0%
destroy0%
toggle0%
update63%
store66%
approve71%
reject71%
destroy71%
index71%
toggle77%
stats83%
-
-
-
-

Project Risks

-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
MethodCRAP
login30
store20
update20
update20
toggle20
register12
index12
store12
update12
toggle12
store12
destroy12
logout6
destroy6
setActive6
destroy6
show6
update3
store3
toggle3
approve2
reject2
destroy2
index2
stats2
-
-
-
- -
- - - - - - diff --git a/backend/coverage-report-controllers/Http/Controllers/Api/index.html b/backend/coverage-report-controllers/Http/Controllers/Api/index.html deleted file mode 100644 index ec19c07c..00000000 --- a/backend/coverage-report-controllers/Http/Controllers/Api/index.html +++ /dev/null @@ -1,121 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Http/Controllers/Api - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 26.81% covered (danger) -
-
-
26.81%
115 / 429
-
- 17.07% covered (danger) -
-
-
17.07%
7 / 41
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 10
V1
-
- 26.81% covered (danger) -
-
-
26.81%
115 / 429
-
- 17.07% covered (danger) -
-
-
17.07%
7 / 41
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 10
-
- -
- - diff --git a/backend/coverage-report-controllers/Http/Controllers/ArticlesController.php.html b/backend/coverage-report-controllers/Http/Controllers/ArticlesController.php.html deleted file mode 100644 index a62e326b..00000000 --- a/backend/coverage-report-controllers/Http/Controllers/ArticlesController.php.html +++ /dev/null @@ -1,234 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Http/Controllers/ArticlesController.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 9
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
ArticlesController
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 9
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
12
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 __invoke
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 5
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 approve
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 reject
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Http\Controllers;
4
5use App\Models\Article;
6use App\Models\Setting;
7use Illuminate\Contracts\View\View;
8use Illuminate\Http\RedirectResponse;
9use Illuminate\Http\Request;
10
11class ArticlesController extends Controller
12{
13    public function __invoke(Request $request): View
14    {
15        $articles = Article::with('articlePublication')
16            ->orderBy('created_at', 'desc')
17            ->paginate(15);
18
19        $publishingApprovalsEnabled = Setting::isPublishingApprovalsEnabled();
20
21        return view('pages.articles.index', compact('articles', 'publishingApprovalsEnabled'));
22    }
23
24    public function approve(Article $article): RedirectResponse
25    {
26        $article->approve('manual');
27
28        return redirect()->back()->with('success', 'Article approved and queued for publishing.');
29    }
30
31    public function reject(Article $article): RedirectResponse
32    {
33        $article->reject('manual');
34
35        return redirect()->back()->with('success', 'Article rejected.');
36    }
37}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:51:47 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-controllers/Http/Controllers/Controller.php.html b/backend/coverage-report-controllers/Http/Controllers/Controller.php.html deleted file mode 100644 index 5d17b566..00000000 --- a/backend/coverage-report-controllers/Http/Controllers/Controller.php.html +++ /dev/null @@ -1,109 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Http/Controllers/Controller.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
n/a
0 / 0
n/a
0 / 0
CRAP
n/a
0 / 0
Controller
n/a
0 / 0
n/a
0 / 0
0
n/a
0 / 0
-
- - - - - - - - - - - - -
1<?php
2
3namespace App\Http\Controllers;
4
5abstract class Controller
6{
7    //
8}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:51:47 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-controllers/Http/Controllers/FeedsController.php.html b/backend/coverage-report-controllers/Http/Controllers/FeedsController.php.html deleted file mode 100644 index 23ac4778..00000000 --- a/backend/coverage-report-controllers/Http/Controllers/FeedsController.php.html +++ /dev/null @@ -1,388 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Http/Controllers/FeedsController.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 28
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 8
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
FeedsController
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 28
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 8
90
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 index
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 4
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 create
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 store
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 8
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 show
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 edit
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 update
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 5
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 destroy
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 toggle
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 5
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
6
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Http\Controllers;
4
5use App\Models\Feed;
6use App\Http\Requests\StoreFeedRequest;
7use App\Http\Requests\UpdateFeedRequest;
8use App\Services\OnboardingRedirectService;
9use Illuminate\Contracts\View\View;
10use Illuminate\Http\RedirectResponse;
11
12class FeedsController extends Controller
13{
14    public function index(): View
15    {
16        $feeds = Feed::orderBy('is_active', 'desc')
17            ->orderBy('name')
18            ->get();
19
20        return view('pages.feeds.index', compact('feeds'));
21    }
22
23    public function create(): View
24    {
25        return view('pages.feeds.create');
26    }
27
28    public function store(StoreFeedRequest $request): RedirectResponse
29    {
30        $validated = $request->validated();
31        $validated['is_active'] = $validated['is_active'] ?? true;
32
33        Feed::create($validated);
34
35        return OnboardingRedirectService::handleRedirect(
36            $request,
37            'feeds.index',
38            'Feed created successfully!'
39        );
40    }
41
42    public function show(Feed $feed): View
43    {
44        return view('pages.feeds.show', compact('feed'));
45    }
46
47    public function edit(Feed $feed): View
48    {
49        return view('pages.feeds.edit', compact('feed'));
50    }
51
52    public function update(UpdateFeedRequest $request, Feed $feed): RedirectResponse
53    {
54        $validated = $request->validated();
55        $validated['is_active'] = $validated['is_active'] ?? $feed->is_active;
56
57        $feed->update($validated);
58
59        return redirect()->route('feeds.index')
60            ->with('success', 'Feed updated successfully!');
61    }
62
63    public function destroy(Feed $feed): RedirectResponse
64    {
65        $feed->delete();
66
67        return redirect()->route('feeds.index')
68            ->with('success', 'Feed deleted successfully!');
69    }
70
71    public function toggle(Feed $feed): RedirectResponse
72    {
73        $newStatus = !$feed->is_active;
74        $feed->update(['is_active' => $newStatus]);
75
76        $status = $newStatus ? 'activated' : 'deactivated';
77
78        return redirect()->route('feeds.index')
79            ->with('success', "Feed {$status} successfully!");
80    }
81}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:51:47 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-controllers/Http/Controllers/LogsController.php.html b/backend/coverage-report-controllers/Http/Controllers/LogsController.php.html deleted file mode 100644 index fd5ade7b..00000000 --- a/backend/coverage-report-controllers/Http/Controllers/LogsController.php.html +++ /dev/null @@ -1,170 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Http/Controllers/LogsController.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
LogsController
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 __invoke
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Http\Controllers;
4
5use App\Models\Log;
6use Illuminate\Contracts\View\View;
7use Illuminate\Http\Request;
8
9class LogsController extends Controller
10{
11    public function __invoke(Request $request): View
12    {
13        $logs = Log::orderBy('created_at', 'desc')->paginate(50);
14
15        return view('pages.logs.index', compact('logs'));
16    }
17}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:51:47 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-controllers/Http/Controllers/OnboardingController.php.html b/backend/coverage-report-controllers/Http/Controllers/OnboardingController.php.html deleted file mode 100644 index ee18185e..00000000 --- a/backend/coverage-report-controllers/Http/Controllers/OnboardingController.php.html +++ /dev/null @@ -1,443 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Http/Controllers/OnboardingController.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 40
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 9
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
OnboardingController
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 40
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 9
506
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 index
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 15
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
6
 platform
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
6
 feed
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 5
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
12
 channel
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 7
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
20
 complete
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 6
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
30
 needsOnboarding
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
12
 hasPlatformAccount
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 hasFeed
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 hasChannel
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Http\Controllers;
4
5use App\Models\Feed;
6use App\Models\PlatformAccount;
7use App\Models\PlatformChannel;
8use App\Models\PlatformInstance;
9use App\Services\SystemStatusService;
10use App\Services\DashboardStatsService;
11use Illuminate\Http\Request;
12use Illuminate\View\View;
13use Illuminate\Http\RedirectResponse;
14
15class OnboardingController extends Controller
16{
17    public function index(Request $request): View|RedirectResponse
18    {
19        // Check if user needs onboarding
20        if (!$this->needsOnboarding()) {
21            $systemStatus = resolve(SystemStatusService::class)->getSystemStatus();
22            $statsService = resolve(DashboardStatsService::class);
23            
24            $period = $request->get('period', 'today');
25            $stats = $statsService->getStats($period);
26            $systemStats = $statsService->getSystemStats();
27            $availablePeriods = $statsService->getAvailablePeriods();
28
29            return view('pages.dashboard', compact(
30                'systemStatus', 
31                'stats', 
32                'systemStats', 
33                'availablePeriods', 
34                'period'
35            ));
36        }
37
38        return view('onboarding.welcome');
39    }
40
41    public function platform(): View|RedirectResponse
42    {
43        if (!$this->needsOnboarding()) {
44            return redirect()->route('feeds.index');
45        }
46
47        return view('onboarding.platform');
48    }
49
50    public function feed(): View|RedirectResponse
51    {
52        if (!$this->needsOnboarding()) {
53            return redirect()->route('feeds.index');
54        }
55
56        if (!$this->hasPlatformAccount()) {
57            return redirect()->route('onboarding.platform');
58        }
59
60        return view('onboarding.feed');
61    }
62
63    public function channel(): View|RedirectResponse
64    {
65        if (!$this->needsOnboarding()) {
66            return redirect()->route('feeds.index');
67        }
68
69        if (!$this->hasPlatformAccount()) {
70            return redirect()->route('onboarding.platform');
71        }
72
73        if (!$this->hasFeed()) {
74            return redirect()->route('onboarding.feed');
75        }
76
77        return view('onboarding.channel');
78    }
79
80    public function complete(): View|RedirectResponse
81    {
82        if (!$this->needsOnboarding()) {
83            return redirect()->route('feeds.index');
84        }
85
86        if (!$this->hasPlatformAccount() || !$this->hasFeed() || !$this->hasChannel()) {
87            return redirect()->route('onboarding.index');
88        }
89
90        $systemStatus = resolve(SystemStatusService::class)->getSystemStatus();
91
92        return view('onboarding.complete', compact('systemStatus'));
93    }
94
95    private function needsOnboarding(): bool
96    {
97        return !$this->hasPlatformAccount() || !$this->hasFeed() || !$this->hasChannel();
98    }
99
100    private function hasPlatformAccount(): bool
101    {
102        return PlatformAccount::where('is_active', true)->exists();
103    }
104
105    private function hasFeed(): bool
106    {
107        return Feed::where('is_active', true)->exists();
108    }
109
110    private function hasChannel(): bool
111    {
112        return PlatformChannel::where('is_active', true)->exists();
113    }
114}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:51:47 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-controllers/Http/Controllers/PlatformAccountsController.php.html b/backend/coverage-report-controllers/Http/Controllers/PlatformAccountsController.php.html deleted file mode 100644 index 4fb65666..00000000 --- a/backend/coverage-report-controllers/Http/Controllers/PlatformAccountsController.php.html +++ /dev/null @@ -1,391 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Http/Controllers/PlatformAccountsController.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 46
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 7
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
PlatformAccountsController
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 46
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 7
110
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 index
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 create
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 store
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 25
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
12
 edit
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 update
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 11
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
6
 destroy
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 setActive
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Http\Controllers;
4
5use App\Models\PlatformAccount;
6use App\Models\PlatformInstance;
7use App\Enums\PlatformEnum;
8use Illuminate\Http\Request;
9use Illuminate\Contracts\View\View;
10use Illuminate\Http\RedirectResponse;
11use Illuminate\Support\Facades\View as ViewFacade;
12
13class PlatformAccountsController extends Controller
14{
15    public function index(): View
16    {
17        $accounts = PlatformAccount::orderBy('platform')->orderBy('created_at', 'desc')->get();
18
19        return view('pages.platforms.index', compact('accounts'));
20    }
21
22    public function create(): View
23    {
24        return ViewFacade::make('pages.platforms.create');
25    }
26
27    public function store(Request $request): RedirectResponse
28    {
29        $validated = $request->validate([
30            'platform' => 'required|in:lemmy,mastodon,reddit',
31            'instance_url' => 'required|url',
32            'username' => 'required|string|max:255',
33            'password' => 'required|string',
34            'settings' => 'nullable|array',
35        ]);
36
37        // Create or find platform instance
38        $platformEnum = PlatformEnum::from($validated['platform']);
39        $instance = PlatformInstance::firstOrCreate([
40            'platform' => $platformEnum,
41            'url' => $validated['instance_url'],
42        ], [
43            'name' => parse_url($validated['instance_url'], PHP_URL_HOST),
44            'description' => ucfirst($validated['platform']) . ' instance',
45            'is_active' => true,
46        ]);
47
48        $account = PlatformAccount::create($validated);
49
50        // If this is the first account for this platform, make it active
51        if (! PlatformAccount::where('platform', $validated['platform'])->where('is_active', true)->exists()) {
52            $account->setAsActive();
53        }
54
55        // Check if there's a redirect_to parameter for onboarding flow
56        $redirectTo = $request->input('redirect_to');
57        if ($redirectTo) {
58            return redirect($redirectTo)
59                ->with('success', 'Platform account created successfully!');
60        }
61
62        return redirect()->route('platforms.index')
63            ->with('success', 'Platform account created successfully!');
64    }
65
66    public function edit(PlatformAccount $platformAccount): View
67    {
68        return ViewFacade::make('pages.platforms.edit', compact('platformAccount'));
69    }
70
71    public function update(Request $request, PlatformAccount $platformAccount): RedirectResponse
72    {
73        $validated = $request->validate([
74            'instance_url' => 'required|url',
75            'username' => 'required|string|max:255',
76            'password' => 'nullable|string',
77            'settings' => 'nullable|array',
78        ]);
79
80        // Don't update password if not provided
81        if (empty($validated['password'])) {
82            unset($validated['password']);
83        }
84
85        $platformAccount->update($validated);
86
87        return redirect()->route('platforms.index')
88            ->with('success', 'Platform account updated successfully!');
89    }
90
91    public function destroy(PlatformAccount $platformAccount): RedirectResponse
92    {
93        $platformAccount->delete();
94
95        return redirect()->route('platforms.index')
96            ->with('success', 'Platform account deleted successfully!');
97    }
98
99    public function setActive(PlatformAccount $platformAccount): RedirectResponse
100    {
101        $platformAccount->setAsActive();
102
103        return redirect()->route('platforms.index')
104            ->with('success', "Set $platformAccount->username@$platformAccount->instance_url as active for {$platformAccount->platform->value}!");
105    }
106}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:51:47 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-controllers/Http/Controllers/PlatformChannelsController.php.html b/backend/coverage-report-controllers/Http/Controllers/PlatformChannelsController.php.html deleted file mode 100644 index 53fbdc0a..00000000 --- a/backend/coverage-report-controllers/Http/Controllers/PlatformChannelsController.php.html +++ /dev/null @@ -1,423 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Http/Controllers/PlatformChannelsController.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 53
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 8
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
PlatformChannelsController
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 53
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 8
110
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 index
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 5
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 create
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 4
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 store
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 18
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
6
 show
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 edit
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 4
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 update
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 12
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 destroy
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 toggle
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 5
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
6
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Http\Controllers;
4
5use App\Models\PlatformChannel;
6use App\Models\PlatformInstance;
7use Illuminate\Http\Request;
8use Illuminate\Contracts\View\View;
9use Illuminate\Http\RedirectResponse;
10use Illuminate\Support\Facades\View as ViewFacade;
11
12class PlatformChannelsController extends Controller
13{
14    public function index(): View
15    {
16        $channels = PlatformChannel::with('platformInstance')
17            ->orderBy('platform_instance_id')
18            ->orderBy('name')
19            ->get();
20        
21        return ViewFacade::make('pages.channels.index', compact('channels'));
22    }
23
24    public function create(): View
25    {
26        $instances = PlatformInstance::where('is_active', true)
27            ->orderBy('name')
28            ->get();
29            
30        return ViewFacade::make('pages.channels.create', compact('instances'));
31    }
32
33    public function store(Request $request): RedirectResponse
34    {
35        $validated = $request->validate([
36            'platform_instance_id' => 'required|exists:platform_instances,id',
37            'name' => 'required|string|max:255',
38            'display_name' => 'nullable|string|max:255',
39            'channel_id' => 'nullable|string|max:255',
40            'description' => 'nullable|string',
41            'language_id' => 'required|exists:languages,id',
42            'is_active' => 'boolean',
43        ]);
44
45        // Default is_active to true if not provided
46        $validated['is_active'] = $validated['is_active'] ?? true;
47        
48        // Set display_name to name if not provided
49        $validated['display_name'] = $validated['display_name'] ?? $validated['name'];
50
51        PlatformChannel::create($validated);
52
53        // Check if there's a redirect_to parameter for onboarding flow
54        $redirectTo = $request->input('redirect_to');
55        if ($redirectTo) {
56            return redirect($redirectTo)
57                ->with('success', 'Channel created successfully!');
58        }
59
60        return redirect()->route('channels.index')
61            ->with('success', 'Channel created successfully!');
62    }
63
64    public function show(PlatformChannel $channel): View
65    {
66        $channel->load(['platformInstance', 'feeds']);
67        
68        return ViewFacade::make('pages.channels.show', compact('channel'));
69    }
70
71    public function edit(PlatformChannel $channel): View
72    {
73        $instances = PlatformInstance::where('is_active', true)
74            ->orderBy('name')
75            ->get();
76            
77        return ViewFacade::make('pages.channels.edit', compact('channel', 'instances'));
78    }
79
80    public function update(Request $request, PlatformChannel $channel): RedirectResponse
81    {
82        $validated = $request->validate([
83            'platform_instance_id' => 'required|exists:platform_instances,id',
84            'name' => 'required|string|max:255',
85            'display_name' => 'nullable|string|max:255',
86            'channel_id' => 'nullable|string|max:255',
87            'description' => 'nullable|string',
88            'language_id' => 'required|exists:languages,id',
89            'is_active' => 'boolean',
90        ]);
91
92        $channel->update($validated);
93
94        return redirect()->route('channels.index')
95            ->with('success', 'Channel updated successfully!');
96    }
97
98    public function destroy(PlatformChannel $channel): RedirectResponse
99    {
100        $channel->delete();
101
102        return redirect()->route('channels.index')
103            ->with('success', 'Channel deleted successfully!');
104    }
105
106    public function toggle(PlatformChannel $channel): RedirectResponse
107    {
108        $newStatus = !$channel->is_active;
109        $channel->update(['is_active' => $newStatus]);
110
111        $status = $newStatus ? 'activated' : 'deactivated';
112
113        return redirect()->route('channels.index')
114            ->with('success', "Channel {$status} successfully!");
115    }
116}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:51:47 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-controllers/Http/Controllers/RoutingController.php.html b/backend/coverage-report-controllers/Http/Controllers/RoutingController.php.html deleted file mode 100644 index 64800e2e..00000000 --- a/backend/coverage-report-controllers/Http/Controllers/RoutingController.php.html +++ /dev/null @@ -1,480 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Http/Controllers/RoutingController.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 87
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 8
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
RoutingController
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 87
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 8
240
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 index
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 9
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 create
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 8
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 store
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 28
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
12
 edit
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 6
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
6
 update
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 14
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 destroy
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 toggle
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 13
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
12
 parseJsonFilters
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 6
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
12
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Http\Controllers;
4
5use App\Models\Feed;
6use App\Models\Route;
7use App\Models\PlatformChannel;
8use App\Services\RoutingValidationService;
9use App\Exceptions\RoutingMismatchException;
10use Illuminate\Database\Eloquent\Collection;
11use Illuminate\Http\Request;
12use Illuminate\Contracts\View\View;
13use Illuminate\Http\RedirectResponse;
14
15class RoutingController extends Controller
16{
17    public function index(): View
18    {
19        $feeds = Feed::with(['channels.platformInstance'])
20            ->where('is_active', true)
21            ->orderBy('name')
22            ->get();
23
24        $channels = PlatformChannel::with(['platformInstance', 'feeds'])
25            ->where('is_active', true)
26            ->orderBy('name')
27            ->get();
28
29        return view('pages.routing.index', compact('feeds', 'channels'));
30    }
31
32    public function create(): View
33    {
34        $feeds = Feed::where('is_active', true)
35            ->orderBy('name')
36            ->get();
37
38        $channels = PlatformChannel::with('platformInstance')
39            ->where('is_active', true)
40            ->orderBy('name')
41            ->get();
42
43        return view('pages.routing.create', compact('feeds', 'channels'));
44    }
45
46    public function store(Request $request): RedirectResponse
47    {
48        $validated = $request->validate([
49            'feed_id' => 'required|exists:feeds,id',
50            'channel_ids' => 'required|array|min:1',
51            'channel_ids.*' => 'exists:platform_channels,id',
52            'priority' => 'integer|min:0|max:100',
53            'filters' => 'nullable|string'
54        ]);
55
56        /** @var Feed $feed */
57        $feed = Feed::findOrFail($validated['feed_id']);
58        
59        /** @var Collection<int, PlatformChannel> $channels */
60        $channels = PlatformChannel::findMany($validated['channel_ids']);
61        $priority = $validated['priority'] ?? 0;
62
63        try {
64            app(RoutingValidationService::class)->validateLanguageCompatibility($feed, $channels);
65        } catch (RoutingMismatchException $e) {
66            return redirect()->back()
67                ->withInput()
68                ->withErrors(['language' => $e->getMessage()]);
69        }
70
71        $filters = $this->parseJsonFilters($validated['filters'] ?? null);
72
73        // Attach channels to feed
74        $syncData = [];
75        foreach ($validated['channel_ids'] as $channelId) {
76            $syncData[$channelId] = [
77                'is_active' => true,
78                'priority' => $priority,
79                'filters' => $filters,
80                'created_at' => now(),
81                'updated_at' => now()
82            ];
83        }
84
85        $feed->channels()->syncWithoutDetaching($syncData);
86
87        return redirect()->route('routing.index')
88            ->with('success', 'Feed routing created successfully!');
89    }
90
91    public function edit(Feed $feed, PlatformChannel $channel): View
92    {
93        $routing = $feed->channels()
94            ->wherePivot('platform_channel_id', $channel->id)
95            ->first();
96
97        if (! $routing) {
98            abort(404, 'Routing not found');
99        }
100
101        return view('pages.routing.edit', compact('feed', 'channel', 'routing'));
102    }
103
104    public function update(Request $request, Feed $feed, PlatformChannel $channel): RedirectResponse
105    {
106        $validated = $request->validate([
107            'is_active' => 'boolean',
108            'priority' => 'integer|min:0|max:100',
109            'filters' => 'nullable|string'
110        ]);
111
112        $filters = $this->parseJsonFilters($validated['filters'] ?? null);
113
114        $feed->channels()->updateExistingPivot($channel->id, [
115            'is_active' => $validated['is_active'] ?? true,
116            'priority' => $validated['priority'] ?? 0,
117            'filters' => $filters,
118            'updated_at' => now()
119        ]);
120
121        return redirect()->route('routing.index')
122            ->with('success', 'Routing updated successfully!');
123    }
124
125    public function destroy(Feed $feed, PlatformChannel $channel): RedirectResponse
126    {
127        $feed->channels()->detach($channel->id);
128
129        return redirect()->route('routing.index')
130            ->with('success', 'Routing deleted successfully!');
131    }
132
133    public function toggle(Request $request, Feed $feed, PlatformChannel $channel): RedirectResponse
134    {
135        $routing = Route::where('feed_id', $feed->id)
136            ->where('platform_channel_id', $channel->id)
137            ->first();
138
139        if (! $routing) {
140            abort(404, 'Routing not found');
141        }
142
143        $newStatus = ! $routing->is_active;
144
145        $feed->channels()->updateExistingPivot($channel->id, [
146            'is_active' => $newStatus,
147            'updated_at' => now()
148        ]);
149
150        $status = $newStatus ? 'activated' : 'deactivated';
151
152        return redirect()->route('routing.index')
153            ->with('success', "Routing {$status} successfully!");
154    }
155
156    /**
157     * @return array<string, mixed>|null
158     */
159    private function parseJsonFilters(?string $json): ?array
160    {
161        if (empty($json)) {
162            return null;
163        }
164
165        $decoded = json_decode($json, true);
166
167        if (json_last_error() === JSON_ERROR_NONE) {
168            return $decoded;
169        }
170
171        return null;
172    }
173}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:51:47 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-controllers/Http/Controllers/SettingsController.php.html b/backend/coverage-report-controllers/Http/Controllers/SettingsController.php.html deleted file mode 100644 index 112fb8dc..00000000 --- a/backend/coverage-report-controllers/Http/Controllers/SettingsController.php.html +++ /dev/null @@ -1,214 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Http/Controllers/SettingsController.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 14
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
SettingsController
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 14
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
12
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 index
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 update
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 11
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
6
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Http\Controllers;
4
5use App\Models\Setting;
6use Illuminate\Contracts\View\View;
7use Illuminate\Http\RedirectResponse;
8use Illuminate\Http\Request;
9
10class SettingsController extends Controller
11{
12    public function index(): View
13    {
14        $articleProcessingEnabled = Setting::isArticleProcessingEnabled();
15        $publishingApprovalsEnabled = Setting::isPublishingApprovalsEnabled();
16        
17        return view('pages.settings.index', compact('articleProcessingEnabled', 'publishingApprovalsEnabled'));
18    }
19
20    public function update(Request $request): RedirectResponse
21    {
22        $request->validate([
23            'article_processing_enabled' => 'boolean',
24            'enable_publishing_approvals' => 'boolean',
25        ]);
26
27        Setting::setArticleProcessingEnabled($request->boolean('article_processing_enabled'));
28        Setting::setPublishingApprovalsEnabled($request->boolean('enable_publishing_approvals'));
29
30        // If redirected from onboarding, go to dashboard
31        if ($request->get('from') === 'onboarding') {
32            return redirect()->route('onboarding.index')
33                ->with('success', 'System activated successfully! Welcome to Lemmy Poster.');
34        }
35
36        return redirect()->route('settings.index')
37            ->with('success', 'Settings updated successfully.');
38    }
39}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:51:47 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-controllers/Http/Controllers/dashboard.html b/backend/coverage-report-controllers/Http/Controllers/dashboard.html deleted file mode 100644 index a0b4d768..00000000 --- a/backend/coverage-report-controllers/Http/Controllers/dashboard.html +++ /dev/null @@ -1,439 +0,0 @@ - - - - - Dashboard for /var/www/html/backend/app/Http/Controllers - - - - - - - -
-
-
-
- -
-
-
-
-
-
-
-

Classes

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
-
- - -
-
-
-

Methods

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
-
-
-

Insufficient Coverage

-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
MethodCoverage
login0%
register0%
logout0%
me0%
sendNotFound0%
sendUnauthorized0%
index0%
index0%
store0%
show0%
update0%
destroy0%
setActive0%
index0%
store0%
show0%
update0%
destroy0%
toggle0%
index0%
store0%
show0%
update0%
destroy0%
toggle0%
__invoke0%
approve0%
reject0%
index0%
create0%
store0%
show0%
edit0%
update0%
destroy0%
toggle0%
__invoke0%
index0%
platform0%
feed0%
channel0%
complete0%
needsOnboarding0%
hasPlatformAccount0%
hasFeed0%
hasChannel0%
index0%
create0%
store0%
edit0%
update0%
destroy0%
setActive0%
index0%
create0%
store0%
show0%
edit0%
update0%
destroy0%
toggle0%
index0%
create0%
store0%
edit0%
update0%
destroy0%
toggle0%
parseJsonFilters0%
index0%
update0%
update63%
store66%
approve71%
reject71%
destroy71%
index71%
toggle77%
stats83%
-
-
-
-

Project Risks

-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
MethodCRAP
login30
complete30
store20
update20
update20
toggle20
channel20
register12
index12
store12
update12
toggle12
store12
destroy12
feed12
needsOnboarding12
store12
store12
toggle12
parseJsonFilters12
logout6
destroy6
setActive6
destroy6
show6
toggle6
index6
platform6
update6
store6
toggle6
edit6
update6
update3
store3
toggle3
approve2
reject2
destroy2
index2
stats2
-
-
-
- -
- - - - - - diff --git a/backend/coverage-report-controllers/Http/Controllers/index.html b/backend/coverage-report-controllers/Http/Controllers/index.html deleted file mode 100644 index 7f8730c2..00000000 --- a/backend/coverage-report-controllers/Http/Controllers/index.html +++ /dev/null @@ -1,357 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Http/Controllers - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 16.24% covered (danger) -
-
-
16.24%
115 / 708
-
- 8.05% covered (danger) -
-
-
8.05%
7 / 87
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 18
Api
-
- 26.81% covered (danger) -
-
-
26.81%
115 / 429
-
- 17.07% covered (danger) -
-
-
17.07%
7 / 41
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 10
ArticlesController.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 9
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
Controller.php
n/a
0 / 0
n/a
0 / 0
n/a
0 / 0
FeedsController.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 28
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 8
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
LogsController.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
OnboardingController.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 40
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 9
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
PlatformAccountsController.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 46
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 7
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
PlatformChannelsController.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 53
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 8
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
RoutingController.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 87
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 8
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
SettingsController.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 14
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- -
- - diff --git a/backend/coverage-report-controllers/Http/Middleware/HandleAppearance.php.html b/backend/coverage-report-controllers/Http/Middleware/HandleAppearance.php.html deleted file mode 100644 index ff877d0b..00000000 --- a/backend/coverage-report-controllers/Http/Middleware/HandleAppearance.php.html +++ /dev/null @@ -1,176 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Http/Middleware/HandleAppearance.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
HandleAppearance
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 handle
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Http\Middleware;
4
5use Closure;
6use Illuminate\Http\Request;
7use Illuminate\Support\Facades\View;
8use Symfony\Component\HttpFoundation\Response;
9
10class HandleAppearance
11{
12    /**
13     * Handle an incoming request.
14     *
15     * @param  \Closure(\Illuminate\Http\Request): (\Symfony\Component\HttpFoundation\Response)  $next
16     */
17    public function handle(Request $request, Closure $next): Response
18    {
19        View::share('appearance', $request->cookie('appearance') ?? 'system');
20
21        return $next($request);
22    }
23}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:51:47 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-controllers/Http/Middleware/HandleInertiaRequests.php.html b/backend/coverage-report-controllers/Http/Middleware/HandleInertiaRequests.php.html deleted file mode 100644 index 9c05d29a..00000000 --- a/backend/coverage-report-controllers/Http/Middleware/HandleInertiaRequests.php.html +++ /dev/null @@ -1,217 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Http/Middleware/HandleInertiaRequests.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 4
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
HandleInertiaRequests
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 4
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
6
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 version
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 share
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Http\Middleware;
4
5use Illuminate\Http\Request;
6use Inertia\Middleware;
7
8class HandleInertiaRequests extends Middleware
9{
10    /**
11     * The root template that's loaded on the first page visit.
12     *
13     * @see https://inertiajs.com/server-side-setup#root-template
14     *
15     * @var string
16     */
17    protected $rootView = 'app';
18
19    /**
20     * Determines the current asset version.
21     *
22     * @see https://inertiajs.com/asset-versioning
23     */
24    public function version(Request $request): ?string
25    {
26        return parent::version($request);
27    }
28
29    /**
30     * Define the props that are shared by default.
31     *
32     * @see https://inertiajs.com/shared-data
33     *
34     * @return array<string, mixed>
35     */
36    public function share(Request $request): array
37    {
38        return array_merge(parent::share($request), [
39            //
40        ]);
41    }
42}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:51:47 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-controllers/Http/Middleware/dashboard.html b/backend/coverage-report-controllers/Http/Middleware/dashboard.html deleted file mode 100644 index 9ea12354..00000000 --- a/backend/coverage-report-controllers/Http/Middleware/dashboard.html +++ /dev/null @@ -1,290 +0,0 @@ - - - - - Dashboard for /var/www/html/backend/app/Http/Middleware - - - - - - - -
-
-
-
- -
-
-
-
-
-
-
-

Classes

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
-
-
-

Insufficient Coverage

- -
-
-

Project Risks

-
- - - - - - - - - - -
ClassCRAP
-
-
-
-
-
-

Methods

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
-
-
-

Insufficient Coverage

-
- - - - - - - - - - - - - -
MethodCoverage
handle0%
version0%
share0%
-
-
-
-

Project Risks

-
- - - - - - - - - - -
MethodCRAP
-
-
-
- -
- - - - - - diff --git a/backend/coverage-report-controllers/Http/Middleware/index.html b/backend/coverage-report-controllers/Http/Middleware/index.html deleted file mode 100644 index 30a5e167..00000000 --- a/backend/coverage-report-controllers/Http/Middleware/index.html +++ /dev/null @@ -1,148 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Http/Middleware - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 6
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
HandleAppearance.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
HandleInertiaRequests.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 4
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- -
- - diff --git a/backend/coverage-report-controllers/Http/Requests/StoreFeedRequest.php.html b/backend/coverage-report-controllers/Http/Requests/StoreFeedRequest.php.html deleted file mode 100644 index 4ead82b3..00000000 --- a/backend/coverage-report-controllers/Http/Requests/StoreFeedRequest.php.html +++ /dev/null @@ -1,203 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Http/Requests/StoreFeedRequest.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 100.00% covered (success) -
-
-
100.00%
9 / 9
-
- 100.00% covered (success) -
-
-
100.00%
2 / 2
CRAP
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
StoreFeedRequest
-
- 100.00% covered (success) -
-
-
100.00%
9 / 9
-
- 100.00% covered (success) -
-
-
100.00%
2 / 2
2
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
 authorize
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
1
 rules
-
- 100.00% covered (success) -
-
-
100.00%
8 / 8
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
1
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Http\Requests;
4
5use Illuminate\Foundation\Http\FormRequest;
6
7class StoreFeedRequest extends FormRequest
8{
9    public function authorize(): bool
10    {
11        return true;
12    }
13
14    /**
15     * @return array<string, string>
16     */
17    public function rules(): array
18    {
19        return [
20            'name' => 'required|string|max:255',
21            'url' => 'required|url|unique:feeds,url',
22            'type' => 'required|in:website,rss',
23            'language_id' => 'required|exists:languages,id',
24            'description' => 'nullable|string',
25            'is_active' => 'boolean'
26        ];
27    }
28}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:51:47 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-controllers/Http/Requests/UpdateFeedRequest.php.html b/backend/coverage-report-controllers/Http/Requests/UpdateFeedRequest.php.html deleted file mode 100644 index cab2b1f3..00000000 --- a/backend/coverage-report-controllers/Http/Requests/UpdateFeedRequest.php.html +++ /dev/null @@ -1,204 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Http/Requests/UpdateFeedRequest.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 100.00% covered (success) -
-
-
100.00%
9 / 9
-
- 100.00% covered (success) -
-
-
100.00%
2 / 2
CRAP
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
UpdateFeedRequest
-
- 100.00% covered (success) -
-
-
100.00%
9 / 9
-
- 100.00% covered (success) -
-
-
100.00%
2 / 2
3
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
 authorize
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
1
 rules
-
- 100.00% covered (success) -
-
-
100.00%
8 / 8
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
2
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Http\Requests;
4
5use App\Models\Feed;
6use Illuminate\Foundation\Http\FormRequest;
7
8class UpdateFeedRequest extends FormRequest
9{
10    public function authorize(): bool
11    {
12        return true;
13    }
14
15    /**
16     * @return array<string, string>
17     */
18    public function rules(): array
19    {
20        return [
21            'name' => 'required|string|max:255',
22            'url' => 'required|url|unique:feeds,url,' . ($this->route('feed') instanceof Feed ? (string)$this->route('feed')->id : (string)$this->route('feed')),
23            'type' => 'required|in:website,rss',
24            'language_id' => 'required|exists:languages,id',
25            'description' => 'nullable|string',
26            'is_active' => 'boolean'
27        ];
28    }
29}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:51:47 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-controllers/Http/Requests/dashboard.html b/backend/coverage-report-controllers/Http/Requests/dashboard.html deleted file mode 100644 index 5eb55f02..00000000 --- a/backend/coverage-report-controllers/Http/Requests/dashboard.html +++ /dev/null @@ -1,285 +0,0 @@ - - - - - Dashboard for /var/www/html/backend/app/Http/Requests - - - - - - - -
-
-
-
- -
-
-
-
-
-
-
-

Classes

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
-
-
-

Insufficient Coverage

-
- - - - - - - - - - -
ClassCoverage
-
-
-
-

Project Risks

-
- - - - - - - - - - -
ClassCRAP
-
-
-
-
-
-

Methods

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
-
-
-

Insufficient Coverage

-
- - - - - - - - - - -
MethodCoverage
-
-
-
-

Project Risks

-
- - - - - - - - - - -
MethodCRAP
-
-
-
- -
- - - - - - diff --git a/backend/coverage-report-controllers/Http/Requests/index.html b/backend/coverage-report-controllers/Http/Requests/index.html deleted file mode 100644 index d0933283..00000000 --- a/backend/coverage-report-controllers/Http/Requests/index.html +++ /dev/null @@ -1,148 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Http/Requests - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 100.00% covered (success) -
-
-
100.00%
18 / 18
-
- 100.00% covered (success) -
-
-
100.00%
4 / 4
-
- 100.00% covered (success) -
-
-
100.00%
2 / 2
StoreFeedRequest.php
-
- 100.00% covered (success) -
-
-
100.00%
9 / 9
-
- 100.00% covered (success) -
-
-
100.00%
2 / 2
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
UpdateFeedRequest.php
-
- 100.00% covered (success) -
-
-
100.00%
9 / 9
-
- 100.00% covered (success) -
-
-
100.00%
2 / 2
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
-
- -
- - diff --git a/backend/coverage-report-controllers/Http/Resources/ArticlePublicationResource.php.html b/backend/coverage-report-controllers/Http/Resources/ArticlePublicationResource.php.html deleted file mode 100644 index 4a190a28..00000000 --- a/backend/coverage-report-controllers/Http/Resources/ArticlePublicationResource.php.html +++ /dev/null @@ -1,179 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Http/Resources/ArticlePublicationResource.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 8
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
ArticlePublicationResource
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 8
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 toArray
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 8
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Http\Resources;
4
5use Illuminate\Http\Request;
6use Illuminate\Http\Resources\Json\JsonResource;
7
8class ArticlePublicationResource extends JsonResource
9{
10    /**
11     * Transform the resource into an array.
12     *
13     * @return array<string, mixed>
14     */
15    public function toArray(Request $request): array
16    {
17        return [
18            'id' => $this->id,
19            'article_id' => $this->article_id,
20            'status' => $this->status,
21            'published_at' => $this->published_at?->toISOString(),
22            'created_at' => $this->created_at->toISOString(),
23            'updated_at' => $this->updated_at->toISOString(),
24        ];
25    }
26}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:51:47 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-controllers/Http/Resources/ArticleResource.php.html b/backend/coverage-report-controllers/Http/Resources/ArticleResource.php.html deleted file mode 100644 index ca8c2969..00000000 --- a/backend/coverage-report-controllers/Http/Resources/ArticleResource.php.html +++ /dev/null @@ -1,189 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Http/Resources/ArticleResource.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 100.00% covered (success) -
-
-
100.00%
18 / 18
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
CRAP
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
ArticleResource
-
- 100.00% covered (success) -
-
-
100.00%
18 / 18
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
1
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
 toArray
-
- 100.00% covered (success) -
-
-
100.00%
18 / 18
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
1
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Http\Resources;
4
5use Illuminate\Http\Request;
6use Illuminate\Http\Resources\Json\JsonResource;
7
8class ArticleResource extends JsonResource
9{
10    /**
11     * Transform the resource into an array.
12     *
13     * @return array<string, mixed>
14     */
15    public function toArray(Request $request): array
16    {
17        return [
18            'id' => $this->id,
19            'feed_id' => $this->feed_id,
20            'url' => $this->url,
21            'title' => $this->title,
22            'description' => $this->description,
23            'is_valid' => $this->is_valid,
24            'is_duplicate' => $this->is_duplicate,
25            'approval_status' => $this->approval_status,
26            'approved_at' => $this->approved_at?->toISOString(),
27            'approved_by' => $this->approved_by,
28            'fetched_at' => $this->fetched_at?->toISOString(),
29            'validated_at' => $this->validated_at?->toISOString(),
30            'created_at' => $this->created_at->toISOString(),
31            'updated_at' => $this->updated_at->toISOString(),
32            'feed' => new FeedResource($this->whenLoaded('feed')),
33            'article_publication' => new ArticlePublicationResource($this->whenLoaded('articlePublication')),
34        ];
35    }
36}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:51:47 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-controllers/Http/Resources/FeedResource.php.html b/backend/coverage-report-controllers/Http/Resources/FeedResource.php.html deleted file mode 100644 index aeca4158..00000000 --- a/backend/coverage-report-controllers/Http/Resources/FeedResource.php.html +++ /dev/null @@ -1,184 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Http/Resources/FeedResource.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 100.00% covered (success) -
-
-
100.00%
13 / 13
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
CRAP
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
FeedResource
-
- 100.00% covered (success) -
-
-
100.00%
13 / 13
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
1
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
 toArray
-
- 100.00% covered (success) -
-
-
100.00%
13 / 13
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
1
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Http\Resources;
4
5use Illuminate\Http\Request;
6use Illuminate\Http\Resources\Json\JsonResource;
7
8class FeedResource extends JsonResource
9{
10    /**
11     * Transform the resource into an array.
12     *
13     * @return array<string, mixed>
14     */
15    public function toArray(Request $request): array
16    {
17        return [
18            'id' => $this->id,
19            'name' => $this->name,
20            'url' => $this->url,
21            'type' => $this->type,
22            'is_active' => $this->is_active,
23            'description' => $this->description,
24            'created_at' => $this->created_at->toISOString(),
25            'updated_at' => $this->updated_at->toISOString(),
26            'articles_count' => $this->when($request->routeIs('api.feeds.*'), function () {
27                return $this->articles()->count();
28            }),
29        ];
30    }
31}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:51:47 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-controllers/Http/Resources/PlatformAccountResource.php.html b/backend/coverage-report-controllers/Http/Resources/PlatformAccountResource.php.html deleted file mode 100644 index 451fd8d0..00000000 --- a/backend/coverage-report-controllers/Http/Resources/PlatformAccountResource.php.html +++ /dev/null @@ -1,184 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Http/Resources/PlatformAccountResource.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 13
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
PlatformAccountResource
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 13
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 toArray
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 13
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Http\Resources;
4
5use Illuminate\Http\Request;
6use Illuminate\Http\Resources\Json\JsonResource;
7
8class PlatformAccountResource extends JsonResource
9{
10    /**
11     * Transform the resource into an array.
12     *
13     * @return array<string, mixed>
14     */
15    public function toArray(Request $request): array
16    {
17        return [
18            'id' => $this->id,
19            'platform_instance_id' => $this->platform_instance_id,
20            'account_id' => $this->account_id,
21            'username' => $this->username,
22            'display_name' => $this->display_name,
23            'description' => $this->description,
24            'is_active' => $this->is_active,
25            'created_at' => $this->created_at->toISOString(),
26            'updated_at' => $this->updated_at->toISOString(),
27            'platform_instance' => new PlatformInstanceResource($this->whenLoaded('platformInstance')),
28            'channels' => PlatformChannelResource::collection($this->whenLoaded('channels')),
29        ];
30    }
31}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:51:47 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-controllers/Http/Resources/PlatformChannelResource.php.html b/backend/coverage-report-controllers/Http/Resources/PlatformChannelResource.php.html deleted file mode 100644 index a2c88eb0..00000000 --- a/backend/coverage-report-controllers/Http/Resources/PlatformChannelResource.php.html +++ /dev/null @@ -1,184 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Http/Resources/PlatformChannelResource.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 13
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
PlatformChannelResource
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 13
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 toArray
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 13
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Http\Resources;
4
5use Illuminate\Http\Request;
6use Illuminate\Http\Resources\Json\JsonResource;
7
8class PlatformChannelResource extends JsonResource
9{
10    /**
11     * Transform the resource into an array.
12     *
13     * @return array<string, mixed>
14     */
15    public function toArray(Request $request): array
16    {
17        return [
18            'id' => $this->id,
19            'platform_instance_id' => $this->platform_instance_id,
20            'channel_id' => $this->channel_id,
21            'name' => $this->name,
22            'display_name' => $this->display_name,
23            'description' => $this->description,
24            'is_active' => $this->is_active,
25            'created_at' => $this->created_at->toISOString(),
26            'updated_at' => $this->updated_at->toISOString(),
27            'platform_instance' => new PlatformInstanceResource($this->whenLoaded('platformInstance')),
28            'routes' => RouteResource::collection($this->whenLoaded('routes')),
29        ];
30    }
31}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:51:47 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-controllers/Http/Resources/PlatformInstanceResource.php.html b/backend/coverage-report-controllers/Http/Resources/PlatformInstanceResource.php.html deleted file mode 100644 index c882e6cb..00000000 --- a/backend/coverage-report-controllers/Http/Resources/PlatformInstanceResource.php.html +++ /dev/null @@ -1,180 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Http/Resources/PlatformInstanceResource.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 9
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
PlatformInstanceResource
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 9
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 toArray
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 9
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Http\Resources;
4
5use Illuminate\Http\Request;
6use Illuminate\Http\Resources\Json\JsonResource;
7
8class PlatformInstanceResource extends JsonResource
9{
10    /**
11     * Transform the resource into an array.
12     *
13     * @return array<string, mixed>
14     */
15    public function toArray(Request $request): array
16    {
17        return [
18            'id' => $this->id,
19            'name' => $this->name,
20            'url' => $this->url,
21            'description' => $this->description,
22            'is_active' => $this->is_active,
23            'created_at' => $this->created_at->toISOString(),
24            'updated_at' => $this->updated_at->toISOString(),
25        ];
26    }
27}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:51:47 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-controllers/Http/Resources/RouteResource.php.html b/backend/coverage-report-controllers/Http/Resources/RouteResource.php.html deleted file mode 100644 index 351e3b79..00000000 --- a/backend/coverage-report-controllers/Http/Resources/RouteResource.php.html +++ /dev/null @@ -1,182 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Http/Resources/RouteResource.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 11
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
RouteResource
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 11
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 toArray
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 11
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Http\Resources;
4
5use Illuminate\Http\Request;
6use Illuminate\Http\Resources\Json\JsonResource;
7
8class RouteResource extends JsonResource
9{
10    /**
11     * Transform the resource into an array.
12     *
13     * @return array<string, mixed>
14     */
15    public function toArray(Request $request): array
16    {
17        return [
18            'id' => $this->id,
19            'feed_id' => $this->feed_id,
20            'platform_channel_id' => $this->platform_channel_id,
21            'is_active' => $this->is_active,
22            'priority' => $this->priority,
23            'created_at' => $this->created_at->toISOString(),
24            'updated_at' => $this->updated_at->toISOString(),
25            'feed' => new FeedResource($this->whenLoaded('feed')),
26            'platform_channel' => new PlatformChannelResource($this->whenLoaded('platformChannel')),
27        ];
28    }
29}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:51:47 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-controllers/Http/Resources/dashboard.html b/backend/coverage-report-controllers/Http/Resources/dashboard.html deleted file mode 100644 index 32b86c69..00000000 --- a/backend/coverage-report-controllers/Http/Resources/dashboard.html +++ /dev/null @@ -1,295 +0,0 @@ - - - - - Dashboard for /var/www/html/backend/app/Http/Resources - - - - - - - -
-
-
-
- -
-
-
-
-
-
-
-

Classes

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
-
- -
-

Project Risks

-
- - - - - - - - - - -
ClassCRAP
-
-
-
-
-
-

Methods

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
-
-
-

Insufficient Coverage

-
- - - - - - - - - - - - - - - -
MethodCoverage
toArray0%
toArray0%
toArray0%
toArray0%
toArray0%
-
-
-
-

Project Risks

-
- - - - - - - - - - -
MethodCRAP
-
-
-
- -
- - - - - - diff --git a/backend/coverage-report-controllers/Http/Resources/index.html b/backend/coverage-report-controllers/Http/Resources/index.html deleted file mode 100644 index 49f7cbc0..00000000 --- a/backend/coverage-report-controllers/Http/Resources/index.html +++ /dev/null @@ -1,288 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Http/Resources - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 36.47% covered (danger) -
-
-
36.47%
31 / 85
-
- 28.57% covered (danger) -
-
-
28.57%
2 / 7
-
- 28.57% covered (danger) -
-
-
28.57%
2 / 7
ArticlePublicationResource.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 8
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
ArticleResource.php
-
- 100.00% covered (success) -
-
-
100.00%
18 / 18
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
FeedResource.php
-
- 100.00% covered (success) -
-
-
100.00%
13 / 13
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
PlatformAccountResource.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 13
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
PlatformChannelResource.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 13
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
PlatformInstanceResource.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 9
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
RouteResource.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 11
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- -
- - diff --git a/backend/coverage-report-controllers/Http/dashboard.html b/backend/coverage-report-controllers/Http/dashboard.html deleted file mode 100644 index ff6d03f3..00000000 --- a/backend/coverage-report-controllers/Http/dashboard.html +++ /dev/null @@ -1,453 +0,0 @@ - - - - - Dashboard for /var/www/html/backend/app/Http - - - - - - - -
-
-
-
- -
-
-
-
-
-
-
-

Classes

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
-
- - -
-
-
-

Methods

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
-
-
-

Insufficient Coverage

-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
MethodCoverage
login0%
register0%
logout0%
me0%
sendNotFound0%
sendUnauthorized0%
index0%
index0%
store0%
show0%
update0%
destroy0%
setActive0%
index0%
store0%
show0%
update0%
destroy0%
toggle0%
index0%
store0%
show0%
update0%
destroy0%
toggle0%
__invoke0%
approve0%
reject0%
index0%
create0%
store0%
show0%
edit0%
update0%
destroy0%
toggle0%
__invoke0%
index0%
platform0%
feed0%
channel0%
complete0%
needsOnboarding0%
hasPlatformAccount0%
hasFeed0%
hasChannel0%
index0%
create0%
store0%
edit0%
update0%
destroy0%
setActive0%
index0%
create0%
store0%
show0%
edit0%
update0%
destroy0%
toggle0%
index0%
create0%
store0%
edit0%
update0%
destroy0%
toggle0%
parseJsonFilters0%
index0%
update0%
handle0%
version0%
share0%
toArray0%
toArray0%
toArray0%
toArray0%
toArray0%
update63%
store66%
approve71%
reject71%
destroy71%
index71%
toggle77%
stats83%
-
-
-
-

Project Risks

-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
MethodCRAP
login30
complete30
store20
update20
update20
toggle20
channel20
register12
index12
store12
update12
toggle12
store12
destroy12
feed12
needsOnboarding12
store12
store12
toggle12
parseJsonFilters12
logout6
destroy6
setActive6
destroy6
show6
toggle6
index6
platform6
update6
store6
toggle6
edit6
update6
update3
store3
toggle3
approve2
reject2
destroy2
index2
stats2
-
-
-
- -
- - - - - - diff --git a/backend/coverage-report-controllers/Http/index.html b/backend/coverage-report-controllers/Http/index.html deleted file mode 100644 index 78050f73..00000000 --- a/backend/coverage-report-controllers/Http/index.html +++ /dev/null @@ -1,203 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Http - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 20.07% covered (danger) -
-
-
20.07%
164 / 817
-
- 12.87% covered (danger) -
-
-
12.87%
13 / 101
-
- 13.79% covered (danger) -
-
-
13.79%
4 / 29
Controllers
-
- 16.24% covered (danger) -
-
-
16.24%
115 / 708
-
- 8.05% covered (danger) -
-
-
8.05%
7 / 87
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 18
Middleware
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 6
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
Requests
-
- 100.00% covered (success) -
-
-
100.00%
18 / 18
-
- 100.00% covered (success) -
-
-
100.00%
4 / 4
-
- 100.00% covered (success) -
-
-
100.00%
2 / 2
Resources
-
- 36.47% covered (danger) -
-
-
36.47%
31 / 85
-
- 28.57% covered (danger) -
-
-
28.57%
2 / 7
-
- 28.57% covered (danger) -
-
-
28.57%
2 / 7
-
- -
- - diff --git a/backend/coverage-report-controllers/Jobs/ArticleDiscoveryForFeedJob.php.html b/backend/coverage-report-controllers/Jobs/ArticleDiscoveryForFeedJob.php.html deleted file mode 100644 index c95ace0c..00000000 --- a/backend/coverage-report-controllers/Jobs/ArticleDiscoveryForFeedJob.php.html +++ /dev/null @@ -1,257 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Jobs/ArticleDiscoveryForFeedJob.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 26
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
ArticleDiscoveryForFeedJob
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 26
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
12
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 __construct
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 handle
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 12
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 dispatchForAllActiveFeeds
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 13
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Jobs;
4
5use App\Models\Feed;
6use App\Services\Article\ArticleFetcher;
7use App\Services\Log\LogSaver;
8use Illuminate\Contracts\Queue\ShouldQueue;
9use Illuminate\Foundation\Queue\Queueable;
10
11class ArticleDiscoveryForFeedJob implements ShouldQueue
12{
13    use Queueable;
14
15    private const FEED_DISCOVERY_DELAY_MINUTES = 5;
16
17    public function __construct(
18        private readonly Feed $feed
19    ) {
20        $this->onQueue('feed-discovery');
21    }
22
23    public function handle(): void
24    {
25        LogSaver::info('Starting feed article fetch', null, [
26            'feed_id' => $this->feed->id,
27            'feed_name' => $this->feed->name,
28            'feed_url' => $this->feed->url
29        ]);
30
31        $articles = ArticleFetcher::getArticlesFromFeed($this->feed);
32
33        LogSaver::info('Feed article fetch completed', null, [
34            'feed_id' => $this->feed->id,
35            'feed_name' => $this->feed->name,
36            'articles_count' => $articles->count()
37        ]);
38
39        $this->feed->update(['last_fetched_at' => now()]);
40    }
41
42    public static function dispatchForAllActiveFeeds(): void
43    {
44        Feed::where('is_active', true)
45            ->get()
46            ->each(function (Feed $feed, $index) {
47                // Space jobs apart to avoid overwhelming feeds
48                $delayMinutes = $index * self::FEED_DISCOVERY_DELAY_MINUTES;
49
50                self::dispatch($feed)
51                    ->delay(now()->addMinutes($delayMinutes))
52                    ->onQueue('feed-discovery');
53
54                LogSaver::info('Dispatched feed discovery job', null, [
55                    'feed_id' => $feed->id,
56                    'feed_name' => $feed->name,
57                    'delay_minutes' => $delayMinutes
58                ]);
59            });
60    }
61}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:51:47 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-controllers/Jobs/ArticleDiscoveryJob.php.html b/backend/coverage-report-controllers/Jobs/ArticleDiscoveryJob.php.html deleted file mode 100644 index 8261e59f..00000000 --- a/backend/coverage-report-controllers/Jobs/ArticleDiscoveryJob.php.html +++ /dev/null @@ -1,207 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Jobs/ArticleDiscoveryJob.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 7
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
ArticleDiscoveryJob
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 7
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
12
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 __construct
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 handle
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 6
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
6
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Jobs;
4
5use App\Models\Setting;
6use App\Services\Log\LogSaver;
7use Illuminate\Contracts\Queue\ShouldQueue;
8use Illuminate\Foundation\Queue\Queueable;
9
10class ArticleDiscoveryJob implements ShouldQueue
11{
12    use Queueable;
13
14    public function __construct()
15    {
16        $this->onQueue('feed-discovery');
17    }
18
19    public function handle(): void
20    {
21        if (!Setting::isArticleProcessingEnabled()) {
22            LogSaver::info('Article processing is disabled. Article discovery skipped.');
23
24            return;
25        }
26
27        LogSaver::info('Starting article discovery for all active feeds');
28
29        ArticleDiscoveryForFeedJob::dispatchForAllActiveFeeds();
30
31        LogSaver::info('Article discovery jobs dispatched for all active feeds');
32    }
33}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:51:47 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-controllers/Jobs/PublishToLemmyJob.php.html b/backend/coverage-report-controllers/Jobs/PublishToLemmyJob.php.html deleted file mode 100644 index 7b92ebd1..00000000 --- a/backend/coverage-report-controllers/Jobs/PublishToLemmyJob.php.html +++ /dev/null @@ -1,212 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Jobs/PublishToLemmyJob.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 6
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
PublishToLemmyJob
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 6
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
12
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 __construct
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 handle
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 5
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
6
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Jobs;
4
5use App\Exceptions\PublishException;
6use App\Models\Article;
7use App\Services\Article\ArticleFetcher;
8use App\Services\Publishing\ArticlePublishingService;
9use Illuminate\Contracts\Queue\ShouldQueue;
10use Illuminate\Foundation\Queue\Queueable;
11
12class PublishToLemmyJob implements ShouldQueue
13{
14    use Queueable;
15
16    public int $tries = 3;
17    public array $backoff = [60, 120, 300];
18
19    public function __construct(
20        private readonly Article $article
21    ) {
22        $this->onQueue('lemmy-posts');
23    }
24
25    public function handle(): void
26    {
27        $extractedData = ArticleFetcher::fetchArticleData($this->article);
28
29        /** @var ArticlePublishingService $publishingService */
30        $publishingService = resolve(ArticlePublishingService::class);
31
32        try {
33            $publishingService->publishToRoutedChannels($this->article, $extractedData);
34        } catch (PublishException $e) {
35            $this->fail($e);
36        }
37    }
38}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:51:47 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-controllers/Jobs/SyncChannelPostsJob.php.html b/backend/coverage-report-controllers/Jobs/SyncChannelPostsJob.php.html deleted file mode 100644 index e0c9c05a..00000000 --- a/backend/coverage-report-controllers/Jobs/SyncChannelPostsJob.php.html +++ /dev/null @@ -1,352 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Jobs/SyncChannelPostsJob.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 42
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 5
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
SyncChannelPostsJob
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 42
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 5
182
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 __construct
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 dispatchForAllActiveChannels
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 9
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 handle
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 5
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
6
 syncLemmyChannelPosts
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 16
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
20
 getAuthToken
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 11
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
30
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Jobs;
4
5use App\Enums\PlatformEnum;
6use App\Exceptions\PlatformAuthException;
7use App\Models\PlatformAccount;
8use App\Models\PlatformChannel;
9use App\Modules\Lemmy\Services\LemmyApiService;
10use App\Services\Log\LogSaver;
11use Exception;
12use Illuminate\Contracts\Queue\ShouldBeUnique;
13use Illuminate\Contracts\Queue\ShouldQueue;
14use Illuminate\Database\Eloquent\Collection;
15use Illuminate\Foundation\Queue\Queueable;
16use Illuminate\Support\Facades\Cache;
17
18class SyncChannelPostsJob implements ShouldQueue, ShouldBeUnique
19{
20    use Queueable;
21
22    public function __construct(
23        private readonly PlatformChannel $channel
24    ) {
25        $this->onQueue('sync');
26    }
27
28    public static function dispatchForAllActiveChannels(): void
29    {
30        PlatformChannel::with(['platformInstance', 'platformAccounts'])
31            ->whereHas('platformInstance', fn ($query) => $query->where('platform', PlatformEnum::LEMMY))
32            ->whereHas('platformAccounts', fn ($query) => $query->where('is_active', true))
33            ->where('is_active', true)
34            ->get()
35            ->each(function (PlatformChannel $channel) {
36                self::dispatch($channel);
37                LogSaver::info('Dispatched sync job for channel', $channel);
38            });
39    }
40
41    public function handle(): void
42    {
43        LogSaver::info('Starting channel posts sync job', $this->channel);
44
45        match ($this->channel->platformInstance->platform) {
46            PlatformEnum::LEMMY => $this->syncLemmyChannelPosts(),
47        };
48
49        LogSaver::info('Channel posts sync job completed', $this->channel);
50    }
51
52    /**
53     * @throws PlatformAuthException
54     */
55    private function syncLemmyChannelPosts(): void
56    {
57        try {
58            /** @var Collection<int, PlatformAccount> $accounts */
59            $accounts = $this->channel->activePlatformAccounts()->get();
60            $account = $accounts->first();
61
62            if (! $account) {
63                throw new PlatformAuthException(PlatformEnum::LEMMY, 'No active account found for channel');
64            }
65
66            $api = new LemmyApiService($this->channel->platformInstance->url);
67            $token = $this->getAuthToken($api, $account);
68
69            $platformChannelId = $this->channel->channel_id
70                ? $this->channel->channel_id
71                : $api->getCommunityId($this->channel->name, $token);
72
73            $api->syncChannelPosts($token, $platformChannelId, $this->channel->name);
74
75            LogSaver::info('Channel posts synced successfully', $this->channel);
76
77        } catch (Exception $e) {
78            LogSaver::error('Failed to sync channel posts', $this->channel, [
79                'error' => $e->getMessage()
80            ]);
81
82            throw $e;
83        }
84    }
85
86    /**
87     * @throws PlatformAuthException
88     */
89    private function getAuthToken(LemmyApiService $api, PlatformAccount $account): string
90    {
91        $cacheKey = "lemmy_jwt_token_{$account->id}";
92        $cachedToken = Cache::get($cacheKey);
93
94        if ($cachedToken) {
95            return $cachedToken;
96        }
97
98        if (!$account->username || !$account->password) {
99            throw new PlatformAuthException(PlatformEnum::LEMMY, 'Missing credentials for account');
100        }
101
102        $token = $api->login($account->username, $account->password);
103
104        if (!$token) {
105            throw new PlatformAuthException(PlatformEnum::LEMMY, 'Login failed for account');
106        }
107
108        Cache::put($cacheKey, $token, 3600);
109
110        return $token;
111    }
112}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:51:47 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-controllers/Jobs/dashboard.html b/backend/coverage-report-controllers/Jobs/dashboard.html deleted file mode 100644 index 0d762640..00000000 --- a/backend/coverage-report-controllers/Jobs/dashboard.html +++ /dev/null @@ -1,308 +0,0 @@ - - - - - Dashboard for /var/www/html/backend/app/Jobs - - - - - - - -
-
-
-
- -
-
-
-
-
-
-
-

Classes

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
-
-
-

Insufficient Coverage

- -
-
-

Project Risks

- -
-
-
-
-

Methods

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
-
-
-

Insufficient Coverage

- -
-
-

Project Risks

-
- - - - - - - - - - - - - - - -
MethodCRAP
getAuthToken30
syncLemmyChannelPosts20
handle6
handle6
handle6
-
-
-
- -
- - - - - - diff --git a/backend/coverage-report-controllers/Jobs/index.html b/backend/coverage-report-controllers/Jobs/index.html deleted file mode 100644 index 6c05a0d4..00000000 --- a/backend/coverage-report-controllers/Jobs/index.html +++ /dev/null @@ -1,203 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Jobs - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 81
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 12
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 4
ArticleDiscoveryForFeedJob.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 26
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
ArticleDiscoveryJob.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 7
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
PublishToLemmyJob.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 6
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
SyncChannelPostsJob.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 42
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 5
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- -
- - diff --git a/backend/coverage-report-controllers/Listeners/LogExceptionToDatabase.php.html b/backend/coverage-report-controllers/Listeners/LogExceptionToDatabase.php.html deleted file mode 100644 index 95c146d6..00000000 --- a/backend/coverage-report-controllers/Listeners/LogExceptionToDatabase.php.html +++ /dev/null @@ -1,179 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Listeners/LogExceptionToDatabase.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 12
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
LogExceptionToDatabase
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 12
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 handle
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 12
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Listeners;
4
5use App\Events\ExceptionLogged;
6use App\Events\ExceptionOccurred;
7use App\Models\Log;
8class LogExceptionToDatabase
9{
10
11    public function handle(ExceptionOccurred $event): void
12    {
13        $log = Log::create([
14            'level' => $event->level,
15            'message' => $event->message,
16            'context' => [
17                'exception_class' => get_class($event->exception),
18                'file' => $event->exception->getFile(),
19                'line' => $event->exception->getLine(),
20                'trace' => $event->exception->getTraceAsString(),
21                ...$event->context
22            ]
23        ]);
24
25        ExceptionLogged::dispatch($log);
26    }
27}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:51:47 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-controllers/Listeners/PublishApprovedArticle.php.html b/backend/coverage-report-controllers/Listeners/PublishApprovedArticle.php.html deleted file mode 100644 index 1d095f43..00000000 --- a/backend/coverage-report-controllers/Listeners/PublishApprovedArticle.php.html +++ /dev/null @@ -1,179 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Listeners/PublishApprovedArticle.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 5
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
PublishApprovedArticle
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 5
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
20
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 handle
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 5
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
20
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Listeners;
4
5use App\Events\ArticleApproved;
6use App\Events\ArticleReadyToPublish;
7use Illuminate\Contracts\Queue\ShouldQueue;
8
9class PublishApprovedArticle implements ShouldQueue
10{
11    public string $queue = 'default';
12
13    public function handle(ArticleApproved $event): void
14    {
15        $article = $event->article;
16
17        // Skip if already has publication (prevents duplicate processing)
18        if ($article->articlePublication()->exists()) {
19            return;
20        }
21
22        // Only publish if the article is valid and approved
23        if ($article->isValid() && $article->isApproved()) {
24            event(new ArticleReadyToPublish($article));
25        }
26    }
27}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:51:47 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-controllers/Listeners/PublishArticle.php.html b/backend/coverage-report-controllers/Listeners/PublishArticle.php.html deleted file mode 100644 index a288fed9..00000000 --- a/backend/coverage-report-controllers/Listeners/PublishArticle.php.html +++ /dev/null @@ -1,213 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Listeners/PublishArticle.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 13
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
PublishArticle
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 13
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
12
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 __construct
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 handle
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 12
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
6
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Listeners;
4
5use App\Events\ArticleReadyToPublish;
6use App\Jobs\PublishToLemmyJob;
7use Illuminate\Contracts\Queue\ShouldQueue;
8
9class PublishArticle implements ShouldQueue
10{
11    public string|null $queue = 'lemmy-publish';
12    public int $delay = 300;
13    public int $tries = 3;
14    public int $backoff = 300;
15
16    public function __construct()
17    {}
18
19    public function handle(ArticleReadyToPublish $event): void
20    {
21        $article = $event->article;
22
23        if ($article->articlePublication()->exists()) {
24            logger()->info('Article already published, skipping job dispatch', [
25                'article_id' => $article->id,
26                'url' => $article->url
27            ]);
28
29            return;
30        }
31
32        logger()->info('Article queued for publishing to Lemmy', [
33            'article_id' => $article->id,
34            'url' => $article->url
35        ]);
36
37        PublishToLemmyJob::dispatch($article);
38    }
39}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:51:47 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-controllers/Listeners/ValidateArticleListener.php.html b/backend/coverage-report-controllers/Listeners/ValidateArticleListener.php.html deleted file mode 100644 index 911498e7..00000000 --- a/backend/coverage-report-controllers/Listeners/ValidateArticleListener.php.html +++ /dev/null @@ -1,201 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Listeners/ValidateArticleListener.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 13
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
ValidateArticleListener
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 13
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
56
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 handle
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 13
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
56
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Listeners;
4
5use App\Events\NewArticleFetched;
6use App\Events\ArticleReadyToPublish;
7use App\Models\Setting;
8use App\Services\Article\ValidationService;
9use Illuminate\Contracts\Queue\ShouldQueue;
10
11class ValidateArticleListener implements ShouldQueue
12{
13    public string $queue = 'default';
14
15    public function handle(NewArticleFetched $event): void
16    {
17        $article = $event->article;
18
19        if (! is_null($article->validated_at)) {
20            return;
21        }
22
23        // Skip if already has publication (prevents duplicate processing)
24        if ($article->articlePublication()->exists()) {
25            return;
26        }
27
28        $article = ValidationService::validate($article);
29
30        if ($article->isValid()) {
31            // Double-check publication doesn't exist (race condition protection)
32            if ($article->articlePublication()->exists()) {
33                return;
34            }
35
36            // Check if approval system is enabled
37            if (Setting::isPublishingApprovalsEnabled()) {
38                // If approvals are enabled, only proceed if article is approved
39                if ($article->isApproved()) {
40                    event(new ArticleReadyToPublish($article));
41                }
42                // If not approved, article will wait for manual approval
43            } else {
44                // If approvals are disabled, proceed with publishing
45                event(new ArticleReadyToPublish($article));
46            }
47        }
48    }
49}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:51:47 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-controllers/Listeners/dashboard.html b/backend/coverage-report-controllers/Listeners/dashboard.html deleted file mode 100644 index eae29672..00000000 --- a/backend/coverage-report-controllers/Listeners/dashboard.html +++ /dev/null @@ -1,299 +0,0 @@ - - - - - Dashboard for /var/www/html/backend/app/Listeners - - - - - - - -
-
-
-
- -
-
-
-
-
-
-
-

Classes

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
- -
-
-

Methods

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
-
-
-

Insufficient Coverage

-
- - - - - - - - - - - - - - - -
MethodCoverage
handle0%
handle0%
__construct0%
handle0%
handle0%
-
-
-
-

Project Risks

-
- - - - - - - - - - - - - -
MethodCRAP
handle56
handle20
handle6
-
-
-
- -
- - - - - - diff --git a/backend/coverage-report-controllers/Listeners/index.html b/backend/coverage-report-controllers/Listeners/index.html deleted file mode 100644 index a6814a01..00000000 --- a/backend/coverage-report-controllers/Listeners/index.html +++ /dev/null @@ -1,203 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Listeners - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 43
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 5
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 4
LogExceptionToDatabase.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 12
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
PublishApprovedArticle.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 5
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
PublishArticle.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 13
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
ValidateArticleListener.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 13
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- -
- - diff --git a/backend/coverage-report-controllers/LogLevelEnum.php.html b/backend/coverage-report-controllers/LogLevelEnum.php.html deleted file mode 100644 index a32ecd0a..00000000 --- a/backend/coverage-report-controllers/LogLevelEnum.php.html +++ /dev/null @@ -1,177 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/LogLevelEnum.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 100.00% covered (success) -
-
-
100.00%
7 / 7
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
CRAP
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
LogLevelEnum
-
- 100.00% covered (success) -
-
-
100.00%
7 / 7
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
1
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
 toArray
-
- 100.00% covered (success) -
-
-
100.00%
7 / 7
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
1
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App;
4
5enum LogLevelEnum: string
6{
7    case DEBUG = 'debug';
8    case INFO = 'info';
9    case WARNING = 'warning';
10    case ERROR = 'error';
11    case CRITICAL = 'critical';
12
13    /**
14     * @return array<int, string>
15     */
16    public static function toArray(): array
17    {
18        return [
19            self::DEBUG->value,
20            self::INFO->value,
21            self::WARNING->value,
22            self::ERROR->value,
23            self::CRITICAL->value,
24        ];
25    }
26}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:51:47 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-controllers/Models/Article.php.html b/backend/coverage-report-controllers/Models/Article.php.html deleted file mode 100644 index fdbfe53c..00000000 --- a/backend/coverage-report-controllers/Models/Article.php.html +++ /dev/null @@ -1,522 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Models/Article.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 66.67% covered (warning) -
-
-
66.67%
26 / 39
-
- 54.55% covered (warning) -
-
-
54.55%
6 / 11
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
Article
-
- 66.67% covered (warning) -
-
-
66.67%
26 / 39
-
- 54.55% covered (warning) -
-
-
54.55%
6 / 11
23.33
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 casts
-
- 100.00% covered (success) -
-
-
100.00%
10 / 10
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
1
 isValid
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 5
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
12
 isApproved
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 isPending
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 isRejected
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 approve
-
- 100.00% covered (success) -
-
-
100.00%
6 / 6
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
1
 reject
-
- 100.00% covered (success) -
-
-
100.00%
5 / 5
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
1
 canBePublished
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 5
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
12
 articlePublication
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
1
 feed
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
1
 booted
-
- 100.00% covered (success) -
-
-
100.00%
3 / 3
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
1
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Models;
4
5use App\Events\ArticleApproved;
6use App\Events\NewArticleFetched;
7use Database\Factories\ArticleFactory;
8use Illuminate\Database\Eloquent\Factories\HasFactory;
9use Illuminate\Database\Eloquent\Model;
10use Illuminate\Database\Eloquent\Relations\BelongsTo;
11use Illuminate\Database\Eloquent\Relations\HasOne;
12use Illuminate\Support\Carbon;
13
14/**
15 * @method static firstOrCreate(array<string, mixed> $array)
16 * @method static where(string $string, string $url)
17 * @method static create(array<string, mixed> $array)
18 * @property integer $id
19 * @property int $feed_id
20 * @property Feed $feed
21 * @property string $url
22 * @property bool|null $is_valid
23 * @property Carbon|null $validated_at
24 * @property Carbon $created_at
25 * @property Carbon $updated_at
26 * @property ArticlePublication $articlePublication
27 */
28class Article extends Model
29{
30    /** @use HasFactory<ArticleFactory> */
31    use HasFactory;
32
33    protected $fillable = [
34        'feed_id',
35        'url',
36        'title',
37        'description',
38        'is_valid',
39        'is_duplicate',
40        'approval_status',
41        'approved_at',
42        'approved_by',
43        'fetched_at',
44        'validated_at',
45    ];
46
47    /**
48     * @return array<string, string>
49     */
50    public function casts(): array
51    {
52        return [
53            'is_valid' => 'boolean',
54            'is_duplicate' => 'boolean',
55            'approval_status' => 'string',
56            'approved_at' => 'datetime',
57            'fetched_at' => 'datetime',
58            'validated_at' => 'datetime',
59            'created_at' => 'datetime',
60            'updated_at' => 'datetime',
61        ];
62    }
63
64    public function isValid(): bool
65    {
66        if (is_null($this->validated_at)) {
67            return false;
68        }
69
70        if (is_null($this->is_valid)) {
71            return false;
72        }
73
74        return $this->is_valid;
75    }
76
77    public function isApproved(): bool
78    {
79        return $this->approval_status === 'approved';
80    }
81
82    public function isPending(): bool
83    {
84        return $this->approval_status === 'pending';
85    }
86
87    public function isRejected(): bool
88    {
89        return $this->approval_status === 'rejected';
90    }
91
92    public function approve(string $approvedBy = null): void
93    {
94        $this->update([
95            'approval_status' => 'approved',
96            'approved_at' => now(),
97            'approved_by' => $approvedBy,
98        ]);
99
100        // Fire event to trigger publishing
101        event(new ArticleApproved($this));
102    }
103
104    public function reject(string $rejectedBy = null): void
105    {
106        $this->update([
107            'approval_status' => 'rejected',
108            'approved_at' => now(),
109            'approved_by' => $rejectedBy,
110        ]);
111    }
112
113    public function canBePublished(): bool
114    {
115        if (!$this->isValid()) {
116            return false;
117        }
118
119        // If approval system is disabled, auto-approve valid articles
120        if (!\App\Models\Setting::isPublishingApprovalsEnabled()) {
121            return true;
122        }
123
124        // If approval system is enabled, only approved articles can be published
125        return $this->isApproved();
126    }
127
128    /**
129     * @return HasOne<ArticlePublication, $this>
130     */
131    public function articlePublication(): HasOne
132    {
133        return $this->hasOne(ArticlePublication::class);
134    }
135
136    /**
137     * @return BelongsTo<Feed, $this>
138     */
139    public function feed(): BelongsTo
140    {
141        return $this->belongsTo(Feed::class);
142    }
143
144    protected static function booted(): void
145    {
146        static::created(function ($article) {
147            event(new NewArticleFetched($article));
148        });
149    }
150}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:51:47 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-controllers/Models/ArticlePublication.php.html b/backend/coverage-report-controllers/Models/ArticlePublication.php.html deleted file mode 100644 index 66684e7b..00000000 --- a/backend/coverage-report-controllers/Models/ArticlePublication.php.html +++ /dev/null @@ -1,196 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Models/ArticlePublication.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
ArticlePublication
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 article
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Models;
4
5use Database\Factories\ArticlePublicationFactory;
6use Illuminate\Database\Eloquent\Factories\HasFactory;
7use Illuminate\Database\Eloquent\Model;
8use Illuminate\Database\Eloquent\Relations\BelongsTo;
9
10/**
11 * @property integer $article_id
12 * @property integer $platform_channel_id
13 * @property integer $post_id
14 *
15 * @method static create(array<string, mixed> $array)
16 */
17class ArticlePublication extends Model
18{
19    /** @use HasFactory<ArticlePublicationFactory> */
20    use HasFactory;
21    
22    protected $fillable = [
23        'article_id',
24        'platform_channel_id',
25        'post_id',
26        'published_at',
27        'published_by',
28        'platform',
29        'publication_data',
30    ];
31
32    protected $casts = [
33        'published_at' => 'datetime',
34        'publication_data' => 'array',
35    ];
36
37    /**
38     * @return BelongsTo<Article, $this>
39     */
40    public function article(): BelongsTo
41    {
42        return $this->belongsTo(Article::class);
43    }
44}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:51:47 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-controllers/Models/Feed.php.html b/backend/coverage-report-controllers/Models/Feed.php.html deleted file mode 100644 index a56803b5..00000000 --- a/backend/coverage-report-controllers/Models/Feed.php.html +++ /dev/null @@ -1,382 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Models/Feed.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 4.17% covered (danger) -
-
-
4.17%
1 / 24
-
- 16.67% covered (danger) -
-
-
16.67%
1 / 6
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
Feed
-
- 4.17% covered (danger) -
-
-
4.17%
1 / 24
-
- 16.67% covered (danger) -
-
-
16.67%
1 / 6
161.74
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 getTypeDisplayAttribute
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 5
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
20
 getStatusAttribute
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 10
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
30
 channels
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 4
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 activeChannels
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 articles
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
1
 language
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Models;
4
5use Database\Factories\FeedFactory;
6use Illuminate\Database\Eloquent\Factories\HasFactory;
7use Illuminate\Database\Eloquent\Model;
8use Illuminate\Database\Eloquent\Relations\BelongsTo;
9use Illuminate\Database\Eloquent\Relations\BelongsToMany;
10use Illuminate\Database\Eloquent\Relations\HasMany;
11use Illuminate\Support\Carbon;
12
13/**
14 * @property int $id
15 * @property string $name
16 * @property string $url
17 * @property string $type
18 * @property int $language_id
19 * @property Language|null $language
20 * @property string $description
21 * @property array<string, mixed> $settings
22 * @property bool $is_active
23 * @property Carbon|null $last_fetched_at
24 * @property Carbon $created_at
25 * @property Carbon $updated_at
26 * @method static orderBy(string $string, string $string1)
27 * @method static where(string $string, true $true)
28 * @method static findOrFail(mixed $feed_id)
29 */
30class Feed extends Model
31{
32    /** @use HasFactory<FeedFactory> */
33    use HasFactory;
34    private const RECENT_FETCH_THRESHOLD_HOURS = 2;
35    private const DAILY_FETCH_THRESHOLD_HOURS = 24;
36
37    protected $fillable = [
38        'name',
39        'url',
40        'type',
41        'language_id',
42        'description',
43        'settings',
44        'is_active',
45        'last_fetched_at'
46    ];
47
48    protected $casts = [
49        'settings' => 'array',
50        'is_active' => 'boolean',
51        'last_fetched_at' => 'datetime'
52    ];
53
54    public function getTypeDisplayAttribute(): string
55    {
56        return match ($this->type) {
57            'website' => 'Website',
58            'rss' => 'RSS Feed',
59            default => 'Unknown'
60        };
61    }
62
63    public function getStatusAttribute(): string
64    {
65        if (!$this->is_active) {
66            return 'Inactive';
67        }
68
69        if (!$this->last_fetched_at) {
70            return 'Never fetched';
71        }
72
73        $hoursAgo = $this->last_fetched_at->diffInHours(now());
74
75        if ($hoursAgo < self::RECENT_FETCH_THRESHOLD_HOURS) {
76            return 'Recently fetched';
77        } elseif ($hoursAgo < self::DAILY_FETCH_THRESHOLD_HOURS) {
78            return "Fetched {$hoursAgo}h ago";
79        } else {
80            return "Fetched " . $this->last_fetched_at->diffForHumans();
81        }
82    }
83
84    /**
85     * @return BelongsToMany<PlatformChannel, $this, Route>
86     */
87    public function channels(): BelongsToMany
88    {
89        return $this->belongsToMany(PlatformChannel::class, 'routes')
90            ->using(Route::class)
91            ->withPivot(['is_active', 'priority', 'filters'])
92            ->withTimestamps();
93    }
94
95    /**
96     * @return BelongsToMany<PlatformChannel, $this, Route>
97     */
98    public function activeChannels(): BelongsToMany
99    {
100        return $this->channels()
101            ->wherePivot('is_active', true)
102            ->orderByPivot('priority', 'desc');
103    }
104
105    /**
106     * @return HasMany<Article, $this>
107     */
108    public function articles(): HasMany
109    {
110        return $this->hasMany(Article::class);
111    }
112
113    /**
114     * @return BelongsTo<Language, $this>
115     */
116    public function language(): BelongsTo
117    {
118        return $this->belongsTo(Language::class);
119    }
120}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:51:47 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-controllers/Models/Keyword.php.html b/backend/coverage-report-controllers/Models/Keyword.php.html deleted file mode 100644 index c910e197..00000000 --- a/backend/coverage-report-controllers/Models/Keyword.php.html +++ /dev/null @@ -1,223 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Models/Keyword.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
Keyword
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
6
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 feed
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 platformChannel
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Models;
4
5use Illuminate\Database\Eloquent\Model;
6use Illuminate\Database\Eloquent\Relations\BelongsTo;
7use Illuminate\Support\Carbon;
8
9/**
10 * @property int $id
11 * @property int $feed_id
12 * @property Feed $feed
13 * @property int $platform_channel_id
14 * @property PlatformChannel $platformChannel
15 * @property string $keyword
16 * @property bool $is_active
17 * @property Carbon $created_at
18 * @property Carbon $updated_at
19 */
20class Keyword extends Model
21{
22    protected $fillable = [
23        'feed_id',
24        'platform_channel_id',
25        'keyword',
26        'is_active'
27    ];
28
29    protected $casts = [
30        'is_active' => 'boolean'
31    ];
32
33    /**
34     * @return BelongsTo<Feed, $this>
35     */
36    public function feed(): BelongsTo
37    {
38        return $this->belongsTo(Feed::class);
39    }
40
41    /**
42     * @return BelongsTo<PlatformChannel, $this>
43     */
44    public function platformChannel(): BelongsTo
45    {
46        return $this->belongsTo(PlatformChannel::class);
47    }
48
49}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:51:47 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-controllers/Models/Language.php.html b/backend/coverage-report-controllers/Models/Language.php.html deleted file mode 100644 index 5935ec19..00000000 --- a/backend/coverage-report-controllers/Models/Language.php.html +++ /dev/null @@ -1,248 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Models/Language.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 5
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
Language
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 5
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
12
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 platformInstances
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 platformChannels
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 feeds
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Models;
4
5use Database\Factories\LanguageFactory;
6use Illuminate\Database\Eloquent\Factories\HasFactory;
7use Illuminate\Database\Eloquent\Model;
8use Illuminate\Database\Eloquent\Relations\BelongsToMany;
9use Illuminate\Database\Eloquent\Relations\HasMany;
10
11class Language extends Model
12{
13    /** @use HasFactory<LanguageFactory> */
14    use HasFactory;
15
16    protected $fillable = [
17        'short_code',
18        'name', 
19        'native_name',
20        'is_active'
21    ];
22
23    protected $casts = [
24        'is_active' => 'boolean'
25    ];
26
27    /**
28     * @return BelongsToMany<PlatformInstance, $this>
29     */
30    public function platformInstances(): BelongsToMany
31    {
32        return $this->belongsToMany(PlatformInstance::class)
33            ->withPivot(['platform_language_id', 'is_default'])
34            ->withTimestamps();
35    }
36
37    /**
38     * @return HasMany<PlatformChannel, $this>
39     */
40    public function platformChannels(): HasMany
41    {
42        return $this->hasMany(PlatformChannel::class);
43    }
44
45    /**
46     * @return HasMany<Feed, $this>
47     */
48    public function feeds(): HasMany
49    {
50        return $this->hasMany(Feed::class);
51    }
52}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:51:47 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-controllers/Models/Log.php.html b/backend/coverage-report-controllers/Models/Log.php.html deleted file mode 100644 index d01f7680..00000000 --- a/backend/coverage-report-controllers/Models/Log.php.html +++ /dev/null @@ -1,136 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Models/Log.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
n/a
0 / 0
n/a
0 / 0
CRAP
n/a
0 / 0
Log
n/a
0 / 0
n/a
0 / 0
0
n/a
0 / 0
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Models;
4
5use App\LogLevelEnum;
6use Illuminate\Database\Eloquent\Factories\HasFactory;
7use Illuminate\Database\Eloquent\Model;
8use Illuminate\Support\Carbon;
9
10/**
11 * @method static create(array<string, mixed> $array)
12 * @property LogLevelEnum $level
13 * @property string $message
14 * @property array<string, mixed> $context
15 * @property Carbon $created_at
16 * @property Carbon $updated_at
17 */
18class Log extends Model
19{
20    use HasFactory;
21    
22    protected $table = 'logs';
23
24    protected $fillable = [
25        'level',
26        'message',
27        'context',
28    ];
29
30    protected $casts = [
31        'level' => LogLevelEnum::class,
32        'context' => 'array',
33        'created_at' => 'datetime',
34        'updated_at' => 'datetime',
35    ];
36}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:51:47 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-controllers/Models/PlatformAccount.php.html b/backend/coverage-report-controllers/Models/PlatformAccount.php.html deleted file mode 100644 index 5f3dd84a..00000000 --- a/backend/coverage-report-controllers/Models/PlatformAccount.php.html +++ /dev/null @@ -1,384 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Models/PlatformAccount.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 21
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 6
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
PlatformAccount
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 21
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 6
110
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 password
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 4
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
12
 apiToken
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 4
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
12
 getActive
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 setAsActive
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 4
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 channels
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 activeChannels
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Models;
4
5use Database\Factories\PlatformAccountFactory;
6use Illuminate\Database\Eloquent\Factories\HasFactory;
7use Illuminate\Database\Eloquent\Model;
8use Illuminate\Database\Eloquent\Casts\Attribute;
9use Illuminate\Database\Eloquent\Collection;
10use Illuminate\Database\Eloquent\Relations\BelongsToMany;
11use Illuminate\Support\Carbon;
12use Illuminate\Support\Facades\Crypt;
13use App\Enums\PlatformEnum;
14
15/**
16 * @property int $id
17 * @property PlatformEnum $platform
18 * @property string $instance_url
19 * @property string $username
20 * @property string $password
21 * @property string $settings
22 * @property bool $is_active
23 * @property Carbon $last_tested_at
24 * @property string $status
25 * @property Carbon $created_at
26 * @property Carbon $updated_at
27 * @property Collection<int, PlatformChannel> $activeChannels
28 * @method static where(string $string, PlatformEnum $platform)
29 * @method static orderBy(string $string)
30 * @method static create(array<string, mixed> $validated)
31 */
32class PlatformAccount extends Model
33{
34    /** @use HasFactory<PlatformAccountFactory> */
35    use HasFactory;
36
37    protected $fillable = [
38        'platform',
39        'instance_url',
40        'username',
41        'password',
42        'api_token',
43        'settings',
44        'is_active',
45        'last_tested_at',
46        'status'
47    ];
48
49    protected $casts = [
50        'platform' => PlatformEnum::class,
51        'settings' => 'array',
52        'is_active' => 'boolean',
53        'last_tested_at' => 'datetime'
54    ];
55
56    // Encrypt password when storing
57    /**
58     * @return Attribute<string|null, string|null>
59     */
60    protected function password(): Attribute
61    {
62        return Attribute::make(
63            get: fn ($value) => $value ? Crypt::decryptString($value) : null,
64            set: fn ($value) => $value ? Crypt::encryptString($value) : null,
65        );
66    }
67
68    // Encrypt API token when storing
69    /**
70     * @return Attribute<string|null, string|null>
71     */
72    protected function apiToken(): Attribute
73    {
74        return Attribute::make(
75            get: fn ($value) => $value ? Crypt::decryptString($value) : null,
76            set: fn ($value) => $value ? Crypt::encryptString($value) : null,
77        );
78    }
79
80    // Get the active accounts for a platform (returns collection)
81    /**
82     * @return Collection<int, PlatformAccount>
83     */
84    public static function getActive(PlatformEnum $platform): Collection
85    {
86        return static::where('platform', $platform)
87            ->where('is_active', true)
88            ->get();
89    }
90
91    // Set this account as active (deactivates others for same platform)
92    public function setAsActive(): void
93    {
94        // Deactivate other accounts for this platform
95        static::where('platform', $this->platform)
96            ->where('id', '!=', $this->id)
97            ->update(['is_active' => false]);
98
99        // Activate this account
100        $this->update(['is_active' => true]);
101    }
102
103    /**
104     * @return BelongsToMany<PlatformChannel, $this>
105     */
106    public function channels(): BelongsToMany
107    {
108        return $this->belongsToMany(PlatformChannel::class, 'platform_account_channels')
109            ->withPivot(['is_active', 'priority'])
110            ->withTimestamps();
111    }
112
113    /**
114     * @return BelongsToMany<PlatformChannel, $this>
115     */
116    public function activeChannels(): BelongsToMany
117    {
118        return $this->channels()
119            ->wherePivot('is_active', true)
120            ->orderByPivot('priority', 'desc');
121    }
122}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:51:47 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-controllers/Models/PlatformChannel.php.html b/backend/coverage-report-controllers/Models/PlatformChannel.php.html deleted file mode 100644 index f80fc1f1..00000000 --- a/backend/coverage-report-controllers/Models/PlatformChannel.php.html +++ /dev/null @@ -1,387 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Models/PlatformChannel.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 14
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 7
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
PlatformChannel
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 14
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 7
56
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 platformInstance
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 platformAccounts
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 activePlatformAccounts
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 getFullNameAttribute
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 feeds
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 4
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 activeFeeds
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 language
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Models;
4
5use Database\Factories\PlatformChannelFactory;
6use Illuminate\Database\Eloquent\Factories\HasFactory;
7use Illuminate\Database\Eloquent\Model;
8use Illuminate\Database\Eloquent\Relations\BelongsTo;
9use Illuminate\Database\Eloquent\Relations\BelongsToMany;
10
11/**
12 * @method static findMany(mixed $channel_ids)
13 * @property integer $id
14 * @property integer $platform_instance_id
15 * @property PlatformInstance $platformInstance
16 * @property integer $channel_id
17 * @property string $name
18 * @property int $language_id
19 * @property Language|null $language
20 * @property boolean $is_active
21 */
22class PlatformChannel extends Model
23{
24    /** @use HasFactory<PlatformChannelFactory> */
25    use HasFactory;
26
27    protected $table = 'platform_channels';
28
29    protected $fillable = [
30        'platform_instance_id',
31        'name',
32        'display_name',
33        'channel_id',
34        'description',
35        'language_id',
36        'is_active'
37    ];
38
39    protected $casts = [
40        'is_active' => 'boolean'
41    ];
42
43    /**
44     * @return BelongsTo<PlatformInstance, $this>
45     */
46    public function platformInstance(): BelongsTo
47    {
48        return $this->belongsTo(PlatformInstance::class);
49    }
50
51    /**
52     * @return BelongsToMany<PlatformAccount, $this>
53     */
54    public function platformAccounts(): BelongsToMany
55    {
56        return $this->belongsToMany(PlatformAccount::class, 'platform_account_channels')
57            ->withPivot(['is_active', 'priority'])
58            ->withTimestamps();
59    }
60
61    /**
62     * @return BelongsToMany<PlatformAccount, $this>
63     */
64    public function activePlatformAccounts(): BelongsToMany
65    {
66        return $this->platformAccounts()->wherePivot('is_active', true);
67    }
68
69    public function getFullNameAttribute(): string
70    {
71        // For Lemmy, use /c/ prefix
72        return $this->platformInstance->url . '/c/' . $this->name;
73    }
74
75    /**
76     * @return BelongsToMany<Feed, $this, Route>
77     */
78    public function feeds(): BelongsToMany
79    {
80        return $this->belongsToMany(Feed::class, 'routes')
81            ->using(Route::class)
82            ->withPivot(['is_active', 'priority', 'filters'])
83            ->withTimestamps();
84    }
85
86    /**
87     * @return BelongsToMany<Feed, $this, Route>
88     */
89    public function activeFeeds(): BelongsToMany
90    {
91        return $this->feeds()
92            ->wherePivot('is_active', true)
93            ->orderByPivot('priority', 'desc');
94    }
95
96    /**
97     * @return BelongsTo<Language, $this>
98     */
99    public function language(): BelongsTo
100    {
101        return $this->belongsTo(Language::class);
102    }
103}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:51:47 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-controllers/Models/PlatformChannelPost.php.html b/backend/coverage-report-controllers/Models/PlatformChannelPost.php.html deleted file mode 100644 index 5a009332..00000000 --- a/backend/coverage-report-controllers/Models/PlatformChannelPost.php.html +++ /dev/null @@ -1,255 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Models/PlatformChannelPost.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 21
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
PlatformChannelPost
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 21
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
12
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 casts
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 4
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 urlExists
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 4
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 storePost
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 13
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Models;
4
5use App\Enums\PlatformEnum;
6use Illuminate\Database\Eloquent\Model;
7
8/**
9 * @method static where(string $string, PlatformEnum $platform)
10 * @method static updateOrCreate(array<string, mixed> $array, array<string, mixed> $array1)
11 */
12class PlatformChannelPost extends Model
13{
14    protected $fillable = [
15        'platform',
16        'channel_id',
17        'channel_name',
18        'post_id',
19        'url',
20        'title',
21        'posted_at',
22    ];
23
24    /**
25     * @return array<string, string>
26     */
27    protected function casts(): array
28    {
29        return [
30            'posted_at' => 'datetime',
31            'platform' => PlatformEnum::class,
32        ];
33    }
34
35    public static function urlExists(PlatformEnum $platform, string $channelId, string $url): bool
36    {
37        return self::where('platform', $platform)
38            ->where('channel_id', $channelId)
39            ->where('url', $url)
40            ->exists();
41    }
42
43    public static function storePost(PlatformEnum $platform, string $channelId, ?string $channelName, string $postId, ?string $url, ?string $title, ?\DateTime $postedAt = null): self
44    {
45        return self::updateOrCreate(
46            [
47                'platform' => $platform,
48                'channel_id' => $channelId,
49                'post_id' => $postId,
50            ],
51            [
52                'channel_name' => $channelName,
53                'url' => $url,
54                'title' => $title,
55                'posted_at' => $postedAt ?? now(),
56            ]
57        );
58    }
59}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:51:47 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-controllers/Models/PlatformInstance.php.html b/backend/coverage-report-controllers/Models/PlatformInstance.php.html deleted file mode 100644 index c4bba901..00000000 --- a/backend/coverage-report-controllers/Models/PlatformInstance.php.html +++ /dev/null @@ -1,259 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Models/PlatformInstance.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 7
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
PlatformInstance
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 7
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
12
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 channels
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 languages
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 findByUrl
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Models;
4
5use App\Enums\PlatformEnum;
6use Database\Factories\PlatformInstanceFactory;
7use Illuminate\Database\Eloquent\Factories\HasFactory;
8use Illuminate\Database\Eloquent\Model;
9use Illuminate\Database\Eloquent\Relations\BelongsToMany;
10use Illuminate\Database\Eloquent\Relations\HasMany;
11
12/**
13 * @method static updateOrCreate(array<string, mixed> $array, $instanceData)
14 * @method static where(string $string, mixed $operator)
15 * @property PlatformEnum $platform
16 * @property string $url
17 * @property string $name
18 * @property string $description
19 * @property boolean $is_active
20 */
21class PlatformInstance extends Model
22{
23    /** @use HasFactory<PlatformInstanceFactory> */
24    use HasFactory;
25    
26    protected $fillable = [
27        'platform',
28        'url',
29        'name',
30        'description',
31        'is_active'
32    ];
33
34    protected $casts = [
35        'platform' => PlatformEnum::class,
36        'is_active' => 'boolean'
37    ];
38
39    /**
40     * @return HasMany<PlatformChannel, $this>
41     */
42    public function channels(): HasMany
43    {
44        return $this->hasMany(PlatformChannel::class);
45    }
46
47    /**
48     * @return BelongsToMany<Language, $this>
49     */
50    public function languages(): BelongsToMany
51    {
52        return $this->belongsToMany(Language::class)
53            ->withPivot(['platform_language_id', 'is_default'])
54            ->withTimestamps();
55    }
56
57    public static function findByUrl(PlatformEnum $platform, string $url): ?self
58    {
59        return static::where('platform', $platform)
60            ->where('url', $url)
61            ->first();
62    }
63}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:51:47 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-controllers/Models/Route.php.html b/backend/coverage-report-controllers/Models/Route.php.html deleted file mode 100644 index 0f34ad88..00000000 --- a/backend/coverage-report-controllers/Models/Route.php.html +++ /dev/null @@ -1,263 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Models/Route.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 4
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
Route
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 4
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
12
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 feed
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 platformChannel
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 keywords
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Models;
4
5use Database\Factories\RouteFactory;
6use Illuminate\Database\Eloquent\Factories\HasFactory;
7use Illuminate\Database\Eloquent\Relations\BelongsTo;
8use Illuminate\Database\Eloquent\Relations\HasMany;
9use Illuminate\Database\Eloquent\Relations\Pivot;
10use Illuminate\Support\Carbon;
11
12/**
13 * @property int $feed_id
14 * @property int $platform_channel_id
15 * @property bool $is_active
16 * @property int $priority
17 * @property array<string, mixed> $filters
18 * @property Carbon $created_at
19 * @property Carbon $updated_at
20 */
21class Route extends Pivot
22{
23    /** @use HasFactory<RouteFactory> */
24    use HasFactory;
25    
26    protected $table = 'routes';
27
28    public $incrementing = false;
29
30    protected $fillable = [
31        'feed_id',
32        'platform_channel_id',
33        'is_active',
34        'priority',
35        'filters'
36    ];
37
38    protected $casts = [
39        'is_active' => 'boolean',
40        'filters' => 'array'
41    ];
42
43    /**
44     * @return BelongsTo<Feed, $this>
45     */
46    public function feed(): BelongsTo
47    {
48        return $this->belongsTo(Feed::class);
49    }
50
51    /**
52     * @return BelongsTo<PlatformChannel, $this>
53     */
54    public function platformChannel(): BelongsTo
55    {
56        return $this->belongsTo(PlatformChannel::class);
57    }
58
59    /**
60     * @return HasMany<Keyword, $this>
61     */
62    public function keywords(): HasMany
63    {
64        return $this->hasMany(Keyword::class, 'feed_id', 'feed_id')
65            ->where('platform_channel_id', $this->platform_channel_id);
66    }
67}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:51:47 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-controllers/Models/Setting.php.html b/backend/coverage-report-controllers/Models/Setting.php.html deleted file mode 100644 index c260d78b..00000000 --- a/backend/coverage-report-controllers/Models/Setting.php.html +++ /dev/null @@ -1,360 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Models/Setting.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 100.00% covered (success) -
-
-
100.00%
10 / 10
-
- 100.00% covered (success) -
-
-
100.00%
8 / 8
CRAP
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
Setting
-
- 100.00% covered (success) -
-
-
100.00%
10 / 10
-
- 100.00% covered (success) -
-
-
100.00%
8 / 8
10
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
 get
-
- 100.00% covered (success) -
-
-
100.00%
2 / 2
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
2
 set
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
1
 getBool
-
- 100.00% covered (success) -
-
-
100.00%
2 / 2
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
1
 setBool
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
2
 isArticleProcessingEnabled
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
1
 setArticleProcessingEnabled
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
1
 isPublishingApprovalsEnabled
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
1
 setPublishingApprovalsEnabled
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
1
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Models;
4
5use Illuminate\Database\Eloquent\Model;
6
7class Setting extends Model
8{
9    protected $fillable = ['key', 'value'];
10
11    public static function get(string $key, mixed $default = null): mixed
12    {
13        $setting = static::where('key', $key)->first();
14        
15        return $setting ? $setting->value : $default;
16    }
17
18    public static function set(string $key, mixed $value): void
19    {
20        static::updateOrCreate(['key' => $key], ['value' => $value]);
21    }
22
23    public static function getBool(string $key, bool $default = false): bool
24    {
25        $value = static::get($key, $default);
26        
27        return filter_var($value, FILTER_VALIDATE_BOOLEAN);
28    }
29
30    public static function setBool(string $key, bool $value): void
31    {
32        static::set($key, $value ? '1' : '0');
33    }
34
35    public static function isArticleProcessingEnabled(): bool
36    {
37        return static::getBool('article_processing_enabled', true);
38    }
39
40    public static function setArticleProcessingEnabled(bool $enabled): void
41    {
42        static::setBool('article_processing_enabled', $enabled);
43    }
44
45    public static function isPublishingApprovalsEnabled(): bool
46    {
47        return static::getBool('enable_publishing_approvals', false);
48    }
49
50    public static function setPublishingApprovalsEnabled(bool $enabled): void
51    {
52        static::setBool('enable_publishing_approvals', $enabled);
53    }
54}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:51:47 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-controllers/Models/User.php.html b/backend/coverage-report-controllers/Models/User.php.html deleted file mode 100644 index be1dd0d8..00000000 --- a/backend/coverage-report-controllers/Models/User.php.html +++ /dev/null @@ -1,201 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Models/User.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 4
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
User
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 4
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 casts
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 4
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Models;
4
5// use Illuminate\Contracts\Auth\MustVerifyEmail;
6use Illuminate\Database\Eloquent\Factories\HasFactory;
7use Illuminate\Foundation\Auth\User as Authenticatable;
8use Illuminate\Notifications\Notifiable;
9use Laravel\Sanctum\HasApiTokens;
10
11class User extends Authenticatable
12{
13    /** @use HasFactory<\Database\Factories\UserFactory> */
14    use HasFactory, Notifiable, HasApiTokens;
15
16    /**
17     * The attributes that are mass assignable.
18     *
19     * @var list<string>
20     */
21    protected $fillable = [
22        'name',
23        'email',
24        'password',
25    ];
26
27    /**
28     * The attributes that should be hidden for serialization.
29     *
30     * @var list<string>
31     */
32    protected $hidden = [
33        'password',
34        'remember_token',
35    ];
36
37    /**
38     * Get the attributes that should be cast.
39     *
40     * @return array<string, string>
41     */
42    protected function casts(): array
43    {
44        return [
45            'email_verified_at' => 'datetime',
46            'password' => 'hashed',
47        ];
48    }
49}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:51:47 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-controllers/Models/dashboard.html b/backend/coverage-report-controllers/Models/dashboard.html deleted file mode 100644 index 79fbfcba..00000000 --- a/backend/coverage-report-controllers/Models/dashboard.html +++ /dev/null @@ -1,343 +0,0 @@ - - - - - Dashboard for /var/www/html/backend/app/Models - - - - - - - -
-
-
-
- -
-
-
-
-
-
-
-

Classes

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
- -
-
-

Methods

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
- - -
- - - - - - diff --git a/backend/coverage-report-controllers/Models/index.html b/backend/coverage-report-controllers/Models/index.html deleted file mode 100644 index 81cdd169..00000000 --- a/backend/coverage-report-controllers/Models/index.html +++ /dev/null @@ -1,440 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Models - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 24.34% covered (danger) -
-
-
24.34%
37 / 152
-
- 27.78% covered (danger) -
-
-
27.78%
15 / 54
-
- 8.33% covered (danger) -
-
-
8.33%
1 / 12
Article.php
-
- 66.67% covered (warning) -
-
-
66.67%
26 / 39
-
- 54.55% covered (warning) -
-
-
54.55%
6 / 11
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
ArticlePublication.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
Feed.php
-
- 4.17% covered (danger) -
-
-
4.17%
1 / 24
-
- 16.67% covered (danger) -
-
-
16.67%
1 / 6
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
Keyword.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
Language.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 5
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
Log.php
n/a
0 / 0
n/a
0 / 0
n/a
0 / 0
PlatformAccount.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 21
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 6
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
PlatformChannel.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 14
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 7
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
PlatformChannelPost.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 21
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
PlatformInstance.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 7
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
Route.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 4
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
Setting.php
-
- 100.00% covered (success) -
-
-
100.00%
10 / 10
-
- 100.00% covered (success) -
-
-
100.00%
8 / 8
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
User.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 4
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- -
- - diff --git a/backend/coverage-report-controllers/Modules/Lemmy/LemmyRequest.php.html b/backend/coverage-report-controllers/Modules/Lemmy/LemmyRequest.php.html deleted file mode 100644 index 1b40ec63..00000000 --- a/backend/coverage-report-controllers/Modules/Lemmy/LemmyRequest.php.html +++ /dev/null @@ -1,275 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Modules/Lemmy/LemmyRequest.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 14
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 4
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
LemmyRequest
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 14
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 4
42
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 __construct
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 get
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 5
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
6
 post
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 5
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
6
 withToken
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Modules\Lemmy;
4
5use Illuminate\Support\Facades\Http;
6use Illuminate\Http\Client\Response;
7
8class LemmyRequest
9{
10    private string $instance;
11    private ?string $token;
12
13    public function __construct(string $instance, ?string $token = null)
14    {
15        $this->instance = $instance;
16        $this->token = $token;
17    }
18
19    /**
20     * @param array<string, mixed> $params
21     */
22    public function get(string $endpoint, array $params = []): Response
23    {
24        $url = "https://{$this->instance}/api/v3/{$endpoint}";
25        
26        $request = Http::timeout(30);
27        
28        if ($this->token) {
29            $request = $request->withToken($this->token);
30        }
31        
32        return $request->get($url, $params);
33    }
34
35    /**
36     * @param array<string, mixed> $data
37     */
38    public function post(string $endpoint, array $data = []): Response
39    {
40        $url = "https://{$this->instance}/api/v3/{$endpoint}";
41        
42        $request = Http::timeout(30);
43        
44        if ($this->token) {
45            $request = $request->withToken($this->token);
46        }
47        
48        return $request->post($url, $data);
49    }
50
51    public function withToken(string $token): self
52    {
53        $this->token = $token;
54        return $this;
55    }
56}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:51:47 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-controllers/Modules/Lemmy/Services/LemmyApiService.php.html b/backend/coverage-report-controllers/Modules/Lemmy/Services/LemmyApiService.php.html deleted file mode 100644 index ffccc839..00000000 --- a/backend/coverage-report-controllers/Modules/Lemmy/Services/LemmyApiService.php.html +++ /dev/null @@ -1,438 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Modules/Lemmy/Services/LemmyApiService.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 93
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 6
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
LemmyApiService
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 93
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 6
462
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 __construct
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 login
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 16
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
12
 getCommunityId
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 9
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
12
 syncChannelPosts
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 34
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
30
 createPost
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 19
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
42
 getLanguages
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 14
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
12
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Modules\Lemmy\Services;
4
5use App\Enums\PlatformEnum;
6use App\Models\PlatformChannelPost;
7use App\Modules\Lemmy\LemmyRequest;
8use Exception;
9
10class LemmyApiService
11{
12    private string $instance;
13
14    public function __construct(string $instance)
15    {
16        $this->instance = $instance;
17    }
18
19    public function login(string $username, string $password): ?string
20    {
21        try {
22            $request = new LemmyRequest($this->instance);
23            $response = $request->post('user/login', [
24                'username_or_email' => $username,
25                'password' => $password,
26            ]);
27
28            if (!$response->successful()) {
29                logger()->error('Lemmy login failed', [
30                    'status' => $response->status(),
31                    'body' => $response->body()
32                ]);
33                return null;
34            }
35
36            $data = $response->json();
37            return $data['jwt'] ?? null;
38        } catch (Exception $e) {
39            logger()->error('Lemmy login exception', ['error' => $e->getMessage()]);
40            return null;
41        }
42    }
43
44    public function getCommunityId(string $communityName, string $token): int
45    {
46        try {
47            $request = new LemmyRequest($this->instance, $token);
48            $response = $request->get('community', ['name' => $communityName]);
49
50            if (!$response->successful()) {
51                throw new Exception('Failed to fetch community: ' . $response->status());
52            }
53
54            $data = $response->json();
55            return $data['community_view']['community']['id'] ?? throw new Exception('Community not found');
56        } catch (Exception $e) {
57            logger()->error('Community lookup failed', ['error' => $e->getMessage()]);
58            throw $e;
59        }
60    }
61
62    public function syncChannelPosts(string $token, int $platformChannelId, string $communityName): void
63    {
64        try {
65            $request = new LemmyRequest($this->instance, $token);
66            $response = $request->get('post/list', [
67                'community_id' => $platformChannelId,
68                'limit' => 50,
69                'sort' => 'New'
70            ]);
71
72            if (!$response->successful()) {
73                logger()->warning('Failed to sync channel posts', [
74                    'status' => $response->status(),
75                    'platform_channel_id' => $platformChannelId
76                ]);
77                return;
78            }
79
80            $data = $response->json();
81            $posts = $data['posts'] ?? [];
82
83            foreach ($posts as $postData) {
84                $post = $postData['post'];
85
86                PlatformChannelPost::storePost(
87                    PlatformEnum::LEMMY,
88                    (string) $platformChannelId,
89                    $communityName,
90                    (string) $post['id'],
91                    $post['url'] ?? null,
92                    $post['name'] ?? null,
93                    isset($post['published']) ? new \DateTime($post['published']) : null
94                );
95            }
96
97            logger()->info('Synced channel posts', [
98                'platform_channel_id' => $platformChannelId,
99                'posts_count' => count($posts)
100            ]);
101
102        } catch (Exception $e) {
103            logger()->error('Exception while syncing channel posts', [
104                'error' => $e->getMessage(),
105                'platform_channel_id' => $platformChannelId
106            ]);
107        }
108    }
109
110    /**
111     * @return array<string, mixed>
112     */
113    public function createPost(string $token, string $title, string $body, int $platformChannelId, ?string $url = null, ?string $thumbnail = null, ?int $languageId = null): array
114    {
115        try {
116            $request = new LemmyRequest($this->instance, $token);
117
118            $postData = [
119                'name' => $title,
120                'body' => $body,
121                'community_id' => $platformChannelId,
122            ];
123
124            if ($url) {
125                $postData['url'] = $url;
126            }
127
128            if ($thumbnail) {
129                $postData['custom_thumbnail'] = $thumbnail;
130            }
131
132            if ($languageId) {
133                $postData['language_id'] = $languageId;
134            }
135
136            $response = $request->post('post', $postData);
137
138            if (!$response->successful()) {
139                throw new Exception('Failed to create post: ' . $response->status() . ' - ' . $response->body());
140            }
141
142            return $response->json();
143        } catch (Exception $e) {
144            logger()->error('Post creation failed', ['error' => $e->getMessage()]);
145            throw $e;
146        }
147    }
148
149    /**
150     * @return array<int, mixed>
151     */
152    public function getLanguages(): array
153    {
154        try {
155            $request = new LemmyRequest($this->instance);
156            $response = $request->get('site');
157
158            if (!$response->successful()) {
159                logger()->warning('Failed to fetch site languages', [
160                    'status' => $response->status()
161                ]);
162                return [];
163            }
164
165            $data = $response->json();
166            return $data['all_languages'] ?? [];
167        } catch (Exception $e) {
168            logger()->error('Exception while fetching languages', [
169                'error' => $e->getMessage()
170            ]);
171            return [];
172        }
173    }
174}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:51:47 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-controllers/Modules/Lemmy/Services/LemmyPublisher.php.html b/backend/coverage-report-controllers/Modules/Lemmy/Services/LemmyPublisher.php.html deleted file mode 100644 index d2067574..00000000 --- a/backend/coverage-report-controllers/Modules/Lemmy/Services/LemmyPublisher.php.html +++ /dev/null @@ -1,223 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Modules/Lemmy/Services/LemmyPublisher.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 13
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
LemmyPublisher
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 13
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
6
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 __construct
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 publishToChannel
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 11
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Modules\Lemmy\Services;
4
5use App\Exceptions\PlatformAuthException;
6use App\Models\Article;
7use App\Models\PlatformAccount;
8use App\Models\PlatformChannel;
9use App\Services\Auth\LemmyAuthService;
10use Exception;
11
12class LemmyPublisher
13{
14    private LemmyApiService $api;
15    private PlatformAccount $account;
16
17    public function __construct(PlatformAccount $account)
18    {
19        $this->api = new LemmyApiService($account->instance_url);
20        $this->account = $account;
21    }
22
23    /**
24     * @param array<string, mixed> $extractedData
25     * @return array<string, mixed>
26     * @throws PlatformAuthException
27     * @throws Exception
28     */
29    public function publishToChannel(Article $article, array $extractedData, PlatformChannel $channel): array
30    {
31        $token = LemmyAuthService::getToken($this->account);
32
33        // Use the language ID from extracted data (should be set during validation)
34        $languageId = $extractedData['language_id'] ?? null;
35
36        return $this->api->createPost(
37            $token,
38            $extractedData['title'] ?? 'Untitled',
39            $extractedData['description'] ?? '',
40            $channel->channel_id,
41            $article->url,
42            $extractedData['thumbnail'] ?? null,
43            $languageId
44        );
45    }
46
47}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:51:47 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-controllers/Modules/Lemmy/Services/dashboard.html b/backend/coverage-report-controllers/Modules/Lemmy/Services/dashboard.html deleted file mode 100644 index 893b06a9..00000000 --- a/backend/coverage-report-controllers/Modules/Lemmy/Services/dashboard.html +++ /dev/null @@ -1,302 +0,0 @@ - - - - - Dashboard for /var/www/html/backend/app/Modules/Lemmy/Services - - - - - - - -
-
-
-
- -
-
-
-
-
-
-
-

Classes

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
-
-
-

Insufficient Coverage

- -
-
-

Project Risks

-
- - - - - - - - - - - -
ClassCRAP
App\Modules\Lemmy\Services\LemmyApiService462
-
-
-
-
-
-

Methods

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
-
-
-

Insufficient Coverage

-
- - - - - - - - - - - - - - - - - - -
MethodCoverage
__construct0%
login0%
getCommunityId0%
syncChannelPosts0%
createPost0%
getLanguages0%
__construct0%
publishToChannel0%
-
-
-
-

Project Risks

-
- - - - - - - - - - - - - - - -
MethodCRAP
createPost42
syncChannelPosts30
login12
getCommunityId12
getLanguages12
-
-
-
- -
- - - - - - diff --git a/backend/coverage-report-controllers/Modules/Lemmy/Services/index.html b/backend/coverage-report-controllers/Modules/Lemmy/Services/index.html deleted file mode 100644 index a94e747a..00000000 --- a/backend/coverage-report-controllers/Modules/Lemmy/Services/index.html +++ /dev/null @@ -1,149 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Modules/Lemmy/Services - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 106
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 8
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
LemmyApiService.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 93
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 6
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
LemmyPublisher.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 13
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- -
- - diff --git a/backend/coverage-report-controllers/Modules/Lemmy/dashboard.html b/backend/coverage-report-controllers/Modules/Lemmy/dashboard.html deleted file mode 100644 index 93de774a..00000000 --- a/backend/coverage-report-controllers/Modules/Lemmy/dashboard.html +++ /dev/null @@ -1,309 +0,0 @@ - - - - - Dashboard for /var/www/html/backend/app/Modules/Lemmy - - - - - - - -
-
-
-
- -
-
-
-
-
-
-
-

Classes

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
-
-
-

Insufficient Coverage

- -
-
-

Project Risks

- -
-
-
-
-

Methods

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
-
-
-

Insufficient Coverage

-
- - - - - - - - - - - - - - - - - - - - - - -
MethodCoverage
__construct0%
get0%
post0%
withToken0%
__construct0%
login0%
getCommunityId0%
syncChannelPosts0%
createPost0%
getLanguages0%
__construct0%
publishToChannel0%
-
-
-
-

Project Risks

-
- - - - - - - - - - - - - - - - - -
MethodCRAP
createPost42
syncChannelPosts30
login12
getCommunityId12
getLanguages12
get6
post6
-
-
-
- -
- - - - - - diff --git a/backend/coverage-report-controllers/Modules/Lemmy/index.html b/backend/coverage-report-controllers/Modules/Lemmy/index.html deleted file mode 100644 index 8c9cf17d..00000000 --- a/backend/coverage-report-controllers/Modules/Lemmy/index.html +++ /dev/null @@ -1,148 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Modules/Lemmy - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 120
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 12
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
Services
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 106
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 8
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
LemmyRequest.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 14
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 4
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- -
- - diff --git a/backend/coverage-report-controllers/Modules/dashboard.html b/backend/coverage-report-controllers/Modules/dashboard.html deleted file mode 100644 index 973e237e..00000000 --- a/backend/coverage-report-controllers/Modules/dashboard.html +++ /dev/null @@ -1,308 +0,0 @@ - - - - - Dashboard for /var/www/html/backend/app/Modules - - - - - - - -
-
-
-
- -
-
-
-
-
-
-
-

Classes

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
-
-
-

Insufficient Coverage

- -
-
-

Project Risks

- -
-
-
-
-

Methods

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
-
-
-

Insufficient Coverage

-
- - - - - - - - - - - - - - - - - - - - - - -
MethodCoverage
__construct0%
get0%
post0%
withToken0%
__construct0%
login0%
getCommunityId0%
syncChannelPosts0%
createPost0%
getLanguages0%
__construct0%
publishToChannel0%
-
-
-
-

Project Risks

-
- - - - - - - - - - - - - - - - - -
MethodCRAP
createPost42
syncChannelPosts30
login12
getCommunityId12
getLanguages12
get6
post6
-
-
-
- -
- - - - - - diff --git a/backend/coverage-report-controllers/Modules/index.html b/backend/coverage-report-controllers/Modules/index.html deleted file mode 100644 index c084045d..00000000 --- a/backend/coverage-report-controllers/Modules/index.html +++ /dev/null @@ -1,119 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Modules - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 120
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 12
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
Lemmy
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 120
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 12
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
-
- -
- - diff --git a/backend/coverage-report-controllers/Providers/AppServiceProvider.php.html b/backend/coverage-report-controllers/Providers/AppServiceProvider.php.html deleted file mode 100644 index 54b0b936..00000000 --- a/backend/coverage-report-controllers/Providers/AppServiceProvider.php.html +++ /dev/null @@ -1,260 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Providers/AppServiceProvider.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 82.76% covered (warning) -
-
-
82.76%
24 / 29
-
- 33.33% covered (danger) -
-
-
33.33%
1 / 3
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
AppServiceProvider
-
- 82.76% covered (warning) -
-
-
82.76%
24 / 29
-
- 33.33% covered (danger) -
-
-
33.33%
1 / 3
6.18
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 register
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
1
 boot
-
- 92.00% covered (success) -
-
-
92.00%
23 / 25
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
1.00
 mapExceptionToLogLevel
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
20
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Providers;
4
5use App\Events\ExceptionOccurred;
6use App\Listeners\LogExceptionToDatabase;
7use App\LogLevelEnum;
8use Error;
9use Illuminate\Contracts\Debug\ExceptionHandler;
10use Illuminate\Support\Facades\Event;
11use Illuminate\Support\ServiceProvider;
12use InvalidArgumentException;
13use Throwable;
14
15class AppServiceProvider extends ServiceProvider
16{
17    public function register(): void
18    {
19    }
20
21    public function boot(): void
22    {
23        Event::listen(
24            ExceptionOccurred::class,
25            LogExceptionToDatabase::class,
26        );
27
28        Event::listen(
29            \App\Events\NewArticleFetched::class,
30            \App\Listeners\ValidateArticleListener::class,
31        );
32
33        Event::listen(
34            \App\Events\ArticleApproved::class,
35            \App\Listeners\PublishApprovedArticle::class,
36        );
37
38        Event::listen(
39            \App\Events\ArticleReadyToPublish::class,
40            \App\Listeners\PublishArticle::class,
41        );
42
43        Event::listen(
44            \App\Events\ExceptionLogged::class,
45            \App\Listeners\LogExceptionToDatabase::class,
46        );
47
48        app()->make(ExceptionHandler::class)
49            ->reportable(function (Throwable $e) {
50                $level = $this->mapExceptionToLogLevel($e);
51
52                ExceptionOccurred::dispatch($e, $level, $e->getMessage(), []);
53            });
54    }
55
56    private function mapExceptionToLogLevel(Throwable $exception): LogLevelEnum
57    {
58        return match (true) {
59            $exception instanceof Error => LogLevelEnum::CRITICAL,
60            $exception instanceof InvalidArgumentException => LogLevelEnum::WARNING,
61            default => LogLevelEnum::ERROR,
62        };
63    }
64}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:51:47 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-controllers/Providers/HorizonServiceProvider.php.html b/backend/coverage-report-controllers/Providers/HorizonServiceProvider.php.html deleted file mode 100644 index 6f649b27..00000000 --- a/backend/coverage-report-controllers/Providers/HorizonServiceProvider.php.html +++ /dev/null @@ -1,208 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Providers/HorizonServiceProvider.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 75.00% covered (warning) -
-
-
75.00%
3 / 4
-
- 50.00% covered (danger) -
-
-
50.00%
1 / 2
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
HorizonServiceProvider
-
- 75.00% covered (warning) -
-
-
75.00%
3 / 4
-
- 50.00% covered (danger) -
-
-
50.00%
1 / 2
2.06
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 boot
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
1
 gate
-
- 66.67% covered (warning) -
-
-
66.67%
2 / 3
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
1.04
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Providers;
4
5use Illuminate\Support\Facades\Gate;
6use Laravel\Horizon\Horizon;
7use Laravel\Horizon\HorizonApplicationServiceProvider;
8
9class HorizonServiceProvider extends HorizonApplicationServiceProvider
10{
11    /**
12     * Bootstrap any application services.
13     */
14    public function boot(): void
15    {
16        parent::boot();
17
18        // Horizon::routeSmsNotificationsTo('15556667777');
19        // Horizon::routeMailNotificationsTo('example@example.com');
20        // Horizon::routeSlackNotificationsTo('slack-webhook-url', '#channel');
21    }
22
23    /**
24     * Register the Horizon gate.
25     *
26     * This gate determines who can access Horizon in non-local environments.
27     */
28    protected function gate(): void
29    {
30        Gate::define('viewHorizon', function ($user = null) {
31            return true;
32        });
33    }
34}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:51:47 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-controllers/Providers/dashboard.html b/backend/coverage-report-controllers/Providers/dashboard.html deleted file mode 100644 index 87fca807..00000000 --- a/backend/coverage-report-controllers/Providers/dashboard.html +++ /dev/null @@ -1,290 +0,0 @@ - - - - - Dashboard for /var/www/html/backend/app/Providers - - - - - - - -
-
-
-
- -
-
-
-
-
-
-
-

Classes

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
-
-
-

Insufficient Coverage

-
- - - - - - - - - - - - -
ClassCoverage
App\Providers\HorizonServiceProvider75%
App\Providers\AppServiceProvider82%
-
-
-
-

Project Risks

-
- - - - - - - - - - - -
ClassCRAP
App\Providers\AppServiceProvider6
-
-
-
-
-
-

Methods

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
-
-
-

Insufficient Coverage

-
- - - - - - - - - - - - -
MethodCoverage
mapExceptionToLogLevel0%
gate66%
-
-
-
-

Project Risks

-
- - - - - - - - - - - -
MethodCRAP
mapExceptionToLogLevel20
-
-
-
- -
- - - - - - diff --git a/backend/coverage-report-controllers/Providers/index.html b/backend/coverage-report-controllers/Providers/index.html deleted file mode 100644 index b337ab06..00000000 --- a/backend/coverage-report-controllers/Providers/index.html +++ /dev/null @@ -1,147 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Providers - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 81.82% covered (warning) -
-
-
81.82%
27 / 33
-
- 40.00% covered (danger) -
-
-
40.00%
2 / 5
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
AppServiceProvider.php
-
- 82.76% covered (warning) -
-
-
82.76%
24 / 29
-
- 33.33% covered (danger) -
-
-
33.33%
1 / 3
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
HorizonServiceProvider.php
-
- 75.00% covered (warning) -
-
-
75.00%
3 / 4
-
- 50.00% covered (danger) -
-
-
50.00%
1 / 2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- -
- - diff --git a/backend/coverage-report-controllers/Services/Article/ArticleFetcher.php.html b/backend/coverage-report-controllers/Services/Article/ArticleFetcher.php.html deleted file mode 100644 index f20ca7b0..00000000 --- a/backend/coverage-report-controllers/Services/Article/ArticleFetcher.php.html +++ /dev/null @@ -1,354 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Services/Article/ArticleFetcher.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 44
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 5
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
ArticleFetcher
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 44
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 5
132
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 getArticlesFromFeed
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 9
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
12
 getArticlesFromRssFeed
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 getArticlesFromWebsiteFeed
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 18
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
12
 fetchArticleData
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 9
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
6
 saveArticle
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 7
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
6
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Services\Article;
4
5use App\Models\Article;
6use App\Models\Feed;
7use App\Services\Http\HttpFetcher;
8use App\Services\Factories\ArticleParserFactory;
9use App\Services\Factories\HomepageParserFactory;
10use App\Services\Log\LogSaver;
11use Exception;
12use Illuminate\Support\Collection;
13
14class ArticleFetcher
15{
16    /**
17     * @return Collection<int, Article>
18     */
19    public static function getArticlesFromFeed(Feed $feed): Collection
20    {
21        if ($feed->type === 'rss') {
22            return self::getArticlesFromRssFeed($feed);
23        } elseif ($feed->type === 'website') {
24            return self::getArticlesFromWebsiteFeed($feed);
25        }
26
27        LogSaver::warning("Unsupported feed type", null, [
28            'feed_id' => $feed->id,
29            'feed_type' => $feed->type
30        ]);
31
32        return collect();
33    }
34
35    /**
36     * @return Collection<int, Article>
37     */
38    private static function getArticlesFromRssFeed(Feed $feed): Collection
39    {
40        // TODO: Implement RSS feed parsing
41        // For now, return empty collection
42        return collect();
43    }
44
45    /**
46     * @return Collection<int, Article>
47     */
48    private static function getArticlesFromWebsiteFeed(Feed $feed): Collection
49    {
50        try {
51            // Try to get parser for this feed
52            $parser = HomepageParserFactory::getParserForFeed($feed);
53
54            if (! $parser) {
55                LogSaver::warning("No parser available for feed URL", null, [
56                    'feed_id' => $feed->id,
57                    'feed_url' => $feed->url
58                ]);
59
60                return collect();
61            }
62
63            $html = HttpFetcher::fetchHtml($feed->url);
64            $urls = $parser->extractArticleUrls($html);
65
66            return collect($urls)
67                ->map(fn (string $url) => self::saveArticle($url, $feed->id));
68
69        } catch (Exception $e) {
70            LogSaver::error("Failed to fetch articles from website feed", null, [
71                'feed_id' => $feed->id,
72                'feed_url' => $feed->url,
73                'error' => $e->getMessage()
74            ]);
75
76            return collect();
77        }
78    }
79
80    /**
81     * @return array<string, mixed>
82     */
83    public static function fetchArticleData(Article $article): array
84    {
85        try {
86            $html = HttpFetcher::fetchHtml($article->url);
87            $parser = ArticleParserFactory::getParser($article->url);
88
89            return $parser->extractData($html);
90        } catch (Exception $e) {
91            LogSaver::error('Exception while fetching article data', null, [
92                'url' => $article->url,
93                'error' => $e->getMessage()
94            ]);
95
96            return [];
97        }
98    }
99
100    private static function saveArticle(string $url, ?int $feedId = null): Article
101    {
102        $existingArticle = Article::where('url', $url)->first();
103
104        if ($existingArticle) {
105            return $existingArticle;
106        }
107
108        return Article::create([
109            'url' => $url,
110            'feed_id' => $feedId
111        ]);
112    }
113}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:51:47 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-controllers/Services/Article/ValidationService.php.html b/backend/coverage-report-controllers/Services/Article/ValidationService.php.html deleted file mode 100644 index 08bc1c7b..00000000 --- a/backend/coverage-report-controllers/Services/Article/ValidationService.php.html +++ /dev/null @@ -1,228 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Services/Article/ValidationService.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 25
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
ValidationService
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 25
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
30
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 validate
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 18
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
6
 validateByKeywords
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 7
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
12
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Services\Article;
4
5use App\Models\Article;
6
7class ValidationService
8{
9    public static function validate(Article $article): Article
10    {
11        logger('Checking keywords for article: ' . $article->id);
12
13        $articleData = ArticleFetcher::fetchArticleData($article);
14        
15        if (!isset($articleData['full_article'])) {
16            logger()->warning('Article data missing full_article key', [
17                'article_id' => $article->id,
18                'url' => $article->url
19            ]);
20            
21            $article->update([
22                'is_valid' => false,
23                'validated_at' => now(),
24            ]);
25            
26            return $article->refresh();
27        }
28        
29        $validationResult = self::validateByKeywords($articleData['full_article']);
30
31        $article->update([
32            'is_valid' => $validationResult,
33            'validated_at' => now(),
34        ]);
35
36        return $article->refresh();
37    }
38
39    private static function validateByKeywords(string $full_article): bool
40    {
41        $keywords = [
42            'N-VA', 'Bart De Wever', 'Frank Vandenbroucke',
43        ];
44
45        foreach ($keywords as $keyword) {
46            if (stripos($full_article, $keyword) !== false) {
47                return true;
48            }
49        }
50
51        return false;
52    }
53}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:51:47 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-controllers/Services/Article/dashboard.html b/backend/coverage-report-controllers/Services/Article/dashboard.html deleted file mode 100644 index b03ce24d..00000000 --- a/backend/coverage-report-controllers/Services/Article/dashboard.html +++ /dev/null @@ -1,302 +0,0 @@ - - - - - Dashboard for /var/www/html/backend/app/Services/Article - - - - - - - -
-
-
-
- -
-
-
-
-
-
-
-

Classes

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
-
-
-

Insufficient Coverage

- -
-
-

Project Risks

- -
-
-
-
-

Methods

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
-
-
-

Insufficient Coverage

- -
-
-

Project Risks

- -
-
- -
- - - - - - diff --git a/backend/coverage-report-controllers/Services/Article/index.html b/backend/coverage-report-controllers/Services/Article/index.html deleted file mode 100644 index 953d3530..00000000 --- a/backend/coverage-report-controllers/Services/Article/index.html +++ /dev/null @@ -1,148 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Services/Article - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 69
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 7
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
ArticleFetcher.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 44
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 5
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
ValidationService.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 25
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- -
- - diff --git a/backend/coverage-report-controllers/Services/Auth/LemmyAuthService.php.html b/backend/coverage-report-controllers/Services/Auth/LemmyAuthService.php.html deleted file mode 100644 index 315bb81c..00000000 --- a/backend/coverage-report-controllers/Services/Auth/LemmyAuthService.php.html +++ /dev/null @@ -1,194 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Services/Auth/LemmyAuthService.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 12
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
LemmyAuthService
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 12
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
42
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 getToken
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 12
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
42
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Services\Auth;
4
5use App\Enums\PlatformEnum;
6use App\Exceptions\PlatformAuthException;
7use App\Models\PlatformAccount;
8use App\Modules\Lemmy\Services\LemmyApiService;
9use Illuminate\Support\Facades\Cache;
10
11class LemmyAuthService
12{
13    /**
14     * @throws PlatformAuthException
15     */
16    public static function getToken(PlatformAccount $account): string
17    {
18        $cacheKey = "lemmy_jwt_token_$account->id";
19        $cachedToken = Cache::get($cacheKey);
20
21        if ($cachedToken) {
22            return $cachedToken;
23        }
24
25        if (! $account->username || ! $account->password || ! $account->instance_url) {
26            throw new PlatformAuthException(PlatformEnum::LEMMY, 'Missing credentials for account: ' . $account->username);
27        }
28
29        $api = new LemmyApiService($account->instance_url);
30        $token = $api->login($account->username, $account->password);
31
32        if (!$token) {
33            throw new PlatformAuthException(PlatformEnum::LEMMY, 'Login failed for account: ' . $account->username);
34        }
35
36        // Cache for 50 minutes (3000 seconds) to allow buffer before token expires
37        Cache::put($cacheKey, $token, 3000);
38
39        return $token;
40    }
41}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:51:47 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-controllers/Services/Auth/dashboard.html b/backend/coverage-report-controllers/Services/Auth/dashboard.html deleted file mode 100644 index 63c11656..00000000 --- a/backend/coverage-report-controllers/Services/Auth/dashboard.html +++ /dev/null @@ -1,289 +0,0 @@ - - - - - Dashboard for /var/www/html/backend/app/Services/Auth - - - - - - - -
-
-
-
- -
-
-
-
-
-
-
-

Classes

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
-
-
-

Insufficient Coverage

-
- - - - - - - - - - - -
ClassCoverage
App\Services\Auth\LemmyAuthService0%
-
-
-
-

Project Risks

-
- - - - - - - - - - - -
ClassCRAP
App\Services\Auth\LemmyAuthService42
-
-
-
-
-
-

Methods

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
-
-
-

Insufficient Coverage

-
- - - - - - - - - - - -
MethodCoverage
getToken0%
-
-
-
-

Project Risks

-
- - - - - - - - - - - -
MethodCRAP
getToken42
-
-
-
- -
- - - - - - diff --git a/backend/coverage-report-controllers/Services/Auth/index.html b/backend/coverage-report-controllers/Services/Auth/index.html deleted file mode 100644 index 6ddb0e6c..00000000 --- a/backend/coverage-report-controllers/Services/Auth/index.html +++ /dev/null @@ -1,120 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Services/Auth - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 12
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
LemmyAuthService.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 12
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- -
- - diff --git a/backend/coverage-report-controllers/Services/DashboardStatsService.php.html b/backend/coverage-report-controllers/Services/DashboardStatsService.php.html deleted file mode 100644 index e58c7831..00000000 --- a/backend/coverage-report-controllers/Services/DashboardStatsService.php.html +++ /dev/null @@ -1,306 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Services/DashboardStatsService.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 100.00% covered (success) -
-
-
100.00%
40 / 40
-
- 100.00% covered (success) -
-
-
100.00%
4 / 4
CRAP
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
DashboardStatsService
-
- 100.00% covered (success) -
-
-
100.00%
40 / 40
-
- 100.00% covered (success) -
-
-
100.00%
4 / 4
13
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
 getStats
-
- 100.00% covered (success) -
-
-
100.00%
16 / 16
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
4
 getAvailablePeriods
-
- 100.00% covered (success) -
-
-
100.00%
7 / 7
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
1
 getDateRange
-
- 100.00% covered (success) -
-
-
100.00%
9 / 9
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
7
 getSystemStats
-
- 100.00% covered (success) -
-
-
100.00%
8 / 8
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
1
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Services;
4
5use App\Models\Article;
6use App\Models\ArticlePublication;
7use Carbon\Carbon;
8
9class DashboardStatsService
10{
11    /**
12     * @return array
13     */
14    public function getStats(string $period = 'today'): array
15    {
16        $dateRange = $this->getDateRange($period);
17        
18        // Get articles fetched for the period
19        $articlesFetchedQuery = Article::query();
20        if ($dateRange) {
21            $articlesFetchedQuery->whereBetween('created_at', $dateRange);
22        }
23        $articlesFetched = $articlesFetchedQuery->count();
24
25        // Get articles published for the period
26        $articlesPublishedQuery = ArticlePublication::query()
27            ->whereNotNull('published_at');
28        if ($dateRange) {
29            $articlesPublishedQuery->whereBetween('published_at', $dateRange);
30        }
31        $articlesPublished = $articlesPublishedQuery->count();
32
33        // Calculate published percentage
34        $publishedPercentage = $articlesFetched > 0 ? round(($articlesPublished / $articlesFetched) * 100, 1) : 0.0;
35
36        return [
37            'articles_fetched' => $articlesFetched,
38            'articles_published' => $articlesPublished,
39            'published_percentage' => $publishedPercentage,
40        ];
41    }
42
43    /**
44     * @return array<string, string>
45     */
46    public function getAvailablePeriods(): array
47    {
48        return [
49            'today' => 'Today',
50            'week' => 'This Week',
51            'month' => 'This Month',
52            'year' => 'This Year',
53            'all' => 'All Time',
54        ];
55    }
56
57    /**
58     * @return array{0: Carbon, 1: Carbon}|null
59     */
60    private function getDateRange(string $period): ?array
61    {
62        $now = Carbon::now();
63        
64        return match ($period) {
65            'today' => [$now->copy()->startOfDay(), $now->copy()->endOfDay()],
66            'week' => [$now->copy()->startOfWeek(), $now->copy()->endOfWeek()],
67            'month' => [$now->copy()->startOfMonth(), $now->copy()->endOfMonth()],
68            'year' => [$now->copy()->startOfYear(), $now->copy()->endOfYear()],
69            'all' => null, // No date filtering for all-time stats
70            default => [$now->copy()->startOfDay(), $now->copy()->endOfDay()],
71        };
72    }
73
74    /**
75     * Get additional stats for dashboard
76     */
77    public function getSystemStats(): array
78    {
79        return [
80            'total_feeds' => \App\Models\Feed::count(),
81            'active_feeds' => \App\Models\Feed::where('is_active', true)->count(),
82            'total_channels' => \App\Models\PlatformChannel::count(),
83            'active_channels' => \App\Models\PlatformChannel::where('is_active', true)->count(),
84            'total_routes' => \App\Models\Route::count(),
85            'active_routes' => \App\Models\Route::where('is_active', true)->count(),
86        ];
87    }
88}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:51:47 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-controllers/Services/Factories/ArticleParserFactory.php.html b/backend/coverage-report-controllers/Services/Factories/ArticleParserFactory.php.html deleted file mode 100644 index abb18d93..00000000 --- a/backend/coverage-report-controllers/Services/Factories/ArticleParserFactory.php.html +++ /dev/null @@ -1,250 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Services/Factories/ArticleParserFactory.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 11
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
ArticleParserFactory
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 11
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
42
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 getParser
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 5
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
12
 getSupportedSources
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 4
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 registerParser
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
6
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Services\Factories;
4
5use App\Contracts\ArticleParserInterface;
6use App\Services\Parsers\VrtArticleParser;
7use App\Services\Parsers\BelgaArticleParser;
8use Exception;
9
10class ArticleParserFactory
11{
12    /**
13     * @var array<int, class-string<ArticleParserInterface>>
14     */
15    private static array $parsers = [
16        VrtArticleParser::class,
17        BelgaArticleParser::class,
18    ];
19
20    public static function getParser(string $url): ArticleParserInterface
21    {
22        foreach (self::$parsers as $parserClass) {
23            $parser = new $parserClass();
24            
25            if ($parser->canParse($url)) {
26                return $parser;
27            }
28        }
29
30        throw new Exception("No parser found for URL: {$url}");
31    }
32
33    /**
34     * @return array<int, string>
35     */
36    public static function getSupportedSources(): array
37    {
38        return array_map(function($parserClass) {
39            $parser = new $parserClass();
40            return $parser->getSourceName();
41        }, self::$parsers);
42    }
43
44    /**
45     * @param class-string<ArticleParserInterface> $parserClass
46     */
47    public static function registerParser(string $parserClass): void
48    {
49        if (!in_array($parserClass, self::$parsers)) {
50            self::$parsers[] = $parserClass;
51        }
52    }
53}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:51:47 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-controllers/Services/Factories/HomepageParserFactory.php.html b/backend/coverage-report-controllers/Services/Factories/HomepageParserFactory.php.html deleted file mode 100644 index 09ceca91..00000000 --- a/backend/coverage-report-controllers/Services/Factories/HomepageParserFactory.php.html +++ /dev/null @@ -1,220 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Services/Factories/HomepageParserFactory.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 8
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
HomepageParserFactory
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 8
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
30
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 getParser
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 5
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
12
 getParserForFeed
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
6
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Services\Factories;
4
5use App\Contracts\HomepageParserInterface;
6use App\Models\Feed;
7use App\Services\Parsers\VrtHomepageParserAdapter;
8use App\Services\Parsers\BelgaHomepageParserAdapter;
9use Exception;
10
11class HomepageParserFactory
12{
13    /**
14     * @var array<int, class-string<HomepageParserInterface>>
15     */
16    private static array $parsers = [
17        VrtHomepageParserAdapter::class,
18        BelgaHomepageParserAdapter::class,
19    ];
20
21    /**
22     * @throws Exception
23     */
24    public static function getParser(string $url): HomepageParserInterface
25    {
26        foreach (self::$parsers as $parserClass) {
27            $parser = new $parserClass();
28
29            if ($parser->canParse($url)) {
30                return $parser;
31            }
32        }
33
34        throw new Exception("No homepage parser found for URL: {$url}");
35    }
36
37    public static function getParserForFeed(Feed $feed): ?HomepageParserInterface
38    {
39        try {
40            return self::getParser($feed->url);
41        } catch (Exception) {
42            return null;
43        }
44    }
45}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:51:47 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-controllers/Services/Factories/dashboard.html b/backend/coverage-report-controllers/Services/Factories/dashboard.html deleted file mode 100644 index 2265aa87..00000000 --- a/backend/coverage-report-controllers/Services/Factories/dashboard.html +++ /dev/null @@ -1,298 +0,0 @@ - - - - - Dashboard for /var/www/html/backend/app/Services/Factories - - - - - - - -
-
-
-
- -
-
-
-
-
-
-
-

Classes

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
-
-
-

Insufficient Coverage

- -
-
-

Project Risks

- -
-
-
-
-

Methods

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
-
-
-

Insufficient Coverage

-
- - - - - - - - - - - - - - - -
MethodCoverage
getParser0%
getSupportedSources0%
registerParser0%
getParser0%
getParserForFeed0%
-
-
-
-

Project Risks

-
- - - - - - - - - - - - - - -
MethodCRAP
getParser12
getParser12
registerParser6
getParserForFeed6
-
-
-
- -
- - - - - - diff --git a/backend/coverage-report-controllers/Services/Factories/index.html b/backend/coverage-report-controllers/Services/Factories/index.html deleted file mode 100644 index 66fa0dbc..00000000 --- a/backend/coverage-report-controllers/Services/Factories/index.html +++ /dev/null @@ -1,148 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Services/Factories - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 19
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 5
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
ArticleParserFactory.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 11
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
HomepageParserFactory.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 8
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- -
- - diff --git a/backend/coverage-report-controllers/Services/Http/HttpFetcher.php.html b/backend/coverage-report-controllers/Services/Http/HttpFetcher.php.html deleted file mode 100644 index e1d7e3a6..00000000 --- a/backend/coverage-report-controllers/Services/Http/HttpFetcher.php.html +++ /dev/null @@ -1,256 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Services/Http/HttpFetcher.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 44
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
HttpFetcher
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 44
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
90
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 fetchHtml
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 10
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
12
 fetchMultipleUrls
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 34
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
42
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Services\Http;
4
5use Illuminate\Support\Facades\Http;
6use Exception;
7
8class HttpFetcher
9{
10    public static function fetchHtml(string $url): string
11    {
12        try {
13            $response = Http::get($url);
14            
15            if (!$response->successful()) {
16                throw new Exception("Failed to fetch URL: {$url} - Status: {$response->status()}");
17            }
18            
19            return $response->body();
20        } catch (Exception $e) {
21            logger()->error('HTTP fetch failed', [
22                'url' => $url,
23                'error' => $e->getMessage()
24            ]);
25            throw $e;
26        }
27    }
28
29    /**
30     * @param array<int, string> $urls
31     * @return array<int, array<string, mixed>>
32     */
33    public static function fetchMultipleUrls(array $urls): array
34    {
35        try {
36            $responses = Http::pool(function ($pool) use ($urls) {
37                foreach ($urls as $url) {
38                    $pool->get($url);
39                }
40            });
41
42            return collect($responses)
43                ->map(function ($response, $index) use ($urls) {
44                    if (!isset($urls[$index])) {
45                        return null;
46                    }
47                    
48                    $url = $urls[$index];
49                    
50                    try {
51                        if ($response->successful()) {
52                            return [
53                                'url' => $url,
54                                'html' => $response->body(),
55                                'success' => true
56                            ];
57                        } else {
58                            return [
59                                'url' => $url,
60                                'html' => null,
61                                'success' => false,
62                                'status' => $response->status()
63                            ];
64                        }
65                    } catch (Exception) {
66                        return [
67                            'url' => $url,
68                            'html' => null,
69                            'success' => false,
70                            'error' => 'Exception occurred'
71                        ];
72                    }
73                })
74                ->filter(fn($result) => $result !== null)
75                ->toArray();
76        } catch (Exception $e) {
77            logger()->error('Multiple URL fetch failed', ['error' => $e->getMessage()]);
78            return [];
79        }
80    }
81}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:51:47 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-controllers/Services/Http/dashboard.html b/backend/coverage-report-controllers/Services/Http/dashboard.html deleted file mode 100644 index fab5cd0b..00000000 --- a/backend/coverage-report-controllers/Services/Http/dashboard.html +++ /dev/null @@ -1,291 +0,0 @@ - - - - - Dashboard for /var/www/html/backend/app/Services/Http - - - - - - - -
-
-
-
- -
-
-
-
-
-
-
-

Classes

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
-
-
-

Insufficient Coverage

-
- - - - - - - - - - - -
ClassCoverage
App\Services\Http\HttpFetcher0%
-
-
-
-

Project Risks

-
- - - - - - - - - - - -
ClassCRAP
App\Services\Http\HttpFetcher90
-
-
-
-
-
-

Methods

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
-
-
-

Insufficient Coverage

-
- - - - - - - - - - - - -
MethodCoverage
fetchHtml0%
fetchMultipleUrls0%
-
-
-
-

Project Risks

-
- - - - - - - - - - - - -
MethodCRAP
fetchMultipleUrls42
fetchHtml12
-
-
-
- -
- - - - - - diff --git a/backend/coverage-report-controllers/Services/Http/index.html b/backend/coverage-report-controllers/Services/Http/index.html deleted file mode 100644 index 194ca660..00000000 --- a/backend/coverage-report-controllers/Services/Http/index.html +++ /dev/null @@ -1,120 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Services/Http - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 44
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
HttpFetcher.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 44
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- -
- - diff --git a/backend/coverage-report-controllers/Services/Log/LogSaver.php.html b/backend/coverage-report-controllers/Services/Log/LogSaver.php.html deleted file mode 100644 index 6b22d796..00000000 --- a/backend/coverage-report-controllers/Services/Log/LogSaver.php.html +++ /dev/null @@ -1,306 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Services/Log/LogSaver.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 17
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 5
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
LogSaver
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 17
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 5
42
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 info
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 error
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 warning
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 debug
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 log
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 13
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
6
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Services\Log;
4
5use App\LogLevelEnum;
6use App\Models\Log;
7use App\Models\PlatformChannel;
8
9class LogSaver
10{
11    /**
12     * @param array<string, mixed> $context
13     */
14    public static function info(string $message, ?PlatformChannel $channel = null, array $context = []): void
15    {
16        self::log(LogLevelEnum::INFO, $message, $channel, $context);
17    }
18
19    /**
20     * @param array<string, mixed> $context
21     */
22    public static function error(string $message, ?PlatformChannel $channel = null, array $context = []): void
23    {
24        self::log(LogLevelEnum::ERROR, $message, $channel, $context);
25    }
26
27    /**
28     * @param array<string, mixed> $context
29     */
30    public static function warning(string $message, ?PlatformChannel $channel = null, array $context = []): void
31    {
32        self::log(LogLevelEnum::WARNING, $message, $channel, $context);
33    }
34
35    /**
36     * @param array<string, mixed> $context
37     */
38    public static function debug(string $message, ?PlatformChannel $channel = null, array $context = []): void
39    {
40        self::log(LogLevelEnum::DEBUG, $message, $channel, $context);
41    }
42
43    /**
44     * @param array<string, mixed> $context
45     */
46    private static function log(LogLevelEnum $level, string $message, ?PlatformChannel $channel = null, array $context = []): void
47    {
48        $logContext = $context;
49
50        if ($channel) {
51            $logContext = array_merge($logContext, [
52                'channel_id' => $channel->id,
53                'channel_name' => $channel->name,
54                'platform' => $channel->platformInstance->platform->value,
55                'instance_url' => $channel->platformInstance->url,
56            ]);
57        }
58
59        Log::create([
60            'level' => $level,
61            'message' => $message,
62            'context' => $logContext,
63        ]);
64    }
65}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:51:47 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-controllers/Services/Log/dashboard.html b/backend/coverage-report-controllers/Services/Log/dashboard.html deleted file mode 100644 index 842cf338..00000000 --- a/backend/coverage-report-controllers/Services/Log/dashboard.html +++ /dev/null @@ -1,293 +0,0 @@ - - - - - Dashboard for /var/www/html/backend/app/Services/Log - - - - - - - -
-
-
-
- -
-
-
-
-
-
-
-

Classes

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
-
-
-

Insufficient Coverage

-
- - - - - - - - - - - -
ClassCoverage
App\Services\Log\LogSaver0%
-
-
-
-

Project Risks

-
- - - - - - - - - - - -
ClassCRAP
App\Services\Log\LogSaver42
-
-
-
-
-
-

Methods

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
-
-
-

Insufficient Coverage

-
- - - - - - - - - - - - - - - -
MethodCoverage
info0%
error0%
warning0%
debug0%
log0%
-
-
-
-

Project Risks

-
- - - - - - - - - - - -
MethodCRAP
log6
-
-
-
- -
- - - - - - diff --git a/backend/coverage-report-controllers/Services/Log/index.html b/backend/coverage-report-controllers/Services/Log/index.html deleted file mode 100644 index 634b13e8..00000000 --- a/backend/coverage-report-controllers/Services/Log/index.html +++ /dev/null @@ -1,120 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Services/Log - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 17
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 5
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
LogSaver.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 17
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 5
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- -
- - diff --git a/backend/coverage-report-controllers/Services/OnboardingRedirectService.php.html b/backend/coverage-report-controllers/Services/OnboardingRedirectService.php.html deleted file mode 100644 index 85174628..00000000 --- a/backend/coverage-report-controllers/Services/OnboardingRedirectService.php.html +++ /dev/null @@ -1,172 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Services/OnboardingRedirectService.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 4
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
OnboardingRedirectService
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 4
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
6
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 handleRedirect
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 4
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
6
-
- - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Services;
4
5use Illuminate\Http\RedirectResponse;
6use Illuminate\Http\Request;
7
8class OnboardingRedirectService
9{
10    public static function handleRedirect(Request $request, string $defaultRoute, string $successMessage): RedirectResponse
11    {
12        $redirectTo = $request->input('redirect_to');
13        
14        if ($redirectTo) {
15            return redirect($redirectTo)->with('success', $successMessage);
16        }
17
18        return redirect()->route($defaultRoute)->with('success', $successMessage);
19    }
20}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:51:47 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-controllers/Services/Parsers/BelgaArticlePageParser.php.html b/backend/coverage-report-controllers/Services/Parsers/BelgaArticlePageParser.php.html deleted file mode 100644 index 4829a5ef..00000000 --- a/backend/coverage-report-controllers/Services/Parsers/BelgaArticlePageParser.php.html +++ /dev/null @@ -1,351 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Services/Parsers/BelgaArticlePageParser.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 42
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 5
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
BelgaArticlePageParser
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 42
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 5
306
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 extractTitle
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 9
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
30
 extractDescription
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 7
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
20
 extractFullArticle
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 15
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
20
 extractThumbnail
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 5
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
12
 extractData
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 6
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Services\Parsers;
4
5class BelgaArticlePageParser
6{
7    public static function extractTitle(string $html): ?string
8    {
9        // Try h1 with Belga-specific class first
10        if (preg_match('/<h1[^>]*class="[^"]*prezly-slate-heading--heading-1[^"]*"[^>]*>([^<]+)<\/h1>/i', $html, $matches)) {
11            return html_entity_decode(strip_tags($matches[1]), ENT_QUOTES, 'UTF-8');
12        }
13        
14        // Try meta title
15        if (preg_match('/<meta property="og:title" content="([^"]+)"/i', $html, $matches)) {
16            return html_entity_decode($matches[1], ENT_QUOTES, 'UTF-8');
17        }
18        
19        // Try any h1 tag
20        if (preg_match('/<h1[^>]*>([^<]+)<\/h1>/i', $html, $matches)) {
21            return html_entity_decode(strip_tags($matches[1]), ENT_QUOTES, 'UTF-8');
22        }
23        
24        // Try title tag
25        if (preg_match('/<title>([^<]+)<\/title>/i', $html, $matches)) {
26            return html_entity_decode($matches[1], ENT_QUOTES, 'UTF-8');
27        }
28        
29        return null;
30    }
31    
32    public static function extractDescription(string $html): ?string
33    {
34        // Try meta description first
35        if (preg_match('/<meta property="og:description" content="([^"]+)"/i', $html, $matches)) {
36            return html_entity_decode($matches[1], ENT_QUOTES, 'UTF-8');
37        }
38        
39        // Try Belga-specific paragraph class
40        if (preg_match('/<p[^>]*class="[^"]*styles_paragraph__[^"]*"[^>]*>([^<]+(?:<[^\/](?!p)[^>]*>[^<]*<\/[^>]*>[^<]*)*)<\/p>/i', $html, $matches)) {
41            return html_entity_decode(strip_tags($matches[1]), ENT_QUOTES, 'UTF-8');
42        }
43        
44        // Try to find first paragraph in article content
45        if (preg_match('/<p[^>]*>([^<]+(?:<[^\/](?!p)[^>]*>[^<]*<\/[^>]*>[^<]*)*)<\/p>/i', $html, $matches)) {
46            return html_entity_decode(strip_tags($matches[1]), ENT_QUOTES, 'UTF-8');
47        }
48        
49        return null;
50    }
51    
52    public static function extractFullArticle(string $html): ?string
53    {
54        // Remove scripts, styles, and other non-content elements
55        $cleanHtml = preg_replace('/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/mi', '', $html);
56        $cleanHtml = preg_replace('/<style\b[^<]*(?:(?!<\/style>)<[^<]*)*<\/style>/mi', '', $cleanHtml);
57        
58        // Try to extract content from Belga-specific document section
59        if (preg_match('/<section[^>]*class="[^"]*prezly-slate-document[^"]*"[^>]*>(.*?)<\/section>/is', $cleanHtml, $sectionMatches)) {
60            $sectionHtml = $sectionMatches[1];
61            preg_match_all('/<p[^>]*>(.*?)<\/p>/is', $sectionHtml, $matches);
62        } else {
63            // Fallback: Extract all paragraph content
64            preg_match_all('/<p[^>]*>(.*?)<\/p>/is', $cleanHtml, $matches);
65        }
66        
67        if (!empty($matches[1])) {
68            $paragraphs = array_map(function($paragraph) {
69                return html_entity_decode(strip_tags($paragraph), ENT_QUOTES, 'UTF-8');
70            }, $matches[1]);
71            
72            // Filter out empty paragraphs and join with double newlines
73            $fullText = implode("\n\n", array_filter($paragraphs, function($p) {
74                return trim($p) !== '';
75            }));
76            
77            return $fullText ?: null;
78        }
79        
80        return null;
81    }
82    
83    public static function extractThumbnail(string $html): ?string
84    {
85        // Try OpenGraph image first
86        if (preg_match('/<meta property="og:image" content="([^"]+)"/i', $html, $matches)) {
87            return $matches[1];
88        }
89        
90        // Try first image in article content
91        if (preg_match('/<img[^>]+src="([^"]+)"/i', $html, $matches)) {
92            return $matches[1];
93        }
94        
95        return null;
96    }
97
98    /**
99     * @return array<string, string|null>
100     */
101    public static function extractData(string $html): array
102    {
103        return [
104            'title' => self::extractTitle($html),
105            'description' => self::extractDescription($html),
106            'full_article' => self::extractFullArticle($html),
107            'thumbnail' => self::extractThumbnail($html),
108        ];
109    }
110}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:51:47 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-controllers/Services/Parsers/BelgaArticleParser.php.html b/backend/coverage-report-controllers/Services/Parsers/BelgaArticleParser.php.html deleted file mode 100644 index 47f9ebd4..00000000 --- a/backend/coverage-report-controllers/Services/Parsers/BelgaArticleParser.php.html +++ /dev/null @@ -1,220 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Services/Parsers/BelgaArticleParser.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
BelgaArticleParser
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
12
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 canParse
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 extractData
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 getSourceName
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Services\Parsers;
4
5use App\Contracts\ArticleParserInterface;
6
7class BelgaArticleParser implements ArticleParserInterface
8{
9    public function canParse(string $url): bool
10    {
11        return str_contains($url, 'belganewsagency.eu');
12    }
13
14    public function extractData(string $html): array
15    {
16        return BelgaArticlePageParser::extractData($html);
17    }
18
19    public function getSourceName(): string
20    {
21        return 'Belga News Agency';
22    }
23}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:51:47 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-controllers/Services/Parsers/BelgaHomepageParser.php.html b/backend/coverage-report-controllers/Services/Parsers/BelgaHomepageParser.php.html deleted file mode 100644 index c3cf37a3..00000000 --- a/backend/coverage-report-controllers/Services/Parsers/BelgaHomepageParser.php.html +++ /dev/null @@ -1,173 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Services/Parsers/BelgaHomepageParser.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 5
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
BelgaHomepageParser
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 5
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 extractArticleUrls
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 5
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Services\Parsers;
4
5class BelgaHomepageParser
6{
7    /**
8     * @return array<int, string>
9     */
10    public static function extractArticleUrls(string $html): array
11    {
12        preg_match_all('/href="(https:\/\/www\.belganewsagency\.eu\/[a-z0-9-]+)"/', $html, $matches);
13
14        $urls = collect($matches[1])
15            ->unique()
16            ->toArray();
17
18        return $urls;
19    }
20}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:51:47 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-controllers/Services/Parsers/BelgaHomepageParserAdapter.php.html b/backend/coverage-report-controllers/Services/Parsers/BelgaHomepageParserAdapter.php.html deleted file mode 100644 index 977b1ea6..00000000 --- a/backend/coverage-report-controllers/Services/Parsers/BelgaHomepageParserAdapter.php.html +++ /dev/null @@ -1,247 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Services/Parsers/BelgaHomepageParserAdapter.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 4
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 4
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
BelgaHomepageParserAdapter
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 4
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 4
20
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 canParse
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 extractArticleUrls
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 getHomepageUrl
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 getSourceName
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Services\Parsers;
4
5use App\Contracts\HomepageParserInterface;
6
7class BelgaHomepageParserAdapter implements HomepageParserInterface
8{
9    public function canParse(string $url): bool
10    {
11        return str_contains($url, 'belganewsagency.eu');
12    }
13
14    public function extractArticleUrls(string $html): array
15    {
16        return BelgaHomepageParser::extractArticleUrls($html);
17    }
18
19    public function getHomepageUrl(): string
20    {
21        return 'https://www.belganewsagency.eu/';
22    }
23
24    public function getSourceName(): string
25    {
26        return 'Belga News Agency';
27    }
28}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:51:47 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-controllers/Services/Parsers/VrtArticlePageParser.php.html b/backend/coverage-report-controllers/Services/Parsers/VrtArticlePageParser.php.html deleted file mode 100644 index 141fe3be..00000000 --- a/backend/coverage-report-controllers/Services/Parsers/VrtArticlePageParser.php.html +++ /dev/null @@ -1,333 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Services/Parsers/VrtArticlePageParser.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 35
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 5
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
VrtArticlePageParser
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 35
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 5
210
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 extractTitle
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 7
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
20
 extractDescription
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 5
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
12
 extractFullArticle
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 12
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
12
 extractThumbnail
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 5
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
12
 extractData
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 6
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Services\Parsers;
4
5class VrtArticlePageParser
6{
7    public static function extractTitle(string $html): ?string
8    {
9        // Try meta title first
10        if (preg_match('/<meta property="og:title" content="([^"]+)"/i', $html, $matches)) {
11            return html_entity_decode($matches[1], ENT_QUOTES, 'UTF-8');
12        }
13
14        // Try h1 tag
15        if (preg_match('/<h1[^>]*>([^<]+)<\/h1>/i', $html, $matches)) {
16            return html_entity_decode(strip_tags($matches[1]), ENT_QUOTES, 'UTF-8');
17        }
18
19        // Try title tag
20        if (preg_match('/<title>([^<]+)<\/title>/i', $html, $matches)) {
21            return html_entity_decode($matches[1], ENT_QUOTES, 'UTF-8');
22        }
23
24        return null;
25    }
26
27    public static function extractDescription(string $html): ?string
28    {
29        // Try meta description first
30        if (preg_match('/<meta property="og:description" content="([^"]+)"/i', $html, $matches)) {
31            return html_entity_decode($matches[1], ENT_QUOTES, 'UTF-8');
32        }
33
34        // Try to find first paragraph in article content
35        if (preg_match('/<p[^>]*>([^<]+(?:<[^\/](?!p)[^>]*>[^<]*<\/[^>]*>[^<]*)*)<\/p>/i', $html, $matches)) {
36            return html_entity_decode(strip_tags($matches[1]), ENT_QUOTES, 'UTF-8');
37        }
38
39        return null;
40    }
41
42    public static function extractFullArticle(string $html): ?string
43    {
44        // Remove scripts, styles, and other non-content elements
45        $cleanHtml = preg_replace('/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/mi', '', $html);
46        $cleanHtml = preg_replace('/<style\b[^<]*(?:(?!<\/style>)<[^<]*)*<\/style>/mi', '', $cleanHtml);
47
48        // Extract all paragraph content
49        preg_match_all('/<p[^>]*>(.*?)<\/p>/is', $cleanHtml, $matches);
50
51        if (!empty($matches[1])) {
52            $paragraphs = array_map(function($paragraph) {
53                return html_entity_decode(strip_tags($paragraph), ENT_QUOTES, 'UTF-8');
54            }, $matches[1]);
55
56            // Filter out empty paragraphs and join with double newlines
57            $fullText = implode("\n\n", array_filter($paragraphs, function($p) {
58                return trim($p) !== '';
59            }));
60
61            return $fullText ?: null;
62        }
63
64        return null;
65    }
66
67    public static function extractThumbnail(string $html): ?string
68    {
69        if (preg_match('/<meta property="og:image" content="([^"]+)"/i', $html, $matches)) {
70            return $matches[1];
71        }
72
73        if (preg_match('/<img[^>]+src="([^"]+)"/i', $html, $matches)) {
74            return $matches[1];
75        }
76
77        return null;
78    }
79
80    /**
81     * @return array<string, string|null>
82     */
83    public static function extractData(string $html): array
84    {
85        return [
86            'title' => self::extractTitle($html),
87            'description' => self::extractDescription($html),
88            'full_article' => self::extractFullArticle($html),
89            'thumbnail' => self::extractThumbnail($html),
90        ];
91    }
92}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:51:47 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-controllers/Services/Parsers/VrtArticleParser.php.html b/backend/coverage-report-controllers/Services/Parsers/VrtArticleParser.php.html deleted file mode 100644 index 9031ec3d..00000000 --- a/backend/coverage-report-controllers/Services/Parsers/VrtArticleParser.php.html +++ /dev/null @@ -1,220 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Services/Parsers/VrtArticleParser.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
VrtArticleParser
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
12
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 canParse
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 extractData
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 getSourceName
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Services\Parsers;
4
5use App\Contracts\ArticleParserInterface;
6
7class VrtArticleParser implements ArticleParserInterface
8{
9    public function canParse(string $url): bool
10    {
11        return str_contains($url, 'vrt.be');
12    }
13
14    public function extractData(string $html): array
15    {
16        return VrtArticlePageParser::extractData($html);
17    }
18
19    public function getSourceName(): string
20    {
21        return 'VRT News';
22    }
23}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:51:47 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-controllers/Services/Parsers/VrtHomepageParser.php.html b/backend/coverage-report-controllers/Services/Parsers/VrtHomepageParser.php.html deleted file mode 100644 index b9242d84..00000000 --- a/backend/coverage-report-controllers/Services/Parsers/VrtHomepageParser.php.html +++ /dev/null @@ -1,175 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Services/Parsers/VrtHomepageParser.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 6
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
VrtHomepageParser
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 6
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 extractArticleUrls
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 6
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Services\Parsers;
4
5class VrtHomepageParser
6{
7    /**
8     * @return array<int, string>
9     */
10    public static function extractArticleUrls(string $html): array
11    {
12        // Extract article links using regex
13        preg_match_all('/href="(\/vrtnws\/en\/\d{4}\/\d{2}\/\d{2}\/[^"]+)"/', $html, $matches);
14
15        $urls = collect($matches[1])
16            ->unique()
17            ->map(fn ($path) => 'https://www.vrt.be' . $path)
18            ->toArray();
19
20        return $urls;
21    }
22}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:51:47 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-controllers/Services/Parsers/VrtHomepageParserAdapter.php.html b/backend/coverage-report-controllers/Services/Parsers/VrtHomepageParserAdapter.php.html deleted file mode 100644 index 2b212139..00000000 --- a/backend/coverage-report-controllers/Services/Parsers/VrtHomepageParserAdapter.php.html +++ /dev/null @@ -1,247 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Services/Parsers/VrtHomepageParserAdapter.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 4
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 4
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
VrtHomepageParserAdapter
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 4
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 4
20
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 canParse
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 extractArticleUrls
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 getHomepageUrl
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 getSourceName
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Services\Parsers;
4
5use App\Contracts\HomepageParserInterface;
6
7class VrtHomepageParserAdapter implements HomepageParserInterface
8{
9    public function canParse(string $url): bool
10    {
11        return str_contains($url, 'vrt.be');
12    }
13
14    public function extractArticleUrls(string $html): array
15    {
16        return VrtHomepageParser::extractArticleUrls($html);
17    }
18
19    public function getHomepageUrl(): string
20    {
21        return 'https://www.vrt.be/vrtnws/en/';
22    }
23
24    public function getSourceName(): string
25    {
26        return 'VRT News';
27    }
28}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:51:47 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-controllers/Services/Parsers/dashboard.html b/backend/coverage-report-controllers/Services/Parsers/dashboard.html deleted file mode 100644 index 6345494a..00000000 --- a/backend/coverage-report-controllers/Services/Parsers/dashboard.html +++ /dev/null @@ -1,329 +0,0 @@ - - - - - Dashboard for /var/www/html/backend/app/Services/Parsers - - - - - - - -
-
-
-
- -
-
-
-
-
-
-
-

Classes

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
- -
-
-

Methods

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
- - -
- - - - - - diff --git a/backend/coverage-report-controllers/Services/Parsers/index.html b/backend/coverage-report-controllers/Services/Parsers/index.html deleted file mode 100644 index 7341500d..00000000 --- a/backend/coverage-report-controllers/Services/Parsers/index.html +++ /dev/null @@ -1,316 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Services/Parsers - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 102
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 26
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 8
BelgaArticlePageParser.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 42
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 5
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
BelgaArticleParser.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
BelgaHomepageParser.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 5
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
BelgaHomepageParserAdapter.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 4
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 4
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
VrtArticlePageParser.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 35
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 5
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
VrtArticleParser.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
VrtHomepageParser.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 6
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
VrtHomepageParserAdapter.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 4
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 4
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- -
- - diff --git a/backend/coverage-report-controllers/Services/Publishing/ArticlePublishingService.php.html b/backend/coverage-report-controllers/Services/Publishing/ArticlePublishingService.php.html deleted file mode 100644 index 77ced687..00000000 --- a/backend/coverage-report-controllers/Services/Publishing/ArticlePublishingService.php.html +++ /dev/null @@ -1,260 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Services/Publishing/ArticlePublishingService.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 36
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
ArticlePublishingService
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 36
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
30
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 publishToRoutedChannels
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 14
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
12
 publishToChannel
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 22
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
6
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Services\Publishing;
4
5use App\Enums\PlatformEnum;
6use App\Exceptions\PublishException;
7use App\Models\Article;
8use App\Models\ArticlePublication;
9use App\Models\PlatformChannel;
10use App\Modules\Lemmy\Services\LemmyPublisher;
11use App\Services\Log\LogSaver;
12use Exception;
13use Illuminate\Database\Eloquent\Collection as EloquentCollection;
14use Illuminate\Support\Collection;
15use RuntimeException;
16
17class ArticlePublishingService
18{
19    /**
20     * @param array<string, mixed> $extractedData
21     * @return EloquentCollection<int, ArticlePublication>
22     * @throws PublishException
23     */
24    public function publishToRoutedChannels(Article $article, array $extractedData): EloquentCollection
25    {
26        if (! $article->is_valid) {
27            throw new PublishException($article, PlatformEnum::LEMMY, new RuntimeException('CANNOT_PUBLISH_INVALID_ARTICLE'));
28        }
29
30        $feed = $article->feed;
31        
32        /** @var EloquentCollection<int, PlatformChannel> $activeChannels */
33        $activeChannels = $feed->activeChannels()->with(['platformInstance', 'activePlatformAccounts'])->get();
34
35        return $activeChannels->map(function (PlatformChannel $channel) use ($article, $extractedData) {
36            $account = $channel->activePlatformAccounts()->first();
37
38            if (! $account) {
39                LogSaver::warning('No active account for channel', $channel, [
40                    'article_id' => $article->id
41                ]);
42
43                return null;
44            }
45
46            return $this->publishToChannel($article, $extractedData, $channel, $account);
47        })
48        ->filter();
49    }
50
51    /**
52     * @param array<string, mixed> $extractedData
53     */
54    private function publishToChannel(Article $article, array $extractedData, PlatformChannel $channel, mixed $account): ?ArticlePublication
55    {
56        try {
57            $publisher = new LemmyPublisher($account);
58            $postData = $publisher->publishToChannel($article, $extractedData, $channel);
59
60            $publication = ArticlePublication::create([
61                'article_id' => $article->id,
62                'post_id' => $postData['post_view']['post']['id'],
63                'platform_channel_id' => $channel->id,
64                'published_by' => $account->username,
65                'published_at' => now(),
66                'platform' => $channel->platformInstance->platform->value,
67                'publication_data' => $postData,
68            ]);
69
70            LogSaver::info('Published to channel via routing', $channel, [
71                'article_id' => $article->id,
72                'priority' => $channel->pivot->priority ?? null
73            ]);
74
75            return $publication;
76        } catch (Exception $e) {
77            LogSaver::warning('Failed to publish to channel', $channel, [
78                'article_id' => $article->id,
79                'error' => $e->getMessage()
80            ]);
81
82            return null;
83        }
84    }
85}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:51:47 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-controllers/Services/Publishing/dashboard.html b/backend/coverage-report-controllers/Services/Publishing/dashboard.html deleted file mode 100644 index df689062..00000000 --- a/backend/coverage-report-controllers/Services/Publishing/dashboard.html +++ /dev/null @@ -1,291 +0,0 @@ - - - - - Dashboard for /var/www/html/backend/app/Services/Publishing - - - - - - - -
-
-
-
- -
-
-
-
-
-
-
-

Classes

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
-
-
-

Insufficient Coverage

-
- - - - - - - - - - - -
ClassCoverage
App\Services\Publishing\ArticlePublishingService0%
-
-
-
-

Project Risks

-
- - - - - - - - - - - -
ClassCRAP
App\Services\Publishing\ArticlePublishingService30
-
-
-
-
-
-

Methods

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
-
-
-

Insufficient Coverage

-
- - - - - - - - - - - - -
MethodCoverage
publishToRoutedChannels0%
publishToChannel0%
-
-
-
-

Project Risks

-
- - - - - - - - - - - - -
MethodCRAP
publishToRoutedChannels12
publishToChannel6
-
-
-
- -
- - - - - - diff --git a/backend/coverage-report-controllers/Services/Publishing/index.html b/backend/coverage-report-controllers/Services/Publishing/index.html deleted file mode 100644 index ee490568..00000000 --- a/backend/coverage-report-controllers/Services/Publishing/index.html +++ /dev/null @@ -1,120 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Services/Publishing - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 36
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
ArticlePublishingService.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 36
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- -
- - diff --git a/backend/coverage-report-controllers/Services/RoutingValidationService.php.html b/backend/coverage-report-controllers/Services/RoutingValidationService.php.html deleted file mode 100644 index 7b297f7f..00000000 --- a/backend/coverage-report-controllers/Services/RoutingValidationService.php.html +++ /dev/null @@ -1,184 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Services/RoutingValidationService.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 7
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
RoutingValidationService
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 7
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
30
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 validateLanguageCompatibility
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 7
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
30
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Services;
4
5use App\Exceptions\RoutingMismatchException;
6use App\Models\Feed;
7use App\Models\PlatformChannel;
8use Illuminate\Support\Collection;
9
10class RoutingValidationService
11{
12    /**
13     * @param Collection<int, PlatformChannel> $channels
14     * @throws RoutingMismatchException
15     */
16    public function validateLanguageCompatibility(Feed $feed, Collection $channels): void
17    {
18        if (! $feed->language) {
19            return;
20        }
21
22        foreach ($channels as $channel) {
23            if (! $channel->language) {
24                continue;
25            }
26
27            if ($feed->language !== $channel->language) {
28                throw new RoutingMismatchException($feed, $channel);
29            }
30        }
31    }
32}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:51:47 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-controllers/Services/SystemStatusService.php.html b/backend/coverage-report-controllers/Services/SystemStatusService.php.html deleted file mode 100644 index e3043de2..00000000 --- a/backend/coverage-report-controllers/Services/SystemStatusService.php.html +++ /dev/null @@ -1,226 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Services/SystemStatusService.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 21
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
SystemStatusService
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 21
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
72
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 getSystemStatus
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 20
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
56
 canProcessArticles
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Services;
4
5use App\Models\Feed;
6use App\Models\Route;
7use App\Models\PlatformChannel;
8use App\Models\Setting;
9
10class SystemStatusService
11{
12    /**
13     * @return array{is_enabled: bool, status: string, status_class: string, reasons: array<int, string>}
14     */
15    public function getSystemStatus(): array
16    {
17        $reasons = [];
18        $isEnabled = true;
19
20        if (!Setting::isArticleProcessingEnabled()) {
21            $isEnabled = false;
22            $reasons[] = 'Manually disabled by user';
23        }
24
25        if (!Feed::where('is_active', true)->exists()) {
26            $isEnabled = false;
27            $reasons[] = 'No active feeds configured';
28        }
29
30        if (!PlatformChannel::where('is_active', true)->exists()) {
31            $isEnabled = false;
32            $reasons[] = 'No active platform channels configured';
33        }
34
35        if (!Route::where('is_active', true)->exists()) {
36            $isEnabled = false;
37            $reasons[] = 'No active feed-to-channel routes configured';
38        }
39
40        return [
41            'is_enabled' => $isEnabled,
42            'status' => $isEnabled ? 'Enabled' : 'Disabled',
43            'status_class' => $isEnabled ? 'text-green-600' : 'text-red-600',
44            'reasons' => $reasons,
45        ];
46    }
47
48    public function canProcessArticles(): bool
49    {
50        return $this->getSystemStatus()['is_enabled'];
51    }
52}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:51:47 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-controllers/Services/dashboard.html b/backend/coverage-report-controllers/Services/dashboard.html deleted file mode 100644 index d53727e9..00000000 --- a/backend/coverage-report-controllers/Services/dashboard.html +++ /dev/null @@ -1,395 +0,0 @@ - - - - - Dashboard for /var/www/html/backend/app/Services - - - - - - - -
-
-
-
- -
-
-
-
-
-
-
-

Classes

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
- -
-
-

Methods

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
-
- - -
- -
- - - - - - diff --git a/backend/coverage-report-controllers/Services/index.html b/backend/coverage-report-controllers/Services/index.html deleted file mode 100644 index 85cef05f..00000000 --- a/backend/coverage-report-controllers/Services/index.html +++ /dev/null @@ -1,399 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Services - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 10.78% covered (danger) -
-
-
10.78%
40 / 371
-
- 7.14% covered (danger) -
-
-
7.14%
4 / 56
-
- 5.00% covered (danger) -
-
-
5.00%
1 / 20
Article
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 69
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 7
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
Auth
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 12
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
Factories
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 19
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 5
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
Http
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 44
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
Log
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 17
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 5
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
Parsers
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 102
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 26
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 8
Publishing
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 36
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
DashboardStatsService.php
-
- 100.00% covered (success) -
-
-
100.00%
40 / 40
-
- 100.00% covered (success) -
-
-
100.00%
4 / 4
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
OnboardingRedirectService.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 4
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
RoutingValidationService.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 7
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
SystemStatusService.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 21
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- -
- - diff --git a/backend/coverage-report-controllers/_css/bootstrap.min.css b/backend/coverage-report-controllers/_css/bootstrap.min.css deleted file mode 100644 index 27d4921c..00000000 --- a/backend/coverage-report-controllers/_css/bootstrap.min.css +++ /dev/null @@ -1,6 +0,0 @@ -@charset "UTF-8";/*! - * Bootstrap v5.3.6 (https://getbootstrap.com/) - * Copyright 2011-2025 The Bootstrap Authors - * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) - */:root,[data-bs-theme=light]{--bs-blue:#0d6efd;--bs-indigo:#6610f2;--bs-purple:#6f42c1;--bs-pink:#d63384;--bs-red:#dc3545;--bs-orange:#fd7e14;--bs-yellow:#ffc107;--bs-green:#198754;--bs-teal:#20c997;--bs-cyan:#0dcaf0;--bs-black:#000;--bs-white:#fff;--bs-gray:#6c757d;--bs-gray-dark:#343a40;--bs-gray-100:#f8f9fa;--bs-gray-200:#e9ecef;--bs-gray-300:#dee2e6;--bs-gray-400:#ced4da;--bs-gray-500:#adb5bd;--bs-gray-600:#6c757d;--bs-gray-700:#495057;--bs-gray-800:#343a40;--bs-gray-900:#212529;--bs-primary:#0d6efd;--bs-secondary:#6c757d;--bs-success:#198754;--bs-info:#0dcaf0;--bs-warning:#ffc107;--bs-danger:#dc3545;--bs-light:#f8f9fa;--bs-dark:#212529;--bs-primary-rgb:13,110,253;--bs-secondary-rgb:108,117,125;--bs-success-rgb:25,135,84;--bs-info-rgb:13,202,240;--bs-warning-rgb:255,193,7;--bs-danger-rgb:220,53,69;--bs-light-rgb:248,249,250;--bs-dark-rgb:33,37,41;--bs-primary-text-emphasis:#052c65;--bs-secondary-text-emphasis:#2b2f32;--bs-success-text-emphasis:#0a3622;--bs-info-text-emphasis:#055160;--bs-warning-text-emphasis:#664d03;--bs-danger-text-emphasis:#58151c;--bs-light-text-emphasis:#495057;--bs-dark-text-emphasis:#495057;--bs-primary-bg-subtle:#cfe2ff;--bs-secondary-bg-subtle:#e2e3e5;--bs-success-bg-subtle:#d1e7dd;--bs-info-bg-subtle:#cff4fc;--bs-warning-bg-subtle:#fff3cd;--bs-danger-bg-subtle:#f8d7da;--bs-light-bg-subtle:#fcfcfd;--bs-dark-bg-subtle:#ced4da;--bs-primary-border-subtle:#9ec5fe;--bs-secondary-border-subtle:#c4c8cb;--bs-success-border-subtle:#a3cfbb;--bs-info-border-subtle:#9eeaf9;--bs-warning-border-subtle:#ffe69c;--bs-danger-border-subtle:#f1aeb5;--bs-light-border-subtle:#e9ecef;--bs-dark-border-subtle:#adb5bd;--bs-white-rgb:255,255,255;--bs-black-rgb:0,0,0;--bs-font-sans-serif:system-ui,-apple-system,"Segoe UI",Roboto,"Helvetica Neue","Noto Sans","Liberation Sans",Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";--bs-font-monospace:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;--bs-gradient:linear-gradient(180deg, rgba(255, 255, 255, 0.15), rgba(255, 255, 255, 0));--bs-body-font-family:var(--bs-font-sans-serif);--bs-body-font-size:1rem;--bs-body-font-weight:400;--bs-body-line-height:1.5;--bs-body-color:#212529;--bs-body-color-rgb:33,37,41;--bs-body-bg:#fff;--bs-body-bg-rgb:255,255,255;--bs-emphasis-color:#000;--bs-emphasis-color-rgb:0,0,0;--bs-secondary-color:rgba(33, 37, 41, 0.75);--bs-secondary-color-rgb:33,37,41;--bs-secondary-bg:#e9ecef;--bs-secondary-bg-rgb:233,236,239;--bs-tertiary-color:rgba(33, 37, 41, 0.5);--bs-tertiary-color-rgb:33,37,41;--bs-tertiary-bg:#f8f9fa;--bs-tertiary-bg-rgb:248,249,250;--bs-heading-color:inherit;--bs-link-color:#0d6efd;--bs-link-color-rgb:13,110,253;--bs-link-decoration:underline;--bs-link-hover-color:#0a58ca;--bs-link-hover-color-rgb:10,88,202;--bs-code-color:#d63384;--bs-highlight-color:#212529;--bs-highlight-bg:#fff3cd;--bs-border-width:1px;--bs-border-style:solid;--bs-border-color:#dee2e6;--bs-border-color-translucent:rgba(0, 0, 0, 0.175);--bs-border-radius:0.375rem;--bs-border-radius-sm:0.25rem;--bs-border-radius-lg:0.5rem;--bs-border-radius-xl:1rem;--bs-border-radius-xxl:2rem;--bs-border-radius-2xl:var(--bs-border-radius-xxl);--bs-border-radius-pill:50rem;--bs-box-shadow:0 0.5rem 1rem rgba(0, 0, 0, 0.15);--bs-box-shadow-sm:0 0.125rem 0.25rem rgba(0, 0, 0, 0.075);--bs-box-shadow-lg:0 1rem 3rem rgba(0, 0, 0, 0.175);--bs-box-shadow-inset:inset 0 1px 2px rgba(0, 0, 0, 0.075);--bs-focus-ring-width:0.25rem;--bs-focus-ring-opacity:0.25;--bs-focus-ring-color:rgba(13, 110, 253, 0.25);--bs-form-valid-color:#198754;--bs-form-valid-border-color:#198754;--bs-form-invalid-color:#dc3545;--bs-form-invalid-border-color:#dc3545}[data-bs-theme=dark]{color-scheme:dark;--bs-body-color:#dee2e6;--bs-body-color-rgb:222,226,230;--bs-body-bg:#212529;--bs-body-bg-rgb:33,37,41;--bs-emphasis-color:#fff;--bs-emphasis-color-rgb:255,255,255;--bs-secondary-color:rgba(222, 226, 230, 0.75);--bs-secondary-color-rgb:222,226,230;--bs-secondary-bg:#343a40;--bs-secondary-bg-rgb:52,58,64;--bs-tertiary-color:rgba(222, 226, 230, 0.5);--bs-tertiary-color-rgb:222,226,230;--bs-tertiary-bg:#2b3035;--bs-tertiary-bg-rgb:43,48,53;--bs-primary-text-emphasis:#6ea8fe;--bs-secondary-text-emphasis:#a7acb1;--bs-success-text-emphasis:#75b798;--bs-info-text-emphasis:#6edff6;--bs-warning-text-emphasis:#ffda6a;--bs-danger-text-emphasis:#ea868f;--bs-light-text-emphasis:#f8f9fa;--bs-dark-text-emphasis:#dee2e6;--bs-primary-bg-subtle:#031633;--bs-secondary-bg-subtle:#161719;--bs-success-bg-subtle:#051b11;--bs-info-bg-subtle:#032830;--bs-warning-bg-subtle:#332701;--bs-danger-bg-subtle:#2c0b0e;--bs-light-bg-subtle:#343a40;--bs-dark-bg-subtle:#1a1d20;--bs-primary-border-subtle:#084298;--bs-secondary-border-subtle:#41464b;--bs-success-border-subtle:#0f5132;--bs-info-border-subtle:#087990;--bs-warning-border-subtle:#997404;--bs-danger-border-subtle:#842029;--bs-light-border-subtle:#495057;--bs-dark-border-subtle:#343a40;--bs-heading-color:inherit;--bs-link-color:#6ea8fe;--bs-link-hover-color:#8bb9fe;--bs-link-color-rgb:110,168,254;--bs-link-hover-color-rgb:139,185,254;--bs-code-color:#e685b5;--bs-highlight-color:#dee2e6;--bs-highlight-bg:#664d03;--bs-border-color:#495057;--bs-border-color-translucent:rgba(255, 255, 255, 0.15);--bs-form-valid-color:#75b798;--bs-form-valid-border-color:#75b798;--bs-form-invalid-color:#ea868f;--bs-form-invalid-border-color:#ea868f}*,::after,::before{box-sizing:border-box}@media (prefers-reduced-motion:no-preference){:root{scroll-behavior:smooth}}body{margin:0;font-family:var(--bs-body-font-family);font-size:var(--bs-body-font-size);font-weight:var(--bs-body-font-weight);line-height:var(--bs-body-line-height);color:var(--bs-body-color);text-align:var(--bs-body-text-align);background-color:var(--bs-body-bg);-webkit-text-size-adjust:100%;-webkit-tap-highlight-color:transparent}hr{margin:1rem 0;color:inherit;border:0;border-top:var(--bs-border-width) solid;opacity:.25}.h1,.h2,.h3,.h4,.h5,.h6,h1,h2,h3,h4,h5,h6{margin-top:0;margin-bottom:.5rem;font-weight:500;line-height:1.2;color:var(--bs-heading-color)}.h1,h1{font-size:calc(1.375rem + 1.5vw)}@media (min-width:1200px){.h1,h1{font-size:2.5rem}}.h2,h2{font-size:calc(1.325rem + .9vw)}@media (min-width:1200px){.h2,h2{font-size:2rem}}.h3,h3{font-size:calc(1.3rem + .6vw)}@media (min-width:1200px){.h3,h3{font-size:1.75rem}}.h4,h4{font-size:calc(1.275rem + .3vw)}@media (min-width:1200px){.h4,h4{font-size:1.5rem}}.h5,h5{font-size:1.25rem}.h6,h6{font-size:1rem}p{margin-top:0;margin-bottom:1rem}abbr[title]{-webkit-text-decoration:underline dotted;text-decoration:underline dotted;cursor:help;-webkit-text-decoration-skip-ink:none;text-decoration-skip-ink:none}address{margin-bottom:1rem;font-style:normal;line-height:inherit}ol,ul{padding-left:2rem}dl,ol,ul{margin-top:0;margin-bottom:1rem}ol ol,ol ul,ul ol,ul ul{margin-bottom:0}dt{font-weight:700}dd{margin-bottom:.5rem;margin-left:0}blockquote{margin:0 0 1rem}b,strong{font-weight:bolder}.small,small{font-size:.875em}.mark,mark{padding:.1875em;color:var(--bs-highlight-color);background-color:var(--bs-highlight-bg)}sub,sup{position:relative;font-size:.75em;line-height:0;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}a{color:rgba(var(--bs-link-color-rgb),var(--bs-link-opacity,1));text-decoration:underline}a:hover{--bs-link-color-rgb:var(--bs-link-hover-color-rgb)}a:not([href]):not([class]),a:not([href]):not([class]):hover{color:inherit;text-decoration:none}code,kbd,pre,samp{font-family:var(--bs-font-monospace);font-size:1em}pre{display:block;margin-top:0;margin-bottom:1rem;overflow:auto;font-size:.875em}pre code{font-size:inherit;color:inherit;word-break:normal}code{font-size:.875em;color:var(--bs-code-color);word-wrap:break-word}a>code{color:inherit}kbd{padding:.1875rem .375rem;font-size:.875em;color:var(--bs-body-bg);background-color:var(--bs-body-color);border-radius:.25rem}kbd kbd{padding:0;font-size:1em}figure{margin:0 0 1rem}img,svg{vertical-align:middle}table{caption-side:bottom;border-collapse:collapse}caption{padding-top:.5rem;padding-bottom:.5rem;color:var(--bs-secondary-color);text-align:left}th{text-align:inherit;text-align:-webkit-match-parent}tbody,td,tfoot,th,thead,tr{border-color:inherit;border-style:solid;border-width:0}label{display:inline-block}button{border-radius:0}button:focus:not(:focus-visible){outline:0}button,input,optgroup,select,textarea{margin:0;font-family:inherit;font-size:inherit;line-height:inherit}button,select{text-transform:none}[role=button]{cursor:pointer}select{word-wrap:normal}select:disabled{opacity:1}[list]:not([type=date]):not([type=datetime-local]):not([type=month]):not([type=week]):not([type=time])::-webkit-calendar-picker-indicator{display:none!important}[type=button],[type=reset],[type=submit],button{-webkit-appearance:button}[type=button]:not(:disabled),[type=reset]:not(:disabled),[type=submit]:not(:disabled),button:not(:disabled){cursor:pointer}::-moz-focus-inner{padding:0;border-style:none}textarea{resize:vertical}fieldset{min-width:0;padding:0;margin:0;border:0}legend{float:left;width:100%;padding:0;margin-bottom:.5rem;line-height:inherit;font-size:calc(1.275rem + .3vw)}@media (min-width:1200px){legend{font-size:1.5rem}}legend+*{clear:left}::-webkit-datetime-edit-day-field,::-webkit-datetime-edit-fields-wrapper,::-webkit-datetime-edit-hour-field,::-webkit-datetime-edit-minute,::-webkit-datetime-edit-month-field,::-webkit-datetime-edit-text,::-webkit-datetime-edit-year-field{padding:0}::-webkit-inner-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-color-swatch-wrapper{padding:0}::-webkit-file-upload-button{font:inherit;-webkit-appearance:button}::file-selector-button{font:inherit;-webkit-appearance:button}output{display:inline-block}iframe{border:0}summary{display:list-item;cursor:pointer}progress{vertical-align:baseline}[hidden]{display:none!important}.lead{font-size:1.25rem;font-weight:300}.display-1{font-weight:300;line-height:1.2;font-size:calc(1.625rem + 4.5vw)}@media (min-width:1200px){.display-1{font-size:5rem}}.display-2{font-weight:300;line-height:1.2;font-size:calc(1.575rem + 3.9vw)}@media (min-width:1200px){.display-2{font-size:4.5rem}}.display-3{font-weight:300;line-height:1.2;font-size:calc(1.525rem + 3.3vw)}@media (min-width:1200px){.display-3{font-size:4rem}}.display-4{font-weight:300;line-height:1.2;font-size:calc(1.475rem + 2.7vw)}@media (min-width:1200px){.display-4{font-size:3.5rem}}.display-5{font-weight:300;line-height:1.2;font-size:calc(1.425rem + 2.1vw)}@media (min-width:1200px){.display-5{font-size:3rem}}.display-6{font-weight:300;line-height:1.2;font-size:calc(1.375rem + 1.5vw)}@media (min-width:1200px){.display-6{font-size:2.5rem}}.list-unstyled{padding-left:0;list-style:none}.list-inline{padding-left:0;list-style:none}.list-inline-item{display:inline-block}.list-inline-item:not(:last-child){margin-right:.5rem}.initialism{font-size:.875em;text-transform:uppercase}.blockquote{margin-bottom:1rem;font-size:1.25rem}.blockquote>:last-child{margin-bottom:0}.blockquote-footer{margin-top:-1rem;margin-bottom:1rem;font-size:.875em;color:#6c757d}.blockquote-footer::before{content:"— "}.img-fluid{max-width:100%;height:auto}.img-thumbnail{padding:.25rem;background-color:var(--bs-body-bg);border:var(--bs-border-width) solid var(--bs-border-color);border-radius:var(--bs-border-radius);max-width:100%;height:auto}.figure{display:inline-block}.figure-img{margin-bottom:.5rem;line-height:1}.figure-caption{font-size:.875em;color:var(--bs-secondary-color)}.container,.container-fluid,.container-lg,.container-md,.container-sm,.container-xl,.container-xxl{--bs-gutter-x:1.5rem;--bs-gutter-y:0;width:100%;padding-right:calc(var(--bs-gutter-x) * .5);padding-left:calc(var(--bs-gutter-x) * .5);margin-right:auto;margin-left:auto}@media (min-width:576px){.container,.container-sm{max-width:540px}}@media (min-width:768px){.container,.container-md,.container-sm{max-width:720px}}@media (min-width:992px){.container,.container-lg,.container-md,.container-sm{max-width:960px}}@media (min-width:1200px){.container,.container-lg,.container-md,.container-sm,.container-xl{max-width:1140px}}@media (min-width:1400px){.container,.container-lg,.container-md,.container-sm,.container-xl,.container-xxl{max-width:1320px}}:root{--bs-breakpoint-xs:0;--bs-breakpoint-sm:576px;--bs-breakpoint-md:768px;--bs-breakpoint-lg:992px;--bs-breakpoint-xl:1200px;--bs-breakpoint-xxl:1400px}.row{--bs-gutter-x:1.5rem;--bs-gutter-y:0;display:flex;flex-wrap:wrap;margin-top:calc(-1 * var(--bs-gutter-y));margin-right:calc(-.5 * var(--bs-gutter-x));margin-left:calc(-.5 * var(--bs-gutter-x))}.row>*{flex-shrink:0;width:100%;max-width:100%;padding-right:calc(var(--bs-gutter-x) * .5);padding-left:calc(var(--bs-gutter-x) * .5);margin-top:var(--bs-gutter-y)}.col{flex:1 0 0}.row-cols-auto>*{flex:0 0 auto;width:auto}.row-cols-1>*{flex:0 0 auto;width:100%}.row-cols-2>*{flex:0 0 auto;width:50%}.row-cols-3>*{flex:0 0 auto;width:33.33333333%}.row-cols-4>*{flex:0 0 auto;width:25%}.row-cols-5>*{flex:0 0 auto;width:20%}.row-cols-6>*{flex:0 0 auto;width:16.66666667%}.col-auto{flex:0 0 auto;width:auto}.col-1{flex:0 0 auto;width:8.33333333%}.col-2{flex:0 0 auto;width:16.66666667%}.col-3{flex:0 0 auto;width:25%}.col-4{flex:0 0 auto;width:33.33333333%}.col-5{flex:0 0 auto;width:41.66666667%}.col-6{flex:0 0 auto;width:50%}.col-7{flex:0 0 auto;width:58.33333333%}.col-8{flex:0 0 auto;width:66.66666667%}.col-9{flex:0 0 auto;width:75%}.col-10{flex:0 0 auto;width:83.33333333%}.col-11{flex:0 0 auto;width:91.66666667%}.col-12{flex:0 0 auto;width:100%}.offset-1{margin-left:8.33333333%}.offset-2{margin-left:16.66666667%}.offset-3{margin-left:25%}.offset-4{margin-left:33.33333333%}.offset-5{margin-left:41.66666667%}.offset-6{margin-left:50%}.offset-7{margin-left:58.33333333%}.offset-8{margin-left:66.66666667%}.offset-9{margin-left:75%}.offset-10{margin-left:83.33333333%}.offset-11{margin-left:91.66666667%}.g-0,.gx-0{--bs-gutter-x:0}.g-0,.gy-0{--bs-gutter-y:0}.g-1,.gx-1{--bs-gutter-x:0.25rem}.g-1,.gy-1{--bs-gutter-y:0.25rem}.g-2,.gx-2{--bs-gutter-x:0.5rem}.g-2,.gy-2{--bs-gutter-y:0.5rem}.g-3,.gx-3{--bs-gutter-x:1rem}.g-3,.gy-3{--bs-gutter-y:1rem}.g-4,.gx-4{--bs-gutter-x:1.5rem}.g-4,.gy-4{--bs-gutter-y:1.5rem}.g-5,.gx-5{--bs-gutter-x:3rem}.g-5,.gy-5{--bs-gutter-y:3rem}@media (min-width:576px){.col-sm{flex:1 0 0}.row-cols-sm-auto>*{flex:0 0 auto;width:auto}.row-cols-sm-1>*{flex:0 0 auto;width:100%}.row-cols-sm-2>*{flex:0 0 auto;width:50%}.row-cols-sm-3>*{flex:0 0 auto;width:33.33333333%}.row-cols-sm-4>*{flex:0 0 auto;width:25%}.row-cols-sm-5>*{flex:0 0 auto;width:20%}.row-cols-sm-6>*{flex:0 0 auto;width:16.66666667%}.col-sm-auto{flex:0 0 auto;width:auto}.col-sm-1{flex:0 0 auto;width:8.33333333%}.col-sm-2{flex:0 0 auto;width:16.66666667%}.col-sm-3{flex:0 0 auto;width:25%}.col-sm-4{flex:0 0 auto;width:33.33333333%}.col-sm-5{flex:0 0 auto;width:41.66666667%}.col-sm-6{flex:0 0 auto;width:50%}.col-sm-7{flex:0 0 auto;width:58.33333333%}.col-sm-8{flex:0 0 auto;width:66.66666667%}.col-sm-9{flex:0 0 auto;width:75%}.col-sm-10{flex:0 0 auto;width:83.33333333%}.col-sm-11{flex:0 0 auto;width:91.66666667%}.col-sm-12{flex:0 0 auto;width:100%}.offset-sm-0{margin-left:0}.offset-sm-1{margin-left:8.33333333%}.offset-sm-2{margin-left:16.66666667%}.offset-sm-3{margin-left:25%}.offset-sm-4{margin-left:33.33333333%}.offset-sm-5{margin-left:41.66666667%}.offset-sm-6{margin-left:50%}.offset-sm-7{margin-left:58.33333333%}.offset-sm-8{margin-left:66.66666667%}.offset-sm-9{margin-left:75%}.offset-sm-10{margin-left:83.33333333%}.offset-sm-11{margin-left:91.66666667%}.g-sm-0,.gx-sm-0{--bs-gutter-x:0}.g-sm-0,.gy-sm-0{--bs-gutter-y:0}.g-sm-1,.gx-sm-1{--bs-gutter-x:0.25rem}.g-sm-1,.gy-sm-1{--bs-gutter-y:0.25rem}.g-sm-2,.gx-sm-2{--bs-gutter-x:0.5rem}.g-sm-2,.gy-sm-2{--bs-gutter-y:0.5rem}.g-sm-3,.gx-sm-3{--bs-gutter-x:1rem}.g-sm-3,.gy-sm-3{--bs-gutter-y:1rem}.g-sm-4,.gx-sm-4{--bs-gutter-x:1.5rem}.g-sm-4,.gy-sm-4{--bs-gutter-y:1.5rem}.g-sm-5,.gx-sm-5{--bs-gutter-x:3rem}.g-sm-5,.gy-sm-5{--bs-gutter-y:3rem}}@media (min-width:768px){.col-md{flex:1 0 0}.row-cols-md-auto>*{flex:0 0 auto;width:auto}.row-cols-md-1>*{flex:0 0 auto;width:100%}.row-cols-md-2>*{flex:0 0 auto;width:50%}.row-cols-md-3>*{flex:0 0 auto;width:33.33333333%}.row-cols-md-4>*{flex:0 0 auto;width:25%}.row-cols-md-5>*{flex:0 0 auto;width:20%}.row-cols-md-6>*{flex:0 0 auto;width:16.66666667%}.col-md-auto{flex:0 0 auto;width:auto}.col-md-1{flex:0 0 auto;width:8.33333333%}.col-md-2{flex:0 0 auto;width:16.66666667%}.col-md-3{flex:0 0 auto;width:25%}.col-md-4{flex:0 0 auto;width:33.33333333%}.col-md-5{flex:0 0 auto;width:41.66666667%}.col-md-6{flex:0 0 auto;width:50%}.col-md-7{flex:0 0 auto;width:58.33333333%}.col-md-8{flex:0 0 auto;width:66.66666667%}.col-md-9{flex:0 0 auto;width:75%}.col-md-10{flex:0 0 auto;width:83.33333333%}.col-md-11{flex:0 0 auto;width:91.66666667%}.col-md-12{flex:0 0 auto;width:100%}.offset-md-0{margin-left:0}.offset-md-1{margin-left:8.33333333%}.offset-md-2{margin-left:16.66666667%}.offset-md-3{margin-left:25%}.offset-md-4{margin-left:33.33333333%}.offset-md-5{margin-left:41.66666667%}.offset-md-6{margin-left:50%}.offset-md-7{margin-left:58.33333333%}.offset-md-8{margin-left:66.66666667%}.offset-md-9{margin-left:75%}.offset-md-10{margin-left:83.33333333%}.offset-md-11{margin-left:91.66666667%}.g-md-0,.gx-md-0{--bs-gutter-x:0}.g-md-0,.gy-md-0{--bs-gutter-y:0}.g-md-1,.gx-md-1{--bs-gutter-x:0.25rem}.g-md-1,.gy-md-1{--bs-gutter-y:0.25rem}.g-md-2,.gx-md-2{--bs-gutter-x:0.5rem}.g-md-2,.gy-md-2{--bs-gutter-y:0.5rem}.g-md-3,.gx-md-3{--bs-gutter-x:1rem}.g-md-3,.gy-md-3{--bs-gutter-y:1rem}.g-md-4,.gx-md-4{--bs-gutter-x:1.5rem}.g-md-4,.gy-md-4{--bs-gutter-y:1.5rem}.g-md-5,.gx-md-5{--bs-gutter-x:3rem}.g-md-5,.gy-md-5{--bs-gutter-y:3rem}}@media (min-width:992px){.col-lg{flex:1 0 0}.row-cols-lg-auto>*{flex:0 0 auto;width:auto}.row-cols-lg-1>*{flex:0 0 auto;width:100%}.row-cols-lg-2>*{flex:0 0 auto;width:50%}.row-cols-lg-3>*{flex:0 0 auto;width:33.33333333%}.row-cols-lg-4>*{flex:0 0 auto;width:25%}.row-cols-lg-5>*{flex:0 0 auto;width:20%}.row-cols-lg-6>*{flex:0 0 auto;width:16.66666667%}.col-lg-auto{flex:0 0 auto;width:auto}.col-lg-1{flex:0 0 auto;width:8.33333333%}.col-lg-2{flex:0 0 auto;width:16.66666667%}.col-lg-3{flex:0 0 auto;width:25%}.col-lg-4{flex:0 0 auto;width:33.33333333%}.col-lg-5{flex:0 0 auto;width:41.66666667%}.col-lg-6{flex:0 0 auto;width:50%}.col-lg-7{flex:0 0 auto;width:58.33333333%}.col-lg-8{flex:0 0 auto;width:66.66666667%}.col-lg-9{flex:0 0 auto;width:75%}.col-lg-10{flex:0 0 auto;width:83.33333333%}.col-lg-11{flex:0 0 auto;width:91.66666667%}.col-lg-12{flex:0 0 auto;width:100%}.offset-lg-0{margin-left:0}.offset-lg-1{margin-left:8.33333333%}.offset-lg-2{margin-left:16.66666667%}.offset-lg-3{margin-left:25%}.offset-lg-4{margin-left:33.33333333%}.offset-lg-5{margin-left:41.66666667%}.offset-lg-6{margin-left:50%}.offset-lg-7{margin-left:58.33333333%}.offset-lg-8{margin-left:66.66666667%}.offset-lg-9{margin-left:75%}.offset-lg-10{margin-left:83.33333333%}.offset-lg-11{margin-left:91.66666667%}.g-lg-0,.gx-lg-0{--bs-gutter-x:0}.g-lg-0,.gy-lg-0{--bs-gutter-y:0}.g-lg-1,.gx-lg-1{--bs-gutter-x:0.25rem}.g-lg-1,.gy-lg-1{--bs-gutter-y:0.25rem}.g-lg-2,.gx-lg-2{--bs-gutter-x:0.5rem}.g-lg-2,.gy-lg-2{--bs-gutter-y:0.5rem}.g-lg-3,.gx-lg-3{--bs-gutter-x:1rem}.g-lg-3,.gy-lg-3{--bs-gutter-y:1rem}.g-lg-4,.gx-lg-4{--bs-gutter-x:1.5rem}.g-lg-4,.gy-lg-4{--bs-gutter-y:1.5rem}.g-lg-5,.gx-lg-5{--bs-gutter-x:3rem}.g-lg-5,.gy-lg-5{--bs-gutter-y:3rem}}@media (min-width:1200px){.col-xl{flex:1 0 0}.row-cols-xl-auto>*{flex:0 0 auto;width:auto}.row-cols-xl-1>*{flex:0 0 auto;width:100%}.row-cols-xl-2>*{flex:0 0 auto;width:50%}.row-cols-xl-3>*{flex:0 0 auto;width:33.33333333%}.row-cols-xl-4>*{flex:0 0 auto;width:25%}.row-cols-xl-5>*{flex:0 0 auto;width:20%}.row-cols-xl-6>*{flex:0 0 auto;width:16.66666667%}.col-xl-auto{flex:0 0 auto;width:auto}.col-xl-1{flex:0 0 auto;width:8.33333333%}.col-xl-2{flex:0 0 auto;width:16.66666667%}.col-xl-3{flex:0 0 auto;width:25%}.col-xl-4{flex:0 0 auto;width:33.33333333%}.col-xl-5{flex:0 0 auto;width:41.66666667%}.col-xl-6{flex:0 0 auto;width:50%}.col-xl-7{flex:0 0 auto;width:58.33333333%}.col-xl-8{flex:0 0 auto;width:66.66666667%}.col-xl-9{flex:0 0 auto;width:75%}.col-xl-10{flex:0 0 auto;width:83.33333333%}.col-xl-11{flex:0 0 auto;width:91.66666667%}.col-xl-12{flex:0 0 auto;width:100%}.offset-xl-0{margin-left:0}.offset-xl-1{margin-left:8.33333333%}.offset-xl-2{margin-left:16.66666667%}.offset-xl-3{margin-left:25%}.offset-xl-4{margin-left:33.33333333%}.offset-xl-5{margin-left:41.66666667%}.offset-xl-6{margin-left:50%}.offset-xl-7{margin-left:58.33333333%}.offset-xl-8{margin-left:66.66666667%}.offset-xl-9{margin-left:75%}.offset-xl-10{margin-left:83.33333333%}.offset-xl-11{margin-left:91.66666667%}.g-xl-0,.gx-xl-0{--bs-gutter-x:0}.g-xl-0,.gy-xl-0{--bs-gutter-y:0}.g-xl-1,.gx-xl-1{--bs-gutter-x:0.25rem}.g-xl-1,.gy-xl-1{--bs-gutter-y:0.25rem}.g-xl-2,.gx-xl-2{--bs-gutter-x:0.5rem}.g-xl-2,.gy-xl-2{--bs-gutter-y:0.5rem}.g-xl-3,.gx-xl-3{--bs-gutter-x:1rem}.g-xl-3,.gy-xl-3{--bs-gutter-y:1rem}.g-xl-4,.gx-xl-4{--bs-gutter-x:1.5rem}.g-xl-4,.gy-xl-4{--bs-gutter-y:1.5rem}.g-xl-5,.gx-xl-5{--bs-gutter-x:3rem}.g-xl-5,.gy-xl-5{--bs-gutter-y:3rem}}@media (min-width:1400px){.col-xxl{flex:1 0 0}.row-cols-xxl-auto>*{flex:0 0 auto;width:auto}.row-cols-xxl-1>*{flex:0 0 auto;width:100%}.row-cols-xxl-2>*{flex:0 0 auto;width:50%}.row-cols-xxl-3>*{flex:0 0 auto;width:33.33333333%}.row-cols-xxl-4>*{flex:0 0 auto;width:25%}.row-cols-xxl-5>*{flex:0 0 auto;width:20%}.row-cols-xxl-6>*{flex:0 0 auto;width:16.66666667%}.col-xxl-auto{flex:0 0 auto;width:auto}.col-xxl-1{flex:0 0 auto;width:8.33333333%}.col-xxl-2{flex:0 0 auto;width:16.66666667%}.col-xxl-3{flex:0 0 auto;width:25%}.col-xxl-4{flex:0 0 auto;width:33.33333333%}.col-xxl-5{flex:0 0 auto;width:41.66666667%}.col-xxl-6{flex:0 0 auto;width:50%}.col-xxl-7{flex:0 0 auto;width:58.33333333%}.col-xxl-8{flex:0 0 auto;width:66.66666667%}.col-xxl-9{flex:0 0 auto;width:75%}.col-xxl-10{flex:0 0 auto;width:83.33333333%}.col-xxl-11{flex:0 0 auto;width:91.66666667%}.col-xxl-12{flex:0 0 auto;width:100%}.offset-xxl-0{margin-left:0}.offset-xxl-1{margin-left:8.33333333%}.offset-xxl-2{margin-left:16.66666667%}.offset-xxl-3{margin-left:25%}.offset-xxl-4{margin-left:33.33333333%}.offset-xxl-5{margin-left:41.66666667%}.offset-xxl-6{margin-left:50%}.offset-xxl-7{margin-left:58.33333333%}.offset-xxl-8{margin-left:66.66666667%}.offset-xxl-9{margin-left:75%}.offset-xxl-10{margin-left:83.33333333%}.offset-xxl-11{margin-left:91.66666667%}.g-xxl-0,.gx-xxl-0{--bs-gutter-x:0}.g-xxl-0,.gy-xxl-0{--bs-gutter-y:0}.g-xxl-1,.gx-xxl-1{--bs-gutter-x:0.25rem}.g-xxl-1,.gy-xxl-1{--bs-gutter-y:0.25rem}.g-xxl-2,.gx-xxl-2{--bs-gutter-x:0.5rem}.g-xxl-2,.gy-xxl-2{--bs-gutter-y:0.5rem}.g-xxl-3,.gx-xxl-3{--bs-gutter-x:1rem}.g-xxl-3,.gy-xxl-3{--bs-gutter-y:1rem}.g-xxl-4,.gx-xxl-4{--bs-gutter-x:1.5rem}.g-xxl-4,.gy-xxl-4{--bs-gutter-y:1.5rem}.g-xxl-5,.gx-xxl-5{--bs-gutter-x:3rem}.g-xxl-5,.gy-xxl-5{--bs-gutter-y:3rem}}.table{--bs-table-color-type:initial;--bs-table-bg-type:initial;--bs-table-color-state:initial;--bs-table-bg-state:initial;--bs-table-color:var(--bs-emphasis-color);--bs-table-bg:var(--bs-body-bg);--bs-table-border-color:var(--bs-border-color);--bs-table-accent-bg:transparent;--bs-table-striped-color:var(--bs-emphasis-color);--bs-table-striped-bg:rgba(var(--bs-emphasis-color-rgb), 0.05);--bs-table-active-color:var(--bs-emphasis-color);--bs-table-active-bg:rgba(var(--bs-emphasis-color-rgb), 0.1);--bs-table-hover-color:var(--bs-emphasis-color);--bs-table-hover-bg:rgba(var(--bs-emphasis-color-rgb), 0.075);width:100%;margin-bottom:1rem;vertical-align:top;border-color:var(--bs-table-border-color)}.table>:not(caption)>*>*{padding:.5rem .5rem;color:var(--bs-table-color-state,var(--bs-table-color-type,var(--bs-table-color)));background-color:var(--bs-table-bg);border-bottom-width:var(--bs-border-width);box-shadow:inset 0 0 0 9999px var(--bs-table-bg-state,var(--bs-table-bg-type,var(--bs-table-accent-bg)))}.table>tbody{vertical-align:inherit}.table>thead{vertical-align:bottom}.table-group-divider{border-top:calc(var(--bs-border-width) * 2) solid currentcolor}.caption-top{caption-side:top}.table-sm>:not(caption)>*>*{padding:.25rem .25rem}.table-bordered>:not(caption)>*{border-width:var(--bs-border-width) 0}.table-bordered>:not(caption)>*>*{border-width:0 var(--bs-border-width)}.table-borderless>:not(caption)>*>*{border-bottom-width:0}.table-borderless>:not(:first-child){border-top-width:0}.table-striped>tbody>tr:nth-of-type(odd)>*{--bs-table-color-type:var(--bs-table-striped-color);--bs-table-bg-type:var(--bs-table-striped-bg)}.table-striped-columns>:not(caption)>tr>:nth-child(2n){--bs-table-color-type:var(--bs-table-striped-color);--bs-table-bg-type:var(--bs-table-striped-bg)}.table-active{--bs-table-color-state:var(--bs-table-active-color);--bs-table-bg-state:var(--bs-table-active-bg)}.table-hover>tbody>tr:hover>*{--bs-table-color-state:var(--bs-table-hover-color);--bs-table-bg-state:var(--bs-table-hover-bg)}.table-primary{--bs-table-color:#000;--bs-table-bg:#cfe2ff;--bs-table-border-color:#a6b5cc;--bs-table-striped-bg:#c5d7f2;--bs-table-striped-color:#000;--bs-table-active-bg:#bacbe6;--bs-table-active-color:#000;--bs-table-hover-bg:#bfd1ec;--bs-table-hover-color:#000;color:var(--bs-table-color);border-color:var(--bs-table-border-color)}.table-secondary{--bs-table-color:#000;--bs-table-bg:#e2e3e5;--bs-table-border-color:#b5b6b7;--bs-table-striped-bg:#d7d8da;--bs-table-striped-color:#000;--bs-table-active-bg:#cbccce;--bs-table-active-color:#000;--bs-table-hover-bg:#d1d2d4;--bs-table-hover-color:#000;color:var(--bs-table-color);border-color:var(--bs-table-border-color)}.table-success{--bs-table-color:#000;--bs-table-bg:#d1e7dd;--bs-table-border-color:#a7b9b1;--bs-table-striped-bg:#c7dbd2;--bs-table-striped-color:#000;--bs-table-active-bg:#bcd0c7;--bs-table-active-color:#000;--bs-table-hover-bg:#c1d6cc;--bs-table-hover-color:#000;color:var(--bs-table-color);border-color:var(--bs-table-border-color)}.table-info{--bs-table-color:#000;--bs-table-bg:#cff4fc;--bs-table-border-color:#a6c3ca;--bs-table-striped-bg:#c5e8ef;--bs-table-striped-color:#000;--bs-table-active-bg:#badce3;--bs-table-active-color:#000;--bs-table-hover-bg:#bfe2e9;--bs-table-hover-color:#000;color:var(--bs-table-color);border-color:var(--bs-table-border-color)}.table-warning{--bs-table-color:#000;--bs-table-bg:#fff3cd;--bs-table-border-color:#ccc2a4;--bs-table-striped-bg:#f2e7c3;--bs-table-striped-color:#000;--bs-table-active-bg:#e6dbb9;--bs-table-active-color:#000;--bs-table-hover-bg:#ece1be;--bs-table-hover-color:#000;color:var(--bs-table-color);border-color:var(--bs-table-border-color)}.table-danger{--bs-table-color:#000;--bs-table-bg:#f8d7da;--bs-table-border-color:#c6acae;--bs-table-striped-bg:#eccccf;--bs-table-striped-color:#000;--bs-table-active-bg:#dfc2c4;--bs-table-active-color:#000;--bs-table-hover-bg:#e5c7ca;--bs-table-hover-color:#000;color:var(--bs-table-color);border-color:var(--bs-table-border-color)}.table-light{--bs-table-color:#000;--bs-table-bg:#f8f9fa;--bs-table-border-color:#c6c7c8;--bs-table-striped-bg:#ecedee;--bs-table-striped-color:#000;--bs-table-active-bg:#dfe0e1;--bs-table-active-color:#000;--bs-table-hover-bg:#e5e6e7;--bs-table-hover-color:#000;color:var(--bs-table-color);border-color:var(--bs-table-border-color)}.table-dark{--bs-table-color:#fff;--bs-table-bg:#212529;--bs-table-border-color:#4d5154;--bs-table-striped-bg:#2c3034;--bs-table-striped-color:#fff;--bs-table-active-bg:#373b3e;--bs-table-active-color:#fff;--bs-table-hover-bg:#323539;--bs-table-hover-color:#fff;color:var(--bs-table-color);border-color:var(--bs-table-border-color)}.table-responsive{overflow-x:auto;-webkit-overflow-scrolling:touch}@media (max-width:575.98px){.table-responsive-sm{overflow-x:auto;-webkit-overflow-scrolling:touch}}@media (max-width:767.98px){.table-responsive-md{overflow-x:auto;-webkit-overflow-scrolling:touch}}@media (max-width:991.98px){.table-responsive-lg{overflow-x:auto;-webkit-overflow-scrolling:touch}}@media (max-width:1199.98px){.table-responsive-xl{overflow-x:auto;-webkit-overflow-scrolling:touch}}@media (max-width:1399.98px){.table-responsive-xxl{overflow-x:auto;-webkit-overflow-scrolling:touch}}.form-label{margin-bottom:.5rem}.col-form-label{padding-top:calc(.375rem + var(--bs-border-width));padding-bottom:calc(.375rem + var(--bs-border-width));margin-bottom:0;font-size:inherit;line-height:1.5}.col-form-label-lg{padding-top:calc(.5rem + var(--bs-border-width));padding-bottom:calc(.5rem + var(--bs-border-width));font-size:1.25rem}.col-form-label-sm{padding-top:calc(.25rem + var(--bs-border-width));padding-bottom:calc(.25rem + var(--bs-border-width));font-size:.875rem}.form-text{margin-top:.25rem;font-size:.875em;color:var(--bs-secondary-color)}.form-control{display:block;width:100%;padding:.375rem .75rem;font-size:1rem;font-weight:400;line-height:1.5;color:var(--bs-body-color);-webkit-appearance:none;-moz-appearance:none;appearance:none;background-color:var(--bs-body-bg);background-clip:padding-box;border:var(--bs-border-width) solid var(--bs-border-color);border-radius:var(--bs-border-radius);transition:border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.form-control{transition:none}}.form-control[type=file]{overflow:hidden}.form-control[type=file]:not(:disabled):not([readonly]){cursor:pointer}.form-control:focus{color:var(--bs-body-color);background-color:var(--bs-body-bg);border-color:#86b7fe;outline:0;box-shadow:0 0 0 .25rem rgba(13,110,253,.25)}.form-control::-webkit-date-and-time-value{min-width:85px;height:1.5em;margin:0}.form-control::-webkit-datetime-edit{display:block;padding:0}.form-control::placeholder{color:var(--bs-secondary-color);opacity:1}.form-control:disabled{background-color:var(--bs-secondary-bg);opacity:1}.form-control::-webkit-file-upload-button{padding:.375rem .75rem;margin:-.375rem -.75rem;-webkit-margin-end:.75rem;margin-inline-end:.75rem;color:var(--bs-body-color);background-color:var(--bs-tertiary-bg);pointer-events:none;border-color:inherit;border-style:solid;border-width:0;border-inline-end-width:var(--bs-border-width);border-radius:0;-webkit-transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}.form-control::file-selector-button{padding:.375rem .75rem;margin:-.375rem -.75rem;-webkit-margin-end:.75rem;margin-inline-end:.75rem;color:var(--bs-body-color);background-color:var(--bs-tertiary-bg);pointer-events:none;border-color:inherit;border-style:solid;border-width:0;border-inline-end-width:var(--bs-border-width);border-radius:0;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.form-control::-webkit-file-upload-button{-webkit-transition:none;transition:none}.form-control::file-selector-button{transition:none}}.form-control:hover:not(:disabled):not([readonly])::-webkit-file-upload-button{background-color:var(--bs-secondary-bg)}.form-control:hover:not(:disabled):not([readonly])::file-selector-button{background-color:var(--bs-secondary-bg)}.form-control-plaintext{display:block;width:100%;padding:.375rem 0;margin-bottom:0;line-height:1.5;color:var(--bs-body-color);background-color:transparent;border:solid transparent;border-width:var(--bs-border-width) 0}.form-control-plaintext:focus{outline:0}.form-control-plaintext.form-control-lg,.form-control-plaintext.form-control-sm{padding-right:0;padding-left:0}.form-control-sm{min-height:calc(1.5em + .5rem + calc(var(--bs-border-width) * 2));padding:.25rem .5rem;font-size:.875rem;border-radius:var(--bs-border-radius-sm)}.form-control-sm::-webkit-file-upload-button{padding:.25rem .5rem;margin:-.25rem -.5rem;-webkit-margin-end:.5rem;margin-inline-end:.5rem}.form-control-sm::file-selector-button{padding:.25rem .5rem;margin:-.25rem -.5rem;-webkit-margin-end:.5rem;margin-inline-end:.5rem}.form-control-lg{min-height:calc(1.5em + 1rem + calc(var(--bs-border-width) * 2));padding:.5rem 1rem;font-size:1.25rem;border-radius:var(--bs-border-radius-lg)}.form-control-lg::-webkit-file-upload-button{padding:.5rem 1rem;margin:-.5rem -1rem;-webkit-margin-end:1rem;margin-inline-end:1rem}.form-control-lg::file-selector-button{padding:.5rem 1rem;margin:-.5rem -1rem;-webkit-margin-end:1rem;margin-inline-end:1rem}textarea.form-control{min-height:calc(1.5em + .75rem + calc(var(--bs-border-width) * 2))}textarea.form-control-sm{min-height:calc(1.5em + .5rem + calc(var(--bs-border-width) * 2))}textarea.form-control-lg{min-height:calc(1.5em + 1rem + calc(var(--bs-border-width) * 2))}.form-control-color{width:3rem;height:calc(1.5em + .75rem + calc(var(--bs-border-width) * 2));padding:.375rem}.form-control-color:not(:disabled):not([readonly]){cursor:pointer}.form-control-color::-moz-color-swatch{border:0!important;border-radius:var(--bs-border-radius)}.form-control-color::-webkit-color-swatch{border:0!important;border-radius:var(--bs-border-radius)}.form-control-color.form-control-sm{height:calc(1.5em + .5rem + calc(var(--bs-border-width) * 2))}.form-control-color.form-control-lg{height:calc(1.5em + 1rem + calc(var(--bs-border-width) * 2))}.form-select{--bs-form-select-bg-img:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%23343a40' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='m2 5 6 6 6-6'/%3e%3c/svg%3e");display:block;width:100%;padding:.375rem 2.25rem .375rem .75rem;font-size:1rem;font-weight:400;line-height:1.5;color:var(--bs-body-color);-webkit-appearance:none;-moz-appearance:none;appearance:none;background-color:var(--bs-body-bg);background-image:var(--bs-form-select-bg-img),var(--bs-form-select-bg-icon,none);background-repeat:no-repeat;background-position:right .75rem center;background-size:16px 12px;border:var(--bs-border-width) solid var(--bs-border-color);border-radius:var(--bs-border-radius);transition:border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.form-select{transition:none}}.form-select:focus{border-color:#86b7fe;outline:0;box-shadow:0 0 0 .25rem rgba(13,110,253,.25)}.form-select[multiple],.form-select[size]:not([size="1"]){padding-right:.75rem;background-image:none}.form-select:disabled{background-color:var(--bs-secondary-bg)}.form-select:-moz-focusring{color:transparent;text-shadow:0 0 0 var(--bs-body-color)}.form-select-sm{padding-top:.25rem;padding-bottom:.25rem;padding-left:.5rem;font-size:.875rem;border-radius:var(--bs-border-radius-sm)}.form-select-lg{padding-top:.5rem;padding-bottom:.5rem;padding-left:1rem;font-size:1.25rem;border-radius:var(--bs-border-radius-lg)}[data-bs-theme=dark] .form-select{--bs-form-select-bg-img:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%23dee2e6' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='m2 5 6 6 6-6'/%3e%3c/svg%3e")}.form-check{display:block;min-height:1.5rem;padding-left:1.5em;margin-bottom:.125rem}.form-check .form-check-input{float:left;margin-left:-1.5em}.form-check-reverse{padding-right:1.5em;padding-left:0;text-align:right}.form-check-reverse .form-check-input{float:right;margin-right:-1.5em;margin-left:0}.form-check-input{--bs-form-check-bg:var(--bs-body-bg);flex-shrink:0;width:1em;height:1em;margin-top:.25em;vertical-align:top;-webkit-appearance:none;-moz-appearance:none;appearance:none;background-color:var(--bs-form-check-bg);background-image:var(--bs-form-check-bg-image);background-repeat:no-repeat;background-position:center;background-size:contain;border:var(--bs-border-width) solid var(--bs-border-color);-webkit-print-color-adjust:exact;color-adjust:exact;print-color-adjust:exact}.form-check-input[type=checkbox]{border-radius:.25em}.form-check-input[type=radio]{border-radius:50%}.form-check-input:active{filter:brightness(90%)}.form-check-input:focus{border-color:#86b7fe;outline:0;box-shadow:0 0 0 .25rem rgba(13,110,253,.25)}.form-check-input:checked{background-color:#0d6efd;border-color:#0d6efd}.form-check-input:checked[type=checkbox]{--bs-form-check-bg-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3e%3cpath fill='none' stroke='%23fff' stroke-linecap='round' stroke-linejoin='round' stroke-width='3' d='m6 10 3 3 6-6'/%3e%3c/svg%3e")}.form-check-input:checked[type=radio]{--bs-form-check-bg-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='2' fill='%23fff'/%3e%3c/svg%3e")}.form-check-input[type=checkbox]:indeterminate{background-color:#0d6efd;border-color:#0d6efd;--bs-form-check-bg-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3e%3cpath fill='none' stroke='%23fff' stroke-linecap='round' stroke-linejoin='round' stroke-width='3' d='M6 10h8'/%3e%3c/svg%3e")}.form-check-input:disabled{pointer-events:none;filter:none;opacity:.5}.form-check-input:disabled~.form-check-label,.form-check-input[disabled]~.form-check-label{cursor:default;opacity:.5}.form-switch{padding-left:2.5em}.form-switch .form-check-input{--bs-form-switch-bg:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='rgba%280, 0, 0, 0.25%29'/%3e%3c/svg%3e");width:2em;margin-left:-2.5em;background-image:var(--bs-form-switch-bg);background-position:left center;border-radius:2em;transition:background-position .15s ease-in-out}@media (prefers-reduced-motion:reduce){.form-switch .form-check-input{transition:none}}.form-switch .form-check-input:focus{--bs-form-switch-bg:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='%2386b7fe'/%3e%3c/svg%3e")}.form-switch .form-check-input:checked{background-position:right center;--bs-form-switch-bg:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='%23fff'/%3e%3c/svg%3e")}.form-switch.form-check-reverse{padding-right:2.5em;padding-left:0}.form-switch.form-check-reverse .form-check-input{margin-right:-2.5em;margin-left:0}.form-check-inline{display:inline-block;margin-right:1rem}.btn-check{position:absolute;clip:rect(0,0,0,0);pointer-events:none}.btn-check:disabled+.btn,.btn-check[disabled]+.btn{pointer-events:none;filter:none;opacity:.65}[data-bs-theme=dark] .form-switch .form-check-input:not(:checked):not(:focus){--bs-form-switch-bg:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='rgba%28255, 255, 255, 0.25%29'/%3e%3c/svg%3e")}.form-range{width:100%;height:1.5rem;padding:0;-webkit-appearance:none;-moz-appearance:none;appearance:none;background-color:transparent}.form-range:focus{outline:0}.form-range:focus::-webkit-slider-thumb{box-shadow:0 0 0 1px #fff,0 0 0 .25rem rgba(13,110,253,.25)}.form-range:focus::-moz-range-thumb{box-shadow:0 0 0 1px #fff,0 0 0 .25rem rgba(13,110,253,.25)}.form-range::-moz-focus-outer{border:0}.form-range::-webkit-slider-thumb{width:1rem;height:1rem;margin-top:-.25rem;-webkit-appearance:none;appearance:none;background-color:#0d6efd;border:0;border-radius:1rem;-webkit-transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.form-range::-webkit-slider-thumb{-webkit-transition:none;transition:none}}.form-range::-webkit-slider-thumb:active{background-color:#b6d4fe}.form-range::-webkit-slider-runnable-track{width:100%;height:.5rem;color:transparent;cursor:pointer;background-color:var(--bs-secondary-bg);border-color:transparent;border-radius:1rem}.form-range::-moz-range-thumb{width:1rem;height:1rem;-moz-appearance:none;appearance:none;background-color:#0d6efd;border:0;border-radius:1rem;-moz-transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.form-range::-moz-range-thumb{-moz-transition:none;transition:none}}.form-range::-moz-range-thumb:active{background-color:#b6d4fe}.form-range::-moz-range-track{width:100%;height:.5rem;color:transparent;cursor:pointer;background-color:var(--bs-secondary-bg);border-color:transparent;border-radius:1rem}.form-range:disabled{pointer-events:none}.form-range:disabled::-webkit-slider-thumb{background-color:var(--bs-secondary-color)}.form-range:disabled::-moz-range-thumb{background-color:var(--bs-secondary-color)}.form-floating{position:relative}.form-floating>.form-control,.form-floating>.form-control-plaintext,.form-floating>.form-select{height:calc(3.5rem + calc(var(--bs-border-width) * 2));min-height:calc(3.5rem + calc(var(--bs-border-width) * 2));line-height:1.25}.form-floating>label{position:absolute;top:0;left:0;z-index:2;max-width:100%;height:100%;padding:1rem .75rem;overflow:hidden;color:rgba(var(--bs-body-color-rgb),.65);text-align:start;text-overflow:ellipsis;white-space:nowrap;pointer-events:none;border:var(--bs-border-width) solid transparent;transform-origin:0 0;transition:opacity .1s ease-in-out,transform .1s ease-in-out}@media (prefers-reduced-motion:reduce){.form-floating>label{transition:none}}.form-floating>.form-control,.form-floating>.form-control-plaintext{padding:1rem .75rem}.form-floating>.form-control-plaintext::placeholder,.form-floating>.form-control::placeholder{color:transparent}.form-floating>.form-control-plaintext:focus,.form-floating>.form-control-plaintext:not(:placeholder-shown),.form-floating>.form-control:focus,.form-floating>.form-control:not(:placeholder-shown){padding-top:1.625rem;padding-bottom:.625rem}.form-floating>.form-control-plaintext:-webkit-autofill,.form-floating>.form-control:-webkit-autofill{padding-top:1.625rem;padding-bottom:.625rem}.form-floating>.form-select{padding-top:1.625rem;padding-bottom:.625rem;padding-left:.75rem}.form-floating>.form-control-plaintext~label,.form-floating>.form-control:focus~label,.form-floating>.form-control:not(:placeholder-shown)~label,.form-floating>.form-select~label{transform:scale(.85) translateY(-.5rem) translateX(.15rem)}.form-floating>.form-control:-webkit-autofill~label{transform:scale(.85) translateY(-.5rem) translateX(.15rem)}.form-floating>textarea:focus~label::after,.form-floating>textarea:not(:placeholder-shown)~label::after{position:absolute;inset:1rem 0.375rem;z-index:-1;height:1.5em;content:"";background-color:var(--bs-body-bg);border-radius:var(--bs-border-radius)}.form-floating>textarea:disabled~label::after{background-color:var(--bs-secondary-bg)}.form-floating>.form-control-plaintext~label{border-width:var(--bs-border-width) 0}.form-floating>.form-control:disabled~label,.form-floating>:disabled~label{color:#6c757d}.input-group{position:relative;display:flex;flex-wrap:wrap;align-items:stretch;width:100%}.input-group>.form-control,.input-group>.form-floating,.input-group>.form-select{position:relative;flex:1 1 auto;width:1%;min-width:0}.input-group>.form-control:focus,.input-group>.form-floating:focus-within,.input-group>.form-select:focus{z-index:5}.input-group .btn{position:relative;z-index:2}.input-group .btn:focus{z-index:5}.input-group-text{display:flex;align-items:center;padding:.375rem .75rem;font-size:1rem;font-weight:400;line-height:1.5;color:var(--bs-body-color);text-align:center;white-space:nowrap;background-color:var(--bs-tertiary-bg);border:var(--bs-border-width) solid var(--bs-border-color);border-radius:var(--bs-border-radius)}.input-group-lg>.btn,.input-group-lg>.form-control,.input-group-lg>.form-select,.input-group-lg>.input-group-text{padding:.5rem 1rem;font-size:1.25rem;border-radius:var(--bs-border-radius-lg)}.input-group-sm>.btn,.input-group-sm>.form-control,.input-group-sm>.form-select,.input-group-sm>.input-group-text{padding:.25rem .5rem;font-size:.875rem;border-radius:var(--bs-border-radius-sm)}.input-group-lg>.form-select,.input-group-sm>.form-select{padding-right:3rem}.input-group:not(.has-validation)>.dropdown-toggle:nth-last-child(n+3),.input-group:not(.has-validation)>.form-floating:not(:last-child)>.form-control,.input-group:not(.has-validation)>.form-floating:not(:last-child)>.form-select,.input-group:not(.has-validation)>:not(:last-child):not(.dropdown-toggle):not(.dropdown-menu):not(.form-floating){border-top-right-radius:0;border-bottom-right-radius:0}.input-group.has-validation>.dropdown-toggle:nth-last-child(n+4),.input-group.has-validation>.form-floating:nth-last-child(n+3)>.form-control,.input-group.has-validation>.form-floating:nth-last-child(n+3)>.form-select,.input-group.has-validation>:nth-last-child(n+3):not(.dropdown-toggle):not(.dropdown-menu):not(.form-floating){border-top-right-radius:0;border-bottom-right-radius:0}.input-group>:not(:first-child):not(.dropdown-menu):not(.valid-tooltip):not(.valid-feedback):not(.invalid-tooltip):not(.invalid-feedback){margin-left:calc(-1 * var(--bs-border-width));border-top-left-radius:0;border-bottom-left-radius:0}.input-group>.form-floating:not(:first-child)>.form-control,.input-group>.form-floating:not(:first-child)>.form-select{border-top-left-radius:0;border-bottom-left-radius:0}.valid-feedback{display:none;width:100%;margin-top:.25rem;font-size:.875em;color:var(--bs-form-valid-color)}.valid-tooltip{position:absolute;top:100%;z-index:5;display:none;max-width:100%;padding:.25rem .5rem;margin-top:.1rem;font-size:.875rem;color:#fff;background-color:var(--bs-success);border-radius:var(--bs-border-radius)}.is-valid~.valid-feedback,.is-valid~.valid-tooltip,.was-validated :valid~.valid-feedback,.was-validated :valid~.valid-tooltip{display:block}.form-control.is-valid,.was-validated .form-control:valid{border-color:var(--bs-form-valid-border-color);padding-right:calc(1.5em + .75rem);background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3e%3cpath fill='%23198754' d='M2.3 6.73.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1'/%3e%3c/svg%3e");background-repeat:no-repeat;background-position:right calc(.375em + .1875rem) center;background-size:calc(.75em + .375rem) calc(.75em + .375rem)}.form-control.is-valid:focus,.was-validated .form-control:valid:focus{border-color:var(--bs-form-valid-border-color);box-shadow:0 0 0 .25rem rgba(var(--bs-success-rgb),.25)}.was-validated textarea.form-control:valid,textarea.form-control.is-valid{padding-right:calc(1.5em + .75rem);background-position:top calc(.375em + .1875rem) right calc(.375em + .1875rem)}.form-select.is-valid,.was-validated .form-select:valid{border-color:var(--bs-form-valid-border-color)}.form-select.is-valid:not([multiple]):not([size]),.form-select.is-valid:not([multiple])[size="1"],.was-validated .form-select:valid:not([multiple]):not([size]),.was-validated .form-select:valid:not([multiple])[size="1"]{--bs-form-select-bg-icon:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3e%3cpath fill='%23198754' d='M2.3 6.73.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1'/%3e%3c/svg%3e");padding-right:4.125rem;background-position:right .75rem center,center right 2.25rem;background-size:16px 12px,calc(.75em + .375rem) calc(.75em + .375rem)}.form-select.is-valid:focus,.was-validated .form-select:valid:focus{border-color:var(--bs-form-valid-border-color);box-shadow:0 0 0 .25rem rgba(var(--bs-success-rgb),.25)}.form-control-color.is-valid,.was-validated .form-control-color:valid{width:calc(3rem + calc(1.5em + .75rem))}.form-check-input.is-valid,.was-validated .form-check-input:valid{border-color:var(--bs-form-valid-border-color)}.form-check-input.is-valid:checked,.was-validated .form-check-input:valid:checked{background-color:var(--bs-form-valid-color)}.form-check-input.is-valid:focus,.was-validated .form-check-input:valid:focus{box-shadow:0 0 0 .25rem rgba(var(--bs-success-rgb),.25)}.form-check-input.is-valid~.form-check-label,.was-validated .form-check-input:valid~.form-check-label{color:var(--bs-form-valid-color)}.form-check-inline .form-check-input~.valid-feedback{margin-left:.5em}.input-group>.form-control:not(:focus).is-valid,.input-group>.form-floating:not(:focus-within).is-valid,.input-group>.form-select:not(:focus).is-valid,.was-validated .input-group>.form-control:not(:focus):valid,.was-validated .input-group>.form-floating:not(:focus-within):valid,.was-validated .input-group>.form-select:not(:focus):valid{z-index:3}.invalid-feedback{display:none;width:100%;margin-top:.25rem;font-size:.875em;color:var(--bs-form-invalid-color)}.invalid-tooltip{position:absolute;top:100%;z-index:5;display:none;max-width:100%;padding:.25rem .5rem;margin-top:.1rem;font-size:.875rem;color:#fff;background-color:var(--bs-danger);border-radius:var(--bs-border-radius)}.is-invalid~.invalid-feedback,.is-invalid~.invalid-tooltip,.was-validated :invalid~.invalid-feedback,.was-validated :invalid~.invalid-tooltip{display:block}.form-control.is-invalid,.was-validated .form-control:invalid{border-color:var(--bs-form-invalid-border-color);padding-right:calc(1.5em + .75rem);background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12' width='12' height='12' fill='none' stroke='%23dc3545'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%23dc3545' stroke='none'/%3e%3c/svg%3e");background-repeat:no-repeat;background-position:right calc(.375em + .1875rem) center;background-size:calc(.75em + .375rem) calc(.75em + .375rem)}.form-control.is-invalid:focus,.was-validated .form-control:invalid:focus{border-color:var(--bs-form-invalid-border-color);box-shadow:0 0 0 .25rem rgba(var(--bs-danger-rgb),.25)}.was-validated textarea.form-control:invalid,textarea.form-control.is-invalid{padding-right:calc(1.5em + .75rem);background-position:top calc(.375em + .1875rem) right calc(.375em + .1875rem)}.form-select.is-invalid,.was-validated .form-select:invalid{border-color:var(--bs-form-invalid-border-color)}.form-select.is-invalid:not([multiple]):not([size]),.form-select.is-invalid:not([multiple])[size="1"],.was-validated .form-select:invalid:not([multiple]):not([size]),.was-validated .form-select:invalid:not([multiple])[size="1"]{--bs-form-select-bg-icon:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12' width='12' height='12' fill='none' stroke='%23dc3545'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%23dc3545' stroke='none'/%3e%3c/svg%3e");padding-right:4.125rem;background-position:right .75rem center,center right 2.25rem;background-size:16px 12px,calc(.75em + .375rem) calc(.75em + .375rem)}.form-select.is-invalid:focus,.was-validated .form-select:invalid:focus{border-color:var(--bs-form-invalid-border-color);box-shadow:0 0 0 .25rem rgba(var(--bs-danger-rgb),.25)}.form-control-color.is-invalid,.was-validated .form-control-color:invalid{width:calc(3rem + calc(1.5em + .75rem))}.form-check-input.is-invalid,.was-validated .form-check-input:invalid{border-color:var(--bs-form-invalid-border-color)}.form-check-input.is-invalid:checked,.was-validated .form-check-input:invalid:checked{background-color:var(--bs-form-invalid-color)}.form-check-input.is-invalid:focus,.was-validated .form-check-input:invalid:focus{box-shadow:0 0 0 .25rem rgba(var(--bs-danger-rgb),.25)}.form-check-input.is-invalid~.form-check-label,.was-validated .form-check-input:invalid~.form-check-label{color:var(--bs-form-invalid-color)}.form-check-inline .form-check-input~.invalid-feedback{margin-left:.5em}.input-group>.form-control:not(:focus).is-invalid,.input-group>.form-floating:not(:focus-within).is-invalid,.input-group>.form-select:not(:focus).is-invalid,.was-validated .input-group>.form-control:not(:focus):invalid,.was-validated .input-group>.form-floating:not(:focus-within):invalid,.was-validated .input-group>.form-select:not(:focus):invalid{z-index:4}.btn{--bs-btn-padding-x:0.75rem;--bs-btn-padding-y:0.375rem;--bs-btn-font-family: ;--bs-btn-font-size:1rem;--bs-btn-font-weight:400;--bs-btn-line-height:1.5;--bs-btn-color:var(--bs-body-color);--bs-btn-bg:transparent;--bs-btn-border-width:var(--bs-border-width);--bs-btn-border-color:transparent;--bs-btn-border-radius:var(--bs-border-radius);--bs-btn-hover-border-color:transparent;--bs-btn-box-shadow:inset 0 1px 0 rgba(255, 255, 255, 0.15),0 1px 1px rgba(0, 0, 0, 0.075);--bs-btn-disabled-opacity:0.65;--bs-btn-focus-box-shadow:0 0 0 0.25rem rgba(var(--bs-btn-focus-shadow-rgb), .5);display:inline-block;padding:var(--bs-btn-padding-y) var(--bs-btn-padding-x);font-family:var(--bs-btn-font-family);font-size:var(--bs-btn-font-size);font-weight:var(--bs-btn-font-weight);line-height:var(--bs-btn-line-height);color:var(--bs-btn-color);text-align:center;text-decoration:none;vertical-align:middle;cursor:pointer;-webkit-user-select:none;-moz-user-select:none;user-select:none;border:var(--bs-btn-border-width) solid var(--bs-btn-border-color);border-radius:var(--bs-btn-border-radius);background-color:var(--bs-btn-bg);transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.btn{transition:none}}.btn:hover{color:var(--bs-btn-hover-color);background-color:var(--bs-btn-hover-bg);border-color:var(--bs-btn-hover-border-color)}.btn-check+.btn:hover{color:var(--bs-btn-color);background-color:var(--bs-btn-bg);border-color:var(--bs-btn-border-color)}.btn:focus-visible{color:var(--bs-btn-hover-color);background-color:var(--bs-btn-hover-bg);border-color:var(--bs-btn-hover-border-color);outline:0;box-shadow:var(--bs-btn-focus-box-shadow)}.btn-check:focus-visible+.btn{border-color:var(--bs-btn-hover-border-color);outline:0;box-shadow:var(--bs-btn-focus-box-shadow)}.btn-check:checked+.btn,.btn.active,.btn.show,.btn:first-child:active,:not(.btn-check)+.btn:active{color:var(--bs-btn-active-color);background-color:var(--bs-btn-active-bg);border-color:var(--bs-btn-active-border-color)}.btn-check:checked+.btn:focus-visible,.btn.active:focus-visible,.btn.show:focus-visible,.btn:first-child:active:focus-visible,:not(.btn-check)+.btn:active:focus-visible{box-shadow:var(--bs-btn-focus-box-shadow)}.btn-check:checked:focus-visible+.btn{box-shadow:var(--bs-btn-focus-box-shadow)}.btn.disabled,.btn:disabled,fieldset:disabled .btn{color:var(--bs-btn-disabled-color);pointer-events:none;background-color:var(--bs-btn-disabled-bg);border-color:var(--bs-btn-disabled-border-color);opacity:var(--bs-btn-disabled-opacity)}.btn-primary{--bs-btn-color:#fff;--bs-btn-bg:#0d6efd;--bs-btn-border-color:#0d6efd;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#0b5ed7;--bs-btn-hover-border-color:#0a58ca;--bs-btn-focus-shadow-rgb:49,132,253;--bs-btn-active-color:#fff;--bs-btn-active-bg:#0a58ca;--bs-btn-active-border-color:#0a53be;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#fff;--bs-btn-disabled-bg:#0d6efd;--bs-btn-disabled-border-color:#0d6efd}.btn-secondary{--bs-btn-color:#fff;--bs-btn-bg:#6c757d;--bs-btn-border-color:#6c757d;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#5c636a;--bs-btn-hover-border-color:#565e64;--bs-btn-focus-shadow-rgb:130,138,145;--bs-btn-active-color:#fff;--bs-btn-active-bg:#565e64;--bs-btn-active-border-color:#51585e;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#fff;--bs-btn-disabled-bg:#6c757d;--bs-btn-disabled-border-color:#6c757d}.btn-success{--bs-btn-color:#fff;--bs-btn-bg:#198754;--bs-btn-border-color:#198754;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#157347;--bs-btn-hover-border-color:#146c43;--bs-btn-focus-shadow-rgb:60,153,110;--bs-btn-active-color:#fff;--bs-btn-active-bg:#146c43;--bs-btn-active-border-color:#13653f;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#fff;--bs-btn-disabled-bg:#198754;--bs-btn-disabled-border-color:#198754}.btn-info{--bs-btn-color:#000;--bs-btn-bg:#0dcaf0;--bs-btn-border-color:#0dcaf0;--bs-btn-hover-color:#000;--bs-btn-hover-bg:#31d2f2;--bs-btn-hover-border-color:#25cff2;--bs-btn-focus-shadow-rgb:11,172,204;--bs-btn-active-color:#000;--bs-btn-active-bg:#3dd5f3;--bs-btn-active-border-color:#25cff2;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#000;--bs-btn-disabled-bg:#0dcaf0;--bs-btn-disabled-border-color:#0dcaf0}.btn-warning{--bs-btn-color:#000;--bs-btn-bg:#ffc107;--bs-btn-border-color:#ffc107;--bs-btn-hover-color:#000;--bs-btn-hover-bg:#ffca2c;--bs-btn-hover-border-color:#ffc720;--bs-btn-focus-shadow-rgb:217,164,6;--bs-btn-active-color:#000;--bs-btn-active-bg:#ffcd39;--bs-btn-active-border-color:#ffc720;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#000;--bs-btn-disabled-bg:#ffc107;--bs-btn-disabled-border-color:#ffc107}.btn-danger{--bs-btn-color:#fff;--bs-btn-bg:#dc3545;--bs-btn-border-color:#dc3545;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#bb2d3b;--bs-btn-hover-border-color:#b02a37;--bs-btn-focus-shadow-rgb:225,83,97;--bs-btn-active-color:#fff;--bs-btn-active-bg:#b02a37;--bs-btn-active-border-color:#a52834;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#fff;--bs-btn-disabled-bg:#dc3545;--bs-btn-disabled-border-color:#dc3545}.btn-light{--bs-btn-color:#000;--bs-btn-bg:#f8f9fa;--bs-btn-border-color:#f8f9fa;--bs-btn-hover-color:#000;--bs-btn-hover-bg:#d3d4d5;--bs-btn-hover-border-color:#c6c7c8;--bs-btn-focus-shadow-rgb:211,212,213;--bs-btn-active-color:#000;--bs-btn-active-bg:#c6c7c8;--bs-btn-active-border-color:#babbbc;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#000;--bs-btn-disabled-bg:#f8f9fa;--bs-btn-disabled-border-color:#f8f9fa}.btn-dark{--bs-btn-color:#fff;--bs-btn-bg:#212529;--bs-btn-border-color:#212529;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#424649;--bs-btn-hover-border-color:#373b3e;--bs-btn-focus-shadow-rgb:66,70,73;--bs-btn-active-color:#fff;--bs-btn-active-bg:#4d5154;--bs-btn-active-border-color:#373b3e;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#fff;--bs-btn-disabled-bg:#212529;--bs-btn-disabled-border-color:#212529}.btn-outline-primary{--bs-btn-color:#0d6efd;--bs-btn-border-color:#0d6efd;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#0d6efd;--bs-btn-hover-border-color:#0d6efd;--bs-btn-focus-shadow-rgb:13,110,253;--bs-btn-active-color:#fff;--bs-btn-active-bg:#0d6efd;--bs-btn-active-border-color:#0d6efd;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#0d6efd;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#0d6efd;--bs-gradient:none}.btn-outline-secondary{--bs-btn-color:#6c757d;--bs-btn-border-color:#6c757d;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#6c757d;--bs-btn-hover-border-color:#6c757d;--bs-btn-focus-shadow-rgb:108,117,125;--bs-btn-active-color:#fff;--bs-btn-active-bg:#6c757d;--bs-btn-active-border-color:#6c757d;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#6c757d;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#6c757d;--bs-gradient:none}.btn-outline-success{--bs-btn-color:#198754;--bs-btn-border-color:#198754;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#198754;--bs-btn-hover-border-color:#198754;--bs-btn-focus-shadow-rgb:25,135,84;--bs-btn-active-color:#fff;--bs-btn-active-bg:#198754;--bs-btn-active-border-color:#198754;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#198754;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#198754;--bs-gradient:none}.btn-outline-info{--bs-btn-color:#0dcaf0;--bs-btn-border-color:#0dcaf0;--bs-btn-hover-color:#000;--bs-btn-hover-bg:#0dcaf0;--bs-btn-hover-border-color:#0dcaf0;--bs-btn-focus-shadow-rgb:13,202,240;--bs-btn-active-color:#000;--bs-btn-active-bg:#0dcaf0;--bs-btn-active-border-color:#0dcaf0;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#0dcaf0;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#0dcaf0;--bs-gradient:none}.btn-outline-warning{--bs-btn-color:#ffc107;--bs-btn-border-color:#ffc107;--bs-btn-hover-color:#000;--bs-btn-hover-bg:#ffc107;--bs-btn-hover-border-color:#ffc107;--bs-btn-focus-shadow-rgb:255,193,7;--bs-btn-active-color:#000;--bs-btn-active-bg:#ffc107;--bs-btn-active-border-color:#ffc107;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#ffc107;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#ffc107;--bs-gradient:none}.btn-outline-danger{--bs-btn-color:#dc3545;--bs-btn-border-color:#dc3545;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#dc3545;--bs-btn-hover-border-color:#dc3545;--bs-btn-focus-shadow-rgb:220,53,69;--bs-btn-active-color:#fff;--bs-btn-active-bg:#dc3545;--bs-btn-active-border-color:#dc3545;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#dc3545;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#dc3545;--bs-gradient:none}.btn-outline-light{--bs-btn-color:#f8f9fa;--bs-btn-border-color:#f8f9fa;--bs-btn-hover-color:#000;--bs-btn-hover-bg:#f8f9fa;--bs-btn-hover-border-color:#f8f9fa;--bs-btn-focus-shadow-rgb:248,249,250;--bs-btn-active-color:#000;--bs-btn-active-bg:#f8f9fa;--bs-btn-active-border-color:#f8f9fa;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#f8f9fa;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#f8f9fa;--bs-gradient:none}.btn-outline-dark{--bs-btn-color:#212529;--bs-btn-border-color:#212529;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#212529;--bs-btn-hover-border-color:#212529;--bs-btn-focus-shadow-rgb:33,37,41;--bs-btn-active-color:#fff;--bs-btn-active-bg:#212529;--bs-btn-active-border-color:#212529;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#212529;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#212529;--bs-gradient:none}.btn-link{--bs-btn-font-weight:400;--bs-btn-color:var(--bs-link-color);--bs-btn-bg:transparent;--bs-btn-border-color:transparent;--bs-btn-hover-color:var(--bs-link-hover-color);--bs-btn-hover-border-color:transparent;--bs-btn-active-color:var(--bs-link-hover-color);--bs-btn-active-border-color:transparent;--bs-btn-disabled-color:#6c757d;--bs-btn-disabled-border-color:transparent;--bs-btn-box-shadow:0 0 0 #000;--bs-btn-focus-shadow-rgb:49,132,253;text-decoration:underline}.btn-link:focus-visible{color:var(--bs-btn-color)}.btn-link:hover{color:var(--bs-btn-hover-color)}.btn-group-lg>.btn,.btn-lg{--bs-btn-padding-y:0.5rem;--bs-btn-padding-x:1rem;--bs-btn-font-size:1.25rem;--bs-btn-border-radius:var(--bs-border-radius-lg)}.btn-group-sm>.btn,.btn-sm{--bs-btn-padding-y:0.25rem;--bs-btn-padding-x:0.5rem;--bs-btn-font-size:0.875rem;--bs-btn-border-radius:var(--bs-border-radius-sm)}.fade{transition:opacity .15s linear}@media (prefers-reduced-motion:reduce){.fade{transition:none}}.fade:not(.show){opacity:0}.collapse:not(.show){display:none}.collapsing{height:0;overflow:hidden;transition:height .35s ease}@media (prefers-reduced-motion:reduce){.collapsing{transition:none}}.collapsing.collapse-horizontal{width:0;height:auto;transition:width .35s ease}@media (prefers-reduced-motion:reduce){.collapsing.collapse-horizontal{transition:none}}.dropdown,.dropdown-center,.dropend,.dropstart,.dropup,.dropup-center{position:relative}.dropdown-toggle{white-space:nowrap}.dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:"";border-top:.3em solid;border-right:.3em solid transparent;border-bottom:0;border-left:.3em solid transparent}.dropdown-toggle:empty::after{margin-left:0}.dropdown-menu{--bs-dropdown-zindex:1000;--bs-dropdown-min-width:10rem;--bs-dropdown-padding-x:0;--bs-dropdown-padding-y:0.5rem;--bs-dropdown-spacer:0.125rem;--bs-dropdown-font-size:1rem;--bs-dropdown-color:var(--bs-body-color);--bs-dropdown-bg:var(--bs-body-bg);--bs-dropdown-border-color:var(--bs-border-color-translucent);--bs-dropdown-border-radius:var(--bs-border-radius);--bs-dropdown-border-width:var(--bs-border-width);--bs-dropdown-inner-border-radius:calc(var(--bs-border-radius) - var(--bs-border-width));--bs-dropdown-divider-bg:var(--bs-border-color-translucent);--bs-dropdown-divider-margin-y:0.5rem;--bs-dropdown-box-shadow:var(--bs-box-shadow);--bs-dropdown-link-color:var(--bs-body-color);--bs-dropdown-link-hover-color:var(--bs-body-color);--bs-dropdown-link-hover-bg:var(--bs-tertiary-bg);--bs-dropdown-link-active-color:#fff;--bs-dropdown-link-active-bg:#0d6efd;--bs-dropdown-link-disabled-color:var(--bs-tertiary-color);--bs-dropdown-item-padding-x:1rem;--bs-dropdown-item-padding-y:0.25rem;--bs-dropdown-header-color:#6c757d;--bs-dropdown-header-padding-x:1rem;--bs-dropdown-header-padding-y:0.5rem;position:absolute;z-index:var(--bs-dropdown-zindex);display:none;min-width:var(--bs-dropdown-min-width);padding:var(--bs-dropdown-padding-y) var(--bs-dropdown-padding-x);margin:0;font-size:var(--bs-dropdown-font-size);color:var(--bs-dropdown-color);text-align:left;list-style:none;background-color:var(--bs-dropdown-bg);background-clip:padding-box;border:var(--bs-dropdown-border-width) solid var(--bs-dropdown-border-color);border-radius:var(--bs-dropdown-border-radius)}.dropdown-menu[data-bs-popper]{top:100%;left:0;margin-top:var(--bs-dropdown-spacer)}.dropdown-menu-start{--bs-position:start}.dropdown-menu-start[data-bs-popper]{right:auto;left:0}.dropdown-menu-end{--bs-position:end}.dropdown-menu-end[data-bs-popper]{right:0;left:auto}@media (min-width:576px){.dropdown-menu-sm-start{--bs-position:start}.dropdown-menu-sm-start[data-bs-popper]{right:auto;left:0}.dropdown-menu-sm-end{--bs-position:end}.dropdown-menu-sm-end[data-bs-popper]{right:0;left:auto}}@media (min-width:768px){.dropdown-menu-md-start{--bs-position:start}.dropdown-menu-md-start[data-bs-popper]{right:auto;left:0}.dropdown-menu-md-end{--bs-position:end}.dropdown-menu-md-end[data-bs-popper]{right:0;left:auto}}@media (min-width:992px){.dropdown-menu-lg-start{--bs-position:start}.dropdown-menu-lg-start[data-bs-popper]{right:auto;left:0}.dropdown-menu-lg-end{--bs-position:end}.dropdown-menu-lg-end[data-bs-popper]{right:0;left:auto}}@media (min-width:1200px){.dropdown-menu-xl-start{--bs-position:start}.dropdown-menu-xl-start[data-bs-popper]{right:auto;left:0}.dropdown-menu-xl-end{--bs-position:end}.dropdown-menu-xl-end[data-bs-popper]{right:0;left:auto}}@media (min-width:1400px){.dropdown-menu-xxl-start{--bs-position:start}.dropdown-menu-xxl-start[data-bs-popper]{right:auto;left:0}.dropdown-menu-xxl-end{--bs-position:end}.dropdown-menu-xxl-end[data-bs-popper]{right:0;left:auto}}.dropup .dropdown-menu[data-bs-popper]{top:auto;bottom:100%;margin-top:0;margin-bottom:var(--bs-dropdown-spacer)}.dropup .dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:"";border-top:0;border-right:.3em solid transparent;border-bottom:.3em solid;border-left:.3em solid transparent}.dropup .dropdown-toggle:empty::after{margin-left:0}.dropend .dropdown-menu[data-bs-popper]{top:0;right:auto;left:100%;margin-top:0;margin-left:var(--bs-dropdown-spacer)}.dropend .dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:"";border-top:.3em solid transparent;border-right:0;border-bottom:.3em solid transparent;border-left:.3em solid}.dropend .dropdown-toggle:empty::after{margin-left:0}.dropend .dropdown-toggle::after{vertical-align:0}.dropstart .dropdown-menu[data-bs-popper]{top:0;right:100%;left:auto;margin-top:0;margin-right:var(--bs-dropdown-spacer)}.dropstart .dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:""}.dropstart .dropdown-toggle::after{display:none}.dropstart .dropdown-toggle::before{display:inline-block;margin-right:.255em;vertical-align:.255em;content:"";border-top:.3em solid transparent;border-right:.3em solid;border-bottom:.3em solid transparent}.dropstart .dropdown-toggle:empty::after{margin-left:0}.dropstart .dropdown-toggle::before{vertical-align:0}.dropdown-divider{height:0;margin:var(--bs-dropdown-divider-margin-y) 0;overflow:hidden;border-top:1px solid var(--bs-dropdown-divider-bg);opacity:1}.dropdown-item{display:block;width:100%;padding:var(--bs-dropdown-item-padding-y) var(--bs-dropdown-item-padding-x);clear:both;font-weight:400;color:var(--bs-dropdown-link-color);text-align:inherit;text-decoration:none;white-space:nowrap;background-color:transparent;border:0;border-radius:var(--bs-dropdown-item-border-radius,0)}.dropdown-item:focus,.dropdown-item:hover{color:var(--bs-dropdown-link-hover-color);background-color:var(--bs-dropdown-link-hover-bg)}.dropdown-item.active,.dropdown-item:active{color:var(--bs-dropdown-link-active-color);text-decoration:none;background-color:var(--bs-dropdown-link-active-bg)}.dropdown-item.disabled,.dropdown-item:disabled{color:var(--bs-dropdown-link-disabled-color);pointer-events:none;background-color:transparent}.dropdown-menu.show{display:block}.dropdown-header{display:block;padding:var(--bs-dropdown-header-padding-y) var(--bs-dropdown-header-padding-x);margin-bottom:0;font-size:.875rem;color:var(--bs-dropdown-header-color);white-space:nowrap}.dropdown-item-text{display:block;padding:var(--bs-dropdown-item-padding-y) var(--bs-dropdown-item-padding-x);color:var(--bs-dropdown-link-color)}.dropdown-menu-dark{--bs-dropdown-color:#dee2e6;--bs-dropdown-bg:#343a40;--bs-dropdown-border-color:var(--bs-border-color-translucent);--bs-dropdown-box-shadow: ;--bs-dropdown-link-color:#dee2e6;--bs-dropdown-link-hover-color:#fff;--bs-dropdown-divider-bg:var(--bs-border-color-translucent);--bs-dropdown-link-hover-bg:rgba(255, 255, 255, 0.15);--bs-dropdown-link-active-color:#fff;--bs-dropdown-link-active-bg:#0d6efd;--bs-dropdown-link-disabled-color:#adb5bd;--bs-dropdown-header-color:#adb5bd}.btn-group,.btn-group-vertical{position:relative;display:inline-flex;vertical-align:middle}.btn-group-vertical>.btn,.btn-group>.btn{position:relative;flex:1 1 auto}.btn-group-vertical>.btn-check:checked+.btn,.btn-group-vertical>.btn-check:focus+.btn,.btn-group-vertical>.btn.active,.btn-group-vertical>.btn:active,.btn-group-vertical>.btn:focus,.btn-group-vertical>.btn:hover,.btn-group>.btn-check:checked+.btn,.btn-group>.btn-check:focus+.btn,.btn-group>.btn.active,.btn-group>.btn:active,.btn-group>.btn:focus,.btn-group>.btn:hover{z-index:1}.btn-toolbar{display:flex;flex-wrap:wrap;justify-content:flex-start}.btn-toolbar .input-group{width:auto}.btn-group{border-radius:var(--bs-border-radius)}.btn-group>.btn-group:not(:first-child),.btn-group>:not(.btn-check:first-child)+.btn{margin-left:calc(-1 * var(--bs-border-width))}.btn-group>.btn-group:not(:last-child)>.btn,.btn-group>.btn.dropdown-toggle-split:first-child,.btn-group>.btn:not(:last-child):not(.dropdown-toggle){border-top-right-radius:0;border-bottom-right-radius:0}.btn-group>.btn-group:not(:first-child)>.btn,.btn-group>.btn:nth-child(n+3),.btn-group>:not(.btn-check)+.btn{border-top-left-radius:0;border-bottom-left-radius:0}.dropdown-toggle-split{padding-right:.5625rem;padding-left:.5625rem}.dropdown-toggle-split::after,.dropend .dropdown-toggle-split::after,.dropup .dropdown-toggle-split::after{margin-left:0}.dropstart .dropdown-toggle-split::before{margin-right:0}.btn-group-sm>.btn+.dropdown-toggle-split,.btn-sm+.dropdown-toggle-split{padding-right:.375rem;padding-left:.375rem}.btn-group-lg>.btn+.dropdown-toggle-split,.btn-lg+.dropdown-toggle-split{padding-right:.75rem;padding-left:.75rem}.btn-group-vertical{flex-direction:column;align-items:flex-start;justify-content:center}.btn-group-vertical>.btn,.btn-group-vertical>.btn-group{width:100%}.btn-group-vertical>.btn-group:not(:first-child),.btn-group-vertical>.btn:not(:first-child){margin-top:calc(-1 * var(--bs-border-width))}.btn-group-vertical>.btn-group:not(:last-child)>.btn,.btn-group-vertical>.btn:not(:last-child):not(.dropdown-toggle){border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn-group:not(:first-child)>.btn,.btn-group-vertical>.btn:nth-child(n+3),.btn-group-vertical>:not(.btn-check)+.btn{border-top-left-radius:0;border-top-right-radius:0}.nav{--bs-nav-link-padding-x:1rem;--bs-nav-link-padding-y:0.5rem;--bs-nav-link-font-weight: ;--bs-nav-link-color:var(--bs-link-color);--bs-nav-link-hover-color:var(--bs-link-hover-color);--bs-nav-link-disabled-color:var(--bs-secondary-color);display:flex;flex-wrap:wrap;padding-left:0;margin-bottom:0;list-style:none}.nav-link{display:block;padding:var(--bs-nav-link-padding-y) var(--bs-nav-link-padding-x);font-size:var(--bs-nav-link-font-size);font-weight:var(--bs-nav-link-font-weight);color:var(--bs-nav-link-color);text-decoration:none;background:0 0;border:0;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out}@media (prefers-reduced-motion:reduce){.nav-link{transition:none}}.nav-link:focus,.nav-link:hover{color:var(--bs-nav-link-hover-color)}.nav-link:focus-visible{outline:0;box-shadow:0 0 0 .25rem rgba(13,110,253,.25)}.nav-link.disabled,.nav-link:disabled{color:var(--bs-nav-link-disabled-color);pointer-events:none;cursor:default}.nav-tabs{--bs-nav-tabs-border-width:var(--bs-border-width);--bs-nav-tabs-border-color:var(--bs-border-color);--bs-nav-tabs-border-radius:var(--bs-border-radius);--bs-nav-tabs-link-hover-border-color:var(--bs-secondary-bg) var(--bs-secondary-bg) var(--bs-border-color);--bs-nav-tabs-link-active-color:var(--bs-emphasis-color);--bs-nav-tabs-link-active-bg:var(--bs-body-bg);--bs-nav-tabs-link-active-border-color:var(--bs-border-color) var(--bs-border-color) var(--bs-body-bg);border-bottom:var(--bs-nav-tabs-border-width) solid var(--bs-nav-tabs-border-color)}.nav-tabs .nav-link{margin-bottom:calc(-1 * var(--bs-nav-tabs-border-width));border:var(--bs-nav-tabs-border-width) solid transparent;border-top-left-radius:var(--bs-nav-tabs-border-radius);border-top-right-radius:var(--bs-nav-tabs-border-radius)}.nav-tabs .nav-link:focus,.nav-tabs .nav-link:hover{isolation:isolate;border-color:var(--bs-nav-tabs-link-hover-border-color)}.nav-tabs .nav-item.show .nav-link,.nav-tabs .nav-link.active{color:var(--bs-nav-tabs-link-active-color);background-color:var(--bs-nav-tabs-link-active-bg);border-color:var(--bs-nav-tabs-link-active-border-color)}.nav-tabs .dropdown-menu{margin-top:calc(-1 * var(--bs-nav-tabs-border-width));border-top-left-radius:0;border-top-right-radius:0}.nav-pills{--bs-nav-pills-border-radius:var(--bs-border-radius);--bs-nav-pills-link-active-color:#fff;--bs-nav-pills-link-active-bg:#0d6efd}.nav-pills .nav-link{border-radius:var(--bs-nav-pills-border-radius)}.nav-pills .nav-link.active,.nav-pills .show>.nav-link{color:var(--bs-nav-pills-link-active-color);background-color:var(--bs-nav-pills-link-active-bg)}.nav-underline{--bs-nav-underline-gap:1rem;--bs-nav-underline-border-width:0.125rem;--bs-nav-underline-link-active-color:var(--bs-emphasis-color);gap:var(--bs-nav-underline-gap)}.nav-underline .nav-link{padding-right:0;padding-left:0;border-bottom:var(--bs-nav-underline-border-width) solid transparent}.nav-underline .nav-link:focus,.nav-underline .nav-link:hover{border-bottom-color:currentcolor}.nav-underline .nav-link.active,.nav-underline .show>.nav-link{font-weight:700;color:var(--bs-nav-underline-link-active-color);border-bottom-color:currentcolor}.nav-fill .nav-item,.nav-fill>.nav-link{flex:1 1 auto;text-align:center}.nav-justified .nav-item,.nav-justified>.nav-link{flex-grow:1;flex-basis:0;text-align:center}.nav-fill .nav-item .nav-link,.nav-justified .nav-item .nav-link{width:100%}.tab-content>.tab-pane{display:none}.tab-content>.active{display:block}.navbar{--bs-navbar-padding-x:0;--bs-navbar-padding-y:0.5rem;--bs-navbar-color:rgba(var(--bs-emphasis-color-rgb), 0.65);--bs-navbar-hover-color:rgba(var(--bs-emphasis-color-rgb), 0.8);--bs-navbar-disabled-color:rgba(var(--bs-emphasis-color-rgb), 0.3);--bs-navbar-active-color:rgba(var(--bs-emphasis-color-rgb), 1);--bs-navbar-brand-padding-y:0.3125rem;--bs-navbar-brand-margin-end:1rem;--bs-navbar-brand-font-size:1.25rem;--bs-navbar-brand-color:rgba(var(--bs-emphasis-color-rgb), 1);--bs-navbar-brand-hover-color:rgba(var(--bs-emphasis-color-rgb), 1);--bs-navbar-nav-link-padding-x:0.5rem;--bs-navbar-toggler-padding-y:0.25rem;--bs-navbar-toggler-padding-x:0.75rem;--bs-navbar-toggler-font-size:1.25rem;--bs-navbar-toggler-icon-bg:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 30 30'%3e%3cpath stroke='rgba%2833, 37, 41, 0.75%29' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e");--bs-navbar-toggler-border-color:rgba(var(--bs-emphasis-color-rgb), 0.15);--bs-navbar-toggler-border-radius:var(--bs-border-radius);--bs-navbar-toggler-focus-width:0.25rem;--bs-navbar-toggler-transition:box-shadow 0.15s ease-in-out;position:relative;display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;padding:var(--bs-navbar-padding-y) var(--bs-navbar-padding-x)}.navbar>.container,.navbar>.container-fluid,.navbar>.container-lg,.navbar>.container-md,.navbar>.container-sm,.navbar>.container-xl,.navbar>.container-xxl{display:flex;flex-wrap:inherit;align-items:center;justify-content:space-between}.navbar-brand{padding-top:var(--bs-navbar-brand-padding-y);padding-bottom:var(--bs-navbar-brand-padding-y);margin-right:var(--bs-navbar-brand-margin-end);font-size:var(--bs-navbar-brand-font-size);color:var(--bs-navbar-brand-color);text-decoration:none;white-space:nowrap}.navbar-brand:focus,.navbar-brand:hover{color:var(--bs-navbar-brand-hover-color)}.navbar-nav{--bs-nav-link-padding-x:0;--bs-nav-link-padding-y:0.5rem;--bs-nav-link-font-weight: ;--bs-nav-link-color:var(--bs-navbar-color);--bs-nav-link-hover-color:var(--bs-navbar-hover-color);--bs-nav-link-disabled-color:var(--bs-navbar-disabled-color);display:flex;flex-direction:column;padding-left:0;margin-bottom:0;list-style:none}.navbar-nav .nav-link.active,.navbar-nav .nav-link.show{color:var(--bs-navbar-active-color)}.navbar-nav .dropdown-menu{position:static}.navbar-text{padding-top:.5rem;padding-bottom:.5rem;color:var(--bs-navbar-color)}.navbar-text a,.navbar-text a:focus,.navbar-text a:hover{color:var(--bs-navbar-active-color)}.navbar-collapse{flex-grow:1;flex-basis:100%;align-items:center}.navbar-toggler{padding:var(--bs-navbar-toggler-padding-y) var(--bs-navbar-toggler-padding-x);font-size:var(--bs-navbar-toggler-font-size);line-height:1;color:var(--bs-navbar-color);background-color:transparent;border:var(--bs-border-width) solid var(--bs-navbar-toggler-border-color);border-radius:var(--bs-navbar-toggler-border-radius);transition:var(--bs-navbar-toggler-transition)}@media (prefers-reduced-motion:reduce){.navbar-toggler{transition:none}}.navbar-toggler:hover{text-decoration:none}.navbar-toggler:focus{text-decoration:none;outline:0;box-shadow:0 0 0 var(--bs-navbar-toggler-focus-width)}.navbar-toggler-icon{display:inline-block;width:1.5em;height:1.5em;vertical-align:middle;background-image:var(--bs-navbar-toggler-icon-bg);background-repeat:no-repeat;background-position:center;background-size:100%}.navbar-nav-scroll{max-height:var(--bs-scroll-height,75vh);overflow-y:auto}@media (min-width:576px){.navbar-expand-sm{flex-wrap:nowrap;justify-content:flex-start}.navbar-expand-sm .navbar-nav{flex-direction:row}.navbar-expand-sm .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-sm .navbar-nav .nav-link{padding-right:var(--bs-navbar-nav-link-padding-x);padding-left:var(--bs-navbar-nav-link-padding-x)}.navbar-expand-sm .navbar-nav-scroll{overflow:visible}.navbar-expand-sm .navbar-collapse{display:flex!important;flex-basis:auto}.navbar-expand-sm .navbar-toggler{display:none}.navbar-expand-sm .offcanvas{position:static;z-index:auto;flex-grow:1;width:auto!important;height:auto!important;visibility:visible!important;background-color:transparent!important;border:0!important;transform:none!important;transition:none}.navbar-expand-sm .offcanvas .offcanvas-header{display:none}.navbar-expand-sm .offcanvas .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible}}@media (min-width:768px){.navbar-expand-md{flex-wrap:nowrap;justify-content:flex-start}.navbar-expand-md .navbar-nav{flex-direction:row}.navbar-expand-md .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-md .navbar-nav .nav-link{padding-right:var(--bs-navbar-nav-link-padding-x);padding-left:var(--bs-navbar-nav-link-padding-x)}.navbar-expand-md .navbar-nav-scroll{overflow:visible}.navbar-expand-md .navbar-collapse{display:flex!important;flex-basis:auto}.navbar-expand-md .navbar-toggler{display:none}.navbar-expand-md .offcanvas{position:static;z-index:auto;flex-grow:1;width:auto!important;height:auto!important;visibility:visible!important;background-color:transparent!important;border:0!important;transform:none!important;transition:none}.navbar-expand-md .offcanvas .offcanvas-header{display:none}.navbar-expand-md .offcanvas .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible}}@media (min-width:992px){.navbar-expand-lg{flex-wrap:nowrap;justify-content:flex-start}.navbar-expand-lg .navbar-nav{flex-direction:row}.navbar-expand-lg .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-lg .navbar-nav .nav-link{padding-right:var(--bs-navbar-nav-link-padding-x);padding-left:var(--bs-navbar-nav-link-padding-x)}.navbar-expand-lg .navbar-nav-scroll{overflow:visible}.navbar-expand-lg .navbar-collapse{display:flex!important;flex-basis:auto}.navbar-expand-lg .navbar-toggler{display:none}.navbar-expand-lg .offcanvas{position:static;z-index:auto;flex-grow:1;width:auto!important;height:auto!important;visibility:visible!important;background-color:transparent!important;border:0!important;transform:none!important;transition:none}.navbar-expand-lg .offcanvas .offcanvas-header{display:none}.navbar-expand-lg .offcanvas .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible}}@media (min-width:1200px){.navbar-expand-xl{flex-wrap:nowrap;justify-content:flex-start}.navbar-expand-xl .navbar-nav{flex-direction:row}.navbar-expand-xl .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-xl .navbar-nav .nav-link{padding-right:var(--bs-navbar-nav-link-padding-x);padding-left:var(--bs-navbar-nav-link-padding-x)}.navbar-expand-xl .navbar-nav-scroll{overflow:visible}.navbar-expand-xl .navbar-collapse{display:flex!important;flex-basis:auto}.navbar-expand-xl .navbar-toggler{display:none}.navbar-expand-xl .offcanvas{position:static;z-index:auto;flex-grow:1;width:auto!important;height:auto!important;visibility:visible!important;background-color:transparent!important;border:0!important;transform:none!important;transition:none}.navbar-expand-xl .offcanvas .offcanvas-header{display:none}.navbar-expand-xl .offcanvas .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible}}@media (min-width:1400px){.navbar-expand-xxl{flex-wrap:nowrap;justify-content:flex-start}.navbar-expand-xxl .navbar-nav{flex-direction:row}.navbar-expand-xxl .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-xxl .navbar-nav .nav-link{padding-right:var(--bs-navbar-nav-link-padding-x);padding-left:var(--bs-navbar-nav-link-padding-x)}.navbar-expand-xxl .navbar-nav-scroll{overflow:visible}.navbar-expand-xxl .navbar-collapse{display:flex!important;flex-basis:auto}.navbar-expand-xxl .navbar-toggler{display:none}.navbar-expand-xxl .offcanvas{position:static;z-index:auto;flex-grow:1;width:auto!important;height:auto!important;visibility:visible!important;background-color:transparent!important;border:0!important;transform:none!important;transition:none}.navbar-expand-xxl .offcanvas .offcanvas-header{display:none}.navbar-expand-xxl .offcanvas .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible}}.navbar-expand{flex-wrap:nowrap;justify-content:flex-start}.navbar-expand .navbar-nav{flex-direction:row}.navbar-expand .navbar-nav .dropdown-menu{position:absolute}.navbar-expand .navbar-nav .nav-link{padding-right:var(--bs-navbar-nav-link-padding-x);padding-left:var(--bs-navbar-nav-link-padding-x)}.navbar-expand .navbar-nav-scroll{overflow:visible}.navbar-expand .navbar-collapse{display:flex!important;flex-basis:auto}.navbar-expand .navbar-toggler{display:none}.navbar-expand .offcanvas{position:static;z-index:auto;flex-grow:1;width:auto!important;height:auto!important;visibility:visible!important;background-color:transparent!important;border:0!important;transform:none!important;transition:none}.navbar-expand .offcanvas .offcanvas-header{display:none}.navbar-expand .offcanvas .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible}.navbar-dark,.navbar[data-bs-theme=dark]{--bs-navbar-color:rgba(255, 255, 255, 0.55);--bs-navbar-hover-color:rgba(255, 255, 255, 0.75);--bs-navbar-disabled-color:rgba(255, 255, 255, 0.25);--bs-navbar-active-color:#fff;--bs-navbar-brand-color:#fff;--bs-navbar-brand-hover-color:#fff;--bs-navbar-toggler-border-color:rgba(255, 255, 255, 0.1);--bs-navbar-toggler-icon-bg:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 30 30'%3e%3cpath stroke='rgba%28255, 255, 255, 0.55%29' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e")}[data-bs-theme=dark] .navbar-toggler-icon{--bs-navbar-toggler-icon-bg:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 30 30'%3e%3cpath stroke='rgba%28255, 255, 255, 0.55%29' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e")}.card{--bs-card-spacer-y:1rem;--bs-card-spacer-x:1rem;--bs-card-title-spacer-y:0.5rem;--bs-card-title-color: ;--bs-card-subtitle-color: ;--bs-card-border-width:var(--bs-border-width);--bs-card-border-color:var(--bs-border-color-translucent);--bs-card-border-radius:var(--bs-border-radius);--bs-card-box-shadow: ;--bs-card-inner-border-radius:calc(var(--bs-border-radius) - (var(--bs-border-width)));--bs-card-cap-padding-y:0.5rem;--bs-card-cap-padding-x:1rem;--bs-card-cap-bg:rgba(var(--bs-body-color-rgb), 0.03);--bs-card-cap-color: ;--bs-card-height: ;--bs-card-color: ;--bs-card-bg:var(--bs-body-bg);--bs-card-img-overlay-padding:1rem;--bs-card-group-margin:0.75rem;position:relative;display:flex;flex-direction:column;min-width:0;height:var(--bs-card-height);color:var(--bs-body-color);word-wrap:break-word;background-color:var(--bs-card-bg);background-clip:border-box;border:var(--bs-card-border-width) solid var(--bs-card-border-color);border-radius:var(--bs-card-border-radius)}.card>hr{margin-right:0;margin-left:0}.card>.list-group{border-top:inherit;border-bottom:inherit}.card>.list-group:first-child{border-top-width:0;border-top-left-radius:var(--bs-card-inner-border-radius);border-top-right-radius:var(--bs-card-inner-border-radius)}.card>.list-group:last-child{border-bottom-width:0;border-bottom-right-radius:var(--bs-card-inner-border-radius);border-bottom-left-radius:var(--bs-card-inner-border-radius)}.card>.card-header+.list-group,.card>.list-group+.card-footer{border-top:0}.card-body{flex:1 1 auto;padding:var(--bs-card-spacer-y) var(--bs-card-spacer-x);color:var(--bs-card-color)}.card-title{margin-bottom:var(--bs-card-title-spacer-y);color:var(--bs-card-title-color)}.card-subtitle{margin-top:calc(-.5 * var(--bs-card-title-spacer-y));margin-bottom:0;color:var(--bs-card-subtitle-color)}.card-text:last-child{margin-bottom:0}.card-link+.card-link{margin-left:var(--bs-card-spacer-x)}.card-header{padding:var(--bs-card-cap-padding-y) var(--bs-card-cap-padding-x);margin-bottom:0;color:var(--bs-card-cap-color);background-color:var(--bs-card-cap-bg);border-bottom:var(--bs-card-border-width) solid var(--bs-card-border-color)}.card-header:first-child{border-radius:var(--bs-card-inner-border-radius) var(--bs-card-inner-border-radius) 0 0}.card-footer{padding:var(--bs-card-cap-padding-y) var(--bs-card-cap-padding-x);color:var(--bs-card-cap-color);background-color:var(--bs-card-cap-bg);border-top:var(--bs-card-border-width) solid var(--bs-card-border-color)}.card-footer:last-child{border-radius:0 0 var(--bs-card-inner-border-radius) var(--bs-card-inner-border-radius)}.card-header-tabs{margin-right:calc(-.5 * var(--bs-card-cap-padding-x));margin-bottom:calc(-1 * var(--bs-card-cap-padding-y));margin-left:calc(-.5 * var(--bs-card-cap-padding-x));border-bottom:0}.card-header-tabs .nav-link.active{background-color:var(--bs-card-bg);border-bottom-color:var(--bs-card-bg)}.card-header-pills{margin-right:calc(-.5 * var(--bs-card-cap-padding-x));margin-left:calc(-.5 * var(--bs-card-cap-padding-x))}.card-img-overlay{position:absolute;top:0;right:0;bottom:0;left:0;padding:var(--bs-card-img-overlay-padding);border-radius:var(--bs-card-inner-border-radius)}.card-img,.card-img-bottom,.card-img-top{width:100%}.card-img,.card-img-top{border-top-left-radius:var(--bs-card-inner-border-radius);border-top-right-radius:var(--bs-card-inner-border-radius)}.card-img,.card-img-bottom{border-bottom-right-radius:var(--bs-card-inner-border-radius);border-bottom-left-radius:var(--bs-card-inner-border-radius)}.card-group>.card{margin-bottom:var(--bs-card-group-margin)}@media (min-width:576px){.card-group{display:flex;flex-flow:row wrap}.card-group>.card{flex:1 0 0;margin-bottom:0}.card-group>.card+.card{margin-left:0;border-left:0}.card-group>.card:not(:last-child){border-top-right-radius:0;border-bottom-right-radius:0}.card-group>.card:not(:last-child)>.card-header,.card-group>.card:not(:last-child)>.card-img-top{border-top-right-radius:0}.card-group>.card:not(:last-child)>.card-footer,.card-group>.card:not(:last-child)>.card-img-bottom{border-bottom-right-radius:0}.card-group>.card:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0}.card-group>.card:not(:first-child)>.card-header,.card-group>.card:not(:first-child)>.card-img-top{border-top-left-radius:0}.card-group>.card:not(:first-child)>.card-footer,.card-group>.card:not(:first-child)>.card-img-bottom{border-bottom-left-radius:0}}.accordion{--bs-accordion-color:var(--bs-body-color);--bs-accordion-bg:var(--bs-body-bg);--bs-accordion-transition:color 0.15s ease-in-out,background-color 0.15s ease-in-out,border-color 0.15s ease-in-out,box-shadow 0.15s ease-in-out,border-radius 0.15s ease;--bs-accordion-border-color:var(--bs-border-color);--bs-accordion-border-width:var(--bs-border-width);--bs-accordion-border-radius:var(--bs-border-radius);--bs-accordion-inner-border-radius:calc(var(--bs-border-radius) - (var(--bs-border-width)));--bs-accordion-btn-padding-x:1.25rem;--bs-accordion-btn-padding-y:1rem;--bs-accordion-btn-color:var(--bs-body-color);--bs-accordion-btn-bg:var(--bs-accordion-bg);--bs-accordion-btn-icon:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='%23212529' stroke-linecap='round' stroke-linejoin='round'%3e%3cpath d='m2 5 6 6 6-6'/%3e%3c/svg%3e");--bs-accordion-btn-icon-width:1.25rem;--bs-accordion-btn-icon-transform:rotate(-180deg);--bs-accordion-btn-icon-transition:transform 0.2s ease-in-out;--bs-accordion-btn-active-icon:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='%23052c65' stroke-linecap='round' stroke-linejoin='round'%3e%3cpath d='m2 5 6 6 6-6'/%3e%3c/svg%3e");--bs-accordion-btn-focus-box-shadow:0 0 0 0.25rem rgba(13, 110, 253, 0.25);--bs-accordion-body-padding-x:1.25rem;--bs-accordion-body-padding-y:1rem;--bs-accordion-active-color:var(--bs-primary-text-emphasis);--bs-accordion-active-bg:var(--bs-primary-bg-subtle)}.accordion-button{position:relative;display:flex;align-items:center;width:100%;padding:var(--bs-accordion-btn-padding-y) var(--bs-accordion-btn-padding-x);font-size:1rem;color:var(--bs-accordion-btn-color);text-align:left;background-color:var(--bs-accordion-btn-bg);border:0;border-radius:0;overflow-anchor:none;transition:var(--bs-accordion-transition)}@media (prefers-reduced-motion:reduce){.accordion-button{transition:none}}.accordion-button:not(.collapsed){color:var(--bs-accordion-active-color);background-color:var(--bs-accordion-active-bg);box-shadow:inset 0 calc(-1 * var(--bs-accordion-border-width)) 0 var(--bs-accordion-border-color)}.accordion-button:not(.collapsed)::after{background-image:var(--bs-accordion-btn-active-icon);transform:var(--bs-accordion-btn-icon-transform)}.accordion-button::after{flex-shrink:0;width:var(--bs-accordion-btn-icon-width);height:var(--bs-accordion-btn-icon-width);margin-left:auto;content:"";background-image:var(--bs-accordion-btn-icon);background-repeat:no-repeat;background-size:var(--bs-accordion-btn-icon-width);transition:var(--bs-accordion-btn-icon-transition)}@media (prefers-reduced-motion:reduce){.accordion-button::after{transition:none}}.accordion-button:hover{z-index:2}.accordion-button:focus{z-index:3;outline:0;box-shadow:var(--bs-accordion-btn-focus-box-shadow)}.accordion-header{margin-bottom:0}.accordion-item{color:var(--bs-accordion-color);background-color:var(--bs-accordion-bg);border:var(--bs-accordion-border-width) solid var(--bs-accordion-border-color)}.accordion-item:first-of-type{border-top-left-radius:var(--bs-accordion-border-radius);border-top-right-radius:var(--bs-accordion-border-radius)}.accordion-item:first-of-type>.accordion-header .accordion-button{border-top-left-radius:var(--bs-accordion-inner-border-radius);border-top-right-radius:var(--bs-accordion-inner-border-radius)}.accordion-item:not(:first-of-type){border-top:0}.accordion-item:last-of-type{border-bottom-right-radius:var(--bs-accordion-border-radius);border-bottom-left-radius:var(--bs-accordion-border-radius)}.accordion-item:last-of-type>.accordion-header .accordion-button.collapsed{border-bottom-right-radius:var(--bs-accordion-inner-border-radius);border-bottom-left-radius:var(--bs-accordion-inner-border-radius)}.accordion-item:last-of-type>.accordion-collapse{border-bottom-right-radius:var(--bs-accordion-border-radius);border-bottom-left-radius:var(--bs-accordion-border-radius)}.accordion-body{padding:var(--bs-accordion-body-padding-y) var(--bs-accordion-body-padding-x)}.accordion-flush>.accordion-item{border-right:0;border-left:0;border-radius:0}.accordion-flush>.accordion-item:first-child{border-top:0}.accordion-flush>.accordion-item:last-child{border-bottom:0}.accordion-flush>.accordion-item>.accordion-collapse,.accordion-flush>.accordion-item>.accordion-header .accordion-button,.accordion-flush>.accordion-item>.accordion-header .accordion-button.collapsed{border-radius:0}[data-bs-theme=dark] .accordion-button::after{--bs-accordion-btn-icon:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%236ea8fe'%3e%3cpath fill-rule='evenodd' d='M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708'/%3e%3c/svg%3e");--bs-accordion-btn-active-icon:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%236ea8fe'%3e%3cpath fill-rule='evenodd' d='M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708'/%3e%3c/svg%3e")}.breadcrumb{--bs-breadcrumb-padding-x:0;--bs-breadcrumb-padding-y:0;--bs-breadcrumb-margin-bottom:1rem;--bs-breadcrumb-bg: ;--bs-breadcrumb-border-radius: ;--bs-breadcrumb-divider-color:var(--bs-secondary-color);--bs-breadcrumb-item-padding-x:0.5rem;--bs-breadcrumb-item-active-color:var(--bs-secondary-color);display:flex;flex-wrap:wrap;padding:var(--bs-breadcrumb-padding-y) var(--bs-breadcrumb-padding-x);margin-bottom:var(--bs-breadcrumb-margin-bottom);font-size:var(--bs-breadcrumb-font-size);list-style:none;background-color:var(--bs-breadcrumb-bg);border-radius:var(--bs-breadcrumb-border-radius)}.breadcrumb-item+.breadcrumb-item{padding-left:var(--bs-breadcrumb-item-padding-x)}.breadcrumb-item+.breadcrumb-item::before{float:left;padding-right:var(--bs-breadcrumb-item-padding-x);color:var(--bs-breadcrumb-divider-color);content:var(--bs-breadcrumb-divider, "/")}.breadcrumb-item.active{color:var(--bs-breadcrumb-item-active-color)}.pagination{--bs-pagination-padding-x:0.75rem;--bs-pagination-padding-y:0.375rem;--bs-pagination-font-size:1rem;--bs-pagination-color:var(--bs-link-color);--bs-pagination-bg:var(--bs-body-bg);--bs-pagination-border-width:var(--bs-border-width);--bs-pagination-border-color:var(--bs-border-color);--bs-pagination-border-radius:var(--bs-border-radius);--bs-pagination-hover-color:var(--bs-link-hover-color);--bs-pagination-hover-bg:var(--bs-tertiary-bg);--bs-pagination-hover-border-color:var(--bs-border-color);--bs-pagination-focus-color:var(--bs-link-hover-color);--bs-pagination-focus-bg:var(--bs-secondary-bg);--bs-pagination-focus-box-shadow:0 0 0 0.25rem rgba(13, 110, 253, 0.25);--bs-pagination-active-color:#fff;--bs-pagination-active-bg:#0d6efd;--bs-pagination-active-border-color:#0d6efd;--bs-pagination-disabled-color:var(--bs-secondary-color);--bs-pagination-disabled-bg:var(--bs-secondary-bg);--bs-pagination-disabled-border-color:var(--bs-border-color);display:flex;padding-left:0;list-style:none}.page-link{position:relative;display:block;padding:var(--bs-pagination-padding-y) var(--bs-pagination-padding-x);font-size:var(--bs-pagination-font-size);color:var(--bs-pagination-color);text-decoration:none;background-color:var(--bs-pagination-bg);border:var(--bs-pagination-border-width) solid var(--bs-pagination-border-color);transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.page-link{transition:none}}.page-link:hover{z-index:2;color:var(--bs-pagination-hover-color);background-color:var(--bs-pagination-hover-bg);border-color:var(--bs-pagination-hover-border-color)}.page-link:focus{z-index:3;color:var(--bs-pagination-focus-color);background-color:var(--bs-pagination-focus-bg);outline:0;box-shadow:var(--bs-pagination-focus-box-shadow)}.active>.page-link,.page-link.active{z-index:3;color:var(--bs-pagination-active-color);background-color:var(--bs-pagination-active-bg);border-color:var(--bs-pagination-active-border-color)}.disabled>.page-link,.page-link.disabled{color:var(--bs-pagination-disabled-color);pointer-events:none;background-color:var(--bs-pagination-disabled-bg);border-color:var(--bs-pagination-disabled-border-color)}.page-item:not(:first-child) .page-link{margin-left:calc(-1 * var(--bs-border-width))}.page-item:first-child .page-link{border-top-left-radius:var(--bs-pagination-border-radius);border-bottom-left-radius:var(--bs-pagination-border-radius)}.page-item:last-child .page-link{border-top-right-radius:var(--bs-pagination-border-radius);border-bottom-right-radius:var(--bs-pagination-border-radius)}.pagination-lg{--bs-pagination-padding-x:1.5rem;--bs-pagination-padding-y:0.75rem;--bs-pagination-font-size:1.25rem;--bs-pagination-border-radius:var(--bs-border-radius-lg)}.pagination-sm{--bs-pagination-padding-x:0.5rem;--bs-pagination-padding-y:0.25rem;--bs-pagination-font-size:0.875rem;--bs-pagination-border-radius:var(--bs-border-radius-sm)}.badge{--bs-badge-padding-x:0.65em;--bs-badge-padding-y:0.35em;--bs-badge-font-size:0.75em;--bs-badge-font-weight:700;--bs-badge-color:#fff;--bs-badge-border-radius:var(--bs-border-radius);display:inline-block;padding:var(--bs-badge-padding-y) var(--bs-badge-padding-x);font-size:var(--bs-badge-font-size);font-weight:var(--bs-badge-font-weight);line-height:1;color:var(--bs-badge-color);text-align:center;white-space:nowrap;vertical-align:baseline;border-radius:var(--bs-badge-border-radius)}.badge:empty{display:none}.btn .badge{position:relative;top:-1px}.alert{--bs-alert-bg:transparent;--bs-alert-padding-x:1rem;--bs-alert-padding-y:1rem;--bs-alert-margin-bottom:1rem;--bs-alert-color:inherit;--bs-alert-border-color:transparent;--bs-alert-border:var(--bs-border-width) solid var(--bs-alert-border-color);--bs-alert-border-radius:var(--bs-border-radius);--bs-alert-link-color:inherit;position:relative;padding:var(--bs-alert-padding-y) var(--bs-alert-padding-x);margin-bottom:var(--bs-alert-margin-bottom);color:var(--bs-alert-color);background-color:var(--bs-alert-bg);border:var(--bs-alert-border);border-radius:var(--bs-alert-border-radius)}.alert-heading{color:inherit}.alert-link{font-weight:700;color:var(--bs-alert-link-color)}.alert-dismissible{padding-right:3rem}.alert-dismissible .btn-close{position:absolute;top:0;right:0;z-index:2;padding:1.25rem 1rem}.alert-primary{--bs-alert-color:var(--bs-primary-text-emphasis);--bs-alert-bg:var(--bs-primary-bg-subtle);--bs-alert-border-color:var(--bs-primary-border-subtle);--bs-alert-link-color:var(--bs-primary-text-emphasis)}.alert-secondary{--bs-alert-color:var(--bs-secondary-text-emphasis);--bs-alert-bg:var(--bs-secondary-bg-subtle);--bs-alert-border-color:var(--bs-secondary-border-subtle);--bs-alert-link-color:var(--bs-secondary-text-emphasis)}.alert-success{--bs-alert-color:var(--bs-success-text-emphasis);--bs-alert-bg:var(--bs-success-bg-subtle);--bs-alert-border-color:var(--bs-success-border-subtle);--bs-alert-link-color:var(--bs-success-text-emphasis)}.alert-info{--bs-alert-color:var(--bs-info-text-emphasis);--bs-alert-bg:var(--bs-info-bg-subtle);--bs-alert-border-color:var(--bs-info-border-subtle);--bs-alert-link-color:var(--bs-info-text-emphasis)}.alert-warning{--bs-alert-color:var(--bs-warning-text-emphasis);--bs-alert-bg:var(--bs-warning-bg-subtle);--bs-alert-border-color:var(--bs-warning-border-subtle);--bs-alert-link-color:var(--bs-warning-text-emphasis)}.alert-danger{--bs-alert-color:var(--bs-danger-text-emphasis);--bs-alert-bg:var(--bs-danger-bg-subtle);--bs-alert-border-color:var(--bs-danger-border-subtle);--bs-alert-link-color:var(--bs-danger-text-emphasis)}.alert-light{--bs-alert-color:var(--bs-light-text-emphasis);--bs-alert-bg:var(--bs-light-bg-subtle);--bs-alert-border-color:var(--bs-light-border-subtle);--bs-alert-link-color:var(--bs-light-text-emphasis)}.alert-dark{--bs-alert-color:var(--bs-dark-text-emphasis);--bs-alert-bg:var(--bs-dark-bg-subtle);--bs-alert-border-color:var(--bs-dark-border-subtle);--bs-alert-link-color:var(--bs-dark-text-emphasis)}@keyframes progress-bar-stripes{0%{background-position-x:var(--bs-progress-height)}}.progress,.progress-stacked{--bs-progress-height:1rem;--bs-progress-font-size:0.75rem;--bs-progress-bg:var(--bs-secondary-bg);--bs-progress-border-radius:var(--bs-border-radius);--bs-progress-box-shadow:var(--bs-box-shadow-inset);--bs-progress-bar-color:#fff;--bs-progress-bar-bg:#0d6efd;--bs-progress-bar-transition:width 0.6s ease;display:flex;height:var(--bs-progress-height);overflow:hidden;font-size:var(--bs-progress-font-size);background-color:var(--bs-progress-bg);border-radius:var(--bs-progress-border-radius)}.progress-bar{display:flex;flex-direction:column;justify-content:center;overflow:hidden;color:var(--bs-progress-bar-color);text-align:center;white-space:nowrap;background-color:var(--bs-progress-bar-bg);transition:var(--bs-progress-bar-transition)}@media (prefers-reduced-motion:reduce){.progress-bar{transition:none}}.progress-bar-striped{background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-size:var(--bs-progress-height) var(--bs-progress-height)}.progress-stacked>.progress{overflow:visible}.progress-stacked>.progress>.progress-bar{width:100%}.progress-bar-animated{animation:1s linear infinite progress-bar-stripes}@media (prefers-reduced-motion:reduce){.progress-bar-animated{animation:none}}.list-group{--bs-list-group-color:var(--bs-body-color);--bs-list-group-bg:var(--bs-body-bg);--bs-list-group-border-color:var(--bs-border-color);--bs-list-group-border-width:var(--bs-border-width);--bs-list-group-border-radius:var(--bs-border-radius);--bs-list-group-item-padding-x:1rem;--bs-list-group-item-padding-y:0.5rem;--bs-list-group-action-color:var(--bs-secondary-color);--bs-list-group-action-hover-color:var(--bs-emphasis-color);--bs-list-group-action-hover-bg:var(--bs-tertiary-bg);--bs-list-group-action-active-color:var(--bs-body-color);--bs-list-group-action-active-bg:var(--bs-secondary-bg);--bs-list-group-disabled-color:var(--bs-secondary-color);--bs-list-group-disabled-bg:var(--bs-body-bg);--bs-list-group-active-color:#fff;--bs-list-group-active-bg:#0d6efd;--bs-list-group-active-border-color:#0d6efd;display:flex;flex-direction:column;padding-left:0;margin-bottom:0;border-radius:var(--bs-list-group-border-radius)}.list-group-numbered{list-style-type:none;counter-reset:section}.list-group-numbered>.list-group-item::before{content:counters(section, ".") ". ";counter-increment:section}.list-group-item{position:relative;display:block;padding:var(--bs-list-group-item-padding-y) var(--bs-list-group-item-padding-x);color:var(--bs-list-group-color);text-decoration:none;background-color:var(--bs-list-group-bg);border:var(--bs-list-group-border-width) solid var(--bs-list-group-border-color)}.list-group-item:first-child{border-top-left-radius:inherit;border-top-right-radius:inherit}.list-group-item:last-child{border-bottom-right-radius:inherit;border-bottom-left-radius:inherit}.list-group-item.disabled,.list-group-item:disabled{color:var(--bs-list-group-disabled-color);pointer-events:none;background-color:var(--bs-list-group-disabled-bg)}.list-group-item.active{z-index:2;color:var(--bs-list-group-active-color);background-color:var(--bs-list-group-active-bg);border-color:var(--bs-list-group-active-border-color)}.list-group-item+.list-group-item{border-top-width:0}.list-group-item+.list-group-item.active{margin-top:calc(-1 * var(--bs-list-group-border-width));border-top-width:var(--bs-list-group-border-width)}.list-group-item-action{width:100%;color:var(--bs-list-group-action-color);text-align:inherit}.list-group-item-action:not(.active):focus,.list-group-item-action:not(.active):hover{z-index:1;color:var(--bs-list-group-action-hover-color);text-decoration:none;background-color:var(--bs-list-group-action-hover-bg)}.list-group-item-action:not(.active):active{color:var(--bs-list-group-action-active-color);background-color:var(--bs-list-group-action-active-bg)}.list-group-horizontal{flex-direction:row}.list-group-horizontal>.list-group-item:first-child:not(:last-child){border-bottom-left-radius:var(--bs-list-group-border-radius);border-top-right-radius:0}.list-group-horizontal>.list-group-item:last-child:not(:first-child){border-top-right-radius:var(--bs-list-group-border-radius);border-bottom-left-radius:0}.list-group-horizontal>.list-group-item.active{margin-top:0}.list-group-horizontal>.list-group-item+.list-group-item{border-top-width:var(--bs-list-group-border-width);border-left-width:0}.list-group-horizontal>.list-group-item+.list-group-item.active{margin-left:calc(-1 * var(--bs-list-group-border-width));border-left-width:var(--bs-list-group-border-width)}@media (min-width:576px){.list-group-horizontal-sm{flex-direction:row}.list-group-horizontal-sm>.list-group-item:first-child:not(:last-child){border-bottom-left-radius:var(--bs-list-group-border-radius);border-top-right-radius:0}.list-group-horizontal-sm>.list-group-item:last-child:not(:first-child){border-top-right-radius:var(--bs-list-group-border-radius);border-bottom-left-radius:0}.list-group-horizontal-sm>.list-group-item.active{margin-top:0}.list-group-horizontal-sm>.list-group-item+.list-group-item{border-top-width:var(--bs-list-group-border-width);border-left-width:0}.list-group-horizontal-sm>.list-group-item+.list-group-item.active{margin-left:calc(-1 * var(--bs-list-group-border-width));border-left-width:var(--bs-list-group-border-width)}}@media (min-width:768px){.list-group-horizontal-md{flex-direction:row}.list-group-horizontal-md>.list-group-item:first-child:not(:last-child){border-bottom-left-radius:var(--bs-list-group-border-radius);border-top-right-radius:0}.list-group-horizontal-md>.list-group-item:last-child:not(:first-child){border-top-right-radius:var(--bs-list-group-border-radius);border-bottom-left-radius:0}.list-group-horizontal-md>.list-group-item.active{margin-top:0}.list-group-horizontal-md>.list-group-item+.list-group-item{border-top-width:var(--bs-list-group-border-width);border-left-width:0}.list-group-horizontal-md>.list-group-item+.list-group-item.active{margin-left:calc(-1 * var(--bs-list-group-border-width));border-left-width:var(--bs-list-group-border-width)}}@media (min-width:992px){.list-group-horizontal-lg{flex-direction:row}.list-group-horizontal-lg>.list-group-item:first-child:not(:last-child){border-bottom-left-radius:var(--bs-list-group-border-radius);border-top-right-radius:0}.list-group-horizontal-lg>.list-group-item:last-child:not(:first-child){border-top-right-radius:var(--bs-list-group-border-radius);border-bottom-left-radius:0}.list-group-horizontal-lg>.list-group-item.active{margin-top:0}.list-group-horizontal-lg>.list-group-item+.list-group-item{border-top-width:var(--bs-list-group-border-width);border-left-width:0}.list-group-horizontal-lg>.list-group-item+.list-group-item.active{margin-left:calc(-1 * var(--bs-list-group-border-width));border-left-width:var(--bs-list-group-border-width)}}@media (min-width:1200px){.list-group-horizontal-xl{flex-direction:row}.list-group-horizontal-xl>.list-group-item:first-child:not(:last-child){border-bottom-left-radius:var(--bs-list-group-border-radius);border-top-right-radius:0}.list-group-horizontal-xl>.list-group-item:last-child:not(:first-child){border-top-right-radius:var(--bs-list-group-border-radius);border-bottom-left-radius:0}.list-group-horizontal-xl>.list-group-item.active{margin-top:0}.list-group-horizontal-xl>.list-group-item+.list-group-item{border-top-width:var(--bs-list-group-border-width);border-left-width:0}.list-group-horizontal-xl>.list-group-item+.list-group-item.active{margin-left:calc(-1 * var(--bs-list-group-border-width));border-left-width:var(--bs-list-group-border-width)}}@media (min-width:1400px){.list-group-horizontal-xxl{flex-direction:row}.list-group-horizontal-xxl>.list-group-item:first-child:not(:last-child){border-bottom-left-radius:var(--bs-list-group-border-radius);border-top-right-radius:0}.list-group-horizontal-xxl>.list-group-item:last-child:not(:first-child){border-top-right-radius:var(--bs-list-group-border-radius);border-bottom-left-radius:0}.list-group-horizontal-xxl>.list-group-item.active{margin-top:0}.list-group-horizontal-xxl>.list-group-item+.list-group-item{border-top-width:var(--bs-list-group-border-width);border-left-width:0}.list-group-horizontal-xxl>.list-group-item+.list-group-item.active{margin-left:calc(-1 * var(--bs-list-group-border-width));border-left-width:var(--bs-list-group-border-width)}}.list-group-flush{border-radius:0}.list-group-flush>.list-group-item{border-width:0 0 var(--bs-list-group-border-width)}.list-group-flush>.list-group-item:last-child{border-bottom-width:0}.list-group-item-primary{--bs-list-group-color:var(--bs-primary-text-emphasis);--bs-list-group-bg:var(--bs-primary-bg-subtle);--bs-list-group-border-color:var(--bs-primary-border-subtle);--bs-list-group-action-hover-color:var(--bs-emphasis-color);--bs-list-group-action-hover-bg:var(--bs-primary-border-subtle);--bs-list-group-action-active-color:var(--bs-emphasis-color);--bs-list-group-action-active-bg:var(--bs-primary-border-subtle);--bs-list-group-active-color:var(--bs-primary-bg-subtle);--bs-list-group-active-bg:var(--bs-primary-text-emphasis);--bs-list-group-active-border-color:var(--bs-primary-text-emphasis)}.list-group-item-secondary{--bs-list-group-color:var(--bs-secondary-text-emphasis);--bs-list-group-bg:var(--bs-secondary-bg-subtle);--bs-list-group-border-color:var(--bs-secondary-border-subtle);--bs-list-group-action-hover-color:var(--bs-emphasis-color);--bs-list-group-action-hover-bg:var(--bs-secondary-border-subtle);--bs-list-group-action-active-color:var(--bs-emphasis-color);--bs-list-group-action-active-bg:var(--bs-secondary-border-subtle);--bs-list-group-active-color:var(--bs-secondary-bg-subtle);--bs-list-group-active-bg:var(--bs-secondary-text-emphasis);--bs-list-group-active-border-color:var(--bs-secondary-text-emphasis)}.list-group-item-success{--bs-list-group-color:var(--bs-success-text-emphasis);--bs-list-group-bg:var(--bs-success-bg-subtle);--bs-list-group-border-color:var(--bs-success-border-subtle);--bs-list-group-action-hover-color:var(--bs-emphasis-color);--bs-list-group-action-hover-bg:var(--bs-success-border-subtle);--bs-list-group-action-active-color:var(--bs-emphasis-color);--bs-list-group-action-active-bg:var(--bs-success-border-subtle);--bs-list-group-active-color:var(--bs-success-bg-subtle);--bs-list-group-active-bg:var(--bs-success-text-emphasis);--bs-list-group-active-border-color:var(--bs-success-text-emphasis)}.list-group-item-info{--bs-list-group-color:var(--bs-info-text-emphasis);--bs-list-group-bg:var(--bs-info-bg-subtle);--bs-list-group-border-color:var(--bs-info-border-subtle);--bs-list-group-action-hover-color:var(--bs-emphasis-color);--bs-list-group-action-hover-bg:var(--bs-info-border-subtle);--bs-list-group-action-active-color:var(--bs-emphasis-color);--bs-list-group-action-active-bg:var(--bs-info-border-subtle);--bs-list-group-active-color:var(--bs-info-bg-subtle);--bs-list-group-active-bg:var(--bs-info-text-emphasis);--bs-list-group-active-border-color:var(--bs-info-text-emphasis)}.list-group-item-warning{--bs-list-group-color:var(--bs-warning-text-emphasis);--bs-list-group-bg:var(--bs-warning-bg-subtle);--bs-list-group-border-color:var(--bs-warning-border-subtle);--bs-list-group-action-hover-color:var(--bs-emphasis-color);--bs-list-group-action-hover-bg:var(--bs-warning-border-subtle);--bs-list-group-action-active-color:var(--bs-emphasis-color);--bs-list-group-action-active-bg:var(--bs-warning-border-subtle);--bs-list-group-active-color:var(--bs-warning-bg-subtle);--bs-list-group-active-bg:var(--bs-warning-text-emphasis);--bs-list-group-active-border-color:var(--bs-warning-text-emphasis)}.list-group-item-danger{--bs-list-group-color:var(--bs-danger-text-emphasis);--bs-list-group-bg:var(--bs-danger-bg-subtle);--bs-list-group-border-color:var(--bs-danger-border-subtle);--bs-list-group-action-hover-color:var(--bs-emphasis-color);--bs-list-group-action-hover-bg:var(--bs-danger-border-subtle);--bs-list-group-action-active-color:var(--bs-emphasis-color);--bs-list-group-action-active-bg:var(--bs-danger-border-subtle);--bs-list-group-active-color:var(--bs-danger-bg-subtle);--bs-list-group-active-bg:var(--bs-danger-text-emphasis);--bs-list-group-active-border-color:var(--bs-danger-text-emphasis)}.list-group-item-light{--bs-list-group-color:var(--bs-light-text-emphasis);--bs-list-group-bg:var(--bs-light-bg-subtle);--bs-list-group-border-color:var(--bs-light-border-subtle);--bs-list-group-action-hover-color:var(--bs-emphasis-color);--bs-list-group-action-hover-bg:var(--bs-light-border-subtle);--bs-list-group-action-active-color:var(--bs-emphasis-color);--bs-list-group-action-active-bg:var(--bs-light-border-subtle);--bs-list-group-active-color:var(--bs-light-bg-subtle);--bs-list-group-active-bg:var(--bs-light-text-emphasis);--bs-list-group-active-border-color:var(--bs-light-text-emphasis)}.list-group-item-dark{--bs-list-group-color:var(--bs-dark-text-emphasis);--bs-list-group-bg:var(--bs-dark-bg-subtle);--bs-list-group-border-color:var(--bs-dark-border-subtle);--bs-list-group-action-hover-color:var(--bs-emphasis-color);--bs-list-group-action-hover-bg:var(--bs-dark-border-subtle);--bs-list-group-action-active-color:var(--bs-emphasis-color);--bs-list-group-action-active-bg:var(--bs-dark-border-subtle);--bs-list-group-active-color:var(--bs-dark-bg-subtle);--bs-list-group-active-bg:var(--bs-dark-text-emphasis);--bs-list-group-active-border-color:var(--bs-dark-text-emphasis)}.btn-close{--bs-btn-close-color:#000;--bs-btn-close-bg:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23000'%3e%3cpath d='M.293.293a1 1 0 0 1 1.414 0L8 6.586 14.293.293a1 1 0 1 1 1.414 1.414L9.414 8l6.293 6.293a1 1 0 0 1-1.414 1.414L8 9.414l-6.293 6.293a1 1 0 0 1-1.414-1.414L6.586 8 .293 1.707a1 1 0 0 1 0-1.414'/%3e%3c/svg%3e");--bs-btn-close-opacity:0.5;--bs-btn-close-hover-opacity:0.75;--bs-btn-close-focus-shadow:0 0 0 0.25rem rgba(13, 110, 253, 0.25);--bs-btn-close-focus-opacity:1;--bs-btn-close-disabled-opacity:0.25;box-sizing:content-box;width:1em;height:1em;padding:.25em .25em;color:var(--bs-btn-close-color);background:transparent var(--bs-btn-close-bg) center/1em auto no-repeat;filter:var(--bs-btn-close-filter);border:0;border-radius:.375rem;opacity:var(--bs-btn-close-opacity)}.btn-close:hover{color:var(--bs-btn-close-color);text-decoration:none;opacity:var(--bs-btn-close-hover-opacity)}.btn-close:focus{outline:0;box-shadow:var(--bs-btn-close-focus-shadow);opacity:var(--bs-btn-close-focus-opacity)}.btn-close.disabled,.btn-close:disabled{pointer-events:none;-webkit-user-select:none;-moz-user-select:none;user-select:none;opacity:var(--bs-btn-close-disabled-opacity)}.btn-close-white{--bs-btn-close-filter:invert(1) grayscale(100%) brightness(200%)}:root,[data-bs-theme=light]{--bs-btn-close-filter: }[data-bs-theme=dark]{--bs-btn-close-filter:invert(1) grayscale(100%) brightness(200%)}.toast{--bs-toast-zindex:1090;--bs-toast-padding-x:0.75rem;--bs-toast-padding-y:0.5rem;--bs-toast-spacing:1.5rem;--bs-toast-max-width:350px;--bs-toast-font-size:0.875rem;--bs-toast-color: ;--bs-toast-bg:rgba(var(--bs-body-bg-rgb), 0.85);--bs-toast-border-width:var(--bs-border-width);--bs-toast-border-color:var(--bs-border-color-translucent);--bs-toast-border-radius:var(--bs-border-radius);--bs-toast-box-shadow:var(--bs-box-shadow);--bs-toast-header-color:var(--bs-secondary-color);--bs-toast-header-bg:rgba(var(--bs-body-bg-rgb), 0.85);--bs-toast-header-border-color:var(--bs-border-color-translucent);width:var(--bs-toast-max-width);max-width:100%;font-size:var(--bs-toast-font-size);color:var(--bs-toast-color);pointer-events:auto;background-color:var(--bs-toast-bg);background-clip:padding-box;border:var(--bs-toast-border-width) solid var(--bs-toast-border-color);box-shadow:var(--bs-toast-box-shadow);border-radius:var(--bs-toast-border-radius)}.toast.showing{opacity:0}.toast:not(.show){display:none}.toast-container{--bs-toast-zindex:1090;position:absolute;z-index:var(--bs-toast-zindex);width:-webkit-max-content;width:-moz-max-content;width:max-content;max-width:100%;pointer-events:none}.toast-container>:not(:last-child){margin-bottom:var(--bs-toast-spacing)}.toast-header{display:flex;align-items:center;padding:var(--bs-toast-padding-y) var(--bs-toast-padding-x);color:var(--bs-toast-header-color);background-color:var(--bs-toast-header-bg);background-clip:padding-box;border-bottom:var(--bs-toast-border-width) solid var(--bs-toast-header-border-color);border-top-left-radius:calc(var(--bs-toast-border-radius) - var(--bs-toast-border-width));border-top-right-radius:calc(var(--bs-toast-border-radius) - var(--bs-toast-border-width))}.toast-header .btn-close{margin-right:calc(-.5 * var(--bs-toast-padding-x));margin-left:var(--bs-toast-padding-x)}.toast-body{padding:var(--bs-toast-padding-x);word-wrap:break-word}.modal{--bs-modal-zindex:1055;--bs-modal-width:500px;--bs-modal-padding:1rem;--bs-modal-margin:0.5rem;--bs-modal-color:var(--bs-body-color);--bs-modal-bg:var(--bs-body-bg);--bs-modal-border-color:var(--bs-border-color-translucent);--bs-modal-border-width:var(--bs-border-width);--bs-modal-border-radius:var(--bs-border-radius-lg);--bs-modal-box-shadow:var(--bs-box-shadow-sm);--bs-modal-inner-border-radius:calc(var(--bs-border-radius-lg) - (var(--bs-border-width)));--bs-modal-header-padding-x:1rem;--bs-modal-header-padding-y:1rem;--bs-modal-header-padding:1rem 1rem;--bs-modal-header-border-color:var(--bs-border-color);--bs-modal-header-border-width:var(--bs-border-width);--bs-modal-title-line-height:1.5;--bs-modal-footer-gap:0.5rem;--bs-modal-footer-bg: ;--bs-modal-footer-border-color:var(--bs-border-color);--bs-modal-footer-border-width:var(--bs-border-width);position:fixed;top:0;left:0;z-index:var(--bs-modal-zindex);display:none;width:100%;height:100%;overflow-x:hidden;overflow-y:auto;outline:0}.modal-dialog{position:relative;width:auto;margin:var(--bs-modal-margin);pointer-events:none}.modal.fade .modal-dialog{transform:translate(0,-50px);transition:transform .3s ease-out}@media (prefers-reduced-motion:reduce){.modal.fade .modal-dialog{transition:none}}.modal.show .modal-dialog{transform:none}.modal.modal-static .modal-dialog{transform:scale(1.02)}.modal-dialog-scrollable{height:calc(100% - var(--bs-modal-margin) * 2)}.modal-dialog-scrollable .modal-content{max-height:100%;overflow:hidden}.modal-dialog-scrollable .modal-body{overflow-y:auto}.modal-dialog-centered{display:flex;align-items:center;min-height:calc(100% - var(--bs-modal-margin) * 2)}.modal-content{position:relative;display:flex;flex-direction:column;width:100%;color:var(--bs-modal-color);pointer-events:auto;background-color:var(--bs-modal-bg);background-clip:padding-box;border:var(--bs-modal-border-width) solid var(--bs-modal-border-color);border-radius:var(--bs-modal-border-radius);outline:0}.modal-backdrop{--bs-backdrop-zindex:1050;--bs-backdrop-bg:#000;--bs-backdrop-opacity:0.5;position:fixed;top:0;left:0;z-index:var(--bs-backdrop-zindex);width:100vw;height:100vh;background-color:var(--bs-backdrop-bg)}.modal-backdrop.fade{opacity:0}.modal-backdrop.show{opacity:var(--bs-backdrop-opacity)}.modal-header{display:flex;flex-shrink:0;align-items:center;padding:var(--bs-modal-header-padding);border-bottom:var(--bs-modal-header-border-width) solid var(--bs-modal-header-border-color);border-top-left-radius:var(--bs-modal-inner-border-radius);border-top-right-radius:var(--bs-modal-inner-border-radius)}.modal-header .btn-close{padding:calc(var(--bs-modal-header-padding-y) * .5) calc(var(--bs-modal-header-padding-x) * .5);margin-top:calc(-.5 * var(--bs-modal-header-padding-y));margin-right:calc(-.5 * var(--bs-modal-header-padding-x));margin-bottom:calc(-.5 * var(--bs-modal-header-padding-y));margin-left:auto}.modal-title{margin-bottom:0;line-height:var(--bs-modal-title-line-height)}.modal-body{position:relative;flex:1 1 auto;padding:var(--bs-modal-padding)}.modal-footer{display:flex;flex-shrink:0;flex-wrap:wrap;align-items:center;justify-content:flex-end;padding:calc(var(--bs-modal-padding) - var(--bs-modal-footer-gap) * .5);background-color:var(--bs-modal-footer-bg);border-top:var(--bs-modal-footer-border-width) solid var(--bs-modal-footer-border-color);border-bottom-right-radius:var(--bs-modal-inner-border-radius);border-bottom-left-radius:var(--bs-modal-inner-border-radius)}.modal-footer>*{margin:calc(var(--bs-modal-footer-gap) * .5)}@media (min-width:576px){.modal{--bs-modal-margin:1.75rem;--bs-modal-box-shadow:var(--bs-box-shadow)}.modal-dialog{max-width:var(--bs-modal-width);margin-right:auto;margin-left:auto}.modal-sm{--bs-modal-width:300px}}@media (min-width:992px){.modal-lg,.modal-xl{--bs-modal-width:800px}}@media (min-width:1200px){.modal-xl{--bs-modal-width:1140px}}.modal-fullscreen{width:100vw;max-width:none;height:100%;margin:0}.modal-fullscreen .modal-content{height:100%;border:0;border-radius:0}.modal-fullscreen .modal-footer,.modal-fullscreen .modal-header{border-radius:0}.modal-fullscreen .modal-body{overflow-y:auto}@media (max-width:575.98px){.modal-fullscreen-sm-down{width:100vw;max-width:none;height:100%;margin:0}.modal-fullscreen-sm-down .modal-content{height:100%;border:0;border-radius:0}.modal-fullscreen-sm-down .modal-footer,.modal-fullscreen-sm-down .modal-header{border-radius:0}.modal-fullscreen-sm-down .modal-body{overflow-y:auto}}@media (max-width:767.98px){.modal-fullscreen-md-down{width:100vw;max-width:none;height:100%;margin:0}.modal-fullscreen-md-down .modal-content{height:100%;border:0;border-radius:0}.modal-fullscreen-md-down .modal-footer,.modal-fullscreen-md-down .modal-header{border-radius:0}.modal-fullscreen-md-down .modal-body{overflow-y:auto}}@media (max-width:991.98px){.modal-fullscreen-lg-down{width:100vw;max-width:none;height:100%;margin:0}.modal-fullscreen-lg-down .modal-content{height:100%;border:0;border-radius:0}.modal-fullscreen-lg-down .modal-footer,.modal-fullscreen-lg-down .modal-header{border-radius:0}.modal-fullscreen-lg-down .modal-body{overflow-y:auto}}@media (max-width:1199.98px){.modal-fullscreen-xl-down{width:100vw;max-width:none;height:100%;margin:0}.modal-fullscreen-xl-down .modal-content{height:100%;border:0;border-radius:0}.modal-fullscreen-xl-down .modal-footer,.modal-fullscreen-xl-down .modal-header{border-radius:0}.modal-fullscreen-xl-down .modal-body{overflow-y:auto}}@media (max-width:1399.98px){.modal-fullscreen-xxl-down{width:100vw;max-width:none;height:100%;margin:0}.modal-fullscreen-xxl-down .modal-content{height:100%;border:0;border-radius:0}.modal-fullscreen-xxl-down .modal-footer,.modal-fullscreen-xxl-down .modal-header{border-radius:0}.modal-fullscreen-xxl-down .modal-body{overflow-y:auto}}.tooltip{--bs-tooltip-zindex:1080;--bs-tooltip-max-width:200px;--bs-tooltip-padding-x:0.5rem;--bs-tooltip-padding-y:0.25rem;--bs-tooltip-margin: ;--bs-tooltip-font-size:0.875rem;--bs-tooltip-color:var(--bs-body-bg);--bs-tooltip-bg:var(--bs-emphasis-color);--bs-tooltip-border-radius:var(--bs-border-radius);--bs-tooltip-opacity:0.9;--bs-tooltip-arrow-width:0.8rem;--bs-tooltip-arrow-height:0.4rem;z-index:var(--bs-tooltip-zindex);display:block;margin:var(--bs-tooltip-margin);font-family:var(--bs-font-sans-serif);font-style:normal;font-weight:400;line-height:1.5;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;white-space:normal;word-spacing:normal;line-break:auto;font-size:var(--bs-tooltip-font-size);word-wrap:break-word;opacity:0}.tooltip.show{opacity:var(--bs-tooltip-opacity)}.tooltip .tooltip-arrow{display:block;width:var(--bs-tooltip-arrow-width);height:var(--bs-tooltip-arrow-height)}.tooltip .tooltip-arrow::before{position:absolute;content:"";border-color:transparent;border-style:solid}.bs-tooltip-auto[data-popper-placement^=top] .tooltip-arrow,.bs-tooltip-top .tooltip-arrow{bottom:calc(-1 * var(--bs-tooltip-arrow-height))}.bs-tooltip-auto[data-popper-placement^=top] .tooltip-arrow::before,.bs-tooltip-top .tooltip-arrow::before{top:-1px;border-width:var(--bs-tooltip-arrow-height) calc(var(--bs-tooltip-arrow-width) * .5) 0;border-top-color:var(--bs-tooltip-bg)}.bs-tooltip-auto[data-popper-placement^=right] .tooltip-arrow,.bs-tooltip-end .tooltip-arrow{left:calc(-1 * var(--bs-tooltip-arrow-height));width:var(--bs-tooltip-arrow-height);height:var(--bs-tooltip-arrow-width)}.bs-tooltip-auto[data-popper-placement^=right] .tooltip-arrow::before,.bs-tooltip-end .tooltip-arrow::before{right:-1px;border-width:calc(var(--bs-tooltip-arrow-width) * .5) var(--bs-tooltip-arrow-height) calc(var(--bs-tooltip-arrow-width) * .5) 0;border-right-color:var(--bs-tooltip-bg)}.bs-tooltip-auto[data-popper-placement^=bottom] .tooltip-arrow,.bs-tooltip-bottom .tooltip-arrow{top:calc(-1 * var(--bs-tooltip-arrow-height))}.bs-tooltip-auto[data-popper-placement^=bottom] .tooltip-arrow::before,.bs-tooltip-bottom .tooltip-arrow::before{bottom:-1px;border-width:0 calc(var(--bs-tooltip-arrow-width) * .5) var(--bs-tooltip-arrow-height);border-bottom-color:var(--bs-tooltip-bg)}.bs-tooltip-auto[data-popper-placement^=left] .tooltip-arrow,.bs-tooltip-start .tooltip-arrow{right:calc(-1 * var(--bs-tooltip-arrow-height));width:var(--bs-tooltip-arrow-height);height:var(--bs-tooltip-arrow-width)}.bs-tooltip-auto[data-popper-placement^=left] .tooltip-arrow::before,.bs-tooltip-start .tooltip-arrow::before{left:-1px;border-width:calc(var(--bs-tooltip-arrow-width) * .5) 0 calc(var(--bs-tooltip-arrow-width) * .5) var(--bs-tooltip-arrow-height);border-left-color:var(--bs-tooltip-bg)}.tooltip-inner{max-width:var(--bs-tooltip-max-width);padding:var(--bs-tooltip-padding-y) var(--bs-tooltip-padding-x);color:var(--bs-tooltip-color);text-align:center;background-color:var(--bs-tooltip-bg);border-radius:var(--bs-tooltip-border-radius)}.popover{--bs-popover-zindex:1070;--bs-popover-max-width:276px;--bs-popover-font-size:0.875rem;--bs-popover-bg:var(--bs-body-bg);--bs-popover-border-width:var(--bs-border-width);--bs-popover-border-color:var(--bs-border-color-translucent);--bs-popover-border-radius:var(--bs-border-radius-lg);--bs-popover-inner-border-radius:calc(var(--bs-border-radius-lg) - var(--bs-border-width));--bs-popover-box-shadow:var(--bs-box-shadow);--bs-popover-header-padding-x:1rem;--bs-popover-header-padding-y:0.5rem;--bs-popover-header-font-size:1rem;--bs-popover-header-color:inherit;--bs-popover-header-bg:var(--bs-secondary-bg);--bs-popover-body-padding-x:1rem;--bs-popover-body-padding-y:1rem;--bs-popover-body-color:var(--bs-body-color);--bs-popover-arrow-width:1rem;--bs-popover-arrow-height:0.5rem;--bs-popover-arrow-border:var(--bs-popover-border-color);z-index:var(--bs-popover-zindex);display:block;max-width:var(--bs-popover-max-width);font-family:var(--bs-font-sans-serif);font-style:normal;font-weight:400;line-height:1.5;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;white-space:normal;word-spacing:normal;line-break:auto;font-size:var(--bs-popover-font-size);word-wrap:break-word;background-color:var(--bs-popover-bg);background-clip:padding-box;border:var(--bs-popover-border-width) solid var(--bs-popover-border-color);border-radius:var(--bs-popover-border-radius)}.popover .popover-arrow{display:block;width:var(--bs-popover-arrow-width);height:var(--bs-popover-arrow-height)}.popover .popover-arrow::after,.popover .popover-arrow::before{position:absolute;display:block;content:"";border-color:transparent;border-style:solid;border-width:0}.bs-popover-auto[data-popper-placement^=top]>.popover-arrow,.bs-popover-top>.popover-arrow{bottom:calc(-1 * (var(--bs-popover-arrow-height)) - var(--bs-popover-border-width))}.bs-popover-auto[data-popper-placement^=top]>.popover-arrow::after,.bs-popover-auto[data-popper-placement^=top]>.popover-arrow::before,.bs-popover-top>.popover-arrow::after,.bs-popover-top>.popover-arrow::before{border-width:var(--bs-popover-arrow-height) calc(var(--bs-popover-arrow-width) * .5) 0}.bs-popover-auto[data-popper-placement^=top]>.popover-arrow::before,.bs-popover-top>.popover-arrow::before{bottom:0;border-top-color:var(--bs-popover-arrow-border)}.bs-popover-auto[data-popper-placement^=top]>.popover-arrow::after,.bs-popover-top>.popover-arrow::after{bottom:var(--bs-popover-border-width);border-top-color:var(--bs-popover-bg)}.bs-popover-auto[data-popper-placement^=right]>.popover-arrow,.bs-popover-end>.popover-arrow{left:calc(-1 * (var(--bs-popover-arrow-height)) - var(--bs-popover-border-width));width:var(--bs-popover-arrow-height);height:var(--bs-popover-arrow-width)}.bs-popover-auto[data-popper-placement^=right]>.popover-arrow::after,.bs-popover-auto[data-popper-placement^=right]>.popover-arrow::before,.bs-popover-end>.popover-arrow::after,.bs-popover-end>.popover-arrow::before{border-width:calc(var(--bs-popover-arrow-width) * .5) var(--bs-popover-arrow-height) calc(var(--bs-popover-arrow-width) * .5) 0}.bs-popover-auto[data-popper-placement^=right]>.popover-arrow::before,.bs-popover-end>.popover-arrow::before{left:0;border-right-color:var(--bs-popover-arrow-border)}.bs-popover-auto[data-popper-placement^=right]>.popover-arrow::after,.bs-popover-end>.popover-arrow::after{left:var(--bs-popover-border-width);border-right-color:var(--bs-popover-bg)}.bs-popover-auto[data-popper-placement^=bottom]>.popover-arrow,.bs-popover-bottom>.popover-arrow{top:calc(-1 * (var(--bs-popover-arrow-height)) - var(--bs-popover-border-width))}.bs-popover-auto[data-popper-placement^=bottom]>.popover-arrow::after,.bs-popover-auto[data-popper-placement^=bottom]>.popover-arrow::before,.bs-popover-bottom>.popover-arrow::after,.bs-popover-bottom>.popover-arrow::before{border-width:0 calc(var(--bs-popover-arrow-width) * .5) var(--bs-popover-arrow-height)}.bs-popover-auto[data-popper-placement^=bottom]>.popover-arrow::before,.bs-popover-bottom>.popover-arrow::before{top:0;border-bottom-color:var(--bs-popover-arrow-border)}.bs-popover-auto[data-popper-placement^=bottom]>.popover-arrow::after,.bs-popover-bottom>.popover-arrow::after{top:var(--bs-popover-border-width);border-bottom-color:var(--bs-popover-bg)}.bs-popover-auto[data-popper-placement^=bottom] .popover-header::before,.bs-popover-bottom .popover-header::before{position:absolute;top:0;left:50%;display:block;width:var(--bs-popover-arrow-width);margin-left:calc(-.5 * var(--bs-popover-arrow-width));content:"";border-bottom:var(--bs-popover-border-width) solid var(--bs-popover-header-bg)}.bs-popover-auto[data-popper-placement^=left]>.popover-arrow,.bs-popover-start>.popover-arrow{right:calc(-1 * (var(--bs-popover-arrow-height)) - var(--bs-popover-border-width));width:var(--bs-popover-arrow-height);height:var(--bs-popover-arrow-width)}.bs-popover-auto[data-popper-placement^=left]>.popover-arrow::after,.bs-popover-auto[data-popper-placement^=left]>.popover-arrow::before,.bs-popover-start>.popover-arrow::after,.bs-popover-start>.popover-arrow::before{border-width:calc(var(--bs-popover-arrow-width) * .5) 0 calc(var(--bs-popover-arrow-width) * .5) var(--bs-popover-arrow-height)}.bs-popover-auto[data-popper-placement^=left]>.popover-arrow::before,.bs-popover-start>.popover-arrow::before{right:0;border-left-color:var(--bs-popover-arrow-border)}.bs-popover-auto[data-popper-placement^=left]>.popover-arrow::after,.bs-popover-start>.popover-arrow::after{right:var(--bs-popover-border-width);border-left-color:var(--bs-popover-bg)}.popover-header{padding:var(--bs-popover-header-padding-y) var(--bs-popover-header-padding-x);margin-bottom:0;font-size:var(--bs-popover-header-font-size);color:var(--bs-popover-header-color);background-color:var(--bs-popover-header-bg);border-bottom:var(--bs-popover-border-width) solid var(--bs-popover-border-color);border-top-left-radius:var(--bs-popover-inner-border-radius);border-top-right-radius:var(--bs-popover-inner-border-radius)}.popover-header:empty{display:none}.popover-body{padding:var(--bs-popover-body-padding-y) var(--bs-popover-body-padding-x);color:var(--bs-popover-body-color)}.carousel{position:relative}.carousel.pointer-event{touch-action:pan-y}.carousel-inner{position:relative;width:100%;overflow:hidden}.carousel-inner::after{display:block;clear:both;content:""}.carousel-item{position:relative;display:none;float:left;width:100%;margin-right:-100%;-webkit-backface-visibility:hidden;backface-visibility:hidden;transition:transform .6s ease-in-out}@media (prefers-reduced-motion:reduce){.carousel-item{transition:none}}.carousel-item-next,.carousel-item-prev,.carousel-item.active{display:block}.active.carousel-item-end,.carousel-item-next:not(.carousel-item-start){transform:translateX(100%)}.active.carousel-item-start,.carousel-item-prev:not(.carousel-item-end){transform:translateX(-100%)}.carousel-fade .carousel-item{opacity:0;transition-property:opacity;transform:none}.carousel-fade .carousel-item-next.carousel-item-start,.carousel-fade .carousel-item-prev.carousel-item-end,.carousel-fade .carousel-item.active{z-index:1;opacity:1}.carousel-fade .active.carousel-item-end,.carousel-fade .active.carousel-item-start{z-index:0;opacity:0;transition:opacity 0s .6s}@media (prefers-reduced-motion:reduce){.carousel-fade .active.carousel-item-end,.carousel-fade .active.carousel-item-start{transition:none}}.carousel-control-next,.carousel-control-prev{position:absolute;top:0;bottom:0;z-index:1;display:flex;align-items:center;justify-content:center;width:15%;padding:0;color:#fff;text-align:center;background:0 0;filter:var(--bs-carousel-control-icon-filter);border:0;opacity:.5;transition:opacity .15s ease}@media (prefers-reduced-motion:reduce){.carousel-control-next,.carousel-control-prev{transition:none}}.carousel-control-next:focus,.carousel-control-next:hover,.carousel-control-prev:focus,.carousel-control-prev:hover{color:#fff;text-decoration:none;outline:0;opacity:.9}.carousel-control-prev{left:0}.carousel-control-next{right:0}.carousel-control-next-icon,.carousel-control-prev-icon{display:inline-block;width:2rem;height:2rem;background-repeat:no-repeat;background-position:50%;background-size:100% 100%}.carousel-control-prev-icon{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23fff'%3e%3cpath d='M11.354 1.646a.5.5 0 0 1 0 .708L5.707 8l5.647 5.646a.5.5 0 0 1-.708.708l-6-6a.5.5 0 0 1 0-.708l6-6a.5.5 0 0 1 .708 0'/%3e%3c/svg%3e")}.carousel-control-next-icon{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23fff'%3e%3cpath d='M4.646 1.646a.5.5 0 0 1 .708 0l6 6a.5.5 0 0 1 0 .708l-6 6a.5.5 0 0 1-.708-.708L10.293 8 4.646 2.354a.5.5 0 0 1 0-.708'/%3e%3c/svg%3e")}.carousel-indicators{position:absolute;right:0;bottom:0;left:0;z-index:2;display:flex;justify-content:center;padding:0;margin-right:15%;margin-bottom:1rem;margin-left:15%}.carousel-indicators [data-bs-target]{box-sizing:content-box;flex:0 1 auto;width:30px;height:3px;padding:0;margin-right:3px;margin-left:3px;text-indent:-999px;cursor:pointer;background-color:var(--bs-carousel-indicator-active-bg);background-clip:padding-box;border:0;border-top:10px solid transparent;border-bottom:10px solid transparent;opacity:.5;transition:opacity .6s ease}@media (prefers-reduced-motion:reduce){.carousel-indicators [data-bs-target]{transition:none}}.carousel-indicators .active{opacity:1}.carousel-caption{position:absolute;right:15%;bottom:1.25rem;left:15%;padding-top:1.25rem;padding-bottom:1.25rem;color:var(--bs-carousel-caption-color);text-align:center}.carousel-dark{--bs-carousel-indicator-active-bg:#000;--bs-carousel-caption-color:#000;--bs-carousel-control-icon-filter:invert(1) grayscale(100)}:root,[data-bs-theme=light]{--bs-carousel-indicator-active-bg:#fff;--bs-carousel-caption-color:#fff;--bs-carousel-control-icon-filter: }[data-bs-theme=dark]{--bs-carousel-indicator-active-bg:#000;--bs-carousel-caption-color:#000;--bs-carousel-control-icon-filter:invert(1) grayscale(100)}.spinner-border,.spinner-grow{display:inline-block;width:var(--bs-spinner-width);height:var(--bs-spinner-height);vertical-align:var(--bs-spinner-vertical-align);border-radius:50%;animation:var(--bs-spinner-animation-speed) linear infinite var(--bs-spinner-animation-name)}@keyframes spinner-border{to{transform:rotate(360deg)}}.spinner-border{--bs-spinner-width:2rem;--bs-spinner-height:2rem;--bs-spinner-vertical-align:-0.125em;--bs-spinner-border-width:0.25em;--bs-spinner-animation-speed:0.75s;--bs-spinner-animation-name:spinner-border;border:var(--bs-spinner-border-width) solid currentcolor;border-right-color:transparent}.spinner-border-sm{--bs-spinner-width:1rem;--bs-spinner-height:1rem;--bs-spinner-border-width:0.2em}@keyframes spinner-grow{0%{transform:scale(0)}50%{opacity:1;transform:none}}.spinner-grow{--bs-spinner-width:2rem;--bs-spinner-height:2rem;--bs-spinner-vertical-align:-0.125em;--bs-spinner-animation-speed:0.75s;--bs-spinner-animation-name:spinner-grow;background-color:currentcolor;opacity:0}.spinner-grow-sm{--bs-spinner-width:1rem;--bs-spinner-height:1rem}@media (prefers-reduced-motion:reduce){.spinner-border,.spinner-grow{--bs-spinner-animation-speed:1.5s}}.offcanvas,.offcanvas-lg,.offcanvas-md,.offcanvas-sm,.offcanvas-xl,.offcanvas-xxl{--bs-offcanvas-zindex:1045;--bs-offcanvas-width:400px;--bs-offcanvas-height:30vh;--bs-offcanvas-padding-x:1rem;--bs-offcanvas-padding-y:1rem;--bs-offcanvas-color:var(--bs-body-color);--bs-offcanvas-bg:var(--bs-body-bg);--bs-offcanvas-border-width:var(--bs-border-width);--bs-offcanvas-border-color:var(--bs-border-color-translucent);--bs-offcanvas-box-shadow:var(--bs-box-shadow-sm);--bs-offcanvas-transition:transform 0.3s ease-in-out;--bs-offcanvas-title-line-height:1.5}@media (max-width:575.98px){.offcanvas-sm{position:fixed;bottom:0;z-index:var(--bs-offcanvas-zindex);display:flex;flex-direction:column;max-width:100%;color:var(--bs-offcanvas-color);visibility:hidden;background-color:var(--bs-offcanvas-bg);background-clip:padding-box;outline:0;transition:var(--bs-offcanvas-transition)}}@media (max-width:575.98px) and (prefers-reduced-motion:reduce){.offcanvas-sm{transition:none}}@media (max-width:575.98px){.offcanvas-sm.offcanvas-start{top:0;left:0;width:var(--bs-offcanvas-width);border-right:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateX(-100%)}.offcanvas-sm.offcanvas-end{top:0;right:0;width:var(--bs-offcanvas-width);border-left:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateX(100%)}.offcanvas-sm.offcanvas-top{top:0;right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-bottom:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(-100%)}.offcanvas-sm.offcanvas-bottom{right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-top:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(100%)}.offcanvas-sm.show:not(.hiding),.offcanvas-sm.showing{transform:none}.offcanvas-sm.hiding,.offcanvas-sm.show,.offcanvas-sm.showing{visibility:visible}}@media (min-width:576px){.offcanvas-sm{--bs-offcanvas-height:auto;--bs-offcanvas-border-width:0;background-color:transparent!important}.offcanvas-sm .offcanvas-header{display:none}.offcanvas-sm .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible;background-color:transparent!important}}@media (max-width:767.98px){.offcanvas-md{position:fixed;bottom:0;z-index:var(--bs-offcanvas-zindex);display:flex;flex-direction:column;max-width:100%;color:var(--bs-offcanvas-color);visibility:hidden;background-color:var(--bs-offcanvas-bg);background-clip:padding-box;outline:0;transition:var(--bs-offcanvas-transition)}}@media (max-width:767.98px) and (prefers-reduced-motion:reduce){.offcanvas-md{transition:none}}@media (max-width:767.98px){.offcanvas-md.offcanvas-start{top:0;left:0;width:var(--bs-offcanvas-width);border-right:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateX(-100%)}.offcanvas-md.offcanvas-end{top:0;right:0;width:var(--bs-offcanvas-width);border-left:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateX(100%)}.offcanvas-md.offcanvas-top{top:0;right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-bottom:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(-100%)}.offcanvas-md.offcanvas-bottom{right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-top:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(100%)}.offcanvas-md.show:not(.hiding),.offcanvas-md.showing{transform:none}.offcanvas-md.hiding,.offcanvas-md.show,.offcanvas-md.showing{visibility:visible}}@media (min-width:768px){.offcanvas-md{--bs-offcanvas-height:auto;--bs-offcanvas-border-width:0;background-color:transparent!important}.offcanvas-md .offcanvas-header{display:none}.offcanvas-md .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible;background-color:transparent!important}}@media (max-width:991.98px){.offcanvas-lg{position:fixed;bottom:0;z-index:var(--bs-offcanvas-zindex);display:flex;flex-direction:column;max-width:100%;color:var(--bs-offcanvas-color);visibility:hidden;background-color:var(--bs-offcanvas-bg);background-clip:padding-box;outline:0;transition:var(--bs-offcanvas-transition)}}@media (max-width:991.98px) and (prefers-reduced-motion:reduce){.offcanvas-lg{transition:none}}@media (max-width:991.98px){.offcanvas-lg.offcanvas-start{top:0;left:0;width:var(--bs-offcanvas-width);border-right:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateX(-100%)}.offcanvas-lg.offcanvas-end{top:0;right:0;width:var(--bs-offcanvas-width);border-left:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateX(100%)}.offcanvas-lg.offcanvas-top{top:0;right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-bottom:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(-100%)}.offcanvas-lg.offcanvas-bottom{right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-top:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(100%)}.offcanvas-lg.show:not(.hiding),.offcanvas-lg.showing{transform:none}.offcanvas-lg.hiding,.offcanvas-lg.show,.offcanvas-lg.showing{visibility:visible}}@media (min-width:992px){.offcanvas-lg{--bs-offcanvas-height:auto;--bs-offcanvas-border-width:0;background-color:transparent!important}.offcanvas-lg .offcanvas-header{display:none}.offcanvas-lg .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible;background-color:transparent!important}}@media (max-width:1199.98px){.offcanvas-xl{position:fixed;bottom:0;z-index:var(--bs-offcanvas-zindex);display:flex;flex-direction:column;max-width:100%;color:var(--bs-offcanvas-color);visibility:hidden;background-color:var(--bs-offcanvas-bg);background-clip:padding-box;outline:0;transition:var(--bs-offcanvas-transition)}}@media (max-width:1199.98px) and (prefers-reduced-motion:reduce){.offcanvas-xl{transition:none}}@media (max-width:1199.98px){.offcanvas-xl.offcanvas-start{top:0;left:0;width:var(--bs-offcanvas-width);border-right:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateX(-100%)}.offcanvas-xl.offcanvas-end{top:0;right:0;width:var(--bs-offcanvas-width);border-left:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateX(100%)}.offcanvas-xl.offcanvas-top{top:0;right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-bottom:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(-100%)}.offcanvas-xl.offcanvas-bottom{right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-top:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(100%)}.offcanvas-xl.show:not(.hiding),.offcanvas-xl.showing{transform:none}.offcanvas-xl.hiding,.offcanvas-xl.show,.offcanvas-xl.showing{visibility:visible}}@media (min-width:1200px){.offcanvas-xl{--bs-offcanvas-height:auto;--bs-offcanvas-border-width:0;background-color:transparent!important}.offcanvas-xl .offcanvas-header{display:none}.offcanvas-xl .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible;background-color:transparent!important}}@media (max-width:1399.98px){.offcanvas-xxl{position:fixed;bottom:0;z-index:var(--bs-offcanvas-zindex);display:flex;flex-direction:column;max-width:100%;color:var(--bs-offcanvas-color);visibility:hidden;background-color:var(--bs-offcanvas-bg);background-clip:padding-box;outline:0;transition:var(--bs-offcanvas-transition)}}@media (max-width:1399.98px) and (prefers-reduced-motion:reduce){.offcanvas-xxl{transition:none}}@media (max-width:1399.98px){.offcanvas-xxl.offcanvas-start{top:0;left:0;width:var(--bs-offcanvas-width);border-right:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateX(-100%)}.offcanvas-xxl.offcanvas-end{top:0;right:0;width:var(--bs-offcanvas-width);border-left:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateX(100%)}.offcanvas-xxl.offcanvas-top{top:0;right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-bottom:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(-100%)}.offcanvas-xxl.offcanvas-bottom{right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-top:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(100%)}.offcanvas-xxl.show:not(.hiding),.offcanvas-xxl.showing{transform:none}.offcanvas-xxl.hiding,.offcanvas-xxl.show,.offcanvas-xxl.showing{visibility:visible}}@media (min-width:1400px){.offcanvas-xxl{--bs-offcanvas-height:auto;--bs-offcanvas-border-width:0;background-color:transparent!important}.offcanvas-xxl .offcanvas-header{display:none}.offcanvas-xxl .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible;background-color:transparent!important}}.offcanvas{position:fixed;bottom:0;z-index:var(--bs-offcanvas-zindex);display:flex;flex-direction:column;max-width:100%;color:var(--bs-offcanvas-color);visibility:hidden;background-color:var(--bs-offcanvas-bg);background-clip:padding-box;outline:0;transition:var(--bs-offcanvas-transition)}@media (prefers-reduced-motion:reduce){.offcanvas{transition:none}}.offcanvas.offcanvas-start{top:0;left:0;width:var(--bs-offcanvas-width);border-right:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateX(-100%)}.offcanvas.offcanvas-end{top:0;right:0;width:var(--bs-offcanvas-width);border-left:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateX(100%)}.offcanvas.offcanvas-top{top:0;right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-bottom:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(-100%)}.offcanvas.offcanvas-bottom{right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-top:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(100%)}.offcanvas.show:not(.hiding),.offcanvas.showing{transform:none}.offcanvas.hiding,.offcanvas.show,.offcanvas.showing{visibility:visible}.offcanvas-backdrop{position:fixed;top:0;left:0;z-index:1040;width:100vw;height:100vh;background-color:#000}.offcanvas-backdrop.fade{opacity:0}.offcanvas-backdrop.show{opacity:.5}.offcanvas-header{display:flex;align-items:center;padding:var(--bs-offcanvas-padding-y) var(--bs-offcanvas-padding-x)}.offcanvas-header .btn-close{padding:calc(var(--bs-offcanvas-padding-y) * .5) calc(var(--bs-offcanvas-padding-x) * .5);margin-top:calc(-.5 * var(--bs-offcanvas-padding-y));margin-right:calc(-.5 * var(--bs-offcanvas-padding-x));margin-bottom:calc(-.5 * var(--bs-offcanvas-padding-y));margin-left:auto}.offcanvas-title{margin-bottom:0;line-height:var(--bs-offcanvas-title-line-height)}.offcanvas-body{flex-grow:1;padding:var(--bs-offcanvas-padding-y) var(--bs-offcanvas-padding-x);overflow-y:auto}.placeholder{display:inline-block;min-height:1em;vertical-align:middle;cursor:wait;background-color:currentcolor;opacity:.5}.placeholder.btn::before{display:inline-block;content:""}.placeholder-xs{min-height:.6em}.placeholder-sm{min-height:.8em}.placeholder-lg{min-height:1.2em}.placeholder-glow .placeholder{animation:placeholder-glow 2s ease-in-out infinite}@keyframes placeholder-glow{50%{opacity:.2}}.placeholder-wave{-webkit-mask-image:linear-gradient(130deg,#000 55%,rgba(0,0,0,0.8) 75%,#000 95%);mask-image:linear-gradient(130deg,#000 55%,rgba(0,0,0,0.8) 75%,#000 95%);-webkit-mask-size:200% 100%;mask-size:200% 100%;animation:placeholder-wave 2s linear infinite}@keyframes placeholder-wave{100%{-webkit-mask-position:-200% 0%;mask-position:-200% 0%}}.clearfix::after{display:block;clear:both;content:""}.text-bg-primary{color:#fff!important;background-color:RGBA(var(--bs-primary-rgb),var(--bs-bg-opacity,1))!important}.text-bg-secondary{color:#fff!important;background-color:RGBA(var(--bs-secondary-rgb),var(--bs-bg-opacity,1))!important}.text-bg-success{color:#fff!important;background-color:RGBA(var(--bs-success-rgb),var(--bs-bg-opacity,1))!important}.text-bg-info{color:#000!important;background-color:RGBA(var(--bs-info-rgb),var(--bs-bg-opacity,1))!important}.text-bg-warning{color:#000!important;background-color:RGBA(var(--bs-warning-rgb),var(--bs-bg-opacity,1))!important}.text-bg-danger{color:#fff!important;background-color:RGBA(var(--bs-danger-rgb),var(--bs-bg-opacity,1))!important}.text-bg-light{color:#000!important;background-color:RGBA(var(--bs-light-rgb),var(--bs-bg-opacity,1))!important}.text-bg-dark{color:#fff!important;background-color:RGBA(var(--bs-dark-rgb),var(--bs-bg-opacity,1))!important}.link-primary{color:RGBA(var(--bs-primary-rgb),var(--bs-link-opacity,1))!important;-webkit-text-decoration-color:RGBA(var(--bs-primary-rgb),var(--bs-link-underline-opacity,1))!important;text-decoration-color:RGBA(var(--bs-primary-rgb),var(--bs-link-underline-opacity,1))!important}.link-primary:focus,.link-primary:hover{color:RGBA(10,88,202,var(--bs-link-opacity,1))!important;-webkit-text-decoration-color:RGBA(10,88,202,var(--bs-link-underline-opacity,1))!important;text-decoration-color:RGBA(10,88,202,var(--bs-link-underline-opacity,1))!important}.link-secondary{color:RGBA(var(--bs-secondary-rgb),var(--bs-link-opacity,1))!important;-webkit-text-decoration-color:RGBA(var(--bs-secondary-rgb),var(--bs-link-underline-opacity,1))!important;text-decoration-color:RGBA(var(--bs-secondary-rgb),var(--bs-link-underline-opacity,1))!important}.link-secondary:focus,.link-secondary:hover{color:RGBA(86,94,100,var(--bs-link-opacity,1))!important;-webkit-text-decoration-color:RGBA(86,94,100,var(--bs-link-underline-opacity,1))!important;text-decoration-color:RGBA(86,94,100,var(--bs-link-underline-opacity,1))!important}.link-success{color:RGBA(var(--bs-success-rgb),var(--bs-link-opacity,1))!important;-webkit-text-decoration-color:RGBA(var(--bs-success-rgb),var(--bs-link-underline-opacity,1))!important;text-decoration-color:RGBA(var(--bs-success-rgb),var(--bs-link-underline-opacity,1))!important}.link-success:focus,.link-success:hover{color:RGBA(20,108,67,var(--bs-link-opacity,1))!important;-webkit-text-decoration-color:RGBA(20,108,67,var(--bs-link-underline-opacity,1))!important;text-decoration-color:RGBA(20,108,67,var(--bs-link-underline-opacity,1))!important}.link-info{color:RGBA(var(--bs-info-rgb),var(--bs-link-opacity,1))!important;-webkit-text-decoration-color:RGBA(var(--bs-info-rgb),var(--bs-link-underline-opacity,1))!important;text-decoration-color:RGBA(var(--bs-info-rgb),var(--bs-link-underline-opacity,1))!important}.link-info:focus,.link-info:hover{color:RGBA(61,213,243,var(--bs-link-opacity,1))!important;-webkit-text-decoration-color:RGBA(61,213,243,var(--bs-link-underline-opacity,1))!important;text-decoration-color:RGBA(61,213,243,var(--bs-link-underline-opacity,1))!important}.link-warning{color:RGBA(var(--bs-warning-rgb),var(--bs-link-opacity,1))!important;-webkit-text-decoration-color:RGBA(var(--bs-warning-rgb),var(--bs-link-underline-opacity,1))!important;text-decoration-color:RGBA(var(--bs-warning-rgb),var(--bs-link-underline-opacity,1))!important}.link-warning:focus,.link-warning:hover{color:RGBA(255,205,57,var(--bs-link-opacity,1))!important;-webkit-text-decoration-color:RGBA(255,205,57,var(--bs-link-underline-opacity,1))!important;text-decoration-color:RGBA(255,205,57,var(--bs-link-underline-opacity,1))!important}.link-danger{color:RGBA(var(--bs-danger-rgb),var(--bs-link-opacity,1))!important;-webkit-text-decoration-color:RGBA(var(--bs-danger-rgb),var(--bs-link-underline-opacity,1))!important;text-decoration-color:RGBA(var(--bs-danger-rgb),var(--bs-link-underline-opacity,1))!important}.link-danger:focus,.link-danger:hover{color:RGBA(176,42,55,var(--bs-link-opacity,1))!important;-webkit-text-decoration-color:RGBA(176,42,55,var(--bs-link-underline-opacity,1))!important;text-decoration-color:RGBA(176,42,55,var(--bs-link-underline-opacity,1))!important}.link-light{color:RGBA(var(--bs-light-rgb),var(--bs-link-opacity,1))!important;-webkit-text-decoration-color:RGBA(var(--bs-light-rgb),var(--bs-link-underline-opacity,1))!important;text-decoration-color:RGBA(var(--bs-light-rgb),var(--bs-link-underline-opacity,1))!important}.link-light:focus,.link-light:hover{color:RGBA(249,250,251,var(--bs-link-opacity,1))!important;-webkit-text-decoration-color:RGBA(249,250,251,var(--bs-link-underline-opacity,1))!important;text-decoration-color:RGBA(249,250,251,var(--bs-link-underline-opacity,1))!important}.link-dark{color:RGBA(var(--bs-dark-rgb),var(--bs-link-opacity,1))!important;-webkit-text-decoration-color:RGBA(var(--bs-dark-rgb),var(--bs-link-underline-opacity,1))!important;text-decoration-color:RGBA(var(--bs-dark-rgb),var(--bs-link-underline-opacity,1))!important}.link-dark:focus,.link-dark:hover{color:RGBA(26,30,33,var(--bs-link-opacity,1))!important;-webkit-text-decoration-color:RGBA(26,30,33,var(--bs-link-underline-opacity,1))!important;text-decoration-color:RGBA(26,30,33,var(--bs-link-underline-opacity,1))!important}.link-body-emphasis{color:RGBA(var(--bs-emphasis-color-rgb),var(--bs-link-opacity,1))!important;-webkit-text-decoration-color:RGBA(var(--bs-emphasis-color-rgb),var(--bs-link-underline-opacity,1))!important;text-decoration-color:RGBA(var(--bs-emphasis-color-rgb),var(--bs-link-underline-opacity,1))!important}.link-body-emphasis:focus,.link-body-emphasis:hover{color:RGBA(var(--bs-emphasis-color-rgb),var(--bs-link-opacity,.75))!important;-webkit-text-decoration-color:RGBA(var(--bs-emphasis-color-rgb),var(--bs-link-underline-opacity,0.75))!important;text-decoration-color:RGBA(var(--bs-emphasis-color-rgb),var(--bs-link-underline-opacity,0.75))!important}.focus-ring:focus{outline:0;box-shadow:var(--bs-focus-ring-x,0) var(--bs-focus-ring-y,0) var(--bs-focus-ring-blur,0) var(--bs-focus-ring-width) var(--bs-focus-ring-color)}.icon-link{display:inline-flex;gap:.375rem;align-items:center;-webkit-text-decoration-color:rgba(var(--bs-link-color-rgb),var(--bs-link-opacity,0.5));text-decoration-color:rgba(var(--bs-link-color-rgb),var(--bs-link-opacity,0.5));text-underline-offset:0.25em;-webkit-backface-visibility:hidden;backface-visibility:hidden}.icon-link>.bi{flex-shrink:0;width:1em;height:1em;fill:currentcolor;transition:.2s ease-in-out transform}@media (prefers-reduced-motion:reduce){.icon-link>.bi{transition:none}}.icon-link-hover:focus-visible>.bi,.icon-link-hover:hover>.bi{transform:var(--bs-icon-link-transform,translate3d(.25em,0,0))}.ratio{position:relative;width:100%}.ratio::before{display:block;padding-top:var(--bs-aspect-ratio);content:""}.ratio>*{position:absolute;top:0;left:0;width:100%;height:100%}.ratio-1x1{--bs-aspect-ratio:100%}.ratio-4x3{--bs-aspect-ratio:75%}.ratio-16x9{--bs-aspect-ratio:56.25%}.ratio-21x9{--bs-aspect-ratio:42.8571428571%}.fixed-top{position:fixed;top:0;right:0;left:0;z-index:1030}.fixed-bottom{position:fixed;right:0;bottom:0;left:0;z-index:1030}.sticky-top{position:-webkit-sticky;position:sticky;top:0;z-index:1020}.sticky-bottom{position:-webkit-sticky;position:sticky;bottom:0;z-index:1020}@media (min-width:576px){.sticky-sm-top{position:-webkit-sticky;position:sticky;top:0;z-index:1020}.sticky-sm-bottom{position:-webkit-sticky;position:sticky;bottom:0;z-index:1020}}@media (min-width:768px){.sticky-md-top{position:-webkit-sticky;position:sticky;top:0;z-index:1020}.sticky-md-bottom{position:-webkit-sticky;position:sticky;bottom:0;z-index:1020}}@media (min-width:992px){.sticky-lg-top{position:-webkit-sticky;position:sticky;top:0;z-index:1020}.sticky-lg-bottom{position:-webkit-sticky;position:sticky;bottom:0;z-index:1020}}@media (min-width:1200px){.sticky-xl-top{position:-webkit-sticky;position:sticky;top:0;z-index:1020}.sticky-xl-bottom{position:-webkit-sticky;position:sticky;bottom:0;z-index:1020}}@media (min-width:1400px){.sticky-xxl-top{position:-webkit-sticky;position:sticky;top:0;z-index:1020}.sticky-xxl-bottom{position:-webkit-sticky;position:sticky;bottom:0;z-index:1020}}.hstack{display:flex;flex-direction:row;align-items:center;align-self:stretch}.vstack{display:flex;flex:1 1 auto;flex-direction:column;align-self:stretch}.visually-hidden,.visually-hidden-focusable:not(:focus):not(:focus-within){width:1px!important;height:1px!important;padding:0!important;margin:-1px!important;overflow:hidden!important;clip:rect(0,0,0,0)!important;white-space:nowrap!important;border:0!important}.visually-hidden-focusable:not(:focus):not(:focus-within):not(caption),.visually-hidden:not(caption){position:absolute!important}.visually-hidden *,.visually-hidden-focusable:not(:focus):not(:focus-within) *{overflow:hidden!important}.stretched-link::after{position:absolute;top:0;right:0;bottom:0;left:0;z-index:1;content:""}.text-truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.vr{display:inline-block;align-self:stretch;width:var(--bs-border-width);min-height:1em;background-color:currentcolor;opacity:.25}.align-baseline{vertical-align:baseline!important}.align-top{vertical-align:top!important}.align-middle{vertical-align:middle!important}.align-bottom{vertical-align:bottom!important}.align-text-bottom{vertical-align:text-bottom!important}.align-text-top{vertical-align:text-top!important}.float-start{float:left!important}.float-end{float:right!important}.float-none{float:none!important}.object-fit-contain{-o-object-fit:contain!important;object-fit:contain!important}.object-fit-cover{-o-object-fit:cover!important;object-fit:cover!important}.object-fit-fill{-o-object-fit:fill!important;object-fit:fill!important}.object-fit-scale{-o-object-fit:scale-down!important;object-fit:scale-down!important}.object-fit-none{-o-object-fit:none!important;object-fit:none!important}.opacity-0{opacity:0!important}.opacity-25{opacity:.25!important}.opacity-50{opacity:.5!important}.opacity-75{opacity:.75!important}.opacity-100{opacity:1!important}.overflow-auto{overflow:auto!important}.overflow-hidden{overflow:hidden!important}.overflow-visible{overflow:visible!important}.overflow-scroll{overflow:scroll!important}.overflow-x-auto{overflow-x:auto!important}.overflow-x-hidden{overflow-x:hidden!important}.overflow-x-visible{overflow-x:visible!important}.overflow-x-scroll{overflow-x:scroll!important}.overflow-y-auto{overflow-y:auto!important}.overflow-y-hidden{overflow-y:hidden!important}.overflow-y-visible{overflow-y:visible!important}.overflow-y-scroll{overflow-y:scroll!important}.d-inline{display:inline!important}.d-inline-block{display:inline-block!important}.d-block{display:block!important}.d-grid{display:grid!important}.d-inline-grid{display:inline-grid!important}.d-table{display:table!important}.d-table-row{display:table-row!important}.d-table-cell{display:table-cell!important}.d-flex{display:flex!important}.d-inline-flex{display:inline-flex!important}.d-none{display:none!important}.shadow{box-shadow:var(--bs-box-shadow)!important}.shadow-sm{box-shadow:var(--bs-box-shadow-sm)!important}.shadow-lg{box-shadow:var(--bs-box-shadow-lg)!important}.shadow-none{box-shadow:none!important}.focus-ring-primary{--bs-focus-ring-color:rgba(var(--bs-primary-rgb), var(--bs-focus-ring-opacity))}.focus-ring-secondary{--bs-focus-ring-color:rgba(var(--bs-secondary-rgb), var(--bs-focus-ring-opacity))}.focus-ring-success{--bs-focus-ring-color:rgba(var(--bs-success-rgb), var(--bs-focus-ring-opacity))}.focus-ring-info{--bs-focus-ring-color:rgba(var(--bs-info-rgb), var(--bs-focus-ring-opacity))}.focus-ring-warning{--bs-focus-ring-color:rgba(var(--bs-warning-rgb), var(--bs-focus-ring-opacity))}.focus-ring-danger{--bs-focus-ring-color:rgba(var(--bs-danger-rgb), var(--bs-focus-ring-opacity))}.focus-ring-light{--bs-focus-ring-color:rgba(var(--bs-light-rgb), var(--bs-focus-ring-opacity))}.focus-ring-dark{--bs-focus-ring-color:rgba(var(--bs-dark-rgb), var(--bs-focus-ring-opacity))}.position-static{position:static!important}.position-relative{position:relative!important}.position-absolute{position:absolute!important}.position-fixed{position:fixed!important}.position-sticky{position:-webkit-sticky!important;position:sticky!important}.top-0{top:0!important}.top-50{top:50%!important}.top-100{top:100%!important}.bottom-0{bottom:0!important}.bottom-50{bottom:50%!important}.bottom-100{bottom:100%!important}.start-0{left:0!important}.start-50{left:50%!important}.start-100{left:100%!important}.end-0{right:0!important}.end-50{right:50%!important}.end-100{right:100%!important}.translate-middle{transform:translate(-50%,-50%)!important}.translate-middle-x{transform:translateX(-50%)!important}.translate-middle-y{transform:translateY(-50%)!important}.border{border:var(--bs-border-width) var(--bs-border-style) var(--bs-border-color)!important}.border-0{border:0!important}.border-top{border-top:var(--bs-border-width) var(--bs-border-style) var(--bs-border-color)!important}.border-top-0{border-top:0!important}.border-end{border-right:var(--bs-border-width) var(--bs-border-style) var(--bs-border-color)!important}.border-end-0{border-right:0!important}.border-bottom{border-bottom:var(--bs-border-width) var(--bs-border-style) var(--bs-border-color)!important}.border-bottom-0{border-bottom:0!important}.border-start{border-left:var(--bs-border-width) var(--bs-border-style) var(--bs-border-color)!important}.border-start-0{border-left:0!important}.border-primary{--bs-border-opacity:1;border-color:rgba(var(--bs-primary-rgb),var(--bs-border-opacity))!important}.border-secondary{--bs-border-opacity:1;border-color:rgba(var(--bs-secondary-rgb),var(--bs-border-opacity))!important}.border-success{--bs-border-opacity:1;border-color:rgba(var(--bs-success-rgb),var(--bs-border-opacity))!important}.border-info{--bs-border-opacity:1;border-color:rgba(var(--bs-info-rgb),var(--bs-border-opacity))!important}.border-warning{--bs-border-opacity:1;border-color:rgba(var(--bs-warning-rgb),var(--bs-border-opacity))!important}.border-danger{--bs-border-opacity:1;border-color:rgba(var(--bs-danger-rgb),var(--bs-border-opacity))!important}.border-light{--bs-border-opacity:1;border-color:rgba(var(--bs-light-rgb),var(--bs-border-opacity))!important}.border-dark{--bs-border-opacity:1;border-color:rgba(var(--bs-dark-rgb),var(--bs-border-opacity))!important}.border-black{--bs-border-opacity:1;border-color:rgba(var(--bs-black-rgb),var(--bs-border-opacity))!important}.border-white{--bs-border-opacity:1;border-color:rgba(var(--bs-white-rgb),var(--bs-border-opacity))!important}.border-primary-subtle{border-color:var(--bs-primary-border-subtle)!important}.border-secondary-subtle{border-color:var(--bs-secondary-border-subtle)!important}.border-success-subtle{border-color:var(--bs-success-border-subtle)!important}.border-info-subtle{border-color:var(--bs-info-border-subtle)!important}.border-warning-subtle{border-color:var(--bs-warning-border-subtle)!important}.border-danger-subtle{border-color:var(--bs-danger-border-subtle)!important}.border-light-subtle{border-color:var(--bs-light-border-subtle)!important}.border-dark-subtle{border-color:var(--bs-dark-border-subtle)!important}.border-1{border-width:1px!important}.border-2{border-width:2px!important}.border-3{border-width:3px!important}.border-4{border-width:4px!important}.border-5{border-width:5px!important}.border-opacity-10{--bs-border-opacity:0.1}.border-opacity-25{--bs-border-opacity:0.25}.border-opacity-50{--bs-border-opacity:0.5}.border-opacity-75{--bs-border-opacity:0.75}.border-opacity-100{--bs-border-opacity:1}.w-25{width:25%!important}.w-50{width:50%!important}.w-75{width:75%!important}.w-100{width:100%!important}.w-auto{width:auto!important}.mw-100{max-width:100%!important}.vw-100{width:100vw!important}.min-vw-100{min-width:100vw!important}.h-25{height:25%!important}.h-50{height:50%!important}.h-75{height:75%!important}.h-100{height:100%!important}.h-auto{height:auto!important}.mh-100{max-height:100%!important}.vh-100{height:100vh!important}.min-vh-100{min-height:100vh!important}.flex-fill{flex:1 1 auto!important}.flex-row{flex-direction:row!important}.flex-column{flex-direction:column!important}.flex-row-reverse{flex-direction:row-reverse!important}.flex-column-reverse{flex-direction:column-reverse!important}.flex-grow-0{flex-grow:0!important}.flex-grow-1{flex-grow:1!important}.flex-shrink-0{flex-shrink:0!important}.flex-shrink-1{flex-shrink:1!important}.flex-wrap{flex-wrap:wrap!important}.flex-nowrap{flex-wrap:nowrap!important}.flex-wrap-reverse{flex-wrap:wrap-reverse!important}.justify-content-start{justify-content:flex-start!important}.justify-content-end{justify-content:flex-end!important}.justify-content-center{justify-content:center!important}.justify-content-between{justify-content:space-between!important}.justify-content-around{justify-content:space-around!important}.justify-content-evenly{justify-content:space-evenly!important}.align-items-start{align-items:flex-start!important}.align-items-end{align-items:flex-end!important}.align-items-center{align-items:center!important}.align-items-baseline{align-items:baseline!important}.align-items-stretch{align-items:stretch!important}.align-content-start{align-content:flex-start!important}.align-content-end{align-content:flex-end!important}.align-content-center{align-content:center!important}.align-content-between{align-content:space-between!important}.align-content-around{align-content:space-around!important}.align-content-stretch{align-content:stretch!important}.align-self-auto{align-self:auto!important}.align-self-start{align-self:flex-start!important}.align-self-end{align-self:flex-end!important}.align-self-center{align-self:center!important}.align-self-baseline{align-self:baseline!important}.align-self-stretch{align-self:stretch!important}.order-first{order:-1!important}.order-0{order:0!important}.order-1{order:1!important}.order-2{order:2!important}.order-3{order:3!important}.order-4{order:4!important}.order-5{order:5!important}.order-last{order:6!important}.m-0{margin:0!important}.m-1{margin:.25rem!important}.m-2{margin:.5rem!important}.m-3{margin:1rem!important}.m-4{margin:1.5rem!important}.m-5{margin:3rem!important}.m-auto{margin:auto!important}.mx-0{margin-right:0!important;margin-left:0!important}.mx-1{margin-right:.25rem!important;margin-left:.25rem!important}.mx-2{margin-right:.5rem!important;margin-left:.5rem!important}.mx-3{margin-right:1rem!important;margin-left:1rem!important}.mx-4{margin-right:1.5rem!important;margin-left:1.5rem!important}.mx-5{margin-right:3rem!important;margin-left:3rem!important}.mx-auto{margin-right:auto!important;margin-left:auto!important}.my-0{margin-top:0!important;margin-bottom:0!important}.my-1{margin-top:.25rem!important;margin-bottom:.25rem!important}.my-2{margin-top:.5rem!important;margin-bottom:.5rem!important}.my-3{margin-top:1rem!important;margin-bottom:1rem!important}.my-4{margin-top:1.5rem!important;margin-bottom:1.5rem!important}.my-5{margin-top:3rem!important;margin-bottom:3rem!important}.my-auto{margin-top:auto!important;margin-bottom:auto!important}.mt-0{margin-top:0!important}.mt-1{margin-top:.25rem!important}.mt-2{margin-top:.5rem!important}.mt-3{margin-top:1rem!important}.mt-4{margin-top:1.5rem!important}.mt-5{margin-top:3rem!important}.mt-auto{margin-top:auto!important}.me-0{margin-right:0!important}.me-1{margin-right:.25rem!important}.me-2{margin-right:.5rem!important}.me-3{margin-right:1rem!important}.me-4{margin-right:1.5rem!important}.me-5{margin-right:3rem!important}.me-auto{margin-right:auto!important}.mb-0{margin-bottom:0!important}.mb-1{margin-bottom:.25rem!important}.mb-2{margin-bottom:.5rem!important}.mb-3{margin-bottom:1rem!important}.mb-4{margin-bottom:1.5rem!important}.mb-5{margin-bottom:3rem!important}.mb-auto{margin-bottom:auto!important}.ms-0{margin-left:0!important}.ms-1{margin-left:.25rem!important}.ms-2{margin-left:.5rem!important}.ms-3{margin-left:1rem!important}.ms-4{margin-left:1.5rem!important}.ms-5{margin-left:3rem!important}.ms-auto{margin-left:auto!important}.p-0{padding:0!important}.p-1{padding:.25rem!important}.p-2{padding:.5rem!important}.p-3{padding:1rem!important}.p-4{padding:1.5rem!important}.p-5{padding:3rem!important}.px-0{padding-right:0!important;padding-left:0!important}.px-1{padding-right:.25rem!important;padding-left:.25rem!important}.px-2{padding-right:.5rem!important;padding-left:.5rem!important}.px-3{padding-right:1rem!important;padding-left:1rem!important}.px-4{padding-right:1.5rem!important;padding-left:1.5rem!important}.px-5{padding-right:3rem!important;padding-left:3rem!important}.py-0{padding-top:0!important;padding-bottom:0!important}.py-1{padding-top:.25rem!important;padding-bottom:.25rem!important}.py-2{padding-top:.5rem!important;padding-bottom:.5rem!important}.py-3{padding-top:1rem!important;padding-bottom:1rem!important}.py-4{padding-top:1.5rem!important;padding-bottom:1.5rem!important}.py-5{padding-top:3rem!important;padding-bottom:3rem!important}.pt-0{padding-top:0!important}.pt-1{padding-top:.25rem!important}.pt-2{padding-top:.5rem!important}.pt-3{padding-top:1rem!important}.pt-4{padding-top:1.5rem!important}.pt-5{padding-top:3rem!important}.pe-0{padding-right:0!important}.pe-1{padding-right:.25rem!important}.pe-2{padding-right:.5rem!important}.pe-3{padding-right:1rem!important}.pe-4{padding-right:1.5rem!important}.pe-5{padding-right:3rem!important}.pb-0{padding-bottom:0!important}.pb-1{padding-bottom:.25rem!important}.pb-2{padding-bottom:.5rem!important}.pb-3{padding-bottom:1rem!important}.pb-4{padding-bottom:1.5rem!important}.pb-5{padding-bottom:3rem!important}.ps-0{padding-left:0!important}.ps-1{padding-left:.25rem!important}.ps-2{padding-left:.5rem!important}.ps-3{padding-left:1rem!important}.ps-4{padding-left:1.5rem!important}.ps-5{padding-left:3rem!important}.gap-0{gap:0!important}.gap-1{gap:.25rem!important}.gap-2{gap:.5rem!important}.gap-3{gap:1rem!important}.gap-4{gap:1.5rem!important}.gap-5{gap:3rem!important}.row-gap-0{row-gap:0!important}.row-gap-1{row-gap:.25rem!important}.row-gap-2{row-gap:.5rem!important}.row-gap-3{row-gap:1rem!important}.row-gap-4{row-gap:1.5rem!important}.row-gap-5{row-gap:3rem!important}.column-gap-0{-moz-column-gap:0!important;column-gap:0!important}.column-gap-1{-moz-column-gap:0.25rem!important;column-gap:.25rem!important}.column-gap-2{-moz-column-gap:0.5rem!important;column-gap:.5rem!important}.column-gap-3{-moz-column-gap:1rem!important;column-gap:1rem!important}.column-gap-4{-moz-column-gap:1.5rem!important;column-gap:1.5rem!important}.column-gap-5{-moz-column-gap:3rem!important;column-gap:3rem!important}.font-monospace{font-family:var(--bs-font-monospace)!important}.fs-1{font-size:calc(1.375rem + 1.5vw)!important}.fs-2{font-size:calc(1.325rem + .9vw)!important}.fs-3{font-size:calc(1.3rem + .6vw)!important}.fs-4{font-size:calc(1.275rem + .3vw)!important}.fs-5{font-size:1.25rem!important}.fs-6{font-size:1rem!important}.fst-italic{font-style:italic!important}.fst-normal{font-style:normal!important}.fw-lighter{font-weight:lighter!important}.fw-light{font-weight:300!important}.fw-normal{font-weight:400!important}.fw-medium{font-weight:500!important}.fw-semibold{font-weight:600!important}.fw-bold{font-weight:700!important}.fw-bolder{font-weight:bolder!important}.lh-1{line-height:1!important}.lh-sm{line-height:1.25!important}.lh-base{line-height:1.5!important}.lh-lg{line-height:2!important}.text-start{text-align:left!important}.text-end{text-align:right!important}.text-center{text-align:center!important}.text-decoration-none{text-decoration:none!important}.text-decoration-underline{text-decoration:underline!important}.text-decoration-line-through{text-decoration:line-through!important}.text-lowercase{text-transform:lowercase!important}.text-uppercase{text-transform:uppercase!important}.text-capitalize{text-transform:capitalize!important}.text-wrap{white-space:normal!important}.text-nowrap{white-space:nowrap!important}.text-break{word-wrap:break-word!important;word-break:break-word!important}.text-primary{--bs-text-opacity:1;color:rgba(var(--bs-primary-rgb),var(--bs-text-opacity))!important}.text-secondary{--bs-text-opacity:1;color:rgba(var(--bs-secondary-rgb),var(--bs-text-opacity))!important}.text-success{--bs-text-opacity:1;color:rgba(var(--bs-success-rgb),var(--bs-text-opacity))!important}.text-info{--bs-text-opacity:1;color:rgba(var(--bs-info-rgb),var(--bs-text-opacity))!important}.text-warning{--bs-text-opacity:1;color:rgba(var(--bs-warning-rgb),var(--bs-text-opacity))!important}.text-danger{--bs-text-opacity:1;color:rgba(var(--bs-danger-rgb),var(--bs-text-opacity))!important}.text-light{--bs-text-opacity:1;color:rgba(var(--bs-light-rgb),var(--bs-text-opacity))!important}.text-dark{--bs-text-opacity:1;color:rgba(var(--bs-dark-rgb),var(--bs-text-opacity))!important}.text-black{--bs-text-opacity:1;color:rgba(var(--bs-black-rgb),var(--bs-text-opacity))!important}.text-white{--bs-text-opacity:1;color:rgba(var(--bs-white-rgb),var(--bs-text-opacity))!important}.text-body{--bs-text-opacity:1;color:rgba(var(--bs-body-color-rgb),var(--bs-text-opacity))!important}.text-muted{--bs-text-opacity:1;color:var(--bs-secondary-color)!important}.text-black-50{--bs-text-opacity:1;color:rgba(0,0,0,.5)!important}.text-white-50{--bs-text-opacity:1;color:rgba(255,255,255,.5)!important}.text-body-secondary{--bs-text-opacity:1;color:var(--bs-secondary-color)!important}.text-body-tertiary{--bs-text-opacity:1;color:var(--bs-tertiary-color)!important}.text-body-emphasis{--bs-text-opacity:1;color:var(--bs-emphasis-color)!important}.text-reset{--bs-text-opacity:1;color:inherit!important}.text-opacity-25{--bs-text-opacity:0.25}.text-opacity-50{--bs-text-opacity:0.5}.text-opacity-75{--bs-text-opacity:0.75}.text-opacity-100{--bs-text-opacity:1}.text-primary-emphasis{color:var(--bs-primary-text-emphasis)!important}.text-secondary-emphasis{color:var(--bs-secondary-text-emphasis)!important}.text-success-emphasis{color:var(--bs-success-text-emphasis)!important}.text-info-emphasis{color:var(--bs-info-text-emphasis)!important}.text-warning-emphasis{color:var(--bs-warning-text-emphasis)!important}.text-danger-emphasis{color:var(--bs-danger-text-emphasis)!important}.text-light-emphasis{color:var(--bs-light-text-emphasis)!important}.text-dark-emphasis{color:var(--bs-dark-text-emphasis)!important}.link-opacity-10{--bs-link-opacity:0.1}.link-opacity-10-hover:hover{--bs-link-opacity:0.1}.link-opacity-25{--bs-link-opacity:0.25}.link-opacity-25-hover:hover{--bs-link-opacity:0.25}.link-opacity-50{--bs-link-opacity:0.5}.link-opacity-50-hover:hover{--bs-link-opacity:0.5}.link-opacity-75{--bs-link-opacity:0.75}.link-opacity-75-hover:hover{--bs-link-opacity:0.75}.link-opacity-100{--bs-link-opacity:1}.link-opacity-100-hover:hover{--bs-link-opacity:1}.link-offset-1{text-underline-offset:0.125em!important}.link-offset-1-hover:hover{text-underline-offset:0.125em!important}.link-offset-2{text-underline-offset:0.25em!important}.link-offset-2-hover:hover{text-underline-offset:0.25em!important}.link-offset-3{text-underline-offset:0.375em!important}.link-offset-3-hover:hover{text-underline-offset:0.375em!important}.link-underline-primary{--bs-link-underline-opacity:1;-webkit-text-decoration-color:rgba(var(--bs-primary-rgb),var(--bs-link-underline-opacity))!important;text-decoration-color:rgba(var(--bs-primary-rgb),var(--bs-link-underline-opacity))!important}.link-underline-secondary{--bs-link-underline-opacity:1;-webkit-text-decoration-color:rgba(var(--bs-secondary-rgb),var(--bs-link-underline-opacity))!important;text-decoration-color:rgba(var(--bs-secondary-rgb),var(--bs-link-underline-opacity))!important}.link-underline-success{--bs-link-underline-opacity:1;-webkit-text-decoration-color:rgba(var(--bs-success-rgb),var(--bs-link-underline-opacity))!important;text-decoration-color:rgba(var(--bs-success-rgb),var(--bs-link-underline-opacity))!important}.link-underline-info{--bs-link-underline-opacity:1;-webkit-text-decoration-color:rgba(var(--bs-info-rgb),var(--bs-link-underline-opacity))!important;text-decoration-color:rgba(var(--bs-info-rgb),var(--bs-link-underline-opacity))!important}.link-underline-warning{--bs-link-underline-opacity:1;-webkit-text-decoration-color:rgba(var(--bs-warning-rgb),var(--bs-link-underline-opacity))!important;text-decoration-color:rgba(var(--bs-warning-rgb),var(--bs-link-underline-opacity))!important}.link-underline-danger{--bs-link-underline-opacity:1;-webkit-text-decoration-color:rgba(var(--bs-danger-rgb),var(--bs-link-underline-opacity))!important;text-decoration-color:rgba(var(--bs-danger-rgb),var(--bs-link-underline-opacity))!important}.link-underline-light{--bs-link-underline-opacity:1;-webkit-text-decoration-color:rgba(var(--bs-light-rgb),var(--bs-link-underline-opacity))!important;text-decoration-color:rgba(var(--bs-light-rgb),var(--bs-link-underline-opacity))!important}.link-underline-dark{--bs-link-underline-opacity:1;-webkit-text-decoration-color:rgba(var(--bs-dark-rgb),var(--bs-link-underline-opacity))!important;text-decoration-color:rgba(var(--bs-dark-rgb),var(--bs-link-underline-opacity))!important}.link-underline{--bs-link-underline-opacity:1;-webkit-text-decoration-color:rgba(var(--bs-link-color-rgb),var(--bs-link-underline-opacity,1))!important;text-decoration-color:rgba(var(--bs-link-color-rgb),var(--bs-link-underline-opacity,1))!important}.link-underline-opacity-0{--bs-link-underline-opacity:0}.link-underline-opacity-0-hover:hover{--bs-link-underline-opacity:0}.link-underline-opacity-10{--bs-link-underline-opacity:0.1}.link-underline-opacity-10-hover:hover{--bs-link-underline-opacity:0.1}.link-underline-opacity-25{--bs-link-underline-opacity:0.25}.link-underline-opacity-25-hover:hover{--bs-link-underline-opacity:0.25}.link-underline-opacity-50{--bs-link-underline-opacity:0.5}.link-underline-opacity-50-hover:hover{--bs-link-underline-opacity:0.5}.link-underline-opacity-75{--bs-link-underline-opacity:0.75}.link-underline-opacity-75-hover:hover{--bs-link-underline-opacity:0.75}.link-underline-opacity-100{--bs-link-underline-opacity:1}.link-underline-opacity-100-hover:hover{--bs-link-underline-opacity:1}.bg-primary{--bs-bg-opacity:1;background-color:rgba(var(--bs-primary-rgb),var(--bs-bg-opacity))!important}.bg-secondary{--bs-bg-opacity:1;background-color:rgba(var(--bs-secondary-rgb),var(--bs-bg-opacity))!important}.bg-success{--bs-bg-opacity:1;background-color:rgba(var(--bs-success-rgb),var(--bs-bg-opacity))!important}.bg-info{--bs-bg-opacity:1;background-color:rgba(var(--bs-info-rgb),var(--bs-bg-opacity))!important}.bg-warning{--bs-bg-opacity:1;background-color:rgba(var(--bs-warning-rgb),var(--bs-bg-opacity))!important}.bg-danger{--bs-bg-opacity:1;background-color:rgba(var(--bs-danger-rgb),var(--bs-bg-opacity))!important}.bg-light{--bs-bg-opacity:1;background-color:rgba(var(--bs-light-rgb),var(--bs-bg-opacity))!important}.bg-dark{--bs-bg-opacity:1;background-color:rgba(var(--bs-dark-rgb),var(--bs-bg-opacity))!important}.bg-black{--bs-bg-opacity:1;background-color:rgba(var(--bs-black-rgb),var(--bs-bg-opacity))!important}.bg-white{--bs-bg-opacity:1;background-color:rgba(var(--bs-white-rgb),var(--bs-bg-opacity))!important}.bg-body{--bs-bg-opacity:1;background-color:rgba(var(--bs-body-bg-rgb),var(--bs-bg-opacity))!important}.bg-transparent{--bs-bg-opacity:1;background-color:transparent!important}.bg-body-secondary{--bs-bg-opacity:1;background-color:rgba(var(--bs-secondary-bg-rgb),var(--bs-bg-opacity))!important}.bg-body-tertiary{--bs-bg-opacity:1;background-color:rgba(var(--bs-tertiary-bg-rgb),var(--bs-bg-opacity))!important}.bg-opacity-10{--bs-bg-opacity:0.1}.bg-opacity-25{--bs-bg-opacity:0.25}.bg-opacity-50{--bs-bg-opacity:0.5}.bg-opacity-75{--bs-bg-opacity:0.75}.bg-opacity-100{--bs-bg-opacity:1}.bg-primary-subtle{background-color:var(--bs-primary-bg-subtle)!important}.bg-secondary-subtle{background-color:var(--bs-secondary-bg-subtle)!important}.bg-success-subtle{background-color:var(--bs-success-bg-subtle)!important}.bg-info-subtle{background-color:var(--bs-info-bg-subtle)!important}.bg-warning-subtle{background-color:var(--bs-warning-bg-subtle)!important}.bg-danger-subtle{background-color:var(--bs-danger-bg-subtle)!important}.bg-light-subtle{background-color:var(--bs-light-bg-subtle)!important}.bg-dark-subtle{background-color:var(--bs-dark-bg-subtle)!important}.bg-gradient{background-image:var(--bs-gradient)!important}.user-select-all{-webkit-user-select:all!important;-moz-user-select:all!important;user-select:all!important}.user-select-auto{-webkit-user-select:auto!important;-moz-user-select:auto!important;user-select:auto!important}.user-select-none{-webkit-user-select:none!important;-moz-user-select:none!important;user-select:none!important}.pe-none{pointer-events:none!important}.pe-auto{pointer-events:auto!important}.rounded{border-radius:var(--bs-border-radius)!important}.rounded-0{border-radius:0!important}.rounded-1{border-radius:var(--bs-border-radius-sm)!important}.rounded-2{border-radius:var(--bs-border-radius)!important}.rounded-3{border-radius:var(--bs-border-radius-lg)!important}.rounded-4{border-radius:var(--bs-border-radius-xl)!important}.rounded-5{border-radius:var(--bs-border-radius-xxl)!important}.rounded-circle{border-radius:50%!important}.rounded-pill{border-radius:var(--bs-border-radius-pill)!important}.rounded-top{border-top-left-radius:var(--bs-border-radius)!important;border-top-right-radius:var(--bs-border-radius)!important}.rounded-top-0{border-top-left-radius:0!important;border-top-right-radius:0!important}.rounded-top-1{border-top-left-radius:var(--bs-border-radius-sm)!important;border-top-right-radius:var(--bs-border-radius-sm)!important}.rounded-top-2{border-top-left-radius:var(--bs-border-radius)!important;border-top-right-radius:var(--bs-border-radius)!important}.rounded-top-3{border-top-left-radius:var(--bs-border-radius-lg)!important;border-top-right-radius:var(--bs-border-radius-lg)!important}.rounded-top-4{border-top-left-radius:var(--bs-border-radius-xl)!important;border-top-right-radius:var(--bs-border-radius-xl)!important}.rounded-top-5{border-top-left-radius:var(--bs-border-radius-xxl)!important;border-top-right-radius:var(--bs-border-radius-xxl)!important}.rounded-top-circle{border-top-left-radius:50%!important;border-top-right-radius:50%!important}.rounded-top-pill{border-top-left-radius:var(--bs-border-radius-pill)!important;border-top-right-radius:var(--bs-border-radius-pill)!important}.rounded-end{border-top-right-radius:var(--bs-border-radius)!important;border-bottom-right-radius:var(--bs-border-radius)!important}.rounded-end-0{border-top-right-radius:0!important;border-bottom-right-radius:0!important}.rounded-end-1{border-top-right-radius:var(--bs-border-radius-sm)!important;border-bottom-right-radius:var(--bs-border-radius-sm)!important}.rounded-end-2{border-top-right-radius:var(--bs-border-radius)!important;border-bottom-right-radius:var(--bs-border-radius)!important}.rounded-end-3{border-top-right-radius:var(--bs-border-radius-lg)!important;border-bottom-right-radius:var(--bs-border-radius-lg)!important}.rounded-end-4{border-top-right-radius:var(--bs-border-radius-xl)!important;border-bottom-right-radius:var(--bs-border-radius-xl)!important}.rounded-end-5{border-top-right-radius:var(--bs-border-radius-xxl)!important;border-bottom-right-radius:var(--bs-border-radius-xxl)!important}.rounded-end-circle{border-top-right-radius:50%!important;border-bottom-right-radius:50%!important}.rounded-end-pill{border-top-right-radius:var(--bs-border-radius-pill)!important;border-bottom-right-radius:var(--bs-border-radius-pill)!important}.rounded-bottom{border-bottom-right-radius:var(--bs-border-radius)!important;border-bottom-left-radius:var(--bs-border-radius)!important}.rounded-bottom-0{border-bottom-right-radius:0!important;border-bottom-left-radius:0!important}.rounded-bottom-1{border-bottom-right-radius:var(--bs-border-radius-sm)!important;border-bottom-left-radius:var(--bs-border-radius-sm)!important}.rounded-bottom-2{border-bottom-right-radius:var(--bs-border-radius)!important;border-bottom-left-radius:var(--bs-border-radius)!important}.rounded-bottom-3{border-bottom-right-radius:var(--bs-border-radius-lg)!important;border-bottom-left-radius:var(--bs-border-radius-lg)!important}.rounded-bottom-4{border-bottom-right-radius:var(--bs-border-radius-xl)!important;border-bottom-left-radius:var(--bs-border-radius-xl)!important}.rounded-bottom-5{border-bottom-right-radius:var(--bs-border-radius-xxl)!important;border-bottom-left-radius:var(--bs-border-radius-xxl)!important}.rounded-bottom-circle{border-bottom-right-radius:50%!important;border-bottom-left-radius:50%!important}.rounded-bottom-pill{border-bottom-right-radius:var(--bs-border-radius-pill)!important;border-bottom-left-radius:var(--bs-border-radius-pill)!important}.rounded-start{border-bottom-left-radius:var(--bs-border-radius)!important;border-top-left-radius:var(--bs-border-radius)!important}.rounded-start-0{border-bottom-left-radius:0!important;border-top-left-radius:0!important}.rounded-start-1{border-bottom-left-radius:var(--bs-border-radius-sm)!important;border-top-left-radius:var(--bs-border-radius-sm)!important}.rounded-start-2{border-bottom-left-radius:var(--bs-border-radius)!important;border-top-left-radius:var(--bs-border-radius)!important}.rounded-start-3{border-bottom-left-radius:var(--bs-border-radius-lg)!important;border-top-left-radius:var(--bs-border-radius-lg)!important}.rounded-start-4{border-bottom-left-radius:var(--bs-border-radius-xl)!important;border-top-left-radius:var(--bs-border-radius-xl)!important}.rounded-start-5{border-bottom-left-radius:var(--bs-border-radius-xxl)!important;border-top-left-radius:var(--bs-border-radius-xxl)!important}.rounded-start-circle{border-bottom-left-radius:50%!important;border-top-left-radius:50%!important}.rounded-start-pill{border-bottom-left-radius:var(--bs-border-radius-pill)!important;border-top-left-radius:var(--bs-border-radius-pill)!important}.visible{visibility:visible!important}.invisible{visibility:hidden!important}.z-n1{z-index:-1!important}.z-0{z-index:0!important}.z-1{z-index:1!important}.z-2{z-index:2!important}.z-3{z-index:3!important}@media (min-width:576px){.float-sm-start{float:left!important}.float-sm-end{float:right!important}.float-sm-none{float:none!important}.object-fit-sm-contain{-o-object-fit:contain!important;object-fit:contain!important}.object-fit-sm-cover{-o-object-fit:cover!important;object-fit:cover!important}.object-fit-sm-fill{-o-object-fit:fill!important;object-fit:fill!important}.object-fit-sm-scale{-o-object-fit:scale-down!important;object-fit:scale-down!important}.object-fit-sm-none{-o-object-fit:none!important;object-fit:none!important}.d-sm-inline{display:inline!important}.d-sm-inline-block{display:inline-block!important}.d-sm-block{display:block!important}.d-sm-grid{display:grid!important}.d-sm-inline-grid{display:inline-grid!important}.d-sm-table{display:table!important}.d-sm-table-row{display:table-row!important}.d-sm-table-cell{display:table-cell!important}.d-sm-flex{display:flex!important}.d-sm-inline-flex{display:inline-flex!important}.d-sm-none{display:none!important}.flex-sm-fill{flex:1 1 auto!important}.flex-sm-row{flex-direction:row!important}.flex-sm-column{flex-direction:column!important}.flex-sm-row-reverse{flex-direction:row-reverse!important}.flex-sm-column-reverse{flex-direction:column-reverse!important}.flex-sm-grow-0{flex-grow:0!important}.flex-sm-grow-1{flex-grow:1!important}.flex-sm-shrink-0{flex-shrink:0!important}.flex-sm-shrink-1{flex-shrink:1!important}.flex-sm-wrap{flex-wrap:wrap!important}.flex-sm-nowrap{flex-wrap:nowrap!important}.flex-sm-wrap-reverse{flex-wrap:wrap-reverse!important}.justify-content-sm-start{justify-content:flex-start!important}.justify-content-sm-end{justify-content:flex-end!important}.justify-content-sm-center{justify-content:center!important}.justify-content-sm-between{justify-content:space-between!important}.justify-content-sm-around{justify-content:space-around!important}.justify-content-sm-evenly{justify-content:space-evenly!important}.align-items-sm-start{align-items:flex-start!important}.align-items-sm-end{align-items:flex-end!important}.align-items-sm-center{align-items:center!important}.align-items-sm-baseline{align-items:baseline!important}.align-items-sm-stretch{align-items:stretch!important}.align-content-sm-start{align-content:flex-start!important}.align-content-sm-end{align-content:flex-end!important}.align-content-sm-center{align-content:center!important}.align-content-sm-between{align-content:space-between!important}.align-content-sm-around{align-content:space-around!important}.align-content-sm-stretch{align-content:stretch!important}.align-self-sm-auto{align-self:auto!important}.align-self-sm-start{align-self:flex-start!important}.align-self-sm-end{align-self:flex-end!important}.align-self-sm-center{align-self:center!important}.align-self-sm-baseline{align-self:baseline!important}.align-self-sm-stretch{align-self:stretch!important}.order-sm-first{order:-1!important}.order-sm-0{order:0!important}.order-sm-1{order:1!important}.order-sm-2{order:2!important}.order-sm-3{order:3!important}.order-sm-4{order:4!important}.order-sm-5{order:5!important}.order-sm-last{order:6!important}.m-sm-0{margin:0!important}.m-sm-1{margin:.25rem!important}.m-sm-2{margin:.5rem!important}.m-sm-3{margin:1rem!important}.m-sm-4{margin:1.5rem!important}.m-sm-5{margin:3rem!important}.m-sm-auto{margin:auto!important}.mx-sm-0{margin-right:0!important;margin-left:0!important}.mx-sm-1{margin-right:.25rem!important;margin-left:.25rem!important}.mx-sm-2{margin-right:.5rem!important;margin-left:.5rem!important}.mx-sm-3{margin-right:1rem!important;margin-left:1rem!important}.mx-sm-4{margin-right:1.5rem!important;margin-left:1.5rem!important}.mx-sm-5{margin-right:3rem!important;margin-left:3rem!important}.mx-sm-auto{margin-right:auto!important;margin-left:auto!important}.my-sm-0{margin-top:0!important;margin-bottom:0!important}.my-sm-1{margin-top:.25rem!important;margin-bottom:.25rem!important}.my-sm-2{margin-top:.5rem!important;margin-bottom:.5rem!important}.my-sm-3{margin-top:1rem!important;margin-bottom:1rem!important}.my-sm-4{margin-top:1.5rem!important;margin-bottom:1.5rem!important}.my-sm-5{margin-top:3rem!important;margin-bottom:3rem!important}.my-sm-auto{margin-top:auto!important;margin-bottom:auto!important}.mt-sm-0{margin-top:0!important}.mt-sm-1{margin-top:.25rem!important}.mt-sm-2{margin-top:.5rem!important}.mt-sm-3{margin-top:1rem!important}.mt-sm-4{margin-top:1.5rem!important}.mt-sm-5{margin-top:3rem!important}.mt-sm-auto{margin-top:auto!important}.me-sm-0{margin-right:0!important}.me-sm-1{margin-right:.25rem!important}.me-sm-2{margin-right:.5rem!important}.me-sm-3{margin-right:1rem!important}.me-sm-4{margin-right:1.5rem!important}.me-sm-5{margin-right:3rem!important}.me-sm-auto{margin-right:auto!important}.mb-sm-0{margin-bottom:0!important}.mb-sm-1{margin-bottom:.25rem!important}.mb-sm-2{margin-bottom:.5rem!important}.mb-sm-3{margin-bottom:1rem!important}.mb-sm-4{margin-bottom:1.5rem!important}.mb-sm-5{margin-bottom:3rem!important}.mb-sm-auto{margin-bottom:auto!important}.ms-sm-0{margin-left:0!important}.ms-sm-1{margin-left:.25rem!important}.ms-sm-2{margin-left:.5rem!important}.ms-sm-3{margin-left:1rem!important}.ms-sm-4{margin-left:1.5rem!important}.ms-sm-5{margin-left:3rem!important}.ms-sm-auto{margin-left:auto!important}.p-sm-0{padding:0!important}.p-sm-1{padding:.25rem!important}.p-sm-2{padding:.5rem!important}.p-sm-3{padding:1rem!important}.p-sm-4{padding:1.5rem!important}.p-sm-5{padding:3rem!important}.px-sm-0{padding-right:0!important;padding-left:0!important}.px-sm-1{padding-right:.25rem!important;padding-left:.25rem!important}.px-sm-2{padding-right:.5rem!important;padding-left:.5rem!important}.px-sm-3{padding-right:1rem!important;padding-left:1rem!important}.px-sm-4{padding-right:1.5rem!important;padding-left:1.5rem!important}.px-sm-5{padding-right:3rem!important;padding-left:3rem!important}.py-sm-0{padding-top:0!important;padding-bottom:0!important}.py-sm-1{padding-top:.25rem!important;padding-bottom:.25rem!important}.py-sm-2{padding-top:.5rem!important;padding-bottom:.5rem!important}.py-sm-3{padding-top:1rem!important;padding-bottom:1rem!important}.py-sm-4{padding-top:1.5rem!important;padding-bottom:1.5rem!important}.py-sm-5{padding-top:3rem!important;padding-bottom:3rem!important}.pt-sm-0{padding-top:0!important}.pt-sm-1{padding-top:.25rem!important}.pt-sm-2{padding-top:.5rem!important}.pt-sm-3{padding-top:1rem!important}.pt-sm-4{padding-top:1.5rem!important}.pt-sm-5{padding-top:3rem!important}.pe-sm-0{padding-right:0!important}.pe-sm-1{padding-right:.25rem!important}.pe-sm-2{padding-right:.5rem!important}.pe-sm-3{padding-right:1rem!important}.pe-sm-4{padding-right:1.5rem!important}.pe-sm-5{padding-right:3rem!important}.pb-sm-0{padding-bottom:0!important}.pb-sm-1{padding-bottom:.25rem!important}.pb-sm-2{padding-bottom:.5rem!important}.pb-sm-3{padding-bottom:1rem!important}.pb-sm-4{padding-bottom:1.5rem!important}.pb-sm-5{padding-bottom:3rem!important}.ps-sm-0{padding-left:0!important}.ps-sm-1{padding-left:.25rem!important}.ps-sm-2{padding-left:.5rem!important}.ps-sm-3{padding-left:1rem!important}.ps-sm-4{padding-left:1.5rem!important}.ps-sm-5{padding-left:3rem!important}.gap-sm-0{gap:0!important}.gap-sm-1{gap:.25rem!important}.gap-sm-2{gap:.5rem!important}.gap-sm-3{gap:1rem!important}.gap-sm-4{gap:1.5rem!important}.gap-sm-5{gap:3rem!important}.row-gap-sm-0{row-gap:0!important}.row-gap-sm-1{row-gap:.25rem!important}.row-gap-sm-2{row-gap:.5rem!important}.row-gap-sm-3{row-gap:1rem!important}.row-gap-sm-4{row-gap:1.5rem!important}.row-gap-sm-5{row-gap:3rem!important}.column-gap-sm-0{-moz-column-gap:0!important;column-gap:0!important}.column-gap-sm-1{-moz-column-gap:0.25rem!important;column-gap:.25rem!important}.column-gap-sm-2{-moz-column-gap:0.5rem!important;column-gap:.5rem!important}.column-gap-sm-3{-moz-column-gap:1rem!important;column-gap:1rem!important}.column-gap-sm-4{-moz-column-gap:1.5rem!important;column-gap:1.5rem!important}.column-gap-sm-5{-moz-column-gap:3rem!important;column-gap:3rem!important}.text-sm-start{text-align:left!important}.text-sm-end{text-align:right!important}.text-sm-center{text-align:center!important}}@media (min-width:768px){.float-md-start{float:left!important}.float-md-end{float:right!important}.float-md-none{float:none!important}.object-fit-md-contain{-o-object-fit:contain!important;object-fit:contain!important}.object-fit-md-cover{-o-object-fit:cover!important;object-fit:cover!important}.object-fit-md-fill{-o-object-fit:fill!important;object-fit:fill!important}.object-fit-md-scale{-o-object-fit:scale-down!important;object-fit:scale-down!important}.object-fit-md-none{-o-object-fit:none!important;object-fit:none!important}.d-md-inline{display:inline!important}.d-md-inline-block{display:inline-block!important}.d-md-block{display:block!important}.d-md-grid{display:grid!important}.d-md-inline-grid{display:inline-grid!important}.d-md-table{display:table!important}.d-md-table-row{display:table-row!important}.d-md-table-cell{display:table-cell!important}.d-md-flex{display:flex!important}.d-md-inline-flex{display:inline-flex!important}.d-md-none{display:none!important}.flex-md-fill{flex:1 1 auto!important}.flex-md-row{flex-direction:row!important}.flex-md-column{flex-direction:column!important}.flex-md-row-reverse{flex-direction:row-reverse!important}.flex-md-column-reverse{flex-direction:column-reverse!important}.flex-md-grow-0{flex-grow:0!important}.flex-md-grow-1{flex-grow:1!important}.flex-md-shrink-0{flex-shrink:0!important}.flex-md-shrink-1{flex-shrink:1!important}.flex-md-wrap{flex-wrap:wrap!important}.flex-md-nowrap{flex-wrap:nowrap!important}.flex-md-wrap-reverse{flex-wrap:wrap-reverse!important}.justify-content-md-start{justify-content:flex-start!important}.justify-content-md-end{justify-content:flex-end!important}.justify-content-md-center{justify-content:center!important}.justify-content-md-between{justify-content:space-between!important}.justify-content-md-around{justify-content:space-around!important}.justify-content-md-evenly{justify-content:space-evenly!important}.align-items-md-start{align-items:flex-start!important}.align-items-md-end{align-items:flex-end!important}.align-items-md-center{align-items:center!important}.align-items-md-baseline{align-items:baseline!important}.align-items-md-stretch{align-items:stretch!important}.align-content-md-start{align-content:flex-start!important}.align-content-md-end{align-content:flex-end!important}.align-content-md-center{align-content:center!important}.align-content-md-between{align-content:space-between!important}.align-content-md-around{align-content:space-around!important}.align-content-md-stretch{align-content:stretch!important}.align-self-md-auto{align-self:auto!important}.align-self-md-start{align-self:flex-start!important}.align-self-md-end{align-self:flex-end!important}.align-self-md-center{align-self:center!important}.align-self-md-baseline{align-self:baseline!important}.align-self-md-stretch{align-self:stretch!important}.order-md-first{order:-1!important}.order-md-0{order:0!important}.order-md-1{order:1!important}.order-md-2{order:2!important}.order-md-3{order:3!important}.order-md-4{order:4!important}.order-md-5{order:5!important}.order-md-last{order:6!important}.m-md-0{margin:0!important}.m-md-1{margin:.25rem!important}.m-md-2{margin:.5rem!important}.m-md-3{margin:1rem!important}.m-md-4{margin:1.5rem!important}.m-md-5{margin:3rem!important}.m-md-auto{margin:auto!important}.mx-md-0{margin-right:0!important;margin-left:0!important}.mx-md-1{margin-right:.25rem!important;margin-left:.25rem!important}.mx-md-2{margin-right:.5rem!important;margin-left:.5rem!important}.mx-md-3{margin-right:1rem!important;margin-left:1rem!important}.mx-md-4{margin-right:1.5rem!important;margin-left:1.5rem!important}.mx-md-5{margin-right:3rem!important;margin-left:3rem!important}.mx-md-auto{margin-right:auto!important;margin-left:auto!important}.my-md-0{margin-top:0!important;margin-bottom:0!important}.my-md-1{margin-top:.25rem!important;margin-bottom:.25rem!important}.my-md-2{margin-top:.5rem!important;margin-bottom:.5rem!important}.my-md-3{margin-top:1rem!important;margin-bottom:1rem!important}.my-md-4{margin-top:1.5rem!important;margin-bottom:1.5rem!important}.my-md-5{margin-top:3rem!important;margin-bottom:3rem!important}.my-md-auto{margin-top:auto!important;margin-bottom:auto!important}.mt-md-0{margin-top:0!important}.mt-md-1{margin-top:.25rem!important}.mt-md-2{margin-top:.5rem!important}.mt-md-3{margin-top:1rem!important}.mt-md-4{margin-top:1.5rem!important}.mt-md-5{margin-top:3rem!important}.mt-md-auto{margin-top:auto!important}.me-md-0{margin-right:0!important}.me-md-1{margin-right:.25rem!important}.me-md-2{margin-right:.5rem!important}.me-md-3{margin-right:1rem!important}.me-md-4{margin-right:1.5rem!important}.me-md-5{margin-right:3rem!important}.me-md-auto{margin-right:auto!important}.mb-md-0{margin-bottom:0!important}.mb-md-1{margin-bottom:.25rem!important}.mb-md-2{margin-bottom:.5rem!important}.mb-md-3{margin-bottom:1rem!important}.mb-md-4{margin-bottom:1.5rem!important}.mb-md-5{margin-bottom:3rem!important}.mb-md-auto{margin-bottom:auto!important}.ms-md-0{margin-left:0!important}.ms-md-1{margin-left:.25rem!important}.ms-md-2{margin-left:.5rem!important}.ms-md-3{margin-left:1rem!important}.ms-md-4{margin-left:1.5rem!important}.ms-md-5{margin-left:3rem!important}.ms-md-auto{margin-left:auto!important}.p-md-0{padding:0!important}.p-md-1{padding:.25rem!important}.p-md-2{padding:.5rem!important}.p-md-3{padding:1rem!important}.p-md-4{padding:1.5rem!important}.p-md-5{padding:3rem!important}.px-md-0{padding-right:0!important;padding-left:0!important}.px-md-1{padding-right:.25rem!important;padding-left:.25rem!important}.px-md-2{padding-right:.5rem!important;padding-left:.5rem!important}.px-md-3{padding-right:1rem!important;padding-left:1rem!important}.px-md-4{padding-right:1.5rem!important;padding-left:1.5rem!important}.px-md-5{padding-right:3rem!important;padding-left:3rem!important}.py-md-0{padding-top:0!important;padding-bottom:0!important}.py-md-1{padding-top:.25rem!important;padding-bottom:.25rem!important}.py-md-2{padding-top:.5rem!important;padding-bottom:.5rem!important}.py-md-3{padding-top:1rem!important;padding-bottom:1rem!important}.py-md-4{padding-top:1.5rem!important;padding-bottom:1.5rem!important}.py-md-5{padding-top:3rem!important;padding-bottom:3rem!important}.pt-md-0{padding-top:0!important}.pt-md-1{padding-top:.25rem!important}.pt-md-2{padding-top:.5rem!important}.pt-md-3{padding-top:1rem!important}.pt-md-4{padding-top:1.5rem!important}.pt-md-5{padding-top:3rem!important}.pe-md-0{padding-right:0!important}.pe-md-1{padding-right:.25rem!important}.pe-md-2{padding-right:.5rem!important}.pe-md-3{padding-right:1rem!important}.pe-md-4{padding-right:1.5rem!important}.pe-md-5{padding-right:3rem!important}.pb-md-0{padding-bottom:0!important}.pb-md-1{padding-bottom:.25rem!important}.pb-md-2{padding-bottom:.5rem!important}.pb-md-3{padding-bottom:1rem!important}.pb-md-4{padding-bottom:1.5rem!important}.pb-md-5{padding-bottom:3rem!important}.ps-md-0{padding-left:0!important}.ps-md-1{padding-left:.25rem!important}.ps-md-2{padding-left:.5rem!important}.ps-md-3{padding-left:1rem!important}.ps-md-4{padding-left:1.5rem!important}.ps-md-5{padding-left:3rem!important}.gap-md-0{gap:0!important}.gap-md-1{gap:.25rem!important}.gap-md-2{gap:.5rem!important}.gap-md-3{gap:1rem!important}.gap-md-4{gap:1.5rem!important}.gap-md-5{gap:3rem!important}.row-gap-md-0{row-gap:0!important}.row-gap-md-1{row-gap:.25rem!important}.row-gap-md-2{row-gap:.5rem!important}.row-gap-md-3{row-gap:1rem!important}.row-gap-md-4{row-gap:1.5rem!important}.row-gap-md-5{row-gap:3rem!important}.column-gap-md-0{-moz-column-gap:0!important;column-gap:0!important}.column-gap-md-1{-moz-column-gap:0.25rem!important;column-gap:.25rem!important}.column-gap-md-2{-moz-column-gap:0.5rem!important;column-gap:.5rem!important}.column-gap-md-3{-moz-column-gap:1rem!important;column-gap:1rem!important}.column-gap-md-4{-moz-column-gap:1.5rem!important;column-gap:1.5rem!important}.column-gap-md-5{-moz-column-gap:3rem!important;column-gap:3rem!important}.text-md-start{text-align:left!important}.text-md-end{text-align:right!important}.text-md-center{text-align:center!important}}@media (min-width:992px){.float-lg-start{float:left!important}.float-lg-end{float:right!important}.float-lg-none{float:none!important}.object-fit-lg-contain{-o-object-fit:contain!important;object-fit:contain!important}.object-fit-lg-cover{-o-object-fit:cover!important;object-fit:cover!important}.object-fit-lg-fill{-o-object-fit:fill!important;object-fit:fill!important}.object-fit-lg-scale{-o-object-fit:scale-down!important;object-fit:scale-down!important}.object-fit-lg-none{-o-object-fit:none!important;object-fit:none!important}.d-lg-inline{display:inline!important}.d-lg-inline-block{display:inline-block!important}.d-lg-block{display:block!important}.d-lg-grid{display:grid!important}.d-lg-inline-grid{display:inline-grid!important}.d-lg-table{display:table!important}.d-lg-table-row{display:table-row!important}.d-lg-table-cell{display:table-cell!important}.d-lg-flex{display:flex!important}.d-lg-inline-flex{display:inline-flex!important}.d-lg-none{display:none!important}.flex-lg-fill{flex:1 1 auto!important}.flex-lg-row{flex-direction:row!important}.flex-lg-column{flex-direction:column!important}.flex-lg-row-reverse{flex-direction:row-reverse!important}.flex-lg-column-reverse{flex-direction:column-reverse!important}.flex-lg-grow-0{flex-grow:0!important}.flex-lg-grow-1{flex-grow:1!important}.flex-lg-shrink-0{flex-shrink:0!important}.flex-lg-shrink-1{flex-shrink:1!important}.flex-lg-wrap{flex-wrap:wrap!important}.flex-lg-nowrap{flex-wrap:nowrap!important}.flex-lg-wrap-reverse{flex-wrap:wrap-reverse!important}.justify-content-lg-start{justify-content:flex-start!important}.justify-content-lg-end{justify-content:flex-end!important}.justify-content-lg-center{justify-content:center!important}.justify-content-lg-between{justify-content:space-between!important}.justify-content-lg-around{justify-content:space-around!important}.justify-content-lg-evenly{justify-content:space-evenly!important}.align-items-lg-start{align-items:flex-start!important}.align-items-lg-end{align-items:flex-end!important}.align-items-lg-center{align-items:center!important}.align-items-lg-baseline{align-items:baseline!important}.align-items-lg-stretch{align-items:stretch!important}.align-content-lg-start{align-content:flex-start!important}.align-content-lg-end{align-content:flex-end!important}.align-content-lg-center{align-content:center!important}.align-content-lg-between{align-content:space-between!important}.align-content-lg-around{align-content:space-around!important}.align-content-lg-stretch{align-content:stretch!important}.align-self-lg-auto{align-self:auto!important}.align-self-lg-start{align-self:flex-start!important}.align-self-lg-end{align-self:flex-end!important}.align-self-lg-center{align-self:center!important}.align-self-lg-baseline{align-self:baseline!important}.align-self-lg-stretch{align-self:stretch!important}.order-lg-first{order:-1!important}.order-lg-0{order:0!important}.order-lg-1{order:1!important}.order-lg-2{order:2!important}.order-lg-3{order:3!important}.order-lg-4{order:4!important}.order-lg-5{order:5!important}.order-lg-last{order:6!important}.m-lg-0{margin:0!important}.m-lg-1{margin:.25rem!important}.m-lg-2{margin:.5rem!important}.m-lg-3{margin:1rem!important}.m-lg-4{margin:1.5rem!important}.m-lg-5{margin:3rem!important}.m-lg-auto{margin:auto!important}.mx-lg-0{margin-right:0!important;margin-left:0!important}.mx-lg-1{margin-right:.25rem!important;margin-left:.25rem!important}.mx-lg-2{margin-right:.5rem!important;margin-left:.5rem!important}.mx-lg-3{margin-right:1rem!important;margin-left:1rem!important}.mx-lg-4{margin-right:1.5rem!important;margin-left:1.5rem!important}.mx-lg-5{margin-right:3rem!important;margin-left:3rem!important}.mx-lg-auto{margin-right:auto!important;margin-left:auto!important}.my-lg-0{margin-top:0!important;margin-bottom:0!important}.my-lg-1{margin-top:.25rem!important;margin-bottom:.25rem!important}.my-lg-2{margin-top:.5rem!important;margin-bottom:.5rem!important}.my-lg-3{margin-top:1rem!important;margin-bottom:1rem!important}.my-lg-4{margin-top:1.5rem!important;margin-bottom:1.5rem!important}.my-lg-5{margin-top:3rem!important;margin-bottom:3rem!important}.my-lg-auto{margin-top:auto!important;margin-bottom:auto!important}.mt-lg-0{margin-top:0!important}.mt-lg-1{margin-top:.25rem!important}.mt-lg-2{margin-top:.5rem!important}.mt-lg-3{margin-top:1rem!important}.mt-lg-4{margin-top:1.5rem!important}.mt-lg-5{margin-top:3rem!important}.mt-lg-auto{margin-top:auto!important}.me-lg-0{margin-right:0!important}.me-lg-1{margin-right:.25rem!important}.me-lg-2{margin-right:.5rem!important}.me-lg-3{margin-right:1rem!important}.me-lg-4{margin-right:1.5rem!important}.me-lg-5{margin-right:3rem!important}.me-lg-auto{margin-right:auto!important}.mb-lg-0{margin-bottom:0!important}.mb-lg-1{margin-bottom:.25rem!important}.mb-lg-2{margin-bottom:.5rem!important}.mb-lg-3{margin-bottom:1rem!important}.mb-lg-4{margin-bottom:1.5rem!important}.mb-lg-5{margin-bottom:3rem!important}.mb-lg-auto{margin-bottom:auto!important}.ms-lg-0{margin-left:0!important}.ms-lg-1{margin-left:.25rem!important}.ms-lg-2{margin-left:.5rem!important}.ms-lg-3{margin-left:1rem!important}.ms-lg-4{margin-left:1.5rem!important}.ms-lg-5{margin-left:3rem!important}.ms-lg-auto{margin-left:auto!important}.p-lg-0{padding:0!important}.p-lg-1{padding:.25rem!important}.p-lg-2{padding:.5rem!important}.p-lg-3{padding:1rem!important}.p-lg-4{padding:1.5rem!important}.p-lg-5{padding:3rem!important}.px-lg-0{padding-right:0!important;padding-left:0!important}.px-lg-1{padding-right:.25rem!important;padding-left:.25rem!important}.px-lg-2{padding-right:.5rem!important;padding-left:.5rem!important}.px-lg-3{padding-right:1rem!important;padding-left:1rem!important}.px-lg-4{padding-right:1.5rem!important;padding-left:1.5rem!important}.px-lg-5{padding-right:3rem!important;padding-left:3rem!important}.py-lg-0{padding-top:0!important;padding-bottom:0!important}.py-lg-1{padding-top:.25rem!important;padding-bottom:.25rem!important}.py-lg-2{padding-top:.5rem!important;padding-bottom:.5rem!important}.py-lg-3{padding-top:1rem!important;padding-bottom:1rem!important}.py-lg-4{padding-top:1.5rem!important;padding-bottom:1.5rem!important}.py-lg-5{padding-top:3rem!important;padding-bottom:3rem!important}.pt-lg-0{padding-top:0!important}.pt-lg-1{padding-top:.25rem!important}.pt-lg-2{padding-top:.5rem!important}.pt-lg-3{padding-top:1rem!important}.pt-lg-4{padding-top:1.5rem!important}.pt-lg-5{padding-top:3rem!important}.pe-lg-0{padding-right:0!important}.pe-lg-1{padding-right:.25rem!important}.pe-lg-2{padding-right:.5rem!important}.pe-lg-3{padding-right:1rem!important}.pe-lg-4{padding-right:1.5rem!important}.pe-lg-5{padding-right:3rem!important}.pb-lg-0{padding-bottom:0!important}.pb-lg-1{padding-bottom:.25rem!important}.pb-lg-2{padding-bottom:.5rem!important}.pb-lg-3{padding-bottom:1rem!important}.pb-lg-4{padding-bottom:1.5rem!important}.pb-lg-5{padding-bottom:3rem!important}.ps-lg-0{padding-left:0!important}.ps-lg-1{padding-left:.25rem!important}.ps-lg-2{padding-left:.5rem!important}.ps-lg-3{padding-left:1rem!important}.ps-lg-4{padding-left:1.5rem!important}.ps-lg-5{padding-left:3rem!important}.gap-lg-0{gap:0!important}.gap-lg-1{gap:.25rem!important}.gap-lg-2{gap:.5rem!important}.gap-lg-3{gap:1rem!important}.gap-lg-4{gap:1.5rem!important}.gap-lg-5{gap:3rem!important}.row-gap-lg-0{row-gap:0!important}.row-gap-lg-1{row-gap:.25rem!important}.row-gap-lg-2{row-gap:.5rem!important}.row-gap-lg-3{row-gap:1rem!important}.row-gap-lg-4{row-gap:1.5rem!important}.row-gap-lg-5{row-gap:3rem!important}.column-gap-lg-0{-moz-column-gap:0!important;column-gap:0!important}.column-gap-lg-1{-moz-column-gap:0.25rem!important;column-gap:.25rem!important}.column-gap-lg-2{-moz-column-gap:0.5rem!important;column-gap:.5rem!important}.column-gap-lg-3{-moz-column-gap:1rem!important;column-gap:1rem!important}.column-gap-lg-4{-moz-column-gap:1.5rem!important;column-gap:1.5rem!important}.column-gap-lg-5{-moz-column-gap:3rem!important;column-gap:3rem!important}.text-lg-start{text-align:left!important}.text-lg-end{text-align:right!important}.text-lg-center{text-align:center!important}}@media (min-width:1200px){.float-xl-start{float:left!important}.float-xl-end{float:right!important}.float-xl-none{float:none!important}.object-fit-xl-contain{-o-object-fit:contain!important;object-fit:contain!important}.object-fit-xl-cover{-o-object-fit:cover!important;object-fit:cover!important}.object-fit-xl-fill{-o-object-fit:fill!important;object-fit:fill!important}.object-fit-xl-scale{-o-object-fit:scale-down!important;object-fit:scale-down!important}.object-fit-xl-none{-o-object-fit:none!important;object-fit:none!important}.d-xl-inline{display:inline!important}.d-xl-inline-block{display:inline-block!important}.d-xl-block{display:block!important}.d-xl-grid{display:grid!important}.d-xl-inline-grid{display:inline-grid!important}.d-xl-table{display:table!important}.d-xl-table-row{display:table-row!important}.d-xl-table-cell{display:table-cell!important}.d-xl-flex{display:flex!important}.d-xl-inline-flex{display:inline-flex!important}.d-xl-none{display:none!important}.flex-xl-fill{flex:1 1 auto!important}.flex-xl-row{flex-direction:row!important}.flex-xl-column{flex-direction:column!important}.flex-xl-row-reverse{flex-direction:row-reverse!important}.flex-xl-column-reverse{flex-direction:column-reverse!important}.flex-xl-grow-0{flex-grow:0!important}.flex-xl-grow-1{flex-grow:1!important}.flex-xl-shrink-0{flex-shrink:0!important}.flex-xl-shrink-1{flex-shrink:1!important}.flex-xl-wrap{flex-wrap:wrap!important}.flex-xl-nowrap{flex-wrap:nowrap!important}.flex-xl-wrap-reverse{flex-wrap:wrap-reverse!important}.justify-content-xl-start{justify-content:flex-start!important}.justify-content-xl-end{justify-content:flex-end!important}.justify-content-xl-center{justify-content:center!important}.justify-content-xl-between{justify-content:space-between!important}.justify-content-xl-around{justify-content:space-around!important}.justify-content-xl-evenly{justify-content:space-evenly!important}.align-items-xl-start{align-items:flex-start!important}.align-items-xl-end{align-items:flex-end!important}.align-items-xl-center{align-items:center!important}.align-items-xl-baseline{align-items:baseline!important}.align-items-xl-stretch{align-items:stretch!important}.align-content-xl-start{align-content:flex-start!important}.align-content-xl-end{align-content:flex-end!important}.align-content-xl-center{align-content:center!important}.align-content-xl-between{align-content:space-between!important}.align-content-xl-around{align-content:space-around!important}.align-content-xl-stretch{align-content:stretch!important}.align-self-xl-auto{align-self:auto!important}.align-self-xl-start{align-self:flex-start!important}.align-self-xl-end{align-self:flex-end!important}.align-self-xl-center{align-self:center!important}.align-self-xl-baseline{align-self:baseline!important}.align-self-xl-stretch{align-self:stretch!important}.order-xl-first{order:-1!important}.order-xl-0{order:0!important}.order-xl-1{order:1!important}.order-xl-2{order:2!important}.order-xl-3{order:3!important}.order-xl-4{order:4!important}.order-xl-5{order:5!important}.order-xl-last{order:6!important}.m-xl-0{margin:0!important}.m-xl-1{margin:.25rem!important}.m-xl-2{margin:.5rem!important}.m-xl-3{margin:1rem!important}.m-xl-4{margin:1.5rem!important}.m-xl-5{margin:3rem!important}.m-xl-auto{margin:auto!important}.mx-xl-0{margin-right:0!important;margin-left:0!important}.mx-xl-1{margin-right:.25rem!important;margin-left:.25rem!important}.mx-xl-2{margin-right:.5rem!important;margin-left:.5rem!important}.mx-xl-3{margin-right:1rem!important;margin-left:1rem!important}.mx-xl-4{margin-right:1.5rem!important;margin-left:1.5rem!important}.mx-xl-5{margin-right:3rem!important;margin-left:3rem!important}.mx-xl-auto{margin-right:auto!important;margin-left:auto!important}.my-xl-0{margin-top:0!important;margin-bottom:0!important}.my-xl-1{margin-top:.25rem!important;margin-bottom:.25rem!important}.my-xl-2{margin-top:.5rem!important;margin-bottom:.5rem!important}.my-xl-3{margin-top:1rem!important;margin-bottom:1rem!important}.my-xl-4{margin-top:1.5rem!important;margin-bottom:1.5rem!important}.my-xl-5{margin-top:3rem!important;margin-bottom:3rem!important}.my-xl-auto{margin-top:auto!important;margin-bottom:auto!important}.mt-xl-0{margin-top:0!important}.mt-xl-1{margin-top:.25rem!important}.mt-xl-2{margin-top:.5rem!important}.mt-xl-3{margin-top:1rem!important}.mt-xl-4{margin-top:1.5rem!important}.mt-xl-5{margin-top:3rem!important}.mt-xl-auto{margin-top:auto!important}.me-xl-0{margin-right:0!important}.me-xl-1{margin-right:.25rem!important}.me-xl-2{margin-right:.5rem!important}.me-xl-3{margin-right:1rem!important}.me-xl-4{margin-right:1.5rem!important}.me-xl-5{margin-right:3rem!important}.me-xl-auto{margin-right:auto!important}.mb-xl-0{margin-bottom:0!important}.mb-xl-1{margin-bottom:.25rem!important}.mb-xl-2{margin-bottom:.5rem!important}.mb-xl-3{margin-bottom:1rem!important}.mb-xl-4{margin-bottom:1.5rem!important}.mb-xl-5{margin-bottom:3rem!important}.mb-xl-auto{margin-bottom:auto!important}.ms-xl-0{margin-left:0!important}.ms-xl-1{margin-left:.25rem!important}.ms-xl-2{margin-left:.5rem!important}.ms-xl-3{margin-left:1rem!important}.ms-xl-4{margin-left:1.5rem!important}.ms-xl-5{margin-left:3rem!important}.ms-xl-auto{margin-left:auto!important}.p-xl-0{padding:0!important}.p-xl-1{padding:.25rem!important}.p-xl-2{padding:.5rem!important}.p-xl-3{padding:1rem!important}.p-xl-4{padding:1.5rem!important}.p-xl-5{padding:3rem!important}.px-xl-0{padding-right:0!important;padding-left:0!important}.px-xl-1{padding-right:.25rem!important;padding-left:.25rem!important}.px-xl-2{padding-right:.5rem!important;padding-left:.5rem!important}.px-xl-3{padding-right:1rem!important;padding-left:1rem!important}.px-xl-4{padding-right:1.5rem!important;padding-left:1.5rem!important}.px-xl-5{padding-right:3rem!important;padding-left:3rem!important}.py-xl-0{padding-top:0!important;padding-bottom:0!important}.py-xl-1{padding-top:.25rem!important;padding-bottom:.25rem!important}.py-xl-2{padding-top:.5rem!important;padding-bottom:.5rem!important}.py-xl-3{padding-top:1rem!important;padding-bottom:1rem!important}.py-xl-4{padding-top:1.5rem!important;padding-bottom:1.5rem!important}.py-xl-5{padding-top:3rem!important;padding-bottom:3rem!important}.pt-xl-0{padding-top:0!important}.pt-xl-1{padding-top:.25rem!important}.pt-xl-2{padding-top:.5rem!important}.pt-xl-3{padding-top:1rem!important}.pt-xl-4{padding-top:1.5rem!important}.pt-xl-5{padding-top:3rem!important}.pe-xl-0{padding-right:0!important}.pe-xl-1{padding-right:.25rem!important}.pe-xl-2{padding-right:.5rem!important}.pe-xl-3{padding-right:1rem!important}.pe-xl-4{padding-right:1.5rem!important}.pe-xl-5{padding-right:3rem!important}.pb-xl-0{padding-bottom:0!important}.pb-xl-1{padding-bottom:.25rem!important}.pb-xl-2{padding-bottom:.5rem!important}.pb-xl-3{padding-bottom:1rem!important}.pb-xl-4{padding-bottom:1.5rem!important}.pb-xl-5{padding-bottom:3rem!important}.ps-xl-0{padding-left:0!important}.ps-xl-1{padding-left:.25rem!important}.ps-xl-2{padding-left:.5rem!important}.ps-xl-3{padding-left:1rem!important}.ps-xl-4{padding-left:1.5rem!important}.ps-xl-5{padding-left:3rem!important}.gap-xl-0{gap:0!important}.gap-xl-1{gap:.25rem!important}.gap-xl-2{gap:.5rem!important}.gap-xl-3{gap:1rem!important}.gap-xl-4{gap:1.5rem!important}.gap-xl-5{gap:3rem!important}.row-gap-xl-0{row-gap:0!important}.row-gap-xl-1{row-gap:.25rem!important}.row-gap-xl-2{row-gap:.5rem!important}.row-gap-xl-3{row-gap:1rem!important}.row-gap-xl-4{row-gap:1.5rem!important}.row-gap-xl-5{row-gap:3rem!important}.column-gap-xl-0{-moz-column-gap:0!important;column-gap:0!important}.column-gap-xl-1{-moz-column-gap:0.25rem!important;column-gap:.25rem!important}.column-gap-xl-2{-moz-column-gap:0.5rem!important;column-gap:.5rem!important}.column-gap-xl-3{-moz-column-gap:1rem!important;column-gap:1rem!important}.column-gap-xl-4{-moz-column-gap:1.5rem!important;column-gap:1.5rem!important}.column-gap-xl-5{-moz-column-gap:3rem!important;column-gap:3rem!important}.text-xl-start{text-align:left!important}.text-xl-end{text-align:right!important}.text-xl-center{text-align:center!important}}@media (min-width:1400px){.float-xxl-start{float:left!important}.float-xxl-end{float:right!important}.float-xxl-none{float:none!important}.object-fit-xxl-contain{-o-object-fit:contain!important;object-fit:contain!important}.object-fit-xxl-cover{-o-object-fit:cover!important;object-fit:cover!important}.object-fit-xxl-fill{-o-object-fit:fill!important;object-fit:fill!important}.object-fit-xxl-scale{-o-object-fit:scale-down!important;object-fit:scale-down!important}.object-fit-xxl-none{-o-object-fit:none!important;object-fit:none!important}.d-xxl-inline{display:inline!important}.d-xxl-inline-block{display:inline-block!important}.d-xxl-block{display:block!important}.d-xxl-grid{display:grid!important}.d-xxl-inline-grid{display:inline-grid!important}.d-xxl-table{display:table!important}.d-xxl-table-row{display:table-row!important}.d-xxl-table-cell{display:table-cell!important}.d-xxl-flex{display:flex!important}.d-xxl-inline-flex{display:inline-flex!important}.d-xxl-none{display:none!important}.flex-xxl-fill{flex:1 1 auto!important}.flex-xxl-row{flex-direction:row!important}.flex-xxl-column{flex-direction:column!important}.flex-xxl-row-reverse{flex-direction:row-reverse!important}.flex-xxl-column-reverse{flex-direction:column-reverse!important}.flex-xxl-grow-0{flex-grow:0!important}.flex-xxl-grow-1{flex-grow:1!important}.flex-xxl-shrink-0{flex-shrink:0!important}.flex-xxl-shrink-1{flex-shrink:1!important}.flex-xxl-wrap{flex-wrap:wrap!important}.flex-xxl-nowrap{flex-wrap:nowrap!important}.flex-xxl-wrap-reverse{flex-wrap:wrap-reverse!important}.justify-content-xxl-start{justify-content:flex-start!important}.justify-content-xxl-end{justify-content:flex-end!important}.justify-content-xxl-center{justify-content:center!important}.justify-content-xxl-between{justify-content:space-between!important}.justify-content-xxl-around{justify-content:space-around!important}.justify-content-xxl-evenly{justify-content:space-evenly!important}.align-items-xxl-start{align-items:flex-start!important}.align-items-xxl-end{align-items:flex-end!important}.align-items-xxl-center{align-items:center!important}.align-items-xxl-baseline{align-items:baseline!important}.align-items-xxl-stretch{align-items:stretch!important}.align-content-xxl-start{align-content:flex-start!important}.align-content-xxl-end{align-content:flex-end!important}.align-content-xxl-center{align-content:center!important}.align-content-xxl-between{align-content:space-between!important}.align-content-xxl-around{align-content:space-around!important}.align-content-xxl-stretch{align-content:stretch!important}.align-self-xxl-auto{align-self:auto!important}.align-self-xxl-start{align-self:flex-start!important}.align-self-xxl-end{align-self:flex-end!important}.align-self-xxl-center{align-self:center!important}.align-self-xxl-baseline{align-self:baseline!important}.align-self-xxl-stretch{align-self:stretch!important}.order-xxl-first{order:-1!important}.order-xxl-0{order:0!important}.order-xxl-1{order:1!important}.order-xxl-2{order:2!important}.order-xxl-3{order:3!important}.order-xxl-4{order:4!important}.order-xxl-5{order:5!important}.order-xxl-last{order:6!important}.m-xxl-0{margin:0!important}.m-xxl-1{margin:.25rem!important}.m-xxl-2{margin:.5rem!important}.m-xxl-3{margin:1rem!important}.m-xxl-4{margin:1.5rem!important}.m-xxl-5{margin:3rem!important}.m-xxl-auto{margin:auto!important}.mx-xxl-0{margin-right:0!important;margin-left:0!important}.mx-xxl-1{margin-right:.25rem!important;margin-left:.25rem!important}.mx-xxl-2{margin-right:.5rem!important;margin-left:.5rem!important}.mx-xxl-3{margin-right:1rem!important;margin-left:1rem!important}.mx-xxl-4{margin-right:1.5rem!important;margin-left:1.5rem!important}.mx-xxl-5{margin-right:3rem!important;margin-left:3rem!important}.mx-xxl-auto{margin-right:auto!important;margin-left:auto!important}.my-xxl-0{margin-top:0!important;margin-bottom:0!important}.my-xxl-1{margin-top:.25rem!important;margin-bottom:.25rem!important}.my-xxl-2{margin-top:.5rem!important;margin-bottom:.5rem!important}.my-xxl-3{margin-top:1rem!important;margin-bottom:1rem!important}.my-xxl-4{margin-top:1.5rem!important;margin-bottom:1.5rem!important}.my-xxl-5{margin-top:3rem!important;margin-bottom:3rem!important}.my-xxl-auto{margin-top:auto!important;margin-bottom:auto!important}.mt-xxl-0{margin-top:0!important}.mt-xxl-1{margin-top:.25rem!important}.mt-xxl-2{margin-top:.5rem!important}.mt-xxl-3{margin-top:1rem!important}.mt-xxl-4{margin-top:1.5rem!important}.mt-xxl-5{margin-top:3rem!important}.mt-xxl-auto{margin-top:auto!important}.me-xxl-0{margin-right:0!important}.me-xxl-1{margin-right:.25rem!important}.me-xxl-2{margin-right:.5rem!important}.me-xxl-3{margin-right:1rem!important}.me-xxl-4{margin-right:1.5rem!important}.me-xxl-5{margin-right:3rem!important}.me-xxl-auto{margin-right:auto!important}.mb-xxl-0{margin-bottom:0!important}.mb-xxl-1{margin-bottom:.25rem!important}.mb-xxl-2{margin-bottom:.5rem!important}.mb-xxl-3{margin-bottom:1rem!important}.mb-xxl-4{margin-bottom:1.5rem!important}.mb-xxl-5{margin-bottom:3rem!important}.mb-xxl-auto{margin-bottom:auto!important}.ms-xxl-0{margin-left:0!important}.ms-xxl-1{margin-left:.25rem!important}.ms-xxl-2{margin-left:.5rem!important}.ms-xxl-3{margin-left:1rem!important}.ms-xxl-4{margin-left:1.5rem!important}.ms-xxl-5{margin-left:3rem!important}.ms-xxl-auto{margin-left:auto!important}.p-xxl-0{padding:0!important}.p-xxl-1{padding:.25rem!important}.p-xxl-2{padding:.5rem!important}.p-xxl-3{padding:1rem!important}.p-xxl-4{padding:1.5rem!important}.p-xxl-5{padding:3rem!important}.px-xxl-0{padding-right:0!important;padding-left:0!important}.px-xxl-1{padding-right:.25rem!important;padding-left:.25rem!important}.px-xxl-2{padding-right:.5rem!important;padding-left:.5rem!important}.px-xxl-3{padding-right:1rem!important;padding-left:1rem!important}.px-xxl-4{padding-right:1.5rem!important;padding-left:1.5rem!important}.px-xxl-5{padding-right:3rem!important;padding-left:3rem!important}.py-xxl-0{padding-top:0!important;padding-bottom:0!important}.py-xxl-1{padding-top:.25rem!important;padding-bottom:.25rem!important}.py-xxl-2{padding-top:.5rem!important;padding-bottom:.5rem!important}.py-xxl-3{padding-top:1rem!important;padding-bottom:1rem!important}.py-xxl-4{padding-top:1.5rem!important;padding-bottom:1.5rem!important}.py-xxl-5{padding-top:3rem!important;padding-bottom:3rem!important}.pt-xxl-0{padding-top:0!important}.pt-xxl-1{padding-top:.25rem!important}.pt-xxl-2{padding-top:.5rem!important}.pt-xxl-3{padding-top:1rem!important}.pt-xxl-4{padding-top:1.5rem!important}.pt-xxl-5{padding-top:3rem!important}.pe-xxl-0{padding-right:0!important}.pe-xxl-1{padding-right:.25rem!important}.pe-xxl-2{padding-right:.5rem!important}.pe-xxl-3{padding-right:1rem!important}.pe-xxl-4{padding-right:1.5rem!important}.pe-xxl-5{padding-right:3rem!important}.pb-xxl-0{padding-bottom:0!important}.pb-xxl-1{padding-bottom:.25rem!important}.pb-xxl-2{padding-bottom:.5rem!important}.pb-xxl-3{padding-bottom:1rem!important}.pb-xxl-4{padding-bottom:1.5rem!important}.pb-xxl-5{padding-bottom:3rem!important}.ps-xxl-0{padding-left:0!important}.ps-xxl-1{padding-left:.25rem!important}.ps-xxl-2{padding-left:.5rem!important}.ps-xxl-3{padding-left:1rem!important}.ps-xxl-4{padding-left:1.5rem!important}.ps-xxl-5{padding-left:3rem!important}.gap-xxl-0{gap:0!important}.gap-xxl-1{gap:.25rem!important}.gap-xxl-2{gap:.5rem!important}.gap-xxl-3{gap:1rem!important}.gap-xxl-4{gap:1.5rem!important}.gap-xxl-5{gap:3rem!important}.row-gap-xxl-0{row-gap:0!important}.row-gap-xxl-1{row-gap:.25rem!important}.row-gap-xxl-2{row-gap:.5rem!important}.row-gap-xxl-3{row-gap:1rem!important}.row-gap-xxl-4{row-gap:1.5rem!important}.row-gap-xxl-5{row-gap:3rem!important}.column-gap-xxl-0{-moz-column-gap:0!important;column-gap:0!important}.column-gap-xxl-1{-moz-column-gap:0.25rem!important;column-gap:.25rem!important}.column-gap-xxl-2{-moz-column-gap:0.5rem!important;column-gap:.5rem!important}.column-gap-xxl-3{-moz-column-gap:1rem!important;column-gap:1rem!important}.column-gap-xxl-4{-moz-column-gap:1.5rem!important;column-gap:1.5rem!important}.column-gap-xxl-5{-moz-column-gap:3rem!important;column-gap:3rem!important}.text-xxl-start{text-align:left!important}.text-xxl-end{text-align:right!important}.text-xxl-center{text-align:center!important}}@media (min-width:1200px){.fs-1{font-size:2.5rem!important}.fs-2{font-size:2rem!important}.fs-3{font-size:1.75rem!important}.fs-4{font-size:1.5rem!important}}@media print{.d-print-inline{display:inline!important}.d-print-inline-block{display:inline-block!important}.d-print-block{display:block!important}.d-print-grid{display:grid!important}.d-print-inline-grid{display:inline-grid!important}.d-print-table{display:table!important}.d-print-table-row{display:table-row!important}.d-print-table-cell{display:table-cell!important}.d-print-flex{display:flex!important}.d-print-inline-flex{display:inline-flex!important}.d-print-none{display:none!important}} -/*# sourceMappingURL=bootstrap.min.css.map */ \ No newline at end of file diff --git a/backend/coverage-report-controllers/_css/custom.css b/backend/coverage-report-controllers/_css/custom.css deleted file mode 100644 index e69de29b..00000000 diff --git a/backend/coverage-report-controllers/_css/nv.d3.min.css b/backend/coverage-report-controllers/_css/nv.d3.min.css deleted file mode 100644 index 7a6f7fe9..00000000 --- a/backend/coverage-report-controllers/_css/nv.d3.min.css +++ /dev/null @@ -1 +0,0 @@ -.nvd3 .nv-axis{pointer-events:none;opacity:1}.nvd3 .nv-axis path{fill:none;stroke:#000;stroke-opacity:.75;shape-rendering:crispEdges}.nvd3 .nv-axis path.domain{stroke-opacity:.75}.nvd3 .nv-axis.nv-x path.domain{stroke-opacity:0}.nvd3 .nv-axis line{fill:none;stroke:#e5e5e5;shape-rendering:crispEdges}.nvd3 .nv-axis .zero line,.nvd3 .nv-axis line.zero{stroke-opacity:.75}.nvd3 .nv-axis .nv-axisMaxMin text{font-weight:700}.nvd3 .x .nv-axis .nv-axisMaxMin text,.nvd3 .x2 .nv-axis .nv-axisMaxMin text,.nvd3 .x3 .nv-axis .nv-axisMaxMin text{text-anchor:middle}.nvd3 .nv-axis.nv-disabled{opacity:0}.nvd3 .nv-bars rect{fill-opacity:.75;transition:fill-opacity 250ms linear;-moz-transition:fill-opacity 250ms linear;-webkit-transition:fill-opacity 250ms linear}.nvd3 .nv-bars rect.hover{fill-opacity:1}.nvd3 .nv-bars .hover rect{fill:#add8e6}.nvd3 .nv-bars text{fill:rgba(0,0,0,0)}.nvd3 .nv-bars .hover text{fill:rgba(0,0,0,1)}.nvd3 .nv-multibar .nv-groups rect,.nvd3 .nv-multibarHorizontal .nv-groups rect,.nvd3 .nv-discretebar .nv-groups rect{stroke-opacity:0;transition:fill-opacity 250ms linear;-moz-transition:fill-opacity 250ms linear;-webkit-transition:fill-opacity 250ms linear}.nvd3 .nv-multibar .nv-groups rect:hover,.nvd3 .nv-multibarHorizontal .nv-groups rect:hover,.nvd3 .nv-candlestickBar .nv-ticks rect:hover,.nvd3 .nv-discretebar .nv-groups rect:hover{fill-opacity:1}.nvd3 .nv-discretebar .nv-groups text,.nvd3 .nv-multibarHorizontal .nv-groups text{font-weight:700;fill:rgba(0,0,0,1);stroke:rgba(0,0,0,0)}.nvd3 .nv-boxplot circle{fill-opacity:.5}.nvd3 .nv-boxplot circle:hover{fill-opacity:1}.nvd3 .nv-boxplot rect:hover{fill-opacity:1}.nvd3 line.nv-boxplot-median{stroke:#000}.nv-boxplot-tick:hover{stroke-width:2.5px}.nvd3.nv-bullet{font:10px sans-serif}.nvd3.nv-bullet .nv-measure{fill-opacity:.8}.nvd3.nv-bullet .nv-measure:hover{fill-opacity:1}.nvd3.nv-bullet .nv-marker{stroke:#000;stroke-width:2px}.nvd3.nv-bullet .nv-markerTriangle{stroke:#000;fill:#fff;stroke-width:1.5px}.nvd3.nv-bullet .nv-tick line{stroke:#666;stroke-width:.5px}.nvd3.nv-bullet .nv-range.nv-s0{fill:#eee}.nvd3.nv-bullet .nv-range.nv-s1{fill:#ddd}.nvd3.nv-bullet .nv-range.nv-s2{fill:#ccc}.nvd3.nv-bullet .nv-title{font-size:14px;font-weight:700}.nvd3.nv-bullet .nv-subtitle{fill:#999}.nvd3.nv-bullet .nv-range{fill:#bababa;fill-opacity:.4}.nvd3.nv-bullet .nv-range:hover{fill-opacity:.7}.nvd3.nv-candlestickBar .nv-ticks .nv-tick{stroke-width:1px}.nvd3.nv-candlestickBar .nv-ticks .nv-tick.hover{stroke-width:2px}.nvd3.nv-candlestickBar .nv-ticks .nv-tick.positive rect{stroke:#2ca02c;fill:#2ca02c}.nvd3.nv-candlestickBar .nv-ticks .nv-tick.negative rect{stroke:#d62728;fill:#d62728}.with-transitions .nv-candlestickBar .nv-ticks .nv-tick{transition:stroke-width 250ms linear,stroke-opacity 250ms linear;-moz-transition:stroke-width 250ms linear,stroke-opacity 250ms linear;-webkit-transition:stroke-width 250ms linear,stroke-opacity 250ms linear}.nvd3.nv-candlestickBar .nv-ticks line{stroke:#333}.nvd3 .nv-legend .nv-disabled rect{}.nvd3 .nv-check-box .nv-box{fill-opacity:0;stroke-width:2}.nvd3 .nv-check-box .nv-check{fill-opacity:0;stroke-width:4}.nvd3 .nv-series.nv-disabled .nv-check-box .nv-check{fill-opacity:0;stroke-opacity:0}.nvd3 .nv-controlsWrap .nv-legend .nv-check-box .nv-check{opacity:0}.nvd3.nv-linePlusBar .nv-bar rect{fill-opacity:.75}.nvd3.nv-linePlusBar .nv-bar rect:hover{fill-opacity:1}.nvd3 .nv-groups path.nv-line{fill:none}.nvd3 .nv-groups path.nv-area{stroke:none}.nvd3.nv-line .nvd3.nv-scatter .nv-groups .nv-point{fill-opacity:0;stroke-opacity:0}.nvd3.nv-scatter.nv-single-point .nv-groups .nv-point{fill-opacity:.5!important;stroke-opacity:.5!important}.with-transitions .nvd3 .nv-groups .nv-point{transition:stroke-width 250ms linear,stroke-opacity 250ms linear;-moz-transition:stroke-width 250ms linear,stroke-opacity 250ms linear;-webkit-transition:stroke-width 250ms linear,stroke-opacity 250ms linear}.nvd3.nv-scatter .nv-groups .nv-point.hover,.nvd3 .nv-groups .nv-point.hover{stroke-width:7px;fill-opacity:.95!important;stroke-opacity:.95!important}.nvd3 .nv-point-paths path{stroke:#aaa;stroke-opacity:0;fill:#eee;fill-opacity:0}.nvd3 .nv-indexLine{cursor:ew-resize}svg.nvd3-svg{-webkit-touch-callout:none;-webkit-user-select:none;-khtml-user-select:none;-ms-user-select:none;-moz-user-select:none;user-select:none;display:block;width:100%;height:100%}.nvtooltip.with-3d-shadow,.with-3d-shadow .nvtooltip{-moz-box-shadow:0 5px 10px rgba(0,0,0,.2);-webkit-box-shadow:0 5px 10px rgba(0,0,0,.2);box-shadow:0 5px 10px rgba(0,0,0,.2);-webkit-border-radius:5px;-moz-border-radius:5px;border-radius:5px}.nvd3 text{font:400 12px Arial}.nvd3 .title{font:700 14px Arial}.nvd3 .nv-background{fill:#fff;fill-opacity:0}.nvd3.nv-noData{font-size:18px;font-weight:700}.nv-brush .extent{fill-opacity:.125;shape-rendering:crispEdges}.nv-brush .resize path{fill:#eee;stroke:#666}.nvd3 .nv-legend .nv-series{cursor:pointer}.nvd3 .nv-legend .nv-disabled circle{fill-opacity:0}.nvd3 .nv-brush .extent{fill-opacity:0!important}.nvd3 .nv-brushBackground rect{stroke:#000;stroke-width:.4;fill:#fff;fill-opacity:.7}.nvd3.nv-ohlcBar .nv-ticks .nv-tick{stroke-width:1px}.nvd3.nv-ohlcBar .nv-ticks .nv-tick.hover{stroke-width:2px}.nvd3.nv-ohlcBar .nv-ticks .nv-tick.positive{stroke:#2ca02c}.nvd3.nv-ohlcBar .nv-ticks .nv-tick.negative{stroke:#d62728}.nvd3 .background path{fill:none;stroke:#EEE;stroke-opacity:.4;shape-rendering:crispEdges}.nvd3 .foreground path{fill:none;stroke-opacity:.7}.nvd3 .nv-parallelCoordinates-brush .extent{fill:#fff;fill-opacity:.6;stroke:gray;shape-rendering:crispEdges}.nvd3 .nv-parallelCoordinates .hover{fill-opacity:1;stroke-width:3px}.nvd3 .missingValuesline line{fill:none;stroke:#000;stroke-width:1;stroke-opacity:1;stroke-dasharray:5,5}.nvd3.nv-pie path{stroke-opacity:0;transition:fill-opacity 250ms linear,stroke-width 250ms linear,stroke-opacity 250ms linear;-moz-transition:fill-opacity 250ms linear,stroke-width 250ms linear,stroke-opacity 250ms linear;-webkit-transition:fill-opacity 250ms linear,stroke-width 250ms linear,stroke-opacity 250ms linear}.nvd3.nv-pie .nv-pie-title{font-size:24px;fill:rgba(19,196,249,.59)}.nvd3.nv-pie .nv-slice text{stroke:#000;stroke-width:0}.nvd3.nv-pie path{stroke:#fff;stroke-width:1px;stroke-opacity:1}.nvd3.nv-pie .hover path{fill-opacity:.7}.nvd3.nv-pie .nv-label{pointer-events:none}.nvd3.nv-pie .nv-label rect{fill-opacity:0;stroke-opacity:0}.nvd3 .nv-groups .nv-point.hover{stroke-width:20px;stroke-opacity:.5}.nvd3 .nv-scatter .nv-point.hover{fill-opacity:1}.nv-noninteractive{pointer-events:none}.nv-distx,.nv-disty{pointer-events:none}.nvd3.nv-sparkline path{fill:none}.nvd3.nv-sparklineplus g.nv-hoverValue{pointer-events:none}.nvd3.nv-sparklineplus .nv-hoverValue line{stroke:#333;stroke-width:1.5px}.nvd3.nv-sparklineplus,.nvd3.nv-sparklineplus g{pointer-events:all}.nvd3 .nv-hoverArea{fill-opacity:0;stroke-opacity:0}.nvd3.nv-sparklineplus .nv-xValue,.nvd3.nv-sparklineplus .nv-yValue{stroke-width:0;font-size:.9em;font-weight:400}.nvd3.nv-sparklineplus .nv-yValue{stroke:#f66}.nvd3.nv-sparklineplus .nv-maxValue{stroke:#2ca02c;fill:#2ca02c}.nvd3.nv-sparklineplus .nv-minValue{stroke:#d62728;fill:#d62728}.nvd3.nv-sparklineplus .nv-currentValue{font-weight:700;font-size:1.1em}.nvd3.nv-stackedarea path.nv-area{fill-opacity:.7;stroke-opacity:0;transition:fill-opacity 250ms linear,stroke-opacity 250ms linear;-moz-transition:fill-opacity 250ms linear,stroke-opacity 250ms linear;-webkit-transition:fill-opacity 250ms linear,stroke-opacity 250ms linear}.nvd3.nv-stackedarea path.nv-area.hover{fill-opacity:.9}.nvd3.nv-stackedarea .nv-groups .nv-point{stroke-opacity:0;fill-opacity:0}.nvtooltip{position:absolute;background-color:rgba(255,255,255,1);color:rgba(0,0,0,1);padding:1px;border:1px solid rgba(0,0,0,.2);z-index:10000;display:block;font-family:Arial;font-size:13px;text-align:left;pointer-events:none;white-space:nowrap;-webkit-touch-callout:none;-webkit-user-select:none;-khtml-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.nvtooltip{background:rgba(255,255,255,.8);border:1px solid rgba(0,0,0,.5);border-radius:4px}.nvtooltip.with-transitions,.with-transitions .nvtooltip{transition:opacity 50ms linear;-moz-transition:opacity 50ms linear;-webkit-transition:opacity 50ms linear;transition-delay:200ms;-moz-transition-delay:200ms;-webkit-transition-delay:200ms}.nvtooltip.x-nvtooltip,.nvtooltip.y-nvtooltip{padding:8px}.nvtooltip h3{margin:0;padding:4px 14px;line-height:18px;font-weight:400;background-color:rgba(247,247,247,.75);color:rgba(0,0,0,1);text-align:center;border-bottom:1px solid #ebebeb;-webkit-border-radius:5px 5px 0 0;-moz-border-radius:5px 5px 0 0;border-radius:5px 5px 0 0}.nvtooltip p{margin:0;padding:5px 14px;text-align:center}.nvtooltip span{display:inline-block;margin:2px 0}.nvtooltip table{margin:6px;border-spacing:0}.nvtooltip table td{padding:2px 9px 2px 0;vertical-align:middle}.nvtooltip table td.key{font-weight:400}.nvtooltip table td.value{text-align:right;font-weight:700}.nvtooltip table tr.highlight td{padding:1px 9px 1px 0;border-bottom-style:solid;border-bottom-width:1px;border-top-style:solid;border-top-width:1px}.nvtooltip table td.legend-color-guide div{width:8px;height:8px;vertical-align:middle}.nvtooltip table td.legend-color-guide div{width:12px;height:12px;border:1px solid #999}.nvtooltip .footer{padding:3px;text-align:center}.nvtooltip-pending-removal{pointer-events:none;display:none}.nvd3 .nv-interactiveGuideLine{pointer-events:none}.nvd3 line.nv-guideline{stroke:#ccc} \ No newline at end of file diff --git a/backend/coverage-report-controllers/_css/octicons.css b/backend/coverage-report-controllers/_css/octicons.css deleted file mode 100644 index 31d97867..00000000 --- a/backend/coverage-report-controllers/_css/octicons.css +++ /dev/null @@ -1,5 +0,0 @@ -.octicon { - display: inline-block; - vertical-align: text-top; - fill: currentColor; -} diff --git a/backend/coverage-report-controllers/_css/style.css b/backend/coverage-report-controllers/_css/style.css deleted file mode 100644 index b007558e..00000000 --- a/backend/coverage-report-controllers/_css/style.css +++ /dev/null @@ -1,201 +0,0 @@ -:root { - --phpunit-breadcrumbs: var(--bs-gray-200); - --phpunit-success-bar: #28a745; - --phpunit-success-high: #99cb84; - --phpunit-success-medium: #c3e3b5; - --phpunit-success-low: #dff0d8; - --phpunit-warning: #fcf8e3; - --phpunit-warning-bar: #ffc107; - --phpunit-danger: #f2dede; - --phpunit-danger-bar: #dc3545; -} - -body { - font-family: sans-serif; - font-size: 1em; - font-kerning: normal; - text-rendering: optimizeLegibility; - padding-top: 10px; -} - -nav .breadcrumb { - border-radius: var(--bs-border-radius); - background-color: var(--phpunit-breadcrumbs); - padding: .75rem 1rem; -} - -.popover { - max-width: none; -} - -.popover-body { - max-height: 90vh; - overflow-y: auto; -} - -.octicon { - margin-right:.25em; - vertical-align: baseline; - width: 0.75em; -} - -.table-bordered>thead>tr>td { - border-bottom-width: 1px; -} - -.table tbody>tr>td, .table thead>tr>td { - padding-top: 3px; - padding-bottom: 3px; -} - -.table-condensed tbody>tr>td { - padding-top: 0; - padding-bottom: 0; -} - -.table .progress { - margin-bottom: inherit; -} - -.table-borderless th, .table-borderless td { - border: 0 !important; -} - -.table tbody tr.covered-by-large-tests, .table tbody tr.covered-by-large-tests td, li.covered-by-large-tests, tr.success, tr.success td, td.success, li.success, span.success { - background-color: var(--phpunit-success-low); -} - -.table tbody tr.covered-by-medium-tests, .table tbody tr.covered-by-medium-tests td, li.covered-by-medium-tests { - background-color: var(--phpunit-success-medium); -} - -.table tbody tr.covered-by-small-tests, .table tbody tr.covered-by-small-tests td, li.covered-by-small-tests { - background-color: var(--phpunit-success-high); -} - -.table tbody tr.warning, .table tbody tr.warning td, .table tbody td.warning, li.warning, span.warning { - background-color: var(--phpunit-warning); -} - -.table tbody tr.danger, .table tbody tr.danger td, .table tbody td.danger, li.danger, span.danger { - background-color: var(--phpunit-danger); -} - -.table tbody td.info { - background-color: rgb(from var(--bs-info) r g b / 0.25); -} - -td.big { - vertical-align: middle; - width: 117px; -} - -td.small { -} - -td.codeLine { - font-family: "Source Code Pro", var(--bs-font-monospace); - white-space: pre-wrap; -} - -td span.comment { - color: var(--bs-secondary-color); -} - -td span.default { - color: var(--bs-body-color); -} - -td span.html { - color: var(--bs-secondary-color); -} - -td span.keyword { - color: var(--bs-body-color); - font-weight: bold; -} - -pre span.string { - color: var(--bs-body-color); -} - -span.success, span.warning, span.danger { - margin-right: 2px; - padding-left: 10px; - padding-right: 10px; - text-align: center; -} - -#toplink { - position: fixed; - left: 5px; - bottom: 5px; - outline: 0; -} - -svg text { - font-family: var(--bs-font-sans-serif); - font-size: 11px; - color: var(--bs-gray); - fill: var(--bs-gray); -} - -.scrollbox { - height:245px; - overflow-x:scroll; - overflow-y:scroll; -} - -table + .structure-heading { - border-top: 1px solid var(--bs-gray-200); - padding-top: 0.5em; -} - -table#code td:first-of-type { - padding-left: .75em; - padding-right: .75em; -} - -table#code td:first-of-type a { - text-decoration: none; -} - -.legend { - font-weight: bold; - margin-right: 2px; - padding-left: 10px; - padding-right: 10px; - text-align: center; -} - -.covered-by-small-tests { - background-color: var(--phpunit-success-high); -} - -.covered-by-medium-tests { - background-color: var(--phpunit-success-medium); -} - -.covered-by-large-tests { - background-color: var(--phpunit-success-low); -} - -.not-covered { - background-color: var(--phpunit-danger); -} - -.not-coverable { - background-color: var(--phpunit-warning); -} - -.progress-bar.bg-success { - background-color: var(--phpunit-success-bar) !important; -} - -.progress-bar.bg-warning { - background-color: var(--phpunit-warning-bar) !important; -} - -.progress-bar.bg-danger { - background-color: var(--phpunit-danger-bar) !important; -} \ No newline at end of file diff --git a/backend/coverage-report-controllers/_icons/file-code.svg b/backend/coverage-report-controllers/_icons/file-code.svg deleted file mode 100644 index 5b4b1995..00000000 --- a/backend/coverage-report-controllers/_icons/file-code.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/backend/coverage-report-controllers/_icons/file-directory.svg b/backend/coverage-report-controllers/_icons/file-directory.svg deleted file mode 100644 index 4bf1f1ca..00000000 --- a/backend/coverage-report-controllers/_icons/file-directory.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/backend/coverage-report-controllers/_js/bootstrap.bundle.min.js b/backend/coverage-report-controllers/_js/bootstrap.bundle.min.js deleted file mode 100644 index 8739c91c..00000000 --- a/backend/coverage-report-controllers/_js/bootstrap.bundle.min.js +++ /dev/null @@ -1,7 +0,0 @@ -/*! - * Bootstrap v5.3.6 (https://getbootstrap.com/) - * Copyright 2011-2025 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors) - * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) - */ -!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):(t="undefined"!=typeof globalThis?globalThis:t||self).bootstrap=e()}(this,(function(){"use strict";const t=new Map,e={set(e,i,n){t.has(e)||t.set(e,new Map);const s=t.get(e);s.has(i)||0===s.size?s.set(i,n):console.error(`Bootstrap doesn't allow more than one instance per element. Bound instance: ${Array.from(s.keys())[0]}.`)},get:(e,i)=>t.has(e)&&t.get(e).get(i)||null,remove(e,i){if(!t.has(e))return;const n=t.get(e);n.delete(i),0===n.size&&t.delete(e)}},i="transitionend",n=t=>(t&&window.CSS&&window.CSS.escape&&(t=t.replace(/#([^\s"#']+)/g,((t,e)=>`#${CSS.escape(e)}`))),t),s=t=>{t.dispatchEvent(new Event(i))},o=t=>!(!t||"object"!=typeof t)&&(void 0!==t.jquery&&(t=t[0]),void 0!==t.nodeType),r=t=>o(t)?t.jquery?t[0]:t:"string"==typeof t&&t.length>0?document.querySelector(n(t)):null,a=t=>{if(!o(t)||0===t.getClientRects().length)return!1;const e="visible"===getComputedStyle(t).getPropertyValue("visibility"),i=t.closest("details:not([open])");if(!i)return e;if(i!==t){const e=t.closest("summary");if(e&&e.parentNode!==i)return!1;if(null===e)return!1}return e},l=t=>!t||t.nodeType!==Node.ELEMENT_NODE||!!t.classList.contains("disabled")||(void 0!==t.disabled?t.disabled:t.hasAttribute("disabled")&&"false"!==t.getAttribute("disabled")),c=t=>{if(!document.documentElement.attachShadow)return null;if("function"==typeof t.getRootNode){const e=t.getRootNode();return e instanceof ShadowRoot?e:null}return t instanceof ShadowRoot?t:t.parentNode?c(t.parentNode):null},h=()=>{},d=t=>{t.offsetHeight},u=()=>window.jQuery&&!document.body.hasAttribute("data-bs-no-jquery")?window.jQuery:null,f=[],p=()=>"rtl"===document.documentElement.dir,m=t=>{var e;e=()=>{const e=u();if(e){const i=t.NAME,n=e.fn[i];e.fn[i]=t.jQueryInterface,e.fn[i].Constructor=t,e.fn[i].noConflict=()=>(e.fn[i]=n,t.jQueryInterface)}},"loading"===document.readyState?(f.length||document.addEventListener("DOMContentLoaded",(()=>{for(const t of f)t()})),f.push(e)):e()},g=(t,e=[],i=t)=>"function"==typeof t?t.call(...e):i,_=(t,e,n=!0)=>{if(!n)return void g(t);const o=(t=>{if(!t)return 0;let{transitionDuration:e,transitionDelay:i}=window.getComputedStyle(t);const n=Number.parseFloat(e),s=Number.parseFloat(i);return n||s?(e=e.split(",")[0],i=i.split(",")[0],1e3*(Number.parseFloat(e)+Number.parseFloat(i))):0})(e)+5;let r=!1;const a=({target:n})=>{n===e&&(r=!0,e.removeEventListener(i,a),g(t))};e.addEventListener(i,a),setTimeout((()=>{r||s(e)}),o)},b=(t,e,i,n)=>{const s=t.length;let o=t.indexOf(e);return-1===o?!i&&n?t[s-1]:t[0]:(o+=i?1:-1,n&&(o=(o+s)%s),t[Math.max(0,Math.min(o,s-1))])},v=/[^.]*(?=\..*)\.|.*/,y=/\..*/,w=/::\d+$/,A={};let E=1;const T={mouseenter:"mouseover",mouseleave:"mouseout"},C=new Set(["click","dblclick","mouseup","mousedown","contextmenu","mousewheel","DOMMouseScroll","mouseover","mouseout","mousemove","selectstart","selectend","keydown","keypress","keyup","orientationchange","touchstart","touchmove","touchend","touchcancel","pointerdown","pointermove","pointerup","pointerleave","pointercancel","gesturestart","gesturechange","gestureend","focus","blur","change","reset","select","submit","focusin","focusout","load","unload","beforeunload","resize","move","DOMContentLoaded","readystatechange","error","abort","scroll"]);function O(t,e){return e&&`${e}::${E++}`||t.uidEvent||E++}function x(t){const e=O(t);return t.uidEvent=e,A[e]=A[e]||{},A[e]}function k(t,e,i=null){return Object.values(t).find((t=>t.callable===e&&t.delegationSelector===i))}function L(t,e,i){const n="string"==typeof e,s=n?i:e||i;let o=I(t);return C.has(o)||(o=t),[n,s,o]}function S(t,e,i,n,s){if("string"!=typeof e||!t)return;let[o,r,a]=L(e,i,n);if(e in T){const t=t=>function(e){if(!e.relatedTarget||e.relatedTarget!==e.delegateTarget&&!e.delegateTarget.contains(e.relatedTarget))return t.call(this,e)};r=t(r)}const l=x(t),c=l[a]||(l[a]={}),h=k(c,r,o?i:null);if(h)return void(h.oneOff=h.oneOff&&s);const d=O(r,e.replace(v,"")),u=o?function(t,e,i){return function n(s){const o=t.querySelectorAll(e);for(let{target:r}=s;r&&r!==this;r=r.parentNode)for(const a of o)if(a===r)return P(s,{delegateTarget:r}),n.oneOff&&N.off(t,s.type,e,i),i.apply(r,[s])}}(t,i,r):function(t,e){return function i(n){return P(n,{delegateTarget:t}),i.oneOff&&N.off(t,n.type,e),e.apply(t,[n])}}(t,r);u.delegationSelector=o?i:null,u.callable=r,u.oneOff=s,u.uidEvent=d,c[d]=u,t.addEventListener(a,u,o)}function D(t,e,i,n,s){const o=k(e[i],n,s);o&&(t.removeEventListener(i,o,Boolean(s)),delete e[i][o.uidEvent])}function $(t,e,i,n){const s=e[i]||{};for(const[o,r]of Object.entries(s))o.includes(n)&&D(t,e,i,r.callable,r.delegationSelector)}function I(t){return t=t.replace(y,""),T[t]||t}const N={on(t,e,i,n){S(t,e,i,n,!1)},one(t,e,i,n){S(t,e,i,n,!0)},off(t,e,i,n){if("string"!=typeof e||!t)return;const[s,o,r]=L(e,i,n),a=r!==e,l=x(t),c=l[r]||{},h=e.startsWith(".");if(void 0===o){if(h)for(const i of Object.keys(l))$(t,l,i,e.slice(1));for(const[i,n]of Object.entries(c)){const s=i.replace(w,"");a&&!e.includes(s)||D(t,l,r,n.callable,n.delegationSelector)}}else{if(!Object.keys(c).length)return;D(t,l,r,o,s?i:null)}},trigger(t,e,i){if("string"!=typeof e||!t)return null;const n=u();let s=null,o=!0,r=!0,a=!1;e!==I(e)&&n&&(s=n.Event(e,i),n(t).trigger(s),o=!s.isPropagationStopped(),r=!s.isImmediatePropagationStopped(),a=s.isDefaultPrevented());const l=P(new Event(e,{bubbles:o,cancelable:!0}),i);return a&&l.preventDefault(),r&&t.dispatchEvent(l),l.defaultPrevented&&s&&s.preventDefault(),l}};function P(t,e={}){for(const[i,n]of Object.entries(e))try{t[i]=n}catch(e){Object.defineProperty(t,i,{configurable:!0,get:()=>n})}return t}function j(t){if("true"===t)return!0;if("false"===t)return!1;if(t===Number(t).toString())return Number(t);if(""===t||"null"===t)return null;if("string"!=typeof t)return t;try{return JSON.parse(decodeURIComponent(t))}catch(e){return t}}function M(t){return t.replace(/[A-Z]/g,(t=>`-${t.toLowerCase()}`))}const F={setDataAttribute(t,e,i){t.setAttribute(`data-bs-${M(e)}`,i)},removeDataAttribute(t,e){t.removeAttribute(`data-bs-${M(e)}`)},getDataAttributes(t){if(!t)return{};const e={},i=Object.keys(t.dataset).filter((t=>t.startsWith("bs")&&!t.startsWith("bsConfig")));for(const n of i){let i=n.replace(/^bs/,"");i=i.charAt(0).toLowerCase()+i.slice(1),e[i]=j(t.dataset[n])}return e},getDataAttribute:(t,e)=>j(t.getAttribute(`data-bs-${M(e)}`))};class H{static get Default(){return{}}static get DefaultType(){return{}}static get NAME(){throw new Error('You have to implement the static method "NAME", for each component!')}_getConfig(t){return t=this._mergeConfigObj(t),t=this._configAfterMerge(t),this._typeCheckConfig(t),t}_configAfterMerge(t){return t}_mergeConfigObj(t,e){const i=o(e)?F.getDataAttribute(e,"config"):{};return{...this.constructor.Default,..."object"==typeof i?i:{},...o(e)?F.getDataAttributes(e):{},..."object"==typeof t?t:{}}}_typeCheckConfig(t,e=this.constructor.DefaultType){for(const[n,s]of Object.entries(e)){const e=t[n],r=o(e)?"element":null==(i=e)?`${i}`:Object.prototype.toString.call(i).match(/\s([a-z]+)/i)[1].toLowerCase();if(!new RegExp(s).test(r))throw new TypeError(`${this.constructor.NAME.toUpperCase()}: Option "${n}" provided type "${r}" but expected type "${s}".`)}var i}}class W extends H{constructor(t,i){super(),(t=r(t))&&(this._element=t,this._config=this._getConfig(i),e.set(this._element,this.constructor.DATA_KEY,this))}dispose(){e.remove(this._element,this.constructor.DATA_KEY),N.off(this._element,this.constructor.EVENT_KEY);for(const t of Object.getOwnPropertyNames(this))this[t]=null}_queueCallback(t,e,i=!0){_(t,e,i)}_getConfig(t){return t=this._mergeConfigObj(t,this._element),t=this._configAfterMerge(t),this._typeCheckConfig(t),t}static getInstance(t){return e.get(r(t),this.DATA_KEY)}static getOrCreateInstance(t,e={}){return this.getInstance(t)||new this(t,"object"==typeof e?e:null)}static get VERSION(){return"5.3.6"}static get DATA_KEY(){return`bs.${this.NAME}`}static get EVENT_KEY(){return`.${this.DATA_KEY}`}static eventName(t){return`${t}${this.EVENT_KEY}`}}const B=t=>{let e=t.getAttribute("data-bs-target");if(!e||"#"===e){let i=t.getAttribute("href");if(!i||!i.includes("#")&&!i.startsWith("."))return null;i.includes("#")&&!i.startsWith("#")&&(i=`#${i.split("#")[1]}`),e=i&&"#"!==i?i.trim():null}return e?e.split(",").map((t=>n(t))).join(","):null},z={find:(t,e=document.documentElement)=>[].concat(...Element.prototype.querySelectorAll.call(e,t)),findOne:(t,e=document.documentElement)=>Element.prototype.querySelector.call(e,t),children:(t,e)=>[].concat(...t.children).filter((t=>t.matches(e))),parents(t,e){const i=[];let n=t.parentNode.closest(e);for(;n;)i.push(n),n=n.parentNode.closest(e);return i},prev(t,e){let i=t.previousElementSibling;for(;i;){if(i.matches(e))return[i];i=i.previousElementSibling}return[]},next(t,e){let i=t.nextElementSibling;for(;i;){if(i.matches(e))return[i];i=i.nextElementSibling}return[]},focusableChildren(t){const e=["a","button","input","textarea","select","details","[tabindex]",'[contenteditable="true"]'].map((t=>`${t}:not([tabindex^="-"])`)).join(",");return this.find(e,t).filter((t=>!l(t)&&a(t)))},getSelectorFromElement(t){const e=B(t);return e&&z.findOne(e)?e:null},getElementFromSelector(t){const e=B(t);return e?z.findOne(e):null},getMultipleElementsFromSelector(t){const e=B(t);return e?z.find(e):[]}},R=(t,e="hide")=>{const i=`click.dismiss${t.EVENT_KEY}`,n=t.NAME;N.on(document,i,`[data-bs-dismiss="${n}"]`,(function(i){if(["A","AREA"].includes(this.tagName)&&i.preventDefault(),l(this))return;const s=z.getElementFromSelector(this)||this.closest(`.${n}`);t.getOrCreateInstance(s)[e]()}))},q=".bs.alert",V=`close${q}`,K=`closed${q}`;class Q extends W{static get NAME(){return"alert"}close(){if(N.trigger(this._element,V).defaultPrevented)return;this._element.classList.remove("show");const t=this._element.classList.contains("fade");this._queueCallback((()=>this._destroyElement()),this._element,t)}_destroyElement(){this._element.remove(),N.trigger(this._element,K),this.dispose()}static jQueryInterface(t){return this.each((function(){const e=Q.getOrCreateInstance(this);if("string"==typeof t){if(void 0===e[t]||t.startsWith("_")||"constructor"===t)throw new TypeError(`No method named "${t}"`);e[t](this)}}))}}R(Q,"close"),m(Q);const X='[data-bs-toggle="button"]';class Y extends W{static get NAME(){return"button"}toggle(){this._element.setAttribute("aria-pressed",this._element.classList.toggle("active"))}static jQueryInterface(t){return this.each((function(){const e=Y.getOrCreateInstance(this);"toggle"===t&&e[t]()}))}}N.on(document,"click.bs.button.data-api",X,(t=>{t.preventDefault();const e=t.target.closest(X);Y.getOrCreateInstance(e).toggle()})),m(Y);const U=".bs.swipe",G=`touchstart${U}`,J=`touchmove${U}`,Z=`touchend${U}`,tt=`pointerdown${U}`,et=`pointerup${U}`,it={endCallback:null,leftCallback:null,rightCallback:null},nt={endCallback:"(function|null)",leftCallback:"(function|null)",rightCallback:"(function|null)"};class st extends H{constructor(t,e){super(),this._element=t,t&&st.isSupported()&&(this._config=this._getConfig(e),this._deltaX=0,this._supportPointerEvents=Boolean(window.PointerEvent),this._initEvents())}static get Default(){return it}static get DefaultType(){return nt}static get NAME(){return"swipe"}dispose(){N.off(this._element,U)}_start(t){this._supportPointerEvents?this._eventIsPointerPenTouch(t)&&(this._deltaX=t.clientX):this._deltaX=t.touches[0].clientX}_end(t){this._eventIsPointerPenTouch(t)&&(this._deltaX=t.clientX-this._deltaX),this._handleSwipe(),g(this._config.endCallback)}_move(t){this._deltaX=t.touches&&t.touches.length>1?0:t.touches[0].clientX-this._deltaX}_handleSwipe(){const t=Math.abs(this._deltaX);if(t<=40)return;const e=t/this._deltaX;this._deltaX=0,e&&g(e>0?this._config.rightCallback:this._config.leftCallback)}_initEvents(){this._supportPointerEvents?(N.on(this._element,tt,(t=>this._start(t))),N.on(this._element,et,(t=>this._end(t))),this._element.classList.add("pointer-event")):(N.on(this._element,G,(t=>this._start(t))),N.on(this._element,J,(t=>this._move(t))),N.on(this._element,Z,(t=>this._end(t))))}_eventIsPointerPenTouch(t){return this._supportPointerEvents&&("pen"===t.pointerType||"touch"===t.pointerType)}static isSupported(){return"ontouchstart"in document.documentElement||navigator.maxTouchPoints>0}}const ot=".bs.carousel",rt=".data-api",at="ArrowLeft",lt="ArrowRight",ct="next",ht="prev",dt="left",ut="right",ft=`slide${ot}`,pt=`slid${ot}`,mt=`keydown${ot}`,gt=`mouseenter${ot}`,_t=`mouseleave${ot}`,bt=`dragstart${ot}`,vt=`load${ot}${rt}`,yt=`click${ot}${rt}`,wt="carousel",At="active",Et=".active",Tt=".carousel-item",Ct=Et+Tt,Ot={[at]:ut,[lt]:dt},xt={interval:5e3,keyboard:!0,pause:"hover",ride:!1,touch:!0,wrap:!0},kt={interval:"(number|boolean)",keyboard:"boolean",pause:"(string|boolean)",ride:"(boolean|string)",touch:"boolean",wrap:"boolean"};class Lt extends W{constructor(t,e){super(t,e),this._interval=null,this._activeElement=null,this._isSliding=!1,this.touchTimeout=null,this._swipeHelper=null,this._indicatorsElement=z.findOne(".carousel-indicators",this._element),this._addEventListeners(),this._config.ride===wt&&this.cycle()}static get Default(){return xt}static get DefaultType(){return kt}static get NAME(){return"carousel"}next(){this._slide(ct)}nextWhenVisible(){!document.hidden&&a(this._element)&&this.next()}prev(){this._slide(ht)}pause(){this._isSliding&&s(this._element),this._clearInterval()}cycle(){this._clearInterval(),this._updateInterval(),this._interval=setInterval((()=>this.nextWhenVisible()),this._config.interval)}_maybeEnableCycle(){this._config.ride&&(this._isSliding?N.one(this._element,pt,(()=>this.cycle())):this.cycle())}to(t){const e=this._getItems();if(t>e.length-1||t<0)return;if(this._isSliding)return void N.one(this._element,pt,(()=>this.to(t)));const i=this._getItemIndex(this._getActive());if(i===t)return;const n=t>i?ct:ht;this._slide(n,e[t])}dispose(){this._swipeHelper&&this._swipeHelper.dispose(),super.dispose()}_configAfterMerge(t){return t.defaultInterval=t.interval,t}_addEventListeners(){this._config.keyboard&&N.on(this._element,mt,(t=>this._keydown(t))),"hover"===this._config.pause&&(N.on(this._element,gt,(()=>this.pause())),N.on(this._element,_t,(()=>this._maybeEnableCycle()))),this._config.touch&&st.isSupported()&&this._addTouchEventListeners()}_addTouchEventListeners(){for(const t of z.find(".carousel-item img",this._element))N.on(t,bt,(t=>t.preventDefault()));const t={leftCallback:()=>this._slide(this._directionToOrder(dt)),rightCallback:()=>this._slide(this._directionToOrder(ut)),endCallback:()=>{"hover"===this._config.pause&&(this.pause(),this.touchTimeout&&clearTimeout(this.touchTimeout),this.touchTimeout=setTimeout((()=>this._maybeEnableCycle()),500+this._config.interval))}};this._swipeHelper=new st(this._element,t)}_keydown(t){if(/input|textarea/i.test(t.target.tagName))return;const e=Ot[t.key];e&&(t.preventDefault(),this._slide(this._directionToOrder(e)))}_getItemIndex(t){return this._getItems().indexOf(t)}_setActiveIndicatorElement(t){if(!this._indicatorsElement)return;const e=z.findOne(Et,this._indicatorsElement);e.classList.remove(At),e.removeAttribute("aria-current");const i=z.findOne(`[data-bs-slide-to="${t}"]`,this._indicatorsElement);i&&(i.classList.add(At),i.setAttribute("aria-current","true"))}_updateInterval(){const t=this._activeElement||this._getActive();if(!t)return;const e=Number.parseInt(t.getAttribute("data-bs-interval"),10);this._config.interval=e||this._config.defaultInterval}_slide(t,e=null){if(this._isSliding)return;const i=this._getActive(),n=t===ct,s=e||b(this._getItems(),i,n,this._config.wrap);if(s===i)return;const o=this._getItemIndex(s),r=e=>N.trigger(this._element,e,{relatedTarget:s,direction:this._orderToDirection(t),from:this._getItemIndex(i),to:o});if(r(ft).defaultPrevented)return;if(!i||!s)return;const a=Boolean(this._interval);this.pause(),this._isSliding=!0,this._setActiveIndicatorElement(o),this._activeElement=s;const l=n?"carousel-item-start":"carousel-item-end",c=n?"carousel-item-next":"carousel-item-prev";s.classList.add(c),d(s),i.classList.add(l),s.classList.add(l),this._queueCallback((()=>{s.classList.remove(l,c),s.classList.add(At),i.classList.remove(At,c,l),this._isSliding=!1,r(pt)}),i,this._isAnimated()),a&&this.cycle()}_isAnimated(){return this._element.classList.contains("slide")}_getActive(){return z.findOne(Ct,this._element)}_getItems(){return z.find(Tt,this._element)}_clearInterval(){this._interval&&(clearInterval(this._interval),this._interval=null)}_directionToOrder(t){return p()?t===dt?ht:ct:t===dt?ct:ht}_orderToDirection(t){return p()?t===ht?dt:ut:t===ht?ut:dt}static jQueryInterface(t){return this.each((function(){const e=Lt.getOrCreateInstance(this,t);if("number"!=typeof t){if("string"==typeof t){if(void 0===e[t]||t.startsWith("_")||"constructor"===t)throw new TypeError(`No method named "${t}"`);e[t]()}}else e.to(t)}))}}N.on(document,yt,"[data-bs-slide], [data-bs-slide-to]",(function(t){const e=z.getElementFromSelector(this);if(!e||!e.classList.contains(wt))return;t.preventDefault();const i=Lt.getOrCreateInstance(e),n=this.getAttribute("data-bs-slide-to");return n?(i.to(n),void i._maybeEnableCycle()):"next"===F.getDataAttribute(this,"slide")?(i.next(),void i._maybeEnableCycle()):(i.prev(),void i._maybeEnableCycle())})),N.on(window,vt,(()=>{const t=z.find('[data-bs-ride="carousel"]');for(const e of t)Lt.getOrCreateInstance(e)})),m(Lt);const St=".bs.collapse",Dt=`show${St}`,$t=`shown${St}`,It=`hide${St}`,Nt=`hidden${St}`,Pt=`click${St}.data-api`,jt="show",Mt="collapse",Ft="collapsing",Ht=`:scope .${Mt} .${Mt}`,Wt='[data-bs-toggle="collapse"]',Bt={parent:null,toggle:!0},zt={parent:"(null|element)",toggle:"boolean"};class Rt extends W{constructor(t,e){super(t,e),this._isTransitioning=!1,this._triggerArray=[];const i=z.find(Wt);for(const t of i){const e=z.getSelectorFromElement(t),i=z.find(e).filter((t=>t===this._element));null!==e&&i.length&&this._triggerArray.push(t)}this._initializeChildren(),this._config.parent||this._addAriaAndCollapsedClass(this._triggerArray,this._isShown()),this._config.toggle&&this.toggle()}static get Default(){return Bt}static get DefaultType(){return zt}static get NAME(){return"collapse"}toggle(){this._isShown()?this.hide():this.show()}show(){if(this._isTransitioning||this._isShown())return;let t=[];if(this._config.parent&&(t=this._getFirstLevelChildren(".collapse.show, .collapse.collapsing").filter((t=>t!==this._element)).map((t=>Rt.getOrCreateInstance(t,{toggle:!1})))),t.length&&t[0]._isTransitioning)return;if(N.trigger(this._element,Dt).defaultPrevented)return;for(const e of t)e.hide();const e=this._getDimension();this._element.classList.remove(Mt),this._element.classList.add(Ft),this._element.style[e]=0,this._addAriaAndCollapsedClass(this._triggerArray,!0),this._isTransitioning=!0;const i=`scroll${e[0].toUpperCase()+e.slice(1)}`;this._queueCallback((()=>{this._isTransitioning=!1,this._element.classList.remove(Ft),this._element.classList.add(Mt,jt),this._element.style[e]="",N.trigger(this._element,$t)}),this._element,!0),this._element.style[e]=`${this._element[i]}px`}hide(){if(this._isTransitioning||!this._isShown())return;if(N.trigger(this._element,It).defaultPrevented)return;const t=this._getDimension();this._element.style[t]=`${this._element.getBoundingClientRect()[t]}px`,d(this._element),this._element.classList.add(Ft),this._element.classList.remove(Mt,jt);for(const t of this._triggerArray){const e=z.getElementFromSelector(t);e&&!this._isShown(e)&&this._addAriaAndCollapsedClass([t],!1)}this._isTransitioning=!0,this._element.style[t]="",this._queueCallback((()=>{this._isTransitioning=!1,this._element.classList.remove(Ft),this._element.classList.add(Mt),N.trigger(this._element,Nt)}),this._element,!0)}_isShown(t=this._element){return t.classList.contains(jt)}_configAfterMerge(t){return t.toggle=Boolean(t.toggle),t.parent=r(t.parent),t}_getDimension(){return this._element.classList.contains("collapse-horizontal")?"width":"height"}_initializeChildren(){if(!this._config.parent)return;const t=this._getFirstLevelChildren(Wt);for(const e of t){const t=z.getElementFromSelector(e);t&&this._addAriaAndCollapsedClass([e],this._isShown(t))}}_getFirstLevelChildren(t){const e=z.find(Ht,this._config.parent);return z.find(t,this._config.parent).filter((t=>!e.includes(t)))}_addAriaAndCollapsedClass(t,e){if(t.length)for(const i of t)i.classList.toggle("collapsed",!e),i.setAttribute("aria-expanded",e)}static jQueryInterface(t){const e={};return"string"==typeof t&&/show|hide/.test(t)&&(e.toggle=!1),this.each((function(){const i=Rt.getOrCreateInstance(this,e);if("string"==typeof t){if(void 0===i[t])throw new TypeError(`No method named "${t}"`);i[t]()}}))}}N.on(document,Pt,Wt,(function(t){("A"===t.target.tagName||t.delegateTarget&&"A"===t.delegateTarget.tagName)&&t.preventDefault();for(const t of z.getMultipleElementsFromSelector(this))Rt.getOrCreateInstance(t,{toggle:!1}).toggle()})),m(Rt);var qt="top",Vt="bottom",Kt="right",Qt="left",Xt="auto",Yt=[qt,Vt,Kt,Qt],Ut="start",Gt="end",Jt="clippingParents",Zt="viewport",te="popper",ee="reference",ie=Yt.reduce((function(t,e){return t.concat([e+"-"+Ut,e+"-"+Gt])}),[]),ne=[].concat(Yt,[Xt]).reduce((function(t,e){return t.concat([e,e+"-"+Ut,e+"-"+Gt])}),[]),se="beforeRead",oe="read",re="afterRead",ae="beforeMain",le="main",ce="afterMain",he="beforeWrite",de="write",ue="afterWrite",fe=[se,oe,re,ae,le,ce,he,de,ue];function pe(t){return t?(t.nodeName||"").toLowerCase():null}function me(t){if(null==t)return window;if("[object Window]"!==t.toString()){var e=t.ownerDocument;return e&&e.defaultView||window}return t}function ge(t){return t instanceof me(t).Element||t instanceof Element}function _e(t){return t instanceof me(t).HTMLElement||t instanceof HTMLElement}function be(t){return"undefined"!=typeof ShadowRoot&&(t instanceof me(t).ShadowRoot||t instanceof ShadowRoot)}const ve={name:"applyStyles",enabled:!0,phase:"write",fn:function(t){var e=t.state;Object.keys(e.elements).forEach((function(t){var i=e.styles[t]||{},n=e.attributes[t]||{},s=e.elements[t];_e(s)&&pe(s)&&(Object.assign(s.style,i),Object.keys(n).forEach((function(t){var e=n[t];!1===e?s.removeAttribute(t):s.setAttribute(t,!0===e?"":e)})))}))},effect:function(t){var e=t.state,i={popper:{position:e.options.strategy,left:"0",top:"0",margin:"0"},arrow:{position:"absolute"},reference:{}};return Object.assign(e.elements.popper.style,i.popper),e.styles=i,e.elements.arrow&&Object.assign(e.elements.arrow.style,i.arrow),function(){Object.keys(e.elements).forEach((function(t){var n=e.elements[t],s=e.attributes[t]||{},o=Object.keys(e.styles.hasOwnProperty(t)?e.styles[t]:i[t]).reduce((function(t,e){return t[e]="",t}),{});_e(n)&&pe(n)&&(Object.assign(n.style,o),Object.keys(s).forEach((function(t){n.removeAttribute(t)})))}))}},requires:["computeStyles"]};function ye(t){return t.split("-")[0]}var we=Math.max,Ae=Math.min,Ee=Math.round;function Te(){var t=navigator.userAgentData;return null!=t&&t.brands&&Array.isArray(t.brands)?t.brands.map((function(t){return t.brand+"/"+t.version})).join(" "):navigator.userAgent}function Ce(){return!/^((?!chrome|android).)*safari/i.test(Te())}function Oe(t,e,i){void 0===e&&(e=!1),void 0===i&&(i=!1);var n=t.getBoundingClientRect(),s=1,o=1;e&&_e(t)&&(s=t.offsetWidth>0&&Ee(n.width)/t.offsetWidth||1,o=t.offsetHeight>0&&Ee(n.height)/t.offsetHeight||1);var r=(ge(t)?me(t):window).visualViewport,a=!Ce()&&i,l=(n.left+(a&&r?r.offsetLeft:0))/s,c=(n.top+(a&&r?r.offsetTop:0))/o,h=n.width/s,d=n.height/o;return{width:h,height:d,top:c,right:l+h,bottom:c+d,left:l,x:l,y:c}}function xe(t){var e=Oe(t),i=t.offsetWidth,n=t.offsetHeight;return Math.abs(e.width-i)<=1&&(i=e.width),Math.abs(e.height-n)<=1&&(n=e.height),{x:t.offsetLeft,y:t.offsetTop,width:i,height:n}}function ke(t,e){var i=e.getRootNode&&e.getRootNode();if(t.contains(e))return!0;if(i&&be(i)){var n=e;do{if(n&&t.isSameNode(n))return!0;n=n.parentNode||n.host}while(n)}return!1}function Le(t){return me(t).getComputedStyle(t)}function Se(t){return["table","td","th"].indexOf(pe(t))>=0}function De(t){return((ge(t)?t.ownerDocument:t.document)||window.document).documentElement}function $e(t){return"html"===pe(t)?t:t.assignedSlot||t.parentNode||(be(t)?t.host:null)||De(t)}function Ie(t){return _e(t)&&"fixed"!==Le(t).position?t.offsetParent:null}function Ne(t){for(var e=me(t),i=Ie(t);i&&Se(i)&&"static"===Le(i).position;)i=Ie(i);return i&&("html"===pe(i)||"body"===pe(i)&&"static"===Le(i).position)?e:i||function(t){var e=/firefox/i.test(Te());if(/Trident/i.test(Te())&&_e(t)&&"fixed"===Le(t).position)return null;var i=$e(t);for(be(i)&&(i=i.host);_e(i)&&["html","body"].indexOf(pe(i))<0;){var n=Le(i);if("none"!==n.transform||"none"!==n.perspective||"paint"===n.contain||-1!==["transform","perspective"].indexOf(n.willChange)||e&&"filter"===n.willChange||e&&n.filter&&"none"!==n.filter)return i;i=i.parentNode}return null}(t)||e}function Pe(t){return["top","bottom"].indexOf(t)>=0?"x":"y"}function je(t,e,i){return we(t,Ae(e,i))}function Me(t){return Object.assign({},{top:0,right:0,bottom:0,left:0},t)}function Fe(t,e){return e.reduce((function(e,i){return e[i]=t,e}),{})}const He={name:"arrow",enabled:!0,phase:"main",fn:function(t){var e,i=t.state,n=t.name,s=t.options,o=i.elements.arrow,r=i.modifiersData.popperOffsets,a=ye(i.placement),l=Pe(a),c=[Qt,Kt].indexOf(a)>=0?"height":"width";if(o&&r){var h=function(t,e){return Me("number"!=typeof(t="function"==typeof t?t(Object.assign({},e.rects,{placement:e.placement})):t)?t:Fe(t,Yt))}(s.padding,i),d=xe(o),u="y"===l?qt:Qt,f="y"===l?Vt:Kt,p=i.rects.reference[c]+i.rects.reference[l]-r[l]-i.rects.popper[c],m=r[l]-i.rects.reference[l],g=Ne(o),_=g?"y"===l?g.clientHeight||0:g.clientWidth||0:0,b=p/2-m/2,v=h[u],y=_-d[c]-h[f],w=_/2-d[c]/2+b,A=je(v,w,y),E=l;i.modifiersData[n]=((e={})[E]=A,e.centerOffset=A-w,e)}},effect:function(t){var e=t.state,i=t.options.element,n=void 0===i?"[data-popper-arrow]":i;null!=n&&("string"!=typeof n||(n=e.elements.popper.querySelector(n)))&&ke(e.elements.popper,n)&&(e.elements.arrow=n)},requires:["popperOffsets"],requiresIfExists:["preventOverflow"]};function We(t){return t.split("-")[1]}var Be={top:"auto",right:"auto",bottom:"auto",left:"auto"};function ze(t){var e,i=t.popper,n=t.popperRect,s=t.placement,o=t.variation,r=t.offsets,a=t.position,l=t.gpuAcceleration,c=t.adaptive,h=t.roundOffsets,d=t.isFixed,u=r.x,f=void 0===u?0:u,p=r.y,m=void 0===p?0:p,g="function"==typeof h?h({x:f,y:m}):{x:f,y:m};f=g.x,m=g.y;var _=r.hasOwnProperty("x"),b=r.hasOwnProperty("y"),v=Qt,y=qt,w=window;if(c){var A=Ne(i),E="clientHeight",T="clientWidth";A===me(i)&&"static"!==Le(A=De(i)).position&&"absolute"===a&&(E="scrollHeight",T="scrollWidth"),(s===qt||(s===Qt||s===Kt)&&o===Gt)&&(y=Vt,m-=(d&&A===w&&w.visualViewport?w.visualViewport.height:A[E])-n.height,m*=l?1:-1),s!==Qt&&(s!==qt&&s!==Vt||o!==Gt)||(v=Kt,f-=(d&&A===w&&w.visualViewport?w.visualViewport.width:A[T])-n.width,f*=l?1:-1)}var C,O=Object.assign({position:a},c&&Be),x=!0===h?function(t,e){var i=t.x,n=t.y,s=e.devicePixelRatio||1;return{x:Ee(i*s)/s||0,y:Ee(n*s)/s||0}}({x:f,y:m},me(i)):{x:f,y:m};return f=x.x,m=x.y,l?Object.assign({},O,((C={})[y]=b?"0":"",C[v]=_?"0":"",C.transform=(w.devicePixelRatio||1)<=1?"translate("+f+"px, "+m+"px)":"translate3d("+f+"px, "+m+"px, 0)",C)):Object.assign({},O,((e={})[y]=b?m+"px":"",e[v]=_?f+"px":"",e.transform="",e))}const Re={name:"computeStyles",enabled:!0,phase:"beforeWrite",fn:function(t){var e=t.state,i=t.options,n=i.gpuAcceleration,s=void 0===n||n,o=i.adaptive,r=void 0===o||o,a=i.roundOffsets,l=void 0===a||a,c={placement:ye(e.placement),variation:We(e.placement),popper:e.elements.popper,popperRect:e.rects.popper,gpuAcceleration:s,isFixed:"fixed"===e.options.strategy};null!=e.modifiersData.popperOffsets&&(e.styles.popper=Object.assign({},e.styles.popper,ze(Object.assign({},c,{offsets:e.modifiersData.popperOffsets,position:e.options.strategy,adaptive:r,roundOffsets:l})))),null!=e.modifiersData.arrow&&(e.styles.arrow=Object.assign({},e.styles.arrow,ze(Object.assign({},c,{offsets:e.modifiersData.arrow,position:"absolute",adaptive:!1,roundOffsets:l})))),e.attributes.popper=Object.assign({},e.attributes.popper,{"data-popper-placement":e.placement})},data:{}};var qe={passive:!0};const Ve={name:"eventListeners",enabled:!0,phase:"write",fn:function(){},effect:function(t){var e=t.state,i=t.instance,n=t.options,s=n.scroll,o=void 0===s||s,r=n.resize,a=void 0===r||r,l=me(e.elements.popper),c=[].concat(e.scrollParents.reference,e.scrollParents.popper);return o&&c.forEach((function(t){t.addEventListener("scroll",i.update,qe)})),a&&l.addEventListener("resize",i.update,qe),function(){o&&c.forEach((function(t){t.removeEventListener("scroll",i.update,qe)})),a&&l.removeEventListener("resize",i.update,qe)}},data:{}};var Ke={left:"right",right:"left",bottom:"top",top:"bottom"};function Qe(t){return t.replace(/left|right|bottom|top/g,(function(t){return Ke[t]}))}var Xe={start:"end",end:"start"};function Ye(t){return t.replace(/start|end/g,(function(t){return Xe[t]}))}function Ue(t){var e=me(t);return{scrollLeft:e.pageXOffset,scrollTop:e.pageYOffset}}function Ge(t){return Oe(De(t)).left+Ue(t).scrollLeft}function Je(t){var e=Le(t),i=e.overflow,n=e.overflowX,s=e.overflowY;return/auto|scroll|overlay|hidden/.test(i+s+n)}function Ze(t){return["html","body","#document"].indexOf(pe(t))>=0?t.ownerDocument.body:_e(t)&&Je(t)?t:Ze($e(t))}function ti(t,e){var i;void 0===e&&(e=[]);var n=Ze(t),s=n===(null==(i=t.ownerDocument)?void 0:i.body),o=me(n),r=s?[o].concat(o.visualViewport||[],Je(n)?n:[]):n,a=e.concat(r);return s?a:a.concat(ti($e(r)))}function ei(t){return Object.assign({},t,{left:t.x,top:t.y,right:t.x+t.width,bottom:t.y+t.height})}function ii(t,e,i){return e===Zt?ei(function(t,e){var i=me(t),n=De(t),s=i.visualViewport,o=n.clientWidth,r=n.clientHeight,a=0,l=0;if(s){o=s.width,r=s.height;var c=Ce();(c||!c&&"fixed"===e)&&(a=s.offsetLeft,l=s.offsetTop)}return{width:o,height:r,x:a+Ge(t),y:l}}(t,i)):ge(e)?function(t,e){var i=Oe(t,!1,"fixed"===e);return i.top=i.top+t.clientTop,i.left=i.left+t.clientLeft,i.bottom=i.top+t.clientHeight,i.right=i.left+t.clientWidth,i.width=t.clientWidth,i.height=t.clientHeight,i.x=i.left,i.y=i.top,i}(e,i):ei(function(t){var e,i=De(t),n=Ue(t),s=null==(e=t.ownerDocument)?void 0:e.body,o=we(i.scrollWidth,i.clientWidth,s?s.scrollWidth:0,s?s.clientWidth:0),r=we(i.scrollHeight,i.clientHeight,s?s.scrollHeight:0,s?s.clientHeight:0),a=-n.scrollLeft+Ge(t),l=-n.scrollTop;return"rtl"===Le(s||i).direction&&(a+=we(i.clientWidth,s?s.clientWidth:0)-o),{width:o,height:r,x:a,y:l}}(De(t)))}function ni(t){var e,i=t.reference,n=t.element,s=t.placement,o=s?ye(s):null,r=s?We(s):null,a=i.x+i.width/2-n.width/2,l=i.y+i.height/2-n.height/2;switch(o){case qt:e={x:a,y:i.y-n.height};break;case Vt:e={x:a,y:i.y+i.height};break;case Kt:e={x:i.x+i.width,y:l};break;case Qt:e={x:i.x-n.width,y:l};break;default:e={x:i.x,y:i.y}}var c=o?Pe(o):null;if(null!=c){var h="y"===c?"height":"width";switch(r){case Ut:e[c]=e[c]-(i[h]/2-n[h]/2);break;case Gt:e[c]=e[c]+(i[h]/2-n[h]/2)}}return e}function si(t,e){void 0===e&&(e={});var i=e,n=i.placement,s=void 0===n?t.placement:n,o=i.strategy,r=void 0===o?t.strategy:o,a=i.boundary,l=void 0===a?Jt:a,c=i.rootBoundary,h=void 0===c?Zt:c,d=i.elementContext,u=void 0===d?te:d,f=i.altBoundary,p=void 0!==f&&f,m=i.padding,g=void 0===m?0:m,_=Me("number"!=typeof g?g:Fe(g,Yt)),b=u===te?ee:te,v=t.rects.popper,y=t.elements[p?b:u],w=function(t,e,i,n){var s="clippingParents"===e?function(t){var e=ti($e(t)),i=["absolute","fixed"].indexOf(Le(t).position)>=0&&_e(t)?Ne(t):t;return ge(i)?e.filter((function(t){return ge(t)&&ke(t,i)&&"body"!==pe(t)})):[]}(t):[].concat(e),o=[].concat(s,[i]),r=o[0],a=o.reduce((function(e,i){var s=ii(t,i,n);return e.top=we(s.top,e.top),e.right=Ae(s.right,e.right),e.bottom=Ae(s.bottom,e.bottom),e.left=we(s.left,e.left),e}),ii(t,r,n));return a.width=a.right-a.left,a.height=a.bottom-a.top,a.x=a.left,a.y=a.top,a}(ge(y)?y:y.contextElement||De(t.elements.popper),l,h,r),A=Oe(t.elements.reference),E=ni({reference:A,element:v,placement:s}),T=ei(Object.assign({},v,E)),C=u===te?T:A,O={top:w.top-C.top+_.top,bottom:C.bottom-w.bottom+_.bottom,left:w.left-C.left+_.left,right:C.right-w.right+_.right},x=t.modifiersData.offset;if(u===te&&x){var k=x[s];Object.keys(O).forEach((function(t){var e=[Kt,Vt].indexOf(t)>=0?1:-1,i=[qt,Vt].indexOf(t)>=0?"y":"x";O[t]+=k[i]*e}))}return O}function oi(t,e){void 0===e&&(e={});var i=e,n=i.placement,s=i.boundary,o=i.rootBoundary,r=i.padding,a=i.flipVariations,l=i.allowedAutoPlacements,c=void 0===l?ne:l,h=We(n),d=h?a?ie:ie.filter((function(t){return We(t)===h})):Yt,u=d.filter((function(t){return c.indexOf(t)>=0}));0===u.length&&(u=d);var f=u.reduce((function(e,i){return e[i]=si(t,{placement:i,boundary:s,rootBoundary:o,padding:r})[ye(i)],e}),{});return Object.keys(f).sort((function(t,e){return f[t]-f[e]}))}const ri={name:"flip",enabled:!0,phase:"main",fn:function(t){var e=t.state,i=t.options,n=t.name;if(!e.modifiersData[n]._skip){for(var s=i.mainAxis,o=void 0===s||s,r=i.altAxis,a=void 0===r||r,l=i.fallbackPlacements,c=i.padding,h=i.boundary,d=i.rootBoundary,u=i.altBoundary,f=i.flipVariations,p=void 0===f||f,m=i.allowedAutoPlacements,g=e.options.placement,_=ye(g),b=l||(_!==g&&p?function(t){if(ye(t)===Xt)return[];var e=Qe(t);return[Ye(t),e,Ye(e)]}(g):[Qe(g)]),v=[g].concat(b).reduce((function(t,i){return t.concat(ye(i)===Xt?oi(e,{placement:i,boundary:h,rootBoundary:d,padding:c,flipVariations:p,allowedAutoPlacements:m}):i)}),[]),y=e.rects.reference,w=e.rects.popper,A=new Map,E=!0,T=v[0],C=0;C=0,S=L?"width":"height",D=si(e,{placement:O,boundary:h,rootBoundary:d,altBoundary:u,padding:c}),$=L?k?Kt:Qt:k?Vt:qt;y[S]>w[S]&&($=Qe($));var I=Qe($),N=[];if(o&&N.push(D[x]<=0),a&&N.push(D[$]<=0,D[I]<=0),N.every((function(t){return t}))){T=O,E=!1;break}A.set(O,N)}if(E)for(var P=function(t){var e=v.find((function(e){var i=A.get(e);if(i)return i.slice(0,t).every((function(t){return t}))}));if(e)return T=e,"break"},j=p?3:1;j>0&&"break"!==P(j);j--);e.placement!==T&&(e.modifiersData[n]._skip=!0,e.placement=T,e.reset=!0)}},requiresIfExists:["offset"],data:{_skip:!1}};function ai(t,e,i){return void 0===i&&(i={x:0,y:0}),{top:t.top-e.height-i.y,right:t.right-e.width+i.x,bottom:t.bottom-e.height+i.y,left:t.left-e.width-i.x}}function li(t){return[qt,Kt,Vt,Qt].some((function(e){return t[e]>=0}))}const ci={name:"hide",enabled:!0,phase:"main",requiresIfExists:["preventOverflow"],fn:function(t){var e=t.state,i=t.name,n=e.rects.reference,s=e.rects.popper,o=e.modifiersData.preventOverflow,r=si(e,{elementContext:"reference"}),a=si(e,{altBoundary:!0}),l=ai(r,n),c=ai(a,s,o),h=li(l),d=li(c);e.modifiersData[i]={referenceClippingOffsets:l,popperEscapeOffsets:c,isReferenceHidden:h,hasPopperEscaped:d},e.attributes.popper=Object.assign({},e.attributes.popper,{"data-popper-reference-hidden":h,"data-popper-escaped":d})}},hi={name:"offset",enabled:!0,phase:"main",requires:["popperOffsets"],fn:function(t){var e=t.state,i=t.options,n=t.name,s=i.offset,o=void 0===s?[0,0]:s,r=ne.reduce((function(t,i){return t[i]=function(t,e,i){var n=ye(t),s=[Qt,qt].indexOf(n)>=0?-1:1,o="function"==typeof i?i(Object.assign({},e,{placement:t})):i,r=o[0],a=o[1];return r=r||0,a=(a||0)*s,[Qt,Kt].indexOf(n)>=0?{x:a,y:r}:{x:r,y:a}}(i,e.rects,o),t}),{}),a=r[e.placement],l=a.x,c=a.y;null!=e.modifiersData.popperOffsets&&(e.modifiersData.popperOffsets.x+=l,e.modifiersData.popperOffsets.y+=c),e.modifiersData[n]=r}},di={name:"popperOffsets",enabled:!0,phase:"read",fn:function(t){var e=t.state,i=t.name;e.modifiersData[i]=ni({reference:e.rects.reference,element:e.rects.popper,placement:e.placement})},data:{}},ui={name:"preventOverflow",enabled:!0,phase:"main",fn:function(t){var e=t.state,i=t.options,n=t.name,s=i.mainAxis,o=void 0===s||s,r=i.altAxis,a=void 0!==r&&r,l=i.boundary,c=i.rootBoundary,h=i.altBoundary,d=i.padding,u=i.tether,f=void 0===u||u,p=i.tetherOffset,m=void 0===p?0:p,g=si(e,{boundary:l,rootBoundary:c,padding:d,altBoundary:h}),_=ye(e.placement),b=We(e.placement),v=!b,y=Pe(_),w="x"===y?"y":"x",A=e.modifiersData.popperOffsets,E=e.rects.reference,T=e.rects.popper,C="function"==typeof m?m(Object.assign({},e.rects,{placement:e.placement})):m,O="number"==typeof C?{mainAxis:C,altAxis:C}:Object.assign({mainAxis:0,altAxis:0},C),x=e.modifiersData.offset?e.modifiersData.offset[e.placement]:null,k={x:0,y:0};if(A){if(o){var L,S="y"===y?qt:Qt,D="y"===y?Vt:Kt,$="y"===y?"height":"width",I=A[y],N=I+g[S],P=I-g[D],j=f?-T[$]/2:0,M=b===Ut?E[$]:T[$],F=b===Ut?-T[$]:-E[$],H=e.elements.arrow,W=f&&H?xe(H):{width:0,height:0},B=e.modifiersData["arrow#persistent"]?e.modifiersData["arrow#persistent"].padding:{top:0,right:0,bottom:0,left:0},z=B[S],R=B[D],q=je(0,E[$],W[$]),V=v?E[$]/2-j-q-z-O.mainAxis:M-q-z-O.mainAxis,K=v?-E[$]/2+j+q+R+O.mainAxis:F+q+R+O.mainAxis,Q=e.elements.arrow&&Ne(e.elements.arrow),X=Q?"y"===y?Q.clientTop||0:Q.clientLeft||0:0,Y=null!=(L=null==x?void 0:x[y])?L:0,U=I+K-Y,G=je(f?Ae(N,I+V-Y-X):N,I,f?we(P,U):P);A[y]=G,k[y]=G-I}if(a){var J,Z="x"===y?qt:Qt,tt="x"===y?Vt:Kt,et=A[w],it="y"===w?"height":"width",nt=et+g[Z],st=et-g[tt],ot=-1!==[qt,Qt].indexOf(_),rt=null!=(J=null==x?void 0:x[w])?J:0,at=ot?nt:et-E[it]-T[it]-rt+O.altAxis,lt=ot?et+E[it]+T[it]-rt-O.altAxis:st,ct=f&&ot?function(t,e,i){var n=je(t,e,i);return n>i?i:n}(at,et,lt):je(f?at:nt,et,f?lt:st);A[w]=ct,k[w]=ct-et}e.modifiersData[n]=k}},requiresIfExists:["offset"]};function fi(t,e,i){void 0===i&&(i=!1);var n,s,o=_e(e),r=_e(e)&&function(t){var e=t.getBoundingClientRect(),i=Ee(e.width)/t.offsetWidth||1,n=Ee(e.height)/t.offsetHeight||1;return 1!==i||1!==n}(e),a=De(e),l=Oe(t,r,i),c={scrollLeft:0,scrollTop:0},h={x:0,y:0};return(o||!o&&!i)&&(("body"!==pe(e)||Je(a))&&(c=(n=e)!==me(n)&&_e(n)?{scrollLeft:(s=n).scrollLeft,scrollTop:s.scrollTop}:Ue(n)),_e(e)?((h=Oe(e,!0)).x+=e.clientLeft,h.y+=e.clientTop):a&&(h.x=Ge(a))),{x:l.left+c.scrollLeft-h.x,y:l.top+c.scrollTop-h.y,width:l.width,height:l.height}}function pi(t){var e=new Map,i=new Set,n=[];function s(t){i.add(t.name),[].concat(t.requires||[],t.requiresIfExists||[]).forEach((function(t){if(!i.has(t)){var n=e.get(t);n&&s(n)}})),n.push(t)}return t.forEach((function(t){e.set(t.name,t)})),t.forEach((function(t){i.has(t.name)||s(t)})),n}var mi={placement:"bottom",modifiers:[],strategy:"absolute"};function gi(){for(var t=arguments.length,e=new Array(t),i=0;iNumber.parseInt(t,10))):"function"==typeof t?e=>t(e,this._element):t}_getPopperConfig(){const t={placement:this._getPlacement(),modifiers:[{name:"preventOverflow",options:{boundary:this._config.boundary}},{name:"offset",options:{offset:this._getOffset()}}]};return(this._inNavbar||"static"===this._config.display)&&(F.setDataAttribute(this._menu,"popper","static"),t.modifiers=[{name:"applyStyles",enabled:!1}]),{...t,...g(this._config.popperConfig,[void 0,t])}}_selectMenuItem({key:t,target:e}){const i=z.find(".dropdown-menu .dropdown-item:not(.disabled):not(:disabled)",this._menu).filter((t=>a(t)));i.length&&b(i,e,t===Oi,!i.includes(e)).focus()}static jQueryInterface(t){return this.each((function(){const e=Ki.getOrCreateInstance(this,t);if("string"==typeof t){if(void 0===e[t])throw new TypeError(`No method named "${t}"`);e[t]()}}))}static clearMenus(t){if(2===t.button||"keyup"===t.type&&"Tab"!==t.key)return;const e=z.find(ji);for(const i of e){const e=Ki.getInstance(i);if(!e||!1===e._config.autoClose)continue;const n=t.composedPath(),s=n.includes(e._menu);if(n.includes(e._element)||"inside"===e._config.autoClose&&!s||"outside"===e._config.autoClose&&s)continue;if(e._menu.contains(t.target)&&("keyup"===t.type&&"Tab"===t.key||/input|select|option|textarea|form/i.test(t.target.tagName)))continue;const o={relatedTarget:e._element};"click"===t.type&&(o.clickEvent=t),e._completeHide(o)}}static dataApiKeydownHandler(t){const e=/input|textarea/i.test(t.target.tagName),i="Escape"===t.key,n=[Ci,Oi].includes(t.key);if(!n&&!i)return;if(e&&!i)return;t.preventDefault();const s=this.matches(Pi)?this:z.prev(this,Pi)[0]||z.next(this,Pi)[0]||z.findOne(Pi,t.delegateTarget.parentNode),o=Ki.getOrCreateInstance(s);if(n)return t.stopPropagation(),o.show(),void o._selectMenuItem(t);o._isShown()&&(t.stopPropagation(),o.hide(),s.focus())}}N.on(document,$i,Pi,Ki.dataApiKeydownHandler),N.on(document,$i,Mi,Ki.dataApiKeydownHandler),N.on(document,Di,Ki.clearMenus),N.on(document,Ii,Ki.clearMenus),N.on(document,Di,Pi,(function(t){t.preventDefault(),Ki.getOrCreateInstance(this).toggle()})),m(Ki);const Qi="backdrop",Xi="show",Yi=`mousedown.bs.${Qi}`,Ui={className:"modal-backdrop",clickCallback:null,isAnimated:!1,isVisible:!0,rootElement:"body"},Gi={className:"string",clickCallback:"(function|null)",isAnimated:"boolean",isVisible:"boolean",rootElement:"(element|string)"};class Ji extends H{constructor(t){super(),this._config=this._getConfig(t),this._isAppended=!1,this._element=null}static get Default(){return Ui}static get DefaultType(){return Gi}static get NAME(){return Qi}show(t){if(!this._config.isVisible)return void g(t);this._append();const e=this._getElement();this._config.isAnimated&&d(e),e.classList.add(Xi),this._emulateAnimation((()=>{g(t)}))}hide(t){this._config.isVisible?(this._getElement().classList.remove(Xi),this._emulateAnimation((()=>{this.dispose(),g(t)}))):g(t)}dispose(){this._isAppended&&(N.off(this._element,Yi),this._element.remove(),this._isAppended=!1)}_getElement(){if(!this._element){const t=document.createElement("div");t.className=this._config.className,this._config.isAnimated&&t.classList.add("fade"),this._element=t}return this._element}_configAfterMerge(t){return t.rootElement=r(t.rootElement),t}_append(){if(this._isAppended)return;const t=this._getElement();this._config.rootElement.append(t),N.on(t,Yi,(()=>{g(this._config.clickCallback)})),this._isAppended=!0}_emulateAnimation(t){_(t,this._getElement(),this._config.isAnimated)}}const Zi=".bs.focustrap",tn=`focusin${Zi}`,en=`keydown.tab${Zi}`,nn="backward",sn={autofocus:!0,trapElement:null},on={autofocus:"boolean",trapElement:"element"};class rn extends H{constructor(t){super(),this._config=this._getConfig(t),this._isActive=!1,this._lastTabNavDirection=null}static get Default(){return sn}static get DefaultType(){return on}static get NAME(){return"focustrap"}activate(){this._isActive||(this._config.autofocus&&this._config.trapElement.focus(),N.off(document,Zi),N.on(document,tn,(t=>this._handleFocusin(t))),N.on(document,en,(t=>this._handleKeydown(t))),this._isActive=!0)}deactivate(){this._isActive&&(this._isActive=!1,N.off(document,Zi))}_handleFocusin(t){const{trapElement:e}=this._config;if(t.target===document||t.target===e||e.contains(t.target))return;const i=z.focusableChildren(e);0===i.length?e.focus():this._lastTabNavDirection===nn?i[i.length-1].focus():i[0].focus()}_handleKeydown(t){"Tab"===t.key&&(this._lastTabNavDirection=t.shiftKey?nn:"forward")}}const an=".fixed-top, .fixed-bottom, .is-fixed, .sticky-top",ln=".sticky-top",cn="padding-right",hn="margin-right";class dn{constructor(){this._element=document.body}getWidth(){const t=document.documentElement.clientWidth;return Math.abs(window.innerWidth-t)}hide(){const t=this.getWidth();this._disableOverFlow(),this._setElementAttributes(this._element,cn,(e=>e+t)),this._setElementAttributes(an,cn,(e=>e+t)),this._setElementAttributes(ln,hn,(e=>e-t))}reset(){this._resetElementAttributes(this._element,"overflow"),this._resetElementAttributes(this._element,cn),this._resetElementAttributes(an,cn),this._resetElementAttributes(ln,hn)}isOverflowing(){return this.getWidth()>0}_disableOverFlow(){this._saveInitialAttribute(this._element,"overflow"),this._element.style.overflow="hidden"}_setElementAttributes(t,e,i){const n=this.getWidth();this._applyManipulationCallback(t,(t=>{if(t!==this._element&&window.innerWidth>t.clientWidth+n)return;this._saveInitialAttribute(t,e);const s=window.getComputedStyle(t).getPropertyValue(e);t.style.setProperty(e,`${i(Number.parseFloat(s))}px`)}))}_saveInitialAttribute(t,e){const i=t.style.getPropertyValue(e);i&&F.setDataAttribute(t,e,i)}_resetElementAttributes(t,e){this._applyManipulationCallback(t,(t=>{const i=F.getDataAttribute(t,e);null!==i?(F.removeDataAttribute(t,e),t.style.setProperty(e,i)):t.style.removeProperty(e)}))}_applyManipulationCallback(t,e){if(o(t))e(t);else for(const i of z.find(t,this._element))e(i)}}const un=".bs.modal",fn=`hide${un}`,pn=`hidePrevented${un}`,mn=`hidden${un}`,gn=`show${un}`,_n=`shown${un}`,bn=`resize${un}`,vn=`click.dismiss${un}`,yn=`mousedown.dismiss${un}`,wn=`keydown.dismiss${un}`,An=`click${un}.data-api`,En="modal-open",Tn="show",Cn="modal-static",On={backdrop:!0,focus:!0,keyboard:!0},xn={backdrop:"(boolean|string)",focus:"boolean",keyboard:"boolean"};class kn extends W{constructor(t,e){super(t,e),this._dialog=z.findOne(".modal-dialog",this._element),this._backdrop=this._initializeBackDrop(),this._focustrap=this._initializeFocusTrap(),this._isShown=!1,this._isTransitioning=!1,this._scrollBar=new dn,this._addEventListeners()}static get Default(){return On}static get DefaultType(){return xn}static get NAME(){return"modal"}toggle(t){return this._isShown?this.hide():this.show(t)}show(t){this._isShown||this._isTransitioning||N.trigger(this._element,gn,{relatedTarget:t}).defaultPrevented||(this._isShown=!0,this._isTransitioning=!0,this._scrollBar.hide(),document.body.classList.add(En),this._adjustDialog(),this._backdrop.show((()=>this._showElement(t))))}hide(){this._isShown&&!this._isTransitioning&&(N.trigger(this._element,fn).defaultPrevented||(this._isShown=!1,this._isTransitioning=!0,this._focustrap.deactivate(),this._element.classList.remove(Tn),this._queueCallback((()=>this._hideModal()),this._element,this._isAnimated())))}dispose(){N.off(window,un),N.off(this._dialog,un),this._backdrop.dispose(),this._focustrap.deactivate(),super.dispose()}handleUpdate(){this._adjustDialog()}_initializeBackDrop(){return new Ji({isVisible:Boolean(this._config.backdrop),isAnimated:this._isAnimated()})}_initializeFocusTrap(){return new rn({trapElement:this._element})}_showElement(t){document.body.contains(this._element)||document.body.append(this._element),this._element.style.display="block",this._element.removeAttribute("aria-hidden"),this._element.setAttribute("aria-modal",!0),this._element.setAttribute("role","dialog"),this._element.scrollTop=0;const e=z.findOne(".modal-body",this._dialog);e&&(e.scrollTop=0),d(this._element),this._element.classList.add(Tn),this._queueCallback((()=>{this._config.focus&&this._focustrap.activate(),this._isTransitioning=!1,N.trigger(this._element,_n,{relatedTarget:t})}),this._dialog,this._isAnimated())}_addEventListeners(){N.on(this._element,wn,(t=>{"Escape"===t.key&&(this._config.keyboard?this.hide():this._triggerBackdropTransition())})),N.on(window,bn,(()=>{this._isShown&&!this._isTransitioning&&this._adjustDialog()})),N.on(this._element,yn,(t=>{N.one(this._element,vn,(e=>{this._element===t.target&&this._element===e.target&&("static"!==this._config.backdrop?this._config.backdrop&&this.hide():this._triggerBackdropTransition())}))}))}_hideModal(){this._element.style.display="none",this._element.setAttribute("aria-hidden",!0),this._element.removeAttribute("aria-modal"),this._element.removeAttribute("role"),this._isTransitioning=!1,this._backdrop.hide((()=>{document.body.classList.remove(En),this._resetAdjustments(),this._scrollBar.reset(),N.trigger(this._element,mn)}))}_isAnimated(){return this._element.classList.contains("fade")}_triggerBackdropTransition(){if(N.trigger(this._element,pn).defaultPrevented)return;const t=this._element.scrollHeight>document.documentElement.clientHeight,e=this._element.style.overflowY;"hidden"===e||this._element.classList.contains(Cn)||(t||(this._element.style.overflowY="hidden"),this._element.classList.add(Cn),this._queueCallback((()=>{this._element.classList.remove(Cn),this._queueCallback((()=>{this._element.style.overflowY=e}),this._dialog)}),this._dialog),this._element.focus())}_adjustDialog(){const t=this._element.scrollHeight>document.documentElement.clientHeight,e=this._scrollBar.getWidth(),i=e>0;if(i&&!t){const t=p()?"paddingLeft":"paddingRight";this._element.style[t]=`${e}px`}if(!i&&t){const t=p()?"paddingRight":"paddingLeft";this._element.style[t]=`${e}px`}}_resetAdjustments(){this._element.style.paddingLeft="",this._element.style.paddingRight=""}static jQueryInterface(t,e){return this.each((function(){const i=kn.getOrCreateInstance(this,t);if("string"==typeof t){if(void 0===i[t])throw new TypeError(`No method named "${t}"`);i[t](e)}}))}}N.on(document,An,'[data-bs-toggle="modal"]',(function(t){const e=z.getElementFromSelector(this);["A","AREA"].includes(this.tagName)&&t.preventDefault(),N.one(e,gn,(t=>{t.defaultPrevented||N.one(e,mn,(()=>{a(this)&&this.focus()}))}));const i=z.findOne(".modal.show");i&&kn.getInstance(i).hide(),kn.getOrCreateInstance(e).toggle(this)})),R(kn),m(kn);const Ln=".bs.offcanvas",Sn=".data-api",Dn=`load${Ln}${Sn}`,$n="show",In="showing",Nn="hiding",Pn=".offcanvas.show",jn=`show${Ln}`,Mn=`shown${Ln}`,Fn=`hide${Ln}`,Hn=`hidePrevented${Ln}`,Wn=`hidden${Ln}`,Bn=`resize${Ln}`,zn=`click${Ln}${Sn}`,Rn=`keydown.dismiss${Ln}`,qn={backdrop:!0,keyboard:!0,scroll:!1},Vn={backdrop:"(boolean|string)",keyboard:"boolean",scroll:"boolean"};class Kn extends W{constructor(t,e){super(t,e),this._isShown=!1,this._backdrop=this._initializeBackDrop(),this._focustrap=this._initializeFocusTrap(),this._addEventListeners()}static get Default(){return qn}static get DefaultType(){return Vn}static get NAME(){return"offcanvas"}toggle(t){return this._isShown?this.hide():this.show(t)}show(t){this._isShown||N.trigger(this._element,jn,{relatedTarget:t}).defaultPrevented||(this._isShown=!0,this._backdrop.show(),this._config.scroll||(new dn).hide(),this._element.setAttribute("aria-modal",!0),this._element.setAttribute("role","dialog"),this._element.classList.add(In),this._queueCallback((()=>{this._config.scroll&&!this._config.backdrop||this._focustrap.activate(),this._element.classList.add($n),this._element.classList.remove(In),N.trigger(this._element,Mn,{relatedTarget:t})}),this._element,!0))}hide(){this._isShown&&(N.trigger(this._element,Fn).defaultPrevented||(this._focustrap.deactivate(),this._element.blur(),this._isShown=!1,this._element.classList.add(Nn),this._backdrop.hide(),this._queueCallback((()=>{this._element.classList.remove($n,Nn),this._element.removeAttribute("aria-modal"),this._element.removeAttribute("role"),this._config.scroll||(new dn).reset(),N.trigger(this._element,Wn)}),this._element,!0)))}dispose(){this._backdrop.dispose(),this._focustrap.deactivate(),super.dispose()}_initializeBackDrop(){const t=Boolean(this._config.backdrop);return new Ji({className:"offcanvas-backdrop",isVisible:t,isAnimated:!0,rootElement:this._element.parentNode,clickCallback:t?()=>{"static"!==this._config.backdrop?this.hide():N.trigger(this._element,Hn)}:null})}_initializeFocusTrap(){return new rn({trapElement:this._element})}_addEventListeners(){N.on(this._element,Rn,(t=>{"Escape"===t.key&&(this._config.keyboard?this.hide():N.trigger(this._element,Hn))}))}static jQueryInterface(t){return this.each((function(){const e=Kn.getOrCreateInstance(this,t);if("string"==typeof t){if(void 0===e[t]||t.startsWith("_")||"constructor"===t)throw new TypeError(`No method named "${t}"`);e[t](this)}}))}}N.on(document,zn,'[data-bs-toggle="offcanvas"]',(function(t){const e=z.getElementFromSelector(this);if(["A","AREA"].includes(this.tagName)&&t.preventDefault(),l(this))return;N.one(e,Wn,(()=>{a(this)&&this.focus()}));const i=z.findOne(Pn);i&&i!==e&&Kn.getInstance(i).hide(),Kn.getOrCreateInstance(e).toggle(this)})),N.on(window,Dn,(()=>{for(const t of z.find(Pn))Kn.getOrCreateInstance(t).show()})),N.on(window,Bn,(()=>{for(const t of z.find("[aria-modal][class*=show][class*=offcanvas-]"))"fixed"!==getComputedStyle(t).position&&Kn.getOrCreateInstance(t).hide()})),R(Kn),m(Kn);const Qn={"*":["class","dir","id","lang","role",/^aria-[\w-]*$/i],a:["target","href","title","rel"],area:[],b:[],br:[],col:[],code:[],dd:[],div:[],dl:[],dt:[],em:[],hr:[],h1:[],h2:[],h3:[],h4:[],h5:[],h6:[],i:[],img:["src","srcset","alt","title","width","height"],li:[],ol:[],p:[],pre:[],s:[],small:[],span:[],sub:[],sup:[],strong:[],u:[],ul:[]},Xn=new Set(["background","cite","href","itemtype","longdesc","poster","src","xlink:href"]),Yn=/^(?!javascript:)(?:[a-z0-9+.-]+:|[^&:/?#]*(?:[/?#]|$))/i,Un=(t,e)=>{const i=t.nodeName.toLowerCase();return e.includes(i)?!Xn.has(i)||Boolean(Yn.test(t.nodeValue)):e.filter((t=>t instanceof RegExp)).some((t=>t.test(i)))},Gn={allowList:Qn,content:{},extraClass:"",html:!1,sanitize:!0,sanitizeFn:null,template:"
"},Jn={allowList:"object",content:"object",extraClass:"(string|function)",html:"boolean",sanitize:"boolean",sanitizeFn:"(null|function)",template:"string"},Zn={entry:"(string|element|function|null)",selector:"(string|element)"};class ts extends H{constructor(t){super(),this._config=this._getConfig(t)}static get Default(){return Gn}static get DefaultType(){return Jn}static get NAME(){return"TemplateFactory"}getContent(){return Object.values(this._config.content).map((t=>this._resolvePossibleFunction(t))).filter(Boolean)}hasContent(){return this.getContent().length>0}changeContent(t){return this._checkContent(t),this._config.content={...this._config.content,...t},this}toHtml(){const t=document.createElement("div");t.innerHTML=this._maybeSanitize(this._config.template);for(const[e,i]of Object.entries(this._config.content))this._setContent(t,i,e);const e=t.children[0],i=this._resolvePossibleFunction(this._config.extraClass);return i&&e.classList.add(...i.split(" ")),e}_typeCheckConfig(t){super._typeCheckConfig(t),this._checkContent(t.content)}_checkContent(t){for(const[e,i]of Object.entries(t))super._typeCheckConfig({selector:e,entry:i},Zn)}_setContent(t,e,i){const n=z.findOne(i,t);n&&((e=this._resolvePossibleFunction(e))?o(e)?this._putElementInTemplate(r(e),n):this._config.html?n.innerHTML=this._maybeSanitize(e):n.textContent=e:n.remove())}_maybeSanitize(t){return this._config.sanitize?function(t,e,i){if(!t.length)return t;if(i&&"function"==typeof i)return i(t);const n=(new window.DOMParser).parseFromString(t,"text/html"),s=[].concat(...n.body.querySelectorAll("*"));for(const t of s){const i=t.nodeName.toLowerCase();if(!Object.keys(e).includes(i)){t.remove();continue}const n=[].concat(...t.attributes),s=[].concat(e["*"]||[],e[i]||[]);for(const e of n)Un(e,s)||t.removeAttribute(e.nodeName)}return n.body.innerHTML}(t,this._config.allowList,this._config.sanitizeFn):t}_resolvePossibleFunction(t){return g(t,[void 0,this])}_putElementInTemplate(t,e){if(this._config.html)return e.innerHTML="",void e.append(t);e.textContent=t.textContent}}const es=new Set(["sanitize","allowList","sanitizeFn"]),is="fade",ns="show",ss=".tooltip-inner",os=".modal",rs="hide.bs.modal",as="hover",ls="focus",cs={AUTO:"auto",TOP:"top",RIGHT:p()?"left":"right",BOTTOM:"bottom",LEFT:p()?"right":"left"},hs={allowList:Qn,animation:!0,boundary:"clippingParents",container:!1,customClass:"",delay:0,fallbackPlacements:["top","right","bottom","left"],html:!1,offset:[0,6],placement:"top",popperConfig:null,sanitize:!0,sanitizeFn:null,selector:!1,template:'',title:"",trigger:"hover focus"},ds={allowList:"object",animation:"boolean",boundary:"(string|element)",container:"(string|element|boolean)",customClass:"(string|function)",delay:"(number|object)",fallbackPlacements:"array",html:"boolean",offset:"(array|string|function)",placement:"(string|function)",popperConfig:"(null|object|function)",sanitize:"boolean",sanitizeFn:"(null|function)",selector:"(string|boolean)",template:"string",title:"(string|element|function)",trigger:"string"};class us extends W{constructor(t,e){if(void 0===wi)throw new TypeError("Bootstrap's tooltips require Popper (https://popper.js.org/docs/v2/)");super(t,e),this._isEnabled=!0,this._timeout=0,this._isHovered=null,this._activeTrigger={},this._popper=null,this._templateFactory=null,this._newContent=null,this.tip=null,this._setListeners(),this._config.selector||this._fixTitle()}static get Default(){return hs}static get DefaultType(){return ds}static get NAME(){return"tooltip"}enable(){this._isEnabled=!0}disable(){this._isEnabled=!1}toggleEnabled(){this._isEnabled=!this._isEnabled}toggle(){this._isEnabled&&(this._isShown()?this._leave():this._enter())}dispose(){clearTimeout(this._timeout),N.off(this._element.closest(os),rs,this._hideModalHandler),this._element.getAttribute("data-bs-original-title")&&this._element.setAttribute("title",this._element.getAttribute("data-bs-original-title")),this._disposePopper(),super.dispose()}show(){if("none"===this._element.style.display)throw new Error("Please use show on visible elements");if(!this._isWithContent()||!this._isEnabled)return;const t=N.trigger(this._element,this.constructor.eventName("show")),e=(c(this._element)||this._element.ownerDocument.documentElement).contains(this._element);if(t.defaultPrevented||!e)return;this._disposePopper();const i=this._getTipElement();this._element.setAttribute("aria-describedby",i.getAttribute("id"));const{container:n}=this._config;if(this._element.ownerDocument.documentElement.contains(this.tip)||(n.append(i),N.trigger(this._element,this.constructor.eventName("inserted"))),this._popper=this._createPopper(i),i.classList.add(ns),"ontouchstart"in document.documentElement)for(const t of[].concat(...document.body.children))N.on(t,"mouseover",h);this._queueCallback((()=>{N.trigger(this._element,this.constructor.eventName("shown")),!1===this._isHovered&&this._leave(),this._isHovered=!1}),this.tip,this._isAnimated())}hide(){if(this._isShown()&&!N.trigger(this._element,this.constructor.eventName("hide")).defaultPrevented){if(this._getTipElement().classList.remove(ns),"ontouchstart"in document.documentElement)for(const t of[].concat(...document.body.children))N.off(t,"mouseover",h);this._activeTrigger.click=!1,this._activeTrigger[ls]=!1,this._activeTrigger[as]=!1,this._isHovered=null,this._queueCallback((()=>{this._isWithActiveTrigger()||(this._isHovered||this._disposePopper(),this._element.removeAttribute("aria-describedby"),N.trigger(this._element,this.constructor.eventName("hidden")))}),this.tip,this._isAnimated())}}update(){this._popper&&this._popper.update()}_isWithContent(){return Boolean(this._getTitle())}_getTipElement(){return this.tip||(this.tip=this._createTipElement(this._newContent||this._getContentForTemplate())),this.tip}_createTipElement(t){const e=this._getTemplateFactory(t).toHtml();if(!e)return null;e.classList.remove(is,ns),e.classList.add(`bs-${this.constructor.NAME}-auto`);const i=(t=>{do{t+=Math.floor(1e6*Math.random())}while(document.getElementById(t));return t})(this.constructor.NAME).toString();return e.setAttribute("id",i),this._isAnimated()&&e.classList.add(is),e}setContent(t){this._newContent=t,this._isShown()&&(this._disposePopper(),this.show())}_getTemplateFactory(t){return this._templateFactory?this._templateFactory.changeContent(t):this._templateFactory=new ts({...this._config,content:t,extraClass:this._resolvePossibleFunction(this._config.customClass)}),this._templateFactory}_getContentForTemplate(){return{[ss]:this._getTitle()}}_getTitle(){return this._resolvePossibleFunction(this._config.title)||this._element.getAttribute("data-bs-original-title")}_initializeOnDelegatedTarget(t){return this.constructor.getOrCreateInstance(t.delegateTarget,this._getDelegateConfig())}_isAnimated(){return this._config.animation||this.tip&&this.tip.classList.contains(is)}_isShown(){return this.tip&&this.tip.classList.contains(ns)}_createPopper(t){const e=g(this._config.placement,[this,t,this._element]),i=cs[e.toUpperCase()];return yi(this._element,t,this._getPopperConfig(i))}_getOffset(){const{offset:t}=this._config;return"string"==typeof t?t.split(",").map((t=>Number.parseInt(t,10))):"function"==typeof t?e=>t(e,this._element):t}_resolvePossibleFunction(t){return g(t,[this._element,this._element])}_getPopperConfig(t){const e={placement:t,modifiers:[{name:"flip",options:{fallbackPlacements:this._config.fallbackPlacements}},{name:"offset",options:{offset:this._getOffset()}},{name:"preventOverflow",options:{boundary:this._config.boundary}},{name:"arrow",options:{element:`.${this.constructor.NAME}-arrow`}},{name:"preSetPlacement",enabled:!0,phase:"beforeMain",fn:t=>{this._getTipElement().setAttribute("data-popper-placement",t.state.placement)}}]};return{...e,...g(this._config.popperConfig,[void 0,e])}}_setListeners(){const t=this._config.trigger.split(" ");for(const e of t)if("click"===e)N.on(this._element,this.constructor.eventName("click"),this._config.selector,(t=>{this._initializeOnDelegatedTarget(t).toggle()}));else if("manual"!==e){const t=e===as?this.constructor.eventName("mouseenter"):this.constructor.eventName("focusin"),i=e===as?this.constructor.eventName("mouseleave"):this.constructor.eventName("focusout");N.on(this._element,t,this._config.selector,(t=>{const e=this._initializeOnDelegatedTarget(t);e._activeTrigger["focusin"===t.type?ls:as]=!0,e._enter()})),N.on(this._element,i,this._config.selector,(t=>{const e=this._initializeOnDelegatedTarget(t);e._activeTrigger["focusout"===t.type?ls:as]=e._element.contains(t.relatedTarget),e._leave()}))}this._hideModalHandler=()=>{this._element&&this.hide()},N.on(this._element.closest(os),rs,this._hideModalHandler)}_fixTitle(){const t=this._element.getAttribute("title");t&&(this._element.getAttribute("aria-label")||this._element.textContent.trim()||this._element.setAttribute("aria-label",t),this._element.setAttribute("data-bs-original-title",t),this._element.removeAttribute("title"))}_enter(){this._isShown()||this._isHovered?this._isHovered=!0:(this._isHovered=!0,this._setTimeout((()=>{this._isHovered&&this.show()}),this._config.delay.show))}_leave(){this._isWithActiveTrigger()||(this._isHovered=!1,this._setTimeout((()=>{this._isHovered||this.hide()}),this._config.delay.hide))}_setTimeout(t,e){clearTimeout(this._timeout),this._timeout=setTimeout(t,e)}_isWithActiveTrigger(){return Object.values(this._activeTrigger).includes(!0)}_getConfig(t){const e=F.getDataAttributes(this._element);for(const t of Object.keys(e))es.has(t)&&delete e[t];return t={...e,..."object"==typeof t&&t?t:{}},t=this._mergeConfigObj(t),t=this._configAfterMerge(t),this._typeCheckConfig(t),t}_configAfterMerge(t){return t.container=!1===t.container?document.body:r(t.container),"number"==typeof t.delay&&(t.delay={show:t.delay,hide:t.delay}),"number"==typeof t.title&&(t.title=t.title.toString()),"number"==typeof t.content&&(t.content=t.content.toString()),t}_getDelegateConfig(){const t={};for(const[e,i]of Object.entries(this._config))this.constructor.Default[e]!==i&&(t[e]=i);return t.selector=!1,t.trigger="manual",t}_disposePopper(){this._popper&&(this._popper.destroy(),this._popper=null),this.tip&&(this.tip.remove(),this.tip=null)}static jQueryInterface(t){return this.each((function(){const e=us.getOrCreateInstance(this,t);if("string"==typeof t){if(void 0===e[t])throw new TypeError(`No method named "${t}"`);e[t]()}}))}}m(us);const fs=".popover-header",ps=".popover-body",ms={...us.Default,content:"",offset:[0,8],placement:"right",template:'',trigger:"click"},gs={...us.DefaultType,content:"(null|string|element|function)"};class _s extends us{static get Default(){return ms}static get DefaultType(){return gs}static get NAME(){return"popover"}_isWithContent(){return this._getTitle()||this._getContent()}_getContentForTemplate(){return{[fs]:this._getTitle(),[ps]:this._getContent()}}_getContent(){return this._resolvePossibleFunction(this._config.content)}static jQueryInterface(t){return this.each((function(){const e=_s.getOrCreateInstance(this,t);if("string"==typeof t){if(void 0===e[t])throw new TypeError(`No method named "${t}"`);e[t]()}}))}}m(_s);const bs=".bs.scrollspy",vs=`activate${bs}`,ys=`click${bs}`,ws=`load${bs}.data-api`,As="active",Es="[href]",Ts=".nav-link",Cs=`${Ts}, .nav-item > ${Ts}, .list-group-item`,Os={offset:null,rootMargin:"0px 0px -25%",smoothScroll:!1,target:null,threshold:[.1,.5,1]},xs={offset:"(number|null)",rootMargin:"string",smoothScroll:"boolean",target:"element",threshold:"array"};class ks extends W{constructor(t,e){super(t,e),this._targetLinks=new Map,this._observableSections=new Map,this._rootElement="visible"===getComputedStyle(this._element).overflowY?null:this._element,this._activeTarget=null,this._observer=null,this._previousScrollData={visibleEntryTop:0,parentScrollTop:0},this.refresh()}static get Default(){return Os}static get DefaultType(){return xs}static get NAME(){return"scrollspy"}refresh(){this._initializeTargetsAndObservables(),this._maybeEnableSmoothScroll(),this._observer?this._observer.disconnect():this._observer=this._getNewObserver();for(const t of this._observableSections.values())this._observer.observe(t)}dispose(){this._observer.disconnect(),super.dispose()}_configAfterMerge(t){return t.target=r(t.target)||document.body,t.rootMargin=t.offset?`${t.offset}px 0px -30%`:t.rootMargin,"string"==typeof t.threshold&&(t.threshold=t.threshold.split(",").map((t=>Number.parseFloat(t)))),t}_maybeEnableSmoothScroll(){this._config.smoothScroll&&(N.off(this._config.target,ys),N.on(this._config.target,ys,Es,(t=>{const e=this._observableSections.get(t.target.hash);if(e){t.preventDefault();const i=this._rootElement||window,n=e.offsetTop-this._element.offsetTop;if(i.scrollTo)return void i.scrollTo({top:n,behavior:"smooth"});i.scrollTop=n}})))}_getNewObserver(){const t={root:this._rootElement,threshold:this._config.threshold,rootMargin:this._config.rootMargin};return new IntersectionObserver((t=>this._observerCallback(t)),t)}_observerCallback(t){const e=t=>this._targetLinks.get(`#${t.target.id}`),i=t=>{this._previousScrollData.visibleEntryTop=t.target.offsetTop,this._process(e(t))},n=(this._rootElement||document.documentElement).scrollTop,s=n>=this._previousScrollData.parentScrollTop;this._previousScrollData.parentScrollTop=n;for(const o of t){if(!o.isIntersecting){this._activeTarget=null,this._clearActiveClass(e(o));continue}const t=o.target.offsetTop>=this._previousScrollData.visibleEntryTop;if(s&&t){if(i(o),!n)return}else s||t||i(o)}}_initializeTargetsAndObservables(){this._targetLinks=new Map,this._observableSections=new Map;const t=z.find(Es,this._config.target);for(const e of t){if(!e.hash||l(e))continue;const t=z.findOne(decodeURI(e.hash),this._element);a(t)&&(this._targetLinks.set(decodeURI(e.hash),e),this._observableSections.set(e.hash,t))}}_process(t){this._activeTarget!==t&&(this._clearActiveClass(this._config.target),this._activeTarget=t,t.classList.add(As),this._activateParents(t),N.trigger(this._element,vs,{relatedTarget:t}))}_activateParents(t){if(t.classList.contains("dropdown-item"))z.findOne(".dropdown-toggle",t.closest(".dropdown")).classList.add(As);else for(const e of z.parents(t,".nav, .list-group"))for(const t of z.prev(e,Cs))t.classList.add(As)}_clearActiveClass(t){t.classList.remove(As);const e=z.find(`${Es}.${As}`,t);for(const t of e)t.classList.remove(As)}static jQueryInterface(t){return this.each((function(){const e=ks.getOrCreateInstance(this,t);if("string"==typeof t){if(void 0===e[t]||t.startsWith("_")||"constructor"===t)throw new TypeError(`No method named "${t}"`);e[t]()}}))}}N.on(window,ws,(()=>{for(const t of z.find('[data-bs-spy="scroll"]'))ks.getOrCreateInstance(t)})),m(ks);const Ls=".bs.tab",Ss=`hide${Ls}`,Ds=`hidden${Ls}`,$s=`show${Ls}`,Is=`shown${Ls}`,Ns=`click${Ls}`,Ps=`keydown${Ls}`,js=`load${Ls}`,Ms="ArrowLeft",Fs="ArrowRight",Hs="ArrowUp",Ws="ArrowDown",Bs="Home",zs="End",Rs="active",qs="fade",Vs="show",Ks=".dropdown-toggle",Qs=`:not(${Ks})`,Xs='[data-bs-toggle="tab"], [data-bs-toggle="pill"], [data-bs-toggle="list"]',Ys=`.nav-link${Qs}, .list-group-item${Qs}, [role="tab"]${Qs}, ${Xs}`,Us=`.${Rs}[data-bs-toggle="tab"], .${Rs}[data-bs-toggle="pill"], .${Rs}[data-bs-toggle="list"]`;class Gs extends W{constructor(t){super(t),this._parent=this._element.closest('.list-group, .nav, [role="tablist"]'),this._parent&&(this._setInitialAttributes(this._parent,this._getChildren()),N.on(this._element,Ps,(t=>this._keydown(t))))}static get NAME(){return"tab"}show(){const t=this._element;if(this._elemIsActive(t))return;const e=this._getActiveElem(),i=e?N.trigger(e,Ss,{relatedTarget:t}):null;N.trigger(t,$s,{relatedTarget:e}).defaultPrevented||i&&i.defaultPrevented||(this._deactivate(e,t),this._activate(t,e))}_activate(t,e){t&&(t.classList.add(Rs),this._activate(z.getElementFromSelector(t)),this._queueCallback((()=>{"tab"===t.getAttribute("role")?(t.removeAttribute("tabindex"),t.setAttribute("aria-selected",!0),this._toggleDropDown(t,!0),N.trigger(t,Is,{relatedTarget:e})):t.classList.add(Vs)}),t,t.classList.contains(qs)))}_deactivate(t,e){t&&(t.classList.remove(Rs),t.blur(),this._deactivate(z.getElementFromSelector(t)),this._queueCallback((()=>{"tab"===t.getAttribute("role")?(t.setAttribute("aria-selected",!1),t.setAttribute("tabindex","-1"),this._toggleDropDown(t,!1),N.trigger(t,Ds,{relatedTarget:e})):t.classList.remove(Vs)}),t,t.classList.contains(qs)))}_keydown(t){if(![Ms,Fs,Hs,Ws,Bs,zs].includes(t.key))return;t.stopPropagation(),t.preventDefault();const e=this._getChildren().filter((t=>!l(t)));let i;if([Bs,zs].includes(t.key))i=e[t.key===Bs?0:e.length-1];else{const n=[Fs,Ws].includes(t.key);i=b(e,t.target,n,!0)}i&&(i.focus({preventScroll:!0}),Gs.getOrCreateInstance(i).show())}_getChildren(){return z.find(Ys,this._parent)}_getActiveElem(){return this._getChildren().find((t=>this._elemIsActive(t)))||null}_setInitialAttributes(t,e){this._setAttributeIfNotExists(t,"role","tablist");for(const t of e)this._setInitialAttributesOnChild(t)}_setInitialAttributesOnChild(t){t=this._getInnerElement(t);const e=this._elemIsActive(t),i=this._getOuterElement(t);t.setAttribute("aria-selected",e),i!==t&&this._setAttributeIfNotExists(i,"role","presentation"),e||t.setAttribute("tabindex","-1"),this._setAttributeIfNotExists(t,"role","tab"),this._setInitialAttributesOnTargetPanel(t)}_setInitialAttributesOnTargetPanel(t){const e=z.getElementFromSelector(t);e&&(this._setAttributeIfNotExists(e,"role","tabpanel"),t.id&&this._setAttributeIfNotExists(e,"aria-labelledby",`${t.id}`))}_toggleDropDown(t,e){const i=this._getOuterElement(t);if(!i.classList.contains("dropdown"))return;const n=(t,n)=>{const s=z.findOne(t,i);s&&s.classList.toggle(n,e)};n(Ks,Rs),n(".dropdown-menu",Vs),i.setAttribute("aria-expanded",e)}_setAttributeIfNotExists(t,e,i){t.hasAttribute(e)||t.setAttribute(e,i)}_elemIsActive(t){return t.classList.contains(Rs)}_getInnerElement(t){return t.matches(Ys)?t:z.findOne(Ys,t)}_getOuterElement(t){return t.closest(".nav-item, .list-group-item")||t}static jQueryInterface(t){return this.each((function(){const e=Gs.getOrCreateInstance(this);if("string"==typeof t){if(void 0===e[t]||t.startsWith("_")||"constructor"===t)throw new TypeError(`No method named "${t}"`);e[t]()}}))}}N.on(document,Ns,Xs,(function(t){["A","AREA"].includes(this.tagName)&&t.preventDefault(),l(this)||Gs.getOrCreateInstance(this).show()})),N.on(window,js,(()=>{for(const t of z.find(Us))Gs.getOrCreateInstance(t)})),m(Gs);const Js=".bs.toast",Zs=`mouseover${Js}`,to=`mouseout${Js}`,eo=`focusin${Js}`,io=`focusout${Js}`,no=`hide${Js}`,so=`hidden${Js}`,oo=`show${Js}`,ro=`shown${Js}`,ao="hide",lo="show",co="showing",ho={animation:"boolean",autohide:"boolean",delay:"number"},uo={animation:!0,autohide:!0,delay:5e3};class fo extends W{constructor(t,e){super(t,e),this._timeout=null,this._hasMouseInteraction=!1,this._hasKeyboardInteraction=!1,this._setListeners()}static get Default(){return uo}static get DefaultType(){return ho}static get NAME(){return"toast"}show(){N.trigger(this._element,oo).defaultPrevented||(this._clearTimeout(),this._config.animation&&this._element.classList.add("fade"),this._element.classList.remove(ao),d(this._element),this._element.classList.add(lo,co),this._queueCallback((()=>{this._element.classList.remove(co),N.trigger(this._element,ro),this._maybeScheduleHide()}),this._element,this._config.animation))}hide(){this.isShown()&&(N.trigger(this._element,no).defaultPrevented||(this._element.classList.add(co),this._queueCallback((()=>{this._element.classList.add(ao),this._element.classList.remove(co,lo),N.trigger(this._element,so)}),this._element,this._config.animation)))}dispose(){this._clearTimeout(),this.isShown()&&this._element.classList.remove(lo),super.dispose()}isShown(){return this._element.classList.contains(lo)}_maybeScheduleHide(){this._config.autohide&&(this._hasMouseInteraction||this._hasKeyboardInteraction||(this._timeout=setTimeout((()=>{this.hide()}),this._config.delay)))}_onInteraction(t,e){switch(t.type){case"mouseover":case"mouseout":this._hasMouseInteraction=e;break;case"focusin":case"focusout":this._hasKeyboardInteraction=e}if(e)return void this._clearTimeout();const i=t.relatedTarget;this._element===i||this._element.contains(i)||this._maybeScheduleHide()}_setListeners(){N.on(this._element,Zs,(t=>this._onInteraction(t,!0))),N.on(this._element,to,(t=>this._onInteraction(t,!1))),N.on(this._element,eo,(t=>this._onInteraction(t,!0))),N.on(this._element,io,(t=>this._onInteraction(t,!1)))}_clearTimeout(){clearTimeout(this._timeout),this._timeout=null}static jQueryInterface(t){return this.each((function(){const e=fo.getOrCreateInstance(this,t);if("string"==typeof t){if(void 0===e[t])throw new TypeError(`No method named "${t}"`);e[t](this)}}))}}return R(fo),m(fo),{Alert:Q,Button:Y,Carousel:Lt,Collapse:Rt,Dropdown:Ki,Modal:kn,Offcanvas:Kn,Popover:_s,ScrollSpy:ks,Tab:Gs,Toast:fo,Tooltip:us}})); -//# sourceMappingURL=bootstrap.bundle.min.js.map \ No newline at end of file diff --git a/backend/coverage-report-controllers/_js/d3.min.js b/backend/coverage-report-controllers/_js/d3.min.js deleted file mode 100644 index 16648730..00000000 --- a/backend/coverage-report-controllers/_js/d3.min.js +++ /dev/null @@ -1,5 +0,0 @@ -!function(){function n(n){return n&&(n.ownerDocument||n.document||n).documentElement}function t(n){return n&&(n.ownerDocument&&n.ownerDocument.defaultView||n.document&&n||n.defaultView)}function e(n,t){return t>n?-1:n>t?1:n>=t?0:NaN}function r(n){return null===n?NaN:+n}function i(n){return!isNaN(n)}function u(n){return{left:function(t,e,r,i){for(arguments.length<3&&(r=0),arguments.length<4&&(i=t.length);i>r;){var u=r+i>>>1;n(t[u],e)<0?r=u+1:i=u}return r},right:function(t,e,r,i){for(arguments.length<3&&(r=0),arguments.length<4&&(i=t.length);i>r;){var u=r+i>>>1;n(t[u],e)>0?i=u:r=u+1}return r}}}function o(n){return n.length}function a(n){for(var t=1;n*t%1;)t*=10;return t}function l(n,t){for(var e in t)Object.defineProperty(n.prototype,e,{value:t[e],enumerable:!1})}function c(){this._=Object.create(null)}function f(n){return(n+="")===bo||n[0]===_o?_o+n:n}function s(n){return(n+="")[0]===_o?n.slice(1):n}function h(n){return f(n)in this._}function p(n){return(n=f(n))in this._&&delete this._[n]}function g(){var n=[];for(var t in this._)n.push(s(t));return n}function v(){var n=0;for(var t in this._)++n;return n}function d(){for(var n in this._)return!1;return!0}function y(){this._=Object.create(null)}function m(n){return n}function M(n,t,e){return function(){var r=e.apply(t,arguments);return r===t?n:r}}function x(n,t){if(t in n)return t;t=t.charAt(0).toUpperCase()+t.slice(1);for(var e=0,r=wo.length;r>e;++e){var i=wo[e]+t;if(i in n)return i}}function b(){}function _(){}function w(n){function t(){for(var t,r=e,i=-1,u=r.length;++ie;e++)for(var i,u=n[e],o=0,a=u.length;a>o;o++)(i=u[o])&&t(i,o,e);return n}function Z(n){return ko(n,qo),n}function V(n){var t,e;return function(r,i,u){var o,a=n[u].update,l=a.length;for(u!=e&&(e=u,t=0),i>=t&&(t=i+1);!(o=a[t])&&++t0&&(n=n.slice(0,a));var c=To.get(n);return c&&(n=c,l=B),a?t?i:r:t?b:u}function $(n,t){return function(e){var r=ao.event;ao.event=e,t[0]=this.__data__;try{n.apply(this,t)}finally{ao.event=r}}}function B(n,t){var e=$(n,t);return function(n){var t=this,r=n.relatedTarget;r&&(r===t||8&r.compareDocumentPosition(t))||e.call(t,n)}}function W(e){var r=".dragsuppress-"+ ++Do,i="click"+r,u=ao.select(t(e)).on("touchmove"+r,S).on("dragstart"+r,S).on("selectstart"+r,S);if(null==Ro&&(Ro="onselectstart"in e?!1:x(e.style,"userSelect")),Ro){var o=n(e).style,a=o[Ro];o[Ro]="none"}return function(n){if(u.on(r,null),Ro&&(o[Ro]=a),n){var t=function(){u.on(i,null)};u.on(i,function(){S(),t()},!0),setTimeout(t,0)}}}function J(n,e){e.changedTouches&&(e=e.changedTouches[0]);var r=n.ownerSVGElement||n;if(r.createSVGPoint){var i=r.createSVGPoint();if(0>Po){var u=t(n);if(u.scrollX||u.scrollY){r=ao.select("body").append("svg").style({position:"absolute",top:0,left:0,margin:0,padding:0,border:"none"},"important");var o=r[0][0].getScreenCTM();Po=!(o.f||o.e),r.remove()}}return Po?(i.x=e.pageX,i.y=e.pageY):(i.x=e.clientX,i.y=e.clientY),i=i.matrixTransform(n.getScreenCTM().inverse()),[i.x,i.y]}var a=n.getBoundingClientRect();return[e.clientX-a.left-n.clientLeft,e.clientY-a.top-n.clientTop]}function G(){return ao.event.changedTouches[0].identifier}function K(n){return n>0?1:0>n?-1:0}function Q(n,t,e){return(t[0]-n[0])*(e[1]-n[1])-(t[1]-n[1])*(e[0]-n[0])}function nn(n){return n>1?0:-1>n?Fo:Math.acos(n)}function tn(n){return n>1?Io:-1>n?-Io:Math.asin(n)}function en(n){return((n=Math.exp(n))-1/n)/2}function rn(n){return((n=Math.exp(n))+1/n)/2}function un(n){return((n=Math.exp(2*n))-1)/(n+1)}function on(n){return(n=Math.sin(n/2))*n}function an(){}function ln(n,t,e){return this instanceof ln?(this.h=+n,this.s=+t,void(this.l=+e)):arguments.length<2?n instanceof ln?new ln(n.h,n.s,n.l):_n(""+n,wn,ln):new ln(n,t,e)}function cn(n,t,e){function r(n){return n>360?n-=360:0>n&&(n+=360),60>n?u+(o-u)*n/60:180>n?o:240>n?u+(o-u)*(240-n)/60:u}function i(n){return Math.round(255*r(n))}var u,o;return n=isNaN(n)?0:(n%=360)<0?n+360:n,t=isNaN(t)?0:0>t?0:t>1?1:t,e=0>e?0:e>1?1:e,o=.5>=e?e*(1+t):e+t-e*t,u=2*e-o,new mn(i(n+120),i(n),i(n-120))}function fn(n,t,e){return this instanceof fn?(this.h=+n,this.c=+t,void(this.l=+e)):arguments.length<2?n instanceof fn?new fn(n.h,n.c,n.l):n instanceof hn?gn(n.l,n.a,n.b):gn((n=Sn((n=ao.rgb(n)).r,n.g,n.b)).l,n.a,n.b):new fn(n,t,e)}function sn(n,t,e){return isNaN(n)&&(n=0),isNaN(t)&&(t=0),new hn(e,Math.cos(n*=Yo)*t,Math.sin(n)*t)}function hn(n,t,e){return this instanceof hn?(this.l=+n,this.a=+t,void(this.b=+e)):arguments.length<2?n instanceof hn?new hn(n.l,n.a,n.b):n instanceof fn?sn(n.h,n.c,n.l):Sn((n=mn(n)).r,n.g,n.b):new hn(n,t,e)}function pn(n,t,e){var r=(n+16)/116,i=r+t/500,u=r-e/200;return i=vn(i)*na,r=vn(r)*ta,u=vn(u)*ea,new mn(yn(3.2404542*i-1.5371385*r-.4985314*u),yn(-.969266*i+1.8760108*r+.041556*u),yn(.0556434*i-.2040259*r+1.0572252*u))}function gn(n,t,e){return n>0?new fn(Math.atan2(e,t)*Zo,Math.sqrt(t*t+e*e),n):new fn(NaN,NaN,n)}function vn(n){return n>.206893034?n*n*n:(n-4/29)/7.787037}function dn(n){return n>.008856?Math.pow(n,1/3):7.787037*n+4/29}function yn(n){return Math.round(255*(.00304>=n?12.92*n:1.055*Math.pow(n,1/2.4)-.055))}function mn(n,t,e){return this instanceof mn?(this.r=~~n,this.g=~~t,void(this.b=~~e)):arguments.length<2?n instanceof mn?new mn(n.r,n.g,n.b):_n(""+n,mn,cn):new mn(n,t,e)}function Mn(n){return new mn(n>>16,n>>8&255,255&n)}function xn(n){return Mn(n)+""}function bn(n){return 16>n?"0"+Math.max(0,n).toString(16):Math.min(255,n).toString(16)}function _n(n,t,e){var r,i,u,o=0,a=0,l=0;if(r=/([a-z]+)\((.*)\)/.exec(n=n.toLowerCase()))switch(i=r[2].split(","),r[1]){case"hsl":return e(parseFloat(i[0]),parseFloat(i[1])/100,parseFloat(i[2])/100);case"rgb":return t(Nn(i[0]),Nn(i[1]),Nn(i[2]))}return(u=ua.get(n))?t(u.r,u.g,u.b):(null==n||"#"!==n.charAt(0)||isNaN(u=parseInt(n.slice(1),16))||(4===n.length?(o=(3840&u)>>4,o=o>>4|o,a=240&u,a=a>>4|a,l=15&u,l=l<<4|l):7===n.length&&(o=(16711680&u)>>16,a=(65280&u)>>8,l=255&u)),t(o,a,l))}function wn(n,t,e){var r,i,u=Math.min(n/=255,t/=255,e/=255),o=Math.max(n,t,e),a=o-u,l=(o+u)/2;return a?(i=.5>l?a/(o+u):a/(2-o-u),r=n==o?(t-e)/a+(e>t?6:0):t==o?(e-n)/a+2:(n-t)/a+4,r*=60):(r=NaN,i=l>0&&1>l?0:r),new ln(r,i,l)}function Sn(n,t,e){n=kn(n),t=kn(t),e=kn(e);var r=dn((.4124564*n+.3575761*t+.1804375*e)/na),i=dn((.2126729*n+.7151522*t+.072175*e)/ta),u=dn((.0193339*n+.119192*t+.9503041*e)/ea);return hn(116*i-16,500*(r-i),200*(i-u))}function kn(n){return(n/=255)<=.04045?n/12.92:Math.pow((n+.055)/1.055,2.4)}function Nn(n){var t=parseFloat(n);return"%"===n.charAt(n.length-1)?Math.round(2.55*t):t}function En(n){return"function"==typeof n?n:function(){return n}}function An(n){return function(t,e,r){return 2===arguments.length&&"function"==typeof e&&(r=e,e=null),Cn(t,e,n,r)}}function Cn(n,t,e,r){function i(){var n,t=l.status;if(!t&&Ln(l)||t>=200&&300>t||304===t){try{n=e.call(u,l)}catch(r){return void o.error.call(u,r)}o.load.call(u,n)}else o.error.call(u,l)}var u={},o=ao.dispatch("beforesend","progress","load","error"),a={},l=new XMLHttpRequest,c=null;return!this.XDomainRequest||"withCredentials"in l||!/^(http(s)?:)?\/\//.test(n)||(l=new XDomainRequest),"onload"in l?l.onload=l.onerror=i:l.onreadystatechange=function(){l.readyState>3&&i()},l.onprogress=function(n){var t=ao.event;ao.event=n;try{o.progress.call(u,l)}finally{ao.event=t}},u.header=function(n,t){return n=(n+"").toLowerCase(),arguments.length<2?a[n]:(null==t?delete a[n]:a[n]=t+"",u)},u.mimeType=function(n){return arguments.length?(t=null==n?null:n+"",u):t},u.responseType=function(n){return arguments.length?(c=n,u):c},u.response=function(n){return e=n,u},["get","post"].forEach(function(n){u[n]=function(){return u.send.apply(u,[n].concat(co(arguments)))}}),u.send=function(e,r,i){if(2===arguments.length&&"function"==typeof r&&(i=r,r=null),l.open(e,n,!0),null==t||"accept"in a||(a.accept=t+",*/*"),l.setRequestHeader)for(var f in a)l.setRequestHeader(f,a[f]);return null!=t&&l.overrideMimeType&&l.overrideMimeType(t),null!=c&&(l.responseType=c),null!=i&&u.on("error",i).on("load",function(n){i(null,n)}),o.beforesend.call(u,l),l.send(null==r?null:r),u},u.abort=function(){return l.abort(),u},ao.rebind(u,o,"on"),null==r?u:u.get(zn(r))}function zn(n){return 1===n.length?function(t,e){n(null==t?e:null)}:n}function Ln(n){var t=n.responseType;return t&&"text"!==t?n.response:n.responseText}function qn(n,t,e){var r=arguments.length;2>r&&(t=0),3>r&&(e=Date.now());var i=e+t,u={c:n,t:i,n:null};return aa?aa.n=u:oa=u,aa=u,la||(ca=clearTimeout(ca),la=1,fa(Tn)),u}function Tn(){var n=Rn(),t=Dn()-n;t>24?(isFinite(t)&&(clearTimeout(ca),ca=setTimeout(Tn,t)),la=0):(la=1,fa(Tn))}function Rn(){for(var n=Date.now(),t=oa;t;)n>=t.t&&t.c(n-t.t)&&(t.c=null),t=t.n;return n}function Dn(){for(var n,t=oa,e=1/0;t;)t.c?(t.t8?function(n){return n/e}:function(n){return n*e},symbol:n}}function jn(n){var t=n.decimal,e=n.thousands,r=n.grouping,i=n.currency,u=r&&e?function(n,t){for(var i=n.length,u=[],o=0,a=r[0],l=0;i>0&&a>0&&(l+a+1>t&&(a=Math.max(1,t-l)),u.push(n.substring(i-=a,i+a)),!((l+=a+1)>t));)a=r[o=(o+1)%r.length];return u.reverse().join(e)}:m;return function(n){var e=ha.exec(n),r=e[1]||" ",o=e[2]||">",a=e[3]||"-",l=e[4]||"",c=e[5],f=+e[6],s=e[7],h=e[8],p=e[9],g=1,v="",d="",y=!1,m=!0;switch(h&&(h=+h.substring(1)),(c||"0"===r&&"="===o)&&(c=r="0",o="="),p){case"n":s=!0,p="g";break;case"%":g=100,d="%",p="f";break;case"p":g=100,d="%",p="r";break;case"b":case"o":case"x":case"X":"#"===l&&(v="0"+p.toLowerCase());case"c":m=!1;case"d":y=!0,h=0;break;case"s":g=-1,p="r"}"$"===l&&(v=i[0],d=i[1]),"r"!=p||h||(p="g"),null!=h&&("g"==p?h=Math.max(1,Math.min(21,h)):"e"!=p&&"f"!=p||(h=Math.max(0,Math.min(20,h)))),p=pa.get(p)||Fn;var M=c&&s;return function(n){var e=d;if(y&&n%1)return"";var i=0>n||0===n&&0>1/n?(n=-n,"-"):"-"===a?"":a;if(0>g){var l=ao.formatPrefix(n,h);n=l.scale(n),e=l.symbol+d}else n*=g;n=p(n,h);var x,b,_=n.lastIndexOf(".");if(0>_){var w=m?n.lastIndexOf("e"):-1;0>w?(x=n,b=""):(x=n.substring(0,w),b=n.substring(w))}else x=n.substring(0,_),b=t+n.substring(_+1);!c&&s&&(x=u(x,1/0));var S=v.length+x.length+b.length+(M?0:i.length),k=f>S?new Array(S=f-S+1).join(r):"";return M&&(x=u(k+x,k.length?f-b.length:1/0)),i+=v,n=x+b,("<"===o?i+n+k:">"===o?k+i+n:"^"===o?k.substring(0,S>>=1)+i+n+k.substring(S):i+(M?n:k+n))+e}}}function Fn(n){return n+""}function Hn(){this._=new Date(arguments.length>1?Date.UTC.apply(this,arguments):arguments[0])}function On(n,t,e){function r(t){var e=n(t),r=u(e,1);return r-t>t-e?e:r}function i(e){return t(e=n(new va(e-1)),1),e}function u(n,e){return t(n=new va(+n),e),n}function o(n,r,u){var o=i(n),a=[];if(u>1)for(;r>o;)e(o)%u||a.push(new Date(+o)),t(o,1);else for(;r>o;)a.push(new Date(+o)),t(o,1);return a}function a(n,t,e){try{va=Hn;var r=new Hn;return r._=n,o(r,t,e)}finally{va=Date}}n.floor=n,n.round=r,n.ceil=i,n.offset=u,n.range=o;var l=n.utc=In(n);return l.floor=l,l.round=In(r),l.ceil=In(i),l.offset=In(u),l.range=a,n}function In(n){return function(t,e){try{va=Hn;var r=new Hn;return r._=t,n(r,e)._}finally{va=Date}}}function Yn(n){function t(n){function t(t){for(var e,i,u,o=[],a=-1,l=0;++aa;){if(r>=c)return-1;if(i=t.charCodeAt(a++),37===i){if(o=t.charAt(a++),u=C[o in ya?t.charAt(a++):o],!u||(r=u(n,e,r))<0)return-1}else if(i!=e.charCodeAt(r++))return-1}return r}function r(n,t,e){_.lastIndex=0;var r=_.exec(t.slice(e));return r?(n.w=w.get(r[0].toLowerCase()),e+r[0].length):-1}function i(n,t,e){x.lastIndex=0;var r=x.exec(t.slice(e));return r?(n.w=b.get(r[0].toLowerCase()),e+r[0].length):-1}function u(n,t,e){N.lastIndex=0;var r=N.exec(t.slice(e));return r?(n.m=E.get(r[0].toLowerCase()),e+r[0].length):-1}function o(n,t,e){S.lastIndex=0;var r=S.exec(t.slice(e));return r?(n.m=k.get(r[0].toLowerCase()),e+r[0].length):-1}function a(n,t,r){return e(n,A.c.toString(),t,r)}function l(n,t,r){return e(n,A.x.toString(),t,r)}function c(n,t,r){return e(n,A.X.toString(),t,r)}function f(n,t,e){var r=M.get(t.slice(e,e+=2).toLowerCase());return null==r?-1:(n.p=r,e)}var s=n.dateTime,h=n.date,p=n.time,g=n.periods,v=n.days,d=n.shortDays,y=n.months,m=n.shortMonths;t.utc=function(n){function e(n){try{va=Hn;var t=new va;return t._=n,r(t)}finally{va=Date}}var r=t(n);return e.parse=function(n){try{va=Hn;var t=r.parse(n);return t&&t._}finally{va=Date}},e.toString=r.toString,e},t.multi=t.utc.multi=ct;var M=ao.map(),x=Vn(v),b=Xn(v),_=Vn(d),w=Xn(d),S=Vn(y),k=Xn(y),N=Vn(m),E=Xn(m);g.forEach(function(n,t){M.set(n.toLowerCase(),t)});var A={a:function(n){return d[n.getDay()]},A:function(n){return v[n.getDay()]},b:function(n){return m[n.getMonth()]},B:function(n){return y[n.getMonth()]},c:t(s),d:function(n,t){return Zn(n.getDate(),t,2)},e:function(n,t){return Zn(n.getDate(),t,2)},H:function(n,t){return Zn(n.getHours(),t,2)},I:function(n,t){return Zn(n.getHours()%12||12,t,2)},j:function(n,t){return Zn(1+ga.dayOfYear(n),t,3)},L:function(n,t){return Zn(n.getMilliseconds(),t,3)},m:function(n,t){return Zn(n.getMonth()+1,t,2)},M:function(n,t){return Zn(n.getMinutes(),t,2)},p:function(n){return g[+(n.getHours()>=12)]},S:function(n,t){return Zn(n.getSeconds(),t,2)},U:function(n,t){return Zn(ga.sundayOfYear(n),t,2)},w:function(n){return n.getDay()},W:function(n,t){return Zn(ga.mondayOfYear(n),t,2)},x:t(h),X:t(p),y:function(n,t){return Zn(n.getFullYear()%100,t,2)},Y:function(n,t){return Zn(n.getFullYear()%1e4,t,4)},Z:at,"%":function(){return"%"}},C={a:r,A:i,b:u,B:o,c:a,d:tt,e:tt,H:rt,I:rt,j:et,L:ot,m:nt,M:it,p:f,S:ut,U:Bn,w:$n,W:Wn,x:l,X:c,y:Gn,Y:Jn,Z:Kn,"%":lt};return t}function Zn(n,t,e){var r=0>n?"-":"",i=(r?-n:n)+"",u=i.length;return r+(e>u?new Array(e-u+1).join(t)+i:i)}function Vn(n){return new RegExp("^(?:"+n.map(ao.requote).join("|")+")","i")}function Xn(n){for(var t=new c,e=-1,r=n.length;++e68?1900:2e3)}function nt(n,t,e){ma.lastIndex=0;var r=ma.exec(t.slice(e,e+2));return r?(n.m=r[0]-1,e+r[0].length):-1}function tt(n,t,e){ma.lastIndex=0;var r=ma.exec(t.slice(e,e+2));return r?(n.d=+r[0],e+r[0].length):-1}function et(n,t,e){ma.lastIndex=0;var r=ma.exec(t.slice(e,e+3));return r?(n.j=+r[0],e+r[0].length):-1}function rt(n,t,e){ma.lastIndex=0;var r=ma.exec(t.slice(e,e+2));return r?(n.H=+r[0],e+r[0].length):-1}function it(n,t,e){ma.lastIndex=0;var r=ma.exec(t.slice(e,e+2));return r?(n.M=+r[0],e+r[0].length):-1}function ut(n,t,e){ma.lastIndex=0;var r=ma.exec(t.slice(e,e+2));return r?(n.S=+r[0],e+r[0].length):-1}function ot(n,t,e){ma.lastIndex=0;var r=ma.exec(t.slice(e,e+3));return r?(n.L=+r[0],e+r[0].length):-1}function at(n){var t=n.getTimezoneOffset(),e=t>0?"-":"+",r=xo(t)/60|0,i=xo(t)%60;return e+Zn(r,"0",2)+Zn(i,"0",2)}function lt(n,t,e){Ma.lastIndex=0;var r=Ma.exec(t.slice(e,e+1));return r?e+r[0].length:-1}function ct(n){for(var t=n.length,e=-1;++e=0?1:-1,a=o*e,l=Math.cos(t),c=Math.sin(t),f=u*c,s=i*l+f*Math.cos(a),h=f*o*Math.sin(a);ka.add(Math.atan2(h,s)),r=n,i=l,u=c}var t,e,r,i,u;Na.point=function(o,a){Na.point=n,r=(t=o)*Yo,i=Math.cos(a=(e=a)*Yo/2+Fo/4),u=Math.sin(a)},Na.lineEnd=function(){n(t,e)}}function dt(n){var t=n[0],e=n[1],r=Math.cos(e);return[r*Math.cos(t),r*Math.sin(t),Math.sin(e)]}function yt(n,t){return n[0]*t[0]+n[1]*t[1]+n[2]*t[2]}function mt(n,t){return[n[1]*t[2]-n[2]*t[1],n[2]*t[0]-n[0]*t[2],n[0]*t[1]-n[1]*t[0]]}function Mt(n,t){n[0]+=t[0],n[1]+=t[1],n[2]+=t[2]}function xt(n,t){return[n[0]*t,n[1]*t,n[2]*t]}function bt(n){var t=Math.sqrt(n[0]*n[0]+n[1]*n[1]+n[2]*n[2]);n[0]/=t,n[1]/=t,n[2]/=t}function _t(n){return[Math.atan2(n[1],n[0]),tn(n[2])]}function wt(n,t){return xo(n[0]-t[0])a;++a)i.point((e=n[a])[0],e[1]);return void i.lineEnd()}var l=new Tt(e,n,null,!0),c=new Tt(e,null,l,!1);l.o=c,u.push(l),o.push(c),l=new Tt(r,n,null,!1),c=new Tt(r,null,l,!0),l.o=c,u.push(l),o.push(c)}}),o.sort(t),qt(u),qt(o),u.length){for(var a=0,l=e,c=o.length;c>a;++a)o[a].e=l=!l;for(var f,s,h=u[0];;){for(var p=h,g=!0;p.v;)if((p=p.n)===h)return;f=p.z,i.lineStart();do{if(p.v=p.o.v=!0,p.e){if(g)for(var a=0,c=f.length;c>a;++a)i.point((s=f[a])[0],s[1]);else r(p.x,p.n.x,1,i);p=p.n}else{if(g){f=p.p.z;for(var a=f.length-1;a>=0;--a)i.point((s=f[a])[0],s[1])}else r(p.x,p.p.x,-1,i);p=p.p}p=p.o,f=p.z,g=!g}while(!p.v);i.lineEnd()}}}function qt(n){if(t=n.length){for(var t,e,r=0,i=n[0];++r0){for(b||(u.polygonStart(),b=!0),u.lineStart();++o1&&2&t&&e.push(e.pop().concat(e.shift())),p.push(e.filter(Dt))}var p,g,v,d=t(u),y=i.invert(r[0],r[1]),m={point:o,lineStart:l,lineEnd:c,polygonStart:function(){m.point=f,m.lineStart=s,m.lineEnd=h,p=[],g=[]},polygonEnd:function(){m.point=o,m.lineStart=l,m.lineEnd=c,p=ao.merge(p);var n=Ot(y,g);p.length?(b||(u.polygonStart(),b=!0),Lt(p,Ut,n,e,u)):n&&(b||(u.polygonStart(),b=!0),u.lineStart(),e(null,null,1,u),u.lineEnd()),b&&(u.polygonEnd(),b=!1),p=g=null},sphere:function(){u.polygonStart(),u.lineStart(),e(null,null,1,u),u.lineEnd(),u.polygonEnd()}},M=Pt(),x=t(M),b=!1;return m}}function Dt(n){return n.length>1}function Pt(){var n,t=[];return{lineStart:function(){t.push(n=[])},point:function(t,e){n.push([t,e])},lineEnd:b,buffer:function(){var e=t;return t=[],n=null,e},rejoin:function(){t.length>1&&t.push(t.pop().concat(t.shift()))}}}function Ut(n,t){return((n=n.x)[0]<0?n[1]-Io-Uo:Io-n[1])-((t=t.x)[0]<0?t[1]-Io-Uo:Io-t[1])}function jt(n){var t,e=NaN,r=NaN,i=NaN;return{lineStart:function(){n.lineStart(),t=1},point:function(u,o){var a=u>0?Fo:-Fo,l=xo(u-e);xo(l-Fo)0?Io:-Io),n.point(i,r),n.lineEnd(),n.lineStart(),n.point(a,r),n.point(u,r),t=0):i!==a&&l>=Fo&&(xo(e-i)Uo?Math.atan((Math.sin(t)*(u=Math.cos(r))*Math.sin(e)-Math.sin(r)*(i=Math.cos(t))*Math.sin(n))/(i*u*o)):(t+r)/2}function Ht(n,t,e,r){var i;if(null==n)i=e*Io,r.point(-Fo,i),r.point(0,i),r.point(Fo,i),r.point(Fo,0),r.point(Fo,-i),r.point(0,-i),r.point(-Fo,-i),r.point(-Fo,0),r.point(-Fo,i);else if(xo(n[0]-t[0])>Uo){var u=n[0]a;++a){var c=t[a],f=c.length;if(f)for(var s=c[0],h=s[0],p=s[1]/2+Fo/4,g=Math.sin(p),v=Math.cos(p),d=1;;){d===f&&(d=0),n=c[d];var y=n[0],m=n[1]/2+Fo/4,M=Math.sin(m),x=Math.cos(m),b=y-h,_=b>=0?1:-1,w=_*b,S=w>Fo,k=g*M;if(ka.add(Math.atan2(k*_*Math.sin(w),v*x+k*Math.cos(w))),u+=S?b+_*Ho:b,S^h>=e^y>=e){var N=mt(dt(s),dt(n));bt(N);var E=mt(i,N);bt(E);var A=(S^b>=0?-1:1)*tn(E[2]);(r>A||r===A&&(N[0]||N[1]))&&(o+=S^b>=0?1:-1)}if(!d++)break;h=y,g=M,v=x,s=n}}return(-Uo>u||Uo>u&&-Uo>ka)^1&o}function It(n){function t(n,t){return Math.cos(n)*Math.cos(t)>u}function e(n){var e,u,l,c,f;return{lineStart:function(){c=l=!1,f=1},point:function(s,h){var p,g=[s,h],v=t(s,h),d=o?v?0:i(s,h):v?i(s+(0>s?Fo:-Fo),h):0;if(!e&&(c=l=v)&&n.lineStart(),v!==l&&(p=r(e,g),(wt(e,p)||wt(g,p))&&(g[0]+=Uo,g[1]+=Uo,v=t(g[0],g[1]))),v!==l)f=0,v?(n.lineStart(),p=r(g,e),n.point(p[0],p[1])):(p=r(e,g),n.point(p[0],p[1]),n.lineEnd()),e=p;else if(a&&e&&o^v){var y;d&u||!(y=r(g,e,!0))||(f=0,o?(n.lineStart(),n.point(y[0][0],y[0][1]),n.point(y[1][0],y[1][1]),n.lineEnd()):(n.point(y[1][0],y[1][1]),n.lineEnd(),n.lineStart(),n.point(y[0][0],y[0][1])))}!v||e&&wt(e,g)||n.point(g[0],g[1]),e=g,l=v,u=d},lineEnd:function(){l&&n.lineEnd(),e=null},clean:function(){return f|(c&&l)<<1}}}function r(n,t,e){var r=dt(n),i=dt(t),o=[1,0,0],a=mt(r,i),l=yt(a,a),c=a[0],f=l-c*c;if(!f)return!e&&n;var s=u*l/f,h=-u*c/f,p=mt(o,a),g=xt(o,s),v=xt(a,h);Mt(g,v);var d=p,y=yt(g,d),m=yt(d,d),M=y*y-m*(yt(g,g)-1);if(!(0>M)){var x=Math.sqrt(M),b=xt(d,(-y-x)/m);if(Mt(b,g),b=_t(b),!e)return b;var _,w=n[0],S=t[0],k=n[1],N=t[1];w>S&&(_=w,w=S,S=_);var E=S-w,A=xo(E-Fo)E;if(!A&&k>N&&(_=k,k=N,N=_),C?A?k+N>0^b[1]<(xo(b[0]-w)Fo^(w<=b[0]&&b[0]<=S)){var z=xt(d,(-y+x)/m);return Mt(z,g),[b,_t(z)]}}}function i(t,e){var r=o?n:Fo-n,i=0;return-r>t?i|=1:t>r&&(i|=2),-r>e?i|=4:e>r&&(i|=8),i}var u=Math.cos(n),o=u>0,a=xo(u)>Uo,l=ve(n,6*Yo);return Rt(t,e,l,o?[0,-n]:[-Fo,n-Fo])}function Yt(n,t,e,r){return function(i){var u,o=i.a,a=i.b,l=o.x,c=o.y,f=a.x,s=a.y,h=0,p=1,g=f-l,v=s-c;if(u=n-l,g||!(u>0)){if(u/=g,0>g){if(h>u)return;p>u&&(p=u)}else if(g>0){if(u>p)return;u>h&&(h=u)}if(u=e-l,g||!(0>u)){if(u/=g,0>g){if(u>p)return;u>h&&(h=u)}else if(g>0){if(h>u)return;p>u&&(p=u)}if(u=t-c,v||!(u>0)){if(u/=v,0>v){if(h>u)return;p>u&&(p=u)}else if(v>0){if(u>p)return;u>h&&(h=u)}if(u=r-c,v||!(0>u)){if(u/=v,0>v){if(u>p)return;u>h&&(h=u)}else if(v>0){if(h>u)return;p>u&&(p=u)}return h>0&&(i.a={x:l+h*g,y:c+h*v}),1>p&&(i.b={x:l+p*g,y:c+p*v}),i}}}}}}function Zt(n,t,e,r){function i(r,i){return xo(r[0]-n)0?0:3:xo(r[0]-e)0?2:1:xo(r[1]-t)0?1:0:i>0?3:2}function u(n,t){return o(n.x,t.x)}function o(n,t){var e=i(n,1),r=i(t,1);return e!==r?e-r:0===e?t[1]-n[1]:1===e?n[0]-t[0]:2===e?n[1]-t[1]:t[0]-n[0]}return function(a){function l(n){for(var t=0,e=d.length,r=n[1],i=0;e>i;++i)for(var u,o=1,a=d[i],l=a.length,c=a[0];l>o;++o)u=a[o],c[1]<=r?u[1]>r&&Q(c,u,n)>0&&++t:u[1]<=r&&Q(c,u,n)<0&&--t,c=u;return 0!==t}function c(u,a,l,c){var f=0,s=0;if(null==u||(f=i(u,l))!==(s=i(a,l))||o(u,a)<0^l>0){do c.point(0===f||3===f?n:e,f>1?r:t);while((f=(f+l+4)%4)!==s)}else c.point(a[0],a[1])}function f(i,u){return i>=n&&e>=i&&u>=t&&r>=u}function s(n,t){f(n,t)&&a.point(n,t)}function h(){C.point=g,d&&d.push(y=[]),S=!0,w=!1,b=_=NaN}function p(){v&&(g(m,M),x&&w&&E.rejoin(),v.push(E.buffer())),C.point=s,w&&a.lineEnd()}function g(n,t){n=Math.max(-Ha,Math.min(Ha,n)),t=Math.max(-Ha,Math.min(Ha,t));var e=f(n,t);if(d&&y.push([n,t]),S)m=n,M=t,x=e,S=!1,e&&(a.lineStart(),a.point(n,t));else if(e&&w)a.point(n,t);else{var r={a:{x:b,y:_},b:{x:n,y:t}};A(r)?(w||(a.lineStart(),a.point(r.a.x,r.a.y)),a.point(r.b.x,r.b.y),e||a.lineEnd(),k=!1):e&&(a.lineStart(),a.point(n,t),k=!1)}b=n,_=t,w=e}var v,d,y,m,M,x,b,_,w,S,k,N=a,E=Pt(),A=Yt(n,t,e,r),C={point:s,lineStart:h,lineEnd:p,polygonStart:function(){a=E,v=[],d=[],k=!0},polygonEnd:function(){a=N,v=ao.merge(v);var t=l([n,r]),e=k&&t,i=v.length;(e||i)&&(a.polygonStart(),e&&(a.lineStart(),c(null,null,1,a),a.lineEnd()),i&&Lt(v,u,t,c,a),a.polygonEnd()),v=d=y=null}};return C}}function Vt(n){var t=0,e=Fo/3,r=ae(n),i=r(t,e);return i.parallels=function(n){return arguments.length?r(t=n[0]*Fo/180,e=n[1]*Fo/180):[t/Fo*180,e/Fo*180]},i}function Xt(n,t){function e(n,t){var e=Math.sqrt(u-2*i*Math.sin(t))/i;return[e*Math.sin(n*=i),o-e*Math.cos(n)]}var r=Math.sin(n),i=(r+Math.sin(t))/2,u=1+r*(2*i-r),o=Math.sqrt(u)/i;return e.invert=function(n,t){var e=o-t;return[Math.atan2(n,e)/i,tn((u-(n*n+e*e)*i*i)/(2*i))]},e}function $t(){function n(n,t){Ia+=i*n-r*t,r=n,i=t}var t,e,r,i;$a.point=function(u,o){$a.point=n,t=r=u,e=i=o},$a.lineEnd=function(){n(t,e)}}function Bt(n,t){Ya>n&&(Ya=n),n>Va&&(Va=n),Za>t&&(Za=t),t>Xa&&(Xa=t)}function Wt(){function n(n,t){o.push("M",n,",",t,u)}function t(n,t){o.push("M",n,",",t),a.point=e}function e(n,t){o.push("L",n,",",t)}function r(){a.point=n}function i(){o.push("Z")}var u=Jt(4.5),o=[],a={point:n,lineStart:function(){a.point=t},lineEnd:r,polygonStart:function(){a.lineEnd=i},polygonEnd:function(){a.lineEnd=r,a.point=n},pointRadius:function(n){return u=Jt(n),a},result:function(){if(o.length){var n=o.join("");return o=[],n}}};return a}function Jt(n){return"m0,"+n+"a"+n+","+n+" 0 1,1 0,"+-2*n+"a"+n+","+n+" 0 1,1 0,"+2*n+"z"}function Gt(n,t){Ca+=n,za+=t,++La}function Kt(){function n(n,r){var i=n-t,u=r-e,o=Math.sqrt(i*i+u*u);qa+=o*(t+n)/2,Ta+=o*(e+r)/2,Ra+=o,Gt(t=n,e=r)}var t,e;Wa.point=function(r,i){Wa.point=n,Gt(t=r,e=i)}}function Qt(){Wa.point=Gt}function ne(){function n(n,t){var e=n-r,u=t-i,o=Math.sqrt(e*e+u*u);qa+=o*(r+n)/2,Ta+=o*(i+t)/2,Ra+=o,o=i*n-r*t,Da+=o*(r+n),Pa+=o*(i+t),Ua+=3*o,Gt(r=n,i=t)}var t,e,r,i;Wa.point=function(u,o){Wa.point=n,Gt(t=r=u,e=i=o)},Wa.lineEnd=function(){n(t,e)}}function te(n){function t(t,e){n.moveTo(t+o,e),n.arc(t,e,o,0,Ho)}function e(t,e){n.moveTo(t,e),a.point=r}function r(t,e){n.lineTo(t,e)}function i(){a.point=t}function u(){n.closePath()}var o=4.5,a={point:t,lineStart:function(){a.point=e},lineEnd:i,polygonStart:function(){a.lineEnd=u},polygonEnd:function(){a.lineEnd=i,a.point=t},pointRadius:function(n){return o=n,a},result:b};return a}function ee(n){function t(n){return(a?r:e)(n)}function e(t){return ue(t,function(e,r){e=n(e,r),t.point(e[0],e[1])})}function r(t){function e(e,r){e=n(e,r),t.point(e[0],e[1])}function r(){M=NaN,S.point=u,t.lineStart()}function u(e,r){var u=dt([e,r]),o=n(e,r);i(M,x,m,b,_,w,M=o[0],x=o[1],m=e,b=u[0],_=u[1],w=u[2],a,t),t.point(M,x)}function o(){S.point=e,t.lineEnd()}function l(){ -r(),S.point=c,S.lineEnd=f}function c(n,t){u(s=n,h=t),p=M,g=x,v=b,d=_,y=w,S.point=u}function f(){i(M,x,m,b,_,w,p,g,s,v,d,y,a,t),S.lineEnd=o,o()}var s,h,p,g,v,d,y,m,M,x,b,_,w,S={point:e,lineStart:r,lineEnd:o,polygonStart:function(){t.polygonStart(),S.lineStart=l},polygonEnd:function(){t.polygonEnd(),S.lineStart=r}};return S}function i(t,e,r,a,l,c,f,s,h,p,g,v,d,y){var m=f-t,M=s-e,x=m*m+M*M;if(x>4*u&&d--){var b=a+p,_=l+g,w=c+v,S=Math.sqrt(b*b+_*_+w*w),k=Math.asin(w/=S),N=xo(xo(w)-1)u||xo((m*z+M*L)/x-.5)>.3||o>a*p+l*g+c*v)&&(i(t,e,r,a,l,c,A,C,N,b/=S,_/=S,w,d,y),y.point(A,C),i(A,C,N,b,_,w,f,s,h,p,g,v,d,y))}}var u=.5,o=Math.cos(30*Yo),a=16;return t.precision=function(n){return arguments.length?(a=(u=n*n)>0&&16,t):Math.sqrt(u)},t}function re(n){var t=ee(function(t,e){return n([t*Zo,e*Zo])});return function(n){return le(t(n))}}function ie(n){this.stream=n}function ue(n,t){return{point:t,sphere:function(){n.sphere()},lineStart:function(){n.lineStart()},lineEnd:function(){n.lineEnd()},polygonStart:function(){n.polygonStart()},polygonEnd:function(){n.polygonEnd()}}}function oe(n){return ae(function(){return n})()}function ae(n){function t(n){return n=a(n[0]*Yo,n[1]*Yo),[n[0]*h+l,c-n[1]*h]}function e(n){return n=a.invert((n[0]-l)/h,(c-n[1])/h),n&&[n[0]*Zo,n[1]*Zo]}function r(){a=Ct(o=se(y,M,x),u);var n=u(v,d);return l=p-n[0]*h,c=g+n[1]*h,i()}function i(){return f&&(f.valid=!1,f=null),t}var u,o,a,l,c,f,s=ee(function(n,t){return n=u(n,t),[n[0]*h+l,c-n[1]*h]}),h=150,p=480,g=250,v=0,d=0,y=0,M=0,x=0,b=Fa,_=m,w=null,S=null;return t.stream=function(n){return f&&(f.valid=!1),f=le(b(o,s(_(n)))),f.valid=!0,f},t.clipAngle=function(n){return arguments.length?(b=null==n?(w=n,Fa):It((w=+n)*Yo),i()):w},t.clipExtent=function(n){return arguments.length?(S=n,_=n?Zt(n[0][0],n[0][1],n[1][0],n[1][1]):m,i()):S},t.scale=function(n){return arguments.length?(h=+n,r()):h},t.translate=function(n){return arguments.length?(p=+n[0],g=+n[1],r()):[p,g]},t.center=function(n){return arguments.length?(v=n[0]%360*Yo,d=n[1]%360*Yo,r()):[v*Zo,d*Zo]},t.rotate=function(n){return arguments.length?(y=n[0]%360*Yo,M=n[1]%360*Yo,x=n.length>2?n[2]%360*Yo:0,r()):[y*Zo,M*Zo,x*Zo]},ao.rebind(t,s,"precision"),function(){return u=n.apply(this,arguments),t.invert=u.invert&&e,r()}}function le(n){return ue(n,function(t,e){n.point(t*Yo,e*Yo)})}function ce(n,t){return[n,t]}function fe(n,t){return[n>Fo?n-Ho:-Fo>n?n+Ho:n,t]}function se(n,t,e){return n?t||e?Ct(pe(n),ge(t,e)):pe(n):t||e?ge(t,e):fe}function he(n){return function(t,e){return t+=n,[t>Fo?t-Ho:-Fo>t?t+Ho:t,e]}}function pe(n){var t=he(n);return t.invert=he(-n),t}function ge(n,t){function e(n,t){var e=Math.cos(t),a=Math.cos(n)*e,l=Math.sin(n)*e,c=Math.sin(t),f=c*r+a*i;return[Math.atan2(l*u-f*o,a*r-c*i),tn(f*u+l*o)]}var r=Math.cos(n),i=Math.sin(n),u=Math.cos(t),o=Math.sin(t);return e.invert=function(n,t){var e=Math.cos(t),a=Math.cos(n)*e,l=Math.sin(n)*e,c=Math.sin(t),f=c*u-l*o;return[Math.atan2(l*u+c*o,a*r+f*i),tn(f*r-a*i)]},e}function ve(n,t){var e=Math.cos(n),r=Math.sin(n);return function(i,u,o,a){var l=o*t;null!=i?(i=de(e,i),u=de(e,u),(o>0?u>i:i>u)&&(i+=o*Ho)):(i=n+o*Ho,u=n-.5*l);for(var c,f=i;o>0?f>u:u>f;f-=l)a.point((c=_t([e,-r*Math.cos(f),-r*Math.sin(f)]))[0],c[1])}}function de(n,t){var e=dt(t);e[0]-=n,bt(e);var r=nn(-e[1]);return((-e[2]<0?-r:r)+2*Math.PI-Uo)%(2*Math.PI)}function ye(n,t,e){var r=ao.range(n,t-Uo,e).concat(t);return function(n){return r.map(function(t){return[n,t]})}}function me(n,t,e){var r=ao.range(n,t-Uo,e).concat(t);return function(n){return r.map(function(t){return[t,n]})}}function Me(n){return n.source}function xe(n){return n.target}function be(n,t,e,r){var i=Math.cos(t),u=Math.sin(t),o=Math.cos(r),a=Math.sin(r),l=i*Math.cos(n),c=i*Math.sin(n),f=o*Math.cos(e),s=o*Math.sin(e),h=2*Math.asin(Math.sqrt(on(r-t)+i*o*on(e-n))),p=1/Math.sin(h),g=h?function(n){var t=Math.sin(n*=h)*p,e=Math.sin(h-n)*p,r=e*l+t*f,i=e*c+t*s,o=e*u+t*a;return[Math.atan2(i,r)*Zo,Math.atan2(o,Math.sqrt(r*r+i*i))*Zo]}:function(){return[n*Zo,t*Zo]};return g.distance=h,g}function _e(){function n(n,i){var u=Math.sin(i*=Yo),o=Math.cos(i),a=xo((n*=Yo)-t),l=Math.cos(a);Ja+=Math.atan2(Math.sqrt((a=o*Math.sin(a))*a+(a=r*u-e*o*l)*a),e*u+r*o*l),t=n,e=u,r=o}var t,e,r;Ga.point=function(i,u){t=i*Yo,e=Math.sin(u*=Yo),r=Math.cos(u),Ga.point=n},Ga.lineEnd=function(){Ga.point=Ga.lineEnd=b}}function we(n,t){function e(t,e){var r=Math.cos(t),i=Math.cos(e),u=n(r*i);return[u*i*Math.sin(t),u*Math.sin(e)]}return e.invert=function(n,e){var r=Math.sqrt(n*n+e*e),i=t(r),u=Math.sin(i),o=Math.cos(i);return[Math.atan2(n*u,r*o),Math.asin(r&&e*u/r)]},e}function Se(n,t){function e(n,t){o>0?-Io+Uo>t&&(t=-Io+Uo):t>Io-Uo&&(t=Io-Uo);var e=o/Math.pow(i(t),u);return[e*Math.sin(u*n),o-e*Math.cos(u*n)]}var r=Math.cos(n),i=function(n){return Math.tan(Fo/4+n/2)},u=n===t?Math.sin(n):Math.log(r/Math.cos(t))/Math.log(i(t)/i(n)),o=r*Math.pow(i(n),u)/u;return u?(e.invert=function(n,t){var e=o-t,r=K(u)*Math.sqrt(n*n+e*e);return[Math.atan2(n,e)/u,2*Math.atan(Math.pow(o/r,1/u))-Io]},e):Ne}function ke(n,t){function e(n,t){var e=u-t;return[e*Math.sin(i*n),u-e*Math.cos(i*n)]}var r=Math.cos(n),i=n===t?Math.sin(n):(r-Math.cos(t))/(t-n),u=r/i+n;return xo(i)i;i++){for(;r>1&&Q(n[e[r-2]],n[e[r-1]],n[i])<=0;)--r;e[r++]=i}return e.slice(0,r)}function qe(n,t){return n[0]-t[0]||n[1]-t[1]}function Te(n,t,e){return(e[0]-t[0])*(n[1]-t[1])<(e[1]-t[1])*(n[0]-t[0])}function Re(n,t,e,r){var i=n[0],u=e[0],o=t[0]-i,a=r[0]-u,l=n[1],c=e[1],f=t[1]-l,s=r[1]-c,h=(a*(l-c)-s*(i-u))/(s*o-a*f);return[i+h*o,l+h*f]}function De(n){var t=n[0],e=n[n.length-1];return!(t[0]-e[0]||t[1]-e[1])}function Pe(){rr(this),this.edge=this.site=this.circle=null}function Ue(n){var t=cl.pop()||new Pe;return t.site=n,t}function je(n){Be(n),ol.remove(n),cl.push(n),rr(n)}function Fe(n){var t=n.circle,e=t.x,r=t.cy,i={x:e,y:r},u=n.P,o=n.N,a=[n];je(n);for(var l=u;l.circle&&xo(e-l.circle.x)f;++f)c=a[f],l=a[f-1],nr(c.edge,l.site,c.site,i);l=a[0],c=a[s-1],c.edge=Ke(l.site,c.site,null,i),$e(l),$e(c)}function He(n){for(var t,e,r,i,u=n.x,o=n.y,a=ol._;a;)if(r=Oe(a,o)-u,r>Uo)a=a.L;else{if(i=u-Ie(a,o),!(i>Uo)){r>-Uo?(t=a.P,e=a):i>-Uo?(t=a,e=a.N):t=e=a;break}if(!a.R){t=a;break}a=a.R}var l=Ue(n);if(ol.insert(t,l),t||e){if(t===e)return Be(t),e=Ue(t.site),ol.insert(l,e),l.edge=e.edge=Ke(t.site,l.site),$e(t),void $e(e);if(!e)return void(l.edge=Ke(t.site,l.site));Be(t),Be(e);var c=t.site,f=c.x,s=c.y,h=n.x-f,p=n.y-s,g=e.site,v=g.x-f,d=g.y-s,y=2*(h*d-p*v),m=h*h+p*p,M=v*v+d*d,x={x:(d*m-p*M)/y+f,y:(h*M-v*m)/y+s};nr(e.edge,c,g,x),l.edge=Ke(c,n,null,x),e.edge=Ke(n,g,null,x),$e(t),$e(e)}}function Oe(n,t){var e=n.site,r=e.x,i=e.y,u=i-t;if(!u)return r;var o=n.P;if(!o)return-(1/0);e=o.site;var a=e.x,l=e.y,c=l-t;if(!c)return a;var f=a-r,s=1/u-1/c,h=f/c;return s?(-h+Math.sqrt(h*h-2*s*(f*f/(-2*c)-l+c/2+i-u/2)))/s+r:(r+a)/2}function Ie(n,t){var e=n.N;if(e)return Oe(e,t);var r=n.site;return r.y===t?r.x:1/0}function Ye(n){this.site=n,this.edges=[]}function Ze(n){for(var t,e,r,i,u,o,a,l,c,f,s=n[0][0],h=n[1][0],p=n[0][1],g=n[1][1],v=ul,d=v.length;d--;)if(u=v[d],u&&u.prepare())for(a=u.edges,l=a.length,o=0;l>o;)f=a[o].end(),r=f.x,i=f.y,c=a[++o%l].start(),t=c.x,e=c.y,(xo(r-t)>Uo||xo(i-e)>Uo)&&(a.splice(o,0,new tr(Qe(u.site,f,xo(r-s)Uo?{x:s,y:xo(t-s)Uo?{x:xo(e-g)Uo?{x:h,y:xo(t-h)Uo?{x:xo(e-p)=-jo)){var p=l*l+c*c,g=f*f+s*s,v=(s*p-c*g)/h,d=(l*g-f*p)/h,s=d+a,y=fl.pop()||new Xe;y.arc=n,y.site=i,y.x=v+o,y.y=s+Math.sqrt(v*v+d*d),y.cy=s,n.circle=y;for(var m=null,M=ll._;M;)if(y.yd||d>=a)return;if(h>g){if(u){if(u.y>=c)return}else u={x:d,y:l};e={x:d,y:c}}else{if(u){if(u.yr||r>1)if(h>g){if(u){if(u.y>=c)return}else u={x:(l-i)/r,y:l};e={x:(c-i)/r,y:c}}else{if(u){if(u.yp){if(u){if(u.x>=a)return}else u={x:o,y:r*o+i};e={x:a,y:r*a+i}}else{if(u){if(u.xu||s>o||r>h||i>p)){if(g=n.point){var g,v=t-n.x,d=e-n.y,y=v*v+d*d;if(l>y){var m=Math.sqrt(l=y);r=t-m,i=e-m,u=t+m,o=e+m,a=g}}for(var M=n.nodes,x=.5*(f+h),b=.5*(s+p),_=t>=x,w=e>=b,S=w<<1|_,k=S+4;k>S;++S)if(n=M[3&S])switch(3&S){case 0:c(n,f,s,x,b);break;case 1:c(n,x,s,h,b);break;case 2:c(n,f,b,x,p);break;case 3:c(n,x,b,h,p)}}}(n,r,i,u,o),a}function vr(n,t){n=ao.rgb(n),t=ao.rgb(t);var e=n.r,r=n.g,i=n.b,u=t.r-e,o=t.g-r,a=t.b-i;return function(n){return"#"+bn(Math.round(e+u*n))+bn(Math.round(r+o*n))+bn(Math.round(i+a*n))}}function dr(n,t){var e,r={},i={};for(e in n)e in t?r[e]=Mr(n[e],t[e]):i[e]=n[e];for(e in t)e in n||(i[e]=t[e]);return function(n){for(e in r)i[e]=r[e](n);return i}}function yr(n,t){return n=+n,t=+t,function(e){return n*(1-e)+t*e}}function mr(n,t){var e,r,i,u=hl.lastIndex=pl.lastIndex=0,o=-1,a=[],l=[];for(n+="",t+="";(e=hl.exec(n))&&(r=pl.exec(t));)(i=r.index)>u&&(i=t.slice(u,i),a[o]?a[o]+=i:a[++o]=i),(e=e[0])===(r=r[0])?a[o]?a[o]+=r:a[++o]=r:(a[++o]=null,l.push({i:o,x:yr(e,r)})),u=pl.lastIndex;return ur;++r)a[(e=l[r]).i]=e.x(n);return a.join("")})}function Mr(n,t){for(var e,r=ao.interpolators.length;--r>=0&&!(e=ao.interpolators[r](n,t)););return e}function xr(n,t){var e,r=[],i=[],u=n.length,o=t.length,a=Math.min(n.length,t.length);for(e=0;a>e;++e)r.push(Mr(n[e],t[e]));for(;u>e;++e)i[e]=n[e];for(;o>e;++e)i[e]=t[e];return function(n){for(e=0;a>e;++e)i[e]=r[e](n);return i}}function br(n){return function(t){return 0>=t?0:t>=1?1:n(t)}}function _r(n){return function(t){return 1-n(1-t)}}function wr(n){return function(t){return.5*(.5>t?n(2*t):2-n(2-2*t))}}function Sr(n){return n*n}function kr(n){return n*n*n}function Nr(n){if(0>=n)return 0;if(n>=1)return 1;var t=n*n,e=t*n;return 4*(.5>n?e:3*(n-t)+e-.75)}function Er(n){return function(t){return Math.pow(t,n)}}function Ar(n){return 1-Math.cos(n*Io)}function Cr(n){return Math.pow(2,10*(n-1))}function zr(n){return 1-Math.sqrt(1-n*n)}function Lr(n,t){var e;return arguments.length<2&&(t=.45),arguments.length?e=t/Ho*Math.asin(1/n):(n=1,e=t/4),function(r){return 1+n*Math.pow(2,-10*r)*Math.sin((r-e)*Ho/t)}}function qr(n){return n||(n=1.70158),function(t){return t*t*((n+1)*t-n)}}function Tr(n){return 1/2.75>n?7.5625*n*n:2/2.75>n?7.5625*(n-=1.5/2.75)*n+.75:2.5/2.75>n?7.5625*(n-=2.25/2.75)*n+.9375:7.5625*(n-=2.625/2.75)*n+.984375}function Rr(n,t){n=ao.hcl(n),t=ao.hcl(t);var e=n.h,r=n.c,i=n.l,u=t.h-e,o=t.c-r,a=t.l-i;return isNaN(o)&&(o=0,r=isNaN(r)?t.c:r),isNaN(u)?(u=0,e=isNaN(e)?t.h:e):u>180?u-=360:-180>u&&(u+=360),function(n){return sn(e+u*n,r+o*n,i+a*n)+""}}function Dr(n,t){n=ao.hsl(n),t=ao.hsl(t);var e=n.h,r=n.s,i=n.l,u=t.h-e,o=t.s-r,a=t.l-i;return isNaN(o)&&(o=0,r=isNaN(r)?t.s:r),isNaN(u)?(u=0,e=isNaN(e)?t.h:e):u>180?u-=360:-180>u&&(u+=360),function(n){return cn(e+u*n,r+o*n,i+a*n)+""}}function Pr(n,t){n=ao.lab(n),t=ao.lab(t);var e=n.l,r=n.a,i=n.b,u=t.l-e,o=t.a-r,a=t.b-i;return function(n){return pn(e+u*n,r+o*n,i+a*n)+""}}function Ur(n,t){return t-=n,function(e){return Math.round(n+t*e)}}function jr(n){var t=[n.a,n.b],e=[n.c,n.d],r=Hr(t),i=Fr(t,e),u=Hr(Or(e,t,-i))||0;t[0]*e[1]180?t+=360:t-n>180&&(n+=360),r.push({i:e.push(Ir(e)+"rotate(",null,")")-2,x:yr(n,t)})):t&&e.push(Ir(e)+"rotate("+t+")")}function Vr(n,t,e,r){n!==t?r.push({i:e.push(Ir(e)+"skewX(",null,")")-2,x:yr(n,t)}):t&&e.push(Ir(e)+"skewX("+t+")")}function Xr(n,t,e,r){if(n[0]!==t[0]||n[1]!==t[1]){var i=e.push(Ir(e)+"scale(",null,",",null,")");r.push({i:i-4,x:yr(n[0],t[0])},{i:i-2,x:yr(n[1],t[1])})}else 1===t[0]&&1===t[1]||e.push(Ir(e)+"scale("+t+")")}function $r(n,t){var e=[],r=[];return n=ao.transform(n),t=ao.transform(t),Yr(n.translate,t.translate,e,r),Zr(n.rotate,t.rotate,e,r),Vr(n.skew,t.skew,e,r),Xr(n.scale,t.scale,e,r),n=t=null,function(n){for(var t,i=-1,u=r.length;++i=0;)e.push(i[r])}function oi(n,t){for(var e=[n],r=[];null!=(n=e.pop());)if(r.push(n),(u=n.children)&&(i=u.length))for(var i,u,o=-1;++oe;++e)(t=n[e][1])>i&&(r=e,i=t);return r}function yi(n){return n.reduce(mi,0)}function mi(n,t){return n+t[1]}function Mi(n,t){return xi(n,Math.ceil(Math.log(t.length)/Math.LN2+1))}function xi(n,t){for(var e=-1,r=+n[0],i=(n[1]-r)/t,u=[];++e<=t;)u[e]=i*e+r;return u}function bi(n){return[ao.min(n),ao.max(n)]}function _i(n,t){return n.value-t.value}function wi(n,t){var e=n._pack_next;n._pack_next=t,t._pack_prev=n,t._pack_next=e,e._pack_prev=t}function Si(n,t){n._pack_next=t,t._pack_prev=n}function ki(n,t){var e=t.x-n.x,r=t.y-n.y,i=n.r+t.r;return.999*i*i>e*e+r*r}function Ni(n){function t(n){f=Math.min(n.x-n.r,f),s=Math.max(n.x+n.r,s),h=Math.min(n.y-n.r,h),p=Math.max(n.y+n.r,p)}if((e=n.children)&&(c=e.length)){var e,r,i,u,o,a,l,c,f=1/0,s=-(1/0),h=1/0,p=-(1/0);if(e.forEach(Ei),r=e[0],r.x=-r.r,r.y=0,t(r),c>1&&(i=e[1],i.x=i.r,i.y=0,t(i),c>2))for(u=e[2],zi(r,i,u),t(u),wi(r,u),r._pack_prev=u,wi(u,i),i=r._pack_next,o=3;c>o;o++){zi(r,i,u=e[o]);var g=0,v=1,d=1;for(a=i._pack_next;a!==i;a=a._pack_next,v++)if(ki(a,u)){g=1;break}if(1==g)for(l=r._pack_prev;l!==a._pack_prev&&!ki(l,u);l=l._pack_prev,d++);g?(d>v||v==d&&i.ro;o++)u=e[o],u.x-=y,u.y-=m,M=Math.max(M,u.r+Math.sqrt(u.x*u.x+u.y*u.y));n.r=M,e.forEach(Ai)}}function Ei(n){n._pack_next=n._pack_prev=n}function Ai(n){delete n._pack_next,delete n._pack_prev}function Ci(n,t,e,r){var i=n.children;if(n.x=t+=r*n.x,n.y=e+=r*n.y,n.r*=r,i)for(var u=-1,o=i.length;++u=0;)t=i[u],t.z+=e,t.m+=e,e+=t.s+(r+=t.c)}function Pi(n,t,e){return n.a.parent===t.parent?n.a:e}function Ui(n){return 1+ao.max(n,function(n){return n.y})}function ji(n){return n.reduce(function(n,t){return n+t.x},0)/n.length}function Fi(n){var t=n.children;return t&&t.length?Fi(t[0]):n}function Hi(n){var t,e=n.children;return e&&(t=e.length)?Hi(e[t-1]):n}function Oi(n){return{x:n.x,y:n.y,dx:n.dx,dy:n.dy}}function Ii(n,t){var e=n.x+t[3],r=n.y+t[0],i=n.dx-t[1]-t[3],u=n.dy-t[0]-t[2];return 0>i&&(e+=i/2,i=0),0>u&&(r+=u/2,u=0),{x:e,y:r,dx:i,dy:u}}function Yi(n){var t=n[0],e=n[n.length-1];return e>t?[t,e]:[e,t]}function Zi(n){return n.rangeExtent?n.rangeExtent():Yi(n.range())}function Vi(n,t,e,r){var i=e(n[0],n[1]),u=r(t[0],t[1]);return function(n){return u(i(n))}}function Xi(n,t){var e,r=0,i=n.length-1,u=n[r],o=n[i];return u>o&&(e=r,r=i,i=e,e=u,u=o,o=e),n[r]=t.floor(u),n[i]=t.ceil(o),n}function $i(n){return n?{floor:function(t){return Math.floor(t/n)*n},ceil:function(t){return Math.ceil(t/n)*n}}:Sl}function Bi(n,t,e,r){var i=[],u=[],o=0,a=Math.min(n.length,t.length)-1;for(n[a]2?Bi:Vi,l=r?Wr:Br;return o=i(n,t,l,e),a=i(t,n,l,Mr),u}function u(n){return o(n)}var o,a;return u.invert=function(n){return a(n)},u.domain=function(t){return arguments.length?(n=t.map(Number),i()):n},u.range=function(n){return arguments.length?(t=n,i()):t},u.rangeRound=function(n){return u.range(n).interpolate(Ur)},u.clamp=function(n){return arguments.length?(r=n,i()):r},u.interpolate=function(n){return arguments.length?(e=n,i()):e},u.ticks=function(t){return Qi(n,t)},u.tickFormat=function(t,e){return nu(n,t,e)},u.nice=function(t){return Gi(n,t),i()},u.copy=function(){return Wi(n,t,e,r)},i()}function Ji(n,t){return ao.rebind(n,t,"range","rangeRound","interpolate","clamp")}function Gi(n,t){return Xi(n,$i(Ki(n,t)[2])),Xi(n,$i(Ki(n,t)[2])),n}function Ki(n,t){null==t&&(t=10);var e=Yi(n),r=e[1]-e[0],i=Math.pow(10,Math.floor(Math.log(r/t)/Math.LN10)),u=t/r*i;return.15>=u?i*=10:.35>=u?i*=5:.75>=u&&(i*=2),e[0]=Math.ceil(e[0]/i)*i,e[1]=Math.floor(e[1]/i)*i+.5*i,e[2]=i,e}function Qi(n,t){return ao.range.apply(ao,Ki(n,t))}function nu(n,t,e){var r=Ki(n,t);if(e){var i=ha.exec(e);if(i.shift(),"s"===i[8]){var u=ao.formatPrefix(Math.max(xo(r[0]),xo(r[1])));return i[7]||(i[7]="."+tu(u.scale(r[2]))),i[8]="f",e=ao.format(i.join("")),function(n){return e(u.scale(n))+u.symbol}}i[7]||(i[7]="."+eu(i[8],r)),e=i.join("")}else e=",."+tu(r[2])+"f";return ao.format(e)}function tu(n){return-Math.floor(Math.log(n)/Math.LN10+.01)}function eu(n,t){var e=tu(t[2]);return n in kl?Math.abs(e-tu(Math.max(xo(t[0]),xo(t[1]))))+ +("e"!==n):e-2*("%"===n)}function ru(n,t,e,r){function i(n){return(e?Math.log(0>n?0:n):-Math.log(n>0?0:-n))/Math.log(t)}function u(n){return e?Math.pow(t,n):-Math.pow(t,-n)}function o(t){return n(i(t))}return o.invert=function(t){return u(n.invert(t))},o.domain=function(t){return arguments.length?(e=t[0]>=0,n.domain((r=t.map(Number)).map(i)),o):r},o.base=function(e){return arguments.length?(t=+e,n.domain(r.map(i)),o):t},o.nice=function(){var t=Xi(r.map(i),e?Math:El);return n.domain(t),r=t.map(u),o},o.ticks=function(){var n=Yi(r),o=[],a=n[0],l=n[1],c=Math.floor(i(a)),f=Math.ceil(i(l)),s=t%1?2:t;if(isFinite(f-c)){if(e){for(;f>c;c++)for(var h=1;s>h;h++)o.push(u(c)*h);o.push(u(c))}else for(o.push(u(c));c++0;h--)o.push(u(c)*h);for(c=0;o[c]l;f--);o=o.slice(c,f)}return o},o.tickFormat=function(n,e){if(!arguments.length)return Nl;arguments.length<2?e=Nl:"function"!=typeof e&&(e=ao.format(e));var r=Math.max(1,t*n/o.ticks().length);return function(n){var o=n/u(Math.round(i(n)));return t-.5>o*t&&(o*=t),r>=o?e(n):""}},o.copy=function(){return ru(n.copy(),t,e,r)},Ji(o,n)}function iu(n,t,e){function r(t){return n(i(t))}var i=uu(t),u=uu(1/t);return r.invert=function(t){return u(n.invert(t))},r.domain=function(t){return arguments.length?(n.domain((e=t.map(Number)).map(i)),r):e},r.ticks=function(n){return Qi(e,n)},r.tickFormat=function(n,t){return nu(e,n,t)},r.nice=function(n){return r.domain(Gi(e,n))},r.exponent=function(o){return arguments.length?(i=uu(t=o),u=uu(1/t),n.domain(e.map(i)),r):t},r.copy=function(){return iu(n.copy(),t,e)},Ji(r,n)}function uu(n){return function(t){return 0>t?-Math.pow(-t,n):Math.pow(t,n)}}function ou(n,t){function e(e){return u[((i.get(e)||("range"===t.t?i.set(e,n.push(e)):NaN))-1)%u.length]}function r(t,e){return ao.range(n.length).map(function(n){return t+e*n})}var i,u,o;return e.domain=function(r){if(!arguments.length)return n;n=[],i=new c;for(var u,o=-1,a=r.length;++oe?[NaN,NaN]:[e>0?a[e-1]:n[0],et?NaN:t/u+n,[t,t+1/u]},r.copy=function(){return lu(n,t,e)},i()}function cu(n,t){function e(e){return e>=e?t[ao.bisect(n,e)]:void 0}return e.domain=function(t){return arguments.length?(n=t,e):n},e.range=function(n){return arguments.length?(t=n,e):t},e.invertExtent=function(e){return e=t.indexOf(e),[n[e-1],n[e]]},e.copy=function(){return cu(n,t)},e}function fu(n){function t(n){return+n}return t.invert=t,t.domain=t.range=function(e){return arguments.length?(n=e.map(t),t):n},t.ticks=function(t){return Qi(n,t)},t.tickFormat=function(t,e){return nu(n,t,e)},t.copy=function(){return fu(n)},t}function su(){return 0}function hu(n){return n.innerRadius}function pu(n){return n.outerRadius}function gu(n){return n.startAngle}function vu(n){return n.endAngle}function du(n){return n&&n.padAngle}function yu(n,t,e,r){return(n-e)*t-(t-r)*n>0?0:1}function mu(n,t,e,r,i){var u=n[0]-t[0],o=n[1]-t[1],a=(i?r:-r)/Math.sqrt(u*u+o*o),l=a*o,c=-a*u,f=n[0]+l,s=n[1]+c,h=t[0]+l,p=t[1]+c,g=(f+h)/2,v=(s+p)/2,d=h-f,y=p-s,m=d*d+y*y,M=e-r,x=f*p-h*s,b=(0>y?-1:1)*Math.sqrt(Math.max(0,M*M*m-x*x)),_=(x*y-d*b)/m,w=(-x*d-y*b)/m,S=(x*y+d*b)/m,k=(-x*d+y*b)/m,N=_-g,E=w-v,A=S-g,C=k-v;return N*N+E*E>A*A+C*C&&(_=S,w=k),[[_-l,w-c],[_*e/M,w*e/M]]}function Mu(n){function t(t){function o(){c.push("M",u(n(f),a))}for(var l,c=[],f=[],s=-1,h=t.length,p=En(e),g=En(r);++s1?n.join("L"):n+"Z"}function bu(n){return n.join("L")+"Z"}function _u(n){for(var t=0,e=n.length,r=n[0],i=[r[0],",",r[1]];++t1&&i.push("H",r[0]),i.join("")}function wu(n){for(var t=0,e=n.length,r=n[0],i=[r[0],",",r[1]];++t1){a=t[1],u=n[l],l++,r+="C"+(i[0]+o[0])+","+(i[1]+o[1])+","+(u[0]-a[0])+","+(u[1]-a[1])+","+u[0]+","+u[1];for(var c=2;c9&&(i=3*t/Math.sqrt(i),o[a]=i*e,o[a+1]=i*r));for(a=-1;++a<=l;)i=(n[Math.min(l,a+1)][0]-n[Math.max(0,a-1)][0])/(6*(1+o[a]*o[a])),u.push([i||0,o[a]*i||0]);return u}function Fu(n){return n.length<3?xu(n):n[0]+Au(n,ju(n))}function Hu(n){for(var t,e,r,i=-1,u=n.length;++i=t?o(n-t):void(f.c=o)}function o(e){var i=g.active,u=g[i];u&&(u.timer.c=null,u.timer.t=NaN,--g.count,delete g[i],u.event&&u.event.interrupt.call(n,n.__data__,u.index));for(var o in g)if(r>+o){var c=g[o];c.timer.c=null,c.timer.t=NaN,--g.count,delete g[o]}f.c=a,qn(function(){return f.c&&a(e||1)&&(f.c=null,f.t=NaN),1},0,l),g.active=r,v.event&&v.event.start.call(n,n.__data__,t),p=[],v.tween.forEach(function(e,r){(r=r.call(n,n.__data__,t))&&p.push(r)}),h=v.ease,s=v.duration}function a(i){for(var u=i/s,o=h(u),a=p.length;a>0;)p[--a].call(n,o);return u>=1?(v.event&&v.event.end.call(n,n.__data__,t),--g.count?delete g[r]:delete n[e],1):void 0}var l,f,s,h,p,g=n[e]||(n[e]={active:0,count:0}),v=g[r];v||(l=i.time,f=qn(u,0,l),v=g[r]={tween:new c,time:l,timer:f,delay:i.delay,duration:i.duration,ease:i.ease,index:t},i=null,++g.count)}function no(n,t,e){n.attr("transform",function(n){var r=t(n);return"translate("+(isFinite(r)?r:e(n))+",0)"})}function to(n,t,e){n.attr("transform",function(n){var r=t(n);return"translate(0,"+(isFinite(r)?r:e(n))+")"})}function eo(n){return n.toISOString()}function ro(n,t,e){function r(t){return n(t)}function i(n,e){var r=n[1]-n[0],i=r/e,u=ao.bisect(Kl,i);return u==Kl.length?[t.year,Ki(n.map(function(n){return n/31536e6}),e)[2]]:u?t[i/Kl[u-1]1?{floor:function(t){for(;e(t=n.floor(t));)t=io(t-1);return t},ceil:function(t){for(;e(t=n.ceil(t));)t=io(+t+1);return t}}:n))},r.ticks=function(n,t){var e=Yi(r.domain()),u=null==n?i(e,10):"number"==typeof n?i(e,n):!n.range&&[{range:n},t];return u&&(n=u[0],t=u[1]),n.range(e[0],io(+e[1]+1),1>t?1:t)},r.tickFormat=function(){return e},r.copy=function(){return ro(n.copy(),t,e)},Ji(r,n)}function io(n){return new Date(n)}function uo(n){return JSON.parse(n.responseText)}function oo(n){var t=fo.createRange();return t.selectNode(fo.body),t.createContextualFragment(n.responseText)}var ao={version:"3.5.17"},lo=[].slice,co=function(n){return lo.call(n)},fo=this.document;if(fo)try{co(fo.documentElement.childNodes)[0].nodeType}catch(so){co=function(n){for(var t=n.length,e=new Array(t);t--;)e[t]=n[t];return e}}if(Date.now||(Date.now=function(){return+new Date}),fo)try{fo.createElement("DIV").style.setProperty("opacity",0,"")}catch(ho){var po=this.Element.prototype,go=po.setAttribute,vo=po.setAttributeNS,yo=this.CSSStyleDeclaration.prototype,mo=yo.setProperty;po.setAttribute=function(n,t){go.call(this,n,t+"")},po.setAttributeNS=function(n,t,e){vo.call(this,n,t,e+"")},yo.setProperty=function(n,t,e){mo.call(this,n,t+"",e)}}ao.ascending=e,ao.descending=function(n,t){return n>t?-1:t>n?1:t>=n?0:NaN},ao.min=function(n,t){var e,r,i=-1,u=n.length;if(1===arguments.length){for(;++i=r){e=r;break}for(;++ir&&(e=r)}else{for(;++i=r){e=r;break}for(;++ir&&(e=r)}return e},ao.max=function(n,t){var e,r,i=-1,u=n.length;if(1===arguments.length){for(;++i=r){e=r;break}for(;++ie&&(e=r)}else{for(;++i=r){e=r;break}for(;++ie&&(e=r)}return e},ao.extent=function(n,t){var e,r,i,u=-1,o=n.length;if(1===arguments.length){for(;++u=r){e=i=r;break}for(;++ur&&(e=r),r>i&&(i=r))}else{for(;++u=r){e=i=r;break}for(;++ur&&(e=r),r>i&&(i=r))}return[e,i]},ao.sum=function(n,t){var e,r=0,u=n.length,o=-1;if(1===arguments.length)for(;++o1?l/(f-1):void 0},ao.deviation=function(){var n=ao.variance.apply(this,arguments);return n?Math.sqrt(n):n};var Mo=u(e);ao.bisectLeft=Mo.left,ao.bisect=ao.bisectRight=Mo.right,ao.bisector=function(n){return u(1===n.length?function(t,r){return e(n(t),r)}:n)},ao.shuffle=function(n,t,e){(u=arguments.length)<3&&(e=n.length,2>u&&(t=0));for(var r,i,u=e-t;u;)i=Math.random()*u--|0,r=n[u+t],n[u+t]=n[i+t],n[i+t]=r;return n},ao.permute=function(n,t){for(var e=t.length,r=new Array(e);e--;)r[e]=n[t[e]];return r},ao.pairs=function(n){for(var t,e=0,r=n.length-1,i=n[0],u=new Array(0>r?0:r);r>e;)u[e]=[t=i,i=n[++e]];return u},ao.transpose=function(n){if(!(i=n.length))return[];for(var t=-1,e=ao.min(n,o),r=new Array(e);++t=0;)for(r=n[i],t=r.length;--t>=0;)e[--o]=r[t];return e};var xo=Math.abs;ao.range=function(n,t,e){if(arguments.length<3&&(e=1,arguments.length<2&&(t=n,n=0)),(t-n)/e===1/0)throw new Error("infinite range");var r,i=[],u=a(xo(e)),o=-1;if(n*=u,t*=u,e*=u,0>e)for(;(r=n+e*++o)>t;)i.push(r/u);else for(;(r=n+e*++o)=u.length)return r?r.call(i,o):e?o.sort(e):o;for(var l,f,s,h,p=-1,g=o.length,v=u[a++],d=new c;++p=u.length)return n;var r=[],i=o[e++];return n.forEach(function(n,i){r.push({key:n,values:t(i,e)})}),i?r.sort(function(n,t){return i(n.key,t.key)}):r}var e,r,i={},u=[],o=[];return i.map=function(t,e){return n(e,t,0)},i.entries=function(e){return t(n(ao.map,e,0),0)},i.key=function(n){return u.push(n),i},i.sortKeys=function(n){return o[u.length-1]=n,i},i.sortValues=function(n){return e=n,i},i.rollup=function(n){return r=n,i},i},ao.set=function(n){var t=new y;if(n)for(var e=0,r=n.length;r>e;++e)t.add(n[e]);return t},l(y,{has:h,add:function(n){return this._[f(n+="")]=!0,n},remove:p,values:g,size:v,empty:d,forEach:function(n){for(var t in this._)n.call(this,s(t))}}),ao.behavior={},ao.rebind=function(n,t){for(var e,r=1,i=arguments.length;++r=0&&(r=n.slice(e+1),n=n.slice(0,e)),n)return arguments.length<2?this[n].on(r):this[n].on(r,t);if(2===arguments.length){if(null==t)for(n in this)this.hasOwnProperty(n)&&this[n].on(r,null);return this}},ao.event=null,ao.requote=function(n){return n.replace(So,"\\$&")};var So=/[\\\^\$\*\+\?\|\[\]\(\)\.\{\}]/g,ko={}.__proto__?function(n,t){n.__proto__=t}:function(n,t){for(var e in t)n[e]=t[e]},No=function(n,t){return t.querySelector(n)},Eo=function(n,t){return t.querySelectorAll(n)},Ao=function(n,t){var e=n.matches||n[x(n,"matchesSelector")];return(Ao=function(n,t){return e.call(n,t)})(n,t)};"function"==typeof Sizzle&&(No=function(n,t){return Sizzle(n,t)[0]||null},Eo=Sizzle,Ao=Sizzle.matchesSelector),ao.selection=function(){return ao.select(fo.documentElement)};var Co=ao.selection.prototype=[];Co.select=function(n){var t,e,r,i,u=[];n=A(n);for(var o=-1,a=this.length;++o=0&&"xmlns"!==(e=n.slice(0,t))&&(n=n.slice(t+1)),Lo.hasOwnProperty(e)?{space:Lo[e],local:n}:n}},Co.attr=function(n,t){if(arguments.length<2){if("string"==typeof n){var e=this.node();return n=ao.ns.qualify(n),n.local?e.getAttributeNS(n.space,n.local):e.getAttribute(n)}for(t in n)this.each(z(t,n[t]));return this}return this.each(z(n,t))},Co.classed=function(n,t){if(arguments.length<2){if("string"==typeof n){var e=this.node(),r=(n=T(n)).length,i=-1;if(t=e.classList){for(;++ii){if("string"!=typeof n){2>i&&(e="");for(r in n)this.each(P(r,n[r],e));return this}if(2>i){var u=this.node();return t(u).getComputedStyle(u,null).getPropertyValue(n)}r=""}return this.each(P(n,e,r))},Co.property=function(n,t){if(arguments.length<2){if("string"==typeof n)return this.node()[n];for(t in n)this.each(U(t,n[t]));return this}return this.each(U(n,t))},Co.text=function(n){return arguments.length?this.each("function"==typeof n?function(){var t=n.apply(this,arguments);this.textContent=null==t?"":t}:null==n?function(){this.textContent=""}:function(){this.textContent=n}):this.node().textContent},Co.html=function(n){return arguments.length?this.each("function"==typeof n?function(){var t=n.apply(this,arguments);this.innerHTML=null==t?"":t}:null==n?function(){this.innerHTML=""}:function(){this.innerHTML=n}):this.node().innerHTML},Co.append=function(n){return n=j(n),this.select(function(){return this.appendChild(n.apply(this,arguments))})},Co.insert=function(n,t){return n=j(n),t=A(t),this.select(function(){return this.insertBefore(n.apply(this,arguments),t.apply(this,arguments)||null)})},Co.remove=function(){return this.each(F)},Co.data=function(n,t){function e(n,e){var r,i,u,o=n.length,s=e.length,h=Math.min(o,s),p=new Array(s),g=new Array(s),v=new Array(o);if(t){var d,y=new c,m=new Array(o);for(r=-1;++rr;++r)g[r]=H(e[r]);for(;o>r;++r)v[r]=n[r]}g.update=p,g.parentNode=p.parentNode=v.parentNode=n.parentNode,a.push(g),l.push(p),f.push(v)}var r,i,u=-1,o=this.length;if(!arguments.length){for(n=new Array(o=(r=this[0]).length);++uu;u++){i.push(t=[]),t.parentNode=(e=this[u]).parentNode;for(var a=0,l=e.length;l>a;a++)(r=e[a])&&n.call(r,r.__data__,a,u)&&t.push(r)}return E(i)},Co.order=function(){for(var n=-1,t=this.length;++n=0;)(e=r[i])&&(u&&u!==e.nextSibling&&u.parentNode.insertBefore(e,u),u=e);return this},Co.sort=function(n){n=I.apply(this,arguments);for(var t=-1,e=this.length;++tn;n++)for(var e=this[n],r=0,i=e.length;i>r;r++){var u=e[r];if(u)return u}return null},Co.size=function(){var n=0;return Y(this,function(){++n}),n};var qo=[];ao.selection.enter=Z,ao.selection.enter.prototype=qo,qo.append=Co.append,qo.empty=Co.empty,qo.node=Co.node,qo.call=Co.call,qo.size=Co.size,qo.select=function(n){for(var t,e,r,i,u,o=[],a=-1,l=this.length;++ar){if("string"!=typeof n){2>r&&(t=!1);for(e in n)this.each(X(e,n[e],t));return this}if(2>r)return(r=this.node()["__on"+n])&&r._;e=!1}return this.each(X(n,t,e))};var To=ao.map({mouseenter:"mouseover",mouseleave:"mouseout"});fo&&To.forEach(function(n){"on"+n in fo&&To.remove(n)});var Ro,Do=0;ao.mouse=function(n){return J(n,k())};var Po=this.navigator&&/WebKit/.test(this.navigator.userAgent)?-1:0;ao.touch=function(n,t,e){if(arguments.length<3&&(e=t,t=k().changedTouches),t)for(var r,i=0,u=t.length;u>i;++i)if((r=t[i]).identifier===e)return J(n,r)},ao.behavior.drag=function(){function n(){this.on("mousedown.drag",u).on("touchstart.drag",o)}function e(n,t,e,u,o){return function(){function a(){var n,e,r=t(h,v);r&&(n=r[0]-M[0],e=r[1]-M[1],g|=n|e,M=r,p({type:"drag",x:r[0]+c[0],y:r[1]+c[1],dx:n,dy:e}))}function l(){t(h,v)&&(y.on(u+d,null).on(o+d,null),m(g),p({type:"dragend"}))}var c,f=this,s=ao.event.target.correspondingElement||ao.event.target,h=f.parentNode,p=r.of(f,arguments),g=0,v=n(),d=".drag"+(null==v?"":"-"+v),y=ao.select(e(s)).on(u+d,a).on(o+d,l),m=W(s),M=t(h,v);i?(c=i.apply(f,arguments),c=[c.x-M[0],c.y-M[1]]):c=[0,0],p({type:"dragstart"})}}var r=N(n,"drag","dragstart","dragend"),i=null,u=e(b,ao.mouse,t,"mousemove","mouseup"),o=e(G,ao.touch,m,"touchmove","touchend");return n.origin=function(t){return arguments.length?(i=t,n):i},ao.rebind(n,r,"on")},ao.touches=function(n,t){return arguments.length<2&&(t=k().touches),t?co(t).map(function(t){var e=J(n,t);return e.identifier=t.identifier,e}):[]};var Uo=1e-6,jo=Uo*Uo,Fo=Math.PI,Ho=2*Fo,Oo=Ho-Uo,Io=Fo/2,Yo=Fo/180,Zo=180/Fo,Vo=Math.SQRT2,Xo=2,$o=4;ao.interpolateZoom=function(n,t){var e,r,i=n[0],u=n[1],o=n[2],a=t[0],l=t[1],c=t[2],f=a-i,s=l-u,h=f*f+s*s;if(jo>h)r=Math.log(c/o)/Vo,e=function(n){return[i+n*f,u+n*s,o*Math.exp(Vo*n*r)]};else{var p=Math.sqrt(h),g=(c*c-o*o+$o*h)/(2*o*Xo*p),v=(c*c-o*o-$o*h)/(2*c*Xo*p),d=Math.log(Math.sqrt(g*g+1)-g),y=Math.log(Math.sqrt(v*v+1)-v);r=(y-d)/Vo,e=function(n){var t=n*r,e=rn(d),a=o/(Xo*p)*(e*un(Vo*t+d)-en(d));return[i+a*f,u+a*s,o*e/rn(Vo*t+d)]}}return e.duration=1e3*r,e},ao.behavior.zoom=function(){function n(n){n.on(L,s).on(Wo+".zoom",p).on("dblclick.zoom",g).on(R,h)}function e(n){return[(n[0]-k.x)/k.k,(n[1]-k.y)/k.k]}function r(n){return[n[0]*k.k+k.x,n[1]*k.k+k.y]}function i(n){k.k=Math.max(A[0],Math.min(A[1],n))}function u(n,t){t=r(t),k.x+=n[0]-t[0],k.y+=n[1]-t[1]}function o(t,e,r,o){t.__chart__={x:k.x,y:k.y,k:k.k},i(Math.pow(2,o)),u(d=e,r),t=ao.select(t),C>0&&(t=t.transition().duration(C)),t.call(n.event)}function a(){b&&b.domain(x.range().map(function(n){return(n-k.x)/k.k}).map(x.invert)),w&&w.domain(_.range().map(function(n){return(n-k.y)/k.k}).map(_.invert))}function l(n){z++||n({type:"zoomstart"})}function c(n){a(),n({type:"zoom",scale:k.k,translate:[k.x,k.y]})}function f(n){--z||(n({type:"zoomend"}),d=null)}function s(){function n(){a=1,u(ao.mouse(i),h),c(o)}function r(){s.on(q,null).on(T,null),p(a),f(o)}var i=this,o=D.of(i,arguments),a=0,s=ao.select(t(i)).on(q,n).on(T,r),h=e(ao.mouse(i)),p=W(i);Il.call(i),l(o)}function h(){function n(){var n=ao.touches(g);return p=k.k,n.forEach(function(n){n.identifier in d&&(d[n.identifier]=e(n))}),n}function t(){var t=ao.event.target;ao.select(t).on(x,r).on(b,a),_.push(t);for(var e=ao.event.changedTouches,i=0,u=e.length;u>i;++i)d[e[i].identifier]=null;var l=n(),c=Date.now();if(1===l.length){if(500>c-M){var f=l[0];o(g,f,d[f.identifier],Math.floor(Math.log(k.k)/Math.LN2)+1),S()}M=c}else if(l.length>1){var f=l[0],s=l[1],h=f[0]-s[0],p=f[1]-s[1];y=h*h+p*p}}function r(){var n,t,e,r,o=ao.touches(g);Il.call(g);for(var a=0,l=o.length;l>a;++a,r=null)if(e=o[a],r=d[e.identifier]){if(t)break;n=e,t=r}if(r){var f=(f=e[0]-n[0])*f+(f=e[1]-n[1])*f,s=y&&Math.sqrt(f/y);n=[(n[0]+e[0])/2,(n[1]+e[1])/2],t=[(t[0]+r[0])/2,(t[1]+r[1])/2],i(s*p)}M=null,u(n,t),c(v)}function a(){if(ao.event.touches.length){for(var t=ao.event.changedTouches,e=0,r=t.length;r>e;++e)delete d[t[e].identifier];for(var i in d)return void n()}ao.selectAll(_).on(m,null),w.on(L,s).on(R,h),N(),f(v)}var p,g=this,v=D.of(g,arguments),d={},y=0,m=".zoom-"+ao.event.changedTouches[0].identifier,x="touchmove"+m,b="touchend"+m,_=[],w=ao.select(g),N=W(g);t(),l(v),w.on(L,null).on(R,t)}function p(){var n=D.of(this,arguments);m?clearTimeout(m):(Il.call(this),v=e(d=y||ao.mouse(this)),l(n)),m=setTimeout(function(){m=null,f(n)},50),S(),i(Math.pow(2,.002*Bo())*k.k),u(d,v),c(n)}function g(){var n=ao.mouse(this),t=Math.log(k.k)/Math.LN2;o(this,n,e(n),ao.event.shiftKey?Math.ceil(t)-1:Math.floor(t)+1)}var v,d,y,m,M,x,b,_,w,k={x:0,y:0,k:1},E=[960,500],A=Jo,C=250,z=0,L="mousedown.zoom",q="mousemove.zoom",T="mouseup.zoom",R="touchstart.zoom",D=N(n,"zoomstart","zoom","zoomend");return Wo||(Wo="onwheel"in fo?(Bo=function(){return-ao.event.deltaY*(ao.event.deltaMode?120:1)},"wheel"):"onmousewheel"in fo?(Bo=function(){return ao.event.wheelDelta},"mousewheel"):(Bo=function(){return-ao.event.detail},"MozMousePixelScroll")),n.event=function(n){n.each(function(){var n=D.of(this,arguments),t=k;Hl?ao.select(this).transition().each("start.zoom",function(){k=this.__chart__||{x:0,y:0,k:1},l(n)}).tween("zoom:zoom",function(){var e=E[0],r=E[1],i=d?d[0]:e/2,u=d?d[1]:r/2,o=ao.interpolateZoom([(i-k.x)/k.k,(u-k.y)/k.k,e/k.k],[(i-t.x)/t.k,(u-t.y)/t.k,e/t.k]);return function(t){var r=o(t),a=e/r[2];this.__chart__=k={x:i-r[0]*a,y:u-r[1]*a,k:a},c(n)}}).each("interrupt.zoom",function(){f(n)}).each("end.zoom",function(){f(n)}):(this.__chart__=k,l(n),c(n),f(n))})},n.translate=function(t){return arguments.length?(k={x:+t[0],y:+t[1],k:k.k},a(),n):[k.x,k.y]},n.scale=function(t){return arguments.length?(k={x:k.x,y:k.y,k:null},i(+t),a(),n):k.k},n.scaleExtent=function(t){return arguments.length?(A=null==t?Jo:[+t[0],+t[1]],n):A},n.center=function(t){return arguments.length?(y=t&&[+t[0],+t[1]],n):y},n.size=function(t){return arguments.length?(E=t&&[+t[0],+t[1]],n):E},n.duration=function(t){return arguments.length?(C=+t,n):C},n.x=function(t){return arguments.length?(b=t,x=t.copy(),k={x:0,y:0,k:1},n):b},n.y=function(t){return arguments.length?(w=t,_=t.copy(),k={x:0,y:0,k:1},n):w},ao.rebind(n,D,"on")};var Bo,Wo,Jo=[0,1/0];ao.color=an,an.prototype.toString=function(){return this.rgb()+""},ao.hsl=ln;var Go=ln.prototype=new an;Go.brighter=function(n){return n=Math.pow(.7,arguments.length?n:1),new ln(this.h,this.s,this.l/n)},Go.darker=function(n){return n=Math.pow(.7,arguments.length?n:1),new ln(this.h,this.s,n*this.l)},Go.rgb=function(){return cn(this.h,this.s,this.l)},ao.hcl=fn;var Ko=fn.prototype=new an;Ko.brighter=function(n){return new fn(this.h,this.c,Math.min(100,this.l+Qo*(arguments.length?n:1)))},Ko.darker=function(n){return new fn(this.h,this.c,Math.max(0,this.l-Qo*(arguments.length?n:1)))},Ko.rgb=function(){return sn(this.h,this.c,this.l).rgb()},ao.lab=hn;var Qo=18,na=.95047,ta=1,ea=1.08883,ra=hn.prototype=new an;ra.brighter=function(n){return new hn(Math.min(100,this.l+Qo*(arguments.length?n:1)),this.a,this.b)},ra.darker=function(n){return new hn(Math.max(0,this.l-Qo*(arguments.length?n:1)),this.a,this.b)},ra.rgb=function(){return pn(this.l,this.a,this.b)},ao.rgb=mn;var ia=mn.prototype=new an;ia.brighter=function(n){n=Math.pow(.7,arguments.length?n:1);var t=this.r,e=this.g,r=this.b,i=30;return t||e||r?(t&&i>t&&(t=i),e&&i>e&&(e=i),r&&i>r&&(r=i),new mn(Math.min(255,t/n),Math.min(255,e/n),Math.min(255,r/n))):new mn(i,i,i)},ia.darker=function(n){return n=Math.pow(.7,arguments.length?n:1),new mn(n*this.r,n*this.g,n*this.b)},ia.hsl=function(){return wn(this.r,this.g,this.b)},ia.toString=function(){return"#"+bn(this.r)+bn(this.g)+bn(this.b)};var ua=ao.map({aliceblue:15792383,antiquewhite:16444375,aqua:65535,aquamarine:8388564,azure:15794175,beige:16119260,bisque:16770244,black:0,blanchedalmond:16772045,blue:255,blueviolet:9055202,brown:10824234,burlywood:14596231,cadetblue:6266528,chartreuse:8388352,chocolate:13789470,coral:16744272,cornflowerblue:6591981,cornsilk:16775388,crimson:14423100,cyan:65535,darkblue:139,darkcyan:35723,darkgoldenrod:12092939,darkgray:11119017,darkgreen:25600,darkgrey:11119017,darkkhaki:12433259,darkmagenta:9109643,darkolivegreen:5597999,darkorange:16747520,darkorchid:10040012,darkred:9109504,darksalmon:15308410,darkseagreen:9419919,darkslateblue:4734347,darkslategray:3100495,darkslategrey:3100495,darkturquoise:52945,darkviolet:9699539,deeppink:16716947,deepskyblue:49151,dimgray:6908265,dimgrey:6908265,dodgerblue:2003199,firebrick:11674146,floralwhite:16775920,forestgreen:2263842,fuchsia:16711935,gainsboro:14474460,ghostwhite:16316671,gold:16766720,goldenrod:14329120,gray:8421504,green:32768,greenyellow:11403055,grey:8421504,honeydew:15794160,hotpink:16738740,indianred:13458524,indigo:4915330,ivory:16777200,khaki:15787660,lavender:15132410,lavenderblush:16773365,lawngreen:8190976,lemonchiffon:16775885,lightblue:11393254,lightcoral:15761536,lightcyan:14745599,lightgoldenrodyellow:16448210,lightgray:13882323,lightgreen:9498256,lightgrey:13882323,lightpink:16758465,lightsalmon:16752762,lightseagreen:2142890,lightskyblue:8900346,lightslategray:7833753,lightslategrey:7833753,lightsteelblue:11584734,lightyellow:16777184,lime:65280,limegreen:3329330,linen:16445670,magenta:16711935,maroon:8388608,mediumaquamarine:6737322,mediumblue:205,mediumorchid:12211667,mediumpurple:9662683,mediumseagreen:3978097,mediumslateblue:8087790,mediumspringgreen:64154,mediumturquoise:4772300,mediumvioletred:13047173,midnightblue:1644912,mintcream:16121850,mistyrose:16770273,moccasin:16770229,navajowhite:16768685,navy:128,oldlace:16643558,olive:8421376,olivedrab:7048739,orange:16753920,orangered:16729344,orchid:14315734,palegoldenrod:15657130,palegreen:10025880,paleturquoise:11529966,palevioletred:14381203,papayawhip:16773077,peachpuff:16767673,peru:13468991,pink:16761035,plum:14524637,powderblue:11591910,purple:8388736,rebeccapurple:6697881,red:16711680,rosybrown:12357519,royalblue:4286945,saddlebrown:9127187,salmon:16416882,sandybrown:16032864,seagreen:3050327,seashell:16774638,sienna:10506797,silver:12632256,skyblue:8900331,slateblue:6970061,slategray:7372944,slategrey:7372944,snow:16775930,springgreen:65407,steelblue:4620980,tan:13808780,teal:32896,thistle:14204888,tomato:16737095,turquoise:4251856,violet:15631086,wheat:16113331,white:16777215,whitesmoke:16119285,yellow:16776960,yellowgreen:10145074});ua.forEach(function(n,t){ua.set(n,Mn(t))}),ao.functor=En,ao.xhr=An(m),ao.dsv=function(n,t){function e(n,e,u){arguments.length<3&&(u=e,e=null);var o=Cn(n,t,null==e?r:i(e),u);return o.row=function(n){return arguments.length?o.response(null==(e=n)?r:i(n)):e},o}function r(n){return e.parse(n.responseText)}function i(n){return function(t){return e.parse(t.responseText,n)}}function u(t){return t.map(o).join(n)}function o(n){return a.test(n)?'"'+n.replace(/\"/g,'""')+'"':n}var a=new RegExp('["'+n+"\n]"),l=n.charCodeAt(0);return e.parse=function(n,t){var r;return e.parseRows(n,function(n,e){if(r)return r(n,e-1);var i=new Function("d","return {"+n.map(function(n,t){return JSON.stringify(n)+": d["+t+"]"}).join(",")+"}");r=t?function(n,e){return t(i(n),e)}:i})},e.parseRows=function(n,t){function e(){if(f>=c)return o;if(i)return i=!1,u;var t=f;if(34===n.charCodeAt(t)){for(var e=t;e++f;){var r=n.charCodeAt(f++),a=1;if(10===r)i=!0;else if(13===r)i=!0,10===n.charCodeAt(f)&&(++f,++a);else if(r!==l)continue;return n.slice(t,f-a)}return n.slice(t)}for(var r,i,u={},o={},a=[],c=n.length,f=0,s=0;(r=e())!==o;){for(var h=[];r!==u&&r!==o;)h.push(r),r=e();t&&null==(h=t(h,s++))||a.push(h)}return a},e.format=function(t){if(Array.isArray(t[0]))return e.formatRows(t);var r=new y,i=[];return t.forEach(function(n){for(var t in n)r.has(t)||i.push(r.add(t))}),[i.map(o).join(n)].concat(t.map(function(t){return i.map(function(n){return o(t[n])}).join(n)})).join("\n")},e.formatRows=function(n){return n.map(u).join("\n")},e},ao.csv=ao.dsv(",","text/csv"),ao.tsv=ao.dsv(" ","text/tab-separated-values");var oa,aa,la,ca,fa=this[x(this,"requestAnimationFrame")]||function(n){setTimeout(n,17)};ao.timer=function(){qn.apply(this,arguments)},ao.timer.flush=function(){Rn(),Dn()},ao.round=function(n,t){return t?Math.round(n*(t=Math.pow(10,t)))/t:Math.round(n)};var sa=["y","z","a","f","p","n","\xb5","m","","k","M","G","T","P","E","Z","Y"].map(Un);ao.formatPrefix=function(n,t){var e=0;return(n=+n)&&(0>n&&(n*=-1),t&&(n=ao.round(n,Pn(n,t))),e=1+Math.floor(1e-12+Math.log(n)/Math.LN10),e=Math.max(-24,Math.min(24,3*Math.floor((e-1)/3)))),sa[8+e/3]};var ha=/(?:([^{])?([<>=^]))?([+\- ])?([$#])?(0)?(\d+)?(,)?(\.-?\d+)?([a-z%])?/i,pa=ao.map({b:function(n){return n.toString(2)},c:function(n){return String.fromCharCode(n)},o:function(n){return n.toString(8)},x:function(n){return n.toString(16)},X:function(n){return n.toString(16).toUpperCase()},g:function(n,t){return n.toPrecision(t)},e:function(n,t){return n.toExponential(t)},f:function(n,t){return n.toFixed(t)},r:function(n,t){return(n=ao.round(n,Pn(n,t))).toFixed(Math.max(0,Math.min(20,Pn(n*(1+1e-15),t))))}}),ga=ao.time={},va=Date;Hn.prototype={getDate:function(){return this._.getUTCDate()},getDay:function(){return this._.getUTCDay()},getFullYear:function(){return this._.getUTCFullYear()},getHours:function(){return this._.getUTCHours()},getMilliseconds:function(){return this._.getUTCMilliseconds()},getMinutes:function(){return this._.getUTCMinutes()},getMonth:function(){return this._.getUTCMonth()},getSeconds:function(){return this._.getUTCSeconds()},getTime:function(){return this._.getTime()},getTimezoneOffset:function(){return 0},valueOf:function(){return this._.valueOf()},setDate:function(){da.setUTCDate.apply(this._,arguments)},setDay:function(){da.setUTCDay.apply(this._,arguments)},setFullYear:function(){da.setUTCFullYear.apply(this._,arguments)},setHours:function(){da.setUTCHours.apply(this._,arguments)},setMilliseconds:function(){da.setUTCMilliseconds.apply(this._,arguments)},setMinutes:function(){da.setUTCMinutes.apply(this._,arguments)},setMonth:function(){da.setUTCMonth.apply(this._,arguments)},setSeconds:function(){da.setUTCSeconds.apply(this._,arguments)},setTime:function(){da.setTime.apply(this._,arguments)}};var da=Date.prototype;ga.year=On(function(n){return n=ga.day(n),n.setMonth(0,1),n},function(n,t){n.setFullYear(n.getFullYear()+t)},function(n){return n.getFullYear()}),ga.years=ga.year.range,ga.years.utc=ga.year.utc.range,ga.day=On(function(n){var t=new va(2e3,0);return t.setFullYear(n.getFullYear(),n.getMonth(),n.getDate()),t},function(n,t){n.setDate(n.getDate()+t)},function(n){return n.getDate()-1}),ga.days=ga.day.range,ga.days.utc=ga.day.utc.range,ga.dayOfYear=function(n){var t=ga.year(n);return Math.floor((n-t-6e4*(n.getTimezoneOffset()-t.getTimezoneOffset()))/864e5)},["sunday","monday","tuesday","wednesday","thursday","friday","saturday"].forEach(function(n,t){t=7-t;var e=ga[n]=On(function(n){return(n=ga.day(n)).setDate(n.getDate()-(n.getDay()+t)%7),n},function(n,t){n.setDate(n.getDate()+7*Math.floor(t))},function(n){var e=ga.year(n).getDay();return Math.floor((ga.dayOfYear(n)+(e+t)%7)/7)-(e!==t)});ga[n+"s"]=e.range,ga[n+"s"].utc=e.utc.range,ga[n+"OfYear"]=function(n){var e=ga.year(n).getDay();return Math.floor((ga.dayOfYear(n)+(e+t)%7)/7)}}),ga.week=ga.sunday,ga.weeks=ga.sunday.range,ga.weeks.utc=ga.sunday.utc.range,ga.weekOfYear=ga.sundayOfYear;var ya={"-":"",_:" ",0:"0"},ma=/^\s*\d+/,Ma=/^%/;ao.locale=function(n){return{numberFormat:jn(n),timeFormat:Yn(n)}};var xa=ao.locale({decimal:".",thousands:",",grouping:[3],currency:["$",""],dateTime:"%a %b %e %X %Y",date:"%m/%d/%Y",time:"%H:%M:%S",periods:["AM","PM"],days:["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"], -shortDays:["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],months:["January","February","March","April","May","June","July","August","September","October","November","December"],shortMonths:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"]});ao.format=xa.numberFormat,ao.geo={},ft.prototype={s:0,t:0,add:function(n){st(n,this.t,ba),st(ba.s,this.s,this),this.s?this.t+=ba.t:this.s=ba.t},reset:function(){this.s=this.t=0},valueOf:function(){return this.s}};var ba=new ft;ao.geo.stream=function(n,t){n&&_a.hasOwnProperty(n.type)?_a[n.type](n,t):ht(n,t)};var _a={Feature:function(n,t){ht(n.geometry,t)},FeatureCollection:function(n,t){for(var e=n.features,r=-1,i=e.length;++rn?4*Fo+n:n,Na.lineStart=Na.lineEnd=Na.point=b}};ao.geo.bounds=function(){function n(n,t){M.push(x=[f=n,h=n]),s>t&&(s=t),t>p&&(p=t)}function t(t,e){var r=dt([t*Yo,e*Yo]);if(y){var i=mt(y,r),u=[i[1],-i[0],0],o=mt(u,i);bt(o),o=_t(o);var l=t-g,c=l>0?1:-1,v=o[0]*Zo*c,d=xo(l)>180;if(d^(v>c*g&&c*t>v)){var m=o[1]*Zo;m>p&&(p=m)}else if(v=(v+360)%360-180,d^(v>c*g&&c*t>v)){var m=-o[1]*Zo;s>m&&(s=m)}else s>e&&(s=e),e>p&&(p=e);d?g>t?a(f,t)>a(f,h)&&(h=t):a(t,h)>a(f,h)&&(f=t):h>=f?(f>t&&(f=t),t>h&&(h=t)):t>g?a(f,t)>a(f,h)&&(h=t):a(t,h)>a(f,h)&&(f=t)}else n(t,e);y=r,g=t}function e(){b.point=t}function r(){x[0]=f,x[1]=h,b.point=n,y=null}function i(n,e){if(y){var r=n-g;m+=xo(r)>180?r+(r>0?360:-360):r}else v=n,d=e;Na.point(n,e),t(n,e)}function u(){Na.lineStart()}function o(){i(v,d),Na.lineEnd(),xo(m)>Uo&&(f=-(h=180)),x[0]=f,x[1]=h,y=null}function a(n,t){return(t-=n)<0?t+360:t}function l(n,t){return n[0]-t[0]}function c(n,t){return t[0]<=t[1]?t[0]<=n&&n<=t[1]:nka?(f=-(h=180),s=-(p=90)):m>Uo?p=90:-Uo>m&&(s=-90),x[0]=f,x[1]=h}};return function(n){p=h=-(f=s=1/0),M=[],ao.geo.stream(n,b);var t=M.length;if(t){M.sort(l);for(var e,r=1,i=M[0],u=[i];t>r;++r)e=M[r],c(e[0],i)||c(e[1],i)?(a(i[0],e[1])>a(i[0],i[1])&&(i[1]=e[1]),a(e[0],i[1])>a(i[0],i[1])&&(i[0]=e[0])):u.push(i=e);for(var o,e,g=-(1/0),t=u.length-1,r=0,i=u[t];t>=r;i=e,++r)e=u[r],(o=a(i[1],e[0]))>g&&(g=o,f=e[0],h=i[1])}return M=x=null,f===1/0||s===1/0?[[NaN,NaN],[NaN,NaN]]:[[f,s],[h,p]]}}(),ao.geo.centroid=function(n){Ea=Aa=Ca=za=La=qa=Ta=Ra=Da=Pa=Ua=0,ao.geo.stream(n,ja);var t=Da,e=Pa,r=Ua,i=t*t+e*e+r*r;return jo>i&&(t=qa,e=Ta,r=Ra,Uo>Aa&&(t=Ca,e=za,r=La),i=t*t+e*e+r*r,jo>i)?[NaN,NaN]:[Math.atan2(e,t)*Zo,tn(r/Math.sqrt(i))*Zo]};var Ea,Aa,Ca,za,La,qa,Ta,Ra,Da,Pa,Ua,ja={sphere:b,point:St,lineStart:Nt,lineEnd:Et,polygonStart:function(){ja.lineStart=At},polygonEnd:function(){ja.lineStart=Nt}},Fa=Rt(zt,jt,Ht,[-Fo,-Fo/2]),Ha=1e9;ao.geo.clipExtent=function(){var n,t,e,r,i,u,o={stream:function(n){return i&&(i.valid=!1),i=u(n),i.valid=!0,i},extent:function(a){return arguments.length?(u=Zt(n=+a[0][0],t=+a[0][1],e=+a[1][0],r=+a[1][1]),i&&(i.valid=!1,i=null),o):[[n,t],[e,r]]}};return o.extent([[0,0],[960,500]])},(ao.geo.conicEqualArea=function(){return Vt(Xt)}).raw=Xt,ao.geo.albers=function(){return ao.geo.conicEqualArea().rotate([96,0]).center([-.6,38.7]).parallels([29.5,45.5]).scale(1070)},ao.geo.albersUsa=function(){function n(n){var u=n[0],o=n[1];return t=null,e(u,o),t||(r(u,o),t)||i(u,o),t}var t,e,r,i,u=ao.geo.albers(),o=ao.geo.conicEqualArea().rotate([154,0]).center([-2,58.5]).parallels([55,65]),a=ao.geo.conicEqualArea().rotate([157,0]).center([-3,19.9]).parallels([8,18]),l={point:function(n,e){t=[n,e]}};return n.invert=function(n){var t=u.scale(),e=u.translate(),r=(n[0]-e[0])/t,i=(n[1]-e[1])/t;return(i>=.12&&.234>i&&r>=-.425&&-.214>r?o:i>=.166&&.234>i&&r>=-.214&&-.115>r?a:u).invert(n)},n.stream=function(n){var t=u.stream(n),e=o.stream(n),r=a.stream(n);return{point:function(n,i){t.point(n,i),e.point(n,i),r.point(n,i)},sphere:function(){t.sphere(),e.sphere(),r.sphere()},lineStart:function(){t.lineStart(),e.lineStart(),r.lineStart()},lineEnd:function(){t.lineEnd(),e.lineEnd(),r.lineEnd()},polygonStart:function(){t.polygonStart(),e.polygonStart(),r.polygonStart()},polygonEnd:function(){t.polygonEnd(),e.polygonEnd(),r.polygonEnd()}}},n.precision=function(t){return arguments.length?(u.precision(t),o.precision(t),a.precision(t),n):u.precision()},n.scale=function(t){return arguments.length?(u.scale(t),o.scale(.35*t),a.scale(t),n.translate(u.translate())):u.scale()},n.translate=function(t){if(!arguments.length)return u.translate();var c=u.scale(),f=+t[0],s=+t[1];return e=u.translate(t).clipExtent([[f-.455*c,s-.238*c],[f+.455*c,s+.238*c]]).stream(l).point,r=o.translate([f-.307*c,s+.201*c]).clipExtent([[f-.425*c+Uo,s+.12*c+Uo],[f-.214*c-Uo,s+.234*c-Uo]]).stream(l).point,i=a.translate([f-.205*c,s+.212*c]).clipExtent([[f-.214*c+Uo,s+.166*c+Uo],[f-.115*c-Uo,s+.234*c-Uo]]).stream(l).point,n},n.scale(1070)};var Oa,Ia,Ya,Za,Va,Xa,$a={point:b,lineStart:b,lineEnd:b,polygonStart:function(){Ia=0,$a.lineStart=$t},polygonEnd:function(){$a.lineStart=$a.lineEnd=$a.point=b,Oa+=xo(Ia/2)}},Ba={point:Bt,lineStart:b,lineEnd:b,polygonStart:b,polygonEnd:b},Wa={point:Gt,lineStart:Kt,lineEnd:Qt,polygonStart:function(){Wa.lineStart=ne},polygonEnd:function(){Wa.point=Gt,Wa.lineStart=Kt,Wa.lineEnd=Qt}};ao.geo.path=function(){function n(n){return n&&("function"==typeof a&&u.pointRadius(+a.apply(this,arguments)),o&&o.valid||(o=i(u)),ao.geo.stream(n,o)),u.result()}function t(){return o=null,n}var e,r,i,u,o,a=4.5;return n.area=function(n){return Oa=0,ao.geo.stream(n,i($a)),Oa},n.centroid=function(n){return Ca=za=La=qa=Ta=Ra=Da=Pa=Ua=0,ao.geo.stream(n,i(Wa)),Ua?[Da/Ua,Pa/Ua]:Ra?[qa/Ra,Ta/Ra]:La?[Ca/La,za/La]:[NaN,NaN]},n.bounds=function(n){return Va=Xa=-(Ya=Za=1/0),ao.geo.stream(n,i(Ba)),[[Ya,Za],[Va,Xa]]},n.projection=function(n){return arguments.length?(i=(e=n)?n.stream||re(n):m,t()):e},n.context=function(n){return arguments.length?(u=null==(r=n)?new Wt:new te(n),"function"!=typeof a&&u.pointRadius(a),t()):r},n.pointRadius=function(t){return arguments.length?(a="function"==typeof t?t:(u.pointRadius(+t),+t),n):a},n.projection(ao.geo.albersUsa()).context(null)},ao.geo.transform=function(n){return{stream:function(t){var e=new ie(t);for(var r in n)e[r]=n[r];return e}}},ie.prototype={point:function(n,t){this.stream.point(n,t)},sphere:function(){this.stream.sphere()},lineStart:function(){this.stream.lineStart()},lineEnd:function(){this.stream.lineEnd()},polygonStart:function(){this.stream.polygonStart()},polygonEnd:function(){this.stream.polygonEnd()}},ao.geo.projection=oe,ao.geo.projectionMutator=ae,(ao.geo.equirectangular=function(){return oe(ce)}).raw=ce.invert=ce,ao.geo.rotation=function(n){function t(t){return t=n(t[0]*Yo,t[1]*Yo),t[0]*=Zo,t[1]*=Zo,t}return n=se(n[0]%360*Yo,n[1]*Yo,n.length>2?n[2]*Yo:0),t.invert=function(t){return t=n.invert(t[0]*Yo,t[1]*Yo),t[0]*=Zo,t[1]*=Zo,t},t},fe.invert=ce,ao.geo.circle=function(){function n(){var n="function"==typeof r?r.apply(this,arguments):r,t=se(-n[0]*Yo,-n[1]*Yo,0).invert,i=[];return e(null,null,1,{point:function(n,e){i.push(n=t(n,e)),n[0]*=Zo,n[1]*=Zo}}),{type:"Polygon",coordinates:[i]}}var t,e,r=[0,0],i=6;return n.origin=function(t){return arguments.length?(r=t,n):r},n.angle=function(r){return arguments.length?(e=ve((t=+r)*Yo,i*Yo),n):t},n.precision=function(r){return arguments.length?(e=ve(t*Yo,(i=+r)*Yo),n):i},n.angle(90)},ao.geo.distance=function(n,t){var e,r=(t[0]-n[0])*Yo,i=n[1]*Yo,u=t[1]*Yo,o=Math.sin(r),a=Math.cos(r),l=Math.sin(i),c=Math.cos(i),f=Math.sin(u),s=Math.cos(u);return Math.atan2(Math.sqrt((e=s*o)*e+(e=c*f-l*s*a)*e),l*f+c*s*a)},ao.geo.graticule=function(){function n(){return{type:"MultiLineString",coordinates:t()}}function t(){return ao.range(Math.ceil(u/d)*d,i,d).map(h).concat(ao.range(Math.ceil(c/y)*y,l,y).map(p)).concat(ao.range(Math.ceil(r/g)*g,e,g).filter(function(n){return xo(n%d)>Uo}).map(f)).concat(ao.range(Math.ceil(a/v)*v,o,v).filter(function(n){return xo(n%y)>Uo}).map(s))}var e,r,i,u,o,a,l,c,f,s,h,p,g=10,v=g,d=90,y=360,m=2.5;return n.lines=function(){return t().map(function(n){return{type:"LineString",coordinates:n}})},n.outline=function(){return{type:"Polygon",coordinates:[h(u).concat(p(l).slice(1),h(i).reverse().slice(1),p(c).reverse().slice(1))]}},n.extent=function(t){return arguments.length?n.majorExtent(t).minorExtent(t):n.minorExtent()},n.majorExtent=function(t){return arguments.length?(u=+t[0][0],i=+t[1][0],c=+t[0][1],l=+t[1][1],u>i&&(t=u,u=i,i=t),c>l&&(t=c,c=l,l=t),n.precision(m)):[[u,c],[i,l]]},n.minorExtent=function(t){return arguments.length?(r=+t[0][0],e=+t[1][0],a=+t[0][1],o=+t[1][1],r>e&&(t=r,r=e,e=t),a>o&&(t=a,a=o,o=t),n.precision(m)):[[r,a],[e,o]]},n.step=function(t){return arguments.length?n.majorStep(t).minorStep(t):n.minorStep()},n.majorStep=function(t){return arguments.length?(d=+t[0],y=+t[1],n):[d,y]},n.minorStep=function(t){return arguments.length?(g=+t[0],v=+t[1],n):[g,v]},n.precision=function(t){return arguments.length?(m=+t,f=ye(a,o,90),s=me(r,e,m),h=ye(c,l,90),p=me(u,i,m),n):m},n.majorExtent([[-180,-90+Uo],[180,90-Uo]]).minorExtent([[-180,-80-Uo],[180,80+Uo]])},ao.geo.greatArc=function(){function n(){return{type:"LineString",coordinates:[t||r.apply(this,arguments),e||i.apply(this,arguments)]}}var t,e,r=Me,i=xe;return n.distance=function(){return ao.geo.distance(t||r.apply(this,arguments),e||i.apply(this,arguments))},n.source=function(e){return arguments.length?(r=e,t="function"==typeof e?null:e,n):r},n.target=function(t){return arguments.length?(i=t,e="function"==typeof t?null:t,n):i},n.precision=function(){return arguments.length?n:0},n},ao.geo.interpolate=function(n,t){return be(n[0]*Yo,n[1]*Yo,t[0]*Yo,t[1]*Yo)},ao.geo.length=function(n){return Ja=0,ao.geo.stream(n,Ga),Ja};var Ja,Ga={sphere:b,point:b,lineStart:_e,lineEnd:b,polygonStart:b,polygonEnd:b},Ka=we(function(n){return Math.sqrt(2/(1+n))},function(n){return 2*Math.asin(n/2)});(ao.geo.azimuthalEqualArea=function(){return oe(Ka)}).raw=Ka;var Qa=we(function(n){var t=Math.acos(n);return t&&t/Math.sin(t)},m);(ao.geo.azimuthalEquidistant=function(){return oe(Qa)}).raw=Qa,(ao.geo.conicConformal=function(){return Vt(Se)}).raw=Se,(ao.geo.conicEquidistant=function(){return Vt(ke)}).raw=ke;var nl=we(function(n){return 1/n},Math.atan);(ao.geo.gnomonic=function(){return oe(nl)}).raw=nl,Ne.invert=function(n,t){return[n,2*Math.atan(Math.exp(t))-Io]},(ao.geo.mercator=function(){return Ee(Ne)}).raw=Ne;var tl=we(function(){return 1},Math.asin);(ao.geo.orthographic=function(){return oe(tl)}).raw=tl;var el=we(function(n){return 1/(1+n)},function(n){return 2*Math.atan(n)});(ao.geo.stereographic=function(){return oe(el)}).raw=el,Ae.invert=function(n,t){return[-t,2*Math.atan(Math.exp(n))-Io]},(ao.geo.transverseMercator=function(){var n=Ee(Ae),t=n.center,e=n.rotate;return n.center=function(n){return n?t([-n[1],n[0]]):(n=t(),[n[1],-n[0]])},n.rotate=function(n){return n?e([n[0],n[1],n.length>2?n[2]+90:90]):(n=e(),[n[0],n[1],n[2]-90])},e([0,0,90])}).raw=Ae,ao.geom={},ao.geom.hull=function(n){function t(n){if(n.length<3)return[];var t,i=En(e),u=En(r),o=n.length,a=[],l=[];for(t=0;o>t;t++)a.push([+i.call(this,n[t],t),+u.call(this,n[t],t),t]);for(a.sort(qe),t=0;o>t;t++)l.push([a[t][0],-a[t][1]]);var c=Le(a),f=Le(l),s=f[0]===c[0],h=f[f.length-1]===c[c.length-1],p=[];for(t=c.length-1;t>=0;--t)p.push(n[a[c[t]][2]]);for(t=+s;t=r&&c.x<=u&&c.y>=i&&c.y<=o?[[r,o],[u,o],[u,i],[r,i]]:[];f.point=n[a]}),t}function e(n){return n.map(function(n,t){return{x:Math.round(u(n,t)/Uo)*Uo,y:Math.round(o(n,t)/Uo)*Uo,i:t}})}var r=Ce,i=ze,u=r,o=i,a=sl;return n?t(n):(t.links=function(n){return ar(e(n)).edges.filter(function(n){return n.l&&n.r}).map(function(t){return{source:n[t.l.i],target:n[t.r.i]}})},t.triangles=function(n){var t=[];return ar(e(n)).cells.forEach(function(e,r){for(var i,u,o=e.site,a=e.edges.sort(Ve),l=-1,c=a.length,f=a[c-1].edge,s=f.l===o?f.r:f.l;++l=c,h=r>=f,p=h<<1|s;n.leaf=!1,n=n.nodes[p]||(n.nodes[p]=hr()),s?i=c:a=c,h?o=f:l=f,u(n,t,e,r,i,o,a,l)}var f,s,h,p,g,v,d,y,m,M=En(a),x=En(l);if(null!=t)v=t,d=e,y=r,m=i;else if(y=m=-(v=d=1/0),s=[],h=[],g=n.length,o)for(p=0;g>p;++p)f=n[p],f.xy&&(y=f.x),f.y>m&&(m=f.y),s.push(f.x),h.push(f.y);else for(p=0;g>p;++p){var b=+M(f=n[p],p),_=+x(f,p);v>b&&(v=b),d>_&&(d=_),b>y&&(y=b),_>m&&(m=_),s.push(b),h.push(_)}var w=y-v,S=m-d;w>S?m=d+w:y=v+S;var k=hr();if(k.add=function(n){u(k,n,+M(n,++p),+x(n,p),v,d,y,m)},k.visit=function(n){pr(n,k,v,d,y,m)},k.find=function(n){return gr(k,n[0],n[1],v,d,y,m)},p=-1,null==t){for(;++p=0?n.slice(0,t):n,r=t>=0?n.slice(t+1):"in";return e=vl.get(e)||gl,r=dl.get(r)||m,br(r(e.apply(null,lo.call(arguments,1))))},ao.interpolateHcl=Rr,ao.interpolateHsl=Dr,ao.interpolateLab=Pr,ao.interpolateRound=Ur,ao.transform=function(n){var t=fo.createElementNS(ao.ns.prefix.svg,"g");return(ao.transform=function(n){if(null!=n){t.setAttribute("transform",n);var e=t.transform.baseVal.consolidate()}return new jr(e?e.matrix:yl)})(n)},jr.prototype.toString=function(){return"translate("+this.translate+")rotate("+this.rotate+")skewX("+this.skew+")scale("+this.scale+")"};var yl={a:1,b:0,c:0,d:1,e:0,f:0};ao.interpolateTransform=$r,ao.layout={},ao.layout.bundle=function(){return function(n){for(var t=[],e=-1,r=n.length;++ea*a/y){if(v>l){var c=t.charge/l;n.px-=u*c,n.py-=o*c}return!0}if(t.point&&l&&v>l){var c=t.pointCharge/l;n.px-=u*c,n.py-=o*c}}return!t.charge}}function t(n){n.px=ao.event.x,n.py=ao.event.y,l.resume()}var e,r,i,u,o,a,l={},c=ao.dispatch("start","tick","end"),f=[1,1],s=.9,h=ml,p=Ml,g=-30,v=xl,d=.1,y=.64,M=[],x=[];return l.tick=function(){if((i*=.99)<.005)return e=null,c.end({type:"end",alpha:i=0}),!0;var t,r,l,h,p,v,y,m,b,_=M.length,w=x.length;for(r=0;w>r;++r)l=x[r],h=l.source,p=l.target,m=p.x-h.x,b=p.y-h.y,(v=m*m+b*b)&&(v=i*o[r]*((v=Math.sqrt(v))-u[r])/v,m*=v,b*=v,p.x-=m*(y=h.weight+p.weight?h.weight/(h.weight+p.weight):.5),p.y-=b*y,h.x+=m*(y=1-y),h.y+=b*y);if((y=i*d)&&(m=f[0]/2,b=f[1]/2,r=-1,y))for(;++r<_;)l=M[r],l.x+=(m-l.x)*y,l.y+=(b-l.y)*y;if(g)for(ri(t=ao.geom.quadtree(M),i,a),r=-1;++r<_;)(l=M[r]).fixed||t.visit(n(l));for(r=-1;++r<_;)l=M[r],l.fixed?(l.x=l.px,l.y=l.py):(l.x-=(l.px-(l.px=l.x))*s,l.y-=(l.py-(l.py=l.y))*s);c.tick({type:"tick",alpha:i})},l.nodes=function(n){return arguments.length?(M=n,l):M},l.links=function(n){return arguments.length?(x=n,l):x},l.size=function(n){return arguments.length?(f=n,l):f},l.linkDistance=function(n){return arguments.length?(h="function"==typeof n?n:+n,l):h},l.distance=l.linkDistance,l.linkStrength=function(n){return arguments.length?(p="function"==typeof n?n:+n,l):p},l.friction=function(n){return arguments.length?(s=+n,l):s},l.charge=function(n){return arguments.length?(g="function"==typeof n?n:+n,l):g},l.chargeDistance=function(n){return arguments.length?(v=n*n,l):Math.sqrt(v)},l.gravity=function(n){return arguments.length?(d=+n,l):d},l.theta=function(n){return arguments.length?(y=n*n,l):Math.sqrt(y)},l.alpha=function(n){return arguments.length?(n=+n,i?n>0?i=n:(e.c=null,e.t=NaN,e=null,c.end({type:"end",alpha:i=0})):n>0&&(c.start({type:"start",alpha:i=n}),e=qn(l.tick)),l):i},l.start=function(){function n(n,r){if(!e){for(e=new Array(i),l=0;i>l;++l)e[l]=[];for(l=0;c>l;++l){var u=x[l];e[u.source.index].push(u.target),e[u.target.index].push(u.source)}}for(var o,a=e[t],l=-1,f=a.length;++lt;++t)(r=M[t]).index=t,r.weight=0;for(t=0;c>t;++t)r=x[t],"number"==typeof r.source&&(r.source=M[r.source]),"number"==typeof r.target&&(r.target=M[r.target]),++r.source.weight,++r.target.weight;for(t=0;i>t;++t)r=M[t],isNaN(r.x)&&(r.x=n("x",s)),isNaN(r.y)&&(r.y=n("y",v)),isNaN(r.px)&&(r.px=r.x),isNaN(r.py)&&(r.py=r.y);if(u=[],"function"==typeof h)for(t=0;c>t;++t)u[t]=+h.call(this,x[t],t);else for(t=0;c>t;++t)u[t]=h;if(o=[],"function"==typeof p)for(t=0;c>t;++t)o[t]=+p.call(this,x[t],t);else for(t=0;c>t;++t)o[t]=p;if(a=[],"function"==typeof g)for(t=0;i>t;++t)a[t]=+g.call(this,M[t],t);else for(t=0;i>t;++t)a[t]=g;return l.resume()},l.resume=function(){return l.alpha(.1)},l.stop=function(){return l.alpha(0)},l.drag=function(){return r||(r=ao.behavior.drag().origin(m).on("dragstart.force",Qr).on("drag.force",t).on("dragend.force",ni)),arguments.length?void this.on("mouseover.force",ti).on("mouseout.force",ei).call(r):r},ao.rebind(l,c,"on")};var ml=20,Ml=1,xl=1/0;ao.layout.hierarchy=function(){function n(i){var u,o=[i],a=[];for(i.depth=0;null!=(u=o.pop());)if(a.push(u),(c=e.call(n,u,u.depth))&&(l=c.length)){for(var l,c,f;--l>=0;)o.push(f=c[l]),f.parent=u,f.depth=u.depth+1;r&&(u.value=0),u.children=c}else r&&(u.value=+r.call(n,u,u.depth)||0),delete u.children;return oi(i,function(n){var e,i;t&&(e=n.children)&&e.sort(t),r&&(i=n.parent)&&(i.value+=n.value)}),a}var t=ci,e=ai,r=li;return n.sort=function(e){return arguments.length?(t=e,n):t},n.children=function(t){return arguments.length?(e=t,n):e},n.value=function(t){return arguments.length?(r=t,n):r},n.revalue=function(t){return r&&(ui(t,function(n){n.children&&(n.value=0)}),oi(t,function(t){var e;t.children||(t.value=+r.call(n,t,t.depth)||0),(e=t.parent)&&(e.value+=t.value)})),t},n},ao.layout.partition=function(){function n(t,e,r,i){var u=t.children;if(t.x=e,t.y=t.depth*i,t.dx=r,t.dy=i,u&&(o=u.length)){var o,a,l,c=-1;for(r=t.value?r/t.value:0;++cs?-1:1),g=ao.sum(c),v=g?(s-l*p)/g:0,d=ao.range(l),y=[];return null!=e&&d.sort(e===bl?function(n,t){return c[t]-c[n]}:function(n,t){return e(o[n],o[t])}),d.forEach(function(n){y[n]={data:o[n],value:a=c[n],startAngle:f,endAngle:f+=a*v+p,padAngle:h}}),y}var t=Number,e=bl,r=0,i=Ho,u=0;return n.value=function(e){return arguments.length?(t=e,n):t},n.sort=function(t){return arguments.length?(e=t,n):e},n.startAngle=function(t){return arguments.length?(r=t,n):r},n.endAngle=function(t){return arguments.length?(i=t,n):i},n.padAngle=function(t){return arguments.length?(u=t,n):u},n};var bl={};ao.layout.stack=function(){function n(a,l){if(!(h=a.length))return a;var c=a.map(function(e,r){return t.call(n,e,r)}),f=c.map(function(t){return t.map(function(t,e){return[u.call(n,t,e),o.call(n,t,e)]})}),s=e.call(n,f,l);c=ao.permute(c,s),f=ao.permute(f,s);var h,p,g,v,d=r.call(n,f,l),y=c[0].length;for(g=0;y>g;++g)for(i.call(n,c[0][g],v=d[g],f[0][g][1]),p=1;h>p;++p)i.call(n,c[p][g],v+=f[p-1][g][1],f[p][g][1]);return a}var t=m,e=gi,r=vi,i=pi,u=si,o=hi;return n.values=function(e){return arguments.length?(t=e,n):t},n.order=function(t){return arguments.length?(e="function"==typeof t?t:_l.get(t)||gi,n):e},n.offset=function(t){return arguments.length?(r="function"==typeof t?t:wl.get(t)||vi,n):r},n.x=function(t){return arguments.length?(u=t,n):u},n.y=function(t){return arguments.length?(o=t,n):o},n.out=function(t){return arguments.length?(i=t,n):i},n};var _l=ao.map({"inside-out":function(n){var t,e,r=n.length,i=n.map(di),u=n.map(yi),o=ao.range(r).sort(function(n,t){return i[n]-i[t]}),a=0,l=0,c=[],f=[];for(t=0;r>t;++t)e=o[t],l>a?(a+=u[e],c.push(e)):(l+=u[e],f.push(e));return f.reverse().concat(c)},reverse:function(n){return ao.range(n.length).reverse()},"default":gi}),wl=ao.map({silhouette:function(n){var t,e,r,i=n.length,u=n[0].length,o=[],a=0,l=[];for(e=0;u>e;++e){for(t=0,r=0;i>t;t++)r+=n[t][e][1];r>a&&(a=r),o.push(r)}for(e=0;u>e;++e)l[e]=(a-o[e])/2;return l},wiggle:function(n){var t,e,r,i,u,o,a,l,c,f=n.length,s=n[0],h=s.length,p=[];for(p[0]=l=c=0,e=1;h>e;++e){for(t=0,i=0;f>t;++t)i+=n[t][e][1];for(t=0,u=0,a=s[e][0]-s[e-1][0];f>t;++t){for(r=0,o=(n[t][e][1]-n[t][e-1][1])/(2*a);t>r;++r)o+=(n[r][e][1]-n[r][e-1][1])/a;u+=o*n[t][e][1]}p[e]=l-=i?u/i*a:0,c>l&&(c=l)}for(e=0;h>e;++e)p[e]-=c;return p},expand:function(n){var t,e,r,i=n.length,u=n[0].length,o=1/i,a=[];for(e=0;u>e;++e){for(t=0,r=0;i>t;t++)r+=n[t][e][1];if(r)for(t=0;i>t;t++)n[t][e][1]/=r;else for(t=0;i>t;t++)n[t][e][1]=o}for(e=0;u>e;++e)a[e]=0;return a},zero:vi});ao.layout.histogram=function(){function n(n,u){for(var o,a,l=[],c=n.map(e,this),f=r.call(this,c,u),s=i.call(this,f,c,u),u=-1,h=c.length,p=s.length-1,g=t?1:1/h;++u0)for(u=-1;++u=f[0]&&a<=f[1]&&(o=l[ao.bisect(s,a,1,p)-1],o.y+=g,o.push(n[u]));return l}var t=!0,e=Number,r=bi,i=Mi;return n.value=function(t){return arguments.length?(e=t,n):e},n.range=function(t){return arguments.length?(r=En(t),n):r},n.bins=function(t){return arguments.length?(i="number"==typeof t?function(n){return xi(n,t)}:En(t),n):i},n.frequency=function(e){return arguments.length?(t=!!e,n):t},n},ao.layout.pack=function(){function n(n,u){var o=e.call(this,n,u),a=o[0],l=i[0],c=i[1],f=null==t?Math.sqrt:"function"==typeof t?t:function(){return t};if(a.x=a.y=0,oi(a,function(n){n.r=+f(n.value)}),oi(a,Ni),r){var s=r*(t?1:Math.max(2*a.r/l,2*a.r/c))/2;oi(a,function(n){n.r+=s}),oi(a,Ni),oi(a,function(n){n.r-=s})}return Ci(a,l/2,c/2,t?1:1/Math.max(2*a.r/l,2*a.r/c)),o}var t,e=ao.layout.hierarchy().sort(_i),r=0,i=[1,1];return n.size=function(t){return arguments.length?(i=t,n):i},n.radius=function(e){return arguments.length?(t=null==e||"function"==typeof e?e:+e,n):t},n.padding=function(t){return arguments.length?(r=+t,n):r},ii(n,e)},ao.layout.tree=function(){function n(n,i){var f=o.call(this,n,i),s=f[0],h=t(s);if(oi(h,e),h.parent.m=-h.z,ui(h,r),c)ui(s,u);else{var p=s,g=s,v=s;ui(s,function(n){n.xg.x&&(g=n),n.depth>v.depth&&(v=n)});var d=a(p,g)/2-p.x,y=l[0]/(g.x+a(g,p)/2+d),m=l[1]/(v.depth||1);ui(s,function(n){n.x=(n.x+d)*y,n.y=n.depth*m})}return f}function t(n){for(var t,e={A:null,children:[n]},r=[e];null!=(t=r.pop());)for(var i,u=t.children,o=0,a=u.length;a>o;++o)r.push((u[o]=i={_:u[o],parent:t,children:(i=u[o].children)&&i.slice()||[],A:null,a:null,z:0,m:0,c:0,s:0,t:null,i:o}).a=i);return e.children[0]}function e(n){var t=n.children,e=n.parent.children,r=n.i?e[n.i-1]:null;if(t.length){Di(n);var u=(t[0].z+t[t.length-1].z)/2;r?(n.z=r.z+a(n._,r._),n.m=n.z-u):n.z=u}else r&&(n.z=r.z+a(n._,r._));n.parent.A=i(n,r,n.parent.A||e[0])}function r(n){n._.x=n.z+n.parent.m,n.m+=n.parent.m}function i(n,t,e){if(t){for(var r,i=n,u=n,o=t,l=i.parent.children[0],c=i.m,f=u.m,s=o.m,h=l.m;o=Ti(o),i=qi(i),o&&i;)l=qi(l),u=Ti(u),u.a=n,r=o.z+s-i.z-c+a(o._,i._),r>0&&(Ri(Pi(o,n,e),n,r),c+=r,f+=r),s+=o.m,c+=i.m,h+=l.m,f+=u.m;o&&!Ti(u)&&(u.t=o,u.m+=s-f),i&&!qi(l)&&(l.t=i,l.m+=c-h,e=n)}return e}function u(n){n.x*=l[0],n.y=n.depth*l[1]}var o=ao.layout.hierarchy().sort(null).value(null),a=Li,l=[1,1],c=null;return n.separation=function(t){return arguments.length?(a=t,n):a},n.size=function(t){return arguments.length?(c=null==(l=t)?u:null,n):c?null:l},n.nodeSize=function(t){return arguments.length?(c=null==(l=t)?null:u,n):c?l:null},ii(n,o)},ao.layout.cluster=function(){function n(n,u){var o,a=t.call(this,n,u),l=a[0],c=0;oi(l,function(n){var t=n.children;t&&t.length?(n.x=ji(t),n.y=Ui(t)):(n.x=o?c+=e(n,o):0,n.y=0,o=n)});var f=Fi(l),s=Hi(l),h=f.x-e(f,s)/2,p=s.x+e(s,f)/2;return oi(l,i?function(n){n.x=(n.x-l.x)*r[0],n.y=(l.y-n.y)*r[1]}:function(n){n.x=(n.x-h)/(p-h)*r[0],n.y=(1-(l.y?n.y/l.y:1))*r[1]}),a}var t=ao.layout.hierarchy().sort(null).value(null),e=Li,r=[1,1],i=!1;return n.separation=function(t){return arguments.length?(e=t,n):e},n.size=function(t){return arguments.length?(i=null==(r=t),n):i?null:r},n.nodeSize=function(t){return arguments.length?(i=null!=(r=t),n):i?r:null},ii(n,t)},ao.layout.treemap=function(){function n(n,t){for(var e,r,i=-1,u=n.length;++it?0:t),e.area=isNaN(r)||0>=r?0:r}function t(e){var u=e.children;if(u&&u.length){var o,a,l,c=s(e),f=[],h=u.slice(),g=1/0,v="slice"===p?c.dx:"dice"===p?c.dy:"slice-dice"===p?1&e.depth?c.dy:c.dx:Math.min(c.dx,c.dy);for(n(h,c.dx*c.dy/e.value),f.area=0;(l=h.length)>0;)f.push(o=h[l-1]),f.area+=o.area,"squarify"!==p||(a=r(f,v))<=g?(h.pop(),g=a):(f.area-=f.pop().area,i(f,v,c,!1),v=Math.min(c.dx,c.dy),f.length=f.area=0,g=1/0);f.length&&(i(f,v,c,!0),f.length=f.area=0),u.forEach(t)}}function e(t){var r=t.children;if(r&&r.length){var u,o=s(t),a=r.slice(),l=[];for(n(a,o.dx*o.dy/t.value),l.area=0;u=a.pop();)l.push(u),l.area+=u.area,null!=u.z&&(i(l,u.z?o.dx:o.dy,o,!a.length),l.length=l.area=0);r.forEach(e)}}function r(n,t){for(var e,r=n.area,i=0,u=1/0,o=-1,a=n.length;++oe&&(u=e),e>i&&(i=e));return r*=r,t*=t,r?Math.max(t*i*g/r,r/(t*u*g)):1/0}function i(n,t,e,r){var i,u=-1,o=n.length,a=e.x,c=e.y,f=t?l(n.area/t):0; -if(t==e.dx){for((r||f>e.dy)&&(f=e.dy);++ue.dx)&&(f=e.dx);++ue&&(t=1),1>e&&(n=0),function(){var e,r,i;do e=2*Math.random()-1,r=2*Math.random()-1,i=e*e+r*r;while(!i||i>1);return n+t*e*Math.sqrt(-2*Math.log(i)/i)}},logNormal:function(){var n=ao.random.normal.apply(ao,arguments);return function(){return Math.exp(n())}},bates:function(n){var t=ao.random.irwinHall(n);return function(){return t()/n}},irwinHall:function(n){return function(){for(var t=0,e=0;n>e;e++)t+=Math.random();return t}}},ao.scale={};var Sl={floor:m,ceil:m};ao.scale.linear=function(){return Wi([0,1],[0,1],Mr,!1)};var kl={s:1,g:1,p:1,r:1,e:1};ao.scale.log=function(){return ru(ao.scale.linear().domain([0,1]),10,!0,[1,10])};var Nl=ao.format(".0e"),El={floor:function(n){return-Math.ceil(-n)},ceil:function(n){return-Math.floor(-n)}};ao.scale.pow=function(){return iu(ao.scale.linear(),1,[0,1])},ao.scale.sqrt=function(){return ao.scale.pow().exponent(.5)},ao.scale.ordinal=function(){return ou([],{t:"range",a:[[]]})},ao.scale.category10=function(){return ao.scale.ordinal().range(Al)},ao.scale.category20=function(){return ao.scale.ordinal().range(Cl)},ao.scale.category20b=function(){return ao.scale.ordinal().range(zl)},ao.scale.category20c=function(){return ao.scale.ordinal().range(Ll)};var Al=[2062260,16744206,2924588,14034728,9725885,9197131,14907330,8355711,12369186,1556175].map(xn),Cl=[2062260,11454440,16744206,16759672,2924588,10018698,14034728,16750742,9725885,12955861,9197131,12885140,14907330,16234194,8355711,13092807,12369186,14408589,1556175,10410725].map(xn),zl=[3750777,5395619,7040719,10264286,6519097,9216594,11915115,13556636,9202993,12426809,15186514,15190932,8666169,11356490,14049643,15177372,8077683,10834324,13528509,14589654].map(xn),Ll=[3244733,7057110,10406625,13032431,15095053,16616764,16625259,16634018,3253076,7652470,10607003,13101504,7695281,10394312,12369372,14342891,6513507,9868950,12434877,14277081].map(xn);ao.scale.quantile=function(){return au([],[])},ao.scale.quantize=function(){return lu(0,1,[0,1])},ao.scale.threshold=function(){return cu([.5],[0,1])},ao.scale.identity=function(){return fu([0,1])},ao.svg={},ao.svg.arc=function(){function n(){var n=Math.max(0,+e.apply(this,arguments)),c=Math.max(0,+r.apply(this,arguments)),f=o.apply(this,arguments)-Io,s=a.apply(this,arguments)-Io,h=Math.abs(s-f),p=f>s?0:1;if(n>c&&(g=c,c=n,n=g),h>=Oo)return t(c,p)+(n?t(n,1-p):"")+"Z";var g,v,d,y,m,M,x,b,_,w,S,k,N=0,E=0,A=[];if((y=(+l.apply(this,arguments)||0)/2)&&(d=u===ql?Math.sqrt(n*n+c*c):+u.apply(this,arguments),p||(E*=-1),c&&(E=tn(d/c*Math.sin(y))),n&&(N=tn(d/n*Math.sin(y)))),c){m=c*Math.cos(f+E),M=c*Math.sin(f+E),x=c*Math.cos(s-E),b=c*Math.sin(s-E);var C=Math.abs(s-f-2*E)<=Fo?0:1;if(E&&yu(m,M,x,b)===p^C){var z=(f+s)/2;m=c*Math.cos(z),M=c*Math.sin(z),x=b=null}}else m=M=0;if(n){_=n*Math.cos(s-N),w=n*Math.sin(s-N),S=n*Math.cos(f+N),k=n*Math.sin(f+N);var L=Math.abs(f-s+2*N)<=Fo?0:1;if(N&&yu(_,w,S,k)===1-p^L){var q=(f+s)/2;_=n*Math.cos(q),w=n*Math.sin(q),S=k=null}}else _=w=0;if(h>Uo&&(g=Math.min(Math.abs(c-n)/2,+i.apply(this,arguments)))>.001){v=c>n^p?0:1;var T=g,R=g;if(Fo>h){var D=null==S?[_,w]:null==x?[m,M]:Re([m,M],[S,k],[x,b],[_,w]),P=m-D[0],U=M-D[1],j=x-D[0],F=b-D[1],H=1/Math.sin(Math.acos((P*j+U*F)/(Math.sqrt(P*P+U*U)*Math.sqrt(j*j+F*F)))/2),O=Math.sqrt(D[0]*D[0]+D[1]*D[1]);R=Math.min(g,(n-O)/(H-1)),T=Math.min(g,(c-O)/(H+1))}if(null!=x){var I=mu(null==S?[_,w]:[S,k],[m,M],c,T,p),Y=mu([x,b],[_,w],c,T,p);g===T?A.push("M",I[0],"A",T,",",T," 0 0,",v," ",I[1],"A",c,",",c," 0 ",1-p^yu(I[1][0],I[1][1],Y[1][0],Y[1][1]),",",p," ",Y[1],"A",T,",",T," 0 0,",v," ",Y[0]):A.push("M",I[0],"A",T,",",T," 0 1,",v," ",Y[0])}else A.push("M",m,",",M);if(null!=S){var Z=mu([m,M],[S,k],n,-R,p),V=mu([_,w],null==x?[m,M]:[x,b],n,-R,p);g===R?A.push("L",V[0],"A",R,",",R," 0 0,",v," ",V[1],"A",n,",",n," 0 ",p^yu(V[1][0],V[1][1],Z[1][0],Z[1][1]),",",1-p," ",Z[1],"A",R,",",R," 0 0,",v," ",Z[0]):A.push("L",V[0],"A",R,",",R," 0 0,",v," ",Z[0])}else A.push("L",_,",",w)}else A.push("M",m,",",M),null!=x&&A.push("A",c,",",c," 0 ",C,",",p," ",x,",",b),A.push("L",_,",",w),null!=S&&A.push("A",n,",",n," 0 ",L,",",1-p," ",S,",",k);return A.push("Z"),A.join("")}function t(n,t){return"M0,"+n+"A"+n+","+n+" 0 1,"+t+" 0,"+-n+"A"+n+","+n+" 0 1,"+t+" 0,"+n}var e=hu,r=pu,i=su,u=ql,o=gu,a=vu,l=du;return n.innerRadius=function(t){return arguments.length?(e=En(t),n):e},n.outerRadius=function(t){return arguments.length?(r=En(t),n):r},n.cornerRadius=function(t){return arguments.length?(i=En(t),n):i},n.padRadius=function(t){return arguments.length?(u=t==ql?ql:En(t),n):u},n.startAngle=function(t){return arguments.length?(o=En(t),n):o},n.endAngle=function(t){return arguments.length?(a=En(t),n):a},n.padAngle=function(t){return arguments.length?(l=En(t),n):l},n.centroid=function(){var n=(+e.apply(this,arguments)+ +r.apply(this,arguments))/2,t=(+o.apply(this,arguments)+ +a.apply(this,arguments))/2-Io;return[Math.cos(t)*n,Math.sin(t)*n]},n};var ql="auto";ao.svg.line=function(){return Mu(m)};var Tl=ao.map({linear:xu,"linear-closed":bu,step:_u,"step-before":wu,"step-after":Su,basis:zu,"basis-open":Lu,"basis-closed":qu,bundle:Tu,cardinal:Eu,"cardinal-open":ku,"cardinal-closed":Nu,monotone:Fu});Tl.forEach(function(n,t){t.key=n,t.closed=/-closed$/.test(n)});var Rl=[0,2/3,1/3,0],Dl=[0,1/3,2/3,0],Pl=[0,1/6,2/3,1/6];ao.svg.line.radial=function(){var n=Mu(Hu);return n.radius=n.x,delete n.x,n.angle=n.y,delete n.y,n},wu.reverse=Su,Su.reverse=wu,ao.svg.area=function(){return Ou(m)},ao.svg.area.radial=function(){var n=Ou(Hu);return n.radius=n.x,delete n.x,n.innerRadius=n.x0,delete n.x0,n.outerRadius=n.x1,delete n.x1,n.angle=n.y,delete n.y,n.startAngle=n.y0,delete n.y0,n.endAngle=n.y1,delete n.y1,n},ao.svg.chord=function(){function n(n,a){var l=t(this,u,n,a),c=t(this,o,n,a);return"M"+l.p0+r(l.r,l.p1,l.a1-l.a0)+(e(l,c)?i(l.r,l.p1,l.r,l.p0):i(l.r,l.p1,c.r,c.p0)+r(c.r,c.p1,c.a1-c.a0)+i(c.r,c.p1,l.r,l.p0))+"Z"}function t(n,t,e,r){var i=t.call(n,e,r),u=a.call(n,i,r),o=l.call(n,i,r)-Io,f=c.call(n,i,r)-Io;return{r:u,a0:o,a1:f,p0:[u*Math.cos(o),u*Math.sin(o)],p1:[u*Math.cos(f),u*Math.sin(f)]}}function e(n,t){return n.a0==t.a0&&n.a1==t.a1}function r(n,t,e){return"A"+n+","+n+" 0 "+ +(e>Fo)+",1 "+t}function i(n,t,e,r){return"Q 0,0 "+r}var u=Me,o=xe,a=Iu,l=gu,c=vu;return n.radius=function(t){return arguments.length?(a=En(t),n):a},n.source=function(t){return arguments.length?(u=En(t),n):u},n.target=function(t){return arguments.length?(o=En(t),n):o},n.startAngle=function(t){return arguments.length?(l=En(t),n):l},n.endAngle=function(t){return arguments.length?(c=En(t),n):c},n},ao.svg.diagonal=function(){function n(n,i){var u=t.call(this,n,i),o=e.call(this,n,i),a=(u.y+o.y)/2,l=[u,{x:u.x,y:a},{x:o.x,y:a},o];return l=l.map(r),"M"+l[0]+"C"+l[1]+" "+l[2]+" "+l[3]}var t=Me,e=xe,r=Yu;return n.source=function(e){return arguments.length?(t=En(e),n):t},n.target=function(t){return arguments.length?(e=En(t),n):e},n.projection=function(t){return arguments.length?(r=t,n):r},n},ao.svg.diagonal.radial=function(){var n=ao.svg.diagonal(),t=Yu,e=n.projection;return n.projection=function(n){return arguments.length?e(Zu(t=n)):t},n},ao.svg.symbol=function(){function n(n,r){return(Ul.get(t.call(this,n,r))||$u)(e.call(this,n,r))}var t=Xu,e=Vu;return n.type=function(e){return arguments.length?(t=En(e),n):t},n.size=function(t){return arguments.length?(e=En(t),n):e},n};var Ul=ao.map({circle:$u,cross:function(n){var t=Math.sqrt(n/5)/2;return"M"+-3*t+","+-t+"H"+-t+"V"+-3*t+"H"+t+"V"+-t+"H"+3*t+"V"+t+"H"+t+"V"+3*t+"H"+-t+"V"+t+"H"+-3*t+"Z"},diamond:function(n){var t=Math.sqrt(n/(2*Fl)),e=t*Fl;return"M0,"+-t+"L"+e+",0 0,"+t+" "+-e+",0Z"},square:function(n){var t=Math.sqrt(n)/2;return"M"+-t+","+-t+"L"+t+","+-t+" "+t+","+t+" "+-t+","+t+"Z"},"triangle-down":function(n){var t=Math.sqrt(n/jl),e=t*jl/2;return"M0,"+e+"L"+t+","+-e+" "+-t+","+-e+"Z"},"triangle-up":function(n){var t=Math.sqrt(n/jl),e=t*jl/2;return"M0,"+-e+"L"+t+","+e+" "+-t+","+e+"Z"}});ao.svg.symbolTypes=Ul.keys();var jl=Math.sqrt(3),Fl=Math.tan(30*Yo);Co.transition=function(n){for(var t,e,r=Hl||++Zl,i=Ku(n),u=[],o=Ol||{time:Date.now(),ease:Nr,delay:0,duration:250},a=-1,l=this.length;++au;u++){i.push(t=[]);for(var e=this[u],a=0,l=e.length;l>a;a++)(r=e[a])&&n.call(r,r.__data__,a,u)&&t.push(r)}return Wu(i,this.namespace,this.id)},Yl.tween=function(n,t){var e=this.id,r=this.namespace;return arguments.length<2?this.node()[r][e].tween.get(n):Y(this,null==t?function(t){t[r][e].tween.remove(n)}:function(i){i[r][e].tween.set(n,t)})},Yl.attr=function(n,t){function e(){this.removeAttribute(a)}function r(){this.removeAttributeNS(a.space,a.local)}function i(n){return null==n?e:(n+="",function(){var t,e=this.getAttribute(a);return e!==n&&(t=o(e,n),function(n){this.setAttribute(a,t(n))})})}function u(n){return null==n?r:(n+="",function(){var t,e=this.getAttributeNS(a.space,a.local);return e!==n&&(t=o(e,n),function(n){this.setAttributeNS(a.space,a.local,t(n))})})}if(arguments.length<2){for(t in n)this.attr(t,n[t]);return this}var o="transform"==n?$r:Mr,a=ao.ns.qualify(n);return Ju(this,"attr."+n,t,a.local?u:i)},Yl.attrTween=function(n,t){function e(n,e){var r=t.call(this,n,e,this.getAttribute(i));return r&&function(n){this.setAttribute(i,r(n))}}function r(n,e){var r=t.call(this,n,e,this.getAttributeNS(i.space,i.local));return r&&function(n){this.setAttributeNS(i.space,i.local,r(n))}}var i=ao.ns.qualify(n);return this.tween("attr."+n,i.local?r:e)},Yl.style=function(n,e,r){function i(){this.style.removeProperty(n)}function u(e){return null==e?i:(e+="",function(){var i,u=t(this).getComputedStyle(this,null).getPropertyValue(n);return u!==e&&(i=Mr(u,e),function(t){this.style.setProperty(n,i(t),r)})})}var o=arguments.length;if(3>o){if("string"!=typeof n){2>o&&(e="");for(r in n)this.style(r,n[r],e);return this}r=""}return Ju(this,"style."+n,e,u)},Yl.styleTween=function(n,e,r){function i(i,u){var o=e.call(this,i,u,t(this).getComputedStyle(this,null).getPropertyValue(n));return o&&function(t){this.style.setProperty(n,o(t),r)}}return arguments.length<3&&(r=""),this.tween("style."+n,i)},Yl.text=function(n){return Ju(this,"text",n,Gu)},Yl.remove=function(){var n=this.namespace;return this.each("end.transition",function(){var t;this[n].count<2&&(t=this.parentNode)&&t.removeChild(this)})},Yl.ease=function(n){var t=this.id,e=this.namespace;return arguments.length<1?this.node()[e][t].ease:("function"!=typeof n&&(n=ao.ease.apply(ao,arguments)),Y(this,function(r){r[e][t].ease=n}))},Yl.delay=function(n){var t=this.id,e=this.namespace;return arguments.length<1?this.node()[e][t].delay:Y(this,"function"==typeof n?function(r,i,u){r[e][t].delay=+n.call(r,r.__data__,i,u)}:(n=+n,function(r){r[e][t].delay=n}))},Yl.duration=function(n){var t=this.id,e=this.namespace;return arguments.length<1?this.node()[e][t].duration:Y(this,"function"==typeof n?function(r,i,u){r[e][t].duration=Math.max(1,n.call(r,r.__data__,i,u))}:(n=Math.max(1,n),function(r){r[e][t].duration=n}))},Yl.each=function(n,t){var e=this.id,r=this.namespace;if(arguments.length<2){var i=Ol,u=Hl;try{Hl=e,Y(this,function(t,i,u){Ol=t[r][e],n.call(t,t.__data__,i,u)})}finally{Ol=i,Hl=u}}else Y(this,function(i){var u=i[r][e];(u.event||(u.event=ao.dispatch("start","end","interrupt"))).on(n,t)});return this},Yl.transition=function(){for(var n,t,e,r,i=this.id,u=++Zl,o=this.namespace,a=[],l=0,c=this.length;c>l;l++){a.push(n=[]);for(var t=this[l],f=0,s=t.length;s>f;f++)(e=t[f])&&(r=e[o][i],Qu(e,f,o,u,{time:r.time,ease:r.ease,delay:r.delay+r.duration,duration:r.duration})),n.push(e)}return Wu(a,o,u)},ao.svg.axis=function(){function n(n){n.each(function(){var n,c=ao.select(this),f=this.__chart__||e,s=this.__chart__=e.copy(),h=null==l?s.ticks?s.ticks.apply(s,a):s.domain():l,p=null==t?s.tickFormat?s.tickFormat.apply(s,a):m:t,g=c.selectAll(".tick").data(h,s),v=g.enter().insert("g",".domain").attr("class","tick").style("opacity",Uo),d=ao.transition(g.exit()).style("opacity",Uo).remove(),y=ao.transition(g.order()).style("opacity",1),M=Math.max(i,0)+o,x=Zi(s),b=c.selectAll(".domain").data([0]),_=(b.enter().append("path").attr("class","domain"),ao.transition(b));v.append("line"),v.append("text");var w,S,k,N,E=v.select("line"),A=y.select("line"),C=g.select("text").text(p),z=v.select("text"),L=y.select("text"),q="top"===r||"left"===r?-1:1;if("bottom"===r||"top"===r?(n=no,w="x",k="y",S="x2",N="y2",C.attr("dy",0>q?"0em":".71em").style("text-anchor","middle"),_.attr("d","M"+x[0]+","+q*u+"V0H"+x[1]+"V"+q*u)):(n=to,w="y",k="x",S="y2",N="x2",C.attr("dy",".32em").style("text-anchor",0>q?"end":"start"),_.attr("d","M"+q*u+","+x[0]+"H0V"+x[1]+"H"+q*u)),E.attr(N,q*i),z.attr(k,q*M),A.attr(S,0).attr(N,q*i),L.attr(w,0).attr(k,q*M),s.rangeBand){var T=s,R=T.rangeBand()/2;f=s=function(n){return T(n)+R}}else f.rangeBand?f=s:d.call(n,s,f);v.call(n,f,s),y.call(n,s,s)})}var t,e=ao.scale.linear(),r=Vl,i=6,u=6,o=3,a=[10],l=null;return n.scale=function(t){return arguments.length?(e=t,n):e},n.orient=function(t){return arguments.length?(r=t in Xl?t+"":Vl,n):r},n.ticks=function(){return arguments.length?(a=co(arguments),n):a},n.tickValues=function(t){return arguments.length?(l=t,n):l},n.tickFormat=function(e){return arguments.length?(t=e,n):t},n.tickSize=function(t){var e=arguments.length;return e?(i=+t,u=+arguments[e-1],n):i},n.innerTickSize=function(t){return arguments.length?(i=+t,n):i},n.outerTickSize=function(t){return arguments.length?(u=+t,n):u},n.tickPadding=function(t){return arguments.length?(o=+t,n):o},n.tickSubdivide=function(){return arguments.length&&n},n};var Vl="bottom",Xl={top:1,right:1,bottom:1,left:1};ao.svg.brush=function(){function n(t){t.each(function(){var t=ao.select(this).style("pointer-events","all").style("-webkit-tap-highlight-color","rgba(0,0,0,0)").on("mousedown.brush",u).on("touchstart.brush",u),o=t.selectAll(".background").data([0]);o.enter().append("rect").attr("class","background").style("visibility","hidden").style("cursor","crosshair"),t.selectAll(".extent").data([0]).enter().append("rect").attr("class","extent").style("cursor","move");var a=t.selectAll(".resize").data(v,m);a.exit().remove(),a.enter().append("g").attr("class",function(n){return"resize "+n}).style("cursor",function(n){return $l[n]}).append("rect").attr("x",function(n){return/[ew]$/.test(n)?-3:null}).attr("y",function(n){return/^[ns]/.test(n)?-3:null}).attr("width",6).attr("height",6).style("visibility","hidden"),a.style("display",n.empty()?"none":null);var l,s=ao.transition(t),h=ao.transition(o);c&&(l=Zi(c),h.attr("x",l[0]).attr("width",l[1]-l[0]),r(s)),f&&(l=Zi(f),h.attr("y",l[0]).attr("height",l[1]-l[0]),i(s)),e(s)})}function e(n){n.selectAll(".resize").attr("transform",function(n){return"translate("+s[+/e$/.test(n)]+","+h[+/^s/.test(n)]+")"})}function r(n){n.select(".extent").attr("x",s[0]),n.selectAll(".extent,.n>rect,.s>rect").attr("width",s[1]-s[0])}function i(n){n.select(".extent").attr("y",h[0]),n.selectAll(".extent,.e>rect,.w>rect").attr("height",h[1]-h[0])}function u(){function u(){32==ao.event.keyCode&&(C||(M=null,L[0]-=s[1],L[1]-=h[1],C=2),S())}function v(){32==ao.event.keyCode&&2==C&&(L[0]+=s[1],L[1]+=h[1],C=0,S())}function d(){var n=ao.mouse(b),t=!1;x&&(n[0]+=x[0],n[1]+=x[1]),C||(ao.event.altKey?(M||(M=[(s[0]+s[1])/2,(h[0]+h[1])/2]),L[0]=s[+(n[0]f?(i=r,r=f):i=f),v[0]!=r||v[1]!=i?(e?a=null:o=null,v[0]=r,v[1]=i,!0):void 0}function m(){d(),k.style("pointer-events","all").selectAll(".resize").style("display",n.empty()?"none":null),ao.select("body").style("cursor",null),q.on("mousemove.brush",null).on("mouseup.brush",null).on("touchmove.brush",null).on("touchend.brush",null).on("keydown.brush",null).on("keyup.brush",null),z(),w({type:"brushend"})}var M,x,b=this,_=ao.select(ao.event.target),w=l.of(b,arguments),k=ao.select(b),N=_.datum(),E=!/^(n|s)$/.test(N)&&c,A=!/^(e|w)$/.test(N)&&f,C=_.classed("extent"),z=W(b),L=ao.mouse(b),q=ao.select(t(b)).on("keydown.brush",u).on("keyup.brush",v);if(ao.event.changedTouches?q.on("touchmove.brush",d).on("touchend.brush",m):q.on("mousemove.brush",d).on("mouseup.brush",m),k.interrupt().selectAll("*").interrupt(),C)L[0]=s[0]-L[0],L[1]=h[0]-L[1];else if(N){var T=+/w$/.test(N),R=+/^n/.test(N);x=[s[1-T]-L[0],h[1-R]-L[1]],L[0]=s[T],L[1]=h[R]}else ao.event.altKey&&(M=L.slice());k.style("pointer-events","none").selectAll(".resize").style("display",null),ao.select("body").style("cursor",_.style("cursor")),w({type:"brushstart"}),d()}var o,a,l=N(n,"brushstart","brush","brushend"),c=null,f=null,s=[0,0],h=[0,0],p=!0,g=!0,v=Bl[0];return n.event=function(n){n.each(function(){var n=l.of(this,arguments),t={x:s,y:h,i:o,j:a},e=this.__chart__||t;this.__chart__=t,Hl?ao.select(this).transition().each("start.brush",function(){o=e.i,a=e.j,s=e.x,h=e.y,n({type:"brushstart"})}).tween("brush:brush",function(){var e=xr(s,t.x),r=xr(h,t.y);return o=a=null,function(i){s=t.x=e(i),h=t.y=r(i),n({type:"brush",mode:"resize"})}}).each("end.brush",function(){o=t.i,a=t.j,n({type:"brush",mode:"resize"}),n({type:"brushend"})}):(n({type:"brushstart"}),n({type:"brush",mode:"resize"}),n({type:"brushend"}))})},n.x=function(t){return arguments.length?(c=t,v=Bl[!c<<1|!f],n):c},n.y=function(t){return arguments.length?(f=t,v=Bl[!c<<1|!f],n):f},n.clamp=function(t){return arguments.length?(c&&f?(p=!!t[0],g=!!t[1]):c?p=!!t:f&&(g=!!t),n):c&&f?[p,g]:c?p:f?g:null},n.extent=function(t){var e,r,i,u,l;return arguments.length?(c&&(e=t[0],r=t[1],f&&(e=e[0],r=r[0]),o=[e,r],c.invert&&(e=c(e),r=c(r)),e>r&&(l=e,e=r,r=l),e==s[0]&&r==s[1]||(s=[e,r])),f&&(i=t[0],u=t[1],c&&(i=i[1],u=u[1]),a=[i,u],f.invert&&(i=f(i),u=f(u)),i>u&&(l=i,i=u,u=l),i==h[0]&&u==h[1]||(h=[i,u])),n):(c&&(o?(e=o[0],r=o[1]):(e=s[0],r=s[1],c.invert&&(e=c.invert(e),r=c.invert(r)),e>r&&(l=e,e=r,r=l))),f&&(a?(i=a[0],u=a[1]):(i=h[0],u=h[1],f.invert&&(i=f.invert(i),u=f.invert(u)),i>u&&(l=i,i=u,u=l))),c&&f?[[e,i],[r,u]]:c?[e,r]:f&&[i,u])},n.clear=function(){return n.empty()||(s=[0,0],h=[0,0],o=a=null),n},n.empty=function(){return!!c&&s[0]==s[1]||!!f&&h[0]==h[1]},ao.rebind(n,l,"on")};var $l={n:"ns-resize",e:"ew-resize",s:"ns-resize",w:"ew-resize",nw:"nwse-resize",ne:"nesw-resize",se:"nwse-resize",sw:"nesw-resize"},Bl=[["n","e","s","w","nw","ne","se","sw"],["e","w"],["n","s"],[]],Wl=ga.format=xa.timeFormat,Jl=Wl.utc,Gl=Jl("%Y-%m-%dT%H:%M:%S.%LZ");Wl.iso=Date.prototype.toISOString&&+new Date("2000-01-01T00:00:00.000Z")?eo:Gl,eo.parse=function(n){var t=new Date(n);return isNaN(t)?null:t},eo.toString=Gl.toString,ga.second=On(function(n){return new va(1e3*Math.floor(n/1e3))},function(n,t){n.setTime(n.getTime()+1e3*Math.floor(t))},function(n){return n.getSeconds()}),ga.seconds=ga.second.range,ga.seconds.utc=ga.second.utc.range,ga.minute=On(function(n){return new va(6e4*Math.floor(n/6e4))},function(n,t){n.setTime(n.getTime()+6e4*Math.floor(t))},function(n){return n.getMinutes()}),ga.minutes=ga.minute.range,ga.minutes.utc=ga.minute.utc.range,ga.hour=On(function(n){var t=n.getTimezoneOffset()/60;return new va(36e5*(Math.floor(n/36e5-t)+t))},function(n,t){n.setTime(n.getTime()+36e5*Math.floor(t))},function(n){return n.getHours()}),ga.hours=ga.hour.range,ga.hours.utc=ga.hour.utc.range,ga.month=On(function(n){return n=ga.day(n),n.setDate(1),n},function(n,t){n.setMonth(n.getMonth()+t)},function(n){return n.getMonth()}),ga.months=ga.month.range,ga.months.utc=ga.month.utc.range;var Kl=[1e3,5e3,15e3,3e4,6e4,3e5,9e5,18e5,36e5,108e5,216e5,432e5,864e5,1728e5,6048e5,2592e6,7776e6,31536e6],Ql=[[ga.second,1],[ga.second,5],[ga.second,15],[ga.second,30],[ga.minute,1],[ga.minute,5],[ga.minute,15],[ga.minute,30],[ga.hour,1],[ga.hour,3],[ga.hour,6],[ga.hour,12],[ga.day,1],[ga.day,2],[ga.week,1],[ga.month,1],[ga.month,3],[ga.year,1]],nc=Wl.multi([[".%L",function(n){return n.getMilliseconds()}],[":%S",function(n){return n.getSeconds()}],["%I:%M",function(n){return n.getMinutes()}],["%I %p",function(n){return n.getHours()}],["%a %d",function(n){return n.getDay()&&1!=n.getDate()}],["%b %d",function(n){return 1!=n.getDate()}],["%B",function(n){return n.getMonth()}],["%Y",zt]]),tc={range:function(n,t,e){return ao.range(Math.ceil(n/e)*e,+t,e).map(io)},floor:m,ceil:m};Ql.year=ga.year,ga.scale=function(){return ro(ao.scale.linear(),Ql,nc)};var ec=Ql.map(function(n){return[n[0].utc,n[1]]}),rc=Jl.multi([[".%L",function(n){return n.getUTCMilliseconds()}],[":%S",function(n){return n.getUTCSeconds()}],["%I:%M",function(n){return n.getUTCMinutes()}],["%I %p",function(n){return n.getUTCHours()}],["%a %d",function(n){return n.getUTCDay()&&1!=n.getUTCDate()}],["%b %d",function(n){return 1!=n.getUTCDate()}],["%B",function(n){return n.getUTCMonth()}],["%Y",zt]]);ec.year=ga.year.utc,ga.scale.utc=function(){return ro(ao.scale.linear(),ec,rc)},ao.text=An(function(n){return n.responseText}),ao.json=function(n,t){return Cn(n,"application/json",uo,t)},ao.html=function(n,t){return Cn(n,"text/html",oo,t)},ao.xml=An(function(n){return n.responseXML}),"function"==typeof define&&define.amd?(this.d3=ao,define(ao)):"object"==typeof module&&module.exports?module.exports=ao:this.d3=ao}(); \ No newline at end of file diff --git a/backend/coverage-report-controllers/_js/file.js b/backend/coverage-report-controllers/_js/file.js deleted file mode 100644 index 124a8a18..00000000 --- a/backend/coverage-report-controllers/_js/file.js +++ /dev/null @@ -1,53 +0,0 @@ -$(function () { - var $window = $(window) - , $top_link = $('#toplink') - , $body = $('body, html') - , offset = $('#code').offset().top; - - $top_link.hide().click(function (event) { - event.preventDefault(); - $body.animate({scrollTop: 0}, 800); - }); - - $window.scroll(function () { - if ($window.scrollTop() > offset) { - $top_link.fadeIn(); - } else { - $top_link.fadeOut(); - } - }); - - var $popovers = $('.popin > :first-child'); - $('.popin').on({ - 'click.popover': function (event) { - event.stopPropagation(); - - var $container = $(this).children().first(); - - //Close all other popovers: - $popovers.each(function () { - var $current = $(this); - if (!$current.is($container)) { - $current.popover('hide'); - } - }); - - // Toggle this popover: - $container.popover('toggle'); - }, - }); - - //Hide all popovers on outside click: - $(document).click(function (event) { - if ($(event.target).closest($('.popover')).length === 0) { - $popovers.popover('hide'); - } - }); - - //Hide all popovers on escape: - $(document).keyup(function (event) { - if (event.key === 'Escape') { - $popovers.popover('hide'); - } - }); -}); diff --git a/backend/coverage-report-controllers/_js/jquery.min.js b/backend/coverage-report-controllers/_js/jquery.min.js deleted file mode 100644 index 798cc8bf..00000000 --- a/backend/coverage-report-controllers/_js/jquery.min.js +++ /dev/null @@ -1,2 +0,0 @@ -/*! jQuery v3.7.1 | (c) OpenJS Foundation and other contributors | jquery.org/license */ -!function(e,t){"use strict";"object"==typeof module&&"object"==typeof module.exports?module.exports=e.document?t(e,!0):function(e){if(!e.document)throw new Error("jQuery requires a window with a document");return t(e)}:t(e)}("undefined"!=typeof window?window:this,function(ie,e){"use strict";var oe=[],r=Object.getPrototypeOf,ae=oe.slice,g=oe.flat?function(e){return oe.flat.call(e)}:function(e){return oe.concat.apply([],e)},s=oe.push,se=oe.indexOf,n={},i=n.toString,ue=n.hasOwnProperty,o=ue.toString,a=o.call(Object),le={},v=function(e){return"function"==typeof e&&"number"!=typeof e.nodeType&&"function"!=typeof e.item},y=function(e){return null!=e&&e===e.window},C=ie.document,u={type:!0,src:!0,nonce:!0,noModule:!0};function m(e,t,n){var r,i,o=(n=n||C).createElement("script");if(o.text=e,t)for(r in u)(i=t[r]||t.getAttribute&&t.getAttribute(r))&&o.setAttribute(r,i);n.head.appendChild(o).parentNode.removeChild(o)}function x(e){return null==e?e+"":"object"==typeof e||"function"==typeof e?n[i.call(e)]||"object":typeof e}var t="3.7.1",l=/HTML$/i,ce=function(e,t){return new ce.fn.init(e,t)};function c(e){var t=!!e&&"length"in e&&e.length,n=x(e);return!v(e)&&!y(e)&&("array"===n||0===t||"number"==typeof t&&0+~]|"+ge+")"+ge+"*"),x=new RegExp(ge+"|>"),j=new RegExp(g),A=new RegExp("^"+t+"$"),D={ID:new RegExp("^#("+t+")"),CLASS:new RegExp("^\\.("+t+")"),TAG:new RegExp("^("+t+"|[*])"),ATTR:new RegExp("^"+p),PSEUDO:new RegExp("^"+g),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+ge+"*(even|odd|(([+-]|)(\\d*)n|)"+ge+"*(?:([+-]|)"+ge+"*(\\d+)|))"+ge+"*\\)|)","i"),bool:new RegExp("^(?:"+f+")$","i"),needsContext:new RegExp("^"+ge+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+ge+"*((?:-\\d)?\\d*)"+ge+"*\\)|)(?=[^-]|$)","i")},N=/^(?:input|select|textarea|button)$/i,q=/^h\d$/i,L=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,H=/[+~]/,O=new RegExp("\\\\[\\da-fA-F]{1,6}"+ge+"?|\\\\([^\\r\\n\\f])","g"),P=function(e,t){var n="0x"+e.slice(1)-65536;return t||(n<0?String.fromCharCode(n+65536):String.fromCharCode(n>>10|55296,1023&n|56320))},M=function(){V()},R=J(function(e){return!0===e.disabled&&fe(e,"fieldset")},{dir:"parentNode",next:"legend"});try{k.apply(oe=ae.call(ye.childNodes),ye.childNodes),oe[ye.childNodes.length].nodeType}catch(e){k={apply:function(e,t){me.apply(e,ae.call(t))},call:function(e){me.apply(e,ae.call(arguments,1))}}}function I(t,e,n,r){var i,o,a,s,u,l,c,f=e&&e.ownerDocument,p=e?e.nodeType:9;if(n=n||[],"string"!=typeof t||!t||1!==p&&9!==p&&11!==p)return n;if(!r&&(V(e),e=e||T,C)){if(11!==p&&(u=L.exec(t)))if(i=u[1]){if(9===p){if(!(a=e.getElementById(i)))return n;if(a.id===i)return k.call(n,a),n}else if(f&&(a=f.getElementById(i))&&I.contains(e,a)&&a.id===i)return k.call(n,a),n}else{if(u[2])return k.apply(n,e.getElementsByTagName(t)),n;if((i=u[3])&&e.getElementsByClassName)return k.apply(n,e.getElementsByClassName(i)),n}if(!(h[t+" "]||d&&d.test(t))){if(c=t,f=e,1===p&&(x.test(t)||m.test(t))){(f=H.test(t)&&U(e.parentNode)||e)==e&&le.scope||((s=e.getAttribute("id"))?s=ce.escapeSelector(s):e.setAttribute("id",s=S)),o=(l=Y(t)).length;while(o--)l[o]=(s?"#"+s:":scope")+" "+Q(l[o]);c=l.join(",")}try{return k.apply(n,f.querySelectorAll(c)),n}catch(e){h(t,!0)}finally{s===S&&e.removeAttribute("id")}}}return re(t.replace(ve,"$1"),e,n,r)}function W(){var r=[];return function e(t,n){return r.push(t+" ")>b.cacheLength&&delete e[r.shift()],e[t+" "]=n}}function F(e){return e[S]=!0,e}function $(e){var t=T.createElement("fieldset");try{return!!e(t)}catch(e){return!1}finally{t.parentNode&&t.parentNode.removeChild(t),t=null}}function B(t){return function(e){return fe(e,"input")&&e.type===t}}function _(t){return function(e){return(fe(e,"input")||fe(e,"button"))&&e.type===t}}function z(t){return function(e){return"form"in e?e.parentNode&&!1===e.disabled?"label"in e?"label"in e.parentNode?e.parentNode.disabled===t:e.disabled===t:e.isDisabled===t||e.isDisabled!==!t&&R(e)===t:e.disabled===t:"label"in e&&e.disabled===t}}function X(a){return F(function(o){return o=+o,F(function(e,t){var n,r=a([],e.length,o),i=r.length;while(i--)e[n=r[i]]&&(e[n]=!(t[n]=e[n]))})})}function U(e){return e&&"undefined"!=typeof e.getElementsByTagName&&e}function V(e){var t,n=e?e.ownerDocument||e:ye;return n!=T&&9===n.nodeType&&n.documentElement&&(r=(T=n).documentElement,C=!ce.isXMLDoc(T),i=r.matches||r.webkitMatchesSelector||r.msMatchesSelector,r.msMatchesSelector&&ye!=T&&(t=T.defaultView)&&t.top!==t&&t.addEventListener("unload",M),le.getById=$(function(e){return r.appendChild(e).id=ce.expando,!T.getElementsByName||!T.getElementsByName(ce.expando).length}),le.disconnectedMatch=$(function(e){return i.call(e,"*")}),le.scope=$(function(){return T.querySelectorAll(":scope")}),le.cssHas=$(function(){try{return T.querySelector(":has(*,:jqfake)"),!1}catch(e){return!0}}),le.getById?(b.filter.ID=function(e){var t=e.replace(O,P);return function(e){return e.getAttribute("id")===t}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&C){var n=t.getElementById(e);return n?[n]:[]}}):(b.filter.ID=function(e){var n=e.replace(O,P);return function(e){var t="undefined"!=typeof e.getAttributeNode&&e.getAttributeNode("id");return t&&t.value===n}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&C){var n,r,i,o=t.getElementById(e);if(o){if((n=o.getAttributeNode("id"))&&n.value===e)return[o];i=t.getElementsByName(e),r=0;while(o=i[r++])if((n=o.getAttributeNode("id"))&&n.value===e)return[o]}return[]}}),b.find.TAG=function(e,t){return"undefined"!=typeof t.getElementsByTagName?t.getElementsByTagName(e):t.querySelectorAll(e)},b.find.CLASS=function(e,t){if("undefined"!=typeof t.getElementsByClassName&&C)return t.getElementsByClassName(e)},d=[],$(function(e){var t;r.appendChild(e).innerHTML="",e.querySelectorAll("[selected]").length||d.push("\\["+ge+"*(?:value|"+f+")"),e.querySelectorAll("[id~="+S+"-]").length||d.push("~="),e.querySelectorAll("a#"+S+"+*").length||d.push(".#.+[+~]"),e.querySelectorAll(":checked").length||d.push(":checked"),(t=T.createElement("input")).setAttribute("type","hidden"),e.appendChild(t).setAttribute("name","D"),r.appendChild(e).disabled=!0,2!==e.querySelectorAll(":disabled").length&&d.push(":enabled",":disabled"),(t=T.createElement("input")).setAttribute("name",""),e.appendChild(t),e.querySelectorAll("[name='']").length||d.push("\\["+ge+"*name"+ge+"*="+ge+"*(?:''|\"\")")}),le.cssHas||d.push(":has"),d=d.length&&new RegExp(d.join("|")),l=function(e,t){if(e===t)return a=!0,0;var n=!e.compareDocumentPosition-!t.compareDocumentPosition;return n||(1&(n=(e.ownerDocument||e)==(t.ownerDocument||t)?e.compareDocumentPosition(t):1)||!le.sortDetached&&t.compareDocumentPosition(e)===n?e===T||e.ownerDocument==ye&&I.contains(ye,e)?-1:t===T||t.ownerDocument==ye&&I.contains(ye,t)?1:o?se.call(o,e)-se.call(o,t):0:4&n?-1:1)}),T}for(e in I.matches=function(e,t){return I(e,null,null,t)},I.matchesSelector=function(e,t){if(V(e),C&&!h[t+" "]&&(!d||!d.test(t)))try{var n=i.call(e,t);if(n||le.disconnectedMatch||e.document&&11!==e.document.nodeType)return n}catch(e){h(t,!0)}return 0":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(O,P),e[3]=(e[3]||e[4]||e[5]||"").replace(O,P),"~="===e[2]&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),"nth"===e[1].slice(0,3)?(e[3]||I.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*("even"===e[3]||"odd"===e[3])),e[5]=+(e[7]+e[8]||"odd"===e[3])):e[3]&&I.error(e[0]),e},PSEUDO:function(e){var t,n=!e[6]&&e[2];return D.CHILD.test(e[0])?null:(e[3]?e[2]=e[4]||e[5]||"":n&&j.test(n)&&(t=Y(n,!0))&&(t=n.indexOf(")",n.length-t)-n.length)&&(e[0]=e[0].slice(0,t),e[2]=n.slice(0,t)),e.slice(0,3))}},filter:{TAG:function(e){var t=e.replace(O,P).toLowerCase();return"*"===e?function(){return!0}:function(e){return fe(e,t)}},CLASS:function(e){var t=s[e+" "];return t||(t=new RegExp("(^|"+ge+")"+e+"("+ge+"|$)"))&&s(e,function(e){return t.test("string"==typeof e.className&&e.className||"undefined"!=typeof e.getAttribute&&e.getAttribute("class")||"")})},ATTR:function(n,r,i){return function(e){var t=I.attr(e,n);return null==t?"!="===r:!r||(t+="","="===r?t===i:"!="===r?t!==i:"^="===r?i&&0===t.indexOf(i):"*="===r?i&&-1:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i;function T(e,n,r){return v(n)?ce.grep(e,function(e,t){return!!n.call(e,t,e)!==r}):n.nodeType?ce.grep(e,function(e){return e===n!==r}):"string"!=typeof n?ce.grep(e,function(e){return-1)[^>]*|#([\w-]+))$/;(ce.fn.init=function(e,t,n){var r,i;if(!e)return this;if(n=n||k,"string"==typeof e){if(!(r="<"===e[0]&&">"===e[e.length-1]&&3<=e.length?[null,e,null]:S.exec(e))||!r[1]&&t)return!t||t.jquery?(t||n).find(e):this.constructor(t).find(e);if(r[1]){if(t=t instanceof ce?t[0]:t,ce.merge(this,ce.parseHTML(r[1],t&&t.nodeType?t.ownerDocument||t:C,!0)),w.test(r[1])&&ce.isPlainObject(t))for(r in t)v(this[r])?this[r](t[r]):this.attr(r,t[r]);return this}return(i=C.getElementById(r[2]))&&(this[0]=i,this.length=1),this}return e.nodeType?(this[0]=e,this.length=1,this):v(e)?void 0!==n.ready?n.ready(e):e(ce):ce.makeArray(e,this)}).prototype=ce.fn,k=ce(C);var E=/^(?:parents|prev(?:Until|All))/,j={children:!0,contents:!0,next:!0,prev:!0};function A(e,t){while((e=e[t])&&1!==e.nodeType);return e}ce.fn.extend({has:function(e){var t=ce(e,this),n=t.length;return this.filter(function(){for(var e=0;e\x20\t\r\n\f]*)/i,Ce=/^$|^module$|\/(?:java|ecma)script/i;xe=C.createDocumentFragment().appendChild(C.createElement("div")),(be=C.createElement("input")).setAttribute("type","radio"),be.setAttribute("checked","checked"),be.setAttribute("name","t"),xe.appendChild(be),le.checkClone=xe.cloneNode(!0).cloneNode(!0).lastChild.checked,xe.innerHTML="",le.noCloneChecked=!!xe.cloneNode(!0).lastChild.defaultValue,xe.innerHTML="",le.option=!!xe.lastChild;var ke={thead:[1,"","
"],col:[2,"","
"],tr:[2,"","
"],td:[3,"","
"],_default:[0,"",""]};function Se(e,t){var n;return n="undefined"!=typeof e.getElementsByTagName?e.getElementsByTagName(t||"*"):"undefined"!=typeof e.querySelectorAll?e.querySelectorAll(t||"*"):[],void 0===t||t&&fe(e,t)?ce.merge([e],n):n}function Ee(e,t){for(var n=0,r=e.length;n",""]);var je=/<|&#?\w+;/;function Ae(e,t,n,r,i){for(var o,a,s,u,l,c,f=t.createDocumentFragment(),p=[],d=0,h=e.length;d\s*$/g;function Re(e,t){return fe(e,"table")&&fe(11!==t.nodeType?t:t.firstChild,"tr")&&ce(e).children("tbody")[0]||e}function Ie(e){return e.type=(null!==e.getAttribute("type"))+"/"+e.type,e}function We(e){return"true/"===(e.type||"").slice(0,5)?e.type=e.type.slice(5):e.removeAttribute("type"),e}function Fe(e,t){var n,r,i,o,a,s;if(1===t.nodeType){if(_.hasData(e)&&(s=_.get(e).events))for(i in _.remove(t,"handle events"),s)for(n=0,r=s[i].length;n").attr(n.scriptAttrs||{}).prop({charset:n.scriptCharset,src:n.url}).on("load error",i=function(e){r.remove(),i=null,e&&t("error"===e.type?404:200,e.type)}),C.head.appendChild(r[0])},abort:function(){i&&i()}}});var Jt,Kt=[],Zt=/(=)\?(?=&|$)|\?\?/;ce.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var e=Kt.pop()||ce.expando+"_"+jt.guid++;return this[e]=!0,e}}),ce.ajaxPrefilter("json jsonp",function(e,t,n){var r,i,o,a=!1!==e.jsonp&&(Zt.test(e.url)?"url":"string"==typeof e.data&&0===(e.contentType||"").indexOf("application/x-www-form-urlencoded")&&Zt.test(e.data)&&"data");if(a||"jsonp"===e.dataTypes[0])return r=e.jsonpCallback=v(e.jsonpCallback)?e.jsonpCallback():e.jsonpCallback,a?e[a]=e[a].replace(Zt,"$1"+r):!1!==e.jsonp&&(e.url+=(At.test(e.url)?"&":"?")+e.jsonp+"="+r),e.converters["script json"]=function(){return o||ce.error(r+" was not called"),o[0]},e.dataTypes[0]="json",i=ie[r],ie[r]=function(){o=arguments},n.always(function(){void 0===i?ce(ie).removeProp(r):ie[r]=i,e[r]&&(e.jsonpCallback=t.jsonpCallback,Kt.push(r)),o&&v(i)&&i(o[0]),o=i=void 0}),"script"}),le.createHTMLDocument=((Jt=C.implementation.createHTMLDocument("").body).innerHTML="
",2===Jt.childNodes.length),ce.parseHTML=function(e,t,n){return"string"!=typeof e?[]:("boolean"==typeof t&&(n=t,t=!1),t||(le.createHTMLDocument?((r=(t=C.implementation.createHTMLDocument("")).createElement("base")).href=C.location.href,t.head.appendChild(r)):t=C),o=!n&&[],(i=w.exec(e))?[t.createElement(i[1])]:(i=Ae([e],t,o),o&&o.length&&ce(o).remove(),ce.merge([],i.childNodes)));var r,i,o},ce.fn.load=function(e,t,n){var r,i,o,a=this,s=e.indexOf(" ");return-1").append(ce.parseHTML(e)).find(r):e)}).always(n&&function(e,t){a.each(function(){n.apply(this,o||[e.responseText,t,e])})}),this},ce.expr.pseudos.animated=function(t){return ce.grep(ce.timers,function(e){return t===e.elem}).length},ce.offset={setOffset:function(e,t,n){var r,i,o,a,s,u,l=ce.css(e,"position"),c=ce(e),f={};"static"===l&&(e.style.position="relative"),s=c.offset(),o=ce.css(e,"top"),u=ce.css(e,"left"),("absolute"===l||"fixed"===l)&&-1<(o+u).indexOf("auto")?(a=(r=c.position()).top,i=r.left):(a=parseFloat(o)||0,i=parseFloat(u)||0),v(t)&&(t=t.call(e,n,ce.extend({},s))),null!=t.top&&(f.top=t.top-s.top+a),null!=t.left&&(f.left=t.left-s.left+i),"using"in t?t.using.call(e,f):c.css(f)}},ce.fn.extend({offset:function(t){if(arguments.length)return void 0===t?this:this.each(function(e){ce.offset.setOffset(this,t,e)});var e,n,r=this[0];return r?r.getClientRects().length?(e=r.getBoundingClientRect(),n=r.ownerDocument.defaultView,{top:e.top+n.pageYOffset,left:e.left+n.pageXOffset}):{top:0,left:0}:void 0},position:function(){if(this[0]){var e,t,n,r=this[0],i={top:0,left:0};if("fixed"===ce.css(r,"position"))t=r.getBoundingClientRect();else{t=this.offset(),n=r.ownerDocument,e=r.offsetParent||n.documentElement;while(e&&(e===n.body||e===n.documentElement)&&"static"===ce.css(e,"position"))e=e.parentNode;e&&e!==r&&1===e.nodeType&&((i=ce(e).offset()).top+=ce.css(e,"borderTopWidth",!0),i.left+=ce.css(e,"borderLeftWidth",!0))}return{top:t.top-i.top-ce.css(r,"marginTop",!0),left:t.left-i.left-ce.css(r,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var e=this.offsetParent;while(e&&"static"===ce.css(e,"position"))e=e.offsetParent;return e||J})}}),ce.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(t,i){var o="pageYOffset"===i;ce.fn[t]=function(e){return M(this,function(e,t,n){var r;if(y(e)?r=e:9===e.nodeType&&(r=e.defaultView),void 0===n)return r?r[i]:e[t];r?r.scrollTo(o?r.pageXOffset:n,o?n:r.pageYOffset):e[t]=n},t,e,arguments.length)}}),ce.each(["top","left"],function(e,n){ce.cssHooks[n]=Ye(le.pixelPosition,function(e,t){if(t)return t=Ge(e,n),_e.test(t)?ce(e).position()[n]+"px":t})}),ce.each({Height:"height",Width:"width"},function(a,s){ce.each({padding:"inner"+a,content:s,"":"outer"+a},function(r,o){ce.fn[o]=function(e,t){var n=arguments.length&&(r||"boolean"!=typeof e),i=r||(!0===e||!0===t?"margin":"border");return M(this,function(e,t,n){var r;return y(e)?0===o.indexOf("outer")?e["inner"+a]:e.document.documentElement["client"+a]:9===e.nodeType?(r=e.documentElement,Math.max(e.body["scroll"+a],r["scroll"+a],e.body["offset"+a],r["offset"+a],r["client"+a])):void 0===n?ce.css(e,t,i):ce.style(e,t,n,i)},s,n?e:void 0,n)}})}),ce.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(e,t){ce.fn[t]=function(e){return this.on(t,e)}}),ce.fn.extend({bind:function(e,t,n){return this.on(e,null,t,n)},unbind:function(e,t){return this.off(e,null,t)},delegate:function(e,t,n,r){return this.on(t,e,n,r)},undelegate:function(e,t,n){return 1===arguments.length?this.off(e,"**"):this.off(t,e||"**",n)},hover:function(e,t){return this.on("mouseenter",e).on("mouseleave",t||e)}}),ce.each("blur focus focusin focusout resize scroll click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup contextmenu".split(" "),function(e,n){ce.fn[n]=function(e,t){return 0f&&(e=a.render.queue[f]);f++)d=e.generate(),typeof e.callback==typeof Function&&e.callback(d);a.render.queue.splice(0,f),a.render.queue.length?setTimeout(c):(a.dispatch.render_end(),a.render.active=!1)};setTimeout(c)},a.render.active=!1,a.render.queue=[],a.addGraph=function(b){typeof arguments[0]==typeof Function&&(b={generate:arguments[0],callback:arguments[1]}),a.render.queue.push(b),a.render.active||a.render()},"undefined"!=typeof module&&"undefined"!=typeof exports&&(module.exports=a),"undefined"!=typeof window&&(window.nv=a),a.dom.write=function(a){return void 0!==window.fastdom?fastdom.write(a):a()},a.dom.read=function(a){return void 0!==window.fastdom?fastdom.read(a):a()},a.interactiveGuideline=function(){"use strict";function b(l){l.each(function(l){function m(){var a=d3.mouse(this),d=a[0],e=a[1],i=!0,j=!1;if(k&&(d=d3.event.offsetX,e=d3.event.offsetY,"svg"!==d3.event.target.tagName&&(i=!1),d3.event.target.className.baseVal.match("nv-legend")&&(j=!0)),i&&(d-=f.left,e-=f.top),0>d||0>e||d>o||e>p||d3.event.relatedTarget&&void 0===d3.event.relatedTarget.ownerSVGElement||j){if(k&&d3.event.relatedTarget&&void 0===d3.event.relatedTarget.ownerSVGElement&&(void 0===d3.event.relatedTarget.className||d3.event.relatedTarget.className.match(c.nvPointerEventsClass)))return;return h.elementMouseout({mouseX:d,mouseY:e}),b.renderGuideLine(null),void c.hidden(!0)}c.hidden(!1);var l=g.invert(d);h.elementMousemove({mouseX:d,mouseY:e,pointXValue:l}),"dblclick"===d3.event.type&&h.elementDblclick({mouseX:d,mouseY:e,pointXValue:l}),"click"===d3.event.type&&h.elementClick({mouseX:d,mouseY:e,pointXValue:l})}var n=d3.select(this),o=d||960,p=e||400,q=n.selectAll("g.nv-wrap.nv-interactiveLineLayer").data([l]),r=q.enter().append("g").attr("class"," nv-wrap nv-interactiveLineLayer");r.append("g").attr("class","nv-interactiveGuideLine"),j&&(j.on("touchmove",m).on("mousemove",m,!0).on("mouseout",m,!0).on("dblclick",m).on("click",m),b.guideLine=null,b.renderGuideLine=function(c){i&&(b.guideLine&&b.guideLine.attr("x1")===c||a.dom.write(function(){var b=q.select(".nv-interactiveGuideLine").selectAll("line").data(null!=c?[a.utils.NaNtoZero(c)]:[],String);b.enter().append("line").attr("class","nv-guideline").attr("x1",function(a){return a}).attr("x2",function(a){return a}).attr("y1",p).attr("y2",0),b.exit().remove()}))})})}var c=a.models.tooltip();c.duration(0).hideDelay(0)._isInteractiveLayer(!0).hidden(!1);var d=null,e=null,f={left:0,top:0},g=d3.scale.linear(),h=d3.dispatch("elementMousemove","elementMouseout","elementClick","elementDblclick"),i=!0,j=null,k="ActiveXObject"in window;return b.dispatch=h,b.tooltip=c,b.margin=function(a){return arguments.length?(f.top="undefined"!=typeof a.top?a.top:f.top,f.left="undefined"!=typeof a.left?a.left:f.left,b):f},b.width=function(a){return arguments.length?(d=a,b):d},b.height=function(a){return arguments.length?(e=a,b):e},b.xScale=function(a){return arguments.length?(g=a,b):g},b.showGuideLine=function(a){return arguments.length?(i=a,b):i},b.svgContainer=function(a){return arguments.length?(j=a,b):j},b},a.interactiveBisect=function(a,b,c){"use strict";if(!(a instanceof Array))return null;var d;d="function"!=typeof c?function(a){return a.x}:c;var e=function(a,b){return d(a)-b},f=d3.bisector(e).left,g=d3.max([0,f(a,b)-1]),h=d(a[g]);if("undefined"==typeof h&&(h=g),h===b)return g;var i=d3.min([g+1,a.length-1]),j=d(a[i]);return"undefined"==typeof j&&(j=i),Math.abs(j-b)>=Math.abs(h-b)?g:i},a.nearestValueIndex=function(a,b,c){"use strict";var d=1/0,e=null;return a.forEach(function(a,f){var g=Math.abs(b-a);null!=a&&d>=g&&c>g&&(d=g,e=f)}),e},function(){"use strict";a.models.tooltip=function(){function b(){if(k){var a=d3.select(k);"svg"!==a.node().tagName&&(a=a.select("svg"));var b=a.node()?a.attr("viewBox"):null;if(b){b=b.split(" ");var c=parseInt(a.style("width"),10)/b[2];p.left=p.left*c,p.top=p.top*c}}}function c(){if(!n){var a;a=k?k:document.body,n=d3.select(a).append("div").attr("class","nvtooltip "+(j?j:"xy-tooltip")).attr("id",v),n.style("top",0).style("left",0),n.style("opacity",0),n.selectAll("div, table, td, tr").classed(w,!0),n.classed(w,!0),o=n.node()}}function d(){if(r&&B(e)){b();var f=p.left,g=null!==i?i:p.top;return a.dom.write(function(){c();var b=A(e);b&&(o.innerHTML=b),k&&u?a.dom.read(function(){var a=k.getElementsByTagName("svg")[0],b={left:0,top:0};if(a){var c=a.getBoundingClientRect(),d=k.getBoundingClientRect(),e=c.top;if(0>e){var i=k.getBoundingClientRect();e=Math.abs(e)>i.height?0:e}b.top=Math.abs(e-d.top),b.left=Math.abs(c.left-d.left)}f+=k.offsetLeft+b.left-2*k.scrollLeft,g+=k.offsetTop+b.top-2*k.scrollTop,h&&h>0&&(g=Math.floor(g/h)*h),C([f,g])}):C([f,g])}),d}}var e=null,f="w",g=25,h=0,i=null,j=null,k=null,l=!0,m=400,n=null,o=null,p={left:null,top:null},q={left:0,top:0},r=!0,s=100,t=!0,u=!1,v="nvtooltip-"+Math.floor(1e5*Math.random()),w="nv-pointer-events-none",x=function(a){return a},y=function(a){return a},z=function(a){return a},A=function(a){if(null===a)return"";var b=d3.select(document.createElement("table"));if(t){var c=b.selectAll("thead").data([a]).enter().append("thead");c.append("tr").append("td").attr("colspan",3).append("strong").classed("x-value",!0).html(y(a.value))}var d=b.selectAll("tbody").data([a]).enter().append("tbody"),e=d.selectAll("tr").data(function(a){return a.series}).enter().append("tr").classed("highlight",function(a){return a.highlight});e.append("td").classed("legend-color-guide",!0).append("div").style("background-color",function(a){return a.color}),e.append("td").classed("key",!0).html(function(a,b){return z(a.key,b)}),e.append("td").classed("value",!0).html(function(a,b){return x(a.value,b)}),e.selectAll("td").each(function(a){if(a.highlight){var b=d3.scale.linear().domain([0,1]).range(["#fff",a.color]),c=.6;d3.select(this).style("border-bottom-color",b(c)).style("border-top-color",b(c))}});var f=b.node().outerHTML;return void 0!==a.footer&&(f+=""),f},B=function(a){if(a&&a.series){if(a.series instanceof Array)return!!a.series.length;if(a.series instanceof Object)return a.series=[a.series],!0}return!1},C=function(b){o&&a.dom.read(function(){var c,d,e=parseInt(o.offsetHeight,10),h=parseInt(o.offsetWidth,10),i=a.utils.windowSize().width,j=a.utils.windowSize().height,k=window.pageYOffset,p=window.pageXOffset;j=window.innerWidth>=document.body.scrollWidth?j:j-16,i=window.innerHeight>=document.body.scrollHeight?i:i-16;var r,t,u=function(a){var b=d;do isNaN(a.offsetTop)||(b+=a.offsetTop),a=a.offsetParent;while(a);return b},v=function(a){var b=c;do isNaN(a.offsetLeft)||(b+=a.offsetLeft),a=a.offsetParent;while(a);return b};switch(f){case"e":c=b[0]-h-g,d=b[1]-e/2,r=v(o),t=u(o),p>r&&(c=b[0]+g>p?b[0]+g:p-r+c),k>t&&(d=k-t+d),t+e>k+j&&(d=k+j-t+d-e);break;case"w":c=b[0]+g,d=b[1]-e/2,r=v(o),t=u(o),r+h>i&&(c=b[0]-h-g),k>t&&(d=k+5),t+e>k+j&&(d=k+j-t+d-e);break;case"n":c=b[0]-h/2-5,d=b[1]+g,r=v(o),t=u(o),p>r&&(c=p+5),r+h>i&&(c=c-h/2+5),t+e>k+j&&(d=k+j-t+d-e);break;case"s":c=b[0]-h/2,d=b[1]-e-g,r=v(o),t=u(o),p>r&&(c=p+5),r+h>i&&(c=c-h/2+5),k>t&&(d=k);break;case"none":c=b[0],d=b[1]-g,r=v(o),t=u(o)}c-=q.left,d-=q.top;var w=o.getBoundingClientRect(),k=window.pageYOffset||document.documentElement.scrollTop,p=window.pageXOffset||document.documentElement.scrollLeft,x="translate("+(w.left+p)+"px, "+(w.top+k)+"px)",y="translate("+c+"px, "+d+"px)",z=d3.interpolateString(x,y),A=n.style("opacity")<.1;l?n.transition().delay(m).duration(0).style("opacity",0):n.interrupt().transition().duration(A?0:s).styleTween("transform",function(){return z},"important").style("-webkit-transform",y).style("opacity",1)})};return d.nvPointerEventsClass=w,d.options=a.utils.optionsFunc.bind(d),d._options=Object.create({},{duration:{get:function(){return s},set:function(a){s=a}},gravity:{get:function(){return f},set:function(a){f=a}},distance:{get:function(){return g},set:function(a){g=a}},snapDistance:{get:function(){return h},set:function(a){h=a}},classes:{get:function(){return j},set:function(a){j=a}},chartContainer:{get:function(){return k},set:function(a){k=a}},fixedTop:{get:function(){return i},set:function(a){i=a}},enabled:{get:function(){return r},set:function(a){r=a}},hideDelay:{get:function(){return m},set:function(a){m=a}},contentGenerator:{get:function(){return A},set:function(a){A=a}},valueFormatter:{get:function(){return x},set:function(a){x=a}},headerFormatter:{get:function(){return y},set:function(a){y=a}},keyFormatter:{get:function(){return z},set:function(a){z=a}},headerEnabled:{get:function(){return t},set:function(a){t=a}},_isInteractiveLayer:{get:function(){return u},set:function(a){u=!!a}},position:{get:function(){return p},set:function(a){p.left=void 0!==a.left?a.left:p.left,p.top=void 0!==a.top?a.top:p.top}},offset:{get:function(){return q},set:function(a){q.left=void 0!==a.left?a.left:q.left,q.top=void 0!==a.top?a.top:q.top}},hidden:{get:function(){return l},set:function(a){l!=a&&(l=!!a,d())}},data:{get:function(){return e},set:function(a){a.point&&(a.value=a.point.x,a.series=a.series||{},a.series.value=a.point.y,a.series.color=a.point.color||a.series.color),e=a}},tooltipElem:{get:function(){return o},set:function(){}},id:{get:function(){return v},set:function(){}}}),a.utils.initOptions(d),d}}(),a.utils.windowSize=function(){var a={width:640,height:480};return window.innerWidth&&window.innerHeight?(a.width=window.innerWidth,a.height=window.innerHeight,a):"CSS1Compat"==document.compatMode&&document.documentElement&&document.documentElement.offsetWidth?(a.width=document.documentElement.offsetWidth,a.height=document.documentElement.offsetHeight,a):document.body&&document.body.offsetWidth?(a.width=document.body.offsetWidth,a.height=document.body.offsetHeight,a):a},a.utils.windowResize=function(b){return window.addEventListener?window.addEventListener("resize",b):a.log("ERROR: Failed to bind to window.resize with: ",b),{callback:b,clear:function(){window.removeEventListener("resize",b)}}},a.utils.getColor=function(b){if(void 0===b)return a.utils.defaultColor();if(Array.isArray(b)){var c=d3.scale.ordinal().range(b);return function(a,b){var d=void 0===b?a:b;return a.color||c(d)}}return b},a.utils.defaultColor=function(){return a.utils.getColor(d3.scale.category20().range())},a.utils.customTheme=function(a,b,c){b=b||function(a){return a.key},c=c||d3.scale.category20().range();var d=c.length;return function(e){var f=b(e);return"function"==typeof a[f]?a[f]():void 0!==a[f]?a[f]:(d||(d=c.length),d-=1,c[d])}},a.utils.pjax=function(b,c){var d=function(d){d3.html(d,function(d){var e=d3.select(c).node();e.parentNode.replaceChild(d3.select(d).select(c).node(),e),a.utils.pjax(b,c)})};d3.selectAll(b).on("click",function(){history.pushState(this.href,this.textContent,this.href),d(this.href),d3.event.preventDefault()}),d3.select(window).on("popstate",function(){d3.event.state&&d(d3.event.state)})},a.utils.calcApproxTextWidth=function(a){if("function"==typeof a.style&&"function"==typeof a.text){var b=parseInt(a.style("font-size").replace("px",""),10),c=a.text().length;return c*b*.5}return 0},a.utils.NaNtoZero=function(a){return"number"!=typeof a||isNaN(a)||null===a||1/0===a||a===-1/0?0:a},d3.selection.prototype.watchTransition=function(a){var b=[this].concat([].slice.call(arguments,1));return a.transition.apply(a,b)},a.utils.renderWatch=function(b,c){if(!(this instanceof a.utils.renderWatch))return new a.utils.renderWatch(b,c);var d=void 0!==c?c:250,e=[],f=this;this.models=function(a){return a=[].slice.call(arguments,0),a.forEach(function(a){a.__rendered=!1,function(a){a.dispatch.on("renderEnd",function(){a.__rendered=!0,f.renderEnd("model")})}(a),e.indexOf(a)<0&&e.push(a)}),this},this.reset=function(a){void 0!==a&&(d=a),e=[]},this.transition=function(a,b,c){if(b=arguments.length>1?[].slice.call(arguments,1):[],c=b.length>1?b.pop():void 0!==d?d:250,a.__rendered=!1,e.indexOf(a)<0&&e.push(a),0===c)return a.__rendered=!0,a.delay=function(){return this},a.duration=function(){return this},a;a.__rendered=0===a.length?!0:a.every(function(a){return!a.length})?!0:!1;var g=0;return a.transition().duration(c).each(function(){++g}).each("end",function(){0===--g&&(a.__rendered=!0,f.renderEnd.apply(this,b))})},this.renderEnd=function(){e.every(function(a){return a.__rendered})&&(e.forEach(function(a){a.__rendered=!1}),b.renderEnd.apply(this,arguments))}},a.utils.deepExtend=function(b){var c=arguments.length>1?[].slice.call(arguments,1):[];c.forEach(function(c){for(var d in c){var e=b[d]instanceof Array,f="object"==typeof b[d],g="object"==typeof c[d];f&&!e&&g?a.utils.deepExtend(b[d],c[d]):b[d]=c[d]}})},a.utils.state=function(){if(!(this instanceof a.utils.state))return new a.utils.state;var b={},c=function(){},d=function(){return{}},e=null,f=null;this.dispatch=d3.dispatch("change","set"),this.dispatch.on("set",function(a){c(a,!0)}),this.getter=function(a){return d=a,this},this.setter=function(a,b){return b||(b=function(){}),c=function(c,d){a(c),d&&b()},this},this.init=function(b){e=e||{},a.utils.deepExtend(e,b)};var g=function(){var a=d();if(JSON.stringify(a)===JSON.stringify(b))return!1;for(var c in a)void 0===b[c]&&(b[c]={}),b[c]=a[c],f=!0;return!0};this.update=function(){e&&(c(e,!1),e=null),g.call(this)&&this.dispatch.change(b)}},a.utils.optionsFunc=function(a){return a&&d3.map(a).forEach(function(a,b){"function"==typeof this[a]&&this[a](b)}.bind(this)),this},a.utils.calcTicksX=function(b,c){var d=1,e=0;for(e;ed?f:d}return a.log("Requested number of ticks: ",b),a.log("Calculated max values to be: ",d),b=b>d?b=d-1:b,b=1>b?1:b,b=Math.floor(b),a.log("Calculating tick count as: ",b),b},a.utils.calcTicksY=function(b,c){return a.utils.calcTicksX(b,c)},a.utils.initOption=function(a,b){a._calls&&a._calls[b]?a[b]=a._calls[b]:(a[b]=function(c){return arguments.length?(a._overrides[b]=!0,a._options[b]=c,a):a._options[b]},a["_"+b]=function(c){return arguments.length?(a._overrides[b]||(a._options[b]=c),a):a._options[b]})},a.utils.initOptions=function(b){b._overrides=b._overrides||{};var c=Object.getOwnPropertyNames(b._options||{}),d=Object.getOwnPropertyNames(b._calls||{});c=c.concat(d);for(var e in c)a.utils.initOption(b,c[e])},a.utils.inheritOptionsD3=function(a,b,c){a._d3options=c.concat(a._d3options||[]),c.unshift(b),c.unshift(a),d3.rebind.apply(this,c)},a.utils.arrayUnique=function(a){return a.sort().filter(function(b,c){return!c||b!=a[c-1]})},a.utils.symbolMap=d3.map(),a.utils.symbol=function(){function b(b,e){var f=c.call(this,b,e),g=d.call(this,b,e);return-1!==d3.svg.symbolTypes.indexOf(f)?d3.svg.symbol().type(f).size(g)():a.utils.symbolMap.get(f)(g)}var c,d=64;return b.type=function(a){return arguments.length?(c=d3.functor(a),b):c},b.size=function(a){return arguments.length?(d=d3.functor(a),b):d},b},a.utils.inheritOptions=function(b,c){var d=Object.getOwnPropertyNames(c._options||{}),e=Object.getOwnPropertyNames(c._calls||{}),f=c._inherited||[],g=c._d3options||[],h=d.concat(e).concat(f).concat(g);h.unshift(c),h.unshift(b),d3.rebind.apply(this,h),b._inherited=a.utils.arrayUnique(d.concat(e).concat(f).concat(d).concat(b._inherited||[])),b._d3options=a.utils.arrayUnique(g.concat(b._d3options||[]))},a.utils.initSVG=function(a){a.classed({"nvd3-svg":!0})},a.utils.sanitizeHeight=function(a,b){return a||parseInt(b.style("height"),10)||400},a.utils.sanitizeWidth=function(a,b){return a||parseInt(b.style("width"),10)||960},a.utils.availableHeight=function(b,c,d){return a.utils.sanitizeHeight(b,c)-d.top-d.bottom},a.utils.availableWidth=function(b,c,d){return a.utils.sanitizeWidth(b,c)-d.left-d.right},a.utils.noData=function(b,c){var d=b.options(),e=d.margin(),f=d.noData(),g=null==f?["No Data Available."]:[f],h=a.utils.availableHeight(d.height(),c,e),i=a.utils.availableWidth(d.width(),c,e),j=e.left+i/2,k=e.top+h/2;c.selectAll("g").remove();var l=c.selectAll(".nv-noData").data(g);l.enter().append("text").attr("class","nvd3 nv-noData").attr("dy","-.7em").style("text-anchor","middle"),l.attr("x",j).attr("y",k).text(function(a){return a})},a.models.axis=function(){"use strict";function b(g){return s.reset(),g.each(function(b){var g=d3.select(this);a.utils.initSVG(g);var p=g.selectAll("g.nv-wrap.nv-axis").data([b]),q=p.enter().append("g").attr("class","nvd3 nv-wrap nv-axis"),t=(q.append("g"),p.select("g"));null!==n?c.ticks(n):("top"==c.orient()||"bottom"==c.orient())&&c.ticks(Math.abs(d.range()[1]-d.range()[0])/100),t.watchTransition(s,"axis").call(c),r=r||c.scale();var u=c.tickFormat();null==u&&(u=r.tickFormat());var v=t.selectAll("text.nv-axislabel").data([h||null]);v.exit().remove();var w,x,y;switch(c.orient()){case"top":v.enter().append("text").attr("class","nv-axislabel"),y=d.range().length<2?0:2===d.range().length?d.range()[1]:d.range()[d.range().length-1]+(d.range()[1]-d.range()[0]),v.attr("text-anchor","middle").attr("y",0).attr("x",y/2),i&&(x=p.selectAll("g.nv-axisMaxMin").data(d.domain()),x.enter().append("g").attr("class",function(a,b){return["nv-axisMaxMin","nv-axisMaxMin-x",0==b?"nv-axisMin-x":"nv-axisMax-x"].join(" ")}).append("text"),x.exit().remove(),x.attr("transform",function(b){return"translate("+a.utils.NaNtoZero(d(b))+",0)"}).select("text").attr("dy","-0.5em").attr("y",-c.tickPadding()).attr("text-anchor","middle").text(function(a){var b=u(a);return(""+b).match("NaN")?"":b}),x.watchTransition(s,"min-max top").attr("transform",function(b,c){return"translate("+a.utils.NaNtoZero(d.range()[c])+",0)"}));break;case"bottom":w=o+36;var z=30,A=0,B=t.selectAll("g").select("text"),C="";if(j%360){B.each(function(){var a=this.getBoundingClientRect(),b=a.width;A=a.height,b>z&&(z=b)}),C="rotate("+j+" 0,"+(A/2+c.tickPadding())+")";var D=Math.abs(Math.sin(j*Math.PI/180));w=(D?D*z:z)+30,B.attr("transform",C).style("text-anchor",j%360>0?"start":"end")}v.enter().append("text").attr("class","nv-axislabel"),y=d.range().length<2?0:2===d.range().length?d.range()[1]:d.range()[d.range().length-1]+(d.range()[1]-d.range()[0]),v.attr("text-anchor","middle").attr("y",w).attr("x",y/2),i&&(x=p.selectAll("g.nv-axisMaxMin").data([d.domain()[0],d.domain()[d.domain().length-1]]),x.enter().append("g").attr("class",function(a,b){return["nv-axisMaxMin","nv-axisMaxMin-x",0==b?"nv-axisMin-x":"nv-axisMax-x"].join(" ")}).append("text"),x.exit().remove(),x.attr("transform",function(b){return"translate("+a.utils.NaNtoZero(d(b)+(m?d.rangeBand()/2:0))+",0)"}).select("text").attr("dy",".71em").attr("y",c.tickPadding()).attr("transform",C).style("text-anchor",j?j%360>0?"start":"end":"middle").text(function(a){var b=u(a);return(""+b).match("NaN")?"":b}),x.watchTransition(s,"min-max bottom").attr("transform",function(b){return"translate("+a.utils.NaNtoZero(d(b)+(m?d.rangeBand()/2:0))+",0)"})),l&&B.attr("transform",function(a,b){return"translate(0,"+(b%2==0?"0":"12")+")"});break;case"right":v.enter().append("text").attr("class","nv-axislabel"),v.style("text-anchor",k?"middle":"begin").attr("transform",k?"rotate(90)":"").attr("y",k?-Math.max(e.right,f)+12:-10).attr("x",k?d3.max(d.range())/2:c.tickPadding()),i&&(x=p.selectAll("g.nv-axisMaxMin").data(d.domain()),x.enter().append("g").attr("class",function(a,b){return["nv-axisMaxMin","nv-axisMaxMin-y",0==b?"nv-axisMin-y":"nv-axisMax-y"].join(" ")}).append("text").style("opacity",0),x.exit().remove(),x.attr("transform",function(b){return"translate(0,"+a.utils.NaNtoZero(d(b))+")"}).select("text").attr("dy",".32em").attr("y",0).attr("x",c.tickPadding()).style("text-anchor","start").text(function(a){var b=u(a);return(""+b).match("NaN")?"":b}),x.watchTransition(s,"min-max right").attr("transform",function(b,c){return"translate(0,"+a.utils.NaNtoZero(d.range()[c])+")"}).select("text").style("opacity",1));break;case"left":v.enter().append("text").attr("class","nv-axislabel"),v.style("text-anchor",k?"middle":"end").attr("transform",k?"rotate(-90)":"").attr("y",k?-Math.max(e.left,f)+25-(o||0):-10).attr("x",k?-d3.max(d.range())/2:-c.tickPadding()),i&&(x=p.selectAll("g.nv-axisMaxMin").data(d.domain()),x.enter().append("g").attr("class",function(a,b){return["nv-axisMaxMin","nv-axisMaxMin-y",0==b?"nv-axisMin-y":"nv-axisMax-y"].join(" ")}).append("text").style("opacity",0),x.exit().remove(),x.attr("transform",function(b){return"translate(0,"+a.utils.NaNtoZero(r(b))+")"}).select("text").attr("dy",".32em").attr("y",0).attr("x",-c.tickPadding()).attr("text-anchor","end").text(function(a){var b=u(a);return(""+b).match("NaN")?"":b}),x.watchTransition(s,"min-max right").attr("transform",function(b,c){return"translate(0,"+a.utils.NaNtoZero(d.range()[c])+")"}).select("text").style("opacity",1))}if(v.text(function(a){return a}),!i||"left"!==c.orient()&&"right"!==c.orient()||(t.selectAll("g").each(function(a){d3.select(this).select("text").attr("opacity",1),(d(a)d.range()[0]-10)&&((a>1e-10||-1e-10>a)&&d3.select(this).attr("opacity",0),d3.select(this).select("text").attr("opacity",0))}),d.domain()[0]==d.domain()[1]&&0==d.domain()[0]&&p.selectAll("g.nv-axisMaxMin").style("opacity",function(a,b){return b?0:1})),i&&("top"===c.orient()||"bottom"===c.orient())){var E=[];p.selectAll("g.nv-axisMaxMin").each(function(a,b){try{E.push(b?d(a)-this.getBoundingClientRect().width-4:d(a)+this.getBoundingClientRect().width+4)}catch(c){E.push(b?d(a)-4:d(a)+4)}}),t.selectAll("g").each(function(a){(d(a)E[1])&&(a>1e-10||-1e-10>a?d3.select(this).remove():d3.select(this).select("text").remove())})}t.selectAll(".tick").filter(function(a){return!parseFloat(Math.round(1e5*a)/1e6)&&void 0!==a}).classed("zero",!0),r=d.copy()}),s.renderEnd("axis immediate"),b}var c=d3.svg.axis(),d=d3.scale.linear(),e={top:0,right:0,bottom:0,left:0},f=75,g=60,h=null,i=!0,j=0,k=!0,l=!1,m=!1,n=null,o=0,p=250,q=d3.dispatch("renderEnd");c.scale(d).orient("bottom").tickFormat(function(a){return a});var r,s=a.utils.renderWatch(q,p);return b.axis=c,b.dispatch=q,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{axisLabelDistance:{get:function(){return o},set:function(a){o=a}},staggerLabels:{get:function(){return l},set:function(a){l=a}},rotateLabels:{get:function(){return j},set:function(a){j=a}},rotateYLabel:{get:function(){return k},set:function(a){k=a}},showMaxMin:{get:function(){return i},set:function(a){i=a}},axisLabel:{get:function(){return h},set:function(a){h=a}},height:{get:function(){return g},set:function(a){g=a}},ticks:{get:function(){return n},set:function(a){n=a}},width:{get:function(){return f},set:function(a){f=a}},margin:{get:function(){return e},set:function(a){e.top=void 0!==a.top?a.top:e.top,e.right=void 0!==a.right?a.right:e.right,e.bottom=void 0!==a.bottom?a.bottom:e.bottom,e.left=void 0!==a.left?a.left:e.left}},duration:{get:function(){return p},set:function(a){p=a,s.reset(p)}},scale:{get:function(){return d},set:function(e){d=e,c.scale(d),m="function"==typeof d.rangeBands,a.utils.inheritOptionsD3(b,d,["domain","range","rangeBand","rangeBands"])}}}),a.utils.initOptions(b),a.utils.inheritOptionsD3(b,c,["orient","tickValues","tickSubdivide","tickSize","tickPadding","tickFormat"]),a.utils.inheritOptionsD3(b,d,["domain","range","rangeBand","rangeBands"]),b},a.models.boxPlot=function(){"use strict";function b(l){return v.reset(),l.each(function(b){var l=j-i.left-i.right,p=k-i.top-i.bottom;r=d3.select(this),a.utils.initSVG(r),m.domain(c||b.map(function(a,b){return o(a,b)})).rangeBands(e||[0,l],.1);var w=[];if(!d){var x=d3.min(b.map(function(a){var b=[];return b.push(a.values.Q1),a.values.hasOwnProperty("whisker_low")&&null!==a.values.whisker_low&&b.push(a.values.whisker_low),a.values.hasOwnProperty("outliers")&&null!==a.values.outliers&&(b=b.concat(a.values.outliers)),d3.min(b)})),y=d3.max(b.map(function(a){var b=[];return b.push(a.values.Q3),a.values.hasOwnProperty("whisker_high")&&null!==a.values.whisker_high&&b.push(a.values.whisker_high),a.values.hasOwnProperty("outliers")&&null!==a.values.outliers&&(b=b.concat(a.values.outliers)),d3.max(b)}));w=[x,y]}n.domain(d||w),n.range(f||[p,0]),g=g||m,h=h||n.copy().range([n(0),n(0)]);{var z=r.selectAll("g.nv-wrap").data([b]);z.enter().append("g").attr("class","nvd3 nv-wrap")}z.attr("transform","translate("+i.left+","+i.top+")");var A=z.selectAll(".nv-boxplot").data(function(a){return a}),B=A.enter().append("g").style("stroke-opacity",1e-6).style("fill-opacity",1e-6);A.attr("class","nv-boxplot").attr("transform",function(a,b){return"translate("+(m(o(a,b))+.05*m.rangeBand())+", 0)"}).classed("hover",function(a){return a.hover}),A.watchTransition(v,"nv-boxplot: boxplots").style("stroke-opacity",1).style("fill-opacity",.75).delay(function(a,c){return c*t/b.length}).attr("transform",function(a,b){return"translate("+(m(o(a,b))+.05*m.rangeBand())+", 0)"}),A.exit().remove(),B.each(function(a,b){var c=d3.select(this);["low","high"].forEach(function(d){a.values.hasOwnProperty("whisker_"+d)&&null!==a.values["whisker_"+d]&&(c.append("line").style("stroke",a.color?a.color:q(a,b)).attr("class","nv-boxplot-whisker nv-boxplot-"+d),c.append("line").style("stroke",a.color?a.color:q(a,b)).attr("class","nv-boxplot-tick nv-boxplot-"+d))})});var C=A.selectAll(".nv-boxplot-outlier").data(function(a){return a.values.hasOwnProperty("outliers")&&null!==a.values.outliers?a.values.outliers:[]});C.enter().append("circle").style("fill",function(a,b,c){return q(a,c)}).style("stroke",function(a,b,c){return q(a,c)}).on("mouseover",function(a,b,c){d3.select(this).classed("hover",!0),s.elementMouseover({series:{key:a,color:q(a,c)},e:d3.event})}).on("mouseout",function(a,b,c){d3.select(this).classed("hover",!1),s.elementMouseout({series:{key:a,color:q(a,c)},e:d3.event})}).on("mousemove",function(){s.elementMousemove({e:d3.event})}),C.attr("class","nv-boxplot-outlier"),C.watchTransition(v,"nv-boxplot: nv-boxplot-outlier").attr("cx",.45*m.rangeBand()).attr("cy",function(a){return n(a)}).attr("r","3"),C.exit().remove();var D=function(){return null===u?.9*m.rangeBand():Math.min(75,.9*m.rangeBand())},E=function(){return.45*m.rangeBand()-D()/2},F=function(){return.45*m.rangeBand()+D()/2};["low","high"].forEach(function(a){var b="low"===a?"Q1":"Q3";A.select("line.nv-boxplot-whisker.nv-boxplot-"+a).watchTransition(v,"nv-boxplot: boxplots").attr("x1",.45*m.rangeBand()).attr("y1",function(b){return n(b.values["whisker_"+a])}).attr("x2",.45*m.rangeBand()).attr("y2",function(a){return n(a.values[b])}),A.select("line.nv-boxplot-tick.nv-boxplot-"+a).watchTransition(v,"nv-boxplot: boxplots").attr("x1",E).attr("y1",function(b){return n(b.values["whisker_"+a])}).attr("x2",F).attr("y2",function(b){return n(b.values["whisker_"+a])})}),["low","high"].forEach(function(a){B.selectAll(".nv-boxplot-"+a).on("mouseover",function(b,c,d){d3.select(this).classed("hover",!0),s.elementMouseover({series:{key:b.values["whisker_"+a],color:q(b,d)},e:d3.event})}).on("mouseout",function(b,c,d){d3.select(this).classed("hover",!1),s.elementMouseout({series:{key:b.values["whisker_"+a],color:q(b,d)},e:d3.event})}).on("mousemove",function(){s.elementMousemove({e:d3.event})})}),B.append("rect").attr("class","nv-boxplot-box").on("mouseover",function(a,b){d3.select(this).classed("hover",!0),s.elementMouseover({key:a.label,value:a.label,series:[{key:"Q3",value:a.values.Q3,color:a.color||q(a,b)},{key:"Q2",value:a.values.Q2,color:a.color||q(a,b)},{key:"Q1",value:a.values.Q1,color:a.color||q(a,b)}],data:a,index:b,e:d3.event})}).on("mouseout",function(a,b){d3.select(this).classed("hover",!1),s.elementMouseout({key:a.label,value:a.label,series:[{key:"Q3",value:a.values.Q3,color:a.color||q(a,b)},{key:"Q2",value:a.values.Q2,color:a.color||q(a,b)},{key:"Q1",value:a.values.Q1,color:a.color||q(a,b)}],data:a,index:b,e:d3.event})}).on("mousemove",function(){s.elementMousemove({e:d3.event})}),A.select("rect.nv-boxplot-box").watchTransition(v,"nv-boxplot: boxes").attr("y",function(a){return n(a.values.Q3)}).attr("width",D).attr("x",E).attr("height",function(a){return Math.abs(n(a.values.Q3)-n(a.values.Q1))||1}).style("fill",function(a,b){return a.color||q(a,b)}).style("stroke",function(a,b){return a.color||q(a,b)}),B.append("line").attr("class","nv-boxplot-median"),A.select("line.nv-boxplot-median").watchTransition(v,"nv-boxplot: boxplots line").attr("x1",E).attr("y1",function(a){return n(a.values.Q2)}).attr("x2",F).attr("y2",function(a){return n(a.values.Q2)}),g=m.copy(),h=n.copy()}),v.renderEnd("nv-boxplot immediate"),b}var c,d,e,f,g,h,i={top:0,right:0,bottom:0,left:0},j=960,k=500,l=Math.floor(1e4*Math.random()),m=d3.scale.ordinal(),n=d3.scale.linear(),o=function(a){return a.x},p=function(a){return a.y},q=a.utils.defaultColor(),r=null,s=d3.dispatch("elementMouseover","elementMouseout","elementMousemove","renderEnd"),t=250,u=null,v=a.utils.renderWatch(s,t);return b.dispatch=s,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return j},set:function(a){j=a}},height:{get:function(){return k},set:function(a){k=a}},maxBoxWidth:{get:function(){return u},set:function(a){u=a}},x:{get:function(){return o},set:function(a){o=a}},y:{get:function(){return p},set:function(a){p=a}},xScale:{get:function(){return m},set:function(a){m=a}},yScale:{get:function(){return n},set:function(a){n=a}},xDomain:{get:function(){return c},set:function(a){c=a}},yDomain:{get:function(){return d},set:function(a){d=a}},xRange:{get:function(){return e},set:function(a){e=a}},yRange:{get:function(){return f},set:function(a){f=a}},id:{get:function(){return l},set:function(a){l=a}},margin:{get:function(){return i},set:function(a){i.top=void 0!==a.top?a.top:i.top,i.right=void 0!==a.right?a.right:i.right,i.bottom=void 0!==a.bottom?a.bottom:i.bottom,i.left=void 0!==a.left?a.left:i.left}},color:{get:function(){return q},set:function(b){q=a.utils.getColor(b)}},duration:{get:function(){return t},set:function(a){t=a,v.reset(t)}}}),a.utils.initOptions(b),b},a.models.boxPlotChart=function(){"use strict";function b(k){return t.reset(),t.models(e),l&&t.models(f),m&&t.models(g),k.each(function(k){var p=d3.select(this);a.utils.initSVG(p);var t=(i||parseInt(p.style("width"))||960)-h.left-h.right,u=(j||parseInt(p.style("height"))||400)-h.top-h.bottom;if(b.update=function(){r.beforeUpdate(),p.transition().duration(s).call(b)},b.container=this,!(k&&k.length&&k.filter(function(a){return a.values.hasOwnProperty("Q1")&&a.values.hasOwnProperty("Q2")&&a.values.hasOwnProperty("Q3")}).length)){var v=p.selectAll(".nv-noData").data([q]);return v.enter().append("text").attr("class","nvd3 nv-noData").attr("dy","-.7em").style("text-anchor","middle"),v.attr("x",h.left+t/2).attr("y",h.top+u/2).text(function(a){return a}),b}p.selectAll(".nv-noData").remove(),c=e.xScale(),d=e.yScale().clamp(!0);var w=p.selectAll("g.nv-wrap.nv-boxPlotWithAxes").data([k]),x=w.enter().append("g").attr("class","nvd3 nv-wrap nv-boxPlotWithAxes").append("g"),y=x.append("defs"),z=w.select("g"); -x.append("g").attr("class","nv-x nv-axis"),x.append("g").attr("class","nv-y nv-axis").append("g").attr("class","nv-zeroLine").append("line"),x.append("g").attr("class","nv-barsWrap"),z.attr("transform","translate("+h.left+","+h.top+")"),n&&z.select(".nv-y.nv-axis").attr("transform","translate("+t+",0)"),e.width(t).height(u);var A=z.select(".nv-barsWrap").datum(k.filter(function(a){return!a.disabled}));if(A.transition().call(e),y.append("clipPath").attr("id","nv-x-label-clip-"+e.id()).append("rect"),z.select("#nv-x-label-clip-"+e.id()+" rect").attr("width",c.rangeBand()*(o?2:1)).attr("height",16).attr("x",-c.rangeBand()/(o?1:2)),l){f.scale(c).ticks(a.utils.calcTicksX(t/100,k)).tickSize(-u,0),z.select(".nv-x.nv-axis").attr("transform","translate(0,"+d.range()[0]+")"),z.select(".nv-x.nv-axis").call(f);var B=z.select(".nv-x.nv-axis").selectAll("g");o&&B.selectAll("text").attr("transform",function(a,b,c){return"translate(0,"+(c%2==0?"5":"17")+")"})}m&&(g.scale(d).ticks(Math.floor(u/36)).tickSize(-t,0),z.select(".nv-y.nv-axis").call(g)),z.select(".nv-zeroLine line").attr("x1",0).attr("x2",t).attr("y1",d(0)).attr("y2",d(0))}),t.renderEnd("nv-boxplot chart immediate"),b}var c,d,e=a.models.boxPlot(),f=a.models.axis(),g=a.models.axis(),h={top:15,right:10,bottom:50,left:60},i=null,j=null,k=a.utils.getColor(),l=!0,m=!0,n=!1,o=!1,p=a.models.tooltip(),q="No Data Available.",r=d3.dispatch("tooltipShow","tooltipHide","beforeUpdate","renderEnd"),s=250;f.orient("bottom").showMaxMin(!1).tickFormat(function(a){return a}),g.orient(n?"right":"left").tickFormat(d3.format(",.1f")),p.duration(0);var t=a.utils.renderWatch(r,s);return e.dispatch.on("elementMouseover.tooltip",function(a){p.data(a).hidden(!1)}),e.dispatch.on("elementMouseout.tooltip",function(a){p.data(a).hidden(!0)}),e.dispatch.on("elementMousemove.tooltip",function(){p.position({top:d3.event.pageY,left:d3.event.pageX})()}),b.dispatch=r,b.boxplot=e,b.xAxis=f,b.yAxis=g,b.tooltip=p,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return i},set:function(a){i=a}},height:{get:function(){return j},set:function(a){j=a}},staggerLabels:{get:function(){return o},set:function(a){o=a}},showXAxis:{get:function(){return l},set:function(a){l=a}},showYAxis:{get:function(){return m},set:function(a){m=a}},tooltips:{get:function(){return tooltips},set:function(a){tooltips=a}},tooltipContent:{get:function(){return p},set:function(a){p=a}},noData:{get:function(){return q},set:function(a){q=a}},margin:{get:function(){return h},set:function(a){h.top=void 0!==a.top?a.top:h.top,h.right=void 0!==a.right?a.right:h.right,h.bottom=void 0!==a.bottom?a.bottom:h.bottom,h.left=void 0!==a.left?a.left:h.left}},duration:{get:function(){return s},set:function(a){s=a,t.reset(s),e.duration(s),f.duration(s),g.duration(s)}},color:{get:function(){return k},set:function(b){k=a.utils.getColor(b),e.color(k)}},rightAlignYAxis:{get:function(){return n},set:function(a){n=a,g.orient(a?"right":"left")}}}),a.utils.inheritOptions(b,e),a.utils.initOptions(b),b},a.models.bullet=function(){"use strict";function b(d){return d.each(function(b,d){var p=m-c.left-c.right,s=n-c.top-c.bottom;o=d3.select(this),a.utils.initSVG(o);{var t=f.call(this,b,d).slice().sort(d3.descending),u=g.call(this,b,d).slice().sort(d3.descending),v=h.call(this,b,d).slice().sort(d3.descending),w=i.call(this,b,d).slice(),x=j.call(this,b,d).slice(),y=k.call(this,b,d).slice(),z=d3.scale.linear().domain(d3.extent(d3.merge([l,t]))).range(e?[p,0]:[0,p]);this.__chart__||d3.scale.linear().domain([0,1/0]).range(z.range())}this.__chart__=z;var A=d3.min(t),B=d3.max(t),C=t[1],D=o.selectAll("g.nv-wrap.nv-bullet").data([b]),E=D.enter().append("g").attr("class","nvd3 nv-wrap nv-bullet"),F=E.append("g"),G=D.select("g");F.append("rect").attr("class","nv-range nv-rangeMax"),F.append("rect").attr("class","nv-range nv-rangeAvg"),F.append("rect").attr("class","nv-range nv-rangeMin"),F.append("rect").attr("class","nv-measure"),D.attr("transform","translate("+c.left+","+c.top+")");var H=function(a){return Math.abs(z(a)-z(0))},I=function(a){return z(0>a?a:0)};G.select("rect.nv-rangeMax").attr("height",s).attr("width",H(B>0?B:A)).attr("x",I(B>0?B:A)).datum(B>0?B:A),G.select("rect.nv-rangeAvg").attr("height",s).attr("width",H(C)).attr("x",I(C)).datum(C),G.select("rect.nv-rangeMin").attr("height",s).attr("width",H(B)).attr("x",I(B)).attr("width",H(B>0?A:B)).attr("x",I(B>0?A:B)).datum(B>0?A:B),G.select("rect.nv-measure").style("fill",q).attr("height",s/3).attr("y",s/3).attr("width",0>v?z(0)-z(v[0]):z(v[0])-z(0)).attr("x",I(v)).on("mouseover",function(){r.elementMouseover({value:v[0],label:y[0]||"Current",color:d3.select(this).style("fill")})}).on("mousemove",function(){r.elementMousemove({value:v[0],label:y[0]||"Current",color:d3.select(this).style("fill")})}).on("mouseout",function(){r.elementMouseout({value:v[0],label:y[0]||"Current",color:d3.select(this).style("fill")})});var J=s/6,K=u.map(function(a,b){return{value:a,label:x[b]}});F.selectAll("path.nv-markerTriangle").data(K).enter().append("path").attr("class","nv-markerTriangle").attr("transform",function(a){return"translate("+z(a.value)+","+s/2+")"}).attr("d","M0,"+J+"L"+J+","+-J+" "+-J+","+-J+"Z").on("mouseover",function(a){r.elementMouseover({value:a.value,label:a.label||"Previous",color:d3.select(this).style("fill"),pos:[z(a.value),s/2]})}).on("mousemove",function(a){r.elementMousemove({value:a.value,label:a.label||"Previous",color:d3.select(this).style("fill")})}).on("mouseout",function(a){r.elementMouseout({value:a.value,label:a.label||"Previous",color:d3.select(this).style("fill")})}),D.selectAll(".nv-range").on("mouseover",function(a,b){var c=w[b]||(b?1==b?"Mean":"Minimum":"Maximum");r.elementMouseover({value:a,label:c,color:d3.select(this).style("fill")})}).on("mousemove",function(){r.elementMousemove({value:v[0],label:y[0]||"Previous",color:d3.select(this).style("fill")})}).on("mouseout",function(a,b){var c=w[b]||(b?1==b?"Mean":"Minimum":"Maximum");r.elementMouseout({value:a,label:c,color:d3.select(this).style("fill")})})}),b}var c={top:0,right:0,bottom:0,left:0},d="left",e=!1,f=function(a){return a.ranges},g=function(a){return a.markers?a.markers:[0]},h=function(a){return a.measures},i=function(a){return a.rangeLabels?a.rangeLabels:[]},j=function(a){return a.markerLabels?a.markerLabels:[]},k=function(a){return a.measureLabels?a.measureLabels:[]},l=[0],m=380,n=30,o=null,p=null,q=a.utils.getColor(["#1f77b4"]),r=d3.dispatch("elementMouseover","elementMouseout","elementMousemove");return b.dispatch=r,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{ranges:{get:function(){return f},set:function(a){f=a}},markers:{get:function(){return g},set:function(a){g=a}},measures:{get:function(){return h},set:function(a){h=a}},forceX:{get:function(){return l},set:function(a){l=a}},width:{get:function(){return m},set:function(a){m=a}},height:{get:function(){return n},set:function(a){n=a}},tickFormat:{get:function(){return p},set:function(a){p=a}},margin:{get:function(){return c},set:function(a){c.top=void 0!==a.top?a.top:c.top,c.right=void 0!==a.right?a.right:c.right,c.bottom=void 0!==a.bottom?a.bottom:c.bottom,c.left=void 0!==a.left?a.left:c.left}},orient:{get:function(){return d},set:function(a){d=a,e="right"==d||"bottom"==d}},color:{get:function(){return q},set:function(b){q=a.utils.getColor(b)}}}),a.utils.initOptions(b),b},a.models.bulletChart=function(){"use strict";function b(d){return d.each(function(e,o){var p=d3.select(this);a.utils.initSVG(p);var q=a.utils.availableWidth(k,p,g),r=l-g.top-g.bottom;if(b.update=function(){b(d)},b.container=this,!e||!h.call(this,e,o))return a.utils.noData(b,p),b;p.selectAll(".nv-noData").remove();var s=h.call(this,e,o).slice().sort(d3.descending),t=i.call(this,e,o).slice().sort(d3.descending),u=j.call(this,e,o).slice().sort(d3.descending),v=p.selectAll("g.nv-wrap.nv-bulletChart").data([e]),w=v.enter().append("g").attr("class","nvd3 nv-wrap nv-bulletChart"),x=w.append("g"),y=v.select("g");x.append("g").attr("class","nv-bulletWrap"),x.append("g").attr("class","nv-titles"),v.attr("transform","translate("+g.left+","+g.top+")");var z=d3.scale.linear().domain([0,Math.max(s[0],t[0],u[0])]).range(f?[q,0]:[0,q]),A=this.__chart__||d3.scale.linear().domain([0,1/0]).range(z.range());this.__chart__=z;var B=x.select(".nv-titles").append("g").attr("text-anchor","end").attr("transform","translate(-6,"+(l-g.top-g.bottom)/2+")");B.append("text").attr("class","nv-title").text(function(a){return a.title}),B.append("text").attr("class","nv-subtitle").attr("dy","1em").text(function(a){return a.subtitle}),c.width(q).height(r);var C=y.select(".nv-bulletWrap");d3.transition(C).call(c);var D=m||z.tickFormat(q/100),E=y.selectAll("g.nv-tick").data(z.ticks(n?n:q/50),function(a){return this.textContent||D(a)}),F=E.enter().append("g").attr("class","nv-tick").attr("transform",function(a){return"translate("+A(a)+",0)"}).style("opacity",1e-6);F.append("line").attr("y1",r).attr("y2",7*r/6),F.append("text").attr("text-anchor","middle").attr("dy","1em").attr("y",7*r/6).text(D);var G=d3.transition(E).attr("transform",function(a){return"translate("+z(a)+",0)"}).style("opacity",1);G.select("line").attr("y1",r).attr("y2",7*r/6),G.select("text").attr("y",7*r/6),d3.transition(E.exit()).attr("transform",function(a){return"translate("+z(a)+",0)"}).style("opacity",1e-6).remove()}),d3.timer.flush(),b}var c=a.models.bullet(),d=a.models.tooltip(),e="left",f=!1,g={top:5,right:40,bottom:20,left:120},h=function(a){return a.ranges},i=function(a){return a.markers?a.markers:[0]},j=function(a){return a.measures},k=null,l=55,m=null,n=null,o=null,p=d3.dispatch("tooltipShow","tooltipHide");return d.duration(0).headerEnabled(!1),c.dispatch.on("elementMouseover.tooltip",function(a){a.series={key:a.label,value:a.value,color:a.color},d.data(a).hidden(!1)}),c.dispatch.on("elementMouseout.tooltip",function(){d.hidden(!0)}),c.dispatch.on("elementMousemove.tooltip",function(){d.position({top:d3.event.pageY,left:d3.event.pageX})()}),b.bullet=c,b.dispatch=p,b.tooltip=d,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{ranges:{get:function(){return h},set:function(a){h=a}},markers:{get:function(){return i},set:function(a){i=a}},measures:{get:function(){return j},set:function(a){j=a}},width:{get:function(){return k},set:function(a){k=a}},height:{get:function(){return l},set:function(a){l=a}},tickFormat:{get:function(){return m},set:function(a){m=a}},ticks:{get:function(){return n},set:function(a){n=a}},noData:{get:function(){return o},set:function(a){o=a}},tooltips:{get:function(){return d.enabled()},set:function(b){a.deprecated("tooltips","use chart.tooltip.enabled() instead"),d.enabled(!!b)}},tooltipContent:{get:function(){return d.contentGenerator()},set:function(b){a.deprecated("tooltipContent","use chart.tooltip.contentGenerator() instead"),d.contentGenerator(b)}},margin:{get:function(){return g},set:function(a){g.top=void 0!==a.top?a.top:g.top,g.right=void 0!==a.right?a.right:g.right,g.bottom=void 0!==a.bottom?a.bottom:g.bottom,g.left=void 0!==a.left?a.left:g.left}},orient:{get:function(){return e},set:function(a){e=a,f="right"==e||"bottom"==e}}}),a.utils.inheritOptions(b,c),a.utils.initOptions(b),b},a.models.candlestickBar=function(){"use strict";function b(x){return x.each(function(b){c=d3.select(this);var x=a.utils.availableWidth(i,c,h),y=a.utils.availableHeight(j,c,h);a.utils.initSVG(c);var A=x/b[0].values.length*.45;l.domain(d||d3.extent(b[0].values.map(n).concat(t))),l.range(v?f||[.5*x/b[0].values.length,x*(b[0].values.length-.5)/b[0].values.length]:f||[5+A/2,x-A/2-5]),m.domain(e||[d3.min(b[0].values.map(s).concat(u)),d3.max(b[0].values.map(r).concat(u))]).range(g||[y,0]),l.domain()[0]===l.domain()[1]&&l.domain(l.domain()[0]?[l.domain()[0]-.01*l.domain()[0],l.domain()[1]+.01*l.domain()[1]]:[-1,1]),m.domain()[0]===m.domain()[1]&&m.domain(m.domain()[0]?[m.domain()[0]+.01*m.domain()[0],m.domain()[1]-.01*m.domain()[1]]:[-1,1]);var B=d3.select(this).selectAll("g.nv-wrap.nv-candlestickBar").data([b[0].values]),C=B.enter().append("g").attr("class","nvd3 nv-wrap nv-candlestickBar"),D=C.append("defs"),E=C.append("g"),F=B.select("g");E.append("g").attr("class","nv-ticks"),B.attr("transform","translate("+h.left+","+h.top+")"),c.on("click",function(a,b){z.chartClick({data:a,index:b,pos:d3.event,id:k})}),D.append("clipPath").attr("id","nv-chart-clip-path-"+k).append("rect"),B.select("#nv-chart-clip-path-"+k+" rect").attr("width",x).attr("height",y),F.attr("clip-path",w?"url(#nv-chart-clip-path-"+k+")":"");var G=B.select(".nv-ticks").selectAll(".nv-tick").data(function(a){return a});G.exit().remove();{var H=G.enter().append("g").attr("class",function(a,b,c){return(p(a,b)>q(a,b)?"nv-tick negative":"nv-tick positive")+" nv-tick-"+c+"-"+b});H.append("line").attr("class","nv-candlestick-lines").attr("transform",function(a,b){return"translate("+l(n(a,b))+",0)"}).attr("x1",0).attr("y1",function(a,b){return m(r(a,b))}).attr("x2",0).attr("y2",function(a,b){return m(s(a,b))}),H.append("rect").attr("class","nv-candlestick-rects nv-bars").attr("transform",function(a,b){return"translate("+(l(n(a,b))-A/2)+","+(m(o(a,b))-(p(a,b)>q(a,b)?m(q(a,b))-m(p(a,b)):0))+")"}).attr("x",0).attr("y",0).attr("width",A).attr("height",function(a,b){var c=p(a,b),d=q(a,b);return c>d?m(d)-m(c):m(c)-m(d)})}c.selectAll(".nv-candlestick-lines").transition().attr("transform",function(a,b){return"translate("+l(n(a,b))+",0)"}).attr("x1",0).attr("y1",function(a,b){return m(r(a,b))}).attr("x2",0).attr("y2",function(a,b){return m(s(a,b))}),c.selectAll(".nv-candlestick-rects").transition().attr("transform",function(a,b){return"translate("+(l(n(a,b))-A/2)+","+(m(o(a,b))-(p(a,b)>q(a,b)?m(q(a,b))-m(p(a,b)):0))+")"}).attr("x",0).attr("y",0).attr("width",A).attr("height",function(a,b){var c=p(a,b),d=q(a,b);return c>d?m(d)-m(c):m(c)-m(d)})}),b}var c,d,e,f,g,h={top:0,right:0,bottom:0,left:0},i=null,j=null,k=Math.floor(1e4*Math.random()),l=d3.scale.linear(),m=d3.scale.linear(),n=function(a){return a.x},o=function(a){return a.y},p=function(a){return a.open},q=function(a){return a.close},r=function(a){return a.high},s=function(a){return a.low},t=[],u=[],v=!1,w=!0,x=a.utils.defaultColor(),y=!1,z=d3.dispatch("tooltipShow","tooltipHide","stateChange","changeState","renderEnd","chartClick","elementClick","elementDblClick","elementMouseover","elementMouseout","elementMousemove");return b.highlightPoint=function(a,d){b.clearHighlights(),c.select(".nv-candlestickBar .nv-tick-0-"+a).classed("hover",d)},b.clearHighlights=function(){c.select(".nv-candlestickBar .nv-tick.hover").classed("hover",!1)},b.dispatch=z,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return i},set:function(a){i=a}},height:{get:function(){return j},set:function(a){j=a}},xScale:{get:function(){return l},set:function(a){l=a}},yScale:{get:function(){return m},set:function(a){m=a}},xDomain:{get:function(){return d},set:function(a){d=a}},yDomain:{get:function(){return e},set:function(a){e=a}},xRange:{get:function(){return f},set:function(a){f=a}},yRange:{get:function(){return g},set:function(a){g=a}},forceX:{get:function(){return t},set:function(a){t=a}},forceY:{get:function(){return u},set:function(a){u=a}},padData:{get:function(){return v},set:function(a){v=a}},clipEdge:{get:function(){return w},set:function(a){w=a}},id:{get:function(){return k},set:function(a){k=a}},interactive:{get:function(){return y},set:function(a){y=a}},x:{get:function(){return n},set:function(a){n=a}},y:{get:function(){return o},set:function(a){o=a}},open:{get:function(){return p()},set:function(a){p=a}},close:{get:function(){return q()},set:function(a){q=a}},high:{get:function(){return r},set:function(a){r=a}},low:{get:function(){return s},set:function(a){s=a}},margin:{get:function(){return h},set:function(a){h.top=void 0!=a.top?a.top:h.top,h.right=void 0!=a.right?a.right:h.right,h.bottom=void 0!=a.bottom?a.bottom:h.bottom,h.left=void 0!=a.left?a.left:h.left}},color:{get:function(){return x},set:function(b){x=a.utils.getColor(b)}}}),a.utils.initOptions(b),b},a.models.cumulativeLineChart=function(){"use strict";function b(l){return H.reset(),H.models(f),r&&H.models(g),s&&H.models(h),l.each(function(l){function A(){d3.select(b.container).style("cursor","ew-resize")}function E(){G.x=d3.event.x,G.i=Math.round(F.invert(G.x)),K()}function H(){d3.select(b.container).style("cursor","auto"),y.index=G.i,C.stateChange(y)}function K(){bb.data([G]);var a=b.duration();b.duration(0),b.update(),b.duration(a)}var L=d3.select(this);a.utils.initSVG(L),L.classed("nv-chart-"+x,!0);var M=this,N=a.utils.availableWidth(o,L,m),O=a.utils.availableHeight(p,L,m);if(b.update=function(){0===D?L.call(b):L.transition().duration(D).call(b)},b.container=this,y.setter(J(l),b.update).getter(I(l)).update(),y.disabled=l.map(function(a){return!!a.disabled}),!z){var P;z={};for(P in y)z[P]=y[P]instanceof Array?y[P].slice(0):y[P]}var Q=d3.behavior.drag().on("dragstart",A).on("drag",E).on("dragend",H);if(!(l&&l.length&&l.filter(function(a){return a.values.length}).length))return a.utils.noData(b,L),b;if(L.selectAll(".nv-noData").remove(),d=f.xScale(),e=f.yScale(),w)f.yDomain(null);else{var R=l.filter(function(a){return!a.disabled}).map(function(a){var b=d3.extent(a.values,f.y());return b[0]<-.95&&(b[0]=-.95),[(b[0]-b[1])/(1+b[1]),(b[1]-b[0])/(1+b[0])]}),S=[d3.min(R,function(a){return a[0]}),d3.max(R,function(a){return a[1]})];f.yDomain(S)}F.domain([0,l[0].values.length-1]).range([0,N]).clamp(!0);var l=c(G.i,l),T=v?"none":"all",U=L.selectAll("g.nv-wrap.nv-cumulativeLine").data([l]),V=U.enter().append("g").attr("class","nvd3 nv-wrap nv-cumulativeLine").append("g"),W=U.select("g");if(V.append("g").attr("class","nv-interactive"),V.append("g").attr("class","nv-x nv-axis").style("pointer-events","none"),V.append("g").attr("class","nv-y nv-axis"),V.append("g").attr("class","nv-background"),V.append("g").attr("class","nv-linesWrap").style("pointer-events",T),V.append("g").attr("class","nv-avgLinesWrap").style("pointer-events","none"),V.append("g").attr("class","nv-legendWrap"),V.append("g").attr("class","nv-controlsWrap"),q&&(i.width(N),W.select(".nv-legendWrap").datum(l).call(i),m.top!=i.height()&&(m.top=i.height(),O=a.utils.availableHeight(p,L,m)),W.select(".nv-legendWrap").attr("transform","translate(0,"+-m.top+")")),u){var X=[{key:"Re-scale y-axis",disabled:!w}];j.width(140).color(["#444","#444","#444"]).rightAlign(!1).margin({top:5,right:0,bottom:5,left:20}),W.select(".nv-controlsWrap").datum(X).attr("transform","translate(0,"+-m.top+")").call(j)}U.attr("transform","translate("+m.left+","+m.top+")"),t&&W.select(".nv-y.nv-axis").attr("transform","translate("+N+",0)");var Y=l.filter(function(a){return a.tempDisabled});U.select(".tempDisabled").remove(),Y.length&&U.append("text").attr("class","tempDisabled").attr("x",N/2).attr("y","-.71em").style("text-anchor","end").text(Y.map(function(a){return a.key}).join(", ")+" values cannot be calculated for this time period."),v&&(k.width(N).height(O).margin({left:m.left,top:m.top}).svgContainer(L).xScale(d),U.select(".nv-interactive").call(k)),V.select(".nv-background").append("rect"),W.select(".nv-background rect").attr("width",N).attr("height",O),f.y(function(a){return a.display.y}).width(N).height(O).color(l.map(function(a,b){return a.color||n(a,b)}).filter(function(a,b){return!l[b].disabled&&!l[b].tempDisabled}));var Z=W.select(".nv-linesWrap").datum(l.filter(function(a){return!a.disabled&&!a.tempDisabled}));Z.call(f),l.forEach(function(a,b){a.seriesIndex=b});var $=l.filter(function(a){return!a.disabled&&!!B(a)}),_=W.select(".nv-avgLinesWrap").selectAll("line").data($,function(a){return a.key}),ab=function(a){var b=e(B(a));return 0>b?0:b>O?O:b};_.enter().append("line").style("stroke-width",2).style("stroke-dasharray","10,10").style("stroke",function(a){return f.color()(a,a.seriesIndex)}).attr("x1",0).attr("x2",N).attr("y1",ab).attr("y2",ab),_.style("stroke-opacity",function(a){var b=e(B(a));return 0>b||b>O?0:1}).attr("x1",0).attr("x2",N).attr("y1",ab).attr("y2",ab),_.exit().remove();var bb=Z.selectAll(".nv-indexLine").data([G]);bb.enter().append("rect").attr("class","nv-indexLine").attr("width",3).attr("x",-2).attr("fill","red").attr("fill-opacity",.5).style("pointer-events","all").call(Q),bb.attr("transform",function(a){return"translate("+F(a.i)+",0)"}).attr("height",O),r&&(g.scale(d)._ticks(a.utils.calcTicksX(N/70,l)).tickSize(-O,0),W.select(".nv-x.nv-axis").attr("transform","translate(0,"+e.range()[0]+")"),W.select(".nv-x.nv-axis").call(g)),s&&(h.scale(e)._ticks(a.utils.calcTicksY(O/36,l)).tickSize(-N,0),W.select(".nv-y.nv-axis").call(h)),W.select(".nv-background rect").on("click",function(){G.x=d3.mouse(this)[0],G.i=Math.round(F.invert(G.x)),y.index=G.i,C.stateChange(y),K()}),f.dispatch.on("elementClick",function(a){G.i=a.pointIndex,G.x=F(G.i),y.index=G.i,C.stateChange(y),K()}),j.dispatch.on("legendClick",function(a){a.disabled=!a.disabled,w=!a.disabled,y.rescaleY=w,C.stateChange(y),b.update()}),i.dispatch.on("stateChange",function(a){for(var c in a)y[c]=a[c];C.stateChange(y),b.update()}),k.dispatch.on("elementMousemove",function(c){f.clearHighlights();var d,e,i,j=[];if(l.filter(function(a,b){return a.seriesIndex=b,!a.disabled}).forEach(function(g,h){e=a.interactiveBisect(g.values,c.pointXValue,b.x()),f.highlightPoint(h,e,!0);var k=g.values[e];"undefined"!=typeof k&&("undefined"==typeof d&&(d=k),"undefined"==typeof i&&(i=b.xScale()(b.x()(k,e))),j.push({key:g.key,value:b.y()(k,e),color:n(g,g.seriesIndex)}))}),j.length>2){var o=b.yScale().invert(c.mouseY),p=Math.abs(b.yScale().domain()[0]-b.yScale().domain()[1]),q=.03*p,r=a.nearestValueIndex(j.map(function(a){return a.value}),o,q);null!==r&&(j[r].highlight=!0)}var s=g.tickFormat()(b.x()(d,e),e);k.tooltip.position({left:i+m.left,top:c.mouseY+m.top}).chartContainer(M.parentNode).valueFormatter(function(a){return h.tickFormat()(a)}).data({value:s,series:j})(),k.renderGuideLine(i)}),k.dispatch.on("elementMouseout",function(){f.clearHighlights()}),C.on("changeState",function(a){"undefined"!=typeof a.disabled&&(l.forEach(function(b,c){b.disabled=a.disabled[c]}),y.disabled=a.disabled),"undefined"!=typeof a.index&&(G.i=a.index,G.x=F(G.i),y.index=a.index,bb.data([G])),"undefined"!=typeof a.rescaleY&&(w=a.rescaleY),b.update()})}),H.renderEnd("cumulativeLineChart immediate"),b}function c(a,b){return K||(K=f.y()),b.map(function(b){if(!b.values)return b;var c=b.values[a];if(null==c)return b;var d=K(c,a);return-.95>d&&!E?(b.tempDisabled=!0,b):(b.tempDisabled=!1,b.values=b.values.map(function(a,b){return a.display={y:(K(a,b)-d)/(1+d)},a}),b)})}var d,e,f=a.models.line(),g=a.models.axis(),h=a.models.axis(),i=a.models.legend(),j=a.models.legend(),k=a.interactiveGuideline(),l=a.models.tooltip(),m={top:30,right:30,bottom:50,left:60},n=a.utils.defaultColor(),o=null,p=null,q=!0,r=!0,s=!0,t=!1,u=!0,v=!1,w=!0,x=f.id(),y=a.utils.state(),z=null,A=null,B=function(a){return a.average},C=d3.dispatch("stateChange","changeState","renderEnd"),D=250,E=!1;y.index=0,y.rescaleY=w,g.orient("bottom").tickPadding(7),h.orient(t?"right":"left"),l.valueFormatter(function(a,b){return h.tickFormat()(a,b)}).headerFormatter(function(a,b){return g.tickFormat()(a,b)}),j.updateState(!1);var F=d3.scale.linear(),G={i:0,x:0},H=a.utils.renderWatch(C,D),I=function(a){return function(){return{active:a.map(function(a){return!a.disabled}),index:G.i,rescaleY:w}}},J=function(a){return function(b){void 0!==b.index&&(G.i=b.index),void 0!==b.rescaleY&&(w=b.rescaleY),void 0!==b.active&&a.forEach(function(a,c){a.disabled=!b.active[c]})}};f.dispatch.on("elementMouseover.tooltip",function(a){var c={x:b.x()(a.point),y:b.y()(a.point),color:a.point.color};a.point=c,l.data(a).position(a.pos).hidden(!1)}),f.dispatch.on("elementMouseout.tooltip",function(){l.hidden(!0)});var K=null;return b.dispatch=C,b.lines=f,b.legend=i,b.controls=j,b.xAxis=g,b.yAxis=h,b.interactiveLayer=k,b.state=y,b.tooltip=l,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return o},set:function(a){o=a}},height:{get:function(){return p},set:function(a){p=a}},rescaleY:{get:function(){return w},set:function(a){w=a}},showControls:{get:function(){return u},set:function(a){u=a}},showLegend:{get:function(){return q},set:function(a){q=a}},average:{get:function(){return B},set:function(a){B=a}},defaultState:{get:function(){return z},set:function(a){z=a}},noData:{get:function(){return A},set:function(a){A=a}},showXAxis:{get:function(){return r},set:function(a){r=a}},showYAxis:{get:function(){return s},set:function(a){s=a}},noErrorCheck:{get:function(){return E},set:function(a){E=a}},tooltips:{get:function(){return l.enabled()},set:function(b){a.deprecated("tooltips","use chart.tooltip.enabled() instead"),l.enabled(!!b)}},tooltipContent:{get:function(){return l.contentGenerator()},set:function(b){a.deprecated("tooltipContent","use chart.tooltip.contentGenerator() instead"),l.contentGenerator(b)}},margin:{get:function(){return m},set:function(a){m.top=void 0!==a.top?a.top:m.top,m.right=void 0!==a.right?a.right:m.right,m.bottom=void 0!==a.bottom?a.bottom:m.bottom,m.left=void 0!==a.left?a.left:m.left}},color:{get:function(){return n},set:function(b){n=a.utils.getColor(b),i.color(n)}},useInteractiveGuideline:{get:function(){return v},set:function(a){v=a,a===!0&&(b.interactive(!1),b.useVoronoi(!1))}},rightAlignYAxis:{get:function(){return t},set:function(a){t=a,h.orient(a?"right":"left")}},duration:{get:function(){return D},set:function(a){D=a,f.duration(D),g.duration(D),h.duration(D),H.reset(D)}}}),a.utils.inheritOptions(b,f),a.utils.initOptions(b),b},a.models.discreteBar=function(){"use strict";function b(m){return y.reset(),m.each(function(b){var m=k-j.left-j.right,x=l-j.top-j.bottom;c=d3.select(this),a.utils.initSVG(c),b.forEach(function(a,b){a.values.forEach(function(a){a.series=b})});var z=d&&e?[]:b.map(function(a){return a.values.map(function(a,b){return{x:p(a,b),y:q(a,b),y0:a.y0}})});n.domain(d||d3.merge(z).map(function(a){return a.x})).rangeBands(f||[0,m],.1),o.domain(e||d3.extent(d3.merge(z).map(function(a){return a.y}).concat(r))),o.range(t?g||[x-(o.domain()[0]<0?12:0),o.domain()[1]>0?12:0]:g||[x,0]),h=h||n,i=i||o.copy().range([o(0),o(0)]);{var A=c.selectAll("g.nv-wrap.nv-discretebar").data([b]),B=A.enter().append("g").attr("class","nvd3 nv-wrap nv-discretebar"),C=B.append("g");A.select("g")}C.append("g").attr("class","nv-groups"),A.attr("transform","translate("+j.left+","+j.top+")");var D=A.select(".nv-groups").selectAll(".nv-group").data(function(a){return a},function(a){return a.key});D.enter().append("g").style("stroke-opacity",1e-6).style("fill-opacity",1e-6),D.exit().watchTransition(y,"discreteBar: exit groups").style("stroke-opacity",1e-6).style("fill-opacity",1e-6).remove(),D.attr("class",function(a,b){return"nv-group nv-series-"+b}).classed("hover",function(a){return a.hover}),D.watchTransition(y,"discreteBar: groups").style("stroke-opacity",1).style("fill-opacity",.75);var E=D.selectAll("g.nv-bar").data(function(a){return a.values});E.exit().remove();var F=E.enter().append("g").attr("transform",function(a,b){return"translate("+(n(p(a,b))+.05*n.rangeBand())+", "+o(0)+")"}).on("mouseover",function(a,b){d3.select(this).classed("hover",!0),v.elementMouseover({data:a,index:b,color:d3.select(this).style("fill")})}).on("mouseout",function(a,b){d3.select(this).classed("hover",!1),v.elementMouseout({data:a,index:b,color:d3.select(this).style("fill")})}).on("mousemove",function(a,b){v.elementMousemove({data:a,index:b,color:d3.select(this).style("fill")})}).on("click",function(a,b){v.elementClick({data:a,index:b,color:d3.select(this).style("fill")}),d3.event.stopPropagation()}).on("dblclick",function(a,b){v.elementDblClick({data:a,index:b,color:d3.select(this).style("fill")}),d3.event.stopPropagation()});F.append("rect").attr("height",0).attr("width",.9*n.rangeBand()/b.length),t?(F.append("text").attr("text-anchor","middle"),E.select("text").text(function(a,b){return u(q(a,b))}).watchTransition(y,"discreteBar: bars text").attr("x",.9*n.rangeBand()/2).attr("y",function(a,b){return q(a,b)<0?o(q(a,b))-o(0)+12:-4})):E.selectAll("text").remove(),E.attr("class",function(a,b){return q(a,b)<0?"nv-bar negative":"nv-bar positive"}).style("fill",function(a,b){return a.color||s(a,b)}).style("stroke",function(a,b){return a.color||s(a,b)}).select("rect").attr("class",w).watchTransition(y,"discreteBar: bars rect").attr("width",.9*n.rangeBand()/b.length),E.watchTransition(y,"discreteBar: bars").attr("transform",function(a,b){var c=n(p(a,b))+.05*n.rangeBand(),d=q(a,b)<0?o(0):o(0)-o(q(a,b))<1?o(0)-1:o(q(a,b));return"translate("+c+", "+d+")"}).select("rect").attr("height",function(a,b){return Math.max(Math.abs(o(q(a,b))-o(e&&e[0]||0))||1)}),h=n.copy(),i=o.copy()}),y.renderEnd("discreteBar immediate"),b}var c,d,e,f,g,h,i,j={top:0,right:0,bottom:0,left:0},k=960,l=500,m=Math.floor(1e4*Math.random()),n=d3.scale.ordinal(),o=d3.scale.linear(),p=function(a){return a.x},q=function(a){return a.y},r=[0],s=a.utils.defaultColor(),t=!1,u=d3.format(",.2f"),v=d3.dispatch("chartClick","elementClick","elementDblClick","elementMouseover","elementMouseout","elementMousemove","renderEnd"),w="discreteBar",x=250,y=a.utils.renderWatch(v,x);return b.dispatch=v,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return k},set:function(a){k=a}},height:{get:function(){return l},set:function(a){l=a}},forceY:{get:function(){return r},set:function(a){r=a}},showValues:{get:function(){return t},set:function(a){t=a}},x:{get:function(){return p},set:function(a){p=a}},y:{get:function(){return q},set:function(a){q=a}},xScale:{get:function(){return n},set:function(a){n=a}},yScale:{get:function(){return o},set:function(a){o=a}},xDomain:{get:function(){return d},set:function(a){d=a}},yDomain:{get:function(){return e},set:function(a){e=a}},xRange:{get:function(){return f},set:function(a){f=a}},yRange:{get:function(){return g},set:function(a){g=a}},valueFormat:{get:function(){return u},set:function(a){u=a}},id:{get:function(){return m},set:function(a){m=a}},rectClass:{get:function(){return w},set:function(a){w=a}},margin:{get:function(){return j},set:function(a){j.top=void 0!==a.top?a.top:j.top,j.right=void 0!==a.right?a.right:j.right,j.bottom=void 0!==a.bottom?a.bottom:j.bottom,j.left=void 0!==a.left?a.left:j.left}},color:{get:function(){return s},set:function(b){s=a.utils.getColor(b)}},duration:{get:function(){return x},set:function(a){x=a,y.reset(x)}}}),a.utils.initOptions(b),b},a.models.discreteBarChart=function(){"use strict";function b(h){return t.reset(),t.models(e),m&&t.models(f),n&&t.models(g),h.each(function(h){var l=d3.select(this);a.utils.initSVG(l);var q=a.utils.availableWidth(j,l,i),t=a.utils.availableHeight(k,l,i);if(b.update=function(){r.beforeUpdate(),l.transition().duration(s).call(b)},b.container=this,!(h&&h.length&&h.filter(function(a){return a.values.length}).length))return a.utils.noData(b,l),b;l.selectAll(".nv-noData").remove(),c=e.xScale(),d=e.yScale().clamp(!0);var u=l.selectAll("g.nv-wrap.nv-discreteBarWithAxes").data([h]),v=u.enter().append("g").attr("class","nvd3 nv-wrap nv-discreteBarWithAxes").append("g"),w=v.append("defs"),x=u.select("g");v.append("g").attr("class","nv-x nv-axis"),v.append("g").attr("class","nv-y nv-axis").append("g").attr("class","nv-zeroLine").append("line"),v.append("g").attr("class","nv-barsWrap"),x.attr("transform","translate("+i.left+","+i.top+")"),o&&x.select(".nv-y.nv-axis").attr("transform","translate("+q+",0)"),e.width(q).height(t);var y=x.select(".nv-barsWrap").datum(h.filter(function(a){return!a.disabled}));if(y.transition().call(e),w.append("clipPath").attr("id","nv-x-label-clip-"+e.id()).append("rect"),x.select("#nv-x-label-clip-"+e.id()+" rect").attr("width",c.rangeBand()*(p?2:1)).attr("height",16).attr("x",-c.rangeBand()/(p?1:2)),m){f.scale(c)._ticks(a.utils.calcTicksX(q/100,h)).tickSize(-t,0),x.select(".nv-x.nv-axis").attr("transform","translate(0,"+(d.range()[0]+(e.showValues()&&d.domain()[0]<0?16:0))+")"),x.select(".nv-x.nv-axis").call(f); -var z=x.select(".nv-x.nv-axis").selectAll("g");p&&z.selectAll("text").attr("transform",function(a,b,c){return"translate(0,"+(c%2==0?"5":"17")+")"})}n&&(g.scale(d)._ticks(a.utils.calcTicksY(t/36,h)).tickSize(-q,0),x.select(".nv-y.nv-axis").call(g)),x.select(".nv-zeroLine line").attr("x1",0).attr("x2",q).attr("y1",d(0)).attr("y2",d(0))}),t.renderEnd("discreteBar chart immediate"),b}var c,d,e=a.models.discreteBar(),f=a.models.axis(),g=a.models.axis(),h=a.models.tooltip(),i={top:15,right:10,bottom:50,left:60},j=null,k=null,l=a.utils.getColor(),m=!0,n=!0,o=!1,p=!1,q=null,r=d3.dispatch("beforeUpdate","renderEnd"),s=250;f.orient("bottom").showMaxMin(!1).tickFormat(function(a){return a}),g.orient(o?"right":"left").tickFormat(d3.format(",.1f")),h.duration(0).headerEnabled(!1).valueFormatter(function(a,b){return g.tickFormat()(a,b)}).keyFormatter(function(a,b){return f.tickFormat()(a,b)});var t=a.utils.renderWatch(r,s);return e.dispatch.on("elementMouseover.tooltip",function(a){a.series={key:b.x()(a.data),value:b.y()(a.data),color:a.color},h.data(a).hidden(!1)}),e.dispatch.on("elementMouseout.tooltip",function(){h.hidden(!0)}),e.dispatch.on("elementMousemove.tooltip",function(){h.position({top:d3.event.pageY,left:d3.event.pageX})()}),b.dispatch=r,b.discretebar=e,b.xAxis=f,b.yAxis=g,b.tooltip=h,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return j},set:function(a){j=a}},height:{get:function(){return k},set:function(a){k=a}},staggerLabels:{get:function(){return p},set:function(a){p=a}},showXAxis:{get:function(){return m},set:function(a){m=a}},showYAxis:{get:function(){return n},set:function(a){n=a}},noData:{get:function(){return q},set:function(a){q=a}},tooltips:{get:function(){return h.enabled()},set:function(b){a.deprecated("tooltips","use chart.tooltip.enabled() instead"),h.enabled(!!b)}},tooltipContent:{get:function(){return h.contentGenerator()},set:function(b){a.deprecated("tooltipContent","use chart.tooltip.contentGenerator() instead"),h.contentGenerator(b)}},margin:{get:function(){return i},set:function(a){i.top=void 0!==a.top?a.top:i.top,i.right=void 0!==a.right?a.right:i.right,i.bottom=void 0!==a.bottom?a.bottom:i.bottom,i.left=void 0!==a.left?a.left:i.left}},duration:{get:function(){return s},set:function(a){s=a,t.reset(s),e.duration(s),f.duration(s),g.duration(s)}},color:{get:function(){return l},set:function(b){l=a.utils.getColor(b),e.color(l)}},rightAlignYAxis:{get:function(){return o},set:function(a){o=a,g.orient(a?"right":"left")}}}),a.utils.inheritOptions(b,e),a.utils.initOptions(b),b},a.models.distribution=function(){"use strict";function b(k){return m.reset(),k.each(function(b){var k=(e-("x"===g?d.left+d.right:d.top+d.bottom),"x"==g?"y":"x"),l=d3.select(this);a.utils.initSVG(l),c=c||j;var n=l.selectAll("g.nv-distribution").data([b]),o=n.enter().append("g").attr("class","nvd3 nv-distribution"),p=(o.append("g"),n.select("g"));n.attr("transform","translate("+d.left+","+d.top+")");var q=p.selectAll("g.nv-dist").data(function(a){return a},function(a){return a.key});q.enter().append("g"),q.attr("class",function(a,b){return"nv-dist nv-series-"+b}).style("stroke",function(a,b){return i(a,b)});var r=q.selectAll("line.nv-dist"+g).data(function(a){return a.values});r.enter().append("line").attr(g+"1",function(a,b){return c(h(a,b))}).attr(g+"2",function(a,b){return c(h(a,b))}),m.transition(q.exit().selectAll("line.nv-dist"+g),"dist exit").attr(g+"1",function(a,b){return j(h(a,b))}).attr(g+"2",function(a,b){return j(h(a,b))}).style("stroke-opacity",0).remove(),r.attr("class",function(a,b){return"nv-dist"+g+" nv-dist"+g+"-"+b}).attr(k+"1",0).attr(k+"2",f),m.transition(r,"dist").attr(g+"1",function(a,b){return j(h(a,b))}).attr(g+"2",function(a,b){return j(h(a,b))}),c=j.copy()}),m.renderEnd("distribution immediate"),b}var c,d={top:0,right:0,bottom:0,left:0},e=400,f=8,g="x",h=function(a){return a[g]},i=a.utils.defaultColor(),j=d3.scale.linear(),k=250,l=d3.dispatch("renderEnd"),m=a.utils.renderWatch(l,k);return b.options=a.utils.optionsFunc.bind(b),b.dispatch=l,b.margin=function(a){return arguments.length?(d.top="undefined"!=typeof a.top?a.top:d.top,d.right="undefined"!=typeof a.right?a.right:d.right,d.bottom="undefined"!=typeof a.bottom?a.bottom:d.bottom,d.left="undefined"!=typeof a.left?a.left:d.left,b):d},b.width=function(a){return arguments.length?(e=a,b):e},b.axis=function(a){return arguments.length?(g=a,b):g},b.size=function(a){return arguments.length?(f=a,b):f},b.getData=function(a){return arguments.length?(h=d3.functor(a),b):h},b.scale=function(a){return arguments.length?(j=a,b):j},b.color=function(c){return arguments.length?(i=a.utils.getColor(c),b):i},b.duration=function(a){return arguments.length?(k=a,m.reset(k),b):k},b},a.models.furiousLegend=function(){"use strict";function b(p){function q(a,b){return"furious"!=o?"#000":m?a.disengaged?g(a,b):"#fff":m?void 0:a.disabled?g(a,b):"#fff"}function r(a,b){return m&&"furious"==o?a.disengaged?"#fff":g(a,b):a.disabled?"#fff":g(a,b)}return p.each(function(b){var p=d-c.left-c.right,s=d3.select(this);a.utils.initSVG(s);var t=s.selectAll("g.nv-legend").data([b]),u=(t.enter().append("g").attr("class","nvd3 nv-legend").append("g"),t.select("g"));t.attr("transform","translate("+c.left+","+c.top+")");var v,w=u.selectAll(".nv-series").data(function(a){return"furious"!=o?a:a.filter(function(a){return m?!0:!a.disengaged})}),x=w.enter().append("g").attr("class","nv-series");if("classic"==o)x.append("circle").style("stroke-width",2).attr("class","nv-legend-symbol").attr("r",5),v=w.select("circle");else if("furious"==o){x.append("rect").style("stroke-width",2).attr("class","nv-legend-symbol").attr("rx",3).attr("ry",3),v=w.select("rect"),x.append("g").attr("class","nv-check-box").property("innerHTML",'').attr("transform","translate(-10,-8)scale(0.5)");var y=w.select(".nv-check-box");y.each(function(a,b){d3.select(this).selectAll("path").attr("stroke",q(a,b))})}x.append("text").attr("text-anchor","start").attr("class","nv-legend-text").attr("dy",".32em").attr("dx","8");var z=w.select("text.nv-legend-text");w.on("mouseover",function(a,b){n.legendMouseover(a,b)}).on("mouseout",function(a,b){n.legendMouseout(a,b)}).on("click",function(a,b){n.legendClick(a,b);var c=w.data();if(k){if("classic"==o)l?(c.forEach(function(a){a.disabled=!0}),a.disabled=!1):(a.disabled=!a.disabled,c.every(function(a){return a.disabled})&&c.forEach(function(a){a.disabled=!1}));else if("furious"==o)if(m)a.disengaged=!a.disengaged,a.userDisabled=void 0==a.userDisabled?!!a.disabled:a.userDisabled,a.disabled=a.disengaged||a.userDisabled;else if(!m){a.disabled=!a.disabled,a.userDisabled=a.disabled;var d=c.filter(function(a){return!a.disengaged});d.every(function(a){return a.userDisabled})&&c.forEach(function(a){a.disabled=a.userDisabled=!1})}n.stateChange({disabled:c.map(function(a){return!!a.disabled}),disengaged:c.map(function(a){return!!a.disengaged})})}}).on("dblclick",function(a,b){if(("furious"!=o||!m)&&(n.legendDblclick(a,b),k)){var c=w.data();c.forEach(function(a){a.disabled=!0,"furious"==o&&(a.userDisabled=a.disabled)}),a.disabled=!1,"furious"==o&&(a.userDisabled=a.disabled),n.stateChange({disabled:c.map(function(a){return!!a.disabled})})}}),w.classed("nv-disabled",function(a){return a.userDisabled}),w.exit().remove(),z.attr("fill",q).text(f);var A;switch(o){case"furious":A=23;break;case"classic":A=20}if(h){var B=[];w.each(function(){var b,c=d3.select(this).select("text");try{if(b=c.node().getComputedTextLength(),0>=b)throw Error()}catch(d){b=a.utils.calcApproxTextWidth(c)}B.push(b+i)});for(var C=0,D=0,E=[];p>D&&Cp&&C>1;){E=[],C--;for(var F=0;F(E[F%C]||0)&&(E[F%C]=B[F]);D=E.reduce(function(a,b){return a+b})}for(var G=[],H=0,I=0;C>H;H++)G[H]=I,I+=E[H];w.attr("transform",function(a,b){return"translate("+G[b%C]+","+(5+Math.floor(b/C)*A)+")"}),j?u.attr("transform","translate("+(d-c.right-D)+","+c.top+")"):u.attr("transform","translate(0,"+c.top+")"),e=c.top+c.bottom+Math.ceil(B.length/C)*A}else{var J,K=5,L=5,M=0;w.attr("transform",function(){var a=d3.select(this).select("text").node().getComputedTextLength()+i;return J=L,dM&&(M=L),"translate("+J+","+K+")"}),u.attr("transform","translate("+(d-c.right-M)+","+c.top+")"),e=c.top+c.bottom+K+15}"furious"==o&&v.attr("width",function(a,b){return z[0][b].getComputedTextLength()+27}).attr("height",18).attr("y",-9).attr("x",-15),v.style("fill",r).style("stroke",function(a,b){return a.color||g(a,b)})}),b}var c={top:5,right:0,bottom:5,left:0},d=400,e=20,f=function(a){return a.key},g=a.utils.getColor(),h=!0,i=28,j=!0,k=!0,l=!1,m=!1,n=d3.dispatch("legendClick","legendDblclick","legendMouseover","legendMouseout","stateChange"),o="classic";return b.dispatch=n,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return d},set:function(a){d=a}},height:{get:function(){return e},set:function(a){e=a}},key:{get:function(){return f},set:function(a){f=a}},align:{get:function(){return h},set:function(a){h=a}},rightAlign:{get:function(){return j},set:function(a){j=a}},padding:{get:function(){return i},set:function(a){i=a}},updateState:{get:function(){return k},set:function(a){k=a}},radioButtonMode:{get:function(){return l},set:function(a){l=a}},expanded:{get:function(){return m},set:function(a){m=a}},vers:{get:function(){return o},set:function(a){o=a}},margin:{get:function(){return c},set:function(a){c.top=void 0!==a.top?a.top:c.top,c.right=void 0!==a.right?a.right:c.right,c.bottom=void 0!==a.bottom?a.bottom:c.bottom,c.left=void 0!==a.left?a.left:c.left}},color:{get:function(){return g},set:function(b){g=a.utils.getColor(b)}}}),a.utils.initOptions(b),b},a.models.historicalBar=function(){"use strict";function b(x){return x.each(function(b){w.reset(),k=d3.select(this);var x=a.utils.availableWidth(h,k,g),y=a.utils.availableHeight(i,k,g);a.utils.initSVG(k),l.domain(c||d3.extent(b[0].values.map(n).concat(p))),l.range(r?e||[.5*x/b[0].values.length,x*(b[0].values.length-.5)/b[0].values.length]:e||[0,x]),m.domain(d||d3.extent(b[0].values.map(o).concat(q))).range(f||[y,0]),l.domain()[0]===l.domain()[1]&&l.domain(l.domain()[0]?[l.domain()[0]-.01*l.domain()[0],l.domain()[1]+.01*l.domain()[1]]:[-1,1]),m.domain()[0]===m.domain()[1]&&m.domain(m.domain()[0]?[m.domain()[0]+.01*m.domain()[0],m.domain()[1]-.01*m.domain()[1]]:[-1,1]);var z=k.selectAll("g.nv-wrap.nv-historicalBar-"+j).data([b[0].values]),A=z.enter().append("g").attr("class","nvd3 nv-wrap nv-historicalBar-"+j),B=A.append("defs"),C=A.append("g"),D=z.select("g");C.append("g").attr("class","nv-bars"),z.attr("transform","translate("+g.left+","+g.top+")"),k.on("click",function(a,b){u.chartClick({data:a,index:b,pos:d3.event,id:j})}),B.append("clipPath").attr("id","nv-chart-clip-path-"+j).append("rect"),z.select("#nv-chart-clip-path-"+j+" rect").attr("width",x).attr("height",y),D.attr("clip-path",s?"url(#nv-chart-clip-path-"+j+")":"");var E=z.select(".nv-bars").selectAll(".nv-bar").data(function(a){return a},function(a,b){return n(a,b)});E.exit().remove(),E.enter().append("rect").attr("x",0).attr("y",function(b,c){return a.utils.NaNtoZero(m(Math.max(0,o(b,c))))}).attr("height",function(b,c){return a.utils.NaNtoZero(Math.abs(m(o(b,c))-m(0)))}).attr("transform",function(a,c){return"translate("+(l(n(a,c))-x/b[0].values.length*.45)+",0)"}).on("mouseover",function(a,b){v&&(d3.select(this).classed("hover",!0),u.elementMouseover({data:a,index:b,color:d3.select(this).style("fill")}))}).on("mouseout",function(a,b){v&&(d3.select(this).classed("hover",!1),u.elementMouseout({data:a,index:b,color:d3.select(this).style("fill")}))}).on("mousemove",function(a,b){v&&u.elementMousemove({data:a,index:b,color:d3.select(this).style("fill")})}).on("click",function(a,b){v&&(u.elementClick({data:a,index:b,color:d3.select(this).style("fill")}),d3.event.stopPropagation())}).on("dblclick",function(a,b){v&&(u.elementDblClick({data:a,index:b,color:d3.select(this).style("fill")}),d3.event.stopPropagation())}),E.attr("fill",function(a,b){return t(a,b)}).attr("class",function(a,b,c){return(o(a,b)<0?"nv-bar negative":"nv-bar positive")+" nv-bar-"+c+"-"+b}).watchTransition(w,"bars").attr("transform",function(a,c){return"translate("+(l(n(a,c))-x/b[0].values.length*.45)+",0)"}).attr("width",x/b[0].values.length*.9),E.watchTransition(w,"bars").attr("y",function(b,c){var d=o(b,c)<0?m(0):m(0)-m(o(b,c))<1?m(0)-1:m(o(b,c));return a.utils.NaNtoZero(d)}).attr("height",function(b,c){return a.utils.NaNtoZero(Math.max(Math.abs(m(o(b,c))-m(0)),1))})}),w.renderEnd("historicalBar immediate"),b}var c,d,e,f,g={top:0,right:0,bottom:0,left:0},h=null,i=null,j=Math.floor(1e4*Math.random()),k=null,l=d3.scale.linear(),m=d3.scale.linear(),n=function(a){return a.x},o=function(a){return a.y},p=[],q=[0],r=!1,s=!0,t=a.utils.defaultColor(),u=d3.dispatch("chartClick","elementClick","elementDblClick","elementMouseover","elementMouseout","elementMousemove","renderEnd"),v=!0,w=a.utils.renderWatch(u,0);return b.highlightPoint=function(a,b){k.select(".nv-bars .nv-bar-0-"+a).classed("hover",b)},b.clearHighlights=function(){k.select(".nv-bars .nv-bar.hover").classed("hover",!1)},b.dispatch=u,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return h},set:function(a){h=a}},height:{get:function(){return i},set:function(a){i=a}},forceX:{get:function(){return p},set:function(a){p=a}},forceY:{get:function(){return q},set:function(a){q=a}},padData:{get:function(){return r},set:function(a){r=a}},x:{get:function(){return n},set:function(a){n=a}},y:{get:function(){return o},set:function(a){o=a}},xScale:{get:function(){return l},set:function(a){l=a}},yScale:{get:function(){return m},set:function(a){m=a}},xDomain:{get:function(){return c},set:function(a){c=a}},yDomain:{get:function(){return d},set:function(a){d=a}},xRange:{get:function(){return e},set:function(a){e=a}},yRange:{get:function(){return f},set:function(a){f=a}},clipEdge:{get:function(){return s},set:function(a){s=a}},id:{get:function(){return j},set:function(a){j=a}},interactive:{get:function(){return v},set:function(a){v=a}},margin:{get:function(){return g},set:function(a){g.top=void 0!==a.top?a.top:g.top,g.right=void 0!==a.right?a.right:g.right,g.bottom=void 0!==a.bottom?a.bottom:g.bottom,g.left=void 0!==a.left?a.left:g.left}},color:{get:function(){return t},set:function(b){t=a.utils.getColor(b)}}}),a.utils.initOptions(b),b},a.models.historicalBarChart=function(b){"use strict";function c(b){return b.each(function(k){z.reset(),z.models(f),q&&z.models(g),r&&z.models(h);var w=d3.select(this),A=this;a.utils.initSVG(w);var B=a.utils.availableWidth(n,w,l),C=a.utils.availableHeight(o,w,l);if(c.update=function(){w.transition().duration(y).call(c)},c.container=this,u.disabled=k.map(function(a){return!!a.disabled}),!v){var D;v={};for(D in u)v[D]=u[D]instanceof Array?u[D].slice(0):u[D]}if(!(k&&k.length&&k.filter(function(a){return a.values.length}).length))return a.utils.noData(c,w),c;w.selectAll(".nv-noData").remove(),d=f.xScale(),e=f.yScale();var E=w.selectAll("g.nv-wrap.nv-historicalBarChart").data([k]),F=E.enter().append("g").attr("class","nvd3 nv-wrap nv-historicalBarChart").append("g"),G=E.select("g");F.append("g").attr("class","nv-x nv-axis"),F.append("g").attr("class","nv-y nv-axis"),F.append("g").attr("class","nv-barsWrap"),F.append("g").attr("class","nv-legendWrap"),F.append("g").attr("class","nv-interactive"),p&&(i.width(B),G.select(".nv-legendWrap").datum(k).call(i),l.top!=i.height()&&(l.top=i.height(),C=a.utils.availableHeight(o,w,l)),E.select(".nv-legendWrap").attr("transform","translate(0,"+-l.top+")")),E.attr("transform","translate("+l.left+","+l.top+")"),s&&G.select(".nv-y.nv-axis").attr("transform","translate("+B+",0)"),t&&(j.width(B).height(C).margin({left:l.left,top:l.top}).svgContainer(w).xScale(d),E.select(".nv-interactive").call(j)),f.width(B).height(C).color(k.map(function(a,b){return a.color||m(a,b)}).filter(function(a,b){return!k[b].disabled}));var H=G.select(".nv-barsWrap").datum(k.filter(function(a){return!a.disabled}));H.transition().call(f),q&&(g.scale(d)._ticks(a.utils.calcTicksX(B/100,k)).tickSize(-C,0),G.select(".nv-x.nv-axis").attr("transform","translate(0,"+e.range()[0]+")"),G.select(".nv-x.nv-axis").transition().call(g)),r&&(h.scale(e)._ticks(a.utils.calcTicksY(C/36,k)).tickSize(-B,0),G.select(".nv-y.nv-axis").transition().call(h)),j.dispatch.on("elementMousemove",function(b){f.clearHighlights();var d,e,i,n=[];k.filter(function(a,b){return a.seriesIndex=b,!a.disabled}).forEach(function(g){e=a.interactiveBisect(g.values,b.pointXValue,c.x()),f.highlightPoint(e,!0);var h=g.values[e];void 0!==h&&(void 0===d&&(d=h),void 0===i&&(i=c.xScale()(c.x()(h,e))),n.push({key:g.key,value:c.y()(h,e),color:m(g,g.seriesIndex),data:g.values[e]}))});var o=g.tickFormat()(c.x()(d,e));j.tooltip.position({left:i+l.left,top:b.mouseY+l.top}).chartContainer(A.parentNode).valueFormatter(function(a){return h.tickFormat()(a)}).data({value:o,index:e,series:n})(),j.renderGuideLine(i)}),j.dispatch.on("elementMouseout",function(){x.tooltipHide(),f.clearHighlights()}),i.dispatch.on("legendClick",function(a){a.disabled=!a.disabled,k.filter(function(a){return!a.disabled}).length||k.map(function(a){return a.disabled=!1,E.selectAll(".nv-series").classed("disabled",!1),a}),u.disabled=k.map(function(a){return!!a.disabled}),x.stateChange(u),b.transition().call(c)}),i.dispatch.on("legendDblclick",function(a){k.forEach(function(a){a.disabled=!0}),a.disabled=!1,u.disabled=k.map(function(a){return!!a.disabled}),x.stateChange(u),c.update()}),x.on("changeState",function(a){"undefined"!=typeof a.disabled&&(k.forEach(function(b,c){b.disabled=a.disabled[c]}),u.disabled=a.disabled),c.update()})}),z.renderEnd("historicalBarChart immediate"),c}var d,e,f=b||a.models.historicalBar(),g=a.models.axis(),h=a.models.axis(),i=a.models.legend(),j=a.interactiveGuideline(),k=a.models.tooltip(),l={top:30,right:90,bottom:50,left:90},m=a.utils.defaultColor(),n=null,o=null,p=!1,q=!0,r=!0,s=!1,t=!1,u={},v=null,w=null,x=d3.dispatch("tooltipHide","stateChange","changeState","renderEnd"),y=250;g.orient("bottom").tickPadding(7),h.orient(s?"right":"left"),k.duration(0).headerEnabled(!1).valueFormatter(function(a,b){return h.tickFormat()(a,b)}).headerFormatter(function(a,b){return g.tickFormat()(a,b)});var z=a.utils.renderWatch(x,0);return f.dispatch.on("elementMouseover.tooltip",function(a){a.series={key:c.x()(a.data),value:c.y()(a.data),color:a.color},k.data(a).hidden(!1)}),f.dispatch.on("elementMouseout.tooltip",function(){k.hidden(!0)}),f.dispatch.on("elementMousemove.tooltip",function(){k.position({top:d3.event.pageY,left:d3.event.pageX})()}),c.dispatch=x,c.bars=f,c.legend=i,c.xAxis=g,c.yAxis=h,c.interactiveLayer=j,c.tooltip=k,c.options=a.utils.optionsFunc.bind(c),c._options=Object.create({},{width:{get:function(){return n},set:function(a){n=a}},height:{get:function(){return o},set:function(a){o=a}},showLegend:{get:function(){return p},set:function(a){p=a}},showXAxis:{get:function(){return q},set:function(a){q=a}},showYAxis:{get:function(){return r},set:function(a){r=a}},defaultState:{get:function(){return v},set:function(a){v=a}},noData:{get:function(){return w},set:function(a){w=a}},tooltips:{get:function(){return k.enabled()},set:function(b){a.deprecated("tooltips","use chart.tooltip.enabled() instead"),k.enabled(!!b)}},tooltipContent:{get:function(){return k.contentGenerator()},set:function(b){a.deprecated("tooltipContent","use chart.tooltip.contentGenerator() instead"),k.contentGenerator(b)}},margin:{get:function(){return l},set:function(a){l.top=void 0!==a.top?a.top:l.top,l.right=void 0!==a.right?a.right:l.right,l.bottom=void 0!==a.bottom?a.bottom:l.bottom,l.left=void 0!==a.left?a.left:l.left}},color:{get:function(){return m},set:function(b){m=a.utils.getColor(b),i.color(m),f.color(m)}},duration:{get:function(){return y},set:function(a){y=a,z.reset(y),h.duration(y),g.duration(y)}},rightAlignYAxis:{get:function(){return s},set:function(a){s=a,h.orient(a?"right":"left")}},useInteractiveGuideline:{get:function(){return t},set:function(a){t=a,a===!0&&c.interactive(!1)}}}),a.utils.inheritOptions(c,f),a.utils.initOptions(c),c},a.models.ohlcBarChart=function(){var b=a.models.historicalBarChart(a.models.ohlcBar());return b.useInteractiveGuideline(!0),b.interactiveLayer.tooltip.contentGenerator(function(a){var c=a.series[0].data,d=c.open'+a.value+"
open:"+b.yAxis.tickFormat()(c.open)+"
close:"+b.yAxis.tickFormat()(c.close)+"
high"+b.yAxis.tickFormat()(c.high)+"
low:"+b.yAxis.tickFormat()(c.low)+"
"}),b},a.models.candlestickBarChart=function(){var b=a.models.historicalBarChart(a.models.candlestickBar());return b.useInteractiveGuideline(!0),b.interactiveLayer.tooltip.contentGenerator(function(a){var c=a.series[0].data,d=c.open'+a.value+"
open:"+b.yAxis.tickFormat()(c.open)+"
close:"+b.yAxis.tickFormat()(c.close)+"
high"+b.yAxis.tickFormat()(c.high)+"
low:"+b.yAxis.tickFormat()(c.low)+"
"}),b},a.models.legend=function(){"use strict";function b(p){function q(a,b){return"furious"!=o?"#000":m?a.disengaged?"#000":"#fff":m?void 0:(a.color||(a.color=g(a,b)),a.disabled?a.color:"#fff")}function r(a,b){return m&&"furious"==o&&a.disengaged?"#eee":a.color||g(a,b)}function s(a){return m&&"furious"==o?1:a.disabled?0:1}return p.each(function(b){var g=d-c.left-c.right,p=d3.select(this);a.utils.initSVG(p);var t=p.selectAll("g.nv-legend").data([b]),u=t.enter().append("g").attr("class","nvd3 nv-legend").append("g"),v=t.select("g");t.attr("transform","translate("+c.left+","+c.top+")");var w,x,y=v.selectAll(".nv-series").data(function(a){return"furious"!=o?a:a.filter(function(a){return m?!0:!a.disengaged})}),z=y.enter().append("g").attr("class","nv-series");switch(o){case"furious":x=23;break;case"classic":x=20}if("classic"==o)z.append("circle").style("stroke-width",2).attr("class","nv-legend-symbol").attr("r",5),w=y.select("circle");else if("furious"==o){z.append("rect").style("stroke-width",2).attr("class","nv-legend-symbol").attr("rx",3).attr("ry",3),w=y.select(".nv-legend-symbol"),z.append("g").attr("class","nv-check-box").property("innerHTML",'').attr("transform","translate(-10,-8)scale(0.5)");var A=y.select(".nv-check-box");A.each(function(a,b){d3.select(this).selectAll("path").attr("stroke",q(a,b))})}z.append("text").attr("text-anchor","start").attr("class","nv-legend-text").attr("dy",".32em").attr("dx","8");var B=y.select("text.nv-legend-text");y.on("mouseover",function(a,b){n.legendMouseover(a,b)}).on("mouseout",function(a,b){n.legendMouseout(a,b)}).on("click",function(a,b){n.legendClick(a,b);var c=y.data();if(k){if("classic"==o)l?(c.forEach(function(a){a.disabled=!0}),a.disabled=!1):(a.disabled=!a.disabled,c.every(function(a){return a.disabled})&&c.forEach(function(a){a.disabled=!1}));else if("furious"==o)if(m)a.disengaged=!a.disengaged,a.userDisabled=void 0==a.userDisabled?!!a.disabled:a.userDisabled,a.disabled=a.disengaged||a.userDisabled;else if(!m){a.disabled=!a.disabled,a.userDisabled=a.disabled;var d=c.filter(function(a){return!a.disengaged});d.every(function(a){return a.userDisabled})&&c.forEach(function(a){a.disabled=a.userDisabled=!1})}n.stateChange({disabled:c.map(function(a){return!!a.disabled}),disengaged:c.map(function(a){return!!a.disengaged})})}}).on("dblclick",function(a,b){if(("furious"!=o||!m)&&(n.legendDblclick(a,b),k)){var c=y.data();c.forEach(function(a){a.disabled=!0,"furious"==o&&(a.userDisabled=a.disabled)}),a.disabled=!1,"furious"==o&&(a.userDisabled=a.disabled),n.stateChange({disabled:c.map(function(a){return!!a.disabled})})}}),y.classed("nv-disabled",function(a){return a.userDisabled}),y.exit().remove(),B.attr("fill",q).text(f);var C=0;if(h){var D=[];y.each(function(){var b,c=d3.select(this).select("text");try{if(b=c.node().getComputedTextLength(),0>=b)throw Error()}catch(d){b=a.utils.calcApproxTextWidth(c)}D.push(b+i)});var E=0,F=[];for(C=0;g>C&&Eg&&E>1;){F=[],E--;for(var G=0;G(F[G%E]||0)&&(F[G%E]=D[G]);C=F.reduce(function(a,b){return a+b})}for(var H=[],I=0,J=0;E>I;I++)H[I]=J,J+=F[I];y.attr("transform",function(a,b){return"translate("+H[b%E]+","+(5+Math.floor(b/E)*x)+")"}),j?v.attr("transform","translate("+(d-c.right-C)+","+c.top+")"):v.attr("transform","translate(0,"+c.top+")"),e=c.top+c.bottom+Math.ceil(D.length/E)*x}else{var K,L=5,M=5,N=0;y.attr("transform",function(){var a=d3.select(this).select("text").node().getComputedTextLength()+i;return K=M,dN&&(N=M),K+N>C&&(C=K+N),"translate("+K+","+L+")"}),v.attr("transform","translate("+(d-c.right-N)+","+c.top+")"),e=c.top+c.bottom+L+15}if("furious"==o){w.attr("width",function(a,b){return B[0][b].getComputedTextLength()+27}).attr("height",18).attr("y",-9).attr("x",-15),u.insert("rect",":first-child").attr("class","nv-legend-bg").attr("fill","#eee").attr("opacity",0);var O=v.select(".nv-legend-bg");O.transition().duration(300).attr("x",-x).attr("width",C+x-12).attr("height",e+10).attr("y",-c.top-10).attr("opacity",m?1:0)}w.style("fill",r).style("fill-opacity",s).style("stroke",r)}),b}var c={top:5,right:0,bottom:5,left:0},d=400,e=20,f=function(a){return a.key},g=a.utils.getColor(),h=!0,i=32,j=!0,k=!0,l=!1,m=!1,n=d3.dispatch("legendClick","legendDblclick","legendMouseover","legendMouseout","stateChange"),o="classic";return b.dispatch=n,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return d},set:function(a){d=a}},height:{get:function(){return e},set:function(a){e=a}},key:{get:function(){return f},set:function(a){f=a}},align:{get:function(){return h},set:function(a){h=a}},rightAlign:{get:function(){return j},set:function(a){j=a}},padding:{get:function(){return i},set:function(a){i=a}},updateState:{get:function(){return k},set:function(a){k=a}},radioButtonMode:{get:function(){return l},set:function(a){l=a}},expanded:{get:function(){return m},set:function(a){m=a}},vers:{get:function(){return o},set:function(a){o=a}},margin:{get:function(){return c},set:function(a){c.top=void 0!==a.top?a.top:c.top,c.right=void 0!==a.right?a.right:c.right,c.bottom=void 0!==a.bottom?a.bottom:c.bottom,c.left=void 0!==a.left?a.left:c.left}},color:{get:function(){return g},set:function(b){g=a.utils.getColor(b)}}}),a.utils.initOptions(b),b},a.models.line=function(){"use strict";function b(r){return v.reset(),v.models(e),r.each(function(b){i=d3.select(this);var r=a.utils.availableWidth(g,i,f),s=a.utils.availableHeight(h,i,f);a.utils.initSVG(i),c=e.xScale(),d=e.yScale(),t=t||c,u=u||d;var w=i.selectAll("g.nv-wrap.nv-line").data([b]),x=w.enter().append("g").attr("class","nvd3 nv-wrap nv-line"),y=x.append("defs"),z=x.append("g"),A=w.select("g");z.append("g").attr("class","nv-groups"),z.append("g").attr("class","nv-scatterWrap"),w.attr("transform","translate("+f.left+","+f.top+")"),e.width(r).height(s);var B=w.select(".nv-scatterWrap");B.call(e),y.append("clipPath").attr("id","nv-edge-clip-"+e.id()).append("rect"),w.select("#nv-edge-clip-"+e.id()+" rect").attr("width",r).attr("height",s>0?s:0),A.attr("clip-path",p?"url(#nv-edge-clip-"+e.id()+")":""),B.attr("clip-path",p?"url(#nv-edge-clip-"+e.id()+")":"");var C=w.select(".nv-groups").selectAll(".nv-group").data(function(a){return a},function(a){return a.key});C.enter().append("g").style("stroke-opacity",1e-6).style("stroke-width",function(a){return a.strokeWidth||j}).style("fill-opacity",1e-6),C.exit().remove(),C.attr("class",function(a,b){return(a.classed||"")+" nv-group nv-series-"+b}).classed("hover",function(a){return a.hover}).style("fill",function(a,b){return k(a,b)}).style("stroke",function(a,b){return k(a,b)}),C.watchTransition(v,"line: groups").style("stroke-opacity",1).style("fill-opacity",function(a){return a.fillOpacity||.5});var D=C.selectAll("path.nv-area").data(function(a){return o(a)?[a]:[]});D.enter().append("path").attr("class","nv-area").attr("d",function(b){return d3.svg.area().interpolate(q).defined(n).x(function(b,c){return a.utils.NaNtoZero(t(l(b,c)))}).y0(function(b,c){return a.utils.NaNtoZero(u(m(b,c)))}).y1(function(){return u(d.domain()[0]<=0?d.domain()[1]>=0?0:d.domain()[1]:d.domain()[0])}).apply(this,[b.values])}),C.exit().selectAll("path.nv-area").remove(),D.watchTransition(v,"line: areaPaths").attr("d",function(b){return d3.svg.area().interpolate(q).defined(n).x(function(b,d){return a.utils.NaNtoZero(c(l(b,d)))}).y0(function(b,c){return a.utils.NaNtoZero(d(m(b,c)))}).y1(function(){return d(d.domain()[0]<=0?d.domain()[1]>=0?0:d.domain()[1]:d.domain()[0])}).apply(this,[b.values])});var E=C.selectAll("path.nv-line").data(function(a){return[a.values]});E.enter().append("path").attr("class","nv-line").attr("d",d3.svg.line().interpolate(q).defined(n).x(function(b,c){return a.utils.NaNtoZero(t(l(b,c)))}).y(function(b,c){return a.utils.NaNtoZero(u(m(b,c)))})),E.watchTransition(v,"line: linePaths").attr("d",d3.svg.line().interpolate(q).defined(n).x(function(b,d){return a.utils.NaNtoZero(c(l(b,d)))}).y(function(b,c){return a.utils.NaNtoZero(d(m(b,c)))})),t=c.copy(),u=d.copy()}),v.renderEnd("line immediate"),b}var c,d,e=a.models.scatter(),f={top:0,right:0,bottom:0,left:0},g=960,h=500,i=null,j=1.5,k=a.utils.defaultColor(),l=function(a){return a.x},m=function(a){return a.y},n=function(a,b){return!isNaN(m(a,b))&&null!==m(a,b)},o=function(a){return a.area},p=!1,q="linear",r=250,s=d3.dispatch("elementClick","elementMouseover","elementMouseout","renderEnd");e.pointSize(16).pointDomain([16,256]);var t,u,v=a.utils.renderWatch(s,r);return b.dispatch=s,b.scatter=e,e.dispatch.on("elementClick",function(){s.elementClick.apply(this,arguments)}),e.dispatch.on("elementMouseover",function(){s.elementMouseover.apply(this,arguments)}),e.dispatch.on("elementMouseout",function(){s.elementMouseout.apply(this,arguments)}),b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return g},set:function(a){g=a}},height:{get:function(){return h},set:function(a){h=a}},defined:{get:function(){return n},set:function(a){n=a}},interpolate:{get:function(){return q},set:function(a){q=a}},clipEdge:{get:function(){return p},set:function(a){p=a}},margin:{get:function(){return f},set:function(a){f.top=void 0!==a.top?a.top:f.top,f.right=void 0!==a.right?a.right:f.right,f.bottom=void 0!==a.bottom?a.bottom:f.bottom,f.left=void 0!==a.left?a.left:f.left}},duration:{get:function(){return r},set:function(a){r=a,v.reset(r),e.duration(r)}},isArea:{get:function(){return o},set:function(a){o=d3.functor(a)}},x:{get:function(){return l},set:function(a){l=a,e.x(a)}},y:{get:function(){return m},set:function(a){m=a,e.y(a)}},color:{get:function(){return k},set:function(b){k=a.utils.getColor(b),e.color(k)}}}),a.utils.inheritOptions(b,e),a.utils.initOptions(b),b},a.models.lineChart=function(){"use strict";function b(j){return y.reset(),y.models(e),p&&y.models(f),q&&y.models(g),j.each(function(j){var v=d3.select(this),y=this;a.utils.initSVG(v);var B=a.utils.availableWidth(m,v,k),C=a.utils.availableHeight(n,v,k);if(b.update=function(){0===x?v.call(b):v.transition().duration(x).call(b)},b.container=this,t.setter(A(j),b.update).getter(z(j)).update(),t.disabled=j.map(function(a){return!!a.disabled}),!u){var D;u={};for(D in t)u[D]=t[D]instanceof Array?t[D].slice(0):t[D] -}if(!(j&&j.length&&j.filter(function(a){return a.values.length}).length))return a.utils.noData(b,v),b;v.selectAll(".nv-noData").remove(),c=e.xScale(),d=e.yScale();var E=v.selectAll("g.nv-wrap.nv-lineChart").data([j]),F=E.enter().append("g").attr("class","nvd3 nv-wrap nv-lineChart").append("g"),G=E.select("g");F.append("rect").style("opacity",0),F.append("g").attr("class","nv-x nv-axis"),F.append("g").attr("class","nv-y nv-axis"),F.append("g").attr("class","nv-linesWrap"),F.append("g").attr("class","nv-legendWrap"),F.append("g").attr("class","nv-interactive"),G.select("rect").attr("width",B).attr("height",C>0?C:0),o&&(h.width(B),G.select(".nv-legendWrap").datum(j).call(h),k.top!=h.height()&&(k.top=h.height(),C=a.utils.availableHeight(n,v,k)),E.select(".nv-legendWrap").attr("transform","translate(0,"+-k.top+")")),E.attr("transform","translate("+k.left+","+k.top+")"),r&&G.select(".nv-y.nv-axis").attr("transform","translate("+B+",0)"),s&&(i.width(B).height(C).margin({left:k.left,top:k.top}).svgContainer(v).xScale(c),E.select(".nv-interactive").call(i)),e.width(B).height(C).color(j.map(function(a,b){return a.color||l(a,b)}).filter(function(a,b){return!j[b].disabled}));var H=G.select(".nv-linesWrap").datum(j.filter(function(a){return!a.disabled}));H.call(e),p&&(f.scale(c)._ticks(a.utils.calcTicksX(B/100,j)).tickSize(-C,0),G.select(".nv-x.nv-axis").attr("transform","translate(0,"+d.range()[0]+")"),G.select(".nv-x.nv-axis").call(f)),q&&(g.scale(d)._ticks(a.utils.calcTicksY(C/36,j)).tickSize(-B,0),G.select(".nv-y.nv-axis").call(g)),h.dispatch.on("stateChange",function(a){for(var c in a)t[c]=a[c];w.stateChange(t),b.update()}),i.dispatch.on("elementMousemove",function(c){e.clearHighlights();var d,h,m,n=[];if(j.filter(function(a,b){return a.seriesIndex=b,!a.disabled}).forEach(function(f,g){h=a.interactiveBisect(f.values,c.pointXValue,b.x());var i=f.values[h],j=b.y()(i,h);null!=j&&e.highlightPoint(g,h,!0),void 0!==i&&(void 0===d&&(d=i),void 0===m&&(m=b.xScale()(b.x()(i,h))),n.push({key:f.key,value:j,color:l(f,f.seriesIndex)}))}),n.length>2){var o=b.yScale().invert(c.mouseY),p=Math.abs(b.yScale().domain()[0]-b.yScale().domain()[1]),q=.03*p,r=a.nearestValueIndex(n.map(function(a){return a.value}),o,q);null!==r&&(n[r].highlight=!0)}var s=f.tickFormat()(b.x()(d,h));i.tooltip.position({left:c.mouseX+k.left,top:c.mouseY+k.top}).chartContainer(y.parentNode).valueFormatter(function(a){return null==a?"N/A":g.tickFormat()(a)}).data({value:s,index:h,series:n})(),i.renderGuideLine(m)}),i.dispatch.on("elementClick",function(c){var d,f=[];j.filter(function(a,b){return a.seriesIndex=b,!a.disabled}).forEach(function(e){var g=a.interactiveBisect(e.values,c.pointXValue,b.x()),h=e.values[g];if("undefined"!=typeof h){"undefined"==typeof d&&(d=b.xScale()(b.x()(h,g)));var i=b.yScale()(b.y()(h,g));f.push({point:h,pointIndex:g,pos:[d,i],seriesIndex:e.seriesIndex,series:e})}}),e.dispatch.elementClick(f)}),i.dispatch.on("elementMouseout",function(){e.clearHighlights()}),w.on("changeState",function(a){"undefined"!=typeof a.disabled&&j.length===a.disabled.length&&(j.forEach(function(b,c){b.disabled=a.disabled[c]}),t.disabled=a.disabled),b.update()})}),y.renderEnd("lineChart immediate"),b}var c,d,e=a.models.line(),f=a.models.axis(),g=a.models.axis(),h=a.models.legend(),i=a.interactiveGuideline(),j=a.models.tooltip(),k={top:30,right:20,bottom:50,left:60},l=a.utils.defaultColor(),m=null,n=null,o=!0,p=!0,q=!0,r=!1,s=!1,t=a.utils.state(),u=null,v=null,w=d3.dispatch("tooltipShow","tooltipHide","stateChange","changeState","renderEnd"),x=250;f.orient("bottom").tickPadding(7),g.orient(r?"right":"left"),j.valueFormatter(function(a,b){return g.tickFormat()(a,b)}).headerFormatter(function(a,b){return f.tickFormat()(a,b)});var y=a.utils.renderWatch(w,x),z=function(a){return function(){return{active:a.map(function(a){return!a.disabled})}}},A=function(a){return function(b){void 0!==b.active&&a.forEach(function(a,c){a.disabled=!b.active[c]})}};return e.dispatch.on("elementMouseover.tooltip",function(a){j.data(a).position(a.pos).hidden(!1)}),e.dispatch.on("elementMouseout.tooltip",function(){j.hidden(!0)}),b.dispatch=w,b.lines=e,b.legend=h,b.xAxis=f,b.yAxis=g,b.interactiveLayer=i,b.tooltip=j,b.dispatch=w,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return m},set:function(a){m=a}},height:{get:function(){return n},set:function(a){n=a}},showLegend:{get:function(){return o},set:function(a){o=a}},showXAxis:{get:function(){return p},set:function(a){p=a}},showYAxis:{get:function(){return q},set:function(a){q=a}},defaultState:{get:function(){return u},set:function(a){u=a}},noData:{get:function(){return v},set:function(a){v=a}},tooltips:{get:function(){return j.enabled()},set:function(b){a.deprecated("tooltips","use chart.tooltip.enabled() instead"),j.enabled(!!b)}},tooltipContent:{get:function(){return j.contentGenerator()},set:function(b){a.deprecated("tooltipContent","use chart.tooltip.contentGenerator() instead"),j.contentGenerator(b)}},margin:{get:function(){return k},set:function(a){k.top=void 0!==a.top?a.top:k.top,k.right=void 0!==a.right?a.right:k.right,k.bottom=void 0!==a.bottom?a.bottom:k.bottom,k.left=void 0!==a.left?a.left:k.left}},duration:{get:function(){return x},set:function(a){x=a,y.reset(x),e.duration(x),f.duration(x),g.duration(x)}},color:{get:function(){return l},set:function(b){l=a.utils.getColor(b),h.color(l),e.color(l)}},rightAlignYAxis:{get:function(){return r},set:function(a){r=a,g.orient(r?"right":"left")}},useInteractiveGuideline:{get:function(){return s},set:function(a){s=a,s&&(e.interactive(!1),e.useVoronoi(!1))}}}),a.utils.inheritOptions(b,e),a.utils.initOptions(b),b},a.models.linePlusBarChart=function(){"use strict";function b(v){return v.each(function(v){function J(a){var b=+("e"==a),c=b?1:-1,d=X/3;return"M"+.5*c+","+d+"A6,6 0 0 "+b+" "+6.5*c+","+(d+6)+"V"+(2*d-6)+"A6,6 0 0 "+b+" "+.5*c+","+2*d+"ZM"+2.5*c+","+(d+8)+"V"+(2*d-8)+"M"+4.5*c+","+(d+8)+"V"+(2*d-8)}function S(){u.empty()||u.extent(I),kb.data([u.empty()?e.domain():I]).each(function(a){var b=e(a[0])-e.range()[0],c=e.range()[1]-e(a[1]);d3.select(this).select(".left").attr("width",0>b?0:b),d3.select(this).select(".right").attr("x",e(a[1])).attr("width",0>c?0:c)})}function T(){I=u.empty()?null:u.extent(),c=u.empty()?e.domain():u.extent(),K.brush({extent:c,brush:u}),S(),l.width(V).height(W).color(v.map(function(a,b){return a.color||C(a,b)}).filter(function(a,b){return!v[b].disabled&&v[b].bar})),j.width(V).height(W).color(v.map(function(a,b){return a.color||C(a,b)}).filter(function(a,b){return!v[b].disabled&&!v[b].bar}));var b=db.select(".nv-focus .nv-barsWrap").datum(Z.length?Z.map(function(a){return{key:a.key,values:a.values.filter(function(a,b){return l.x()(a,b)>=c[0]&&l.x()(a,b)<=c[1]})}}):[{values:[]}]),h=db.select(".nv-focus .nv-linesWrap").datum($[0].disabled?[{values:[]}]:$.map(function(a){return{area:a.area,fillOpacity:a.fillOpacity,key:a.key,values:a.values.filter(function(a,b){return j.x()(a,b)>=c[0]&&j.x()(a,b)<=c[1]})}}));d=Z.length?l.xScale():j.xScale(),n.scale(d)._ticks(a.utils.calcTicksX(V/100,v)).tickSize(-W,0),n.domain([Math.ceil(c[0]),Math.floor(c[1])]),db.select(".nv-x.nv-axis").transition().duration(L).call(n),b.transition().duration(L).call(l),h.transition().duration(L).call(j),db.select(".nv-focus .nv-x.nv-axis").attr("transform","translate(0,"+f.range()[0]+")"),p.scale(f)._ticks(a.utils.calcTicksY(W/36,v)).tickSize(-V,0),q.scale(g)._ticks(a.utils.calcTicksY(W/36,v)).tickSize(Z.length?0:-V,0),db.select(".nv-focus .nv-y1.nv-axis").style("opacity",Z.length?1:0),db.select(".nv-focus .nv-y2.nv-axis").style("opacity",$.length&&!$[0].disabled?1:0).attr("transform","translate("+d.range()[1]+",0)"),db.select(".nv-focus .nv-y1.nv-axis").transition().duration(L).call(p),db.select(".nv-focus .nv-y2.nv-axis").transition().duration(L).call(q)}var U=d3.select(this);a.utils.initSVG(U);var V=a.utils.availableWidth(y,U,w),W=a.utils.availableHeight(z,U,w)-(E?H:0),X=H-x.top-x.bottom;if(b.update=function(){U.transition().duration(L).call(b)},b.container=this,M.setter(R(v),b.update).getter(Q(v)).update(),M.disabled=v.map(function(a){return!!a.disabled}),!N){var Y;N={};for(Y in M)N[Y]=M[Y]instanceof Array?M[Y].slice(0):M[Y]}if(!(v&&v.length&&v.filter(function(a){return a.values.length}).length))return a.utils.noData(b,U),b;U.selectAll(".nv-noData").remove();var Z=v.filter(function(a){return!a.disabled&&a.bar}),$=v.filter(function(a){return!a.bar});d=l.xScale(),e=o.scale(),f=l.yScale(),g=j.yScale(),h=m.yScale(),i=k.yScale();var _=v.filter(function(a){return!a.disabled&&a.bar}).map(function(a){return a.values.map(function(a,b){return{x:A(a,b),y:B(a,b)}})}),ab=v.filter(function(a){return!a.disabled&&!a.bar}).map(function(a){return a.values.map(function(a,b){return{x:A(a,b),y:B(a,b)}})});d.range([0,V]),e.domain(d3.extent(d3.merge(_.concat(ab)),function(a){return a.x})).range([0,V]);var bb=U.selectAll("g.nv-wrap.nv-linePlusBar").data([v]),cb=bb.enter().append("g").attr("class","nvd3 nv-wrap nv-linePlusBar").append("g"),db=bb.select("g");cb.append("g").attr("class","nv-legendWrap");var eb=cb.append("g").attr("class","nv-focus");eb.append("g").attr("class","nv-x nv-axis"),eb.append("g").attr("class","nv-y1 nv-axis"),eb.append("g").attr("class","nv-y2 nv-axis"),eb.append("g").attr("class","nv-barsWrap"),eb.append("g").attr("class","nv-linesWrap");var fb=cb.append("g").attr("class","nv-context");if(fb.append("g").attr("class","nv-x nv-axis"),fb.append("g").attr("class","nv-y1 nv-axis"),fb.append("g").attr("class","nv-y2 nv-axis"),fb.append("g").attr("class","nv-barsWrap"),fb.append("g").attr("class","nv-linesWrap"),fb.append("g").attr("class","nv-brushBackground"),fb.append("g").attr("class","nv-x nv-brush"),D){var gb=t.align()?V/2:V,hb=t.align()?gb:0;t.width(gb),db.select(".nv-legendWrap").datum(v.map(function(a){return a.originalKey=void 0===a.originalKey?a.key:a.originalKey,a.key=a.originalKey+(a.bar?O:P),a})).call(t),w.top!=t.height()&&(w.top=t.height(),W=a.utils.availableHeight(z,U,w)-H),db.select(".nv-legendWrap").attr("transform","translate("+hb+","+-w.top+")")}bb.attr("transform","translate("+w.left+","+w.top+")"),db.select(".nv-context").style("display",E?"initial":"none"),m.width(V).height(X).color(v.map(function(a,b){return a.color||C(a,b)}).filter(function(a,b){return!v[b].disabled&&v[b].bar})),k.width(V).height(X).color(v.map(function(a,b){return a.color||C(a,b)}).filter(function(a,b){return!v[b].disabled&&!v[b].bar}));var ib=db.select(".nv-context .nv-barsWrap").datum(Z.length?Z:[{values:[]}]),jb=db.select(".nv-context .nv-linesWrap").datum($[0].disabled?[{values:[]}]:$);db.select(".nv-context").attr("transform","translate(0,"+(W+w.bottom+x.top)+")"),ib.transition().call(m),jb.transition().call(k),G&&(o._ticks(a.utils.calcTicksX(V/100,v)).tickSize(-X,0),db.select(".nv-context .nv-x.nv-axis").attr("transform","translate(0,"+h.range()[0]+")"),db.select(".nv-context .nv-x.nv-axis").transition().call(o)),F&&(r.scale(h)._ticks(X/36).tickSize(-V,0),s.scale(i)._ticks(X/36).tickSize(Z.length?0:-V,0),db.select(".nv-context .nv-y3.nv-axis").style("opacity",Z.length?1:0).attr("transform","translate(0,"+e.range()[0]+")"),db.select(".nv-context .nv-y2.nv-axis").style("opacity",$.length?1:0).attr("transform","translate("+e.range()[1]+",0)"),db.select(".nv-context .nv-y1.nv-axis").transition().call(r),db.select(".nv-context .nv-y2.nv-axis").transition().call(s)),u.x(e).on("brush",T),I&&u.extent(I);var kb=db.select(".nv-brushBackground").selectAll("g").data([I||u.extent()]),lb=kb.enter().append("g");lb.append("rect").attr("class","left").attr("x",0).attr("y",0).attr("height",X),lb.append("rect").attr("class","right").attr("x",0).attr("y",0).attr("height",X);var mb=db.select(".nv-x.nv-brush").call(u);mb.selectAll("rect").attr("height",X),mb.selectAll(".resize").append("path").attr("d",J),t.dispatch.on("stateChange",function(a){for(var c in a)M[c]=a[c];K.stateChange(M),b.update()}),K.on("changeState",function(a){"undefined"!=typeof a.disabled&&(v.forEach(function(b,c){b.disabled=a.disabled[c]}),M.disabled=a.disabled),b.update()}),T()}),b}var c,d,e,f,g,h,i,j=a.models.line(),k=a.models.line(),l=a.models.historicalBar(),m=a.models.historicalBar(),n=a.models.axis(),o=a.models.axis(),p=a.models.axis(),q=a.models.axis(),r=a.models.axis(),s=a.models.axis(),t=a.models.legend(),u=d3.svg.brush(),v=a.models.tooltip(),w={top:30,right:30,bottom:30,left:60},x={top:0,right:30,bottom:20,left:60},y=null,z=null,A=function(a){return a.x},B=function(a){return a.y},C=a.utils.defaultColor(),D=!0,E=!0,F=!1,G=!0,H=50,I=null,J=null,K=d3.dispatch("brush","stateChange","changeState"),L=0,M=a.utils.state(),N=null,O=" (left axis)",P=" (right axis)";j.clipEdge(!0),k.interactive(!1),n.orient("bottom").tickPadding(5),p.orient("left"),q.orient("right"),o.orient("bottom").tickPadding(5),r.orient("left"),s.orient("right"),v.headerEnabled(!0).headerFormatter(function(a,b){return n.tickFormat()(a,b)});var Q=function(a){return function(){return{active:a.map(function(a){return!a.disabled})}}},R=function(a){return function(b){void 0!==b.active&&a.forEach(function(a,c){a.disabled=!b.active[c]})}};return j.dispatch.on("elementMouseover.tooltip",function(a){v.duration(100).valueFormatter(function(a,b){return q.tickFormat()(a,b)}).data(a).position(a.pos).hidden(!1)}),j.dispatch.on("elementMouseout.tooltip",function(){v.hidden(!0)}),l.dispatch.on("elementMouseover.tooltip",function(a){a.value=b.x()(a.data),a.series={value:b.y()(a.data),color:a.color},v.duration(0).valueFormatter(function(a,b){return p.tickFormat()(a,b)}).data(a).hidden(!1)}),l.dispatch.on("elementMouseout.tooltip",function(){v.hidden(!0)}),l.dispatch.on("elementMousemove.tooltip",function(){v.position({top:d3.event.pageY,left:d3.event.pageX})()}),b.dispatch=K,b.legend=t,b.lines=j,b.lines2=k,b.bars=l,b.bars2=m,b.xAxis=n,b.x2Axis=o,b.y1Axis=p,b.y2Axis=q,b.y3Axis=r,b.y4Axis=s,b.tooltip=v,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return y},set:function(a){y=a}},height:{get:function(){return z},set:function(a){z=a}},showLegend:{get:function(){return D},set:function(a){D=a}},brushExtent:{get:function(){return I},set:function(a){I=a}},noData:{get:function(){return J},set:function(a){J=a}},focusEnable:{get:function(){return E},set:function(a){E=a}},focusHeight:{get:function(){return H},set:function(a){H=a}},focusShowAxisX:{get:function(){return G},set:function(a){G=a}},focusShowAxisY:{get:function(){return F},set:function(a){F=a}},legendLeftAxisHint:{get:function(){return O},set:function(a){O=a}},legendRightAxisHint:{get:function(){return P},set:function(a){P=a}},tooltips:{get:function(){return v.enabled()},set:function(b){a.deprecated("tooltips","use chart.tooltip.enabled() instead"),v.enabled(!!b)}},tooltipContent:{get:function(){return v.contentGenerator()},set:function(b){a.deprecated("tooltipContent","use chart.tooltip.contentGenerator() instead"),v.contentGenerator(b)}},margin:{get:function(){return w},set:function(a){w.top=void 0!==a.top?a.top:w.top,w.right=void 0!==a.right?a.right:w.right,w.bottom=void 0!==a.bottom?a.bottom:w.bottom,w.left=void 0!==a.left?a.left:w.left}},duration:{get:function(){return L},set:function(a){L=a}},color:{get:function(){return C},set:function(b){C=a.utils.getColor(b),t.color(C)}},x:{get:function(){return A},set:function(a){A=a,j.x(a),k.x(a),l.x(a),m.x(a)}},y:{get:function(){return B},set:function(a){B=a,j.y(a),k.y(a),l.y(a),m.y(a)}}}),a.utils.inheritOptions(b,j),a.utils.initOptions(b),b},a.models.lineWithFocusChart=function(){"use strict";function b(o){return o.each(function(o){function z(a){var b=+("e"==a),c=b?1:-1,d=M/3;return"M"+.5*c+","+d+"A6,6 0 0 "+b+" "+6.5*c+","+(d+6)+"V"+(2*d-6)+"A6,6 0 0 "+b+" "+.5*c+","+2*d+"ZM"+2.5*c+","+(d+8)+"V"+(2*d-8)+"M"+4.5*c+","+(d+8)+"V"+(2*d-8)}function G(){n.empty()||n.extent(y),U.data([n.empty()?e.domain():y]).each(function(a){var b=e(a[0])-c.range()[0],d=K-e(a[1]);d3.select(this).select(".left").attr("width",0>b?0:b),d3.select(this).select(".right").attr("x",e(a[1])).attr("width",0>d?0:d)})}function H(){y=n.empty()?null:n.extent();var a=n.empty()?e.domain():n.extent();if(!(Math.abs(a[0]-a[1])<=1)){A.brush({extent:a,brush:n}),G();var b=Q.select(".nv-focus .nv-linesWrap").datum(o.filter(function(a){return!a.disabled}).map(function(b){return{key:b.key,area:b.area,values:b.values.filter(function(b,c){return g.x()(b,c)>=a[0]&&g.x()(b,c)<=a[1]})}}));b.transition().duration(B).call(g),Q.select(".nv-focus .nv-x.nv-axis").transition().duration(B).call(i),Q.select(".nv-focus .nv-y.nv-axis").transition().duration(B).call(j)}}var I=d3.select(this),J=this;a.utils.initSVG(I);var K=a.utils.availableWidth(t,I,q),L=a.utils.availableHeight(u,I,q)-v,M=v-r.top-r.bottom;if(b.update=function(){I.transition().duration(B).call(b)},b.container=this,C.setter(F(o),b.update).getter(E(o)).update(),C.disabled=o.map(function(a){return!!a.disabled}),!D){var N;D={};for(N in C)D[N]=C[N]instanceof Array?C[N].slice(0):C[N]}if(!(o&&o.length&&o.filter(function(a){return a.values.length}).length))return a.utils.noData(b,I),b;I.selectAll(".nv-noData").remove(),c=g.xScale(),d=g.yScale(),e=h.xScale(),f=h.yScale();var O=I.selectAll("g.nv-wrap.nv-lineWithFocusChart").data([o]),P=O.enter().append("g").attr("class","nvd3 nv-wrap nv-lineWithFocusChart").append("g"),Q=O.select("g");P.append("g").attr("class","nv-legendWrap");var R=P.append("g").attr("class","nv-focus");R.append("g").attr("class","nv-x nv-axis"),R.append("g").attr("class","nv-y nv-axis"),R.append("g").attr("class","nv-linesWrap"),R.append("g").attr("class","nv-interactive");var S=P.append("g").attr("class","nv-context");S.append("g").attr("class","nv-x nv-axis"),S.append("g").attr("class","nv-y nv-axis"),S.append("g").attr("class","nv-linesWrap"),S.append("g").attr("class","nv-brushBackground"),S.append("g").attr("class","nv-x nv-brush"),x&&(m.width(K),Q.select(".nv-legendWrap").datum(o).call(m),q.top!=m.height()&&(q.top=m.height(),L=a.utils.availableHeight(u,I,q)-v),Q.select(".nv-legendWrap").attr("transform","translate(0,"+-q.top+")")),O.attr("transform","translate("+q.left+","+q.top+")"),w&&(p.width(K).height(L).margin({left:q.left,top:q.top}).svgContainer(I).xScale(c),O.select(".nv-interactive").call(p)),g.width(K).height(L).color(o.map(function(a,b){return a.color||s(a,b)}).filter(function(a,b){return!o[b].disabled})),h.defined(g.defined()).width(K).height(M).color(o.map(function(a,b){return a.color||s(a,b)}).filter(function(a,b){return!o[b].disabled})),Q.select(".nv-context").attr("transform","translate(0,"+(L+q.bottom+r.top)+")");var T=Q.select(".nv-context .nv-linesWrap").datum(o.filter(function(a){return!a.disabled}));d3.transition(T).call(h),i.scale(c)._ticks(a.utils.calcTicksX(K/100,o)).tickSize(-L,0),j.scale(d)._ticks(a.utils.calcTicksY(L/36,o)).tickSize(-K,0),Q.select(".nv-focus .nv-x.nv-axis").attr("transform","translate(0,"+L+")"),n.x(e).on("brush",function(){H()}),y&&n.extent(y);var U=Q.select(".nv-brushBackground").selectAll("g").data([y||n.extent()]),V=U.enter().append("g");V.append("rect").attr("class","left").attr("x",0).attr("y",0).attr("height",M),V.append("rect").attr("class","right").attr("x",0).attr("y",0).attr("height",M);var W=Q.select(".nv-x.nv-brush").call(n);W.selectAll("rect").attr("height",M),W.selectAll(".resize").append("path").attr("d",z),H(),k.scale(e)._ticks(a.utils.calcTicksX(K/100,o)).tickSize(-M,0),Q.select(".nv-context .nv-x.nv-axis").attr("transform","translate(0,"+f.range()[0]+")"),d3.transition(Q.select(".nv-context .nv-x.nv-axis")).call(k),l.scale(f)._ticks(a.utils.calcTicksY(M/36,o)).tickSize(-K,0),d3.transition(Q.select(".nv-context .nv-y.nv-axis")).call(l),Q.select(".nv-context .nv-x.nv-axis").attr("transform","translate(0,"+f.range()[0]+")"),m.dispatch.on("stateChange",function(a){for(var c in a)C[c]=a[c];A.stateChange(C),b.update()}),p.dispatch.on("elementMousemove",function(c){g.clearHighlights();var d,f,h,k=[];if(o.filter(function(a,b){return a.seriesIndex=b,!a.disabled}).forEach(function(i,j){var l=n.empty()?e.domain():n.extent(),m=i.values.filter(function(a,b){return g.x()(a,b)>=l[0]&&g.x()(a,b)<=l[1]});f=a.interactiveBisect(m,c.pointXValue,g.x());var o=m[f],p=b.y()(o,f);null!=p&&g.highlightPoint(j,f,!0),void 0!==o&&(void 0===d&&(d=o),void 0===h&&(h=b.xScale()(b.x()(o,f))),k.push({key:i.key,value:b.y()(o,f),color:s(i,i.seriesIndex)}))}),k.length>2){var l=b.yScale().invert(c.mouseY),m=Math.abs(b.yScale().domain()[0]-b.yScale().domain()[1]),r=.03*m,t=a.nearestValueIndex(k.map(function(a){return a.value}),l,r);null!==t&&(k[t].highlight=!0)}var u=i.tickFormat()(b.x()(d,f));p.tooltip.position({left:c.mouseX+q.left,top:c.mouseY+q.top}).chartContainer(J.parentNode).valueFormatter(function(a){return null==a?"N/A":j.tickFormat()(a)}).data({value:u,index:f,series:k})(),p.renderGuideLine(h)}),p.dispatch.on("elementMouseout",function(){g.clearHighlights()}),A.on("changeState",function(a){"undefined"!=typeof a.disabled&&o.forEach(function(b,c){b.disabled=a.disabled[c]}),b.update()})}),b}var c,d,e,f,g=a.models.line(),h=a.models.line(),i=a.models.axis(),j=a.models.axis(),k=a.models.axis(),l=a.models.axis(),m=a.models.legend(),n=d3.svg.brush(),o=a.models.tooltip(),p=a.interactiveGuideline(),q={top:30,right:30,bottom:30,left:60},r={top:0,right:30,bottom:20,left:60},s=a.utils.defaultColor(),t=null,u=null,v=50,w=!1,x=!0,y=null,z=null,A=d3.dispatch("brush","stateChange","changeState"),B=250,C=a.utils.state(),D=null;g.clipEdge(!0).duration(0),h.interactive(!1),i.orient("bottom").tickPadding(5),j.orient("left"),k.orient("bottom").tickPadding(5),l.orient("left"),o.valueFormatter(function(a,b){return j.tickFormat()(a,b)}).headerFormatter(function(a,b){return i.tickFormat()(a,b)});var E=function(a){return function(){return{active:a.map(function(a){return!a.disabled})}}},F=function(a){return function(b){void 0!==b.active&&a.forEach(function(a,c){a.disabled=!b.active[c]})}};return g.dispatch.on("elementMouseover.tooltip",function(a){o.data(a).position(a.pos).hidden(!1)}),g.dispatch.on("elementMouseout.tooltip",function(){o.hidden(!0)}),b.dispatch=A,b.legend=m,b.lines=g,b.lines2=h,b.xAxis=i,b.yAxis=j,b.x2Axis=k,b.y2Axis=l,b.interactiveLayer=p,b.tooltip=o,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return t},set:function(a){t=a}},height:{get:function(){return u},set:function(a){u=a}},focusHeight:{get:function(){return v},set:function(a){v=a}},showLegend:{get:function(){return x},set:function(a){x=a}},brushExtent:{get:function(){return y},set:function(a){y=a}},defaultState:{get:function(){return D},set:function(a){D=a}},noData:{get:function(){return z},set:function(a){z=a}},tooltips:{get:function(){return o.enabled()},set:function(b){a.deprecated("tooltips","use chart.tooltip.enabled() instead"),o.enabled(!!b)}},tooltipContent:{get:function(){return o.contentGenerator()},set:function(b){a.deprecated("tooltipContent","use chart.tooltip.contentGenerator() instead"),o.contentGenerator(b)}},margin:{get:function(){return q},set:function(a){q.top=void 0!==a.top?a.top:q.top,q.right=void 0!==a.right?a.right:q.right,q.bottom=void 0!==a.bottom?a.bottom:q.bottom,q.left=void 0!==a.left?a.left:q.left}},color:{get:function(){return s},set:function(b){s=a.utils.getColor(b),m.color(s)}},interpolate:{get:function(){return g.interpolate()},set:function(a){g.interpolate(a),h.interpolate(a)}},xTickFormat:{get:function(){return i.tickFormat()},set:function(a){i.tickFormat(a),k.tickFormat(a)}},yTickFormat:{get:function(){return j.tickFormat()},set:function(a){j.tickFormat(a),l.tickFormat(a)}},duration:{get:function(){return B},set:function(a){B=a,j.duration(B),l.duration(B),i.duration(B),k.duration(B)}},x:{get:function(){return g.x()},set:function(a){g.x(a),h.x(a)}},y:{get:function(){return g.y()},set:function(a){g.y(a),h.y(a)}},useInteractiveGuideline:{get:function(){return w},set:function(a){w=a,w&&(g.interactive(!1),g.useVoronoi(!1))}}}),a.utils.inheritOptions(b,g),a.utils.initOptions(b),b},a.models.multiBar=function(){"use strict";function b(E){return C.reset(),E.each(function(b){var E=k-j.left-j.right,F=l-j.top-j.bottom;p=d3.select(this),a.utils.initSVG(p);var G=0;if(x&&b.length&&(x=[{values:b[0].values.map(function(a){return{x:a.x,y:0,series:a.series,size:.01}})}]),u){var H=d3.layout.stack().offset(v).values(function(a){return a.values}).y(r)(!b.length&&x?x:b);H.forEach(function(a,c){a.nonStackable?(b[c].nonStackableSeries=G++,H[c]=b[c]):c>0&&H[c-1].nonStackable&&H[c].values.map(function(a,b){a.y0-=H[c-1].values[b].y,a.y1=a.y0+a.y})}),b=H}b.forEach(function(a,b){a.values.forEach(function(c){c.series=b,c.key=a.key})}),u&&b[0].values.map(function(a,c){var d=0,e=0;b.map(function(a,f){if(!b[f].nonStackable){var g=a.values[c];g.size=Math.abs(g.y),g.y<0?(g.y1=e,e-=g.size):(g.y1=g.size+d,d+=g.size)}})});var I=d&&e?[]:b.map(function(a,b){return a.values.map(function(a,c){return{x:q(a,c),y:r(a,c),y0:a.y0,y1:a.y1,idx:b}})});m.domain(d||d3.merge(I).map(function(a){return a.x})).rangeBands(f||[0,E],A),n.domain(e||d3.extent(d3.merge(I).map(function(a){var c=a.y;return u&&!b[a.idx].nonStackable&&(c=a.y>0?a.y1:a.y1+a.y),c}).concat(s))).range(g||[F,0]),m.domain()[0]===m.domain()[1]&&m.domain(m.domain()[0]?[m.domain()[0]-.01*m.domain()[0],m.domain()[1]+.01*m.domain()[1]]:[-1,1]),n.domain()[0]===n.domain()[1]&&n.domain(n.domain()[0]?[n.domain()[0]+.01*n.domain()[0],n.domain()[1]-.01*n.domain()[1]]:[-1,1]),h=h||m,i=i||n;var J=p.selectAll("g.nv-wrap.nv-multibar").data([b]),K=J.enter().append("g").attr("class","nvd3 nv-wrap nv-multibar"),L=K.append("defs"),M=K.append("g"),N=J.select("g");M.append("g").attr("class","nv-groups"),J.attr("transform","translate("+j.left+","+j.top+")"),L.append("clipPath").attr("id","nv-edge-clip-"+o).append("rect"),J.select("#nv-edge-clip-"+o+" rect").attr("width",E).attr("height",F),N.attr("clip-path",t?"url(#nv-edge-clip-"+o+")":"");var O=J.select(".nv-groups").selectAll(".nv-group").data(function(a){return a},function(a,b){return b});O.enter().append("g").style("stroke-opacity",1e-6).style("fill-opacity",1e-6);var P=C.transition(O.exit().selectAll("rect.nv-bar"),"multibarExit",Math.min(100,z)).attr("y",function(a){var c=i(0)||0;return u&&b[a.series]&&!b[a.series].nonStackable&&(c=i(a.y0)),c}).attr("height",0).remove();P.delay&&P.delay(function(a,b){var c=b*(z/(D+1))-b;return c}),O.attr("class",function(a,b){return"nv-group nv-series-"+b}).classed("hover",function(a){return a.hover}).style("fill",function(a,b){return w(a,b)}).style("stroke",function(a,b){return w(a,b)}),O.style("stroke-opacity",1).style("fill-opacity",.75);var Q=O.selectAll("rect.nv-bar").data(function(a){return x&&!b.length?x.values:a.values});Q.exit().remove();Q.enter().append("rect").attr("class",function(a,b){return r(a,b)<0?"nv-bar negative":"nv-bar positive"}).attr("x",function(a,c,d){return u&&!b[d].nonStackable?0:d*m.rangeBand()/b.length}).attr("y",function(a,c,d){return i(u&&!b[d].nonStackable?a.y0:0)||0}).attr("height",0).attr("width",function(a,c,d){return m.rangeBand()/(u&&!b[d].nonStackable?1:b.length)}).attr("transform",function(a,b){return"translate("+m(q(a,b))+",0)"});Q.style("fill",function(a,b,c){return w(a,c,b)}).style("stroke",function(a,b,c){return w(a,c,b)}).on("mouseover",function(a,b){d3.select(this).classed("hover",!0),B.elementMouseover({data:a,index:b,color:d3.select(this).style("fill")})}).on("mouseout",function(a,b){d3.select(this).classed("hover",!1),B.elementMouseout({data:a,index:b,color:d3.select(this).style("fill")})}).on("mousemove",function(a,b){B.elementMousemove({data:a,index:b,color:d3.select(this).style("fill")})}).on("click",function(a,b){B.elementClick({data:a,index:b,color:d3.select(this).style("fill")}),d3.event.stopPropagation()}).on("dblclick",function(a,b){B.elementDblClick({data:a,index:b,color:d3.select(this).style("fill")}),d3.event.stopPropagation()}),Q.attr("class",function(a,b){return r(a,b)<0?"nv-bar negative":"nv-bar positive"}).attr("transform",function(a,b){return"translate("+m(q(a,b))+",0)"}),y&&(c||(c=b.map(function(){return!0})),Q.style("fill",function(a,b,d){return d3.rgb(y(a,b)).darker(c.map(function(a,b){return b}).filter(function(a,b){return!c[b]})[d]).toString()}).style("stroke",function(a,b,d){return d3.rgb(y(a,b)).darker(c.map(function(a,b){return b}).filter(function(a,b){return!c[b]})[d]).toString()}));var R=Q.watchTransition(C,"multibar",Math.min(250,z)).delay(function(a,c){return c*z/b[0].values.length});u?R.attr("y",function(a,c,d){var e=0;return e=b[d].nonStackable?r(a,c)<0?n(0):n(0)-n(r(a,c))<-1?n(0)-1:n(r(a,c))||0:n(a.y1)}).attr("height",function(a,c,d){return b[d].nonStackable?Math.max(Math.abs(n(r(a,c))-n(0)),1)||0:Math.max(Math.abs(n(a.y+a.y0)-n(a.y0)),1)}).attr("x",function(a,c,d){var e=0;return b[d].nonStackable&&(e=a.series*m.rangeBand()/b.length,b.length!==G&&(e=b[d].nonStackableSeries*m.rangeBand()/(2*G))),e}).attr("width",function(a,c,d){if(b[d].nonStackable){var e=m.rangeBand()/G;return b.length!==G&&(e=m.rangeBand()/(2*G)),e}return m.rangeBand()}):R.attr("x",function(a){return a.series*m.rangeBand()/b.length}).attr("width",m.rangeBand()/b.length).attr("y",function(a,b){return r(a,b)<0?n(0):n(0)-n(r(a,b))<1?n(0)-1:n(r(a,b))||0}).attr("height",function(a,b){return Math.max(Math.abs(n(r(a,b))-n(0)),1)||0}),h=m.copy(),i=n.copy(),b[0]&&b[0].values&&(D=b[0].values.length)}),C.renderEnd("multibar immediate"),b}var c,d,e,f,g,h,i,j={top:0,right:0,bottom:0,left:0},k=960,l=500,m=d3.scale.ordinal(),n=d3.scale.linear(),o=Math.floor(1e4*Math.random()),p=null,q=function(a){return a.x},r=function(a){return a.y},s=[0],t=!0,u=!1,v="zero",w=a.utils.defaultColor(),x=!1,y=null,z=500,A=.1,B=d3.dispatch("chartClick","elementClick","elementDblClick","elementMouseover","elementMouseout","elementMousemove","renderEnd"),C=a.utils.renderWatch(B,z),D=0;return b.dispatch=B,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return k},set:function(a){k=a}},height:{get:function(){return l},set:function(a){l=a}},x:{get:function(){return q},set:function(a){q=a}},y:{get:function(){return r},set:function(a){r=a}},xScale:{get:function(){return m},set:function(a){m=a}},yScale:{get:function(){return n},set:function(a){n=a}},xDomain:{get:function(){return d},set:function(a){d=a}},yDomain:{get:function(){return e},set:function(a){e=a}},xRange:{get:function(){return f},set:function(a){f=a}},yRange:{get:function(){return g},set:function(a){g=a}},forceY:{get:function(){return s},set:function(a){s=a}},stacked:{get:function(){return u},set:function(a){u=a}},stackOffset:{get:function(){return v},set:function(a){v=a}},clipEdge:{get:function(){return t},set:function(a){t=a}},disabled:{get:function(){return c},set:function(a){c=a}},id:{get:function(){return o},set:function(a){o=a}},hideable:{get:function(){return x},set:function(a){x=a}},groupSpacing:{get:function(){return A},set:function(a){A=a}},margin:{get:function(){return j},set:function(a){j.top=void 0!==a.top?a.top:j.top,j.right=void 0!==a.right?a.right:j.right,j.bottom=void 0!==a.bottom?a.bottom:j.bottom,j.left=void 0!==a.left?a.left:j.left}},duration:{get:function(){return z},set:function(a){z=a,C.reset(z)}},color:{get:function(){return w},set:function(b){w=a.utils.getColor(b)}},barColor:{get:function(){return y},set:function(b){y=b?a.utils.getColor(b):null}}}),a.utils.initOptions(b),b},a.models.multiBarChart=function(){"use strict";function b(j){return D.reset(),D.models(e),r&&D.models(f),s&&D.models(g),j.each(function(j){var z=d3.select(this);a.utils.initSVG(z);var D=a.utils.availableWidth(l,z,k),H=a.utils.availableHeight(m,z,k);if(b.update=function(){0===C?z.call(b):z.transition().duration(C).call(b)},b.container=this,x.setter(G(j),b.update).getter(F(j)).update(),x.disabled=j.map(function(a){return!!a.disabled}),!y){var I;y={};for(I in x)y[I]=x[I]instanceof Array?x[I].slice(0):x[I]}if(!(j&&j.length&&j.filter(function(a){return a.values.length}).length))return a.utils.noData(b,z),b;z.selectAll(".nv-noData").remove(),c=e.xScale(),d=e.yScale(); -var J=z.selectAll("g.nv-wrap.nv-multiBarWithLegend").data([j]),K=J.enter().append("g").attr("class","nvd3 nv-wrap nv-multiBarWithLegend").append("g"),L=J.select("g");if(K.append("g").attr("class","nv-x nv-axis"),K.append("g").attr("class","nv-y nv-axis"),K.append("g").attr("class","nv-barsWrap"),K.append("g").attr("class","nv-legendWrap"),K.append("g").attr("class","nv-controlsWrap"),q&&(h.width(D-B()),L.select(".nv-legendWrap").datum(j).call(h),k.top!=h.height()&&(k.top=h.height(),H=a.utils.availableHeight(m,z,k)),L.select(".nv-legendWrap").attr("transform","translate("+B()+","+-k.top+")")),o){var M=[{key:p.grouped||"Grouped",disabled:e.stacked()},{key:p.stacked||"Stacked",disabled:!e.stacked()}];i.width(B()).color(["#444","#444","#444"]),L.select(".nv-controlsWrap").datum(M).attr("transform","translate(0,"+-k.top+")").call(i)}J.attr("transform","translate("+k.left+","+k.top+")"),t&&L.select(".nv-y.nv-axis").attr("transform","translate("+D+",0)"),e.disabled(j.map(function(a){return a.disabled})).width(D).height(H).color(j.map(function(a,b){return a.color||n(a,b)}).filter(function(a,b){return!j[b].disabled}));var N=L.select(".nv-barsWrap").datum(j.filter(function(a){return!a.disabled}));if(N.call(e),r){f.scale(c)._ticks(a.utils.calcTicksX(D/100,j)).tickSize(-H,0),L.select(".nv-x.nv-axis").attr("transform","translate(0,"+d.range()[0]+")"),L.select(".nv-x.nv-axis").call(f);var O=L.select(".nv-x.nv-axis > g").selectAll("g");if(O.selectAll("line, text").style("opacity",1),v){var P=function(a,b){return"translate("+a+","+b+")"},Q=5,R=17;O.selectAll("text").attr("transform",function(a,b,c){return P(0,c%2==0?Q:R)});var S=d3.selectAll(".nv-x.nv-axis .nv-wrap g g text")[0].length;L.selectAll(".nv-x.nv-axis .nv-axisMaxMin text").attr("transform",function(a,b){return P(0,0===b||S%2!==0?R:Q)})}u&&O.filter(function(a,b){return b%Math.ceil(j[0].values.length/(D/100))!==0}).selectAll("text, line").style("opacity",0),w&&O.selectAll(".tick text").attr("transform","rotate("+w+" 0,0)").style("text-anchor",w>0?"start":"end"),L.select(".nv-x.nv-axis").selectAll("g.nv-axisMaxMin text").style("opacity",1)}s&&(g.scale(d)._ticks(a.utils.calcTicksY(H/36,j)).tickSize(-D,0),L.select(".nv-y.nv-axis").call(g)),h.dispatch.on("stateChange",function(a){for(var c in a)x[c]=a[c];A.stateChange(x),b.update()}),i.dispatch.on("legendClick",function(a){if(a.disabled){switch(M=M.map(function(a){return a.disabled=!0,a}),a.disabled=!1,a.key){case"Grouped":case p.grouped:e.stacked(!1);break;case"Stacked":case p.stacked:e.stacked(!0)}x.stacked=e.stacked(),A.stateChange(x),b.update()}}),A.on("changeState",function(a){"undefined"!=typeof a.disabled&&(j.forEach(function(b,c){b.disabled=a.disabled[c]}),x.disabled=a.disabled),"undefined"!=typeof a.stacked&&(e.stacked(a.stacked),x.stacked=a.stacked,E=a.stacked),b.update()})}),D.renderEnd("multibarchart immediate"),b}var c,d,e=a.models.multiBar(),f=a.models.axis(),g=a.models.axis(),h=a.models.legend(),i=a.models.legend(),j=a.models.tooltip(),k={top:30,right:20,bottom:50,left:60},l=null,m=null,n=a.utils.defaultColor(),o=!0,p={},q=!0,r=!0,s=!0,t=!1,u=!0,v=!1,w=0,x=a.utils.state(),y=null,z=null,A=d3.dispatch("stateChange","changeState","renderEnd"),B=function(){return o?180:0},C=250;x.stacked=!1,e.stacked(!1),f.orient("bottom").tickPadding(7).showMaxMin(!1).tickFormat(function(a){return a}),g.orient(t?"right":"left").tickFormat(d3.format(",.1f")),j.duration(0).valueFormatter(function(a,b){return g.tickFormat()(a,b)}).headerFormatter(function(a,b){return f.tickFormat()(a,b)}),i.updateState(!1);var D=a.utils.renderWatch(A),E=!1,F=function(a){return function(){return{active:a.map(function(a){return!a.disabled}),stacked:E}}},G=function(a){return function(b){void 0!==b.stacked&&(E=b.stacked),void 0!==b.active&&a.forEach(function(a,c){a.disabled=!b.active[c]})}};return e.dispatch.on("elementMouseover.tooltip",function(a){a.value=b.x()(a.data),a.series={key:a.data.key,value:b.y()(a.data),color:a.color},j.data(a).hidden(!1)}),e.dispatch.on("elementMouseout.tooltip",function(){j.hidden(!0)}),e.dispatch.on("elementMousemove.tooltip",function(){j.position({top:d3.event.pageY,left:d3.event.pageX})()}),b.dispatch=A,b.multibar=e,b.legend=h,b.controls=i,b.xAxis=f,b.yAxis=g,b.state=x,b.tooltip=j,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return l},set:function(a){l=a}},height:{get:function(){return m},set:function(a){m=a}},showLegend:{get:function(){return q},set:function(a){q=a}},showControls:{get:function(){return o},set:function(a){o=a}},controlLabels:{get:function(){return p},set:function(a){p=a}},showXAxis:{get:function(){return r},set:function(a){r=a}},showYAxis:{get:function(){return s},set:function(a){s=a}},defaultState:{get:function(){return y},set:function(a){y=a}},noData:{get:function(){return z},set:function(a){z=a}},reduceXTicks:{get:function(){return u},set:function(a){u=a}},rotateLabels:{get:function(){return w},set:function(a){w=a}},staggerLabels:{get:function(){return v},set:function(a){v=a}},tooltips:{get:function(){return j.enabled()},set:function(b){a.deprecated("tooltips","use chart.tooltip.enabled() instead"),j.enabled(!!b)}},tooltipContent:{get:function(){return j.contentGenerator()},set:function(b){a.deprecated("tooltipContent","use chart.tooltip.contentGenerator() instead"),j.contentGenerator(b)}},margin:{get:function(){return k},set:function(a){k.top=void 0!==a.top?a.top:k.top,k.right=void 0!==a.right?a.right:k.right,k.bottom=void 0!==a.bottom?a.bottom:k.bottom,k.left=void 0!==a.left?a.left:k.left}},duration:{get:function(){return C},set:function(a){C=a,e.duration(C),f.duration(C),g.duration(C),D.reset(C)}},color:{get:function(){return n},set:function(b){n=a.utils.getColor(b),h.color(n)}},rightAlignYAxis:{get:function(){return t},set:function(a){t=a,g.orient(t?"right":"left")}},barColor:{get:function(){return e.barColor},set:function(a){e.barColor(a),h.color(function(a,b){return d3.rgb("#ccc").darker(1.5*b).toString()})}}}),a.utils.inheritOptions(b,e),a.utils.initOptions(b),b},a.models.multiBarHorizontal=function(){"use strict";function b(m){return E.reset(),m.each(function(b){var m=k-j.left-j.right,C=l-j.top-j.bottom;n=d3.select(this),a.utils.initSVG(n),w&&(b=d3.layout.stack().offset("zero").values(function(a){return a.values}).y(r)(b)),b.forEach(function(a,b){a.values.forEach(function(c){c.series=b,c.key=a.key})}),w&&b[0].values.map(function(a,c){var d=0,e=0;b.map(function(a){var b=a.values[c];b.size=Math.abs(b.y),b.y<0?(b.y1=e-b.size,e-=b.size):(b.y1=d,d+=b.size)})});var F=d&&e?[]:b.map(function(a){return a.values.map(function(a,b){return{x:q(a,b),y:r(a,b),y0:a.y0,y1:a.y1}})});o.domain(d||d3.merge(F).map(function(a){return a.x})).rangeBands(f||[0,C],A),p.domain(e||d3.extent(d3.merge(F).map(function(a){return w?a.y>0?a.y1+a.y:a.y1:a.y}).concat(t))),p.range(x&&!w?g||[p.domain()[0]<0?z:0,m-(p.domain()[1]>0?z:0)]:g||[0,m]),h=h||o,i=i||d3.scale.linear().domain(p.domain()).range([p(0),p(0)]);{var G=d3.select(this).selectAll("g.nv-wrap.nv-multibarHorizontal").data([b]),H=G.enter().append("g").attr("class","nvd3 nv-wrap nv-multibarHorizontal"),I=(H.append("defs"),H.append("g"));G.select("g")}I.append("g").attr("class","nv-groups"),G.attr("transform","translate("+j.left+","+j.top+")");var J=G.select(".nv-groups").selectAll(".nv-group").data(function(a){return a},function(a,b){return b});J.enter().append("g").style("stroke-opacity",1e-6).style("fill-opacity",1e-6),J.exit().watchTransition(E,"multibarhorizontal: exit groups").style("stroke-opacity",1e-6).style("fill-opacity",1e-6).remove(),J.attr("class",function(a,b){return"nv-group nv-series-"+b}).classed("hover",function(a){return a.hover}).style("fill",function(a,b){return u(a,b)}).style("stroke",function(a,b){return u(a,b)}),J.watchTransition(E,"multibarhorizontal: groups").style("stroke-opacity",1).style("fill-opacity",.75);var K=J.selectAll("g.nv-bar").data(function(a){return a.values});K.exit().remove();var L=K.enter().append("g").attr("transform",function(a,c,d){return"translate("+i(w?a.y0:0)+","+(w?0:d*o.rangeBand()/b.length+o(q(a,c)))+")"});L.append("rect").attr("width",0).attr("height",o.rangeBand()/(w?1:b.length)),K.on("mouseover",function(a,b){d3.select(this).classed("hover",!0),D.elementMouseover({data:a,index:b,color:d3.select(this).style("fill")})}).on("mouseout",function(a,b){d3.select(this).classed("hover",!1),D.elementMouseout({data:a,index:b,color:d3.select(this).style("fill")})}).on("mouseout",function(a,b){D.elementMouseout({data:a,index:b,color:d3.select(this).style("fill")})}).on("mousemove",function(a,b){D.elementMousemove({data:a,index:b,color:d3.select(this).style("fill")})}).on("click",function(a,b){D.elementClick({data:a,index:b,color:d3.select(this).style("fill")}),d3.event.stopPropagation()}).on("dblclick",function(a,b){D.elementDblClick({data:a,index:b,color:d3.select(this).style("fill")}),d3.event.stopPropagation()}),s(b[0],0)&&(L.append("polyline"),K.select("polyline").attr("fill","none").attr("points",function(a,c){var d=s(a,c),e=.8*o.rangeBand()/(2*(w?1:b.length));d=d.length?d:[-Math.abs(d),Math.abs(d)],d=d.map(function(a){return p(a)-p(0)});var f=[[d[0],-e],[d[0],e],[d[0],0],[d[1],0],[d[1],-e],[d[1],e]];return f.map(function(a){return a.join(",")}).join(" ")}).attr("transform",function(a,c){var d=o.rangeBand()/(2*(w?1:b.length));return"translate("+(r(a,c)<0?0:p(r(a,c))-p(0))+", "+d+")"})),L.append("text"),x&&!w?(K.select("text").attr("text-anchor",function(a,b){return r(a,b)<0?"end":"start"}).attr("y",o.rangeBand()/(2*b.length)).attr("dy",".32em").text(function(a,b){var c=B(r(a,b)),d=s(a,b);return void 0===d?c:d.length?c+"+"+B(Math.abs(d[1]))+"-"+B(Math.abs(d[0])):c+"±"+B(Math.abs(d))}),K.watchTransition(E,"multibarhorizontal: bars").select("text").attr("x",function(a,b){return r(a,b)<0?-4:p(r(a,b))-p(0)+4})):K.selectAll("text").text(""),y&&!w?(L.append("text").classed("nv-bar-label",!0),K.select("text.nv-bar-label").attr("text-anchor",function(a,b){return r(a,b)<0?"start":"end"}).attr("y",o.rangeBand()/(2*b.length)).attr("dy",".32em").text(function(a,b){return q(a,b)}),K.watchTransition(E,"multibarhorizontal: bars").select("text.nv-bar-label").attr("x",function(a,b){return r(a,b)<0?p(0)-p(r(a,b))+4:-4})):K.selectAll("text.nv-bar-label").text(""),K.attr("class",function(a,b){return r(a,b)<0?"nv-bar negative":"nv-bar positive"}),v&&(c||(c=b.map(function(){return!0})),K.style("fill",function(a,b,d){return d3.rgb(v(a,b)).darker(c.map(function(a,b){return b}).filter(function(a,b){return!c[b]})[d]).toString()}).style("stroke",function(a,b,d){return d3.rgb(v(a,b)).darker(c.map(function(a,b){return b}).filter(function(a,b){return!c[b]})[d]).toString()})),w?K.watchTransition(E,"multibarhorizontal: bars").attr("transform",function(a,b){return"translate("+p(a.y1)+","+o(q(a,b))+")"}).select("rect").attr("width",function(a,b){return Math.abs(p(r(a,b)+a.y0)-p(a.y0))}).attr("height",o.rangeBand()):K.watchTransition(E,"multibarhorizontal: bars").attr("transform",function(a,c){return"translate("+p(r(a,c)<0?r(a,c):0)+","+(a.series*o.rangeBand()/b.length+o(q(a,c)))+")"}).select("rect").attr("height",o.rangeBand()/b.length).attr("width",function(a,b){return Math.max(Math.abs(p(r(a,b))-p(0)),1)}),h=o.copy(),i=p.copy()}),E.renderEnd("multibarHorizontal immediate"),b}var c,d,e,f,g,h,i,j={top:0,right:0,bottom:0,left:0},k=960,l=500,m=Math.floor(1e4*Math.random()),n=null,o=d3.scale.ordinal(),p=d3.scale.linear(),q=function(a){return a.x},r=function(a){return a.y},s=function(a){return a.yErr},t=[0],u=a.utils.defaultColor(),v=null,w=!1,x=!1,y=!1,z=60,A=.1,B=d3.format(",.2f"),C=250,D=d3.dispatch("chartClick","elementClick","elementDblClick","elementMouseover","elementMouseout","elementMousemove","renderEnd"),E=a.utils.renderWatch(D,C);return b.dispatch=D,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return k},set:function(a){k=a}},height:{get:function(){return l},set:function(a){l=a}},x:{get:function(){return q},set:function(a){q=a}},y:{get:function(){return r},set:function(a){r=a}},yErr:{get:function(){return s},set:function(a){s=a}},xScale:{get:function(){return o},set:function(a){o=a}},yScale:{get:function(){return p},set:function(a){p=a}},xDomain:{get:function(){return d},set:function(a){d=a}},yDomain:{get:function(){return e},set:function(a){e=a}},xRange:{get:function(){return f},set:function(a){f=a}},yRange:{get:function(){return g},set:function(a){g=a}},forceY:{get:function(){return t},set:function(a){t=a}},stacked:{get:function(){return w},set:function(a){w=a}},showValues:{get:function(){return x},set:function(a){x=a}},disabled:{get:function(){return c},set:function(a){c=a}},id:{get:function(){return m},set:function(a){m=a}},valueFormat:{get:function(){return B},set:function(a){B=a}},valuePadding:{get:function(){return z},set:function(a){z=a}},groupSpacing:{get:function(){return A},set:function(a){A=a}},margin:{get:function(){return j},set:function(a){j.top=void 0!==a.top?a.top:j.top,j.right=void 0!==a.right?a.right:j.right,j.bottom=void 0!==a.bottom?a.bottom:j.bottom,j.left=void 0!==a.left?a.left:j.left}},duration:{get:function(){return C},set:function(a){C=a,E.reset(C)}},color:{get:function(){return u},set:function(b){u=a.utils.getColor(b)}},barColor:{get:function(){return v},set:function(b){v=b?a.utils.getColor(b):null}}}),a.utils.initOptions(b),b},a.models.multiBarHorizontalChart=function(){"use strict";function b(j){return C.reset(),C.models(e),r&&C.models(f),s&&C.models(g),j.each(function(j){var w=d3.select(this);a.utils.initSVG(w);var C=a.utils.availableWidth(l,w,k),D=a.utils.availableHeight(m,w,k);if(b.update=function(){w.transition().duration(z).call(b)},b.container=this,t=e.stacked(),u.setter(B(j),b.update).getter(A(j)).update(),u.disabled=j.map(function(a){return!!a.disabled}),!v){var E;v={};for(E in u)v[E]=u[E]instanceof Array?u[E].slice(0):u[E]}if(!(j&&j.length&&j.filter(function(a){return a.values.length}).length))return a.utils.noData(b,w),b;w.selectAll(".nv-noData").remove(),c=e.xScale(),d=e.yScale();var F=w.selectAll("g.nv-wrap.nv-multiBarHorizontalChart").data([j]),G=F.enter().append("g").attr("class","nvd3 nv-wrap nv-multiBarHorizontalChart").append("g"),H=F.select("g");if(G.append("g").attr("class","nv-x nv-axis"),G.append("g").attr("class","nv-y nv-axis").append("g").attr("class","nv-zeroLine").append("line"),G.append("g").attr("class","nv-barsWrap"),G.append("g").attr("class","nv-legendWrap"),G.append("g").attr("class","nv-controlsWrap"),q&&(h.width(C-y()),H.select(".nv-legendWrap").datum(j).call(h),k.top!=h.height()&&(k.top=h.height(),D=a.utils.availableHeight(m,w,k)),H.select(".nv-legendWrap").attr("transform","translate("+y()+","+-k.top+")")),o){var I=[{key:p.grouped||"Grouped",disabled:e.stacked()},{key:p.stacked||"Stacked",disabled:!e.stacked()}];i.width(y()).color(["#444","#444","#444"]),H.select(".nv-controlsWrap").datum(I).attr("transform","translate(0,"+-k.top+")").call(i)}F.attr("transform","translate("+k.left+","+k.top+")"),e.disabled(j.map(function(a){return a.disabled})).width(C).height(D).color(j.map(function(a,b){return a.color||n(a,b)}).filter(function(a,b){return!j[b].disabled}));var J=H.select(".nv-barsWrap").datum(j.filter(function(a){return!a.disabled}));if(J.transition().call(e),r){f.scale(c)._ticks(a.utils.calcTicksY(D/24,j)).tickSize(-C,0),H.select(".nv-x.nv-axis").call(f);var K=H.select(".nv-x.nv-axis").selectAll("g");K.selectAll("line, text")}s&&(g.scale(d)._ticks(a.utils.calcTicksX(C/100,j)).tickSize(-D,0),H.select(".nv-y.nv-axis").attr("transform","translate(0,"+D+")"),H.select(".nv-y.nv-axis").call(g)),H.select(".nv-zeroLine line").attr("x1",d(0)).attr("x2",d(0)).attr("y1",0).attr("y2",-D),h.dispatch.on("stateChange",function(a){for(var c in a)u[c]=a[c];x.stateChange(u),b.update()}),i.dispatch.on("legendClick",function(a){if(a.disabled){switch(I=I.map(function(a){return a.disabled=!0,a}),a.disabled=!1,a.key){case"Grouped":e.stacked(!1);break;case"Stacked":e.stacked(!0)}u.stacked=e.stacked(),x.stateChange(u),t=e.stacked(),b.update()}}),x.on("changeState",function(a){"undefined"!=typeof a.disabled&&(j.forEach(function(b,c){b.disabled=a.disabled[c]}),u.disabled=a.disabled),"undefined"!=typeof a.stacked&&(e.stacked(a.stacked),u.stacked=a.stacked,t=a.stacked),b.update()})}),C.renderEnd("multibar horizontal chart immediate"),b}var c,d,e=a.models.multiBarHorizontal(),f=a.models.axis(),g=a.models.axis(),h=a.models.legend().height(30),i=a.models.legend().height(30),j=a.models.tooltip(),k={top:30,right:20,bottom:50,left:60},l=null,m=null,n=a.utils.defaultColor(),o=!0,p={},q=!0,r=!0,s=!0,t=!1,u=a.utils.state(),v=null,w=null,x=d3.dispatch("stateChange","changeState","renderEnd"),y=function(){return o?180:0},z=250;u.stacked=!1,e.stacked(t),f.orient("left").tickPadding(5).showMaxMin(!1).tickFormat(function(a){return a}),g.orient("bottom").tickFormat(d3.format(",.1f")),j.duration(0).valueFormatter(function(a,b){return g.tickFormat()(a,b)}).headerFormatter(function(a,b){return f.tickFormat()(a,b)}),i.updateState(!1);var A=function(a){return function(){return{active:a.map(function(a){return!a.disabled}),stacked:t}}},B=function(a){return function(b){void 0!==b.stacked&&(t=b.stacked),void 0!==b.active&&a.forEach(function(a,c){a.disabled=!b.active[c]})}},C=a.utils.renderWatch(x,z);return e.dispatch.on("elementMouseover.tooltip",function(a){a.value=b.x()(a.data),a.series={key:a.data.key,value:b.y()(a.data),color:a.color},j.data(a).hidden(!1)}),e.dispatch.on("elementMouseout.tooltip",function(){j.hidden(!0)}),e.dispatch.on("elementMousemove.tooltip",function(){j.position({top:d3.event.pageY,left:d3.event.pageX})()}),b.dispatch=x,b.multibar=e,b.legend=h,b.controls=i,b.xAxis=f,b.yAxis=g,b.state=u,b.tooltip=j,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return l},set:function(a){l=a}},height:{get:function(){return m},set:function(a){m=a}},showLegend:{get:function(){return q},set:function(a){q=a}},showControls:{get:function(){return o},set:function(a){o=a}},controlLabels:{get:function(){return p},set:function(a){p=a}},showXAxis:{get:function(){return r},set:function(a){r=a}},showYAxis:{get:function(){return s},set:function(a){s=a}},defaultState:{get:function(){return v},set:function(a){v=a}},noData:{get:function(){return w},set:function(a){w=a}},tooltips:{get:function(){return j.enabled()},set:function(b){a.deprecated("tooltips","use chart.tooltip.enabled() instead"),j.enabled(!!b)}},tooltipContent:{get:function(){return j.contentGenerator()},set:function(b){a.deprecated("tooltipContent","use chart.tooltip.contentGenerator() instead"),j.contentGenerator(b)}},margin:{get:function(){return k},set:function(a){k.top=void 0!==a.top?a.top:k.top,k.right=void 0!==a.right?a.right:k.right,k.bottom=void 0!==a.bottom?a.bottom:k.bottom,k.left=void 0!==a.left?a.left:k.left}},duration:{get:function(){return z},set:function(a){z=a,C.reset(z),e.duration(z),f.duration(z),g.duration(z)}},color:{get:function(){return n},set:function(b){n=a.utils.getColor(b),h.color(n)}},barColor:{get:function(){return e.barColor},set:function(a){e.barColor(a),h.color(function(a,b){return d3.rgb("#ccc").darker(1.5*b).toString()})}}}),a.utils.inheritOptions(b,e),a.utils.initOptions(b),b},a.models.multiChart=function(){"use strict";function b(j){return j.each(function(j){function k(a){var b=2===j[a.seriesIndex].yAxis?z:y;a.value=a.point.x,a.series={value:a.point.y,color:a.point.color},B.duration(100).valueFormatter(function(a,c){return b.tickFormat()(a,c)}).data(a).position(a.pos).hidden(!1)}function l(a){var b=2===j[a.seriesIndex].yAxis?z:y;a.point.x=v.x()(a.point),a.point.y=v.y()(a.point),B.duration(100).valueFormatter(function(a,c){return b.tickFormat()(a,c)}).data(a).position(a.pos).hidden(!1)}function n(a){var b=2===j[a.data.series].yAxis?z:y;a.value=t.x()(a.data),a.series={value:t.y()(a.data),color:a.color},B.duration(0).valueFormatter(function(a,c){return b.tickFormat()(a,c)}).data(a).hidden(!1)}var C=d3.select(this);a.utils.initSVG(C),b.update=function(){C.transition().call(b)},b.container=this;var D=a.utils.availableWidth(g,C,e),E=a.utils.availableHeight(h,C,e),F=j.filter(function(a){return"line"==a.type&&1==a.yAxis}),G=j.filter(function(a){return"line"==a.type&&2==a.yAxis}),H=j.filter(function(a){return"bar"==a.type&&1==a.yAxis}),I=j.filter(function(a){return"bar"==a.type&&2==a.yAxis}),J=j.filter(function(a){return"area"==a.type&&1==a.yAxis}),K=j.filter(function(a){return"area"==a.type&&2==a.yAxis});if(!(j&&j.length&&j.filter(function(a){return a.values.length}).length))return a.utils.noData(b,C),b;C.selectAll(".nv-noData").remove();var L=j.filter(function(a){return!a.disabled&&1==a.yAxis}).map(function(a){return a.values.map(function(a){return{x:a.x,y:a.y}})}),M=j.filter(function(a){return!a.disabled&&2==a.yAxis}).map(function(a){return a.values.map(function(a){return{x:a.x,y:a.y}})});o.domain(d3.extent(d3.merge(L.concat(M)),function(a){return a.x})).range([0,D]);var N=C.selectAll("g.wrap.multiChart").data([j]),O=N.enter().append("g").attr("class","wrap nvd3 multiChart").append("g");O.append("g").attr("class","nv-x nv-axis"),O.append("g").attr("class","nv-y1 nv-axis"),O.append("g").attr("class","nv-y2 nv-axis"),O.append("g").attr("class","lines1Wrap"),O.append("g").attr("class","lines2Wrap"),O.append("g").attr("class","bars1Wrap"),O.append("g").attr("class","bars2Wrap"),O.append("g").attr("class","stack1Wrap"),O.append("g").attr("class","stack2Wrap"),O.append("g").attr("class","legendWrap");var P=N.select("g"),Q=j.map(function(a,b){return j[b].color||f(a,b)});if(i){var R=A.align()?D/2:D,S=A.align()?R:0;A.width(R),A.color(Q),P.select(".legendWrap").datum(j.map(function(a){return a.originalKey=void 0===a.originalKey?a.key:a.originalKey,a.key=a.originalKey+(1==a.yAxis?"":" (right axis)"),a})).call(A),e.top!=A.height()&&(e.top=A.height(),E=a.utils.availableHeight(h,C,e)),P.select(".legendWrap").attr("transform","translate("+S+","+-e.top+")")}r.width(D).height(E).interpolate(m).color(Q.filter(function(a,b){return!j[b].disabled&&1==j[b].yAxis&&"line"==j[b].type})),s.width(D).height(E).interpolate(m).color(Q.filter(function(a,b){return!j[b].disabled&&2==j[b].yAxis&&"line"==j[b].type})),t.width(D).height(E).color(Q.filter(function(a,b){return!j[b].disabled&&1==j[b].yAxis&&"bar"==j[b].type})),u.width(D).height(E).color(Q.filter(function(a,b){return!j[b].disabled&&2==j[b].yAxis&&"bar"==j[b].type})),v.width(D).height(E).color(Q.filter(function(a,b){return!j[b].disabled&&1==j[b].yAxis&&"area"==j[b].type})),w.width(D).height(E).color(Q.filter(function(a,b){return!j[b].disabled&&2==j[b].yAxis&&"area"==j[b].type})),P.attr("transform","translate("+e.left+","+e.top+")");var T=P.select(".lines1Wrap").datum(F.filter(function(a){return!a.disabled})),U=P.select(".bars1Wrap").datum(H.filter(function(a){return!a.disabled})),V=P.select(".stack1Wrap").datum(J.filter(function(a){return!a.disabled})),W=P.select(".lines2Wrap").datum(G.filter(function(a){return!a.disabled})),X=P.select(".bars2Wrap").datum(I.filter(function(a){return!a.disabled})),Y=P.select(".stack2Wrap").datum(K.filter(function(a){return!a.disabled})),Z=J.length?J.map(function(a){return a.values}).reduce(function(a,b){return a.map(function(a,c){return{x:a.x,y:a.y+b[c].y}})}).concat([{x:0,y:0}]):[],$=K.length?K.map(function(a){return a.values}).reduce(function(a,b){return a.map(function(a,c){return{x:a.x,y:a.y+b[c].y}})}).concat([{x:0,y:0}]):[];p.domain(c||d3.extent(d3.merge(L).concat(Z),function(a){return a.y})).range([0,E]),q.domain(d||d3.extent(d3.merge(M).concat($),function(a){return a.y})).range([0,E]),r.yDomain(p.domain()),t.yDomain(p.domain()),v.yDomain(p.domain()),s.yDomain(q.domain()),u.yDomain(q.domain()),w.yDomain(q.domain()),J.length&&d3.transition(V).call(v),K.length&&d3.transition(Y).call(w),H.length&&d3.transition(U).call(t),I.length&&d3.transition(X).call(u),F.length&&d3.transition(T).call(r),G.length&&d3.transition(W).call(s),x._ticks(a.utils.calcTicksX(D/100,j)).tickSize(-E,0),P.select(".nv-x.nv-axis").attr("transform","translate(0,"+E+")"),d3.transition(P.select(".nv-x.nv-axis")).call(x),y._ticks(a.utils.calcTicksY(E/36,j)).tickSize(-D,0),d3.transition(P.select(".nv-y1.nv-axis")).call(y),z._ticks(a.utils.calcTicksY(E/36,j)).tickSize(-D,0),d3.transition(P.select(".nv-y2.nv-axis")).call(z),P.select(".nv-y1.nv-axis").classed("nv-disabled",L.length?!1:!0).attr("transform","translate("+o.range()[0]+",0)"),P.select(".nv-y2.nv-axis").classed("nv-disabled",M.length?!1:!0).attr("transform","translate("+o.range()[1]+",0)"),A.dispatch.on("stateChange",function(){b.update()}),r.dispatch.on("elementMouseover.tooltip",k),s.dispatch.on("elementMouseover.tooltip",k),r.dispatch.on("elementMouseout.tooltip",function(){B.hidden(!0)}),s.dispatch.on("elementMouseout.tooltip",function(){B.hidden(!0)}),v.dispatch.on("elementMouseover.tooltip",l),w.dispatch.on("elementMouseover.tooltip",l),v.dispatch.on("elementMouseout.tooltip",function(){B.hidden(!0)}),w.dispatch.on("elementMouseout.tooltip",function(){B.hidden(!0)}),t.dispatch.on("elementMouseover.tooltip",n),u.dispatch.on("elementMouseover.tooltip",n),t.dispatch.on("elementMouseout.tooltip",function(){B.hidden(!0)}),u.dispatch.on("elementMouseout.tooltip",function(){B.hidden(!0)}),t.dispatch.on("elementMousemove.tooltip",function(){B.position({top:d3.event.pageY,left:d3.event.pageX})()}),u.dispatch.on("elementMousemove.tooltip",function(){B.position({top:d3.event.pageY,left:d3.event.pageX})()})}),b}var c,d,e={top:30,right:20,bottom:50,left:60},f=a.utils.defaultColor(),g=null,h=null,i=!0,j=null,k=function(a){return a.x},l=function(a){return a.y},m="monotone",n=!0,o=d3.scale.linear(),p=d3.scale.linear(),q=d3.scale.linear(),r=a.models.line().yScale(p),s=a.models.line().yScale(q),t=a.models.multiBar().stacked(!1).yScale(p),u=a.models.multiBar().stacked(!1).yScale(q),v=a.models.stackedArea().yScale(p),w=a.models.stackedArea().yScale(q),x=a.models.axis().scale(o).orient("bottom").tickPadding(5),y=a.models.axis().scale(p).orient("left"),z=a.models.axis().scale(q).orient("right"),A=a.models.legend().height(30),B=a.models.tooltip(),C=d3.dispatch();return b.dispatch=C,b.lines1=r,b.lines2=s,b.bars1=t,b.bars2=u,b.stack1=v,b.stack2=w,b.xAxis=x,b.yAxis1=y,b.yAxis2=z,b.tooltip=B,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return g},set:function(a){g=a}},height:{get:function(){return h},set:function(a){h=a}},showLegend:{get:function(){return i},set:function(a){i=a}},yDomain1:{get:function(){return c},set:function(a){c=a}},yDomain2:{get:function(){return d},set:function(a){d=a}},noData:{get:function(){return j},set:function(a){j=a}},interpolate:{get:function(){return m},set:function(a){m=a}},tooltips:{get:function(){return B.enabled()},set:function(b){a.deprecated("tooltips","use chart.tooltip.enabled() instead"),B.enabled(!!b)}},tooltipContent:{get:function(){return B.contentGenerator()},set:function(b){a.deprecated("tooltipContent","use chart.tooltip.contentGenerator() instead"),B.contentGenerator(b)}},margin:{get:function(){return e},set:function(a){e.top=void 0!==a.top?a.top:e.top,e.right=void 0!==a.right?a.right:e.right,e.bottom=void 0!==a.bottom?a.bottom:e.bottom,e.left=void 0!==a.left?a.left:e.left}},color:{get:function(){return f},set:function(b){f=a.utils.getColor(b)}},x:{get:function(){return k},set:function(a){k=a,r.x(a),s.x(a),t.x(a),u.x(a),v.x(a),w.x(a)}},y:{get:function(){return l},set:function(a){l=a,r.y(a),s.y(a),v.y(a),w.y(a),t.y(a),u.y(a)}},useVoronoi:{get:function(){return n},set:function(a){n=a,r.useVoronoi(a),s.useVoronoi(a),v.useVoronoi(a),w.useVoronoi(a)}}}),a.utils.initOptions(b),b},a.models.ohlcBar=function(){"use strict";function b(y){return y.each(function(b){k=d3.select(this);var y=a.utils.availableWidth(h,k,g),A=a.utils.availableHeight(i,k,g);a.utils.initSVG(k);var B=y/b[0].values.length*.9;l.domain(c||d3.extent(b[0].values.map(n).concat(t))),l.range(v?e||[.5*y/b[0].values.length,y*(b[0].values.length-.5)/b[0].values.length]:e||[5+B/2,y-B/2-5]),m.domain(d||[d3.min(b[0].values.map(s).concat(u)),d3.max(b[0].values.map(r).concat(u))]).range(f||[A,0]),l.domain()[0]===l.domain()[1]&&l.domain(l.domain()[0]?[l.domain()[0]-.01*l.domain()[0],l.domain()[1]+.01*l.domain()[1]]:[-1,1]),m.domain()[0]===m.domain()[1]&&m.domain(m.domain()[0]?[m.domain()[0]+.01*m.domain()[0],m.domain()[1]-.01*m.domain()[1]]:[-1,1]);var C=d3.select(this).selectAll("g.nv-wrap.nv-ohlcBar").data([b[0].values]),D=C.enter().append("g").attr("class","nvd3 nv-wrap nv-ohlcBar"),E=D.append("defs"),F=D.append("g"),G=C.select("g");F.append("g").attr("class","nv-ticks"),C.attr("transform","translate("+g.left+","+g.top+")"),k.on("click",function(a,b){z.chartClick({data:a,index:b,pos:d3.event,id:j})}),E.append("clipPath").attr("id","nv-chart-clip-path-"+j).append("rect"),C.select("#nv-chart-clip-path-"+j+" rect").attr("width",y).attr("height",A),G.attr("clip-path",w?"url(#nv-chart-clip-path-"+j+")":"");var H=C.select(".nv-ticks").selectAll(".nv-tick").data(function(a){return a});H.exit().remove(),H.enter().append("path").attr("class",function(a,b,c){return(p(a,b)>q(a,b)?"nv-tick negative":"nv-tick positive")+" nv-tick-"+c+"-"+b}).attr("d",function(a,b){return"m0,0l0,"+(m(p(a,b))-m(r(a,b)))+"l"+-B/2+",0l"+B/2+",0l0,"+(m(s(a,b))-m(p(a,b)))+"l0,"+(m(q(a,b))-m(s(a,b)))+"l"+B/2+",0l"+-B/2+",0z"}).attr("transform",function(a,b){return"translate("+l(n(a,b))+","+m(r(a,b))+")"}).attr("fill",function(){return x[0]}).attr("stroke",function(){return x[0]}).attr("x",0).attr("y",function(a,b){return m(Math.max(0,o(a,b)))}).attr("height",function(a,b){return Math.abs(m(o(a,b))-m(0))}),H.attr("class",function(a,b,c){return(p(a,b)>q(a,b)?"nv-tick negative":"nv-tick positive")+" nv-tick-"+c+"-"+b}),d3.transition(H).attr("transform",function(a,b){return"translate("+l(n(a,b))+","+m(r(a,b))+")"}).attr("d",function(a,c){var d=y/b[0].values.length*.9;return"m0,0l0,"+(m(p(a,c))-m(r(a,c)))+"l"+-d/2+",0l"+d/2+",0l0,"+(m(s(a,c))-m(p(a,c)))+"l0,"+(m(q(a,c))-m(s(a,c)))+"l"+d/2+",0l"+-d/2+",0z"})}),b}var c,d,e,f,g={top:0,right:0,bottom:0,left:0},h=null,i=null,j=Math.floor(1e4*Math.random()),k=null,l=d3.scale.linear(),m=d3.scale.linear(),n=function(a){return a.x},o=function(a){return a.y},p=function(a){return a.open},q=function(a){return a.close},r=function(a){return a.high},s=function(a){return a.low},t=[],u=[],v=!1,w=!0,x=a.utils.defaultColor(),y=!1,z=d3.dispatch("tooltipShow","tooltipHide","stateChange","changeState","renderEnd","chartClick","elementClick","elementDblClick","elementMouseover","elementMouseout","elementMousemove");return b.highlightPoint=function(a,c){b.clearHighlights(),k.select(".nv-ohlcBar .nv-tick-0-"+a).classed("hover",c)},b.clearHighlights=function(){k.select(".nv-ohlcBar .nv-tick.hover").classed("hover",!1)},b.dispatch=z,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return h},set:function(a){h=a}},height:{get:function(){return i},set:function(a){i=a}},xScale:{get:function(){return l},set:function(a){l=a}},yScale:{get:function(){return m},set:function(a){m=a}},xDomain:{get:function(){return c},set:function(a){c=a}},yDomain:{get:function(){return d},set:function(a){d=a}},xRange:{get:function(){return e},set:function(a){e=a}},yRange:{get:function(){return f},set:function(a){f=a}},forceX:{get:function(){return t},set:function(a){t=a}},forceY:{get:function(){return u},set:function(a){u=a}},padData:{get:function(){return v},set:function(a){v=a}},clipEdge:{get:function(){return w},set:function(a){w=a}},id:{get:function(){return j},set:function(a){j=a}},interactive:{get:function(){return y},set:function(a){y=a}},x:{get:function(){return n},set:function(a){n=a}},y:{get:function(){return o},set:function(a){o=a}},open:{get:function(){return p()},set:function(a){p=a}},close:{get:function(){return q()},set:function(a){q=a}},high:{get:function(){return r},set:function(a){r=a}},low:{get:function(){return s},set:function(a){s=a}},margin:{get:function(){return g},set:function(a){g.top=void 0!=a.top?a.top:g.top,g.right=void 0!=a.right?a.right:g.right,g.bottom=void 0!=a.bottom?a.bottom:g.bottom,g.left=void 0!=a.left?a.left:g.left -}},color:{get:function(){return x},set:function(b){x=a.utils.getColor(b)}}}),a.utils.initOptions(b),b},a.models.parallelCoordinates=function(){"use strict";function b(p){return p.each(function(b){function p(a){return F(h.map(function(b){if(isNaN(a[b])||isNaN(parseFloat(a[b]))){var c=g[b].domain(),d=g[b].range(),e=c[0]-(c[1]-c[0])/9;if(J.indexOf(b)<0){var h=d3.scale.linear().domain([e,c[1]]).range([x-12,d[1]]);g[b].brush.y(h),J.push(b)}return[f(b),g[b](e)]}return J.length>0?(D.style("display","inline"),E.style("display","inline")):(D.style("display","none"),E.style("display","none")),[f(b),g[b](a[b])]}))}function q(){var a=h.filter(function(a){return!g[a].brush.empty()}),b=a.map(function(a){return g[a].brush.extent()});k=[],a.forEach(function(a,c){k[c]={dimension:a,extent:b[c]}}),l=[],M.style("display",function(c){var d=a.every(function(a,d){return isNaN(c[a])&&b[d][0]==g[a].brush.y().domain()[0]?!0:b[d][0]<=c[a]&&c[a]<=b[d][1]});return d&&l.push(c),d?null:"none"}),o.brush({filters:k,active:l})}function r(a){m[a]=this.parentNode.__origin__=f(a),L.attr("visibility","hidden")}function s(a){m[a]=Math.min(w,Math.max(0,this.parentNode.__origin__+=d3.event.x)),M.attr("d",p),h.sort(function(a,b){return u(a)-u(b)}),f.domain(h),N.attr("transform",function(a){return"translate("+u(a)+")"})}function t(a){delete this.parentNode.__origin__,delete m[a],d3.select(this.parentNode).attr("transform","translate("+f(a)+")"),M.attr("d",p),L.attr("d",p).attr("visibility",null)}function u(a){var b=m[a];return null==b?f(a):b}var v=d3.select(this),w=a.utils.availableWidth(d,v,c),x=a.utils.availableHeight(e,v,c);a.utils.initSVG(v),l=b,f.rangePoints([0,w],1).domain(h);var y={};h.forEach(function(a){var c=d3.extent(b,function(b){return+b[a]});return y[a]=!1,void 0===c[0]&&(y[a]=!0,c[0]=0,c[1]=0),c[0]===c[1]&&(c[0]=c[0]-1,c[1]=c[1]+1),g[a]=d3.scale.linear().domain(c).range([.9*(x-12),0]),g[a].brush=d3.svg.brush().y(g[a]).on("brush",q),"name"!=a});var z=v.selectAll("g.nv-wrap.nv-parallelCoordinates").data([b]),A=z.enter().append("g").attr("class","nvd3 nv-wrap nv-parallelCoordinates"),B=A.append("g"),C=z.select("g");B.append("g").attr("class","nv-parallelCoordinates background"),B.append("g").attr("class","nv-parallelCoordinates foreground"),B.append("g").attr("class","nv-parallelCoordinates missingValuesline"),z.attr("transform","translate("+c.left+","+c.top+")");var D,E,F=d3.svg.line().interpolate("cardinal").tension(n),G=d3.svg.axis().orient("left"),H=d3.behavior.drag().on("dragstart",r).on("drag",s).on("dragend",t),I=f.range()[1]-f.range()[0],J=[],K=[0+I/2,x-12,w-I/2,x-12];D=z.select(".missingValuesline").selectAll("line").data([K]),D.enter().append("line"),D.exit().remove(),D.attr("x1",function(a){return a[0]}).attr("y1",function(a){return a[1]}).attr("x2",function(a){return a[2]}).attr("y2",function(a){return a[3]}),E=z.select(".missingValuesline").selectAll("text").data(["undefined values"]),E.append("text").data(["undefined values"]),E.enter().append("text"),E.exit().remove(),E.attr("y",x).attr("x",w-92-I/2).text(function(a){return a});var L=z.select(".background").selectAll("path").data(b);L.enter().append("path"),L.exit().remove(),L.attr("d",p);var M=z.select(".foreground").selectAll("path").data(b);M.enter().append("path"),M.exit().remove(),M.attr("d",p).attr("stroke",j),M.on("mouseover",function(a,b){d3.select(this).classed("hover",!0),o.elementMouseover({label:a.name,data:a.data,index:b,pos:[d3.mouse(this.parentNode)[0],d3.mouse(this.parentNode)[1]]})}),M.on("mouseout",function(a,b){d3.select(this).classed("hover",!1),o.elementMouseout({label:a.name,data:a.data,index:b})});var N=C.selectAll(".dimension").data(h),O=N.enter().append("g").attr("class","nv-parallelCoordinates dimension");O.append("g").attr("class","nv-parallelCoordinates nv-axis"),O.append("g").attr("class","nv-parallelCoordinates-brush"),O.append("text").attr("class","nv-parallelCoordinates nv-label"),N.attr("transform",function(a){return"translate("+f(a)+",0)"}),N.exit().remove(),N.select(".nv-label").style("cursor","move").attr("dy","-1em").attr("text-anchor","middle").text(String).on("mouseover",function(a){o.elementMouseover({dim:a,pos:[d3.mouse(this.parentNode.parentNode)[0],d3.mouse(this.parentNode.parentNode)[1]]})}).on("mouseout",function(a){o.elementMouseout({dim:a})}).call(H),N.select(".nv-axis").each(function(a,b){d3.select(this).call(G.scale(g[a]).tickFormat(d3.format(i[b])))}),N.select(".nv-parallelCoordinates-brush").each(function(a){d3.select(this).call(g[a].brush)}).selectAll("rect").attr("x",-8).attr("width",16)}),b}var c={top:30,right:0,bottom:10,left:0},d=null,e=null,f=d3.scale.ordinal(),g={},h=[],i=[],j=a.utils.defaultColor(),k=[],l=[],m=[],n=1,o=d3.dispatch("brush","elementMouseover","elementMouseout");return b.dispatch=o,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return d},set:function(a){d=a}},height:{get:function(){return e},set:function(a){e=a}},dimensionNames:{get:function(){return h},set:function(a){h=a}},dimensionFormats:{get:function(){return i},set:function(a){i=a}},lineTension:{get:function(){return n},set:function(a){n=a}},dimensions:{get:function(){return h},set:function(b){a.deprecated("dimensions","use dimensionNames instead"),h=b}},margin:{get:function(){return c},set:function(a){c.top=void 0!==a.top?a.top:c.top,c.right=void 0!==a.right?a.right:c.right,c.bottom=void 0!==a.bottom?a.bottom:c.bottom,c.left=void 0!==a.left?a.left:c.left}},color:{get:function(){return j},set:function(b){j=a.utils.getColor(b)}}}),a.utils.initOptions(b),b},a.models.pie=function(){"use strict";function b(E){return D.reset(),E.each(function(b){function E(a,b){a.endAngle=isNaN(a.endAngle)?0:a.endAngle,a.startAngle=isNaN(a.startAngle)?0:a.startAngle,p||(a.innerRadius=0);var c=d3.interpolate(this._current,a);return this._current=c(0),function(a){return B[b](c(a))}}var F=d-c.left-c.right,G=e-c.top-c.bottom,H=Math.min(F,G)/2,I=[],J=[];if(i=d3.select(this),0===z.length)for(var K=H-H/5,L=y*H,M=0;Mc)return"";if("function"==typeof n)d=n(a,b,{key:f(a.data),value:g(a.data),percent:k(c)});else switch(n){case"key":d=f(a.data);break;case"value":d=k(g(a.data));break;case"percent":d=d3.format("%")(c)}return d})}}),D.renderEnd("pie immediate"),b}var c={top:0,right:0,bottom:0,left:0},d=500,e=500,f=function(a){return a.x},g=function(a){return a.y},h=Math.floor(1e4*Math.random()),i=null,j=a.utils.defaultColor(),k=d3.format(",.2f"),l=!0,m=!1,n="key",o=.02,p=!1,q=!1,r=!0,s=0,t=!1,u=!1,v=!1,w=!1,x=0,y=.5,z=[],A=d3.dispatch("chartClick","elementClick","elementDblClick","elementMouseover","elementMouseout","elementMousemove","renderEnd"),B=[],C=[],D=a.utils.renderWatch(A);return b.dispatch=A,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{arcsRadius:{get:function(){return z},set:function(a){z=a}},width:{get:function(){return d},set:function(a){d=a}},height:{get:function(){return e},set:function(a){e=a}},showLabels:{get:function(){return l},set:function(a){l=a}},title:{get:function(){return q},set:function(a){q=a}},titleOffset:{get:function(){return s},set:function(a){s=a}},labelThreshold:{get:function(){return o},set:function(a){o=a}},valueFormat:{get:function(){return k},set:function(a){k=a}},x:{get:function(){return f},set:function(a){f=a}},id:{get:function(){return h},set:function(a){h=a}},endAngle:{get:function(){return w},set:function(a){w=a}},startAngle:{get:function(){return u},set:function(a){u=a}},padAngle:{get:function(){return v},set:function(a){v=a}},cornerRadius:{get:function(){return x},set:function(a){x=a}},donutRatio:{get:function(){return y},set:function(a){y=a}},labelsOutside:{get:function(){return m},set:function(a){m=a}},labelSunbeamLayout:{get:function(){return t},set:function(a){t=a}},donut:{get:function(){return p},set:function(a){p=a}},growOnHover:{get:function(){return r},set:function(a){r=a}},pieLabelsOutside:{get:function(){return m},set:function(b){m=b,a.deprecated("pieLabelsOutside","use labelsOutside instead")}},donutLabelsOutside:{get:function(){return m},set:function(b){m=b,a.deprecated("donutLabelsOutside","use labelsOutside instead")}},labelFormat:{get:function(){return k},set:function(b){k=b,a.deprecated("labelFormat","use valueFormat instead")}},margin:{get:function(){return c},set:function(a){c.top="undefined"!=typeof a.top?a.top:c.top,c.right="undefined"!=typeof a.right?a.right:c.right,c.bottom="undefined"!=typeof a.bottom?a.bottom:c.bottom,c.left="undefined"!=typeof a.left?a.left:c.left}},y:{get:function(){return g},set:function(a){g=d3.functor(a)}},color:{get:function(){return j},set:function(b){j=a.utils.getColor(b)}},labelType:{get:function(){return n},set:function(a){n=a||"key"}}}),a.utils.initOptions(b),b},a.models.pieChart=function(){"use strict";function b(e){return q.reset(),q.models(c),e.each(function(e){var k=d3.select(this);a.utils.initSVG(k);var n=a.utils.availableWidth(g,k,f),o=a.utils.availableHeight(h,k,f);if(b.update=function(){k.transition().call(b)},b.container=this,l.setter(s(e),b.update).getter(r(e)).update(),l.disabled=e.map(function(a){return!!a.disabled}),!m){var q;m={};for(q in l)m[q]=l[q]instanceof Array?l[q].slice(0):l[q]}if(!e||!e.length)return a.utils.noData(b,k),b;k.selectAll(".nv-noData").remove();var t=k.selectAll("g.nv-wrap.nv-pieChart").data([e]),u=t.enter().append("g").attr("class","nvd3 nv-wrap nv-pieChart").append("g"),v=t.select("g");if(u.append("g").attr("class","nv-pieWrap"),u.append("g").attr("class","nv-legendWrap"),i)if("top"===j)d.width(n).key(c.x()),t.select(".nv-legendWrap").datum(e).call(d),f.top!=d.height()&&(f.top=d.height(),o=a.utils.availableHeight(h,k,f)),t.select(".nv-legendWrap").attr("transform","translate(0,"+-f.top+")");else if("right"===j){var w=a.models.legend().width();w>n/2&&(w=n/2),d.height(o).key(c.x()),d.width(w),n-=d.width(),t.select(".nv-legendWrap").datum(e).call(d).attr("transform","translate("+n+",0)")}t.attr("transform","translate("+f.left+","+f.top+")"),c.width(n).height(o);var x=v.select(".nv-pieWrap").datum([e]);d3.transition(x).call(c),d.dispatch.on("stateChange",function(a){for(var c in a)l[c]=a[c];p.stateChange(l),b.update()}),p.on("changeState",function(a){"undefined"!=typeof a.disabled&&(e.forEach(function(b,c){b.disabled=a.disabled[c]}),l.disabled=a.disabled),b.update()})}),q.renderEnd("pieChart immediate"),b}var c=a.models.pie(),d=a.models.legend(),e=a.models.tooltip(),f={top:30,right:20,bottom:20,left:20},g=null,h=null,i=!0,j="top",k=a.utils.defaultColor(),l=a.utils.state(),m=null,n=null,o=250,p=d3.dispatch("tooltipShow","tooltipHide","stateChange","changeState","renderEnd");e.headerEnabled(!1).duration(0).valueFormatter(function(a,b){return c.valueFormat()(a,b)});var q=a.utils.renderWatch(p),r=function(a){return function(){return{active:a.map(function(a){return!a.disabled})}}},s=function(a){return function(b){void 0!==b.active&&a.forEach(function(a,c){a.disabled=!b.active[c]})}};return c.dispatch.on("elementMouseover.tooltip",function(a){a.series={key:b.x()(a.data),value:b.y()(a.data),color:a.color},e.data(a).hidden(!1)}),c.dispatch.on("elementMouseout.tooltip",function(){e.hidden(!0)}),c.dispatch.on("elementMousemove.tooltip",function(){e.position({top:d3.event.pageY,left:d3.event.pageX})()}),b.legend=d,b.dispatch=p,b.pie=c,b.tooltip=e,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{noData:{get:function(){return n},set:function(a){n=a}},showLegend:{get:function(){return i},set:function(a){i=a}},legendPosition:{get:function(){return j},set:function(a){j=a}},defaultState:{get:function(){return m},set:function(a){m=a}},tooltips:{get:function(){return e.enabled()},set:function(b){a.deprecated("tooltips","use chart.tooltip.enabled() instead"),e.enabled(!!b)}},tooltipContent:{get:function(){return e.contentGenerator()},set:function(b){a.deprecated("tooltipContent","use chart.tooltip.contentGenerator() instead"),e.contentGenerator(b)}},color:{get:function(){return k},set:function(a){k=a,d.color(k),c.color(k)}},duration:{get:function(){return o},set:function(a){o=a,q.reset(o)}},margin:{get:function(){return f},set:function(a){f.top=void 0!==a.top?a.top:f.top,f.right=void 0!==a.right?a.right:f.right,f.bottom=void 0!==a.bottom?a.bottom:f.bottom,f.left=void 0!==a.left?a.left:f.left}}}),a.utils.inheritOptions(b,c),a.utils.initOptions(b),b},a.models.scatter=function(){"use strict";function b(N){return P.reset(),N.each(function(b){function N(){if(O=!1,!w)return!1;if(M===!0){var a=d3.merge(b.map(function(a,b){return a.values.map(function(a,c){var d=p(a,c),e=q(a,c);return[m(d)+1e-4*Math.random(),n(e)+1e-4*Math.random(),b,c,a]}).filter(function(a,b){return x(a[4],b)})}));if(0==a.length)return!1;a.length<3&&(a.push([m.range()[0]-20,n.range()[0]-20,null,null]),a.push([m.range()[1]+20,n.range()[1]+20,null,null]),a.push([m.range()[0]-20,n.range()[0]+20,null,null]),a.push([m.range()[1]+20,n.range()[1]-20,null,null]));var c=d3.geom.polygon([[-10,-10],[-10,i+10],[h+10,i+10],[h+10,-10]]),d=d3.geom.voronoi(a).map(function(b,d){return{data:c.clip(b),series:a[d][2],point:a[d][3]}});U.select(".nv-point-paths").selectAll("path").remove();var e=U.select(".nv-point-paths").selectAll("path").data(d),f=e.enter().append("svg:path").attr("d",function(a){return a&&a.data&&0!==a.data.length?"M"+a.data.join(",")+"Z":"M 0 0"}).attr("id",function(a,b){return"nv-path-"+b}).attr("clip-path",function(a,b){return"url(#nv-clip-"+b+")"});C&&f.style("fill",d3.rgb(230,230,230)).style("fill-opacity",.4).style("stroke-opacity",1).style("stroke",d3.rgb(200,200,200)),B&&(U.select(".nv-point-clips").selectAll("clipPath").remove(),U.select(".nv-point-clips").selectAll("clipPath").data(a).enter().append("svg:clipPath").attr("id",function(a,b){return"nv-clip-"+b}).append("svg:circle").attr("cx",function(a){return a[0]}).attr("cy",function(a){return a[1]}).attr("r",D));var k=function(a,c){if(O)return 0;var d=b[a.series];if(void 0!==d){var e=d.values[a.point];e.color=j(d,a.series),e.x=p(e),e.y=q(e);var f=l.node().getBoundingClientRect(),h=window.pageYOffset||document.documentElement.scrollTop,i=window.pageXOffset||document.documentElement.scrollLeft,k={left:m(p(e,a.point))+f.left+i+g.left+10,top:n(q(e,a.point))+f.top+h+g.top+10};c({point:e,series:d,pos:k,seriesIndex:a.series,pointIndex:a.point})}};e.on("click",function(a){k(a,L.elementClick)}).on("dblclick",function(a){k(a,L.elementDblClick)}).on("mouseover",function(a){k(a,L.elementMouseover)}).on("mouseout",function(a){k(a,L.elementMouseout)})}else U.select(".nv-groups").selectAll(".nv-group").selectAll(".nv-point").on("click",function(a,c){if(O||!b[a.series])return 0;var d=b[a.series],e=d.values[c];L.elementClick({point:e,series:d,pos:[m(p(e,c))+g.left,n(q(e,c))+g.top],seriesIndex:a.series,pointIndex:c})}).on("dblclick",function(a,c){if(O||!b[a.series])return 0;var d=b[a.series],e=d.values[c];L.elementDblClick({point:e,series:d,pos:[m(p(e,c))+g.left,n(q(e,c))+g.top],seriesIndex:a.series,pointIndex:c})}).on("mouseover",function(a,c){if(O||!b[a.series])return 0;var d=b[a.series],e=d.values[c];L.elementMouseover({point:e,series:d,pos:[m(p(e,c))+g.left,n(q(e,c))+g.top],seriesIndex:a.series,pointIndex:c,color:j(a,c)})}).on("mouseout",function(a,c){if(O||!b[a.series])return 0;var d=b[a.series],e=d.values[c];L.elementMouseout({point:e,series:d,seriesIndex:a.series,pointIndex:c,color:j(a,c)})})}l=d3.select(this);var R=a.utils.availableWidth(h,l,g),S=a.utils.availableHeight(i,l,g);a.utils.initSVG(l),b.forEach(function(a,b){a.values.forEach(function(a){a.series=b})});var T=E&&F&&I?[]:d3.merge(b.map(function(a){return a.values.map(function(a,b){return{x:p(a,b),y:q(a,b),size:r(a,b)}})}));m.domain(E||d3.extent(T.map(function(a){return a.x}).concat(t))),m.range(y&&b[0]?G||[(R*z+R)/(2*b[0].values.length),R-R*(1+z)/(2*b[0].values.length)]:G||[0,R]),n.domain(F||d3.extent(T.map(function(a){return a.y}).concat(u))).range(H||[S,0]),o.domain(I||d3.extent(T.map(function(a){return a.size}).concat(v))).range(J||Q),K=m.domain()[0]===m.domain()[1]||n.domain()[0]===n.domain()[1],m.domain()[0]===m.domain()[1]&&m.domain(m.domain()[0]?[m.domain()[0]-.01*m.domain()[0],m.domain()[1]+.01*m.domain()[1]]:[-1,1]),n.domain()[0]===n.domain()[1]&&n.domain(n.domain()[0]?[n.domain()[0]-.01*n.domain()[0],n.domain()[1]+.01*n.domain()[1]]:[-1,1]),isNaN(m.domain()[0])&&m.domain([-1,1]),isNaN(n.domain()[0])&&n.domain([-1,1]),c=c||m,d=d||n,e=e||o;var U=l.selectAll("g.nv-wrap.nv-scatter").data([b]),V=U.enter().append("g").attr("class","nvd3 nv-wrap nv-scatter nv-chart-"+k),W=V.append("defs"),X=V.append("g"),Y=U.select("g");U.classed("nv-single-point",K),X.append("g").attr("class","nv-groups"),X.append("g").attr("class","nv-point-paths"),V.append("g").attr("class","nv-point-clips"),U.attr("transform","translate("+g.left+","+g.top+")"),W.append("clipPath").attr("id","nv-edge-clip-"+k).append("rect"),U.select("#nv-edge-clip-"+k+" rect").attr("width",R).attr("height",S>0?S:0),Y.attr("clip-path",A?"url(#nv-edge-clip-"+k+")":""),O=!0;var Z=U.select(".nv-groups").selectAll(".nv-group").data(function(a){return a},function(a){return a.key});Z.enter().append("g").style("stroke-opacity",1e-6).style("fill-opacity",1e-6),Z.exit().remove(),Z.attr("class",function(a,b){return"nv-group nv-series-"+b}).classed("hover",function(a){return a.hover}),Z.watchTransition(P,"scatter: groups").style("fill",function(a,b){return j(a,b)}).style("stroke",function(a,b){return j(a,b)}).style("stroke-opacity",1).style("fill-opacity",.5);var $=Z.selectAll("path.nv-point").data(function(a){return a.values.map(function(a,b){return[a,b]}).filter(function(a,b){return x(a[0],b)})});$.enter().append("path").style("fill",function(a){return a.color}).style("stroke",function(a){return a.color}).attr("transform",function(a){return"translate("+c(p(a[0],a[1]))+","+d(q(a[0],a[1]))+")"}).attr("d",a.utils.symbol().type(function(a){return s(a[0])}).size(function(a){return o(r(a[0],a[1]))})),$.exit().remove(),Z.exit().selectAll("path.nv-point").watchTransition(P,"scatter exit").attr("transform",function(a){return"translate("+m(p(a[0],a[1]))+","+n(q(a[0],a[1]))+")"}).remove(),$.each(function(a){d3.select(this).classed("nv-point",!0).classed("nv-point-"+a[1],!0).classed("nv-noninteractive",!w).classed("hover",!1)}),$.watchTransition(P,"scatter points").attr("transform",function(a){return"translate("+m(p(a[0],a[1]))+","+n(q(a[0],a[1]))+")"}).attr("d",a.utils.symbol().type(function(a){return s(a[0])}).size(function(a){return o(r(a[0],a[1]))})),clearTimeout(f),f=setTimeout(N,300),c=m.copy(),d=n.copy(),e=o.copy()}),P.renderEnd("scatter immediate"),b}var c,d,e,f,g={top:0,right:0,bottom:0,left:0},h=null,i=null,j=a.utils.defaultColor(),k=Math.floor(1e5*Math.random()),l=null,m=d3.scale.linear(),n=d3.scale.linear(),o=d3.scale.linear(),p=function(a){return a.x},q=function(a){return a.y},r=function(a){return a.size||1},s=function(a){return a.shape||"circle"},t=[],u=[],v=[],w=!0,x=function(a){return!a.notActive},y=!1,z=.1,A=!1,B=!0,C=!1,D=function(){return 25},E=null,F=null,G=null,H=null,I=null,J=null,K=!1,L=d3.dispatch("elementClick","elementDblClick","elementMouseover","elementMouseout","renderEnd"),M=!0,N=250,O=!1,P=a.utils.renderWatch(L,N),Q=[16,256];return b.dispatch=L,b.options=a.utils.optionsFunc.bind(b),b._calls=new function(){this.clearHighlights=function(){return a.dom.write(function(){l.selectAll(".nv-point.hover").classed("hover",!1)}),null},this.highlightPoint=function(b,c,d){a.dom.write(function(){l.select(" .nv-series-"+b+" .nv-point-"+c).classed("hover",d)})}},L.on("elementMouseover.point",function(a){w&&b._calls.highlightPoint(a.seriesIndex,a.pointIndex,!0)}),L.on("elementMouseout.point",function(a){w&&b._calls.highlightPoint(a.seriesIndex,a.pointIndex,!1)}),b._options=Object.create({},{width:{get:function(){return h},set:function(a){h=a}},height:{get:function(){return i},set:function(a){i=a}},xScale:{get:function(){return m},set:function(a){m=a}},yScale:{get:function(){return n},set:function(a){n=a}},pointScale:{get:function(){return o},set:function(a){o=a}},xDomain:{get:function(){return E},set:function(a){E=a}},yDomain:{get:function(){return F},set:function(a){F=a}},pointDomain:{get:function(){return I},set:function(a){I=a}},xRange:{get:function(){return G},set:function(a){G=a}},yRange:{get:function(){return H},set:function(a){H=a}},pointRange:{get:function(){return J},set:function(a){J=a}},forceX:{get:function(){return t},set:function(a){t=a}},forceY:{get:function(){return u},set:function(a){u=a}},forcePoint:{get:function(){return v},set:function(a){v=a}},interactive:{get:function(){return w},set:function(a){w=a}},pointActive:{get:function(){return x},set:function(a){x=a}},padDataOuter:{get:function(){return z},set:function(a){z=a}},padData:{get:function(){return y},set:function(a){y=a}},clipEdge:{get:function(){return A},set:function(a){A=a}},clipVoronoi:{get:function(){return B},set:function(a){B=a}},clipRadius:{get:function(){return D},set:function(a){D=a}},showVoronoi:{get:function(){return C},set:function(a){C=a}},id:{get:function(){return k},set:function(a){k=a}},x:{get:function(){return p},set:function(a){p=d3.functor(a)}},y:{get:function(){return q},set:function(a){q=d3.functor(a)}},pointSize:{get:function(){return r},set:function(a){r=d3.functor(a)}},pointShape:{get:function(){return s},set:function(a){s=d3.functor(a)}},margin:{get:function(){return g},set:function(a){g.top=void 0!==a.top?a.top:g.top,g.right=void 0!==a.right?a.right:g.right,g.bottom=void 0!==a.bottom?a.bottom:g.bottom,g.left=void 0!==a.left?a.left:g.left}},duration:{get:function(){return N},set:function(a){N=a,P.reset(N)}},color:{get:function(){return j},set:function(b){j=a.utils.getColor(b)}},useVoronoi:{get:function(){return M},set:function(a){M=a,M===!1&&(B=!1)}}}),a.utils.initOptions(b),b},a.models.scatterChart=function(){"use strict";function b(z){return D.reset(),D.models(c),t&&D.models(d),u&&D.models(e),q&&D.models(g),r&&D.models(h),z.each(function(z){m=d3.select(this),a.utils.initSVG(m);var G=a.utils.availableWidth(k,m,j),H=a.utils.availableHeight(l,m,j);if(b.update=function(){0===A?m.call(b):m.transition().duration(A).call(b)},b.container=this,w.setter(F(z),b.update).getter(E(z)).update(),w.disabled=z.map(function(a){return!!a.disabled}),!x){var I;x={};for(I in w)x[I]=w[I]instanceof Array?w[I].slice(0):w[I]}if(!(z&&z.length&&z.filter(function(a){return a.values.length}).length))return a.utils.noData(b,m),D.renderEnd("scatter immediate"),b;m.selectAll(".nv-noData").remove(),o=c.xScale(),p=c.yScale();var J=m.selectAll("g.nv-wrap.nv-scatterChart").data([z]),K=J.enter().append("g").attr("class","nvd3 nv-wrap nv-scatterChart nv-chart-"+c.id()),L=K.append("g"),M=J.select("g");if(L.append("rect").attr("class","nvd3 nv-background").style("pointer-events","none"),L.append("g").attr("class","nv-x nv-axis"),L.append("g").attr("class","nv-y nv-axis"),L.append("g").attr("class","nv-scatterWrap"),L.append("g").attr("class","nv-regressionLinesWrap"),L.append("g").attr("class","nv-distWrap"),L.append("g").attr("class","nv-legendWrap"),v&&M.select(".nv-y.nv-axis").attr("transform","translate("+G+",0)"),s){var N=G;f.width(N),J.select(".nv-legendWrap").datum(z).call(f),j.top!=f.height()&&(j.top=f.height(),H=a.utils.availableHeight(l,m,j)),J.select(".nv-legendWrap").attr("transform","translate(0,"+-j.top+")")}J.attr("transform","translate("+j.left+","+j.top+")"),c.width(G).height(H).color(z.map(function(a,b){return a.color=a.color||n(a,b),a.color}).filter(function(a,b){return!z[b].disabled})),J.select(".nv-scatterWrap").datum(z.filter(function(a){return!a.disabled})).call(c),J.select(".nv-regressionLinesWrap").attr("clip-path","url(#nv-edge-clip-"+c.id()+")");var O=J.select(".nv-regressionLinesWrap").selectAll(".nv-regLines").data(function(a){return a});O.enter().append("g").attr("class","nv-regLines");var P=O.selectAll(".nv-regLine").data(function(a){return[a]});P.enter().append("line").attr("class","nv-regLine").style("stroke-opacity",0),P.filter(function(a){return a.intercept&&a.slope}).watchTransition(D,"scatterPlusLineChart: regline").attr("x1",o.range()[0]).attr("x2",o.range()[1]).attr("y1",function(a){return p(o.domain()[0]*a.slope+a.intercept)}).attr("y2",function(a){return p(o.domain()[1]*a.slope+a.intercept)}).style("stroke",function(a,b,c){return n(a,c)}).style("stroke-opacity",function(a){return a.disabled||"undefined"==typeof a.slope||"undefined"==typeof a.intercept?0:1}),t&&(d.scale(o)._ticks(a.utils.calcTicksX(G/100,z)).tickSize(-H,0),M.select(".nv-x.nv-axis").attr("transform","translate(0,"+p.range()[0]+")").call(d)),u&&(e.scale(p)._ticks(a.utils.calcTicksY(H/36,z)).tickSize(-G,0),M.select(".nv-y.nv-axis").call(e)),q&&(g.getData(c.x()).scale(o).width(G).color(z.map(function(a,b){return a.color||n(a,b)}).filter(function(a,b){return!z[b].disabled})),L.select(".nv-distWrap").append("g").attr("class","nv-distributionX"),M.select(".nv-distributionX").attr("transform","translate(0,"+p.range()[0]+")").datum(z.filter(function(a){return!a.disabled})).call(g)),r&&(h.getData(c.y()).scale(p).width(H).color(z.map(function(a,b){return a.color||n(a,b)}).filter(function(a,b){return!z[b].disabled})),L.select(".nv-distWrap").append("g").attr("class","nv-distributionY"),M.select(".nv-distributionY").attr("transform","translate("+(v?G:-h.size())+",0)").datum(z.filter(function(a){return!a.disabled})).call(h)),f.dispatch.on("stateChange",function(a){for(var c in a)w[c]=a[c];y.stateChange(w),b.update()}),y.on("changeState",function(a){"undefined"!=typeof a.disabled&&(z.forEach(function(b,c){b.disabled=a.disabled[c]}),w.disabled=a.disabled),b.update()}),c.dispatch.on("elementMouseout.tooltip",function(a){i.hidden(!0),m.select(".nv-chart-"+c.id()+" .nv-series-"+a.seriesIndex+" .nv-distx-"+a.pointIndex).attr("y1",0),m.select(".nv-chart-"+c.id()+" .nv-series-"+a.seriesIndex+" .nv-disty-"+a.pointIndex).attr("x2",h.size())}),c.dispatch.on("elementMouseover.tooltip",function(a){m.select(".nv-series-"+a.seriesIndex+" .nv-distx-"+a.pointIndex).attr("y1",a.pos.top-H-j.top),m.select(".nv-series-"+a.seriesIndex+" .nv-disty-"+a.pointIndex).attr("x2",a.pos.left+g.size()-j.left),i.position(a.pos).data(a).hidden(!1)}),B=o.copy(),C=p.copy()}),D.renderEnd("scatter with line immediate"),b}var c=a.models.scatter(),d=a.models.axis(),e=a.models.axis(),f=a.models.legend(),g=a.models.distribution(),h=a.models.distribution(),i=a.models.tooltip(),j={top:30,right:20,bottom:50,left:75},k=null,l=null,m=null,n=a.utils.defaultColor(),o=c.xScale(),p=c.yScale(),q=!1,r=!1,s=!0,t=!0,u=!0,v=!1,w=a.utils.state(),x=null,y=d3.dispatch("stateChange","changeState","renderEnd"),z=null,A=250;c.xScale(o).yScale(p),d.orient("bottom").tickPadding(10),e.orient(v?"right":"left").tickPadding(10),g.axis("x"),h.axis("y"),i.headerFormatter(function(a,b){return d.tickFormat()(a,b)}).valueFormatter(function(a,b){return e.tickFormat()(a,b)});var B,C,D=a.utils.renderWatch(y,A),E=function(a){return function(){return{active:a.map(function(a){return!a.disabled})}}},F=function(a){return function(b){void 0!==b.active&&a.forEach(function(a,c){a.disabled=!b.active[c]})}};return b.dispatch=y,b.scatter=c,b.legend=f,b.xAxis=d,b.yAxis=e,b.distX=g,b.distY=h,b.tooltip=i,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return k},set:function(a){k=a}},height:{get:function(){return l},set:function(a){l=a}},container:{get:function(){return m},set:function(a){m=a}},showDistX:{get:function(){return q},set:function(a){q=a}},showDistY:{get:function(){return r},set:function(a){r=a}},showLegend:{get:function(){return s},set:function(a){s=a}},showXAxis:{get:function(){return t},set:function(a){t=a}},showYAxis:{get:function(){return u},set:function(a){u=a}},defaultState:{get:function(){return x},set:function(a){x=a}},noData:{get:function(){return z},set:function(a){z=a}},duration:{get:function(){return A},set:function(a){A=a}},tooltips:{get:function(){return i.enabled()},set:function(b){a.deprecated("tooltips","use chart.tooltip.enabled() instead"),i.enabled(!!b) -}},tooltipContent:{get:function(){return i.contentGenerator()},set:function(b){a.deprecated("tooltipContent","use chart.tooltip.contentGenerator() instead"),i.contentGenerator(b)}},tooltipXContent:{get:function(){return i.contentGenerator()},set:function(){a.deprecated("tooltipContent","This option is removed, put values into main tooltip.")}},tooltipYContent:{get:function(){return i.contentGenerator()},set:function(){a.deprecated("tooltipContent","This option is removed, put values into main tooltip.")}},margin:{get:function(){return j},set:function(a){j.top=void 0!==a.top?a.top:j.top,j.right=void 0!==a.right?a.right:j.right,j.bottom=void 0!==a.bottom?a.bottom:j.bottom,j.left=void 0!==a.left?a.left:j.left}},rightAlignYAxis:{get:function(){return v},set:function(a){v=a,e.orient(a?"right":"left")}},color:{get:function(){return n},set:function(b){n=a.utils.getColor(b),f.color(n),g.color(n),h.color(n)}}}),a.utils.inheritOptions(b,c),a.utils.initOptions(b),b},a.models.sparkline=function(){"use strict";function b(k){return k.each(function(b){var k=h-g.left-g.right,q=i-g.top-g.bottom;j=d3.select(this),a.utils.initSVG(j),l.domain(c||d3.extent(b,n)).range(e||[0,k]),m.domain(d||d3.extent(b,o)).range(f||[q,0]);{var r=j.selectAll("g.nv-wrap.nv-sparkline").data([b]),s=r.enter().append("g").attr("class","nvd3 nv-wrap nv-sparkline");s.append("g"),r.select("g")}r.attr("transform","translate("+g.left+","+g.top+")");var t=r.selectAll("path").data(function(a){return[a]});t.enter().append("path"),t.exit().remove(),t.style("stroke",function(a,b){return a.color||p(a,b)}).attr("d",d3.svg.line().x(function(a,b){return l(n(a,b))}).y(function(a,b){return m(o(a,b))}));var u=r.selectAll("circle.nv-point").data(function(a){function b(b){if(-1!=b){var c=a[b];return c.pointIndex=b,c}return null}var c=a.map(function(a,b){return o(a,b)}),d=b(c.lastIndexOf(m.domain()[1])),e=b(c.indexOf(m.domain()[0])),f=b(c.length-1);return[e,d,f].filter(function(a){return null!=a})});u.enter().append("circle"),u.exit().remove(),u.attr("cx",function(a){return l(n(a,a.pointIndex))}).attr("cy",function(a){return m(o(a,a.pointIndex))}).attr("r",2).attr("class",function(a){return n(a,a.pointIndex)==l.domain()[1]?"nv-point nv-currentValue":o(a,a.pointIndex)==m.domain()[0]?"nv-point nv-minValue":"nv-point nv-maxValue"})}),b}var c,d,e,f,g={top:2,right:0,bottom:2,left:0},h=400,i=32,j=null,k=!0,l=d3.scale.linear(),m=d3.scale.linear(),n=function(a){return a.x},o=function(a){return a.y},p=a.utils.getColor(["#000"]);return b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return h},set:function(a){h=a}},height:{get:function(){return i},set:function(a){i=a}},xDomain:{get:function(){return c},set:function(a){c=a}},yDomain:{get:function(){return d},set:function(a){d=a}},xRange:{get:function(){return e},set:function(a){e=a}},yRange:{get:function(){return f},set:function(a){f=a}},xScale:{get:function(){return l},set:function(a){l=a}},yScale:{get:function(){return m},set:function(a){m=a}},animate:{get:function(){return k},set:function(a){k=a}},x:{get:function(){return n},set:function(a){n=d3.functor(a)}},y:{get:function(){return o},set:function(a){o=d3.functor(a)}},margin:{get:function(){return g},set:function(a){g.top=void 0!==a.top?a.top:g.top,g.right=void 0!==a.right?a.right:g.right,g.bottom=void 0!==a.bottom?a.bottom:g.bottom,g.left=void 0!==a.left?a.left:g.left}},color:{get:function(){return p},set:function(b){p=a.utils.getColor(b)}}}),a.utils.initOptions(b),b},a.models.sparklinePlus=function(){"use strict";function b(p){return p.each(function(p){function q(){if(!j){var a=z.selectAll(".nv-hoverValue").data(i),b=a.enter().append("g").attr("class","nv-hoverValue").style("stroke-opacity",0).style("fill-opacity",0);a.exit().transition().duration(250).style("stroke-opacity",0).style("fill-opacity",0).remove(),a.attr("transform",function(a){return"translate("+c(e.x()(p[a],a))+",0)"}).transition().duration(250).style("stroke-opacity",1).style("fill-opacity",1),i.length&&(b.append("line").attr("x1",0).attr("y1",-f.top).attr("x2",0).attr("y2",u),b.append("text").attr("class","nv-xValue").attr("x",-6).attr("y",-f.top).attr("text-anchor","end").attr("dy",".9em"),z.select(".nv-hoverValue .nv-xValue").text(k(e.x()(p[i[0]],i[0]))),b.append("text").attr("class","nv-yValue").attr("x",6).attr("y",-f.top).attr("text-anchor","start").attr("dy",".9em"),z.select(".nv-hoverValue .nv-yValue").text(l(e.y()(p[i[0]],i[0]))))}}function r(){function a(a,b){for(var c=Math.abs(e.x()(a[0],0)-b),d=0,f=0;fc;++c){for(b=0,d=0;bb;b++)a[b][c][1]/=d;else for(b=0;e>b;b++)a[b][c][1]=0}for(c=0;f>c;++c)g[c]=0;return g}}),u.renderEnd("stackedArea immediate"),b}var c,d,e={top:0,right:0,bottom:0,left:0},f=960,g=500,h=a.utils.defaultColor(),i=Math.floor(1e5*Math.random()),j=null,k=function(a){return a.x},l=function(a){return a.y},m="stack",n="zero",o="default",p="linear",q=!1,r=a.models.scatter(),s=250,t=d3.dispatch("areaClick","areaMouseover","areaMouseout","renderEnd","elementClick","elementMouseover","elementMouseout");r.pointSize(2.2).pointDomain([2.2,2.2]);var u=a.utils.renderWatch(t,s);return b.dispatch=t,b.scatter=r,r.dispatch.on("elementClick",function(){t.elementClick.apply(this,arguments)}),r.dispatch.on("elementMouseover",function(){t.elementMouseover.apply(this,arguments)}),r.dispatch.on("elementMouseout",function(){t.elementMouseout.apply(this,arguments)}),b.interpolate=function(a){return arguments.length?(p=a,b):p},b.duration=function(a){return arguments.length?(s=a,u.reset(s),r.duration(s),b):s},b.dispatch=t,b.scatter=r,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return f},set:function(a){f=a}},height:{get:function(){return g},set:function(a){g=a}},clipEdge:{get:function(){return q},set:function(a){q=a}},offset:{get:function(){return n},set:function(a){n=a}},order:{get:function(){return o},set:function(a){o=a}},interpolate:{get:function(){return p},set:function(a){p=a}},x:{get:function(){return k},set:function(a){k=d3.functor(a)}},y:{get:function(){return l},set:function(a){l=d3.functor(a)}},margin:{get:function(){return e},set:function(a){e.top=void 0!==a.top?a.top:e.top,e.right=void 0!==a.right?a.right:e.right,e.bottom=void 0!==a.bottom?a.bottom:e.bottom,e.left=void 0!==a.left?a.left:e.left}},color:{get:function(){return h},set:function(b){h=a.utils.getColor(b)}},style:{get:function(){return m},set:function(a){switch(m=a){case"stack":b.offset("zero"),b.order("default");break;case"stream":b.offset("wiggle"),b.order("inside-out");break;case"stream-center":b.offset("silhouette"),b.order("inside-out");break;case"expand":b.offset("expand"),b.order("default");break;case"stack_percent":b.offset(b.d3_stackedOffset_stackPercent),b.order("default")}}},duration:{get:function(){return s},set:function(a){s=a,u.reset(s),r.duration(s)}}}),a.utils.inheritOptions(b,r),a.utils.initOptions(b),b},a.models.stackedAreaChart=function(){"use strict";function b(k){return F.reset(),F.models(e),r&&F.models(f),s&&F.models(g),k.each(function(k){var x=d3.select(this),F=this;a.utils.initSVG(x);var K=a.utils.availableWidth(m,x,l),L=a.utils.availableHeight(n,x,l);if(b.update=function(){x.transition().duration(C).call(b)},b.container=this,v.setter(I(k),b.update).getter(H(k)).update(),v.disabled=k.map(function(a){return!!a.disabled}),!w){var M;w={};for(M in v)w[M]=v[M]instanceof Array?v[M].slice(0):v[M]}if(!(k&&k.length&&k.filter(function(a){return a.values.length}).length))return a.utils.noData(b,x),b;x.selectAll(".nv-noData").remove(),c=e.xScale(),d=e.yScale();var N=x.selectAll("g.nv-wrap.nv-stackedAreaChart").data([k]),O=N.enter().append("g").attr("class","nvd3 nv-wrap nv-stackedAreaChart").append("g"),P=N.select("g");if(O.append("rect").style("opacity",0),O.append("g").attr("class","nv-x nv-axis"),O.append("g").attr("class","nv-y nv-axis"),O.append("g").attr("class","nv-stackedWrap"),O.append("g").attr("class","nv-legendWrap"),O.append("g").attr("class","nv-controlsWrap"),O.append("g").attr("class","nv-interactive"),P.select("rect").attr("width",K).attr("height",L),q){var Q=p?K-z:K;h.width(Q),P.select(".nv-legendWrap").datum(k).call(h),l.top!=h.height()&&(l.top=h.height(),L=a.utils.availableHeight(n,x,l)),P.select(".nv-legendWrap").attr("transform","translate("+(K-Q)+","+-l.top+")")}if(p){var R=[{key:B.stacked||"Stacked",metaKey:"Stacked",disabled:"stack"!=e.style(),style:"stack"},{key:B.stream||"Stream",metaKey:"Stream",disabled:"stream"!=e.style(),style:"stream"},{key:B.expanded||"Expanded",metaKey:"Expanded",disabled:"expand"!=e.style(),style:"expand"},{key:B.stack_percent||"Stack %",metaKey:"Stack_Percent",disabled:"stack_percent"!=e.style(),style:"stack_percent"}];z=A.length/3*260,R=R.filter(function(a){return-1!==A.indexOf(a.metaKey)}),i.width(z).color(["#444","#444","#444"]),P.select(".nv-controlsWrap").datum(R).call(i),l.top!=Math.max(i.height(),h.height())&&(l.top=Math.max(i.height(),h.height()),L=a.utils.availableHeight(n,x,l)),P.select(".nv-controlsWrap").attr("transform","translate(0,"+-l.top+")")}N.attr("transform","translate("+l.left+","+l.top+")"),t&&P.select(".nv-y.nv-axis").attr("transform","translate("+K+",0)"),u&&(j.width(K).height(L).margin({left:l.left,top:l.top}).svgContainer(x).xScale(c),N.select(".nv-interactive").call(j)),e.width(K).height(L);var S=P.select(".nv-stackedWrap").datum(k);if(S.transition().call(e),r&&(f.scale(c)._ticks(a.utils.calcTicksX(K/100,k)).tickSize(-L,0),P.select(".nv-x.nv-axis").attr("transform","translate(0,"+L+")"),P.select(".nv-x.nv-axis").transition().duration(0).call(f)),s){var T;if(T="wiggle"===e.offset()?0:a.utils.calcTicksY(L/36,k),g.scale(d)._ticks(T).tickSize(-K,0),"expand"===e.style()||"stack_percent"===e.style()){var U=g.tickFormat();D&&U===J||(D=U),g.tickFormat(J)}else D&&(g.tickFormat(D),D=null);P.select(".nv-y.nv-axis").transition().duration(0).call(g)}e.dispatch.on("areaClick.toggle",function(a){k.forEach(1===k.filter(function(a){return!a.disabled}).length?function(a){a.disabled=!1}:function(b,c){b.disabled=c!=a.seriesIndex}),v.disabled=k.map(function(a){return!!a.disabled}),y.stateChange(v),b.update()}),h.dispatch.on("stateChange",function(a){for(var c in a)v[c]=a[c];y.stateChange(v),b.update()}),i.dispatch.on("legendClick",function(a){a.disabled&&(R=R.map(function(a){return a.disabled=!0,a}),a.disabled=!1,e.style(a.style),v.style=e.style(),y.stateChange(v),b.update())}),j.dispatch.on("elementMousemove",function(c){e.clearHighlights();var d,g,h,i=[];if(k.filter(function(a,b){return a.seriesIndex=b,!a.disabled}).forEach(function(f,j){g=a.interactiveBisect(f.values,c.pointXValue,b.x());var k=f.values[g],l=b.y()(k,g);if(null!=l&&e.highlightPoint(j,g,!0),"undefined"!=typeof k){"undefined"==typeof d&&(d=k),"undefined"==typeof h&&(h=b.xScale()(b.x()(k,g)));var m="expand"==e.style()?k.display.y:b.y()(k,g);i.push({key:f.key,value:m,color:o(f,f.seriesIndex),stackedValue:k.display})}}),i.reverse(),i.length>2){var m=b.yScale().invert(c.mouseY),n=null;i.forEach(function(a,b){m=Math.abs(m);var c=Math.abs(a.stackedValue.y0),d=Math.abs(a.stackedValue.y);return m>=c&&d+c>=m?void(n=b):void 0}),null!=n&&(i[n].highlight=!0)}var p=f.tickFormat()(b.x()(d,g)),q=j.tooltip.valueFormatter();"expand"===e.style()||"stack_percent"===e.style()?(E||(E=q),q=d3.format(".1%")):E&&(q=E,E=null),j.tooltip.position({left:h+l.left,top:c.mouseY+l.top}).chartContainer(F.parentNode).valueFormatter(q).data({value:p,series:i})(),j.renderGuideLine(h)}),j.dispatch.on("elementMouseout",function(){e.clearHighlights()}),y.on("changeState",function(a){"undefined"!=typeof a.disabled&&k.length===a.disabled.length&&(k.forEach(function(b,c){b.disabled=a.disabled[c]}),v.disabled=a.disabled),"undefined"!=typeof a.style&&(e.style(a.style),G=a.style),b.update()})}),F.renderEnd("stacked Area chart immediate"),b}var c,d,e=a.models.stackedArea(),f=a.models.axis(),g=a.models.axis(),h=a.models.legend(),i=a.models.legend(),j=a.interactiveGuideline(),k=a.models.tooltip(),l={top:30,right:25,bottom:50,left:60},m=null,n=null,o=a.utils.defaultColor(),p=!0,q=!0,r=!0,s=!0,t=!1,u=!1,v=a.utils.state(),w=null,x=null,y=d3.dispatch("stateChange","changeState","renderEnd"),z=250,A=["Stacked","Stream","Expanded"],B={},C=250;v.style=e.style(),f.orient("bottom").tickPadding(7),g.orient(t?"right":"left"),k.headerFormatter(function(a,b){return f.tickFormat()(a,b)}).valueFormatter(function(a,b){return g.tickFormat()(a,b)}),j.tooltip.headerFormatter(function(a,b){return f.tickFormat()(a,b)}).valueFormatter(function(a,b){return g.tickFormat()(a,b)});var D=null,E=null;i.updateState(!1);var F=a.utils.renderWatch(y),G=e.style(),H=function(a){return function(){return{active:a.map(function(a){return!a.disabled}),style:e.style()}}},I=function(a){return function(b){void 0!==b.style&&(G=b.style),void 0!==b.active&&a.forEach(function(a,c){a.disabled=!b.active[c]})}},J=d3.format("%");return e.dispatch.on("elementMouseover.tooltip",function(a){a.point.x=e.x()(a.point),a.point.y=e.y()(a.point),k.data(a).position(a.pos).hidden(!1)}),e.dispatch.on("elementMouseout.tooltip",function(){k.hidden(!0)}),b.dispatch=y,b.stacked=e,b.legend=h,b.controls=i,b.xAxis=f,b.yAxis=g,b.interactiveLayer=j,b.tooltip=k,b.dispatch=y,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return m},set:function(a){m=a}},height:{get:function(){return n},set:function(a){n=a}},showLegend:{get:function(){return q},set:function(a){q=a}},showXAxis:{get:function(){return r},set:function(a){r=a}},showYAxis:{get:function(){return s},set:function(a){s=a}},defaultState:{get:function(){return w},set:function(a){w=a}},noData:{get:function(){return x},set:function(a){x=a}},showControls:{get:function(){return p},set:function(a){p=a}},controlLabels:{get:function(){return B},set:function(a){B=a}},controlOptions:{get:function(){return A},set:function(a){A=a}},tooltips:{get:function(){return k.enabled()},set:function(b){a.deprecated("tooltips","use chart.tooltip.enabled() instead"),k.enabled(!!b)}},tooltipContent:{get:function(){return k.contentGenerator()},set:function(b){a.deprecated("tooltipContent","use chart.tooltip.contentGenerator() instead"),k.contentGenerator(b)}},margin:{get:function(){return l},set:function(a){l.top=void 0!==a.top?a.top:l.top,l.right=void 0!==a.right?a.right:l.right,l.bottom=void 0!==a.bottom?a.bottom:l.bottom,l.left=void 0!==a.left?a.left:l.left}},duration:{get:function(){return C},set:function(a){C=a,F.reset(C),e.duration(C),f.duration(C),g.duration(C)}},color:{get:function(){return o},set:function(b){o=a.utils.getColor(b),h.color(o),e.color(o)}},rightAlignYAxis:{get:function(){return t},set:function(a){t=a,g.orient(t?"right":"left")}},useInteractiveGuideline:{get:function(){return u},set:function(a){u=!!a,b.interactive(!a),b.useVoronoi(!a),e.scatter.interactive(!a)}}}),a.utils.inheritOptions(b,e),a.utils.initOptions(b),b},a.models.sunburst=function(){"use strict";function b(u){return t.reset(),u.each(function(b){function t(a){a.x0=a.x,a.dx0=a.dx}function u(a){var b=d3.interpolate(p.domain(),[a.x,a.x+a.dx]),c=d3.interpolate(q.domain(),[a.y,1]),d=d3.interpolate(q.range(),[a.y?20:0,y]);return function(a,e){return e?function(){return s(a)}:function(e){return p.domain(b(e)),q.domain(c(e)).range(d(e)),s(a)}}}l=d3.select(this);var v,w=a.utils.availableWidth(g,l,f),x=a.utils.availableHeight(h,l,f),y=Math.min(w,x)/2;a.utils.initSVG(l);var z=l.selectAll(".nv-wrap.nv-sunburst").data(b),A=z.enter().append("g").attr("class","nvd3 nv-wrap nv-sunburst nv-chart-"+k),B=A.selectAll("nv-sunburst");z.attr("transform","translate("+w/2+","+x/2+")"),l.on("click",function(a,b){o.chartClick({data:a,index:b,pos:d3.event,id:k})}),q.range([0,y]),c=c||b,e=b[0],r.value(j[i]||j.count),v=B.data(r.nodes).enter().append("path").attr("d",s).style("fill",function(a){return m((a.children?a:a.parent).name)}).style("stroke","#FFF").on("click",function(a){d!==c&&c!==a&&(d=c),c=a,v.transition().duration(n).attrTween("d",u(a))}).each(t).on("dblclick",function(a){d.parent==a&&v.transition().duration(n).attrTween("d",u(e))}).each(t).on("mouseover",function(a){d3.select(this).classed("hover",!0).style("opacity",.8),o.elementMouseover({data:a,color:d3.select(this).style("fill")})}).on("mouseout",function(a){d3.select(this).classed("hover",!1).style("opacity",1),o.elementMouseout({data:a})}).on("mousemove",function(a){o.elementMousemove({data:a})})}),t.renderEnd("sunburst immediate"),b}var c,d,e,f={top:0,right:0,bottom:0,left:0},g=null,h=null,i="count",j={count:function(){return 1},size:function(a){return a.size}},k=Math.floor(1e4*Math.random()),l=null,m=a.utils.defaultColor(),n=500,o=d3.dispatch("chartClick","elementClick","elementDblClick","elementMousemove","elementMouseover","elementMouseout","renderEnd"),p=d3.scale.linear().range([0,2*Math.PI]),q=d3.scale.sqrt(),r=d3.layout.partition().sort(null).value(function(){return 1}),s=d3.svg.arc().startAngle(function(a){return Math.max(0,Math.min(2*Math.PI,p(a.x)))}).endAngle(function(a){return Math.max(0,Math.min(2*Math.PI,p(a.x+a.dx)))}).innerRadius(function(a){return Math.max(0,q(a.y))}).outerRadius(function(a){return Math.max(0,q(a.y+a.dy))}),t=a.utils.renderWatch(o);return b.dispatch=o,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return g},set:function(a){g=a}},height:{get:function(){return h},set:function(a){h=a}},mode:{get:function(){return i},set:function(a){i=a}},id:{get:function(){return k},set:function(a){k=a}},duration:{get:function(){return n},set:function(a){n=a}},margin:{get:function(){return f},set:function(a){f.top=void 0!=a.top?a.top:f.top,f.right=void 0!=a.right?a.right:f.right,f.bottom=void 0!=a.bottom?a.bottom:f.bottom,f.left=void 0!=a.left?a.left:f.left}},color:{get:function(){return m},set:function(b){m=a.utils.getColor(b)}}}),a.utils.initOptions(b),b},a.models.sunburstChart=function(){"use strict";function b(d){return m.reset(),m.models(c),d.each(function(d){var h=d3.select(this);a.utils.initSVG(h);var i=a.utils.availableWidth(f,h,e),j=a.utils.availableHeight(g,h,e);if(b.update=function(){0===k?h.call(b):h.transition().duration(k).call(b)},b.container=this,!d||!d.length)return a.utils.noData(b,h),b;h.selectAll(".nv-noData").remove();var l=h.selectAll("g.nv-wrap.nv-sunburstChart").data(d),m=l.enter().append("g").attr("class","nvd3 nv-wrap nv-sunburstChart").append("g"),n=l.select("g");m.append("g").attr("class","nv-sunburstWrap"),l.attr("transform","translate("+e.left+","+e.top+")"),c.width(i).height(j);var o=n.select(".nv-sunburstWrap").datum(d);d3.transition(o).call(c)}),m.renderEnd("sunburstChart immediate"),b}var c=a.models.sunburst(),d=a.models.tooltip(),e={top:30,right:20,bottom:20,left:20},f=null,g=null,h=a.utils.defaultColor(),i=(Math.round(1e5*Math.random()),null),j=null,k=250,l=d3.dispatch("tooltipShow","tooltipHide","stateChange","changeState","renderEnd"),m=a.utils.renderWatch(l);return d.headerEnabled(!1).duration(0).valueFormatter(function(a){return a}),c.dispatch.on("elementMouseover.tooltip",function(a){a.series={key:a.data.name,value:a.data.size,color:a.color},d.data(a).hidden(!1)}),c.dispatch.on("elementMouseout.tooltip",function(){d.hidden(!0)}),c.dispatch.on("elementMousemove.tooltip",function(){d.position({top:d3.event.pageY,left:d3.event.pageX})()}),b.dispatch=l,b.sunburst=c,b.tooltip=d,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{noData:{get:function(){return j},set:function(a){j=a}},defaultState:{get:function(){return i},set:function(a){i=a}},color:{get:function(){return h},set:function(a){h=a,c.color(h)}},duration:{get:function(){return k},set:function(a){k=a,m.reset(k),c.duration(k)}},margin:{get:function(){return e},set:function(a){e.top=void 0!==a.top?a.top:e.top,e.right=void 0!==a.right?a.right:e.right,e.bottom=void 0!==a.bottom?a.bottom:e.bottom,e.left=void 0!==a.left?a.left:e.left}}}),a.utils.inheritOptions(b,c),a.utils.initOptions(b),b},a.version="1.8.1"}(); \ No newline at end of file diff --git a/backend/coverage-report-controllers/dashboard.html b/backend/coverage-report-controllers/dashboard.html deleted file mode 100644 index ba7e7a4a..00000000 --- a/backend/coverage-report-controllers/dashboard.html +++ /dev/null @@ -1,717 +0,0 @@ - - - - - Dashboard for /var/www/html/backend/app - - - - - - - -
-
-
-
- -
-
-
-
-
-
-
-

Classes

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
-
-
-

Insufficient Coverage

-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
ClassCoverage
App\Console\Commands\FetchNewArticlesCommand0%
App\Console\Commands\SyncChannelPostsCommand0%
App\Events\ArticleReadyToPublish0%
App\Events\ExceptionLogged0%
App\Events\ExceptionOccurred0%
App\Exceptions\PlatformAuthException0%
App\Exceptions\PublishException0%
App\Exceptions\RoutingMismatchException0%
App\Http\Controllers\Api\V1\AuthController0%
App\Http\Controllers\Api\V1\LogsController0%
App\Http\Controllers\Api\V1\PlatformAccountsController0%
App\Http\Controllers\Api\V1\PlatformChannelsController0%
App\Http\Controllers\Api\V1\RoutingController0%
App\Http\Controllers\ArticlesController0%
App\Http\Controllers\FeedsController0%
App\Http\Controllers\LogsController0%
App\Http\Controllers\OnboardingController0%
App\Http\Controllers\PlatformAccountsController0%
App\Http\Controllers\PlatformChannelsController0%
App\Http\Controllers\RoutingController0%
App\Http\Controllers\SettingsController0%
App\Http\Middleware\HandleAppearance0%
App\Http\Middleware\HandleInertiaRequests0%
App\Http\Resources\ArticlePublicationResource0%
App\Http\Resources\PlatformAccountResource0%
App\Http\Resources\PlatformChannelResource0%
App\Http\Resources\PlatformInstanceResource0%
App\Http\Resources\RouteResource0%
App\Jobs\ArticleDiscoveryForFeedJob0%
App\Jobs\ArticleDiscoveryJob0%
App\Jobs\PublishToLemmyJob0%
App\Jobs\SyncChannelPostsJob0%
App\Listeners\LogExceptionToDatabase0%
App\Listeners\PublishApprovedArticle0%
App\Listeners\PublishArticle0%
App\Listeners\ValidateArticleListener0%
App\Models\ArticlePublication0%
App\Models\Keyword0%
App\Models\Language0%
App\Models\PlatformAccount0%
App\Models\PlatformChannel0%
App\Models\PlatformChannelPost0%
App\Models\PlatformInstance0%
App\Models\Route0%
App\Models\User0%
App\Modules\Lemmy\LemmyRequest0%
App\Modules\Lemmy\Services\LemmyApiService0%
App\Modules\Lemmy\Services\LemmyPublisher0%
App\Services\Article\ArticleFetcher0%
App\Services\Article\ValidationService0%
App\Services\Auth\LemmyAuthService0%
App\Services\Factories\ArticleParserFactory0%
App\Services\Factories\HomepageParserFactory0%
App\Services\Http\HttpFetcher0%
App\Services\Log\LogSaver0%
App\Services\OnboardingRedirectService0%
App\Services\Parsers\BelgaArticlePageParser0%
App\Services\Parsers\BelgaArticleParser0%
App\Services\Parsers\BelgaHomepageParser0%
App\Services\Parsers\BelgaHomepageParserAdapter0%
App\Services\Parsers\VrtArticlePageParser0%
App\Services\Parsers\VrtArticleParser0%
App\Services\Parsers\VrtHomepageParser0%
App\Services\Parsers\VrtHomepageParserAdapter0%
App\Services\Publishing\ArticlePublishingService0%
App\Services\RoutingValidationService0%
App\Services\SystemStatusService0%
App\Models\Feed4%
App\Models\Article66%
App\Providers\HorizonServiceProvider75%
App\Http\Controllers\Api\V1\FeedsController76%
App\Providers\AppServiceProvider82%
App\Http\Controllers\Api\V1\DashboardController84%
App\Http\Controllers\Api\V1\SettingsController85%
App\Http\Controllers\Api\V1\BaseController87%
App\Http\Controllers\Api\V1\ArticlesController87%
-
-
-
-

Project Risks

-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
ClassCRAP
App\Http\Controllers\OnboardingController506
App\Modules\Lemmy\Services\LemmyApiService462
App\Http\Controllers\Api\V1\RoutingController306
App\Services\Parsers\BelgaArticlePageParser306
App\Http\Controllers\RoutingController240
App\Http\Controllers\Api\V1\PlatformAccountsController210
App\Services\Parsers\VrtArticlePageParser210
App\Http\Controllers\Api\V1\PlatformChannelsController182
App\Jobs\SyncChannelPostsJob182
App\Models\Feed161
App\Http\Controllers\Api\V1\AuthController132
App\Services\Article\ArticleFetcher132
App\Http\Controllers\PlatformAccountsController110
App\Http\Controllers\PlatformChannelsController110
App\Models\PlatformAccount110
App\Http\Controllers\FeedsController90
App\Services\Http\HttpFetcher90
App\Services\SystemStatusService72
App\Listeners\ValidateArticleListener56
App\Modules\Lemmy\LemmyRequest42
App\Services\Auth\LemmyAuthService42
App\Services\Factories\ArticleParserFactory42
App\Services\Log\LogSaver42
App\Exceptions\PublishException30
App\Services\Article\ValidationService30
App\Services\Factories\HomepageParserFactory30
App\Services\Publishing\ArticlePublishingService30
App\Services\RoutingValidationService30
App\Models\Article23
App\Listeners\PublishApprovedArticle20
App\Http\Controllers\Api\V1\FeedsController15
App\Console\Commands\FetchNewArticlesCommand12
App\Console\Commands\SyncChannelPostsCommand12
App\Http\Controllers\Api\V1\LogsController12
App\Http\Controllers\SettingsController12
App\Jobs\ArticleDiscoveryJob12
App\Jobs\PublishToLemmyJob12
App\Listeners\PublishArticle12
App\Http\Controllers\Api\V1\SettingsController7
App\Providers\AppServiceProvider6
App\Http\Controllers\Api\V1\BaseController6
App\Services\OnboardingRedirectService6
App\Http\Controllers\Api\V1\ArticlesController5
App\Http\Controllers\Api\V1\DashboardController3
-
-
-
-
-
-

Methods

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
-
-
-

Insufficient Coverage

-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
MethodCoverage
handle0%
handle0%
syncLemmy0%
__construct0%
__construct0%
__construct0%
__construct0%
getPlatform0%
__construct0%
getArticle0%
getPlatform0%
__construct0%
login0%
register0%
logout0%
me0%
sendNotFound0%
sendUnauthorized0%
index0%
index0%
store0%
show0%
update0%
destroy0%
setActive0%
index0%
store0%
show0%
update0%
destroy0%
toggle0%
index0%
store0%
show0%
update0%
destroy0%
toggle0%
__invoke0%
approve0%
reject0%
index0%
create0%
store0%
show0%
edit0%
update0%
destroy0%
toggle0%
__invoke0%
index0%
platform0%
feed0%
channel0%
complete0%
needsOnboarding0%
hasPlatformAccount0%
hasFeed0%
hasChannel0%
index0%
create0%
store0%
edit0%
update0%
destroy0%
setActive0%
index0%
create0%
store0%
show0%
edit0%
update0%
destroy0%
toggle0%
index0%
create0%
store0%
edit0%
update0%
destroy0%
toggle0%
parseJsonFilters0%
index0%
update0%
handle0%
version0%
share0%
toArray0%
toArray0%
toArray0%
toArray0%
toArray0%
__construct0%
handle0%
dispatchForAllActiveFeeds0%
__construct0%
handle0%
__construct0%
handle0%
__construct0%
dispatchForAllActiveChannels0%
handle0%
syncLemmyChannelPosts0%
getAuthToken0%
handle0%
handle0%
__construct0%
handle0%
handle0%
isValid0%
isApproved0%
isPending0%
isRejected0%
canBePublished0%
article0%
getTypeDisplayAttribute0%
getStatusAttribute0%
channels0%
activeChannels0%
language0%
feed0%
platformChannel0%
platformInstances0%
platformChannels0%
feeds0%
password0%
apiToken0%
getActive0%
setAsActive0%
channels0%
activeChannels0%
platformInstance0%
platformAccounts0%
activePlatformAccounts0%
getFullNameAttribute0%
feeds0%
activeFeeds0%
language0%
casts0%
urlExists0%
storePost0%
channels0%
languages0%
findByUrl0%
feed0%
platformChannel0%
keywords0%
casts0%
__construct0%
get0%
post0%
withToken0%
__construct0%
login0%
getCommunityId0%
syncChannelPosts0%
createPost0%
getLanguages0%
__construct0%
publishToChannel0%
mapExceptionToLogLevel0%
getArticlesFromFeed0%
getArticlesFromRssFeed0%
getArticlesFromWebsiteFeed0%
fetchArticleData0%
saveArticle0%
validate0%
validateByKeywords0%
getToken0%
getParser0%
getSupportedSources0%
registerParser0%
getParser0%
getParserForFeed0%
fetchHtml0%
fetchMultipleUrls0%
info0%
error0%
warning0%
debug0%
log0%
handleRedirect0%
extractTitle0%
extractDescription0%
extractFullArticle0%
extractThumbnail0%
extractData0%
canParse0%
extractData0%
getSourceName0%
extractArticleUrls0%
canParse0%
extractArticleUrls0%
getHomepageUrl0%
getSourceName0%
extractTitle0%
extractDescription0%
extractFullArticle0%
extractThumbnail0%
extractData0%
canParse0%
extractData0%
getSourceName0%
extractArticleUrls0%
canParse0%
extractArticleUrls0%
getHomepageUrl0%
getSourceName0%
publishToRoutedChannels0%
publishToChannel0%
validateLanguageCompatibility0%
getSystemStatus0%
canProcessArticles0%
update63%
store66%
gate66%
approve71%
reject71%
destroy71%
index71%
toggle77%
stats83%
-
-
- -
- -
- - - - - - diff --git a/backend/coverage-report-controllers/index.html b/backend/coverage-report-controllers/index.html deleted file mode 100644 index 4323547a..00000000 --- a/backend/coverage-report-controllers/index.html +++ /dev/null @@ -1,424 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 16.65% covered (danger) -
-
-
16.65%
277 / 1664
-
- 14.23% covered (danger) -
-
-
14.23%
37 / 260
-
- 10.59% covered (danger) -
-
-
10.59%
9 / 85
Console
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 16
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
Contracts
n/a
0 / 0
n/a
0 / 0
n/a
0 / 0
Enums
n/a
0 / 0
n/a
0 / 0
n/a
0 / 0
Events
-
- 40.00% covered (danger) -
-
-
40.00%
2 / 5
-
- 40.00% covered (danger) -
-
-
40.00%
2 / 5
-
- 40.00% covered (danger) -
-
-
40.00%
2 / 5
Exceptions
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 19
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 6
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
Http
-
- 20.07% covered (danger) -
-
-
20.07%
164 / 817
-
- 12.87% covered (danger) -
-
-
12.87%
13 / 101
-
- 13.79% covered (danger) -
-
-
13.79%
4 / 29
Jobs
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 81
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 12
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 4
Listeners
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 43
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 5
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 4
Models
-
- 24.34% covered (danger) -
-
-
24.34%
37 / 152
-
- 27.78% covered (danger) -
-
-
27.78%
15 / 54
-
- 8.33% covered (danger) -
-
-
8.33%
1 / 12
Modules
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 120
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 12
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
Providers
-
- 81.82% covered (warning) -
-
-
81.82%
27 / 33
-
- 40.00% covered (danger) -
-
-
40.00%
2 / 5
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
Services
-
- 10.78% covered (danger) -
-
-
10.78%
40 / 371
-
- 7.14% covered (danger) -
-
-
7.14%
4 / 56
-
- 5.00% covered (danger) -
-
-
5.00%
1 / 20
LogLevelEnum.php
-
- 100.00% covered (success) -
-
-
100.00%
7 / 7
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
-
- -
- - diff --git a/backend/coverage-report-final/Console/Commands/FetchNewArticlesCommand.php.html b/backend/coverage-report-final/Console/Commands/FetchNewArticlesCommand.php.html deleted file mode 100644 index 562bcd85..00000000 --- a/backend/coverage-report-final/Console/Commands/FetchNewArticlesCommand.php.html +++ /dev/null @@ -1,187 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Console/Commands/FetchNewArticlesCommand.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 8
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
FetchNewArticlesCommand
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 8
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
12
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 handle
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 8
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
12
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Console\Commands;
4
5use App\Jobs\ArticleDiscoveryJob;
6use App\Models\Feed;
7use App\Models\Setting;
8use Illuminate\Console\Command;
9
10class FetchNewArticlesCommand extends Command
11{
12    protected $signature = 'article:refresh';
13
14    protected $description = 'Fetches latest articles';
15
16    public function handle(): int
17    {
18        if (!Setting::isArticleProcessingEnabled()) {
19            $this->info('Article processing is disabled. Article discovery skipped.');
20
21            return self::SUCCESS;
22        }
23
24        if (!Feed::where('is_active', true)->exists()) {
25            $this->info('No active feeds found. Article discovery skipped.');
26
27            return self::SUCCESS;
28        }
29
30        ArticleDiscoveryJob::dispatch();
31
32        return self::SUCCESS;
33    }
34}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:53:46 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-final/Console/Commands/SyncChannelPostsCommand.php.html b/backend/coverage-report-final/Console/Commands/SyncChannelPostsCommand.php.html deleted file mode 100644 index 8a6ded49..00000000 --- a/backend/coverage-report-final/Console/Commands/SyncChannelPostsCommand.php.html +++ /dev/null @@ -1,209 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Console/Commands/SyncChannelPostsCommand.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 8
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
SyncChannelPostsCommand
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 8
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
12
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 handle
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 5
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
6
 syncLemmy
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Console\Commands;
4
5use App\Jobs\SyncChannelPostsJob;
6use Illuminate\Console\Command;
7
8class SyncChannelPostsCommand extends Command
9{
10    protected $signature = 'channel:sync {platform=lemmy}';
11
12    protected $description = 'Manually sync channel posts for a platform';
13
14    public function handle(): int
15    {
16        $platform = $this->argument('platform');
17
18        if ($platform === 'lemmy') {
19            return $this->syncLemmy();
20        }
21
22        $this->error("Unsupported platform: {$platform}");
23
24        return self::FAILURE;
25    }
26
27    private function syncLemmy(): int
28    {
29        SyncChannelPostsJob::dispatchForAllActiveChannels();
30        $this->info('Successfully dispatched sync jobs for all active Lemmy channels');
31
32        return self::SUCCESS;
33    }
34}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:53:46 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-final/Console/Commands/dashboard.html b/backend/coverage-report-final/Console/Commands/dashboard.html deleted file mode 100644 index ee617926..00000000 --- a/backend/coverage-report-final/Console/Commands/dashboard.html +++ /dev/null @@ -1,294 +0,0 @@ - - - - - Dashboard for /var/www/html/backend/app/Console/Commands - - - - - - - -
-
-
-
- -
-
-
-
-
-
-
-

Classes

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
-
-
-

Insufficient Coverage

- -
-
-

Project Risks

- -
-
-
-
-

Methods

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
-
-
-

Insufficient Coverage

-
- - - - - - - - - - - - - -
MethodCoverage
handle0%
handle0%
syncLemmy0%
-
-
-
-

Project Risks

-
- - - - - - - - - - - - -
MethodCRAP
handle12
handle6
-
-
-
- -
- - - - - - diff --git a/backend/coverage-report-final/Console/Commands/index.html b/backend/coverage-report-final/Console/Commands/index.html deleted file mode 100644 index 4012e3a1..00000000 --- a/backend/coverage-report-final/Console/Commands/index.html +++ /dev/null @@ -1,148 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Console/Commands - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 16
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
FetchNewArticlesCommand.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 8
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
SyncChannelPostsCommand.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 8
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- -
- - diff --git a/backend/coverage-report-final/Console/dashboard.html b/backend/coverage-report-final/Console/dashboard.html deleted file mode 100644 index 1b688d11..00000000 --- a/backend/coverage-report-final/Console/dashboard.html +++ /dev/null @@ -1,293 +0,0 @@ - - - - - Dashboard for /var/www/html/backend/app/Console - - - - - - - -
-
-
-
- -
-
-
-
-
-
-
-

Classes

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
-
-
-

Insufficient Coverage

- -
-
-

Project Risks

- -
-
-
-
-

Methods

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
-
-
-

Insufficient Coverage

-
- - - - - - - - - - - - - -
MethodCoverage
handle0%
handle0%
syncLemmy0%
-
-
-
-

Project Risks

-
- - - - - - - - - - - - -
MethodCRAP
handle12
handle6
-
-
-
- -
- - - - - - diff --git a/backend/coverage-report-final/Console/index.html b/backend/coverage-report-final/Console/index.html deleted file mode 100644 index 33511b3d..00000000 --- a/backend/coverage-report-final/Console/index.html +++ /dev/null @@ -1,119 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Console - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 16
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
Commands
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 16
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
-
- -
- - diff --git a/backend/coverage-report-final/Contracts/ArticleParserInterface.php.html b/backend/coverage-report-final/Contracts/ArticleParserInterface.php.html deleted file mode 100644 index b1c43311..00000000 --- a/backend/coverage-report-final/Contracts/ArticleParserInterface.php.html +++ /dev/null @@ -1,108 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Contracts/ArticleParserInterface.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
n/a
0 / 0
n/a
0 / 0
CRAP
n/a
0 / 0
-
- - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Contracts;
4
5interface ArticleParserInterface
6{
7    /**
8     * Check if this parser can handle the given URL
9     */
10    public function canParse(string $url): bool;
11
12    /**
13     * Extract article data from HTML
14     * @return array<string, mixed>
15     */
16    public function extractData(string $html): array;
17
18    /**
19     * Get the source name for this parser
20     */
21    public function getSourceName(): string;
22}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:53:46 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-final/Contracts/HomepageParserInterface.php.html b/backend/coverage-report-final/Contracts/HomepageParserInterface.php.html deleted file mode 100644 index 30822acc..00000000 --- a/backend/coverage-report-final/Contracts/HomepageParserInterface.php.html +++ /dev/null @@ -1,113 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Contracts/HomepageParserInterface.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
n/a
0 / 0
n/a
0 / 0
CRAP
n/a
0 / 0
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Contracts;
4
5interface HomepageParserInterface
6{
7    /**
8     * Check if this parser can handle the given homepage URL
9     */
10    public function canParse(string $url): bool;
11
12    /**
13     * Extract article URLs from homepage HTML
14     * @return array<int, string>
15     */
16    public function extractArticleUrls(string $html): array;
17
18    /**
19     * Get the homepage URL for this source
20     */
21    public function getHomepageUrl(): string;
22
23    /**
24     * Get the source name for this parser
25     */
26    public function getSourceName(): string;
27}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:53:46 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-final/Contracts/dashboard.html b/backend/coverage-report-final/Contracts/dashboard.html deleted file mode 100644 index 679b5a83..00000000 --- a/backend/coverage-report-final/Contracts/dashboard.html +++ /dev/null @@ -1,284 +0,0 @@ - - - - - Dashboard for /var/www/html/backend/app/Contracts - - - - - - - -
-
-
-
- -
-
-
-
-
-
-
-

Classes

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
-
-
-

Insufficient Coverage

-
- - - - - - - - - - -
ClassCoverage
-
-
-
-

Project Risks

-
- - - - - - - - - - -
ClassCRAP
-
-
-
-
-
-

Methods

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
-
-
-

Insufficient Coverage

-
- - - - - - - - - - -
MethodCoverage
-
-
-
-

Project Risks

-
- - - - - - - - - - -
MethodCRAP
-
-
-
- -
- - - - - - diff --git a/backend/coverage-report-final/Contracts/index.html b/backend/coverage-report-final/Contracts/index.html deleted file mode 100644 index 5ea65915..00000000 --- a/backend/coverage-report-final/Contracts/index.html +++ /dev/null @@ -1,102 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Contracts - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
n/a
0 / 0
n/a
0 / 0
n/a
0 / 0
ArticleParserInterface.php
n/a
0 / 0
n/a
0 / 0
n/a
0 / 0
HomepageParserInterface.php
n/a
0 / 0
n/a
0 / 0
n/a
0 / 0
-
- -
- - diff --git a/backend/coverage-report-final/Enums/PlatformEnum.php.html b/backend/coverage-report-final/Enums/PlatformEnum.php.html deleted file mode 100644 index 4bca2566..00000000 --- a/backend/coverage-report-final/Enums/PlatformEnum.php.html +++ /dev/null @@ -1,94 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Enums/PlatformEnum.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
n/a
0 / 0
n/a
0 / 0
CRAP
n/a
0 / 0
-
- - - - - - - - - - - - -
1<?php
2
3namespace App\Enums;
4
5enum PlatformEnum: string
6{
7    case LEMMY = 'lemmy';
8}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:53:46 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-final/Enums/dashboard.html b/backend/coverage-report-final/Enums/dashboard.html deleted file mode 100644 index c2ceb5ec..00000000 --- a/backend/coverage-report-final/Enums/dashboard.html +++ /dev/null @@ -1,284 +0,0 @@ - - - - - Dashboard for /var/www/html/backend/app/Enums - - - - - - - -
-
-
-
- -
-
-
-
-
-
-
-

Classes

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
-
-
-

Insufficient Coverage

-
- - - - - - - - - - -
ClassCoverage
-
-
-
-

Project Risks

-
- - - - - - - - - - -
ClassCRAP
-
-
-
-
-
-

Methods

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
-
-
-

Insufficient Coverage

-
- - - - - - - - - - -
MethodCoverage
-
-
-
-

Project Risks

-
- - - - - - - - - - -
MethodCRAP
-
-
-
- -
- - - - - - diff --git a/backend/coverage-report-final/Enums/index.html b/backend/coverage-report-final/Enums/index.html deleted file mode 100644 index ffbba100..00000000 --- a/backend/coverage-report-final/Enums/index.html +++ /dev/null @@ -1,89 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Enums - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
n/a
0 / 0
n/a
0 / 0
n/a
0 / 0
PlatformEnum.php
n/a
0 / 0
n/a
0 / 0
n/a
0 / 0
-
- -
- - diff --git a/backend/coverage-report-final/Events/ArticleApproved.php.html b/backend/coverage-report-final/Events/ArticleApproved.php.html deleted file mode 100644 index d05243fe..00000000 --- a/backend/coverage-report-final/Events/ArticleApproved.php.html +++ /dev/null @@ -1,169 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Events/ArticleApproved.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
CRAP
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
ArticleApproved
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
1
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
 __construct
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
1
-
- - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Events;
4
5use App\Models\Article;
6use Illuminate\Foundation\Events\Dispatchable;
7use Illuminate\Queue\SerializesModels;
8
9class ArticleApproved
10{
11    use Dispatchable, SerializesModels;
12
13    public function __construct(public Article $article)
14    {
15        //
16    }
17}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:53:46 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-final/Events/ArticleReadyToPublish.php.html b/backend/coverage-report-final/Events/ArticleReadyToPublish.php.html deleted file mode 100644 index e045d12d..00000000 --- a/backend/coverage-report-final/Events/ArticleReadyToPublish.php.html +++ /dev/null @@ -1,170 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Events/ArticleReadyToPublish.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
ArticleReadyToPublish
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 __construct
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Events;
4
5use App\Models\Article;
6use Illuminate\Broadcasting\InteractsWithSockets;
7use Illuminate\Foundation\Events\Dispatchable;
8use Illuminate\Queue\SerializesModels;
9
10class ArticleReadyToPublish
11{
12    use Dispatchable, InteractsWithSockets, SerializesModels;
13
14    public function __construct(public Article $article)
15    {
16
17    }
18}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:53:46 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-final/Events/ExceptionLogged.php.html b/backend/coverage-report-final/Events/ExceptionLogged.php.html deleted file mode 100644 index 4e8df9d9..00000000 --- a/backend/coverage-report-final/Events/ExceptionLogged.php.html +++ /dev/null @@ -1,169 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Events/ExceptionLogged.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
ExceptionLogged
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 __construct
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Events;
4
5use App\Models\Log;
6use Illuminate\Foundation\Events\Dispatchable;
7use Illuminate\Queue\SerializesModels;
8
9class ExceptionLogged
10{
11    use Dispatchable, SerializesModels;
12
13    public function __construct(
14        public Log $log
15    ) {
16    }
17}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:53:46 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-final/Events/ExceptionOccurred.php.html b/backend/coverage-report-final/Events/ExceptionOccurred.php.html deleted file mode 100644 index 1b99fe30..00000000 --- a/backend/coverage-report-final/Events/ExceptionOccurred.php.html +++ /dev/null @@ -1,174 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Events/ExceptionOccurred.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
ExceptionOccurred
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 __construct
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Events;
4
5use App\LogLevelEnum;
6use Illuminate\Foundation\Events\Dispatchable;
7use Illuminate\Queue\SerializesModels;
8use Throwable;
9
10class ExceptionOccurred
11{
12    use Dispatchable, SerializesModels;
13
14    public function __construct(
15        public Throwable $exception,
16        public LogLevelEnum $level,
17        public string $message,
18        /** @var array<string, mixed> */
19        public array $context = []
20    ) {
21    }
22}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:53:46 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-final/Events/NewArticleFetched.php.html b/backend/coverage-report-final/Events/NewArticleFetched.php.html deleted file mode 100644 index 5a7cf677..00000000 --- a/backend/coverage-report-final/Events/NewArticleFetched.php.html +++ /dev/null @@ -1,169 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Events/NewArticleFetched.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
CRAP
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
NewArticleFetched
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
1
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
 __construct
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
1
-
- - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Events;
4
5use App\Models\Article;
6use Illuminate\Broadcasting\InteractsWithSockets;
7use Illuminate\Foundation\Events\Dispatchable;
8use Illuminate\Queue\SerializesModels;
9
10class NewArticleFetched
11{
12    use Dispatchable, InteractsWithSockets, SerializesModels;
13
14    public function __construct(public Article $article)
15    {
16    }
17}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:53:46 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-final/Events/dashboard.html b/backend/coverage-report-final/Events/dashboard.html deleted file mode 100644 index 48daa99f..00000000 --- a/backend/coverage-report-final/Events/dashboard.html +++ /dev/null @@ -1,290 +0,0 @@ - - - - - Dashboard for /var/www/html/backend/app/Events - - - - - - - -
-
-
-
- -
-
-
-
-
-
-
-

Classes

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
-
-
-

Insufficient Coverage

- -
-
-

Project Risks

-
- - - - - - - - - - -
ClassCRAP
-
-
-
-
-
-

Methods

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
-
-
-

Insufficient Coverage

-
- - - - - - - - - - - - - -
MethodCoverage
__construct0%
__construct0%
__construct0%
-
-
-
-

Project Risks

-
- - - - - - - - - - -
MethodCRAP
-
-
-
- -
- - - - - - diff --git a/backend/coverage-report-final/Events/index.html b/backend/coverage-report-final/Events/index.html deleted file mode 100644 index 266f0378..00000000 --- a/backend/coverage-report-final/Events/index.html +++ /dev/null @@ -1,231 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Events - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 40.00% covered (danger) -
-
-
40.00%
2 / 5
-
- 40.00% covered (danger) -
-
-
40.00%
2 / 5
-
- 40.00% covered (danger) -
-
-
40.00%
2 / 5
ArticleApproved.php
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
ArticleReadyToPublish.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
ExceptionLogged.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
ExceptionOccurred.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
NewArticleFetched.php
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
-
- -
- - diff --git a/backend/coverage-report-final/Exceptions/ChannelException.php.html b/backend/coverage-report-final/Exceptions/ChannelException.php.html deleted file mode 100644 index 983af59a..00000000 --- a/backend/coverage-report-final/Exceptions/ChannelException.php.html +++ /dev/null @@ -1,109 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Exceptions/ChannelException.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
n/a
0 / 0
n/a
0 / 0
CRAP
n/a
0 / 0
ChannelException
n/a
0 / 0
n/a
0 / 0
0
n/a
0 / 0
-
- - - - - - - - - - - - - -
1<?php
2
3namespace App\Exceptions;
4
5use Exception;
6
7class ChannelException extends Exception
8{
9}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:53:46 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-final/Exceptions/PlatformAuthException.php.html b/backend/coverage-report-final/Exceptions/PlatformAuthException.php.html deleted file mode 100644 index 33ef1e0f..00000000 --- a/backend/coverage-report-final/Exceptions/PlatformAuthException.php.html +++ /dev/null @@ -1,197 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Exceptions/PlatformAuthException.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
PlatformAuthException
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
6
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 __construct
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 getPlatform
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Exceptions;
4
5use App\Enums\PlatformEnum;
6use Exception;
7
8class PlatformAuthException extends Exception
9{
10    public function __construct(
11        private readonly PlatformEnum $platform,
12        string $reason = 'Authentication failed'
13    ) {
14        $message = "Failed to authenticate with {$platform->value}: {$reason}";
15
16        parent::__construct($message);
17    }
18
19    public function getPlatform(): PlatformEnum
20    {
21        return $this->platform;
22    }
23}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:53:46 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-final/Exceptions/PublishException.php.html b/backend/coverage-report-final/Exceptions/PublishException.php.html deleted file mode 100644 index 8a1936f5..00000000 --- a/backend/coverage-report-final/Exceptions/PublishException.php.html +++ /dev/null @@ -1,235 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Exceptions/PublishException.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 8
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
PublishException
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 8
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
30
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 __construct
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 6
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
12
 getArticle
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 getPlatform
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Exceptions;
4
5use App\Enums\PlatformEnum;
6use App\Models\Article;
7use Exception;
8use Throwable;
9
10class PublishException extends Exception
11{
12    public function __construct(
13        private readonly Article $article,
14        private readonly PlatformEnum|null $platform,
15        ?Throwable $previous = null
16    ) {
17        $message = "Failed to publish article #$article->id";
18
19        if ($this->platform) {
20            $message .= "  to $platform->value";
21        }
22
23        if ($previous) {
24            $message .= ": {$previous->getMessage()}";
25        }
26
27        parent::__construct($message, 0, $previous);
28    }
29
30    public function getArticle(): Article
31    {
32        return $this->article;
33    }
34
35    public function getPlatform(): ?PlatformEnum
36    {
37        return $this->platform;
38    }
39}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:53:46 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-final/Exceptions/RoutingException.php.html b/backend/coverage-report-final/Exceptions/RoutingException.php.html deleted file mode 100644 index 2b1cf290..00000000 --- a/backend/coverage-report-final/Exceptions/RoutingException.php.html +++ /dev/null @@ -1,109 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Exceptions/RoutingException.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
n/a
0 / 0
n/a
0 / 0
CRAP
n/a
0 / 0
RoutingException
n/a
0 / 0
n/a
0 / 0
0
n/a
0 / 0
-
- - - - - - - - - - - - - -
1<?php
2
3namespace App\Exceptions;
4
5use Exception;
6
7class RoutingException extends Exception
8{
9}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:53:46 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-final/Exceptions/RoutingMismatchException.php.html b/backend/coverage-report-final/Exceptions/RoutingMismatchException.php.html deleted file mode 100644 index b64c41c9..00000000 --- a/backend/coverage-report-final/Exceptions/RoutingMismatchException.php.html +++ /dev/null @@ -1,174 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Exceptions/RoutingMismatchException.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 8
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
RoutingMismatchException
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 8
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 __construct
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 8
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Exceptions;
4
5use App\Models\Feed;
6use App\Models\PlatformChannel;
7
8class RoutingMismatchException extends RoutingException
9{
10    public function __construct(Feed $feed, PlatformChannel $channel)
11    {
12        $message = sprintf(
13            "Language mismatch: Feed '%s' is in '%s' but channel '%s' is set to '%s'. Feed and channel languages must match for proper content routing.",
14            $feed->name,
15            $feed->language,
16            $channel->name,
17            $channel->language
18        );
19
20        parent::__construct($message);
21    }
22}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:53:46 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-final/Exceptions/dashboard.html b/backend/coverage-report-final/Exceptions/dashboard.html deleted file mode 100644 index 5e9ecf2c..00000000 --- a/backend/coverage-report-final/Exceptions/dashboard.html +++ /dev/null @@ -1,295 +0,0 @@ - - - - - Dashboard for /var/www/html/backend/app/Exceptions - - - - - - - -
-
-
-
- -
-
-
-
-
-
-
-

Classes

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
-
-
-

Insufficient Coverage

- -
-
-

Project Risks

-
- - - - - - - - - - - -
ClassCRAP
App\Exceptions\PublishException30
-
-
-
-
-
-

Methods

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
-
-
-

Insufficient Coverage

-
- - - - - - - - - - - - - - - - -
MethodCoverage
__construct0%
getPlatform0%
__construct0%
getArticle0%
getPlatform0%
__construct0%
-
-
-
-

Project Risks

-
- - - - - - - - - - - -
MethodCRAP
__construct12
-
-
-
- -
- - - - - - diff --git a/backend/coverage-report-final/Exceptions/index.html b/backend/coverage-report-final/Exceptions/index.html deleted file mode 100644 index 0aaa0613..00000000 --- a/backend/coverage-report-final/Exceptions/index.html +++ /dev/null @@ -1,201 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Exceptions - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 19
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 6
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
ChannelException.php
n/a
0 / 0
n/a
0 / 0
n/a
0 / 0
PlatformAuthException.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
PublishException.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 8
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
RoutingException.php
n/a
0 / 0
n/a
0 / 0
n/a
0 / 0
RoutingMismatchException.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 8
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- -
- - diff --git a/backend/coverage-report-final/Http/Controllers/Api/V1/ArticlesController.php.html b/backend/coverage-report-final/Http/Controllers/Api/V1/ArticlesController.php.html deleted file mode 100644 index 37bad7ea..00000000 --- a/backend/coverage-report-final/Http/Controllers/Api/V1/ArticlesController.php.html +++ /dev/null @@ -1,273 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Http/Controllers/Api/V1/ArticlesController.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 87.88% covered (warning) -
-
-
87.88%
29 / 33
-
- 33.33% covered (danger) -
-
-
33.33%
1 / 3
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
ArticlesController
-
- 87.88% covered (warning) -
-
-
87.88%
29 / 33
-
- 33.33% covered (danger) -
-
-
33.33%
1 / 3
5.04
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 index
-
- 100.00% covered (success) -
-
-
100.00%
19 / 19
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
1
 approve
-
- 71.43% covered (warning) -
-
-
71.43%
5 / 7
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2.09
 reject
-
- 71.43% covered (warning) -
-
-
71.43%
5 / 7
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2.09
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Http\Controllers\Api\V1;
4
5use App\Http\Resources\ArticleResource;
6use App\Models\Article;
7use App\Models\Setting;
8use Illuminate\Http\JsonResponse;
9use Illuminate\Http\Request;
10
11class ArticlesController extends BaseController
12{
13    /**
14     * Display a listing of articles
15     */
16    public function index(Request $request): JsonResponse
17    {
18        $perPage = min($request->get('per_page', 15), 100); // Max 100 items per page
19        $articles = Article::with(['feed', 'articlePublication'])
20            ->orderBy('created_at', 'desc')
21            ->paginate($perPage);
22
23        $publishingApprovalsEnabled = Setting::isPublishingApprovalsEnabled();
24
25        return $this->sendResponse([
26            'articles' => ArticleResource::collection($articles->items()),
27            'pagination' => [
28                'current_page' => $articles->currentPage(),
29                'last_page' => $articles->lastPage(),
30                'per_page' => $articles->perPage(),
31                'total' => $articles->total(),
32                'from' => $articles->firstItem(),
33                'to' => $articles->lastItem(),
34            ],
35            'settings' => [
36                'publishing_approvals_enabled' => $publishingApprovalsEnabled,
37            ],
38        ]);
39    }
40
41    /**
42     * Approve an article
43     */
44    public function approve(Article $article): JsonResponse
45    {
46        try {
47            $article->approve('manual');
48            
49            return $this->sendResponse(
50                new ArticleResource($article->fresh(['feed', 'articlePublication'])),
51                'Article approved and queued for publishing.'
52            );
53        } catch (\Exception $e) {
54            return $this->sendError('Failed to approve article: ' . $e->getMessage(), [], 500);
55        }
56    }
57
58    /**
59     * Reject an article
60     */
61    public function reject(Article $article): JsonResponse
62    {
63        try {
64            $article->reject('manual');
65            
66            return $this->sendResponse(
67                new ArticleResource($article->fresh(['feed', 'articlePublication'])),
68                'Article rejected.'
69            );
70        } catch (\Exception $e) {
71            return $this->sendError('Failed to reject article: ' . $e->getMessage(), [], 500);
72        }
73    }
74}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:53:46 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-final/Http/Controllers/Api/V1/AuthController.php.html b/backend/coverage-report-final/Http/Controllers/Api/V1/AuthController.php.html deleted file mode 100644 index 43fd6113..00000000 --- a/backend/coverage-report-final/Http/Controllers/Api/V1/AuthController.php.html +++ /dev/null @@ -1,333 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Http/Controllers/Api/V1/AuthController.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 56
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 4
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
AuthController
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 56
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 4
132
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 login
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 21
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
30
 register
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 24
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
12
 logout
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 4
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
6
 me
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 7
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Http\Controllers\Api\V1;
4
5use App\Models\User;
6use Illuminate\Http\JsonResponse;
7use Illuminate\Http\Request;
8use Illuminate\Support\Facades\Auth;
9use Illuminate\Support\Facades\Hash;
10use Illuminate\Validation\ValidationException;
11
12class AuthController extends BaseController
13{
14    /**
15     * Login user and create token
16     */
17    public function login(Request $request): JsonResponse
18    {
19        try {
20            $request->validate([
21                'email' => 'required|email',
22                'password' => 'required',
23            ]);
24
25            $user = User::where('email', $request->email)->first();
26
27            if (!$user || !Hash::check($request->password, $user->password)) {
28                return $this->sendError('Invalid credentials', [], 401);
29            }
30
31            $token = $user->createToken('api-token')->plainTextToken;
32
33            return $this->sendResponse([
34                'user' => [
35                    'id' => $user->id,
36                    'name' => $user->name,
37                    'email' => $user->email,
38                ],
39                'token' => $token,
40                'token_type' => 'Bearer',
41            ], 'Login successful');
42        } catch (ValidationException $e) {
43            return $this->sendValidationError($e->errors());
44        } catch (\Exception $e) {
45            return $this->sendError('Login failed: ' . $e->getMessage(), [], 500);
46        }
47    }
48
49    /**
50     * Register a new user
51     */
52    public function register(Request $request): JsonResponse
53    {
54        try {
55            $validated = $request->validate([
56                'name' => 'required|string|max:255',
57                'email' => 'required|string|email|max:255|unique:users',
58                'password' => 'required|string|min:8|confirmed',
59            ]);
60
61            $user = User::create([
62                'name' => $validated['name'],
63                'email' => $validated['email'],
64                'password' => Hash::make($validated['password']),
65            ]);
66
67            $token = $user->createToken('api-token')->plainTextToken;
68
69            return $this->sendResponse([
70                'user' => [
71                    'id' => $user->id,
72                    'name' => $user->name,
73                    'email' => $user->email,
74                ],
75                'token' => $token,
76                'token_type' => 'Bearer',
77            ], 'Registration successful', 201);
78        } catch (ValidationException $e) {
79            return $this->sendValidationError($e->errors());
80        } catch (\Exception $e) {
81            return $this->sendError('Registration failed: ' . $e->getMessage(), [], 500);
82        }
83    }
84
85    /**
86     * Logout user (revoke token)
87     */
88    public function logout(Request $request): JsonResponse
89    {
90        try {
91            $request->user()->currentAccessToken()->delete();
92
93            return $this->sendResponse(null, 'Logged out successfully');
94        } catch (\Exception $e) {
95            return $this->sendError('Logout failed: ' . $e->getMessage(), [], 500);
96        }
97    }
98
99    /**
100     * Get current authenticated user
101     */
102    public function me(Request $request): JsonResponse
103    {
104        return $this->sendResponse([
105            'user' => [
106                'id' => $request->user()->id,
107                'name' => $request->user()->name,
108                'email' => $request->user()->email,
109            ],
110        ], 'User retrieved successfully');
111    }
112}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:53:46 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-final/Http/Controllers/Api/V1/BaseController.php.html b/backend/coverage-report-final/Http/Controllers/Api/V1/BaseController.php.html deleted file mode 100644 index 0f490941..00000000 --- a/backend/coverage-report-final/Http/Controllers/Api/V1/BaseController.php.html +++ /dev/null @@ -1,307 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Http/Controllers/Api/V1/BaseController.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 87.50% covered (warning) -
-
-
87.50%
14 / 16
-
- 60.00% covered (warning) -
-
-
60.00%
3 / 5
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
BaseController
-
- 87.50% covered (warning) -
-
-
87.50%
14 / 16
-
- 60.00% covered (warning) -
-
-
60.00%
3 / 5
6.07
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 sendResponse
-
- 100.00% covered (success) -
-
-
100.00%
6 / 6
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
1
 sendError
-
- 100.00% covered (success) -
-
-
100.00%
7 / 7
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
2
 sendValidationError
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
1
 sendNotFound
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 sendUnauthorized
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Http\Controllers\Api\V1;
4
5use App\Http\Controllers\Controller;
6use Illuminate\Http\JsonResponse;
7
8class BaseController extends Controller
9{
10    /**
11     * Success response method
12     */
13    public function sendResponse(mixed $result, string $message = 'Success', int $code = 200): JsonResponse
14    {
15        $response = [
16            'success' => true,
17            'data' => $result,
18            'message' => $message,
19        ];
20
21        return response()->json($response, $code);
22    }
23
24    /**
25     * Error response method
26     */
27    public function sendError(string $error, array $errorMessages = [], int $code = 400): JsonResponse
28    {
29        $response = [
30            'success' => false,
31            'message' => $error,
32        ];
33
34        if (!empty($errorMessages)) {
35            $response['errors'] = $errorMessages;
36        }
37
38        return response()->json($response, $code);
39    }
40
41    /**
42     * Validation error response method
43     */
44    public function sendValidationError(array $errors): JsonResponse
45    {
46        return $this->sendError('Validation failed', $errors, 422);
47    }
48
49    /**
50     * Not found response method
51     */
52    public function sendNotFound(string $message = 'Resource not found'): JsonResponse
53    {
54        return $this->sendError($message, [], 404);
55    }
56
57    /**
58     * Unauthorized response method
59     */
60    public function sendUnauthorized(string $message = 'Unauthorized'): JsonResponse
61    {
62        return $this->sendError($message, [], 401);
63    }
64}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:53:46 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-final/Http/Controllers/Api/V1/DashboardController.php.html b/backend/coverage-report-final/Http/Controllers/Api/V1/DashboardController.php.html deleted file mode 100644 index f9dffe67..00000000 --- a/backend/coverage-report-final/Http/Controllers/Api/V1/DashboardController.php.html +++ /dev/null @@ -1,223 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Http/Controllers/Api/V1/DashboardController.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 84.62% covered (warning) -
-
-
84.62%
11 / 13
-
- 50.00% covered (danger) -
-
-
50.00%
1 / 2
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
DashboardController
-
- 84.62% covered (warning) -
-
-
84.62%
11 / 13
-
- 50.00% covered (danger) -
-
-
50.00%
1 / 2
3.03
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 __construct
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
1
 stats
-
- 83.33% covered (warning) -
-
-
83.33%
10 / 12
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2.02
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Http\Controllers\Api\V1;
4
5use App\Models\Article;
6use App\Models\Feed;
7use App\Models\PlatformAccount;
8use App\Models\PlatformChannel;
9use App\Services\DashboardStatsService;
10use Illuminate\Http\JsonResponse;
11use Illuminate\Http\Request;
12
13class DashboardController extends BaseController
14{
15    public function __construct(
16        private DashboardStatsService $dashboardStatsService
17    ) {}
18
19    /**
20     * Get dashboard statistics
21     */
22    public function stats(Request $request): JsonResponse
23    {
24        $period = $request->get('period', 'today');
25        
26        try {
27            // Get article stats from service
28            $articleStats = $this->dashboardStatsService->getStats($period);
29            
30            // Get system stats
31            $systemStats = $this->dashboardStatsService->getSystemStats();
32            
33            // Get available periods
34            $availablePeriods = $this->dashboardStatsService->getAvailablePeriods();
35            
36            return $this->sendResponse([
37                'article_stats' => $articleStats,
38                'system_stats' => $systemStats,
39                'available_periods' => $availablePeriods,
40                'current_period' => $period,
41            ]);
42        } catch (\Exception $e) {
43            return $this->sendError('Failed to fetch dashboard stats: ' . $e->getMessage(), [], 500);
44        }
45    }
46}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:53:46 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-final/Http/Controllers/Api/V1/FeedsController.php.html b/backend/coverage-report-final/Http/Controllers/Api/V1/FeedsController.php.html deleted file mode 100644 index f5680f8a..00000000 --- a/backend/coverage-report-final/Http/Controllers/Api/V1/FeedsController.php.html +++ /dev/null @@ -1,387 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Http/Controllers/Api/V1/FeedsController.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 76.00% covered (warning) -
-
-
76.00%
38 / 50
-
- 33.33% covered (danger) -
-
-
33.33%
2 / 6
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
FeedsController
-
- 76.00% covered (warning) -
-
-
76.00%
38 / 50
-
- 33.33% covered (danger) -
-
-
33.33%
2 / 6
15.34
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 index
-
- 100.00% covered (success) -
-
-
100.00%
7 / 7
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
1
 store
-
- 66.67% covered (warning) -
-
-
66.67%
8 / 12
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
3.33
 show
-
- 100.00% covered (success) -
-
-
100.00%
4 / 4
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
1
 update
-
- 63.64% covered (warning) -
-
-
63.64%
7 / 11
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
3.43
 destroy
-
- 71.43% covered (warning) -
-
-
71.43%
5 / 7
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2.09
 toggle
-
- 77.78% covered (warning) -
-
-
77.78%
7 / 9
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
3.10
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Http\Controllers\Api\V1;
4
5use App\Http\Requests\StoreFeedRequest;
6use App\Http\Requests\UpdateFeedRequest;
7use App\Http\Resources\FeedResource;
8use App\Models\Feed;
9use Illuminate\Http\JsonResponse;
10use Illuminate\Http\Request;
11use Illuminate\Validation\ValidationException;
12
13class FeedsController extends BaseController
14{
15    /**
16     * Display a listing of feeds
17     */
18    public function index(Request $request): JsonResponse
19    {
20        $feeds = Feed::orderBy('is_active', 'desc')
21            ->orderBy('name')
22            ->get();
23
24        return $this->sendResponse(
25            FeedResource::collection($feeds),
26            'Feeds retrieved successfully.'
27        );
28    }
29
30    /**
31     * Store a newly created feed
32     */
33    public function store(StoreFeedRequest $request): JsonResponse
34    {
35        try {
36            $validated = $request->validated();
37            $validated['is_active'] = $validated['is_active'] ?? true;
38
39            $feed = Feed::create($validated);
40
41            return $this->sendResponse(
42                new FeedResource($feed),
43                'Feed created successfully!',
44                201
45            );
46        } catch (ValidationException $e) {
47            return $this->sendValidationError($e->errors());
48        } catch (\Exception $e) {
49            return $this->sendError('Failed to create feed: ' . $e->getMessage(), [], 500);
50        }
51    }
52
53    /**
54     * Display the specified feed
55     */
56    public function show(Feed $feed): JsonResponse
57    {
58        return $this->sendResponse(
59            new FeedResource($feed),
60            'Feed retrieved successfully.'
61        );
62    }
63
64    /**
65     * Update the specified feed
66     */
67    public function update(UpdateFeedRequest $request, Feed $feed): JsonResponse
68    {
69        try {
70            $validated = $request->validated();
71            $validated['is_active'] = $validated['is_active'] ?? $feed->is_active;
72
73            $feed->update($validated);
74
75            return $this->sendResponse(
76                new FeedResource($feed->fresh()),
77                'Feed updated successfully!'
78            );
79        } catch (ValidationException $e) {
80            return $this->sendValidationError($e->errors());
81        } catch (\Exception $e) {
82            return $this->sendError('Failed to update feed: ' . $e->getMessage(), [], 500);
83        }
84    }
85
86    /**
87     * Remove the specified feed
88     */
89    public function destroy(Feed $feed): JsonResponse
90    {
91        try {
92            $feed->delete();
93
94            return $this->sendResponse(
95                null,
96                'Feed deleted successfully!'
97            );
98        } catch (\Exception $e) {
99            return $this->sendError('Failed to delete feed: ' . $e->getMessage(), [], 500);
100        }
101    }
102
103    /**
104     * Toggle feed active status
105     */
106    public function toggle(Feed $feed): JsonResponse
107    {
108        try {
109            $newStatus = !$feed->is_active;
110            $feed->update(['is_active' => $newStatus]);
111
112            $status = $newStatus ? 'activated' : 'deactivated';
113
114            return $this->sendResponse(
115                new FeedResource($feed->fresh()),
116                "Feed {$status} successfully!"
117            );
118        } catch (\Exception $e) {
119            return $this->sendError('Failed to toggle feed status: ' . $e->getMessage(), [], 500);
120        }
121    }
122}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:53:46 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-final/Http/Controllers/Api/V1/LogsController.php.html b/backend/coverage-report-final/Http/Controllers/Api/V1/LogsController.php.html deleted file mode 100644 index 5f7b0bbc..00000000 --- a/backend/coverage-report-final/Http/Controllers/Api/V1/LogsController.php.html +++ /dev/null @@ -1,198 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Http/Controllers/Api/V1/LogsController.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 19
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
LogsController
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 19
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
12
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 index
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 19
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
12
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Http\Controllers\Api\V1;
4
5use App\Models\Log;
6use Illuminate\Http\JsonResponse;
7use Illuminate\Http\Request;
8
9class LogsController extends BaseController
10{
11    /**
12     * Display a listing of logs
13     */
14    public function index(Request $request): JsonResponse
15    {
16        try {
17            $perPage = min($request->get('per_page', 20), 100);
18            $level = $request->get('level');
19            
20            $query = Log::orderBy('created_at', 'desc');
21            
22            if ($level) {
23                $query->where('level', $level);
24            }
25            
26            $logs = $query->paginate($perPage);
27
28            return $this->sendResponse([
29                'logs' => $logs->items(),
30                'pagination' => [
31                    'current_page' => $logs->currentPage(),
32                    'last_page' => $logs->lastPage(),
33                    'per_page' => $logs->perPage(),
34                    'total' => $logs->total(),
35                    'from' => $logs->firstItem(),
36                    'to' => $logs->lastItem(),
37                ],
38            ], 'Logs retrieved successfully.');
39        } catch (\Exception $e) {
40            return $this->sendError('Failed to retrieve logs: ' . $e->getMessage(), [], 500);
41        }
42    }
43}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:53:46 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-final/Http/Controllers/Api/V1/PlatformAccountsController.php.html b/backend/coverage-report-final/Http/Controllers/Api/V1/PlatformAccountsController.php.html deleted file mode 100644 index 369fdca5..00000000 --- a/backend/coverage-report-final/Http/Controllers/Api/V1/PlatformAccountsController.php.html +++ /dev/null @@ -1,417 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Http/Controllers/Api/V1/PlatformAccountsController.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 73
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 6
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
PlatformAccountsController
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 73
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 6
210
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 index
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 8
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 store
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 30
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
20
 show
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 4
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 update
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 17
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
20
 destroy
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 7
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
6
 setActive
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 7
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
6
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Http\Controllers\Api\V1;
4
5use App\Enums\PlatformEnum;
6use App\Http\Resources\PlatformAccountResource;
7use App\Models\PlatformAccount;
8use App\Models\PlatformInstance;
9use Illuminate\Http\JsonResponse;
10use Illuminate\Http\Request;
11use Illuminate\Validation\ValidationException;
12
13class PlatformAccountsController extends BaseController
14{
15    /**
16     * Display a listing of platform accounts
17     */
18    public function index(): JsonResponse
19    {
20        $accounts = PlatformAccount::with(['platformInstance'])
21            ->orderBy('platform')
22            ->orderBy('created_at', 'desc')
23            ->get();
24
25        return $this->sendResponse(
26            PlatformAccountResource::collection($accounts),
27            'Platform accounts retrieved successfully.'
28        );
29    }
30
31    /**
32     * Store a newly created platform account
33     */
34    public function store(Request $request): JsonResponse
35    {
36        try {
37            $validated = $request->validate([
38                'platform' => 'required|in:lemmy,mastodon,reddit',
39                'instance_url' => 'required|url',
40                'username' => 'required|string|max:255',
41                'password' => 'required|string',
42                'settings' => 'nullable|array',
43            ]);
44
45            // Create or find platform instance
46            $platformEnum = PlatformEnum::from($validated['platform']);
47            $instance = PlatformInstance::firstOrCreate([
48                'platform' => $platformEnum,
49                'url' => $validated['instance_url'],
50            ], [
51                'name' => parse_url($validated['instance_url'], PHP_URL_HOST),
52                'description' => ucfirst($validated['platform']) . ' instance',
53                'is_active' => true,
54            ]);
55
56            $account = PlatformAccount::create($validated);
57
58            // If this is the first account for this platform, make it active
59            if (!PlatformAccount::where('platform', $validated['platform'])
60                ->where('is_active', true)
61                ->exists()) {
62                $account->setAsActive();
63            }
64
65            return $this->sendResponse(
66                new PlatformAccountResource($account->load('platformInstance')),
67                'Platform account created successfully!',
68                201
69            );
70        } catch (ValidationException $e) {
71            return $this->sendValidationError($e->errors());
72        } catch (\Exception $e) {
73            return $this->sendError('Failed to create platform account: ' . $e->getMessage(), [], 500);
74        }
75    }
76
77    /**
78     * Display the specified platform account
79     */
80    public function show(PlatformAccount $platformAccount): JsonResponse
81    {
82        return $this->sendResponse(
83            new PlatformAccountResource($platformAccount->load('platformInstance')),
84            'Platform account retrieved successfully.'
85        );
86    }
87
88    /**
89     * Update the specified platform account
90     */
91    public function update(Request $request, PlatformAccount $platformAccount): JsonResponse
92    {
93        try {
94            $validated = $request->validate([
95                'instance_url' => 'required|url',
96                'username' => 'required|string|max:255',
97                'password' => 'nullable|string',
98                'settings' => 'nullable|array',
99            ]);
100
101            // Don't update password if not provided
102            if (empty($validated['password'])) {
103                unset($validated['password']);
104            }
105
106            $platformAccount->update($validated);
107
108            return $this->sendResponse(
109                new PlatformAccountResource($platformAccount->fresh(['platformInstance'])),
110                'Platform account updated successfully!'
111            );
112        } catch (ValidationException $e) {
113            return $this->sendValidationError($e->errors());
114        } catch (\Exception $e) {
115            return $this->sendError('Failed to update platform account: ' . $e->getMessage(), [], 500);
116        }
117    }
118
119    /**
120     * Remove the specified platform account
121     */
122    public function destroy(PlatformAccount $platformAccount): JsonResponse
123    {
124        try {
125            $platformAccount->delete();
126
127            return $this->sendResponse(
128                null,
129                'Platform account deleted successfully!'
130            );
131        } catch (\Exception $e) {
132            return $this->sendError('Failed to delete platform account: ' . $e->getMessage(), [], 500);
133        }
134    }
135
136    /**
137     * Set platform account as active
138     */
139    public function setActive(PlatformAccount $platformAccount): JsonResponse
140    {
141        try {
142            $platformAccount->setAsActive();
143
144            return $this->sendResponse(
145                new PlatformAccountResource($platformAccount->fresh(['platformInstance'])),
146                "Set {$platformAccount->username}@{$platformAccount->instance_url} as active for {$platformAccount->platform->value}!"
147            );
148        } catch (\Exception $e) {
149            return $this->sendError('Failed to set platform account as active: ' . $e->getMessage(), [], 500);
150        }
151    }
152}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:53:46 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-final/Http/Controllers/Api/V1/PlatformChannelsController.php.html b/backend/coverage-report-final/Http/Controllers/Api/V1/PlatformChannelsController.php.html deleted file mode 100644 index 3bb08e90..00000000 --- a/backend/coverage-report-final/Http/Controllers/Api/V1/PlatformChannelsController.php.html +++ /dev/null @@ -1,398 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Http/Controllers/Api/V1/PlatformChannelsController.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 62
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 6
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
PlatformChannelsController
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 62
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 6
182
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 index
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 8
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 store
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 19
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
12
 show
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 4
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 update
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 15
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
12
 destroy
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 7
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
6
 toggle
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 9
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
12
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Http\Controllers\Api\V1;
4
5use App\Http\Resources\PlatformChannelResource;
6use App\Models\PlatformChannel;
7use Illuminate\Http\JsonResponse;
8use Illuminate\Http\Request;
9use Illuminate\Validation\ValidationException;
10
11class PlatformChannelsController extends BaseController
12{
13    /**
14     * Display a listing of platform channels
15     */
16    public function index(): JsonResponse
17    {
18        $channels = PlatformChannel::with(['platformInstance'])
19            ->orderBy('is_active', 'desc')
20            ->orderBy('name')
21            ->get();
22
23        return $this->sendResponse(
24            PlatformChannelResource::collection($channels),
25            'Platform channels retrieved successfully.'
26        );
27    }
28
29    /**
30     * Store a newly created platform channel
31     */
32    public function store(Request $request): JsonResponse
33    {
34        try {
35            $validated = $request->validate([
36                'platform_instance_id' => 'required|exists:platform_instances,id',
37                'channel_id' => 'required|string|max:255',
38                'name' => 'required|string|max:255',
39                'display_name' => 'nullable|string|max:255',
40                'description' => 'nullable|string',
41                'is_active' => 'boolean',
42            ]);
43
44            $validated['is_active'] = $validated['is_active'] ?? true;
45
46            $channel = PlatformChannel::create($validated);
47
48            return $this->sendResponse(
49                new PlatformChannelResource($channel->load('platformInstance')),
50                'Platform channel created successfully!',
51                201
52            );
53        } catch (ValidationException $e) {
54            return $this->sendValidationError($e->errors());
55        } catch (\Exception $e) {
56            return $this->sendError('Failed to create platform channel: ' . $e->getMessage(), [], 500);
57        }
58    }
59
60    /**
61     * Display the specified platform channel
62     */
63    public function show(PlatformChannel $channel): JsonResponse
64    {
65        return $this->sendResponse(
66            new PlatformChannelResource($channel->load('platformInstance')),
67            'Platform channel retrieved successfully.'
68        );
69    }
70
71    /**
72     * Update the specified platform channel
73     */
74    public function update(Request $request, PlatformChannel $channel): JsonResponse
75    {
76        try {
77            $validated = $request->validate([
78                'name' => 'required|string|max:255',
79                'display_name' => 'nullable|string|max:255',
80                'description' => 'nullable|string',
81                'is_active' => 'boolean',
82            ]);
83
84            $channel->update($validated);
85
86            return $this->sendResponse(
87                new PlatformChannelResource($channel->fresh(['platformInstance'])),
88                'Platform channel updated successfully!'
89            );
90        } catch (ValidationException $e) {
91            return $this->sendValidationError($e->errors());
92        } catch (\Exception $e) {
93            return $this->sendError('Failed to update platform channel: ' . $e->getMessage(), [], 500);
94        }
95    }
96
97    /**
98     * Remove the specified platform channel
99     */
100    public function destroy(PlatformChannel $channel): JsonResponse
101    {
102        try {
103            $channel->delete();
104
105            return $this->sendResponse(
106                null,
107                'Platform channel deleted successfully!'
108            );
109        } catch (\Exception $e) {
110            return $this->sendError('Failed to delete platform channel: ' . $e->getMessage(), [], 500);
111        }
112    }
113
114    /**
115     * Toggle platform channel active status
116     */
117    public function toggle(PlatformChannel $channel): JsonResponse
118    {
119        try {
120            $newStatus = !$channel->is_active;
121            $channel->update(['is_active' => $newStatus]);
122
123            $status = $newStatus ? 'activated' : 'deactivated';
124
125            return $this->sendResponse(
126                new PlatformChannelResource($channel->fresh(['platformInstance'])),
127                "Platform channel {$status} successfully!"
128            );
129        } catch (\Exception $e) {
130            return $this->sendError('Failed to toggle platform channel status: ' . $e->getMessage(), [], 500);
131        }
132    }
133}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:53:46 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-final/Http/Controllers/Api/V1/RoutingController.php.html b/backend/coverage-report-final/Http/Controllers/Api/V1/RoutingController.php.html deleted file mode 100644 index 9b5ce6f5..00000000 --- a/backend/coverage-report-final/Http/Controllers/Api/V1/RoutingController.php.html +++ /dev/null @@ -1,430 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Http/Controllers/Api/V1/RoutingController.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 80
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 6
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
RoutingController
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 80
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 6
306
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 index
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 8
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 store
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 18
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
12
 show
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 10
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
6
 update
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 18
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
20
 destroy
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 12
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
12
 toggle
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 14
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
20
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Http\Controllers\Api\V1;
4
5use App\Http\Resources\RouteResource;
6use App\Models\Feed;
7use App\Models\PlatformChannel;
8use App\Models\Route;
9use Illuminate\Http\JsonResponse;
10use Illuminate\Http\Request;
11use Illuminate\Validation\ValidationException;
12
13class RoutingController extends BaseController
14{
15    /**
16     * Display a listing of routing configurations
17     */
18    public function index(): JsonResponse
19    {
20        $routes = Route::with(['feed', 'platformChannel'])
21            ->orderBy('is_active', 'desc')
22            ->orderBy('priority', 'asc')
23            ->get();
24
25        return $this->sendResponse(
26            RouteResource::collection($routes),
27            'Routing configurations retrieved successfully.'
28        );
29    }
30
31    /**
32     * Store a newly created routing configuration
33     */
34    public function store(Request $request): JsonResponse
35    {
36        try {
37            $validated = $request->validate([
38                'feed_id' => 'required|exists:feeds,id',
39                'platform_channel_id' => 'required|exists:platform_channels,id',
40                'is_active' => 'boolean',
41                'priority' => 'nullable|integer|min:0',
42            ]);
43
44            $validated['is_active'] = $validated['is_active'] ?? true;
45            $validated['priority'] = $validated['priority'] ?? 0;
46
47            $route = Route::create($validated);
48
49            return $this->sendResponse(
50                new RouteResource($route->load(['feed', 'platformChannel'])),
51                'Routing configuration created successfully!',
52                201
53            );
54        } catch (ValidationException $e) {
55            return $this->sendValidationError($e->errors());
56        } catch (\Exception $e) {
57            return $this->sendError('Failed to create routing configuration: ' . $e->getMessage(), [], 500);
58        }
59    }
60
61    /**
62     * Display the specified routing configuration
63     */
64    public function show(Feed $feed, PlatformChannel $channel): JsonResponse
65    {
66        $route = Route::where('feed_id', $feed->id)
67            ->where('platform_channel_id', $channel->id)
68            ->with(['feed', 'platformChannel'])
69            ->first();
70
71        if (!$route) {
72            return $this->sendNotFound('Routing configuration not found.');
73        }
74
75        return $this->sendResponse(
76            new RouteResource($route),
77            'Routing configuration retrieved successfully.'
78        );
79    }
80
81    /**
82     * Update the specified routing configuration
83     */
84    public function update(Request $request, Feed $feed, PlatformChannel $channel): JsonResponse
85    {
86        try {
87            $route = Route::where('feed_id', $feed->id)
88                ->where('platform_channel_id', $channel->id)
89                ->first();
90
91            if (!$route) {
92                return $this->sendNotFound('Routing configuration not found.');
93            }
94
95            $validated = $request->validate([
96                'is_active' => 'boolean',
97                'priority' => 'nullable|integer|min:0',
98            ]);
99
100            $route->update($validated);
101
102            return $this->sendResponse(
103                new RouteResource($route->fresh(['feed', 'platformChannel'])),
104                'Routing configuration updated successfully!'
105            );
106        } catch (ValidationException $e) {
107            return $this->sendValidationError($e->errors());
108        } catch (\Exception $e) {
109            return $this->sendError('Failed to update routing configuration: ' . $e->getMessage(), [], 500);
110        }
111    }
112
113    /**
114     * Remove the specified routing configuration
115     */
116    public function destroy(Feed $feed, PlatformChannel $channel): JsonResponse
117    {
118        try {
119            $route = Route::where('feed_id', $feed->id)
120                ->where('platform_channel_id', $channel->id)
121                ->first();
122
123            if (!$route) {
124                return $this->sendNotFound('Routing configuration not found.');
125            }
126
127            $route->delete();
128
129            return $this->sendResponse(
130                null,
131                'Routing configuration deleted successfully!'
132            );
133        } catch (\Exception $e) {
134            return $this->sendError('Failed to delete routing configuration: ' . $e->getMessage(), [], 500);
135        }
136    }
137
138    /**
139     * Toggle routing configuration active status
140     */
141    public function toggle(Feed $feed, PlatformChannel $channel): JsonResponse
142    {
143        try {
144            $route = Route::where('feed_id', $feed->id)
145                ->where('platform_channel_id', $channel->id)
146                ->first();
147
148            if (!$route) {
149                return $this->sendNotFound('Routing configuration not found.');
150            }
151
152            $newStatus = !$route->is_active;
153            $route->update(['is_active' => $newStatus]);
154
155            $status = $newStatus ? 'activated' : 'deactivated';
156
157            return $this->sendResponse(
158                new RouteResource($route->fresh(['feed', 'platformChannel'])),
159                "Routing configuration {$status} successfully!"
160            );
161        } catch (\Exception $e) {
162            return $this->sendError('Failed to toggle routing configuration status: ' . $e->getMessage(), [], 500);
163        }
164    }
165}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:53:46 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-final/Http/Controllers/Api/V1/SettingsController.php.html b/backend/coverage-report-final/Http/Controllers/Api/V1/SettingsController.php.html deleted file mode 100644 index b4b968ea..00000000 --- a/backend/coverage-report-final/Http/Controllers/Api/V1/SettingsController.php.html +++ /dev/null @@ -1,240 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Http/Controllers/Api/V1/SettingsController.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 85.19% covered (warning) -
-
-
85.19%
23 / 27
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
SettingsController
-
- 85.19% covered (warning) -
-
-
85.19%
23 / 27
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
7.16
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 index
-
- 71.43% covered (warning) -
-
-
71.43%
5 / 7
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2.09
 update
-
- 90.00% covered (success) -
-
-
90.00%
18 / 20
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
5.03
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Http\Controllers\Api\V1;
4
5use App\Models\Setting;
6use Illuminate\Http\JsonResponse;
7use Illuminate\Http\Request;
8use Illuminate\Validation\ValidationException;
9
10class SettingsController extends BaseController
11{
12    /**
13     * Display current settings
14     */
15    public function index(): JsonResponse
16    {
17        try {
18            $settings = [
19                'article_processing_enabled' => Setting::isArticleProcessingEnabled(),
20                'publishing_approvals_enabled' => Setting::isPublishingApprovalsEnabled(),
21            ];
22
23            return $this->sendResponse($settings, 'Settings retrieved successfully.');
24        } catch (\Exception $e) {
25            return $this->sendError('Failed to retrieve settings: ' . $e->getMessage(), [], 500);
26        }
27    }
28
29    /**
30     * Update settings
31     */
32    public function update(Request $request): JsonResponse
33    {
34        try {
35            $validated = $request->validate([
36                'article_processing_enabled' => 'boolean',
37                'enable_publishing_approvals' => 'boolean',
38            ]);
39
40            if (isset($validated['article_processing_enabled'])) {
41                Setting::setArticleProcessingEnabled($validated['article_processing_enabled']);
42            }
43
44            if (isset($validated['enable_publishing_approvals'])) {
45                Setting::setPublishingApprovalsEnabled($validated['enable_publishing_approvals']);
46            }
47
48            $updatedSettings = [
49                'article_processing_enabled' => Setting::isArticleProcessingEnabled(),
50                'publishing_approvals_enabled' => Setting::isPublishingApprovalsEnabled(),
51            ];
52
53            return $this->sendResponse(
54                $updatedSettings,
55                'Settings updated successfully.'
56            );
57        } catch (ValidationException $e) {
58            return $this->sendValidationError($e->errors());
59        } catch (\Exception $e) {
60            return $this->sendError('Failed to update settings: ' . $e->getMessage(), [], 500);
61        }
62    }
63}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:53:46 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-final/Http/Controllers/Api/V1/dashboard.html b/backend/coverage-report-final/Http/Controllers/Api/V1/dashboard.html deleted file mode 100644 index 420a8709..00000000 --- a/backend/coverage-report-final/Http/Controllers/Api/V1/dashboard.html +++ /dev/null @@ -1,365 +0,0 @@ - - - - - Dashboard for /var/www/html/backend/app/Http/Controllers/Api/V1 - - - - - - - -
-
-
-
- -
-
-
-
-
-
-
-

Classes

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
- -
-
-

Methods

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
-
-
-

Insufficient Coverage

-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
MethodCoverage
login0%
register0%
logout0%
me0%
sendNotFound0%
sendUnauthorized0%
index0%
index0%
store0%
show0%
update0%
destroy0%
setActive0%
index0%
store0%
show0%
update0%
destroy0%
toggle0%
index0%
store0%
show0%
update0%
destroy0%
toggle0%
update63%
store66%
approve71%
reject71%
destroy71%
index71%
toggle77%
stats83%
-
-
-
-

Project Risks

-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
MethodCRAP
login30
store20
update20
update20
toggle20
register12
index12
store12
update12
toggle12
store12
destroy12
logout6
destroy6
setActive6
destroy6
show6
update3
store3
toggle3
approve2
reject2
destroy2
index2
stats2
-
-
-
- -
- - - - - - diff --git a/backend/coverage-report-final/Http/Controllers/Api/V1/index.html b/backend/coverage-report-final/Http/Controllers/Api/V1/index.html deleted file mode 100644 index 916b0ce2..00000000 --- a/backend/coverage-report-final/Http/Controllers/Api/V1/index.html +++ /dev/null @@ -1,374 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Http/Controllers/Api/V1 - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 26.81% covered (danger) -
-
-
26.81%
115 / 429
-
- 17.07% covered (danger) -
-
-
17.07%
7 / 41
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 10
ArticlesController.php
-
- 87.88% covered (warning) -
-
-
87.88%
29 / 33
-
- 33.33% covered (danger) -
-
-
33.33%
1 / 3
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
AuthController.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 56
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 4
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
BaseController.php
-
- 87.50% covered (warning) -
-
-
87.50%
14 / 16
-
- 60.00% covered (warning) -
-
-
60.00%
3 / 5
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
DashboardController.php
-
- 84.62% covered (warning) -
-
-
84.62%
11 / 13
-
- 50.00% covered (danger) -
-
-
50.00%
1 / 2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
FeedsController.php
-
- 76.00% covered (warning) -
-
-
76.00%
38 / 50
-
- 33.33% covered (danger) -
-
-
33.33%
2 / 6
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
LogsController.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 19
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
PlatformAccountsController.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 73
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 6
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
PlatformChannelsController.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 62
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 6
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
RoutingController.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 80
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 6
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
SettingsController.php
-
- 85.19% covered (warning) -
-
-
85.19%
23 / 27
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- -
- - diff --git a/backend/coverage-report-final/Http/Controllers/Api/dashboard.html b/backend/coverage-report-final/Http/Controllers/Api/dashboard.html deleted file mode 100644 index 3ccc2103..00000000 --- a/backend/coverage-report-final/Http/Controllers/Api/dashboard.html +++ /dev/null @@ -1,364 +0,0 @@ - - - - - Dashboard for /var/www/html/backend/app/Http/Controllers/Api - - - - - - - -
-
-
-
- -
-
-
-
-
-
-
-

Classes

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
- -
-
-

Methods

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
-
-
-

Insufficient Coverage

-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
MethodCoverage
login0%
register0%
logout0%
me0%
sendNotFound0%
sendUnauthorized0%
index0%
index0%
store0%
show0%
update0%
destroy0%
setActive0%
index0%
store0%
show0%
update0%
destroy0%
toggle0%
index0%
store0%
show0%
update0%
destroy0%
toggle0%
update63%
store66%
approve71%
reject71%
destroy71%
index71%
toggle77%
stats83%
-
-
-
-

Project Risks

-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
MethodCRAP
login30
store20
update20
update20
toggle20
register12
index12
store12
update12
toggle12
store12
destroy12
logout6
destroy6
setActive6
destroy6
show6
update3
store3
toggle3
approve2
reject2
destroy2
index2
stats2
-
-
-
- -
- - - - - - diff --git a/backend/coverage-report-final/Http/Controllers/Api/index.html b/backend/coverage-report-final/Http/Controllers/Api/index.html deleted file mode 100644 index c4b76476..00000000 --- a/backend/coverage-report-final/Http/Controllers/Api/index.html +++ /dev/null @@ -1,121 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Http/Controllers/Api - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 26.81% covered (danger) -
-
-
26.81%
115 / 429
-
- 17.07% covered (danger) -
-
-
17.07%
7 / 41
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 10
V1
-
- 26.81% covered (danger) -
-
-
26.81%
115 / 429
-
- 17.07% covered (danger) -
-
-
17.07%
7 / 41
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 10
-
- -
- - diff --git a/backend/coverage-report-final/Http/Controllers/ArticlesController.php.html b/backend/coverage-report-final/Http/Controllers/ArticlesController.php.html deleted file mode 100644 index d142dae5..00000000 --- a/backend/coverage-report-final/Http/Controllers/ArticlesController.php.html +++ /dev/null @@ -1,234 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Http/Controllers/ArticlesController.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 9
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
ArticlesController
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 9
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
12
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 __invoke
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 5
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 approve
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 reject
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Http\Controllers;
4
5use App\Models\Article;
6use App\Models\Setting;
7use Illuminate\Contracts\View\View;
8use Illuminate\Http\RedirectResponse;
9use Illuminate\Http\Request;
10
11class ArticlesController extends Controller
12{
13    public function __invoke(Request $request): View
14    {
15        $articles = Article::with('articlePublication')
16            ->orderBy('created_at', 'desc')
17            ->paginate(15);
18
19        $publishingApprovalsEnabled = Setting::isPublishingApprovalsEnabled();
20
21        return view('pages.articles.index', compact('articles', 'publishingApprovalsEnabled'));
22    }
23
24    public function approve(Article $article): RedirectResponse
25    {
26        $article->approve('manual');
27
28        return redirect()->back()->with('success', 'Article approved and queued for publishing.');
29    }
30
31    public function reject(Article $article): RedirectResponse
32    {
33        $article->reject('manual');
34
35        return redirect()->back()->with('success', 'Article rejected.');
36    }
37}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:53:46 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-final/Http/Controllers/Controller.php.html b/backend/coverage-report-final/Http/Controllers/Controller.php.html deleted file mode 100644 index 2c0ddf6f..00000000 --- a/backend/coverage-report-final/Http/Controllers/Controller.php.html +++ /dev/null @@ -1,109 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Http/Controllers/Controller.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
n/a
0 / 0
n/a
0 / 0
CRAP
n/a
0 / 0
Controller
n/a
0 / 0
n/a
0 / 0
0
n/a
0 / 0
-
- - - - - - - - - - - - -
1<?php
2
3namespace App\Http\Controllers;
4
5abstract class Controller
6{
7    //
8}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:53:46 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-final/Http/Controllers/FeedsController.php.html b/backend/coverage-report-final/Http/Controllers/FeedsController.php.html deleted file mode 100644 index 9c9cfd95..00000000 --- a/backend/coverage-report-final/Http/Controllers/FeedsController.php.html +++ /dev/null @@ -1,388 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Http/Controllers/FeedsController.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 28
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 8
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
FeedsController
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 28
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 8
90
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 index
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 4
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 create
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 store
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 8
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 show
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 edit
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 update
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 5
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 destroy
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 toggle
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 5
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
6
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Http\Controllers;
4
5use App\Models\Feed;
6use App\Http\Requests\StoreFeedRequest;
7use App\Http\Requests\UpdateFeedRequest;
8use App\Services\OnboardingRedirectService;
9use Illuminate\Contracts\View\View;
10use Illuminate\Http\RedirectResponse;
11
12class FeedsController extends Controller
13{
14    public function index(): View
15    {
16        $feeds = Feed::orderBy('is_active', 'desc')
17            ->orderBy('name')
18            ->get();
19
20        return view('pages.feeds.index', compact('feeds'));
21    }
22
23    public function create(): View
24    {
25        return view('pages.feeds.create');
26    }
27
28    public function store(StoreFeedRequest $request): RedirectResponse
29    {
30        $validated = $request->validated();
31        $validated['is_active'] = $validated['is_active'] ?? true;
32
33        Feed::create($validated);
34
35        return OnboardingRedirectService::handleRedirect(
36            $request,
37            'feeds.index',
38            'Feed created successfully!'
39        );
40    }
41
42    public function show(Feed $feed): View
43    {
44        return view('pages.feeds.show', compact('feed'));
45    }
46
47    public function edit(Feed $feed): View
48    {
49        return view('pages.feeds.edit', compact('feed'));
50    }
51
52    public function update(UpdateFeedRequest $request, Feed $feed): RedirectResponse
53    {
54        $validated = $request->validated();
55        $validated['is_active'] = $validated['is_active'] ?? $feed->is_active;
56
57        $feed->update($validated);
58
59        return redirect()->route('feeds.index')
60            ->with('success', 'Feed updated successfully!');
61    }
62
63    public function destroy(Feed $feed): RedirectResponse
64    {
65        $feed->delete();
66
67        return redirect()->route('feeds.index')
68            ->with('success', 'Feed deleted successfully!');
69    }
70
71    public function toggle(Feed $feed): RedirectResponse
72    {
73        $newStatus = !$feed->is_active;
74        $feed->update(['is_active' => $newStatus]);
75
76        $status = $newStatus ? 'activated' : 'deactivated';
77
78        return redirect()->route('feeds.index')
79            ->with('success', "Feed {$status} successfully!");
80    }
81}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:53:46 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-final/Http/Controllers/LogsController.php.html b/backend/coverage-report-final/Http/Controllers/LogsController.php.html deleted file mode 100644 index 69f4c2e4..00000000 --- a/backend/coverage-report-final/Http/Controllers/LogsController.php.html +++ /dev/null @@ -1,170 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Http/Controllers/LogsController.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
LogsController
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 __invoke
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Http\Controllers;
4
5use App\Models\Log;
6use Illuminate\Contracts\View\View;
7use Illuminate\Http\Request;
8
9class LogsController extends Controller
10{
11    public function __invoke(Request $request): View
12    {
13        $logs = Log::orderBy('created_at', 'desc')->paginate(50);
14
15        return view('pages.logs.index', compact('logs'));
16    }
17}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:53:46 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-final/Http/Controllers/OnboardingController.php.html b/backend/coverage-report-final/Http/Controllers/OnboardingController.php.html deleted file mode 100644 index 4d8745b5..00000000 --- a/backend/coverage-report-final/Http/Controllers/OnboardingController.php.html +++ /dev/null @@ -1,443 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Http/Controllers/OnboardingController.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 40
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 9
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
OnboardingController
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 40
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 9
506
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 index
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 15
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
6
 platform
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
6
 feed
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 5
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
12
 channel
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 7
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
20
 complete
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 6
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
30
 needsOnboarding
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
12
 hasPlatformAccount
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 hasFeed
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 hasChannel
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Http\Controllers;
4
5use App\Models\Feed;
6use App\Models\PlatformAccount;
7use App\Models\PlatformChannel;
8use App\Models\PlatformInstance;
9use App\Services\SystemStatusService;
10use App\Services\DashboardStatsService;
11use Illuminate\Http\Request;
12use Illuminate\View\View;
13use Illuminate\Http\RedirectResponse;
14
15class OnboardingController extends Controller
16{
17    public function index(Request $request): View|RedirectResponse
18    {
19        // Check if user needs onboarding
20        if (!$this->needsOnboarding()) {
21            $systemStatus = resolve(SystemStatusService::class)->getSystemStatus();
22            $statsService = resolve(DashboardStatsService::class);
23            
24            $period = $request->get('period', 'today');
25            $stats = $statsService->getStats($period);
26            $systemStats = $statsService->getSystemStats();
27            $availablePeriods = $statsService->getAvailablePeriods();
28
29            return view('pages.dashboard', compact(
30                'systemStatus', 
31                'stats', 
32                'systemStats', 
33                'availablePeriods', 
34                'period'
35            ));
36        }
37
38        return view('onboarding.welcome');
39    }
40
41    public function platform(): View|RedirectResponse
42    {
43        if (!$this->needsOnboarding()) {
44            return redirect()->route('feeds.index');
45        }
46
47        return view('onboarding.platform');
48    }
49
50    public function feed(): View|RedirectResponse
51    {
52        if (!$this->needsOnboarding()) {
53            return redirect()->route('feeds.index');
54        }
55
56        if (!$this->hasPlatformAccount()) {
57            return redirect()->route('onboarding.platform');
58        }
59
60        return view('onboarding.feed');
61    }
62
63    public function channel(): View|RedirectResponse
64    {
65        if (!$this->needsOnboarding()) {
66            return redirect()->route('feeds.index');
67        }
68
69        if (!$this->hasPlatformAccount()) {
70            return redirect()->route('onboarding.platform');
71        }
72
73        if (!$this->hasFeed()) {
74            return redirect()->route('onboarding.feed');
75        }
76
77        return view('onboarding.channel');
78    }
79
80    public function complete(): View|RedirectResponse
81    {
82        if (!$this->needsOnboarding()) {
83            return redirect()->route('feeds.index');
84        }
85
86        if (!$this->hasPlatformAccount() || !$this->hasFeed() || !$this->hasChannel()) {
87            return redirect()->route('onboarding.index');
88        }
89
90        $systemStatus = resolve(SystemStatusService::class)->getSystemStatus();
91
92        return view('onboarding.complete', compact('systemStatus'));
93    }
94
95    private function needsOnboarding(): bool
96    {
97        return !$this->hasPlatformAccount() || !$this->hasFeed() || !$this->hasChannel();
98    }
99
100    private function hasPlatformAccount(): bool
101    {
102        return PlatformAccount::where('is_active', true)->exists();
103    }
104
105    private function hasFeed(): bool
106    {
107        return Feed::where('is_active', true)->exists();
108    }
109
110    private function hasChannel(): bool
111    {
112        return PlatformChannel::where('is_active', true)->exists();
113    }
114}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:53:46 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-final/Http/Controllers/PlatformAccountsController.php.html b/backend/coverage-report-final/Http/Controllers/PlatformAccountsController.php.html deleted file mode 100644 index f03f399f..00000000 --- a/backend/coverage-report-final/Http/Controllers/PlatformAccountsController.php.html +++ /dev/null @@ -1,391 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Http/Controllers/PlatformAccountsController.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 46
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 7
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
PlatformAccountsController
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 46
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 7
110
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 index
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 create
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 store
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 25
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
12
 edit
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 update
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 11
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
6
 destroy
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 setActive
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Http\Controllers;
4
5use App\Models\PlatformAccount;
6use App\Models\PlatformInstance;
7use App\Enums\PlatformEnum;
8use Illuminate\Http\Request;
9use Illuminate\Contracts\View\View;
10use Illuminate\Http\RedirectResponse;
11use Illuminate\Support\Facades\View as ViewFacade;
12
13class PlatformAccountsController extends Controller
14{
15    public function index(): View
16    {
17        $accounts = PlatformAccount::orderBy('platform')->orderBy('created_at', 'desc')->get();
18
19        return view('pages.platforms.index', compact('accounts'));
20    }
21
22    public function create(): View
23    {
24        return ViewFacade::make('pages.platforms.create');
25    }
26
27    public function store(Request $request): RedirectResponse
28    {
29        $validated = $request->validate([
30            'platform' => 'required|in:lemmy,mastodon,reddit',
31            'instance_url' => 'required|url',
32            'username' => 'required|string|max:255',
33            'password' => 'required|string',
34            'settings' => 'nullable|array',
35        ]);
36
37        // Create or find platform instance
38        $platformEnum = PlatformEnum::from($validated['platform']);
39        $instance = PlatformInstance::firstOrCreate([
40            'platform' => $platformEnum,
41            'url' => $validated['instance_url'],
42        ], [
43            'name' => parse_url($validated['instance_url'], PHP_URL_HOST),
44            'description' => ucfirst($validated['platform']) . ' instance',
45            'is_active' => true,
46        ]);
47
48        $account = PlatformAccount::create($validated);
49
50        // If this is the first account for this platform, make it active
51        if (! PlatformAccount::where('platform', $validated['platform'])->where('is_active', true)->exists()) {
52            $account->setAsActive();
53        }
54
55        // Check if there's a redirect_to parameter for onboarding flow
56        $redirectTo = $request->input('redirect_to');
57        if ($redirectTo) {
58            return redirect($redirectTo)
59                ->with('success', 'Platform account created successfully!');
60        }
61
62        return redirect()->route('platforms.index')
63            ->with('success', 'Platform account created successfully!');
64    }
65
66    public function edit(PlatformAccount $platformAccount): View
67    {
68        return ViewFacade::make('pages.platforms.edit', compact('platformAccount'));
69    }
70
71    public function update(Request $request, PlatformAccount $platformAccount): RedirectResponse
72    {
73        $validated = $request->validate([
74            'instance_url' => 'required|url',
75            'username' => 'required|string|max:255',
76            'password' => 'nullable|string',
77            'settings' => 'nullable|array',
78        ]);
79
80        // Don't update password if not provided
81        if (empty($validated['password'])) {
82            unset($validated['password']);
83        }
84
85        $platformAccount->update($validated);
86
87        return redirect()->route('platforms.index')
88            ->with('success', 'Platform account updated successfully!');
89    }
90
91    public function destroy(PlatformAccount $platformAccount): RedirectResponse
92    {
93        $platformAccount->delete();
94
95        return redirect()->route('platforms.index')
96            ->with('success', 'Platform account deleted successfully!');
97    }
98
99    public function setActive(PlatformAccount $platformAccount): RedirectResponse
100    {
101        $platformAccount->setAsActive();
102
103        return redirect()->route('platforms.index')
104            ->with('success', "Set $platformAccount->username@$platformAccount->instance_url as active for {$platformAccount->platform->value}!");
105    }
106}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:53:46 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-final/Http/Controllers/PlatformChannelsController.php.html b/backend/coverage-report-final/Http/Controllers/PlatformChannelsController.php.html deleted file mode 100644 index bc3db06b..00000000 --- a/backend/coverage-report-final/Http/Controllers/PlatformChannelsController.php.html +++ /dev/null @@ -1,423 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Http/Controllers/PlatformChannelsController.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 53
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 8
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
PlatformChannelsController
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 53
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 8
110
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 index
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 5
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 create
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 4
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 store
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 18
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
6
 show
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 edit
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 4
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 update
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 12
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 destroy
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 toggle
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 5
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
6
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Http\Controllers;
4
5use App\Models\PlatformChannel;
6use App\Models\PlatformInstance;
7use Illuminate\Http\Request;
8use Illuminate\Contracts\View\View;
9use Illuminate\Http\RedirectResponse;
10use Illuminate\Support\Facades\View as ViewFacade;
11
12class PlatformChannelsController extends Controller
13{
14    public function index(): View
15    {
16        $channels = PlatformChannel::with('platformInstance')
17            ->orderBy('platform_instance_id')
18            ->orderBy('name')
19            ->get();
20        
21        return ViewFacade::make('pages.channels.index', compact('channels'));
22    }
23
24    public function create(): View
25    {
26        $instances = PlatformInstance::where('is_active', true)
27            ->orderBy('name')
28            ->get();
29            
30        return ViewFacade::make('pages.channels.create', compact('instances'));
31    }
32
33    public function store(Request $request): RedirectResponse
34    {
35        $validated = $request->validate([
36            'platform_instance_id' => 'required|exists:platform_instances,id',
37            'name' => 'required|string|max:255',
38            'display_name' => 'nullable|string|max:255',
39            'channel_id' => 'nullable|string|max:255',
40            'description' => 'nullable|string',
41            'language_id' => 'required|exists:languages,id',
42            'is_active' => 'boolean',
43        ]);
44
45        // Default is_active to true if not provided
46        $validated['is_active'] = $validated['is_active'] ?? true;
47        
48        // Set display_name to name if not provided
49        $validated['display_name'] = $validated['display_name'] ?? $validated['name'];
50
51        PlatformChannel::create($validated);
52
53        // Check if there's a redirect_to parameter for onboarding flow
54        $redirectTo = $request->input('redirect_to');
55        if ($redirectTo) {
56            return redirect($redirectTo)
57                ->with('success', 'Channel created successfully!');
58        }
59
60        return redirect()->route('channels.index')
61            ->with('success', 'Channel created successfully!');
62    }
63
64    public function show(PlatformChannel $channel): View
65    {
66        $channel->load(['platformInstance', 'feeds']);
67        
68        return ViewFacade::make('pages.channels.show', compact('channel'));
69    }
70
71    public function edit(PlatformChannel $channel): View
72    {
73        $instances = PlatformInstance::where('is_active', true)
74            ->orderBy('name')
75            ->get();
76            
77        return ViewFacade::make('pages.channels.edit', compact('channel', 'instances'));
78    }
79
80    public function update(Request $request, PlatformChannel $channel): RedirectResponse
81    {
82        $validated = $request->validate([
83            'platform_instance_id' => 'required|exists:platform_instances,id',
84            'name' => 'required|string|max:255',
85            'display_name' => 'nullable|string|max:255',
86            'channel_id' => 'nullable|string|max:255',
87            'description' => 'nullable|string',
88            'language_id' => 'required|exists:languages,id',
89            'is_active' => 'boolean',
90        ]);
91
92        $channel->update($validated);
93
94        return redirect()->route('channels.index')
95            ->with('success', 'Channel updated successfully!');
96    }
97
98    public function destroy(PlatformChannel $channel): RedirectResponse
99    {
100        $channel->delete();
101
102        return redirect()->route('channels.index')
103            ->with('success', 'Channel deleted successfully!');
104    }
105
106    public function toggle(PlatformChannel $channel): RedirectResponse
107    {
108        $newStatus = !$channel->is_active;
109        $channel->update(['is_active' => $newStatus]);
110
111        $status = $newStatus ? 'activated' : 'deactivated';
112
113        return redirect()->route('channels.index')
114            ->with('success', "Channel {$status} successfully!");
115    }
116}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:53:46 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-final/Http/Controllers/RoutingController.php.html b/backend/coverage-report-final/Http/Controllers/RoutingController.php.html deleted file mode 100644 index 240ab32b..00000000 --- a/backend/coverage-report-final/Http/Controllers/RoutingController.php.html +++ /dev/null @@ -1,480 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Http/Controllers/RoutingController.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 87
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 8
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
RoutingController
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 87
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 8
240
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 index
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 9
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 create
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 8
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 store
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 28
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
12
 edit
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 6
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
6
 update
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 14
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 destroy
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 toggle
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 13
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
12
 parseJsonFilters
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 6
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
12
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Http\Controllers;
4
5use App\Models\Feed;
6use App\Models\Route;
7use App\Models\PlatformChannel;
8use App\Services\RoutingValidationService;
9use App\Exceptions\RoutingMismatchException;
10use Illuminate\Database\Eloquent\Collection;
11use Illuminate\Http\Request;
12use Illuminate\Contracts\View\View;
13use Illuminate\Http\RedirectResponse;
14
15class RoutingController extends Controller
16{
17    public function index(): View
18    {
19        $feeds = Feed::with(['channels.platformInstance'])
20            ->where('is_active', true)
21            ->orderBy('name')
22            ->get();
23
24        $channels = PlatformChannel::with(['platformInstance', 'feeds'])
25            ->where('is_active', true)
26            ->orderBy('name')
27            ->get();
28
29        return view('pages.routing.index', compact('feeds', 'channels'));
30    }
31
32    public function create(): View
33    {
34        $feeds = Feed::where('is_active', true)
35            ->orderBy('name')
36            ->get();
37
38        $channels = PlatformChannel::with('platformInstance')
39            ->where('is_active', true)
40            ->orderBy('name')
41            ->get();
42
43        return view('pages.routing.create', compact('feeds', 'channels'));
44    }
45
46    public function store(Request $request): RedirectResponse
47    {
48        $validated = $request->validate([
49            'feed_id' => 'required|exists:feeds,id',
50            'channel_ids' => 'required|array|min:1',
51            'channel_ids.*' => 'exists:platform_channels,id',
52            'priority' => 'integer|min:0|max:100',
53            'filters' => 'nullable|string'
54        ]);
55
56        /** @var Feed $feed */
57        $feed = Feed::findOrFail($validated['feed_id']);
58        
59        /** @var Collection<int, PlatformChannel> $channels */
60        $channels = PlatformChannel::findMany($validated['channel_ids']);
61        $priority = $validated['priority'] ?? 0;
62
63        try {
64            app(RoutingValidationService::class)->validateLanguageCompatibility($feed, $channels);
65        } catch (RoutingMismatchException $e) {
66            return redirect()->back()
67                ->withInput()
68                ->withErrors(['language' => $e->getMessage()]);
69        }
70
71        $filters = $this->parseJsonFilters($validated['filters'] ?? null);
72
73        // Attach channels to feed
74        $syncData = [];
75        foreach ($validated['channel_ids'] as $channelId) {
76            $syncData[$channelId] = [
77                'is_active' => true,
78                'priority' => $priority,
79                'filters' => $filters,
80                'created_at' => now(),
81                'updated_at' => now()
82            ];
83        }
84
85        $feed->channels()->syncWithoutDetaching($syncData);
86
87        return redirect()->route('routing.index')
88            ->with('success', 'Feed routing created successfully!');
89    }
90
91    public function edit(Feed $feed, PlatformChannel $channel): View
92    {
93        $routing = $feed->channels()
94            ->wherePivot('platform_channel_id', $channel->id)
95            ->first();
96
97        if (! $routing) {
98            abort(404, 'Routing not found');
99        }
100
101        return view('pages.routing.edit', compact('feed', 'channel', 'routing'));
102    }
103
104    public function update(Request $request, Feed $feed, PlatformChannel $channel): RedirectResponse
105    {
106        $validated = $request->validate([
107            'is_active' => 'boolean',
108            'priority' => 'integer|min:0|max:100',
109            'filters' => 'nullable|string'
110        ]);
111
112        $filters = $this->parseJsonFilters($validated['filters'] ?? null);
113
114        $feed->channels()->updateExistingPivot($channel->id, [
115            'is_active' => $validated['is_active'] ?? true,
116            'priority' => $validated['priority'] ?? 0,
117            'filters' => $filters,
118            'updated_at' => now()
119        ]);
120
121        return redirect()->route('routing.index')
122            ->with('success', 'Routing updated successfully!');
123    }
124
125    public function destroy(Feed $feed, PlatformChannel $channel): RedirectResponse
126    {
127        $feed->channels()->detach($channel->id);
128
129        return redirect()->route('routing.index')
130            ->with('success', 'Routing deleted successfully!');
131    }
132
133    public function toggle(Request $request, Feed $feed, PlatformChannel $channel): RedirectResponse
134    {
135        $routing = Route::where('feed_id', $feed->id)
136            ->where('platform_channel_id', $channel->id)
137            ->first();
138
139        if (! $routing) {
140            abort(404, 'Routing not found');
141        }
142
143        $newStatus = ! $routing->is_active;
144
145        $feed->channels()->updateExistingPivot($channel->id, [
146            'is_active' => $newStatus,
147            'updated_at' => now()
148        ]);
149
150        $status = $newStatus ? 'activated' : 'deactivated';
151
152        return redirect()->route('routing.index')
153            ->with('success', "Routing {$status} successfully!");
154    }
155
156    /**
157     * @return array<string, mixed>|null
158     */
159    private function parseJsonFilters(?string $json): ?array
160    {
161        if (empty($json)) {
162            return null;
163        }
164
165        $decoded = json_decode($json, true);
166
167        if (json_last_error() === JSON_ERROR_NONE) {
168            return $decoded;
169        }
170
171        return null;
172    }
173}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:53:46 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-final/Http/Controllers/SettingsController.php.html b/backend/coverage-report-final/Http/Controllers/SettingsController.php.html deleted file mode 100644 index eaba1bfb..00000000 --- a/backend/coverage-report-final/Http/Controllers/SettingsController.php.html +++ /dev/null @@ -1,214 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Http/Controllers/SettingsController.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 14
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
SettingsController
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 14
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
12
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 index
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 update
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 11
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
6
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Http\Controllers;
4
5use App\Models\Setting;
6use Illuminate\Contracts\View\View;
7use Illuminate\Http\RedirectResponse;
8use Illuminate\Http\Request;
9
10class SettingsController extends Controller
11{
12    public function index(): View
13    {
14        $articleProcessingEnabled = Setting::isArticleProcessingEnabled();
15        $publishingApprovalsEnabled = Setting::isPublishingApprovalsEnabled();
16        
17        return view('pages.settings.index', compact('articleProcessingEnabled', 'publishingApprovalsEnabled'));
18    }
19
20    public function update(Request $request): RedirectResponse
21    {
22        $request->validate([
23            'article_processing_enabled' => 'boolean',
24            'enable_publishing_approvals' => 'boolean',
25        ]);
26
27        Setting::setArticleProcessingEnabled($request->boolean('article_processing_enabled'));
28        Setting::setPublishingApprovalsEnabled($request->boolean('enable_publishing_approvals'));
29
30        // If redirected from onboarding, go to dashboard
31        if ($request->get('from') === 'onboarding') {
32            return redirect()->route('onboarding.index')
33                ->with('success', 'System activated successfully! Welcome to Lemmy Poster.');
34        }
35
36        return redirect()->route('settings.index')
37            ->with('success', 'Settings updated successfully.');
38    }
39}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:53:46 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-final/Http/Controllers/dashboard.html b/backend/coverage-report-final/Http/Controllers/dashboard.html deleted file mode 100644 index fdb021b4..00000000 --- a/backend/coverage-report-final/Http/Controllers/dashboard.html +++ /dev/null @@ -1,439 +0,0 @@ - - - - - Dashboard for /var/www/html/backend/app/Http/Controllers - - - - - - - -
-
-
-
- -
-
-
-
-
-
-
-

Classes

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
-
- - -
-
-
-

Methods

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
-
-
-

Insufficient Coverage

-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
MethodCoverage
login0%
register0%
logout0%
me0%
sendNotFound0%
sendUnauthorized0%
index0%
index0%
store0%
show0%
update0%
destroy0%
setActive0%
index0%
store0%
show0%
update0%
destroy0%
toggle0%
index0%
store0%
show0%
update0%
destroy0%
toggle0%
__invoke0%
approve0%
reject0%
index0%
create0%
store0%
show0%
edit0%
update0%
destroy0%
toggle0%
__invoke0%
index0%
platform0%
feed0%
channel0%
complete0%
needsOnboarding0%
hasPlatformAccount0%
hasFeed0%
hasChannel0%
index0%
create0%
store0%
edit0%
update0%
destroy0%
setActive0%
index0%
create0%
store0%
show0%
edit0%
update0%
destroy0%
toggle0%
index0%
create0%
store0%
edit0%
update0%
destroy0%
toggle0%
parseJsonFilters0%
index0%
update0%
update63%
store66%
approve71%
reject71%
destroy71%
index71%
toggle77%
stats83%
-
-
-
-

Project Risks

-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
MethodCRAP
login30
complete30
store20
update20
update20
toggle20
channel20
register12
index12
store12
update12
toggle12
store12
destroy12
feed12
needsOnboarding12
store12
store12
toggle12
parseJsonFilters12
logout6
destroy6
setActive6
destroy6
show6
toggle6
index6
platform6
update6
store6
toggle6
edit6
update6
update3
store3
toggle3
approve2
reject2
destroy2
index2
stats2
-
-
-
- -
- - - - - - diff --git a/backend/coverage-report-final/Http/Controllers/index.html b/backend/coverage-report-final/Http/Controllers/index.html deleted file mode 100644 index 5eb97aec..00000000 --- a/backend/coverage-report-final/Http/Controllers/index.html +++ /dev/null @@ -1,357 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Http/Controllers - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 16.24% covered (danger) -
-
-
16.24%
115 / 708
-
- 8.05% covered (danger) -
-
-
8.05%
7 / 87
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 18
Api
-
- 26.81% covered (danger) -
-
-
26.81%
115 / 429
-
- 17.07% covered (danger) -
-
-
17.07%
7 / 41
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 10
ArticlesController.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 9
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
Controller.php
n/a
0 / 0
n/a
0 / 0
n/a
0 / 0
FeedsController.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 28
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 8
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
LogsController.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
OnboardingController.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 40
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 9
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
PlatformAccountsController.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 46
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 7
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
PlatformChannelsController.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 53
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 8
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
RoutingController.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 87
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 8
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
SettingsController.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 14
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- -
- - diff --git a/backend/coverage-report-final/Http/Middleware/HandleAppearance.php.html b/backend/coverage-report-final/Http/Middleware/HandleAppearance.php.html deleted file mode 100644 index fe7badba..00000000 --- a/backend/coverage-report-final/Http/Middleware/HandleAppearance.php.html +++ /dev/null @@ -1,176 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Http/Middleware/HandleAppearance.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
HandleAppearance
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 handle
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Http\Middleware;
4
5use Closure;
6use Illuminate\Http\Request;
7use Illuminate\Support\Facades\View;
8use Symfony\Component\HttpFoundation\Response;
9
10class HandleAppearance
11{
12    /**
13     * Handle an incoming request.
14     *
15     * @param  \Closure(\Illuminate\Http\Request): (\Symfony\Component\HttpFoundation\Response)  $next
16     */
17    public function handle(Request $request, Closure $next): Response
18    {
19        View::share('appearance', $request->cookie('appearance') ?? 'system');
20
21        return $next($request);
22    }
23}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:53:46 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-final/Http/Middleware/HandleInertiaRequests.php.html b/backend/coverage-report-final/Http/Middleware/HandleInertiaRequests.php.html deleted file mode 100644 index 336af8e8..00000000 --- a/backend/coverage-report-final/Http/Middleware/HandleInertiaRequests.php.html +++ /dev/null @@ -1,217 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Http/Middleware/HandleInertiaRequests.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 4
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
HandleInertiaRequests
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 4
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
6
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 version
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 share
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Http\Middleware;
4
5use Illuminate\Http\Request;
6use Inertia\Middleware;
7
8class HandleInertiaRequests extends Middleware
9{
10    /**
11     * The root template that's loaded on the first page visit.
12     *
13     * @see https://inertiajs.com/server-side-setup#root-template
14     *
15     * @var string
16     */
17    protected $rootView = 'app';
18
19    /**
20     * Determines the current asset version.
21     *
22     * @see https://inertiajs.com/asset-versioning
23     */
24    public function version(Request $request): ?string
25    {
26        return parent::version($request);
27    }
28
29    /**
30     * Define the props that are shared by default.
31     *
32     * @see https://inertiajs.com/shared-data
33     *
34     * @return array<string, mixed>
35     */
36    public function share(Request $request): array
37    {
38        return array_merge(parent::share($request), [
39            //
40        ]);
41    }
42}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:53:46 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-final/Http/Middleware/dashboard.html b/backend/coverage-report-final/Http/Middleware/dashboard.html deleted file mode 100644 index 25fa3791..00000000 --- a/backend/coverage-report-final/Http/Middleware/dashboard.html +++ /dev/null @@ -1,290 +0,0 @@ - - - - - Dashboard for /var/www/html/backend/app/Http/Middleware - - - - - - - -
-
-
-
- -
-
-
-
-
-
-
-

Classes

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
-
-
-

Insufficient Coverage

- -
-
-

Project Risks

-
- - - - - - - - - - -
ClassCRAP
-
-
-
-
-
-

Methods

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
-
-
-

Insufficient Coverage

-
- - - - - - - - - - - - - -
MethodCoverage
handle0%
version0%
share0%
-
-
-
-

Project Risks

-
- - - - - - - - - - -
MethodCRAP
-
-
-
- -
- - - - - - diff --git a/backend/coverage-report-final/Http/Middleware/index.html b/backend/coverage-report-final/Http/Middleware/index.html deleted file mode 100644 index ba10e0db..00000000 --- a/backend/coverage-report-final/Http/Middleware/index.html +++ /dev/null @@ -1,148 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Http/Middleware - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 6
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
HandleAppearance.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
HandleInertiaRequests.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 4
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- -
- - diff --git a/backend/coverage-report-final/Http/Requests/StoreFeedRequest.php.html b/backend/coverage-report-final/Http/Requests/StoreFeedRequest.php.html deleted file mode 100644 index c8ee0935..00000000 --- a/backend/coverage-report-final/Http/Requests/StoreFeedRequest.php.html +++ /dev/null @@ -1,203 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Http/Requests/StoreFeedRequest.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 100.00% covered (success) -
-
-
100.00%
9 / 9
-
- 100.00% covered (success) -
-
-
100.00%
2 / 2
CRAP
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
StoreFeedRequest
-
- 100.00% covered (success) -
-
-
100.00%
9 / 9
-
- 100.00% covered (success) -
-
-
100.00%
2 / 2
2
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
 authorize
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
1
 rules
-
- 100.00% covered (success) -
-
-
100.00%
8 / 8
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
1
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Http\Requests;
4
5use Illuminate\Foundation\Http\FormRequest;
6
7class StoreFeedRequest extends FormRequest
8{
9    public function authorize(): bool
10    {
11        return true;
12    }
13
14    /**
15     * @return array<string, string>
16     */
17    public function rules(): array
18    {
19        return [
20            'name' => 'required|string|max:255',
21            'url' => 'required|url|unique:feeds,url',
22            'type' => 'required|in:website,rss',
23            'language_id' => 'required|exists:languages,id',
24            'description' => 'nullable|string',
25            'is_active' => 'boolean'
26        ];
27    }
28}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:53:46 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-final/Http/Requests/UpdateFeedRequest.php.html b/backend/coverage-report-final/Http/Requests/UpdateFeedRequest.php.html deleted file mode 100644 index 942af9e9..00000000 --- a/backend/coverage-report-final/Http/Requests/UpdateFeedRequest.php.html +++ /dev/null @@ -1,204 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Http/Requests/UpdateFeedRequest.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 100.00% covered (success) -
-
-
100.00%
9 / 9
-
- 100.00% covered (success) -
-
-
100.00%
2 / 2
CRAP
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
UpdateFeedRequest
-
- 100.00% covered (success) -
-
-
100.00%
9 / 9
-
- 100.00% covered (success) -
-
-
100.00%
2 / 2
3
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
 authorize
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
1
 rules
-
- 100.00% covered (success) -
-
-
100.00%
8 / 8
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
2
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Http\Requests;
4
5use App\Models\Feed;
6use Illuminate\Foundation\Http\FormRequest;
7
8class UpdateFeedRequest extends FormRequest
9{
10    public function authorize(): bool
11    {
12        return true;
13    }
14
15    /**
16     * @return array<string, string>
17     */
18    public function rules(): array
19    {
20        return [
21            'name' => 'required|string|max:255',
22            'url' => 'required|url|unique:feeds,url,' . ($this->route('feed') instanceof Feed ? (string)$this->route('feed')->id : (string)$this->route('feed')),
23            'type' => 'required|in:website,rss',
24            'language_id' => 'required|exists:languages,id',
25            'description' => 'nullable|string',
26            'is_active' => 'boolean'
27        ];
28    }
29}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:53:46 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-final/Http/Requests/dashboard.html b/backend/coverage-report-final/Http/Requests/dashboard.html deleted file mode 100644 index f6d012dc..00000000 --- a/backend/coverage-report-final/Http/Requests/dashboard.html +++ /dev/null @@ -1,285 +0,0 @@ - - - - - Dashboard for /var/www/html/backend/app/Http/Requests - - - - - - - -
-
-
-
- -
-
-
-
-
-
-
-

Classes

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
-
-
-

Insufficient Coverage

-
- - - - - - - - - - -
ClassCoverage
-
-
-
-

Project Risks

-
- - - - - - - - - - -
ClassCRAP
-
-
-
-
-
-

Methods

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
-
-
-

Insufficient Coverage

-
- - - - - - - - - - -
MethodCoverage
-
-
-
-

Project Risks

-
- - - - - - - - - - -
MethodCRAP
-
-
-
- -
- - - - - - diff --git a/backend/coverage-report-final/Http/Requests/index.html b/backend/coverage-report-final/Http/Requests/index.html deleted file mode 100644 index 476e187d..00000000 --- a/backend/coverage-report-final/Http/Requests/index.html +++ /dev/null @@ -1,148 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Http/Requests - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 100.00% covered (success) -
-
-
100.00%
18 / 18
-
- 100.00% covered (success) -
-
-
100.00%
4 / 4
-
- 100.00% covered (success) -
-
-
100.00%
2 / 2
StoreFeedRequest.php
-
- 100.00% covered (success) -
-
-
100.00%
9 / 9
-
- 100.00% covered (success) -
-
-
100.00%
2 / 2
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
UpdateFeedRequest.php
-
- 100.00% covered (success) -
-
-
100.00%
9 / 9
-
- 100.00% covered (success) -
-
-
100.00%
2 / 2
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
-
- -
- - diff --git a/backend/coverage-report-final/Http/Resources/ArticlePublicationResource.php.html b/backend/coverage-report-final/Http/Resources/ArticlePublicationResource.php.html deleted file mode 100644 index 7fe845ef..00000000 --- a/backend/coverage-report-final/Http/Resources/ArticlePublicationResource.php.html +++ /dev/null @@ -1,179 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Http/Resources/ArticlePublicationResource.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 8
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
ArticlePublicationResource
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 8
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 toArray
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 8
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Http\Resources;
4
5use Illuminate\Http\Request;
6use Illuminate\Http\Resources\Json\JsonResource;
7
8class ArticlePublicationResource extends JsonResource
9{
10    /**
11     * Transform the resource into an array.
12     *
13     * @return array<string, mixed>
14     */
15    public function toArray(Request $request): array
16    {
17        return [
18            'id' => $this->id,
19            'article_id' => $this->article_id,
20            'status' => $this->status,
21            'published_at' => $this->published_at?->toISOString(),
22            'created_at' => $this->created_at->toISOString(),
23            'updated_at' => $this->updated_at->toISOString(),
24        ];
25    }
26}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:53:46 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-final/Http/Resources/ArticleResource.php.html b/backend/coverage-report-final/Http/Resources/ArticleResource.php.html deleted file mode 100644 index 2c32745f..00000000 --- a/backend/coverage-report-final/Http/Resources/ArticleResource.php.html +++ /dev/null @@ -1,189 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Http/Resources/ArticleResource.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 100.00% covered (success) -
-
-
100.00%
18 / 18
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
CRAP
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
ArticleResource
-
- 100.00% covered (success) -
-
-
100.00%
18 / 18
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
1
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
 toArray
-
- 100.00% covered (success) -
-
-
100.00%
18 / 18
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
1
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Http\Resources;
4
5use Illuminate\Http\Request;
6use Illuminate\Http\Resources\Json\JsonResource;
7
8class ArticleResource extends JsonResource
9{
10    /**
11     * Transform the resource into an array.
12     *
13     * @return array<string, mixed>
14     */
15    public function toArray(Request $request): array
16    {
17        return [
18            'id' => $this->id,
19            'feed_id' => $this->feed_id,
20            'url' => $this->url,
21            'title' => $this->title,
22            'description' => $this->description,
23            'is_valid' => $this->is_valid,
24            'is_duplicate' => $this->is_duplicate,
25            'approval_status' => $this->approval_status,
26            'approved_at' => $this->approved_at?->toISOString(),
27            'approved_by' => $this->approved_by,
28            'fetched_at' => $this->fetched_at?->toISOString(),
29            'validated_at' => $this->validated_at?->toISOString(),
30            'created_at' => $this->created_at->toISOString(),
31            'updated_at' => $this->updated_at->toISOString(),
32            'feed' => new FeedResource($this->whenLoaded('feed')),
33            'article_publication' => new ArticlePublicationResource($this->whenLoaded('articlePublication')),
34        ];
35    }
36}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:53:46 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-final/Http/Resources/FeedResource.php.html b/backend/coverage-report-final/Http/Resources/FeedResource.php.html deleted file mode 100644 index 3d5e576c..00000000 --- a/backend/coverage-report-final/Http/Resources/FeedResource.php.html +++ /dev/null @@ -1,184 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Http/Resources/FeedResource.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 100.00% covered (success) -
-
-
100.00%
13 / 13
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
CRAP
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
FeedResource
-
- 100.00% covered (success) -
-
-
100.00%
13 / 13
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
1
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
 toArray
-
- 100.00% covered (success) -
-
-
100.00%
13 / 13
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
1
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Http\Resources;
4
5use Illuminate\Http\Request;
6use Illuminate\Http\Resources\Json\JsonResource;
7
8class FeedResource extends JsonResource
9{
10    /**
11     * Transform the resource into an array.
12     *
13     * @return array<string, mixed>
14     */
15    public function toArray(Request $request): array
16    {
17        return [
18            'id' => $this->id,
19            'name' => $this->name,
20            'url' => $this->url,
21            'type' => $this->type,
22            'is_active' => $this->is_active,
23            'description' => $this->description,
24            'created_at' => $this->created_at->toISOString(),
25            'updated_at' => $this->updated_at->toISOString(),
26            'articles_count' => $this->when($request->routeIs('api.feeds.*'), function () {
27                return $this->articles()->count();
28            }),
29        ];
30    }
31}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:53:46 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-final/Http/Resources/PlatformAccountResource.php.html b/backend/coverage-report-final/Http/Resources/PlatformAccountResource.php.html deleted file mode 100644 index 28ad5a76..00000000 --- a/backend/coverage-report-final/Http/Resources/PlatformAccountResource.php.html +++ /dev/null @@ -1,184 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Http/Resources/PlatformAccountResource.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 13
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
PlatformAccountResource
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 13
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 toArray
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 13
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Http\Resources;
4
5use Illuminate\Http\Request;
6use Illuminate\Http\Resources\Json\JsonResource;
7
8class PlatformAccountResource extends JsonResource
9{
10    /**
11     * Transform the resource into an array.
12     *
13     * @return array<string, mixed>
14     */
15    public function toArray(Request $request): array
16    {
17        return [
18            'id' => $this->id,
19            'platform_instance_id' => $this->platform_instance_id,
20            'account_id' => $this->account_id,
21            'username' => $this->username,
22            'display_name' => $this->display_name,
23            'description' => $this->description,
24            'is_active' => $this->is_active,
25            'created_at' => $this->created_at->toISOString(),
26            'updated_at' => $this->updated_at->toISOString(),
27            'platform_instance' => new PlatformInstanceResource($this->whenLoaded('platformInstance')),
28            'channels' => PlatformChannelResource::collection($this->whenLoaded('channels')),
29        ];
30    }
31}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:53:46 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-final/Http/Resources/PlatformChannelResource.php.html b/backend/coverage-report-final/Http/Resources/PlatformChannelResource.php.html deleted file mode 100644 index 59bae068..00000000 --- a/backend/coverage-report-final/Http/Resources/PlatformChannelResource.php.html +++ /dev/null @@ -1,184 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Http/Resources/PlatformChannelResource.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 13
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
PlatformChannelResource
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 13
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 toArray
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 13
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Http\Resources;
4
5use Illuminate\Http\Request;
6use Illuminate\Http\Resources\Json\JsonResource;
7
8class PlatformChannelResource extends JsonResource
9{
10    /**
11     * Transform the resource into an array.
12     *
13     * @return array<string, mixed>
14     */
15    public function toArray(Request $request): array
16    {
17        return [
18            'id' => $this->id,
19            'platform_instance_id' => $this->platform_instance_id,
20            'channel_id' => $this->channel_id,
21            'name' => $this->name,
22            'display_name' => $this->display_name,
23            'description' => $this->description,
24            'is_active' => $this->is_active,
25            'created_at' => $this->created_at->toISOString(),
26            'updated_at' => $this->updated_at->toISOString(),
27            'platform_instance' => new PlatformInstanceResource($this->whenLoaded('platformInstance')),
28            'routes' => RouteResource::collection($this->whenLoaded('routes')),
29        ];
30    }
31}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:53:46 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-final/Http/Resources/PlatformInstanceResource.php.html b/backend/coverage-report-final/Http/Resources/PlatformInstanceResource.php.html deleted file mode 100644 index 21c9a616..00000000 --- a/backend/coverage-report-final/Http/Resources/PlatformInstanceResource.php.html +++ /dev/null @@ -1,180 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Http/Resources/PlatformInstanceResource.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 9
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
PlatformInstanceResource
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 9
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 toArray
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 9
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Http\Resources;
4
5use Illuminate\Http\Request;
6use Illuminate\Http\Resources\Json\JsonResource;
7
8class PlatformInstanceResource extends JsonResource
9{
10    /**
11     * Transform the resource into an array.
12     *
13     * @return array<string, mixed>
14     */
15    public function toArray(Request $request): array
16    {
17        return [
18            'id' => $this->id,
19            'name' => $this->name,
20            'url' => $this->url,
21            'description' => $this->description,
22            'is_active' => $this->is_active,
23            'created_at' => $this->created_at->toISOString(),
24            'updated_at' => $this->updated_at->toISOString(),
25        ];
26    }
27}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:53:46 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-final/Http/Resources/RouteResource.php.html b/backend/coverage-report-final/Http/Resources/RouteResource.php.html deleted file mode 100644 index e6e51413..00000000 --- a/backend/coverage-report-final/Http/Resources/RouteResource.php.html +++ /dev/null @@ -1,182 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Http/Resources/RouteResource.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 11
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
RouteResource
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 11
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 toArray
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 11
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Http\Resources;
4
5use Illuminate\Http\Request;
6use Illuminate\Http\Resources\Json\JsonResource;
7
8class RouteResource extends JsonResource
9{
10    /**
11     * Transform the resource into an array.
12     *
13     * @return array<string, mixed>
14     */
15    public function toArray(Request $request): array
16    {
17        return [
18            'id' => $this->id,
19            'feed_id' => $this->feed_id,
20            'platform_channel_id' => $this->platform_channel_id,
21            'is_active' => $this->is_active,
22            'priority' => $this->priority,
23            'created_at' => $this->created_at->toISOString(),
24            'updated_at' => $this->updated_at->toISOString(),
25            'feed' => new FeedResource($this->whenLoaded('feed')),
26            'platform_channel' => new PlatformChannelResource($this->whenLoaded('platformChannel')),
27        ];
28    }
29}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:53:46 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-final/Http/Resources/dashboard.html b/backend/coverage-report-final/Http/Resources/dashboard.html deleted file mode 100644 index 9e1e7384..00000000 --- a/backend/coverage-report-final/Http/Resources/dashboard.html +++ /dev/null @@ -1,295 +0,0 @@ - - - - - Dashboard for /var/www/html/backend/app/Http/Resources - - - - - - - -
-
-
-
- -
-
-
-
-
-
-
-

Classes

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
-
- -
-

Project Risks

-
- - - - - - - - - - -
ClassCRAP
-
-
-
-
-
-

Methods

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
-
-
-

Insufficient Coverage

-
- - - - - - - - - - - - - - - -
MethodCoverage
toArray0%
toArray0%
toArray0%
toArray0%
toArray0%
-
-
-
-

Project Risks

-
- - - - - - - - - - -
MethodCRAP
-
-
-
- -
- - - - - - diff --git a/backend/coverage-report-final/Http/Resources/index.html b/backend/coverage-report-final/Http/Resources/index.html deleted file mode 100644 index 94f6afd8..00000000 --- a/backend/coverage-report-final/Http/Resources/index.html +++ /dev/null @@ -1,288 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Http/Resources - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 36.47% covered (danger) -
-
-
36.47%
31 / 85
-
- 28.57% covered (danger) -
-
-
28.57%
2 / 7
-
- 28.57% covered (danger) -
-
-
28.57%
2 / 7
ArticlePublicationResource.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 8
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
ArticleResource.php
-
- 100.00% covered (success) -
-
-
100.00%
18 / 18
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
FeedResource.php
-
- 100.00% covered (success) -
-
-
100.00%
13 / 13
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
PlatformAccountResource.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 13
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
PlatformChannelResource.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 13
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
PlatformInstanceResource.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 9
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
RouteResource.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 11
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- -
- - diff --git a/backend/coverage-report-final/Http/dashboard.html b/backend/coverage-report-final/Http/dashboard.html deleted file mode 100644 index 007b541b..00000000 --- a/backend/coverage-report-final/Http/dashboard.html +++ /dev/null @@ -1,453 +0,0 @@ - - - - - Dashboard for /var/www/html/backend/app/Http - - - - - - - -
-
-
-
- -
-
-
-
-
-
-
-

Classes

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
-
- - -
-
-
-

Methods

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
-
-
-

Insufficient Coverage

-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
MethodCoverage
login0%
register0%
logout0%
me0%
sendNotFound0%
sendUnauthorized0%
index0%
index0%
store0%
show0%
update0%
destroy0%
setActive0%
index0%
store0%
show0%
update0%
destroy0%
toggle0%
index0%
store0%
show0%
update0%
destroy0%
toggle0%
__invoke0%
approve0%
reject0%
index0%
create0%
store0%
show0%
edit0%
update0%
destroy0%
toggle0%
__invoke0%
index0%
platform0%
feed0%
channel0%
complete0%
needsOnboarding0%
hasPlatformAccount0%
hasFeed0%
hasChannel0%
index0%
create0%
store0%
edit0%
update0%
destroy0%
setActive0%
index0%
create0%
store0%
show0%
edit0%
update0%
destroy0%
toggle0%
index0%
create0%
store0%
edit0%
update0%
destroy0%
toggle0%
parseJsonFilters0%
index0%
update0%
handle0%
version0%
share0%
toArray0%
toArray0%
toArray0%
toArray0%
toArray0%
update63%
store66%
approve71%
reject71%
destroy71%
index71%
toggle77%
stats83%
-
-
-
-

Project Risks

-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
MethodCRAP
login30
complete30
store20
update20
update20
toggle20
channel20
register12
index12
store12
update12
toggle12
store12
destroy12
feed12
needsOnboarding12
store12
store12
toggle12
parseJsonFilters12
logout6
destroy6
setActive6
destroy6
show6
toggle6
index6
platform6
update6
store6
toggle6
edit6
update6
update3
store3
toggle3
approve2
reject2
destroy2
index2
stats2
-
-
-
- -
- - - - - - diff --git a/backend/coverage-report-final/Http/index.html b/backend/coverage-report-final/Http/index.html deleted file mode 100644 index eed84b30..00000000 --- a/backend/coverage-report-final/Http/index.html +++ /dev/null @@ -1,203 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Http - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 20.07% covered (danger) -
-
-
20.07%
164 / 817
-
- 12.87% covered (danger) -
-
-
12.87%
13 / 101
-
- 13.79% covered (danger) -
-
-
13.79%
4 / 29
Controllers
-
- 16.24% covered (danger) -
-
-
16.24%
115 / 708
-
- 8.05% covered (danger) -
-
-
8.05%
7 / 87
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 18
Middleware
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 6
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
Requests
-
- 100.00% covered (success) -
-
-
100.00%
18 / 18
-
- 100.00% covered (success) -
-
-
100.00%
4 / 4
-
- 100.00% covered (success) -
-
-
100.00%
2 / 2
Resources
-
- 36.47% covered (danger) -
-
-
36.47%
31 / 85
-
- 28.57% covered (danger) -
-
-
28.57%
2 / 7
-
- 28.57% covered (danger) -
-
-
28.57%
2 / 7
-
- -
- - diff --git a/backend/coverage-report-final/Jobs/ArticleDiscoveryForFeedJob.php.html b/backend/coverage-report-final/Jobs/ArticleDiscoveryForFeedJob.php.html deleted file mode 100644 index e9695dfb..00000000 --- a/backend/coverage-report-final/Jobs/ArticleDiscoveryForFeedJob.php.html +++ /dev/null @@ -1,257 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Jobs/ArticleDiscoveryForFeedJob.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 26
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
ArticleDiscoveryForFeedJob
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 26
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
12
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 __construct
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 handle
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 12
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 dispatchForAllActiveFeeds
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 13
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Jobs;
4
5use App\Models\Feed;
6use App\Services\Article\ArticleFetcher;
7use App\Services\Log\LogSaver;
8use Illuminate\Contracts\Queue\ShouldQueue;
9use Illuminate\Foundation\Queue\Queueable;
10
11class ArticleDiscoveryForFeedJob implements ShouldQueue
12{
13    use Queueable;
14
15    private const FEED_DISCOVERY_DELAY_MINUTES = 5;
16
17    public function __construct(
18        private readonly Feed $feed
19    ) {
20        $this->onQueue('feed-discovery');
21    }
22
23    public function handle(): void
24    {
25        LogSaver::info('Starting feed article fetch', null, [
26            'feed_id' => $this->feed->id,
27            'feed_name' => $this->feed->name,
28            'feed_url' => $this->feed->url
29        ]);
30
31        $articles = ArticleFetcher::getArticlesFromFeed($this->feed);
32
33        LogSaver::info('Feed article fetch completed', null, [
34            'feed_id' => $this->feed->id,
35            'feed_name' => $this->feed->name,
36            'articles_count' => $articles->count()
37        ]);
38
39        $this->feed->update(['last_fetched_at' => now()]);
40    }
41
42    public static function dispatchForAllActiveFeeds(): void
43    {
44        Feed::where('is_active', true)
45            ->get()
46            ->each(function (Feed $feed, $index) {
47                // Space jobs apart to avoid overwhelming feeds
48                $delayMinutes = $index * self::FEED_DISCOVERY_DELAY_MINUTES;
49
50                self::dispatch($feed)
51                    ->delay(now()->addMinutes($delayMinutes))
52                    ->onQueue('feed-discovery');
53
54                LogSaver::info('Dispatched feed discovery job', null, [
55                    'feed_id' => $feed->id,
56                    'feed_name' => $feed->name,
57                    'delay_minutes' => $delayMinutes
58                ]);
59            });
60    }
61}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:53:46 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-final/Jobs/ArticleDiscoveryJob.php.html b/backend/coverage-report-final/Jobs/ArticleDiscoveryJob.php.html deleted file mode 100644 index fd6d8271..00000000 --- a/backend/coverage-report-final/Jobs/ArticleDiscoveryJob.php.html +++ /dev/null @@ -1,207 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Jobs/ArticleDiscoveryJob.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 7
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
ArticleDiscoveryJob
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 7
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
12
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 __construct
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 handle
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 6
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
6
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Jobs;
4
5use App\Models\Setting;
6use App\Services\Log\LogSaver;
7use Illuminate\Contracts\Queue\ShouldQueue;
8use Illuminate\Foundation\Queue\Queueable;
9
10class ArticleDiscoveryJob implements ShouldQueue
11{
12    use Queueable;
13
14    public function __construct()
15    {
16        $this->onQueue('feed-discovery');
17    }
18
19    public function handle(): void
20    {
21        if (!Setting::isArticleProcessingEnabled()) {
22            LogSaver::info('Article processing is disabled. Article discovery skipped.');
23
24            return;
25        }
26
27        LogSaver::info('Starting article discovery for all active feeds');
28
29        ArticleDiscoveryForFeedJob::dispatchForAllActiveFeeds();
30
31        LogSaver::info('Article discovery jobs dispatched for all active feeds');
32    }
33}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:53:46 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-final/Jobs/PublishToLemmyJob.php.html b/backend/coverage-report-final/Jobs/PublishToLemmyJob.php.html deleted file mode 100644 index 8bcba228..00000000 --- a/backend/coverage-report-final/Jobs/PublishToLemmyJob.php.html +++ /dev/null @@ -1,212 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Jobs/PublishToLemmyJob.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 6
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
PublishToLemmyJob
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 6
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
12
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 __construct
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 handle
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 5
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
6
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Jobs;
4
5use App\Exceptions\PublishException;
6use App\Models\Article;
7use App\Services\Article\ArticleFetcher;
8use App\Services\Publishing\ArticlePublishingService;
9use Illuminate\Contracts\Queue\ShouldQueue;
10use Illuminate\Foundation\Queue\Queueable;
11
12class PublishToLemmyJob implements ShouldQueue
13{
14    use Queueable;
15
16    public int $tries = 3;
17    public array $backoff = [60, 120, 300];
18
19    public function __construct(
20        private readonly Article $article
21    ) {
22        $this->onQueue('lemmy-posts');
23    }
24
25    public function handle(): void
26    {
27        $extractedData = ArticleFetcher::fetchArticleData($this->article);
28
29        /** @var ArticlePublishingService $publishingService */
30        $publishingService = resolve(ArticlePublishingService::class);
31
32        try {
33            $publishingService->publishToRoutedChannels($this->article, $extractedData);
34        } catch (PublishException $e) {
35            $this->fail($e);
36        }
37    }
38}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:53:46 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-final/Jobs/SyncChannelPostsJob.php.html b/backend/coverage-report-final/Jobs/SyncChannelPostsJob.php.html deleted file mode 100644 index 9159cb88..00000000 --- a/backend/coverage-report-final/Jobs/SyncChannelPostsJob.php.html +++ /dev/null @@ -1,352 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Jobs/SyncChannelPostsJob.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 42
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 5
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
SyncChannelPostsJob
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 42
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 5
182
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 __construct
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 dispatchForAllActiveChannels
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 9
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 handle
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 5
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
6
 syncLemmyChannelPosts
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 16
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
20
 getAuthToken
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 11
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
30
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Jobs;
4
5use App\Enums\PlatformEnum;
6use App\Exceptions\PlatformAuthException;
7use App\Models\PlatformAccount;
8use App\Models\PlatformChannel;
9use App\Modules\Lemmy\Services\LemmyApiService;
10use App\Services\Log\LogSaver;
11use Exception;
12use Illuminate\Contracts\Queue\ShouldBeUnique;
13use Illuminate\Contracts\Queue\ShouldQueue;
14use Illuminate\Database\Eloquent\Collection;
15use Illuminate\Foundation\Queue\Queueable;
16use Illuminate\Support\Facades\Cache;
17
18class SyncChannelPostsJob implements ShouldQueue, ShouldBeUnique
19{
20    use Queueable;
21
22    public function __construct(
23        private readonly PlatformChannel $channel
24    ) {
25        $this->onQueue('sync');
26    }
27
28    public static function dispatchForAllActiveChannels(): void
29    {
30        PlatformChannel::with(['platformInstance', 'platformAccounts'])
31            ->whereHas('platformInstance', fn ($query) => $query->where('platform', PlatformEnum::LEMMY))
32            ->whereHas('platformAccounts', fn ($query) => $query->where('is_active', true))
33            ->where('is_active', true)
34            ->get()
35            ->each(function (PlatformChannel $channel) {
36                self::dispatch($channel);
37                LogSaver::info('Dispatched sync job for channel', $channel);
38            });
39    }
40
41    public function handle(): void
42    {
43        LogSaver::info('Starting channel posts sync job', $this->channel);
44
45        match ($this->channel->platformInstance->platform) {
46            PlatformEnum::LEMMY => $this->syncLemmyChannelPosts(),
47        };
48
49        LogSaver::info('Channel posts sync job completed', $this->channel);
50    }
51
52    /**
53     * @throws PlatformAuthException
54     */
55    private function syncLemmyChannelPosts(): void
56    {
57        try {
58            /** @var Collection<int, PlatformAccount> $accounts */
59            $accounts = $this->channel->activePlatformAccounts()->get();
60            $account = $accounts->first();
61
62            if (! $account) {
63                throw new PlatformAuthException(PlatformEnum::LEMMY, 'No active account found for channel');
64            }
65
66            $api = new LemmyApiService($this->channel->platformInstance->url);
67            $token = $this->getAuthToken($api, $account);
68
69            $platformChannelId = $this->channel->channel_id
70                ? $this->channel->channel_id
71                : $api->getCommunityId($this->channel->name, $token);
72
73            $api->syncChannelPosts($token, $platformChannelId, $this->channel->name);
74
75            LogSaver::info('Channel posts synced successfully', $this->channel);
76
77        } catch (Exception $e) {
78            LogSaver::error('Failed to sync channel posts', $this->channel, [
79                'error' => $e->getMessage()
80            ]);
81
82            throw $e;
83        }
84    }
85
86    /**
87     * @throws PlatformAuthException
88     */
89    private function getAuthToken(LemmyApiService $api, PlatformAccount $account): string
90    {
91        $cacheKey = "lemmy_jwt_token_{$account->id}";
92        $cachedToken = Cache::get($cacheKey);
93
94        if ($cachedToken) {
95            return $cachedToken;
96        }
97
98        if (!$account->username || !$account->password) {
99            throw new PlatformAuthException(PlatformEnum::LEMMY, 'Missing credentials for account');
100        }
101
102        $token = $api->login($account->username, $account->password);
103
104        if (!$token) {
105            throw new PlatformAuthException(PlatformEnum::LEMMY, 'Login failed for account');
106        }
107
108        Cache::put($cacheKey, $token, 3600);
109
110        return $token;
111    }
112}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:53:46 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-final/Jobs/dashboard.html b/backend/coverage-report-final/Jobs/dashboard.html deleted file mode 100644 index 0c50f5c2..00000000 --- a/backend/coverage-report-final/Jobs/dashboard.html +++ /dev/null @@ -1,308 +0,0 @@ - - - - - Dashboard for /var/www/html/backend/app/Jobs - - - - - - - -
-
-
-
- -
-
-
-
-
-
-
-

Classes

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
-
-
-

Insufficient Coverage

- -
-
-

Project Risks

- -
-
-
-
-

Methods

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
-
-
-

Insufficient Coverage

- -
-
-

Project Risks

-
- - - - - - - - - - - - - - - -
MethodCRAP
getAuthToken30
syncLemmyChannelPosts20
handle6
handle6
handle6
-
-
-
- -
- - - - - - diff --git a/backend/coverage-report-final/Jobs/index.html b/backend/coverage-report-final/Jobs/index.html deleted file mode 100644 index d63563ef..00000000 --- a/backend/coverage-report-final/Jobs/index.html +++ /dev/null @@ -1,203 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Jobs - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 81
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 12
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 4
ArticleDiscoveryForFeedJob.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 26
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
ArticleDiscoveryJob.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 7
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
PublishToLemmyJob.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 6
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
SyncChannelPostsJob.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 42
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 5
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- -
- - diff --git a/backend/coverage-report-final/Listeners/LogExceptionToDatabase.php.html b/backend/coverage-report-final/Listeners/LogExceptionToDatabase.php.html deleted file mode 100644 index b24adc22..00000000 --- a/backend/coverage-report-final/Listeners/LogExceptionToDatabase.php.html +++ /dev/null @@ -1,179 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Listeners/LogExceptionToDatabase.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 12
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
LogExceptionToDatabase
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 12
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 handle
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 12
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Listeners;
4
5use App\Events\ExceptionLogged;
6use App\Events\ExceptionOccurred;
7use App\Models\Log;
8class LogExceptionToDatabase
9{
10
11    public function handle(ExceptionOccurred $event): void
12    {
13        $log = Log::create([
14            'level' => $event->level,
15            'message' => $event->message,
16            'context' => [
17                'exception_class' => get_class($event->exception),
18                'file' => $event->exception->getFile(),
19                'line' => $event->exception->getLine(),
20                'trace' => $event->exception->getTraceAsString(),
21                ...$event->context
22            ]
23        ]);
24
25        ExceptionLogged::dispatch($log);
26    }
27}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:53:46 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-final/Listeners/PublishApprovedArticle.php.html b/backend/coverage-report-final/Listeners/PublishApprovedArticle.php.html deleted file mode 100644 index 2367e4f9..00000000 --- a/backend/coverage-report-final/Listeners/PublishApprovedArticle.php.html +++ /dev/null @@ -1,179 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Listeners/PublishApprovedArticle.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 5
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
PublishApprovedArticle
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 5
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
20
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 handle
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 5
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
20
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Listeners;
4
5use App\Events\ArticleApproved;
6use App\Events\ArticleReadyToPublish;
7use Illuminate\Contracts\Queue\ShouldQueue;
8
9class PublishApprovedArticle implements ShouldQueue
10{
11    public string $queue = 'default';
12
13    public function handle(ArticleApproved $event): void
14    {
15        $article = $event->article;
16
17        // Skip if already has publication (prevents duplicate processing)
18        if ($article->articlePublication()->exists()) {
19            return;
20        }
21
22        // Only publish if the article is valid and approved
23        if ($article->isValid() && $article->isApproved()) {
24            event(new ArticleReadyToPublish($article));
25        }
26    }
27}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:53:46 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-final/Listeners/PublishArticle.php.html b/backend/coverage-report-final/Listeners/PublishArticle.php.html deleted file mode 100644 index f570a2d2..00000000 --- a/backend/coverage-report-final/Listeners/PublishArticle.php.html +++ /dev/null @@ -1,213 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Listeners/PublishArticle.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 13
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
PublishArticle
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 13
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
12
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 __construct
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 handle
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 12
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
6
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Listeners;
4
5use App\Events\ArticleReadyToPublish;
6use App\Jobs\PublishToLemmyJob;
7use Illuminate\Contracts\Queue\ShouldQueue;
8
9class PublishArticle implements ShouldQueue
10{
11    public string|null $queue = 'lemmy-publish';
12    public int $delay = 300;
13    public int $tries = 3;
14    public int $backoff = 300;
15
16    public function __construct()
17    {}
18
19    public function handle(ArticleReadyToPublish $event): void
20    {
21        $article = $event->article;
22
23        if ($article->articlePublication()->exists()) {
24            logger()->info('Article already published, skipping job dispatch', [
25                'article_id' => $article->id,
26                'url' => $article->url
27            ]);
28
29            return;
30        }
31
32        logger()->info('Article queued for publishing to Lemmy', [
33            'article_id' => $article->id,
34            'url' => $article->url
35        ]);
36
37        PublishToLemmyJob::dispatch($article);
38    }
39}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:53:46 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-final/Listeners/ValidateArticleListener.php.html b/backend/coverage-report-final/Listeners/ValidateArticleListener.php.html deleted file mode 100644 index fb2577f9..00000000 --- a/backend/coverage-report-final/Listeners/ValidateArticleListener.php.html +++ /dev/null @@ -1,201 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Listeners/ValidateArticleListener.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 13
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
ValidateArticleListener
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 13
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
56
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 handle
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 13
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
56
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Listeners;
4
5use App\Events\NewArticleFetched;
6use App\Events\ArticleReadyToPublish;
7use App\Models\Setting;
8use App\Services\Article\ValidationService;
9use Illuminate\Contracts\Queue\ShouldQueue;
10
11class ValidateArticleListener implements ShouldQueue
12{
13    public string $queue = 'default';
14
15    public function handle(NewArticleFetched $event): void
16    {
17        $article = $event->article;
18
19        if (! is_null($article->validated_at)) {
20            return;
21        }
22
23        // Skip if already has publication (prevents duplicate processing)
24        if ($article->articlePublication()->exists()) {
25            return;
26        }
27
28        $article = ValidationService::validate($article);
29
30        if ($article->isValid()) {
31            // Double-check publication doesn't exist (race condition protection)
32            if ($article->articlePublication()->exists()) {
33                return;
34            }
35
36            // Check if approval system is enabled
37            if (Setting::isPublishingApprovalsEnabled()) {
38                // If approvals are enabled, only proceed if article is approved
39                if ($article->isApproved()) {
40                    event(new ArticleReadyToPublish($article));
41                }
42                // If not approved, article will wait for manual approval
43            } else {
44                // If approvals are disabled, proceed with publishing
45                event(new ArticleReadyToPublish($article));
46            }
47        }
48    }
49}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:53:46 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-final/Listeners/dashboard.html b/backend/coverage-report-final/Listeners/dashboard.html deleted file mode 100644 index 277c5093..00000000 --- a/backend/coverage-report-final/Listeners/dashboard.html +++ /dev/null @@ -1,299 +0,0 @@ - - - - - Dashboard for /var/www/html/backend/app/Listeners - - - - - - - -
-
-
-
- -
-
-
-
-
-
-
-

Classes

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
- -
-
-

Methods

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
-
-
-

Insufficient Coverage

-
- - - - - - - - - - - - - - - -
MethodCoverage
handle0%
handle0%
__construct0%
handle0%
handle0%
-
-
-
-

Project Risks

-
- - - - - - - - - - - - - -
MethodCRAP
handle56
handle20
handle6
-
-
-
- -
- - - - - - diff --git a/backend/coverage-report-final/Listeners/index.html b/backend/coverage-report-final/Listeners/index.html deleted file mode 100644 index eba8286a..00000000 --- a/backend/coverage-report-final/Listeners/index.html +++ /dev/null @@ -1,203 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Listeners - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 43
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 5
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 4
LogExceptionToDatabase.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 12
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
PublishApprovedArticle.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 5
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
PublishArticle.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 13
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
ValidateArticleListener.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 13
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- -
- - diff --git a/backend/coverage-report-final/LogLevelEnum.php.html b/backend/coverage-report-final/LogLevelEnum.php.html deleted file mode 100644 index a13fe977..00000000 --- a/backend/coverage-report-final/LogLevelEnum.php.html +++ /dev/null @@ -1,177 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/LogLevelEnum.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 100.00% covered (success) -
-
-
100.00%
7 / 7
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
CRAP
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
LogLevelEnum
-
- 100.00% covered (success) -
-
-
100.00%
7 / 7
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
1
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
 toArray
-
- 100.00% covered (success) -
-
-
100.00%
7 / 7
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
1
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App;
4
5enum LogLevelEnum: string
6{
7    case DEBUG = 'debug';
8    case INFO = 'info';
9    case WARNING = 'warning';
10    case ERROR = 'error';
11    case CRITICAL = 'critical';
12
13    /**
14     * @return array<int, string>
15     */
16    public static function toArray(): array
17    {
18        return [
19            self::DEBUG->value,
20            self::INFO->value,
21            self::WARNING->value,
22            self::ERROR->value,
23            self::CRITICAL->value,
24        ];
25    }
26}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:53:46 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-final/Models/Article.php.html b/backend/coverage-report-final/Models/Article.php.html deleted file mode 100644 index 0e50aada..00000000 --- a/backend/coverage-report-final/Models/Article.php.html +++ /dev/null @@ -1,522 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Models/Article.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 100.00% covered (success) -
-
-
100.00%
39 / 39
-
- 100.00% covered (success) -
-
-
100.00%
11 / 11
CRAP
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
Article
-
- 100.00% covered (success) -
-
-
100.00%
39 / 39
-
- 100.00% covered (success) -
-
-
100.00%
11 / 11
15
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
 casts
-
- 100.00% covered (success) -
-
-
100.00%
10 / 10
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
1
 isValid
-
- 100.00% covered (success) -
-
-
100.00%
5 / 5
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
3
 isApproved
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
1
 isPending
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
1
 isRejected
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
1
 approve
-
- 100.00% covered (success) -
-
-
100.00%
6 / 6
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
1
 reject
-
- 100.00% covered (success) -
-
-
100.00%
5 / 5
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
1
 canBePublished
-
- 100.00% covered (success) -
-
-
100.00%
5 / 5
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
3
 articlePublication
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
1
 feed
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
1
 booted
-
- 100.00% covered (success) -
-
-
100.00%
3 / 3
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
1
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Models;
4
5use App\Events\ArticleApproved;
6use App\Events\NewArticleFetched;
7use Database\Factories\ArticleFactory;
8use Illuminate\Database\Eloquent\Factories\HasFactory;
9use Illuminate\Database\Eloquent\Model;
10use Illuminate\Database\Eloquent\Relations\BelongsTo;
11use Illuminate\Database\Eloquent\Relations\HasOne;
12use Illuminate\Support\Carbon;
13
14/**
15 * @method static firstOrCreate(array<string, mixed> $array)
16 * @method static where(string $string, string $url)
17 * @method static create(array<string, mixed> $array)
18 * @property integer $id
19 * @property int $feed_id
20 * @property Feed $feed
21 * @property string $url
22 * @property bool|null $is_valid
23 * @property Carbon|null $validated_at
24 * @property Carbon $created_at
25 * @property Carbon $updated_at
26 * @property ArticlePublication $articlePublication
27 */
28class Article extends Model
29{
30    /** @use HasFactory<ArticleFactory> */
31    use HasFactory;
32
33    protected $fillable = [
34        'feed_id',
35        'url',
36        'title',
37        'description',
38        'is_valid',
39        'is_duplicate',
40        'approval_status',
41        'approved_at',
42        'approved_by',
43        'fetched_at',
44        'validated_at',
45    ];
46
47    /**
48     * @return array<string, string>
49     */
50    public function casts(): array
51    {
52        return [
53            'is_valid' => 'boolean',
54            'is_duplicate' => 'boolean',
55            'approval_status' => 'string',
56            'approved_at' => 'datetime',
57            'fetched_at' => 'datetime',
58            'validated_at' => 'datetime',
59            'created_at' => 'datetime',
60            'updated_at' => 'datetime',
61        ];
62    }
63
64    public function isValid(): bool
65    {
66        if (is_null($this->validated_at)) {
67            return false;
68        }
69
70        if (is_null($this->is_valid)) {
71            return false;
72        }
73
74        return $this->is_valid;
75    }
76
77    public function isApproved(): bool
78    {
79        return $this->approval_status === 'approved';
80    }
81
82    public function isPending(): bool
83    {
84        return $this->approval_status === 'pending';
85    }
86
87    public function isRejected(): bool
88    {
89        return $this->approval_status === 'rejected';
90    }
91
92    public function approve(string $approvedBy = null): void
93    {
94        $this->update([
95            'approval_status' => 'approved',
96            'approved_at' => now(),
97            'approved_by' => $approvedBy,
98        ]);
99
100        // Fire event to trigger publishing
101        event(new ArticleApproved($this));
102    }
103
104    public function reject(string $rejectedBy = null): void
105    {
106        $this->update([
107            'approval_status' => 'rejected',
108            'approved_at' => now(),
109            'approved_by' => $rejectedBy,
110        ]);
111    }
112
113    public function canBePublished(): bool
114    {
115        if (!$this->isValid()) {
116            return false;
117        }
118
119        // If approval system is disabled, auto-approve valid articles
120        if (!\App\Models\Setting::isPublishingApprovalsEnabled()) {
121            return true;
122        }
123
124        // If approval system is enabled, only approved articles can be published
125        return $this->isApproved();
126    }
127
128    /**
129     * @return HasOne<ArticlePublication, $this>
130     */
131    public function articlePublication(): HasOne
132    {
133        return $this->hasOne(ArticlePublication::class);
134    }
135
136    /**
137     * @return BelongsTo<Feed, $this>
138     */
139    public function feed(): BelongsTo
140    {
141        return $this->belongsTo(Feed::class);
142    }
143
144    protected static function booted(): void
145    {
146        static::created(function ($article) {
147            event(new NewArticleFetched($article));
148        });
149    }
150}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:53:46 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-final/Models/ArticlePublication.php.html b/backend/coverage-report-final/Models/ArticlePublication.php.html deleted file mode 100644 index 26ce2bcd..00000000 --- a/backend/coverage-report-final/Models/ArticlePublication.php.html +++ /dev/null @@ -1,196 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Models/ArticlePublication.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
ArticlePublication
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 article
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Models;
4
5use Database\Factories\ArticlePublicationFactory;
6use Illuminate\Database\Eloquent\Factories\HasFactory;
7use Illuminate\Database\Eloquent\Model;
8use Illuminate\Database\Eloquent\Relations\BelongsTo;
9
10/**
11 * @property integer $article_id
12 * @property integer $platform_channel_id
13 * @property integer $post_id
14 *
15 * @method static create(array<string, mixed> $array)
16 */
17class ArticlePublication extends Model
18{
19    /** @use HasFactory<ArticlePublicationFactory> */
20    use HasFactory;
21    
22    protected $fillable = [
23        'article_id',
24        'platform_channel_id',
25        'post_id',
26        'published_at',
27        'published_by',
28        'platform',
29        'publication_data',
30    ];
31
32    protected $casts = [
33        'published_at' => 'datetime',
34        'publication_data' => 'array',
35    ];
36
37    /**
38     * @return BelongsTo<Article, $this>
39     */
40    public function article(): BelongsTo
41    {
42        return $this->belongsTo(Article::class);
43    }
44}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:53:46 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-final/Models/Feed.php.html b/backend/coverage-report-final/Models/Feed.php.html deleted file mode 100644 index 22baf31b..00000000 --- a/backend/coverage-report-final/Models/Feed.php.html +++ /dev/null @@ -1,382 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Models/Feed.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 4.17% covered (danger) -
-
-
4.17%
1 / 24
-
- 16.67% covered (danger) -
-
-
16.67%
1 / 6
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
Feed
-
- 4.17% covered (danger) -
-
-
4.17%
1 / 24
-
- 16.67% covered (danger) -
-
-
16.67%
1 / 6
161.74
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 getTypeDisplayAttribute
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 5
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
20
 getStatusAttribute
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 10
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
30
 channels
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 4
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 activeChannels
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 articles
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
1
 language
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Models;
4
5use Database\Factories\FeedFactory;
6use Illuminate\Database\Eloquent\Factories\HasFactory;
7use Illuminate\Database\Eloquent\Model;
8use Illuminate\Database\Eloquent\Relations\BelongsTo;
9use Illuminate\Database\Eloquent\Relations\BelongsToMany;
10use Illuminate\Database\Eloquent\Relations\HasMany;
11use Illuminate\Support\Carbon;
12
13/**
14 * @property int $id
15 * @property string $name
16 * @property string $url
17 * @property string $type
18 * @property int $language_id
19 * @property Language|null $language
20 * @property string $description
21 * @property array<string, mixed> $settings
22 * @property bool $is_active
23 * @property Carbon|null $last_fetched_at
24 * @property Carbon $created_at
25 * @property Carbon $updated_at
26 * @method static orderBy(string $string, string $string1)
27 * @method static where(string $string, true $true)
28 * @method static findOrFail(mixed $feed_id)
29 */
30class Feed extends Model
31{
32    /** @use HasFactory<FeedFactory> */
33    use HasFactory;
34    private const RECENT_FETCH_THRESHOLD_HOURS = 2;
35    private const DAILY_FETCH_THRESHOLD_HOURS = 24;
36
37    protected $fillable = [
38        'name',
39        'url',
40        'type',
41        'language_id',
42        'description',
43        'settings',
44        'is_active',
45        'last_fetched_at'
46    ];
47
48    protected $casts = [
49        'settings' => 'array',
50        'is_active' => 'boolean',
51        'last_fetched_at' => 'datetime'
52    ];
53
54    public function getTypeDisplayAttribute(): string
55    {
56        return match ($this->type) {
57            'website' => 'Website',
58            'rss' => 'RSS Feed',
59            default => 'Unknown'
60        };
61    }
62
63    public function getStatusAttribute(): string
64    {
65        if (!$this->is_active) {
66            return 'Inactive';
67        }
68
69        if (!$this->last_fetched_at) {
70            return 'Never fetched';
71        }
72
73        $hoursAgo = $this->last_fetched_at->diffInHours(now());
74
75        if ($hoursAgo < self::RECENT_FETCH_THRESHOLD_HOURS) {
76            return 'Recently fetched';
77        } elseif ($hoursAgo < self::DAILY_FETCH_THRESHOLD_HOURS) {
78            return "Fetched {$hoursAgo}h ago";
79        } else {
80            return "Fetched " . $this->last_fetched_at->diffForHumans();
81        }
82    }
83
84    /**
85     * @return BelongsToMany<PlatformChannel, $this, Route>
86     */
87    public function channels(): BelongsToMany
88    {
89        return $this->belongsToMany(PlatformChannel::class, 'routes')
90            ->using(Route::class)
91            ->withPivot(['is_active', 'priority', 'filters'])
92            ->withTimestamps();
93    }
94
95    /**
96     * @return BelongsToMany<PlatformChannel, $this, Route>
97     */
98    public function activeChannels(): BelongsToMany
99    {
100        return $this->channels()
101            ->wherePivot('is_active', true)
102            ->orderByPivot('priority', 'desc');
103    }
104
105    /**
106     * @return HasMany<Article, $this>
107     */
108    public function articles(): HasMany
109    {
110        return $this->hasMany(Article::class);
111    }
112
113    /**
114     * @return BelongsTo<Language, $this>
115     */
116    public function language(): BelongsTo
117    {
118        return $this->belongsTo(Language::class);
119    }
120}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:53:46 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-final/Models/Keyword.php.html b/backend/coverage-report-final/Models/Keyword.php.html deleted file mode 100644 index ac31cb2e..00000000 --- a/backend/coverage-report-final/Models/Keyword.php.html +++ /dev/null @@ -1,223 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Models/Keyword.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
Keyword
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
6
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 feed
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 platformChannel
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Models;
4
5use Illuminate\Database\Eloquent\Model;
6use Illuminate\Database\Eloquent\Relations\BelongsTo;
7use Illuminate\Support\Carbon;
8
9/**
10 * @property int $id
11 * @property int $feed_id
12 * @property Feed $feed
13 * @property int $platform_channel_id
14 * @property PlatformChannel $platformChannel
15 * @property string $keyword
16 * @property bool $is_active
17 * @property Carbon $created_at
18 * @property Carbon $updated_at
19 */
20class Keyword extends Model
21{
22    protected $fillable = [
23        'feed_id',
24        'platform_channel_id',
25        'keyword',
26        'is_active'
27    ];
28
29    protected $casts = [
30        'is_active' => 'boolean'
31    ];
32
33    /**
34     * @return BelongsTo<Feed, $this>
35     */
36    public function feed(): BelongsTo
37    {
38        return $this->belongsTo(Feed::class);
39    }
40
41    /**
42     * @return BelongsTo<PlatformChannel, $this>
43     */
44    public function platformChannel(): BelongsTo
45    {
46        return $this->belongsTo(PlatformChannel::class);
47    }
48
49}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:53:46 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-final/Models/Language.php.html b/backend/coverage-report-final/Models/Language.php.html deleted file mode 100644 index bbe9ed5e..00000000 --- a/backend/coverage-report-final/Models/Language.php.html +++ /dev/null @@ -1,248 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Models/Language.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 5
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
Language
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 5
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
12
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 platformInstances
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 platformChannels
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 feeds
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Models;
4
5use Database\Factories\LanguageFactory;
6use Illuminate\Database\Eloquent\Factories\HasFactory;
7use Illuminate\Database\Eloquent\Model;
8use Illuminate\Database\Eloquent\Relations\BelongsToMany;
9use Illuminate\Database\Eloquent\Relations\HasMany;
10
11class Language extends Model
12{
13    /** @use HasFactory<LanguageFactory> */
14    use HasFactory;
15
16    protected $fillable = [
17        'short_code',
18        'name', 
19        'native_name',
20        'is_active'
21    ];
22
23    protected $casts = [
24        'is_active' => 'boolean'
25    ];
26
27    /**
28     * @return BelongsToMany<PlatformInstance, $this>
29     */
30    public function platformInstances(): BelongsToMany
31    {
32        return $this->belongsToMany(PlatformInstance::class)
33            ->withPivot(['platform_language_id', 'is_default'])
34            ->withTimestamps();
35    }
36
37    /**
38     * @return HasMany<PlatformChannel, $this>
39     */
40    public function platformChannels(): HasMany
41    {
42        return $this->hasMany(PlatformChannel::class);
43    }
44
45    /**
46     * @return HasMany<Feed, $this>
47     */
48    public function feeds(): HasMany
49    {
50        return $this->hasMany(Feed::class);
51    }
52}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:53:46 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-final/Models/Log.php.html b/backend/coverage-report-final/Models/Log.php.html deleted file mode 100644 index a5aac4c3..00000000 --- a/backend/coverage-report-final/Models/Log.php.html +++ /dev/null @@ -1,136 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Models/Log.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
n/a
0 / 0
n/a
0 / 0
CRAP
n/a
0 / 0
Log
n/a
0 / 0
n/a
0 / 0
0
n/a
0 / 0
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Models;
4
5use App\LogLevelEnum;
6use Illuminate\Database\Eloquent\Factories\HasFactory;
7use Illuminate\Database\Eloquent\Model;
8use Illuminate\Support\Carbon;
9
10/**
11 * @method static create(array<string, mixed> $array)
12 * @property LogLevelEnum $level
13 * @property string $message
14 * @property array<string, mixed> $context
15 * @property Carbon $created_at
16 * @property Carbon $updated_at
17 */
18class Log extends Model
19{
20    use HasFactory;
21    
22    protected $table = 'logs';
23
24    protected $fillable = [
25        'level',
26        'message',
27        'context',
28    ];
29
30    protected $casts = [
31        'level' => LogLevelEnum::class,
32        'context' => 'array',
33        'created_at' => 'datetime',
34        'updated_at' => 'datetime',
35    ];
36}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:53:46 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-final/Models/PlatformAccount.php.html b/backend/coverage-report-final/Models/PlatformAccount.php.html deleted file mode 100644 index 66cf6b48..00000000 --- a/backend/coverage-report-final/Models/PlatformAccount.php.html +++ /dev/null @@ -1,384 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Models/PlatformAccount.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 21
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 6
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
PlatformAccount
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 21
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 6
110
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 password
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 4
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
12
 apiToken
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 4
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
12
 getActive
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 setAsActive
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 4
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 channels
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 activeChannels
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Models;
4
5use Database\Factories\PlatformAccountFactory;
6use Illuminate\Database\Eloquent\Factories\HasFactory;
7use Illuminate\Database\Eloquent\Model;
8use Illuminate\Database\Eloquent\Casts\Attribute;
9use Illuminate\Database\Eloquent\Collection;
10use Illuminate\Database\Eloquent\Relations\BelongsToMany;
11use Illuminate\Support\Carbon;
12use Illuminate\Support\Facades\Crypt;
13use App\Enums\PlatformEnum;
14
15/**
16 * @property int $id
17 * @property PlatformEnum $platform
18 * @property string $instance_url
19 * @property string $username
20 * @property string $password
21 * @property string $settings
22 * @property bool $is_active
23 * @property Carbon $last_tested_at
24 * @property string $status
25 * @property Carbon $created_at
26 * @property Carbon $updated_at
27 * @property Collection<int, PlatformChannel> $activeChannels
28 * @method static where(string $string, PlatformEnum $platform)
29 * @method static orderBy(string $string)
30 * @method static create(array<string, mixed> $validated)
31 */
32class PlatformAccount extends Model
33{
34    /** @use HasFactory<PlatformAccountFactory> */
35    use HasFactory;
36
37    protected $fillable = [
38        'platform',
39        'instance_url',
40        'username',
41        'password',
42        'api_token',
43        'settings',
44        'is_active',
45        'last_tested_at',
46        'status'
47    ];
48
49    protected $casts = [
50        'platform' => PlatformEnum::class,
51        'settings' => 'array',
52        'is_active' => 'boolean',
53        'last_tested_at' => 'datetime'
54    ];
55
56    // Encrypt password when storing
57    /**
58     * @return Attribute<string|null, string|null>
59     */
60    protected function password(): Attribute
61    {
62        return Attribute::make(
63            get: fn ($value) => $value ? Crypt::decryptString($value) : null,
64            set: fn ($value) => $value ? Crypt::encryptString($value) : null,
65        );
66    }
67
68    // Encrypt API token when storing
69    /**
70     * @return Attribute<string|null, string|null>
71     */
72    protected function apiToken(): Attribute
73    {
74        return Attribute::make(
75            get: fn ($value) => $value ? Crypt::decryptString($value) : null,
76            set: fn ($value) => $value ? Crypt::encryptString($value) : null,
77        );
78    }
79
80    // Get the active accounts for a platform (returns collection)
81    /**
82     * @return Collection<int, PlatformAccount>
83     */
84    public static function getActive(PlatformEnum $platform): Collection
85    {
86        return static::where('platform', $platform)
87            ->where('is_active', true)
88            ->get();
89    }
90
91    // Set this account as active (deactivates others for same platform)
92    public function setAsActive(): void
93    {
94        // Deactivate other accounts for this platform
95        static::where('platform', $this->platform)
96            ->where('id', '!=', $this->id)
97            ->update(['is_active' => false]);
98
99        // Activate this account
100        $this->update(['is_active' => true]);
101    }
102
103    /**
104     * @return BelongsToMany<PlatformChannel, $this>
105     */
106    public function channels(): BelongsToMany
107    {
108        return $this->belongsToMany(PlatformChannel::class, 'platform_account_channels')
109            ->withPivot(['is_active', 'priority'])
110            ->withTimestamps();
111    }
112
113    /**
114     * @return BelongsToMany<PlatformChannel, $this>
115     */
116    public function activeChannels(): BelongsToMany
117    {
118        return $this->channels()
119            ->wherePivot('is_active', true)
120            ->orderByPivot('priority', 'desc');
121    }
122}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:53:46 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-final/Models/PlatformChannel.php.html b/backend/coverage-report-final/Models/PlatformChannel.php.html deleted file mode 100644 index 95881ac9..00000000 --- a/backend/coverage-report-final/Models/PlatformChannel.php.html +++ /dev/null @@ -1,387 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Models/PlatformChannel.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 14
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 7
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
PlatformChannel
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 14
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 7
56
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 platformInstance
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 platformAccounts
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 activePlatformAccounts
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 getFullNameAttribute
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 feeds
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 4
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 activeFeeds
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 language
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Models;
4
5use Database\Factories\PlatformChannelFactory;
6use Illuminate\Database\Eloquent\Factories\HasFactory;
7use Illuminate\Database\Eloquent\Model;
8use Illuminate\Database\Eloquent\Relations\BelongsTo;
9use Illuminate\Database\Eloquent\Relations\BelongsToMany;
10
11/**
12 * @method static findMany(mixed $channel_ids)
13 * @property integer $id
14 * @property integer $platform_instance_id
15 * @property PlatformInstance $platformInstance
16 * @property integer $channel_id
17 * @property string $name
18 * @property int $language_id
19 * @property Language|null $language
20 * @property boolean $is_active
21 */
22class PlatformChannel extends Model
23{
24    /** @use HasFactory<PlatformChannelFactory> */
25    use HasFactory;
26
27    protected $table = 'platform_channels';
28
29    protected $fillable = [
30        'platform_instance_id',
31        'name',
32        'display_name',
33        'channel_id',
34        'description',
35        'language_id',
36        'is_active'
37    ];
38
39    protected $casts = [
40        'is_active' => 'boolean'
41    ];
42
43    /**
44     * @return BelongsTo<PlatformInstance, $this>
45     */
46    public function platformInstance(): BelongsTo
47    {
48        return $this->belongsTo(PlatformInstance::class);
49    }
50
51    /**
52     * @return BelongsToMany<PlatformAccount, $this>
53     */
54    public function platformAccounts(): BelongsToMany
55    {
56        return $this->belongsToMany(PlatformAccount::class, 'platform_account_channels')
57            ->withPivot(['is_active', 'priority'])
58            ->withTimestamps();
59    }
60
61    /**
62     * @return BelongsToMany<PlatformAccount, $this>
63     */
64    public function activePlatformAccounts(): BelongsToMany
65    {
66        return $this->platformAccounts()->wherePivot('is_active', true);
67    }
68
69    public function getFullNameAttribute(): string
70    {
71        // For Lemmy, use /c/ prefix
72        return $this->platformInstance->url . '/c/' . $this->name;
73    }
74
75    /**
76     * @return BelongsToMany<Feed, $this, Route>
77     */
78    public function feeds(): BelongsToMany
79    {
80        return $this->belongsToMany(Feed::class, 'routes')
81            ->using(Route::class)
82            ->withPivot(['is_active', 'priority', 'filters'])
83            ->withTimestamps();
84    }
85
86    /**
87     * @return BelongsToMany<Feed, $this, Route>
88     */
89    public function activeFeeds(): BelongsToMany
90    {
91        return $this->feeds()
92            ->wherePivot('is_active', true)
93            ->orderByPivot('priority', 'desc');
94    }
95
96    /**
97     * @return BelongsTo<Language, $this>
98     */
99    public function language(): BelongsTo
100    {
101        return $this->belongsTo(Language::class);
102    }
103}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:53:46 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-final/Models/PlatformChannelPost.php.html b/backend/coverage-report-final/Models/PlatformChannelPost.php.html deleted file mode 100644 index 3e85681f..00000000 --- a/backend/coverage-report-final/Models/PlatformChannelPost.php.html +++ /dev/null @@ -1,255 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Models/PlatformChannelPost.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 21
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
PlatformChannelPost
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 21
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
12
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 casts
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 4
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 urlExists
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 4
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 storePost
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 13
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Models;
4
5use App\Enums\PlatformEnum;
6use Illuminate\Database\Eloquent\Model;
7
8/**
9 * @method static where(string $string, PlatformEnum $platform)
10 * @method static updateOrCreate(array<string, mixed> $array, array<string, mixed> $array1)
11 */
12class PlatformChannelPost extends Model
13{
14    protected $fillable = [
15        'platform',
16        'channel_id',
17        'channel_name',
18        'post_id',
19        'url',
20        'title',
21        'posted_at',
22    ];
23
24    /**
25     * @return array<string, string>
26     */
27    protected function casts(): array
28    {
29        return [
30            'posted_at' => 'datetime',
31            'platform' => PlatformEnum::class,
32        ];
33    }
34
35    public static function urlExists(PlatformEnum $platform, string $channelId, string $url): bool
36    {
37        return self::where('platform', $platform)
38            ->where('channel_id', $channelId)
39            ->where('url', $url)
40            ->exists();
41    }
42
43    public static function storePost(PlatformEnum $platform, string $channelId, ?string $channelName, string $postId, ?string $url, ?string $title, ?\DateTime $postedAt = null): self
44    {
45        return self::updateOrCreate(
46            [
47                'platform' => $platform,
48                'channel_id' => $channelId,
49                'post_id' => $postId,
50            ],
51            [
52                'channel_name' => $channelName,
53                'url' => $url,
54                'title' => $title,
55                'posted_at' => $postedAt ?? now(),
56            ]
57        );
58    }
59}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:53:46 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-final/Models/PlatformInstance.php.html b/backend/coverage-report-final/Models/PlatformInstance.php.html deleted file mode 100644 index 2e411cee..00000000 --- a/backend/coverage-report-final/Models/PlatformInstance.php.html +++ /dev/null @@ -1,259 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Models/PlatformInstance.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 7
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
PlatformInstance
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 7
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
12
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 channels
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 languages
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 findByUrl
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Models;
4
5use App\Enums\PlatformEnum;
6use Database\Factories\PlatformInstanceFactory;
7use Illuminate\Database\Eloquent\Factories\HasFactory;
8use Illuminate\Database\Eloquent\Model;
9use Illuminate\Database\Eloquent\Relations\BelongsToMany;
10use Illuminate\Database\Eloquent\Relations\HasMany;
11
12/**
13 * @method static updateOrCreate(array<string, mixed> $array, $instanceData)
14 * @method static where(string $string, mixed $operator)
15 * @property PlatformEnum $platform
16 * @property string $url
17 * @property string $name
18 * @property string $description
19 * @property boolean $is_active
20 */
21class PlatformInstance extends Model
22{
23    /** @use HasFactory<PlatformInstanceFactory> */
24    use HasFactory;
25    
26    protected $fillable = [
27        'platform',
28        'url',
29        'name',
30        'description',
31        'is_active'
32    ];
33
34    protected $casts = [
35        'platform' => PlatformEnum::class,
36        'is_active' => 'boolean'
37    ];
38
39    /**
40     * @return HasMany<PlatformChannel, $this>
41     */
42    public function channels(): HasMany
43    {
44        return $this->hasMany(PlatformChannel::class);
45    }
46
47    /**
48     * @return BelongsToMany<Language, $this>
49     */
50    public function languages(): BelongsToMany
51    {
52        return $this->belongsToMany(Language::class)
53            ->withPivot(['platform_language_id', 'is_default'])
54            ->withTimestamps();
55    }
56
57    public static function findByUrl(PlatformEnum $platform, string $url): ?self
58    {
59        return static::where('platform', $platform)
60            ->where('url', $url)
61            ->first();
62    }
63}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:53:46 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-final/Models/Route.php.html b/backend/coverage-report-final/Models/Route.php.html deleted file mode 100644 index f4bf48c5..00000000 --- a/backend/coverage-report-final/Models/Route.php.html +++ /dev/null @@ -1,263 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Models/Route.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 4
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
Route
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 4
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
12
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 feed
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 platformChannel
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 keywords
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Models;
4
5use Database\Factories\RouteFactory;
6use Illuminate\Database\Eloquent\Factories\HasFactory;
7use Illuminate\Database\Eloquent\Relations\BelongsTo;
8use Illuminate\Database\Eloquent\Relations\HasMany;
9use Illuminate\Database\Eloquent\Relations\Pivot;
10use Illuminate\Support\Carbon;
11
12/**
13 * @property int $feed_id
14 * @property int $platform_channel_id
15 * @property bool $is_active
16 * @property int $priority
17 * @property array<string, mixed> $filters
18 * @property Carbon $created_at
19 * @property Carbon $updated_at
20 */
21class Route extends Pivot
22{
23    /** @use HasFactory<RouteFactory> */
24    use HasFactory;
25    
26    protected $table = 'routes';
27
28    public $incrementing = false;
29
30    protected $fillable = [
31        'feed_id',
32        'platform_channel_id',
33        'is_active',
34        'priority',
35        'filters'
36    ];
37
38    protected $casts = [
39        'is_active' => 'boolean',
40        'filters' => 'array'
41    ];
42
43    /**
44     * @return BelongsTo<Feed, $this>
45     */
46    public function feed(): BelongsTo
47    {
48        return $this->belongsTo(Feed::class);
49    }
50
51    /**
52     * @return BelongsTo<PlatformChannel, $this>
53     */
54    public function platformChannel(): BelongsTo
55    {
56        return $this->belongsTo(PlatformChannel::class);
57    }
58
59    /**
60     * @return HasMany<Keyword, $this>
61     */
62    public function keywords(): HasMany
63    {
64        return $this->hasMany(Keyword::class, 'feed_id', 'feed_id')
65            ->where('platform_channel_id', $this->platform_channel_id);
66    }
67}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:53:46 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-final/Models/Setting.php.html b/backend/coverage-report-final/Models/Setting.php.html deleted file mode 100644 index 1f6b00f3..00000000 --- a/backend/coverage-report-final/Models/Setting.php.html +++ /dev/null @@ -1,360 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Models/Setting.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 100.00% covered (success) -
-
-
100.00%
10 / 10
-
- 100.00% covered (success) -
-
-
100.00%
8 / 8
CRAP
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
Setting
-
- 100.00% covered (success) -
-
-
100.00%
10 / 10
-
- 100.00% covered (success) -
-
-
100.00%
8 / 8
10
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
 get
-
- 100.00% covered (success) -
-
-
100.00%
2 / 2
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
2
 set
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
1
 getBool
-
- 100.00% covered (success) -
-
-
100.00%
2 / 2
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
1
 setBool
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
2
 isArticleProcessingEnabled
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
1
 setArticleProcessingEnabled
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
1
 isPublishingApprovalsEnabled
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
1
 setPublishingApprovalsEnabled
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
1
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Models;
4
5use Illuminate\Database\Eloquent\Model;
6
7class Setting extends Model
8{
9    protected $fillable = ['key', 'value'];
10
11    public static function get(string $key, mixed $default = null): mixed
12    {
13        $setting = static::where('key', $key)->first();
14        
15        return $setting ? $setting->value : $default;
16    }
17
18    public static function set(string $key, mixed $value): void
19    {
20        static::updateOrCreate(['key' => $key], ['value' => $value]);
21    }
22
23    public static function getBool(string $key, bool $default = false): bool
24    {
25        $value = static::get($key, $default);
26        
27        return filter_var($value, FILTER_VALIDATE_BOOLEAN);
28    }
29
30    public static function setBool(string $key, bool $value): void
31    {
32        static::set($key, $value ? '1' : '0');
33    }
34
35    public static function isArticleProcessingEnabled(): bool
36    {
37        return static::getBool('article_processing_enabled', true);
38    }
39
40    public static function setArticleProcessingEnabled(bool $enabled): void
41    {
42        static::setBool('article_processing_enabled', $enabled);
43    }
44
45    public static function isPublishingApprovalsEnabled(): bool
46    {
47        return static::getBool('enable_publishing_approvals', false);
48    }
49
50    public static function setPublishingApprovalsEnabled(bool $enabled): void
51    {
52        static::setBool('enable_publishing_approvals', $enabled);
53    }
54}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:53:46 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-final/Models/User.php.html b/backend/coverage-report-final/Models/User.php.html deleted file mode 100644 index b2d13ba0..00000000 --- a/backend/coverage-report-final/Models/User.php.html +++ /dev/null @@ -1,201 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Models/User.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 4
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
User
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 4
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 casts
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 4
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Models;
4
5// use Illuminate\Contracts\Auth\MustVerifyEmail;
6use Illuminate\Database\Eloquent\Factories\HasFactory;
7use Illuminate\Foundation\Auth\User as Authenticatable;
8use Illuminate\Notifications\Notifiable;
9use Laravel\Sanctum\HasApiTokens;
10
11class User extends Authenticatable
12{
13    /** @use HasFactory<\Database\Factories\UserFactory> */
14    use HasFactory, Notifiable, HasApiTokens;
15
16    /**
17     * The attributes that are mass assignable.
18     *
19     * @var list<string>
20     */
21    protected $fillable = [
22        'name',
23        'email',
24        'password',
25    ];
26
27    /**
28     * The attributes that should be hidden for serialization.
29     *
30     * @var list<string>
31     */
32    protected $hidden = [
33        'password',
34        'remember_token',
35    ];
36
37    /**
38     * Get the attributes that should be cast.
39     *
40     * @return array<string, string>
41     */
42    protected function casts(): array
43    {
44        return [
45            'email_verified_at' => 'datetime',
46            'password' => 'hashed',
47        ];
48    }
49}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:53:46 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-final/Models/dashboard.html b/backend/coverage-report-final/Models/dashboard.html deleted file mode 100644 index 1e68672c..00000000 --- a/backend/coverage-report-final/Models/dashboard.html +++ /dev/null @@ -1,334 +0,0 @@ - - - - - Dashboard for /var/www/html/backend/app/Models - - - - - - - -
-
-
-
- -
-
-
-
-
-
-
-

Classes

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
-
- -
-

Project Risks

-
- - - - - - - - - - - - -
ClassCRAP
App\Models\Feed161
App\Models\PlatformAccount110
-
-
-
-
-
-

Methods

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
- - -
- - - - - - diff --git a/backend/coverage-report-final/Models/index.html b/backend/coverage-report-final/Models/index.html deleted file mode 100644 index ec2e7801..00000000 --- a/backend/coverage-report-final/Models/index.html +++ /dev/null @@ -1,440 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Models - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 32.89% covered (danger) -
-
-
32.89%
50 / 152
-
- 37.04% covered (danger) -
-
-
37.04%
20 / 54
-
- 16.67% covered (danger) -
-
-
16.67%
2 / 12
Article.php
-
- 100.00% covered (success) -
-
-
100.00%
39 / 39
-
- 100.00% covered (success) -
-
-
100.00%
11 / 11
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
ArticlePublication.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
Feed.php
-
- 4.17% covered (danger) -
-
-
4.17%
1 / 24
-
- 16.67% covered (danger) -
-
-
16.67%
1 / 6
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
Keyword.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
Language.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 5
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
Log.php
n/a
0 / 0
n/a
0 / 0
n/a
0 / 0
PlatformAccount.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 21
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 6
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
PlatformChannel.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 14
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 7
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
PlatformChannelPost.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 21
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
PlatformInstance.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 7
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
Route.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 4
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
Setting.php
-
- 100.00% covered (success) -
-
-
100.00%
10 / 10
-
- 100.00% covered (success) -
-
-
100.00%
8 / 8
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
User.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 4
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- -
- - diff --git a/backend/coverage-report-final/Modules/Lemmy/LemmyRequest.php.html b/backend/coverage-report-final/Modules/Lemmy/LemmyRequest.php.html deleted file mode 100644 index 71ec21e7..00000000 --- a/backend/coverage-report-final/Modules/Lemmy/LemmyRequest.php.html +++ /dev/null @@ -1,275 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Modules/Lemmy/LemmyRequest.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 14
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 4
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
LemmyRequest
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 14
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 4
42
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 __construct
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 get
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 5
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
6
 post
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 5
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
6
 withToken
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Modules\Lemmy;
4
5use Illuminate\Support\Facades\Http;
6use Illuminate\Http\Client\Response;
7
8class LemmyRequest
9{
10    private string $instance;
11    private ?string $token;
12
13    public function __construct(string $instance, ?string $token = null)
14    {
15        $this->instance = $instance;
16        $this->token = $token;
17    }
18
19    /**
20     * @param array<string, mixed> $params
21     */
22    public function get(string $endpoint, array $params = []): Response
23    {
24        $url = "https://{$this->instance}/api/v3/{$endpoint}";
25        
26        $request = Http::timeout(30);
27        
28        if ($this->token) {
29            $request = $request->withToken($this->token);
30        }
31        
32        return $request->get($url, $params);
33    }
34
35    /**
36     * @param array<string, mixed> $data
37     */
38    public function post(string $endpoint, array $data = []): Response
39    {
40        $url = "https://{$this->instance}/api/v3/{$endpoint}";
41        
42        $request = Http::timeout(30);
43        
44        if ($this->token) {
45            $request = $request->withToken($this->token);
46        }
47        
48        return $request->post($url, $data);
49    }
50
51    public function withToken(string $token): self
52    {
53        $this->token = $token;
54        return $this;
55    }
56}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:53:46 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-final/Modules/Lemmy/Services/LemmyApiService.php.html b/backend/coverage-report-final/Modules/Lemmy/Services/LemmyApiService.php.html deleted file mode 100644 index f3977652..00000000 --- a/backend/coverage-report-final/Modules/Lemmy/Services/LemmyApiService.php.html +++ /dev/null @@ -1,438 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Modules/Lemmy/Services/LemmyApiService.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 93
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 6
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
LemmyApiService
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 93
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 6
462
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 __construct
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 login
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 16
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
12
 getCommunityId
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 9
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
12
 syncChannelPosts
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 34
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
30
 createPost
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 19
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
42
 getLanguages
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 14
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
12
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Modules\Lemmy\Services;
4
5use App\Enums\PlatformEnum;
6use App\Models\PlatformChannelPost;
7use App\Modules\Lemmy\LemmyRequest;
8use Exception;
9
10class LemmyApiService
11{
12    private string $instance;
13
14    public function __construct(string $instance)
15    {
16        $this->instance = $instance;
17    }
18
19    public function login(string $username, string $password): ?string
20    {
21        try {
22            $request = new LemmyRequest($this->instance);
23            $response = $request->post('user/login', [
24                'username_or_email' => $username,
25                'password' => $password,
26            ]);
27
28            if (!$response->successful()) {
29                logger()->error('Lemmy login failed', [
30                    'status' => $response->status(),
31                    'body' => $response->body()
32                ]);
33                return null;
34            }
35
36            $data = $response->json();
37            return $data['jwt'] ?? null;
38        } catch (Exception $e) {
39            logger()->error('Lemmy login exception', ['error' => $e->getMessage()]);
40            return null;
41        }
42    }
43
44    public function getCommunityId(string $communityName, string $token): int
45    {
46        try {
47            $request = new LemmyRequest($this->instance, $token);
48            $response = $request->get('community', ['name' => $communityName]);
49
50            if (!$response->successful()) {
51                throw new Exception('Failed to fetch community: ' . $response->status());
52            }
53
54            $data = $response->json();
55            return $data['community_view']['community']['id'] ?? throw new Exception('Community not found');
56        } catch (Exception $e) {
57            logger()->error('Community lookup failed', ['error' => $e->getMessage()]);
58            throw $e;
59        }
60    }
61
62    public function syncChannelPosts(string $token, int $platformChannelId, string $communityName): void
63    {
64        try {
65            $request = new LemmyRequest($this->instance, $token);
66            $response = $request->get('post/list', [
67                'community_id' => $platformChannelId,
68                'limit' => 50,
69                'sort' => 'New'
70            ]);
71
72            if (!$response->successful()) {
73                logger()->warning('Failed to sync channel posts', [
74                    'status' => $response->status(),
75                    'platform_channel_id' => $platformChannelId
76                ]);
77                return;
78            }
79
80            $data = $response->json();
81            $posts = $data['posts'] ?? [];
82
83            foreach ($posts as $postData) {
84                $post = $postData['post'];
85
86                PlatformChannelPost::storePost(
87                    PlatformEnum::LEMMY,
88                    (string) $platformChannelId,
89                    $communityName,
90                    (string) $post['id'],
91                    $post['url'] ?? null,
92                    $post['name'] ?? null,
93                    isset($post['published']) ? new \DateTime($post['published']) : null
94                );
95            }
96
97            logger()->info('Synced channel posts', [
98                'platform_channel_id' => $platformChannelId,
99                'posts_count' => count($posts)
100            ]);
101
102        } catch (Exception $e) {
103            logger()->error('Exception while syncing channel posts', [
104                'error' => $e->getMessage(),
105                'platform_channel_id' => $platformChannelId
106            ]);
107        }
108    }
109
110    /**
111     * @return array<string, mixed>
112     */
113    public function createPost(string $token, string $title, string $body, int $platformChannelId, ?string $url = null, ?string $thumbnail = null, ?int $languageId = null): array
114    {
115        try {
116            $request = new LemmyRequest($this->instance, $token);
117
118            $postData = [
119                'name' => $title,
120                'body' => $body,
121                'community_id' => $platformChannelId,
122            ];
123
124            if ($url) {
125                $postData['url'] = $url;
126            }
127
128            if ($thumbnail) {
129                $postData['custom_thumbnail'] = $thumbnail;
130            }
131
132            if ($languageId) {
133                $postData['language_id'] = $languageId;
134            }
135
136            $response = $request->post('post', $postData);
137
138            if (!$response->successful()) {
139                throw new Exception('Failed to create post: ' . $response->status() . ' - ' . $response->body());
140            }
141
142            return $response->json();
143        } catch (Exception $e) {
144            logger()->error('Post creation failed', ['error' => $e->getMessage()]);
145            throw $e;
146        }
147    }
148
149    /**
150     * @return array<int, mixed>
151     */
152    public function getLanguages(): array
153    {
154        try {
155            $request = new LemmyRequest($this->instance);
156            $response = $request->get('site');
157
158            if (!$response->successful()) {
159                logger()->warning('Failed to fetch site languages', [
160                    'status' => $response->status()
161                ]);
162                return [];
163            }
164
165            $data = $response->json();
166            return $data['all_languages'] ?? [];
167        } catch (Exception $e) {
168            logger()->error('Exception while fetching languages', [
169                'error' => $e->getMessage()
170            ]);
171            return [];
172        }
173    }
174}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:53:46 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-final/Modules/Lemmy/Services/LemmyPublisher.php.html b/backend/coverage-report-final/Modules/Lemmy/Services/LemmyPublisher.php.html deleted file mode 100644 index 3a2d8b1d..00000000 --- a/backend/coverage-report-final/Modules/Lemmy/Services/LemmyPublisher.php.html +++ /dev/null @@ -1,223 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Modules/Lemmy/Services/LemmyPublisher.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 13
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
LemmyPublisher
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 13
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
6
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 __construct
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 publishToChannel
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 11
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Modules\Lemmy\Services;
4
5use App\Exceptions\PlatformAuthException;
6use App\Models\Article;
7use App\Models\PlatformAccount;
8use App\Models\PlatformChannel;
9use App\Services\Auth\LemmyAuthService;
10use Exception;
11
12class LemmyPublisher
13{
14    private LemmyApiService $api;
15    private PlatformAccount $account;
16
17    public function __construct(PlatformAccount $account)
18    {
19        $this->api = new LemmyApiService($account->instance_url);
20        $this->account = $account;
21    }
22
23    /**
24     * @param array<string, mixed> $extractedData
25     * @return array<string, mixed>
26     * @throws PlatformAuthException
27     * @throws Exception
28     */
29    public function publishToChannel(Article $article, array $extractedData, PlatformChannel $channel): array
30    {
31        $token = LemmyAuthService::getToken($this->account);
32
33        // Use the language ID from extracted data (should be set during validation)
34        $languageId = $extractedData['language_id'] ?? null;
35
36        return $this->api->createPost(
37            $token,
38            $extractedData['title'] ?? 'Untitled',
39            $extractedData['description'] ?? '',
40            $channel->channel_id,
41            $article->url,
42            $extractedData['thumbnail'] ?? null,
43            $languageId
44        );
45    }
46
47}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:53:46 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-final/Modules/Lemmy/Services/dashboard.html b/backend/coverage-report-final/Modules/Lemmy/Services/dashboard.html deleted file mode 100644 index b8413596..00000000 --- a/backend/coverage-report-final/Modules/Lemmy/Services/dashboard.html +++ /dev/null @@ -1,302 +0,0 @@ - - - - - Dashboard for /var/www/html/backend/app/Modules/Lemmy/Services - - - - - - - -
-
-
-
- -
-
-
-
-
-
-
-

Classes

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
-
-
-

Insufficient Coverage

- -
-
-

Project Risks

-
- - - - - - - - - - - -
ClassCRAP
App\Modules\Lemmy\Services\LemmyApiService462
-
-
-
-
-
-

Methods

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
-
-
-

Insufficient Coverage

-
- - - - - - - - - - - - - - - - - - -
MethodCoverage
__construct0%
login0%
getCommunityId0%
syncChannelPosts0%
createPost0%
getLanguages0%
__construct0%
publishToChannel0%
-
-
-
-

Project Risks

-
- - - - - - - - - - - - - - - -
MethodCRAP
createPost42
syncChannelPosts30
login12
getCommunityId12
getLanguages12
-
-
-
- -
- - - - - - diff --git a/backend/coverage-report-final/Modules/Lemmy/Services/index.html b/backend/coverage-report-final/Modules/Lemmy/Services/index.html deleted file mode 100644 index c48fd492..00000000 --- a/backend/coverage-report-final/Modules/Lemmy/Services/index.html +++ /dev/null @@ -1,149 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Modules/Lemmy/Services - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 106
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 8
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
LemmyApiService.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 93
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 6
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
LemmyPublisher.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 13
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- -
- - diff --git a/backend/coverage-report-final/Modules/Lemmy/dashboard.html b/backend/coverage-report-final/Modules/Lemmy/dashboard.html deleted file mode 100644 index ee47fa13..00000000 --- a/backend/coverage-report-final/Modules/Lemmy/dashboard.html +++ /dev/null @@ -1,309 +0,0 @@ - - - - - Dashboard for /var/www/html/backend/app/Modules/Lemmy - - - - - - - -
-
-
-
- -
-
-
-
-
-
-
-

Classes

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
-
-
-

Insufficient Coverage

- -
-
-

Project Risks

- -
-
-
-
-

Methods

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
-
-
-

Insufficient Coverage

-
- - - - - - - - - - - - - - - - - - - - - - -
MethodCoverage
__construct0%
get0%
post0%
withToken0%
__construct0%
login0%
getCommunityId0%
syncChannelPosts0%
createPost0%
getLanguages0%
__construct0%
publishToChannel0%
-
-
-
-

Project Risks

-
- - - - - - - - - - - - - - - - - -
MethodCRAP
createPost42
syncChannelPosts30
login12
getCommunityId12
getLanguages12
get6
post6
-
-
-
- -
- - - - - - diff --git a/backend/coverage-report-final/Modules/Lemmy/index.html b/backend/coverage-report-final/Modules/Lemmy/index.html deleted file mode 100644 index 93159faf..00000000 --- a/backend/coverage-report-final/Modules/Lemmy/index.html +++ /dev/null @@ -1,148 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Modules/Lemmy - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 120
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 12
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
Services
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 106
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 8
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
LemmyRequest.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 14
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 4
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- -
- - diff --git a/backend/coverage-report-final/Modules/dashboard.html b/backend/coverage-report-final/Modules/dashboard.html deleted file mode 100644 index 9a00e534..00000000 --- a/backend/coverage-report-final/Modules/dashboard.html +++ /dev/null @@ -1,308 +0,0 @@ - - - - - Dashboard for /var/www/html/backend/app/Modules - - - - - - - -
-
-
-
- -
-
-
-
-
-
-
-

Classes

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
-
-
-

Insufficient Coverage

- -
-
-

Project Risks

- -
-
-
-
-

Methods

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
-
-
-

Insufficient Coverage

-
- - - - - - - - - - - - - - - - - - - - - - -
MethodCoverage
__construct0%
get0%
post0%
withToken0%
__construct0%
login0%
getCommunityId0%
syncChannelPosts0%
createPost0%
getLanguages0%
__construct0%
publishToChannel0%
-
-
-
-

Project Risks

-
- - - - - - - - - - - - - - - - - -
MethodCRAP
createPost42
syncChannelPosts30
login12
getCommunityId12
getLanguages12
get6
post6
-
-
-
- -
- - - - - - diff --git a/backend/coverage-report-final/Modules/index.html b/backend/coverage-report-final/Modules/index.html deleted file mode 100644 index 8be402fb..00000000 --- a/backend/coverage-report-final/Modules/index.html +++ /dev/null @@ -1,119 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Modules - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 120
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 12
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
Lemmy
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 120
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 12
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
-
- -
- - diff --git a/backend/coverage-report-final/Providers/AppServiceProvider.php.html b/backend/coverage-report-final/Providers/AppServiceProvider.php.html deleted file mode 100644 index c9c8ab8b..00000000 --- a/backend/coverage-report-final/Providers/AppServiceProvider.php.html +++ /dev/null @@ -1,260 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Providers/AppServiceProvider.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 82.76% covered (warning) -
-
-
82.76%
24 / 29
-
- 33.33% covered (danger) -
-
-
33.33%
1 / 3
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
AppServiceProvider
-
- 82.76% covered (warning) -
-
-
82.76%
24 / 29
-
- 33.33% covered (danger) -
-
-
33.33%
1 / 3
6.18
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 register
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
1
 boot
-
- 92.00% covered (success) -
-
-
92.00%
23 / 25
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
1.00
 mapExceptionToLogLevel
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
20
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Providers;
4
5use App\Events\ExceptionOccurred;
6use App\Listeners\LogExceptionToDatabase;
7use App\LogLevelEnum;
8use Error;
9use Illuminate\Contracts\Debug\ExceptionHandler;
10use Illuminate\Support\Facades\Event;
11use Illuminate\Support\ServiceProvider;
12use InvalidArgumentException;
13use Throwable;
14
15class AppServiceProvider extends ServiceProvider
16{
17    public function register(): void
18    {
19    }
20
21    public function boot(): void
22    {
23        Event::listen(
24            ExceptionOccurred::class,
25            LogExceptionToDatabase::class,
26        );
27
28        Event::listen(
29            \App\Events\NewArticleFetched::class,
30            \App\Listeners\ValidateArticleListener::class,
31        );
32
33        Event::listen(
34            \App\Events\ArticleApproved::class,
35            \App\Listeners\PublishApprovedArticle::class,
36        );
37
38        Event::listen(
39            \App\Events\ArticleReadyToPublish::class,
40            \App\Listeners\PublishArticle::class,
41        );
42
43        Event::listen(
44            \App\Events\ExceptionLogged::class,
45            \App\Listeners\LogExceptionToDatabase::class,
46        );
47
48        app()->make(ExceptionHandler::class)
49            ->reportable(function (Throwable $e) {
50                $level = $this->mapExceptionToLogLevel($e);
51
52                ExceptionOccurred::dispatch($e, $level, $e->getMessage(), []);
53            });
54    }
55
56    private function mapExceptionToLogLevel(Throwable $exception): LogLevelEnum
57    {
58        return match (true) {
59            $exception instanceof Error => LogLevelEnum::CRITICAL,
60            $exception instanceof InvalidArgumentException => LogLevelEnum::WARNING,
61            default => LogLevelEnum::ERROR,
62        };
63    }
64}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:53:46 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-final/Providers/HorizonServiceProvider.php.html b/backend/coverage-report-final/Providers/HorizonServiceProvider.php.html deleted file mode 100644 index 66d5bc42..00000000 --- a/backend/coverage-report-final/Providers/HorizonServiceProvider.php.html +++ /dev/null @@ -1,208 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Providers/HorizonServiceProvider.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 75.00% covered (warning) -
-
-
75.00%
3 / 4
-
- 50.00% covered (danger) -
-
-
50.00%
1 / 2
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
HorizonServiceProvider
-
- 75.00% covered (warning) -
-
-
75.00%
3 / 4
-
- 50.00% covered (danger) -
-
-
50.00%
1 / 2
2.06
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 boot
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
1
 gate
-
- 66.67% covered (warning) -
-
-
66.67%
2 / 3
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
1.04
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Providers;
4
5use Illuminate\Support\Facades\Gate;
6use Laravel\Horizon\Horizon;
7use Laravel\Horizon\HorizonApplicationServiceProvider;
8
9class HorizonServiceProvider extends HorizonApplicationServiceProvider
10{
11    /**
12     * Bootstrap any application services.
13     */
14    public function boot(): void
15    {
16        parent::boot();
17
18        // Horizon::routeSmsNotificationsTo('15556667777');
19        // Horizon::routeMailNotificationsTo('example@example.com');
20        // Horizon::routeSlackNotificationsTo('slack-webhook-url', '#channel');
21    }
22
23    /**
24     * Register the Horizon gate.
25     *
26     * This gate determines who can access Horizon in non-local environments.
27     */
28    protected function gate(): void
29    {
30        Gate::define('viewHorizon', function ($user = null) {
31            return true;
32        });
33    }
34}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:53:46 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-final/Providers/dashboard.html b/backend/coverage-report-final/Providers/dashboard.html deleted file mode 100644 index e197b0fc..00000000 --- a/backend/coverage-report-final/Providers/dashboard.html +++ /dev/null @@ -1,290 +0,0 @@ - - - - - Dashboard for /var/www/html/backend/app/Providers - - - - - - - -
-
-
-
- -
-
-
-
-
-
-
-

Classes

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
-
-
-

Insufficient Coverage

-
- - - - - - - - - - - - -
ClassCoverage
App\Providers\HorizonServiceProvider75%
App\Providers\AppServiceProvider82%
-
-
-
-

Project Risks

-
- - - - - - - - - - - -
ClassCRAP
App\Providers\AppServiceProvider6
-
-
-
-
-
-

Methods

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
-
-
-

Insufficient Coverage

-
- - - - - - - - - - - - -
MethodCoverage
mapExceptionToLogLevel0%
gate66%
-
-
-
-

Project Risks

-
- - - - - - - - - - - -
MethodCRAP
mapExceptionToLogLevel20
-
-
-
- -
- - - - - - diff --git a/backend/coverage-report-final/Providers/index.html b/backend/coverage-report-final/Providers/index.html deleted file mode 100644 index f8ece8d3..00000000 --- a/backend/coverage-report-final/Providers/index.html +++ /dev/null @@ -1,147 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Providers - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 81.82% covered (warning) -
-
-
81.82%
27 / 33
-
- 40.00% covered (danger) -
-
-
40.00%
2 / 5
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
AppServiceProvider.php
-
- 82.76% covered (warning) -
-
-
82.76%
24 / 29
-
- 33.33% covered (danger) -
-
-
33.33%
1 / 3
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
HorizonServiceProvider.php
-
- 75.00% covered (warning) -
-
-
75.00%
3 / 4
-
- 50.00% covered (danger) -
-
-
50.00%
1 / 2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- -
- - diff --git a/backend/coverage-report-final/Services/Article/ArticleFetcher.php.html b/backend/coverage-report-final/Services/Article/ArticleFetcher.php.html deleted file mode 100644 index bc46ebab..00000000 --- a/backend/coverage-report-final/Services/Article/ArticleFetcher.php.html +++ /dev/null @@ -1,354 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Services/Article/ArticleFetcher.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 44
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 5
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
ArticleFetcher
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 44
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 5
132
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 getArticlesFromFeed
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 9
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
12
 getArticlesFromRssFeed
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 getArticlesFromWebsiteFeed
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 18
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
12
 fetchArticleData
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 9
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
6
 saveArticle
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 7
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
6
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Services\Article;
4
5use App\Models\Article;
6use App\Models\Feed;
7use App\Services\Http\HttpFetcher;
8use App\Services\Factories\ArticleParserFactory;
9use App\Services\Factories\HomepageParserFactory;
10use App\Services\Log\LogSaver;
11use Exception;
12use Illuminate\Support\Collection;
13
14class ArticleFetcher
15{
16    /**
17     * @return Collection<int, Article>
18     */
19    public static function getArticlesFromFeed(Feed $feed): Collection
20    {
21        if ($feed->type === 'rss') {
22            return self::getArticlesFromRssFeed($feed);
23        } elseif ($feed->type === 'website') {
24            return self::getArticlesFromWebsiteFeed($feed);
25        }
26
27        LogSaver::warning("Unsupported feed type", null, [
28            'feed_id' => $feed->id,
29            'feed_type' => $feed->type
30        ]);
31
32        return collect();
33    }
34
35    /**
36     * @return Collection<int, Article>
37     */
38    private static function getArticlesFromRssFeed(Feed $feed): Collection
39    {
40        // TODO: Implement RSS feed parsing
41        // For now, return empty collection
42        return collect();
43    }
44
45    /**
46     * @return Collection<int, Article>
47     */
48    private static function getArticlesFromWebsiteFeed(Feed $feed): Collection
49    {
50        try {
51            // Try to get parser for this feed
52            $parser = HomepageParserFactory::getParserForFeed($feed);
53
54            if (! $parser) {
55                LogSaver::warning("No parser available for feed URL", null, [
56                    'feed_id' => $feed->id,
57                    'feed_url' => $feed->url
58                ]);
59
60                return collect();
61            }
62
63            $html = HttpFetcher::fetchHtml($feed->url);
64            $urls = $parser->extractArticleUrls($html);
65
66            return collect($urls)
67                ->map(fn (string $url) => self::saveArticle($url, $feed->id));
68
69        } catch (Exception $e) {
70            LogSaver::error("Failed to fetch articles from website feed", null, [
71                'feed_id' => $feed->id,
72                'feed_url' => $feed->url,
73                'error' => $e->getMessage()
74            ]);
75
76            return collect();
77        }
78    }
79
80    /**
81     * @return array<string, mixed>
82     */
83    public static function fetchArticleData(Article $article): array
84    {
85        try {
86            $html = HttpFetcher::fetchHtml($article->url);
87            $parser = ArticleParserFactory::getParser($article->url);
88
89            return $parser->extractData($html);
90        } catch (Exception $e) {
91            LogSaver::error('Exception while fetching article data', null, [
92                'url' => $article->url,
93                'error' => $e->getMessage()
94            ]);
95
96            return [];
97        }
98    }
99
100    private static function saveArticle(string $url, ?int $feedId = null): Article
101    {
102        $existingArticle = Article::where('url', $url)->first();
103
104        if ($existingArticle) {
105            return $existingArticle;
106        }
107
108        return Article::create([
109            'url' => $url,
110            'feed_id' => $feedId
111        ]);
112    }
113}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:53:46 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-final/Services/Article/ValidationService.php.html b/backend/coverage-report-final/Services/Article/ValidationService.php.html deleted file mode 100644 index 640b4a5d..00000000 --- a/backend/coverage-report-final/Services/Article/ValidationService.php.html +++ /dev/null @@ -1,228 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Services/Article/ValidationService.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 25
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
ValidationService
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 25
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
30
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 validate
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 18
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
6
 validateByKeywords
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 7
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
12
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Services\Article;
4
5use App\Models\Article;
6
7class ValidationService
8{
9    public static function validate(Article $article): Article
10    {
11        logger('Checking keywords for article: ' . $article->id);
12
13        $articleData = ArticleFetcher::fetchArticleData($article);
14        
15        if (!isset($articleData['full_article'])) {
16            logger()->warning('Article data missing full_article key', [
17                'article_id' => $article->id,
18                'url' => $article->url
19            ]);
20            
21            $article->update([
22                'is_valid' => false,
23                'validated_at' => now(),
24            ]);
25            
26            return $article->refresh();
27        }
28        
29        $validationResult = self::validateByKeywords($articleData['full_article']);
30
31        $article->update([
32            'is_valid' => $validationResult,
33            'validated_at' => now(),
34        ]);
35
36        return $article->refresh();
37    }
38
39    private static function validateByKeywords(string $full_article): bool
40    {
41        $keywords = [
42            'N-VA', 'Bart De Wever', 'Frank Vandenbroucke',
43        ];
44
45        foreach ($keywords as $keyword) {
46            if (stripos($full_article, $keyword) !== false) {
47                return true;
48            }
49        }
50
51        return false;
52    }
53}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:53:46 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-final/Services/Article/dashboard.html b/backend/coverage-report-final/Services/Article/dashboard.html deleted file mode 100644 index f18c4ae9..00000000 --- a/backend/coverage-report-final/Services/Article/dashboard.html +++ /dev/null @@ -1,302 +0,0 @@ - - - - - Dashboard for /var/www/html/backend/app/Services/Article - - - - - - - -
-
-
-
- -
-
-
-
-
-
-
-

Classes

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
-
-
-

Insufficient Coverage

- -
-
-

Project Risks

- -
-
-
-
-

Methods

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
-
-
-

Insufficient Coverage

- -
-
-

Project Risks

- -
-
- -
- - - - - - diff --git a/backend/coverage-report-final/Services/Article/index.html b/backend/coverage-report-final/Services/Article/index.html deleted file mode 100644 index b26226d3..00000000 --- a/backend/coverage-report-final/Services/Article/index.html +++ /dev/null @@ -1,148 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Services/Article - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 69
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 7
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
ArticleFetcher.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 44
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 5
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
ValidationService.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 25
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- -
- - diff --git a/backend/coverage-report-final/Services/Auth/LemmyAuthService.php.html b/backend/coverage-report-final/Services/Auth/LemmyAuthService.php.html deleted file mode 100644 index a04e7fd3..00000000 --- a/backend/coverage-report-final/Services/Auth/LemmyAuthService.php.html +++ /dev/null @@ -1,194 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Services/Auth/LemmyAuthService.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 12
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
LemmyAuthService
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 12
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
42
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 getToken
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 12
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
42
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Services\Auth;
4
5use App\Enums\PlatformEnum;
6use App\Exceptions\PlatformAuthException;
7use App\Models\PlatformAccount;
8use App\Modules\Lemmy\Services\LemmyApiService;
9use Illuminate\Support\Facades\Cache;
10
11class LemmyAuthService
12{
13    /**
14     * @throws PlatformAuthException
15     */
16    public static function getToken(PlatformAccount $account): string
17    {
18        $cacheKey = "lemmy_jwt_token_$account->id";
19        $cachedToken = Cache::get($cacheKey);
20
21        if ($cachedToken) {
22            return $cachedToken;
23        }
24
25        if (! $account->username || ! $account->password || ! $account->instance_url) {
26            throw new PlatformAuthException(PlatformEnum::LEMMY, 'Missing credentials for account: ' . $account->username);
27        }
28
29        $api = new LemmyApiService($account->instance_url);
30        $token = $api->login($account->username, $account->password);
31
32        if (!$token) {
33            throw new PlatformAuthException(PlatformEnum::LEMMY, 'Login failed for account: ' . $account->username);
34        }
35
36        // Cache for 50 minutes (3000 seconds) to allow buffer before token expires
37        Cache::put($cacheKey, $token, 3000);
38
39        return $token;
40    }
41}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:53:46 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-final/Services/Auth/dashboard.html b/backend/coverage-report-final/Services/Auth/dashboard.html deleted file mode 100644 index 6525a51a..00000000 --- a/backend/coverage-report-final/Services/Auth/dashboard.html +++ /dev/null @@ -1,289 +0,0 @@ - - - - - Dashboard for /var/www/html/backend/app/Services/Auth - - - - - - - -
-
-
-
- -
-
-
-
-
-
-
-

Classes

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
-
-
-

Insufficient Coverage

-
- - - - - - - - - - - -
ClassCoverage
App\Services\Auth\LemmyAuthService0%
-
-
-
-

Project Risks

-
- - - - - - - - - - - -
ClassCRAP
App\Services\Auth\LemmyAuthService42
-
-
-
-
-
-

Methods

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
-
-
-

Insufficient Coverage

-
- - - - - - - - - - - -
MethodCoverage
getToken0%
-
-
-
-

Project Risks

-
- - - - - - - - - - - -
MethodCRAP
getToken42
-
-
-
- -
- - - - - - diff --git a/backend/coverage-report-final/Services/Auth/index.html b/backend/coverage-report-final/Services/Auth/index.html deleted file mode 100644 index 022ba09d..00000000 --- a/backend/coverage-report-final/Services/Auth/index.html +++ /dev/null @@ -1,120 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Services/Auth - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 12
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
LemmyAuthService.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 12
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- -
- - diff --git a/backend/coverage-report-final/Services/DashboardStatsService.php.html b/backend/coverage-report-final/Services/DashboardStatsService.php.html deleted file mode 100644 index ddeae2ee..00000000 --- a/backend/coverage-report-final/Services/DashboardStatsService.php.html +++ /dev/null @@ -1,306 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Services/DashboardStatsService.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 100.00% covered (success) -
-
-
100.00%
40 / 40
-
- 100.00% covered (success) -
-
-
100.00%
4 / 4
CRAP
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
DashboardStatsService
-
- 100.00% covered (success) -
-
-
100.00%
40 / 40
-
- 100.00% covered (success) -
-
-
100.00%
4 / 4
13
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
 getStats
-
- 100.00% covered (success) -
-
-
100.00%
16 / 16
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
4
 getAvailablePeriods
-
- 100.00% covered (success) -
-
-
100.00%
7 / 7
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
1
 getDateRange
-
- 100.00% covered (success) -
-
-
100.00%
9 / 9
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
7
 getSystemStats
-
- 100.00% covered (success) -
-
-
100.00%
8 / 8
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
1
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Services;
4
5use App\Models\Article;
6use App\Models\ArticlePublication;
7use Carbon\Carbon;
8
9class DashboardStatsService
10{
11    /**
12     * @return array
13     */
14    public function getStats(string $period = 'today'): array
15    {
16        $dateRange = $this->getDateRange($period);
17        
18        // Get articles fetched for the period
19        $articlesFetchedQuery = Article::query();
20        if ($dateRange) {
21            $articlesFetchedQuery->whereBetween('created_at', $dateRange);
22        }
23        $articlesFetched = $articlesFetchedQuery->count();
24
25        // Get articles published for the period
26        $articlesPublishedQuery = ArticlePublication::query()
27            ->whereNotNull('published_at');
28        if ($dateRange) {
29            $articlesPublishedQuery->whereBetween('published_at', $dateRange);
30        }
31        $articlesPublished = $articlesPublishedQuery->count();
32
33        // Calculate published percentage
34        $publishedPercentage = $articlesFetched > 0 ? round(($articlesPublished / $articlesFetched) * 100, 1) : 0.0;
35
36        return [
37            'articles_fetched' => $articlesFetched,
38            'articles_published' => $articlesPublished,
39            'published_percentage' => $publishedPercentage,
40        ];
41    }
42
43    /**
44     * @return array<string, string>
45     */
46    public function getAvailablePeriods(): array
47    {
48        return [
49            'today' => 'Today',
50            'week' => 'This Week',
51            'month' => 'This Month',
52            'year' => 'This Year',
53            'all' => 'All Time',
54        ];
55    }
56
57    /**
58     * @return array{0: Carbon, 1: Carbon}|null
59     */
60    private function getDateRange(string $period): ?array
61    {
62        $now = Carbon::now();
63        
64        return match ($period) {
65            'today' => [$now->copy()->startOfDay(), $now->copy()->endOfDay()],
66            'week' => [$now->copy()->startOfWeek(), $now->copy()->endOfWeek()],
67            'month' => [$now->copy()->startOfMonth(), $now->copy()->endOfMonth()],
68            'year' => [$now->copy()->startOfYear(), $now->copy()->endOfYear()],
69            'all' => null, // No date filtering for all-time stats
70            default => [$now->copy()->startOfDay(), $now->copy()->endOfDay()],
71        };
72    }
73
74    /**
75     * Get additional stats for dashboard
76     */
77    public function getSystemStats(): array
78    {
79        return [
80            'total_feeds' => \App\Models\Feed::count(),
81            'active_feeds' => \App\Models\Feed::where('is_active', true)->count(),
82            'total_channels' => \App\Models\PlatformChannel::count(),
83            'active_channels' => \App\Models\PlatformChannel::where('is_active', true)->count(),
84            'total_routes' => \App\Models\Route::count(),
85            'active_routes' => \App\Models\Route::where('is_active', true)->count(),
86        ];
87    }
88}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:53:46 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-final/Services/Factories/ArticleParserFactory.php.html b/backend/coverage-report-final/Services/Factories/ArticleParserFactory.php.html deleted file mode 100644 index 38e000b1..00000000 --- a/backend/coverage-report-final/Services/Factories/ArticleParserFactory.php.html +++ /dev/null @@ -1,250 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Services/Factories/ArticleParserFactory.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 11
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
ArticleParserFactory
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 11
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
42
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 getParser
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 5
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
12
 getSupportedSources
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 4
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 registerParser
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
6
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Services\Factories;
4
5use App\Contracts\ArticleParserInterface;
6use App\Services\Parsers\VrtArticleParser;
7use App\Services\Parsers\BelgaArticleParser;
8use Exception;
9
10class ArticleParserFactory
11{
12    /**
13     * @var array<int, class-string<ArticleParserInterface>>
14     */
15    private static array $parsers = [
16        VrtArticleParser::class,
17        BelgaArticleParser::class,
18    ];
19
20    public static function getParser(string $url): ArticleParserInterface
21    {
22        foreach (self::$parsers as $parserClass) {
23            $parser = new $parserClass();
24            
25            if ($parser->canParse($url)) {
26                return $parser;
27            }
28        }
29
30        throw new Exception("No parser found for URL: {$url}");
31    }
32
33    /**
34     * @return array<int, string>
35     */
36    public static function getSupportedSources(): array
37    {
38        return array_map(function($parserClass) {
39            $parser = new $parserClass();
40            return $parser->getSourceName();
41        }, self::$parsers);
42    }
43
44    /**
45     * @param class-string<ArticleParserInterface> $parserClass
46     */
47    public static function registerParser(string $parserClass): void
48    {
49        if (!in_array($parserClass, self::$parsers)) {
50            self::$parsers[] = $parserClass;
51        }
52    }
53}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:53:46 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-final/Services/Factories/HomepageParserFactory.php.html b/backend/coverage-report-final/Services/Factories/HomepageParserFactory.php.html deleted file mode 100644 index 21d9600c..00000000 --- a/backend/coverage-report-final/Services/Factories/HomepageParserFactory.php.html +++ /dev/null @@ -1,220 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Services/Factories/HomepageParserFactory.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 8
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
HomepageParserFactory
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 8
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
30
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 getParser
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 5
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
12
 getParserForFeed
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
6
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Services\Factories;
4
5use App\Contracts\HomepageParserInterface;
6use App\Models\Feed;
7use App\Services\Parsers\VrtHomepageParserAdapter;
8use App\Services\Parsers\BelgaHomepageParserAdapter;
9use Exception;
10
11class HomepageParserFactory
12{
13    /**
14     * @var array<int, class-string<HomepageParserInterface>>
15     */
16    private static array $parsers = [
17        VrtHomepageParserAdapter::class,
18        BelgaHomepageParserAdapter::class,
19    ];
20
21    /**
22     * @throws Exception
23     */
24    public static function getParser(string $url): HomepageParserInterface
25    {
26        foreach (self::$parsers as $parserClass) {
27            $parser = new $parserClass();
28
29            if ($parser->canParse($url)) {
30                return $parser;
31            }
32        }
33
34        throw new Exception("No homepage parser found for URL: {$url}");
35    }
36
37    public static function getParserForFeed(Feed $feed): ?HomepageParserInterface
38    {
39        try {
40            return self::getParser($feed->url);
41        } catch (Exception) {
42            return null;
43        }
44    }
45}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:53:46 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-final/Services/Factories/dashboard.html b/backend/coverage-report-final/Services/Factories/dashboard.html deleted file mode 100644 index 26c40547..00000000 --- a/backend/coverage-report-final/Services/Factories/dashboard.html +++ /dev/null @@ -1,298 +0,0 @@ - - - - - Dashboard for /var/www/html/backend/app/Services/Factories - - - - - - - -
-
-
-
- -
-
-
-
-
-
-
-

Classes

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
-
-
-

Insufficient Coverage

- -
-
-

Project Risks

- -
-
-
-
-

Methods

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
-
-
-

Insufficient Coverage

-
- - - - - - - - - - - - - - - -
MethodCoverage
getParser0%
getSupportedSources0%
registerParser0%
getParser0%
getParserForFeed0%
-
-
-
-

Project Risks

-
- - - - - - - - - - - - - - -
MethodCRAP
getParser12
getParser12
registerParser6
getParserForFeed6
-
-
-
- -
- - - - - - diff --git a/backend/coverage-report-final/Services/Factories/index.html b/backend/coverage-report-final/Services/Factories/index.html deleted file mode 100644 index 924830c8..00000000 --- a/backend/coverage-report-final/Services/Factories/index.html +++ /dev/null @@ -1,148 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Services/Factories - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 19
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 5
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
ArticleParserFactory.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 11
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
HomepageParserFactory.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 8
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- -
- - diff --git a/backend/coverage-report-final/Services/Http/HttpFetcher.php.html b/backend/coverage-report-final/Services/Http/HttpFetcher.php.html deleted file mode 100644 index 52107b40..00000000 --- a/backend/coverage-report-final/Services/Http/HttpFetcher.php.html +++ /dev/null @@ -1,256 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Services/Http/HttpFetcher.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 44
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
HttpFetcher
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 44
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
90
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 fetchHtml
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 10
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
12
 fetchMultipleUrls
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 34
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
42
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Services\Http;
4
5use Illuminate\Support\Facades\Http;
6use Exception;
7
8class HttpFetcher
9{
10    public static function fetchHtml(string $url): string
11    {
12        try {
13            $response = Http::get($url);
14            
15            if (!$response->successful()) {
16                throw new Exception("Failed to fetch URL: {$url} - Status: {$response->status()}");
17            }
18            
19            return $response->body();
20        } catch (Exception $e) {
21            logger()->error('HTTP fetch failed', [
22                'url' => $url,
23                'error' => $e->getMessage()
24            ]);
25            throw $e;
26        }
27    }
28
29    /**
30     * @param array<int, string> $urls
31     * @return array<int, array<string, mixed>>
32     */
33    public static function fetchMultipleUrls(array $urls): array
34    {
35        try {
36            $responses = Http::pool(function ($pool) use ($urls) {
37                foreach ($urls as $url) {
38                    $pool->get($url);
39                }
40            });
41
42            return collect($responses)
43                ->map(function ($response, $index) use ($urls) {
44                    if (!isset($urls[$index])) {
45                        return null;
46                    }
47                    
48                    $url = $urls[$index];
49                    
50                    try {
51                        if ($response->successful()) {
52                            return [
53                                'url' => $url,
54                                'html' => $response->body(),
55                                'success' => true
56                            ];
57                        } else {
58                            return [
59                                'url' => $url,
60                                'html' => null,
61                                'success' => false,
62                                'status' => $response->status()
63                            ];
64                        }
65                    } catch (Exception) {
66                        return [
67                            'url' => $url,
68                            'html' => null,
69                            'success' => false,
70                            'error' => 'Exception occurred'
71                        ];
72                    }
73                })
74                ->filter(fn($result) => $result !== null)
75                ->toArray();
76        } catch (Exception $e) {
77            logger()->error('Multiple URL fetch failed', ['error' => $e->getMessage()]);
78            return [];
79        }
80    }
81}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:53:46 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-final/Services/Http/dashboard.html b/backend/coverage-report-final/Services/Http/dashboard.html deleted file mode 100644 index 20460c41..00000000 --- a/backend/coverage-report-final/Services/Http/dashboard.html +++ /dev/null @@ -1,291 +0,0 @@ - - - - - Dashboard for /var/www/html/backend/app/Services/Http - - - - - - - -
-
-
-
- -
-
-
-
-
-
-
-

Classes

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
-
-
-

Insufficient Coverage

-
- - - - - - - - - - - -
ClassCoverage
App\Services\Http\HttpFetcher0%
-
-
-
-

Project Risks

-
- - - - - - - - - - - -
ClassCRAP
App\Services\Http\HttpFetcher90
-
-
-
-
-
-

Methods

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
-
-
-

Insufficient Coverage

-
- - - - - - - - - - - - -
MethodCoverage
fetchHtml0%
fetchMultipleUrls0%
-
-
-
-

Project Risks

-
- - - - - - - - - - - - -
MethodCRAP
fetchMultipleUrls42
fetchHtml12
-
-
-
- -
- - - - - - diff --git a/backend/coverage-report-final/Services/Http/index.html b/backend/coverage-report-final/Services/Http/index.html deleted file mode 100644 index dc7ff768..00000000 --- a/backend/coverage-report-final/Services/Http/index.html +++ /dev/null @@ -1,120 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Services/Http - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 44
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
HttpFetcher.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 44
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- -
- - diff --git a/backend/coverage-report-final/Services/Log/LogSaver.php.html b/backend/coverage-report-final/Services/Log/LogSaver.php.html deleted file mode 100644 index f6863b6b..00000000 --- a/backend/coverage-report-final/Services/Log/LogSaver.php.html +++ /dev/null @@ -1,306 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Services/Log/LogSaver.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 17
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 5
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
LogSaver
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 17
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 5
42
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 info
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 error
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 warning
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 debug
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 log
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 13
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
6
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Services\Log;
4
5use App\LogLevelEnum;
6use App\Models\Log;
7use App\Models\PlatformChannel;
8
9class LogSaver
10{
11    /**
12     * @param array<string, mixed> $context
13     */
14    public static function info(string $message, ?PlatformChannel $channel = null, array $context = []): void
15    {
16        self::log(LogLevelEnum::INFO, $message, $channel, $context);
17    }
18
19    /**
20     * @param array<string, mixed> $context
21     */
22    public static function error(string $message, ?PlatformChannel $channel = null, array $context = []): void
23    {
24        self::log(LogLevelEnum::ERROR, $message, $channel, $context);
25    }
26
27    /**
28     * @param array<string, mixed> $context
29     */
30    public static function warning(string $message, ?PlatformChannel $channel = null, array $context = []): void
31    {
32        self::log(LogLevelEnum::WARNING, $message, $channel, $context);
33    }
34
35    /**
36     * @param array<string, mixed> $context
37     */
38    public static function debug(string $message, ?PlatformChannel $channel = null, array $context = []): void
39    {
40        self::log(LogLevelEnum::DEBUG, $message, $channel, $context);
41    }
42
43    /**
44     * @param array<string, mixed> $context
45     */
46    private static function log(LogLevelEnum $level, string $message, ?PlatformChannel $channel = null, array $context = []): void
47    {
48        $logContext = $context;
49
50        if ($channel) {
51            $logContext = array_merge($logContext, [
52                'channel_id' => $channel->id,
53                'channel_name' => $channel->name,
54                'platform' => $channel->platformInstance->platform->value,
55                'instance_url' => $channel->platformInstance->url,
56            ]);
57        }
58
59        Log::create([
60            'level' => $level,
61            'message' => $message,
62            'context' => $logContext,
63        ]);
64    }
65}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:53:46 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-final/Services/Log/dashboard.html b/backend/coverage-report-final/Services/Log/dashboard.html deleted file mode 100644 index 8e16601d..00000000 --- a/backend/coverage-report-final/Services/Log/dashboard.html +++ /dev/null @@ -1,293 +0,0 @@ - - - - - Dashboard for /var/www/html/backend/app/Services/Log - - - - - - - -
-
-
-
- -
-
-
-
-
-
-
-

Classes

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
-
-
-

Insufficient Coverage

-
- - - - - - - - - - - -
ClassCoverage
App\Services\Log\LogSaver0%
-
-
-
-

Project Risks

-
- - - - - - - - - - - -
ClassCRAP
App\Services\Log\LogSaver42
-
-
-
-
-
-

Methods

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
-
-
-

Insufficient Coverage

-
- - - - - - - - - - - - - - - -
MethodCoverage
info0%
error0%
warning0%
debug0%
log0%
-
-
-
-

Project Risks

-
- - - - - - - - - - - -
MethodCRAP
log6
-
-
-
- -
- - - - - - diff --git a/backend/coverage-report-final/Services/Log/index.html b/backend/coverage-report-final/Services/Log/index.html deleted file mode 100644 index 6dfe931f..00000000 --- a/backend/coverage-report-final/Services/Log/index.html +++ /dev/null @@ -1,120 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Services/Log - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 17
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 5
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
LogSaver.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 17
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 5
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- -
- - diff --git a/backend/coverage-report-final/Services/OnboardingRedirectService.php.html b/backend/coverage-report-final/Services/OnboardingRedirectService.php.html deleted file mode 100644 index 7352c4b8..00000000 --- a/backend/coverage-report-final/Services/OnboardingRedirectService.php.html +++ /dev/null @@ -1,172 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Services/OnboardingRedirectService.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 4
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
OnboardingRedirectService
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 4
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
6
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 handleRedirect
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 4
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
6
-
- - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Services;
4
5use Illuminate\Http\RedirectResponse;
6use Illuminate\Http\Request;
7
8class OnboardingRedirectService
9{
10    public static function handleRedirect(Request $request, string $defaultRoute, string $successMessage): RedirectResponse
11    {
12        $redirectTo = $request->input('redirect_to');
13        
14        if ($redirectTo) {
15            return redirect($redirectTo)->with('success', $successMessage);
16        }
17
18        return redirect()->route($defaultRoute)->with('success', $successMessage);
19    }
20}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:53:46 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-final/Services/Parsers/BelgaArticlePageParser.php.html b/backend/coverage-report-final/Services/Parsers/BelgaArticlePageParser.php.html deleted file mode 100644 index 9f45555e..00000000 --- a/backend/coverage-report-final/Services/Parsers/BelgaArticlePageParser.php.html +++ /dev/null @@ -1,351 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Services/Parsers/BelgaArticlePageParser.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 42
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 5
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
BelgaArticlePageParser
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 42
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 5
306
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 extractTitle
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 9
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
30
 extractDescription
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 7
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
20
 extractFullArticle
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 15
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
20
 extractThumbnail
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 5
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
12
 extractData
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 6
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Services\Parsers;
4
5class BelgaArticlePageParser
6{
7    public static function extractTitle(string $html): ?string
8    {
9        // Try h1 with Belga-specific class first
10        if (preg_match('/<h1[^>]*class="[^"]*prezly-slate-heading--heading-1[^"]*"[^>]*>([^<]+)<\/h1>/i', $html, $matches)) {
11            return html_entity_decode(strip_tags($matches[1]), ENT_QUOTES, 'UTF-8');
12        }
13        
14        // Try meta title
15        if (preg_match('/<meta property="og:title" content="([^"]+)"/i', $html, $matches)) {
16            return html_entity_decode($matches[1], ENT_QUOTES, 'UTF-8');
17        }
18        
19        // Try any h1 tag
20        if (preg_match('/<h1[^>]*>([^<]+)<\/h1>/i', $html, $matches)) {
21            return html_entity_decode(strip_tags($matches[1]), ENT_QUOTES, 'UTF-8');
22        }
23        
24        // Try title tag
25        if (preg_match('/<title>([^<]+)<\/title>/i', $html, $matches)) {
26            return html_entity_decode($matches[1], ENT_QUOTES, 'UTF-8');
27        }
28        
29        return null;
30    }
31    
32    public static function extractDescription(string $html): ?string
33    {
34        // Try meta description first
35        if (preg_match('/<meta property="og:description" content="([^"]+)"/i', $html, $matches)) {
36            return html_entity_decode($matches[1], ENT_QUOTES, 'UTF-8');
37        }
38        
39        // Try Belga-specific paragraph class
40        if (preg_match('/<p[^>]*class="[^"]*styles_paragraph__[^"]*"[^>]*>([^<]+(?:<[^\/](?!p)[^>]*>[^<]*<\/[^>]*>[^<]*)*)<\/p>/i', $html, $matches)) {
41            return html_entity_decode(strip_tags($matches[1]), ENT_QUOTES, 'UTF-8');
42        }
43        
44        // Try to find first paragraph in article content
45        if (preg_match('/<p[^>]*>([^<]+(?:<[^\/](?!p)[^>]*>[^<]*<\/[^>]*>[^<]*)*)<\/p>/i', $html, $matches)) {
46            return html_entity_decode(strip_tags($matches[1]), ENT_QUOTES, 'UTF-8');
47        }
48        
49        return null;
50    }
51    
52    public static function extractFullArticle(string $html): ?string
53    {
54        // Remove scripts, styles, and other non-content elements
55        $cleanHtml = preg_replace('/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/mi', '', $html);
56        $cleanHtml = preg_replace('/<style\b[^<]*(?:(?!<\/style>)<[^<]*)*<\/style>/mi', '', $cleanHtml);
57        
58        // Try to extract content from Belga-specific document section
59        if (preg_match('/<section[^>]*class="[^"]*prezly-slate-document[^"]*"[^>]*>(.*?)<\/section>/is', $cleanHtml, $sectionMatches)) {
60            $sectionHtml = $sectionMatches[1];
61            preg_match_all('/<p[^>]*>(.*?)<\/p>/is', $sectionHtml, $matches);
62        } else {
63            // Fallback: Extract all paragraph content
64            preg_match_all('/<p[^>]*>(.*?)<\/p>/is', $cleanHtml, $matches);
65        }
66        
67        if (!empty($matches[1])) {
68            $paragraphs = array_map(function($paragraph) {
69                return html_entity_decode(strip_tags($paragraph), ENT_QUOTES, 'UTF-8');
70            }, $matches[1]);
71            
72            // Filter out empty paragraphs and join with double newlines
73            $fullText = implode("\n\n", array_filter($paragraphs, function($p) {
74                return trim($p) !== '';
75            }));
76            
77            return $fullText ?: null;
78        }
79        
80        return null;
81    }
82    
83    public static function extractThumbnail(string $html): ?string
84    {
85        // Try OpenGraph image first
86        if (preg_match('/<meta property="og:image" content="([^"]+)"/i', $html, $matches)) {
87            return $matches[1];
88        }
89        
90        // Try first image in article content
91        if (preg_match('/<img[^>]+src="([^"]+)"/i', $html, $matches)) {
92            return $matches[1];
93        }
94        
95        return null;
96    }
97
98    /**
99     * @return array<string, string|null>
100     */
101    public static function extractData(string $html): array
102    {
103        return [
104            'title' => self::extractTitle($html),
105            'description' => self::extractDescription($html),
106            'full_article' => self::extractFullArticle($html),
107            'thumbnail' => self::extractThumbnail($html),
108        ];
109    }
110}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:53:46 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-final/Services/Parsers/BelgaArticleParser.php.html b/backend/coverage-report-final/Services/Parsers/BelgaArticleParser.php.html deleted file mode 100644 index e0a9c349..00000000 --- a/backend/coverage-report-final/Services/Parsers/BelgaArticleParser.php.html +++ /dev/null @@ -1,220 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Services/Parsers/BelgaArticleParser.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
BelgaArticleParser
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
12
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 canParse
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 extractData
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 getSourceName
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Services\Parsers;
4
5use App\Contracts\ArticleParserInterface;
6
7class BelgaArticleParser implements ArticleParserInterface
8{
9    public function canParse(string $url): bool
10    {
11        return str_contains($url, 'belganewsagency.eu');
12    }
13
14    public function extractData(string $html): array
15    {
16        return BelgaArticlePageParser::extractData($html);
17    }
18
19    public function getSourceName(): string
20    {
21        return 'Belga News Agency';
22    }
23}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:53:46 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-final/Services/Parsers/BelgaHomepageParser.php.html b/backend/coverage-report-final/Services/Parsers/BelgaHomepageParser.php.html deleted file mode 100644 index 4f7aae4c..00000000 --- a/backend/coverage-report-final/Services/Parsers/BelgaHomepageParser.php.html +++ /dev/null @@ -1,173 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Services/Parsers/BelgaHomepageParser.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 5
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
BelgaHomepageParser
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 5
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 extractArticleUrls
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 5
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Services\Parsers;
4
5class BelgaHomepageParser
6{
7    /**
8     * @return array<int, string>
9     */
10    public static function extractArticleUrls(string $html): array
11    {
12        preg_match_all('/href="(https:\/\/www\.belganewsagency\.eu\/[a-z0-9-]+)"/', $html, $matches);
13
14        $urls = collect($matches[1])
15            ->unique()
16            ->toArray();
17
18        return $urls;
19    }
20}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:53:46 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-final/Services/Parsers/BelgaHomepageParserAdapter.php.html b/backend/coverage-report-final/Services/Parsers/BelgaHomepageParserAdapter.php.html deleted file mode 100644 index f2d534f1..00000000 --- a/backend/coverage-report-final/Services/Parsers/BelgaHomepageParserAdapter.php.html +++ /dev/null @@ -1,247 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Services/Parsers/BelgaHomepageParserAdapter.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 4
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 4
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
BelgaHomepageParserAdapter
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 4
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 4
20
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 canParse
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 extractArticleUrls
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 getHomepageUrl
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 getSourceName
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Services\Parsers;
4
5use App\Contracts\HomepageParserInterface;
6
7class BelgaHomepageParserAdapter implements HomepageParserInterface
8{
9    public function canParse(string $url): bool
10    {
11        return str_contains($url, 'belganewsagency.eu');
12    }
13
14    public function extractArticleUrls(string $html): array
15    {
16        return BelgaHomepageParser::extractArticleUrls($html);
17    }
18
19    public function getHomepageUrl(): string
20    {
21        return 'https://www.belganewsagency.eu/';
22    }
23
24    public function getSourceName(): string
25    {
26        return 'Belga News Agency';
27    }
28}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:53:46 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-final/Services/Parsers/VrtArticlePageParser.php.html b/backend/coverage-report-final/Services/Parsers/VrtArticlePageParser.php.html deleted file mode 100644 index 4230130e..00000000 --- a/backend/coverage-report-final/Services/Parsers/VrtArticlePageParser.php.html +++ /dev/null @@ -1,333 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Services/Parsers/VrtArticlePageParser.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 35
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 5
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
VrtArticlePageParser
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 35
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 5
210
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 extractTitle
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 7
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
20
 extractDescription
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 5
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
12
 extractFullArticle
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 12
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
12
 extractThumbnail
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 5
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
12
 extractData
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 6
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Services\Parsers;
4
5class VrtArticlePageParser
6{
7    public static function extractTitle(string $html): ?string
8    {
9        // Try meta title first
10        if (preg_match('/<meta property="og:title" content="([^"]+)"/i', $html, $matches)) {
11            return html_entity_decode($matches[1], ENT_QUOTES, 'UTF-8');
12        }
13
14        // Try h1 tag
15        if (preg_match('/<h1[^>]*>([^<]+)<\/h1>/i', $html, $matches)) {
16            return html_entity_decode(strip_tags($matches[1]), ENT_QUOTES, 'UTF-8');
17        }
18
19        // Try title tag
20        if (preg_match('/<title>([^<]+)<\/title>/i', $html, $matches)) {
21            return html_entity_decode($matches[1], ENT_QUOTES, 'UTF-8');
22        }
23
24        return null;
25    }
26
27    public static function extractDescription(string $html): ?string
28    {
29        // Try meta description first
30        if (preg_match('/<meta property="og:description" content="([^"]+)"/i', $html, $matches)) {
31            return html_entity_decode($matches[1], ENT_QUOTES, 'UTF-8');
32        }
33
34        // Try to find first paragraph in article content
35        if (preg_match('/<p[^>]*>([^<]+(?:<[^\/](?!p)[^>]*>[^<]*<\/[^>]*>[^<]*)*)<\/p>/i', $html, $matches)) {
36            return html_entity_decode(strip_tags($matches[1]), ENT_QUOTES, 'UTF-8');
37        }
38
39        return null;
40    }
41
42    public static function extractFullArticle(string $html): ?string
43    {
44        // Remove scripts, styles, and other non-content elements
45        $cleanHtml = preg_replace('/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/mi', '', $html);
46        $cleanHtml = preg_replace('/<style\b[^<]*(?:(?!<\/style>)<[^<]*)*<\/style>/mi', '', $cleanHtml);
47
48        // Extract all paragraph content
49        preg_match_all('/<p[^>]*>(.*?)<\/p>/is', $cleanHtml, $matches);
50
51        if (!empty($matches[1])) {
52            $paragraphs = array_map(function($paragraph) {
53                return html_entity_decode(strip_tags($paragraph), ENT_QUOTES, 'UTF-8');
54            }, $matches[1]);
55
56            // Filter out empty paragraphs and join with double newlines
57            $fullText = implode("\n\n", array_filter($paragraphs, function($p) {
58                return trim($p) !== '';
59            }));
60
61            return $fullText ?: null;
62        }
63
64        return null;
65    }
66
67    public static function extractThumbnail(string $html): ?string
68    {
69        if (preg_match('/<meta property="og:image" content="([^"]+)"/i', $html, $matches)) {
70            return $matches[1];
71        }
72
73        if (preg_match('/<img[^>]+src="([^"]+)"/i', $html, $matches)) {
74            return $matches[1];
75        }
76
77        return null;
78    }
79
80    /**
81     * @return array<string, string|null>
82     */
83    public static function extractData(string $html): array
84    {
85        return [
86            'title' => self::extractTitle($html),
87            'description' => self::extractDescription($html),
88            'full_article' => self::extractFullArticle($html),
89            'thumbnail' => self::extractThumbnail($html),
90        ];
91    }
92}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:53:46 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-final/Services/Parsers/VrtArticleParser.php.html b/backend/coverage-report-final/Services/Parsers/VrtArticleParser.php.html deleted file mode 100644 index b05fe079..00000000 --- a/backend/coverage-report-final/Services/Parsers/VrtArticleParser.php.html +++ /dev/null @@ -1,220 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Services/Parsers/VrtArticleParser.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
VrtArticleParser
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
12
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 canParse
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 extractData
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 getSourceName
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Services\Parsers;
4
5use App\Contracts\ArticleParserInterface;
6
7class VrtArticleParser implements ArticleParserInterface
8{
9    public function canParse(string $url): bool
10    {
11        return str_contains($url, 'vrt.be');
12    }
13
14    public function extractData(string $html): array
15    {
16        return VrtArticlePageParser::extractData($html);
17    }
18
19    public function getSourceName(): string
20    {
21        return 'VRT News';
22    }
23}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:53:46 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-final/Services/Parsers/VrtHomepageParser.php.html b/backend/coverage-report-final/Services/Parsers/VrtHomepageParser.php.html deleted file mode 100644 index d516e795..00000000 --- a/backend/coverage-report-final/Services/Parsers/VrtHomepageParser.php.html +++ /dev/null @@ -1,175 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Services/Parsers/VrtHomepageParser.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 6
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
VrtHomepageParser
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 6
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 extractArticleUrls
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 6
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Services\Parsers;
4
5class VrtHomepageParser
6{
7    /**
8     * @return array<int, string>
9     */
10    public static function extractArticleUrls(string $html): array
11    {
12        // Extract article links using regex
13        preg_match_all('/href="(\/vrtnws\/en\/\d{4}\/\d{2}\/\d{2}\/[^"]+)"/', $html, $matches);
14
15        $urls = collect($matches[1])
16            ->unique()
17            ->map(fn ($path) => 'https://www.vrt.be' . $path)
18            ->toArray();
19
20        return $urls;
21    }
22}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:53:46 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-final/Services/Parsers/VrtHomepageParserAdapter.php.html b/backend/coverage-report-final/Services/Parsers/VrtHomepageParserAdapter.php.html deleted file mode 100644 index 68078583..00000000 --- a/backend/coverage-report-final/Services/Parsers/VrtHomepageParserAdapter.php.html +++ /dev/null @@ -1,247 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Services/Parsers/VrtHomepageParserAdapter.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 4
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 4
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
VrtHomepageParserAdapter
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 4
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 4
20
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 canParse
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 extractArticleUrls
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 getHomepageUrl
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 getSourceName
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Services\Parsers;
4
5use App\Contracts\HomepageParserInterface;
6
7class VrtHomepageParserAdapter implements HomepageParserInterface
8{
9    public function canParse(string $url): bool
10    {
11        return str_contains($url, 'vrt.be');
12    }
13
14    public function extractArticleUrls(string $html): array
15    {
16        return VrtHomepageParser::extractArticleUrls($html);
17    }
18
19    public function getHomepageUrl(): string
20    {
21        return 'https://www.vrt.be/vrtnws/en/';
22    }
23
24    public function getSourceName(): string
25    {
26        return 'VRT News';
27    }
28}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:53:46 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-final/Services/Parsers/dashboard.html b/backend/coverage-report-final/Services/Parsers/dashboard.html deleted file mode 100644 index 30d91ac2..00000000 --- a/backend/coverage-report-final/Services/Parsers/dashboard.html +++ /dev/null @@ -1,329 +0,0 @@ - - - - - Dashboard for /var/www/html/backend/app/Services/Parsers - - - - - - - -
-
-
-
- -
-
-
-
-
-
-
-

Classes

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
- -
-
-

Methods

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
- - -
- - - - - - diff --git a/backend/coverage-report-final/Services/Parsers/index.html b/backend/coverage-report-final/Services/Parsers/index.html deleted file mode 100644 index a325f6b0..00000000 --- a/backend/coverage-report-final/Services/Parsers/index.html +++ /dev/null @@ -1,316 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Services/Parsers - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 102
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 26
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 8
BelgaArticlePageParser.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 42
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 5
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
BelgaArticleParser.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
BelgaHomepageParser.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 5
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
BelgaHomepageParserAdapter.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 4
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 4
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
VrtArticlePageParser.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 35
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 5
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
VrtArticleParser.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
VrtHomepageParser.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 6
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
VrtHomepageParserAdapter.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 4
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 4
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- -
- - diff --git a/backend/coverage-report-final/Services/Publishing/ArticlePublishingService.php.html b/backend/coverage-report-final/Services/Publishing/ArticlePublishingService.php.html deleted file mode 100644 index 957dc942..00000000 --- a/backend/coverage-report-final/Services/Publishing/ArticlePublishingService.php.html +++ /dev/null @@ -1,260 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Services/Publishing/ArticlePublishingService.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 36
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
ArticlePublishingService
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 36
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
30
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 publishToRoutedChannels
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 14
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
12
 publishToChannel
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 22
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
6
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Services\Publishing;
4
5use App\Enums\PlatformEnum;
6use App\Exceptions\PublishException;
7use App\Models\Article;
8use App\Models\ArticlePublication;
9use App\Models\PlatformChannel;
10use App\Modules\Lemmy\Services\LemmyPublisher;
11use App\Services\Log\LogSaver;
12use Exception;
13use Illuminate\Database\Eloquent\Collection as EloquentCollection;
14use Illuminate\Support\Collection;
15use RuntimeException;
16
17class ArticlePublishingService
18{
19    /**
20     * @param array<string, mixed> $extractedData
21     * @return EloquentCollection<int, ArticlePublication>
22     * @throws PublishException
23     */
24    public function publishToRoutedChannels(Article $article, array $extractedData): EloquentCollection
25    {
26        if (! $article->is_valid) {
27            throw new PublishException($article, PlatformEnum::LEMMY, new RuntimeException('CANNOT_PUBLISH_INVALID_ARTICLE'));
28        }
29
30        $feed = $article->feed;
31        
32        /** @var EloquentCollection<int, PlatformChannel> $activeChannels */
33        $activeChannels = $feed->activeChannels()->with(['platformInstance', 'activePlatformAccounts'])->get();
34
35        return $activeChannels->map(function (PlatformChannel $channel) use ($article, $extractedData) {
36            $account = $channel->activePlatformAccounts()->first();
37
38            if (! $account) {
39                LogSaver::warning('No active account for channel', $channel, [
40                    'article_id' => $article->id
41                ]);
42
43                return null;
44            }
45
46            return $this->publishToChannel($article, $extractedData, $channel, $account);
47        })
48        ->filter();
49    }
50
51    /**
52     * @param array<string, mixed> $extractedData
53     */
54    private function publishToChannel(Article $article, array $extractedData, PlatformChannel $channel, mixed $account): ?ArticlePublication
55    {
56        try {
57            $publisher = new LemmyPublisher($account);
58            $postData = $publisher->publishToChannel($article, $extractedData, $channel);
59
60            $publication = ArticlePublication::create([
61                'article_id' => $article->id,
62                'post_id' => $postData['post_view']['post']['id'],
63                'platform_channel_id' => $channel->id,
64                'published_by' => $account->username,
65                'published_at' => now(),
66                'platform' => $channel->platformInstance->platform->value,
67                'publication_data' => $postData,
68            ]);
69
70            LogSaver::info('Published to channel via routing', $channel, [
71                'article_id' => $article->id,
72                'priority' => $channel->pivot->priority ?? null
73            ]);
74
75            return $publication;
76        } catch (Exception $e) {
77            LogSaver::warning('Failed to publish to channel', $channel, [
78                'article_id' => $article->id,
79                'error' => $e->getMessage()
80            ]);
81
82            return null;
83        }
84    }
85}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:53:46 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-final/Services/Publishing/dashboard.html b/backend/coverage-report-final/Services/Publishing/dashboard.html deleted file mode 100644 index 6a136cb9..00000000 --- a/backend/coverage-report-final/Services/Publishing/dashboard.html +++ /dev/null @@ -1,291 +0,0 @@ - - - - - Dashboard for /var/www/html/backend/app/Services/Publishing - - - - - - - -
-
-
-
- -
-
-
-
-
-
-
-

Classes

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
-
-
-

Insufficient Coverage

-
- - - - - - - - - - - -
ClassCoverage
App\Services\Publishing\ArticlePublishingService0%
-
-
-
-

Project Risks

-
- - - - - - - - - - - -
ClassCRAP
App\Services\Publishing\ArticlePublishingService30
-
-
-
-
-
-

Methods

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
-
-
-

Insufficient Coverage

-
- - - - - - - - - - - - -
MethodCoverage
publishToRoutedChannels0%
publishToChannel0%
-
-
-
-

Project Risks

-
- - - - - - - - - - - - -
MethodCRAP
publishToRoutedChannels12
publishToChannel6
-
-
-
- -
- - - - - - diff --git a/backend/coverage-report-final/Services/Publishing/index.html b/backend/coverage-report-final/Services/Publishing/index.html deleted file mode 100644 index 238ec85c..00000000 --- a/backend/coverage-report-final/Services/Publishing/index.html +++ /dev/null @@ -1,120 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Services/Publishing - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 36
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
ArticlePublishingService.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 36
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- -
- - diff --git a/backend/coverage-report-final/Services/RoutingValidationService.php.html b/backend/coverage-report-final/Services/RoutingValidationService.php.html deleted file mode 100644 index 5ab4a5e2..00000000 --- a/backend/coverage-report-final/Services/RoutingValidationService.php.html +++ /dev/null @@ -1,184 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Services/RoutingValidationService.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 7
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
RoutingValidationService
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 7
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
30
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 validateLanguageCompatibility
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 7
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
30
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Services;
4
5use App\Exceptions\RoutingMismatchException;
6use App\Models\Feed;
7use App\Models\PlatformChannel;
8use Illuminate\Support\Collection;
9
10class RoutingValidationService
11{
12    /**
13     * @param Collection<int, PlatformChannel> $channels
14     * @throws RoutingMismatchException
15     */
16    public function validateLanguageCompatibility(Feed $feed, Collection $channels): void
17    {
18        if (! $feed->language) {
19            return;
20        }
21
22        foreach ($channels as $channel) {
23            if (! $channel->language) {
24                continue;
25            }
26
27            if ($feed->language !== $channel->language) {
28                throw new RoutingMismatchException($feed, $channel);
29            }
30        }
31    }
32}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:53:46 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-final/Services/SystemStatusService.php.html b/backend/coverage-report-final/Services/SystemStatusService.php.html deleted file mode 100644 index 788a4a93..00000000 --- a/backend/coverage-report-final/Services/SystemStatusService.php.html +++ /dev/null @@ -1,226 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Services/SystemStatusService.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 21
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
SystemStatusService
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 21
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
72
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 getSystemStatus
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 20
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
56
 canProcessArticles
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Services;
4
5use App\Models\Feed;
6use App\Models\Route;
7use App\Models\PlatformChannel;
8use App\Models\Setting;
9
10class SystemStatusService
11{
12    /**
13     * @return array{is_enabled: bool, status: string, status_class: string, reasons: array<int, string>}
14     */
15    public function getSystemStatus(): array
16    {
17        $reasons = [];
18        $isEnabled = true;
19
20        if (!Setting::isArticleProcessingEnabled()) {
21            $isEnabled = false;
22            $reasons[] = 'Manually disabled by user';
23        }
24
25        if (!Feed::where('is_active', true)->exists()) {
26            $isEnabled = false;
27            $reasons[] = 'No active feeds configured';
28        }
29
30        if (!PlatformChannel::where('is_active', true)->exists()) {
31            $isEnabled = false;
32            $reasons[] = 'No active platform channels configured';
33        }
34
35        if (!Route::where('is_active', true)->exists()) {
36            $isEnabled = false;
37            $reasons[] = 'No active feed-to-channel routes configured';
38        }
39
40        return [
41            'is_enabled' => $isEnabled,
42            'status' => $isEnabled ? 'Enabled' : 'Disabled',
43            'status_class' => $isEnabled ? 'text-green-600' : 'text-red-600',
44            'reasons' => $reasons,
45        ];
46    }
47
48    public function canProcessArticles(): bool
49    {
50        return $this->getSystemStatus()['is_enabled'];
51    }
52}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:53:46 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-final/Services/dashboard.html b/backend/coverage-report-final/Services/dashboard.html deleted file mode 100644 index 59f55c8a..00000000 --- a/backend/coverage-report-final/Services/dashboard.html +++ /dev/null @@ -1,395 +0,0 @@ - - - - - Dashboard for /var/www/html/backend/app/Services - - - - - - - -
-
-
-
- -
-
-
-
-
-
-
-

Classes

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
- -
-
-

Methods

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
-
- - -
- -
- - - - - - diff --git a/backend/coverage-report-final/Services/index.html b/backend/coverage-report-final/Services/index.html deleted file mode 100644 index 3ed6775c..00000000 --- a/backend/coverage-report-final/Services/index.html +++ /dev/null @@ -1,399 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Services - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 10.78% covered (danger) -
-
-
10.78%
40 / 371
-
- 7.14% covered (danger) -
-
-
7.14%
4 / 56
-
- 5.00% covered (danger) -
-
-
5.00%
1 / 20
Article
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 69
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 7
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
Auth
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 12
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
Factories
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 19
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 5
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
Http
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 44
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
Log
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 17
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 5
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
Parsers
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 102
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 26
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 8
Publishing
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 36
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
DashboardStatsService.php
-
- 100.00% covered (success) -
-
-
100.00%
40 / 40
-
- 100.00% covered (success) -
-
-
100.00%
4 / 4
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
OnboardingRedirectService.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 4
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
RoutingValidationService.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 7
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
SystemStatusService.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 21
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- -
- - diff --git a/backend/coverage-report-final/_css/bootstrap.min.css b/backend/coverage-report-final/_css/bootstrap.min.css deleted file mode 100644 index 27d4921c..00000000 --- a/backend/coverage-report-final/_css/bootstrap.min.css +++ /dev/null @@ -1,6 +0,0 @@ -@charset "UTF-8";/*! - * Bootstrap v5.3.6 (https://getbootstrap.com/) - * Copyright 2011-2025 The Bootstrap Authors - * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) - */:root,[data-bs-theme=light]{--bs-blue:#0d6efd;--bs-indigo:#6610f2;--bs-purple:#6f42c1;--bs-pink:#d63384;--bs-red:#dc3545;--bs-orange:#fd7e14;--bs-yellow:#ffc107;--bs-green:#198754;--bs-teal:#20c997;--bs-cyan:#0dcaf0;--bs-black:#000;--bs-white:#fff;--bs-gray:#6c757d;--bs-gray-dark:#343a40;--bs-gray-100:#f8f9fa;--bs-gray-200:#e9ecef;--bs-gray-300:#dee2e6;--bs-gray-400:#ced4da;--bs-gray-500:#adb5bd;--bs-gray-600:#6c757d;--bs-gray-700:#495057;--bs-gray-800:#343a40;--bs-gray-900:#212529;--bs-primary:#0d6efd;--bs-secondary:#6c757d;--bs-success:#198754;--bs-info:#0dcaf0;--bs-warning:#ffc107;--bs-danger:#dc3545;--bs-light:#f8f9fa;--bs-dark:#212529;--bs-primary-rgb:13,110,253;--bs-secondary-rgb:108,117,125;--bs-success-rgb:25,135,84;--bs-info-rgb:13,202,240;--bs-warning-rgb:255,193,7;--bs-danger-rgb:220,53,69;--bs-light-rgb:248,249,250;--bs-dark-rgb:33,37,41;--bs-primary-text-emphasis:#052c65;--bs-secondary-text-emphasis:#2b2f32;--bs-success-text-emphasis:#0a3622;--bs-info-text-emphasis:#055160;--bs-warning-text-emphasis:#664d03;--bs-danger-text-emphasis:#58151c;--bs-light-text-emphasis:#495057;--bs-dark-text-emphasis:#495057;--bs-primary-bg-subtle:#cfe2ff;--bs-secondary-bg-subtle:#e2e3e5;--bs-success-bg-subtle:#d1e7dd;--bs-info-bg-subtle:#cff4fc;--bs-warning-bg-subtle:#fff3cd;--bs-danger-bg-subtle:#f8d7da;--bs-light-bg-subtle:#fcfcfd;--bs-dark-bg-subtle:#ced4da;--bs-primary-border-subtle:#9ec5fe;--bs-secondary-border-subtle:#c4c8cb;--bs-success-border-subtle:#a3cfbb;--bs-info-border-subtle:#9eeaf9;--bs-warning-border-subtle:#ffe69c;--bs-danger-border-subtle:#f1aeb5;--bs-light-border-subtle:#e9ecef;--bs-dark-border-subtle:#adb5bd;--bs-white-rgb:255,255,255;--bs-black-rgb:0,0,0;--bs-font-sans-serif:system-ui,-apple-system,"Segoe UI",Roboto,"Helvetica Neue","Noto Sans","Liberation Sans",Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";--bs-font-monospace:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;--bs-gradient:linear-gradient(180deg, rgba(255, 255, 255, 0.15), rgba(255, 255, 255, 0));--bs-body-font-family:var(--bs-font-sans-serif);--bs-body-font-size:1rem;--bs-body-font-weight:400;--bs-body-line-height:1.5;--bs-body-color:#212529;--bs-body-color-rgb:33,37,41;--bs-body-bg:#fff;--bs-body-bg-rgb:255,255,255;--bs-emphasis-color:#000;--bs-emphasis-color-rgb:0,0,0;--bs-secondary-color:rgba(33, 37, 41, 0.75);--bs-secondary-color-rgb:33,37,41;--bs-secondary-bg:#e9ecef;--bs-secondary-bg-rgb:233,236,239;--bs-tertiary-color:rgba(33, 37, 41, 0.5);--bs-tertiary-color-rgb:33,37,41;--bs-tertiary-bg:#f8f9fa;--bs-tertiary-bg-rgb:248,249,250;--bs-heading-color:inherit;--bs-link-color:#0d6efd;--bs-link-color-rgb:13,110,253;--bs-link-decoration:underline;--bs-link-hover-color:#0a58ca;--bs-link-hover-color-rgb:10,88,202;--bs-code-color:#d63384;--bs-highlight-color:#212529;--bs-highlight-bg:#fff3cd;--bs-border-width:1px;--bs-border-style:solid;--bs-border-color:#dee2e6;--bs-border-color-translucent:rgba(0, 0, 0, 0.175);--bs-border-radius:0.375rem;--bs-border-radius-sm:0.25rem;--bs-border-radius-lg:0.5rem;--bs-border-radius-xl:1rem;--bs-border-radius-xxl:2rem;--bs-border-radius-2xl:var(--bs-border-radius-xxl);--bs-border-radius-pill:50rem;--bs-box-shadow:0 0.5rem 1rem rgba(0, 0, 0, 0.15);--bs-box-shadow-sm:0 0.125rem 0.25rem rgba(0, 0, 0, 0.075);--bs-box-shadow-lg:0 1rem 3rem rgba(0, 0, 0, 0.175);--bs-box-shadow-inset:inset 0 1px 2px rgba(0, 0, 0, 0.075);--bs-focus-ring-width:0.25rem;--bs-focus-ring-opacity:0.25;--bs-focus-ring-color:rgba(13, 110, 253, 0.25);--bs-form-valid-color:#198754;--bs-form-valid-border-color:#198754;--bs-form-invalid-color:#dc3545;--bs-form-invalid-border-color:#dc3545}[data-bs-theme=dark]{color-scheme:dark;--bs-body-color:#dee2e6;--bs-body-color-rgb:222,226,230;--bs-body-bg:#212529;--bs-body-bg-rgb:33,37,41;--bs-emphasis-color:#fff;--bs-emphasis-color-rgb:255,255,255;--bs-secondary-color:rgba(222, 226, 230, 0.75);--bs-secondary-color-rgb:222,226,230;--bs-secondary-bg:#343a40;--bs-secondary-bg-rgb:52,58,64;--bs-tertiary-color:rgba(222, 226, 230, 0.5);--bs-tertiary-color-rgb:222,226,230;--bs-tertiary-bg:#2b3035;--bs-tertiary-bg-rgb:43,48,53;--bs-primary-text-emphasis:#6ea8fe;--bs-secondary-text-emphasis:#a7acb1;--bs-success-text-emphasis:#75b798;--bs-info-text-emphasis:#6edff6;--bs-warning-text-emphasis:#ffda6a;--bs-danger-text-emphasis:#ea868f;--bs-light-text-emphasis:#f8f9fa;--bs-dark-text-emphasis:#dee2e6;--bs-primary-bg-subtle:#031633;--bs-secondary-bg-subtle:#161719;--bs-success-bg-subtle:#051b11;--bs-info-bg-subtle:#032830;--bs-warning-bg-subtle:#332701;--bs-danger-bg-subtle:#2c0b0e;--bs-light-bg-subtle:#343a40;--bs-dark-bg-subtle:#1a1d20;--bs-primary-border-subtle:#084298;--bs-secondary-border-subtle:#41464b;--bs-success-border-subtle:#0f5132;--bs-info-border-subtle:#087990;--bs-warning-border-subtle:#997404;--bs-danger-border-subtle:#842029;--bs-light-border-subtle:#495057;--bs-dark-border-subtle:#343a40;--bs-heading-color:inherit;--bs-link-color:#6ea8fe;--bs-link-hover-color:#8bb9fe;--bs-link-color-rgb:110,168,254;--bs-link-hover-color-rgb:139,185,254;--bs-code-color:#e685b5;--bs-highlight-color:#dee2e6;--bs-highlight-bg:#664d03;--bs-border-color:#495057;--bs-border-color-translucent:rgba(255, 255, 255, 0.15);--bs-form-valid-color:#75b798;--bs-form-valid-border-color:#75b798;--bs-form-invalid-color:#ea868f;--bs-form-invalid-border-color:#ea868f}*,::after,::before{box-sizing:border-box}@media (prefers-reduced-motion:no-preference){:root{scroll-behavior:smooth}}body{margin:0;font-family:var(--bs-body-font-family);font-size:var(--bs-body-font-size);font-weight:var(--bs-body-font-weight);line-height:var(--bs-body-line-height);color:var(--bs-body-color);text-align:var(--bs-body-text-align);background-color:var(--bs-body-bg);-webkit-text-size-adjust:100%;-webkit-tap-highlight-color:transparent}hr{margin:1rem 0;color:inherit;border:0;border-top:var(--bs-border-width) solid;opacity:.25}.h1,.h2,.h3,.h4,.h5,.h6,h1,h2,h3,h4,h5,h6{margin-top:0;margin-bottom:.5rem;font-weight:500;line-height:1.2;color:var(--bs-heading-color)}.h1,h1{font-size:calc(1.375rem + 1.5vw)}@media (min-width:1200px){.h1,h1{font-size:2.5rem}}.h2,h2{font-size:calc(1.325rem + .9vw)}@media (min-width:1200px){.h2,h2{font-size:2rem}}.h3,h3{font-size:calc(1.3rem + .6vw)}@media (min-width:1200px){.h3,h3{font-size:1.75rem}}.h4,h4{font-size:calc(1.275rem + .3vw)}@media (min-width:1200px){.h4,h4{font-size:1.5rem}}.h5,h5{font-size:1.25rem}.h6,h6{font-size:1rem}p{margin-top:0;margin-bottom:1rem}abbr[title]{-webkit-text-decoration:underline dotted;text-decoration:underline dotted;cursor:help;-webkit-text-decoration-skip-ink:none;text-decoration-skip-ink:none}address{margin-bottom:1rem;font-style:normal;line-height:inherit}ol,ul{padding-left:2rem}dl,ol,ul{margin-top:0;margin-bottom:1rem}ol ol,ol ul,ul ol,ul ul{margin-bottom:0}dt{font-weight:700}dd{margin-bottom:.5rem;margin-left:0}blockquote{margin:0 0 1rem}b,strong{font-weight:bolder}.small,small{font-size:.875em}.mark,mark{padding:.1875em;color:var(--bs-highlight-color);background-color:var(--bs-highlight-bg)}sub,sup{position:relative;font-size:.75em;line-height:0;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}a{color:rgba(var(--bs-link-color-rgb),var(--bs-link-opacity,1));text-decoration:underline}a:hover{--bs-link-color-rgb:var(--bs-link-hover-color-rgb)}a:not([href]):not([class]),a:not([href]):not([class]):hover{color:inherit;text-decoration:none}code,kbd,pre,samp{font-family:var(--bs-font-monospace);font-size:1em}pre{display:block;margin-top:0;margin-bottom:1rem;overflow:auto;font-size:.875em}pre code{font-size:inherit;color:inherit;word-break:normal}code{font-size:.875em;color:var(--bs-code-color);word-wrap:break-word}a>code{color:inherit}kbd{padding:.1875rem .375rem;font-size:.875em;color:var(--bs-body-bg);background-color:var(--bs-body-color);border-radius:.25rem}kbd kbd{padding:0;font-size:1em}figure{margin:0 0 1rem}img,svg{vertical-align:middle}table{caption-side:bottom;border-collapse:collapse}caption{padding-top:.5rem;padding-bottom:.5rem;color:var(--bs-secondary-color);text-align:left}th{text-align:inherit;text-align:-webkit-match-parent}tbody,td,tfoot,th,thead,tr{border-color:inherit;border-style:solid;border-width:0}label{display:inline-block}button{border-radius:0}button:focus:not(:focus-visible){outline:0}button,input,optgroup,select,textarea{margin:0;font-family:inherit;font-size:inherit;line-height:inherit}button,select{text-transform:none}[role=button]{cursor:pointer}select{word-wrap:normal}select:disabled{opacity:1}[list]:not([type=date]):not([type=datetime-local]):not([type=month]):not([type=week]):not([type=time])::-webkit-calendar-picker-indicator{display:none!important}[type=button],[type=reset],[type=submit],button{-webkit-appearance:button}[type=button]:not(:disabled),[type=reset]:not(:disabled),[type=submit]:not(:disabled),button:not(:disabled){cursor:pointer}::-moz-focus-inner{padding:0;border-style:none}textarea{resize:vertical}fieldset{min-width:0;padding:0;margin:0;border:0}legend{float:left;width:100%;padding:0;margin-bottom:.5rem;line-height:inherit;font-size:calc(1.275rem + .3vw)}@media (min-width:1200px){legend{font-size:1.5rem}}legend+*{clear:left}::-webkit-datetime-edit-day-field,::-webkit-datetime-edit-fields-wrapper,::-webkit-datetime-edit-hour-field,::-webkit-datetime-edit-minute,::-webkit-datetime-edit-month-field,::-webkit-datetime-edit-text,::-webkit-datetime-edit-year-field{padding:0}::-webkit-inner-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-color-swatch-wrapper{padding:0}::-webkit-file-upload-button{font:inherit;-webkit-appearance:button}::file-selector-button{font:inherit;-webkit-appearance:button}output{display:inline-block}iframe{border:0}summary{display:list-item;cursor:pointer}progress{vertical-align:baseline}[hidden]{display:none!important}.lead{font-size:1.25rem;font-weight:300}.display-1{font-weight:300;line-height:1.2;font-size:calc(1.625rem + 4.5vw)}@media (min-width:1200px){.display-1{font-size:5rem}}.display-2{font-weight:300;line-height:1.2;font-size:calc(1.575rem + 3.9vw)}@media (min-width:1200px){.display-2{font-size:4.5rem}}.display-3{font-weight:300;line-height:1.2;font-size:calc(1.525rem + 3.3vw)}@media (min-width:1200px){.display-3{font-size:4rem}}.display-4{font-weight:300;line-height:1.2;font-size:calc(1.475rem + 2.7vw)}@media (min-width:1200px){.display-4{font-size:3.5rem}}.display-5{font-weight:300;line-height:1.2;font-size:calc(1.425rem + 2.1vw)}@media (min-width:1200px){.display-5{font-size:3rem}}.display-6{font-weight:300;line-height:1.2;font-size:calc(1.375rem + 1.5vw)}@media (min-width:1200px){.display-6{font-size:2.5rem}}.list-unstyled{padding-left:0;list-style:none}.list-inline{padding-left:0;list-style:none}.list-inline-item{display:inline-block}.list-inline-item:not(:last-child){margin-right:.5rem}.initialism{font-size:.875em;text-transform:uppercase}.blockquote{margin-bottom:1rem;font-size:1.25rem}.blockquote>:last-child{margin-bottom:0}.blockquote-footer{margin-top:-1rem;margin-bottom:1rem;font-size:.875em;color:#6c757d}.blockquote-footer::before{content:"— "}.img-fluid{max-width:100%;height:auto}.img-thumbnail{padding:.25rem;background-color:var(--bs-body-bg);border:var(--bs-border-width) solid var(--bs-border-color);border-radius:var(--bs-border-radius);max-width:100%;height:auto}.figure{display:inline-block}.figure-img{margin-bottom:.5rem;line-height:1}.figure-caption{font-size:.875em;color:var(--bs-secondary-color)}.container,.container-fluid,.container-lg,.container-md,.container-sm,.container-xl,.container-xxl{--bs-gutter-x:1.5rem;--bs-gutter-y:0;width:100%;padding-right:calc(var(--bs-gutter-x) * .5);padding-left:calc(var(--bs-gutter-x) * .5);margin-right:auto;margin-left:auto}@media (min-width:576px){.container,.container-sm{max-width:540px}}@media (min-width:768px){.container,.container-md,.container-sm{max-width:720px}}@media (min-width:992px){.container,.container-lg,.container-md,.container-sm{max-width:960px}}@media (min-width:1200px){.container,.container-lg,.container-md,.container-sm,.container-xl{max-width:1140px}}@media (min-width:1400px){.container,.container-lg,.container-md,.container-sm,.container-xl,.container-xxl{max-width:1320px}}:root{--bs-breakpoint-xs:0;--bs-breakpoint-sm:576px;--bs-breakpoint-md:768px;--bs-breakpoint-lg:992px;--bs-breakpoint-xl:1200px;--bs-breakpoint-xxl:1400px}.row{--bs-gutter-x:1.5rem;--bs-gutter-y:0;display:flex;flex-wrap:wrap;margin-top:calc(-1 * var(--bs-gutter-y));margin-right:calc(-.5 * var(--bs-gutter-x));margin-left:calc(-.5 * var(--bs-gutter-x))}.row>*{flex-shrink:0;width:100%;max-width:100%;padding-right:calc(var(--bs-gutter-x) * .5);padding-left:calc(var(--bs-gutter-x) * .5);margin-top:var(--bs-gutter-y)}.col{flex:1 0 0}.row-cols-auto>*{flex:0 0 auto;width:auto}.row-cols-1>*{flex:0 0 auto;width:100%}.row-cols-2>*{flex:0 0 auto;width:50%}.row-cols-3>*{flex:0 0 auto;width:33.33333333%}.row-cols-4>*{flex:0 0 auto;width:25%}.row-cols-5>*{flex:0 0 auto;width:20%}.row-cols-6>*{flex:0 0 auto;width:16.66666667%}.col-auto{flex:0 0 auto;width:auto}.col-1{flex:0 0 auto;width:8.33333333%}.col-2{flex:0 0 auto;width:16.66666667%}.col-3{flex:0 0 auto;width:25%}.col-4{flex:0 0 auto;width:33.33333333%}.col-5{flex:0 0 auto;width:41.66666667%}.col-6{flex:0 0 auto;width:50%}.col-7{flex:0 0 auto;width:58.33333333%}.col-8{flex:0 0 auto;width:66.66666667%}.col-9{flex:0 0 auto;width:75%}.col-10{flex:0 0 auto;width:83.33333333%}.col-11{flex:0 0 auto;width:91.66666667%}.col-12{flex:0 0 auto;width:100%}.offset-1{margin-left:8.33333333%}.offset-2{margin-left:16.66666667%}.offset-3{margin-left:25%}.offset-4{margin-left:33.33333333%}.offset-5{margin-left:41.66666667%}.offset-6{margin-left:50%}.offset-7{margin-left:58.33333333%}.offset-8{margin-left:66.66666667%}.offset-9{margin-left:75%}.offset-10{margin-left:83.33333333%}.offset-11{margin-left:91.66666667%}.g-0,.gx-0{--bs-gutter-x:0}.g-0,.gy-0{--bs-gutter-y:0}.g-1,.gx-1{--bs-gutter-x:0.25rem}.g-1,.gy-1{--bs-gutter-y:0.25rem}.g-2,.gx-2{--bs-gutter-x:0.5rem}.g-2,.gy-2{--bs-gutter-y:0.5rem}.g-3,.gx-3{--bs-gutter-x:1rem}.g-3,.gy-3{--bs-gutter-y:1rem}.g-4,.gx-4{--bs-gutter-x:1.5rem}.g-4,.gy-4{--bs-gutter-y:1.5rem}.g-5,.gx-5{--bs-gutter-x:3rem}.g-5,.gy-5{--bs-gutter-y:3rem}@media (min-width:576px){.col-sm{flex:1 0 0}.row-cols-sm-auto>*{flex:0 0 auto;width:auto}.row-cols-sm-1>*{flex:0 0 auto;width:100%}.row-cols-sm-2>*{flex:0 0 auto;width:50%}.row-cols-sm-3>*{flex:0 0 auto;width:33.33333333%}.row-cols-sm-4>*{flex:0 0 auto;width:25%}.row-cols-sm-5>*{flex:0 0 auto;width:20%}.row-cols-sm-6>*{flex:0 0 auto;width:16.66666667%}.col-sm-auto{flex:0 0 auto;width:auto}.col-sm-1{flex:0 0 auto;width:8.33333333%}.col-sm-2{flex:0 0 auto;width:16.66666667%}.col-sm-3{flex:0 0 auto;width:25%}.col-sm-4{flex:0 0 auto;width:33.33333333%}.col-sm-5{flex:0 0 auto;width:41.66666667%}.col-sm-6{flex:0 0 auto;width:50%}.col-sm-7{flex:0 0 auto;width:58.33333333%}.col-sm-8{flex:0 0 auto;width:66.66666667%}.col-sm-9{flex:0 0 auto;width:75%}.col-sm-10{flex:0 0 auto;width:83.33333333%}.col-sm-11{flex:0 0 auto;width:91.66666667%}.col-sm-12{flex:0 0 auto;width:100%}.offset-sm-0{margin-left:0}.offset-sm-1{margin-left:8.33333333%}.offset-sm-2{margin-left:16.66666667%}.offset-sm-3{margin-left:25%}.offset-sm-4{margin-left:33.33333333%}.offset-sm-5{margin-left:41.66666667%}.offset-sm-6{margin-left:50%}.offset-sm-7{margin-left:58.33333333%}.offset-sm-8{margin-left:66.66666667%}.offset-sm-9{margin-left:75%}.offset-sm-10{margin-left:83.33333333%}.offset-sm-11{margin-left:91.66666667%}.g-sm-0,.gx-sm-0{--bs-gutter-x:0}.g-sm-0,.gy-sm-0{--bs-gutter-y:0}.g-sm-1,.gx-sm-1{--bs-gutter-x:0.25rem}.g-sm-1,.gy-sm-1{--bs-gutter-y:0.25rem}.g-sm-2,.gx-sm-2{--bs-gutter-x:0.5rem}.g-sm-2,.gy-sm-2{--bs-gutter-y:0.5rem}.g-sm-3,.gx-sm-3{--bs-gutter-x:1rem}.g-sm-3,.gy-sm-3{--bs-gutter-y:1rem}.g-sm-4,.gx-sm-4{--bs-gutter-x:1.5rem}.g-sm-4,.gy-sm-4{--bs-gutter-y:1.5rem}.g-sm-5,.gx-sm-5{--bs-gutter-x:3rem}.g-sm-5,.gy-sm-5{--bs-gutter-y:3rem}}@media (min-width:768px){.col-md{flex:1 0 0}.row-cols-md-auto>*{flex:0 0 auto;width:auto}.row-cols-md-1>*{flex:0 0 auto;width:100%}.row-cols-md-2>*{flex:0 0 auto;width:50%}.row-cols-md-3>*{flex:0 0 auto;width:33.33333333%}.row-cols-md-4>*{flex:0 0 auto;width:25%}.row-cols-md-5>*{flex:0 0 auto;width:20%}.row-cols-md-6>*{flex:0 0 auto;width:16.66666667%}.col-md-auto{flex:0 0 auto;width:auto}.col-md-1{flex:0 0 auto;width:8.33333333%}.col-md-2{flex:0 0 auto;width:16.66666667%}.col-md-3{flex:0 0 auto;width:25%}.col-md-4{flex:0 0 auto;width:33.33333333%}.col-md-5{flex:0 0 auto;width:41.66666667%}.col-md-6{flex:0 0 auto;width:50%}.col-md-7{flex:0 0 auto;width:58.33333333%}.col-md-8{flex:0 0 auto;width:66.66666667%}.col-md-9{flex:0 0 auto;width:75%}.col-md-10{flex:0 0 auto;width:83.33333333%}.col-md-11{flex:0 0 auto;width:91.66666667%}.col-md-12{flex:0 0 auto;width:100%}.offset-md-0{margin-left:0}.offset-md-1{margin-left:8.33333333%}.offset-md-2{margin-left:16.66666667%}.offset-md-3{margin-left:25%}.offset-md-4{margin-left:33.33333333%}.offset-md-5{margin-left:41.66666667%}.offset-md-6{margin-left:50%}.offset-md-7{margin-left:58.33333333%}.offset-md-8{margin-left:66.66666667%}.offset-md-9{margin-left:75%}.offset-md-10{margin-left:83.33333333%}.offset-md-11{margin-left:91.66666667%}.g-md-0,.gx-md-0{--bs-gutter-x:0}.g-md-0,.gy-md-0{--bs-gutter-y:0}.g-md-1,.gx-md-1{--bs-gutter-x:0.25rem}.g-md-1,.gy-md-1{--bs-gutter-y:0.25rem}.g-md-2,.gx-md-2{--bs-gutter-x:0.5rem}.g-md-2,.gy-md-2{--bs-gutter-y:0.5rem}.g-md-3,.gx-md-3{--bs-gutter-x:1rem}.g-md-3,.gy-md-3{--bs-gutter-y:1rem}.g-md-4,.gx-md-4{--bs-gutter-x:1.5rem}.g-md-4,.gy-md-4{--bs-gutter-y:1.5rem}.g-md-5,.gx-md-5{--bs-gutter-x:3rem}.g-md-5,.gy-md-5{--bs-gutter-y:3rem}}@media (min-width:992px){.col-lg{flex:1 0 0}.row-cols-lg-auto>*{flex:0 0 auto;width:auto}.row-cols-lg-1>*{flex:0 0 auto;width:100%}.row-cols-lg-2>*{flex:0 0 auto;width:50%}.row-cols-lg-3>*{flex:0 0 auto;width:33.33333333%}.row-cols-lg-4>*{flex:0 0 auto;width:25%}.row-cols-lg-5>*{flex:0 0 auto;width:20%}.row-cols-lg-6>*{flex:0 0 auto;width:16.66666667%}.col-lg-auto{flex:0 0 auto;width:auto}.col-lg-1{flex:0 0 auto;width:8.33333333%}.col-lg-2{flex:0 0 auto;width:16.66666667%}.col-lg-3{flex:0 0 auto;width:25%}.col-lg-4{flex:0 0 auto;width:33.33333333%}.col-lg-5{flex:0 0 auto;width:41.66666667%}.col-lg-6{flex:0 0 auto;width:50%}.col-lg-7{flex:0 0 auto;width:58.33333333%}.col-lg-8{flex:0 0 auto;width:66.66666667%}.col-lg-9{flex:0 0 auto;width:75%}.col-lg-10{flex:0 0 auto;width:83.33333333%}.col-lg-11{flex:0 0 auto;width:91.66666667%}.col-lg-12{flex:0 0 auto;width:100%}.offset-lg-0{margin-left:0}.offset-lg-1{margin-left:8.33333333%}.offset-lg-2{margin-left:16.66666667%}.offset-lg-3{margin-left:25%}.offset-lg-4{margin-left:33.33333333%}.offset-lg-5{margin-left:41.66666667%}.offset-lg-6{margin-left:50%}.offset-lg-7{margin-left:58.33333333%}.offset-lg-8{margin-left:66.66666667%}.offset-lg-9{margin-left:75%}.offset-lg-10{margin-left:83.33333333%}.offset-lg-11{margin-left:91.66666667%}.g-lg-0,.gx-lg-0{--bs-gutter-x:0}.g-lg-0,.gy-lg-0{--bs-gutter-y:0}.g-lg-1,.gx-lg-1{--bs-gutter-x:0.25rem}.g-lg-1,.gy-lg-1{--bs-gutter-y:0.25rem}.g-lg-2,.gx-lg-2{--bs-gutter-x:0.5rem}.g-lg-2,.gy-lg-2{--bs-gutter-y:0.5rem}.g-lg-3,.gx-lg-3{--bs-gutter-x:1rem}.g-lg-3,.gy-lg-3{--bs-gutter-y:1rem}.g-lg-4,.gx-lg-4{--bs-gutter-x:1.5rem}.g-lg-4,.gy-lg-4{--bs-gutter-y:1.5rem}.g-lg-5,.gx-lg-5{--bs-gutter-x:3rem}.g-lg-5,.gy-lg-5{--bs-gutter-y:3rem}}@media (min-width:1200px){.col-xl{flex:1 0 0}.row-cols-xl-auto>*{flex:0 0 auto;width:auto}.row-cols-xl-1>*{flex:0 0 auto;width:100%}.row-cols-xl-2>*{flex:0 0 auto;width:50%}.row-cols-xl-3>*{flex:0 0 auto;width:33.33333333%}.row-cols-xl-4>*{flex:0 0 auto;width:25%}.row-cols-xl-5>*{flex:0 0 auto;width:20%}.row-cols-xl-6>*{flex:0 0 auto;width:16.66666667%}.col-xl-auto{flex:0 0 auto;width:auto}.col-xl-1{flex:0 0 auto;width:8.33333333%}.col-xl-2{flex:0 0 auto;width:16.66666667%}.col-xl-3{flex:0 0 auto;width:25%}.col-xl-4{flex:0 0 auto;width:33.33333333%}.col-xl-5{flex:0 0 auto;width:41.66666667%}.col-xl-6{flex:0 0 auto;width:50%}.col-xl-7{flex:0 0 auto;width:58.33333333%}.col-xl-8{flex:0 0 auto;width:66.66666667%}.col-xl-9{flex:0 0 auto;width:75%}.col-xl-10{flex:0 0 auto;width:83.33333333%}.col-xl-11{flex:0 0 auto;width:91.66666667%}.col-xl-12{flex:0 0 auto;width:100%}.offset-xl-0{margin-left:0}.offset-xl-1{margin-left:8.33333333%}.offset-xl-2{margin-left:16.66666667%}.offset-xl-3{margin-left:25%}.offset-xl-4{margin-left:33.33333333%}.offset-xl-5{margin-left:41.66666667%}.offset-xl-6{margin-left:50%}.offset-xl-7{margin-left:58.33333333%}.offset-xl-8{margin-left:66.66666667%}.offset-xl-9{margin-left:75%}.offset-xl-10{margin-left:83.33333333%}.offset-xl-11{margin-left:91.66666667%}.g-xl-0,.gx-xl-0{--bs-gutter-x:0}.g-xl-0,.gy-xl-0{--bs-gutter-y:0}.g-xl-1,.gx-xl-1{--bs-gutter-x:0.25rem}.g-xl-1,.gy-xl-1{--bs-gutter-y:0.25rem}.g-xl-2,.gx-xl-2{--bs-gutter-x:0.5rem}.g-xl-2,.gy-xl-2{--bs-gutter-y:0.5rem}.g-xl-3,.gx-xl-3{--bs-gutter-x:1rem}.g-xl-3,.gy-xl-3{--bs-gutter-y:1rem}.g-xl-4,.gx-xl-4{--bs-gutter-x:1.5rem}.g-xl-4,.gy-xl-4{--bs-gutter-y:1.5rem}.g-xl-5,.gx-xl-5{--bs-gutter-x:3rem}.g-xl-5,.gy-xl-5{--bs-gutter-y:3rem}}@media (min-width:1400px){.col-xxl{flex:1 0 0}.row-cols-xxl-auto>*{flex:0 0 auto;width:auto}.row-cols-xxl-1>*{flex:0 0 auto;width:100%}.row-cols-xxl-2>*{flex:0 0 auto;width:50%}.row-cols-xxl-3>*{flex:0 0 auto;width:33.33333333%}.row-cols-xxl-4>*{flex:0 0 auto;width:25%}.row-cols-xxl-5>*{flex:0 0 auto;width:20%}.row-cols-xxl-6>*{flex:0 0 auto;width:16.66666667%}.col-xxl-auto{flex:0 0 auto;width:auto}.col-xxl-1{flex:0 0 auto;width:8.33333333%}.col-xxl-2{flex:0 0 auto;width:16.66666667%}.col-xxl-3{flex:0 0 auto;width:25%}.col-xxl-4{flex:0 0 auto;width:33.33333333%}.col-xxl-5{flex:0 0 auto;width:41.66666667%}.col-xxl-6{flex:0 0 auto;width:50%}.col-xxl-7{flex:0 0 auto;width:58.33333333%}.col-xxl-8{flex:0 0 auto;width:66.66666667%}.col-xxl-9{flex:0 0 auto;width:75%}.col-xxl-10{flex:0 0 auto;width:83.33333333%}.col-xxl-11{flex:0 0 auto;width:91.66666667%}.col-xxl-12{flex:0 0 auto;width:100%}.offset-xxl-0{margin-left:0}.offset-xxl-1{margin-left:8.33333333%}.offset-xxl-2{margin-left:16.66666667%}.offset-xxl-3{margin-left:25%}.offset-xxl-4{margin-left:33.33333333%}.offset-xxl-5{margin-left:41.66666667%}.offset-xxl-6{margin-left:50%}.offset-xxl-7{margin-left:58.33333333%}.offset-xxl-8{margin-left:66.66666667%}.offset-xxl-9{margin-left:75%}.offset-xxl-10{margin-left:83.33333333%}.offset-xxl-11{margin-left:91.66666667%}.g-xxl-0,.gx-xxl-0{--bs-gutter-x:0}.g-xxl-0,.gy-xxl-0{--bs-gutter-y:0}.g-xxl-1,.gx-xxl-1{--bs-gutter-x:0.25rem}.g-xxl-1,.gy-xxl-1{--bs-gutter-y:0.25rem}.g-xxl-2,.gx-xxl-2{--bs-gutter-x:0.5rem}.g-xxl-2,.gy-xxl-2{--bs-gutter-y:0.5rem}.g-xxl-3,.gx-xxl-3{--bs-gutter-x:1rem}.g-xxl-3,.gy-xxl-3{--bs-gutter-y:1rem}.g-xxl-4,.gx-xxl-4{--bs-gutter-x:1.5rem}.g-xxl-4,.gy-xxl-4{--bs-gutter-y:1.5rem}.g-xxl-5,.gx-xxl-5{--bs-gutter-x:3rem}.g-xxl-5,.gy-xxl-5{--bs-gutter-y:3rem}}.table{--bs-table-color-type:initial;--bs-table-bg-type:initial;--bs-table-color-state:initial;--bs-table-bg-state:initial;--bs-table-color:var(--bs-emphasis-color);--bs-table-bg:var(--bs-body-bg);--bs-table-border-color:var(--bs-border-color);--bs-table-accent-bg:transparent;--bs-table-striped-color:var(--bs-emphasis-color);--bs-table-striped-bg:rgba(var(--bs-emphasis-color-rgb), 0.05);--bs-table-active-color:var(--bs-emphasis-color);--bs-table-active-bg:rgba(var(--bs-emphasis-color-rgb), 0.1);--bs-table-hover-color:var(--bs-emphasis-color);--bs-table-hover-bg:rgba(var(--bs-emphasis-color-rgb), 0.075);width:100%;margin-bottom:1rem;vertical-align:top;border-color:var(--bs-table-border-color)}.table>:not(caption)>*>*{padding:.5rem .5rem;color:var(--bs-table-color-state,var(--bs-table-color-type,var(--bs-table-color)));background-color:var(--bs-table-bg);border-bottom-width:var(--bs-border-width);box-shadow:inset 0 0 0 9999px var(--bs-table-bg-state,var(--bs-table-bg-type,var(--bs-table-accent-bg)))}.table>tbody{vertical-align:inherit}.table>thead{vertical-align:bottom}.table-group-divider{border-top:calc(var(--bs-border-width) * 2) solid currentcolor}.caption-top{caption-side:top}.table-sm>:not(caption)>*>*{padding:.25rem .25rem}.table-bordered>:not(caption)>*{border-width:var(--bs-border-width) 0}.table-bordered>:not(caption)>*>*{border-width:0 var(--bs-border-width)}.table-borderless>:not(caption)>*>*{border-bottom-width:0}.table-borderless>:not(:first-child){border-top-width:0}.table-striped>tbody>tr:nth-of-type(odd)>*{--bs-table-color-type:var(--bs-table-striped-color);--bs-table-bg-type:var(--bs-table-striped-bg)}.table-striped-columns>:not(caption)>tr>:nth-child(2n){--bs-table-color-type:var(--bs-table-striped-color);--bs-table-bg-type:var(--bs-table-striped-bg)}.table-active{--bs-table-color-state:var(--bs-table-active-color);--bs-table-bg-state:var(--bs-table-active-bg)}.table-hover>tbody>tr:hover>*{--bs-table-color-state:var(--bs-table-hover-color);--bs-table-bg-state:var(--bs-table-hover-bg)}.table-primary{--bs-table-color:#000;--bs-table-bg:#cfe2ff;--bs-table-border-color:#a6b5cc;--bs-table-striped-bg:#c5d7f2;--bs-table-striped-color:#000;--bs-table-active-bg:#bacbe6;--bs-table-active-color:#000;--bs-table-hover-bg:#bfd1ec;--bs-table-hover-color:#000;color:var(--bs-table-color);border-color:var(--bs-table-border-color)}.table-secondary{--bs-table-color:#000;--bs-table-bg:#e2e3e5;--bs-table-border-color:#b5b6b7;--bs-table-striped-bg:#d7d8da;--bs-table-striped-color:#000;--bs-table-active-bg:#cbccce;--bs-table-active-color:#000;--bs-table-hover-bg:#d1d2d4;--bs-table-hover-color:#000;color:var(--bs-table-color);border-color:var(--bs-table-border-color)}.table-success{--bs-table-color:#000;--bs-table-bg:#d1e7dd;--bs-table-border-color:#a7b9b1;--bs-table-striped-bg:#c7dbd2;--bs-table-striped-color:#000;--bs-table-active-bg:#bcd0c7;--bs-table-active-color:#000;--bs-table-hover-bg:#c1d6cc;--bs-table-hover-color:#000;color:var(--bs-table-color);border-color:var(--bs-table-border-color)}.table-info{--bs-table-color:#000;--bs-table-bg:#cff4fc;--bs-table-border-color:#a6c3ca;--bs-table-striped-bg:#c5e8ef;--bs-table-striped-color:#000;--bs-table-active-bg:#badce3;--bs-table-active-color:#000;--bs-table-hover-bg:#bfe2e9;--bs-table-hover-color:#000;color:var(--bs-table-color);border-color:var(--bs-table-border-color)}.table-warning{--bs-table-color:#000;--bs-table-bg:#fff3cd;--bs-table-border-color:#ccc2a4;--bs-table-striped-bg:#f2e7c3;--bs-table-striped-color:#000;--bs-table-active-bg:#e6dbb9;--bs-table-active-color:#000;--bs-table-hover-bg:#ece1be;--bs-table-hover-color:#000;color:var(--bs-table-color);border-color:var(--bs-table-border-color)}.table-danger{--bs-table-color:#000;--bs-table-bg:#f8d7da;--bs-table-border-color:#c6acae;--bs-table-striped-bg:#eccccf;--bs-table-striped-color:#000;--bs-table-active-bg:#dfc2c4;--bs-table-active-color:#000;--bs-table-hover-bg:#e5c7ca;--bs-table-hover-color:#000;color:var(--bs-table-color);border-color:var(--bs-table-border-color)}.table-light{--bs-table-color:#000;--bs-table-bg:#f8f9fa;--bs-table-border-color:#c6c7c8;--bs-table-striped-bg:#ecedee;--bs-table-striped-color:#000;--bs-table-active-bg:#dfe0e1;--bs-table-active-color:#000;--bs-table-hover-bg:#e5e6e7;--bs-table-hover-color:#000;color:var(--bs-table-color);border-color:var(--bs-table-border-color)}.table-dark{--bs-table-color:#fff;--bs-table-bg:#212529;--bs-table-border-color:#4d5154;--bs-table-striped-bg:#2c3034;--bs-table-striped-color:#fff;--bs-table-active-bg:#373b3e;--bs-table-active-color:#fff;--bs-table-hover-bg:#323539;--bs-table-hover-color:#fff;color:var(--bs-table-color);border-color:var(--bs-table-border-color)}.table-responsive{overflow-x:auto;-webkit-overflow-scrolling:touch}@media (max-width:575.98px){.table-responsive-sm{overflow-x:auto;-webkit-overflow-scrolling:touch}}@media (max-width:767.98px){.table-responsive-md{overflow-x:auto;-webkit-overflow-scrolling:touch}}@media (max-width:991.98px){.table-responsive-lg{overflow-x:auto;-webkit-overflow-scrolling:touch}}@media (max-width:1199.98px){.table-responsive-xl{overflow-x:auto;-webkit-overflow-scrolling:touch}}@media (max-width:1399.98px){.table-responsive-xxl{overflow-x:auto;-webkit-overflow-scrolling:touch}}.form-label{margin-bottom:.5rem}.col-form-label{padding-top:calc(.375rem + var(--bs-border-width));padding-bottom:calc(.375rem + var(--bs-border-width));margin-bottom:0;font-size:inherit;line-height:1.5}.col-form-label-lg{padding-top:calc(.5rem + var(--bs-border-width));padding-bottom:calc(.5rem + var(--bs-border-width));font-size:1.25rem}.col-form-label-sm{padding-top:calc(.25rem + var(--bs-border-width));padding-bottom:calc(.25rem + var(--bs-border-width));font-size:.875rem}.form-text{margin-top:.25rem;font-size:.875em;color:var(--bs-secondary-color)}.form-control{display:block;width:100%;padding:.375rem .75rem;font-size:1rem;font-weight:400;line-height:1.5;color:var(--bs-body-color);-webkit-appearance:none;-moz-appearance:none;appearance:none;background-color:var(--bs-body-bg);background-clip:padding-box;border:var(--bs-border-width) solid var(--bs-border-color);border-radius:var(--bs-border-radius);transition:border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.form-control{transition:none}}.form-control[type=file]{overflow:hidden}.form-control[type=file]:not(:disabled):not([readonly]){cursor:pointer}.form-control:focus{color:var(--bs-body-color);background-color:var(--bs-body-bg);border-color:#86b7fe;outline:0;box-shadow:0 0 0 .25rem rgba(13,110,253,.25)}.form-control::-webkit-date-and-time-value{min-width:85px;height:1.5em;margin:0}.form-control::-webkit-datetime-edit{display:block;padding:0}.form-control::placeholder{color:var(--bs-secondary-color);opacity:1}.form-control:disabled{background-color:var(--bs-secondary-bg);opacity:1}.form-control::-webkit-file-upload-button{padding:.375rem .75rem;margin:-.375rem -.75rem;-webkit-margin-end:.75rem;margin-inline-end:.75rem;color:var(--bs-body-color);background-color:var(--bs-tertiary-bg);pointer-events:none;border-color:inherit;border-style:solid;border-width:0;border-inline-end-width:var(--bs-border-width);border-radius:0;-webkit-transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}.form-control::file-selector-button{padding:.375rem .75rem;margin:-.375rem -.75rem;-webkit-margin-end:.75rem;margin-inline-end:.75rem;color:var(--bs-body-color);background-color:var(--bs-tertiary-bg);pointer-events:none;border-color:inherit;border-style:solid;border-width:0;border-inline-end-width:var(--bs-border-width);border-radius:0;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.form-control::-webkit-file-upload-button{-webkit-transition:none;transition:none}.form-control::file-selector-button{transition:none}}.form-control:hover:not(:disabled):not([readonly])::-webkit-file-upload-button{background-color:var(--bs-secondary-bg)}.form-control:hover:not(:disabled):not([readonly])::file-selector-button{background-color:var(--bs-secondary-bg)}.form-control-plaintext{display:block;width:100%;padding:.375rem 0;margin-bottom:0;line-height:1.5;color:var(--bs-body-color);background-color:transparent;border:solid transparent;border-width:var(--bs-border-width) 0}.form-control-plaintext:focus{outline:0}.form-control-plaintext.form-control-lg,.form-control-plaintext.form-control-sm{padding-right:0;padding-left:0}.form-control-sm{min-height:calc(1.5em + .5rem + calc(var(--bs-border-width) * 2));padding:.25rem .5rem;font-size:.875rem;border-radius:var(--bs-border-radius-sm)}.form-control-sm::-webkit-file-upload-button{padding:.25rem .5rem;margin:-.25rem -.5rem;-webkit-margin-end:.5rem;margin-inline-end:.5rem}.form-control-sm::file-selector-button{padding:.25rem .5rem;margin:-.25rem -.5rem;-webkit-margin-end:.5rem;margin-inline-end:.5rem}.form-control-lg{min-height:calc(1.5em + 1rem + calc(var(--bs-border-width) * 2));padding:.5rem 1rem;font-size:1.25rem;border-radius:var(--bs-border-radius-lg)}.form-control-lg::-webkit-file-upload-button{padding:.5rem 1rem;margin:-.5rem -1rem;-webkit-margin-end:1rem;margin-inline-end:1rem}.form-control-lg::file-selector-button{padding:.5rem 1rem;margin:-.5rem -1rem;-webkit-margin-end:1rem;margin-inline-end:1rem}textarea.form-control{min-height:calc(1.5em + .75rem + calc(var(--bs-border-width) * 2))}textarea.form-control-sm{min-height:calc(1.5em + .5rem + calc(var(--bs-border-width) * 2))}textarea.form-control-lg{min-height:calc(1.5em + 1rem + calc(var(--bs-border-width) * 2))}.form-control-color{width:3rem;height:calc(1.5em + .75rem + calc(var(--bs-border-width) * 2));padding:.375rem}.form-control-color:not(:disabled):not([readonly]){cursor:pointer}.form-control-color::-moz-color-swatch{border:0!important;border-radius:var(--bs-border-radius)}.form-control-color::-webkit-color-swatch{border:0!important;border-radius:var(--bs-border-radius)}.form-control-color.form-control-sm{height:calc(1.5em + .5rem + calc(var(--bs-border-width) * 2))}.form-control-color.form-control-lg{height:calc(1.5em + 1rem + calc(var(--bs-border-width) * 2))}.form-select{--bs-form-select-bg-img:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%23343a40' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='m2 5 6 6 6-6'/%3e%3c/svg%3e");display:block;width:100%;padding:.375rem 2.25rem .375rem .75rem;font-size:1rem;font-weight:400;line-height:1.5;color:var(--bs-body-color);-webkit-appearance:none;-moz-appearance:none;appearance:none;background-color:var(--bs-body-bg);background-image:var(--bs-form-select-bg-img),var(--bs-form-select-bg-icon,none);background-repeat:no-repeat;background-position:right .75rem center;background-size:16px 12px;border:var(--bs-border-width) solid var(--bs-border-color);border-radius:var(--bs-border-radius);transition:border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.form-select{transition:none}}.form-select:focus{border-color:#86b7fe;outline:0;box-shadow:0 0 0 .25rem rgba(13,110,253,.25)}.form-select[multiple],.form-select[size]:not([size="1"]){padding-right:.75rem;background-image:none}.form-select:disabled{background-color:var(--bs-secondary-bg)}.form-select:-moz-focusring{color:transparent;text-shadow:0 0 0 var(--bs-body-color)}.form-select-sm{padding-top:.25rem;padding-bottom:.25rem;padding-left:.5rem;font-size:.875rem;border-radius:var(--bs-border-radius-sm)}.form-select-lg{padding-top:.5rem;padding-bottom:.5rem;padding-left:1rem;font-size:1.25rem;border-radius:var(--bs-border-radius-lg)}[data-bs-theme=dark] .form-select{--bs-form-select-bg-img:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%23dee2e6' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='m2 5 6 6 6-6'/%3e%3c/svg%3e")}.form-check{display:block;min-height:1.5rem;padding-left:1.5em;margin-bottom:.125rem}.form-check .form-check-input{float:left;margin-left:-1.5em}.form-check-reverse{padding-right:1.5em;padding-left:0;text-align:right}.form-check-reverse .form-check-input{float:right;margin-right:-1.5em;margin-left:0}.form-check-input{--bs-form-check-bg:var(--bs-body-bg);flex-shrink:0;width:1em;height:1em;margin-top:.25em;vertical-align:top;-webkit-appearance:none;-moz-appearance:none;appearance:none;background-color:var(--bs-form-check-bg);background-image:var(--bs-form-check-bg-image);background-repeat:no-repeat;background-position:center;background-size:contain;border:var(--bs-border-width) solid var(--bs-border-color);-webkit-print-color-adjust:exact;color-adjust:exact;print-color-adjust:exact}.form-check-input[type=checkbox]{border-radius:.25em}.form-check-input[type=radio]{border-radius:50%}.form-check-input:active{filter:brightness(90%)}.form-check-input:focus{border-color:#86b7fe;outline:0;box-shadow:0 0 0 .25rem rgba(13,110,253,.25)}.form-check-input:checked{background-color:#0d6efd;border-color:#0d6efd}.form-check-input:checked[type=checkbox]{--bs-form-check-bg-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3e%3cpath fill='none' stroke='%23fff' stroke-linecap='round' stroke-linejoin='round' stroke-width='3' d='m6 10 3 3 6-6'/%3e%3c/svg%3e")}.form-check-input:checked[type=radio]{--bs-form-check-bg-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='2' fill='%23fff'/%3e%3c/svg%3e")}.form-check-input[type=checkbox]:indeterminate{background-color:#0d6efd;border-color:#0d6efd;--bs-form-check-bg-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3e%3cpath fill='none' stroke='%23fff' stroke-linecap='round' stroke-linejoin='round' stroke-width='3' d='M6 10h8'/%3e%3c/svg%3e")}.form-check-input:disabled{pointer-events:none;filter:none;opacity:.5}.form-check-input:disabled~.form-check-label,.form-check-input[disabled]~.form-check-label{cursor:default;opacity:.5}.form-switch{padding-left:2.5em}.form-switch .form-check-input{--bs-form-switch-bg:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='rgba%280, 0, 0, 0.25%29'/%3e%3c/svg%3e");width:2em;margin-left:-2.5em;background-image:var(--bs-form-switch-bg);background-position:left center;border-radius:2em;transition:background-position .15s ease-in-out}@media (prefers-reduced-motion:reduce){.form-switch .form-check-input{transition:none}}.form-switch .form-check-input:focus{--bs-form-switch-bg:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='%2386b7fe'/%3e%3c/svg%3e")}.form-switch .form-check-input:checked{background-position:right center;--bs-form-switch-bg:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='%23fff'/%3e%3c/svg%3e")}.form-switch.form-check-reverse{padding-right:2.5em;padding-left:0}.form-switch.form-check-reverse .form-check-input{margin-right:-2.5em;margin-left:0}.form-check-inline{display:inline-block;margin-right:1rem}.btn-check{position:absolute;clip:rect(0,0,0,0);pointer-events:none}.btn-check:disabled+.btn,.btn-check[disabled]+.btn{pointer-events:none;filter:none;opacity:.65}[data-bs-theme=dark] .form-switch .form-check-input:not(:checked):not(:focus){--bs-form-switch-bg:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='rgba%28255, 255, 255, 0.25%29'/%3e%3c/svg%3e")}.form-range{width:100%;height:1.5rem;padding:0;-webkit-appearance:none;-moz-appearance:none;appearance:none;background-color:transparent}.form-range:focus{outline:0}.form-range:focus::-webkit-slider-thumb{box-shadow:0 0 0 1px #fff,0 0 0 .25rem rgba(13,110,253,.25)}.form-range:focus::-moz-range-thumb{box-shadow:0 0 0 1px #fff,0 0 0 .25rem rgba(13,110,253,.25)}.form-range::-moz-focus-outer{border:0}.form-range::-webkit-slider-thumb{width:1rem;height:1rem;margin-top:-.25rem;-webkit-appearance:none;appearance:none;background-color:#0d6efd;border:0;border-radius:1rem;-webkit-transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.form-range::-webkit-slider-thumb{-webkit-transition:none;transition:none}}.form-range::-webkit-slider-thumb:active{background-color:#b6d4fe}.form-range::-webkit-slider-runnable-track{width:100%;height:.5rem;color:transparent;cursor:pointer;background-color:var(--bs-secondary-bg);border-color:transparent;border-radius:1rem}.form-range::-moz-range-thumb{width:1rem;height:1rem;-moz-appearance:none;appearance:none;background-color:#0d6efd;border:0;border-radius:1rem;-moz-transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.form-range::-moz-range-thumb{-moz-transition:none;transition:none}}.form-range::-moz-range-thumb:active{background-color:#b6d4fe}.form-range::-moz-range-track{width:100%;height:.5rem;color:transparent;cursor:pointer;background-color:var(--bs-secondary-bg);border-color:transparent;border-radius:1rem}.form-range:disabled{pointer-events:none}.form-range:disabled::-webkit-slider-thumb{background-color:var(--bs-secondary-color)}.form-range:disabled::-moz-range-thumb{background-color:var(--bs-secondary-color)}.form-floating{position:relative}.form-floating>.form-control,.form-floating>.form-control-plaintext,.form-floating>.form-select{height:calc(3.5rem + calc(var(--bs-border-width) * 2));min-height:calc(3.5rem + calc(var(--bs-border-width) * 2));line-height:1.25}.form-floating>label{position:absolute;top:0;left:0;z-index:2;max-width:100%;height:100%;padding:1rem .75rem;overflow:hidden;color:rgba(var(--bs-body-color-rgb),.65);text-align:start;text-overflow:ellipsis;white-space:nowrap;pointer-events:none;border:var(--bs-border-width) solid transparent;transform-origin:0 0;transition:opacity .1s ease-in-out,transform .1s ease-in-out}@media (prefers-reduced-motion:reduce){.form-floating>label{transition:none}}.form-floating>.form-control,.form-floating>.form-control-plaintext{padding:1rem .75rem}.form-floating>.form-control-plaintext::placeholder,.form-floating>.form-control::placeholder{color:transparent}.form-floating>.form-control-plaintext:focus,.form-floating>.form-control-plaintext:not(:placeholder-shown),.form-floating>.form-control:focus,.form-floating>.form-control:not(:placeholder-shown){padding-top:1.625rem;padding-bottom:.625rem}.form-floating>.form-control-plaintext:-webkit-autofill,.form-floating>.form-control:-webkit-autofill{padding-top:1.625rem;padding-bottom:.625rem}.form-floating>.form-select{padding-top:1.625rem;padding-bottom:.625rem;padding-left:.75rem}.form-floating>.form-control-plaintext~label,.form-floating>.form-control:focus~label,.form-floating>.form-control:not(:placeholder-shown)~label,.form-floating>.form-select~label{transform:scale(.85) translateY(-.5rem) translateX(.15rem)}.form-floating>.form-control:-webkit-autofill~label{transform:scale(.85) translateY(-.5rem) translateX(.15rem)}.form-floating>textarea:focus~label::after,.form-floating>textarea:not(:placeholder-shown)~label::after{position:absolute;inset:1rem 0.375rem;z-index:-1;height:1.5em;content:"";background-color:var(--bs-body-bg);border-radius:var(--bs-border-radius)}.form-floating>textarea:disabled~label::after{background-color:var(--bs-secondary-bg)}.form-floating>.form-control-plaintext~label{border-width:var(--bs-border-width) 0}.form-floating>.form-control:disabled~label,.form-floating>:disabled~label{color:#6c757d}.input-group{position:relative;display:flex;flex-wrap:wrap;align-items:stretch;width:100%}.input-group>.form-control,.input-group>.form-floating,.input-group>.form-select{position:relative;flex:1 1 auto;width:1%;min-width:0}.input-group>.form-control:focus,.input-group>.form-floating:focus-within,.input-group>.form-select:focus{z-index:5}.input-group .btn{position:relative;z-index:2}.input-group .btn:focus{z-index:5}.input-group-text{display:flex;align-items:center;padding:.375rem .75rem;font-size:1rem;font-weight:400;line-height:1.5;color:var(--bs-body-color);text-align:center;white-space:nowrap;background-color:var(--bs-tertiary-bg);border:var(--bs-border-width) solid var(--bs-border-color);border-radius:var(--bs-border-radius)}.input-group-lg>.btn,.input-group-lg>.form-control,.input-group-lg>.form-select,.input-group-lg>.input-group-text{padding:.5rem 1rem;font-size:1.25rem;border-radius:var(--bs-border-radius-lg)}.input-group-sm>.btn,.input-group-sm>.form-control,.input-group-sm>.form-select,.input-group-sm>.input-group-text{padding:.25rem .5rem;font-size:.875rem;border-radius:var(--bs-border-radius-sm)}.input-group-lg>.form-select,.input-group-sm>.form-select{padding-right:3rem}.input-group:not(.has-validation)>.dropdown-toggle:nth-last-child(n+3),.input-group:not(.has-validation)>.form-floating:not(:last-child)>.form-control,.input-group:not(.has-validation)>.form-floating:not(:last-child)>.form-select,.input-group:not(.has-validation)>:not(:last-child):not(.dropdown-toggle):not(.dropdown-menu):not(.form-floating){border-top-right-radius:0;border-bottom-right-radius:0}.input-group.has-validation>.dropdown-toggle:nth-last-child(n+4),.input-group.has-validation>.form-floating:nth-last-child(n+3)>.form-control,.input-group.has-validation>.form-floating:nth-last-child(n+3)>.form-select,.input-group.has-validation>:nth-last-child(n+3):not(.dropdown-toggle):not(.dropdown-menu):not(.form-floating){border-top-right-radius:0;border-bottom-right-radius:0}.input-group>:not(:first-child):not(.dropdown-menu):not(.valid-tooltip):not(.valid-feedback):not(.invalid-tooltip):not(.invalid-feedback){margin-left:calc(-1 * var(--bs-border-width));border-top-left-radius:0;border-bottom-left-radius:0}.input-group>.form-floating:not(:first-child)>.form-control,.input-group>.form-floating:not(:first-child)>.form-select{border-top-left-radius:0;border-bottom-left-radius:0}.valid-feedback{display:none;width:100%;margin-top:.25rem;font-size:.875em;color:var(--bs-form-valid-color)}.valid-tooltip{position:absolute;top:100%;z-index:5;display:none;max-width:100%;padding:.25rem .5rem;margin-top:.1rem;font-size:.875rem;color:#fff;background-color:var(--bs-success);border-radius:var(--bs-border-radius)}.is-valid~.valid-feedback,.is-valid~.valid-tooltip,.was-validated :valid~.valid-feedback,.was-validated :valid~.valid-tooltip{display:block}.form-control.is-valid,.was-validated .form-control:valid{border-color:var(--bs-form-valid-border-color);padding-right:calc(1.5em + .75rem);background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3e%3cpath fill='%23198754' d='M2.3 6.73.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1'/%3e%3c/svg%3e");background-repeat:no-repeat;background-position:right calc(.375em + .1875rem) center;background-size:calc(.75em + .375rem) calc(.75em + .375rem)}.form-control.is-valid:focus,.was-validated .form-control:valid:focus{border-color:var(--bs-form-valid-border-color);box-shadow:0 0 0 .25rem rgba(var(--bs-success-rgb),.25)}.was-validated textarea.form-control:valid,textarea.form-control.is-valid{padding-right:calc(1.5em + .75rem);background-position:top calc(.375em + .1875rem) right calc(.375em + .1875rem)}.form-select.is-valid,.was-validated .form-select:valid{border-color:var(--bs-form-valid-border-color)}.form-select.is-valid:not([multiple]):not([size]),.form-select.is-valid:not([multiple])[size="1"],.was-validated .form-select:valid:not([multiple]):not([size]),.was-validated .form-select:valid:not([multiple])[size="1"]{--bs-form-select-bg-icon:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3e%3cpath fill='%23198754' d='M2.3 6.73.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1'/%3e%3c/svg%3e");padding-right:4.125rem;background-position:right .75rem center,center right 2.25rem;background-size:16px 12px,calc(.75em + .375rem) calc(.75em + .375rem)}.form-select.is-valid:focus,.was-validated .form-select:valid:focus{border-color:var(--bs-form-valid-border-color);box-shadow:0 0 0 .25rem rgba(var(--bs-success-rgb),.25)}.form-control-color.is-valid,.was-validated .form-control-color:valid{width:calc(3rem + calc(1.5em + .75rem))}.form-check-input.is-valid,.was-validated .form-check-input:valid{border-color:var(--bs-form-valid-border-color)}.form-check-input.is-valid:checked,.was-validated .form-check-input:valid:checked{background-color:var(--bs-form-valid-color)}.form-check-input.is-valid:focus,.was-validated .form-check-input:valid:focus{box-shadow:0 0 0 .25rem rgba(var(--bs-success-rgb),.25)}.form-check-input.is-valid~.form-check-label,.was-validated .form-check-input:valid~.form-check-label{color:var(--bs-form-valid-color)}.form-check-inline .form-check-input~.valid-feedback{margin-left:.5em}.input-group>.form-control:not(:focus).is-valid,.input-group>.form-floating:not(:focus-within).is-valid,.input-group>.form-select:not(:focus).is-valid,.was-validated .input-group>.form-control:not(:focus):valid,.was-validated .input-group>.form-floating:not(:focus-within):valid,.was-validated .input-group>.form-select:not(:focus):valid{z-index:3}.invalid-feedback{display:none;width:100%;margin-top:.25rem;font-size:.875em;color:var(--bs-form-invalid-color)}.invalid-tooltip{position:absolute;top:100%;z-index:5;display:none;max-width:100%;padding:.25rem .5rem;margin-top:.1rem;font-size:.875rem;color:#fff;background-color:var(--bs-danger);border-radius:var(--bs-border-radius)}.is-invalid~.invalid-feedback,.is-invalid~.invalid-tooltip,.was-validated :invalid~.invalid-feedback,.was-validated :invalid~.invalid-tooltip{display:block}.form-control.is-invalid,.was-validated .form-control:invalid{border-color:var(--bs-form-invalid-border-color);padding-right:calc(1.5em + .75rem);background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12' width='12' height='12' fill='none' stroke='%23dc3545'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%23dc3545' stroke='none'/%3e%3c/svg%3e");background-repeat:no-repeat;background-position:right calc(.375em + .1875rem) center;background-size:calc(.75em + .375rem) calc(.75em + .375rem)}.form-control.is-invalid:focus,.was-validated .form-control:invalid:focus{border-color:var(--bs-form-invalid-border-color);box-shadow:0 0 0 .25rem rgba(var(--bs-danger-rgb),.25)}.was-validated textarea.form-control:invalid,textarea.form-control.is-invalid{padding-right:calc(1.5em + .75rem);background-position:top calc(.375em + .1875rem) right calc(.375em + .1875rem)}.form-select.is-invalid,.was-validated .form-select:invalid{border-color:var(--bs-form-invalid-border-color)}.form-select.is-invalid:not([multiple]):not([size]),.form-select.is-invalid:not([multiple])[size="1"],.was-validated .form-select:invalid:not([multiple]):not([size]),.was-validated .form-select:invalid:not([multiple])[size="1"]{--bs-form-select-bg-icon:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12' width='12' height='12' fill='none' stroke='%23dc3545'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%23dc3545' stroke='none'/%3e%3c/svg%3e");padding-right:4.125rem;background-position:right .75rem center,center right 2.25rem;background-size:16px 12px,calc(.75em + .375rem) calc(.75em + .375rem)}.form-select.is-invalid:focus,.was-validated .form-select:invalid:focus{border-color:var(--bs-form-invalid-border-color);box-shadow:0 0 0 .25rem rgba(var(--bs-danger-rgb),.25)}.form-control-color.is-invalid,.was-validated .form-control-color:invalid{width:calc(3rem + calc(1.5em + .75rem))}.form-check-input.is-invalid,.was-validated .form-check-input:invalid{border-color:var(--bs-form-invalid-border-color)}.form-check-input.is-invalid:checked,.was-validated .form-check-input:invalid:checked{background-color:var(--bs-form-invalid-color)}.form-check-input.is-invalid:focus,.was-validated .form-check-input:invalid:focus{box-shadow:0 0 0 .25rem rgba(var(--bs-danger-rgb),.25)}.form-check-input.is-invalid~.form-check-label,.was-validated .form-check-input:invalid~.form-check-label{color:var(--bs-form-invalid-color)}.form-check-inline .form-check-input~.invalid-feedback{margin-left:.5em}.input-group>.form-control:not(:focus).is-invalid,.input-group>.form-floating:not(:focus-within).is-invalid,.input-group>.form-select:not(:focus).is-invalid,.was-validated .input-group>.form-control:not(:focus):invalid,.was-validated .input-group>.form-floating:not(:focus-within):invalid,.was-validated .input-group>.form-select:not(:focus):invalid{z-index:4}.btn{--bs-btn-padding-x:0.75rem;--bs-btn-padding-y:0.375rem;--bs-btn-font-family: ;--bs-btn-font-size:1rem;--bs-btn-font-weight:400;--bs-btn-line-height:1.5;--bs-btn-color:var(--bs-body-color);--bs-btn-bg:transparent;--bs-btn-border-width:var(--bs-border-width);--bs-btn-border-color:transparent;--bs-btn-border-radius:var(--bs-border-radius);--bs-btn-hover-border-color:transparent;--bs-btn-box-shadow:inset 0 1px 0 rgba(255, 255, 255, 0.15),0 1px 1px rgba(0, 0, 0, 0.075);--bs-btn-disabled-opacity:0.65;--bs-btn-focus-box-shadow:0 0 0 0.25rem rgba(var(--bs-btn-focus-shadow-rgb), .5);display:inline-block;padding:var(--bs-btn-padding-y) var(--bs-btn-padding-x);font-family:var(--bs-btn-font-family);font-size:var(--bs-btn-font-size);font-weight:var(--bs-btn-font-weight);line-height:var(--bs-btn-line-height);color:var(--bs-btn-color);text-align:center;text-decoration:none;vertical-align:middle;cursor:pointer;-webkit-user-select:none;-moz-user-select:none;user-select:none;border:var(--bs-btn-border-width) solid var(--bs-btn-border-color);border-radius:var(--bs-btn-border-radius);background-color:var(--bs-btn-bg);transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.btn{transition:none}}.btn:hover{color:var(--bs-btn-hover-color);background-color:var(--bs-btn-hover-bg);border-color:var(--bs-btn-hover-border-color)}.btn-check+.btn:hover{color:var(--bs-btn-color);background-color:var(--bs-btn-bg);border-color:var(--bs-btn-border-color)}.btn:focus-visible{color:var(--bs-btn-hover-color);background-color:var(--bs-btn-hover-bg);border-color:var(--bs-btn-hover-border-color);outline:0;box-shadow:var(--bs-btn-focus-box-shadow)}.btn-check:focus-visible+.btn{border-color:var(--bs-btn-hover-border-color);outline:0;box-shadow:var(--bs-btn-focus-box-shadow)}.btn-check:checked+.btn,.btn.active,.btn.show,.btn:first-child:active,:not(.btn-check)+.btn:active{color:var(--bs-btn-active-color);background-color:var(--bs-btn-active-bg);border-color:var(--bs-btn-active-border-color)}.btn-check:checked+.btn:focus-visible,.btn.active:focus-visible,.btn.show:focus-visible,.btn:first-child:active:focus-visible,:not(.btn-check)+.btn:active:focus-visible{box-shadow:var(--bs-btn-focus-box-shadow)}.btn-check:checked:focus-visible+.btn{box-shadow:var(--bs-btn-focus-box-shadow)}.btn.disabled,.btn:disabled,fieldset:disabled .btn{color:var(--bs-btn-disabled-color);pointer-events:none;background-color:var(--bs-btn-disabled-bg);border-color:var(--bs-btn-disabled-border-color);opacity:var(--bs-btn-disabled-opacity)}.btn-primary{--bs-btn-color:#fff;--bs-btn-bg:#0d6efd;--bs-btn-border-color:#0d6efd;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#0b5ed7;--bs-btn-hover-border-color:#0a58ca;--bs-btn-focus-shadow-rgb:49,132,253;--bs-btn-active-color:#fff;--bs-btn-active-bg:#0a58ca;--bs-btn-active-border-color:#0a53be;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#fff;--bs-btn-disabled-bg:#0d6efd;--bs-btn-disabled-border-color:#0d6efd}.btn-secondary{--bs-btn-color:#fff;--bs-btn-bg:#6c757d;--bs-btn-border-color:#6c757d;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#5c636a;--bs-btn-hover-border-color:#565e64;--bs-btn-focus-shadow-rgb:130,138,145;--bs-btn-active-color:#fff;--bs-btn-active-bg:#565e64;--bs-btn-active-border-color:#51585e;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#fff;--bs-btn-disabled-bg:#6c757d;--bs-btn-disabled-border-color:#6c757d}.btn-success{--bs-btn-color:#fff;--bs-btn-bg:#198754;--bs-btn-border-color:#198754;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#157347;--bs-btn-hover-border-color:#146c43;--bs-btn-focus-shadow-rgb:60,153,110;--bs-btn-active-color:#fff;--bs-btn-active-bg:#146c43;--bs-btn-active-border-color:#13653f;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#fff;--bs-btn-disabled-bg:#198754;--bs-btn-disabled-border-color:#198754}.btn-info{--bs-btn-color:#000;--bs-btn-bg:#0dcaf0;--bs-btn-border-color:#0dcaf0;--bs-btn-hover-color:#000;--bs-btn-hover-bg:#31d2f2;--bs-btn-hover-border-color:#25cff2;--bs-btn-focus-shadow-rgb:11,172,204;--bs-btn-active-color:#000;--bs-btn-active-bg:#3dd5f3;--bs-btn-active-border-color:#25cff2;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#000;--bs-btn-disabled-bg:#0dcaf0;--bs-btn-disabled-border-color:#0dcaf0}.btn-warning{--bs-btn-color:#000;--bs-btn-bg:#ffc107;--bs-btn-border-color:#ffc107;--bs-btn-hover-color:#000;--bs-btn-hover-bg:#ffca2c;--bs-btn-hover-border-color:#ffc720;--bs-btn-focus-shadow-rgb:217,164,6;--bs-btn-active-color:#000;--bs-btn-active-bg:#ffcd39;--bs-btn-active-border-color:#ffc720;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#000;--bs-btn-disabled-bg:#ffc107;--bs-btn-disabled-border-color:#ffc107}.btn-danger{--bs-btn-color:#fff;--bs-btn-bg:#dc3545;--bs-btn-border-color:#dc3545;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#bb2d3b;--bs-btn-hover-border-color:#b02a37;--bs-btn-focus-shadow-rgb:225,83,97;--bs-btn-active-color:#fff;--bs-btn-active-bg:#b02a37;--bs-btn-active-border-color:#a52834;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#fff;--bs-btn-disabled-bg:#dc3545;--bs-btn-disabled-border-color:#dc3545}.btn-light{--bs-btn-color:#000;--bs-btn-bg:#f8f9fa;--bs-btn-border-color:#f8f9fa;--bs-btn-hover-color:#000;--bs-btn-hover-bg:#d3d4d5;--bs-btn-hover-border-color:#c6c7c8;--bs-btn-focus-shadow-rgb:211,212,213;--bs-btn-active-color:#000;--bs-btn-active-bg:#c6c7c8;--bs-btn-active-border-color:#babbbc;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#000;--bs-btn-disabled-bg:#f8f9fa;--bs-btn-disabled-border-color:#f8f9fa}.btn-dark{--bs-btn-color:#fff;--bs-btn-bg:#212529;--bs-btn-border-color:#212529;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#424649;--bs-btn-hover-border-color:#373b3e;--bs-btn-focus-shadow-rgb:66,70,73;--bs-btn-active-color:#fff;--bs-btn-active-bg:#4d5154;--bs-btn-active-border-color:#373b3e;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#fff;--bs-btn-disabled-bg:#212529;--bs-btn-disabled-border-color:#212529}.btn-outline-primary{--bs-btn-color:#0d6efd;--bs-btn-border-color:#0d6efd;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#0d6efd;--bs-btn-hover-border-color:#0d6efd;--bs-btn-focus-shadow-rgb:13,110,253;--bs-btn-active-color:#fff;--bs-btn-active-bg:#0d6efd;--bs-btn-active-border-color:#0d6efd;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#0d6efd;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#0d6efd;--bs-gradient:none}.btn-outline-secondary{--bs-btn-color:#6c757d;--bs-btn-border-color:#6c757d;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#6c757d;--bs-btn-hover-border-color:#6c757d;--bs-btn-focus-shadow-rgb:108,117,125;--bs-btn-active-color:#fff;--bs-btn-active-bg:#6c757d;--bs-btn-active-border-color:#6c757d;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#6c757d;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#6c757d;--bs-gradient:none}.btn-outline-success{--bs-btn-color:#198754;--bs-btn-border-color:#198754;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#198754;--bs-btn-hover-border-color:#198754;--bs-btn-focus-shadow-rgb:25,135,84;--bs-btn-active-color:#fff;--bs-btn-active-bg:#198754;--bs-btn-active-border-color:#198754;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#198754;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#198754;--bs-gradient:none}.btn-outline-info{--bs-btn-color:#0dcaf0;--bs-btn-border-color:#0dcaf0;--bs-btn-hover-color:#000;--bs-btn-hover-bg:#0dcaf0;--bs-btn-hover-border-color:#0dcaf0;--bs-btn-focus-shadow-rgb:13,202,240;--bs-btn-active-color:#000;--bs-btn-active-bg:#0dcaf0;--bs-btn-active-border-color:#0dcaf0;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#0dcaf0;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#0dcaf0;--bs-gradient:none}.btn-outline-warning{--bs-btn-color:#ffc107;--bs-btn-border-color:#ffc107;--bs-btn-hover-color:#000;--bs-btn-hover-bg:#ffc107;--bs-btn-hover-border-color:#ffc107;--bs-btn-focus-shadow-rgb:255,193,7;--bs-btn-active-color:#000;--bs-btn-active-bg:#ffc107;--bs-btn-active-border-color:#ffc107;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#ffc107;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#ffc107;--bs-gradient:none}.btn-outline-danger{--bs-btn-color:#dc3545;--bs-btn-border-color:#dc3545;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#dc3545;--bs-btn-hover-border-color:#dc3545;--bs-btn-focus-shadow-rgb:220,53,69;--bs-btn-active-color:#fff;--bs-btn-active-bg:#dc3545;--bs-btn-active-border-color:#dc3545;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#dc3545;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#dc3545;--bs-gradient:none}.btn-outline-light{--bs-btn-color:#f8f9fa;--bs-btn-border-color:#f8f9fa;--bs-btn-hover-color:#000;--bs-btn-hover-bg:#f8f9fa;--bs-btn-hover-border-color:#f8f9fa;--bs-btn-focus-shadow-rgb:248,249,250;--bs-btn-active-color:#000;--bs-btn-active-bg:#f8f9fa;--bs-btn-active-border-color:#f8f9fa;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#f8f9fa;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#f8f9fa;--bs-gradient:none}.btn-outline-dark{--bs-btn-color:#212529;--bs-btn-border-color:#212529;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#212529;--bs-btn-hover-border-color:#212529;--bs-btn-focus-shadow-rgb:33,37,41;--bs-btn-active-color:#fff;--bs-btn-active-bg:#212529;--bs-btn-active-border-color:#212529;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#212529;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#212529;--bs-gradient:none}.btn-link{--bs-btn-font-weight:400;--bs-btn-color:var(--bs-link-color);--bs-btn-bg:transparent;--bs-btn-border-color:transparent;--bs-btn-hover-color:var(--bs-link-hover-color);--bs-btn-hover-border-color:transparent;--bs-btn-active-color:var(--bs-link-hover-color);--bs-btn-active-border-color:transparent;--bs-btn-disabled-color:#6c757d;--bs-btn-disabled-border-color:transparent;--bs-btn-box-shadow:0 0 0 #000;--bs-btn-focus-shadow-rgb:49,132,253;text-decoration:underline}.btn-link:focus-visible{color:var(--bs-btn-color)}.btn-link:hover{color:var(--bs-btn-hover-color)}.btn-group-lg>.btn,.btn-lg{--bs-btn-padding-y:0.5rem;--bs-btn-padding-x:1rem;--bs-btn-font-size:1.25rem;--bs-btn-border-radius:var(--bs-border-radius-lg)}.btn-group-sm>.btn,.btn-sm{--bs-btn-padding-y:0.25rem;--bs-btn-padding-x:0.5rem;--bs-btn-font-size:0.875rem;--bs-btn-border-radius:var(--bs-border-radius-sm)}.fade{transition:opacity .15s linear}@media (prefers-reduced-motion:reduce){.fade{transition:none}}.fade:not(.show){opacity:0}.collapse:not(.show){display:none}.collapsing{height:0;overflow:hidden;transition:height .35s ease}@media (prefers-reduced-motion:reduce){.collapsing{transition:none}}.collapsing.collapse-horizontal{width:0;height:auto;transition:width .35s ease}@media (prefers-reduced-motion:reduce){.collapsing.collapse-horizontal{transition:none}}.dropdown,.dropdown-center,.dropend,.dropstart,.dropup,.dropup-center{position:relative}.dropdown-toggle{white-space:nowrap}.dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:"";border-top:.3em solid;border-right:.3em solid transparent;border-bottom:0;border-left:.3em solid transparent}.dropdown-toggle:empty::after{margin-left:0}.dropdown-menu{--bs-dropdown-zindex:1000;--bs-dropdown-min-width:10rem;--bs-dropdown-padding-x:0;--bs-dropdown-padding-y:0.5rem;--bs-dropdown-spacer:0.125rem;--bs-dropdown-font-size:1rem;--bs-dropdown-color:var(--bs-body-color);--bs-dropdown-bg:var(--bs-body-bg);--bs-dropdown-border-color:var(--bs-border-color-translucent);--bs-dropdown-border-radius:var(--bs-border-radius);--bs-dropdown-border-width:var(--bs-border-width);--bs-dropdown-inner-border-radius:calc(var(--bs-border-radius) - var(--bs-border-width));--bs-dropdown-divider-bg:var(--bs-border-color-translucent);--bs-dropdown-divider-margin-y:0.5rem;--bs-dropdown-box-shadow:var(--bs-box-shadow);--bs-dropdown-link-color:var(--bs-body-color);--bs-dropdown-link-hover-color:var(--bs-body-color);--bs-dropdown-link-hover-bg:var(--bs-tertiary-bg);--bs-dropdown-link-active-color:#fff;--bs-dropdown-link-active-bg:#0d6efd;--bs-dropdown-link-disabled-color:var(--bs-tertiary-color);--bs-dropdown-item-padding-x:1rem;--bs-dropdown-item-padding-y:0.25rem;--bs-dropdown-header-color:#6c757d;--bs-dropdown-header-padding-x:1rem;--bs-dropdown-header-padding-y:0.5rem;position:absolute;z-index:var(--bs-dropdown-zindex);display:none;min-width:var(--bs-dropdown-min-width);padding:var(--bs-dropdown-padding-y) var(--bs-dropdown-padding-x);margin:0;font-size:var(--bs-dropdown-font-size);color:var(--bs-dropdown-color);text-align:left;list-style:none;background-color:var(--bs-dropdown-bg);background-clip:padding-box;border:var(--bs-dropdown-border-width) solid var(--bs-dropdown-border-color);border-radius:var(--bs-dropdown-border-radius)}.dropdown-menu[data-bs-popper]{top:100%;left:0;margin-top:var(--bs-dropdown-spacer)}.dropdown-menu-start{--bs-position:start}.dropdown-menu-start[data-bs-popper]{right:auto;left:0}.dropdown-menu-end{--bs-position:end}.dropdown-menu-end[data-bs-popper]{right:0;left:auto}@media (min-width:576px){.dropdown-menu-sm-start{--bs-position:start}.dropdown-menu-sm-start[data-bs-popper]{right:auto;left:0}.dropdown-menu-sm-end{--bs-position:end}.dropdown-menu-sm-end[data-bs-popper]{right:0;left:auto}}@media (min-width:768px){.dropdown-menu-md-start{--bs-position:start}.dropdown-menu-md-start[data-bs-popper]{right:auto;left:0}.dropdown-menu-md-end{--bs-position:end}.dropdown-menu-md-end[data-bs-popper]{right:0;left:auto}}@media (min-width:992px){.dropdown-menu-lg-start{--bs-position:start}.dropdown-menu-lg-start[data-bs-popper]{right:auto;left:0}.dropdown-menu-lg-end{--bs-position:end}.dropdown-menu-lg-end[data-bs-popper]{right:0;left:auto}}@media (min-width:1200px){.dropdown-menu-xl-start{--bs-position:start}.dropdown-menu-xl-start[data-bs-popper]{right:auto;left:0}.dropdown-menu-xl-end{--bs-position:end}.dropdown-menu-xl-end[data-bs-popper]{right:0;left:auto}}@media (min-width:1400px){.dropdown-menu-xxl-start{--bs-position:start}.dropdown-menu-xxl-start[data-bs-popper]{right:auto;left:0}.dropdown-menu-xxl-end{--bs-position:end}.dropdown-menu-xxl-end[data-bs-popper]{right:0;left:auto}}.dropup .dropdown-menu[data-bs-popper]{top:auto;bottom:100%;margin-top:0;margin-bottom:var(--bs-dropdown-spacer)}.dropup .dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:"";border-top:0;border-right:.3em solid transparent;border-bottom:.3em solid;border-left:.3em solid transparent}.dropup .dropdown-toggle:empty::after{margin-left:0}.dropend .dropdown-menu[data-bs-popper]{top:0;right:auto;left:100%;margin-top:0;margin-left:var(--bs-dropdown-spacer)}.dropend .dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:"";border-top:.3em solid transparent;border-right:0;border-bottom:.3em solid transparent;border-left:.3em solid}.dropend .dropdown-toggle:empty::after{margin-left:0}.dropend .dropdown-toggle::after{vertical-align:0}.dropstart .dropdown-menu[data-bs-popper]{top:0;right:100%;left:auto;margin-top:0;margin-right:var(--bs-dropdown-spacer)}.dropstart .dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:""}.dropstart .dropdown-toggle::after{display:none}.dropstart .dropdown-toggle::before{display:inline-block;margin-right:.255em;vertical-align:.255em;content:"";border-top:.3em solid transparent;border-right:.3em solid;border-bottom:.3em solid transparent}.dropstart .dropdown-toggle:empty::after{margin-left:0}.dropstart .dropdown-toggle::before{vertical-align:0}.dropdown-divider{height:0;margin:var(--bs-dropdown-divider-margin-y) 0;overflow:hidden;border-top:1px solid var(--bs-dropdown-divider-bg);opacity:1}.dropdown-item{display:block;width:100%;padding:var(--bs-dropdown-item-padding-y) var(--bs-dropdown-item-padding-x);clear:both;font-weight:400;color:var(--bs-dropdown-link-color);text-align:inherit;text-decoration:none;white-space:nowrap;background-color:transparent;border:0;border-radius:var(--bs-dropdown-item-border-radius,0)}.dropdown-item:focus,.dropdown-item:hover{color:var(--bs-dropdown-link-hover-color);background-color:var(--bs-dropdown-link-hover-bg)}.dropdown-item.active,.dropdown-item:active{color:var(--bs-dropdown-link-active-color);text-decoration:none;background-color:var(--bs-dropdown-link-active-bg)}.dropdown-item.disabled,.dropdown-item:disabled{color:var(--bs-dropdown-link-disabled-color);pointer-events:none;background-color:transparent}.dropdown-menu.show{display:block}.dropdown-header{display:block;padding:var(--bs-dropdown-header-padding-y) var(--bs-dropdown-header-padding-x);margin-bottom:0;font-size:.875rem;color:var(--bs-dropdown-header-color);white-space:nowrap}.dropdown-item-text{display:block;padding:var(--bs-dropdown-item-padding-y) var(--bs-dropdown-item-padding-x);color:var(--bs-dropdown-link-color)}.dropdown-menu-dark{--bs-dropdown-color:#dee2e6;--bs-dropdown-bg:#343a40;--bs-dropdown-border-color:var(--bs-border-color-translucent);--bs-dropdown-box-shadow: ;--bs-dropdown-link-color:#dee2e6;--bs-dropdown-link-hover-color:#fff;--bs-dropdown-divider-bg:var(--bs-border-color-translucent);--bs-dropdown-link-hover-bg:rgba(255, 255, 255, 0.15);--bs-dropdown-link-active-color:#fff;--bs-dropdown-link-active-bg:#0d6efd;--bs-dropdown-link-disabled-color:#adb5bd;--bs-dropdown-header-color:#adb5bd}.btn-group,.btn-group-vertical{position:relative;display:inline-flex;vertical-align:middle}.btn-group-vertical>.btn,.btn-group>.btn{position:relative;flex:1 1 auto}.btn-group-vertical>.btn-check:checked+.btn,.btn-group-vertical>.btn-check:focus+.btn,.btn-group-vertical>.btn.active,.btn-group-vertical>.btn:active,.btn-group-vertical>.btn:focus,.btn-group-vertical>.btn:hover,.btn-group>.btn-check:checked+.btn,.btn-group>.btn-check:focus+.btn,.btn-group>.btn.active,.btn-group>.btn:active,.btn-group>.btn:focus,.btn-group>.btn:hover{z-index:1}.btn-toolbar{display:flex;flex-wrap:wrap;justify-content:flex-start}.btn-toolbar .input-group{width:auto}.btn-group{border-radius:var(--bs-border-radius)}.btn-group>.btn-group:not(:first-child),.btn-group>:not(.btn-check:first-child)+.btn{margin-left:calc(-1 * var(--bs-border-width))}.btn-group>.btn-group:not(:last-child)>.btn,.btn-group>.btn.dropdown-toggle-split:first-child,.btn-group>.btn:not(:last-child):not(.dropdown-toggle){border-top-right-radius:0;border-bottom-right-radius:0}.btn-group>.btn-group:not(:first-child)>.btn,.btn-group>.btn:nth-child(n+3),.btn-group>:not(.btn-check)+.btn{border-top-left-radius:0;border-bottom-left-radius:0}.dropdown-toggle-split{padding-right:.5625rem;padding-left:.5625rem}.dropdown-toggle-split::after,.dropend .dropdown-toggle-split::after,.dropup .dropdown-toggle-split::after{margin-left:0}.dropstart .dropdown-toggle-split::before{margin-right:0}.btn-group-sm>.btn+.dropdown-toggle-split,.btn-sm+.dropdown-toggle-split{padding-right:.375rem;padding-left:.375rem}.btn-group-lg>.btn+.dropdown-toggle-split,.btn-lg+.dropdown-toggle-split{padding-right:.75rem;padding-left:.75rem}.btn-group-vertical{flex-direction:column;align-items:flex-start;justify-content:center}.btn-group-vertical>.btn,.btn-group-vertical>.btn-group{width:100%}.btn-group-vertical>.btn-group:not(:first-child),.btn-group-vertical>.btn:not(:first-child){margin-top:calc(-1 * var(--bs-border-width))}.btn-group-vertical>.btn-group:not(:last-child)>.btn,.btn-group-vertical>.btn:not(:last-child):not(.dropdown-toggle){border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn-group:not(:first-child)>.btn,.btn-group-vertical>.btn:nth-child(n+3),.btn-group-vertical>:not(.btn-check)+.btn{border-top-left-radius:0;border-top-right-radius:0}.nav{--bs-nav-link-padding-x:1rem;--bs-nav-link-padding-y:0.5rem;--bs-nav-link-font-weight: ;--bs-nav-link-color:var(--bs-link-color);--bs-nav-link-hover-color:var(--bs-link-hover-color);--bs-nav-link-disabled-color:var(--bs-secondary-color);display:flex;flex-wrap:wrap;padding-left:0;margin-bottom:0;list-style:none}.nav-link{display:block;padding:var(--bs-nav-link-padding-y) var(--bs-nav-link-padding-x);font-size:var(--bs-nav-link-font-size);font-weight:var(--bs-nav-link-font-weight);color:var(--bs-nav-link-color);text-decoration:none;background:0 0;border:0;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out}@media (prefers-reduced-motion:reduce){.nav-link{transition:none}}.nav-link:focus,.nav-link:hover{color:var(--bs-nav-link-hover-color)}.nav-link:focus-visible{outline:0;box-shadow:0 0 0 .25rem rgba(13,110,253,.25)}.nav-link.disabled,.nav-link:disabled{color:var(--bs-nav-link-disabled-color);pointer-events:none;cursor:default}.nav-tabs{--bs-nav-tabs-border-width:var(--bs-border-width);--bs-nav-tabs-border-color:var(--bs-border-color);--bs-nav-tabs-border-radius:var(--bs-border-radius);--bs-nav-tabs-link-hover-border-color:var(--bs-secondary-bg) var(--bs-secondary-bg) var(--bs-border-color);--bs-nav-tabs-link-active-color:var(--bs-emphasis-color);--bs-nav-tabs-link-active-bg:var(--bs-body-bg);--bs-nav-tabs-link-active-border-color:var(--bs-border-color) var(--bs-border-color) var(--bs-body-bg);border-bottom:var(--bs-nav-tabs-border-width) solid var(--bs-nav-tabs-border-color)}.nav-tabs .nav-link{margin-bottom:calc(-1 * var(--bs-nav-tabs-border-width));border:var(--bs-nav-tabs-border-width) solid transparent;border-top-left-radius:var(--bs-nav-tabs-border-radius);border-top-right-radius:var(--bs-nav-tabs-border-radius)}.nav-tabs .nav-link:focus,.nav-tabs .nav-link:hover{isolation:isolate;border-color:var(--bs-nav-tabs-link-hover-border-color)}.nav-tabs .nav-item.show .nav-link,.nav-tabs .nav-link.active{color:var(--bs-nav-tabs-link-active-color);background-color:var(--bs-nav-tabs-link-active-bg);border-color:var(--bs-nav-tabs-link-active-border-color)}.nav-tabs .dropdown-menu{margin-top:calc(-1 * var(--bs-nav-tabs-border-width));border-top-left-radius:0;border-top-right-radius:0}.nav-pills{--bs-nav-pills-border-radius:var(--bs-border-radius);--bs-nav-pills-link-active-color:#fff;--bs-nav-pills-link-active-bg:#0d6efd}.nav-pills .nav-link{border-radius:var(--bs-nav-pills-border-radius)}.nav-pills .nav-link.active,.nav-pills .show>.nav-link{color:var(--bs-nav-pills-link-active-color);background-color:var(--bs-nav-pills-link-active-bg)}.nav-underline{--bs-nav-underline-gap:1rem;--bs-nav-underline-border-width:0.125rem;--bs-nav-underline-link-active-color:var(--bs-emphasis-color);gap:var(--bs-nav-underline-gap)}.nav-underline .nav-link{padding-right:0;padding-left:0;border-bottom:var(--bs-nav-underline-border-width) solid transparent}.nav-underline .nav-link:focus,.nav-underline .nav-link:hover{border-bottom-color:currentcolor}.nav-underline .nav-link.active,.nav-underline .show>.nav-link{font-weight:700;color:var(--bs-nav-underline-link-active-color);border-bottom-color:currentcolor}.nav-fill .nav-item,.nav-fill>.nav-link{flex:1 1 auto;text-align:center}.nav-justified .nav-item,.nav-justified>.nav-link{flex-grow:1;flex-basis:0;text-align:center}.nav-fill .nav-item .nav-link,.nav-justified .nav-item .nav-link{width:100%}.tab-content>.tab-pane{display:none}.tab-content>.active{display:block}.navbar{--bs-navbar-padding-x:0;--bs-navbar-padding-y:0.5rem;--bs-navbar-color:rgba(var(--bs-emphasis-color-rgb), 0.65);--bs-navbar-hover-color:rgba(var(--bs-emphasis-color-rgb), 0.8);--bs-navbar-disabled-color:rgba(var(--bs-emphasis-color-rgb), 0.3);--bs-navbar-active-color:rgba(var(--bs-emphasis-color-rgb), 1);--bs-navbar-brand-padding-y:0.3125rem;--bs-navbar-brand-margin-end:1rem;--bs-navbar-brand-font-size:1.25rem;--bs-navbar-brand-color:rgba(var(--bs-emphasis-color-rgb), 1);--bs-navbar-brand-hover-color:rgba(var(--bs-emphasis-color-rgb), 1);--bs-navbar-nav-link-padding-x:0.5rem;--bs-navbar-toggler-padding-y:0.25rem;--bs-navbar-toggler-padding-x:0.75rem;--bs-navbar-toggler-font-size:1.25rem;--bs-navbar-toggler-icon-bg:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 30 30'%3e%3cpath stroke='rgba%2833, 37, 41, 0.75%29' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e");--bs-navbar-toggler-border-color:rgba(var(--bs-emphasis-color-rgb), 0.15);--bs-navbar-toggler-border-radius:var(--bs-border-radius);--bs-navbar-toggler-focus-width:0.25rem;--bs-navbar-toggler-transition:box-shadow 0.15s ease-in-out;position:relative;display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;padding:var(--bs-navbar-padding-y) var(--bs-navbar-padding-x)}.navbar>.container,.navbar>.container-fluid,.navbar>.container-lg,.navbar>.container-md,.navbar>.container-sm,.navbar>.container-xl,.navbar>.container-xxl{display:flex;flex-wrap:inherit;align-items:center;justify-content:space-between}.navbar-brand{padding-top:var(--bs-navbar-brand-padding-y);padding-bottom:var(--bs-navbar-brand-padding-y);margin-right:var(--bs-navbar-brand-margin-end);font-size:var(--bs-navbar-brand-font-size);color:var(--bs-navbar-brand-color);text-decoration:none;white-space:nowrap}.navbar-brand:focus,.navbar-brand:hover{color:var(--bs-navbar-brand-hover-color)}.navbar-nav{--bs-nav-link-padding-x:0;--bs-nav-link-padding-y:0.5rem;--bs-nav-link-font-weight: ;--bs-nav-link-color:var(--bs-navbar-color);--bs-nav-link-hover-color:var(--bs-navbar-hover-color);--bs-nav-link-disabled-color:var(--bs-navbar-disabled-color);display:flex;flex-direction:column;padding-left:0;margin-bottom:0;list-style:none}.navbar-nav .nav-link.active,.navbar-nav .nav-link.show{color:var(--bs-navbar-active-color)}.navbar-nav .dropdown-menu{position:static}.navbar-text{padding-top:.5rem;padding-bottom:.5rem;color:var(--bs-navbar-color)}.navbar-text a,.navbar-text a:focus,.navbar-text a:hover{color:var(--bs-navbar-active-color)}.navbar-collapse{flex-grow:1;flex-basis:100%;align-items:center}.navbar-toggler{padding:var(--bs-navbar-toggler-padding-y) var(--bs-navbar-toggler-padding-x);font-size:var(--bs-navbar-toggler-font-size);line-height:1;color:var(--bs-navbar-color);background-color:transparent;border:var(--bs-border-width) solid var(--bs-navbar-toggler-border-color);border-radius:var(--bs-navbar-toggler-border-radius);transition:var(--bs-navbar-toggler-transition)}@media (prefers-reduced-motion:reduce){.navbar-toggler{transition:none}}.navbar-toggler:hover{text-decoration:none}.navbar-toggler:focus{text-decoration:none;outline:0;box-shadow:0 0 0 var(--bs-navbar-toggler-focus-width)}.navbar-toggler-icon{display:inline-block;width:1.5em;height:1.5em;vertical-align:middle;background-image:var(--bs-navbar-toggler-icon-bg);background-repeat:no-repeat;background-position:center;background-size:100%}.navbar-nav-scroll{max-height:var(--bs-scroll-height,75vh);overflow-y:auto}@media (min-width:576px){.navbar-expand-sm{flex-wrap:nowrap;justify-content:flex-start}.navbar-expand-sm .navbar-nav{flex-direction:row}.navbar-expand-sm .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-sm .navbar-nav .nav-link{padding-right:var(--bs-navbar-nav-link-padding-x);padding-left:var(--bs-navbar-nav-link-padding-x)}.navbar-expand-sm .navbar-nav-scroll{overflow:visible}.navbar-expand-sm .navbar-collapse{display:flex!important;flex-basis:auto}.navbar-expand-sm .navbar-toggler{display:none}.navbar-expand-sm .offcanvas{position:static;z-index:auto;flex-grow:1;width:auto!important;height:auto!important;visibility:visible!important;background-color:transparent!important;border:0!important;transform:none!important;transition:none}.navbar-expand-sm .offcanvas .offcanvas-header{display:none}.navbar-expand-sm .offcanvas .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible}}@media (min-width:768px){.navbar-expand-md{flex-wrap:nowrap;justify-content:flex-start}.navbar-expand-md .navbar-nav{flex-direction:row}.navbar-expand-md .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-md .navbar-nav .nav-link{padding-right:var(--bs-navbar-nav-link-padding-x);padding-left:var(--bs-navbar-nav-link-padding-x)}.navbar-expand-md .navbar-nav-scroll{overflow:visible}.navbar-expand-md .navbar-collapse{display:flex!important;flex-basis:auto}.navbar-expand-md .navbar-toggler{display:none}.navbar-expand-md .offcanvas{position:static;z-index:auto;flex-grow:1;width:auto!important;height:auto!important;visibility:visible!important;background-color:transparent!important;border:0!important;transform:none!important;transition:none}.navbar-expand-md .offcanvas .offcanvas-header{display:none}.navbar-expand-md .offcanvas .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible}}@media (min-width:992px){.navbar-expand-lg{flex-wrap:nowrap;justify-content:flex-start}.navbar-expand-lg .navbar-nav{flex-direction:row}.navbar-expand-lg .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-lg .navbar-nav .nav-link{padding-right:var(--bs-navbar-nav-link-padding-x);padding-left:var(--bs-navbar-nav-link-padding-x)}.navbar-expand-lg .navbar-nav-scroll{overflow:visible}.navbar-expand-lg .navbar-collapse{display:flex!important;flex-basis:auto}.navbar-expand-lg .navbar-toggler{display:none}.navbar-expand-lg .offcanvas{position:static;z-index:auto;flex-grow:1;width:auto!important;height:auto!important;visibility:visible!important;background-color:transparent!important;border:0!important;transform:none!important;transition:none}.navbar-expand-lg .offcanvas .offcanvas-header{display:none}.navbar-expand-lg .offcanvas .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible}}@media (min-width:1200px){.navbar-expand-xl{flex-wrap:nowrap;justify-content:flex-start}.navbar-expand-xl .navbar-nav{flex-direction:row}.navbar-expand-xl .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-xl .navbar-nav .nav-link{padding-right:var(--bs-navbar-nav-link-padding-x);padding-left:var(--bs-navbar-nav-link-padding-x)}.navbar-expand-xl .navbar-nav-scroll{overflow:visible}.navbar-expand-xl .navbar-collapse{display:flex!important;flex-basis:auto}.navbar-expand-xl .navbar-toggler{display:none}.navbar-expand-xl .offcanvas{position:static;z-index:auto;flex-grow:1;width:auto!important;height:auto!important;visibility:visible!important;background-color:transparent!important;border:0!important;transform:none!important;transition:none}.navbar-expand-xl .offcanvas .offcanvas-header{display:none}.navbar-expand-xl .offcanvas .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible}}@media (min-width:1400px){.navbar-expand-xxl{flex-wrap:nowrap;justify-content:flex-start}.navbar-expand-xxl .navbar-nav{flex-direction:row}.navbar-expand-xxl .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-xxl .navbar-nav .nav-link{padding-right:var(--bs-navbar-nav-link-padding-x);padding-left:var(--bs-navbar-nav-link-padding-x)}.navbar-expand-xxl .navbar-nav-scroll{overflow:visible}.navbar-expand-xxl .navbar-collapse{display:flex!important;flex-basis:auto}.navbar-expand-xxl .navbar-toggler{display:none}.navbar-expand-xxl .offcanvas{position:static;z-index:auto;flex-grow:1;width:auto!important;height:auto!important;visibility:visible!important;background-color:transparent!important;border:0!important;transform:none!important;transition:none}.navbar-expand-xxl .offcanvas .offcanvas-header{display:none}.navbar-expand-xxl .offcanvas .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible}}.navbar-expand{flex-wrap:nowrap;justify-content:flex-start}.navbar-expand .navbar-nav{flex-direction:row}.navbar-expand .navbar-nav .dropdown-menu{position:absolute}.navbar-expand .navbar-nav .nav-link{padding-right:var(--bs-navbar-nav-link-padding-x);padding-left:var(--bs-navbar-nav-link-padding-x)}.navbar-expand .navbar-nav-scroll{overflow:visible}.navbar-expand .navbar-collapse{display:flex!important;flex-basis:auto}.navbar-expand .navbar-toggler{display:none}.navbar-expand .offcanvas{position:static;z-index:auto;flex-grow:1;width:auto!important;height:auto!important;visibility:visible!important;background-color:transparent!important;border:0!important;transform:none!important;transition:none}.navbar-expand .offcanvas .offcanvas-header{display:none}.navbar-expand .offcanvas .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible}.navbar-dark,.navbar[data-bs-theme=dark]{--bs-navbar-color:rgba(255, 255, 255, 0.55);--bs-navbar-hover-color:rgba(255, 255, 255, 0.75);--bs-navbar-disabled-color:rgba(255, 255, 255, 0.25);--bs-navbar-active-color:#fff;--bs-navbar-brand-color:#fff;--bs-navbar-brand-hover-color:#fff;--bs-navbar-toggler-border-color:rgba(255, 255, 255, 0.1);--bs-navbar-toggler-icon-bg:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 30 30'%3e%3cpath stroke='rgba%28255, 255, 255, 0.55%29' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e")}[data-bs-theme=dark] .navbar-toggler-icon{--bs-navbar-toggler-icon-bg:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 30 30'%3e%3cpath stroke='rgba%28255, 255, 255, 0.55%29' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e")}.card{--bs-card-spacer-y:1rem;--bs-card-spacer-x:1rem;--bs-card-title-spacer-y:0.5rem;--bs-card-title-color: ;--bs-card-subtitle-color: ;--bs-card-border-width:var(--bs-border-width);--bs-card-border-color:var(--bs-border-color-translucent);--bs-card-border-radius:var(--bs-border-radius);--bs-card-box-shadow: ;--bs-card-inner-border-radius:calc(var(--bs-border-radius) - (var(--bs-border-width)));--bs-card-cap-padding-y:0.5rem;--bs-card-cap-padding-x:1rem;--bs-card-cap-bg:rgba(var(--bs-body-color-rgb), 0.03);--bs-card-cap-color: ;--bs-card-height: ;--bs-card-color: ;--bs-card-bg:var(--bs-body-bg);--bs-card-img-overlay-padding:1rem;--bs-card-group-margin:0.75rem;position:relative;display:flex;flex-direction:column;min-width:0;height:var(--bs-card-height);color:var(--bs-body-color);word-wrap:break-word;background-color:var(--bs-card-bg);background-clip:border-box;border:var(--bs-card-border-width) solid var(--bs-card-border-color);border-radius:var(--bs-card-border-radius)}.card>hr{margin-right:0;margin-left:0}.card>.list-group{border-top:inherit;border-bottom:inherit}.card>.list-group:first-child{border-top-width:0;border-top-left-radius:var(--bs-card-inner-border-radius);border-top-right-radius:var(--bs-card-inner-border-radius)}.card>.list-group:last-child{border-bottom-width:0;border-bottom-right-radius:var(--bs-card-inner-border-radius);border-bottom-left-radius:var(--bs-card-inner-border-radius)}.card>.card-header+.list-group,.card>.list-group+.card-footer{border-top:0}.card-body{flex:1 1 auto;padding:var(--bs-card-spacer-y) var(--bs-card-spacer-x);color:var(--bs-card-color)}.card-title{margin-bottom:var(--bs-card-title-spacer-y);color:var(--bs-card-title-color)}.card-subtitle{margin-top:calc(-.5 * var(--bs-card-title-spacer-y));margin-bottom:0;color:var(--bs-card-subtitle-color)}.card-text:last-child{margin-bottom:0}.card-link+.card-link{margin-left:var(--bs-card-spacer-x)}.card-header{padding:var(--bs-card-cap-padding-y) var(--bs-card-cap-padding-x);margin-bottom:0;color:var(--bs-card-cap-color);background-color:var(--bs-card-cap-bg);border-bottom:var(--bs-card-border-width) solid var(--bs-card-border-color)}.card-header:first-child{border-radius:var(--bs-card-inner-border-radius) var(--bs-card-inner-border-radius) 0 0}.card-footer{padding:var(--bs-card-cap-padding-y) var(--bs-card-cap-padding-x);color:var(--bs-card-cap-color);background-color:var(--bs-card-cap-bg);border-top:var(--bs-card-border-width) solid var(--bs-card-border-color)}.card-footer:last-child{border-radius:0 0 var(--bs-card-inner-border-radius) var(--bs-card-inner-border-radius)}.card-header-tabs{margin-right:calc(-.5 * var(--bs-card-cap-padding-x));margin-bottom:calc(-1 * var(--bs-card-cap-padding-y));margin-left:calc(-.5 * var(--bs-card-cap-padding-x));border-bottom:0}.card-header-tabs .nav-link.active{background-color:var(--bs-card-bg);border-bottom-color:var(--bs-card-bg)}.card-header-pills{margin-right:calc(-.5 * var(--bs-card-cap-padding-x));margin-left:calc(-.5 * var(--bs-card-cap-padding-x))}.card-img-overlay{position:absolute;top:0;right:0;bottom:0;left:0;padding:var(--bs-card-img-overlay-padding);border-radius:var(--bs-card-inner-border-radius)}.card-img,.card-img-bottom,.card-img-top{width:100%}.card-img,.card-img-top{border-top-left-radius:var(--bs-card-inner-border-radius);border-top-right-radius:var(--bs-card-inner-border-radius)}.card-img,.card-img-bottom{border-bottom-right-radius:var(--bs-card-inner-border-radius);border-bottom-left-radius:var(--bs-card-inner-border-radius)}.card-group>.card{margin-bottom:var(--bs-card-group-margin)}@media (min-width:576px){.card-group{display:flex;flex-flow:row wrap}.card-group>.card{flex:1 0 0;margin-bottom:0}.card-group>.card+.card{margin-left:0;border-left:0}.card-group>.card:not(:last-child){border-top-right-radius:0;border-bottom-right-radius:0}.card-group>.card:not(:last-child)>.card-header,.card-group>.card:not(:last-child)>.card-img-top{border-top-right-radius:0}.card-group>.card:not(:last-child)>.card-footer,.card-group>.card:not(:last-child)>.card-img-bottom{border-bottom-right-radius:0}.card-group>.card:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0}.card-group>.card:not(:first-child)>.card-header,.card-group>.card:not(:first-child)>.card-img-top{border-top-left-radius:0}.card-group>.card:not(:first-child)>.card-footer,.card-group>.card:not(:first-child)>.card-img-bottom{border-bottom-left-radius:0}}.accordion{--bs-accordion-color:var(--bs-body-color);--bs-accordion-bg:var(--bs-body-bg);--bs-accordion-transition:color 0.15s ease-in-out,background-color 0.15s ease-in-out,border-color 0.15s ease-in-out,box-shadow 0.15s ease-in-out,border-radius 0.15s ease;--bs-accordion-border-color:var(--bs-border-color);--bs-accordion-border-width:var(--bs-border-width);--bs-accordion-border-radius:var(--bs-border-radius);--bs-accordion-inner-border-radius:calc(var(--bs-border-radius) - (var(--bs-border-width)));--bs-accordion-btn-padding-x:1.25rem;--bs-accordion-btn-padding-y:1rem;--bs-accordion-btn-color:var(--bs-body-color);--bs-accordion-btn-bg:var(--bs-accordion-bg);--bs-accordion-btn-icon:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='%23212529' stroke-linecap='round' stroke-linejoin='round'%3e%3cpath d='m2 5 6 6 6-6'/%3e%3c/svg%3e");--bs-accordion-btn-icon-width:1.25rem;--bs-accordion-btn-icon-transform:rotate(-180deg);--bs-accordion-btn-icon-transition:transform 0.2s ease-in-out;--bs-accordion-btn-active-icon:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='%23052c65' stroke-linecap='round' stroke-linejoin='round'%3e%3cpath d='m2 5 6 6 6-6'/%3e%3c/svg%3e");--bs-accordion-btn-focus-box-shadow:0 0 0 0.25rem rgba(13, 110, 253, 0.25);--bs-accordion-body-padding-x:1.25rem;--bs-accordion-body-padding-y:1rem;--bs-accordion-active-color:var(--bs-primary-text-emphasis);--bs-accordion-active-bg:var(--bs-primary-bg-subtle)}.accordion-button{position:relative;display:flex;align-items:center;width:100%;padding:var(--bs-accordion-btn-padding-y) var(--bs-accordion-btn-padding-x);font-size:1rem;color:var(--bs-accordion-btn-color);text-align:left;background-color:var(--bs-accordion-btn-bg);border:0;border-radius:0;overflow-anchor:none;transition:var(--bs-accordion-transition)}@media (prefers-reduced-motion:reduce){.accordion-button{transition:none}}.accordion-button:not(.collapsed){color:var(--bs-accordion-active-color);background-color:var(--bs-accordion-active-bg);box-shadow:inset 0 calc(-1 * var(--bs-accordion-border-width)) 0 var(--bs-accordion-border-color)}.accordion-button:not(.collapsed)::after{background-image:var(--bs-accordion-btn-active-icon);transform:var(--bs-accordion-btn-icon-transform)}.accordion-button::after{flex-shrink:0;width:var(--bs-accordion-btn-icon-width);height:var(--bs-accordion-btn-icon-width);margin-left:auto;content:"";background-image:var(--bs-accordion-btn-icon);background-repeat:no-repeat;background-size:var(--bs-accordion-btn-icon-width);transition:var(--bs-accordion-btn-icon-transition)}@media (prefers-reduced-motion:reduce){.accordion-button::after{transition:none}}.accordion-button:hover{z-index:2}.accordion-button:focus{z-index:3;outline:0;box-shadow:var(--bs-accordion-btn-focus-box-shadow)}.accordion-header{margin-bottom:0}.accordion-item{color:var(--bs-accordion-color);background-color:var(--bs-accordion-bg);border:var(--bs-accordion-border-width) solid var(--bs-accordion-border-color)}.accordion-item:first-of-type{border-top-left-radius:var(--bs-accordion-border-radius);border-top-right-radius:var(--bs-accordion-border-radius)}.accordion-item:first-of-type>.accordion-header .accordion-button{border-top-left-radius:var(--bs-accordion-inner-border-radius);border-top-right-radius:var(--bs-accordion-inner-border-radius)}.accordion-item:not(:first-of-type){border-top:0}.accordion-item:last-of-type{border-bottom-right-radius:var(--bs-accordion-border-radius);border-bottom-left-radius:var(--bs-accordion-border-radius)}.accordion-item:last-of-type>.accordion-header .accordion-button.collapsed{border-bottom-right-radius:var(--bs-accordion-inner-border-radius);border-bottom-left-radius:var(--bs-accordion-inner-border-radius)}.accordion-item:last-of-type>.accordion-collapse{border-bottom-right-radius:var(--bs-accordion-border-radius);border-bottom-left-radius:var(--bs-accordion-border-radius)}.accordion-body{padding:var(--bs-accordion-body-padding-y) var(--bs-accordion-body-padding-x)}.accordion-flush>.accordion-item{border-right:0;border-left:0;border-radius:0}.accordion-flush>.accordion-item:first-child{border-top:0}.accordion-flush>.accordion-item:last-child{border-bottom:0}.accordion-flush>.accordion-item>.accordion-collapse,.accordion-flush>.accordion-item>.accordion-header .accordion-button,.accordion-flush>.accordion-item>.accordion-header .accordion-button.collapsed{border-radius:0}[data-bs-theme=dark] .accordion-button::after{--bs-accordion-btn-icon:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%236ea8fe'%3e%3cpath fill-rule='evenodd' d='M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708'/%3e%3c/svg%3e");--bs-accordion-btn-active-icon:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%236ea8fe'%3e%3cpath fill-rule='evenodd' d='M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708'/%3e%3c/svg%3e")}.breadcrumb{--bs-breadcrumb-padding-x:0;--bs-breadcrumb-padding-y:0;--bs-breadcrumb-margin-bottom:1rem;--bs-breadcrumb-bg: ;--bs-breadcrumb-border-radius: ;--bs-breadcrumb-divider-color:var(--bs-secondary-color);--bs-breadcrumb-item-padding-x:0.5rem;--bs-breadcrumb-item-active-color:var(--bs-secondary-color);display:flex;flex-wrap:wrap;padding:var(--bs-breadcrumb-padding-y) var(--bs-breadcrumb-padding-x);margin-bottom:var(--bs-breadcrumb-margin-bottom);font-size:var(--bs-breadcrumb-font-size);list-style:none;background-color:var(--bs-breadcrumb-bg);border-radius:var(--bs-breadcrumb-border-radius)}.breadcrumb-item+.breadcrumb-item{padding-left:var(--bs-breadcrumb-item-padding-x)}.breadcrumb-item+.breadcrumb-item::before{float:left;padding-right:var(--bs-breadcrumb-item-padding-x);color:var(--bs-breadcrumb-divider-color);content:var(--bs-breadcrumb-divider, "/")}.breadcrumb-item.active{color:var(--bs-breadcrumb-item-active-color)}.pagination{--bs-pagination-padding-x:0.75rem;--bs-pagination-padding-y:0.375rem;--bs-pagination-font-size:1rem;--bs-pagination-color:var(--bs-link-color);--bs-pagination-bg:var(--bs-body-bg);--bs-pagination-border-width:var(--bs-border-width);--bs-pagination-border-color:var(--bs-border-color);--bs-pagination-border-radius:var(--bs-border-radius);--bs-pagination-hover-color:var(--bs-link-hover-color);--bs-pagination-hover-bg:var(--bs-tertiary-bg);--bs-pagination-hover-border-color:var(--bs-border-color);--bs-pagination-focus-color:var(--bs-link-hover-color);--bs-pagination-focus-bg:var(--bs-secondary-bg);--bs-pagination-focus-box-shadow:0 0 0 0.25rem rgba(13, 110, 253, 0.25);--bs-pagination-active-color:#fff;--bs-pagination-active-bg:#0d6efd;--bs-pagination-active-border-color:#0d6efd;--bs-pagination-disabled-color:var(--bs-secondary-color);--bs-pagination-disabled-bg:var(--bs-secondary-bg);--bs-pagination-disabled-border-color:var(--bs-border-color);display:flex;padding-left:0;list-style:none}.page-link{position:relative;display:block;padding:var(--bs-pagination-padding-y) var(--bs-pagination-padding-x);font-size:var(--bs-pagination-font-size);color:var(--bs-pagination-color);text-decoration:none;background-color:var(--bs-pagination-bg);border:var(--bs-pagination-border-width) solid var(--bs-pagination-border-color);transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.page-link{transition:none}}.page-link:hover{z-index:2;color:var(--bs-pagination-hover-color);background-color:var(--bs-pagination-hover-bg);border-color:var(--bs-pagination-hover-border-color)}.page-link:focus{z-index:3;color:var(--bs-pagination-focus-color);background-color:var(--bs-pagination-focus-bg);outline:0;box-shadow:var(--bs-pagination-focus-box-shadow)}.active>.page-link,.page-link.active{z-index:3;color:var(--bs-pagination-active-color);background-color:var(--bs-pagination-active-bg);border-color:var(--bs-pagination-active-border-color)}.disabled>.page-link,.page-link.disabled{color:var(--bs-pagination-disabled-color);pointer-events:none;background-color:var(--bs-pagination-disabled-bg);border-color:var(--bs-pagination-disabled-border-color)}.page-item:not(:first-child) .page-link{margin-left:calc(-1 * var(--bs-border-width))}.page-item:first-child .page-link{border-top-left-radius:var(--bs-pagination-border-radius);border-bottom-left-radius:var(--bs-pagination-border-radius)}.page-item:last-child .page-link{border-top-right-radius:var(--bs-pagination-border-radius);border-bottom-right-radius:var(--bs-pagination-border-radius)}.pagination-lg{--bs-pagination-padding-x:1.5rem;--bs-pagination-padding-y:0.75rem;--bs-pagination-font-size:1.25rem;--bs-pagination-border-radius:var(--bs-border-radius-lg)}.pagination-sm{--bs-pagination-padding-x:0.5rem;--bs-pagination-padding-y:0.25rem;--bs-pagination-font-size:0.875rem;--bs-pagination-border-radius:var(--bs-border-radius-sm)}.badge{--bs-badge-padding-x:0.65em;--bs-badge-padding-y:0.35em;--bs-badge-font-size:0.75em;--bs-badge-font-weight:700;--bs-badge-color:#fff;--bs-badge-border-radius:var(--bs-border-radius);display:inline-block;padding:var(--bs-badge-padding-y) var(--bs-badge-padding-x);font-size:var(--bs-badge-font-size);font-weight:var(--bs-badge-font-weight);line-height:1;color:var(--bs-badge-color);text-align:center;white-space:nowrap;vertical-align:baseline;border-radius:var(--bs-badge-border-radius)}.badge:empty{display:none}.btn .badge{position:relative;top:-1px}.alert{--bs-alert-bg:transparent;--bs-alert-padding-x:1rem;--bs-alert-padding-y:1rem;--bs-alert-margin-bottom:1rem;--bs-alert-color:inherit;--bs-alert-border-color:transparent;--bs-alert-border:var(--bs-border-width) solid var(--bs-alert-border-color);--bs-alert-border-radius:var(--bs-border-radius);--bs-alert-link-color:inherit;position:relative;padding:var(--bs-alert-padding-y) var(--bs-alert-padding-x);margin-bottom:var(--bs-alert-margin-bottom);color:var(--bs-alert-color);background-color:var(--bs-alert-bg);border:var(--bs-alert-border);border-radius:var(--bs-alert-border-radius)}.alert-heading{color:inherit}.alert-link{font-weight:700;color:var(--bs-alert-link-color)}.alert-dismissible{padding-right:3rem}.alert-dismissible .btn-close{position:absolute;top:0;right:0;z-index:2;padding:1.25rem 1rem}.alert-primary{--bs-alert-color:var(--bs-primary-text-emphasis);--bs-alert-bg:var(--bs-primary-bg-subtle);--bs-alert-border-color:var(--bs-primary-border-subtle);--bs-alert-link-color:var(--bs-primary-text-emphasis)}.alert-secondary{--bs-alert-color:var(--bs-secondary-text-emphasis);--bs-alert-bg:var(--bs-secondary-bg-subtle);--bs-alert-border-color:var(--bs-secondary-border-subtle);--bs-alert-link-color:var(--bs-secondary-text-emphasis)}.alert-success{--bs-alert-color:var(--bs-success-text-emphasis);--bs-alert-bg:var(--bs-success-bg-subtle);--bs-alert-border-color:var(--bs-success-border-subtle);--bs-alert-link-color:var(--bs-success-text-emphasis)}.alert-info{--bs-alert-color:var(--bs-info-text-emphasis);--bs-alert-bg:var(--bs-info-bg-subtle);--bs-alert-border-color:var(--bs-info-border-subtle);--bs-alert-link-color:var(--bs-info-text-emphasis)}.alert-warning{--bs-alert-color:var(--bs-warning-text-emphasis);--bs-alert-bg:var(--bs-warning-bg-subtle);--bs-alert-border-color:var(--bs-warning-border-subtle);--bs-alert-link-color:var(--bs-warning-text-emphasis)}.alert-danger{--bs-alert-color:var(--bs-danger-text-emphasis);--bs-alert-bg:var(--bs-danger-bg-subtle);--bs-alert-border-color:var(--bs-danger-border-subtle);--bs-alert-link-color:var(--bs-danger-text-emphasis)}.alert-light{--bs-alert-color:var(--bs-light-text-emphasis);--bs-alert-bg:var(--bs-light-bg-subtle);--bs-alert-border-color:var(--bs-light-border-subtle);--bs-alert-link-color:var(--bs-light-text-emphasis)}.alert-dark{--bs-alert-color:var(--bs-dark-text-emphasis);--bs-alert-bg:var(--bs-dark-bg-subtle);--bs-alert-border-color:var(--bs-dark-border-subtle);--bs-alert-link-color:var(--bs-dark-text-emphasis)}@keyframes progress-bar-stripes{0%{background-position-x:var(--bs-progress-height)}}.progress,.progress-stacked{--bs-progress-height:1rem;--bs-progress-font-size:0.75rem;--bs-progress-bg:var(--bs-secondary-bg);--bs-progress-border-radius:var(--bs-border-radius);--bs-progress-box-shadow:var(--bs-box-shadow-inset);--bs-progress-bar-color:#fff;--bs-progress-bar-bg:#0d6efd;--bs-progress-bar-transition:width 0.6s ease;display:flex;height:var(--bs-progress-height);overflow:hidden;font-size:var(--bs-progress-font-size);background-color:var(--bs-progress-bg);border-radius:var(--bs-progress-border-radius)}.progress-bar{display:flex;flex-direction:column;justify-content:center;overflow:hidden;color:var(--bs-progress-bar-color);text-align:center;white-space:nowrap;background-color:var(--bs-progress-bar-bg);transition:var(--bs-progress-bar-transition)}@media (prefers-reduced-motion:reduce){.progress-bar{transition:none}}.progress-bar-striped{background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-size:var(--bs-progress-height) var(--bs-progress-height)}.progress-stacked>.progress{overflow:visible}.progress-stacked>.progress>.progress-bar{width:100%}.progress-bar-animated{animation:1s linear infinite progress-bar-stripes}@media (prefers-reduced-motion:reduce){.progress-bar-animated{animation:none}}.list-group{--bs-list-group-color:var(--bs-body-color);--bs-list-group-bg:var(--bs-body-bg);--bs-list-group-border-color:var(--bs-border-color);--bs-list-group-border-width:var(--bs-border-width);--bs-list-group-border-radius:var(--bs-border-radius);--bs-list-group-item-padding-x:1rem;--bs-list-group-item-padding-y:0.5rem;--bs-list-group-action-color:var(--bs-secondary-color);--bs-list-group-action-hover-color:var(--bs-emphasis-color);--bs-list-group-action-hover-bg:var(--bs-tertiary-bg);--bs-list-group-action-active-color:var(--bs-body-color);--bs-list-group-action-active-bg:var(--bs-secondary-bg);--bs-list-group-disabled-color:var(--bs-secondary-color);--bs-list-group-disabled-bg:var(--bs-body-bg);--bs-list-group-active-color:#fff;--bs-list-group-active-bg:#0d6efd;--bs-list-group-active-border-color:#0d6efd;display:flex;flex-direction:column;padding-left:0;margin-bottom:0;border-radius:var(--bs-list-group-border-radius)}.list-group-numbered{list-style-type:none;counter-reset:section}.list-group-numbered>.list-group-item::before{content:counters(section, ".") ". ";counter-increment:section}.list-group-item{position:relative;display:block;padding:var(--bs-list-group-item-padding-y) var(--bs-list-group-item-padding-x);color:var(--bs-list-group-color);text-decoration:none;background-color:var(--bs-list-group-bg);border:var(--bs-list-group-border-width) solid var(--bs-list-group-border-color)}.list-group-item:first-child{border-top-left-radius:inherit;border-top-right-radius:inherit}.list-group-item:last-child{border-bottom-right-radius:inherit;border-bottom-left-radius:inherit}.list-group-item.disabled,.list-group-item:disabled{color:var(--bs-list-group-disabled-color);pointer-events:none;background-color:var(--bs-list-group-disabled-bg)}.list-group-item.active{z-index:2;color:var(--bs-list-group-active-color);background-color:var(--bs-list-group-active-bg);border-color:var(--bs-list-group-active-border-color)}.list-group-item+.list-group-item{border-top-width:0}.list-group-item+.list-group-item.active{margin-top:calc(-1 * var(--bs-list-group-border-width));border-top-width:var(--bs-list-group-border-width)}.list-group-item-action{width:100%;color:var(--bs-list-group-action-color);text-align:inherit}.list-group-item-action:not(.active):focus,.list-group-item-action:not(.active):hover{z-index:1;color:var(--bs-list-group-action-hover-color);text-decoration:none;background-color:var(--bs-list-group-action-hover-bg)}.list-group-item-action:not(.active):active{color:var(--bs-list-group-action-active-color);background-color:var(--bs-list-group-action-active-bg)}.list-group-horizontal{flex-direction:row}.list-group-horizontal>.list-group-item:first-child:not(:last-child){border-bottom-left-radius:var(--bs-list-group-border-radius);border-top-right-radius:0}.list-group-horizontal>.list-group-item:last-child:not(:first-child){border-top-right-radius:var(--bs-list-group-border-radius);border-bottom-left-radius:0}.list-group-horizontal>.list-group-item.active{margin-top:0}.list-group-horizontal>.list-group-item+.list-group-item{border-top-width:var(--bs-list-group-border-width);border-left-width:0}.list-group-horizontal>.list-group-item+.list-group-item.active{margin-left:calc(-1 * var(--bs-list-group-border-width));border-left-width:var(--bs-list-group-border-width)}@media (min-width:576px){.list-group-horizontal-sm{flex-direction:row}.list-group-horizontal-sm>.list-group-item:first-child:not(:last-child){border-bottom-left-radius:var(--bs-list-group-border-radius);border-top-right-radius:0}.list-group-horizontal-sm>.list-group-item:last-child:not(:first-child){border-top-right-radius:var(--bs-list-group-border-radius);border-bottom-left-radius:0}.list-group-horizontal-sm>.list-group-item.active{margin-top:0}.list-group-horizontal-sm>.list-group-item+.list-group-item{border-top-width:var(--bs-list-group-border-width);border-left-width:0}.list-group-horizontal-sm>.list-group-item+.list-group-item.active{margin-left:calc(-1 * var(--bs-list-group-border-width));border-left-width:var(--bs-list-group-border-width)}}@media (min-width:768px){.list-group-horizontal-md{flex-direction:row}.list-group-horizontal-md>.list-group-item:first-child:not(:last-child){border-bottom-left-radius:var(--bs-list-group-border-radius);border-top-right-radius:0}.list-group-horizontal-md>.list-group-item:last-child:not(:first-child){border-top-right-radius:var(--bs-list-group-border-radius);border-bottom-left-radius:0}.list-group-horizontal-md>.list-group-item.active{margin-top:0}.list-group-horizontal-md>.list-group-item+.list-group-item{border-top-width:var(--bs-list-group-border-width);border-left-width:0}.list-group-horizontal-md>.list-group-item+.list-group-item.active{margin-left:calc(-1 * var(--bs-list-group-border-width));border-left-width:var(--bs-list-group-border-width)}}@media (min-width:992px){.list-group-horizontal-lg{flex-direction:row}.list-group-horizontal-lg>.list-group-item:first-child:not(:last-child){border-bottom-left-radius:var(--bs-list-group-border-radius);border-top-right-radius:0}.list-group-horizontal-lg>.list-group-item:last-child:not(:first-child){border-top-right-radius:var(--bs-list-group-border-radius);border-bottom-left-radius:0}.list-group-horizontal-lg>.list-group-item.active{margin-top:0}.list-group-horizontal-lg>.list-group-item+.list-group-item{border-top-width:var(--bs-list-group-border-width);border-left-width:0}.list-group-horizontal-lg>.list-group-item+.list-group-item.active{margin-left:calc(-1 * var(--bs-list-group-border-width));border-left-width:var(--bs-list-group-border-width)}}@media (min-width:1200px){.list-group-horizontal-xl{flex-direction:row}.list-group-horizontal-xl>.list-group-item:first-child:not(:last-child){border-bottom-left-radius:var(--bs-list-group-border-radius);border-top-right-radius:0}.list-group-horizontal-xl>.list-group-item:last-child:not(:first-child){border-top-right-radius:var(--bs-list-group-border-radius);border-bottom-left-radius:0}.list-group-horizontal-xl>.list-group-item.active{margin-top:0}.list-group-horizontal-xl>.list-group-item+.list-group-item{border-top-width:var(--bs-list-group-border-width);border-left-width:0}.list-group-horizontal-xl>.list-group-item+.list-group-item.active{margin-left:calc(-1 * var(--bs-list-group-border-width));border-left-width:var(--bs-list-group-border-width)}}@media (min-width:1400px){.list-group-horizontal-xxl{flex-direction:row}.list-group-horizontal-xxl>.list-group-item:first-child:not(:last-child){border-bottom-left-radius:var(--bs-list-group-border-radius);border-top-right-radius:0}.list-group-horizontal-xxl>.list-group-item:last-child:not(:first-child){border-top-right-radius:var(--bs-list-group-border-radius);border-bottom-left-radius:0}.list-group-horizontal-xxl>.list-group-item.active{margin-top:0}.list-group-horizontal-xxl>.list-group-item+.list-group-item{border-top-width:var(--bs-list-group-border-width);border-left-width:0}.list-group-horizontal-xxl>.list-group-item+.list-group-item.active{margin-left:calc(-1 * var(--bs-list-group-border-width));border-left-width:var(--bs-list-group-border-width)}}.list-group-flush{border-radius:0}.list-group-flush>.list-group-item{border-width:0 0 var(--bs-list-group-border-width)}.list-group-flush>.list-group-item:last-child{border-bottom-width:0}.list-group-item-primary{--bs-list-group-color:var(--bs-primary-text-emphasis);--bs-list-group-bg:var(--bs-primary-bg-subtle);--bs-list-group-border-color:var(--bs-primary-border-subtle);--bs-list-group-action-hover-color:var(--bs-emphasis-color);--bs-list-group-action-hover-bg:var(--bs-primary-border-subtle);--bs-list-group-action-active-color:var(--bs-emphasis-color);--bs-list-group-action-active-bg:var(--bs-primary-border-subtle);--bs-list-group-active-color:var(--bs-primary-bg-subtle);--bs-list-group-active-bg:var(--bs-primary-text-emphasis);--bs-list-group-active-border-color:var(--bs-primary-text-emphasis)}.list-group-item-secondary{--bs-list-group-color:var(--bs-secondary-text-emphasis);--bs-list-group-bg:var(--bs-secondary-bg-subtle);--bs-list-group-border-color:var(--bs-secondary-border-subtle);--bs-list-group-action-hover-color:var(--bs-emphasis-color);--bs-list-group-action-hover-bg:var(--bs-secondary-border-subtle);--bs-list-group-action-active-color:var(--bs-emphasis-color);--bs-list-group-action-active-bg:var(--bs-secondary-border-subtle);--bs-list-group-active-color:var(--bs-secondary-bg-subtle);--bs-list-group-active-bg:var(--bs-secondary-text-emphasis);--bs-list-group-active-border-color:var(--bs-secondary-text-emphasis)}.list-group-item-success{--bs-list-group-color:var(--bs-success-text-emphasis);--bs-list-group-bg:var(--bs-success-bg-subtle);--bs-list-group-border-color:var(--bs-success-border-subtle);--bs-list-group-action-hover-color:var(--bs-emphasis-color);--bs-list-group-action-hover-bg:var(--bs-success-border-subtle);--bs-list-group-action-active-color:var(--bs-emphasis-color);--bs-list-group-action-active-bg:var(--bs-success-border-subtle);--bs-list-group-active-color:var(--bs-success-bg-subtle);--bs-list-group-active-bg:var(--bs-success-text-emphasis);--bs-list-group-active-border-color:var(--bs-success-text-emphasis)}.list-group-item-info{--bs-list-group-color:var(--bs-info-text-emphasis);--bs-list-group-bg:var(--bs-info-bg-subtle);--bs-list-group-border-color:var(--bs-info-border-subtle);--bs-list-group-action-hover-color:var(--bs-emphasis-color);--bs-list-group-action-hover-bg:var(--bs-info-border-subtle);--bs-list-group-action-active-color:var(--bs-emphasis-color);--bs-list-group-action-active-bg:var(--bs-info-border-subtle);--bs-list-group-active-color:var(--bs-info-bg-subtle);--bs-list-group-active-bg:var(--bs-info-text-emphasis);--bs-list-group-active-border-color:var(--bs-info-text-emphasis)}.list-group-item-warning{--bs-list-group-color:var(--bs-warning-text-emphasis);--bs-list-group-bg:var(--bs-warning-bg-subtle);--bs-list-group-border-color:var(--bs-warning-border-subtle);--bs-list-group-action-hover-color:var(--bs-emphasis-color);--bs-list-group-action-hover-bg:var(--bs-warning-border-subtle);--bs-list-group-action-active-color:var(--bs-emphasis-color);--bs-list-group-action-active-bg:var(--bs-warning-border-subtle);--bs-list-group-active-color:var(--bs-warning-bg-subtle);--bs-list-group-active-bg:var(--bs-warning-text-emphasis);--bs-list-group-active-border-color:var(--bs-warning-text-emphasis)}.list-group-item-danger{--bs-list-group-color:var(--bs-danger-text-emphasis);--bs-list-group-bg:var(--bs-danger-bg-subtle);--bs-list-group-border-color:var(--bs-danger-border-subtle);--bs-list-group-action-hover-color:var(--bs-emphasis-color);--bs-list-group-action-hover-bg:var(--bs-danger-border-subtle);--bs-list-group-action-active-color:var(--bs-emphasis-color);--bs-list-group-action-active-bg:var(--bs-danger-border-subtle);--bs-list-group-active-color:var(--bs-danger-bg-subtle);--bs-list-group-active-bg:var(--bs-danger-text-emphasis);--bs-list-group-active-border-color:var(--bs-danger-text-emphasis)}.list-group-item-light{--bs-list-group-color:var(--bs-light-text-emphasis);--bs-list-group-bg:var(--bs-light-bg-subtle);--bs-list-group-border-color:var(--bs-light-border-subtle);--bs-list-group-action-hover-color:var(--bs-emphasis-color);--bs-list-group-action-hover-bg:var(--bs-light-border-subtle);--bs-list-group-action-active-color:var(--bs-emphasis-color);--bs-list-group-action-active-bg:var(--bs-light-border-subtle);--bs-list-group-active-color:var(--bs-light-bg-subtle);--bs-list-group-active-bg:var(--bs-light-text-emphasis);--bs-list-group-active-border-color:var(--bs-light-text-emphasis)}.list-group-item-dark{--bs-list-group-color:var(--bs-dark-text-emphasis);--bs-list-group-bg:var(--bs-dark-bg-subtle);--bs-list-group-border-color:var(--bs-dark-border-subtle);--bs-list-group-action-hover-color:var(--bs-emphasis-color);--bs-list-group-action-hover-bg:var(--bs-dark-border-subtle);--bs-list-group-action-active-color:var(--bs-emphasis-color);--bs-list-group-action-active-bg:var(--bs-dark-border-subtle);--bs-list-group-active-color:var(--bs-dark-bg-subtle);--bs-list-group-active-bg:var(--bs-dark-text-emphasis);--bs-list-group-active-border-color:var(--bs-dark-text-emphasis)}.btn-close{--bs-btn-close-color:#000;--bs-btn-close-bg:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23000'%3e%3cpath d='M.293.293a1 1 0 0 1 1.414 0L8 6.586 14.293.293a1 1 0 1 1 1.414 1.414L9.414 8l6.293 6.293a1 1 0 0 1-1.414 1.414L8 9.414l-6.293 6.293a1 1 0 0 1-1.414-1.414L6.586 8 .293 1.707a1 1 0 0 1 0-1.414'/%3e%3c/svg%3e");--bs-btn-close-opacity:0.5;--bs-btn-close-hover-opacity:0.75;--bs-btn-close-focus-shadow:0 0 0 0.25rem rgba(13, 110, 253, 0.25);--bs-btn-close-focus-opacity:1;--bs-btn-close-disabled-opacity:0.25;box-sizing:content-box;width:1em;height:1em;padding:.25em .25em;color:var(--bs-btn-close-color);background:transparent var(--bs-btn-close-bg) center/1em auto no-repeat;filter:var(--bs-btn-close-filter);border:0;border-radius:.375rem;opacity:var(--bs-btn-close-opacity)}.btn-close:hover{color:var(--bs-btn-close-color);text-decoration:none;opacity:var(--bs-btn-close-hover-opacity)}.btn-close:focus{outline:0;box-shadow:var(--bs-btn-close-focus-shadow);opacity:var(--bs-btn-close-focus-opacity)}.btn-close.disabled,.btn-close:disabled{pointer-events:none;-webkit-user-select:none;-moz-user-select:none;user-select:none;opacity:var(--bs-btn-close-disabled-opacity)}.btn-close-white{--bs-btn-close-filter:invert(1) grayscale(100%) brightness(200%)}:root,[data-bs-theme=light]{--bs-btn-close-filter: }[data-bs-theme=dark]{--bs-btn-close-filter:invert(1) grayscale(100%) brightness(200%)}.toast{--bs-toast-zindex:1090;--bs-toast-padding-x:0.75rem;--bs-toast-padding-y:0.5rem;--bs-toast-spacing:1.5rem;--bs-toast-max-width:350px;--bs-toast-font-size:0.875rem;--bs-toast-color: ;--bs-toast-bg:rgba(var(--bs-body-bg-rgb), 0.85);--bs-toast-border-width:var(--bs-border-width);--bs-toast-border-color:var(--bs-border-color-translucent);--bs-toast-border-radius:var(--bs-border-radius);--bs-toast-box-shadow:var(--bs-box-shadow);--bs-toast-header-color:var(--bs-secondary-color);--bs-toast-header-bg:rgba(var(--bs-body-bg-rgb), 0.85);--bs-toast-header-border-color:var(--bs-border-color-translucent);width:var(--bs-toast-max-width);max-width:100%;font-size:var(--bs-toast-font-size);color:var(--bs-toast-color);pointer-events:auto;background-color:var(--bs-toast-bg);background-clip:padding-box;border:var(--bs-toast-border-width) solid var(--bs-toast-border-color);box-shadow:var(--bs-toast-box-shadow);border-radius:var(--bs-toast-border-radius)}.toast.showing{opacity:0}.toast:not(.show){display:none}.toast-container{--bs-toast-zindex:1090;position:absolute;z-index:var(--bs-toast-zindex);width:-webkit-max-content;width:-moz-max-content;width:max-content;max-width:100%;pointer-events:none}.toast-container>:not(:last-child){margin-bottom:var(--bs-toast-spacing)}.toast-header{display:flex;align-items:center;padding:var(--bs-toast-padding-y) var(--bs-toast-padding-x);color:var(--bs-toast-header-color);background-color:var(--bs-toast-header-bg);background-clip:padding-box;border-bottom:var(--bs-toast-border-width) solid var(--bs-toast-header-border-color);border-top-left-radius:calc(var(--bs-toast-border-radius) - var(--bs-toast-border-width));border-top-right-radius:calc(var(--bs-toast-border-radius) - var(--bs-toast-border-width))}.toast-header .btn-close{margin-right:calc(-.5 * var(--bs-toast-padding-x));margin-left:var(--bs-toast-padding-x)}.toast-body{padding:var(--bs-toast-padding-x);word-wrap:break-word}.modal{--bs-modal-zindex:1055;--bs-modal-width:500px;--bs-modal-padding:1rem;--bs-modal-margin:0.5rem;--bs-modal-color:var(--bs-body-color);--bs-modal-bg:var(--bs-body-bg);--bs-modal-border-color:var(--bs-border-color-translucent);--bs-modal-border-width:var(--bs-border-width);--bs-modal-border-radius:var(--bs-border-radius-lg);--bs-modal-box-shadow:var(--bs-box-shadow-sm);--bs-modal-inner-border-radius:calc(var(--bs-border-radius-lg) - (var(--bs-border-width)));--bs-modal-header-padding-x:1rem;--bs-modal-header-padding-y:1rem;--bs-modal-header-padding:1rem 1rem;--bs-modal-header-border-color:var(--bs-border-color);--bs-modal-header-border-width:var(--bs-border-width);--bs-modal-title-line-height:1.5;--bs-modal-footer-gap:0.5rem;--bs-modal-footer-bg: ;--bs-modal-footer-border-color:var(--bs-border-color);--bs-modal-footer-border-width:var(--bs-border-width);position:fixed;top:0;left:0;z-index:var(--bs-modal-zindex);display:none;width:100%;height:100%;overflow-x:hidden;overflow-y:auto;outline:0}.modal-dialog{position:relative;width:auto;margin:var(--bs-modal-margin);pointer-events:none}.modal.fade .modal-dialog{transform:translate(0,-50px);transition:transform .3s ease-out}@media (prefers-reduced-motion:reduce){.modal.fade .modal-dialog{transition:none}}.modal.show .modal-dialog{transform:none}.modal.modal-static .modal-dialog{transform:scale(1.02)}.modal-dialog-scrollable{height:calc(100% - var(--bs-modal-margin) * 2)}.modal-dialog-scrollable .modal-content{max-height:100%;overflow:hidden}.modal-dialog-scrollable .modal-body{overflow-y:auto}.modal-dialog-centered{display:flex;align-items:center;min-height:calc(100% - var(--bs-modal-margin) * 2)}.modal-content{position:relative;display:flex;flex-direction:column;width:100%;color:var(--bs-modal-color);pointer-events:auto;background-color:var(--bs-modal-bg);background-clip:padding-box;border:var(--bs-modal-border-width) solid var(--bs-modal-border-color);border-radius:var(--bs-modal-border-radius);outline:0}.modal-backdrop{--bs-backdrop-zindex:1050;--bs-backdrop-bg:#000;--bs-backdrop-opacity:0.5;position:fixed;top:0;left:0;z-index:var(--bs-backdrop-zindex);width:100vw;height:100vh;background-color:var(--bs-backdrop-bg)}.modal-backdrop.fade{opacity:0}.modal-backdrop.show{opacity:var(--bs-backdrop-opacity)}.modal-header{display:flex;flex-shrink:0;align-items:center;padding:var(--bs-modal-header-padding);border-bottom:var(--bs-modal-header-border-width) solid var(--bs-modal-header-border-color);border-top-left-radius:var(--bs-modal-inner-border-radius);border-top-right-radius:var(--bs-modal-inner-border-radius)}.modal-header .btn-close{padding:calc(var(--bs-modal-header-padding-y) * .5) calc(var(--bs-modal-header-padding-x) * .5);margin-top:calc(-.5 * var(--bs-modal-header-padding-y));margin-right:calc(-.5 * var(--bs-modal-header-padding-x));margin-bottom:calc(-.5 * var(--bs-modal-header-padding-y));margin-left:auto}.modal-title{margin-bottom:0;line-height:var(--bs-modal-title-line-height)}.modal-body{position:relative;flex:1 1 auto;padding:var(--bs-modal-padding)}.modal-footer{display:flex;flex-shrink:0;flex-wrap:wrap;align-items:center;justify-content:flex-end;padding:calc(var(--bs-modal-padding) - var(--bs-modal-footer-gap) * .5);background-color:var(--bs-modal-footer-bg);border-top:var(--bs-modal-footer-border-width) solid var(--bs-modal-footer-border-color);border-bottom-right-radius:var(--bs-modal-inner-border-radius);border-bottom-left-radius:var(--bs-modal-inner-border-radius)}.modal-footer>*{margin:calc(var(--bs-modal-footer-gap) * .5)}@media (min-width:576px){.modal{--bs-modal-margin:1.75rem;--bs-modal-box-shadow:var(--bs-box-shadow)}.modal-dialog{max-width:var(--bs-modal-width);margin-right:auto;margin-left:auto}.modal-sm{--bs-modal-width:300px}}@media (min-width:992px){.modal-lg,.modal-xl{--bs-modal-width:800px}}@media (min-width:1200px){.modal-xl{--bs-modal-width:1140px}}.modal-fullscreen{width:100vw;max-width:none;height:100%;margin:0}.modal-fullscreen .modal-content{height:100%;border:0;border-radius:0}.modal-fullscreen .modal-footer,.modal-fullscreen .modal-header{border-radius:0}.modal-fullscreen .modal-body{overflow-y:auto}@media (max-width:575.98px){.modal-fullscreen-sm-down{width:100vw;max-width:none;height:100%;margin:0}.modal-fullscreen-sm-down .modal-content{height:100%;border:0;border-radius:0}.modal-fullscreen-sm-down .modal-footer,.modal-fullscreen-sm-down .modal-header{border-radius:0}.modal-fullscreen-sm-down .modal-body{overflow-y:auto}}@media (max-width:767.98px){.modal-fullscreen-md-down{width:100vw;max-width:none;height:100%;margin:0}.modal-fullscreen-md-down .modal-content{height:100%;border:0;border-radius:0}.modal-fullscreen-md-down .modal-footer,.modal-fullscreen-md-down .modal-header{border-radius:0}.modal-fullscreen-md-down .modal-body{overflow-y:auto}}@media (max-width:991.98px){.modal-fullscreen-lg-down{width:100vw;max-width:none;height:100%;margin:0}.modal-fullscreen-lg-down .modal-content{height:100%;border:0;border-radius:0}.modal-fullscreen-lg-down .modal-footer,.modal-fullscreen-lg-down .modal-header{border-radius:0}.modal-fullscreen-lg-down .modal-body{overflow-y:auto}}@media (max-width:1199.98px){.modal-fullscreen-xl-down{width:100vw;max-width:none;height:100%;margin:0}.modal-fullscreen-xl-down .modal-content{height:100%;border:0;border-radius:0}.modal-fullscreen-xl-down .modal-footer,.modal-fullscreen-xl-down .modal-header{border-radius:0}.modal-fullscreen-xl-down .modal-body{overflow-y:auto}}@media (max-width:1399.98px){.modal-fullscreen-xxl-down{width:100vw;max-width:none;height:100%;margin:0}.modal-fullscreen-xxl-down .modal-content{height:100%;border:0;border-radius:0}.modal-fullscreen-xxl-down .modal-footer,.modal-fullscreen-xxl-down .modal-header{border-radius:0}.modal-fullscreen-xxl-down .modal-body{overflow-y:auto}}.tooltip{--bs-tooltip-zindex:1080;--bs-tooltip-max-width:200px;--bs-tooltip-padding-x:0.5rem;--bs-tooltip-padding-y:0.25rem;--bs-tooltip-margin: ;--bs-tooltip-font-size:0.875rem;--bs-tooltip-color:var(--bs-body-bg);--bs-tooltip-bg:var(--bs-emphasis-color);--bs-tooltip-border-radius:var(--bs-border-radius);--bs-tooltip-opacity:0.9;--bs-tooltip-arrow-width:0.8rem;--bs-tooltip-arrow-height:0.4rem;z-index:var(--bs-tooltip-zindex);display:block;margin:var(--bs-tooltip-margin);font-family:var(--bs-font-sans-serif);font-style:normal;font-weight:400;line-height:1.5;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;white-space:normal;word-spacing:normal;line-break:auto;font-size:var(--bs-tooltip-font-size);word-wrap:break-word;opacity:0}.tooltip.show{opacity:var(--bs-tooltip-opacity)}.tooltip .tooltip-arrow{display:block;width:var(--bs-tooltip-arrow-width);height:var(--bs-tooltip-arrow-height)}.tooltip .tooltip-arrow::before{position:absolute;content:"";border-color:transparent;border-style:solid}.bs-tooltip-auto[data-popper-placement^=top] .tooltip-arrow,.bs-tooltip-top .tooltip-arrow{bottom:calc(-1 * var(--bs-tooltip-arrow-height))}.bs-tooltip-auto[data-popper-placement^=top] .tooltip-arrow::before,.bs-tooltip-top .tooltip-arrow::before{top:-1px;border-width:var(--bs-tooltip-arrow-height) calc(var(--bs-tooltip-arrow-width) * .5) 0;border-top-color:var(--bs-tooltip-bg)}.bs-tooltip-auto[data-popper-placement^=right] .tooltip-arrow,.bs-tooltip-end .tooltip-arrow{left:calc(-1 * var(--bs-tooltip-arrow-height));width:var(--bs-tooltip-arrow-height);height:var(--bs-tooltip-arrow-width)}.bs-tooltip-auto[data-popper-placement^=right] .tooltip-arrow::before,.bs-tooltip-end .tooltip-arrow::before{right:-1px;border-width:calc(var(--bs-tooltip-arrow-width) * .5) var(--bs-tooltip-arrow-height) calc(var(--bs-tooltip-arrow-width) * .5) 0;border-right-color:var(--bs-tooltip-bg)}.bs-tooltip-auto[data-popper-placement^=bottom] .tooltip-arrow,.bs-tooltip-bottom .tooltip-arrow{top:calc(-1 * var(--bs-tooltip-arrow-height))}.bs-tooltip-auto[data-popper-placement^=bottom] .tooltip-arrow::before,.bs-tooltip-bottom .tooltip-arrow::before{bottom:-1px;border-width:0 calc(var(--bs-tooltip-arrow-width) * .5) var(--bs-tooltip-arrow-height);border-bottom-color:var(--bs-tooltip-bg)}.bs-tooltip-auto[data-popper-placement^=left] .tooltip-arrow,.bs-tooltip-start .tooltip-arrow{right:calc(-1 * var(--bs-tooltip-arrow-height));width:var(--bs-tooltip-arrow-height);height:var(--bs-tooltip-arrow-width)}.bs-tooltip-auto[data-popper-placement^=left] .tooltip-arrow::before,.bs-tooltip-start .tooltip-arrow::before{left:-1px;border-width:calc(var(--bs-tooltip-arrow-width) * .5) 0 calc(var(--bs-tooltip-arrow-width) * .5) var(--bs-tooltip-arrow-height);border-left-color:var(--bs-tooltip-bg)}.tooltip-inner{max-width:var(--bs-tooltip-max-width);padding:var(--bs-tooltip-padding-y) var(--bs-tooltip-padding-x);color:var(--bs-tooltip-color);text-align:center;background-color:var(--bs-tooltip-bg);border-radius:var(--bs-tooltip-border-radius)}.popover{--bs-popover-zindex:1070;--bs-popover-max-width:276px;--bs-popover-font-size:0.875rem;--bs-popover-bg:var(--bs-body-bg);--bs-popover-border-width:var(--bs-border-width);--bs-popover-border-color:var(--bs-border-color-translucent);--bs-popover-border-radius:var(--bs-border-radius-lg);--bs-popover-inner-border-radius:calc(var(--bs-border-radius-lg) - var(--bs-border-width));--bs-popover-box-shadow:var(--bs-box-shadow);--bs-popover-header-padding-x:1rem;--bs-popover-header-padding-y:0.5rem;--bs-popover-header-font-size:1rem;--bs-popover-header-color:inherit;--bs-popover-header-bg:var(--bs-secondary-bg);--bs-popover-body-padding-x:1rem;--bs-popover-body-padding-y:1rem;--bs-popover-body-color:var(--bs-body-color);--bs-popover-arrow-width:1rem;--bs-popover-arrow-height:0.5rem;--bs-popover-arrow-border:var(--bs-popover-border-color);z-index:var(--bs-popover-zindex);display:block;max-width:var(--bs-popover-max-width);font-family:var(--bs-font-sans-serif);font-style:normal;font-weight:400;line-height:1.5;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;white-space:normal;word-spacing:normal;line-break:auto;font-size:var(--bs-popover-font-size);word-wrap:break-word;background-color:var(--bs-popover-bg);background-clip:padding-box;border:var(--bs-popover-border-width) solid var(--bs-popover-border-color);border-radius:var(--bs-popover-border-radius)}.popover .popover-arrow{display:block;width:var(--bs-popover-arrow-width);height:var(--bs-popover-arrow-height)}.popover .popover-arrow::after,.popover .popover-arrow::before{position:absolute;display:block;content:"";border-color:transparent;border-style:solid;border-width:0}.bs-popover-auto[data-popper-placement^=top]>.popover-arrow,.bs-popover-top>.popover-arrow{bottom:calc(-1 * (var(--bs-popover-arrow-height)) - var(--bs-popover-border-width))}.bs-popover-auto[data-popper-placement^=top]>.popover-arrow::after,.bs-popover-auto[data-popper-placement^=top]>.popover-arrow::before,.bs-popover-top>.popover-arrow::after,.bs-popover-top>.popover-arrow::before{border-width:var(--bs-popover-arrow-height) calc(var(--bs-popover-arrow-width) * .5) 0}.bs-popover-auto[data-popper-placement^=top]>.popover-arrow::before,.bs-popover-top>.popover-arrow::before{bottom:0;border-top-color:var(--bs-popover-arrow-border)}.bs-popover-auto[data-popper-placement^=top]>.popover-arrow::after,.bs-popover-top>.popover-arrow::after{bottom:var(--bs-popover-border-width);border-top-color:var(--bs-popover-bg)}.bs-popover-auto[data-popper-placement^=right]>.popover-arrow,.bs-popover-end>.popover-arrow{left:calc(-1 * (var(--bs-popover-arrow-height)) - var(--bs-popover-border-width));width:var(--bs-popover-arrow-height);height:var(--bs-popover-arrow-width)}.bs-popover-auto[data-popper-placement^=right]>.popover-arrow::after,.bs-popover-auto[data-popper-placement^=right]>.popover-arrow::before,.bs-popover-end>.popover-arrow::after,.bs-popover-end>.popover-arrow::before{border-width:calc(var(--bs-popover-arrow-width) * .5) var(--bs-popover-arrow-height) calc(var(--bs-popover-arrow-width) * .5) 0}.bs-popover-auto[data-popper-placement^=right]>.popover-arrow::before,.bs-popover-end>.popover-arrow::before{left:0;border-right-color:var(--bs-popover-arrow-border)}.bs-popover-auto[data-popper-placement^=right]>.popover-arrow::after,.bs-popover-end>.popover-arrow::after{left:var(--bs-popover-border-width);border-right-color:var(--bs-popover-bg)}.bs-popover-auto[data-popper-placement^=bottom]>.popover-arrow,.bs-popover-bottom>.popover-arrow{top:calc(-1 * (var(--bs-popover-arrow-height)) - var(--bs-popover-border-width))}.bs-popover-auto[data-popper-placement^=bottom]>.popover-arrow::after,.bs-popover-auto[data-popper-placement^=bottom]>.popover-arrow::before,.bs-popover-bottom>.popover-arrow::after,.bs-popover-bottom>.popover-arrow::before{border-width:0 calc(var(--bs-popover-arrow-width) * .5) var(--bs-popover-arrow-height)}.bs-popover-auto[data-popper-placement^=bottom]>.popover-arrow::before,.bs-popover-bottom>.popover-arrow::before{top:0;border-bottom-color:var(--bs-popover-arrow-border)}.bs-popover-auto[data-popper-placement^=bottom]>.popover-arrow::after,.bs-popover-bottom>.popover-arrow::after{top:var(--bs-popover-border-width);border-bottom-color:var(--bs-popover-bg)}.bs-popover-auto[data-popper-placement^=bottom] .popover-header::before,.bs-popover-bottom .popover-header::before{position:absolute;top:0;left:50%;display:block;width:var(--bs-popover-arrow-width);margin-left:calc(-.5 * var(--bs-popover-arrow-width));content:"";border-bottom:var(--bs-popover-border-width) solid var(--bs-popover-header-bg)}.bs-popover-auto[data-popper-placement^=left]>.popover-arrow,.bs-popover-start>.popover-arrow{right:calc(-1 * (var(--bs-popover-arrow-height)) - var(--bs-popover-border-width));width:var(--bs-popover-arrow-height);height:var(--bs-popover-arrow-width)}.bs-popover-auto[data-popper-placement^=left]>.popover-arrow::after,.bs-popover-auto[data-popper-placement^=left]>.popover-arrow::before,.bs-popover-start>.popover-arrow::after,.bs-popover-start>.popover-arrow::before{border-width:calc(var(--bs-popover-arrow-width) * .5) 0 calc(var(--bs-popover-arrow-width) * .5) var(--bs-popover-arrow-height)}.bs-popover-auto[data-popper-placement^=left]>.popover-arrow::before,.bs-popover-start>.popover-arrow::before{right:0;border-left-color:var(--bs-popover-arrow-border)}.bs-popover-auto[data-popper-placement^=left]>.popover-arrow::after,.bs-popover-start>.popover-arrow::after{right:var(--bs-popover-border-width);border-left-color:var(--bs-popover-bg)}.popover-header{padding:var(--bs-popover-header-padding-y) var(--bs-popover-header-padding-x);margin-bottom:0;font-size:var(--bs-popover-header-font-size);color:var(--bs-popover-header-color);background-color:var(--bs-popover-header-bg);border-bottom:var(--bs-popover-border-width) solid var(--bs-popover-border-color);border-top-left-radius:var(--bs-popover-inner-border-radius);border-top-right-radius:var(--bs-popover-inner-border-radius)}.popover-header:empty{display:none}.popover-body{padding:var(--bs-popover-body-padding-y) var(--bs-popover-body-padding-x);color:var(--bs-popover-body-color)}.carousel{position:relative}.carousel.pointer-event{touch-action:pan-y}.carousel-inner{position:relative;width:100%;overflow:hidden}.carousel-inner::after{display:block;clear:both;content:""}.carousel-item{position:relative;display:none;float:left;width:100%;margin-right:-100%;-webkit-backface-visibility:hidden;backface-visibility:hidden;transition:transform .6s ease-in-out}@media (prefers-reduced-motion:reduce){.carousel-item{transition:none}}.carousel-item-next,.carousel-item-prev,.carousel-item.active{display:block}.active.carousel-item-end,.carousel-item-next:not(.carousel-item-start){transform:translateX(100%)}.active.carousel-item-start,.carousel-item-prev:not(.carousel-item-end){transform:translateX(-100%)}.carousel-fade .carousel-item{opacity:0;transition-property:opacity;transform:none}.carousel-fade .carousel-item-next.carousel-item-start,.carousel-fade .carousel-item-prev.carousel-item-end,.carousel-fade .carousel-item.active{z-index:1;opacity:1}.carousel-fade .active.carousel-item-end,.carousel-fade .active.carousel-item-start{z-index:0;opacity:0;transition:opacity 0s .6s}@media (prefers-reduced-motion:reduce){.carousel-fade .active.carousel-item-end,.carousel-fade .active.carousel-item-start{transition:none}}.carousel-control-next,.carousel-control-prev{position:absolute;top:0;bottom:0;z-index:1;display:flex;align-items:center;justify-content:center;width:15%;padding:0;color:#fff;text-align:center;background:0 0;filter:var(--bs-carousel-control-icon-filter);border:0;opacity:.5;transition:opacity .15s ease}@media (prefers-reduced-motion:reduce){.carousel-control-next,.carousel-control-prev{transition:none}}.carousel-control-next:focus,.carousel-control-next:hover,.carousel-control-prev:focus,.carousel-control-prev:hover{color:#fff;text-decoration:none;outline:0;opacity:.9}.carousel-control-prev{left:0}.carousel-control-next{right:0}.carousel-control-next-icon,.carousel-control-prev-icon{display:inline-block;width:2rem;height:2rem;background-repeat:no-repeat;background-position:50%;background-size:100% 100%}.carousel-control-prev-icon{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23fff'%3e%3cpath d='M11.354 1.646a.5.5 0 0 1 0 .708L5.707 8l5.647 5.646a.5.5 0 0 1-.708.708l-6-6a.5.5 0 0 1 0-.708l6-6a.5.5 0 0 1 .708 0'/%3e%3c/svg%3e")}.carousel-control-next-icon{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23fff'%3e%3cpath d='M4.646 1.646a.5.5 0 0 1 .708 0l6 6a.5.5 0 0 1 0 .708l-6 6a.5.5 0 0 1-.708-.708L10.293 8 4.646 2.354a.5.5 0 0 1 0-.708'/%3e%3c/svg%3e")}.carousel-indicators{position:absolute;right:0;bottom:0;left:0;z-index:2;display:flex;justify-content:center;padding:0;margin-right:15%;margin-bottom:1rem;margin-left:15%}.carousel-indicators [data-bs-target]{box-sizing:content-box;flex:0 1 auto;width:30px;height:3px;padding:0;margin-right:3px;margin-left:3px;text-indent:-999px;cursor:pointer;background-color:var(--bs-carousel-indicator-active-bg);background-clip:padding-box;border:0;border-top:10px solid transparent;border-bottom:10px solid transparent;opacity:.5;transition:opacity .6s ease}@media (prefers-reduced-motion:reduce){.carousel-indicators [data-bs-target]{transition:none}}.carousel-indicators .active{opacity:1}.carousel-caption{position:absolute;right:15%;bottom:1.25rem;left:15%;padding-top:1.25rem;padding-bottom:1.25rem;color:var(--bs-carousel-caption-color);text-align:center}.carousel-dark{--bs-carousel-indicator-active-bg:#000;--bs-carousel-caption-color:#000;--bs-carousel-control-icon-filter:invert(1) grayscale(100)}:root,[data-bs-theme=light]{--bs-carousel-indicator-active-bg:#fff;--bs-carousel-caption-color:#fff;--bs-carousel-control-icon-filter: }[data-bs-theme=dark]{--bs-carousel-indicator-active-bg:#000;--bs-carousel-caption-color:#000;--bs-carousel-control-icon-filter:invert(1) grayscale(100)}.spinner-border,.spinner-grow{display:inline-block;width:var(--bs-spinner-width);height:var(--bs-spinner-height);vertical-align:var(--bs-spinner-vertical-align);border-radius:50%;animation:var(--bs-spinner-animation-speed) linear infinite var(--bs-spinner-animation-name)}@keyframes spinner-border{to{transform:rotate(360deg)}}.spinner-border{--bs-spinner-width:2rem;--bs-spinner-height:2rem;--bs-spinner-vertical-align:-0.125em;--bs-spinner-border-width:0.25em;--bs-spinner-animation-speed:0.75s;--bs-spinner-animation-name:spinner-border;border:var(--bs-spinner-border-width) solid currentcolor;border-right-color:transparent}.spinner-border-sm{--bs-spinner-width:1rem;--bs-spinner-height:1rem;--bs-spinner-border-width:0.2em}@keyframes spinner-grow{0%{transform:scale(0)}50%{opacity:1;transform:none}}.spinner-grow{--bs-spinner-width:2rem;--bs-spinner-height:2rem;--bs-spinner-vertical-align:-0.125em;--bs-spinner-animation-speed:0.75s;--bs-spinner-animation-name:spinner-grow;background-color:currentcolor;opacity:0}.spinner-grow-sm{--bs-spinner-width:1rem;--bs-spinner-height:1rem}@media (prefers-reduced-motion:reduce){.spinner-border,.spinner-grow{--bs-spinner-animation-speed:1.5s}}.offcanvas,.offcanvas-lg,.offcanvas-md,.offcanvas-sm,.offcanvas-xl,.offcanvas-xxl{--bs-offcanvas-zindex:1045;--bs-offcanvas-width:400px;--bs-offcanvas-height:30vh;--bs-offcanvas-padding-x:1rem;--bs-offcanvas-padding-y:1rem;--bs-offcanvas-color:var(--bs-body-color);--bs-offcanvas-bg:var(--bs-body-bg);--bs-offcanvas-border-width:var(--bs-border-width);--bs-offcanvas-border-color:var(--bs-border-color-translucent);--bs-offcanvas-box-shadow:var(--bs-box-shadow-sm);--bs-offcanvas-transition:transform 0.3s ease-in-out;--bs-offcanvas-title-line-height:1.5}@media (max-width:575.98px){.offcanvas-sm{position:fixed;bottom:0;z-index:var(--bs-offcanvas-zindex);display:flex;flex-direction:column;max-width:100%;color:var(--bs-offcanvas-color);visibility:hidden;background-color:var(--bs-offcanvas-bg);background-clip:padding-box;outline:0;transition:var(--bs-offcanvas-transition)}}@media (max-width:575.98px) and (prefers-reduced-motion:reduce){.offcanvas-sm{transition:none}}@media (max-width:575.98px){.offcanvas-sm.offcanvas-start{top:0;left:0;width:var(--bs-offcanvas-width);border-right:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateX(-100%)}.offcanvas-sm.offcanvas-end{top:0;right:0;width:var(--bs-offcanvas-width);border-left:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateX(100%)}.offcanvas-sm.offcanvas-top{top:0;right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-bottom:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(-100%)}.offcanvas-sm.offcanvas-bottom{right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-top:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(100%)}.offcanvas-sm.show:not(.hiding),.offcanvas-sm.showing{transform:none}.offcanvas-sm.hiding,.offcanvas-sm.show,.offcanvas-sm.showing{visibility:visible}}@media (min-width:576px){.offcanvas-sm{--bs-offcanvas-height:auto;--bs-offcanvas-border-width:0;background-color:transparent!important}.offcanvas-sm .offcanvas-header{display:none}.offcanvas-sm .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible;background-color:transparent!important}}@media (max-width:767.98px){.offcanvas-md{position:fixed;bottom:0;z-index:var(--bs-offcanvas-zindex);display:flex;flex-direction:column;max-width:100%;color:var(--bs-offcanvas-color);visibility:hidden;background-color:var(--bs-offcanvas-bg);background-clip:padding-box;outline:0;transition:var(--bs-offcanvas-transition)}}@media (max-width:767.98px) and (prefers-reduced-motion:reduce){.offcanvas-md{transition:none}}@media (max-width:767.98px){.offcanvas-md.offcanvas-start{top:0;left:0;width:var(--bs-offcanvas-width);border-right:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateX(-100%)}.offcanvas-md.offcanvas-end{top:0;right:0;width:var(--bs-offcanvas-width);border-left:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateX(100%)}.offcanvas-md.offcanvas-top{top:0;right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-bottom:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(-100%)}.offcanvas-md.offcanvas-bottom{right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-top:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(100%)}.offcanvas-md.show:not(.hiding),.offcanvas-md.showing{transform:none}.offcanvas-md.hiding,.offcanvas-md.show,.offcanvas-md.showing{visibility:visible}}@media (min-width:768px){.offcanvas-md{--bs-offcanvas-height:auto;--bs-offcanvas-border-width:0;background-color:transparent!important}.offcanvas-md .offcanvas-header{display:none}.offcanvas-md .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible;background-color:transparent!important}}@media (max-width:991.98px){.offcanvas-lg{position:fixed;bottom:0;z-index:var(--bs-offcanvas-zindex);display:flex;flex-direction:column;max-width:100%;color:var(--bs-offcanvas-color);visibility:hidden;background-color:var(--bs-offcanvas-bg);background-clip:padding-box;outline:0;transition:var(--bs-offcanvas-transition)}}@media (max-width:991.98px) and (prefers-reduced-motion:reduce){.offcanvas-lg{transition:none}}@media (max-width:991.98px){.offcanvas-lg.offcanvas-start{top:0;left:0;width:var(--bs-offcanvas-width);border-right:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateX(-100%)}.offcanvas-lg.offcanvas-end{top:0;right:0;width:var(--bs-offcanvas-width);border-left:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateX(100%)}.offcanvas-lg.offcanvas-top{top:0;right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-bottom:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(-100%)}.offcanvas-lg.offcanvas-bottom{right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-top:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(100%)}.offcanvas-lg.show:not(.hiding),.offcanvas-lg.showing{transform:none}.offcanvas-lg.hiding,.offcanvas-lg.show,.offcanvas-lg.showing{visibility:visible}}@media (min-width:992px){.offcanvas-lg{--bs-offcanvas-height:auto;--bs-offcanvas-border-width:0;background-color:transparent!important}.offcanvas-lg .offcanvas-header{display:none}.offcanvas-lg .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible;background-color:transparent!important}}@media (max-width:1199.98px){.offcanvas-xl{position:fixed;bottom:0;z-index:var(--bs-offcanvas-zindex);display:flex;flex-direction:column;max-width:100%;color:var(--bs-offcanvas-color);visibility:hidden;background-color:var(--bs-offcanvas-bg);background-clip:padding-box;outline:0;transition:var(--bs-offcanvas-transition)}}@media (max-width:1199.98px) and (prefers-reduced-motion:reduce){.offcanvas-xl{transition:none}}@media (max-width:1199.98px){.offcanvas-xl.offcanvas-start{top:0;left:0;width:var(--bs-offcanvas-width);border-right:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateX(-100%)}.offcanvas-xl.offcanvas-end{top:0;right:0;width:var(--bs-offcanvas-width);border-left:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateX(100%)}.offcanvas-xl.offcanvas-top{top:0;right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-bottom:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(-100%)}.offcanvas-xl.offcanvas-bottom{right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-top:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(100%)}.offcanvas-xl.show:not(.hiding),.offcanvas-xl.showing{transform:none}.offcanvas-xl.hiding,.offcanvas-xl.show,.offcanvas-xl.showing{visibility:visible}}@media (min-width:1200px){.offcanvas-xl{--bs-offcanvas-height:auto;--bs-offcanvas-border-width:0;background-color:transparent!important}.offcanvas-xl .offcanvas-header{display:none}.offcanvas-xl .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible;background-color:transparent!important}}@media (max-width:1399.98px){.offcanvas-xxl{position:fixed;bottom:0;z-index:var(--bs-offcanvas-zindex);display:flex;flex-direction:column;max-width:100%;color:var(--bs-offcanvas-color);visibility:hidden;background-color:var(--bs-offcanvas-bg);background-clip:padding-box;outline:0;transition:var(--bs-offcanvas-transition)}}@media (max-width:1399.98px) and (prefers-reduced-motion:reduce){.offcanvas-xxl{transition:none}}@media (max-width:1399.98px){.offcanvas-xxl.offcanvas-start{top:0;left:0;width:var(--bs-offcanvas-width);border-right:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateX(-100%)}.offcanvas-xxl.offcanvas-end{top:0;right:0;width:var(--bs-offcanvas-width);border-left:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateX(100%)}.offcanvas-xxl.offcanvas-top{top:0;right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-bottom:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(-100%)}.offcanvas-xxl.offcanvas-bottom{right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-top:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(100%)}.offcanvas-xxl.show:not(.hiding),.offcanvas-xxl.showing{transform:none}.offcanvas-xxl.hiding,.offcanvas-xxl.show,.offcanvas-xxl.showing{visibility:visible}}@media (min-width:1400px){.offcanvas-xxl{--bs-offcanvas-height:auto;--bs-offcanvas-border-width:0;background-color:transparent!important}.offcanvas-xxl .offcanvas-header{display:none}.offcanvas-xxl .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible;background-color:transparent!important}}.offcanvas{position:fixed;bottom:0;z-index:var(--bs-offcanvas-zindex);display:flex;flex-direction:column;max-width:100%;color:var(--bs-offcanvas-color);visibility:hidden;background-color:var(--bs-offcanvas-bg);background-clip:padding-box;outline:0;transition:var(--bs-offcanvas-transition)}@media (prefers-reduced-motion:reduce){.offcanvas{transition:none}}.offcanvas.offcanvas-start{top:0;left:0;width:var(--bs-offcanvas-width);border-right:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateX(-100%)}.offcanvas.offcanvas-end{top:0;right:0;width:var(--bs-offcanvas-width);border-left:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateX(100%)}.offcanvas.offcanvas-top{top:0;right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-bottom:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(-100%)}.offcanvas.offcanvas-bottom{right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-top:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(100%)}.offcanvas.show:not(.hiding),.offcanvas.showing{transform:none}.offcanvas.hiding,.offcanvas.show,.offcanvas.showing{visibility:visible}.offcanvas-backdrop{position:fixed;top:0;left:0;z-index:1040;width:100vw;height:100vh;background-color:#000}.offcanvas-backdrop.fade{opacity:0}.offcanvas-backdrop.show{opacity:.5}.offcanvas-header{display:flex;align-items:center;padding:var(--bs-offcanvas-padding-y) var(--bs-offcanvas-padding-x)}.offcanvas-header .btn-close{padding:calc(var(--bs-offcanvas-padding-y) * .5) calc(var(--bs-offcanvas-padding-x) * .5);margin-top:calc(-.5 * var(--bs-offcanvas-padding-y));margin-right:calc(-.5 * var(--bs-offcanvas-padding-x));margin-bottom:calc(-.5 * var(--bs-offcanvas-padding-y));margin-left:auto}.offcanvas-title{margin-bottom:0;line-height:var(--bs-offcanvas-title-line-height)}.offcanvas-body{flex-grow:1;padding:var(--bs-offcanvas-padding-y) var(--bs-offcanvas-padding-x);overflow-y:auto}.placeholder{display:inline-block;min-height:1em;vertical-align:middle;cursor:wait;background-color:currentcolor;opacity:.5}.placeholder.btn::before{display:inline-block;content:""}.placeholder-xs{min-height:.6em}.placeholder-sm{min-height:.8em}.placeholder-lg{min-height:1.2em}.placeholder-glow .placeholder{animation:placeholder-glow 2s ease-in-out infinite}@keyframes placeholder-glow{50%{opacity:.2}}.placeholder-wave{-webkit-mask-image:linear-gradient(130deg,#000 55%,rgba(0,0,0,0.8) 75%,#000 95%);mask-image:linear-gradient(130deg,#000 55%,rgba(0,0,0,0.8) 75%,#000 95%);-webkit-mask-size:200% 100%;mask-size:200% 100%;animation:placeholder-wave 2s linear infinite}@keyframes placeholder-wave{100%{-webkit-mask-position:-200% 0%;mask-position:-200% 0%}}.clearfix::after{display:block;clear:both;content:""}.text-bg-primary{color:#fff!important;background-color:RGBA(var(--bs-primary-rgb),var(--bs-bg-opacity,1))!important}.text-bg-secondary{color:#fff!important;background-color:RGBA(var(--bs-secondary-rgb),var(--bs-bg-opacity,1))!important}.text-bg-success{color:#fff!important;background-color:RGBA(var(--bs-success-rgb),var(--bs-bg-opacity,1))!important}.text-bg-info{color:#000!important;background-color:RGBA(var(--bs-info-rgb),var(--bs-bg-opacity,1))!important}.text-bg-warning{color:#000!important;background-color:RGBA(var(--bs-warning-rgb),var(--bs-bg-opacity,1))!important}.text-bg-danger{color:#fff!important;background-color:RGBA(var(--bs-danger-rgb),var(--bs-bg-opacity,1))!important}.text-bg-light{color:#000!important;background-color:RGBA(var(--bs-light-rgb),var(--bs-bg-opacity,1))!important}.text-bg-dark{color:#fff!important;background-color:RGBA(var(--bs-dark-rgb),var(--bs-bg-opacity,1))!important}.link-primary{color:RGBA(var(--bs-primary-rgb),var(--bs-link-opacity,1))!important;-webkit-text-decoration-color:RGBA(var(--bs-primary-rgb),var(--bs-link-underline-opacity,1))!important;text-decoration-color:RGBA(var(--bs-primary-rgb),var(--bs-link-underline-opacity,1))!important}.link-primary:focus,.link-primary:hover{color:RGBA(10,88,202,var(--bs-link-opacity,1))!important;-webkit-text-decoration-color:RGBA(10,88,202,var(--bs-link-underline-opacity,1))!important;text-decoration-color:RGBA(10,88,202,var(--bs-link-underline-opacity,1))!important}.link-secondary{color:RGBA(var(--bs-secondary-rgb),var(--bs-link-opacity,1))!important;-webkit-text-decoration-color:RGBA(var(--bs-secondary-rgb),var(--bs-link-underline-opacity,1))!important;text-decoration-color:RGBA(var(--bs-secondary-rgb),var(--bs-link-underline-opacity,1))!important}.link-secondary:focus,.link-secondary:hover{color:RGBA(86,94,100,var(--bs-link-opacity,1))!important;-webkit-text-decoration-color:RGBA(86,94,100,var(--bs-link-underline-opacity,1))!important;text-decoration-color:RGBA(86,94,100,var(--bs-link-underline-opacity,1))!important}.link-success{color:RGBA(var(--bs-success-rgb),var(--bs-link-opacity,1))!important;-webkit-text-decoration-color:RGBA(var(--bs-success-rgb),var(--bs-link-underline-opacity,1))!important;text-decoration-color:RGBA(var(--bs-success-rgb),var(--bs-link-underline-opacity,1))!important}.link-success:focus,.link-success:hover{color:RGBA(20,108,67,var(--bs-link-opacity,1))!important;-webkit-text-decoration-color:RGBA(20,108,67,var(--bs-link-underline-opacity,1))!important;text-decoration-color:RGBA(20,108,67,var(--bs-link-underline-opacity,1))!important}.link-info{color:RGBA(var(--bs-info-rgb),var(--bs-link-opacity,1))!important;-webkit-text-decoration-color:RGBA(var(--bs-info-rgb),var(--bs-link-underline-opacity,1))!important;text-decoration-color:RGBA(var(--bs-info-rgb),var(--bs-link-underline-opacity,1))!important}.link-info:focus,.link-info:hover{color:RGBA(61,213,243,var(--bs-link-opacity,1))!important;-webkit-text-decoration-color:RGBA(61,213,243,var(--bs-link-underline-opacity,1))!important;text-decoration-color:RGBA(61,213,243,var(--bs-link-underline-opacity,1))!important}.link-warning{color:RGBA(var(--bs-warning-rgb),var(--bs-link-opacity,1))!important;-webkit-text-decoration-color:RGBA(var(--bs-warning-rgb),var(--bs-link-underline-opacity,1))!important;text-decoration-color:RGBA(var(--bs-warning-rgb),var(--bs-link-underline-opacity,1))!important}.link-warning:focus,.link-warning:hover{color:RGBA(255,205,57,var(--bs-link-opacity,1))!important;-webkit-text-decoration-color:RGBA(255,205,57,var(--bs-link-underline-opacity,1))!important;text-decoration-color:RGBA(255,205,57,var(--bs-link-underline-opacity,1))!important}.link-danger{color:RGBA(var(--bs-danger-rgb),var(--bs-link-opacity,1))!important;-webkit-text-decoration-color:RGBA(var(--bs-danger-rgb),var(--bs-link-underline-opacity,1))!important;text-decoration-color:RGBA(var(--bs-danger-rgb),var(--bs-link-underline-opacity,1))!important}.link-danger:focus,.link-danger:hover{color:RGBA(176,42,55,var(--bs-link-opacity,1))!important;-webkit-text-decoration-color:RGBA(176,42,55,var(--bs-link-underline-opacity,1))!important;text-decoration-color:RGBA(176,42,55,var(--bs-link-underline-opacity,1))!important}.link-light{color:RGBA(var(--bs-light-rgb),var(--bs-link-opacity,1))!important;-webkit-text-decoration-color:RGBA(var(--bs-light-rgb),var(--bs-link-underline-opacity,1))!important;text-decoration-color:RGBA(var(--bs-light-rgb),var(--bs-link-underline-opacity,1))!important}.link-light:focus,.link-light:hover{color:RGBA(249,250,251,var(--bs-link-opacity,1))!important;-webkit-text-decoration-color:RGBA(249,250,251,var(--bs-link-underline-opacity,1))!important;text-decoration-color:RGBA(249,250,251,var(--bs-link-underline-opacity,1))!important}.link-dark{color:RGBA(var(--bs-dark-rgb),var(--bs-link-opacity,1))!important;-webkit-text-decoration-color:RGBA(var(--bs-dark-rgb),var(--bs-link-underline-opacity,1))!important;text-decoration-color:RGBA(var(--bs-dark-rgb),var(--bs-link-underline-opacity,1))!important}.link-dark:focus,.link-dark:hover{color:RGBA(26,30,33,var(--bs-link-opacity,1))!important;-webkit-text-decoration-color:RGBA(26,30,33,var(--bs-link-underline-opacity,1))!important;text-decoration-color:RGBA(26,30,33,var(--bs-link-underline-opacity,1))!important}.link-body-emphasis{color:RGBA(var(--bs-emphasis-color-rgb),var(--bs-link-opacity,1))!important;-webkit-text-decoration-color:RGBA(var(--bs-emphasis-color-rgb),var(--bs-link-underline-opacity,1))!important;text-decoration-color:RGBA(var(--bs-emphasis-color-rgb),var(--bs-link-underline-opacity,1))!important}.link-body-emphasis:focus,.link-body-emphasis:hover{color:RGBA(var(--bs-emphasis-color-rgb),var(--bs-link-opacity,.75))!important;-webkit-text-decoration-color:RGBA(var(--bs-emphasis-color-rgb),var(--bs-link-underline-opacity,0.75))!important;text-decoration-color:RGBA(var(--bs-emphasis-color-rgb),var(--bs-link-underline-opacity,0.75))!important}.focus-ring:focus{outline:0;box-shadow:var(--bs-focus-ring-x,0) var(--bs-focus-ring-y,0) var(--bs-focus-ring-blur,0) var(--bs-focus-ring-width) var(--bs-focus-ring-color)}.icon-link{display:inline-flex;gap:.375rem;align-items:center;-webkit-text-decoration-color:rgba(var(--bs-link-color-rgb),var(--bs-link-opacity,0.5));text-decoration-color:rgba(var(--bs-link-color-rgb),var(--bs-link-opacity,0.5));text-underline-offset:0.25em;-webkit-backface-visibility:hidden;backface-visibility:hidden}.icon-link>.bi{flex-shrink:0;width:1em;height:1em;fill:currentcolor;transition:.2s ease-in-out transform}@media (prefers-reduced-motion:reduce){.icon-link>.bi{transition:none}}.icon-link-hover:focus-visible>.bi,.icon-link-hover:hover>.bi{transform:var(--bs-icon-link-transform,translate3d(.25em,0,0))}.ratio{position:relative;width:100%}.ratio::before{display:block;padding-top:var(--bs-aspect-ratio);content:""}.ratio>*{position:absolute;top:0;left:0;width:100%;height:100%}.ratio-1x1{--bs-aspect-ratio:100%}.ratio-4x3{--bs-aspect-ratio:75%}.ratio-16x9{--bs-aspect-ratio:56.25%}.ratio-21x9{--bs-aspect-ratio:42.8571428571%}.fixed-top{position:fixed;top:0;right:0;left:0;z-index:1030}.fixed-bottom{position:fixed;right:0;bottom:0;left:0;z-index:1030}.sticky-top{position:-webkit-sticky;position:sticky;top:0;z-index:1020}.sticky-bottom{position:-webkit-sticky;position:sticky;bottom:0;z-index:1020}@media (min-width:576px){.sticky-sm-top{position:-webkit-sticky;position:sticky;top:0;z-index:1020}.sticky-sm-bottom{position:-webkit-sticky;position:sticky;bottom:0;z-index:1020}}@media (min-width:768px){.sticky-md-top{position:-webkit-sticky;position:sticky;top:0;z-index:1020}.sticky-md-bottom{position:-webkit-sticky;position:sticky;bottom:0;z-index:1020}}@media (min-width:992px){.sticky-lg-top{position:-webkit-sticky;position:sticky;top:0;z-index:1020}.sticky-lg-bottom{position:-webkit-sticky;position:sticky;bottom:0;z-index:1020}}@media (min-width:1200px){.sticky-xl-top{position:-webkit-sticky;position:sticky;top:0;z-index:1020}.sticky-xl-bottom{position:-webkit-sticky;position:sticky;bottom:0;z-index:1020}}@media (min-width:1400px){.sticky-xxl-top{position:-webkit-sticky;position:sticky;top:0;z-index:1020}.sticky-xxl-bottom{position:-webkit-sticky;position:sticky;bottom:0;z-index:1020}}.hstack{display:flex;flex-direction:row;align-items:center;align-self:stretch}.vstack{display:flex;flex:1 1 auto;flex-direction:column;align-self:stretch}.visually-hidden,.visually-hidden-focusable:not(:focus):not(:focus-within){width:1px!important;height:1px!important;padding:0!important;margin:-1px!important;overflow:hidden!important;clip:rect(0,0,0,0)!important;white-space:nowrap!important;border:0!important}.visually-hidden-focusable:not(:focus):not(:focus-within):not(caption),.visually-hidden:not(caption){position:absolute!important}.visually-hidden *,.visually-hidden-focusable:not(:focus):not(:focus-within) *{overflow:hidden!important}.stretched-link::after{position:absolute;top:0;right:0;bottom:0;left:0;z-index:1;content:""}.text-truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.vr{display:inline-block;align-self:stretch;width:var(--bs-border-width);min-height:1em;background-color:currentcolor;opacity:.25}.align-baseline{vertical-align:baseline!important}.align-top{vertical-align:top!important}.align-middle{vertical-align:middle!important}.align-bottom{vertical-align:bottom!important}.align-text-bottom{vertical-align:text-bottom!important}.align-text-top{vertical-align:text-top!important}.float-start{float:left!important}.float-end{float:right!important}.float-none{float:none!important}.object-fit-contain{-o-object-fit:contain!important;object-fit:contain!important}.object-fit-cover{-o-object-fit:cover!important;object-fit:cover!important}.object-fit-fill{-o-object-fit:fill!important;object-fit:fill!important}.object-fit-scale{-o-object-fit:scale-down!important;object-fit:scale-down!important}.object-fit-none{-o-object-fit:none!important;object-fit:none!important}.opacity-0{opacity:0!important}.opacity-25{opacity:.25!important}.opacity-50{opacity:.5!important}.opacity-75{opacity:.75!important}.opacity-100{opacity:1!important}.overflow-auto{overflow:auto!important}.overflow-hidden{overflow:hidden!important}.overflow-visible{overflow:visible!important}.overflow-scroll{overflow:scroll!important}.overflow-x-auto{overflow-x:auto!important}.overflow-x-hidden{overflow-x:hidden!important}.overflow-x-visible{overflow-x:visible!important}.overflow-x-scroll{overflow-x:scroll!important}.overflow-y-auto{overflow-y:auto!important}.overflow-y-hidden{overflow-y:hidden!important}.overflow-y-visible{overflow-y:visible!important}.overflow-y-scroll{overflow-y:scroll!important}.d-inline{display:inline!important}.d-inline-block{display:inline-block!important}.d-block{display:block!important}.d-grid{display:grid!important}.d-inline-grid{display:inline-grid!important}.d-table{display:table!important}.d-table-row{display:table-row!important}.d-table-cell{display:table-cell!important}.d-flex{display:flex!important}.d-inline-flex{display:inline-flex!important}.d-none{display:none!important}.shadow{box-shadow:var(--bs-box-shadow)!important}.shadow-sm{box-shadow:var(--bs-box-shadow-sm)!important}.shadow-lg{box-shadow:var(--bs-box-shadow-lg)!important}.shadow-none{box-shadow:none!important}.focus-ring-primary{--bs-focus-ring-color:rgba(var(--bs-primary-rgb), var(--bs-focus-ring-opacity))}.focus-ring-secondary{--bs-focus-ring-color:rgba(var(--bs-secondary-rgb), var(--bs-focus-ring-opacity))}.focus-ring-success{--bs-focus-ring-color:rgba(var(--bs-success-rgb), var(--bs-focus-ring-opacity))}.focus-ring-info{--bs-focus-ring-color:rgba(var(--bs-info-rgb), var(--bs-focus-ring-opacity))}.focus-ring-warning{--bs-focus-ring-color:rgba(var(--bs-warning-rgb), var(--bs-focus-ring-opacity))}.focus-ring-danger{--bs-focus-ring-color:rgba(var(--bs-danger-rgb), var(--bs-focus-ring-opacity))}.focus-ring-light{--bs-focus-ring-color:rgba(var(--bs-light-rgb), var(--bs-focus-ring-opacity))}.focus-ring-dark{--bs-focus-ring-color:rgba(var(--bs-dark-rgb), var(--bs-focus-ring-opacity))}.position-static{position:static!important}.position-relative{position:relative!important}.position-absolute{position:absolute!important}.position-fixed{position:fixed!important}.position-sticky{position:-webkit-sticky!important;position:sticky!important}.top-0{top:0!important}.top-50{top:50%!important}.top-100{top:100%!important}.bottom-0{bottom:0!important}.bottom-50{bottom:50%!important}.bottom-100{bottom:100%!important}.start-0{left:0!important}.start-50{left:50%!important}.start-100{left:100%!important}.end-0{right:0!important}.end-50{right:50%!important}.end-100{right:100%!important}.translate-middle{transform:translate(-50%,-50%)!important}.translate-middle-x{transform:translateX(-50%)!important}.translate-middle-y{transform:translateY(-50%)!important}.border{border:var(--bs-border-width) var(--bs-border-style) var(--bs-border-color)!important}.border-0{border:0!important}.border-top{border-top:var(--bs-border-width) var(--bs-border-style) var(--bs-border-color)!important}.border-top-0{border-top:0!important}.border-end{border-right:var(--bs-border-width) var(--bs-border-style) var(--bs-border-color)!important}.border-end-0{border-right:0!important}.border-bottom{border-bottom:var(--bs-border-width) var(--bs-border-style) var(--bs-border-color)!important}.border-bottom-0{border-bottom:0!important}.border-start{border-left:var(--bs-border-width) var(--bs-border-style) var(--bs-border-color)!important}.border-start-0{border-left:0!important}.border-primary{--bs-border-opacity:1;border-color:rgba(var(--bs-primary-rgb),var(--bs-border-opacity))!important}.border-secondary{--bs-border-opacity:1;border-color:rgba(var(--bs-secondary-rgb),var(--bs-border-opacity))!important}.border-success{--bs-border-opacity:1;border-color:rgba(var(--bs-success-rgb),var(--bs-border-opacity))!important}.border-info{--bs-border-opacity:1;border-color:rgba(var(--bs-info-rgb),var(--bs-border-opacity))!important}.border-warning{--bs-border-opacity:1;border-color:rgba(var(--bs-warning-rgb),var(--bs-border-opacity))!important}.border-danger{--bs-border-opacity:1;border-color:rgba(var(--bs-danger-rgb),var(--bs-border-opacity))!important}.border-light{--bs-border-opacity:1;border-color:rgba(var(--bs-light-rgb),var(--bs-border-opacity))!important}.border-dark{--bs-border-opacity:1;border-color:rgba(var(--bs-dark-rgb),var(--bs-border-opacity))!important}.border-black{--bs-border-opacity:1;border-color:rgba(var(--bs-black-rgb),var(--bs-border-opacity))!important}.border-white{--bs-border-opacity:1;border-color:rgba(var(--bs-white-rgb),var(--bs-border-opacity))!important}.border-primary-subtle{border-color:var(--bs-primary-border-subtle)!important}.border-secondary-subtle{border-color:var(--bs-secondary-border-subtle)!important}.border-success-subtle{border-color:var(--bs-success-border-subtle)!important}.border-info-subtle{border-color:var(--bs-info-border-subtle)!important}.border-warning-subtle{border-color:var(--bs-warning-border-subtle)!important}.border-danger-subtle{border-color:var(--bs-danger-border-subtle)!important}.border-light-subtle{border-color:var(--bs-light-border-subtle)!important}.border-dark-subtle{border-color:var(--bs-dark-border-subtle)!important}.border-1{border-width:1px!important}.border-2{border-width:2px!important}.border-3{border-width:3px!important}.border-4{border-width:4px!important}.border-5{border-width:5px!important}.border-opacity-10{--bs-border-opacity:0.1}.border-opacity-25{--bs-border-opacity:0.25}.border-opacity-50{--bs-border-opacity:0.5}.border-opacity-75{--bs-border-opacity:0.75}.border-opacity-100{--bs-border-opacity:1}.w-25{width:25%!important}.w-50{width:50%!important}.w-75{width:75%!important}.w-100{width:100%!important}.w-auto{width:auto!important}.mw-100{max-width:100%!important}.vw-100{width:100vw!important}.min-vw-100{min-width:100vw!important}.h-25{height:25%!important}.h-50{height:50%!important}.h-75{height:75%!important}.h-100{height:100%!important}.h-auto{height:auto!important}.mh-100{max-height:100%!important}.vh-100{height:100vh!important}.min-vh-100{min-height:100vh!important}.flex-fill{flex:1 1 auto!important}.flex-row{flex-direction:row!important}.flex-column{flex-direction:column!important}.flex-row-reverse{flex-direction:row-reverse!important}.flex-column-reverse{flex-direction:column-reverse!important}.flex-grow-0{flex-grow:0!important}.flex-grow-1{flex-grow:1!important}.flex-shrink-0{flex-shrink:0!important}.flex-shrink-1{flex-shrink:1!important}.flex-wrap{flex-wrap:wrap!important}.flex-nowrap{flex-wrap:nowrap!important}.flex-wrap-reverse{flex-wrap:wrap-reverse!important}.justify-content-start{justify-content:flex-start!important}.justify-content-end{justify-content:flex-end!important}.justify-content-center{justify-content:center!important}.justify-content-between{justify-content:space-between!important}.justify-content-around{justify-content:space-around!important}.justify-content-evenly{justify-content:space-evenly!important}.align-items-start{align-items:flex-start!important}.align-items-end{align-items:flex-end!important}.align-items-center{align-items:center!important}.align-items-baseline{align-items:baseline!important}.align-items-stretch{align-items:stretch!important}.align-content-start{align-content:flex-start!important}.align-content-end{align-content:flex-end!important}.align-content-center{align-content:center!important}.align-content-between{align-content:space-between!important}.align-content-around{align-content:space-around!important}.align-content-stretch{align-content:stretch!important}.align-self-auto{align-self:auto!important}.align-self-start{align-self:flex-start!important}.align-self-end{align-self:flex-end!important}.align-self-center{align-self:center!important}.align-self-baseline{align-self:baseline!important}.align-self-stretch{align-self:stretch!important}.order-first{order:-1!important}.order-0{order:0!important}.order-1{order:1!important}.order-2{order:2!important}.order-3{order:3!important}.order-4{order:4!important}.order-5{order:5!important}.order-last{order:6!important}.m-0{margin:0!important}.m-1{margin:.25rem!important}.m-2{margin:.5rem!important}.m-3{margin:1rem!important}.m-4{margin:1.5rem!important}.m-5{margin:3rem!important}.m-auto{margin:auto!important}.mx-0{margin-right:0!important;margin-left:0!important}.mx-1{margin-right:.25rem!important;margin-left:.25rem!important}.mx-2{margin-right:.5rem!important;margin-left:.5rem!important}.mx-3{margin-right:1rem!important;margin-left:1rem!important}.mx-4{margin-right:1.5rem!important;margin-left:1.5rem!important}.mx-5{margin-right:3rem!important;margin-left:3rem!important}.mx-auto{margin-right:auto!important;margin-left:auto!important}.my-0{margin-top:0!important;margin-bottom:0!important}.my-1{margin-top:.25rem!important;margin-bottom:.25rem!important}.my-2{margin-top:.5rem!important;margin-bottom:.5rem!important}.my-3{margin-top:1rem!important;margin-bottom:1rem!important}.my-4{margin-top:1.5rem!important;margin-bottom:1.5rem!important}.my-5{margin-top:3rem!important;margin-bottom:3rem!important}.my-auto{margin-top:auto!important;margin-bottom:auto!important}.mt-0{margin-top:0!important}.mt-1{margin-top:.25rem!important}.mt-2{margin-top:.5rem!important}.mt-3{margin-top:1rem!important}.mt-4{margin-top:1.5rem!important}.mt-5{margin-top:3rem!important}.mt-auto{margin-top:auto!important}.me-0{margin-right:0!important}.me-1{margin-right:.25rem!important}.me-2{margin-right:.5rem!important}.me-3{margin-right:1rem!important}.me-4{margin-right:1.5rem!important}.me-5{margin-right:3rem!important}.me-auto{margin-right:auto!important}.mb-0{margin-bottom:0!important}.mb-1{margin-bottom:.25rem!important}.mb-2{margin-bottom:.5rem!important}.mb-3{margin-bottom:1rem!important}.mb-4{margin-bottom:1.5rem!important}.mb-5{margin-bottom:3rem!important}.mb-auto{margin-bottom:auto!important}.ms-0{margin-left:0!important}.ms-1{margin-left:.25rem!important}.ms-2{margin-left:.5rem!important}.ms-3{margin-left:1rem!important}.ms-4{margin-left:1.5rem!important}.ms-5{margin-left:3rem!important}.ms-auto{margin-left:auto!important}.p-0{padding:0!important}.p-1{padding:.25rem!important}.p-2{padding:.5rem!important}.p-3{padding:1rem!important}.p-4{padding:1.5rem!important}.p-5{padding:3rem!important}.px-0{padding-right:0!important;padding-left:0!important}.px-1{padding-right:.25rem!important;padding-left:.25rem!important}.px-2{padding-right:.5rem!important;padding-left:.5rem!important}.px-3{padding-right:1rem!important;padding-left:1rem!important}.px-4{padding-right:1.5rem!important;padding-left:1.5rem!important}.px-5{padding-right:3rem!important;padding-left:3rem!important}.py-0{padding-top:0!important;padding-bottom:0!important}.py-1{padding-top:.25rem!important;padding-bottom:.25rem!important}.py-2{padding-top:.5rem!important;padding-bottom:.5rem!important}.py-3{padding-top:1rem!important;padding-bottom:1rem!important}.py-4{padding-top:1.5rem!important;padding-bottom:1.5rem!important}.py-5{padding-top:3rem!important;padding-bottom:3rem!important}.pt-0{padding-top:0!important}.pt-1{padding-top:.25rem!important}.pt-2{padding-top:.5rem!important}.pt-3{padding-top:1rem!important}.pt-4{padding-top:1.5rem!important}.pt-5{padding-top:3rem!important}.pe-0{padding-right:0!important}.pe-1{padding-right:.25rem!important}.pe-2{padding-right:.5rem!important}.pe-3{padding-right:1rem!important}.pe-4{padding-right:1.5rem!important}.pe-5{padding-right:3rem!important}.pb-0{padding-bottom:0!important}.pb-1{padding-bottom:.25rem!important}.pb-2{padding-bottom:.5rem!important}.pb-3{padding-bottom:1rem!important}.pb-4{padding-bottom:1.5rem!important}.pb-5{padding-bottom:3rem!important}.ps-0{padding-left:0!important}.ps-1{padding-left:.25rem!important}.ps-2{padding-left:.5rem!important}.ps-3{padding-left:1rem!important}.ps-4{padding-left:1.5rem!important}.ps-5{padding-left:3rem!important}.gap-0{gap:0!important}.gap-1{gap:.25rem!important}.gap-2{gap:.5rem!important}.gap-3{gap:1rem!important}.gap-4{gap:1.5rem!important}.gap-5{gap:3rem!important}.row-gap-0{row-gap:0!important}.row-gap-1{row-gap:.25rem!important}.row-gap-2{row-gap:.5rem!important}.row-gap-3{row-gap:1rem!important}.row-gap-4{row-gap:1.5rem!important}.row-gap-5{row-gap:3rem!important}.column-gap-0{-moz-column-gap:0!important;column-gap:0!important}.column-gap-1{-moz-column-gap:0.25rem!important;column-gap:.25rem!important}.column-gap-2{-moz-column-gap:0.5rem!important;column-gap:.5rem!important}.column-gap-3{-moz-column-gap:1rem!important;column-gap:1rem!important}.column-gap-4{-moz-column-gap:1.5rem!important;column-gap:1.5rem!important}.column-gap-5{-moz-column-gap:3rem!important;column-gap:3rem!important}.font-monospace{font-family:var(--bs-font-monospace)!important}.fs-1{font-size:calc(1.375rem + 1.5vw)!important}.fs-2{font-size:calc(1.325rem + .9vw)!important}.fs-3{font-size:calc(1.3rem + .6vw)!important}.fs-4{font-size:calc(1.275rem + .3vw)!important}.fs-5{font-size:1.25rem!important}.fs-6{font-size:1rem!important}.fst-italic{font-style:italic!important}.fst-normal{font-style:normal!important}.fw-lighter{font-weight:lighter!important}.fw-light{font-weight:300!important}.fw-normal{font-weight:400!important}.fw-medium{font-weight:500!important}.fw-semibold{font-weight:600!important}.fw-bold{font-weight:700!important}.fw-bolder{font-weight:bolder!important}.lh-1{line-height:1!important}.lh-sm{line-height:1.25!important}.lh-base{line-height:1.5!important}.lh-lg{line-height:2!important}.text-start{text-align:left!important}.text-end{text-align:right!important}.text-center{text-align:center!important}.text-decoration-none{text-decoration:none!important}.text-decoration-underline{text-decoration:underline!important}.text-decoration-line-through{text-decoration:line-through!important}.text-lowercase{text-transform:lowercase!important}.text-uppercase{text-transform:uppercase!important}.text-capitalize{text-transform:capitalize!important}.text-wrap{white-space:normal!important}.text-nowrap{white-space:nowrap!important}.text-break{word-wrap:break-word!important;word-break:break-word!important}.text-primary{--bs-text-opacity:1;color:rgba(var(--bs-primary-rgb),var(--bs-text-opacity))!important}.text-secondary{--bs-text-opacity:1;color:rgba(var(--bs-secondary-rgb),var(--bs-text-opacity))!important}.text-success{--bs-text-opacity:1;color:rgba(var(--bs-success-rgb),var(--bs-text-opacity))!important}.text-info{--bs-text-opacity:1;color:rgba(var(--bs-info-rgb),var(--bs-text-opacity))!important}.text-warning{--bs-text-opacity:1;color:rgba(var(--bs-warning-rgb),var(--bs-text-opacity))!important}.text-danger{--bs-text-opacity:1;color:rgba(var(--bs-danger-rgb),var(--bs-text-opacity))!important}.text-light{--bs-text-opacity:1;color:rgba(var(--bs-light-rgb),var(--bs-text-opacity))!important}.text-dark{--bs-text-opacity:1;color:rgba(var(--bs-dark-rgb),var(--bs-text-opacity))!important}.text-black{--bs-text-opacity:1;color:rgba(var(--bs-black-rgb),var(--bs-text-opacity))!important}.text-white{--bs-text-opacity:1;color:rgba(var(--bs-white-rgb),var(--bs-text-opacity))!important}.text-body{--bs-text-opacity:1;color:rgba(var(--bs-body-color-rgb),var(--bs-text-opacity))!important}.text-muted{--bs-text-opacity:1;color:var(--bs-secondary-color)!important}.text-black-50{--bs-text-opacity:1;color:rgba(0,0,0,.5)!important}.text-white-50{--bs-text-opacity:1;color:rgba(255,255,255,.5)!important}.text-body-secondary{--bs-text-opacity:1;color:var(--bs-secondary-color)!important}.text-body-tertiary{--bs-text-opacity:1;color:var(--bs-tertiary-color)!important}.text-body-emphasis{--bs-text-opacity:1;color:var(--bs-emphasis-color)!important}.text-reset{--bs-text-opacity:1;color:inherit!important}.text-opacity-25{--bs-text-opacity:0.25}.text-opacity-50{--bs-text-opacity:0.5}.text-opacity-75{--bs-text-opacity:0.75}.text-opacity-100{--bs-text-opacity:1}.text-primary-emphasis{color:var(--bs-primary-text-emphasis)!important}.text-secondary-emphasis{color:var(--bs-secondary-text-emphasis)!important}.text-success-emphasis{color:var(--bs-success-text-emphasis)!important}.text-info-emphasis{color:var(--bs-info-text-emphasis)!important}.text-warning-emphasis{color:var(--bs-warning-text-emphasis)!important}.text-danger-emphasis{color:var(--bs-danger-text-emphasis)!important}.text-light-emphasis{color:var(--bs-light-text-emphasis)!important}.text-dark-emphasis{color:var(--bs-dark-text-emphasis)!important}.link-opacity-10{--bs-link-opacity:0.1}.link-opacity-10-hover:hover{--bs-link-opacity:0.1}.link-opacity-25{--bs-link-opacity:0.25}.link-opacity-25-hover:hover{--bs-link-opacity:0.25}.link-opacity-50{--bs-link-opacity:0.5}.link-opacity-50-hover:hover{--bs-link-opacity:0.5}.link-opacity-75{--bs-link-opacity:0.75}.link-opacity-75-hover:hover{--bs-link-opacity:0.75}.link-opacity-100{--bs-link-opacity:1}.link-opacity-100-hover:hover{--bs-link-opacity:1}.link-offset-1{text-underline-offset:0.125em!important}.link-offset-1-hover:hover{text-underline-offset:0.125em!important}.link-offset-2{text-underline-offset:0.25em!important}.link-offset-2-hover:hover{text-underline-offset:0.25em!important}.link-offset-3{text-underline-offset:0.375em!important}.link-offset-3-hover:hover{text-underline-offset:0.375em!important}.link-underline-primary{--bs-link-underline-opacity:1;-webkit-text-decoration-color:rgba(var(--bs-primary-rgb),var(--bs-link-underline-opacity))!important;text-decoration-color:rgba(var(--bs-primary-rgb),var(--bs-link-underline-opacity))!important}.link-underline-secondary{--bs-link-underline-opacity:1;-webkit-text-decoration-color:rgba(var(--bs-secondary-rgb),var(--bs-link-underline-opacity))!important;text-decoration-color:rgba(var(--bs-secondary-rgb),var(--bs-link-underline-opacity))!important}.link-underline-success{--bs-link-underline-opacity:1;-webkit-text-decoration-color:rgba(var(--bs-success-rgb),var(--bs-link-underline-opacity))!important;text-decoration-color:rgba(var(--bs-success-rgb),var(--bs-link-underline-opacity))!important}.link-underline-info{--bs-link-underline-opacity:1;-webkit-text-decoration-color:rgba(var(--bs-info-rgb),var(--bs-link-underline-opacity))!important;text-decoration-color:rgba(var(--bs-info-rgb),var(--bs-link-underline-opacity))!important}.link-underline-warning{--bs-link-underline-opacity:1;-webkit-text-decoration-color:rgba(var(--bs-warning-rgb),var(--bs-link-underline-opacity))!important;text-decoration-color:rgba(var(--bs-warning-rgb),var(--bs-link-underline-opacity))!important}.link-underline-danger{--bs-link-underline-opacity:1;-webkit-text-decoration-color:rgba(var(--bs-danger-rgb),var(--bs-link-underline-opacity))!important;text-decoration-color:rgba(var(--bs-danger-rgb),var(--bs-link-underline-opacity))!important}.link-underline-light{--bs-link-underline-opacity:1;-webkit-text-decoration-color:rgba(var(--bs-light-rgb),var(--bs-link-underline-opacity))!important;text-decoration-color:rgba(var(--bs-light-rgb),var(--bs-link-underline-opacity))!important}.link-underline-dark{--bs-link-underline-opacity:1;-webkit-text-decoration-color:rgba(var(--bs-dark-rgb),var(--bs-link-underline-opacity))!important;text-decoration-color:rgba(var(--bs-dark-rgb),var(--bs-link-underline-opacity))!important}.link-underline{--bs-link-underline-opacity:1;-webkit-text-decoration-color:rgba(var(--bs-link-color-rgb),var(--bs-link-underline-opacity,1))!important;text-decoration-color:rgba(var(--bs-link-color-rgb),var(--bs-link-underline-opacity,1))!important}.link-underline-opacity-0{--bs-link-underline-opacity:0}.link-underline-opacity-0-hover:hover{--bs-link-underline-opacity:0}.link-underline-opacity-10{--bs-link-underline-opacity:0.1}.link-underline-opacity-10-hover:hover{--bs-link-underline-opacity:0.1}.link-underline-opacity-25{--bs-link-underline-opacity:0.25}.link-underline-opacity-25-hover:hover{--bs-link-underline-opacity:0.25}.link-underline-opacity-50{--bs-link-underline-opacity:0.5}.link-underline-opacity-50-hover:hover{--bs-link-underline-opacity:0.5}.link-underline-opacity-75{--bs-link-underline-opacity:0.75}.link-underline-opacity-75-hover:hover{--bs-link-underline-opacity:0.75}.link-underline-opacity-100{--bs-link-underline-opacity:1}.link-underline-opacity-100-hover:hover{--bs-link-underline-opacity:1}.bg-primary{--bs-bg-opacity:1;background-color:rgba(var(--bs-primary-rgb),var(--bs-bg-opacity))!important}.bg-secondary{--bs-bg-opacity:1;background-color:rgba(var(--bs-secondary-rgb),var(--bs-bg-opacity))!important}.bg-success{--bs-bg-opacity:1;background-color:rgba(var(--bs-success-rgb),var(--bs-bg-opacity))!important}.bg-info{--bs-bg-opacity:1;background-color:rgba(var(--bs-info-rgb),var(--bs-bg-opacity))!important}.bg-warning{--bs-bg-opacity:1;background-color:rgba(var(--bs-warning-rgb),var(--bs-bg-opacity))!important}.bg-danger{--bs-bg-opacity:1;background-color:rgba(var(--bs-danger-rgb),var(--bs-bg-opacity))!important}.bg-light{--bs-bg-opacity:1;background-color:rgba(var(--bs-light-rgb),var(--bs-bg-opacity))!important}.bg-dark{--bs-bg-opacity:1;background-color:rgba(var(--bs-dark-rgb),var(--bs-bg-opacity))!important}.bg-black{--bs-bg-opacity:1;background-color:rgba(var(--bs-black-rgb),var(--bs-bg-opacity))!important}.bg-white{--bs-bg-opacity:1;background-color:rgba(var(--bs-white-rgb),var(--bs-bg-opacity))!important}.bg-body{--bs-bg-opacity:1;background-color:rgba(var(--bs-body-bg-rgb),var(--bs-bg-opacity))!important}.bg-transparent{--bs-bg-opacity:1;background-color:transparent!important}.bg-body-secondary{--bs-bg-opacity:1;background-color:rgba(var(--bs-secondary-bg-rgb),var(--bs-bg-opacity))!important}.bg-body-tertiary{--bs-bg-opacity:1;background-color:rgba(var(--bs-tertiary-bg-rgb),var(--bs-bg-opacity))!important}.bg-opacity-10{--bs-bg-opacity:0.1}.bg-opacity-25{--bs-bg-opacity:0.25}.bg-opacity-50{--bs-bg-opacity:0.5}.bg-opacity-75{--bs-bg-opacity:0.75}.bg-opacity-100{--bs-bg-opacity:1}.bg-primary-subtle{background-color:var(--bs-primary-bg-subtle)!important}.bg-secondary-subtle{background-color:var(--bs-secondary-bg-subtle)!important}.bg-success-subtle{background-color:var(--bs-success-bg-subtle)!important}.bg-info-subtle{background-color:var(--bs-info-bg-subtle)!important}.bg-warning-subtle{background-color:var(--bs-warning-bg-subtle)!important}.bg-danger-subtle{background-color:var(--bs-danger-bg-subtle)!important}.bg-light-subtle{background-color:var(--bs-light-bg-subtle)!important}.bg-dark-subtle{background-color:var(--bs-dark-bg-subtle)!important}.bg-gradient{background-image:var(--bs-gradient)!important}.user-select-all{-webkit-user-select:all!important;-moz-user-select:all!important;user-select:all!important}.user-select-auto{-webkit-user-select:auto!important;-moz-user-select:auto!important;user-select:auto!important}.user-select-none{-webkit-user-select:none!important;-moz-user-select:none!important;user-select:none!important}.pe-none{pointer-events:none!important}.pe-auto{pointer-events:auto!important}.rounded{border-radius:var(--bs-border-radius)!important}.rounded-0{border-radius:0!important}.rounded-1{border-radius:var(--bs-border-radius-sm)!important}.rounded-2{border-radius:var(--bs-border-radius)!important}.rounded-3{border-radius:var(--bs-border-radius-lg)!important}.rounded-4{border-radius:var(--bs-border-radius-xl)!important}.rounded-5{border-radius:var(--bs-border-radius-xxl)!important}.rounded-circle{border-radius:50%!important}.rounded-pill{border-radius:var(--bs-border-radius-pill)!important}.rounded-top{border-top-left-radius:var(--bs-border-radius)!important;border-top-right-radius:var(--bs-border-radius)!important}.rounded-top-0{border-top-left-radius:0!important;border-top-right-radius:0!important}.rounded-top-1{border-top-left-radius:var(--bs-border-radius-sm)!important;border-top-right-radius:var(--bs-border-radius-sm)!important}.rounded-top-2{border-top-left-radius:var(--bs-border-radius)!important;border-top-right-radius:var(--bs-border-radius)!important}.rounded-top-3{border-top-left-radius:var(--bs-border-radius-lg)!important;border-top-right-radius:var(--bs-border-radius-lg)!important}.rounded-top-4{border-top-left-radius:var(--bs-border-radius-xl)!important;border-top-right-radius:var(--bs-border-radius-xl)!important}.rounded-top-5{border-top-left-radius:var(--bs-border-radius-xxl)!important;border-top-right-radius:var(--bs-border-radius-xxl)!important}.rounded-top-circle{border-top-left-radius:50%!important;border-top-right-radius:50%!important}.rounded-top-pill{border-top-left-radius:var(--bs-border-radius-pill)!important;border-top-right-radius:var(--bs-border-radius-pill)!important}.rounded-end{border-top-right-radius:var(--bs-border-radius)!important;border-bottom-right-radius:var(--bs-border-radius)!important}.rounded-end-0{border-top-right-radius:0!important;border-bottom-right-radius:0!important}.rounded-end-1{border-top-right-radius:var(--bs-border-radius-sm)!important;border-bottom-right-radius:var(--bs-border-radius-sm)!important}.rounded-end-2{border-top-right-radius:var(--bs-border-radius)!important;border-bottom-right-radius:var(--bs-border-radius)!important}.rounded-end-3{border-top-right-radius:var(--bs-border-radius-lg)!important;border-bottom-right-radius:var(--bs-border-radius-lg)!important}.rounded-end-4{border-top-right-radius:var(--bs-border-radius-xl)!important;border-bottom-right-radius:var(--bs-border-radius-xl)!important}.rounded-end-5{border-top-right-radius:var(--bs-border-radius-xxl)!important;border-bottom-right-radius:var(--bs-border-radius-xxl)!important}.rounded-end-circle{border-top-right-radius:50%!important;border-bottom-right-radius:50%!important}.rounded-end-pill{border-top-right-radius:var(--bs-border-radius-pill)!important;border-bottom-right-radius:var(--bs-border-radius-pill)!important}.rounded-bottom{border-bottom-right-radius:var(--bs-border-radius)!important;border-bottom-left-radius:var(--bs-border-radius)!important}.rounded-bottom-0{border-bottom-right-radius:0!important;border-bottom-left-radius:0!important}.rounded-bottom-1{border-bottom-right-radius:var(--bs-border-radius-sm)!important;border-bottom-left-radius:var(--bs-border-radius-sm)!important}.rounded-bottom-2{border-bottom-right-radius:var(--bs-border-radius)!important;border-bottom-left-radius:var(--bs-border-radius)!important}.rounded-bottom-3{border-bottom-right-radius:var(--bs-border-radius-lg)!important;border-bottom-left-radius:var(--bs-border-radius-lg)!important}.rounded-bottom-4{border-bottom-right-radius:var(--bs-border-radius-xl)!important;border-bottom-left-radius:var(--bs-border-radius-xl)!important}.rounded-bottom-5{border-bottom-right-radius:var(--bs-border-radius-xxl)!important;border-bottom-left-radius:var(--bs-border-radius-xxl)!important}.rounded-bottom-circle{border-bottom-right-radius:50%!important;border-bottom-left-radius:50%!important}.rounded-bottom-pill{border-bottom-right-radius:var(--bs-border-radius-pill)!important;border-bottom-left-radius:var(--bs-border-radius-pill)!important}.rounded-start{border-bottom-left-radius:var(--bs-border-radius)!important;border-top-left-radius:var(--bs-border-radius)!important}.rounded-start-0{border-bottom-left-radius:0!important;border-top-left-radius:0!important}.rounded-start-1{border-bottom-left-radius:var(--bs-border-radius-sm)!important;border-top-left-radius:var(--bs-border-radius-sm)!important}.rounded-start-2{border-bottom-left-radius:var(--bs-border-radius)!important;border-top-left-radius:var(--bs-border-radius)!important}.rounded-start-3{border-bottom-left-radius:var(--bs-border-radius-lg)!important;border-top-left-radius:var(--bs-border-radius-lg)!important}.rounded-start-4{border-bottom-left-radius:var(--bs-border-radius-xl)!important;border-top-left-radius:var(--bs-border-radius-xl)!important}.rounded-start-5{border-bottom-left-radius:var(--bs-border-radius-xxl)!important;border-top-left-radius:var(--bs-border-radius-xxl)!important}.rounded-start-circle{border-bottom-left-radius:50%!important;border-top-left-radius:50%!important}.rounded-start-pill{border-bottom-left-radius:var(--bs-border-radius-pill)!important;border-top-left-radius:var(--bs-border-radius-pill)!important}.visible{visibility:visible!important}.invisible{visibility:hidden!important}.z-n1{z-index:-1!important}.z-0{z-index:0!important}.z-1{z-index:1!important}.z-2{z-index:2!important}.z-3{z-index:3!important}@media (min-width:576px){.float-sm-start{float:left!important}.float-sm-end{float:right!important}.float-sm-none{float:none!important}.object-fit-sm-contain{-o-object-fit:contain!important;object-fit:contain!important}.object-fit-sm-cover{-o-object-fit:cover!important;object-fit:cover!important}.object-fit-sm-fill{-o-object-fit:fill!important;object-fit:fill!important}.object-fit-sm-scale{-o-object-fit:scale-down!important;object-fit:scale-down!important}.object-fit-sm-none{-o-object-fit:none!important;object-fit:none!important}.d-sm-inline{display:inline!important}.d-sm-inline-block{display:inline-block!important}.d-sm-block{display:block!important}.d-sm-grid{display:grid!important}.d-sm-inline-grid{display:inline-grid!important}.d-sm-table{display:table!important}.d-sm-table-row{display:table-row!important}.d-sm-table-cell{display:table-cell!important}.d-sm-flex{display:flex!important}.d-sm-inline-flex{display:inline-flex!important}.d-sm-none{display:none!important}.flex-sm-fill{flex:1 1 auto!important}.flex-sm-row{flex-direction:row!important}.flex-sm-column{flex-direction:column!important}.flex-sm-row-reverse{flex-direction:row-reverse!important}.flex-sm-column-reverse{flex-direction:column-reverse!important}.flex-sm-grow-0{flex-grow:0!important}.flex-sm-grow-1{flex-grow:1!important}.flex-sm-shrink-0{flex-shrink:0!important}.flex-sm-shrink-1{flex-shrink:1!important}.flex-sm-wrap{flex-wrap:wrap!important}.flex-sm-nowrap{flex-wrap:nowrap!important}.flex-sm-wrap-reverse{flex-wrap:wrap-reverse!important}.justify-content-sm-start{justify-content:flex-start!important}.justify-content-sm-end{justify-content:flex-end!important}.justify-content-sm-center{justify-content:center!important}.justify-content-sm-between{justify-content:space-between!important}.justify-content-sm-around{justify-content:space-around!important}.justify-content-sm-evenly{justify-content:space-evenly!important}.align-items-sm-start{align-items:flex-start!important}.align-items-sm-end{align-items:flex-end!important}.align-items-sm-center{align-items:center!important}.align-items-sm-baseline{align-items:baseline!important}.align-items-sm-stretch{align-items:stretch!important}.align-content-sm-start{align-content:flex-start!important}.align-content-sm-end{align-content:flex-end!important}.align-content-sm-center{align-content:center!important}.align-content-sm-between{align-content:space-between!important}.align-content-sm-around{align-content:space-around!important}.align-content-sm-stretch{align-content:stretch!important}.align-self-sm-auto{align-self:auto!important}.align-self-sm-start{align-self:flex-start!important}.align-self-sm-end{align-self:flex-end!important}.align-self-sm-center{align-self:center!important}.align-self-sm-baseline{align-self:baseline!important}.align-self-sm-stretch{align-self:stretch!important}.order-sm-first{order:-1!important}.order-sm-0{order:0!important}.order-sm-1{order:1!important}.order-sm-2{order:2!important}.order-sm-3{order:3!important}.order-sm-4{order:4!important}.order-sm-5{order:5!important}.order-sm-last{order:6!important}.m-sm-0{margin:0!important}.m-sm-1{margin:.25rem!important}.m-sm-2{margin:.5rem!important}.m-sm-3{margin:1rem!important}.m-sm-4{margin:1.5rem!important}.m-sm-5{margin:3rem!important}.m-sm-auto{margin:auto!important}.mx-sm-0{margin-right:0!important;margin-left:0!important}.mx-sm-1{margin-right:.25rem!important;margin-left:.25rem!important}.mx-sm-2{margin-right:.5rem!important;margin-left:.5rem!important}.mx-sm-3{margin-right:1rem!important;margin-left:1rem!important}.mx-sm-4{margin-right:1.5rem!important;margin-left:1.5rem!important}.mx-sm-5{margin-right:3rem!important;margin-left:3rem!important}.mx-sm-auto{margin-right:auto!important;margin-left:auto!important}.my-sm-0{margin-top:0!important;margin-bottom:0!important}.my-sm-1{margin-top:.25rem!important;margin-bottom:.25rem!important}.my-sm-2{margin-top:.5rem!important;margin-bottom:.5rem!important}.my-sm-3{margin-top:1rem!important;margin-bottom:1rem!important}.my-sm-4{margin-top:1.5rem!important;margin-bottom:1.5rem!important}.my-sm-5{margin-top:3rem!important;margin-bottom:3rem!important}.my-sm-auto{margin-top:auto!important;margin-bottom:auto!important}.mt-sm-0{margin-top:0!important}.mt-sm-1{margin-top:.25rem!important}.mt-sm-2{margin-top:.5rem!important}.mt-sm-3{margin-top:1rem!important}.mt-sm-4{margin-top:1.5rem!important}.mt-sm-5{margin-top:3rem!important}.mt-sm-auto{margin-top:auto!important}.me-sm-0{margin-right:0!important}.me-sm-1{margin-right:.25rem!important}.me-sm-2{margin-right:.5rem!important}.me-sm-3{margin-right:1rem!important}.me-sm-4{margin-right:1.5rem!important}.me-sm-5{margin-right:3rem!important}.me-sm-auto{margin-right:auto!important}.mb-sm-0{margin-bottom:0!important}.mb-sm-1{margin-bottom:.25rem!important}.mb-sm-2{margin-bottom:.5rem!important}.mb-sm-3{margin-bottom:1rem!important}.mb-sm-4{margin-bottom:1.5rem!important}.mb-sm-5{margin-bottom:3rem!important}.mb-sm-auto{margin-bottom:auto!important}.ms-sm-0{margin-left:0!important}.ms-sm-1{margin-left:.25rem!important}.ms-sm-2{margin-left:.5rem!important}.ms-sm-3{margin-left:1rem!important}.ms-sm-4{margin-left:1.5rem!important}.ms-sm-5{margin-left:3rem!important}.ms-sm-auto{margin-left:auto!important}.p-sm-0{padding:0!important}.p-sm-1{padding:.25rem!important}.p-sm-2{padding:.5rem!important}.p-sm-3{padding:1rem!important}.p-sm-4{padding:1.5rem!important}.p-sm-5{padding:3rem!important}.px-sm-0{padding-right:0!important;padding-left:0!important}.px-sm-1{padding-right:.25rem!important;padding-left:.25rem!important}.px-sm-2{padding-right:.5rem!important;padding-left:.5rem!important}.px-sm-3{padding-right:1rem!important;padding-left:1rem!important}.px-sm-4{padding-right:1.5rem!important;padding-left:1.5rem!important}.px-sm-5{padding-right:3rem!important;padding-left:3rem!important}.py-sm-0{padding-top:0!important;padding-bottom:0!important}.py-sm-1{padding-top:.25rem!important;padding-bottom:.25rem!important}.py-sm-2{padding-top:.5rem!important;padding-bottom:.5rem!important}.py-sm-3{padding-top:1rem!important;padding-bottom:1rem!important}.py-sm-4{padding-top:1.5rem!important;padding-bottom:1.5rem!important}.py-sm-5{padding-top:3rem!important;padding-bottom:3rem!important}.pt-sm-0{padding-top:0!important}.pt-sm-1{padding-top:.25rem!important}.pt-sm-2{padding-top:.5rem!important}.pt-sm-3{padding-top:1rem!important}.pt-sm-4{padding-top:1.5rem!important}.pt-sm-5{padding-top:3rem!important}.pe-sm-0{padding-right:0!important}.pe-sm-1{padding-right:.25rem!important}.pe-sm-2{padding-right:.5rem!important}.pe-sm-3{padding-right:1rem!important}.pe-sm-4{padding-right:1.5rem!important}.pe-sm-5{padding-right:3rem!important}.pb-sm-0{padding-bottom:0!important}.pb-sm-1{padding-bottom:.25rem!important}.pb-sm-2{padding-bottom:.5rem!important}.pb-sm-3{padding-bottom:1rem!important}.pb-sm-4{padding-bottom:1.5rem!important}.pb-sm-5{padding-bottom:3rem!important}.ps-sm-0{padding-left:0!important}.ps-sm-1{padding-left:.25rem!important}.ps-sm-2{padding-left:.5rem!important}.ps-sm-3{padding-left:1rem!important}.ps-sm-4{padding-left:1.5rem!important}.ps-sm-5{padding-left:3rem!important}.gap-sm-0{gap:0!important}.gap-sm-1{gap:.25rem!important}.gap-sm-2{gap:.5rem!important}.gap-sm-3{gap:1rem!important}.gap-sm-4{gap:1.5rem!important}.gap-sm-5{gap:3rem!important}.row-gap-sm-0{row-gap:0!important}.row-gap-sm-1{row-gap:.25rem!important}.row-gap-sm-2{row-gap:.5rem!important}.row-gap-sm-3{row-gap:1rem!important}.row-gap-sm-4{row-gap:1.5rem!important}.row-gap-sm-5{row-gap:3rem!important}.column-gap-sm-0{-moz-column-gap:0!important;column-gap:0!important}.column-gap-sm-1{-moz-column-gap:0.25rem!important;column-gap:.25rem!important}.column-gap-sm-2{-moz-column-gap:0.5rem!important;column-gap:.5rem!important}.column-gap-sm-3{-moz-column-gap:1rem!important;column-gap:1rem!important}.column-gap-sm-4{-moz-column-gap:1.5rem!important;column-gap:1.5rem!important}.column-gap-sm-5{-moz-column-gap:3rem!important;column-gap:3rem!important}.text-sm-start{text-align:left!important}.text-sm-end{text-align:right!important}.text-sm-center{text-align:center!important}}@media (min-width:768px){.float-md-start{float:left!important}.float-md-end{float:right!important}.float-md-none{float:none!important}.object-fit-md-contain{-o-object-fit:contain!important;object-fit:contain!important}.object-fit-md-cover{-o-object-fit:cover!important;object-fit:cover!important}.object-fit-md-fill{-o-object-fit:fill!important;object-fit:fill!important}.object-fit-md-scale{-o-object-fit:scale-down!important;object-fit:scale-down!important}.object-fit-md-none{-o-object-fit:none!important;object-fit:none!important}.d-md-inline{display:inline!important}.d-md-inline-block{display:inline-block!important}.d-md-block{display:block!important}.d-md-grid{display:grid!important}.d-md-inline-grid{display:inline-grid!important}.d-md-table{display:table!important}.d-md-table-row{display:table-row!important}.d-md-table-cell{display:table-cell!important}.d-md-flex{display:flex!important}.d-md-inline-flex{display:inline-flex!important}.d-md-none{display:none!important}.flex-md-fill{flex:1 1 auto!important}.flex-md-row{flex-direction:row!important}.flex-md-column{flex-direction:column!important}.flex-md-row-reverse{flex-direction:row-reverse!important}.flex-md-column-reverse{flex-direction:column-reverse!important}.flex-md-grow-0{flex-grow:0!important}.flex-md-grow-1{flex-grow:1!important}.flex-md-shrink-0{flex-shrink:0!important}.flex-md-shrink-1{flex-shrink:1!important}.flex-md-wrap{flex-wrap:wrap!important}.flex-md-nowrap{flex-wrap:nowrap!important}.flex-md-wrap-reverse{flex-wrap:wrap-reverse!important}.justify-content-md-start{justify-content:flex-start!important}.justify-content-md-end{justify-content:flex-end!important}.justify-content-md-center{justify-content:center!important}.justify-content-md-between{justify-content:space-between!important}.justify-content-md-around{justify-content:space-around!important}.justify-content-md-evenly{justify-content:space-evenly!important}.align-items-md-start{align-items:flex-start!important}.align-items-md-end{align-items:flex-end!important}.align-items-md-center{align-items:center!important}.align-items-md-baseline{align-items:baseline!important}.align-items-md-stretch{align-items:stretch!important}.align-content-md-start{align-content:flex-start!important}.align-content-md-end{align-content:flex-end!important}.align-content-md-center{align-content:center!important}.align-content-md-between{align-content:space-between!important}.align-content-md-around{align-content:space-around!important}.align-content-md-stretch{align-content:stretch!important}.align-self-md-auto{align-self:auto!important}.align-self-md-start{align-self:flex-start!important}.align-self-md-end{align-self:flex-end!important}.align-self-md-center{align-self:center!important}.align-self-md-baseline{align-self:baseline!important}.align-self-md-stretch{align-self:stretch!important}.order-md-first{order:-1!important}.order-md-0{order:0!important}.order-md-1{order:1!important}.order-md-2{order:2!important}.order-md-3{order:3!important}.order-md-4{order:4!important}.order-md-5{order:5!important}.order-md-last{order:6!important}.m-md-0{margin:0!important}.m-md-1{margin:.25rem!important}.m-md-2{margin:.5rem!important}.m-md-3{margin:1rem!important}.m-md-4{margin:1.5rem!important}.m-md-5{margin:3rem!important}.m-md-auto{margin:auto!important}.mx-md-0{margin-right:0!important;margin-left:0!important}.mx-md-1{margin-right:.25rem!important;margin-left:.25rem!important}.mx-md-2{margin-right:.5rem!important;margin-left:.5rem!important}.mx-md-3{margin-right:1rem!important;margin-left:1rem!important}.mx-md-4{margin-right:1.5rem!important;margin-left:1.5rem!important}.mx-md-5{margin-right:3rem!important;margin-left:3rem!important}.mx-md-auto{margin-right:auto!important;margin-left:auto!important}.my-md-0{margin-top:0!important;margin-bottom:0!important}.my-md-1{margin-top:.25rem!important;margin-bottom:.25rem!important}.my-md-2{margin-top:.5rem!important;margin-bottom:.5rem!important}.my-md-3{margin-top:1rem!important;margin-bottom:1rem!important}.my-md-4{margin-top:1.5rem!important;margin-bottom:1.5rem!important}.my-md-5{margin-top:3rem!important;margin-bottom:3rem!important}.my-md-auto{margin-top:auto!important;margin-bottom:auto!important}.mt-md-0{margin-top:0!important}.mt-md-1{margin-top:.25rem!important}.mt-md-2{margin-top:.5rem!important}.mt-md-3{margin-top:1rem!important}.mt-md-4{margin-top:1.5rem!important}.mt-md-5{margin-top:3rem!important}.mt-md-auto{margin-top:auto!important}.me-md-0{margin-right:0!important}.me-md-1{margin-right:.25rem!important}.me-md-2{margin-right:.5rem!important}.me-md-3{margin-right:1rem!important}.me-md-4{margin-right:1.5rem!important}.me-md-5{margin-right:3rem!important}.me-md-auto{margin-right:auto!important}.mb-md-0{margin-bottom:0!important}.mb-md-1{margin-bottom:.25rem!important}.mb-md-2{margin-bottom:.5rem!important}.mb-md-3{margin-bottom:1rem!important}.mb-md-4{margin-bottom:1.5rem!important}.mb-md-5{margin-bottom:3rem!important}.mb-md-auto{margin-bottom:auto!important}.ms-md-0{margin-left:0!important}.ms-md-1{margin-left:.25rem!important}.ms-md-2{margin-left:.5rem!important}.ms-md-3{margin-left:1rem!important}.ms-md-4{margin-left:1.5rem!important}.ms-md-5{margin-left:3rem!important}.ms-md-auto{margin-left:auto!important}.p-md-0{padding:0!important}.p-md-1{padding:.25rem!important}.p-md-2{padding:.5rem!important}.p-md-3{padding:1rem!important}.p-md-4{padding:1.5rem!important}.p-md-5{padding:3rem!important}.px-md-0{padding-right:0!important;padding-left:0!important}.px-md-1{padding-right:.25rem!important;padding-left:.25rem!important}.px-md-2{padding-right:.5rem!important;padding-left:.5rem!important}.px-md-3{padding-right:1rem!important;padding-left:1rem!important}.px-md-4{padding-right:1.5rem!important;padding-left:1.5rem!important}.px-md-5{padding-right:3rem!important;padding-left:3rem!important}.py-md-0{padding-top:0!important;padding-bottom:0!important}.py-md-1{padding-top:.25rem!important;padding-bottom:.25rem!important}.py-md-2{padding-top:.5rem!important;padding-bottom:.5rem!important}.py-md-3{padding-top:1rem!important;padding-bottom:1rem!important}.py-md-4{padding-top:1.5rem!important;padding-bottom:1.5rem!important}.py-md-5{padding-top:3rem!important;padding-bottom:3rem!important}.pt-md-0{padding-top:0!important}.pt-md-1{padding-top:.25rem!important}.pt-md-2{padding-top:.5rem!important}.pt-md-3{padding-top:1rem!important}.pt-md-4{padding-top:1.5rem!important}.pt-md-5{padding-top:3rem!important}.pe-md-0{padding-right:0!important}.pe-md-1{padding-right:.25rem!important}.pe-md-2{padding-right:.5rem!important}.pe-md-3{padding-right:1rem!important}.pe-md-4{padding-right:1.5rem!important}.pe-md-5{padding-right:3rem!important}.pb-md-0{padding-bottom:0!important}.pb-md-1{padding-bottom:.25rem!important}.pb-md-2{padding-bottom:.5rem!important}.pb-md-3{padding-bottom:1rem!important}.pb-md-4{padding-bottom:1.5rem!important}.pb-md-5{padding-bottom:3rem!important}.ps-md-0{padding-left:0!important}.ps-md-1{padding-left:.25rem!important}.ps-md-2{padding-left:.5rem!important}.ps-md-3{padding-left:1rem!important}.ps-md-4{padding-left:1.5rem!important}.ps-md-5{padding-left:3rem!important}.gap-md-0{gap:0!important}.gap-md-1{gap:.25rem!important}.gap-md-2{gap:.5rem!important}.gap-md-3{gap:1rem!important}.gap-md-4{gap:1.5rem!important}.gap-md-5{gap:3rem!important}.row-gap-md-0{row-gap:0!important}.row-gap-md-1{row-gap:.25rem!important}.row-gap-md-2{row-gap:.5rem!important}.row-gap-md-3{row-gap:1rem!important}.row-gap-md-4{row-gap:1.5rem!important}.row-gap-md-5{row-gap:3rem!important}.column-gap-md-0{-moz-column-gap:0!important;column-gap:0!important}.column-gap-md-1{-moz-column-gap:0.25rem!important;column-gap:.25rem!important}.column-gap-md-2{-moz-column-gap:0.5rem!important;column-gap:.5rem!important}.column-gap-md-3{-moz-column-gap:1rem!important;column-gap:1rem!important}.column-gap-md-4{-moz-column-gap:1.5rem!important;column-gap:1.5rem!important}.column-gap-md-5{-moz-column-gap:3rem!important;column-gap:3rem!important}.text-md-start{text-align:left!important}.text-md-end{text-align:right!important}.text-md-center{text-align:center!important}}@media (min-width:992px){.float-lg-start{float:left!important}.float-lg-end{float:right!important}.float-lg-none{float:none!important}.object-fit-lg-contain{-o-object-fit:contain!important;object-fit:contain!important}.object-fit-lg-cover{-o-object-fit:cover!important;object-fit:cover!important}.object-fit-lg-fill{-o-object-fit:fill!important;object-fit:fill!important}.object-fit-lg-scale{-o-object-fit:scale-down!important;object-fit:scale-down!important}.object-fit-lg-none{-o-object-fit:none!important;object-fit:none!important}.d-lg-inline{display:inline!important}.d-lg-inline-block{display:inline-block!important}.d-lg-block{display:block!important}.d-lg-grid{display:grid!important}.d-lg-inline-grid{display:inline-grid!important}.d-lg-table{display:table!important}.d-lg-table-row{display:table-row!important}.d-lg-table-cell{display:table-cell!important}.d-lg-flex{display:flex!important}.d-lg-inline-flex{display:inline-flex!important}.d-lg-none{display:none!important}.flex-lg-fill{flex:1 1 auto!important}.flex-lg-row{flex-direction:row!important}.flex-lg-column{flex-direction:column!important}.flex-lg-row-reverse{flex-direction:row-reverse!important}.flex-lg-column-reverse{flex-direction:column-reverse!important}.flex-lg-grow-0{flex-grow:0!important}.flex-lg-grow-1{flex-grow:1!important}.flex-lg-shrink-0{flex-shrink:0!important}.flex-lg-shrink-1{flex-shrink:1!important}.flex-lg-wrap{flex-wrap:wrap!important}.flex-lg-nowrap{flex-wrap:nowrap!important}.flex-lg-wrap-reverse{flex-wrap:wrap-reverse!important}.justify-content-lg-start{justify-content:flex-start!important}.justify-content-lg-end{justify-content:flex-end!important}.justify-content-lg-center{justify-content:center!important}.justify-content-lg-between{justify-content:space-between!important}.justify-content-lg-around{justify-content:space-around!important}.justify-content-lg-evenly{justify-content:space-evenly!important}.align-items-lg-start{align-items:flex-start!important}.align-items-lg-end{align-items:flex-end!important}.align-items-lg-center{align-items:center!important}.align-items-lg-baseline{align-items:baseline!important}.align-items-lg-stretch{align-items:stretch!important}.align-content-lg-start{align-content:flex-start!important}.align-content-lg-end{align-content:flex-end!important}.align-content-lg-center{align-content:center!important}.align-content-lg-between{align-content:space-between!important}.align-content-lg-around{align-content:space-around!important}.align-content-lg-stretch{align-content:stretch!important}.align-self-lg-auto{align-self:auto!important}.align-self-lg-start{align-self:flex-start!important}.align-self-lg-end{align-self:flex-end!important}.align-self-lg-center{align-self:center!important}.align-self-lg-baseline{align-self:baseline!important}.align-self-lg-stretch{align-self:stretch!important}.order-lg-first{order:-1!important}.order-lg-0{order:0!important}.order-lg-1{order:1!important}.order-lg-2{order:2!important}.order-lg-3{order:3!important}.order-lg-4{order:4!important}.order-lg-5{order:5!important}.order-lg-last{order:6!important}.m-lg-0{margin:0!important}.m-lg-1{margin:.25rem!important}.m-lg-2{margin:.5rem!important}.m-lg-3{margin:1rem!important}.m-lg-4{margin:1.5rem!important}.m-lg-5{margin:3rem!important}.m-lg-auto{margin:auto!important}.mx-lg-0{margin-right:0!important;margin-left:0!important}.mx-lg-1{margin-right:.25rem!important;margin-left:.25rem!important}.mx-lg-2{margin-right:.5rem!important;margin-left:.5rem!important}.mx-lg-3{margin-right:1rem!important;margin-left:1rem!important}.mx-lg-4{margin-right:1.5rem!important;margin-left:1.5rem!important}.mx-lg-5{margin-right:3rem!important;margin-left:3rem!important}.mx-lg-auto{margin-right:auto!important;margin-left:auto!important}.my-lg-0{margin-top:0!important;margin-bottom:0!important}.my-lg-1{margin-top:.25rem!important;margin-bottom:.25rem!important}.my-lg-2{margin-top:.5rem!important;margin-bottom:.5rem!important}.my-lg-3{margin-top:1rem!important;margin-bottom:1rem!important}.my-lg-4{margin-top:1.5rem!important;margin-bottom:1.5rem!important}.my-lg-5{margin-top:3rem!important;margin-bottom:3rem!important}.my-lg-auto{margin-top:auto!important;margin-bottom:auto!important}.mt-lg-0{margin-top:0!important}.mt-lg-1{margin-top:.25rem!important}.mt-lg-2{margin-top:.5rem!important}.mt-lg-3{margin-top:1rem!important}.mt-lg-4{margin-top:1.5rem!important}.mt-lg-5{margin-top:3rem!important}.mt-lg-auto{margin-top:auto!important}.me-lg-0{margin-right:0!important}.me-lg-1{margin-right:.25rem!important}.me-lg-2{margin-right:.5rem!important}.me-lg-3{margin-right:1rem!important}.me-lg-4{margin-right:1.5rem!important}.me-lg-5{margin-right:3rem!important}.me-lg-auto{margin-right:auto!important}.mb-lg-0{margin-bottom:0!important}.mb-lg-1{margin-bottom:.25rem!important}.mb-lg-2{margin-bottom:.5rem!important}.mb-lg-3{margin-bottom:1rem!important}.mb-lg-4{margin-bottom:1.5rem!important}.mb-lg-5{margin-bottom:3rem!important}.mb-lg-auto{margin-bottom:auto!important}.ms-lg-0{margin-left:0!important}.ms-lg-1{margin-left:.25rem!important}.ms-lg-2{margin-left:.5rem!important}.ms-lg-3{margin-left:1rem!important}.ms-lg-4{margin-left:1.5rem!important}.ms-lg-5{margin-left:3rem!important}.ms-lg-auto{margin-left:auto!important}.p-lg-0{padding:0!important}.p-lg-1{padding:.25rem!important}.p-lg-2{padding:.5rem!important}.p-lg-3{padding:1rem!important}.p-lg-4{padding:1.5rem!important}.p-lg-5{padding:3rem!important}.px-lg-0{padding-right:0!important;padding-left:0!important}.px-lg-1{padding-right:.25rem!important;padding-left:.25rem!important}.px-lg-2{padding-right:.5rem!important;padding-left:.5rem!important}.px-lg-3{padding-right:1rem!important;padding-left:1rem!important}.px-lg-4{padding-right:1.5rem!important;padding-left:1.5rem!important}.px-lg-5{padding-right:3rem!important;padding-left:3rem!important}.py-lg-0{padding-top:0!important;padding-bottom:0!important}.py-lg-1{padding-top:.25rem!important;padding-bottom:.25rem!important}.py-lg-2{padding-top:.5rem!important;padding-bottom:.5rem!important}.py-lg-3{padding-top:1rem!important;padding-bottom:1rem!important}.py-lg-4{padding-top:1.5rem!important;padding-bottom:1.5rem!important}.py-lg-5{padding-top:3rem!important;padding-bottom:3rem!important}.pt-lg-0{padding-top:0!important}.pt-lg-1{padding-top:.25rem!important}.pt-lg-2{padding-top:.5rem!important}.pt-lg-3{padding-top:1rem!important}.pt-lg-4{padding-top:1.5rem!important}.pt-lg-5{padding-top:3rem!important}.pe-lg-0{padding-right:0!important}.pe-lg-1{padding-right:.25rem!important}.pe-lg-2{padding-right:.5rem!important}.pe-lg-3{padding-right:1rem!important}.pe-lg-4{padding-right:1.5rem!important}.pe-lg-5{padding-right:3rem!important}.pb-lg-0{padding-bottom:0!important}.pb-lg-1{padding-bottom:.25rem!important}.pb-lg-2{padding-bottom:.5rem!important}.pb-lg-3{padding-bottom:1rem!important}.pb-lg-4{padding-bottom:1.5rem!important}.pb-lg-5{padding-bottom:3rem!important}.ps-lg-0{padding-left:0!important}.ps-lg-1{padding-left:.25rem!important}.ps-lg-2{padding-left:.5rem!important}.ps-lg-3{padding-left:1rem!important}.ps-lg-4{padding-left:1.5rem!important}.ps-lg-5{padding-left:3rem!important}.gap-lg-0{gap:0!important}.gap-lg-1{gap:.25rem!important}.gap-lg-2{gap:.5rem!important}.gap-lg-3{gap:1rem!important}.gap-lg-4{gap:1.5rem!important}.gap-lg-5{gap:3rem!important}.row-gap-lg-0{row-gap:0!important}.row-gap-lg-1{row-gap:.25rem!important}.row-gap-lg-2{row-gap:.5rem!important}.row-gap-lg-3{row-gap:1rem!important}.row-gap-lg-4{row-gap:1.5rem!important}.row-gap-lg-5{row-gap:3rem!important}.column-gap-lg-0{-moz-column-gap:0!important;column-gap:0!important}.column-gap-lg-1{-moz-column-gap:0.25rem!important;column-gap:.25rem!important}.column-gap-lg-2{-moz-column-gap:0.5rem!important;column-gap:.5rem!important}.column-gap-lg-3{-moz-column-gap:1rem!important;column-gap:1rem!important}.column-gap-lg-4{-moz-column-gap:1.5rem!important;column-gap:1.5rem!important}.column-gap-lg-5{-moz-column-gap:3rem!important;column-gap:3rem!important}.text-lg-start{text-align:left!important}.text-lg-end{text-align:right!important}.text-lg-center{text-align:center!important}}@media (min-width:1200px){.float-xl-start{float:left!important}.float-xl-end{float:right!important}.float-xl-none{float:none!important}.object-fit-xl-contain{-o-object-fit:contain!important;object-fit:contain!important}.object-fit-xl-cover{-o-object-fit:cover!important;object-fit:cover!important}.object-fit-xl-fill{-o-object-fit:fill!important;object-fit:fill!important}.object-fit-xl-scale{-o-object-fit:scale-down!important;object-fit:scale-down!important}.object-fit-xl-none{-o-object-fit:none!important;object-fit:none!important}.d-xl-inline{display:inline!important}.d-xl-inline-block{display:inline-block!important}.d-xl-block{display:block!important}.d-xl-grid{display:grid!important}.d-xl-inline-grid{display:inline-grid!important}.d-xl-table{display:table!important}.d-xl-table-row{display:table-row!important}.d-xl-table-cell{display:table-cell!important}.d-xl-flex{display:flex!important}.d-xl-inline-flex{display:inline-flex!important}.d-xl-none{display:none!important}.flex-xl-fill{flex:1 1 auto!important}.flex-xl-row{flex-direction:row!important}.flex-xl-column{flex-direction:column!important}.flex-xl-row-reverse{flex-direction:row-reverse!important}.flex-xl-column-reverse{flex-direction:column-reverse!important}.flex-xl-grow-0{flex-grow:0!important}.flex-xl-grow-1{flex-grow:1!important}.flex-xl-shrink-0{flex-shrink:0!important}.flex-xl-shrink-1{flex-shrink:1!important}.flex-xl-wrap{flex-wrap:wrap!important}.flex-xl-nowrap{flex-wrap:nowrap!important}.flex-xl-wrap-reverse{flex-wrap:wrap-reverse!important}.justify-content-xl-start{justify-content:flex-start!important}.justify-content-xl-end{justify-content:flex-end!important}.justify-content-xl-center{justify-content:center!important}.justify-content-xl-between{justify-content:space-between!important}.justify-content-xl-around{justify-content:space-around!important}.justify-content-xl-evenly{justify-content:space-evenly!important}.align-items-xl-start{align-items:flex-start!important}.align-items-xl-end{align-items:flex-end!important}.align-items-xl-center{align-items:center!important}.align-items-xl-baseline{align-items:baseline!important}.align-items-xl-stretch{align-items:stretch!important}.align-content-xl-start{align-content:flex-start!important}.align-content-xl-end{align-content:flex-end!important}.align-content-xl-center{align-content:center!important}.align-content-xl-between{align-content:space-between!important}.align-content-xl-around{align-content:space-around!important}.align-content-xl-stretch{align-content:stretch!important}.align-self-xl-auto{align-self:auto!important}.align-self-xl-start{align-self:flex-start!important}.align-self-xl-end{align-self:flex-end!important}.align-self-xl-center{align-self:center!important}.align-self-xl-baseline{align-self:baseline!important}.align-self-xl-stretch{align-self:stretch!important}.order-xl-first{order:-1!important}.order-xl-0{order:0!important}.order-xl-1{order:1!important}.order-xl-2{order:2!important}.order-xl-3{order:3!important}.order-xl-4{order:4!important}.order-xl-5{order:5!important}.order-xl-last{order:6!important}.m-xl-0{margin:0!important}.m-xl-1{margin:.25rem!important}.m-xl-2{margin:.5rem!important}.m-xl-3{margin:1rem!important}.m-xl-4{margin:1.5rem!important}.m-xl-5{margin:3rem!important}.m-xl-auto{margin:auto!important}.mx-xl-0{margin-right:0!important;margin-left:0!important}.mx-xl-1{margin-right:.25rem!important;margin-left:.25rem!important}.mx-xl-2{margin-right:.5rem!important;margin-left:.5rem!important}.mx-xl-3{margin-right:1rem!important;margin-left:1rem!important}.mx-xl-4{margin-right:1.5rem!important;margin-left:1.5rem!important}.mx-xl-5{margin-right:3rem!important;margin-left:3rem!important}.mx-xl-auto{margin-right:auto!important;margin-left:auto!important}.my-xl-0{margin-top:0!important;margin-bottom:0!important}.my-xl-1{margin-top:.25rem!important;margin-bottom:.25rem!important}.my-xl-2{margin-top:.5rem!important;margin-bottom:.5rem!important}.my-xl-3{margin-top:1rem!important;margin-bottom:1rem!important}.my-xl-4{margin-top:1.5rem!important;margin-bottom:1.5rem!important}.my-xl-5{margin-top:3rem!important;margin-bottom:3rem!important}.my-xl-auto{margin-top:auto!important;margin-bottom:auto!important}.mt-xl-0{margin-top:0!important}.mt-xl-1{margin-top:.25rem!important}.mt-xl-2{margin-top:.5rem!important}.mt-xl-3{margin-top:1rem!important}.mt-xl-4{margin-top:1.5rem!important}.mt-xl-5{margin-top:3rem!important}.mt-xl-auto{margin-top:auto!important}.me-xl-0{margin-right:0!important}.me-xl-1{margin-right:.25rem!important}.me-xl-2{margin-right:.5rem!important}.me-xl-3{margin-right:1rem!important}.me-xl-4{margin-right:1.5rem!important}.me-xl-5{margin-right:3rem!important}.me-xl-auto{margin-right:auto!important}.mb-xl-0{margin-bottom:0!important}.mb-xl-1{margin-bottom:.25rem!important}.mb-xl-2{margin-bottom:.5rem!important}.mb-xl-3{margin-bottom:1rem!important}.mb-xl-4{margin-bottom:1.5rem!important}.mb-xl-5{margin-bottom:3rem!important}.mb-xl-auto{margin-bottom:auto!important}.ms-xl-0{margin-left:0!important}.ms-xl-1{margin-left:.25rem!important}.ms-xl-2{margin-left:.5rem!important}.ms-xl-3{margin-left:1rem!important}.ms-xl-4{margin-left:1.5rem!important}.ms-xl-5{margin-left:3rem!important}.ms-xl-auto{margin-left:auto!important}.p-xl-0{padding:0!important}.p-xl-1{padding:.25rem!important}.p-xl-2{padding:.5rem!important}.p-xl-3{padding:1rem!important}.p-xl-4{padding:1.5rem!important}.p-xl-5{padding:3rem!important}.px-xl-0{padding-right:0!important;padding-left:0!important}.px-xl-1{padding-right:.25rem!important;padding-left:.25rem!important}.px-xl-2{padding-right:.5rem!important;padding-left:.5rem!important}.px-xl-3{padding-right:1rem!important;padding-left:1rem!important}.px-xl-4{padding-right:1.5rem!important;padding-left:1.5rem!important}.px-xl-5{padding-right:3rem!important;padding-left:3rem!important}.py-xl-0{padding-top:0!important;padding-bottom:0!important}.py-xl-1{padding-top:.25rem!important;padding-bottom:.25rem!important}.py-xl-2{padding-top:.5rem!important;padding-bottom:.5rem!important}.py-xl-3{padding-top:1rem!important;padding-bottom:1rem!important}.py-xl-4{padding-top:1.5rem!important;padding-bottom:1.5rem!important}.py-xl-5{padding-top:3rem!important;padding-bottom:3rem!important}.pt-xl-0{padding-top:0!important}.pt-xl-1{padding-top:.25rem!important}.pt-xl-2{padding-top:.5rem!important}.pt-xl-3{padding-top:1rem!important}.pt-xl-4{padding-top:1.5rem!important}.pt-xl-5{padding-top:3rem!important}.pe-xl-0{padding-right:0!important}.pe-xl-1{padding-right:.25rem!important}.pe-xl-2{padding-right:.5rem!important}.pe-xl-3{padding-right:1rem!important}.pe-xl-4{padding-right:1.5rem!important}.pe-xl-5{padding-right:3rem!important}.pb-xl-0{padding-bottom:0!important}.pb-xl-1{padding-bottom:.25rem!important}.pb-xl-2{padding-bottom:.5rem!important}.pb-xl-3{padding-bottom:1rem!important}.pb-xl-4{padding-bottom:1.5rem!important}.pb-xl-5{padding-bottom:3rem!important}.ps-xl-0{padding-left:0!important}.ps-xl-1{padding-left:.25rem!important}.ps-xl-2{padding-left:.5rem!important}.ps-xl-3{padding-left:1rem!important}.ps-xl-4{padding-left:1.5rem!important}.ps-xl-5{padding-left:3rem!important}.gap-xl-0{gap:0!important}.gap-xl-1{gap:.25rem!important}.gap-xl-2{gap:.5rem!important}.gap-xl-3{gap:1rem!important}.gap-xl-4{gap:1.5rem!important}.gap-xl-5{gap:3rem!important}.row-gap-xl-0{row-gap:0!important}.row-gap-xl-1{row-gap:.25rem!important}.row-gap-xl-2{row-gap:.5rem!important}.row-gap-xl-3{row-gap:1rem!important}.row-gap-xl-4{row-gap:1.5rem!important}.row-gap-xl-5{row-gap:3rem!important}.column-gap-xl-0{-moz-column-gap:0!important;column-gap:0!important}.column-gap-xl-1{-moz-column-gap:0.25rem!important;column-gap:.25rem!important}.column-gap-xl-2{-moz-column-gap:0.5rem!important;column-gap:.5rem!important}.column-gap-xl-3{-moz-column-gap:1rem!important;column-gap:1rem!important}.column-gap-xl-4{-moz-column-gap:1.5rem!important;column-gap:1.5rem!important}.column-gap-xl-5{-moz-column-gap:3rem!important;column-gap:3rem!important}.text-xl-start{text-align:left!important}.text-xl-end{text-align:right!important}.text-xl-center{text-align:center!important}}@media (min-width:1400px){.float-xxl-start{float:left!important}.float-xxl-end{float:right!important}.float-xxl-none{float:none!important}.object-fit-xxl-contain{-o-object-fit:contain!important;object-fit:contain!important}.object-fit-xxl-cover{-o-object-fit:cover!important;object-fit:cover!important}.object-fit-xxl-fill{-o-object-fit:fill!important;object-fit:fill!important}.object-fit-xxl-scale{-o-object-fit:scale-down!important;object-fit:scale-down!important}.object-fit-xxl-none{-o-object-fit:none!important;object-fit:none!important}.d-xxl-inline{display:inline!important}.d-xxl-inline-block{display:inline-block!important}.d-xxl-block{display:block!important}.d-xxl-grid{display:grid!important}.d-xxl-inline-grid{display:inline-grid!important}.d-xxl-table{display:table!important}.d-xxl-table-row{display:table-row!important}.d-xxl-table-cell{display:table-cell!important}.d-xxl-flex{display:flex!important}.d-xxl-inline-flex{display:inline-flex!important}.d-xxl-none{display:none!important}.flex-xxl-fill{flex:1 1 auto!important}.flex-xxl-row{flex-direction:row!important}.flex-xxl-column{flex-direction:column!important}.flex-xxl-row-reverse{flex-direction:row-reverse!important}.flex-xxl-column-reverse{flex-direction:column-reverse!important}.flex-xxl-grow-0{flex-grow:0!important}.flex-xxl-grow-1{flex-grow:1!important}.flex-xxl-shrink-0{flex-shrink:0!important}.flex-xxl-shrink-1{flex-shrink:1!important}.flex-xxl-wrap{flex-wrap:wrap!important}.flex-xxl-nowrap{flex-wrap:nowrap!important}.flex-xxl-wrap-reverse{flex-wrap:wrap-reverse!important}.justify-content-xxl-start{justify-content:flex-start!important}.justify-content-xxl-end{justify-content:flex-end!important}.justify-content-xxl-center{justify-content:center!important}.justify-content-xxl-between{justify-content:space-between!important}.justify-content-xxl-around{justify-content:space-around!important}.justify-content-xxl-evenly{justify-content:space-evenly!important}.align-items-xxl-start{align-items:flex-start!important}.align-items-xxl-end{align-items:flex-end!important}.align-items-xxl-center{align-items:center!important}.align-items-xxl-baseline{align-items:baseline!important}.align-items-xxl-stretch{align-items:stretch!important}.align-content-xxl-start{align-content:flex-start!important}.align-content-xxl-end{align-content:flex-end!important}.align-content-xxl-center{align-content:center!important}.align-content-xxl-between{align-content:space-between!important}.align-content-xxl-around{align-content:space-around!important}.align-content-xxl-stretch{align-content:stretch!important}.align-self-xxl-auto{align-self:auto!important}.align-self-xxl-start{align-self:flex-start!important}.align-self-xxl-end{align-self:flex-end!important}.align-self-xxl-center{align-self:center!important}.align-self-xxl-baseline{align-self:baseline!important}.align-self-xxl-stretch{align-self:stretch!important}.order-xxl-first{order:-1!important}.order-xxl-0{order:0!important}.order-xxl-1{order:1!important}.order-xxl-2{order:2!important}.order-xxl-3{order:3!important}.order-xxl-4{order:4!important}.order-xxl-5{order:5!important}.order-xxl-last{order:6!important}.m-xxl-0{margin:0!important}.m-xxl-1{margin:.25rem!important}.m-xxl-2{margin:.5rem!important}.m-xxl-3{margin:1rem!important}.m-xxl-4{margin:1.5rem!important}.m-xxl-5{margin:3rem!important}.m-xxl-auto{margin:auto!important}.mx-xxl-0{margin-right:0!important;margin-left:0!important}.mx-xxl-1{margin-right:.25rem!important;margin-left:.25rem!important}.mx-xxl-2{margin-right:.5rem!important;margin-left:.5rem!important}.mx-xxl-3{margin-right:1rem!important;margin-left:1rem!important}.mx-xxl-4{margin-right:1.5rem!important;margin-left:1.5rem!important}.mx-xxl-5{margin-right:3rem!important;margin-left:3rem!important}.mx-xxl-auto{margin-right:auto!important;margin-left:auto!important}.my-xxl-0{margin-top:0!important;margin-bottom:0!important}.my-xxl-1{margin-top:.25rem!important;margin-bottom:.25rem!important}.my-xxl-2{margin-top:.5rem!important;margin-bottom:.5rem!important}.my-xxl-3{margin-top:1rem!important;margin-bottom:1rem!important}.my-xxl-4{margin-top:1.5rem!important;margin-bottom:1.5rem!important}.my-xxl-5{margin-top:3rem!important;margin-bottom:3rem!important}.my-xxl-auto{margin-top:auto!important;margin-bottom:auto!important}.mt-xxl-0{margin-top:0!important}.mt-xxl-1{margin-top:.25rem!important}.mt-xxl-2{margin-top:.5rem!important}.mt-xxl-3{margin-top:1rem!important}.mt-xxl-4{margin-top:1.5rem!important}.mt-xxl-5{margin-top:3rem!important}.mt-xxl-auto{margin-top:auto!important}.me-xxl-0{margin-right:0!important}.me-xxl-1{margin-right:.25rem!important}.me-xxl-2{margin-right:.5rem!important}.me-xxl-3{margin-right:1rem!important}.me-xxl-4{margin-right:1.5rem!important}.me-xxl-5{margin-right:3rem!important}.me-xxl-auto{margin-right:auto!important}.mb-xxl-0{margin-bottom:0!important}.mb-xxl-1{margin-bottom:.25rem!important}.mb-xxl-2{margin-bottom:.5rem!important}.mb-xxl-3{margin-bottom:1rem!important}.mb-xxl-4{margin-bottom:1.5rem!important}.mb-xxl-5{margin-bottom:3rem!important}.mb-xxl-auto{margin-bottom:auto!important}.ms-xxl-0{margin-left:0!important}.ms-xxl-1{margin-left:.25rem!important}.ms-xxl-2{margin-left:.5rem!important}.ms-xxl-3{margin-left:1rem!important}.ms-xxl-4{margin-left:1.5rem!important}.ms-xxl-5{margin-left:3rem!important}.ms-xxl-auto{margin-left:auto!important}.p-xxl-0{padding:0!important}.p-xxl-1{padding:.25rem!important}.p-xxl-2{padding:.5rem!important}.p-xxl-3{padding:1rem!important}.p-xxl-4{padding:1.5rem!important}.p-xxl-5{padding:3rem!important}.px-xxl-0{padding-right:0!important;padding-left:0!important}.px-xxl-1{padding-right:.25rem!important;padding-left:.25rem!important}.px-xxl-2{padding-right:.5rem!important;padding-left:.5rem!important}.px-xxl-3{padding-right:1rem!important;padding-left:1rem!important}.px-xxl-4{padding-right:1.5rem!important;padding-left:1.5rem!important}.px-xxl-5{padding-right:3rem!important;padding-left:3rem!important}.py-xxl-0{padding-top:0!important;padding-bottom:0!important}.py-xxl-1{padding-top:.25rem!important;padding-bottom:.25rem!important}.py-xxl-2{padding-top:.5rem!important;padding-bottom:.5rem!important}.py-xxl-3{padding-top:1rem!important;padding-bottom:1rem!important}.py-xxl-4{padding-top:1.5rem!important;padding-bottom:1.5rem!important}.py-xxl-5{padding-top:3rem!important;padding-bottom:3rem!important}.pt-xxl-0{padding-top:0!important}.pt-xxl-1{padding-top:.25rem!important}.pt-xxl-2{padding-top:.5rem!important}.pt-xxl-3{padding-top:1rem!important}.pt-xxl-4{padding-top:1.5rem!important}.pt-xxl-5{padding-top:3rem!important}.pe-xxl-0{padding-right:0!important}.pe-xxl-1{padding-right:.25rem!important}.pe-xxl-2{padding-right:.5rem!important}.pe-xxl-3{padding-right:1rem!important}.pe-xxl-4{padding-right:1.5rem!important}.pe-xxl-5{padding-right:3rem!important}.pb-xxl-0{padding-bottom:0!important}.pb-xxl-1{padding-bottom:.25rem!important}.pb-xxl-2{padding-bottom:.5rem!important}.pb-xxl-3{padding-bottom:1rem!important}.pb-xxl-4{padding-bottom:1.5rem!important}.pb-xxl-5{padding-bottom:3rem!important}.ps-xxl-0{padding-left:0!important}.ps-xxl-1{padding-left:.25rem!important}.ps-xxl-2{padding-left:.5rem!important}.ps-xxl-3{padding-left:1rem!important}.ps-xxl-4{padding-left:1.5rem!important}.ps-xxl-5{padding-left:3rem!important}.gap-xxl-0{gap:0!important}.gap-xxl-1{gap:.25rem!important}.gap-xxl-2{gap:.5rem!important}.gap-xxl-3{gap:1rem!important}.gap-xxl-4{gap:1.5rem!important}.gap-xxl-5{gap:3rem!important}.row-gap-xxl-0{row-gap:0!important}.row-gap-xxl-1{row-gap:.25rem!important}.row-gap-xxl-2{row-gap:.5rem!important}.row-gap-xxl-3{row-gap:1rem!important}.row-gap-xxl-4{row-gap:1.5rem!important}.row-gap-xxl-5{row-gap:3rem!important}.column-gap-xxl-0{-moz-column-gap:0!important;column-gap:0!important}.column-gap-xxl-1{-moz-column-gap:0.25rem!important;column-gap:.25rem!important}.column-gap-xxl-2{-moz-column-gap:0.5rem!important;column-gap:.5rem!important}.column-gap-xxl-3{-moz-column-gap:1rem!important;column-gap:1rem!important}.column-gap-xxl-4{-moz-column-gap:1.5rem!important;column-gap:1.5rem!important}.column-gap-xxl-5{-moz-column-gap:3rem!important;column-gap:3rem!important}.text-xxl-start{text-align:left!important}.text-xxl-end{text-align:right!important}.text-xxl-center{text-align:center!important}}@media (min-width:1200px){.fs-1{font-size:2.5rem!important}.fs-2{font-size:2rem!important}.fs-3{font-size:1.75rem!important}.fs-4{font-size:1.5rem!important}}@media print{.d-print-inline{display:inline!important}.d-print-inline-block{display:inline-block!important}.d-print-block{display:block!important}.d-print-grid{display:grid!important}.d-print-inline-grid{display:inline-grid!important}.d-print-table{display:table!important}.d-print-table-row{display:table-row!important}.d-print-table-cell{display:table-cell!important}.d-print-flex{display:flex!important}.d-print-inline-flex{display:inline-flex!important}.d-print-none{display:none!important}} -/*# sourceMappingURL=bootstrap.min.css.map */ \ No newline at end of file diff --git a/backend/coverage-report-final/_css/custom.css b/backend/coverage-report-final/_css/custom.css deleted file mode 100644 index e69de29b..00000000 diff --git a/backend/coverage-report-final/_css/nv.d3.min.css b/backend/coverage-report-final/_css/nv.d3.min.css deleted file mode 100644 index 7a6f7fe9..00000000 --- a/backend/coverage-report-final/_css/nv.d3.min.css +++ /dev/null @@ -1 +0,0 @@ -.nvd3 .nv-axis{pointer-events:none;opacity:1}.nvd3 .nv-axis path{fill:none;stroke:#000;stroke-opacity:.75;shape-rendering:crispEdges}.nvd3 .nv-axis path.domain{stroke-opacity:.75}.nvd3 .nv-axis.nv-x path.domain{stroke-opacity:0}.nvd3 .nv-axis line{fill:none;stroke:#e5e5e5;shape-rendering:crispEdges}.nvd3 .nv-axis .zero line,.nvd3 .nv-axis line.zero{stroke-opacity:.75}.nvd3 .nv-axis .nv-axisMaxMin text{font-weight:700}.nvd3 .x .nv-axis .nv-axisMaxMin text,.nvd3 .x2 .nv-axis .nv-axisMaxMin text,.nvd3 .x3 .nv-axis .nv-axisMaxMin text{text-anchor:middle}.nvd3 .nv-axis.nv-disabled{opacity:0}.nvd3 .nv-bars rect{fill-opacity:.75;transition:fill-opacity 250ms linear;-moz-transition:fill-opacity 250ms linear;-webkit-transition:fill-opacity 250ms linear}.nvd3 .nv-bars rect.hover{fill-opacity:1}.nvd3 .nv-bars .hover rect{fill:#add8e6}.nvd3 .nv-bars text{fill:rgba(0,0,0,0)}.nvd3 .nv-bars .hover text{fill:rgba(0,0,0,1)}.nvd3 .nv-multibar .nv-groups rect,.nvd3 .nv-multibarHorizontal .nv-groups rect,.nvd3 .nv-discretebar .nv-groups rect{stroke-opacity:0;transition:fill-opacity 250ms linear;-moz-transition:fill-opacity 250ms linear;-webkit-transition:fill-opacity 250ms linear}.nvd3 .nv-multibar .nv-groups rect:hover,.nvd3 .nv-multibarHorizontal .nv-groups rect:hover,.nvd3 .nv-candlestickBar .nv-ticks rect:hover,.nvd3 .nv-discretebar .nv-groups rect:hover{fill-opacity:1}.nvd3 .nv-discretebar .nv-groups text,.nvd3 .nv-multibarHorizontal .nv-groups text{font-weight:700;fill:rgba(0,0,0,1);stroke:rgba(0,0,0,0)}.nvd3 .nv-boxplot circle{fill-opacity:.5}.nvd3 .nv-boxplot circle:hover{fill-opacity:1}.nvd3 .nv-boxplot rect:hover{fill-opacity:1}.nvd3 line.nv-boxplot-median{stroke:#000}.nv-boxplot-tick:hover{stroke-width:2.5px}.nvd3.nv-bullet{font:10px sans-serif}.nvd3.nv-bullet .nv-measure{fill-opacity:.8}.nvd3.nv-bullet .nv-measure:hover{fill-opacity:1}.nvd3.nv-bullet .nv-marker{stroke:#000;stroke-width:2px}.nvd3.nv-bullet .nv-markerTriangle{stroke:#000;fill:#fff;stroke-width:1.5px}.nvd3.nv-bullet .nv-tick line{stroke:#666;stroke-width:.5px}.nvd3.nv-bullet .nv-range.nv-s0{fill:#eee}.nvd3.nv-bullet .nv-range.nv-s1{fill:#ddd}.nvd3.nv-bullet .nv-range.nv-s2{fill:#ccc}.nvd3.nv-bullet .nv-title{font-size:14px;font-weight:700}.nvd3.nv-bullet .nv-subtitle{fill:#999}.nvd3.nv-bullet .nv-range{fill:#bababa;fill-opacity:.4}.nvd3.nv-bullet .nv-range:hover{fill-opacity:.7}.nvd3.nv-candlestickBar .nv-ticks .nv-tick{stroke-width:1px}.nvd3.nv-candlestickBar .nv-ticks .nv-tick.hover{stroke-width:2px}.nvd3.nv-candlestickBar .nv-ticks .nv-tick.positive rect{stroke:#2ca02c;fill:#2ca02c}.nvd3.nv-candlestickBar .nv-ticks .nv-tick.negative rect{stroke:#d62728;fill:#d62728}.with-transitions .nv-candlestickBar .nv-ticks .nv-tick{transition:stroke-width 250ms linear,stroke-opacity 250ms linear;-moz-transition:stroke-width 250ms linear,stroke-opacity 250ms linear;-webkit-transition:stroke-width 250ms linear,stroke-opacity 250ms linear}.nvd3.nv-candlestickBar .nv-ticks line{stroke:#333}.nvd3 .nv-legend .nv-disabled rect{}.nvd3 .nv-check-box .nv-box{fill-opacity:0;stroke-width:2}.nvd3 .nv-check-box .nv-check{fill-opacity:0;stroke-width:4}.nvd3 .nv-series.nv-disabled .nv-check-box .nv-check{fill-opacity:0;stroke-opacity:0}.nvd3 .nv-controlsWrap .nv-legend .nv-check-box .nv-check{opacity:0}.nvd3.nv-linePlusBar .nv-bar rect{fill-opacity:.75}.nvd3.nv-linePlusBar .nv-bar rect:hover{fill-opacity:1}.nvd3 .nv-groups path.nv-line{fill:none}.nvd3 .nv-groups path.nv-area{stroke:none}.nvd3.nv-line .nvd3.nv-scatter .nv-groups .nv-point{fill-opacity:0;stroke-opacity:0}.nvd3.nv-scatter.nv-single-point .nv-groups .nv-point{fill-opacity:.5!important;stroke-opacity:.5!important}.with-transitions .nvd3 .nv-groups .nv-point{transition:stroke-width 250ms linear,stroke-opacity 250ms linear;-moz-transition:stroke-width 250ms linear,stroke-opacity 250ms linear;-webkit-transition:stroke-width 250ms linear,stroke-opacity 250ms linear}.nvd3.nv-scatter .nv-groups .nv-point.hover,.nvd3 .nv-groups .nv-point.hover{stroke-width:7px;fill-opacity:.95!important;stroke-opacity:.95!important}.nvd3 .nv-point-paths path{stroke:#aaa;stroke-opacity:0;fill:#eee;fill-opacity:0}.nvd3 .nv-indexLine{cursor:ew-resize}svg.nvd3-svg{-webkit-touch-callout:none;-webkit-user-select:none;-khtml-user-select:none;-ms-user-select:none;-moz-user-select:none;user-select:none;display:block;width:100%;height:100%}.nvtooltip.with-3d-shadow,.with-3d-shadow .nvtooltip{-moz-box-shadow:0 5px 10px rgba(0,0,0,.2);-webkit-box-shadow:0 5px 10px rgba(0,0,0,.2);box-shadow:0 5px 10px rgba(0,0,0,.2);-webkit-border-radius:5px;-moz-border-radius:5px;border-radius:5px}.nvd3 text{font:400 12px Arial}.nvd3 .title{font:700 14px Arial}.nvd3 .nv-background{fill:#fff;fill-opacity:0}.nvd3.nv-noData{font-size:18px;font-weight:700}.nv-brush .extent{fill-opacity:.125;shape-rendering:crispEdges}.nv-brush .resize path{fill:#eee;stroke:#666}.nvd3 .nv-legend .nv-series{cursor:pointer}.nvd3 .nv-legend .nv-disabled circle{fill-opacity:0}.nvd3 .nv-brush .extent{fill-opacity:0!important}.nvd3 .nv-brushBackground rect{stroke:#000;stroke-width:.4;fill:#fff;fill-opacity:.7}.nvd3.nv-ohlcBar .nv-ticks .nv-tick{stroke-width:1px}.nvd3.nv-ohlcBar .nv-ticks .nv-tick.hover{stroke-width:2px}.nvd3.nv-ohlcBar .nv-ticks .nv-tick.positive{stroke:#2ca02c}.nvd3.nv-ohlcBar .nv-ticks .nv-tick.negative{stroke:#d62728}.nvd3 .background path{fill:none;stroke:#EEE;stroke-opacity:.4;shape-rendering:crispEdges}.nvd3 .foreground path{fill:none;stroke-opacity:.7}.nvd3 .nv-parallelCoordinates-brush .extent{fill:#fff;fill-opacity:.6;stroke:gray;shape-rendering:crispEdges}.nvd3 .nv-parallelCoordinates .hover{fill-opacity:1;stroke-width:3px}.nvd3 .missingValuesline line{fill:none;stroke:#000;stroke-width:1;stroke-opacity:1;stroke-dasharray:5,5}.nvd3.nv-pie path{stroke-opacity:0;transition:fill-opacity 250ms linear,stroke-width 250ms linear,stroke-opacity 250ms linear;-moz-transition:fill-opacity 250ms linear,stroke-width 250ms linear,stroke-opacity 250ms linear;-webkit-transition:fill-opacity 250ms linear,stroke-width 250ms linear,stroke-opacity 250ms linear}.nvd3.nv-pie .nv-pie-title{font-size:24px;fill:rgba(19,196,249,.59)}.nvd3.nv-pie .nv-slice text{stroke:#000;stroke-width:0}.nvd3.nv-pie path{stroke:#fff;stroke-width:1px;stroke-opacity:1}.nvd3.nv-pie .hover path{fill-opacity:.7}.nvd3.nv-pie .nv-label{pointer-events:none}.nvd3.nv-pie .nv-label rect{fill-opacity:0;stroke-opacity:0}.nvd3 .nv-groups .nv-point.hover{stroke-width:20px;stroke-opacity:.5}.nvd3 .nv-scatter .nv-point.hover{fill-opacity:1}.nv-noninteractive{pointer-events:none}.nv-distx,.nv-disty{pointer-events:none}.nvd3.nv-sparkline path{fill:none}.nvd3.nv-sparklineplus g.nv-hoverValue{pointer-events:none}.nvd3.nv-sparklineplus .nv-hoverValue line{stroke:#333;stroke-width:1.5px}.nvd3.nv-sparklineplus,.nvd3.nv-sparklineplus g{pointer-events:all}.nvd3 .nv-hoverArea{fill-opacity:0;stroke-opacity:0}.nvd3.nv-sparklineplus .nv-xValue,.nvd3.nv-sparklineplus .nv-yValue{stroke-width:0;font-size:.9em;font-weight:400}.nvd3.nv-sparklineplus .nv-yValue{stroke:#f66}.nvd3.nv-sparklineplus .nv-maxValue{stroke:#2ca02c;fill:#2ca02c}.nvd3.nv-sparklineplus .nv-minValue{stroke:#d62728;fill:#d62728}.nvd3.nv-sparklineplus .nv-currentValue{font-weight:700;font-size:1.1em}.nvd3.nv-stackedarea path.nv-area{fill-opacity:.7;stroke-opacity:0;transition:fill-opacity 250ms linear,stroke-opacity 250ms linear;-moz-transition:fill-opacity 250ms linear,stroke-opacity 250ms linear;-webkit-transition:fill-opacity 250ms linear,stroke-opacity 250ms linear}.nvd3.nv-stackedarea path.nv-area.hover{fill-opacity:.9}.nvd3.nv-stackedarea .nv-groups .nv-point{stroke-opacity:0;fill-opacity:0}.nvtooltip{position:absolute;background-color:rgba(255,255,255,1);color:rgba(0,0,0,1);padding:1px;border:1px solid rgba(0,0,0,.2);z-index:10000;display:block;font-family:Arial;font-size:13px;text-align:left;pointer-events:none;white-space:nowrap;-webkit-touch-callout:none;-webkit-user-select:none;-khtml-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.nvtooltip{background:rgba(255,255,255,.8);border:1px solid rgba(0,0,0,.5);border-radius:4px}.nvtooltip.with-transitions,.with-transitions .nvtooltip{transition:opacity 50ms linear;-moz-transition:opacity 50ms linear;-webkit-transition:opacity 50ms linear;transition-delay:200ms;-moz-transition-delay:200ms;-webkit-transition-delay:200ms}.nvtooltip.x-nvtooltip,.nvtooltip.y-nvtooltip{padding:8px}.nvtooltip h3{margin:0;padding:4px 14px;line-height:18px;font-weight:400;background-color:rgba(247,247,247,.75);color:rgba(0,0,0,1);text-align:center;border-bottom:1px solid #ebebeb;-webkit-border-radius:5px 5px 0 0;-moz-border-radius:5px 5px 0 0;border-radius:5px 5px 0 0}.nvtooltip p{margin:0;padding:5px 14px;text-align:center}.nvtooltip span{display:inline-block;margin:2px 0}.nvtooltip table{margin:6px;border-spacing:0}.nvtooltip table td{padding:2px 9px 2px 0;vertical-align:middle}.nvtooltip table td.key{font-weight:400}.nvtooltip table td.value{text-align:right;font-weight:700}.nvtooltip table tr.highlight td{padding:1px 9px 1px 0;border-bottom-style:solid;border-bottom-width:1px;border-top-style:solid;border-top-width:1px}.nvtooltip table td.legend-color-guide div{width:8px;height:8px;vertical-align:middle}.nvtooltip table td.legend-color-guide div{width:12px;height:12px;border:1px solid #999}.nvtooltip .footer{padding:3px;text-align:center}.nvtooltip-pending-removal{pointer-events:none;display:none}.nvd3 .nv-interactiveGuideLine{pointer-events:none}.nvd3 line.nv-guideline{stroke:#ccc} \ No newline at end of file diff --git a/backend/coverage-report-final/_css/octicons.css b/backend/coverage-report-final/_css/octicons.css deleted file mode 100644 index 31d97867..00000000 --- a/backend/coverage-report-final/_css/octicons.css +++ /dev/null @@ -1,5 +0,0 @@ -.octicon { - display: inline-block; - vertical-align: text-top; - fill: currentColor; -} diff --git a/backend/coverage-report-final/_css/style.css b/backend/coverage-report-final/_css/style.css deleted file mode 100644 index b007558e..00000000 --- a/backend/coverage-report-final/_css/style.css +++ /dev/null @@ -1,201 +0,0 @@ -:root { - --phpunit-breadcrumbs: var(--bs-gray-200); - --phpunit-success-bar: #28a745; - --phpunit-success-high: #99cb84; - --phpunit-success-medium: #c3e3b5; - --phpunit-success-low: #dff0d8; - --phpunit-warning: #fcf8e3; - --phpunit-warning-bar: #ffc107; - --phpunit-danger: #f2dede; - --phpunit-danger-bar: #dc3545; -} - -body { - font-family: sans-serif; - font-size: 1em; - font-kerning: normal; - text-rendering: optimizeLegibility; - padding-top: 10px; -} - -nav .breadcrumb { - border-radius: var(--bs-border-radius); - background-color: var(--phpunit-breadcrumbs); - padding: .75rem 1rem; -} - -.popover { - max-width: none; -} - -.popover-body { - max-height: 90vh; - overflow-y: auto; -} - -.octicon { - margin-right:.25em; - vertical-align: baseline; - width: 0.75em; -} - -.table-bordered>thead>tr>td { - border-bottom-width: 1px; -} - -.table tbody>tr>td, .table thead>tr>td { - padding-top: 3px; - padding-bottom: 3px; -} - -.table-condensed tbody>tr>td { - padding-top: 0; - padding-bottom: 0; -} - -.table .progress { - margin-bottom: inherit; -} - -.table-borderless th, .table-borderless td { - border: 0 !important; -} - -.table tbody tr.covered-by-large-tests, .table tbody tr.covered-by-large-tests td, li.covered-by-large-tests, tr.success, tr.success td, td.success, li.success, span.success { - background-color: var(--phpunit-success-low); -} - -.table tbody tr.covered-by-medium-tests, .table tbody tr.covered-by-medium-tests td, li.covered-by-medium-tests { - background-color: var(--phpunit-success-medium); -} - -.table tbody tr.covered-by-small-tests, .table tbody tr.covered-by-small-tests td, li.covered-by-small-tests { - background-color: var(--phpunit-success-high); -} - -.table tbody tr.warning, .table tbody tr.warning td, .table tbody td.warning, li.warning, span.warning { - background-color: var(--phpunit-warning); -} - -.table tbody tr.danger, .table tbody tr.danger td, .table tbody td.danger, li.danger, span.danger { - background-color: var(--phpunit-danger); -} - -.table tbody td.info { - background-color: rgb(from var(--bs-info) r g b / 0.25); -} - -td.big { - vertical-align: middle; - width: 117px; -} - -td.small { -} - -td.codeLine { - font-family: "Source Code Pro", var(--bs-font-monospace); - white-space: pre-wrap; -} - -td span.comment { - color: var(--bs-secondary-color); -} - -td span.default { - color: var(--bs-body-color); -} - -td span.html { - color: var(--bs-secondary-color); -} - -td span.keyword { - color: var(--bs-body-color); - font-weight: bold; -} - -pre span.string { - color: var(--bs-body-color); -} - -span.success, span.warning, span.danger { - margin-right: 2px; - padding-left: 10px; - padding-right: 10px; - text-align: center; -} - -#toplink { - position: fixed; - left: 5px; - bottom: 5px; - outline: 0; -} - -svg text { - font-family: var(--bs-font-sans-serif); - font-size: 11px; - color: var(--bs-gray); - fill: var(--bs-gray); -} - -.scrollbox { - height:245px; - overflow-x:scroll; - overflow-y:scroll; -} - -table + .structure-heading { - border-top: 1px solid var(--bs-gray-200); - padding-top: 0.5em; -} - -table#code td:first-of-type { - padding-left: .75em; - padding-right: .75em; -} - -table#code td:first-of-type a { - text-decoration: none; -} - -.legend { - font-weight: bold; - margin-right: 2px; - padding-left: 10px; - padding-right: 10px; - text-align: center; -} - -.covered-by-small-tests { - background-color: var(--phpunit-success-high); -} - -.covered-by-medium-tests { - background-color: var(--phpunit-success-medium); -} - -.covered-by-large-tests { - background-color: var(--phpunit-success-low); -} - -.not-covered { - background-color: var(--phpunit-danger); -} - -.not-coverable { - background-color: var(--phpunit-warning); -} - -.progress-bar.bg-success { - background-color: var(--phpunit-success-bar) !important; -} - -.progress-bar.bg-warning { - background-color: var(--phpunit-warning-bar) !important; -} - -.progress-bar.bg-danger { - background-color: var(--phpunit-danger-bar) !important; -} \ No newline at end of file diff --git a/backend/coverage-report-final/_icons/file-code.svg b/backend/coverage-report-final/_icons/file-code.svg deleted file mode 100644 index 5b4b1995..00000000 --- a/backend/coverage-report-final/_icons/file-code.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/backend/coverage-report-final/_icons/file-directory.svg b/backend/coverage-report-final/_icons/file-directory.svg deleted file mode 100644 index 4bf1f1ca..00000000 --- a/backend/coverage-report-final/_icons/file-directory.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/backend/coverage-report-final/_js/bootstrap.bundle.min.js b/backend/coverage-report-final/_js/bootstrap.bundle.min.js deleted file mode 100644 index 8739c91c..00000000 --- a/backend/coverage-report-final/_js/bootstrap.bundle.min.js +++ /dev/null @@ -1,7 +0,0 @@ -/*! - * Bootstrap v5.3.6 (https://getbootstrap.com/) - * Copyright 2011-2025 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors) - * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) - */ -!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):(t="undefined"!=typeof globalThis?globalThis:t||self).bootstrap=e()}(this,(function(){"use strict";const t=new Map,e={set(e,i,n){t.has(e)||t.set(e,new Map);const s=t.get(e);s.has(i)||0===s.size?s.set(i,n):console.error(`Bootstrap doesn't allow more than one instance per element. Bound instance: ${Array.from(s.keys())[0]}.`)},get:(e,i)=>t.has(e)&&t.get(e).get(i)||null,remove(e,i){if(!t.has(e))return;const n=t.get(e);n.delete(i),0===n.size&&t.delete(e)}},i="transitionend",n=t=>(t&&window.CSS&&window.CSS.escape&&(t=t.replace(/#([^\s"#']+)/g,((t,e)=>`#${CSS.escape(e)}`))),t),s=t=>{t.dispatchEvent(new Event(i))},o=t=>!(!t||"object"!=typeof t)&&(void 0!==t.jquery&&(t=t[0]),void 0!==t.nodeType),r=t=>o(t)?t.jquery?t[0]:t:"string"==typeof t&&t.length>0?document.querySelector(n(t)):null,a=t=>{if(!o(t)||0===t.getClientRects().length)return!1;const e="visible"===getComputedStyle(t).getPropertyValue("visibility"),i=t.closest("details:not([open])");if(!i)return e;if(i!==t){const e=t.closest("summary");if(e&&e.parentNode!==i)return!1;if(null===e)return!1}return e},l=t=>!t||t.nodeType!==Node.ELEMENT_NODE||!!t.classList.contains("disabled")||(void 0!==t.disabled?t.disabled:t.hasAttribute("disabled")&&"false"!==t.getAttribute("disabled")),c=t=>{if(!document.documentElement.attachShadow)return null;if("function"==typeof t.getRootNode){const e=t.getRootNode();return e instanceof ShadowRoot?e:null}return t instanceof ShadowRoot?t:t.parentNode?c(t.parentNode):null},h=()=>{},d=t=>{t.offsetHeight},u=()=>window.jQuery&&!document.body.hasAttribute("data-bs-no-jquery")?window.jQuery:null,f=[],p=()=>"rtl"===document.documentElement.dir,m=t=>{var e;e=()=>{const e=u();if(e){const i=t.NAME,n=e.fn[i];e.fn[i]=t.jQueryInterface,e.fn[i].Constructor=t,e.fn[i].noConflict=()=>(e.fn[i]=n,t.jQueryInterface)}},"loading"===document.readyState?(f.length||document.addEventListener("DOMContentLoaded",(()=>{for(const t of f)t()})),f.push(e)):e()},g=(t,e=[],i=t)=>"function"==typeof t?t.call(...e):i,_=(t,e,n=!0)=>{if(!n)return void g(t);const o=(t=>{if(!t)return 0;let{transitionDuration:e,transitionDelay:i}=window.getComputedStyle(t);const n=Number.parseFloat(e),s=Number.parseFloat(i);return n||s?(e=e.split(",")[0],i=i.split(",")[0],1e3*(Number.parseFloat(e)+Number.parseFloat(i))):0})(e)+5;let r=!1;const a=({target:n})=>{n===e&&(r=!0,e.removeEventListener(i,a),g(t))};e.addEventListener(i,a),setTimeout((()=>{r||s(e)}),o)},b=(t,e,i,n)=>{const s=t.length;let o=t.indexOf(e);return-1===o?!i&&n?t[s-1]:t[0]:(o+=i?1:-1,n&&(o=(o+s)%s),t[Math.max(0,Math.min(o,s-1))])},v=/[^.]*(?=\..*)\.|.*/,y=/\..*/,w=/::\d+$/,A={};let E=1;const T={mouseenter:"mouseover",mouseleave:"mouseout"},C=new Set(["click","dblclick","mouseup","mousedown","contextmenu","mousewheel","DOMMouseScroll","mouseover","mouseout","mousemove","selectstart","selectend","keydown","keypress","keyup","orientationchange","touchstart","touchmove","touchend","touchcancel","pointerdown","pointermove","pointerup","pointerleave","pointercancel","gesturestart","gesturechange","gestureend","focus","blur","change","reset","select","submit","focusin","focusout","load","unload","beforeunload","resize","move","DOMContentLoaded","readystatechange","error","abort","scroll"]);function O(t,e){return e&&`${e}::${E++}`||t.uidEvent||E++}function x(t){const e=O(t);return t.uidEvent=e,A[e]=A[e]||{},A[e]}function k(t,e,i=null){return Object.values(t).find((t=>t.callable===e&&t.delegationSelector===i))}function L(t,e,i){const n="string"==typeof e,s=n?i:e||i;let o=I(t);return C.has(o)||(o=t),[n,s,o]}function S(t,e,i,n,s){if("string"!=typeof e||!t)return;let[o,r,a]=L(e,i,n);if(e in T){const t=t=>function(e){if(!e.relatedTarget||e.relatedTarget!==e.delegateTarget&&!e.delegateTarget.contains(e.relatedTarget))return t.call(this,e)};r=t(r)}const l=x(t),c=l[a]||(l[a]={}),h=k(c,r,o?i:null);if(h)return void(h.oneOff=h.oneOff&&s);const d=O(r,e.replace(v,"")),u=o?function(t,e,i){return function n(s){const o=t.querySelectorAll(e);for(let{target:r}=s;r&&r!==this;r=r.parentNode)for(const a of o)if(a===r)return P(s,{delegateTarget:r}),n.oneOff&&N.off(t,s.type,e,i),i.apply(r,[s])}}(t,i,r):function(t,e){return function i(n){return P(n,{delegateTarget:t}),i.oneOff&&N.off(t,n.type,e),e.apply(t,[n])}}(t,r);u.delegationSelector=o?i:null,u.callable=r,u.oneOff=s,u.uidEvent=d,c[d]=u,t.addEventListener(a,u,o)}function D(t,e,i,n,s){const o=k(e[i],n,s);o&&(t.removeEventListener(i,o,Boolean(s)),delete e[i][o.uidEvent])}function $(t,e,i,n){const s=e[i]||{};for(const[o,r]of Object.entries(s))o.includes(n)&&D(t,e,i,r.callable,r.delegationSelector)}function I(t){return t=t.replace(y,""),T[t]||t}const N={on(t,e,i,n){S(t,e,i,n,!1)},one(t,e,i,n){S(t,e,i,n,!0)},off(t,e,i,n){if("string"!=typeof e||!t)return;const[s,o,r]=L(e,i,n),a=r!==e,l=x(t),c=l[r]||{},h=e.startsWith(".");if(void 0===o){if(h)for(const i of Object.keys(l))$(t,l,i,e.slice(1));for(const[i,n]of Object.entries(c)){const s=i.replace(w,"");a&&!e.includes(s)||D(t,l,r,n.callable,n.delegationSelector)}}else{if(!Object.keys(c).length)return;D(t,l,r,o,s?i:null)}},trigger(t,e,i){if("string"!=typeof e||!t)return null;const n=u();let s=null,o=!0,r=!0,a=!1;e!==I(e)&&n&&(s=n.Event(e,i),n(t).trigger(s),o=!s.isPropagationStopped(),r=!s.isImmediatePropagationStopped(),a=s.isDefaultPrevented());const l=P(new Event(e,{bubbles:o,cancelable:!0}),i);return a&&l.preventDefault(),r&&t.dispatchEvent(l),l.defaultPrevented&&s&&s.preventDefault(),l}};function P(t,e={}){for(const[i,n]of Object.entries(e))try{t[i]=n}catch(e){Object.defineProperty(t,i,{configurable:!0,get:()=>n})}return t}function j(t){if("true"===t)return!0;if("false"===t)return!1;if(t===Number(t).toString())return Number(t);if(""===t||"null"===t)return null;if("string"!=typeof t)return t;try{return JSON.parse(decodeURIComponent(t))}catch(e){return t}}function M(t){return t.replace(/[A-Z]/g,(t=>`-${t.toLowerCase()}`))}const F={setDataAttribute(t,e,i){t.setAttribute(`data-bs-${M(e)}`,i)},removeDataAttribute(t,e){t.removeAttribute(`data-bs-${M(e)}`)},getDataAttributes(t){if(!t)return{};const e={},i=Object.keys(t.dataset).filter((t=>t.startsWith("bs")&&!t.startsWith("bsConfig")));for(const n of i){let i=n.replace(/^bs/,"");i=i.charAt(0).toLowerCase()+i.slice(1),e[i]=j(t.dataset[n])}return e},getDataAttribute:(t,e)=>j(t.getAttribute(`data-bs-${M(e)}`))};class H{static get Default(){return{}}static get DefaultType(){return{}}static get NAME(){throw new Error('You have to implement the static method "NAME", for each component!')}_getConfig(t){return t=this._mergeConfigObj(t),t=this._configAfterMerge(t),this._typeCheckConfig(t),t}_configAfterMerge(t){return t}_mergeConfigObj(t,e){const i=o(e)?F.getDataAttribute(e,"config"):{};return{...this.constructor.Default,..."object"==typeof i?i:{},...o(e)?F.getDataAttributes(e):{},..."object"==typeof t?t:{}}}_typeCheckConfig(t,e=this.constructor.DefaultType){for(const[n,s]of Object.entries(e)){const e=t[n],r=o(e)?"element":null==(i=e)?`${i}`:Object.prototype.toString.call(i).match(/\s([a-z]+)/i)[1].toLowerCase();if(!new RegExp(s).test(r))throw new TypeError(`${this.constructor.NAME.toUpperCase()}: Option "${n}" provided type "${r}" but expected type "${s}".`)}var i}}class W extends H{constructor(t,i){super(),(t=r(t))&&(this._element=t,this._config=this._getConfig(i),e.set(this._element,this.constructor.DATA_KEY,this))}dispose(){e.remove(this._element,this.constructor.DATA_KEY),N.off(this._element,this.constructor.EVENT_KEY);for(const t of Object.getOwnPropertyNames(this))this[t]=null}_queueCallback(t,e,i=!0){_(t,e,i)}_getConfig(t){return t=this._mergeConfigObj(t,this._element),t=this._configAfterMerge(t),this._typeCheckConfig(t),t}static getInstance(t){return e.get(r(t),this.DATA_KEY)}static getOrCreateInstance(t,e={}){return this.getInstance(t)||new this(t,"object"==typeof e?e:null)}static get VERSION(){return"5.3.6"}static get DATA_KEY(){return`bs.${this.NAME}`}static get EVENT_KEY(){return`.${this.DATA_KEY}`}static eventName(t){return`${t}${this.EVENT_KEY}`}}const B=t=>{let e=t.getAttribute("data-bs-target");if(!e||"#"===e){let i=t.getAttribute("href");if(!i||!i.includes("#")&&!i.startsWith("."))return null;i.includes("#")&&!i.startsWith("#")&&(i=`#${i.split("#")[1]}`),e=i&&"#"!==i?i.trim():null}return e?e.split(",").map((t=>n(t))).join(","):null},z={find:(t,e=document.documentElement)=>[].concat(...Element.prototype.querySelectorAll.call(e,t)),findOne:(t,e=document.documentElement)=>Element.prototype.querySelector.call(e,t),children:(t,e)=>[].concat(...t.children).filter((t=>t.matches(e))),parents(t,e){const i=[];let n=t.parentNode.closest(e);for(;n;)i.push(n),n=n.parentNode.closest(e);return i},prev(t,e){let i=t.previousElementSibling;for(;i;){if(i.matches(e))return[i];i=i.previousElementSibling}return[]},next(t,e){let i=t.nextElementSibling;for(;i;){if(i.matches(e))return[i];i=i.nextElementSibling}return[]},focusableChildren(t){const e=["a","button","input","textarea","select","details","[tabindex]",'[contenteditable="true"]'].map((t=>`${t}:not([tabindex^="-"])`)).join(",");return this.find(e,t).filter((t=>!l(t)&&a(t)))},getSelectorFromElement(t){const e=B(t);return e&&z.findOne(e)?e:null},getElementFromSelector(t){const e=B(t);return e?z.findOne(e):null},getMultipleElementsFromSelector(t){const e=B(t);return e?z.find(e):[]}},R=(t,e="hide")=>{const i=`click.dismiss${t.EVENT_KEY}`,n=t.NAME;N.on(document,i,`[data-bs-dismiss="${n}"]`,(function(i){if(["A","AREA"].includes(this.tagName)&&i.preventDefault(),l(this))return;const s=z.getElementFromSelector(this)||this.closest(`.${n}`);t.getOrCreateInstance(s)[e]()}))},q=".bs.alert",V=`close${q}`,K=`closed${q}`;class Q extends W{static get NAME(){return"alert"}close(){if(N.trigger(this._element,V).defaultPrevented)return;this._element.classList.remove("show");const t=this._element.classList.contains("fade");this._queueCallback((()=>this._destroyElement()),this._element,t)}_destroyElement(){this._element.remove(),N.trigger(this._element,K),this.dispose()}static jQueryInterface(t){return this.each((function(){const e=Q.getOrCreateInstance(this);if("string"==typeof t){if(void 0===e[t]||t.startsWith("_")||"constructor"===t)throw new TypeError(`No method named "${t}"`);e[t](this)}}))}}R(Q,"close"),m(Q);const X='[data-bs-toggle="button"]';class Y extends W{static get NAME(){return"button"}toggle(){this._element.setAttribute("aria-pressed",this._element.classList.toggle("active"))}static jQueryInterface(t){return this.each((function(){const e=Y.getOrCreateInstance(this);"toggle"===t&&e[t]()}))}}N.on(document,"click.bs.button.data-api",X,(t=>{t.preventDefault();const e=t.target.closest(X);Y.getOrCreateInstance(e).toggle()})),m(Y);const U=".bs.swipe",G=`touchstart${U}`,J=`touchmove${U}`,Z=`touchend${U}`,tt=`pointerdown${U}`,et=`pointerup${U}`,it={endCallback:null,leftCallback:null,rightCallback:null},nt={endCallback:"(function|null)",leftCallback:"(function|null)",rightCallback:"(function|null)"};class st extends H{constructor(t,e){super(),this._element=t,t&&st.isSupported()&&(this._config=this._getConfig(e),this._deltaX=0,this._supportPointerEvents=Boolean(window.PointerEvent),this._initEvents())}static get Default(){return it}static get DefaultType(){return nt}static get NAME(){return"swipe"}dispose(){N.off(this._element,U)}_start(t){this._supportPointerEvents?this._eventIsPointerPenTouch(t)&&(this._deltaX=t.clientX):this._deltaX=t.touches[0].clientX}_end(t){this._eventIsPointerPenTouch(t)&&(this._deltaX=t.clientX-this._deltaX),this._handleSwipe(),g(this._config.endCallback)}_move(t){this._deltaX=t.touches&&t.touches.length>1?0:t.touches[0].clientX-this._deltaX}_handleSwipe(){const t=Math.abs(this._deltaX);if(t<=40)return;const e=t/this._deltaX;this._deltaX=0,e&&g(e>0?this._config.rightCallback:this._config.leftCallback)}_initEvents(){this._supportPointerEvents?(N.on(this._element,tt,(t=>this._start(t))),N.on(this._element,et,(t=>this._end(t))),this._element.classList.add("pointer-event")):(N.on(this._element,G,(t=>this._start(t))),N.on(this._element,J,(t=>this._move(t))),N.on(this._element,Z,(t=>this._end(t))))}_eventIsPointerPenTouch(t){return this._supportPointerEvents&&("pen"===t.pointerType||"touch"===t.pointerType)}static isSupported(){return"ontouchstart"in document.documentElement||navigator.maxTouchPoints>0}}const ot=".bs.carousel",rt=".data-api",at="ArrowLeft",lt="ArrowRight",ct="next",ht="prev",dt="left",ut="right",ft=`slide${ot}`,pt=`slid${ot}`,mt=`keydown${ot}`,gt=`mouseenter${ot}`,_t=`mouseleave${ot}`,bt=`dragstart${ot}`,vt=`load${ot}${rt}`,yt=`click${ot}${rt}`,wt="carousel",At="active",Et=".active",Tt=".carousel-item",Ct=Et+Tt,Ot={[at]:ut,[lt]:dt},xt={interval:5e3,keyboard:!0,pause:"hover",ride:!1,touch:!0,wrap:!0},kt={interval:"(number|boolean)",keyboard:"boolean",pause:"(string|boolean)",ride:"(boolean|string)",touch:"boolean",wrap:"boolean"};class Lt extends W{constructor(t,e){super(t,e),this._interval=null,this._activeElement=null,this._isSliding=!1,this.touchTimeout=null,this._swipeHelper=null,this._indicatorsElement=z.findOne(".carousel-indicators",this._element),this._addEventListeners(),this._config.ride===wt&&this.cycle()}static get Default(){return xt}static get DefaultType(){return kt}static get NAME(){return"carousel"}next(){this._slide(ct)}nextWhenVisible(){!document.hidden&&a(this._element)&&this.next()}prev(){this._slide(ht)}pause(){this._isSliding&&s(this._element),this._clearInterval()}cycle(){this._clearInterval(),this._updateInterval(),this._interval=setInterval((()=>this.nextWhenVisible()),this._config.interval)}_maybeEnableCycle(){this._config.ride&&(this._isSliding?N.one(this._element,pt,(()=>this.cycle())):this.cycle())}to(t){const e=this._getItems();if(t>e.length-1||t<0)return;if(this._isSliding)return void N.one(this._element,pt,(()=>this.to(t)));const i=this._getItemIndex(this._getActive());if(i===t)return;const n=t>i?ct:ht;this._slide(n,e[t])}dispose(){this._swipeHelper&&this._swipeHelper.dispose(),super.dispose()}_configAfterMerge(t){return t.defaultInterval=t.interval,t}_addEventListeners(){this._config.keyboard&&N.on(this._element,mt,(t=>this._keydown(t))),"hover"===this._config.pause&&(N.on(this._element,gt,(()=>this.pause())),N.on(this._element,_t,(()=>this._maybeEnableCycle()))),this._config.touch&&st.isSupported()&&this._addTouchEventListeners()}_addTouchEventListeners(){for(const t of z.find(".carousel-item img",this._element))N.on(t,bt,(t=>t.preventDefault()));const t={leftCallback:()=>this._slide(this._directionToOrder(dt)),rightCallback:()=>this._slide(this._directionToOrder(ut)),endCallback:()=>{"hover"===this._config.pause&&(this.pause(),this.touchTimeout&&clearTimeout(this.touchTimeout),this.touchTimeout=setTimeout((()=>this._maybeEnableCycle()),500+this._config.interval))}};this._swipeHelper=new st(this._element,t)}_keydown(t){if(/input|textarea/i.test(t.target.tagName))return;const e=Ot[t.key];e&&(t.preventDefault(),this._slide(this._directionToOrder(e)))}_getItemIndex(t){return this._getItems().indexOf(t)}_setActiveIndicatorElement(t){if(!this._indicatorsElement)return;const e=z.findOne(Et,this._indicatorsElement);e.classList.remove(At),e.removeAttribute("aria-current");const i=z.findOne(`[data-bs-slide-to="${t}"]`,this._indicatorsElement);i&&(i.classList.add(At),i.setAttribute("aria-current","true"))}_updateInterval(){const t=this._activeElement||this._getActive();if(!t)return;const e=Number.parseInt(t.getAttribute("data-bs-interval"),10);this._config.interval=e||this._config.defaultInterval}_slide(t,e=null){if(this._isSliding)return;const i=this._getActive(),n=t===ct,s=e||b(this._getItems(),i,n,this._config.wrap);if(s===i)return;const o=this._getItemIndex(s),r=e=>N.trigger(this._element,e,{relatedTarget:s,direction:this._orderToDirection(t),from:this._getItemIndex(i),to:o});if(r(ft).defaultPrevented)return;if(!i||!s)return;const a=Boolean(this._interval);this.pause(),this._isSliding=!0,this._setActiveIndicatorElement(o),this._activeElement=s;const l=n?"carousel-item-start":"carousel-item-end",c=n?"carousel-item-next":"carousel-item-prev";s.classList.add(c),d(s),i.classList.add(l),s.classList.add(l),this._queueCallback((()=>{s.classList.remove(l,c),s.classList.add(At),i.classList.remove(At,c,l),this._isSliding=!1,r(pt)}),i,this._isAnimated()),a&&this.cycle()}_isAnimated(){return this._element.classList.contains("slide")}_getActive(){return z.findOne(Ct,this._element)}_getItems(){return z.find(Tt,this._element)}_clearInterval(){this._interval&&(clearInterval(this._interval),this._interval=null)}_directionToOrder(t){return p()?t===dt?ht:ct:t===dt?ct:ht}_orderToDirection(t){return p()?t===ht?dt:ut:t===ht?ut:dt}static jQueryInterface(t){return this.each((function(){const e=Lt.getOrCreateInstance(this,t);if("number"!=typeof t){if("string"==typeof t){if(void 0===e[t]||t.startsWith("_")||"constructor"===t)throw new TypeError(`No method named "${t}"`);e[t]()}}else e.to(t)}))}}N.on(document,yt,"[data-bs-slide], [data-bs-slide-to]",(function(t){const e=z.getElementFromSelector(this);if(!e||!e.classList.contains(wt))return;t.preventDefault();const i=Lt.getOrCreateInstance(e),n=this.getAttribute("data-bs-slide-to");return n?(i.to(n),void i._maybeEnableCycle()):"next"===F.getDataAttribute(this,"slide")?(i.next(),void i._maybeEnableCycle()):(i.prev(),void i._maybeEnableCycle())})),N.on(window,vt,(()=>{const t=z.find('[data-bs-ride="carousel"]');for(const e of t)Lt.getOrCreateInstance(e)})),m(Lt);const St=".bs.collapse",Dt=`show${St}`,$t=`shown${St}`,It=`hide${St}`,Nt=`hidden${St}`,Pt=`click${St}.data-api`,jt="show",Mt="collapse",Ft="collapsing",Ht=`:scope .${Mt} .${Mt}`,Wt='[data-bs-toggle="collapse"]',Bt={parent:null,toggle:!0},zt={parent:"(null|element)",toggle:"boolean"};class Rt extends W{constructor(t,e){super(t,e),this._isTransitioning=!1,this._triggerArray=[];const i=z.find(Wt);for(const t of i){const e=z.getSelectorFromElement(t),i=z.find(e).filter((t=>t===this._element));null!==e&&i.length&&this._triggerArray.push(t)}this._initializeChildren(),this._config.parent||this._addAriaAndCollapsedClass(this._triggerArray,this._isShown()),this._config.toggle&&this.toggle()}static get Default(){return Bt}static get DefaultType(){return zt}static get NAME(){return"collapse"}toggle(){this._isShown()?this.hide():this.show()}show(){if(this._isTransitioning||this._isShown())return;let t=[];if(this._config.parent&&(t=this._getFirstLevelChildren(".collapse.show, .collapse.collapsing").filter((t=>t!==this._element)).map((t=>Rt.getOrCreateInstance(t,{toggle:!1})))),t.length&&t[0]._isTransitioning)return;if(N.trigger(this._element,Dt).defaultPrevented)return;for(const e of t)e.hide();const e=this._getDimension();this._element.classList.remove(Mt),this._element.classList.add(Ft),this._element.style[e]=0,this._addAriaAndCollapsedClass(this._triggerArray,!0),this._isTransitioning=!0;const i=`scroll${e[0].toUpperCase()+e.slice(1)}`;this._queueCallback((()=>{this._isTransitioning=!1,this._element.classList.remove(Ft),this._element.classList.add(Mt,jt),this._element.style[e]="",N.trigger(this._element,$t)}),this._element,!0),this._element.style[e]=`${this._element[i]}px`}hide(){if(this._isTransitioning||!this._isShown())return;if(N.trigger(this._element,It).defaultPrevented)return;const t=this._getDimension();this._element.style[t]=`${this._element.getBoundingClientRect()[t]}px`,d(this._element),this._element.classList.add(Ft),this._element.classList.remove(Mt,jt);for(const t of this._triggerArray){const e=z.getElementFromSelector(t);e&&!this._isShown(e)&&this._addAriaAndCollapsedClass([t],!1)}this._isTransitioning=!0,this._element.style[t]="",this._queueCallback((()=>{this._isTransitioning=!1,this._element.classList.remove(Ft),this._element.classList.add(Mt),N.trigger(this._element,Nt)}),this._element,!0)}_isShown(t=this._element){return t.classList.contains(jt)}_configAfterMerge(t){return t.toggle=Boolean(t.toggle),t.parent=r(t.parent),t}_getDimension(){return this._element.classList.contains("collapse-horizontal")?"width":"height"}_initializeChildren(){if(!this._config.parent)return;const t=this._getFirstLevelChildren(Wt);for(const e of t){const t=z.getElementFromSelector(e);t&&this._addAriaAndCollapsedClass([e],this._isShown(t))}}_getFirstLevelChildren(t){const e=z.find(Ht,this._config.parent);return z.find(t,this._config.parent).filter((t=>!e.includes(t)))}_addAriaAndCollapsedClass(t,e){if(t.length)for(const i of t)i.classList.toggle("collapsed",!e),i.setAttribute("aria-expanded",e)}static jQueryInterface(t){const e={};return"string"==typeof t&&/show|hide/.test(t)&&(e.toggle=!1),this.each((function(){const i=Rt.getOrCreateInstance(this,e);if("string"==typeof t){if(void 0===i[t])throw new TypeError(`No method named "${t}"`);i[t]()}}))}}N.on(document,Pt,Wt,(function(t){("A"===t.target.tagName||t.delegateTarget&&"A"===t.delegateTarget.tagName)&&t.preventDefault();for(const t of z.getMultipleElementsFromSelector(this))Rt.getOrCreateInstance(t,{toggle:!1}).toggle()})),m(Rt);var qt="top",Vt="bottom",Kt="right",Qt="left",Xt="auto",Yt=[qt,Vt,Kt,Qt],Ut="start",Gt="end",Jt="clippingParents",Zt="viewport",te="popper",ee="reference",ie=Yt.reduce((function(t,e){return t.concat([e+"-"+Ut,e+"-"+Gt])}),[]),ne=[].concat(Yt,[Xt]).reduce((function(t,e){return t.concat([e,e+"-"+Ut,e+"-"+Gt])}),[]),se="beforeRead",oe="read",re="afterRead",ae="beforeMain",le="main",ce="afterMain",he="beforeWrite",de="write",ue="afterWrite",fe=[se,oe,re,ae,le,ce,he,de,ue];function pe(t){return t?(t.nodeName||"").toLowerCase():null}function me(t){if(null==t)return window;if("[object Window]"!==t.toString()){var e=t.ownerDocument;return e&&e.defaultView||window}return t}function ge(t){return t instanceof me(t).Element||t instanceof Element}function _e(t){return t instanceof me(t).HTMLElement||t instanceof HTMLElement}function be(t){return"undefined"!=typeof ShadowRoot&&(t instanceof me(t).ShadowRoot||t instanceof ShadowRoot)}const ve={name:"applyStyles",enabled:!0,phase:"write",fn:function(t){var e=t.state;Object.keys(e.elements).forEach((function(t){var i=e.styles[t]||{},n=e.attributes[t]||{},s=e.elements[t];_e(s)&&pe(s)&&(Object.assign(s.style,i),Object.keys(n).forEach((function(t){var e=n[t];!1===e?s.removeAttribute(t):s.setAttribute(t,!0===e?"":e)})))}))},effect:function(t){var e=t.state,i={popper:{position:e.options.strategy,left:"0",top:"0",margin:"0"},arrow:{position:"absolute"},reference:{}};return Object.assign(e.elements.popper.style,i.popper),e.styles=i,e.elements.arrow&&Object.assign(e.elements.arrow.style,i.arrow),function(){Object.keys(e.elements).forEach((function(t){var n=e.elements[t],s=e.attributes[t]||{},o=Object.keys(e.styles.hasOwnProperty(t)?e.styles[t]:i[t]).reduce((function(t,e){return t[e]="",t}),{});_e(n)&&pe(n)&&(Object.assign(n.style,o),Object.keys(s).forEach((function(t){n.removeAttribute(t)})))}))}},requires:["computeStyles"]};function ye(t){return t.split("-")[0]}var we=Math.max,Ae=Math.min,Ee=Math.round;function Te(){var t=navigator.userAgentData;return null!=t&&t.brands&&Array.isArray(t.brands)?t.brands.map((function(t){return t.brand+"/"+t.version})).join(" "):navigator.userAgent}function Ce(){return!/^((?!chrome|android).)*safari/i.test(Te())}function Oe(t,e,i){void 0===e&&(e=!1),void 0===i&&(i=!1);var n=t.getBoundingClientRect(),s=1,o=1;e&&_e(t)&&(s=t.offsetWidth>0&&Ee(n.width)/t.offsetWidth||1,o=t.offsetHeight>0&&Ee(n.height)/t.offsetHeight||1);var r=(ge(t)?me(t):window).visualViewport,a=!Ce()&&i,l=(n.left+(a&&r?r.offsetLeft:0))/s,c=(n.top+(a&&r?r.offsetTop:0))/o,h=n.width/s,d=n.height/o;return{width:h,height:d,top:c,right:l+h,bottom:c+d,left:l,x:l,y:c}}function xe(t){var e=Oe(t),i=t.offsetWidth,n=t.offsetHeight;return Math.abs(e.width-i)<=1&&(i=e.width),Math.abs(e.height-n)<=1&&(n=e.height),{x:t.offsetLeft,y:t.offsetTop,width:i,height:n}}function ke(t,e){var i=e.getRootNode&&e.getRootNode();if(t.contains(e))return!0;if(i&&be(i)){var n=e;do{if(n&&t.isSameNode(n))return!0;n=n.parentNode||n.host}while(n)}return!1}function Le(t){return me(t).getComputedStyle(t)}function Se(t){return["table","td","th"].indexOf(pe(t))>=0}function De(t){return((ge(t)?t.ownerDocument:t.document)||window.document).documentElement}function $e(t){return"html"===pe(t)?t:t.assignedSlot||t.parentNode||(be(t)?t.host:null)||De(t)}function Ie(t){return _e(t)&&"fixed"!==Le(t).position?t.offsetParent:null}function Ne(t){for(var e=me(t),i=Ie(t);i&&Se(i)&&"static"===Le(i).position;)i=Ie(i);return i&&("html"===pe(i)||"body"===pe(i)&&"static"===Le(i).position)?e:i||function(t){var e=/firefox/i.test(Te());if(/Trident/i.test(Te())&&_e(t)&&"fixed"===Le(t).position)return null;var i=$e(t);for(be(i)&&(i=i.host);_e(i)&&["html","body"].indexOf(pe(i))<0;){var n=Le(i);if("none"!==n.transform||"none"!==n.perspective||"paint"===n.contain||-1!==["transform","perspective"].indexOf(n.willChange)||e&&"filter"===n.willChange||e&&n.filter&&"none"!==n.filter)return i;i=i.parentNode}return null}(t)||e}function Pe(t){return["top","bottom"].indexOf(t)>=0?"x":"y"}function je(t,e,i){return we(t,Ae(e,i))}function Me(t){return Object.assign({},{top:0,right:0,bottom:0,left:0},t)}function Fe(t,e){return e.reduce((function(e,i){return e[i]=t,e}),{})}const He={name:"arrow",enabled:!0,phase:"main",fn:function(t){var e,i=t.state,n=t.name,s=t.options,o=i.elements.arrow,r=i.modifiersData.popperOffsets,a=ye(i.placement),l=Pe(a),c=[Qt,Kt].indexOf(a)>=0?"height":"width";if(o&&r){var h=function(t,e){return Me("number"!=typeof(t="function"==typeof t?t(Object.assign({},e.rects,{placement:e.placement})):t)?t:Fe(t,Yt))}(s.padding,i),d=xe(o),u="y"===l?qt:Qt,f="y"===l?Vt:Kt,p=i.rects.reference[c]+i.rects.reference[l]-r[l]-i.rects.popper[c],m=r[l]-i.rects.reference[l],g=Ne(o),_=g?"y"===l?g.clientHeight||0:g.clientWidth||0:0,b=p/2-m/2,v=h[u],y=_-d[c]-h[f],w=_/2-d[c]/2+b,A=je(v,w,y),E=l;i.modifiersData[n]=((e={})[E]=A,e.centerOffset=A-w,e)}},effect:function(t){var e=t.state,i=t.options.element,n=void 0===i?"[data-popper-arrow]":i;null!=n&&("string"!=typeof n||(n=e.elements.popper.querySelector(n)))&&ke(e.elements.popper,n)&&(e.elements.arrow=n)},requires:["popperOffsets"],requiresIfExists:["preventOverflow"]};function We(t){return t.split("-")[1]}var Be={top:"auto",right:"auto",bottom:"auto",left:"auto"};function ze(t){var e,i=t.popper,n=t.popperRect,s=t.placement,o=t.variation,r=t.offsets,a=t.position,l=t.gpuAcceleration,c=t.adaptive,h=t.roundOffsets,d=t.isFixed,u=r.x,f=void 0===u?0:u,p=r.y,m=void 0===p?0:p,g="function"==typeof h?h({x:f,y:m}):{x:f,y:m};f=g.x,m=g.y;var _=r.hasOwnProperty("x"),b=r.hasOwnProperty("y"),v=Qt,y=qt,w=window;if(c){var A=Ne(i),E="clientHeight",T="clientWidth";A===me(i)&&"static"!==Le(A=De(i)).position&&"absolute"===a&&(E="scrollHeight",T="scrollWidth"),(s===qt||(s===Qt||s===Kt)&&o===Gt)&&(y=Vt,m-=(d&&A===w&&w.visualViewport?w.visualViewport.height:A[E])-n.height,m*=l?1:-1),s!==Qt&&(s!==qt&&s!==Vt||o!==Gt)||(v=Kt,f-=(d&&A===w&&w.visualViewport?w.visualViewport.width:A[T])-n.width,f*=l?1:-1)}var C,O=Object.assign({position:a},c&&Be),x=!0===h?function(t,e){var i=t.x,n=t.y,s=e.devicePixelRatio||1;return{x:Ee(i*s)/s||0,y:Ee(n*s)/s||0}}({x:f,y:m},me(i)):{x:f,y:m};return f=x.x,m=x.y,l?Object.assign({},O,((C={})[y]=b?"0":"",C[v]=_?"0":"",C.transform=(w.devicePixelRatio||1)<=1?"translate("+f+"px, "+m+"px)":"translate3d("+f+"px, "+m+"px, 0)",C)):Object.assign({},O,((e={})[y]=b?m+"px":"",e[v]=_?f+"px":"",e.transform="",e))}const Re={name:"computeStyles",enabled:!0,phase:"beforeWrite",fn:function(t){var e=t.state,i=t.options,n=i.gpuAcceleration,s=void 0===n||n,o=i.adaptive,r=void 0===o||o,a=i.roundOffsets,l=void 0===a||a,c={placement:ye(e.placement),variation:We(e.placement),popper:e.elements.popper,popperRect:e.rects.popper,gpuAcceleration:s,isFixed:"fixed"===e.options.strategy};null!=e.modifiersData.popperOffsets&&(e.styles.popper=Object.assign({},e.styles.popper,ze(Object.assign({},c,{offsets:e.modifiersData.popperOffsets,position:e.options.strategy,adaptive:r,roundOffsets:l})))),null!=e.modifiersData.arrow&&(e.styles.arrow=Object.assign({},e.styles.arrow,ze(Object.assign({},c,{offsets:e.modifiersData.arrow,position:"absolute",adaptive:!1,roundOffsets:l})))),e.attributes.popper=Object.assign({},e.attributes.popper,{"data-popper-placement":e.placement})},data:{}};var qe={passive:!0};const Ve={name:"eventListeners",enabled:!0,phase:"write",fn:function(){},effect:function(t){var e=t.state,i=t.instance,n=t.options,s=n.scroll,o=void 0===s||s,r=n.resize,a=void 0===r||r,l=me(e.elements.popper),c=[].concat(e.scrollParents.reference,e.scrollParents.popper);return o&&c.forEach((function(t){t.addEventListener("scroll",i.update,qe)})),a&&l.addEventListener("resize",i.update,qe),function(){o&&c.forEach((function(t){t.removeEventListener("scroll",i.update,qe)})),a&&l.removeEventListener("resize",i.update,qe)}},data:{}};var Ke={left:"right",right:"left",bottom:"top",top:"bottom"};function Qe(t){return t.replace(/left|right|bottom|top/g,(function(t){return Ke[t]}))}var Xe={start:"end",end:"start"};function Ye(t){return t.replace(/start|end/g,(function(t){return Xe[t]}))}function Ue(t){var e=me(t);return{scrollLeft:e.pageXOffset,scrollTop:e.pageYOffset}}function Ge(t){return Oe(De(t)).left+Ue(t).scrollLeft}function Je(t){var e=Le(t),i=e.overflow,n=e.overflowX,s=e.overflowY;return/auto|scroll|overlay|hidden/.test(i+s+n)}function Ze(t){return["html","body","#document"].indexOf(pe(t))>=0?t.ownerDocument.body:_e(t)&&Je(t)?t:Ze($e(t))}function ti(t,e){var i;void 0===e&&(e=[]);var n=Ze(t),s=n===(null==(i=t.ownerDocument)?void 0:i.body),o=me(n),r=s?[o].concat(o.visualViewport||[],Je(n)?n:[]):n,a=e.concat(r);return s?a:a.concat(ti($e(r)))}function ei(t){return Object.assign({},t,{left:t.x,top:t.y,right:t.x+t.width,bottom:t.y+t.height})}function ii(t,e,i){return e===Zt?ei(function(t,e){var i=me(t),n=De(t),s=i.visualViewport,o=n.clientWidth,r=n.clientHeight,a=0,l=0;if(s){o=s.width,r=s.height;var c=Ce();(c||!c&&"fixed"===e)&&(a=s.offsetLeft,l=s.offsetTop)}return{width:o,height:r,x:a+Ge(t),y:l}}(t,i)):ge(e)?function(t,e){var i=Oe(t,!1,"fixed"===e);return i.top=i.top+t.clientTop,i.left=i.left+t.clientLeft,i.bottom=i.top+t.clientHeight,i.right=i.left+t.clientWidth,i.width=t.clientWidth,i.height=t.clientHeight,i.x=i.left,i.y=i.top,i}(e,i):ei(function(t){var e,i=De(t),n=Ue(t),s=null==(e=t.ownerDocument)?void 0:e.body,o=we(i.scrollWidth,i.clientWidth,s?s.scrollWidth:0,s?s.clientWidth:0),r=we(i.scrollHeight,i.clientHeight,s?s.scrollHeight:0,s?s.clientHeight:0),a=-n.scrollLeft+Ge(t),l=-n.scrollTop;return"rtl"===Le(s||i).direction&&(a+=we(i.clientWidth,s?s.clientWidth:0)-o),{width:o,height:r,x:a,y:l}}(De(t)))}function ni(t){var e,i=t.reference,n=t.element,s=t.placement,o=s?ye(s):null,r=s?We(s):null,a=i.x+i.width/2-n.width/2,l=i.y+i.height/2-n.height/2;switch(o){case qt:e={x:a,y:i.y-n.height};break;case Vt:e={x:a,y:i.y+i.height};break;case Kt:e={x:i.x+i.width,y:l};break;case Qt:e={x:i.x-n.width,y:l};break;default:e={x:i.x,y:i.y}}var c=o?Pe(o):null;if(null!=c){var h="y"===c?"height":"width";switch(r){case Ut:e[c]=e[c]-(i[h]/2-n[h]/2);break;case Gt:e[c]=e[c]+(i[h]/2-n[h]/2)}}return e}function si(t,e){void 0===e&&(e={});var i=e,n=i.placement,s=void 0===n?t.placement:n,o=i.strategy,r=void 0===o?t.strategy:o,a=i.boundary,l=void 0===a?Jt:a,c=i.rootBoundary,h=void 0===c?Zt:c,d=i.elementContext,u=void 0===d?te:d,f=i.altBoundary,p=void 0!==f&&f,m=i.padding,g=void 0===m?0:m,_=Me("number"!=typeof g?g:Fe(g,Yt)),b=u===te?ee:te,v=t.rects.popper,y=t.elements[p?b:u],w=function(t,e,i,n){var s="clippingParents"===e?function(t){var e=ti($e(t)),i=["absolute","fixed"].indexOf(Le(t).position)>=0&&_e(t)?Ne(t):t;return ge(i)?e.filter((function(t){return ge(t)&&ke(t,i)&&"body"!==pe(t)})):[]}(t):[].concat(e),o=[].concat(s,[i]),r=o[0],a=o.reduce((function(e,i){var s=ii(t,i,n);return e.top=we(s.top,e.top),e.right=Ae(s.right,e.right),e.bottom=Ae(s.bottom,e.bottom),e.left=we(s.left,e.left),e}),ii(t,r,n));return a.width=a.right-a.left,a.height=a.bottom-a.top,a.x=a.left,a.y=a.top,a}(ge(y)?y:y.contextElement||De(t.elements.popper),l,h,r),A=Oe(t.elements.reference),E=ni({reference:A,element:v,placement:s}),T=ei(Object.assign({},v,E)),C=u===te?T:A,O={top:w.top-C.top+_.top,bottom:C.bottom-w.bottom+_.bottom,left:w.left-C.left+_.left,right:C.right-w.right+_.right},x=t.modifiersData.offset;if(u===te&&x){var k=x[s];Object.keys(O).forEach((function(t){var e=[Kt,Vt].indexOf(t)>=0?1:-1,i=[qt,Vt].indexOf(t)>=0?"y":"x";O[t]+=k[i]*e}))}return O}function oi(t,e){void 0===e&&(e={});var i=e,n=i.placement,s=i.boundary,o=i.rootBoundary,r=i.padding,a=i.flipVariations,l=i.allowedAutoPlacements,c=void 0===l?ne:l,h=We(n),d=h?a?ie:ie.filter((function(t){return We(t)===h})):Yt,u=d.filter((function(t){return c.indexOf(t)>=0}));0===u.length&&(u=d);var f=u.reduce((function(e,i){return e[i]=si(t,{placement:i,boundary:s,rootBoundary:o,padding:r})[ye(i)],e}),{});return Object.keys(f).sort((function(t,e){return f[t]-f[e]}))}const ri={name:"flip",enabled:!0,phase:"main",fn:function(t){var e=t.state,i=t.options,n=t.name;if(!e.modifiersData[n]._skip){for(var s=i.mainAxis,o=void 0===s||s,r=i.altAxis,a=void 0===r||r,l=i.fallbackPlacements,c=i.padding,h=i.boundary,d=i.rootBoundary,u=i.altBoundary,f=i.flipVariations,p=void 0===f||f,m=i.allowedAutoPlacements,g=e.options.placement,_=ye(g),b=l||(_!==g&&p?function(t){if(ye(t)===Xt)return[];var e=Qe(t);return[Ye(t),e,Ye(e)]}(g):[Qe(g)]),v=[g].concat(b).reduce((function(t,i){return t.concat(ye(i)===Xt?oi(e,{placement:i,boundary:h,rootBoundary:d,padding:c,flipVariations:p,allowedAutoPlacements:m}):i)}),[]),y=e.rects.reference,w=e.rects.popper,A=new Map,E=!0,T=v[0],C=0;C=0,S=L?"width":"height",D=si(e,{placement:O,boundary:h,rootBoundary:d,altBoundary:u,padding:c}),$=L?k?Kt:Qt:k?Vt:qt;y[S]>w[S]&&($=Qe($));var I=Qe($),N=[];if(o&&N.push(D[x]<=0),a&&N.push(D[$]<=0,D[I]<=0),N.every((function(t){return t}))){T=O,E=!1;break}A.set(O,N)}if(E)for(var P=function(t){var e=v.find((function(e){var i=A.get(e);if(i)return i.slice(0,t).every((function(t){return t}))}));if(e)return T=e,"break"},j=p?3:1;j>0&&"break"!==P(j);j--);e.placement!==T&&(e.modifiersData[n]._skip=!0,e.placement=T,e.reset=!0)}},requiresIfExists:["offset"],data:{_skip:!1}};function ai(t,e,i){return void 0===i&&(i={x:0,y:0}),{top:t.top-e.height-i.y,right:t.right-e.width+i.x,bottom:t.bottom-e.height+i.y,left:t.left-e.width-i.x}}function li(t){return[qt,Kt,Vt,Qt].some((function(e){return t[e]>=0}))}const ci={name:"hide",enabled:!0,phase:"main",requiresIfExists:["preventOverflow"],fn:function(t){var e=t.state,i=t.name,n=e.rects.reference,s=e.rects.popper,o=e.modifiersData.preventOverflow,r=si(e,{elementContext:"reference"}),a=si(e,{altBoundary:!0}),l=ai(r,n),c=ai(a,s,o),h=li(l),d=li(c);e.modifiersData[i]={referenceClippingOffsets:l,popperEscapeOffsets:c,isReferenceHidden:h,hasPopperEscaped:d},e.attributes.popper=Object.assign({},e.attributes.popper,{"data-popper-reference-hidden":h,"data-popper-escaped":d})}},hi={name:"offset",enabled:!0,phase:"main",requires:["popperOffsets"],fn:function(t){var e=t.state,i=t.options,n=t.name,s=i.offset,o=void 0===s?[0,0]:s,r=ne.reduce((function(t,i){return t[i]=function(t,e,i){var n=ye(t),s=[Qt,qt].indexOf(n)>=0?-1:1,o="function"==typeof i?i(Object.assign({},e,{placement:t})):i,r=o[0],a=o[1];return r=r||0,a=(a||0)*s,[Qt,Kt].indexOf(n)>=0?{x:a,y:r}:{x:r,y:a}}(i,e.rects,o),t}),{}),a=r[e.placement],l=a.x,c=a.y;null!=e.modifiersData.popperOffsets&&(e.modifiersData.popperOffsets.x+=l,e.modifiersData.popperOffsets.y+=c),e.modifiersData[n]=r}},di={name:"popperOffsets",enabled:!0,phase:"read",fn:function(t){var e=t.state,i=t.name;e.modifiersData[i]=ni({reference:e.rects.reference,element:e.rects.popper,placement:e.placement})},data:{}},ui={name:"preventOverflow",enabled:!0,phase:"main",fn:function(t){var e=t.state,i=t.options,n=t.name,s=i.mainAxis,o=void 0===s||s,r=i.altAxis,a=void 0!==r&&r,l=i.boundary,c=i.rootBoundary,h=i.altBoundary,d=i.padding,u=i.tether,f=void 0===u||u,p=i.tetherOffset,m=void 0===p?0:p,g=si(e,{boundary:l,rootBoundary:c,padding:d,altBoundary:h}),_=ye(e.placement),b=We(e.placement),v=!b,y=Pe(_),w="x"===y?"y":"x",A=e.modifiersData.popperOffsets,E=e.rects.reference,T=e.rects.popper,C="function"==typeof m?m(Object.assign({},e.rects,{placement:e.placement})):m,O="number"==typeof C?{mainAxis:C,altAxis:C}:Object.assign({mainAxis:0,altAxis:0},C),x=e.modifiersData.offset?e.modifiersData.offset[e.placement]:null,k={x:0,y:0};if(A){if(o){var L,S="y"===y?qt:Qt,D="y"===y?Vt:Kt,$="y"===y?"height":"width",I=A[y],N=I+g[S],P=I-g[D],j=f?-T[$]/2:0,M=b===Ut?E[$]:T[$],F=b===Ut?-T[$]:-E[$],H=e.elements.arrow,W=f&&H?xe(H):{width:0,height:0},B=e.modifiersData["arrow#persistent"]?e.modifiersData["arrow#persistent"].padding:{top:0,right:0,bottom:0,left:0},z=B[S],R=B[D],q=je(0,E[$],W[$]),V=v?E[$]/2-j-q-z-O.mainAxis:M-q-z-O.mainAxis,K=v?-E[$]/2+j+q+R+O.mainAxis:F+q+R+O.mainAxis,Q=e.elements.arrow&&Ne(e.elements.arrow),X=Q?"y"===y?Q.clientTop||0:Q.clientLeft||0:0,Y=null!=(L=null==x?void 0:x[y])?L:0,U=I+K-Y,G=je(f?Ae(N,I+V-Y-X):N,I,f?we(P,U):P);A[y]=G,k[y]=G-I}if(a){var J,Z="x"===y?qt:Qt,tt="x"===y?Vt:Kt,et=A[w],it="y"===w?"height":"width",nt=et+g[Z],st=et-g[tt],ot=-1!==[qt,Qt].indexOf(_),rt=null!=(J=null==x?void 0:x[w])?J:0,at=ot?nt:et-E[it]-T[it]-rt+O.altAxis,lt=ot?et+E[it]+T[it]-rt-O.altAxis:st,ct=f&&ot?function(t,e,i){var n=je(t,e,i);return n>i?i:n}(at,et,lt):je(f?at:nt,et,f?lt:st);A[w]=ct,k[w]=ct-et}e.modifiersData[n]=k}},requiresIfExists:["offset"]};function fi(t,e,i){void 0===i&&(i=!1);var n,s,o=_e(e),r=_e(e)&&function(t){var e=t.getBoundingClientRect(),i=Ee(e.width)/t.offsetWidth||1,n=Ee(e.height)/t.offsetHeight||1;return 1!==i||1!==n}(e),a=De(e),l=Oe(t,r,i),c={scrollLeft:0,scrollTop:0},h={x:0,y:0};return(o||!o&&!i)&&(("body"!==pe(e)||Je(a))&&(c=(n=e)!==me(n)&&_e(n)?{scrollLeft:(s=n).scrollLeft,scrollTop:s.scrollTop}:Ue(n)),_e(e)?((h=Oe(e,!0)).x+=e.clientLeft,h.y+=e.clientTop):a&&(h.x=Ge(a))),{x:l.left+c.scrollLeft-h.x,y:l.top+c.scrollTop-h.y,width:l.width,height:l.height}}function pi(t){var e=new Map,i=new Set,n=[];function s(t){i.add(t.name),[].concat(t.requires||[],t.requiresIfExists||[]).forEach((function(t){if(!i.has(t)){var n=e.get(t);n&&s(n)}})),n.push(t)}return t.forEach((function(t){e.set(t.name,t)})),t.forEach((function(t){i.has(t.name)||s(t)})),n}var mi={placement:"bottom",modifiers:[],strategy:"absolute"};function gi(){for(var t=arguments.length,e=new Array(t),i=0;iNumber.parseInt(t,10))):"function"==typeof t?e=>t(e,this._element):t}_getPopperConfig(){const t={placement:this._getPlacement(),modifiers:[{name:"preventOverflow",options:{boundary:this._config.boundary}},{name:"offset",options:{offset:this._getOffset()}}]};return(this._inNavbar||"static"===this._config.display)&&(F.setDataAttribute(this._menu,"popper","static"),t.modifiers=[{name:"applyStyles",enabled:!1}]),{...t,...g(this._config.popperConfig,[void 0,t])}}_selectMenuItem({key:t,target:e}){const i=z.find(".dropdown-menu .dropdown-item:not(.disabled):not(:disabled)",this._menu).filter((t=>a(t)));i.length&&b(i,e,t===Oi,!i.includes(e)).focus()}static jQueryInterface(t){return this.each((function(){const e=Ki.getOrCreateInstance(this,t);if("string"==typeof t){if(void 0===e[t])throw new TypeError(`No method named "${t}"`);e[t]()}}))}static clearMenus(t){if(2===t.button||"keyup"===t.type&&"Tab"!==t.key)return;const e=z.find(ji);for(const i of e){const e=Ki.getInstance(i);if(!e||!1===e._config.autoClose)continue;const n=t.composedPath(),s=n.includes(e._menu);if(n.includes(e._element)||"inside"===e._config.autoClose&&!s||"outside"===e._config.autoClose&&s)continue;if(e._menu.contains(t.target)&&("keyup"===t.type&&"Tab"===t.key||/input|select|option|textarea|form/i.test(t.target.tagName)))continue;const o={relatedTarget:e._element};"click"===t.type&&(o.clickEvent=t),e._completeHide(o)}}static dataApiKeydownHandler(t){const e=/input|textarea/i.test(t.target.tagName),i="Escape"===t.key,n=[Ci,Oi].includes(t.key);if(!n&&!i)return;if(e&&!i)return;t.preventDefault();const s=this.matches(Pi)?this:z.prev(this,Pi)[0]||z.next(this,Pi)[0]||z.findOne(Pi,t.delegateTarget.parentNode),o=Ki.getOrCreateInstance(s);if(n)return t.stopPropagation(),o.show(),void o._selectMenuItem(t);o._isShown()&&(t.stopPropagation(),o.hide(),s.focus())}}N.on(document,$i,Pi,Ki.dataApiKeydownHandler),N.on(document,$i,Mi,Ki.dataApiKeydownHandler),N.on(document,Di,Ki.clearMenus),N.on(document,Ii,Ki.clearMenus),N.on(document,Di,Pi,(function(t){t.preventDefault(),Ki.getOrCreateInstance(this).toggle()})),m(Ki);const Qi="backdrop",Xi="show",Yi=`mousedown.bs.${Qi}`,Ui={className:"modal-backdrop",clickCallback:null,isAnimated:!1,isVisible:!0,rootElement:"body"},Gi={className:"string",clickCallback:"(function|null)",isAnimated:"boolean",isVisible:"boolean",rootElement:"(element|string)"};class Ji extends H{constructor(t){super(),this._config=this._getConfig(t),this._isAppended=!1,this._element=null}static get Default(){return Ui}static get DefaultType(){return Gi}static get NAME(){return Qi}show(t){if(!this._config.isVisible)return void g(t);this._append();const e=this._getElement();this._config.isAnimated&&d(e),e.classList.add(Xi),this._emulateAnimation((()=>{g(t)}))}hide(t){this._config.isVisible?(this._getElement().classList.remove(Xi),this._emulateAnimation((()=>{this.dispose(),g(t)}))):g(t)}dispose(){this._isAppended&&(N.off(this._element,Yi),this._element.remove(),this._isAppended=!1)}_getElement(){if(!this._element){const t=document.createElement("div");t.className=this._config.className,this._config.isAnimated&&t.classList.add("fade"),this._element=t}return this._element}_configAfterMerge(t){return t.rootElement=r(t.rootElement),t}_append(){if(this._isAppended)return;const t=this._getElement();this._config.rootElement.append(t),N.on(t,Yi,(()=>{g(this._config.clickCallback)})),this._isAppended=!0}_emulateAnimation(t){_(t,this._getElement(),this._config.isAnimated)}}const Zi=".bs.focustrap",tn=`focusin${Zi}`,en=`keydown.tab${Zi}`,nn="backward",sn={autofocus:!0,trapElement:null},on={autofocus:"boolean",trapElement:"element"};class rn extends H{constructor(t){super(),this._config=this._getConfig(t),this._isActive=!1,this._lastTabNavDirection=null}static get Default(){return sn}static get DefaultType(){return on}static get NAME(){return"focustrap"}activate(){this._isActive||(this._config.autofocus&&this._config.trapElement.focus(),N.off(document,Zi),N.on(document,tn,(t=>this._handleFocusin(t))),N.on(document,en,(t=>this._handleKeydown(t))),this._isActive=!0)}deactivate(){this._isActive&&(this._isActive=!1,N.off(document,Zi))}_handleFocusin(t){const{trapElement:e}=this._config;if(t.target===document||t.target===e||e.contains(t.target))return;const i=z.focusableChildren(e);0===i.length?e.focus():this._lastTabNavDirection===nn?i[i.length-1].focus():i[0].focus()}_handleKeydown(t){"Tab"===t.key&&(this._lastTabNavDirection=t.shiftKey?nn:"forward")}}const an=".fixed-top, .fixed-bottom, .is-fixed, .sticky-top",ln=".sticky-top",cn="padding-right",hn="margin-right";class dn{constructor(){this._element=document.body}getWidth(){const t=document.documentElement.clientWidth;return Math.abs(window.innerWidth-t)}hide(){const t=this.getWidth();this._disableOverFlow(),this._setElementAttributes(this._element,cn,(e=>e+t)),this._setElementAttributes(an,cn,(e=>e+t)),this._setElementAttributes(ln,hn,(e=>e-t))}reset(){this._resetElementAttributes(this._element,"overflow"),this._resetElementAttributes(this._element,cn),this._resetElementAttributes(an,cn),this._resetElementAttributes(ln,hn)}isOverflowing(){return this.getWidth()>0}_disableOverFlow(){this._saveInitialAttribute(this._element,"overflow"),this._element.style.overflow="hidden"}_setElementAttributes(t,e,i){const n=this.getWidth();this._applyManipulationCallback(t,(t=>{if(t!==this._element&&window.innerWidth>t.clientWidth+n)return;this._saveInitialAttribute(t,e);const s=window.getComputedStyle(t).getPropertyValue(e);t.style.setProperty(e,`${i(Number.parseFloat(s))}px`)}))}_saveInitialAttribute(t,e){const i=t.style.getPropertyValue(e);i&&F.setDataAttribute(t,e,i)}_resetElementAttributes(t,e){this._applyManipulationCallback(t,(t=>{const i=F.getDataAttribute(t,e);null!==i?(F.removeDataAttribute(t,e),t.style.setProperty(e,i)):t.style.removeProperty(e)}))}_applyManipulationCallback(t,e){if(o(t))e(t);else for(const i of z.find(t,this._element))e(i)}}const un=".bs.modal",fn=`hide${un}`,pn=`hidePrevented${un}`,mn=`hidden${un}`,gn=`show${un}`,_n=`shown${un}`,bn=`resize${un}`,vn=`click.dismiss${un}`,yn=`mousedown.dismiss${un}`,wn=`keydown.dismiss${un}`,An=`click${un}.data-api`,En="modal-open",Tn="show",Cn="modal-static",On={backdrop:!0,focus:!0,keyboard:!0},xn={backdrop:"(boolean|string)",focus:"boolean",keyboard:"boolean"};class kn extends W{constructor(t,e){super(t,e),this._dialog=z.findOne(".modal-dialog",this._element),this._backdrop=this._initializeBackDrop(),this._focustrap=this._initializeFocusTrap(),this._isShown=!1,this._isTransitioning=!1,this._scrollBar=new dn,this._addEventListeners()}static get Default(){return On}static get DefaultType(){return xn}static get NAME(){return"modal"}toggle(t){return this._isShown?this.hide():this.show(t)}show(t){this._isShown||this._isTransitioning||N.trigger(this._element,gn,{relatedTarget:t}).defaultPrevented||(this._isShown=!0,this._isTransitioning=!0,this._scrollBar.hide(),document.body.classList.add(En),this._adjustDialog(),this._backdrop.show((()=>this._showElement(t))))}hide(){this._isShown&&!this._isTransitioning&&(N.trigger(this._element,fn).defaultPrevented||(this._isShown=!1,this._isTransitioning=!0,this._focustrap.deactivate(),this._element.classList.remove(Tn),this._queueCallback((()=>this._hideModal()),this._element,this._isAnimated())))}dispose(){N.off(window,un),N.off(this._dialog,un),this._backdrop.dispose(),this._focustrap.deactivate(),super.dispose()}handleUpdate(){this._adjustDialog()}_initializeBackDrop(){return new Ji({isVisible:Boolean(this._config.backdrop),isAnimated:this._isAnimated()})}_initializeFocusTrap(){return new rn({trapElement:this._element})}_showElement(t){document.body.contains(this._element)||document.body.append(this._element),this._element.style.display="block",this._element.removeAttribute("aria-hidden"),this._element.setAttribute("aria-modal",!0),this._element.setAttribute("role","dialog"),this._element.scrollTop=0;const e=z.findOne(".modal-body",this._dialog);e&&(e.scrollTop=0),d(this._element),this._element.classList.add(Tn),this._queueCallback((()=>{this._config.focus&&this._focustrap.activate(),this._isTransitioning=!1,N.trigger(this._element,_n,{relatedTarget:t})}),this._dialog,this._isAnimated())}_addEventListeners(){N.on(this._element,wn,(t=>{"Escape"===t.key&&(this._config.keyboard?this.hide():this._triggerBackdropTransition())})),N.on(window,bn,(()=>{this._isShown&&!this._isTransitioning&&this._adjustDialog()})),N.on(this._element,yn,(t=>{N.one(this._element,vn,(e=>{this._element===t.target&&this._element===e.target&&("static"!==this._config.backdrop?this._config.backdrop&&this.hide():this._triggerBackdropTransition())}))}))}_hideModal(){this._element.style.display="none",this._element.setAttribute("aria-hidden",!0),this._element.removeAttribute("aria-modal"),this._element.removeAttribute("role"),this._isTransitioning=!1,this._backdrop.hide((()=>{document.body.classList.remove(En),this._resetAdjustments(),this._scrollBar.reset(),N.trigger(this._element,mn)}))}_isAnimated(){return this._element.classList.contains("fade")}_triggerBackdropTransition(){if(N.trigger(this._element,pn).defaultPrevented)return;const t=this._element.scrollHeight>document.documentElement.clientHeight,e=this._element.style.overflowY;"hidden"===e||this._element.classList.contains(Cn)||(t||(this._element.style.overflowY="hidden"),this._element.classList.add(Cn),this._queueCallback((()=>{this._element.classList.remove(Cn),this._queueCallback((()=>{this._element.style.overflowY=e}),this._dialog)}),this._dialog),this._element.focus())}_adjustDialog(){const t=this._element.scrollHeight>document.documentElement.clientHeight,e=this._scrollBar.getWidth(),i=e>0;if(i&&!t){const t=p()?"paddingLeft":"paddingRight";this._element.style[t]=`${e}px`}if(!i&&t){const t=p()?"paddingRight":"paddingLeft";this._element.style[t]=`${e}px`}}_resetAdjustments(){this._element.style.paddingLeft="",this._element.style.paddingRight=""}static jQueryInterface(t,e){return this.each((function(){const i=kn.getOrCreateInstance(this,t);if("string"==typeof t){if(void 0===i[t])throw new TypeError(`No method named "${t}"`);i[t](e)}}))}}N.on(document,An,'[data-bs-toggle="modal"]',(function(t){const e=z.getElementFromSelector(this);["A","AREA"].includes(this.tagName)&&t.preventDefault(),N.one(e,gn,(t=>{t.defaultPrevented||N.one(e,mn,(()=>{a(this)&&this.focus()}))}));const i=z.findOne(".modal.show");i&&kn.getInstance(i).hide(),kn.getOrCreateInstance(e).toggle(this)})),R(kn),m(kn);const Ln=".bs.offcanvas",Sn=".data-api",Dn=`load${Ln}${Sn}`,$n="show",In="showing",Nn="hiding",Pn=".offcanvas.show",jn=`show${Ln}`,Mn=`shown${Ln}`,Fn=`hide${Ln}`,Hn=`hidePrevented${Ln}`,Wn=`hidden${Ln}`,Bn=`resize${Ln}`,zn=`click${Ln}${Sn}`,Rn=`keydown.dismiss${Ln}`,qn={backdrop:!0,keyboard:!0,scroll:!1},Vn={backdrop:"(boolean|string)",keyboard:"boolean",scroll:"boolean"};class Kn extends W{constructor(t,e){super(t,e),this._isShown=!1,this._backdrop=this._initializeBackDrop(),this._focustrap=this._initializeFocusTrap(),this._addEventListeners()}static get Default(){return qn}static get DefaultType(){return Vn}static get NAME(){return"offcanvas"}toggle(t){return this._isShown?this.hide():this.show(t)}show(t){this._isShown||N.trigger(this._element,jn,{relatedTarget:t}).defaultPrevented||(this._isShown=!0,this._backdrop.show(),this._config.scroll||(new dn).hide(),this._element.setAttribute("aria-modal",!0),this._element.setAttribute("role","dialog"),this._element.classList.add(In),this._queueCallback((()=>{this._config.scroll&&!this._config.backdrop||this._focustrap.activate(),this._element.classList.add($n),this._element.classList.remove(In),N.trigger(this._element,Mn,{relatedTarget:t})}),this._element,!0))}hide(){this._isShown&&(N.trigger(this._element,Fn).defaultPrevented||(this._focustrap.deactivate(),this._element.blur(),this._isShown=!1,this._element.classList.add(Nn),this._backdrop.hide(),this._queueCallback((()=>{this._element.classList.remove($n,Nn),this._element.removeAttribute("aria-modal"),this._element.removeAttribute("role"),this._config.scroll||(new dn).reset(),N.trigger(this._element,Wn)}),this._element,!0)))}dispose(){this._backdrop.dispose(),this._focustrap.deactivate(),super.dispose()}_initializeBackDrop(){const t=Boolean(this._config.backdrop);return new Ji({className:"offcanvas-backdrop",isVisible:t,isAnimated:!0,rootElement:this._element.parentNode,clickCallback:t?()=>{"static"!==this._config.backdrop?this.hide():N.trigger(this._element,Hn)}:null})}_initializeFocusTrap(){return new rn({trapElement:this._element})}_addEventListeners(){N.on(this._element,Rn,(t=>{"Escape"===t.key&&(this._config.keyboard?this.hide():N.trigger(this._element,Hn))}))}static jQueryInterface(t){return this.each((function(){const e=Kn.getOrCreateInstance(this,t);if("string"==typeof t){if(void 0===e[t]||t.startsWith("_")||"constructor"===t)throw new TypeError(`No method named "${t}"`);e[t](this)}}))}}N.on(document,zn,'[data-bs-toggle="offcanvas"]',(function(t){const e=z.getElementFromSelector(this);if(["A","AREA"].includes(this.tagName)&&t.preventDefault(),l(this))return;N.one(e,Wn,(()=>{a(this)&&this.focus()}));const i=z.findOne(Pn);i&&i!==e&&Kn.getInstance(i).hide(),Kn.getOrCreateInstance(e).toggle(this)})),N.on(window,Dn,(()=>{for(const t of z.find(Pn))Kn.getOrCreateInstance(t).show()})),N.on(window,Bn,(()=>{for(const t of z.find("[aria-modal][class*=show][class*=offcanvas-]"))"fixed"!==getComputedStyle(t).position&&Kn.getOrCreateInstance(t).hide()})),R(Kn),m(Kn);const Qn={"*":["class","dir","id","lang","role",/^aria-[\w-]*$/i],a:["target","href","title","rel"],area:[],b:[],br:[],col:[],code:[],dd:[],div:[],dl:[],dt:[],em:[],hr:[],h1:[],h2:[],h3:[],h4:[],h5:[],h6:[],i:[],img:["src","srcset","alt","title","width","height"],li:[],ol:[],p:[],pre:[],s:[],small:[],span:[],sub:[],sup:[],strong:[],u:[],ul:[]},Xn=new Set(["background","cite","href","itemtype","longdesc","poster","src","xlink:href"]),Yn=/^(?!javascript:)(?:[a-z0-9+.-]+:|[^&:/?#]*(?:[/?#]|$))/i,Un=(t,e)=>{const i=t.nodeName.toLowerCase();return e.includes(i)?!Xn.has(i)||Boolean(Yn.test(t.nodeValue)):e.filter((t=>t instanceof RegExp)).some((t=>t.test(i)))},Gn={allowList:Qn,content:{},extraClass:"",html:!1,sanitize:!0,sanitizeFn:null,template:"
"},Jn={allowList:"object",content:"object",extraClass:"(string|function)",html:"boolean",sanitize:"boolean",sanitizeFn:"(null|function)",template:"string"},Zn={entry:"(string|element|function|null)",selector:"(string|element)"};class ts extends H{constructor(t){super(),this._config=this._getConfig(t)}static get Default(){return Gn}static get DefaultType(){return Jn}static get NAME(){return"TemplateFactory"}getContent(){return Object.values(this._config.content).map((t=>this._resolvePossibleFunction(t))).filter(Boolean)}hasContent(){return this.getContent().length>0}changeContent(t){return this._checkContent(t),this._config.content={...this._config.content,...t},this}toHtml(){const t=document.createElement("div");t.innerHTML=this._maybeSanitize(this._config.template);for(const[e,i]of Object.entries(this._config.content))this._setContent(t,i,e);const e=t.children[0],i=this._resolvePossibleFunction(this._config.extraClass);return i&&e.classList.add(...i.split(" ")),e}_typeCheckConfig(t){super._typeCheckConfig(t),this._checkContent(t.content)}_checkContent(t){for(const[e,i]of Object.entries(t))super._typeCheckConfig({selector:e,entry:i},Zn)}_setContent(t,e,i){const n=z.findOne(i,t);n&&((e=this._resolvePossibleFunction(e))?o(e)?this._putElementInTemplate(r(e),n):this._config.html?n.innerHTML=this._maybeSanitize(e):n.textContent=e:n.remove())}_maybeSanitize(t){return this._config.sanitize?function(t,e,i){if(!t.length)return t;if(i&&"function"==typeof i)return i(t);const n=(new window.DOMParser).parseFromString(t,"text/html"),s=[].concat(...n.body.querySelectorAll("*"));for(const t of s){const i=t.nodeName.toLowerCase();if(!Object.keys(e).includes(i)){t.remove();continue}const n=[].concat(...t.attributes),s=[].concat(e["*"]||[],e[i]||[]);for(const e of n)Un(e,s)||t.removeAttribute(e.nodeName)}return n.body.innerHTML}(t,this._config.allowList,this._config.sanitizeFn):t}_resolvePossibleFunction(t){return g(t,[void 0,this])}_putElementInTemplate(t,e){if(this._config.html)return e.innerHTML="",void e.append(t);e.textContent=t.textContent}}const es=new Set(["sanitize","allowList","sanitizeFn"]),is="fade",ns="show",ss=".tooltip-inner",os=".modal",rs="hide.bs.modal",as="hover",ls="focus",cs={AUTO:"auto",TOP:"top",RIGHT:p()?"left":"right",BOTTOM:"bottom",LEFT:p()?"right":"left"},hs={allowList:Qn,animation:!0,boundary:"clippingParents",container:!1,customClass:"",delay:0,fallbackPlacements:["top","right","bottom","left"],html:!1,offset:[0,6],placement:"top",popperConfig:null,sanitize:!0,sanitizeFn:null,selector:!1,template:'',title:"",trigger:"hover focus"},ds={allowList:"object",animation:"boolean",boundary:"(string|element)",container:"(string|element|boolean)",customClass:"(string|function)",delay:"(number|object)",fallbackPlacements:"array",html:"boolean",offset:"(array|string|function)",placement:"(string|function)",popperConfig:"(null|object|function)",sanitize:"boolean",sanitizeFn:"(null|function)",selector:"(string|boolean)",template:"string",title:"(string|element|function)",trigger:"string"};class us extends W{constructor(t,e){if(void 0===wi)throw new TypeError("Bootstrap's tooltips require Popper (https://popper.js.org/docs/v2/)");super(t,e),this._isEnabled=!0,this._timeout=0,this._isHovered=null,this._activeTrigger={},this._popper=null,this._templateFactory=null,this._newContent=null,this.tip=null,this._setListeners(),this._config.selector||this._fixTitle()}static get Default(){return hs}static get DefaultType(){return ds}static get NAME(){return"tooltip"}enable(){this._isEnabled=!0}disable(){this._isEnabled=!1}toggleEnabled(){this._isEnabled=!this._isEnabled}toggle(){this._isEnabled&&(this._isShown()?this._leave():this._enter())}dispose(){clearTimeout(this._timeout),N.off(this._element.closest(os),rs,this._hideModalHandler),this._element.getAttribute("data-bs-original-title")&&this._element.setAttribute("title",this._element.getAttribute("data-bs-original-title")),this._disposePopper(),super.dispose()}show(){if("none"===this._element.style.display)throw new Error("Please use show on visible elements");if(!this._isWithContent()||!this._isEnabled)return;const t=N.trigger(this._element,this.constructor.eventName("show")),e=(c(this._element)||this._element.ownerDocument.documentElement).contains(this._element);if(t.defaultPrevented||!e)return;this._disposePopper();const i=this._getTipElement();this._element.setAttribute("aria-describedby",i.getAttribute("id"));const{container:n}=this._config;if(this._element.ownerDocument.documentElement.contains(this.tip)||(n.append(i),N.trigger(this._element,this.constructor.eventName("inserted"))),this._popper=this._createPopper(i),i.classList.add(ns),"ontouchstart"in document.documentElement)for(const t of[].concat(...document.body.children))N.on(t,"mouseover",h);this._queueCallback((()=>{N.trigger(this._element,this.constructor.eventName("shown")),!1===this._isHovered&&this._leave(),this._isHovered=!1}),this.tip,this._isAnimated())}hide(){if(this._isShown()&&!N.trigger(this._element,this.constructor.eventName("hide")).defaultPrevented){if(this._getTipElement().classList.remove(ns),"ontouchstart"in document.documentElement)for(const t of[].concat(...document.body.children))N.off(t,"mouseover",h);this._activeTrigger.click=!1,this._activeTrigger[ls]=!1,this._activeTrigger[as]=!1,this._isHovered=null,this._queueCallback((()=>{this._isWithActiveTrigger()||(this._isHovered||this._disposePopper(),this._element.removeAttribute("aria-describedby"),N.trigger(this._element,this.constructor.eventName("hidden")))}),this.tip,this._isAnimated())}}update(){this._popper&&this._popper.update()}_isWithContent(){return Boolean(this._getTitle())}_getTipElement(){return this.tip||(this.tip=this._createTipElement(this._newContent||this._getContentForTemplate())),this.tip}_createTipElement(t){const e=this._getTemplateFactory(t).toHtml();if(!e)return null;e.classList.remove(is,ns),e.classList.add(`bs-${this.constructor.NAME}-auto`);const i=(t=>{do{t+=Math.floor(1e6*Math.random())}while(document.getElementById(t));return t})(this.constructor.NAME).toString();return e.setAttribute("id",i),this._isAnimated()&&e.classList.add(is),e}setContent(t){this._newContent=t,this._isShown()&&(this._disposePopper(),this.show())}_getTemplateFactory(t){return this._templateFactory?this._templateFactory.changeContent(t):this._templateFactory=new ts({...this._config,content:t,extraClass:this._resolvePossibleFunction(this._config.customClass)}),this._templateFactory}_getContentForTemplate(){return{[ss]:this._getTitle()}}_getTitle(){return this._resolvePossibleFunction(this._config.title)||this._element.getAttribute("data-bs-original-title")}_initializeOnDelegatedTarget(t){return this.constructor.getOrCreateInstance(t.delegateTarget,this._getDelegateConfig())}_isAnimated(){return this._config.animation||this.tip&&this.tip.classList.contains(is)}_isShown(){return this.tip&&this.tip.classList.contains(ns)}_createPopper(t){const e=g(this._config.placement,[this,t,this._element]),i=cs[e.toUpperCase()];return yi(this._element,t,this._getPopperConfig(i))}_getOffset(){const{offset:t}=this._config;return"string"==typeof t?t.split(",").map((t=>Number.parseInt(t,10))):"function"==typeof t?e=>t(e,this._element):t}_resolvePossibleFunction(t){return g(t,[this._element,this._element])}_getPopperConfig(t){const e={placement:t,modifiers:[{name:"flip",options:{fallbackPlacements:this._config.fallbackPlacements}},{name:"offset",options:{offset:this._getOffset()}},{name:"preventOverflow",options:{boundary:this._config.boundary}},{name:"arrow",options:{element:`.${this.constructor.NAME}-arrow`}},{name:"preSetPlacement",enabled:!0,phase:"beforeMain",fn:t=>{this._getTipElement().setAttribute("data-popper-placement",t.state.placement)}}]};return{...e,...g(this._config.popperConfig,[void 0,e])}}_setListeners(){const t=this._config.trigger.split(" ");for(const e of t)if("click"===e)N.on(this._element,this.constructor.eventName("click"),this._config.selector,(t=>{this._initializeOnDelegatedTarget(t).toggle()}));else if("manual"!==e){const t=e===as?this.constructor.eventName("mouseenter"):this.constructor.eventName("focusin"),i=e===as?this.constructor.eventName("mouseleave"):this.constructor.eventName("focusout");N.on(this._element,t,this._config.selector,(t=>{const e=this._initializeOnDelegatedTarget(t);e._activeTrigger["focusin"===t.type?ls:as]=!0,e._enter()})),N.on(this._element,i,this._config.selector,(t=>{const e=this._initializeOnDelegatedTarget(t);e._activeTrigger["focusout"===t.type?ls:as]=e._element.contains(t.relatedTarget),e._leave()}))}this._hideModalHandler=()=>{this._element&&this.hide()},N.on(this._element.closest(os),rs,this._hideModalHandler)}_fixTitle(){const t=this._element.getAttribute("title");t&&(this._element.getAttribute("aria-label")||this._element.textContent.trim()||this._element.setAttribute("aria-label",t),this._element.setAttribute("data-bs-original-title",t),this._element.removeAttribute("title"))}_enter(){this._isShown()||this._isHovered?this._isHovered=!0:(this._isHovered=!0,this._setTimeout((()=>{this._isHovered&&this.show()}),this._config.delay.show))}_leave(){this._isWithActiveTrigger()||(this._isHovered=!1,this._setTimeout((()=>{this._isHovered||this.hide()}),this._config.delay.hide))}_setTimeout(t,e){clearTimeout(this._timeout),this._timeout=setTimeout(t,e)}_isWithActiveTrigger(){return Object.values(this._activeTrigger).includes(!0)}_getConfig(t){const e=F.getDataAttributes(this._element);for(const t of Object.keys(e))es.has(t)&&delete e[t];return t={...e,..."object"==typeof t&&t?t:{}},t=this._mergeConfigObj(t),t=this._configAfterMerge(t),this._typeCheckConfig(t),t}_configAfterMerge(t){return t.container=!1===t.container?document.body:r(t.container),"number"==typeof t.delay&&(t.delay={show:t.delay,hide:t.delay}),"number"==typeof t.title&&(t.title=t.title.toString()),"number"==typeof t.content&&(t.content=t.content.toString()),t}_getDelegateConfig(){const t={};for(const[e,i]of Object.entries(this._config))this.constructor.Default[e]!==i&&(t[e]=i);return t.selector=!1,t.trigger="manual",t}_disposePopper(){this._popper&&(this._popper.destroy(),this._popper=null),this.tip&&(this.tip.remove(),this.tip=null)}static jQueryInterface(t){return this.each((function(){const e=us.getOrCreateInstance(this,t);if("string"==typeof t){if(void 0===e[t])throw new TypeError(`No method named "${t}"`);e[t]()}}))}}m(us);const fs=".popover-header",ps=".popover-body",ms={...us.Default,content:"",offset:[0,8],placement:"right",template:'',trigger:"click"},gs={...us.DefaultType,content:"(null|string|element|function)"};class _s extends us{static get Default(){return ms}static get DefaultType(){return gs}static get NAME(){return"popover"}_isWithContent(){return this._getTitle()||this._getContent()}_getContentForTemplate(){return{[fs]:this._getTitle(),[ps]:this._getContent()}}_getContent(){return this._resolvePossibleFunction(this._config.content)}static jQueryInterface(t){return this.each((function(){const e=_s.getOrCreateInstance(this,t);if("string"==typeof t){if(void 0===e[t])throw new TypeError(`No method named "${t}"`);e[t]()}}))}}m(_s);const bs=".bs.scrollspy",vs=`activate${bs}`,ys=`click${bs}`,ws=`load${bs}.data-api`,As="active",Es="[href]",Ts=".nav-link",Cs=`${Ts}, .nav-item > ${Ts}, .list-group-item`,Os={offset:null,rootMargin:"0px 0px -25%",smoothScroll:!1,target:null,threshold:[.1,.5,1]},xs={offset:"(number|null)",rootMargin:"string",smoothScroll:"boolean",target:"element",threshold:"array"};class ks extends W{constructor(t,e){super(t,e),this._targetLinks=new Map,this._observableSections=new Map,this._rootElement="visible"===getComputedStyle(this._element).overflowY?null:this._element,this._activeTarget=null,this._observer=null,this._previousScrollData={visibleEntryTop:0,parentScrollTop:0},this.refresh()}static get Default(){return Os}static get DefaultType(){return xs}static get NAME(){return"scrollspy"}refresh(){this._initializeTargetsAndObservables(),this._maybeEnableSmoothScroll(),this._observer?this._observer.disconnect():this._observer=this._getNewObserver();for(const t of this._observableSections.values())this._observer.observe(t)}dispose(){this._observer.disconnect(),super.dispose()}_configAfterMerge(t){return t.target=r(t.target)||document.body,t.rootMargin=t.offset?`${t.offset}px 0px -30%`:t.rootMargin,"string"==typeof t.threshold&&(t.threshold=t.threshold.split(",").map((t=>Number.parseFloat(t)))),t}_maybeEnableSmoothScroll(){this._config.smoothScroll&&(N.off(this._config.target,ys),N.on(this._config.target,ys,Es,(t=>{const e=this._observableSections.get(t.target.hash);if(e){t.preventDefault();const i=this._rootElement||window,n=e.offsetTop-this._element.offsetTop;if(i.scrollTo)return void i.scrollTo({top:n,behavior:"smooth"});i.scrollTop=n}})))}_getNewObserver(){const t={root:this._rootElement,threshold:this._config.threshold,rootMargin:this._config.rootMargin};return new IntersectionObserver((t=>this._observerCallback(t)),t)}_observerCallback(t){const e=t=>this._targetLinks.get(`#${t.target.id}`),i=t=>{this._previousScrollData.visibleEntryTop=t.target.offsetTop,this._process(e(t))},n=(this._rootElement||document.documentElement).scrollTop,s=n>=this._previousScrollData.parentScrollTop;this._previousScrollData.parentScrollTop=n;for(const o of t){if(!o.isIntersecting){this._activeTarget=null,this._clearActiveClass(e(o));continue}const t=o.target.offsetTop>=this._previousScrollData.visibleEntryTop;if(s&&t){if(i(o),!n)return}else s||t||i(o)}}_initializeTargetsAndObservables(){this._targetLinks=new Map,this._observableSections=new Map;const t=z.find(Es,this._config.target);for(const e of t){if(!e.hash||l(e))continue;const t=z.findOne(decodeURI(e.hash),this._element);a(t)&&(this._targetLinks.set(decodeURI(e.hash),e),this._observableSections.set(e.hash,t))}}_process(t){this._activeTarget!==t&&(this._clearActiveClass(this._config.target),this._activeTarget=t,t.classList.add(As),this._activateParents(t),N.trigger(this._element,vs,{relatedTarget:t}))}_activateParents(t){if(t.classList.contains("dropdown-item"))z.findOne(".dropdown-toggle",t.closest(".dropdown")).classList.add(As);else for(const e of z.parents(t,".nav, .list-group"))for(const t of z.prev(e,Cs))t.classList.add(As)}_clearActiveClass(t){t.classList.remove(As);const e=z.find(`${Es}.${As}`,t);for(const t of e)t.classList.remove(As)}static jQueryInterface(t){return this.each((function(){const e=ks.getOrCreateInstance(this,t);if("string"==typeof t){if(void 0===e[t]||t.startsWith("_")||"constructor"===t)throw new TypeError(`No method named "${t}"`);e[t]()}}))}}N.on(window,ws,(()=>{for(const t of z.find('[data-bs-spy="scroll"]'))ks.getOrCreateInstance(t)})),m(ks);const Ls=".bs.tab",Ss=`hide${Ls}`,Ds=`hidden${Ls}`,$s=`show${Ls}`,Is=`shown${Ls}`,Ns=`click${Ls}`,Ps=`keydown${Ls}`,js=`load${Ls}`,Ms="ArrowLeft",Fs="ArrowRight",Hs="ArrowUp",Ws="ArrowDown",Bs="Home",zs="End",Rs="active",qs="fade",Vs="show",Ks=".dropdown-toggle",Qs=`:not(${Ks})`,Xs='[data-bs-toggle="tab"], [data-bs-toggle="pill"], [data-bs-toggle="list"]',Ys=`.nav-link${Qs}, .list-group-item${Qs}, [role="tab"]${Qs}, ${Xs}`,Us=`.${Rs}[data-bs-toggle="tab"], .${Rs}[data-bs-toggle="pill"], .${Rs}[data-bs-toggle="list"]`;class Gs extends W{constructor(t){super(t),this._parent=this._element.closest('.list-group, .nav, [role="tablist"]'),this._parent&&(this._setInitialAttributes(this._parent,this._getChildren()),N.on(this._element,Ps,(t=>this._keydown(t))))}static get NAME(){return"tab"}show(){const t=this._element;if(this._elemIsActive(t))return;const e=this._getActiveElem(),i=e?N.trigger(e,Ss,{relatedTarget:t}):null;N.trigger(t,$s,{relatedTarget:e}).defaultPrevented||i&&i.defaultPrevented||(this._deactivate(e,t),this._activate(t,e))}_activate(t,e){t&&(t.classList.add(Rs),this._activate(z.getElementFromSelector(t)),this._queueCallback((()=>{"tab"===t.getAttribute("role")?(t.removeAttribute("tabindex"),t.setAttribute("aria-selected",!0),this._toggleDropDown(t,!0),N.trigger(t,Is,{relatedTarget:e})):t.classList.add(Vs)}),t,t.classList.contains(qs)))}_deactivate(t,e){t&&(t.classList.remove(Rs),t.blur(),this._deactivate(z.getElementFromSelector(t)),this._queueCallback((()=>{"tab"===t.getAttribute("role")?(t.setAttribute("aria-selected",!1),t.setAttribute("tabindex","-1"),this._toggleDropDown(t,!1),N.trigger(t,Ds,{relatedTarget:e})):t.classList.remove(Vs)}),t,t.classList.contains(qs)))}_keydown(t){if(![Ms,Fs,Hs,Ws,Bs,zs].includes(t.key))return;t.stopPropagation(),t.preventDefault();const e=this._getChildren().filter((t=>!l(t)));let i;if([Bs,zs].includes(t.key))i=e[t.key===Bs?0:e.length-1];else{const n=[Fs,Ws].includes(t.key);i=b(e,t.target,n,!0)}i&&(i.focus({preventScroll:!0}),Gs.getOrCreateInstance(i).show())}_getChildren(){return z.find(Ys,this._parent)}_getActiveElem(){return this._getChildren().find((t=>this._elemIsActive(t)))||null}_setInitialAttributes(t,e){this._setAttributeIfNotExists(t,"role","tablist");for(const t of e)this._setInitialAttributesOnChild(t)}_setInitialAttributesOnChild(t){t=this._getInnerElement(t);const e=this._elemIsActive(t),i=this._getOuterElement(t);t.setAttribute("aria-selected",e),i!==t&&this._setAttributeIfNotExists(i,"role","presentation"),e||t.setAttribute("tabindex","-1"),this._setAttributeIfNotExists(t,"role","tab"),this._setInitialAttributesOnTargetPanel(t)}_setInitialAttributesOnTargetPanel(t){const e=z.getElementFromSelector(t);e&&(this._setAttributeIfNotExists(e,"role","tabpanel"),t.id&&this._setAttributeIfNotExists(e,"aria-labelledby",`${t.id}`))}_toggleDropDown(t,e){const i=this._getOuterElement(t);if(!i.classList.contains("dropdown"))return;const n=(t,n)=>{const s=z.findOne(t,i);s&&s.classList.toggle(n,e)};n(Ks,Rs),n(".dropdown-menu",Vs),i.setAttribute("aria-expanded",e)}_setAttributeIfNotExists(t,e,i){t.hasAttribute(e)||t.setAttribute(e,i)}_elemIsActive(t){return t.classList.contains(Rs)}_getInnerElement(t){return t.matches(Ys)?t:z.findOne(Ys,t)}_getOuterElement(t){return t.closest(".nav-item, .list-group-item")||t}static jQueryInterface(t){return this.each((function(){const e=Gs.getOrCreateInstance(this);if("string"==typeof t){if(void 0===e[t]||t.startsWith("_")||"constructor"===t)throw new TypeError(`No method named "${t}"`);e[t]()}}))}}N.on(document,Ns,Xs,(function(t){["A","AREA"].includes(this.tagName)&&t.preventDefault(),l(this)||Gs.getOrCreateInstance(this).show()})),N.on(window,js,(()=>{for(const t of z.find(Us))Gs.getOrCreateInstance(t)})),m(Gs);const Js=".bs.toast",Zs=`mouseover${Js}`,to=`mouseout${Js}`,eo=`focusin${Js}`,io=`focusout${Js}`,no=`hide${Js}`,so=`hidden${Js}`,oo=`show${Js}`,ro=`shown${Js}`,ao="hide",lo="show",co="showing",ho={animation:"boolean",autohide:"boolean",delay:"number"},uo={animation:!0,autohide:!0,delay:5e3};class fo extends W{constructor(t,e){super(t,e),this._timeout=null,this._hasMouseInteraction=!1,this._hasKeyboardInteraction=!1,this._setListeners()}static get Default(){return uo}static get DefaultType(){return ho}static get NAME(){return"toast"}show(){N.trigger(this._element,oo).defaultPrevented||(this._clearTimeout(),this._config.animation&&this._element.classList.add("fade"),this._element.classList.remove(ao),d(this._element),this._element.classList.add(lo,co),this._queueCallback((()=>{this._element.classList.remove(co),N.trigger(this._element,ro),this._maybeScheduleHide()}),this._element,this._config.animation))}hide(){this.isShown()&&(N.trigger(this._element,no).defaultPrevented||(this._element.classList.add(co),this._queueCallback((()=>{this._element.classList.add(ao),this._element.classList.remove(co,lo),N.trigger(this._element,so)}),this._element,this._config.animation)))}dispose(){this._clearTimeout(),this.isShown()&&this._element.classList.remove(lo),super.dispose()}isShown(){return this._element.classList.contains(lo)}_maybeScheduleHide(){this._config.autohide&&(this._hasMouseInteraction||this._hasKeyboardInteraction||(this._timeout=setTimeout((()=>{this.hide()}),this._config.delay)))}_onInteraction(t,e){switch(t.type){case"mouseover":case"mouseout":this._hasMouseInteraction=e;break;case"focusin":case"focusout":this._hasKeyboardInteraction=e}if(e)return void this._clearTimeout();const i=t.relatedTarget;this._element===i||this._element.contains(i)||this._maybeScheduleHide()}_setListeners(){N.on(this._element,Zs,(t=>this._onInteraction(t,!0))),N.on(this._element,to,(t=>this._onInteraction(t,!1))),N.on(this._element,eo,(t=>this._onInteraction(t,!0))),N.on(this._element,io,(t=>this._onInteraction(t,!1)))}_clearTimeout(){clearTimeout(this._timeout),this._timeout=null}static jQueryInterface(t){return this.each((function(){const e=fo.getOrCreateInstance(this,t);if("string"==typeof t){if(void 0===e[t])throw new TypeError(`No method named "${t}"`);e[t](this)}}))}}return R(fo),m(fo),{Alert:Q,Button:Y,Carousel:Lt,Collapse:Rt,Dropdown:Ki,Modal:kn,Offcanvas:Kn,Popover:_s,ScrollSpy:ks,Tab:Gs,Toast:fo,Tooltip:us}})); -//# sourceMappingURL=bootstrap.bundle.min.js.map \ No newline at end of file diff --git a/backend/coverage-report-final/_js/d3.min.js b/backend/coverage-report-final/_js/d3.min.js deleted file mode 100644 index 16648730..00000000 --- a/backend/coverage-report-final/_js/d3.min.js +++ /dev/null @@ -1,5 +0,0 @@ -!function(){function n(n){return n&&(n.ownerDocument||n.document||n).documentElement}function t(n){return n&&(n.ownerDocument&&n.ownerDocument.defaultView||n.document&&n||n.defaultView)}function e(n,t){return t>n?-1:n>t?1:n>=t?0:NaN}function r(n){return null===n?NaN:+n}function i(n){return!isNaN(n)}function u(n){return{left:function(t,e,r,i){for(arguments.length<3&&(r=0),arguments.length<4&&(i=t.length);i>r;){var u=r+i>>>1;n(t[u],e)<0?r=u+1:i=u}return r},right:function(t,e,r,i){for(arguments.length<3&&(r=0),arguments.length<4&&(i=t.length);i>r;){var u=r+i>>>1;n(t[u],e)>0?i=u:r=u+1}return r}}}function o(n){return n.length}function a(n){for(var t=1;n*t%1;)t*=10;return t}function l(n,t){for(var e in t)Object.defineProperty(n.prototype,e,{value:t[e],enumerable:!1})}function c(){this._=Object.create(null)}function f(n){return(n+="")===bo||n[0]===_o?_o+n:n}function s(n){return(n+="")[0]===_o?n.slice(1):n}function h(n){return f(n)in this._}function p(n){return(n=f(n))in this._&&delete this._[n]}function g(){var n=[];for(var t in this._)n.push(s(t));return n}function v(){var n=0;for(var t in this._)++n;return n}function d(){for(var n in this._)return!1;return!0}function y(){this._=Object.create(null)}function m(n){return n}function M(n,t,e){return function(){var r=e.apply(t,arguments);return r===t?n:r}}function x(n,t){if(t in n)return t;t=t.charAt(0).toUpperCase()+t.slice(1);for(var e=0,r=wo.length;r>e;++e){var i=wo[e]+t;if(i in n)return i}}function b(){}function _(){}function w(n){function t(){for(var t,r=e,i=-1,u=r.length;++ie;e++)for(var i,u=n[e],o=0,a=u.length;a>o;o++)(i=u[o])&&t(i,o,e);return n}function Z(n){return ko(n,qo),n}function V(n){var t,e;return function(r,i,u){var o,a=n[u].update,l=a.length;for(u!=e&&(e=u,t=0),i>=t&&(t=i+1);!(o=a[t])&&++t0&&(n=n.slice(0,a));var c=To.get(n);return c&&(n=c,l=B),a?t?i:r:t?b:u}function $(n,t){return function(e){var r=ao.event;ao.event=e,t[0]=this.__data__;try{n.apply(this,t)}finally{ao.event=r}}}function B(n,t){var e=$(n,t);return function(n){var t=this,r=n.relatedTarget;r&&(r===t||8&r.compareDocumentPosition(t))||e.call(t,n)}}function W(e){var r=".dragsuppress-"+ ++Do,i="click"+r,u=ao.select(t(e)).on("touchmove"+r,S).on("dragstart"+r,S).on("selectstart"+r,S);if(null==Ro&&(Ro="onselectstart"in e?!1:x(e.style,"userSelect")),Ro){var o=n(e).style,a=o[Ro];o[Ro]="none"}return function(n){if(u.on(r,null),Ro&&(o[Ro]=a),n){var t=function(){u.on(i,null)};u.on(i,function(){S(),t()},!0),setTimeout(t,0)}}}function J(n,e){e.changedTouches&&(e=e.changedTouches[0]);var r=n.ownerSVGElement||n;if(r.createSVGPoint){var i=r.createSVGPoint();if(0>Po){var u=t(n);if(u.scrollX||u.scrollY){r=ao.select("body").append("svg").style({position:"absolute",top:0,left:0,margin:0,padding:0,border:"none"},"important");var o=r[0][0].getScreenCTM();Po=!(o.f||o.e),r.remove()}}return Po?(i.x=e.pageX,i.y=e.pageY):(i.x=e.clientX,i.y=e.clientY),i=i.matrixTransform(n.getScreenCTM().inverse()),[i.x,i.y]}var a=n.getBoundingClientRect();return[e.clientX-a.left-n.clientLeft,e.clientY-a.top-n.clientTop]}function G(){return ao.event.changedTouches[0].identifier}function K(n){return n>0?1:0>n?-1:0}function Q(n,t,e){return(t[0]-n[0])*(e[1]-n[1])-(t[1]-n[1])*(e[0]-n[0])}function nn(n){return n>1?0:-1>n?Fo:Math.acos(n)}function tn(n){return n>1?Io:-1>n?-Io:Math.asin(n)}function en(n){return((n=Math.exp(n))-1/n)/2}function rn(n){return((n=Math.exp(n))+1/n)/2}function un(n){return((n=Math.exp(2*n))-1)/(n+1)}function on(n){return(n=Math.sin(n/2))*n}function an(){}function ln(n,t,e){return this instanceof ln?(this.h=+n,this.s=+t,void(this.l=+e)):arguments.length<2?n instanceof ln?new ln(n.h,n.s,n.l):_n(""+n,wn,ln):new ln(n,t,e)}function cn(n,t,e){function r(n){return n>360?n-=360:0>n&&(n+=360),60>n?u+(o-u)*n/60:180>n?o:240>n?u+(o-u)*(240-n)/60:u}function i(n){return Math.round(255*r(n))}var u,o;return n=isNaN(n)?0:(n%=360)<0?n+360:n,t=isNaN(t)?0:0>t?0:t>1?1:t,e=0>e?0:e>1?1:e,o=.5>=e?e*(1+t):e+t-e*t,u=2*e-o,new mn(i(n+120),i(n),i(n-120))}function fn(n,t,e){return this instanceof fn?(this.h=+n,this.c=+t,void(this.l=+e)):arguments.length<2?n instanceof fn?new fn(n.h,n.c,n.l):n instanceof hn?gn(n.l,n.a,n.b):gn((n=Sn((n=ao.rgb(n)).r,n.g,n.b)).l,n.a,n.b):new fn(n,t,e)}function sn(n,t,e){return isNaN(n)&&(n=0),isNaN(t)&&(t=0),new hn(e,Math.cos(n*=Yo)*t,Math.sin(n)*t)}function hn(n,t,e){return this instanceof hn?(this.l=+n,this.a=+t,void(this.b=+e)):arguments.length<2?n instanceof hn?new hn(n.l,n.a,n.b):n instanceof fn?sn(n.h,n.c,n.l):Sn((n=mn(n)).r,n.g,n.b):new hn(n,t,e)}function pn(n,t,e){var r=(n+16)/116,i=r+t/500,u=r-e/200;return i=vn(i)*na,r=vn(r)*ta,u=vn(u)*ea,new mn(yn(3.2404542*i-1.5371385*r-.4985314*u),yn(-.969266*i+1.8760108*r+.041556*u),yn(.0556434*i-.2040259*r+1.0572252*u))}function gn(n,t,e){return n>0?new fn(Math.atan2(e,t)*Zo,Math.sqrt(t*t+e*e),n):new fn(NaN,NaN,n)}function vn(n){return n>.206893034?n*n*n:(n-4/29)/7.787037}function dn(n){return n>.008856?Math.pow(n,1/3):7.787037*n+4/29}function yn(n){return Math.round(255*(.00304>=n?12.92*n:1.055*Math.pow(n,1/2.4)-.055))}function mn(n,t,e){return this instanceof mn?(this.r=~~n,this.g=~~t,void(this.b=~~e)):arguments.length<2?n instanceof mn?new mn(n.r,n.g,n.b):_n(""+n,mn,cn):new mn(n,t,e)}function Mn(n){return new mn(n>>16,n>>8&255,255&n)}function xn(n){return Mn(n)+""}function bn(n){return 16>n?"0"+Math.max(0,n).toString(16):Math.min(255,n).toString(16)}function _n(n,t,e){var r,i,u,o=0,a=0,l=0;if(r=/([a-z]+)\((.*)\)/.exec(n=n.toLowerCase()))switch(i=r[2].split(","),r[1]){case"hsl":return e(parseFloat(i[0]),parseFloat(i[1])/100,parseFloat(i[2])/100);case"rgb":return t(Nn(i[0]),Nn(i[1]),Nn(i[2]))}return(u=ua.get(n))?t(u.r,u.g,u.b):(null==n||"#"!==n.charAt(0)||isNaN(u=parseInt(n.slice(1),16))||(4===n.length?(o=(3840&u)>>4,o=o>>4|o,a=240&u,a=a>>4|a,l=15&u,l=l<<4|l):7===n.length&&(o=(16711680&u)>>16,a=(65280&u)>>8,l=255&u)),t(o,a,l))}function wn(n,t,e){var r,i,u=Math.min(n/=255,t/=255,e/=255),o=Math.max(n,t,e),a=o-u,l=(o+u)/2;return a?(i=.5>l?a/(o+u):a/(2-o-u),r=n==o?(t-e)/a+(e>t?6:0):t==o?(e-n)/a+2:(n-t)/a+4,r*=60):(r=NaN,i=l>0&&1>l?0:r),new ln(r,i,l)}function Sn(n,t,e){n=kn(n),t=kn(t),e=kn(e);var r=dn((.4124564*n+.3575761*t+.1804375*e)/na),i=dn((.2126729*n+.7151522*t+.072175*e)/ta),u=dn((.0193339*n+.119192*t+.9503041*e)/ea);return hn(116*i-16,500*(r-i),200*(i-u))}function kn(n){return(n/=255)<=.04045?n/12.92:Math.pow((n+.055)/1.055,2.4)}function Nn(n){var t=parseFloat(n);return"%"===n.charAt(n.length-1)?Math.round(2.55*t):t}function En(n){return"function"==typeof n?n:function(){return n}}function An(n){return function(t,e,r){return 2===arguments.length&&"function"==typeof e&&(r=e,e=null),Cn(t,e,n,r)}}function Cn(n,t,e,r){function i(){var n,t=l.status;if(!t&&Ln(l)||t>=200&&300>t||304===t){try{n=e.call(u,l)}catch(r){return void o.error.call(u,r)}o.load.call(u,n)}else o.error.call(u,l)}var u={},o=ao.dispatch("beforesend","progress","load","error"),a={},l=new XMLHttpRequest,c=null;return!this.XDomainRequest||"withCredentials"in l||!/^(http(s)?:)?\/\//.test(n)||(l=new XDomainRequest),"onload"in l?l.onload=l.onerror=i:l.onreadystatechange=function(){l.readyState>3&&i()},l.onprogress=function(n){var t=ao.event;ao.event=n;try{o.progress.call(u,l)}finally{ao.event=t}},u.header=function(n,t){return n=(n+"").toLowerCase(),arguments.length<2?a[n]:(null==t?delete a[n]:a[n]=t+"",u)},u.mimeType=function(n){return arguments.length?(t=null==n?null:n+"",u):t},u.responseType=function(n){return arguments.length?(c=n,u):c},u.response=function(n){return e=n,u},["get","post"].forEach(function(n){u[n]=function(){return u.send.apply(u,[n].concat(co(arguments)))}}),u.send=function(e,r,i){if(2===arguments.length&&"function"==typeof r&&(i=r,r=null),l.open(e,n,!0),null==t||"accept"in a||(a.accept=t+",*/*"),l.setRequestHeader)for(var f in a)l.setRequestHeader(f,a[f]);return null!=t&&l.overrideMimeType&&l.overrideMimeType(t),null!=c&&(l.responseType=c),null!=i&&u.on("error",i).on("load",function(n){i(null,n)}),o.beforesend.call(u,l),l.send(null==r?null:r),u},u.abort=function(){return l.abort(),u},ao.rebind(u,o,"on"),null==r?u:u.get(zn(r))}function zn(n){return 1===n.length?function(t,e){n(null==t?e:null)}:n}function Ln(n){var t=n.responseType;return t&&"text"!==t?n.response:n.responseText}function qn(n,t,e){var r=arguments.length;2>r&&(t=0),3>r&&(e=Date.now());var i=e+t,u={c:n,t:i,n:null};return aa?aa.n=u:oa=u,aa=u,la||(ca=clearTimeout(ca),la=1,fa(Tn)),u}function Tn(){var n=Rn(),t=Dn()-n;t>24?(isFinite(t)&&(clearTimeout(ca),ca=setTimeout(Tn,t)),la=0):(la=1,fa(Tn))}function Rn(){for(var n=Date.now(),t=oa;t;)n>=t.t&&t.c(n-t.t)&&(t.c=null),t=t.n;return n}function Dn(){for(var n,t=oa,e=1/0;t;)t.c?(t.t8?function(n){return n/e}:function(n){return n*e},symbol:n}}function jn(n){var t=n.decimal,e=n.thousands,r=n.grouping,i=n.currency,u=r&&e?function(n,t){for(var i=n.length,u=[],o=0,a=r[0],l=0;i>0&&a>0&&(l+a+1>t&&(a=Math.max(1,t-l)),u.push(n.substring(i-=a,i+a)),!((l+=a+1)>t));)a=r[o=(o+1)%r.length];return u.reverse().join(e)}:m;return function(n){var e=ha.exec(n),r=e[1]||" ",o=e[2]||">",a=e[3]||"-",l=e[4]||"",c=e[5],f=+e[6],s=e[7],h=e[8],p=e[9],g=1,v="",d="",y=!1,m=!0;switch(h&&(h=+h.substring(1)),(c||"0"===r&&"="===o)&&(c=r="0",o="="),p){case"n":s=!0,p="g";break;case"%":g=100,d="%",p="f";break;case"p":g=100,d="%",p="r";break;case"b":case"o":case"x":case"X":"#"===l&&(v="0"+p.toLowerCase());case"c":m=!1;case"d":y=!0,h=0;break;case"s":g=-1,p="r"}"$"===l&&(v=i[0],d=i[1]),"r"!=p||h||(p="g"),null!=h&&("g"==p?h=Math.max(1,Math.min(21,h)):"e"!=p&&"f"!=p||(h=Math.max(0,Math.min(20,h)))),p=pa.get(p)||Fn;var M=c&&s;return function(n){var e=d;if(y&&n%1)return"";var i=0>n||0===n&&0>1/n?(n=-n,"-"):"-"===a?"":a;if(0>g){var l=ao.formatPrefix(n,h);n=l.scale(n),e=l.symbol+d}else n*=g;n=p(n,h);var x,b,_=n.lastIndexOf(".");if(0>_){var w=m?n.lastIndexOf("e"):-1;0>w?(x=n,b=""):(x=n.substring(0,w),b=n.substring(w))}else x=n.substring(0,_),b=t+n.substring(_+1);!c&&s&&(x=u(x,1/0));var S=v.length+x.length+b.length+(M?0:i.length),k=f>S?new Array(S=f-S+1).join(r):"";return M&&(x=u(k+x,k.length?f-b.length:1/0)),i+=v,n=x+b,("<"===o?i+n+k:">"===o?k+i+n:"^"===o?k.substring(0,S>>=1)+i+n+k.substring(S):i+(M?n:k+n))+e}}}function Fn(n){return n+""}function Hn(){this._=new Date(arguments.length>1?Date.UTC.apply(this,arguments):arguments[0])}function On(n,t,e){function r(t){var e=n(t),r=u(e,1);return r-t>t-e?e:r}function i(e){return t(e=n(new va(e-1)),1),e}function u(n,e){return t(n=new va(+n),e),n}function o(n,r,u){var o=i(n),a=[];if(u>1)for(;r>o;)e(o)%u||a.push(new Date(+o)),t(o,1);else for(;r>o;)a.push(new Date(+o)),t(o,1);return a}function a(n,t,e){try{va=Hn;var r=new Hn;return r._=n,o(r,t,e)}finally{va=Date}}n.floor=n,n.round=r,n.ceil=i,n.offset=u,n.range=o;var l=n.utc=In(n);return l.floor=l,l.round=In(r),l.ceil=In(i),l.offset=In(u),l.range=a,n}function In(n){return function(t,e){try{va=Hn;var r=new Hn;return r._=t,n(r,e)._}finally{va=Date}}}function Yn(n){function t(n){function t(t){for(var e,i,u,o=[],a=-1,l=0;++aa;){if(r>=c)return-1;if(i=t.charCodeAt(a++),37===i){if(o=t.charAt(a++),u=C[o in ya?t.charAt(a++):o],!u||(r=u(n,e,r))<0)return-1}else if(i!=e.charCodeAt(r++))return-1}return r}function r(n,t,e){_.lastIndex=0;var r=_.exec(t.slice(e));return r?(n.w=w.get(r[0].toLowerCase()),e+r[0].length):-1}function i(n,t,e){x.lastIndex=0;var r=x.exec(t.slice(e));return r?(n.w=b.get(r[0].toLowerCase()),e+r[0].length):-1}function u(n,t,e){N.lastIndex=0;var r=N.exec(t.slice(e));return r?(n.m=E.get(r[0].toLowerCase()),e+r[0].length):-1}function o(n,t,e){S.lastIndex=0;var r=S.exec(t.slice(e));return r?(n.m=k.get(r[0].toLowerCase()),e+r[0].length):-1}function a(n,t,r){return e(n,A.c.toString(),t,r)}function l(n,t,r){return e(n,A.x.toString(),t,r)}function c(n,t,r){return e(n,A.X.toString(),t,r)}function f(n,t,e){var r=M.get(t.slice(e,e+=2).toLowerCase());return null==r?-1:(n.p=r,e)}var s=n.dateTime,h=n.date,p=n.time,g=n.periods,v=n.days,d=n.shortDays,y=n.months,m=n.shortMonths;t.utc=function(n){function e(n){try{va=Hn;var t=new va;return t._=n,r(t)}finally{va=Date}}var r=t(n);return e.parse=function(n){try{va=Hn;var t=r.parse(n);return t&&t._}finally{va=Date}},e.toString=r.toString,e},t.multi=t.utc.multi=ct;var M=ao.map(),x=Vn(v),b=Xn(v),_=Vn(d),w=Xn(d),S=Vn(y),k=Xn(y),N=Vn(m),E=Xn(m);g.forEach(function(n,t){M.set(n.toLowerCase(),t)});var A={a:function(n){return d[n.getDay()]},A:function(n){return v[n.getDay()]},b:function(n){return m[n.getMonth()]},B:function(n){return y[n.getMonth()]},c:t(s),d:function(n,t){return Zn(n.getDate(),t,2)},e:function(n,t){return Zn(n.getDate(),t,2)},H:function(n,t){return Zn(n.getHours(),t,2)},I:function(n,t){return Zn(n.getHours()%12||12,t,2)},j:function(n,t){return Zn(1+ga.dayOfYear(n),t,3)},L:function(n,t){return Zn(n.getMilliseconds(),t,3)},m:function(n,t){return Zn(n.getMonth()+1,t,2)},M:function(n,t){return Zn(n.getMinutes(),t,2)},p:function(n){return g[+(n.getHours()>=12)]},S:function(n,t){return Zn(n.getSeconds(),t,2)},U:function(n,t){return Zn(ga.sundayOfYear(n),t,2)},w:function(n){return n.getDay()},W:function(n,t){return Zn(ga.mondayOfYear(n),t,2)},x:t(h),X:t(p),y:function(n,t){return Zn(n.getFullYear()%100,t,2)},Y:function(n,t){return Zn(n.getFullYear()%1e4,t,4)},Z:at,"%":function(){return"%"}},C={a:r,A:i,b:u,B:o,c:a,d:tt,e:tt,H:rt,I:rt,j:et,L:ot,m:nt,M:it,p:f,S:ut,U:Bn,w:$n,W:Wn,x:l,X:c,y:Gn,Y:Jn,Z:Kn,"%":lt};return t}function Zn(n,t,e){var r=0>n?"-":"",i=(r?-n:n)+"",u=i.length;return r+(e>u?new Array(e-u+1).join(t)+i:i)}function Vn(n){return new RegExp("^(?:"+n.map(ao.requote).join("|")+")","i")}function Xn(n){for(var t=new c,e=-1,r=n.length;++e68?1900:2e3)}function nt(n,t,e){ma.lastIndex=0;var r=ma.exec(t.slice(e,e+2));return r?(n.m=r[0]-1,e+r[0].length):-1}function tt(n,t,e){ma.lastIndex=0;var r=ma.exec(t.slice(e,e+2));return r?(n.d=+r[0],e+r[0].length):-1}function et(n,t,e){ma.lastIndex=0;var r=ma.exec(t.slice(e,e+3));return r?(n.j=+r[0],e+r[0].length):-1}function rt(n,t,e){ma.lastIndex=0;var r=ma.exec(t.slice(e,e+2));return r?(n.H=+r[0],e+r[0].length):-1}function it(n,t,e){ma.lastIndex=0;var r=ma.exec(t.slice(e,e+2));return r?(n.M=+r[0],e+r[0].length):-1}function ut(n,t,e){ma.lastIndex=0;var r=ma.exec(t.slice(e,e+2));return r?(n.S=+r[0],e+r[0].length):-1}function ot(n,t,e){ma.lastIndex=0;var r=ma.exec(t.slice(e,e+3));return r?(n.L=+r[0],e+r[0].length):-1}function at(n){var t=n.getTimezoneOffset(),e=t>0?"-":"+",r=xo(t)/60|0,i=xo(t)%60;return e+Zn(r,"0",2)+Zn(i,"0",2)}function lt(n,t,e){Ma.lastIndex=0;var r=Ma.exec(t.slice(e,e+1));return r?e+r[0].length:-1}function ct(n){for(var t=n.length,e=-1;++e=0?1:-1,a=o*e,l=Math.cos(t),c=Math.sin(t),f=u*c,s=i*l+f*Math.cos(a),h=f*o*Math.sin(a);ka.add(Math.atan2(h,s)),r=n,i=l,u=c}var t,e,r,i,u;Na.point=function(o,a){Na.point=n,r=(t=o)*Yo,i=Math.cos(a=(e=a)*Yo/2+Fo/4),u=Math.sin(a)},Na.lineEnd=function(){n(t,e)}}function dt(n){var t=n[0],e=n[1],r=Math.cos(e);return[r*Math.cos(t),r*Math.sin(t),Math.sin(e)]}function yt(n,t){return n[0]*t[0]+n[1]*t[1]+n[2]*t[2]}function mt(n,t){return[n[1]*t[2]-n[2]*t[1],n[2]*t[0]-n[0]*t[2],n[0]*t[1]-n[1]*t[0]]}function Mt(n,t){n[0]+=t[0],n[1]+=t[1],n[2]+=t[2]}function xt(n,t){return[n[0]*t,n[1]*t,n[2]*t]}function bt(n){var t=Math.sqrt(n[0]*n[0]+n[1]*n[1]+n[2]*n[2]);n[0]/=t,n[1]/=t,n[2]/=t}function _t(n){return[Math.atan2(n[1],n[0]),tn(n[2])]}function wt(n,t){return xo(n[0]-t[0])a;++a)i.point((e=n[a])[0],e[1]);return void i.lineEnd()}var l=new Tt(e,n,null,!0),c=new Tt(e,null,l,!1);l.o=c,u.push(l),o.push(c),l=new Tt(r,n,null,!1),c=new Tt(r,null,l,!0),l.o=c,u.push(l),o.push(c)}}),o.sort(t),qt(u),qt(o),u.length){for(var a=0,l=e,c=o.length;c>a;++a)o[a].e=l=!l;for(var f,s,h=u[0];;){for(var p=h,g=!0;p.v;)if((p=p.n)===h)return;f=p.z,i.lineStart();do{if(p.v=p.o.v=!0,p.e){if(g)for(var a=0,c=f.length;c>a;++a)i.point((s=f[a])[0],s[1]);else r(p.x,p.n.x,1,i);p=p.n}else{if(g){f=p.p.z;for(var a=f.length-1;a>=0;--a)i.point((s=f[a])[0],s[1])}else r(p.x,p.p.x,-1,i);p=p.p}p=p.o,f=p.z,g=!g}while(!p.v);i.lineEnd()}}}function qt(n){if(t=n.length){for(var t,e,r=0,i=n[0];++r0){for(b||(u.polygonStart(),b=!0),u.lineStart();++o1&&2&t&&e.push(e.pop().concat(e.shift())),p.push(e.filter(Dt))}var p,g,v,d=t(u),y=i.invert(r[0],r[1]),m={point:o,lineStart:l,lineEnd:c,polygonStart:function(){m.point=f,m.lineStart=s,m.lineEnd=h,p=[],g=[]},polygonEnd:function(){m.point=o,m.lineStart=l,m.lineEnd=c,p=ao.merge(p);var n=Ot(y,g);p.length?(b||(u.polygonStart(),b=!0),Lt(p,Ut,n,e,u)):n&&(b||(u.polygonStart(),b=!0),u.lineStart(),e(null,null,1,u),u.lineEnd()),b&&(u.polygonEnd(),b=!1),p=g=null},sphere:function(){u.polygonStart(),u.lineStart(),e(null,null,1,u),u.lineEnd(),u.polygonEnd()}},M=Pt(),x=t(M),b=!1;return m}}function Dt(n){return n.length>1}function Pt(){var n,t=[];return{lineStart:function(){t.push(n=[])},point:function(t,e){n.push([t,e])},lineEnd:b,buffer:function(){var e=t;return t=[],n=null,e},rejoin:function(){t.length>1&&t.push(t.pop().concat(t.shift()))}}}function Ut(n,t){return((n=n.x)[0]<0?n[1]-Io-Uo:Io-n[1])-((t=t.x)[0]<0?t[1]-Io-Uo:Io-t[1])}function jt(n){var t,e=NaN,r=NaN,i=NaN;return{lineStart:function(){n.lineStart(),t=1},point:function(u,o){var a=u>0?Fo:-Fo,l=xo(u-e);xo(l-Fo)0?Io:-Io),n.point(i,r),n.lineEnd(),n.lineStart(),n.point(a,r),n.point(u,r),t=0):i!==a&&l>=Fo&&(xo(e-i)Uo?Math.atan((Math.sin(t)*(u=Math.cos(r))*Math.sin(e)-Math.sin(r)*(i=Math.cos(t))*Math.sin(n))/(i*u*o)):(t+r)/2}function Ht(n,t,e,r){var i;if(null==n)i=e*Io,r.point(-Fo,i),r.point(0,i),r.point(Fo,i),r.point(Fo,0),r.point(Fo,-i),r.point(0,-i),r.point(-Fo,-i),r.point(-Fo,0),r.point(-Fo,i);else if(xo(n[0]-t[0])>Uo){var u=n[0]a;++a){var c=t[a],f=c.length;if(f)for(var s=c[0],h=s[0],p=s[1]/2+Fo/4,g=Math.sin(p),v=Math.cos(p),d=1;;){d===f&&(d=0),n=c[d];var y=n[0],m=n[1]/2+Fo/4,M=Math.sin(m),x=Math.cos(m),b=y-h,_=b>=0?1:-1,w=_*b,S=w>Fo,k=g*M;if(ka.add(Math.atan2(k*_*Math.sin(w),v*x+k*Math.cos(w))),u+=S?b+_*Ho:b,S^h>=e^y>=e){var N=mt(dt(s),dt(n));bt(N);var E=mt(i,N);bt(E);var A=(S^b>=0?-1:1)*tn(E[2]);(r>A||r===A&&(N[0]||N[1]))&&(o+=S^b>=0?1:-1)}if(!d++)break;h=y,g=M,v=x,s=n}}return(-Uo>u||Uo>u&&-Uo>ka)^1&o}function It(n){function t(n,t){return Math.cos(n)*Math.cos(t)>u}function e(n){var e,u,l,c,f;return{lineStart:function(){c=l=!1,f=1},point:function(s,h){var p,g=[s,h],v=t(s,h),d=o?v?0:i(s,h):v?i(s+(0>s?Fo:-Fo),h):0;if(!e&&(c=l=v)&&n.lineStart(),v!==l&&(p=r(e,g),(wt(e,p)||wt(g,p))&&(g[0]+=Uo,g[1]+=Uo,v=t(g[0],g[1]))),v!==l)f=0,v?(n.lineStart(),p=r(g,e),n.point(p[0],p[1])):(p=r(e,g),n.point(p[0],p[1]),n.lineEnd()),e=p;else if(a&&e&&o^v){var y;d&u||!(y=r(g,e,!0))||(f=0,o?(n.lineStart(),n.point(y[0][0],y[0][1]),n.point(y[1][0],y[1][1]),n.lineEnd()):(n.point(y[1][0],y[1][1]),n.lineEnd(),n.lineStart(),n.point(y[0][0],y[0][1])))}!v||e&&wt(e,g)||n.point(g[0],g[1]),e=g,l=v,u=d},lineEnd:function(){l&&n.lineEnd(),e=null},clean:function(){return f|(c&&l)<<1}}}function r(n,t,e){var r=dt(n),i=dt(t),o=[1,0,0],a=mt(r,i),l=yt(a,a),c=a[0],f=l-c*c;if(!f)return!e&&n;var s=u*l/f,h=-u*c/f,p=mt(o,a),g=xt(o,s),v=xt(a,h);Mt(g,v);var d=p,y=yt(g,d),m=yt(d,d),M=y*y-m*(yt(g,g)-1);if(!(0>M)){var x=Math.sqrt(M),b=xt(d,(-y-x)/m);if(Mt(b,g),b=_t(b),!e)return b;var _,w=n[0],S=t[0],k=n[1],N=t[1];w>S&&(_=w,w=S,S=_);var E=S-w,A=xo(E-Fo)E;if(!A&&k>N&&(_=k,k=N,N=_),C?A?k+N>0^b[1]<(xo(b[0]-w)Fo^(w<=b[0]&&b[0]<=S)){var z=xt(d,(-y+x)/m);return Mt(z,g),[b,_t(z)]}}}function i(t,e){var r=o?n:Fo-n,i=0;return-r>t?i|=1:t>r&&(i|=2),-r>e?i|=4:e>r&&(i|=8),i}var u=Math.cos(n),o=u>0,a=xo(u)>Uo,l=ve(n,6*Yo);return Rt(t,e,l,o?[0,-n]:[-Fo,n-Fo])}function Yt(n,t,e,r){return function(i){var u,o=i.a,a=i.b,l=o.x,c=o.y,f=a.x,s=a.y,h=0,p=1,g=f-l,v=s-c;if(u=n-l,g||!(u>0)){if(u/=g,0>g){if(h>u)return;p>u&&(p=u)}else if(g>0){if(u>p)return;u>h&&(h=u)}if(u=e-l,g||!(0>u)){if(u/=g,0>g){if(u>p)return;u>h&&(h=u)}else if(g>0){if(h>u)return;p>u&&(p=u)}if(u=t-c,v||!(u>0)){if(u/=v,0>v){if(h>u)return;p>u&&(p=u)}else if(v>0){if(u>p)return;u>h&&(h=u)}if(u=r-c,v||!(0>u)){if(u/=v,0>v){if(u>p)return;u>h&&(h=u)}else if(v>0){if(h>u)return;p>u&&(p=u)}return h>0&&(i.a={x:l+h*g,y:c+h*v}),1>p&&(i.b={x:l+p*g,y:c+p*v}),i}}}}}}function Zt(n,t,e,r){function i(r,i){return xo(r[0]-n)0?0:3:xo(r[0]-e)0?2:1:xo(r[1]-t)0?1:0:i>0?3:2}function u(n,t){return o(n.x,t.x)}function o(n,t){var e=i(n,1),r=i(t,1);return e!==r?e-r:0===e?t[1]-n[1]:1===e?n[0]-t[0]:2===e?n[1]-t[1]:t[0]-n[0]}return function(a){function l(n){for(var t=0,e=d.length,r=n[1],i=0;e>i;++i)for(var u,o=1,a=d[i],l=a.length,c=a[0];l>o;++o)u=a[o],c[1]<=r?u[1]>r&&Q(c,u,n)>0&&++t:u[1]<=r&&Q(c,u,n)<0&&--t,c=u;return 0!==t}function c(u,a,l,c){var f=0,s=0;if(null==u||(f=i(u,l))!==(s=i(a,l))||o(u,a)<0^l>0){do c.point(0===f||3===f?n:e,f>1?r:t);while((f=(f+l+4)%4)!==s)}else c.point(a[0],a[1])}function f(i,u){return i>=n&&e>=i&&u>=t&&r>=u}function s(n,t){f(n,t)&&a.point(n,t)}function h(){C.point=g,d&&d.push(y=[]),S=!0,w=!1,b=_=NaN}function p(){v&&(g(m,M),x&&w&&E.rejoin(),v.push(E.buffer())),C.point=s,w&&a.lineEnd()}function g(n,t){n=Math.max(-Ha,Math.min(Ha,n)),t=Math.max(-Ha,Math.min(Ha,t));var e=f(n,t);if(d&&y.push([n,t]),S)m=n,M=t,x=e,S=!1,e&&(a.lineStart(),a.point(n,t));else if(e&&w)a.point(n,t);else{var r={a:{x:b,y:_},b:{x:n,y:t}};A(r)?(w||(a.lineStart(),a.point(r.a.x,r.a.y)),a.point(r.b.x,r.b.y),e||a.lineEnd(),k=!1):e&&(a.lineStart(),a.point(n,t),k=!1)}b=n,_=t,w=e}var v,d,y,m,M,x,b,_,w,S,k,N=a,E=Pt(),A=Yt(n,t,e,r),C={point:s,lineStart:h,lineEnd:p,polygonStart:function(){a=E,v=[],d=[],k=!0},polygonEnd:function(){a=N,v=ao.merge(v);var t=l([n,r]),e=k&&t,i=v.length;(e||i)&&(a.polygonStart(),e&&(a.lineStart(),c(null,null,1,a),a.lineEnd()),i&&Lt(v,u,t,c,a),a.polygonEnd()),v=d=y=null}};return C}}function Vt(n){var t=0,e=Fo/3,r=ae(n),i=r(t,e);return i.parallels=function(n){return arguments.length?r(t=n[0]*Fo/180,e=n[1]*Fo/180):[t/Fo*180,e/Fo*180]},i}function Xt(n,t){function e(n,t){var e=Math.sqrt(u-2*i*Math.sin(t))/i;return[e*Math.sin(n*=i),o-e*Math.cos(n)]}var r=Math.sin(n),i=(r+Math.sin(t))/2,u=1+r*(2*i-r),o=Math.sqrt(u)/i;return e.invert=function(n,t){var e=o-t;return[Math.atan2(n,e)/i,tn((u-(n*n+e*e)*i*i)/(2*i))]},e}function $t(){function n(n,t){Ia+=i*n-r*t,r=n,i=t}var t,e,r,i;$a.point=function(u,o){$a.point=n,t=r=u,e=i=o},$a.lineEnd=function(){n(t,e)}}function Bt(n,t){Ya>n&&(Ya=n),n>Va&&(Va=n),Za>t&&(Za=t),t>Xa&&(Xa=t)}function Wt(){function n(n,t){o.push("M",n,",",t,u)}function t(n,t){o.push("M",n,",",t),a.point=e}function e(n,t){o.push("L",n,",",t)}function r(){a.point=n}function i(){o.push("Z")}var u=Jt(4.5),o=[],a={point:n,lineStart:function(){a.point=t},lineEnd:r,polygonStart:function(){a.lineEnd=i},polygonEnd:function(){a.lineEnd=r,a.point=n},pointRadius:function(n){return u=Jt(n),a},result:function(){if(o.length){var n=o.join("");return o=[],n}}};return a}function Jt(n){return"m0,"+n+"a"+n+","+n+" 0 1,1 0,"+-2*n+"a"+n+","+n+" 0 1,1 0,"+2*n+"z"}function Gt(n,t){Ca+=n,za+=t,++La}function Kt(){function n(n,r){var i=n-t,u=r-e,o=Math.sqrt(i*i+u*u);qa+=o*(t+n)/2,Ta+=o*(e+r)/2,Ra+=o,Gt(t=n,e=r)}var t,e;Wa.point=function(r,i){Wa.point=n,Gt(t=r,e=i)}}function Qt(){Wa.point=Gt}function ne(){function n(n,t){var e=n-r,u=t-i,o=Math.sqrt(e*e+u*u);qa+=o*(r+n)/2,Ta+=o*(i+t)/2,Ra+=o,o=i*n-r*t,Da+=o*(r+n),Pa+=o*(i+t),Ua+=3*o,Gt(r=n,i=t)}var t,e,r,i;Wa.point=function(u,o){Wa.point=n,Gt(t=r=u,e=i=o)},Wa.lineEnd=function(){n(t,e)}}function te(n){function t(t,e){n.moveTo(t+o,e),n.arc(t,e,o,0,Ho)}function e(t,e){n.moveTo(t,e),a.point=r}function r(t,e){n.lineTo(t,e)}function i(){a.point=t}function u(){n.closePath()}var o=4.5,a={point:t,lineStart:function(){a.point=e},lineEnd:i,polygonStart:function(){a.lineEnd=u},polygonEnd:function(){a.lineEnd=i,a.point=t},pointRadius:function(n){return o=n,a},result:b};return a}function ee(n){function t(n){return(a?r:e)(n)}function e(t){return ue(t,function(e,r){e=n(e,r),t.point(e[0],e[1])})}function r(t){function e(e,r){e=n(e,r),t.point(e[0],e[1])}function r(){M=NaN,S.point=u,t.lineStart()}function u(e,r){var u=dt([e,r]),o=n(e,r);i(M,x,m,b,_,w,M=o[0],x=o[1],m=e,b=u[0],_=u[1],w=u[2],a,t),t.point(M,x)}function o(){S.point=e,t.lineEnd()}function l(){ -r(),S.point=c,S.lineEnd=f}function c(n,t){u(s=n,h=t),p=M,g=x,v=b,d=_,y=w,S.point=u}function f(){i(M,x,m,b,_,w,p,g,s,v,d,y,a,t),S.lineEnd=o,o()}var s,h,p,g,v,d,y,m,M,x,b,_,w,S={point:e,lineStart:r,lineEnd:o,polygonStart:function(){t.polygonStart(),S.lineStart=l},polygonEnd:function(){t.polygonEnd(),S.lineStart=r}};return S}function i(t,e,r,a,l,c,f,s,h,p,g,v,d,y){var m=f-t,M=s-e,x=m*m+M*M;if(x>4*u&&d--){var b=a+p,_=l+g,w=c+v,S=Math.sqrt(b*b+_*_+w*w),k=Math.asin(w/=S),N=xo(xo(w)-1)u||xo((m*z+M*L)/x-.5)>.3||o>a*p+l*g+c*v)&&(i(t,e,r,a,l,c,A,C,N,b/=S,_/=S,w,d,y),y.point(A,C),i(A,C,N,b,_,w,f,s,h,p,g,v,d,y))}}var u=.5,o=Math.cos(30*Yo),a=16;return t.precision=function(n){return arguments.length?(a=(u=n*n)>0&&16,t):Math.sqrt(u)},t}function re(n){var t=ee(function(t,e){return n([t*Zo,e*Zo])});return function(n){return le(t(n))}}function ie(n){this.stream=n}function ue(n,t){return{point:t,sphere:function(){n.sphere()},lineStart:function(){n.lineStart()},lineEnd:function(){n.lineEnd()},polygonStart:function(){n.polygonStart()},polygonEnd:function(){n.polygonEnd()}}}function oe(n){return ae(function(){return n})()}function ae(n){function t(n){return n=a(n[0]*Yo,n[1]*Yo),[n[0]*h+l,c-n[1]*h]}function e(n){return n=a.invert((n[0]-l)/h,(c-n[1])/h),n&&[n[0]*Zo,n[1]*Zo]}function r(){a=Ct(o=se(y,M,x),u);var n=u(v,d);return l=p-n[0]*h,c=g+n[1]*h,i()}function i(){return f&&(f.valid=!1,f=null),t}var u,o,a,l,c,f,s=ee(function(n,t){return n=u(n,t),[n[0]*h+l,c-n[1]*h]}),h=150,p=480,g=250,v=0,d=0,y=0,M=0,x=0,b=Fa,_=m,w=null,S=null;return t.stream=function(n){return f&&(f.valid=!1),f=le(b(o,s(_(n)))),f.valid=!0,f},t.clipAngle=function(n){return arguments.length?(b=null==n?(w=n,Fa):It((w=+n)*Yo),i()):w},t.clipExtent=function(n){return arguments.length?(S=n,_=n?Zt(n[0][0],n[0][1],n[1][0],n[1][1]):m,i()):S},t.scale=function(n){return arguments.length?(h=+n,r()):h},t.translate=function(n){return arguments.length?(p=+n[0],g=+n[1],r()):[p,g]},t.center=function(n){return arguments.length?(v=n[0]%360*Yo,d=n[1]%360*Yo,r()):[v*Zo,d*Zo]},t.rotate=function(n){return arguments.length?(y=n[0]%360*Yo,M=n[1]%360*Yo,x=n.length>2?n[2]%360*Yo:0,r()):[y*Zo,M*Zo,x*Zo]},ao.rebind(t,s,"precision"),function(){return u=n.apply(this,arguments),t.invert=u.invert&&e,r()}}function le(n){return ue(n,function(t,e){n.point(t*Yo,e*Yo)})}function ce(n,t){return[n,t]}function fe(n,t){return[n>Fo?n-Ho:-Fo>n?n+Ho:n,t]}function se(n,t,e){return n?t||e?Ct(pe(n),ge(t,e)):pe(n):t||e?ge(t,e):fe}function he(n){return function(t,e){return t+=n,[t>Fo?t-Ho:-Fo>t?t+Ho:t,e]}}function pe(n){var t=he(n);return t.invert=he(-n),t}function ge(n,t){function e(n,t){var e=Math.cos(t),a=Math.cos(n)*e,l=Math.sin(n)*e,c=Math.sin(t),f=c*r+a*i;return[Math.atan2(l*u-f*o,a*r-c*i),tn(f*u+l*o)]}var r=Math.cos(n),i=Math.sin(n),u=Math.cos(t),o=Math.sin(t);return e.invert=function(n,t){var e=Math.cos(t),a=Math.cos(n)*e,l=Math.sin(n)*e,c=Math.sin(t),f=c*u-l*o;return[Math.atan2(l*u+c*o,a*r+f*i),tn(f*r-a*i)]},e}function ve(n,t){var e=Math.cos(n),r=Math.sin(n);return function(i,u,o,a){var l=o*t;null!=i?(i=de(e,i),u=de(e,u),(o>0?u>i:i>u)&&(i+=o*Ho)):(i=n+o*Ho,u=n-.5*l);for(var c,f=i;o>0?f>u:u>f;f-=l)a.point((c=_t([e,-r*Math.cos(f),-r*Math.sin(f)]))[0],c[1])}}function de(n,t){var e=dt(t);e[0]-=n,bt(e);var r=nn(-e[1]);return((-e[2]<0?-r:r)+2*Math.PI-Uo)%(2*Math.PI)}function ye(n,t,e){var r=ao.range(n,t-Uo,e).concat(t);return function(n){return r.map(function(t){return[n,t]})}}function me(n,t,e){var r=ao.range(n,t-Uo,e).concat(t);return function(n){return r.map(function(t){return[t,n]})}}function Me(n){return n.source}function xe(n){return n.target}function be(n,t,e,r){var i=Math.cos(t),u=Math.sin(t),o=Math.cos(r),a=Math.sin(r),l=i*Math.cos(n),c=i*Math.sin(n),f=o*Math.cos(e),s=o*Math.sin(e),h=2*Math.asin(Math.sqrt(on(r-t)+i*o*on(e-n))),p=1/Math.sin(h),g=h?function(n){var t=Math.sin(n*=h)*p,e=Math.sin(h-n)*p,r=e*l+t*f,i=e*c+t*s,o=e*u+t*a;return[Math.atan2(i,r)*Zo,Math.atan2(o,Math.sqrt(r*r+i*i))*Zo]}:function(){return[n*Zo,t*Zo]};return g.distance=h,g}function _e(){function n(n,i){var u=Math.sin(i*=Yo),o=Math.cos(i),a=xo((n*=Yo)-t),l=Math.cos(a);Ja+=Math.atan2(Math.sqrt((a=o*Math.sin(a))*a+(a=r*u-e*o*l)*a),e*u+r*o*l),t=n,e=u,r=o}var t,e,r;Ga.point=function(i,u){t=i*Yo,e=Math.sin(u*=Yo),r=Math.cos(u),Ga.point=n},Ga.lineEnd=function(){Ga.point=Ga.lineEnd=b}}function we(n,t){function e(t,e){var r=Math.cos(t),i=Math.cos(e),u=n(r*i);return[u*i*Math.sin(t),u*Math.sin(e)]}return e.invert=function(n,e){var r=Math.sqrt(n*n+e*e),i=t(r),u=Math.sin(i),o=Math.cos(i);return[Math.atan2(n*u,r*o),Math.asin(r&&e*u/r)]},e}function Se(n,t){function e(n,t){o>0?-Io+Uo>t&&(t=-Io+Uo):t>Io-Uo&&(t=Io-Uo);var e=o/Math.pow(i(t),u);return[e*Math.sin(u*n),o-e*Math.cos(u*n)]}var r=Math.cos(n),i=function(n){return Math.tan(Fo/4+n/2)},u=n===t?Math.sin(n):Math.log(r/Math.cos(t))/Math.log(i(t)/i(n)),o=r*Math.pow(i(n),u)/u;return u?(e.invert=function(n,t){var e=o-t,r=K(u)*Math.sqrt(n*n+e*e);return[Math.atan2(n,e)/u,2*Math.atan(Math.pow(o/r,1/u))-Io]},e):Ne}function ke(n,t){function e(n,t){var e=u-t;return[e*Math.sin(i*n),u-e*Math.cos(i*n)]}var r=Math.cos(n),i=n===t?Math.sin(n):(r-Math.cos(t))/(t-n),u=r/i+n;return xo(i)i;i++){for(;r>1&&Q(n[e[r-2]],n[e[r-1]],n[i])<=0;)--r;e[r++]=i}return e.slice(0,r)}function qe(n,t){return n[0]-t[0]||n[1]-t[1]}function Te(n,t,e){return(e[0]-t[0])*(n[1]-t[1])<(e[1]-t[1])*(n[0]-t[0])}function Re(n,t,e,r){var i=n[0],u=e[0],o=t[0]-i,a=r[0]-u,l=n[1],c=e[1],f=t[1]-l,s=r[1]-c,h=(a*(l-c)-s*(i-u))/(s*o-a*f);return[i+h*o,l+h*f]}function De(n){var t=n[0],e=n[n.length-1];return!(t[0]-e[0]||t[1]-e[1])}function Pe(){rr(this),this.edge=this.site=this.circle=null}function Ue(n){var t=cl.pop()||new Pe;return t.site=n,t}function je(n){Be(n),ol.remove(n),cl.push(n),rr(n)}function Fe(n){var t=n.circle,e=t.x,r=t.cy,i={x:e,y:r},u=n.P,o=n.N,a=[n];je(n);for(var l=u;l.circle&&xo(e-l.circle.x)f;++f)c=a[f],l=a[f-1],nr(c.edge,l.site,c.site,i);l=a[0],c=a[s-1],c.edge=Ke(l.site,c.site,null,i),$e(l),$e(c)}function He(n){for(var t,e,r,i,u=n.x,o=n.y,a=ol._;a;)if(r=Oe(a,o)-u,r>Uo)a=a.L;else{if(i=u-Ie(a,o),!(i>Uo)){r>-Uo?(t=a.P,e=a):i>-Uo?(t=a,e=a.N):t=e=a;break}if(!a.R){t=a;break}a=a.R}var l=Ue(n);if(ol.insert(t,l),t||e){if(t===e)return Be(t),e=Ue(t.site),ol.insert(l,e),l.edge=e.edge=Ke(t.site,l.site),$e(t),void $e(e);if(!e)return void(l.edge=Ke(t.site,l.site));Be(t),Be(e);var c=t.site,f=c.x,s=c.y,h=n.x-f,p=n.y-s,g=e.site,v=g.x-f,d=g.y-s,y=2*(h*d-p*v),m=h*h+p*p,M=v*v+d*d,x={x:(d*m-p*M)/y+f,y:(h*M-v*m)/y+s};nr(e.edge,c,g,x),l.edge=Ke(c,n,null,x),e.edge=Ke(n,g,null,x),$e(t),$e(e)}}function Oe(n,t){var e=n.site,r=e.x,i=e.y,u=i-t;if(!u)return r;var o=n.P;if(!o)return-(1/0);e=o.site;var a=e.x,l=e.y,c=l-t;if(!c)return a;var f=a-r,s=1/u-1/c,h=f/c;return s?(-h+Math.sqrt(h*h-2*s*(f*f/(-2*c)-l+c/2+i-u/2)))/s+r:(r+a)/2}function Ie(n,t){var e=n.N;if(e)return Oe(e,t);var r=n.site;return r.y===t?r.x:1/0}function Ye(n){this.site=n,this.edges=[]}function Ze(n){for(var t,e,r,i,u,o,a,l,c,f,s=n[0][0],h=n[1][0],p=n[0][1],g=n[1][1],v=ul,d=v.length;d--;)if(u=v[d],u&&u.prepare())for(a=u.edges,l=a.length,o=0;l>o;)f=a[o].end(),r=f.x,i=f.y,c=a[++o%l].start(),t=c.x,e=c.y,(xo(r-t)>Uo||xo(i-e)>Uo)&&(a.splice(o,0,new tr(Qe(u.site,f,xo(r-s)Uo?{x:s,y:xo(t-s)Uo?{x:xo(e-g)Uo?{x:h,y:xo(t-h)Uo?{x:xo(e-p)=-jo)){var p=l*l+c*c,g=f*f+s*s,v=(s*p-c*g)/h,d=(l*g-f*p)/h,s=d+a,y=fl.pop()||new Xe;y.arc=n,y.site=i,y.x=v+o,y.y=s+Math.sqrt(v*v+d*d),y.cy=s,n.circle=y;for(var m=null,M=ll._;M;)if(y.yd||d>=a)return;if(h>g){if(u){if(u.y>=c)return}else u={x:d,y:l};e={x:d,y:c}}else{if(u){if(u.yr||r>1)if(h>g){if(u){if(u.y>=c)return}else u={x:(l-i)/r,y:l};e={x:(c-i)/r,y:c}}else{if(u){if(u.yp){if(u){if(u.x>=a)return}else u={x:o,y:r*o+i};e={x:a,y:r*a+i}}else{if(u){if(u.xu||s>o||r>h||i>p)){if(g=n.point){var g,v=t-n.x,d=e-n.y,y=v*v+d*d;if(l>y){var m=Math.sqrt(l=y);r=t-m,i=e-m,u=t+m,o=e+m,a=g}}for(var M=n.nodes,x=.5*(f+h),b=.5*(s+p),_=t>=x,w=e>=b,S=w<<1|_,k=S+4;k>S;++S)if(n=M[3&S])switch(3&S){case 0:c(n,f,s,x,b);break;case 1:c(n,x,s,h,b);break;case 2:c(n,f,b,x,p);break;case 3:c(n,x,b,h,p)}}}(n,r,i,u,o),a}function vr(n,t){n=ao.rgb(n),t=ao.rgb(t);var e=n.r,r=n.g,i=n.b,u=t.r-e,o=t.g-r,a=t.b-i;return function(n){return"#"+bn(Math.round(e+u*n))+bn(Math.round(r+o*n))+bn(Math.round(i+a*n))}}function dr(n,t){var e,r={},i={};for(e in n)e in t?r[e]=Mr(n[e],t[e]):i[e]=n[e];for(e in t)e in n||(i[e]=t[e]);return function(n){for(e in r)i[e]=r[e](n);return i}}function yr(n,t){return n=+n,t=+t,function(e){return n*(1-e)+t*e}}function mr(n,t){var e,r,i,u=hl.lastIndex=pl.lastIndex=0,o=-1,a=[],l=[];for(n+="",t+="";(e=hl.exec(n))&&(r=pl.exec(t));)(i=r.index)>u&&(i=t.slice(u,i),a[o]?a[o]+=i:a[++o]=i),(e=e[0])===(r=r[0])?a[o]?a[o]+=r:a[++o]=r:(a[++o]=null,l.push({i:o,x:yr(e,r)})),u=pl.lastIndex;return ur;++r)a[(e=l[r]).i]=e.x(n);return a.join("")})}function Mr(n,t){for(var e,r=ao.interpolators.length;--r>=0&&!(e=ao.interpolators[r](n,t)););return e}function xr(n,t){var e,r=[],i=[],u=n.length,o=t.length,a=Math.min(n.length,t.length);for(e=0;a>e;++e)r.push(Mr(n[e],t[e]));for(;u>e;++e)i[e]=n[e];for(;o>e;++e)i[e]=t[e];return function(n){for(e=0;a>e;++e)i[e]=r[e](n);return i}}function br(n){return function(t){return 0>=t?0:t>=1?1:n(t)}}function _r(n){return function(t){return 1-n(1-t)}}function wr(n){return function(t){return.5*(.5>t?n(2*t):2-n(2-2*t))}}function Sr(n){return n*n}function kr(n){return n*n*n}function Nr(n){if(0>=n)return 0;if(n>=1)return 1;var t=n*n,e=t*n;return 4*(.5>n?e:3*(n-t)+e-.75)}function Er(n){return function(t){return Math.pow(t,n)}}function Ar(n){return 1-Math.cos(n*Io)}function Cr(n){return Math.pow(2,10*(n-1))}function zr(n){return 1-Math.sqrt(1-n*n)}function Lr(n,t){var e;return arguments.length<2&&(t=.45),arguments.length?e=t/Ho*Math.asin(1/n):(n=1,e=t/4),function(r){return 1+n*Math.pow(2,-10*r)*Math.sin((r-e)*Ho/t)}}function qr(n){return n||(n=1.70158),function(t){return t*t*((n+1)*t-n)}}function Tr(n){return 1/2.75>n?7.5625*n*n:2/2.75>n?7.5625*(n-=1.5/2.75)*n+.75:2.5/2.75>n?7.5625*(n-=2.25/2.75)*n+.9375:7.5625*(n-=2.625/2.75)*n+.984375}function Rr(n,t){n=ao.hcl(n),t=ao.hcl(t);var e=n.h,r=n.c,i=n.l,u=t.h-e,o=t.c-r,a=t.l-i;return isNaN(o)&&(o=0,r=isNaN(r)?t.c:r),isNaN(u)?(u=0,e=isNaN(e)?t.h:e):u>180?u-=360:-180>u&&(u+=360),function(n){return sn(e+u*n,r+o*n,i+a*n)+""}}function Dr(n,t){n=ao.hsl(n),t=ao.hsl(t);var e=n.h,r=n.s,i=n.l,u=t.h-e,o=t.s-r,a=t.l-i;return isNaN(o)&&(o=0,r=isNaN(r)?t.s:r),isNaN(u)?(u=0,e=isNaN(e)?t.h:e):u>180?u-=360:-180>u&&(u+=360),function(n){return cn(e+u*n,r+o*n,i+a*n)+""}}function Pr(n,t){n=ao.lab(n),t=ao.lab(t);var e=n.l,r=n.a,i=n.b,u=t.l-e,o=t.a-r,a=t.b-i;return function(n){return pn(e+u*n,r+o*n,i+a*n)+""}}function Ur(n,t){return t-=n,function(e){return Math.round(n+t*e)}}function jr(n){var t=[n.a,n.b],e=[n.c,n.d],r=Hr(t),i=Fr(t,e),u=Hr(Or(e,t,-i))||0;t[0]*e[1]180?t+=360:t-n>180&&(n+=360),r.push({i:e.push(Ir(e)+"rotate(",null,")")-2,x:yr(n,t)})):t&&e.push(Ir(e)+"rotate("+t+")")}function Vr(n,t,e,r){n!==t?r.push({i:e.push(Ir(e)+"skewX(",null,")")-2,x:yr(n,t)}):t&&e.push(Ir(e)+"skewX("+t+")")}function Xr(n,t,e,r){if(n[0]!==t[0]||n[1]!==t[1]){var i=e.push(Ir(e)+"scale(",null,",",null,")");r.push({i:i-4,x:yr(n[0],t[0])},{i:i-2,x:yr(n[1],t[1])})}else 1===t[0]&&1===t[1]||e.push(Ir(e)+"scale("+t+")")}function $r(n,t){var e=[],r=[];return n=ao.transform(n),t=ao.transform(t),Yr(n.translate,t.translate,e,r),Zr(n.rotate,t.rotate,e,r),Vr(n.skew,t.skew,e,r),Xr(n.scale,t.scale,e,r),n=t=null,function(n){for(var t,i=-1,u=r.length;++i=0;)e.push(i[r])}function oi(n,t){for(var e=[n],r=[];null!=(n=e.pop());)if(r.push(n),(u=n.children)&&(i=u.length))for(var i,u,o=-1;++oe;++e)(t=n[e][1])>i&&(r=e,i=t);return r}function yi(n){return n.reduce(mi,0)}function mi(n,t){return n+t[1]}function Mi(n,t){return xi(n,Math.ceil(Math.log(t.length)/Math.LN2+1))}function xi(n,t){for(var e=-1,r=+n[0],i=(n[1]-r)/t,u=[];++e<=t;)u[e]=i*e+r;return u}function bi(n){return[ao.min(n),ao.max(n)]}function _i(n,t){return n.value-t.value}function wi(n,t){var e=n._pack_next;n._pack_next=t,t._pack_prev=n,t._pack_next=e,e._pack_prev=t}function Si(n,t){n._pack_next=t,t._pack_prev=n}function ki(n,t){var e=t.x-n.x,r=t.y-n.y,i=n.r+t.r;return.999*i*i>e*e+r*r}function Ni(n){function t(n){f=Math.min(n.x-n.r,f),s=Math.max(n.x+n.r,s),h=Math.min(n.y-n.r,h),p=Math.max(n.y+n.r,p)}if((e=n.children)&&(c=e.length)){var e,r,i,u,o,a,l,c,f=1/0,s=-(1/0),h=1/0,p=-(1/0);if(e.forEach(Ei),r=e[0],r.x=-r.r,r.y=0,t(r),c>1&&(i=e[1],i.x=i.r,i.y=0,t(i),c>2))for(u=e[2],zi(r,i,u),t(u),wi(r,u),r._pack_prev=u,wi(u,i),i=r._pack_next,o=3;c>o;o++){zi(r,i,u=e[o]);var g=0,v=1,d=1;for(a=i._pack_next;a!==i;a=a._pack_next,v++)if(ki(a,u)){g=1;break}if(1==g)for(l=r._pack_prev;l!==a._pack_prev&&!ki(l,u);l=l._pack_prev,d++);g?(d>v||v==d&&i.ro;o++)u=e[o],u.x-=y,u.y-=m,M=Math.max(M,u.r+Math.sqrt(u.x*u.x+u.y*u.y));n.r=M,e.forEach(Ai)}}function Ei(n){n._pack_next=n._pack_prev=n}function Ai(n){delete n._pack_next,delete n._pack_prev}function Ci(n,t,e,r){var i=n.children;if(n.x=t+=r*n.x,n.y=e+=r*n.y,n.r*=r,i)for(var u=-1,o=i.length;++u=0;)t=i[u],t.z+=e,t.m+=e,e+=t.s+(r+=t.c)}function Pi(n,t,e){return n.a.parent===t.parent?n.a:e}function Ui(n){return 1+ao.max(n,function(n){return n.y})}function ji(n){return n.reduce(function(n,t){return n+t.x},0)/n.length}function Fi(n){var t=n.children;return t&&t.length?Fi(t[0]):n}function Hi(n){var t,e=n.children;return e&&(t=e.length)?Hi(e[t-1]):n}function Oi(n){return{x:n.x,y:n.y,dx:n.dx,dy:n.dy}}function Ii(n,t){var e=n.x+t[3],r=n.y+t[0],i=n.dx-t[1]-t[3],u=n.dy-t[0]-t[2];return 0>i&&(e+=i/2,i=0),0>u&&(r+=u/2,u=0),{x:e,y:r,dx:i,dy:u}}function Yi(n){var t=n[0],e=n[n.length-1];return e>t?[t,e]:[e,t]}function Zi(n){return n.rangeExtent?n.rangeExtent():Yi(n.range())}function Vi(n,t,e,r){var i=e(n[0],n[1]),u=r(t[0],t[1]);return function(n){return u(i(n))}}function Xi(n,t){var e,r=0,i=n.length-1,u=n[r],o=n[i];return u>o&&(e=r,r=i,i=e,e=u,u=o,o=e),n[r]=t.floor(u),n[i]=t.ceil(o),n}function $i(n){return n?{floor:function(t){return Math.floor(t/n)*n},ceil:function(t){return Math.ceil(t/n)*n}}:Sl}function Bi(n,t,e,r){var i=[],u=[],o=0,a=Math.min(n.length,t.length)-1;for(n[a]2?Bi:Vi,l=r?Wr:Br;return o=i(n,t,l,e),a=i(t,n,l,Mr),u}function u(n){return o(n)}var o,a;return u.invert=function(n){return a(n)},u.domain=function(t){return arguments.length?(n=t.map(Number),i()):n},u.range=function(n){return arguments.length?(t=n,i()):t},u.rangeRound=function(n){return u.range(n).interpolate(Ur)},u.clamp=function(n){return arguments.length?(r=n,i()):r},u.interpolate=function(n){return arguments.length?(e=n,i()):e},u.ticks=function(t){return Qi(n,t)},u.tickFormat=function(t,e){return nu(n,t,e)},u.nice=function(t){return Gi(n,t),i()},u.copy=function(){return Wi(n,t,e,r)},i()}function Ji(n,t){return ao.rebind(n,t,"range","rangeRound","interpolate","clamp")}function Gi(n,t){return Xi(n,$i(Ki(n,t)[2])),Xi(n,$i(Ki(n,t)[2])),n}function Ki(n,t){null==t&&(t=10);var e=Yi(n),r=e[1]-e[0],i=Math.pow(10,Math.floor(Math.log(r/t)/Math.LN10)),u=t/r*i;return.15>=u?i*=10:.35>=u?i*=5:.75>=u&&(i*=2),e[0]=Math.ceil(e[0]/i)*i,e[1]=Math.floor(e[1]/i)*i+.5*i,e[2]=i,e}function Qi(n,t){return ao.range.apply(ao,Ki(n,t))}function nu(n,t,e){var r=Ki(n,t);if(e){var i=ha.exec(e);if(i.shift(),"s"===i[8]){var u=ao.formatPrefix(Math.max(xo(r[0]),xo(r[1])));return i[7]||(i[7]="."+tu(u.scale(r[2]))),i[8]="f",e=ao.format(i.join("")),function(n){return e(u.scale(n))+u.symbol}}i[7]||(i[7]="."+eu(i[8],r)),e=i.join("")}else e=",."+tu(r[2])+"f";return ao.format(e)}function tu(n){return-Math.floor(Math.log(n)/Math.LN10+.01)}function eu(n,t){var e=tu(t[2]);return n in kl?Math.abs(e-tu(Math.max(xo(t[0]),xo(t[1]))))+ +("e"!==n):e-2*("%"===n)}function ru(n,t,e,r){function i(n){return(e?Math.log(0>n?0:n):-Math.log(n>0?0:-n))/Math.log(t)}function u(n){return e?Math.pow(t,n):-Math.pow(t,-n)}function o(t){return n(i(t))}return o.invert=function(t){return u(n.invert(t))},o.domain=function(t){return arguments.length?(e=t[0]>=0,n.domain((r=t.map(Number)).map(i)),o):r},o.base=function(e){return arguments.length?(t=+e,n.domain(r.map(i)),o):t},o.nice=function(){var t=Xi(r.map(i),e?Math:El);return n.domain(t),r=t.map(u),o},o.ticks=function(){var n=Yi(r),o=[],a=n[0],l=n[1],c=Math.floor(i(a)),f=Math.ceil(i(l)),s=t%1?2:t;if(isFinite(f-c)){if(e){for(;f>c;c++)for(var h=1;s>h;h++)o.push(u(c)*h);o.push(u(c))}else for(o.push(u(c));c++0;h--)o.push(u(c)*h);for(c=0;o[c]l;f--);o=o.slice(c,f)}return o},o.tickFormat=function(n,e){if(!arguments.length)return Nl;arguments.length<2?e=Nl:"function"!=typeof e&&(e=ao.format(e));var r=Math.max(1,t*n/o.ticks().length);return function(n){var o=n/u(Math.round(i(n)));return t-.5>o*t&&(o*=t),r>=o?e(n):""}},o.copy=function(){return ru(n.copy(),t,e,r)},Ji(o,n)}function iu(n,t,e){function r(t){return n(i(t))}var i=uu(t),u=uu(1/t);return r.invert=function(t){return u(n.invert(t))},r.domain=function(t){return arguments.length?(n.domain((e=t.map(Number)).map(i)),r):e},r.ticks=function(n){return Qi(e,n)},r.tickFormat=function(n,t){return nu(e,n,t)},r.nice=function(n){return r.domain(Gi(e,n))},r.exponent=function(o){return arguments.length?(i=uu(t=o),u=uu(1/t),n.domain(e.map(i)),r):t},r.copy=function(){return iu(n.copy(),t,e)},Ji(r,n)}function uu(n){return function(t){return 0>t?-Math.pow(-t,n):Math.pow(t,n)}}function ou(n,t){function e(e){return u[((i.get(e)||("range"===t.t?i.set(e,n.push(e)):NaN))-1)%u.length]}function r(t,e){return ao.range(n.length).map(function(n){return t+e*n})}var i,u,o;return e.domain=function(r){if(!arguments.length)return n;n=[],i=new c;for(var u,o=-1,a=r.length;++oe?[NaN,NaN]:[e>0?a[e-1]:n[0],et?NaN:t/u+n,[t,t+1/u]},r.copy=function(){return lu(n,t,e)},i()}function cu(n,t){function e(e){return e>=e?t[ao.bisect(n,e)]:void 0}return e.domain=function(t){return arguments.length?(n=t,e):n},e.range=function(n){return arguments.length?(t=n,e):t},e.invertExtent=function(e){return e=t.indexOf(e),[n[e-1],n[e]]},e.copy=function(){return cu(n,t)},e}function fu(n){function t(n){return+n}return t.invert=t,t.domain=t.range=function(e){return arguments.length?(n=e.map(t),t):n},t.ticks=function(t){return Qi(n,t)},t.tickFormat=function(t,e){return nu(n,t,e)},t.copy=function(){return fu(n)},t}function su(){return 0}function hu(n){return n.innerRadius}function pu(n){return n.outerRadius}function gu(n){return n.startAngle}function vu(n){return n.endAngle}function du(n){return n&&n.padAngle}function yu(n,t,e,r){return(n-e)*t-(t-r)*n>0?0:1}function mu(n,t,e,r,i){var u=n[0]-t[0],o=n[1]-t[1],a=(i?r:-r)/Math.sqrt(u*u+o*o),l=a*o,c=-a*u,f=n[0]+l,s=n[1]+c,h=t[0]+l,p=t[1]+c,g=(f+h)/2,v=(s+p)/2,d=h-f,y=p-s,m=d*d+y*y,M=e-r,x=f*p-h*s,b=(0>y?-1:1)*Math.sqrt(Math.max(0,M*M*m-x*x)),_=(x*y-d*b)/m,w=(-x*d-y*b)/m,S=(x*y+d*b)/m,k=(-x*d+y*b)/m,N=_-g,E=w-v,A=S-g,C=k-v;return N*N+E*E>A*A+C*C&&(_=S,w=k),[[_-l,w-c],[_*e/M,w*e/M]]}function Mu(n){function t(t){function o(){c.push("M",u(n(f),a))}for(var l,c=[],f=[],s=-1,h=t.length,p=En(e),g=En(r);++s1?n.join("L"):n+"Z"}function bu(n){return n.join("L")+"Z"}function _u(n){for(var t=0,e=n.length,r=n[0],i=[r[0],",",r[1]];++t1&&i.push("H",r[0]),i.join("")}function wu(n){for(var t=0,e=n.length,r=n[0],i=[r[0],",",r[1]];++t1){a=t[1],u=n[l],l++,r+="C"+(i[0]+o[0])+","+(i[1]+o[1])+","+(u[0]-a[0])+","+(u[1]-a[1])+","+u[0]+","+u[1];for(var c=2;c9&&(i=3*t/Math.sqrt(i),o[a]=i*e,o[a+1]=i*r));for(a=-1;++a<=l;)i=(n[Math.min(l,a+1)][0]-n[Math.max(0,a-1)][0])/(6*(1+o[a]*o[a])),u.push([i||0,o[a]*i||0]);return u}function Fu(n){return n.length<3?xu(n):n[0]+Au(n,ju(n))}function Hu(n){for(var t,e,r,i=-1,u=n.length;++i=t?o(n-t):void(f.c=o)}function o(e){var i=g.active,u=g[i];u&&(u.timer.c=null,u.timer.t=NaN,--g.count,delete g[i],u.event&&u.event.interrupt.call(n,n.__data__,u.index));for(var o in g)if(r>+o){var c=g[o];c.timer.c=null,c.timer.t=NaN,--g.count,delete g[o]}f.c=a,qn(function(){return f.c&&a(e||1)&&(f.c=null,f.t=NaN),1},0,l),g.active=r,v.event&&v.event.start.call(n,n.__data__,t),p=[],v.tween.forEach(function(e,r){(r=r.call(n,n.__data__,t))&&p.push(r)}),h=v.ease,s=v.duration}function a(i){for(var u=i/s,o=h(u),a=p.length;a>0;)p[--a].call(n,o);return u>=1?(v.event&&v.event.end.call(n,n.__data__,t),--g.count?delete g[r]:delete n[e],1):void 0}var l,f,s,h,p,g=n[e]||(n[e]={active:0,count:0}),v=g[r];v||(l=i.time,f=qn(u,0,l),v=g[r]={tween:new c,time:l,timer:f,delay:i.delay,duration:i.duration,ease:i.ease,index:t},i=null,++g.count)}function no(n,t,e){n.attr("transform",function(n){var r=t(n);return"translate("+(isFinite(r)?r:e(n))+",0)"})}function to(n,t,e){n.attr("transform",function(n){var r=t(n);return"translate(0,"+(isFinite(r)?r:e(n))+")"})}function eo(n){return n.toISOString()}function ro(n,t,e){function r(t){return n(t)}function i(n,e){var r=n[1]-n[0],i=r/e,u=ao.bisect(Kl,i);return u==Kl.length?[t.year,Ki(n.map(function(n){return n/31536e6}),e)[2]]:u?t[i/Kl[u-1]1?{floor:function(t){for(;e(t=n.floor(t));)t=io(t-1);return t},ceil:function(t){for(;e(t=n.ceil(t));)t=io(+t+1);return t}}:n))},r.ticks=function(n,t){var e=Yi(r.domain()),u=null==n?i(e,10):"number"==typeof n?i(e,n):!n.range&&[{range:n},t];return u&&(n=u[0],t=u[1]),n.range(e[0],io(+e[1]+1),1>t?1:t)},r.tickFormat=function(){return e},r.copy=function(){return ro(n.copy(),t,e)},Ji(r,n)}function io(n){return new Date(n)}function uo(n){return JSON.parse(n.responseText)}function oo(n){var t=fo.createRange();return t.selectNode(fo.body),t.createContextualFragment(n.responseText)}var ao={version:"3.5.17"},lo=[].slice,co=function(n){return lo.call(n)},fo=this.document;if(fo)try{co(fo.documentElement.childNodes)[0].nodeType}catch(so){co=function(n){for(var t=n.length,e=new Array(t);t--;)e[t]=n[t];return e}}if(Date.now||(Date.now=function(){return+new Date}),fo)try{fo.createElement("DIV").style.setProperty("opacity",0,"")}catch(ho){var po=this.Element.prototype,go=po.setAttribute,vo=po.setAttributeNS,yo=this.CSSStyleDeclaration.prototype,mo=yo.setProperty;po.setAttribute=function(n,t){go.call(this,n,t+"")},po.setAttributeNS=function(n,t,e){vo.call(this,n,t,e+"")},yo.setProperty=function(n,t,e){mo.call(this,n,t+"",e)}}ao.ascending=e,ao.descending=function(n,t){return n>t?-1:t>n?1:t>=n?0:NaN},ao.min=function(n,t){var e,r,i=-1,u=n.length;if(1===arguments.length){for(;++i=r){e=r;break}for(;++ir&&(e=r)}else{for(;++i=r){e=r;break}for(;++ir&&(e=r)}return e},ao.max=function(n,t){var e,r,i=-1,u=n.length;if(1===arguments.length){for(;++i=r){e=r;break}for(;++ie&&(e=r)}else{for(;++i=r){e=r;break}for(;++ie&&(e=r)}return e},ao.extent=function(n,t){var e,r,i,u=-1,o=n.length;if(1===arguments.length){for(;++u=r){e=i=r;break}for(;++ur&&(e=r),r>i&&(i=r))}else{for(;++u=r){e=i=r;break}for(;++ur&&(e=r),r>i&&(i=r))}return[e,i]},ao.sum=function(n,t){var e,r=0,u=n.length,o=-1;if(1===arguments.length)for(;++o1?l/(f-1):void 0},ao.deviation=function(){var n=ao.variance.apply(this,arguments);return n?Math.sqrt(n):n};var Mo=u(e);ao.bisectLeft=Mo.left,ao.bisect=ao.bisectRight=Mo.right,ao.bisector=function(n){return u(1===n.length?function(t,r){return e(n(t),r)}:n)},ao.shuffle=function(n,t,e){(u=arguments.length)<3&&(e=n.length,2>u&&(t=0));for(var r,i,u=e-t;u;)i=Math.random()*u--|0,r=n[u+t],n[u+t]=n[i+t],n[i+t]=r;return n},ao.permute=function(n,t){for(var e=t.length,r=new Array(e);e--;)r[e]=n[t[e]];return r},ao.pairs=function(n){for(var t,e=0,r=n.length-1,i=n[0],u=new Array(0>r?0:r);r>e;)u[e]=[t=i,i=n[++e]];return u},ao.transpose=function(n){if(!(i=n.length))return[];for(var t=-1,e=ao.min(n,o),r=new Array(e);++t=0;)for(r=n[i],t=r.length;--t>=0;)e[--o]=r[t];return e};var xo=Math.abs;ao.range=function(n,t,e){if(arguments.length<3&&(e=1,arguments.length<2&&(t=n,n=0)),(t-n)/e===1/0)throw new Error("infinite range");var r,i=[],u=a(xo(e)),o=-1;if(n*=u,t*=u,e*=u,0>e)for(;(r=n+e*++o)>t;)i.push(r/u);else for(;(r=n+e*++o)=u.length)return r?r.call(i,o):e?o.sort(e):o;for(var l,f,s,h,p=-1,g=o.length,v=u[a++],d=new c;++p=u.length)return n;var r=[],i=o[e++];return n.forEach(function(n,i){r.push({key:n,values:t(i,e)})}),i?r.sort(function(n,t){return i(n.key,t.key)}):r}var e,r,i={},u=[],o=[];return i.map=function(t,e){return n(e,t,0)},i.entries=function(e){return t(n(ao.map,e,0),0)},i.key=function(n){return u.push(n),i},i.sortKeys=function(n){return o[u.length-1]=n,i},i.sortValues=function(n){return e=n,i},i.rollup=function(n){return r=n,i},i},ao.set=function(n){var t=new y;if(n)for(var e=0,r=n.length;r>e;++e)t.add(n[e]);return t},l(y,{has:h,add:function(n){return this._[f(n+="")]=!0,n},remove:p,values:g,size:v,empty:d,forEach:function(n){for(var t in this._)n.call(this,s(t))}}),ao.behavior={},ao.rebind=function(n,t){for(var e,r=1,i=arguments.length;++r=0&&(r=n.slice(e+1),n=n.slice(0,e)),n)return arguments.length<2?this[n].on(r):this[n].on(r,t);if(2===arguments.length){if(null==t)for(n in this)this.hasOwnProperty(n)&&this[n].on(r,null);return this}},ao.event=null,ao.requote=function(n){return n.replace(So,"\\$&")};var So=/[\\\^\$\*\+\?\|\[\]\(\)\.\{\}]/g,ko={}.__proto__?function(n,t){n.__proto__=t}:function(n,t){for(var e in t)n[e]=t[e]},No=function(n,t){return t.querySelector(n)},Eo=function(n,t){return t.querySelectorAll(n)},Ao=function(n,t){var e=n.matches||n[x(n,"matchesSelector")];return(Ao=function(n,t){return e.call(n,t)})(n,t)};"function"==typeof Sizzle&&(No=function(n,t){return Sizzle(n,t)[0]||null},Eo=Sizzle,Ao=Sizzle.matchesSelector),ao.selection=function(){return ao.select(fo.documentElement)};var Co=ao.selection.prototype=[];Co.select=function(n){var t,e,r,i,u=[];n=A(n);for(var o=-1,a=this.length;++o=0&&"xmlns"!==(e=n.slice(0,t))&&(n=n.slice(t+1)),Lo.hasOwnProperty(e)?{space:Lo[e],local:n}:n}},Co.attr=function(n,t){if(arguments.length<2){if("string"==typeof n){var e=this.node();return n=ao.ns.qualify(n),n.local?e.getAttributeNS(n.space,n.local):e.getAttribute(n)}for(t in n)this.each(z(t,n[t]));return this}return this.each(z(n,t))},Co.classed=function(n,t){if(arguments.length<2){if("string"==typeof n){var e=this.node(),r=(n=T(n)).length,i=-1;if(t=e.classList){for(;++ii){if("string"!=typeof n){2>i&&(e="");for(r in n)this.each(P(r,n[r],e));return this}if(2>i){var u=this.node();return t(u).getComputedStyle(u,null).getPropertyValue(n)}r=""}return this.each(P(n,e,r))},Co.property=function(n,t){if(arguments.length<2){if("string"==typeof n)return this.node()[n];for(t in n)this.each(U(t,n[t]));return this}return this.each(U(n,t))},Co.text=function(n){return arguments.length?this.each("function"==typeof n?function(){var t=n.apply(this,arguments);this.textContent=null==t?"":t}:null==n?function(){this.textContent=""}:function(){this.textContent=n}):this.node().textContent},Co.html=function(n){return arguments.length?this.each("function"==typeof n?function(){var t=n.apply(this,arguments);this.innerHTML=null==t?"":t}:null==n?function(){this.innerHTML=""}:function(){this.innerHTML=n}):this.node().innerHTML},Co.append=function(n){return n=j(n),this.select(function(){return this.appendChild(n.apply(this,arguments))})},Co.insert=function(n,t){return n=j(n),t=A(t),this.select(function(){return this.insertBefore(n.apply(this,arguments),t.apply(this,arguments)||null)})},Co.remove=function(){return this.each(F)},Co.data=function(n,t){function e(n,e){var r,i,u,o=n.length,s=e.length,h=Math.min(o,s),p=new Array(s),g=new Array(s),v=new Array(o);if(t){var d,y=new c,m=new Array(o);for(r=-1;++rr;++r)g[r]=H(e[r]);for(;o>r;++r)v[r]=n[r]}g.update=p,g.parentNode=p.parentNode=v.parentNode=n.parentNode,a.push(g),l.push(p),f.push(v)}var r,i,u=-1,o=this.length;if(!arguments.length){for(n=new Array(o=(r=this[0]).length);++uu;u++){i.push(t=[]),t.parentNode=(e=this[u]).parentNode;for(var a=0,l=e.length;l>a;a++)(r=e[a])&&n.call(r,r.__data__,a,u)&&t.push(r)}return E(i)},Co.order=function(){for(var n=-1,t=this.length;++n=0;)(e=r[i])&&(u&&u!==e.nextSibling&&u.parentNode.insertBefore(e,u),u=e);return this},Co.sort=function(n){n=I.apply(this,arguments);for(var t=-1,e=this.length;++tn;n++)for(var e=this[n],r=0,i=e.length;i>r;r++){var u=e[r];if(u)return u}return null},Co.size=function(){var n=0;return Y(this,function(){++n}),n};var qo=[];ao.selection.enter=Z,ao.selection.enter.prototype=qo,qo.append=Co.append,qo.empty=Co.empty,qo.node=Co.node,qo.call=Co.call,qo.size=Co.size,qo.select=function(n){for(var t,e,r,i,u,o=[],a=-1,l=this.length;++ar){if("string"!=typeof n){2>r&&(t=!1);for(e in n)this.each(X(e,n[e],t));return this}if(2>r)return(r=this.node()["__on"+n])&&r._;e=!1}return this.each(X(n,t,e))};var To=ao.map({mouseenter:"mouseover",mouseleave:"mouseout"});fo&&To.forEach(function(n){"on"+n in fo&&To.remove(n)});var Ro,Do=0;ao.mouse=function(n){return J(n,k())};var Po=this.navigator&&/WebKit/.test(this.navigator.userAgent)?-1:0;ao.touch=function(n,t,e){if(arguments.length<3&&(e=t,t=k().changedTouches),t)for(var r,i=0,u=t.length;u>i;++i)if((r=t[i]).identifier===e)return J(n,r)},ao.behavior.drag=function(){function n(){this.on("mousedown.drag",u).on("touchstart.drag",o)}function e(n,t,e,u,o){return function(){function a(){var n,e,r=t(h,v);r&&(n=r[0]-M[0],e=r[1]-M[1],g|=n|e,M=r,p({type:"drag",x:r[0]+c[0],y:r[1]+c[1],dx:n,dy:e}))}function l(){t(h,v)&&(y.on(u+d,null).on(o+d,null),m(g),p({type:"dragend"}))}var c,f=this,s=ao.event.target.correspondingElement||ao.event.target,h=f.parentNode,p=r.of(f,arguments),g=0,v=n(),d=".drag"+(null==v?"":"-"+v),y=ao.select(e(s)).on(u+d,a).on(o+d,l),m=W(s),M=t(h,v);i?(c=i.apply(f,arguments),c=[c.x-M[0],c.y-M[1]]):c=[0,0],p({type:"dragstart"})}}var r=N(n,"drag","dragstart","dragend"),i=null,u=e(b,ao.mouse,t,"mousemove","mouseup"),o=e(G,ao.touch,m,"touchmove","touchend");return n.origin=function(t){return arguments.length?(i=t,n):i},ao.rebind(n,r,"on")},ao.touches=function(n,t){return arguments.length<2&&(t=k().touches),t?co(t).map(function(t){var e=J(n,t);return e.identifier=t.identifier,e}):[]};var Uo=1e-6,jo=Uo*Uo,Fo=Math.PI,Ho=2*Fo,Oo=Ho-Uo,Io=Fo/2,Yo=Fo/180,Zo=180/Fo,Vo=Math.SQRT2,Xo=2,$o=4;ao.interpolateZoom=function(n,t){var e,r,i=n[0],u=n[1],o=n[2],a=t[0],l=t[1],c=t[2],f=a-i,s=l-u,h=f*f+s*s;if(jo>h)r=Math.log(c/o)/Vo,e=function(n){return[i+n*f,u+n*s,o*Math.exp(Vo*n*r)]};else{var p=Math.sqrt(h),g=(c*c-o*o+$o*h)/(2*o*Xo*p),v=(c*c-o*o-$o*h)/(2*c*Xo*p),d=Math.log(Math.sqrt(g*g+1)-g),y=Math.log(Math.sqrt(v*v+1)-v);r=(y-d)/Vo,e=function(n){var t=n*r,e=rn(d),a=o/(Xo*p)*(e*un(Vo*t+d)-en(d));return[i+a*f,u+a*s,o*e/rn(Vo*t+d)]}}return e.duration=1e3*r,e},ao.behavior.zoom=function(){function n(n){n.on(L,s).on(Wo+".zoom",p).on("dblclick.zoom",g).on(R,h)}function e(n){return[(n[0]-k.x)/k.k,(n[1]-k.y)/k.k]}function r(n){return[n[0]*k.k+k.x,n[1]*k.k+k.y]}function i(n){k.k=Math.max(A[0],Math.min(A[1],n))}function u(n,t){t=r(t),k.x+=n[0]-t[0],k.y+=n[1]-t[1]}function o(t,e,r,o){t.__chart__={x:k.x,y:k.y,k:k.k},i(Math.pow(2,o)),u(d=e,r),t=ao.select(t),C>0&&(t=t.transition().duration(C)),t.call(n.event)}function a(){b&&b.domain(x.range().map(function(n){return(n-k.x)/k.k}).map(x.invert)),w&&w.domain(_.range().map(function(n){return(n-k.y)/k.k}).map(_.invert))}function l(n){z++||n({type:"zoomstart"})}function c(n){a(),n({type:"zoom",scale:k.k,translate:[k.x,k.y]})}function f(n){--z||(n({type:"zoomend"}),d=null)}function s(){function n(){a=1,u(ao.mouse(i),h),c(o)}function r(){s.on(q,null).on(T,null),p(a),f(o)}var i=this,o=D.of(i,arguments),a=0,s=ao.select(t(i)).on(q,n).on(T,r),h=e(ao.mouse(i)),p=W(i);Il.call(i),l(o)}function h(){function n(){var n=ao.touches(g);return p=k.k,n.forEach(function(n){n.identifier in d&&(d[n.identifier]=e(n))}),n}function t(){var t=ao.event.target;ao.select(t).on(x,r).on(b,a),_.push(t);for(var e=ao.event.changedTouches,i=0,u=e.length;u>i;++i)d[e[i].identifier]=null;var l=n(),c=Date.now();if(1===l.length){if(500>c-M){var f=l[0];o(g,f,d[f.identifier],Math.floor(Math.log(k.k)/Math.LN2)+1),S()}M=c}else if(l.length>1){var f=l[0],s=l[1],h=f[0]-s[0],p=f[1]-s[1];y=h*h+p*p}}function r(){var n,t,e,r,o=ao.touches(g);Il.call(g);for(var a=0,l=o.length;l>a;++a,r=null)if(e=o[a],r=d[e.identifier]){if(t)break;n=e,t=r}if(r){var f=(f=e[0]-n[0])*f+(f=e[1]-n[1])*f,s=y&&Math.sqrt(f/y);n=[(n[0]+e[0])/2,(n[1]+e[1])/2],t=[(t[0]+r[0])/2,(t[1]+r[1])/2],i(s*p)}M=null,u(n,t),c(v)}function a(){if(ao.event.touches.length){for(var t=ao.event.changedTouches,e=0,r=t.length;r>e;++e)delete d[t[e].identifier];for(var i in d)return void n()}ao.selectAll(_).on(m,null),w.on(L,s).on(R,h),N(),f(v)}var p,g=this,v=D.of(g,arguments),d={},y=0,m=".zoom-"+ao.event.changedTouches[0].identifier,x="touchmove"+m,b="touchend"+m,_=[],w=ao.select(g),N=W(g);t(),l(v),w.on(L,null).on(R,t)}function p(){var n=D.of(this,arguments);m?clearTimeout(m):(Il.call(this),v=e(d=y||ao.mouse(this)),l(n)),m=setTimeout(function(){m=null,f(n)},50),S(),i(Math.pow(2,.002*Bo())*k.k),u(d,v),c(n)}function g(){var n=ao.mouse(this),t=Math.log(k.k)/Math.LN2;o(this,n,e(n),ao.event.shiftKey?Math.ceil(t)-1:Math.floor(t)+1)}var v,d,y,m,M,x,b,_,w,k={x:0,y:0,k:1},E=[960,500],A=Jo,C=250,z=0,L="mousedown.zoom",q="mousemove.zoom",T="mouseup.zoom",R="touchstart.zoom",D=N(n,"zoomstart","zoom","zoomend");return Wo||(Wo="onwheel"in fo?(Bo=function(){return-ao.event.deltaY*(ao.event.deltaMode?120:1)},"wheel"):"onmousewheel"in fo?(Bo=function(){return ao.event.wheelDelta},"mousewheel"):(Bo=function(){return-ao.event.detail},"MozMousePixelScroll")),n.event=function(n){n.each(function(){var n=D.of(this,arguments),t=k;Hl?ao.select(this).transition().each("start.zoom",function(){k=this.__chart__||{x:0,y:0,k:1},l(n)}).tween("zoom:zoom",function(){var e=E[0],r=E[1],i=d?d[0]:e/2,u=d?d[1]:r/2,o=ao.interpolateZoom([(i-k.x)/k.k,(u-k.y)/k.k,e/k.k],[(i-t.x)/t.k,(u-t.y)/t.k,e/t.k]);return function(t){var r=o(t),a=e/r[2];this.__chart__=k={x:i-r[0]*a,y:u-r[1]*a,k:a},c(n)}}).each("interrupt.zoom",function(){f(n)}).each("end.zoom",function(){f(n)}):(this.__chart__=k,l(n),c(n),f(n))})},n.translate=function(t){return arguments.length?(k={x:+t[0],y:+t[1],k:k.k},a(),n):[k.x,k.y]},n.scale=function(t){return arguments.length?(k={x:k.x,y:k.y,k:null},i(+t),a(),n):k.k},n.scaleExtent=function(t){return arguments.length?(A=null==t?Jo:[+t[0],+t[1]],n):A},n.center=function(t){return arguments.length?(y=t&&[+t[0],+t[1]],n):y},n.size=function(t){return arguments.length?(E=t&&[+t[0],+t[1]],n):E},n.duration=function(t){return arguments.length?(C=+t,n):C},n.x=function(t){return arguments.length?(b=t,x=t.copy(),k={x:0,y:0,k:1},n):b},n.y=function(t){return arguments.length?(w=t,_=t.copy(),k={x:0,y:0,k:1},n):w},ao.rebind(n,D,"on")};var Bo,Wo,Jo=[0,1/0];ao.color=an,an.prototype.toString=function(){return this.rgb()+""},ao.hsl=ln;var Go=ln.prototype=new an;Go.brighter=function(n){return n=Math.pow(.7,arguments.length?n:1),new ln(this.h,this.s,this.l/n)},Go.darker=function(n){return n=Math.pow(.7,arguments.length?n:1),new ln(this.h,this.s,n*this.l)},Go.rgb=function(){return cn(this.h,this.s,this.l)},ao.hcl=fn;var Ko=fn.prototype=new an;Ko.brighter=function(n){return new fn(this.h,this.c,Math.min(100,this.l+Qo*(arguments.length?n:1)))},Ko.darker=function(n){return new fn(this.h,this.c,Math.max(0,this.l-Qo*(arguments.length?n:1)))},Ko.rgb=function(){return sn(this.h,this.c,this.l).rgb()},ao.lab=hn;var Qo=18,na=.95047,ta=1,ea=1.08883,ra=hn.prototype=new an;ra.brighter=function(n){return new hn(Math.min(100,this.l+Qo*(arguments.length?n:1)),this.a,this.b)},ra.darker=function(n){return new hn(Math.max(0,this.l-Qo*(arguments.length?n:1)),this.a,this.b)},ra.rgb=function(){return pn(this.l,this.a,this.b)},ao.rgb=mn;var ia=mn.prototype=new an;ia.brighter=function(n){n=Math.pow(.7,arguments.length?n:1);var t=this.r,e=this.g,r=this.b,i=30;return t||e||r?(t&&i>t&&(t=i),e&&i>e&&(e=i),r&&i>r&&(r=i),new mn(Math.min(255,t/n),Math.min(255,e/n),Math.min(255,r/n))):new mn(i,i,i)},ia.darker=function(n){return n=Math.pow(.7,arguments.length?n:1),new mn(n*this.r,n*this.g,n*this.b)},ia.hsl=function(){return wn(this.r,this.g,this.b)},ia.toString=function(){return"#"+bn(this.r)+bn(this.g)+bn(this.b)};var ua=ao.map({aliceblue:15792383,antiquewhite:16444375,aqua:65535,aquamarine:8388564,azure:15794175,beige:16119260,bisque:16770244,black:0,blanchedalmond:16772045,blue:255,blueviolet:9055202,brown:10824234,burlywood:14596231,cadetblue:6266528,chartreuse:8388352,chocolate:13789470,coral:16744272,cornflowerblue:6591981,cornsilk:16775388,crimson:14423100,cyan:65535,darkblue:139,darkcyan:35723,darkgoldenrod:12092939,darkgray:11119017,darkgreen:25600,darkgrey:11119017,darkkhaki:12433259,darkmagenta:9109643,darkolivegreen:5597999,darkorange:16747520,darkorchid:10040012,darkred:9109504,darksalmon:15308410,darkseagreen:9419919,darkslateblue:4734347,darkslategray:3100495,darkslategrey:3100495,darkturquoise:52945,darkviolet:9699539,deeppink:16716947,deepskyblue:49151,dimgray:6908265,dimgrey:6908265,dodgerblue:2003199,firebrick:11674146,floralwhite:16775920,forestgreen:2263842,fuchsia:16711935,gainsboro:14474460,ghostwhite:16316671,gold:16766720,goldenrod:14329120,gray:8421504,green:32768,greenyellow:11403055,grey:8421504,honeydew:15794160,hotpink:16738740,indianred:13458524,indigo:4915330,ivory:16777200,khaki:15787660,lavender:15132410,lavenderblush:16773365,lawngreen:8190976,lemonchiffon:16775885,lightblue:11393254,lightcoral:15761536,lightcyan:14745599,lightgoldenrodyellow:16448210,lightgray:13882323,lightgreen:9498256,lightgrey:13882323,lightpink:16758465,lightsalmon:16752762,lightseagreen:2142890,lightskyblue:8900346,lightslategray:7833753,lightslategrey:7833753,lightsteelblue:11584734,lightyellow:16777184,lime:65280,limegreen:3329330,linen:16445670,magenta:16711935,maroon:8388608,mediumaquamarine:6737322,mediumblue:205,mediumorchid:12211667,mediumpurple:9662683,mediumseagreen:3978097,mediumslateblue:8087790,mediumspringgreen:64154,mediumturquoise:4772300,mediumvioletred:13047173,midnightblue:1644912,mintcream:16121850,mistyrose:16770273,moccasin:16770229,navajowhite:16768685,navy:128,oldlace:16643558,olive:8421376,olivedrab:7048739,orange:16753920,orangered:16729344,orchid:14315734,palegoldenrod:15657130,palegreen:10025880,paleturquoise:11529966,palevioletred:14381203,papayawhip:16773077,peachpuff:16767673,peru:13468991,pink:16761035,plum:14524637,powderblue:11591910,purple:8388736,rebeccapurple:6697881,red:16711680,rosybrown:12357519,royalblue:4286945,saddlebrown:9127187,salmon:16416882,sandybrown:16032864,seagreen:3050327,seashell:16774638,sienna:10506797,silver:12632256,skyblue:8900331,slateblue:6970061,slategray:7372944,slategrey:7372944,snow:16775930,springgreen:65407,steelblue:4620980,tan:13808780,teal:32896,thistle:14204888,tomato:16737095,turquoise:4251856,violet:15631086,wheat:16113331,white:16777215,whitesmoke:16119285,yellow:16776960,yellowgreen:10145074});ua.forEach(function(n,t){ua.set(n,Mn(t))}),ao.functor=En,ao.xhr=An(m),ao.dsv=function(n,t){function e(n,e,u){arguments.length<3&&(u=e,e=null);var o=Cn(n,t,null==e?r:i(e),u);return o.row=function(n){return arguments.length?o.response(null==(e=n)?r:i(n)):e},o}function r(n){return e.parse(n.responseText)}function i(n){return function(t){return e.parse(t.responseText,n)}}function u(t){return t.map(o).join(n)}function o(n){return a.test(n)?'"'+n.replace(/\"/g,'""')+'"':n}var a=new RegExp('["'+n+"\n]"),l=n.charCodeAt(0);return e.parse=function(n,t){var r;return e.parseRows(n,function(n,e){if(r)return r(n,e-1);var i=new Function("d","return {"+n.map(function(n,t){return JSON.stringify(n)+": d["+t+"]"}).join(",")+"}");r=t?function(n,e){return t(i(n),e)}:i})},e.parseRows=function(n,t){function e(){if(f>=c)return o;if(i)return i=!1,u;var t=f;if(34===n.charCodeAt(t)){for(var e=t;e++f;){var r=n.charCodeAt(f++),a=1;if(10===r)i=!0;else if(13===r)i=!0,10===n.charCodeAt(f)&&(++f,++a);else if(r!==l)continue;return n.slice(t,f-a)}return n.slice(t)}for(var r,i,u={},o={},a=[],c=n.length,f=0,s=0;(r=e())!==o;){for(var h=[];r!==u&&r!==o;)h.push(r),r=e();t&&null==(h=t(h,s++))||a.push(h)}return a},e.format=function(t){if(Array.isArray(t[0]))return e.formatRows(t);var r=new y,i=[];return t.forEach(function(n){for(var t in n)r.has(t)||i.push(r.add(t))}),[i.map(o).join(n)].concat(t.map(function(t){return i.map(function(n){return o(t[n])}).join(n)})).join("\n")},e.formatRows=function(n){return n.map(u).join("\n")},e},ao.csv=ao.dsv(",","text/csv"),ao.tsv=ao.dsv(" ","text/tab-separated-values");var oa,aa,la,ca,fa=this[x(this,"requestAnimationFrame")]||function(n){setTimeout(n,17)};ao.timer=function(){qn.apply(this,arguments)},ao.timer.flush=function(){Rn(),Dn()},ao.round=function(n,t){return t?Math.round(n*(t=Math.pow(10,t)))/t:Math.round(n)};var sa=["y","z","a","f","p","n","\xb5","m","","k","M","G","T","P","E","Z","Y"].map(Un);ao.formatPrefix=function(n,t){var e=0;return(n=+n)&&(0>n&&(n*=-1),t&&(n=ao.round(n,Pn(n,t))),e=1+Math.floor(1e-12+Math.log(n)/Math.LN10),e=Math.max(-24,Math.min(24,3*Math.floor((e-1)/3)))),sa[8+e/3]};var ha=/(?:([^{])?([<>=^]))?([+\- ])?([$#])?(0)?(\d+)?(,)?(\.-?\d+)?([a-z%])?/i,pa=ao.map({b:function(n){return n.toString(2)},c:function(n){return String.fromCharCode(n)},o:function(n){return n.toString(8)},x:function(n){return n.toString(16)},X:function(n){return n.toString(16).toUpperCase()},g:function(n,t){return n.toPrecision(t)},e:function(n,t){return n.toExponential(t)},f:function(n,t){return n.toFixed(t)},r:function(n,t){return(n=ao.round(n,Pn(n,t))).toFixed(Math.max(0,Math.min(20,Pn(n*(1+1e-15),t))))}}),ga=ao.time={},va=Date;Hn.prototype={getDate:function(){return this._.getUTCDate()},getDay:function(){return this._.getUTCDay()},getFullYear:function(){return this._.getUTCFullYear()},getHours:function(){return this._.getUTCHours()},getMilliseconds:function(){return this._.getUTCMilliseconds()},getMinutes:function(){return this._.getUTCMinutes()},getMonth:function(){return this._.getUTCMonth()},getSeconds:function(){return this._.getUTCSeconds()},getTime:function(){return this._.getTime()},getTimezoneOffset:function(){return 0},valueOf:function(){return this._.valueOf()},setDate:function(){da.setUTCDate.apply(this._,arguments)},setDay:function(){da.setUTCDay.apply(this._,arguments)},setFullYear:function(){da.setUTCFullYear.apply(this._,arguments)},setHours:function(){da.setUTCHours.apply(this._,arguments)},setMilliseconds:function(){da.setUTCMilliseconds.apply(this._,arguments)},setMinutes:function(){da.setUTCMinutes.apply(this._,arguments)},setMonth:function(){da.setUTCMonth.apply(this._,arguments)},setSeconds:function(){da.setUTCSeconds.apply(this._,arguments)},setTime:function(){da.setTime.apply(this._,arguments)}};var da=Date.prototype;ga.year=On(function(n){return n=ga.day(n),n.setMonth(0,1),n},function(n,t){n.setFullYear(n.getFullYear()+t)},function(n){return n.getFullYear()}),ga.years=ga.year.range,ga.years.utc=ga.year.utc.range,ga.day=On(function(n){var t=new va(2e3,0);return t.setFullYear(n.getFullYear(),n.getMonth(),n.getDate()),t},function(n,t){n.setDate(n.getDate()+t)},function(n){return n.getDate()-1}),ga.days=ga.day.range,ga.days.utc=ga.day.utc.range,ga.dayOfYear=function(n){var t=ga.year(n);return Math.floor((n-t-6e4*(n.getTimezoneOffset()-t.getTimezoneOffset()))/864e5)},["sunday","monday","tuesday","wednesday","thursday","friday","saturday"].forEach(function(n,t){t=7-t;var e=ga[n]=On(function(n){return(n=ga.day(n)).setDate(n.getDate()-(n.getDay()+t)%7),n},function(n,t){n.setDate(n.getDate()+7*Math.floor(t))},function(n){var e=ga.year(n).getDay();return Math.floor((ga.dayOfYear(n)+(e+t)%7)/7)-(e!==t)});ga[n+"s"]=e.range,ga[n+"s"].utc=e.utc.range,ga[n+"OfYear"]=function(n){var e=ga.year(n).getDay();return Math.floor((ga.dayOfYear(n)+(e+t)%7)/7)}}),ga.week=ga.sunday,ga.weeks=ga.sunday.range,ga.weeks.utc=ga.sunday.utc.range,ga.weekOfYear=ga.sundayOfYear;var ya={"-":"",_:" ",0:"0"},ma=/^\s*\d+/,Ma=/^%/;ao.locale=function(n){return{numberFormat:jn(n),timeFormat:Yn(n)}};var xa=ao.locale({decimal:".",thousands:",",grouping:[3],currency:["$",""],dateTime:"%a %b %e %X %Y",date:"%m/%d/%Y",time:"%H:%M:%S",periods:["AM","PM"],days:["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"], -shortDays:["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],months:["January","February","March","April","May","June","July","August","September","October","November","December"],shortMonths:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"]});ao.format=xa.numberFormat,ao.geo={},ft.prototype={s:0,t:0,add:function(n){st(n,this.t,ba),st(ba.s,this.s,this),this.s?this.t+=ba.t:this.s=ba.t},reset:function(){this.s=this.t=0},valueOf:function(){return this.s}};var ba=new ft;ao.geo.stream=function(n,t){n&&_a.hasOwnProperty(n.type)?_a[n.type](n,t):ht(n,t)};var _a={Feature:function(n,t){ht(n.geometry,t)},FeatureCollection:function(n,t){for(var e=n.features,r=-1,i=e.length;++rn?4*Fo+n:n,Na.lineStart=Na.lineEnd=Na.point=b}};ao.geo.bounds=function(){function n(n,t){M.push(x=[f=n,h=n]),s>t&&(s=t),t>p&&(p=t)}function t(t,e){var r=dt([t*Yo,e*Yo]);if(y){var i=mt(y,r),u=[i[1],-i[0],0],o=mt(u,i);bt(o),o=_t(o);var l=t-g,c=l>0?1:-1,v=o[0]*Zo*c,d=xo(l)>180;if(d^(v>c*g&&c*t>v)){var m=o[1]*Zo;m>p&&(p=m)}else if(v=(v+360)%360-180,d^(v>c*g&&c*t>v)){var m=-o[1]*Zo;s>m&&(s=m)}else s>e&&(s=e),e>p&&(p=e);d?g>t?a(f,t)>a(f,h)&&(h=t):a(t,h)>a(f,h)&&(f=t):h>=f?(f>t&&(f=t),t>h&&(h=t)):t>g?a(f,t)>a(f,h)&&(h=t):a(t,h)>a(f,h)&&(f=t)}else n(t,e);y=r,g=t}function e(){b.point=t}function r(){x[0]=f,x[1]=h,b.point=n,y=null}function i(n,e){if(y){var r=n-g;m+=xo(r)>180?r+(r>0?360:-360):r}else v=n,d=e;Na.point(n,e),t(n,e)}function u(){Na.lineStart()}function o(){i(v,d),Na.lineEnd(),xo(m)>Uo&&(f=-(h=180)),x[0]=f,x[1]=h,y=null}function a(n,t){return(t-=n)<0?t+360:t}function l(n,t){return n[0]-t[0]}function c(n,t){return t[0]<=t[1]?t[0]<=n&&n<=t[1]:nka?(f=-(h=180),s=-(p=90)):m>Uo?p=90:-Uo>m&&(s=-90),x[0]=f,x[1]=h}};return function(n){p=h=-(f=s=1/0),M=[],ao.geo.stream(n,b);var t=M.length;if(t){M.sort(l);for(var e,r=1,i=M[0],u=[i];t>r;++r)e=M[r],c(e[0],i)||c(e[1],i)?(a(i[0],e[1])>a(i[0],i[1])&&(i[1]=e[1]),a(e[0],i[1])>a(i[0],i[1])&&(i[0]=e[0])):u.push(i=e);for(var o,e,g=-(1/0),t=u.length-1,r=0,i=u[t];t>=r;i=e,++r)e=u[r],(o=a(i[1],e[0]))>g&&(g=o,f=e[0],h=i[1])}return M=x=null,f===1/0||s===1/0?[[NaN,NaN],[NaN,NaN]]:[[f,s],[h,p]]}}(),ao.geo.centroid=function(n){Ea=Aa=Ca=za=La=qa=Ta=Ra=Da=Pa=Ua=0,ao.geo.stream(n,ja);var t=Da,e=Pa,r=Ua,i=t*t+e*e+r*r;return jo>i&&(t=qa,e=Ta,r=Ra,Uo>Aa&&(t=Ca,e=za,r=La),i=t*t+e*e+r*r,jo>i)?[NaN,NaN]:[Math.atan2(e,t)*Zo,tn(r/Math.sqrt(i))*Zo]};var Ea,Aa,Ca,za,La,qa,Ta,Ra,Da,Pa,Ua,ja={sphere:b,point:St,lineStart:Nt,lineEnd:Et,polygonStart:function(){ja.lineStart=At},polygonEnd:function(){ja.lineStart=Nt}},Fa=Rt(zt,jt,Ht,[-Fo,-Fo/2]),Ha=1e9;ao.geo.clipExtent=function(){var n,t,e,r,i,u,o={stream:function(n){return i&&(i.valid=!1),i=u(n),i.valid=!0,i},extent:function(a){return arguments.length?(u=Zt(n=+a[0][0],t=+a[0][1],e=+a[1][0],r=+a[1][1]),i&&(i.valid=!1,i=null),o):[[n,t],[e,r]]}};return o.extent([[0,0],[960,500]])},(ao.geo.conicEqualArea=function(){return Vt(Xt)}).raw=Xt,ao.geo.albers=function(){return ao.geo.conicEqualArea().rotate([96,0]).center([-.6,38.7]).parallels([29.5,45.5]).scale(1070)},ao.geo.albersUsa=function(){function n(n){var u=n[0],o=n[1];return t=null,e(u,o),t||(r(u,o),t)||i(u,o),t}var t,e,r,i,u=ao.geo.albers(),o=ao.geo.conicEqualArea().rotate([154,0]).center([-2,58.5]).parallels([55,65]),a=ao.geo.conicEqualArea().rotate([157,0]).center([-3,19.9]).parallels([8,18]),l={point:function(n,e){t=[n,e]}};return n.invert=function(n){var t=u.scale(),e=u.translate(),r=(n[0]-e[0])/t,i=(n[1]-e[1])/t;return(i>=.12&&.234>i&&r>=-.425&&-.214>r?o:i>=.166&&.234>i&&r>=-.214&&-.115>r?a:u).invert(n)},n.stream=function(n){var t=u.stream(n),e=o.stream(n),r=a.stream(n);return{point:function(n,i){t.point(n,i),e.point(n,i),r.point(n,i)},sphere:function(){t.sphere(),e.sphere(),r.sphere()},lineStart:function(){t.lineStart(),e.lineStart(),r.lineStart()},lineEnd:function(){t.lineEnd(),e.lineEnd(),r.lineEnd()},polygonStart:function(){t.polygonStart(),e.polygonStart(),r.polygonStart()},polygonEnd:function(){t.polygonEnd(),e.polygonEnd(),r.polygonEnd()}}},n.precision=function(t){return arguments.length?(u.precision(t),o.precision(t),a.precision(t),n):u.precision()},n.scale=function(t){return arguments.length?(u.scale(t),o.scale(.35*t),a.scale(t),n.translate(u.translate())):u.scale()},n.translate=function(t){if(!arguments.length)return u.translate();var c=u.scale(),f=+t[0],s=+t[1];return e=u.translate(t).clipExtent([[f-.455*c,s-.238*c],[f+.455*c,s+.238*c]]).stream(l).point,r=o.translate([f-.307*c,s+.201*c]).clipExtent([[f-.425*c+Uo,s+.12*c+Uo],[f-.214*c-Uo,s+.234*c-Uo]]).stream(l).point,i=a.translate([f-.205*c,s+.212*c]).clipExtent([[f-.214*c+Uo,s+.166*c+Uo],[f-.115*c-Uo,s+.234*c-Uo]]).stream(l).point,n},n.scale(1070)};var Oa,Ia,Ya,Za,Va,Xa,$a={point:b,lineStart:b,lineEnd:b,polygonStart:function(){Ia=0,$a.lineStart=$t},polygonEnd:function(){$a.lineStart=$a.lineEnd=$a.point=b,Oa+=xo(Ia/2)}},Ba={point:Bt,lineStart:b,lineEnd:b,polygonStart:b,polygonEnd:b},Wa={point:Gt,lineStart:Kt,lineEnd:Qt,polygonStart:function(){Wa.lineStart=ne},polygonEnd:function(){Wa.point=Gt,Wa.lineStart=Kt,Wa.lineEnd=Qt}};ao.geo.path=function(){function n(n){return n&&("function"==typeof a&&u.pointRadius(+a.apply(this,arguments)),o&&o.valid||(o=i(u)),ao.geo.stream(n,o)),u.result()}function t(){return o=null,n}var e,r,i,u,o,a=4.5;return n.area=function(n){return Oa=0,ao.geo.stream(n,i($a)),Oa},n.centroid=function(n){return Ca=za=La=qa=Ta=Ra=Da=Pa=Ua=0,ao.geo.stream(n,i(Wa)),Ua?[Da/Ua,Pa/Ua]:Ra?[qa/Ra,Ta/Ra]:La?[Ca/La,za/La]:[NaN,NaN]},n.bounds=function(n){return Va=Xa=-(Ya=Za=1/0),ao.geo.stream(n,i(Ba)),[[Ya,Za],[Va,Xa]]},n.projection=function(n){return arguments.length?(i=(e=n)?n.stream||re(n):m,t()):e},n.context=function(n){return arguments.length?(u=null==(r=n)?new Wt:new te(n),"function"!=typeof a&&u.pointRadius(a),t()):r},n.pointRadius=function(t){return arguments.length?(a="function"==typeof t?t:(u.pointRadius(+t),+t),n):a},n.projection(ao.geo.albersUsa()).context(null)},ao.geo.transform=function(n){return{stream:function(t){var e=new ie(t);for(var r in n)e[r]=n[r];return e}}},ie.prototype={point:function(n,t){this.stream.point(n,t)},sphere:function(){this.stream.sphere()},lineStart:function(){this.stream.lineStart()},lineEnd:function(){this.stream.lineEnd()},polygonStart:function(){this.stream.polygonStart()},polygonEnd:function(){this.stream.polygonEnd()}},ao.geo.projection=oe,ao.geo.projectionMutator=ae,(ao.geo.equirectangular=function(){return oe(ce)}).raw=ce.invert=ce,ao.geo.rotation=function(n){function t(t){return t=n(t[0]*Yo,t[1]*Yo),t[0]*=Zo,t[1]*=Zo,t}return n=se(n[0]%360*Yo,n[1]*Yo,n.length>2?n[2]*Yo:0),t.invert=function(t){return t=n.invert(t[0]*Yo,t[1]*Yo),t[0]*=Zo,t[1]*=Zo,t},t},fe.invert=ce,ao.geo.circle=function(){function n(){var n="function"==typeof r?r.apply(this,arguments):r,t=se(-n[0]*Yo,-n[1]*Yo,0).invert,i=[];return e(null,null,1,{point:function(n,e){i.push(n=t(n,e)),n[0]*=Zo,n[1]*=Zo}}),{type:"Polygon",coordinates:[i]}}var t,e,r=[0,0],i=6;return n.origin=function(t){return arguments.length?(r=t,n):r},n.angle=function(r){return arguments.length?(e=ve((t=+r)*Yo,i*Yo),n):t},n.precision=function(r){return arguments.length?(e=ve(t*Yo,(i=+r)*Yo),n):i},n.angle(90)},ao.geo.distance=function(n,t){var e,r=(t[0]-n[0])*Yo,i=n[1]*Yo,u=t[1]*Yo,o=Math.sin(r),a=Math.cos(r),l=Math.sin(i),c=Math.cos(i),f=Math.sin(u),s=Math.cos(u);return Math.atan2(Math.sqrt((e=s*o)*e+(e=c*f-l*s*a)*e),l*f+c*s*a)},ao.geo.graticule=function(){function n(){return{type:"MultiLineString",coordinates:t()}}function t(){return ao.range(Math.ceil(u/d)*d,i,d).map(h).concat(ao.range(Math.ceil(c/y)*y,l,y).map(p)).concat(ao.range(Math.ceil(r/g)*g,e,g).filter(function(n){return xo(n%d)>Uo}).map(f)).concat(ao.range(Math.ceil(a/v)*v,o,v).filter(function(n){return xo(n%y)>Uo}).map(s))}var e,r,i,u,o,a,l,c,f,s,h,p,g=10,v=g,d=90,y=360,m=2.5;return n.lines=function(){return t().map(function(n){return{type:"LineString",coordinates:n}})},n.outline=function(){return{type:"Polygon",coordinates:[h(u).concat(p(l).slice(1),h(i).reverse().slice(1),p(c).reverse().slice(1))]}},n.extent=function(t){return arguments.length?n.majorExtent(t).minorExtent(t):n.minorExtent()},n.majorExtent=function(t){return arguments.length?(u=+t[0][0],i=+t[1][0],c=+t[0][1],l=+t[1][1],u>i&&(t=u,u=i,i=t),c>l&&(t=c,c=l,l=t),n.precision(m)):[[u,c],[i,l]]},n.minorExtent=function(t){return arguments.length?(r=+t[0][0],e=+t[1][0],a=+t[0][1],o=+t[1][1],r>e&&(t=r,r=e,e=t),a>o&&(t=a,a=o,o=t),n.precision(m)):[[r,a],[e,o]]},n.step=function(t){return arguments.length?n.majorStep(t).minorStep(t):n.minorStep()},n.majorStep=function(t){return arguments.length?(d=+t[0],y=+t[1],n):[d,y]},n.minorStep=function(t){return arguments.length?(g=+t[0],v=+t[1],n):[g,v]},n.precision=function(t){return arguments.length?(m=+t,f=ye(a,o,90),s=me(r,e,m),h=ye(c,l,90),p=me(u,i,m),n):m},n.majorExtent([[-180,-90+Uo],[180,90-Uo]]).minorExtent([[-180,-80-Uo],[180,80+Uo]])},ao.geo.greatArc=function(){function n(){return{type:"LineString",coordinates:[t||r.apply(this,arguments),e||i.apply(this,arguments)]}}var t,e,r=Me,i=xe;return n.distance=function(){return ao.geo.distance(t||r.apply(this,arguments),e||i.apply(this,arguments))},n.source=function(e){return arguments.length?(r=e,t="function"==typeof e?null:e,n):r},n.target=function(t){return arguments.length?(i=t,e="function"==typeof t?null:t,n):i},n.precision=function(){return arguments.length?n:0},n},ao.geo.interpolate=function(n,t){return be(n[0]*Yo,n[1]*Yo,t[0]*Yo,t[1]*Yo)},ao.geo.length=function(n){return Ja=0,ao.geo.stream(n,Ga),Ja};var Ja,Ga={sphere:b,point:b,lineStart:_e,lineEnd:b,polygonStart:b,polygonEnd:b},Ka=we(function(n){return Math.sqrt(2/(1+n))},function(n){return 2*Math.asin(n/2)});(ao.geo.azimuthalEqualArea=function(){return oe(Ka)}).raw=Ka;var Qa=we(function(n){var t=Math.acos(n);return t&&t/Math.sin(t)},m);(ao.geo.azimuthalEquidistant=function(){return oe(Qa)}).raw=Qa,(ao.geo.conicConformal=function(){return Vt(Se)}).raw=Se,(ao.geo.conicEquidistant=function(){return Vt(ke)}).raw=ke;var nl=we(function(n){return 1/n},Math.atan);(ao.geo.gnomonic=function(){return oe(nl)}).raw=nl,Ne.invert=function(n,t){return[n,2*Math.atan(Math.exp(t))-Io]},(ao.geo.mercator=function(){return Ee(Ne)}).raw=Ne;var tl=we(function(){return 1},Math.asin);(ao.geo.orthographic=function(){return oe(tl)}).raw=tl;var el=we(function(n){return 1/(1+n)},function(n){return 2*Math.atan(n)});(ao.geo.stereographic=function(){return oe(el)}).raw=el,Ae.invert=function(n,t){return[-t,2*Math.atan(Math.exp(n))-Io]},(ao.geo.transverseMercator=function(){var n=Ee(Ae),t=n.center,e=n.rotate;return n.center=function(n){return n?t([-n[1],n[0]]):(n=t(),[n[1],-n[0]])},n.rotate=function(n){return n?e([n[0],n[1],n.length>2?n[2]+90:90]):(n=e(),[n[0],n[1],n[2]-90])},e([0,0,90])}).raw=Ae,ao.geom={},ao.geom.hull=function(n){function t(n){if(n.length<3)return[];var t,i=En(e),u=En(r),o=n.length,a=[],l=[];for(t=0;o>t;t++)a.push([+i.call(this,n[t],t),+u.call(this,n[t],t),t]);for(a.sort(qe),t=0;o>t;t++)l.push([a[t][0],-a[t][1]]);var c=Le(a),f=Le(l),s=f[0]===c[0],h=f[f.length-1]===c[c.length-1],p=[];for(t=c.length-1;t>=0;--t)p.push(n[a[c[t]][2]]);for(t=+s;t=r&&c.x<=u&&c.y>=i&&c.y<=o?[[r,o],[u,o],[u,i],[r,i]]:[];f.point=n[a]}),t}function e(n){return n.map(function(n,t){return{x:Math.round(u(n,t)/Uo)*Uo,y:Math.round(o(n,t)/Uo)*Uo,i:t}})}var r=Ce,i=ze,u=r,o=i,a=sl;return n?t(n):(t.links=function(n){return ar(e(n)).edges.filter(function(n){return n.l&&n.r}).map(function(t){return{source:n[t.l.i],target:n[t.r.i]}})},t.triangles=function(n){var t=[];return ar(e(n)).cells.forEach(function(e,r){for(var i,u,o=e.site,a=e.edges.sort(Ve),l=-1,c=a.length,f=a[c-1].edge,s=f.l===o?f.r:f.l;++l=c,h=r>=f,p=h<<1|s;n.leaf=!1,n=n.nodes[p]||(n.nodes[p]=hr()),s?i=c:a=c,h?o=f:l=f,u(n,t,e,r,i,o,a,l)}var f,s,h,p,g,v,d,y,m,M=En(a),x=En(l);if(null!=t)v=t,d=e,y=r,m=i;else if(y=m=-(v=d=1/0),s=[],h=[],g=n.length,o)for(p=0;g>p;++p)f=n[p],f.xy&&(y=f.x),f.y>m&&(m=f.y),s.push(f.x),h.push(f.y);else for(p=0;g>p;++p){var b=+M(f=n[p],p),_=+x(f,p);v>b&&(v=b),d>_&&(d=_),b>y&&(y=b),_>m&&(m=_),s.push(b),h.push(_)}var w=y-v,S=m-d;w>S?m=d+w:y=v+S;var k=hr();if(k.add=function(n){u(k,n,+M(n,++p),+x(n,p),v,d,y,m)},k.visit=function(n){pr(n,k,v,d,y,m)},k.find=function(n){return gr(k,n[0],n[1],v,d,y,m)},p=-1,null==t){for(;++p=0?n.slice(0,t):n,r=t>=0?n.slice(t+1):"in";return e=vl.get(e)||gl,r=dl.get(r)||m,br(r(e.apply(null,lo.call(arguments,1))))},ao.interpolateHcl=Rr,ao.interpolateHsl=Dr,ao.interpolateLab=Pr,ao.interpolateRound=Ur,ao.transform=function(n){var t=fo.createElementNS(ao.ns.prefix.svg,"g");return(ao.transform=function(n){if(null!=n){t.setAttribute("transform",n);var e=t.transform.baseVal.consolidate()}return new jr(e?e.matrix:yl)})(n)},jr.prototype.toString=function(){return"translate("+this.translate+")rotate("+this.rotate+")skewX("+this.skew+")scale("+this.scale+")"};var yl={a:1,b:0,c:0,d:1,e:0,f:0};ao.interpolateTransform=$r,ao.layout={},ao.layout.bundle=function(){return function(n){for(var t=[],e=-1,r=n.length;++ea*a/y){if(v>l){var c=t.charge/l;n.px-=u*c,n.py-=o*c}return!0}if(t.point&&l&&v>l){var c=t.pointCharge/l;n.px-=u*c,n.py-=o*c}}return!t.charge}}function t(n){n.px=ao.event.x,n.py=ao.event.y,l.resume()}var e,r,i,u,o,a,l={},c=ao.dispatch("start","tick","end"),f=[1,1],s=.9,h=ml,p=Ml,g=-30,v=xl,d=.1,y=.64,M=[],x=[];return l.tick=function(){if((i*=.99)<.005)return e=null,c.end({type:"end",alpha:i=0}),!0;var t,r,l,h,p,v,y,m,b,_=M.length,w=x.length;for(r=0;w>r;++r)l=x[r],h=l.source,p=l.target,m=p.x-h.x,b=p.y-h.y,(v=m*m+b*b)&&(v=i*o[r]*((v=Math.sqrt(v))-u[r])/v,m*=v,b*=v,p.x-=m*(y=h.weight+p.weight?h.weight/(h.weight+p.weight):.5),p.y-=b*y,h.x+=m*(y=1-y),h.y+=b*y);if((y=i*d)&&(m=f[0]/2,b=f[1]/2,r=-1,y))for(;++r<_;)l=M[r],l.x+=(m-l.x)*y,l.y+=(b-l.y)*y;if(g)for(ri(t=ao.geom.quadtree(M),i,a),r=-1;++r<_;)(l=M[r]).fixed||t.visit(n(l));for(r=-1;++r<_;)l=M[r],l.fixed?(l.x=l.px,l.y=l.py):(l.x-=(l.px-(l.px=l.x))*s,l.y-=(l.py-(l.py=l.y))*s);c.tick({type:"tick",alpha:i})},l.nodes=function(n){return arguments.length?(M=n,l):M},l.links=function(n){return arguments.length?(x=n,l):x},l.size=function(n){return arguments.length?(f=n,l):f},l.linkDistance=function(n){return arguments.length?(h="function"==typeof n?n:+n,l):h},l.distance=l.linkDistance,l.linkStrength=function(n){return arguments.length?(p="function"==typeof n?n:+n,l):p},l.friction=function(n){return arguments.length?(s=+n,l):s},l.charge=function(n){return arguments.length?(g="function"==typeof n?n:+n,l):g},l.chargeDistance=function(n){return arguments.length?(v=n*n,l):Math.sqrt(v)},l.gravity=function(n){return arguments.length?(d=+n,l):d},l.theta=function(n){return arguments.length?(y=n*n,l):Math.sqrt(y)},l.alpha=function(n){return arguments.length?(n=+n,i?n>0?i=n:(e.c=null,e.t=NaN,e=null,c.end({type:"end",alpha:i=0})):n>0&&(c.start({type:"start",alpha:i=n}),e=qn(l.tick)),l):i},l.start=function(){function n(n,r){if(!e){for(e=new Array(i),l=0;i>l;++l)e[l]=[];for(l=0;c>l;++l){var u=x[l];e[u.source.index].push(u.target),e[u.target.index].push(u.source)}}for(var o,a=e[t],l=-1,f=a.length;++lt;++t)(r=M[t]).index=t,r.weight=0;for(t=0;c>t;++t)r=x[t],"number"==typeof r.source&&(r.source=M[r.source]),"number"==typeof r.target&&(r.target=M[r.target]),++r.source.weight,++r.target.weight;for(t=0;i>t;++t)r=M[t],isNaN(r.x)&&(r.x=n("x",s)),isNaN(r.y)&&(r.y=n("y",v)),isNaN(r.px)&&(r.px=r.x),isNaN(r.py)&&(r.py=r.y);if(u=[],"function"==typeof h)for(t=0;c>t;++t)u[t]=+h.call(this,x[t],t);else for(t=0;c>t;++t)u[t]=h;if(o=[],"function"==typeof p)for(t=0;c>t;++t)o[t]=+p.call(this,x[t],t);else for(t=0;c>t;++t)o[t]=p;if(a=[],"function"==typeof g)for(t=0;i>t;++t)a[t]=+g.call(this,M[t],t);else for(t=0;i>t;++t)a[t]=g;return l.resume()},l.resume=function(){return l.alpha(.1)},l.stop=function(){return l.alpha(0)},l.drag=function(){return r||(r=ao.behavior.drag().origin(m).on("dragstart.force",Qr).on("drag.force",t).on("dragend.force",ni)),arguments.length?void this.on("mouseover.force",ti).on("mouseout.force",ei).call(r):r},ao.rebind(l,c,"on")};var ml=20,Ml=1,xl=1/0;ao.layout.hierarchy=function(){function n(i){var u,o=[i],a=[];for(i.depth=0;null!=(u=o.pop());)if(a.push(u),(c=e.call(n,u,u.depth))&&(l=c.length)){for(var l,c,f;--l>=0;)o.push(f=c[l]),f.parent=u,f.depth=u.depth+1;r&&(u.value=0),u.children=c}else r&&(u.value=+r.call(n,u,u.depth)||0),delete u.children;return oi(i,function(n){var e,i;t&&(e=n.children)&&e.sort(t),r&&(i=n.parent)&&(i.value+=n.value)}),a}var t=ci,e=ai,r=li;return n.sort=function(e){return arguments.length?(t=e,n):t},n.children=function(t){return arguments.length?(e=t,n):e},n.value=function(t){return arguments.length?(r=t,n):r},n.revalue=function(t){return r&&(ui(t,function(n){n.children&&(n.value=0)}),oi(t,function(t){var e;t.children||(t.value=+r.call(n,t,t.depth)||0),(e=t.parent)&&(e.value+=t.value)})),t},n},ao.layout.partition=function(){function n(t,e,r,i){var u=t.children;if(t.x=e,t.y=t.depth*i,t.dx=r,t.dy=i,u&&(o=u.length)){var o,a,l,c=-1;for(r=t.value?r/t.value:0;++cs?-1:1),g=ao.sum(c),v=g?(s-l*p)/g:0,d=ao.range(l),y=[];return null!=e&&d.sort(e===bl?function(n,t){return c[t]-c[n]}:function(n,t){return e(o[n],o[t])}),d.forEach(function(n){y[n]={data:o[n],value:a=c[n],startAngle:f,endAngle:f+=a*v+p,padAngle:h}}),y}var t=Number,e=bl,r=0,i=Ho,u=0;return n.value=function(e){return arguments.length?(t=e,n):t},n.sort=function(t){return arguments.length?(e=t,n):e},n.startAngle=function(t){return arguments.length?(r=t,n):r},n.endAngle=function(t){return arguments.length?(i=t,n):i},n.padAngle=function(t){return arguments.length?(u=t,n):u},n};var bl={};ao.layout.stack=function(){function n(a,l){if(!(h=a.length))return a;var c=a.map(function(e,r){return t.call(n,e,r)}),f=c.map(function(t){return t.map(function(t,e){return[u.call(n,t,e),o.call(n,t,e)]})}),s=e.call(n,f,l);c=ao.permute(c,s),f=ao.permute(f,s);var h,p,g,v,d=r.call(n,f,l),y=c[0].length;for(g=0;y>g;++g)for(i.call(n,c[0][g],v=d[g],f[0][g][1]),p=1;h>p;++p)i.call(n,c[p][g],v+=f[p-1][g][1],f[p][g][1]);return a}var t=m,e=gi,r=vi,i=pi,u=si,o=hi;return n.values=function(e){return arguments.length?(t=e,n):t},n.order=function(t){return arguments.length?(e="function"==typeof t?t:_l.get(t)||gi,n):e},n.offset=function(t){return arguments.length?(r="function"==typeof t?t:wl.get(t)||vi,n):r},n.x=function(t){return arguments.length?(u=t,n):u},n.y=function(t){return arguments.length?(o=t,n):o},n.out=function(t){return arguments.length?(i=t,n):i},n};var _l=ao.map({"inside-out":function(n){var t,e,r=n.length,i=n.map(di),u=n.map(yi),o=ao.range(r).sort(function(n,t){return i[n]-i[t]}),a=0,l=0,c=[],f=[];for(t=0;r>t;++t)e=o[t],l>a?(a+=u[e],c.push(e)):(l+=u[e],f.push(e));return f.reverse().concat(c)},reverse:function(n){return ao.range(n.length).reverse()},"default":gi}),wl=ao.map({silhouette:function(n){var t,e,r,i=n.length,u=n[0].length,o=[],a=0,l=[];for(e=0;u>e;++e){for(t=0,r=0;i>t;t++)r+=n[t][e][1];r>a&&(a=r),o.push(r)}for(e=0;u>e;++e)l[e]=(a-o[e])/2;return l},wiggle:function(n){var t,e,r,i,u,o,a,l,c,f=n.length,s=n[0],h=s.length,p=[];for(p[0]=l=c=0,e=1;h>e;++e){for(t=0,i=0;f>t;++t)i+=n[t][e][1];for(t=0,u=0,a=s[e][0]-s[e-1][0];f>t;++t){for(r=0,o=(n[t][e][1]-n[t][e-1][1])/(2*a);t>r;++r)o+=(n[r][e][1]-n[r][e-1][1])/a;u+=o*n[t][e][1]}p[e]=l-=i?u/i*a:0,c>l&&(c=l)}for(e=0;h>e;++e)p[e]-=c;return p},expand:function(n){var t,e,r,i=n.length,u=n[0].length,o=1/i,a=[];for(e=0;u>e;++e){for(t=0,r=0;i>t;t++)r+=n[t][e][1];if(r)for(t=0;i>t;t++)n[t][e][1]/=r;else for(t=0;i>t;t++)n[t][e][1]=o}for(e=0;u>e;++e)a[e]=0;return a},zero:vi});ao.layout.histogram=function(){function n(n,u){for(var o,a,l=[],c=n.map(e,this),f=r.call(this,c,u),s=i.call(this,f,c,u),u=-1,h=c.length,p=s.length-1,g=t?1:1/h;++u0)for(u=-1;++u=f[0]&&a<=f[1]&&(o=l[ao.bisect(s,a,1,p)-1],o.y+=g,o.push(n[u]));return l}var t=!0,e=Number,r=bi,i=Mi;return n.value=function(t){return arguments.length?(e=t,n):e},n.range=function(t){return arguments.length?(r=En(t),n):r},n.bins=function(t){return arguments.length?(i="number"==typeof t?function(n){return xi(n,t)}:En(t),n):i},n.frequency=function(e){return arguments.length?(t=!!e,n):t},n},ao.layout.pack=function(){function n(n,u){var o=e.call(this,n,u),a=o[0],l=i[0],c=i[1],f=null==t?Math.sqrt:"function"==typeof t?t:function(){return t};if(a.x=a.y=0,oi(a,function(n){n.r=+f(n.value)}),oi(a,Ni),r){var s=r*(t?1:Math.max(2*a.r/l,2*a.r/c))/2;oi(a,function(n){n.r+=s}),oi(a,Ni),oi(a,function(n){n.r-=s})}return Ci(a,l/2,c/2,t?1:1/Math.max(2*a.r/l,2*a.r/c)),o}var t,e=ao.layout.hierarchy().sort(_i),r=0,i=[1,1];return n.size=function(t){return arguments.length?(i=t,n):i},n.radius=function(e){return arguments.length?(t=null==e||"function"==typeof e?e:+e,n):t},n.padding=function(t){return arguments.length?(r=+t,n):r},ii(n,e)},ao.layout.tree=function(){function n(n,i){var f=o.call(this,n,i),s=f[0],h=t(s);if(oi(h,e),h.parent.m=-h.z,ui(h,r),c)ui(s,u);else{var p=s,g=s,v=s;ui(s,function(n){n.xg.x&&(g=n),n.depth>v.depth&&(v=n)});var d=a(p,g)/2-p.x,y=l[0]/(g.x+a(g,p)/2+d),m=l[1]/(v.depth||1);ui(s,function(n){n.x=(n.x+d)*y,n.y=n.depth*m})}return f}function t(n){for(var t,e={A:null,children:[n]},r=[e];null!=(t=r.pop());)for(var i,u=t.children,o=0,a=u.length;a>o;++o)r.push((u[o]=i={_:u[o],parent:t,children:(i=u[o].children)&&i.slice()||[],A:null,a:null,z:0,m:0,c:0,s:0,t:null,i:o}).a=i);return e.children[0]}function e(n){var t=n.children,e=n.parent.children,r=n.i?e[n.i-1]:null;if(t.length){Di(n);var u=(t[0].z+t[t.length-1].z)/2;r?(n.z=r.z+a(n._,r._),n.m=n.z-u):n.z=u}else r&&(n.z=r.z+a(n._,r._));n.parent.A=i(n,r,n.parent.A||e[0])}function r(n){n._.x=n.z+n.parent.m,n.m+=n.parent.m}function i(n,t,e){if(t){for(var r,i=n,u=n,o=t,l=i.parent.children[0],c=i.m,f=u.m,s=o.m,h=l.m;o=Ti(o),i=qi(i),o&&i;)l=qi(l),u=Ti(u),u.a=n,r=o.z+s-i.z-c+a(o._,i._),r>0&&(Ri(Pi(o,n,e),n,r),c+=r,f+=r),s+=o.m,c+=i.m,h+=l.m,f+=u.m;o&&!Ti(u)&&(u.t=o,u.m+=s-f),i&&!qi(l)&&(l.t=i,l.m+=c-h,e=n)}return e}function u(n){n.x*=l[0],n.y=n.depth*l[1]}var o=ao.layout.hierarchy().sort(null).value(null),a=Li,l=[1,1],c=null;return n.separation=function(t){return arguments.length?(a=t,n):a},n.size=function(t){return arguments.length?(c=null==(l=t)?u:null,n):c?null:l},n.nodeSize=function(t){return arguments.length?(c=null==(l=t)?null:u,n):c?l:null},ii(n,o)},ao.layout.cluster=function(){function n(n,u){var o,a=t.call(this,n,u),l=a[0],c=0;oi(l,function(n){var t=n.children;t&&t.length?(n.x=ji(t),n.y=Ui(t)):(n.x=o?c+=e(n,o):0,n.y=0,o=n)});var f=Fi(l),s=Hi(l),h=f.x-e(f,s)/2,p=s.x+e(s,f)/2;return oi(l,i?function(n){n.x=(n.x-l.x)*r[0],n.y=(l.y-n.y)*r[1]}:function(n){n.x=(n.x-h)/(p-h)*r[0],n.y=(1-(l.y?n.y/l.y:1))*r[1]}),a}var t=ao.layout.hierarchy().sort(null).value(null),e=Li,r=[1,1],i=!1;return n.separation=function(t){return arguments.length?(e=t,n):e},n.size=function(t){return arguments.length?(i=null==(r=t),n):i?null:r},n.nodeSize=function(t){return arguments.length?(i=null!=(r=t),n):i?r:null},ii(n,t)},ao.layout.treemap=function(){function n(n,t){for(var e,r,i=-1,u=n.length;++it?0:t),e.area=isNaN(r)||0>=r?0:r}function t(e){var u=e.children;if(u&&u.length){var o,a,l,c=s(e),f=[],h=u.slice(),g=1/0,v="slice"===p?c.dx:"dice"===p?c.dy:"slice-dice"===p?1&e.depth?c.dy:c.dx:Math.min(c.dx,c.dy);for(n(h,c.dx*c.dy/e.value),f.area=0;(l=h.length)>0;)f.push(o=h[l-1]),f.area+=o.area,"squarify"!==p||(a=r(f,v))<=g?(h.pop(),g=a):(f.area-=f.pop().area,i(f,v,c,!1),v=Math.min(c.dx,c.dy),f.length=f.area=0,g=1/0);f.length&&(i(f,v,c,!0),f.length=f.area=0),u.forEach(t)}}function e(t){var r=t.children;if(r&&r.length){var u,o=s(t),a=r.slice(),l=[];for(n(a,o.dx*o.dy/t.value),l.area=0;u=a.pop();)l.push(u),l.area+=u.area,null!=u.z&&(i(l,u.z?o.dx:o.dy,o,!a.length),l.length=l.area=0);r.forEach(e)}}function r(n,t){for(var e,r=n.area,i=0,u=1/0,o=-1,a=n.length;++oe&&(u=e),e>i&&(i=e));return r*=r,t*=t,r?Math.max(t*i*g/r,r/(t*u*g)):1/0}function i(n,t,e,r){var i,u=-1,o=n.length,a=e.x,c=e.y,f=t?l(n.area/t):0; -if(t==e.dx){for((r||f>e.dy)&&(f=e.dy);++ue.dx)&&(f=e.dx);++ue&&(t=1),1>e&&(n=0),function(){var e,r,i;do e=2*Math.random()-1,r=2*Math.random()-1,i=e*e+r*r;while(!i||i>1);return n+t*e*Math.sqrt(-2*Math.log(i)/i)}},logNormal:function(){var n=ao.random.normal.apply(ao,arguments);return function(){return Math.exp(n())}},bates:function(n){var t=ao.random.irwinHall(n);return function(){return t()/n}},irwinHall:function(n){return function(){for(var t=0,e=0;n>e;e++)t+=Math.random();return t}}},ao.scale={};var Sl={floor:m,ceil:m};ao.scale.linear=function(){return Wi([0,1],[0,1],Mr,!1)};var kl={s:1,g:1,p:1,r:1,e:1};ao.scale.log=function(){return ru(ao.scale.linear().domain([0,1]),10,!0,[1,10])};var Nl=ao.format(".0e"),El={floor:function(n){return-Math.ceil(-n)},ceil:function(n){return-Math.floor(-n)}};ao.scale.pow=function(){return iu(ao.scale.linear(),1,[0,1])},ao.scale.sqrt=function(){return ao.scale.pow().exponent(.5)},ao.scale.ordinal=function(){return ou([],{t:"range",a:[[]]})},ao.scale.category10=function(){return ao.scale.ordinal().range(Al)},ao.scale.category20=function(){return ao.scale.ordinal().range(Cl)},ao.scale.category20b=function(){return ao.scale.ordinal().range(zl)},ao.scale.category20c=function(){return ao.scale.ordinal().range(Ll)};var Al=[2062260,16744206,2924588,14034728,9725885,9197131,14907330,8355711,12369186,1556175].map(xn),Cl=[2062260,11454440,16744206,16759672,2924588,10018698,14034728,16750742,9725885,12955861,9197131,12885140,14907330,16234194,8355711,13092807,12369186,14408589,1556175,10410725].map(xn),zl=[3750777,5395619,7040719,10264286,6519097,9216594,11915115,13556636,9202993,12426809,15186514,15190932,8666169,11356490,14049643,15177372,8077683,10834324,13528509,14589654].map(xn),Ll=[3244733,7057110,10406625,13032431,15095053,16616764,16625259,16634018,3253076,7652470,10607003,13101504,7695281,10394312,12369372,14342891,6513507,9868950,12434877,14277081].map(xn);ao.scale.quantile=function(){return au([],[])},ao.scale.quantize=function(){return lu(0,1,[0,1])},ao.scale.threshold=function(){return cu([.5],[0,1])},ao.scale.identity=function(){return fu([0,1])},ao.svg={},ao.svg.arc=function(){function n(){var n=Math.max(0,+e.apply(this,arguments)),c=Math.max(0,+r.apply(this,arguments)),f=o.apply(this,arguments)-Io,s=a.apply(this,arguments)-Io,h=Math.abs(s-f),p=f>s?0:1;if(n>c&&(g=c,c=n,n=g),h>=Oo)return t(c,p)+(n?t(n,1-p):"")+"Z";var g,v,d,y,m,M,x,b,_,w,S,k,N=0,E=0,A=[];if((y=(+l.apply(this,arguments)||0)/2)&&(d=u===ql?Math.sqrt(n*n+c*c):+u.apply(this,arguments),p||(E*=-1),c&&(E=tn(d/c*Math.sin(y))),n&&(N=tn(d/n*Math.sin(y)))),c){m=c*Math.cos(f+E),M=c*Math.sin(f+E),x=c*Math.cos(s-E),b=c*Math.sin(s-E);var C=Math.abs(s-f-2*E)<=Fo?0:1;if(E&&yu(m,M,x,b)===p^C){var z=(f+s)/2;m=c*Math.cos(z),M=c*Math.sin(z),x=b=null}}else m=M=0;if(n){_=n*Math.cos(s-N),w=n*Math.sin(s-N),S=n*Math.cos(f+N),k=n*Math.sin(f+N);var L=Math.abs(f-s+2*N)<=Fo?0:1;if(N&&yu(_,w,S,k)===1-p^L){var q=(f+s)/2;_=n*Math.cos(q),w=n*Math.sin(q),S=k=null}}else _=w=0;if(h>Uo&&(g=Math.min(Math.abs(c-n)/2,+i.apply(this,arguments)))>.001){v=c>n^p?0:1;var T=g,R=g;if(Fo>h){var D=null==S?[_,w]:null==x?[m,M]:Re([m,M],[S,k],[x,b],[_,w]),P=m-D[0],U=M-D[1],j=x-D[0],F=b-D[1],H=1/Math.sin(Math.acos((P*j+U*F)/(Math.sqrt(P*P+U*U)*Math.sqrt(j*j+F*F)))/2),O=Math.sqrt(D[0]*D[0]+D[1]*D[1]);R=Math.min(g,(n-O)/(H-1)),T=Math.min(g,(c-O)/(H+1))}if(null!=x){var I=mu(null==S?[_,w]:[S,k],[m,M],c,T,p),Y=mu([x,b],[_,w],c,T,p);g===T?A.push("M",I[0],"A",T,",",T," 0 0,",v," ",I[1],"A",c,",",c," 0 ",1-p^yu(I[1][0],I[1][1],Y[1][0],Y[1][1]),",",p," ",Y[1],"A",T,",",T," 0 0,",v," ",Y[0]):A.push("M",I[0],"A",T,",",T," 0 1,",v," ",Y[0])}else A.push("M",m,",",M);if(null!=S){var Z=mu([m,M],[S,k],n,-R,p),V=mu([_,w],null==x?[m,M]:[x,b],n,-R,p);g===R?A.push("L",V[0],"A",R,",",R," 0 0,",v," ",V[1],"A",n,",",n," 0 ",p^yu(V[1][0],V[1][1],Z[1][0],Z[1][1]),",",1-p," ",Z[1],"A",R,",",R," 0 0,",v," ",Z[0]):A.push("L",V[0],"A",R,",",R," 0 0,",v," ",Z[0])}else A.push("L",_,",",w)}else A.push("M",m,",",M),null!=x&&A.push("A",c,",",c," 0 ",C,",",p," ",x,",",b),A.push("L",_,",",w),null!=S&&A.push("A",n,",",n," 0 ",L,",",1-p," ",S,",",k);return A.push("Z"),A.join("")}function t(n,t){return"M0,"+n+"A"+n+","+n+" 0 1,"+t+" 0,"+-n+"A"+n+","+n+" 0 1,"+t+" 0,"+n}var e=hu,r=pu,i=su,u=ql,o=gu,a=vu,l=du;return n.innerRadius=function(t){return arguments.length?(e=En(t),n):e},n.outerRadius=function(t){return arguments.length?(r=En(t),n):r},n.cornerRadius=function(t){return arguments.length?(i=En(t),n):i},n.padRadius=function(t){return arguments.length?(u=t==ql?ql:En(t),n):u},n.startAngle=function(t){return arguments.length?(o=En(t),n):o},n.endAngle=function(t){return arguments.length?(a=En(t),n):a},n.padAngle=function(t){return arguments.length?(l=En(t),n):l},n.centroid=function(){var n=(+e.apply(this,arguments)+ +r.apply(this,arguments))/2,t=(+o.apply(this,arguments)+ +a.apply(this,arguments))/2-Io;return[Math.cos(t)*n,Math.sin(t)*n]},n};var ql="auto";ao.svg.line=function(){return Mu(m)};var Tl=ao.map({linear:xu,"linear-closed":bu,step:_u,"step-before":wu,"step-after":Su,basis:zu,"basis-open":Lu,"basis-closed":qu,bundle:Tu,cardinal:Eu,"cardinal-open":ku,"cardinal-closed":Nu,monotone:Fu});Tl.forEach(function(n,t){t.key=n,t.closed=/-closed$/.test(n)});var Rl=[0,2/3,1/3,0],Dl=[0,1/3,2/3,0],Pl=[0,1/6,2/3,1/6];ao.svg.line.radial=function(){var n=Mu(Hu);return n.radius=n.x,delete n.x,n.angle=n.y,delete n.y,n},wu.reverse=Su,Su.reverse=wu,ao.svg.area=function(){return Ou(m)},ao.svg.area.radial=function(){var n=Ou(Hu);return n.radius=n.x,delete n.x,n.innerRadius=n.x0,delete n.x0,n.outerRadius=n.x1,delete n.x1,n.angle=n.y,delete n.y,n.startAngle=n.y0,delete n.y0,n.endAngle=n.y1,delete n.y1,n},ao.svg.chord=function(){function n(n,a){var l=t(this,u,n,a),c=t(this,o,n,a);return"M"+l.p0+r(l.r,l.p1,l.a1-l.a0)+(e(l,c)?i(l.r,l.p1,l.r,l.p0):i(l.r,l.p1,c.r,c.p0)+r(c.r,c.p1,c.a1-c.a0)+i(c.r,c.p1,l.r,l.p0))+"Z"}function t(n,t,e,r){var i=t.call(n,e,r),u=a.call(n,i,r),o=l.call(n,i,r)-Io,f=c.call(n,i,r)-Io;return{r:u,a0:o,a1:f,p0:[u*Math.cos(o),u*Math.sin(o)],p1:[u*Math.cos(f),u*Math.sin(f)]}}function e(n,t){return n.a0==t.a0&&n.a1==t.a1}function r(n,t,e){return"A"+n+","+n+" 0 "+ +(e>Fo)+",1 "+t}function i(n,t,e,r){return"Q 0,0 "+r}var u=Me,o=xe,a=Iu,l=gu,c=vu;return n.radius=function(t){return arguments.length?(a=En(t),n):a},n.source=function(t){return arguments.length?(u=En(t),n):u},n.target=function(t){return arguments.length?(o=En(t),n):o},n.startAngle=function(t){return arguments.length?(l=En(t),n):l},n.endAngle=function(t){return arguments.length?(c=En(t),n):c},n},ao.svg.diagonal=function(){function n(n,i){var u=t.call(this,n,i),o=e.call(this,n,i),a=(u.y+o.y)/2,l=[u,{x:u.x,y:a},{x:o.x,y:a},o];return l=l.map(r),"M"+l[0]+"C"+l[1]+" "+l[2]+" "+l[3]}var t=Me,e=xe,r=Yu;return n.source=function(e){return arguments.length?(t=En(e),n):t},n.target=function(t){return arguments.length?(e=En(t),n):e},n.projection=function(t){return arguments.length?(r=t,n):r},n},ao.svg.diagonal.radial=function(){var n=ao.svg.diagonal(),t=Yu,e=n.projection;return n.projection=function(n){return arguments.length?e(Zu(t=n)):t},n},ao.svg.symbol=function(){function n(n,r){return(Ul.get(t.call(this,n,r))||$u)(e.call(this,n,r))}var t=Xu,e=Vu;return n.type=function(e){return arguments.length?(t=En(e),n):t},n.size=function(t){return arguments.length?(e=En(t),n):e},n};var Ul=ao.map({circle:$u,cross:function(n){var t=Math.sqrt(n/5)/2;return"M"+-3*t+","+-t+"H"+-t+"V"+-3*t+"H"+t+"V"+-t+"H"+3*t+"V"+t+"H"+t+"V"+3*t+"H"+-t+"V"+t+"H"+-3*t+"Z"},diamond:function(n){var t=Math.sqrt(n/(2*Fl)),e=t*Fl;return"M0,"+-t+"L"+e+",0 0,"+t+" "+-e+",0Z"},square:function(n){var t=Math.sqrt(n)/2;return"M"+-t+","+-t+"L"+t+","+-t+" "+t+","+t+" "+-t+","+t+"Z"},"triangle-down":function(n){var t=Math.sqrt(n/jl),e=t*jl/2;return"M0,"+e+"L"+t+","+-e+" "+-t+","+-e+"Z"},"triangle-up":function(n){var t=Math.sqrt(n/jl),e=t*jl/2;return"M0,"+-e+"L"+t+","+e+" "+-t+","+e+"Z"}});ao.svg.symbolTypes=Ul.keys();var jl=Math.sqrt(3),Fl=Math.tan(30*Yo);Co.transition=function(n){for(var t,e,r=Hl||++Zl,i=Ku(n),u=[],o=Ol||{time:Date.now(),ease:Nr,delay:0,duration:250},a=-1,l=this.length;++au;u++){i.push(t=[]);for(var e=this[u],a=0,l=e.length;l>a;a++)(r=e[a])&&n.call(r,r.__data__,a,u)&&t.push(r)}return Wu(i,this.namespace,this.id)},Yl.tween=function(n,t){var e=this.id,r=this.namespace;return arguments.length<2?this.node()[r][e].tween.get(n):Y(this,null==t?function(t){t[r][e].tween.remove(n)}:function(i){i[r][e].tween.set(n,t)})},Yl.attr=function(n,t){function e(){this.removeAttribute(a)}function r(){this.removeAttributeNS(a.space,a.local)}function i(n){return null==n?e:(n+="",function(){var t,e=this.getAttribute(a);return e!==n&&(t=o(e,n),function(n){this.setAttribute(a,t(n))})})}function u(n){return null==n?r:(n+="",function(){var t,e=this.getAttributeNS(a.space,a.local);return e!==n&&(t=o(e,n),function(n){this.setAttributeNS(a.space,a.local,t(n))})})}if(arguments.length<2){for(t in n)this.attr(t,n[t]);return this}var o="transform"==n?$r:Mr,a=ao.ns.qualify(n);return Ju(this,"attr."+n,t,a.local?u:i)},Yl.attrTween=function(n,t){function e(n,e){var r=t.call(this,n,e,this.getAttribute(i));return r&&function(n){this.setAttribute(i,r(n))}}function r(n,e){var r=t.call(this,n,e,this.getAttributeNS(i.space,i.local));return r&&function(n){this.setAttributeNS(i.space,i.local,r(n))}}var i=ao.ns.qualify(n);return this.tween("attr."+n,i.local?r:e)},Yl.style=function(n,e,r){function i(){this.style.removeProperty(n)}function u(e){return null==e?i:(e+="",function(){var i,u=t(this).getComputedStyle(this,null).getPropertyValue(n);return u!==e&&(i=Mr(u,e),function(t){this.style.setProperty(n,i(t),r)})})}var o=arguments.length;if(3>o){if("string"!=typeof n){2>o&&(e="");for(r in n)this.style(r,n[r],e);return this}r=""}return Ju(this,"style."+n,e,u)},Yl.styleTween=function(n,e,r){function i(i,u){var o=e.call(this,i,u,t(this).getComputedStyle(this,null).getPropertyValue(n));return o&&function(t){this.style.setProperty(n,o(t),r)}}return arguments.length<3&&(r=""),this.tween("style."+n,i)},Yl.text=function(n){return Ju(this,"text",n,Gu)},Yl.remove=function(){var n=this.namespace;return this.each("end.transition",function(){var t;this[n].count<2&&(t=this.parentNode)&&t.removeChild(this)})},Yl.ease=function(n){var t=this.id,e=this.namespace;return arguments.length<1?this.node()[e][t].ease:("function"!=typeof n&&(n=ao.ease.apply(ao,arguments)),Y(this,function(r){r[e][t].ease=n}))},Yl.delay=function(n){var t=this.id,e=this.namespace;return arguments.length<1?this.node()[e][t].delay:Y(this,"function"==typeof n?function(r,i,u){r[e][t].delay=+n.call(r,r.__data__,i,u)}:(n=+n,function(r){r[e][t].delay=n}))},Yl.duration=function(n){var t=this.id,e=this.namespace;return arguments.length<1?this.node()[e][t].duration:Y(this,"function"==typeof n?function(r,i,u){r[e][t].duration=Math.max(1,n.call(r,r.__data__,i,u))}:(n=Math.max(1,n),function(r){r[e][t].duration=n}))},Yl.each=function(n,t){var e=this.id,r=this.namespace;if(arguments.length<2){var i=Ol,u=Hl;try{Hl=e,Y(this,function(t,i,u){Ol=t[r][e],n.call(t,t.__data__,i,u)})}finally{Ol=i,Hl=u}}else Y(this,function(i){var u=i[r][e];(u.event||(u.event=ao.dispatch("start","end","interrupt"))).on(n,t)});return this},Yl.transition=function(){for(var n,t,e,r,i=this.id,u=++Zl,o=this.namespace,a=[],l=0,c=this.length;c>l;l++){a.push(n=[]);for(var t=this[l],f=0,s=t.length;s>f;f++)(e=t[f])&&(r=e[o][i],Qu(e,f,o,u,{time:r.time,ease:r.ease,delay:r.delay+r.duration,duration:r.duration})),n.push(e)}return Wu(a,o,u)},ao.svg.axis=function(){function n(n){n.each(function(){var n,c=ao.select(this),f=this.__chart__||e,s=this.__chart__=e.copy(),h=null==l?s.ticks?s.ticks.apply(s,a):s.domain():l,p=null==t?s.tickFormat?s.tickFormat.apply(s,a):m:t,g=c.selectAll(".tick").data(h,s),v=g.enter().insert("g",".domain").attr("class","tick").style("opacity",Uo),d=ao.transition(g.exit()).style("opacity",Uo).remove(),y=ao.transition(g.order()).style("opacity",1),M=Math.max(i,0)+o,x=Zi(s),b=c.selectAll(".domain").data([0]),_=(b.enter().append("path").attr("class","domain"),ao.transition(b));v.append("line"),v.append("text");var w,S,k,N,E=v.select("line"),A=y.select("line"),C=g.select("text").text(p),z=v.select("text"),L=y.select("text"),q="top"===r||"left"===r?-1:1;if("bottom"===r||"top"===r?(n=no,w="x",k="y",S="x2",N="y2",C.attr("dy",0>q?"0em":".71em").style("text-anchor","middle"),_.attr("d","M"+x[0]+","+q*u+"V0H"+x[1]+"V"+q*u)):(n=to,w="y",k="x",S="y2",N="x2",C.attr("dy",".32em").style("text-anchor",0>q?"end":"start"),_.attr("d","M"+q*u+","+x[0]+"H0V"+x[1]+"H"+q*u)),E.attr(N,q*i),z.attr(k,q*M),A.attr(S,0).attr(N,q*i),L.attr(w,0).attr(k,q*M),s.rangeBand){var T=s,R=T.rangeBand()/2;f=s=function(n){return T(n)+R}}else f.rangeBand?f=s:d.call(n,s,f);v.call(n,f,s),y.call(n,s,s)})}var t,e=ao.scale.linear(),r=Vl,i=6,u=6,o=3,a=[10],l=null;return n.scale=function(t){return arguments.length?(e=t,n):e},n.orient=function(t){return arguments.length?(r=t in Xl?t+"":Vl,n):r},n.ticks=function(){return arguments.length?(a=co(arguments),n):a},n.tickValues=function(t){return arguments.length?(l=t,n):l},n.tickFormat=function(e){return arguments.length?(t=e,n):t},n.tickSize=function(t){var e=arguments.length;return e?(i=+t,u=+arguments[e-1],n):i},n.innerTickSize=function(t){return arguments.length?(i=+t,n):i},n.outerTickSize=function(t){return arguments.length?(u=+t,n):u},n.tickPadding=function(t){return arguments.length?(o=+t,n):o},n.tickSubdivide=function(){return arguments.length&&n},n};var Vl="bottom",Xl={top:1,right:1,bottom:1,left:1};ao.svg.brush=function(){function n(t){t.each(function(){var t=ao.select(this).style("pointer-events","all").style("-webkit-tap-highlight-color","rgba(0,0,0,0)").on("mousedown.brush",u).on("touchstart.brush",u),o=t.selectAll(".background").data([0]);o.enter().append("rect").attr("class","background").style("visibility","hidden").style("cursor","crosshair"),t.selectAll(".extent").data([0]).enter().append("rect").attr("class","extent").style("cursor","move");var a=t.selectAll(".resize").data(v,m);a.exit().remove(),a.enter().append("g").attr("class",function(n){return"resize "+n}).style("cursor",function(n){return $l[n]}).append("rect").attr("x",function(n){return/[ew]$/.test(n)?-3:null}).attr("y",function(n){return/^[ns]/.test(n)?-3:null}).attr("width",6).attr("height",6).style("visibility","hidden"),a.style("display",n.empty()?"none":null);var l,s=ao.transition(t),h=ao.transition(o);c&&(l=Zi(c),h.attr("x",l[0]).attr("width",l[1]-l[0]),r(s)),f&&(l=Zi(f),h.attr("y",l[0]).attr("height",l[1]-l[0]),i(s)),e(s)})}function e(n){n.selectAll(".resize").attr("transform",function(n){return"translate("+s[+/e$/.test(n)]+","+h[+/^s/.test(n)]+")"})}function r(n){n.select(".extent").attr("x",s[0]),n.selectAll(".extent,.n>rect,.s>rect").attr("width",s[1]-s[0])}function i(n){n.select(".extent").attr("y",h[0]),n.selectAll(".extent,.e>rect,.w>rect").attr("height",h[1]-h[0])}function u(){function u(){32==ao.event.keyCode&&(C||(M=null,L[0]-=s[1],L[1]-=h[1],C=2),S())}function v(){32==ao.event.keyCode&&2==C&&(L[0]+=s[1],L[1]+=h[1],C=0,S())}function d(){var n=ao.mouse(b),t=!1;x&&(n[0]+=x[0],n[1]+=x[1]),C||(ao.event.altKey?(M||(M=[(s[0]+s[1])/2,(h[0]+h[1])/2]),L[0]=s[+(n[0]f?(i=r,r=f):i=f),v[0]!=r||v[1]!=i?(e?a=null:o=null,v[0]=r,v[1]=i,!0):void 0}function m(){d(),k.style("pointer-events","all").selectAll(".resize").style("display",n.empty()?"none":null),ao.select("body").style("cursor",null),q.on("mousemove.brush",null).on("mouseup.brush",null).on("touchmove.brush",null).on("touchend.brush",null).on("keydown.brush",null).on("keyup.brush",null),z(),w({type:"brushend"})}var M,x,b=this,_=ao.select(ao.event.target),w=l.of(b,arguments),k=ao.select(b),N=_.datum(),E=!/^(n|s)$/.test(N)&&c,A=!/^(e|w)$/.test(N)&&f,C=_.classed("extent"),z=W(b),L=ao.mouse(b),q=ao.select(t(b)).on("keydown.brush",u).on("keyup.brush",v);if(ao.event.changedTouches?q.on("touchmove.brush",d).on("touchend.brush",m):q.on("mousemove.brush",d).on("mouseup.brush",m),k.interrupt().selectAll("*").interrupt(),C)L[0]=s[0]-L[0],L[1]=h[0]-L[1];else if(N){var T=+/w$/.test(N),R=+/^n/.test(N);x=[s[1-T]-L[0],h[1-R]-L[1]],L[0]=s[T],L[1]=h[R]}else ao.event.altKey&&(M=L.slice());k.style("pointer-events","none").selectAll(".resize").style("display",null),ao.select("body").style("cursor",_.style("cursor")),w({type:"brushstart"}),d()}var o,a,l=N(n,"brushstart","brush","brushend"),c=null,f=null,s=[0,0],h=[0,0],p=!0,g=!0,v=Bl[0];return n.event=function(n){n.each(function(){var n=l.of(this,arguments),t={x:s,y:h,i:o,j:a},e=this.__chart__||t;this.__chart__=t,Hl?ao.select(this).transition().each("start.brush",function(){o=e.i,a=e.j,s=e.x,h=e.y,n({type:"brushstart"})}).tween("brush:brush",function(){var e=xr(s,t.x),r=xr(h,t.y);return o=a=null,function(i){s=t.x=e(i),h=t.y=r(i),n({type:"brush",mode:"resize"})}}).each("end.brush",function(){o=t.i,a=t.j,n({type:"brush",mode:"resize"}),n({type:"brushend"})}):(n({type:"brushstart"}),n({type:"brush",mode:"resize"}),n({type:"brushend"}))})},n.x=function(t){return arguments.length?(c=t,v=Bl[!c<<1|!f],n):c},n.y=function(t){return arguments.length?(f=t,v=Bl[!c<<1|!f],n):f},n.clamp=function(t){return arguments.length?(c&&f?(p=!!t[0],g=!!t[1]):c?p=!!t:f&&(g=!!t),n):c&&f?[p,g]:c?p:f?g:null},n.extent=function(t){var e,r,i,u,l;return arguments.length?(c&&(e=t[0],r=t[1],f&&(e=e[0],r=r[0]),o=[e,r],c.invert&&(e=c(e),r=c(r)),e>r&&(l=e,e=r,r=l),e==s[0]&&r==s[1]||(s=[e,r])),f&&(i=t[0],u=t[1],c&&(i=i[1],u=u[1]),a=[i,u],f.invert&&(i=f(i),u=f(u)),i>u&&(l=i,i=u,u=l),i==h[0]&&u==h[1]||(h=[i,u])),n):(c&&(o?(e=o[0],r=o[1]):(e=s[0],r=s[1],c.invert&&(e=c.invert(e),r=c.invert(r)),e>r&&(l=e,e=r,r=l))),f&&(a?(i=a[0],u=a[1]):(i=h[0],u=h[1],f.invert&&(i=f.invert(i),u=f.invert(u)),i>u&&(l=i,i=u,u=l))),c&&f?[[e,i],[r,u]]:c?[e,r]:f&&[i,u])},n.clear=function(){return n.empty()||(s=[0,0],h=[0,0],o=a=null),n},n.empty=function(){return!!c&&s[0]==s[1]||!!f&&h[0]==h[1]},ao.rebind(n,l,"on")};var $l={n:"ns-resize",e:"ew-resize",s:"ns-resize",w:"ew-resize",nw:"nwse-resize",ne:"nesw-resize",se:"nwse-resize",sw:"nesw-resize"},Bl=[["n","e","s","w","nw","ne","se","sw"],["e","w"],["n","s"],[]],Wl=ga.format=xa.timeFormat,Jl=Wl.utc,Gl=Jl("%Y-%m-%dT%H:%M:%S.%LZ");Wl.iso=Date.prototype.toISOString&&+new Date("2000-01-01T00:00:00.000Z")?eo:Gl,eo.parse=function(n){var t=new Date(n);return isNaN(t)?null:t},eo.toString=Gl.toString,ga.second=On(function(n){return new va(1e3*Math.floor(n/1e3))},function(n,t){n.setTime(n.getTime()+1e3*Math.floor(t))},function(n){return n.getSeconds()}),ga.seconds=ga.second.range,ga.seconds.utc=ga.second.utc.range,ga.minute=On(function(n){return new va(6e4*Math.floor(n/6e4))},function(n,t){n.setTime(n.getTime()+6e4*Math.floor(t))},function(n){return n.getMinutes()}),ga.minutes=ga.minute.range,ga.minutes.utc=ga.minute.utc.range,ga.hour=On(function(n){var t=n.getTimezoneOffset()/60;return new va(36e5*(Math.floor(n/36e5-t)+t))},function(n,t){n.setTime(n.getTime()+36e5*Math.floor(t))},function(n){return n.getHours()}),ga.hours=ga.hour.range,ga.hours.utc=ga.hour.utc.range,ga.month=On(function(n){return n=ga.day(n),n.setDate(1),n},function(n,t){n.setMonth(n.getMonth()+t)},function(n){return n.getMonth()}),ga.months=ga.month.range,ga.months.utc=ga.month.utc.range;var Kl=[1e3,5e3,15e3,3e4,6e4,3e5,9e5,18e5,36e5,108e5,216e5,432e5,864e5,1728e5,6048e5,2592e6,7776e6,31536e6],Ql=[[ga.second,1],[ga.second,5],[ga.second,15],[ga.second,30],[ga.minute,1],[ga.minute,5],[ga.minute,15],[ga.minute,30],[ga.hour,1],[ga.hour,3],[ga.hour,6],[ga.hour,12],[ga.day,1],[ga.day,2],[ga.week,1],[ga.month,1],[ga.month,3],[ga.year,1]],nc=Wl.multi([[".%L",function(n){return n.getMilliseconds()}],[":%S",function(n){return n.getSeconds()}],["%I:%M",function(n){return n.getMinutes()}],["%I %p",function(n){return n.getHours()}],["%a %d",function(n){return n.getDay()&&1!=n.getDate()}],["%b %d",function(n){return 1!=n.getDate()}],["%B",function(n){return n.getMonth()}],["%Y",zt]]),tc={range:function(n,t,e){return ao.range(Math.ceil(n/e)*e,+t,e).map(io)},floor:m,ceil:m};Ql.year=ga.year,ga.scale=function(){return ro(ao.scale.linear(),Ql,nc)};var ec=Ql.map(function(n){return[n[0].utc,n[1]]}),rc=Jl.multi([[".%L",function(n){return n.getUTCMilliseconds()}],[":%S",function(n){return n.getUTCSeconds()}],["%I:%M",function(n){return n.getUTCMinutes()}],["%I %p",function(n){return n.getUTCHours()}],["%a %d",function(n){return n.getUTCDay()&&1!=n.getUTCDate()}],["%b %d",function(n){return 1!=n.getUTCDate()}],["%B",function(n){return n.getUTCMonth()}],["%Y",zt]]);ec.year=ga.year.utc,ga.scale.utc=function(){return ro(ao.scale.linear(),ec,rc)},ao.text=An(function(n){return n.responseText}),ao.json=function(n,t){return Cn(n,"application/json",uo,t)},ao.html=function(n,t){return Cn(n,"text/html",oo,t)},ao.xml=An(function(n){return n.responseXML}),"function"==typeof define&&define.amd?(this.d3=ao,define(ao)):"object"==typeof module&&module.exports?module.exports=ao:this.d3=ao}(); \ No newline at end of file diff --git a/backend/coverage-report-final/_js/file.js b/backend/coverage-report-final/_js/file.js deleted file mode 100644 index 124a8a18..00000000 --- a/backend/coverage-report-final/_js/file.js +++ /dev/null @@ -1,53 +0,0 @@ -$(function () { - var $window = $(window) - , $top_link = $('#toplink') - , $body = $('body, html') - , offset = $('#code').offset().top; - - $top_link.hide().click(function (event) { - event.preventDefault(); - $body.animate({scrollTop: 0}, 800); - }); - - $window.scroll(function () { - if ($window.scrollTop() > offset) { - $top_link.fadeIn(); - } else { - $top_link.fadeOut(); - } - }); - - var $popovers = $('.popin > :first-child'); - $('.popin').on({ - 'click.popover': function (event) { - event.stopPropagation(); - - var $container = $(this).children().first(); - - //Close all other popovers: - $popovers.each(function () { - var $current = $(this); - if (!$current.is($container)) { - $current.popover('hide'); - } - }); - - // Toggle this popover: - $container.popover('toggle'); - }, - }); - - //Hide all popovers on outside click: - $(document).click(function (event) { - if ($(event.target).closest($('.popover')).length === 0) { - $popovers.popover('hide'); - } - }); - - //Hide all popovers on escape: - $(document).keyup(function (event) { - if (event.key === 'Escape') { - $popovers.popover('hide'); - } - }); -}); diff --git a/backend/coverage-report-final/_js/jquery.min.js b/backend/coverage-report-final/_js/jquery.min.js deleted file mode 100644 index 798cc8bf..00000000 --- a/backend/coverage-report-final/_js/jquery.min.js +++ /dev/null @@ -1,2 +0,0 @@ -/*! jQuery v3.7.1 | (c) OpenJS Foundation and other contributors | jquery.org/license */ -!function(e,t){"use strict";"object"==typeof module&&"object"==typeof module.exports?module.exports=e.document?t(e,!0):function(e){if(!e.document)throw new Error("jQuery requires a window with a document");return t(e)}:t(e)}("undefined"!=typeof window?window:this,function(ie,e){"use strict";var oe=[],r=Object.getPrototypeOf,ae=oe.slice,g=oe.flat?function(e){return oe.flat.call(e)}:function(e){return oe.concat.apply([],e)},s=oe.push,se=oe.indexOf,n={},i=n.toString,ue=n.hasOwnProperty,o=ue.toString,a=o.call(Object),le={},v=function(e){return"function"==typeof e&&"number"!=typeof e.nodeType&&"function"!=typeof e.item},y=function(e){return null!=e&&e===e.window},C=ie.document,u={type:!0,src:!0,nonce:!0,noModule:!0};function m(e,t,n){var r,i,o=(n=n||C).createElement("script");if(o.text=e,t)for(r in u)(i=t[r]||t.getAttribute&&t.getAttribute(r))&&o.setAttribute(r,i);n.head.appendChild(o).parentNode.removeChild(o)}function x(e){return null==e?e+"":"object"==typeof e||"function"==typeof e?n[i.call(e)]||"object":typeof e}var t="3.7.1",l=/HTML$/i,ce=function(e,t){return new ce.fn.init(e,t)};function c(e){var t=!!e&&"length"in e&&e.length,n=x(e);return!v(e)&&!y(e)&&("array"===n||0===t||"number"==typeof t&&0+~]|"+ge+")"+ge+"*"),x=new RegExp(ge+"|>"),j=new RegExp(g),A=new RegExp("^"+t+"$"),D={ID:new RegExp("^#("+t+")"),CLASS:new RegExp("^\\.("+t+")"),TAG:new RegExp("^("+t+"|[*])"),ATTR:new RegExp("^"+p),PSEUDO:new RegExp("^"+g),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+ge+"*(even|odd|(([+-]|)(\\d*)n|)"+ge+"*(?:([+-]|)"+ge+"*(\\d+)|))"+ge+"*\\)|)","i"),bool:new RegExp("^(?:"+f+")$","i"),needsContext:new RegExp("^"+ge+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+ge+"*((?:-\\d)?\\d*)"+ge+"*\\)|)(?=[^-]|$)","i")},N=/^(?:input|select|textarea|button)$/i,q=/^h\d$/i,L=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,H=/[+~]/,O=new RegExp("\\\\[\\da-fA-F]{1,6}"+ge+"?|\\\\([^\\r\\n\\f])","g"),P=function(e,t){var n="0x"+e.slice(1)-65536;return t||(n<0?String.fromCharCode(n+65536):String.fromCharCode(n>>10|55296,1023&n|56320))},M=function(){V()},R=J(function(e){return!0===e.disabled&&fe(e,"fieldset")},{dir:"parentNode",next:"legend"});try{k.apply(oe=ae.call(ye.childNodes),ye.childNodes),oe[ye.childNodes.length].nodeType}catch(e){k={apply:function(e,t){me.apply(e,ae.call(t))},call:function(e){me.apply(e,ae.call(arguments,1))}}}function I(t,e,n,r){var i,o,a,s,u,l,c,f=e&&e.ownerDocument,p=e?e.nodeType:9;if(n=n||[],"string"!=typeof t||!t||1!==p&&9!==p&&11!==p)return n;if(!r&&(V(e),e=e||T,C)){if(11!==p&&(u=L.exec(t)))if(i=u[1]){if(9===p){if(!(a=e.getElementById(i)))return n;if(a.id===i)return k.call(n,a),n}else if(f&&(a=f.getElementById(i))&&I.contains(e,a)&&a.id===i)return k.call(n,a),n}else{if(u[2])return k.apply(n,e.getElementsByTagName(t)),n;if((i=u[3])&&e.getElementsByClassName)return k.apply(n,e.getElementsByClassName(i)),n}if(!(h[t+" "]||d&&d.test(t))){if(c=t,f=e,1===p&&(x.test(t)||m.test(t))){(f=H.test(t)&&U(e.parentNode)||e)==e&&le.scope||((s=e.getAttribute("id"))?s=ce.escapeSelector(s):e.setAttribute("id",s=S)),o=(l=Y(t)).length;while(o--)l[o]=(s?"#"+s:":scope")+" "+Q(l[o]);c=l.join(",")}try{return k.apply(n,f.querySelectorAll(c)),n}catch(e){h(t,!0)}finally{s===S&&e.removeAttribute("id")}}}return re(t.replace(ve,"$1"),e,n,r)}function W(){var r=[];return function e(t,n){return r.push(t+" ")>b.cacheLength&&delete e[r.shift()],e[t+" "]=n}}function F(e){return e[S]=!0,e}function $(e){var t=T.createElement("fieldset");try{return!!e(t)}catch(e){return!1}finally{t.parentNode&&t.parentNode.removeChild(t),t=null}}function B(t){return function(e){return fe(e,"input")&&e.type===t}}function _(t){return function(e){return(fe(e,"input")||fe(e,"button"))&&e.type===t}}function z(t){return function(e){return"form"in e?e.parentNode&&!1===e.disabled?"label"in e?"label"in e.parentNode?e.parentNode.disabled===t:e.disabled===t:e.isDisabled===t||e.isDisabled!==!t&&R(e)===t:e.disabled===t:"label"in e&&e.disabled===t}}function X(a){return F(function(o){return o=+o,F(function(e,t){var n,r=a([],e.length,o),i=r.length;while(i--)e[n=r[i]]&&(e[n]=!(t[n]=e[n]))})})}function U(e){return e&&"undefined"!=typeof e.getElementsByTagName&&e}function V(e){var t,n=e?e.ownerDocument||e:ye;return n!=T&&9===n.nodeType&&n.documentElement&&(r=(T=n).documentElement,C=!ce.isXMLDoc(T),i=r.matches||r.webkitMatchesSelector||r.msMatchesSelector,r.msMatchesSelector&&ye!=T&&(t=T.defaultView)&&t.top!==t&&t.addEventListener("unload",M),le.getById=$(function(e){return r.appendChild(e).id=ce.expando,!T.getElementsByName||!T.getElementsByName(ce.expando).length}),le.disconnectedMatch=$(function(e){return i.call(e,"*")}),le.scope=$(function(){return T.querySelectorAll(":scope")}),le.cssHas=$(function(){try{return T.querySelector(":has(*,:jqfake)"),!1}catch(e){return!0}}),le.getById?(b.filter.ID=function(e){var t=e.replace(O,P);return function(e){return e.getAttribute("id")===t}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&C){var n=t.getElementById(e);return n?[n]:[]}}):(b.filter.ID=function(e){var n=e.replace(O,P);return function(e){var t="undefined"!=typeof e.getAttributeNode&&e.getAttributeNode("id");return t&&t.value===n}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&C){var n,r,i,o=t.getElementById(e);if(o){if((n=o.getAttributeNode("id"))&&n.value===e)return[o];i=t.getElementsByName(e),r=0;while(o=i[r++])if((n=o.getAttributeNode("id"))&&n.value===e)return[o]}return[]}}),b.find.TAG=function(e,t){return"undefined"!=typeof t.getElementsByTagName?t.getElementsByTagName(e):t.querySelectorAll(e)},b.find.CLASS=function(e,t){if("undefined"!=typeof t.getElementsByClassName&&C)return t.getElementsByClassName(e)},d=[],$(function(e){var t;r.appendChild(e).innerHTML="",e.querySelectorAll("[selected]").length||d.push("\\["+ge+"*(?:value|"+f+")"),e.querySelectorAll("[id~="+S+"-]").length||d.push("~="),e.querySelectorAll("a#"+S+"+*").length||d.push(".#.+[+~]"),e.querySelectorAll(":checked").length||d.push(":checked"),(t=T.createElement("input")).setAttribute("type","hidden"),e.appendChild(t).setAttribute("name","D"),r.appendChild(e).disabled=!0,2!==e.querySelectorAll(":disabled").length&&d.push(":enabled",":disabled"),(t=T.createElement("input")).setAttribute("name",""),e.appendChild(t),e.querySelectorAll("[name='']").length||d.push("\\["+ge+"*name"+ge+"*="+ge+"*(?:''|\"\")")}),le.cssHas||d.push(":has"),d=d.length&&new RegExp(d.join("|")),l=function(e,t){if(e===t)return a=!0,0;var n=!e.compareDocumentPosition-!t.compareDocumentPosition;return n||(1&(n=(e.ownerDocument||e)==(t.ownerDocument||t)?e.compareDocumentPosition(t):1)||!le.sortDetached&&t.compareDocumentPosition(e)===n?e===T||e.ownerDocument==ye&&I.contains(ye,e)?-1:t===T||t.ownerDocument==ye&&I.contains(ye,t)?1:o?se.call(o,e)-se.call(o,t):0:4&n?-1:1)}),T}for(e in I.matches=function(e,t){return I(e,null,null,t)},I.matchesSelector=function(e,t){if(V(e),C&&!h[t+" "]&&(!d||!d.test(t)))try{var n=i.call(e,t);if(n||le.disconnectedMatch||e.document&&11!==e.document.nodeType)return n}catch(e){h(t,!0)}return 0":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(O,P),e[3]=(e[3]||e[4]||e[5]||"").replace(O,P),"~="===e[2]&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),"nth"===e[1].slice(0,3)?(e[3]||I.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*("even"===e[3]||"odd"===e[3])),e[5]=+(e[7]+e[8]||"odd"===e[3])):e[3]&&I.error(e[0]),e},PSEUDO:function(e){var t,n=!e[6]&&e[2];return D.CHILD.test(e[0])?null:(e[3]?e[2]=e[4]||e[5]||"":n&&j.test(n)&&(t=Y(n,!0))&&(t=n.indexOf(")",n.length-t)-n.length)&&(e[0]=e[0].slice(0,t),e[2]=n.slice(0,t)),e.slice(0,3))}},filter:{TAG:function(e){var t=e.replace(O,P).toLowerCase();return"*"===e?function(){return!0}:function(e){return fe(e,t)}},CLASS:function(e){var t=s[e+" "];return t||(t=new RegExp("(^|"+ge+")"+e+"("+ge+"|$)"))&&s(e,function(e){return t.test("string"==typeof e.className&&e.className||"undefined"!=typeof e.getAttribute&&e.getAttribute("class")||"")})},ATTR:function(n,r,i){return function(e){var t=I.attr(e,n);return null==t?"!="===r:!r||(t+="","="===r?t===i:"!="===r?t!==i:"^="===r?i&&0===t.indexOf(i):"*="===r?i&&-1:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i;function T(e,n,r){return v(n)?ce.grep(e,function(e,t){return!!n.call(e,t,e)!==r}):n.nodeType?ce.grep(e,function(e){return e===n!==r}):"string"!=typeof n?ce.grep(e,function(e){return-1)[^>]*|#([\w-]+))$/;(ce.fn.init=function(e,t,n){var r,i;if(!e)return this;if(n=n||k,"string"==typeof e){if(!(r="<"===e[0]&&">"===e[e.length-1]&&3<=e.length?[null,e,null]:S.exec(e))||!r[1]&&t)return!t||t.jquery?(t||n).find(e):this.constructor(t).find(e);if(r[1]){if(t=t instanceof ce?t[0]:t,ce.merge(this,ce.parseHTML(r[1],t&&t.nodeType?t.ownerDocument||t:C,!0)),w.test(r[1])&&ce.isPlainObject(t))for(r in t)v(this[r])?this[r](t[r]):this.attr(r,t[r]);return this}return(i=C.getElementById(r[2]))&&(this[0]=i,this.length=1),this}return e.nodeType?(this[0]=e,this.length=1,this):v(e)?void 0!==n.ready?n.ready(e):e(ce):ce.makeArray(e,this)}).prototype=ce.fn,k=ce(C);var E=/^(?:parents|prev(?:Until|All))/,j={children:!0,contents:!0,next:!0,prev:!0};function A(e,t){while((e=e[t])&&1!==e.nodeType);return e}ce.fn.extend({has:function(e){var t=ce(e,this),n=t.length;return this.filter(function(){for(var e=0;e\x20\t\r\n\f]*)/i,Ce=/^$|^module$|\/(?:java|ecma)script/i;xe=C.createDocumentFragment().appendChild(C.createElement("div")),(be=C.createElement("input")).setAttribute("type","radio"),be.setAttribute("checked","checked"),be.setAttribute("name","t"),xe.appendChild(be),le.checkClone=xe.cloneNode(!0).cloneNode(!0).lastChild.checked,xe.innerHTML="",le.noCloneChecked=!!xe.cloneNode(!0).lastChild.defaultValue,xe.innerHTML="",le.option=!!xe.lastChild;var ke={thead:[1,"","
"],col:[2,"","
"],tr:[2,"","
"],td:[3,"","
"],_default:[0,"",""]};function Se(e,t){var n;return n="undefined"!=typeof e.getElementsByTagName?e.getElementsByTagName(t||"*"):"undefined"!=typeof e.querySelectorAll?e.querySelectorAll(t||"*"):[],void 0===t||t&&fe(e,t)?ce.merge([e],n):n}function Ee(e,t){for(var n=0,r=e.length;n",""]);var je=/<|&#?\w+;/;function Ae(e,t,n,r,i){for(var o,a,s,u,l,c,f=t.createDocumentFragment(),p=[],d=0,h=e.length;d\s*$/g;function Re(e,t){return fe(e,"table")&&fe(11!==t.nodeType?t:t.firstChild,"tr")&&ce(e).children("tbody")[0]||e}function Ie(e){return e.type=(null!==e.getAttribute("type"))+"/"+e.type,e}function We(e){return"true/"===(e.type||"").slice(0,5)?e.type=e.type.slice(5):e.removeAttribute("type"),e}function Fe(e,t){var n,r,i,o,a,s;if(1===t.nodeType){if(_.hasData(e)&&(s=_.get(e).events))for(i in _.remove(t,"handle events"),s)for(n=0,r=s[i].length;n").attr(n.scriptAttrs||{}).prop({charset:n.scriptCharset,src:n.url}).on("load error",i=function(e){r.remove(),i=null,e&&t("error"===e.type?404:200,e.type)}),C.head.appendChild(r[0])},abort:function(){i&&i()}}});var Jt,Kt=[],Zt=/(=)\?(?=&|$)|\?\?/;ce.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var e=Kt.pop()||ce.expando+"_"+jt.guid++;return this[e]=!0,e}}),ce.ajaxPrefilter("json jsonp",function(e,t,n){var r,i,o,a=!1!==e.jsonp&&(Zt.test(e.url)?"url":"string"==typeof e.data&&0===(e.contentType||"").indexOf("application/x-www-form-urlencoded")&&Zt.test(e.data)&&"data");if(a||"jsonp"===e.dataTypes[0])return r=e.jsonpCallback=v(e.jsonpCallback)?e.jsonpCallback():e.jsonpCallback,a?e[a]=e[a].replace(Zt,"$1"+r):!1!==e.jsonp&&(e.url+=(At.test(e.url)?"&":"?")+e.jsonp+"="+r),e.converters["script json"]=function(){return o||ce.error(r+" was not called"),o[0]},e.dataTypes[0]="json",i=ie[r],ie[r]=function(){o=arguments},n.always(function(){void 0===i?ce(ie).removeProp(r):ie[r]=i,e[r]&&(e.jsonpCallback=t.jsonpCallback,Kt.push(r)),o&&v(i)&&i(o[0]),o=i=void 0}),"script"}),le.createHTMLDocument=((Jt=C.implementation.createHTMLDocument("").body).innerHTML="
",2===Jt.childNodes.length),ce.parseHTML=function(e,t,n){return"string"!=typeof e?[]:("boolean"==typeof t&&(n=t,t=!1),t||(le.createHTMLDocument?((r=(t=C.implementation.createHTMLDocument("")).createElement("base")).href=C.location.href,t.head.appendChild(r)):t=C),o=!n&&[],(i=w.exec(e))?[t.createElement(i[1])]:(i=Ae([e],t,o),o&&o.length&&ce(o).remove(),ce.merge([],i.childNodes)));var r,i,o},ce.fn.load=function(e,t,n){var r,i,o,a=this,s=e.indexOf(" ");return-1").append(ce.parseHTML(e)).find(r):e)}).always(n&&function(e,t){a.each(function(){n.apply(this,o||[e.responseText,t,e])})}),this},ce.expr.pseudos.animated=function(t){return ce.grep(ce.timers,function(e){return t===e.elem}).length},ce.offset={setOffset:function(e,t,n){var r,i,o,a,s,u,l=ce.css(e,"position"),c=ce(e),f={};"static"===l&&(e.style.position="relative"),s=c.offset(),o=ce.css(e,"top"),u=ce.css(e,"left"),("absolute"===l||"fixed"===l)&&-1<(o+u).indexOf("auto")?(a=(r=c.position()).top,i=r.left):(a=parseFloat(o)||0,i=parseFloat(u)||0),v(t)&&(t=t.call(e,n,ce.extend({},s))),null!=t.top&&(f.top=t.top-s.top+a),null!=t.left&&(f.left=t.left-s.left+i),"using"in t?t.using.call(e,f):c.css(f)}},ce.fn.extend({offset:function(t){if(arguments.length)return void 0===t?this:this.each(function(e){ce.offset.setOffset(this,t,e)});var e,n,r=this[0];return r?r.getClientRects().length?(e=r.getBoundingClientRect(),n=r.ownerDocument.defaultView,{top:e.top+n.pageYOffset,left:e.left+n.pageXOffset}):{top:0,left:0}:void 0},position:function(){if(this[0]){var e,t,n,r=this[0],i={top:0,left:0};if("fixed"===ce.css(r,"position"))t=r.getBoundingClientRect();else{t=this.offset(),n=r.ownerDocument,e=r.offsetParent||n.documentElement;while(e&&(e===n.body||e===n.documentElement)&&"static"===ce.css(e,"position"))e=e.parentNode;e&&e!==r&&1===e.nodeType&&((i=ce(e).offset()).top+=ce.css(e,"borderTopWidth",!0),i.left+=ce.css(e,"borderLeftWidth",!0))}return{top:t.top-i.top-ce.css(r,"marginTop",!0),left:t.left-i.left-ce.css(r,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var e=this.offsetParent;while(e&&"static"===ce.css(e,"position"))e=e.offsetParent;return e||J})}}),ce.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(t,i){var o="pageYOffset"===i;ce.fn[t]=function(e){return M(this,function(e,t,n){var r;if(y(e)?r=e:9===e.nodeType&&(r=e.defaultView),void 0===n)return r?r[i]:e[t];r?r.scrollTo(o?r.pageXOffset:n,o?n:r.pageYOffset):e[t]=n},t,e,arguments.length)}}),ce.each(["top","left"],function(e,n){ce.cssHooks[n]=Ye(le.pixelPosition,function(e,t){if(t)return t=Ge(e,n),_e.test(t)?ce(e).position()[n]+"px":t})}),ce.each({Height:"height",Width:"width"},function(a,s){ce.each({padding:"inner"+a,content:s,"":"outer"+a},function(r,o){ce.fn[o]=function(e,t){var n=arguments.length&&(r||"boolean"!=typeof e),i=r||(!0===e||!0===t?"margin":"border");return M(this,function(e,t,n){var r;return y(e)?0===o.indexOf("outer")?e["inner"+a]:e.document.documentElement["client"+a]:9===e.nodeType?(r=e.documentElement,Math.max(e.body["scroll"+a],r["scroll"+a],e.body["offset"+a],r["offset"+a],r["client"+a])):void 0===n?ce.css(e,t,i):ce.style(e,t,n,i)},s,n?e:void 0,n)}})}),ce.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(e,t){ce.fn[t]=function(e){return this.on(t,e)}}),ce.fn.extend({bind:function(e,t,n){return this.on(e,null,t,n)},unbind:function(e,t){return this.off(e,null,t)},delegate:function(e,t,n,r){return this.on(t,e,n,r)},undelegate:function(e,t,n){return 1===arguments.length?this.off(e,"**"):this.off(t,e||"**",n)},hover:function(e,t){return this.on("mouseenter",e).on("mouseleave",t||e)}}),ce.each("blur focus focusin focusout resize scroll click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup contextmenu".split(" "),function(e,n){ce.fn[n]=function(e,t){return 0f&&(e=a.render.queue[f]);f++)d=e.generate(),typeof e.callback==typeof Function&&e.callback(d);a.render.queue.splice(0,f),a.render.queue.length?setTimeout(c):(a.dispatch.render_end(),a.render.active=!1)};setTimeout(c)},a.render.active=!1,a.render.queue=[],a.addGraph=function(b){typeof arguments[0]==typeof Function&&(b={generate:arguments[0],callback:arguments[1]}),a.render.queue.push(b),a.render.active||a.render()},"undefined"!=typeof module&&"undefined"!=typeof exports&&(module.exports=a),"undefined"!=typeof window&&(window.nv=a),a.dom.write=function(a){return void 0!==window.fastdom?fastdom.write(a):a()},a.dom.read=function(a){return void 0!==window.fastdom?fastdom.read(a):a()},a.interactiveGuideline=function(){"use strict";function b(l){l.each(function(l){function m(){var a=d3.mouse(this),d=a[0],e=a[1],i=!0,j=!1;if(k&&(d=d3.event.offsetX,e=d3.event.offsetY,"svg"!==d3.event.target.tagName&&(i=!1),d3.event.target.className.baseVal.match("nv-legend")&&(j=!0)),i&&(d-=f.left,e-=f.top),0>d||0>e||d>o||e>p||d3.event.relatedTarget&&void 0===d3.event.relatedTarget.ownerSVGElement||j){if(k&&d3.event.relatedTarget&&void 0===d3.event.relatedTarget.ownerSVGElement&&(void 0===d3.event.relatedTarget.className||d3.event.relatedTarget.className.match(c.nvPointerEventsClass)))return;return h.elementMouseout({mouseX:d,mouseY:e}),b.renderGuideLine(null),void c.hidden(!0)}c.hidden(!1);var l=g.invert(d);h.elementMousemove({mouseX:d,mouseY:e,pointXValue:l}),"dblclick"===d3.event.type&&h.elementDblclick({mouseX:d,mouseY:e,pointXValue:l}),"click"===d3.event.type&&h.elementClick({mouseX:d,mouseY:e,pointXValue:l})}var n=d3.select(this),o=d||960,p=e||400,q=n.selectAll("g.nv-wrap.nv-interactiveLineLayer").data([l]),r=q.enter().append("g").attr("class"," nv-wrap nv-interactiveLineLayer");r.append("g").attr("class","nv-interactiveGuideLine"),j&&(j.on("touchmove",m).on("mousemove",m,!0).on("mouseout",m,!0).on("dblclick",m).on("click",m),b.guideLine=null,b.renderGuideLine=function(c){i&&(b.guideLine&&b.guideLine.attr("x1")===c||a.dom.write(function(){var b=q.select(".nv-interactiveGuideLine").selectAll("line").data(null!=c?[a.utils.NaNtoZero(c)]:[],String);b.enter().append("line").attr("class","nv-guideline").attr("x1",function(a){return a}).attr("x2",function(a){return a}).attr("y1",p).attr("y2",0),b.exit().remove()}))})})}var c=a.models.tooltip();c.duration(0).hideDelay(0)._isInteractiveLayer(!0).hidden(!1);var d=null,e=null,f={left:0,top:0},g=d3.scale.linear(),h=d3.dispatch("elementMousemove","elementMouseout","elementClick","elementDblclick"),i=!0,j=null,k="ActiveXObject"in window;return b.dispatch=h,b.tooltip=c,b.margin=function(a){return arguments.length?(f.top="undefined"!=typeof a.top?a.top:f.top,f.left="undefined"!=typeof a.left?a.left:f.left,b):f},b.width=function(a){return arguments.length?(d=a,b):d},b.height=function(a){return arguments.length?(e=a,b):e},b.xScale=function(a){return arguments.length?(g=a,b):g},b.showGuideLine=function(a){return arguments.length?(i=a,b):i},b.svgContainer=function(a){return arguments.length?(j=a,b):j},b},a.interactiveBisect=function(a,b,c){"use strict";if(!(a instanceof Array))return null;var d;d="function"!=typeof c?function(a){return a.x}:c;var e=function(a,b){return d(a)-b},f=d3.bisector(e).left,g=d3.max([0,f(a,b)-1]),h=d(a[g]);if("undefined"==typeof h&&(h=g),h===b)return g;var i=d3.min([g+1,a.length-1]),j=d(a[i]);return"undefined"==typeof j&&(j=i),Math.abs(j-b)>=Math.abs(h-b)?g:i},a.nearestValueIndex=function(a,b,c){"use strict";var d=1/0,e=null;return a.forEach(function(a,f){var g=Math.abs(b-a);null!=a&&d>=g&&c>g&&(d=g,e=f)}),e},function(){"use strict";a.models.tooltip=function(){function b(){if(k){var a=d3.select(k);"svg"!==a.node().tagName&&(a=a.select("svg"));var b=a.node()?a.attr("viewBox"):null;if(b){b=b.split(" ");var c=parseInt(a.style("width"),10)/b[2];p.left=p.left*c,p.top=p.top*c}}}function c(){if(!n){var a;a=k?k:document.body,n=d3.select(a).append("div").attr("class","nvtooltip "+(j?j:"xy-tooltip")).attr("id",v),n.style("top",0).style("left",0),n.style("opacity",0),n.selectAll("div, table, td, tr").classed(w,!0),n.classed(w,!0),o=n.node()}}function d(){if(r&&B(e)){b();var f=p.left,g=null!==i?i:p.top;return a.dom.write(function(){c();var b=A(e);b&&(o.innerHTML=b),k&&u?a.dom.read(function(){var a=k.getElementsByTagName("svg")[0],b={left:0,top:0};if(a){var c=a.getBoundingClientRect(),d=k.getBoundingClientRect(),e=c.top;if(0>e){var i=k.getBoundingClientRect();e=Math.abs(e)>i.height?0:e}b.top=Math.abs(e-d.top),b.left=Math.abs(c.left-d.left)}f+=k.offsetLeft+b.left-2*k.scrollLeft,g+=k.offsetTop+b.top-2*k.scrollTop,h&&h>0&&(g=Math.floor(g/h)*h),C([f,g])}):C([f,g])}),d}}var e=null,f="w",g=25,h=0,i=null,j=null,k=null,l=!0,m=400,n=null,o=null,p={left:null,top:null},q={left:0,top:0},r=!0,s=100,t=!0,u=!1,v="nvtooltip-"+Math.floor(1e5*Math.random()),w="nv-pointer-events-none",x=function(a){return a},y=function(a){return a},z=function(a){return a},A=function(a){if(null===a)return"";var b=d3.select(document.createElement("table"));if(t){var c=b.selectAll("thead").data([a]).enter().append("thead");c.append("tr").append("td").attr("colspan",3).append("strong").classed("x-value",!0).html(y(a.value))}var d=b.selectAll("tbody").data([a]).enter().append("tbody"),e=d.selectAll("tr").data(function(a){return a.series}).enter().append("tr").classed("highlight",function(a){return a.highlight});e.append("td").classed("legend-color-guide",!0).append("div").style("background-color",function(a){return a.color}),e.append("td").classed("key",!0).html(function(a,b){return z(a.key,b)}),e.append("td").classed("value",!0).html(function(a,b){return x(a.value,b)}),e.selectAll("td").each(function(a){if(a.highlight){var b=d3.scale.linear().domain([0,1]).range(["#fff",a.color]),c=.6;d3.select(this).style("border-bottom-color",b(c)).style("border-top-color",b(c))}});var f=b.node().outerHTML;return void 0!==a.footer&&(f+=""),f},B=function(a){if(a&&a.series){if(a.series instanceof Array)return!!a.series.length;if(a.series instanceof Object)return a.series=[a.series],!0}return!1},C=function(b){o&&a.dom.read(function(){var c,d,e=parseInt(o.offsetHeight,10),h=parseInt(o.offsetWidth,10),i=a.utils.windowSize().width,j=a.utils.windowSize().height,k=window.pageYOffset,p=window.pageXOffset;j=window.innerWidth>=document.body.scrollWidth?j:j-16,i=window.innerHeight>=document.body.scrollHeight?i:i-16;var r,t,u=function(a){var b=d;do isNaN(a.offsetTop)||(b+=a.offsetTop),a=a.offsetParent;while(a);return b},v=function(a){var b=c;do isNaN(a.offsetLeft)||(b+=a.offsetLeft),a=a.offsetParent;while(a);return b};switch(f){case"e":c=b[0]-h-g,d=b[1]-e/2,r=v(o),t=u(o),p>r&&(c=b[0]+g>p?b[0]+g:p-r+c),k>t&&(d=k-t+d),t+e>k+j&&(d=k+j-t+d-e);break;case"w":c=b[0]+g,d=b[1]-e/2,r=v(o),t=u(o),r+h>i&&(c=b[0]-h-g),k>t&&(d=k+5),t+e>k+j&&(d=k+j-t+d-e);break;case"n":c=b[0]-h/2-5,d=b[1]+g,r=v(o),t=u(o),p>r&&(c=p+5),r+h>i&&(c=c-h/2+5),t+e>k+j&&(d=k+j-t+d-e);break;case"s":c=b[0]-h/2,d=b[1]-e-g,r=v(o),t=u(o),p>r&&(c=p+5),r+h>i&&(c=c-h/2+5),k>t&&(d=k);break;case"none":c=b[0],d=b[1]-g,r=v(o),t=u(o)}c-=q.left,d-=q.top;var w=o.getBoundingClientRect(),k=window.pageYOffset||document.documentElement.scrollTop,p=window.pageXOffset||document.documentElement.scrollLeft,x="translate("+(w.left+p)+"px, "+(w.top+k)+"px)",y="translate("+c+"px, "+d+"px)",z=d3.interpolateString(x,y),A=n.style("opacity")<.1;l?n.transition().delay(m).duration(0).style("opacity",0):n.interrupt().transition().duration(A?0:s).styleTween("transform",function(){return z},"important").style("-webkit-transform",y).style("opacity",1)})};return d.nvPointerEventsClass=w,d.options=a.utils.optionsFunc.bind(d),d._options=Object.create({},{duration:{get:function(){return s},set:function(a){s=a}},gravity:{get:function(){return f},set:function(a){f=a}},distance:{get:function(){return g},set:function(a){g=a}},snapDistance:{get:function(){return h},set:function(a){h=a}},classes:{get:function(){return j},set:function(a){j=a}},chartContainer:{get:function(){return k},set:function(a){k=a}},fixedTop:{get:function(){return i},set:function(a){i=a}},enabled:{get:function(){return r},set:function(a){r=a}},hideDelay:{get:function(){return m},set:function(a){m=a}},contentGenerator:{get:function(){return A},set:function(a){A=a}},valueFormatter:{get:function(){return x},set:function(a){x=a}},headerFormatter:{get:function(){return y},set:function(a){y=a}},keyFormatter:{get:function(){return z},set:function(a){z=a}},headerEnabled:{get:function(){return t},set:function(a){t=a}},_isInteractiveLayer:{get:function(){return u},set:function(a){u=!!a}},position:{get:function(){return p},set:function(a){p.left=void 0!==a.left?a.left:p.left,p.top=void 0!==a.top?a.top:p.top}},offset:{get:function(){return q},set:function(a){q.left=void 0!==a.left?a.left:q.left,q.top=void 0!==a.top?a.top:q.top}},hidden:{get:function(){return l},set:function(a){l!=a&&(l=!!a,d())}},data:{get:function(){return e},set:function(a){a.point&&(a.value=a.point.x,a.series=a.series||{},a.series.value=a.point.y,a.series.color=a.point.color||a.series.color),e=a}},tooltipElem:{get:function(){return o},set:function(){}},id:{get:function(){return v},set:function(){}}}),a.utils.initOptions(d),d}}(),a.utils.windowSize=function(){var a={width:640,height:480};return window.innerWidth&&window.innerHeight?(a.width=window.innerWidth,a.height=window.innerHeight,a):"CSS1Compat"==document.compatMode&&document.documentElement&&document.documentElement.offsetWidth?(a.width=document.documentElement.offsetWidth,a.height=document.documentElement.offsetHeight,a):document.body&&document.body.offsetWidth?(a.width=document.body.offsetWidth,a.height=document.body.offsetHeight,a):a},a.utils.windowResize=function(b){return window.addEventListener?window.addEventListener("resize",b):a.log("ERROR: Failed to bind to window.resize with: ",b),{callback:b,clear:function(){window.removeEventListener("resize",b)}}},a.utils.getColor=function(b){if(void 0===b)return a.utils.defaultColor();if(Array.isArray(b)){var c=d3.scale.ordinal().range(b);return function(a,b){var d=void 0===b?a:b;return a.color||c(d)}}return b},a.utils.defaultColor=function(){return a.utils.getColor(d3.scale.category20().range())},a.utils.customTheme=function(a,b,c){b=b||function(a){return a.key},c=c||d3.scale.category20().range();var d=c.length;return function(e){var f=b(e);return"function"==typeof a[f]?a[f]():void 0!==a[f]?a[f]:(d||(d=c.length),d-=1,c[d])}},a.utils.pjax=function(b,c){var d=function(d){d3.html(d,function(d){var e=d3.select(c).node();e.parentNode.replaceChild(d3.select(d).select(c).node(),e),a.utils.pjax(b,c)})};d3.selectAll(b).on("click",function(){history.pushState(this.href,this.textContent,this.href),d(this.href),d3.event.preventDefault()}),d3.select(window).on("popstate",function(){d3.event.state&&d(d3.event.state)})},a.utils.calcApproxTextWidth=function(a){if("function"==typeof a.style&&"function"==typeof a.text){var b=parseInt(a.style("font-size").replace("px",""),10),c=a.text().length;return c*b*.5}return 0},a.utils.NaNtoZero=function(a){return"number"!=typeof a||isNaN(a)||null===a||1/0===a||a===-1/0?0:a},d3.selection.prototype.watchTransition=function(a){var b=[this].concat([].slice.call(arguments,1));return a.transition.apply(a,b)},a.utils.renderWatch=function(b,c){if(!(this instanceof a.utils.renderWatch))return new a.utils.renderWatch(b,c);var d=void 0!==c?c:250,e=[],f=this;this.models=function(a){return a=[].slice.call(arguments,0),a.forEach(function(a){a.__rendered=!1,function(a){a.dispatch.on("renderEnd",function(){a.__rendered=!0,f.renderEnd("model")})}(a),e.indexOf(a)<0&&e.push(a)}),this},this.reset=function(a){void 0!==a&&(d=a),e=[]},this.transition=function(a,b,c){if(b=arguments.length>1?[].slice.call(arguments,1):[],c=b.length>1?b.pop():void 0!==d?d:250,a.__rendered=!1,e.indexOf(a)<0&&e.push(a),0===c)return a.__rendered=!0,a.delay=function(){return this},a.duration=function(){return this},a;a.__rendered=0===a.length?!0:a.every(function(a){return!a.length})?!0:!1;var g=0;return a.transition().duration(c).each(function(){++g}).each("end",function(){0===--g&&(a.__rendered=!0,f.renderEnd.apply(this,b))})},this.renderEnd=function(){e.every(function(a){return a.__rendered})&&(e.forEach(function(a){a.__rendered=!1}),b.renderEnd.apply(this,arguments))}},a.utils.deepExtend=function(b){var c=arguments.length>1?[].slice.call(arguments,1):[];c.forEach(function(c){for(var d in c){var e=b[d]instanceof Array,f="object"==typeof b[d],g="object"==typeof c[d];f&&!e&&g?a.utils.deepExtend(b[d],c[d]):b[d]=c[d]}})},a.utils.state=function(){if(!(this instanceof a.utils.state))return new a.utils.state;var b={},c=function(){},d=function(){return{}},e=null,f=null;this.dispatch=d3.dispatch("change","set"),this.dispatch.on("set",function(a){c(a,!0)}),this.getter=function(a){return d=a,this},this.setter=function(a,b){return b||(b=function(){}),c=function(c,d){a(c),d&&b()},this},this.init=function(b){e=e||{},a.utils.deepExtend(e,b)};var g=function(){var a=d();if(JSON.stringify(a)===JSON.stringify(b))return!1;for(var c in a)void 0===b[c]&&(b[c]={}),b[c]=a[c],f=!0;return!0};this.update=function(){e&&(c(e,!1),e=null),g.call(this)&&this.dispatch.change(b)}},a.utils.optionsFunc=function(a){return a&&d3.map(a).forEach(function(a,b){"function"==typeof this[a]&&this[a](b)}.bind(this)),this},a.utils.calcTicksX=function(b,c){var d=1,e=0;for(e;ed?f:d}return a.log("Requested number of ticks: ",b),a.log("Calculated max values to be: ",d),b=b>d?b=d-1:b,b=1>b?1:b,b=Math.floor(b),a.log("Calculating tick count as: ",b),b},a.utils.calcTicksY=function(b,c){return a.utils.calcTicksX(b,c)},a.utils.initOption=function(a,b){a._calls&&a._calls[b]?a[b]=a._calls[b]:(a[b]=function(c){return arguments.length?(a._overrides[b]=!0,a._options[b]=c,a):a._options[b]},a["_"+b]=function(c){return arguments.length?(a._overrides[b]||(a._options[b]=c),a):a._options[b]})},a.utils.initOptions=function(b){b._overrides=b._overrides||{};var c=Object.getOwnPropertyNames(b._options||{}),d=Object.getOwnPropertyNames(b._calls||{});c=c.concat(d);for(var e in c)a.utils.initOption(b,c[e])},a.utils.inheritOptionsD3=function(a,b,c){a._d3options=c.concat(a._d3options||[]),c.unshift(b),c.unshift(a),d3.rebind.apply(this,c)},a.utils.arrayUnique=function(a){return a.sort().filter(function(b,c){return!c||b!=a[c-1]})},a.utils.symbolMap=d3.map(),a.utils.symbol=function(){function b(b,e){var f=c.call(this,b,e),g=d.call(this,b,e);return-1!==d3.svg.symbolTypes.indexOf(f)?d3.svg.symbol().type(f).size(g)():a.utils.symbolMap.get(f)(g)}var c,d=64;return b.type=function(a){return arguments.length?(c=d3.functor(a),b):c},b.size=function(a){return arguments.length?(d=d3.functor(a),b):d},b},a.utils.inheritOptions=function(b,c){var d=Object.getOwnPropertyNames(c._options||{}),e=Object.getOwnPropertyNames(c._calls||{}),f=c._inherited||[],g=c._d3options||[],h=d.concat(e).concat(f).concat(g);h.unshift(c),h.unshift(b),d3.rebind.apply(this,h),b._inherited=a.utils.arrayUnique(d.concat(e).concat(f).concat(d).concat(b._inherited||[])),b._d3options=a.utils.arrayUnique(g.concat(b._d3options||[]))},a.utils.initSVG=function(a){a.classed({"nvd3-svg":!0})},a.utils.sanitizeHeight=function(a,b){return a||parseInt(b.style("height"),10)||400},a.utils.sanitizeWidth=function(a,b){return a||parseInt(b.style("width"),10)||960},a.utils.availableHeight=function(b,c,d){return a.utils.sanitizeHeight(b,c)-d.top-d.bottom},a.utils.availableWidth=function(b,c,d){return a.utils.sanitizeWidth(b,c)-d.left-d.right},a.utils.noData=function(b,c){var d=b.options(),e=d.margin(),f=d.noData(),g=null==f?["No Data Available."]:[f],h=a.utils.availableHeight(d.height(),c,e),i=a.utils.availableWidth(d.width(),c,e),j=e.left+i/2,k=e.top+h/2;c.selectAll("g").remove();var l=c.selectAll(".nv-noData").data(g);l.enter().append("text").attr("class","nvd3 nv-noData").attr("dy","-.7em").style("text-anchor","middle"),l.attr("x",j).attr("y",k).text(function(a){return a})},a.models.axis=function(){"use strict";function b(g){return s.reset(),g.each(function(b){var g=d3.select(this);a.utils.initSVG(g);var p=g.selectAll("g.nv-wrap.nv-axis").data([b]),q=p.enter().append("g").attr("class","nvd3 nv-wrap nv-axis"),t=(q.append("g"),p.select("g"));null!==n?c.ticks(n):("top"==c.orient()||"bottom"==c.orient())&&c.ticks(Math.abs(d.range()[1]-d.range()[0])/100),t.watchTransition(s,"axis").call(c),r=r||c.scale();var u=c.tickFormat();null==u&&(u=r.tickFormat());var v=t.selectAll("text.nv-axislabel").data([h||null]);v.exit().remove();var w,x,y;switch(c.orient()){case"top":v.enter().append("text").attr("class","nv-axislabel"),y=d.range().length<2?0:2===d.range().length?d.range()[1]:d.range()[d.range().length-1]+(d.range()[1]-d.range()[0]),v.attr("text-anchor","middle").attr("y",0).attr("x",y/2),i&&(x=p.selectAll("g.nv-axisMaxMin").data(d.domain()),x.enter().append("g").attr("class",function(a,b){return["nv-axisMaxMin","nv-axisMaxMin-x",0==b?"nv-axisMin-x":"nv-axisMax-x"].join(" ")}).append("text"),x.exit().remove(),x.attr("transform",function(b){return"translate("+a.utils.NaNtoZero(d(b))+",0)"}).select("text").attr("dy","-0.5em").attr("y",-c.tickPadding()).attr("text-anchor","middle").text(function(a){var b=u(a);return(""+b).match("NaN")?"":b}),x.watchTransition(s,"min-max top").attr("transform",function(b,c){return"translate("+a.utils.NaNtoZero(d.range()[c])+",0)"}));break;case"bottom":w=o+36;var z=30,A=0,B=t.selectAll("g").select("text"),C="";if(j%360){B.each(function(){var a=this.getBoundingClientRect(),b=a.width;A=a.height,b>z&&(z=b)}),C="rotate("+j+" 0,"+(A/2+c.tickPadding())+")";var D=Math.abs(Math.sin(j*Math.PI/180));w=(D?D*z:z)+30,B.attr("transform",C).style("text-anchor",j%360>0?"start":"end")}v.enter().append("text").attr("class","nv-axislabel"),y=d.range().length<2?0:2===d.range().length?d.range()[1]:d.range()[d.range().length-1]+(d.range()[1]-d.range()[0]),v.attr("text-anchor","middle").attr("y",w).attr("x",y/2),i&&(x=p.selectAll("g.nv-axisMaxMin").data([d.domain()[0],d.domain()[d.domain().length-1]]),x.enter().append("g").attr("class",function(a,b){return["nv-axisMaxMin","nv-axisMaxMin-x",0==b?"nv-axisMin-x":"nv-axisMax-x"].join(" ")}).append("text"),x.exit().remove(),x.attr("transform",function(b){return"translate("+a.utils.NaNtoZero(d(b)+(m?d.rangeBand()/2:0))+",0)"}).select("text").attr("dy",".71em").attr("y",c.tickPadding()).attr("transform",C).style("text-anchor",j?j%360>0?"start":"end":"middle").text(function(a){var b=u(a);return(""+b).match("NaN")?"":b}),x.watchTransition(s,"min-max bottom").attr("transform",function(b){return"translate("+a.utils.NaNtoZero(d(b)+(m?d.rangeBand()/2:0))+",0)"})),l&&B.attr("transform",function(a,b){return"translate(0,"+(b%2==0?"0":"12")+")"});break;case"right":v.enter().append("text").attr("class","nv-axislabel"),v.style("text-anchor",k?"middle":"begin").attr("transform",k?"rotate(90)":"").attr("y",k?-Math.max(e.right,f)+12:-10).attr("x",k?d3.max(d.range())/2:c.tickPadding()),i&&(x=p.selectAll("g.nv-axisMaxMin").data(d.domain()),x.enter().append("g").attr("class",function(a,b){return["nv-axisMaxMin","nv-axisMaxMin-y",0==b?"nv-axisMin-y":"nv-axisMax-y"].join(" ")}).append("text").style("opacity",0),x.exit().remove(),x.attr("transform",function(b){return"translate(0,"+a.utils.NaNtoZero(d(b))+")"}).select("text").attr("dy",".32em").attr("y",0).attr("x",c.tickPadding()).style("text-anchor","start").text(function(a){var b=u(a);return(""+b).match("NaN")?"":b}),x.watchTransition(s,"min-max right").attr("transform",function(b,c){return"translate(0,"+a.utils.NaNtoZero(d.range()[c])+")"}).select("text").style("opacity",1));break;case"left":v.enter().append("text").attr("class","nv-axislabel"),v.style("text-anchor",k?"middle":"end").attr("transform",k?"rotate(-90)":"").attr("y",k?-Math.max(e.left,f)+25-(o||0):-10).attr("x",k?-d3.max(d.range())/2:-c.tickPadding()),i&&(x=p.selectAll("g.nv-axisMaxMin").data(d.domain()),x.enter().append("g").attr("class",function(a,b){return["nv-axisMaxMin","nv-axisMaxMin-y",0==b?"nv-axisMin-y":"nv-axisMax-y"].join(" ")}).append("text").style("opacity",0),x.exit().remove(),x.attr("transform",function(b){return"translate(0,"+a.utils.NaNtoZero(r(b))+")"}).select("text").attr("dy",".32em").attr("y",0).attr("x",-c.tickPadding()).attr("text-anchor","end").text(function(a){var b=u(a);return(""+b).match("NaN")?"":b}),x.watchTransition(s,"min-max right").attr("transform",function(b,c){return"translate(0,"+a.utils.NaNtoZero(d.range()[c])+")"}).select("text").style("opacity",1))}if(v.text(function(a){return a}),!i||"left"!==c.orient()&&"right"!==c.orient()||(t.selectAll("g").each(function(a){d3.select(this).select("text").attr("opacity",1),(d(a)d.range()[0]-10)&&((a>1e-10||-1e-10>a)&&d3.select(this).attr("opacity",0),d3.select(this).select("text").attr("opacity",0))}),d.domain()[0]==d.domain()[1]&&0==d.domain()[0]&&p.selectAll("g.nv-axisMaxMin").style("opacity",function(a,b){return b?0:1})),i&&("top"===c.orient()||"bottom"===c.orient())){var E=[];p.selectAll("g.nv-axisMaxMin").each(function(a,b){try{E.push(b?d(a)-this.getBoundingClientRect().width-4:d(a)+this.getBoundingClientRect().width+4)}catch(c){E.push(b?d(a)-4:d(a)+4)}}),t.selectAll("g").each(function(a){(d(a)E[1])&&(a>1e-10||-1e-10>a?d3.select(this).remove():d3.select(this).select("text").remove())})}t.selectAll(".tick").filter(function(a){return!parseFloat(Math.round(1e5*a)/1e6)&&void 0!==a}).classed("zero",!0),r=d.copy()}),s.renderEnd("axis immediate"),b}var c=d3.svg.axis(),d=d3.scale.linear(),e={top:0,right:0,bottom:0,left:0},f=75,g=60,h=null,i=!0,j=0,k=!0,l=!1,m=!1,n=null,o=0,p=250,q=d3.dispatch("renderEnd");c.scale(d).orient("bottom").tickFormat(function(a){return a});var r,s=a.utils.renderWatch(q,p);return b.axis=c,b.dispatch=q,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{axisLabelDistance:{get:function(){return o},set:function(a){o=a}},staggerLabels:{get:function(){return l},set:function(a){l=a}},rotateLabels:{get:function(){return j},set:function(a){j=a}},rotateYLabel:{get:function(){return k},set:function(a){k=a}},showMaxMin:{get:function(){return i},set:function(a){i=a}},axisLabel:{get:function(){return h},set:function(a){h=a}},height:{get:function(){return g},set:function(a){g=a}},ticks:{get:function(){return n},set:function(a){n=a}},width:{get:function(){return f},set:function(a){f=a}},margin:{get:function(){return e},set:function(a){e.top=void 0!==a.top?a.top:e.top,e.right=void 0!==a.right?a.right:e.right,e.bottom=void 0!==a.bottom?a.bottom:e.bottom,e.left=void 0!==a.left?a.left:e.left}},duration:{get:function(){return p},set:function(a){p=a,s.reset(p)}},scale:{get:function(){return d},set:function(e){d=e,c.scale(d),m="function"==typeof d.rangeBands,a.utils.inheritOptionsD3(b,d,["domain","range","rangeBand","rangeBands"])}}}),a.utils.initOptions(b),a.utils.inheritOptionsD3(b,c,["orient","tickValues","tickSubdivide","tickSize","tickPadding","tickFormat"]),a.utils.inheritOptionsD3(b,d,["domain","range","rangeBand","rangeBands"]),b},a.models.boxPlot=function(){"use strict";function b(l){return v.reset(),l.each(function(b){var l=j-i.left-i.right,p=k-i.top-i.bottom;r=d3.select(this),a.utils.initSVG(r),m.domain(c||b.map(function(a,b){return o(a,b)})).rangeBands(e||[0,l],.1);var w=[];if(!d){var x=d3.min(b.map(function(a){var b=[];return b.push(a.values.Q1),a.values.hasOwnProperty("whisker_low")&&null!==a.values.whisker_low&&b.push(a.values.whisker_low),a.values.hasOwnProperty("outliers")&&null!==a.values.outliers&&(b=b.concat(a.values.outliers)),d3.min(b)})),y=d3.max(b.map(function(a){var b=[];return b.push(a.values.Q3),a.values.hasOwnProperty("whisker_high")&&null!==a.values.whisker_high&&b.push(a.values.whisker_high),a.values.hasOwnProperty("outliers")&&null!==a.values.outliers&&(b=b.concat(a.values.outliers)),d3.max(b)}));w=[x,y]}n.domain(d||w),n.range(f||[p,0]),g=g||m,h=h||n.copy().range([n(0),n(0)]);{var z=r.selectAll("g.nv-wrap").data([b]);z.enter().append("g").attr("class","nvd3 nv-wrap")}z.attr("transform","translate("+i.left+","+i.top+")");var A=z.selectAll(".nv-boxplot").data(function(a){return a}),B=A.enter().append("g").style("stroke-opacity",1e-6).style("fill-opacity",1e-6);A.attr("class","nv-boxplot").attr("transform",function(a,b){return"translate("+(m(o(a,b))+.05*m.rangeBand())+", 0)"}).classed("hover",function(a){return a.hover}),A.watchTransition(v,"nv-boxplot: boxplots").style("stroke-opacity",1).style("fill-opacity",.75).delay(function(a,c){return c*t/b.length}).attr("transform",function(a,b){return"translate("+(m(o(a,b))+.05*m.rangeBand())+", 0)"}),A.exit().remove(),B.each(function(a,b){var c=d3.select(this);["low","high"].forEach(function(d){a.values.hasOwnProperty("whisker_"+d)&&null!==a.values["whisker_"+d]&&(c.append("line").style("stroke",a.color?a.color:q(a,b)).attr("class","nv-boxplot-whisker nv-boxplot-"+d),c.append("line").style("stroke",a.color?a.color:q(a,b)).attr("class","nv-boxplot-tick nv-boxplot-"+d))})});var C=A.selectAll(".nv-boxplot-outlier").data(function(a){return a.values.hasOwnProperty("outliers")&&null!==a.values.outliers?a.values.outliers:[]});C.enter().append("circle").style("fill",function(a,b,c){return q(a,c)}).style("stroke",function(a,b,c){return q(a,c)}).on("mouseover",function(a,b,c){d3.select(this).classed("hover",!0),s.elementMouseover({series:{key:a,color:q(a,c)},e:d3.event})}).on("mouseout",function(a,b,c){d3.select(this).classed("hover",!1),s.elementMouseout({series:{key:a,color:q(a,c)},e:d3.event})}).on("mousemove",function(){s.elementMousemove({e:d3.event})}),C.attr("class","nv-boxplot-outlier"),C.watchTransition(v,"nv-boxplot: nv-boxplot-outlier").attr("cx",.45*m.rangeBand()).attr("cy",function(a){return n(a)}).attr("r","3"),C.exit().remove();var D=function(){return null===u?.9*m.rangeBand():Math.min(75,.9*m.rangeBand())},E=function(){return.45*m.rangeBand()-D()/2},F=function(){return.45*m.rangeBand()+D()/2};["low","high"].forEach(function(a){var b="low"===a?"Q1":"Q3";A.select("line.nv-boxplot-whisker.nv-boxplot-"+a).watchTransition(v,"nv-boxplot: boxplots").attr("x1",.45*m.rangeBand()).attr("y1",function(b){return n(b.values["whisker_"+a])}).attr("x2",.45*m.rangeBand()).attr("y2",function(a){return n(a.values[b])}),A.select("line.nv-boxplot-tick.nv-boxplot-"+a).watchTransition(v,"nv-boxplot: boxplots").attr("x1",E).attr("y1",function(b){return n(b.values["whisker_"+a])}).attr("x2",F).attr("y2",function(b){return n(b.values["whisker_"+a])})}),["low","high"].forEach(function(a){B.selectAll(".nv-boxplot-"+a).on("mouseover",function(b,c,d){d3.select(this).classed("hover",!0),s.elementMouseover({series:{key:b.values["whisker_"+a],color:q(b,d)},e:d3.event})}).on("mouseout",function(b,c,d){d3.select(this).classed("hover",!1),s.elementMouseout({series:{key:b.values["whisker_"+a],color:q(b,d)},e:d3.event})}).on("mousemove",function(){s.elementMousemove({e:d3.event})})}),B.append("rect").attr("class","nv-boxplot-box").on("mouseover",function(a,b){d3.select(this).classed("hover",!0),s.elementMouseover({key:a.label,value:a.label,series:[{key:"Q3",value:a.values.Q3,color:a.color||q(a,b)},{key:"Q2",value:a.values.Q2,color:a.color||q(a,b)},{key:"Q1",value:a.values.Q1,color:a.color||q(a,b)}],data:a,index:b,e:d3.event})}).on("mouseout",function(a,b){d3.select(this).classed("hover",!1),s.elementMouseout({key:a.label,value:a.label,series:[{key:"Q3",value:a.values.Q3,color:a.color||q(a,b)},{key:"Q2",value:a.values.Q2,color:a.color||q(a,b)},{key:"Q1",value:a.values.Q1,color:a.color||q(a,b)}],data:a,index:b,e:d3.event})}).on("mousemove",function(){s.elementMousemove({e:d3.event})}),A.select("rect.nv-boxplot-box").watchTransition(v,"nv-boxplot: boxes").attr("y",function(a){return n(a.values.Q3)}).attr("width",D).attr("x",E).attr("height",function(a){return Math.abs(n(a.values.Q3)-n(a.values.Q1))||1}).style("fill",function(a,b){return a.color||q(a,b)}).style("stroke",function(a,b){return a.color||q(a,b)}),B.append("line").attr("class","nv-boxplot-median"),A.select("line.nv-boxplot-median").watchTransition(v,"nv-boxplot: boxplots line").attr("x1",E).attr("y1",function(a){return n(a.values.Q2)}).attr("x2",F).attr("y2",function(a){return n(a.values.Q2)}),g=m.copy(),h=n.copy()}),v.renderEnd("nv-boxplot immediate"),b}var c,d,e,f,g,h,i={top:0,right:0,bottom:0,left:0},j=960,k=500,l=Math.floor(1e4*Math.random()),m=d3.scale.ordinal(),n=d3.scale.linear(),o=function(a){return a.x},p=function(a){return a.y},q=a.utils.defaultColor(),r=null,s=d3.dispatch("elementMouseover","elementMouseout","elementMousemove","renderEnd"),t=250,u=null,v=a.utils.renderWatch(s,t);return b.dispatch=s,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return j},set:function(a){j=a}},height:{get:function(){return k},set:function(a){k=a}},maxBoxWidth:{get:function(){return u},set:function(a){u=a}},x:{get:function(){return o},set:function(a){o=a}},y:{get:function(){return p},set:function(a){p=a}},xScale:{get:function(){return m},set:function(a){m=a}},yScale:{get:function(){return n},set:function(a){n=a}},xDomain:{get:function(){return c},set:function(a){c=a}},yDomain:{get:function(){return d},set:function(a){d=a}},xRange:{get:function(){return e},set:function(a){e=a}},yRange:{get:function(){return f},set:function(a){f=a}},id:{get:function(){return l},set:function(a){l=a}},margin:{get:function(){return i},set:function(a){i.top=void 0!==a.top?a.top:i.top,i.right=void 0!==a.right?a.right:i.right,i.bottom=void 0!==a.bottom?a.bottom:i.bottom,i.left=void 0!==a.left?a.left:i.left}},color:{get:function(){return q},set:function(b){q=a.utils.getColor(b)}},duration:{get:function(){return t},set:function(a){t=a,v.reset(t)}}}),a.utils.initOptions(b),b},a.models.boxPlotChart=function(){"use strict";function b(k){return t.reset(),t.models(e),l&&t.models(f),m&&t.models(g),k.each(function(k){var p=d3.select(this);a.utils.initSVG(p);var t=(i||parseInt(p.style("width"))||960)-h.left-h.right,u=(j||parseInt(p.style("height"))||400)-h.top-h.bottom;if(b.update=function(){r.beforeUpdate(),p.transition().duration(s).call(b)},b.container=this,!(k&&k.length&&k.filter(function(a){return a.values.hasOwnProperty("Q1")&&a.values.hasOwnProperty("Q2")&&a.values.hasOwnProperty("Q3")}).length)){var v=p.selectAll(".nv-noData").data([q]);return v.enter().append("text").attr("class","nvd3 nv-noData").attr("dy","-.7em").style("text-anchor","middle"),v.attr("x",h.left+t/2).attr("y",h.top+u/2).text(function(a){return a}),b}p.selectAll(".nv-noData").remove(),c=e.xScale(),d=e.yScale().clamp(!0);var w=p.selectAll("g.nv-wrap.nv-boxPlotWithAxes").data([k]),x=w.enter().append("g").attr("class","nvd3 nv-wrap nv-boxPlotWithAxes").append("g"),y=x.append("defs"),z=w.select("g"); -x.append("g").attr("class","nv-x nv-axis"),x.append("g").attr("class","nv-y nv-axis").append("g").attr("class","nv-zeroLine").append("line"),x.append("g").attr("class","nv-barsWrap"),z.attr("transform","translate("+h.left+","+h.top+")"),n&&z.select(".nv-y.nv-axis").attr("transform","translate("+t+",0)"),e.width(t).height(u);var A=z.select(".nv-barsWrap").datum(k.filter(function(a){return!a.disabled}));if(A.transition().call(e),y.append("clipPath").attr("id","nv-x-label-clip-"+e.id()).append("rect"),z.select("#nv-x-label-clip-"+e.id()+" rect").attr("width",c.rangeBand()*(o?2:1)).attr("height",16).attr("x",-c.rangeBand()/(o?1:2)),l){f.scale(c).ticks(a.utils.calcTicksX(t/100,k)).tickSize(-u,0),z.select(".nv-x.nv-axis").attr("transform","translate(0,"+d.range()[0]+")"),z.select(".nv-x.nv-axis").call(f);var B=z.select(".nv-x.nv-axis").selectAll("g");o&&B.selectAll("text").attr("transform",function(a,b,c){return"translate(0,"+(c%2==0?"5":"17")+")"})}m&&(g.scale(d).ticks(Math.floor(u/36)).tickSize(-t,0),z.select(".nv-y.nv-axis").call(g)),z.select(".nv-zeroLine line").attr("x1",0).attr("x2",t).attr("y1",d(0)).attr("y2",d(0))}),t.renderEnd("nv-boxplot chart immediate"),b}var c,d,e=a.models.boxPlot(),f=a.models.axis(),g=a.models.axis(),h={top:15,right:10,bottom:50,left:60},i=null,j=null,k=a.utils.getColor(),l=!0,m=!0,n=!1,o=!1,p=a.models.tooltip(),q="No Data Available.",r=d3.dispatch("tooltipShow","tooltipHide","beforeUpdate","renderEnd"),s=250;f.orient("bottom").showMaxMin(!1).tickFormat(function(a){return a}),g.orient(n?"right":"left").tickFormat(d3.format(",.1f")),p.duration(0);var t=a.utils.renderWatch(r,s);return e.dispatch.on("elementMouseover.tooltip",function(a){p.data(a).hidden(!1)}),e.dispatch.on("elementMouseout.tooltip",function(a){p.data(a).hidden(!0)}),e.dispatch.on("elementMousemove.tooltip",function(){p.position({top:d3.event.pageY,left:d3.event.pageX})()}),b.dispatch=r,b.boxplot=e,b.xAxis=f,b.yAxis=g,b.tooltip=p,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return i},set:function(a){i=a}},height:{get:function(){return j},set:function(a){j=a}},staggerLabels:{get:function(){return o},set:function(a){o=a}},showXAxis:{get:function(){return l},set:function(a){l=a}},showYAxis:{get:function(){return m},set:function(a){m=a}},tooltips:{get:function(){return tooltips},set:function(a){tooltips=a}},tooltipContent:{get:function(){return p},set:function(a){p=a}},noData:{get:function(){return q},set:function(a){q=a}},margin:{get:function(){return h},set:function(a){h.top=void 0!==a.top?a.top:h.top,h.right=void 0!==a.right?a.right:h.right,h.bottom=void 0!==a.bottom?a.bottom:h.bottom,h.left=void 0!==a.left?a.left:h.left}},duration:{get:function(){return s},set:function(a){s=a,t.reset(s),e.duration(s),f.duration(s),g.duration(s)}},color:{get:function(){return k},set:function(b){k=a.utils.getColor(b),e.color(k)}},rightAlignYAxis:{get:function(){return n},set:function(a){n=a,g.orient(a?"right":"left")}}}),a.utils.inheritOptions(b,e),a.utils.initOptions(b),b},a.models.bullet=function(){"use strict";function b(d){return d.each(function(b,d){var p=m-c.left-c.right,s=n-c.top-c.bottom;o=d3.select(this),a.utils.initSVG(o);{var t=f.call(this,b,d).slice().sort(d3.descending),u=g.call(this,b,d).slice().sort(d3.descending),v=h.call(this,b,d).slice().sort(d3.descending),w=i.call(this,b,d).slice(),x=j.call(this,b,d).slice(),y=k.call(this,b,d).slice(),z=d3.scale.linear().domain(d3.extent(d3.merge([l,t]))).range(e?[p,0]:[0,p]);this.__chart__||d3.scale.linear().domain([0,1/0]).range(z.range())}this.__chart__=z;var A=d3.min(t),B=d3.max(t),C=t[1],D=o.selectAll("g.nv-wrap.nv-bullet").data([b]),E=D.enter().append("g").attr("class","nvd3 nv-wrap nv-bullet"),F=E.append("g"),G=D.select("g");F.append("rect").attr("class","nv-range nv-rangeMax"),F.append("rect").attr("class","nv-range nv-rangeAvg"),F.append("rect").attr("class","nv-range nv-rangeMin"),F.append("rect").attr("class","nv-measure"),D.attr("transform","translate("+c.left+","+c.top+")");var H=function(a){return Math.abs(z(a)-z(0))},I=function(a){return z(0>a?a:0)};G.select("rect.nv-rangeMax").attr("height",s).attr("width",H(B>0?B:A)).attr("x",I(B>0?B:A)).datum(B>0?B:A),G.select("rect.nv-rangeAvg").attr("height",s).attr("width",H(C)).attr("x",I(C)).datum(C),G.select("rect.nv-rangeMin").attr("height",s).attr("width",H(B)).attr("x",I(B)).attr("width",H(B>0?A:B)).attr("x",I(B>0?A:B)).datum(B>0?A:B),G.select("rect.nv-measure").style("fill",q).attr("height",s/3).attr("y",s/3).attr("width",0>v?z(0)-z(v[0]):z(v[0])-z(0)).attr("x",I(v)).on("mouseover",function(){r.elementMouseover({value:v[0],label:y[0]||"Current",color:d3.select(this).style("fill")})}).on("mousemove",function(){r.elementMousemove({value:v[0],label:y[0]||"Current",color:d3.select(this).style("fill")})}).on("mouseout",function(){r.elementMouseout({value:v[0],label:y[0]||"Current",color:d3.select(this).style("fill")})});var J=s/6,K=u.map(function(a,b){return{value:a,label:x[b]}});F.selectAll("path.nv-markerTriangle").data(K).enter().append("path").attr("class","nv-markerTriangle").attr("transform",function(a){return"translate("+z(a.value)+","+s/2+")"}).attr("d","M0,"+J+"L"+J+","+-J+" "+-J+","+-J+"Z").on("mouseover",function(a){r.elementMouseover({value:a.value,label:a.label||"Previous",color:d3.select(this).style("fill"),pos:[z(a.value),s/2]})}).on("mousemove",function(a){r.elementMousemove({value:a.value,label:a.label||"Previous",color:d3.select(this).style("fill")})}).on("mouseout",function(a){r.elementMouseout({value:a.value,label:a.label||"Previous",color:d3.select(this).style("fill")})}),D.selectAll(".nv-range").on("mouseover",function(a,b){var c=w[b]||(b?1==b?"Mean":"Minimum":"Maximum");r.elementMouseover({value:a,label:c,color:d3.select(this).style("fill")})}).on("mousemove",function(){r.elementMousemove({value:v[0],label:y[0]||"Previous",color:d3.select(this).style("fill")})}).on("mouseout",function(a,b){var c=w[b]||(b?1==b?"Mean":"Minimum":"Maximum");r.elementMouseout({value:a,label:c,color:d3.select(this).style("fill")})})}),b}var c={top:0,right:0,bottom:0,left:0},d="left",e=!1,f=function(a){return a.ranges},g=function(a){return a.markers?a.markers:[0]},h=function(a){return a.measures},i=function(a){return a.rangeLabels?a.rangeLabels:[]},j=function(a){return a.markerLabels?a.markerLabels:[]},k=function(a){return a.measureLabels?a.measureLabels:[]},l=[0],m=380,n=30,o=null,p=null,q=a.utils.getColor(["#1f77b4"]),r=d3.dispatch("elementMouseover","elementMouseout","elementMousemove");return b.dispatch=r,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{ranges:{get:function(){return f},set:function(a){f=a}},markers:{get:function(){return g},set:function(a){g=a}},measures:{get:function(){return h},set:function(a){h=a}},forceX:{get:function(){return l},set:function(a){l=a}},width:{get:function(){return m},set:function(a){m=a}},height:{get:function(){return n},set:function(a){n=a}},tickFormat:{get:function(){return p},set:function(a){p=a}},margin:{get:function(){return c},set:function(a){c.top=void 0!==a.top?a.top:c.top,c.right=void 0!==a.right?a.right:c.right,c.bottom=void 0!==a.bottom?a.bottom:c.bottom,c.left=void 0!==a.left?a.left:c.left}},orient:{get:function(){return d},set:function(a){d=a,e="right"==d||"bottom"==d}},color:{get:function(){return q},set:function(b){q=a.utils.getColor(b)}}}),a.utils.initOptions(b),b},a.models.bulletChart=function(){"use strict";function b(d){return d.each(function(e,o){var p=d3.select(this);a.utils.initSVG(p);var q=a.utils.availableWidth(k,p,g),r=l-g.top-g.bottom;if(b.update=function(){b(d)},b.container=this,!e||!h.call(this,e,o))return a.utils.noData(b,p),b;p.selectAll(".nv-noData").remove();var s=h.call(this,e,o).slice().sort(d3.descending),t=i.call(this,e,o).slice().sort(d3.descending),u=j.call(this,e,o).slice().sort(d3.descending),v=p.selectAll("g.nv-wrap.nv-bulletChart").data([e]),w=v.enter().append("g").attr("class","nvd3 nv-wrap nv-bulletChart"),x=w.append("g"),y=v.select("g");x.append("g").attr("class","nv-bulletWrap"),x.append("g").attr("class","nv-titles"),v.attr("transform","translate("+g.left+","+g.top+")");var z=d3.scale.linear().domain([0,Math.max(s[0],t[0],u[0])]).range(f?[q,0]:[0,q]),A=this.__chart__||d3.scale.linear().domain([0,1/0]).range(z.range());this.__chart__=z;var B=x.select(".nv-titles").append("g").attr("text-anchor","end").attr("transform","translate(-6,"+(l-g.top-g.bottom)/2+")");B.append("text").attr("class","nv-title").text(function(a){return a.title}),B.append("text").attr("class","nv-subtitle").attr("dy","1em").text(function(a){return a.subtitle}),c.width(q).height(r);var C=y.select(".nv-bulletWrap");d3.transition(C).call(c);var D=m||z.tickFormat(q/100),E=y.selectAll("g.nv-tick").data(z.ticks(n?n:q/50),function(a){return this.textContent||D(a)}),F=E.enter().append("g").attr("class","nv-tick").attr("transform",function(a){return"translate("+A(a)+",0)"}).style("opacity",1e-6);F.append("line").attr("y1",r).attr("y2",7*r/6),F.append("text").attr("text-anchor","middle").attr("dy","1em").attr("y",7*r/6).text(D);var G=d3.transition(E).attr("transform",function(a){return"translate("+z(a)+",0)"}).style("opacity",1);G.select("line").attr("y1",r).attr("y2",7*r/6),G.select("text").attr("y",7*r/6),d3.transition(E.exit()).attr("transform",function(a){return"translate("+z(a)+",0)"}).style("opacity",1e-6).remove()}),d3.timer.flush(),b}var c=a.models.bullet(),d=a.models.tooltip(),e="left",f=!1,g={top:5,right:40,bottom:20,left:120},h=function(a){return a.ranges},i=function(a){return a.markers?a.markers:[0]},j=function(a){return a.measures},k=null,l=55,m=null,n=null,o=null,p=d3.dispatch("tooltipShow","tooltipHide");return d.duration(0).headerEnabled(!1),c.dispatch.on("elementMouseover.tooltip",function(a){a.series={key:a.label,value:a.value,color:a.color},d.data(a).hidden(!1)}),c.dispatch.on("elementMouseout.tooltip",function(){d.hidden(!0)}),c.dispatch.on("elementMousemove.tooltip",function(){d.position({top:d3.event.pageY,left:d3.event.pageX})()}),b.bullet=c,b.dispatch=p,b.tooltip=d,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{ranges:{get:function(){return h},set:function(a){h=a}},markers:{get:function(){return i},set:function(a){i=a}},measures:{get:function(){return j},set:function(a){j=a}},width:{get:function(){return k},set:function(a){k=a}},height:{get:function(){return l},set:function(a){l=a}},tickFormat:{get:function(){return m},set:function(a){m=a}},ticks:{get:function(){return n},set:function(a){n=a}},noData:{get:function(){return o},set:function(a){o=a}},tooltips:{get:function(){return d.enabled()},set:function(b){a.deprecated("tooltips","use chart.tooltip.enabled() instead"),d.enabled(!!b)}},tooltipContent:{get:function(){return d.contentGenerator()},set:function(b){a.deprecated("tooltipContent","use chart.tooltip.contentGenerator() instead"),d.contentGenerator(b)}},margin:{get:function(){return g},set:function(a){g.top=void 0!==a.top?a.top:g.top,g.right=void 0!==a.right?a.right:g.right,g.bottom=void 0!==a.bottom?a.bottom:g.bottom,g.left=void 0!==a.left?a.left:g.left}},orient:{get:function(){return e},set:function(a){e=a,f="right"==e||"bottom"==e}}}),a.utils.inheritOptions(b,c),a.utils.initOptions(b),b},a.models.candlestickBar=function(){"use strict";function b(x){return x.each(function(b){c=d3.select(this);var x=a.utils.availableWidth(i,c,h),y=a.utils.availableHeight(j,c,h);a.utils.initSVG(c);var A=x/b[0].values.length*.45;l.domain(d||d3.extent(b[0].values.map(n).concat(t))),l.range(v?f||[.5*x/b[0].values.length,x*(b[0].values.length-.5)/b[0].values.length]:f||[5+A/2,x-A/2-5]),m.domain(e||[d3.min(b[0].values.map(s).concat(u)),d3.max(b[0].values.map(r).concat(u))]).range(g||[y,0]),l.domain()[0]===l.domain()[1]&&l.domain(l.domain()[0]?[l.domain()[0]-.01*l.domain()[0],l.domain()[1]+.01*l.domain()[1]]:[-1,1]),m.domain()[0]===m.domain()[1]&&m.domain(m.domain()[0]?[m.domain()[0]+.01*m.domain()[0],m.domain()[1]-.01*m.domain()[1]]:[-1,1]);var B=d3.select(this).selectAll("g.nv-wrap.nv-candlestickBar").data([b[0].values]),C=B.enter().append("g").attr("class","nvd3 nv-wrap nv-candlestickBar"),D=C.append("defs"),E=C.append("g"),F=B.select("g");E.append("g").attr("class","nv-ticks"),B.attr("transform","translate("+h.left+","+h.top+")"),c.on("click",function(a,b){z.chartClick({data:a,index:b,pos:d3.event,id:k})}),D.append("clipPath").attr("id","nv-chart-clip-path-"+k).append("rect"),B.select("#nv-chart-clip-path-"+k+" rect").attr("width",x).attr("height",y),F.attr("clip-path",w?"url(#nv-chart-clip-path-"+k+")":"");var G=B.select(".nv-ticks").selectAll(".nv-tick").data(function(a){return a});G.exit().remove();{var H=G.enter().append("g").attr("class",function(a,b,c){return(p(a,b)>q(a,b)?"nv-tick negative":"nv-tick positive")+" nv-tick-"+c+"-"+b});H.append("line").attr("class","nv-candlestick-lines").attr("transform",function(a,b){return"translate("+l(n(a,b))+",0)"}).attr("x1",0).attr("y1",function(a,b){return m(r(a,b))}).attr("x2",0).attr("y2",function(a,b){return m(s(a,b))}),H.append("rect").attr("class","nv-candlestick-rects nv-bars").attr("transform",function(a,b){return"translate("+(l(n(a,b))-A/2)+","+(m(o(a,b))-(p(a,b)>q(a,b)?m(q(a,b))-m(p(a,b)):0))+")"}).attr("x",0).attr("y",0).attr("width",A).attr("height",function(a,b){var c=p(a,b),d=q(a,b);return c>d?m(d)-m(c):m(c)-m(d)})}c.selectAll(".nv-candlestick-lines").transition().attr("transform",function(a,b){return"translate("+l(n(a,b))+",0)"}).attr("x1",0).attr("y1",function(a,b){return m(r(a,b))}).attr("x2",0).attr("y2",function(a,b){return m(s(a,b))}),c.selectAll(".nv-candlestick-rects").transition().attr("transform",function(a,b){return"translate("+(l(n(a,b))-A/2)+","+(m(o(a,b))-(p(a,b)>q(a,b)?m(q(a,b))-m(p(a,b)):0))+")"}).attr("x",0).attr("y",0).attr("width",A).attr("height",function(a,b){var c=p(a,b),d=q(a,b);return c>d?m(d)-m(c):m(c)-m(d)})}),b}var c,d,e,f,g,h={top:0,right:0,bottom:0,left:0},i=null,j=null,k=Math.floor(1e4*Math.random()),l=d3.scale.linear(),m=d3.scale.linear(),n=function(a){return a.x},o=function(a){return a.y},p=function(a){return a.open},q=function(a){return a.close},r=function(a){return a.high},s=function(a){return a.low},t=[],u=[],v=!1,w=!0,x=a.utils.defaultColor(),y=!1,z=d3.dispatch("tooltipShow","tooltipHide","stateChange","changeState","renderEnd","chartClick","elementClick","elementDblClick","elementMouseover","elementMouseout","elementMousemove");return b.highlightPoint=function(a,d){b.clearHighlights(),c.select(".nv-candlestickBar .nv-tick-0-"+a).classed("hover",d)},b.clearHighlights=function(){c.select(".nv-candlestickBar .nv-tick.hover").classed("hover",!1)},b.dispatch=z,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return i},set:function(a){i=a}},height:{get:function(){return j},set:function(a){j=a}},xScale:{get:function(){return l},set:function(a){l=a}},yScale:{get:function(){return m},set:function(a){m=a}},xDomain:{get:function(){return d},set:function(a){d=a}},yDomain:{get:function(){return e},set:function(a){e=a}},xRange:{get:function(){return f},set:function(a){f=a}},yRange:{get:function(){return g},set:function(a){g=a}},forceX:{get:function(){return t},set:function(a){t=a}},forceY:{get:function(){return u},set:function(a){u=a}},padData:{get:function(){return v},set:function(a){v=a}},clipEdge:{get:function(){return w},set:function(a){w=a}},id:{get:function(){return k},set:function(a){k=a}},interactive:{get:function(){return y},set:function(a){y=a}},x:{get:function(){return n},set:function(a){n=a}},y:{get:function(){return o},set:function(a){o=a}},open:{get:function(){return p()},set:function(a){p=a}},close:{get:function(){return q()},set:function(a){q=a}},high:{get:function(){return r},set:function(a){r=a}},low:{get:function(){return s},set:function(a){s=a}},margin:{get:function(){return h},set:function(a){h.top=void 0!=a.top?a.top:h.top,h.right=void 0!=a.right?a.right:h.right,h.bottom=void 0!=a.bottom?a.bottom:h.bottom,h.left=void 0!=a.left?a.left:h.left}},color:{get:function(){return x},set:function(b){x=a.utils.getColor(b)}}}),a.utils.initOptions(b),b},a.models.cumulativeLineChart=function(){"use strict";function b(l){return H.reset(),H.models(f),r&&H.models(g),s&&H.models(h),l.each(function(l){function A(){d3.select(b.container).style("cursor","ew-resize")}function E(){G.x=d3.event.x,G.i=Math.round(F.invert(G.x)),K()}function H(){d3.select(b.container).style("cursor","auto"),y.index=G.i,C.stateChange(y)}function K(){bb.data([G]);var a=b.duration();b.duration(0),b.update(),b.duration(a)}var L=d3.select(this);a.utils.initSVG(L),L.classed("nv-chart-"+x,!0);var M=this,N=a.utils.availableWidth(o,L,m),O=a.utils.availableHeight(p,L,m);if(b.update=function(){0===D?L.call(b):L.transition().duration(D).call(b)},b.container=this,y.setter(J(l),b.update).getter(I(l)).update(),y.disabled=l.map(function(a){return!!a.disabled}),!z){var P;z={};for(P in y)z[P]=y[P]instanceof Array?y[P].slice(0):y[P]}var Q=d3.behavior.drag().on("dragstart",A).on("drag",E).on("dragend",H);if(!(l&&l.length&&l.filter(function(a){return a.values.length}).length))return a.utils.noData(b,L),b;if(L.selectAll(".nv-noData").remove(),d=f.xScale(),e=f.yScale(),w)f.yDomain(null);else{var R=l.filter(function(a){return!a.disabled}).map(function(a){var b=d3.extent(a.values,f.y());return b[0]<-.95&&(b[0]=-.95),[(b[0]-b[1])/(1+b[1]),(b[1]-b[0])/(1+b[0])]}),S=[d3.min(R,function(a){return a[0]}),d3.max(R,function(a){return a[1]})];f.yDomain(S)}F.domain([0,l[0].values.length-1]).range([0,N]).clamp(!0);var l=c(G.i,l),T=v?"none":"all",U=L.selectAll("g.nv-wrap.nv-cumulativeLine").data([l]),V=U.enter().append("g").attr("class","nvd3 nv-wrap nv-cumulativeLine").append("g"),W=U.select("g");if(V.append("g").attr("class","nv-interactive"),V.append("g").attr("class","nv-x nv-axis").style("pointer-events","none"),V.append("g").attr("class","nv-y nv-axis"),V.append("g").attr("class","nv-background"),V.append("g").attr("class","nv-linesWrap").style("pointer-events",T),V.append("g").attr("class","nv-avgLinesWrap").style("pointer-events","none"),V.append("g").attr("class","nv-legendWrap"),V.append("g").attr("class","nv-controlsWrap"),q&&(i.width(N),W.select(".nv-legendWrap").datum(l).call(i),m.top!=i.height()&&(m.top=i.height(),O=a.utils.availableHeight(p,L,m)),W.select(".nv-legendWrap").attr("transform","translate(0,"+-m.top+")")),u){var X=[{key:"Re-scale y-axis",disabled:!w}];j.width(140).color(["#444","#444","#444"]).rightAlign(!1).margin({top:5,right:0,bottom:5,left:20}),W.select(".nv-controlsWrap").datum(X).attr("transform","translate(0,"+-m.top+")").call(j)}U.attr("transform","translate("+m.left+","+m.top+")"),t&&W.select(".nv-y.nv-axis").attr("transform","translate("+N+",0)");var Y=l.filter(function(a){return a.tempDisabled});U.select(".tempDisabled").remove(),Y.length&&U.append("text").attr("class","tempDisabled").attr("x",N/2).attr("y","-.71em").style("text-anchor","end").text(Y.map(function(a){return a.key}).join(", ")+" values cannot be calculated for this time period."),v&&(k.width(N).height(O).margin({left:m.left,top:m.top}).svgContainer(L).xScale(d),U.select(".nv-interactive").call(k)),V.select(".nv-background").append("rect"),W.select(".nv-background rect").attr("width",N).attr("height",O),f.y(function(a){return a.display.y}).width(N).height(O).color(l.map(function(a,b){return a.color||n(a,b)}).filter(function(a,b){return!l[b].disabled&&!l[b].tempDisabled}));var Z=W.select(".nv-linesWrap").datum(l.filter(function(a){return!a.disabled&&!a.tempDisabled}));Z.call(f),l.forEach(function(a,b){a.seriesIndex=b});var $=l.filter(function(a){return!a.disabled&&!!B(a)}),_=W.select(".nv-avgLinesWrap").selectAll("line").data($,function(a){return a.key}),ab=function(a){var b=e(B(a));return 0>b?0:b>O?O:b};_.enter().append("line").style("stroke-width",2).style("stroke-dasharray","10,10").style("stroke",function(a){return f.color()(a,a.seriesIndex)}).attr("x1",0).attr("x2",N).attr("y1",ab).attr("y2",ab),_.style("stroke-opacity",function(a){var b=e(B(a));return 0>b||b>O?0:1}).attr("x1",0).attr("x2",N).attr("y1",ab).attr("y2",ab),_.exit().remove();var bb=Z.selectAll(".nv-indexLine").data([G]);bb.enter().append("rect").attr("class","nv-indexLine").attr("width",3).attr("x",-2).attr("fill","red").attr("fill-opacity",.5).style("pointer-events","all").call(Q),bb.attr("transform",function(a){return"translate("+F(a.i)+",0)"}).attr("height",O),r&&(g.scale(d)._ticks(a.utils.calcTicksX(N/70,l)).tickSize(-O,0),W.select(".nv-x.nv-axis").attr("transform","translate(0,"+e.range()[0]+")"),W.select(".nv-x.nv-axis").call(g)),s&&(h.scale(e)._ticks(a.utils.calcTicksY(O/36,l)).tickSize(-N,0),W.select(".nv-y.nv-axis").call(h)),W.select(".nv-background rect").on("click",function(){G.x=d3.mouse(this)[0],G.i=Math.round(F.invert(G.x)),y.index=G.i,C.stateChange(y),K()}),f.dispatch.on("elementClick",function(a){G.i=a.pointIndex,G.x=F(G.i),y.index=G.i,C.stateChange(y),K()}),j.dispatch.on("legendClick",function(a){a.disabled=!a.disabled,w=!a.disabled,y.rescaleY=w,C.stateChange(y),b.update()}),i.dispatch.on("stateChange",function(a){for(var c in a)y[c]=a[c];C.stateChange(y),b.update()}),k.dispatch.on("elementMousemove",function(c){f.clearHighlights();var d,e,i,j=[];if(l.filter(function(a,b){return a.seriesIndex=b,!a.disabled}).forEach(function(g,h){e=a.interactiveBisect(g.values,c.pointXValue,b.x()),f.highlightPoint(h,e,!0);var k=g.values[e];"undefined"!=typeof k&&("undefined"==typeof d&&(d=k),"undefined"==typeof i&&(i=b.xScale()(b.x()(k,e))),j.push({key:g.key,value:b.y()(k,e),color:n(g,g.seriesIndex)}))}),j.length>2){var o=b.yScale().invert(c.mouseY),p=Math.abs(b.yScale().domain()[0]-b.yScale().domain()[1]),q=.03*p,r=a.nearestValueIndex(j.map(function(a){return a.value}),o,q);null!==r&&(j[r].highlight=!0)}var s=g.tickFormat()(b.x()(d,e),e);k.tooltip.position({left:i+m.left,top:c.mouseY+m.top}).chartContainer(M.parentNode).valueFormatter(function(a){return h.tickFormat()(a)}).data({value:s,series:j})(),k.renderGuideLine(i)}),k.dispatch.on("elementMouseout",function(){f.clearHighlights()}),C.on("changeState",function(a){"undefined"!=typeof a.disabled&&(l.forEach(function(b,c){b.disabled=a.disabled[c]}),y.disabled=a.disabled),"undefined"!=typeof a.index&&(G.i=a.index,G.x=F(G.i),y.index=a.index,bb.data([G])),"undefined"!=typeof a.rescaleY&&(w=a.rescaleY),b.update()})}),H.renderEnd("cumulativeLineChart immediate"),b}function c(a,b){return K||(K=f.y()),b.map(function(b){if(!b.values)return b;var c=b.values[a];if(null==c)return b;var d=K(c,a);return-.95>d&&!E?(b.tempDisabled=!0,b):(b.tempDisabled=!1,b.values=b.values.map(function(a,b){return a.display={y:(K(a,b)-d)/(1+d)},a}),b)})}var d,e,f=a.models.line(),g=a.models.axis(),h=a.models.axis(),i=a.models.legend(),j=a.models.legend(),k=a.interactiveGuideline(),l=a.models.tooltip(),m={top:30,right:30,bottom:50,left:60},n=a.utils.defaultColor(),o=null,p=null,q=!0,r=!0,s=!0,t=!1,u=!0,v=!1,w=!0,x=f.id(),y=a.utils.state(),z=null,A=null,B=function(a){return a.average},C=d3.dispatch("stateChange","changeState","renderEnd"),D=250,E=!1;y.index=0,y.rescaleY=w,g.orient("bottom").tickPadding(7),h.orient(t?"right":"left"),l.valueFormatter(function(a,b){return h.tickFormat()(a,b)}).headerFormatter(function(a,b){return g.tickFormat()(a,b)}),j.updateState(!1);var F=d3.scale.linear(),G={i:0,x:0},H=a.utils.renderWatch(C,D),I=function(a){return function(){return{active:a.map(function(a){return!a.disabled}),index:G.i,rescaleY:w}}},J=function(a){return function(b){void 0!==b.index&&(G.i=b.index),void 0!==b.rescaleY&&(w=b.rescaleY),void 0!==b.active&&a.forEach(function(a,c){a.disabled=!b.active[c]})}};f.dispatch.on("elementMouseover.tooltip",function(a){var c={x:b.x()(a.point),y:b.y()(a.point),color:a.point.color};a.point=c,l.data(a).position(a.pos).hidden(!1)}),f.dispatch.on("elementMouseout.tooltip",function(){l.hidden(!0)});var K=null;return b.dispatch=C,b.lines=f,b.legend=i,b.controls=j,b.xAxis=g,b.yAxis=h,b.interactiveLayer=k,b.state=y,b.tooltip=l,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return o},set:function(a){o=a}},height:{get:function(){return p},set:function(a){p=a}},rescaleY:{get:function(){return w},set:function(a){w=a}},showControls:{get:function(){return u},set:function(a){u=a}},showLegend:{get:function(){return q},set:function(a){q=a}},average:{get:function(){return B},set:function(a){B=a}},defaultState:{get:function(){return z},set:function(a){z=a}},noData:{get:function(){return A},set:function(a){A=a}},showXAxis:{get:function(){return r},set:function(a){r=a}},showYAxis:{get:function(){return s},set:function(a){s=a}},noErrorCheck:{get:function(){return E},set:function(a){E=a}},tooltips:{get:function(){return l.enabled()},set:function(b){a.deprecated("tooltips","use chart.tooltip.enabled() instead"),l.enabled(!!b)}},tooltipContent:{get:function(){return l.contentGenerator()},set:function(b){a.deprecated("tooltipContent","use chart.tooltip.contentGenerator() instead"),l.contentGenerator(b)}},margin:{get:function(){return m},set:function(a){m.top=void 0!==a.top?a.top:m.top,m.right=void 0!==a.right?a.right:m.right,m.bottom=void 0!==a.bottom?a.bottom:m.bottom,m.left=void 0!==a.left?a.left:m.left}},color:{get:function(){return n},set:function(b){n=a.utils.getColor(b),i.color(n)}},useInteractiveGuideline:{get:function(){return v},set:function(a){v=a,a===!0&&(b.interactive(!1),b.useVoronoi(!1))}},rightAlignYAxis:{get:function(){return t},set:function(a){t=a,h.orient(a?"right":"left")}},duration:{get:function(){return D},set:function(a){D=a,f.duration(D),g.duration(D),h.duration(D),H.reset(D)}}}),a.utils.inheritOptions(b,f),a.utils.initOptions(b),b},a.models.discreteBar=function(){"use strict";function b(m){return y.reset(),m.each(function(b){var m=k-j.left-j.right,x=l-j.top-j.bottom;c=d3.select(this),a.utils.initSVG(c),b.forEach(function(a,b){a.values.forEach(function(a){a.series=b})});var z=d&&e?[]:b.map(function(a){return a.values.map(function(a,b){return{x:p(a,b),y:q(a,b),y0:a.y0}})});n.domain(d||d3.merge(z).map(function(a){return a.x})).rangeBands(f||[0,m],.1),o.domain(e||d3.extent(d3.merge(z).map(function(a){return a.y}).concat(r))),o.range(t?g||[x-(o.domain()[0]<0?12:0),o.domain()[1]>0?12:0]:g||[x,0]),h=h||n,i=i||o.copy().range([o(0),o(0)]);{var A=c.selectAll("g.nv-wrap.nv-discretebar").data([b]),B=A.enter().append("g").attr("class","nvd3 nv-wrap nv-discretebar"),C=B.append("g");A.select("g")}C.append("g").attr("class","nv-groups"),A.attr("transform","translate("+j.left+","+j.top+")");var D=A.select(".nv-groups").selectAll(".nv-group").data(function(a){return a},function(a){return a.key});D.enter().append("g").style("stroke-opacity",1e-6).style("fill-opacity",1e-6),D.exit().watchTransition(y,"discreteBar: exit groups").style("stroke-opacity",1e-6).style("fill-opacity",1e-6).remove(),D.attr("class",function(a,b){return"nv-group nv-series-"+b}).classed("hover",function(a){return a.hover}),D.watchTransition(y,"discreteBar: groups").style("stroke-opacity",1).style("fill-opacity",.75);var E=D.selectAll("g.nv-bar").data(function(a){return a.values});E.exit().remove();var F=E.enter().append("g").attr("transform",function(a,b){return"translate("+(n(p(a,b))+.05*n.rangeBand())+", "+o(0)+")"}).on("mouseover",function(a,b){d3.select(this).classed("hover",!0),v.elementMouseover({data:a,index:b,color:d3.select(this).style("fill")})}).on("mouseout",function(a,b){d3.select(this).classed("hover",!1),v.elementMouseout({data:a,index:b,color:d3.select(this).style("fill")})}).on("mousemove",function(a,b){v.elementMousemove({data:a,index:b,color:d3.select(this).style("fill")})}).on("click",function(a,b){v.elementClick({data:a,index:b,color:d3.select(this).style("fill")}),d3.event.stopPropagation()}).on("dblclick",function(a,b){v.elementDblClick({data:a,index:b,color:d3.select(this).style("fill")}),d3.event.stopPropagation()});F.append("rect").attr("height",0).attr("width",.9*n.rangeBand()/b.length),t?(F.append("text").attr("text-anchor","middle"),E.select("text").text(function(a,b){return u(q(a,b))}).watchTransition(y,"discreteBar: bars text").attr("x",.9*n.rangeBand()/2).attr("y",function(a,b){return q(a,b)<0?o(q(a,b))-o(0)+12:-4})):E.selectAll("text").remove(),E.attr("class",function(a,b){return q(a,b)<0?"nv-bar negative":"nv-bar positive"}).style("fill",function(a,b){return a.color||s(a,b)}).style("stroke",function(a,b){return a.color||s(a,b)}).select("rect").attr("class",w).watchTransition(y,"discreteBar: bars rect").attr("width",.9*n.rangeBand()/b.length),E.watchTransition(y,"discreteBar: bars").attr("transform",function(a,b){var c=n(p(a,b))+.05*n.rangeBand(),d=q(a,b)<0?o(0):o(0)-o(q(a,b))<1?o(0)-1:o(q(a,b));return"translate("+c+", "+d+")"}).select("rect").attr("height",function(a,b){return Math.max(Math.abs(o(q(a,b))-o(e&&e[0]||0))||1)}),h=n.copy(),i=o.copy()}),y.renderEnd("discreteBar immediate"),b}var c,d,e,f,g,h,i,j={top:0,right:0,bottom:0,left:0},k=960,l=500,m=Math.floor(1e4*Math.random()),n=d3.scale.ordinal(),o=d3.scale.linear(),p=function(a){return a.x},q=function(a){return a.y},r=[0],s=a.utils.defaultColor(),t=!1,u=d3.format(",.2f"),v=d3.dispatch("chartClick","elementClick","elementDblClick","elementMouseover","elementMouseout","elementMousemove","renderEnd"),w="discreteBar",x=250,y=a.utils.renderWatch(v,x);return b.dispatch=v,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return k},set:function(a){k=a}},height:{get:function(){return l},set:function(a){l=a}},forceY:{get:function(){return r},set:function(a){r=a}},showValues:{get:function(){return t},set:function(a){t=a}},x:{get:function(){return p},set:function(a){p=a}},y:{get:function(){return q},set:function(a){q=a}},xScale:{get:function(){return n},set:function(a){n=a}},yScale:{get:function(){return o},set:function(a){o=a}},xDomain:{get:function(){return d},set:function(a){d=a}},yDomain:{get:function(){return e},set:function(a){e=a}},xRange:{get:function(){return f},set:function(a){f=a}},yRange:{get:function(){return g},set:function(a){g=a}},valueFormat:{get:function(){return u},set:function(a){u=a}},id:{get:function(){return m},set:function(a){m=a}},rectClass:{get:function(){return w},set:function(a){w=a}},margin:{get:function(){return j},set:function(a){j.top=void 0!==a.top?a.top:j.top,j.right=void 0!==a.right?a.right:j.right,j.bottom=void 0!==a.bottom?a.bottom:j.bottom,j.left=void 0!==a.left?a.left:j.left}},color:{get:function(){return s},set:function(b){s=a.utils.getColor(b)}},duration:{get:function(){return x},set:function(a){x=a,y.reset(x)}}}),a.utils.initOptions(b),b},a.models.discreteBarChart=function(){"use strict";function b(h){return t.reset(),t.models(e),m&&t.models(f),n&&t.models(g),h.each(function(h){var l=d3.select(this);a.utils.initSVG(l);var q=a.utils.availableWidth(j,l,i),t=a.utils.availableHeight(k,l,i);if(b.update=function(){r.beforeUpdate(),l.transition().duration(s).call(b)},b.container=this,!(h&&h.length&&h.filter(function(a){return a.values.length}).length))return a.utils.noData(b,l),b;l.selectAll(".nv-noData").remove(),c=e.xScale(),d=e.yScale().clamp(!0);var u=l.selectAll("g.nv-wrap.nv-discreteBarWithAxes").data([h]),v=u.enter().append("g").attr("class","nvd3 nv-wrap nv-discreteBarWithAxes").append("g"),w=v.append("defs"),x=u.select("g");v.append("g").attr("class","nv-x nv-axis"),v.append("g").attr("class","nv-y nv-axis").append("g").attr("class","nv-zeroLine").append("line"),v.append("g").attr("class","nv-barsWrap"),x.attr("transform","translate("+i.left+","+i.top+")"),o&&x.select(".nv-y.nv-axis").attr("transform","translate("+q+",0)"),e.width(q).height(t);var y=x.select(".nv-barsWrap").datum(h.filter(function(a){return!a.disabled}));if(y.transition().call(e),w.append("clipPath").attr("id","nv-x-label-clip-"+e.id()).append("rect"),x.select("#nv-x-label-clip-"+e.id()+" rect").attr("width",c.rangeBand()*(p?2:1)).attr("height",16).attr("x",-c.rangeBand()/(p?1:2)),m){f.scale(c)._ticks(a.utils.calcTicksX(q/100,h)).tickSize(-t,0),x.select(".nv-x.nv-axis").attr("transform","translate(0,"+(d.range()[0]+(e.showValues()&&d.domain()[0]<0?16:0))+")"),x.select(".nv-x.nv-axis").call(f); -var z=x.select(".nv-x.nv-axis").selectAll("g");p&&z.selectAll("text").attr("transform",function(a,b,c){return"translate(0,"+(c%2==0?"5":"17")+")"})}n&&(g.scale(d)._ticks(a.utils.calcTicksY(t/36,h)).tickSize(-q,0),x.select(".nv-y.nv-axis").call(g)),x.select(".nv-zeroLine line").attr("x1",0).attr("x2",q).attr("y1",d(0)).attr("y2",d(0))}),t.renderEnd("discreteBar chart immediate"),b}var c,d,e=a.models.discreteBar(),f=a.models.axis(),g=a.models.axis(),h=a.models.tooltip(),i={top:15,right:10,bottom:50,left:60},j=null,k=null,l=a.utils.getColor(),m=!0,n=!0,o=!1,p=!1,q=null,r=d3.dispatch("beforeUpdate","renderEnd"),s=250;f.orient("bottom").showMaxMin(!1).tickFormat(function(a){return a}),g.orient(o?"right":"left").tickFormat(d3.format(",.1f")),h.duration(0).headerEnabled(!1).valueFormatter(function(a,b){return g.tickFormat()(a,b)}).keyFormatter(function(a,b){return f.tickFormat()(a,b)});var t=a.utils.renderWatch(r,s);return e.dispatch.on("elementMouseover.tooltip",function(a){a.series={key:b.x()(a.data),value:b.y()(a.data),color:a.color},h.data(a).hidden(!1)}),e.dispatch.on("elementMouseout.tooltip",function(){h.hidden(!0)}),e.dispatch.on("elementMousemove.tooltip",function(){h.position({top:d3.event.pageY,left:d3.event.pageX})()}),b.dispatch=r,b.discretebar=e,b.xAxis=f,b.yAxis=g,b.tooltip=h,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return j},set:function(a){j=a}},height:{get:function(){return k},set:function(a){k=a}},staggerLabels:{get:function(){return p},set:function(a){p=a}},showXAxis:{get:function(){return m},set:function(a){m=a}},showYAxis:{get:function(){return n},set:function(a){n=a}},noData:{get:function(){return q},set:function(a){q=a}},tooltips:{get:function(){return h.enabled()},set:function(b){a.deprecated("tooltips","use chart.tooltip.enabled() instead"),h.enabled(!!b)}},tooltipContent:{get:function(){return h.contentGenerator()},set:function(b){a.deprecated("tooltipContent","use chart.tooltip.contentGenerator() instead"),h.contentGenerator(b)}},margin:{get:function(){return i},set:function(a){i.top=void 0!==a.top?a.top:i.top,i.right=void 0!==a.right?a.right:i.right,i.bottom=void 0!==a.bottom?a.bottom:i.bottom,i.left=void 0!==a.left?a.left:i.left}},duration:{get:function(){return s},set:function(a){s=a,t.reset(s),e.duration(s),f.duration(s),g.duration(s)}},color:{get:function(){return l},set:function(b){l=a.utils.getColor(b),e.color(l)}},rightAlignYAxis:{get:function(){return o},set:function(a){o=a,g.orient(a?"right":"left")}}}),a.utils.inheritOptions(b,e),a.utils.initOptions(b),b},a.models.distribution=function(){"use strict";function b(k){return m.reset(),k.each(function(b){var k=(e-("x"===g?d.left+d.right:d.top+d.bottom),"x"==g?"y":"x"),l=d3.select(this);a.utils.initSVG(l),c=c||j;var n=l.selectAll("g.nv-distribution").data([b]),o=n.enter().append("g").attr("class","nvd3 nv-distribution"),p=(o.append("g"),n.select("g"));n.attr("transform","translate("+d.left+","+d.top+")");var q=p.selectAll("g.nv-dist").data(function(a){return a},function(a){return a.key});q.enter().append("g"),q.attr("class",function(a,b){return"nv-dist nv-series-"+b}).style("stroke",function(a,b){return i(a,b)});var r=q.selectAll("line.nv-dist"+g).data(function(a){return a.values});r.enter().append("line").attr(g+"1",function(a,b){return c(h(a,b))}).attr(g+"2",function(a,b){return c(h(a,b))}),m.transition(q.exit().selectAll("line.nv-dist"+g),"dist exit").attr(g+"1",function(a,b){return j(h(a,b))}).attr(g+"2",function(a,b){return j(h(a,b))}).style("stroke-opacity",0).remove(),r.attr("class",function(a,b){return"nv-dist"+g+" nv-dist"+g+"-"+b}).attr(k+"1",0).attr(k+"2",f),m.transition(r,"dist").attr(g+"1",function(a,b){return j(h(a,b))}).attr(g+"2",function(a,b){return j(h(a,b))}),c=j.copy()}),m.renderEnd("distribution immediate"),b}var c,d={top:0,right:0,bottom:0,left:0},e=400,f=8,g="x",h=function(a){return a[g]},i=a.utils.defaultColor(),j=d3.scale.linear(),k=250,l=d3.dispatch("renderEnd"),m=a.utils.renderWatch(l,k);return b.options=a.utils.optionsFunc.bind(b),b.dispatch=l,b.margin=function(a){return arguments.length?(d.top="undefined"!=typeof a.top?a.top:d.top,d.right="undefined"!=typeof a.right?a.right:d.right,d.bottom="undefined"!=typeof a.bottom?a.bottom:d.bottom,d.left="undefined"!=typeof a.left?a.left:d.left,b):d},b.width=function(a){return arguments.length?(e=a,b):e},b.axis=function(a){return arguments.length?(g=a,b):g},b.size=function(a){return arguments.length?(f=a,b):f},b.getData=function(a){return arguments.length?(h=d3.functor(a),b):h},b.scale=function(a){return arguments.length?(j=a,b):j},b.color=function(c){return arguments.length?(i=a.utils.getColor(c),b):i},b.duration=function(a){return arguments.length?(k=a,m.reset(k),b):k},b},a.models.furiousLegend=function(){"use strict";function b(p){function q(a,b){return"furious"!=o?"#000":m?a.disengaged?g(a,b):"#fff":m?void 0:a.disabled?g(a,b):"#fff"}function r(a,b){return m&&"furious"==o?a.disengaged?"#fff":g(a,b):a.disabled?"#fff":g(a,b)}return p.each(function(b){var p=d-c.left-c.right,s=d3.select(this);a.utils.initSVG(s);var t=s.selectAll("g.nv-legend").data([b]),u=(t.enter().append("g").attr("class","nvd3 nv-legend").append("g"),t.select("g"));t.attr("transform","translate("+c.left+","+c.top+")");var v,w=u.selectAll(".nv-series").data(function(a){return"furious"!=o?a:a.filter(function(a){return m?!0:!a.disengaged})}),x=w.enter().append("g").attr("class","nv-series");if("classic"==o)x.append("circle").style("stroke-width",2).attr("class","nv-legend-symbol").attr("r",5),v=w.select("circle");else if("furious"==o){x.append("rect").style("stroke-width",2).attr("class","nv-legend-symbol").attr("rx",3).attr("ry",3),v=w.select("rect"),x.append("g").attr("class","nv-check-box").property("innerHTML",'').attr("transform","translate(-10,-8)scale(0.5)");var y=w.select(".nv-check-box");y.each(function(a,b){d3.select(this).selectAll("path").attr("stroke",q(a,b))})}x.append("text").attr("text-anchor","start").attr("class","nv-legend-text").attr("dy",".32em").attr("dx","8");var z=w.select("text.nv-legend-text");w.on("mouseover",function(a,b){n.legendMouseover(a,b)}).on("mouseout",function(a,b){n.legendMouseout(a,b)}).on("click",function(a,b){n.legendClick(a,b);var c=w.data();if(k){if("classic"==o)l?(c.forEach(function(a){a.disabled=!0}),a.disabled=!1):(a.disabled=!a.disabled,c.every(function(a){return a.disabled})&&c.forEach(function(a){a.disabled=!1}));else if("furious"==o)if(m)a.disengaged=!a.disengaged,a.userDisabled=void 0==a.userDisabled?!!a.disabled:a.userDisabled,a.disabled=a.disengaged||a.userDisabled;else if(!m){a.disabled=!a.disabled,a.userDisabled=a.disabled;var d=c.filter(function(a){return!a.disengaged});d.every(function(a){return a.userDisabled})&&c.forEach(function(a){a.disabled=a.userDisabled=!1})}n.stateChange({disabled:c.map(function(a){return!!a.disabled}),disengaged:c.map(function(a){return!!a.disengaged})})}}).on("dblclick",function(a,b){if(("furious"!=o||!m)&&(n.legendDblclick(a,b),k)){var c=w.data();c.forEach(function(a){a.disabled=!0,"furious"==o&&(a.userDisabled=a.disabled)}),a.disabled=!1,"furious"==o&&(a.userDisabled=a.disabled),n.stateChange({disabled:c.map(function(a){return!!a.disabled})})}}),w.classed("nv-disabled",function(a){return a.userDisabled}),w.exit().remove(),z.attr("fill",q).text(f);var A;switch(o){case"furious":A=23;break;case"classic":A=20}if(h){var B=[];w.each(function(){var b,c=d3.select(this).select("text");try{if(b=c.node().getComputedTextLength(),0>=b)throw Error()}catch(d){b=a.utils.calcApproxTextWidth(c)}B.push(b+i)});for(var C=0,D=0,E=[];p>D&&Cp&&C>1;){E=[],C--;for(var F=0;F(E[F%C]||0)&&(E[F%C]=B[F]);D=E.reduce(function(a,b){return a+b})}for(var G=[],H=0,I=0;C>H;H++)G[H]=I,I+=E[H];w.attr("transform",function(a,b){return"translate("+G[b%C]+","+(5+Math.floor(b/C)*A)+")"}),j?u.attr("transform","translate("+(d-c.right-D)+","+c.top+")"):u.attr("transform","translate(0,"+c.top+")"),e=c.top+c.bottom+Math.ceil(B.length/C)*A}else{var J,K=5,L=5,M=0;w.attr("transform",function(){var a=d3.select(this).select("text").node().getComputedTextLength()+i;return J=L,dM&&(M=L),"translate("+J+","+K+")"}),u.attr("transform","translate("+(d-c.right-M)+","+c.top+")"),e=c.top+c.bottom+K+15}"furious"==o&&v.attr("width",function(a,b){return z[0][b].getComputedTextLength()+27}).attr("height",18).attr("y",-9).attr("x",-15),v.style("fill",r).style("stroke",function(a,b){return a.color||g(a,b)})}),b}var c={top:5,right:0,bottom:5,left:0},d=400,e=20,f=function(a){return a.key},g=a.utils.getColor(),h=!0,i=28,j=!0,k=!0,l=!1,m=!1,n=d3.dispatch("legendClick","legendDblclick","legendMouseover","legendMouseout","stateChange"),o="classic";return b.dispatch=n,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return d},set:function(a){d=a}},height:{get:function(){return e},set:function(a){e=a}},key:{get:function(){return f},set:function(a){f=a}},align:{get:function(){return h},set:function(a){h=a}},rightAlign:{get:function(){return j},set:function(a){j=a}},padding:{get:function(){return i},set:function(a){i=a}},updateState:{get:function(){return k},set:function(a){k=a}},radioButtonMode:{get:function(){return l},set:function(a){l=a}},expanded:{get:function(){return m},set:function(a){m=a}},vers:{get:function(){return o},set:function(a){o=a}},margin:{get:function(){return c},set:function(a){c.top=void 0!==a.top?a.top:c.top,c.right=void 0!==a.right?a.right:c.right,c.bottom=void 0!==a.bottom?a.bottom:c.bottom,c.left=void 0!==a.left?a.left:c.left}},color:{get:function(){return g},set:function(b){g=a.utils.getColor(b)}}}),a.utils.initOptions(b),b},a.models.historicalBar=function(){"use strict";function b(x){return x.each(function(b){w.reset(),k=d3.select(this);var x=a.utils.availableWidth(h,k,g),y=a.utils.availableHeight(i,k,g);a.utils.initSVG(k),l.domain(c||d3.extent(b[0].values.map(n).concat(p))),l.range(r?e||[.5*x/b[0].values.length,x*(b[0].values.length-.5)/b[0].values.length]:e||[0,x]),m.domain(d||d3.extent(b[0].values.map(o).concat(q))).range(f||[y,0]),l.domain()[0]===l.domain()[1]&&l.domain(l.domain()[0]?[l.domain()[0]-.01*l.domain()[0],l.domain()[1]+.01*l.domain()[1]]:[-1,1]),m.domain()[0]===m.domain()[1]&&m.domain(m.domain()[0]?[m.domain()[0]+.01*m.domain()[0],m.domain()[1]-.01*m.domain()[1]]:[-1,1]);var z=k.selectAll("g.nv-wrap.nv-historicalBar-"+j).data([b[0].values]),A=z.enter().append("g").attr("class","nvd3 nv-wrap nv-historicalBar-"+j),B=A.append("defs"),C=A.append("g"),D=z.select("g");C.append("g").attr("class","nv-bars"),z.attr("transform","translate("+g.left+","+g.top+")"),k.on("click",function(a,b){u.chartClick({data:a,index:b,pos:d3.event,id:j})}),B.append("clipPath").attr("id","nv-chart-clip-path-"+j).append("rect"),z.select("#nv-chart-clip-path-"+j+" rect").attr("width",x).attr("height",y),D.attr("clip-path",s?"url(#nv-chart-clip-path-"+j+")":"");var E=z.select(".nv-bars").selectAll(".nv-bar").data(function(a){return a},function(a,b){return n(a,b)});E.exit().remove(),E.enter().append("rect").attr("x",0).attr("y",function(b,c){return a.utils.NaNtoZero(m(Math.max(0,o(b,c))))}).attr("height",function(b,c){return a.utils.NaNtoZero(Math.abs(m(o(b,c))-m(0)))}).attr("transform",function(a,c){return"translate("+(l(n(a,c))-x/b[0].values.length*.45)+",0)"}).on("mouseover",function(a,b){v&&(d3.select(this).classed("hover",!0),u.elementMouseover({data:a,index:b,color:d3.select(this).style("fill")}))}).on("mouseout",function(a,b){v&&(d3.select(this).classed("hover",!1),u.elementMouseout({data:a,index:b,color:d3.select(this).style("fill")}))}).on("mousemove",function(a,b){v&&u.elementMousemove({data:a,index:b,color:d3.select(this).style("fill")})}).on("click",function(a,b){v&&(u.elementClick({data:a,index:b,color:d3.select(this).style("fill")}),d3.event.stopPropagation())}).on("dblclick",function(a,b){v&&(u.elementDblClick({data:a,index:b,color:d3.select(this).style("fill")}),d3.event.stopPropagation())}),E.attr("fill",function(a,b){return t(a,b)}).attr("class",function(a,b,c){return(o(a,b)<0?"nv-bar negative":"nv-bar positive")+" nv-bar-"+c+"-"+b}).watchTransition(w,"bars").attr("transform",function(a,c){return"translate("+(l(n(a,c))-x/b[0].values.length*.45)+",0)"}).attr("width",x/b[0].values.length*.9),E.watchTransition(w,"bars").attr("y",function(b,c){var d=o(b,c)<0?m(0):m(0)-m(o(b,c))<1?m(0)-1:m(o(b,c));return a.utils.NaNtoZero(d)}).attr("height",function(b,c){return a.utils.NaNtoZero(Math.max(Math.abs(m(o(b,c))-m(0)),1))})}),w.renderEnd("historicalBar immediate"),b}var c,d,e,f,g={top:0,right:0,bottom:0,left:0},h=null,i=null,j=Math.floor(1e4*Math.random()),k=null,l=d3.scale.linear(),m=d3.scale.linear(),n=function(a){return a.x},o=function(a){return a.y},p=[],q=[0],r=!1,s=!0,t=a.utils.defaultColor(),u=d3.dispatch("chartClick","elementClick","elementDblClick","elementMouseover","elementMouseout","elementMousemove","renderEnd"),v=!0,w=a.utils.renderWatch(u,0);return b.highlightPoint=function(a,b){k.select(".nv-bars .nv-bar-0-"+a).classed("hover",b)},b.clearHighlights=function(){k.select(".nv-bars .nv-bar.hover").classed("hover",!1)},b.dispatch=u,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return h},set:function(a){h=a}},height:{get:function(){return i},set:function(a){i=a}},forceX:{get:function(){return p},set:function(a){p=a}},forceY:{get:function(){return q},set:function(a){q=a}},padData:{get:function(){return r},set:function(a){r=a}},x:{get:function(){return n},set:function(a){n=a}},y:{get:function(){return o},set:function(a){o=a}},xScale:{get:function(){return l},set:function(a){l=a}},yScale:{get:function(){return m},set:function(a){m=a}},xDomain:{get:function(){return c},set:function(a){c=a}},yDomain:{get:function(){return d},set:function(a){d=a}},xRange:{get:function(){return e},set:function(a){e=a}},yRange:{get:function(){return f},set:function(a){f=a}},clipEdge:{get:function(){return s},set:function(a){s=a}},id:{get:function(){return j},set:function(a){j=a}},interactive:{get:function(){return v},set:function(a){v=a}},margin:{get:function(){return g},set:function(a){g.top=void 0!==a.top?a.top:g.top,g.right=void 0!==a.right?a.right:g.right,g.bottom=void 0!==a.bottom?a.bottom:g.bottom,g.left=void 0!==a.left?a.left:g.left}},color:{get:function(){return t},set:function(b){t=a.utils.getColor(b)}}}),a.utils.initOptions(b),b},a.models.historicalBarChart=function(b){"use strict";function c(b){return b.each(function(k){z.reset(),z.models(f),q&&z.models(g),r&&z.models(h);var w=d3.select(this),A=this;a.utils.initSVG(w);var B=a.utils.availableWidth(n,w,l),C=a.utils.availableHeight(o,w,l);if(c.update=function(){w.transition().duration(y).call(c)},c.container=this,u.disabled=k.map(function(a){return!!a.disabled}),!v){var D;v={};for(D in u)v[D]=u[D]instanceof Array?u[D].slice(0):u[D]}if(!(k&&k.length&&k.filter(function(a){return a.values.length}).length))return a.utils.noData(c,w),c;w.selectAll(".nv-noData").remove(),d=f.xScale(),e=f.yScale();var E=w.selectAll("g.nv-wrap.nv-historicalBarChart").data([k]),F=E.enter().append("g").attr("class","nvd3 nv-wrap nv-historicalBarChart").append("g"),G=E.select("g");F.append("g").attr("class","nv-x nv-axis"),F.append("g").attr("class","nv-y nv-axis"),F.append("g").attr("class","nv-barsWrap"),F.append("g").attr("class","nv-legendWrap"),F.append("g").attr("class","nv-interactive"),p&&(i.width(B),G.select(".nv-legendWrap").datum(k).call(i),l.top!=i.height()&&(l.top=i.height(),C=a.utils.availableHeight(o,w,l)),E.select(".nv-legendWrap").attr("transform","translate(0,"+-l.top+")")),E.attr("transform","translate("+l.left+","+l.top+")"),s&&G.select(".nv-y.nv-axis").attr("transform","translate("+B+",0)"),t&&(j.width(B).height(C).margin({left:l.left,top:l.top}).svgContainer(w).xScale(d),E.select(".nv-interactive").call(j)),f.width(B).height(C).color(k.map(function(a,b){return a.color||m(a,b)}).filter(function(a,b){return!k[b].disabled}));var H=G.select(".nv-barsWrap").datum(k.filter(function(a){return!a.disabled}));H.transition().call(f),q&&(g.scale(d)._ticks(a.utils.calcTicksX(B/100,k)).tickSize(-C,0),G.select(".nv-x.nv-axis").attr("transform","translate(0,"+e.range()[0]+")"),G.select(".nv-x.nv-axis").transition().call(g)),r&&(h.scale(e)._ticks(a.utils.calcTicksY(C/36,k)).tickSize(-B,0),G.select(".nv-y.nv-axis").transition().call(h)),j.dispatch.on("elementMousemove",function(b){f.clearHighlights();var d,e,i,n=[];k.filter(function(a,b){return a.seriesIndex=b,!a.disabled}).forEach(function(g){e=a.interactiveBisect(g.values,b.pointXValue,c.x()),f.highlightPoint(e,!0);var h=g.values[e];void 0!==h&&(void 0===d&&(d=h),void 0===i&&(i=c.xScale()(c.x()(h,e))),n.push({key:g.key,value:c.y()(h,e),color:m(g,g.seriesIndex),data:g.values[e]}))});var o=g.tickFormat()(c.x()(d,e));j.tooltip.position({left:i+l.left,top:b.mouseY+l.top}).chartContainer(A.parentNode).valueFormatter(function(a){return h.tickFormat()(a)}).data({value:o,index:e,series:n})(),j.renderGuideLine(i)}),j.dispatch.on("elementMouseout",function(){x.tooltipHide(),f.clearHighlights()}),i.dispatch.on("legendClick",function(a){a.disabled=!a.disabled,k.filter(function(a){return!a.disabled}).length||k.map(function(a){return a.disabled=!1,E.selectAll(".nv-series").classed("disabled",!1),a}),u.disabled=k.map(function(a){return!!a.disabled}),x.stateChange(u),b.transition().call(c)}),i.dispatch.on("legendDblclick",function(a){k.forEach(function(a){a.disabled=!0}),a.disabled=!1,u.disabled=k.map(function(a){return!!a.disabled}),x.stateChange(u),c.update()}),x.on("changeState",function(a){"undefined"!=typeof a.disabled&&(k.forEach(function(b,c){b.disabled=a.disabled[c]}),u.disabled=a.disabled),c.update()})}),z.renderEnd("historicalBarChart immediate"),c}var d,e,f=b||a.models.historicalBar(),g=a.models.axis(),h=a.models.axis(),i=a.models.legend(),j=a.interactiveGuideline(),k=a.models.tooltip(),l={top:30,right:90,bottom:50,left:90},m=a.utils.defaultColor(),n=null,o=null,p=!1,q=!0,r=!0,s=!1,t=!1,u={},v=null,w=null,x=d3.dispatch("tooltipHide","stateChange","changeState","renderEnd"),y=250;g.orient("bottom").tickPadding(7),h.orient(s?"right":"left"),k.duration(0).headerEnabled(!1).valueFormatter(function(a,b){return h.tickFormat()(a,b)}).headerFormatter(function(a,b){return g.tickFormat()(a,b)});var z=a.utils.renderWatch(x,0);return f.dispatch.on("elementMouseover.tooltip",function(a){a.series={key:c.x()(a.data),value:c.y()(a.data),color:a.color},k.data(a).hidden(!1)}),f.dispatch.on("elementMouseout.tooltip",function(){k.hidden(!0)}),f.dispatch.on("elementMousemove.tooltip",function(){k.position({top:d3.event.pageY,left:d3.event.pageX})()}),c.dispatch=x,c.bars=f,c.legend=i,c.xAxis=g,c.yAxis=h,c.interactiveLayer=j,c.tooltip=k,c.options=a.utils.optionsFunc.bind(c),c._options=Object.create({},{width:{get:function(){return n},set:function(a){n=a}},height:{get:function(){return o},set:function(a){o=a}},showLegend:{get:function(){return p},set:function(a){p=a}},showXAxis:{get:function(){return q},set:function(a){q=a}},showYAxis:{get:function(){return r},set:function(a){r=a}},defaultState:{get:function(){return v},set:function(a){v=a}},noData:{get:function(){return w},set:function(a){w=a}},tooltips:{get:function(){return k.enabled()},set:function(b){a.deprecated("tooltips","use chart.tooltip.enabled() instead"),k.enabled(!!b)}},tooltipContent:{get:function(){return k.contentGenerator()},set:function(b){a.deprecated("tooltipContent","use chart.tooltip.contentGenerator() instead"),k.contentGenerator(b)}},margin:{get:function(){return l},set:function(a){l.top=void 0!==a.top?a.top:l.top,l.right=void 0!==a.right?a.right:l.right,l.bottom=void 0!==a.bottom?a.bottom:l.bottom,l.left=void 0!==a.left?a.left:l.left}},color:{get:function(){return m},set:function(b){m=a.utils.getColor(b),i.color(m),f.color(m)}},duration:{get:function(){return y},set:function(a){y=a,z.reset(y),h.duration(y),g.duration(y)}},rightAlignYAxis:{get:function(){return s},set:function(a){s=a,h.orient(a?"right":"left")}},useInteractiveGuideline:{get:function(){return t},set:function(a){t=a,a===!0&&c.interactive(!1)}}}),a.utils.inheritOptions(c,f),a.utils.initOptions(c),c},a.models.ohlcBarChart=function(){var b=a.models.historicalBarChart(a.models.ohlcBar());return b.useInteractiveGuideline(!0),b.interactiveLayer.tooltip.contentGenerator(function(a){var c=a.series[0].data,d=c.open'+a.value+"
open:"+b.yAxis.tickFormat()(c.open)+"
close:"+b.yAxis.tickFormat()(c.close)+"
high"+b.yAxis.tickFormat()(c.high)+"
low:"+b.yAxis.tickFormat()(c.low)+"
"}),b},a.models.candlestickBarChart=function(){var b=a.models.historicalBarChart(a.models.candlestickBar());return b.useInteractiveGuideline(!0),b.interactiveLayer.tooltip.contentGenerator(function(a){var c=a.series[0].data,d=c.open'+a.value+"
open:"+b.yAxis.tickFormat()(c.open)+"
close:"+b.yAxis.tickFormat()(c.close)+"
high"+b.yAxis.tickFormat()(c.high)+"
low:"+b.yAxis.tickFormat()(c.low)+"
"}),b},a.models.legend=function(){"use strict";function b(p){function q(a,b){return"furious"!=o?"#000":m?a.disengaged?"#000":"#fff":m?void 0:(a.color||(a.color=g(a,b)),a.disabled?a.color:"#fff")}function r(a,b){return m&&"furious"==o&&a.disengaged?"#eee":a.color||g(a,b)}function s(a){return m&&"furious"==o?1:a.disabled?0:1}return p.each(function(b){var g=d-c.left-c.right,p=d3.select(this);a.utils.initSVG(p);var t=p.selectAll("g.nv-legend").data([b]),u=t.enter().append("g").attr("class","nvd3 nv-legend").append("g"),v=t.select("g");t.attr("transform","translate("+c.left+","+c.top+")");var w,x,y=v.selectAll(".nv-series").data(function(a){return"furious"!=o?a:a.filter(function(a){return m?!0:!a.disengaged})}),z=y.enter().append("g").attr("class","nv-series");switch(o){case"furious":x=23;break;case"classic":x=20}if("classic"==o)z.append("circle").style("stroke-width",2).attr("class","nv-legend-symbol").attr("r",5),w=y.select("circle");else if("furious"==o){z.append("rect").style("stroke-width",2).attr("class","nv-legend-symbol").attr("rx",3).attr("ry",3),w=y.select(".nv-legend-symbol"),z.append("g").attr("class","nv-check-box").property("innerHTML",'').attr("transform","translate(-10,-8)scale(0.5)");var A=y.select(".nv-check-box");A.each(function(a,b){d3.select(this).selectAll("path").attr("stroke",q(a,b))})}z.append("text").attr("text-anchor","start").attr("class","nv-legend-text").attr("dy",".32em").attr("dx","8");var B=y.select("text.nv-legend-text");y.on("mouseover",function(a,b){n.legendMouseover(a,b)}).on("mouseout",function(a,b){n.legendMouseout(a,b)}).on("click",function(a,b){n.legendClick(a,b);var c=y.data();if(k){if("classic"==o)l?(c.forEach(function(a){a.disabled=!0}),a.disabled=!1):(a.disabled=!a.disabled,c.every(function(a){return a.disabled})&&c.forEach(function(a){a.disabled=!1}));else if("furious"==o)if(m)a.disengaged=!a.disengaged,a.userDisabled=void 0==a.userDisabled?!!a.disabled:a.userDisabled,a.disabled=a.disengaged||a.userDisabled;else if(!m){a.disabled=!a.disabled,a.userDisabled=a.disabled;var d=c.filter(function(a){return!a.disengaged});d.every(function(a){return a.userDisabled})&&c.forEach(function(a){a.disabled=a.userDisabled=!1})}n.stateChange({disabled:c.map(function(a){return!!a.disabled}),disengaged:c.map(function(a){return!!a.disengaged})})}}).on("dblclick",function(a,b){if(("furious"!=o||!m)&&(n.legendDblclick(a,b),k)){var c=y.data();c.forEach(function(a){a.disabled=!0,"furious"==o&&(a.userDisabled=a.disabled)}),a.disabled=!1,"furious"==o&&(a.userDisabled=a.disabled),n.stateChange({disabled:c.map(function(a){return!!a.disabled})})}}),y.classed("nv-disabled",function(a){return a.userDisabled}),y.exit().remove(),B.attr("fill",q).text(f);var C=0;if(h){var D=[];y.each(function(){var b,c=d3.select(this).select("text");try{if(b=c.node().getComputedTextLength(),0>=b)throw Error()}catch(d){b=a.utils.calcApproxTextWidth(c)}D.push(b+i)});var E=0,F=[];for(C=0;g>C&&Eg&&E>1;){F=[],E--;for(var G=0;G(F[G%E]||0)&&(F[G%E]=D[G]);C=F.reduce(function(a,b){return a+b})}for(var H=[],I=0,J=0;E>I;I++)H[I]=J,J+=F[I];y.attr("transform",function(a,b){return"translate("+H[b%E]+","+(5+Math.floor(b/E)*x)+")"}),j?v.attr("transform","translate("+(d-c.right-C)+","+c.top+")"):v.attr("transform","translate(0,"+c.top+")"),e=c.top+c.bottom+Math.ceil(D.length/E)*x}else{var K,L=5,M=5,N=0;y.attr("transform",function(){var a=d3.select(this).select("text").node().getComputedTextLength()+i;return K=M,dN&&(N=M),K+N>C&&(C=K+N),"translate("+K+","+L+")"}),v.attr("transform","translate("+(d-c.right-N)+","+c.top+")"),e=c.top+c.bottom+L+15}if("furious"==o){w.attr("width",function(a,b){return B[0][b].getComputedTextLength()+27}).attr("height",18).attr("y",-9).attr("x",-15),u.insert("rect",":first-child").attr("class","nv-legend-bg").attr("fill","#eee").attr("opacity",0);var O=v.select(".nv-legend-bg");O.transition().duration(300).attr("x",-x).attr("width",C+x-12).attr("height",e+10).attr("y",-c.top-10).attr("opacity",m?1:0)}w.style("fill",r).style("fill-opacity",s).style("stroke",r)}),b}var c={top:5,right:0,bottom:5,left:0},d=400,e=20,f=function(a){return a.key},g=a.utils.getColor(),h=!0,i=32,j=!0,k=!0,l=!1,m=!1,n=d3.dispatch("legendClick","legendDblclick","legendMouseover","legendMouseout","stateChange"),o="classic";return b.dispatch=n,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return d},set:function(a){d=a}},height:{get:function(){return e},set:function(a){e=a}},key:{get:function(){return f},set:function(a){f=a}},align:{get:function(){return h},set:function(a){h=a}},rightAlign:{get:function(){return j},set:function(a){j=a}},padding:{get:function(){return i},set:function(a){i=a}},updateState:{get:function(){return k},set:function(a){k=a}},radioButtonMode:{get:function(){return l},set:function(a){l=a}},expanded:{get:function(){return m},set:function(a){m=a}},vers:{get:function(){return o},set:function(a){o=a}},margin:{get:function(){return c},set:function(a){c.top=void 0!==a.top?a.top:c.top,c.right=void 0!==a.right?a.right:c.right,c.bottom=void 0!==a.bottom?a.bottom:c.bottom,c.left=void 0!==a.left?a.left:c.left}},color:{get:function(){return g},set:function(b){g=a.utils.getColor(b)}}}),a.utils.initOptions(b),b},a.models.line=function(){"use strict";function b(r){return v.reset(),v.models(e),r.each(function(b){i=d3.select(this);var r=a.utils.availableWidth(g,i,f),s=a.utils.availableHeight(h,i,f);a.utils.initSVG(i),c=e.xScale(),d=e.yScale(),t=t||c,u=u||d;var w=i.selectAll("g.nv-wrap.nv-line").data([b]),x=w.enter().append("g").attr("class","nvd3 nv-wrap nv-line"),y=x.append("defs"),z=x.append("g"),A=w.select("g");z.append("g").attr("class","nv-groups"),z.append("g").attr("class","nv-scatterWrap"),w.attr("transform","translate("+f.left+","+f.top+")"),e.width(r).height(s);var B=w.select(".nv-scatterWrap");B.call(e),y.append("clipPath").attr("id","nv-edge-clip-"+e.id()).append("rect"),w.select("#nv-edge-clip-"+e.id()+" rect").attr("width",r).attr("height",s>0?s:0),A.attr("clip-path",p?"url(#nv-edge-clip-"+e.id()+")":""),B.attr("clip-path",p?"url(#nv-edge-clip-"+e.id()+")":"");var C=w.select(".nv-groups").selectAll(".nv-group").data(function(a){return a},function(a){return a.key});C.enter().append("g").style("stroke-opacity",1e-6).style("stroke-width",function(a){return a.strokeWidth||j}).style("fill-opacity",1e-6),C.exit().remove(),C.attr("class",function(a,b){return(a.classed||"")+" nv-group nv-series-"+b}).classed("hover",function(a){return a.hover}).style("fill",function(a,b){return k(a,b)}).style("stroke",function(a,b){return k(a,b)}),C.watchTransition(v,"line: groups").style("stroke-opacity",1).style("fill-opacity",function(a){return a.fillOpacity||.5});var D=C.selectAll("path.nv-area").data(function(a){return o(a)?[a]:[]});D.enter().append("path").attr("class","nv-area").attr("d",function(b){return d3.svg.area().interpolate(q).defined(n).x(function(b,c){return a.utils.NaNtoZero(t(l(b,c)))}).y0(function(b,c){return a.utils.NaNtoZero(u(m(b,c)))}).y1(function(){return u(d.domain()[0]<=0?d.domain()[1]>=0?0:d.domain()[1]:d.domain()[0])}).apply(this,[b.values])}),C.exit().selectAll("path.nv-area").remove(),D.watchTransition(v,"line: areaPaths").attr("d",function(b){return d3.svg.area().interpolate(q).defined(n).x(function(b,d){return a.utils.NaNtoZero(c(l(b,d)))}).y0(function(b,c){return a.utils.NaNtoZero(d(m(b,c)))}).y1(function(){return d(d.domain()[0]<=0?d.domain()[1]>=0?0:d.domain()[1]:d.domain()[0])}).apply(this,[b.values])});var E=C.selectAll("path.nv-line").data(function(a){return[a.values]});E.enter().append("path").attr("class","nv-line").attr("d",d3.svg.line().interpolate(q).defined(n).x(function(b,c){return a.utils.NaNtoZero(t(l(b,c)))}).y(function(b,c){return a.utils.NaNtoZero(u(m(b,c)))})),E.watchTransition(v,"line: linePaths").attr("d",d3.svg.line().interpolate(q).defined(n).x(function(b,d){return a.utils.NaNtoZero(c(l(b,d)))}).y(function(b,c){return a.utils.NaNtoZero(d(m(b,c)))})),t=c.copy(),u=d.copy()}),v.renderEnd("line immediate"),b}var c,d,e=a.models.scatter(),f={top:0,right:0,bottom:0,left:0},g=960,h=500,i=null,j=1.5,k=a.utils.defaultColor(),l=function(a){return a.x},m=function(a){return a.y},n=function(a,b){return!isNaN(m(a,b))&&null!==m(a,b)},o=function(a){return a.area},p=!1,q="linear",r=250,s=d3.dispatch("elementClick","elementMouseover","elementMouseout","renderEnd");e.pointSize(16).pointDomain([16,256]);var t,u,v=a.utils.renderWatch(s,r);return b.dispatch=s,b.scatter=e,e.dispatch.on("elementClick",function(){s.elementClick.apply(this,arguments)}),e.dispatch.on("elementMouseover",function(){s.elementMouseover.apply(this,arguments)}),e.dispatch.on("elementMouseout",function(){s.elementMouseout.apply(this,arguments)}),b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return g},set:function(a){g=a}},height:{get:function(){return h},set:function(a){h=a}},defined:{get:function(){return n},set:function(a){n=a}},interpolate:{get:function(){return q},set:function(a){q=a}},clipEdge:{get:function(){return p},set:function(a){p=a}},margin:{get:function(){return f},set:function(a){f.top=void 0!==a.top?a.top:f.top,f.right=void 0!==a.right?a.right:f.right,f.bottom=void 0!==a.bottom?a.bottom:f.bottom,f.left=void 0!==a.left?a.left:f.left}},duration:{get:function(){return r},set:function(a){r=a,v.reset(r),e.duration(r)}},isArea:{get:function(){return o},set:function(a){o=d3.functor(a)}},x:{get:function(){return l},set:function(a){l=a,e.x(a)}},y:{get:function(){return m},set:function(a){m=a,e.y(a)}},color:{get:function(){return k},set:function(b){k=a.utils.getColor(b),e.color(k)}}}),a.utils.inheritOptions(b,e),a.utils.initOptions(b),b},a.models.lineChart=function(){"use strict";function b(j){return y.reset(),y.models(e),p&&y.models(f),q&&y.models(g),j.each(function(j){var v=d3.select(this),y=this;a.utils.initSVG(v);var B=a.utils.availableWidth(m,v,k),C=a.utils.availableHeight(n,v,k);if(b.update=function(){0===x?v.call(b):v.transition().duration(x).call(b)},b.container=this,t.setter(A(j),b.update).getter(z(j)).update(),t.disabled=j.map(function(a){return!!a.disabled}),!u){var D;u={};for(D in t)u[D]=t[D]instanceof Array?t[D].slice(0):t[D] -}if(!(j&&j.length&&j.filter(function(a){return a.values.length}).length))return a.utils.noData(b,v),b;v.selectAll(".nv-noData").remove(),c=e.xScale(),d=e.yScale();var E=v.selectAll("g.nv-wrap.nv-lineChart").data([j]),F=E.enter().append("g").attr("class","nvd3 nv-wrap nv-lineChart").append("g"),G=E.select("g");F.append("rect").style("opacity",0),F.append("g").attr("class","nv-x nv-axis"),F.append("g").attr("class","nv-y nv-axis"),F.append("g").attr("class","nv-linesWrap"),F.append("g").attr("class","nv-legendWrap"),F.append("g").attr("class","nv-interactive"),G.select("rect").attr("width",B).attr("height",C>0?C:0),o&&(h.width(B),G.select(".nv-legendWrap").datum(j).call(h),k.top!=h.height()&&(k.top=h.height(),C=a.utils.availableHeight(n,v,k)),E.select(".nv-legendWrap").attr("transform","translate(0,"+-k.top+")")),E.attr("transform","translate("+k.left+","+k.top+")"),r&&G.select(".nv-y.nv-axis").attr("transform","translate("+B+",0)"),s&&(i.width(B).height(C).margin({left:k.left,top:k.top}).svgContainer(v).xScale(c),E.select(".nv-interactive").call(i)),e.width(B).height(C).color(j.map(function(a,b){return a.color||l(a,b)}).filter(function(a,b){return!j[b].disabled}));var H=G.select(".nv-linesWrap").datum(j.filter(function(a){return!a.disabled}));H.call(e),p&&(f.scale(c)._ticks(a.utils.calcTicksX(B/100,j)).tickSize(-C,0),G.select(".nv-x.nv-axis").attr("transform","translate(0,"+d.range()[0]+")"),G.select(".nv-x.nv-axis").call(f)),q&&(g.scale(d)._ticks(a.utils.calcTicksY(C/36,j)).tickSize(-B,0),G.select(".nv-y.nv-axis").call(g)),h.dispatch.on("stateChange",function(a){for(var c in a)t[c]=a[c];w.stateChange(t),b.update()}),i.dispatch.on("elementMousemove",function(c){e.clearHighlights();var d,h,m,n=[];if(j.filter(function(a,b){return a.seriesIndex=b,!a.disabled}).forEach(function(f,g){h=a.interactiveBisect(f.values,c.pointXValue,b.x());var i=f.values[h],j=b.y()(i,h);null!=j&&e.highlightPoint(g,h,!0),void 0!==i&&(void 0===d&&(d=i),void 0===m&&(m=b.xScale()(b.x()(i,h))),n.push({key:f.key,value:j,color:l(f,f.seriesIndex)}))}),n.length>2){var o=b.yScale().invert(c.mouseY),p=Math.abs(b.yScale().domain()[0]-b.yScale().domain()[1]),q=.03*p,r=a.nearestValueIndex(n.map(function(a){return a.value}),o,q);null!==r&&(n[r].highlight=!0)}var s=f.tickFormat()(b.x()(d,h));i.tooltip.position({left:c.mouseX+k.left,top:c.mouseY+k.top}).chartContainer(y.parentNode).valueFormatter(function(a){return null==a?"N/A":g.tickFormat()(a)}).data({value:s,index:h,series:n})(),i.renderGuideLine(m)}),i.dispatch.on("elementClick",function(c){var d,f=[];j.filter(function(a,b){return a.seriesIndex=b,!a.disabled}).forEach(function(e){var g=a.interactiveBisect(e.values,c.pointXValue,b.x()),h=e.values[g];if("undefined"!=typeof h){"undefined"==typeof d&&(d=b.xScale()(b.x()(h,g)));var i=b.yScale()(b.y()(h,g));f.push({point:h,pointIndex:g,pos:[d,i],seriesIndex:e.seriesIndex,series:e})}}),e.dispatch.elementClick(f)}),i.dispatch.on("elementMouseout",function(){e.clearHighlights()}),w.on("changeState",function(a){"undefined"!=typeof a.disabled&&j.length===a.disabled.length&&(j.forEach(function(b,c){b.disabled=a.disabled[c]}),t.disabled=a.disabled),b.update()})}),y.renderEnd("lineChart immediate"),b}var c,d,e=a.models.line(),f=a.models.axis(),g=a.models.axis(),h=a.models.legend(),i=a.interactiveGuideline(),j=a.models.tooltip(),k={top:30,right:20,bottom:50,left:60},l=a.utils.defaultColor(),m=null,n=null,o=!0,p=!0,q=!0,r=!1,s=!1,t=a.utils.state(),u=null,v=null,w=d3.dispatch("tooltipShow","tooltipHide","stateChange","changeState","renderEnd"),x=250;f.orient("bottom").tickPadding(7),g.orient(r?"right":"left"),j.valueFormatter(function(a,b){return g.tickFormat()(a,b)}).headerFormatter(function(a,b){return f.tickFormat()(a,b)});var y=a.utils.renderWatch(w,x),z=function(a){return function(){return{active:a.map(function(a){return!a.disabled})}}},A=function(a){return function(b){void 0!==b.active&&a.forEach(function(a,c){a.disabled=!b.active[c]})}};return e.dispatch.on("elementMouseover.tooltip",function(a){j.data(a).position(a.pos).hidden(!1)}),e.dispatch.on("elementMouseout.tooltip",function(){j.hidden(!0)}),b.dispatch=w,b.lines=e,b.legend=h,b.xAxis=f,b.yAxis=g,b.interactiveLayer=i,b.tooltip=j,b.dispatch=w,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return m},set:function(a){m=a}},height:{get:function(){return n},set:function(a){n=a}},showLegend:{get:function(){return o},set:function(a){o=a}},showXAxis:{get:function(){return p},set:function(a){p=a}},showYAxis:{get:function(){return q},set:function(a){q=a}},defaultState:{get:function(){return u},set:function(a){u=a}},noData:{get:function(){return v},set:function(a){v=a}},tooltips:{get:function(){return j.enabled()},set:function(b){a.deprecated("tooltips","use chart.tooltip.enabled() instead"),j.enabled(!!b)}},tooltipContent:{get:function(){return j.contentGenerator()},set:function(b){a.deprecated("tooltipContent","use chart.tooltip.contentGenerator() instead"),j.contentGenerator(b)}},margin:{get:function(){return k},set:function(a){k.top=void 0!==a.top?a.top:k.top,k.right=void 0!==a.right?a.right:k.right,k.bottom=void 0!==a.bottom?a.bottom:k.bottom,k.left=void 0!==a.left?a.left:k.left}},duration:{get:function(){return x},set:function(a){x=a,y.reset(x),e.duration(x),f.duration(x),g.duration(x)}},color:{get:function(){return l},set:function(b){l=a.utils.getColor(b),h.color(l),e.color(l)}},rightAlignYAxis:{get:function(){return r},set:function(a){r=a,g.orient(r?"right":"left")}},useInteractiveGuideline:{get:function(){return s},set:function(a){s=a,s&&(e.interactive(!1),e.useVoronoi(!1))}}}),a.utils.inheritOptions(b,e),a.utils.initOptions(b),b},a.models.linePlusBarChart=function(){"use strict";function b(v){return v.each(function(v){function J(a){var b=+("e"==a),c=b?1:-1,d=X/3;return"M"+.5*c+","+d+"A6,6 0 0 "+b+" "+6.5*c+","+(d+6)+"V"+(2*d-6)+"A6,6 0 0 "+b+" "+.5*c+","+2*d+"ZM"+2.5*c+","+(d+8)+"V"+(2*d-8)+"M"+4.5*c+","+(d+8)+"V"+(2*d-8)}function S(){u.empty()||u.extent(I),kb.data([u.empty()?e.domain():I]).each(function(a){var b=e(a[0])-e.range()[0],c=e.range()[1]-e(a[1]);d3.select(this).select(".left").attr("width",0>b?0:b),d3.select(this).select(".right").attr("x",e(a[1])).attr("width",0>c?0:c)})}function T(){I=u.empty()?null:u.extent(),c=u.empty()?e.domain():u.extent(),K.brush({extent:c,brush:u}),S(),l.width(V).height(W).color(v.map(function(a,b){return a.color||C(a,b)}).filter(function(a,b){return!v[b].disabled&&v[b].bar})),j.width(V).height(W).color(v.map(function(a,b){return a.color||C(a,b)}).filter(function(a,b){return!v[b].disabled&&!v[b].bar}));var b=db.select(".nv-focus .nv-barsWrap").datum(Z.length?Z.map(function(a){return{key:a.key,values:a.values.filter(function(a,b){return l.x()(a,b)>=c[0]&&l.x()(a,b)<=c[1]})}}):[{values:[]}]),h=db.select(".nv-focus .nv-linesWrap").datum($[0].disabled?[{values:[]}]:$.map(function(a){return{area:a.area,fillOpacity:a.fillOpacity,key:a.key,values:a.values.filter(function(a,b){return j.x()(a,b)>=c[0]&&j.x()(a,b)<=c[1]})}}));d=Z.length?l.xScale():j.xScale(),n.scale(d)._ticks(a.utils.calcTicksX(V/100,v)).tickSize(-W,0),n.domain([Math.ceil(c[0]),Math.floor(c[1])]),db.select(".nv-x.nv-axis").transition().duration(L).call(n),b.transition().duration(L).call(l),h.transition().duration(L).call(j),db.select(".nv-focus .nv-x.nv-axis").attr("transform","translate(0,"+f.range()[0]+")"),p.scale(f)._ticks(a.utils.calcTicksY(W/36,v)).tickSize(-V,0),q.scale(g)._ticks(a.utils.calcTicksY(W/36,v)).tickSize(Z.length?0:-V,0),db.select(".nv-focus .nv-y1.nv-axis").style("opacity",Z.length?1:0),db.select(".nv-focus .nv-y2.nv-axis").style("opacity",$.length&&!$[0].disabled?1:0).attr("transform","translate("+d.range()[1]+",0)"),db.select(".nv-focus .nv-y1.nv-axis").transition().duration(L).call(p),db.select(".nv-focus .nv-y2.nv-axis").transition().duration(L).call(q)}var U=d3.select(this);a.utils.initSVG(U);var V=a.utils.availableWidth(y,U,w),W=a.utils.availableHeight(z,U,w)-(E?H:0),X=H-x.top-x.bottom;if(b.update=function(){U.transition().duration(L).call(b)},b.container=this,M.setter(R(v),b.update).getter(Q(v)).update(),M.disabled=v.map(function(a){return!!a.disabled}),!N){var Y;N={};for(Y in M)N[Y]=M[Y]instanceof Array?M[Y].slice(0):M[Y]}if(!(v&&v.length&&v.filter(function(a){return a.values.length}).length))return a.utils.noData(b,U),b;U.selectAll(".nv-noData").remove();var Z=v.filter(function(a){return!a.disabled&&a.bar}),$=v.filter(function(a){return!a.bar});d=l.xScale(),e=o.scale(),f=l.yScale(),g=j.yScale(),h=m.yScale(),i=k.yScale();var _=v.filter(function(a){return!a.disabled&&a.bar}).map(function(a){return a.values.map(function(a,b){return{x:A(a,b),y:B(a,b)}})}),ab=v.filter(function(a){return!a.disabled&&!a.bar}).map(function(a){return a.values.map(function(a,b){return{x:A(a,b),y:B(a,b)}})});d.range([0,V]),e.domain(d3.extent(d3.merge(_.concat(ab)),function(a){return a.x})).range([0,V]);var bb=U.selectAll("g.nv-wrap.nv-linePlusBar").data([v]),cb=bb.enter().append("g").attr("class","nvd3 nv-wrap nv-linePlusBar").append("g"),db=bb.select("g");cb.append("g").attr("class","nv-legendWrap");var eb=cb.append("g").attr("class","nv-focus");eb.append("g").attr("class","nv-x nv-axis"),eb.append("g").attr("class","nv-y1 nv-axis"),eb.append("g").attr("class","nv-y2 nv-axis"),eb.append("g").attr("class","nv-barsWrap"),eb.append("g").attr("class","nv-linesWrap");var fb=cb.append("g").attr("class","nv-context");if(fb.append("g").attr("class","nv-x nv-axis"),fb.append("g").attr("class","nv-y1 nv-axis"),fb.append("g").attr("class","nv-y2 nv-axis"),fb.append("g").attr("class","nv-barsWrap"),fb.append("g").attr("class","nv-linesWrap"),fb.append("g").attr("class","nv-brushBackground"),fb.append("g").attr("class","nv-x nv-brush"),D){var gb=t.align()?V/2:V,hb=t.align()?gb:0;t.width(gb),db.select(".nv-legendWrap").datum(v.map(function(a){return a.originalKey=void 0===a.originalKey?a.key:a.originalKey,a.key=a.originalKey+(a.bar?O:P),a})).call(t),w.top!=t.height()&&(w.top=t.height(),W=a.utils.availableHeight(z,U,w)-H),db.select(".nv-legendWrap").attr("transform","translate("+hb+","+-w.top+")")}bb.attr("transform","translate("+w.left+","+w.top+")"),db.select(".nv-context").style("display",E?"initial":"none"),m.width(V).height(X).color(v.map(function(a,b){return a.color||C(a,b)}).filter(function(a,b){return!v[b].disabled&&v[b].bar})),k.width(V).height(X).color(v.map(function(a,b){return a.color||C(a,b)}).filter(function(a,b){return!v[b].disabled&&!v[b].bar}));var ib=db.select(".nv-context .nv-barsWrap").datum(Z.length?Z:[{values:[]}]),jb=db.select(".nv-context .nv-linesWrap").datum($[0].disabled?[{values:[]}]:$);db.select(".nv-context").attr("transform","translate(0,"+(W+w.bottom+x.top)+")"),ib.transition().call(m),jb.transition().call(k),G&&(o._ticks(a.utils.calcTicksX(V/100,v)).tickSize(-X,0),db.select(".nv-context .nv-x.nv-axis").attr("transform","translate(0,"+h.range()[0]+")"),db.select(".nv-context .nv-x.nv-axis").transition().call(o)),F&&(r.scale(h)._ticks(X/36).tickSize(-V,0),s.scale(i)._ticks(X/36).tickSize(Z.length?0:-V,0),db.select(".nv-context .nv-y3.nv-axis").style("opacity",Z.length?1:0).attr("transform","translate(0,"+e.range()[0]+")"),db.select(".nv-context .nv-y2.nv-axis").style("opacity",$.length?1:0).attr("transform","translate("+e.range()[1]+",0)"),db.select(".nv-context .nv-y1.nv-axis").transition().call(r),db.select(".nv-context .nv-y2.nv-axis").transition().call(s)),u.x(e).on("brush",T),I&&u.extent(I);var kb=db.select(".nv-brushBackground").selectAll("g").data([I||u.extent()]),lb=kb.enter().append("g");lb.append("rect").attr("class","left").attr("x",0).attr("y",0).attr("height",X),lb.append("rect").attr("class","right").attr("x",0).attr("y",0).attr("height",X);var mb=db.select(".nv-x.nv-brush").call(u);mb.selectAll("rect").attr("height",X),mb.selectAll(".resize").append("path").attr("d",J),t.dispatch.on("stateChange",function(a){for(var c in a)M[c]=a[c];K.stateChange(M),b.update()}),K.on("changeState",function(a){"undefined"!=typeof a.disabled&&(v.forEach(function(b,c){b.disabled=a.disabled[c]}),M.disabled=a.disabled),b.update()}),T()}),b}var c,d,e,f,g,h,i,j=a.models.line(),k=a.models.line(),l=a.models.historicalBar(),m=a.models.historicalBar(),n=a.models.axis(),o=a.models.axis(),p=a.models.axis(),q=a.models.axis(),r=a.models.axis(),s=a.models.axis(),t=a.models.legend(),u=d3.svg.brush(),v=a.models.tooltip(),w={top:30,right:30,bottom:30,left:60},x={top:0,right:30,bottom:20,left:60},y=null,z=null,A=function(a){return a.x},B=function(a){return a.y},C=a.utils.defaultColor(),D=!0,E=!0,F=!1,G=!0,H=50,I=null,J=null,K=d3.dispatch("brush","stateChange","changeState"),L=0,M=a.utils.state(),N=null,O=" (left axis)",P=" (right axis)";j.clipEdge(!0),k.interactive(!1),n.orient("bottom").tickPadding(5),p.orient("left"),q.orient("right"),o.orient("bottom").tickPadding(5),r.orient("left"),s.orient("right"),v.headerEnabled(!0).headerFormatter(function(a,b){return n.tickFormat()(a,b)});var Q=function(a){return function(){return{active:a.map(function(a){return!a.disabled})}}},R=function(a){return function(b){void 0!==b.active&&a.forEach(function(a,c){a.disabled=!b.active[c]})}};return j.dispatch.on("elementMouseover.tooltip",function(a){v.duration(100).valueFormatter(function(a,b){return q.tickFormat()(a,b)}).data(a).position(a.pos).hidden(!1)}),j.dispatch.on("elementMouseout.tooltip",function(){v.hidden(!0)}),l.dispatch.on("elementMouseover.tooltip",function(a){a.value=b.x()(a.data),a.series={value:b.y()(a.data),color:a.color},v.duration(0).valueFormatter(function(a,b){return p.tickFormat()(a,b)}).data(a).hidden(!1)}),l.dispatch.on("elementMouseout.tooltip",function(){v.hidden(!0)}),l.dispatch.on("elementMousemove.tooltip",function(){v.position({top:d3.event.pageY,left:d3.event.pageX})()}),b.dispatch=K,b.legend=t,b.lines=j,b.lines2=k,b.bars=l,b.bars2=m,b.xAxis=n,b.x2Axis=o,b.y1Axis=p,b.y2Axis=q,b.y3Axis=r,b.y4Axis=s,b.tooltip=v,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return y},set:function(a){y=a}},height:{get:function(){return z},set:function(a){z=a}},showLegend:{get:function(){return D},set:function(a){D=a}},brushExtent:{get:function(){return I},set:function(a){I=a}},noData:{get:function(){return J},set:function(a){J=a}},focusEnable:{get:function(){return E},set:function(a){E=a}},focusHeight:{get:function(){return H},set:function(a){H=a}},focusShowAxisX:{get:function(){return G},set:function(a){G=a}},focusShowAxisY:{get:function(){return F},set:function(a){F=a}},legendLeftAxisHint:{get:function(){return O},set:function(a){O=a}},legendRightAxisHint:{get:function(){return P},set:function(a){P=a}},tooltips:{get:function(){return v.enabled()},set:function(b){a.deprecated("tooltips","use chart.tooltip.enabled() instead"),v.enabled(!!b)}},tooltipContent:{get:function(){return v.contentGenerator()},set:function(b){a.deprecated("tooltipContent","use chart.tooltip.contentGenerator() instead"),v.contentGenerator(b)}},margin:{get:function(){return w},set:function(a){w.top=void 0!==a.top?a.top:w.top,w.right=void 0!==a.right?a.right:w.right,w.bottom=void 0!==a.bottom?a.bottom:w.bottom,w.left=void 0!==a.left?a.left:w.left}},duration:{get:function(){return L},set:function(a){L=a}},color:{get:function(){return C},set:function(b){C=a.utils.getColor(b),t.color(C)}},x:{get:function(){return A},set:function(a){A=a,j.x(a),k.x(a),l.x(a),m.x(a)}},y:{get:function(){return B},set:function(a){B=a,j.y(a),k.y(a),l.y(a),m.y(a)}}}),a.utils.inheritOptions(b,j),a.utils.initOptions(b),b},a.models.lineWithFocusChart=function(){"use strict";function b(o){return o.each(function(o){function z(a){var b=+("e"==a),c=b?1:-1,d=M/3;return"M"+.5*c+","+d+"A6,6 0 0 "+b+" "+6.5*c+","+(d+6)+"V"+(2*d-6)+"A6,6 0 0 "+b+" "+.5*c+","+2*d+"ZM"+2.5*c+","+(d+8)+"V"+(2*d-8)+"M"+4.5*c+","+(d+8)+"V"+(2*d-8)}function G(){n.empty()||n.extent(y),U.data([n.empty()?e.domain():y]).each(function(a){var b=e(a[0])-c.range()[0],d=K-e(a[1]);d3.select(this).select(".left").attr("width",0>b?0:b),d3.select(this).select(".right").attr("x",e(a[1])).attr("width",0>d?0:d)})}function H(){y=n.empty()?null:n.extent();var a=n.empty()?e.domain():n.extent();if(!(Math.abs(a[0]-a[1])<=1)){A.brush({extent:a,brush:n}),G();var b=Q.select(".nv-focus .nv-linesWrap").datum(o.filter(function(a){return!a.disabled}).map(function(b){return{key:b.key,area:b.area,values:b.values.filter(function(b,c){return g.x()(b,c)>=a[0]&&g.x()(b,c)<=a[1]})}}));b.transition().duration(B).call(g),Q.select(".nv-focus .nv-x.nv-axis").transition().duration(B).call(i),Q.select(".nv-focus .nv-y.nv-axis").transition().duration(B).call(j)}}var I=d3.select(this),J=this;a.utils.initSVG(I);var K=a.utils.availableWidth(t,I,q),L=a.utils.availableHeight(u,I,q)-v,M=v-r.top-r.bottom;if(b.update=function(){I.transition().duration(B).call(b)},b.container=this,C.setter(F(o),b.update).getter(E(o)).update(),C.disabled=o.map(function(a){return!!a.disabled}),!D){var N;D={};for(N in C)D[N]=C[N]instanceof Array?C[N].slice(0):C[N]}if(!(o&&o.length&&o.filter(function(a){return a.values.length}).length))return a.utils.noData(b,I),b;I.selectAll(".nv-noData").remove(),c=g.xScale(),d=g.yScale(),e=h.xScale(),f=h.yScale();var O=I.selectAll("g.nv-wrap.nv-lineWithFocusChart").data([o]),P=O.enter().append("g").attr("class","nvd3 nv-wrap nv-lineWithFocusChart").append("g"),Q=O.select("g");P.append("g").attr("class","nv-legendWrap");var R=P.append("g").attr("class","nv-focus");R.append("g").attr("class","nv-x nv-axis"),R.append("g").attr("class","nv-y nv-axis"),R.append("g").attr("class","nv-linesWrap"),R.append("g").attr("class","nv-interactive");var S=P.append("g").attr("class","nv-context");S.append("g").attr("class","nv-x nv-axis"),S.append("g").attr("class","nv-y nv-axis"),S.append("g").attr("class","nv-linesWrap"),S.append("g").attr("class","nv-brushBackground"),S.append("g").attr("class","nv-x nv-brush"),x&&(m.width(K),Q.select(".nv-legendWrap").datum(o).call(m),q.top!=m.height()&&(q.top=m.height(),L=a.utils.availableHeight(u,I,q)-v),Q.select(".nv-legendWrap").attr("transform","translate(0,"+-q.top+")")),O.attr("transform","translate("+q.left+","+q.top+")"),w&&(p.width(K).height(L).margin({left:q.left,top:q.top}).svgContainer(I).xScale(c),O.select(".nv-interactive").call(p)),g.width(K).height(L).color(o.map(function(a,b){return a.color||s(a,b)}).filter(function(a,b){return!o[b].disabled})),h.defined(g.defined()).width(K).height(M).color(o.map(function(a,b){return a.color||s(a,b)}).filter(function(a,b){return!o[b].disabled})),Q.select(".nv-context").attr("transform","translate(0,"+(L+q.bottom+r.top)+")");var T=Q.select(".nv-context .nv-linesWrap").datum(o.filter(function(a){return!a.disabled}));d3.transition(T).call(h),i.scale(c)._ticks(a.utils.calcTicksX(K/100,o)).tickSize(-L,0),j.scale(d)._ticks(a.utils.calcTicksY(L/36,o)).tickSize(-K,0),Q.select(".nv-focus .nv-x.nv-axis").attr("transform","translate(0,"+L+")"),n.x(e).on("brush",function(){H()}),y&&n.extent(y);var U=Q.select(".nv-brushBackground").selectAll("g").data([y||n.extent()]),V=U.enter().append("g");V.append("rect").attr("class","left").attr("x",0).attr("y",0).attr("height",M),V.append("rect").attr("class","right").attr("x",0).attr("y",0).attr("height",M);var W=Q.select(".nv-x.nv-brush").call(n);W.selectAll("rect").attr("height",M),W.selectAll(".resize").append("path").attr("d",z),H(),k.scale(e)._ticks(a.utils.calcTicksX(K/100,o)).tickSize(-M,0),Q.select(".nv-context .nv-x.nv-axis").attr("transform","translate(0,"+f.range()[0]+")"),d3.transition(Q.select(".nv-context .nv-x.nv-axis")).call(k),l.scale(f)._ticks(a.utils.calcTicksY(M/36,o)).tickSize(-K,0),d3.transition(Q.select(".nv-context .nv-y.nv-axis")).call(l),Q.select(".nv-context .nv-x.nv-axis").attr("transform","translate(0,"+f.range()[0]+")"),m.dispatch.on("stateChange",function(a){for(var c in a)C[c]=a[c];A.stateChange(C),b.update()}),p.dispatch.on("elementMousemove",function(c){g.clearHighlights();var d,f,h,k=[];if(o.filter(function(a,b){return a.seriesIndex=b,!a.disabled}).forEach(function(i,j){var l=n.empty()?e.domain():n.extent(),m=i.values.filter(function(a,b){return g.x()(a,b)>=l[0]&&g.x()(a,b)<=l[1]});f=a.interactiveBisect(m,c.pointXValue,g.x());var o=m[f],p=b.y()(o,f);null!=p&&g.highlightPoint(j,f,!0),void 0!==o&&(void 0===d&&(d=o),void 0===h&&(h=b.xScale()(b.x()(o,f))),k.push({key:i.key,value:b.y()(o,f),color:s(i,i.seriesIndex)}))}),k.length>2){var l=b.yScale().invert(c.mouseY),m=Math.abs(b.yScale().domain()[0]-b.yScale().domain()[1]),r=.03*m,t=a.nearestValueIndex(k.map(function(a){return a.value}),l,r);null!==t&&(k[t].highlight=!0)}var u=i.tickFormat()(b.x()(d,f));p.tooltip.position({left:c.mouseX+q.left,top:c.mouseY+q.top}).chartContainer(J.parentNode).valueFormatter(function(a){return null==a?"N/A":j.tickFormat()(a)}).data({value:u,index:f,series:k})(),p.renderGuideLine(h)}),p.dispatch.on("elementMouseout",function(){g.clearHighlights()}),A.on("changeState",function(a){"undefined"!=typeof a.disabled&&o.forEach(function(b,c){b.disabled=a.disabled[c]}),b.update()})}),b}var c,d,e,f,g=a.models.line(),h=a.models.line(),i=a.models.axis(),j=a.models.axis(),k=a.models.axis(),l=a.models.axis(),m=a.models.legend(),n=d3.svg.brush(),o=a.models.tooltip(),p=a.interactiveGuideline(),q={top:30,right:30,bottom:30,left:60},r={top:0,right:30,bottom:20,left:60},s=a.utils.defaultColor(),t=null,u=null,v=50,w=!1,x=!0,y=null,z=null,A=d3.dispatch("brush","stateChange","changeState"),B=250,C=a.utils.state(),D=null;g.clipEdge(!0).duration(0),h.interactive(!1),i.orient("bottom").tickPadding(5),j.orient("left"),k.orient("bottom").tickPadding(5),l.orient("left"),o.valueFormatter(function(a,b){return j.tickFormat()(a,b)}).headerFormatter(function(a,b){return i.tickFormat()(a,b)});var E=function(a){return function(){return{active:a.map(function(a){return!a.disabled})}}},F=function(a){return function(b){void 0!==b.active&&a.forEach(function(a,c){a.disabled=!b.active[c]})}};return g.dispatch.on("elementMouseover.tooltip",function(a){o.data(a).position(a.pos).hidden(!1)}),g.dispatch.on("elementMouseout.tooltip",function(){o.hidden(!0)}),b.dispatch=A,b.legend=m,b.lines=g,b.lines2=h,b.xAxis=i,b.yAxis=j,b.x2Axis=k,b.y2Axis=l,b.interactiveLayer=p,b.tooltip=o,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return t},set:function(a){t=a}},height:{get:function(){return u},set:function(a){u=a}},focusHeight:{get:function(){return v},set:function(a){v=a}},showLegend:{get:function(){return x},set:function(a){x=a}},brushExtent:{get:function(){return y},set:function(a){y=a}},defaultState:{get:function(){return D},set:function(a){D=a}},noData:{get:function(){return z},set:function(a){z=a}},tooltips:{get:function(){return o.enabled()},set:function(b){a.deprecated("tooltips","use chart.tooltip.enabled() instead"),o.enabled(!!b)}},tooltipContent:{get:function(){return o.contentGenerator()},set:function(b){a.deprecated("tooltipContent","use chart.tooltip.contentGenerator() instead"),o.contentGenerator(b)}},margin:{get:function(){return q},set:function(a){q.top=void 0!==a.top?a.top:q.top,q.right=void 0!==a.right?a.right:q.right,q.bottom=void 0!==a.bottom?a.bottom:q.bottom,q.left=void 0!==a.left?a.left:q.left}},color:{get:function(){return s},set:function(b){s=a.utils.getColor(b),m.color(s)}},interpolate:{get:function(){return g.interpolate()},set:function(a){g.interpolate(a),h.interpolate(a)}},xTickFormat:{get:function(){return i.tickFormat()},set:function(a){i.tickFormat(a),k.tickFormat(a)}},yTickFormat:{get:function(){return j.tickFormat()},set:function(a){j.tickFormat(a),l.tickFormat(a)}},duration:{get:function(){return B},set:function(a){B=a,j.duration(B),l.duration(B),i.duration(B),k.duration(B)}},x:{get:function(){return g.x()},set:function(a){g.x(a),h.x(a)}},y:{get:function(){return g.y()},set:function(a){g.y(a),h.y(a)}},useInteractiveGuideline:{get:function(){return w},set:function(a){w=a,w&&(g.interactive(!1),g.useVoronoi(!1))}}}),a.utils.inheritOptions(b,g),a.utils.initOptions(b),b},a.models.multiBar=function(){"use strict";function b(E){return C.reset(),E.each(function(b){var E=k-j.left-j.right,F=l-j.top-j.bottom;p=d3.select(this),a.utils.initSVG(p);var G=0;if(x&&b.length&&(x=[{values:b[0].values.map(function(a){return{x:a.x,y:0,series:a.series,size:.01}})}]),u){var H=d3.layout.stack().offset(v).values(function(a){return a.values}).y(r)(!b.length&&x?x:b);H.forEach(function(a,c){a.nonStackable?(b[c].nonStackableSeries=G++,H[c]=b[c]):c>0&&H[c-1].nonStackable&&H[c].values.map(function(a,b){a.y0-=H[c-1].values[b].y,a.y1=a.y0+a.y})}),b=H}b.forEach(function(a,b){a.values.forEach(function(c){c.series=b,c.key=a.key})}),u&&b[0].values.map(function(a,c){var d=0,e=0;b.map(function(a,f){if(!b[f].nonStackable){var g=a.values[c];g.size=Math.abs(g.y),g.y<0?(g.y1=e,e-=g.size):(g.y1=g.size+d,d+=g.size)}})});var I=d&&e?[]:b.map(function(a,b){return a.values.map(function(a,c){return{x:q(a,c),y:r(a,c),y0:a.y0,y1:a.y1,idx:b}})});m.domain(d||d3.merge(I).map(function(a){return a.x})).rangeBands(f||[0,E],A),n.domain(e||d3.extent(d3.merge(I).map(function(a){var c=a.y;return u&&!b[a.idx].nonStackable&&(c=a.y>0?a.y1:a.y1+a.y),c}).concat(s))).range(g||[F,0]),m.domain()[0]===m.domain()[1]&&m.domain(m.domain()[0]?[m.domain()[0]-.01*m.domain()[0],m.domain()[1]+.01*m.domain()[1]]:[-1,1]),n.domain()[0]===n.domain()[1]&&n.domain(n.domain()[0]?[n.domain()[0]+.01*n.domain()[0],n.domain()[1]-.01*n.domain()[1]]:[-1,1]),h=h||m,i=i||n;var J=p.selectAll("g.nv-wrap.nv-multibar").data([b]),K=J.enter().append("g").attr("class","nvd3 nv-wrap nv-multibar"),L=K.append("defs"),M=K.append("g"),N=J.select("g");M.append("g").attr("class","nv-groups"),J.attr("transform","translate("+j.left+","+j.top+")"),L.append("clipPath").attr("id","nv-edge-clip-"+o).append("rect"),J.select("#nv-edge-clip-"+o+" rect").attr("width",E).attr("height",F),N.attr("clip-path",t?"url(#nv-edge-clip-"+o+")":"");var O=J.select(".nv-groups").selectAll(".nv-group").data(function(a){return a},function(a,b){return b});O.enter().append("g").style("stroke-opacity",1e-6).style("fill-opacity",1e-6);var P=C.transition(O.exit().selectAll("rect.nv-bar"),"multibarExit",Math.min(100,z)).attr("y",function(a){var c=i(0)||0;return u&&b[a.series]&&!b[a.series].nonStackable&&(c=i(a.y0)),c}).attr("height",0).remove();P.delay&&P.delay(function(a,b){var c=b*(z/(D+1))-b;return c}),O.attr("class",function(a,b){return"nv-group nv-series-"+b}).classed("hover",function(a){return a.hover}).style("fill",function(a,b){return w(a,b)}).style("stroke",function(a,b){return w(a,b)}),O.style("stroke-opacity",1).style("fill-opacity",.75);var Q=O.selectAll("rect.nv-bar").data(function(a){return x&&!b.length?x.values:a.values});Q.exit().remove();Q.enter().append("rect").attr("class",function(a,b){return r(a,b)<0?"nv-bar negative":"nv-bar positive"}).attr("x",function(a,c,d){return u&&!b[d].nonStackable?0:d*m.rangeBand()/b.length}).attr("y",function(a,c,d){return i(u&&!b[d].nonStackable?a.y0:0)||0}).attr("height",0).attr("width",function(a,c,d){return m.rangeBand()/(u&&!b[d].nonStackable?1:b.length)}).attr("transform",function(a,b){return"translate("+m(q(a,b))+",0)"});Q.style("fill",function(a,b,c){return w(a,c,b)}).style("stroke",function(a,b,c){return w(a,c,b)}).on("mouseover",function(a,b){d3.select(this).classed("hover",!0),B.elementMouseover({data:a,index:b,color:d3.select(this).style("fill")})}).on("mouseout",function(a,b){d3.select(this).classed("hover",!1),B.elementMouseout({data:a,index:b,color:d3.select(this).style("fill")})}).on("mousemove",function(a,b){B.elementMousemove({data:a,index:b,color:d3.select(this).style("fill")})}).on("click",function(a,b){B.elementClick({data:a,index:b,color:d3.select(this).style("fill")}),d3.event.stopPropagation()}).on("dblclick",function(a,b){B.elementDblClick({data:a,index:b,color:d3.select(this).style("fill")}),d3.event.stopPropagation()}),Q.attr("class",function(a,b){return r(a,b)<0?"nv-bar negative":"nv-bar positive"}).attr("transform",function(a,b){return"translate("+m(q(a,b))+",0)"}),y&&(c||(c=b.map(function(){return!0})),Q.style("fill",function(a,b,d){return d3.rgb(y(a,b)).darker(c.map(function(a,b){return b}).filter(function(a,b){return!c[b]})[d]).toString()}).style("stroke",function(a,b,d){return d3.rgb(y(a,b)).darker(c.map(function(a,b){return b}).filter(function(a,b){return!c[b]})[d]).toString()}));var R=Q.watchTransition(C,"multibar",Math.min(250,z)).delay(function(a,c){return c*z/b[0].values.length});u?R.attr("y",function(a,c,d){var e=0;return e=b[d].nonStackable?r(a,c)<0?n(0):n(0)-n(r(a,c))<-1?n(0)-1:n(r(a,c))||0:n(a.y1)}).attr("height",function(a,c,d){return b[d].nonStackable?Math.max(Math.abs(n(r(a,c))-n(0)),1)||0:Math.max(Math.abs(n(a.y+a.y0)-n(a.y0)),1)}).attr("x",function(a,c,d){var e=0;return b[d].nonStackable&&(e=a.series*m.rangeBand()/b.length,b.length!==G&&(e=b[d].nonStackableSeries*m.rangeBand()/(2*G))),e}).attr("width",function(a,c,d){if(b[d].nonStackable){var e=m.rangeBand()/G;return b.length!==G&&(e=m.rangeBand()/(2*G)),e}return m.rangeBand()}):R.attr("x",function(a){return a.series*m.rangeBand()/b.length}).attr("width",m.rangeBand()/b.length).attr("y",function(a,b){return r(a,b)<0?n(0):n(0)-n(r(a,b))<1?n(0)-1:n(r(a,b))||0}).attr("height",function(a,b){return Math.max(Math.abs(n(r(a,b))-n(0)),1)||0}),h=m.copy(),i=n.copy(),b[0]&&b[0].values&&(D=b[0].values.length)}),C.renderEnd("multibar immediate"),b}var c,d,e,f,g,h,i,j={top:0,right:0,bottom:0,left:0},k=960,l=500,m=d3.scale.ordinal(),n=d3.scale.linear(),o=Math.floor(1e4*Math.random()),p=null,q=function(a){return a.x},r=function(a){return a.y},s=[0],t=!0,u=!1,v="zero",w=a.utils.defaultColor(),x=!1,y=null,z=500,A=.1,B=d3.dispatch("chartClick","elementClick","elementDblClick","elementMouseover","elementMouseout","elementMousemove","renderEnd"),C=a.utils.renderWatch(B,z),D=0;return b.dispatch=B,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return k},set:function(a){k=a}},height:{get:function(){return l},set:function(a){l=a}},x:{get:function(){return q},set:function(a){q=a}},y:{get:function(){return r},set:function(a){r=a}},xScale:{get:function(){return m},set:function(a){m=a}},yScale:{get:function(){return n},set:function(a){n=a}},xDomain:{get:function(){return d},set:function(a){d=a}},yDomain:{get:function(){return e},set:function(a){e=a}},xRange:{get:function(){return f},set:function(a){f=a}},yRange:{get:function(){return g},set:function(a){g=a}},forceY:{get:function(){return s},set:function(a){s=a}},stacked:{get:function(){return u},set:function(a){u=a}},stackOffset:{get:function(){return v},set:function(a){v=a}},clipEdge:{get:function(){return t},set:function(a){t=a}},disabled:{get:function(){return c},set:function(a){c=a}},id:{get:function(){return o},set:function(a){o=a}},hideable:{get:function(){return x},set:function(a){x=a}},groupSpacing:{get:function(){return A},set:function(a){A=a}},margin:{get:function(){return j},set:function(a){j.top=void 0!==a.top?a.top:j.top,j.right=void 0!==a.right?a.right:j.right,j.bottom=void 0!==a.bottom?a.bottom:j.bottom,j.left=void 0!==a.left?a.left:j.left}},duration:{get:function(){return z},set:function(a){z=a,C.reset(z)}},color:{get:function(){return w},set:function(b){w=a.utils.getColor(b)}},barColor:{get:function(){return y},set:function(b){y=b?a.utils.getColor(b):null}}}),a.utils.initOptions(b),b},a.models.multiBarChart=function(){"use strict";function b(j){return D.reset(),D.models(e),r&&D.models(f),s&&D.models(g),j.each(function(j){var z=d3.select(this);a.utils.initSVG(z);var D=a.utils.availableWidth(l,z,k),H=a.utils.availableHeight(m,z,k);if(b.update=function(){0===C?z.call(b):z.transition().duration(C).call(b)},b.container=this,x.setter(G(j),b.update).getter(F(j)).update(),x.disabled=j.map(function(a){return!!a.disabled}),!y){var I;y={};for(I in x)y[I]=x[I]instanceof Array?x[I].slice(0):x[I]}if(!(j&&j.length&&j.filter(function(a){return a.values.length}).length))return a.utils.noData(b,z),b;z.selectAll(".nv-noData").remove(),c=e.xScale(),d=e.yScale(); -var J=z.selectAll("g.nv-wrap.nv-multiBarWithLegend").data([j]),K=J.enter().append("g").attr("class","nvd3 nv-wrap nv-multiBarWithLegend").append("g"),L=J.select("g");if(K.append("g").attr("class","nv-x nv-axis"),K.append("g").attr("class","nv-y nv-axis"),K.append("g").attr("class","nv-barsWrap"),K.append("g").attr("class","nv-legendWrap"),K.append("g").attr("class","nv-controlsWrap"),q&&(h.width(D-B()),L.select(".nv-legendWrap").datum(j).call(h),k.top!=h.height()&&(k.top=h.height(),H=a.utils.availableHeight(m,z,k)),L.select(".nv-legendWrap").attr("transform","translate("+B()+","+-k.top+")")),o){var M=[{key:p.grouped||"Grouped",disabled:e.stacked()},{key:p.stacked||"Stacked",disabled:!e.stacked()}];i.width(B()).color(["#444","#444","#444"]),L.select(".nv-controlsWrap").datum(M).attr("transform","translate(0,"+-k.top+")").call(i)}J.attr("transform","translate("+k.left+","+k.top+")"),t&&L.select(".nv-y.nv-axis").attr("transform","translate("+D+",0)"),e.disabled(j.map(function(a){return a.disabled})).width(D).height(H).color(j.map(function(a,b){return a.color||n(a,b)}).filter(function(a,b){return!j[b].disabled}));var N=L.select(".nv-barsWrap").datum(j.filter(function(a){return!a.disabled}));if(N.call(e),r){f.scale(c)._ticks(a.utils.calcTicksX(D/100,j)).tickSize(-H,0),L.select(".nv-x.nv-axis").attr("transform","translate(0,"+d.range()[0]+")"),L.select(".nv-x.nv-axis").call(f);var O=L.select(".nv-x.nv-axis > g").selectAll("g");if(O.selectAll("line, text").style("opacity",1),v){var P=function(a,b){return"translate("+a+","+b+")"},Q=5,R=17;O.selectAll("text").attr("transform",function(a,b,c){return P(0,c%2==0?Q:R)});var S=d3.selectAll(".nv-x.nv-axis .nv-wrap g g text")[0].length;L.selectAll(".nv-x.nv-axis .nv-axisMaxMin text").attr("transform",function(a,b){return P(0,0===b||S%2!==0?R:Q)})}u&&O.filter(function(a,b){return b%Math.ceil(j[0].values.length/(D/100))!==0}).selectAll("text, line").style("opacity",0),w&&O.selectAll(".tick text").attr("transform","rotate("+w+" 0,0)").style("text-anchor",w>0?"start":"end"),L.select(".nv-x.nv-axis").selectAll("g.nv-axisMaxMin text").style("opacity",1)}s&&(g.scale(d)._ticks(a.utils.calcTicksY(H/36,j)).tickSize(-D,0),L.select(".nv-y.nv-axis").call(g)),h.dispatch.on("stateChange",function(a){for(var c in a)x[c]=a[c];A.stateChange(x),b.update()}),i.dispatch.on("legendClick",function(a){if(a.disabled){switch(M=M.map(function(a){return a.disabled=!0,a}),a.disabled=!1,a.key){case"Grouped":case p.grouped:e.stacked(!1);break;case"Stacked":case p.stacked:e.stacked(!0)}x.stacked=e.stacked(),A.stateChange(x),b.update()}}),A.on("changeState",function(a){"undefined"!=typeof a.disabled&&(j.forEach(function(b,c){b.disabled=a.disabled[c]}),x.disabled=a.disabled),"undefined"!=typeof a.stacked&&(e.stacked(a.stacked),x.stacked=a.stacked,E=a.stacked),b.update()})}),D.renderEnd("multibarchart immediate"),b}var c,d,e=a.models.multiBar(),f=a.models.axis(),g=a.models.axis(),h=a.models.legend(),i=a.models.legend(),j=a.models.tooltip(),k={top:30,right:20,bottom:50,left:60},l=null,m=null,n=a.utils.defaultColor(),o=!0,p={},q=!0,r=!0,s=!0,t=!1,u=!0,v=!1,w=0,x=a.utils.state(),y=null,z=null,A=d3.dispatch("stateChange","changeState","renderEnd"),B=function(){return o?180:0},C=250;x.stacked=!1,e.stacked(!1),f.orient("bottom").tickPadding(7).showMaxMin(!1).tickFormat(function(a){return a}),g.orient(t?"right":"left").tickFormat(d3.format(",.1f")),j.duration(0).valueFormatter(function(a,b){return g.tickFormat()(a,b)}).headerFormatter(function(a,b){return f.tickFormat()(a,b)}),i.updateState(!1);var D=a.utils.renderWatch(A),E=!1,F=function(a){return function(){return{active:a.map(function(a){return!a.disabled}),stacked:E}}},G=function(a){return function(b){void 0!==b.stacked&&(E=b.stacked),void 0!==b.active&&a.forEach(function(a,c){a.disabled=!b.active[c]})}};return e.dispatch.on("elementMouseover.tooltip",function(a){a.value=b.x()(a.data),a.series={key:a.data.key,value:b.y()(a.data),color:a.color},j.data(a).hidden(!1)}),e.dispatch.on("elementMouseout.tooltip",function(){j.hidden(!0)}),e.dispatch.on("elementMousemove.tooltip",function(){j.position({top:d3.event.pageY,left:d3.event.pageX})()}),b.dispatch=A,b.multibar=e,b.legend=h,b.controls=i,b.xAxis=f,b.yAxis=g,b.state=x,b.tooltip=j,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return l},set:function(a){l=a}},height:{get:function(){return m},set:function(a){m=a}},showLegend:{get:function(){return q},set:function(a){q=a}},showControls:{get:function(){return o},set:function(a){o=a}},controlLabels:{get:function(){return p},set:function(a){p=a}},showXAxis:{get:function(){return r},set:function(a){r=a}},showYAxis:{get:function(){return s},set:function(a){s=a}},defaultState:{get:function(){return y},set:function(a){y=a}},noData:{get:function(){return z},set:function(a){z=a}},reduceXTicks:{get:function(){return u},set:function(a){u=a}},rotateLabels:{get:function(){return w},set:function(a){w=a}},staggerLabels:{get:function(){return v},set:function(a){v=a}},tooltips:{get:function(){return j.enabled()},set:function(b){a.deprecated("tooltips","use chart.tooltip.enabled() instead"),j.enabled(!!b)}},tooltipContent:{get:function(){return j.contentGenerator()},set:function(b){a.deprecated("tooltipContent","use chart.tooltip.contentGenerator() instead"),j.contentGenerator(b)}},margin:{get:function(){return k},set:function(a){k.top=void 0!==a.top?a.top:k.top,k.right=void 0!==a.right?a.right:k.right,k.bottom=void 0!==a.bottom?a.bottom:k.bottom,k.left=void 0!==a.left?a.left:k.left}},duration:{get:function(){return C},set:function(a){C=a,e.duration(C),f.duration(C),g.duration(C),D.reset(C)}},color:{get:function(){return n},set:function(b){n=a.utils.getColor(b),h.color(n)}},rightAlignYAxis:{get:function(){return t},set:function(a){t=a,g.orient(t?"right":"left")}},barColor:{get:function(){return e.barColor},set:function(a){e.barColor(a),h.color(function(a,b){return d3.rgb("#ccc").darker(1.5*b).toString()})}}}),a.utils.inheritOptions(b,e),a.utils.initOptions(b),b},a.models.multiBarHorizontal=function(){"use strict";function b(m){return E.reset(),m.each(function(b){var m=k-j.left-j.right,C=l-j.top-j.bottom;n=d3.select(this),a.utils.initSVG(n),w&&(b=d3.layout.stack().offset("zero").values(function(a){return a.values}).y(r)(b)),b.forEach(function(a,b){a.values.forEach(function(c){c.series=b,c.key=a.key})}),w&&b[0].values.map(function(a,c){var d=0,e=0;b.map(function(a){var b=a.values[c];b.size=Math.abs(b.y),b.y<0?(b.y1=e-b.size,e-=b.size):(b.y1=d,d+=b.size)})});var F=d&&e?[]:b.map(function(a){return a.values.map(function(a,b){return{x:q(a,b),y:r(a,b),y0:a.y0,y1:a.y1}})});o.domain(d||d3.merge(F).map(function(a){return a.x})).rangeBands(f||[0,C],A),p.domain(e||d3.extent(d3.merge(F).map(function(a){return w?a.y>0?a.y1+a.y:a.y1:a.y}).concat(t))),p.range(x&&!w?g||[p.domain()[0]<0?z:0,m-(p.domain()[1]>0?z:0)]:g||[0,m]),h=h||o,i=i||d3.scale.linear().domain(p.domain()).range([p(0),p(0)]);{var G=d3.select(this).selectAll("g.nv-wrap.nv-multibarHorizontal").data([b]),H=G.enter().append("g").attr("class","nvd3 nv-wrap nv-multibarHorizontal"),I=(H.append("defs"),H.append("g"));G.select("g")}I.append("g").attr("class","nv-groups"),G.attr("transform","translate("+j.left+","+j.top+")");var J=G.select(".nv-groups").selectAll(".nv-group").data(function(a){return a},function(a,b){return b});J.enter().append("g").style("stroke-opacity",1e-6).style("fill-opacity",1e-6),J.exit().watchTransition(E,"multibarhorizontal: exit groups").style("stroke-opacity",1e-6).style("fill-opacity",1e-6).remove(),J.attr("class",function(a,b){return"nv-group nv-series-"+b}).classed("hover",function(a){return a.hover}).style("fill",function(a,b){return u(a,b)}).style("stroke",function(a,b){return u(a,b)}),J.watchTransition(E,"multibarhorizontal: groups").style("stroke-opacity",1).style("fill-opacity",.75);var K=J.selectAll("g.nv-bar").data(function(a){return a.values});K.exit().remove();var L=K.enter().append("g").attr("transform",function(a,c,d){return"translate("+i(w?a.y0:0)+","+(w?0:d*o.rangeBand()/b.length+o(q(a,c)))+")"});L.append("rect").attr("width",0).attr("height",o.rangeBand()/(w?1:b.length)),K.on("mouseover",function(a,b){d3.select(this).classed("hover",!0),D.elementMouseover({data:a,index:b,color:d3.select(this).style("fill")})}).on("mouseout",function(a,b){d3.select(this).classed("hover",!1),D.elementMouseout({data:a,index:b,color:d3.select(this).style("fill")})}).on("mouseout",function(a,b){D.elementMouseout({data:a,index:b,color:d3.select(this).style("fill")})}).on("mousemove",function(a,b){D.elementMousemove({data:a,index:b,color:d3.select(this).style("fill")})}).on("click",function(a,b){D.elementClick({data:a,index:b,color:d3.select(this).style("fill")}),d3.event.stopPropagation()}).on("dblclick",function(a,b){D.elementDblClick({data:a,index:b,color:d3.select(this).style("fill")}),d3.event.stopPropagation()}),s(b[0],0)&&(L.append("polyline"),K.select("polyline").attr("fill","none").attr("points",function(a,c){var d=s(a,c),e=.8*o.rangeBand()/(2*(w?1:b.length));d=d.length?d:[-Math.abs(d),Math.abs(d)],d=d.map(function(a){return p(a)-p(0)});var f=[[d[0],-e],[d[0],e],[d[0],0],[d[1],0],[d[1],-e],[d[1],e]];return f.map(function(a){return a.join(",")}).join(" ")}).attr("transform",function(a,c){var d=o.rangeBand()/(2*(w?1:b.length));return"translate("+(r(a,c)<0?0:p(r(a,c))-p(0))+", "+d+")"})),L.append("text"),x&&!w?(K.select("text").attr("text-anchor",function(a,b){return r(a,b)<0?"end":"start"}).attr("y",o.rangeBand()/(2*b.length)).attr("dy",".32em").text(function(a,b){var c=B(r(a,b)),d=s(a,b);return void 0===d?c:d.length?c+"+"+B(Math.abs(d[1]))+"-"+B(Math.abs(d[0])):c+"±"+B(Math.abs(d))}),K.watchTransition(E,"multibarhorizontal: bars").select("text").attr("x",function(a,b){return r(a,b)<0?-4:p(r(a,b))-p(0)+4})):K.selectAll("text").text(""),y&&!w?(L.append("text").classed("nv-bar-label",!0),K.select("text.nv-bar-label").attr("text-anchor",function(a,b){return r(a,b)<0?"start":"end"}).attr("y",o.rangeBand()/(2*b.length)).attr("dy",".32em").text(function(a,b){return q(a,b)}),K.watchTransition(E,"multibarhorizontal: bars").select("text.nv-bar-label").attr("x",function(a,b){return r(a,b)<0?p(0)-p(r(a,b))+4:-4})):K.selectAll("text.nv-bar-label").text(""),K.attr("class",function(a,b){return r(a,b)<0?"nv-bar negative":"nv-bar positive"}),v&&(c||(c=b.map(function(){return!0})),K.style("fill",function(a,b,d){return d3.rgb(v(a,b)).darker(c.map(function(a,b){return b}).filter(function(a,b){return!c[b]})[d]).toString()}).style("stroke",function(a,b,d){return d3.rgb(v(a,b)).darker(c.map(function(a,b){return b}).filter(function(a,b){return!c[b]})[d]).toString()})),w?K.watchTransition(E,"multibarhorizontal: bars").attr("transform",function(a,b){return"translate("+p(a.y1)+","+o(q(a,b))+")"}).select("rect").attr("width",function(a,b){return Math.abs(p(r(a,b)+a.y0)-p(a.y0))}).attr("height",o.rangeBand()):K.watchTransition(E,"multibarhorizontal: bars").attr("transform",function(a,c){return"translate("+p(r(a,c)<0?r(a,c):0)+","+(a.series*o.rangeBand()/b.length+o(q(a,c)))+")"}).select("rect").attr("height",o.rangeBand()/b.length).attr("width",function(a,b){return Math.max(Math.abs(p(r(a,b))-p(0)),1)}),h=o.copy(),i=p.copy()}),E.renderEnd("multibarHorizontal immediate"),b}var c,d,e,f,g,h,i,j={top:0,right:0,bottom:0,left:0},k=960,l=500,m=Math.floor(1e4*Math.random()),n=null,o=d3.scale.ordinal(),p=d3.scale.linear(),q=function(a){return a.x},r=function(a){return a.y},s=function(a){return a.yErr},t=[0],u=a.utils.defaultColor(),v=null,w=!1,x=!1,y=!1,z=60,A=.1,B=d3.format(",.2f"),C=250,D=d3.dispatch("chartClick","elementClick","elementDblClick","elementMouseover","elementMouseout","elementMousemove","renderEnd"),E=a.utils.renderWatch(D,C);return b.dispatch=D,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return k},set:function(a){k=a}},height:{get:function(){return l},set:function(a){l=a}},x:{get:function(){return q},set:function(a){q=a}},y:{get:function(){return r},set:function(a){r=a}},yErr:{get:function(){return s},set:function(a){s=a}},xScale:{get:function(){return o},set:function(a){o=a}},yScale:{get:function(){return p},set:function(a){p=a}},xDomain:{get:function(){return d},set:function(a){d=a}},yDomain:{get:function(){return e},set:function(a){e=a}},xRange:{get:function(){return f},set:function(a){f=a}},yRange:{get:function(){return g},set:function(a){g=a}},forceY:{get:function(){return t},set:function(a){t=a}},stacked:{get:function(){return w},set:function(a){w=a}},showValues:{get:function(){return x},set:function(a){x=a}},disabled:{get:function(){return c},set:function(a){c=a}},id:{get:function(){return m},set:function(a){m=a}},valueFormat:{get:function(){return B},set:function(a){B=a}},valuePadding:{get:function(){return z},set:function(a){z=a}},groupSpacing:{get:function(){return A},set:function(a){A=a}},margin:{get:function(){return j},set:function(a){j.top=void 0!==a.top?a.top:j.top,j.right=void 0!==a.right?a.right:j.right,j.bottom=void 0!==a.bottom?a.bottom:j.bottom,j.left=void 0!==a.left?a.left:j.left}},duration:{get:function(){return C},set:function(a){C=a,E.reset(C)}},color:{get:function(){return u},set:function(b){u=a.utils.getColor(b)}},barColor:{get:function(){return v},set:function(b){v=b?a.utils.getColor(b):null}}}),a.utils.initOptions(b),b},a.models.multiBarHorizontalChart=function(){"use strict";function b(j){return C.reset(),C.models(e),r&&C.models(f),s&&C.models(g),j.each(function(j){var w=d3.select(this);a.utils.initSVG(w);var C=a.utils.availableWidth(l,w,k),D=a.utils.availableHeight(m,w,k);if(b.update=function(){w.transition().duration(z).call(b)},b.container=this,t=e.stacked(),u.setter(B(j),b.update).getter(A(j)).update(),u.disabled=j.map(function(a){return!!a.disabled}),!v){var E;v={};for(E in u)v[E]=u[E]instanceof Array?u[E].slice(0):u[E]}if(!(j&&j.length&&j.filter(function(a){return a.values.length}).length))return a.utils.noData(b,w),b;w.selectAll(".nv-noData").remove(),c=e.xScale(),d=e.yScale();var F=w.selectAll("g.nv-wrap.nv-multiBarHorizontalChart").data([j]),G=F.enter().append("g").attr("class","nvd3 nv-wrap nv-multiBarHorizontalChart").append("g"),H=F.select("g");if(G.append("g").attr("class","nv-x nv-axis"),G.append("g").attr("class","nv-y nv-axis").append("g").attr("class","nv-zeroLine").append("line"),G.append("g").attr("class","nv-barsWrap"),G.append("g").attr("class","nv-legendWrap"),G.append("g").attr("class","nv-controlsWrap"),q&&(h.width(C-y()),H.select(".nv-legendWrap").datum(j).call(h),k.top!=h.height()&&(k.top=h.height(),D=a.utils.availableHeight(m,w,k)),H.select(".nv-legendWrap").attr("transform","translate("+y()+","+-k.top+")")),o){var I=[{key:p.grouped||"Grouped",disabled:e.stacked()},{key:p.stacked||"Stacked",disabled:!e.stacked()}];i.width(y()).color(["#444","#444","#444"]),H.select(".nv-controlsWrap").datum(I).attr("transform","translate(0,"+-k.top+")").call(i)}F.attr("transform","translate("+k.left+","+k.top+")"),e.disabled(j.map(function(a){return a.disabled})).width(C).height(D).color(j.map(function(a,b){return a.color||n(a,b)}).filter(function(a,b){return!j[b].disabled}));var J=H.select(".nv-barsWrap").datum(j.filter(function(a){return!a.disabled}));if(J.transition().call(e),r){f.scale(c)._ticks(a.utils.calcTicksY(D/24,j)).tickSize(-C,0),H.select(".nv-x.nv-axis").call(f);var K=H.select(".nv-x.nv-axis").selectAll("g");K.selectAll("line, text")}s&&(g.scale(d)._ticks(a.utils.calcTicksX(C/100,j)).tickSize(-D,0),H.select(".nv-y.nv-axis").attr("transform","translate(0,"+D+")"),H.select(".nv-y.nv-axis").call(g)),H.select(".nv-zeroLine line").attr("x1",d(0)).attr("x2",d(0)).attr("y1",0).attr("y2",-D),h.dispatch.on("stateChange",function(a){for(var c in a)u[c]=a[c];x.stateChange(u),b.update()}),i.dispatch.on("legendClick",function(a){if(a.disabled){switch(I=I.map(function(a){return a.disabled=!0,a}),a.disabled=!1,a.key){case"Grouped":e.stacked(!1);break;case"Stacked":e.stacked(!0)}u.stacked=e.stacked(),x.stateChange(u),t=e.stacked(),b.update()}}),x.on("changeState",function(a){"undefined"!=typeof a.disabled&&(j.forEach(function(b,c){b.disabled=a.disabled[c]}),u.disabled=a.disabled),"undefined"!=typeof a.stacked&&(e.stacked(a.stacked),u.stacked=a.stacked,t=a.stacked),b.update()})}),C.renderEnd("multibar horizontal chart immediate"),b}var c,d,e=a.models.multiBarHorizontal(),f=a.models.axis(),g=a.models.axis(),h=a.models.legend().height(30),i=a.models.legend().height(30),j=a.models.tooltip(),k={top:30,right:20,bottom:50,left:60},l=null,m=null,n=a.utils.defaultColor(),o=!0,p={},q=!0,r=!0,s=!0,t=!1,u=a.utils.state(),v=null,w=null,x=d3.dispatch("stateChange","changeState","renderEnd"),y=function(){return o?180:0},z=250;u.stacked=!1,e.stacked(t),f.orient("left").tickPadding(5).showMaxMin(!1).tickFormat(function(a){return a}),g.orient("bottom").tickFormat(d3.format(",.1f")),j.duration(0).valueFormatter(function(a,b){return g.tickFormat()(a,b)}).headerFormatter(function(a,b){return f.tickFormat()(a,b)}),i.updateState(!1);var A=function(a){return function(){return{active:a.map(function(a){return!a.disabled}),stacked:t}}},B=function(a){return function(b){void 0!==b.stacked&&(t=b.stacked),void 0!==b.active&&a.forEach(function(a,c){a.disabled=!b.active[c]})}},C=a.utils.renderWatch(x,z);return e.dispatch.on("elementMouseover.tooltip",function(a){a.value=b.x()(a.data),a.series={key:a.data.key,value:b.y()(a.data),color:a.color},j.data(a).hidden(!1)}),e.dispatch.on("elementMouseout.tooltip",function(){j.hidden(!0)}),e.dispatch.on("elementMousemove.tooltip",function(){j.position({top:d3.event.pageY,left:d3.event.pageX})()}),b.dispatch=x,b.multibar=e,b.legend=h,b.controls=i,b.xAxis=f,b.yAxis=g,b.state=u,b.tooltip=j,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return l},set:function(a){l=a}},height:{get:function(){return m},set:function(a){m=a}},showLegend:{get:function(){return q},set:function(a){q=a}},showControls:{get:function(){return o},set:function(a){o=a}},controlLabels:{get:function(){return p},set:function(a){p=a}},showXAxis:{get:function(){return r},set:function(a){r=a}},showYAxis:{get:function(){return s},set:function(a){s=a}},defaultState:{get:function(){return v},set:function(a){v=a}},noData:{get:function(){return w},set:function(a){w=a}},tooltips:{get:function(){return j.enabled()},set:function(b){a.deprecated("tooltips","use chart.tooltip.enabled() instead"),j.enabled(!!b)}},tooltipContent:{get:function(){return j.contentGenerator()},set:function(b){a.deprecated("tooltipContent","use chart.tooltip.contentGenerator() instead"),j.contentGenerator(b)}},margin:{get:function(){return k},set:function(a){k.top=void 0!==a.top?a.top:k.top,k.right=void 0!==a.right?a.right:k.right,k.bottom=void 0!==a.bottom?a.bottom:k.bottom,k.left=void 0!==a.left?a.left:k.left}},duration:{get:function(){return z},set:function(a){z=a,C.reset(z),e.duration(z),f.duration(z),g.duration(z)}},color:{get:function(){return n},set:function(b){n=a.utils.getColor(b),h.color(n)}},barColor:{get:function(){return e.barColor},set:function(a){e.barColor(a),h.color(function(a,b){return d3.rgb("#ccc").darker(1.5*b).toString()})}}}),a.utils.inheritOptions(b,e),a.utils.initOptions(b),b},a.models.multiChart=function(){"use strict";function b(j){return j.each(function(j){function k(a){var b=2===j[a.seriesIndex].yAxis?z:y;a.value=a.point.x,a.series={value:a.point.y,color:a.point.color},B.duration(100).valueFormatter(function(a,c){return b.tickFormat()(a,c)}).data(a).position(a.pos).hidden(!1)}function l(a){var b=2===j[a.seriesIndex].yAxis?z:y;a.point.x=v.x()(a.point),a.point.y=v.y()(a.point),B.duration(100).valueFormatter(function(a,c){return b.tickFormat()(a,c)}).data(a).position(a.pos).hidden(!1)}function n(a){var b=2===j[a.data.series].yAxis?z:y;a.value=t.x()(a.data),a.series={value:t.y()(a.data),color:a.color},B.duration(0).valueFormatter(function(a,c){return b.tickFormat()(a,c)}).data(a).hidden(!1)}var C=d3.select(this);a.utils.initSVG(C),b.update=function(){C.transition().call(b)},b.container=this;var D=a.utils.availableWidth(g,C,e),E=a.utils.availableHeight(h,C,e),F=j.filter(function(a){return"line"==a.type&&1==a.yAxis}),G=j.filter(function(a){return"line"==a.type&&2==a.yAxis}),H=j.filter(function(a){return"bar"==a.type&&1==a.yAxis}),I=j.filter(function(a){return"bar"==a.type&&2==a.yAxis}),J=j.filter(function(a){return"area"==a.type&&1==a.yAxis}),K=j.filter(function(a){return"area"==a.type&&2==a.yAxis});if(!(j&&j.length&&j.filter(function(a){return a.values.length}).length))return a.utils.noData(b,C),b;C.selectAll(".nv-noData").remove();var L=j.filter(function(a){return!a.disabled&&1==a.yAxis}).map(function(a){return a.values.map(function(a){return{x:a.x,y:a.y}})}),M=j.filter(function(a){return!a.disabled&&2==a.yAxis}).map(function(a){return a.values.map(function(a){return{x:a.x,y:a.y}})});o.domain(d3.extent(d3.merge(L.concat(M)),function(a){return a.x})).range([0,D]);var N=C.selectAll("g.wrap.multiChart").data([j]),O=N.enter().append("g").attr("class","wrap nvd3 multiChart").append("g");O.append("g").attr("class","nv-x nv-axis"),O.append("g").attr("class","nv-y1 nv-axis"),O.append("g").attr("class","nv-y2 nv-axis"),O.append("g").attr("class","lines1Wrap"),O.append("g").attr("class","lines2Wrap"),O.append("g").attr("class","bars1Wrap"),O.append("g").attr("class","bars2Wrap"),O.append("g").attr("class","stack1Wrap"),O.append("g").attr("class","stack2Wrap"),O.append("g").attr("class","legendWrap");var P=N.select("g"),Q=j.map(function(a,b){return j[b].color||f(a,b)});if(i){var R=A.align()?D/2:D,S=A.align()?R:0;A.width(R),A.color(Q),P.select(".legendWrap").datum(j.map(function(a){return a.originalKey=void 0===a.originalKey?a.key:a.originalKey,a.key=a.originalKey+(1==a.yAxis?"":" (right axis)"),a})).call(A),e.top!=A.height()&&(e.top=A.height(),E=a.utils.availableHeight(h,C,e)),P.select(".legendWrap").attr("transform","translate("+S+","+-e.top+")")}r.width(D).height(E).interpolate(m).color(Q.filter(function(a,b){return!j[b].disabled&&1==j[b].yAxis&&"line"==j[b].type})),s.width(D).height(E).interpolate(m).color(Q.filter(function(a,b){return!j[b].disabled&&2==j[b].yAxis&&"line"==j[b].type})),t.width(D).height(E).color(Q.filter(function(a,b){return!j[b].disabled&&1==j[b].yAxis&&"bar"==j[b].type})),u.width(D).height(E).color(Q.filter(function(a,b){return!j[b].disabled&&2==j[b].yAxis&&"bar"==j[b].type})),v.width(D).height(E).color(Q.filter(function(a,b){return!j[b].disabled&&1==j[b].yAxis&&"area"==j[b].type})),w.width(D).height(E).color(Q.filter(function(a,b){return!j[b].disabled&&2==j[b].yAxis&&"area"==j[b].type})),P.attr("transform","translate("+e.left+","+e.top+")");var T=P.select(".lines1Wrap").datum(F.filter(function(a){return!a.disabled})),U=P.select(".bars1Wrap").datum(H.filter(function(a){return!a.disabled})),V=P.select(".stack1Wrap").datum(J.filter(function(a){return!a.disabled})),W=P.select(".lines2Wrap").datum(G.filter(function(a){return!a.disabled})),X=P.select(".bars2Wrap").datum(I.filter(function(a){return!a.disabled})),Y=P.select(".stack2Wrap").datum(K.filter(function(a){return!a.disabled})),Z=J.length?J.map(function(a){return a.values}).reduce(function(a,b){return a.map(function(a,c){return{x:a.x,y:a.y+b[c].y}})}).concat([{x:0,y:0}]):[],$=K.length?K.map(function(a){return a.values}).reduce(function(a,b){return a.map(function(a,c){return{x:a.x,y:a.y+b[c].y}})}).concat([{x:0,y:0}]):[];p.domain(c||d3.extent(d3.merge(L).concat(Z),function(a){return a.y})).range([0,E]),q.domain(d||d3.extent(d3.merge(M).concat($),function(a){return a.y})).range([0,E]),r.yDomain(p.domain()),t.yDomain(p.domain()),v.yDomain(p.domain()),s.yDomain(q.domain()),u.yDomain(q.domain()),w.yDomain(q.domain()),J.length&&d3.transition(V).call(v),K.length&&d3.transition(Y).call(w),H.length&&d3.transition(U).call(t),I.length&&d3.transition(X).call(u),F.length&&d3.transition(T).call(r),G.length&&d3.transition(W).call(s),x._ticks(a.utils.calcTicksX(D/100,j)).tickSize(-E,0),P.select(".nv-x.nv-axis").attr("transform","translate(0,"+E+")"),d3.transition(P.select(".nv-x.nv-axis")).call(x),y._ticks(a.utils.calcTicksY(E/36,j)).tickSize(-D,0),d3.transition(P.select(".nv-y1.nv-axis")).call(y),z._ticks(a.utils.calcTicksY(E/36,j)).tickSize(-D,0),d3.transition(P.select(".nv-y2.nv-axis")).call(z),P.select(".nv-y1.nv-axis").classed("nv-disabled",L.length?!1:!0).attr("transform","translate("+o.range()[0]+",0)"),P.select(".nv-y2.nv-axis").classed("nv-disabled",M.length?!1:!0).attr("transform","translate("+o.range()[1]+",0)"),A.dispatch.on("stateChange",function(){b.update()}),r.dispatch.on("elementMouseover.tooltip",k),s.dispatch.on("elementMouseover.tooltip",k),r.dispatch.on("elementMouseout.tooltip",function(){B.hidden(!0)}),s.dispatch.on("elementMouseout.tooltip",function(){B.hidden(!0)}),v.dispatch.on("elementMouseover.tooltip",l),w.dispatch.on("elementMouseover.tooltip",l),v.dispatch.on("elementMouseout.tooltip",function(){B.hidden(!0)}),w.dispatch.on("elementMouseout.tooltip",function(){B.hidden(!0)}),t.dispatch.on("elementMouseover.tooltip",n),u.dispatch.on("elementMouseover.tooltip",n),t.dispatch.on("elementMouseout.tooltip",function(){B.hidden(!0)}),u.dispatch.on("elementMouseout.tooltip",function(){B.hidden(!0)}),t.dispatch.on("elementMousemove.tooltip",function(){B.position({top:d3.event.pageY,left:d3.event.pageX})()}),u.dispatch.on("elementMousemove.tooltip",function(){B.position({top:d3.event.pageY,left:d3.event.pageX})()})}),b}var c,d,e={top:30,right:20,bottom:50,left:60},f=a.utils.defaultColor(),g=null,h=null,i=!0,j=null,k=function(a){return a.x},l=function(a){return a.y},m="monotone",n=!0,o=d3.scale.linear(),p=d3.scale.linear(),q=d3.scale.linear(),r=a.models.line().yScale(p),s=a.models.line().yScale(q),t=a.models.multiBar().stacked(!1).yScale(p),u=a.models.multiBar().stacked(!1).yScale(q),v=a.models.stackedArea().yScale(p),w=a.models.stackedArea().yScale(q),x=a.models.axis().scale(o).orient("bottom").tickPadding(5),y=a.models.axis().scale(p).orient("left"),z=a.models.axis().scale(q).orient("right"),A=a.models.legend().height(30),B=a.models.tooltip(),C=d3.dispatch();return b.dispatch=C,b.lines1=r,b.lines2=s,b.bars1=t,b.bars2=u,b.stack1=v,b.stack2=w,b.xAxis=x,b.yAxis1=y,b.yAxis2=z,b.tooltip=B,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return g},set:function(a){g=a}},height:{get:function(){return h},set:function(a){h=a}},showLegend:{get:function(){return i},set:function(a){i=a}},yDomain1:{get:function(){return c},set:function(a){c=a}},yDomain2:{get:function(){return d},set:function(a){d=a}},noData:{get:function(){return j},set:function(a){j=a}},interpolate:{get:function(){return m},set:function(a){m=a}},tooltips:{get:function(){return B.enabled()},set:function(b){a.deprecated("tooltips","use chart.tooltip.enabled() instead"),B.enabled(!!b)}},tooltipContent:{get:function(){return B.contentGenerator()},set:function(b){a.deprecated("tooltipContent","use chart.tooltip.contentGenerator() instead"),B.contentGenerator(b)}},margin:{get:function(){return e},set:function(a){e.top=void 0!==a.top?a.top:e.top,e.right=void 0!==a.right?a.right:e.right,e.bottom=void 0!==a.bottom?a.bottom:e.bottom,e.left=void 0!==a.left?a.left:e.left}},color:{get:function(){return f},set:function(b){f=a.utils.getColor(b)}},x:{get:function(){return k},set:function(a){k=a,r.x(a),s.x(a),t.x(a),u.x(a),v.x(a),w.x(a)}},y:{get:function(){return l},set:function(a){l=a,r.y(a),s.y(a),v.y(a),w.y(a),t.y(a),u.y(a)}},useVoronoi:{get:function(){return n},set:function(a){n=a,r.useVoronoi(a),s.useVoronoi(a),v.useVoronoi(a),w.useVoronoi(a)}}}),a.utils.initOptions(b),b},a.models.ohlcBar=function(){"use strict";function b(y){return y.each(function(b){k=d3.select(this);var y=a.utils.availableWidth(h,k,g),A=a.utils.availableHeight(i,k,g);a.utils.initSVG(k);var B=y/b[0].values.length*.9;l.domain(c||d3.extent(b[0].values.map(n).concat(t))),l.range(v?e||[.5*y/b[0].values.length,y*(b[0].values.length-.5)/b[0].values.length]:e||[5+B/2,y-B/2-5]),m.domain(d||[d3.min(b[0].values.map(s).concat(u)),d3.max(b[0].values.map(r).concat(u))]).range(f||[A,0]),l.domain()[0]===l.domain()[1]&&l.domain(l.domain()[0]?[l.domain()[0]-.01*l.domain()[0],l.domain()[1]+.01*l.domain()[1]]:[-1,1]),m.domain()[0]===m.domain()[1]&&m.domain(m.domain()[0]?[m.domain()[0]+.01*m.domain()[0],m.domain()[1]-.01*m.domain()[1]]:[-1,1]);var C=d3.select(this).selectAll("g.nv-wrap.nv-ohlcBar").data([b[0].values]),D=C.enter().append("g").attr("class","nvd3 nv-wrap nv-ohlcBar"),E=D.append("defs"),F=D.append("g"),G=C.select("g");F.append("g").attr("class","nv-ticks"),C.attr("transform","translate("+g.left+","+g.top+")"),k.on("click",function(a,b){z.chartClick({data:a,index:b,pos:d3.event,id:j})}),E.append("clipPath").attr("id","nv-chart-clip-path-"+j).append("rect"),C.select("#nv-chart-clip-path-"+j+" rect").attr("width",y).attr("height",A),G.attr("clip-path",w?"url(#nv-chart-clip-path-"+j+")":"");var H=C.select(".nv-ticks").selectAll(".nv-tick").data(function(a){return a});H.exit().remove(),H.enter().append("path").attr("class",function(a,b,c){return(p(a,b)>q(a,b)?"nv-tick negative":"nv-tick positive")+" nv-tick-"+c+"-"+b}).attr("d",function(a,b){return"m0,0l0,"+(m(p(a,b))-m(r(a,b)))+"l"+-B/2+",0l"+B/2+",0l0,"+(m(s(a,b))-m(p(a,b)))+"l0,"+(m(q(a,b))-m(s(a,b)))+"l"+B/2+",0l"+-B/2+",0z"}).attr("transform",function(a,b){return"translate("+l(n(a,b))+","+m(r(a,b))+")"}).attr("fill",function(){return x[0]}).attr("stroke",function(){return x[0]}).attr("x",0).attr("y",function(a,b){return m(Math.max(0,o(a,b)))}).attr("height",function(a,b){return Math.abs(m(o(a,b))-m(0))}),H.attr("class",function(a,b,c){return(p(a,b)>q(a,b)?"nv-tick negative":"nv-tick positive")+" nv-tick-"+c+"-"+b}),d3.transition(H).attr("transform",function(a,b){return"translate("+l(n(a,b))+","+m(r(a,b))+")"}).attr("d",function(a,c){var d=y/b[0].values.length*.9;return"m0,0l0,"+(m(p(a,c))-m(r(a,c)))+"l"+-d/2+",0l"+d/2+",0l0,"+(m(s(a,c))-m(p(a,c)))+"l0,"+(m(q(a,c))-m(s(a,c)))+"l"+d/2+",0l"+-d/2+",0z"})}),b}var c,d,e,f,g={top:0,right:0,bottom:0,left:0},h=null,i=null,j=Math.floor(1e4*Math.random()),k=null,l=d3.scale.linear(),m=d3.scale.linear(),n=function(a){return a.x},o=function(a){return a.y},p=function(a){return a.open},q=function(a){return a.close},r=function(a){return a.high},s=function(a){return a.low},t=[],u=[],v=!1,w=!0,x=a.utils.defaultColor(),y=!1,z=d3.dispatch("tooltipShow","tooltipHide","stateChange","changeState","renderEnd","chartClick","elementClick","elementDblClick","elementMouseover","elementMouseout","elementMousemove");return b.highlightPoint=function(a,c){b.clearHighlights(),k.select(".nv-ohlcBar .nv-tick-0-"+a).classed("hover",c)},b.clearHighlights=function(){k.select(".nv-ohlcBar .nv-tick.hover").classed("hover",!1)},b.dispatch=z,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return h},set:function(a){h=a}},height:{get:function(){return i},set:function(a){i=a}},xScale:{get:function(){return l},set:function(a){l=a}},yScale:{get:function(){return m},set:function(a){m=a}},xDomain:{get:function(){return c},set:function(a){c=a}},yDomain:{get:function(){return d},set:function(a){d=a}},xRange:{get:function(){return e},set:function(a){e=a}},yRange:{get:function(){return f},set:function(a){f=a}},forceX:{get:function(){return t},set:function(a){t=a}},forceY:{get:function(){return u},set:function(a){u=a}},padData:{get:function(){return v},set:function(a){v=a}},clipEdge:{get:function(){return w},set:function(a){w=a}},id:{get:function(){return j},set:function(a){j=a}},interactive:{get:function(){return y},set:function(a){y=a}},x:{get:function(){return n},set:function(a){n=a}},y:{get:function(){return o},set:function(a){o=a}},open:{get:function(){return p()},set:function(a){p=a}},close:{get:function(){return q()},set:function(a){q=a}},high:{get:function(){return r},set:function(a){r=a}},low:{get:function(){return s},set:function(a){s=a}},margin:{get:function(){return g},set:function(a){g.top=void 0!=a.top?a.top:g.top,g.right=void 0!=a.right?a.right:g.right,g.bottom=void 0!=a.bottom?a.bottom:g.bottom,g.left=void 0!=a.left?a.left:g.left -}},color:{get:function(){return x},set:function(b){x=a.utils.getColor(b)}}}),a.utils.initOptions(b),b},a.models.parallelCoordinates=function(){"use strict";function b(p){return p.each(function(b){function p(a){return F(h.map(function(b){if(isNaN(a[b])||isNaN(parseFloat(a[b]))){var c=g[b].domain(),d=g[b].range(),e=c[0]-(c[1]-c[0])/9;if(J.indexOf(b)<0){var h=d3.scale.linear().domain([e,c[1]]).range([x-12,d[1]]);g[b].brush.y(h),J.push(b)}return[f(b),g[b](e)]}return J.length>0?(D.style("display","inline"),E.style("display","inline")):(D.style("display","none"),E.style("display","none")),[f(b),g[b](a[b])]}))}function q(){var a=h.filter(function(a){return!g[a].brush.empty()}),b=a.map(function(a){return g[a].brush.extent()});k=[],a.forEach(function(a,c){k[c]={dimension:a,extent:b[c]}}),l=[],M.style("display",function(c){var d=a.every(function(a,d){return isNaN(c[a])&&b[d][0]==g[a].brush.y().domain()[0]?!0:b[d][0]<=c[a]&&c[a]<=b[d][1]});return d&&l.push(c),d?null:"none"}),o.brush({filters:k,active:l})}function r(a){m[a]=this.parentNode.__origin__=f(a),L.attr("visibility","hidden")}function s(a){m[a]=Math.min(w,Math.max(0,this.parentNode.__origin__+=d3.event.x)),M.attr("d",p),h.sort(function(a,b){return u(a)-u(b)}),f.domain(h),N.attr("transform",function(a){return"translate("+u(a)+")"})}function t(a){delete this.parentNode.__origin__,delete m[a],d3.select(this.parentNode).attr("transform","translate("+f(a)+")"),M.attr("d",p),L.attr("d",p).attr("visibility",null)}function u(a){var b=m[a];return null==b?f(a):b}var v=d3.select(this),w=a.utils.availableWidth(d,v,c),x=a.utils.availableHeight(e,v,c);a.utils.initSVG(v),l=b,f.rangePoints([0,w],1).domain(h);var y={};h.forEach(function(a){var c=d3.extent(b,function(b){return+b[a]});return y[a]=!1,void 0===c[0]&&(y[a]=!0,c[0]=0,c[1]=0),c[0]===c[1]&&(c[0]=c[0]-1,c[1]=c[1]+1),g[a]=d3.scale.linear().domain(c).range([.9*(x-12),0]),g[a].brush=d3.svg.brush().y(g[a]).on("brush",q),"name"!=a});var z=v.selectAll("g.nv-wrap.nv-parallelCoordinates").data([b]),A=z.enter().append("g").attr("class","nvd3 nv-wrap nv-parallelCoordinates"),B=A.append("g"),C=z.select("g");B.append("g").attr("class","nv-parallelCoordinates background"),B.append("g").attr("class","nv-parallelCoordinates foreground"),B.append("g").attr("class","nv-parallelCoordinates missingValuesline"),z.attr("transform","translate("+c.left+","+c.top+")");var D,E,F=d3.svg.line().interpolate("cardinal").tension(n),G=d3.svg.axis().orient("left"),H=d3.behavior.drag().on("dragstart",r).on("drag",s).on("dragend",t),I=f.range()[1]-f.range()[0],J=[],K=[0+I/2,x-12,w-I/2,x-12];D=z.select(".missingValuesline").selectAll("line").data([K]),D.enter().append("line"),D.exit().remove(),D.attr("x1",function(a){return a[0]}).attr("y1",function(a){return a[1]}).attr("x2",function(a){return a[2]}).attr("y2",function(a){return a[3]}),E=z.select(".missingValuesline").selectAll("text").data(["undefined values"]),E.append("text").data(["undefined values"]),E.enter().append("text"),E.exit().remove(),E.attr("y",x).attr("x",w-92-I/2).text(function(a){return a});var L=z.select(".background").selectAll("path").data(b);L.enter().append("path"),L.exit().remove(),L.attr("d",p);var M=z.select(".foreground").selectAll("path").data(b);M.enter().append("path"),M.exit().remove(),M.attr("d",p).attr("stroke",j),M.on("mouseover",function(a,b){d3.select(this).classed("hover",!0),o.elementMouseover({label:a.name,data:a.data,index:b,pos:[d3.mouse(this.parentNode)[0],d3.mouse(this.parentNode)[1]]})}),M.on("mouseout",function(a,b){d3.select(this).classed("hover",!1),o.elementMouseout({label:a.name,data:a.data,index:b})});var N=C.selectAll(".dimension").data(h),O=N.enter().append("g").attr("class","nv-parallelCoordinates dimension");O.append("g").attr("class","nv-parallelCoordinates nv-axis"),O.append("g").attr("class","nv-parallelCoordinates-brush"),O.append("text").attr("class","nv-parallelCoordinates nv-label"),N.attr("transform",function(a){return"translate("+f(a)+",0)"}),N.exit().remove(),N.select(".nv-label").style("cursor","move").attr("dy","-1em").attr("text-anchor","middle").text(String).on("mouseover",function(a){o.elementMouseover({dim:a,pos:[d3.mouse(this.parentNode.parentNode)[0],d3.mouse(this.parentNode.parentNode)[1]]})}).on("mouseout",function(a){o.elementMouseout({dim:a})}).call(H),N.select(".nv-axis").each(function(a,b){d3.select(this).call(G.scale(g[a]).tickFormat(d3.format(i[b])))}),N.select(".nv-parallelCoordinates-brush").each(function(a){d3.select(this).call(g[a].brush)}).selectAll("rect").attr("x",-8).attr("width",16)}),b}var c={top:30,right:0,bottom:10,left:0},d=null,e=null,f=d3.scale.ordinal(),g={},h=[],i=[],j=a.utils.defaultColor(),k=[],l=[],m=[],n=1,o=d3.dispatch("brush","elementMouseover","elementMouseout");return b.dispatch=o,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return d},set:function(a){d=a}},height:{get:function(){return e},set:function(a){e=a}},dimensionNames:{get:function(){return h},set:function(a){h=a}},dimensionFormats:{get:function(){return i},set:function(a){i=a}},lineTension:{get:function(){return n},set:function(a){n=a}},dimensions:{get:function(){return h},set:function(b){a.deprecated("dimensions","use dimensionNames instead"),h=b}},margin:{get:function(){return c},set:function(a){c.top=void 0!==a.top?a.top:c.top,c.right=void 0!==a.right?a.right:c.right,c.bottom=void 0!==a.bottom?a.bottom:c.bottom,c.left=void 0!==a.left?a.left:c.left}},color:{get:function(){return j},set:function(b){j=a.utils.getColor(b)}}}),a.utils.initOptions(b),b},a.models.pie=function(){"use strict";function b(E){return D.reset(),E.each(function(b){function E(a,b){a.endAngle=isNaN(a.endAngle)?0:a.endAngle,a.startAngle=isNaN(a.startAngle)?0:a.startAngle,p||(a.innerRadius=0);var c=d3.interpolate(this._current,a);return this._current=c(0),function(a){return B[b](c(a))}}var F=d-c.left-c.right,G=e-c.top-c.bottom,H=Math.min(F,G)/2,I=[],J=[];if(i=d3.select(this),0===z.length)for(var K=H-H/5,L=y*H,M=0;Mc)return"";if("function"==typeof n)d=n(a,b,{key:f(a.data),value:g(a.data),percent:k(c)});else switch(n){case"key":d=f(a.data);break;case"value":d=k(g(a.data));break;case"percent":d=d3.format("%")(c)}return d})}}),D.renderEnd("pie immediate"),b}var c={top:0,right:0,bottom:0,left:0},d=500,e=500,f=function(a){return a.x},g=function(a){return a.y},h=Math.floor(1e4*Math.random()),i=null,j=a.utils.defaultColor(),k=d3.format(",.2f"),l=!0,m=!1,n="key",o=.02,p=!1,q=!1,r=!0,s=0,t=!1,u=!1,v=!1,w=!1,x=0,y=.5,z=[],A=d3.dispatch("chartClick","elementClick","elementDblClick","elementMouseover","elementMouseout","elementMousemove","renderEnd"),B=[],C=[],D=a.utils.renderWatch(A);return b.dispatch=A,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{arcsRadius:{get:function(){return z},set:function(a){z=a}},width:{get:function(){return d},set:function(a){d=a}},height:{get:function(){return e},set:function(a){e=a}},showLabels:{get:function(){return l},set:function(a){l=a}},title:{get:function(){return q},set:function(a){q=a}},titleOffset:{get:function(){return s},set:function(a){s=a}},labelThreshold:{get:function(){return o},set:function(a){o=a}},valueFormat:{get:function(){return k},set:function(a){k=a}},x:{get:function(){return f},set:function(a){f=a}},id:{get:function(){return h},set:function(a){h=a}},endAngle:{get:function(){return w},set:function(a){w=a}},startAngle:{get:function(){return u},set:function(a){u=a}},padAngle:{get:function(){return v},set:function(a){v=a}},cornerRadius:{get:function(){return x},set:function(a){x=a}},donutRatio:{get:function(){return y},set:function(a){y=a}},labelsOutside:{get:function(){return m},set:function(a){m=a}},labelSunbeamLayout:{get:function(){return t},set:function(a){t=a}},donut:{get:function(){return p},set:function(a){p=a}},growOnHover:{get:function(){return r},set:function(a){r=a}},pieLabelsOutside:{get:function(){return m},set:function(b){m=b,a.deprecated("pieLabelsOutside","use labelsOutside instead")}},donutLabelsOutside:{get:function(){return m},set:function(b){m=b,a.deprecated("donutLabelsOutside","use labelsOutside instead")}},labelFormat:{get:function(){return k},set:function(b){k=b,a.deprecated("labelFormat","use valueFormat instead")}},margin:{get:function(){return c},set:function(a){c.top="undefined"!=typeof a.top?a.top:c.top,c.right="undefined"!=typeof a.right?a.right:c.right,c.bottom="undefined"!=typeof a.bottom?a.bottom:c.bottom,c.left="undefined"!=typeof a.left?a.left:c.left}},y:{get:function(){return g},set:function(a){g=d3.functor(a)}},color:{get:function(){return j},set:function(b){j=a.utils.getColor(b)}},labelType:{get:function(){return n},set:function(a){n=a||"key"}}}),a.utils.initOptions(b),b},a.models.pieChart=function(){"use strict";function b(e){return q.reset(),q.models(c),e.each(function(e){var k=d3.select(this);a.utils.initSVG(k);var n=a.utils.availableWidth(g,k,f),o=a.utils.availableHeight(h,k,f);if(b.update=function(){k.transition().call(b)},b.container=this,l.setter(s(e),b.update).getter(r(e)).update(),l.disabled=e.map(function(a){return!!a.disabled}),!m){var q;m={};for(q in l)m[q]=l[q]instanceof Array?l[q].slice(0):l[q]}if(!e||!e.length)return a.utils.noData(b,k),b;k.selectAll(".nv-noData").remove();var t=k.selectAll("g.nv-wrap.nv-pieChart").data([e]),u=t.enter().append("g").attr("class","nvd3 nv-wrap nv-pieChart").append("g"),v=t.select("g");if(u.append("g").attr("class","nv-pieWrap"),u.append("g").attr("class","nv-legendWrap"),i)if("top"===j)d.width(n).key(c.x()),t.select(".nv-legendWrap").datum(e).call(d),f.top!=d.height()&&(f.top=d.height(),o=a.utils.availableHeight(h,k,f)),t.select(".nv-legendWrap").attr("transform","translate(0,"+-f.top+")");else if("right"===j){var w=a.models.legend().width();w>n/2&&(w=n/2),d.height(o).key(c.x()),d.width(w),n-=d.width(),t.select(".nv-legendWrap").datum(e).call(d).attr("transform","translate("+n+",0)")}t.attr("transform","translate("+f.left+","+f.top+")"),c.width(n).height(o);var x=v.select(".nv-pieWrap").datum([e]);d3.transition(x).call(c),d.dispatch.on("stateChange",function(a){for(var c in a)l[c]=a[c];p.stateChange(l),b.update()}),p.on("changeState",function(a){"undefined"!=typeof a.disabled&&(e.forEach(function(b,c){b.disabled=a.disabled[c]}),l.disabled=a.disabled),b.update()})}),q.renderEnd("pieChart immediate"),b}var c=a.models.pie(),d=a.models.legend(),e=a.models.tooltip(),f={top:30,right:20,bottom:20,left:20},g=null,h=null,i=!0,j="top",k=a.utils.defaultColor(),l=a.utils.state(),m=null,n=null,o=250,p=d3.dispatch("tooltipShow","tooltipHide","stateChange","changeState","renderEnd");e.headerEnabled(!1).duration(0).valueFormatter(function(a,b){return c.valueFormat()(a,b)});var q=a.utils.renderWatch(p),r=function(a){return function(){return{active:a.map(function(a){return!a.disabled})}}},s=function(a){return function(b){void 0!==b.active&&a.forEach(function(a,c){a.disabled=!b.active[c]})}};return c.dispatch.on("elementMouseover.tooltip",function(a){a.series={key:b.x()(a.data),value:b.y()(a.data),color:a.color},e.data(a).hidden(!1)}),c.dispatch.on("elementMouseout.tooltip",function(){e.hidden(!0)}),c.dispatch.on("elementMousemove.tooltip",function(){e.position({top:d3.event.pageY,left:d3.event.pageX})()}),b.legend=d,b.dispatch=p,b.pie=c,b.tooltip=e,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{noData:{get:function(){return n},set:function(a){n=a}},showLegend:{get:function(){return i},set:function(a){i=a}},legendPosition:{get:function(){return j},set:function(a){j=a}},defaultState:{get:function(){return m},set:function(a){m=a}},tooltips:{get:function(){return e.enabled()},set:function(b){a.deprecated("tooltips","use chart.tooltip.enabled() instead"),e.enabled(!!b)}},tooltipContent:{get:function(){return e.contentGenerator()},set:function(b){a.deprecated("tooltipContent","use chart.tooltip.contentGenerator() instead"),e.contentGenerator(b)}},color:{get:function(){return k},set:function(a){k=a,d.color(k),c.color(k)}},duration:{get:function(){return o},set:function(a){o=a,q.reset(o)}},margin:{get:function(){return f},set:function(a){f.top=void 0!==a.top?a.top:f.top,f.right=void 0!==a.right?a.right:f.right,f.bottom=void 0!==a.bottom?a.bottom:f.bottom,f.left=void 0!==a.left?a.left:f.left}}}),a.utils.inheritOptions(b,c),a.utils.initOptions(b),b},a.models.scatter=function(){"use strict";function b(N){return P.reset(),N.each(function(b){function N(){if(O=!1,!w)return!1;if(M===!0){var a=d3.merge(b.map(function(a,b){return a.values.map(function(a,c){var d=p(a,c),e=q(a,c);return[m(d)+1e-4*Math.random(),n(e)+1e-4*Math.random(),b,c,a]}).filter(function(a,b){return x(a[4],b)})}));if(0==a.length)return!1;a.length<3&&(a.push([m.range()[0]-20,n.range()[0]-20,null,null]),a.push([m.range()[1]+20,n.range()[1]+20,null,null]),a.push([m.range()[0]-20,n.range()[0]+20,null,null]),a.push([m.range()[1]+20,n.range()[1]-20,null,null]));var c=d3.geom.polygon([[-10,-10],[-10,i+10],[h+10,i+10],[h+10,-10]]),d=d3.geom.voronoi(a).map(function(b,d){return{data:c.clip(b),series:a[d][2],point:a[d][3]}});U.select(".nv-point-paths").selectAll("path").remove();var e=U.select(".nv-point-paths").selectAll("path").data(d),f=e.enter().append("svg:path").attr("d",function(a){return a&&a.data&&0!==a.data.length?"M"+a.data.join(",")+"Z":"M 0 0"}).attr("id",function(a,b){return"nv-path-"+b}).attr("clip-path",function(a,b){return"url(#nv-clip-"+b+")"});C&&f.style("fill",d3.rgb(230,230,230)).style("fill-opacity",.4).style("stroke-opacity",1).style("stroke",d3.rgb(200,200,200)),B&&(U.select(".nv-point-clips").selectAll("clipPath").remove(),U.select(".nv-point-clips").selectAll("clipPath").data(a).enter().append("svg:clipPath").attr("id",function(a,b){return"nv-clip-"+b}).append("svg:circle").attr("cx",function(a){return a[0]}).attr("cy",function(a){return a[1]}).attr("r",D));var k=function(a,c){if(O)return 0;var d=b[a.series];if(void 0!==d){var e=d.values[a.point];e.color=j(d,a.series),e.x=p(e),e.y=q(e);var f=l.node().getBoundingClientRect(),h=window.pageYOffset||document.documentElement.scrollTop,i=window.pageXOffset||document.documentElement.scrollLeft,k={left:m(p(e,a.point))+f.left+i+g.left+10,top:n(q(e,a.point))+f.top+h+g.top+10};c({point:e,series:d,pos:k,seriesIndex:a.series,pointIndex:a.point})}};e.on("click",function(a){k(a,L.elementClick)}).on("dblclick",function(a){k(a,L.elementDblClick)}).on("mouseover",function(a){k(a,L.elementMouseover)}).on("mouseout",function(a){k(a,L.elementMouseout)})}else U.select(".nv-groups").selectAll(".nv-group").selectAll(".nv-point").on("click",function(a,c){if(O||!b[a.series])return 0;var d=b[a.series],e=d.values[c];L.elementClick({point:e,series:d,pos:[m(p(e,c))+g.left,n(q(e,c))+g.top],seriesIndex:a.series,pointIndex:c})}).on("dblclick",function(a,c){if(O||!b[a.series])return 0;var d=b[a.series],e=d.values[c];L.elementDblClick({point:e,series:d,pos:[m(p(e,c))+g.left,n(q(e,c))+g.top],seriesIndex:a.series,pointIndex:c})}).on("mouseover",function(a,c){if(O||!b[a.series])return 0;var d=b[a.series],e=d.values[c];L.elementMouseover({point:e,series:d,pos:[m(p(e,c))+g.left,n(q(e,c))+g.top],seriesIndex:a.series,pointIndex:c,color:j(a,c)})}).on("mouseout",function(a,c){if(O||!b[a.series])return 0;var d=b[a.series],e=d.values[c];L.elementMouseout({point:e,series:d,seriesIndex:a.series,pointIndex:c,color:j(a,c)})})}l=d3.select(this);var R=a.utils.availableWidth(h,l,g),S=a.utils.availableHeight(i,l,g);a.utils.initSVG(l),b.forEach(function(a,b){a.values.forEach(function(a){a.series=b})});var T=E&&F&&I?[]:d3.merge(b.map(function(a){return a.values.map(function(a,b){return{x:p(a,b),y:q(a,b),size:r(a,b)}})}));m.domain(E||d3.extent(T.map(function(a){return a.x}).concat(t))),m.range(y&&b[0]?G||[(R*z+R)/(2*b[0].values.length),R-R*(1+z)/(2*b[0].values.length)]:G||[0,R]),n.domain(F||d3.extent(T.map(function(a){return a.y}).concat(u))).range(H||[S,0]),o.domain(I||d3.extent(T.map(function(a){return a.size}).concat(v))).range(J||Q),K=m.domain()[0]===m.domain()[1]||n.domain()[0]===n.domain()[1],m.domain()[0]===m.domain()[1]&&m.domain(m.domain()[0]?[m.domain()[0]-.01*m.domain()[0],m.domain()[1]+.01*m.domain()[1]]:[-1,1]),n.domain()[0]===n.domain()[1]&&n.domain(n.domain()[0]?[n.domain()[0]-.01*n.domain()[0],n.domain()[1]+.01*n.domain()[1]]:[-1,1]),isNaN(m.domain()[0])&&m.domain([-1,1]),isNaN(n.domain()[0])&&n.domain([-1,1]),c=c||m,d=d||n,e=e||o;var U=l.selectAll("g.nv-wrap.nv-scatter").data([b]),V=U.enter().append("g").attr("class","nvd3 nv-wrap nv-scatter nv-chart-"+k),W=V.append("defs"),X=V.append("g"),Y=U.select("g");U.classed("nv-single-point",K),X.append("g").attr("class","nv-groups"),X.append("g").attr("class","nv-point-paths"),V.append("g").attr("class","nv-point-clips"),U.attr("transform","translate("+g.left+","+g.top+")"),W.append("clipPath").attr("id","nv-edge-clip-"+k).append("rect"),U.select("#nv-edge-clip-"+k+" rect").attr("width",R).attr("height",S>0?S:0),Y.attr("clip-path",A?"url(#nv-edge-clip-"+k+")":""),O=!0;var Z=U.select(".nv-groups").selectAll(".nv-group").data(function(a){return a},function(a){return a.key});Z.enter().append("g").style("stroke-opacity",1e-6).style("fill-opacity",1e-6),Z.exit().remove(),Z.attr("class",function(a,b){return"nv-group nv-series-"+b}).classed("hover",function(a){return a.hover}),Z.watchTransition(P,"scatter: groups").style("fill",function(a,b){return j(a,b)}).style("stroke",function(a,b){return j(a,b)}).style("stroke-opacity",1).style("fill-opacity",.5);var $=Z.selectAll("path.nv-point").data(function(a){return a.values.map(function(a,b){return[a,b]}).filter(function(a,b){return x(a[0],b)})});$.enter().append("path").style("fill",function(a){return a.color}).style("stroke",function(a){return a.color}).attr("transform",function(a){return"translate("+c(p(a[0],a[1]))+","+d(q(a[0],a[1]))+")"}).attr("d",a.utils.symbol().type(function(a){return s(a[0])}).size(function(a){return o(r(a[0],a[1]))})),$.exit().remove(),Z.exit().selectAll("path.nv-point").watchTransition(P,"scatter exit").attr("transform",function(a){return"translate("+m(p(a[0],a[1]))+","+n(q(a[0],a[1]))+")"}).remove(),$.each(function(a){d3.select(this).classed("nv-point",!0).classed("nv-point-"+a[1],!0).classed("nv-noninteractive",!w).classed("hover",!1)}),$.watchTransition(P,"scatter points").attr("transform",function(a){return"translate("+m(p(a[0],a[1]))+","+n(q(a[0],a[1]))+")"}).attr("d",a.utils.symbol().type(function(a){return s(a[0])}).size(function(a){return o(r(a[0],a[1]))})),clearTimeout(f),f=setTimeout(N,300),c=m.copy(),d=n.copy(),e=o.copy()}),P.renderEnd("scatter immediate"),b}var c,d,e,f,g={top:0,right:0,bottom:0,left:0},h=null,i=null,j=a.utils.defaultColor(),k=Math.floor(1e5*Math.random()),l=null,m=d3.scale.linear(),n=d3.scale.linear(),o=d3.scale.linear(),p=function(a){return a.x},q=function(a){return a.y},r=function(a){return a.size||1},s=function(a){return a.shape||"circle"},t=[],u=[],v=[],w=!0,x=function(a){return!a.notActive},y=!1,z=.1,A=!1,B=!0,C=!1,D=function(){return 25},E=null,F=null,G=null,H=null,I=null,J=null,K=!1,L=d3.dispatch("elementClick","elementDblClick","elementMouseover","elementMouseout","renderEnd"),M=!0,N=250,O=!1,P=a.utils.renderWatch(L,N),Q=[16,256];return b.dispatch=L,b.options=a.utils.optionsFunc.bind(b),b._calls=new function(){this.clearHighlights=function(){return a.dom.write(function(){l.selectAll(".nv-point.hover").classed("hover",!1)}),null},this.highlightPoint=function(b,c,d){a.dom.write(function(){l.select(" .nv-series-"+b+" .nv-point-"+c).classed("hover",d)})}},L.on("elementMouseover.point",function(a){w&&b._calls.highlightPoint(a.seriesIndex,a.pointIndex,!0)}),L.on("elementMouseout.point",function(a){w&&b._calls.highlightPoint(a.seriesIndex,a.pointIndex,!1)}),b._options=Object.create({},{width:{get:function(){return h},set:function(a){h=a}},height:{get:function(){return i},set:function(a){i=a}},xScale:{get:function(){return m},set:function(a){m=a}},yScale:{get:function(){return n},set:function(a){n=a}},pointScale:{get:function(){return o},set:function(a){o=a}},xDomain:{get:function(){return E},set:function(a){E=a}},yDomain:{get:function(){return F},set:function(a){F=a}},pointDomain:{get:function(){return I},set:function(a){I=a}},xRange:{get:function(){return G},set:function(a){G=a}},yRange:{get:function(){return H},set:function(a){H=a}},pointRange:{get:function(){return J},set:function(a){J=a}},forceX:{get:function(){return t},set:function(a){t=a}},forceY:{get:function(){return u},set:function(a){u=a}},forcePoint:{get:function(){return v},set:function(a){v=a}},interactive:{get:function(){return w},set:function(a){w=a}},pointActive:{get:function(){return x},set:function(a){x=a}},padDataOuter:{get:function(){return z},set:function(a){z=a}},padData:{get:function(){return y},set:function(a){y=a}},clipEdge:{get:function(){return A},set:function(a){A=a}},clipVoronoi:{get:function(){return B},set:function(a){B=a}},clipRadius:{get:function(){return D},set:function(a){D=a}},showVoronoi:{get:function(){return C},set:function(a){C=a}},id:{get:function(){return k},set:function(a){k=a}},x:{get:function(){return p},set:function(a){p=d3.functor(a)}},y:{get:function(){return q},set:function(a){q=d3.functor(a)}},pointSize:{get:function(){return r},set:function(a){r=d3.functor(a)}},pointShape:{get:function(){return s},set:function(a){s=d3.functor(a)}},margin:{get:function(){return g},set:function(a){g.top=void 0!==a.top?a.top:g.top,g.right=void 0!==a.right?a.right:g.right,g.bottom=void 0!==a.bottom?a.bottom:g.bottom,g.left=void 0!==a.left?a.left:g.left}},duration:{get:function(){return N},set:function(a){N=a,P.reset(N)}},color:{get:function(){return j},set:function(b){j=a.utils.getColor(b)}},useVoronoi:{get:function(){return M},set:function(a){M=a,M===!1&&(B=!1)}}}),a.utils.initOptions(b),b},a.models.scatterChart=function(){"use strict";function b(z){return D.reset(),D.models(c),t&&D.models(d),u&&D.models(e),q&&D.models(g),r&&D.models(h),z.each(function(z){m=d3.select(this),a.utils.initSVG(m);var G=a.utils.availableWidth(k,m,j),H=a.utils.availableHeight(l,m,j);if(b.update=function(){0===A?m.call(b):m.transition().duration(A).call(b)},b.container=this,w.setter(F(z),b.update).getter(E(z)).update(),w.disabled=z.map(function(a){return!!a.disabled}),!x){var I;x={};for(I in w)x[I]=w[I]instanceof Array?w[I].slice(0):w[I]}if(!(z&&z.length&&z.filter(function(a){return a.values.length}).length))return a.utils.noData(b,m),D.renderEnd("scatter immediate"),b;m.selectAll(".nv-noData").remove(),o=c.xScale(),p=c.yScale();var J=m.selectAll("g.nv-wrap.nv-scatterChart").data([z]),K=J.enter().append("g").attr("class","nvd3 nv-wrap nv-scatterChart nv-chart-"+c.id()),L=K.append("g"),M=J.select("g");if(L.append("rect").attr("class","nvd3 nv-background").style("pointer-events","none"),L.append("g").attr("class","nv-x nv-axis"),L.append("g").attr("class","nv-y nv-axis"),L.append("g").attr("class","nv-scatterWrap"),L.append("g").attr("class","nv-regressionLinesWrap"),L.append("g").attr("class","nv-distWrap"),L.append("g").attr("class","nv-legendWrap"),v&&M.select(".nv-y.nv-axis").attr("transform","translate("+G+",0)"),s){var N=G;f.width(N),J.select(".nv-legendWrap").datum(z).call(f),j.top!=f.height()&&(j.top=f.height(),H=a.utils.availableHeight(l,m,j)),J.select(".nv-legendWrap").attr("transform","translate(0,"+-j.top+")")}J.attr("transform","translate("+j.left+","+j.top+")"),c.width(G).height(H).color(z.map(function(a,b){return a.color=a.color||n(a,b),a.color}).filter(function(a,b){return!z[b].disabled})),J.select(".nv-scatterWrap").datum(z.filter(function(a){return!a.disabled})).call(c),J.select(".nv-regressionLinesWrap").attr("clip-path","url(#nv-edge-clip-"+c.id()+")");var O=J.select(".nv-regressionLinesWrap").selectAll(".nv-regLines").data(function(a){return a});O.enter().append("g").attr("class","nv-regLines");var P=O.selectAll(".nv-regLine").data(function(a){return[a]});P.enter().append("line").attr("class","nv-regLine").style("stroke-opacity",0),P.filter(function(a){return a.intercept&&a.slope}).watchTransition(D,"scatterPlusLineChart: regline").attr("x1",o.range()[0]).attr("x2",o.range()[1]).attr("y1",function(a){return p(o.domain()[0]*a.slope+a.intercept)}).attr("y2",function(a){return p(o.domain()[1]*a.slope+a.intercept)}).style("stroke",function(a,b,c){return n(a,c)}).style("stroke-opacity",function(a){return a.disabled||"undefined"==typeof a.slope||"undefined"==typeof a.intercept?0:1}),t&&(d.scale(o)._ticks(a.utils.calcTicksX(G/100,z)).tickSize(-H,0),M.select(".nv-x.nv-axis").attr("transform","translate(0,"+p.range()[0]+")").call(d)),u&&(e.scale(p)._ticks(a.utils.calcTicksY(H/36,z)).tickSize(-G,0),M.select(".nv-y.nv-axis").call(e)),q&&(g.getData(c.x()).scale(o).width(G).color(z.map(function(a,b){return a.color||n(a,b)}).filter(function(a,b){return!z[b].disabled})),L.select(".nv-distWrap").append("g").attr("class","nv-distributionX"),M.select(".nv-distributionX").attr("transform","translate(0,"+p.range()[0]+")").datum(z.filter(function(a){return!a.disabled})).call(g)),r&&(h.getData(c.y()).scale(p).width(H).color(z.map(function(a,b){return a.color||n(a,b)}).filter(function(a,b){return!z[b].disabled})),L.select(".nv-distWrap").append("g").attr("class","nv-distributionY"),M.select(".nv-distributionY").attr("transform","translate("+(v?G:-h.size())+",0)").datum(z.filter(function(a){return!a.disabled})).call(h)),f.dispatch.on("stateChange",function(a){for(var c in a)w[c]=a[c];y.stateChange(w),b.update()}),y.on("changeState",function(a){"undefined"!=typeof a.disabled&&(z.forEach(function(b,c){b.disabled=a.disabled[c]}),w.disabled=a.disabled),b.update()}),c.dispatch.on("elementMouseout.tooltip",function(a){i.hidden(!0),m.select(".nv-chart-"+c.id()+" .nv-series-"+a.seriesIndex+" .nv-distx-"+a.pointIndex).attr("y1",0),m.select(".nv-chart-"+c.id()+" .nv-series-"+a.seriesIndex+" .nv-disty-"+a.pointIndex).attr("x2",h.size())}),c.dispatch.on("elementMouseover.tooltip",function(a){m.select(".nv-series-"+a.seriesIndex+" .nv-distx-"+a.pointIndex).attr("y1",a.pos.top-H-j.top),m.select(".nv-series-"+a.seriesIndex+" .nv-disty-"+a.pointIndex).attr("x2",a.pos.left+g.size()-j.left),i.position(a.pos).data(a).hidden(!1)}),B=o.copy(),C=p.copy()}),D.renderEnd("scatter with line immediate"),b}var c=a.models.scatter(),d=a.models.axis(),e=a.models.axis(),f=a.models.legend(),g=a.models.distribution(),h=a.models.distribution(),i=a.models.tooltip(),j={top:30,right:20,bottom:50,left:75},k=null,l=null,m=null,n=a.utils.defaultColor(),o=c.xScale(),p=c.yScale(),q=!1,r=!1,s=!0,t=!0,u=!0,v=!1,w=a.utils.state(),x=null,y=d3.dispatch("stateChange","changeState","renderEnd"),z=null,A=250;c.xScale(o).yScale(p),d.orient("bottom").tickPadding(10),e.orient(v?"right":"left").tickPadding(10),g.axis("x"),h.axis("y"),i.headerFormatter(function(a,b){return d.tickFormat()(a,b)}).valueFormatter(function(a,b){return e.tickFormat()(a,b)});var B,C,D=a.utils.renderWatch(y,A),E=function(a){return function(){return{active:a.map(function(a){return!a.disabled})}}},F=function(a){return function(b){void 0!==b.active&&a.forEach(function(a,c){a.disabled=!b.active[c]})}};return b.dispatch=y,b.scatter=c,b.legend=f,b.xAxis=d,b.yAxis=e,b.distX=g,b.distY=h,b.tooltip=i,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return k},set:function(a){k=a}},height:{get:function(){return l},set:function(a){l=a}},container:{get:function(){return m},set:function(a){m=a}},showDistX:{get:function(){return q},set:function(a){q=a}},showDistY:{get:function(){return r},set:function(a){r=a}},showLegend:{get:function(){return s},set:function(a){s=a}},showXAxis:{get:function(){return t},set:function(a){t=a}},showYAxis:{get:function(){return u},set:function(a){u=a}},defaultState:{get:function(){return x},set:function(a){x=a}},noData:{get:function(){return z},set:function(a){z=a}},duration:{get:function(){return A},set:function(a){A=a}},tooltips:{get:function(){return i.enabled()},set:function(b){a.deprecated("tooltips","use chart.tooltip.enabled() instead"),i.enabled(!!b) -}},tooltipContent:{get:function(){return i.contentGenerator()},set:function(b){a.deprecated("tooltipContent","use chart.tooltip.contentGenerator() instead"),i.contentGenerator(b)}},tooltipXContent:{get:function(){return i.contentGenerator()},set:function(){a.deprecated("tooltipContent","This option is removed, put values into main tooltip.")}},tooltipYContent:{get:function(){return i.contentGenerator()},set:function(){a.deprecated("tooltipContent","This option is removed, put values into main tooltip.")}},margin:{get:function(){return j},set:function(a){j.top=void 0!==a.top?a.top:j.top,j.right=void 0!==a.right?a.right:j.right,j.bottom=void 0!==a.bottom?a.bottom:j.bottom,j.left=void 0!==a.left?a.left:j.left}},rightAlignYAxis:{get:function(){return v},set:function(a){v=a,e.orient(a?"right":"left")}},color:{get:function(){return n},set:function(b){n=a.utils.getColor(b),f.color(n),g.color(n),h.color(n)}}}),a.utils.inheritOptions(b,c),a.utils.initOptions(b),b},a.models.sparkline=function(){"use strict";function b(k){return k.each(function(b){var k=h-g.left-g.right,q=i-g.top-g.bottom;j=d3.select(this),a.utils.initSVG(j),l.domain(c||d3.extent(b,n)).range(e||[0,k]),m.domain(d||d3.extent(b,o)).range(f||[q,0]);{var r=j.selectAll("g.nv-wrap.nv-sparkline").data([b]),s=r.enter().append("g").attr("class","nvd3 nv-wrap nv-sparkline");s.append("g"),r.select("g")}r.attr("transform","translate("+g.left+","+g.top+")");var t=r.selectAll("path").data(function(a){return[a]});t.enter().append("path"),t.exit().remove(),t.style("stroke",function(a,b){return a.color||p(a,b)}).attr("d",d3.svg.line().x(function(a,b){return l(n(a,b))}).y(function(a,b){return m(o(a,b))}));var u=r.selectAll("circle.nv-point").data(function(a){function b(b){if(-1!=b){var c=a[b];return c.pointIndex=b,c}return null}var c=a.map(function(a,b){return o(a,b)}),d=b(c.lastIndexOf(m.domain()[1])),e=b(c.indexOf(m.domain()[0])),f=b(c.length-1);return[e,d,f].filter(function(a){return null!=a})});u.enter().append("circle"),u.exit().remove(),u.attr("cx",function(a){return l(n(a,a.pointIndex))}).attr("cy",function(a){return m(o(a,a.pointIndex))}).attr("r",2).attr("class",function(a){return n(a,a.pointIndex)==l.domain()[1]?"nv-point nv-currentValue":o(a,a.pointIndex)==m.domain()[0]?"nv-point nv-minValue":"nv-point nv-maxValue"})}),b}var c,d,e,f,g={top:2,right:0,bottom:2,left:0},h=400,i=32,j=null,k=!0,l=d3.scale.linear(),m=d3.scale.linear(),n=function(a){return a.x},o=function(a){return a.y},p=a.utils.getColor(["#000"]);return b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return h},set:function(a){h=a}},height:{get:function(){return i},set:function(a){i=a}},xDomain:{get:function(){return c},set:function(a){c=a}},yDomain:{get:function(){return d},set:function(a){d=a}},xRange:{get:function(){return e},set:function(a){e=a}},yRange:{get:function(){return f},set:function(a){f=a}},xScale:{get:function(){return l},set:function(a){l=a}},yScale:{get:function(){return m},set:function(a){m=a}},animate:{get:function(){return k},set:function(a){k=a}},x:{get:function(){return n},set:function(a){n=d3.functor(a)}},y:{get:function(){return o},set:function(a){o=d3.functor(a)}},margin:{get:function(){return g},set:function(a){g.top=void 0!==a.top?a.top:g.top,g.right=void 0!==a.right?a.right:g.right,g.bottom=void 0!==a.bottom?a.bottom:g.bottom,g.left=void 0!==a.left?a.left:g.left}},color:{get:function(){return p},set:function(b){p=a.utils.getColor(b)}}}),a.utils.initOptions(b),b},a.models.sparklinePlus=function(){"use strict";function b(p){return p.each(function(p){function q(){if(!j){var a=z.selectAll(".nv-hoverValue").data(i),b=a.enter().append("g").attr("class","nv-hoverValue").style("stroke-opacity",0).style("fill-opacity",0);a.exit().transition().duration(250).style("stroke-opacity",0).style("fill-opacity",0).remove(),a.attr("transform",function(a){return"translate("+c(e.x()(p[a],a))+",0)"}).transition().duration(250).style("stroke-opacity",1).style("fill-opacity",1),i.length&&(b.append("line").attr("x1",0).attr("y1",-f.top).attr("x2",0).attr("y2",u),b.append("text").attr("class","nv-xValue").attr("x",-6).attr("y",-f.top).attr("text-anchor","end").attr("dy",".9em"),z.select(".nv-hoverValue .nv-xValue").text(k(e.x()(p[i[0]],i[0]))),b.append("text").attr("class","nv-yValue").attr("x",6).attr("y",-f.top).attr("text-anchor","start").attr("dy",".9em"),z.select(".nv-hoverValue .nv-yValue").text(l(e.y()(p[i[0]],i[0]))))}}function r(){function a(a,b){for(var c=Math.abs(e.x()(a[0],0)-b),d=0,f=0;fc;++c){for(b=0,d=0;bb;b++)a[b][c][1]/=d;else for(b=0;e>b;b++)a[b][c][1]=0}for(c=0;f>c;++c)g[c]=0;return g}}),u.renderEnd("stackedArea immediate"),b}var c,d,e={top:0,right:0,bottom:0,left:0},f=960,g=500,h=a.utils.defaultColor(),i=Math.floor(1e5*Math.random()),j=null,k=function(a){return a.x},l=function(a){return a.y},m="stack",n="zero",o="default",p="linear",q=!1,r=a.models.scatter(),s=250,t=d3.dispatch("areaClick","areaMouseover","areaMouseout","renderEnd","elementClick","elementMouseover","elementMouseout");r.pointSize(2.2).pointDomain([2.2,2.2]);var u=a.utils.renderWatch(t,s);return b.dispatch=t,b.scatter=r,r.dispatch.on("elementClick",function(){t.elementClick.apply(this,arguments)}),r.dispatch.on("elementMouseover",function(){t.elementMouseover.apply(this,arguments)}),r.dispatch.on("elementMouseout",function(){t.elementMouseout.apply(this,arguments)}),b.interpolate=function(a){return arguments.length?(p=a,b):p},b.duration=function(a){return arguments.length?(s=a,u.reset(s),r.duration(s),b):s},b.dispatch=t,b.scatter=r,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return f},set:function(a){f=a}},height:{get:function(){return g},set:function(a){g=a}},clipEdge:{get:function(){return q},set:function(a){q=a}},offset:{get:function(){return n},set:function(a){n=a}},order:{get:function(){return o},set:function(a){o=a}},interpolate:{get:function(){return p},set:function(a){p=a}},x:{get:function(){return k},set:function(a){k=d3.functor(a)}},y:{get:function(){return l},set:function(a){l=d3.functor(a)}},margin:{get:function(){return e},set:function(a){e.top=void 0!==a.top?a.top:e.top,e.right=void 0!==a.right?a.right:e.right,e.bottom=void 0!==a.bottom?a.bottom:e.bottom,e.left=void 0!==a.left?a.left:e.left}},color:{get:function(){return h},set:function(b){h=a.utils.getColor(b)}},style:{get:function(){return m},set:function(a){switch(m=a){case"stack":b.offset("zero"),b.order("default");break;case"stream":b.offset("wiggle"),b.order("inside-out");break;case"stream-center":b.offset("silhouette"),b.order("inside-out");break;case"expand":b.offset("expand"),b.order("default");break;case"stack_percent":b.offset(b.d3_stackedOffset_stackPercent),b.order("default")}}},duration:{get:function(){return s},set:function(a){s=a,u.reset(s),r.duration(s)}}}),a.utils.inheritOptions(b,r),a.utils.initOptions(b),b},a.models.stackedAreaChart=function(){"use strict";function b(k){return F.reset(),F.models(e),r&&F.models(f),s&&F.models(g),k.each(function(k){var x=d3.select(this),F=this;a.utils.initSVG(x);var K=a.utils.availableWidth(m,x,l),L=a.utils.availableHeight(n,x,l);if(b.update=function(){x.transition().duration(C).call(b)},b.container=this,v.setter(I(k),b.update).getter(H(k)).update(),v.disabled=k.map(function(a){return!!a.disabled}),!w){var M;w={};for(M in v)w[M]=v[M]instanceof Array?v[M].slice(0):v[M]}if(!(k&&k.length&&k.filter(function(a){return a.values.length}).length))return a.utils.noData(b,x),b;x.selectAll(".nv-noData").remove(),c=e.xScale(),d=e.yScale();var N=x.selectAll("g.nv-wrap.nv-stackedAreaChart").data([k]),O=N.enter().append("g").attr("class","nvd3 nv-wrap nv-stackedAreaChart").append("g"),P=N.select("g");if(O.append("rect").style("opacity",0),O.append("g").attr("class","nv-x nv-axis"),O.append("g").attr("class","nv-y nv-axis"),O.append("g").attr("class","nv-stackedWrap"),O.append("g").attr("class","nv-legendWrap"),O.append("g").attr("class","nv-controlsWrap"),O.append("g").attr("class","nv-interactive"),P.select("rect").attr("width",K).attr("height",L),q){var Q=p?K-z:K;h.width(Q),P.select(".nv-legendWrap").datum(k).call(h),l.top!=h.height()&&(l.top=h.height(),L=a.utils.availableHeight(n,x,l)),P.select(".nv-legendWrap").attr("transform","translate("+(K-Q)+","+-l.top+")")}if(p){var R=[{key:B.stacked||"Stacked",metaKey:"Stacked",disabled:"stack"!=e.style(),style:"stack"},{key:B.stream||"Stream",metaKey:"Stream",disabled:"stream"!=e.style(),style:"stream"},{key:B.expanded||"Expanded",metaKey:"Expanded",disabled:"expand"!=e.style(),style:"expand"},{key:B.stack_percent||"Stack %",metaKey:"Stack_Percent",disabled:"stack_percent"!=e.style(),style:"stack_percent"}];z=A.length/3*260,R=R.filter(function(a){return-1!==A.indexOf(a.metaKey)}),i.width(z).color(["#444","#444","#444"]),P.select(".nv-controlsWrap").datum(R).call(i),l.top!=Math.max(i.height(),h.height())&&(l.top=Math.max(i.height(),h.height()),L=a.utils.availableHeight(n,x,l)),P.select(".nv-controlsWrap").attr("transform","translate(0,"+-l.top+")")}N.attr("transform","translate("+l.left+","+l.top+")"),t&&P.select(".nv-y.nv-axis").attr("transform","translate("+K+",0)"),u&&(j.width(K).height(L).margin({left:l.left,top:l.top}).svgContainer(x).xScale(c),N.select(".nv-interactive").call(j)),e.width(K).height(L);var S=P.select(".nv-stackedWrap").datum(k);if(S.transition().call(e),r&&(f.scale(c)._ticks(a.utils.calcTicksX(K/100,k)).tickSize(-L,0),P.select(".nv-x.nv-axis").attr("transform","translate(0,"+L+")"),P.select(".nv-x.nv-axis").transition().duration(0).call(f)),s){var T;if(T="wiggle"===e.offset()?0:a.utils.calcTicksY(L/36,k),g.scale(d)._ticks(T).tickSize(-K,0),"expand"===e.style()||"stack_percent"===e.style()){var U=g.tickFormat();D&&U===J||(D=U),g.tickFormat(J)}else D&&(g.tickFormat(D),D=null);P.select(".nv-y.nv-axis").transition().duration(0).call(g)}e.dispatch.on("areaClick.toggle",function(a){k.forEach(1===k.filter(function(a){return!a.disabled}).length?function(a){a.disabled=!1}:function(b,c){b.disabled=c!=a.seriesIndex}),v.disabled=k.map(function(a){return!!a.disabled}),y.stateChange(v),b.update()}),h.dispatch.on("stateChange",function(a){for(var c in a)v[c]=a[c];y.stateChange(v),b.update()}),i.dispatch.on("legendClick",function(a){a.disabled&&(R=R.map(function(a){return a.disabled=!0,a}),a.disabled=!1,e.style(a.style),v.style=e.style(),y.stateChange(v),b.update())}),j.dispatch.on("elementMousemove",function(c){e.clearHighlights();var d,g,h,i=[];if(k.filter(function(a,b){return a.seriesIndex=b,!a.disabled}).forEach(function(f,j){g=a.interactiveBisect(f.values,c.pointXValue,b.x());var k=f.values[g],l=b.y()(k,g);if(null!=l&&e.highlightPoint(j,g,!0),"undefined"!=typeof k){"undefined"==typeof d&&(d=k),"undefined"==typeof h&&(h=b.xScale()(b.x()(k,g)));var m="expand"==e.style()?k.display.y:b.y()(k,g);i.push({key:f.key,value:m,color:o(f,f.seriesIndex),stackedValue:k.display})}}),i.reverse(),i.length>2){var m=b.yScale().invert(c.mouseY),n=null;i.forEach(function(a,b){m=Math.abs(m);var c=Math.abs(a.stackedValue.y0),d=Math.abs(a.stackedValue.y);return m>=c&&d+c>=m?void(n=b):void 0}),null!=n&&(i[n].highlight=!0)}var p=f.tickFormat()(b.x()(d,g)),q=j.tooltip.valueFormatter();"expand"===e.style()||"stack_percent"===e.style()?(E||(E=q),q=d3.format(".1%")):E&&(q=E,E=null),j.tooltip.position({left:h+l.left,top:c.mouseY+l.top}).chartContainer(F.parentNode).valueFormatter(q).data({value:p,series:i})(),j.renderGuideLine(h)}),j.dispatch.on("elementMouseout",function(){e.clearHighlights()}),y.on("changeState",function(a){"undefined"!=typeof a.disabled&&k.length===a.disabled.length&&(k.forEach(function(b,c){b.disabled=a.disabled[c]}),v.disabled=a.disabled),"undefined"!=typeof a.style&&(e.style(a.style),G=a.style),b.update()})}),F.renderEnd("stacked Area chart immediate"),b}var c,d,e=a.models.stackedArea(),f=a.models.axis(),g=a.models.axis(),h=a.models.legend(),i=a.models.legend(),j=a.interactiveGuideline(),k=a.models.tooltip(),l={top:30,right:25,bottom:50,left:60},m=null,n=null,o=a.utils.defaultColor(),p=!0,q=!0,r=!0,s=!0,t=!1,u=!1,v=a.utils.state(),w=null,x=null,y=d3.dispatch("stateChange","changeState","renderEnd"),z=250,A=["Stacked","Stream","Expanded"],B={},C=250;v.style=e.style(),f.orient("bottom").tickPadding(7),g.orient(t?"right":"left"),k.headerFormatter(function(a,b){return f.tickFormat()(a,b)}).valueFormatter(function(a,b){return g.tickFormat()(a,b)}),j.tooltip.headerFormatter(function(a,b){return f.tickFormat()(a,b)}).valueFormatter(function(a,b){return g.tickFormat()(a,b)});var D=null,E=null;i.updateState(!1);var F=a.utils.renderWatch(y),G=e.style(),H=function(a){return function(){return{active:a.map(function(a){return!a.disabled}),style:e.style()}}},I=function(a){return function(b){void 0!==b.style&&(G=b.style),void 0!==b.active&&a.forEach(function(a,c){a.disabled=!b.active[c]})}},J=d3.format("%");return e.dispatch.on("elementMouseover.tooltip",function(a){a.point.x=e.x()(a.point),a.point.y=e.y()(a.point),k.data(a).position(a.pos).hidden(!1)}),e.dispatch.on("elementMouseout.tooltip",function(){k.hidden(!0)}),b.dispatch=y,b.stacked=e,b.legend=h,b.controls=i,b.xAxis=f,b.yAxis=g,b.interactiveLayer=j,b.tooltip=k,b.dispatch=y,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return m},set:function(a){m=a}},height:{get:function(){return n},set:function(a){n=a}},showLegend:{get:function(){return q},set:function(a){q=a}},showXAxis:{get:function(){return r},set:function(a){r=a}},showYAxis:{get:function(){return s},set:function(a){s=a}},defaultState:{get:function(){return w},set:function(a){w=a}},noData:{get:function(){return x},set:function(a){x=a}},showControls:{get:function(){return p},set:function(a){p=a}},controlLabels:{get:function(){return B},set:function(a){B=a}},controlOptions:{get:function(){return A},set:function(a){A=a}},tooltips:{get:function(){return k.enabled()},set:function(b){a.deprecated("tooltips","use chart.tooltip.enabled() instead"),k.enabled(!!b)}},tooltipContent:{get:function(){return k.contentGenerator()},set:function(b){a.deprecated("tooltipContent","use chart.tooltip.contentGenerator() instead"),k.contentGenerator(b)}},margin:{get:function(){return l},set:function(a){l.top=void 0!==a.top?a.top:l.top,l.right=void 0!==a.right?a.right:l.right,l.bottom=void 0!==a.bottom?a.bottom:l.bottom,l.left=void 0!==a.left?a.left:l.left}},duration:{get:function(){return C},set:function(a){C=a,F.reset(C),e.duration(C),f.duration(C),g.duration(C)}},color:{get:function(){return o},set:function(b){o=a.utils.getColor(b),h.color(o),e.color(o)}},rightAlignYAxis:{get:function(){return t},set:function(a){t=a,g.orient(t?"right":"left")}},useInteractiveGuideline:{get:function(){return u},set:function(a){u=!!a,b.interactive(!a),b.useVoronoi(!a),e.scatter.interactive(!a)}}}),a.utils.inheritOptions(b,e),a.utils.initOptions(b),b},a.models.sunburst=function(){"use strict";function b(u){return t.reset(),u.each(function(b){function t(a){a.x0=a.x,a.dx0=a.dx}function u(a){var b=d3.interpolate(p.domain(),[a.x,a.x+a.dx]),c=d3.interpolate(q.domain(),[a.y,1]),d=d3.interpolate(q.range(),[a.y?20:0,y]);return function(a,e){return e?function(){return s(a)}:function(e){return p.domain(b(e)),q.domain(c(e)).range(d(e)),s(a)}}}l=d3.select(this);var v,w=a.utils.availableWidth(g,l,f),x=a.utils.availableHeight(h,l,f),y=Math.min(w,x)/2;a.utils.initSVG(l);var z=l.selectAll(".nv-wrap.nv-sunburst").data(b),A=z.enter().append("g").attr("class","nvd3 nv-wrap nv-sunburst nv-chart-"+k),B=A.selectAll("nv-sunburst");z.attr("transform","translate("+w/2+","+x/2+")"),l.on("click",function(a,b){o.chartClick({data:a,index:b,pos:d3.event,id:k})}),q.range([0,y]),c=c||b,e=b[0],r.value(j[i]||j.count),v=B.data(r.nodes).enter().append("path").attr("d",s).style("fill",function(a){return m((a.children?a:a.parent).name)}).style("stroke","#FFF").on("click",function(a){d!==c&&c!==a&&(d=c),c=a,v.transition().duration(n).attrTween("d",u(a))}).each(t).on("dblclick",function(a){d.parent==a&&v.transition().duration(n).attrTween("d",u(e))}).each(t).on("mouseover",function(a){d3.select(this).classed("hover",!0).style("opacity",.8),o.elementMouseover({data:a,color:d3.select(this).style("fill")})}).on("mouseout",function(a){d3.select(this).classed("hover",!1).style("opacity",1),o.elementMouseout({data:a})}).on("mousemove",function(a){o.elementMousemove({data:a})})}),t.renderEnd("sunburst immediate"),b}var c,d,e,f={top:0,right:0,bottom:0,left:0},g=null,h=null,i="count",j={count:function(){return 1},size:function(a){return a.size}},k=Math.floor(1e4*Math.random()),l=null,m=a.utils.defaultColor(),n=500,o=d3.dispatch("chartClick","elementClick","elementDblClick","elementMousemove","elementMouseover","elementMouseout","renderEnd"),p=d3.scale.linear().range([0,2*Math.PI]),q=d3.scale.sqrt(),r=d3.layout.partition().sort(null).value(function(){return 1}),s=d3.svg.arc().startAngle(function(a){return Math.max(0,Math.min(2*Math.PI,p(a.x)))}).endAngle(function(a){return Math.max(0,Math.min(2*Math.PI,p(a.x+a.dx)))}).innerRadius(function(a){return Math.max(0,q(a.y))}).outerRadius(function(a){return Math.max(0,q(a.y+a.dy))}),t=a.utils.renderWatch(o);return b.dispatch=o,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return g},set:function(a){g=a}},height:{get:function(){return h},set:function(a){h=a}},mode:{get:function(){return i},set:function(a){i=a}},id:{get:function(){return k},set:function(a){k=a}},duration:{get:function(){return n},set:function(a){n=a}},margin:{get:function(){return f},set:function(a){f.top=void 0!=a.top?a.top:f.top,f.right=void 0!=a.right?a.right:f.right,f.bottom=void 0!=a.bottom?a.bottom:f.bottom,f.left=void 0!=a.left?a.left:f.left}},color:{get:function(){return m},set:function(b){m=a.utils.getColor(b)}}}),a.utils.initOptions(b),b},a.models.sunburstChart=function(){"use strict";function b(d){return m.reset(),m.models(c),d.each(function(d){var h=d3.select(this);a.utils.initSVG(h);var i=a.utils.availableWidth(f,h,e),j=a.utils.availableHeight(g,h,e);if(b.update=function(){0===k?h.call(b):h.transition().duration(k).call(b)},b.container=this,!d||!d.length)return a.utils.noData(b,h),b;h.selectAll(".nv-noData").remove();var l=h.selectAll("g.nv-wrap.nv-sunburstChart").data(d),m=l.enter().append("g").attr("class","nvd3 nv-wrap nv-sunburstChart").append("g"),n=l.select("g");m.append("g").attr("class","nv-sunburstWrap"),l.attr("transform","translate("+e.left+","+e.top+")"),c.width(i).height(j);var o=n.select(".nv-sunburstWrap").datum(d);d3.transition(o).call(c)}),m.renderEnd("sunburstChart immediate"),b}var c=a.models.sunburst(),d=a.models.tooltip(),e={top:30,right:20,bottom:20,left:20},f=null,g=null,h=a.utils.defaultColor(),i=(Math.round(1e5*Math.random()),null),j=null,k=250,l=d3.dispatch("tooltipShow","tooltipHide","stateChange","changeState","renderEnd"),m=a.utils.renderWatch(l);return d.headerEnabled(!1).duration(0).valueFormatter(function(a){return a}),c.dispatch.on("elementMouseover.tooltip",function(a){a.series={key:a.data.name,value:a.data.size,color:a.color},d.data(a).hidden(!1)}),c.dispatch.on("elementMouseout.tooltip",function(){d.hidden(!0)}),c.dispatch.on("elementMousemove.tooltip",function(){d.position({top:d3.event.pageY,left:d3.event.pageX})()}),b.dispatch=l,b.sunburst=c,b.tooltip=d,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{noData:{get:function(){return j},set:function(a){j=a}},defaultState:{get:function(){return i},set:function(a){i=a}},color:{get:function(){return h},set:function(a){h=a,c.color(h)}},duration:{get:function(){return k},set:function(a){k=a,m.reset(k),c.duration(k)}},margin:{get:function(){return e},set:function(a){e.top=void 0!==a.top?a.top:e.top,e.right=void 0!==a.right?a.right:e.right,e.bottom=void 0!==a.bottom?a.bottom:e.bottom,e.left=void 0!==a.left?a.left:e.left}}}),a.utils.inheritOptions(b,c),a.utils.initOptions(b),b},a.version="1.8.1"}(); \ No newline at end of file diff --git a/backend/coverage-report-final/dashboard.html b/backend/coverage-report-final/dashboard.html deleted file mode 100644 index e6522dc0..00000000 --- a/backend/coverage-report-final/dashboard.html +++ /dev/null @@ -1,708 +0,0 @@ - - - - - Dashboard for /var/www/html/backend/app - - - - - - - -
-
-
-
- -
-
-
-
-
-
-
-

Classes

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
-
-
-

Insufficient Coverage

-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
ClassCoverage
App\Console\Commands\FetchNewArticlesCommand0%
App\Console\Commands\SyncChannelPostsCommand0%
App\Events\ArticleReadyToPublish0%
App\Events\ExceptionLogged0%
App\Events\ExceptionOccurred0%
App\Exceptions\PlatformAuthException0%
App\Exceptions\PublishException0%
App\Exceptions\RoutingMismatchException0%
App\Http\Controllers\Api\V1\AuthController0%
App\Http\Controllers\Api\V1\LogsController0%
App\Http\Controllers\Api\V1\PlatformAccountsController0%
App\Http\Controllers\Api\V1\PlatformChannelsController0%
App\Http\Controllers\Api\V1\RoutingController0%
App\Http\Controllers\ArticlesController0%
App\Http\Controllers\FeedsController0%
App\Http\Controllers\LogsController0%
App\Http\Controllers\OnboardingController0%
App\Http\Controllers\PlatformAccountsController0%
App\Http\Controllers\PlatformChannelsController0%
App\Http\Controllers\RoutingController0%
App\Http\Controllers\SettingsController0%
App\Http\Middleware\HandleAppearance0%
App\Http\Middleware\HandleInertiaRequests0%
App\Http\Resources\ArticlePublicationResource0%
App\Http\Resources\PlatformAccountResource0%
App\Http\Resources\PlatformChannelResource0%
App\Http\Resources\PlatformInstanceResource0%
App\Http\Resources\RouteResource0%
App\Jobs\ArticleDiscoveryForFeedJob0%
App\Jobs\ArticleDiscoveryJob0%
App\Jobs\PublishToLemmyJob0%
App\Jobs\SyncChannelPostsJob0%
App\Listeners\LogExceptionToDatabase0%
App\Listeners\PublishApprovedArticle0%
App\Listeners\PublishArticle0%
App\Listeners\ValidateArticleListener0%
App\Models\ArticlePublication0%
App\Models\Keyword0%
App\Models\Language0%
App\Models\PlatformAccount0%
App\Models\PlatformChannel0%
App\Models\PlatformChannelPost0%
App\Models\PlatformInstance0%
App\Models\Route0%
App\Models\User0%
App\Modules\Lemmy\LemmyRequest0%
App\Modules\Lemmy\Services\LemmyApiService0%
App\Modules\Lemmy\Services\LemmyPublisher0%
App\Services\Article\ArticleFetcher0%
App\Services\Article\ValidationService0%
App\Services\Auth\LemmyAuthService0%
App\Services\Factories\ArticleParserFactory0%
App\Services\Factories\HomepageParserFactory0%
App\Services\Http\HttpFetcher0%
App\Services\Log\LogSaver0%
App\Services\OnboardingRedirectService0%
App\Services\Parsers\BelgaArticlePageParser0%
App\Services\Parsers\BelgaArticleParser0%
App\Services\Parsers\BelgaHomepageParser0%
App\Services\Parsers\BelgaHomepageParserAdapter0%
App\Services\Parsers\VrtArticlePageParser0%
App\Services\Parsers\VrtArticleParser0%
App\Services\Parsers\VrtHomepageParser0%
App\Services\Parsers\VrtHomepageParserAdapter0%
App\Services\Publishing\ArticlePublishingService0%
App\Services\RoutingValidationService0%
App\Services\SystemStatusService0%
App\Models\Feed4%
App\Providers\HorizonServiceProvider75%
App\Http\Controllers\Api\V1\FeedsController76%
App\Providers\AppServiceProvider82%
App\Http\Controllers\Api\V1\DashboardController84%
App\Http\Controllers\Api\V1\SettingsController85%
App\Http\Controllers\Api\V1\BaseController87%
App\Http\Controllers\Api\V1\ArticlesController87%
-
-
-
-

Project Risks

-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
ClassCRAP
App\Http\Controllers\OnboardingController506
App\Modules\Lemmy\Services\LemmyApiService462
App\Http\Controllers\Api\V1\RoutingController306
App\Services\Parsers\BelgaArticlePageParser306
App\Http\Controllers\RoutingController240
App\Http\Controllers\Api\V1\PlatformAccountsController210
App\Services\Parsers\VrtArticlePageParser210
App\Http\Controllers\Api\V1\PlatformChannelsController182
App\Jobs\SyncChannelPostsJob182
App\Models\Feed161
App\Http\Controllers\Api\V1\AuthController132
App\Services\Article\ArticleFetcher132
App\Http\Controllers\PlatformAccountsController110
App\Http\Controllers\PlatformChannelsController110
App\Models\PlatformAccount110
App\Http\Controllers\FeedsController90
App\Services\Http\HttpFetcher90
App\Services\SystemStatusService72
App\Listeners\ValidateArticleListener56
App\Modules\Lemmy\LemmyRequest42
App\Services\Auth\LemmyAuthService42
App\Services\Factories\ArticleParserFactory42
App\Services\Log\LogSaver42
App\Exceptions\PublishException30
App\Services\Article\ValidationService30
App\Services\Factories\HomepageParserFactory30
App\Services\Publishing\ArticlePublishingService30
App\Services\RoutingValidationService30
App\Listeners\PublishApprovedArticle20
App\Http\Controllers\Api\V1\FeedsController15
App\Console\Commands\FetchNewArticlesCommand12
App\Console\Commands\SyncChannelPostsCommand12
App\Http\Controllers\Api\V1\LogsController12
App\Http\Controllers\SettingsController12
App\Jobs\ArticleDiscoveryJob12
App\Jobs\PublishToLemmyJob12
App\Listeners\PublishArticle12
App\Http\Controllers\Api\V1\SettingsController7
App\Providers\AppServiceProvider6
App\Http\Controllers\Api\V1\BaseController6
App\Services\OnboardingRedirectService6
App\Http\Controllers\Api\V1\ArticlesController5
App\Http\Controllers\Api\V1\DashboardController3
-
-
-
-
-
-

Methods

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
-
-
-

Insufficient Coverage

-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
MethodCoverage
handle0%
handle0%
syncLemmy0%
__construct0%
__construct0%
__construct0%
__construct0%
getPlatform0%
__construct0%
getArticle0%
getPlatform0%
__construct0%
login0%
register0%
logout0%
me0%
sendNotFound0%
sendUnauthorized0%
index0%
index0%
store0%
show0%
update0%
destroy0%
setActive0%
index0%
store0%
show0%
update0%
destroy0%
toggle0%
index0%
store0%
show0%
update0%
destroy0%
toggle0%
__invoke0%
approve0%
reject0%
index0%
create0%
store0%
show0%
edit0%
update0%
destroy0%
toggle0%
__invoke0%
index0%
platform0%
feed0%
channel0%
complete0%
needsOnboarding0%
hasPlatformAccount0%
hasFeed0%
hasChannel0%
index0%
create0%
store0%
edit0%
update0%
destroy0%
setActive0%
index0%
create0%
store0%
show0%
edit0%
update0%
destroy0%
toggle0%
index0%
create0%
store0%
edit0%
update0%
destroy0%
toggle0%
parseJsonFilters0%
index0%
update0%
handle0%
version0%
share0%
toArray0%
toArray0%
toArray0%
toArray0%
toArray0%
__construct0%
handle0%
dispatchForAllActiveFeeds0%
__construct0%
handle0%
__construct0%
handle0%
__construct0%
dispatchForAllActiveChannels0%
handle0%
syncLemmyChannelPosts0%
getAuthToken0%
handle0%
handle0%
__construct0%
handle0%
handle0%
article0%
getTypeDisplayAttribute0%
getStatusAttribute0%
channels0%
activeChannels0%
language0%
feed0%
platformChannel0%
platformInstances0%
platformChannels0%
feeds0%
password0%
apiToken0%
getActive0%
setAsActive0%
channels0%
activeChannels0%
platformInstance0%
platformAccounts0%
activePlatformAccounts0%
getFullNameAttribute0%
feeds0%
activeFeeds0%
language0%
casts0%
urlExists0%
storePost0%
channels0%
languages0%
findByUrl0%
feed0%
platformChannel0%
keywords0%
casts0%
__construct0%
get0%
post0%
withToken0%
__construct0%
login0%
getCommunityId0%
syncChannelPosts0%
createPost0%
getLanguages0%
__construct0%
publishToChannel0%
mapExceptionToLogLevel0%
getArticlesFromFeed0%
getArticlesFromRssFeed0%
getArticlesFromWebsiteFeed0%
fetchArticleData0%
saveArticle0%
validate0%
validateByKeywords0%
getToken0%
getParser0%
getSupportedSources0%
registerParser0%
getParser0%
getParserForFeed0%
fetchHtml0%
fetchMultipleUrls0%
info0%
error0%
warning0%
debug0%
log0%
handleRedirect0%
extractTitle0%
extractDescription0%
extractFullArticle0%
extractThumbnail0%
extractData0%
canParse0%
extractData0%
getSourceName0%
extractArticleUrls0%
canParse0%
extractArticleUrls0%
getHomepageUrl0%
getSourceName0%
extractTitle0%
extractDescription0%
extractFullArticle0%
extractThumbnail0%
extractData0%
canParse0%
extractData0%
getSourceName0%
extractArticleUrls0%
canParse0%
extractArticleUrls0%
getHomepageUrl0%
getSourceName0%
publishToRoutedChannels0%
publishToChannel0%
validateLanguageCompatibility0%
getSystemStatus0%
canProcessArticles0%
update63%
store66%
gate66%
approve71%
reject71%
destroy71%
index71%
toggle77%
stats83%
-
-
- -
- -
- - - - - - diff --git a/backend/coverage-report-final/index.html b/backend/coverage-report-final/index.html deleted file mode 100644 index 7e3b142d..00000000 --- a/backend/coverage-report-final/index.html +++ /dev/null @@ -1,424 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 17.43% covered (danger) -
-
-
17.43%
290 / 1664
-
- 16.15% covered (danger) -
-
-
16.15%
42 / 260
-
- 11.76% covered (danger) -
-
-
11.76%
10 / 85
Console
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 16
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
Contracts
n/a
0 / 0
n/a
0 / 0
n/a
0 / 0
Enums
n/a
0 / 0
n/a
0 / 0
n/a
0 / 0
Events
-
- 40.00% covered (danger) -
-
-
40.00%
2 / 5
-
- 40.00% covered (danger) -
-
-
40.00%
2 / 5
-
- 40.00% covered (danger) -
-
-
40.00%
2 / 5
Exceptions
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 19
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 6
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
Http
-
- 20.07% covered (danger) -
-
-
20.07%
164 / 817
-
- 12.87% covered (danger) -
-
-
12.87%
13 / 101
-
- 13.79% covered (danger) -
-
-
13.79%
4 / 29
Jobs
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 81
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 12
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 4
Listeners
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 43
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 5
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 4
Models
-
- 32.89% covered (danger) -
-
-
32.89%
50 / 152
-
- 37.04% covered (danger) -
-
-
37.04%
20 / 54
-
- 16.67% covered (danger) -
-
-
16.67%
2 / 12
Modules
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 120
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 12
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
Providers
-
- 81.82% covered (warning) -
-
-
81.82%
27 / 33
-
- 40.00% covered (danger) -
-
-
40.00%
2 / 5
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
Services
-
- 10.78% covered (danger) -
-
-
10.78%
40 / 371
-
- 7.14% covered (danger) -
-
-
7.14%
4 / 56
-
- 5.00% covered (danger) -
-
-
5.00%
1 / 20
LogLevelEnum.php
-
- 100.00% covered (success) -
-
-
100.00%
7 / 7
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
-
- -
- - diff --git a/backend/coverage-report-progress/Console/Commands/FetchNewArticlesCommand.php.html b/backend/coverage-report-progress/Console/Commands/FetchNewArticlesCommand.php.html deleted file mode 100644 index eb2c9922..00000000 --- a/backend/coverage-report-progress/Console/Commands/FetchNewArticlesCommand.php.html +++ /dev/null @@ -1,187 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Console/Commands/FetchNewArticlesCommand.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 8
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
FetchNewArticlesCommand
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 8
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
12
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 handle
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 8
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
12
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Console\Commands;
4
5use App\Jobs\ArticleDiscoveryJob;
6use App\Models\Feed;
7use App\Models\Setting;
8use Illuminate\Console\Command;
9
10class FetchNewArticlesCommand extends Command
11{
12    protected $signature = 'article:refresh';
13
14    protected $description = 'Fetches latest articles';
15
16    public function handle(): int
17    {
18        if (!Setting::isArticleProcessingEnabled()) {
19            $this->info('Article processing is disabled. Article discovery skipped.');
20
21            return self::SUCCESS;
22        }
23
24        if (!Feed::where('is_active', true)->exists()) {
25            $this->info('No active feeds found. Article discovery skipped.');
26
27            return self::SUCCESS;
28        }
29
30        ArticleDiscoveryJob::dispatch();
31
32        return self::SUCCESS;
33    }
34}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:50:30 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-progress/Console/Commands/SyncChannelPostsCommand.php.html b/backend/coverage-report-progress/Console/Commands/SyncChannelPostsCommand.php.html deleted file mode 100644 index 46f4213b..00000000 --- a/backend/coverage-report-progress/Console/Commands/SyncChannelPostsCommand.php.html +++ /dev/null @@ -1,209 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Console/Commands/SyncChannelPostsCommand.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 8
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
SyncChannelPostsCommand
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 8
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
12
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 handle
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 5
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
6
 syncLemmy
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Console\Commands;
4
5use App\Jobs\SyncChannelPostsJob;
6use Illuminate\Console\Command;
7
8class SyncChannelPostsCommand extends Command
9{
10    protected $signature = 'channel:sync {platform=lemmy}';
11
12    protected $description = 'Manually sync channel posts for a platform';
13
14    public function handle(): int
15    {
16        $platform = $this->argument('platform');
17
18        if ($platform === 'lemmy') {
19            return $this->syncLemmy();
20        }
21
22        $this->error("Unsupported platform: {$platform}");
23
24        return self::FAILURE;
25    }
26
27    private function syncLemmy(): int
28    {
29        SyncChannelPostsJob::dispatchForAllActiveChannels();
30        $this->info('Successfully dispatched sync jobs for all active Lemmy channels');
31
32        return self::SUCCESS;
33    }
34}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:50:30 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-progress/Console/Commands/dashboard.html b/backend/coverage-report-progress/Console/Commands/dashboard.html deleted file mode 100644 index fbeeaa6b..00000000 --- a/backend/coverage-report-progress/Console/Commands/dashboard.html +++ /dev/null @@ -1,294 +0,0 @@ - - - - - Dashboard for /var/www/html/backend/app/Console/Commands - - - - - - - -
-
-
-
- -
-
-
-
-
-
-
-

Classes

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
-
-
-

Insufficient Coverage

- -
-
-

Project Risks

- -
-
-
-
-

Methods

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
-
-
-

Insufficient Coverage

-
- - - - - - - - - - - - - -
MethodCoverage
handle0%
handle0%
syncLemmy0%
-
-
-
-

Project Risks

-
- - - - - - - - - - - - -
MethodCRAP
handle12
handle6
-
-
-
- -
- - - - - - diff --git a/backend/coverage-report-progress/Console/Commands/index.html b/backend/coverage-report-progress/Console/Commands/index.html deleted file mode 100644 index 33ccb5b2..00000000 --- a/backend/coverage-report-progress/Console/Commands/index.html +++ /dev/null @@ -1,148 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Console/Commands - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 16
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
FetchNewArticlesCommand.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 8
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
SyncChannelPostsCommand.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 8
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- -
- - diff --git a/backend/coverage-report-progress/Console/dashboard.html b/backend/coverage-report-progress/Console/dashboard.html deleted file mode 100644 index 13c87f2e..00000000 --- a/backend/coverage-report-progress/Console/dashboard.html +++ /dev/null @@ -1,293 +0,0 @@ - - - - - Dashboard for /var/www/html/backend/app/Console - - - - - - - -
-
-
-
- -
-
-
-
-
-
-
-

Classes

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
-
-
-

Insufficient Coverage

- -
-
-

Project Risks

- -
-
-
-
-

Methods

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
-
-
-

Insufficient Coverage

-
- - - - - - - - - - - - - -
MethodCoverage
handle0%
handle0%
syncLemmy0%
-
-
-
-

Project Risks

-
- - - - - - - - - - - - -
MethodCRAP
handle12
handle6
-
-
-
- -
- - - - - - diff --git a/backend/coverage-report-progress/Console/index.html b/backend/coverage-report-progress/Console/index.html deleted file mode 100644 index f4035166..00000000 --- a/backend/coverage-report-progress/Console/index.html +++ /dev/null @@ -1,119 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Console - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 16
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
Commands
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 16
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
-
- -
- - diff --git a/backend/coverage-report-progress/Contracts/ArticleParserInterface.php.html b/backend/coverage-report-progress/Contracts/ArticleParserInterface.php.html deleted file mode 100644 index d9cf1aed..00000000 --- a/backend/coverage-report-progress/Contracts/ArticleParserInterface.php.html +++ /dev/null @@ -1,108 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Contracts/ArticleParserInterface.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
n/a
0 / 0
n/a
0 / 0
CRAP
n/a
0 / 0
-
- - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Contracts;
4
5interface ArticleParserInterface
6{
7    /**
8     * Check if this parser can handle the given URL
9     */
10    public function canParse(string $url): bool;
11
12    /**
13     * Extract article data from HTML
14     * @return array<string, mixed>
15     */
16    public function extractData(string $html): array;
17
18    /**
19     * Get the source name for this parser
20     */
21    public function getSourceName(): string;
22}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:50:30 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-progress/Contracts/HomepageParserInterface.php.html b/backend/coverage-report-progress/Contracts/HomepageParserInterface.php.html deleted file mode 100644 index 62d2f87c..00000000 --- a/backend/coverage-report-progress/Contracts/HomepageParserInterface.php.html +++ /dev/null @@ -1,113 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Contracts/HomepageParserInterface.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
n/a
0 / 0
n/a
0 / 0
CRAP
n/a
0 / 0
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Contracts;
4
5interface HomepageParserInterface
6{
7    /**
8     * Check if this parser can handle the given homepage URL
9     */
10    public function canParse(string $url): bool;
11
12    /**
13     * Extract article URLs from homepage HTML
14     * @return array<int, string>
15     */
16    public function extractArticleUrls(string $html): array;
17
18    /**
19     * Get the homepage URL for this source
20     */
21    public function getHomepageUrl(): string;
22
23    /**
24     * Get the source name for this parser
25     */
26    public function getSourceName(): string;
27}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:50:30 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-progress/Contracts/dashboard.html b/backend/coverage-report-progress/Contracts/dashboard.html deleted file mode 100644 index 05232b52..00000000 --- a/backend/coverage-report-progress/Contracts/dashboard.html +++ /dev/null @@ -1,284 +0,0 @@ - - - - - Dashboard for /var/www/html/backend/app/Contracts - - - - - - - -
-
-
-
- -
-
-
-
-
-
-
-

Classes

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
-
-
-

Insufficient Coverage

-
- - - - - - - - - - -
ClassCoverage
-
-
-
-

Project Risks

-
- - - - - - - - - - -
ClassCRAP
-
-
-
-
-
-

Methods

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
-
-
-

Insufficient Coverage

-
- - - - - - - - - - -
MethodCoverage
-
-
-
-

Project Risks

-
- - - - - - - - - - -
MethodCRAP
-
-
-
- -
- - - - - - diff --git a/backend/coverage-report-progress/Contracts/index.html b/backend/coverage-report-progress/Contracts/index.html deleted file mode 100644 index ba330950..00000000 --- a/backend/coverage-report-progress/Contracts/index.html +++ /dev/null @@ -1,102 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Contracts - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
n/a
0 / 0
n/a
0 / 0
n/a
0 / 0
ArticleParserInterface.php
n/a
0 / 0
n/a
0 / 0
n/a
0 / 0
HomepageParserInterface.php
n/a
0 / 0
n/a
0 / 0
n/a
0 / 0
-
- -
- - diff --git a/backend/coverage-report-progress/Enums/PlatformEnum.php.html b/backend/coverage-report-progress/Enums/PlatformEnum.php.html deleted file mode 100644 index 33096c65..00000000 --- a/backend/coverage-report-progress/Enums/PlatformEnum.php.html +++ /dev/null @@ -1,94 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Enums/PlatformEnum.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
n/a
0 / 0
n/a
0 / 0
CRAP
n/a
0 / 0
-
- - - - - - - - - - - - -
1<?php
2
3namespace App\Enums;
4
5enum PlatformEnum: string
6{
7    case LEMMY = 'lemmy';
8}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:50:30 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-progress/Enums/dashboard.html b/backend/coverage-report-progress/Enums/dashboard.html deleted file mode 100644 index d20b6371..00000000 --- a/backend/coverage-report-progress/Enums/dashboard.html +++ /dev/null @@ -1,284 +0,0 @@ - - - - - Dashboard for /var/www/html/backend/app/Enums - - - - - - - -
-
-
-
- -
-
-
-
-
-
-
-

Classes

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
-
-
-

Insufficient Coverage

-
- - - - - - - - - - -
ClassCoverage
-
-
-
-

Project Risks

-
- - - - - - - - - - -
ClassCRAP
-
-
-
-
-
-

Methods

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
-
-
-

Insufficient Coverage

-
- - - - - - - - - - -
MethodCoverage
-
-
-
-

Project Risks

-
- - - - - - - - - - -
MethodCRAP
-
-
-
- -
- - - - - - diff --git a/backend/coverage-report-progress/Enums/index.html b/backend/coverage-report-progress/Enums/index.html deleted file mode 100644 index ba2d4265..00000000 --- a/backend/coverage-report-progress/Enums/index.html +++ /dev/null @@ -1,89 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Enums - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
n/a
0 / 0
n/a
0 / 0
n/a
0 / 0
PlatformEnum.php
n/a
0 / 0
n/a
0 / 0
n/a
0 / 0
-
- -
- - diff --git a/backend/coverage-report-progress/Events/ArticleApproved.php.html b/backend/coverage-report-progress/Events/ArticleApproved.php.html deleted file mode 100644 index a2c46b6e..00000000 --- a/backend/coverage-report-progress/Events/ArticleApproved.php.html +++ /dev/null @@ -1,169 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Events/ArticleApproved.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
CRAP
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
ArticleApproved
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
1
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
 __construct
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
1
-
- - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Events;
4
5use App\Models\Article;
6use Illuminate\Foundation\Events\Dispatchable;
7use Illuminate\Queue\SerializesModels;
8
9class ArticleApproved
10{
11    use Dispatchable, SerializesModels;
12
13    public function __construct(public Article $article)
14    {
15        //
16    }
17}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:50:30 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-progress/Events/ArticleReadyToPublish.php.html b/backend/coverage-report-progress/Events/ArticleReadyToPublish.php.html deleted file mode 100644 index 0604fea0..00000000 --- a/backend/coverage-report-progress/Events/ArticleReadyToPublish.php.html +++ /dev/null @@ -1,170 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Events/ArticleReadyToPublish.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
ArticleReadyToPublish
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 __construct
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Events;
4
5use App\Models\Article;
6use Illuminate\Broadcasting\InteractsWithSockets;
7use Illuminate\Foundation\Events\Dispatchable;
8use Illuminate\Queue\SerializesModels;
9
10class ArticleReadyToPublish
11{
12    use Dispatchable, InteractsWithSockets, SerializesModels;
13
14    public function __construct(public Article $article)
15    {
16
17    }
18}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:50:30 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-progress/Events/ExceptionLogged.php.html b/backend/coverage-report-progress/Events/ExceptionLogged.php.html deleted file mode 100644 index 6402e310..00000000 --- a/backend/coverage-report-progress/Events/ExceptionLogged.php.html +++ /dev/null @@ -1,169 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Events/ExceptionLogged.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
ExceptionLogged
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 __construct
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Events;
4
5use App\Models\Log;
6use Illuminate\Foundation\Events\Dispatchable;
7use Illuminate\Queue\SerializesModels;
8
9class ExceptionLogged
10{
11    use Dispatchable, SerializesModels;
12
13    public function __construct(
14        public Log $log
15    ) {
16    }
17}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:50:30 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-progress/Events/ExceptionOccurred.php.html b/backend/coverage-report-progress/Events/ExceptionOccurred.php.html deleted file mode 100644 index bd32a021..00000000 --- a/backend/coverage-report-progress/Events/ExceptionOccurred.php.html +++ /dev/null @@ -1,174 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Events/ExceptionOccurred.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
ExceptionOccurred
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 __construct
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Events;
4
5use App\LogLevelEnum;
6use Illuminate\Foundation\Events\Dispatchable;
7use Illuminate\Queue\SerializesModels;
8use Throwable;
9
10class ExceptionOccurred
11{
12    use Dispatchable, SerializesModels;
13
14    public function __construct(
15        public Throwable $exception,
16        public LogLevelEnum $level,
17        public string $message,
18        /** @var array<string, mixed> */
19        public array $context = []
20    ) {
21    }
22}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:50:30 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-progress/Events/NewArticleFetched.php.html b/backend/coverage-report-progress/Events/NewArticleFetched.php.html deleted file mode 100644 index 5f745a55..00000000 --- a/backend/coverage-report-progress/Events/NewArticleFetched.php.html +++ /dev/null @@ -1,169 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Events/NewArticleFetched.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
CRAP
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
NewArticleFetched
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
1
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
 __construct
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
1
-
- - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Events;
4
5use App\Models\Article;
6use Illuminate\Broadcasting\InteractsWithSockets;
7use Illuminate\Foundation\Events\Dispatchable;
8use Illuminate\Queue\SerializesModels;
9
10class NewArticleFetched
11{
12    use Dispatchable, InteractsWithSockets, SerializesModels;
13
14    public function __construct(public Article $article)
15    {
16    }
17}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:50:30 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-progress/Events/dashboard.html b/backend/coverage-report-progress/Events/dashboard.html deleted file mode 100644 index 1a201ea1..00000000 --- a/backend/coverage-report-progress/Events/dashboard.html +++ /dev/null @@ -1,290 +0,0 @@ - - - - - Dashboard for /var/www/html/backend/app/Events - - - - - - - -
-
-
-
- -
-
-
-
-
-
-
-

Classes

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
-
-
-

Insufficient Coverage

- -
-
-

Project Risks

-
- - - - - - - - - - -
ClassCRAP
-
-
-
-
-
-

Methods

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
-
-
-

Insufficient Coverage

-
- - - - - - - - - - - - - -
MethodCoverage
__construct0%
__construct0%
__construct0%
-
-
-
-

Project Risks

-
- - - - - - - - - - -
MethodCRAP
-
-
-
- -
- - - - - - diff --git a/backend/coverage-report-progress/Events/index.html b/backend/coverage-report-progress/Events/index.html deleted file mode 100644 index c81604d4..00000000 --- a/backend/coverage-report-progress/Events/index.html +++ /dev/null @@ -1,231 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Events - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 40.00% covered (danger) -
-
-
40.00%
2 / 5
-
- 40.00% covered (danger) -
-
-
40.00%
2 / 5
-
- 40.00% covered (danger) -
-
-
40.00%
2 / 5
ArticleApproved.php
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
ArticleReadyToPublish.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
ExceptionLogged.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
ExceptionOccurred.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
NewArticleFetched.php
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
-
- -
- - diff --git a/backend/coverage-report-progress/Exceptions/ChannelException.php.html b/backend/coverage-report-progress/Exceptions/ChannelException.php.html deleted file mode 100644 index f769d88d..00000000 --- a/backend/coverage-report-progress/Exceptions/ChannelException.php.html +++ /dev/null @@ -1,109 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Exceptions/ChannelException.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
n/a
0 / 0
n/a
0 / 0
CRAP
n/a
0 / 0
ChannelException
n/a
0 / 0
n/a
0 / 0
0
n/a
0 / 0
-
- - - - - - - - - - - - - -
1<?php
2
3namespace App\Exceptions;
4
5use Exception;
6
7class ChannelException extends Exception
8{
9}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:50:30 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-progress/Exceptions/PlatformAuthException.php.html b/backend/coverage-report-progress/Exceptions/PlatformAuthException.php.html deleted file mode 100644 index 4dd33691..00000000 --- a/backend/coverage-report-progress/Exceptions/PlatformAuthException.php.html +++ /dev/null @@ -1,197 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Exceptions/PlatformAuthException.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
PlatformAuthException
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
6
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 __construct
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 getPlatform
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Exceptions;
4
5use App\Enums\PlatformEnum;
6use Exception;
7
8class PlatformAuthException extends Exception
9{
10    public function __construct(
11        private readonly PlatformEnum $platform,
12        string $reason = 'Authentication failed'
13    ) {
14        $message = "Failed to authenticate with {$platform->value}: {$reason}";
15
16        parent::__construct($message);
17    }
18
19    public function getPlatform(): PlatformEnum
20    {
21        return $this->platform;
22    }
23}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:50:30 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-progress/Exceptions/PublishException.php.html b/backend/coverage-report-progress/Exceptions/PublishException.php.html deleted file mode 100644 index 67f2936b..00000000 --- a/backend/coverage-report-progress/Exceptions/PublishException.php.html +++ /dev/null @@ -1,235 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Exceptions/PublishException.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 8
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
PublishException
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 8
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
30
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 __construct
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 6
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
12
 getArticle
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 getPlatform
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Exceptions;
4
5use App\Enums\PlatformEnum;
6use App\Models\Article;
7use Exception;
8use Throwable;
9
10class PublishException extends Exception
11{
12    public function __construct(
13        private readonly Article $article,
14        private readonly PlatformEnum|null $platform,
15        ?Throwable $previous = null
16    ) {
17        $message = "Failed to publish article #$article->id";
18
19        if ($this->platform) {
20            $message .= "  to $platform->value";
21        }
22
23        if ($previous) {
24            $message .= ": {$previous->getMessage()}";
25        }
26
27        parent::__construct($message, 0, $previous);
28    }
29
30    public function getArticle(): Article
31    {
32        return $this->article;
33    }
34
35    public function getPlatform(): ?PlatformEnum
36    {
37        return $this->platform;
38    }
39}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:50:30 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-progress/Exceptions/RoutingException.php.html b/backend/coverage-report-progress/Exceptions/RoutingException.php.html deleted file mode 100644 index de79c882..00000000 --- a/backend/coverage-report-progress/Exceptions/RoutingException.php.html +++ /dev/null @@ -1,109 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Exceptions/RoutingException.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
n/a
0 / 0
n/a
0 / 0
CRAP
n/a
0 / 0
RoutingException
n/a
0 / 0
n/a
0 / 0
0
n/a
0 / 0
-
- - - - - - - - - - - - - -
1<?php
2
3namespace App\Exceptions;
4
5use Exception;
6
7class RoutingException extends Exception
8{
9}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:50:30 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-progress/Exceptions/RoutingMismatchException.php.html b/backend/coverage-report-progress/Exceptions/RoutingMismatchException.php.html deleted file mode 100644 index adc2eb83..00000000 --- a/backend/coverage-report-progress/Exceptions/RoutingMismatchException.php.html +++ /dev/null @@ -1,174 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Exceptions/RoutingMismatchException.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 8
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
RoutingMismatchException
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 8
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 __construct
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 8
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Exceptions;
4
5use App\Models\Feed;
6use App\Models\PlatformChannel;
7
8class RoutingMismatchException extends RoutingException
9{
10    public function __construct(Feed $feed, PlatformChannel $channel)
11    {
12        $message = sprintf(
13            "Language mismatch: Feed '%s' is in '%s' but channel '%s' is set to '%s'. Feed and channel languages must match for proper content routing.",
14            $feed->name,
15            $feed->language,
16            $channel->name,
17            $channel->language
18        );
19
20        parent::__construct($message);
21    }
22}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:50:30 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-progress/Exceptions/dashboard.html b/backend/coverage-report-progress/Exceptions/dashboard.html deleted file mode 100644 index c1dfefd3..00000000 --- a/backend/coverage-report-progress/Exceptions/dashboard.html +++ /dev/null @@ -1,295 +0,0 @@ - - - - - Dashboard for /var/www/html/backend/app/Exceptions - - - - - - - -
-
-
-
- -
-
-
-
-
-
-
-

Classes

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
-
-
-

Insufficient Coverage

- -
-
-

Project Risks

-
- - - - - - - - - - - -
ClassCRAP
App\Exceptions\PublishException30
-
-
-
-
-
-

Methods

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
-
-
-

Insufficient Coverage

-
- - - - - - - - - - - - - - - - -
MethodCoverage
__construct0%
getPlatform0%
__construct0%
getArticle0%
getPlatform0%
__construct0%
-
-
-
-

Project Risks

-
- - - - - - - - - - - -
MethodCRAP
__construct12
-
-
-
- -
- - - - - - diff --git a/backend/coverage-report-progress/Exceptions/index.html b/backend/coverage-report-progress/Exceptions/index.html deleted file mode 100644 index 062a7584..00000000 --- a/backend/coverage-report-progress/Exceptions/index.html +++ /dev/null @@ -1,201 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Exceptions - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 19
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 6
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
ChannelException.php
n/a
0 / 0
n/a
0 / 0
n/a
0 / 0
PlatformAuthException.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
PublishException.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 8
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
RoutingException.php
n/a
0 / 0
n/a
0 / 0
n/a
0 / 0
RoutingMismatchException.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 8
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- -
- - diff --git a/backend/coverage-report-progress/Http/Controllers/Api/V1/ArticlesController.php.html b/backend/coverage-report-progress/Http/Controllers/Api/V1/ArticlesController.php.html deleted file mode 100644 index ab64f2cb..00000000 --- a/backend/coverage-report-progress/Http/Controllers/Api/V1/ArticlesController.php.html +++ /dev/null @@ -1,273 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Http/Controllers/Api/V1/ArticlesController.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 87.88% covered (warning) -
-
-
87.88%
29 / 33
-
- 33.33% covered (danger) -
-
-
33.33%
1 / 3
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
ArticlesController
-
- 87.88% covered (warning) -
-
-
87.88%
29 / 33
-
- 33.33% covered (danger) -
-
-
33.33%
1 / 3
5.04
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 index
-
- 100.00% covered (success) -
-
-
100.00%
19 / 19
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
1
 approve
-
- 71.43% covered (warning) -
-
-
71.43%
5 / 7
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2.09
 reject
-
- 71.43% covered (warning) -
-
-
71.43%
5 / 7
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2.09
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Http\Controllers\Api\V1;
4
5use App\Http\Resources\ArticleResource;
6use App\Models\Article;
7use App\Models\Setting;
8use Illuminate\Http\JsonResponse;
9use Illuminate\Http\Request;
10
11class ArticlesController extends BaseController
12{
13    /**
14     * Display a listing of articles
15     */
16    public function index(Request $request): JsonResponse
17    {
18        $perPage = min($request->get('per_page', 15), 100); // Max 100 items per page
19        $articles = Article::with(['feed', 'articlePublication'])
20            ->orderBy('created_at', 'desc')
21            ->paginate($perPage);
22
23        $publishingApprovalsEnabled = Setting::isPublishingApprovalsEnabled();
24
25        return $this->sendResponse([
26            'articles' => ArticleResource::collection($articles->items()),
27            'pagination' => [
28                'current_page' => $articles->currentPage(),
29                'last_page' => $articles->lastPage(),
30                'per_page' => $articles->perPage(),
31                'total' => $articles->total(),
32                'from' => $articles->firstItem(),
33                'to' => $articles->lastItem(),
34            ],
35            'settings' => [
36                'publishing_approvals_enabled' => $publishingApprovalsEnabled,
37            ],
38        ]);
39    }
40
41    /**
42     * Approve an article
43     */
44    public function approve(Article $article): JsonResponse
45    {
46        try {
47            $article->approve('manual');
48            
49            return $this->sendResponse(
50                new ArticleResource($article->fresh(['feed', 'articlePublication'])),
51                'Article approved and queued for publishing.'
52            );
53        } catch (\Exception $e) {
54            return $this->sendError('Failed to approve article: ' . $e->getMessage(), [], 500);
55        }
56    }
57
58    /**
59     * Reject an article
60     */
61    public function reject(Article $article): JsonResponse
62    {
63        try {
64            $article->reject('manual');
65            
66            return $this->sendResponse(
67                new ArticleResource($article->fresh(['feed', 'articlePublication'])),
68                'Article rejected.'
69            );
70        } catch (\Exception $e) {
71            return $this->sendError('Failed to reject article: ' . $e->getMessage(), [], 500);
72        }
73    }
74}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:50:30 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-progress/Http/Controllers/Api/V1/AuthController.php.html b/backend/coverage-report-progress/Http/Controllers/Api/V1/AuthController.php.html deleted file mode 100644 index 962d17a4..00000000 --- a/backend/coverage-report-progress/Http/Controllers/Api/V1/AuthController.php.html +++ /dev/null @@ -1,333 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Http/Controllers/Api/V1/AuthController.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 56
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 4
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
AuthController
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 56
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 4
132
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 login
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 21
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
30
 register
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 24
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
12
 logout
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 4
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
6
 me
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 7
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Http\Controllers\Api\V1;
4
5use App\Models\User;
6use Illuminate\Http\JsonResponse;
7use Illuminate\Http\Request;
8use Illuminate\Support\Facades\Auth;
9use Illuminate\Support\Facades\Hash;
10use Illuminate\Validation\ValidationException;
11
12class AuthController extends BaseController
13{
14    /**
15     * Login user and create token
16     */
17    public function login(Request $request): JsonResponse
18    {
19        try {
20            $request->validate([
21                'email' => 'required|email',
22                'password' => 'required',
23            ]);
24
25            $user = User::where('email', $request->email)->first();
26
27            if (!$user || !Hash::check($request->password, $user->password)) {
28                return $this->sendError('Invalid credentials', [], 401);
29            }
30
31            $token = $user->createToken('api-token')->plainTextToken;
32
33            return $this->sendResponse([
34                'user' => [
35                    'id' => $user->id,
36                    'name' => $user->name,
37                    'email' => $user->email,
38                ],
39                'token' => $token,
40                'token_type' => 'Bearer',
41            ], 'Login successful');
42        } catch (ValidationException $e) {
43            return $this->sendValidationError($e->errors());
44        } catch (\Exception $e) {
45            return $this->sendError('Login failed: ' . $e->getMessage(), [], 500);
46        }
47    }
48
49    /**
50     * Register a new user
51     */
52    public function register(Request $request): JsonResponse
53    {
54        try {
55            $validated = $request->validate([
56                'name' => 'required|string|max:255',
57                'email' => 'required|string|email|max:255|unique:users',
58                'password' => 'required|string|min:8|confirmed',
59            ]);
60
61            $user = User::create([
62                'name' => $validated['name'],
63                'email' => $validated['email'],
64                'password' => Hash::make($validated['password']),
65            ]);
66
67            $token = $user->createToken('api-token')->plainTextToken;
68
69            return $this->sendResponse([
70                'user' => [
71                    'id' => $user->id,
72                    'name' => $user->name,
73                    'email' => $user->email,
74                ],
75                'token' => $token,
76                'token_type' => 'Bearer',
77            ], 'Registration successful', 201);
78        } catch (ValidationException $e) {
79            return $this->sendValidationError($e->errors());
80        } catch (\Exception $e) {
81            return $this->sendError('Registration failed: ' . $e->getMessage(), [], 500);
82        }
83    }
84
85    /**
86     * Logout user (revoke token)
87     */
88    public function logout(Request $request): JsonResponse
89    {
90        try {
91            $request->user()->currentAccessToken()->delete();
92
93            return $this->sendResponse(null, 'Logged out successfully');
94        } catch (\Exception $e) {
95            return $this->sendError('Logout failed: ' . $e->getMessage(), [], 500);
96        }
97    }
98
99    /**
100     * Get current authenticated user
101     */
102    public function me(Request $request): JsonResponse
103    {
104        return $this->sendResponse([
105            'user' => [
106                'id' => $request->user()->id,
107                'name' => $request->user()->name,
108                'email' => $request->user()->email,
109            ],
110        ], 'User retrieved successfully');
111    }
112}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:50:30 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-progress/Http/Controllers/Api/V1/BaseController.php.html b/backend/coverage-report-progress/Http/Controllers/Api/V1/BaseController.php.html deleted file mode 100644 index f3f52e64..00000000 --- a/backend/coverage-report-progress/Http/Controllers/Api/V1/BaseController.php.html +++ /dev/null @@ -1,307 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Http/Controllers/Api/V1/BaseController.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 37.50% covered (danger) -
-
-
37.50%
6 / 16
-
- 20.00% covered (danger) -
-
-
20.00%
1 / 5
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
BaseController
-
- 37.50% covered (danger) -
-
-
37.50%
6 / 16
-
- 20.00% covered (danger) -
-
-
20.00%
1 / 5
14.79
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 sendResponse
-
- 100.00% covered (success) -
-
-
100.00%
6 / 6
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
1
 sendError
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 7
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
6
 sendValidationError
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 sendNotFound
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 sendUnauthorized
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Http\Controllers\Api\V1;
4
5use App\Http\Controllers\Controller;
6use Illuminate\Http\JsonResponse;
7
8class BaseController extends Controller
9{
10    /**
11     * Success response method
12     */
13    public function sendResponse(mixed $result, string $message = 'Success', int $code = 200): JsonResponse
14    {
15        $response = [
16            'success' => true,
17            'data' => $result,
18            'message' => $message,
19        ];
20
21        return response()->json($response, $code);
22    }
23
24    /**
25     * Error response method
26     */
27    public function sendError(string $error, array $errorMessages = [], int $code = 400): JsonResponse
28    {
29        $response = [
30            'success' => false,
31            'message' => $error,
32        ];
33
34        if (!empty($errorMessages)) {
35            $response['errors'] = $errorMessages;
36        }
37
38        return response()->json($response, $code);
39    }
40
41    /**
42     * Validation error response method
43     */
44    public function sendValidationError(array $errors): JsonResponse
45    {
46        return $this->sendError('Validation failed', $errors, 422);
47    }
48
49    /**
50     * Not found response method
51     */
52    public function sendNotFound(string $message = 'Resource not found'): JsonResponse
53    {
54        return $this->sendError($message, [], 404);
55    }
56
57    /**
58     * Unauthorized response method
59     */
60    public function sendUnauthorized(string $message = 'Unauthorized'): JsonResponse
61    {
62        return $this->sendError($message, [], 401);
63    }
64}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:50:30 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-progress/Http/Controllers/Api/V1/DashboardController.php.html b/backend/coverage-report-progress/Http/Controllers/Api/V1/DashboardController.php.html deleted file mode 100644 index bfedf3d7..00000000 --- a/backend/coverage-report-progress/Http/Controllers/Api/V1/DashboardController.php.html +++ /dev/null @@ -1,223 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Http/Controllers/Api/V1/DashboardController.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 84.62% covered (warning) -
-
-
84.62%
11 / 13
-
- 50.00% covered (danger) -
-
-
50.00%
1 / 2
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
DashboardController
-
- 84.62% covered (warning) -
-
-
84.62%
11 / 13
-
- 50.00% covered (danger) -
-
-
50.00%
1 / 2
3.03
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 __construct
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
1
 stats
-
- 83.33% covered (warning) -
-
-
83.33%
10 / 12
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2.02
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Http\Controllers\Api\V1;
4
5use App\Models\Article;
6use App\Models\Feed;
7use App\Models\PlatformAccount;
8use App\Models\PlatformChannel;
9use App\Services\DashboardStatsService;
10use Illuminate\Http\JsonResponse;
11use Illuminate\Http\Request;
12
13class DashboardController extends BaseController
14{
15    public function __construct(
16        private DashboardStatsService $dashboardStatsService
17    ) {}
18
19    /**
20     * Get dashboard statistics
21     */
22    public function stats(Request $request): JsonResponse
23    {
24        $period = $request->get('period', 'today');
25        
26        try {
27            // Get article stats from service
28            $articleStats = $this->dashboardStatsService->getStats($period);
29            
30            // Get system stats
31            $systemStats = $this->dashboardStatsService->getSystemStats();
32            
33            // Get available periods
34            $availablePeriods = $this->dashboardStatsService->getAvailablePeriods();
35            
36            return $this->sendResponse([
37                'article_stats' => $articleStats,
38                'system_stats' => $systemStats,
39                'available_periods' => $availablePeriods,
40                'current_period' => $period,
41            ]);
42        } catch (\Exception $e) {
43            return $this->sendError('Failed to fetch dashboard stats: ' . $e->getMessage(), [], 500);
44        }
45    }
46}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:50:30 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-progress/Http/Controllers/Api/V1/FeedsController.php.html b/backend/coverage-report-progress/Http/Controllers/Api/V1/FeedsController.php.html deleted file mode 100644 index 3d380a7e..00000000 --- a/backend/coverage-report-progress/Http/Controllers/Api/V1/FeedsController.php.html +++ /dev/null @@ -1,387 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Http/Controllers/Api/V1/FeedsController.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 50
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 6
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
FeedsController
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 50
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 6
182
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 index
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 7
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 store
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 12
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
12
 show
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 4
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 update
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 11
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
12
 destroy
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 7
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
6
 toggle
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 9
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
12
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Http\Controllers\Api\V1;
4
5use App\Http\Requests\StoreFeedRequest;
6use App\Http\Requests\UpdateFeedRequest;
7use App\Http\Resources\FeedResource;
8use App\Models\Feed;
9use Illuminate\Http\JsonResponse;
10use Illuminate\Http\Request;
11use Illuminate\Validation\ValidationException;
12
13class FeedsController extends BaseController
14{
15    /**
16     * Display a listing of feeds
17     */
18    public function index(Request $request): JsonResponse
19    {
20        $feeds = Feed::orderBy('is_active', 'desc')
21            ->orderBy('name')
22            ->get();
23
24        return $this->sendResponse(
25            FeedResource::collection($feeds),
26            'Feeds retrieved successfully.'
27        );
28    }
29
30    /**
31     * Store a newly created feed
32     */
33    public function store(StoreFeedRequest $request): JsonResponse
34    {
35        try {
36            $validated = $request->validated();
37            $validated['is_active'] = $validated['is_active'] ?? true;
38
39            $feed = Feed::create($validated);
40
41            return $this->sendResponse(
42                new FeedResource($feed),
43                'Feed created successfully!',
44                201
45            );
46        } catch (ValidationException $e) {
47            return $this->sendValidationError($e->errors());
48        } catch (\Exception $e) {
49            return $this->sendError('Failed to create feed: ' . $e->getMessage(), [], 500);
50        }
51    }
52
53    /**
54     * Display the specified feed
55     */
56    public function show(Feed $feed): JsonResponse
57    {
58        return $this->sendResponse(
59            new FeedResource($feed),
60            'Feed retrieved successfully.'
61        );
62    }
63
64    /**
65     * Update the specified feed
66     */
67    public function update(UpdateFeedRequest $request, Feed $feed): JsonResponse
68    {
69        try {
70            $validated = $request->validated();
71            $validated['is_active'] = $validated['is_active'] ?? $feed->is_active;
72
73            $feed->update($validated);
74
75            return $this->sendResponse(
76                new FeedResource($feed->fresh()),
77                'Feed updated successfully!'
78            );
79        } catch (ValidationException $e) {
80            return $this->sendValidationError($e->errors());
81        } catch (\Exception $e) {
82            return $this->sendError('Failed to update feed: ' . $e->getMessage(), [], 500);
83        }
84    }
85
86    /**
87     * Remove the specified feed
88     */
89    public function destroy(Feed $feed): JsonResponse
90    {
91        try {
92            $feed->delete();
93
94            return $this->sendResponse(
95                null,
96                'Feed deleted successfully!'
97            );
98        } catch (\Exception $e) {
99            return $this->sendError('Failed to delete feed: ' . $e->getMessage(), [], 500);
100        }
101    }
102
103    /**
104     * Toggle feed active status
105     */
106    public function toggle(Feed $feed): JsonResponse
107    {
108        try {
109            $newStatus = !$feed->is_active;
110            $feed->update(['is_active' => $newStatus]);
111
112            $status = $newStatus ? 'activated' : 'deactivated';
113
114            return $this->sendResponse(
115                new FeedResource($feed->fresh()),
116                "Feed {$status} successfully!"
117            );
118        } catch (\Exception $e) {
119            return $this->sendError('Failed to toggle feed status: ' . $e->getMessage(), [], 500);
120        }
121    }
122}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:50:30 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-progress/Http/Controllers/Api/V1/LogsController.php.html b/backend/coverage-report-progress/Http/Controllers/Api/V1/LogsController.php.html deleted file mode 100644 index a2dacef6..00000000 --- a/backend/coverage-report-progress/Http/Controllers/Api/V1/LogsController.php.html +++ /dev/null @@ -1,198 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Http/Controllers/Api/V1/LogsController.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 19
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
LogsController
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 19
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
12
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 index
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 19
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
12
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Http\Controllers\Api\V1;
4
5use App\Models\Log;
6use Illuminate\Http\JsonResponse;
7use Illuminate\Http\Request;
8
9class LogsController extends BaseController
10{
11    /**
12     * Display a listing of logs
13     */
14    public function index(Request $request): JsonResponse
15    {
16        try {
17            $perPage = min($request->get('per_page', 20), 100);
18            $level = $request->get('level');
19            
20            $query = Log::orderBy('created_at', 'desc');
21            
22            if ($level) {
23                $query->where('level', $level);
24            }
25            
26            $logs = $query->paginate($perPage);
27
28            return $this->sendResponse([
29                'logs' => $logs->items(),
30                'pagination' => [
31                    'current_page' => $logs->currentPage(),
32                    'last_page' => $logs->lastPage(),
33                    'per_page' => $logs->perPage(),
34                    'total' => $logs->total(),
35                    'from' => $logs->firstItem(),
36                    'to' => $logs->lastItem(),
37                ],
38            ], 'Logs retrieved successfully.');
39        } catch (\Exception $e) {
40            return $this->sendError('Failed to retrieve logs: ' . $e->getMessage(), [], 500);
41        }
42    }
43}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:50:30 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-progress/Http/Controllers/Api/V1/PlatformAccountsController.php.html b/backend/coverage-report-progress/Http/Controllers/Api/V1/PlatformAccountsController.php.html deleted file mode 100644 index d191eeeb..00000000 --- a/backend/coverage-report-progress/Http/Controllers/Api/V1/PlatformAccountsController.php.html +++ /dev/null @@ -1,417 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Http/Controllers/Api/V1/PlatformAccountsController.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 73
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 6
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
PlatformAccountsController
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 73
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 6
210
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 index
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 8
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 store
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 30
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
20
 show
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 4
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 update
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 17
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
20
 destroy
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 7
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
6
 setActive
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 7
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
6
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Http\Controllers\Api\V1;
4
5use App\Enums\PlatformEnum;
6use App\Http\Resources\PlatformAccountResource;
7use App\Models\PlatformAccount;
8use App\Models\PlatformInstance;
9use Illuminate\Http\JsonResponse;
10use Illuminate\Http\Request;
11use Illuminate\Validation\ValidationException;
12
13class PlatformAccountsController extends BaseController
14{
15    /**
16     * Display a listing of platform accounts
17     */
18    public function index(): JsonResponse
19    {
20        $accounts = PlatformAccount::with(['platformInstance'])
21            ->orderBy('platform')
22            ->orderBy('created_at', 'desc')
23            ->get();
24
25        return $this->sendResponse(
26            PlatformAccountResource::collection($accounts),
27            'Platform accounts retrieved successfully.'
28        );
29    }
30
31    /**
32     * Store a newly created platform account
33     */
34    public function store(Request $request): JsonResponse
35    {
36        try {
37            $validated = $request->validate([
38                'platform' => 'required|in:lemmy,mastodon,reddit',
39                'instance_url' => 'required|url',
40                'username' => 'required|string|max:255',
41                'password' => 'required|string',
42                'settings' => 'nullable|array',
43            ]);
44
45            // Create or find platform instance
46            $platformEnum = PlatformEnum::from($validated['platform']);
47            $instance = PlatformInstance::firstOrCreate([
48                'platform' => $platformEnum,
49                'url' => $validated['instance_url'],
50            ], [
51                'name' => parse_url($validated['instance_url'], PHP_URL_HOST),
52                'description' => ucfirst($validated['platform']) . ' instance',
53                'is_active' => true,
54            ]);
55
56            $account = PlatformAccount::create($validated);
57
58            // If this is the first account for this platform, make it active
59            if (!PlatformAccount::where('platform', $validated['platform'])
60                ->where('is_active', true)
61                ->exists()) {
62                $account->setAsActive();
63            }
64
65            return $this->sendResponse(
66                new PlatformAccountResource($account->load('platformInstance')),
67                'Platform account created successfully!',
68                201
69            );
70        } catch (ValidationException $e) {
71            return $this->sendValidationError($e->errors());
72        } catch (\Exception $e) {
73            return $this->sendError('Failed to create platform account: ' . $e->getMessage(), [], 500);
74        }
75    }
76
77    /**
78     * Display the specified platform account
79     */
80    public function show(PlatformAccount $platformAccount): JsonResponse
81    {
82        return $this->sendResponse(
83            new PlatformAccountResource($platformAccount->load('platformInstance')),
84            'Platform account retrieved successfully.'
85        );
86    }
87
88    /**
89     * Update the specified platform account
90     */
91    public function update(Request $request, PlatformAccount $platformAccount): JsonResponse
92    {
93        try {
94            $validated = $request->validate([
95                'instance_url' => 'required|url',
96                'username' => 'required|string|max:255',
97                'password' => 'nullable|string',
98                'settings' => 'nullable|array',
99            ]);
100
101            // Don't update password if not provided
102            if (empty($validated['password'])) {
103                unset($validated['password']);
104            }
105
106            $platformAccount->update($validated);
107
108            return $this->sendResponse(
109                new PlatformAccountResource($platformAccount->fresh(['platformInstance'])),
110                'Platform account updated successfully!'
111            );
112        } catch (ValidationException $e) {
113            return $this->sendValidationError($e->errors());
114        } catch (\Exception $e) {
115            return $this->sendError('Failed to update platform account: ' . $e->getMessage(), [], 500);
116        }
117    }
118
119    /**
120     * Remove the specified platform account
121     */
122    public function destroy(PlatformAccount $platformAccount): JsonResponse
123    {
124        try {
125            $platformAccount->delete();
126
127            return $this->sendResponse(
128                null,
129                'Platform account deleted successfully!'
130            );
131        } catch (\Exception $e) {
132            return $this->sendError('Failed to delete platform account: ' . $e->getMessage(), [], 500);
133        }
134    }
135
136    /**
137     * Set platform account as active
138     */
139    public function setActive(PlatformAccount $platformAccount): JsonResponse
140    {
141        try {
142            $platformAccount->setAsActive();
143
144            return $this->sendResponse(
145                new PlatformAccountResource($platformAccount->fresh(['platformInstance'])),
146                "Set {$platformAccount->username}@{$platformAccount->instance_url} as active for {$platformAccount->platform->value}!"
147            );
148        } catch (\Exception $e) {
149            return $this->sendError('Failed to set platform account as active: ' . $e->getMessage(), [], 500);
150        }
151    }
152}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:50:30 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-progress/Http/Controllers/Api/V1/PlatformChannelsController.php.html b/backend/coverage-report-progress/Http/Controllers/Api/V1/PlatformChannelsController.php.html deleted file mode 100644 index 00b065bc..00000000 --- a/backend/coverage-report-progress/Http/Controllers/Api/V1/PlatformChannelsController.php.html +++ /dev/null @@ -1,398 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Http/Controllers/Api/V1/PlatformChannelsController.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 62
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 6
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
PlatformChannelsController
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 62
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 6
182
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 index
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 8
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 store
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 19
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
12
 show
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 4
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 update
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 15
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
12
 destroy
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 7
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
6
 toggle
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 9
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
12
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Http\Controllers\Api\V1;
4
5use App\Http\Resources\PlatformChannelResource;
6use App\Models\PlatformChannel;
7use Illuminate\Http\JsonResponse;
8use Illuminate\Http\Request;
9use Illuminate\Validation\ValidationException;
10
11class PlatformChannelsController extends BaseController
12{
13    /**
14     * Display a listing of platform channels
15     */
16    public function index(): JsonResponse
17    {
18        $channels = PlatformChannel::with(['platformInstance'])
19            ->orderBy('is_active', 'desc')
20            ->orderBy('name')
21            ->get();
22
23        return $this->sendResponse(
24            PlatformChannelResource::collection($channels),
25            'Platform channels retrieved successfully.'
26        );
27    }
28
29    /**
30     * Store a newly created platform channel
31     */
32    public function store(Request $request): JsonResponse
33    {
34        try {
35            $validated = $request->validate([
36                'platform_instance_id' => 'required|exists:platform_instances,id',
37                'channel_id' => 'required|string|max:255',
38                'name' => 'required|string|max:255',
39                'display_name' => 'nullable|string|max:255',
40                'description' => 'nullable|string',
41                'is_active' => 'boolean',
42            ]);
43
44            $validated['is_active'] = $validated['is_active'] ?? true;
45
46            $channel = PlatformChannel::create($validated);
47
48            return $this->sendResponse(
49                new PlatformChannelResource($channel->load('platformInstance')),
50                'Platform channel created successfully!',
51                201
52            );
53        } catch (ValidationException $e) {
54            return $this->sendValidationError($e->errors());
55        } catch (\Exception $e) {
56            return $this->sendError('Failed to create platform channel: ' . $e->getMessage(), [], 500);
57        }
58    }
59
60    /**
61     * Display the specified platform channel
62     */
63    public function show(PlatformChannel $channel): JsonResponse
64    {
65        return $this->sendResponse(
66            new PlatformChannelResource($channel->load('platformInstance')),
67            'Platform channel retrieved successfully.'
68        );
69    }
70
71    /**
72     * Update the specified platform channel
73     */
74    public function update(Request $request, PlatformChannel $channel): JsonResponse
75    {
76        try {
77            $validated = $request->validate([
78                'name' => 'required|string|max:255',
79                'display_name' => 'nullable|string|max:255',
80                'description' => 'nullable|string',
81                'is_active' => 'boolean',
82            ]);
83
84            $channel->update($validated);
85
86            return $this->sendResponse(
87                new PlatformChannelResource($channel->fresh(['platformInstance'])),
88                'Platform channel updated successfully!'
89            );
90        } catch (ValidationException $e) {
91            return $this->sendValidationError($e->errors());
92        } catch (\Exception $e) {
93            return $this->sendError('Failed to update platform channel: ' . $e->getMessage(), [], 500);
94        }
95    }
96
97    /**
98     * Remove the specified platform channel
99     */
100    public function destroy(PlatformChannel $channel): JsonResponse
101    {
102        try {
103            $channel->delete();
104
105            return $this->sendResponse(
106                null,
107                'Platform channel deleted successfully!'
108            );
109        } catch (\Exception $e) {
110            return $this->sendError('Failed to delete platform channel: ' . $e->getMessage(), [], 500);
111        }
112    }
113
114    /**
115     * Toggle platform channel active status
116     */
117    public function toggle(PlatformChannel $channel): JsonResponse
118    {
119        try {
120            $newStatus = !$channel->is_active;
121            $channel->update(['is_active' => $newStatus]);
122
123            $status = $newStatus ? 'activated' : 'deactivated';
124
125            return $this->sendResponse(
126                new PlatformChannelResource($channel->fresh(['platformInstance'])),
127                "Platform channel {$status} successfully!"
128            );
129        } catch (\Exception $e) {
130            return $this->sendError('Failed to toggle platform channel status: ' . $e->getMessage(), [], 500);
131        }
132    }
133}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:50:30 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-progress/Http/Controllers/Api/V1/RoutingController.php.html b/backend/coverage-report-progress/Http/Controllers/Api/V1/RoutingController.php.html deleted file mode 100644 index b685b94b..00000000 --- a/backend/coverage-report-progress/Http/Controllers/Api/V1/RoutingController.php.html +++ /dev/null @@ -1,430 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Http/Controllers/Api/V1/RoutingController.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 80
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 6
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
RoutingController
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 80
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 6
306
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 index
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 8
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 store
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 18
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
12
 show
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 10
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
6
 update
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 18
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
20
 destroy
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 12
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
12
 toggle
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 14
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
20
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Http\Controllers\Api\V1;
4
5use App\Http\Resources\RouteResource;
6use App\Models\Feed;
7use App\Models\PlatformChannel;
8use App\Models\Route;
9use Illuminate\Http\JsonResponse;
10use Illuminate\Http\Request;
11use Illuminate\Validation\ValidationException;
12
13class RoutingController extends BaseController
14{
15    /**
16     * Display a listing of routing configurations
17     */
18    public function index(): JsonResponse
19    {
20        $routes = Route::with(['feed', 'platformChannel'])
21            ->orderBy('is_active', 'desc')
22            ->orderBy('priority', 'asc')
23            ->get();
24
25        return $this->sendResponse(
26            RouteResource::collection($routes),
27            'Routing configurations retrieved successfully.'
28        );
29    }
30
31    /**
32     * Store a newly created routing configuration
33     */
34    public function store(Request $request): JsonResponse
35    {
36        try {
37            $validated = $request->validate([
38                'feed_id' => 'required|exists:feeds,id',
39                'platform_channel_id' => 'required|exists:platform_channels,id',
40                'is_active' => 'boolean',
41                'priority' => 'nullable|integer|min:0',
42            ]);
43
44            $validated['is_active'] = $validated['is_active'] ?? true;
45            $validated['priority'] = $validated['priority'] ?? 0;
46
47            $route = Route::create($validated);
48
49            return $this->sendResponse(
50                new RouteResource($route->load(['feed', 'platformChannel'])),
51                'Routing configuration created successfully!',
52                201
53            );
54        } catch (ValidationException $e) {
55            return $this->sendValidationError($e->errors());
56        } catch (\Exception $e) {
57            return $this->sendError('Failed to create routing configuration: ' . $e->getMessage(), [], 500);
58        }
59    }
60
61    /**
62     * Display the specified routing configuration
63     */
64    public function show(Feed $feed, PlatformChannel $channel): JsonResponse
65    {
66        $route = Route::where('feed_id', $feed->id)
67            ->where('platform_channel_id', $channel->id)
68            ->with(['feed', 'platformChannel'])
69            ->first();
70
71        if (!$route) {
72            return $this->sendNotFound('Routing configuration not found.');
73        }
74
75        return $this->sendResponse(
76            new RouteResource($route),
77            'Routing configuration retrieved successfully.'
78        );
79    }
80
81    /**
82     * Update the specified routing configuration
83     */
84    public function update(Request $request, Feed $feed, PlatformChannel $channel): JsonResponse
85    {
86        try {
87            $route = Route::where('feed_id', $feed->id)
88                ->where('platform_channel_id', $channel->id)
89                ->first();
90
91            if (!$route) {
92                return $this->sendNotFound('Routing configuration not found.');
93            }
94
95            $validated = $request->validate([
96                'is_active' => 'boolean',
97                'priority' => 'nullable|integer|min:0',
98            ]);
99
100            $route->update($validated);
101
102            return $this->sendResponse(
103                new RouteResource($route->fresh(['feed', 'platformChannel'])),
104                'Routing configuration updated successfully!'
105            );
106        } catch (ValidationException $e) {
107            return $this->sendValidationError($e->errors());
108        } catch (\Exception $e) {
109            return $this->sendError('Failed to update routing configuration: ' . $e->getMessage(), [], 500);
110        }
111    }
112
113    /**
114     * Remove the specified routing configuration
115     */
116    public function destroy(Feed $feed, PlatformChannel $channel): JsonResponse
117    {
118        try {
119            $route = Route::where('feed_id', $feed->id)
120                ->where('platform_channel_id', $channel->id)
121                ->first();
122
123            if (!$route) {
124                return $this->sendNotFound('Routing configuration not found.');
125            }
126
127            $route->delete();
128
129            return $this->sendResponse(
130                null,
131                'Routing configuration deleted successfully!'
132            );
133        } catch (\Exception $e) {
134            return $this->sendError('Failed to delete routing configuration: ' . $e->getMessage(), [], 500);
135        }
136    }
137
138    /**
139     * Toggle routing configuration active status
140     */
141    public function toggle(Feed $feed, PlatformChannel $channel): JsonResponse
142    {
143        try {
144            $route = Route::where('feed_id', $feed->id)
145                ->where('platform_channel_id', $channel->id)
146                ->first();
147
148            if (!$route) {
149                return $this->sendNotFound('Routing configuration not found.');
150            }
151
152            $newStatus = !$route->is_active;
153            $route->update(['is_active' => $newStatus]);
154
155            $status = $newStatus ? 'activated' : 'deactivated';
156
157            return $this->sendResponse(
158                new RouteResource($route->fresh(['feed', 'platformChannel'])),
159                "Routing configuration {$status} successfully!"
160            );
161        } catch (\Exception $e) {
162            return $this->sendError('Failed to toggle routing configuration status: ' . $e->getMessage(), [], 500);
163        }
164    }
165}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:50:30 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-progress/Http/Controllers/Api/V1/SettingsController.php.html b/backend/coverage-report-progress/Http/Controllers/Api/V1/SettingsController.php.html deleted file mode 100644 index d62ba482..00000000 --- a/backend/coverage-report-progress/Http/Controllers/Api/V1/SettingsController.php.html +++ /dev/null @@ -1,240 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Http/Controllers/Api/V1/SettingsController.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 27
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
SettingsController
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 27
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
56
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 index
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 7
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
6
 update
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 20
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
30
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Http\Controllers\Api\V1;
4
5use App\Models\Setting;
6use Illuminate\Http\JsonResponse;
7use Illuminate\Http\Request;
8use Illuminate\Validation\ValidationException;
9
10class SettingsController extends BaseController
11{
12    /**
13     * Display current settings
14     */
15    public function index(): JsonResponse
16    {
17        try {
18            $settings = [
19                'article_processing_enabled' => Setting::isArticleProcessingEnabled(),
20                'publishing_approvals_enabled' => Setting::isPublishingApprovalsEnabled(),
21            ];
22
23            return $this->sendResponse($settings, 'Settings retrieved successfully.');
24        } catch (\Exception $e) {
25            return $this->sendError('Failed to retrieve settings: ' . $e->getMessage(), [], 500);
26        }
27    }
28
29    /**
30     * Update settings
31     */
32    public function update(Request $request): JsonResponse
33    {
34        try {
35            $validated = $request->validate([
36                'article_processing_enabled' => 'boolean',
37                'enable_publishing_approvals' => 'boolean',
38            ]);
39
40            if (isset($validated['article_processing_enabled'])) {
41                Setting::setArticleProcessingEnabled($validated['article_processing_enabled']);
42            }
43
44            if (isset($validated['enable_publishing_approvals'])) {
45                Setting::setPublishingApprovalsEnabled($validated['enable_publishing_approvals']);
46            }
47
48            $updatedSettings = [
49                'article_processing_enabled' => Setting::isArticleProcessingEnabled(),
50                'publishing_approvals_enabled' => Setting::isPublishingApprovalsEnabled(),
51            ];
52
53            return $this->sendResponse(
54                $updatedSettings,
55                'Settings updated successfully.'
56            );
57        } catch (ValidationException $e) {
58            return $this->sendValidationError($e->errors());
59        } catch (\Exception $e) {
60            return $this->sendError('Failed to update settings: ' . $e->getMessage(), [], 500);
61        }
62    }
63}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:50:30 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-progress/Http/Controllers/Api/V1/dashboard.html b/backend/coverage-report-progress/Http/Controllers/Api/V1/dashboard.html deleted file mode 100644 index ec0ddfae..00000000 --- a/backend/coverage-report-progress/Http/Controllers/Api/V1/dashboard.html +++ /dev/null @@ -1,372 +0,0 @@ - - - - - Dashboard for /var/www/html/backend/app/Http/Controllers/Api/V1 - - - - - - - -
-
-
-
- -
-
-
-
-
-
-
-

Classes

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
- -
-
-

Methods

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
-
-
-

Insufficient Coverage

-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
MethodCoverage
login0%
register0%
logout0%
me0%
sendError0%
sendValidationError0%
sendNotFound0%
sendUnauthorized0%
index0%
store0%
show0%
update0%
destroy0%
toggle0%
index0%
index0%
store0%
show0%
update0%
destroy0%
setActive0%
index0%
store0%
show0%
update0%
destroy0%
toggle0%
index0%
store0%
show0%
update0%
destroy0%
toggle0%
index0%
update0%
approve71%
reject71%
stats83%
-
-
-
-

Project Risks

-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
MethodCRAP
login30
update30
store20
update20
update20
toggle20
register12
store12
update12
toggle12
index12
store12
update12
toggle12
store12
destroy12
logout6
sendError6
destroy6
destroy6
setActive6
destroy6
show6
index6
approve2
reject2
stats2
-
-
-
- -
- - - - - - diff --git a/backend/coverage-report-progress/Http/Controllers/Api/V1/index.html b/backend/coverage-report-progress/Http/Controllers/Api/V1/index.html deleted file mode 100644 index 71196fde..00000000 --- a/backend/coverage-report-progress/Http/Controllers/Api/V1/index.html +++ /dev/null @@ -1,374 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Http/Controllers/Api/V1 - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 10.72% covered (danger) -
-
-
10.72%
46 / 429
-
- 7.32% covered (danger) -
-
-
7.32%
3 / 41
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 10
ArticlesController.php
-
- 87.88% covered (warning) -
-
-
87.88%
29 / 33
-
- 33.33% covered (danger) -
-
-
33.33%
1 / 3
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
AuthController.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 56
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 4
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
BaseController.php
-
- 37.50% covered (danger) -
-
-
37.50%
6 / 16
-
- 20.00% covered (danger) -
-
-
20.00%
1 / 5
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
DashboardController.php
-
- 84.62% covered (warning) -
-
-
84.62%
11 / 13
-
- 50.00% covered (danger) -
-
-
50.00%
1 / 2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
FeedsController.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 50
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 6
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
LogsController.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 19
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
PlatformAccountsController.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 73
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 6
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
PlatformChannelsController.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 62
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 6
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
RoutingController.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 80
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 6
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
SettingsController.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 27
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- -
- - diff --git a/backend/coverage-report-progress/Http/Controllers/Api/dashboard.html b/backend/coverage-report-progress/Http/Controllers/Api/dashboard.html deleted file mode 100644 index 80487025..00000000 --- a/backend/coverage-report-progress/Http/Controllers/Api/dashboard.html +++ /dev/null @@ -1,371 +0,0 @@ - - - - - Dashboard for /var/www/html/backend/app/Http/Controllers/Api - - - - - - - -
-
-
-
- -
-
-
-
-
-
-
-

Classes

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
- -
-
-

Methods

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
-
-
-

Insufficient Coverage

-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
MethodCoverage
login0%
register0%
logout0%
me0%
sendError0%
sendValidationError0%
sendNotFound0%
sendUnauthorized0%
index0%
store0%
show0%
update0%
destroy0%
toggle0%
index0%
index0%
store0%
show0%
update0%
destroy0%
setActive0%
index0%
store0%
show0%
update0%
destroy0%
toggle0%
index0%
store0%
show0%
update0%
destroy0%
toggle0%
index0%
update0%
approve71%
reject71%
stats83%
-
-
-
-

Project Risks

-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
MethodCRAP
login30
update30
store20
update20
update20
toggle20
register12
store12
update12
toggle12
index12
store12
update12
toggle12
store12
destroy12
logout6
sendError6
destroy6
destroy6
setActive6
destroy6
show6
index6
approve2
reject2
stats2
-
-
-
- -
- - - - - - diff --git a/backend/coverage-report-progress/Http/Controllers/Api/index.html b/backend/coverage-report-progress/Http/Controllers/Api/index.html deleted file mode 100644 index 9f27d077..00000000 --- a/backend/coverage-report-progress/Http/Controllers/Api/index.html +++ /dev/null @@ -1,121 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Http/Controllers/Api - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 10.72% covered (danger) -
-
-
10.72%
46 / 429
-
- 7.32% covered (danger) -
-
-
7.32%
3 / 41
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 10
V1
-
- 10.72% covered (danger) -
-
-
10.72%
46 / 429
-
- 7.32% covered (danger) -
-
-
7.32%
3 / 41
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 10
-
- -
- - diff --git a/backend/coverage-report-progress/Http/Controllers/ArticlesController.php.html b/backend/coverage-report-progress/Http/Controllers/ArticlesController.php.html deleted file mode 100644 index ec9154da..00000000 --- a/backend/coverage-report-progress/Http/Controllers/ArticlesController.php.html +++ /dev/null @@ -1,234 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Http/Controllers/ArticlesController.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 9
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
ArticlesController
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 9
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
12
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 __invoke
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 5
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 approve
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 reject
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Http\Controllers;
4
5use App\Models\Article;
6use App\Models\Setting;
7use Illuminate\Contracts\View\View;
8use Illuminate\Http\RedirectResponse;
9use Illuminate\Http\Request;
10
11class ArticlesController extends Controller
12{
13    public function __invoke(Request $request): View
14    {
15        $articles = Article::with('articlePublication')
16            ->orderBy('created_at', 'desc')
17            ->paginate(15);
18
19        $publishingApprovalsEnabled = Setting::isPublishingApprovalsEnabled();
20
21        return view('pages.articles.index', compact('articles', 'publishingApprovalsEnabled'));
22    }
23
24    public function approve(Article $article): RedirectResponse
25    {
26        $article->approve('manual');
27
28        return redirect()->back()->with('success', 'Article approved and queued for publishing.');
29    }
30
31    public function reject(Article $article): RedirectResponse
32    {
33        $article->reject('manual');
34
35        return redirect()->back()->with('success', 'Article rejected.');
36    }
37}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:50:30 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-progress/Http/Controllers/Controller.php.html b/backend/coverage-report-progress/Http/Controllers/Controller.php.html deleted file mode 100644 index b1bdfe0d..00000000 --- a/backend/coverage-report-progress/Http/Controllers/Controller.php.html +++ /dev/null @@ -1,109 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Http/Controllers/Controller.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
n/a
0 / 0
n/a
0 / 0
CRAP
n/a
0 / 0
Controller
n/a
0 / 0
n/a
0 / 0
0
n/a
0 / 0
-
- - - - - - - - - - - - -
1<?php
2
3namespace App\Http\Controllers;
4
5abstract class Controller
6{
7    //
8}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:50:30 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-progress/Http/Controllers/FeedsController.php.html b/backend/coverage-report-progress/Http/Controllers/FeedsController.php.html deleted file mode 100644 index 659db1ee..00000000 --- a/backend/coverage-report-progress/Http/Controllers/FeedsController.php.html +++ /dev/null @@ -1,388 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Http/Controllers/FeedsController.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 28
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 8
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
FeedsController
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 28
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 8
90
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 index
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 4
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 create
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 store
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 8
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 show
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 edit
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 update
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 5
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 destroy
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 toggle
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 5
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
6
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Http\Controllers;
4
5use App\Models\Feed;
6use App\Http\Requests\StoreFeedRequest;
7use App\Http\Requests\UpdateFeedRequest;
8use App\Services\OnboardingRedirectService;
9use Illuminate\Contracts\View\View;
10use Illuminate\Http\RedirectResponse;
11
12class FeedsController extends Controller
13{
14    public function index(): View
15    {
16        $feeds = Feed::orderBy('is_active', 'desc')
17            ->orderBy('name')
18            ->get();
19
20        return view('pages.feeds.index', compact('feeds'));
21    }
22
23    public function create(): View
24    {
25        return view('pages.feeds.create');
26    }
27
28    public function store(StoreFeedRequest $request): RedirectResponse
29    {
30        $validated = $request->validated();
31        $validated['is_active'] = $validated['is_active'] ?? true;
32
33        Feed::create($validated);
34
35        return OnboardingRedirectService::handleRedirect(
36            $request,
37            'feeds.index',
38            'Feed created successfully!'
39        );
40    }
41
42    public function show(Feed $feed): View
43    {
44        return view('pages.feeds.show', compact('feed'));
45    }
46
47    public function edit(Feed $feed): View
48    {
49        return view('pages.feeds.edit', compact('feed'));
50    }
51
52    public function update(UpdateFeedRequest $request, Feed $feed): RedirectResponse
53    {
54        $validated = $request->validated();
55        $validated['is_active'] = $validated['is_active'] ?? $feed->is_active;
56
57        $feed->update($validated);
58
59        return redirect()->route('feeds.index')
60            ->with('success', 'Feed updated successfully!');
61    }
62
63    public function destroy(Feed $feed): RedirectResponse
64    {
65        $feed->delete();
66
67        return redirect()->route('feeds.index')
68            ->with('success', 'Feed deleted successfully!');
69    }
70
71    public function toggle(Feed $feed): RedirectResponse
72    {
73        $newStatus = !$feed->is_active;
74        $feed->update(['is_active' => $newStatus]);
75
76        $status = $newStatus ? 'activated' : 'deactivated';
77
78        return redirect()->route('feeds.index')
79            ->with('success', "Feed {$status} successfully!");
80    }
81}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:50:30 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-progress/Http/Controllers/LogsController.php.html b/backend/coverage-report-progress/Http/Controllers/LogsController.php.html deleted file mode 100644 index 7cdc4294..00000000 --- a/backend/coverage-report-progress/Http/Controllers/LogsController.php.html +++ /dev/null @@ -1,170 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Http/Controllers/LogsController.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
LogsController
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 __invoke
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Http\Controllers;
4
5use App\Models\Log;
6use Illuminate\Contracts\View\View;
7use Illuminate\Http\Request;
8
9class LogsController extends Controller
10{
11    public function __invoke(Request $request): View
12    {
13        $logs = Log::orderBy('created_at', 'desc')->paginate(50);
14
15        return view('pages.logs.index', compact('logs'));
16    }
17}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:50:30 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-progress/Http/Controllers/OnboardingController.php.html b/backend/coverage-report-progress/Http/Controllers/OnboardingController.php.html deleted file mode 100644 index 7bc31f0b..00000000 --- a/backend/coverage-report-progress/Http/Controllers/OnboardingController.php.html +++ /dev/null @@ -1,443 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Http/Controllers/OnboardingController.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 40
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 9
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
OnboardingController
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 40
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 9
506
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 index
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 15
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
6
 platform
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
6
 feed
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 5
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
12
 channel
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 7
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
20
 complete
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 6
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
30
 needsOnboarding
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
12
 hasPlatformAccount
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 hasFeed
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 hasChannel
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Http\Controllers;
4
5use App\Models\Feed;
6use App\Models\PlatformAccount;
7use App\Models\PlatformChannel;
8use App\Models\PlatformInstance;
9use App\Services\SystemStatusService;
10use App\Services\DashboardStatsService;
11use Illuminate\Http\Request;
12use Illuminate\View\View;
13use Illuminate\Http\RedirectResponse;
14
15class OnboardingController extends Controller
16{
17    public function index(Request $request): View|RedirectResponse
18    {
19        // Check if user needs onboarding
20        if (!$this->needsOnboarding()) {
21            $systemStatus = resolve(SystemStatusService::class)->getSystemStatus();
22            $statsService = resolve(DashboardStatsService::class);
23            
24            $period = $request->get('period', 'today');
25            $stats = $statsService->getStats($period);
26            $systemStats = $statsService->getSystemStats();
27            $availablePeriods = $statsService->getAvailablePeriods();
28
29            return view('pages.dashboard', compact(
30                'systemStatus', 
31                'stats', 
32                'systemStats', 
33                'availablePeriods', 
34                'period'
35            ));
36        }
37
38        return view('onboarding.welcome');
39    }
40
41    public function platform(): View|RedirectResponse
42    {
43        if (!$this->needsOnboarding()) {
44            return redirect()->route('feeds.index');
45        }
46
47        return view('onboarding.platform');
48    }
49
50    public function feed(): View|RedirectResponse
51    {
52        if (!$this->needsOnboarding()) {
53            return redirect()->route('feeds.index');
54        }
55
56        if (!$this->hasPlatformAccount()) {
57            return redirect()->route('onboarding.platform');
58        }
59
60        return view('onboarding.feed');
61    }
62
63    public function channel(): View|RedirectResponse
64    {
65        if (!$this->needsOnboarding()) {
66            return redirect()->route('feeds.index');
67        }
68
69        if (!$this->hasPlatformAccount()) {
70            return redirect()->route('onboarding.platform');
71        }
72
73        if (!$this->hasFeed()) {
74            return redirect()->route('onboarding.feed');
75        }
76
77        return view('onboarding.channel');
78    }
79
80    public function complete(): View|RedirectResponse
81    {
82        if (!$this->needsOnboarding()) {
83            return redirect()->route('feeds.index');
84        }
85
86        if (!$this->hasPlatformAccount() || !$this->hasFeed() || !$this->hasChannel()) {
87            return redirect()->route('onboarding.index');
88        }
89
90        $systemStatus = resolve(SystemStatusService::class)->getSystemStatus();
91
92        return view('onboarding.complete', compact('systemStatus'));
93    }
94
95    private function needsOnboarding(): bool
96    {
97        return !$this->hasPlatformAccount() || !$this->hasFeed() || !$this->hasChannel();
98    }
99
100    private function hasPlatformAccount(): bool
101    {
102        return PlatformAccount::where('is_active', true)->exists();
103    }
104
105    private function hasFeed(): bool
106    {
107        return Feed::where('is_active', true)->exists();
108    }
109
110    private function hasChannel(): bool
111    {
112        return PlatformChannel::where('is_active', true)->exists();
113    }
114}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:50:30 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-progress/Http/Controllers/PlatformAccountsController.php.html b/backend/coverage-report-progress/Http/Controllers/PlatformAccountsController.php.html deleted file mode 100644 index 49dad122..00000000 --- a/backend/coverage-report-progress/Http/Controllers/PlatformAccountsController.php.html +++ /dev/null @@ -1,391 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Http/Controllers/PlatformAccountsController.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 46
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 7
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
PlatformAccountsController
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 46
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 7
110
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 index
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 create
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 store
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 25
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
12
 edit
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 update
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 11
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
6
 destroy
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 setActive
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Http\Controllers;
4
5use App\Models\PlatformAccount;
6use App\Models\PlatformInstance;
7use App\Enums\PlatformEnum;
8use Illuminate\Http\Request;
9use Illuminate\Contracts\View\View;
10use Illuminate\Http\RedirectResponse;
11use Illuminate\Support\Facades\View as ViewFacade;
12
13class PlatformAccountsController extends Controller
14{
15    public function index(): View
16    {
17        $accounts = PlatformAccount::orderBy('platform')->orderBy('created_at', 'desc')->get();
18
19        return view('pages.platforms.index', compact('accounts'));
20    }
21
22    public function create(): View
23    {
24        return ViewFacade::make('pages.platforms.create');
25    }
26
27    public function store(Request $request): RedirectResponse
28    {
29        $validated = $request->validate([
30            'platform' => 'required|in:lemmy,mastodon,reddit',
31            'instance_url' => 'required|url',
32            'username' => 'required|string|max:255',
33            'password' => 'required|string',
34            'settings' => 'nullable|array',
35        ]);
36
37        // Create or find platform instance
38        $platformEnum = PlatformEnum::from($validated['platform']);
39        $instance = PlatformInstance::firstOrCreate([
40            'platform' => $platformEnum,
41            'url' => $validated['instance_url'],
42        ], [
43            'name' => parse_url($validated['instance_url'], PHP_URL_HOST),
44            'description' => ucfirst($validated['platform']) . ' instance',
45            'is_active' => true,
46        ]);
47
48        $account = PlatformAccount::create($validated);
49
50        // If this is the first account for this platform, make it active
51        if (! PlatformAccount::where('platform', $validated['platform'])->where('is_active', true)->exists()) {
52            $account->setAsActive();
53        }
54
55        // Check if there's a redirect_to parameter for onboarding flow
56        $redirectTo = $request->input('redirect_to');
57        if ($redirectTo) {
58            return redirect($redirectTo)
59                ->with('success', 'Platform account created successfully!');
60        }
61
62        return redirect()->route('platforms.index')
63            ->with('success', 'Platform account created successfully!');
64    }
65
66    public function edit(PlatformAccount $platformAccount): View
67    {
68        return ViewFacade::make('pages.platforms.edit', compact('platformAccount'));
69    }
70
71    public function update(Request $request, PlatformAccount $platformAccount): RedirectResponse
72    {
73        $validated = $request->validate([
74            'instance_url' => 'required|url',
75            'username' => 'required|string|max:255',
76            'password' => 'nullable|string',
77            'settings' => 'nullable|array',
78        ]);
79
80        // Don't update password if not provided
81        if (empty($validated['password'])) {
82            unset($validated['password']);
83        }
84
85        $platformAccount->update($validated);
86
87        return redirect()->route('platforms.index')
88            ->with('success', 'Platform account updated successfully!');
89    }
90
91    public function destroy(PlatformAccount $platformAccount): RedirectResponse
92    {
93        $platformAccount->delete();
94
95        return redirect()->route('platforms.index')
96            ->with('success', 'Platform account deleted successfully!');
97    }
98
99    public function setActive(PlatformAccount $platformAccount): RedirectResponse
100    {
101        $platformAccount->setAsActive();
102
103        return redirect()->route('platforms.index')
104            ->with('success', "Set $platformAccount->username@$platformAccount->instance_url as active for {$platformAccount->platform->value}!");
105    }
106}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:50:30 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-progress/Http/Controllers/PlatformChannelsController.php.html b/backend/coverage-report-progress/Http/Controllers/PlatformChannelsController.php.html deleted file mode 100644 index 7447ec6a..00000000 --- a/backend/coverage-report-progress/Http/Controllers/PlatformChannelsController.php.html +++ /dev/null @@ -1,423 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Http/Controllers/PlatformChannelsController.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 53
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 8
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
PlatformChannelsController
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 53
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 8
110
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 index
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 5
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 create
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 4
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 store
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 18
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
6
 show
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 edit
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 4
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 update
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 12
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 destroy
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 toggle
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 5
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
6
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Http\Controllers;
4
5use App\Models\PlatformChannel;
6use App\Models\PlatformInstance;
7use Illuminate\Http\Request;
8use Illuminate\Contracts\View\View;
9use Illuminate\Http\RedirectResponse;
10use Illuminate\Support\Facades\View as ViewFacade;
11
12class PlatformChannelsController extends Controller
13{
14    public function index(): View
15    {
16        $channels = PlatformChannel::with('platformInstance')
17            ->orderBy('platform_instance_id')
18            ->orderBy('name')
19            ->get();
20        
21        return ViewFacade::make('pages.channels.index', compact('channels'));
22    }
23
24    public function create(): View
25    {
26        $instances = PlatformInstance::where('is_active', true)
27            ->orderBy('name')
28            ->get();
29            
30        return ViewFacade::make('pages.channels.create', compact('instances'));
31    }
32
33    public function store(Request $request): RedirectResponse
34    {
35        $validated = $request->validate([
36            'platform_instance_id' => 'required|exists:platform_instances,id',
37            'name' => 'required|string|max:255',
38            'display_name' => 'nullable|string|max:255',
39            'channel_id' => 'nullable|string|max:255',
40            'description' => 'nullable|string',
41            'language_id' => 'required|exists:languages,id',
42            'is_active' => 'boolean',
43        ]);
44
45        // Default is_active to true if not provided
46        $validated['is_active'] = $validated['is_active'] ?? true;
47        
48        // Set display_name to name if not provided
49        $validated['display_name'] = $validated['display_name'] ?? $validated['name'];
50
51        PlatformChannel::create($validated);
52
53        // Check if there's a redirect_to parameter for onboarding flow
54        $redirectTo = $request->input('redirect_to');
55        if ($redirectTo) {
56            return redirect($redirectTo)
57                ->with('success', 'Channel created successfully!');
58        }
59
60        return redirect()->route('channels.index')
61            ->with('success', 'Channel created successfully!');
62    }
63
64    public function show(PlatformChannel $channel): View
65    {
66        $channel->load(['platformInstance', 'feeds']);
67        
68        return ViewFacade::make('pages.channels.show', compact('channel'));
69    }
70
71    public function edit(PlatformChannel $channel): View
72    {
73        $instances = PlatformInstance::where('is_active', true)
74            ->orderBy('name')
75            ->get();
76            
77        return ViewFacade::make('pages.channels.edit', compact('channel', 'instances'));
78    }
79
80    public function update(Request $request, PlatformChannel $channel): RedirectResponse
81    {
82        $validated = $request->validate([
83            'platform_instance_id' => 'required|exists:platform_instances,id',
84            'name' => 'required|string|max:255',
85            'display_name' => 'nullable|string|max:255',
86            'channel_id' => 'nullable|string|max:255',
87            'description' => 'nullable|string',
88            'language_id' => 'required|exists:languages,id',
89            'is_active' => 'boolean',
90        ]);
91
92        $channel->update($validated);
93
94        return redirect()->route('channels.index')
95            ->with('success', 'Channel updated successfully!');
96    }
97
98    public function destroy(PlatformChannel $channel): RedirectResponse
99    {
100        $channel->delete();
101
102        return redirect()->route('channels.index')
103            ->with('success', 'Channel deleted successfully!');
104    }
105
106    public function toggle(PlatformChannel $channel): RedirectResponse
107    {
108        $newStatus = !$channel->is_active;
109        $channel->update(['is_active' => $newStatus]);
110
111        $status = $newStatus ? 'activated' : 'deactivated';
112
113        return redirect()->route('channels.index')
114            ->with('success', "Channel {$status} successfully!");
115    }
116}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:50:30 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-progress/Http/Controllers/RoutingController.php.html b/backend/coverage-report-progress/Http/Controllers/RoutingController.php.html deleted file mode 100644 index ef35793b..00000000 --- a/backend/coverage-report-progress/Http/Controllers/RoutingController.php.html +++ /dev/null @@ -1,480 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Http/Controllers/RoutingController.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 87
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 8
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
RoutingController
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 87
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 8
240
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 index
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 9
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 create
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 8
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 store
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 28
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
12
 edit
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 6
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
6
 update
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 14
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 destroy
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 toggle
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 13
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
12
 parseJsonFilters
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 6
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
12
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Http\Controllers;
4
5use App\Models\Feed;
6use App\Models\Route;
7use App\Models\PlatformChannel;
8use App\Services\RoutingValidationService;
9use App\Exceptions\RoutingMismatchException;
10use Illuminate\Database\Eloquent\Collection;
11use Illuminate\Http\Request;
12use Illuminate\Contracts\View\View;
13use Illuminate\Http\RedirectResponse;
14
15class RoutingController extends Controller
16{
17    public function index(): View
18    {
19        $feeds = Feed::with(['channels.platformInstance'])
20            ->where('is_active', true)
21            ->orderBy('name')
22            ->get();
23
24        $channels = PlatformChannel::with(['platformInstance', 'feeds'])
25            ->where('is_active', true)
26            ->orderBy('name')
27            ->get();
28
29        return view('pages.routing.index', compact('feeds', 'channels'));
30    }
31
32    public function create(): View
33    {
34        $feeds = Feed::where('is_active', true)
35            ->orderBy('name')
36            ->get();
37
38        $channels = PlatformChannel::with('platformInstance')
39            ->where('is_active', true)
40            ->orderBy('name')
41            ->get();
42
43        return view('pages.routing.create', compact('feeds', 'channels'));
44    }
45
46    public function store(Request $request): RedirectResponse
47    {
48        $validated = $request->validate([
49            'feed_id' => 'required|exists:feeds,id',
50            'channel_ids' => 'required|array|min:1',
51            'channel_ids.*' => 'exists:platform_channels,id',
52            'priority' => 'integer|min:0|max:100',
53            'filters' => 'nullable|string'
54        ]);
55
56        /** @var Feed $feed */
57        $feed = Feed::findOrFail($validated['feed_id']);
58        
59        /** @var Collection<int, PlatformChannel> $channels */
60        $channels = PlatformChannel::findMany($validated['channel_ids']);
61        $priority = $validated['priority'] ?? 0;
62
63        try {
64            app(RoutingValidationService::class)->validateLanguageCompatibility($feed, $channels);
65        } catch (RoutingMismatchException $e) {
66            return redirect()->back()
67                ->withInput()
68                ->withErrors(['language' => $e->getMessage()]);
69        }
70
71        $filters = $this->parseJsonFilters($validated['filters'] ?? null);
72
73        // Attach channels to feed
74        $syncData = [];
75        foreach ($validated['channel_ids'] as $channelId) {
76            $syncData[$channelId] = [
77                'is_active' => true,
78                'priority' => $priority,
79                'filters' => $filters,
80                'created_at' => now(),
81                'updated_at' => now()
82            ];
83        }
84
85        $feed->channels()->syncWithoutDetaching($syncData);
86
87        return redirect()->route('routing.index')
88            ->with('success', 'Feed routing created successfully!');
89    }
90
91    public function edit(Feed $feed, PlatformChannel $channel): View
92    {
93        $routing = $feed->channels()
94            ->wherePivot('platform_channel_id', $channel->id)
95            ->first();
96
97        if (! $routing) {
98            abort(404, 'Routing not found');
99        }
100
101        return view('pages.routing.edit', compact('feed', 'channel', 'routing'));
102    }
103
104    public function update(Request $request, Feed $feed, PlatformChannel $channel): RedirectResponse
105    {
106        $validated = $request->validate([
107            'is_active' => 'boolean',
108            'priority' => 'integer|min:0|max:100',
109            'filters' => 'nullable|string'
110        ]);
111
112        $filters = $this->parseJsonFilters($validated['filters'] ?? null);
113
114        $feed->channels()->updateExistingPivot($channel->id, [
115            'is_active' => $validated['is_active'] ?? true,
116            'priority' => $validated['priority'] ?? 0,
117            'filters' => $filters,
118            'updated_at' => now()
119        ]);
120
121        return redirect()->route('routing.index')
122            ->with('success', 'Routing updated successfully!');
123    }
124
125    public function destroy(Feed $feed, PlatformChannel $channel): RedirectResponse
126    {
127        $feed->channels()->detach($channel->id);
128
129        return redirect()->route('routing.index')
130            ->with('success', 'Routing deleted successfully!');
131    }
132
133    public function toggle(Request $request, Feed $feed, PlatformChannel $channel): RedirectResponse
134    {
135        $routing = Route::where('feed_id', $feed->id)
136            ->where('platform_channel_id', $channel->id)
137            ->first();
138
139        if (! $routing) {
140            abort(404, 'Routing not found');
141        }
142
143        $newStatus = ! $routing->is_active;
144
145        $feed->channels()->updateExistingPivot($channel->id, [
146            'is_active' => $newStatus,
147            'updated_at' => now()
148        ]);
149
150        $status = $newStatus ? 'activated' : 'deactivated';
151
152        return redirect()->route('routing.index')
153            ->with('success', "Routing {$status} successfully!");
154    }
155
156    /**
157     * @return array<string, mixed>|null
158     */
159    private function parseJsonFilters(?string $json): ?array
160    {
161        if (empty($json)) {
162            return null;
163        }
164
165        $decoded = json_decode($json, true);
166
167        if (json_last_error() === JSON_ERROR_NONE) {
168            return $decoded;
169        }
170
171        return null;
172    }
173}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:50:30 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-progress/Http/Controllers/SettingsController.php.html b/backend/coverage-report-progress/Http/Controllers/SettingsController.php.html deleted file mode 100644 index f2d58686..00000000 --- a/backend/coverage-report-progress/Http/Controllers/SettingsController.php.html +++ /dev/null @@ -1,214 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Http/Controllers/SettingsController.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 14
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
SettingsController
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 14
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
12
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 index
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 update
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 11
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
6
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Http\Controllers;
4
5use App\Models\Setting;
6use Illuminate\Contracts\View\View;
7use Illuminate\Http\RedirectResponse;
8use Illuminate\Http\Request;
9
10class SettingsController extends Controller
11{
12    public function index(): View
13    {
14        $articleProcessingEnabled = Setting::isArticleProcessingEnabled();
15        $publishingApprovalsEnabled = Setting::isPublishingApprovalsEnabled();
16        
17        return view('pages.settings.index', compact('articleProcessingEnabled', 'publishingApprovalsEnabled'));
18    }
19
20    public function update(Request $request): RedirectResponse
21    {
22        $request->validate([
23            'article_processing_enabled' => 'boolean',
24            'enable_publishing_approvals' => 'boolean',
25        ]);
26
27        Setting::setArticleProcessingEnabled($request->boolean('article_processing_enabled'));
28        Setting::setPublishingApprovalsEnabled($request->boolean('enable_publishing_approvals'));
29
30        // If redirected from onboarding, go to dashboard
31        if ($request->get('from') === 'onboarding') {
32            return redirect()->route('onboarding.index')
33                ->with('success', 'System activated successfully! Welcome to Lemmy Poster.');
34        }
35
36        return redirect()->route('settings.index')
37            ->with('success', 'Settings updated successfully.');
38    }
39}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:50:30 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-progress/Http/Controllers/dashboard.html b/backend/coverage-report-progress/Http/Controllers/dashboard.html deleted file mode 100644 index 693bd421..00000000 --- a/backend/coverage-report-progress/Http/Controllers/dashboard.html +++ /dev/null @@ -1,446 +0,0 @@ - - - - - Dashboard for /var/www/html/backend/app/Http/Controllers - - - - - - - -
-
-
-
- -
-
-
-
-
-
-
-

Classes

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
-
- - -
-
-
-

Methods

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
-
-
-

Insufficient Coverage

-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
MethodCoverage
login0%
register0%
logout0%
me0%
sendError0%
sendValidationError0%
sendNotFound0%
sendUnauthorized0%
index0%
store0%
show0%
update0%
destroy0%
toggle0%
index0%
index0%
store0%
show0%
update0%
destroy0%
setActive0%
index0%
store0%
show0%
update0%
destroy0%
toggle0%
index0%
store0%
show0%
update0%
destroy0%
toggle0%
index0%
update0%
__invoke0%
approve0%
reject0%
index0%
create0%
store0%
show0%
edit0%
update0%
destroy0%
toggle0%
__invoke0%
index0%
platform0%
feed0%
channel0%
complete0%
needsOnboarding0%
hasPlatformAccount0%
hasFeed0%
hasChannel0%
index0%
create0%
store0%
edit0%
update0%
destroy0%
setActive0%
index0%
create0%
store0%
show0%
edit0%
update0%
destroy0%
toggle0%
index0%
create0%
store0%
edit0%
update0%
destroy0%
toggle0%
parseJsonFilters0%
index0%
update0%
approve71%
reject71%
stats83%
-
-
-
-

Project Risks

-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
MethodCRAP
login30
update30
complete30
store20
update20
update20
toggle20
channel20
register12
store12
update12
toggle12
index12
store12
update12
toggle12
store12
destroy12
feed12
needsOnboarding12
store12
store12
toggle12
parseJsonFilters12
logout6
sendError6
destroy6
destroy6
setActive6
destroy6
show6
index6
toggle6
index6
platform6
update6
store6
toggle6
edit6
update6
approve2
reject2
stats2
-
-
-
- -
- - - - - - diff --git a/backend/coverage-report-progress/Http/Controllers/index.html b/backend/coverage-report-progress/Http/Controllers/index.html deleted file mode 100644 index c3ae50aa..00000000 --- a/backend/coverage-report-progress/Http/Controllers/index.html +++ /dev/null @@ -1,357 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Http/Controllers - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 6.50% covered (danger) -
-
-
6.50%
46 / 708
-
- 3.45% covered (danger) -
-
-
3.45%
3 / 87
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 18
Api
-
- 10.72% covered (danger) -
-
-
10.72%
46 / 429
-
- 7.32% covered (danger) -
-
-
7.32%
3 / 41
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 10
ArticlesController.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 9
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
Controller.php
n/a
0 / 0
n/a
0 / 0
n/a
0 / 0
FeedsController.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 28
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 8
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
LogsController.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
OnboardingController.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 40
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 9
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
PlatformAccountsController.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 46
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 7
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
PlatformChannelsController.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 53
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 8
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
RoutingController.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 87
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 8
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
SettingsController.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 14
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- -
- - diff --git a/backend/coverage-report-progress/Http/Middleware/HandleAppearance.php.html b/backend/coverage-report-progress/Http/Middleware/HandleAppearance.php.html deleted file mode 100644 index 0c807045..00000000 --- a/backend/coverage-report-progress/Http/Middleware/HandleAppearance.php.html +++ /dev/null @@ -1,176 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Http/Middleware/HandleAppearance.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
HandleAppearance
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 handle
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Http\Middleware;
4
5use Closure;
6use Illuminate\Http\Request;
7use Illuminate\Support\Facades\View;
8use Symfony\Component\HttpFoundation\Response;
9
10class HandleAppearance
11{
12    /**
13     * Handle an incoming request.
14     *
15     * @param  \Closure(\Illuminate\Http\Request): (\Symfony\Component\HttpFoundation\Response)  $next
16     */
17    public function handle(Request $request, Closure $next): Response
18    {
19        View::share('appearance', $request->cookie('appearance') ?? 'system');
20
21        return $next($request);
22    }
23}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:50:30 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-progress/Http/Middleware/HandleInertiaRequests.php.html b/backend/coverage-report-progress/Http/Middleware/HandleInertiaRequests.php.html deleted file mode 100644 index c976fb8d..00000000 --- a/backend/coverage-report-progress/Http/Middleware/HandleInertiaRequests.php.html +++ /dev/null @@ -1,217 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Http/Middleware/HandleInertiaRequests.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 4
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
HandleInertiaRequests
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 4
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
6
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 version
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 share
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Http\Middleware;
4
5use Illuminate\Http\Request;
6use Inertia\Middleware;
7
8class HandleInertiaRequests extends Middleware
9{
10    /**
11     * The root template that's loaded on the first page visit.
12     *
13     * @see https://inertiajs.com/server-side-setup#root-template
14     *
15     * @var string
16     */
17    protected $rootView = 'app';
18
19    /**
20     * Determines the current asset version.
21     *
22     * @see https://inertiajs.com/asset-versioning
23     */
24    public function version(Request $request): ?string
25    {
26        return parent::version($request);
27    }
28
29    /**
30     * Define the props that are shared by default.
31     *
32     * @see https://inertiajs.com/shared-data
33     *
34     * @return array<string, mixed>
35     */
36    public function share(Request $request): array
37    {
38        return array_merge(parent::share($request), [
39            //
40        ]);
41    }
42}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:50:30 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-progress/Http/Middleware/dashboard.html b/backend/coverage-report-progress/Http/Middleware/dashboard.html deleted file mode 100644 index 6f3c0d19..00000000 --- a/backend/coverage-report-progress/Http/Middleware/dashboard.html +++ /dev/null @@ -1,290 +0,0 @@ - - - - - Dashboard for /var/www/html/backend/app/Http/Middleware - - - - - - - -
-
-
-
- -
-
-
-
-
-
-
-

Classes

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
-
-
-

Insufficient Coverage

- -
-
-

Project Risks

-
- - - - - - - - - - -
ClassCRAP
-
-
-
-
-
-

Methods

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
-
-
-

Insufficient Coverage

-
- - - - - - - - - - - - - -
MethodCoverage
handle0%
version0%
share0%
-
-
-
-

Project Risks

-
- - - - - - - - - - -
MethodCRAP
-
-
-
- -
- - - - - - diff --git a/backend/coverage-report-progress/Http/Middleware/index.html b/backend/coverage-report-progress/Http/Middleware/index.html deleted file mode 100644 index dac95395..00000000 --- a/backend/coverage-report-progress/Http/Middleware/index.html +++ /dev/null @@ -1,148 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Http/Middleware - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 6
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
HandleAppearance.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
HandleInertiaRequests.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 4
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- -
- - diff --git a/backend/coverage-report-progress/Http/Requests/StoreFeedRequest.php.html b/backend/coverage-report-progress/Http/Requests/StoreFeedRequest.php.html deleted file mode 100644 index 701a6b52..00000000 --- a/backend/coverage-report-progress/Http/Requests/StoreFeedRequest.php.html +++ /dev/null @@ -1,203 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Http/Requests/StoreFeedRequest.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 9
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
StoreFeedRequest
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 9
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
6
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 authorize
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 rules
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 8
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Http\Requests;
4
5use Illuminate\Foundation\Http\FormRequest;
6
7class StoreFeedRequest extends FormRequest
8{
9    public function authorize(): bool
10    {
11        return true;
12    }
13
14    /**
15     * @return array<string, string>
16     */
17    public function rules(): array
18    {
19        return [
20            'name' => 'required|string|max:255',
21            'url' => 'required|url|unique:feeds,url',
22            'type' => 'required|in:website,rss',
23            'language_id' => 'required|exists:languages,id',
24            'description' => 'nullable|string',
25            'is_active' => 'boolean'
26        ];
27    }
28}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:50:30 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-progress/Http/Requests/UpdateFeedRequest.php.html b/backend/coverage-report-progress/Http/Requests/UpdateFeedRequest.php.html deleted file mode 100644 index 2b506180..00000000 --- a/backend/coverage-report-progress/Http/Requests/UpdateFeedRequest.php.html +++ /dev/null @@ -1,204 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Http/Requests/UpdateFeedRequest.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 9
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
UpdateFeedRequest
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 9
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
12
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 authorize
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 rules
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 8
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
6
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Http\Requests;
4
5use App\Models\Feed;
6use Illuminate\Foundation\Http\FormRequest;
7
8class UpdateFeedRequest extends FormRequest
9{
10    public function authorize(): bool
11    {
12        return true;
13    }
14
15    /**
16     * @return array<string, string>
17     */
18    public function rules(): array
19    {
20        return [
21            'name' => 'required|string|max:255',
22            'url' => 'required|url|unique:feeds,url,' . ($this->route('feed') instanceof Feed ? (string)$this->route('feed')->id : (string)$this->route('feed')),
23            'type' => 'required|in:website,rss',
24            'language_id' => 'required|exists:languages,id',
25            'description' => 'nullable|string',
26            'is_active' => 'boolean'
27        ];
28    }
29}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:50:30 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-progress/Http/Requests/dashboard.html b/backend/coverage-report-progress/Http/Requests/dashboard.html deleted file mode 100644 index 0a7df07f..00000000 --- a/backend/coverage-report-progress/Http/Requests/dashboard.html +++ /dev/null @@ -1,293 +0,0 @@ - - - - - Dashboard for /var/www/html/backend/app/Http/Requests - - - - - - - -
-
-
-
- -
-
-
-
-
-
-
-

Classes

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
-
-
-

Insufficient Coverage

-
- - - - - - - - - - - - -
ClassCoverage
App\Http\Requests\StoreFeedRequest0%
App\Http\Requests\UpdateFeedRequest0%
-
-
-
-

Project Risks

-
- - - - - - - - - - - -
ClassCRAP
App\Http\Requests\UpdateFeedRequest12
-
-
-
-
-
-

Methods

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
-
-
-

Insufficient Coverage

-
- - - - - - - - - - - - - - -
MethodCoverage
authorize0%
rules0%
authorize0%
rules0%
-
-
-
-

Project Risks

-
- - - - - - - - - - - -
MethodCRAP
rules6
-
-
-
- -
- - - - - - diff --git a/backend/coverage-report-progress/Http/Requests/index.html b/backend/coverage-report-progress/Http/Requests/index.html deleted file mode 100644 index 3aee2be1..00000000 --- a/backend/coverage-report-progress/Http/Requests/index.html +++ /dev/null @@ -1,148 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Http/Requests - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 18
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 4
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
StoreFeedRequest.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 9
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
UpdateFeedRequest.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 9
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- -
- - diff --git a/backend/coverage-report-progress/Http/Resources/ArticlePublicationResource.php.html b/backend/coverage-report-progress/Http/Resources/ArticlePublicationResource.php.html deleted file mode 100644 index 434749e6..00000000 --- a/backend/coverage-report-progress/Http/Resources/ArticlePublicationResource.php.html +++ /dev/null @@ -1,179 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Http/Resources/ArticlePublicationResource.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 8
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
ArticlePublicationResource
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 8
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 toArray
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 8
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Http\Resources;
4
5use Illuminate\Http\Request;
6use Illuminate\Http\Resources\Json\JsonResource;
7
8class ArticlePublicationResource extends JsonResource
9{
10    /**
11     * Transform the resource into an array.
12     *
13     * @return array<string, mixed>
14     */
15    public function toArray(Request $request): array
16    {
17        return [
18            'id' => $this->id,
19            'article_id' => $this->article_id,
20            'status' => $this->status,
21            'published_at' => $this->published_at?->toISOString(),
22            'created_at' => $this->created_at->toISOString(),
23            'updated_at' => $this->updated_at->toISOString(),
24        ];
25    }
26}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:50:30 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-progress/Http/Resources/ArticleResource.php.html b/backend/coverage-report-progress/Http/Resources/ArticleResource.php.html deleted file mode 100644 index 5f9001af..00000000 --- a/backend/coverage-report-progress/Http/Resources/ArticleResource.php.html +++ /dev/null @@ -1,189 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Http/Resources/ArticleResource.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 100.00% covered (success) -
-
-
100.00%
18 / 18
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
CRAP
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
ArticleResource
-
- 100.00% covered (success) -
-
-
100.00%
18 / 18
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
1
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
 toArray
-
- 100.00% covered (success) -
-
-
100.00%
18 / 18
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
1
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Http\Resources;
4
5use Illuminate\Http\Request;
6use Illuminate\Http\Resources\Json\JsonResource;
7
8class ArticleResource extends JsonResource
9{
10    /**
11     * Transform the resource into an array.
12     *
13     * @return array<string, mixed>
14     */
15    public function toArray(Request $request): array
16    {
17        return [
18            'id' => $this->id,
19            'feed_id' => $this->feed_id,
20            'url' => $this->url,
21            'title' => $this->title,
22            'description' => $this->description,
23            'is_valid' => $this->is_valid,
24            'is_duplicate' => $this->is_duplicate,
25            'approval_status' => $this->approval_status,
26            'approved_at' => $this->approved_at?->toISOString(),
27            'approved_by' => $this->approved_by,
28            'fetched_at' => $this->fetched_at?->toISOString(),
29            'validated_at' => $this->validated_at?->toISOString(),
30            'created_at' => $this->created_at->toISOString(),
31            'updated_at' => $this->updated_at->toISOString(),
32            'feed' => new FeedResource($this->whenLoaded('feed')),
33            'article_publication' => new ArticlePublicationResource($this->whenLoaded('articlePublication')),
34        ];
35    }
36}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:50:30 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-progress/Http/Resources/FeedResource.php.html b/backend/coverage-report-progress/Http/Resources/FeedResource.php.html deleted file mode 100644 index a377199b..00000000 --- a/backend/coverage-report-progress/Http/Resources/FeedResource.php.html +++ /dev/null @@ -1,184 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Http/Resources/FeedResource.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 92.31% covered (success) -
-
-
92.31%
12 / 13
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
FeedResource
-
- 92.31% covered (success) -
-
-
92.31%
12 / 13
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
1.00
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 toArray
-
- 92.31% covered (success) -
-
-
92.31%
12 / 13
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
1.00
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Http\Resources;
4
5use Illuminate\Http\Request;
6use Illuminate\Http\Resources\Json\JsonResource;
7
8class FeedResource extends JsonResource
9{
10    /**
11     * Transform the resource into an array.
12     *
13     * @return array<string, mixed>
14     */
15    public function toArray(Request $request): array
16    {
17        return [
18            'id' => $this->id,
19            'name' => $this->name,
20            'url' => $this->url,
21            'type' => $this->type,
22            'is_active' => $this->is_active,
23            'description' => $this->description,
24            'created_at' => $this->created_at->toISOString(),
25            'updated_at' => $this->updated_at->toISOString(),
26            'articles_count' => $this->when($request->routeIs('api.feeds.*'), function () {
27                return $this->articles()->count();
28            }),
29        ];
30    }
31}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:50:30 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-progress/Http/Resources/PlatformAccountResource.php.html b/backend/coverage-report-progress/Http/Resources/PlatformAccountResource.php.html deleted file mode 100644 index 69eacce7..00000000 --- a/backend/coverage-report-progress/Http/Resources/PlatformAccountResource.php.html +++ /dev/null @@ -1,184 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Http/Resources/PlatformAccountResource.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 13
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
PlatformAccountResource
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 13
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 toArray
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 13
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Http\Resources;
4
5use Illuminate\Http\Request;
6use Illuminate\Http\Resources\Json\JsonResource;
7
8class PlatformAccountResource extends JsonResource
9{
10    /**
11     * Transform the resource into an array.
12     *
13     * @return array<string, mixed>
14     */
15    public function toArray(Request $request): array
16    {
17        return [
18            'id' => $this->id,
19            'platform_instance_id' => $this->platform_instance_id,
20            'account_id' => $this->account_id,
21            'username' => $this->username,
22            'display_name' => $this->display_name,
23            'description' => $this->description,
24            'is_active' => $this->is_active,
25            'created_at' => $this->created_at->toISOString(),
26            'updated_at' => $this->updated_at->toISOString(),
27            'platform_instance' => new PlatformInstanceResource($this->whenLoaded('platformInstance')),
28            'channels' => PlatformChannelResource::collection($this->whenLoaded('channels')),
29        ];
30    }
31}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:50:30 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-progress/Http/Resources/PlatformChannelResource.php.html b/backend/coverage-report-progress/Http/Resources/PlatformChannelResource.php.html deleted file mode 100644 index 66540a9c..00000000 --- a/backend/coverage-report-progress/Http/Resources/PlatformChannelResource.php.html +++ /dev/null @@ -1,184 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Http/Resources/PlatformChannelResource.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 13
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
PlatformChannelResource
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 13
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 toArray
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 13
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Http\Resources;
4
5use Illuminate\Http\Request;
6use Illuminate\Http\Resources\Json\JsonResource;
7
8class PlatformChannelResource extends JsonResource
9{
10    /**
11     * Transform the resource into an array.
12     *
13     * @return array<string, mixed>
14     */
15    public function toArray(Request $request): array
16    {
17        return [
18            'id' => $this->id,
19            'platform_instance_id' => $this->platform_instance_id,
20            'channel_id' => $this->channel_id,
21            'name' => $this->name,
22            'display_name' => $this->display_name,
23            'description' => $this->description,
24            'is_active' => $this->is_active,
25            'created_at' => $this->created_at->toISOString(),
26            'updated_at' => $this->updated_at->toISOString(),
27            'platform_instance' => new PlatformInstanceResource($this->whenLoaded('platformInstance')),
28            'routes' => RouteResource::collection($this->whenLoaded('routes')),
29        ];
30    }
31}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:50:30 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-progress/Http/Resources/PlatformInstanceResource.php.html b/backend/coverage-report-progress/Http/Resources/PlatformInstanceResource.php.html deleted file mode 100644 index 5dc969a9..00000000 --- a/backend/coverage-report-progress/Http/Resources/PlatformInstanceResource.php.html +++ /dev/null @@ -1,180 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Http/Resources/PlatformInstanceResource.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 9
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
PlatformInstanceResource
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 9
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 toArray
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 9
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Http\Resources;
4
5use Illuminate\Http\Request;
6use Illuminate\Http\Resources\Json\JsonResource;
7
8class PlatformInstanceResource extends JsonResource
9{
10    /**
11     * Transform the resource into an array.
12     *
13     * @return array<string, mixed>
14     */
15    public function toArray(Request $request): array
16    {
17        return [
18            'id' => $this->id,
19            'name' => $this->name,
20            'url' => $this->url,
21            'description' => $this->description,
22            'is_active' => $this->is_active,
23            'created_at' => $this->created_at->toISOString(),
24            'updated_at' => $this->updated_at->toISOString(),
25        ];
26    }
27}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:50:30 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-progress/Http/Resources/RouteResource.php.html b/backend/coverage-report-progress/Http/Resources/RouteResource.php.html deleted file mode 100644 index 8fdd5890..00000000 --- a/backend/coverage-report-progress/Http/Resources/RouteResource.php.html +++ /dev/null @@ -1,182 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Http/Resources/RouteResource.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 11
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
RouteResource
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 11
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 toArray
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 11
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Http\Resources;
4
5use Illuminate\Http\Request;
6use Illuminate\Http\Resources\Json\JsonResource;
7
8class RouteResource extends JsonResource
9{
10    /**
11     * Transform the resource into an array.
12     *
13     * @return array<string, mixed>
14     */
15    public function toArray(Request $request): array
16    {
17        return [
18            'id' => $this->id,
19            'feed_id' => $this->feed_id,
20            'platform_channel_id' => $this->platform_channel_id,
21            'is_active' => $this->is_active,
22            'priority' => $this->priority,
23            'created_at' => $this->created_at->toISOString(),
24            'updated_at' => $this->updated_at->toISOString(),
25            'feed' => new FeedResource($this->whenLoaded('feed')),
26            'platform_channel' => new PlatformChannelResource($this->whenLoaded('platformChannel')),
27        ];
28    }
29}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:50:30 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-progress/Http/Resources/dashboard.html b/backend/coverage-report-progress/Http/Resources/dashboard.html deleted file mode 100644 index 5639be9d..00000000 --- a/backend/coverage-report-progress/Http/Resources/dashboard.html +++ /dev/null @@ -1,295 +0,0 @@ - - - - - Dashboard for /var/www/html/backend/app/Http/Resources - - - - - - - -
-
-
-
- -
-
-
-
-
-
-
-

Classes

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
-
- -
-

Project Risks

-
- - - - - - - - - - -
ClassCRAP
-
-
-
-
-
-

Methods

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
-
-
-

Insufficient Coverage

-
- - - - - - - - - - - - - - - -
MethodCoverage
toArray0%
toArray0%
toArray0%
toArray0%
toArray0%
-
-
-
-

Project Risks

-
- - - - - - - - - - -
MethodCRAP
-
-
-
- -
- - - - - - diff --git a/backend/coverage-report-progress/Http/Resources/index.html b/backend/coverage-report-progress/Http/Resources/index.html deleted file mode 100644 index 0093356c..00000000 --- a/backend/coverage-report-progress/Http/Resources/index.html +++ /dev/null @@ -1,288 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Http/Resources - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 35.29% covered (danger) -
-
-
35.29%
30 / 85
-
- 14.29% covered (danger) -
-
-
14.29%
1 / 7
-
- 14.29% covered (danger) -
-
-
14.29%
1 / 7
ArticlePublicationResource.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 8
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
ArticleResource.php
-
- 100.00% covered (success) -
-
-
100.00%
18 / 18
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
FeedResource.php
-
- 92.31% covered (success) -
-
-
92.31%
12 / 13
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
PlatformAccountResource.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 13
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
PlatformChannelResource.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 13
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
PlatformInstanceResource.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 9
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
RouteResource.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 11
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- -
- - diff --git a/backend/coverage-report-progress/Http/dashboard.html b/backend/coverage-report-progress/Http/dashboard.html deleted file mode 100644 index 4686d015..00000000 --- a/backend/coverage-report-progress/Http/dashboard.html +++ /dev/null @@ -1,468 +0,0 @@ - - - - - Dashboard for /var/www/html/backend/app/Http - - - - - - - -
-
-
-
- -
-
-
-
-
-
-
-

Classes

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
-
- - -
-
-
-

Methods

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
-
-
-

Insufficient Coverage

-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
MethodCoverage
login0%
register0%
logout0%
me0%
sendError0%
sendValidationError0%
sendNotFound0%
sendUnauthorized0%
index0%
store0%
show0%
update0%
destroy0%
toggle0%
index0%
index0%
store0%
show0%
update0%
destroy0%
setActive0%
index0%
store0%
show0%
update0%
destroy0%
toggle0%
index0%
store0%
show0%
update0%
destroy0%
toggle0%
index0%
update0%
__invoke0%
approve0%
reject0%
index0%
create0%
store0%
show0%
edit0%
update0%
destroy0%
toggle0%
__invoke0%
index0%
platform0%
feed0%
channel0%
complete0%
needsOnboarding0%
hasPlatformAccount0%
hasFeed0%
hasChannel0%
index0%
create0%
store0%
edit0%
update0%
destroy0%
setActive0%
index0%
create0%
store0%
show0%
edit0%
update0%
destroy0%
toggle0%
index0%
create0%
store0%
edit0%
update0%
destroy0%
toggle0%
parseJsonFilters0%
index0%
update0%
handle0%
version0%
share0%
authorize0%
rules0%
authorize0%
rules0%
toArray0%
toArray0%
toArray0%
toArray0%
toArray0%
approve71%
reject71%
stats83%
-
-
-
-

Project Risks

-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
MethodCRAP
login30
update30
complete30
store20
update20
update20
toggle20
channel20
register12
store12
update12
toggle12
index12
store12
update12
toggle12
store12
destroy12
feed12
needsOnboarding12
store12
store12
toggle12
parseJsonFilters12
logout6
sendError6
destroy6
destroy6
setActive6
destroy6
show6
index6
toggle6
index6
platform6
update6
store6
toggle6
edit6
update6
rules6
approve2
reject2
stats2
-
-
-
- -
- - - - - - diff --git a/backend/coverage-report-progress/Http/index.html b/backend/coverage-report-progress/Http/index.html deleted file mode 100644 index a7e35f77..00000000 --- a/backend/coverage-report-progress/Http/index.html +++ /dev/null @@ -1,203 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Http - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 9.30% covered (danger) -
-
-
9.30%
76 / 817
-
- 3.96% covered (danger) -
-
-
3.96%
4 / 101
-
- 3.45% covered (danger) -
-
-
3.45%
1 / 29
Controllers
-
- 6.50% covered (danger) -
-
-
6.50%
46 / 708
-
- 3.45% covered (danger) -
-
-
3.45%
3 / 87
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 18
Middleware
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 6
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
Requests
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 18
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 4
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
Resources
-
- 35.29% covered (danger) -
-
-
35.29%
30 / 85
-
- 14.29% covered (danger) -
-
-
14.29%
1 / 7
-
- 14.29% covered (danger) -
-
-
14.29%
1 / 7
-
- -
- - diff --git a/backend/coverage-report-progress/Jobs/ArticleDiscoveryForFeedJob.php.html b/backend/coverage-report-progress/Jobs/ArticleDiscoveryForFeedJob.php.html deleted file mode 100644 index 76b5ad7f..00000000 --- a/backend/coverage-report-progress/Jobs/ArticleDiscoveryForFeedJob.php.html +++ /dev/null @@ -1,257 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Jobs/ArticleDiscoveryForFeedJob.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 26
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
ArticleDiscoveryForFeedJob
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 26
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
12
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 __construct
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 handle
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 12
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 dispatchForAllActiveFeeds
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 13
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Jobs;
4
5use App\Models\Feed;
6use App\Services\Article\ArticleFetcher;
7use App\Services\Log\LogSaver;
8use Illuminate\Contracts\Queue\ShouldQueue;
9use Illuminate\Foundation\Queue\Queueable;
10
11class ArticleDiscoveryForFeedJob implements ShouldQueue
12{
13    use Queueable;
14
15    private const FEED_DISCOVERY_DELAY_MINUTES = 5;
16
17    public function __construct(
18        private readonly Feed $feed
19    ) {
20        $this->onQueue('feed-discovery');
21    }
22
23    public function handle(): void
24    {
25        LogSaver::info('Starting feed article fetch', null, [
26            'feed_id' => $this->feed->id,
27            'feed_name' => $this->feed->name,
28            'feed_url' => $this->feed->url
29        ]);
30
31        $articles = ArticleFetcher::getArticlesFromFeed($this->feed);
32
33        LogSaver::info('Feed article fetch completed', null, [
34            'feed_id' => $this->feed->id,
35            'feed_name' => $this->feed->name,
36            'articles_count' => $articles->count()
37        ]);
38
39        $this->feed->update(['last_fetched_at' => now()]);
40    }
41
42    public static function dispatchForAllActiveFeeds(): void
43    {
44        Feed::where('is_active', true)
45            ->get()
46            ->each(function (Feed $feed, $index) {
47                // Space jobs apart to avoid overwhelming feeds
48                $delayMinutes = $index * self::FEED_DISCOVERY_DELAY_MINUTES;
49
50                self::dispatch($feed)
51                    ->delay(now()->addMinutes($delayMinutes))
52                    ->onQueue('feed-discovery');
53
54                LogSaver::info('Dispatched feed discovery job', null, [
55                    'feed_id' => $feed->id,
56                    'feed_name' => $feed->name,
57                    'delay_minutes' => $delayMinutes
58                ]);
59            });
60    }
61}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:50:30 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-progress/Jobs/ArticleDiscoveryJob.php.html b/backend/coverage-report-progress/Jobs/ArticleDiscoveryJob.php.html deleted file mode 100644 index 3a8bf227..00000000 --- a/backend/coverage-report-progress/Jobs/ArticleDiscoveryJob.php.html +++ /dev/null @@ -1,207 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Jobs/ArticleDiscoveryJob.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 7
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
ArticleDiscoveryJob
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 7
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
12
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 __construct
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 handle
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 6
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
6
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Jobs;
4
5use App\Models\Setting;
6use App\Services\Log\LogSaver;
7use Illuminate\Contracts\Queue\ShouldQueue;
8use Illuminate\Foundation\Queue\Queueable;
9
10class ArticleDiscoveryJob implements ShouldQueue
11{
12    use Queueable;
13
14    public function __construct()
15    {
16        $this->onQueue('feed-discovery');
17    }
18
19    public function handle(): void
20    {
21        if (!Setting::isArticleProcessingEnabled()) {
22            LogSaver::info('Article processing is disabled. Article discovery skipped.');
23
24            return;
25        }
26
27        LogSaver::info('Starting article discovery for all active feeds');
28
29        ArticleDiscoveryForFeedJob::dispatchForAllActiveFeeds();
30
31        LogSaver::info('Article discovery jobs dispatched for all active feeds');
32    }
33}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:50:30 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-progress/Jobs/PublishToLemmyJob.php.html b/backend/coverage-report-progress/Jobs/PublishToLemmyJob.php.html deleted file mode 100644 index 34bb39a8..00000000 --- a/backend/coverage-report-progress/Jobs/PublishToLemmyJob.php.html +++ /dev/null @@ -1,212 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Jobs/PublishToLemmyJob.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 6
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
PublishToLemmyJob
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 6
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
12
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 __construct
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 handle
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 5
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
6
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Jobs;
4
5use App\Exceptions\PublishException;
6use App\Models\Article;
7use App\Services\Article\ArticleFetcher;
8use App\Services\Publishing\ArticlePublishingService;
9use Illuminate\Contracts\Queue\ShouldQueue;
10use Illuminate\Foundation\Queue\Queueable;
11
12class PublishToLemmyJob implements ShouldQueue
13{
14    use Queueable;
15
16    public int $tries = 3;
17    public array $backoff = [60, 120, 300];
18
19    public function __construct(
20        private readonly Article $article
21    ) {
22        $this->onQueue('lemmy-posts');
23    }
24
25    public function handle(): void
26    {
27        $extractedData = ArticleFetcher::fetchArticleData($this->article);
28
29        /** @var ArticlePublishingService $publishingService */
30        $publishingService = resolve(ArticlePublishingService::class);
31
32        try {
33            $publishingService->publishToRoutedChannels($this->article, $extractedData);
34        } catch (PublishException $e) {
35            $this->fail($e);
36        }
37    }
38}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:50:30 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-progress/Jobs/SyncChannelPostsJob.php.html b/backend/coverage-report-progress/Jobs/SyncChannelPostsJob.php.html deleted file mode 100644 index d800207e..00000000 --- a/backend/coverage-report-progress/Jobs/SyncChannelPostsJob.php.html +++ /dev/null @@ -1,352 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Jobs/SyncChannelPostsJob.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 42
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 5
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
SyncChannelPostsJob
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 42
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 5
182
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 __construct
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 dispatchForAllActiveChannels
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 9
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 handle
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 5
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
6
 syncLemmyChannelPosts
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 16
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
20
 getAuthToken
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 11
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
30
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Jobs;
4
5use App\Enums\PlatformEnum;
6use App\Exceptions\PlatformAuthException;
7use App\Models\PlatformAccount;
8use App\Models\PlatformChannel;
9use App\Modules\Lemmy\Services\LemmyApiService;
10use App\Services\Log\LogSaver;
11use Exception;
12use Illuminate\Contracts\Queue\ShouldBeUnique;
13use Illuminate\Contracts\Queue\ShouldQueue;
14use Illuminate\Database\Eloquent\Collection;
15use Illuminate\Foundation\Queue\Queueable;
16use Illuminate\Support\Facades\Cache;
17
18class SyncChannelPostsJob implements ShouldQueue, ShouldBeUnique
19{
20    use Queueable;
21
22    public function __construct(
23        private readonly PlatformChannel $channel
24    ) {
25        $this->onQueue('sync');
26    }
27
28    public static function dispatchForAllActiveChannels(): void
29    {
30        PlatformChannel::with(['platformInstance', 'platformAccounts'])
31            ->whereHas('platformInstance', fn ($query) => $query->where('platform', PlatformEnum::LEMMY))
32            ->whereHas('platformAccounts', fn ($query) => $query->where('is_active', true))
33            ->where('is_active', true)
34            ->get()
35            ->each(function (PlatformChannel $channel) {
36                self::dispatch($channel);
37                LogSaver::info('Dispatched sync job for channel', $channel);
38            });
39    }
40
41    public function handle(): void
42    {
43        LogSaver::info('Starting channel posts sync job', $this->channel);
44
45        match ($this->channel->platformInstance->platform) {
46            PlatformEnum::LEMMY => $this->syncLemmyChannelPosts(),
47        };
48
49        LogSaver::info('Channel posts sync job completed', $this->channel);
50    }
51
52    /**
53     * @throws PlatformAuthException
54     */
55    private function syncLemmyChannelPosts(): void
56    {
57        try {
58            /** @var Collection<int, PlatformAccount> $accounts */
59            $accounts = $this->channel->activePlatformAccounts()->get();
60            $account = $accounts->first();
61
62            if (! $account) {
63                throw new PlatformAuthException(PlatformEnum::LEMMY, 'No active account found for channel');
64            }
65
66            $api = new LemmyApiService($this->channel->platformInstance->url);
67            $token = $this->getAuthToken($api, $account);
68
69            $platformChannelId = $this->channel->channel_id
70                ? $this->channel->channel_id
71                : $api->getCommunityId($this->channel->name, $token);
72
73            $api->syncChannelPosts($token, $platformChannelId, $this->channel->name);
74
75            LogSaver::info('Channel posts synced successfully', $this->channel);
76
77        } catch (Exception $e) {
78            LogSaver::error('Failed to sync channel posts', $this->channel, [
79                'error' => $e->getMessage()
80            ]);
81
82            throw $e;
83        }
84    }
85
86    /**
87     * @throws PlatformAuthException
88     */
89    private function getAuthToken(LemmyApiService $api, PlatformAccount $account): string
90    {
91        $cacheKey = "lemmy_jwt_token_{$account->id}";
92        $cachedToken = Cache::get($cacheKey);
93
94        if ($cachedToken) {
95            return $cachedToken;
96        }
97
98        if (!$account->username || !$account->password) {
99            throw new PlatformAuthException(PlatformEnum::LEMMY, 'Missing credentials for account');
100        }
101
102        $token = $api->login($account->username, $account->password);
103
104        if (!$token) {
105            throw new PlatformAuthException(PlatformEnum::LEMMY, 'Login failed for account');
106        }
107
108        Cache::put($cacheKey, $token, 3600);
109
110        return $token;
111    }
112}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:50:30 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-progress/Jobs/dashboard.html b/backend/coverage-report-progress/Jobs/dashboard.html deleted file mode 100644 index 782b737e..00000000 --- a/backend/coverage-report-progress/Jobs/dashboard.html +++ /dev/null @@ -1,308 +0,0 @@ - - - - - Dashboard for /var/www/html/backend/app/Jobs - - - - - - - -
-
-
-
- -
-
-
-
-
-
-
-

Classes

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
-
-
-

Insufficient Coverage

- -
-
-

Project Risks

- -
-
-
-
-

Methods

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
-
-
-

Insufficient Coverage

- -
-
-

Project Risks

-
- - - - - - - - - - - - - - - -
MethodCRAP
getAuthToken30
syncLemmyChannelPosts20
handle6
handle6
handle6
-
-
-
- -
- - - - - - diff --git a/backend/coverage-report-progress/Jobs/index.html b/backend/coverage-report-progress/Jobs/index.html deleted file mode 100644 index c2ec45eb..00000000 --- a/backend/coverage-report-progress/Jobs/index.html +++ /dev/null @@ -1,203 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Jobs - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 81
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 12
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 4
ArticleDiscoveryForFeedJob.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 26
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
ArticleDiscoveryJob.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 7
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
PublishToLemmyJob.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 6
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
SyncChannelPostsJob.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 42
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 5
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- -
- - diff --git a/backend/coverage-report-progress/Listeners/LogExceptionToDatabase.php.html b/backend/coverage-report-progress/Listeners/LogExceptionToDatabase.php.html deleted file mode 100644 index d5bc252e..00000000 --- a/backend/coverage-report-progress/Listeners/LogExceptionToDatabase.php.html +++ /dev/null @@ -1,179 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Listeners/LogExceptionToDatabase.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 12
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
LogExceptionToDatabase
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 12
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 handle
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 12
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Listeners;
4
5use App\Events\ExceptionLogged;
6use App\Events\ExceptionOccurred;
7use App\Models\Log;
8class LogExceptionToDatabase
9{
10
11    public function handle(ExceptionOccurred $event): void
12    {
13        $log = Log::create([
14            'level' => $event->level,
15            'message' => $event->message,
16            'context' => [
17                'exception_class' => get_class($event->exception),
18                'file' => $event->exception->getFile(),
19                'line' => $event->exception->getLine(),
20                'trace' => $event->exception->getTraceAsString(),
21                ...$event->context
22            ]
23        ]);
24
25        ExceptionLogged::dispatch($log);
26    }
27}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:50:30 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-progress/Listeners/PublishApprovedArticle.php.html b/backend/coverage-report-progress/Listeners/PublishApprovedArticle.php.html deleted file mode 100644 index 1c07178d..00000000 --- a/backend/coverage-report-progress/Listeners/PublishApprovedArticle.php.html +++ /dev/null @@ -1,179 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Listeners/PublishApprovedArticle.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 5
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
PublishApprovedArticle
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 5
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
20
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 handle
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 5
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
20
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Listeners;
4
5use App\Events\ArticleApproved;
6use App\Events\ArticleReadyToPublish;
7use Illuminate\Contracts\Queue\ShouldQueue;
8
9class PublishApprovedArticle implements ShouldQueue
10{
11    public string $queue = 'default';
12
13    public function handle(ArticleApproved $event): void
14    {
15        $article = $event->article;
16
17        // Skip if already has publication (prevents duplicate processing)
18        if ($article->articlePublication()->exists()) {
19            return;
20        }
21
22        // Only publish if the article is valid and approved
23        if ($article->isValid() && $article->isApproved()) {
24            event(new ArticleReadyToPublish($article));
25        }
26    }
27}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:50:30 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-progress/Listeners/PublishArticle.php.html b/backend/coverage-report-progress/Listeners/PublishArticle.php.html deleted file mode 100644 index 2ef963a8..00000000 --- a/backend/coverage-report-progress/Listeners/PublishArticle.php.html +++ /dev/null @@ -1,213 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Listeners/PublishArticle.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 13
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
PublishArticle
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 13
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
12
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 __construct
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 handle
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 12
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
6
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Listeners;
4
5use App\Events\ArticleReadyToPublish;
6use App\Jobs\PublishToLemmyJob;
7use Illuminate\Contracts\Queue\ShouldQueue;
8
9class PublishArticle implements ShouldQueue
10{
11    public string|null $queue = 'lemmy-publish';
12    public int $delay = 300;
13    public int $tries = 3;
14    public int $backoff = 300;
15
16    public function __construct()
17    {}
18
19    public function handle(ArticleReadyToPublish $event): void
20    {
21        $article = $event->article;
22
23        if ($article->articlePublication()->exists()) {
24            logger()->info('Article already published, skipping job dispatch', [
25                'article_id' => $article->id,
26                'url' => $article->url
27            ]);
28
29            return;
30        }
31
32        logger()->info('Article queued for publishing to Lemmy', [
33            'article_id' => $article->id,
34            'url' => $article->url
35        ]);
36
37        PublishToLemmyJob::dispatch($article);
38    }
39}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:50:30 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-progress/Listeners/ValidateArticleListener.php.html b/backend/coverage-report-progress/Listeners/ValidateArticleListener.php.html deleted file mode 100644 index 5cc0bbd9..00000000 --- a/backend/coverage-report-progress/Listeners/ValidateArticleListener.php.html +++ /dev/null @@ -1,201 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Listeners/ValidateArticleListener.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 13
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
ValidateArticleListener
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 13
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
56
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 handle
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 13
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
56
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Listeners;
4
5use App\Events\NewArticleFetched;
6use App\Events\ArticleReadyToPublish;
7use App\Models\Setting;
8use App\Services\Article\ValidationService;
9use Illuminate\Contracts\Queue\ShouldQueue;
10
11class ValidateArticleListener implements ShouldQueue
12{
13    public string $queue = 'default';
14
15    public function handle(NewArticleFetched $event): void
16    {
17        $article = $event->article;
18
19        if (! is_null($article->validated_at)) {
20            return;
21        }
22
23        // Skip if already has publication (prevents duplicate processing)
24        if ($article->articlePublication()->exists()) {
25            return;
26        }
27
28        $article = ValidationService::validate($article);
29
30        if ($article->isValid()) {
31            // Double-check publication doesn't exist (race condition protection)
32            if ($article->articlePublication()->exists()) {
33                return;
34            }
35
36            // Check if approval system is enabled
37            if (Setting::isPublishingApprovalsEnabled()) {
38                // If approvals are enabled, only proceed if article is approved
39                if ($article->isApproved()) {
40                    event(new ArticleReadyToPublish($article));
41                }
42                // If not approved, article will wait for manual approval
43            } else {
44                // If approvals are disabled, proceed with publishing
45                event(new ArticleReadyToPublish($article));
46            }
47        }
48    }
49}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:50:30 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-progress/Listeners/dashboard.html b/backend/coverage-report-progress/Listeners/dashboard.html deleted file mode 100644 index d63c7d33..00000000 --- a/backend/coverage-report-progress/Listeners/dashboard.html +++ /dev/null @@ -1,299 +0,0 @@ - - - - - Dashboard for /var/www/html/backend/app/Listeners - - - - - - - -
-
-
-
- -
-
-
-
-
-
-
-

Classes

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
- -
-
-

Methods

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
-
-
-

Insufficient Coverage

-
- - - - - - - - - - - - - - - -
MethodCoverage
handle0%
handle0%
__construct0%
handle0%
handle0%
-
-
-
-

Project Risks

-
- - - - - - - - - - - - - -
MethodCRAP
handle56
handle20
handle6
-
-
-
- -
- - - - - - diff --git a/backend/coverage-report-progress/Listeners/index.html b/backend/coverage-report-progress/Listeners/index.html deleted file mode 100644 index bb1a7eec..00000000 --- a/backend/coverage-report-progress/Listeners/index.html +++ /dev/null @@ -1,203 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Listeners - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 43
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 5
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 4
LogExceptionToDatabase.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 12
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
PublishApprovedArticle.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 5
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
PublishArticle.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 13
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
ValidateArticleListener.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 13
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- -
- - diff --git a/backend/coverage-report-progress/LogLevelEnum.php.html b/backend/coverage-report-progress/LogLevelEnum.php.html deleted file mode 100644 index ff6a5869..00000000 --- a/backend/coverage-report-progress/LogLevelEnum.php.html +++ /dev/null @@ -1,177 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/LogLevelEnum.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 100.00% covered (success) -
-
-
100.00%
7 / 7
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
CRAP
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
LogLevelEnum
-
- 100.00% covered (success) -
-
-
100.00%
7 / 7
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
1
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
 toArray
-
- 100.00% covered (success) -
-
-
100.00%
7 / 7
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
1
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App;
4
5enum LogLevelEnum: string
6{
7    case DEBUG = 'debug';
8    case INFO = 'info';
9    case WARNING = 'warning';
10    case ERROR = 'error';
11    case CRITICAL = 'critical';
12
13    /**
14     * @return array<int, string>
15     */
16    public static function toArray(): array
17    {
18        return [
19            self::DEBUG->value,
20            self::INFO->value,
21            self::WARNING->value,
22            self::ERROR->value,
23            self::CRITICAL->value,
24        ];
25    }
26}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:50:30 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-progress/Models/Article.php.html b/backend/coverage-report-progress/Models/Article.php.html deleted file mode 100644 index 2c85ff36..00000000 --- a/backend/coverage-report-progress/Models/Article.php.html +++ /dev/null @@ -1,522 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Models/Article.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 66.67% covered (warning) -
-
-
66.67%
26 / 39
-
- 54.55% covered (warning) -
-
-
54.55%
6 / 11
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
Article
-
- 66.67% covered (warning) -
-
-
66.67%
26 / 39
-
- 54.55% covered (warning) -
-
-
54.55%
6 / 11
23.33
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 casts
-
- 100.00% covered (success) -
-
-
100.00%
10 / 10
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
1
 isValid
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 5
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
12
 isApproved
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 isPending
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 isRejected
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 approve
-
- 100.00% covered (success) -
-
-
100.00%
6 / 6
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
1
 reject
-
- 100.00% covered (success) -
-
-
100.00%
5 / 5
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
1
 canBePublished
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 5
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
12
 articlePublication
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
1
 feed
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
1
 booted
-
- 100.00% covered (success) -
-
-
100.00%
3 / 3
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
1
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Models;
4
5use App\Events\ArticleApproved;
6use App\Events\NewArticleFetched;
7use Database\Factories\ArticleFactory;
8use Illuminate\Database\Eloquent\Factories\HasFactory;
9use Illuminate\Database\Eloquent\Model;
10use Illuminate\Database\Eloquent\Relations\BelongsTo;
11use Illuminate\Database\Eloquent\Relations\HasOne;
12use Illuminate\Support\Carbon;
13
14/**
15 * @method static firstOrCreate(array<string, mixed> $array)
16 * @method static where(string $string, string $url)
17 * @method static create(array<string, mixed> $array)
18 * @property integer $id
19 * @property int $feed_id
20 * @property Feed $feed
21 * @property string $url
22 * @property bool|null $is_valid
23 * @property Carbon|null $validated_at
24 * @property Carbon $created_at
25 * @property Carbon $updated_at
26 * @property ArticlePublication $articlePublication
27 */
28class Article extends Model
29{
30    /** @use HasFactory<ArticleFactory> */
31    use HasFactory;
32
33    protected $fillable = [
34        'feed_id',
35        'url',
36        'title',
37        'description',
38        'is_valid',
39        'is_duplicate',
40        'approval_status',
41        'approved_at',
42        'approved_by',
43        'fetched_at',
44        'validated_at',
45    ];
46
47    /**
48     * @return array<string, string>
49     */
50    public function casts(): array
51    {
52        return [
53            'is_valid' => 'boolean',
54            'is_duplicate' => 'boolean',
55            'approval_status' => 'string',
56            'approved_at' => 'datetime',
57            'fetched_at' => 'datetime',
58            'validated_at' => 'datetime',
59            'created_at' => 'datetime',
60            'updated_at' => 'datetime',
61        ];
62    }
63
64    public function isValid(): bool
65    {
66        if (is_null($this->validated_at)) {
67            return false;
68        }
69
70        if (is_null($this->is_valid)) {
71            return false;
72        }
73
74        return $this->is_valid;
75    }
76
77    public function isApproved(): bool
78    {
79        return $this->approval_status === 'approved';
80    }
81
82    public function isPending(): bool
83    {
84        return $this->approval_status === 'pending';
85    }
86
87    public function isRejected(): bool
88    {
89        return $this->approval_status === 'rejected';
90    }
91
92    public function approve(string $approvedBy = null): void
93    {
94        $this->update([
95            'approval_status' => 'approved',
96            'approved_at' => now(),
97            'approved_by' => $approvedBy,
98        ]);
99
100        // Fire event to trigger publishing
101        event(new ArticleApproved($this));
102    }
103
104    public function reject(string $rejectedBy = null): void
105    {
106        $this->update([
107            'approval_status' => 'rejected',
108            'approved_at' => now(),
109            'approved_by' => $rejectedBy,
110        ]);
111    }
112
113    public function canBePublished(): bool
114    {
115        if (!$this->isValid()) {
116            return false;
117        }
118
119        // If approval system is disabled, auto-approve valid articles
120        if (!\App\Models\Setting::isPublishingApprovalsEnabled()) {
121            return true;
122        }
123
124        // If approval system is enabled, only approved articles can be published
125        return $this->isApproved();
126    }
127
128    /**
129     * @return HasOne<ArticlePublication, $this>
130     */
131    public function articlePublication(): HasOne
132    {
133        return $this->hasOne(ArticlePublication::class);
134    }
135
136    /**
137     * @return BelongsTo<Feed, $this>
138     */
139    public function feed(): BelongsTo
140    {
141        return $this->belongsTo(Feed::class);
142    }
143
144    protected static function booted(): void
145    {
146        static::created(function ($article) {
147            event(new NewArticleFetched($article));
148        });
149    }
150}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:50:30 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-progress/Models/ArticlePublication.php.html b/backend/coverage-report-progress/Models/ArticlePublication.php.html deleted file mode 100644 index 26f9c6c0..00000000 --- a/backend/coverage-report-progress/Models/ArticlePublication.php.html +++ /dev/null @@ -1,196 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Models/ArticlePublication.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
ArticlePublication
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 article
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Models;
4
5use Database\Factories\ArticlePublicationFactory;
6use Illuminate\Database\Eloquent\Factories\HasFactory;
7use Illuminate\Database\Eloquent\Model;
8use Illuminate\Database\Eloquent\Relations\BelongsTo;
9
10/**
11 * @property integer $article_id
12 * @property integer $platform_channel_id
13 * @property integer $post_id
14 *
15 * @method static create(array<string, mixed> $array)
16 */
17class ArticlePublication extends Model
18{
19    /** @use HasFactory<ArticlePublicationFactory> */
20    use HasFactory;
21    
22    protected $fillable = [
23        'article_id',
24        'platform_channel_id',
25        'post_id',
26        'published_at',
27        'published_by',
28        'platform',
29        'publication_data',
30    ];
31
32    protected $casts = [
33        'published_at' => 'datetime',
34        'publication_data' => 'array',
35    ];
36
37    /**
38     * @return BelongsTo<Article, $this>
39     */
40    public function article(): BelongsTo
41    {
42        return $this->belongsTo(Article::class);
43    }
44}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:50:30 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-progress/Models/Feed.php.html b/backend/coverage-report-progress/Models/Feed.php.html deleted file mode 100644 index 0302b2a0..00000000 --- a/backend/coverage-report-progress/Models/Feed.php.html +++ /dev/null @@ -1,382 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Models/Feed.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 24
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 6
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
Feed
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 24
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 6
182
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 getTypeDisplayAttribute
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 5
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
20
 getStatusAttribute
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 10
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
30
 channels
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 4
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 activeChannels
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 articles
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 language
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Models;
4
5use Database\Factories\FeedFactory;
6use Illuminate\Database\Eloquent\Factories\HasFactory;
7use Illuminate\Database\Eloquent\Model;
8use Illuminate\Database\Eloquent\Relations\BelongsTo;
9use Illuminate\Database\Eloquent\Relations\BelongsToMany;
10use Illuminate\Database\Eloquent\Relations\HasMany;
11use Illuminate\Support\Carbon;
12
13/**
14 * @property int $id
15 * @property string $name
16 * @property string $url
17 * @property string $type
18 * @property int $language_id
19 * @property Language|null $language
20 * @property string $description
21 * @property array<string, mixed> $settings
22 * @property bool $is_active
23 * @property Carbon|null $last_fetched_at
24 * @property Carbon $created_at
25 * @property Carbon $updated_at
26 * @method static orderBy(string $string, string $string1)
27 * @method static where(string $string, true $true)
28 * @method static findOrFail(mixed $feed_id)
29 */
30class Feed extends Model
31{
32    /** @use HasFactory<FeedFactory> */
33    use HasFactory;
34    private const RECENT_FETCH_THRESHOLD_HOURS = 2;
35    private const DAILY_FETCH_THRESHOLD_HOURS = 24;
36
37    protected $fillable = [
38        'name',
39        'url',
40        'type',
41        'language_id',
42        'description',
43        'settings',
44        'is_active',
45        'last_fetched_at'
46    ];
47
48    protected $casts = [
49        'settings' => 'array',
50        'is_active' => 'boolean',
51        'last_fetched_at' => 'datetime'
52    ];
53
54    public function getTypeDisplayAttribute(): string
55    {
56        return match ($this->type) {
57            'website' => 'Website',
58            'rss' => 'RSS Feed',
59            default => 'Unknown'
60        };
61    }
62
63    public function getStatusAttribute(): string
64    {
65        if (!$this->is_active) {
66            return 'Inactive';
67        }
68
69        if (!$this->last_fetched_at) {
70            return 'Never fetched';
71        }
72
73        $hoursAgo = $this->last_fetched_at->diffInHours(now());
74
75        if ($hoursAgo < self::RECENT_FETCH_THRESHOLD_HOURS) {
76            return 'Recently fetched';
77        } elseif ($hoursAgo < self::DAILY_FETCH_THRESHOLD_HOURS) {
78            return "Fetched {$hoursAgo}h ago";
79        } else {
80            return "Fetched " . $this->last_fetched_at->diffForHumans();
81        }
82    }
83
84    /**
85     * @return BelongsToMany<PlatformChannel, $this, Route>
86     */
87    public function channels(): BelongsToMany
88    {
89        return $this->belongsToMany(PlatformChannel::class, 'routes')
90            ->using(Route::class)
91            ->withPivot(['is_active', 'priority', 'filters'])
92            ->withTimestamps();
93    }
94
95    /**
96     * @return BelongsToMany<PlatformChannel, $this, Route>
97     */
98    public function activeChannels(): BelongsToMany
99    {
100        return $this->channels()
101            ->wherePivot('is_active', true)
102            ->orderByPivot('priority', 'desc');
103    }
104
105    /**
106     * @return HasMany<Article, $this>
107     */
108    public function articles(): HasMany
109    {
110        return $this->hasMany(Article::class);
111    }
112
113    /**
114     * @return BelongsTo<Language, $this>
115     */
116    public function language(): BelongsTo
117    {
118        return $this->belongsTo(Language::class);
119    }
120}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:50:30 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-progress/Models/Keyword.php.html b/backend/coverage-report-progress/Models/Keyword.php.html deleted file mode 100644 index 66c8cda9..00000000 --- a/backend/coverage-report-progress/Models/Keyword.php.html +++ /dev/null @@ -1,223 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Models/Keyword.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
Keyword
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
6
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 feed
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 platformChannel
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Models;
4
5use Illuminate\Database\Eloquent\Model;
6use Illuminate\Database\Eloquent\Relations\BelongsTo;
7use Illuminate\Support\Carbon;
8
9/**
10 * @property int $id
11 * @property int $feed_id
12 * @property Feed $feed
13 * @property int $platform_channel_id
14 * @property PlatformChannel $platformChannel
15 * @property string $keyword
16 * @property bool $is_active
17 * @property Carbon $created_at
18 * @property Carbon $updated_at
19 */
20class Keyword extends Model
21{
22    protected $fillable = [
23        'feed_id',
24        'platform_channel_id',
25        'keyword',
26        'is_active'
27    ];
28
29    protected $casts = [
30        'is_active' => 'boolean'
31    ];
32
33    /**
34     * @return BelongsTo<Feed, $this>
35     */
36    public function feed(): BelongsTo
37    {
38        return $this->belongsTo(Feed::class);
39    }
40
41    /**
42     * @return BelongsTo<PlatformChannel, $this>
43     */
44    public function platformChannel(): BelongsTo
45    {
46        return $this->belongsTo(PlatformChannel::class);
47    }
48
49}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:50:30 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-progress/Models/Language.php.html b/backend/coverage-report-progress/Models/Language.php.html deleted file mode 100644 index 5d1964ae..00000000 --- a/backend/coverage-report-progress/Models/Language.php.html +++ /dev/null @@ -1,248 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Models/Language.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 5
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
Language
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 5
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
12
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 platformInstances
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 platformChannels
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 feeds
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Models;
4
5use Database\Factories\LanguageFactory;
6use Illuminate\Database\Eloquent\Factories\HasFactory;
7use Illuminate\Database\Eloquent\Model;
8use Illuminate\Database\Eloquent\Relations\BelongsToMany;
9use Illuminate\Database\Eloquent\Relations\HasMany;
10
11class Language extends Model
12{
13    /** @use HasFactory<LanguageFactory> */
14    use HasFactory;
15
16    protected $fillable = [
17        'short_code',
18        'name', 
19        'native_name',
20        'is_active'
21    ];
22
23    protected $casts = [
24        'is_active' => 'boolean'
25    ];
26
27    /**
28     * @return BelongsToMany<PlatformInstance, $this>
29     */
30    public function platformInstances(): BelongsToMany
31    {
32        return $this->belongsToMany(PlatformInstance::class)
33            ->withPivot(['platform_language_id', 'is_default'])
34            ->withTimestamps();
35    }
36
37    /**
38     * @return HasMany<PlatformChannel, $this>
39     */
40    public function platformChannels(): HasMany
41    {
42        return $this->hasMany(PlatformChannel::class);
43    }
44
45    /**
46     * @return HasMany<Feed, $this>
47     */
48    public function feeds(): HasMany
49    {
50        return $this->hasMany(Feed::class);
51    }
52}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:50:30 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-progress/Models/Log.php.html b/backend/coverage-report-progress/Models/Log.php.html deleted file mode 100644 index be158a3e..00000000 --- a/backend/coverage-report-progress/Models/Log.php.html +++ /dev/null @@ -1,136 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Models/Log.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
n/a
0 / 0
n/a
0 / 0
CRAP
n/a
0 / 0
Log
n/a
0 / 0
n/a
0 / 0
0
n/a
0 / 0
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Models;
4
5use App\LogLevelEnum;
6use Illuminate\Database\Eloquent\Factories\HasFactory;
7use Illuminate\Database\Eloquent\Model;
8use Illuminate\Support\Carbon;
9
10/**
11 * @method static create(array<string, mixed> $array)
12 * @property LogLevelEnum $level
13 * @property string $message
14 * @property array<string, mixed> $context
15 * @property Carbon $created_at
16 * @property Carbon $updated_at
17 */
18class Log extends Model
19{
20    use HasFactory;
21    
22    protected $table = 'logs';
23
24    protected $fillable = [
25        'level',
26        'message',
27        'context',
28    ];
29
30    protected $casts = [
31        'level' => LogLevelEnum::class,
32        'context' => 'array',
33        'created_at' => 'datetime',
34        'updated_at' => 'datetime',
35    ];
36}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:50:30 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-progress/Models/PlatformAccount.php.html b/backend/coverage-report-progress/Models/PlatformAccount.php.html deleted file mode 100644 index f5efe27f..00000000 --- a/backend/coverage-report-progress/Models/PlatformAccount.php.html +++ /dev/null @@ -1,384 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Models/PlatformAccount.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 21
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 6
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
PlatformAccount
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 21
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 6
110
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 password
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 4
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
12
 apiToken
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 4
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
12
 getActive
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 setAsActive
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 4
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 channels
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 activeChannels
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Models;
4
5use Database\Factories\PlatformAccountFactory;
6use Illuminate\Database\Eloquent\Factories\HasFactory;
7use Illuminate\Database\Eloquent\Model;
8use Illuminate\Database\Eloquent\Casts\Attribute;
9use Illuminate\Database\Eloquent\Collection;
10use Illuminate\Database\Eloquent\Relations\BelongsToMany;
11use Illuminate\Support\Carbon;
12use Illuminate\Support\Facades\Crypt;
13use App\Enums\PlatformEnum;
14
15/**
16 * @property int $id
17 * @property PlatformEnum $platform
18 * @property string $instance_url
19 * @property string $username
20 * @property string $password
21 * @property string $settings
22 * @property bool $is_active
23 * @property Carbon $last_tested_at
24 * @property string $status
25 * @property Carbon $created_at
26 * @property Carbon $updated_at
27 * @property Collection<int, PlatformChannel> $activeChannels
28 * @method static where(string $string, PlatformEnum $platform)
29 * @method static orderBy(string $string)
30 * @method static create(array<string, mixed> $validated)
31 */
32class PlatformAccount extends Model
33{
34    /** @use HasFactory<PlatformAccountFactory> */
35    use HasFactory;
36
37    protected $fillable = [
38        'platform',
39        'instance_url',
40        'username',
41        'password',
42        'api_token',
43        'settings',
44        'is_active',
45        'last_tested_at',
46        'status'
47    ];
48
49    protected $casts = [
50        'platform' => PlatformEnum::class,
51        'settings' => 'array',
52        'is_active' => 'boolean',
53        'last_tested_at' => 'datetime'
54    ];
55
56    // Encrypt password when storing
57    /**
58     * @return Attribute<string|null, string|null>
59     */
60    protected function password(): Attribute
61    {
62        return Attribute::make(
63            get: fn ($value) => $value ? Crypt::decryptString($value) : null,
64            set: fn ($value) => $value ? Crypt::encryptString($value) : null,
65        );
66    }
67
68    // Encrypt API token when storing
69    /**
70     * @return Attribute<string|null, string|null>
71     */
72    protected function apiToken(): Attribute
73    {
74        return Attribute::make(
75            get: fn ($value) => $value ? Crypt::decryptString($value) : null,
76            set: fn ($value) => $value ? Crypt::encryptString($value) : null,
77        );
78    }
79
80    // Get the active accounts for a platform (returns collection)
81    /**
82     * @return Collection<int, PlatformAccount>
83     */
84    public static function getActive(PlatformEnum $platform): Collection
85    {
86        return static::where('platform', $platform)
87            ->where('is_active', true)
88            ->get();
89    }
90
91    // Set this account as active (deactivates others for same platform)
92    public function setAsActive(): void
93    {
94        // Deactivate other accounts for this platform
95        static::where('platform', $this->platform)
96            ->where('id', '!=', $this->id)
97            ->update(['is_active' => false]);
98
99        // Activate this account
100        $this->update(['is_active' => true]);
101    }
102
103    /**
104     * @return BelongsToMany<PlatformChannel, $this>
105     */
106    public function channels(): BelongsToMany
107    {
108        return $this->belongsToMany(PlatformChannel::class, 'platform_account_channels')
109            ->withPivot(['is_active', 'priority'])
110            ->withTimestamps();
111    }
112
113    /**
114     * @return BelongsToMany<PlatformChannel, $this>
115     */
116    public function activeChannels(): BelongsToMany
117    {
118        return $this->channels()
119            ->wherePivot('is_active', true)
120            ->orderByPivot('priority', 'desc');
121    }
122}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:50:30 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-progress/Models/PlatformChannel.php.html b/backend/coverage-report-progress/Models/PlatformChannel.php.html deleted file mode 100644 index c514d29f..00000000 --- a/backend/coverage-report-progress/Models/PlatformChannel.php.html +++ /dev/null @@ -1,387 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Models/PlatformChannel.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 14
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 7
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
PlatformChannel
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 14
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 7
56
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 platformInstance
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 platformAccounts
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 activePlatformAccounts
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 getFullNameAttribute
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 feeds
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 4
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 activeFeeds
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 language
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Models;
4
5use Database\Factories\PlatformChannelFactory;
6use Illuminate\Database\Eloquent\Factories\HasFactory;
7use Illuminate\Database\Eloquent\Model;
8use Illuminate\Database\Eloquent\Relations\BelongsTo;
9use Illuminate\Database\Eloquent\Relations\BelongsToMany;
10
11/**
12 * @method static findMany(mixed $channel_ids)
13 * @property integer $id
14 * @property integer $platform_instance_id
15 * @property PlatformInstance $platformInstance
16 * @property integer $channel_id
17 * @property string $name
18 * @property int $language_id
19 * @property Language|null $language
20 * @property boolean $is_active
21 */
22class PlatformChannel extends Model
23{
24    /** @use HasFactory<PlatformChannelFactory> */
25    use HasFactory;
26
27    protected $table = 'platform_channels';
28
29    protected $fillable = [
30        'platform_instance_id',
31        'name',
32        'display_name',
33        'channel_id',
34        'description',
35        'language_id',
36        'is_active'
37    ];
38
39    protected $casts = [
40        'is_active' => 'boolean'
41    ];
42
43    /**
44     * @return BelongsTo<PlatformInstance, $this>
45     */
46    public function platformInstance(): BelongsTo
47    {
48        return $this->belongsTo(PlatformInstance::class);
49    }
50
51    /**
52     * @return BelongsToMany<PlatformAccount, $this>
53     */
54    public function platformAccounts(): BelongsToMany
55    {
56        return $this->belongsToMany(PlatformAccount::class, 'platform_account_channels')
57            ->withPivot(['is_active', 'priority'])
58            ->withTimestamps();
59    }
60
61    /**
62     * @return BelongsToMany<PlatformAccount, $this>
63     */
64    public function activePlatformAccounts(): BelongsToMany
65    {
66        return $this->platformAccounts()->wherePivot('is_active', true);
67    }
68
69    public function getFullNameAttribute(): string
70    {
71        // For Lemmy, use /c/ prefix
72        return $this->platformInstance->url . '/c/' . $this->name;
73    }
74
75    /**
76     * @return BelongsToMany<Feed, $this, Route>
77     */
78    public function feeds(): BelongsToMany
79    {
80        return $this->belongsToMany(Feed::class, 'routes')
81            ->using(Route::class)
82            ->withPivot(['is_active', 'priority', 'filters'])
83            ->withTimestamps();
84    }
85
86    /**
87     * @return BelongsToMany<Feed, $this, Route>
88     */
89    public function activeFeeds(): BelongsToMany
90    {
91        return $this->feeds()
92            ->wherePivot('is_active', true)
93            ->orderByPivot('priority', 'desc');
94    }
95
96    /**
97     * @return BelongsTo<Language, $this>
98     */
99    public function language(): BelongsTo
100    {
101        return $this->belongsTo(Language::class);
102    }
103}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:50:30 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-progress/Models/PlatformChannelPost.php.html b/backend/coverage-report-progress/Models/PlatformChannelPost.php.html deleted file mode 100644 index 1cbab37b..00000000 --- a/backend/coverage-report-progress/Models/PlatformChannelPost.php.html +++ /dev/null @@ -1,255 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Models/PlatformChannelPost.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 21
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
PlatformChannelPost
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 21
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
12
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 casts
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 4
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 urlExists
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 4
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 storePost
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 13
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Models;
4
5use App\Enums\PlatformEnum;
6use Illuminate\Database\Eloquent\Model;
7
8/**
9 * @method static where(string $string, PlatformEnum $platform)
10 * @method static updateOrCreate(array<string, mixed> $array, array<string, mixed> $array1)
11 */
12class PlatformChannelPost extends Model
13{
14    protected $fillable = [
15        'platform',
16        'channel_id',
17        'channel_name',
18        'post_id',
19        'url',
20        'title',
21        'posted_at',
22    ];
23
24    /**
25     * @return array<string, string>
26     */
27    protected function casts(): array
28    {
29        return [
30            'posted_at' => 'datetime',
31            'platform' => PlatformEnum::class,
32        ];
33    }
34
35    public static function urlExists(PlatformEnum $platform, string $channelId, string $url): bool
36    {
37        return self::where('platform', $platform)
38            ->where('channel_id', $channelId)
39            ->where('url', $url)
40            ->exists();
41    }
42
43    public static function storePost(PlatformEnum $platform, string $channelId, ?string $channelName, string $postId, ?string $url, ?string $title, ?\DateTime $postedAt = null): self
44    {
45        return self::updateOrCreate(
46            [
47                'platform' => $platform,
48                'channel_id' => $channelId,
49                'post_id' => $postId,
50            ],
51            [
52                'channel_name' => $channelName,
53                'url' => $url,
54                'title' => $title,
55                'posted_at' => $postedAt ?? now(),
56            ]
57        );
58    }
59}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:50:30 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-progress/Models/PlatformInstance.php.html b/backend/coverage-report-progress/Models/PlatformInstance.php.html deleted file mode 100644 index 3867338a..00000000 --- a/backend/coverage-report-progress/Models/PlatformInstance.php.html +++ /dev/null @@ -1,259 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Models/PlatformInstance.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 7
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
PlatformInstance
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 7
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
12
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 channels
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 languages
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 findByUrl
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Models;
4
5use App\Enums\PlatformEnum;
6use Database\Factories\PlatformInstanceFactory;
7use Illuminate\Database\Eloquent\Factories\HasFactory;
8use Illuminate\Database\Eloquent\Model;
9use Illuminate\Database\Eloquent\Relations\BelongsToMany;
10use Illuminate\Database\Eloquent\Relations\HasMany;
11
12/**
13 * @method static updateOrCreate(array<string, mixed> $array, $instanceData)
14 * @method static where(string $string, mixed $operator)
15 * @property PlatformEnum $platform
16 * @property string $url
17 * @property string $name
18 * @property string $description
19 * @property boolean $is_active
20 */
21class PlatformInstance extends Model
22{
23    /** @use HasFactory<PlatformInstanceFactory> */
24    use HasFactory;
25    
26    protected $fillable = [
27        'platform',
28        'url',
29        'name',
30        'description',
31        'is_active'
32    ];
33
34    protected $casts = [
35        'platform' => PlatformEnum::class,
36        'is_active' => 'boolean'
37    ];
38
39    /**
40     * @return HasMany<PlatformChannel, $this>
41     */
42    public function channels(): HasMany
43    {
44        return $this->hasMany(PlatformChannel::class);
45    }
46
47    /**
48     * @return BelongsToMany<Language, $this>
49     */
50    public function languages(): BelongsToMany
51    {
52        return $this->belongsToMany(Language::class)
53            ->withPivot(['platform_language_id', 'is_default'])
54            ->withTimestamps();
55    }
56
57    public static function findByUrl(PlatformEnum $platform, string $url): ?self
58    {
59        return static::where('platform', $platform)
60            ->where('url', $url)
61            ->first();
62    }
63}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:50:30 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-progress/Models/Route.php.html b/backend/coverage-report-progress/Models/Route.php.html deleted file mode 100644 index 121ad4c9..00000000 --- a/backend/coverage-report-progress/Models/Route.php.html +++ /dev/null @@ -1,263 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Models/Route.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 4
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
Route
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 4
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
12
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 feed
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 platformChannel
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 keywords
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Models;
4
5use Database\Factories\RouteFactory;
6use Illuminate\Database\Eloquent\Factories\HasFactory;
7use Illuminate\Database\Eloquent\Relations\BelongsTo;
8use Illuminate\Database\Eloquent\Relations\HasMany;
9use Illuminate\Database\Eloquent\Relations\Pivot;
10use Illuminate\Support\Carbon;
11
12/**
13 * @property int $feed_id
14 * @property int $platform_channel_id
15 * @property bool $is_active
16 * @property int $priority
17 * @property array<string, mixed> $filters
18 * @property Carbon $created_at
19 * @property Carbon $updated_at
20 */
21class Route extends Pivot
22{
23    /** @use HasFactory<RouteFactory> */
24    use HasFactory;
25    
26    protected $table = 'routes';
27
28    public $incrementing = false;
29
30    protected $fillable = [
31        'feed_id',
32        'platform_channel_id',
33        'is_active',
34        'priority',
35        'filters'
36    ];
37
38    protected $casts = [
39        'is_active' => 'boolean',
40        'filters' => 'array'
41    ];
42
43    /**
44     * @return BelongsTo<Feed, $this>
45     */
46    public function feed(): BelongsTo
47    {
48        return $this->belongsTo(Feed::class);
49    }
50
51    /**
52     * @return BelongsTo<PlatformChannel, $this>
53     */
54    public function platformChannel(): BelongsTo
55    {
56        return $this->belongsTo(PlatformChannel::class);
57    }
58
59    /**
60     * @return HasMany<Keyword, $this>
61     */
62    public function keywords(): HasMany
63    {
64        return $this->hasMany(Keyword::class, 'feed_id', 'feed_id')
65            ->where('platform_channel_id', $this->platform_channel_id);
66    }
67}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:50:30 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-progress/Models/Setting.php.html b/backend/coverage-report-progress/Models/Setting.php.html deleted file mode 100644 index bab8e518..00000000 --- a/backend/coverage-report-progress/Models/Setting.php.html +++ /dev/null @@ -1,360 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Models/Setting.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 50.00% covered (danger) -
-
-
50.00%
5 / 10
-
- 37.50% covered (danger) -
-
-
37.50%
3 / 8
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
Setting
-
- 50.00% covered (danger) -
-
-
50.00%
5 / 10
-
- 37.50% covered (danger) -
-
-
37.50%
3 / 8
22.50
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 get
-
- 100.00% covered (success) -
-
-
100.00%
2 / 2
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
2
 set
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 getBool
-
- 100.00% covered (success) -
-
-
100.00%
2 / 2
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
1
 setBool
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
6
 isArticleProcessingEnabled
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 setArticleProcessingEnabled
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 isPublishingApprovalsEnabled
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
1
 setPublishingApprovalsEnabled
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Models;
4
5use Illuminate\Database\Eloquent\Model;
6
7class Setting extends Model
8{
9    protected $fillable = ['key', 'value'];
10
11    public static function get(string $key, mixed $default = null): mixed
12    {
13        $setting = static::where('key', $key)->first();
14        
15        return $setting ? $setting->value : $default;
16    }
17
18    public static function set(string $key, mixed $value): void
19    {
20        static::updateOrCreate(['key' => $key], ['value' => $value]);
21    }
22
23    public static function getBool(string $key, bool $default = false): bool
24    {
25        $value = static::get($key, $default);
26        
27        return filter_var($value, FILTER_VALIDATE_BOOLEAN);
28    }
29
30    public static function setBool(string $key, bool $value): void
31    {
32        static::set($key, $value ? '1' : '0');
33    }
34
35    public static function isArticleProcessingEnabled(): bool
36    {
37        return static::getBool('article_processing_enabled', true);
38    }
39
40    public static function setArticleProcessingEnabled(bool $enabled): void
41    {
42        static::setBool('article_processing_enabled', $enabled);
43    }
44
45    public static function isPublishingApprovalsEnabled(): bool
46    {
47        return static::getBool('enable_publishing_approvals', false);
48    }
49
50    public static function setPublishingApprovalsEnabled(bool $enabled): void
51    {
52        static::setBool('enable_publishing_approvals', $enabled);
53    }
54}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:50:30 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-progress/Models/User.php.html b/backend/coverage-report-progress/Models/User.php.html deleted file mode 100644 index 15028bff..00000000 --- a/backend/coverage-report-progress/Models/User.php.html +++ /dev/null @@ -1,201 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Models/User.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 4
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
User
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 4
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 casts
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 4
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Models;
4
5// use Illuminate\Contracts\Auth\MustVerifyEmail;
6use Illuminate\Database\Eloquent\Factories\HasFactory;
7use Illuminate\Foundation\Auth\User as Authenticatable;
8use Illuminate\Notifications\Notifiable;
9use Laravel\Sanctum\HasApiTokens;
10
11class User extends Authenticatable
12{
13    /** @use HasFactory<\Database\Factories\UserFactory> */
14    use HasFactory, Notifiable, HasApiTokens;
15
16    /**
17     * The attributes that are mass assignable.
18     *
19     * @var list<string>
20     */
21    protected $fillable = [
22        'name',
23        'email',
24        'password',
25    ];
26
27    /**
28     * The attributes that should be hidden for serialization.
29     *
30     * @var list<string>
31     */
32    protected $hidden = [
33        'password',
34        'remember_token',
35    ];
36
37    /**
38     * Get the attributes that should be cast.
39     *
40     * @return array<string, string>
41     */
42    protected function casts(): array
43    {
44        return [
45            'email_verified_at' => 'datetime',
46            'password' => 'hashed',
47        ];
48    }
49}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:50:30 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-progress/Models/dashboard.html b/backend/coverage-report-progress/Models/dashboard.html deleted file mode 100644 index 9ea48d45..00000000 --- a/backend/coverage-report-progress/Models/dashboard.html +++ /dev/null @@ -1,352 +0,0 @@ - - - - - Dashboard for /var/www/html/backend/app/Models - - - - - - - -
-
-
-
- -
-
-
-
-
-
-
-

Classes

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
- -
-
-

Methods

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
- - -
- - - - - - diff --git a/backend/coverage-report-progress/Models/index.html b/backend/coverage-report-progress/Models/index.html deleted file mode 100644 index 35da39aa..00000000 --- a/backend/coverage-report-progress/Models/index.html +++ /dev/null @@ -1,440 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Models - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 20.39% covered (danger) -
-
-
20.39%
31 / 152
-
- 16.67% covered (danger) -
-
-
16.67%
9 / 54
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 12
Article.php
-
- 66.67% covered (warning) -
-
-
66.67%
26 / 39
-
- 54.55% covered (warning) -
-
-
54.55%
6 / 11
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
ArticlePublication.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
Feed.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 24
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 6
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
Keyword.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
Language.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 5
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
Log.php
n/a
0 / 0
n/a
0 / 0
n/a
0 / 0
PlatformAccount.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 21
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 6
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
PlatformChannel.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 14
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 7
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
PlatformChannelPost.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 21
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
PlatformInstance.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 7
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
Route.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 4
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
Setting.php
-
- 50.00% covered (danger) -
-
-
50.00%
5 / 10
-
- 37.50% covered (danger) -
-
-
37.50%
3 / 8
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
User.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 4
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- -
- - diff --git a/backend/coverage-report-progress/Modules/Lemmy/LemmyRequest.php.html b/backend/coverage-report-progress/Modules/Lemmy/LemmyRequest.php.html deleted file mode 100644 index 6364d579..00000000 --- a/backend/coverage-report-progress/Modules/Lemmy/LemmyRequest.php.html +++ /dev/null @@ -1,275 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Modules/Lemmy/LemmyRequest.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 14
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 4
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
LemmyRequest
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 14
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 4
42
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 __construct
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 get
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 5
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
6
 post
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 5
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
6
 withToken
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Modules\Lemmy;
4
5use Illuminate\Support\Facades\Http;
6use Illuminate\Http\Client\Response;
7
8class LemmyRequest
9{
10    private string $instance;
11    private ?string $token;
12
13    public function __construct(string $instance, ?string $token = null)
14    {
15        $this->instance = $instance;
16        $this->token = $token;
17    }
18
19    /**
20     * @param array<string, mixed> $params
21     */
22    public function get(string $endpoint, array $params = []): Response
23    {
24        $url = "https://{$this->instance}/api/v3/{$endpoint}";
25        
26        $request = Http::timeout(30);
27        
28        if ($this->token) {
29            $request = $request->withToken($this->token);
30        }
31        
32        return $request->get($url, $params);
33    }
34
35    /**
36     * @param array<string, mixed> $data
37     */
38    public function post(string $endpoint, array $data = []): Response
39    {
40        $url = "https://{$this->instance}/api/v3/{$endpoint}";
41        
42        $request = Http::timeout(30);
43        
44        if ($this->token) {
45            $request = $request->withToken($this->token);
46        }
47        
48        return $request->post($url, $data);
49    }
50
51    public function withToken(string $token): self
52    {
53        $this->token = $token;
54        return $this;
55    }
56}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:50:30 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-progress/Modules/Lemmy/Services/LemmyApiService.php.html b/backend/coverage-report-progress/Modules/Lemmy/Services/LemmyApiService.php.html deleted file mode 100644 index 5207938a..00000000 --- a/backend/coverage-report-progress/Modules/Lemmy/Services/LemmyApiService.php.html +++ /dev/null @@ -1,438 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Modules/Lemmy/Services/LemmyApiService.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 93
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 6
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
LemmyApiService
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 93
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 6
462
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 __construct
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 login
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 16
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
12
 getCommunityId
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 9
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
12
 syncChannelPosts
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 34
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
30
 createPost
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 19
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
42
 getLanguages
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 14
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
12
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Modules\Lemmy\Services;
4
5use App\Enums\PlatformEnum;
6use App\Models\PlatformChannelPost;
7use App\Modules\Lemmy\LemmyRequest;
8use Exception;
9
10class LemmyApiService
11{
12    private string $instance;
13
14    public function __construct(string $instance)
15    {
16        $this->instance = $instance;
17    }
18
19    public function login(string $username, string $password): ?string
20    {
21        try {
22            $request = new LemmyRequest($this->instance);
23            $response = $request->post('user/login', [
24                'username_or_email' => $username,
25                'password' => $password,
26            ]);
27
28            if (!$response->successful()) {
29                logger()->error('Lemmy login failed', [
30                    'status' => $response->status(),
31                    'body' => $response->body()
32                ]);
33                return null;
34            }
35
36            $data = $response->json();
37            return $data['jwt'] ?? null;
38        } catch (Exception $e) {
39            logger()->error('Lemmy login exception', ['error' => $e->getMessage()]);
40            return null;
41        }
42    }
43
44    public function getCommunityId(string $communityName, string $token): int
45    {
46        try {
47            $request = new LemmyRequest($this->instance, $token);
48            $response = $request->get('community', ['name' => $communityName]);
49
50            if (!$response->successful()) {
51                throw new Exception('Failed to fetch community: ' . $response->status());
52            }
53
54            $data = $response->json();
55            return $data['community_view']['community']['id'] ?? throw new Exception('Community not found');
56        } catch (Exception $e) {
57            logger()->error('Community lookup failed', ['error' => $e->getMessage()]);
58            throw $e;
59        }
60    }
61
62    public function syncChannelPosts(string $token, int $platformChannelId, string $communityName): void
63    {
64        try {
65            $request = new LemmyRequest($this->instance, $token);
66            $response = $request->get('post/list', [
67                'community_id' => $platformChannelId,
68                'limit' => 50,
69                'sort' => 'New'
70            ]);
71
72            if (!$response->successful()) {
73                logger()->warning('Failed to sync channel posts', [
74                    'status' => $response->status(),
75                    'platform_channel_id' => $platformChannelId
76                ]);
77                return;
78            }
79
80            $data = $response->json();
81            $posts = $data['posts'] ?? [];
82
83            foreach ($posts as $postData) {
84                $post = $postData['post'];
85
86                PlatformChannelPost::storePost(
87                    PlatformEnum::LEMMY,
88                    (string) $platformChannelId,
89                    $communityName,
90                    (string) $post['id'],
91                    $post['url'] ?? null,
92                    $post['name'] ?? null,
93                    isset($post['published']) ? new \DateTime($post['published']) : null
94                );
95            }
96
97            logger()->info('Synced channel posts', [
98                'platform_channel_id' => $platformChannelId,
99                'posts_count' => count($posts)
100            ]);
101
102        } catch (Exception $e) {
103            logger()->error('Exception while syncing channel posts', [
104                'error' => $e->getMessage(),
105                'platform_channel_id' => $platformChannelId
106            ]);
107        }
108    }
109
110    /**
111     * @return array<string, mixed>
112     */
113    public function createPost(string $token, string $title, string $body, int $platformChannelId, ?string $url = null, ?string $thumbnail = null, ?int $languageId = null): array
114    {
115        try {
116            $request = new LemmyRequest($this->instance, $token);
117
118            $postData = [
119                'name' => $title,
120                'body' => $body,
121                'community_id' => $platformChannelId,
122            ];
123
124            if ($url) {
125                $postData['url'] = $url;
126            }
127
128            if ($thumbnail) {
129                $postData['custom_thumbnail'] = $thumbnail;
130            }
131
132            if ($languageId) {
133                $postData['language_id'] = $languageId;
134            }
135
136            $response = $request->post('post', $postData);
137
138            if (!$response->successful()) {
139                throw new Exception('Failed to create post: ' . $response->status() . ' - ' . $response->body());
140            }
141
142            return $response->json();
143        } catch (Exception $e) {
144            logger()->error('Post creation failed', ['error' => $e->getMessage()]);
145            throw $e;
146        }
147    }
148
149    /**
150     * @return array<int, mixed>
151     */
152    public function getLanguages(): array
153    {
154        try {
155            $request = new LemmyRequest($this->instance);
156            $response = $request->get('site');
157
158            if (!$response->successful()) {
159                logger()->warning('Failed to fetch site languages', [
160                    'status' => $response->status()
161                ]);
162                return [];
163            }
164
165            $data = $response->json();
166            return $data['all_languages'] ?? [];
167        } catch (Exception $e) {
168            logger()->error('Exception while fetching languages', [
169                'error' => $e->getMessage()
170            ]);
171            return [];
172        }
173    }
174}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:50:30 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-progress/Modules/Lemmy/Services/LemmyPublisher.php.html b/backend/coverage-report-progress/Modules/Lemmy/Services/LemmyPublisher.php.html deleted file mode 100644 index 26a6395b..00000000 --- a/backend/coverage-report-progress/Modules/Lemmy/Services/LemmyPublisher.php.html +++ /dev/null @@ -1,223 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Modules/Lemmy/Services/LemmyPublisher.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 13
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
LemmyPublisher
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 13
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
6
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 __construct
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 publishToChannel
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 11
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Modules\Lemmy\Services;
4
5use App\Exceptions\PlatformAuthException;
6use App\Models\Article;
7use App\Models\PlatformAccount;
8use App\Models\PlatformChannel;
9use App\Services\Auth\LemmyAuthService;
10use Exception;
11
12class LemmyPublisher
13{
14    private LemmyApiService $api;
15    private PlatformAccount $account;
16
17    public function __construct(PlatformAccount $account)
18    {
19        $this->api = new LemmyApiService($account->instance_url);
20        $this->account = $account;
21    }
22
23    /**
24     * @param array<string, mixed> $extractedData
25     * @return array<string, mixed>
26     * @throws PlatformAuthException
27     * @throws Exception
28     */
29    public function publishToChannel(Article $article, array $extractedData, PlatformChannel $channel): array
30    {
31        $token = LemmyAuthService::getToken($this->account);
32
33        // Use the language ID from extracted data (should be set during validation)
34        $languageId = $extractedData['language_id'] ?? null;
35
36        return $this->api->createPost(
37            $token,
38            $extractedData['title'] ?? 'Untitled',
39            $extractedData['description'] ?? '',
40            $channel->channel_id,
41            $article->url,
42            $extractedData['thumbnail'] ?? null,
43            $languageId
44        );
45    }
46
47}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:50:30 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-progress/Modules/Lemmy/Services/dashboard.html b/backend/coverage-report-progress/Modules/Lemmy/Services/dashboard.html deleted file mode 100644 index aa610c19..00000000 --- a/backend/coverage-report-progress/Modules/Lemmy/Services/dashboard.html +++ /dev/null @@ -1,302 +0,0 @@ - - - - - Dashboard for /var/www/html/backend/app/Modules/Lemmy/Services - - - - - - - -
-
-
-
- -
-
-
-
-
-
-
-

Classes

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
-
-
-

Insufficient Coverage

- -
-
-

Project Risks

-
- - - - - - - - - - - -
ClassCRAP
App\Modules\Lemmy\Services\LemmyApiService462
-
-
-
-
-
-

Methods

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
-
-
-

Insufficient Coverage

-
- - - - - - - - - - - - - - - - - - -
MethodCoverage
__construct0%
login0%
getCommunityId0%
syncChannelPosts0%
createPost0%
getLanguages0%
__construct0%
publishToChannel0%
-
-
-
-

Project Risks

-
- - - - - - - - - - - - - - - -
MethodCRAP
createPost42
syncChannelPosts30
login12
getCommunityId12
getLanguages12
-
-
-
- -
- - - - - - diff --git a/backend/coverage-report-progress/Modules/Lemmy/Services/index.html b/backend/coverage-report-progress/Modules/Lemmy/Services/index.html deleted file mode 100644 index 76729809..00000000 --- a/backend/coverage-report-progress/Modules/Lemmy/Services/index.html +++ /dev/null @@ -1,149 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Modules/Lemmy/Services - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 106
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 8
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
LemmyApiService.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 93
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 6
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
LemmyPublisher.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 13
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- -
- - diff --git a/backend/coverage-report-progress/Modules/Lemmy/dashboard.html b/backend/coverage-report-progress/Modules/Lemmy/dashboard.html deleted file mode 100644 index 95153122..00000000 --- a/backend/coverage-report-progress/Modules/Lemmy/dashboard.html +++ /dev/null @@ -1,309 +0,0 @@ - - - - - Dashboard for /var/www/html/backend/app/Modules/Lemmy - - - - - - - -
-
-
-
- -
-
-
-
-
-
-
-

Classes

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
-
-
-

Insufficient Coverage

- -
-
-

Project Risks

- -
-
-
-
-

Methods

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
-
-
-

Insufficient Coverage

-
- - - - - - - - - - - - - - - - - - - - - - -
MethodCoverage
__construct0%
get0%
post0%
withToken0%
__construct0%
login0%
getCommunityId0%
syncChannelPosts0%
createPost0%
getLanguages0%
__construct0%
publishToChannel0%
-
-
-
-

Project Risks

-
- - - - - - - - - - - - - - - - - -
MethodCRAP
createPost42
syncChannelPosts30
login12
getCommunityId12
getLanguages12
get6
post6
-
-
-
- -
- - - - - - diff --git a/backend/coverage-report-progress/Modules/Lemmy/index.html b/backend/coverage-report-progress/Modules/Lemmy/index.html deleted file mode 100644 index 82b263b9..00000000 --- a/backend/coverage-report-progress/Modules/Lemmy/index.html +++ /dev/null @@ -1,148 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Modules/Lemmy - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 120
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 12
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
Services
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 106
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 8
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
LemmyRequest.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 14
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 4
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- -
- - diff --git a/backend/coverage-report-progress/Modules/dashboard.html b/backend/coverage-report-progress/Modules/dashboard.html deleted file mode 100644 index b9ebbab5..00000000 --- a/backend/coverage-report-progress/Modules/dashboard.html +++ /dev/null @@ -1,308 +0,0 @@ - - - - - Dashboard for /var/www/html/backend/app/Modules - - - - - - - -
-
-
-
- -
-
-
-
-
-
-
-

Classes

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
-
-
-

Insufficient Coverage

- -
-
-

Project Risks

- -
-
-
-
-

Methods

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
-
-
-

Insufficient Coverage

-
- - - - - - - - - - - - - - - - - - - - - - -
MethodCoverage
__construct0%
get0%
post0%
withToken0%
__construct0%
login0%
getCommunityId0%
syncChannelPosts0%
createPost0%
getLanguages0%
__construct0%
publishToChannel0%
-
-
-
-

Project Risks

-
- - - - - - - - - - - - - - - - - -
MethodCRAP
createPost42
syncChannelPosts30
login12
getCommunityId12
getLanguages12
get6
post6
-
-
-
- -
- - - - - - diff --git a/backend/coverage-report-progress/Modules/index.html b/backend/coverage-report-progress/Modules/index.html deleted file mode 100644 index af2108ce..00000000 --- a/backend/coverage-report-progress/Modules/index.html +++ /dev/null @@ -1,119 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Modules - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 120
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 12
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
Lemmy
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 120
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 12
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
-
- -
- - diff --git a/backend/coverage-report-progress/Providers/AppServiceProvider.php.html b/backend/coverage-report-progress/Providers/AppServiceProvider.php.html deleted file mode 100644 index c9515a87..00000000 --- a/backend/coverage-report-progress/Providers/AppServiceProvider.php.html +++ /dev/null @@ -1,260 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Providers/AppServiceProvider.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 82.76% covered (warning) -
-
-
82.76%
24 / 29
-
- 33.33% covered (danger) -
-
-
33.33%
1 / 3
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
AppServiceProvider
-
- 82.76% covered (warning) -
-
-
82.76%
24 / 29
-
- 33.33% covered (danger) -
-
-
33.33%
1 / 3
6.18
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 register
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
1
 boot
-
- 92.00% covered (success) -
-
-
92.00%
23 / 25
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
1.00
 mapExceptionToLogLevel
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
20
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Providers;
4
5use App\Events\ExceptionOccurred;
6use App\Listeners\LogExceptionToDatabase;
7use App\LogLevelEnum;
8use Error;
9use Illuminate\Contracts\Debug\ExceptionHandler;
10use Illuminate\Support\Facades\Event;
11use Illuminate\Support\ServiceProvider;
12use InvalidArgumentException;
13use Throwable;
14
15class AppServiceProvider extends ServiceProvider
16{
17    public function register(): void
18    {
19    }
20
21    public function boot(): void
22    {
23        Event::listen(
24            ExceptionOccurred::class,
25            LogExceptionToDatabase::class,
26        );
27
28        Event::listen(
29            \App\Events\NewArticleFetched::class,
30            \App\Listeners\ValidateArticleListener::class,
31        );
32
33        Event::listen(
34            \App\Events\ArticleApproved::class,
35            \App\Listeners\PublishApprovedArticle::class,
36        );
37
38        Event::listen(
39            \App\Events\ArticleReadyToPublish::class,
40            \App\Listeners\PublishArticle::class,
41        );
42
43        Event::listen(
44            \App\Events\ExceptionLogged::class,
45            \App\Listeners\LogExceptionToDatabase::class,
46        );
47
48        app()->make(ExceptionHandler::class)
49            ->reportable(function (Throwable $e) {
50                $level = $this->mapExceptionToLogLevel($e);
51
52                ExceptionOccurred::dispatch($e, $level, $e->getMessage(), []);
53            });
54    }
55
56    private function mapExceptionToLogLevel(Throwable $exception): LogLevelEnum
57    {
58        return match (true) {
59            $exception instanceof Error => LogLevelEnum::CRITICAL,
60            $exception instanceof InvalidArgumentException => LogLevelEnum::WARNING,
61            default => LogLevelEnum::ERROR,
62        };
63    }
64}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:50:30 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-progress/Providers/HorizonServiceProvider.php.html b/backend/coverage-report-progress/Providers/HorizonServiceProvider.php.html deleted file mode 100644 index c1f8a29e..00000000 --- a/backend/coverage-report-progress/Providers/HorizonServiceProvider.php.html +++ /dev/null @@ -1,208 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Providers/HorizonServiceProvider.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 75.00% covered (warning) -
-
-
75.00%
3 / 4
-
- 50.00% covered (danger) -
-
-
50.00%
1 / 2
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
HorizonServiceProvider
-
- 75.00% covered (warning) -
-
-
75.00%
3 / 4
-
- 50.00% covered (danger) -
-
-
50.00%
1 / 2
2.06
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 boot
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
1
 gate
-
- 66.67% covered (warning) -
-
-
66.67%
2 / 3
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
1.04
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Providers;
4
5use Illuminate\Support\Facades\Gate;
6use Laravel\Horizon\Horizon;
7use Laravel\Horizon\HorizonApplicationServiceProvider;
8
9class HorizonServiceProvider extends HorizonApplicationServiceProvider
10{
11    /**
12     * Bootstrap any application services.
13     */
14    public function boot(): void
15    {
16        parent::boot();
17
18        // Horizon::routeSmsNotificationsTo('15556667777');
19        // Horizon::routeMailNotificationsTo('example@example.com');
20        // Horizon::routeSlackNotificationsTo('slack-webhook-url', '#channel');
21    }
22
23    /**
24     * Register the Horizon gate.
25     *
26     * This gate determines who can access Horizon in non-local environments.
27     */
28    protected function gate(): void
29    {
30        Gate::define('viewHorizon', function ($user = null) {
31            return true;
32        });
33    }
34}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:50:30 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-progress/Providers/dashboard.html b/backend/coverage-report-progress/Providers/dashboard.html deleted file mode 100644 index 43324117..00000000 --- a/backend/coverage-report-progress/Providers/dashboard.html +++ /dev/null @@ -1,290 +0,0 @@ - - - - - Dashboard for /var/www/html/backend/app/Providers - - - - - - - -
-
-
-
- -
-
-
-
-
-
-
-

Classes

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
-
-
-

Insufficient Coverage

-
- - - - - - - - - - - - -
ClassCoverage
App\Providers\HorizonServiceProvider75%
App\Providers\AppServiceProvider82%
-
-
-
-

Project Risks

-
- - - - - - - - - - - -
ClassCRAP
App\Providers\AppServiceProvider6
-
-
-
-
-
-

Methods

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
-
-
-

Insufficient Coverage

-
- - - - - - - - - - - - -
MethodCoverage
mapExceptionToLogLevel0%
gate66%
-
-
-
-

Project Risks

-
- - - - - - - - - - - -
MethodCRAP
mapExceptionToLogLevel20
-
-
-
- -
- - - - - - diff --git a/backend/coverage-report-progress/Providers/index.html b/backend/coverage-report-progress/Providers/index.html deleted file mode 100644 index ec1fdd8a..00000000 --- a/backend/coverage-report-progress/Providers/index.html +++ /dev/null @@ -1,147 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Providers - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 81.82% covered (warning) -
-
-
81.82%
27 / 33
-
- 40.00% covered (danger) -
-
-
40.00%
2 / 5
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
AppServiceProvider.php
-
- 82.76% covered (warning) -
-
-
82.76%
24 / 29
-
- 33.33% covered (danger) -
-
-
33.33%
1 / 3
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
HorizonServiceProvider.php
-
- 75.00% covered (warning) -
-
-
75.00%
3 / 4
-
- 50.00% covered (danger) -
-
-
50.00%
1 / 2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- -
- - diff --git a/backend/coverage-report-progress/Services/Article/ArticleFetcher.php.html b/backend/coverage-report-progress/Services/Article/ArticleFetcher.php.html deleted file mode 100644 index 805fe1ce..00000000 --- a/backend/coverage-report-progress/Services/Article/ArticleFetcher.php.html +++ /dev/null @@ -1,354 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Services/Article/ArticleFetcher.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 44
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 5
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
ArticleFetcher
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 44
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 5
132
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 getArticlesFromFeed
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 9
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
12
 getArticlesFromRssFeed
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 getArticlesFromWebsiteFeed
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 18
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
12
 fetchArticleData
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 9
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
6
 saveArticle
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 7
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
6
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Services\Article;
4
5use App\Models\Article;
6use App\Models\Feed;
7use App\Services\Http\HttpFetcher;
8use App\Services\Factories\ArticleParserFactory;
9use App\Services\Factories\HomepageParserFactory;
10use App\Services\Log\LogSaver;
11use Exception;
12use Illuminate\Support\Collection;
13
14class ArticleFetcher
15{
16    /**
17     * @return Collection<int, Article>
18     */
19    public static function getArticlesFromFeed(Feed $feed): Collection
20    {
21        if ($feed->type === 'rss') {
22            return self::getArticlesFromRssFeed($feed);
23        } elseif ($feed->type === 'website') {
24            return self::getArticlesFromWebsiteFeed($feed);
25        }
26
27        LogSaver::warning("Unsupported feed type", null, [
28            'feed_id' => $feed->id,
29            'feed_type' => $feed->type
30        ]);
31
32        return collect();
33    }
34
35    /**
36     * @return Collection<int, Article>
37     */
38    private static function getArticlesFromRssFeed(Feed $feed): Collection
39    {
40        // TODO: Implement RSS feed parsing
41        // For now, return empty collection
42        return collect();
43    }
44
45    /**
46     * @return Collection<int, Article>
47     */
48    private static function getArticlesFromWebsiteFeed(Feed $feed): Collection
49    {
50        try {
51            // Try to get parser for this feed
52            $parser = HomepageParserFactory::getParserForFeed($feed);
53
54            if (! $parser) {
55                LogSaver::warning("No parser available for feed URL", null, [
56                    'feed_id' => $feed->id,
57                    'feed_url' => $feed->url
58                ]);
59
60                return collect();
61            }
62
63            $html = HttpFetcher::fetchHtml($feed->url);
64            $urls = $parser->extractArticleUrls($html);
65
66            return collect($urls)
67                ->map(fn (string $url) => self::saveArticle($url, $feed->id));
68
69        } catch (Exception $e) {
70            LogSaver::error("Failed to fetch articles from website feed", null, [
71                'feed_id' => $feed->id,
72                'feed_url' => $feed->url,
73                'error' => $e->getMessage()
74            ]);
75
76            return collect();
77        }
78    }
79
80    /**
81     * @return array<string, mixed>
82     */
83    public static function fetchArticleData(Article $article): array
84    {
85        try {
86            $html = HttpFetcher::fetchHtml($article->url);
87            $parser = ArticleParserFactory::getParser($article->url);
88
89            return $parser->extractData($html);
90        } catch (Exception $e) {
91            LogSaver::error('Exception while fetching article data', null, [
92                'url' => $article->url,
93                'error' => $e->getMessage()
94            ]);
95
96            return [];
97        }
98    }
99
100    private static function saveArticle(string $url, ?int $feedId = null): Article
101    {
102        $existingArticle = Article::where('url', $url)->first();
103
104        if ($existingArticle) {
105            return $existingArticle;
106        }
107
108        return Article::create([
109            'url' => $url,
110            'feed_id' => $feedId
111        ]);
112    }
113}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:50:30 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-progress/Services/Article/ValidationService.php.html b/backend/coverage-report-progress/Services/Article/ValidationService.php.html deleted file mode 100644 index f68f9c25..00000000 --- a/backend/coverage-report-progress/Services/Article/ValidationService.php.html +++ /dev/null @@ -1,228 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Services/Article/ValidationService.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 25
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
ValidationService
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 25
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
30
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 validate
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 18
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
6
 validateByKeywords
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 7
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
12
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Services\Article;
4
5use App\Models\Article;
6
7class ValidationService
8{
9    public static function validate(Article $article): Article
10    {
11        logger('Checking keywords for article: ' . $article->id);
12
13        $articleData = ArticleFetcher::fetchArticleData($article);
14        
15        if (!isset($articleData['full_article'])) {
16            logger()->warning('Article data missing full_article key', [
17                'article_id' => $article->id,
18                'url' => $article->url
19            ]);
20            
21            $article->update([
22                'is_valid' => false,
23                'validated_at' => now(),
24            ]);
25            
26            return $article->refresh();
27        }
28        
29        $validationResult = self::validateByKeywords($articleData['full_article']);
30
31        $article->update([
32            'is_valid' => $validationResult,
33            'validated_at' => now(),
34        ]);
35
36        return $article->refresh();
37    }
38
39    private static function validateByKeywords(string $full_article): bool
40    {
41        $keywords = [
42            'N-VA', 'Bart De Wever', 'Frank Vandenbroucke',
43        ];
44
45        foreach ($keywords as $keyword) {
46            if (stripos($full_article, $keyword) !== false) {
47                return true;
48            }
49        }
50
51        return false;
52    }
53}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:50:30 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-progress/Services/Article/dashboard.html b/backend/coverage-report-progress/Services/Article/dashboard.html deleted file mode 100644 index 00e8485d..00000000 --- a/backend/coverage-report-progress/Services/Article/dashboard.html +++ /dev/null @@ -1,302 +0,0 @@ - - - - - Dashboard for /var/www/html/backend/app/Services/Article - - - - - - - -
-
-
-
- -
-
-
-
-
-
-
-

Classes

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
-
-
-

Insufficient Coverage

- -
-
-

Project Risks

- -
-
-
-
-

Methods

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
-
-
-

Insufficient Coverage

- -
-
-

Project Risks

- -
-
- -
- - - - - - diff --git a/backend/coverage-report-progress/Services/Article/index.html b/backend/coverage-report-progress/Services/Article/index.html deleted file mode 100644 index fbd4a6bd..00000000 --- a/backend/coverage-report-progress/Services/Article/index.html +++ /dev/null @@ -1,148 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Services/Article - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 69
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 7
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
ArticleFetcher.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 44
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 5
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
ValidationService.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 25
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- -
- - diff --git a/backend/coverage-report-progress/Services/Auth/LemmyAuthService.php.html b/backend/coverage-report-progress/Services/Auth/LemmyAuthService.php.html deleted file mode 100644 index d3283763..00000000 --- a/backend/coverage-report-progress/Services/Auth/LemmyAuthService.php.html +++ /dev/null @@ -1,194 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Services/Auth/LemmyAuthService.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 12
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
LemmyAuthService
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 12
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
42
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 getToken
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 12
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
42
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Services\Auth;
4
5use App\Enums\PlatformEnum;
6use App\Exceptions\PlatformAuthException;
7use App\Models\PlatformAccount;
8use App\Modules\Lemmy\Services\LemmyApiService;
9use Illuminate\Support\Facades\Cache;
10
11class LemmyAuthService
12{
13    /**
14     * @throws PlatformAuthException
15     */
16    public static function getToken(PlatformAccount $account): string
17    {
18        $cacheKey = "lemmy_jwt_token_$account->id";
19        $cachedToken = Cache::get($cacheKey);
20
21        if ($cachedToken) {
22            return $cachedToken;
23        }
24
25        if (! $account->username || ! $account->password || ! $account->instance_url) {
26            throw new PlatformAuthException(PlatformEnum::LEMMY, 'Missing credentials for account: ' . $account->username);
27        }
28
29        $api = new LemmyApiService($account->instance_url);
30        $token = $api->login($account->username, $account->password);
31
32        if (!$token) {
33            throw new PlatformAuthException(PlatformEnum::LEMMY, 'Login failed for account: ' . $account->username);
34        }
35
36        // Cache for 50 minutes (3000 seconds) to allow buffer before token expires
37        Cache::put($cacheKey, $token, 3000);
38
39        return $token;
40    }
41}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:50:30 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-progress/Services/Auth/dashboard.html b/backend/coverage-report-progress/Services/Auth/dashboard.html deleted file mode 100644 index eb7573d8..00000000 --- a/backend/coverage-report-progress/Services/Auth/dashboard.html +++ /dev/null @@ -1,289 +0,0 @@ - - - - - Dashboard for /var/www/html/backend/app/Services/Auth - - - - - - - -
-
-
-
- -
-
-
-
-
-
-
-

Classes

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
-
-
-

Insufficient Coverage

-
- - - - - - - - - - - -
ClassCoverage
App\Services\Auth\LemmyAuthService0%
-
-
-
-

Project Risks

-
- - - - - - - - - - - -
ClassCRAP
App\Services\Auth\LemmyAuthService42
-
-
-
-
-
-

Methods

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
-
-
-

Insufficient Coverage

-
- - - - - - - - - - - -
MethodCoverage
getToken0%
-
-
-
-

Project Risks

-
- - - - - - - - - - - -
MethodCRAP
getToken42
-
-
-
- -
- - - - - - diff --git a/backend/coverage-report-progress/Services/Auth/index.html b/backend/coverage-report-progress/Services/Auth/index.html deleted file mode 100644 index de0ab776..00000000 --- a/backend/coverage-report-progress/Services/Auth/index.html +++ /dev/null @@ -1,120 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Services/Auth - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 12
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
LemmyAuthService.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 12
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- -
- - diff --git a/backend/coverage-report-progress/Services/DashboardStatsService.php.html b/backend/coverage-report-progress/Services/DashboardStatsService.php.html deleted file mode 100644 index 16615f45..00000000 --- a/backend/coverage-report-progress/Services/DashboardStatsService.php.html +++ /dev/null @@ -1,306 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Services/DashboardStatsService.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 100.00% covered (success) -
-
-
100.00%
40 / 40
-
- 100.00% covered (success) -
-
-
100.00%
4 / 4
CRAP
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
DashboardStatsService
-
- 100.00% covered (success) -
-
-
100.00%
40 / 40
-
- 100.00% covered (success) -
-
-
100.00%
4 / 4
13
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
 getStats
-
- 100.00% covered (success) -
-
-
100.00%
16 / 16
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
4
 getAvailablePeriods
-
- 100.00% covered (success) -
-
-
100.00%
7 / 7
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
1
 getDateRange
-
- 100.00% covered (success) -
-
-
100.00%
9 / 9
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
7
 getSystemStats
-
- 100.00% covered (success) -
-
-
100.00%
8 / 8
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
1
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Services;
4
5use App\Models\Article;
6use App\Models\ArticlePublication;
7use Carbon\Carbon;
8
9class DashboardStatsService
10{
11    /**
12     * @return array
13     */
14    public function getStats(string $period = 'today'): array
15    {
16        $dateRange = $this->getDateRange($period);
17        
18        // Get articles fetched for the period
19        $articlesFetchedQuery = Article::query();
20        if ($dateRange) {
21            $articlesFetchedQuery->whereBetween('created_at', $dateRange);
22        }
23        $articlesFetched = $articlesFetchedQuery->count();
24
25        // Get articles published for the period
26        $articlesPublishedQuery = ArticlePublication::query()
27            ->whereNotNull('published_at');
28        if ($dateRange) {
29            $articlesPublishedQuery->whereBetween('published_at', $dateRange);
30        }
31        $articlesPublished = $articlesPublishedQuery->count();
32
33        // Calculate published percentage
34        $publishedPercentage = $articlesFetched > 0 ? round(($articlesPublished / $articlesFetched) * 100, 1) : 0.0;
35
36        return [
37            'articles_fetched' => $articlesFetched,
38            'articles_published' => $articlesPublished,
39            'published_percentage' => $publishedPercentage,
40        ];
41    }
42
43    /**
44     * @return array<string, string>
45     */
46    public function getAvailablePeriods(): array
47    {
48        return [
49            'today' => 'Today',
50            'week' => 'This Week',
51            'month' => 'This Month',
52            'year' => 'This Year',
53            'all' => 'All Time',
54        ];
55    }
56
57    /**
58     * @return array{0: Carbon, 1: Carbon}|null
59     */
60    private function getDateRange(string $period): ?array
61    {
62        $now = Carbon::now();
63        
64        return match ($period) {
65            'today' => [$now->copy()->startOfDay(), $now->copy()->endOfDay()],
66            'week' => [$now->copy()->startOfWeek(), $now->copy()->endOfWeek()],
67            'month' => [$now->copy()->startOfMonth(), $now->copy()->endOfMonth()],
68            'year' => [$now->copy()->startOfYear(), $now->copy()->endOfYear()],
69            'all' => null, // No date filtering for all-time stats
70            default => [$now->copy()->startOfDay(), $now->copy()->endOfDay()],
71        };
72    }
73
74    /**
75     * Get additional stats for dashboard
76     */
77    public function getSystemStats(): array
78    {
79        return [
80            'total_feeds' => \App\Models\Feed::count(),
81            'active_feeds' => \App\Models\Feed::where('is_active', true)->count(),
82            'total_channels' => \App\Models\PlatformChannel::count(),
83            'active_channels' => \App\Models\PlatformChannel::where('is_active', true)->count(),
84            'total_routes' => \App\Models\Route::count(),
85            'active_routes' => \App\Models\Route::where('is_active', true)->count(),
86        ];
87    }
88}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:50:30 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-progress/Services/Factories/ArticleParserFactory.php.html b/backend/coverage-report-progress/Services/Factories/ArticleParserFactory.php.html deleted file mode 100644 index e93e5b43..00000000 --- a/backend/coverage-report-progress/Services/Factories/ArticleParserFactory.php.html +++ /dev/null @@ -1,250 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Services/Factories/ArticleParserFactory.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 11
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
ArticleParserFactory
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 11
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
42
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 getParser
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 5
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
12
 getSupportedSources
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 4
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 registerParser
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
6
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Services\Factories;
4
5use App\Contracts\ArticleParserInterface;
6use App\Services\Parsers\VrtArticleParser;
7use App\Services\Parsers\BelgaArticleParser;
8use Exception;
9
10class ArticleParserFactory
11{
12    /**
13     * @var array<int, class-string<ArticleParserInterface>>
14     */
15    private static array $parsers = [
16        VrtArticleParser::class,
17        BelgaArticleParser::class,
18    ];
19
20    public static function getParser(string $url): ArticleParserInterface
21    {
22        foreach (self::$parsers as $parserClass) {
23            $parser = new $parserClass();
24            
25            if ($parser->canParse($url)) {
26                return $parser;
27            }
28        }
29
30        throw new Exception("No parser found for URL: {$url}");
31    }
32
33    /**
34     * @return array<int, string>
35     */
36    public static function getSupportedSources(): array
37    {
38        return array_map(function($parserClass) {
39            $parser = new $parserClass();
40            return $parser->getSourceName();
41        }, self::$parsers);
42    }
43
44    /**
45     * @param class-string<ArticleParserInterface> $parserClass
46     */
47    public static function registerParser(string $parserClass): void
48    {
49        if (!in_array($parserClass, self::$parsers)) {
50            self::$parsers[] = $parserClass;
51        }
52    }
53}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:50:30 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-progress/Services/Factories/HomepageParserFactory.php.html b/backend/coverage-report-progress/Services/Factories/HomepageParserFactory.php.html deleted file mode 100644 index c3363af4..00000000 --- a/backend/coverage-report-progress/Services/Factories/HomepageParserFactory.php.html +++ /dev/null @@ -1,220 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Services/Factories/HomepageParserFactory.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 8
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
HomepageParserFactory
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 8
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
30
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 getParser
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 5
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
12
 getParserForFeed
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
6
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Services\Factories;
4
5use App\Contracts\HomepageParserInterface;
6use App\Models\Feed;
7use App\Services\Parsers\VrtHomepageParserAdapter;
8use App\Services\Parsers\BelgaHomepageParserAdapter;
9use Exception;
10
11class HomepageParserFactory
12{
13    /**
14     * @var array<int, class-string<HomepageParserInterface>>
15     */
16    private static array $parsers = [
17        VrtHomepageParserAdapter::class,
18        BelgaHomepageParserAdapter::class,
19    ];
20
21    /**
22     * @throws Exception
23     */
24    public static function getParser(string $url): HomepageParserInterface
25    {
26        foreach (self::$parsers as $parserClass) {
27            $parser = new $parserClass();
28
29            if ($parser->canParse($url)) {
30                return $parser;
31            }
32        }
33
34        throw new Exception("No homepage parser found for URL: {$url}");
35    }
36
37    public static function getParserForFeed(Feed $feed): ?HomepageParserInterface
38    {
39        try {
40            return self::getParser($feed->url);
41        } catch (Exception) {
42            return null;
43        }
44    }
45}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:50:30 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-progress/Services/Factories/dashboard.html b/backend/coverage-report-progress/Services/Factories/dashboard.html deleted file mode 100644 index 6ebd5628..00000000 --- a/backend/coverage-report-progress/Services/Factories/dashboard.html +++ /dev/null @@ -1,298 +0,0 @@ - - - - - Dashboard for /var/www/html/backend/app/Services/Factories - - - - - - - -
-
-
-
- -
-
-
-
-
-
-
-

Classes

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
-
-
-

Insufficient Coverage

- -
-
-

Project Risks

- -
-
-
-
-

Methods

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
-
-
-

Insufficient Coverage

-
- - - - - - - - - - - - - - - -
MethodCoverage
getParser0%
getSupportedSources0%
registerParser0%
getParser0%
getParserForFeed0%
-
-
-
-

Project Risks

-
- - - - - - - - - - - - - - -
MethodCRAP
getParser12
getParser12
registerParser6
getParserForFeed6
-
-
-
- -
- - - - - - diff --git a/backend/coverage-report-progress/Services/Factories/index.html b/backend/coverage-report-progress/Services/Factories/index.html deleted file mode 100644 index 41ce643e..00000000 --- a/backend/coverage-report-progress/Services/Factories/index.html +++ /dev/null @@ -1,148 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Services/Factories - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 19
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 5
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
ArticleParserFactory.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 11
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
HomepageParserFactory.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 8
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- -
- - diff --git a/backend/coverage-report-progress/Services/Http/HttpFetcher.php.html b/backend/coverage-report-progress/Services/Http/HttpFetcher.php.html deleted file mode 100644 index 356a5999..00000000 --- a/backend/coverage-report-progress/Services/Http/HttpFetcher.php.html +++ /dev/null @@ -1,256 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Services/Http/HttpFetcher.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 44
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
HttpFetcher
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 44
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
90
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 fetchHtml
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 10
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
12
 fetchMultipleUrls
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 34
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
42
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Services\Http;
4
5use Illuminate\Support\Facades\Http;
6use Exception;
7
8class HttpFetcher
9{
10    public static function fetchHtml(string $url): string
11    {
12        try {
13            $response = Http::get($url);
14            
15            if (!$response->successful()) {
16                throw new Exception("Failed to fetch URL: {$url} - Status: {$response->status()}");
17            }
18            
19            return $response->body();
20        } catch (Exception $e) {
21            logger()->error('HTTP fetch failed', [
22                'url' => $url,
23                'error' => $e->getMessage()
24            ]);
25            throw $e;
26        }
27    }
28
29    /**
30     * @param array<int, string> $urls
31     * @return array<int, array<string, mixed>>
32     */
33    public static function fetchMultipleUrls(array $urls): array
34    {
35        try {
36            $responses = Http::pool(function ($pool) use ($urls) {
37                foreach ($urls as $url) {
38                    $pool->get($url);
39                }
40            });
41
42            return collect($responses)
43                ->map(function ($response, $index) use ($urls) {
44                    if (!isset($urls[$index])) {
45                        return null;
46                    }
47                    
48                    $url = $urls[$index];
49                    
50                    try {
51                        if ($response->successful()) {
52                            return [
53                                'url' => $url,
54                                'html' => $response->body(),
55                                'success' => true
56                            ];
57                        } else {
58                            return [
59                                'url' => $url,
60                                'html' => null,
61                                'success' => false,
62                                'status' => $response->status()
63                            ];
64                        }
65                    } catch (Exception) {
66                        return [
67                            'url' => $url,
68                            'html' => null,
69                            'success' => false,
70                            'error' => 'Exception occurred'
71                        ];
72                    }
73                })
74                ->filter(fn($result) => $result !== null)
75                ->toArray();
76        } catch (Exception $e) {
77            logger()->error('Multiple URL fetch failed', ['error' => $e->getMessage()]);
78            return [];
79        }
80    }
81}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:50:30 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-progress/Services/Http/dashboard.html b/backend/coverage-report-progress/Services/Http/dashboard.html deleted file mode 100644 index 9a3d44e6..00000000 --- a/backend/coverage-report-progress/Services/Http/dashboard.html +++ /dev/null @@ -1,291 +0,0 @@ - - - - - Dashboard for /var/www/html/backend/app/Services/Http - - - - - - - -
-
-
-
- -
-
-
-
-
-
-
-

Classes

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
-
-
-

Insufficient Coverage

-
- - - - - - - - - - - -
ClassCoverage
App\Services\Http\HttpFetcher0%
-
-
-
-

Project Risks

-
- - - - - - - - - - - -
ClassCRAP
App\Services\Http\HttpFetcher90
-
-
-
-
-
-

Methods

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
-
-
-

Insufficient Coverage

-
- - - - - - - - - - - - -
MethodCoverage
fetchHtml0%
fetchMultipleUrls0%
-
-
-
-

Project Risks

-
- - - - - - - - - - - - -
MethodCRAP
fetchMultipleUrls42
fetchHtml12
-
-
-
- -
- - - - - - diff --git a/backend/coverage-report-progress/Services/Http/index.html b/backend/coverage-report-progress/Services/Http/index.html deleted file mode 100644 index 15e30495..00000000 --- a/backend/coverage-report-progress/Services/Http/index.html +++ /dev/null @@ -1,120 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Services/Http - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 44
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
HttpFetcher.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 44
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- -
- - diff --git a/backend/coverage-report-progress/Services/Log/LogSaver.php.html b/backend/coverage-report-progress/Services/Log/LogSaver.php.html deleted file mode 100644 index 55211f24..00000000 --- a/backend/coverage-report-progress/Services/Log/LogSaver.php.html +++ /dev/null @@ -1,306 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Services/Log/LogSaver.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 17
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 5
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
LogSaver
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 17
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 5
42
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 info
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 error
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 warning
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 debug
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 log
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 13
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
6
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Services\Log;
4
5use App\LogLevelEnum;
6use App\Models\Log;
7use App\Models\PlatformChannel;
8
9class LogSaver
10{
11    /**
12     * @param array<string, mixed> $context
13     */
14    public static function info(string $message, ?PlatformChannel $channel = null, array $context = []): void
15    {
16        self::log(LogLevelEnum::INFO, $message, $channel, $context);
17    }
18
19    /**
20     * @param array<string, mixed> $context
21     */
22    public static function error(string $message, ?PlatformChannel $channel = null, array $context = []): void
23    {
24        self::log(LogLevelEnum::ERROR, $message, $channel, $context);
25    }
26
27    /**
28     * @param array<string, mixed> $context
29     */
30    public static function warning(string $message, ?PlatformChannel $channel = null, array $context = []): void
31    {
32        self::log(LogLevelEnum::WARNING, $message, $channel, $context);
33    }
34
35    /**
36     * @param array<string, mixed> $context
37     */
38    public static function debug(string $message, ?PlatformChannel $channel = null, array $context = []): void
39    {
40        self::log(LogLevelEnum::DEBUG, $message, $channel, $context);
41    }
42
43    /**
44     * @param array<string, mixed> $context
45     */
46    private static function log(LogLevelEnum $level, string $message, ?PlatformChannel $channel = null, array $context = []): void
47    {
48        $logContext = $context;
49
50        if ($channel) {
51            $logContext = array_merge($logContext, [
52                'channel_id' => $channel->id,
53                'channel_name' => $channel->name,
54                'platform' => $channel->platformInstance->platform->value,
55                'instance_url' => $channel->platformInstance->url,
56            ]);
57        }
58
59        Log::create([
60            'level' => $level,
61            'message' => $message,
62            'context' => $logContext,
63        ]);
64    }
65}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:50:30 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-progress/Services/Log/dashboard.html b/backend/coverage-report-progress/Services/Log/dashboard.html deleted file mode 100644 index 6e45d349..00000000 --- a/backend/coverage-report-progress/Services/Log/dashboard.html +++ /dev/null @@ -1,293 +0,0 @@ - - - - - Dashboard for /var/www/html/backend/app/Services/Log - - - - - - - -
-
-
-
- -
-
-
-
-
-
-
-

Classes

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
-
-
-

Insufficient Coverage

-
- - - - - - - - - - - -
ClassCoverage
App\Services\Log\LogSaver0%
-
-
-
-

Project Risks

-
- - - - - - - - - - - -
ClassCRAP
App\Services\Log\LogSaver42
-
-
-
-
-
-

Methods

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
-
-
-

Insufficient Coverage

-
- - - - - - - - - - - - - - - -
MethodCoverage
info0%
error0%
warning0%
debug0%
log0%
-
-
-
-

Project Risks

-
- - - - - - - - - - - -
MethodCRAP
log6
-
-
-
- -
- - - - - - diff --git a/backend/coverage-report-progress/Services/Log/index.html b/backend/coverage-report-progress/Services/Log/index.html deleted file mode 100644 index b1a9aaba..00000000 --- a/backend/coverage-report-progress/Services/Log/index.html +++ /dev/null @@ -1,120 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Services/Log - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 17
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 5
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
LogSaver.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 17
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 5
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- -
- - diff --git a/backend/coverage-report-progress/Services/OnboardingRedirectService.php.html b/backend/coverage-report-progress/Services/OnboardingRedirectService.php.html deleted file mode 100644 index 66397e5e..00000000 --- a/backend/coverage-report-progress/Services/OnboardingRedirectService.php.html +++ /dev/null @@ -1,172 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Services/OnboardingRedirectService.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 4
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
OnboardingRedirectService
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 4
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
6
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 handleRedirect
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 4
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
6
-
- - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Services;
4
5use Illuminate\Http\RedirectResponse;
6use Illuminate\Http\Request;
7
8class OnboardingRedirectService
9{
10    public static function handleRedirect(Request $request, string $defaultRoute, string $successMessage): RedirectResponse
11    {
12        $redirectTo = $request->input('redirect_to');
13        
14        if ($redirectTo) {
15            return redirect($redirectTo)->with('success', $successMessage);
16        }
17
18        return redirect()->route($defaultRoute)->with('success', $successMessage);
19    }
20}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:50:30 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-progress/Services/Parsers/BelgaArticlePageParser.php.html b/backend/coverage-report-progress/Services/Parsers/BelgaArticlePageParser.php.html deleted file mode 100644 index 8bc94869..00000000 --- a/backend/coverage-report-progress/Services/Parsers/BelgaArticlePageParser.php.html +++ /dev/null @@ -1,351 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Services/Parsers/BelgaArticlePageParser.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 42
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 5
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
BelgaArticlePageParser
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 42
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 5
306
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 extractTitle
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 9
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
30
 extractDescription
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 7
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
20
 extractFullArticle
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 15
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
20
 extractThumbnail
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 5
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
12
 extractData
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 6
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Services\Parsers;
4
5class BelgaArticlePageParser
6{
7    public static function extractTitle(string $html): ?string
8    {
9        // Try h1 with Belga-specific class first
10        if (preg_match('/<h1[^>]*class="[^"]*prezly-slate-heading--heading-1[^"]*"[^>]*>([^<]+)<\/h1>/i', $html, $matches)) {
11            return html_entity_decode(strip_tags($matches[1]), ENT_QUOTES, 'UTF-8');
12        }
13        
14        // Try meta title
15        if (preg_match('/<meta property="og:title" content="([^"]+)"/i', $html, $matches)) {
16            return html_entity_decode($matches[1], ENT_QUOTES, 'UTF-8');
17        }
18        
19        // Try any h1 tag
20        if (preg_match('/<h1[^>]*>([^<]+)<\/h1>/i', $html, $matches)) {
21            return html_entity_decode(strip_tags($matches[1]), ENT_QUOTES, 'UTF-8');
22        }
23        
24        // Try title tag
25        if (preg_match('/<title>([^<]+)<\/title>/i', $html, $matches)) {
26            return html_entity_decode($matches[1], ENT_QUOTES, 'UTF-8');
27        }
28        
29        return null;
30    }
31    
32    public static function extractDescription(string $html): ?string
33    {
34        // Try meta description first
35        if (preg_match('/<meta property="og:description" content="([^"]+)"/i', $html, $matches)) {
36            return html_entity_decode($matches[1], ENT_QUOTES, 'UTF-8');
37        }
38        
39        // Try Belga-specific paragraph class
40        if (preg_match('/<p[^>]*class="[^"]*styles_paragraph__[^"]*"[^>]*>([^<]+(?:<[^\/](?!p)[^>]*>[^<]*<\/[^>]*>[^<]*)*)<\/p>/i', $html, $matches)) {
41            return html_entity_decode(strip_tags($matches[1]), ENT_QUOTES, 'UTF-8');
42        }
43        
44        // Try to find first paragraph in article content
45        if (preg_match('/<p[^>]*>([^<]+(?:<[^\/](?!p)[^>]*>[^<]*<\/[^>]*>[^<]*)*)<\/p>/i', $html, $matches)) {
46            return html_entity_decode(strip_tags($matches[1]), ENT_QUOTES, 'UTF-8');
47        }
48        
49        return null;
50    }
51    
52    public static function extractFullArticle(string $html): ?string
53    {
54        // Remove scripts, styles, and other non-content elements
55        $cleanHtml = preg_replace('/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/mi', '', $html);
56        $cleanHtml = preg_replace('/<style\b[^<]*(?:(?!<\/style>)<[^<]*)*<\/style>/mi', '', $cleanHtml);
57        
58        // Try to extract content from Belga-specific document section
59        if (preg_match('/<section[^>]*class="[^"]*prezly-slate-document[^"]*"[^>]*>(.*?)<\/section>/is', $cleanHtml, $sectionMatches)) {
60            $sectionHtml = $sectionMatches[1];
61            preg_match_all('/<p[^>]*>(.*?)<\/p>/is', $sectionHtml, $matches);
62        } else {
63            // Fallback: Extract all paragraph content
64            preg_match_all('/<p[^>]*>(.*?)<\/p>/is', $cleanHtml, $matches);
65        }
66        
67        if (!empty($matches[1])) {
68            $paragraphs = array_map(function($paragraph) {
69                return html_entity_decode(strip_tags($paragraph), ENT_QUOTES, 'UTF-8');
70            }, $matches[1]);
71            
72            // Filter out empty paragraphs and join with double newlines
73            $fullText = implode("\n\n", array_filter($paragraphs, function($p) {
74                return trim($p) !== '';
75            }));
76            
77            return $fullText ?: null;
78        }
79        
80        return null;
81    }
82    
83    public static function extractThumbnail(string $html): ?string
84    {
85        // Try OpenGraph image first
86        if (preg_match('/<meta property="og:image" content="([^"]+)"/i', $html, $matches)) {
87            return $matches[1];
88        }
89        
90        // Try first image in article content
91        if (preg_match('/<img[^>]+src="([^"]+)"/i', $html, $matches)) {
92            return $matches[1];
93        }
94        
95        return null;
96    }
97
98    /**
99     * @return array<string, string|null>
100     */
101    public static function extractData(string $html): array
102    {
103        return [
104            'title' => self::extractTitle($html),
105            'description' => self::extractDescription($html),
106            'full_article' => self::extractFullArticle($html),
107            'thumbnail' => self::extractThumbnail($html),
108        ];
109    }
110}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:50:30 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-progress/Services/Parsers/BelgaArticleParser.php.html b/backend/coverage-report-progress/Services/Parsers/BelgaArticleParser.php.html deleted file mode 100644 index 9f11ec02..00000000 --- a/backend/coverage-report-progress/Services/Parsers/BelgaArticleParser.php.html +++ /dev/null @@ -1,220 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Services/Parsers/BelgaArticleParser.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
BelgaArticleParser
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
12
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 canParse
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 extractData
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 getSourceName
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Services\Parsers;
4
5use App\Contracts\ArticleParserInterface;
6
7class BelgaArticleParser implements ArticleParserInterface
8{
9    public function canParse(string $url): bool
10    {
11        return str_contains($url, 'belganewsagency.eu');
12    }
13
14    public function extractData(string $html): array
15    {
16        return BelgaArticlePageParser::extractData($html);
17    }
18
19    public function getSourceName(): string
20    {
21        return 'Belga News Agency';
22    }
23}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:50:30 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-progress/Services/Parsers/BelgaHomepageParser.php.html b/backend/coverage-report-progress/Services/Parsers/BelgaHomepageParser.php.html deleted file mode 100644 index c0886484..00000000 --- a/backend/coverage-report-progress/Services/Parsers/BelgaHomepageParser.php.html +++ /dev/null @@ -1,173 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Services/Parsers/BelgaHomepageParser.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 5
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
BelgaHomepageParser
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 5
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 extractArticleUrls
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 5
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Services\Parsers;
4
5class BelgaHomepageParser
6{
7    /**
8     * @return array<int, string>
9     */
10    public static function extractArticleUrls(string $html): array
11    {
12        preg_match_all('/href="(https:\/\/www\.belganewsagency\.eu\/[a-z0-9-]+)"/', $html, $matches);
13
14        $urls = collect($matches[1])
15            ->unique()
16            ->toArray();
17
18        return $urls;
19    }
20}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:50:30 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-progress/Services/Parsers/BelgaHomepageParserAdapter.php.html b/backend/coverage-report-progress/Services/Parsers/BelgaHomepageParserAdapter.php.html deleted file mode 100644 index a73eab9e..00000000 --- a/backend/coverage-report-progress/Services/Parsers/BelgaHomepageParserAdapter.php.html +++ /dev/null @@ -1,247 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Services/Parsers/BelgaHomepageParserAdapter.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 4
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 4
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
BelgaHomepageParserAdapter
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 4
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 4
20
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 canParse
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 extractArticleUrls
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 getHomepageUrl
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 getSourceName
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Services\Parsers;
4
5use App\Contracts\HomepageParserInterface;
6
7class BelgaHomepageParserAdapter implements HomepageParserInterface
8{
9    public function canParse(string $url): bool
10    {
11        return str_contains($url, 'belganewsagency.eu');
12    }
13
14    public function extractArticleUrls(string $html): array
15    {
16        return BelgaHomepageParser::extractArticleUrls($html);
17    }
18
19    public function getHomepageUrl(): string
20    {
21        return 'https://www.belganewsagency.eu/';
22    }
23
24    public function getSourceName(): string
25    {
26        return 'Belga News Agency';
27    }
28}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:50:30 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-progress/Services/Parsers/VrtArticlePageParser.php.html b/backend/coverage-report-progress/Services/Parsers/VrtArticlePageParser.php.html deleted file mode 100644 index 5c3cf12e..00000000 --- a/backend/coverage-report-progress/Services/Parsers/VrtArticlePageParser.php.html +++ /dev/null @@ -1,333 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Services/Parsers/VrtArticlePageParser.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 35
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 5
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
VrtArticlePageParser
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 35
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 5
210
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 extractTitle
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 7
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
20
 extractDescription
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 5
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
12
 extractFullArticle
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 12
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
12
 extractThumbnail
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 5
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
12
 extractData
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 6
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Services\Parsers;
4
5class VrtArticlePageParser
6{
7    public static function extractTitle(string $html): ?string
8    {
9        // Try meta title first
10        if (preg_match('/<meta property="og:title" content="([^"]+)"/i', $html, $matches)) {
11            return html_entity_decode($matches[1], ENT_QUOTES, 'UTF-8');
12        }
13
14        // Try h1 tag
15        if (preg_match('/<h1[^>]*>([^<]+)<\/h1>/i', $html, $matches)) {
16            return html_entity_decode(strip_tags($matches[1]), ENT_QUOTES, 'UTF-8');
17        }
18
19        // Try title tag
20        if (preg_match('/<title>([^<]+)<\/title>/i', $html, $matches)) {
21            return html_entity_decode($matches[1], ENT_QUOTES, 'UTF-8');
22        }
23
24        return null;
25    }
26
27    public static function extractDescription(string $html): ?string
28    {
29        // Try meta description first
30        if (preg_match('/<meta property="og:description" content="([^"]+)"/i', $html, $matches)) {
31            return html_entity_decode($matches[1], ENT_QUOTES, 'UTF-8');
32        }
33
34        // Try to find first paragraph in article content
35        if (preg_match('/<p[^>]*>([^<]+(?:<[^\/](?!p)[^>]*>[^<]*<\/[^>]*>[^<]*)*)<\/p>/i', $html, $matches)) {
36            return html_entity_decode(strip_tags($matches[1]), ENT_QUOTES, 'UTF-8');
37        }
38
39        return null;
40    }
41
42    public static function extractFullArticle(string $html): ?string
43    {
44        // Remove scripts, styles, and other non-content elements
45        $cleanHtml = preg_replace('/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/mi', '', $html);
46        $cleanHtml = preg_replace('/<style\b[^<]*(?:(?!<\/style>)<[^<]*)*<\/style>/mi', '', $cleanHtml);
47
48        // Extract all paragraph content
49        preg_match_all('/<p[^>]*>(.*?)<\/p>/is', $cleanHtml, $matches);
50
51        if (!empty($matches[1])) {
52            $paragraphs = array_map(function($paragraph) {
53                return html_entity_decode(strip_tags($paragraph), ENT_QUOTES, 'UTF-8');
54            }, $matches[1]);
55
56            // Filter out empty paragraphs and join with double newlines
57            $fullText = implode("\n\n", array_filter($paragraphs, function($p) {
58                return trim($p) !== '';
59            }));
60
61            return $fullText ?: null;
62        }
63
64        return null;
65    }
66
67    public static function extractThumbnail(string $html): ?string
68    {
69        if (preg_match('/<meta property="og:image" content="([^"]+)"/i', $html, $matches)) {
70            return $matches[1];
71        }
72
73        if (preg_match('/<img[^>]+src="([^"]+)"/i', $html, $matches)) {
74            return $matches[1];
75        }
76
77        return null;
78    }
79
80    /**
81     * @return array<string, string|null>
82     */
83    public static function extractData(string $html): array
84    {
85        return [
86            'title' => self::extractTitle($html),
87            'description' => self::extractDescription($html),
88            'full_article' => self::extractFullArticle($html),
89            'thumbnail' => self::extractThumbnail($html),
90        ];
91    }
92}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:50:30 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-progress/Services/Parsers/VrtArticleParser.php.html b/backend/coverage-report-progress/Services/Parsers/VrtArticleParser.php.html deleted file mode 100644 index 0e98f0e8..00000000 --- a/backend/coverage-report-progress/Services/Parsers/VrtArticleParser.php.html +++ /dev/null @@ -1,220 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Services/Parsers/VrtArticleParser.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
VrtArticleParser
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
12
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 canParse
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 extractData
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 getSourceName
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Services\Parsers;
4
5use App\Contracts\ArticleParserInterface;
6
7class VrtArticleParser implements ArticleParserInterface
8{
9    public function canParse(string $url): bool
10    {
11        return str_contains($url, 'vrt.be');
12    }
13
14    public function extractData(string $html): array
15    {
16        return VrtArticlePageParser::extractData($html);
17    }
18
19    public function getSourceName(): string
20    {
21        return 'VRT News';
22    }
23}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:50:30 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-progress/Services/Parsers/VrtHomepageParser.php.html b/backend/coverage-report-progress/Services/Parsers/VrtHomepageParser.php.html deleted file mode 100644 index 03f2e95f..00000000 --- a/backend/coverage-report-progress/Services/Parsers/VrtHomepageParser.php.html +++ /dev/null @@ -1,175 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Services/Parsers/VrtHomepageParser.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 6
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
VrtHomepageParser
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 6
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 extractArticleUrls
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 6
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Services\Parsers;
4
5class VrtHomepageParser
6{
7    /**
8     * @return array<int, string>
9     */
10    public static function extractArticleUrls(string $html): array
11    {
12        // Extract article links using regex
13        preg_match_all('/href="(\/vrtnws\/en\/\d{4}\/\d{2}\/\d{2}\/[^"]+)"/', $html, $matches);
14
15        $urls = collect($matches[1])
16            ->unique()
17            ->map(fn ($path) => 'https://www.vrt.be' . $path)
18            ->toArray();
19
20        return $urls;
21    }
22}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:50:30 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-progress/Services/Parsers/VrtHomepageParserAdapter.php.html b/backend/coverage-report-progress/Services/Parsers/VrtHomepageParserAdapter.php.html deleted file mode 100644 index cd25674a..00000000 --- a/backend/coverage-report-progress/Services/Parsers/VrtHomepageParserAdapter.php.html +++ /dev/null @@ -1,247 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Services/Parsers/VrtHomepageParserAdapter.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 4
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 4
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
VrtHomepageParserAdapter
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 4
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 4
20
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 canParse
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 extractArticleUrls
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 getHomepageUrl
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 getSourceName
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Services\Parsers;
4
5use App\Contracts\HomepageParserInterface;
6
7class VrtHomepageParserAdapter implements HomepageParserInterface
8{
9    public function canParse(string $url): bool
10    {
11        return str_contains($url, 'vrt.be');
12    }
13
14    public function extractArticleUrls(string $html): array
15    {
16        return VrtHomepageParser::extractArticleUrls($html);
17    }
18
19    public function getHomepageUrl(): string
20    {
21        return 'https://www.vrt.be/vrtnws/en/';
22    }
23
24    public function getSourceName(): string
25    {
26        return 'VRT News';
27    }
28}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:50:30 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-progress/Services/Parsers/dashboard.html b/backend/coverage-report-progress/Services/Parsers/dashboard.html deleted file mode 100644 index ae288da7..00000000 --- a/backend/coverage-report-progress/Services/Parsers/dashboard.html +++ /dev/null @@ -1,329 +0,0 @@ - - - - - Dashboard for /var/www/html/backend/app/Services/Parsers - - - - - - - -
-
-
-
- -
-
-
-
-
-
-
-

Classes

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
- -
-
-

Methods

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
- - -
- - - - - - diff --git a/backend/coverage-report-progress/Services/Parsers/index.html b/backend/coverage-report-progress/Services/Parsers/index.html deleted file mode 100644 index a0be858f..00000000 --- a/backend/coverage-report-progress/Services/Parsers/index.html +++ /dev/null @@ -1,316 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Services/Parsers - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 102
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 26
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 8
BelgaArticlePageParser.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 42
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 5
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
BelgaArticleParser.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
BelgaHomepageParser.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 5
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
BelgaHomepageParserAdapter.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 4
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 4
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
VrtArticlePageParser.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 35
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 5
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
VrtArticleParser.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
VrtHomepageParser.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 6
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
VrtHomepageParserAdapter.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 4
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 4
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- -
- - diff --git a/backend/coverage-report-progress/Services/Publishing/ArticlePublishingService.php.html b/backend/coverage-report-progress/Services/Publishing/ArticlePublishingService.php.html deleted file mode 100644 index ec4ea034..00000000 --- a/backend/coverage-report-progress/Services/Publishing/ArticlePublishingService.php.html +++ /dev/null @@ -1,260 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Services/Publishing/ArticlePublishingService.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 36
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
ArticlePublishingService
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 36
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
30
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 publishToRoutedChannels
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 14
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
12
 publishToChannel
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 22
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
6
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Services\Publishing;
4
5use App\Enums\PlatformEnum;
6use App\Exceptions\PublishException;
7use App\Models\Article;
8use App\Models\ArticlePublication;
9use App\Models\PlatformChannel;
10use App\Modules\Lemmy\Services\LemmyPublisher;
11use App\Services\Log\LogSaver;
12use Exception;
13use Illuminate\Database\Eloquent\Collection as EloquentCollection;
14use Illuminate\Support\Collection;
15use RuntimeException;
16
17class ArticlePublishingService
18{
19    /**
20     * @param array<string, mixed> $extractedData
21     * @return EloquentCollection<int, ArticlePublication>
22     * @throws PublishException
23     */
24    public function publishToRoutedChannels(Article $article, array $extractedData): EloquentCollection
25    {
26        if (! $article->is_valid) {
27            throw new PublishException($article, PlatformEnum::LEMMY, new RuntimeException('CANNOT_PUBLISH_INVALID_ARTICLE'));
28        }
29
30        $feed = $article->feed;
31        
32        /** @var EloquentCollection<int, PlatformChannel> $activeChannels */
33        $activeChannels = $feed->activeChannels()->with(['platformInstance', 'activePlatformAccounts'])->get();
34
35        return $activeChannels->map(function (PlatformChannel $channel) use ($article, $extractedData) {
36            $account = $channel->activePlatformAccounts()->first();
37
38            if (! $account) {
39                LogSaver::warning('No active account for channel', $channel, [
40                    'article_id' => $article->id
41                ]);
42
43                return null;
44            }
45
46            return $this->publishToChannel($article, $extractedData, $channel, $account);
47        })
48        ->filter();
49    }
50
51    /**
52     * @param array<string, mixed> $extractedData
53     */
54    private function publishToChannel(Article $article, array $extractedData, PlatformChannel $channel, mixed $account): ?ArticlePublication
55    {
56        try {
57            $publisher = new LemmyPublisher($account);
58            $postData = $publisher->publishToChannel($article, $extractedData, $channel);
59
60            $publication = ArticlePublication::create([
61                'article_id' => $article->id,
62                'post_id' => $postData['post_view']['post']['id'],
63                'platform_channel_id' => $channel->id,
64                'published_by' => $account->username,
65                'published_at' => now(),
66                'platform' => $channel->platformInstance->platform->value,
67                'publication_data' => $postData,
68            ]);
69
70            LogSaver::info('Published to channel via routing', $channel, [
71                'article_id' => $article->id,
72                'priority' => $channel->pivot->priority ?? null
73            ]);
74
75            return $publication;
76        } catch (Exception $e) {
77            LogSaver::warning('Failed to publish to channel', $channel, [
78                'article_id' => $article->id,
79                'error' => $e->getMessage()
80            ]);
81
82            return null;
83        }
84    }
85}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:50:30 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-progress/Services/Publishing/dashboard.html b/backend/coverage-report-progress/Services/Publishing/dashboard.html deleted file mode 100644 index 9d8dffa3..00000000 --- a/backend/coverage-report-progress/Services/Publishing/dashboard.html +++ /dev/null @@ -1,291 +0,0 @@ - - - - - Dashboard for /var/www/html/backend/app/Services/Publishing - - - - - - - -
-
-
-
- -
-
-
-
-
-
-
-

Classes

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
-
-
-

Insufficient Coverage

-
- - - - - - - - - - - -
ClassCoverage
App\Services\Publishing\ArticlePublishingService0%
-
-
-
-

Project Risks

-
- - - - - - - - - - - -
ClassCRAP
App\Services\Publishing\ArticlePublishingService30
-
-
-
-
-
-

Methods

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
-
-
-

Insufficient Coverage

-
- - - - - - - - - - - - -
MethodCoverage
publishToRoutedChannels0%
publishToChannel0%
-
-
-
-

Project Risks

-
- - - - - - - - - - - - -
MethodCRAP
publishToRoutedChannels12
publishToChannel6
-
-
-
- -
- - - - - - diff --git a/backend/coverage-report-progress/Services/Publishing/index.html b/backend/coverage-report-progress/Services/Publishing/index.html deleted file mode 100644 index 8eed2510..00000000 --- a/backend/coverage-report-progress/Services/Publishing/index.html +++ /dev/null @@ -1,120 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Services/Publishing - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 36
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
ArticlePublishingService.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 36
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- -
- - diff --git a/backend/coverage-report-progress/Services/RoutingValidationService.php.html b/backend/coverage-report-progress/Services/RoutingValidationService.php.html deleted file mode 100644 index 3e4442d5..00000000 --- a/backend/coverage-report-progress/Services/RoutingValidationService.php.html +++ /dev/null @@ -1,184 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Services/RoutingValidationService.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 7
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
RoutingValidationService
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 7
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
30
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 validateLanguageCompatibility
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 7
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
30
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Services;
4
5use App\Exceptions\RoutingMismatchException;
6use App\Models\Feed;
7use App\Models\PlatformChannel;
8use Illuminate\Support\Collection;
9
10class RoutingValidationService
11{
12    /**
13     * @param Collection<int, PlatformChannel> $channels
14     * @throws RoutingMismatchException
15     */
16    public function validateLanguageCompatibility(Feed $feed, Collection $channels): void
17    {
18        if (! $feed->language) {
19            return;
20        }
21
22        foreach ($channels as $channel) {
23            if (! $channel->language) {
24                continue;
25            }
26
27            if ($feed->language !== $channel->language) {
28                throw new RoutingMismatchException($feed, $channel);
29            }
30        }
31    }
32}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:50:30 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-progress/Services/SystemStatusService.php.html b/backend/coverage-report-progress/Services/SystemStatusService.php.html deleted file mode 100644 index 292fe904..00000000 --- a/backend/coverage-report-progress/Services/SystemStatusService.php.html +++ /dev/null @@ -1,226 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Services/SystemStatusService.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 21
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
SystemStatusService
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 21
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
72
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 getSystemStatus
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 20
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
56
 canProcessArticles
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Services;
4
5use App\Models\Feed;
6use App\Models\Route;
7use App\Models\PlatformChannel;
8use App\Models\Setting;
9
10class SystemStatusService
11{
12    /**
13     * @return array{is_enabled: bool, status: string, status_class: string, reasons: array<int, string>}
14     */
15    public function getSystemStatus(): array
16    {
17        $reasons = [];
18        $isEnabled = true;
19
20        if (!Setting::isArticleProcessingEnabled()) {
21            $isEnabled = false;
22            $reasons[] = 'Manually disabled by user';
23        }
24
25        if (!Feed::where('is_active', true)->exists()) {
26            $isEnabled = false;
27            $reasons[] = 'No active feeds configured';
28        }
29
30        if (!PlatformChannel::where('is_active', true)->exists()) {
31            $isEnabled = false;
32            $reasons[] = 'No active platform channels configured';
33        }
34
35        if (!Route::where('is_active', true)->exists()) {
36            $isEnabled = false;
37            $reasons[] = 'No active feed-to-channel routes configured';
38        }
39
40        return [
41            'is_enabled' => $isEnabled,
42            'status' => $isEnabled ? 'Enabled' : 'Disabled',
43            'status_class' => $isEnabled ? 'text-green-600' : 'text-red-600',
44            'reasons' => $reasons,
45        ];
46    }
47
48    public function canProcessArticles(): bool
49    {
50        return $this->getSystemStatus()['is_enabled'];
51    }
52}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:50:30 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-progress/Services/dashboard.html b/backend/coverage-report-progress/Services/dashboard.html deleted file mode 100644 index 253db78e..00000000 --- a/backend/coverage-report-progress/Services/dashboard.html +++ /dev/null @@ -1,395 +0,0 @@ - - - - - Dashboard for /var/www/html/backend/app/Services - - - - - - - -
-
-
-
- -
-
-
-
-
-
-
-

Classes

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
- -
-
-

Methods

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
-
- - -
- -
- - - - - - diff --git a/backend/coverage-report-progress/Services/index.html b/backend/coverage-report-progress/Services/index.html deleted file mode 100644 index 01729def..00000000 --- a/backend/coverage-report-progress/Services/index.html +++ /dev/null @@ -1,399 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Services - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 10.78% covered (danger) -
-
-
10.78%
40 / 371
-
- 7.14% covered (danger) -
-
-
7.14%
4 / 56
-
- 5.00% covered (danger) -
-
-
5.00%
1 / 20
Article
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 69
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 7
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
Auth
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 12
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
Factories
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 19
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 5
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
Http
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 44
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
Log
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 17
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 5
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
Parsers
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 102
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 26
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 8
Publishing
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 36
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
DashboardStatsService.php
-
- 100.00% covered (success) -
-
-
100.00%
40 / 40
-
- 100.00% covered (success) -
-
-
100.00%
4 / 4
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
OnboardingRedirectService.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 4
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
RoutingValidationService.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 7
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
SystemStatusService.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 21
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- -
- - diff --git a/backend/coverage-report-progress/_css/bootstrap.min.css b/backend/coverage-report-progress/_css/bootstrap.min.css deleted file mode 100644 index 27d4921c..00000000 --- a/backend/coverage-report-progress/_css/bootstrap.min.css +++ /dev/null @@ -1,6 +0,0 @@ -@charset "UTF-8";/*! - * Bootstrap v5.3.6 (https://getbootstrap.com/) - * Copyright 2011-2025 The Bootstrap Authors - * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) - */:root,[data-bs-theme=light]{--bs-blue:#0d6efd;--bs-indigo:#6610f2;--bs-purple:#6f42c1;--bs-pink:#d63384;--bs-red:#dc3545;--bs-orange:#fd7e14;--bs-yellow:#ffc107;--bs-green:#198754;--bs-teal:#20c997;--bs-cyan:#0dcaf0;--bs-black:#000;--bs-white:#fff;--bs-gray:#6c757d;--bs-gray-dark:#343a40;--bs-gray-100:#f8f9fa;--bs-gray-200:#e9ecef;--bs-gray-300:#dee2e6;--bs-gray-400:#ced4da;--bs-gray-500:#adb5bd;--bs-gray-600:#6c757d;--bs-gray-700:#495057;--bs-gray-800:#343a40;--bs-gray-900:#212529;--bs-primary:#0d6efd;--bs-secondary:#6c757d;--bs-success:#198754;--bs-info:#0dcaf0;--bs-warning:#ffc107;--bs-danger:#dc3545;--bs-light:#f8f9fa;--bs-dark:#212529;--bs-primary-rgb:13,110,253;--bs-secondary-rgb:108,117,125;--bs-success-rgb:25,135,84;--bs-info-rgb:13,202,240;--bs-warning-rgb:255,193,7;--bs-danger-rgb:220,53,69;--bs-light-rgb:248,249,250;--bs-dark-rgb:33,37,41;--bs-primary-text-emphasis:#052c65;--bs-secondary-text-emphasis:#2b2f32;--bs-success-text-emphasis:#0a3622;--bs-info-text-emphasis:#055160;--bs-warning-text-emphasis:#664d03;--bs-danger-text-emphasis:#58151c;--bs-light-text-emphasis:#495057;--bs-dark-text-emphasis:#495057;--bs-primary-bg-subtle:#cfe2ff;--bs-secondary-bg-subtle:#e2e3e5;--bs-success-bg-subtle:#d1e7dd;--bs-info-bg-subtle:#cff4fc;--bs-warning-bg-subtle:#fff3cd;--bs-danger-bg-subtle:#f8d7da;--bs-light-bg-subtle:#fcfcfd;--bs-dark-bg-subtle:#ced4da;--bs-primary-border-subtle:#9ec5fe;--bs-secondary-border-subtle:#c4c8cb;--bs-success-border-subtle:#a3cfbb;--bs-info-border-subtle:#9eeaf9;--bs-warning-border-subtle:#ffe69c;--bs-danger-border-subtle:#f1aeb5;--bs-light-border-subtle:#e9ecef;--bs-dark-border-subtle:#adb5bd;--bs-white-rgb:255,255,255;--bs-black-rgb:0,0,0;--bs-font-sans-serif:system-ui,-apple-system,"Segoe UI",Roboto,"Helvetica Neue","Noto Sans","Liberation Sans",Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";--bs-font-monospace:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;--bs-gradient:linear-gradient(180deg, rgba(255, 255, 255, 0.15), rgba(255, 255, 255, 0));--bs-body-font-family:var(--bs-font-sans-serif);--bs-body-font-size:1rem;--bs-body-font-weight:400;--bs-body-line-height:1.5;--bs-body-color:#212529;--bs-body-color-rgb:33,37,41;--bs-body-bg:#fff;--bs-body-bg-rgb:255,255,255;--bs-emphasis-color:#000;--bs-emphasis-color-rgb:0,0,0;--bs-secondary-color:rgba(33, 37, 41, 0.75);--bs-secondary-color-rgb:33,37,41;--bs-secondary-bg:#e9ecef;--bs-secondary-bg-rgb:233,236,239;--bs-tertiary-color:rgba(33, 37, 41, 0.5);--bs-tertiary-color-rgb:33,37,41;--bs-tertiary-bg:#f8f9fa;--bs-tertiary-bg-rgb:248,249,250;--bs-heading-color:inherit;--bs-link-color:#0d6efd;--bs-link-color-rgb:13,110,253;--bs-link-decoration:underline;--bs-link-hover-color:#0a58ca;--bs-link-hover-color-rgb:10,88,202;--bs-code-color:#d63384;--bs-highlight-color:#212529;--bs-highlight-bg:#fff3cd;--bs-border-width:1px;--bs-border-style:solid;--bs-border-color:#dee2e6;--bs-border-color-translucent:rgba(0, 0, 0, 0.175);--bs-border-radius:0.375rem;--bs-border-radius-sm:0.25rem;--bs-border-radius-lg:0.5rem;--bs-border-radius-xl:1rem;--bs-border-radius-xxl:2rem;--bs-border-radius-2xl:var(--bs-border-radius-xxl);--bs-border-radius-pill:50rem;--bs-box-shadow:0 0.5rem 1rem rgba(0, 0, 0, 0.15);--bs-box-shadow-sm:0 0.125rem 0.25rem rgba(0, 0, 0, 0.075);--bs-box-shadow-lg:0 1rem 3rem rgba(0, 0, 0, 0.175);--bs-box-shadow-inset:inset 0 1px 2px rgba(0, 0, 0, 0.075);--bs-focus-ring-width:0.25rem;--bs-focus-ring-opacity:0.25;--bs-focus-ring-color:rgba(13, 110, 253, 0.25);--bs-form-valid-color:#198754;--bs-form-valid-border-color:#198754;--bs-form-invalid-color:#dc3545;--bs-form-invalid-border-color:#dc3545}[data-bs-theme=dark]{color-scheme:dark;--bs-body-color:#dee2e6;--bs-body-color-rgb:222,226,230;--bs-body-bg:#212529;--bs-body-bg-rgb:33,37,41;--bs-emphasis-color:#fff;--bs-emphasis-color-rgb:255,255,255;--bs-secondary-color:rgba(222, 226, 230, 0.75);--bs-secondary-color-rgb:222,226,230;--bs-secondary-bg:#343a40;--bs-secondary-bg-rgb:52,58,64;--bs-tertiary-color:rgba(222, 226, 230, 0.5);--bs-tertiary-color-rgb:222,226,230;--bs-tertiary-bg:#2b3035;--bs-tertiary-bg-rgb:43,48,53;--bs-primary-text-emphasis:#6ea8fe;--bs-secondary-text-emphasis:#a7acb1;--bs-success-text-emphasis:#75b798;--bs-info-text-emphasis:#6edff6;--bs-warning-text-emphasis:#ffda6a;--bs-danger-text-emphasis:#ea868f;--bs-light-text-emphasis:#f8f9fa;--bs-dark-text-emphasis:#dee2e6;--bs-primary-bg-subtle:#031633;--bs-secondary-bg-subtle:#161719;--bs-success-bg-subtle:#051b11;--bs-info-bg-subtle:#032830;--bs-warning-bg-subtle:#332701;--bs-danger-bg-subtle:#2c0b0e;--bs-light-bg-subtle:#343a40;--bs-dark-bg-subtle:#1a1d20;--bs-primary-border-subtle:#084298;--bs-secondary-border-subtle:#41464b;--bs-success-border-subtle:#0f5132;--bs-info-border-subtle:#087990;--bs-warning-border-subtle:#997404;--bs-danger-border-subtle:#842029;--bs-light-border-subtle:#495057;--bs-dark-border-subtle:#343a40;--bs-heading-color:inherit;--bs-link-color:#6ea8fe;--bs-link-hover-color:#8bb9fe;--bs-link-color-rgb:110,168,254;--bs-link-hover-color-rgb:139,185,254;--bs-code-color:#e685b5;--bs-highlight-color:#dee2e6;--bs-highlight-bg:#664d03;--bs-border-color:#495057;--bs-border-color-translucent:rgba(255, 255, 255, 0.15);--bs-form-valid-color:#75b798;--bs-form-valid-border-color:#75b798;--bs-form-invalid-color:#ea868f;--bs-form-invalid-border-color:#ea868f}*,::after,::before{box-sizing:border-box}@media (prefers-reduced-motion:no-preference){:root{scroll-behavior:smooth}}body{margin:0;font-family:var(--bs-body-font-family);font-size:var(--bs-body-font-size);font-weight:var(--bs-body-font-weight);line-height:var(--bs-body-line-height);color:var(--bs-body-color);text-align:var(--bs-body-text-align);background-color:var(--bs-body-bg);-webkit-text-size-adjust:100%;-webkit-tap-highlight-color:transparent}hr{margin:1rem 0;color:inherit;border:0;border-top:var(--bs-border-width) solid;opacity:.25}.h1,.h2,.h3,.h4,.h5,.h6,h1,h2,h3,h4,h5,h6{margin-top:0;margin-bottom:.5rem;font-weight:500;line-height:1.2;color:var(--bs-heading-color)}.h1,h1{font-size:calc(1.375rem + 1.5vw)}@media (min-width:1200px){.h1,h1{font-size:2.5rem}}.h2,h2{font-size:calc(1.325rem + .9vw)}@media (min-width:1200px){.h2,h2{font-size:2rem}}.h3,h3{font-size:calc(1.3rem + .6vw)}@media (min-width:1200px){.h3,h3{font-size:1.75rem}}.h4,h4{font-size:calc(1.275rem + .3vw)}@media (min-width:1200px){.h4,h4{font-size:1.5rem}}.h5,h5{font-size:1.25rem}.h6,h6{font-size:1rem}p{margin-top:0;margin-bottom:1rem}abbr[title]{-webkit-text-decoration:underline dotted;text-decoration:underline dotted;cursor:help;-webkit-text-decoration-skip-ink:none;text-decoration-skip-ink:none}address{margin-bottom:1rem;font-style:normal;line-height:inherit}ol,ul{padding-left:2rem}dl,ol,ul{margin-top:0;margin-bottom:1rem}ol ol,ol ul,ul ol,ul ul{margin-bottom:0}dt{font-weight:700}dd{margin-bottom:.5rem;margin-left:0}blockquote{margin:0 0 1rem}b,strong{font-weight:bolder}.small,small{font-size:.875em}.mark,mark{padding:.1875em;color:var(--bs-highlight-color);background-color:var(--bs-highlight-bg)}sub,sup{position:relative;font-size:.75em;line-height:0;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}a{color:rgba(var(--bs-link-color-rgb),var(--bs-link-opacity,1));text-decoration:underline}a:hover{--bs-link-color-rgb:var(--bs-link-hover-color-rgb)}a:not([href]):not([class]),a:not([href]):not([class]):hover{color:inherit;text-decoration:none}code,kbd,pre,samp{font-family:var(--bs-font-monospace);font-size:1em}pre{display:block;margin-top:0;margin-bottom:1rem;overflow:auto;font-size:.875em}pre code{font-size:inherit;color:inherit;word-break:normal}code{font-size:.875em;color:var(--bs-code-color);word-wrap:break-word}a>code{color:inherit}kbd{padding:.1875rem .375rem;font-size:.875em;color:var(--bs-body-bg);background-color:var(--bs-body-color);border-radius:.25rem}kbd kbd{padding:0;font-size:1em}figure{margin:0 0 1rem}img,svg{vertical-align:middle}table{caption-side:bottom;border-collapse:collapse}caption{padding-top:.5rem;padding-bottom:.5rem;color:var(--bs-secondary-color);text-align:left}th{text-align:inherit;text-align:-webkit-match-parent}tbody,td,tfoot,th,thead,tr{border-color:inherit;border-style:solid;border-width:0}label{display:inline-block}button{border-radius:0}button:focus:not(:focus-visible){outline:0}button,input,optgroup,select,textarea{margin:0;font-family:inherit;font-size:inherit;line-height:inherit}button,select{text-transform:none}[role=button]{cursor:pointer}select{word-wrap:normal}select:disabled{opacity:1}[list]:not([type=date]):not([type=datetime-local]):not([type=month]):not([type=week]):not([type=time])::-webkit-calendar-picker-indicator{display:none!important}[type=button],[type=reset],[type=submit],button{-webkit-appearance:button}[type=button]:not(:disabled),[type=reset]:not(:disabled),[type=submit]:not(:disabled),button:not(:disabled){cursor:pointer}::-moz-focus-inner{padding:0;border-style:none}textarea{resize:vertical}fieldset{min-width:0;padding:0;margin:0;border:0}legend{float:left;width:100%;padding:0;margin-bottom:.5rem;line-height:inherit;font-size:calc(1.275rem + .3vw)}@media (min-width:1200px){legend{font-size:1.5rem}}legend+*{clear:left}::-webkit-datetime-edit-day-field,::-webkit-datetime-edit-fields-wrapper,::-webkit-datetime-edit-hour-field,::-webkit-datetime-edit-minute,::-webkit-datetime-edit-month-field,::-webkit-datetime-edit-text,::-webkit-datetime-edit-year-field{padding:0}::-webkit-inner-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-color-swatch-wrapper{padding:0}::-webkit-file-upload-button{font:inherit;-webkit-appearance:button}::file-selector-button{font:inherit;-webkit-appearance:button}output{display:inline-block}iframe{border:0}summary{display:list-item;cursor:pointer}progress{vertical-align:baseline}[hidden]{display:none!important}.lead{font-size:1.25rem;font-weight:300}.display-1{font-weight:300;line-height:1.2;font-size:calc(1.625rem + 4.5vw)}@media (min-width:1200px){.display-1{font-size:5rem}}.display-2{font-weight:300;line-height:1.2;font-size:calc(1.575rem + 3.9vw)}@media (min-width:1200px){.display-2{font-size:4.5rem}}.display-3{font-weight:300;line-height:1.2;font-size:calc(1.525rem + 3.3vw)}@media (min-width:1200px){.display-3{font-size:4rem}}.display-4{font-weight:300;line-height:1.2;font-size:calc(1.475rem + 2.7vw)}@media (min-width:1200px){.display-4{font-size:3.5rem}}.display-5{font-weight:300;line-height:1.2;font-size:calc(1.425rem + 2.1vw)}@media (min-width:1200px){.display-5{font-size:3rem}}.display-6{font-weight:300;line-height:1.2;font-size:calc(1.375rem + 1.5vw)}@media (min-width:1200px){.display-6{font-size:2.5rem}}.list-unstyled{padding-left:0;list-style:none}.list-inline{padding-left:0;list-style:none}.list-inline-item{display:inline-block}.list-inline-item:not(:last-child){margin-right:.5rem}.initialism{font-size:.875em;text-transform:uppercase}.blockquote{margin-bottom:1rem;font-size:1.25rem}.blockquote>:last-child{margin-bottom:0}.blockquote-footer{margin-top:-1rem;margin-bottom:1rem;font-size:.875em;color:#6c757d}.blockquote-footer::before{content:"— "}.img-fluid{max-width:100%;height:auto}.img-thumbnail{padding:.25rem;background-color:var(--bs-body-bg);border:var(--bs-border-width) solid var(--bs-border-color);border-radius:var(--bs-border-radius);max-width:100%;height:auto}.figure{display:inline-block}.figure-img{margin-bottom:.5rem;line-height:1}.figure-caption{font-size:.875em;color:var(--bs-secondary-color)}.container,.container-fluid,.container-lg,.container-md,.container-sm,.container-xl,.container-xxl{--bs-gutter-x:1.5rem;--bs-gutter-y:0;width:100%;padding-right:calc(var(--bs-gutter-x) * .5);padding-left:calc(var(--bs-gutter-x) * .5);margin-right:auto;margin-left:auto}@media (min-width:576px){.container,.container-sm{max-width:540px}}@media (min-width:768px){.container,.container-md,.container-sm{max-width:720px}}@media (min-width:992px){.container,.container-lg,.container-md,.container-sm{max-width:960px}}@media (min-width:1200px){.container,.container-lg,.container-md,.container-sm,.container-xl{max-width:1140px}}@media (min-width:1400px){.container,.container-lg,.container-md,.container-sm,.container-xl,.container-xxl{max-width:1320px}}:root{--bs-breakpoint-xs:0;--bs-breakpoint-sm:576px;--bs-breakpoint-md:768px;--bs-breakpoint-lg:992px;--bs-breakpoint-xl:1200px;--bs-breakpoint-xxl:1400px}.row{--bs-gutter-x:1.5rem;--bs-gutter-y:0;display:flex;flex-wrap:wrap;margin-top:calc(-1 * var(--bs-gutter-y));margin-right:calc(-.5 * var(--bs-gutter-x));margin-left:calc(-.5 * var(--bs-gutter-x))}.row>*{flex-shrink:0;width:100%;max-width:100%;padding-right:calc(var(--bs-gutter-x) * .5);padding-left:calc(var(--bs-gutter-x) * .5);margin-top:var(--bs-gutter-y)}.col{flex:1 0 0}.row-cols-auto>*{flex:0 0 auto;width:auto}.row-cols-1>*{flex:0 0 auto;width:100%}.row-cols-2>*{flex:0 0 auto;width:50%}.row-cols-3>*{flex:0 0 auto;width:33.33333333%}.row-cols-4>*{flex:0 0 auto;width:25%}.row-cols-5>*{flex:0 0 auto;width:20%}.row-cols-6>*{flex:0 0 auto;width:16.66666667%}.col-auto{flex:0 0 auto;width:auto}.col-1{flex:0 0 auto;width:8.33333333%}.col-2{flex:0 0 auto;width:16.66666667%}.col-3{flex:0 0 auto;width:25%}.col-4{flex:0 0 auto;width:33.33333333%}.col-5{flex:0 0 auto;width:41.66666667%}.col-6{flex:0 0 auto;width:50%}.col-7{flex:0 0 auto;width:58.33333333%}.col-8{flex:0 0 auto;width:66.66666667%}.col-9{flex:0 0 auto;width:75%}.col-10{flex:0 0 auto;width:83.33333333%}.col-11{flex:0 0 auto;width:91.66666667%}.col-12{flex:0 0 auto;width:100%}.offset-1{margin-left:8.33333333%}.offset-2{margin-left:16.66666667%}.offset-3{margin-left:25%}.offset-4{margin-left:33.33333333%}.offset-5{margin-left:41.66666667%}.offset-6{margin-left:50%}.offset-7{margin-left:58.33333333%}.offset-8{margin-left:66.66666667%}.offset-9{margin-left:75%}.offset-10{margin-left:83.33333333%}.offset-11{margin-left:91.66666667%}.g-0,.gx-0{--bs-gutter-x:0}.g-0,.gy-0{--bs-gutter-y:0}.g-1,.gx-1{--bs-gutter-x:0.25rem}.g-1,.gy-1{--bs-gutter-y:0.25rem}.g-2,.gx-2{--bs-gutter-x:0.5rem}.g-2,.gy-2{--bs-gutter-y:0.5rem}.g-3,.gx-3{--bs-gutter-x:1rem}.g-3,.gy-3{--bs-gutter-y:1rem}.g-4,.gx-4{--bs-gutter-x:1.5rem}.g-4,.gy-4{--bs-gutter-y:1.5rem}.g-5,.gx-5{--bs-gutter-x:3rem}.g-5,.gy-5{--bs-gutter-y:3rem}@media (min-width:576px){.col-sm{flex:1 0 0}.row-cols-sm-auto>*{flex:0 0 auto;width:auto}.row-cols-sm-1>*{flex:0 0 auto;width:100%}.row-cols-sm-2>*{flex:0 0 auto;width:50%}.row-cols-sm-3>*{flex:0 0 auto;width:33.33333333%}.row-cols-sm-4>*{flex:0 0 auto;width:25%}.row-cols-sm-5>*{flex:0 0 auto;width:20%}.row-cols-sm-6>*{flex:0 0 auto;width:16.66666667%}.col-sm-auto{flex:0 0 auto;width:auto}.col-sm-1{flex:0 0 auto;width:8.33333333%}.col-sm-2{flex:0 0 auto;width:16.66666667%}.col-sm-3{flex:0 0 auto;width:25%}.col-sm-4{flex:0 0 auto;width:33.33333333%}.col-sm-5{flex:0 0 auto;width:41.66666667%}.col-sm-6{flex:0 0 auto;width:50%}.col-sm-7{flex:0 0 auto;width:58.33333333%}.col-sm-8{flex:0 0 auto;width:66.66666667%}.col-sm-9{flex:0 0 auto;width:75%}.col-sm-10{flex:0 0 auto;width:83.33333333%}.col-sm-11{flex:0 0 auto;width:91.66666667%}.col-sm-12{flex:0 0 auto;width:100%}.offset-sm-0{margin-left:0}.offset-sm-1{margin-left:8.33333333%}.offset-sm-2{margin-left:16.66666667%}.offset-sm-3{margin-left:25%}.offset-sm-4{margin-left:33.33333333%}.offset-sm-5{margin-left:41.66666667%}.offset-sm-6{margin-left:50%}.offset-sm-7{margin-left:58.33333333%}.offset-sm-8{margin-left:66.66666667%}.offset-sm-9{margin-left:75%}.offset-sm-10{margin-left:83.33333333%}.offset-sm-11{margin-left:91.66666667%}.g-sm-0,.gx-sm-0{--bs-gutter-x:0}.g-sm-0,.gy-sm-0{--bs-gutter-y:0}.g-sm-1,.gx-sm-1{--bs-gutter-x:0.25rem}.g-sm-1,.gy-sm-1{--bs-gutter-y:0.25rem}.g-sm-2,.gx-sm-2{--bs-gutter-x:0.5rem}.g-sm-2,.gy-sm-2{--bs-gutter-y:0.5rem}.g-sm-3,.gx-sm-3{--bs-gutter-x:1rem}.g-sm-3,.gy-sm-3{--bs-gutter-y:1rem}.g-sm-4,.gx-sm-4{--bs-gutter-x:1.5rem}.g-sm-4,.gy-sm-4{--bs-gutter-y:1.5rem}.g-sm-5,.gx-sm-5{--bs-gutter-x:3rem}.g-sm-5,.gy-sm-5{--bs-gutter-y:3rem}}@media (min-width:768px){.col-md{flex:1 0 0}.row-cols-md-auto>*{flex:0 0 auto;width:auto}.row-cols-md-1>*{flex:0 0 auto;width:100%}.row-cols-md-2>*{flex:0 0 auto;width:50%}.row-cols-md-3>*{flex:0 0 auto;width:33.33333333%}.row-cols-md-4>*{flex:0 0 auto;width:25%}.row-cols-md-5>*{flex:0 0 auto;width:20%}.row-cols-md-6>*{flex:0 0 auto;width:16.66666667%}.col-md-auto{flex:0 0 auto;width:auto}.col-md-1{flex:0 0 auto;width:8.33333333%}.col-md-2{flex:0 0 auto;width:16.66666667%}.col-md-3{flex:0 0 auto;width:25%}.col-md-4{flex:0 0 auto;width:33.33333333%}.col-md-5{flex:0 0 auto;width:41.66666667%}.col-md-6{flex:0 0 auto;width:50%}.col-md-7{flex:0 0 auto;width:58.33333333%}.col-md-8{flex:0 0 auto;width:66.66666667%}.col-md-9{flex:0 0 auto;width:75%}.col-md-10{flex:0 0 auto;width:83.33333333%}.col-md-11{flex:0 0 auto;width:91.66666667%}.col-md-12{flex:0 0 auto;width:100%}.offset-md-0{margin-left:0}.offset-md-1{margin-left:8.33333333%}.offset-md-2{margin-left:16.66666667%}.offset-md-3{margin-left:25%}.offset-md-4{margin-left:33.33333333%}.offset-md-5{margin-left:41.66666667%}.offset-md-6{margin-left:50%}.offset-md-7{margin-left:58.33333333%}.offset-md-8{margin-left:66.66666667%}.offset-md-9{margin-left:75%}.offset-md-10{margin-left:83.33333333%}.offset-md-11{margin-left:91.66666667%}.g-md-0,.gx-md-0{--bs-gutter-x:0}.g-md-0,.gy-md-0{--bs-gutter-y:0}.g-md-1,.gx-md-1{--bs-gutter-x:0.25rem}.g-md-1,.gy-md-1{--bs-gutter-y:0.25rem}.g-md-2,.gx-md-2{--bs-gutter-x:0.5rem}.g-md-2,.gy-md-2{--bs-gutter-y:0.5rem}.g-md-3,.gx-md-3{--bs-gutter-x:1rem}.g-md-3,.gy-md-3{--bs-gutter-y:1rem}.g-md-4,.gx-md-4{--bs-gutter-x:1.5rem}.g-md-4,.gy-md-4{--bs-gutter-y:1.5rem}.g-md-5,.gx-md-5{--bs-gutter-x:3rem}.g-md-5,.gy-md-5{--bs-gutter-y:3rem}}@media (min-width:992px){.col-lg{flex:1 0 0}.row-cols-lg-auto>*{flex:0 0 auto;width:auto}.row-cols-lg-1>*{flex:0 0 auto;width:100%}.row-cols-lg-2>*{flex:0 0 auto;width:50%}.row-cols-lg-3>*{flex:0 0 auto;width:33.33333333%}.row-cols-lg-4>*{flex:0 0 auto;width:25%}.row-cols-lg-5>*{flex:0 0 auto;width:20%}.row-cols-lg-6>*{flex:0 0 auto;width:16.66666667%}.col-lg-auto{flex:0 0 auto;width:auto}.col-lg-1{flex:0 0 auto;width:8.33333333%}.col-lg-2{flex:0 0 auto;width:16.66666667%}.col-lg-3{flex:0 0 auto;width:25%}.col-lg-4{flex:0 0 auto;width:33.33333333%}.col-lg-5{flex:0 0 auto;width:41.66666667%}.col-lg-6{flex:0 0 auto;width:50%}.col-lg-7{flex:0 0 auto;width:58.33333333%}.col-lg-8{flex:0 0 auto;width:66.66666667%}.col-lg-9{flex:0 0 auto;width:75%}.col-lg-10{flex:0 0 auto;width:83.33333333%}.col-lg-11{flex:0 0 auto;width:91.66666667%}.col-lg-12{flex:0 0 auto;width:100%}.offset-lg-0{margin-left:0}.offset-lg-1{margin-left:8.33333333%}.offset-lg-2{margin-left:16.66666667%}.offset-lg-3{margin-left:25%}.offset-lg-4{margin-left:33.33333333%}.offset-lg-5{margin-left:41.66666667%}.offset-lg-6{margin-left:50%}.offset-lg-7{margin-left:58.33333333%}.offset-lg-8{margin-left:66.66666667%}.offset-lg-9{margin-left:75%}.offset-lg-10{margin-left:83.33333333%}.offset-lg-11{margin-left:91.66666667%}.g-lg-0,.gx-lg-0{--bs-gutter-x:0}.g-lg-0,.gy-lg-0{--bs-gutter-y:0}.g-lg-1,.gx-lg-1{--bs-gutter-x:0.25rem}.g-lg-1,.gy-lg-1{--bs-gutter-y:0.25rem}.g-lg-2,.gx-lg-2{--bs-gutter-x:0.5rem}.g-lg-2,.gy-lg-2{--bs-gutter-y:0.5rem}.g-lg-3,.gx-lg-3{--bs-gutter-x:1rem}.g-lg-3,.gy-lg-3{--bs-gutter-y:1rem}.g-lg-4,.gx-lg-4{--bs-gutter-x:1.5rem}.g-lg-4,.gy-lg-4{--bs-gutter-y:1.5rem}.g-lg-5,.gx-lg-5{--bs-gutter-x:3rem}.g-lg-5,.gy-lg-5{--bs-gutter-y:3rem}}@media (min-width:1200px){.col-xl{flex:1 0 0}.row-cols-xl-auto>*{flex:0 0 auto;width:auto}.row-cols-xl-1>*{flex:0 0 auto;width:100%}.row-cols-xl-2>*{flex:0 0 auto;width:50%}.row-cols-xl-3>*{flex:0 0 auto;width:33.33333333%}.row-cols-xl-4>*{flex:0 0 auto;width:25%}.row-cols-xl-5>*{flex:0 0 auto;width:20%}.row-cols-xl-6>*{flex:0 0 auto;width:16.66666667%}.col-xl-auto{flex:0 0 auto;width:auto}.col-xl-1{flex:0 0 auto;width:8.33333333%}.col-xl-2{flex:0 0 auto;width:16.66666667%}.col-xl-3{flex:0 0 auto;width:25%}.col-xl-4{flex:0 0 auto;width:33.33333333%}.col-xl-5{flex:0 0 auto;width:41.66666667%}.col-xl-6{flex:0 0 auto;width:50%}.col-xl-7{flex:0 0 auto;width:58.33333333%}.col-xl-8{flex:0 0 auto;width:66.66666667%}.col-xl-9{flex:0 0 auto;width:75%}.col-xl-10{flex:0 0 auto;width:83.33333333%}.col-xl-11{flex:0 0 auto;width:91.66666667%}.col-xl-12{flex:0 0 auto;width:100%}.offset-xl-0{margin-left:0}.offset-xl-1{margin-left:8.33333333%}.offset-xl-2{margin-left:16.66666667%}.offset-xl-3{margin-left:25%}.offset-xl-4{margin-left:33.33333333%}.offset-xl-5{margin-left:41.66666667%}.offset-xl-6{margin-left:50%}.offset-xl-7{margin-left:58.33333333%}.offset-xl-8{margin-left:66.66666667%}.offset-xl-9{margin-left:75%}.offset-xl-10{margin-left:83.33333333%}.offset-xl-11{margin-left:91.66666667%}.g-xl-0,.gx-xl-0{--bs-gutter-x:0}.g-xl-0,.gy-xl-0{--bs-gutter-y:0}.g-xl-1,.gx-xl-1{--bs-gutter-x:0.25rem}.g-xl-1,.gy-xl-1{--bs-gutter-y:0.25rem}.g-xl-2,.gx-xl-2{--bs-gutter-x:0.5rem}.g-xl-2,.gy-xl-2{--bs-gutter-y:0.5rem}.g-xl-3,.gx-xl-3{--bs-gutter-x:1rem}.g-xl-3,.gy-xl-3{--bs-gutter-y:1rem}.g-xl-4,.gx-xl-4{--bs-gutter-x:1.5rem}.g-xl-4,.gy-xl-4{--bs-gutter-y:1.5rem}.g-xl-5,.gx-xl-5{--bs-gutter-x:3rem}.g-xl-5,.gy-xl-5{--bs-gutter-y:3rem}}@media (min-width:1400px){.col-xxl{flex:1 0 0}.row-cols-xxl-auto>*{flex:0 0 auto;width:auto}.row-cols-xxl-1>*{flex:0 0 auto;width:100%}.row-cols-xxl-2>*{flex:0 0 auto;width:50%}.row-cols-xxl-3>*{flex:0 0 auto;width:33.33333333%}.row-cols-xxl-4>*{flex:0 0 auto;width:25%}.row-cols-xxl-5>*{flex:0 0 auto;width:20%}.row-cols-xxl-6>*{flex:0 0 auto;width:16.66666667%}.col-xxl-auto{flex:0 0 auto;width:auto}.col-xxl-1{flex:0 0 auto;width:8.33333333%}.col-xxl-2{flex:0 0 auto;width:16.66666667%}.col-xxl-3{flex:0 0 auto;width:25%}.col-xxl-4{flex:0 0 auto;width:33.33333333%}.col-xxl-5{flex:0 0 auto;width:41.66666667%}.col-xxl-6{flex:0 0 auto;width:50%}.col-xxl-7{flex:0 0 auto;width:58.33333333%}.col-xxl-8{flex:0 0 auto;width:66.66666667%}.col-xxl-9{flex:0 0 auto;width:75%}.col-xxl-10{flex:0 0 auto;width:83.33333333%}.col-xxl-11{flex:0 0 auto;width:91.66666667%}.col-xxl-12{flex:0 0 auto;width:100%}.offset-xxl-0{margin-left:0}.offset-xxl-1{margin-left:8.33333333%}.offset-xxl-2{margin-left:16.66666667%}.offset-xxl-3{margin-left:25%}.offset-xxl-4{margin-left:33.33333333%}.offset-xxl-5{margin-left:41.66666667%}.offset-xxl-6{margin-left:50%}.offset-xxl-7{margin-left:58.33333333%}.offset-xxl-8{margin-left:66.66666667%}.offset-xxl-9{margin-left:75%}.offset-xxl-10{margin-left:83.33333333%}.offset-xxl-11{margin-left:91.66666667%}.g-xxl-0,.gx-xxl-0{--bs-gutter-x:0}.g-xxl-0,.gy-xxl-0{--bs-gutter-y:0}.g-xxl-1,.gx-xxl-1{--bs-gutter-x:0.25rem}.g-xxl-1,.gy-xxl-1{--bs-gutter-y:0.25rem}.g-xxl-2,.gx-xxl-2{--bs-gutter-x:0.5rem}.g-xxl-2,.gy-xxl-2{--bs-gutter-y:0.5rem}.g-xxl-3,.gx-xxl-3{--bs-gutter-x:1rem}.g-xxl-3,.gy-xxl-3{--bs-gutter-y:1rem}.g-xxl-4,.gx-xxl-4{--bs-gutter-x:1.5rem}.g-xxl-4,.gy-xxl-4{--bs-gutter-y:1.5rem}.g-xxl-5,.gx-xxl-5{--bs-gutter-x:3rem}.g-xxl-5,.gy-xxl-5{--bs-gutter-y:3rem}}.table{--bs-table-color-type:initial;--bs-table-bg-type:initial;--bs-table-color-state:initial;--bs-table-bg-state:initial;--bs-table-color:var(--bs-emphasis-color);--bs-table-bg:var(--bs-body-bg);--bs-table-border-color:var(--bs-border-color);--bs-table-accent-bg:transparent;--bs-table-striped-color:var(--bs-emphasis-color);--bs-table-striped-bg:rgba(var(--bs-emphasis-color-rgb), 0.05);--bs-table-active-color:var(--bs-emphasis-color);--bs-table-active-bg:rgba(var(--bs-emphasis-color-rgb), 0.1);--bs-table-hover-color:var(--bs-emphasis-color);--bs-table-hover-bg:rgba(var(--bs-emphasis-color-rgb), 0.075);width:100%;margin-bottom:1rem;vertical-align:top;border-color:var(--bs-table-border-color)}.table>:not(caption)>*>*{padding:.5rem .5rem;color:var(--bs-table-color-state,var(--bs-table-color-type,var(--bs-table-color)));background-color:var(--bs-table-bg);border-bottom-width:var(--bs-border-width);box-shadow:inset 0 0 0 9999px var(--bs-table-bg-state,var(--bs-table-bg-type,var(--bs-table-accent-bg)))}.table>tbody{vertical-align:inherit}.table>thead{vertical-align:bottom}.table-group-divider{border-top:calc(var(--bs-border-width) * 2) solid currentcolor}.caption-top{caption-side:top}.table-sm>:not(caption)>*>*{padding:.25rem .25rem}.table-bordered>:not(caption)>*{border-width:var(--bs-border-width) 0}.table-bordered>:not(caption)>*>*{border-width:0 var(--bs-border-width)}.table-borderless>:not(caption)>*>*{border-bottom-width:0}.table-borderless>:not(:first-child){border-top-width:0}.table-striped>tbody>tr:nth-of-type(odd)>*{--bs-table-color-type:var(--bs-table-striped-color);--bs-table-bg-type:var(--bs-table-striped-bg)}.table-striped-columns>:not(caption)>tr>:nth-child(2n){--bs-table-color-type:var(--bs-table-striped-color);--bs-table-bg-type:var(--bs-table-striped-bg)}.table-active{--bs-table-color-state:var(--bs-table-active-color);--bs-table-bg-state:var(--bs-table-active-bg)}.table-hover>tbody>tr:hover>*{--bs-table-color-state:var(--bs-table-hover-color);--bs-table-bg-state:var(--bs-table-hover-bg)}.table-primary{--bs-table-color:#000;--bs-table-bg:#cfe2ff;--bs-table-border-color:#a6b5cc;--bs-table-striped-bg:#c5d7f2;--bs-table-striped-color:#000;--bs-table-active-bg:#bacbe6;--bs-table-active-color:#000;--bs-table-hover-bg:#bfd1ec;--bs-table-hover-color:#000;color:var(--bs-table-color);border-color:var(--bs-table-border-color)}.table-secondary{--bs-table-color:#000;--bs-table-bg:#e2e3e5;--bs-table-border-color:#b5b6b7;--bs-table-striped-bg:#d7d8da;--bs-table-striped-color:#000;--bs-table-active-bg:#cbccce;--bs-table-active-color:#000;--bs-table-hover-bg:#d1d2d4;--bs-table-hover-color:#000;color:var(--bs-table-color);border-color:var(--bs-table-border-color)}.table-success{--bs-table-color:#000;--bs-table-bg:#d1e7dd;--bs-table-border-color:#a7b9b1;--bs-table-striped-bg:#c7dbd2;--bs-table-striped-color:#000;--bs-table-active-bg:#bcd0c7;--bs-table-active-color:#000;--bs-table-hover-bg:#c1d6cc;--bs-table-hover-color:#000;color:var(--bs-table-color);border-color:var(--bs-table-border-color)}.table-info{--bs-table-color:#000;--bs-table-bg:#cff4fc;--bs-table-border-color:#a6c3ca;--bs-table-striped-bg:#c5e8ef;--bs-table-striped-color:#000;--bs-table-active-bg:#badce3;--bs-table-active-color:#000;--bs-table-hover-bg:#bfe2e9;--bs-table-hover-color:#000;color:var(--bs-table-color);border-color:var(--bs-table-border-color)}.table-warning{--bs-table-color:#000;--bs-table-bg:#fff3cd;--bs-table-border-color:#ccc2a4;--bs-table-striped-bg:#f2e7c3;--bs-table-striped-color:#000;--bs-table-active-bg:#e6dbb9;--bs-table-active-color:#000;--bs-table-hover-bg:#ece1be;--bs-table-hover-color:#000;color:var(--bs-table-color);border-color:var(--bs-table-border-color)}.table-danger{--bs-table-color:#000;--bs-table-bg:#f8d7da;--bs-table-border-color:#c6acae;--bs-table-striped-bg:#eccccf;--bs-table-striped-color:#000;--bs-table-active-bg:#dfc2c4;--bs-table-active-color:#000;--bs-table-hover-bg:#e5c7ca;--bs-table-hover-color:#000;color:var(--bs-table-color);border-color:var(--bs-table-border-color)}.table-light{--bs-table-color:#000;--bs-table-bg:#f8f9fa;--bs-table-border-color:#c6c7c8;--bs-table-striped-bg:#ecedee;--bs-table-striped-color:#000;--bs-table-active-bg:#dfe0e1;--bs-table-active-color:#000;--bs-table-hover-bg:#e5e6e7;--bs-table-hover-color:#000;color:var(--bs-table-color);border-color:var(--bs-table-border-color)}.table-dark{--bs-table-color:#fff;--bs-table-bg:#212529;--bs-table-border-color:#4d5154;--bs-table-striped-bg:#2c3034;--bs-table-striped-color:#fff;--bs-table-active-bg:#373b3e;--bs-table-active-color:#fff;--bs-table-hover-bg:#323539;--bs-table-hover-color:#fff;color:var(--bs-table-color);border-color:var(--bs-table-border-color)}.table-responsive{overflow-x:auto;-webkit-overflow-scrolling:touch}@media (max-width:575.98px){.table-responsive-sm{overflow-x:auto;-webkit-overflow-scrolling:touch}}@media (max-width:767.98px){.table-responsive-md{overflow-x:auto;-webkit-overflow-scrolling:touch}}@media (max-width:991.98px){.table-responsive-lg{overflow-x:auto;-webkit-overflow-scrolling:touch}}@media (max-width:1199.98px){.table-responsive-xl{overflow-x:auto;-webkit-overflow-scrolling:touch}}@media (max-width:1399.98px){.table-responsive-xxl{overflow-x:auto;-webkit-overflow-scrolling:touch}}.form-label{margin-bottom:.5rem}.col-form-label{padding-top:calc(.375rem + var(--bs-border-width));padding-bottom:calc(.375rem + var(--bs-border-width));margin-bottom:0;font-size:inherit;line-height:1.5}.col-form-label-lg{padding-top:calc(.5rem + var(--bs-border-width));padding-bottom:calc(.5rem + var(--bs-border-width));font-size:1.25rem}.col-form-label-sm{padding-top:calc(.25rem + var(--bs-border-width));padding-bottom:calc(.25rem + var(--bs-border-width));font-size:.875rem}.form-text{margin-top:.25rem;font-size:.875em;color:var(--bs-secondary-color)}.form-control{display:block;width:100%;padding:.375rem .75rem;font-size:1rem;font-weight:400;line-height:1.5;color:var(--bs-body-color);-webkit-appearance:none;-moz-appearance:none;appearance:none;background-color:var(--bs-body-bg);background-clip:padding-box;border:var(--bs-border-width) solid var(--bs-border-color);border-radius:var(--bs-border-radius);transition:border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.form-control{transition:none}}.form-control[type=file]{overflow:hidden}.form-control[type=file]:not(:disabled):not([readonly]){cursor:pointer}.form-control:focus{color:var(--bs-body-color);background-color:var(--bs-body-bg);border-color:#86b7fe;outline:0;box-shadow:0 0 0 .25rem rgba(13,110,253,.25)}.form-control::-webkit-date-and-time-value{min-width:85px;height:1.5em;margin:0}.form-control::-webkit-datetime-edit{display:block;padding:0}.form-control::placeholder{color:var(--bs-secondary-color);opacity:1}.form-control:disabled{background-color:var(--bs-secondary-bg);opacity:1}.form-control::-webkit-file-upload-button{padding:.375rem .75rem;margin:-.375rem -.75rem;-webkit-margin-end:.75rem;margin-inline-end:.75rem;color:var(--bs-body-color);background-color:var(--bs-tertiary-bg);pointer-events:none;border-color:inherit;border-style:solid;border-width:0;border-inline-end-width:var(--bs-border-width);border-radius:0;-webkit-transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}.form-control::file-selector-button{padding:.375rem .75rem;margin:-.375rem -.75rem;-webkit-margin-end:.75rem;margin-inline-end:.75rem;color:var(--bs-body-color);background-color:var(--bs-tertiary-bg);pointer-events:none;border-color:inherit;border-style:solid;border-width:0;border-inline-end-width:var(--bs-border-width);border-radius:0;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.form-control::-webkit-file-upload-button{-webkit-transition:none;transition:none}.form-control::file-selector-button{transition:none}}.form-control:hover:not(:disabled):not([readonly])::-webkit-file-upload-button{background-color:var(--bs-secondary-bg)}.form-control:hover:not(:disabled):not([readonly])::file-selector-button{background-color:var(--bs-secondary-bg)}.form-control-plaintext{display:block;width:100%;padding:.375rem 0;margin-bottom:0;line-height:1.5;color:var(--bs-body-color);background-color:transparent;border:solid transparent;border-width:var(--bs-border-width) 0}.form-control-plaintext:focus{outline:0}.form-control-plaintext.form-control-lg,.form-control-plaintext.form-control-sm{padding-right:0;padding-left:0}.form-control-sm{min-height:calc(1.5em + .5rem + calc(var(--bs-border-width) * 2));padding:.25rem .5rem;font-size:.875rem;border-radius:var(--bs-border-radius-sm)}.form-control-sm::-webkit-file-upload-button{padding:.25rem .5rem;margin:-.25rem -.5rem;-webkit-margin-end:.5rem;margin-inline-end:.5rem}.form-control-sm::file-selector-button{padding:.25rem .5rem;margin:-.25rem -.5rem;-webkit-margin-end:.5rem;margin-inline-end:.5rem}.form-control-lg{min-height:calc(1.5em + 1rem + calc(var(--bs-border-width) * 2));padding:.5rem 1rem;font-size:1.25rem;border-radius:var(--bs-border-radius-lg)}.form-control-lg::-webkit-file-upload-button{padding:.5rem 1rem;margin:-.5rem -1rem;-webkit-margin-end:1rem;margin-inline-end:1rem}.form-control-lg::file-selector-button{padding:.5rem 1rem;margin:-.5rem -1rem;-webkit-margin-end:1rem;margin-inline-end:1rem}textarea.form-control{min-height:calc(1.5em + .75rem + calc(var(--bs-border-width) * 2))}textarea.form-control-sm{min-height:calc(1.5em + .5rem + calc(var(--bs-border-width) * 2))}textarea.form-control-lg{min-height:calc(1.5em + 1rem + calc(var(--bs-border-width) * 2))}.form-control-color{width:3rem;height:calc(1.5em + .75rem + calc(var(--bs-border-width) * 2));padding:.375rem}.form-control-color:not(:disabled):not([readonly]){cursor:pointer}.form-control-color::-moz-color-swatch{border:0!important;border-radius:var(--bs-border-radius)}.form-control-color::-webkit-color-swatch{border:0!important;border-radius:var(--bs-border-radius)}.form-control-color.form-control-sm{height:calc(1.5em + .5rem + calc(var(--bs-border-width) * 2))}.form-control-color.form-control-lg{height:calc(1.5em + 1rem + calc(var(--bs-border-width) * 2))}.form-select{--bs-form-select-bg-img:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%23343a40' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='m2 5 6 6 6-6'/%3e%3c/svg%3e");display:block;width:100%;padding:.375rem 2.25rem .375rem .75rem;font-size:1rem;font-weight:400;line-height:1.5;color:var(--bs-body-color);-webkit-appearance:none;-moz-appearance:none;appearance:none;background-color:var(--bs-body-bg);background-image:var(--bs-form-select-bg-img),var(--bs-form-select-bg-icon,none);background-repeat:no-repeat;background-position:right .75rem center;background-size:16px 12px;border:var(--bs-border-width) solid var(--bs-border-color);border-radius:var(--bs-border-radius);transition:border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.form-select{transition:none}}.form-select:focus{border-color:#86b7fe;outline:0;box-shadow:0 0 0 .25rem rgba(13,110,253,.25)}.form-select[multiple],.form-select[size]:not([size="1"]){padding-right:.75rem;background-image:none}.form-select:disabled{background-color:var(--bs-secondary-bg)}.form-select:-moz-focusring{color:transparent;text-shadow:0 0 0 var(--bs-body-color)}.form-select-sm{padding-top:.25rem;padding-bottom:.25rem;padding-left:.5rem;font-size:.875rem;border-radius:var(--bs-border-radius-sm)}.form-select-lg{padding-top:.5rem;padding-bottom:.5rem;padding-left:1rem;font-size:1.25rem;border-radius:var(--bs-border-radius-lg)}[data-bs-theme=dark] .form-select{--bs-form-select-bg-img:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%23dee2e6' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='m2 5 6 6 6-6'/%3e%3c/svg%3e")}.form-check{display:block;min-height:1.5rem;padding-left:1.5em;margin-bottom:.125rem}.form-check .form-check-input{float:left;margin-left:-1.5em}.form-check-reverse{padding-right:1.5em;padding-left:0;text-align:right}.form-check-reverse .form-check-input{float:right;margin-right:-1.5em;margin-left:0}.form-check-input{--bs-form-check-bg:var(--bs-body-bg);flex-shrink:0;width:1em;height:1em;margin-top:.25em;vertical-align:top;-webkit-appearance:none;-moz-appearance:none;appearance:none;background-color:var(--bs-form-check-bg);background-image:var(--bs-form-check-bg-image);background-repeat:no-repeat;background-position:center;background-size:contain;border:var(--bs-border-width) solid var(--bs-border-color);-webkit-print-color-adjust:exact;color-adjust:exact;print-color-adjust:exact}.form-check-input[type=checkbox]{border-radius:.25em}.form-check-input[type=radio]{border-radius:50%}.form-check-input:active{filter:brightness(90%)}.form-check-input:focus{border-color:#86b7fe;outline:0;box-shadow:0 0 0 .25rem rgba(13,110,253,.25)}.form-check-input:checked{background-color:#0d6efd;border-color:#0d6efd}.form-check-input:checked[type=checkbox]{--bs-form-check-bg-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3e%3cpath fill='none' stroke='%23fff' stroke-linecap='round' stroke-linejoin='round' stroke-width='3' d='m6 10 3 3 6-6'/%3e%3c/svg%3e")}.form-check-input:checked[type=radio]{--bs-form-check-bg-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='2' fill='%23fff'/%3e%3c/svg%3e")}.form-check-input[type=checkbox]:indeterminate{background-color:#0d6efd;border-color:#0d6efd;--bs-form-check-bg-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3e%3cpath fill='none' stroke='%23fff' stroke-linecap='round' stroke-linejoin='round' stroke-width='3' d='M6 10h8'/%3e%3c/svg%3e")}.form-check-input:disabled{pointer-events:none;filter:none;opacity:.5}.form-check-input:disabled~.form-check-label,.form-check-input[disabled]~.form-check-label{cursor:default;opacity:.5}.form-switch{padding-left:2.5em}.form-switch .form-check-input{--bs-form-switch-bg:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='rgba%280, 0, 0, 0.25%29'/%3e%3c/svg%3e");width:2em;margin-left:-2.5em;background-image:var(--bs-form-switch-bg);background-position:left center;border-radius:2em;transition:background-position .15s ease-in-out}@media (prefers-reduced-motion:reduce){.form-switch .form-check-input{transition:none}}.form-switch .form-check-input:focus{--bs-form-switch-bg:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='%2386b7fe'/%3e%3c/svg%3e")}.form-switch .form-check-input:checked{background-position:right center;--bs-form-switch-bg:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='%23fff'/%3e%3c/svg%3e")}.form-switch.form-check-reverse{padding-right:2.5em;padding-left:0}.form-switch.form-check-reverse .form-check-input{margin-right:-2.5em;margin-left:0}.form-check-inline{display:inline-block;margin-right:1rem}.btn-check{position:absolute;clip:rect(0,0,0,0);pointer-events:none}.btn-check:disabled+.btn,.btn-check[disabled]+.btn{pointer-events:none;filter:none;opacity:.65}[data-bs-theme=dark] .form-switch .form-check-input:not(:checked):not(:focus){--bs-form-switch-bg:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='rgba%28255, 255, 255, 0.25%29'/%3e%3c/svg%3e")}.form-range{width:100%;height:1.5rem;padding:0;-webkit-appearance:none;-moz-appearance:none;appearance:none;background-color:transparent}.form-range:focus{outline:0}.form-range:focus::-webkit-slider-thumb{box-shadow:0 0 0 1px #fff,0 0 0 .25rem rgba(13,110,253,.25)}.form-range:focus::-moz-range-thumb{box-shadow:0 0 0 1px #fff,0 0 0 .25rem rgba(13,110,253,.25)}.form-range::-moz-focus-outer{border:0}.form-range::-webkit-slider-thumb{width:1rem;height:1rem;margin-top:-.25rem;-webkit-appearance:none;appearance:none;background-color:#0d6efd;border:0;border-radius:1rem;-webkit-transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.form-range::-webkit-slider-thumb{-webkit-transition:none;transition:none}}.form-range::-webkit-slider-thumb:active{background-color:#b6d4fe}.form-range::-webkit-slider-runnable-track{width:100%;height:.5rem;color:transparent;cursor:pointer;background-color:var(--bs-secondary-bg);border-color:transparent;border-radius:1rem}.form-range::-moz-range-thumb{width:1rem;height:1rem;-moz-appearance:none;appearance:none;background-color:#0d6efd;border:0;border-radius:1rem;-moz-transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.form-range::-moz-range-thumb{-moz-transition:none;transition:none}}.form-range::-moz-range-thumb:active{background-color:#b6d4fe}.form-range::-moz-range-track{width:100%;height:.5rem;color:transparent;cursor:pointer;background-color:var(--bs-secondary-bg);border-color:transparent;border-radius:1rem}.form-range:disabled{pointer-events:none}.form-range:disabled::-webkit-slider-thumb{background-color:var(--bs-secondary-color)}.form-range:disabled::-moz-range-thumb{background-color:var(--bs-secondary-color)}.form-floating{position:relative}.form-floating>.form-control,.form-floating>.form-control-plaintext,.form-floating>.form-select{height:calc(3.5rem + calc(var(--bs-border-width) * 2));min-height:calc(3.5rem + calc(var(--bs-border-width) * 2));line-height:1.25}.form-floating>label{position:absolute;top:0;left:0;z-index:2;max-width:100%;height:100%;padding:1rem .75rem;overflow:hidden;color:rgba(var(--bs-body-color-rgb),.65);text-align:start;text-overflow:ellipsis;white-space:nowrap;pointer-events:none;border:var(--bs-border-width) solid transparent;transform-origin:0 0;transition:opacity .1s ease-in-out,transform .1s ease-in-out}@media (prefers-reduced-motion:reduce){.form-floating>label{transition:none}}.form-floating>.form-control,.form-floating>.form-control-plaintext{padding:1rem .75rem}.form-floating>.form-control-plaintext::placeholder,.form-floating>.form-control::placeholder{color:transparent}.form-floating>.form-control-plaintext:focus,.form-floating>.form-control-plaintext:not(:placeholder-shown),.form-floating>.form-control:focus,.form-floating>.form-control:not(:placeholder-shown){padding-top:1.625rem;padding-bottom:.625rem}.form-floating>.form-control-plaintext:-webkit-autofill,.form-floating>.form-control:-webkit-autofill{padding-top:1.625rem;padding-bottom:.625rem}.form-floating>.form-select{padding-top:1.625rem;padding-bottom:.625rem;padding-left:.75rem}.form-floating>.form-control-plaintext~label,.form-floating>.form-control:focus~label,.form-floating>.form-control:not(:placeholder-shown)~label,.form-floating>.form-select~label{transform:scale(.85) translateY(-.5rem) translateX(.15rem)}.form-floating>.form-control:-webkit-autofill~label{transform:scale(.85) translateY(-.5rem) translateX(.15rem)}.form-floating>textarea:focus~label::after,.form-floating>textarea:not(:placeholder-shown)~label::after{position:absolute;inset:1rem 0.375rem;z-index:-1;height:1.5em;content:"";background-color:var(--bs-body-bg);border-radius:var(--bs-border-radius)}.form-floating>textarea:disabled~label::after{background-color:var(--bs-secondary-bg)}.form-floating>.form-control-plaintext~label{border-width:var(--bs-border-width) 0}.form-floating>.form-control:disabled~label,.form-floating>:disabled~label{color:#6c757d}.input-group{position:relative;display:flex;flex-wrap:wrap;align-items:stretch;width:100%}.input-group>.form-control,.input-group>.form-floating,.input-group>.form-select{position:relative;flex:1 1 auto;width:1%;min-width:0}.input-group>.form-control:focus,.input-group>.form-floating:focus-within,.input-group>.form-select:focus{z-index:5}.input-group .btn{position:relative;z-index:2}.input-group .btn:focus{z-index:5}.input-group-text{display:flex;align-items:center;padding:.375rem .75rem;font-size:1rem;font-weight:400;line-height:1.5;color:var(--bs-body-color);text-align:center;white-space:nowrap;background-color:var(--bs-tertiary-bg);border:var(--bs-border-width) solid var(--bs-border-color);border-radius:var(--bs-border-radius)}.input-group-lg>.btn,.input-group-lg>.form-control,.input-group-lg>.form-select,.input-group-lg>.input-group-text{padding:.5rem 1rem;font-size:1.25rem;border-radius:var(--bs-border-radius-lg)}.input-group-sm>.btn,.input-group-sm>.form-control,.input-group-sm>.form-select,.input-group-sm>.input-group-text{padding:.25rem .5rem;font-size:.875rem;border-radius:var(--bs-border-radius-sm)}.input-group-lg>.form-select,.input-group-sm>.form-select{padding-right:3rem}.input-group:not(.has-validation)>.dropdown-toggle:nth-last-child(n+3),.input-group:not(.has-validation)>.form-floating:not(:last-child)>.form-control,.input-group:not(.has-validation)>.form-floating:not(:last-child)>.form-select,.input-group:not(.has-validation)>:not(:last-child):not(.dropdown-toggle):not(.dropdown-menu):not(.form-floating){border-top-right-radius:0;border-bottom-right-radius:0}.input-group.has-validation>.dropdown-toggle:nth-last-child(n+4),.input-group.has-validation>.form-floating:nth-last-child(n+3)>.form-control,.input-group.has-validation>.form-floating:nth-last-child(n+3)>.form-select,.input-group.has-validation>:nth-last-child(n+3):not(.dropdown-toggle):not(.dropdown-menu):not(.form-floating){border-top-right-radius:0;border-bottom-right-radius:0}.input-group>:not(:first-child):not(.dropdown-menu):not(.valid-tooltip):not(.valid-feedback):not(.invalid-tooltip):not(.invalid-feedback){margin-left:calc(-1 * var(--bs-border-width));border-top-left-radius:0;border-bottom-left-radius:0}.input-group>.form-floating:not(:first-child)>.form-control,.input-group>.form-floating:not(:first-child)>.form-select{border-top-left-radius:0;border-bottom-left-radius:0}.valid-feedback{display:none;width:100%;margin-top:.25rem;font-size:.875em;color:var(--bs-form-valid-color)}.valid-tooltip{position:absolute;top:100%;z-index:5;display:none;max-width:100%;padding:.25rem .5rem;margin-top:.1rem;font-size:.875rem;color:#fff;background-color:var(--bs-success);border-radius:var(--bs-border-radius)}.is-valid~.valid-feedback,.is-valid~.valid-tooltip,.was-validated :valid~.valid-feedback,.was-validated :valid~.valid-tooltip{display:block}.form-control.is-valid,.was-validated .form-control:valid{border-color:var(--bs-form-valid-border-color);padding-right:calc(1.5em + .75rem);background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3e%3cpath fill='%23198754' d='M2.3 6.73.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1'/%3e%3c/svg%3e");background-repeat:no-repeat;background-position:right calc(.375em + .1875rem) center;background-size:calc(.75em + .375rem) calc(.75em + .375rem)}.form-control.is-valid:focus,.was-validated .form-control:valid:focus{border-color:var(--bs-form-valid-border-color);box-shadow:0 0 0 .25rem rgba(var(--bs-success-rgb),.25)}.was-validated textarea.form-control:valid,textarea.form-control.is-valid{padding-right:calc(1.5em + .75rem);background-position:top calc(.375em + .1875rem) right calc(.375em + .1875rem)}.form-select.is-valid,.was-validated .form-select:valid{border-color:var(--bs-form-valid-border-color)}.form-select.is-valid:not([multiple]):not([size]),.form-select.is-valid:not([multiple])[size="1"],.was-validated .form-select:valid:not([multiple]):not([size]),.was-validated .form-select:valid:not([multiple])[size="1"]{--bs-form-select-bg-icon:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3e%3cpath fill='%23198754' d='M2.3 6.73.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1'/%3e%3c/svg%3e");padding-right:4.125rem;background-position:right .75rem center,center right 2.25rem;background-size:16px 12px,calc(.75em + .375rem) calc(.75em + .375rem)}.form-select.is-valid:focus,.was-validated .form-select:valid:focus{border-color:var(--bs-form-valid-border-color);box-shadow:0 0 0 .25rem rgba(var(--bs-success-rgb),.25)}.form-control-color.is-valid,.was-validated .form-control-color:valid{width:calc(3rem + calc(1.5em + .75rem))}.form-check-input.is-valid,.was-validated .form-check-input:valid{border-color:var(--bs-form-valid-border-color)}.form-check-input.is-valid:checked,.was-validated .form-check-input:valid:checked{background-color:var(--bs-form-valid-color)}.form-check-input.is-valid:focus,.was-validated .form-check-input:valid:focus{box-shadow:0 0 0 .25rem rgba(var(--bs-success-rgb),.25)}.form-check-input.is-valid~.form-check-label,.was-validated .form-check-input:valid~.form-check-label{color:var(--bs-form-valid-color)}.form-check-inline .form-check-input~.valid-feedback{margin-left:.5em}.input-group>.form-control:not(:focus).is-valid,.input-group>.form-floating:not(:focus-within).is-valid,.input-group>.form-select:not(:focus).is-valid,.was-validated .input-group>.form-control:not(:focus):valid,.was-validated .input-group>.form-floating:not(:focus-within):valid,.was-validated .input-group>.form-select:not(:focus):valid{z-index:3}.invalid-feedback{display:none;width:100%;margin-top:.25rem;font-size:.875em;color:var(--bs-form-invalid-color)}.invalid-tooltip{position:absolute;top:100%;z-index:5;display:none;max-width:100%;padding:.25rem .5rem;margin-top:.1rem;font-size:.875rem;color:#fff;background-color:var(--bs-danger);border-radius:var(--bs-border-radius)}.is-invalid~.invalid-feedback,.is-invalid~.invalid-tooltip,.was-validated :invalid~.invalid-feedback,.was-validated :invalid~.invalid-tooltip{display:block}.form-control.is-invalid,.was-validated .form-control:invalid{border-color:var(--bs-form-invalid-border-color);padding-right:calc(1.5em + .75rem);background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12' width='12' height='12' fill='none' stroke='%23dc3545'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%23dc3545' stroke='none'/%3e%3c/svg%3e");background-repeat:no-repeat;background-position:right calc(.375em + .1875rem) center;background-size:calc(.75em + .375rem) calc(.75em + .375rem)}.form-control.is-invalid:focus,.was-validated .form-control:invalid:focus{border-color:var(--bs-form-invalid-border-color);box-shadow:0 0 0 .25rem rgba(var(--bs-danger-rgb),.25)}.was-validated textarea.form-control:invalid,textarea.form-control.is-invalid{padding-right:calc(1.5em + .75rem);background-position:top calc(.375em + .1875rem) right calc(.375em + .1875rem)}.form-select.is-invalid,.was-validated .form-select:invalid{border-color:var(--bs-form-invalid-border-color)}.form-select.is-invalid:not([multiple]):not([size]),.form-select.is-invalid:not([multiple])[size="1"],.was-validated .form-select:invalid:not([multiple]):not([size]),.was-validated .form-select:invalid:not([multiple])[size="1"]{--bs-form-select-bg-icon:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12' width='12' height='12' fill='none' stroke='%23dc3545'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%23dc3545' stroke='none'/%3e%3c/svg%3e");padding-right:4.125rem;background-position:right .75rem center,center right 2.25rem;background-size:16px 12px,calc(.75em + .375rem) calc(.75em + .375rem)}.form-select.is-invalid:focus,.was-validated .form-select:invalid:focus{border-color:var(--bs-form-invalid-border-color);box-shadow:0 0 0 .25rem rgba(var(--bs-danger-rgb),.25)}.form-control-color.is-invalid,.was-validated .form-control-color:invalid{width:calc(3rem + calc(1.5em + .75rem))}.form-check-input.is-invalid,.was-validated .form-check-input:invalid{border-color:var(--bs-form-invalid-border-color)}.form-check-input.is-invalid:checked,.was-validated .form-check-input:invalid:checked{background-color:var(--bs-form-invalid-color)}.form-check-input.is-invalid:focus,.was-validated .form-check-input:invalid:focus{box-shadow:0 0 0 .25rem rgba(var(--bs-danger-rgb),.25)}.form-check-input.is-invalid~.form-check-label,.was-validated .form-check-input:invalid~.form-check-label{color:var(--bs-form-invalid-color)}.form-check-inline .form-check-input~.invalid-feedback{margin-left:.5em}.input-group>.form-control:not(:focus).is-invalid,.input-group>.form-floating:not(:focus-within).is-invalid,.input-group>.form-select:not(:focus).is-invalid,.was-validated .input-group>.form-control:not(:focus):invalid,.was-validated .input-group>.form-floating:not(:focus-within):invalid,.was-validated .input-group>.form-select:not(:focus):invalid{z-index:4}.btn{--bs-btn-padding-x:0.75rem;--bs-btn-padding-y:0.375rem;--bs-btn-font-family: ;--bs-btn-font-size:1rem;--bs-btn-font-weight:400;--bs-btn-line-height:1.5;--bs-btn-color:var(--bs-body-color);--bs-btn-bg:transparent;--bs-btn-border-width:var(--bs-border-width);--bs-btn-border-color:transparent;--bs-btn-border-radius:var(--bs-border-radius);--bs-btn-hover-border-color:transparent;--bs-btn-box-shadow:inset 0 1px 0 rgba(255, 255, 255, 0.15),0 1px 1px rgba(0, 0, 0, 0.075);--bs-btn-disabled-opacity:0.65;--bs-btn-focus-box-shadow:0 0 0 0.25rem rgba(var(--bs-btn-focus-shadow-rgb), .5);display:inline-block;padding:var(--bs-btn-padding-y) var(--bs-btn-padding-x);font-family:var(--bs-btn-font-family);font-size:var(--bs-btn-font-size);font-weight:var(--bs-btn-font-weight);line-height:var(--bs-btn-line-height);color:var(--bs-btn-color);text-align:center;text-decoration:none;vertical-align:middle;cursor:pointer;-webkit-user-select:none;-moz-user-select:none;user-select:none;border:var(--bs-btn-border-width) solid var(--bs-btn-border-color);border-radius:var(--bs-btn-border-radius);background-color:var(--bs-btn-bg);transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.btn{transition:none}}.btn:hover{color:var(--bs-btn-hover-color);background-color:var(--bs-btn-hover-bg);border-color:var(--bs-btn-hover-border-color)}.btn-check+.btn:hover{color:var(--bs-btn-color);background-color:var(--bs-btn-bg);border-color:var(--bs-btn-border-color)}.btn:focus-visible{color:var(--bs-btn-hover-color);background-color:var(--bs-btn-hover-bg);border-color:var(--bs-btn-hover-border-color);outline:0;box-shadow:var(--bs-btn-focus-box-shadow)}.btn-check:focus-visible+.btn{border-color:var(--bs-btn-hover-border-color);outline:0;box-shadow:var(--bs-btn-focus-box-shadow)}.btn-check:checked+.btn,.btn.active,.btn.show,.btn:first-child:active,:not(.btn-check)+.btn:active{color:var(--bs-btn-active-color);background-color:var(--bs-btn-active-bg);border-color:var(--bs-btn-active-border-color)}.btn-check:checked+.btn:focus-visible,.btn.active:focus-visible,.btn.show:focus-visible,.btn:first-child:active:focus-visible,:not(.btn-check)+.btn:active:focus-visible{box-shadow:var(--bs-btn-focus-box-shadow)}.btn-check:checked:focus-visible+.btn{box-shadow:var(--bs-btn-focus-box-shadow)}.btn.disabled,.btn:disabled,fieldset:disabled .btn{color:var(--bs-btn-disabled-color);pointer-events:none;background-color:var(--bs-btn-disabled-bg);border-color:var(--bs-btn-disabled-border-color);opacity:var(--bs-btn-disabled-opacity)}.btn-primary{--bs-btn-color:#fff;--bs-btn-bg:#0d6efd;--bs-btn-border-color:#0d6efd;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#0b5ed7;--bs-btn-hover-border-color:#0a58ca;--bs-btn-focus-shadow-rgb:49,132,253;--bs-btn-active-color:#fff;--bs-btn-active-bg:#0a58ca;--bs-btn-active-border-color:#0a53be;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#fff;--bs-btn-disabled-bg:#0d6efd;--bs-btn-disabled-border-color:#0d6efd}.btn-secondary{--bs-btn-color:#fff;--bs-btn-bg:#6c757d;--bs-btn-border-color:#6c757d;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#5c636a;--bs-btn-hover-border-color:#565e64;--bs-btn-focus-shadow-rgb:130,138,145;--bs-btn-active-color:#fff;--bs-btn-active-bg:#565e64;--bs-btn-active-border-color:#51585e;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#fff;--bs-btn-disabled-bg:#6c757d;--bs-btn-disabled-border-color:#6c757d}.btn-success{--bs-btn-color:#fff;--bs-btn-bg:#198754;--bs-btn-border-color:#198754;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#157347;--bs-btn-hover-border-color:#146c43;--bs-btn-focus-shadow-rgb:60,153,110;--bs-btn-active-color:#fff;--bs-btn-active-bg:#146c43;--bs-btn-active-border-color:#13653f;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#fff;--bs-btn-disabled-bg:#198754;--bs-btn-disabled-border-color:#198754}.btn-info{--bs-btn-color:#000;--bs-btn-bg:#0dcaf0;--bs-btn-border-color:#0dcaf0;--bs-btn-hover-color:#000;--bs-btn-hover-bg:#31d2f2;--bs-btn-hover-border-color:#25cff2;--bs-btn-focus-shadow-rgb:11,172,204;--bs-btn-active-color:#000;--bs-btn-active-bg:#3dd5f3;--bs-btn-active-border-color:#25cff2;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#000;--bs-btn-disabled-bg:#0dcaf0;--bs-btn-disabled-border-color:#0dcaf0}.btn-warning{--bs-btn-color:#000;--bs-btn-bg:#ffc107;--bs-btn-border-color:#ffc107;--bs-btn-hover-color:#000;--bs-btn-hover-bg:#ffca2c;--bs-btn-hover-border-color:#ffc720;--bs-btn-focus-shadow-rgb:217,164,6;--bs-btn-active-color:#000;--bs-btn-active-bg:#ffcd39;--bs-btn-active-border-color:#ffc720;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#000;--bs-btn-disabled-bg:#ffc107;--bs-btn-disabled-border-color:#ffc107}.btn-danger{--bs-btn-color:#fff;--bs-btn-bg:#dc3545;--bs-btn-border-color:#dc3545;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#bb2d3b;--bs-btn-hover-border-color:#b02a37;--bs-btn-focus-shadow-rgb:225,83,97;--bs-btn-active-color:#fff;--bs-btn-active-bg:#b02a37;--bs-btn-active-border-color:#a52834;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#fff;--bs-btn-disabled-bg:#dc3545;--bs-btn-disabled-border-color:#dc3545}.btn-light{--bs-btn-color:#000;--bs-btn-bg:#f8f9fa;--bs-btn-border-color:#f8f9fa;--bs-btn-hover-color:#000;--bs-btn-hover-bg:#d3d4d5;--bs-btn-hover-border-color:#c6c7c8;--bs-btn-focus-shadow-rgb:211,212,213;--bs-btn-active-color:#000;--bs-btn-active-bg:#c6c7c8;--bs-btn-active-border-color:#babbbc;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#000;--bs-btn-disabled-bg:#f8f9fa;--bs-btn-disabled-border-color:#f8f9fa}.btn-dark{--bs-btn-color:#fff;--bs-btn-bg:#212529;--bs-btn-border-color:#212529;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#424649;--bs-btn-hover-border-color:#373b3e;--bs-btn-focus-shadow-rgb:66,70,73;--bs-btn-active-color:#fff;--bs-btn-active-bg:#4d5154;--bs-btn-active-border-color:#373b3e;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#fff;--bs-btn-disabled-bg:#212529;--bs-btn-disabled-border-color:#212529}.btn-outline-primary{--bs-btn-color:#0d6efd;--bs-btn-border-color:#0d6efd;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#0d6efd;--bs-btn-hover-border-color:#0d6efd;--bs-btn-focus-shadow-rgb:13,110,253;--bs-btn-active-color:#fff;--bs-btn-active-bg:#0d6efd;--bs-btn-active-border-color:#0d6efd;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#0d6efd;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#0d6efd;--bs-gradient:none}.btn-outline-secondary{--bs-btn-color:#6c757d;--bs-btn-border-color:#6c757d;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#6c757d;--bs-btn-hover-border-color:#6c757d;--bs-btn-focus-shadow-rgb:108,117,125;--bs-btn-active-color:#fff;--bs-btn-active-bg:#6c757d;--bs-btn-active-border-color:#6c757d;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#6c757d;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#6c757d;--bs-gradient:none}.btn-outline-success{--bs-btn-color:#198754;--bs-btn-border-color:#198754;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#198754;--bs-btn-hover-border-color:#198754;--bs-btn-focus-shadow-rgb:25,135,84;--bs-btn-active-color:#fff;--bs-btn-active-bg:#198754;--bs-btn-active-border-color:#198754;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#198754;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#198754;--bs-gradient:none}.btn-outline-info{--bs-btn-color:#0dcaf0;--bs-btn-border-color:#0dcaf0;--bs-btn-hover-color:#000;--bs-btn-hover-bg:#0dcaf0;--bs-btn-hover-border-color:#0dcaf0;--bs-btn-focus-shadow-rgb:13,202,240;--bs-btn-active-color:#000;--bs-btn-active-bg:#0dcaf0;--bs-btn-active-border-color:#0dcaf0;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#0dcaf0;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#0dcaf0;--bs-gradient:none}.btn-outline-warning{--bs-btn-color:#ffc107;--bs-btn-border-color:#ffc107;--bs-btn-hover-color:#000;--bs-btn-hover-bg:#ffc107;--bs-btn-hover-border-color:#ffc107;--bs-btn-focus-shadow-rgb:255,193,7;--bs-btn-active-color:#000;--bs-btn-active-bg:#ffc107;--bs-btn-active-border-color:#ffc107;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#ffc107;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#ffc107;--bs-gradient:none}.btn-outline-danger{--bs-btn-color:#dc3545;--bs-btn-border-color:#dc3545;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#dc3545;--bs-btn-hover-border-color:#dc3545;--bs-btn-focus-shadow-rgb:220,53,69;--bs-btn-active-color:#fff;--bs-btn-active-bg:#dc3545;--bs-btn-active-border-color:#dc3545;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#dc3545;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#dc3545;--bs-gradient:none}.btn-outline-light{--bs-btn-color:#f8f9fa;--bs-btn-border-color:#f8f9fa;--bs-btn-hover-color:#000;--bs-btn-hover-bg:#f8f9fa;--bs-btn-hover-border-color:#f8f9fa;--bs-btn-focus-shadow-rgb:248,249,250;--bs-btn-active-color:#000;--bs-btn-active-bg:#f8f9fa;--bs-btn-active-border-color:#f8f9fa;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#f8f9fa;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#f8f9fa;--bs-gradient:none}.btn-outline-dark{--bs-btn-color:#212529;--bs-btn-border-color:#212529;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#212529;--bs-btn-hover-border-color:#212529;--bs-btn-focus-shadow-rgb:33,37,41;--bs-btn-active-color:#fff;--bs-btn-active-bg:#212529;--bs-btn-active-border-color:#212529;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#212529;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#212529;--bs-gradient:none}.btn-link{--bs-btn-font-weight:400;--bs-btn-color:var(--bs-link-color);--bs-btn-bg:transparent;--bs-btn-border-color:transparent;--bs-btn-hover-color:var(--bs-link-hover-color);--bs-btn-hover-border-color:transparent;--bs-btn-active-color:var(--bs-link-hover-color);--bs-btn-active-border-color:transparent;--bs-btn-disabled-color:#6c757d;--bs-btn-disabled-border-color:transparent;--bs-btn-box-shadow:0 0 0 #000;--bs-btn-focus-shadow-rgb:49,132,253;text-decoration:underline}.btn-link:focus-visible{color:var(--bs-btn-color)}.btn-link:hover{color:var(--bs-btn-hover-color)}.btn-group-lg>.btn,.btn-lg{--bs-btn-padding-y:0.5rem;--bs-btn-padding-x:1rem;--bs-btn-font-size:1.25rem;--bs-btn-border-radius:var(--bs-border-radius-lg)}.btn-group-sm>.btn,.btn-sm{--bs-btn-padding-y:0.25rem;--bs-btn-padding-x:0.5rem;--bs-btn-font-size:0.875rem;--bs-btn-border-radius:var(--bs-border-radius-sm)}.fade{transition:opacity .15s linear}@media (prefers-reduced-motion:reduce){.fade{transition:none}}.fade:not(.show){opacity:0}.collapse:not(.show){display:none}.collapsing{height:0;overflow:hidden;transition:height .35s ease}@media (prefers-reduced-motion:reduce){.collapsing{transition:none}}.collapsing.collapse-horizontal{width:0;height:auto;transition:width .35s ease}@media (prefers-reduced-motion:reduce){.collapsing.collapse-horizontal{transition:none}}.dropdown,.dropdown-center,.dropend,.dropstart,.dropup,.dropup-center{position:relative}.dropdown-toggle{white-space:nowrap}.dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:"";border-top:.3em solid;border-right:.3em solid transparent;border-bottom:0;border-left:.3em solid transparent}.dropdown-toggle:empty::after{margin-left:0}.dropdown-menu{--bs-dropdown-zindex:1000;--bs-dropdown-min-width:10rem;--bs-dropdown-padding-x:0;--bs-dropdown-padding-y:0.5rem;--bs-dropdown-spacer:0.125rem;--bs-dropdown-font-size:1rem;--bs-dropdown-color:var(--bs-body-color);--bs-dropdown-bg:var(--bs-body-bg);--bs-dropdown-border-color:var(--bs-border-color-translucent);--bs-dropdown-border-radius:var(--bs-border-radius);--bs-dropdown-border-width:var(--bs-border-width);--bs-dropdown-inner-border-radius:calc(var(--bs-border-radius) - var(--bs-border-width));--bs-dropdown-divider-bg:var(--bs-border-color-translucent);--bs-dropdown-divider-margin-y:0.5rem;--bs-dropdown-box-shadow:var(--bs-box-shadow);--bs-dropdown-link-color:var(--bs-body-color);--bs-dropdown-link-hover-color:var(--bs-body-color);--bs-dropdown-link-hover-bg:var(--bs-tertiary-bg);--bs-dropdown-link-active-color:#fff;--bs-dropdown-link-active-bg:#0d6efd;--bs-dropdown-link-disabled-color:var(--bs-tertiary-color);--bs-dropdown-item-padding-x:1rem;--bs-dropdown-item-padding-y:0.25rem;--bs-dropdown-header-color:#6c757d;--bs-dropdown-header-padding-x:1rem;--bs-dropdown-header-padding-y:0.5rem;position:absolute;z-index:var(--bs-dropdown-zindex);display:none;min-width:var(--bs-dropdown-min-width);padding:var(--bs-dropdown-padding-y) var(--bs-dropdown-padding-x);margin:0;font-size:var(--bs-dropdown-font-size);color:var(--bs-dropdown-color);text-align:left;list-style:none;background-color:var(--bs-dropdown-bg);background-clip:padding-box;border:var(--bs-dropdown-border-width) solid var(--bs-dropdown-border-color);border-radius:var(--bs-dropdown-border-radius)}.dropdown-menu[data-bs-popper]{top:100%;left:0;margin-top:var(--bs-dropdown-spacer)}.dropdown-menu-start{--bs-position:start}.dropdown-menu-start[data-bs-popper]{right:auto;left:0}.dropdown-menu-end{--bs-position:end}.dropdown-menu-end[data-bs-popper]{right:0;left:auto}@media (min-width:576px){.dropdown-menu-sm-start{--bs-position:start}.dropdown-menu-sm-start[data-bs-popper]{right:auto;left:0}.dropdown-menu-sm-end{--bs-position:end}.dropdown-menu-sm-end[data-bs-popper]{right:0;left:auto}}@media (min-width:768px){.dropdown-menu-md-start{--bs-position:start}.dropdown-menu-md-start[data-bs-popper]{right:auto;left:0}.dropdown-menu-md-end{--bs-position:end}.dropdown-menu-md-end[data-bs-popper]{right:0;left:auto}}@media (min-width:992px){.dropdown-menu-lg-start{--bs-position:start}.dropdown-menu-lg-start[data-bs-popper]{right:auto;left:0}.dropdown-menu-lg-end{--bs-position:end}.dropdown-menu-lg-end[data-bs-popper]{right:0;left:auto}}@media (min-width:1200px){.dropdown-menu-xl-start{--bs-position:start}.dropdown-menu-xl-start[data-bs-popper]{right:auto;left:0}.dropdown-menu-xl-end{--bs-position:end}.dropdown-menu-xl-end[data-bs-popper]{right:0;left:auto}}@media (min-width:1400px){.dropdown-menu-xxl-start{--bs-position:start}.dropdown-menu-xxl-start[data-bs-popper]{right:auto;left:0}.dropdown-menu-xxl-end{--bs-position:end}.dropdown-menu-xxl-end[data-bs-popper]{right:0;left:auto}}.dropup .dropdown-menu[data-bs-popper]{top:auto;bottom:100%;margin-top:0;margin-bottom:var(--bs-dropdown-spacer)}.dropup .dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:"";border-top:0;border-right:.3em solid transparent;border-bottom:.3em solid;border-left:.3em solid transparent}.dropup .dropdown-toggle:empty::after{margin-left:0}.dropend .dropdown-menu[data-bs-popper]{top:0;right:auto;left:100%;margin-top:0;margin-left:var(--bs-dropdown-spacer)}.dropend .dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:"";border-top:.3em solid transparent;border-right:0;border-bottom:.3em solid transparent;border-left:.3em solid}.dropend .dropdown-toggle:empty::after{margin-left:0}.dropend .dropdown-toggle::after{vertical-align:0}.dropstart .dropdown-menu[data-bs-popper]{top:0;right:100%;left:auto;margin-top:0;margin-right:var(--bs-dropdown-spacer)}.dropstart .dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:""}.dropstart .dropdown-toggle::after{display:none}.dropstart .dropdown-toggle::before{display:inline-block;margin-right:.255em;vertical-align:.255em;content:"";border-top:.3em solid transparent;border-right:.3em solid;border-bottom:.3em solid transparent}.dropstart .dropdown-toggle:empty::after{margin-left:0}.dropstart .dropdown-toggle::before{vertical-align:0}.dropdown-divider{height:0;margin:var(--bs-dropdown-divider-margin-y) 0;overflow:hidden;border-top:1px solid var(--bs-dropdown-divider-bg);opacity:1}.dropdown-item{display:block;width:100%;padding:var(--bs-dropdown-item-padding-y) var(--bs-dropdown-item-padding-x);clear:both;font-weight:400;color:var(--bs-dropdown-link-color);text-align:inherit;text-decoration:none;white-space:nowrap;background-color:transparent;border:0;border-radius:var(--bs-dropdown-item-border-radius,0)}.dropdown-item:focus,.dropdown-item:hover{color:var(--bs-dropdown-link-hover-color);background-color:var(--bs-dropdown-link-hover-bg)}.dropdown-item.active,.dropdown-item:active{color:var(--bs-dropdown-link-active-color);text-decoration:none;background-color:var(--bs-dropdown-link-active-bg)}.dropdown-item.disabled,.dropdown-item:disabled{color:var(--bs-dropdown-link-disabled-color);pointer-events:none;background-color:transparent}.dropdown-menu.show{display:block}.dropdown-header{display:block;padding:var(--bs-dropdown-header-padding-y) var(--bs-dropdown-header-padding-x);margin-bottom:0;font-size:.875rem;color:var(--bs-dropdown-header-color);white-space:nowrap}.dropdown-item-text{display:block;padding:var(--bs-dropdown-item-padding-y) var(--bs-dropdown-item-padding-x);color:var(--bs-dropdown-link-color)}.dropdown-menu-dark{--bs-dropdown-color:#dee2e6;--bs-dropdown-bg:#343a40;--bs-dropdown-border-color:var(--bs-border-color-translucent);--bs-dropdown-box-shadow: ;--bs-dropdown-link-color:#dee2e6;--bs-dropdown-link-hover-color:#fff;--bs-dropdown-divider-bg:var(--bs-border-color-translucent);--bs-dropdown-link-hover-bg:rgba(255, 255, 255, 0.15);--bs-dropdown-link-active-color:#fff;--bs-dropdown-link-active-bg:#0d6efd;--bs-dropdown-link-disabled-color:#adb5bd;--bs-dropdown-header-color:#adb5bd}.btn-group,.btn-group-vertical{position:relative;display:inline-flex;vertical-align:middle}.btn-group-vertical>.btn,.btn-group>.btn{position:relative;flex:1 1 auto}.btn-group-vertical>.btn-check:checked+.btn,.btn-group-vertical>.btn-check:focus+.btn,.btn-group-vertical>.btn.active,.btn-group-vertical>.btn:active,.btn-group-vertical>.btn:focus,.btn-group-vertical>.btn:hover,.btn-group>.btn-check:checked+.btn,.btn-group>.btn-check:focus+.btn,.btn-group>.btn.active,.btn-group>.btn:active,.btn-group>.btn:focus,.btn-group>.btn:hover{z-index:1}.btn-toolbar{display:flex;flex-wrap:wrap;justify-content:flex-start}.btn-toolbar .input-group{width:auto}.btn-group{border-radius:var(--bs-border-radius)}.btn-group>.btn-group:not(:first-child),.btn-group>:not(.btn-check:first-child)+.btn{margin-left:calc(-1 * var(--bs-border-width))}.btn-group>.btn-group:not(:last-child)>.btn,.btn-group>.btn.dropdown-toggle-split:first-child,.btn-group>.btn:not(:last-child):not(.dropdown-toggle){border-top-right-radius:0;border-bottom-right-radius:0}.btn-group>.btn-group:not(:first-child)>.btn,.btn-group>.btn:nth-child(n+3),.btn-group>:not(.btn-check)+.btn{border-top-left-radius:0;border-bottom-left-radius:0}.dropdown-toggle-split{padding-right:.5625rem;padding-left:.5625rem}.dropdown-toggle-split::after,.dropend .dropdown-toggle-split::after,.dropup .dropdown-toggle-split::after{margin-left:0}.dropstart .dropdown-toggle-split::before{margin-right:0}.btn-group-sm>.btn+.dropdown-toggle-split,.btn-sm+.dropdown-toggle-split{padding-right:.375rem;padding-left:.375rem}.btn-group-lg>.btn+.dropdown-toggle-split,.btn-lg+.dropdown-toggle-split{padding-right:.75rem;padding-left:.75rem}.btn-group-vertical{flex-direction:column;align-items:flex-start;justify-content:center}.btn-group-vertical>.btn,.btn-group-vertical>.btn-group{width:100%}.btn-group-vertical>.btn-group:not(:first-child),.btn-group-vertical>.btn:not(:first-child){margin-top:calc(-1 * var(--bs-border-width))}.btn-group-vertical>.btn-group:not(:last-child)>.btn,.btn-group-vertical>.btn:not(:last-child):not(.dropdown-toggle){border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn-group:not(:first-child)>.btn,.btn-group-vertical>.btn:nth-child(n+3),.btn-group-vertical>:not(.btn-check)+.btn{border-top-left-radius:0;border-top-right-radius:0}.nav{--bs-nav-link-padding-x:1rem;--bs-nav-link-padding-y:0.5rem;--bs-nav-link-font-weight: ;--bs-nav-link-color:var(--bs-link-color);--bs-nav-link-hover-color:var(--bs-link-hover-color);--bs-nav-link-disabled-color:var(--bs-secondary-color);display:flex;flex-wrap:wrap;padding-left:0;margin-bottom:0;list-style:none}.nav-link{display:block;padding:var(--bs-nav-link-padding-y) var(--bs-nav-link-padding-x);font-size:var(--bs-nav-link-font-size);font-weight:var(--bs-nav-link-font-weight);color:var(--bs-nav-link-color);text-decoration:none;background:0 0;border:0;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out}@media (prefers-reduced-motion:reduce){.nav-link{transition:none}}.nav-link:focus,.nav-link:hover{color:var(--bs-nav-link-hover-color)}.nav-link:focus-visible{outline:0;box-shadow:0 0 0 .25rem rgba(13,110,253,.25)}.nav-link.disabled,.nav-link:disabled{color:var(--bs-nav-link-disabled-color);pointer-events:none;cursor:default}.nav-tabs{--bs-nav-tabs-border-width:var(--bs-border-width);--bs-nav-tabs-border-color:var(--bs-border-color);--bs-nav-tabs-border-radius:var(--bs-border-radius);--bs-nav-tabs-link-hover-border-color:var(--bs-secondary-bg) var(--bs-secondary-bg) var(--bs-border-color);--bs-nav-tabs-link-active-color:var(--bs-emphasis-color);--bs-nav-tabs-link-active-bg:var(--bs-body-bg);--bs-nav-tabs-link-active-border-color:var(--bs-border-color) var(--bs-border-color) var(--bs-body-bg);border-bottom:var(--bs-nav-tabs-border-width) solid var(--bs-nav-tabs-border-color)}.nav-tabs .nav-link{margin-bottom:calc(-1 * var(--bs-nav-tabs-border-width));border:var(--bs-nav-tabs-border-width) solid transparent;border-top-left-radius:var(--bs-nav-tabs-border-radius);border-top-right-radius:var(--bs-nav-tabs-border-radius)}.nav-tabs .nav-link:focus,.nav-tabs .nav-link:hover{isolation:isolate;border-color:var(--bs-nav-tabs-link-hover-border-color)}.nav-tabs .nav-item.show .nav-link,.nav-tabs .nav-link.active{color:var(--bs-nav-tabs-link-active-color);background-color:var(--bs-nav-tabs-link-active-bg);border-color:var(--bs-nav-tabs-link-active-border-color)}.nav-tabs .dropdown-menu{margin-top:calc(-1 * var(--bs-nav-tabs-border-width));border-top-left-radius:0;border-top-right-radius:0}.nav-pills{--bs-nav-pills-border-radius:var(--bs-border-radius);--bs-nav-pills-link-active-color:#fff;--bs-nav-pills-link-active-bg:#0d6efd}.nav-pills .nav-link{border-radius:var(--bs-nav-pills-border-radius)}.nav-pills .nav-link.active,.nav-pills .show>.nav-link{color:var(--bs-nav-pills-link-active-color);background-color:var(--bs-nav-pills-link-active-bg)}.nav-underline{--bs-nav-underline-gap:1rem;--bs-nav-underline-border-width:0.125rem;--bs-nav-underline-link-active-color:var(--bs-emphasis-color);gap:var(--bs-nav-underline-gap)}.nav-underline .nav-link{padding-right:0;padding-left:0;border-bottom:var(--bs-nav-underline-border-width) solid transparent}.nav-underline .nav-link:focus,.nav-underline .nav-link:hover{border-bottom-color:currentcolor}.nav-underline .nav-link.active,.nav-underline .show>.nav-link{font-weight:700;color:var(--bs-nav-underline-link-active-color);border-bottom-color:currentcolor}.nav-fill .nav-item,.nav-fill>.nav-link{flex:1 1 auto;text-align:center}.nav-justified .nav-item,.nav-justified>.nav-link{flex-grow:1;flex-basis:0;text-align:center}.nav-fill .nav-item .nav-link,.nav-justified .nav-item .nav-link{width:100%}.tab-content>.tab-pane{display:none}.tab-content>.active{display:block}.navbar{--bs-navbar-padding-x:0;--bs-navbar-padding-y:0.5rem;--bs-navbar-color:rgba(var(--bs-emphasis-color-rgb), 0.65);--bs-navbar-hover-color:rgba(var(--bs-emphasis-color-rgb), 0.8);--bs-navbar-disabled-color:rgba(var(--bs-emphasis-color-rgb), 0.3);--bs-navbar-active-color:rgba(var(--bs-emphasis-color-rgb), 1);--bs-navbar-brand-padding-y:0.3125rem;--bs-navbar-brand-margin-end:1rem;--bs-navbar-brand-font-size:1.25rem;--bs-navbar-brand-color:rgba(var(--bs-emphasis-color-rgb), 1);--bs-navbar-brand-hover-color:rgba(var(--bs-emphasis-color-rgb), 1);--bs-navbar-nav-link-padding-x:0.5rem;--bs-navbar-toggler-padding-y:0.25rem;--bs-navbar-toggler-padding-x:0.75rem;--bs-navbar-toggler-font-size:1.25rem;--bs-navbar-toggler-icon-bg:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 30 30'%3e%3cpath stroke='rgba%2833, 37, 41, 0.75%29' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e");--bs-navbar-toggler-border-color:rgba(var(--bs-emphasis-color-rgb), 0.15);--bs-navbar-toggler-border-radius:var(--bs-border-radius);--bs-navbar-toggler-focus-width:0.25rem;--bs-navbar-toggler-transition:box-shadow 0.15s ease-in-out;position:relative;display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;padding:var(--bs-navbar-padding-y) var(--bs-navbar-padding-x)}.navbar>.container,.navbar>.container-fluid,.navbar>.container-lg,.navbar>.container-md,.navbar>.container-sm,.navbar>.container-xl,.navbar>.container-xxl{display:flex;flex-wrap:inherit;align-items:center;justify-content:space-between}.navbar-brand{padding-top:var(--bs-navbar-brand-padding-y);padding-bottom:var(--bs-navbar-brand-padding-y);margin-right:var(--bs-navbar-brand-margin-end);font-size:var(--bs-navbar-brand-font-size);color:var(--bs-navbar-brand-color);text-decoration:none;white-space:nowrap}.navbar-brand:focus,.navbar-brand:hover{color:var(--bs-navbar-brand-hover-color)}.navbar-nav{--bs-nav-link-padding-x:0;--bs-nav-link-padding-y:0.5rem;--bs-nav-link-font-weight: ;--bs-nav-link-color:var(--bs-navbar-color);--bs-nav-link-hover-color:var(--bs-navbar-hover-color);--bs-nav-link-disabled-color:var(--bs-navbar-disabled-color);display:flex;flex-direction:column;padding-left:0;margin-bottom:0;list-style:none}.navbar-nav .nav-link.active,.navbar-nav .nav-link.show{color:var(--bs-navbar-active-color)}.navbar-nav .dropdown-menu{position:static}.navbar-text{padding-top:.5rem;padding-bottom:.5rem;color:var(--bs-navbar-color)}.navbar-text a,.navbar-text a:focus,.navbar-text a:hover{color:var(--bs-navbar-active-color)}.navbar-collapse{flex-grow:1;flex-basis:100%;align-items:center}.navbar-toggler{padding:var(--bs-navbar-toggler-padding-y) var(--bs-navbar-toggler-padding-x);font-size:var(--bs-navbar-toggler-font-size);line-height:1;color:var(--bs-navbar-color);background-color:transparent;border:var(--bs-border-width) solid var(--bs-navbar-toggler-border-color);border-radius:var(--bs-navbar-toggler-border-radius);transition:var(--bs-navbar-toggler-transition)}@media (prefers-reduced-motion:reduce){.navbar-toggler{transition:none}}.navbar-toggler:hover{text-decoration:none}.navbar-toggler:focus{text-decoration:none;outline:0;box-shadow:0 0 0 var(--bs-navbar-toggler-focus-width)}.navbar-toggler-icon{display:inline-block;width:1.5em;height:1.5em;vertical-align:middle;background-image:var(--bs-navbar-toggler-icon-bg);background-repeat:no-repeat;background-position:center;background-size:100%}.navbar-nav-scroll{max-height:var(--bs-scroll-height,75vh);overflow-y:auto}@media (min-width:576px){.navbar-expand-sm{flex-wrap:nowrap;justify-content:flex-start}.navbar-expand-sm .navbar-nav{flex-direction:row}.navbar-expand-sm .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-sm .navbar-nav .nav-link{padding-right:var(--bs-navbar-nav-link-padding-x);padding-left:var(--bs-navbar-nav-link-padding-x)}.navbar-expand-sm .navbar-nav-scroll{overflow:visible}.navbar-expand-sm .navbar-collapse{display:flex!important;flex-basis:auto}.navbar-expand-sm .navbar-toggler{display:none}.navbar-expand-sm .offcanvas{position:static;z-index:auto;flex-grow:1;width:auto!important;height:auto!important;visibility:visible!important;background-color:transparent!important;border:0!important;transform:none!important;transition:none}.navbar-expand-sm .offcanvas .offcanvas-header{display:none}.navbar-expand-sm .offcanvas .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible}}@media (min-width:768px){.navbar-expand-md{flex-wrap:nowrap;justify-content:flex-start}.navbar-expand-md .navbar-nav{flex-direction:row}.navbar-expand-md .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-md .navbar-nav .nav-link{padding-right:var(--bs-navbar-nav-link-padding-x);padding-left:var(--bs-navbar-nav-link-padding-x)}.navbar-expand-md .navbar-nav-scroll{overflow:visible}.navbar-expand-md .navbar-collapse{display:flex!important;flex-basis:auto}.navbar-expand-md .navbar-toggler{display:none}.navbar-expand-md .offcanvas{position:static;z-index:auto;flex-grow:1;width:auto!important;height:auto!important;visibility:visible!important;background-color:transparent!important;border:0!important;transform:none!important;transition:none}.navbar-expand-md .offcanvas .offcanvas-header{display:none}.navbar-expand-md .offcanvas .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible}}@media (min-width:992px){.navbar-expand-lg{flex-wrap:nowrap;justify-content:flex-start}.navbar-expand-lg .navbar-nav{flex-direction:row}.navbar-expand-lg .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-lg .navbar-nav .nav-link{padding-right:var(--bs-navbar-nav-link-padding-x);padding-left:var(--bs-navbar-nav-link-padding-x)}.navbar-expand-lg .navbar-nav-scroll{overflow:visible}.navbar-expand-lg .navbar-collapse{display:flex!important;flex-basis:auto}.navbar-expand-lg .navbar-toggler{display:none}.navbar-expand-lg .offcanvas{position:static;z-index:auto;flex-grow:1;width:auto!important;height:auto!important;visibility:visible!important;background-color:transparent!important;border:0!important;transform:none!important;transition:none}.navbar-expand-lg .offcanvas .offcanvas-header{display:none}.navbar-expand-lg .offcanvas .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible}}@media (min-width:1200px){.navbar-expand-xl{flex-wrap:nowrap;justify-content:flex-start}.navbar-expand-xl .navbar-nav{flex-direction:row}.navbar-expand-xl .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-xl .navbar-nav .nav-link{padding-right:var(--bs-navbar-nav-link-padding-x);padding-left:var(--bs-navbar-nav-link-padding-x)}.navbar-expand-xl .navbar-nav-scroll{overflow:visible}.navbar-expand-xl .navbar-collapse{display:flex!important;flex-basis:auto}.navbar-expand-xl .navbar-toggler{display:none}.navbar-expand-xl .offcanvas{position:static;z-index:auto;flex-grow:1;width:auto!important;height:auto!important;visibility:visible!important;background-color:transparent!important;border:0!important;transform:none!important;transition:none}.navbar-expand-xl .offcanvas .offcanvas-header{display:none}.navbar-expand-xl .offcanvas .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible}}@media (min-width:1400px){.navbar-expand-xxl{flex-wrap:nowrap;justify-content:flex-start}.navbar-expand-xxl .navbar-nav{flex-direction:row}.navbar-expand-xxl .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-xxl .navbar-nav .nav-link{padding-right:var(--bs-navbar-nav-link-padding-x);padding-left:var(--bs-navbar-nav-link-padding-x)}.navbar-expand-xxl .navbar-nav-scroll{overflow:visible}.navbar-expand-xxl .navbar-collapse{display:flex!important;flex-basis:auto}.navbar-expand-xxl .navbar-toggler{display:none}.navbar-expand-xxl .offcanvas{position:static;z-index:auto;flex-grow:1;width:auto!important;height:auto!important;visibility:visible!important;background-color:transparent!important;border:0!important;transform:none!important;transition:none}.navbar-expand-xxl .offcanvas .offcanvas-header{display:none}.navbar-expand-xxl .offcanvas .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible}}.navbar-expand{flex-wrap:nowrap;justify-content:flex-start}.navbar-expand .navbar-nav{flex-direction:row}.navbar-expand .navbar-nav .dropdown-menu{position:absolute}.navbar-expand .navbar-nav .nav-link{padding-right:var(--bs-navbar-nav-link-padding-x);padding-left:var(--bs-navbar-nav-link-padding-x)}.navbar-expand .navbar-nav-scroll{overflow:visible}.navbar-expand .navbar-collapse{display:flex!important;flex-basis:auto}.navbar-expand .navbar-toggler{display:none}.navbar-expand .offcanvas{position:static;z-index:auto;flex-grow:1;width:auto!important;height:auto!important;visibility:visible!important;background-color:transparent!important;border:0!important;transform:none!important;transition:none}.navbar-expand .offcanvas .offcanvas-header{display:none}.navbar-expand .offcanvas .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible}.navbar-dark,.navbar[data-bs-theme=dark]{--bs-navbar-color:rgba(255, 255, 255, 0.55);--bs-navbar-hover-color:rgba(255, 255, 255, 0.75);--bs-navbar-disabled-color:rgba(255, 255, 255, 0.25);--bs-navbar-active-color:#fff;--bs-navbar-brand-color:#fff;--bs-navbar-brand-hover-color:#fff;--bs-navbar-toggler-border-color:rgba(255, 255, 255, 0.1);--bs-navbar-toggler-icon-bg:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 30 30'%3e%3cpath stroke='rgba%28255, 255, 255, 0.55%29' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e")}[data-bs-theme=dark] .navbar-toggler-icon{--bs-navbar-toggler-icon-bg:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 30 30'%3e%3cpath stroke='rgba%28255, 255, 255, 0.55%29' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e")}.card{--bs-card-spacer-y:1rem;--bs-card-spacer-x:1rem;--bs-card-title-spacer-y:0.5rem;--bs-card-title-color: ;--bs-card-subtitle-color: ;--bs-card-border-width:var(--bs-border-width);--bs-card-border-color:var(--bs-border-color-translucent);--bs-card-border-radius:var(--bs-border-radius);--bs-card-box-shadow: ;--bs-card-inner-border-radius:calc(var(--bs-border-radius) - (var(--bs-border-width)));--bs-card-cap-padding-y:0.5rem;--bs-card-cap-padding-x:1rem;--bs-card-cap-bg:rgba(var(--bs-body-color-rgb), 0.03);--bs-card-cap-color: ;--bs-card-height: ;--bs-card-color: ;--bs-card-bg:var(--bs-body-bg);--bs-card-img-overlay-padding:1rem;--bs-card-group-margin:0.75rem;position:relative;display:flex;flex-direction:column;min-width:0;height:var(--bs-card-height);color:var(--bs-body-color);word-wrap:break-word;background-color:var(--bs-card-bg);background-clip:border-box;border:var(--bs-card-border-width) solid var(--bs-card-border-color);border-radius:var(--bs-card-border-radius)}.card>hr{margin-right:0;margin-left:0}.card>.list-group{border-top:inherit;border-bottom:inherit}.card>.list-group:first-child{border-top-width:0;border-top-left-radius:var(--bs-card-inner-border-radius);border-top-right-radius:var(--bs-card-inner-border-radius)}.card>.list-group:last-child{border-bottom-width:0;border-bottom-right-radius:var(--bs-card-inner-border-radius);border-bottom-left-radius:var(--bs-card-inner-border-radius)}.card>.card-header+.list-group,.card>.list-group+.card-footer{border-top:0}.card-body{flex:1 1 auto;padding:var(--bs-card-spacer-y) var(--bs-card-spacer-x);color:var(--bs-card-color)}.card-title{margin-bottom:var(--bs-card-title-spacer-y);color:var(--bs-card-title-color)}.card-subtitle{margin-top:calc(-.5 * var(--bs-card-title-spacer-y));margin-bottom:0;color:var(--bs-card-subtitle-color)}.card-text:last-child{margin-bottom:0}.card-link+.card-link{margin-left:var(--bs-card-spacer-x)}.card-header{padding:var(--bs-card-cap-padding-y) var(--bs-card-cap-padding-x);margin-bottom:0;color:var(--bs-card-cap-color);background-color:var(--bs-card-cap-bg);border-bottom:var(--bs-card-border-width) solid var(--bs-card-border-color)}.card-header:first-child{border-radius:var(--bs-card-inner-border-radius) var(--bs-card-inner-border-radius) 0 0}.card-footer{padding:var(--bs-card-cap-padding-y) var(--bs-card-cap-padding-x);color:var(--bs-card-cap-color);background-color:var(--bs-card-cap-bg);border-top:var(--bs-card-border-width) solid var(--bs-card-border-color)}.card-footer:last-child{border-radius:0 0 var(--bs-card-inner-border-radius) var(--bs-card-inner-border-radius)}.card-header-tabs{margin-right:calc(-.5 * var(--bs-card-cap-padding-x));margin-bottom:calc(-1 * var(--bs-card-cap-padding-y));margin-left:calc(-.5 * var(--bs-card-cap-padding-x));border-bottom:0}.card-header-tabs .nav-link.active{background-color:var(--bs-card-bg);border-bottom-color:var(--bs-card-bg)}.card-header-pills{margin-right:calc(-.5 * var(--bs-card-cap-padding-x));margin-left:calc(-.5 * var(--bs-card-cap-padding-x))}.card-img-overlay{position:absolute;top:0;right:0;bottom:0;left:0;padding:var(--bs-card-img-overlay-padding);border-radius:var(--bs-card-inner-border-radius)}.card-img,.card-img-bottom,.card-img-top{width:100%}.card-img,.card-img-top{border-top-left-radius:var(--bs-card-inner-border-radius);border-top-right-radius:var(--bs-card-inner-border-radius)}.card-img,.card-img-bottom{border-bottom-right-radius:var(--bs-card-inner-border-radius);border-bottom-left-radius:var(--bs-card-inner-border-radius)}.card-group>.card{margin-bottom:var(--bs-card-group-margin)}@media (min-width:576px){.card-group{display:flex;flex-flow:row wrap}.card-group>.card{flex:1 0 0;margin-bottom:0}.card-group>.card+.card{margin-left:0;border-left:0}.card-group>.card:not(:last-child){border-top-right-radius:0;border-bottom-right-radius:0}.card-group>.card:not(:last-child)>.card-header,.card-group>.card:not(:last-child)>.card-img-top{border-top-right-radius:0}.card-group>.card:not(:last-child)>.card-footer,.card-group>.card:not(:last-child)>.card-img-bottom{border-bottom-right-radius:0}.card-group>.card:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0}.card-group>.card:not(:first-child)>.card-header,.card-group>.card:not(:first-child)>.card-img-top{border-top-left-radius:0}.card-group>.card:not(:first-child)>.card-footer,.card-group>.card:not(:first-child)>.card-img-bottom{border-bottom-left-radius:0}}.accordion{--bs-accordion-color:var(--bs-body-color);--bs-accordion-bg:var(--bs-body-bg);--bs-accordion-transition:color 0.15s ease-in-out,background-color 0.15s ease-in-out,border-color 0.15s ease-in-out,box-shadow 0.15s ease-in-out,border-radius 0.15s ease;--bs-accordion-border-color:var(--bs-border-color);--bs-accordion-border-width:var(--bs-border-width);--bs-accordion-border-radius:var(--bs-border-radius);--bs-accordion-inner-border-radius:calc(var(--bs-border-radius) - (var(--bs-border-width)));--bs-accordion-btn-padding-x:1.25rem;--bs-accordion-btn-padding-y:1rem;--bs-accordion-btn-color:var(--bs-body-color);--bs-accordion-btn-bg:var(--bs-accordion-bg);--bs-accordion-btn-icon:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='%23212529' stroke-linecap='round' stroke-linejoin='round'%3e%3cpath d='m2 5 6 6 6-6'/%3e%3c/svg%3e");--bs-accordion-btn-icon-width:1.25rem;--bs-accordion-btn-icon-transform:rotate(-180deg);--bs-accordion-btn-icon-transition:transform 0.2s ease-in-out;--bs-accordion-btn-active-icon:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='%23052c65' stroke-linecap='round' stroke-linejoin='round'%3e%3cpath d='m2 5 6 6 6-6'/%3e%3c/svg%3e");--bs-accordion-btn-focus-box-shadow:0 0 0 0.25rem rgba(13, 110, 253, 0.25);--bs-accordion-body-padding-x:1.25rem;--bs-accordion-body-padding-y:1rem;--bs-accordion-active-color:var(--bs-primary-text-emphasis);--bs-accordion-active-bg:var(--bs-primary-bg-subtle)}.accordion-button{position:relative;display:flex;align-items:center;width:100%;padding:var(--bs-accordion-btn-padding-y) var(--bs-accordion-btn-padding-x);font-size:1rem;color:var(--bs-accordion-btn-color);text-align:left;background-color:var(--bs-accordion-btn-bg);border:0;border-radius:0;overflow-anchor:none;transition:var(--bs-accordion-transition)}@media (prefers-reduced-motion:reduce){.accordion-button{transition:none}}.accordion-button:not(.collapsed){color:var(--bs-accordion-active-color);background-color:var(--bs-accordion-active-bg);box-shadow:inset 0 calc(-1 * var(--bs-accordion-border-width)) 0 var(--bs-accordion-border-color)}.accordion-button:not(.collapsed)::after{background-image:var(--bs-accordion-btn-active-icon);transform:var(--bs-accordion-btn-icon-transform)}.accordion-button::after{flex-shrink:0;width:var(--bs-accordion-btn-icon-width);height:var(--bs-accordion-btn-icon-width);margin-left:auto;content:"";background-image:var(--bs-accordion-btn-icon);background-repeat:no-repeat;background-size:var(--bs-accordion-btn-icon-width);transition:var(--bs-accordion-btn-icon-transition)}@media (prefers-reduced-motion:reduce){.accordion-button::after{transition:none}}.accordion-button:hover{z-index:2}.accordion-button:focus{z-index:3;outline:0;box-shadow:var(--bs-accordion-btn-focus-box-shadow)}.accordion-header{margin-bottom:0}.accordion-item{color:var(--bs-accordion-color);background-color:var(--bs-accordion-bg);border:var(--bs-accordion-border-width) solid var(--bs-accordion-border-color)}.accordion-item:first-of-type{border-top-left-radius:var(--bs-accordion-border-radius);border-top-right-radius:var(--bs-accordion-border-radius)}.accordion-item:first-of-type>.accordion-header .accordion-button{border-top-left-radius:var(--bs-accordion-inner-border-radius);border-top-right-radius:var(--bs-accordion-inner-border-radius)}.accordion-item:not(:first-of-type){border-top:0}.accordion-item:last-of-type{border-bottom-right-radius:var(--bs-accordion-border-radius);border-bottom-left-radius:var(--bs-accordion-border-radius)}.accordion-item:last-of-type>.accordion-header .accordion-button.collapsed{border-bottom-right-radius:var(--bs-accordion-inner-border-radius);border-bottom-left-radius:var(--bs-accordion-inner-border-radius)}.accordion-item:last-of-type>.accordion-collapse{border-bottom-right-radius:var(--bs-accordion-border-radius);border-bottom-left-radius:var(--bs-accordion-border-radius)}.accordion-body{padding:var(--bs-accordion-body-padding-y) var(--bs-accordion-body-padding-x)}.accordion-flush>.accordion-item{border-right:0;border-left:0;border-radius:0}.accordion-flush>.accordion-item:first-child{border-top:0}.accordion-flush>.accordion-item:last-child{border-bottom:0}.accordion-flush>.accordion-item>.accordion-collapse,.accordion-flush>.accordion-item>.accordion-header .accordion-button,.accordion-flush>.accordion-item>.accordion-header .accordion-button.collapsed{border-radius:0}[data-bs-theme=dark] .accordion-button::after{--bs-accordion-btn-icon:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%236ea8fe'%3e%3cpath fill-rule='evenodd' d='M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708'/%3e%3c/svg%3e");--bs-accordion-btn-active-icon:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%236ea8fe'%3e%3cpath fill-rule='evenodd' d='M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708'/%3e%3c/svg%3e")}.breadcrumb{--bs-breadcrumb-padding-x:0;--bs-breadcrumb-padding-y:0;--bs-breadcrumb-margin-bottom:1rem;--bs-breadcrumb-bg: ;--bs-breadcrumb-border-radius: ;--bs-breadcrumb-divider-color:var(--bs-secondary-color);--bs-breadcrumb-item-padding-x:0.5rem;--bs-breadcrumb-item-active-color:var(--bs-secondary-color);display:flex;flex-wrap:wrap;padding:var(--bs-breadcrumb-padding-y) var(--bs-breadcrumb-padding-x);margin-bottom:var(--bs-breadcrumb-margin-bottom);font-size:var(--bs-breadcrumb-font-size);list-style:none;background-color:var(--bs-breadcrumb-bg);border-radius:var(--bs-breadcrumb-border-radius)}.breadcrumb-item+.breadcrumb-item{padding-left:var(--bs-breadcrumb-item-padding-x)}.breadcrumb-item+.breadcrumb-item::before{float:left;padding-right:var(--bs-breadcrumb-item-padding-x);color:var(--bs-breadcrumb-divider-color);content:var(--bs-breadcrumb-divider, "/")}.breadcrumb-item.active{color:var(--bs-breadcrumb-item-active-color)}.pagination{--bs-pagination-padding-x:0.75rem;--bs-pagination-padding-y:0.375rem;--bs-pagination-font-size:1rem;--bs-pagination-color:var(--bs-link-color);--bs-pagination-bg:var(--bs-body-bg);--bs-pagination-border-width:var(--bs-border-width);--bs-pagination-border-color:var(--bs-border-color);--bs-pagination-border-radius:var(--bs-border-radius);--bs-pagination-hover-color:var(--bs-link-hover-color);--bs-pagination-hover-bg:var(--bs-tertiary-bg);--bs-pagination-hover-border-color:var(--bs-border-color);--bs-pagination-focus-color:var(--bs-link-hover-color);--bs-pagination-focus-bg:var(--bs-secondary-bg);--bs-pagination-focus-box-shadow:0 0 0 0.25rem rgba(13, 110, 253, 0.25);--bs-pagination-active-color:#fff;--bs-pagination-active-bg:#0d6efd;--bs-pagination-active-border-color:#0d6efd;--bs-pagination-disabled-color:var(--bs-secondary-color);--bs-pagination-disabled-bg:var(--bs-secondary-bg);--bs-pagination-disabled-border-color:var(--bs-border-color);display:flex;padding-left:0;list-style:none}.page-link{position:relative;display:block;padding:var(--bs-pagination-padding-y) var(--bs-pagination-padding-x);font-size:var(--bs-pagination-font-size);color:var(--bs-pagination-color);text-decoration:none;background-color:var(--bs-pagination-bg);border:var(--bs-pagination-border-width) solid var(--bs-pagination-border-color);transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.page-link{transition:none}}.page-link:hover{z-index:2;color:var(--bs-pagination-hover-color);background-color:var(--bs-pagination-hover-bg);border-color:var(--bs-pagination-hover-border-color)}.page-link:focus{z-index:3;color:var(--bs-pagination-focus-color);background-color:var(--bs-pagination-focus-bg);outline:0;box-shadow:var(--bs-pagination-focus-box-shadow)}.active>.page-link,.page-link.active{z-index:3;color:var(--bs-pagination-active-color);background-color:var(--bs-pagination-active-bg);border-color:var(--bs-pagination-active-border-color)}.disabled>.page-link,.page-link.disabled{color:var(--bs-pagination-disabled-color);pointer-events:none;background-color:var(--bs-pagination-disabled-bg);border-color:var(--bs-pagination-disabled-border-color)}.page-item:not(:first-child) .page-link{margin-left:calc(-1 * var(--bs-border-width))}.page-item:first-child .page-link{border-top-left-radius:var(--bs-pagination-border-radius);border-bottom-left-radius:var(--bs-pagination-border-radius)}.page-item:last-child .page-link{border-top-right-radius:var(--bs-pagination-border-radius);border-bottom-right-radius:var(--bs-pagination-border-radius)}.pagination-lg{--bs-pagination-padding-x:1.5rem;--bs-pagination-padding-y:0.75rem;--bs-pagination-font-size:1.25rem;--bs-pagination-border-radius:var(--bs-border-radius-lg)}.pagination-sm{--bs-pagination-padding-x:0.5rem;--bs-pagination-padding-y:0.25rem;--bs-pagination-font-size:0.875rem;--bs-pagination-border-radius:var(--bs-border-radius-sm)}.badge{--bs-badge-padding-x:0.65em;--bs-badge-padding-y:0.35em;--bs-badge-font-size:0.75em;--bs-badge-font-weight:700;--bs-badge-color:#fff;--bs-badge-border-radius:var(--bs-border-radius);display:inline-block;padding:var(--bs-badge-padding-y) var(--bs-badge-padding-x);font-size:var(--bs-badge-font-size);font-weight:var(--bs-badge-font-weight);line-height:1;color:var(--bs-badge-color);text-align:center;white-space:nowrap;vertical-align:baseline;border-radius:var(--bs-badge-border-radius)}.badge:empty{display:none}.btn .badge{position:relative;top:-1px}.alert{--bs-alert-bg:transparent;--bs-alert-padding-x:1rem;--bs-alert-padding-y:1rem;--bs-alert-margin-bottom:1rem;--bs-alert-color:inherit;--bs-alert-border-color:transparent;--bs-alert-border:var(--bs-border-width) solid var(--bs-alert-border-color);--bs-alert-border-radius:var(--bs-border-radius);--bs-alert-link-color:inherit;position:relative;padding:var(--bs-alert-padding-y) var(--bs-alert-padding-x);margin-bottom:var(--bs-alert-margin-bottom);color:var(--bs-alert-color);background-color:var(--bs-alert-bg);border:var(--bs-alert-border);border-radius:var(--bs-alert-border-radius)}.alert-heading{color:inherit}.alert-link{font-weight:700;color:var(--bs-alert-link-color)}.alert-dismissible{padding-right:3rem}.alert-dismissible .btn-close{position:absolute;top:0;right:0;z-index:2;padding:1.25rem 1rem}.alert-primary{--bs-alert-color:var(--bs-primary-text-emphasis);--bs-alert-bg:var(--bs-primary-bg-subtle);--bs-alert-border-color:var(--bs-primary-border-subtle);--bs-alert-link-color:var(--bs-primary-text-emphasis)}.alert-secondary{--bs-alert-color:var(--bs-secondary-text-emphasis);--bs-alert-bg:var(--bs-secondary-bg-subtle);--bs-alert-border-color:var(--bs-secondary-border-subtle);--bs-alert-link-color:var(--bs-secondary-text-emphasis)}.alert-success{--bs-alert-color:var(--bs-success-text-emphasis);--bs-alert-bg:var(--bs-success-bg-subtle);--bs-alert-border-color:var(--bs-success-border-subtle);--bs-alert-link-color:var(--bs-success-text-emphasis)}.alert-info{--bs-alert-color:var(--bs-info-text-emphasis);--bs-alert-bg:var(--bs-info-bg-subtle);--bs-alert-border-color:var(--bs-info-border-subtle);--bs-alert-link-color:var(--bs-info-text-emphasis)}.alert-warning{--bs-alert-color:var(--bs-warning-text-emphasis);--bs-alert-bg:var(--bs-warning-bg-subtle);--bs-alert-border-color:var(--bs-warning-border-subtle);--bs-alert-link-color:var(--bs-warning-text-emphasis)}.alert-danger{--bs-alert-color:var(--bs-danger-text-emphasis);--bs-alert-bg:var(--bs-danger-bg-subtle);--bs-alert-border-color:var(--bs-danger-border-subtle);--bs-alert-link-color:var(--bs-danger-text-emphasis)}.alert-light{--bs-alert-color:var(--bs-light-text-emphasis);--bs-alert-bg:var(--bs-light-bg-subtle);--bs-alert-border-color:var(--bs-light-border-subtle);--bs-alert-link-color:var(--bs-light-text-emphasis)}.alert-dark{--bs-alert-color:var(--bs-dark-text-emphasis);--bs-alert-bg:var(--bs-dark-bg-subtle);--bs-alert-border-color:var(--bs-dark-border-subtle);--bs-alert-link-color:var(--bs-dark-text-emphasis)}@keyframes progress-bar-stripes{0%{background-position-x:var(--bs-progress-height)}}.progress,.progress-stacked{--bs-progress-height:1rem;--bs-progress-font-size:0.75rem;--bs-progress-bg:var(--bs-secondary-bg);--bs-progress-border-radius:var(--bs-border-radius);--bs-progress-box-shadow:var(--bs-box-shadow-inset);--bs-progress-bar-color:#fff;--bs-progress-bar-bg:#0d6efd;--bs-progress-bar-transition:width 0.6s ease;display:flex;height:var(--bs-progress-height);overflow:hidden;font-size:var(--bs-progress-font-size);background-color:var(--bs-progress-bg);border-radius:var(--bs-progress-border-radius)}.progress-bar{display:flex;flex-direction:column;justify-content:center;overflow:hidden;color:var(--bs-progress-bar-color);text-align:center;white-space:nowrap;background-color:var(--bs-progress-bar-bg);transition:var(--bs-progress-bar-transition)}@media (prefers-reduced-motion:reduce){.progress-bar{transition:none}}.progress-bar-striped{background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-size:var(--bs-progress-height) var(--bs-progress-height)}.progress-stacked>.progress{overflow:visible}.progress-stacked>.progress>.progress-bar{width:100%}.progress-bar-animated{animation:1s linear infinite progress-bar-stripes}@media (prefers-reduced-motion:reduce){.progress-bar-animated{animation:none}}.list-group{--bs-list-group-color:var(--bs-body-color);--bs-list-group-bg:var(--bs-body-bg);--bs-list-group-border-color:var(--bs-border-color);--bs-list-group-border-width:var(--bs-border-width);--bs-list-group-border-radius:var(--bs-border-radius);--bs-list-group-item-padding-x:1rem;--bs-list-group-item-padding-y:0.5rem;--bs-list-group-action-color:var(--bs-secondary-color);--bs-list-group-action-hover-color:var(--bs-emphasis-color);--bs-list-group-action-hover-bg:var(--bs-tertiary-bg);--bs-list-group-action-active-color:var(--bs-body-color);--bs-list-group-action-active-bg:var(--bs-secondary-bg);--bs-list-group-disabled-color:var(--bs-secondary-color);--bs-list-group-disabled-bg:var(--bs-body-bg);--bs-list-group-active-color:#fff;--bs-list-group-active-bg:#0d6efd;--bs-list-group-active-border-color:#0d6efd;display:flex;flex-direction:column;padding-left:0;margin-bottom:0;border-radius:var(--bs-list-group-border-radius)}.list-group-numbered{list-style-type:none;counter-reset:section}.list-group-numbered>.list-group-item::before{content:counters(section, ".") ". ";counter-increment:section}.list-group-item{position:relative;display:block;padding:var(--bs-list-group-item-padding-y) var(--bs-list-group-item-padding-x);color:var(--bs-list-group-color);text-decoration:none;background-color:var(--bs-list-group-bg);border:var(--bs-list-group-border-width) solid var(--bs-list-group-border-color)}.list-group-item:first-child{border-top-left-radius:inherit;border-top-right-radius:inherit}.list-group-item:last-child{border-bottom-right-radius:inherit;border-bottom-left-radius:inherit}.list-group-item.disabled,.list-group-item:disabled{color:var(--bs-list-group-disabled-color);pointer-events:none;background-color:var(--bs-list-group-disabled-bg)}.list-group-item.active{z-index:2;color:var(--bs-list-group-active-color);background-color:var(--bs-list-group-active-bg);border-color:var(--bs-list-group-active-border-color)}.list-group-item+.list-group-item{border-top-width:0}.list-group-item+.list-group-item.active{margin-top:calc(-1 * var(--bs-list-group-border-width));border-top-width:var(--bs-list-group-border-width)}.list-group-item-action{width:100%;color:var(--bs-list-group-action-color);text-align:inherit}.list-group-item-action:not(.active):focus,.list-group-item-action:not(.active):hover{z-index:1;color:var(--bs-list-group-action-hover-color);text-decoration:none;background-color:var(--bs-list-group-action-hover-bg)}.list-group-item-action:not(.active):active{color:var(--bs-list-group-action-active-color);background-color:var(--bs-list-group-action-active-bg)}.list-group-horizontal{flex-direction:row}.list-group-horizontal>.list-group-item:first-child:not(:last-child){border-bottom-left-radius:var(--bs-list-group-border-radius);border-top-right-radius:0}.list-group-horizontal>.list-group-item:last-child:not(:first-child){border-top-right-radius:var(--bs-list-group-border-radius);border-bottom-left-radius:0}.list-group-horizontal>.list-group-item.active{margin-top:0}.list-group-horizontal>.list-group-item+.list-group-item{border-top-width:var(--bs-list-group-border-width);border-left-width:0}.list-group-horizontal>.list-group-item+.list-group-item.active{margin-left:calc(-1 * var(--bs-list-group-border-width));border-left-width:var(--bs-list-group-border-width)}@media (min-width:576px){.list-group-horizontal-sm{flex-direction:row}.list-group-horizontal-sm>.list-group-item:first-child:not(:last-child){border-bottom-left-radius:var(--bs-list-group-border-radius);border-top-right-radius:0}.list-group-horizontal-sm>.list-group-item:last-child:not(:first-child){border-top-right-radius:var(--bs-list-group-border-radius);border-bottom-left-radius:0}.list-group-horizontal-sm>.list-group-item.active{margin-top:0}.list-group-horizontal-sm>.list-group-item+.list-group-item{border-top-width:var(--bs-list-group-border-width);border-left-width:0}.list-group-horizontal-sm>.list-group-item+.list-group-item.active{margin-left:calc(-1 * var(--bs-list-group-border-width));border-left-width:var(--bs-list-group-border-width)}}@media (min-width:768px){.list-group-horizontal-md{flex-direction:row}.list-group-horizontal-md>.list-group-item:first-child:not(:last-child){border-bottom-left-radius:var(--bs-list-group-border-radius);border-top-right-radius:0}.list-group-horizontal-md>.list-group-item:last-child:not(:first-child){border-top-right-radius:var(--bs-list-group-border-radius);border-bottom-left-radius:0}.list-group-horizontal-md>.list-group-item.active{margin-top:0}.list-group-horizontal-md>.list-group-item+.list-group-item{border-top-width:var(--bs-list-group-border-width);border-left-width:0}.list-group-horizontal-md>.list-group-item+.list-group-item.active{margin-left:calc(-1 * var(--bs-list-group-border-width));border-left-width:var(--bs-list-group-border-width)}}@media (min-width:992px){.list-group-horizontal-lg{flex-direction:row}.list-group-horizontal-lg>.list-group-item:first-child:not(:last-child){border-bottom-left-radius:var(--bs-list-group-border-radius);border-top-right-radius:0}.list-group-horizontal-lg>.list-group-item:last-child:not(:first-child){border-top-right-radius:var(--bs-list-group-border-radius);border-bottom-left-radius:0}.list-group-horizontal-lg>.list-group-item.active{margin-top:0}.list-group-horizontal-lg>.list-group-item+.list-group-item{border-top-width:var(--bs-list-group-border-width);border-left-width:0}.list-group-horizontal-lg>.list-group-item+.list-group-item.active{margin-left:calc(-1 * var(--bs-list-group-border-width));border-left-width:var(--bs-list-group-border-width)}}@media (min-width:1200px){.list-group-horizontal-xl{flex-direction:row}.list-group-horizontal-xl>.list-group-item:first-child:not(:last-child){border-bottom-left-radius:var(--bs-list-group-border-radius);border-top-right-radius:0}.list-group-horizontal-xl>.list-group-item:last-child:not(:first-child){border-top-right-radius:var(--bs-list-group-border-radius);border-bottom-left-radius:0}.list-group-horizontal-xl>.list-group-item.active{margin-top:0}.list-group-horizontal-xl>.list-group-item+.list-group-item{border-top-width:var(--bs-list-group-border-width);border-left-width:0}.list-group-horizontal-xl>.list-group-item+.list-group-item.active{margin-left:calc(-1 * var(--bs-list-group-border-width));border-left-width:var(--bs-list-group-border-width)}}@media (min-width:1400px){.list-group-horizontal-xxl{flex-direction:row}.list-group-horizontal-xxl>.list-group-item:first-child:not(:last-child){border-bottom-left-radius:var(--bs-list-group-border-radius);border-top-right-radius:0}.list-group-horizontal-xxl>.list-group-item:last-child:not(:first-child){border-top-right-radius:var(--bs-list-group-border-radius);border-bottom-left-radius:0}.list-group-horizontal-xxl>.list-group-item.active{margin-top:0}.list-group-horizontal-xxl>.list-group-item+.list-group-item{border-top-width:var(--bs-list-group-border-width);border-left-width:0}.list-group-horizontal-xxl>.list-group-item+.list-group-item.active{margin-left:calc(-1 * var(--bs-list-group-border-width));border-left-width:var(--bs-list-group-border-width)}}.list-group-flush{border-radius:0}.list-group-flush>.list-group-item{border-width:0 0 var(--bs-list-group-border-width)}.list-group-flush>.list-group-item:last-child{border-bottom-width:0}.list-group-item-primary{--bs-list-group-color:var(--bs-primary-text-emphasis);--bs-list-group-bg:var(--bs-primary-bg-subtle);--bs-list-group-border-color:var(--bs-primary-border-subtle);--bs-list-group-action-hover-color:var(--bs-emphasis-color);--bs-list-group-action-hover-bg:var(--bs-primary-border-subtle);--bs-list-group-action-active-color:var(--bs-emphasis-color);--bs-list-group-action-active-bg:var(--bs-primary-border-subtle);--bs-list-group-active-color:var(--bs-primary-bg-subtle);--bs-list-group-active-bg:var(--bs-primary-text-emphasis);--bs-list-group-active-border-color:var(--bs-primary-text-emphasis)}.list-group-item-secondary{--bs-list-group-color:var(--bs-secondary-text-emphasis);--bs-list-group-bg:var(--bs-secondary-bg-subtle);--bs-list-group-border-color:var(--bs-secondary-border-subtle);--bs-list-group-action-hover-color:var(--bs-emphasis-color);--bs-list-group-action-hover-bg:var(--bs-secondary-border-subtle);--bs-list-group-action-active-color:var(--bs-emphasis-color);--bs-list-group-action-active-bg:var(--bs-secondary-border-subtle);--bs-list-group-active-color:var(--bs-secondary-bg-subtle);--bs-list-group-active-bg:var(--bs-secondary-text-emphasis);--bs-list-group-active-border-color:var(--bs-secondary-text-emphasis)}.list-group-item-success{--bs-list-group-color:var(--bs-success-text-emphasis);--bs-list-group-bg:var(--bs-success-bg-subtle);--bs-list-group-border-color:var(--bs-success-border-subtle);--bs-list-group-action-hover-color:var(--bs-emphasis-color);--bs-list-group-action-hover-bg:var(--bs-success-border-subtle);--bs-list-group-action-active-color:var(--bs-emphasis-color);--bs-list-group-action-active-bg:var(--bs-success-border-subtle);--bs-list-group-active-color:var(--bs-success-bg-subtle);--bs-list-group-active-bg:var(--bs-success-text-emphasis);--bs-list-group-active-border-color:var(--bs-success-text-emphasis)}.list-group-item-info{--bs-list-group-color:var(--bs-info-text-emphasis);--bs-list-group-bg:var(--bs-info-bg-subtle);--bs-list-group-border-color:var(--bs-info-border-subtle);--bs-list-group-action-hover-color:var(--bs-emphasis-color);--bs-list-group-action-hover-bg:var(--bs-info-border-subtle);--bs-list-group-action-active-color:var(--bs-emphasis-color);--bs-list-group-action-active-bg:var(--bs-info-border-subtle);--bs-list-group-active-color:var(--bs-info-bg-subtle);--bs-list-group-active-bg:var(--bs-info-text-emphasis);--bs-list-group-active-border-color:var(--bs-info-text-emphasis)}.list-group-item-warning{--bs-list-group-color:var(--bs-warning-text-emphasis);--bs-list-group-bg:var(--bs-warning-bg-subtle);--bs-list-group-border-color:var(--bs-warning-border-subtle);--bs-list-group-action-hover-color:var(--bs-emphasis-color);--bs-list-group-action-hover-bg:var(--bs-warning-border-subtle);--bs-list-group-action-active-color:var(--bs-emphasis-color);--bs-list-group-action-active-bg:var(--bs-warning-border-subtle);--bs-list-group-active-color:var(--bs-warning-bg-subtle);--bs-list-group-active-bg:var(--bs-warning-text-emphasis);--bs-list-group-active-border-color:var(--bs-warning-text-emphasis)}.list-group-item-danger{--bs-list-group-color:var(--bs-danger-text-emphasis);--bs-list-group-bg:var(--bs-danger-bg-subtle);--bs-list-group-border-color:var(--bs-danger-border-subtle);--bs-list-group-action-hover-color:var(--bs-emphasis-color);--bs-list-group-action-hover-bg:var(--bs-danger-border-subtle);--bs-list-group-action-active-color:var(--bs-emphasis-color);--bs-list-group-action-active-bg:var(--bs-danger-border-subtle);--bs-list-group-active-color:var(--bs-danger-bg-subtle);--bs-list-group-active-bg:var(--bs-danger-text-emphasis);--bs-list-group-active-border-color:var(--bs-danger-text-emphasis)}.list-group-item-light{--bs-list-group-color:var(--bs-light-text-emphasis);--bs-list-group-bg:var(--bs-light-bg-subtle);--bs-list-group-border-color:var(--bs-light-border-subtle);--bs-list-group-action-hover-color:var(--bs-emphasis-color);--bs-list-group-action-hover-bg:var(--bs-light-border-subtle);--bs-list-group-action-active-color:var(--bs-emphasis-color);--bs-list-group-action-active-bg:var(--bs-light-border-subtle);--bs-list-group-active-color:var(--bs-light-bg-subtle);--bs-list-group-active-bg:var(--bs-light-text-emphasis);--bs-list-group-active-border-color:var(--bs-light-text-emphasis)}.list-group-item-dark{--bs-list-group-color:var(--bs-dark-text-emphasis);--bs-list-group-bg:var(--bs-dark-bg-subtle);--bs-list-group-border-color:var(--bs-dark-border-subtle);--bs-list-group-action-hover-color:var(--bs-emphasis-color);--bs-list-group-action-hover-bg:var(--bs-dark-border-subtle);--bs-list-group-action-active-color:var(--bs-emphasis-color);--bs-list-group-action-active-bg:var(--bs-dark-border-subtle);--bs-list-group-active-color:var(--bs-dark-bg-subtle);--bs-list-group-active-bg:var(--bs-dark-text-emphasis);--bs-list-group-active-border-color:var(--bs-dark-text-emphasis)}.btn-close{--bs-btn-close-color:#000;--bs-btn-close-bg:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23000'%3e%3cpath d='M.293.293a1 1 0 0 1 1.414 0L8 6.586 14.293.293a1 1 0 1 1 1.414 1.414L9.414 8l6.293 6.293a1 1 0 0 1-1.414 1.414L8 9.414l-6.293 6.293a1 1 0 0 1-1.414-1.414L6.586 8 .293 1.707a1 1 0 0 1 0-1.414'/%3e%3c/svg%3e");--bs-btn-close-opacity:0.5;--bs-btn-close-hover-opacity:0.75;--bs-btn-close-focus-shadow:0 0 0 0.25rem rgba(13, 110, 253, 0.25);--bs-btn-close-focus-opacity:1;--bs-btn-close-disabled-opacity:0.25;box-sizing:content-box;width:1em;height:1em;padding:.25em .25em;color:var(--bs-btn-close-color);background:transparent var(--bs-btn-close-bg) center/1em auto no-repeat;filter:var(--bs-btn-close-filter);border:0;border-radius:.375rem;opacity:var(--bs-btn-close-opacity)}.btn-close:hover{color:var(--bs-btn-close-color);text-decoration:none;opacity:var(--bs-btn-close-hover-opacity)}.btn-close:focus{outline:0;box-shadow:var(--bs-btn-close-focus-shadow);opacity:var(--bs-btn-close-focus-opacity)}.btn-close.disabled,.btn-close:disabled{pointer-events:none;-webkit-user-select:none;-moz-user-select:none;user-select:none;opacity:var(--bs-btn-close-disabled-opacity)}.btn-close-white{--bs-btn-close-filter:invert(1) grayscale(100%) brightness(200%)}:root,[data-bs-theme=light]{--bs-btn-close-filter: }[data-bs-theme=dark]{--bs-btn-close-filter:invert(1) grayscale(100%) brightness(200%)}.toast{--bs-toast-zindex:1090;--bs-toast-padding-x:0.75rem;--bs-toast-padding-y:0.5rem;--bs-toast-spacing:1.5rem;--bs-toast-max-width:350px;--bs-toast-font-size:0.875rem;--bs-toast-color: ;--bs-toast-bg:rgba(var(--bs-body-bg-rgb), 0.85);--bs-toast-border-width:var(--bs-border-width);--bs-toast-border-color:var(--bs-border-color-translucent);--bs-toast-border-radius:var(--bs-border-radius);--bs-toast-box-shadow:var(--bs-box-shadow);--bs-toast-header-color:var(--bs-secondary-color);--bs-toast-header-bg:rgba(var(--bs-body-bg-rgb), 0.85);--bs-toast-header-border-color:var(--bs-border-color-translucent);width:var(--bs-toast-max-width);max-width:100%;font-size:var(--bs-toast-font-size);color:var(--bs-toast-color);pointer-events:auto;background-color:var(--bs-toast-bg);background-clip:padding-box;border:var(--bs-toast-border-width) solid var(--bs-toast-border-color);box-shadow:var(--bs-toast-box-shadow);border-radius:var(--bs-toast-border-radius)}.toast.showing{opacity:0}.toast:not(.show){display:none}.toast-container{--bs-toast-zindex:1090;position:absolute;z-index:var(--bs-toast-zindex);width:-webkit-max-content;width:-moz-max-content;width:max-content;max-width:100%;pointer-events:none}.toast-container>:not(:last-child){margin-bottom:var(--bs-toast-spacing)}.toast-header{display:flex;align-items:center;padding:var(--bs-toast-padding-y) var(--bs-toast-padding-x);color:var(--bs-toast-header-color);background-color:var(--bs-toast-header-bg);background-clip:padding-box;border-bottom:var(--bs-toast-border-width) solid var(--bs-toast-header-border-color);border-top-left-radius:calc(var(--bs-toast-border-radius) - var(--bs-toast-border-width));border-top-right-radius:calc(var(--bs-toast-border-radius) - var(--bs-toast-border-width))}.toast-header .btn-close{margin-right:calc(-.5 * var(--bs-toast-padding-x));margin-left:var(--bs-toast-padding-x)}.toast-body{padding:var(--bs-toast-padding-x);word-wrap:break-word}.modal{--bs-modal-zindex:1055;--bs-modal-width:500px;--bs-modal-padding:1rem;--bs-modal-margin:0.5rem;--bs-modal-color:var(--bs-body-color);--bs-modal-bg:var(--bs-body-bg);--bs-modal-border-color:var(--bs-border-color-translucent);--bs-modal-border-width:var(--bs-border-width);--bs-modal-border-radius:var(--bs-border-radius-lg);--bs-modal-box-shadow:var(--bs-box-shadow-sm);--bs-modal-inner-border-radius:calc(var(--bs-border-radius-lg) - (var(--bs-border-width)));--bs-modal-header-padding-x:1rem;--bs-modal-header-padding-y:1rem;--bs-modal-header-padding:1rem 1rem;--bs-modal-header-border-color:var(--bs-border-color);--bs-modal-header-border-width:var(--bs-border-width);--bs-modal-title-line-height:1.5;--bs-modal-footer-gap:0.5rem;--bs-modal-footer-bg: ;--bs-modal-footer-border-color:var(--bs-border-color);--bs-modal-footer-border-width:var(--bs-border-width);position:fixed;top:0;left:0;z-index:var(--bs-modal-zindex);display:none;width:100%;height:100%;overflow-x:hidden;overflow-y:auto;outline:0}.modal-dialog{position:relative;width:auto;margin:var(--bs-modal-margin);pointer-events:none}.modal.fade .modal-dialog{transform:translate(0,-50px);transition:transform .3s ease-out}@media (prefers-reduced-motion:reduce){.modal.fade .modal-dialog{transition:none}}.modal.show .modal-dialog{transform:none}.modal.modal-static .modal-dialog{transform:scale(1.02)}.modal-dialog-scrollable{height:calc(100% - var(--bs-modal-margin) * 2)}.modal-dialog-scrollable .modal-content{max-height:100%;overflow:hidden}.modal-dialog-scrollable .modal-body{overflow-y:auto}.modal-dialog-centered{display:flex;align-items:center;min-height:calc(100% - var(--bs-modal-margin) * 2)}.modal-content{position:relative;display:flex;flex-direction:column;width:100%;color:var(--bs-modal-color);pointer-events:auto;background-color:var(--bs-modal-bg);background-clip:padding-box;border:var(--bs-modal-border-width) solid var(--bs-modal-border-color);border-radius:var(--bs-modal-border-radius);outline:0}.modal-backdrop{--bs-backdrop-zindex:1050;--bs-backdrop-bg:#000;--bs-backdrop-opacity:0.5;position:fixed;top:0;left:0;z-index:var(--bs-backdrop-zindex);width:100vw;height:100vh;background-color:var(--bs-backdrop-bg)}.modal-backdrop.fade{opacity:0}.modal-backdrop.show{opacity:var(--bs-backdrop-opacity)}.modal-header{display:flex;flex-shrink:0;align-items:center;padding:var(--bs-modal-header-padding);border-bottom:var(--bs-modal-header-border-width) solid var(--bs-modal-header-border-color);border-top-left-radius:var(--bs-modal-inner-border-radius);border-top-right-radius:var(--bs-modal-inner-border-radius)}.modal-header .btn-close{padding:calc(var(--bs-modal-header-padding-y) * .5) calc(var(--bs-modal-header-padding-x) * .5);margin-top:calc(-.5 * var(--bs-modal-header-padding-y));margin-right:calc(-.5 * var(--bs-modal-header-padding-x));margin-bottom:calc(-.5 * var(--bs-modal-header-padding-y));margin-left:auto}.modal-title{margin-bottom:0;line-height:var(--bs-modal-title-line-height)}.modal-body{position:relative;flex:1 1 auto;padding:var(--bs-modal-padding)}.modal-footer{display:flex;flex-shrink:0;flex-wrap:wrap;align-items:center;justify-content:flex-end;padding:calc(var(--bs-modal-padding) - var(--bs-modal-footer-gap) * .5);background-color:var(--bs-modal-footer-bg);border-top:var(--bs-modal-footer-border-width) solid var(--bs-modal-footer-border-color);border-bottom-right-radius:var(--bs-modal-inner-border-radius);border-bottom-left-radius:var(--bs-modal-inner-border-radius)}.modal-footer>*{margin:calc(var(--bs-modal-footer-gap) * .5)}@media (min-width:576px){.modal{--bs-modal-margin:1.75rem;--bs-modal-box-shadow:var(--bs-box-shadow)}.modal-dialog{max-width:var(--bs-modal-width);margin-right:auto;margin-left:auto}.modal-sm{--bs-modal-width:300px}}@media (min-width:992px){.modal-lg,.modal-xl{--bs-modal-width:800px}}@media (min-width:1200px){.modal-xl{--bs-modal-width:1140px}}.modal-fullscreen{width:100vw;max-width:none;height:100%;margin:0}.modal-fullscreen .modal-content{height:100%;border:0;border-radius:0}.modal-fullscreen .modal-footer,.modal-fullscreen .modal-header{border-radius:0}.modal-fullscreen .modal-body{overflow-y:auto}@media (max-width:575.98px){.modal-fullscreen-sm-down{width:100vw;max-width:none;height:100%;margin:0}.modal-fullscreen-sm-down .modal-content{height:100%;border:0;border-radius:0}.modal-fullscreen-sm-down .modal-footer,.modal-fullscreen-sm-down .modal-header{border-radius:0}.modal-fullscreen-sm-down .modal-body{overflow-y:auto}}@media (max-width:767.98px){.modal-fullscreen-md-down{width:100vw;max-width:none;height:100%;margin:0}.modal-fullscreen-md-down .modal-content{height:100%;border:0;border-radius:0}.modal-fullscreen-md-down .modal-footer,.modal-fullscreen-md-down .modal-header{border-radius:0}.modal-fullscreen-md-down .modal-body{overflow-y:auto}}@media (max-width:991.98px){.modal-fullscreen-lg-down{width:100vw;max-width:none;height:100%;margin:0}.modal-fullscreen-lg-down .modal-content{height:100%;border:0;border-radius:0}.modal-fullscreen-lg-down .modal-footer,.modal-fullscreen-lg-down .modal-header{border-radius:0}.modal-fullscreen-lg-down .modal-body{overflow-y:auto}}@media (max-width:1199.98px){.modal-fullscreen-xl-down{width:100vw;max-width:none;height:100%;margin:0}.modal-fullscreen-xl-down .modal-content{height:100%;border:0;border-radius:0}.modal-fullscreen-xl-down .modal-footer,.modal-fullscreen-xl-down .modal-header{border-radius:0}.modal-fullscreen-xl-down .modal-body{overflow-y:auto}}@media (max-width:1399.98px){.modal-fullscreen-xxl-down{width:100vw;max-width:none;height:100%;margin:0}.modal-fullscreen-xxl-down .modal-content{height:100%;border:0;border-radius:0}.modal-fullscreen-xxl-down .modal-footer,.modal-fullscreen-xxl-down .modal-header{border-radius:0}.modal-fullscreen-xxl-down .modal-body{overflow-y:auto}}.tooltip{--bs-tooltip-zindex:1080;--bs-tooltip-max-width:200px;--bs-tooltip-padding-x:0.5rem;--bs-tooltip-padding-y:0.25rem;--bs-tooltip-margin: ;--bs-tooltip-font-size:0.875rem;--bs-tooltip-color:var(--bs-body-bg);--bs-tooltip-bg:var(--bs-emphasis-color);--bs-tooltip-border-radius:var(--bs-border-radius);--bs-tooltip-opacity:0.9;--bs-tooltip-arrow-width:0.8rem;--bs-tooltip-arrow-height:0.4rem;z-index:var(--bs-tooltip-zindex);display:block;margin:var(--bs-tooltip-margin);font-family:var(--bs-font-sans-serif);font-style:normal;font-weight:400;line-height:1.5;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;white-space:normal;word-spacing:normal;line-break:auto;font-size:var(--bs-tooltip-font-size);word-wrap:break-word;opacity:0}.tooltip.show{opacity:var(--bs-tooltip-opacity)}.tooltip .tooltip-arrow{display:block;width:var(--bs-tooltip-arrow-width);height:var(--bs-tooltip-arrow-height)}.tooltip .tooltip-arrow::before{position:absolute;content:"";border-color:transparent;border-style:solid}.bs-tooltip-auto[data-popper-placement^=top] .tooltip-arrow,.bs-tooltip-top .tooltip-arrow{bottom:calc(-1 * var(--bs-tooltip-arrow-height))}.bs-tooltip-auto[data-popper-placement^=top] .tooltip-arrow::before,.bs-tooltip-top .tooltip-arrow::before{top:-1px;border-width:var(--bs-tooltip-arrow-height) calc(var(--bs-tooltip-arrow-width) * .5) 0;border-top-color:var(--bs-tooltip-bg)}.bs-tooltip-auto[data-popper-placement^=right] .tooltip-arrow,.bs-tooltip-end .tooltip-arrow{left:calc(-1 * var(--bs-tooltip-arrow-height));width:var(--bs-tooltip-arrow-height);height:var(--bs-tooltip-arrow-width)}.bs-tooltip-auto[data-popper-placement^=right] .tooltip-arrow::before,.bs-tooltip-end .tooltip-arrow::before{right:-1px;border-width:calc(var(--bs-tooltip-arrow-width) * .5) var(--bs-tooltip-arrow-height) calc(var(--bs-tooltip-arrow-width) * .5) 0;border-right-color:var(--bs-tooltip-bg)}.bs-tooltip-auto[data-popper-placement^=bottom] .tooltip-arrow,.bs-tooltip-bottom .tooltip-arrow{top:calc(-1 * var(--bs-tooltip-arrow-height))}.bs-tooltip-auto[data-popper-placement^=bottom] .tooltip-arrow::before,.bs-tooltip-bottom .tooltip-arrow::before{bottom:-1px;border-width:0 calc(var(--bs-tooltip-arrow-width) * .5) var(--bs-tooltip-arrow-height);border-bottom-color:var(--bs-tooltip-bg)}.bs-tooltip-auto[data-popper-placement^=left] .tooltip-arrow,.bs-tooltip-start .tooltip-arrow{right:calc(-1 * var(--bs-tooltip-arrow-height));width:var(--bs-tooltip-arrow-height);height:var(--bs-tooltip-arrow-width)}.bs-tooltip-auto[data-popper-placement^=left] .tooltip-arrow::before,.bs-tooltip-start .tooltip-arrow::before{left:-1px;border-width:calc(var(--bs-tooltip-arrow-width) * .5) 0 calc(var(--bs-tooltip-arrow-width) * .5) var(--bs-tooltip-arrow-height);border-left-color:var(--bs-tooltip-bg)}.tooltip-inner{max-width:var(--bs-tooltip-max-width);padding:var(--bs-tooltip-padding-y) var(--bs-tooltip-padding-x);color:var(--bs-tooltip-color);text-align:center;background-color:var(--bs-tooltip-bg);border-radius:var(--bs-tooltip-border-radius)}.popover{--bs-popover-zindex:1070;--bs-popover-max-width:276px;--bs-popover-font-size:0.875rem;--bs-popover-bg:var(--bs-body-bg);--bs-popover-border-width:var(--bs-border-width);--bs-popover-border-color:var(--bs-border-color-translucent);--bs-popover-border-radius:var(--bs-border-radius-lg);--bs-popover-inner-border-radius:calc(var(--bs-border-radius-lg) - var(--bs-border-width));--bs-popover-box-shadow:var(--bs-box-shadow);--bs-popover-header-padding-x:1rem;--bs-popover-header-padding-y:0.5rem;--bs-popover-header-font-size:1rem;--bs-popover-header-color:inherit;--bs-popover-header-bg:var(--bs-secondary-bg);--bs-popover-body-padding-x:1rem;--bs-popover-body-padding-y:1rem;--bs-popover-body-color:var(--bs-body-color);--bs-popover-arrow-width:1rem;--bs-popover-arrow-height:0.5rem;--bs-popover-arrow-border:var(--bs-popover-border-color);z-index:var(--bs-popover-zindex);display:block;max-width:var(--bs-popover-max-width);font-family:var(--bs-font-sans-serif);font-style:normal;font-weight:400;line-height:1.5;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;white-space:normal;word-spacing:normal;line-break:auto;font-size:var(--bs-popover-font-size);word-wrap:break-word;background-color:var(--bs-popover-bg);background-clip:padding-box;border:var(--bs-popover-border-width) solid var(--bs-popover-border-color);border-radius:var(--bs-popover-border-radius)}.popover .popover-arrow{display:block;width:var(--bs-popover-arrow-width);height:var(--bs-popover-arrow-height)}.popover .popover-arrow::after,.popover .popover-arrow::before{position:absolute;display:block;content:"";border-color:transparent;border-style:solid;border-width:0}.bs-popover-auto[data-popper-placement^=top]>.popover-arrow,.bs-popover-top>.popover-arrow{bottom:calc(-1 * (var(--bs-popover-arrow-height)) - var(--bs-popover-border-width))}.bs-popover-auto[data-popper-placement^=top]>.popover-arrow::after,.bs-popover-auto[data-popper-placement^=top]>.popover-arrow::before,.bs-popover-top>.popover-arrow::after,.bs-popover-top>.popover-arrow::before{border-width:var(--bs-popover-arrow-height) calc(var(--bs-popover-arrow-width) * .5) 0}.bs-popover-auto[data-popper-placement^=top]>.popover-arrow::before,.bs-popover-top>.popover-arrow::before{bottom:0;border-top-color:var(--bs-popover-arrow-border)}.bs-popover-auto[data-popper-placement^=top]>.popover-arrow::after,.bs-popover-top>.popover-arrow::after{bottom:var(--bs-popover-border-width);border-top-color:var(--bs-popover-bg)}.bs-popover-auto[data-popper-placement^=right]>.popover-arrow,.bs-popover-end>.popover-arrow{left:calc(-1 * (var(--bs-popover-arrow-height)) - var(--bs-popover-border-width));width:var(--bs-popover-arrow-height);height:var(--bs-popover-arrow-width)}.bs-popover-auto[data-popper-placement^=right]>.popover-arrow::after,.bs-popover-auto[data-popper-placement^=right]>.popover-arrow::before,.bs-popover-end>.popover-arrow::after,.bs-popover-end>.popover-arrow::before{border-width:calc(var(--bs-popover-arrow-width) * .5) var(--bs-popover-arrow-height) calc(var(--bs-popover-arrow-width) * .5) 0}.bs-popover-auto[data-popper-placement^=right]>.popover-arrow::before,.bs-popover-end>.popover-arrow::before{left:0;border-right-color:var(--bs-popover-arrow-border)}.bs-popover-auto[data-popper-placement^=right]>.popover-arrow::after,.bs-popover-end>.popover-arrow::after{left:var(--bs-popover-border-width);border-right-color:var(--bs-popover-bg)}.bs-popover-auto[data-popper-placement^=bottom]>.popover-arrow,.bs-popover-bottom>.popover-arrow{top:calc(-1 * (var(--bs-popover-arrow-height)) - var(--bs-popover-border-width))}.bs-popover-auto[data-popper-placement^=bottom]>.popover-arrow::after,.bs-popover-auto[data-popper-placement^=bottom]>.popover-arrow::before,.bs-popover-bottom>.popover-arrow::after,.bs-popover-bottom>.popover-arrow::before{border-width:0 calc(var(--bs-popover-arrow-width) * .5) var(--bs-popover-arrow-height)}.bs-popover-auto[data-popper-placement^=bottom]>.popover-arrow::before,.bs-popover-bottom>.popover-arrow::before{top:0;border-bottom-color:var(--bs-popover-arrow-border)}.bs-popover-auto[data-popper-placement^=bottom]>.popover-arrow::after,.bs-popover-bottom>.popover-arrow::after{top:var(--bs-popover-border-width);border-bottom-color:var(--bs-popover-bg)}.bs-popover-auto[data-popper-placement^=bottom] .popover-header::before,.bs-popover-bottom .popover-header::before{position:absolute;top:0;left:50%;display:block;width:var(--bs-popover-arrow-width);margin-left:calc(-.5 * var(--bs-popover-arrow-width));content:"";border-bottom:var(--bs-popover-border-width) solid var(--bs-popover-header-bg)}.bs-popover-auto[data-popper-placement^=left]>.popover-arrow,.bs-popover-start>.popover-arrow{right:calc(-1 * (var(--bs-popover-arrow-height)) - var(--bs-popover-border-width));width:var(--bs-popover-arrow-height);height:var(--bs-popover-arrow-width)}.bs-popover-auto[data-popper-placement^=left]>.popover-arrow::after,.bs-popover-auto[data-popper-placement^=left]>.popover-arrow::before,.bs-popover-start>.popover-arrow::after,.bs-popover-start>.popover-arrow::before{border-width:calc(var(--bs-popover-arrow-width) * .5) 0 calc(var(--bs-popover-arrow-width) * .5) var(--bs-popover-arrow-height)}.bs-popover-auto[data-popper-placement^=left]>.popover-arrow::before,.bs-popover-start>.popover-arrow::before{right:0;border-left-color:var(--bs-popover-arrow-border)}.bs-popover-auto[data-popper-placement^=left]>.popover-arrow::after,.bs-popover-start>.popover-arrow::after{right:var(--bs-popover-border-width);border-left-color:var(--bs-popover-bg)}.popover-header{padding:var(--bs-popover-header-padding-y) var(--bs-popover-header-padding-x);margin-bottom:0;font-size:var(--bs-popover-header-font-size);color:var(--bs-popover-header-color);background-color:var(--bs-popover-header-bg);border-bottom:var(--bs-popover-border-width) solid var(--bs-popover-border-color);border-top-left-radius:var(--bs-popover-inner-border-radius);border-top-right-radius:var(--bs-popover-inner-border-radius)}.popover-header:empty{display:none}.popover-body{padding:var(--bs-popover-body-padding-y) var(--bs-popover-body-padding-x);color:var(--bs-popover-body-color)}.carousel{position:relative}.carousel.pointer-event{touch-action:pan-y}.carousel-inner{position:relative;width:100%;overflow:hidden}.carousel-inner::after{display:block;clear:both;content:""}.carousel-item{position:relative;display:none;float:left;width:100%;margin-right:-100%;-webkit-backface-visibility:hidden;backface-visibility:hidden;transition:transform .6s ease-in-out}@media (prefers-reduced-motion:reduce){.carousel-item{transition:none}}.carousel-item-next,.carousel-item-prev,.carousel-item.active{display:block}.active.carousel-item-end,.carousel-item-next:not(.carousel-item-start){transform:translateX(100%)}.active.carousel-item-start,.carousel-item-prev:not(.carousel-item-end){transform:translateX(-100%)}.carousel-fade .carousel-item{opacity:0;transition-property:opacity;transform:none}.carousel-fade .carousel-item-next.carousel-item-start,.carousel-fade .carousel-item-prev.carousel-item-end,.carousel-fade .carousel-item.active{z-index:1;opacity:1}.carousel-fade .active.carousel-item-end,.carousel-fade .active.carousel-item-start{z-index:0;opacity:0;transition:opacity 0s .6s}@media (prefers-reduced-motion:reduce){.carousel-fade .active.carousel-item-end,.carousel-fade .active.carousel-item-start{transition:none}}.carousel-control-next,.carousel-control-prev{position:absolute;top:0;bottom:0;z-index:1;display:flex;align-items:center;justify-content:center;width:15%;padding:0;color:#fff;text-align:center;background:0 0;filter:var(--bs-carousel-control-icon-filter);border:0;opacity:.5;transition:opacity .15s ease}@media (prefers-reduced-motion:reduce){.carousel-control-next,.carousel-control-prev{transition:none}}.carousel-control-next:focus,.carousel-control-next:hover,.carousel-control-prev:focus,.carousel-control-prev:hover{color:#fff;text-decoration:none;outline:0;opacity:.9}.carousel-control-prev{left:0}.carousel-control-next{right:0}.carousel-control-next-icon,.carousel-control-prev-icon{display:inline-block;width:2rem;height:2rem;background-repeat:no-repeat;background-position:50%;background-size:100% 100%}.carousel-control-prev-icon{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23fff'%3e%3cpath d='M11.354 1.646a.5.5 0 0 1 0 .708L5.707 8l5.647 5.646a.5.5 0 0 1-.708.708l-6-6a.5.5 0 0 1 0-.708l6-6a.5.5 0 0 1 .708 0'/%3e%3c/svg%3e")}.carousel-control-next-icon{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23fff'%3e%3cpath d='M4.646 1.646a.5.5 0 0 1 .708 0l6 6a.5.5 0 0 1 0 .708l-6 6a.5.5 0 0 1-.708-.708L10.293 8 4.646 2.354a.5.5 0 0 1 0-.708'/%3e%3c/svg%3e")}.carousel-indicators{position:absolute;right:0;bottom:0;left:0;z-index:2;display:flex;justify-content:center;padding:0;margin-right:15%;margin-bottom:1rem;margin-left:15%}.carousel-indicators [data-bs-target]{box-sizing:content-box;flex:0 1 auto;width:30px;height:3px;padding:0;margin-right:3px;margin-left:3px;text-indent:-999px;cursor:pointer;background-color:var(--bs-carousel-indicator-active-bg);background-clip:padding-box;border:0;border-top:10px solid transparent;border-bottom:10px solid transparent;opacity:.5;transition:opacity .6s ease}@media (prefers-reduced-motion:reduce){.carousel-indicators [data-bs-target]{transition:none}}.carousel-indicators .active{opacity:1}.carousel-caption{position:absolute;right:15%;bottom:1.25rem;left:15%;padding-top:1.25rem;padding-bottom:1.25rem;color:var(--bs-carousel-caption-color);text-align:center}.carousel-dark{--bs-carousel-indicator-active-bg:#000;--bs-carousel-caption-color:#000;--bs-carousel-control-icon-filter:invert(1) grayscale(100)}:root,[data-bs-theme=light]{--bs-carousel-indicator-active-bg:#fff;--bs-carousel-caption-color:#fff;--bs-carousel-control-icon-filter: }[data-bs-theme=dark]{--bs-carousel-indicator-active-bg:#000;--bs-carousel-caption-color:#000;--bs-carousel-control-icon-filter:invert(1) grayscale(100)}.spinner-border,.spinner-grow{display:inline-block;width:var(--bs-spinner-width);height:var(--bs-spinner-height);vertical-align:var(--bs-spinner-vertical-align);border-radius:50%;animation:var(--bs-spinner-animation-speed) linear infinite var(--bs-spinner-animation-name)}@keyframes spinner-border{to{transform:rotate(360deg)}}.spinner-border{--bs-spinner-width:2rem;--bs-spinner-height:2rem;--bs-spinner-vertical-align:-0.125em;--bs-spinner-border-width:0.25em;--bs-spinner-animation-speed:0.75s;--bs-spinner-animation-name:spinner-border;border:var(--bs-spinner-border-width) solid currentcolor;border-right-color:transparent}.spinner-border-sm{--bs-spinner-width:1rem;--bs-spinner-height:1rem;--bs-spinner-border-width:0.2em}@keyframes spinner-grow{0%{transform:scale(0)}50%{opacity:1;transform:none}}.spinner-grow{--bs-spinner-width:2rem;--bs-spinner-height:2rem;--bs-spinner-vertical-align:-0.125em;--bs-spinner-animation-speed:0.75s;--bs-spinner-animation-name:spinner-grow;background-color:currentcolor;opacity:0}.spinner-grow-sm{--bs-spinner-width:1rem;--bs-spinner-height:1rem}@media (prefers-reduced-motion:reduce){.spinner-border,.spinner-grow{--bs-spinner-animation-speed:1.5s}}.offcanvas,.offcanvas-lg,.offcanvas-md,.offcanvas-sm,.offcanvas-xl,.offcanvas-xxl{--bs-offcanvas-zindex:1045;--bs-offcanvas-width:400px;--bs-offcanvas-height:30vh;--bs-offcanvas-padding-x:1rem;--bs-offcanvas-padding-y:1rem;--bs-offcanvas-color:var(--bs-body-color);--bs-offcanvas-bg:var(--bs-body-bg);--bs-offcanvas-border-width:var(--bs-border-width);--bs-offcanvas-border-color:var(--bs-border-color-translucent);--bs-offcanvas-box-shadow:var(--bs-box-shadow-sm);--bs-offcanvas-transition:transform 0.3s ease-in-out;--bs-offcanvas-title-line-height:1.5}@media (max-width:575.98px){.offcanvas-sm{position:fixed;bottom:0;z-index:var(--bs-offcanvas-zindex);display:flex;flex-direction:column;max-width:100%;color:var(--bs-offcanvas-color);visibility:hidden;background-color:var(--bs-offcanvas-bg);background-clip:padding-box;outline:0;transition:var(--bs-offcanvas-transition)}}@media (max-width:575.98px) and (prefers-reduced-motion:reduce){.offcanvas-sm{transition:none}}@media (max-width:575.98px){.offcanvas-sm.offcanvas-start{top:0;left:0;width:var(--bs-offcanvas-width);border-right:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateX(-100%)}.offcanvas-sm.offcanvas-end{top:0;right:0;width:var(--bs-offcanvas-width);border-left:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateX(100%)}.offcanvas-sm.offcanvas-top{top:0;right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-bottom:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(-100%)}.offcanvas-sm.offcanvas-bottom{right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-top:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(100%)}.offcanvas-sm.show:not(.hiding),.offcanvas-sm.showing{transform:none}.offcanvas-sm.hiding,.offcanvas-sm.show,.offcanvas-sm.showing{visibility:visible}}@media (min-width:576px){.offcanvas-sm{--bs-offcanvas-height:auto;--bs-offcanvas-border-width:0;background-color:transparent!important}.offcanvas-sm .offcanvas-header{display:none}.offcanvas-sm .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible;background-color:transparent!important}}@media (max-width:767.98px){.offcanvas-md{position:fixed;bottom:0;z-index:var(--bs-offcanvas-zindex);display:flex;flex-direction:column;max-width:100%;color:var(--bs-offcanvas-color);visibility:hidden;background-color:var(--bs-offcanvas-bg);background-clip:padding-box;outline:0;transition:var(--bs-offcanvas-transition)}}@media (max-width:767.98px) and (prefers-reduced-motion:reduce){.offcanvas-md{transition:none}}@media (max-width:767.98px){.offcanvas-md.offcanvas-start{top:0;left:0;width:var(--bs-offcanvas-width);border-right:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateX(-100%)}.offcanvas-md.offcanvas-end{top:0;right:0;width:var(--bs-offcanvas-width);border-left:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateX(100%)}.offcanvas-md.offcanvas-top{top:0;right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-bottom:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(-100%)}.offcanvas-md.offcanvas-bottom{right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-top:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(100%)}.offcanvas-md.show:not(.hiding),.offcanvas-md.showing{transform:none}.offcanvas-md.hiding,.offcanvas-md.show,.offcanvas-md.showing{visibility:visible}}@media (min-width:768px){.offcanvas-md{--bs-offcanvas-height:auto;--bs-offcanvas-border-width:0;background-color:transparent!important}.offcanvas-md .offcanvas-header{display:none}.offcanvas-md .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible;background-color:transparent!important}}@media (max-width:991.98px){.offcanvas-lg{position:fixed;bottom:0;z-index:var(--bs-offcanvas-zindex);display:flex;flex-direction:column;max-width:100%;color:var(--bs-offcanvas-color);visibility:hidden;background-color:var(--bs-offcanvas-bg);background-clip:padding-box;outline:0;transition:var(--bs-offcanvas-transition)}}@media (max-width:991.98px) and (prefers-reduced-motion:reduce){.offcanvas-lg{transition:none}}@media (max-width:991.98px){.offcanvas-lg.offcanvas-start{top:0;left:0;width:var(--bs-offcanvas-width);border-right:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateX(-100%)}.offcanvas-lg.offcanvas-end{top:0;right:0;width:var(--bs-offcanvas-width);border-left:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateX(100%)}.offcanvas-lg.offcanvas-top{top:0;right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-bottom:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(-100%)}.offcanvas-lg.offcanvas-bottom{right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-top:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(100%)}.offcanvas-lg.show:not(.hiding),.offcanvas-lg.showing{transform:none}.offcanvas-lg.hiding,.offcanvas-lg.show,.offcanvas-lg.showing{visibility:visible}}@media (min-width:992px){.offcanvas-lg{--bs-offcanvas-height:auto;--bs-offcanvas-border-width:0;background-color:transparent!important}.offcanvas-lg .offcanvas-header{display:none}.offcanvas-lg .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible;background-color:transparent!important}}@media (max-width:1199.98px){.offcanvas-xl{position:fixed;bottom:0;z-index:var(--bs-offcanvas-zindex);display:flex;flex-direction:column;max-width:100%;color:var(--bs-offcanvas-color);visibility:hidden;background-color:var(--bs-offcanvas-bg);background-clip:padding-box;outline:0;transition:var(--bs-offcanvas-transition)}}@media (max-width:1199.98px) and (prefers-reduced-motion:reduce){.offcanvas-xl{transition:none}}@media (max-width:1199.98px){.offcanvas-xl.offcanvas-start{top:0;left:0;width:var(--bs-offcanvas-width);border-right:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateX(-100%)}.offcanvas-xl.offcanvas-end{top:0;right:0;width:var(--bs-offcanvas-width);border-left:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateX(100%)}.offcanvas-xl.offcanvas-top{top:0;right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-bottom:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(-100%)}.offcanvas-xl.offcanvas-bottom{right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-top:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(100%)}.offcanvas-xl.show:not(.hiding),.offcanvas-xl.showing{transform:none}.offcanvas-xl.hiding,.offcanvas-xl.show,.offcanvas-xl.showing{visibility:visible}}@media (min-width:1200px){.offcanvas-xl{--bs-offcanvas-height:auto;--bs-offcanvas-border-width:0;background-color:transparent!important}.offcanvas-xl .offcanvas-header{display:none}.offcanvas-xl .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible;background-color:transparent!important}}@media (max-width:1399.98px){.offcanvas-xxl{position:fixed;bottom:0;z-index:var(--bs-offcanvas-zindex);display:flex;flex-direction:column;max-width:100%;color:var(--bs-offcanvas-color);visibility:hidden;background-color:var(--bs-offcanvas-bg);background-clip:padding-box;outline:0;transition:var(--bs-offcanvas-transition)}}@media (max-width:1399.98px) and (prefers-reduced-motion:reduce){.offcanvas-xxl{transition:none}}@media (max-width:1399.98px){.offcanvas-xxl.offcanvas-start{top:0;left:0;width:var(--bs-offcanvas-width);border-right:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateX(-100%)}.offcanvas-xxl.offcanvas-end{top:0;right:0;width:var(--bs-offcanvas-width);border-left:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateX(100%)}.offcanvas-xxl.offcanvas-top{top:0;right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-bottom:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(-100%)}.offcanvas-xxl.offcanvas-bottom{right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-top:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(100%)}.offcanvas-xxl.show:not(.hiding),.offcanvas-xxl.showing{transform:none}.offcanvas-xxl.hiding,.offcanvas-xxl.show,.offcanvas-xxl.showing{visibility:visible}}@media (min-width:1400px){.offcanvas-xxl{--bs-offcanvas-height:auto;--bs-offcanvas-border-width:0;background-color:transparent!important}.offcanvas-xxl .offcanvas-header{display:none}.offcanvas-xxl .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible;background-color:transparent!important}}.offcanvas{position:fixed;bottom:0;z-index:var(--bs-offcanvas-zindex);display:flex;flex-direction:column;max-width:100%;color:var(--bs-offcanvas-color);visibility:hidden;background-color:var(--bs-offcanvas-bg);background-clip:padding-box;outline:0;transition:var(--bs-offcanvas-transition)}@media (prefers-reduced-motion:reduce){.offcanvas{transition:none}}.offcanvas.offcanvas-start{top:0;left:0;width:var(--bs-offcanvas-width);border-right:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateX(-100%)}.offcanvas.offcanvas-end{top:0;right:0;width:var(--bs-offcanvas-width);border-left:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateX(100%)}.offcanvas.offcanvas-top{top:0;right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-bottom:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(-100%)}.offcanvas.offcanvas-bottom{right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-top:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(100%)}.offcanvas.show:not(.hiding),.offcanvas.showing{transform:none}.offcanvas.hiding,.offcanvas.show,.offcanvas.showing{visibility:visible}.offcanvas-backdrop{position:fixed;top:0;left:0;z-index:1040;width:100vw;height:100vh;background-color:#000}.offcanvas-backdrop.fade{opacity:0}.offcanvas-backdrop.show{opacity:.5}.offcanvas-header{display:flex;align-items:center;padding:var(--bs-offcanvas-padding-y) var(--bs-offcanvas-padding-x)}.offcanvas-header .btn-close{padding:calc(var(--bs-offcanvas-padding-y) * .5) calc(var(--bs-offcanvas-padding-x) * .5);margin-top:calc(-.5 * var(--bs-offcanvas-padding-y));margin-right:calc(-.5 * var(--bs-offcanvas-padding-x));margin-bottom:calc(-.5 * var(--bs-offcanvas-padding-y));margin-left:auto}.offcanvas-title{margin-bottom:0;line-height:var(--bs-offcanvas-title-line-height)}.offcanvas-body{flex-grow:1;padding:var(--bs-offcanvas-padding-y) var(--bs-offcanvas-padding-x);overflow-y:auto}.placeholder{display:inline-block;min-height:1em;vertical-align:middle;cursor:wait;background-color:currentcolor;opacity:.5}.placeholder.btn::before{display:inline-block;content:""}.placeholder-xs{min-height:.6em}.placeholder-sm{min-height:.8em}.placeholder-lg{min-height:1.2em}.placeholder-glow .placeholder{animation:placeholder-glow 2s ease-in-out infinite}@keyframes placeholder-glow{50%{opacity:.2}}.placeholder-wave{-webkit-mask-image:linear-gradient(130deg,#000 55%,rgba(0,0,0,0.8) 75%,#000 95%);mask-image:linear-gradient(130deg,#000 55%,rgba(0,0,0,0.8) 75%,#000 95%);-webkit-mask-size:200% 100%;mask-size:200% 100%;animation:placeholder-wave 2s linear infinite}@keyframes placeholder-wave{100%{-webkit-mask-position:-200% 0%;mask-position:-200% 0%}}.clearfix::after{display:block;clear:both;content:""}.text-bg-primary{color:#fff!important;background-color:RGBA(var(--bs-primary-rgb),var(--bs-bg-opacity,1))!important}.text-bg-secondary{color:#fff!important;background-color:RGBA(var(--bs-secondary-rgb),var(--bs-bg-opacity,1))!important}.text-bg-success{color:#fff!important;background-color:RGBA(var(--bs-success-rgb),var(--bs-bg-opacity,1))!important}.text-bg-info{color:#000!important;background-color:RGBA(var(--bs-info-rgb),var(--bs-bg-opacity,1))!important}.text-bg-warning{color:#000!important;background-color:RGBA(var(--bs-warning-rgb),var(--bs-bg-opacity,1))!important}.text-bg-danger{color:#fff!important;background-color:RGBA(var(--bs-danger-rgb),var(--bs-bg-opacity,1))!important}.text-bg-light{color:#000!important;background-color:RGBA(var(--bs-light-rgb),var(--bs-bg-opacity,1))!important}.text-bg-dark{color:#fff!important;background-color:RGBA(var(--bs-dark-rgb),var(--bs-bg-opacity,1))!important}.link-primary{color:RGBA(var(--bs-primary-rgb),var(--bs-link-opacity,1))!important;-webkit-text-decoration-color:RGBA(var(--bs-primary-rgb),var(--bs-link-underline-opacity,1))!important;text-decoration-color:RGBA(var(--bs-primary-rgb),var(--bs-link-underline-opacity,1))!important}.link-primary:focus,.link-primary:hover{color:RGBA(10,88,202,var(--bs-link-opacity,1))!important;-webkit-text-decoration-color:RGBA(10,88,202,var(--bs-link-underline-opacity,1))!important;text-decoration-color:RGBA(10,88,202,var(--bs-link-underline-opacity,1))!important}.link-secondary{color:RGBA(var(--bs-secondary-rgb),var(--bs-link-opacity,1))!important;-webkit-text-decoration-color:RGBA(var(--bs-secondary-rgb),var(--bs-link-underline-opacity,1))!important;text-decoration-color:RGBA(var(--bs-secondary-rgb),var(--bs-link-underline-opacity,1))!important}.link-secondary:focus,.link-secondary:hover{color:RGBA(86,94,100,var(--bs-link-opacity,1))!important;-webkit-text-decoration-color:RGBA(86,94,100,var(--bs-link-underline-opacity,1))!important;text-decoration-color:RGBA(86,94,100,var(--bs-link-underline-opacity,1))!important}.link-success{color:RGBA(var(--bs-success-rgb),var(--bs-link-opacity,1))!important;-webkit-text-decoration-color:RGBA(var(--bs-success-rgb),var(--bs-link-underline-opacity,1))!important;text-decoration-color:RGBA(var(--bs-success-rgb),var(--bs-link-underline-opacity,1))!important}.link-success:focus,.link-success:hover{color:RGBA(20,108,67,var(--bs-link-opacity,1))!important;-webkit-text-decoration-color:RGBA(20,108,67,var(--bs-link-underline-opacity,1))!important;text-decoration-color:RGBA(20,108,67,var(--bs-link-underline-opacity,1))!important}.link-info{color:RGBA(var(--bs-info-rgb),var(--bs-link-opacity,1))!important;-webkit-text-decoration-color:RGBA(var(--bs-info-rgb),var(--bs-link-underline-opacity,1))!important;text-decoration-color:RGBA(var(--bs-info-rgb),var(--bs-link-underline-opacity,1))!important}.link-info:focus,.link-info:hover{color:RGBA(61,213,243,var(--bs-link-opacity,1))!important;-webkit-text-decoration-color:RGBA(61,213,243,var(--bs-link-underline-opacity,1))!important;text-decoration-color:RGBA(61,213,243,var(--bs-link-underline-opacity,1))!important}.link-warning{color:RGBA(var(--bs-warning-rgb),var(--bs-link-opacity,1))!important;-webkit-text-decoration-color:RGBA(var(--bs-warning-rgb),var(--bs-link-underline-opacity,1))!important;text-decoration-color:RGBA(var(--bs-warning-rgb),var(--bs-link-underline-opacity,1))!important}.link-warning:focus,.link-warning:hover{color:RGBA(255,205,57,var(--bs-link-opacity,1))!important;-webkit-text-decoration-color:RGBA(255,205,57,var(--bs-link-underline-opacity,1))!important;text-decoration-color:RGBA(255,205,57,var(--bs-link-underline-opacity,1))!important}.link-danger{color:RGBA(var(--bs-danger-rgb),var(--bs-link-opacity,1))!important;-webkit-text-decoration-color:RGBA(var(--bs-danger-rgb),var(--bs-link-underline-opacity,1))!important;text-decoration-color:RGBA(var(--bs-danger-rgb),var(--bs-link-underline-opacity,1))!important}.link-danger:focus,.link-danger:hover{color:RGBA(176,42,55,var(--bs-link-opacity,1))!important;-webkit-text-decoration-color:RGBA(176,42,55,var(--bs-link-underline-opacity,1))!important;text-decoration-color:RGBA(176,42,55,var(--bs-link-underline-opacity,1))!important}.link-light{color:RGBA(var(--bs-light-rgb),var(--bs-link-opacity,1))!important;-webkit-text-decoration-color:RGBA(var(--bs-light-rgb),var(--bs-link-underline-opacity,1))!important;text-decoration-color:RGBA(var(--bs-light-rgb),var(--bs-link-underline-opacity,1))!important}.link-light:focus,.link-light:hover{color:RGBA(249,250,251,var(--bs-link-opacity,1))!important;-webkit-text-decoration-color:RGBA(249,250,251,var(--bs-link-underline-opacity,1))!important;text-decoration-color:RGBA(249,250,251,var(--bs-link-underline-opacity,1))!important}.link-dark{color:RGBA(var(--bs-dark-rgb),var(--bs-link-opacity,1))!important;-webkit-text-decoration-color:RGBA(var(--bs-dark-rgb),var(--bs-link-underline-opacity,1))!important;text-decoration-color:RGBA(var(--bs-dark-rgb),var(--bs-link-underline-opacity,1))!important}.link-dark:focus,.link-dark:hover{color:RGBA(26,30,33,var(--bs-link-opacity,1))!important;-webkit-text-decoration-color:RGBA(26,30,33,var(--bs-link-underline-opacity,1))!important;text-decoration-color:RGBA(26,30,33,var(--bs-link-underline-opacity,1))!important}.link-body-emphasis{color:RGBA(var(--bs-emphasis-color-rgb),var(--bs-link-opacity,1))!important;-webkit-text-decoration-color:RGBA(var(--bs-emphasis-color-rgb),var(--bs-link-underline-opacity,1))!important;text-decoration-color:RGBA(var(--bs-emphasis-color-rgb),var(--bs-link-underline-opacity,1))!important}.link-body-emphasis:focus,.link-body-emphasis:hover{color:RGBA(var(--bs-emphasis-color-rgb),var(--bs-link-opacity,.75))!important;-webkit-text-decoration-color:RGBA(var(--bs-emphasis-color-rgb),var(--bs-link-underline-opacity,0.75))!important;text-decoration-color:RGBA(var(--bs-emphasis-color-rgb),var(--bs-link-underline-opacity,0.75))!important}.focus-ring:focus{outline:0;box-shadow:var(--bs-focus-ring-x,0) var(--bs-focus-ring-y,0) var(--bs-focus-ring-blur,0) var(--bs-focus-ring-width) var(--bs-focus-ring-color)}.icon-link{display:inline-flex;gap:.375rem;align-items:center;-webkit-text-decoration-color:rgba(var(--bs-link-color-rgb),var(--bs-link-opacity,0.5));text-decoration-color:rgba(var(--bs-link-color-rgb),var(--bs-link-opacity,0.5));text-underline-offset:0.25em;-webkit-backface-visibility:hidden;backface-visibility:hidden}.icon-link>.bi{flex-shrink:0;width:1em;height:1em;fill:currentcolor;transition:.2s ease-in-out transform}@media (prefers-reduced-motion:reduce){.icon-link>.bi{transition:none}}.icon-link-hover:focus-visible>.bi,.icon-link-hover:hover>.bi{transform:var(--bs-icon-link-transform,translate3d(.25em,0,0))}.ratio{position:relative;width:100%}.ratio::before{display:block;padding-top:var(--bs-aspect-ratio);content:""}.ratio>*{position:absolute;top:0;left:0;width:100%;height:100%}.ratio-1x1{--bs-aspect-ratio:100%}.ratio-4x3{--bs-aspect-ratio:75%}.ratio-16x9{--bs-aspect-ratio:56.25%}.ratio-21x9{--bs-aspect-ratio:42.8571428571%}.fixed-top{position:fixed;top:0;right:0;left:0;z-index:1030}.fixed-bottom{position:fixed;right:0;bottom:0;left:0;z-index:1030}.sticky-top{position:-webkit-sticky;position:sticky;top:0;z-index:1020}.sticky-bottom{position:-webkit-sticky;position:sticky;bottom:0;z-index:1020}@media (min-width:576px){.sticky-sm-top{position:-webkit-sticky;position:sticky;top:0;z-index:1020}.sticky-sm-bottom{position:-webkit-sticky;position:sticky;bottom:0;z-index:1020}}@media (min-width:768px){.sticky-md-top{position:-webkit-sticky;position:sticky;top:0;z-index:1020}.sticky-md-bottom{position:-webkit-sticky;position:sticky;bottom:0;z-index:1020}}@media (min-width:992px){.sticky-lg-top{position:-webkit-sticky;position:sticky;top:0;z-index:1020}.sticky-lg-bottom{position:-webkit-sticky;position:sticky;bottom:0;z-index:1020}}@media (min-width:1200px){.sticky-xl-top{position:-webkit-sticky;position:sticky;top:0;z-index:1020}.sticky-xl-bottom{position:-webkit-sticky;position:sticky;bottom:0;z-index:1020}}@media (min-width:1400px){.sticky-xxl-top{position:-webkit-sticky;position:sticky;top:0;z-index:1020}.sticky-xxl-bottom{position:-webkit-sticky;position:sticky;bottom:0;z-index:1020}}.hstack{display:flex;flex-direction:row;align-items:center;align-self:stretch}.vstack{display:flex;flex:1 1 auto;flex-direction:column;align-self:stretch}.visually-hidden,.visually-hidden-focusable:not(:focus):not(:focus-within){width:1px!important;height:1px!important;padding:0!important;margin:-1px!important;overflow:hidden!important;clip:rect(0,0,0,0)!important;white-space:nowrap!important;border:0!important}.visually-hidden-focusable:not(:focus):not(:focus-within):not(caption),.visually-hidden:not(caption){position:absolute!important}.visually-hidden *,.visually-hidden-focusable:not(:focus):not(:focus-within) *{overflow:hidden!important}.stretched-link::after{position:absolute;top:0;right:0;bottom:0;left:0;z-index:1;content:""}.text-truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.vr{display:inline-block;align-self:stretch;width:var(--bs-border-width);min-height:1em;background-color:currentcolor;opacity:.25}.align-baseline{vertical-align:baseline!important}.align-top{vertical-align:top!important}.align-middle{vertical-align:middle!important}.align-bottom{vertical-align:bottom!important}.align-text-bottom{vertical-align:text-bottom!important}.align-text-top{vertical-align:text-top!important}.float-start{float:left!important}.float-end{float:right!important}.float-none{float:none!important}.object-fit-contain{-o-object-fit:contain!important;object-fit:contain!important}.object-fit-cover{-o-object-fit:cover!important;object-fit:cover!important}.object-fit-fill{-o-object-fit:fill!important;object-fit:fill!important}.object-fit-scale{-o-object-fit:scale-down!important;object-fit:scale-down!important}.object-fit-none{-o-object-fit:none!important;object-fit:none!important}.opacity-0{opacity:0!important}.opacity-25{opacity:.25!important}.opacity-50{opacity:.5!important}.opacity-75{opacity:.75!important}.opacity-100{opacity:1!important}.overflow-auto{overflow:auto!important}.overflow-hidden{overflow:hidden!important}.overflow-visible{overflow:visible!important}.overflow-scroll{overflow:scroll!important}.overflow-x-auto{overflow-x:auto!important}.overflow-x-hidden{overflow-x:hidden!important}.overflow-x-visible{overflow-x:visible!important}.overflow-x-scroll{overflow-x:scroll!important}.overflow-y-auto{overflow-y:auto!important}.overflow-y-hidden{overflow-y:hidden!important}.overflow-y-visible{overflow-y:visible!important}.overflow-y-scroll{overflow-y:scroll!important}.d-inline{display:inline!important}.d-inline-block{display:inline-block!important}.d-block{display:block!important}.d-grid{display:grid!important}.d-inline-grid{display:inline-grid!important}.d-table{display:table!important}.d-table-row{display:table-row!important}.d-table-cell{display:table-cell!important}.d-flex{display:flex!important}.d-inline-flex{display:inline-flex!important}.d-none{display:none!important}.shadow{box-shadow:var(--bs-box-shadow)!important}.shadow-sm{box-shadow:var(--bs-box-shadow-sm)!important}.shadow-lg{box-shadow:var(--bs-box-shadow-lg)!important}.shadow-none{box-shadow:none!important}.focus-ring-primary{--bs-focus-ring-color:rgba(var(--bs-primary-rgb), var(--bs-focus-ring-opacity))}.focus-ring-secondary{--bs-focus-ring-color:rgba(var(--bs-secondary-rgb), var(--bs-focus-ring-opacity))}.focus-ring-success{--bs-focus-ring-color:rgba(var(--bs-success-rgb), var(--bs-focus-ring-opacity))}.focus-ring-info{--bs-focus-ring-color:rgba(var(--bs-info-rgb), var(--bs-focus-ring-opacity))}.focus-ring-warning{--bs-focus-ring-color:rgba(var(--bs-warning-rgb), var(--bs-focus-ring-opacity))}.focus-ring-danger{--bs-focus-ring-color:rgba(var(--bs-danger-rgb), var(--bs-focus-ring-opacity))}.focus-ring-light{--bs-focus-ring-color:rgba(var(--bs-light-rgb), var(--bs-focus-ring-opacity))}.focus-ring-dark{--bs-focus-ring-color:rgba(var(--bs-dark-rgb), var(--bs-focus-ring-opacity))}.position-static{position:static!important}.position-relative{position:relative!important}.position-absolute{position:absolute!important}.position-fixed{position:fixed!important}.position-sticky{position:-webkit-sticky!important;position:sticky!important}.top-0{top:0!important}.top-50{top:50%!important}.top-100{top:100%!important}.bottom-0{bottom:0!important}.bottom-50{bottom:50%!important}.bottom-100{bottom:100%!important}.start-0{left:0!important}.start-50{left:50%!important}.start-100{left:100%!important}.end-0{right:0!important}.end-50{right:50%!important}.end-100{right:100%!important}.translate-middle{transform:translate(-50%,-50%)!important}.translate-middle-x{transform:translateX(-50%)!important}.translate-middle-y{transform:translateY(-50%)!important}.border{border:var(--bs-border-width) var(--bs-border-style) var(--bs-border-color)!important}.border-0{border:0!important}.border-top{border-top:var(--bs-border-width) var(--bs-border-style) var(--bs-border-color)!important}.border-top-0{border-top:0!important}.border-end{border-right:var(--bs-border-width) var(--bs-border-style) var(--bs-border-color)!important}.border-end-0{border-right:0!important}.border-bottom{border-bottom:var(--bs-border-width) var(--bs-border-style) var(--bs-border-color)!important}.border-bottom-0{border-bottom:0!important}.border-start{border-left:var(--bs-border-width) var(--bs-border-style) var(--bs-border-color)!important}.border-start-0{border-left:0!important}.border-primary{--bs-border-opacity:1;border-color:rgba(var(--bs-primary-rgb),var(--bs-border-opacity))!important}.border-secondary{--bs-border-opacity:1;border-color:rgba(var(--bs-secondary-rgb),var(--bs-border-opacity))!important}.border-success{--bs-border-opacity:1;border-color:rgba(var(--bs-success-rgb),var(--bs-border-opacity))!important}.border-info{--bs-border-opacity:1;border-color:rgba(var(--bs-info-rgb),var(--bs-border-opacity))!important}.border-warning{--bs-border-opacity:1;border-color:rgba(var(--bs-warning-rgb),var(--bs-border-opacity))!important}.border-danger{--bs-border-opacity:1;border-color:rgba(var(--bs-danger-rgb),var(--bs-border-opacity))!important}.border-light{--bs-border-opacity:1;border-color:rgba(var(--bs-light-rgb),var(--bs-border-opacity))!important}.border-dark{--bs-border-opacity:1;border-color:rgba(var(--bs-dark-rgb),var(--bs-border-opacity))!important}.border-black{--bs-border-opacity:1;border-color:rgba(var(--bs-black-rgb),var(--bs-border-opacity))!important}.border-white{--bs-border-opacity:1;border-color:rgba(var(--bs-white-rgb),var(--bs-border-opacity))!important}.border-primary-subtle{border-color:var(--bs-primary-border-subtle)!important}.border-secondary-subtle{border-color:var(--bs-secondary-border-subtle)!important}.border-success-subtle{border-color:var(--bs-success-border-subtle)!important}.border-info-subtle{border-color:var(--bs-info-border-subtle)!important}.border-warning-subtle{border-color:var(--bs-warning-border-subtle)!important}.border-danger-subtle{border-color:var(--bs-danger-border-subtle)!important}.border-light-subtle{border-color:var(--bs-light-border-subtle)!important}.border-dark-subtle{border-color:var(--bs-dark-border-subtle)!important}.border-1{border-width:1px!important}.border-2{border-width:2px!important}.border-3{border-width:3px!important}.border-4{border-width:4px!important}.border-5{border-width:5px!important}.border-opacity-10{--bs-border-opacity:0.1}.border-opacity-25{--bs-border-opacity:0.25}.border-opacity-50{--bs-border-opacity:0.5}.border-opacity-75{--bs-border-opacity:0.75}.border-opacity-100{--bs-border-opacity:1}.w-25{width:25%!important}.w-50{width:50%!important}.w-75{width:75%!important}.w-100{width:100%!important}.w-auto{width:auto!important}.mw-100{max-width:100%!important}.vw-100{width:100vw!important}.min-vw-100{min-width:100vw!important}.h-25{height:25%!important}.h-50{height:50%!important}.h-75{height:75%!important}.h-100{height:100%!important}.h-auto{height:auto!important}.mh-100{max-height:100%!important}.vh-100{height:100vh!important}.min-vh-100{min-height:100vh!important}.flex-fill{flex:1 1 auto!important}.flex-row{flex-direction:row!important}.flex-column{flex-direction:column!important}.flex-row-reverse{flex-direction:row-reverse!important}.flex-column-reverse{flex-direction:column-reverse!important}.flex-grow-0{flex-grow:0!important}.flex-grow-1{flex-grow:1!important}.flex-shrink-0{flex-shrink:0!important}.flex-shrink-1{flex-shrink:1!important}.flex-wrap{flex-wrap:wrap!important}.flex-nowrap{flex-wrap:nowrap!important}.flex-wrap-reverse{flex-wrap:wrap-reverse!important}.justify-content-start{justify-content:flex-start!important}.justify-content-end{justify-content:flex-end!important}.justify-content-center{justify-content:center!important}.justify-content-between{justify-content:space-between!important}.justify-content-around{justify-content:space-around!important}.justify-content-evenly{justify-content:space-evenly!important}.align-items-start{align-items:flex-start!important}.align-items-end{align-items:flex-end!important}.align-items-center{align-items:center!important}.align-items-baseline{align-items:baseline!important}.align-items-stretch{align-items:stretch!important}.align-content-start{align-content:flex-start!important}.align-content-end{align-content:flex-end!important}.align-content-center{align-content:center!important}.align-content-between{align-content:space-between!important}.align-content-around{align-content:space-around!important}.align-content-stretch{align-content:stretch!important}.align-self-auto{align-self:auto!important}.align-self-start{align-self:flex-start!important}.align-self-end{align-self:flex-end!important}.align-self-center{align-self:center!important}.align-self-baseline{align-self:baseline!important}.align-self-stretch{align-self:stretch!important}.order-first{order:-1!important}.order-0{order:0!important}.order-1{order:1!important}.order-2{order:2!important}.order-3{order:3!important}.order-4{order:4!important}.order-5{order:5!important}.order-last{order:6!important}.m-0{margin:0!important}.m-1{margin:.25rem!important}.m-2{margin:.5rem!important}.m-3{margin:1rem!important}.m-4{margin:1.5rem!important}.m-5{margin:3rem!important}.m-auto{margin:auto!important}.mx-0{margin-right:0!important;margin-left:0!important}.mx-1{margin-right:.25rem!important;margin-left:.25rem!important}.mx-2{margin-right:.5rem!important;margin-left:.5rem!important}.mx-3{margin-right:1rem!important;margin-left:1rem!important}.mx-4{margin-right:1.5rem!important;margin-left:1.5rem!important}.mx-5{margin-right:3rem!important;margin-left:3rem!important}.mx-auto{margin-right:auto!important;margin-left:auto!important}.my-0{margin-top:0!important;margin-bottom:0!important}.my-1{margin-top:.25rem!important;margin-bottom:.25rem!important}.my-2{margin-top:.5rem!important;margin-bottom:.5rem!important}.my-3{margin-top:1rem!important;margin-bottom:1rem!important}.my-4{margin-top:1.5rem!important;margin-bottom:1.5rem!important}.my-5{margin-top:3rem!important;margin-bottom:3rem!important}.my-auto{margin-top:auto!important;margin-bottom:auto!important}.mt-0{margin-top:0!important}.mt-1{margin-top:.25rem!important}.mt-2{margin-top:.5rem!important}.mt-3{margin-top:1rem!important}.mt-4{margin-top:1.5rem!important}.mt-5{margin-top:3rem!important}.mt-auto{margin-top:auto!important}.me-0{margin-right:0!important}.me-1{margin-right:.25rem!important}.me-2{margin-right:.5rem!important}.me-3{margin-right:1rem!important}.me-4{margin-right:1.5rem!important}.me-5{margin-right:3rem!important}.me-auto{margin-right:auto!important}.mb-0{margin-bottom:0!important}.mb-1{margin-bottom:.25rem!important}.mb-2{margin-bottom:.5rem!important}.mb-3{margin-bottom:1rem!important}.mb-4{margin-bottom:1.5rem!important}.mb-5{margin-bottom:3rem!important}.mb-auto{margin-bottom:auto!important}.ms-0{margin-left:0!important}.ms-1{margin-left:.25rem!important}.ms-2{margin-left:.5rem!important}.ms-3{margin-left:1rem!important}.ms-4{margin-left:1.5rem!important}.ms-5{margin-left:3rem!important}.ms-auto{margin-left:auto!important}.p-0{padding:0!important}.p-1{padding:.25rem!important}.p-2{padding:.5rem!important}.p-3{padding:1rem!important}.p-4{padding:1.5rem!important}.p-5{padding:3rem!important}.px-0{padding-right:0!important;padding-left:0!important}.px-1{padding-right:.25rem!important;padding-left:.25rem!important}.px-2{padding-right:.5rem!important;padding-left:.5rem!important}.px-3{padding-right:1rem!important;padding-left:1rem!important}.px-4{padding-right:1.5rem!important;padding-left:1.5rem!important}.px-5{padding-right:3rem!important;padding-left:3rem!important}.py-0{padding-top:0!important;padding-bottom:0!important}.py-1{padding-top:.25rem!important;padding-bottom:.25rem!important}.py-2{padding-top:.5rem!important;padding-bottom:.5rem!important}.py-3{padding-top:1rem!important;padding-bottom:1rem!important}.py-4{padding-top:1.5rem!important;padding-bottom:1.5rem!important}.py-5{padding-top:3rem!important;padding-bottom:3rem!important}.pt-0{padding-top:0!important}.pt-1{padding-top:.25rem!important}.pt-2{padding-top:.5rem!important}.pt-3{padding-top:1rem!important}.pt-4{padding-top:1.5rem!important}.pt-5{padding-top:3rem!important}.pe-0{padding-right:0!important}.pe-1{padding-right:.25rem!important}.pe-2{padding-right:.5rem!important}.pe-3{padding-right:1rem!important}.pe-4{padding-right:1.5rem!important}.pe-5{padding-right:3rem!important}.pb-0{padding-bottom:0!important}.pb-1{padding-bottom:.25rem!important}.pb-2{padding-bottom:.5rem!important}.pb-3{padding-bottom:1rem!important}.pb-4{padding-bottom:1.5rem!important}.pb-5{padding-bottom:3rem!important}.ps-0{padding-left:0!important}.ps-1{padding-left:.25rem!important}.ps-2{padding-left:.5rem!important}.ps-3{padding-left:1rem!important}.ps-4{padding-left:1.5rem!important}.ps-5{padding-left:3rem!important}.gap-0{gap:0!important}.gap-1{gap:.25rem!important}.gap-2{gap:.5rem!important}.gap-3{gap:1rem!important}.gap-4{gap:1.5rem!important}.gap-5{gap:3rem!important}.row-gap-0{row-gap:0!important}.row-gap-1{row-gap:.25rem!important}.row-gap-2{row-gap:.5rem!important}.row-gap-3{row-gap:1rem!important}.row-gap-4{row-gap:1.5rem!important}.row-gap-5{row-gap:3rem!important}.column-gap-0{-moz-column-gap:0!important;column-gap:0!important}.column-gap-1{-moz-column-gap:0.25rem!important;column-gap:.25rem!important}.column-gap-2{-moz-column-gap:0.5rem!important;column-gap:.5rem!important}.column-gap-3{-moz-column-gap:1rem!important;column-gap:1rem!important}.column-gap-4{-moz-column-gap:1.5rem!important;column-gap:1.5rem!important}.column-gap-5{-moz-column-gap:3rem!important;column-gap:3rem!important}.font-monospace{font-family:var(--bs-font-monospace)!important}.fs-1{font-size:calc(1.375rem + 1.5vw)!important}.fs-2{font-size:calc(1.325rem + .9vw)!important}.fs-3{font-size:calc(1.3rem + .6vw)!important}.fs-4{font-size:calc(1.275rem + .3vw)!important}.fs-5{font-size:1.25rem!important}.fs-6{font-size:1rem!important}.fst-italic{font-style:italic!important}.fst-normal{font-style:normal!important}.fw-lighter{font-weight:lighter!important}.fw-light{font-weight:300!important}.fw-normal{font-weight:400!important}.fw-medium{font-weight:500!important}.fw-semibold{font-weight:600!important}.fw-bold{font-weight:700!important}.fw-bolder{font-weight:bolder!important}.lh-1{line-height:1!important}.lh-sm{line-height:1.25!important}.lh-base{line-height:1.5!important}.lh-lg{line-height:2!important}.text-start{text-align:left!important}.text-end{text-align:right!important}.text-center{text-align:center!important}.text-decoration-none{text-decoration:none!important}.text-decoration-underline{text-decoration:underline!important}.text-decoration-line-through{text-decoration:line-through!important}.text-lowercase{text-transform:lowercase!important}.text-uppercase{text-transform:uppercase!important}.text-capitalize{text-transform:capitalize!important}.text-wrap{white-space:normal!important}.text-nowrap{white-space:nowrap!important}.text-break{word-wrap:break-word!important;word-break:break-word!important}.text-primary{--bs-text-opacity:1;color:rgba(var(--bs-primary-rgb),var(--bs-text-opacity))!important}.text-secondary{--bs-text-opacity:1;color:rgba(var(--bs-secondary-rgb),var(--bs-text-opacity))!important}.text-success{--bs-text-opacity:1;color:rgba(var(--bs-success-rgb),var(--bs-text-opacity))!important}.text-info{--bs-text-opacity:1;color:rgba(var(--bs-info-rgb),var(--bs-text-opacity))!important}.text-warning{--bs-text-opacity:1;color:rgba(var(--bs-warning-rgb),var(--bs-text-opacity))!important}.text-danger{--bs-text-opacity:1;color:rgba(var(--bs-danger-rgb),var(--bs-text-opacity))!important}.text-light{--bs-text-opacity:1;color:rgba(var(--bs-light-rgb),var(--bs-text-opacity))!important}.text-dark{--bs-text-opacity:1;color:rgba(var(--bs-dark-rgb),var(--bs-text-opacity))!important}.text-black{--bs-text-opacity:1;color:rgba(var(--bs-black-rgb),var(--bs-text-opacity))!important}.text-white{--bs-text-opacity:1;color:rgba(var(--bs-white-rgb),var(--bs-text-opacity))!important}.text-body{--bs-text-opacity:1;color:rgba(var(--bs-body-color-rgb),var(--bs-text-opacity))!important}.text-muted{--bs-text-opacity:1;color:var(--bs-secondary-color)!important}.text-black-50{--bs-text-opacity:1;color:rgba(0,0,0,.5)!important}.text-white-50{--bs-text-opacity:1;color:rgba(255,255,255,.5)!important}.text-body-secondary{--bs-text-opacity:1;color:var(--bs-secondary-color)!important}.text-body-tertiary{--bs-text-opacity:1;color:var(--bs-tertiary-color)!important}.text-body-emphasis{--bs-text-opacity:1;color:var(--bs-emphasis-color)!important}.text-reset{--bs-text-opacity:1;color:inherit!important}.text-opacity-25{--bs-text-opacity:0.25}.text-opacity-50{--bs-text-opacity:0.5}.text-opacity-75{--bs-text-opacity:0.75}.text-opacity-100{--bs-text-opacity:1}.text-primary-emphasis{color:var(--bs-primary-text-emphasis)!important}.text-secondary-emphasis{color:var(--bs-secondary-text-emphasis)!important}.text-success-emphasis{color:var(--bs-success-text-emphasis)!important}.text-info-emphasis{color:var(--bs-info-text-emphasis)!important}.text-warning-emphasis{color:var(--bs-warning-text-emphasis)!important}.text-danger-emphasis{color:var(--bs-danger-text-emphasis)!important}.text-light-emphasis{color:var(--bs-light-text-emphasis)!important}.text-dark-emphasis{color:var(--bs-dark-text-emphasis)!important}.link-opacity-10{--bs-link-opacity:0.1}.link-opacity-10-hover:hover{--bs-link-opacity:0.1}.link-opacity-25{--bs-link-opacity:0.25}.link-opacity-25-hover:hover{--bs-link-opacity:0.25}.link-opacity-50{--bs-link-opacity:0.5}.link-opacity-50-hover:hover{--bs-link-opacity:0.5}.link-opacity-75{--bs-link-opacity:0.75}.link-opacity-75-hover:hover{--bs-link-opacity:0.75}.link-opacity-100{--bs-link-opacity:1}.link-opacity-100-hover:hover{--bs-link-opacity:1}.link-offset-1{text-underline-offset:0.125em!important}.link-offset-1-hover:hover{text-underline-offset:0.125em!important}.link-offset-2{text-underline-offset:0.25em!important}.link-offset-2-hover:hover{text-underline-offset:0.25em!important}.link-offset-3{text-underline-offset:0.375em!important}.link-offset-3-hover:hover{text-underline-offset:0.375em!important}.link-underline-primary{--bs-link-underline-opacity:1;-webkit-text-decoration-color:rgba(var(--bs-primary-rgb),var(--bs-link-underline-opacity))!important;text-decoration-color:rgba(var(--bs-primary-rgb),var(--bs-link-underline-opacity))!important}.link-underline-secondary{--bs-link-underline-opacity:1;-webkit-text-decoration-color:rgba(var(--bs-secondary-rgb),var(--bs-link-underline-opacity))!important;text-decoration-color:rgba(var(--bs-secondary-rgb),var(--bs-link-underline-opacity))!important}.link-underline-success{--bs-link-underline-opacity:1;-webkit-text-decoration-color:rgba(var(--bs-success-rgb),var(--bs-link-underline-opacity))!important;text-decoration-color:rgba(var(--bs-success-rgb),var(--bs-link-underline-opacity))!important}.link-underline-info{--bs-link-underline-opacity:1;-webkit-text-decoration-color:rgba(var(--bs-info-rgb),var(--bs-link-underline-opacity))!important;text-decoration-color:rgba(var(--bs-info-rgb),var(--bs-link-underline-opacity))!important}.link-underline-warning{--bs-link-underline-opacity:1;-webkit-text-decoration-color:rgba(var(--bs-warning-rgb),var(--bs-link-underline-opacity))!important;text-decoration-color:rgba(var(--bs-warning-rgb),var(--bs-link-underline-opacity))!important}.link-underline-danger{--bs-link-underline-opacity:1;-webkit-text-decoration-color:rgba(var(--bs-danger-rgb),var(--bs-link-underline-opacity))!important;text-decoration-color:rgba(var(--bs-danger-rgb),var(--bs-link-underline-opacity))!important}.link-underline-light{--bs-link-underline-opacity:1;-webkit-text-decoration-color:rgba(var(--bs-light-rgb),var(--bs-link-underline-opacity))!important;text-decoration-color:rgba(var(--bs-light-rgb),var(--bs-link-underline-opacity))!important}.link-underline-dark{--bs-link-underline-opacity:1;-webkit-text-decoration-color:rgba(var(--bs-dark-rgb),var(--bs-link-underline-opacity))!important;text-decoration-color:rgba(var(--bs-dark-rgb),var(--bs-link-underline-opacity))!important}.link-underline{--bs-link-underline-opacity:1;-webkit-text-decoration-color:rgba(var(--bs-link-color-rgb),var(--bs-link-underline-opacity,1))!important;text-decoration-color:rgba(var(--bs-link-color-rgb),var(--bs-link-underline-opacity,1))!important}.link-underline-opacity-0{--bs-link-underline-opacity:0}.link-underline-opacity-0-hover:hover{--bs-link-underline-opacity:0}.link-underline-opacity-10{--bs-link-underline-opacity:0.1}.link-underline-opacity-10-hover:hover{--bs-link-underline-opacity:0.1}.link-underline-opacity-25{--bs-link-underline-opacity:0.25}.link-underline-opacity-25-hover:hover{--bs-link-underline-opacity:0.25}.link-underline-opacity-50{--bs-link-underline-opacity:0.5}.link-underline-opacity-50-hover:hover{--bs-link-underline-opacity:0.5}.link-underline-opacity-75{--bs-link-underline-opacity:0.75}.link-underline-opacity-75-hover:hover{--bs-link-underline-opacity:0.75}.link-underline-opacity-100{--bs-link-underline-opacity:1}.link-underline-opacity-100-hover:hover{--bs-link-underline-opacity:1}.bg-primary{--bs-bg-opacity:1;background-color:rgba(var(--bs-primary-rgb),var(--bs-bg-opacity))!important}.bg-secondary{--bs-bg-opacity:1;background-color:rgba(var(--bs-secondary-rgb),var(--bs-bg-opacity))!important}.bg-success{--bs-bg-opacity:1;background-color:rgba(var(--bs-success-rgb),var(--bs-bg-opacity))!important}.bg-info{--bs-bg-opacity:1;background-color:rgba(var(--bs-info-rgb),var(--bs-bg-opacity))!important}.bg-warning{--bs-bg-opacity:1;background-color:rgba(var(--bs-warning-rgb),var(--bs-bg-opacity))!important}.bg-danger{--bs-bg-opacity:1;background-color:rgba(var(--bs-danger-rgb),var(--bs-bg-opacity))!important}.bg-light{--bs-bg-opacity:1;background-color:rgba(var(--bs-light-rgb),var(--bs-bg-opacity))!important}.bg-dark{--bs-bg-opacity:1;background-color:rgba(var(--bs-dark-rgb),var(--bs-bg-opacity))!important}.bg-black{--bs-bg-opacity:1;background-color:rgba(var(--bs-black-rgb),var(--bs-bg-opacity))!important}.bg-white{--bs-bg-opacity:1;background-color:rgba(var(--bs-white-rgb),var(--bs-bg-opacity))!important}.bg-body{--bs-bg-opacity:1;background-color:rgba(var(--bs-body-bg-rgb),var(--bs-bg-opacity))!important}.bg-transparent{--bs-bg-opacity:1;background-color:transparent!important}.bg-body-secondary{--bs-bg-opacity:1;background-color:rgba(var(--bs-secondary-bg-rgb),var(--bs-bg-opacity))!important}.bg-body-tertiary{--bs-bg-opacity:1;background-color:rgba(var(--bs-tertiary-bg-rgb),var(--bs-bg-opacity))!important}.bg-opacity-10{--bs-bg-opacity:0.1}.bg-opacity-25{--bs-bg-opacity:0.25}.bg-opacity-50{--bs-bg-opacity:0.5}.bg-opacity-75{--bs-bg-opacity:0.75}.bg-opacity-100{--bs-bg-opacity:1}.bg-primary-subtle{background-color:var(--bs-primary-bg-subtle)!important}.bg-secondary-subtle{background-color:var(--bs-secondary-bg-subtle)!important}.bg-success-subtle{background-color:var(--bs-success-bg-subtle)!important}.bg-info-subtle{background-color:var(--bs-info-bg-subtle)!important}.bg-warning-subtle{background-color:var(--bs-warning-bg-subtle)!important}.bg-danger-subtle{background-color:var(--bs-danger-bg-subtle)!important}.bg-light-subtle{background-color:var(--bs-light-bg-subtle)!important}.bg-dark-subtle{background-color:var(--bs-dark-bg-subtle)!important}.bg-gradient{background-image:var(--bs-gradient)!important}.user-select-all{-webkit-user-select:all!important;-moz-user-select:all!important;user-select:all!important}.user-select-auto{-webkit-user-select:auto!important;-moz-user-select:auto!important;user-select:auto!important}.user-select-none{-webkit-user-select:none!important;-moz-user-select:none!important;user-select:none!important}.pe-none{pointer-events:none!important}.pe-auto{pointer-events:auto!important}.rounded{border-radius:var(--bs-border-radius)!important}.rounded-0{border-radius:0!important}.rounded-1{border-radius:var(--bs-border-radius-sm)!important}.rounded-2{border-radius:var(--bs-border-radius)!important}.rounded-3{border-radius:var(--bs-border-radius-lg)!important}.rounded-4{border-radius:var(--bs-border-radius-xl)!important}.rounded-5{border-radius:var(--bs-border-radius-xxl)!important}.rounded-circle{border-radius:50%!important}.rounded-pill{border-radius:var(--bs-border-radius-pill)!important}.rounded-top{border-top-left-radius:var(--bs-border-radius)!important;border-top-right-radius:var(--bs-border-radius)!important}.rounded-top-0{border-top-left-radius:0!important;border-top-right-radius:0!important}.rounded-top-1{border-top-left-radius:var(--bs-border-radius-sm)!important;border-top-right-radius:var(--bs-border-radius-sm)!important}.rounded-top-2{border-top-left-radius:var(--bs-border-radius)!important;border-top-right-radius:var(--bs-border-radius)!important}.rounded-top-3{border-top-left-radius:var(--bs-border-radius-lg)!important;border-top-right-radius:var(--bs-border-radius-lg)!important}.rounded-top-4{border-top-left-radius:var(--bs-border-radius-xl)!important;border-top-right-radius:var(--bs-border-radius-xl)!important}.rounded-top-5{border-top-left-radius:var(--bs-border-radius-xxl)!important;border-top-right-radius:var(--bs-border-radius-xxl)!important}.rounded-top-circle{border-top-left-radius:50%!important;border-top-right-radius:50%!important}.rounded-top-pill{border-top-left-radius:var(--bs-border-radius-pill)!important;border-top-right-radius:var(--bs-border-radius-pill)!important}.rounded-end{border-top-right-radius:var(--bs-border-radius)!important;border-bottom-right-radius:var(--bs-border-radius)!important}.rounded-end-0{border-top-right-radius:0!important;border-bottom-right-radius:0!important}.rounded-end-1{border-top-right-radius:var(--bs-border-radius-sm)!important;border-bottom-right-radius:var(--bs-border-radius-sm)!important}.rounded-end-2{border-top-right-radius:var(--bs-border-radius)!important;border-bottom-right-radius:var(--bs-border-radius)!important}.rounded-end-3{border-top-right-radius:var(--bs-border-radius-lg)!important;border-bottom-right-radius:var(--bs-border-radius-lg)!important}.rounded-end-4{border-top-right-radius:var(--bs-border-radius-xl)!important;border-bottom-right-radius:var(--bs-border-radius-xl)!important}.rounded-end-5{border-top-right-radius:var(--bs-border-radius-xxl)!important;border-bottom-right-radius:var(--bs-border-radius-xxl)!important}.rounded-end-circle{border-top-right-radius:50%!important;border-bottom-right-radius:50%!important}.rounded-end-pill{border-top-right-radius:var(--bs-border-radius-pill)!important;border-bottom-right-radius:var(--bs-border-radius-pill)!important}.rounded-bottom{border-bottom-right-radius:var(--bs-border-radius)!important;border-bottom-left-radius:var(--bs-border-radius)!important}.rounded-bottom-0{border-bottom-right-radius:0!important;border-bottom-left-radius:0!important}.rounded-bottom-1{border-bottom-right-radius:var(--bs-border-radius-sm)!important;border-bottom-left-radius:var(--bs-border-radius-sm)!important}.rounded-bottom-2{border-bottom-right-radius:var(--bs-border-radius)!important;border-bottom-left-radius:var(--bs-border-radius)!important}.rounded-bottom-3{border-bottom-right-radius:var(--bs-border-radius-lg)!important;border-bottom-left-radius:var(--bs-border-radius-lg)!important}.rounded-bottom-4{border-bottom-right-radius:var(--bs-border-radius-xl)!important;border-bottom-left-radius:var(--bs-border-radius-xl)!important}.rounded-bottom-5{border-bottom-right-radius:var(--bs-border-radius-xxl)!important;border-bottom-left-radius:var(--bs-border-radius-xxl)!important}.rounded-bottom-circle{border-bottom-right-radius:50%!important;border-bottom-left-radius:50%!important}.rounded-bottom-pill{border-bottom-right-radius:var(--bs-border-radius-pill)!important;border-bottom-left-radius:var(--bs-border-radius-pill)!important}.rounded-start{border-bottom-left-radius:var(--bs-border-radius)!important;border-top-left-radius:var(--bs-border-radius)!important}.rounded-start-0{border-bottom-left-radius:0!important;border-top-left-radius:0!important}.rounded-start-1{border-bottom-left-radius:var(--bs-border-radius-sm)!important;border-top-left-radius:var(--bs-border-radius-sm)!important}.rounded-start-2{border-bottom-left-radius:var(--bs-border-radius)!important;border-top-left-radius:var(--bs-border-radius)!important}.rounded-start-3{border-bottom-left-radius:var(--bs-border-radius-lg)!important;border-top-left-radius:var(--bs-border-radius-lg)!important}.rounded-start-4{border-bottom-left-radius:var(--bs-border-radius-xl)!important;border-top-left-radius:var(--bs-border-radius-xl)!important}.rounded-start-5{border-bottom-left-radius:var(--bs-border-radius-xxl)!important;border-top-left-radius:var(--bs-border-radius-xxl)!important}.rounded-start-circle{border-bottom-left-radius:50%!important;border-top-left-radius:50%!important}.rounded-start-pill{border-bottom-left-radius:var(--bs-border-radius-pill)!important;border-top-left-radius:var(--bs-border-radius-pill)!important}.visible{visibility:visible!important}.invisible{visibility:hidden!important}.z-n1{z-index:-1!important}.z-0{z-index:0!important}.z-1{z-index:1!important}.z-2{z-index:2!important}.z-3{z-index:3!important}@media (min-width:576px){.float-sm-start{float:left!important}.float-sm-end{float:right!important}.float-sm-none{float:none!important}.object-fit-sm-contain{-o-object-fit:contain!important;object-fit:contain!important}.object-fit-sm-cover{-o-object-fit:cover!important;object-fit:cover!important}.object-fit-sm-fill{-o-object-fit:fill!important;object-fit:fill!important}.object-fit-sm-scale{-o-object-fit:scale-down!important;object-fit:scale-down!important}.object-fit-sm-none{-o-object-fit:none!important;object-fit:none!important}.d-sm-inline{display:inline!important}.d-sm-inline-block{display:inline-block!important}.d-sm-block{display:block!important}.d-sm-grid{display:grid!important}.d-sm-inline-grid{display:inline-grid!important}.d-sm-table{display:table!important}.d-sm-table-row{display:table-row!important}.d-sm-table-cell{display:table-cell!important}.d-sm-flex{display:flex!important}.d-sm-inline-flex{display:inline-flex!important}.d-sm-none{display:none!important}.flex-sm-fill{flex:1 1 auto!important}.flex-sm-row{flex-direction:row!important}.flex-sm-column{flex-direction:column!important}.flex-sm-row-reverse{flex-direction:row-reverse!important}.flex-sm-column-reverse{flex-direction:column-reverse!important}.flex-sm-grow-0{flex-grow:0!important}.flex-sm-grow-1{flex-grow:1!important}.flex-sm-shrink-0{flex-shrink:0!important}.flex-sm-shrink-1{flex-shrink:1!important}.flex-sm-wrap{flex-wrap:wrap!important}.flex-sm-nowrap{flex-wrap:nowrap!important}.flex-sm-wrap-reverse{flex-wrap:wrap-reverse!important}.justify-content-sm-start{justify-content:flex-start!important}.justify-content-sm-end{justify-content:flex-end!important}.justify-content-sm-center{justify-content:center!important}.justify-content-sm-between{justify-content:space-between!important}.justify-content-sm-around{justify-content:space-around!important}.justify-content-sm-evenly{justify-content:space-evenly!important}.align-items-sm-start{align-items:flex-start!important}.align-items-sm-end{align-items:flex-end!important}.align-items-sm-center{align-items:center!important}.align-items-sm-baseline{align-items:baseline!important}.align-items-sm-stretch{align-items:stretch!important}.align-content-sm-start{align-content:flex-start!important}.align-content-sm-end{align-content:flex-end!important}.align-content-sm-center{align-content:center!important}.align-content-sm-between{align-content:space-between!important}.align-content-sm-around{align-content:space-around!important}.align-content-sm-stretch{align-content:stretch!important}.align-self-sm-auto{align-self:auto!important}.align-self-sm-start{align-self:flex-start!important}.align-self-sm-end{align-self:flex-end!important}.align-self-sm-center{align-self:center!important}.align-self-sm-baseline{align-self:baseline!important}.align-self-sm-stretch{align-self:stretch!important}.order-sm-first{order:-1!important}.order-sm-0{order:0!important}.order-sm-1{order:1!important}.order-sm-2{order:2!important}.order-sm-3{order:3!important}.order-sm-4{order:4!important}.order-sm-5{order:5!important}.order-sm-last{order:6!important}.m-sm-0{margin:0!important}.m-sm-1{margin:.25rem!important}.m-sm-2{margin:.5rem!important}.m-sm-3{margin:1rem!important}.m-sm-4{margin:1.5rem!important}.m-sm-5{margin:3rem!important}.m-sm-auto{margin:auto!important}.mx-sm-0{margin-right:0!important;margin-left:0!important}.mx-sm-1{margin-right:.25rem!important;margin-left:.25rem!important}.mx-sm-2{margin-right:.5rem!important;margin-left:.5rem!important}.mx-sm-3{margin-right:1rem!important;margin-left:1rem!important}.mx-sm-4{margin-right:1.5rem!important;margin-left:1.5rem!important}.mx-sm-5{margin-right:3rem!important;margin-left:3rem!important}.mx-sm-auto{margin-right:auto!important;margin-left:auto!important}.my-sm-0{margin-top:0!important;margin-bottom:0!important}.my-sm-1{margin-top:.25rem!important;margin-bottom:.25rem!important}.my-sm-2{margin-top:.5rem!important;margin-bottom:.5rem!important}.my-sm-3{margin-top:1rem!important;margin-bottom:1rem!important}.my-sm-4{margin-top:1.5rem!important;margin-bottom:1.5rem!important}.my-sm-5{margin-top:3rem!important;margin-bottom:3rem!important}.my-sm-auto{margin-top:auto!important;margin-bottom:auto!important}.mt-sm-0{margin-top:0!important}.mt-sm-1{margin-top:.25rem!important}.mt-sm-2{margin-top:.5rem!important}.mt-sm-3{margin-top:1rem!important}.mt-sm-4{margin-top:1.5rem!important}.mt-sm-5{margin-top:3rem!important}.mt-sm-auto{margin-top:auto!important}.me-sm-0{margin-right:0!important}.me-sm-1{margin-right:.25rem!important}.me-sm-2{margin-right:.5rem!important}.me-sm-3{margin-right:1rem!important}.me-sm-4{margin-right:1.5rem!important}.me-sm-5{margin-right:3rem!important}.me-sm-auto{margin-right:auto!important}.mb-sm-0{margin-bottom:0!important}.mb-sm-1{margin-bottom:.25rem!important}.mb-sm-2{margin-bottom:.5rem!important}.mb-sm-3{margin-bottom:1rem!important}.mb-sm-4{margin-bottom:1.5rem!important}.mb-sm-5{margin-bottom:3rem!important}.mb-sm-auto{margin-bottom:auto!important}.ms-sm-0{margin-left:0!important}.ms-sm-1{margin-left:.25rem!important}.ms-sm-2{margin-left:.5rem!important}.ms-sm-3{margin-left:1rem!important}.ms-sm-4{margin-left:1.5rem!important}.ms-sm-5{margin-left:3rem!important}.ms-sm-auto{margin-left:auto!important}.p-sm-0{padding:0!important}.p-sm-1{padding:.25rem!important}.p-sm-2{padding:.5rem!important}.p-sm-3{padding:1rem!important}.p-sm-4{padding:1.5rem!important}.p-sm-5{padding:3rem!important}.px-sm-0{padding-right:0!important;padding-left:0!important}.px-sm-1{padding-right:.25rem!important;padding-left:.25rem!important}.px-sm-2{padding-right:.5rem!important;padding-left:.5rem!important}.px-sm-3{padding-right:1rem!important;padding-left:1rem!important}.px-sm-4{padding-right:1.5rem!important;padding-left:1.5rem!important}.px-sm-5{padding-right:3rem!important;padding-left:3rem!important}.py-sm-0{padding-top:0!important;padding-bottom:0!important}.py-sm-1{padding-top:.25rem!important;padding-bottom:.25rem!important}.py-sm-2{padding-top:.5rem!important;padding-bottom:.5rem!important}.py-sm-3{padding-top:1rem!important;padding-bottom:1rem!important}.py-sm-4{padding-top:1.5rem!important;padding-bottom:1.5rem!important}.py-sm-5{padding-top:3rem!important;padding-bottom:3rem!important}.pt-sm-0{padding-top:0!important}.pt-sm-1{padding-top:.25rem!important}.pt-sm-2{padding-top:.5rem!important}.pt-sm-3{padding-top:1rem!important}.pt-sm-4{padding-top:1.5rem!important}.pt-sm-5{padding-top:3rem!important}.pe-sm-0{padding-right:0!important}.pe-sm-1{padding-right:.25rem!important}.pe-sm-2{padding-right:.5rem!important}.pe-sm-3{padding-right:1rem!important}.pe-sm-4{padding-right:1.5rem!important}.pe-sm-5{padding-right:3rem!important}.pb-sm-0{padding-bottom:0!important}.pb-sm-1{padding-bottom:.25rem!important}.pb-sm-2{padding-bottom:.5rem!important}.pb-sm-3{padding-bottom:1rem!important}.pb-sm-4{padding-bottom:1.5rem!important}.pb-sm-5{padding-bottom:3rem!important}.ps-sm-0{padding-left:0!important}.ps-sm-1{padding-left:.25rem!important}.ps-sm-2{padding-left:.5rem!important}.ps-sm-3{padding-left:1rem!important}.ps-sm-4{padding-left:1.5rem!important}.ps-sm-5{padding-left:3rem!important}.gap-sm-0{gap:0!important}.gap-sm-1{gap:.25rem!important}.gap-sm-2{gap:.5rem!important}.gap-sm-3{gap:1rem!important}.gap-sm-4{gap:1.5rem!important}.gap-sm-5{gap:3rem!important}.row-gap-sm-0{row-gap:0!important}.row-gap-sm-1{row-gap:.25rem!important}.row-gap-sm-2{row-gap:.5rem!important}.row-gap-sm-3{row-gap:1rem!important}.row-gap-sm-4{row-gap:1.5rem!important}.row-gap-sm-5{row-gap:3rem!important}.column-gap-sm-0{-moz-column-gap:0!important;column-gap:0!important}.column-gap-sm-1{-moz-column-gap:0.25rem!important;column-gap:.25rem!important}.column-gap-sm-2{-moz-column-gap:0.5rem!important;column-gap:.5rem!important}.column-gap-sm-3{-moz-column-gap:1rem!important;column-gap:1rem!important}.column-gap-sm-4{-moz-column-gap:1.5rem!important;column-gap:1.5rem!important}.column-gap-sm-5{-moz-column-gap:3rem!important;column-gap:3rem!important}.text-sm-start{text-align:left!important}.text-sm-end{text-align:right!important}.text-sm-center{text-align:center!important}}@media (min-width:768px){.float-md-start{float:left!important}.float-md-end{float:right!important}.float-md-none{float:none!important}.object-fit-md-contain{-o-object-fit:contain!important;object-fit:contain!important}.object-fit-md-cover{-o-object-fit:cover!important;object-fit:cover!important}.object-fit-md-fill{-o-object-fit:fill!important;object-fit:fill!important}.object-fit-md-scale{-o-object-fit:scale-down!important;object-fit:scale-down!important}.object-fit-md-none{-o-object-fit:none!important;object-fit:none!important}.d-md-inline{display:inline!important}.d-md-inline-block{display:inline-block!important}.d-md-block{display:block!important}.d-md-grid{display:grid!important}.d-md-inline-grid{display:inline-grid!important}.d-md-table{display:table!important}.d-md-table-row{display:table-row!important}.d-md-table-cell{display:table-cell!important}.d-md-flex{display:flex!important}.d-md-inline-flex{display:inline-flex!important}.d-md-none{display:none!important}.flex-md-fill{flex:1 1 auto!important}.flex-md-row{flex-direction:row!important}.flex-md-column{flex-direction:column!important}.flex-md-row-reverse{flex-direction:row-reverse!important}.flex-md-column-reverse{flex-direction:column-reverse!important}.flex-md-grow-0{flex-grow:0!important}.flex-md-grow-1{flex-grow:1!important}.flex-md-shrink-0{flex-shrink:0!important}.flex-md-shrink-1{flex-shrink:1!important}.flex-md-wrap{flex-wrap:wrap!important}.flex-md-nowrap{flex-wrap:nowrap!important}.flex-md-wrap-reverse{flex-wrap:wrap-reverse!important}.justify-content-md-start{justify-content:flex-start!important}.justify-content-md-end{justify-content:flex-end!important}.justify-content-md-center{justify-content:center!important}.justify-content-md-between{justify-content:space-between!important}.justify-content-md-around{justify-content:space-around!important}.justify-content-md-evenly{justify-content:space-evenly!important}.align-items-md-start{align-items:flex-start!important}.align-items-md-end{align-items:flex-end!important}.align-items-md-center{align-items:center!important}.align-items-md-baseline{align-items:baseline!important}.align-items-md-stretch{align-items:stretch!important}.align-content-md-start{align-content:flex-start!important}.align-content-md-end{align-content:flex-end!important}.align-content-md-center{align-content:center!important}.align-content-md-between{align-content:space-between!important}.align-content-md-around{align-content:space-around!important}.align-content-md-stretch{align-content:stretch!important}.align-self-md-auto{align-self:auto!important}.align-self-md-start{align-self:flex-start!important}.align-self-md-end{align-self:flex-end!important}.align-self-md-center{align-self:center!important}.align-self-md-baseline{align-self:baseline!important}.align-self-md-stretch{align-self:stretch!important}.order-md-first{order:-1!important}.order-md-0{order:0!important}.order-md-1{order:1!important}.order-md-2{order:2!important}.order-md-3{order:3!important}.order-md-4{order:4!important}.order-md-5{order:5!important}.order-md-last{order:6!important}.m-md-0{margin:0!important}.m-md-1{margin:.25rem!important}.m-md-2{margin:.5rem!important}.m-md-3{margin:1rem!important}.m-md-4{margin:1.5rem!important}.m-md-5{margin:3rem!important}.m-md-auto{margin:auto!important}.mx-md-0{margin-right:0!important;margin-left:0!important}.mx-md-1{margin-right:.25rem!important;margin-left:.25rem!important}.mx-md-2{margin-right:.5rem!important;margin-left:.5rem!important}.mx-md-3{margin-right:1rem!important;margin-left:1rem!important}.mx-md-4{margin-right:1.5rem!important;margin-left:1.5rem!important}.mx-md-5{margin-right:3rem!important;margin-left:3rem!important}.mx-md-auto{margin-right:auto!important;margin-left:auto!important}.my-md-0{margin-top:0!important;margin-bottom:0!important}.my-md-1{margin-top:.25rem!important;margin-bottom:.25rem!important}.my-md-2{margin-top:.5rem!important;margin-bottom:.5rem!important}.my-md-3{margin-top:1rem!important;margin-bottom:1rem!important}.my-md-4{margin-top:1.5rem!important;margin-bottom:1.5rem!important}.my-md-5{margin-top:3rem!important;margin-bottom:3rem!important}.my-md-auto{margin-top:auto!important;margin-bottom:auto!important}.mt-md-0{margin-top:0!important}.mt-md-1{margin-top:.25rem!important}.mt-md-2{margin-top:.5rem!important}.mt-md-3{margin-top:1rem!important}.mt-md-4{margin-top:1.5rem!important}.mt-md-5{margin-top:3rem!important}.mt-md-auto{margin-top:auto!important}.me-md-0{margin-right:0!important}.me-md-1{margin-right:.25rem!important}.me-md-2{margin-right:.5rem!important}.me-md-3{margin-right:1rem!important}.me-md-4{margin-right:1.5rem!important}.me-md-5{margin-right:3rem!important}.me-md-auto{margin-right:auto!important}.mb-md-0{margin-bottom:0!important}.mb-md-1{margin-bottom:.25rem!important}.mb-md-2{margin-bottom:.5rem!important}.mb-md-3{margin-bottom:1rem!important}.mb-md-4{margin-bottom:1.5rem!important}.mb-md-5{margin-bottom:3rem!important}.mb-md-auto{margin-bottom:auto!important}.ms-md-0{margin-left:0!important}.ms-md-1{margin-left:.25rem!important}.ms-md-2{margin-left:.5rem!important}.ms-md-3{margin-left:1rem!important}.ms-md-4{margin-left:1.5rem!important}.ms-md-5{margin-left:3rem!important}.ms-md-auto{margin-left:auto!important}.p-md-0{padding:0!important}.p-md-1{padding:.25rem!important}.p-md-2{padding:.5rem!important}.p-md-3{padding:1rem!important}.p-md-4{padding:1.5rem!important}.p-md-5{padding:3rem!important}.px-md-0{padding-right:0!important;padding-left:0!important}.px-md-1{padding-right:.25rem!important;padding-left:.25rem!important}.px-md-2{padding-right:.5rem!important;padding-left:.5rem!important}.px-md-3{padding-right:1rem!important;padding-left:1rem!important}.px-md-4{padding-right:1.5rem!important;padding-left:1.5rem!important}.px-md-5{padding-right:3rem!important;padding-left:3rem!important}.py-md-0{padding-top:0!important;padding-bottom:0!important}.py-md-1{padding-top:.25rem!important;padding-bottom:.25rem!important}.py-md-2{padding-top:.5rem!important;padding-bottom:.5rem!important}.py-md-3{padding-top:1rem!important;padding-bottom:1rem!important}.py-md-4{padding-top:1.5rem!important;padding-bottom:1.5rem!important}.py-md-5{padding-top:3rem!important;padding-bottom:3rem!important}.pt-md-0{padding-top:0!important}.pt-md-1{padding-top:.25rem!important}.pt-md-2{padding-top:.5rem!important}.pt-md-3{padding-top:1rem!important}.pt-md-4{padding-top:1.5rem!important}.pt-md-5{padding-top:3rem!important}.pe-md-0{padding-right:0!important}.pe-md-1{padding-right:.25rem!important}.pe-md-2{padding-right:.5rem!important}.pe-md-3{padding-right:1rem!important}.pe-md-4{padding-right:1.5rem!important}.pe-md-5{padding-right:3rem!important}.pb-md-0{padding-bottom:0!important}.pb-md-1{padding-bottom:.25rem!important}.pb-md-2{padding-bottom:.5rem!important}.pb-md-3{padding-bottom:1rem!important}.pb-md-4{padding-bottom:1.5rem!important}.pb-md-5{padding-bottom:3rem!important}.ps-md-0{padding-left:0!important}.ps-md-1{padding-left:.25rem!important}.ps-md-2{padding-left:.5rem!important}.ps-md-3{padding-left:1rem!important}.ps-md-4{padding-left:1.5rem!important}.ps-md-5{padding-left:3rem!important}.gap-md-0{gap:0!important}.gap-md-1{gap:.25rem!important}.gap-md-2{gap:.5rem!important}.gap-md-3{gap:1rem!important}.gap-md-4{gap:1.5rem!important}.gap-md-5{gap:3rem!important}.row-gap-md-0{row-gap:0!important}.row-gap-md-1{row-gap:.25rem!important}.row-gap-md-2{row-gap:.5rem!important}.row-gap-md-3{row-gap:1rem!important}.row-gap-md-4{row-gap:1.5rem!important}.row-gap-md-5{row-gap:3rem!important}.column-gap-md-0{-moz-column-gap:0!important;column-gap:0!important}.column-gap-md-1{-moz-column-gap:0.25rem!important;column-gap:.25rem!important}.column-gap-md-2{-moz-column-gap:0.5rem!important;column-gap:.5rem!important}.column-gap-md-3{-moz-column-gap:1rem!important;column-gap:1rem!important}.column-gap-md-4{-moz-column-gap:1.5rem!important;column-gap:1.5rem!important}.column-gap-md-5{-moz-column-gap:3rem!important;column-gap:3rem!important}.text-md-start{text-align:left!important}.text-md-end{text-align:right!important}.text-md-center{text-align:center!important}}@media (min-width:992px){.float-lg-start{float:left!important}.float-lg-end{float:right!important}.float-lg-none{float:none!important}.object-fit-lg-contain{-o-object-fit:contain!important;object-fit:contain!important}.object-fit-lg-cover{-o-object-fit:cover!important;object-fit:cover!important}.object-fit-lg-fill{-o-object-fit:fill!important;object-fit:fill!important}.object-fit-lg-scale{-o-object-fit:scale-down!important;object-fit:scale-down!important}.object-fit-lg-none{-o-object-fit:none!important;object-fit:none!important}.d-lg-inline{display:inline!important}.d-lg-inline-block{display:inline-block!important}.d-lg-block{display:block!important}.d-lg-grid{display:grid!important}.d-lg-inline-grid{display:inline-grid!important}.d-lg-table{display:table!important}.d-lg-table-row{display:table-row!important}.d-lg-table-cell{display:table-cell!important}.d-lg-flex{display:flex!important}.d-lg-inline-flex{display:inline-flex!important}.d-lg-none{display:none!important}.flex-lg-fill{flex:1 1 auto!important}.flex-lg-row{flex-direction:row!important}.flex-lg-column{flex-direction:column!important}.flex-lg-row-reverse{flex-direction:row-reverse!important}.flex-lg-column-reverse{flex-direction:column-reverse!important}.flex-lg-grow-0{flex-grow:0!important}.flex-lg-grow-1{flex-grow:1!important}.flex-lg-shrink-0{flex-shrink:0!important}.flex-lg-shrink-1{flex-shrink:1!important}.flex-lg-wrap{flex-wrap:wrap!important}.flex-lg-nowrap{flex-wrap:nowrap!important}.flex-lg-wrap-reverse{flex-wrap:wrap-reverse!important}.justify-content-lg-start{justify-content:flex-start!important}.justify-content-lg-end{justify-content:flex-end!important}.justify-content-lg-center{justify-content:center!important}.justify-content-lg-between{justify-content:space-between!important}.justify-content-lg-around{justify-content:space-around!important}.justify-content-lg-evenly{justify-content:space-evenly!important}.align-items-lg-start{align-items:flex-start!important}.align-items-lg-end{align-items:flex-end!important}.align-items-lg-center{align-items:center!important}.align-items-lg-baseline{align-items:baseline!important}.align-items-lg-stretch{align-items:stretch!important}.align-content-lg-start{align-content:flex-start!important}.align-content-lg-end{align-content:flex-end!important}.align-content-lg-center{align-content:center!important}.align-content-lg-between{align-content:space-between!important}.align-content-lg-around{align-content:space-around!important}.align-content-lg-stretch{align-content:stretch!important}.align-self-lg-auto{align-self:auto!important}.align-self-lg-start{align-self:flex-start!important}.align-self-lg-end{align-self:flex-end!important}.align-self-lg-center{align-self:center!important}.align-self-lg-baseline{align-self:baseline!important}.align-self-lg-stretch{align-self:stretch!important}.order-lg-first{order:-1!important}.order-lg-0{order:0!important}.order-lg-1{order:1!important}.order-lg-2{order:2!important}.order-lg-3{order:3!important}.order-lg-4{order:4!important}.order-lg-5{order:5!important}.order-lg-last{order:6!important}.m-lg-0{margin:0!important}.m-lg-1{margin:.25rem!important}.m-lg-2{margin:.5rem!important}.m-lg-3{margin:1rem!important}.m-lg-4{margin:1.5rem!important}.m-lg-5{margin:3rem!important}.m-lg-auto{margin:auto!important}.mx-lg-0{margin-right:0!important;margin-left:0!important}.mx-lg-1{margin-right:.25rem!important;margin-left:.25rem!important}.mx-lg-2{margin-right:.5rem!important;margin-left:.5rem!important}.mx-lg-3{margin-right:1rem!important;margin-left:1rem!important}.mx-lg-4{margin-right:1.5rem!important;margin-left:1.5rem!important}.mx-lg-5{margin-right:3rem!important;margin-left:3rem!important}.mx-lg-auto{margin-right:auto!important;margin-left:auto!important}.my-lg-0{margin-top:0!important;margin-bottom:0!important}.my-lg-1{margin-top:.25rem!important;margin-bottom:.25rem!important}.my-lg-2{margin-top:.5rem!important;margin-bottom:.5rem!important}.my-lg-3{margin-top:1rem!important;margin-bottom:1rem!important}.my-lg-4{margin-top:1.5rem!important;margin-bottom:1.5rem!important}.my-lg-5{margin-top:3rem!important;margin-bottom:3rem!important}.my-lg-auto{margin-top:auto!important;margin-bottom:auto!important}.mt-lg-0{margin-top:0!important}.mt-lg-1{margin-top:.25rem!important}.mt-lg-2{margin-top:.5rem!important}.mt-lg-3{margin-top:1rem!important}.mt-lg-4{margin-top:1.5rem!important}.mt-lg-5{margin-top:3rem!important}.mt-lg-auto{margin-top:auto!important}.me-lg-0{margin-right:0!important}.me-lg-1{margin-right:.25rem!important}.me-lg-2{margin-right:.5rem!important}.me-lg-3{margin-right:1rem!important}.me-lg-4{margin-right:1.5rem!important}.me-lg-5{margin-right:3rem!important}.me-lg-auto{margin-right:auto!important}.mb-lg-0{margin-bottom:0!important}.mb-lg-1{margin-bottom:.25rem!important}.mb-lg-2{margin-bottom:.5rem!important}.mb-lg-3{margin-bottom:1rem!important}.mb-lg-4{margin-bottom:1.5rem!important}.mb-lg-5{margin-bottom:3rem!important}.mb-lg-auto{margin-bottom:auto!important}.ms-lg-0{margin-left:0!important}.ms-lg-1{margin-left:.25rem!important}.ms-lg-2{margin-left:.5rem!important}.ms-lg-3{margin-left:1rem!important}.ms-lg-4{margin-left:1.5rem!important}.ms-lg-5{margin-left:3rem!important}.ms-lg-auto{margin-left:auto!important}.p-lg-0{padding:0!important}.p-lg-1{padding:.25rem!important}.p-lg-2{padding:.5rem!important}.p-lg-3{padding:1rem!important}.p-lg-4{padding:1.5rem!important}.p-lg-5{padding:3rem!important}.px-lg-0{padding-right:0!important;padding-left:0!important}.px-lg-1{padding-right:.25rem!important;padding-left:.25rem!important}.px-lg-2{padding-right:.5rem!important;padding-left:.5rem!important}.px-lg-3{padding-right:1rem!important;padding-left:1rem!important}.px-lg-4{padding-right:1.5rem!important;padding-left:1.5rem!important}.px-lg-5{padding-right:3rem!important;padding-left:3rem!important}.py-lg-0{padding-top:0!important;padding-bottom:0!important}.py-lg-1{padding-top:.25rem!important;padding-bottom:.25rem!important}.py-lg-2{padding-top:.5rem!important;padding-bottom:.5rem!important}.py-lg-3{padding-top:1rem!important;padding-bottom:1rem!important}.py-lg-4{padding-top:1.5rem!important;padding-bottom:1.5rem!important}.py-lg-5{padding-top:3rem!important;padding-bottom:3rem!important}.pt-lg-0{padding-top:0!important}.pt-lg-1{padding-top:.25rem!important}.pt-lg-2{padding-top:.5rem!important}.pt-lg-3{padding-top:1rem!important}.pt-lg-4{padding-top:1.5rem!important}.pt-lg-5{padding-top:3rem!important}.pe-lg-0{padding-right:0!important}.pe-lg-1{padding-right:.25rem!important}.pe-lg-2{padding-right:.5rem!important}.pe-lg-3{padding-right:1rem!important}.pe-lg-4{padding-right:1.5rem!important}.pe-lg-5{padding-right:3rem!important}.pb-lg-0{padding-bottom:0!important}.pb-lg-1{padding-bottom:.25rem!important}.pb-lg-2{padding-bottom:.5rem!important}.pb-lg-3{padding-bottom:1rem!important}.pb-lg-4{padding-bottom:1.5rem!important}.pb-lg-5{padding-bottom:3rem!important}.ps-lg-0{padding-left:0!important}.ps-lg-1{padding-left:.25rem!important}.ps-lg-2{padding-left:.5rem!important}.ps-lg-3{padding-left:1rem!important}.ps-lg-4{padding-left:1.5rem!important}.ps-lg-5{padding-left:3rem!important}.gap-lg-0{gap:0!important}.gap-lg-1{gap:.25rem!important}.gap-lg-2{gap:.5rem!important}.gap-lg-3{gap:1rem!important}.gap-lg-4{gap:1.5rem!important}.gap-lg-5{gap:3rem!important}.row-gap-lg-0{row-gap:0!important}.row-gap-lg-1{row-gap:.25rem!important}.row-gap-lg-2{row-gap:.5rem!important}.row-gap-lg-3{row-gap:1rem!important}.row-gap-lg-4{row-gap:1.5rem!important}.row-gap-lg-5{row-gap:3rem!important}.column-gap-lg-0{-moz-column-gap:0!important;column-gap:0!important}.column-gap-lg-1{-moz-column-gap:0.25rem!important;column-gap:.25rem!important}.column-gap-lg-2{-moz-column-gap:0.5rem!important;column-gap:.5rem!important}.column-gap-lg-3{-moz-column-gap:1rem!important;column-gap:1rem!important}.column-gap-lg-4{-moz-column-gap:1.5rem!important;column-gap:1.5rem!important}.column-gap-lg-5{-moz-column-gap:3rem!important;column-gap:3rem!important}.text-lg-start{text-align:left!important}.text-lg-end{text-align:right!important}.text-lg-center{text-align:center!important}}@media (min-width:1200px){.float-xl-start{float:left!important}.float-xl-end{float:right!important}.float-xl-none{float:none!important}.object-fit-xl-contain{-o-object-fit:contain!important;object-fit:contain!important}.object-fit-xl-cover{-o-object-fit:cover!important;object-fit:cover!important}.object-fit-xl-fill{-o-object-fit:fill!important;object-fit:fill!important}.object-fit-xl-scale{-o-object-fit:scale-down!important;object-fit:scale-down!important}.object-fit-xl-none{-o-object-fit:none!important;object-fit:none!important}.d-xl-inline{display:inline!important}.d-xl-inline-block{display:inline-block!important}.d-xl-block{display:block!important}.d-xl-grid{display:grid!important}.d-xl-inline-grid{display:inline-grid!important}.d-xl-table{display:table!important}.d-xl-table-row{display:table-row!important}.d-xl-table-cell{display:table-cell!important}.d-xl-flex{display:flex!important}.d-xl-inline-flex{display:inline-flex!important}.d-xl-none{display:none!important}.flex-xl-fill{flex:1 1 auto!important}.flex-xl-row{flex-direction:row!important}.flex-xl-column{flex-direction:column!important}.flex-xl-row-reverse{flex-direction:row-reverse!important}.flex-xl-column-reverse{flex-direction:column-reverse!important}.flex-xl-grow-0{flex-grow:0!important}.flex-xl-grow-1{flex-grow:1!important}.flex-xl-shrink-0{flex-shrink:0!important}.flex-xl-shrink-1{flex-shrink:1!important}.flex-xl-wrap{flex-wrap:wrap!important}.flex-xl-nowrap{flex-wrap:nowrap!important}.flex-xl-wrap-reverse{flex-wrap:wrap-reverse!important}.justify-content-xl-start{justify-content:flex-start!important}.justify-content-xl-end{justify-content:flex-end!important}.justify-content-xl-center{justify-content:center!important}.justify-content-xl-between{justify-content:space-between!important}.justify-content-xl-around{justify-content:space-around!important}.justify-content-xl-evenly{justify-content:space-evenly!important}.align-items-xl-start{align-items:flex-start!important}.align-items-xl-end{align-items:flex-end!important}.align-items-xl-center{align-items:center!important}.align-items-xl-baseline{align-items:baseline!important}.align-items-xl-stretch{align-items:stretch!important}.align-content-xl-start{align-content:flex-start!important}.align-content-xl-end{align-content:flex-end!important}.align-content-xl-center{align-content:center!important}.align-content-xl-between{align-content:space-between!important}.align-content-xl-around{align-content:space-around!important}.align-content-xl-stretch{align-content:stretch!important}.align-self-xl-auto{align-self:auto!important}.align-self-xl-start{align-self:flex-start!important}.align-self-xl-end{align-self:flex-end!important}.align-self-xl-center{align-self:center!important}.align-self-xl-baseline{align-self:baseline!important}.align-self-xl-stretch{align-self:stretch!important}.order-xl-first{order:-1!important}.order-xl-0{order:0!important}.order-xl-1{order:1!important}.order-xl-2{order:2!important}.order-xl-3{order:3!important}.order-xl-4{order:4!important}.order-xl-5{order:5!important}.order-xl-last{order:6!important}.m-xl-0{margin:0!important}.m-xl-1{margin:.25rem!important}.m-xl-2{margin:.5rem!important}.m-xl-3{margin:1rem!important}.m-xl-4{margin:1.5rem!important}.m-xl-5{margin:3rem!important}.m-xl-auto{margin:auto!important}.mx-xl-0{margin-right:0!important;margin-left:0!important}.mx-xl-1{margin-right:.25rem!important;margin-left:.25rem!important}.mx-xl-2{margin-right:.5rem!important;margin-left:.5rem!important}.mx-xl-3{margin-right:1rem!important;margin-left:1rem!important}.mx-xl-4{margin-right:1.5rem!important;margin-left:1.5rem!important}.mx-xl-5{margin-right:3rem!important;margin-left:3rem!important}.mx-xl-auto{margin-right:auto!important;margin-left:auto!important}.my-xl-0{margin-top:0!important;margin-bottom:0!important}.my-xl-1{margin-top:.25rem!important;margin-bottom:.25rem!important}.my-xl-2{margin-top:.5rem!important;margin-bottom:.5rem!important}.my-xl-3{margin-top:1rem!important;margin-bottom:1rem!important}.my-xl-4{margin-top:1.5rem!important;margin-bottom:1.5rem!important}.my-xl-5{margin-top:3rem!important;margin-bottom:3rem!important}.my-xl-auto{margin-top:auto!important;margin-bottom:auto!important}.mt-xl-0{margin-top:0!important}.mt-xl-1{margin-top:.25rem!important}.mt-xl-2{margin-top:.5rem!important}.mt-xl-3{margin-top:1rem!important}.mt-xl-4{margin-top:1.5rem!important}.mt-xl-5{margin-top:3rem!important}.mt-xl-auto{margin-top:auto!important}.me-xl-0{margin-right:0!important}.me-xl-1{margin-right:.25rem!important}.me-xl-2{margin-right:.5rem!important}.me-xl-3{margin-right:1rem!important}.me-xl-4{margin-right:1.5rem!important}.me-xl-5{margin-right:3rem!important}.me-xl-auto{margin-right:auto!important}.mb-xl-0{margin-bottom:0!important}.mb-xl-1{margin-bottom:.25rem!important}.mb-xl-2{margin-bottom:.5rem!important}.mb-xl-3{margin-bottom:1rem!important}.mb-xl-4{margin-bottom:1.5rem!important}.mb-xl-5{margin-bottom:3rem!important}.mb-xl-auto{margin-bottom:auto!important}.ms-xl-0{margin-left:0!important}.ms-xl-1{margin-left:.25rem!important}.ms-xl-2{margin-left:.5rem!important}.ms-xl-3{margin-left:1rem!important}.ms-xl-4{margin-left:1.5rem!important}.ms-xl-5{margin-left:3rem!important}.ms-xl-auto{margin-left:auto!important}.p-xl-0{padding:0!important}.p-xl-1{padding:.25rem!important}.p-xl-2{padding:.5rem!important}.p-xl-3{padding:1rem!important}.p-xl-4{padding:1.5rem!important}.p-xl-5{padding:3rem!important}.px-xl-0{padding-right:0!important;padding-left:0!important}.px-xl-1{padding-right:.25rem!important;padding-left:.25rem!important}.px-xl-2{padding-right:.5rem!important;padding-left:.5rem!important}.px-xl-3{padding-right:1rem!important;padding-left:1rem!important}.px-xl-4{padding-right:1.5rem!important;padding-left:1.5rem!important}.px-xl-5{padding-right:3rem!important;padding-left:3rem!important}.py-xl-0{padding-top:0!important;padding-bottom:0!important}.py-xl-1{padding-top:.25rem!important;padding-bottom:.25rem!important}.py-xl-2{padding-top:.5rem!important;padding-bottom:.5rem!important}.py-xl-3{padding-top:1rem!important;padding-bottom:1rem!important}.py-xl-4{padding-top:1.5rem!important;padding-bottom:1.5rem!important}.py-xl-5{padding-top:3rem!important;padding-bottom:3rem!important}.pt-xl-0{padding-top:0!important}.pt-xl-1{padding-top:.25rem!important}.pt-xl-2{padding-top:.5rem!important}.pt-xl-3{padding-top:1rem!important}.pt-xl-4{padding-top:1.5rem!important}.pt-xl-5{padding-top:3rem!important}.pe-xl-0{padding-right:0!important}.pe-xl-1{padding-right:.25rem!important}.pe-xl-2{padding-right:.5rem!important}.pe-xl-3{padding-right:1rem!important}.pe-xl-4{padding-right:1.5rem!important}.pe-xl-5{padding-right:3rem!important}.pb-xl-0{padding-bottom:0!important}.pb-xl-1{padding-bottom:.25rem!important}.pb-xl-2{padding-bottom:.5rem!important}.pb-xl-3{padding-bottom:1rem!important}.pb-xl-4{padding-bottom:1.5rem!important}.pb-xl-5{padding-bottom:3rem!important}.ps-xl-0{padding-left:0!important}.ps-xl-1{padding-left:.25rem!important}.ps-xl-2{padding-left:.5rem!important}.ps-xl-3{padding-left:1rem!important}.ps-xl-4{padding-left:1.5rem!important}.ps-xl-5{padding-left:3rem!important}.gap-xl-0{gap:0!important}.gap-xl-1{gap:.25rem!important}.gap-xl-2{gap:.5rem!important}.gap-xl-3{gap:1rem!important}.gap-xl-4{gap:1.5rem!important}.gap-xl-5{gap:3rem!important}.row-gap-xl-0{row-gap:0!important}.row-gap-xl-1{row-gap:.25rem!important}.row-gap-xl-2{row-gap:.5rem!important}.row-gap-xl-3{row-gap:1rem!important}.row-gap-xl-4{row-gap:1.5rem!important}.row-gap-xl-5{row-gap:3rem!important}.column-gap-xl-0{-moz-column-gap:0!important;column-gap:0!important}.column-gap-xl-1{-moz-column-gap:0.25rem!important;column-gap:.25rem!important}.column-gap-xl-2{-moz-column-gap:0.5rem!important;column-gap:.5rem!important}.column-gap-xl-3{-moz-column-gap:1rem!important;column-gap:1rem!important}.column-gap-xl-4{-moz-column-gap:1.5rem!important;column-gap:1.5rem!important}.column-gap-xl-5{-moz-column-gap:3rem!important;column-gap:3rem!important}.text-xl-start{text-align:left!important}.text-xl-end{text-align:right!important}.text-xl-center{text-align:center!important}}@media (min-width:1400px){.float-xxl-start{float:left!important}.float-xxl-end{float:right!important}.float-xxl-none{float:none!important}.object-fit-xxl-contain{-o-object-fit:contain!important;object-fit:contain!important}.object-fit-xxl-cover{-o-object-fit:cover!important;object-fit:cover!important}.object-fit-xxl-fill{-o-object-fit:fill!important;object-fit:fill!important}.object-fit-xxl-scale{-o-object-fit:scale-down!important;object-fit:scale-down!important}.object-fit-xxl-none{-o-object-fit:none!important;object-fit:none!important}.d-xxl-inline{display:inline!important}.d-xxl-inline-block{display:inline-block!important}.d-xxl-block{display:block!important}.d-xxl-grid{display:grid!important}.d-xxl-inline-grid{display:inline-grid!important}.d-xxl-table{display:table!important}.d-xxl-table-row{display:table-row!important}.d-xxl-table-cell{display:table-cell!important}.d-xxl-flex{display:flex!important}.d-xxl-inline-flex{display:inline-flex!important}.d-xxl-none{display:none!important}.flex-xxl-fill{flex:1 1 auto!important}.flex-xxl-row{flex-direction:row!important}.flex-xxl-column{flex-direction:column!important}.flex-xxl-row-reverse{flex-direction:row-reverse!important}.flex-xxl-column-reverse{flex-direction:column-reverse!important}.flex-xxl-grow-0{flex-grow:0!important}.flex-xxl-grow-1{flex-grow:1!important}.flex-xxl-shrink-0{flex-shrink:0!important}.flex-xxl-shrink-1{flex-shrink:1!important}.flex-xxl-wrap{flex-wrap:wrap!important}.flex-xxl-nowrap{flex-wrap:nowrap!important}.flex-xxl-wrap-reverse{flex-wrap:wrap-reverse!important}.justify-content-xxl-start{justify-content:flex-start!important}.justify-content-xxl-end{justify-content:flex-end!important}.justify-content-xxl-center{justify-content:center!important}.justify-content-xxl-between{justify-content:space-between!important}.justify-content-xxl-around{justify-content:space-around!important}.justify-content-xxl-evenly{justify-content:space-evenly!important}.align-items-xxl-start{align-items:flex-start!important}.align-items-xxl-end{align-items:flex-end!important}.align-items-xxl-center{align-items:center!important}.align-items-xxl-baseline{align-items:baseline!important}.align-items-xxl-stretch{align-items:stretch!important}.align-content-xxl-start{align-content:flex-start!important}.align-content-xxl-end{align-content:flex-end!important}.align-content-xxl-center{align-content:center!important}.align-content-xxl-between{align-content:space-between!important}.align-content-xxl-around{align-content:space-around!important}.align-content-xxl-stretch{align-content:stretch!important}.align-self-xxl-auto{align-self:auto!important}.align-self-xxl-start{align-self:flex-start!important}.align-self-xxl-end{align-self:flex-end!important}.align-self-xxl-center{align-self:center!important}.align-self-xxl-baseline{align-self:baseline!important}.align-self-xxl-stretch{align-self:stretch!important}.order-xxl-first{order:-1!important}.order-xxl-0{order:0!important}.order-xxl-1{order:1!important}.order-xxl-2{order:2!important}.order-xxl-3{order:3!important}.order-xxl-4{order:4!important}.order-xxl-5{order:5!important}.order-xxl-last{order:6!important}.m-xxl-0{margin:0!important}.m-xxl-1{margin:.25rem!important}.m-xxl-2{margin:.5rem!important}.m-xxl-3{margin:1rem!important}.m-xxl-4{margin:1.5rem!important}.m-xxl-5{margin:3rem!important}.m-xxl-auto{margin:auto!important}.mx-xxl-0{margin-right:0!important;margin-left:0!important}.mx-xxl-1{margin-right:.25rem!important;margin-left:.25rem!important}.mx-xxl-2{margin-right:.5rem!important;margin-left:.5rem!important}.mx-xxl-3{margin-right:1rem!important;margin-left:1rem!important}.mx-xxl-4{margin-right:1.5rem!important;margin-left:1.5rem!important}.mx-xxl-5{margin-right:3rem!important;margin-left:3rem!important}.mx-xxl-auto{margin-right:auto!important;margin-left:auto!important}.my-xxl-0{margin-top:0!important;margin-bottom:0!important}.my-xxl-1{margin-top:.25rem!important;margin-bottom:.25rem!important}.my-xxl-2{margin-top:.5rem!important;margin-bottom:.5rem!important}.my-xxl-3{margin-top:1rem!important;margin-bottom:1rem!important}.my-xxl-4{margin-top:1.5rem!important;margin-bottom:1.5rem!important}.my-xxl-5{margin-top:3rem!important;margin-bottom:3rem!important}.my-xxl-auto{margin-top:auto!important;margin-bottom:auto!important}.mt-xxl-0{margin-top:0!important}.mt-xxl-1{margin-top:.25rem!important}.mt-xxl-2{margin-top:.5rem!important}.mt-xxl-3{margin-top:1rem!important}.mt-xxl-4{margin-top:1.5rem!important}.mt-xxl-5{margin-top:3rem!important}.mt-xxl-auto{margin-top:auto!important}.me-xxl-0{margin-right:0!important}.me-xxl-1{margin-right:.25rem!important}.me-xxl-2{margin-right:.5rem!important}.me-xxl-3{margin-right:1rem!important}.me-xxl-4{margin-right:1.5rem!important}.me-xxl-5{margin-right:3rem!important}.me-xxl-auto{margin-right:auto!important}.mb-xxl-0{margin-bottom:0!important}.mb-xxl-1{margin-bottom:.25rem!important}.mb-xxl-2{margin-bottom:.5rem!important}.mb-xxl-3{margin-bottom:1rem!important}.mb-xxl-4{margin-bottom:1.5rem!important}.mb-xxl-5{margin-bottom:3rem!important}.mb-xxl-auto{margin-bottom:auto!important}.ms-xxl-0{margin-left:0!important}.ms-xxl-1{margin-left:.25rem!important}.ms-xxl-2{margin-left:.5rem!important}.ms-xxl-3{margin-left:1rem!important}.ms-xxl-4{margin-left:1.5rem!important}.ms-xxl-5{margin-left:3rem!important}.ms-xxl-auto{margin-left:auto!important}.p-xxl-0{padding:0!important}.p-xxl-1{padding:.25rem!important}.p-xxl-2{padding:.5rem!important}.p-xxl-3{padding:1rem!important}.p-xxl-4{padding:1.5rem!important}.p-xxl-5{padding:3rem!important}.px-xxl-0{padding-right:0!important;padding-left:0!important}.px-xxl-1{padding-right:.25rem!important;padding-left:.25rem!important}.px-xxl-2{padding-right:.5rem!important;padding-left:.5rem!important}.px-xxl-3{padding-right:1rem!important;padding-left:1rem!important}.px-xxl-4{padding-right:1.5rem!important;padding-left:1.5rem!important}.px-xxl-5{padding-right:3rem!important;padding-left:3rem!important}.py-xxl-0{padding-top:0!important;padding-bottom:0!important}.py-xxl-1{padding-top:.25rem!important;padding-bottom:.25rem!important}.py-xxl-2{padding-top:.5rem!important;padding-bottom:.5rem!important}.py-xxl-3{padding-top:1rem!important;padding-bottom:1rem!important}.py-xxl-4{padding-top:1.5rem!important;padding-bottom:1.5rem!important}.py-xxl-5{padding-top:3rem!important;padding-bottom:3rem!important}.pt-xxl-0{padding-top:0!important}.pt-xxl-1{padding-top:.25rem!important}.pt-xxl-2{padding-top:.5rem!important}.pt-xxl-3{padding-top:1rem!important}.pt-xxl-4{padding-top:1.5rem!important}.pt-xxl-5{padding-top:3rem!important}.pe-xxl-0{padding-right:0!important}.pe-xxl-1{padding-right:.25rem!important}.pe-xxl-2{padding-right:.5rem!important}.pe-xxl-3{padding-right:1rem!important}.pe-xxl-4{padding-right:1.5rem!important}.pe-xxl-5{padding-right:3rem!important}.pb-xxl-0{padding-bottom:0!important}.pb-xxl-1{padding-bottom:.25rem!important}.pb-xxl-2{padding-bottom:.5rem!important}.pb-xxl-3{padding-bottom:1rem!important}.pb-xxl-4{padding-bottom:1.5rem!important}.pb-xxl-5{padding-bottom:3rem!important}.ps-xxl-0{padding-left:0!important}.ps-xxl-1{padding-left:.25rem!important}.ps-xxl-2{padding-left:.5rem!important}.ps-xxl-3{padding-left:1rem!important}.ps-xxl-4{padding-left:1.5rem!important}.ps-xxl-5{padding-left:3rem!important}.gap-xxl-0{gap:0!important}.gap-xxl-1{gap:.25rem!important}.gap-xxl-2{gap:.5rem!important}.gap-xxl-3{gap:1rem!important}.gap-xxl-4{gap:1.5rem!important}.gap-xxl-5{gap:3rem!important}.row-gap-xxl-0{row-gap:0!important}.row-gap-xxl-1{row-gap:.25rem!important}.row-gap-xxl-2{row-gap:.5rem!important}.row-gap-xxl-3{row-gap:1rem!important}.row-gap-xxl-4{row-gap:1.5rem!important}.row-gap-xxl-5{row-gap:3rem!important}.column-gap-xxl-0{-moz-column-gap:0!important;column-gap:0!important}.column-gap-xxl-1{-moz-column-gap:0.25rem!important;column-gap:.25rem!important}.column-gap-xxl-2{-moz-column-gap:0.5rem!important;column-gap:.5rem!important}.column-gap-xxl-3{-moz-column-gap:1rem!important;column-gap:1rem!important}.column-gap-xxl-4{-moz-column-gap:1.5rem!important;column-gap:1.5rem!important}.column-gap-xxl-5{-moz-column-gap:3rem!important;column-gap:3rem!important}.text-xxl-start{text-align:left!important}.text-xxl-end{text-align:right!important}.text-xxl-center{text-align:center!important}}@media (min-width:1200px){.fs-1{font-size:2.5rem!important}.fs-2{font-size:2rem!important}.fs-3{font-size:1.75rem!important}.fs-4{font-size:1.5rem!important}}@media print{.d-print-inline{display:inline!important}.d-print-inline-block{display:inline-block!important}.d-print-block{display:block!important}.d-print-grid{display:grid!important}.d-print-inline-grid{display:inline-grid!important}.d-print-table{display:table!important}.d-print-table-row{display:table-row!important}.d-print-table-cell{display:table-cell!important}.d-print-flex{display:flex!important}.d-print-inline-flex{display:inline-flex!important}.d-print-none{display:none!important}} -/*# sourceMappingURL=bootstrap.min.css.map */ \ No newline at end of file diff --git a/backend/coverage-report-progress/_css/custom.css b/backend/coverage-report-progress/_css/custom.css deleted file mode 100644 index e69de29b..00000000 diff --git a/backend/coverage-report-progress/_css/nv.d3.min.css b/backend/coverage-report-progress/_css/nv.d3.min.css deleted file mode 100644 index 7a6f7fe9..00000000 --- a/backend/coverage-report-progress/_css/nv.d3.min.css +++ /dev/null @@ -1 +0,0 @@ -.nvd3 .nv-axis{pointer-events:none;opacity:1}.nvd3 .nv-axis path{fill:none;stroke:#000;stroke-opacity:.75;shape-rendering:crispEdges}.nvd3 .nv-axis path.domain{stroke-opacity:.75}.nvd3 .nv-axis.nv-x path.domain{stroke-opacity:0}.nvd3 .nv-axis line{fill:none;stroke:#e5e5e5;shape-rendering:crispEdges}.nvd3 .nv-axis .zero line,.nvd3 .nv-axis line.zero{stroke-opacity:.75}.nvd3 .nv-axis .nv-axisMaxMin text{font-weight:700}.nvd3 .x .nv-axis .nv-axisMaxMin text,.nvd3 .x2 .nv-axis .nv-axisMaxMin text,.nvd3 .x3 .nv-axis .nv-axisMaxMin text{text-anchor:middle}.nvd3 .nv-axis.nv-disabled{opacity:0}.nvd3 .nv-bars rect{fill-opacity:.75;transition:fill-opacity 250ms linear;-moz-transition:fill-opacity 250ms linear;-webkit-transition:fill-opacity 250ms linear}.nvd3 .nv-bars rect.hover{fill-opacity:1}.nvd3 .nv-bars .hover rect{fill:#add8e6}.nvd3 .nv-bars text{fill:rgba(0,0,0,0)}.nvd3 .nv-bars .hover text{fill:rgba(0,0,0,1)}.nvd3 .nv-multibar .nv-groups rect,.nvd3 .nv-multibarHorizontal .nv-groups rect,.nvd3 .nv-discretebar .nv-groups rect{stroke-opacity:0;transition:fill-opacity 250ms linear;-moz-transition:fill-opacity 250ms linear;-webkit-transition:fill-opacity 250ms linear}.nvd3 .nv-multibar .nv-groups rect:hover,.nvd3 .nv-multibarHorizontal .nv-groups rect:hover,.nvd3 .nv-candlestickBar .nv-ticks rect:hover,.nvd3 .nv-discretebar .nv-groups rect:hover{fill-opacity:1}.nvd3 .nv-discretebar .nv-groups text,.nvd3 .nv-multibarHorizontal .nv-groups text{font-weight:700;fill:rgba(0,0,0,1);stroke:rgba(0,0,0,0)}.nvd3 .nv-boxplot circle{fill-opacity:.5}.nvd3 .nv-boxplot circle:hover{fill-opacity:1}.nvd3 .nv-boxplot rect:hover{fill-opacity:1}.nvd3 line.nv-boxplot-median{stroke:#000}.nv-boxplot-tick:hover{stroke-width:2.5px}.nvd3.nv-bullet{font:10px sans-serif}.nvd3.nv-bullet .nv-measure{fill-opacity:.8}.nvd3.nv-bullet .nv-measure:hover{fill-opacity:1}.nvd3.nv-bullet .nv-marker{stroke:#000;stroke-width:2px}.nvd3.nv-bullet .nv-markerTriangle{stroke:#000;fill:#fff;stroke-width:1.5px}.nvd3.nv-bullet .nv-tick line{stroke:#666;stroke-width:.5px}.nvd3.nv-bullet .nv-range.nv-s0{fill:#eee}.nvd3.nv-bullet .nv-range.nv-s1{fill:#ddd}.nvd3.nv-bullet .nv-range.nv-s2{fill:#ccc}.nvd3.nv-bullet .nv-title{font-size:14px;font-weight:700}.nvd3.nv-bullet .nv-subtitle{fill:#999}.nvd3.nv-bullet .nv-range{fill:#bababa;fill-opacity:.4}.nvd3.nv-bullet .nv-range:hover{fill-opacity:.7}.nvd3.nv-candlestickBar .nv-ticks .nv-tick{stroke-width:1px}.nvd3.nv-candlestickBar .nv-ticks .nv-tick.hover{stroke-width:2px}.nvd3.nv-candlestickBar .nv-ticks .nv-tick.positive rect{stroke:#2ca02c;fill:#2ca02c}.nvd3.nv-candlestickBar .nv-ticks .nv-tick.negative rect{stroke:#d62728;fill:#d62728}.with-transitions .nv-candlestickBar .nv-ticks .nv-tick{transition:stroke-width 250ms linear,stroke-opacity 250ms linear;-moz-transition:stroke-width 250ms linear,stroke-opacity 250ms linear;-webkit-transition:stroke-width 250ms linear,stroke-opacity 250ms linear}.nvd3.nv-candlestickBar .nv-ticks line{stroke:#333}.nvd3 .nv-legend .nv-disabled rect{}.nvd3 .nv-check-box .nv-box{fill-opacity:0;stroke-width:2}.nvd3 .nv-check-box .nv-check{fill-opacity:0;stroke-width:4}.nvd3 .nv-series.nv-disabled .nv-check-box .nv-check{fill-opacity:0;stroke-opacity:0}.nvd3 .nv-controlsWrap .nv-legend .nv-check-box .nv-check{opacity:0}.nvd3.nv-linePlusBar .nv-bar rect{fill-opacity:.75}.nvd3.nv-linePlusBar .nv-bar rect:hover{fill-opacity:1}.nvd3 .nv-groups path.nv-line{fill:none}.nvd3 .nv-groups path.nv-area{stroke:none}.nvd3.nv-line .nvd3.nv-scatter .nv-groups .nv-point{fill-opacity:0;stroke-opacity:0}.nvd3.nv-scatter.nv-single-point .nv-groups .nv-point{fill-opacity:.5!important;stroke-opacity:.5!important}.with-transitions .nvd3 .nv-groups .nv-point{transition:stroke-width 250ms linear,stroke-opacity 250ms linear;-moz-transition:stroke-width 250ms linear,stroke-opacity 250ms linear;-webkit-transition:stroke-width 250ms linear,stroke-opacity 250ms linear}.nvd3.nv-scatter .nv-groups .nv-point.hover,.nvd3 .nv-groups .nv-point.hover{stroke-width:7px;fill-opacity:.95!important;stroke-opacity:.95!important}.nvd3 .nv-point-paths path{stroke:#aaa;stroke-opacity:0;fill:#eee;fill-opacity:0}.nvd3 .nv-indexLine{cursor:ew-resize}svg.nvd3-svg{-webkit-touch-callout:none;-webkit-user-select:none;-khtml-user-select:none;-ms-user-select:none;-moz-user-select:none;user-select:none;display:block;width:100%;height:100%}.nvtooltip.with-3d-shadow,.with-3d-shadow .nvtooltip{-moz-box-shadow:0 5px 10px rgba(0,0,0,.2);-webkit-box-shadow:0 5px 10px rgba(0,0,0,.2);box-shadow:0 5px 10px rgba(0,0,0,.2);-webkit-border-radius:5px;-moz-border-radius:5px;border-radius:5px}.nvd3 text{font:400 12px Arial}.nvd3 .title{font:700 14px Arial}.nvd3 .nv-background{fill:#fff;fill-opacity:0}.nvd3.nv-noData{font-size:18px;font-weight:700}.nv-brush .extent{fill-opacity:.125;shape-rendering:crispEdges}.nv-brush .resize path{fill:#eee;stroke:#666}.nvd3 .nv-legend .nv-series{cursor:pointer}.nvd3 .nv-legend .nv-disabled circle{fill-opacity:0}.nvd3 .nv-brush .extent{fill-opacity:0!important}.nvd3 .nv-brushBackground rect{stroke:#000;stroke-width:.4;fill:#fff;fill-opacity:.7}.nvd3.nv-ohlcBar .nv-ticks .nv-tick{stroke-width:1px}.nvd3.nv-ohlcBar .nv-ticks .nv-tick.hover{stroke-width:2px}.nvd3.nv-ohlcBar .nv-ticks .nv-tick.positive{stroke:#2ca02c}.nvd3.nv-ohlcBar .nv-ticks .nv-tick.negative{stroke:#d62728}.nvd3 .background path{fill:none;stroke:#EEE;stroke-opacity:.4;shape-rendering:crispEdges}.nvd3 .foreground path{fill:none;stroke-opacity:.7}.nvd3 .nv-parallelCoordinates-brush .extent{fill:#fff;fill-opacity:.6;stroke:gray;shape-rendering:crispEdges}.nvd3 .nv-parallelCoordinates .hover{fill-opacity:1;stroke-width:3px}.nvd3 .missingValuesline line{fill:none;stroke:#000;stroke-width:1;stroke-opacity:1;stroke-dasharray:5,5}.nvd3.nv-pie path{stroke-opacity:0;transition:fill-opacity 250ms linear,stroke-width 250ms linear,stroke-opacity 250ms linear;-moz-transition:fill-opacity 250ms linear,stroke-width 250ms linear,stroke-opacity 250ms linear;-webkit-transition:fill-opacity 250ms linear,stroke-width 250ms linear,stroke-opacity 250ms linear}.nvd3.nv-pie .nv-pie-title{font-size:24px;fill:rgba(19,196,249,.59)}.nvd3.nv-pie .nv-slice text{stroke:#000;stroke-width:0}.nvd3.nv-pie path{stroke:#fff;stroke-width:1px;stroke-opacity:1}.nvd3.nv-pie .hover path{fill-opacity:.7}.nvd3.nv-pie .nv-label{pointer-events:none}.nvd3.nv-pie .nv-label rect{fill-opacity:0;stroke-opacity:0}.nvd3 .nv-groups .nv-point.hover{stroke-width:20px;stroke-opacity:.5}.nvd3 .nv-scatter .nv-point.hover{fill-opacity:1}.nv-noninteractive{pointer-events:none}.nv-distx,.nv-disty{pointer-events:none}.nvd3.nv-sparkline path{fill:none}.nvd3.nv-sparklineplus g.nv-hoverValue{pointer-events:none}.nvd3.nv-sparklineplus .nv-hoverValue line{stroke:#333;stroke-width:1.5px}.nvd3.nv-sparklineplus,.nvd3.nv-sparklineplus g{pointer-events:all}.nvd3 .nv-hoverArea{fill-opacity:0;stroke-opacity:0}.nvd3.nv-sparklineplus .nv-xValue,.nvd3.nv-sparklineplus .nv-yValue{stroke-width:0;font-size:.9em;font-weight:400}.nvd3.nv-sparklineplus .nv-yValue{stroke:#f66}.nvd3.nv-sparklineplus .nv-maxValue{stroke:#2ca02c;fill:#2ca02c}.nvd3.nv-sparklineplus .nv-minValue{stroke:#d62728;fill:#d62728}.nvd3.nv-sparklineplus .nv-currentValue{font-weight:700;font-size:1.1em}.nvd3.nv-stackedarea path.nv-area{fill-opacity:.7;stroke-opacity:0;transition:fill-opacity 250ms linear,stroke-opacity 250ms linear;-moz-transition:fill-opacity 250ms linear,stroke-opacity 250ms linear;-webkit-transition:fill-opacity 250ms linear,stroke-opacity 250ms linear}.nvd3.nv-stackedarea path.nv-area.hover{fill-opacity:.9}.nvd3.nv-stackedarea .nv-groups .nv-point{stroke-opacity:0;fill-opacity:0}.nvtooltip{position:absolute;background-color:rgba(255,255,255,1);color:rgba(0,0,0,1);padding:1px;border:1px solid rgba(0,0,0,.2);z-index:10000;display:block;font-family:Arial;font-size:13px;text-align:left;pointer-events:none;white-space:nowrap;-webkit-touch-callout:none;-webkit-user-select:none;-khtml-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.nvtooltip{background:rgba(255,255,255,.8);border:1px solid rgba(0,0,0,.5);border-radius:4px}.nvtooltip.with-transitions,.with-transitions .nvtooltip{transition:opacity 50ms linear;-moz-transition:opacity 50ms linear;-webkit-transition:opacity 50ms linear;transition-delay:200ms;-moz-transition-delay:200ms;-webkit-transition-delay:200ms}.nvtooltip.x-nvtooltip,.nvtooltip.y-nvtooltip{padding:8px}.nvtooltip h3{margin:0;padding:4px 14px;line-height:18px;font-weight:400;background-color:rgba(247,247,247,.75);color:rgba(0,0,0,1);text-align:center;border-bottom:1px solid #ebebeb;-webkit-border-radius:5px 5px 0 0;-moz-border-radius:5px 5px 0 0;border-radius:5px 5px 0 0}.nvtooltip p{margin:0;padding:5px 14px;text-align:center}.nvtooltip span{display:inline-block;margin:2px 0}.nvtooltip table{margin:6px;border-spacing:0}.nvtooltip table td{padding:2px 9px 2px 0;vertical-align:middle}.nvtooltip table td.key{font-weight:400}.nvtooltip table td.value{text-align:right;font-weight:700}.nvtooltip table tr.highlight td{padding:1px 9px 1px 0;border-bottom-style:solid;border-bottom-width:1px;border-top-style:solid;border-top-width:1px}.nvtooltip table td.legend-color-guide div{width:8px;height:8px;vertical-align:middle}.nvtooltip table td.legend-color-guide div{width:12px;height:12px;border:1px solid #999}.nvtooltip .footer{padding:3px;text-align:center}.nvtooltip-pending-removal{pointer-events:none;display:none}.nvd3 .nv-interactiveGuideLine{pointer-events:none}.nvd3 line.nv-guideline{stroke:#ccc} \ No newline at end of file diff --git a/backend/coverage-report-progress/_css/octicons.css b/backend/coverage-report-progress/_css/octicons.css deleted file mode 100644 index 31d97867..00000000 --- a/backend/coverage-report-progress/_css/octicons.css +++ /dev/null @@ -1,5 +0,0 @@ -.octicon { - display: inline-block; - vertical-align: text-top; - fill: currentColor; -} diff --git a/backend/coverage-report-progress/_css/style.css b/backend/coverage-report-progress/_css/style.css deleted file mode 100644 index b007558e..00000000 --- a/backend/coverage-report-progress/_css/style.css +++ /dev/null @@ -1,201 +0,0 @@ -:root { - --phpunit-breadcrumbs: var(--bs-gray-200); - --phpunit-success-bar: #28a745; - --phpunit-success-high: #99cb84; - --phpunit-success-medium: #c3e3b5; - --phpunit-success-low: #dff0d8; - --phpunit-warning: #fcf8e3; - --phpunit-warning-bar: #ffc107; - --phpunit-danger: #f2dede; - --phpunit-danger-bar: #dc3545; -} - -body { - font-family: sans-serif; - font-size: 1em; - font-kerning: normal; - text-rendering: optimizeLegibility; - padding-top: 10px; -} - -nav .breadcrumb { - border-radius: var(--bs-border-radius); - background-color: var(--phpunit-breadcrumbs); - padding: .75rem 1rem; -} - -.popover { - max-width: none; -} - -.popover-body { - max-height: 90vh; - overflow-y: auto; -} - -.octicon { - margin-right:.25em; - vertical-align: baseline; - width: 0.75em; -} - -.table-bordered>thead>tr>td { - border-bottom-width: 1px; -} - -.table tbody>tr>td, .table thead>tr>td { - padding-top: 3px; - padding-bottom: 3px; -} - -.table-condensed tbody>tr>td { - padding-top: 0; - padding-bottom: 0; -} - -.table .progress { - margin-bottom: inherit; -} - -.table-borderless th, .table-borderless td { - border: 0 !important; -} - -.table tbody tr.covered-by-large-tests, .table tbody tr.covered-by-large-tests td, li.covered-by-large-tests, tr.success, tr.success td, td.success, li.success, span.success { - background-color: var(--phpunit-success-low); -} - -.table tbody tr.covered-by-medium-tests, .table tbody tr.covered-by-medium-tests td, li.covered-by-medium-tests { - background-color: var(--phpunit-success-medium); -} - -.table tbody tr.covered-by-small-tests, .table tbody tr.covered-by-small-tests td, li.covered-by-small-tests { - background-color: var(--phpunit-success-high); -} - -.table tbody tr.warning, .table tbody tr.warning td, .table tbody td.warning, li.warning, span.warning { - background-color: var(--phpunit-warning); -} - -.table tbody tr.danger, .table tbody tr.danger td, .table tbody td.danger, li.danger, span.danger { - background-color: var(--phpunit-danger); -} - -.table tbody td.info { - background-color: rgb(from var(--bs-info) r g b / 0.25); -} - -td.big { - vertical-align: middle; - width: 117px; -} - -td.small { -} - -td.codeLine { - font-family: "Source Code Pro", var(--bs-font-monospace); - white-space: pre-wrap; -} - -td span.comment { - color: var(--bs-secondary-color); -} - -td span.default { - color: var(--bs-body-color); -} - -td span.html { - color: var(--bs-secondary-color); -} - -td span.keyword { - color: var(--bs-body-color); - font-weight: bold; -} - -pre span.string { - color: var(--bs-body-color); -} - -span.success, span.warning, span.danger { - margin-right: 2px; - padding-left: 10px; - padding-right: 10px; - text-align: center; -} - -#toplink { - position: fixed; - left: 5px; - bottom: 5px; - outline: 0; -} - -svg text { - font-family: var(--bs-font-sans-serif); - font-size: 11px; - color: var(--bs-gray); - fill: var(--bs-gray); -} - -.scrollbox { - height:245px; - overflow-x:scroll; - overflow-y:scroll; -} - -table + .structure-heading { - border-top: 1px solid var(--bs-gray-200); - padding-top: 0.5em; -} - -table#code td:first-of-type { - padding-left: .75em; - padding-right: .75em; -} - -table#code td:first-of-type a { - text-decoration: none; -} - -.legend { - font-weight: bold; - margin-right: 2px; - padding-left: 10px; - padding-right: 10px; - text-align: center; -} - -.covered-by-small-tests { - background-color: var(--phpunit-success-high); -} - -.covered-by-medium-tests { - background-color: var(--phpunit-success-medium); -} - -.covered-by-large-tests { - background-color: var(--phpunit-success-low); -} - -.not-covered { - background-color: var(--phpunit-danger); -} - -.not-coverable { - background-color: var(--phpunit-warning); -} - -.progress-bar.bg-success { - background-color: var(--phpunit-success-bar) !important; -} - -.progress-bar.bg-warning { - background-color: var(--phpunit-warning-bar) !important; -} - -.progress-bar.bg-danger { - background-color: var(--phpunit-danger-bar) !important; -} \ No newline at end of file diff --git a/backend/coverage-report-progress/_icons/file-code.svg b/backend/coverage-report-progress/_icons/file-code.svg deleted file mode 100644 index 5b4b1995..00000000 --- a/backend/coverage-report-progress/_icons/file-code.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/backend/coverage-report-progress/_icons/file-directory.svg b/backend/coverage-report-progress/_icons/file-directory.svg deleted file mode 100644 index 4bf1f1ca..00000000 --- a/backend/coverage-report-progress/_icons/file-directory.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/backend/coverage-report-progress/_js/bootstrap.bundle.min.js b/backend/coverage-report-progress/_js/bootstrap.bundle.min.js deleted file mode 100644 index 8739c91c..00000000 --- a/backend/coverage-report-progress/_js/bootstrap.bundle.min.js +++ /dev/null @@ -1,7 +0,0 @@ -/*! - * Bootstrap v5.3.6 (https://getbootstrap.com/) - * Copyright 2011-2025 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors) - * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) - */ -!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):(t="undefined"!=typeof globalThis?globalThis:t||self).bootstrap=e()}(this,(function(){"use strict";const t=new Map,e={set(e,i,n){t.has(e)||t.set(e,new Map);const s=t.get(e);s.has(i)||0===s.size?s.set(i,n):console.error(`Bootstrap doesn't allow more than one instance per element. Bound instance: ${Array.from(s.keys())[0]}.`)},get:(e,i)=>t.has(e)&&t.get(e).get(i)||null,remove(e,i){if(!t.has(e))return;const n=t.get(e);n.delete(i),0===n.size&&t.delete(e)}},i="transitionend",n=t=>(t&&window.CSS&&window.CSS.escape&&(t=t.replace(/#([^\s"#']+)/g,((t,e)=>`#${CSS.escape(e)}`))),t),s=t=>{t.dispatchEvent(new Event(i))},o=t=>!(!t||"object"!=typeof t)&&(void 0!==t.jquery&&(t=t[0]),void 0!==t.nodeType),r=t=>o(t)?t.jquery?t[0]:t:"string"==typeof t&&t.length>0?document.querySelector(n(t)):null,a=t=>{if(!o(t)||0===t.getClientRects().length)return!1;const e="visible"===getComputedStyle(t).getPropertyValue("visibility"),i=t.closest("details:not([open])");if(!i)return e;if(i!==t){const e=t.closest("summary");if(e&&e.parentNode!==i)return!1;if(null===e)return!1}return e},l=t=>!t||t.nodeType!==Node.ELEMENT_NODE||!!t.classList.contains("disabled")||(void 0!==t.disabled?t.disabled:t.hasAttribute("disabled")&&"false"!==t.getAttribute("disabled")),c=t=>{if(!document.documentElement.attachShadow)return null;if("function"==typeof t.getRootNode){const e=t.getRootNode();return e instanceof ShadowRoot?e:null}return t instanceof ShadowRoot?t:t.parentNode?c(t.parentNode):null},h=()=>{},d=t=>{t.offsetHeight},u=()=>window.jQuery&&!document.body.hasAttribute("data-bs-no-jquery")?window.jQuery:null,f=[],p=()=>"rtl"===document.documentElement.dir,m=t=>{var e;e=()=>{const e=u();if(e){const i=t.NAME,n=e.fn[i];e.fn[i]=t.jQueryInterface,e.fn[i].Constructor=t,e.fn[i].noConflict=()=>(e.fn[i]=n,t.jQueryInterface)}},"loading"===document.readyState?(f.length||document.addEventListener("DOMContentLoaded",(()=>{for(const t of f)t()})),f.push(e)):e()},g=(t,e=[],i=t)=>"function"==typeof t?t.call(...e):i,_=(t,e,n=!0)=>{if(!n)return void g(t);const o=(t=>{if(!t)return 0;let{transitionDuration:e,transitionDelay:i}=window.getComputedStyle(t);const n=Number.parseFloat(e),s=Number.parseFloat(i);return n||s?(e=e.split(",")[0],i=i.split(",")[0],1e3*(Number.parseFloat(e)+Number.parseFloat(i))):0})(e)+5;let r=!1;const a=({target:n})=>{n===e&&(r=!0,e.removeEventListener(i,a),g(t))};e.addEventListener(i,a),setTimeout((()=>{r||s(e)}),o)},b=(t,e,i,n)=>{const s=t.length;let o=t.indexOf(e);return-1===o?!i&&n?t[s-1]:t[0]:(o+=i?1:-1,n&&(o=(o+s)%s),t[Math.max(0,Math.min(o,s-1))])},v=/[^.]*(?=\..*)\.|.*/,y=/\..*/,w=/::\d+$/,A={};let E=1;const T={mouseenter:"mouseover",mouseleave:"mouseout"},C=new Set(["click","dblclick","mouseup","mousedown","contextmenu","mousewheel","DOMMouseScroll","mouseover","mouseout","mousemove","selectstart","selectend","keydown","keypress","keyup","orientationchange","touchstart","touchmove","touchend","touchcancel","pointerdown","pointermove","pointerup","pointerleave","pointercancel","gesturestart","gesturechange","gestureend","focus","blur","change","reset","select","submit","focusin","focusout","load","unload","beforeunload","resize","move","DOMContentLoaded","readystatechange","error","abort","scroll"]);function O(t,e){return e&&`${e}::${E++}`||t.uidEvent||E++}function x(t){const e=O(t);return t.uidEvent=e,A[e]=A[e]||{},A[e]}function k(t,e,i=null){return Object.values(t).find((t=>t.callable===e&&t.delegationSelector===i))}function L(t,e,i){const n="string"==typeof e,s=n?i:e||i;let o=I(t);return C.has(o)||(o=t),[n,s,o]}function S(t,e,i,n,s){if("string"!=typeof e||!t)return;let[o,r,a]=L(e,i,n);if(e in T){const t=t=>function(e){if(!e.relatedTarget||e.relatedTarget!==e.delegateTarget&&!e.delegateTarget.contains(e.relatedTarget))return t.call(this,e)};r=t(r)}const l=x(t),c=l[a]||(l[a]={}),h=k(c,r,o?i:null);if(h)return void(h.oneOff=h.oneOff&&s);const d=O(r,e.replace(v,"")),u=o?function(t,e,i){return function n(s){const o=t.querySelectorAll(e);for(let{target:r}=s;r&&r!==this;r=r.parentNode)for(const a of o)if(a===r)return P(s,{delegateTarget:r}),n.oneOff&&N.off(t,s.type,e,i),i.apply(r,[s])}}(t,i,r):function(t,e){return function i(n){return P(n,{delegateTarget:t}),i.oneOff&&N.off(t,n.type,e),e.apply(t,[n])}}(t,r);u.delegationSelector=o?i:null,u.callable=r,u.oneOff=s,u.uidEvent=d,c[d]=u,t.addEventListener(a,u,o)}function D(t,e,i,n,s){const o=k(e[i],n,s);o&&(t.removeEventListener(i,o,Boolean(s)),delete e[i][o.uidEvent])}function $(t,e,i,n){const s=e[i]||{};for(const[o,r]of Object.entries(s))o.includes(n)&&D(t,e,i,r.callable,r.delegationSelector)}function I(t){return t=t.replace(y,""),T[t]||t}const N={on(t,e,i,n){S(t,e,i,n,!1)},one(t,e,i,n){S(t,e,i,n,!0)},off(t,e,i,n){if("string"!=typeof e||!t)return;const[s,o,r]=L(e,i,n),a=r!==e,l=x(t),c=l[r]||{},h=e.startsWith(".");if(void 0===o){if(h)for(const i of Object.keys(l))$(t,l,i,e.slice(1));for(const[i,n]of Object.entries(c)){const s=i.replace(w,"");a&&!e.includes(s)||D(t,l,r,n.callable,n.delegationSelector)}}else{if(!Object.keys(c).length)return;D(t,l,r,o,s?i:null)}},trigger(t,e,i){if("string"!=typeof e||!t)return null;const n=u();let s=null,o=!0,r=!0,a=!1;e!==I(e)&&n&&(s=n.Event(e,i),n(t).trigger(s),o=!s.isPropagationStopped(),r=!s.isImmediatePropagationStopped(),a=s.isDefaultPrevented());const l=P(new Event(e,{bubbles:o,cancelable:!0}),i);return a&&l.preventDefault(),r&&t.dispatchEvent(l),l.defaultPrevented&&s&&s.preventDefault(),l}};function P(t,e={}){for(const[i,n]of Object.entries(e))try{t[i]=n}catch(e){Object.defineProperty(t,i,{configurable:!0,get:()=>n})}return t}function j(t){if("true"===t)return!0;if("false"===t)return!1;if(t===Number(t).toString())return Number(t);if(""===t||"null"===t)return null;if("string"!=typeof t)return t;try{return JSON.parse(decodeURIComponent(t))}catch(e){return t}}function M(t){return t.replace(/[A-Z]/g,(t=>`-${t.toLowerCase()}`))}const F={setDataAttribute(t,e,i){t.setAttribute(`data-bs-${M(e)}`,i)},removeDataAttribute(t,e){t.removeAttribute(`data-bs-${M(e)}`)},getDataAttributes(t){if(!t)return{};const e={},i=Object.keys(t.dataset).filter((t=>t.startsWith("bs")&&!t.startsWith("bsConfig")));for(const n of i){let i=n.replace(/^bs/,"");i=i.charAt(0).toLowerCase()+i.slice(1),e[i]=j(t.dataset[n])}return e},getDataAttribute:(t,e)=>j(t.getAttribute(`data-bs-${M(e)}`))};class H{static get Default(){return{}}static get DefaultType(){return{}}static get NAME(){throw new Error('You have to implement the static method "NAME", for each component!')}_getConfig(t){return t=this._mergeConfigObj(t),t=this._configAfterMerge(t),this._typeCheckConfig(t),t}_configAfterMerge(t){return t}_mergeConfigObj(t,e){const i=o(e)?F.getDataAttribute(e,"config"):{};return{...this.constructor.Default,..."object"==typeof i?i:{},...o(e)?F.getDataAttributes(e):{},..."object"==typeof t?t:{}}}_typeCheckConfig(t,e=this.constructor.DefaultType){for(const[n,s]of Object.entries(e)){const e=t[n],r=o(e)?"element":null==(i=e)?`${i}`:Object.prototype.toString.call(i).match(/\s([a-z]+)/i)[1].toLowerCase();if(!new RegExp(s).test(r))throw new TypeError(`${this.constructor.NAME.toUpperCase()}: Option "${n}" provided type "${r}" but expected type "${s}".`)}var i}}class W extends H{constructor(t,i){super(),(t=r(t))&&(this._element=t,this._config=this._getConfig(i),e.set(this._element,this.constructor.DATA_KEY,this))}dispose(){e.remove(this._element,this.constructor.DATA_KEY),N.off(this._element,this.constructor.EVENT_KEY);for(const t of Object.getOwnPropertyNames(this))this[t]=null}_queueCallback(t,e,i=!0){_(t,e,i)}_getConfig(t){return t=this._mergeConfigObj(t,this._element),t=this._configAfterMerge(t),this._typeCheckConfig(t),t}static getInstance(t){return e.get(r(t),this.DATA_KEY)}static getOrCreateInstance(t,e={}){return this.getInstance(t)||new this(t,"object"==typeof e?e:null)}static get VERSION(){return"5.3.6"}static get DATA_KEY(){return`bs.${this.NAME}`}static get EVENT_KEY(){return`.${this.DATA_KEY}`}static eventName(t){return`${t}${this.EVENT_KEY}`}}const B=t=>{let e=t.getAttribute("data-bs-target");if(!e||"#"===e){let i=t.getAttribute("href");if(!i||!i.includes("#")&&!i.startsWith("."))return null;i.includes("#")&&!i.startsWith("#")&&(i=`#${i.split("#")[1]}`),e=i&&"#"!==i?i.trim():null}return e?e.split(",").map((t=>n(t))).join(","):null},z={find:(t,e=document.documentElement)=>[].concat(...Element.prototype.querySelectorAll.call(e,t)),findOne:(t,e=document.documentElement)=>Element.prototype.querySelector.call(e,t),children:(t,e)=>[].concat(...t.children).filter((t=>t.matches(e))),parents(t,e){const i=[];let n=t.parentNode.closest(e);for(;n;)i.push(n),n=n.parentNode.closest(e);return i},prev(t,e){let i=t.previousElementSibling;for(;i;){if(i.matches(e))return[i];i=i.previousElementSibling}return[]},next(t,e){let i=t.nextElementSibling;for(;i;){if(i.matches(e))return[i];i=i.nextElementSibling}return[]},focusableChildren(t){const e=["a","button","input","textarea","select","details","[tabindex]",'[contenteditable="true"]'].map((t=>`${t}:not([tabindex^="-"])`)).join(",");return this.find(e,t).filter((t=>!l(t)&&a(t)))},getSelectorFromElement(t){const e=B(t);return e&&z.findOne(e)?e:null},getElementFromSelector(t){const e=B(t);return e?z.findOne(e):null},getMultipleElementsFromSelector(t){const e=B(t);return e?z.find(e):[]}},R=(t,e="hide")=>{const i=`click.dismiss${t.EVENT_KEY}`,n=t.NAME;N.on(document,i,`[data-bs-dismiss="${n}"]`,(function(i){if(["A","AREA"].includes(this.tagName)&&i.preventDefault(),l(this))return;const s=z.getElementFromSelector(this)||this.closest(`.${n}`);t.getOrCreateInstance(s)[e]()}))},q=".bs.alert",V=`close${q}`,K=`closed${q}`;class Q extends W{static get NAME(){return"alert"}close(){if(N.trigger(this._element,V).defaultPrevented)return;this._element.classList.remove("show");const t=this._element.classList.contains("fade");this._queueCallback((()=>this._destroyElement()),this._element,t)}_destroyElement(){this._element.remove(),N.trigger(this._element,K),this.dispose()}static jQueryInterface(t){return this.each((function(){const e=Q.getOrCreateInstance(this);if("string"==typeof t){if(void 0===e[t]||t.startsWith("_")||"constructor"===t)throw new TypeError(`No method named "${t}"`);e[t](this)}}))}}R(Q,"close"),m(Q);const X='[data-bs-toggle="button"]';class Y extends W{static get NAME(){return"button"}toggle(){this._element.setAttribute("aria-pressed",this._element.classList.toggle("active"))}static jQueryInterface(t){return this.each((function(){const e=Y.getOrCreateInstance(this);"toggle"===t&&e[t]()}))}}N.on(document,"click.bs.button.data-api",X,(t=>{t.preventDefault();const e=t.target.closest(X);Y.getOrCreateInstance(e).toggle()})),m(Y);const U=".bs.swipe",G=`touchstart${U}`,J=`touchmove${U}`,Z=`touchend${U}`,tt=`pointerdown${U}`,et=`pointerup${U}`,it={endCallback:null,leftCallback:null,rightCallback:null},nt={endCallback:"(function|null)",leftCallback:"(function|null)",rightCallback:"(function|null)"};class st extends H{constructor(t,e){super(),this._element=t,t&&st.isSupported()&&(this._config=this._getConfig(e),this._deltaX=0,this._supportPointerEvents=Boolean(window.PointerEvent),this._initEvents())}static get Default(){return it}static get DefaultType(){return nt}static get NAME(){return"swipe"}dispose(){N.off(this._element,U)}_start(t){this._supportPointerEvents?this._eventIsPointerPenTouch(t)&&(this._deltaX=t.clientX):this._deltaX=t.touches[0].clientX}_end(t){this._eventIsPointerPenTouch(t)&&(this._deltaX=t.clientX-this._deltaX),this._handleSwipe(),g(this._config.endCallback)}_move(t){this._deltaX=t.touches&&t.touches.length>1?0:t.touches[0].clientX-this._deltaX}_handleSwipe(){const t=Math.abs(this._deltaX);if(t<=40)return;const e=t/this._deltaX;this._deltaX=0,e&&g(e>0?this._config.rightCallback:this._config.leftCallback)}_initEvents(){this._supportPointerEvents?(N.on(this._element,tt,(t=>this._start(t))),N.on(this._element,et,(t=>this._end(t))),this._element.classList.add("pointer-event")):(N.on(this._element,G,(t=>this._start(t))),N.on(this._element,J,(t=>this._move(t))),N.on(this._element,Z,(t=>this._end(t))))}_eventIsPointerPenTouch(t){return this._supportPointerEvents&&("pen"===t.pointerType||"touch"===t.pointerType)}static isSupported(){return"ontouchstart"in document.documentElement||navigator.maxTouchPoints>0}}const ot=".bs.carousel",rt=".data-api",at="ArrowLeft",lt="ArrowRight",ct="next",ht="prev",dt="left",ut="right",ft=`slide${ot}`,pt=`slid${ot}`,mt=`keydown${ot}`,gt=`mouseenter${ot}`,_t=`mouseleave${ot}`,bt=`dragstart${ot}`,vt=`load${ot}${rt}`,yt=`click${ot}${rt}`,wt="carousel",At="active",Et=".active",Tt=".carousel-item",Ct=Et+Tt,Ot={[at]:ut,[lt]:dt},xt={interval:5e3,keyboard:!0,pause:"hover",ride:!1,touch:!0,wrap:!0},kt={interval:"(number|boolean)",keyboard:"boolean",pause:"(string|boolean)",ride:"(boolean|string)",touch:"boolean",wrap:"boolean"};class Lt extends W{constructor(t,e){super(t,e),this._interval=null,this._activeElement=null,this._isSliding=!1,this.touchTimeout=null,this._swipeHelper=null,this._indicatorsElement=z.findOne(".carousel-indicators",this._element),this._addEventListeners(),this._config.ride===wt&&this.cycle()}static get Default(){return xt}static get DefaultType(){return kt}static get NAME(){return"carousel"}next(){this._slide(ct)}nextWhenVisible(){!document.hidden&&a(this._element)&&this.next()}prev(){this._slide(ht)}pause(){this._isSliding&&s(this._element),this._clearInterval()}cycle(){this._clearInterval(),this._updateInterval(),this._interval=setInterval((()=>this.nextWhenVisible()),this._config.interval)}_maybeEnableCycle(){this._config.ride&&(this._isSliding?N.one(this._element,pt,(()=>this.cycle())):this.cycle())}to(t){const e=this._getItems();if(t>e.length-1||t<0)return;if(this._isSliding)return void N.one(this._element,pt,(()=>this.to(t)));const i=this._getItemIndex(this._getActive());if(i===t)return;const n=t>i?ct:ht;this._slide(n,e[t])}dispose(){this._swipeHelper&&this._swipeHelper.dispose(),super.dispose()}_configAfterMerge(t){return t.defaultInterval=t.interval,t}_addEventListeners(){this._config.keyboard&&N.on(this._element,mt,(t=>this._keydown(t))),"hover"===this._config.pause&&(N.on(this._element,gt,(()=>this.pause())),N.on(this._element,_t,(()=>this._maybeEnableCycle()))),this._config.touch&&st.isSupported()&&this._addTouchEventListeners()}_addTouchEventListeners(){for(const t of z.find(".carousel-item img",this._element))N.on(t,bt,(t=>t.preventDefault()));const t={leftCallback:()=>this._slide(this._directionToOrder(dt)),rightCallback:()=>this._slide(this._directionToOrder(ut)),endCallback:()=>{"hover"===this._config.pause&&(this.pause(),this.touchTimeout&&clearTimeout(this.touchTimeout),this.touchTimeout=setTimeout((()=>this._maybeEnableCycle()),500+this._config.interval))}};this._swipeHelper=new st(this._element,t)}_keydown(t){if(/input|textarea/i.test(t.target.tagName))return;const e=Ot[t.key];e&&(t.preventDefault(),this._slide(this._directionToOrder(e)))}_getItemIndex(t){return this._getItems().indexOf(t)}_setActiveIndicatorElement(t){if(!this._indicatorsElement)return;const e=z.findOne(Et,this._indicatorsElement);e.classList.remove(At),e.removeAttribute("aria-current");const i=z.findOne(`[data-bs-slide-to="${t}"]`,this._indicatorsElement);i&&(i.classList.add(At),i.setAttribute("aria-current","true"))}_updateInterval(){const t=this._activeElement||this._getActive();if(!t)return;const e=Number.parseInt(t.getAttribute("data-bs-interval"),10);this._config.interval=e||this._config.defaultInterval}_slide(t,e=null){if(this._isSliding)return;const i=this._getActive(),n=t===ct,s=e||b(this._getItems(),i,n,this._config.wrap);if(s===i)return;const o=this._getItemIndex(s),r=e=>N.trigger(this._element,e,{relatedTarget:s,direction:this._orderToDirection(t),from:this._getItemIndex(i),to:o});if(r(ft).defaultPrevented)return;if(!i||!s)return;const a=Boolean(this._interval);this.pause(),this._isSliding=!0,this._setActiveIndicatorElement(o),this._activeElement=s;const l=n?"carousel-item-start":"carousel-item-end",c=n?"carousel-item-next":"carousel-item-prev";s.classList.add(c),d(s),i.classList.add(l),s.classList.add(l),this._queueCallback((()=>{s.classList.remove(l,c),s.classList.add(At),i.classList.remove(At,c,l),this._isSliding=!1,r(pt)}),i,this._isAnimated()),a&&this.cycle()}_isAnimated(){return this._element.classList.contains("slide")}_getActive(){return z.findOne(Ct,this._element)}_getItems(){return z.find(Tt,this._element)}_clearInterval(){this._interval&&(clearInterval(this._interval),this._interval=null)}_directionToOrder(t){return p()?t===dt?ht:ct:t===dt?ct:ht}_orderToDirection(t){return p()?t===ht?dt:ut:t===ht?ut:dt}static jQueryInterface(t){return this.each((function(){const e=Lt.getOrCreateInstance(this,t);if("number"!=typeof t){if("string"==typeof t){if(void 0===e[t]||t.startsWith("_")||"constructor"===t)throw new TypeError(`No method named "${t}"`);e[t]()}}else e.to(t)}))}}N.on(document,yt,"[data-bs-slide], [data-bs-slide-to]",(function(t){const e=z.getElementFromSelector(this);if(!e||!e.classList.contains(wt))return;t.preventDefault();const i=Lt.getOrCreateInstance(e),n=this.getAttribute("data-bs-slide-to");return n?(i.to(n),void i._maybeEnableCycle()):"next"===F.getDataAttribute(this,"slide")?(i.next(),void i._maybeEnableCycle()):(i.prev(),void i._maybeEnableCycle())})),N.on(window,vt,(()=>{const t=z.find('[data-bs-ride="carousel"]');for(const e of t)Lt.getOrCreateInstance(e)})),m(Lt);const St=".bs.collapse",Dt=`show${St}`,$t=`shown${St}`,It=`hide${St}`,Nt=`hidden${St}`,Pt=`click${St}.data-api`,jt="show",Mt="collapse",Ft="collapsing",Ht=`:scope .${Mt} .${Mt}`,Wt='[data-bs-toggle="collapse"]',Bt={parent:null,toggle:!0},zt={parent:"(null|element)",toggle:"boolean"};class Rt extends W{constructor(t,e){super(t,e),this._isTransitioning=!1,this._triggerArray=[];const i=z.find(Wt);for(const t of i){const e=z.getSelectorFromElement(t),i=z.find(e).filter((t=>t===this._element));null!==e&&i.length&&this._triggerArray.push(t)}this._initializeChildren(),this._config.parent||this._addAriaAndCollapsedClass(this._triggerArray,this._isShown()),this._config.toggle&&this.toggle()}static get Default(){return Bt}static get DefaultType(){return zt}static get NAME(){return"collapse"}toggle(){this._isShown()?this.hide():this.show()}show(){if(this._isTransitioning||this._isShown())return;let t=[];if(this._config.parent&&(t=this._getFirstLevelChildren(".collapse.show, .collapse.collapsing").filter((t=>t!==this._element)).map((t=>Rt.getOrCreateInstance(t,{toggle:!1})))),t.length&&t[0]._isTransitioning)return;if(N.trigger(this._element,Dt).defaultPrevented)return;for(const e of t)e.hide();const e=this._getDimension();this._element.classList.remove(Mt),this._element.classList.add(Ft),this._element.style[e]=0,this._addAriaAndCollapsedClass(this._triggerArray,!0),this._isTransitioning=!0;const i=`scroll${e[0].toUpperCase()+e.slice(1)}`;this._queueCallback((()=>{this._isTransitioning=!1,this._element.classList.remove(Ft),this._element.classList.add(Mt,jt),this._element.style[e]="",N.trigger(this._element,$t)}),this._element,!0),this._element.style[e]=`${this._element[i]}px`}hide(){if(this._isTransitioning||!this._isShown())return;if(N.trigger(this._element,It).defaultPrevented)return;const t=this._getDimension();this._element.style[t]=`${this._element.getBoundingClientRect()[t]}px`,d(this._element),this._element.classList.add(Ft),this._element.classList.remove(Mt,jt);for(const t of this._triggerArray){const e=z.getElementFromSelector(t);e&&!this._isShown(e)&&this._addAriaAndCollapsedClass([t],!1)}this._isTransitioning=!0,this._element.style[t]="",this._queueCallback((()=>{this._isTransitioning=!1,this._element.classList.remove(Ft),this._element.classList.add(Mt),N.trigger(this._element,Nt)}),this._element,!0)}_isShown(t=this._element){return t.classList.contains(jt)}_configAfterMerge(t){return t.toggle=Boolean(t.toggle),t.parent=r(t.parent),t}_getDimension(){return this._element.classList.contains("collapse-horizontal")?"width":"height"}_initializeChildren(){if(!this._config.parent)return;const t=this._getFirstLevelChildren(Wt);for(const e of t){const t=z.getElementFromSelector(e);t&&this._addAriaAndCollapsedClass([e],this._isShown(t))}}_getFirstLevelChildren(t){const e=z.find(Ht,this._config.parent);return z.find(t,this._config.parent).filter((t=>!e.includes(t)))}_addAriaAndCollapsedClass(t,e){if(t.length)for(const i of t)i.classList.toggle("collapsed",!e),i.setAttribute("aria-expanded",e)}static jQueryInterface(t){const e={};return"string"==typeof t&&/show|hide/.test(t)&&(e.toggle=!1),this.each((function(){const i=Rt.getOrCreateInstance(this,e);if("string"==typeof t){if(void 0===i[t])throw new TypeError(`No method named "${t}"`);i[t]()}}))}}N.on(document,Pt,Wt,(function(t){("A"===t.target.tagName||t.delegateTarget&&"A"===t.delegateTarget.tagName)&&t.preventDefault();for(const t of z.getMultipleElementsFromSelector(this))Rt.getOrCreateInstance(t,{toggle:!1}).toggle()})),m(Rt);var qt="top",Vt="bottom",Kt="right",Qt="left",Xt="auto",Yt=[qt,Vt,Kt,Qt],Ut="start",Gt="end",Jt="clippingParents",Zt="viewport",te="popper",ee="reference",ie=Yt.reduce((function(t,e){return t.concat([e+"-"+Ut,e+"-"+Gt])}),[]),ne=[].concat(Yt,[Xt]).reduce((function(t,e){return t.concat([e,e+"-"+Ut,e+"-"+Gt])}),[]),se="beforeRead",oe="read",re="afterRead",ae="beforeMain",le="main",ce="afterMain",he="beforeWrite",de="write",ue="afterWrite",fe=[se,oe,re,ae,le,ce,he,de,ue];function pe(t){return t?(t.nodeName||"").toLowerCase():null}function me(t){if(null==t)return window;if("[object Window]"!==t.toString()){var e=t.ownerDocument;return e&&e.defaultView||window}return t}function ge(t){return t instanceof me(t).Element||t instanceof Element}function _e(t){return t instanceof me(t).HTMLElement||t instanceof HTMLElement}function be(t){return"undefined"!=typeof ShadowRoot&&(t instanceof me(t).ShadowRoot||t instanceof ShadowRoot)}const ve={name:"applyStyles",enabled:!0,phase:"write",fn:function(t){var e=t.state;Object.keys(e.elements).forEach((function(t){var i=e.styles[t]||{},n=e.attributes[t]||{},s=e.elements[t];_e(s)&&pe(s)&&(Object.assign(s.style,i),Object.keys(n).forEach((function(t){var e=n[t];!1===e?s.removeAttribute(t):s.setAttribute(t,!0===e?"":e)})))}))},effect:function(t){var e=t.state,i={popper:{position:e.options.strategy,left:"0",top:"0",margin:"0"},arrow:{position:"absolute"},reference:{}};return Object.assign(e.elements.popper.style,i.popper),e.styles=i,e.elements.arrow&&Object.assign(e.elements.arrow.style,i.arrow),function(){Object.keys(e.elements).forEach((function(t){var n=e.elements[t],s=e.attributes[t]||{},o=Object.keys(e.styles.hasOwnProperty(t)?e.styles[t]:i[t]).reduce((function(t,e){return t[e]="",t}),{});_e(n)&&pe(n)&&(Object.assign(n.style,o),Object.keys(s).forEach((function(t){n.removeAttribute(t)})))}))}},requires:["computeStyles"]};function ye(t){return t.split("-")[0]}var we=Math.max,Ae=Math.min,Ee=Math.round;function Te(){var t=navigator.userAgentData;return null!=t&&t.brands&&Array.isArray(t.brands)?t.brands.map((function(t){return t.brand+"/"+t.version})).join(" "):navigator.userAgent}function Ce(){return!/^((?!chrome|android).)*safari/i.test(Te())}function Oe(t,e,i){void 0===e&&(e=!1),void 0===i&&(i=!1);var n=t.getBoundingClientRect(),s=1,o=1;e&&_e(t)&&(s=t.offsetWidth>0&&Ee(n.width)/t.offsetWidth||1,o=t.offsetHeight>0&&Ee(n.height)/t.offsetHeight||1);var r=(ge(t)?me(t):window).visualViewport,a=!Ce()&&i,l=(n.left+(a&&r?r.offsetLeft:0))/s,c=(n.top+(a&&r?r.offsetTop:0))/o,h=n.width/s,d=n.height/o;return{width:h,height:d,top:c,right:l+h,bottom:c+d,left:l,x:l,y:c}}function xe(t){var e=Oe(t),i=t.offsetWidth,n=t.offsetHeight;return Math.abs(e.width-i)<=1&&(i=e.width),Math.abs(e.height-n)<=1&&(n=e.height),{x:t.offsetLeft,y:t.offsetTop,width:i,height:n}}function ke(t,e){var i=e.getRootNode&&e.getRootNode();if(t.contains(e))return!0;if(i&&be(i)){var n=e;do{if(n&&t.isSameNode(n))return!0;n=n.parentNode||n.host}while(n)}return!1}function Le(t){return me(t).getComputedStyle(t)}function Se(t){return["table","td","th"].indexOf(pe(t))>=0}function De(t){return((ge(t)?t.ownerDocument:t.document)||window.document).documentElement}function $e(t){return"html"===pe(t)?t:t.assignedSlot||t.parentNode||(be(t)?t.host:null)||De(t)}function Ie(t){return _e(t)&&"fixed"!==Le(t).position?t.offsetParent:null}function Ne(t){for(var e=me(t),i=Ie(t);i&&Se(i)&&"static"===Le(i).position;)i=Ie(i);return i&&("html"===pe(i)||"body"===pe(i)&&"static"===Le(i).position)?e:i||function(t){var e=/firefox/i.test(Te());if(/Trident/i.test(Te())&&_e(t)&&"fixed"===Le(t).position)return null;var i=$e(t);for(be(i)&&(i=i.host);_e(i)&&["html","body"].indexOf(pe(i))<0;){var n=Le(i);if("none"!==n.transform||"none"!==n.perspective||"paint"===n.contain||-1!==["transform","perspective"].indexOf(n.willChange)||e&&"filter"===n.willChange||e&&n.filter&&"none"!==n.filter)return i;i=i.parentNode}return null}(t)||e}function Pe(t){return["top","bottom"].indexOf(t)>=0?"x":"y"}function je(t,e,i){return we(t,Ae(e,i))}function Me(t){return Object.assign({},{top:0,right:0,bottom:0,left:0},t)}function Fe(t,e){return e.reduce((function(e,i){return e[i]=t,e}),{})}const He={name:"arrow",enabled:!0,phase:"main",fn:function(t){var e,i=t.state,n=t.name,s=t.options,o=i.elements.arrow,r=i.modifiersData.popperOffsets,a=ye(i.placement),l=Pe(a),c=[Qt,Kt].indexOf(a)>=0?"height":"width";if(o&&r){var h=function(t,e){return Me("number"!=typeof(t="function"==typeof t?t(Object.assign({},e.rects,{placement:e.placement})):t)?t:Fe(t,Yt))}(s.padding,i),d=xe(o),u="y"===l?qt:Qt,f="y"===l?Vt:Kt,p=i.rects.reference[c]+i.rects.reference[l]-r[l]-i.rects.popper[c],m=r[l]-i.rects.reference[l],g=Ne(o),_=g?"y"===l?g.clientHeight||0:g.clientWidth||0:0,b=p/2-m/2,v=h[u],y=_-d[c]-h[f],w=_/2-d[c]/2+b,A=je(v,w,y),E=l;i.modifiersData[n]=((e={})[E]=A,e.centerOffset=A-w,e)}},effect:function(t){var e=t.state,i=t.options.element,n=void 0===i?"[data-popper-arrow]":i;null!=n&&("string"!=typeof n||(n=e.elements.popper.querySelector(n)))&&ke(e.elements.popper,n)&&(e.elements.arrow=n)},requires:["popperOffsets"],requiresIfExists:["preventOverflow"]};function We(t){return t.split("-")[1]}var Be={top:"auto",right:"auto",bottom:"auto",left:"auto"};function ze(t){var e,i=t.popper,n=t.popperRect,s=t.placement,o=t.variation,r=t.offsets,a=t.position,l=t.gpuAcceleration,c=t.adaptive,h=t.roundOffsets,d=t.isFixed,u=r.x,f=void 0===u?0:u,p=r.y,m=void 0===p?0:p,g="function"==typeof h?h({x:f,y:m}):{x:f,y:m};f=g.x,m=g.y;var _=r.hasOwnProperty("x"),b=r.hasOwnProperty("y"),v=Qt,y=qt,w=window;if(c){var A=Ne(i),E="clientHeight",T="clientWidth";A===me(i)&&"static"!==Le(A=De(i)).position&&"absolute"===a&&(E="scrollHeight",T="scrollWidth"),(s===qt||(s===Qt||s===Kt)&&o===Gt)&&(y=Vt,m-=(d&&A===w&&w.visualViewport?w.visualViewport.height:A[E])-n.height,m*=l?1:-1),s!==Qt&&(s!==qt&&s!==Vt||o!==Gt)||(v=Kt,f-=(d&&A===w&&w.visualViewport?w.visualViewport.width:A[T])-n.width,f*=l?1:-1)}var C,O=Object.assign({position:a},c&&Be),x=!0===h?function(t,e){var i=t.x,n=t.y,s=e.devicePixelRatio||1;return{x:Ee(i*s)/s||0,y:Ee(n*s)/s||0}}({x:f,y:m},me(i)):{x:f,y:m};return f=x.x,m=x.y,l?Object.assign({},O,((C={})[y]=b?"0":"",C[v]=_?"0":"",C.transform=(w.devicePixelRatio||1)<=1?"translate("+f+"px, "+m+"px)":"translate3d("+f+"px, "+m+"px, 0)",C)):Object.assign({},O,((e={})[y]=b?m+"px":"",e[v]=_?f+"px":"",e.transform="",e))}const Re={name:"computeStyles",enabled:!0,phase:"beforeWrite",fn:function(t){var e=t.state,i=t.options,n=i.gpuAcceleration,s=void 0===n||n,o=i.adaptive,r=void 0===o||o,a=i.roundOffsets,l=void 0===a||a,c={placement:ye(e.placement),variation:We(e.placement),popper:e.elements.popper,popperRect:e.rects.popper,gpuAcceleration:s,isFixed:"fixed"===e.options.strategy};null!=e.modifiersData.popperOffsets&&(e.styles.popper=Object.assign({},e.styles.popper,ze(Object.assign({},c,{offsets:e.modifiersData.popperOffsets,position:e.options.strategy,adaptive:r,roundOffsets:l})))),null!=e.modifiersData.arrow&&(e.styles.arrow=Object.assign({},e.styles.arrow,ze(Object.assign({},c,{offsets:e.modifiersData.arrow,position:"absolute",adaptive:!1,roundOffsets:l})))),e.attributes.popper=Object.assign({},e.attributes.popper,{"data-popper-placement":e.placement})},data:{}};var qe={passive:!0};const Ve={name:"eventListeners",enabled:!0,phase:"write",fn:function(){},effect:function(t){var e=t.state,i=t.instance,n=t.options,s=n.scroll,o=void 0===s||s,r=n.resize,a=void 0===r||r,l=me(e.elements.popper),c=[].concat(e.scrollParents.reference,e.scrollParents.popper);return o&&c.forEach((function(t){t.addEventListener("scroll",i.update,qe)})),a&&l.addEventListener("resize",i.update,qe),function(){o&&c.forEach((function(t){t.removeEventListener("scroll",i.update,qe)})),a&&l.removeEventListener("resize",i.update,qe)}},data:{}};var Ke={left:"right",right:"left",bottom:"top",top:"bottom"};function Qe(t){return t.replace(/left|right|bottom|top/g,(function(t){return Ke[t]}))}var Xe={start:"end",end:"start"};function Ye(t){return t.replace(/start|end/g,(function(t){return Xe[t]}))}function Ue(t){var e=me(t);return{scrollLeft:e.pageXOffset,scrollTop:e.pageYOffset}}function Ge(t){return Oe(De(t)).left+Ue(t).scrollLeft}function Je(t){var e=Le(t),i=e.overflow,n=e.overflowX,s=e.overflowY;return/auto|scroll|overlay|hidden/.test(i+s+n)}function Ze(t){return["html","body","#document"].indexOf(pe(t))>=0?t.ownerDocument.body:_e(t)&&Je(t)?t:Ze($e(t))}function ti(t,e){var i;void 0===e&&(e=[]);var n=Ze(t),s=n===(null==(i=t.ownerDocument)?void 0:i.body),o=me(n),r=s?[o].concat(o.visualViewport||[],Je(n)?n:[]):n,a=e.concat(r);return s?a:a.concat(ti($e(r)))}function ei(t){return Object.assign({},t,{left:t.x,top:t.y,right:t.x+t.width,bottom:t.y+t.height})}function ii(t,e,i){return e===Zt?ei(function(t,e){var i=me(t),n=De(t),s=i.visualViewport,o=n.clientWidth,r=n.clientHeight,a=0,l=0;if(s){o=s.width,r=s.height;var c=Ce();(c||!c&&"fixed"===e)&&(a=s.offsetLeft,l=s.offsetTop)}return{width:o,height:r,x:a+Ge(t),y:l}}(t,i)):ge(e)?function(t,e){var i=Oe(t,!1,"fixed"===e);return i.top=i.top+t.clientTop,i.left=i.left+t.clientLeft,i.bottom=i.top+t.clientHeight,i.right=i.left+t.clientWidth,i.width=t.clientWidth,i.height=t.clientHeight,i.x=i.left,i.y=i.top,i}(e,i):ei(function(t){var e,i=De(t),n=Ue(t),s=null==(e=t.ownerDocument)?void 0:e.body,o=we(i.scrollWidth,i.clientWidth,s?s.scrollWidth:0,s?s.clientWidth:0),r=we(i.scrollHeight,i.clientHeight,s?s.scrollHeight:0,s?s.clientHeight:0),a=-n.scrollLeft+Ge(t),l=-n.scrollTop;return"rtl"===Le(s||i).direction&&(a+=we(i.clientWidth,s?s.clientWidth:0)-o),{width:o,height:r,x:a,y:l}}(De(t)))}function ni(t){var e,i=t.reference,n=t.element,s=t.placement,o=s?ye(s):null,r=s?We(s):null,a=i.x+i.width/2-n.width/2,l=i.y+i.height/2-n.height/2;switch(o){case qt:e={x:a,y:i.y-n.height};break;case Vt:e={x:a,y:i.y+i.height};break;case Kt:e={x:i.x+i.width,y:l};break;case Qt:e={x:i.x-n.width,y:l};break;default:e={x:i.x,y:i.y}}var c=o?Pe(o):null;if(null!=c){var h="y"===c?"height":"width";switch(r){case Ut:e[c]=e[c]-(i[h]/2-n[h]/2);break;case Gt:e[c]=e[c]+(i[h]/2-n[h]/2)}}return e}function si(t,e){void 0===e&&(e={});var i=e,n=i.placement,s=void 0===n?t.placement:n,o=i.strategy,r=void 0===o?t.strategy:o,a=i.boundary,l=void 0===a?Jt:a,c=i.rootBoundary,h=void 0===c?Zt:c,d=i.elementContext,u=void 0===d?te:d,f=i.altBoundary,p=void 0!==f&&f,m=i.padding,g=void 0===m?0:m,_=Me("number"!=typeof g?g:Fe(g,Yt)),b=u===te?ee:te,v=t.rects.popper,y=t.elements[p?b:u],w=function(t,e,i,n){var s="clippingParents"===e?function(t){var e=ti($e(t)),i=["absolute","fixed"].indexOf(Le(t).position)>=0&&_e(t)?Ne(t):t;return ge(i)?e.filter((function(t){return ge(t)&&ke(t,i)&&"body"!==pe(t)})):[]}(t):[].concat(e),o=[].concat(s,[i]),r=o[0],a=o.reduce((function(e,i){var s=ii(t,i,n);return e.top=we(s.top,e.top),e.right=Ae(s.right,e.right),e.bottom=Ae(s.bottom,e.bottom),e.left=we(s.left,e.left),e}),ii(t,r,n));return a.width=a.right-a.left,a.height=a.bottom-a.top,a.x=a.left,a.y=a.top,a}(ge(y)?y:y.contextElement||De(t.elements.popper),l,h,r),A=Oe(t.elements.reference),E=ni({reference:A,element:v,placement:s}),T=ei(Object.assign({},v,E)),C=u===te?T:A,O={top:w.top-C.top+_.top,bottom:C.bottom-w.bottom+_.bottom,left:w.left-C.left+_.left,right:C.right-w.right+_.right},x=t.modifiersData.offset;if(u===te&&x){var k=x[s];Object.keys(O).forEach((function(t){var e=[Kt,Vt].indexOf(t)>=0?1:-1,i=[qt,Vt].indexOf(t)>=0?"y":"x";O[t]+=k[i]*e}))}return O}function oi(t,e){void 0===e&&(e={});var i=e,n=i.placement,s=i.boundary,o=i.rootBoundary,r=i.padding,a=i.flipVariations,l=i.allowedAutoPlacements,c=void 0===l?ne:l,h=We(n),d=h?a?ie:ie.filter((function(t){return We(t)===h})):Yt,u=d.filter((function(t){return c.indexOf(t)>=0}));0===u.length&&(u=d);var f=u.reduce((function(e,i){return e[i]=si(t,{placement:i,boundary:s,rootBoundary:o,padding:r})[ye(i)],e}),{});return Object.keys(f).sort((function(t,e){return f[t]-f[e]}))}const ri={name:"flip",enabled:!0,phase:"main",fn:function(t){var e=t.state,i=t.options,n=t.name;if(!e.modifiersData[n]._skip){for(var s=i.mainAxis,o=void 0===s||s,r=i.altAxis,a=void 0===r||r,l=i.fallbackPlacements,c=i.padding,h=i.boundary,d=i.rootBoundary,u=i.altBoundary,f=i.flipVariations,p=void 0===f||f,m=i.allowedAutoPlacements,g=e.options.placement,_=ye(g),b=l||(_!==g&&p?function(t){if(ye(t)===Xt)return[];var e=Qe(t);return[Ye(t),e,Ye(e)]}(g):[Qe(g)]),v=[g].concat(b).reduce((function(t,i){return t.concat(ye(i)===Xt?oi(e,{placement:i,boundary:h,rootBoundary:d,padding:c,flipVariations:p,allowedAutoPlacements:m}):i)}),[]),y=e.rects.reference,w=e.rects.popper,A=new Map,E=!0,T=v[0],C=0;C=0,S=L?"width":"height",D=si(e,{placement:O,boundary:h,rootBoundary:d,altBoundary:u,padding:c}),$=L?k?Kt:Qt:k?Vt:qt;y[S]>w[S]&&($=Qe($));var I=Qe($),N=[];if(o&&N.push(D[x]<=0),a&&N.push(D[$]<=0,D[I]<=0),N.every((function(t){return t}))){T=O,E=!1;break}A.set(O,N)}if(E)for(var P=function(t){var e=v.find((function(e){var i=A.get(e);if(i)return i.slice(0,t).every((function(t){return t}))}));if(e)return T=e,"break"},j=p?3:1;j>0&&"break"!==P(j);j--);e.placement!==T&&(e.modifiersData[n]._skip=!0,e.placement=T,e.reset=!0)}},requiresIfExists:["offset"],data:{_skip:!1}};function ai(t,e,i){return void 0===i&&(i={x:0,y:0}),{top:t.top-e.height-i.y,right:t.right-e.width+i.x,bottom:t.bottom-e.height+i.y,left:t.left-e.width-i.x}}function li(t){return[qt,Kt,Vt,Qt].some((function(e){return t[e]>=0}))}const ci={name:"hide",enabled:!0,phase:"main",requiresIfExists:["preventOverflow"],fn:function(t){var e=t.state,i=t.name,n=e.rects.reference,s=e.rects.popper,o=e.modifiersData.preventOverflow,r=si(e,{elementContext:"reference"}),a=si(e,{altBoundary:!0}),l=ai(r,n),c=ai(a,s,o),h=li(l),d=li(c);e.modifiersData[i]={referenceClippingOffsets:l,popperEscapeOffsets:c,isReferenceHidden:h,hasPopperEscaped:d},e.attributes.popper=Object.assign({},e.attributes.popper,{"data-popper-reference-hidden":h,"data-popper-escaped":d})}},hi={name:"offset",enabled:!0,phase:"main",requires:["popperOffsets"],fn:function(t){var e=t.state,i=t.options,n=t.name,s=i.offset,o=void 0===s?[0,0]:s,r=ne.reduce((function(t,i){return t[i]=function(t,e,i){var n=ye(t),s=[Qt,qt].indexOf(n)>=0?-1:1,o="function"==typeof i?i(Object.assign({},e,{placement:t})):i,r=o[0],a=o[1];return r=r||0,a=(a||0)*s,[Qt,Kt].indexOf(n)>=0?{x:a,y:r}:{x:r,y:a}}(i,e.rects,o),t}),{}),a=r[e.placement],l=a.x,c=a.y;null!=e.modifiersData.popperOffsets&&(e.modifiersData.popperOffsets.x+=l,e.modifiersData.popperOffsets.y+=c),e.modifiersData[n]=r}},di={name:"popperOffsets",enabled:!0,phase:"read",fn:function(t){var e=t.state,i=t.name;e.modifiersData[i]=ni({reference:e.rects.reference,element:e.rects.popper,placement:e.placement})},data:{}},ui={name:"preventOverflow",enabled:!0,phase:"main",fn:function(t){var e=t.state,i=t.options,n=t.name,s=i.mainAxis,o=void 0===s||s,r=i.altAxis,a=void 0!==r&&r,l=i.boundary,c=i.rootBoundary,h=i.altBoundary,d=i.padding,u=i.tether,f=void 0===u||u,p=i.tetherOffset,m=void 0===p?0:p,g=si(e,{boundary:l,rootBoundary:c,padding:d,altBoundary:h}),_=ye(e.placement),b=We(e.placement),v=!b,y=Pe(_),w="x"===y?"y":"x",A=e.modifiersData.popperOffsets,E=e.rects.reference,T=e.rects.popper,C="function"==typeof m?m(Object.assign({},e.rects,{placement:e.placement})):m,O="number"==typeof C?{mainAxis:C,altAxis:C}:Object.assign({mainAxis:0,altAxis:0},C),x=e.modifiersData.offset?e.modifiersData.offset[e.placement]:null,k={x:0,y:0};if(A){if(o){var L,S="y"===y?qt:Qt,D="y"===y?Vt:Kt,$="y"===y?"height":"width",I=A[y],N=I+g[S],P=I-g[D],j=f?-T[$]/2:0,M=b===Ut?E[$]:T[$],F=b===Ut?-T[$]:-E[$],H=e.elements.arrow,W=f&&H?xe(H):{width:0,height:0},B=e.modifiersData["arrow#persistent"]?e.modifiersData["arrow#persistent"].padding:{top:0,right:0,bottom:0,left:0},z=B[S],R=B[D],q=je(0,E[$],W[$]),V=v?E[$]/2-j-q-z-O.mainAxis:M-q-z-O.mainAxis,K=v?-E[$]/2+j+q+R+O.mainAxis:F+q+R+O.mainAxis,Q=e.elements.arrow&&Ne(e.elements.arrow),X=Q?"y"===y?Q.clientTop||0:Q.clientLeft||0:0,Y=null!=(L=null==x?void 0:x[y])?L:0,U=I+K-Y,G=je(f?Ae(N,I+V-Y-X):N,I,f?we(P,U):P);A[y]=G,k[y]=G-I}if(a){var J,Z="x"===y?qt:Qt,tt="x"===y?Vt:Kt,et=A[w],it="y"===w?"height":"width",nt=et+g[Z],st=et-g[tt],ot=-1!==[qt,Qt].indexOf(_),rt=null!=(J=null==x?void 0:x[w])?J:0,at=ot?nt:et-E[it]-T[it]-rt+O.altAxis,lt=ot?et+E[it]+T[it]-rt-O.altAxis:st,ct=f&&ot?function(t,e,i){var n=je(t,e,i);return n>i?i:n}(at,et,lt):je(f?at:nt,et,f?lt:st);A[w]=ct,k[w]=ct-et}e.modifiersData[n]=k}},requiresIfExists:["offset"]};function fi(t,e,i){void 0===i&&(i=!1);var n,s,o=_e(e),r=_e(e)&&function(t){var e=t.getBoundingClientRect(),i=Ee(e.width)/t.offsetWidth||1,n=Ee(e.height)/t.offsetHeight||1;return 1!==i||1!==n}(e),a=De(e),l=Oe(t,r,i),c={scrollLeft:0,scrollTop:0},h={x:0,y:0};return(o||!o&&!i)&&(("body"!==pe(e)||Je(a))&&(c=(n=e)!==me(n)&&_e(n)?{scrollLeft:(s=n).scrollLeft,scrollTop:s.scrollTop}:Ue(n)),_e(e)?((h=Oe(e,!0)).x+=e.clientLeft,h.y+=e.clientTop):a&&(h.x=Ge(a))),{x:l.left+c.scrollLeft-h.x,y:l.top+c.scrollTop-h.y,width:l.width,height:l.height}}function pi(t){var e=new Map,i=new Set,n=[];function s(t){i.add(t.name),[].concat(t.requires||[],t.requiresIfExists||[]).forEach((function(t){if(!i.has(t)){var n=e.get(t);n&&s(n)}})),n.push(t)}return t.forEach((function(t){e.set(t.name,t)})),t.forEach((function(t){i.has(t.name)||s(t)})),n}var mi={placement:"bottom",modifiers:[],strategy:"absolute"};function gi(){for(var t=arguments.length,e=new Array(t),i=0;iNumber.parseInt(t,10))):"function"==typeof t?e=>t(e,this._element):t}_getPopperConfig(){const t={placement:this._getPlacement(),modifiers:[{name:"preventOverflow",options:{boundary:this._config.boundary}},{name:"offset",options:{offset:this._getOffset()}}]};return(this._inNavbar||"static"===this._config.display)&&(F.setDataAttribute(this._menu,"popper","static"),t.modifiers=[{name:"applyStyles",enabled:!1}]),{...t,...g(this._config.popperConfig,[void 0,t])}}_selectMenuItem({key:t,target:e}){const i=z.find(".dropdown-menu .dropdown-item:not(.disabled):not(:disabled)",this._menu).filter((t=>a(t)));i.length&&b(i,e,t===Oi,!i.includes(e)).focus()}static jQueryInterface(t){return this.each((function(){const e=Ki.getOrCreateInstance(this,t);if("string"==typeof t){if(void 0===e[t])throw new TypeError(`No method named "${t}"`);e[t]()}}))}static clearMenus(t){if(2===t.button||"keyup"===t.type&&"Tab"!==t.key)return;const e=z.find(ji);for(const i of e){const e=Ki.getInstance(i);if(!e||!1===e._config.autoClose)continue;const n=t.composedPath(),s=n.includes(e._menu);if(n.includes(e._element)||"inside"===e._config.autoClose&&!s||"outside"===e._config.autoClose&&s)continue;if(e._menu.contains(t.target)&&("keyup"===t.type&&"Tab"===t.key||/input|select|option|textarea|form/i.test(t.target.tagName)))continue;const o={relatedTarget:e._element};"click"===t.type&&(o.clickEvent=t),e._completeHide(o)}}static dataApiKeydownHandler(t){const e=/input|textarea/i.test(t.target.tagName),i="Escape"===t.key,n=[Ci,Oi].includes(t.key);if(!n&&!i)return;if(e&&!i)return;t.preventDefault();const s=this.matches(Pi)?this:z.prev(this,Pi)[0]||z.next(this,Pi)[0]||z.findOne(Pi,t.delegateTarget.parentNode),o=Ki.getOrCreateInstance(s);if(n)return t.stopPropagation(),o.show(),void o._selectMenuItem(t);o._isShown()&&(t.stopPropagation(),o.hide(),s.focus())}}N.on(document,$i,Pi,Ki.dataApiKeydownHandler),N.on(document,$i,Mi,Ki.dataApiKeydownHandler),N.on(document,Di,Ki.clearMenus),N.on(document,Ii,Ki.clearMenus),N.on(document,Di,Pi,(function(t){t.preventDefault(),Ki.getOrCreateInstance(this).toggle()})),m(Ki);const Qi="backdrop",Xi="show",Yi=`mousedown.bs.${Qi}`,Ui={className:"modal-backdrop",clickCallback:null,isAnimated:!1,isVisible:!0,rootElement:"body"},Gi={className:"string",clickCallback:"(function|null)",isAnimated:"boolean",isVisible:"boolean",rootElement:"(element|string)"};class Ji extends H{constructor(t){super(),this._config=this._getConfig(t),this._isAppended=!1,this._element=null}static get Default(){return Ui}static get DefaultType(){return Gi}static get NAME(){return Qi}show(t){if(!this._config.isVisible)return void g(t);this._append();const e=this._getElement();this._config.isAnimated&&d(e),e.classList.add(Xi),this._emulateAnimation((()=>{g(t)}))}hide(t){this._config.isVisible?(this._getElement().classList.remove(Xi),this._emulateAnimation((()=>{this.dispose(),g(t)}))):g(t)}dispose(){this._isAppended&&(N.off(this._element,Yi),this._element.remove(),this._isAppended=!1)}_getElement(){if(!this._element){const t=document.createElement("div");t.className=this._config.className,this._config.isAnimated&&t.classList.add("fade"),this._element=t}return this._element}_configAfterMerge(t){return t.rootElement=r(t.rootElement),t}_append(){if(this._isAppended)return;const t=this._getElement();this._config.rootElement.append(t),N.on(t,Yi,(()=>{g(this._config.clickCallback)})),this._isAppended=!0}_emulateAnimation(t){_(t,this._getElement(),this._config.isAnimated)}}const Zi=".bs.focustrap",tn=`focusin${Zi}`,en=`keydown.tab${Zi}`,nn="backward",sn={autofocus:!0,trapElement:null},on={autofocus:"boolean",trapElement:"element"};class rn extends H{constructor(t){super(),this._config=this._getConfig(t),this._isActive=!1,this._lastTabNavDirection=null}static get Default(){return sn}static get DefaultType(){return on}static get NAME(){return"focustrap"}activate(){this._isActive||(this._config.autofocus&&this._config.trapElement.focus(),N.off(document,Zi),N.on(document,tn,(t=>this._handleFocusin(t))),N.on(document,en,(t=>this._handleKeydown(t))),this._isActive=!0)}deactivate(){this._isActive&&(this._isActive=!1,N.off(document,Zi))}_handleFocusin(t){const{trapElement:e}=this._config;if(t.target===document||t.target===e||e.contains(t.target))return;const i=z.focusableChildren(e);0===i.length?e.focus():this._lastTabNavDirection===nn?i[i.length-1].focus():i[0].focus()}_handleKeydown(t){"Tab"===t.key&&(this._lastTabNavDirection=t.shiftKey?nn:"forward")}}const an=".fixed-top, .fixed-bottom, .is-fixed, .sticky-top",ln=".sticky-top",cn="padding-right",hn="margin-right";class dn{constructor(){this._element=document.body}getWidth(){const t=document.documentElement.clientWidth;return Math.abs(window.innerWidth-t)}hide(){const t=this.getWidth();this._disableOverFlow(),this._setElementAttributes(this._element,cn,(e=>e+t)),this._setElementAttributes(an,cn,(e=>e+t)),this._setElementAttributes(ln,hn,(e=>e-t))}reset(){this._resetElementAttributes(this._element,"overflow"),this._resetElementAttributes(this._element,cn),this._resetElementAttributes(an,cn),this._resetElementAttributes(ln,hn)}isOverflowing(){return this.getWidth()>0}_disableOverFlow(){this._saveInitialAttribute(this._element,"overflow"),this._element.style.overflow="hidden"}_setElementAttributes(t,e,i){const n=this.getWidth();this._applyManipulationCallback(t,(t=>{if(t!==this._element&&window.innerWidth>t.clientWidth+n)return;this._saveInitialAttribute(t,e);const s=window.getComputedStyle(t).getPropertyValue(e);t.style.setProperty(e,`${i(Number.parseFloat(s))}px`)}))}_saveInitialAttribute(t,e){const i=t.style.getPropertyValue(e);i&&F.setDataAttribute(t,e,i)}_resetElementAttributes(t,e){this._applyManipulationCallback(t,(t=>{const i=F.getDataAttribute(t,e);null!==i?(F.removeDataAttribute(t,e),t.style.setProperty(e,i)):t.style.removeProperty(e)}))}_applyManipulationCallback(t,e){if(o(t))e(t);else for(const i of z.find(t,this._element))e(i)}}const un=".bs.modal",fn=`hide${un}`,pn=`hidePrevented${un}`,mn=`hidden${un}`,gn=`show${un}`,_n=`shown${un}`,bn=`resize${un}`,vn=`click.dismiss${un}`,yn=`mousedown.dismiss${un}`,wn=`keydown.dismiss${un}`,An=`click${un}.data-api`,En="modal-open",Tn="show",Cn="modal-static",On={backdrop:!0,focus:!0,keyboard:!0},xn={backdrop:"(boolean|string)",focus:"boolean",keyboard:"boolean"};class kn extends W{constructor(t,e){super(t,e),this._dialog=z.findOne(".modal-dialog",this._element),this._backdrop=this._initializeBackDrop(),this._focustrap=this._initializeFocusTrap(),this._isShown=!1,this._isTransitioning=!1,this._scrollBar=new dn,this._addEventListeners()}static get Default(){return On}static get DefaultType(){return xn}static get NAME(){return"modal"}toggle(t){return this._isShown?this.hide():this.show(t)}show(t){this._isShown||this._isTransitioning||N.trigger(this._element,gn,{relatedTarget:t}).defaultPrevented||(this._isShown=!0,this._isTransitioning=!0,this._scrollBar.hide(),document.body.classList.add(En),this._adjustDialog(),this._backdrop.show((()=>this._showElement(t))))}hide(){this._isShown&&!this._isTransitioning&&(N.trigger(this._element,fn).defaultPrevented||(this._isShown=!1,this._isTransitioning=!0,this._focustrap.deactivate(),this._element.classList.remove(Tn),this._queueCallback((()=>this._hideModal()),this._element,this._isAnimated())))}dispose(){N.off(window,un),N.off(this._dialog,un),this._backdrop.dispose(),this._focustrap.deactivate(),super.dispose()}handleUpdate(){this._adjustDialog()}_initializeBackDrop(){return new Ji({isVisible:Boolean(this._config.backdrop),isAnimated:this._isAnimated()})}_initializeFocusTrap(){return new rn({trapElement:this._element})}_showElement(t){document.body.contains(this._element)||document.body.append(this._element),this._element.style.display="block",this._element.removeAttribute("aria-hidden"),this._element.setAttribute("aria-modal",!0),this._element.setAttribute("role","dialog"),this._element.scrollTop=0;const e=z.findOne(".modal-body",this._dialog);e&&(e.scrollTop=0),d(this._element),this._element.classList.add(Tn),this._queueCallback((()=>{this._config.focus&&this._focustrap.activate(),this._isTransitioning=!1,N.trigger(this._element,_n,{relatedTarget:t})}),this._dialog,this._isAnimated())}_addEventListeners(){N.on(this._element,wn,(t=>{"Escape"===t.key&&(this._config.keyboard?this.hide():this._triggerBackdropTransition())})),N.on(window,bn,(()=>{this._isShown&&!this._isTransitioning&&this._adjustDialog()})),N.on(this._element,yn,(t=>{N.one(this._element,vn,(e=>{this._element===t.target&&this._element===e.target&&("static"!==this._config.backdrop?this._config.backdrop&&this.hide():this._triggerBackdropTransition())}))}))}_hideModal(){this._element.style.display="none",this._element.setAttribute("aria-hidden",!0),this._element.removeAttribute("aria-modal"),this._element.removeAttribute("role"),this._isTransitioning=!1,this._backdrop.hide((()=>{document.body.classList.remove(En),this._resetAdjustments(),this._scrollBar.reset(),N.trigger(this._element,mn)}))}_isAnimated(){return this._element.classList.contains("fade")}_triggerBackdropTransition(){if(N.trigger(this._element,pn).defaultPrevented)return;const t=this._element.scrollHeight>document.documentElement.clientHeight,e=this._element.style.overflowY;"hidden"===e||this._element.classList.contains(Cn)||(t||(this._element.style.overflowY="hidden"),this._element.classList.add(Cn),this._queueCallback((()=>{this._element.classList.remove(Cn),this._queueCallback((()=>{this._element.style.overflowY=e}),this._dialog)}),this._dialog),this._element.focus())}_adjustDialog(){const t=this._element.scrollHeight>document.documentElement.clientHeight,e=this._scrollBar.getWidth(),i=e>0;if(i&&!t){const t=p()?"paddingLeft":"paddingRight";this._element.style[t]=`${e}px`}if(!i&&t){const t=p()?"paddingRight":"paddingLeft";this._element.style[t]=`${e}px`}}_resetAdjustments(){this._element.style.paddingLeft="",this._element.style.paddingRight=""}static jQueryInterface(t,e){return this.each((function(){const i=kn.getOrCreateInstance(this,t);if("string"==typeof t){if(void 0===i[t])throw new TypeError(`No method named "${t}"`);i[t](e)}}))}}N.on(document,An,'[data-bs-toggle="modal"]',(function(t){const e=z.getElementFromSelector(this);["A","AREA"].includes(this.tagName)&&t.preventDefault(),N.one(e,gn,(t=>{t.defaultPrevented||N.one(e,mn,(()=>{a(this)&&this.focus()}))}));const i=z.findOne(".modal.show");i&&kn.getInstance(i).hide(),kn.getOrCreateInstance(e).toggle(this)})),R(kn),m(kn);const Ln=".bs.offcanvas",Sn=".data-api",Dn=`load${Ln}${Sn}`,$n="show",In="showing",Nn="hiding",Pn=".offcanvas.show",jn=`show${Ln}`,Mn=`shown${Ln}`,Fn=`hide${Ln}`,Hn=`hidePrevented${Ln}`,Wn=`hidden${Ln}`,Bn=`resize${Ln}`,zn=`click${Ln}${Sn}`,Rn=`keydown.dismiss${Ln}`,qn={backdrop:!0,keyboard:!0,scroll:!1},Vn={backdrop:"(boolean|string)",keyboard:"boolean",scroll:"boolean"};class Kn extends W{constructor(t,e){super(t,e),this._isShown=!1,this._backdrop=this._initializeBackDrop(),this._focustrap=this._initializeFocusTrap(),this._addEventListeners()}static get Default(){return qn}static get DefaultType(){return Vn}static get NAME(){return"offcanvas"}toggle(t){return this._isShown?this.hide():this.show(t)}show(t){this._isShown||N.trigger(this._element,jn,{relatedTarget:t}).defaultPrevented||(this._isShown=!0,this._backdrop.show(),this._config.scroll||(new dn).hide(),this._element.setAttribute("aria-modal",!0),this._element.setAttribute("role","dialog"),this._element.classList.add(In),this._queueCallback((()=>{this._config.scroll&&!this._config.backdrop||this._focustrap.activate(),this._element.classList.add($n),this._element.classList.remove(In),N.trigger(this._element,Mn,{relatedTarget:t})}),this._element,!0))}hide(){this._isShown&&(N.trigger(this._element,Fn).defaultPrevented||(this._focustrap.deactivate(),this._element.blur(),this._isShown=!1,this._element.classList.add(Nn),this._backdrop.hide(),this._queueCallback((()=>{this._element.classList.remove($n,Nn),this._element.removeAttribute("aria-modal"),this._element.removeAttribute("role"),this._config.scroll||(new dn).reset(),N.trigger(this._element,Wn)}),this._element,!0)))}dispose(){this._backdrop.dispose(),this._focustrap.deactivate(),super.dispose()}_initializeBackDrop(){const t=Boolean(this._config.backdrop);return new Ji({className:"offcanvas-backdrop",isVisible:t,isAnimated:!0,rootElement:this._element.parentNode,clickCallback:t?()=>{"static"!==this._config.backdrop?this.hide():N.trigger(this._element,Hn)}:null})}_initializeFocusTrap(){return new rn({trapElement:this._element})}_addEventListeners(){N.on(this._element,Rn,(t=>{"Escape"===t.key&&(this._config.keyboard?this.hide():N.trigger(this._element,Hn))}))}static jQueryInterface(t){return this.each((function(){const e=Kn.getOrCreateInstance(this,t);if("string"==typeof t){if(void 0===e[t]||t.startsWith("_")||"constructor"===t)throw new TypeError(`No method named "${t}"`);e[t](this)}}))}}N.on(document,zn,'[data-bs-toggle="offcanvas"]',(function(t){const e=z.getElementFromSelector(this);if(["A","AREA"].includes(this.tagName)&&t.preventDefault(),l(this))return;N.one(e,Wn,(()=>{a(this)&&this.focus()}));const i=z.findOne(Pn);i&&i!==e&&Kn.getInstance(i).hide(),Kn.getOrCreateInstance(e).toggle(this)})),N.on(window,Dn,(()=>{for(const t of z.find(Pn))Kn.getOrCreateInstance(t).show()})),N.on(window,Bn,(()=>{for(const t of z.find("[aria-modal][class*=show][class*=offcanvas-]"))"fixed"!==getComputedStyle(t).position&&Kn.getOrCreateInstance(t).hide()})),R(Kn),m(Kn);const Qn={"*":["class","dir","id","lang","role",/^aria-[\w-]*$/i],a:["target","href","title","rel"],area:[],b:[],br:[],col:[],code:[],dd:[],div:[],dl:[],dt:[],em:[],hr:[],h1:[],h2:[],h3:[],h4:[],h5:[],h6:[],i:[],img:["src","srcset","alt","title","width","height"],li:[],ol:[],p:[],pre:[],s:[],small:[],span:[],sub:[],sup:[],strong:[],u:[],ul:[]},Xn=new Set(["background","cite","href","itemtype","longdesc","poster","src","xlink:href"]),Yn=/^(?!javascript:)(?:[a-z0-9+.-]+:|[^&:/?#]*(?:[/?#]|$))/i,Un=(t,e)=>{const i=t.nodeName.toLowerCase();return e.includes(i)?!Xn.has(i)||Boolean(Yn.test(t.nodeValue)):e.filter((t=>t instanceof RegExp)).some((t=>t.test(i)))},Gn={allowList:Qn,content:{},extraClass:"",html:!1,sanitize:!0,sanitizeFn:null,template:"
"},Jn={allowList:"object",content:"object",extraClass:"(string|function)",html:"boolean",sanitize:"boolean",sanitizeFn:"(null|function)",template:"string"},Zn={entry:"(string|element|function|null)",selector:"(string|element)"};class ts extends H{constructor(t){super(),this._config=this._getConfig(t)}static get Default(){return Gn}static get DefaultType(){return Jn}static get NAME(){return"TemplateFactory"}getContent(){return Object.values(this._config.content).map((t=>this._resolvePossibleFunction(t))).filter(Boolean)}hasContent(){return this.getContent().length>0}changeContent(t){return this._checkContent(t),this._config.content={...this._config.content,...t},this}toHtml(){const t=document.createElement("div");t.innerHTML=this._maybeSanitize(this._config.template);for(const[e,i]of Object.entries(this._config.content))this._setContent(t,i,e);const e=t.children[0],i=this._resolvePossibleFunction(this._config.extraClass);return i&&e.classList.add(...i.split(" ")),e}_typeCheckConfig(t){super._typeCheckConfig(t),this._checkContent(t.content)}_checkContent(t){for(const[e,i]of Object.entries(t))super._typeCheckConfig({selector:e,entry:i},Zn)}_setContent(t,e,i){const n=z.findOne(i,t);n&&((e=this._resolvePossibleFunction(e))?o(e)?this._putElementInTemplate(r(e),n):this._config.html?n.innerHTML=this._maybeSanitize(e):n.textContent=e:n.remove())}_maybeSanitize(t){return this._config.sanitize?function(t,e,i){if(!t.length)return t;if(i&&"function"==typeof i)return i(t);const n=(new window.DOMParser).parseFromString(t,"text/html"),s=[].concat(...n.body.querySelectorAll("*"));for(const t of s){const i=t.nodeName.toLowerCase();if(!Object.keys(e).includes(i)){t.remove();continue}const n=[].concat(...t.attributes),s=[].concat(e["*"]||[],e[i]||[]);for(const e of n)Un(e,s)||t.removeAttribute(e.nodeName)}return n.body.innerHTML}(t,this._config.allowList,this._config.sanitizeFn):t}_resolvePossibleFunction(t){return g(t,[void 0,this])}_putElementInTemplate(t,e){if(this._config.html)return e.innerHTML="",void e.append(t);e.textContent=t.textContent}}const es=new Set(["sanitize","allowList","sanitizeFn"]),is="fade",ns="show",ss=".tooltip-inner",os=".modal",rs="hide.bs.modal",as="hover",ls="focus",cs={AUTO:"auto",TOP:"top",RIGHT:p()?"left":"right",BOTTOM:"bottom",LEFT:p()?"right":"left"},hs={allowList:Qn,animation:!0,boundary:"clippingParents",container:!1,customClass:"",delay:0,fallbackPlacements:["top","right","bottom","left"],html:!1,offset:[0,6],placement:"top",popperConfig:null,sanitize:!0,sanitizeFn:null,selector:!1,template:'',title:"",trigger:"hover focus"},ds={allowList:"object",animation:"boolean",boundary:"(string|element)",container:"(string|element|boolean)",customClass:"(string|function)",delay:"(number|object)",fallbackPlacements:"array",html:"boolean",offset:"(array|string|function)",placement:"(string|function)",popperConfig:"(null|object|function)",sanitize:"boolean",sanitizeFn:"(null|function)",selector:"(string|boolean)",template:"string",title:"(string|element|function)",trigger:"string"};class us extends W{constructor(t,e){if(void 0===wi)throw new TypeError("Bootstrap's tooltips require Popper (https://popper.js.org/docs/v2/)");super(t,e),this._isEnabled=!0,this._timeout=0,this._isHovered=null,this._activeTrigger={},this._popper=null,this._templateFactory=null,this._newContent=null,this.tip=null,this._setListeners(),this._config.selector||this._fixTitle()}static get Default(){return hs}static get DefaultType(){return ds}static get NAME(){return"tooltip"}enable(){this._isEnabled=!0}disable(){this._isEnabled=!1}toggleEnabled(){this._isEnabled=!this._isEnabled}toggle(){this._isEnabled&&(this._isShown()?this._leave():this._enter())}dispose(){clearTimeout(this._timeout),N.off(this._element.closest(os),rs,this._hideModalHandler),this._element.getAttribute("data-bs-original-title")&&this._element.setAttribute("title",this._element.getAttribute("data-bs-original-title")),this._disposePopper(),super.dispose()}show(){if("none"===this._element.style.display)throw new Error("Please use show on visible elements");if(!this._isWithContent()||!this._isEnabled)return;const t=N.trigger(this._element,this.constructor.eventName("show")),e=(c(this._element)||this._element.ownerDocument.documentElement).contains(this._element);if(t.defaultPrevented||!e)return;this._disposePopper();const i=this._getTipElement();this._element.setAttribute("aria-describedby",i.getAttribute("id"));const{container:n}=this._config;if(this._element.ownerDocument.documentElement.contains(this.tip)||(n.append(i),N.trigger(this._element,this.constructor.eventName("inserted"))),this._popper=this._createPopper(i),i.classList.add(ns),"ontouchstart"in document.documentElement)for(const t of[].concat(...document.body.children))N.on(t,"mouseover",h);this._queueCallback((()=>{N.trigger(this._element,this.constructor.eventName("shown")),!1===this._isHovered&&this._leave(),this._isHovered=!1}),this.tip,this._isAnimated())}hide(){if(this._isShown()&&!N.trigger(this._element,this.constructor.eventName("hide")).defaultPrevented){if(this._getTipElement().classList.remove(ns),"ontouchstart"in document.documentElement)for(const t of[].concat(...document.body.children))N.off(t,"mouseover",h);this._activeTrigger.click=!1,this._activeTrigger[ls]=!1,this._activeTrigger[as]=!1,this._isHovered=null,this._queueCallback((()=>{this._isWithActiveTrigger()||(this._isHovered||this._disposePopper(),this._element.removeAttribute("aria-describedby"),N.trigger(this._element,this.constructor.eventName("hidden")))}),this.tip,this._isAnimated())}}update(){this._popper&&this._popper.update()}_isWithContent(){return Boolean(this._getTitle())}_getTipElement(){return this.tip||(this.tip=this._createTipElement(this._newContent||this._getContentForTemplate())),this.tip}_createTipElement(t){const e=this._getTemplateFactory(t).toHtml();if(!e)return null;e.classList.remove(is,ns),e.classList.add(`bs-${this.constructor.NAME}-auto`);const i=(t=>{do{t+=Math.floor(1e6*Math.random())}while(document.getElementById(t));return t})(this.constructor.NAME).toString();return e.setAttribute("id",i),this._isAnimated()&&e.classList.add(is),e}setContent(t){this._newContent=t,this._isShown()&&(this._disposePopper(),this.show())}_getTemplateFactory(t){return this._templateFactory?this._templateFactory.changeContent(t):this._templateFactory=new ts({...this._config,content:t,extraClass:this._resolvePossibleFunction(this._config.customClass)}),this._templateFactory}_getContentForTemplate(){return{[ss]:this._getTitle()}}_getTitle(){return this._resolvePossibleFunction(this._config.title)||this._element.getAttribute("data-bs-original-title")}_initializeOnDelegatedTarget(t){return this.constructor.getOrCreateInstance(t.delegateTarget,this._getDelegateConfig())}_isAnimated(){return this._config.animation||this.tip&&this.tip.classList.contains(is)}_isShown(){return this.tip&&this.tip.classList.contains(ns)}_createPopper(t){const e=g(this._config.placement,[this,t,this._element]),i=cs[e.toUpperCase()];return yi(this._element,t,this._getPopperConfig(i))}_getOffset(){const{offset:t}=this._config;return"string"==typeof t?t.split(",").map((t=>Number.parseInt(t,10))):"function"==typeof t?e=>t(e,this._element):t}_resolvePossibleFunction(t){return g(t,[this._element,this._element])}_getPopperConfig(t){const e={placement:t,modifiers:[{name:"flip",options:{fallbackPlacements:this._config.fallbackPlacements}},{name:"offset",options:{offset:this._getOffset()}},{name:"preventOverflow",options:{boundary:this._config.boundary}},{name:"arrow",options:{element:`.${this.constructor.NAME}-arrow`}},{name:"preSetPlacement",enabled:!0,phase:"beforeMain",fn:t=>{this._getTipElement().setAttribute("data-popper-placement",t.state.placement)}}]};return{...e,...g(this._config.popperConfig,[void 0,e])}}_setListeners(){const t=this._config.trigger.split(" ");for(const e of t)if("click"===e)N.on(this._element,this.constructor.eventName("click"),this._config.selector,(t=>{this._initializeOnDelegatedTarget(t).toggle()}));else if("manual"!==e){const t=e===as?this.constructor.eventName("mouseenter"):this.constructor.eventName("focusin"),i=e===as?this.constructor.eventName("mouseleave"):this.constructor.eventName("focusout");N.on(this._element,t,this._config.selector,(t=>{const e=this._initializeOnDelegatedTarget(t);e._activeTrigger["focusin"===t.type?ls:as]=!0,e._enter()})),N.on(this._element,i,this._config.selector,(t=>{const e=this._initializeOnDelegatedTarget(t);e._activeTrigger["focusout"===t.type?ls:as]=e._element.contains(t.relatedTarget),e._leave()}))}this._hideModalHandler=()=>{this._element&&this.hide()},N.on(this._element.closest(os),rs,this._hideModalHandler)}_fixTitle(){const t=this._element.getAttribute("title");t&&(this._element.getAttribute("aria-label")||this._element.textContent.trim()||this._element.setAttribute("aria-label",t),this._element.setAttribute("data-bs-original-title",t),this._element.removeAttribute("title"))}_enter(){this._isShown()||this._isHovered?this._isHovered=!0:(this._isHovered=!0,this._setTimeout((()=>{this._isHovered&&this.show()}),this._config.delay.show))}_leave(){this._isWithActiveTrigger()||(this._isHovered=!1,this._setTimeout((()=>{this._isHovered||this.hide()}),this._config.delay.hide))}_setTimeout(t,e){clearTimeout(this._timeout),this._timeout=setTimeout(t,e)}_isWithActiveTrigger(){return Object.values(this._activeTrigger).includes(!0)}_getConfig(t){const e=F.getDataAttributes(this._element);for(const t of Object.keys(e))es.has(t)&&delete e[t];return t={...e,..."object"==typeof t&&t?t:{}},t=this._mergeConfigObj(t),t=this._configAfterMerge(t),this._typeCheckConfig(t),t}_configAfterMerge(t){return t.container=!1===t.container?document.body:r(t.container),"number"==typeof t.delay&&(t.delay={show:t.delay,hide:t.delay}),"number"==typeof t.title&&(t.title=t.title.toString()),"number"==typeof t.content&&(t.content=t.content.toString()),t}_getDelegateConfig(){const t={};for(const[e,i]of Object.entries(this._config))this.constructor.Default[e]!==i&&(t[e]=i);return t.selector=!1,t.trigger="manual",t}_disposePopper(){this._popper&&(this._popper.destroy(),this._popper=null),this.tip&&(this.tip.remove(),this.tip=null)}static jQueryInterface(t){return this.each((function(){const e=us.getOrCreateInstance(this,t);if("string"==typeof t){if(void 0===e[t])throw new TypeError(`No method named "${t}"`);e[t]()}}))}}m(us);const fs=".popover-header",ps=".popover-body",ms={...us.Default,content:"",offset:[0,8],placement:"right",template:'',trigger:"click"},gs={...us.DefaultType,content:"(null|string|element|function)"};class _s extends us{static get Default(){return ms}static get DefaultType(){return gs}static get NAME(){return"popover"}_isWithContent(){return this._getTitle()||this._getContent()}_getContentForTemplate(){return{[fs]:this._getTitle(),[ps]:this._getContent()}}_getContent(){return this._resolvePossibleFunction(this._config.content)}static jQueryInterface(t){return this.each((function(){const e=_s.getOrCreateInstance(this,t);if("string"==typeof t){if(void 0===e[t])throw new TypeError(`No method named "${t}"`);e[t]()}}))}}m(_s);const bs=".bs.scrollspy",vs=`activate${bs}`,ys=`click${bs}`,ws=`load${bs}.data-api`,As="active",Es="[href]",Ts=".nav-link",Cs=`${Ts}, .nav-item > ${Ts}, .list-group-item`,Os={offset:null,rootMargin:"0px 0px -25%",smoothScroll:!1,target:null,threshold:[.1,.5,1]},xs={offset:"(number|null)",rootMargin:"string",smoothScroll:"boolean",target:"element",threshold:"array"};class ks extends W{constructor(t,e){super(t,e),this._targetLinks=new Map,this._observableSections=new Map,this._rootElement="visible"===getComputedStyle(this._element).overflowY?null:this._element,this._activeTarget=null,this._observer=null,this._previousScrollData={visibleEntryTop:0,parentScrollTop:0},this.refresh()}static get Default(){return Os}static get DefaultType(){return xs}static get NAME(){return"scrollspy"}refresh(){this._initializeTargetsAndObservables(),this._maybeEnableSmoothScroll(),this._observer?this._observer.disconnect():this._observer=this._getNewObserver();for(const t of this._observableSections.values())this._observer.observe(t)}dispose(){this._observer.disconnect(),super.dispose()}_configAfterMerge(t){return t.target=r(t.target)||document.body,t.rootMargin=t.offset?`${t.offset}px 0px -30%`:t.rootMargin,"string"==typeof t.threshold&&(t.threshold=t.threshold.split(",").map((t=>Number.parseFloat(t)))),t}_maybeEnableSmoothScroll(){this._config.smoothScroll&&(N.off(this._config.target,ys),N.on(this._config.target,ys,Es,(t=>{const e=this._observableSections.get(t.target.hash);if(e){t.preventDefault();const i=this._rootElement||window,n=e.offsetTop-this._element.offsetTop;if(i.scrollTo)return void i.scrollTo({top:n,behavior:"smooth"});i.scrollTop=n}})))}_getNewObserver(){const t={root:this._rootElement,threshold:this._config.threshold,rootMargin:this._config.rootMargin};return new IntersectionObserver((t=>this._observerCallback(t)),t)}_observerCallback(t){const e=t=>this._targetLinks.get(`#${t.target.id}`),i=t=>{this._previousScrollData.visibleEntryTop=t.target.offsetTop,this._process(e(t))},n=(this._rootElement||document.documentElement).scrollTop,s=n>=this._previousScrollData.parentScrollTop;this._previousScrollData.parentScrollTop=n;for(const o of t){if(!o.isIntersecting){this._activeTarget=null,this._clearActiveClass(e(o));continue}const t=o.target.offsetTop>=this._previousScrollData.visibleEntryTop;if(s&&t){if(i(o),!n)return}else s||t||i(o)}}_initializeTargetsAndObservables(){this._targetLinks=new Map,this._observableSections=new Map;const t=z.find(Es,this._config.target);for(const e of t){if(!e.hash||l(e))continue;const t=z.findOne(decodeURI(e.hash),this._element);a(t)&&(this._targetLinks.set(decodeURI(e.hash),e),this._observableSections.set(e.hash,t))}}_process(t){this._activeTarget!==t&&(this._clearActiveClass(this._config.target),this._activeTarget=t,t.classList.add(As),this._activateParents(t),N.trigger(this._element,vs,{relatedTarget:t}))}_activateParents(t){if(t.classList.contains("dropdown-item"))z.findOne(".dropdown-toggle",t.closest(".dropdown")).classList.add(As);else for(const e of z.parents(t,".nav, .list-group"))for(const t of z.prev(e,Cs))t.classList.add(As)}_clearActiveClass(t){t.classList.remove(As);const e=z.find(`${Es}.${As}`,t);for(const t of e)t.classList.remove(As)}static jQueryInterface(t){return this.each((function(){const e=ks.getOrCreateInstance(this,t);if("string"==typeof t){if(void 0===e[t]||t.startsWith("_")||"constructor"===t)throw new TypeError(`No method named "${t}"`);e[t]()}}))}}N.on(window,ws,(()=>{for(const t of z.find('[data-bs-spy="scroll"]'))ks.getOrCreateInstance(t)})),m(ks);const Ls=".bs.tab",Ss=`hide${Ls}`,Ds=`hidden${Ls}`,$s=`show${Ls}`,Is=`shown${Ls}`,Ns=`click${Ls}`,Ps=`keydown${Ls}`,js=`load${Ls}`,Ms="ArrowLeft",Fs="ArrowRight",Hs="ArrowUp",Ws="ArrowDown",Bs="Home",zs="End",Rs="active",qs="fade",Vs="show",Ks=".dropdown-toggle",Qs=`:not(${Ks})`,Xs='[data-bs-toggle="tab"], [data-bs-toggle="pill"], [data-bs-toggle="list"]',Ys=`.nav-link${Qs}, .list-group-item${Qs}, [role="tab"]${Qs}, ${Xs}`,Us=`.${Rs}[data-bs-toggle="tab"], .${Rs}[data-bs-toggle="pill"], .${Rs}[data-bs-toggle="list"]`;class Gs extends W{constructor(t){super(t),this._parent=this._element.closest('.list-group, .nav, [role="tablist"]'),this._parent&&(this._setInitialAttributes(this._parent,this._getChildren()),N.on(this._element,Ps,(t=>this._keydown(t))))}static get NAME(){return"tab"}show(){const t=this._element;if(this._elemIsActive(t))return;const e=this._getActiveElem(),i=e?N.trigger(e,Ss,{relatedTarget:t}):null;N.trigger(t,$s,{relatedTarget:e}).defaultPrevented||i&&i.defaultPrevented||(this._deactivate(e,t),this._activate(t,e))}_activate(t,e){t&&(t.classList.add(Rs),this._activate(z.getElementFromSelector(t)),this._queueCallback((()=>{"tab"===t.getAttribute("role")?(t.removeAttribute("tabindex"),t.setAttribute("aria-selected",!0),this._toggleDropDown(t,!0),N.trigger(t,Is,{relatedTarget:e})):t.classList.add(Vs)}),t,t.classList.contains(qs)))}_deactivate(t,e){t&&(t.classList.remove(Rs),t.blur(),this._deactivate(z.getElementFromSelector(t)),this._queueCallback((()=>{"tab"===t.getAttribute("role")?(t.setAttribute("aria-selected",!1),t.setAttribute("tabindex","-1"),this._toggleDropDown(t,!1),N.trigger(t,Ds,{relatedTarget:e})):t.classList.remove(Vs)}),t,t.classList.contains(qs)))}_keydown(t){if(![Ms,Fs,Hs,Ws,Bs,zs].includes(t.key))return;t.stopPropagation(),t.preventDefault();const e=this._getChildren().filter((t=>!l(t)));let i;if([Bs,zs].includes(t.key))i=e[t.key===Bs?0:e.length-1];else{const n=[Fs,Ws].includes(t.key);i=b(e,t.target,n,!0)}i&&(i.focus({preventScroll:!0}),Gs.getOrCreateInstance(i).show())}_getChildren(){return z.find(Ys,this._parent)}_getActiveElem(){return this._getChildren().find((t=>this._elemIsActive(t)))||null}_setInitialAttributes(t,e){this._setAttributeIfNotExists(t,"role","tablist");for(const t of e)this._setInitialAttributesOnChild(t)}_setInitialAttributesOnChild(t){t=this._getInnerElement(t);const e=this._elemIsActive(t),i=this._getOuterElement(t);t.setAttribute("aria-selected",e),i!==t&&this._setAttributeIfNotExists(i,"role","presentation"),e||t.setAttribute("tabindex","-1"),this._setAttributeIfNotExists(t,"role","tab"),this._setInitialAttributesOnTargetPanel(t)}_setInitialAttributesOnTargetPanel(t){const e=z.getElementFromSelector(t);e&&(this._setAttributeIfNotExists(e,"role","tabpanel"),t.id&&this._setAttributeIfNotExists(e,"aria-labelledby",`${t.id}`))}_toggleDropDown(t,e){const i=this._getOuterElement(t);if(!i.classList.contains("dropdown"))return;const n=(t,n)=>{const s=z.findOne(t,i);s&&s.classList.toggle(n,e)};n(Ks,Rs),n(".dropdown-menu",Vs),i.setAttribute("aria-expanded",e)}_setAttributeIfNotExists(t,e,i){t.hasAttribute(e)||t.setAttribute(e,i)}_elemIsActive(t){return t.classList.contains(Rs)}_getInnerElement(t){return t.matches(Ys)?t:z.findOne(Ys,t)}_getOuterElement(t){return t.closest(".nav-item, .list-group-item")||t}static jQueryInterface(t){return this.each((function(){const e=Gs.getOrCreateInstance(this);if("string"==typeof t){if(void 0===e[t]||t.startsWith("_")||"constructor"===t)throw new TypeError(`No method named "${t}"`);e[t]()}}))}}N.on(document,Ns,Xs,(function(t){["A","AREA"].includes(this.tagName)&&t.preventDefault(),l(this)||Gs.getOrCreateInstance(this).show()})),N.on(window,js,(()=>{for(const t of z.find(Us))Gs.getOrCreateInstance(t)})),m(Gs);const Js=".bs.toast",Zs=`mouseover${Js}`,to=`mouseout${Js}`,eo=`focusin${Js}`,io=`focusout${Js}`,no=`hide${Js}`,so=`hidden${Js}`,oo=`show${Js}`,ro=`shown${Js}`,ao="hide",lo="show",co="showing",ho={animation:"boolean",autohide:"boolean",delay:"number"},uo={animation:!0,autohide:!0,delay:5e3};class fo extends W{constructor(t,e){super(t,e),this._timeout=null,this._hasMouseInteraction=!1,this._hasKeyboardInteraction=!1,this._setListeners()}static get Default(){return uo}static get DefaultType(){return ho}static get NAME(){return"toast"}show(){N.trigger(this._element,oo).defaultPrevented||(this._clearTimeout(),this._config.animation&&this._element.classList.add("fade"),this._element.classList.remove(ao),d(this._element),this._element.classList.add(lo,co),this._queueCallback((()=>{this._element.classList.remove(co),N.trigger(this._element,ro),this._maybeScheduleHide()}),this._element,this._config.animation))}hide(){this.isShown()&&(N.trigger(this._element,no).defaultPrevented||(this._element.classList.add(co),this._queueCallback((()=>{this._element.classList.add(ao),this._element.classList.remove(co,lo),N.trigger(this._element,so)}),this._element,this._config.animation)))}dispose(){this._clearTimeout(),this.isShown()&&this._element.classList.remove(lo),super.dispose()}isShown(){return this._element.classList.contains(lo)}_maybeScheduleHide(){this._config.autohide&&(this._hasMouseInteraction||this._hasKeyboardInteraction||(this._timeout=setTimeout((()=>{this.hide()}),this._config.delay)))}_onInteraction(t,e){switch(t.type){case"mouseover":case"mouseout":this._hasMouseInteraction=e;break;case"focusin":case"focusout":this._hasKeyboardInteraction=e}if(e)return void this._clearTimeout();const i=t.relatedTarget;this._element===i||this._element.contains(i)||this._maybeScheduleHide()}_setListeners(){N.on(this._element,Zs,(t=>this._onInteraction(t,!0))),N.on(this._element,to,(t=>this._onInteraction(t,!1))),N.on(this._element,eo,(t=>this._onInteraction(t,!0))),N.on(this._element,io,(t=>this._onInteraction(t,!1)))}_clearTimeout(){clearTimeout(this._timeout),this._timeout=null}static jQueryInterface(t){return this.each((function(){const e=fo.getOrCreateInstance(this,t);if("string"==typeof t){if(void 0===e[t])throw new TypeError(`No method named "${t}"`);e[t](this)}}))}}return R(fo),m(fo),{Alert:Q,Button:Y,Carousel:Lt,Collapse:Rt,Dropdown:Ki,Modal:kn,Offcanvas:Kn,Popover:_s,ScrollSpy:ks,Tab:Gs,Toast:fo,Tooltip:us}})); -//# sourceMappingURL=bootstrap.bundle.min.js.map \ No newline at end of file diff --git a/backend/coverage-report-progress/_js/d3.min.js b/backend/coverage-report-progress/_js/d3.min.js deleted file mode 100644 index 16648730..00000000 --- a/backend/coverage-report-progress/_js/d3.min.js +++ /dev/null @@ -1,5 +0,0 @@ -!function(){function n(n){return n&&(n.ownerDocument||n.document||n).documentElement}function t(n){return n&&(n.ownerDocument&&n.ownerDocument.defaultView||n.document&&n||n.defaultView)}function e(n,t){return t>n?-1:n>t?1:n>=t?0:NaN}function r(n){return null===n?NaN:+n}function i(n){return!isNaN(n)}function u(n){return{left:function(t,e,r,i){for(arguments.length<3&&(r=0),arguments.length<4&&(i=t.length);i>r;){var u=r+i>>>1;n(t[u],e)<0?r=u+1:i=u}return r},right:function(t,e,r,i){for(arguments.length<3&&(r=0),arguments.length<4&&(i=t.length);i>r;){var u=r+i>>>1;n(t[u],e)>0?i=u:r=u+1}return r}}}function o(n){return n.length}function a(n){for(var t=1;n*t%1;)t*=10;return t}function l(n,t){for(var e in t)Object.defineProperty(n.prototype,e,{value:t[e],enumerable:!1})}function c(){this._=Object.create(null)}function f(n){return(n+="")===bo||n[0]===_o?_o+n:n}function s(n){return(n+="")[0]===_o?n.slice(1):n}function h(n){return f(n)in this._}function p(n){return(n=f(n))in this._&&delete this._[n]}function g(){var n=[];for(var t in this._)n.push(s(t));return n}function v(){var n=0;for(var t in this._)++n;return n}function d(){for(var n in this._)return!1;return!0}function y(){this._=Object.create(null)}function m(n){return n}function M(n,t,e){return function(){var r=e.apply(t,arguments);return r===t?n:r}}function x(n,t){if(t in n)return t;t=t.charAt(0).toUpperCase()+t.slice(1);for(var e=0,r=wo.length;r>e;++e){var i=wo[e]+t;if(i in n)return i}}function b(){}function _(){}function w(n){function t(){for(var t,r=e,i=-1,u=r.length;++ie;e++)for(var i,u=n[e],o=0,a=u.length;a>o;o++)(i=u[o])&&t(i,o,e);return n}function Z(n){return ko(n,qo),n}function V(n){var t,e;return function(r,i,u){var o,a=n[u].update,l=a.length;for(u!=e&&(e=u,t=0),i>=t&&(t=i+1);!(o=a[t])&&++t0&&(n=n.slice(0,a));var c=To.get(n);return c&&(n=c,l=B),a?t?i:r:t?b:u}function $(n,t){return function(e){var r=ao.event;ao.event=e,t[0]=this.__data__;try{n.apply(this,t)}finally{ao.event=r}}}function B(n,t){var e=$(n,t);return function(n){var t=this,r=n.relatedTarget;r&&(r===t||8&r.compareDocumentPosition(t))||e.call(t,n)}}function W(e){var r=".dragsuppress-"+ ++Do,i="click"+r,u=ao.select(t(e)).on("touchmove"+r,S).on("dragstart"+r,S).on("selectstart"+r,S);if(null==Ro&&(Ro="onselectstart"in e?!1:x(e.style,"userSelect")),Ro){var o=n(e).style,a=o[Ro];o[Ro]="none"}return function(n){if(u.on(r,null),Ro&&(o[Ro]=a),n){var t=function(){u.on(i,null)};u.on(i,function(){S(),t()},!0),setTimeout(t,0)}}}function J(n,e){e.changedTouches&&(e=e.changedTouches[0]);var r=n.ownerSVGElement||n;if(r.createSVGPoint){var i=r.createSVGPoint();if(0>Po){var u=t(n);if(u.scrollX||u.scrollY){r=ao.select("body").append("svg").style({position:"absolute",top:0,left:0,margin:0,padding:0,border:"none"},"important");var o=r[0][0].getScreenCTM();Po=!(o.f||o.e),r.remove()}}return Po?(i.x=e.pageX,i.y=e.pageY):(i.x=e.clientX,i.y=e.clientY),i=i.matrixTransform(n.getScreenCTM().inverse()),[i.x,i.y]}var a=n.getBoundingClientRect();return[e.clientX-a.left-n.clientLeft,e.clientY-a.top-n.clientTop]}function G(){return ao.event.changedTouches[0].identifier}function K(n){return n>0?1:0>n?-1:0}function Q(n,t,e){return(t[0]-n[0])*(e[1]-n[1])-(t[1]-n[1])*(e[0]-n[0])}function nn(n){return n>1?0:-1>n?Fo:Math.acos(n)}function tn(n){return n>1?Io:-1>n?-Io:Math.asin(n)}function en(n){return((n=Math.exp(n))-1/n)/2}function rn(n){return((n=Math.exp(n))+1/n)/2}function un(n){return((n=Math.exp(2*n))-1)/(n+1)}function on(n){return(n=Math.sin(n/2))*n}function an(){}function ln(n,t,e){return this instanceof ln?(this.h=+n,this.s=+t,void(this.l=+e)):arguments.length<2?n instanceof ln?new ln(n.h,n.s,n.l):_n(""+n,wn,ln):new ln(n,t,e)}function cn(n,t,e){function r(n){return n>360?n-=360:0>n&&(n+=360),60>n?u+(o-u)*n/60:180>n?o:240>n?u+(o-u)*(240-n)/60:u}function i(n){return Math.round(255*r(n))}var u,o;return n=isNaN(n)?0:(n%=360)<0?n+360:n,t=isNaN(t)?0:0>t?0:t>1?1:t,e=0>e?0:e>1?1:e,o=.5>=e?e*(1+t):e+t-e*t,u=2*e-o,new mn(i(n+120),i(n),i(n-120))}function fn(n,t,e){return this instanceof fn?(this.h=+n,this.c=+t,void(this.l=+e)):arguments.length<2?n instanceof fn?new fn(n.h,n.c,n.l):n instanceof hn?gn(n.l,n.a,n.b):gn((n=Sn((n=ao.rgb(n)).r,n.g,n.b)).l,n.a,n.b):new fn(n,t,e)}function sn(n,t,e){return isNaN(n)&&(n=0),isNaN(t)&&(t=0),new hn(e,Math.cos(n*=Yo)*t,Math.sin(n)*t)}function hn(n,t,e){return this instanceof hn?(this.l=+n,this.a=+t,void(this.b=+e)):arguments.length<2?n instanceof hn?new hn(n.l,n.a,n.b):n instanceof fn?sn(n.h,n.c,n.l):Sn((n=mn(n)).r,n.g,n.b):new hn(n,t,e)}function pn(n,t,e){var r=(n+16)/116,i=r+t/500,u=r-e/200;return i=vn(i)*na,r=vn(r)*ta,u=vn(u)*ea,new mn(yn(3.2404542*i-1.5371385*r-.4985314*u),yn(-.969266*i+1.8760108*r+.041556*u),yn(.0556434*i-.2040259*r+1.0572252*u))}function gn(n,t,e){return n>0?new fn(Math.atan2(e,t)*Zo,Math.sqrt(t*t+e*e),n):new fn(NaN,NaN,n)}function vn(n){return n>.206893034?n*n*n:(n-4/29)/7.787037}function dn(n){return n>.008856?Math.pow(n,1/3):7.787037*n+4/29}function yn(n){return Math.round(255*(.00304>=n?12.92*n:1.055*Math.pow(n,1/2.4)-.055))}function mn(n,t,e){return this instanceof mn?(this.r=~~n,this.g=~~t,void(this.b=~~e)):arguments.length<2?n instanceof mn?new mn(n.r,n.g,n.b):_n(""+n,mn,cn):new mn(n,t,e)}function Mn(n){return new mn(n>>16,n>>8&255,255&n)}function xn(n){return Mn(n)+""}function bn(n){return 16>n?"0"+Math.max(0,n).toString(16):Math.min(255,n).toString(16)}function _n(n,t,e){var r,i,u,o=0,a=0,l=0;if(r=/([a-z]+)\((.*)\)/.exec(n=n.toLowerCase()))switch(i=r[2].split(","),r[1]){case"hsl":return e(parseFloat(i[0]),parseFloat(i[1])/100,parseFloat(i[2])/100);case"rgb":return t(Nn(i[0]),Nn(i[1]),Nn(i[2]))}return(u=ua.get(n))?t(u.r,u.g,u.b):(null==n||"#"!==n.charAt(0)||isNaN(u=parseInt(n.slice(1),16))||(4===n.length?(o=(3840&u)>>4,o=o>>4|o,a=240&u,a=a>>4|a,l=15&u,l=l<<4|l):7===n.length&&(o=(16711680&u)>>16,a=(65280&u)>>8,l=255&u)),t(o,a,l))}function wn(n,t,e){var r,i,u=Math.min(n/=255,t/=255,e/=255),o=Math.max(n,t,e),a=o-u,l=(o+u)/2;return a?(i=.5>l?a/(o+u):a/(2-o-u),r=n==o?(t-e)/a+(e>t?6:0):t==o?(e-n)/a+2:(n-t)/a+4,r*=60):(r=NaN,i=l>0&&1>l?0:r),new ln(r,i,l)}function Sn(n,t,e){n=kn(n),t=kn(t),e=kn(e);var r=dn((.4124564*n+.3575761*t+.1804375*e)/na),i=dn((.2126729*n+.7151522*t+.072175*e)/ta),u=dn((.0193339*n+.119192*t+.9503041*e)/ea);return hn(116*i-16,500*(r-i),200*(i-u))}function kn(n){return(n/=255)<=.04045?n/12.92:Math.pow((n+.055)/1.055,2.4)}function Nn(n){var t=parseFloat(n);return"%"===n.charAt(n.length-1)?Math.round(2.55*t):t}function En(n){return"function"==typeof n?n:function(){return n}}function An(n){return function(t,e,r){return 2===arguments.length&&"function"==typeof e&&(r=e,e=null),Cn(t,e,n,r)}}function Cn(n,t,e,r){function i(){var n,t=l.status;if(!t&&Ln(l)||t>=200&&300>t||304===t){try{n=e.call(u,l)}catch(r){return void o.error.call(u,r)}o.load.call(u,n)}else o.error.call(u,l)}var u={},o=ao.dispatch("beforesend","progress","load","error"),a={},l=new XMLHttpRequest,c=null;return!this.XDomainRequest||"withCredentials"in l||!/^(http(s)?:)?\/\//.test(n)||(l=new XDomainRequest),"onload"in l?l.onload=l.onerror=i:l.onreadystatechange=function(){l.readyState>3&&i()},l.onprogress=function(n){var t=ao.event;ao.event=n;try{o.progress.call(u,l)}finally{ao.event=t}},u.header=function(n,t){return n=(n+"").toLowerCase(),arguments.length<2?a[n]:(null==t?delete a[n]:a[n]=t+"",u)},u.mimeType=function(n){return arguments.length?(t=null==n?null:n+"",u):t},u.responseType=function(n){return arguments.length?(c=n,u):c},u.response=function(n){return e=n,u},["get","post"].forEach(function(n){u[n]=function(){return u.send.apply(u,[n].concat(co(arguments)))}}),u.send=function(e,r,i){if(2===arguments.length&&"function"==typeof r&&(i=r,r=null),l.open(e,n,!0),null==t||"accept"in a||(a.accept=t+",*/*"),l.setRequestHeader)for(var f in a)l.setRequestHeader(f,a[f]);return null!=t&&l.overrideMimeType&&l.overrideMimeType(t),null!=c&&(l.responseType=c),null!=i&&u.on("error",i).on("load",function(n){i(null,n)}),o.beforesend.call(u,l),l.send(null==r?null:r),u},u.abort=function(){return l.abort(),u},ao.rebind(u,o,"on"),null==r?u:u.get(zn(r))}function zn(n){return 1===n.length?function(t,e){n(null==t?e:null)}:n}function Ln(n){var t=n.responseType;return t&&"text"!==t?n.response:n.responseText}function qn(n,t,e){var r=arguments.length;2>r&&(t=0),3>r&&(e=Date.now());var i=e+t,u={c:n,t:i,n:null};return aa?aa.n=u:oa=u,aa=u,la||(ca=clearTimeout(ca),la=1,fa(Tn)),u}function Tn(){var n=Rn(),t=Dn()-n;t>24?(isFinite(t)&&(clearTimeout(ca),ca=setTimeout(Tn,t)),la=0):(la=1,fa(Tn))}function Rn(){for(var n=Date.now(),t=oa;t;)n>=t.t&&t.c(n-t.t)&&(t.c=null),t=t.n;return n}function Dn(){for(var n,t=oa,e=1/0;t;)t.c?(t.t8?function(n){return n/e}:function(n){return n*e},symbol:n}}function jn(n){var t=n.decimal,e=n.thousands,r=n.grouping,i=n.currency,u=r&&e?function(n,t){for(var i=n.length,u=[],o=0,a=r[0],l=0;i>0&&a>0&&(l+a+1>t&&(a=Math.max(1,t-l)),u.push(n.substring(i-=a,i+a)),!((l+=a+1)>t));)a=r[o=(o+1)%r.length];return u.reverse().join(e)}:m;return function(n){var e=ha.exec(n),r=e[1]||" ",o=e[2]||">",a=e[3]||"-",l=e[4]||"",c=e[5],f=+e[6],s=e[7],h=e[8],p=e[9],g=1,v="",d="",y=!1,m=!0;switch(h&&(h=+h.substring(1)),(c||"0"===r&&"="===o)&&(c=r="0",o="="),p){case"n":s=!0,p="g";break;case"%":g=100,d="%",p="f";break;case"p":g=100,d="%",p="r";break;case"b":case"o":case"x":case"X":"#"===l&&(v="0"+p.toLowerCase());case"c":m=!1;case"d":y=!0,h=0;break;case"s":g=-1,p="r"}"$"===l&&(v=i[0],d=i[1]),"r"!=p||h||(p="g"),null!=h&&("g"==p?h=Math.max(1,Math.min(21,h)):"e"!=p&&"f"!=p||(h=Math.max(0,Math.min(20,h)))),p=pa.get(p)||Fn;var M=c&&s;return function(n){var e=d;if(y&&n%1)return"";var i=0>n||0===n&&0>1/n?(n=-n,"-"):"-"===a?"":a;if(0>g){var l=ao.formatPrefix(n,h);n=l.scale(n),e=l.symbol+d}else n*=g;n=p(n,h);var x,b,_=n.lastIndexOf(".");if(0>_){var w=m?n.lastIndexOf("e"):-1;0>w?(x=n,b=""):(x=n.substring(0,w),b=n.substring(w))}else x=n.substring(0,_),b=t+n.substring(_+1);!c&&s&&(x=u(x,1/0));var S=v.length+x.length+b.length+(M?0:i.length),k=f>S?new Array(S=f-S+1).join(r):"";return M&&(x=u(k+x,k.length?f-b.length:1/0)),i+=v,n=x+b,("<"===o?i+n+k:">"===o?k+i+n:"^"===o?k.substring(0,S>>=1)+i+n+k.substring(S):i+(M?n:k+n))+e}}}function Fn(n){return n+""}function Hn(){this._=new Date(arguments.length>1?Date.UTC.apply(this,arguments):arguments[0])}function On(n,t,e){function r(t){var e=n(t),r=u(e,1);return r-t>t-e?e:r}function i(e){return t(e=n(new va(e-1)),1),e}function u(n,e){return t(n=new va(+n),e),n}function o(n,r,u){var o=i(n),a=[];if(u>1)for(;r>o;)e(o)%u||a.push(new Date(+o)),t(o,1);else for(;r>o;)a.push(new Date(+o)),t(o,1);return a}function a(n,t,e){try{va=Hn;var r=new Hn;return r._=n,o(r,t,e)}finally{va=Date}}n.floor=n,n.round=r,n.ceil=i,n.offset=u,n.range=o;var l=n.utc=In(n);return l.floor=l,l.round=In(r),l.ceil=In(i),l.offset=In(u),l.range=a,n}function In(n){return function(t,e){try{va=Hn;var r=new Hn;return r._=t,n(r,e)._}finally{va=Date}}}function Yn(n){function t(n){function t(t){for(var e,i,u,o=[],a=-1,l=0;++aa;){if(r>=c)return-1;if(i=t.charCodeAt(a++),37===i){if(o=t.charAt(a++),u=C[o in ya?t.charAt(a++):o],!u||(r=u(n,e,r))<0)return-1}else if(i!=e.charCodeAt(r++))return-1}return r}function r(n,t,e){_.lastIndex=0;var r=_.exec(t.slice(e));return r?(n.w=w.get(r[0].toLowerCase()),e+r[0].length):-1}function i(n,t,e){x.lastIndex=0;var r=x.exec(t.slice(e));return r?(n.w=b.get(r[0].toLowerCase()),e+r[0].length):-1}function u(n,t,e){N.lastIndex=0;var r=N.exec(t.slice(e));return r?(n.m=E.get(r[0].toLowerCase()),e+r[0].length):-1}function o(n,t,e){S.lastIndex=0;var r=S.exec(t.slice(e));return r?(n.m=k.get(r[0].toLowerCase()),e+r[0].length):-1}function a(n,t,r){return e(n,A.c.toString(),t,r)}function l(n,t,r){return e(n,A.x.toString(),t,r)}function c(n,t,r){return e(n,A.X.toString(),t,r)}function f(n,t,e){var r=M.get(t.slice(e,e+=2).toLowerCase());return null==r?-1:(n.p=r,e)}var s=n.dateTime,h=n.date,p=n.time,g=n.periods,v=n.days,d=n.shortDays,y=n.months,m=n.shortMonths;t.utc=function(n){function e(n){try{va=Hn;var t=new va;return t._=n,r(t)}finally{va=Date}}var r=t(n);return e.parse=function(n){try{va=Hn;var t=r.parse(n);return t&&t._}finally{va=Date}},e.toString=r.toString,e},t.multi=t.utc.multi=ct;var M=ao.map(),x=Vn(v),b=Xn(v),_=Vn(d),w=Xn(d),S=Vn(y),k=Xn(y),N=Vn(m),E=Xn(m);g.forEach(function(n,t){M.set(n.toLowerCase(),t)});var A={a:function(n){return d[n.getDay()]},A:function(n){return v[n.getDay()]},b:function(n){return m[n.getMonth()]},B:function(n){return y[n.getMonth()]},c:t(s),d:function(n,t){return Zn(n.getDate(),t,2)},e:function(n,t){return Zn(n.getDate(),t,2)},H:function(n,t){return Zn(n.getHours(),t,2)},I:function(n,t){return Zn(n.getHours()%12||12,t,2)},j:function(n,t){return Zn(1+ga.dayOfYear(n),t,3)},L:function(n,t){return Zn(n.getMilliseconds(),t,3)},m:function(n,t){return Zn(n.getMonth()+1,t,2)},M:function(n,t){return Zn(n.getMinutes(),t,2)},p:function(n){return g[+(n.getHours()>=12)]},S:function(n,t){return Zn(n.getSeconds(),t,2)},U:function(n,t){return Zn(ga.sundayOfYear(n),t,2)},w:function(n){return n.getDay()},W:function(n,t){return Zn(ga.mondayOfYear(n),t,2)},x:t(h),X:t(p),y:function(n,t){return Zn(n.getFullYear()%100,t,2)},Y:function(n,t){return Zn(n.getFullYear()%1e4,t,4)},Z:at,"%":function(){return"%"}},C={a:r,A:i,b:u,B:o,c:a,d:tt,e:tt,H:rt,I:rt,j:et,L:ot,m:nt,M:it,p:f,S:ut,U:Bn,w:$n,W:Wn,x:l,X:c,y:Gn,Y:Jn,Z:Kn,"%":lt};return t}function Zn(n,t,e){var r=0>n?"-":"",i=(r?-n:n)+"",u=i.length;return r+(e>u?new Array(e-u+1).join(t)+i:i)}function Vn(n){return new RegExp("^(?:"+n.map(ao.requote).join("|")+")","i")}function Xn(n){for(var t=new c,e=-1,r=n.length;++e68?1900:2e3)}function nt(n,t,e){ma.lastIndex=0;var r=ma.exec(t.slice(e,e+2));return r?(n.m=r[0]-1,e+r[0].length):-1}function tt(n,t,e){ma.lastIndex=0;var r=ma.exec(t.slice(e,e+2));return r?(n.d=+r[0],e+r[0].length):-1}function et(n,t,e){ma.lastIndex=0;var r=ma.exec(t.slice(e,e+3));return r?(n.j=+r[0],e+r[0].length):-1}function rt(n,t,e){ma.lastIndex=0;var r=ma.exec(t.slice(e,e+2));return r?(n.H=+r[0],e+r[0].length):-1}function it(n,t,e){ma.lastIndex=0;var r=ma.exec(t.slice(e,e+2));return r?(n.M=+r[0],e+r[0].length):-1}function ut(n,t,e){ma.lastIndex=0;var r=ma.exec(t.slice(e,e+2));return r?(n.S=+r[0],e+r[0].length):-1}function ot(n,t,e){ma.lastIndex=0;var r=ma.exec(t.slice(e,e+3));return r?(n.L=+r[0],e+r[0].length):-1}function at(n){var t=n.getTimezoneOffset(),e=t>0?"-":"+",r=xo(t)/60|0,i=xo(t)%60;return e+Zn(r,"0",2)+Zn(i,"0",2)}function lt(n,t,e){Ma.lastIndex=0;var r=Ma.exec(t.slice(e,e+1));return r?e+r[0].length:-1}function ct(n){for(var t=n.length,e=-1;++e=0?1:-1,a=o*e,l=Math.cos(t),c=Math.sin(t),f=u*c,s=i*l+f*Math.cos(a),h=f*o*Math.sin(a);ka.add(Math.atan2(h,s)),r=n,i=l,u=c}var t,e,r,i,u;Na.point=function(o,a){Na.point=n,r=(t=o)*Yo,i=Math.cos(a=(e=a)*Yo/2+Fo/4),u=Math.sin(a)},Na.lineEnd=function(){n(t,e)}}function dt(n){var t=n[0],e=n[1],r=Math.cos(e);return[r*Math.cos(t),r*Math.sin(t),Math.sin(e)]}function yt(n,t){return n[0]*t[0]+n[1]*t[1]+n[2]*t[2]}function mt(n,t){return[n[1]*t[2]-n[2]*t[1],n[2]*t[0]-n[0]*t[2],n[0]*t[1]-n[1]*t[0]]}function Mt(n,t){n[0]+=t[0],n[1]+=t[1],n[2]+=t[2]}function xt(n,t){return[n[0]*t,n[1]*t,n[2]*t]}function bt(n){var t=Math.sqrt(n[0]*n[0]+n[1]*n[1]+n[2]*n[2]);n[0]/=t,n[1]/=t,n[2]/=t}function _t(n){return[Math.atan2(n[1],n[0]),tn(n[2])]}function wt(n,t){return xo(n[0]-t[0])a;++a)i.point((e=n[a])[0],e[1]);return void i.lineEnd()}var l=new Tt(e,n,null,!0),c=new Tt(e,null,l,!1);l.o=c,u.push(l),o.push(c),l=new Tt(r,n,null,!1),c=new Tt(r,null,l,!0),l.o=c,u.push(l),o.push(c)}}),o.sort(t),qt(u),qt(o),u.length){for(var a=0,l=e,c=o.length;c>a;++a)o[a].e=l=!l;for(var f,s,h=u[0];;){for(var p=h,g=!0;p.v;)if((p=p.n)===h)return;f=p.z,i.lineStart();do{if(p.v=p.o.v=!0,p.e){if(g)for(var a=0,c=f.length;c>a;++a)i.point((s=f[a])[0],s[1]);else r(p.x,p.n.x,1,i);p=p.n}else{if(g){f=p.p.z;for(var a=f.length-1;a>=0;--a)i.point((s=f[a])[0],s[1])}else r(p.x,p.p.x,-1,i);p=p.p}p=p.o,f=p.z,g=!g}while(!p.v);i.lineEnd()}}}function qt(n){if(t=n.length){for(var t,e,r=0,i=n[0];++r0){for(b||(u.polygonStart(),b=!0),u.lineStart();++o1&&2&t&&e.push(e.pop().concat(e.shift())),p.push(e.filter(Dt))}var p,g,v,d=t(u),y=i.invert(r[0],r[1]),m={point:o,lineStart:l,lineEnd:c,polygonStart:function(){m.point=f,m.lineStart=s,m.lineEnd=h,p=[],g=[]},polygonEnd:function(){m.point=o,m.lineStart=l,m.lineEnd=c,p=ao.merge(p);var n=Ot(y,g);p.length?(b||(u.polygonStart(),b=!0),Lt(p,Ut,n,e,u)):n&&(b||(u.polygonStart(),b=!0),u.lineStart(),e(null,null,1,u),u.lineEnd()),b&&(u.polygonEnd(),b=!1),p=g=null},sphere:function(){u.polygonStart(),u.lineStart(),e(null,null,1,u),u.lineEnd(),u.polygonEnd()}},M=Pt(),x=t(M),b=!1;return m}}function Dt(n){return n.length>1}function Pt(){var n,t=[];return{lineStart:function(){t.push(n=[])},point:function(t,e){n.push([t,e])},lineEnd:b,buffer:function(){var e=t;return t=[],n=null,e},rejoin:function(){t.length>1&&t.push(t.pop().concat(t.shift()))}}}function Ut(n,t){return((n=n.x)[0]<0?n[1]-Io-Uo:Io-n[1])-((t=t.x)[0]<0?t[1]-Io-Uo:Io-t[1])}function jt(n){var t,e=NaN,r=NaN,i=NaN;return{lineStart:function(){n.lineStart(),t=1},point:function(u,o){var a=u>0?Fo:-Fo,l=xo(u-e);xo(l-Fo)0?Io:-Io),n.point(i,r),n.lineEnd(),n.lineStart(),n.point(a,r),n.point(u,r),t=0):i!==a&&l>=Fo&&(xo(e-i)Uo?Math.atan((Math.sin(t)*(u=Math.cos(r))*Math.sin(e)-Math.sin(r)*(i=Math.cos(t))*Math.sin(n))/(i*u*o)):(t+r)/2}function Ht(n,t,e,r){var i;if(null==n)i=e*Io,r.point(-Fo,i),r.point(0,i),r.point(Fo,i),r.point(Fo,0),r.point(Fo,-i),r.point(0,-i),r.point(-Fo,-i),r.point(-Fo,0),r.point(-Fo,i);else if(xo(n[0]-t[0])>Uo){var u=n[0]a;++a){var c=t[a],f=c.length;if(f)for(var s=c[0],h=s[0],p=s[1]/2+Fo/4,g=Math.sin(p),v=Math.cos(p),d=1;;){d===f&&(d=0),n=c[d];var y=n[0],m=n[1]/2+Fo/4,M=Math.sin(m),x=Math.cos(m),b=y-h,_=b>=0?1:-1,w=_*b,S=w>Fo,k=g*M;if(ka.add(Math.atan2(k*_*Math.sin(w),v*x+k*Math.cos(w))),u+=S?b+_*Ho:b,S^h>=e^y>=e){var N=mt(dt(s),dt(n));bt(N);var E=mt(i,N);bt(E);var A=(S^b>=0?-1:1)*tn(E[2]);(r>A||r===A&&(N[0]||N[1]))&&(o+=S^b>=0?1:-1)}if(!d++)break;h=y,g=M,v=x,s=n}}return(-Uo>u||Uo>u&&-Uo>ka)^1&o}function It(n){function t(n,t){return Math.cos(n)*Math.cos(t)>u}function e(n){var e,u,l,c,f;return{lineStart:function(){c=l=!1,f=1},point:function(s,h){var p,g=[s,h],v=t(s,h),d=o?v?0:i(s,h):v?i(s+(0>s?Fo:-Fo),h):0;if(!e&&(c=l=v)&&n.lineStart(),v!==l&&(p=r(e,g),(wt(e,p)||wt(g,p))&&(g[0]+=Uo,g[1]+=Uo,v=t(g[0],g[1]))),v!==l)f=0,v?(n.lineStart(),p=r(g,e),n.point(p[0],p[1])):(p=r(e,g),n.point(p[0],p[1]),n.lineEnd()),e=p;else if(a&&e&&o^v){var y;d&u||!(y=r(g,e,!0))||(f=0,o?(n.lineStart(),n.point(y[0][0],y[0][1]),n.point(y[1][0],y[1][1]),n.lineEnd()):(n.point(y[1][0],y[1][1]),n.lineEnd(),n.lineStart(),n.point(y[0][0],y[0][1])))}!v||e&&wt(e,g)||n.point(g[0],g[1]),e=g,l=v,u=d},lineEnd:function(){l&&n.lineEnd(),e=null},clean:function(){return f|(c&&l)<<1}}}function r(n,t,e){var r=dt(n),i=dt(t),o=[1,0,0],a=mt(r,i),l=yt(a,a),c=a[0],f=l-c*c;if(!f)return!e&&n;var s=u*l/f,h=-u*c/f,p=mt(o,a),g=xt(o,s),v=xt(a,h);Mt(g,v);var d=p,y=yt(g,d),m=yt(d,d),M=y*y-m*(yt(g,g)-1);if(!(0>M)){var x=Math.sqrt(M),b=xt(d,(-y-x)/m);if(Mt(b,g),b=_t(b),!e)return b;var _,w=n[0],S=t[0],k=n[1],N=t[1];w>S&&(_=w,w=S,S=_);var E=S-w,A=xo(E-Fo)E;if(!A&&k>N&&(_=k,k=N,N=_),C?A?k+N>0^b[1]<(xo(b[0]-w)Fo^(w<=b[0]&&b[0]<=S)){var z=xt(d,(-y+x)/m);return Mt(z,g),[b,_t(z)]}}}function i(t,e){var r=o?n:Fo-n,i=0;return-r>t?i|=1:t>r&&(i|=2),-r>e?i|=4:e>r&&(i|=8),i}var u=Math.cos(n),o=u>0,a=xo(u)>Uo,l=ve(n,6*Yo);return Rt(t,e,l,o?[0,-n]:[-Fo,n-Fo])}function Yt(n,t,e,r){return function(i){var u,o=i.a,a=i.b,l=o.x,c=o.y,f=a.x,s=a.y,h=0,p=1,g=f-l,v=s-c;if(u=n-l,g||!(u>0)){if(u/=g,0>g){if(h>u)return;p>u&&(p=u)}else if(g>0){if(u>p)return;u>h&&(h=u)}if(u=e-l,g||!(0>u)){if(u/=g,0>g){if(u>p)return;u>h&&(h=u)}else if(g>0){if(h>u)return;p>u&&(p=u)}if(u=t-c,v||!(u>0)){if(u/=v,0>v){if(h>u)return;p>u&&(p=u)}else if(v>0){if(u>p)return;u>h&&(h=u)}if(u=r-c,v||!(0>u)){if(u/=v,0>v){if(u>p)return;u>h&&(h=u)}else if(v>0){if(h>u)return;p>u&&(p=u)}return h>0&&(i.a={x:l+h*g,y:c+h*v}),1>p&&(i.b={x:l+p*g,y:c+p*v}),i}}}}}}function Zt(n,t,e,r){function i(r,i){return xo(r[0]-n)0?0:3:xo(r[0]-e)0?2:1:xo(r[1]-t)0?1:0:i>0?3:2}function u(n,t){return o(n.x,t.x)}function o(n,t){var e=i(n,1),r=i(t,1);return e!==r?e-r:0===e?t[1]-n[1]:1===e?n[0]-t[0]:2===e?n[1]-t[1]:t[0]-n[0]}return function(a){function l(n){for(var t=0,e=d.length,r=n[1],i=0;e>i;++i)for(var u,o=1,a=d[i],l=a.length,c=a[0];l>o;++o)u=a[o],c[1]<=r?u[1]>r&&Q(c,u,n)>0&&++t:u[1]<=r&&Q(c,u,n)<0&&--t,c=u;return 0!==t}function c(u,a,l,c){var f=0,s=0;if(null==u||(f=i(u,l))!==(s=i(a,l))||o(u,a)<0^l>0){do c.point(0===f||3===f?n:e,f>1?r:t);while((f=(f+l+4)%4)!==s)}else c.point(a[0],a[1])}function f(i,u){return i>=n&&e>=i&&u>=t&&r>=u}function s(n,t){f(n,t)&&a.point(n,t)}function h(){C.point=g,d&&d.push(y=[]),S=!0,w=!1,b=_=NaN}function p(){v&&(g(m,M),x&&w&&E.rejoin(),v.push(E.buffer())),C.point=s,w&&a.lineEnd()}function g(n,t){n=Math.max(-Ha,Math.min(Ha,n)),t=Math.max(-Ha,Math.min(Ha,t));var e=f(n,t);if(d&&y.push([n,t]),S)m=n,M=t,x=e,S=!1,e&&(a.lineStart(),a.point(n,t));else if(e&&w)a.point(n,t);else{var r={a:{x:b,y:_},b:{x:n,y:t}};A(r)?(w||(a.lineStart(),a.point(r.a.x,r.a.y)),a.point(r.b.x,r.b.y),e||a.lineEnd(),k=!1):e&&(a.lineStart(),a.point(n,t),k=!1)}b=n,_=t,w=e}var v,d,y,m,M,x,b,_,w,S,k,N=a,E=Pt(),A=Yt(n,t,e,r),C={point:s,lineStart:h,lineEnd:p,polygonStart:function(){a=E,v=[],d=[],k=!0},polygonEnd:function(){a=N,v=ao.merge(v);var t=l([n,r]),e=k&&t,i=v.length;(e||i)&&(a.polygonStart(),e&&(a.lineStart(),c(null,null,1,a),a.lineEnd()),i&&Lt(v,u,t,c,a),a.polygonEnd()),v=d=y=null}};return C}}function Vt(n){var t=0,e=Fo/3,r=ae(n),i=r(t,e);return i.parallels=function(n){return arguments.length?r(t=n[0]*Fo/180,e=n[1]*Fo/180):[t/Fo*180,e/Fo*180]},i}function Xt(n,t){function e(n,t){var e=Math.sqrt(u-2*i*Math.sin(t))/i;return[e*Math.sin(n*=i),o-e*Math.cos(n)]}var r=Math.sin(n),i=(r+Math.sin(t))/2,u=1+r*(2*i-r),o=Math.sqrt(u)/i;return e.invert=function(n,t){var e=o-t;return[Math.atan2(n,e)/i,tn((u-(n*n+e*e)*i*i)/(2*i))]},e}function $t(){function n(n,t){Ia+=i*n-r*t,r=n,i=t}var t,e,r,i;$a.point=function(u,o){$a.point=n,t=r=u,e=i=o},$a.lineEnd=function(){n(t,e)}}function Bt(n,t){Ya>n&&(Ya=n),n>Va&&(Va=n),Za>t&&(Za=t),t>Xa&&(Xa=t)}function Wt(){function n(n,t){o.push("M",n,",",t,u)}function t(n,t){o.push("M",n,",",t),a.point=e}function e(n,t){o.push("L",n,",",t)}function r(){a.point=n}function i(){o.push("Z")}var u=Jt(4.5),o=[],a={point:n,lineStart:function(){a.point=t},lineEnd:r,polygonStart:function(){a.lineEnd=i},polygonEnd:function(){a.lineEnd=r,a.point=n},pointRadius:function(n){return u=Jt(n),a},result:function(){if(o.length){var n=o.join("");return o=[],n}}};return a}function Jt(n){return"m0,"+n+"a"+n+","+n+" 0 1,1 0,"+-2*n+"a"+n+","+n+" 0 1,1 0,"+2*n+"z"}function Gt(n,t){Ca+=n,za+=t,++La}function Kt(){function n(n,r){var i=n-t,u=r-e,o=Math.sqrt(i*i+u*u);qa+=o*(t+n)/2,Ta+=o*(e+r)/2,Ra+=o,Gt(t=n,e=r)}var t,e;Wa.point=function(r,i){Wa.point=n,Gt(t=r,e=i)}}function Qt(){Wa.point=Gt}function ne(){function n(n,t){var e=n-r,u=t-i,o=Math.sqrt(e*e+u*u);qa+=o*(r+n)/2,Ta+=o*(i+t)/2,Ra+=o,o=i*n-r*t,Da+=o*(r+n),Pa+=o*(i+t),Ua+=3*o,Gt(r=n,i=t)}var t,e,r,i;Wa.point=function(u,o){Wa.point=n,Gt(t=r=u,e=i=o)},Wa.lineEnd=function(){n(t,e)}}function te(n){function t(t,e){n.moveTo(t+o,e),n.arc(t,e,o,0,Ho)}function e(t,e){n.moveTo(t,e),a.point=r}function r(t,e){n.lineTo(t,e)}function i(){a.point=t}function u(){n.closePath()}var o=4.5,a={point:t,lineStart:function(){a.point=e},lineEnd:i,polygonStart:function(){a.lineEnd=u},polygonEnd:function(){a.lineEnd=i,a.point=t},pointRadius:function(n){return o=n,a},result:b};return a}function ee(n){function t(n){return(a?r:e)(n)}function e(t){return ue(t,function(e,r){e=n(e,r),t.point(e[0],e[1])})}function r(t){function e(e,r){e=n(e,r),t.point(e[0],e[1])}function r(){M=NaN,S.point=u,t.lineStart()}function u(e,r){var u=dt([e,r]),o=n(e,r);i(M,x,m,b,_,w,M=o[0],x=o[1],m=e,b=u[0],_=u[1],w=u[2],a,t),t.point(M,x)}function o(){S.point=e,t.lineEnd()}function l(){ -r(),S.point=c,S.lineEnd=f}function c(n,t){u(s=n,h=t),p=M,g=x,v=b,d=_,y=w,S.point=u}function f(){i(M,x,m,b,_,w,p,g,s,v,d,y,a,t),S.lineEnd=o,o()}var s,h,p,g,v,d,y,m,M,x,b,_,w,S={point:e,lineStart:r,lineEnd:o,polygonStart:function(){t.polygonStart(),S.lineStart=l},polygonEnd:function(){t.polygonEnd(),S.lineStart=r}};return S}function i(t,e,r,a,l,c,f,s,h,p,g,v,d,y){var m=f-t,M=s-e,x=m*m+M*M;if(x>4*u&&d--){var b=a+p,_=l+g,w=c+v,S=Math.sqrt(b*b+_*_+w*w),k=Math.asin(w/=S),N=xo(xo(w)-1)u||xo((m*z+M*L)/x-.5)>.3||o>a*p+l*g+c*v)&&(i(t,e,r,a,l,c,A,C,N,b/=S,_/=S,w,d,y),y.point(A,C),i(A,C,N,b,_,w,f,s,h,p,g,v,d,y))}}var u=.5,o=Math.cos(30*Yo),a=16;return t.precision=function(n){return arguments.length?(a=(u=n*n)>0&&16,t):Math.sqrt(u)},t}function re(n){var t=ee(function(t,e){return n([t*Zo,e*Zo])});return function(n){return le(t(n))}}function ie(n){this.stream=n}function ue(n,t){return{point:t,sphere:function(){n.sphere()},lineStart:function(){n.lineStart()},lineEnd:function(){n.lineEnd()},polygonStart:function(){n.polygonStart()},polygonEnd:function(){n.polygonEnd()}}}function oe(n){return ae(function(){return n})()}function ae(n){function t(n){return n=a(n[0]*Yo,n[1]*Yo),[n[0]*h+l,c-n[1]*h]}function e(n){return n=a.invert((n[0]-l)/h,(c-n[1])/h),n&&[n[0]*Zo,n[1]*Zo]}function r(){a=Ct(o=se(y,M,x),u);var n=u(v,d);return l=p-n[0]*h,c=g+n[1]*h,i()}function i(){return f&&(f.valid=!1,f=null),t}var u,o,a,l,c,f,s=ee(function(n,t){return n=u(n,t),[n[0]*h+l,c-n[1]*h]}),h=150,p=480,g=250,v=0,d=0,y=0,M=0,x=0,b=Fa,_=m,w=null,S=null;return t.stream=function(n){return f&&(f.valid=!1),f=le(b(o,s(_(n)))),f.valid=!0,f},t.clipAngle=function(n){return arguments.length?(b=null==n?(w=n,Fa):It((w=+n)*Yo),i()):w},t.clipExtent=function(n){return arguments.length?(S=n,_=n?Zt(n[0][0],n[0][1],n[1][0],n[1][1]):m,i()):S},t.scale=function(n){return arguments.length?(h=+n,r()):h},t.translate=function(n){return arguments.length?(p=+n[0],g=+n[1],r()):[p,g]},t.center=function(n){return arguments.length?(v=n[0]%360*Yo,d=n[1]%360*Yo,r()):[v*Zo,d*Zo]},t.rotate=function(n){return arguments.length?(y=n[0]%360*Yo,M=n[1]%360*Yo,x=n.length>2?n[2]%360*Yo:0,r()):[y*Zo,M*Zo,x*Zo]},ao.rebind(t,s,"precision"),function(){return u=n.apply(this,arguments),t.invert=u.invert&&e,r()}}function le(n){return ue(n,function(t,e){n.point(t*Yo,e*Yo)})}function ce(n,t){return[n,t]}function fe(n,t){return[n>Fo?n-Ho:-Fo>n?n+Ho:n,t]}function se(n,t,e){return n?t||e?Ct(pe(n),ge(t,e)):pe(n):t||e?ge(t,e):fe}function he(n){return function(t,e){return t+=n,[t>Fo?t-Ho:-Fo>t?t+Ho:t,e]}}function pe(n){var t=he(n);return t.invert=he(-n),t}function ge(n,t){function e(n,t){var e=Math.cos(t),a=Math.cos(n)*e,l=Math.sin(n)*e,c=Math.sin(t),f=c*r+a*i;return[Math.atan2(l*u-f*o,a*r-c*i),tn(f*u+l*o)]}var r=Math.cos(n),i=Math.sin(n),u=Math.cos(t),o=Math.sin(t);return e.invert=function(n,t){var e=Math.cos(t),a=Math.cos(n)*e,l=Math.sin(n)*e,c=Math.sin(t),f=c*u-l*o;return[Math.atan2(l*u+c*o,a*r+f*i),tn(f*r-a*i)]},e}function ve(n,t){var e=Math.cos(n),r=Math.sin(n);return function(i,u,o,a){var l=o*t;null!=i?(i=de(e,i),u=de(e,u),(o>0?u>i:i>u)&&(i+=o*Ho)):(i=n+o*Ho,u=n-.5*l);for(var c,f=i;o>0?f>u:u>f;f-=l)a.point((c=_t([e,-r*Math.cos(f),-r*Math.sin(f)]))[0],c[1])}}function de(n,t){var e=dt(t);e[0]-=n,bt(e);var r=nn(-e[1]);return((-e[2]<0?-r:r)+2*Math.PI-Uo)%(2*Math.PI)}function ye(n,t,e){var r=ao.range(n,t-Uo,e).concat(t);return function(n){return r.map(function(t){return[n,t]})}}function me(n,t,e){var r=ao.range(n,t-Uo,e).concat(t);return function(n){return r.map(function(t){return[t,n]})}}function Me(n){return n.source}function xe(n){return n.target}function be(n,t,e,r){var i=Math.cos(t),u=Math.sin(t),o=Math.cos(r),a=Math.sin(r),l=i*Math.cos(n),c=i*Math.sin(n),f=o*Math.cos(e),s=o*Math.sin(e),h=2*Math.asin(Math.sqrt(on(r-t)+i*o*on(e-n))),p=1/Math.sin(h),g=h?function(n){var t=Math.sin(n*=h)*p,e=Math.sin(h-n)*p,r=e*l+t*f,i=e*c+t*s,o=e*u+t*a;return[Math.atan2(i,r)*Zo,Math.atan2(o,Math.sqrt(r*r+i*i))*Zo]}:function(){return[n*Zo,t*Zo]};return g.distance=h,g}function _e(){function n(n,i){var u=Math.sin(i*=Yo),o=Math.cos(i),a=xo((n*=Yo)-t),l=Math.cos(a);Ja+=Math.atan2(Math.sqrt((a=o*Math.sin(a))*a+(a=r*u-e*o*l)*a),e*u+r*o*l),t=n,e=u,r=o}var t,e,r;Ga.point=function(i,u){t=i*Yo,e=Math.sin(u*=Yo),r=Math.cos(u),Ga.point=n},Ga.lineEnd=function(){Ga.point=Ga.lineEnd=b}}function we(n,t){function e(t,e){var r=Math.cos(t),i=Math.cos(e),u=n(r*i);return[u*i*Math.sin(t),u*Math.sin(e)]}return e.invert=function(n,e){var r=Math.sqrt(n*n+e*e),i=t(r),u=Math.sin(i),o=Math.cos(i);return[Math.atan2(n*u,r*o),Math.asin(r&&e*u/r)]},e}function Se(n,t){function e(n,t){o>0?-Io+Uo>t&&(t=-Io+Uo):t>Io-Uo&&(t=Io-Uo);var e=o/Math.pow(i(t),u);return[e*Math.sin(u*n),o-e*Math.cos(u*n)]}var r=Math.cos(n),i=function(n){return Math.tan(Fo/4+n/2)},u=n===t?Math.sin(n):Math.log(r/Math.cos(t))/Math.log(i(t)/i(n)),o=r*Math.pow(i(n),u)/u;return u?(e.invert=function(n,t){var e=o-t,r=K(u)*Math.sqrt(n*n+e*e);return[Math.atan2(n,e)/u,2*Math.atan(Math.pow(o/r,1/u))-Io]},e):Ne}function ke(n,t){function e(n,t){var e=u-t;return[e*Math.sin(i*n),u-e*Math.cos(i*n)]}var r=Math.cos(n),i=n===t?Math.sin(n):(r-Math.cos(t))/(t-n),u=r/i+n;return xo(i)i;i++){for(;r>1&&Q(n[e[r-2]],n[e[r-1]],n[i])<=0;)--r;e[r++]=i}return e.slice(0,r)}function qe(n,t){return n[0]-t[0]||n[1]-t[1]}function Te(n,t,e){return(e[0]-t[0])*(n[1]-t[1])<(e[1]-t[1])*(n[0]-t[0])}function Re(n,t,e,r){var i=n[0],u=e[0],o=t[0]-i,a=r[0]-u,l=n[1],c=e[1],f=t[1]-l,s=r[1]-c,h=(a*(l-c)-s*(i-u))/(s*o-a*f);return[i+h*o,l+h*f]}function De(n){var t=n[0],e=n[n.length-1];return!(t[0]-e[0]||t[1]-e[1])}function Pe(){rr(this),this.edge=this.site=this.circle=null}function Ue(n){var t=cl.pop()||new Pe;return t.site=n,t}function je(n){Be(n),ol.remove(n),cl.push(n),rr(n)}function Fe(n){var t=n.circle,e=t.x,r=t.cy,i={x:e,y:r},u=n.P,o=n.N,a=[n];je(n);for(var l=u;l.circle&&xo(e-l.circle.x)f;++f)c=a[f],l=a[f-1],nr(c.edge,l.site,c.site,i);l=a[0],c=a[s-1],c.edge=Ke(l.site,c.site,null,i),$e(l),$e(c)}function He(n){for(var t,e,r,i,u=n.x,o=n.y,a=ol._;a;)if(r=Oe(a,o)-u,r>Uo)a=a.L;else{if(i=u-Ie(a,o),!(i>Uo)){r>-Uo?(t=a.P,e=a):i>-Uo?(t=a,e=a.N):t=e=a;break}if(!a.R){t=a;break}a=a.R}var l=Ue(n);if(ol.insert(t,l),t||e){if(t===e)return Be(t),e=Ue(t.site),ol.insert(l,e),l.edge=e.edge=Ke(t.site,l.site),$e(t),void $e(e);if(!e)return void(l.edge=Ke(t.site,l.site));Be(t),Be(e);var c=t.site,f=c.x,s=c.y,h=n.x-f,p=n.y-s,g=e.site,v=g.x-f,d=g.y-s,y=2*(h*d-p*v),m=h*h+p*p,M=v*v+d*d,x={x:(d*m-p*M)/y+f,y:(h*M-v*m)/y+s};nr(e.edge,c,g,x),l.edge=Ke(c,n,null,x),e.edge=Ke(n,g,null,x),$e(t),$e(e)}}function Oe(n,t){var e=n.site,r=e.x,i=e.y,u=i-t;if(!u)return r;var o=n.P;if(!o)return-(1/0);e=o.site;var a=e.x,l=e.y,c=l-t;if(!c)return a;var f=a-r,s=1/u-1/c,h=f/c;return s?(-h+Math.sqrt(h*h-2*s*(f*f/(-2*c)-l+c/2+i-u/2)))/s+r:(r+a)/2}function Ie(n,t){var e=n.N;if(e)return Oe(e,t);var r=n.site;return r.y===t?r.x:1/0}function Ye(n){this.site=n,this.edges=[]}function Ze(n){for(var t,e,r,i,u,o,a,l,c,f,s=n[0][0],h=n[1][0],p=n[0][1],g=n[1][1],v=ul,d=v.length;d--;)if(u=v[d],u&&u.prepare())for(a=u.edges,l=a.length,o=0;l>o;)f=a[o].end(),r=f.x,i=f.y,c=a[++o%l].start(),t=c.x,e=c.y,(xo(r-t)>Uo||xo(i-e)>Uo)&&(a.splice(o,0,new tr(Qe(u.site,f,xo(r-s)Uo?{x:s,y:xo(t-s)Uo?{x:xo(e-g)Uo?{x:h,y:xo(t-h)Uo?{x:xo(e-p)=-jo)){var p=l*l+c*c,g=f*f+s*s,v=(s*p-c*g)/h,d=(l*g-f*p)/h,s=d+a,y=fl.pop()||new Xe;y.arc=n,y.site=i,y.x=v+o,y.y=s+Math.sqrt(v*v+d*d),y.cy=s,n.circle=y;for(var m=null,M=ll._;M;)if(y.yd||d>=a)return;if(h>g){if(u){if(u.y>=c)return}else u={x:d,y:l};e={x:d,y:c}}else{if(u){if(u.yr||r>1)if(h>g){if(u){if(u.y>=c)return}else u={x:(l-i)/r,y:l};e={x:(c-i)/r,y:c}}else{if(u){if(u.yp){if(u){if(u.x>=a)return}else u={x:o,y:r*o+i};e={x:a,y:r*a+i}}else{if(u){if(u.xu||s>o||r>h||i>p)){if(g=n.point){var g,v=t-n.x,d=e-n.y,y=v*v+d*d;if(l>y){var m=Math.sqrt(l=y);r=t-m,i=e-m,u=t+m,o=e+m,a=g}}for(var M=n.nodes,x=.5*(f+h),b=.5*(s+p),_=t>=x,w=e>=b,S=w<<1|_,k=S+4;k>S;++S)if(n=M[3&S])switch(3&S){case 0:c(n,f,s,x,b);break;case 1:c(n,x,s,h,b);break;case 2:c(n,f,b,x,p);break;case 3:c(n,x,b,h,p)}}}(n,r,i,u,o),a}function vr(n,t){n=ao.rgb(n),t=ao.rgb(t);var e=n.r,r=n.g,i=n.b,u=t.r-e,o=t.g-r,a=t.b-i;return function(n){return"#"+bn(Math.round(e+u*n))+bn(Math.round(r+o*n))+bn(Math.round(i+a*n))}}function dr(n,t){var e,r={},i={};for(e in n)e in t?r[e]=Mr(n[e],t[e]):i[e]=n[e];for(e in t)e in n||(i[e]=t[e]);return function(n){for(e in r)i[e]=r[e](n);return i}}function yr(n,t){return n=+n,t=+t,function(e){return n*(1-e)+t*e}}function mr(n,t){var e,r,i,u=hl.lastIndex=pl.lastIndex=0,o=-1,a=[],l=[];for(n+="",t+="";(e=hl.exec(n))&&(r=pl.exec(t));)(i=r.index)>u&&(i=t.slice(u,i),a[o]?a[o]+=i:a[++o]=i),(e=e[0])===(r=r[0])?a[o]?a[o]+=r:a[++o]=r:(a[++o]=null,l.push({i:o,x:yr(e,r)})),u=pl.lastIndex;return ur;++r)a[(e=l[r]).i]=e.x(n);return a.join("")})}function Mr(n,t){for(var e,r=ao.interpolators.length;--r>=0&&!(e=ao.interpolators[r](n,t)););return e}function xr(n,t){var e,r=[],i=[],u=n.length,o=t.length,a=Math.min(n.length,t.length);for(e=0;a>e;++e)r.push(Mr(n[e],t[e]));for(;u>e;++e)i[e]=n[e];for(;o>e;++e)i[e]=t[e];return function(n){for(e=0;a>e;++e)i[e]=r[e](n);return i}}function br(n){return function(t){return 0>=t?0:t>=1?1:n(t)}}function _r(n){return function(t){return 1-n(1-t)}}function wr(n){return function(t){return.5*(.5>t?n(2*t):2-n(2-2*t))}}function Sr(n){return n*n}function kr(n){return n*n*n}function Nr(n){if(0>=n)return 0;if(n>=1)return 1;var t=n*n,e=t*n;return 4*(.5>n?e:3*(n-t)+e-.75)}function Er(n){return function(t){return Math.pow(t,n)}}function Ar(n){return 1-Math.cos(n*Io)}function Cr(n){return Math.pow(2,10*(n-1))}function zr(n){return 1-Math.sqrt(1-n*n)}function Lr(n,t){var e;return arguments.length<2&&(t=.45),arguments.length?e=t/Ho*Math.asin(1/n):(n=1,e=t/4),function(r){return 1+n*Math.pow(2,-10*r)*Math.sin((r-e)*Ho/t)}}function qr(n){return n||(n=1.70158),function(t){return t*t*((n+1)*t-n)}}function Tr(n){return 1/2.75>n?7.5625*n*n:2/2.75>n?7.5625*(n-=1.5/2.75)*n+.75:2.5/2.75>n?7.5625*(n-=2.25/2.75)*n+.9375:7.5625*(n-=2.625/2.75)*n+.984375}function Rr(n,t){n=ao.hcl(n),t=ao.hcl(t);var e=n.h,r=n.c,i=n.l,u=t.h-e,o=t.c-r,a=t.l-i;return isNaN(o)&&(o=0,r=isNaN(r)?t.c:r),isNaN(u)?(u=0,e=isNaN(e)?t.h:e):u>180?u-=360:-180>u&&(u+=360),function(n){return sn(e+u*n,r+o*n,i+a*n)+""}}function Dr(n,t){n=ao.hsl(n),t=ao.hsl(t);var e=n.h,r=n.s,i=n.l,u=t.h-e,o=t.s-r,a=t.l-i;return isNaN(o)&&(o=0,r=isNaN(r)?t.s:r),isNaN(u)?(u=0,e=isNaN(e)?t.h:e):u>180?u-=360:-180>u&&(u+=360),function(n){return cn(e+u*n,r+o*n,i+a*n)+""}}function Pr(n,t){n=ao.lab(n),t=ao.lab(t);var e=n.l,r=n.a,i=n.b,u=t.l-e,o=t.a-r,a=t.b-i;return function(n){return pn(e+u*n,r+o*n,i+a*n)+""}}function Ur(n,t){return t-=n,function(e){return Math.round(n+t*e)}}function jr(n){var t=[n.a,n.b],e=[n.c,n.d],r=Hr(t),i=Fr(t,e),u=Hr(Or(e,t,-i))||0;t[0]*e[1]180?t+=360:t-n>180&&(n+=360),r.push({i:e.push(Ir(e)+"rotate(",null,")")-2,x:yr(n,t)})):t&&e.push(Ir(e)+"rotate("+t+")")}function Vr(n,t,e,r){n!==t?r.push({i:e.push(Ir(e)+"skewX(",null,")")-2,x:yr(n,t)}):t&&e.push(Ir(e)+"skewX("+t+")")}function Xr(n,t,e,r){if(n[0]!==t[0]||n[1]!==t[1]){var i=e.push(Ir(e)+"scale(",null,",",null,")");r.push({i:i-4,x:yr(n[0],t[0])},{i:i-2,x:yr(n[1],t[1])})}else 1===t[0]&&1===t[1]||e.push(Ir(e)+"scale("+t+")")}function $r(n,t){var e=[],r=[];return n=ao.transform(n),t=ao.transform(t),Yr(n.translate,t.translate,e,r),Zr(n.rotate,t.rotate,e,r),Vr(n.skew,t.skew,e,r),Xr(n.scale,t.scale,e,r),n=t=null,function(n){for(var t,i=-1,u=r.length;++i=0;)e.push(i[r])}function oi(n,t){for(var e=[n],r=[];null!=(n=e.pop());)if(r.push(n),(u=n.children)&&(i=u.length))for(var i,u,o=-1;++oe;++e)(t=n[e][1])>i&&(r=e,i=t);return r}function yi(n){return n.reduce(mi,0)}function mi(n,t){return n+t[1]}function Mi(n,t){return xi(n,Math.ceil(Math.log(t.length)/Math.LN2+1))}function xi(n,t){for(var e=-1,r=+n[0],i=(n[1]-r)/t,u=[];++e<=t;)u[e]=i*e+r;return u}function bi(n){return[ao.min(n),ao.max(n)]}function _i(n,t){return n.value-t.value}function wi(n,t){var e=n._pack_next;n._pack_next=t,t._pack_prev=n,t._pack_next=e,e._pack_prev=t}function Si(n,t){n._pack_next=t,t._pack_prev=n}function ki(n,t){var e=t.x-n.x,r=t.y-n.y,i=n.r+t.r;return.999*i*i>e*e+r*r}function Ni(n){function t(n){f=Math.min(n.x-n.r,f),s=Math.max(n.x+n.r,s),h=Math.min(n.y-n.r,h),p=Math.max(n.y+n.r,p)}if((e=n.children)&&(c=e.length)){var e,r,i,u,o,a,l,c,f=1/0,s=-(1/0),h=1/0,p=-(1/0);if(e.forEach(Ei),r=e[0],r.x=-r.r,r.y=0,t(r),c>1&&(i=e[1],i.x=i.r,i.y=0,t(i),c>2))for(u=e[2],zi(r,i,u),t(u),wi(r,u),r._pack_prev=u,wi(u,i),i=r._pack_next,o=3;c>o;o++){zi(r,i,u=e[o]);var g=0,v=1,d=1;for(a=i._pack_next;a!==i;a=a._pack_next,v++)if(ki(a,u)){g=1;break}if(1==g)for(l=r._pack_prev;l!==a._pack_prev&&!ki(l,u);l=l._pack_prev,d++);g?(d>v||v==d&&i.ro;o++)u=e[o],u.x-=y,u.y-=m,M=Math.max(M,u.r+Math.sqrt(u.x*u.x+u.y*u.y));n.r=M,e.forEach(Ai)}}function Ei(n){n._pack_next=n._pack_prev=n}function Ai(n){delete n._pack_next,delete n._pack_prev}function Ci(n,t,e,r){var i=n.children;if(n.x=t+=r*n.x,n.y=e+=r*n.y,n.r*=r,i)for(var u=-1,o=i.length;++u=0;)t=i[u],t.z+=e,t.m+=e,e+=t.s+(r+=t.c)}function Pi(n,t,e){return n.a.parent===t.parent?n.a:e}function Ui(n){return 1+ao.max(n,function(n){return n.y})}function ji(n){return n.reduce(function(n,t){return n+t.x},0)/n.length}function Fi(n){var t=n.children;return t&&t.length?Fi(t[0]):n}function Hi(n){var t,e=n.children;return e&&(t=e.length)?Hi(e[t-1]):n}function Oi(n){return{x:n.x,y:n.y,dx:n.dx,dy:n.dy}}function Ii(n,t){var e=n.x+t[3],r=n.y+t[0],i=n.dx-t[1]-t[3],u=n.dy-t[0]-t[2];return 0>i&&(e+=i/2,i=0),0>u&&(r+=u/2,u=0),{x:e,y:r,dx:i,dy:u}}function Yi(n){var t=n[0],e=n[n.length-1];return e>t?[t,e]:[e,t]}function Zi(n){return n.rangeExtent?n.rangeExtent():Yi(n.range())}function Vi(n,t,e,r){var i=e(n[0],n[1]),u=r(t[0],t[1]);return function(n){return u(i(n))}}function Xi(n,t){var e,r=0,i=n.length-1,u=n[r],o=n[i];return u>o&&(e=r,r=i,i=e,e=u,u=o,o=e),n[r]=t.floor(u),n[i]=t.ceil(o),n}function $i(n){return n?{floor:function(t){return Math.floor(t/n)*n},ceil:function(t){return Math.ceil(t/n)*n}}:Sl}function Bi(n,t,e,r){var i=[],u=[],o=0,a=Math.min(n.length,t.length)-1;for(n[a]2?Bi:Vi,l=r?Wr:Br;return o=i(n,t,l,e),a=i(t,n,l,Mr),u}function u(n){return o(n)}var o,a;return u.invert=function(n){return a(n)},u.domain=function(t){return arguments.length?(n=t.map(Number),i()):n},u.range=function(n){return arguments.length?(t=n,i()):t},u.rangeRound=function(n){return u.range(n).interpolate(Ur)},u.clamp=function(n){return arguments.length?(r=n,i()):r},u.interpolate=function(n){return arguments.length?(e=n,i()):e},u.ticks=function(t){return Qi(n,t)},u.tickFormat=function(t,e){return nu(n,t,e)},u.nice=function(t){return Gi(n,t),i()},u.copy=function(){return Wi(n,t,e,r)},i()}function Ji(n,t){return ao.rebind(n,t,"range","rangeRound","interpolate","clamp")}function Gi(n,t){return Xi(n,$i(Ki(n,t)[2])),Xi(n,$i(Ki(n,t)[2])),n}function Ki(n,t){null==t&&(t=10);var e=Yi(n),r=e[1]-e[0],i=Math.pow(10,Math.floor(Math.log(r/t)/Math.LN10)),u=t/r*i;return.15>=u?i*=10:.35>=u?i*=5:.75>=u&&(i*=2),e[0]=Math.ceil(e[0]/i)*i,e[1]=Math.floor(e[1]/i)*i+.5*i,e[2]=i,e}function Qi(n,t){return ao.range.apply(ao,Ki(n,t))}function nu(n,t,e){var r=Ki(n,t);if(e){var i=ha.exec(e);if(i.shift(),"s"===i[8]){var u=ao.formatPrefix(Math.max(xo(r[0]),xo(r[1])));return i[7]||(i[7]="."+tu(u.scale(r[2]))),i[8]="f",e=ao.format(i.join("")),function(n){return e(u.scale(n))+u.symbol}}i[7]||(i[7]="."+eu(i[8],r)),e=i.join("")}else e=",."+tu(r[2])+"f";return ao.format(e)}function tu(n){return-Math.floor(Math.log(n)/Math.LN10+.01)}function eu(n,t){var e=tu(t[2]);return n in kl?Math.abs(e-tu(Math.max(xo(t[0]),xo(t[1]))))+ +("e"!==n):e-2*("%"===n)}function ru(n,t,e,r){function i(n){return(e?Math.log(0>n?0:n):-Math.log(n>0?0:-n))/Math.log(t)}function u(n){return e?Math.pow(t,n):-Math.pow(t,-n)}function o(t){return n(i(t))}return o.invert=function(t){return u(n.invert(t))},o.domain=function(t){return arguments.length?(e=t[0]>=0,n.domain((r=t.map(Number)).map(i)),o):r},o.base=function(e){return arguments.length?(t=+e,n.domain(r.map(i)),o):t},o.nice=function(){var t=Xi(r.map(i),e?Math:El);return n.domain(t),r=t.map(u),o},o.ticks=function(){var n=Yi(r),o=[],a=n[0],l=n[1],c=Math.floor(i(a)),f=Math.ceil(i(l)),s=t%1?2:t;if(isFinite(f-c)){if(e){for(;f>c;c++)for(var h=1;s>h;h++)o.push(u(c)*h);o.push(u(c))}else for(o.push(u(c));c++0;h--)o.push(u(c)*h);for(c=0;o[c]l;f--);o=o.slice(c,f)}return o},o.tickFormat=function(n,e){if(!arguments.length)return Nl;arguments.length<2?e=Nl:"function"!=typeof e&&(e=ao.format(e));var r=Math.max(1,t*n/o.ticks().length);return function(n){var o=n/u(Math.round(i(n)));return t-.5>o*t&&(o*=t),r>=o?e(n):""}},o.copy=function(){return ru(n.copy(),t,e,r)},Ji(o,n)}function iu(n,t,e){function r(t){return n(i(t))}var i=uu(t),u=uu(1/t);return r.invert=function(t){return u(n.invert(t))},r.domain=function(t){return arguments.length?(n.domain((e=t.map(Number)).map(i)),r):e},r.ticks=function(n){return Qi(e,n)},r.tickFormat=function(n,t){return nu(e,n,t)},r.nice=function(n){return r.domain(Gi(e,n))},r.exponent=function(o){return arguments.length?(i=uu(t=o),u=uu(1/t),n.domain(e.map(i)),r):t},r.copy=function(){return iu(n.copy(),t,e)},Ji(r,n)}function uu(n){return function(t){return 0>t?-Math.pow(-t,n):Math.pow(t,n)}}function ou(n,t){function e(e){return u[((i.get(e)||("range"===t.t?i.set(e,n.push(e)):NaN))-1)%u.length]}function r(t,e){return ao.range(n.length).map(function(n){return t+e*n})}var i,u,o;return e.domain=function(r){if(!arguments.length)return n;n=[],i=new c;for(var u,o=-1,a=r.length;++oe?[NaN,NaN]:[e>0?a[e-1]:n[0],et?NaN:t/u+n,[t,t+1/u]},r.copy=function(){return lu(n,t,e)},i()}function cu(n,t){function e(e){return e>=e?t[ao.bisect(n,e)]:void 0}return e.domain=function(t){return arguments.length?(n=t,e):n},e.range=function(n){return arguments.length?(t=n,e):t},e.invertExtent=function(e){return e=t.indexOf(e),[n[e-1],n[e]]},e.copy=function(){return cu(n,t)},e}function fu(n){function t(n){return+n}return t.invert=t,t.domain=t.range=function(e){return arguments.length?(n=e.map(t),t):n},t.ticks=function(t){return Qi(n,t)},t.tickFormat=function(t,e){return nu(n,t,e)},t.copy=function(){return fu(n)},t}function su(){return 0}function hu(n){return n.innerRadius}function pu(n){return n.outerRadius}function gu(n){return n.startAngle}function vu(n){return n.endAngle}function du(n){return n&&n.padAngle}function yu(n,t,e,r){return(n-e)*t-(t-r)*n>0?0:1}function mu(n,t,e,r,i){var u=n[0]-t[0],o=n[1]-t[1],a=(i?r:-r)/Math.sqrt(u*u+o*o),l=a*o,c=-a*u,f=n[0]+l,s=n[1]+c,h=t[0]+l,p=t[1]+c,g=(f+h)/2,v=(s+p)/2,d=h-f,y=p-s,m=d*d+y*y,M=e-r,x=f*p-h*s,b=(0>y?-1:1)*Math.sqrt(Math.max(0,M*M*m-x*x)),_=(x*y-d*b)/m,w=(-x*d-y*b)/m,S=(x*y+d*b)/m,k=(-x*d+y*b)/m,N=_-g,E=w-v,A=S-g,C=k-v;return N*N+E*E>A*A+C*C&&(_=S,w=k),[[_-l,w-c],[_*e/M,w*e/M]]}function Mu(n){function t(t){function o(){c.push("M",u(n(f),a))}for(var l,c=[],f=[],s=-1,h=t.length,p=En(e),g=En(r);++s1?n.join("L"):n+"Z"}function bu(n){return n.join("L")+"Z"}function _u(n){for(var t=0,e=n.length,r=n[0],i=[r[0],",",r[1]];++t1&&i.push("H",r[0]),i.join("")}function wu(n){for(var t=0,e=n.length,r=n[0],i=[r[0],",",r[1]];++t1){a=t[1],u=n[l],l++,r+="C"+(i[0]+o[0])+","+(i[1]+o[1])+","+(u[0]-a[0])+","+(u[1]-a[1])+","+u[0]+","+u[1];for(var c=2;c9&&(i=3*t/Math.sqrt(i),o[a]=i*e,o[a+1]=i*r));for(a=-1;++a<=l;)i=(n[Math.min(l,a+1)][0]-n[Math.max(0,a-1)][0])/(6*(1+o[a]*o[a])),u.push([i||0,o[a]*i||0]);return u}function Fu(n){return n.length<3?xu(n):n[0]+Au(n,ju(n))}function Hu(n){for(var t,e,r,i=-1,u=n.length;++i=t?o(n-t):void(f.c=o)}function o(e){var i=g.active,u=g[i];u&&(u.timer.c=null,u.timer.t=NaN,--g.count,delete g[i],u.event&&u.event.interrupt.call(n,n.__data__,u.index));for(var o in g)if(r>+o){var c=g[o];c.timer.c=null,c.timer.t=NaN,--g.count,delete g[o]}f.c=a,qn(function(){return f.c&&a(e||1)&&(f.c=null,f.t=NaN),1},0,l),g.active=r,v.event&&v.event.start.call(n,n.__data__,t),p=[],v.tween.forEach(function(e,r){(r=r.call(n,n.__data__,t))&&p.push(r)}),h=v.ease,s=v.duration}function a(i){for(var u=i/s,o=h(u),a=p.length;a>0;)p[--a].call(n,o);return u>=1?(v.event&&v.event.end.call(n,n.__data__,t),--g.count?delete g[r]:delete n[e],1):void 0}var l,f,s,h,p,g=n[e]||(n[e]={active:0,count:0}),v=g[r];v||(l=i.time,f=qn(u,0,l),v=g[r]={tween:new c,time:l,timer:f,delay:i.delay,duration:i.duration,ease:i.ease,index:t},i=null,++g.count)}function no(n,t,e){n.attr("transform",function(n){var r=t(n);return"translate("+(isFinite(r)?r:e(n))+",0)"})}function to(n,t,e){n.attr("transform",function(n){var r=t(n);return"translate(0,"+(isFinite(r)?r:e(n))+")"})}function eo(n){return n.toISOString()}function ro(n,t,e){function r(t){return n(t)}function i(n,e){var r=n[1]-n[0],i=r/e,u=ao.bisect(Kl,i);return u==Kl.length?[t.year,Ki(n.map(function(n){return n/31536e6}),e)[2]]:u?t[i/Kl[u-1]1?{floor:function(t){for(;e(t=n.floor(t));)t=io(t-1);return t},ceil:function(t){for(;e(t=n.ceil(t));)t=io(+t+1);return t}}:n))},r.ticks=function(n,t){var e=Yi(r.domain()),u=null==n?i(e,10):"number"==typeof n?i(e,n):!n.range&&[{range:n},t];return u&&(n=u[0],t=u[1]),n.range(e[0],io(+e[1]+1),1>t?1:t)},r.tickFormat=function(){return e},r.copy=function(){return ro(n.copy(),t,e)},Ji(r,n)}function io(n){return new Date(n)}function uo(n){return JSON.parse(n.responseText)}function oo(n){var t=fo.createRange();return t.selectNode(fo.body),t.createContextualFragment(n.responseText)}var ao={version:"3.5.17"},lo=[].slice,co=function(n){return lo.call(n)},fo=this.document;if(fo)try{co(fo.documentElement.childNodes)[0].nodeType}catch(so){co=function(n){for(var t=n.length,e=new Array(t);t--;)e[t]=n[t];return e}}if(Date.now||(Date.now=function(){return+new Date}),fo)try{fo.createElement("DIV").style.setProperty("opacity",0,"")}catch(ho){var po=this.Element.prototype,go=po.setAttribute,vo=po.setAttributeNS,yo=this.CSSStyleDeclaration.prototype,mo=yo.setProperty;po.setAttribute=function(n,t){go.call(this,n,t+"")},po.setAttributeNS=function(n,t,e){vo.call(this,n,t,e+"")},yo.setProperty=function(n,t,e){mo.call(this,n,t+"",e)}}ao.ascending=e,ao.descending=function(n,t){return n>t?-1:t>n?1:t>=n?0:NaN},ao.min=function(n,t){var e,r,i=-1,u=n.length;if(1===arguments.length){for(;++i=r){e=r;break}for(;++ir&&(e=r)}else{for(;++i=r){e=r;break}for(;++ir&&(e=r)}return e},ao.max=function(n,t){var e,r,i=-1,u=n.length;if(1===arguments.length){for(;++i=r){e=r;break}for(;++ie&&(e=r)}else{for(;++i=r){e=r;break}for(;++ie&&(e=r)}return e},ao.extent=function(n,t){var e,r,i,u=-1,o=n.length;if(1===arguments.length){for(;++u=r){e=i=r;break}for(;++ur&&(e=r),r>i&&(i=r))}else{for(;++u=r){e=i=r;break}for(;++ur&&(e=r),r>i&&(i=r))}return[e,i]},ao.sum=function(n,t){var e,r=0,u=n.length,o=-1;if(1===arguments.length)for(;++o1?l/(f-1):void 0},ao.deviation=function(){var n=ao.variance.apply(this,arguments);return n?Math.sqrt(n):n};var Mo=u(e);ao.bisectLeft=Mo.left,ao.bisect=ao.bisectRight=Mo.right,ao.bisector=function(n){return u(1===n.length?function(t,r){return e(n(t),r)}:n)},ao.shuffle=function(n,t,e){(u=arguments.length)<3&&(e=n.length,2>u&&(t=0));for(var r,i,u=e-t;u;)i=Math.random()*u--|0,r=n[u+t],n[u+t]=n[i+t],n[i+t]=r;return n},ao.permute=function(n,t){for(var e=t.length,r=new Array(e);e--;)r[e]=n[t[e]];return r},ao.pairs=function(n){for(var t,e=0,r=n.length-1,i=n[0],u=new Array(0>r?0:r);r>e;)u[e]=[t=i,i=n[++e]];return u},ao.transpose=function(n){if(!(i=n.length))return[];for(var t=-1,e=ao.min(n,o),r=new Array(e);++t=0;)for(r=n[i],t=r.length;--t>=0;)e[--o]=r[t];return e};var xo=Math.abs;ao.range=function(n,t,e){if(arguments.length<3&&(e=1,arguments.length<2&&(t=n,n=0)),(t-n)/e===1/0)throw new Error("infinite range");var r,i=[],u=a(xo(e)),o=-1;if(n*=u,t*=u,e*=u,0>e)for(;(r=n+e*++o)>t;)i.push(r/u);else for(;(r=n+e*++o)=u.length)return r?r.call(i,o):e?o.sort(e):o;for(var l,f,s,h,p=-1,g=o.length,v=u[a++],d=new c;++p=u.length)return n;var r=[],i=o[e++];return n.forEach(function(n,i){r.push({key:n,values:t(i,e)})}),i?r.sort(function(n,t){return i(n.key,t.key)}):r}var e,r,i={},u=[],o=[];return i.map=function(t,e){return n(e,t,0)},i.entries=function(e){return t(n(ao.map,e,0),0)},i.key=function(n){return u.push(n),i},i.sortKeys=function(n){return o[u.length-1]=n,i},i.sortValues=function(n){return e=n,i},i.rollup=function(n){return r=n,i},i},ao.set=function(n){var t=new y;if(n)for(var e=0,r=n.length;r>e;++e)t.add(n[e]);return t},l(y,{has:h,add:function(n){return this._[f(n+="")]=!0,n},remove:p,values:g,size:v,empty:d,forEach:function(n){for(var t in this._)n.call(this,s(t))}}),ao.behavior={},ao.rebind=function(n,t){for(var e,r=1,i=arguments.length;++r=0&&(r=n.slice(e+1),n=n.slice(0,e)),n)return arguments.length<2?this[n].on(r):this[n].on(r,t);if(2===arguments.length){if(null==t)for(n in this)this.hasOwnProperty(n)&&this[n].on(r,null);return this}},ao.event=null,ao.requote=function(n){return n.replace(So,"\\$&")};var So=/[\\\^\$\*\+\?\|\[\]\(\)\.\{\}]/g,ko={}.__proto__?function(n,t){n.__proto__=t}:function(n,t){for(var e in t)n[e]=t[e]},No=function(n,t){return t.querySelector(n)},Eo=function(n,t){return t.querySelectorAll(n)},Ao=function(n,t){var e=n.matches||n[x(n,"matchesSelector")];return(Ao=function(n,t){return e.call(n,t)})(n,t)};"function"==typeof Sizzle&&(No=function(n,t){return Sizzle(n,t)[0]||null},Eo=Sizzle,Ao=Sizzle.matchesSelector),ao.selection=function(){return ao.select(fo.documentElement)};var Co=ao.selection.prototype=[];Co.select=function(n){var t,e,r,i,u=[];n=A(n);for(var o=-1,a=this.length;++o=0&&"xmlns"!==(e=n.slice(0,t))&&(n=n.slice(t+1)),Lo.hasOwnProperty(e)?{space:Lo[e],local:n}:n}},Co.attr=function(n,t){if(arguments.length<2){if("string"==typeof n){var e=this.node();return n=ao.ns.qualify(n),n.local?e.getAttributeNS(n.space,n.local):e.getAttribute(n)}for(t in n)this.each(z(t,n[t]));return this}return this.each(z(n,t))},Co.classed=function(n,t){if(arguments.length<2){if("string"==typeof n){var e=this.node(),r=(n=T(n)).length,i=-1;if(t=e.classList){for(;++ii){if("string"!=typeof n){2>i&&(e="");for(r in n)this.each(P(r,n[r],e));return this}if(2>i){var u=this.node();return t(u).getComputedStyle(u,null).getPropertyValue(n)}r=""}return this.each(P(n,e,r))},Co.property=function(n,t){if(arguments.length<2){if("string"==typeof n)return this.node()[n];for(t in n)this.each(U(t,n[t]));return this}return this.each(U(n,t))},Co.text=function(n){return arguments.length?this.each("function"==typeof n?function(){var t=n.apply(this,arguments);this.textContent=null==t?"":t}:null==n?function(){this.textContent=""}:function(){this.textContent=n}):this.node().textContent},Co.html=function(n){return arguments.length?this.each("function"==typeof n?function(){var t=n.apply(this,arguments);this.innerHTML=null==t?"":t}:null==n?function(){this.innerHTML=""}:function(){this.innerHTML=n}):this.node().innerHTML},Co.append=function(n){return n=j(n),this.select(function(){return this.appendChild(n.apply(this,arguments))})},Co.insert=function(n,t){return n=j(n),t=A(t),this.select(function(){return this.insertBefore(n.apply(this,arguments),t.apply(this,arguments)||null)})},Co.remove=function(){return this.each(F)},Co.data=function(n,t){function e(n,e){var r,i,u,o=n.length,s=e.length,h=Math.min(o,s),p=new Array(s),g=new Array(s),v=new Array(o);if(t){var d,y=new c,m=new Array(o);for(r=-1;++rr;++r)g[r]=H(e[r]);for(;o>r;++r)v[r]=n[r]}g.update=p,g.parentNode=p.parentNode=v.parentNode=n.parentNode,a.push(g),l.push(p),f.push(v)}var r,i,u=-1,o=this.length;if(!arguments.length){for(n=new Array(o=(r=this[0]).length);++uu;u++){i.push(t=[]),t.parentNode=(e=this[u]).parentNode;for(var a=0,l=e.length;l>a;a++)(r=e[a])&&n.call(r,r.__data__,a,u)&&t.push(r)}return E(i)},Co.order=function(){for(var n=-1,t=this.length;++n=0;)(e=r[i])&&(u&&u!==e.nextSibling&&u.parentNode.insertBefore(e,u),u=e);return this},Co.sort=function(n){n=I.apply(this,arguments);for(var t=-1,e=this.length;++tn;n++)for(var e=this[n],r=0,i=e.length;i>r;r++){var u=e[r];if(u)return u}return null},Co.size=function(){var n=0;return Y(this,function(){++n}),n};var qo=[];ao.selection.enter=Z,ao.selection.enter.prototype=qo,qo.append=Co.append,qo.empty=Co.empty,qo.node=Co.node,qo.call=Co.call,qo.size=Co.size,qo.select=function(n){for(var t,e,r,i,u,o=[],a=-1,l=this.length;++ar){if("string"!=typeof n){2>r&&(t=!1);for(e in n)this.each(X(e,n[e],t));return this}if(2>r)return(r=this.node()["__on"+n])&&r._;e=!1}return this.each(X(n,t,e))};var To=ao.map({mouseenter:"mouseover",mouseleave:"mouseout"});fo&&To.forEach(function(n){"on"+n in fo&&To.remove(n)});var Ro,Do=0;ao.mouse=function(n){return J(n,k())};var Po=this.navigator&&/WebKit/.test(this.navigator.userAgent)?-1:0;ao.touch=function(n,t,e){if(arguments.length<3&&(e=t,t=k().changedTouches),t)for(var r,i=0,u=t.length;u>i;++i)if((r=t[i]).identifier===e)return J(n,r)},ao.behavior.drag=function(){function n(){this.on("mousedown.drag",u).on("touchstart.drag",o)}function e(n,t,e,u,o){return function(){function a(){var n,e,r=t(h,v);r&&(n=r[0]-M[0],e=r[1]-M[1],g|=n|e,M=r,p({type:"drag",x:r[0]+c[0],y:r[1]+c[1],dx:n,dy:e}))}function l(){t(h,v)&&(y.on(u+d,null).on(o+d,null),m(g),p({type:"dragend"}))}var c,f=this,s=ao.event.target.correspondingElement||ao.event.target,h=f.parentNode,p=r.of(f,arguments),g=0,v=n(),d=".drag"+(null==v?"":"-"+v),y=ao.select(e(s)).on(u+d,a).on(o+d,l),m=W(s),M=t(h,v);i?(c=i.apply(f,arguments),c=[c.x-M[0],c.y-M[1]]):c=[0,0],p({type:"dragstart"})}}var r=N(n,"drag","dragstart","dragend"),i=null,u=e(b,ao.mouse,t,"mousemove","mouseup"),o=e(G,ao.touch,m,"touchmove","touchend");return n.origin=function(t){return arguments.length?(i=t,n):i},ao.rebind(n,r,"on")},ao.touches=function(n,t){return arguments.length<2&&(t=k().touches),t?co(t).map(function(t){var e=J(n,t);return e.identifier=t.identifier,e}):[]};var Uo=1e-6,jo=Uo*Uo,Fo=Math.PI,Ho=2*Fo,Oo=Ho-Uo,Io=Fo/2,Yo=Fo/180,Zo=180/Fo,Vo=Math.SQRT2,Xo=2,$o=4;ao.interpolateZoom=function(n,t){var e,r,i=n[0],u=n[1],o=n[2],a=t[0],l=t[1],c=t[2],f=a-i,s=l-u,h=f*f+s*s;if(jo>h)r=Math.log(c/o)/Vo,e=function(n){return[i+n*f,u+n*s,o*Math.exp(Vo*n*r)]};else{var p=Math.sqrt(h),g=(c*c-o*o+$o*h)/(2*o*Xo*p),v=(c*c-o*o-$o*h)/(2*c*Xo*p),d=Math.log(Math.sqrt(g*g+1)-g),y=Math.log(Math.sqrt(v*v+1)-v);r=(y-d)/Vo,e=function(n){var t=n*r,e=rn(d),a=o/(Xo*p)*(e*un(Vo*t+d)-en(d));return[i+a*f,u+a*s,o*e/rn(Vo*t+d)]}}return e.duration=1e3*r,e},ao.behavior.zoom=function(){function n(n){n.on(L,s).on(Wo+".zoom",p).on("dblclick.zoom",g).on(R,h)}function e(n){return[(n[0]-k.x)/k.k,(n[1]-k.y)/k.k]}function r(n){return[n[0]*k.k+k.x,n[1]*k.k+k.y]}function i(n){k.k=Math.max(A[0],Math.min(A[1],n))}function u(n,t){t=r(t),k.x+=n[0]-t[0],k.y+=n[1]-t[1]}function o(t,e,r,o){t.__chart__={x:k.x,y:k.y,k:k.k},i(Math.pow(2,o)),u(d=e,r),t=ao.select(t),C>0&&(t=t.transition().duration(C)),t.call(n.event)}function a(){b&&b.domain(x.range().map(function(n){return(n-k.x)/k.k}).map(x.invert)),w&&w.domain(_.range().map(function(n){return(n-k.y)/k.k}).map(_.invert))}function l(n){z++||n({type:"zoomstart"})}function c(n){a(),n({type:"zoom",scale:k.k,translate:[k.x,k.y]})}function f(n){--z||(n({type:"zoomend"}),d=null)}function s(){function n(){a=1,u(ao.mouse(i),h),c(o)}function r(){s.on(q,null).on(T,null),p(a),f(o)}var i=this,o=D.of(i,arguments),a=0,s=ao.select(t(i)).on(q,n).on(T,r),h=e(ao.mouse(i)),p=W(i);Il.call(i),l(o)}function h(){function n(){var n=ao.touches(g);return p=k.k,n.forEach(function(n){n.identifier in d&&(d[n.identifier]=e(n))}),n}function t(){var t=ao.event.target;ao.select(t).on(x,r).on(b,a),_.push(t);for(var e=ao.event.changedTouches,i=0,u=e.length;u>i;++i)d[e[i].identifier]=null;var l=n(),c=Date.now();if(1===l.length){if(500>c-M){var f=l[0];o(g,f,d[f.identifier],Math.floor(Math.log(k.k)/Math.LN2)+1),S()}M=c}else if(l.length>1){var f=l[0],s=l[1],h=f[0]-s[0],p=f[1]-s[1];y=h*h+p*p}}function r(){var n,t,e,r,o=ao.touches(g);Il.call(g);for(var a=0,l=o.length;l>a;++a,r=null)if(e=o[a],r=d[e.identifier]){if(t)break;n=e,t=r}if(r){var f=(f=e[0]-n[0])*f+(f=e[1]-n[1])*f,s=y&&Math.sqrt(f/y);n=[(n[0]+e[0])/2,(n[1]+e[1])/2],t=[(t[0]+r[0])/2,(t[1]+r[1])/2],i(s*p)}M=null,u(n,t),c(v)}function a(){if(ao.event.touches.length){for(var t=ao.event.changedTouches,e=0,r=t.length;r>e;++e)delete d[t[e].identifier];for(var i in d)return void n()}ao.selectAll(_).on(m,null),w.on(L,s).on(R,h),N(),f(v)}var p,g=this,v=D.of(g,arguments),d={},y=0,m=".zoom-"+ao.event.changedTouches[0].identifier,x="touchmove"+m,b="touchend"+m,_=[],w=ao.select(g),N=W(g);t(),l(v),w.on(L,null).on(R,t)}function p(){var n=D.of(this,arguments);m?clearTimeout(m):(Il.call(this),v=e(d=y||ao.mouse(this)),l(n)),m=setTimeout(function(){m=null,f(n)},50),S(),i(Math.pow(2,.002*Bo())*k.k),u(d,v),c(n)}function g(){var n=ao.mouse(this),t=Math.log(k.k)/Math.LN2;o(this,n,e(n),ao.event.shiftKey?Math.ceil(t)-1:Math.floor(t)+1)}var v,d,y,m,M,x,b,_,w,k={x:0,y:0,k:1},E=[960,500],A=Jo,C=250,z=0,L="mousedown.zoom",q="mousemove.zoom",T="mouseup.zoom",R="touchstart.zoom",D=N(n,"zoomstart","zoom","zoomend");return Wo||(Wo="onwheel"in fo?(Bo=function(){return-ao.event.deltaY*(ao.event.deltaMode?120:1)},"wheel"):"onmousewheel"in fo?(Bo=function(){return ao.event.wheelDelta},"mousewheel"):(Bo=function(){return-ao.event.detail},"MozMousePixelScroll")),n.event=function(n){n.each(function(){var n=D.of(this,arguments),t=k;Hl?ao.select(this).transition().each("start.zoom",function(){k=this.__chart__||{x:0,y:0,k:1},l(n)}).tween("zoom:zoom",function(){var e=E[0],r=E[1],i=d?d[0]:e/2,u=d?d[1]:r/2,o=ao.interpolateZoom([(i-k.x)/k.k,(u-k.y)/k.k,e/k.k],[(i-t.x)/t.k,(u-t.y)/t.k,e/t.k]);return function(t){var r=o(t),a=e/r[2];this.__chart__=k={x:i-r[0]*a,y:u-r[1]*a,k:a},c(n)}}).each("interrupt.zoom",function(){f(n)}).each("end.zoom",function(){f(n)}):(this.__chart__=k,l(n),c(n),f(n))})},n.translate=function(t){return arguments.length?(k={x:+t[0],y:+t[1],k:k.k},a(),n):[k.x,k.y]},n.scale=function(t){return arguments.length?(k={x:k.x,y:k.y,k:null},i(+t),a(),n):k.k},n.scaleExtent=function(t){return arguments.length?(A=null==t?Jo:[+t[0],+t[1]],n):A},n.center=function(t){return arguments.length?(y=t&&[+t[0],+t[1]],n):y},n.size=function(t){return arguments.length?(E=t&&[+t[0],+t[1]],n):E},n.duration=function(t){return arguments.length?(C=+t,n):C},n.x=function(t){return arguments.length?(b=t,x=t.copy(),k={x:0,y:0,k:1},n):b},n.y=function(t){return arguments.length?(w=t,_=t.copy(),k={x:0,y:0,k:1},n):w},ao.rebind(n,D,"on")};var Bo,Wo,Jo=[0,1/0];ao.color=an,an.prototype.toString=function(){return this.rgb()+""},ao.hsl=ln;var Go=ln.prototype=new an;Go.brighter=function(n){return n=Math.pow(.7,arguments.length?n:1),new ln(this.h,this.s,this.l/n)},Go.darker=function(n){return n=Math.pow(.7,arguments.length?n:1),new ln(this.h,this.s,n*this.l)},Go.rgb=function(){return cn(this.h,this.s,this.l)},ao.hcl=fn;var Ko=fn.prototype=new an;Ko.brighter=function(n){return new fn(this.h,this.c,Math.min(100,this.l+Qo*(arguments.length?n:1)))},Ko.darker=function(n){return new fn(this.h,this.c,Math.max(0,this.l-Qo*(arguments.length?n:1)))},Ko.rgb=function(){return sn(this.h,this.c,this.l).rgb()},ao.lab=hn;var Qo=18,na=.95047,ta=1,ea=1.08883,ra=hn.prototype=new an;ra.brighter=function(n){return new hn(Math.min(100,this.l+Qo*(arguments.length?n:1)),this.a,this.b)},ra.darker=function(n){return new hn(Math.max(0,this.l-Qo*(arguments.length?n:1)),this.a,this.b)},ra.rgb=function(){return pn(this.l,this.a,this.b)},ao.rgb=mn;var ia=mn.prototype=new an;ia.brighter=function(n){n=Math.pow(.7,arguments.length?n:1);var t=this.r,e=this.g,r=this.b,i=30;return t||e||r?(t&&i>t&&(t=i),e&&i>e&&(e=i),r&&i>r&&(r=i),new mn(Math.min(255,t/n),Math.min(255,e/n),Math.min(255,r/n))):new mn(i,i,i)},ia.darker=function(n){return n=Math.pow(.7,arguments.length?n:1),new mn(n*this.r,n*this.g,n*this.b)},ia.hsl=function(){return wn(this.r,this.g,this.b)},ia.toString=function(){return"#"+bn(this.r)+bn(this.g)+bn(this.b)};var ua=ao.map({aliceblue:15792383,antiquewhite:16444375,aqua:65535,aquamarine:8388564,azure:15794175,beige:16119260,bisque:16770244,black:0,blanchedalmond:16772045,blue:255,blueviolet:9055202,brown:10824234,burlywood:14596231,cadetblue:6266528,chartreuse:8388352,chocolate:13789470,coral:16744272,cornflowerblue:6591981,cornsilk:16775388,crimson:14423100,cyan:65535,darkblue:139,darkcyan:35723,darkgoldenrod:12092939,darkgray:11119017,darkgreen:25600,darkgrey:11119017,darkkhaki:12433259,darkmagenta:9109643,darkolivegreen:5597999,darkorange:16747520,darkorchid:10040012,darkred:9109504,darksalmon:15308410,darkseagreen:9419919,darkslateblue:4734347,darkslategray:3100495,darkslategrey:3100495,darkturquoise:52945,darkviolet:9699539,deeppink:16716947,deepskyblue:49151,dimgray:6908265,dimgrey:6908265,dodgerblue:2003199,firebrick:11674146,floralwhite:16775920,forestgreen:2263842,fuchsia:16711935,gainsboro:14474460,ghostwhite:16316671,gold:16766720,goldenrod:14329120,gray:8421504,green:32768,greenyellow:11403055,grey:8421504,honeydew:15794160,hotpink:16738740,indianred:13458524,indigo:4915330,ivory:16777200,khaki:15787660,lavender:15132410,lavenderblush:16773365,lawngreen:8190976,lemonchiffon:16775885,lightblue:11393254,lightcoral:15761536,lightcyan:14745599,lightgoldenrodyellow:16448210,lightgray:13882323,lightgreen:9498256,lightgrey:13882323,lightpink:16758465,lightsalmon:16752762,lightseagreen:2142890,lightskyblue:8900346,lightslategray:7833753,lightslategrey:7833753,lightsteelblue:11584734,lightyellow:16777184,lime:65280,limegreen:3329330,linen:16445670,magenta:16711935,maroon:8388608,mediumaquamarine:6737322,mediumblue:205,mediumorchid:12211667,mediumpurple:9662683,mediumseagreen:3978097,mediumslateblue:8087790,mediumspringgreen:64154,mediumturquoise:4772300,mediumvioletred:13047173,midnightblue:1644912,mintcream:16121850,mistyrose:16770273,moccasin:16770229,navajowhite:16768685,navy:128,oldlace:16643558,olive:8421376,olivedrab:7048739,orange:16753920,orangered:16729344,orchid:14315734,palegoldenrod:15657130,palegreen:10025880,paleturquoise:11529966,palevioletred:14381203,papayawhip:16773077,peachpuff:16767673,peru:13468991,pink:16761035,plum:14524637,powderblue:11591910,purple:8388736,rebeccapurple:6697881,red:16711680,rosybrown:12357519,royalblue:4286945,saddlebrown:9127187,salmon:16416882,sandybrown:16032864,seagreen:3050327,seashell:16774638,sienna:10506797,silver:12632256,skyblue:8900331,slateblue:6970061,slategray:7372944,slategrey:7372944,snow:16775930,springgreen:65407,steelblue:4620980,tan:13808780,teal:32896,thistle:14204888,tomato:16737095,turquoise:4251856,violet:15631086,wheat:16113331,white:16777215,whitesmoke:16119285,yellow:16776960,yellowgreen:10145074});ua.forEach(function(n,t){ua.set(n,Mn(t))}),ao.functor=En,ao.xhr=An(m),ao.dsv=function(n,t){function e(n,e,u){arguments.length<3&&(u=e,e=null);var o=Cn(n,t,null==e?r:i(e),u);return o.row=function(n){return arguments.length?o.response(null==(e=n)?r:i(n)):e},o}function r(n){return e.parse(n.responseText)}function i(n){return function(t){return e.parse(t.responseText,n)}}function u(t){return t.map(o).join(n)}function o(n){return a.test(n)?'"'+n.replace(/\"/g,'""')+'"':n}var a=new RegExp('["'+n+"\n]"),l=n.charCodeAt(0);return e.parse=function(n,t){var r;return e.parseRows(n,function(n,e){if(r)return r(n,e-1);var i=new Function("d","return {"+n.map(function(n,t){return JSON.stringify(n)+": d["+t+"]"}).join(",")+"}");r=t?function(n,e){return t(i(n),e)}:i})},e.parseRows=function(n,t){function e(){if(f>=c)return o;if(i)return i=!1,u;var t=f;if(34===n.charCodeAt(t)){for(var e=t;e++f;){var r=n.charCodeAt(f++),a=1;if(10===r)i=!0;else if(13===r)i=!0,10===n.charCodeAt(f)&&(++f,++a);else if(r!==l)continue;return n.slice(t,f-a)}return n.slice(t)}for(var r,i,u={},o={},a=[],c=n.length,f=0,s=0;(r=e())!==o;){for(var h=[];r!==u&&r!==o;)h.push(r),r=e();t&&null==(h=t(h,s++))||a.push(h)}return a},e.format=function(t){if(Array.isArray(t[0]))return e.formatRows(t);var r=new y,i=[];return t.forEach(function(n){for(var t in n)r.has(t)||i.push(r.add(t))}),[i.map(o).join(n)].concat(t.map(function(t){return i.map(function(n){return o(t[n])}).join(n)})).join("\n")},e.formatRows=function(n){return n.map(u).join("\n")},e},ao.csv=ao.dsv(",","text/csv"),ao.tsv=ao.dsv(" ","text/tab-separated-values");var oa,aa,la,ca,fa=this[x(this,"requestAnimationFrame")]||function(n){setTimeout(n,17)};ao.timer=function(){qn.apply(this,arguments)},ao.timer.flush=function(){Rn(),Dn()},ao.round=function(n,t){return t?Math.round(n*(t=Math.pow(10,t)))/t:Math.round(n)};var sa=["y","z","a","f","p","n","\xb5","m","","k","M","G","T","P","E","Z","Y"].map(Un);ao.formatPrefix=function(n,t){var e=0;return(n=+n)&&(0>n&&(n*=-1),t&&(n=ao.round(n,Pn(n,t))),e=1+Math.floor(1e-12+Math.log(n)/Math.LN10),e=Math.max(-24,Math.min(24,3*Math.floor((e-1)/3)))),sa[8+e/3]};var ha=/(?:([^{])?([<>=^]))?([+\- ])?([$#])?(0)?(\d+)?(,)?(\.-?\d+)?([a-z%])?/i,pa=ao.map({b:function(n){return n.toString(2)},c:function(n){return String.fromCharCode(n)},o:function(n){return n.toString(8)},x:function(n){return n.toString(16)},X:function(n){return n.toString(16).toUpperCase()},g:function(n,t){return n.toPrecision(t)},e:function(n,t){return n.toExponential(t)},f:function(n,t){return n.toFixed(t)},r:function(n,t){return(n=ao.round(n,Pn(n,t))).toFixed(Math.max(0,Math.min(20,Pn(n*(1+1e-15),t))))}}),ga=ao.time={},va=Date;Hn.prototype={getDate:function(){return this._.getUTCDate()},getDay:function(){return this._.getUTCDay()},getFullYear:function(){return this._.getUTCFullYear()},getHours:function(){return this._.getUTCHours()},getMilliseconds:function(){return this._.getUTCMilliseconds()},getMinutes:function(){return this._.getUTCMinutes()},getMonth:function(){return this._.getUTCMonth()},getSeconds:function(){return this._.getUTCSeconds()},getTime:function(){return this._.getTime()},getTimezoneOffset:function(){return 0},valueOf:function(){return this._.valueOf()},setDate:function(){da.setUTCDate.apply(this._,arguments)},setDay:function(){da.setUTCDay.apply(this._,arguments)},setFullYear:function(){da.setUTCFullYear.apply(this._,arguments)},setHours:function(){da.setUTCHours.apply(this._,arguments)},setMilliseconds:function(){da.setUTCMilliseconds.apply(this._,arguments)},setMinutes:function(){da.setUTCMinutes.apply(this._,arguments)},setMonth:function(){da.setUTCMonth.apply(this._,arguments)},setSeconds:function(){da.setUTCSeconds.apply(this._,arguments)},setTime:function(){da.setTime.apply(this._,arguments)}};var da=Date.prototype;ga.year=On(function(n){return n=ga.day(n),n.setMonth(0,1),n},function(n,t){n.setFullYear(n.getFullYear()+t)},function(n){return n.getFullYear()}),ga.years=ga.year.range,ga.years.utc=ga.year.utc.range,ga.day=On(function(n){var t=new va(2e3,0);return t.setFullYear(n.getFullYear(),n.getMonth(),n.getDate()),t},function(n,t){n.setDate(n.getDate()+t)},function(n){return n.getDate()-1}),ga.days=ga.day.range,ga.days.utc=ga.day.utc.range,ga.dayOfYear=function(n){var t=ga.year(n);return Math.floor((n-t-6e4*(n.getTimezoneOffset()-t.getTimezoneOffset()))/864e5)},["sunday","monday","tuesday","wednesday","thursday","friday","saturday"].forEach(function(n,t){t=7-t;var e=ga[n]=On(function(n){return(n=ga.day(n)).setDate(n.getDate()-(n.getDay()+t)%7),n},function(n,t){n.setDate(n.getDate()+7*Math.floor(t))},function(n){var e=ga.year(n).getDay();return Math.floor((ga.dayOfYear(n)+(e+t)%7)/7)-(e!==t)});ga[n+"s"]=e.range,ga[n+"s"].utc=e.utc.range,ga[n+"OfYear"]=function(n){var e=ga.year(n).getDay();return Math.floor((ga.dayOfYear(n)+(e+t)%7)/7)}}),ga.week=ga.sunday,ga.weeks=ga.sunday.range,ga.weeks.utc=ga.sunday.utc.range,ga.weekOfYear=ga.sundayOfYear;var ya={"-":"",_:" ",0:"0"},ma=/^\s*\d+/,Ma=/^%/;ao.locale=function(n){return{numberFormat:jn(n),timeFormat:Yn(n)}};var xa=ao.locale({decimal:".",thousands:",",grouping:[3],currency:["$",""],dateTime:"%a %b %e %X %Y",date:"%m/%d/%Y",time:"%H:%M:%S",periods:["AM","PM"],days:["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"], -shortDays:["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],months:["January","February","March","April","May","June","July","August","September","October","November","December"],shortMonths:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"]});ao.format=xa.numberFormat,ao.geo={},ft.prototype={s:0,t:0,add:function(n){st(n,this.t,ba),st(ba.s,this.s,this),this.s?this.t+=ba.t:this.s=ba.t},reset:function(){this.s=this.t=0},valueOf:function(){return this.s}};var ba=new ft;ao.geo.stream=function(n,t){n&&_a.hasOwnProperty(n.type)?_a[n.type](n,t):ht(n,t)};var _a={Feature:function(n,t){ht(n.geometry,t)},FeatureCollection:function(n,t){for(var e=n.features,r=-1,i=e.length;++rn?4*Fo+n:n,Na.lineStart=Na.lineEnd=Na.point=b}};ao.geo.bounds=function(){function n(n,t){M.push(x=[f=n,h=n]),s>t&&(s=t),t>p&&(p=t)}function t(t,e){var r=dt([t*Yo,e*Yo]);if(y){var i=mt(y,r),u=[i[1],-i[0],0],o=mt(u,i);bt(o),o=_t(o);var l=t-g,c=l>0?1:-1,v=o[0]*Zo*c,d=xo(l)>180;if(d^(v>c*g&&c*t>v)){var m=o[1]*Zo;m>p&&(p=m)}else if(v=(v+360)%360-180,d^(v>c*g&&c*t>v)){var m=-o[1]*Zo;s>m&&(s=m)}else s>e&&(s=e),e>p&&(p=e);d?g>t?a(f,t)>a(f,h)&&(h=t):a(t,h)>a(f,h)&&(f=t):h>=f?(f>t&&(f=t),t>h&&(h=t)):t>g?a(f,t)>a(f,h)&&(h=t):a(t,h)>a(f,h)&&(f=t)}else n(t,e);y=r,g=t}function e(){b.point=t}function r(){x[0]=f,x[1]=h,b.point=n,y=null}function i(n,e){if(y){var r=n-g;m+=xo(r)>180?r+(r>0?360:-360):r}else v=n,d=e;Na.point(n,e),t(n,e)}function u(){Na.lineStart()}function o(){i(v,d),Na.lineEnd(),xo(m)>Uo&&(f=-(h=180)),x[0]=f,x[1]=h,y=null}function a(n,t){return(t-=n)<0?t+360:t}function l(n,t){return n[0]-t[0]}function c(n,t){return t[0]<=t[1]?t[0]<=n&&n<=t[1]:nka?(f=-(h=180),s=-(p=90)):m>Uo?p=90:-Uo>m&&(s=-90),x[0]=f,x[1]=h}};return function(n){p=h=-(f=s=1/0),M=[],ao.geo.stream(n,b);var t=M.length;if(t){M.sort(l);for(var e,r=1,i=M[0],u=[i];t>r;++r)e=M[r],c(e[0],i)||c(e[1],i)?(a(i[0],e[1])>a(i[0],i[1])&&(i[1]=e[1]),a(e[0],i[1])>a(i[0],i[1])&&(i[0]=e[0])):u.push(i=e);for(var o,e,g=-(1/0),t=u.length-1,r=0,i=u[t];t>=r;i=e,++r)e=u[r],(o=a(i[1],e[0]))>g&&(g=o,f=e[0],h=i[1])}return M=x=null,f===1/0||s===1/0?[[NaN,NaN],[NaN,NaN]]:[[f,s],[h,p]]}}(),ao.geo.centroid=function(n){Ea=Aa=Ca=za=La=qa=Ta=Ra=Da=Pa=Ua=0,ao.geo.stream(n,ja);var t=Da,e=Pa,r=Ua,i=t*t+e*e+r*r;return jo>i&&(t=qa,e=Ta,r=Ra,Uo>Aa&&(t=Ca,e=za,r=La),i=t*t+e*e+r*r,jo>i)?[NaN,NaN]:[Math.atan2(e,t)*Zo,tn(r/Math.sqrt(i))*Zo]};var Ea,Aa,Ca,za,La,qa,Ta,Ra,Da,Pa,Ua,ja={sphere:b,point:St,lineStart:Nt,lineEnd:Et,polygonStart:function(){ja.lineStart=At},polygonEnd:function(){ja.lineStart=Nt}},Fa=Rt(zt,jt,Ht,[-Fo,-Fo/2]),Ha=1e9;ao.geo.clipExtent=function(){var n,t,e,r,i,u,o={stream:function(n){return i&&(i.valid=!1),i=u(n),i.valid=!0,i},extent:function(a){return arguments.length?(u=Zt(n=+a[0][0],t=+a[0][1],e=+a[1][0],r=+a[1][1]),i&&(i.valid=!1,i=null),o):[[n,t],[e,r]]}};return o.extent([[0,0],[960,500]])},(ao.geo.conicEqualArea=function(){return Vt(Xt)}).raw=Xt,ao.geo.albers=function(){return ao.geo.conicEqualArea().rotate([96,0]).center([-.6,38.7]).parallels([29.5,45.5]).scale(1070)},ao.geo.albersUsa=function(){function n(n){var u=n[0],o=n[1];return t=null,e(u,o),t||(r(u,o),t)||i(u,o),t}var t,e,r,i,u=ao.geo.albers(),o=ao.geo.conicEqualArea().rotate([154,0]).center([-2,58.5]).parallels([55,65]),a=ao.geo.conicEqualArea().rotate([157,0]).center([-3,19.9]).parallels([8,18]),l={point:function(n,e){t=[n,e]}};return n.invert=function(n){var t=u.scale(),e=u.translate(),r=(n[0]-e[0])/t,i=(n[1]-e[1])/t;return(i>=.12&&.234>i&&r>=-.425&&-.214>r?o:i>=.166&&.234>i&&r>=-.214&&-.115>r?a:u).invert(n)},n.stream=function(n){var t=u.stream(n),e=o.stream(n),r=a.stream(n);return{point:function(n,i){t.point(n,i),e.point(n,i),r.point(n,i)},sphere:function(){t.sphere(),e.sphere(),r.sphere()},lineStart:function(){t.lineStart(),e.lineStart(),r.lineStart()},lineEnd:function(){t.lineEnd(),e.lineEnd(),r.lineEnd()},polygonStart:function(){t.polygonStart(),e.polygonStart(),r.polygonStart()},polygonEnd:function(){t.polygonEnd(),e.polygonEnd(),r.polygonEnd()}}},n.precision=function(t){return arguments.length?(u.precision(t),o.precision(t),a.precision(t),n):u.precision()},n.scale=function(t){return arguments.length?(u.scale(t),o.scale(.35*t),a.scale(t),n.translate(u.translate())):u.scale()},n.translate=function(t){if(!arguments.length)return u.translate();var c=u.scale(),f=+t[0],s=+t[1];return e=u.translate(t).clipExtent([[f-.455*c,s-.238*c],[f+.455*c,s+.238*c]]).stream(l).point,r=o.translate([f-.307*c,s+.201*c]).clipExtent([[f-.425*c+Uo,s+.12*c+Uo],[f-.214*c-Uo,s+.234*c-Uo]]).stream(l).point,i=a.translate([f-.205*c,s+.212*c]).clipExtent([[f-.214*c+Uo,s+.166*c+Uo],[f-.115*c-Uo,s+.234*c-Uo]]).stream(l).point,n},n.scale(1070)};var Oa,Ia,Ya,Za,Va,Xa,$a={point:b,lineStart:b,lineEnd:b,polygonStart:function(){Ia=0,$a.lineStart=$t},polygonEnd:function(){$a.lineStart=$a.lineEnd=$a.point=b,Oa+=xo(Ia/2)}},Ba={point:Bt,lineStart:b,lineEnd:b,polygonStart:b,polygonEnd:b},Wa={point:Gt,lineStart:Kt,lineEnd:Qt,polygonStart:function(){Wa.lineStart=ne},polygonEnd:function(){Wa.point=Gt,Wa.lineStart=Kt,Wa.lineEnd=Qt}};ao.geo.path=function(){function n(n){return n&&("function"==typeof a&&u.pointRadius(+a.apply(this,arguments)),o&&o.valid||(o=i(u)),ao.geo.stream(n,o)),u.result()}function t(){return o=null,n}var e,r,i,u,o,a=4.5;return n.area=function(n){return Oa=0,ao.geo.stream(n,i($a)),Oa},n.centroid=function(n){return Ca=za=La=qa=Ta=Ra=Da=Pa=Ua=0,ao.geo.stream(n,i(Wa)),Ua?[Da/Ua,Pa/Ua]:Ra?[qa/Ra,Ta/Ra]:La?[Ca/La,za/La]:[NaN,NaN]},n.bounds=function(n){return Va=Xa=-(Ya=Za=1/0),ao.geo.stream(n,i(Ba)),[[Ya,Za],[Va,Xa]]},n.projection=function(n){return arguments.length?(i=(e=n)?n.stream||re(n):m,t()):e},n.context=function(n){return arguments.length?(u=null==(r=n)?new Wt:new te(n),"function"!=typeof a&&u.pointRadius(a),t()):r},n.pointRadius=function(t){return arguments.length?(a="function"==typeof t?t:(u.pointRadius(+t),+t),n):a},n.projection(ao.geo.albersUsa()).context(null)},ao.geo.transform=function(n){return{stream:function(t){var e=new ie(t);for(var r in n)e[r]=n[r];return e}}},ie.prototype={point:function(n,t){this.stream.point(n,t)},sphere:function(){this.stream.sphere()},lineStart:function(){this.stream.lineStart()},lineEnd:function(){this.stream.lineEnd()},polygonStart:function(){this.stream.polygonStart()},polygonEnd:function(){this.stream.polygonEnd()}},ao.geo.projection=oe,ao.geo.projectionMutator=ae,(ao.geo.equirectangular=function(){return oe(ce)}).raw=ce.invert=ce,ao.geo.rotation=function(n){function t(t){return t=n(t[0]*Yo,t[1]*Yo),t[0]*=Zo,t[1]*=Zo,t}return n=se(n[0]%360*Yo,n[1]*Yo,n.length>2?n[2]*Yo:0),t.invert=function(t){return t=n.invert(t[0]*Yo,t[1]*Yo),t[0]*=Zo,t[1]*=Zo,t},t},fe.invert=ce,ao.geo.circle=function(){function n(){var n="function"==typeof r?r.apply(this,arguments):r,t=se(-n[0]*Yo,-n[1]*Yo,0).invert,i=[];return e(null,null,1,{point:function(n,e){i.push(n=t(n,e)),n[0]*=Zo,n[1]*=Zo}}),{type:"Polygon",coordinates:[i]}}var t,e,r=[0,0],i=6;return n.origin=function(t){return arguments.length?(r=t,n):r},n.angle=function(r){return arguments.length?(e=ve((t=+r)*Yo,i*Yo),n):t},n.precision=function(r){return arguments.length?(e=ve(t*Yo,(i=+r)*Yo),n):i},n.angle(90)},ao.geo.distance=function(n,t){var e,r=(t[0]-n[0])*Yo,i=n[1]*Yo,u=t[1]*Yo,o=Math.sin(r),a=Math.cos(r),l=Math.sin(i),c=Math.cos(i),f=Math.sin(u),s=Math.cos(u);return Math.atan2(Math.sqrt((e=s*o)*e+(e=c*f-l*s*a)*e),l*f+c*s*a)},ao.geo.graticule=function(){function n(){return{type:"MultiLineString",coordinates:t()}}function t(){return ao.range(Math.ceil(u/d)*d,i,d).map(h).concat(ao.range(Math.ceil(c/y)*y,l,y).map(p)).concat(ao.range(Math.ceil(r/g)*g,e,g).filter(function(n){return xo(n%d)>Uo}).map(f)).concat(ao.range(Math.ceil(a/v)*v,o,v).filter(function(n){return xo(n%y)>Uo}).map(s))}var e,r,i,u,o,a,l,c,f,s,h,p,g=10,v=g,d=90,y=360,m=2.5;return n.lines=function(){return t().map(function(n){return{type:"LineString",coordinates:n}})},n.outline=function(){return{type:"Polygon",coordinates:[h(u).concat(p(l).slice(1),h(i).reverse().slice(1),p(c).reverse().slice(1))]}},n.extent=function(t){return arguments.length?n.majorExtent(t).minorExtent(t):n.minorExtent()},n.majorExtent=function(t){return arguments.length?(u=+t[0][0],i=+t[1][0],c=+t[0][1],l=+t[1][1],u>i&&(t=u,u=i,i=t),c>l&&(t=c,c=l,l=t),n.precision(m)):[[u,c],[i,l]]},n.minorExtent=function(t){return arguments.length?(r=+t[0][0],e=+t[1][0],a=+t[0][1],o=+t[1][1],r>e&&(t=r,r=e,e=t),a>o&&(t=a,a=o,o=t),n.precision(m)):[[r,a],[e,o]]},n.step=function(t){return arguments.length?n.majorStep(t).minorStep(t):n.minorStep()},n.majorStep=function(t){return arguments.length?(d=+t[0],y=+t[1],n):[d,y]},n.minorStep=function(t){return arguments.length?(g=+t[0],v=+t[1],n):[g,v]},n.precision=function(t){return arguments.length?(m=+t,f=ye(a,o,90),s=me(r,e,m),h=ye(c,l,90),p=me(u,i,m),n):m},n.majorExtent([[-180,-90+Uo],[180,90-Uo]]).minorExtent([[-180,-80-Uo],[180,80+Uo]])},ao.geo.greatArc=function(){function n(){return{type:"LineString",coordinates:[t||r.apply(this,arguments),e||i.apply(this,arguments)]}}var t,e,r=Me,i=xe;return n.distance=function(){return ao.geo.distance(t||r.apply(this,arguments),e||i.apply(this,arguments))},n.source=function(e){return arguments.length?(r=e,t="function"==typeof e?null:e,n):r},n.target=function(t){return arguments.length?(i=t,e="function"==typeof t?null:t,n):i},n.precision=function(){return arguments.length?n:0},n},ao.geo.interpolate=function(n,t){return be(n[0]*Yo,n[1]*Yo,t[0]*Yo,t[1]*Yo)},ao.geo.length=function(n){return Ja=0,ao.geo.stream(n,Ga),Ja};var Ja,Ga={sphere:b,point:b,lineStart:_e,lineEnd:b,polygonStart:b,polygonEnd:b},Ka=we(function(n){return Math.sqrt(2/(1+n))},function(n){return 2*Math.asin(n/2)});(ao.geo.azimuthalEqualArea=function(){return oe(Ka)}).raw=Ka;var Qa=we(function(n){var t=Math.acos(n);return t&&t/Math.sin(t)},m);(ao.geo.azimuthalEquidistant=function(){return oe(Qa)}).raw=Qa,(ao.geo.conicConformal=function(){return Vt(Se)}).raw=Se,(ao.geo.conicEquidistant=function(){return Vt(ke)}).raw=ke;var nl=we(function(n){return 1/n},Math.atan);(ao.geo.gnomonic=function(){return oe(nl)}).raw=nl,Ne.invert=function(n,t){return[n,2*Math.atan(Math.exp(t))-Io]},(ao.geo.mercator=function(){return Ee(Ne)}).raw=Ne;var tl=we(function(){return 1},Math.asin);(ao.geo.orthographic=function(){return oe(tl)}).raw=tl;var el=we(function(n){return 1/(1+n)},function(n){return 2*Math.atan(n)});(ao.geo.stereographic=function(){return oe(el)}).raw=el,Ae.invert=function(n,t){return[-t,2*Math.atan(Math.exp(n))-Io]},(ao.geo.transverseMercator=function(){var n=Ee(Ae),t=n.center,e=n.rotate;return n.center=function(n){return n?t([-n[1],n[0]]):(n=t(),[n[1],-n[0]])},n.rotate=function(n){return n?e([n[0],n[1],n.length>2?n[2]+90:90]):(n=e(),[n[0],n[1],n[2]-90])},e([0,0,90])}).raw=Ae,ao.geom={},ao.geom.hull=function(n){function t(n){if(n.length<3)return[];var t,i=En(e),u=En(r),o=n.length,a=[],l=[];for(t=0;o>t;t++)a.push([+i.call(this,n[t],t),+u.call(this,n[t],t),t]);for(a.sort(qe),t=0;o>t;t++)l.push([a[t][0],-a[t][1]]);var c=Le(a),f=Le(l),s=f[0]===c[0],h=f[f.length-1]===c[c.length-1],p=[];for(t=c.length-1;t>=0;--t)p.push(n[a[c[t]][2]]);for(t=+s;t=r&&c.x<=u&&c.y>=i&&c.y<=o?[[r,o],[u,o],[u,i],[r,i]]:[];f.point=n[a]}),t}function e(n){return n.map(function(n,t){return{x:Math.round(u(n,t)/Uo)*Uo,y:Math.round(o(n,t)/Uo)*Uo,i:t}})}var r=Ce,i=ze,u=r,o=i,a=sl;return n?t(n):(t.links=function(n){return ar(e(n)).edges.filter(function(n){return n.l&&n.r}).map(function(t){return{source:n[t.l.i],target:n[t.r.i]}})},t.triangles=function(n){var t=[];return ar(e(n)).cells.forEach(function(e,r){for(var i,u,o=e.site,a=e.edges.sort(Ve),l=-1,c=a.length,f=a[c-1].edge,s=f.l===o?f.r:f.l;++l=c,h=r>=f,p=h<<1|s;n.leaf=!1,n=n.nodes[p]||(n.nodes[p]=hr()),s?i=c:a=c,h?o=f:l=f,u(n,t,e,r,i,o,a,l)}var f,s,h,p,g,v,d,y,m,M=En(a),x=En(l);if(null!=t)v=t,d=e,y=r,m=i;else if(y=m=-(v=d=1/0),s=[],h=[],g=n.length,o)for(p=0;g>p;++p)f=n[p],f.xy&&(y=f.x),f.y>m&&(m=f.y),s.push(f.x),h.push(f.y);else for(p=0;g>p;++p){var b=+M(f=n[p],p),_=+x(f,p);v>b&&(v=b),d>_&&(d=_),b>y&&(y=b),_>m&&(m=_),s.push(b),h.push(_)}var w=y-v,S=m-d;w>S?m=d+w:y=v+S;var k=hr();if(k.add=function(n){u(k,n,+M(n,++p),+x(n,p),v,d,y,m)},k.visit=function(n){pr(n,k,v,d,y,m)},k.find=function(n){return gr(k,n[0],n[1],v,d,y,m)},p=-1,null==t){for(;++p=0?n.slice(0,t):n,r=t>=0?n.slice(t+1):"in";return e=vl.get(e)||gl,r=dl.get(r)||m,br(r(e.apply(null,lo.call(arguments,1))))},ao.interpolateHcl=Rr,ao.interpolateHsl=Dr,ao.interpolateLab=Pr,ao.interpolateRound=Ur,ao.transform=function(n){var t=fo.createElementNS(ao.ns.prefix.svg,"g");return(ao.transform=function(n){if(null!=n){t.setAttribute("transform",n);var e=t.transform.baseVal.consolidate()}return new jr(e?e.matrix:yl)})(n)},jr.prototype.toString=function(){return"translate("+this.translate+")rotate("+this.rotate+")skewX("+this.skew+")scale("+this.scale+")"};var yl={a:1,b:0,c:0,d:1,e:0,f:0};ao.interpolateTransform=$r,ao.layout={},ao.layout.bundle=function(){return function(n){for(var t=[],e=-1,r=n.length;++ea*a/y){if(v>l){var c=t.charge/l;n.px-=u*c,n.py-=o*c}return!0}if(t.point&&l&&v>l){var c=t.pointCharge/l;n.px-=u*c,n.py-=o*c}}return!t.charge}}function t(n){n.px=ao.event.x,n.py=ao.event.y,l.resume()}var e,r,i,u,o,a,l={},c=ao.dispatch("start","tick","end"),f=[1,1],s=.9,h=ml,p=Ml,g=-30,v=xl,d=.1,y=.64,M=[],x=[];return l.tick=function(){if((i*=.99)<.005)return e=null,c.end({type:"end",alpha:i=0}),!0;var t,r,l,h,p,v,y,m,b,_=M.length,w=x.length;for(r=0;w>r;++r)l=x[r],h=l.source,p=l.target,m=p.x-h.x,b=p.y-h.y,(v=m*m+b*b)&&(v=i*o[r]*((v=Math.sqrt(v))-u[r])/v,m*=v,b*=v,p.x-=m*(y=h.weight+p.weight?h.weight/(h.weight+p.weight):.5),p.y-=b*y,h.x+=m*(y=1-y),h.y+=b*y);if((y=i*d)&&(m=f[0]/2,b=f[1]/2,r=-1,y))for(;++r<_;)l=M[r],l.x+=(m-l.x)*y,l.y+=(b-l.y)*y;if(g)for(ri(t=ao.geom.quadtree(M),i,a),r=-1;++r<_;)(l=M[r]).fixed||t.visit(n(l));for(r=-1;++r<_;)l=M[r],l.fixed?(l.x=l.px,l.y=l.py):(l.x-=(l.px-(l.px=l.x))*s,l.y-=(l.py-(l.py=l.y))*s);c.tick({type:"tick",alpha:i})},l.nodes=function(n){return arguments.length?(M=n,l):M},l.links=function(n){return arguments.length?(x=n,l):x},l.size=function(n){return arguments.length?(f=n,l):f},l.linkDistance=function(n){return arguments.length?(h="function"==typeof n?n:+n,l):h},l.distance=l.linkDistance,l.linkStrength=function(n){return arguments.length?(p="function"==typeof n?n:+n,l):p},l.friction=function(n){return arguments.length?(s=+n,l):s},l.charge=function(n){return arguments.length?(g="function"==typeof n?n:+n,l):g},l.chargeDistance=function(n){return arguments.length?(v=n*n,l):Math.sqrt(v)},l.gravity=function(n){return arguments.length?(d=+n,l):d},l.theta=function(n){return arguments.length?(y=n*n,l):Math.sqrt(y)},l.alpha=function(n){return arguments.length?(n=+n,i?n>0?i=n:(e.c=null,e.t=NaN,e=null,c.end({type:"end",alpha:i=0})):n>0&&(c.start({type:"start",alpha:i=n}),e=qn(l.tick)),l):i},l.start=function(){function n(n,r){if(!e){for(e=new Array(i),l=0;i>l;++l)e[l]=[];for(l=0;c>l;++l){var u=x[l];e[u.source.index].push(u.target),e[u.target.index].push(u.source)}}for(var o,a=e[t],l=-1,f=a.length;++lt;++t)(r=M[t]).index=t,r.weight=0;for(t=0;c>t;++t)r=x[t],"number"==typeof r.source&&(r.source=M[r.source]),"number"==typeof r.target&&(r.target=M[r.target]),++r.source.weight,++r.target.weight;for(t=0;i>t;++t)r=M[t],isNaN(r.x)&&(r.x=n("x",s)),isNaN(r.y)&&(r.y=n("y",v)),isNaN(r.px)&&(r.px=r.x),isNaN(r.py)&&(r.py=r.y);if(u=[],"function"==typeof h)for(t=0;c>t;++t)u[t]=+h.call(this,x[t],t);else for(t=0;c>t;++t)u[t]=h;if(o=[],"function"==typeof p)for(t=0;c>t;++t)o[t]=+p.call(this,x[t],t);else for(t=0;c>t;++t)o[t]=p;if(a=[],"function"==typeof g)for(t=0;i>t;++t)a[t]=+g.call(this,M[t],t);else for(t=0;i>t;++t)a[t]=g;return l.resume()},l.resume=function(){return l.alpha(.1)},l.stop=function(){return l.alpha(0)},l.drag=function(){return r||(r=ao.behavior.drag().origin(m).on("dragstart.force",Qr).on("drag.force",t).on("dragend.force",ni)),arguments.length?void this.on("mouseover.force",ti).on("mouseout.force",ei).call(r):r},ao.rebind(l,c,"on")};var ml=20,Ml=1,xl=1/0;ao.layout.hierarchy=function(){function n(i){var u,o=[i],a=[];for(i.depth=0;null!=(u=o.pop());)if(a.push(u),(c=e.call(n,u,u.depth))&&(l=c.length)){for(var l,c,f;--l>=0;)o.push(f=c[l]),f.parent=u,f.depth=u.depth+1;r&&(u.value=0),u.children=c}else r&&(u.value=+r.call(n,u,u.depth)||0),delete u.children;return oi(i,function(n){var e,i;t&&(e=n.children)&&e.sort(t),r&&(i=n.parent)&&(i.value+=n.value)}),a}var t=ci,e=ai,r=li;return n.sort=function(e){return arguments.length?(t=e,n):t},n.children=function(t){return arguments.length?(e=t,n):e},n.value=function(t){return arguments.length?(r=t,n):r},n.revalue=function(t){return r&&(ui(t,function(n){n.children&&(n.value=0)}),oi(t,function(t){var e;t.children||(t.value=+r.call(n,t,t.depth)||0),(e=t.parent)&&(e.value+=t.value)})),t},n},ao.layout.partition=function(){function n(t,e,r,i){var u=t.children;if(t.x=e,t.y=t.depth*i,t.dx=r,t.dy=i,u&&(o=u.length)){var o,a,l,c=-1;for(r=t.value?r/t.value:0;++cs?-1:1),g=ao.sum(c),v=g?(s-l*p)/g:0,d=ao.range(l),y=[];return null!=e&&d.sort(e===bl?function(n,t){return c[t]-c[n]}:function(n,t){return e(o[n],o[t])}),d.forEach(function(n){y[n]={data:o[n],value:a=c[n],startAngle:f,endAngle:f+=a*v+p,padAngle:h}}),y}var t=Number,e=bl,r=0,i=Ho,u=0;return n.value=function(e){return arguments.length?(t=e,n):t},n.sort=function(t){return arguments.length?(e=t,n):e},n.startAngle=function(t){return arguments.length?(r=t,n):r},n.endAngle=function(t){return arguments.length?(i=t,n):i},n.padAngle=function(t){return arguments.length?(u=t,n):u},n};var bl={};ao.layout.stack=function(){function n(a,l){if(!(h=a.length))return a;var c=a.map(function(e,r){return t.call(n,e,r)}),f=c.map(function(t){return t.map(function(t,e){return[u.call(n,t,e),o.call(n,t,e)]})}),s=e.call(n,f,l);c=ao.permute(c,s),f=ao.permute(f,s);var h,p,g,v,d=r.call(n,f,l),y=c[0].length;for(g=0;y>g;++g)for(i.call(n,c[0][g],v=d[g],f[0][g][1]),p=1;h>p;++p)i.call(n,c[p][g],v+=f[p-1][g][1],f[p][g][1]);return a}var t=m,e=gi,r=vi,i=pi,u=si,o=hi;return n.values=function(e){return arguments.length?(t=e,n):t},n.order=function(t){return arguments.length?(e="function"==typeof t?t:_l.get(t)||gi,n):e},n.offset=function(t){return arguments.length?(r="function"==typeof t?t:wl.get(t)||vi,n):r},n.x=function(t){return arguments.length?(u=t,n):u},n.y=function(t){return arguments.length?(o=t,n):o},n.out=function(t){return arguments.length?(i=t,n):i},n};var _l=ao.map({"inside-out":function(n){var t,e,r=n.length,i=n.map(di),u=n.map(yi),o=ao.range(r).sort(function(n,t){return i[n]-i[t]}),a=0,l=0,c=[],f=[];for(t=0;r>t;++t)e=o[t],l>a?(a+=u[e],c.push(e)):(l+=u[e],f.push(e));return f.reverse().concat(c)},reverse:function(n){return ao.range(n.length).reverse()},"default":gi}),wl=ao.map({silhouette:function(n){var t,e,r,i=n.length,u=n[0].length,o=[],a=0,l=[];for(e=0;u>e;++e){for(t=0,r=0;i>t;t++)r+=n[t][e][1];r>a&&(a=r),o.push(r)}for(e=0;u>e;++e)l[e]=(a-o[e])/2;return l},wiggle:function(n){var t,e,r,i,u,o,a,l,c,f=n.length,s=n[0],h=s.length,p=[];for(p[0]=l=c=0,e=1;h>e;++e){for(t=0,i=0;f>t;++t)i+=n[t][e][1];for(t=0,u=0,a=s[e][0]-s[e-1][0];f>t;++t){for(r=0,o=(n[t][e][1]-n[t][e-1][1])/(2*a);t>r;++r)o+=(n[r][e][1]-n[r][e-1][1])/a;u+=o*n[t][e][1]}p[e]=l-=i?u/i*a:0,c>l&&(c=l)}for(e=0;h>e;++e)p[e]-=c;return p},expand:function(n){var t,e,r,i=n.length,u=n[0].length,o=1/i,a=[];for(e=0;u>e;++e){for(t=0,r=0;i>t;t++)r+=n[t][e][1];if(r)for(t=0;i>t;t++)n[t][e][1]/=r;else for(t=0;i>t;t++)n[t][e][1]=o}for(e=0;u>e;++e)a[e]=0;return a},zero:vi});ao.layout.histogram=function(){function n(n,u){for(var o,a,l=[],c=n.map(e,this),f=r.call(this,c,u),s=i.call(this,f,c,u),u=-1,h=c.length,p=s.length-1,g=t?1:1/h;++u0)for(u=-1;++u=f[0]&&a<=f[1]&&(o=l[ao.bisect(s,a,1,p)-1],o.y+=g,o.push(n[u]));return l}var t=!0,e=Number,r=bi,i=Mi;return n.value=function(t){return arguments.length?(e=t,n):e},n.range=function(t){return arguments.length?(r=En(t),n):r},n.bins=function(t){return arguments.length?(i="number"==typeof t?function(n){return xi(n,t)}:En(t),n):i},n.frequency=function(e){return arguments.length?(t=!!e,n):t},n},ao.layout.pack=function(){function n(n,u){var o=e.call(this,n,u),a=o[0],l=i[0],c=i[1],f=null==t?Math.sqrt:"function"==typeof t?t:function(){return t};if(a.x=a.y=0,oi(a,function(n){n.r=+f(n.value)}),oi(a,Ni),r){var s=r*(t?1:Math.max(2*a.r/l,2*a.r/c))/2;oi(a,function(n){n.r+=s}),oi(a,Ni),oi(a,function(n){n.r-=s})}return Ci(a,l/2,c/2,t?1:1/Math.max(2*a.r/l,2*a.r/c)),o}var t,e=ao.layout.hierarchy().sort(_i),r=0,i=[1,1];return n.size=function(t){return arguments.length?(i=t,n):i},n.radius=function(e){return arguments.length?(t=null==e||"function"==typeof e?e:+e,n):t},n.padding=function(t){return arguments.length?(r=+t,n):r},ii(n,e)},ao.layout.tree=function(){function n(n,i){var f=o.call(this,n,i),s=f[0],h=t(s);if(oi(h,e),h.parent.m=-h.z,ui(h,r),c)ui(s,u);else{var p=s,g=s,v=s;ui(s,function(n){n.xg.x&&(g=n),n.depth>v.depth&&(v=n)});var d=a(p,g)/2-p.x,y=l[0]/(g.x+a(g,p)/2+d),m=l[1]/(v.depth||1);ui(s,function(n){n.x=(n.x+d)*y,n.y=n.depth*m})}return f}function t(n){for(var t,e={A:null,children:[n]},r=[e];null!=(t=r.pop());)for(var i,u=t.children,o=0,a=u.length;a>o;++o)r.push((u[o]=i={_:u[o],parent:t,children:(i=u[o].children)&&i.slice()||[],A:null,a:null,z:0,m:0,c:0,s:0,t:null,i:o}).a=i);return e.children[0]}function e(n){var t=n.children,e=n.parent.children,r=n.i?e[n.i-1]:null;if(t.length){Di(n);var u=(t[0].z+t[t.length-1].z)/2;r?(n.z=r.z+a(n._,r._),n.m=n.z-u):n.z=u}else r&&(n.z=r.z+a(n._,r._));n.parent.A=i(n,r,n.parent.A||e[0])}function r(n){n._.x=n.z+n.parent.m,n.m+=n.parent.m}function i(n,t,e){if(t){for(var r,i=n,u=n,o=t,l=i.parent.children[0],c=i.m,f=u.m,s=o.m,h=l.m;o=Ti(o),i=qi(i),o&&i;)l=qi(l),u=Ti(u),u.a=n,r=o.z+s-i.z-c+a(o._,i._),r>0&&(Ri(Pi(o,n,e),n,r),c+=r,f+=r),s+=o.m,c+=i.m,h+=l.m,f+=u.m;o&&!Ti(u)&&(u.t=o,u.m+=s-f),i&&!qi(l)&&(l.t=i,l.m+=c-h,e=n)}return e}function u(n){n.x*=l[0],n.y=n.depth*l[1]}var o=ao.layout.hierarchy().sort(null).value(null),a=Li,l=[1,1],c=null;return n.separation=function(t){return arguments.length?(a=t,n):a},n.size=function(t){return arguments.length?(c=null==(l=t)?u:null,n):c?null:l},n.nodeSize=function(t){return arguments.length?(c=null==(l=t)?null:u,n):c?l:null},ii(n,o)},ao.layout.cluster=function(){function n(n,u){var o,a=t.call(this,n,u),l=a[0],c=0;oi(l,function(n){var t=n.children;t&&t.length?(n.x=ji(t),n.y=Ui(t)):(n.x=o?c+=e(n,o):0,n.y=0,o=n)});var f=Fi(l),s=Hi(l),h=f.x-e(f,s)/2,p=s.x+e(s,f)/2;return oi(l,i?function(n){n.x=(n.x-l.x)*r[0],n.y=(l.y-n.y)*r[1]}:function(n){n.x=(n.x-h)/(p-h)*r[0],n.y=(1-(l.y?n.y/l.y:1))*r[1]}),a}var t=ao.layout.hierarchy().sort(null).value(null),e=Li,r=[1,1],i=!1;return n.separation=function(t){return arguments.length?(e=t,n):e},n.size=function(t){return arguments.length?(i=null==(r=t),n):i?null:r},n.nodeSize=function(t){return arguments.length?(i=null!=(r=t),n):i?r:null},ii(n,t)},ao.layout.treemap=function(){function n(n,t){for(var e,r,i=-1,u=n.length;++it?0:t),e.area=isNaN(r)||0>=r?0:r}function t(e){var u=e.children;if(u&&u.length){var o,a,l,c=s(e),f=[],h=u.slice(),g=1/0,v="slice"===p?c.dx:"dice"===p?c.dy:"slice-dice"===p?1&e.depth?c.dy:c.dx:Math.min(c.dx,c.dy);for(n(h,c.dx*c.dy/e.value),f.area=0;(l=h.length)>0;)f.push(o=h[l-1]),f.area+=o.area,"squarify"!==p||(a=r(f,v))<=g?(h.pop(),g=a):(f.area-=f.pop().area,i(f,v,c,!1),v=Math.min(c.dx,c.dy),f.length=f.area=0,g=1/0);f.length&&(i(f,v,c,!0),f.length=f.area=0),u.forEach(t)}}function e(t){var r=t.children;if(r&&r.length){var u,o=s(t),a=r.slice(),l=[];for(n(a,o.dx*o.dy/t.value),l.area=0;u=a.pop();)l.push(u),l.area+=u.area,null!=u.z&&(i(l,u.z?o.dx:o.dy,o,!a.length),l.length=l.area=0);r.forEach(e)}}function r(n,t){for(var e,r=n.area,i=0,u=1/0,o=-1,a=n.length;++oe&&(u=e),e>i&&(i=e));return r*=r,t*=t,r?Math.max(t*i*g/r,r/(t*u*g)):1/0}function i(n,t,e,r){var i,u=-1,o=n.length,a=e.x,c=e.y,f=t?l(n.area/t):0; -if(t==e.dx){for((r||f>e.dy)&&(f=e.dy);++ue.dx)&&(f=e.dx);++ue&&(t=1),1>e&&(n=0),function(){var e,r,i;do e=2*Math.random()-1,r=2*Math.random()-1,i=e*e+r*r;while(!i||i>1);return n+t*e*Math.sqrt(-2*Math.log(i)/i)}},logNormal:function(){var n=ao.random.normal.apply(ao,arguments);return function(){return Math.exp(n())}},bates:function(n){var t=ao.random.irwinHall(n);return function(){return t()/n}},irwinHall:function(n){return function(){for(var t=0,e=0;n>e;e++)t+=Math.random();return t}}},ao.scale={};var Sl={floor:m,ceil:m};ao.scale.linear=function(){return Wi([0,1],[0,1],Mr,!1)};var kl={s:1,g:1,p:1,r:1,e:1};ao.scale.log=function(){return ru(ao.scale.linear().domain([0,1]),10,!0,[1,10])};var Nl=ao.format(".0e"),El={floor:function(n){return-Math.ceil(-n)},ceil:function(n){return-Math.floor(-n)}};ao.scale.pow=function(){return iu(ao.scale.linear(),1,[0,1])},ao.scale.sqrt=function(){return ao.scale.pow().exponent(.5)},ao.scale.ordinal=function(){return ou([],{t:"range",a:[[]]})},ao.scale.category10=function(){return ao.scale.ordinal().range(Al)},ao.scale.category20=function(){return ao.scale.ordinal().range(Cl)},ao.scale.category20b=function(){return ao.scale.ordinal().range(zl)},ao.scale.category20c=function(){return ao.scale.ordinal().range(Ll)};var Al=[2062260,16744206,2924588,14034728,9725885,9197131,14907330,8355711,12369186,1556175].map(xn),Cl=[2062260,11454440,16744206,16759672,2924588,10018698,14034728,16750742,9725885,12955861,9197131,12885140,14907330,16234194,8355711,13092807,12369186,14408589,1556175,10410725].map(xn),zl=[3750777,5395619,7040719,10264286,6519097,9216594,11915115,13556636,9202993,12426809,15186514,15190932,8666169,11356490,14049643,15177372,8077683,10834324,13528509,14589654].map(xn),Ll=[3244733,7057110,10406625,13032431,15095053,16616764,16625259,16634018,3253076,7652470,10607003,13101504,7695281,10394312,12369372,14342891,6513507,9868950,12434877,14277081].map(xn);ao.scale.quantile=function(){return au([],[])},ao.scale.quantize=function(){return lu(0,1,[0,1])},ao.scale.threshold=function(){return cu([.5],[0,1])},ao.scale.identity=function(){return fu([0,1])},ao.svg={},ao.svg.arc=function(){function n(){var n=Math.max(0,+e.apply(this,arguments)),c=Math.max(0,+r.apply(this,arguments)),f=o.apply(this,arguments)-Io,s=a.apply(this,arguments)-Io,h=Math.abs(s-f),p=f>s?0:1;if(n>c&&(g=c,c=n,n=g),h>=Oo)return t(c,p)+(n?t(n,1-p):"")+"Z";var g,v,d,y,m,M,x,b,_,w,S,k,N=0,E=0,A=[];if((y=(+l.apply(this,arguments)||0)/2)&&(d=u===ql?Math.sqrt(n*n+c*c):+u.apply(this,arguments),p||(E*=-1),c&&(E=tn(d/c*Math.sin(y))),n&&(N=tn(d/n*Math.sin(y)))),c){m=c*Math.cos(f+E),M=c*Math.sin(f+E),x=c*Math.cos(s-E),b=c*Math.sin(s-E);var C=Math.abs(s-f-2*E)<=Fo?0:1;if(E&&yu(m,M,x,b)===p^C){var z=(f+s)/2;m=c*Math.cos(z),M=c*Math.sin(z),x=b=null}}else m=M=0;if(n){_=n*Math.cos(s-N),w=n*Math.sin(s-N),S=n*Math.cos(f+N),k=n*Math.sin(f+N);var L=Math.abs(f-s+2*N)<=Fo?0:1;if(N&&yu(_,w,S,k)===1-p^L){var q=(f+s)/2;_=n*Math.cos(q),w=n*Math.sin(q),S=k=null}}else _=w=0;if(h>Uo&&(g=Math.min(Math.abs(c-n)/2,+i.apply(this,arguments)))>.001){v=c>n^p?0:1;var T=g,R=g;if(Fo>h){var D=null==S?[_,w]:null==x?[m,M]:Re([m,M],[S,k],[x,b],[_,w]),P=m-D[0],U=M-D[1],j=x-D[0],F=b-D[1],H=1/Math.sin(Math.acos((P*j+U*F)/(Math.sqrt(P*P+U*U)*Math.sqrt(j*j+F*F)))/2),O=Math.sqrt(D[0]*D[0]+D[1]*D[1]);R=Math.min(g,(n-O)/(H-1)),T=Math.min(g,(c-O)/(H+1))}if(null!=x){var I=mu(null==S?[_,w]:[S,k],[m,M],c,T,p),Y=mu([x,b],[_,w],c,T,p);g===T?A.push("M",I[0],"A",T,",",T," 0 0,",v," ",I[1],"A",c,",",c," 0 ",1-p^yu(I[1][0],I[1][1],Y[1][0],Y[1][1]),",",p," ",Y[1],"A",T,",",T," 0 0,",v," ",Y[0]):A.push("M",I[0],"A",T,",",T," 0 1,",v," ",Y[0])}else A.push("M",m,",",M);if(null!=S){var Z=mu([m,M],[S,k],n,-R,p),V=mu([_,w],null==x?[m,M]:[x,b],n,-R,p);g===R?A.push("L",V[0],"A",R,",",R," 0 0,",v," ",V[1],"A",n,",",n," 0 ",p^yu(V[1][0],V[1][1],Z[1][0],Z[1][1]),",",1-p," ",Z[1],"A",R,",",R," 0 0,",v," ",Z[0]):A.push("L",V[0],"A",R,",",R," 0 0,",v," ",Z[0])}else A.push("L",_,",",w)}else A.push("M",m,",",M),null!=x&&A.push("A",c,",",c," 0 ",C,",",p," ",x,",",b),A.push("L",_,",",w),null!=S&&A.push("A",n,",",n," 0 ",L,",",1-p," ",S,",",k);return A.push("Z"),A.join("")}function t(n,t){return"M0,"+n+"A"+n+","+n+" 0 1,"+t+" 0,"+-n+"A"+n+","+n+" 0 1,"+t+" 0,"+n}var e=hu,r=pu,i=su,u=ql,o=gu,a=vu,l=du;return n.innerRadius=function(t){return arguments.length?(e=En(t),n):e},n.outerRadius=function(t){return arguments.length?(r=En(t),n):r},n.cornerRadius=function(t){return arguments.length?(i=En(t),n):i},n.padRadius=function(t){return arguments.length?(u=t==ql?ql:En(t),n):u},n.startAngle=function(t){return arguments.length?(o=En(t),n):o},n.endAngle=function(t){return arguments.length?(a=En(t),n):a},n.padAngle=function(t){return arguments.length?(l=En(t),n):l},n.centroid=function(){var n=(+e.apply(this,arguments)+ +r.apply(this,arguments))/2,t=(+o.apply(this,arguments)+ +a.apply(this,arguments))/2-Io;return[Math.cos(t)*n,Math.sin(t)*n]},n};var ql="auto";ao.svg.line=function(){return Mu(m)};var Tl=ao.map({linear:xu,"linear-closed":bu,step:_u,"step-before":wu,"step-after":Su,basis:zu,"basis-open":Lu,"basis-closed":qu,bundle:Tu,cardinal:Eu,"cardinal-open":ku,"cardinal-closed":Nu,monotone:Fu});Tl.forEach(function(n,t){t.key=n,t.closed=/-closed$/.test(n)});var Rl=[0,2/3,1/3,0],Dl=[0,1/3,2/3,0],Pl=[0,1/6,2/3,1/6];ao.svg.line.radial=function(){var n=Mu(Hu);return n.radius=n.x,delete n.x,n.angle=n.y,delete n.y,n},wu.reverse=Su,Su.reverse=wu,ao.svg.area=function(){return Ou(m)},ao.svg.area.radial=function(){var n=Ou(Hu);return n.radius=n.x,delete n.x,n.innerRadius=n.x0,delete n.x0,n.outerRadius=n.x1,delete n.x1,n.angle=n.y,delete n.y,n.startAngle=n.y0,delete n.y0,n.endAngle=n.y1,delete n.y1,n},ao.svg.chord=function(){function n(n,a){var l=t(this,u,n,a),c=t(this,o,n,a);return"M"+l.p0+r(l.r,l.p1,l.a1-l.a0)+(e(l,c)?i(l.r,l.p1,l.r,l.p0):i(l.r,l.p1,c.r,c.p0)+r(c.r,c.p1,c.a1-c.a0)+i(c.r,c.p1,l.r,l.p0))+"Z"}function t(n,t,e,r){var i=t.call(n,e,r),u=a.call(n,i,r),o=l.call(n,i,r)-Io,f=c.call(n,i,r)-Io;return{r:u,a0:o,a1:f,p0:[u*Math.cos(o),u*Math.sin(o)],p1:[u*Math.cos(f),u*Math.sin(f)]}}function e(n,t){return n.a0==t.a0&&n.a1==t.a1}function r(n,t,e){return"A"+n+","+n+" 0 "+ +(e>Fo)+",1 "+t}function i(n,t,e,r){return"Q 0,0 "+r}var u=Me,o=xe,a=Iu,l=gu,c=vu;return n.radius=function(t){return arguments.length?(a=En(t),n):a},n.source=function(t){return arguments.length?(u=En(t),n):u},n.target=function(t){return arguments.length?(o=En(t),n):o},n.startAngle=function(t){return arguments.length?(l=En(t),n):l},n.endAngle=function(t){return arguments.length?(c=En(t),n):c},n},ao.svg.diagonal=function(){function n(n,i){var u=t.call(this,n,i),o=e.call(this,n,i),a=(u.y+o.y)/2,l=[u,{x:u.x,y:a},{x:o.x,y:a},o];return l=l.map(r),"M"+l[0]+"C"+l[1]+" "+l[2]+" "+l[3]}var t=Me,e=xe,r=Yu;return n.source=function(e){return arguments.length?(t=En(e),n):t},n.target=function(t){return arguments.length?(e=En(t),n):e},n.projection=function(t){return arguments.length?(r=t,n):r},n},ao.svg.diagonal.radial=function(){var n=ao.svg.diagonal(),t=Yu,e=n.projection;return n.projection=function(n){return arguments.length?e(Zu(t=n)):t},n},ao.svg.symbol=function(){function n(n,r){return(Ul.get(t.call(this,n,r))||$u)(e.call(this,n,r))}var t=Xu,e=Vu;return n.type=function(e){return arguments.length?(t=En(e),n):t},n.size=function(t){return arguments.length?(e=En(t),n):e},n};var Ul=ao.map({circle:$u,cross:function(n){var t=Math.sqrt(n/5)/2;return"M"+-3*t+","+-t+"H"+-t+"V"+-3*t+"H"+t+"V"+-t+"H"+3*t+"V"+t+"H"+t+"V"+3*t+"H"+-t+"V"+t+"H"+-3*t+"Z"},diamond:function(n){var t=Math.sqrt(n/(2*Fl)),e=t*Fl;return"M0,"+-t+"L"+e+",0 0,"+t+" "+-e+",0Z"},square:function(n){var t=Math.sqrt(n)/2;return"M"+-t+","+-t+"L"+t+","+-t+" "+t+","+t+" "+-t+","+t+"Z"},"triangle-down":function(n){var t=Math.sqrt(n/jl),e=t*jl/2;return"M0,"+e+"L"+t+","+-e+" "+-t+","+-e+"Z"},"triangle-up":function(n){var t=Math.sqrt(n/jl),e=t*jl/2;return"M0,"+-e+"L"+t+","+e+" "+-t+","+e+"Z"}});ao.svg.symbolTypes=Ul.keys();var jl=Math.sqrt(3),Fl=Math.tan(30*Yo);Co.transition=function(n){for(var t,e,r=Hl||++Zl,i=Ku(n),u=[],o=Ol||{time:Date.now(),ease:Nr,delay:0,duration:250},a=-1,l=this.length;++au;u++){i.push(t=[]);for(var e=this[u],a=0,l=e.length;l>a;a++)(r=e[a])&&n.call(r,r.__data__,a,u)&&t.push(r)}return Wu(i,this.namespace,this.id)},Yl.tween=function(n,t){var e=this.id,r=this.namespace;return arguments.length<2?this.node()[r][e].tween.get(n):Y(this,null==t?function(t){t[r][e].tween.remove(n)}:function(i){i[r][e].tween.set(n,t)})},Yl.attr=function(n,t){function e(){this.removeAttribute(a)}function r(){this.removeAttributeNS(a.space,a.local)}function i(n){return null==n?e:(n+="",function(){var t,e=this.getAttribute(a);return e!==n&&(t=o(e,n),function(n){this.setAttribute(a,t(n))})})}function u(n){return null==n?r:(n+="",function(){var t,e=this.getAttributeNS(a.space,a.local);return e!==n&&(t=o(e,n),function(n){this.setAttributeNS(a.space,a.local,t(n))})})}if(arguments.length<2){for(t in n)this.attr(t,n[t]);return this}var o="transform"==n?$r:Mr,a=ao.ns.qualify(n);return Ju(this,"attr."+n,t,a.local?u:i)},Yl.attrTween=function(n,t){function e(n,e){var r=t.call(this,n,e,this.getAttribute(i));return r&&function(n){this.setAttribute(i,r(n))}}function r(n,e){var r=t.call(this,n,e,this.getAttributeNS(i.space,i.local));return r&&function(n){this.setAttributeNS(i.space,i.local,r(n))}}var i=ao.ns.qualify(n);return this.tween("attr."+n,i.local?r:e)},Yl.style=function(n,e,r){function i(){this.style.removeProperty(n)}function u(e){return null==e?i:(e+="",function(){var i,u=t(this).getComputedStyle(this,null).getPropertyValue(n);return u!==e&&(i=Mr(u,e),function(t){this.style.setProperty(n,i(t),r)})})}var o=arguments.length;if(3>o){if("string"!=typeof n){2>o&&(e="");for(r in n)this.style(r,n[r],e);return this}r=""}return Ju(this,"style."+n,e,u)},Yl.styleTween=function(n,e,r){function i(i,u){var o=e.call(this,i,u,t(this).getComputedStyle(this,null).getPropertyValue(n));return o&&function(t){this.style.setProperty(n,o(t),r)}}return arguments.length<3&&(r=""),this.tween("style."+n,i)},Yl.text=function(n){return Ju(this,"text",n,Gu)},Yl.remove=function(){var n=this.namespace;return this.each("end.transition",function(){var t;this[n].count<2&&(t=this.parentNode)&&t.removeChild(this)})},Yl.ease=function(n){var t=this.id,e=this.namespace;return arguments.length<1?this.node()[e][t].ease:("function"!=typeof n&&(n=ao.ease.apply(ao,arguments)),Y(this,function(r){r[e][t].ease=n}))},Yl.delay=function(n){var t=this.id,e=this.namespace;return arguments.length<1?this.node()[e][t].delay:Y(this,"function"==typeof n?function(r,i,u){r[e][t].delay=+n.call(r,r.__data__,i,u)}:(n=+n,function(r){r[e][t].delay=n}))},Yl.duration=function(n){var t=this.id,e=this.namespace;return arguments.length<1?this.node()[e][t].duration:Y(this,"function"==typeof n?function(r,i,u){r[e][t].duration=Math.max(1,n.call(r,r.__data__,i,u))}:(n=Math.max(1,n),function(r){r[e][t].duration=n}))},Yl.each=function(n,t){var e=this.id,r=this.namespace;if(arguments.length<2){var i=Ol,u=Hl;try{Hl=e,Y(this,function(t,i,u){Ol=t[r][e],n.call(t,t.__data__,i,u)})}finally{Ol=i,Hl=u}}else Y(this,function(i){var u=i[r][e];(u.event||(u.event=ao.dispatch("start","end","interrupt"))).on(n,t)});return this},Yl.transition=function(){for(var n,t,e,r,i=this.id,u=++Zl,o=this.namespace,a=[],l=0,c=this.length;c>l;l++){a.push(n=[]);for(var t=this[l],f=0,s=t.length;s>f;f++)(e=t[f])&&(r=e[o][i],Qu(e,f,o,u,{time:r.time,ease:r.ease,delay:r.delay+r.duration,duration:r.duration})),n.push(e)}return Wu(a,o,u)},ao.svg.axis=function(){function n(n){n.each(function(){var n,c=ao.select(this),f=this.__chart__||e,s=this.__chart__=e.copy(),h=null==l?s.ticks?s.ticks.apply(s,a):s.domain():l,p=null==t?s.tickFormat?s.tickFormat.apply(s,a):m:t,g=c.selectAll(".tick").data(h,s),v=g.enter().insert("g",".domain").attr("class","tick").style("opacity",Uo),d=ao.transition(g.exit()).style("opacity",Uo).remove(),y=ao.transition(g.order()).style("opacity",1),M=Math.max(i,0)+o,x=Zi(s),b=c.selectAll(".domain").data([0]),_=(b.enter().append("path").attr("class","domain"),ao.transition(b));v.append("line"),v.append("text");var w,S,k,N,E=v.select("line"),A=y.select("line"),C=g.select("text").text(p),z=v.select("text"),L=y.select("text"),q="top"===r||"left"===r?-1:1;if("bottom"===r||"top"===r?(n=no,w="x",k="y",S="x2",N="y2",C.attr("dy",0>q?"0em":".71em").style("text-anchor","middle"),_.attr("d","M"+x[0]+","+q*u+"V0H"+x[1]+"V"+q*u)):(n=to,w="y",k="x",S="y2",N="x2",C.attr("dy",".32em").style("text-anchor",0>q?"end":"start"),_.attr("d","M"+q*u+","+x[0]+"H0V"+x[1]+"H"+q*u)),E.attr(N,q*i),z.attr(k,q*M),A.attr(S,0).attr(N,q*i),L.attr(w,0).attr(k,q*M),s.rangeBand){var T=s,R=T.rangeBand()/2;f=s=function(n){return T(n)+R}}else f.rangeBand?f=s:d.call(n,s,f);v.call(n,f,s),y.call(n,s,s)})}var t,e=ao.scale.linear(),r=Vl,i=6,u=6,o=3,a=[10],l=null;return n.scale=function(t){return arguments.length?(e=t,n):e},n.orient=function(t){return arguments.length?(r=t in Xl?t+"":Vl,n):r},n.ticks=function(){return arguments.length?(a=co(arguments),n):a},n.tickValues=function(t){return arguments.length?(l=t,n):l},n.tickFormat=function(e){return arguments.length?(t=e,n):t},n.tickSize=function(t){var e=arguments.length;return e?(i=+t,u=+arguments[e-1],n):i},n.innerTickSize=function(t){return arguments.length?(i=+t,n):i},n.outerTickSize=function(t){return arguments.length?(u=+t,n):u},n.tickPadding=function(t){return arguments.length?(o=+t,n):o},n.tickSubdivide=function(){return arguments.length&&n},n};var Vl="bottom",Xl={top:1,right:1,bottom:1,left:1};ao.svg.brush=function(){function n(t){t.each(function(){var t=ao.select(this).style("pointer-events","all").style("-webkit-tap-highlight-color","rgba(0,0,0,0)").on("mousedown.brush",u).on("touchstart.brush",u),o=t.selectAll(".background").data([0]);o.enter().append("rect").attr("class","background").style("visibility","hidden").style("cursor","crosshair"),t.selectAll(".extent").data([0]).enter().append("rect").attr("class","extent").style("cursor","move");var a=t.selectAll(".resize").data(v,m);a.exit().remove(),a.enter().append("g").attr("class",function(n){return"resize "+n}).style("cursor",function(n){return $l[n]}).append("rect").attr("x",function(n){return/[ew]$/.test(n)?-3:null}).attr("y",function(n){return/^[ns]/.test(n)?-3:null}).attr("width",6).attr("height",6).style("visibility","hidden"),a.style("display",n.empty()?"none":null);var l,s=ao.transition(t),h=ao.transition(o);c&&(l=Zi(c),h.attr("x",l[0]).attr("width",l[1]-l[0]),r(s)),f&&(l=Zi(f),h.attr("y",l[0]).attr("height",l[1]-l[0]),i(s)),e(s)})}function e(n){n.selectAll(".resize").attr("transform",function(n){return"translate("+s[+/e$/.test(n)]+","+h[+/^s/.test(n)]+")"})}function r(n){n.select(".extent").attr("x",s[0]),n.selectAll(".extent,.n>rect,.s>rect").attr("width",s[1]-s[0])}function i(n){n.select(".extent").attr("y",h[0]),n.selectAll(".extent,.e>rect,.w>rect").attr("height",h[1]-h[0])}function u(){function u(){32==ao.event.keyCode&&(C||(M=null,L[0]-=s[1],L[1]-=h[1],C=2),S())}function v(){32==ao.event.keyCode&&2==C&&(L[0]+=s[1],L[1]+=h[1],C=0,S())}function d(){var n=ao.mouse(b),t=!1;x&&(n[0]+=x[0],n[1]+=x[1]),C||(ao.event.altKey?(M||(M=[(s[0]+s[1])/2,(h[0]+h[1])/2]),L[0]=s[+(n[0]f?(i=r,r=f):i=f),v[0]!=r||v[1]!=i?(e?a=null:o=null,v[0]=r,v[1]=i,!0):void 0}function m(){d(),k.style("pointer-events","all").selectAll(".resize").style("display",n.empty()?"none":null),ao.select("body").style("cursor",null),q.on("mousemove.brush",null).on("mouseup.brush",null).on("touchmove.brush",null).on("touchend.brush",null).on("keydown.brush",null).on("keyup.brush",null),z(),w({type:"brushend"})}var M,x,b=this,_=ao.select(ao.event.target),w=l.of(b,arguments),k=ao.select(b),N=_.datum(),E=!/^(n|s)$/.test(N)&&c,A=!/^(e|w)$/.test(N)&&f,C=_.classed("extent"),z=W(b),L=ao.mouse(b),q=ao.select(t(b)).on("keydown.brush",u).on("keyup.brush",v);if(ao.event.changedTouches?q.on("touchmove.brush",d).on("touchend.brush",m):q.on("mousemove.brush",d).on("mouseup.brush",m),k.interrupt().selectAll("*").interrupt(),C)L[0]=s[0]-L[0],L[1]=h[0]-L[1];else if(N){var T=+/w$/.test(N),R=+/^n/.test(N);x=[s[1-T]-L[0],h[1-R]-L[1]],L[0]=s[T],L[1]=h[R]}else ao.event.altKey&&(M=L.slice());k.style("pointer-events","none").selectAll(".resize").style("display",null),ao.select("body").style("cursor",_.style("cursor")),w({type:"brushstart"}),d()}var o,a,l=N(n,"brushstart","brush","brushend"),c=null,f=null,s=[0,0],h=[0,0],p=!0,g=!0,v=Bl[0];return n.event=function(n){n.each(function(){var n=l.of(this,arguments),t={x:s,y:h,i:o,j:a},e=this.__chart__||t;this.__chart__=t,Hl?ao.select(this).transition().each("start.brush",function(){o=e.i,a=e.j,s=e.x,h=e.y,n({type:"brushstart"})}).tween("brush:brush",function(){var e=xr(s,t.x),r=xr(h,t.y);return o=a=null,function(i){s=t.x=e(i),h=t.y=r(i),n({type:"brush",mode:"resize"})}}).each("end.brush",function(){o=t.i,a=t.j,n({type:"brush",mode:"resize"}),n({type:"brushend"})}):(n({type:"brushstart"}),n({type:"brush",mode:"resize"}),n({type:"brushend"}))})},n.x=function(t){return arguments.length?(c=t,v=Bl[!c<<1|!f],n):c},n.y=function(t){return arguments.length?(f=t,v=Bl[!c<<1|!f],n):f},n.clamp=function(t){return arguments.length?(c&&f?(p=!!t[0],g=!!t[1]):c?p=!!t:f&&(g=!!t),n):c&&f?[p,g]:c?p:f?g:null},n.extent=function(t){var e,r,i,u,l;return arguments.length?(c&&(e=t[0],r=t[1],f&&(e=e[0],r=r[0]),o=[e,r],c.invert&&(e=c(e),r=c(r)),e>r&&(l=e,e=r,r=l),e==s[0]&&r==s[1]||(s=[e,r])),f&&(i=t[0],u=t[1],c&&(i=i[1],u=u[1]),a=[i,u],f.invert&&(i=f(i),u=f(u)),i>u&&(l=i,i=u,u=l),i==h[0]&&u==h[1]||(h=[i,u])),n):(c&&(o?(e=o[0],r=o[1]):(e=s[0],r=s[1],c.invert&&(e=c.invert(e),r=c.invert(r)),e>r&&(l=e,e=r,r=l))),f&&(a?(i=a[0],u=a[1]):(i=h[0],u=h[1],f.invert&&(i=f.invert(i),u=f.invert(u)),i>u&&(l=i,i=u,u=l))),c&&f?[[e,i],[r,u]]:c?[e,r]:f&&[i,u])},n.clear=function(){return n.empty()||(s=[0,0],h=[0,0],o=a=null),n},n.empty=function(){return!!c&&s[0]==s[1]||!!f&&h[0]==h[1]},ao.rebind(n,l,"on")};var $l={n:"ns-resize",e:"ew-resize",s:"ns-resize",w:"ew-resize",nw:"nwse-resize",ne:"nesw-resize",se:"nwse-resize",sw:"nesw-resize"},Bl=[["n","e","s","w","nw","ne","se","sw"],["e","w"],["n","s"],[]],Wl=ga.format=xa.timeFormat,Jl=Wl.utc,Gl=Jl("%Y-%m-%dT%H:%M:%S.%LZ");Wl.iso=Date.prototype.toISOString&&+new Date("2000-01-01T00:00:00.000Z")?eo:Gl,eo.parse=function(n){var t=new Date(n);return isNaN(t)?null:t},eo.toString=Gl.toString,ga.second=On(function(n){return new va(1e3*Math.floor(n/1e3))},function(n,t){n.setTime(n.getTime()+1e3*Math.floor(t))},function(n){return n.getSeconds()}),ga.seconds=ga.second.range,ga.seconds.utc=ga.second.utc.range,ga.minute=On(function(n){return new va(6e4*Math.floor(n/6e4))},function(n,t){n.setTime(n.getTime()+6e4*Math.floor(t))},function(n){return n.getMinutes()}),ga.minutes=ga.minute.range,ga.minutes.utc=ga.minute.utc.range,ga.hour=On(function(n){var t=n.getTimezoneOffset()/60;return new va(36e5*(Math.floor(n/36e5-t)+t))},function(n,t){n.setTime(n.getTime()+36e5*Math.floor(t))},function(n){return n.getHours()}),ga.hours=ga.hour.range,ga.hours.utc=ga.hour.utc.range,ga.month=On(function(n){return n=ga.day(n),n.setDate(1),n},function(n,t){n.setMonth(n.getMonth()+t)},function(n){return n.getMonth()}),ga.months=ga.month.range,ga.months.utc=ga.month.utc.range;var Kl=[1e3,5e3,15e3,3e4,6e4,3e5,9e5,18e5,36e5,108e5,216e5,432e5,864e5,1728e5,6048e5,2592e6,7776e6,31536e6],Ql=[[ga.second,1],[ga.second,5],[ga.second,15],[ga.second,30],[ga.minute,1],[ga.minute,5],[ga.minute,15],[ga.minute,30],[ga.hour,1],[ga.hour,3],[ga.hour,6],[ga.hour,12],[ga.day,1],[ga.day,2],[ga.week,1],[ga.month,1],[ga.month,3],[ga.year,1]],nc=Wl.multi([[".%L",function(n){return n.getMilliseconds()}],[":%S",function(n){return n.getSeconds()}],["%I:%M",function(n){return n.getMinutes()}],["%I %p",function(n){return n.getHours()}],["%a %d",function(n){return n.getDay()&&1!=n.getDate()}],["%b %d",function(n){return 1!=n.getDate()}],["%B",function(n){return n.getMonth()}],["%Y",zt]]),tc={range:function(n,t,e){return ao.range(Math.ceil(n/e)*e,+t,e).map(io)},floor:m,ceil:m};Ql.year=ga.year,ga.scale=function(){return ro(ao.scale.linear(),Ql,nc)};var ec=Ql.map(function(n){return[n[0].utc,n[1]]}),rc=Jl.multi([[".%L",function(n){return n.getUTCMilliseconds()}],[":%S",function(n){return n.getUTCSeconds()}],["%I:%M",function(n){return n.getUTCMinutes()}],["%I %p",function(n){return n.getUTCHours()}],["%a %d",function(n){return n.getUTCDay()&&1!=n.getUTCDate()}],["%b %d",function(n){return 1!=n.getUTCDate()}],["%B",function(n){return n.getUTCMonth()}],["%Y",zt]]);ec.year=ga.year.utc,ga.scale.utc=function(){return ro(ao.scale.linear(),ec,rc)},ao.text=An(function(n){return n.responseText}),ao.json=function(n,t){return Cn(n,"application/json",uo,t)},ao.html=function(n,t){return Cn(n,"text/html",oo,t)},ao.xml=An(function(n){return n.responseXML}),"function"==typeof define&&define.amd?(this.d3=ao,define(ao)):"object"==typeof module&&module.exports?module.exports=ao:this.d3=ao}(); \ No newline at end of file diff --git a/backend/coverage-report-progress/_js/file.js b/backend/coverage-report-progress/_js/file.js deleted file mode 100644 index 124a8a18..00000000 --- a/backend/coverage-report-progress/_js/file.js +++ /dev/null @@ -1,53 +0,0 @@ -$(function () { - var $window = $(window) - , $top_link = $('#toplink') - , $body = $('body, html') - , offset = $('#code').offset().top; - - $top_link.hide().click(function (event) { - event.preventDefault(); - $body.animate({scrollTop: 0}, 800); - }); - - $window.scroll(function () { - if ($window.scrollTop() > offset) { - $top_link.fadeIn(); - } else { - $top_link.fadeOut(); - } - }); - - var $popovers = $('.popin > :first-child'); - $('.popin').on({ - 'click.popover': function (event) { - event.stopPropagation(); - - var $container = $(this).children().first(); - - //Close all other popovers: - $popovers.each(function () { - var $current = $(this); - if (!$current.is($container)) { - $current.popover('hide'); - } - }); - - // Toggle this popover: - $container.popover('toggle'); - }, - }); - - //Hide all popovers on outside click: - $(document).click(function (event) { - if ($(event.target).closest($('.popover')).length === 0) { - $popovers.popover('hide'); - } - }); - - //Hide all popovers on escape: - $(document).keyup(function (event) { - if (event.key === 'Escape') { - $popovers.popover('hide'); - } - }); -}); diff --git a/backend/coverage-report-progress/_js/jquery.min.js b/backend/coverage-report-progress/_js/jquery.min.js deleted file mode 100644 index 798cc8bf..00000000 --- a/backend/coverage-report-progress/_js/jquery.min.js +++ /dev/null @@ -1,2 +0,0 @@ -/*! jQuery v3.7.1 | (c) OpenJS Foundation and other contributors | jquery.org/license */ -!function(e,t){"use strict";"object"==typeof module&&"object"==typeof module.exports?module.exports=e.document?t(e,!0):function(e){if(!e.document)throw new Error("jQuery requires a window with a document");return t(e)}:t(e)}("undefined"!=typeof window?window:this,function(ie,e){"use strict";var oe=[],r=Object.getPrototypeOf,ae=oe.slice,g=oe.flat?function(e){return oe.flat.call(e)}:function(e){return oe.concat.apply([],e)},s=oe.push,se=oe.indexOf,n={},i=n.toString,ue=n.hasOwnProperty,o=ue.toString,a=o.call(Object),le={},v=function(e){return"function"==typeof e&&"number"!=typeof e.nodeType&&"function"!=typeof e.item},y=function(e){return null!=e&&e===e.window},C=ie.document,u={type:!0,src:!0,nonce:!0,noModule:!0};function m(e,t,n){var r,i,o=(n=n||C).createElement("script");if(o.text=e,t)for(r in u)(i=t[r]||t.getAttribute&&t.getAttribute(r))&&o.setAttribute(r,i);n.head.appendChild(o).parentNode.removeChild(o)}function x(e){return null==e?e+"":"object"==typeof e||"function"==typeof e?n[i.call(e)]||"object":typeof e}var t="3.7.1",l=/HTML$/i,ce=function(e,t){return new ce.fn.init(e,t)};function c(e){var t=!!e&&"length"in e&&e.length,n=x(e);return!v(e)&&!y(e)&&("array"===n||0===t||"number"==typeof t&&0+~]|"+ge+")"+ge+"*"),x=new RegExp(ge+"|>"),j=new RegExp(g),A=new RegExp("^"+t+"$"),D={ID:new RegExp("^#("+t+")"),CLASS:new RegExp("^\\.("+t+")"),TAG:new RegExp("^("+t+"|[*])"),ATTR:new RegExp("^"+p),PSEUDO:new RegExp("^"+g),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+ge+"*(even|odd|(([+-]|)(\\d*)n|)"+ge+"*(?:([+-]|)"+ge+"*(\\d+)|))"+ge+"*\\)|)","i"),bool:new RegExp("^(?:"+f+")$","i"),needsContext:new RegExp("^"+ge+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+ge+"*((?:-\\d)?\\d*)"+ge+"*\\)|)(?=[^-]|$)","i")},N=/^(?:input|select|textarea|button)$/i,q=/^h\d$/i,L=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,H=/[+~]/,O=new RegExp("\\\\[\\da-fA-F]{1,6}"+ge+"?|\\\\([^\\r\\n\\f])","g"),P=function(e,t){var n="0x"+e.slice(1)-65536;return t||(n<0?String.fromCharCode(n+65536):String.fromCharCode(n>>10|55296,1023&n|56320))},M=function(){V()},R=J(function(e){return!0===e.disabled&&fe(e,"fieldset")},{dir:"parentNode",next:"legend"});try{k.apply(oe=ae.call(ye.childNodes),ye.childNodes),oe[ye.childNodes.length].nodeType}catch(e){k={apply:function(e,t){me.apply(e,ae.call(t))},call:function(e){me.apply(e,ae.call(arguments,1))}}}function I(t,e,n,r){var i,o,a,s,u,l,c,f=e&&e.ownerDocument,p=e?e.nodeType:9;if(n=n||[],"string"!=typeof t||!t||1!==p&&9!==p&&11!==p)return n;if(!r&&(V(e),e=e||T,C)){if(11!==p&&(u=L.exec(t)))if(i=u[1]){if(9===p){if(!(a=e.getElementById(i)))return n;if(a.id===i)return k.call(n,a),n}else if(f&&(a=f.getElementById(i))&&I.contains(e,a)&&a.id===i)return k.call(n,a),n}else{if(u[2])return k.apply(n,e.getElementsByTagName(t)),n;if((i=u[3])&&e.getElementsByClassName)return k.apply(n,e.getElementsByClassName(i)),n}if(!(h[t+" "]||d&&d.test(t))){if(c=t,f=e,1===p&&(x.test(t)||m.test(t))){(f=H.test(t)&&U(e.parentNode)||e)==e&&le.scope||((s=e.getAttribute("id"))?s=ce.escapeSelector(s):e.setAttribute("id",s=S)),o=(l=Y(t)).length;while(o--)l[o]=(s?"#"+s:":scope")+" "+Q(l[o]);c=l.join(",")}try{return k.apply(n,f.querySelectorAll(c)),n}catch(e){h(t,!0)}finally{s===S&&e.removeAttribute("id")}}}return re(t.replace(ve,"$1"),e,n,r)}function W(){var r=[];return function e(t,n){return r.push(t+" ")>b.cacheLength&&delete e[r.shift()],e[t+" "]=n}}function F(e){return e[S]=!0,e}function $(e){var t=T.createElement("fieldset");try{return!!e(t)}catch(e){return!1}finally{t.parentNode&&t.parentNode.removeChild(t),t=null}}function B(t){return function(e){return fe(e,"input")&&e.type===t}}function _(t){return function(e){return(fe(e,"input")||fe(e,"button"))&&e.type===t}}function z(t){return function(e){return"form"in e?e.parentNode&&!1===e.disabled?"label"in e?"label"in e.parentNode?e.parentNode.disabled===t:e.disabled===t:e.isDisabled===t||e.isDisabled!==!t&&R(e)===t:e.disabled===t:"label"in e&&e.disabled===t}}function X(a){return F(function(o){return o=+o,F(function(e,t){var n,r=a([],e.length,o),i=r.length;while(i--)e[n=r[i]]&&(e[n]=!(t[n]=e[n]))})})}function U(e){return e&&"undefined"!=typeof e.getElementsByTagName&&e}function V(e){var t,n=e?e.ownerDocument||e:ye;return n!=T&&9===n.nodeType&&n.documentElement&&(r=(T=n).documentElement,C=!ce.isXMLDoc(T),i=r.matches||r.webkitMatchesSelector||r.msMatchesSelector,r.msMatchesSelector&&ye!=T&&(t=T.defaultView)&&t.top!==t&&t.addEventListener("unload",M),le.getById=$(function(e){return r.appendChild(e).id=ce.expando,!T.getElementsByName||!T.getElementsByName(ce.expando).length}),le.disconnectedMatch=$(function(e){return i.call(e,"*")}),le.scope=$(function(){return T.querySelectorAll(":scope")}),le.cssHas=$(function(){try{return T.querySelector(":has(*,:jqfake)"),!1}catch(e){return!0}}),le.getById?(b.filter.ID=function(e){var t=e.replace(O,P);return function(e){return e.getAttribute("id")===t}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&C){var n=t.getElementById(e);return n?[n]:[]}}):(b.filter.ID=function(e){var n=e.replace(O,P);return function(e){var t="undefined"!=typeof e.getAttributeNode&&e.getAttributeNode("id");return t&&t.value===n}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&C){var n,r,i,o=t.getElementById(e);if(o){if((n=o.getAttributeNode("id"))&&n.value===e)return[o];i=t.getElementsByName(e),r=0;while(o=i[r++])if((n=o.getAttributeNode("id"))&&n.value===e)return[o]}return[]}}),b.find.TAG=function(e,t){return"undefined"!=typeof t.getElementsByTagName?t.getElementsByTagName(e):t.querySelectorAll(e)},b.find.CLASS=function(e,t){if("undefined"!=typeof t.getElementsByClassName&&C)return t.getElementsByClassName(e)},d=[],$(function(e){var t;r.appendChild(e).innerHTML="",e.querySelectorAll("[selected]").length||d.push("\\["+ge+"*(?:value|"+f+")"),e.querySelectorAll("[id~="+S+"-]").length||d.push("~="),e.querySelectorAll("a#"+S+"+*").length||d.push(".#.+[+~]"),e.querySelectorAll(":checked").length||d.push(":checked"),(t=T.createElement("input")).setAttribute("type","hidden"),e.appendChild(t).setAttribute("name","D"),r.appendChild(e).disabled=!0,2!==e.querySelectorAll(":disabled").length&&d.push(":enabled",":disabled"),(t=T.createElement("input")).setAttribute("name",""),e.appendChild(t),e.querySelectorAll("[name='']").length||d.push("\\["+ge+"*name"+ge+"*="+ge+"*(?:''|\"\")")}),le.cssHas||d.push(":has"),d=d.length&&new RegExp(d.join("|")),l=function(e,t){if(e===t)return a=!0,0;var n=!e.compareDocumentPosition-!t.compareDocumentPosition;return n||(1&(n=(e.ownerDocument||e)==(t.ownerDocument||t)?e.compareDocumentPosition(t):1)||!le.sortDetached&&t.compareDocumentPosition(e)===n?e===T||e.ownerDocument==ye&&I.contains(ye,e)?-1:t===T||t.ownerDocument==ye&&I.contains(ye,t)?1:o?se.call(o,e)-se.call(o,t):0:4&n?-1:1)}),T}for(e in I.matches=function(e,t){return I(e,null,null,t)},I.matchesSelector=function(e,t){if(V(e),C&&!h[t+" "]&&(!d||!d.test(t)))try{var n=i.call(e,t);if(n||le.disconnectedMatch||e.document&&11!==e.document.nodeType)return n}catch(e){h(t,!0)}return 0":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(O,P),e[3]=(e[3]||e[4]||e[5]||"").replace(O,P),"~="===e[2]&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),"nth"===e[1].slice(0,3)?(e[3]||I.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*("even"===e[3]||"odd"===e[3])),e[5]=+(e[7]+e[8]||"odd"===e[3])):e[3]&&I.error(e[0]),e},PSEUDO:function(e){var t,n=!e[6]&&e[2];return D.CHILD.test(e[0])?null:(e[3]?e[2]=e[4]||e[5]||"":n&&j.test(n)&&(t=Y(n,!0))&&(t=n.indexOf(")",n.length-t)-n.length)&&(e[0]=e[0].slice(0,t),e[2]=n.slice(0,t)),e.slice(0,3))}},filter:{TAG:function(e){var t=e.replace(O,P).toLowerCase();return"*"===e?function(){return!0}:function(e){return fe(e,t)}},CLASS:function(e){var t=s[e+" "];return t||(t=new RegExp("(^|"+ge+")"+e+"("+ge+"|$)"))&&s(e,function(e){return t.test("string"==typeof e.className&&e.className||"undefined"!=typeof e.getAttribute&&e.getAttribute("class")||"")})},ATTR:function(n,r,i){return function(e){var t=I.attr(e,n);return null==t?"!="===r:!r||(t+="","="===r?t===i:"!="===r?t!==i:"^="===r?i&&0===t.indexOf(i):"*="===r?i&&-1:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i;function T(e,n,r){return v(n)?ce.grep(e,function(e,t){return!!n.call(e,t,e)!==r}):n.nodeType?ce.grep(e,function(e){return e===n!==r}):"string"!=typeof n?ce.grep(e,function(e){return-1)[^>]*|#([\w-]+))$/;(ce.fn.init=function(e,t,n){var r,i;if(!e)return this;if(n=n||k,"string"==typeof e){if(!(r="<"===e[0]&&">"===e[e.length-1]&&3<=e.length?[null,e,null]:S.exec(e))||!r[1]&&t)return!t||t.jquery?(t||n).find(e):this.constructor(t).find(e);if(r[1]){if(t=t instanceof ce?t[0]:t,ce.merge(this,ce.parseHTML(r[1],t&&t.nodeType?t.ownerDocument||t:C,!0)),w.test(r[1])&&ce.isPlainObject(t))for(r in t)v(this[r])?this[r](t[r]):this.attr(r,t[r]);return this}return(i=C.getElementById(r[2]))&&(this[0]=i,this.length=1),this}return e.nodeType?(this[0]=e,this.length=1,this):v(e)?void 0!==n.ready?n.ready(e):e(ce):ce.makeArray(e,this)}).prototype=ce.fn,k=ce(C);var E=/^(?:parents|prev(?:Until|All))/,j={children:!0,contents:!0,next:!0,prev:!0};function A(e,t){while((e=e[t])&&1!==e.nodeType);return e}ce.fn.extend({has:function(e){var t=ce(e,this),n=t.length;return this.filter(function(){for(var e=0;e\x20\t\r\n\f]*)/i,Ce=/^$|^module$|\/(?:java|ecma)script/i;xe=C.createDocumentFragment().appendChild(C.createElement("div")),(be=C.createElement("input")).setAttribute("type","radio"),be.setAttribute("checked","checked"),be.setAttribute("name","t"),xe.appendChild(be),le.checkClone=xe.cloneNode(!0).cloneNode(!0).lastChild.checked,xe.innerHTML="",le.noCloneChecked=!!xe.cloneNode(!0).lastChild.defaultValue,xe.innerHTML="",le.option=!!xe.lastChild;var ke={thead:[1,"","
"],col:[2,"","
"],tr:[2,"","
"],td:[3,"","
"],_default:[0,"",""]};function Se(e,t){var n;return n="undefined"!=typeof e.getElementsByTagName?e.getElementsByTagName(t||"*"):"undefined"!=typeof e.querySelectorAll?e.querySelectorAll(t||"*"):[],void 0===t||t&&fe(e,t)?ce.merge([e],n):n}function Ee(e,t){for(var n=0,r=e.length;n",""]);var je=/<|&#?\w+;/;function Ae(e,t,n,r,i){for(var o,a,s,u,l,c,f=t.createDocumentFragment(),p=[],d=0,h=e.length;d\s*$/g;function Re(e,t){return fe(e,"table")&&fe(11!==t.nodeType?t:t.firstChild,"tr")&&ce(e).children("tbody")[0]||e}function Ie(e){return e.type=(null!==e.getAttribute("type"))+"/"+e.type,e}function We(e){return"true/"===(e.type||"").slice(0,5)?e.type=e.type.slice(5):e.removeAttribute("type"),e}function Fe(e,t){var n,r,i,o,a,s;if(1===t.nodeType){if(_.hasData(e)&&(s=_.get(e).events))for(i in _.remove(t,"handle events"),s)for(n=0,r=s[i].length;n").attr(n.scriptAttrs||{}).prop({charset:n.scriptCharset,src:n.url}).on("load error",i=function(e){r.remove(),i=null,e&&t("error"===e.type?404:200,e.type)}),C.head.appendChild(r[0])},abort:function(){i&&i()}}});var Jt,Kt=[],Zt=/(=)\?(?=&|$)|\?\?/;ce.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var e=Kt.pop()||ce.expando+"_"+jt.guid++;return this[e]=!0,e}}),ce.ajaxPrefilter("json jsonp",function(e,t,n){var r,i,o,a=!1!==e.jsonp&&(Zt.test(e.url)?"url":"string"==typeof e.data&&0===(e.contentType||"").indexOf("application/x-www-form-urlencoded")&&Zt.test(e.data)&&"data");if(a||"jsonp"===e.dataTypes[0])return r=e.jsonpCallback=v(e.jsonpCallback)?e.jsonpCallback():e.jsonpCallback,a?e[a]=e[a].replace(Zt,"$1"+r):!1!==e.jsonp&&(e.url+=(At.test(e.url)?"&":"?")+e.jsonp+"="+r),e.converters["script json"]=function(){return o||ce.error(r+" was not called"),o[0]},e.dataTypes[0]="json",i=ie[r],ie[r]=function(){o=arguments},n.always(function(){void 0===i?ce(ie).removeProp(r):ie[r]=i,e[r]&&(e.jsonpCallback=t.jsonpCallback,Kt.push(r)),o&&v(i)&&i(o[0]),o=i=void 0}),"script"}),le.createHTMLDocument=((Jt=C.implementation.createHTMLDocument("").body).innerHTML="
",2===Jt.childNodes.length),ce.parseHTML=function(e,t,n){return"string"!=typeof e?[]:("boolean"==typeof t&&(n=t,t=!1),t||(le.createHTMLDocument?((r=(t=C.implementation.createHTMLDocument("")).createElement("base")).href=C.location.href,t.head.appendChild(r)):t=C),o=!n&&[],(i=w.exec(e))?[t.createElement(i[1])]:(i=Ae([e],t,o),o&&o.length&&ce(o).remove(),ce.merge([],i.childNodes)));var r,i,o},ce.fn.load=function(e,t,n){var r,i,o,a=this,s=e.indexOf(" ");return-1").append(ce.parseHTML(e)).find(r):e)}).always(n&&function(e,t){a.each(function(){n.apply(this,o||[e.responseText,t,e])})}),this},ce.expr.pseudos.animated=function(t){return ce.grep(ce.timers,function(e){return t===e.elem}).length},ce.offset={setOffset:function(e,t,n){var r,i,o,a,s,u,l=ce.css(e,"position"),c=ce(e),f={};"static"===l&&(e.style.position="relative"),s=c.offset(),o=ce.css(e,"top"),u=ce.css(e,"left"),("absolute"===l||"fixed"===l)&&-1<(o+u).indexOf("auto")?(a=(r=c.position()).top,i=r.left):(a=parseFloat(o)||0,i=parseFloat(u)||0),v(t)&&(t=t.call(e,n,ce.extend({},s))),null!=t.top&&(f.top=t.top-s.top+a),null!=t.left&&(f.left=t.left-s.left+i),"using"in t?t.using.call(e,f):c.css(f)}},ce.fn.extend({offset:function(t){if(arguments.length)return void 0===t?this:this.each(function(e){ce.offset.setOffset(this,t,e)});var e,n,r=this[0];return r?r.getClientRects().length?(e=r.getBoundingClientRect(),n=r.ownerDocument.defaultView,{top:e.top+n.pageYOffset,left:e.left+n.pageXOffset}):{top:0,left:0}:void 0},position:function(){if(this[0]){var e,t,n,r=this[0],i={top:0,left:0};if("fixed"===ce.css(r,"position"))t=r.getBoundingClientRect();else{t=this.offset(),n=r.ownerDocument,e=r.offsetParent||n.documentElement;while(e&&(e===n.body||e===n.documentElement)&&"static"===ce.css(e,"position"))e=e.parentNode;e&&e!==r&&1===e.nodeType&&((i=ce(e).offset()).top+=ce.css(e,"borderTopWidth",!0),i.left+=ce.css(e,"borderLeftWidth",!0))}return{top:t.top-i.top-ce.css(r,"marginTop",!0),left:t.left-i.left-ce.css(r,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var e=this.offsetParent;while(e&&"static"===ce.css(e,"position"))e=e.offsetParent;return e||J})}}),ce.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(t,i){var o="pageYOffset"===i;ce.fn[t]=function(e){return M(this,function(e,t,n){var r;if(y(e)?r=e:9===e.nodeType&&(r=e.defaultView),void 0===n)return r?r[i]:e[t];r?r.scrollTo(o?r.pageXOffset:n,o?n:r.pageYOffset):e[t]=n},t,e,arguments.length)}}),ce.each(["top","left"],function(e,n){ce.cssHooks[n]=Ye(le.pixelPosition,function(e,t){if(t)return t=Ge(e,n),_e.test(t)?ce(e).position()[n]+"px":t})}),ce.each({Height:"height",Width:"width"},function(a,s){ce.each({padding:"inner"+a,content:s,"":"outer"+a},function(r,o){ce.fn[o]=function(e,t){var n=arguments.length&&(r||"boolean"!=typeof e),i=r||(!0===e||!0===t?"margin":"border");return M(this,function(e,t,n){var r;return y(e)?0===o.indexOf("outer")?e["inner"+a]:e.document.documentElement["client"+a]:9===e.nodeType?(r=e.documentElement,Math.max(e.body["scroll"+a],r["scroll"+a],e.body["offset"+a],r["offset"+a],r["client"+a])):void 0===n?ce.css(e,t,i):ce.style(e,t,n,i)},s,n?e:void 0,n)}})}),ce.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(e,t){ce.fn[t]=function(e){return this.on(t,e)}}),ce.fn.extend({bind:function(e,t,n){return this.on(e,null,t,n)},unbind:function(e,t){return this.off(e,null,t)},delegate:function(e,t,n,r){return this.on(t,e,n,r)},undelegate:function(e,t,n){return 1===arguments.length?this.off(e,"**"):this.off(t,e||"**",n)},hover:function(e,t){return this.on("mouseenter",e).on("mouseleave",t||e)}}),ce.each("blur focus focusin focusout resize scroll click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup contextmenu".split(" "),function(e,n){ce.fn[n]=function(e,t){return 0f&&(e=a.render.queue[f]);f++)d=e.generate(),typeof e.callback==typeof Function&&e.callback(d);a.render.queue.splice(0,f),a.render.queue.length?setTimeout(c):(a.dispatch.render_end(),a.render.active=!1)};setTimeout(c)},a.render.active=!1,a.render.queue=[],a.addGraph=function(b){typeof arguments[0]==typeof Function&&(b={generate:arguments[0],callback:arguments[1]}),a.render.queue.push(b),a.render.active||a.render()},"undefined"!=typeof module&&"undefined"!=typeof exports&&(module.exports=a),"undefined"!=typeof window&&(window.nv=a),a.dom.write=function(a){return void 0!==window.fastdom?fastdom.write(a):a()},a.dom.read=function(a){return void 0!==window.fastdom?fastdom.read(a):a()},a.interactiveGuideline=function(){"use strict";function b(l){l.each(function(l){function m(){var a=d3.mouse(this),d=a[0],e=a[1],i=!0,j=!1;if(k&&(d=d3.event.offsetX,e=d3.event.offsetY,"svg"!==d3.event.target.tagName&&(i=!1),d3.event.target.className.baseVal.match("nv-legend")&&(j=!0)),i&&(d-=f.left,e-=f.top),0>d||0>e||d>o||e>p||d3.event.relatedTarget&&void 0===d3.event.relatedTarget.ownerSVGElement||j){if(k&&d3.event.relatedTarget&&void 0===d3.event.relatedTarget.ownerSVGElement&&(void 0===d3.event.relatedTarget.className||d3.event.relatedTarget.className.match(c.nvPointerEventsClass)))return;return h.elementMouseout({mouseX:d,mouseY:e}),b.renderGuideLine(null),void c.hidden(!0)}c.hidden(!1);var l=g.invert(d);h.elementMousemove({mouseX:d,mouseY:e,pointXValue:l}),"dblclick"===d3.event.type&&h.elementDblclick({mouseX:d,mouseY:e,pointXValue:l}),"click"===d3.event.type&&h.elementClick({mouseX:d,mouseY:e,pointXValue:l})}var n=d3.select(this),o=d||960,p=e||400,q=n.selectAll("g.nv-wrap.nv-interactiveLineLayer").data([l]),r=q.enter().append("g").attr("class"," nv-wrap nv-interactiveLineLayer");r.append("g").attr("class","nv-interactiveGuideLine"),j&&(j.on("touchmove",m).on("mousemove",m,!0).on("mouseout",m,!0).on("dblclick",m).on("click",m),b.guideLine=null,b.renderGuideLine=function(c){i&&(b.guideLine&&b.guideLine.attr("x1")===c||a.dom.write(function(){var b=q.select(".nv-interactiveGuideLine").selectAll("line").data(null!=c?[a.utils.NaNtoZero(c)]:[],String);b.enter().append("line").attr("class","nv-guideline").attr("x1",function(a){return a}).attr("x2",function(a){return a}).attr("y1",p).attr("y2",0),b.exit().remove()}))})})}var c=a.models.tooltip();c.duration(0).hideDelay(0)._isInteractiveLayer(!0).hidden(!1);var d=null,e=null,f={left:0,top:0},g=d3.scale.linear(),h=d3.dispatch("elementMousemove","elementMouseout","elementClick","elementDblclick"),i=!0,j=null,k="ActiveXObject"in window;return b.dispatch=h,b.tooltip=c,b.margin=function(a){return arguments.length?(f.top="undefined"!=typeof a.top?a.top:f.top,f.left="undefined"!=typeof a.left?a.left:f.left,b):f},b.width=function(a){return arguments.length?(d=a,b):d},b.height=function(a){return arguments.length?(e=a,b):e},b.xScale=function(a){return arguments.length?(g=a,b):g},b.showGuideLine=function(a){return arguments.length?(i=a,b):i},b.svgContainer=function(a){return arguments.length?(j=a,b):j},b},a.interactiveBisect=function(a,b,c){"use strict";if(!(a instanceof Array))return null;var d;d="function"!=typeof c?function(a){return a.x}:c;var e=function(a,b){return d(a)-b},f=d3.bisector(e).left,g=d3.max([0,f(a,b)-1]),h=d(a[g]);if("undefined"==typeof h&&(h=g),h===b)return g;var i=d3.min([g+1,a.length-1]),j=d(a[i]);return"undefined"==typeof j&&(j=i),Math.abs(j-b)>=Math.abs(h-b)?g:i},a.nearestValueIndex=function(a,b,c){"use strict";var d=1/0,e=null;return a.forEach(function(a,f){var g=Math.abs(b-a);null!=a&&d>=g&&c>g&&(d=g,e=f)}),e},function(){"use strict";a.models.tooltip=function(){function b(){if(k){var a=d3.select(k);"svg"!==a.node().tagName&&(a=a.select("svg"));var b=a.node()?a.attr("viewBox"):null;if(b){b=b.split(" ");var c=parseInt(a.style("width"),10)/b[2];p.left=p.left*c,p.top=p.top*c}}}function c(){if(!n){var a;a=k?k:document.body,n=d3.select(a).append("div").attr("class","nvtooltip "+(j?j:"xy-tooltip")).attr("id",v),n.style("top",0).style("left",0),n.style("opacity",0),n.selectAll("div, table, td, tr").classed(w,!0),n.classed(w,!0),o=n.node()}}function d(){if(r&&B(e)){b();var f=p.left,g=null!==i?i:p.top;return a.dom.write(function(){c();var b=A(e);b&&(o.innerHTML=b),k&&u?a.dom.read(function(){var a=k.getElementsByTagName("svg")[0],b={left:0,top:0};if(a){var c=a.getBoundingClientRect(),d=k.getBoundingClientRect(),e=c.top;if(0>e){var i=k.getBoundingClientRect();e=Math.abs(e)>i.height?0:e}b.top=Math.abs(e-d.top),b.left=Math.abs(c.left-d.left)}f+=k.offsetLeft+b.left-2*k.scrollLeft,g+=k.offsetTop+b.top-2*k.scrollTop,h&&h>0&&(g=Math.floor(g/h)*h),C([f,g])}):C([f,g])}),d}}var e=null,f="w",g=25,h=0,i=null,j=null,k=null,l=!0,m=400,n=null,o=null,p={left:null,top:null},q={left:0,top:0},r=!0,s=100,t=!0,u=!1,v="nvtooltip-"+Math.floor(1e5*Math.random()),w="nv-pointer-events-none",x=function(a){return a},y=function(a){return a},z=function(a){return a},A=function(a){if(null===a)return"";var b=d3.select(document.createElement("table"));if(t){var c=b.selectAll("thead").data([a]).enter().append("thead");c.append("tr").append("td").attr("colspan",3).append("strong").classed("x-value",!0).html(y(a.value))}var d=b.selectAll("tbody").data([a]).enter().append("tbody"),e=d.selectAll("tr").data(function(a){return a.series}).enter().append("tr").classed("highlight",function(a){return a.highlight});e.append("td").classed("legend-color-guide",!0).append("div").style("background-color",function(a){return a.color}),e.append("td").classed("key",!0).html(function(a,b){return z(a.key,b)}),e.append("td").classed("value",!0).html(function(a,b){return x(a.value,b)}),e.selectAll("td").each(function(a){if(a.highlight){var b=d3.scale.linear().domain([0,1]).range(["#fff",a.color]),c=.6;d3.select(this).style("border-bottom-color",b(c)).style("border-top-color",b(c))}});var f=b.node().outerHTML;return void 0!==a.footer&&(f+=""),f},B=function(a){if(a&&a.series){if(a.series instanceof Array)return!!a.series.length;if(a.series instanceof Object)return a.series=[a.series],!0}return!1},C=function(b){o&&a.dom.read(function(){var c,d,e=parseInt(o.offsetHeight,10),h=parseInt(o.offsetWidth,10),i=a.utils.windowSize().width,j=a.utils.windowSize().height,k=window.pageYOffset,p=window.pageXOffset;j=window.innerWidth>=document.body.scrollWidth?j:j-16,i=window.innerHeight>=document.body.scrollHeight?i:i-16;var r,t,u=function(a){var b=d;do isNaN(a.offsetTop)||(b+=a.offsetTop),a=a.offsetParent;while(a);return b},v=function(a){var b=c;do isNaN(a.offsetLeft)||(b+=a.offsetLeft),a=a.offsetParent;while(a);return b};switch(f){case"e":c=b[0]-h-g,d=b[1]-e/2,r=v(o),t=u(o),p>r&&(c=b[0]+g>p?b[0]+g:p-r+c),k>t&&(d=k-t+d),t+e>k+j&&(d=k+j-t+d-e);break;case"w":c=b[0]+g,d=b[1]-e/2,r=v(o),t=u(o),r+h>i&&(c=b[0]-h-g),k>t&&(d=k+5),t+e>k+j&&(d=k+j-t+d-e);break;case"n":c=b[0]-h/2-5,d=b[1]+g,r=v(o),t=u(o),p>r&&(c=p+5),r+h>i&&(c=c-h/2+5),t+e>k+j&&(d=k+j-t+d-e);break;case"s":c=b[0]-h/2,d=b[1]-e-g,r=v(o),t=u(o),p>r&&(c=p+5),r+h>i&&(c=c-h/2+5),k>t&&(d=k);break;case"none":c=b[0],d=b[1]-g,r=v(o),t=u(o)}c-=q.left,d-=q.top;var w=o.getBoundingClientRect(),k=window.pageYOffset||document.documentElement.scrollTop,p=window.pageXOffset||document.documentElement.scrollLeft,x="translate("+(w.left+p)+"px, "+(w.top+k)+"px)",y="translate("+c+"px, "+d+"px)",z=d3.interpolateString(x,y),A=n.style("opacity")<.1;l?n.transition().delay(m).duration(0).style("opacity",0):n.interrupt().transition().duration(A?0:s).styleTween("transform",function(){return z},"important").style("-webkit-transform",y).style("opacity",1)})};return d.nvPointerEventsClass=w,d.options=a.utils.optionsFunc.bind(d),d._options=Object.create({},{duration:{get:function(){return s},set:function(a){s=a}},gravity:{get:function(){return f},set:function(a){f=a}},distance:{get:function(){return g},set:function(a){g=a}},snapDistance:{get:function(){return h},set:function(a){h=a}},classes:{get:function(){return j},set:function(a){j=a}},chartContainer:{get:function(){return k},set:function(a){k=a}},fixedTop:{get:function(){return i},set:function(a){i=a}},enabled:{get:function(){return r},set:function(a){r=a}},hideDelay:{get:function(){return m},set:function(a){m=a}},contentGenerator:{get:function(){return A},set:function(a){A=a}},valueFormatter:{get:function(){return x},set:function(a){x=a}},headerFormatter:{get:function(){return y},set:function(a){y=a}},keyFormatter:{get:function(){return z},set:function(a){z=a}},headerEnabled:{get:function(){return t},set:function(a){t=a}},_isInteractiveLayer:{get:function(){return u},set:function(a){u=!!a}},position:{get:function(){return p},set:function(a){p.left=void 0!==a.left?a.left:p.left,p.top=void 0!==a.top?a.top:p.top}},offset:{get:function(){return q},set:function(a){q.left=void 0!==a.left?a.left:q.left,q.top=void 0!==a.top?a.top:q.top}},hidden:{get:function(){return l},set:function(a){l!=a&&(l=!!a,d())}},data:{get:function(){return e},set:function(a){a.point&&(a.value=a.point.x,a.series=a.series||{},a.series.value=a.point.y,a.series.color=a.point.color||a.series.color),e=a}},tooltipElem:{get:function(){return o},set:function(){}},id:{get:function(){return v},set:function(){}}}),a.utils.initOptions(d),d}}(),a.utils.windowSize=function(){var a={width:640,height:480};return window.innerWidth&&window.innerHeight?(a.width=window.innerWidth,a.height=window.innerHeight,a):"CSS1Compat"==document.compatMode&&document.documentElement&&document.documentElement.offsetWidth?(a.width=document.documentElement.offsetWidth,a.height=document.documentElement.offsetHeight,a):document.body&&document.body.offsetWidth?(a.width=document.body.offsetWidth,a.height=document.body.offsetHeight,a):a},a.utils.windowResize=function(b){return window.addEventListener?window.addEventListener("resize",b):a.log("ERROR: Failed to bind to window.resize with: ",b),{callback:b,clear:function(){window.removeEventListener("resize",b)}}},a.utils.getColor=function(b){if(void 0===b)return a.utils.defaultColor();if(Array.isArray(b)){var c=d3.scale.ordinal().range(b);return function(a,b){var d=void 0===b?a:b;return a.color||c(d)}}return b},a.utils.defaultColor=function(){return a.utils.getColor(d3.scale.category20().range())},a.utils.customTheme=function(a,b,c){b=b||function(a){return a.key},c=c||d3.scale.category20().range();var d=c.length;return function(e){var f=b(e);return"function"==typeof a[f]?a[f]():void 0!==a[f]?a[f]:(d||(d=c.length),d-=1,c[d])}},a.utils.pjax=function(b,c){var d=function(d){d3.html(d,function(d){var e=d3.select(c).node();e.parentNode.replaceChild(d3.select(d).select(c).node(),e),a.utils.pjax(b,c)})};d3.selectAll(b).on("click",function(){history.pushState(this.href,this.textContent,this.href),d(this.href),d3.event.preventDefault()}),d3.select(window).on("popstate",function(){d3.event.state&&d(d3.event.state)})},a.utils.calcApproxTextWidth=function(a){if("function"==typeof a.style&&"function"==typeof a.text){var b=parseInt(a.style("font-size").replace("px",""),10),c=a.text().length;return c*b*.5}return 0},a.utils.NaNtoZero=function(a){return"number"!=typeof a||isNaN(a)||null===a||1/0===a||a===-1/0?0:a},d3.selection.prototype.watchTransition=function(a){var b=[this].concat([].slice.call(arguments,1));return a.transition.apply(a,b)},a.utils.renderWatch=function(b,c){if(!(this instanceof a.utils.renderWatch))return new a.utils.renderWatch(b,c);var d=void 0!==c?c:250,e=[],f=this;this.models=function(a){return a=[].slice.call(arguments,0),a.forEach(function(a){a.__rendered=!1,function(a){a.dispatch.on("renderEnd",function(){a.__rendered=!0,f.renderEnd("model")})}(a),e.indexOf(a)<0&&e.push(a)}),this},this.reset=function(a){void 0!==a&&(d=a),e=[]},this.transition=function(a,b,c){if(b=arguments.length>1?[].slice.call(arguments,1):[],c=b.length>1?b.pop():void 0!==d?d:250,a.__rendered=!1,e.indexOf(a)<0&&e.push(a),0===c)return a.__rendered=!0,a.delay=function(){return this},a.duration=function(){return this},a;a.__rendered=0===a.length?!0:a.every(function(a){return!a.length})?!0:!1;var g=0;return a.transition().duration(c).each(function(){++g}).each("end",function(){0===--g&&(a.__rendered=!0,f.renderEnd.apply(this,b))})},this.renderEnd=function(){e.every(function(a){return a.__rendered})&&(e.forEach(function(a){a.__rendered=!1}),b.renderEnd.apply(this,arguments))}},a.utils.deepExtend=function(b){var c=arguments.length>1?[].slice.call(arguments,1):[];c.forEach(function(c){for(var d in c){var e=b[d]instanceof Array,f="object"==typeof b[d],g="object"==typeof c[d];f&&!e&&g?a.utils.deepExtend(b[d],c[d]):b[d]=c[d]}})},a.utils.state=function(){if(!(this instanceof a.utils.state))return new a.utils.state;var b={},c=function(){},d=function(){return{}},e=null,f=null;this.dispatch=d3.dispatch("change","set"),this.dispatch.on("set",function(a){c(a,!0)}),this.getter=function(a){return d=a,this},this.setter=function(a,b){return b||(b=function(){}),c=function(c,d){a(c),d&&b()},this},this.init=function(b){e=e||{},a.utils.deepExtend(e,b)};var g=function(){var a=d();if(JSON.stringify(a)===JSON.stringify(b))return!1;for(var c in a)void 0===b[c]&&(b[c]={}),b[c]=a[c],f=!0;return!0};this.update=function(){e&&(c(e,!1),e=null),g.call(this)&&this.dispatch.change(b)}},a.utils.optionsFunc=function(a){return a&&d3.map(a).forEach(function(a,b){"function"==typeof this[a]&&this[a](b)}.bind(this)),this},a.utils.calcTicksX=function(b,c){var d=1,e=0;for(e;ed?f:d}return a.log("Requested number of ticks: ",b),a.log("Calculated max values to be: ",d),b=b>d?b=d-1:b,b=1>b?1:b,b=Math.floor(b),a.log("Calculating tick count as: ",b),b},a.utils.calcTicksY=function(b,c){return a.utils.calcTicksX(b,c)},a.utils.initOption=function(a,b){a._calls&&a._calls[b]?a[b]=a._calls[b]:(a[b]=function(c){return arguments.length?(a._overrides[b]=!0,a._options[b]=c,a):a._options[b]},a["_"+b]=function(c){return arguments.length?(a._overrides[b]||(a._options[b]=c),a):a._options[b]})},a.utils.initOptions=function(b){b._overrides=b._overrides||{};var c=Object.getOwnPropertyNames(b._options||{}),d=Object.getOwnPropertyNames(b._calls||{});c=c.concat(d);for(var e in c)a.utils.initOption(b,c[e])},a.utils.inheritOptionsD3=function(a,b,c){a._d3options=c.concat(a._d3options||[]),c.unshift(b),c.unshift(a),d3.rebind.apply(this,c)},a.utils.arrayUnique=function(a){return a.sort().filter(function(b,c){return!c||b!=a[c-1]})},a.utils.symbolMap=d3.map(),a.utils.symbol=function(){function b(b,e){var f=c.call(this,b,e),g=d.call(this,b,e);return-1!==d3.svg.symbolTypes.indexOf(f)?d3.svg.symbol().type(f).size(g)():a.utils.symbolMap.get(f)(g)}var c,d=64;return b.type=function(a){return arguments.length?(c=d3.functor(a),b):c},b.size=function(a){return arguments.length?(d=d3.functor(a),b):d},b},a.utils.inheritOptions=function(b,c){var d=Object.getOwnPropertyNames(c._options||{}),e=Object.getOwnPropertyNames(c._calls||{}),f=c._inherited||[],g=c._d3options||[],h=d.concat(e).concat(f).concat(g);h.unshift(c),h.unshift(b),d3.rebind.apply(this,h),b._inherited=a.utils.arrayUnique(d.concat(e).concat(f).concat(d).concat(b._inherited||[])),b._d3options=a.utils.arrayUnique(g.concat(b._d3options||[]))},a.utils.initSVG=function(a){a.classed({"nvd3-svg":!0})},a.utils.sanitizeHeight=function(a,b){return a||parseInt(b.style("height"),10)||400},a.utils.sanitizeWidth=function(a,b){return a||parseInt(b.style("width"),10)||960},a.utils.availableHeight=function(b,c,d){return a.utils.sanitizeHeight(b,c)-d.top-d.bottom},a.utils.availableWidth=function(b,c,d){return a.utils.sanitizeWidth(b,c)-d.left-d.right},a.utils.noData=function(b,c){var d=b.options(),e=d.margin(),f=d.noData(),g=null==f?["No Data Available."]:[f],h=a.utils.availableHeight(d.height(),c,e),i=a.utils.availableWidth(d.width(),c,e),j=e.left+i/2,k=e.top+h/2;c.selectAll("g").remove();var l=c.selectAll(".nv-noData").data(g);l.enter().append("text").attr("class","nvd3 nv-noData").attr("dy","-.7em").style("text-anchor","middle"),l.attr("x",j).attr("y",k).text(function(a){return a})},a.models.axis=function(){"use strict";function b(g){return s.reset(),g.each(function(b){var g=d3.select(this);a.utils.initSVG(g);var p=g.selectAll("g.nv-wrap.nv-axis").data([b]),q=p.enter().append("g").attr("class","nvd3 nv-wrap nv-axis"),t=(q.append("g"),p.select("g"));null!==n?c.ticks(n):("top"==c.orient()||"bottom"==c.orient())&&c.ticks(Math.abs(d.range()[1]-d.range()[0])/100),t.watchTransition(s,"axis").call(c),r=r||c.scale();var u=c.tickFormat();null==u&&(u=r.tickFormat());var v=t.selectAll("text.nv-axislabel").data([h||null]);v.exit().remove();var w,x,y;switch(c.orient()){case"top":v.enter().append("text").attr("class","nv-axislabel"),y=d.range().length<2?0:2===d.range().length?d.range()[1]:d.range()[d.range().length-1]+(d.range()[1]-d.range()[0]),v.attr("text-anchor","middle").attr("y",0).attr("x",y/2),i&&(x=p.selectAll("g.nv-axisMaxMin").data(d.domain()),x.enter().append("g").attr("class",function(a,b){return["nv-axisMaxMin","nv-axisMaxMin-x",0==b?"nv-axisMin-x":"nv-axisMax-x"].join(" ")}).append("text"),x.exit().remove(),x.attr("transform",function(b){return"translate("+a.utils.NaNtoZero(d(b))+",0)"}).select("text").attr("dy","-0.5em").attr("y",-c.tickPadding()).attr("text-anchor","middle").text(function(a){var b=u(a);return(""+b).match("NaN")?"":b}),x.watchTransition(s,"min-max top").attr("transform",function(b,c){return"translate("+a.utils.NaNtoZero(d.range()[c])+",0)"}));break;case"bottom":w=o+36;var z=30,A=0,B=t.selectAll("g").select("text"),C="";if(j%360){B.each(function(){var a=this.getBoundingClientRect(),b=a.width;A=a.height,b>z&&(z=b)}),C="rotate("+j+" 0,"+(A/2+c.tickPadding())+")";var D=Math.abs(Math.sin(j*Math.PI/180));w=(D?D*z:z)+30,B.attr("transform",C).style("text-anchor",j%360>0?"start":"end")}v.enter().append("text").attr("class","nv-axislabel"),y=d.range().length<2?0:2===d.range().length?d.range()[1]:d.range()[d.range().length-1]+(d.range()[1]-d.range()[0]),v.attr("text-anchor","middle").attr("y",w).attr("x",y/2),i&&(x=p.selectAll("g.nv-axisMaxMin").data([d.domain()[0],d.domain()[d.domain().length-1]]),x.enter().append("g").attr("class",function(a,b){return["nv-axisMaxMin","nv-axisMaxMin-x",0==b?"nv-axisMin-x":"nv-axisMax-x"].join(" ")}).append("text"),x.exit().remove(),x.attr("transform",function(b){return"translate("+a.utils.NaNtoZero(d(b)+(m?d.rangeBand()/2:0))+",0)"}).select("text").attr("dy",".71em").attr("y",c.tickPadding()).attr("transform",C).style("text-anchor",j?j%360>0?"start":"end":"middle").text(function(a){var b=u(a);return(""+b).match("NaN")?"":b}),x.watchTransition(s,"min-max bottom").attr("transform",function(b){return"translate("+a.utils.NaNtoZero(d(b)+(m?d.rangeBand()/2:0))+",0)"})),l&&B.attr("transform",function(a,b){return"translate(0,"+(b%2==0?"0":"12")+")"});break;case"right":v.enter().append("text").attr("class","nv-axislabel"),v.style("text-anchor",k?"middle":"begin").attr("transform",k?"rotate(90)":"").attr("y",k?-Math.max(e.right,f)+12:-10).attr("x",k?d3.max(d.range())/2:c.tickPadding()),i&&(x=p.selectAll("g.nv-axisMaxMin").data(d.domain()),x.enter().append("g").attr("class",function(a,b){return["nv-axisMaxMin","nv-axisMaxMin-y",0==b?"nv-axisMin-y":"nv-axisMax-y"].join(" ")}).append("text").style("opacity",0),x.exit().remove(),x.attr("transform",function(b){return"translate(0,"+a.utils.NaNtoZero(d(b))+")"}).select("text").attr("dy",".32em").attr("y",0).attr("x",c.tickPadding()).style("text-anchor","start").text(function(a){var b=u(a);return(""+b).match("NaN")?"":b}),x.watchTransition(s,"min-max right").attr("transform",function(b,c){return"translate(0,"+a.utils.NaNtoZero(d.range()[c])+")"}).select("text").style("opacity",1));break;case"left":v.enter().append("text").attr("class","nv-axislabel"),v.style("text-anchor",k?"middle":"end").attr("transform",k?"rotate(-90)":"").attr("y",k?-Math.max(e.left,f)+25-(o||0):-10).attr("x",k?-d3.max(d.range())/2:-c.tickPadding()),i&&(x=p.selectAll("g.nv-axisMaxMin").data(d.domain()),x.enter().append("g").attr("class",function(a,b){return["nv-axisMaxMin","nv-axisMaxMin-y",0==b?"nv-axisMin-y":"nv-axisMax-y"].join(" ")}).append("text").style("opacity",0),x.exit().remove(),x.attr("transform",function(b){return"translate(0,"+a.utils.NaNtoZero(r(b))+")"}).select("text").attr("dy",".32em").attr("y",0).attr("x",-c.tickPadding()).attr("text-anchor","end").text(function(a){var b=u(a);return(""+b).match("NaN")?"":b}),x.watchTransition(s,"min-max right").attr("transform",function(b,c){return"translate(0,"+a.utils.NaNtoZero(d.range()[c])+")"}).select("text").style("opacity",1))}if(v.text(function(a){return a}),!i||"left"!==c.orient()&&"right"!==c.orient()||(t.selectAll("g").each(function(a){d3.select(this).select("text").attr("opacity",1),(d(a)d.range()[0]-10)&&((a>1e-10||-1e-10>a)&&d3.select(this).attr("opacity",0),d3.select(this).select("text").attr("opacity",0))}),d.domain()[0]==d.domain()[1]&&0==d.domain()[0]&&p.selectAll("g.nv-axisMaxMin").style("opacity",function(a,b){return b?0:1})),i&&("top"===c.orient()||"bottom"===c.orient())){var E=[];p.selectAll("g.nv-axisMaxMin").each(function(a,b){try{E.push(b?d(a)-this.getBoundingClientRect().width-4:d(a)+this.getBoundingClientRect().width+4)}catch(c){E.push(b?d(a)-4:d(a)+4)}}),t.selectAll("g").each(function(a){(d(a)E[1])&&(a>1e-10||-1e-10>a?d3.select(this).remove():d3.select(this).select("text").remove())})}t.selectAll(".tick").filter(function(a){return!parseFloat(Math.round(1e5*a)/1e6)&&void 0!==a}).classed("zero",!0),r=d.copy()}),s.renderEnd("axis immediate"),b}var c=d3.svg.axis(),d=d3.scale.linear(),e={top:0,right:0,bottom:0,left:0},f=75,g=60,h=null,i=!0,j=0,k=!0,l=!1,m=!1,n=null,o=0,p=250,q=d3.dispatch("renderEnd");c.scale(d).orient("bottom").tickFormat(function(a){return a});var r,s=a.utils.renderWatch(q,p);return b.axis=c,b.dispatch=q,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{axisLabelDistance:{get:function(){return o},set:function(a){o=a}},staggerLabels:{get:function(){return l},set:function(a){l=a}},rotateLabels:{get:function(){return j},set:function(a){j=a}},rotateYLabel:{get:function(){return k},set:function(a){k=a}},showMaxMin:{get:function(){return i},set:function(a){i=a}},axisLabel:{get:function(){return h},set:function(a){h=a}},height:{get:function(){return g},set:function(a){g=a}},ticks:{get:function(){return n},set:function(a){n=a}},width:{get:function(){return f},set:function(a){f=a}},margin:{get:function(){return e},set:function(a){e.top=void 0!==a.top?a.top:e.top,e.right=void 0!==a.right?a.right:e.right,e.bottom=void 0!==a.bottom?a.bottom:e.bottom,e.left=void 0!==a.left?a.left:e.left}},duration:{get:function(){return p},set:function(a){p=a,s.reset(p)}},scale:{get:function(){return d},set:function(e){d=e,c.scale(d),m="function"==typeof d.rangeBands,a.utils.inheritOptionsD3(b,d,["domain","range","rangeBand","rangeBands"])}}}),a.utils.initOptions(b),a.utils.inheritOptionsD3(b,c,["orient","tickValues","tickSubdivide","tickSize","tickPadding","tickFormat"]),a.utils.inheritOptionsD3(b,d,["domain","range","rangeBand","rangeBands"]),b},a.models.boxPlot=function(){"use strict";function b(l){return v.reset(),l.each(function(b){var l=j-i.left-i.right,p=k-i.top-i.bottom;r=d3.select(this),a.utils.initSVG(r),m.domain(c||b.map(function(a,b){return o(a,b)})).rangeBands(e||[0,l],.1);var w=[];if(!d){var x=d3.min(b.map(function(a){var b=[];return b.push(a.values.Q1),a.values.hasOwnProperty("whisker_low")&&null!==a.values.whisker_low&&b.push(a.values.whisker_low),a.values.hasOwnProperty("outliers")&&null!==a.values.outliers&&(b=b.concat(a.values.outliers)),d3.min(b)})),y=d3.max(b.map(function(a){var b=[];return b.push(a.values.Q3),a.values.hasOwnProperty("whisker_high")&&null!==a.values.whisker_high&&b.push(a.values.whisker_high),a.values.hasOwnProperty("outliers")&&null!==a.values.outliers&&(b=b.concat(a.values.outliers)),d3.max(b)}));w=[x,y]}n.domain(d||w),n.range(f||[p,0]),g=g||m,h=h||n.copy().range([n(0),n(0)]);{var z=r.selectAll("g.nv-wrap").data([b]);z.enter().append("g").attr("class","nvd3 nv-wrap")}z.attr("transform","translate("+i.left+","+i.top+")");var A=z.selectAll(".nv-boxplot").data(function(a){return a}),B=A.enter().append("g").style("stroke-opacity",1e-6).style("fill-opacity",1e-6);A.attr("class","nv-boxplot").attr("transform",function(a,b){return"translate("+(m(o(a,b))+.05*m.rangeBand())+", 0)"}).classed("hover",function(a){return a.hover}),A.watchTransition(v,"nv-boxplot: boxplots").style("stroke-opacity",1).style("fill-opacity",.75).delay(function(a,c){return c*t/b.length}).attr("transform",function(a,b){return"translate("+(m(o(a,b))+.05*m.rangeBand())+", 0)"}),A.exit().remove(),B.each(function(a,b){var c=d3.select(this);["low","high"].forEach(function(d){a.values.hasOwnProperty("whisker_"+d)&&null!==a.values["whisker_"+d]&&(c.append("line").style("stroke",a.color?a.color:q(a,b)).attr("class","nv-boxplot-whisker nv-boxplot-"+d),c.append("line").style("stroke",a.color?a.color:q(a,b)).attr("class","nv-boxplot-tick nv-boxplot-"+d))})});var C=A.selectAll(".nv-boxplot-outlier").data(function(a){return a.values.hasOwnProperty("outliers")&&null!==a.values.outliers?a.values.outliers:[]});C.enter().append("circle").style("fill",function(a,b,c){return q(a,c)}).style("stroke",function(a,b,c){return q(a,c)}).on("mouseover",function(a,b,c){d3.select(this).classed("hover",!0),s.elementMouseover({series:{key:a,color:q(a,c)},e:d3.event})}).on("mouseout",function(a,b,c){d3.select(this).classed("hover",!1),s.elementMouseout({series:{key:a,color:q(a,c)},e:d3.event})}).on("mousemove",function(){s.elementMousemove({e:d3.event})}),C.attr("class","nv-boxplot-outlier"),C.watchTransition(v,"nv-boxplot: nv-boxplot-outlier").attr("cx",.45*m.rangeBand()).attr("cy",function(a){return n(a)}).attr("r","3"),C.exit().remove();var D=function(){return null===u?.9*m.rangeBand():Math.min(75,.9*m.rangeBand())},E=function(){return.45*m.rangeBand()-D()/2},F=function(){return.45*m.rangeBand()+D()/2};["low","high"].forEach(function(a){var b="low"===a?"Q1":"Q3";A.select("line.nv-boxplot-whisker.nv-boxplot-"+a).watchTransition(v,"nv-boxplot: boxplots").attr("x1",.45*m.rangeBand()).attr("y1",function(b){return n(b.values["whisker_"+a])}).attr("x2",.45*m.rangeBand()).attr("y2",function(a){return n(a.values[b])}),A.select("line.nv-boxplot-tick.nv-boxplot-"+a).watchTransition(v,"nv-boxplot: boxplots").attr("x1",E).attr("y1",function(b){return n(b.values["whisker_"+a])}).attr("x2",F).attr("y2",function(b){return n(b.values["whisker_"+a])})}),["low","high"].forEach(function(a){B.selectAll(".nv-boxplot-"+a).on("mouseover",function(b,c,d){d3.select(this).classed("hover",!0),s.elementMouseover({series:{key:b.values["whisker_"+a],color:q(b,d)},e:d3.event})}).on("mouseout",function(b,c,d){d3.select(this).classed("hover",!1),s.elementMouseout({series:{key:b.values["whisker_"+a],color:q(b,d)},e:d3.event})}).on("mousemove",function(){s.elementMousemove({e:d3.event})})}),B.append("rect").attr("class","nv-boxplot-box").on("mouseover",function(a,b){d3.select(this).classed("hover",!0),s.elementMouseover({key:a.label,value:a.label,series:[{key:"Q3",value:a.values.Q3,color:a.color||q(a,b)},{key:"Q2",value:a.values.Q2,color:a.color||q(a,b)},{key:"Q1",value:a.values.Q1,color:a.color||q(a,b)}],data:a,index:b,e:d3.event})}).on("mouseout",function(a,b){d3.select(this).classed("hover",!1),s.elementMouseout({key:a.label,value:a.label,series:[{key:"Q3",value:a.values.Q3,color:a.color||q(a,b)},{key:"Q2",value:a.values.Q2,color:a.color||q(a,b)},{key:"Q1",value:a.values.Q1,color:a.color||q(a,b)}],data:a,index:b,e:d3.event})}).on("mousemove",function(){s.elementMousemove({e:d3.event})}),A.select("rect.nv-boxplot-box").watchTransition(v,"nv-boxplot: boxes").attr("y",function(a){return n(a.values.Q3)}).attr("width",D).attr("x",E).attr("height",function(a){return Math.abs(n(a.values.Q3)-n(a.values.Q1))||1}).style("fill",function(a,b){return a.color||q(a,b)}).style("stroke",function(a,b){return a.color||q(a,b)}),B.append("line").attr("class","nv-boxplot-median"),A.select("line.nv-boxplot-median").watchTransition(v,"nv-boxplot: boxplots line").attr("x1",E).attr("y1",function(a){return n(a.values.Q2)}).attr("x2",F).attr("y2",function(a){return n(a.values.Q2)}),g=m.copy(),h=n.copy()}),v.renderEnd("nv-boxplot immediate"),b}var c,d,e,f,g,h,i={top:0,right:0,bottom:0,left:0},j=960,k=500,l=Math.floor(1e4*Math.random()),m=d3.scale.ordinal(),n=d3.scale.linear(),o=function(a){return a.x},p=function(a){return a.y},q=a.utils.defaultColor(),r=null,s=d3.dispatch("elementMouseover","elementMouseout","elementMousemove","renderEnd"),t=250,u=null,v=a.utils.renderWatch(s,t);return b.dispatch=s,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return j},set:function(a){j=a}},height:{get:function(){return k},set:function(a){k=a}},maxBoxWidth:{get:function(){return u},set:function(a){u=a}},x:{get:function(){return o},set:function(a){o=a}},y:{get:function(){return p},set:function(a){p=a}},xScale:{get:function(){return m},set:function(a){m=a}},yScale:{get:function(){return n},set:function(a){n=a}},xDomain:{get:function(){return c},set:function(a){c=a}},yDomain:{get:function(){return d},set:function(a){d=a}},xRange:{get:function(){return e},set:function(a){e=a}},yRange:{get:function(){return f},set:function(a){f=a}},id:{get:function(){return l},set:function(a){l=a}},margin:{get:function(){return i},set:function(a){i.top=void 0!==a.top?a.top:i.top,i.right=void 0!==a.right?a.right:i.right,i.bottom=void 0!==a.bottom?a.bottom:i.bottom,i.left=void 0!==a.left?a.left:i.left}},color:{get:function(){return q},set:function(b){q=a.utils.getColor(b)}},duration:{get:function(){return t},set:function(a){t=a,v.reset(t)}}}),a.utils.initOptions(b),b},a.models.boxPlotChart=function(){"use strict";function b(k){return t.reset(),t.models(e),l&&t.models(f),m&&t.models(g),k.each(function(k){var p=d3.select(this);a.utils.initSVG(p);var t=(i||parseInt(p.style("width"))||960)-h.left-h.right,u=(j||parseInt(p.style("height"))||400)-h.top-h.bottom;if(b.update=function(){r.beforeUpdate(),p.transition().duration(s).call(b)},b.container=this,!(k&&k.length&&k.filter(function(a){return a.values.hasOwnProperty("Q1")&&a.values.hasOwnProperty("Q2")&&a.values.hasOwnProperty("Q3")}).length)){var v=p.selectAll(".nv-noData").data([q]);return v.enter().append("text").attr("class","nvd3 nv-noData").attr("dy","-.7em").style("text-anchor","middle"),v.attr("x",h.left+t/2).attr("y",h.top+u/2).text(function(a){return a}),b}p.selectAll(".nv-noData").remove(),c=e.xScale(),d=e.yScale().clamp(!0);var w=p.selectAll("g.nv-wrap.nv-boxPlotWithAxes").data([k]),x=w.enter().append("g").attr("class","nvd3 nv-wrap nv-boxPlotWithAxes").append("g"),y=x.append("defs"),z=w.select("g"); -x.append("g").attr("class","nv-x nv-axis"),x.append("g").attr("class","nv-y nv-axis").append("g").attr("class","nv-zeroLine").append("line"),x.append("g").attr("class","nv-barsWrap"),z.attr("transform","translate("+h.left+","+h.top+")"),n&&z.select(".nv-y.nv-axis").attr("transform","translate("+t+",0)"),e.width(t).height(u);var A=z.select(".nv-barsWrap").datum(k.filter(function(a){return!a.disabled}));if(A.transition().call(e),y.append("clipPath").attr("id","nv-x-label-clip-"+e.id()).append("rect"),z.select("#nv-x-label-clip-"+e.id()+" rect").attr("width",c.rangeBand()*(o?2:1)).attr("height",16).attr("x",-c.rangeBand()/(o?1:2)),l){f.scale(c).ticks(a.utils.calcTicksX(t/100,k)).tickSize(-u,0),z.select(".nv-x.nv-axis").attr("transform","translate(0,"+d.range()[0]+")"),z.select(".nv-x.nv-axis").call(f);var B=z.select(".nv-x.nv-axis").selectAll("g");o&&B.selectAll("text").attr("transform",function(a,b,c){return"translate(0,"+(c%2==0?"5":"17")+")"})}m&&(g.scale(d).ticks(Math.floor(u/36)).tickSize(-t,0),z.select(".nv-y.nv-axis").call(g)),z.select(".nv-zeroLine line").attr("x1",0).attr("x2",t).attr("y1",d(0)).attr("y2",d(0))}),t.renderEnd("nv-boxplot chart immediate"),b}var c,d,e=a.models.boxPlot(),f=a.models.axis(),g=a.models.axis(),h={top:15,right:10,bottom:50,left:60},i=null,j=null,k=a.utils.getColor(),l=!0,m=!0,n=!1,o=!1,p=a.models.tooltip(),q="No Data Available.",r=d3.dispatch("tooltipShow","tooltipHide","beforeUpdate","renderEnd"),s=250;f.orient("bottom").showMaxMin(!1).tickFormat(function(a){return a}),g.orient(n?"right":"left").tickFormat(d3.format(",.1f")),p.duration(0);var t=a.utils.renderWatch(r,s);return e.dispatch.on("elementMouseover.tooltip",function(a){p.data(a).hidden(!1)}),e.dispatch.on("elementMouseout.tooltip",function(a){p.data(a).hidden(!0)}),e.dispatch.on("elementMousemove.tooltip",function(){p.position({top:d3.event.pageY,left:d3.event.pageX})()}),b.dispatch=r,b.boxplot=e,b.xAxis=f,b.yAxis=g,b.tooltip=p,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return i},set:function(a){i=a}},height:{get:function(){return j},set:function(a){j=a}},staggerLabels:{get:function(){return o},set:function(a){o=a}},showXAxis:{get:function(){return l},set:function(a){l=a}},showYAxis:{get:function(){return m},set:function(a){m=a}},tooltips:{get:function(){return tooltips},set:function(a){tooltips=a}},tooltipContent:{get:function(){return p},set:function(a){p=a}},noData:{get:function(){return q},set:function(a){q=a}},margin:{get:function(){return h},set:function(a){h.top=void 0!==a.top?a.top:h.top,h.right=void 0!==a.right?a.right:h.right,h.bottom=void 0!==a.bottom?a.bottom:h.bottom,h.left=void 0!==a.left?a.left:h.left}},duration:{get:function(){return s},set:function(a){s=a,t.reset(s),e.duration(s),f.duration(s),g.duration(s)}},color:{get:function(){return k},set:function(b){k=a.utils.getColor(b),e.color(k)}},rightAlignYAxis:{get:function(){return n},set:function(a){n=a,g.orient(a?"right":"left")}}}),a.utils.inheritOptions(b,e),a.utils.initOptions(b),b},a.models.bullet=function(){"use strict";function b(d){return d.each(function(b,d){var p=m-c.left-c.right,s=n-c.top-c.bottom;o=d3.select(this),a.utils.initSVG(o);{var t=f.call(this,b,d).slice().sort(d3.descending),u=g.call(this,b,d).slice().sort(d3.descending),v=h.call(this,b,d).slice().sort(d3.descending),w=i.call(this,b,d).slice(),x=j.call(this,b,d).slice(),y=k.call(this,b,d).slice(),z=d3.scale.linear().domain(d3.extent(d3.merge([l,t]))).range(e?[p,0]:[0,p]);this.__chart__||d3.scale.linear().domain([0,1/0]).range(z.range())}this.__chart__=z;var A=d3.min(t),B=d3.max(t),C=t[1],D=o.selectAll("g.nv-wrap.nv-bullet").data([b]),E=D.enter().append("g").attr("class","nvd3 nv-wrap nv-bullet"),F=E.append("g"),G=D.select("g");F.append("rect").attr("class","nv-range nv-rangeMax"),F.append("rect").attr("class","nv-range nv-rangeAvg"),F.append("rect").attr("class","nv-range nv-rangeMin"),F.append("rect").attr("class","nv-measure"),D.attr("transform","translate("+c.left+","+c.top+")");var H=function(a){return Math.abs(z(a)-z(0))},I=function(a){return z(0>a?a:0)};G.select("rect.nv-rangeMax").attr("height",s).attr("width",H(B>0?B:A)).attr("x",I(B>0?B:A)).datum(B>0?B:A),G.select("rect.nv-rangeAvg").attr("height",s).attr("width",H(C)).attr("x",I(C)).datum(C),G.select("rect.nv-rangeMin").attr("height",s).attr("width",H(B)).attr("x",I(B)).attr("width",H(B>0?A:B)).attr("x",I(B>0?A:B)).datum(B>0?A:B),G.select("rect.nv-measure").style("fill",q).attr("height",s/3).attr("y",s/3).attr("width",0>v?z(0)-z(v[0]):z(v[0])-z(0)).attr("x",I(v)).on("mouseover",function(){r.elementMouseover({value:v[0],label:y[0]||"Current",color:d3.select(this).style("fill")})}).on("mousemove",function(){r.elementMousemove({value:v[0],label:y[0]||"Current",color:d3.select(this).style("fill")})}).on("mouseout",function(){r.elementMouseout({value:v[0],label:y[0]||"Current",color:d3.select(this).style("fill")})});var J=s/6,K=u.map(function(a,b){return{value:a,label:x[b]}});F.selectAll("path.nv-markerTriangle").data(K).enter().append("path").attr("class","nv-markerTriangle").attr("transform",function(a){return"translate("+z(a.value)+","+s/2+")"}).attr("d","M0,"+J+"L"+J+","+-J+" "+-J+","+-J+"Z").on("mouseover",function(a){r.elementMouseover({value:a.value,label:a.label||"Previous",color:d3.select(this).style("fill"),pos:[z(a.value),s/2]})}).on("mousemove",function(a){r.elementMousemove({value:a.value,label:a.label||"Previous",color:d3.select(this).style("fill")})}).on("mouseout",function(a){r.elementMouseout({value:a.value,label:a.label||"Previous",color:d3.select(this).style("fill")})}),D.selectAll(".nv-range").on("mouseover",function(a,b){var c=w[b]||(b?1==b?"Mean":"Minimum":"Maximum");r.elementMouseover({value:a,label:c,color:d3.select(this).style("fill")})}).on("mousemove",function(){r.elementMousemove({value:v[0],label:y[0]||"Previous",color:d3.select(this).style("fill")})}).on("mouseout",function(a,b){var c=w[b]||(b?1==b?"Mean":"Minimum":"Maximum");r.elementMouseout({value:a,label:c,color:d3.select(this).style("fill")})})}),b}var c={top:0,right:0,bottom:0,left:0},d="left",e=!1,f=function(a){return a.ranges},g=function(a){return a.markers?a.markers:[0]},h=function(a){return a.measures},i=function(a){return a.rangeLabels?a.rangeLabels:[]},j=function(a){return a.markerLabels?a.markerLabels:[]},k=function(a){return a.measureLabels?a.measureLabels:[]},l=[0],m=380,n=30,o=null,p=null,q=a.utils.getColor(["#1f77b4"]),r=d3.dispatch("elementMouseover","elementMouseout","elementMousemove");return b.dispatch=r,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{ranges:{get:function(){return f},set:function(a){f=a}},markers:{get:function(){return g},set:function(a){g=a}},measures:{get:function(){return h},set:function(a){h=a}},forceX:{get:function(){return l},set:function(a){l=a}},width:{get:function(){return m},set:function(a){m=a}},height:{get:function(){return n},set:function(a){n=a}},tickFormat:{get:function(){return p},set:function(a){p=a}},margin:{get:function(){return c},set:function(a){c.top=void 0!==a.top?a.top:c.top,c.right=void 0!==a.right?a.right:c.right,c.bottom=void 0!==a.bottom?a.bottom:c.bottom,c.left=void 0!==a.left?a.left:c.left}},orient:{get:function(){return d},set:function(a){d=a,e="right"==d||"bottom"==d}},color:{get:function(){return q},set:function(b){q=a.utils.getColor(b)}}}),a.utils.initOptions(b),b},a.models.bulletChart=function(){"use strict";function b(d){return d.each(function(e,o){var p=d3.select(this);a.utils.initSVG(p);var q=a.utils.availableWidth(k,p,g),r=l-g.top-g.bottom;if(b.update=function(){b(d)},b.container=this,!e||!h.call(this,e,o))return a.utils.noData(b,p),b;p.selectAll(".nv-noData").remove();var s=h.call(this,e,o).slice().sort(d3.descending),t=i.call(this,e,o).slice().sort(d3.descending),u=j.call(this,e,o).slice().sort(d3.descending),v=p.selectAll("g.nv-wrap.nv-bulletChart").data([e]),w=v.enter().append("g").attr("class","nvd3 nv-wrap nv-bulletChart"),x=w.append("g"),y=v.select("g");x.append("g").attr("class","nv-bulletWrap"),x.append("g").attr("class","nv-titles"),v.attr("transform","translate("+g.left+","+g.top+")");var z=d3.scale.linear().domain([0,Math.max(s[0],t[0],u[0])]).range(f?[q,0]:[0,q]),A=this.__chart__||d3.scale.linear().domain([0,1/0]).range(z.range());this.__chart__=z;var B=x.select(".nv-titles").append("g").attr("text-anchor","end").attr("transform","translate(-6,"+(l-g.top-g.bottom)/2+")");B.append("text").attr("class","nv-title").text(function(a){return a.title}),B.append("text").attr("class","nv-subtitle").attr("dy","1em").text(function(a){return a.subtitle}),c.width(q).height(r);var C=y.select(".nv-bulletWrap");d3.transition(C).call(c);var D=m||z.tickFormat(q/100),E=y.selectAll("g.nv-tick").data(z.ticks(n?n:q/50),function(a){return this.textContent||D(a)}),F=E.enter().append("g").attr("class","nv-tick").attr("transform",function(a){return"translate("+A(a)+",0)"}).style("opacity",1e-6);F.append("line").attr("y1",r).attr("y2",7*r/6),F.append("text").attr("text-anchor","middle").attr("dy","1em").attr("y",7*r/6).text(D);var G=d3.transition(E).attr("transform",function(a){return"translate("+z(a)+",0)"}).style("opacity",1);G.select("line").attr("y1",r).attr("y2",7*r/6),G.select("text").attr("y",7*r/6),d3.transition(E.exit()).attr("transform",function(a){return"translate("+z(a)+",0)"}).style("opacity",1e-6).remove()}),d3.timer.flush(),b}var c=a.models.bullet(),d=a.models.tooltip(),e="left",f=!1,g={top:5,right:40,bottom:20,left:120},h=function(a){return a.ranges},i=function(a){return a.markers?a.markers:[0]},j=function(a){return a.measures},k=null,l=55,m=null,n=null,o=null,p=d3.dispatch("tooltipShow","tooltipHide");return d.duration(0).headerEnabled(!1),c.dispatch.on("elementMouseover.tooltip",function(a){a.series={key:a.label,value:a.value,color:a.color},d.data(a).hidden(!1)}),c.dispatch.on("elementMouseout.tooltip",function(){d.hidden(!0)}),c.dispatch.on("elementMousemove.tooltip",function(){d.position({top:d3.event.pageY,left:d3.event.pageX})()}),b.bullet=c,b.dispatch=p,b.tooltip=d,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{ranges:{get:function(){return h},set:function(a){h=a}},markers:{get:function(){return i},set:function(a){i=a}},measures:{get:function(){return j},set:function(a){j=a}},width:{get:function(){return k},set:function(a){k=a}},height:{get:function(){return l},set:function(a){l=a}},tickFormat:{get:function(){return m},set:function(a){m=a}},ticks:{get:function(){return n},set:function(a){n=a}},noData:{get:function(){return o},set:function(a){o=a}},tooltips:{get:function(){return d.enabled()},set:function(b){a.deprecated("tooltips","use chart.tooltip.enabled() instead"),d.enabled(!!b)}},tooltipContent:{get:function(){return d.contentGenerator()},set:function(b){a.deprecated("tooltipContent","use chart.tooltip.contentGenerator() instead"),d.contentGenerator(b)}},margin:{get:function(){return g},set:function(a){g.top=void 0!==a.top?a.top:g.top,g.right=void 0!==a.right?a.right:g.right,g.bottom=void 0!==a.bottom?a.bottom:g.bottom,g.left=void 0!==a.left?a.left:g.left}},orient:{get:function(){return e},set:function(a){e=a,f="right"==e||"bottom"==e}}}),a.utils.inheritOptions(b,c),a.utils.initOptions(b),b},a.models.candlestickBar=function(){"use strict";function b(x){return x.each(function(b){c=d3.select(this);var x=a.utils.availableWidth(i,c,h),y=a.utils.availableHeight(j,c,h);a.utils.initSVG(c);var A=x/b[0].values.length*.45;l.domain(d||d3.extent(b[0].values.map(n).concat(t))),l.range(v?f||[.5*x/b[0].values.length,x*(b[0].values.length-.5)/b[0].values.length]:f||[5+A/2,x-A/2-5]),m.domain(e||[d3.min(b[0].values.map(s).concat(u)),d3.max(b[0].values.map(r).concat(u))]).range(g||[y,0]),l.domain()[0]===l.domain()[1]&&l.domain(l.domain()[0]?[l.domain()[0]-.01*l.domain()[0],l.domain()[1]+.01*l.domain()[1]]:[-1,1]),m.domain()[0]===m.domain()[1]&&m.domain(m.domain()[0]?[m.domain()[0]+.01*m.domain()[0],m.domain()[1]-.01*m.domain()[1]]:[-1,1]);var B=d3.select(this).selectAll("g.nv-wrap.nv-candlestickBar").data([b[0].values]),C=B.enter().append("g").attr("class","nvd3 nv-wrap nv-candlestickBar"),D=C.append("defs"),E=C.append("g"),F=B.select("g");E.append("g").attr("class","nv-ticks"),B.attr("transform","translate("+h.left+","+h.top+")"),c.on("click",function(a,b){z.chartClick({data:a,index:b,pos:d3.event,id:k})}),D.append("clipPath").attr("id","nv-chart-clip-path-"+k).append("rect"),B.select("#nv-chart-clip-path-"+k+" rect").attr("width",x).attr("height",y),F.attr("clip-path",w?"url(#nv-chart-clip-path-"+k+")":"");var G=B.select(".nv-ticks").selectAll(".nv-tick").data(function(a){return a});G.exit().remove();{var H=G.enter().append("g").attr("class",function(a,b,c){return(p(a,b)>q(a,b)?"nv-tick negative":"nv-tick positive")+" nv-tick-"+c+"-"+b});H.append("line").attr("class","nv-candlestick-lines").attr("transform",function(a,b){return"translate("+l(n(a,b))+",0)"}).attr("x1",0).attr("y1",function(a,b){return m(r(a,b))}).attr("x2",0).attr("y2",function(a,b){return m(s(a,b))}),H.append("rect").attr("class","nv-candlestick-rects nv-bars").attr("transform",function(a,b){return"translate("+(l(n(a,b))-A/2)+","+(m(o(a,b))-(p(a,b)>q(a,b)?m(q(a,b))-m(p(a,b)):0))+")"}).attr("x",0).attr("y",0).attr("width",A).attr("height",function(a,b){var c=p(a,b),d=q(a,b);return c>d?m(d)-m(c):m(c)-m(d)})}c.selectAll(".nv-candlestick-lines").transition().attr("transform",function(a,b){return"translate("+l(n(a,b))+",0)"}).attr("x1",0).attr("y1",function(a,b){return m(r(a,b))}).attr("x2",0).attr("y2",function(a,b){return m(s(a,b))}),c.selectAll(".nv-candlestick-rects").transition().attr("transform",function(a,b){return"translate("+(l(n(a,b))-A/2)+","+(m(o(a,b))-(p(a,b)>q(a,b)?m(q(a,b))-m(p(a,b)):0))+")"}).attr("x",0).attr("y",0).attr("width",A).attr("height",function(a,b){var c=p(a,b),d=q(a,b);return c>d?m(d)-m(c):m(c)-m(d)})}),b}var c,d,e,f,g,h={top:0,right:0,bottom:0,left:0},i=null,j=null,k=Math.floor(1e4*Math.random()),l=d3.scale.linear(),m=d3.scale.linear(),n=function(a){return a.x},o=function(a){return a.y},p=function(a){return a.open},q=function(a){return a.close},r=function(a){return a.high},s=function(a){return a.low},t=[],u=[],v=!1,w=!0,x=a.utils.defaultColor(),y=!1,z=d3.dispatch("tooltipShow","tooltipHide","stateChange","changeState","renderEnd","chartClick","elementClick","elementDblClick","elementMouseover","elementMouseout","elementMousemove");return b.highlightPoint=function(a,d){b.clearHighlights(),c.select(".nv-candlestickBar .nv-tick-0-"+a).classed("hover",d)},b.clearHighlights=function(){c.select(".nv-candlestickBar .nv-tick.hover").classed("hover",!1)},b.dispatch=z,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return i},set:function(a){i=a}},height:{get:function(){return j},set:function(a){j=a}},xScale:{get:function(){return l},set:function(a){l=a}},yScale:{get:function(){return m},set:function(a){m=a}},xDomain:{get:function(){return d},set:function(a){d=a}},yDomain:{get:function(){return e},set:function(a){e=a}},xRange:{get:function(){return f},set:function(a){f=a}},yRange:{get:function(){return g},set:function(a){g=a}},forceX:{get:function(){return t},set:function(a){t=a}},forceY:{get:function(){return u},set:function(a){u=a}},padData:{get:function(){return v},set:function(a){v=a}},clipEdge:{get:function(){return w},set:function(a){w=a}},id:{get:function(){return k},set:function(a){k=a}},interactive:{get:function(){return y},set:function(a){y=a}},x:{get:function(){return n},set:function(a){n=a}},y:{get:function(){return o},set:function(a){o=a}},open:{get:function(){return p()},set:function(a){p=a}},close:{get:function(){return q()},set:function(a){q=a}},high:{get:function(){return r},set:function(a){r=a}},low:{get:function(){return s},set:function(a){s=a}},margin:{get:function(){return h},set:function(a){h.top=void 0!=a.top?a.top:h.top,h.right=void 0!=a.right?a.right:h.right,h.bottom=void 0!=a.bottom?a.bottom:h.bottom,h.left=void 0!=a.left?a.left:h.left}},color:{get:function(){return x},set:function(b){x=a.utils.getColor(b)}}}),a.utils.initOptions(b),b},a.models.cumulativeLineChart=function(){"use strict";function b(l){return H.reset(),H.models(f),r&&H.models(g),s&&H.models(h),l.each(function(l){function A(){d3.select(b.container).style("cursor","ew-resize")}function E(){G.x=d3.event.x,G.i=Math.round(F.invert(G.x)),K()}function H(){d3.select(b.container).style("cursor","auto"),y.index=G.i,C.stateChange(y)}function K(){bb.data([G]);var a=b.duration();b.duration(0),b.update(),b.duration(a)}var L=d3.select(this);a.utils.initSVG(L),L.classed("nv-chart-"+x,!0);var M=this,N=a.utils.availableWidth(o,L,m),O=a.utils.availableHeight(p,L,m);if(b.update=function(){0===D?L.call(b):L.transition().duration(D).call(b)},b.container=this,y.setter(J(l),b.update).getter(I(l)).update(),y.disabled=l.map(function(a){return!!a.disabled}),!z){var P;z={};for(P in y)z[P]=y[P]instanceof Array?y[P].slice(0):y[P]}var Q=d3.behavior.drag().on("dragstart",A).on("drag",E).on("dragend",H);if(!(l&&l.length&&l.filter(function(a){return a.values.length}).length))return a.utils.noData(b,L),b;if(L.selectAll(".nv-noData").remove(),d=f.xScale(),e=f.yScale(),w)f.yDomain(null);else{var R=l.filter(function(a){return!a.disabled}).map(function(a){var b=d3.extent(a.values,f.y());return b[0]<-.95&&(b[0]=-.95),[(b[0]-b[1])/(1+b[1]),(b[1]-b[0])/(1+b[0])]}),S=[d3.min(R,function(a){return a[0]}),d3.max(R,function(a){return a[1]})];f.yDomain(S)}F.domain([0,l[0].values.length-1]).range([0,N]).clamp(!0);var l=c(G.i,l),T=v?"none":"all",U=L.selectAll("g.nv-wrap.nv-cumulativeLine").data([l]),V=U.enter().append("g").attr("class","nvd3 nv-wrap nv-cumulativeLine").append("g"),W=U.select("g");if(V.append("g").attr("class","nv-interactive"),V.append("g").attr("class","nv-x nv-axis").style("pointer-events","none"),V.append("g").attr("class","nv-y nv-axis"),V.append("g").attr("class","nv-background"),V.append("g").attr("class","nv-linesWrap").style("pointer-events",T),V.append("g").attr("class","nv-avgLinesWrap").style("pointer-events","none"),V.append("g").attr("class","nv-legendWrap"),V.append("g").attr("class","nv-controlsWrap"),q&&(i.width(N),W.select(".nv-legendWrap").datum(l).call(i),m.top!=i.height()&&(m.top=i.height(),O=a.utils.availableHeight(p,L,m)),W.select(".nv-legendWrap").attr("transform","translate(0,"+-m.top+")")),u){var X=[{key:"Re-scale y-axis",disabled:!w}];j.width(140).color(["#444","#444","#444"]).rightAlign(!1).margin({top:5,right:0,bottom:5,left:20}),W.select(".nv-controlsWrap").datum(X).attr("transform","translate(0,"+-m.top+")").call(j)}U.attr("transform","translate("+m.left+","+m.top+")"),t&&W.select(".nv-y.nv-axis").attr("transform","translate("+N+",0)");var Y=l.filter(function(a){return a.tempDisabled});U.select(".tempDisabled").remove(),Y.length&&U.append("text").attr("class","tempDisabled").attr("x",N/2).attr("y","-.71em").style("text-anchor","end").text(Y.map(function(a){return a.key}).join(", ")+" values cannot be calculated for this time period."),v&&(k.width(N).height(O).margin({left:m.left,top:m.top}).svgContainer(L).xScale(d),U.select(".nv-interactive").call(k)),V.select(".nv-background").append("rect"),W.select(".nv-background rect").attr("width",N).attr("height",O),f.y(function(a){return a.display.y}).width(N).height(O).color(l.map(function(a,b){return a.color||n(a,b)}).filter(function(a,b){return!l[b].disabled&&!l[b].tempDisabled}));var Z=W.select(".nv-linesWrap").datum(l.filter(function(a){return!a.disabled&&!a.tempDisabled}));Z.call(f),l.forEach(function(a,b){a.seriesIndex=b});var $=l.filter(function(a){return!a.disabled&&!!B(a)}),_=W.select(".nv-avgLinesWrap").selectAll("line").data($,function(a){return a.key}),ab=function(a){var b=e(B(a));return 0>b?0:b>O?O:b};_.enter().append("line").style("stroke-width",2).style("stroke-dasharray","10,10").style("stroke",function(a){return f.color()(a,a.seriesIndex)}).attr("x1",0).attr("x2",N).attr("y1",ab).attr("y2",ab),_.style("stroke-opacity",function(a){var b=e(B(a));return 0>b||b>O?0:1}).attr("x1",0).attr("x2",N).attr("y1",ab).attr("y2",ab),_.exit().remove();var bb=Z.selectAll(".nv-indexLine").data([G]);bb.enter().append("rect").attr("class","nv-indexLine").attr("width",3).attr("x",-2).attr("fill","red").attr("fill-opacity",.5).style("pointer-events","all").call(Q),bb.attr("transform",function(a){return"translate("+F(a.i)+",0)"}).attr("height",O),r&&(g.scale(d)._ticks(a.utils.calcTicksX(N/70,l)).tickSize(-O,0),W.select(".nv-x.nv-axis").attr("transform","translate(0,"+e.range()[0]+")"),W.select(".nv-x.nv-axis").call(g)),s&&(h.scale(e)._ticks(a.utils.calcTicksY(O/36,l)).tickSize(-N,0),W.select(".nv-y.nv-axis").call(h)),W.select(".nv-background rect").on("click",function(){G.x=d3.mouse(this)[0],G.i=Math.round(F.invert(G.x)),y.index=G.i,C.stateChange(y),K()}),f.dispatch.on("elementClick",function(a){G.i=a.pointIndex,G.x=F(G.i),y.index=G.i,C.stateChange(y),K()}),j.dispatch.on("legendClick",function(a){a.disabled=!a.disabled,w=!a.disabled,y.rescaleY=w,C.stateChange(y),b.update()}),i.dispatch.on("stateChange",function(a){for(var c in a)y[c]=a[c];C.stateChange(y),b.update()}),k.dispatch.on("elementMousemove",function(c){f.clearHighlights();var d,e,i,j=[];if(l.filter(function(a,b){return a.seriesIndex=b,!a.disabled}).forEach(function(g,h){e=a.interactiveBisect(g.values,c.pointXValue,b.x()),f.highlightPoint(h,e,!0);var k=g.values[e];"undefined"!=typeof k&&("undefined"==typeof d&&(d=k),"undefined"==typeof i&&(i=b.xScale()(b.x()(k,e))),j.push({key:g.key,value:b.y()(k,e),color:n(g,g.seriesIndex)}))}),j.length>2){var o=b.yScale().invert(c.mouseY),p=Math.abs(b.yScale().domain()[0]-b.yScale().domain()[1]),q=.03*p,r=a.nearestValueIndex(j.map(function(a){return a.value}),o,q);null!==r&&(j[r].highlight=!0)}var s=g.tickFormat()(b.x()(d,e),e);k.tooltip.position({left:i+m.left,top:c.mouseY+m.top}).chartContainer(M.parentNode).valueFormatter(function(a){return h.tickFormat()(a)}).data({value:s,series:j})(),k.renderGuideLine(i)}),k.dispatch.on("elementMouseout",function(){f.clearHighlights()}),C.on("changeState",function(a){"undefined"!=typeof a.disabled&&(l.forEach(function(b,c){b.disabled=a.disabled[c]}),y.disabled=a.disabled),"undefined"!=typeof a.index&&(G.i=a.index,G.x=F(G.i),y.index=a.index,bb.data([G])),"undefined"!=typeof a.rescaleY&&(w=a.rescaleY),b.update()})}),H.renderEnd("cumulativeLineChart immediate"),b}function c(a,b){return K||(K=f.y()),b.map(function(b){if(!b.values)return b;var c=b.values[a];if(null==c)return b;var d=K(c,a);return-.95>d&&!E?(b.tempDisabled=!0,b):(b.tempDisabled=!1,b.values=b.values.map(function(a,b){return a.display={y:(K(a,b)-d)/(1+d)},a}),b)})}var d,e,f=a.models.line(),g=a.models.axis(),h=a.models.axis(),i=a.models.legend(),j=a.models.legend(),k=a.interactiveGuideline(),l=a.models.tooltip(),m={top:30,right:30,bottom:50,left:60},n=a.utils.defaultColor(),o=null,p=null,q=!0,r=!0,s=!0,t=!1,u=!0,v=!1,w=!0,x=f.id(),y=a.utils.state(),z=null,A=null,B=function(a){return a.average},C=d3.dispatch("stateChange","changeState","renderEnd"),D=250,E=!1;y.index=0,y.rescaleY=w,g.orient("bottom").tickPadding(7),h.orient(t?"right":"left"),l.valueFormatter(function(a,b){return h.tickFormat()(a,b)}).headerFormatter(function(a,b){return g.tickFormat()(a,b)}),j.updateState(!1);var F=d3.scale.linear(),G={i:0,x:0},H=a.utils.renderWatch(C,D),I=function(a){return function(){return{active:a.map(function(a){return!a.disabled}),index:G.i,rescaleY:w}}},J=function(a){return function(b){void 0!==b.index&&(G.i=b.index),void 0!==b.rescaleY&&(w=b.rescaleY),void 0!==b.active&&a.forEach(function(a,c){a.disabled=!b.active[c]})}};f.dispatch.on("elementMouseover.tooltip",function(a){var c={x:b.x()(a.point),y:b.y()(a.point),color:a.point.color};a.point=c,l.data(a).position(a.pos).hidden(!1)}),f.dispatch.on("elementMouseout.tooltip",function(){l.hidden(!0)});var K=null;return b.dispatch=C,b.lines=f,b.legend=i,b.controls=j,b.xAxis=g,b.yAxis=h,b.interactiveLayer=k,b.state=y,b.tooltip=l,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return o},set:function(a){o=a}},height:{get:function(){return p},set:function(a){p=a}},rescaleY:{get:function(){return w},set:function(a){w=a}},showControls:{get:function(){return u},set:function(a){u=a}},showLegend:{get:function(){return q},set:function(a){q=a}},average:{get:function(){return B},set:function(a){B=a}},defaultState:{get:function(){return z},set:function(a){z=a}},noData:{get:function(){return A},set:function(a){A=a}},showXAxis:{get:function(){return r},set:function(a){r=a}},showYAxis:{get:function(){return s},set:function(a){s=a}},noErrorCheck:{get:function(){return E},set:function(a){E=a}},tooltips:{get:function(){return l.enabled()},set:function(b){a.deprecated("tooltips","use chart.tooltip.enabled() instead"),l.enabled(!!b)}},tooltipContent:{get:function(){return l.contentGenerator()},set:function(b){a.deprecated("tooltipContent","use chart.tooltip.contentGenerator() instead"),l.contentGenerator(b)}},margin:{get:function(){return m},set:function(a){m.top=void 0!==a.top?a.top:m.top,m.right=void 0!==a.right?a.right:m.right,m.bottom=void 0!==a.bottom?a.bottom:m.bottom,m.left=void 0!==a.left?a.left:m.left}},color:{get:function(){return n},set:function(b){n=a.utils.getColor(b),i.color(n)}},useInteractiveGuideline:{get:function(){return v},set:function(a){v=a,a===!0&&(b.interactive(!1),b.useVoronoi(!1))}},rightAlignYAxis:{get:function(){return t},set:function(a){t=a,h.orient(a?"right":"left")}},duration:{get:function(){return D},set:function(a){D=a,f.duration(D),g.duration(D),h.duration(D),H.reset(D)}}}),a.utils.inheritOptions(b,f),a.utils.initOptions(b),b},a.models.discreteBar=function(){"use strict";function b(m){return y.reset(),m.each(function(b){var m=k-j.left-j.right,x=l-j.top-j.bottom;c=d3.select(this),a.utils.initSVG(c),b.forEach(function(a,b){a.values.forEach(function(a){a.series=b})});var z=d&&e?[]:b.map(function(a){return a.values.map(function(a,b){return{x:p(a,b),y:q(a,b),y0:a.y0}})});n.domain(d||d3.merge(z).map(function(a){return a.x})).rangeBands(f||[0,m],.1),o.domain(e||d3.extent(d3.merge(z).map(function(a){return a.y}).concat(r))),o.range(t?g||[x-(o.domain()[0]<0?12:0),o.domain()[1]>0?12:0]:g||[x,0]),h=h||n,i=i||o.copy().range([o(0),o(0)]);{var A=c.selectAll("g.nv-wrap.nv-discretebar").data([b]),B=A.enter().append("g").attr("class","nvd3 nv-wrap nv-discretebar"),C=B.append("g");A.select("g")}C.append("g").attr("class","nv-groups"),A.attr("transform","translate("+j.left+","+j.top+")");var D=A.select(".nv-groups").selectAll(".nv-group").data(function(a){return a},function(a){return a.key});D.enter().append("g").style("stroke-opacity",1e-6).style("fill-opacity",1e-6),D.exit().watchTransition(y,"discreteBar: exit groups").style("stroke-opacity",1e-6).style("fill-opacity",1e-6).remove(),D.attr("class",function(a,b){return"nv-group nv-series-"+b}).classed("hover",function(a){return a.hover}),D.watchTransition(y,"discreteBar: groups").style("stroke-opacity",1).style("fill-opacity",.75);var E=D.selectAll("g.nv-bar").data(function(a){return a.values});E.exit().remove();var F=E.enter().append("g").attr("transform",function(a,b){return"translate("+(n(p(a,b))+.05*n.rangeBand())+", "+o(0)+")"}).on("mouseover",function(a,b){d3.select(this).classed("hover",!0),v.elementMouseover({data:a,index:b,color:d3.select(this).style("fill")})}).on("mouseout",function(a,b){d3.select(this).classed("hover",!1),v.elementMouseout({data:a,index:b,color:d3.select(this).style("fill")})}).on("mousemove",function(a,b){v.elementMousemove({data:a,index:b,color:d3.select(this).style("fill")})}).on("click",function(a,b){v.elementClick({data:a,index:b,color:d3.select(this).style("fill")}),d3.event.stopPropagation()}).on("dblclick",function(a,b){v.elementDblClick({data:a,index:b,color:d3.select(this).style("fill")}),d3.event.stopPropagation()});F.append("rect").attr("height",0).attr("width",.9*n.rangeBand()/b.length),t?(F.append("text").attr("text-anchor","middle"),E.select("text").text(function(a,b){return u(q(a,b))}).watchTransition(y,"discreteBar: bars text").attr("x",.9*n.rangeBand()/2).attr("y",function(a,b){return q(a,b)<0?o(q(a,b))-o(0)+12:-4})):E.selectAll("text").remove(),E.attr("class",function(a,b){return q(a,b)<0?"nv-bar negative":"nv-bar positive"}).style("fill",function(a,b){return a.color||s(a,b)}).style("stroke",function(a,b){return a.color||s(a,b)}).select("rect").attr("class",w).watchTransition(y,"discreteBar: bars rect").attr("width",.9*n.rangeBand()/b.length),E.watchTransition(y,"discreteBar: bars").attr("transform",function(a,b){var c=n(p(a,b))+.05*n.rangeBand(),d=q(a,b)<0?o(0):o(0)-o(q(a,b))<1?o(0)-1:o(q(a,b));return"translate("+c+", "+d+")"}).select("rect").attr("height",function(a,b){return Math.max(Math.abs(o(q(a,b))-o(e&&e[0]||0))||1)}),h=n.copy(),i=o.copy()}),y.renderEnd("discreteBar immediate"),b}var c,d,e,f,g,h,i,j={top:0,right:0,bottom:0,left:0},k=960,l=500,m=Math.floor(1e4*Math.random()),n=d3.scale.ordinal(),o=d3.scale.linear(),p=function(a){return a.x},q=function(a){return a.y},r=[0],s=a.utils.defaultColor(),t=!1,u=d3.format(",.2f"),v=d3.dispatch("chartClick","elementClick","elementDblClick","elementMouseover","elementMouseout","elementMousemove","renderEnd"),w="discreteBar",x=250,y=a.utils.renderWatch(v,x);return b.dispatch=v,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return k},set:function(a){k=a}},height:{get:function(){return l},set:function(a){l=a}},forceY:{get:function(){return r},set:function(a){r=a}},showValues:{get:function(){return t},set:function(a){t=a}},x:{get:function(){return p},set:function(a){p=a}},y:{get:function(){return q},set:function(a){q=a}},xScale:{get:function(){return n},set:function(a){n=a}},yScale:{get:function(){return o},set:function(a){o=a}},xDomain:{get:function(){return d},set:function(a){d=a}},yDomain:{get:function(){return e},set:function(a){e=a}},xRange:{get:function(){return f},set:function(a){f=a}},yRange:{get:function(){return g},set:function(a){g=a}},valueFormat:{get:function(){return u},set:function(a){u=a}},id:{get:function(){return m},set:function(a){m=a}},rectClass:{get:function(){return w},set:function(a){w=a}},margin:{get:function(){return j},set:function(a){j.top=void 0!==a.top?a.top:j.top,j.right=void 0!==a.right?a.right:j.right,j.bottom=void 0!==a.bottom?a.bottom:j.bottom,j.left=void 0!==a.left?a.left:j.left}},color:{get:function(){return s},set:function(b){s=a.utils.getColor(b)}},duration:{get:function(){return x},set:function(a){x=a,y.reset(x)}}}),a.utils.initOptions(b),b},a.models.discreteBarChart=function(){"use strict";function b(h){return t.reset(),t.models(e),m&&t.models(f),n&&t.models(g),h.each(function(h){var l=d3.select(this);a.utils.initSVG(l);var q=a.utils.availableWidth(j,l,i),t=a.utils.availableHeight(k,l,i);if(b.update=function(){r.beforeUpdate(),l.transition().duration(s).call(b)},b.container=this,!(h&&h.length&&h.filter(function(a){return a.values.length}).length))return a.utils.noData(b,l),b;l.selectAll(".nv-noData").remove(),c=e.xScale(),d=e.yScale().clamp(!0);var u=l.selectAll("g.nv-wrap.nv-discreteBarWithAxes").data([h]),v=u.enter().append("g").attr("class","nvd3 nv-wrap nv-discreteBarWithAxes").append("g"),w=v.append("defs"),x=u.select("g");v.append("g").attr("class","nv-x nv-axis"),v.append("g").attr("class","nv-y nv-axis").append("g").attr("class","nv-zeroLine").append("line"),v.append("g").attr("class","nv-barsWrap"),x.attr("transform","translate("+i.left+","+i.top+")"),o&&x.select(".nv-y.nv-axis").attr("transform","translate("+q+",0)"),e.width(q).height(t);var y=x.select(".nv-barsWrap").datum(h.filter(function(a){return!a.disabled}));if(y.transition().call(e),w.append("clipPath").attr("id","nv-x-label-clip-"+e.id()).append("rect"),x.select("#nv-x-label-clip-"+e.id()+" rect").attr("width",c.rangeBand()*(p?2:1)).attr("height",16).attr("x",-c.rangeBand()/(p?1:2)),m){f.scale(c)._ticks(a.utils.calcTicksX(q/100,h)).tickSize(-t,0),x.select(".nv-x.nv-axis").attr("transform","translate(0,"+(d.range()[0]+(e.showValues()&&d.domain()[0]<0?16:0))+")"),x.select(".nv-x.nv-axis").call(f); -var z=x.select(".nv-x.nv-axis").selectAll("g");p&&z.selectAll("text").attr("transform",function(a,b,c){return"translate(0,"+(c%2==0?"5":"17")+")"})}n&&(g.scale(d)._ticks(a.utils.calcTicksY(t/36,h)).tickSize(-q,0),x.select(".nv-y.nv-axis").call(g)),x.select(".nv-zeroLine line").attr("x1",0).attr("x2",q).attr("y1",d(0)).attr("y2",d(0))}),t.renderEnd("discreteBar chart immediate"),b}var c,d,e=a.models.discreteBar(),f=a.models.axis(),g=a.models.axis(),h=a.models.tooltip(),i={top:15,right:10,bottom:50,left:60},j=null,k=null,l=a.utils.getColor(),m=!0,n=!0,o=!1,p=!1,q=null,r=d3.dispatch("beforeUpdate","renderEnd"),s=250;f.orient("bottom").showMaxMin(!1).tickFormat(function(a){return a}),g.orient(o?"right":"left").tickFormat(d3.format(",.1f")),h.duration(0).headerEnabled(!1).valueFormatter(function(a,b){return g.tickFormat()(a,b)}).keyFormatter(function(a,b){return f.tickFormat()(a,b)});var t=a.utils.renderWatch(r,s);return e.dispatch.on("elementMouseover.tooltip",function(a){a.series={key:b.x()(a.data),value:b.y()(a.data),color:a.color},h.data(a).hidden(!1)}),e.dispatch.on("elementMouseout.tooltip",function(){h.hidden(!0)}),e.dispatch.on("elementMousemove.tooltip",function(){h.position({top:d3.event.pageY,left:d3.event.pageX})()}),b.dispatch=r,b.discretebar=e,b.xAxis=f,b.yAxis=g,b.tooltip=h,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return j},set:function(a){j=a}},height:{get:function(){return k},set:function(a){k=a}},staggerLabels:{get:function(){return p},set:function(a){p=a}},showXAxis:{get:function(){return m},set:function(a){m=a}},showYAxis:{get:function(){return n},set:function(a){n=a}},noData:{get:function(){return q},set:function(a){q=a}},tooltips:{get:function(){return h.enabled()},set:function(b){a.deprecated("tooltips","use chart.tooltip.enabled() instead"),h.enabled(!!b)}},tooltipContent:{get:function(){return h.contentGenerator()},set:function(b){a.deprecated("tooltipContent","use chart.tooltip.contentGenerator() instead"),h.contentGenerator(b)}},margin:{get:function(){return i},set:function(a){i.top=void 0!==a.top?a.top:i.top,i.right=void 0!==a.right?a.right:i.right,i.bottom=void 0!==a.bottom?a.bottom:i.bottom,i.left=void 0!==a.left?a.left:i.left}},duration:{get:function(){return s},set:function(a){s=a,t.reset(s),e.duration(s),f.duration(s),g.duration(s)}},color:{get:function(){return l},set:function(b){l=a.utils.getColor(b),e.color(l)}},rightAlignYAxis:{get:function(){return o},set:function(a){o=a,g.orient(a?"right":"left")}}}),a.utils.inheritOptions(b,e),a.utils.initOptions(b),b},a.models.distribution=function(){"use strict";function b(k){return m.reset(),k.each(function(b){var k=(e-("x"===g?d.left+d.right:d.top+d.bottom),"x"==g?"y":"x"),l=d3.select(this);a.utils.initSVG(l),c=c||j;var n=l.selectAll("g.nv-distribution").data([b]),o=n.enter().append("g").attr("class","nvd3 nv-distribution"),p=(o.append("g"),n.select("g"));n.attr("transform","translate("+d.left+","+d.top+")");var q=p.selectAll("g.nv-dist").data(function(a){return a},function(a){return a.key});q.enter().append("g"),q.attr("class",function(a,b){return"nv-dist nv-series-"+b}).style("stroke",function(a,b){return i(a,b)});var r=q.selectAll("line.nv-dist"+g).data(function(a){return a.values});r.enter().append("line").attr(g+"1",function(a,b){return c(h(a,b))}).attr(g+"2",function(a,b){return c(h(a,b))}),m.transition(q.exit().selectAll("line.nv-dist"+g),"dist exit").attr(g+"1",function(a,b){return j(h(a,b))}).attr(g+"2",function(a,b){return j(h(a,b))}).style("stroke-opacity",0).remove(),r.attr("class",function(a,b){return"nv-dist"+g+" nv-dist"+g+"-"+b}).attr(k+"1",0).attr(k+"2",f),m.transition(r,"dist").attr(g+"1",function(a,b){return j(h(a,b))}).attr(g+"2",function(a,b){return j(h(a,b))}),c=j.copy()}),m.renderEnd("distribution immediate"),b}var c,d={top:0,right:0,bottom:0,left:0},e=400,f=8,g="x",h=function(a){return a[g]},i=a.utils.defaultColor(),j=d3.scale.linear(),k=250,l=d3.dispatch("renderEnd"),m=a.utils.renderWatch(l,k);return b.options=a.utils.optionsFunc.bind(b),b.dispatch=l,b.margin=function(a){return arguments.length?(d.top="undefined"!=typeof a.top?a.top:d.top,d.right="undefined"!=typeof a.right?a.right:d.right,d.bottom="undefined"!=typeof a.bottom?a.bottom:d.bottom,d.left="undefined"!=typeof a.left?a.left:d.left,b):d},b.width=function(a){return arguments.length?(e=a,b):e},b.axis=function(a){return arguments.length?(g=a,b):g},b.size=function(a){return arguments.length?(f=a,b):f},b.getData=function(a){return arguments.length?(h=d3.functor(a),b):h},b.scale=function(a){return arguments.length?(j=a,b):j},b.color=function(c){return arguments.length?(i=a.utils.getColor(c),b):i},b.duration=function(a){return arguments.length?(k=a,m.reset(k),b):k},b},a.models.furiousLegend=function(){"use strict";function b(p){function q(a,b){return"furious"!=o?"#000":m?a.disengaged?g(a,b):"#fff":m?void 0:a.disabled?g(a,b):"#fff"}function r(a,b){return m&&"furious"==o?a.disengaged?"#fff":g(a,b):a.disabled?"#fff":g(a,b)}return p.each(function(b){var p=d-c.left-c.right,s=d3.select(this);a.utils.initSVG(s);var t=s.selectAll("g.nv-legend").data([b]),u=(t.enter().append("g").attr("class","nvd3 nv-legend").append("g"),t.select("g"));t.attr("transform","translate("+c.left+","+c.top+")");var v,w=u.selectAll(".nv-series").data(function(a){return"furious"!=o?a:a.filter(function(a){return m?!0:!a.disengaged})}),x=w.enter().append("g").attr("class","nv-series");if("classic"==o)x.append("circle").style("stroke-width",2).attr("class","nv-legend-symbol").attr("r",5),v=w.select("circle");else if("furious"==o){x.append("rect").style("stroke-width",2).attr("class","nv-legend-symbol").attr("rx",3).attr("ry",3),v=w.select("rect"),x.append("g").attr("class","nv-check-box").property("innerHTML",'').attr("transform","translate(-10,-8)scale(0.5)");var y=w.select(".nv-check-box");y.each(function(a,b){d3.select(this).selectAll("path").attr("stroke",q(a,b))})}x.append("text").attr("text-anchor","start").attr("class","nv-legend-text").attr("dy",".32em").attr("dx","8");var z=w.select("text.nv-legend-text");w.on("mouseover",function(a,b){n.legendMouseover(a,b)}).on("mouseout",function(a,b){n.legendMouseout(a,b)}).on("click",function(a,b){n.legendClick(a,b);var c=w.data();if(k){if("classic"==o)l?(c.forEach(function(a){a.disabled=!0}),a.disabled=!1):(a.disabled=!a.disabled,c.every(function(a){return a.disabled})&&c.forEach(function(a){a.disabled=!1}));else if("furious"==o)if(m)a.disengaged=!a.disengaged,a.userDisabled=void 0==a.userDisabled?!!a.disabled:a.userDisabled,a.disabled=a.disengaged||a.userDisabled;else if(!m){a.disabled=!a.disabled,a.userDisabled=a.disabled;var d=c.filter(function(a){return!a.disengaged});d.every(function(a){return a.userDisabled})&&c.forEach(function(a){a.disabled=a.userDisabled=!1})}n.stateChange({disabled:c.map(function(a){return!!a.disabled}),disengaged:c.map(function(a){return!!a.disengaged})})}}).on("dblclick",function(a,b){if(("furious"!=o||!m)&&(n.legendDblclick(a,b),k)){var c=w.data();c.forEach(function(a){a.disabled=!0,"furious"==o&&(a.userDisabled=a.disabled)}),a.disabled=!1,"furious"==o&&(a.userDisabled=a.disabled),n.stateChange({disabled:c.map(function(a){return!!a.disabled})})}}),w.classed("nv-disabled",function(a){return a.userDisabled}),w.exit().remove(),z.attr("fill",q).text(f);var A;switch(o){case"furious":A=23;break;case"classic":A=20}if(h){var B=[];w.each(function(){var b,c=d3.select(this).select("text");try{if(b=c.node().getComputedTextLength(),0>=b)throw Error()}catch(d){b=a.utils.calcApproxTextWidth(c)}B.push(b+i)});for(var C=0,D=0,E=[];p>D&&Cp&&C>1;){E=[],C--;for(var F=0;F(E[F%C]||0)&&(E[F%C]=B[F]);D=E.reduce(function(a,b){return a+b})}for(var G=[],H=0,I=0;C>H;H++)G[H]=I,I+=E[H];w.attr("transform",function(a,b){return"translate("+G[b%C]+","+(5+Math.floor(b/C)*A)+")"}),j?u.attr("transform","translate("+(d-c.right-D)+","+c.top+")"):u.attr("transform","translate(0,"+c.top+")"),e=c.top+c.bottom+Math.ceil(B.length/C)*A}else{var J,K=5,L=5,M=0;w.attr("transform",function(){var a=d3.select(this).select("text").node().getComputedTextLength()+i;return J=L,dM&&(M=L),"translate("+J+","+K+")"}),u.attr("transform","translate("+(d-c.right-M)+","+c.top+")"),e=c.top+c.bottom+K+15}"furious"==o&&v.attr("width",function(a,b){return z[0][b].getComputedTextLength()+27}).attr("height",18).attr("y",-9).attr("x",-15),v.style("fill",r).style("stroke",function(a,b){return a.color||g(a,b)})}),b}var c={top:5,right:0,bottom:5,left:0},d=400,e=20,f=function(a){return a.key},g=a.utils.getColor(),h=!0,i=28,j=!0,k=!0,l=!1,m=!1,n=d3.dispatch("legendClick","legendDblclick","legendMouseover","legendMouseout","stateChange"),o="classic";return b.dispatch=n,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return d},set:function(a){d=a}},height:{get:function(){return e},set:function(a){e=a}},key:{get:function(){return f},set:function(a){f=a}},align:{get:function(){return h},set:function(a){h=a}},rightAlign:{get:function(){return j},set:function(a){j=a}},padding:{get:function(){return i},set:function(a){i=a}},updateState:{get:function(){return k},set:function(a){k=a}},radioButtonMode:{get:function(){return l},set:function(a){l=a}},expanded:{get:function(){return m},set:function(a){m=a}},vers:{get:function(){return o},set:function(a){o=a}},margin:{get:function(){return c},set:function(a){c.top=void 0!==a.top?a.top:c.top,c.right=void 0!==a.right?a.right:c.right,c.bottom=void 0!==a.bottom?a.bottom:c.bottom,c.left=void 0!==a.left?a.left:c.left}},color:{get:function(){return g},set:function(b){g=a.utils.getColor(b)}}}),a.utils.initOptions(b),b},a.models.historicalBar=function(){"use strict";function b(x){return x.each(function(b){w.reset(),k=d3.select(this);var x=a.utils.availableWidth(h,k,g),y=a.utils.availableHeight(i,k,g);a.utils.initSVG(k),l.domain(c||d3.extent(b[0].values.map(n).concat(p))),l.range(r?e||[.5*x/b[0].values.length,x*(b[0].values.length-.5)/b[0].values.length]:e||[0,x]),m.domain(d||d3.extent(b[0].values.map(o).concat(q))).range(f||[y,0]),l.domain()[0]===l.domain()[1]&&l.domain(l.domain()[0]?[l.domain()[0]-.01*l.domain()[0],l.domain()[1]+.01*l.domain()[1]]:[-1,1]),m.domain()[0]===m.domain()[1]&&m.domain(m.domain()[0]?[m.domain()[0]+.01*m.domain()[0],m.domain()[1]-.01*m.domain()[1]]:[-1,1]);var z=k.selectAll("g.nv-wrap.nv-historicalBar-"+j).data([b[0].values]),A=z.enter().append("g").attr("class","nvd3 nv-wrap nv-historicalBar-"+j),B=A.append("defs"),C=A.append("g"),D=z.select("g");C.append("g").attr("class","nv-bars"),z.attr("transform","translate("+g.left+","+g.top+")"),k.on("click",function(a,b){u.chartClick({data:a,index:b,pos:d3.event,id:j})}),B.append("clipPath").attr("id","nv-chart-clip-path-"+j).append("rect"),z.select("#nv-chart-clip-path-"+j+" rect").attr("width",x).attr("height",y),D.attr("clip-path",s?"url(#nv-chart-clip-path-"+j+")":"");var E=z.select(".nv-bars").selectAll(".nv-bar").data(function(a){return a},function(a,b){return n(a,b)});E.exit().remove(),E.enter().append("rect").attr("x",0).attr("y",function(b,c){return a.utils.NaNtoZero(m(Math.max(0,o(b,c))))}).attr("height",function(b,c){return a.utils.NaNtoZero(Math.abs(m(o(b,c))-m(0)))}).attr("transform",function(a,c){return"translate("+(l(n(a,c))-x/b[0].values.length*.45)+",0)"}).on("mouseover",function(a,b){v&&(d3.select(this).classed("hover",!0),u.elementMouseover({data:a,index:b,color:d3.select(this).style("fill")}))}).on("mouseout",function(a,b){v&&(d3.select(this).classed("hover",!1),u.elementMouseout({data:a,index:b,color:d3.select(this).style("fill")}))}).on("mousemove",function(a,b){v&&u.elementMousemove({data:a,index:b,color:d3.select(this).style("fill")})}).on("click",function(a,b){v&&(u.elementClick({data:a,index:b,color:d3.select(this).style("fill")}),d3.event.stopPropagation())}).on("dblclick",function(a,b){v&&(u.elementDblClick({data:a,index:b,color:d3.select(this).style("fill")}),d3.event.stopPropagation())}),E.attr("fill",function(a,b){return t(a,b)}).attr("class",function(a,b,c){return(o(a,b)<0?"nv-bar negative":"nv-bar positive")+" nv-bar-"+c+"-"+b}).watchTransition(w,"bars").attr("transform",function(a,c){return"translate("+(l(n(a,c))-x/b[0].values.length*.45)+",0)"}).attr("width",x/b[0].values.length*.9),E.watchTransition(w,"bars").attr("y",function(b,c){var d=o(b,c)<0?m(0):m(0)-m(o(b,c))<1?m(0)-1:m(o(b,c));return a.utils.NaNtoZero(d)}).attr("height",function(b,c){return a.utils.NaNtoZero(Math.max(Math.abs(m(o(b,c))-m(0)),1))})}),w.renderEnd("historicalBar immediate"),b}var c,d,e,f,g={top:0,right:0,bottom:0,left:0},h=null,i=null,j=Math.floor(1e4*Math.random()),k=null,l=d3.scale.linear(),m=d3.scale.linear(),n=function(a){return a.x},o=function(a){return a.y},p=[],q=[0],r=!1,s=!0,t=a.utils.defaultColor(),u=d3.dispatch("chartClick","elementClick","elementDblClick","elementMouseover","elementMouseout","elementMousemove","renderEnd"),v=!0,w=a.utils.renderWatch(u,0);return b.highlightPoint=function(a,b){k.select(".nv-bars .nv-bar-0-"+a).classed("hover",b)},b.clearHighlights=function(){k.select(".nv-bars .nv-bar.hover").classed("hover",!1)},b.dispatch=u,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return h},set:function(a){h=a}},height:{get:function(){return i},set:function(a){i=a}},forceX:{get:function(){return p},set:function(a){p=a}},forceY:{get:function(){return q},set:function(a){q=a}},padData:{get:function(){return r},set:function(a){r=a}},x:{get:function(){return n},set:function(a){n=a}},y:{get:function(){return o},set:function(a){o=a}},xScale:{get:function(){return l},set:function(a){l=a}},yScale:{get:function(){return m},set:function(a){m=a}},xDomain:{get:function(){return c},set:function(a){c=a}},yDomain:{get:function(){return d},set:function(a){d=a}},xRange:{get:function(){return e},set:function(a){e=a}},yRange:{get:function(){return f},set:function(a){f=a}},clipEdge:{get:function(){return s},set:function(a){s=a}},id:{get:function(){return j},set:function(a){j=a}},interactive:{get:function(){return v},set:function(a){v=a}},margin:{get:function(){return g},set:function(a){g.top=void 0!==a.top?a.top:g.top,g.right=void 0!==a.right?a.right:g.right,g.bottom=void 0!==a.bottom?a.bottom:g.bottom,g.left=void 0!==a.left?a.left:g.left}},color:{get:function(){return t},set:function(b){t=a.utils.getColor(b)}}}),a.utils.initOptions(b),b},a.models.historicalBarChart=function(b){"use strict";function c(b){return b.each(function(k){z.reset(),z.models(f),q&&z.models(g),r&&z.models(h);var w=d3.select(this),A=this;a.utils.initSVG(w);var B=a.utils.availableWidth(n,w,l),C=a.utils.availableHeight(o,w,l);if(c.update=function(){w.transition().duration(y).call(c)},c.container=this,u.disabled=k.map(function(a){return!!a.disabled}),!v){var D;v={};for(D in u)v[D]=u[D]instanceof Array?u[D].slice(0):u[D]}if(!(k&&k.length&&k.filter(function(a){return a.values.length}).length))return a.utils.noData(c,w),c;w.selectAll(".nv-noData").remove(),d=f.xScale(),e=f.yScale();var E=w.selectAll("g.nv-wrap.nv-historicalBarChart").data([k]),F=E.enter().append("g").attr("class","nvd3 nv-wrap nv-historicalBarChart").append("g"),G=E.select("g");F.append("g").attr("class","nv-x nv-axis"),F.append("g").attr("class","nv-y nv-axis"),F.append("g").attr("class","nv-barsWrap"),F.append("g").attr("class","nv-legendWrap"),F.append("g").attr("class","nv-interactive"),p&&(i.width(B),G.select(".nv-legendWrap").datum(k).call(i),l.top!=i.height()&&(l.top=i.height(),C=a.utils.availableHeight(o,w,l)),E.select(".nv-legendWrap").attr("transform","translate(0,"+-l.top+")")),E.attr("transform","translate("+l.left+","+l.top+")"),s&&G.select(".nv-y.nv-axis").attr("transform","translate("+B+",0)"),t&&(j.width(B).height(C).margin({left:l.left,top:l.top}).svgContainer(w).xScale(d),E.select(".nv-interactive").call(j)),f.width(B).height(C).color(k.map(function(a,b){return a.color||m(a,b)}).filter(function(a,b){return!k[b].disabled}));var H=G.select(".nv-barsWrap").datum(k.filter(function(a){return!a.disabled}));H.transition().call(f),q&&(g.scale(d)._ticks(a.utils.calcTicksX(B/100,k)).tickSize(-C,0),G.select(".nv-x.nv-axis").attr("transform","translate(0,"+e.range()[0]+")"),G.select(".nv-x.nv-axis").transition().call(g)),r&&(h.scale(e)._ticks(a.utils.calcTicksY(C/36,k)).tickSize(-B,0),G.select(".nv-y.nv-axis").transition().call(h)),j.dispatch.on("elementMousemove",function(b){f.clearHighlights();var d,e,i,n=[];k.filter(function(a,b){return a.seriesIndex=b,!a.disabled}).forEach(function(g){e=a.interactiveBisect(g.values,b.pointXValue,c.x()),f.highlightPoint(e,!0);var h=g.values[e];void 0!==h&&(void 0===d&&(d=h),void 0===i&&(i=c.xScale()(c.x()(h,e))),n.push({key:g.key,value:c.y()(h,e),color:m(g,g.seriesIndex),data:g.values[e]}))});var o=g.tickFormat()(c.x()(d,e));j.tooltip.position({left:i+l.left,top:b.mouseY+l.top}).chartContainer(A.parentNode).valueFormatter(function(a){return h.tickFormat()(a)}).data({value:o,index:e,series:n})(),j.renderGuideLine(i)}),j.dispatch.on("elementMouseout",function(){x.tooltipHide(),f.clearHighlights()}),i.dispatch.on("legendClick",function(a){a.disabled=!a.disabled,k.filter(function(a){return!a.disabled}).length||k.map(function(a){return a.disabled=!1,E.selectAll(".nv-series").classed("disabled",!1),a}),u.disabled=k.map(function(a){return!!a.disabled}),x.stateChange(u),b.transition().call(c)}),i.dispatch.on("legendDblclick",function(a){k.forEach(function(a){a.disabled=!0}),a.disabled=!1,u.disabled=k.map(function(a){return!!a.disabled}),x.stateChange(u),c.update()}),x.on("changeState",function(a){"undefined"!=typeof a.disabled&&(k.forEach(function(b,c){b.disabled=a.disabled[c]}),u.disabled=a.disabled),c.update()})}),z.renderEnd("historicalBarChart immediate"),c}var d,e,f=b||a.models.historicalBar(),g=a.models.axis(),h=a.models.axis(),i=a.models.legend(),j=a.interactiveGuideline(),k=a.models.tooltip(),l={top:30,right:90,bottom:50,left:90},m=a.utils.defaultColor(),n=null,o=null,p=!1,q=!0,r=!0,s=!1,t=!1,u={},v=null,w=null,x=d3.dispatch("tooltipHide","stateChange","changeState","renderEnd"),y=250;g.orient("bottom").tickPadding(7),h.orient(s?"right":"left"),k.duration(0).headerEnabled(!1).valueFormatter(function(a,b){return h.tickFormat()(a,b)}).headerFormatter(function(a,b){return g.tickFormat()(a,b)});var z=a.utils.renderWatch(x,0);return f.dispatch.on("elementMouseover.tooltip",function(a){a.series={key:c.x()(a.data),value:c.y()(a.data),color:a.color},k.data(a).hidden(!1)}),f.dispatch.on("elementMouseout.tooltip",function(){k.hidden(!0)}),f.dispatch.on("elementMousemove.tooltip",function(){k.position({top:d3.event.pageY,left:d3.event.pageX})()}),c.dispatch=x,c.bars=f,c.legend=i,c.xAxis=g,c.yAxis=h,c.interactiveLayer=j,c.tooltip=k,c.options=a.utils.optionsFunc.bind(c),c._options=Object.create({},{width:{get:function(){return n},set:function(a){n=a}},height:{get:function(){return o},set:function(a){o=a}},showLegend:{get:function(){return p},set:function(a){p=a}},showXAxis:{get:function(){return q},set:function(a){q=a}},showYAxis:{get:function(){return r},set:function(a){r=a}},defaultState:{get:function(){return v},set:function(a){v=a}},noData:{get:function(){return w},set:function(a){w=a}},tooltips:{get:function(){return k.enabled()},set:function(b){a.deprecated("tooltips","use chart.tooltip.enabled() instead"),k.enabled(!!b)}},tooltipContent:{get:function(){return k.contentGenerator()},set:function(b){a.deprecated("tooltipContent","use chart.tooltip.contentGenerator() instead"),k.contentGenerator(b)}},margin:{get:function(){return l},set:function(a){l.top=void 0!==a.top?a.top:l.top,l.right=void 0!==a.right?a.right:l.right,l.bottom=void 0!==a.bottom?a.bottom:l.bottom,l.left=void 0!==a.left?a.left:l.left}},color:{get:function(){return m},set:function(b){m=a.utils.getColor(b),i.color(m),f.color(m)}},duration:{get:function(){return y},set:function(a){y=a,z.reset(y),h.duration(y),g.duration(y)}},rightAlignYAxis:{get:function(){return s},set:function(a){s=a,h.orient(a?"right":"left")}},useInteractiveGuideline:{get:function(){return t},set:function(a){t=a,a===!0&&c.interactive(!1)}}}),a.utils.inheritOptions(c,f),a.utils.initOptions(c),c},a.models.ohlcBarChart=function(){var b=a.models.historicalBarChart(a.models.ohlcBar());return b.useInteractiveGuideline(!0),b.interactiveLayer.tooltip.contentGenerator(function(a){var c=a.series[0].data,d=c.open'+a.value+"
open:"+b.yAxis.tickFormat()(c.open)+"
close:"+b.yAxis.tickFormat()(c.close)+"
high"+b.yAxis.tickFormat()(c.high)+"
low:"+b.yAxis.tickFormat()(c.low)+"
"}),b},a.models.candlestickBarChart=function(){var b=a.models.historicalBarChart(a.models.candlestickBar());return b.useInteractiveGuideline(!0),b.interactiveLayer.tooltip.contentGenerator(function(a){var c=a.series[0].data,d=c.open'+a.value+"
open:"+b.yAxis.tickFormat()(c.open)+"
close:"+b.yAxis.tickFormat()(c.close)+"
high"+b.yAxis.tickFormat()(c.high)+"
low:"+b.yAxis.tickFormat()(c.low)+"
"}),b},a.models.legend=function(){"use strict";function b(p){function q(a,b){return"furious"!=o?"#000":m?a.disengaged?"#000":"#fff":m?void 0:(a.color||(a.color=g(a,b)),a.disabled?a.color:"#fff")}function r(a,b){return m&&"furious"==o&&a.disengaged?"#eee":a.color||g(a,b)}function s(a){return m&&"furious"==o?1:a.disabled?0:1}return p.each(function(b){var g=d-c.left-c.right,p=d3.select(this);a.utils.initSVG(p);var t=p.selectAll("g.nv-legend").data([b]),u=t.enter().append("g").attr("class","nvd3 nv-legend").append("g"),v=t.select("g");t.attr("transform","translate("+c.left+","+c.top+")");var w,x,y=v.selectAll(".nv-series").data(function(a){return"furious"!=o?a:a.filter(function(a){return m?!0:!a.disengaged})}),z=y.enter().append("g").attr("class","nv-series");switch(o){case"furious":x=23;break;case"classic":x=20}if("classic"==o)z.append("circle").style("stroke-width",2).attr("class","nv-legend-symbol").attr("r",5),w=y.select("circle");else if("furious"==o){z.append("rect").style("stroke-width",2).attr("class","nv-legend-symbol").attr("rx",3).attr("ry",3),w=y.select(".nv-legend-symbol"),z.append("g").attr("class","nv-check-box").property("innerHTML",'').attr("transform","translate(-10,-8)scale(0.5)");var A=y.select(".nv-check-box");A.each(function(a,b){d3.select(this).selectAll("path").attr("stroke",q(a,b))})}z.append("text").attr("text-anchor","start").attr("class","nv-legend-text").attr("dy",".32em").attr("dx","8");var B=y.select("text.nv-legend-text");y.on("mouseover",function(a,b){n.legendMouseover(a,b)}).on("mouseout",function(a,b){n.legendMouseout(a,b)}).on("click",function(a,b){n.legendClick(a,b);var c=y.data();if(k){if("classic"==o)l?(c.forEach(function(a){a.disabled=!0}),a.disabled=!1):(a.disabled=!a.disabled,c.every(function(a){return a.disabled})&&c.forEach(function(a){a.disabled=!1}));else if("furious"==o)if(m)a.disengaged=!a.disengaged,a.userDisabled=void 0==a.userDisabled?!!a.disabled:a.userDisabled,a.disabled=a.disengaged||a.userDisabled;else if(!m){a.disabled=!a.disabled,a.userDisabled=a.disabled;var d=c.filter(function(a){return!a.disengaged});d.every(function(a){return a.userDisabled})&&c.forEach(function(a){a.disabled=a.userDisabled=!1})}n.stateChange({disabled:c.map(function(a){return!!a.disabled}),disengaged:c.map(function(a){return!!a.disengaged})})}}).on("dblclick",function(a,b){if(("furious"!=o||!m)&&(n.legendDblclick(a,b),k)){var c=y.data();c.forEach(function(a){a.disabled=!0,"furious"==o&&(a.userDisabled=a.disabled)}),a.disabled=!1,"furious"==o&&(a.userDisabled=a.disabled),n.stateChange({disabled:c.map(function(a){return!!a.disabled})})}}),y.classed("nv-disabled",function(a){return a.userDisabled}),y.exit().remove(),B.attr("fill",q).text(f);var C=0;if(h){var D=[];y.each(function(){var b,c=d3.select(this).select("text");try{if(b=c.node().getComputedTextLength(),0>=b)throw Error()}catch(d){b=a.utils.calcApproxTextWidth(c)}D.push(b+i)});var E=0,F=[];for(C=0;g>C&&Eg&&E>1;){F=[],E--;for(var G=0;G(F[G%E]||0)&&(F[G%E]=D[G]);C=F.reduce(function(a,b){return a+b})}for(var H=[],I=0,J=0;E>I;I++)H[I]=J,J+=F[I];y.attr("transform",function(a,b){return"translate("+H[b%E]+","+(5+Math.floor(b/E)*x)+")"}),j?v.attr("transform","translate("+(d-c.right-C)+","+c.top+")"):v.attr("transform","translate(0,"+c.top+")"),e=c.top+c.bottom+Math.ceil(D.length/E)*x}else{var K,L=5,M=5,N=0;y.attr("transform",function(){var a=d3.select(this).select("text").node().getComputedTextLength()+i;return K=M,dN&&(N=M),K+N>C&&(C=K+N),"translate("+K+","+L+")"}),v.attr("transform","translate("+(d-c.right-N)+","+c.top+")"),e=c.top+c.bottom+L+15}if("furious"==o){w.attr("width",function(a,b){return B[0][b].getComputedTextLength()+27}).attr("height",18).attr("y",-9).attr("x",-15),u.insert("rect",":first-child").attr("class","nv-legend-bg").attr("fill","#eee").attr("opacity",0);var O=v.select(".nv-legend-bg");O.transition().duration(300).attr("x",-x).attr("width",C+x-12).attr("height",e+10).attr("y",-c.top-10).attr("opacity",m?1:0)}w.style("fill",r).style("fill-opacity",s).style("stroke",r)}),b}var c={top:5,right:0,bottom:5,left:0},d=400,e=20,f=function(a){return a.key},g=a.utils.getColor(),h=!0,i=32,j=!0,k=!0,l=!1,m=!1,n=d3.dispatch("legendClick","legendDblclick","legendMouseover","legendMouseout","stateChange"),o="classic";return b.dispatch=n,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return d},set:function(a){d=a}},height:{get:function(){return e},set:function(a){e=a}},key:{get:function(){return f},set:function(a){f=a}},align:{get:function(){return h},set:function(a){h=a}},rightAlign:{get:function(){return j},set:function(a){j=a}},padding:{get:function(){return i},set:function(a){i=a}},updateState:{get:function(){return k},set:function(a){k=a}},radioButtonMode:{get:function(){return l},set:function(a){l=a}},expanded:{get:function(){return m},set:function(a){m=a}},vers:{get:function(){return o},set:function(a){o=a}},margin:{get:function(){return c},set:function(a){c.top=void 0!==a.top?a.top:c.top,c.right=void 0!==a.right?a.right:c.right,c.bottom=void 0!==a.bottom?a.bottom:c.bottom,c.left=void 0!==a.left?a.left:c.left}},color:{get:function(){return g},set:function(b){g=a.utils.getColor(b)}}}),a.utils.initOptions(b),b},a.models.line=function(){"use strict";function b(r){return v.reset(),v.models(e),r.each(function(b){i=d3.select(this);var r=a.utils.availableWidth(g,i,f),s=a.utils.availableHeight(h,i,f);a.utils.initSVG(i),c=e.xScale(),d=e.yScale(),t=t||c,u=u||d;var w=i.selectAll("g.nv-wrap.nv-line").data([b]),x=w.enter().append("g").attr("class","nvd3 nv-wrap nv-line"),y=x.append("defs"),z=x.append("g"),A=w.select("g");z.append("g").attr("class","nv-groups"),z.append("g").attr("class","nv-scatterWrap"),w.attr("transform","translate("+f.left+","+f.top+")"),e.width(r).height(s);var B=w.select(".nv-scatterWrap");B.call(e),y.append("clipPath").attr("id","nv-edge-clip-"+e.id()).append("rect"),w.select("#nv-edge-clip-"+e.id()+" rect").attr("width",r).attr("height",s>0?s:0),A.attr("clip-path",p?"url(#nv-edge-clip-"+e.id()+")":""),B.attr("clip-path",p?"url(#nv-edge-clip-"+e.id()+")":"");var C=w.select(".nv-groups").selectAll(".nv-group").data(function(a){return a},function(a){return a.key});C.enter().append("g").style("stroke-opacity",1e-6).style("stroke-width",function(a){return a.strokeWidth||j}).style("fill-opacity",1e-6),C.exit().remove(),C.attr("class",function(a,b){return(a.classed||"")+" nv-group nv-series-"+b}).classed("hover",function(a){return a.hover}).style("fill",function(a,b){return k(a,b)}).style("stroke",function(a,b){return k(a,b)}),C.watchTransition(v,"line: groups").style("stroke-opacity",1).style("fill-opacity",function(a){return a.fillOpacity||.5});var D=C.selectAll("path.nv-area").data(function(a){return o(a)?[a]:[]});D.enter().append("path").attr("class","nv-area").attr("d",function(b){return d3.svg.area().interpolate(q).defined(n).x(function(b,c){return a.utils.NaNtoZero(t(l(b,c)))}).y0(function(b,c){return a.utils.NaNtoZero(u(m(b,c)))}).y1(function(){return u(d.domain()[0]<=0?d.domain()[1]>=0?0:d.domain()[1]:d.domain()[0])}).apply(this,[b.values])}),C.exit().selectAll("path.nv-area").remove(),D.watchTransition(v,"line: areaPaths").attr("d",function(b){return d3.svg.area().interpolate(q).defined(n).x(function(b,d){return a.utils.NaNtoZero(c(l(b,d)))}).y0(function(b,c){return a.utils.NaNtoZero(d(m(b,c)))}).y1(function(){return d(d.domain()[0]<=0?d.domain()[1]>=0?0:d.domain()[1]:d.domain()[0])}).apply(this,[b.values])});var E=C.selectAll("path.nv-line").data(function(a){return[a.values]});E.enter().append("path").attr("class","nv-line").attr("d",d3.svg.line().interpolate(q).defined(n).x(function(b,c){return a.utils.NaNtoZero(t(l(b,c)))}).y(function(b,c){return a.utils.NaNtoZero(u(m(b,c)))})),E.watchTransition(v,"line: linePaths").attr("d",d3.svg.line().interpolate(q).defined(n).x(function(b,d){return a.utils.NaNtoZero(c(l(b,d)))}).y(function(b,c){return a.utils.NaNtoZero(d(m(b,c)))})),t=c.copy(),u=d.copy()}),v.renderEnd("line immediate"),b}var c,d,e=a.models.scatter(),f={top:0,right:0,bottom:0,left:0},g=960,h=500,i=null,j=1.5,k=a.utils.defaultColor(),l=function(a){return a.x},m=function(a){return a.y},n=function(a,b){return!isNaN(m(a,b))&&null!==m(a,b)},o=function(a){return a.area},p=!1,q="linear",r=250,s=d3.dispatch("elementClick","elementMouseover","elementMouseout","renderEnd");e.pointSize(16).pointDomain([16,256]);var t,u,v=a.utils.renderWatch(s,r);return b.dispatch=s,b.scatter=e,e.dispatch.on("elementClick",function(){s.elementClick.apply(this,arguments)}),e.dispatch.on("elementMouseover",function(){s.elementMouseover.apply(this,arguments)}),e.dispatch.on("elementMouseout",function(){s.elementMouseout.apply(this,arguments)}),b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return g},set:function(a){g=a}},height:{get:function(){return h},set:function(a){h=a}},defined:{get:function(){return n},set:function(a){n=a}},interpolate:{get:function(){return q},set:function(a){q=a}},clipEdge:{get:function(){return p},set:function(a){p=a}},margin:{get:function(){return f},set:function(a){f.top=void 0!==a.top?a.top:f.top,f.right=void 0!==a.right?a.right:f.right,f.bottom=void 0!==a.bottom?a.bottom:f.bottom,f.left=void 0!==a.left?a.left:f.left}},duration:{get:function(){return r},set:function(a){r=a,v.reset(r),e.duration(r)}},isArea:{get:function(){return o},set:function(a){o=d3.functor(a)}},x:{get:function(){return l},set:function(a){l=a,e.x(a)}},y:{get:function(){return m},set:function(a){m=a,e.y(a)}},color:{get:function(){return k},set:function(b){k=a.utils.getColor(b),e.color(k)}}}),a.utils.inheritOptions(b,e),a.utils.initOptions(b),b},a.models.lineChart=function(){"use strict";function b(j){return y.reset(),y.models(e),p&&y.models(f),q&&y.models(g),j.each(function(j){var v=d3.select(this),y=this;a.utils.initSVG(v);var B=a.utils.availableWidth(m,v,k),C=a.utils.availableHeight(n,v,k);if(b.update=function(){0===x?v.call(b):v.transition().duration(x).call(b)},b.container=this,t.setter(A(j),b.update).getter(z(j)).update(),t.disabled=j.map(function(a){return!!a.disabled}),!u){var D;u={};for(D in t)u[D]=t[D]instanceof Array?t[D].slice(0):t[D] -}if(!(j&&j.length&&j.filter(function(a){return a.values.length}).length))return a.utils.noData(b,v),b;v.selectAll(".nv-noData").remove(),c=e.xScale(),d=e.yScale();var E=v.selectAll("g.nv-wrap.nv-lineChart").data([j]),F=E.enter().append("g").attr("class","nvd3 nv-wrap nv-lineChart").append("g"),G=E.select("g");F.append("rect").style("opacity",0),F.append("g").attr("class","nv-x nv-axis"),F.append("g").attr("class","nv-y nv-axis"),F.append("g").attr("class","nv-linesWrap"),F.append("g").attr("class","nv-legendWrap"),F.append("g").attr("class","nv-interactive"),G.select("rect").attr("width",B).attr("height",C>0?C:0),o&&(h.width(B),G.select(".nv-legendWrap").datum(j).call(h),k.top!=h.height()&&(k.top=h.height(),C=a.utils.availableHeight(n,v,k)),E.select(".nv-legendWrap").attr("transform","translate(0,"+-k.top+")")),E.attr("transform","translate("+k.left+","+k.top+")"),r&&G.select(".nv-y.nv-axis").attr("transform","translate("+B+",0)"),s&&(i.width(B).height(C).margin({left:k.left,top:k.top}).svgContainer(v).xScale(c),E.select(".nv-interactive").call(i)),e.width(B).height(C).color(j.map(function(a,b){return a.color||l(a,b)}).filter(function(a,b){return!j[b].disabled}));var H=G.select(".nv-linesWrap").datum(j.filter(function(a){return!a.disabled}));H.call(e),p&&(f.scale(c)._ticks(a.utils.calcTicksX(B/100,j)).tickSize(-C,0),G.select(".nv-x.nv-axis").attr("transform","translate(0,"+d.range()[0]+")"),G.select(".nv-x.nv-axis").call(f)),q&&(g.scale(d)._ticks(a.utils.calcTicksY(C/36,j)).tickSize(-B,0),G.select(".nv-y.nv-axis").call(g)),h.dispatch.on("stateChange",function(a){for(var c in a)t[c]=a[c];w.stateChange(t),b.update()}),i.dispatch.on("elementMousemove",function(c){e.clearHighlights();var d,h,m,n=[];if(j.filter(function(a,b){return a.seriesIndex=b,!a.disabled}).forEach(function(f,g){h=a.interactiveBisect(f.values,c.pointXValue,b.x());var i=f.values[h],j=b.y()(i,h);null!=j&&e.highlightPoint(g,h,!0),void 0!==i&&(void 0===d&&(d=i),void 0===m&&(m=b.xScale()(b.x()(i,h))),n.push({key:f.key,value:j,color:l(f,f.seriesIndex)}))}),n.length>2){var o=b.yScale().invert(c.mouseY),p=Math.abs(b.yScale().domain()[0]-b.yScale().domain()[1]),q=.03*p,r=a.nearestValueIndex(n.map(function(a){return a.value}),o,q);null!==r&&(n[r].highlight=!0)}var s=f.tickFormat()(b.x()(d,h));i.tooltip.position({left:c.mouseX+k.left,top:c.mouseY+k.top}).chartContainer(y.parentNode).valueFormatter(function(a){return null==a?"N/A":g.tickFormat()(a)}).data({value:s,index:h,series:n})(),i.renderGuideLine(m)}),i.dispatch.on("elementClick",function(c){var d,f=[];j.filter(function(a,b){return a.seriesIndex=b,!a.disabled}).forEach(function(e){var g=a.interactiveBisect(e.values,c.pointXValue,b.x()),h=e.values[g];if("undefined"!=typeof h){"undefined"==typeof d&&(d=b.xScale()(b.x()(h,g)));var i=b.yScale()(b.y()(h,g));f.push({point:h,pointIndex:g,pos:[d,i],seriesIndex:e.seriesIndex,series:e})}}),e.dispatch.elementClick(f)}),i.dispatch.on("elementMouseout",function(){e.clearHighlights()}),w.on("changeState",function(a){"undefined"!=typeof a.disabled&&j.length===a.disabled.length&&(j.forEach(function(b,c){b.disabled=a.disabled[c]}),t.disabled=a.disabled),b.update()})}),y.renderEnd("lineChart immediate"),b}var c,d,e=a.models.line(),f=a.models.axis(),g=a.models.axis(),h=a.models.legend(),i=a.interactiveGuideline(),j=a.models.tooltip(),k={top:30,right:20,bottom:50,left:60},l=a.utils.defaultColor(),m=null,n=null,o=!0,p=!0,q=!0,r=!1,s=!1,t=a.utils.state(),u=null,v=null,w=d3.dispatch("tooltipShow","tooltipHide","stateChange","changeState","renderEnd"),x=250;f.orient("bottom").tickPadding(7),g.orient(r?"right":"left"),j.valueFormatter(function(a,b){return g.tickFormat()(a,b)}).headerFormatter(function(a,b){return f.tickFormat()(a,b)});var y=a.utils.renderWatch(w,x),z=function(a){return function(){return{active:a.map(function(a){return!a.disabled})}}},A=function(a){return function(b){void 0!==b.active&&a.forEach(function(a,c){a.disabled=!b.active[c]})}};return e.dispatch.on("elementMouseover.tooltip",function(a){j.data(a).position(a.pos).hidden(!1)}),e.dispatch.on("elementMouseout.tooltip",function(){j.hidden(!0)}),b.dispatch=w,b.lines=e,b.legend=h,b.xAxis=f,b.yAxis=g,b.interactiveLayer=i,b.tooltip=j,b.dispatch=w,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return m},set:function(a){m=a}},height:{get:function(){return n},set:function(a){n=a}},showLegend:{get:function(){return o},set:function(a){o=a}},showXAxis:{get:function(){return p},set:function(a){p=a}},showYAxis:{get:function(){return q},set:function(a){q=a}},defaultState:{get:function(){return u},set:function(a){u=a}},noData:{get:function(){return v},set:function(a){v=a}},tooltips:{get:function(){return j.enabled()},set:function(b){a.deprecated("tooltips","use chart.tooltip.enabled() instead"),j.enabled(!!b)}},tooltipContent:{get:function(){return j.contentGenerator()},set:function(b){a.deprecated("tooltipContent","use chart.tooltip.contentGenerator() instead"),j.contentGenerator(b)}},margin:{get:function(){return k},set:function(a){k.top=void 0!==a.top?a.top:k.top,k.right=void 0!==a.right?a.right:k.right,k.bottom=void 0!==a.bottom?a.bottom:k.bottom,k.left=void 0!==a.left?a.left:k.left}},duration:{get:function(){return x},set:function(a){x=a,y.reset(x),e.duration(x),f.duration(x),g.duration(x)}},color:{get:function(){return l},set:function(b){l=a.utils.getColor(b),h.color(l),e.color(l)}},rightAlignYAxis:{get:function(){return r},set:function(a){r=a,g.orient(r?"right":"left")}},useInteractiveGuideline:{get:function(){return s},set:function(a){s=a,s&&(e.interactive(!1),e.useVoronoi(!1))}}}),a.utils.inheritOptions(b,e),a.utils.initOptions(b),b},a.models.linePlusBarChart=function(){"use strict";function b(v){return v.each(function(v){function J(a){var b=+("e"==a),c=b?1:-1,d=X/3;return"M"+.5*c+","+d+"A6,6 0 0 "+b+" "+6.5*c+","+(d+6)+"V"+(2*d-6)+"A6,6 0 0 "+b+" "+.5*c+","+2*d+"ZM"+2.5*c+","+(d+8)+"V"+(2*d-8)+"M"+4.5*c+","+(d+8)+"V"+(2*d-8)}function S(){u.empty()||u.extent(I),kb.data([u.empty()?e.domain():I]).each(function(a){var b=e(a[0])-e.range()[0],c=e.range()[1]-e(a[1]);d3.select(this).select(".left").attr("width",0>b?0:b),d3.select(this).select(".right").attr("x",e(a[1])).attr("width",0>c?0:c)})}function T(){I=u.empty()?null:u.extent(),c=u.empty()?e.domain():u.extent(),K.brush({extent:c,brush:u}),S(),l.width(V).height(W).color(v.map(function(a,b){return a.color||C(a,b)}).filter(function(a,b){return!v[b].disabled&&v[b].bar})),j.width(V).height(W).color(v.map(function(a,b){return a.color||C(a,b)}).filter(function(a,b){return!v[b].disabled&&!v[b].bar}));var b=db.select(".nv-focus .nv-barsWrap").datum(Z.length?Z.map(function(a){return{key:a.key,values:a.values.filter(function(a,b){return l.x()(a,b)>=c[0]&&l.x()(a,b)<=c[1]})}}):[{values:[]}]),h=db.select(".nv-focus .nv-linesWrap").datum($[0].disabled?[{values:[]}]:$.map(function(a){return{area:a.area,fillOpacity:a.fillOpacity,key:a.key,values:a.values.filter(function(a,b){return j.x()(a,b)>=c[0]&&j.x()(a,b)<=c[1]})}}));d=Z.length?l.xScale():j.xScale(),n.scale(d)._ticks(a.utils.calcTicksX(V/100,v)).tickSize(-W,0),n.domain([Math.ceil(c[0]),Math.floor(c[1])]),db.select(".nv-x.nv-axis").transition().duration(L).call(n),b.transition().duration(L).call(l),h.transition().duration(L).call(j),db.select(".nv-focus .nv-x.nv-axis").attr("transform","translate(0,"+f.range()[0]+")"),p.scale(f)._ticks(a.utils.calcTicksY(W/36,v)).tickSize(-V,0),q.scale(g)._ticks(a.utils.calcTicksY(W/36,v)).tickSize(Z.length?0:-V,0),db.select(".nv-focus .nv-y1.nv-axis").style("opacity",Z.length?1:0),db.select(".nv-focus .nv-y2.nv-axis").style("opacity",$.length&&!$[0].disabled?1:0).attr("transform","translate("+d.range()[1]+",0)"),db.select(".nv-focus .nv-y1.nv-axis").transition().duration(L).call(p),db.select(".nv-focus .nv-y2.nv-axis").transition().duration(L).call(q)}var U=d3.select(this);a.utils.initSVG(U);var V=a.utils.availableWidth(y,U,w),W=a.utils.availableHeight(z,U,w)-(E?H:0),X=H-x.top-x.bottom;if(b.update=function(){U.transition().duration(L).call(b)},b.container=this,M.setter(R(v),b.update).getter(Q(v)).update(),M.disabled=v.map(function(a){return!!a.disabled}),!N){var Y;N={};for(Y in M)N[Y]=M[Y]instanceof Array?M[Y].slice(0):M[Y]}if(!(v&&v.length&&v.filter(function(a){return a.values.length}).length))return a.utils.noData(b,U),b;U.selectAll(".nv-noData").remove();var Z=v.filter(function(a){return!a.disabled&&a.bar}),$=v.filter(function(a){return!a.bar});d=l.xScale(),e=o.scale(),f=l.yScale(),g=j.yScale(),h=m.yScale(),i=k.yScale();var _=v.filter(function(a){return!a.disabled&&a.bar}).map(function(a){return a.values.map(function(a,b){return{x:A(a,b),y:B(a,b)}})}),ab=v.filter(function(a){return!a.disabled&&!a.bar}).map(function(a){return a.values.map(function(a,b){return{x:A(a,b),y:B(a,b)}})});d.range([0,V]),e.domain(d3.extent(d3.merge(_.concat(ab)),function(a){return a.x})).range([0,V]);var bb=U.selectAll("g.nv-wrap.nv-linePlusBar").data([v]),cb=bb.enter().append("g").attr("class","nvd3 nv-wrap nv-linePlusBar").append("g"),db=bb.select("g");cb.append("g").attr("class","nv-legendWrap");var eb=cb.append("g").attr("class","nv-focus");eb.append("g").attr("class","nv-x nv-axis"),eb.append("g").attr("class","nv-y1 nv-axis"),eb.append("g").attr("class","nv-y2 nv-axis"),eb.append("g").attr("class","nv-barsWrap"),eb.append("g").attr("class","nv-linesWrap");var fb=cb.append("g").attr("class","nv-context");if(fb.append("g").attr("class","nv-x nv-axis"),fb.append("g").attr("class","nv-y1 nv-axis"),fb.append("g").attr("class","nv-y2 nv-axis"),fb.append("g").attr("class","nv-barsWrap"),fb.append("g").attr("class","nv-linesWrap"),fb.append("g").attr("class","nv-brushBackground"),fb.append("g").attr("class","nv-x nv-brush"),D){var gb=t.align()?V/2:V,hb=t.align()?gb:0;t.width(gb),db.select(".nv-legendWrap").datum(v.map(function(a){return a.originalKey=void 0===a.originalKey?a.key:a.originalKey,a.key=a.originalKey+(a.bar?O:P),a})).call(t),w.top!=t.height()&&(w.top=t.height(),W=a.utils.availableHeight(z,U,w)-H),db.select(".nv-legendWrap").attr("transform","translate("+hb+","+-w.top+")")}bb.attr("transform","translate("+w.left+","+w.top+")"),db.select(".nv-context").style("display",E?"initial":"none"),m.width(V).height(X).color(v.map(function(a,b){return a.color||C(a,b)}).filter(function(a,b){return!v[b].disabled&&v[b].bar})),k.width(V).height(X).color(v.map(function(a,b){return a.color||C(a,b)}).filter(function(a,b){return!v[b].disabled&&!v[b].bar}));var ib=db.select(".nv-context .nv-barsWrap").datum(Z.length?Z:[{values:[]}]),jb=db.select(".nv-context .nv-linesWrap").datum($[0].disabled?[{values:[]}]:$);db.select(".nv-context").attr("transform","translate(0,"+(W+w.bottom+x.top)+")"),ib.transition().call(m),jb.transition().call(k),G&&(o._ticks(a.utils.calcTicksX(V/100,v)).tickSize(-X,0),db.select(".nv-context .nv-x.nv-axis").attr("transform","translate(0,"+h.range()[0]+")"),db.select(".nv-context .nv-x.nv-axis").transition().call(o)),F&&(r.scale(h)._ticks(X/36).tickSize(-V,0),s.scale(i)._ticks(X/36).tickSize(Z.length?0:-V,0),db.select(".nv-context .nv-y3.nv-axis").style("opacity",Z.length?1:0).attr("transform","translate(0,"+e.range()[0]+")"),db.select(".nv-context .nv-y2.nv-axis").style("opacity",$.length?1:0).attr("transform","translate("+e.range()[1]+",0)"),db.select(".nv-context .nv-y1.nv-axis").transition().call(r),db.select(".nv-context .nv-y2.nv-axis").transition().call(s)),u.x(e).on("brush",T),I&&u.extent(I);var kb=db.select(".nv-brushBackground").selectAll("g").data([I||u.extent()]),lb=kb.enter().append("g");lb.append("rect").attr("class","left").attr("x",0).attr("y",0).attr("height",X),lb.append("rect").attr("class","right").attr("x",0).attr("y",0).attr("height",X);var mb=db.select(".nv-x.nv-brush").call(u);mb.selectAll("rect").attr("height",X),mb.selectAll(".resize").append("path").attr("d",J),t.dispatch.on("stateChange",function(a){for(var c in a)M[c]=a[c];K.stateChange(M),b.update()}),K.on("changeState",function(a){"undefined"!=typeof a.disabled&&(v.forEach(function(b,c){b.disabled=a.disabled[c]}),M.disabled=a.disabled),b.update()}),T()}),b}var c,d,e,f,g,h,i,j=a.models.line(),k=a.models.line(),l=a.models.historicalBar(),m=a.models.historicalBar(),n=a.models.axis(),o=a.models.axis(),p=a.models.axis(),q=a.models.axis(),r=a.models.axis(),s=a.models.axis(),t=a.models.legend(),u=d3.svg.brush(),v=a.models.tooltip(),w={top:30,right:30,bottom:30,left:60},x={top:0,right:30,bottom:20,left:60},y=null,z=null,A=function(a){return a.x},B=function(a){return a.y},C=a.utils.defaultColor(),D=!0,E=!0,F=!1,G=!0,H=50,I=null,J=null,K=d3.dispatch("brush","stateChange","changeState"),L=0,M=a.utils.state(),N=null,O=" (left axis)",P=" (right axis)";j.clipEdge(!0),k.interactive(!1),n.orient("bottom").tickPadding(5),p.orient("left"),q.orient("right"),o.orient("bottom").tickPadding(5),r.orient("left"),s.orient("right"),v.headerEnabled(!0).headerFormatter(function(a,b){return n.tickFormat()(a,b)});var Q=function(a){return function(){return{active:a.map(function(a){return!a.disabled})}}},R=function(a){return function(b){void 0!==b.active&&a.forEach(function(a,c){a.disabled=!b.active[c]})}};return j.dispatch.on("elementMouseover.tooltip",function(a){v.duration(100).valueFormatter(function(a,b){return q.tickFormat()(a,b)}).data(a).position(a.pos).hidden(!1)}),j.dispatch.on("elementMouseout.tooltip",function(){v.hidden(!0)}),l.dispatch.on("elementMouseover.tooltip",function(a){a.value=b.x()(a.data),a.series={value:b.y()(a.data),color:a.color},v.duration(0).valueFormatter(function(a,b){return p.tickFormat()(a,b)}).data(a).hidden(!1)}),l.dispatch.on("elementMouseout.tooltip",function(){v.hidden(!0)}),l.dispatch.on("elementMousemove.tooltip",function(){v.position({top:d3.event.pageY,left:d3.event.pageX})()}),b.dispatch=K,b.legend=t,b.lines=j,b.lines2=k,b.bars=l,b.bars2=m,b.xAxis=n,b.x2Axis=o,b.y1Axis=p,b.y2Axis=q,b.y3Axis=r,b.y4Axis=s,b.tooltip=v,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return y},set:function(a){y=a}},height:{get:function(){return z},set:function(a){z=a}},showLegend:{get:function(){return D},set:function(a){D=a}},brushExtent:{get:function(){return I},set:function(a){I=a}},noData:{get:function(){return J},set:function(a){J=a}},focusEnable:{get:function(){return E},set:function(a){E=a}},focusHeight:{get:function(){return H},set:function(a){H=a}},focusShowAxisX:{get:function(){return G},set:function(a){G=a}},focusShowAxisY:{get:function(){return F},set:function(a){F=a}},legendLeftAxisHint:{get:function(){return O},set:function(a){O=a}},legendRightAxisHint:{get:function(){return P},set:function(a){P=a}},tooltips:{get:function(){return v.enabled()},set:function(b){a.deprecated("tooltips","use chart.tooltip.enabled() instead"),v.enabled(!!b)}},tooltipContent:{get:function(){return v.contentGenerator()},set:function(b){a.deprecated("tooltipContent","use chart.tooltip.contentGenerator() instead"),v.contentGenerator(b)}},margin:{get:function(){return w},set:function(a){w.top=void 0!==a.top?a.top:w.top,w.right=void 0!==a.right?a.right:w.right,w.bottom=void 0!==a.bottom?a.bottom:w.bottom,w.left=void 0!==a.left?a.left:w.left}},duration:{get:function(){return L},set:function(a){L=a}},color:{get:function(){return C},set:function(b){C=a.utils.getColor(b),t.color(C)}},x:{get:function(){return A},set:function(a){A=a,j.x(a),k.x(a),l.x(a),m.x(a)}},y:{get:function(){return B},set:function(a){B=a,j.y(a),k.y(a),l.y(a),m.y(a)}}}),a.utils.inheritOptions(b,j),a.utils.initOptions(b),b},a.models.lineWithFocusChart=function(){"use strict";function b(o){return o.each(function(o){function z(a){var b=+("e"==a),c=b?1:-1,d=M/3;return"M"+.5*c+","+d+"A6,6 0 0 "+b+" "+6.5*c+","+(d+6)+"V"+(2*d-6)+"A6,6 0 0 "+b+" "+.5*c+","+2*d+"ZM"+2.5*c+","+(d+8)+"V"+(2*d-8)+"M"+4.5*c+","+(d+8)+"V"+(2*d-8)}function G(){n.empty()||n.extent(y),U.data([n.empty()?e.domain():y]).each(function(a){var b=e(a[0])-c.range()[0],d=K-e(a[1]);d3.select(this).select(".left").attr("width",0>b?0:b),d3.select(this).select(".right").attr("x",e(a[1])).attr("width",0>d?0:d)})}function H(){y=n.empty()?null:n.extent();var a=n.empty()?e.domain():n.extent();if(!(Math.abs(a[0]-a[1])<=1)){A.brush({extent:a,brush:n}),G();var b=Q.select(".nv-focus .nv-linesWrap").datum(o.filter(function(a){return!a.disabled}).map(function(b){return{key:b.key,area:b.area,values:b.values.filter(function(b,c){return g.x()(b,c)>=a[0]&&g.x()(b,c)<=a[1]})}}));b.transition().duration(B).call(g),Q.select(".nv-focus .nv-x.nv-axis").transition().duration(B).call(i),Q.select(".nv-focus .nv-y.nv-axis").transition().duration(B).call(j)}}var I=d3.select(this),J=this;a.utils.initSVG(I);var K=a.utils.availableWidth(t,I,q),L=a.utils.availableHeight(u,I,q)-v,M=v-r.top-r.bottom;if(b.update=function(){I.transition().duration(B).call(b)},b.container=this,C.setter(F(o),b.update).getter(E(o)).update(),C.disabled=o.map(function(a){return!!a.disabled}),!D){var N;D={};for(N in C)D[N]=C[N]instanceof Array?C[N].slice(0):C[N]}if(!(o&&o.length&&o.filter(function(a){return a.values.length}).length))return a.utils.noData(b,I),b;I.selectAll(".nv-noData").remove(),c=g.xScale(),d=g.yScale(),e=h.xScale(),f=h.yScale();var O=I.selectAll("g.nv-wrap.nv-lineWithFocusChart").data([o]),P=O.enter().append("g").attr("class","nvd3 nv-wrap nv-lineWithFocusChart").append("g"),Q=O.select("g");P.append("g").attr("class","nv-legendWrap");var R=P.append("g").attr("class","nv-focus");R.append("g").attr("class","nv-x nv-axis"),R.append("g").attr("class","nv-y nv-axis"),R.append("g").attr("class","nv-linesWrap"),R.append("g").attr("class","nv-interactive");var S=P.append("g").attr("class","nv-context");S.append("g").attr("class","nv-x nv-axis"),S.append("g").attr("class","nv-y nv-axis"),S.append("g").attr("class","nv-linesWrap"),S.append("g").attr("class","nv-brushBackground"),S.append("g").attr("class","nv-x nv-brush"),x&&(m.width(K),Q.select(".nv-legendWrap").datum(o).call(m),q.top!=m.height()&&(q.top=m.height(),L=a.utils.availableHeight(u,I,q)-v),Q.select(".nv-legendWrap").attr("transform","translate(0,"+-q.top+")")),O.attr("transform","translate("+q.left+","+q.top+")"),w&&(p.width(K).height(L).margin({left:q.left,top:q.top}).svgContainer(I).xScale(c),O.select(".nv-interactive").call(p)),g.width(K).height(L).color(o.map(function(a,b){return a.color||s(a,b)}).filter(function(a,b){return!o[b].disabled})),h.defined(g.defined()).width(K).height(M).color(o.map(function(a,b){return a.color||s(a,b)}).filter(function(a,b){return!o[b].disabled})),Q.select(".nv-context").attr("transform","translate(0,"+(L+q.bottom+r.top)+")");var T=Q.select(".nv-context .nv-linesWrap").datum(o.filter(function(a){return!a.disabled}));d3.transition(T).call(h),i.scale(c)._ticks(a.utils.calcTicksX(K/100,o)).tickSize(-L,0),j.scale(d)._ticks(a.utils.calcTicksY(L/36,o)).tickSize(-K,0),Q.select(".nv-focus .nv-x.nv-axis").attr("transform","translate(0,"+L+")"),n.x(e).on("brush",function(){H()}),y&&n.extent(y);var U=Q.select(".nv-brushBackground").selectAll("g").data([y||n.extent()]),V=U.enter().append("g");V.append("rect").attr("class","left").attr("x",0).attr("y",0).attr("height",M),V.append("rect").attr("class","right").attr("x",0).attr("y",0).attr("height",M);var W=Q.select(".nv-x.nv-brush").call(n);W.selectAll("rect").attr("height",M),W.selectAll(".resize").append("path").attr("d",z),H(),k.scale(e)._ticks(a.utils.calcTicksX(K/100,o)).tickSize(-M,0),Q.select(".nv-context .nv-x.nv-axis").attr("transform","translate(0,"+f.range()[0]+")"),d3.transition(Q.select(".nv-context .nv-x.nv-axis")).call(k),l.scale(f)._ticks(a.utils.calcTicksY(M/36,o)).tickSize(-K,0),d3.transition(Q.select(".nv-context .nv-y.nv-axis")).call(l),Q.select(".nv-context .nv-x.nv-axis").attr("transform","translate(0,"+f.range()[0]+")"),m.dispatch.on("stateChange",function(a){for(var c in a)C[c]=a[c];A.stateChange(C),b.update()}),p.dispatch.on("elementMousemove",function(c){g.clearHighlights();var d,f,h,k=[];if(o.filter(function(a,b){return a.seriesIndex=b,!a.disabled}).forEach(function(i,j){var l=n.empty()?e.domain():n.extent(),m=i.values.filter(function(a,b){return g.x()(a,b)>=l[0]&&g.x()(a,b)<=l[1]});f=a.interactiveBisect(m,c.pointXValue,g.x());var o=m[f],p=b.y()(o,f);null!=p&&g.highlightPoint(j,f,!0),void 0!==o&&(void 0===d&&(d=o),void 0===h&&(h=b.xScale()(b.x()(o,f))),k.push({key:i.key,value:b.y()(o,f),color:s(i,i.seriesIndex)}))}),k.length>2){var l=b.yScale().invert(c.mouseY),m=Math.abs(b.yScale().domain()[0]-b.yScale().domain()[1]),r=.03*m,t=a.nearestValueIndex(k.map(function(a){return a.value}),l,r);null!==t&&(k[t].highlight=!0)}var u=i.tickFormat()(b.x()(d,f));p.tooltip.position({left:c.mouseX+q.left,top:c.mouseY+q.top}).chartContainer(J.parentNode).valueFormatter(function(a){return null==a?"N/A":j.tickFormat()(a)}).data({value:u,index:f,series:k})(),p.renderGuideLine(h)}),p.dispatch.on("elementMouseout",function(){g.clearHighlights()}),A.on("changeState",function(a){"undefined"!=typeof a.disabled&&o.forEach(function(b,c){b.disabled=a.disabled[c]}),b.update()})}),b}var c,d,e,f,g=a.models.line(),h=a.models.line(),i=a.models.axis(),j=a.models.axis(),k=a.models.axis(),l=a.models.axis(),m=a.models.legend(),n=d3.svg.brush(),o=a.models.tooltip(),p=a.interactiveGuideline(),q={top:30,right:30,bottom:30,left:60},r={top:0,right:30,bottom:20,left:60},s=a.utils.defaultColor(),t=null,u=null,v=50,w=!1,x=!0,y=null,z=null,A=d3.dispatch("brush","stateChange","changeState"),B=250,C=a.utils.state(),D=null;g.clipEdge(!0).duration(0),h.interactive(!1),i.orient("bottom").tickPadding(5),j.orient("left"),k.orient("bottom").tickPadding(5),l.orient("left"),o.valueFormatter(function(a,b){return j.tickFormat()(a,b)}).headerFormatter(function(a,b){return i.tickFormat()(a,b)});var E=function(a){return function(){return{active:a.map(function(a){return!a.disabled})}}},F=function(a){return function(b){void 0!==b.active&&a.forEach(function(a,c){a.disabled=!b.active[c]})}};return g.dispatch.on("elementMouseover.tooltip",function(a){o.data(a).position(a.pos).hidden(!1)}),g.dispatch.on("elementMouseout.tooltip",function(){o.hidden(!0)}),b.dispatch=A,b.legend=m,b.lines=g,b.lines2=h,b.xAxis=i,b.yAxis=j,b.x2Axis=k,b.y2Axis=l,b.interactiveLayer=p,b.tooltip=o,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return t},set:function(a){t=a}},height:{get:function(){return u},set:function(a){u=a}},focusHeight:{get:function(){return v},set:function(a){v=a}},showLegend:{get:function(){return x},set:function(a){x=a}},brushExtent:{get:function(){return y},set:function(a){y=a}},defaultState:{get:function(){return D},set:function(a){D=a}},noData:{get:function(){return z},set:function(a){z=a}},tooltips:{get:function(){return o.enabled()},set:function(b){a.deprecated("tooltips","use chart.tooltip.enabled() instead"),o.enabled(!!b)}},tooltipContent:{get:function(){return o.contentGenerator()},set:function(b){a.deprecated("tooltipContent","use chart.tooltip.contentGenerator() instead"),o.contentGenerator(b)}},margin:{get:function(){return q},set:function(a){q.top=void 0!==a.top?a.top:q.top,q.right=void 0!==a.right?a.right:q.right,q.bottom=void 0!==a.bottom?a.bottom:q.bottom,q.left=void 0!==a.left?a.left:q.left}},color:{get:function(){return s},set:function(b){s=a.utils.getColor(b),m.color(s)}},interpolate:{get:function(){return g.interpolate()},set:function(a){g.interpolate(a),h.interpolate(a)}},xTickFormat:{get:function(){return i.tickFormat()},set:function(a){i.tickFormat(a),k.tickFormat(a)}},yTickFormat:{get:function(){return j.tickFormat()},set:function(a){j.tickFormat(a),l.tickFormat(a)}},duration:{get:function(){return B},set:function(a){B=a,j.duration(B),l.duration(B),i.duration(B),k.duration(B)}},x:{get:function(){return g.x()},set:function(a){g.x(a),h.x(a)}},y:{get:function(){return g.y()},set:function(a){g.y(a),h.y(a)}},useInteractiveGuideline:{get:function(){return w},set:function(a){w=a,w&&(g.interactive(!1),g.useVoronoi(!1))}}}),a.utils.inheritOptions(b,g),a.utils.initOptions(b),b},a.models.multiBar=function(){"use strict";function b(E){return C.reset(),E.each(function(b){var E=k-j.left-j.right,F=l-j.top-j.bottom;p=d3.select(this),a.utils.initSVG(p);var G=0;if(x&&b.length&&(x=[{values:b[0].values.map(function(a){return{x:a.x,y:0,series:a.series,size:.01}})}]),u){var H=d3.layout.stack().offset(v).values(function(a){return a.values}).y(r)(!b.length&&x?x:b);H.forEach(function(a,c){a.nonStackable?(b[c].nonStackableSeries=G++,H[c]=b[c]):c>0&&H[c-1].nonStackable&&H[c].values.map(function(a,b){a.y0-=H[c-1].values[b].y,a.y1=a.y0+a.y})}),b=H}b.forEach(function(a,b){a.values.forEach(function(c){c.series=b,c.key=a.key})}),u&&b[0].values.map(function(a,c){var d=0,e=0;b.map(function(a,f){if(!b[f].nonStackable){var g=a.values[c];g.size=Math.abs(g.y),g.y<0?(g.y1=e,e-=g.size):(g.y1=g.size+d,d+=g.size)}})});var I=d&&e?[]:b.map(function(a,b){return a.values.map(function(a,c){return{x:q(a,c),y:r(a,c),y0:a.y0,y1:a.y1,idx:b}})});m.domain(d||d3.merge(I).map(function(a){return a.x})).rangeBands(f||[0,E],A),n.domain(e||d3.extent(d3.merge(I).map(function(a){var c=a.y;return u&&!b[a.idx].nonStackable&&(c=a.y>0?a.y1:a.y1+a.y),c}).concat(s))).range(g||[F,0]),m.domain()[0]===m.domain()[1]&&m.domain(m.domain()[0]?[m.domain()[0]-.01*m.domain()[0],m.domain()[1]+.01*m.domain()[1]]:[-1,1]),n.domain()[0]===n.domain()[1]&&n.domain(n.domain()[0]?[n.domain()[0]+.01*n.domain()[0],n.domain()[1]-.01*n.domain()[1]]:[-1,1]),h=h||m,i=i||n;var J=p.selectAll("g.nv-wrap.nv-multibar").data([b]),K=J.enter().append("g").attr("class","nvd3 nv-wrap nv-multibar"),L=K.append("defs"),M=K.append("g"),N=J.select("g");M.append("g").attr("class","nv-groups"),J.attr("transform","translate("+j.left+","+j.top+")"),L.append("clipPath").attr("id","nv-edge-clip-"+o).append("rect"),J.select("#nv-edge-clip-"+o+" rect").attr("width",E).attr("height",F),N.attr("clip-path",t?"url(#nv-edge-clip-"+o+")":"");var O=J.select(".nv-groups").selectAll(".nv-group").data(function(a){return a},function(a,b){return b});O.enter().append("g").style("stroke-opacity",1e-6).style("fill-opacity",1e-6);var P=C.transition(O.exit().selectAll("rect.nv-bar"),"multibarExit",Math.min(100,z)).attr("y",function(a){var c=i(0)||0;return u&&b[a.series]&&!b[a.series].nonStackable&&(c=i(a.y0)),c}).attr("height",0).remove();P.delay&&P.delay(function(a,b){var c=b*(z/(D+1))-b;return c}),O.attr("class",function(a,b){return"nv-group nv-series-"+b}).classed("hover",function(a){return a.hover}).style("fill",function(a,b){return w(a,b)}).style("stroke",function(a,b){return w(a,b)}),O.style("stroke-opacity",1).style("fill-opacity",.75);var Q=O.selectAll("rect.nv-bar").data(function(a){return x&&!b.length?x.values:a.values});Q.exit().remove();Q.enter().append("rect").attr("class",function(a,b){return r(a,b)<0?"nv-bar negative":"nv-bar positive"}).attr("x",function(a,c,d){return u&&!b[d].nonStackable?0:d*m.rangeBand()/b.length}).attr("y",function(a,c,d){return i(u&&!b[d].nonStackable?a.y0:0)||0}).attr("height",0).attr("width",function(a,c,d){return m.rangeBand()/(u&&!b[d].nonStackable?1:b.length)}).attr("transform",function(a,b){return"translate("+m(q(a,b))+",0)"});Q.style("fill",function(a,b,c){return w(a,c,b)}).style("stroke",function(a,b,c){return w(a,c,b)}).on("mouseover",function(a,b){d3.select(this).classed("hover",!0),B.elementMouseover({data:a,index:b,color:d3.select(this).style("fill")})}).on("mouseout",function(a,b){d3.select(this).classed("hover",!1),B.elementMouseout({data:a,index:b,color:d3.select(this).style("fill")})}).on("mousemove",function(a,b){B.elementMousemove({data:a,index:b,color:d3.select(this).style("fill")})}).on("click",function(a,b){B.elementClick({data:a,index:b,color:d3.select(this).style("fill")}),d3.event.stopPropagation()}).on("dblclick",function(a,b){B.elementDblClick({data:a,index:b,color:d3.select(this).style("fill")}),d3.event.stopPropagation()}),Q.attr("class",function(a,b){return r(a,b)<0?"nv-bar negative":"nv-bar positive"}).attr("transform",function(a,b){return"translate("+m(q(a,b))+",0)"}),y&&(c||(c=b.map(function(){return!0})),Q.style("fill",function(a,b,d){return d3.rgb(y(a,b)).darker(c.map(function(a,b){return b}).filter(function(a,b){return!c[b]})[d]).toString()}).style("stroke",function(a,b,d){return d3.rgb(y(a,b)).darker(c.map(function(a,b){return b}).filter(function(a,b){return!c[b]})[d]).toString()}));var R=Q.watchTransition(C,"multibar",Math.min(250,z)).delay(function(a,c){return c*z/b[0].values.length});u?R.attr("y",function(a,c,d){var e=0;return e=b[d].nonStackable?r(a,c)<0?n(0):n(0)-n(r(a,c))<-1?n(0)-1:n(r(a,c))||0:n(a.y1)}).attr("height",function(a,c,d){return b[d].nonStackable?Math.max(Math.abs(n(r(a,c))-n(0)),1)||0:Math.max(Math.abs(n(a.y+a.y0)-n(a.y0)),1)}).attr("x",function(a,c,d){var e=0;return b[d].nonStackable&&(e=a.series*m.rangeBand()/b.length,b.length!==G&&(e=b[d].nonStackableSeries*m.rangeBand()/(2*G))),e}).attr("width",function(a,c,d){if(b[d].nonStackable){var e=m.rangeBand()/G;return b.length!==G&&(e=m.rangeBand()/(2*G)),e}return m.rangeBand()}):R.attr("x",function(a){return a.series*m.rangeBand()/b.length}).attr("width",m.rangeBand()/b.length).attr("y",function(a,b){return r(a,b)<0?n(0):n(0)-n(r(a,b))<1?n(0)-1:n(r(a,b))||0}).attr("height",function(a,b){return Math.max(Math.abs(n(r(a,b))-n(0)),1)||0}),h=m.copy(),i=n.copy(),b[0]&&b[0].values&&(D=b[0].values.length)}),C.renderEnd("multibar immediate"),b}var c,d,e,f,g,h,i,j={top:0,right:0,bottom:0,left:0},k=960,l=500,m=d3.scale.ordinal(),n=d3.scale.linear(),o=Math.floor(1e4*Math.random()),p=null,q=function(a){return a.x},r=function(a){return a.y},s=[0],t=!0,u=!1,v="zero",w=a.utils.defaultColor(),x=!1,y=null,z=500,A=.1,B=d3.dispatch("chartClick","elementClick","elementDblClick","elementMouseover","elementMouseout","elementMousemove","renderEnd"),C=a.utils.renderWatch(B,z),D=0;return b.dispatch=B,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return k},set:function(a){k=a}},height:{get:function(){return l},set:function(a){l=a}},x:{get:function(){return q},set:function(a){q=a}},y:{get:function(){return r},set:function(a){r=a}},xScale:{get:function(){return m},set:function(a){m=a}},yScale:{get:function(){return n},set:function(a){n=a}},xDomain:{get:function(){return d},set:function(a){d=a}},yDomain:{get:function(){return e},set:function(a){e=a}},xRange:{get:function(){return f},set:function(a){f=a}},yRange:{get:function(){return g},set:function(a){g=a}},forceY:{get:function(){return s},set:function(a){s=a}},stacked:{get:function(){return u},set:function(a){u=a}},stackOffset:{get:function(){return v},set:function(a){v=a}},clipEdge:{get:function(){return t},set:function(a){t=a}},disabled:{get:function(){return c},set:function(a){c=a}},id:{get:function(){return o},set:function(a){o=a}},hideable:{get:function(){return x},set:function(a){x=a}},groupSpacing:{get:function(){return A},set:function(a){A=a}},margin:{get:function(){return j},set:function(a){j.top=void 0!==a.top?a.top:j.top,j.right=void 0!==a.right?a.right:j.right,j.bottom=void 0!==a.bottom?a.bottom:j.bottom,j.left=void 0!==a.left?a.left:j.left}},duration:{get:function(){return z},set:function(a){z=a,C.reset(z)}},color:{get:function(){return w},set:function(b){w=a.utils.getColor(b)}},barColor:{get:function(){return y},set:function(b){y=b?a.utils.getColor(b):null}}}),a.utils.initOptions(b),b},a.models.multiBarChart=function(){"use strict";function b(j){return D.reset(),D.models(e),r&&D.models(f),s&&D.models(g),j.each(function(j){var z=d3.select(this);a.utils.initSVG(z);var D=a.utils.availableWidth(l,z,k),H=a.utils.availableHeight(m,z,k);if(b.update=function(){0===C?z.call(b):z.transition().duration(C).call(b)},b.container=this,x.setter(G(j),b.update).getter(F(j)).update(),x.disabled=j.map(function(a){return!!a.disabled}),!y){var I;y={};for(I in x)y[I]=x[I]instanceof Array?x[I].slice(0):x[I]}if(!(j&&j.length&&j.filter(function(a){return a.values.length}).length))return a.utils.noData(b,z),b;z.selectAll(".nv-noData").remove(),c=e.xScale(),d=e.yScale(); -var J=z.selectAll("g.nv-wrap.nv-multiBarWithLegend").data([j]),K=J.enter().append("g").attr("class","nvd3 nv-wrap nv-multiBarWithLegend").append("g"),L=J.select("g");if(K.append("g").attr("class","nv-x nv-axis"),K.append("g").attr("class","nv-y nv-axis"),K.append("g").attr("class","nv-barsWrap"),K.append("g").attr("class","nv-legendWrap"),K.append("g").attr("class","nv-controlsWrap"),q&&(h.width(D-B()),L.select(".nv-legendWrap").datum(j).call(h),k.top!=h.height()&&(k.top=h.height(),H=a.utils.availableHeight(m,z,k)),L.select(".nv-legendWrap").attr("transform","translate("+B()+","+-k.top+")")),o){var M=[{key:p.grouped||"Grouped",disabled:e.stacked()},{key:p.stacked||"Stacked",disabled:!e.stacked()}];i.width(B()).color(["#444","#444","#444"]),L.select(".nv-controlsWrap").datum(M).attr("transform","translate(0,"+-k.top+")").call(i)}J.attr("transform","translate("+k.left+","+k.top+")"),t&&L.select(".nv-y.nv-axis").attr("transform","translate("+D+",0)"),e.disabled(j.map(function(a){return a.disabled})).width(D).height(H).color(j.map(function(a,b){return a.color||n(a,b)}).filter(function(a,b){return!j[b].disabled}));var N=L.select(".nv-barsWrap").datum(j.filter(function(a){return!a.disabled}));if(N.call(e),r){f.scale(c)._ticks(a.utils.calcTicksX(D/100,j)).tickSize(-H,0),L.select(".nv-x.nv-axis").attr("transform","translate(0,"+d.range()[0]+")"),L.select(".nv-x.nv-axis").call(f);var O=L.select(".nv-x.nv-axis > g").selectAll("g");if(O.selectAll("line, text").style("opacity",1),v){var P=function(a,b){return"translate("+a+","+b+")"},Q=5,R=17;O.selectAll("text").attr("transform",function(a,b,c){return P(0,c%2==0?Q:R)});var S=d3.selectAll(".nv-x.nv-axis .nv-wrap g g text")[0].length;L.selectAll(".nv-x.nv-axis .nv-axisMaxMin text").attr("transform",function(a,b){return P(0,0===b||S%2!==0?R:Q)})}u&&O.filter(function(a,b){return b%Math.ceil(j[0].values.length/(D/100))!==0}).selectAll("text, line").style("opacity",0),w&&O.selectAll(".tick text").attr("transform","rotate("+w+" 0,0)").style("text-anchor",w>0?"start":"end"),L.select(".nv-x.nv-axis").selectAll("g.nv-axisMaxMin text").style("opacity",1)}s&&(g.scale(d)._ticks(a.utils.calcTicksY(H/36,j)).tickSize(-D,0),L.select(".nv-y.nv-axis").call(g)),h.dispatch.on("stateChange",function(a){for(var c in a)x[c]=a[c];A.stateChange(x),b.update()}),i.dispatch.on("legendClick",function(a){if(a.disabled){switch(M=M.map(function(a){return a.disabled=!0,a}),a.disabled=!1,a.key){case"Grouped":case p.grouped:e.stacked(!1);break;case"Stacked":case p.stacked:e.stacked(!0)}x.stacked=e.stacked(),A.stateChange(x),b.update()}}),A.on("changeState",function(a){"undefined"!=typeof a.disabled&&(j.forEach(function(b,c){b.disabled=a.disabled[c]}),x.disabled=a.disabled),"undefined"!=typeof a.stacked&&(e.stacked(a.stacked),x.stacked=a.stacked,E=a.stacked),b.update()})}),D.renderEnd("multibarchart immediate"),b}var c,d,e=a.models.multiBar(),f=a.models.axis(),g=a.models.axis(),h=a.models.legend(),i=a.models.legend(),j=a.models.tooltip(),k={top:30,right:20,bottom:50,left:60},l=null,m=null,n=a.utils.defaultColor(),o=!0,p={},q=!0,r=!0,s=!0,t=!1,u=!0,v=!1,w=0,x=a.utils.state(),y=null,z=null,A=d3.dispatch("stateChange","changeState","renderEnd"),B=function(){return o?180:0},C=250;x.stacked=!1,e.stacked(!1),f.orient("bottom").tickPadding(7).showMaxMin(!1).tickFormat(function(a){return a}),g.orient(t?"right":"left").tickFormat(d3.format(",.1f")),j.duration(0).valueFormatter(function(a,b){return g.tickFormat()(a,b)}).headerFormatter(function(a,b){return f.tickFormat()(a,b)}),i.updateState(!1);var D=a.utils.renderWatch(A),E=!1,F=function(a){return function(){return{active:a.map(function(a){return!a.disabled}),stacked:E}}},G=function(a){return function(b){void 0!==b.stacked&&(E=b.stacked),void 0!==b.active&&a.forEach(function(a,c){a.disabled=!b.active[c]})}};return e.dispatch.on("elementMouseover.tooltip",function(a){a.value=b.x()(a.data),a.series={key:a.data.key,value:b.y()(a.data),color:a.color},j.data(a).hidden(!1)}),e.dispatch.on("elementMouseout.tooltip",function(){j.hidden(!0)}),e.dispatch.on("elementMousemove.tooltip",function(){j.position({top:d3.event.pageY,left:d3.event.pageX})()}),b.dispatch=A,b.multibar=e,b.legend=h,b.controls=i,b.xAxis=f,b.yAxis=g,b.state=x,b.tooltip=j,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return l},set:function(a){l=a}},height:{get:function(){return m},set:function(a){m=a}},showLegend:{get:function(){return q},set:function(a){q=a}},showControls:{get:function(){return o},set:function(a){o=a}},controlLabels:{get:function(){return p},set:function(a){p=a}},showXAxis:{get:function(){return r},set:function(a){r=a}},showYAxis:{get:function(){return s},set:function(a){s=a}},defaultState:{get:function(){return y},set:function(a){y=a}},noData:{get:function(){return z},set:function(a){z=a}},reduceXTicks:{get:function(){return u},set:function(a){u=a}},rotateLabels:{get:function(){return w},set:function(a){w=a}},staggerLabels:{get:function(){return v},set:function(a){v=a}},tooltips:{get:function(){return j.enabled()},set:function(b){a.deprecated("tooltips","use chart.tooltip.enabled() instead"),j.enabled(!!b)}},tooltipContent:{get:function(){return j.contentGenerator()},set:function(b){a.deprecated("tooltipContent","use chart.tooltip.contentGenerator() instead"),j.contentGenerator(b)}},margin:{get:function(){return k},set:function(a){k.top=void 0!==a.top?a.top:k.top,k.right=void 0!==a.right?a.right:k.right,k.bottom=void 0!==a.bottom?a.bottom:k.bottom,k.left=void 0!==a.left?a.left:k.left}},duration:{get:function(){return C},set:function(a){C=a,e.duration(C),f.duration(C),g.duration(C),D.reset(C)}},color:{get:function(){return n},set:function(b){n=a.utils.getColor(b),h.color(n)}},rightAlignYAxis:{get:function(){return t},set:function(a){t=a,g.orient(t?"right":"left")}},barColor:{get:function(){return e.barColor},set:function(a){e.barColor(a),h.color(function(a,b){return d3.rgb("#ccc").darker(1.5*b).toString()})}}}),a.utils.inheritOptions(b,e),a.utils.initOptions(b),b},a.models.multiBarHorizontal=function(){"use strict";function b(m){return E.reset(),m.each(function(b){var m=k-j.left-j.right,C=l-j.top-j.bottom;n=d3.select(this),a.utils.initSVG(n),w&&(b=d3.layout.stack().offset("zero").values(function(a){return a.values}).y(r)(b)),b.forEach(function(a,b){a.values.forEach(function(c){c.series=b,c.key=a.key})}),w&&b[0].values.map(function(a,c){var d=0,e=0;b.map(function(a){var b=a.values[c];b.size=Math.abs(b.y),b.y<0?(b.y1=e-b.size,e-=b.size):(b.y1=d,d+=b.size)})});var F=d&&e?[]:b.map(function(a){return a.values.map(function(a,b){return{x:q(a,b),y:r(a,b),y0:a.y0,y1:a.y1}})});o.domain(d||d3.merge(F).map(function(a){return a.x})).rangeBands(f||[0,C],A),p.domain(e||d3.extent(d3.merge(F).map(function(a){return w?a.y>0?a.y1+a.y:a.y1:a.y}).concat(t))),p.range(x&&!w?g||[p.domain()[0]<0?z:0,m-(p.domain()[1]>0?z:0)]:g||[0,m]),h=h||o,i=i||d3.scale.linear().domain(p.domain()).range([p(0),p(0)]);{var G=d3.select(this).selectAll("g.nv-wrap.nv-multibarHorizontal").data([b]),H=G.enter().append("g").attr("class","nvd3 nv-wrap nv-multibarHorizontal"),I=(H.append("defs"),H.append("g"));G.select("g")}I.append("g").attr("class","nv-groups"),G.attr("transform","translate("+j.left+","+j.top+")");var J=G.select(".nv-groups").selectAll(".nv-group").data(function(a){return a},function(a,b){return b});J.enter().append("g").style("stroke-opacity",1e-6).style("fill-opacity",1e-6),J.exit().watchTransition(E,"multibarhorizontal: exit groups").style("stroke-opacity",1e-6).style("fill-opacity",1e-6).remove(),J.attr("class",function(a,b){return"nv-group nv-series-"+b}).classed("hover",function(a){return a.hover}).style("fill",function(a,b){return u(a,b)}).style("stroke",function(a,b){return u(a,b)}),J.watchTransition(E,"multibarhorizontal: groups").style("stroke-opacity",1).style("fill-opacity",.75);var K=J.selectAll("g.nv-bar").data(function(a){return a.values});K.exit().remove();var L=K.enter().append("g").attr("transform",function(a,c,d){return"translate("+i(w?a.y0:0)+","+(w?0:d*o.rangeBand()/b.length+o(q(a,c)))+")"});L.append("rect").attr("width",0).attr("height",o.rangeBand()/(w?1:b.length)),K.on("mouseover",function(a,b){d3.select(this).classed("hover",!0),D.elementMouseover({data:a,index:b,color:d3.select(this).style("fill")})}).on("mouseout",function(a,b){d3.select(this).classed("hover",!1),D.elementMouseout({data:a,index:b,color:d3.select(this).style("fill")})}).on("mouseout",function(a,b){D.elementMouseout({data:a,index:b,color:d3.select(this).style("fill")})}).on("mousemove",function(a,b){D.elementMousemove({data:a,index:b,color:d3.select(this).style("fill")})}).on("click",function(a,b){D.elementClick({data:a,index:b,color:d3.select(this).style("fill")}),d3.event.stopPropagation()}).on("dblclick",function(a,b){D.elementDblClick({data:a,index:b,color:d3.select(this).style("fill")}),d3.event.stopPropagation()}),s(b[0],0)&&(L.append("polyline"),K.select("polyline").attr("fill","none").attr("points",function(a,c){var d=s(a,c),e=.8*o.rangeBand()/(2*(w?1:b.length));d=d.length?d:[-Math.abs(d),Math.abs(d)],d=d.map(function(a){return p(a)-p(0)});var f=[[d[0],-e],[d[0],e],[d[0],0],[d[1],0],[d[1],-e],[d[1],e]];return f.map(function(a){return a.join(",")}).join(" ")}).attr("transform",function(a,c){var d=o.rangeBand()/(2*(w?1:b.length));return"translate("+(r(a,c)<0?0:p(r(a,c))-p(0))+", "+d+")"})),L.append("text"),x&&!w?(K.select("text").attr("text-anchor",function(a,b){return r(a,b)<0?"end":"start"}).attr("y",o.rangeBand()/(2*b.length)).attr("dy",".32em").text(function(a,b){var c=B(r(a,b)),d=s(a,b);return void 0===d?c:d.length?c+"+"+B(Math.abs(d[1]))+"-"+B(Math.abs(d[0])):c+"±"+B(Math.abs(d))}),K.watchTransition(E,"multibarhorizontal: bars").select("text").attr("x",function(a,b){return r(a,b)<0?-4:p(r(a,b))-p(0)+4})):K.selectAll("text").text(""),y&&!w?(L.append("text").classed("nv-bar-label",!0),K.select("text.nv-bar-label").attr("text-anchor",function(a,b){return r(a,b)<0?"start":"end"}).attr("y",o.rangeBand()/(2*b.length)).attr("dy",".32em").text(function(a,b){return q(a,b)}),K.watchTransition(E,"multibarhorizontal: bars").select("text.nv-bar-label").attr("x",function(a,b){return r(a,b)<0?p(0)-p(r(a,b))+4:-4})):K.selectAll("text.nv-bar-label").text(""),K.attr("class",function(a,b){return r(a,b)<0?"nv-bar negative":"nv-bar positive"}),v&&(c||(c=b.map(function(){return!0})),K.style("fill",function(a,b,d){return d3.rgb(v(a,b)).darker(c.map(function(a,b){return b}).filter(function(a,b){return!c[b]})[d]).toString()}).style("stroke",function(a,b,d){return d3.rgb(v(a,b)).darker(c.map(function(a,b){return b}).filter(function(a,b){return!c[b]})[d]).toString()})),w?K.watchTransition(E,"multibarhorizontal: bars").attr("transform",function(a,b){return"translate("+p(a.y1)+","+o(q(a,b))+")"}).select("rect").attr("width",function(a,b){return Math.abs(p(r(a,b)+a.y0)-p(a.y0))}).attr("height",o.rangeBand()):K.watchTransition(E,"multibarhorizontal: bars").attr("transform",function(a,c){return"translate("+p(r(a,c)<0?r(a,c):0)+","+(a.series*o.rangeBand()/b.length+o(q(a,c)))+")"}).select("rect").attr("height",o.rangeBand()/b.length).attr("width",function(a,b){return Math.max(Math.abs(p(r(a,b))-p(0)),1)}),h=o.copy(),i=p.copy()}),E.renderEnd("multibarHorizontal immediate"),b}var c,d,e,f,g,h,i,j={top:0,right:0,bottom:0,left:0},k=960,l=500,m=Math.floor(1e4*Math.random()),n=null,o=d3.scale.ordinal(),p=d3.scale.linear(),q=function(a){return a.x},r=function(a){return a.y},s=function(a){return a.yErr},t=[0],u=a.utils.defaultColor(),v=null,w=!1,x=!1,y=!1,z=60,A=.1,B=d3.format(",.2f"),C=250,D=d3.dispatch("chartClick","elementClick","elementDblClick","elementMouseover","elementMouseout","elementMousemove","renderEnd"),E=a.utils.renderWatch(D,C);return b.dispatch=D,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return k},set:function(a){k=a}},height:{get:function(){return l},set:function(a){l=a}},x:{get:function(){return q},set:function(a){q=a}},y:{get:function(){return r},set:function(a){r=a}},yErr:{get:function(){return s},set:function(a){s=a}},xScale:{get:function(){return o},set:function(a){o=a}},yScale:{get:function(){return p},set:function(a){p=a}},xDomain:{get:function(){return d},set:function(a){d=a}},yDomain:{get:function(){return e},set:function(a){e=a}},xRange:{get:function(){return f},set:function(a){f=a}},yRange:{get:function(){return g},set:function(a){g=a}},forceY:{get:function(){return t},set:function(a){t=a}},stacked:{get:function(){return w},set:function(a){w=a}},showValues:{get:function(){return x},set:function(a){x=a}},disabled:{get:function(){return c},set:function(a){c=a}},id:{get:function(){return m},set:function(a){m=a}},valueFormat:{get:function(){return B},set:function(a){B=a}},valuePadding:{get:function(){return z},set:function(a){z=a}},groupSpacing:{get:function(){return A},set:function(a){A=a}},margin:{get:function(){return j},set:function(a){j.top=void 0!==a.top?a.top:j.top,j.right=void 0!==a.right?a.right:j.right,j.bottom=void 0!==a.bottom?a.bottom:j.bottom,j.left=void 0!==a.left?a.left:j.left}},duration:{get:function(){return C},set:function(a){C=a,E.reset(C)}},color:{get:function(){return u},set:function(b){u=a.utils.getColor(b)}},barColor:{get:function(){return v},set:function(b){v=b?a.utils.getColor(b):null}}}),a.utils.initOptions(b),b},a.models.multiBarHorizontalChart=function(){"use strict";function b(j){return C.reset(),C.models(e),r&&C.models(f),s&&C.models(g),j.each(function(j){var w=d3.select(this);a.utils.initSVG(w);var C=a.utils.availableWidth(l,w,k),D=a.utils.availableHeight(m,w,k);if(b.update=function(){w.transition().duration(z).call(b)},b.container=this,t=e.stacked(),u.setter(B(j),b.update).getter(A(j)).update(),u.disabled=j.map(function(a){return!!a.disabled}),!v){var E;v={};for(E in u)v[E]=u[E]instanceof Array?u[E].slice(0):u[E]}if(!(j&&j.length&&j.filter(function(a){return a.values.length}).length))return a.utils.noData(b,w),b;w.selectAll(".nv-noData").remove(),c=e.xScale(),d=e.yScale();var F=w.selectAll("g.nv-wrap.nv-multiBarHorizontalChart").data([j]),G=F.enter().append("g").attr("class","nvd3 nv-wrap nv-multiBarHorizontalChart").append("g"),H=F.select("g");if(G.append("g").attr("class","nv-x nv-axis"),G.append("g").attr("class","nv-y nv-axis").append("g").attr("class","nv-zeroLine").append("line"),G.append("g").attr("class","nv-barsWrap"),G.append("g").attr("class","nv-legendWrap"),G.append("g").attr("class","nv-controlsWrap"),q&&(h.width(C-y()),H.select(".nv-legendWrap").datum(j).call(h),k.top!=h.height()&&(k.top=h.height(),D=a.utils.availableHeight(m,w,k)),H.select(".nv-legendWrap").attr("transform","translate("+y()+","+-k.top+")")),o){var I=[{key:p.grouped||"Grouped",disabled:e.stacked()},{key:p.stacked||"Stacked",disabled:!e.stacked()}];i.width(y()).color(["#444","#444","#444"]),H.select(".nv-controlsWrap").datum(I).attr("transform","translate(0,"+-k.top+")").call(i)}F.attr("transform","translate("+k.left+","+k.top+")"),e.disabled(j.map(function(a){return a.disabled})).width(C).height(D).color(j.map(function(a,b){return a.color||n(a,b)}).filter(function(a,b){return!j[b].disabled}));var J=H.select(".nv-barsWrap").datum(j.filter(function(a){return!a.disabled}));if(J.transition().call(e),r){f.scale(c)._ticks(a.utils.calcTicksY(D/24,j)).tickSize(-C,0),H.select(".nv-x.nv-axis").call(f);var K=H.select(".nv-x.nv-axis").selectAll("g");K.selectAll("line, text")}s&&(g.scale(d)._ticks(a.utils.calcTicksX(C/100,j)).tickSize(-D,0),H.select(".nv-y.nv-axis").attr("transform","translate(0,"+D+")"),H.select(".nv-y.nv-axis").call(g)),H.select(".nv-zeroLine line").attr("x1",d(0)).attr("x2",d(0)).attr("y1",0).attr("y2",-D),h.dispatch.on("stateChange",function(a){for(var c in a)u[c]=a[c];x.stateChange(u),b.update()}),i.dispatch.on("legendClick",function(a){if(a.disabled){switch(I=I.map(function(a){return a.disabled=!0,a}),a.disabled=!1,a.key){case"Grouped":e.stacked(!1);break;case"Stacked":e.stacked(!0)}u.stacked=e.stacked(),x.stateChange(u),t=e.stacked(),b.update()}}),x.on("changeState",function(a){"undefined"!=typeof a.disabled&&(j.forEach(function(b,c){b.disabled=a.disabled[c]}),u.disabled=a.disabled),"undefined"!=typeof a.stacked&&(e.stacked(a.stacked),u.stacked=a.stacked,t=a.stacked),b.update()})}),C.renderEnd("multibar horizontal chart immediate"),b}var c,d,e=a.models.multiBarHorizontal(),f=a.models.axis(),g=a.models.axis(),h=a.models.legend().height(30),i=a.models.legend().height(30),j=a.models.tooltip(),k={top:30,right:20,bottom:50,left:60},l=null,m=null,n=a.utils.defaultColor(),o=!0,p={},q=!0,r=!0,s=!0,t=!1,u=a.utils.state(),v=null,w=null,x=d3.dispatch("stateChange","changeState","renderEnd"),y=function(){return o?180:0},z=250;u.stacked=!1,e.stacked(t),f.orient("left").tickPadding(5).showMaxMin(!1).tickFormat(function(a){return a}),g.orient("bottom").tickFormat(d3.format(",.1f")),j.duration(0).valueFormatter(function(a,b){return g.tickFormat()(a,b)}).headerFormatter(function(a,b){return f.tickFormat()(a,b)}),i.updateState(!1);var A=function(a){return function(){return{active:a.map(function(a){return!a.disabled}),stacked:t}}},B=function(a){return function(b){void 0!==b.stacked&&(t=b.stacked),void 0!==b.active&&a.forEach(function(a,c){a.disabled=!b.active[c]})}},C=a.utils.renderWatch(x,z);return e.dispatch.on("elementMouseover.tooltip",function(a){a.value=b.x()(a.data),a.series={key:a.data.key,value:b.y()(a.data),color:a.color},j.data(a).hidden(!1)}),e.dispatch.on("elementMouseout.tooltip",function(){j.hidden(!0)}),e.dispatch.on("elementMousemove.tooltip",function(){j.position({top:d3.event.pageY,left:d3.event.pageX})()}),b.dispatch=x,b.multibar=e,b.legend=h,b.controls=i,b.xAxis=f,b.yAxis=g,b.state=u,b.tooltip=j,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return l},set:function(a){l=a}},height:{get:function(){return m},set:function(a){m=a}},showLegend:{get:function(){return q},set:function(a){q=a}},showControls:{get:function(){return o},set:function(a){o=a}},controlLabels:{get:function(){return p},set:function(a){p=a}},showXAxis:{get:function(){return r},set:function(a){r=a}},showYAxis:{get:function(){return s},set:function(a){s=a}},defaultState:{get:function(){return v},set:function(a){v=a}},noData:{get:function(){return w},set:function(a){w=a}},tooltips:{get:function(){return j.enabled()},set:function(b){a.deprecated("tooltips","use chart.tooltip.enabled() instead"),j.enabled(!!b)}},tooltipContent:{get:function(){return j.contentGenerator()},set:function(b){a.deprecated("tooltipContent","use chart.tooltip.contentGenerator() instead"),j.contentGenerator(b)}},margin:{get:function(){return k},set:function(a){k.top=void 0!==a.top?a.top:k.top,k.right=void 0!==a.right?a.right:k.right,k.bottom=void 0!==a.bottom?a.bottom:k.bottom,k.left=void 0!==a.left?a.left:k.left}},duration:{get:function(){return z},set:function(a){z=a,C.reset(z),e.duration(z),f.duration(z),g.duration(z)}},color:{get:function(){return n},set:function(b){n=a.utils.getColor(b),h.color(n)}},barColor:{get:function(){return e.barColor},set:function(a){e.barColor(a),h.color(function(a,b){return d3.rgb("#ccc").darker(1.5*b).toString()})}}}),a.utils.inheritOptions(b,e),a.utils.initOptions(b),b},a.models.multiChart=function(){"use strict";function b(j){return j.each(function(j){function k(a){var b=2===j[a.seriesIndex].yAxis?z:y;a.value=a.point.x,a.series={value:a.point.y,color:a.point.color},B.duration(100).valueFormatter(function(a,c){return b.tickFormat()(a,c)}).data(a).position(a.pos).hidden(!1)}function l(a){var b=2===j[a.seriesIndex].yAxis?z:y;a.point.x=v.x()(a.point),a.point.y=v.y()(a.point),B.duration(100).valueFormatter(function(a,c){return b.tickFormat()(a,c)}).data(a).position(a.pos).hidden(!1)}function n(a){var b=2===j[a.data.series].yAxis?z:y;a.value=t.x()(a.data),a.series={value:t.y()(a.data),color:a.color},B.duration(0).valueFormatter(function(a,c){return b.tickFormat()(a,c)}).data(a).hidden(!1)}var C=d3.select(this);a.utils.initSVG(C),b.update=function(){C.transition().call(b)},b.container=this;var D=a.utils.availableWidth(g,C,e),E=a.utils.availableHeight(h,C,e),F=j.filter(function(a){return"line"==a.type&&1==a.yAxis}),G=j.filter(function(a){return"line"==a.type&&2==a.yAxis}),H=j.filter(function(a){return"bar"==a.type&&1==a.yAxis}),I=j.filter(function(a){return"bar"==a.type&&2==a.yAxis}),J=j.filter(function(a){return"area"==a.type&&1==a.yAxis}),K=j.filter(function(a){return"area"==a.type&&2==a.yAxis});if(!(j&&j.length&&j.filter(function(a){return a.values.length}).length))return a.utils.noData(b,C),b;C.selectAll(".nv-noData").remove();var L=j.filter(function(a){return!a.disabled&&1==a.yAxis}).map(function(a){return a.values.map(function(a){return{x:a.x,y:a.y}})}),M=j.filter(function(a){return!a.disabled&&2==a.yAxis}).map(function(a){return a.values.map(function(a){return{x:a.x,y:a.y}})});o.domain(d3.extent(d3.merge(L.concat(M)),function(a){return a.x})).range([0,D]);var N=C.selectAll("g.wrap.multiChart").data([j]),O=N.enter().append("g").attr("class","wrap nvd3 multiChart").append("g");O.append("g").attr("class","nv-x nv-axis"),O.append("g").attr("class","nv-y1 nv-axis"),O.append("g").attr("class","nv-y2 nv-axis"),O.append("g").attr("class","lines1Wrap"),O.append("g").attr("class","lines2Wrap"),O.append("g").attr("class","bars1Wrap"),O.append("g").attr("class","bars2Wrap"),O.append("g").attr("class","stack1Wrap"),O.append("g").attr("class","stack2Wrap"),O.append("g").attr("class","legendWrap");var P=N.select("g"),Q=j.map(function(a,b){return j[b].color||f(a,b)});if(i){var R=A.align()?D/2:D,S=A.align()?R:0;A.width(R),A.color(Q),P.select(".legendWrap").datum(j.map(function(a){return a.originalKey=void 0===a.originalKey?a.key:a.originalKey,a.key=a.originalKey+(1==a.yAxis?"":" (right axis)"),a})).call(A),e.top!=A.height()&&(e.top=A.height(),E=a.utils.availableHeight(h,C,e)),P.select(".legendWrap").attr("transform","translate("+S+","+-e.top+")")}r.width(D).height(E).interpolate(m).color(Q.filter(function(a,b){return!j[b].disabled&&1==j[b].yAxis&&"line"==j[b].type})),s.width(D).height(E).interpolate(m).color(Q.filter(function(a,b){return!j[b].disabled&&2==j[b].yAxis&&"line"==j[b].type})),t.width(D).height(E).color(Q.filter(function(a,b){return!j[b].disabled&&1==j[b].yAxis&&"bar"==j[b].type})),u.width(D).height(E).color(Q.filter(function(a,b){return!j[b].disabled&&2==j[b].yAxis&&"bar"==j[b].type})),v.width(D).height(E).color(Q.filter(function(a,b){return!j[b].disabled&&1==j[b].yAxis&&"area"==j[b].type})),w.width(D).height(E).color(Q.filter(function(a,b){return!j[b].disabled&&2==j[b].yAxis&&"area"==j[b].type})),P.attr("transform","translate("+e.left+","+e.top+")");var T=P.select(".lines1Wrap").datum(F.filter(function(a){return!a.disabled})),U=P.select(".bars1Wrap").datum(H.filter(function(a){return!a.disabled})),V=P.select(".stack1Wrap").datum(J.filter(function(a){return!a.disabled})),W=P.select(".lines2Wrap").datum(G.filter(function(a){return!a.disabled})),X=P.select(".bars2Wrap").datum(I.filter(function(a){return!a.disabled})),Y=P.select(".stack2Wrap").datum(K.filter(function(a){return!a.disabled})),Z=J.length?J.map(function(a){return a.values}).reduce(function(a,b){return a.map(function(a,c){return{x:a.x,y:a.y+b[c].y}})}).concat([{x:0,y:0}]):[],$=K.length?K.map(function(a){return a.values}).reduce(function(a,b){return a.map(function(a,c){return{x:a.x,y:a.y+b[c].y}})}).concat([{x:0,y:0}]):[];p.domain(c||d3.extent(d3.merge(L).concat(Z),function(a){return a.y})).range([0,E]),q.domain(d||d3.extent(d3.merge(M).concat($),function(a){return a.y})).range([0,E]),r.yDomain(p.domain()),t.yDomain(p.domain()),v.yDomain(p.domain()),s.yDomain(q.domain()),u.yDomain(q.domain()),w.yDomain(q.domain()),J.length&&d3.transition(V).call(v),K.length&&d3.transition(Y).call(w),H.length&&d3.transition(U).call(t),I.length&&d3.transition(X).call(u),F.length&&d3.transition(T).call(r),G.length&&d3.transition(W).call(s),x._ticks(a.utils.calcTicksX(D/100,j)).tickSize(-E,0),P.select(".nv-x.nv-axis").attr("transform","translate(0,"+E+")"),d3.transition(P.select(".nv-x.nv-axis")).call(x),y._ticks(a.utils.calcTicksY(E/36,j)).tickSize(-D,0),d3.transition(P.select(".nv-y1.nv-axis")).call(y),z._ticks(a.utils.calcTicksY(E/36,j)).tickSize(-D,0),d3.transition(P.select(".nv-y2.nv-axis")).call(z),P.select(".nv-y1.nv-axis").classed("nv-disabled",L.length?!1:!0).attr("transform","translate("+o.range()[0]+",0)"),P.select(".nv-y2.nv-axis").classed("nv-disabled",M.length?!1:!0).attr("transform","translate("+o.range()[1]+",0)"),A.dispatch.on("stateChange",function(){b.update()}),r.dispatch.on("elementMouseover.tooltip",k),s.dispatch.on("elementMouseover.tooltip",k),r.dispatch.on("elementMouseout.tooltip",function(){B.hidden(!0)}),s.dispatch.on("elementMouseout.tooltip",function(){B.hidden(!0)}),v.dispatch.on("elementMouseover.tooltip",l),w.dispatch.on("elementMouseover.tooltip",l),v.dispatch.on("elementMouseout.tooltip",function(){B.hidden(!0)}),w.dispatch.on("elementMouseout.tooltip",function(){B.hidden(!0)}),t.dispatch.on("elementMouseover.tooltip",n),u.dispatch.on("elementMouseover.tooltip",n),t.dispatch.on("elementMouseout.tooltip",function(){B.hidden(!0)}),u.dispatch.on("elementMouseout.tooltip",function(){B.hidden(!0)}),t.dispatch.on("elementMousemove.tooltip",function(){B.position({top:d3.event.pageY,left:d3.event.pageX})()}),u.dispatch.on("elementMousemove.tooltip",function(){B.position({top:d3.event.pageY,left:d3.event.pageX})()})}),b}var c,d,e={top:30,right:20,bottom:50,left:60},f=a.utils.defaultColor(),g=null,h=null,i=!0,j=null,k=function(a){return a.x},l=function(a){return a.y},m="monotone",n=!0,o=d3.scale.linear(),p=d3.scale.linear(),q=d3.scale.linear(),r=a.models.line().yScale(p),s=a.models.line().yScale(q),t=a.models.multiBar().stacked(!1).yScale(p),u=a.models.multiBar().stacked(!1).yScale(q),v=a.models.stackedArea().yScale(p),w=a.models.stackedArea().yScale(q),x=a.models.axis().scale(o).orient("bottom").tickPadding(5),y=a.models.axis().scale(p).orient("left"),z=a.models.axis().scale(q).orient("right"),A=a.models.legend().height(30),B=a.models.tooltip(),C=d3.dispatch();return b.dispatch=C,b.lines1=r,b.lines2=s,b.bars1=t,b.bars2=u,b.stack1=v,b.stack2=w,b.xAxis=x,b.yAxis1=y,b.yAxis2=z,b.tooltip=B,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return g},set:function(a){g=a}},height:{get:function(){return h},set:function(a){h=a}},showLegend:{get:function(){return i},set:function(a){i=a}},yDomain1:{get:function(){return c},set:function(a){c=a}},yDomain2:{get:function(){return d},set:function(a){d=a}},noData:{get:function(){return j},set:function(a){j=a}},interpolate:{get:function(){return m},set:function(a){m=a}},tooltips:{get:function(){return B.enabled()},set:function(b){a.deprecated("tooltips","use chart.tooltip.enabled() instead"),B.enabled(!!b)}},tooltipContent:{get:function(){return B.contentGenerator()},set:function(b){a.deprecated("tooltipContent","use chart.tooltip.contentGenerator() instead"),B.contentGenerator(b)}},margin:{get:function(){return e},set:function(a){e.top=void 0!==a.top?a.top:e.top,e.right=void 0!==a.right?a.right:e.right,e.bottom=void 0!==a.bottom?a.bottom:e.bottom,e.left=void 0!==a.left?a.left:e.left}},color:{get:function(){return f},set:function(b){f=a.utils.getColor(b)}},x:{get:function(){return k},set:function(a){k=a,r.x(a),s.x(a),t.x(a),u.x(a),v.x(a),w.x(a)}},y:{get:function(){return l},set:function(a){l=a,r.y(a),s.y(a),v.y(a),w.y(a),t.y(a),u.y(a)}},useVoronoi:{get:function(){return n},set:function(a){n=a,r.useVoronoi(a),s.useVoronoi(a),v.useVoronoi(a),w.useVoronoi(a)}}}),a.utils.initOptions(b),b},a.models.ohlcBar=function(){"use strict";function b(y){return y.each(function(b){k=d3.select(this);var y=a.utils.availableWidth(h,k,g),A=a.utils.availableHeight(i,k,g);a.utils.initSVG(k);var B=y/b[0].values.length*.9;l.domain(c||d3.extent(b[0].values.map(n).concat(t))),l.range(v?e||[.5*y/b[0].values.length,y*(b[0].values.length-.5)/b[0].values.length]:e||[5+B/2,y-B/2-5]),m.domain(d||[d3.min(b[0].values.map(s).concat(u)),d3.max(b[0].values.map(r).concat(u))]).range(f||[A,0]),l.domain()[0]===l.domain()[1]&&l.domain(l.domain()[0]?[l.domain()[0]-.01*l.domain()[0],l.domain()[1]+.01*l.domain()[1]]:[-1,1]),m.domain()[0]===m.domain()[1]&&m.domain(m.domain()[0]?[m.domain()[0]+.01*m.domain()[0],m.domain()[1]-.01*m.domain()[1]]:[-1,1]);var C=d3.select(this).selectAll("g.nv-wrap.nv-ohlcBar").data([b[0].values]),D=C.enter().append("g").attr("class","nvd3 nv-wrap nv-ohlcBar"),E=D.append("defs"),F=D.append("g"),G=C.select("g");F.append("g").attr("class","nv-ticks"),C.attr("transform","translate("+g.left+","+g.top+")"),k.on("click",function(a,b){z.chartClick({data:a,index:b,pos:d3.event,id:j})}),E.append("clipPath").attr("id","nv-chart-clip-path-"+j).append("rect"),C.select("#nv-chart-clip-path-"+j+" rect").attr("width",y).attr("height",A),G.attr("clip-path",w?"url(#nv-chart-clip-path-"+j+")":"");var H=C.select(".nv-ticks").selectAll(".nv-tick").data(function(a){return a});H.exit().remove(),H.enter().append("path").attr("class",function(a,b,c){return(p(a,b)>q(a,b)?"nv-tick negative":"nv-tick positive")+" nv-tick-"+c+"-"+b}).attr("d",function(a,b){return"m0,0l0,"+(m(p(a,b))-m(r(a,b)))+"l"+-B/2+",0l"+B/2+",0l0,"+(m(s(a,b))-m(p(a,b)))+"l0,"+(m(q(a,b))-m(s(a,b)))+"l"+B/2+",0l"+-B/2+",0z"}).attr("transform",function(a,b){return"translate("+l(n(a,b))+","+m(r(a,b))+")"}).attr("fill",function(){return x[0]}).attr("stroke",function(){return x[0]}).attr("x",0).attr("y",function(a,b){return m(Math.max(0,o(a,b)))}).attr("height",function(a,b){return Math.abs(m(o(a,b))-m(0))}),H.attr("class",function(a,b,c){return(p(a,b)>q(a,b)?"nv-tick negative":"nv-tick positive")+" nv-tick-"+c+"-"+b}),d3.transition(H).attr("transform",function(a,b){return"translate("+l(n(a,b))+","+m(r(a,b))+")"}).attr("d",function(a,c){var d=y/b[0].values.length*.9;return"m0,0l0,"+(m(p(a,c))-m(r(a,c)))+"l"+-d/2+",0l"+d/2+",0l0,"+(m(s(a,c))-m(p(a,c)))+"l0,"+(m(q(a,c))-m(s(a,c)))+"l"+d/2+",0l"+-d/2+",0z"})}),b}var c,d,e,f,g={top:0,right:0,bottom:0,left:0},h=null,i=null,j=Math.floor(1e4*Math.random()),k=null,l=d3.scale.linear(),m=d3.scale.linear(),n=function(a){return a.x},o=function(a){return a.y},p=function(a){return a.open},q=function(a){return a.close},r=function(a){return a.high},s=function(a){return a.low},t=[],u=[],v=!1,w=!0,x=a.utils.defaultColor(),y=!1,z=d3.dispatch("tooltipShow","tooltipHide","stateChange","changeState","renderEnd","chartClick","elementClick","elementDblClick","elementMouseover","elementMouseout","elementMousemove");return b.highlightPoint=function(a,c){b.clearHighlights(),k.select(".nv-ohlcBar .nv-tick-0-"+a).classed("hover",c)},b.clearHighlights=function(){k.select(".nv-ohlcBar .nv-tick.hover").classed("hover",!1)},b.dispatch=z,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return h},set:function(a){h=a}},height:{get:function(){return i},set:function(a){i=a}},xScale:{get:function(){return l},set:function(a){l=a}},yScale:{get:function(){return m},set:function(a){m=a}},xDomain:{get:function(){return c},set:function(a){c=a}},yDomain:{get:function(){return d},set:function(a){d=a}},xRange:{get:function(){return e},set:function(a){e=a}},yRange:{get:function(){return f},set:function(a){f=a}},forceX:{get:function(){return t},set:function(a){t=a}},forceY:{get:function(){return u},set:function(a){u=a}},padData:{get:function(){return v},set:function(a){v=a}},clipEdge:{get:function(){return w},set:function(a){w=a}},id:{get:function(){return j},set:function(a){j=a}},interactive:{get:function(){return y},set:function(a){y=a}},x:{get:function(){return n},set:function(a){n=a}},y:{get:function(){return o},set:function(a){o=a}},open:{get:function(){return p()},set:function(a){p=a}},close:{get:function(){return q()},set:function(a){q=a}},high:{get:function(){return r},set:function(a){r=a}},low:{get:function(){return s},set:function(a){s=a}},margin:{get:function(){return g},set:function(a){g.top=void 0!=a.top?a.top:g.top,g.right=void 0!=a.right?a.right:g.right,g.bottom=void 0!=a.bottom?a.bottom:g.bottom,g.left=void 0!=a.left?a.left:g.left -}},color:{get:function(){return x},set:function(b){x=a.utils.getColor(b)}}}),a.utils.initOptions(b),b},a.models.parallelCoordinates=function(){"use strict";function b(p){return p.each(function(b){function p(a){return F(h.map(function(b){if(isNaN(a[b])||isNaN(parseFloat(a[b]))){var c=g[b].domain(),d=g[b].range(),e=c[0]-(c[1]-c[0])/9;if(J.indexOf(b)<0){var h=d3.scale.linear().domain([e,c[1]]).range([x-12,d[1]]);g[b].brush.y(h),J.push(b)}return[f(b),g[b](e)]}return J.length>0?(D.style("display","inline"),E.style("display","inline")):(D.style("display","none"),E.style("display","none")),[f(b),g[b](a[b])]}))}function q(){var a=h.filter(function(a){return!g[a].brush.empty()}),b=a.map(function(a){return g[a].brush.extent()});k=[],a.forEach(function(a,c){k[c]={dimension:a,extent:b[c]}}),l=[],M.style("display",function(c){var d=a.every(function(a,d){return isNaN(c[a])&&b[d][0]==g[a].brush.y().domain()[0]?!0:b[d][0]<=c[a]&&c[a]<=b[d][1]});return d&&l.push(c),d?null:"none"}),o.brush({filters:k,active:l})}function r(a){m[a]=this.parentNode.__origin__=f(a),L.attr("visibility","hidden")}function s(a){m[a]=Math.min(w,Math.max(0,this.parentNode.__origin__+=d3.event.x)),M.attr("d",p),h.sort(function(a,b){return u(a)-u(b)}),f.domain(h),N.attr("transform",function(a){return"translate("+u(a)+")"})}function t(a){delete this.parentNode.__origin__,delete m[a],d3.select(this.parentNode).attr("transform","translate("+f(a)+")"),M.attr("d",p),L.attr("d",p).attr("visibility",null)}function u(a){var b=m[a];return null==b?f(a):b}var v=d3.select(this),w=a.utils.availableWidth(d,v,c),x=a.utils.availableHeight(e,v,c);a.utils.initSVG(v),l=b,f.rangePoints([0,w],1).domain(h);var y={};h.forEach(function(a){var c=d3.extent(b,function(b){return+b[a]});return y[a]=!1,void 0===c[0]&&(y[a]=!0,c[0]=0,c[1]=0),c[0]===c[1]&&(c[0]=c[0]-1,c[1]=c[1]+1),g[a]=d3.scale.linear().domain(c).range([.9*(x-12),0]),g[a].brush=d3.svg.brush().y(g[a]).on("brush",q),"name"!=a});var z=v.selectAll("g.nv-wrap.nv-parallelCoordinates").data([b]),A=z.enter().append("g").attr("class","nvd3 nv-wrap nv-parallelCoordinates"),B=A.append("g"),C=z.select("g");B.append("g").attr("class","nv-parallelCoordinates background"),B.append("g").attr("class","nv-parallelCoordinates foreground"),B.append("g").attr("class","nv-parallelCoordinates missingValuesline"),z.attr("transform","translate("+c.left+","+c.top+")");var D,E,F=d3.svg.line().interpolate("cardinal").tension(n),G=d3.svg.axis().orient("left"),H=d3.behavior.drag().on("dragstart",r).on("drag",s).on("dragend",t),I=f.range()[1]-f.range()[0],J=[],K=[0+I/2,x-12,w-I/2,x-12];D=z.select(".missingValuesline").selectAll("line").data([K]),D.enter().append("line"),D.exit().remove(),D.attr("x1",function(a){return a[0]}).attr("y1",function(a){return a[1]}).attr("x2",function(a){return a[2]}).attr("y2",function(a){return a[3]}),E=z.select(".missingValuesline").selectAll("text").data(["undefined values"]),E.append("text").data(["undefined values"]),E.enter().append("text"),E.exit().remove(),E.attr("y",x).attr("x",w-92-I/2).text(function(a){return a});var L=z.select(".background").selectAll("path").data(b);L.enter().append("path"),L.exit().remove(),L.attr("d",p);var M=z.select(".foreground").selectAll("path").data(b);M.enter().append("path"),M.exit().remove(),M.attr("d",p).attr("stroke",j),M.on("mouseover",function(a,b){d3.select(this).classed("hover",!0),o.elementMouseover({label:a.name,data:a.data,index:b,pos:[d3.mouse(this.parentNode)[0],d3.mouse(this.parentNode)[1]]})}),M.on("mouseout",function(a,b){d3.select(this).classed("hover",!1),o.elementMouseout({label:a.name,data:a.data,index:b})});var N=C.selectAll(".dimension").data(h),O=N.enter().append("g").attr("class","nv-parallelCoordinates dimension");O.append("g").attr("class","nv-parallelCoordinates nv-axis"),O.append("g").attr("class","nv-parallelCoordinates-brush"),O.append("text").attr("class","nv-parallelCoordinates nv-label"),N.attr("transform",function(a){return"translate("+f(a)+",0)"}),N.exit().remove(),N.select(".nv-label").style("cursor","move").attr("dy","-1em").attr("text-anchor","middle").text(String).on("mouseover",function(a){o.elementMouseover({dim:a,pos:[d3.mouse(this.parentNode.parentNode)[0],d3.mouse(this.parentNode.parentNode)[1]]})}).on("mouseout",function(a){o.elementMouseout({dim:a})}).call(H),N.select(".nv-axis").each(function(a,b){d3.select(this).call(G.scale(g[a]).tickFormat(d3.format(i[b])))}),N.select(".nv-parallelCoordinates-brush").each(function(a){d3.select(this).call(g[a].brush)}).selectAll("rect").attr("x",-8).attr("width",16)}),b}var c={top:30,right:0,bottom:10,left:0},d=null,e=null,f=d3.scale.ordinal(),g={},h=[],i=[],j=a.utils.defaultColor(),k=[],l=[],m=[],n=1,o=d3.dispatch("brush","elementMouseover","elementMouseout");return b.dispatch=o,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return d},set:function(a){d=a}},height:{get:function(){return e},set:function(a){e=a}},dimensionNames:{get:function(){return h},set:function(a){h=a}},dimensionFormats:{get:function(){return i},set:function(a){i=a}},lineTension:{get:function(){return n},set:function(a){n=a}},dimensions:{get:function(){return h},set:function(b){a.deprecated("dimensions","use dimensionNames instead"),h=b}},margin:{get:function(){return c},set:function(a){c.top=void 0!==a.top?a.top:c.top,c.right=void 0!==a.right?a.right:c.right,c.bottom=void 0!==a.bottom?a.bottom:c.bottom,c.left=void 0!==a.left?a.left:c.left}},color:{get:function(){return j},set:function(b){j=a.utils.getColor(b)}}}),a.utils.initOptions(b),b},a.models.pie=function(){"use strict";function b(E){return D.reset(),E.each(function(b){function E(a,b){a.endAngle=isNaN(a.endAngle)?0:a.endAngle,a.startAngle=isNaN(a.startAngle)?0:a.startAngle,p||(a.innerRadius=0);var c=d3.interpolate(this._current,a);return this._current=c(0),function(a){return B[b](c(a))}}var F=d-c.left-c.right,G=e-c.top-c.bottom,H=Math.min(F,G)/2,I=[],J=[];if(i=d3.select(this),0===z.length)for(var K=H-H/5,L=y*H,M=0;Mc)return"";if("function"==typeof n)d=n(a,b,{key:f(a.data),value:g(a.data),percent:k(c)});else switch(n){case"key":d=f(a.data);break;case"value":d=k(g(a.data));break;case"percent":d=d3.format("%")(c)}return d})}}),D.renderEnd("pie immediate"),b}var c={top:0,right:0,bottom:0,left:0},d=500,e=500,f=function(a){return a.x},g=function(a){return a.y},h=Math.floor(1e4*Math.random()),i=null,j=a.utils.defaultColor(),k=d3.format(",.2f"),l=!0,m=!1,n="key",o=.02,p=!1,q=!1,r=!0,s=0,t=!1,u=!1,v=!1,w=!1,x=0,y=.5,z=[],A=d3.dispatch("chartClick","elementClick","elementDblClick","elementMouseover","elementMouseout","elementMousemove","renderEnd"),B=[],C=[],D=a.utils.renderWatch(A);return b.dispatch=A,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{arcsRadius:{get:function(){return z},set:function(a){z=a}},width:{get:function(){return d},set:function(a){d=a}},height:{get:function(){return e},set:function(a){e=a}},showLabels:{get:function(){return l},set:function(a){l=a}},title:{get:function(){return q},set:function(a){q=a}},titleOffset:{get:function(){return s},set:function(a){s=a}},labelThreshold:{get:function(){return o},set:function(a){o=a}},valueFormat:{get:function(){return k},set:function(a){k=a}},x:{get:function(){return f},set:function(a){f=a}},id:{get:function(){return h},set:function(a){h=a}},endAngle:{get:function(){return w},set:function(a){w=a}},startAngle:{get:function(){return u},set:function(a){u=a}},padAngle:{get:function(){return v},set:function(a){v=a}},cornerRadius:{get:function(){return x},set:function(a){x=a}},donutRatio:{get:function(){return y},set:function(a){y=a}},labelsOutside:{get:function(){return m},set:function(a){m=a}},labelSunbeamLayout:{get:function(){return t},set:function(a){t=a}},donut:{get:function(){return p},set:function(a){p=a}},growOnHover:{get:function(){return r},set:function(a){r=a}},pieLabelsOutside:{get:function(){return m},set:function(b){m=b,a.deprecated("pieLabelsOutside","use labelsOutside instead")}},donutLabelsOutside:{get:function(){return m},set:function(b){m=b,a.deprecated("donutLabelsOutside","use labelsOutside instead")}},labelFormat:{get:function(){return k},set:function(b){k=b,a.deprecated("labelFormat","use valueFormat instead")}},margin:{get:function(){return c},set:function(a){c.top="undefined"!=typeof a.top?a.top:c.top,c.right="undefined"!=typeof a.right?a.right:c.right,c.bottom="undefined"!=typeof a.bottom?a.bottom:c.bottom,c.left="undefined"!=typeof a.left?a.left:c.left}},y:{get:function(){return g},set:function(a){g=d3.functor(a)}},color:{get:function(){return j},set:function(b){j=a.utils.getColor(b)}},labelType:{get:function(){return n},set:function(a){n=a||"key"}}}),a.utils.initOptions(b),b},a.models.pieChart=function(){"use strict";function b(e){return q.reset(),q.models(c),e.each(function(e){var k=d3.select(this);a.utils.initSVG(k);var n=a.utils.availableWidth(g,k,f),o=a.utils.availableHeight(h,k,f);if(b.update=function(){k.transition().call(b)},b.container=this,l.setter(s(e),b.update).getter(r(e)).update(),l.disabled=e.map(function(a){return!!a.disabled}),!m){var q;m={};for(q in l)m[q]=l[q]instanceof Array?l[q].slice(0):l[q]}if(!e||!e.length)return a.utils.noData(b,k),b;k.selectAll(".nv-noData").remove();var t=k.selectAll("g.nv-wrap.nv-pieChart").data([e]),u=t.enter().append("g").attr("class","nvd3 nv-wrap nv-pieChart").append("g"),v=t.select("g");if(u.append("g").attr("class","nv-pieWrap"),u.append("g").attr("class","nv-legendWrap"),i)if("top"===j)d.width(n).key(c.x()),t.select(".nv-legendWrap").datum(e).call(d),f.top!=d.height()&&(f.top=d.height(),o=a.utils.availableHeight(h,k,f)),t.select(".nv-legendWrap").attr("transform","translate(0,"+-f.top+")");else if("right"===j){var w=a.models.legend().width();w>n/2&&(w=n/2),d.height(o).key(c.x()),d.width(w),n-=d.width(),t.select(".nv-legendWrap").datum(e).call(d).attr("transform","translate("+n+",0)")}t.attr("transform","translate("+f.left+","+f.top+")"),c.width(n).height(o);var x=v.select(".nv-pieWrap").datum([e]);d3.transition(x).call(c),d.dispatch.on("stateChange",function(a){for(var c in a)l[c]=a[c];p.stateChange(l),b.update()}),p.on("changeState",function(a){"undefined"!=typeof a.disabled&&(e.forEach(function(b,c){b.disabled=a.disabled[c]}),l.disabled=a.disabled),b.update()})}),q.renderEnd("pieChart immediate"),b}var c=a.models.pie(),d=a.models.legend(),e=a.models.tooltip(),f={top:30,right:20,bottom:20,left:20},g=null,h=null,i=!0,j="top",k=a.utils.defaultColor(),l=a.utils.state(),m=null,n=null,o=250,p=d3.dispatch("tooltipShow","tooltipHide","stateChange","changeState","renderEnd");e.headerEnabled(!1).duration(0).valueFormatter(function(a,b){return c.valueFormat()(a,b)});var q=a.utils.renderWatch(p),r=function(a){return function(){return{active:a.map(function(a){return!a.disabled})}}},s=function(a){return function(b){void 0!==b.active&&a.forEach(function(a,c){a.disabled=!b.active[c]})}};return c.dispatch.on("elementMouseover.tooltip",function(a){a.series={key:b.x()(a.data),value:b.y()(a.data),color:a.color},e.data(a).hidden(!1)}),c.dispatch.on("elementMouseout.tooltip",function(){e.hidden(!0)}),c.dispatch.on("elementMousemove.tooltip",function(){e.position({top:d3.event.pageY,left:d3.event.pageX})()}),b.legend=d,b.dispatch=p,b.pie=c,b.tooltip=e,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{noData:{get:function(){return n},set:function(a){n=a}},showLegend:{get:function(){return i},set:function(a){i=a}},legendPosition:{get:function(){return j},set:function(a){j=a}},defaultState:{get:function(){return m},set:function(a){m=a}},tooltips:{get:function(){return e.enabled()},set:function(b){a.deprecated("tooltips","use chart.tooltip.enabled() instead"),e.enabled(!!b)}},tooltipContent:{get:function(){return e.contentGenerator()},set:function(b){a.deprecated("tooltipContent","use chart.tooltip.contentGenerator() instead"),e.contentGenerator(b)}},color:{get:function(){return k},set:function(a){k=a,d.color(k),c.color(k)}},duration:{get:function(){return o},set:function(a){o=a,q.reset(o)}},margin:{get:function(){return f},set:function(a){f.top=void 0!==a.top?a.top:f.top,f.right=void 0!==a.right?a.right:f.right,f.bottom=void 0!==a.bottom?a.bottom:f.bottom,f.left=void 0!==a.left?a.left:f.left}}}),a.utils.inheritOptions(b,c),a.utils.initOptions(b),b},a.models.scatter=function(){"use strict";function b(N){return P.reset(),N.each(function(b){function N(){if(O=!1,!w)return!1;if(M===!0){var a=d3.merge(b.map(function(a,b){return a.values.map(function(a,c){var d=p(a,c),e=q(a,c);return[m(d)+1e-4*Math.random(),n(e)+1e-4*Math.random(),b,c,a]}).filter(function(a,b){return x(a[4],b)})}));if(0==a.length)return!1;a.length<3&&(a.push([m.range()[0]-20,n.range()[0]-20,null,null]),a.push([m.range()[1]+20,n.range()[1]+20,null,null]),a.push([m.range()[0]-20,n.range()[0]+20,null,null]),a.push([m.range()[1]+20,n.range()[1]-20,null,null]));var c=d3.geom.polygon([[-10,-10],[-10,i+10],[h+10,i+10],[h+10,-10]]),d=d3.geom.voronoi(a).map(function(b,d){return{data:c.clip(b),series:a[d][2],point:a[d][3]}});U.select(".nv-point-paths").selectAll("path").remove();var e=U.select(".nv-point-paths").selectAll("path").data(d),f=e.enter().append("svg:path").attr("d",function(a){return a&&a.data&&0!==a.data.length?"M"+a.data.join(",")+"Z":"M 0 0"}).attr("id",function(a,b){return"nv-path-"+b}).attr("clip-path",function(a,b){return"url(#nv-clip-"+b+")"});C&&f.style("fill",d3.rgb(230,230,230)).style("fill-opacity",.4).style("stroke-opacity",1).style("stroke",d3.rgb(200,200,200)),B&&(U.select(".nv-point-clips").selectAll("clipPath").remove(),U.select(".nv-point-clips").selectAll("clipPath").data(a).enter().append("svg:clipPath").attr("id",function(a,b){return"nv-clip-"+b}).append("svg:circle").attr("cx",function(a){return a[0]}).attr("cy",function(a){return a[1]}).attr("r",D));var k=function(a,c){if(O)return 0;var d=b[a.series];if(void 0!==d){var e=d.values[a.point];e.color=j(d,a.series),e.x=p(e),e.y=q(e);var f=l.node().getBoundingClientRect(),h=window.pageYOffset||document.documentElement.scrollTop,i=window.pageXOffset||document.documentElement.scrollLeft,k={left:m(p(e,a.point))+f.left+i+g.left+10,top:n(q(e,a.point))+f.top+h+g.top+10};c({point:e,series:d,pos:k,seriesIndex:a.series,pointIndex:a.point})}};e.on("click",function(a){k(a,L.elementClick)}).on("dblclick",function(a){k(a,L.elementDblClick)}).on("mouseover",function(a){k(a,L.elementMouseover)}).on("mouseout",function(a){k(a,L.elementMouseout)})}else U.select(".nv-groups").selectAll(".nv-group").selectAll(".nv-point").on("click",function(a,c){if(O||!b[a.series])return 0;var d=b[a.series],e=d.values[c];L.elementClick({point:e,series:d,pos:[m(p(e,c))+g.left,n(q(e,c))+g.top],seriesIndex:a.series,pointIndex:c})}).on("dblclick",function(a,c){if(O||!b[a.series])return 0;var d=b[a.series],e=d.values[c];L.elementDblClick({point:e,series:d,pos:[m(p(e,c))+g.left,n(q(e,c))+g.top],seriesIndex:a.series,pointIndex:c})}).on("mouseover",function(a,c){if(O||!b[a.series])return 0;var d=b[a.series],e=d.values[c];L.elementMouseover({point:e,series:d,pos:[m(p(e,c))+g.left,n(q(e,c))+g.top],seriesIndex:a.series,pointIndex:c,color:j(a,c)})}).on("mouseout",function(a,c){if(O||!b[a.series])return 0;var d=b[a.series],e=d.values[c];L.elementMouseout({point:e,series:d,seriesIndex:a.series,pointIndex:c,color:j(a,c)})})}l=d3.select(this);var R=a.utils.availableWidth(h,l,g),S=a.utils.availableHeight(i,l,g);a.utils.initSVG(l),b.forEach(function(a,b){a.values.forEach(function(a){a.series=b})});var T=E&&F&&I?[]:d3.merge(b.map(function(a){return a.values.map(function(a,b){return{x:p(a,b),y:q(a,b),size:r(a,b)}})}));m.domain(E||d3.extent(T.map(function(a){return a.x}).concat(t))),m.range(y&&b[0]?G||[(R*z+R)/(2*b[0].values.length),R-R*(1+z)/(2*b[0].values.length)]:G||[0,R]),n.domain(F||d3.extent(T.map(function(a){return a.y}).concat(u))).range(H||[S,0]),o.domain(I||d3.extent(T.map(function(a){return a.size}).concat(v))).range(J||Q),K=m.domain()[0]===m.domain()[1]||n.domain()[0]===n.domain()[1],m.domain()[0]===m.domain()[1]&&m.domain(m.domain()[0]?[m.domain()[0]-.01*m.domain()[0],m.domain()[1]+.01*m.domain()[1]]:[-1,1]),n.domain()[0]===n.domain()[1]&&n.domain(n.domain()[0]?[n.domain()[0]-.01*n.domain()[0],n.domain()[1]+.01*n.domain()[1]]:[-1,1]),isNaN(m.domain()[0])&&m.domain([-1,1]),isNaN(n.domain()[0])&&n.domain([-1,1]),c=c||m,d=d||n,e=e||o;var U=l.selectAll("g.nv-wrap.nv-scatter").data([b]),V=U.enter().append("g").attr("class","nvd3 nv-wrap nv-scatter nv-chart-"+k),W=V.append("defs"),X=V.append("g"),Y=U.select("g");U.classed("nv-single-point",K),X.append("g").attr("class","nv-groups"),X.append("g").attr("class","nv-point-paths"),V.append("g").attr("class","nv-point-clips"),U.attr("transform","translate("+g.left+","+g.top+")"),W.append("clipPath").attr("id","nv-edge-clip-"+k).append("rect"),U.select("#nv-edge-clip-"+k+" rect").attr("width",R).attr("height",S>0?S:0),Y.attr("clip-path",A?"url(#nv-edge-clip-"+k+")":""),O=!0;var Z=U.select(".nv-groups").selectAll(".nv-group").data(function(a){return a},function(a){return a.key});Z.enter().append("g").style("stroke-opacity",1e-6).style("fill-opacity",1e-6),Z.exit().remove(),Z.attr("class",function(a,b){return"nv-group nv-series-"+b}).classed("hover",function(a){return a.hover}),Z.watchTransition(P,"scatter: groups").style("fill",function(a,b){return j(a,b)}).style("stroke",function(a,b){return j(a,b)}).style("stroke-opacity",1).style("fill-opacity",.5);var $=Z.selectAll("path.nv-point").data(function(a){return a.values.map(function(a,b){return[a,b]}).filter(function(a,b){return x(a[0],b)})});$.enter().append("path").style("fill",function(a){return a.color}).style("stroke",function(a){return a.color}).attr("transform",function(a){return"translate("+c(p(a[0],a[1]))+","+d(q(a[0],a[1]))+")"}).attr("d",a.utils.symbol().type(function(a){return s(a[0])}).size(function(a){return o(r(a[0],a[1]))})),$.exit().remove(),Z.exit().selectAll("path.nv-point").watchTransition(P,"scatter exit").attr("transform",function(a){return"translate("+m(p(a[0],a[1]))+","+n(q(a[0],a[1]))+")"}).remove(),$.each(function(a){d3.select(this).classed("nv-point",!0).classed("nv-point-"+a[1],!0).classed("nv-noninteractive",!w).classed("hover",!1)}),$.watchTransition(P,"scatter points").attr("transform",function(a){return"translate("+m(p(a[0],a[1]))+","+n(q(a[0],a[1]))+")"}).attr("d",a.utils.symbol().type(function(a){return s(a[0])}).size(function(a){return o(r(a[0],a[1]))})),clearTimeout(f),f=setTimeout(N,300),c=m.copy(),d=n.copy(),e=o.copy()}),P.renderEnd("scatter immediate"),b}var c,d,e,f,g={top:0,right:0,bottom:0,left:0},h=null,i=null,j=a.utils.defaultColor(),k=Math.floor(1e5*Math.random()),l=null,m=d3.scale.linear(),n=d3.scale.linear(),o=d3.scale.linear(),p=function(a){return a.x},q=function(a){return a.y},r=function(a){return a.size||1},s=function(a){return a.shape||"circle"},t=[],u=[],v=[],w=!0,x=function(a){return!a.notActive},y=!1,z=.1,A=!1,B=!0,C=!1,D=function(){return 25},E=null,F=null,G=null,H=null,I=null,J=null,K=!1,L=d3.dispatch("elementClick","elementDblClick","elementMouseover","elementMouseout","renderEnd"),M=!0,N=250,O=!1,P=a.utils.renderWatch(L,N),Q=[16,256];return b.dispatch=L,b.options=a.utils.optionsFunc.bind(b),b._calls=new function(){this.clearHighlights=function(){return a.dom.write(function(){l.selectAll(".nv-point.hover").classed("hover",!1)}),null},this.highlightPoint=function(b,c,d){a.dom.write(function(){l.select(" .nv-series-"+b+" .nv-point-"+c).classed("hover",d)})}},L.on("elementMouseover.point",function(a){w&&b._calls.highlightPoint(a.seriesIndex,a.pointIndex,!0)}),L.on("elementMouseout.point",function(a){w&&b._calls.highlightPoint(a.seriesIndex,a.pointIndex,!1)}),b._options=Object.create({},{width:{get:function(){return h},set:function(a){h=a}},height:{get:function(){return i},set:function(a){i=a}},xScale:{get:function(){return m},set:function(a){m=a}},yScale:{get:function(){return n},set:function(a){n=a}},pointScale:{get:function(){return o},set:function(a){o=a}},xDomain:{get:function(){return E},set:function(a){E=a}},yDomain:{get:function(){return F},set:function(a){F=a}},pointDomain:{get:function(){return I},set:function(a){I=a}},xRange:{get:function(){return G},set:function(a){G=a}},yRange:{get:function(){return H},set:function(a){H=a}},pointRange:{get:function(){return J},set:function(a){J=a}},forceX:{get:function(){return t},set:function(a){t=a}},forceY:{get:function(){return u},set:function(a){u=a}},forcePoint:{get:function(){return v},set:function(a){v=a}},interactive:{get:function(){return w},set:function(a){w=a}},pointActive:{get:function(){return x},set:function(a){x=a}},padDataOuter:{get:function(){return z},set:function(a){z=a}},padData:{get:function(){return y},set:function(a){y=a}},clipEdge:{get:function(){return A},set:function(a){A=a}},clipVoronoi:{get:function(){return B},set:function(a){B=a}},clipRadius:{get:function(){return D},set:function(a){D=a}},showVoronoi:{get:function(){return C},set:function(a){C=a}},id:{get:function(){return k},set:function(a){k=a}},x:{get:function(){return p},set:function(a){p=d3.functor(a)}},y:{get:function(){return q},set:function(a){q=d3.functor(a)}},pointSize:{get:function(){return r},set:function(a){r=d3.functor(a)}},pointShape:{get:function(){return s},set:function(a){s=d3.functor(a)}},margin:{get:function(){return g},set:function(a){g.top=void 0!==a.top?a.top:g.top,g.right=void 0!==a.right?a.right:g.right,g.bottom=void 0!==a.bottom?a.bottom:g.bottom,g.left=void 0!==a.left?a.left:g.left}},duration:{get:function(){return N},set:function(a){N=a,P.reset(N)}},color:{get:function(){return j},set:function(b){j=a.utils.getColor(b)}},useVoronoi:{get:function(){return M},set:function(a){M=a,M===!1&&(B=!1)}}}),a.utils.initOptions(b),b},a.models.scatterChart=function(){"use strict";function b(z){return D.reset(),D.models(c),t&&D.models(d),u&&D.models(e),q&&D.models(g),r&&D.models(h),z.each(function(z){m=d3.select(this),a.utils.initSVG(m);var G=a.utils.availableWidth(k,m,j),H=a.utils.availableHeight(l,m,j);if(b.update=function(){0===A?m.call(b):m.transition().duration(A).call(b)},b.container=this,w.setter(F(z),b.update).getter(E(z)).update(),w.disabled=z.map(function(a){return!!a.disabled}),!x){var I;x={};for(I in w)x[I]=w[I]instanceof Array?w[I].slice(0):w[I]}if(!(z&&z.length&&z.filter(function(a){return a.values.length}).length))return a.utils.noData(b,m),D.renderEnd("scatter immediate"),b;m.selectAll(".nv-noData").remove(),o=c.xScale(),p=c.yScale();var J=m.selectAll("g.nv-wrap.nv-scatterChart").data([z]),K=J.enter().append("g").attr("class","nvd3 nv-wrap nv-scatterChart nv-chart-"+c.id()),L=K.append("g"),M=J.select("g");if(L.append("rect").attr("class","nvd3 nv-background").style("pointer-events","none"),L.append("g").attr("class","nv-x nv-axis"),L.append("g").attr("class","nv-y nv-axis"),L.append("g").attr("class","nv-scatterWrap"),L.append("g").attr("class","nv-regressionLinesWrap"),L.append("g").attr("class","nv-distWrap"),L.append("g").attr("class","nv-legendWrap"),v&&M.select(".nv-y.nv-axis").attr("transform","translate("+G+",0)"),s){var N=G;f.width(N),J.select(".nv-legendWrap").datum(z).call(f),j.top!=f.height()&&(j.top=f.height(),H=a.utils.availableHeight(l,m,j)),J.select(".nv-legendWrap").attr("transform","translate(0,"+-j.top+")")}J.attr("transform","translate("+j.left+","+j.top+")"),c.width(G).height(H).color(z.map(function(a,b){return a.color=a.color||n(a,b),a.color}).filter(function(a,b){return!z[b].disabled})),J.select(".nv-scatterWrap").datum(z.filter(function(a){return!a.disabled})).call(c),J.select(".nv-regressionLinesWrap").attr("clip-path","url(#nv-edge-clip-"+c.id()+")");var O=J.select(".nv-regressionLinesWrap").selectAll(".nv-regLines").data(function(a){return a});O.enter().append("g").attr("class","nv-regLines");var P=O.selectAll(".nv-regLine").data(function(a){return[a]});P.enter().append("line").attr("class","nv-regLine").style("stroke-opacity",0),P.filter(function(a){return a.intercept&&a.slope}).watchTransition(D,"scatterPlusLineChart: regline").attr("x1",o.range()[0]).attr("x2",o.range()[1]).attr("y1",function(a){return p(o.domain()[0]*a.slope+a.intercept)}).attr("y2",function(a){return p(o.domain()[1]*a.slope+a.intercept)}).style("stroke",function(a,b,c){return n(a,c)}).style("stroke-opacity",function(a){return a.disabled||"undefined"==typeof a.slope||"undefined"==typeof a.intercept?0:1}),t&&(d.scale(o)._ticks(a.utils.calcTicksX(G/100,z)).tickSize(-H,0),M.select(".nv-x.nv-axis").attr("transform","translate(0,"+p.range()[0]+")").call(d)),u&&(e.scale(p)._ticks(a.utils.calcTicksY(H/36,z)).tickSize(-G,0),M.select(".nv-y.nv-axis").call(e)),q&&(g.getData(c.x()).scale(o).width(G).color(z.map(function(a,b){return a.color||n(a,b)}).filter(function(a,b){return!z[b].disabled})),L.select(".nv-distWrap").append("g").attr("class","nv-distributionX"),M.select(".nv-distributionX").attr("transform","translate(0,"+p.range()[0]+")").datum(z.filter(function(a){return!a.disabled})).call(g)),r&&(h.getData(c.y()).scale(p).width(H).color(z.map(function(a,b){return a.color||n(a,b)}).filter(function(a,b){return!z[b].disabled})),L.select(".nv-distWrap").append("g").attr("class","nv-distributionY"),M.select(".nv-distributionY").attr("transform","translate("+(v?G:-h.size())+",0)").datum(z.filter(function(a){return!a.disabled})).call(h)),f.dispatch.on("stateChange",function(a){for(var c in a)w[c]=a[c];y.stateChange(w),b.update()}),y.on("changeState",function(a){"undefined"!=typeof a.disabled&&(z.forEach(function(b,c){b.disabled=a.disabled[c]}),w.disabled=a.disabled),b.update()}),c.dispatch.on("elementMouseout.tooltip",function(a){i.hidden(!0),m.select(".nv-chart-"+c.id()+" .nv-series-"+a.seriesIndex+" .nv-distx-"+a.pointIndex).attr("y1",0),m.select(".nv-chart-"+c.id()+" .nv-series-"+a.seriesIndex+" .nv-disty-"+a.pointIndex).attr("x2",h.size())}),c.dispatch.on("elementMouseover.tooltip",function(a){m.select(".nv-series-"+a.seriesIndex+" .nv-distx-"+a.pointIndex).attr("y1",a.pos.top-H-j.top),m.select(".nv-series-"+a.seriesIndex+" .nv-disty-"+a.pointIndex).attr("x2",a.pos.left+g.size()-j.left),i.position(a.pos).data(a).hidden(!1)}),B=o.copy(),C=p.copy()}),D.renderEnd("scatter with line immediate"),b}var c=a.models.scatter(),d=a.models.axis(),e=a.models.axis(),f=a.models.legend(),g=a.models.distribution(),h=a.models.distribution(),i=a.models.tooltip(),j={top:30,right:20,bottom:50,left:75},k=null,l=null,m=null,n=a.utils.defaultColor(),o=c.xScale(),p=c.yScale(),q=!1,r=!1,s=!0,t=!0,u=!0,v=!1,w=a.utils.state(),x=null,y=d3.dispatch("stateChange","changeState","renderEnd"),z=null,A=250;c.xScale(o).yScale(p),d.orient("bottom").tickPadding(10),e.orient(v?"right":"left").tickPadding(10),g.axis("x"),h.axis("y"),i.headerFormatter(function(a,b){return d.tickFormat()(a,b)}).valueFormatter(function(a,b){return e.tickFormat()(a,b)});var B,C,D=a.utils.renderWatch(y,A),E=function(a){return function(){return{active:a.map(function(a){return!a.disabled})}}},F=function(a){return function(b){void 0!==b.active&&a.forEach(function(a,c){a.disabled=!b.active[c]})}};return b.dispatch=y,b.scatter=c,b.legend=f,b.xAxis=d,b.yAxis=e,b.distX=g,b.distY=h,b.tooltip=i,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return k},set:function(a){k=a}},height:{get:function(){return l},set:function(a){l=a}},container:{get:function(){return m},set:function(a){m=a}},showDistX:{get:function(){return q},set:function(a){q=a}},showDistY:{get:function(){return r},set:function(a){r=a}},showLegend:{get:function(){return s},set:function(a){s=a}},showXAxis:{get:function(){return t},set:function(a){t=a}},showYAxis:{get:function(){return u},set:function(a){u=a}},defaultState:{get:function(){return x},set:function(a){x=a}},noData:{get:function(){return z},set:function(a){z=a}},duration:{get:function(){return A},set:function(a){A=a}},tooltips:{get:function(){return i.enabled()},set:function(b){a.deprecated("tooltips","use chart.tooltip.enabled() instead"),i.enabled(!!b) -}},tooltipContent:{get:function(){return i.contentGenerator()},set:function(b){a.deprecated("tooltipContent","use chart.tooltip.contentGenerator() instead"),i.contentGenerator(b)}},tooltipXContent:{get:function(){return i.contentGenerator()},set:function(){a.deprecated("tooltipContent","This option is removed, put values into main tooltip.")}},tooltipYContent:{get:function(){return i.contentGenerator()},set:function(){a.deprecated("tooltipContent","This option is removed, put values into main tooltip.")}},margin:{get:function(){return j},set:function(a){j.top=void 0!==a.top?a.top:j.top,j.right=void 0!==a.right?a.right:j.right,j.bottom=void 0!==a.bottom?a.bottom:j.bottom,j.left=void 0!==a.left?a.left:j.left}},rightAlignYAxis:{get:function(){return v},set:function(a){v=a,e.orient(a?"right":"left")}},color:{get:function(){return n},set:function(b){n=a.utils.getColor(b),f.color(n),g.color(n),h.color(n)}}}),a.utils.inheritOptions(b,c),a.utils.initOptions(b),b},a.models.sparkline=function(){"use strict";function b(k){return k.each(function(b){var k=h-g.left-g.right,q=i-g.top-g.bottom;j=d3.select(this),a.utils.initSVG(j),l.domain(c||d3.extent(b,n)).range(e||[0,k]),m.domain(d||d3.extent(b,o)).range(f||[q,0]);{var r=j.selectAll("g.nv-wrap.nv-sparkline").data([b]),s=r.enter().append("g").attr("class","nvd3 nv-wrap nv-sparkline");s.append("g"),r.select("g")}r.attr("transform","translate("+g.left+","+g.top+")");var t=r.selectAll("path").data(function(a){return[a]});t.enter().append("path"),t.exit().remove(),t.style("stroke",function(a,b){return a.color||p(a,b)}).attr("d",d3.svg.line().x(function(a,b){return l(n(a,b))}).y(function(a,b){return m(o(a,b))}));var u=r.selectAll("circle.nv-point").data(function(a){function b(b){if(-1!=b){var c=a[b];return c.pointIndex=b,c}return null}var c=a.map(function(a,b){return o(a,b)}),d=b(c.lastIndexOf(m.domain()[1])),e=b(c.indexOf(m.domain()[0])),f=b(c.length-1);return[e,d,f].filter(function(a){return null!=a})});u.enter().append("circle"),u.exit().remove(),u.attr("cx",function(a){return l(n(a,a.pointIndex))}).attr("cy",function(a){return m(o(a,a.pointIndex))}).attr("r",2).attr("class",function(a){return n(a,a.pointIndex)==l.domain()[1]?"nv-point nv-currentValue":o(a,a.pointIndex)==m.domain()[0]?"nv-point nv-minValue":"nv-point nv-maxValue"})}),b}var c,d,e,f,g={top:2,right:0,bottom:2,left:0},h=400,i=32,j=null,k=!0,l=d3.scale.linear(),m=d3.scale.linear(),n=function(a){return a.x},o=function(a){return a.y},p=a.utils.getColor(["#000"]);return b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return h},set:function(a){h=a}},height:{get:function(){return i},set:function(a){i=a}},xDomain:{get:function(){return c},set:function(a){c=a}},yDomain:{get:function(){return d},set:function(a){d=a}},xRange:{get:function(){return e},set:function(a){e=a}},yRange:{get:function(){return f},set:function(a){f=a}},xScale:{get:function(){return l},set:function(a){l=a}},yScale:{get:function(){return m},set:function(a){m=a}},animate:{get:function(){return k},set:function(a){k=a}},x:{get:function(){return n},set:function(a){n=d3.functor(a)}},y:{get:function(){return o},set:function(a){o=d3.functor(a)}},margin:{get:function(){return g},set:function(a){g.top=void 0!==a.top?a.top:g.top,g.right=void 0!==a.right?a.right:g.right,g.bottom=void 0!==a.bottom?a.bottom:g.bottom,g.left=void 0!==a.left?a.left:g.left}},color:{get:function(){return p},set:function(b){p=a.utils.getColor(b)}}}),a.utils.initOptions(b),b},a.models.sparklinePlus=function(){"use strict";function b(p){return p.each(function(p){function q(){if(!j){var a=z.selectAll(".nv-hoverValue").data(i),b=a.enter().append("g").attr("class","nv-hoverValue").style("stroke-opacity",0).style("fill-opacity",0);a.exit().transition().duration(250).style("stroke-opacity",0).style("fill-opacity",0).remove(),a.attr("transform",function(a){return"translate("+c(e.x()(p[a],a))+",0)"}).transition().duration(250).style("stroke-opacity",1).style("fill-opacity",1),i.length&&(b.append("line").attr("x1",0).attr("y1",-f.top).attr("x2",0).attr("y2",u),b.append("text").attr("class","nv-xValue").attr("x",-6).attr("y",-f.top).attr("text-anchor","end").attr("dy",".9em"),z.select(".nv-hoverValue .nv-xValue").text(k(e.x()(p[i[0]],i[0]))),b.append("text").attr("class","nv-yValue").attr("x",6).attr("y",-f.top).attr("text-anchor","start").attr("dy",".9em"),z.select(".nv-hoverValue .nv-yValue").text(l(e.y()(p[i[0]],i[0]))))}}function r(){function a(a,b){for(var c=Math.abs(e.x()(a[0],0)-b),d=0,f=0;fc;++c){for(b=0,d=0;bb;b++)a[b][c][1]/=d;else for(b=0;e>b;b++)a[b][c][1]=0}for(c=0;f>c;++c)g[c]=0;return g}}),u.renderEnd("stackedArea immediate"),b}var c,d,e={top:0,right:0,bottom:0,left:0},f=960,g=500,h=a.utils.defaultColor(),i=Math.floor(1e5*Math.random()),j=null,k=function(a){return a.x},l=function(a){return a.y},m="stack",n="zero",o="default",p="linear",q=!1,r=a.models.scatter(),s=250,t=d3.dispatch("areaClick","areaMouseover","areaMouseout","renderEnd","elementClick","elementMouseover","elementMouseout");r.pointSize(2.2).pointDomain([2.2,2.2]);var u=a.utils.renderWatch(t,s);return b.dispatch=t,b.scatter=r,r.dispatch.on("elementClick",function(){t.elementClick.apply(this,arguments)}),r.dispatch.on("elementMouseover",function(){t.elementMouseover.apply(this,arguments)}),r.dispatch.on("elementMouseout",function(){t.elementMouseout.apply(this,arguments)}),b.interpolate=function(a){return arguments.length?(p=a,b):p},b.duration=function(a){return arguments.length?(s=a,u.reset(s),r.duration(s),b):s},b.dispatch=t,b.scatter=r,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return f},set:function(a){f=a}},height:{get:function(){return g},set:function(a){g=a}},clipEdge:{get:function(){return q},set:function(a){q=a}},offset:{get:function(){return n},set:function(a){n=a}},order:{get:function(){return o},set:function(a){o=a}},interpolate:{get:function(){return p},set:function(a){p=a}},x:{get:function(){return k},set:function(a){k=d3.functor(a)}},y:{get:function(){return l},set:function(a){l=d3.functor(a)}},margin:{get:function(){return e},set:function(a){e.top=void 0!==a.top?a.top:e.top,e.right=void 0!==a.right?a.right:e.right,e.bottom=void 0!==a.bottom?a.bottom:e.bottom,e.left=void 0!==a.left?a.left:e.left}},color:{get:function(){return h},set:function(b){h=a.utils.getColor(b)}},style:{get:function(){return m},set:function(a){switch(m=a){case"stack":b.offset("zero"),b.order("default");break;case"stream":b.offset("wiggle"),b.order("inside-out");break;case"stream-center":b.offset("silhouette"),b.order("inside-out");break;case"expand":b.offset("expand"),b.order("default");break;case"stack_percent":b.offset(b.d3_stackedOffset_stackPercent),b.order("default")}}},duration:{get:function(){return s},set:function(a){s=a,u.reset(s),r.duration(s)}}}),a.utils.inheritOptions(b,r),a.utils.initOptions(b),b},a.models.stackedAreaChart=function(){"use strict";function b(k){return F.reset(),F.models(e),r&&F.models(f),s&&F.models(g),k.each(function(k){var x=d3.select(this),F=this;a.utils.initSVG(x);var K=a.utils.availableWidth(m,x,l),L=a.utils.availableHeight(n,x,l);if(b.update=function(){x.transition().duration(C).call(b)},b.container=this,v.setter(I(k),b.update).getter(H(k)).update(),v.disabled=k.map(function(a){return!!a.disabled}),!w){var M;w={};for(M in v)w[M]=v[M]instanceof Array?v[M].slice(0):v[M]}if(!(k&&k.length&&k.filter(function(a){return a.values.length}).length))return a.utils.noData(b,x),b;x.selectAll(".nv-noData").remove(),c=e.xScale(),d=e.yScale();var N=x.selectAll("g.nv-wrap.nv-stackedAreaChart").data([k]),O=N.enter().append("g").attr("class","nvd3 nv-wrap nv-stackedAreaChart").append("g"),P=N.select("g");if(O.append("rect").style("opacity",0),O.append("g").attr("class","nv-x nv-axis"),O.append("g").attr("class","nv-y nv-axis"),O.append("g").attr("class","nv-stackedWrap"),O.append("g").attr("class","nv-legendWrap"),O.append("g").attr("class","nv-controlsWrap"),O.append("g").attr("class","nv-interactive"),P.select("rect").attr("width",K).attr("height",L),q){var Q=p?K-z:K;h.width(Q),P.select(".nv-legendWrap").datum(k).call(h),l.top!=h.height()&&(l.top=h.height(),L=a.utils.availableHeight(n,x,l)),P.select(".nv-legendWrap").attr("transform","translate("+(K-Q)+","+-l.top+")")}if(p){var R=[{key:B.stacked||"Stacked",metaKey:"Stacked",disabled:"stack"!=e.style(),style:"stack"},{key:B.stream||"Stream",metaKey:"Stream",disabled:"stream"!=e.style(),style:"stream"},{key:B.expanded||"Expanded",metaKey:"Expanded",disabled:"expand"!=e.style(),style:"expand"},{key:B.stack_percent||"Stack %",metaKey:"Stack_Percent",disabled:"stack_percent"!=e.style(),style:"stack_percent"}];z=A.length/3*260,R=R.filter(function(a){return-1!==A.indexOf(a.metaKey)}),i.width(z).color(["#444","#444","#444"]),P.select(".nv-controlsWrap").datum(R).call(i),l.top!=Math.max(i.height(),h.height())&&(l.top=Math.max(i.height(),h.height()),L=a.utils.availableHeight(n,x,l)),P.select(".nv-controlsWrap").attr("transform","translate(0,"+-l.top+")")}N.attr("transform","translate("+l.left+","+l.top+")"),t&&P.select(".nv-y.nv-axis").attr("transform","translate("+K+",0)"),u&&(j.width(K).height(L).margin({left:l.left,top:l.top}).svgContainer(x).xScale(c),N.select(".nv-interactive").call(j)),e.width(K).height(L);var S=P.select(".nv-stackedWrap").datum(k);if(S.transition().call(e),r&&(f.scale(c)._ticks(a.utils.calcTicksX(K/100,k)).tickSize(-L,0),P.select(".nv-x.nv-axis").attr("transform","translate(0,"+L+")"),P.select(".nv-x.nv-axis").transition().duration(0).call(f)),s){var T;if(T="wiggle"===e.offset()?0:a.utils.calcTicksY(L/36,k),g.scale(d)._ticks(T).tickSize(-K,0),"expand"===e.style()||"stack_percent"===e.style()){var U=g.tickFormat();D&&U===J||(D=U),g.tickFormat(J)}else D&&(g.tickFormat(D),D=null);P.select(".nv-y.nv-axis").transition().duration(0).call(g)}e.dispatch.on("areaClick.toggle",function(a){k.forEach(1===k.filter(function(a){return!a.disabled}).length?function(a){a.disabled=!1}:function(b,c){b.disabled=c!=a.seriesIndex}),v.disabled=k.map(function(a){return!!a.disabled}),y.stateChange(v),b.update()}),h.dispatch.on("stateChange",function(a){for(var c in a)v[c]=a[c];y.stateChange(v),b.update()}),i.dispatch.on("legendClick",function(a){a.disabled&&(R=R.map(function(a){return a.disabled=!0,a}),a.disabled=!1,e.style(a.style),v.style=e.style(),y.stateChange(v),b.update())}),j.dispatch.on("elementMousemove",function(c){e.clearHighlights();var d,g,h,i=[];if(k.filter(function(a,b){return a.seriesIndex=b,!a.disabled}).forEach(function(f,j){g=a.interactiveBisect(f.values,c.pointXValue,b.x());var k=f.values[g],l=b.y()(k,g);if(null!=l&&e.highlightPoint(j,g,!0),"undefined"!=typeof k){"undefined"==typeof d&&(d=k),"undefined"==typeof h&&(h=b.xScale()(b.x()(k,g)));var m="expand"==e.style()?k.display.y:b.y()(k,g);i.push({key:f.key,value:m,color:o(f,f.seriesIndex),stackedValue:k.display})}}),i.reverse(),i.length>2){var m=b.yScale().invert(c.mouseY),n=null;i.forEach(function(a,b){m=Math.abs(m);var c=Math.abs(a.stackedValue.y0),d=Math.abs(a.stackedValue.y);return m>=c&&d+c>=m?void(n=b):void 0}),null!=n&&(i[n].highlight=!0)}var p=f.tickFormat()(b.x()(d,g)),q=j.tooltip.valueFormatter();"expand"===e.style()||"stack_percent"===e.style()?(E||(E=q),q=d3.format(".1%")):E&&(q=E,E=null),j.tooltip.position({left:h+l.left,top:c.mouseY+l.top}).chartContainer(F.parentNode).valueFormatter(q).data({value:p,series:i})(),j.renderGuideLine(h)}),j.dispatch.on("elementMouseout",function(){e.clearHighlights()}),y.on("changeState",function(a){"undefined"!=typeof a.disabled&&k.length===a.disabled.length&&(k.forEach(function(b,c){b.disabled=a.disabled[c]}),v.disabled=a.disabled),"undefined"!=typeof a.style&&(e.style(a.style),G=a.style),b.update()})}),F.renderEnd("stacked Area chart immediate"),b}var c,d,e=a.models.stackedArea(),f=a.models.axis(),g=a.models.axis(),h=a.models.legend(),i=a.models.legend(),j=a.interactiveGuideline(),k=a.models.tooltip(),l={top:30,right:25,bottom:50,left:60},m=null,n=null,o=a.utils.defaultColor(),p=!0,q=!0,r=!0,s=!0,t=!1,u=!1,v=a.utils.state(),w=null,x=null,y=d3.dispatch("stateChange","changeState","renderEnd"),z=250,A=["Stacked","Stream","Expanded"],B={},C=250;v.style=e.style(),f.orient("bottom").tickPadding(7),g.orient(t?"right":"left"),k.headerFormatter(function(a,b){return f.tickFormat()(a,b)}).valueFormatter(function(a,b){return g.tickFormat()(a,b)}),j.tooltip.headerFormatter(function(a,b){return f.tickFormat()(a,b)}).valueFormatter(function(a,b){return g.tickFormat()(a,b)});var D=null,E=null;i.updateState(!1);var F=a.utils.renderWatch(y),G=e.style(),H=function(a){return function(){return{active:a.map(function(a){return!a.disabled}),style:e.style()}}},I=function(a){return function(b){void 0!==b.style&&(G=b.style),void 0!==b.active&&a.forEach(function(a,c){a.disabled=!b.active[c]})}},J=d3.format("%");return e.dispatch.on("elementMouseover.tooltip",function(a){a.point.x=e.x()(a.point),a.point.y=e.y()(a.point),k.data(a).position(a.pos).hidden(!1)}),e.dispatch.on("elementMouseout.tooltip",function(){k.hidden(!0)}),b.dispatch=y,b.stacked=e,b.legend=h,b.controls=i,b.xAxis=f,b.yAxis=g,b.interactiveLayer=j,b.tooltip=k,b.dispatch=y,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return m},set:function(a){m=a}},height:{get:function(){return n},set:function(a){n=a}},showLegend:{get:function(){return q},set:function(a){q=a}},showXAxis:{get:function(){return r},set:function(a){r=a}},showYAxis:{get:function(){return s},set:function(a){s=a}},defaultState:{get:function(){return w},set:function(a){w=a}},noData:{get:function(){return x},set:function(a){x=a}},showControls:{get:function(){return p},set:function(a){p=a}},controlLabels:{get:function(){return B},set:function(a){B=a}},controlOptions:{get:function(){return A},set:function(a){A=a}},tooltips:{get:function(){return k.enabled()},set:function(b){a.deprecated("tooltips","use chart.tooltip.enabled() instead"),k.enabled(!!b)}},tooltipContent:{get:function(){return k.contentGenerator()},set:function(b){a.deprecated("tooltipContent","use chart.tooltip.contentGenerator() instead"),k.contentGenerator(b)}},margin:{get:function(){return l},set:function(a){l.top=void 0!==a.top?a.top:l.top,l.right=void 0!==a.right?a.right:l.right,l.bottom=void 0!==a.bottom?a.bottom:l.bottom,l.left=void 0!==a.left?a.left:l.left}},duration:{get:function(){return C},set:function(a){C=a,F.reset(C),e.duration(C),f.duration(C),g.duration(C)}},color:{get:function(){return o},set:function(b){o=a.utils.getColor(b),h.color(o),e.color(o)}},rightAlignYAxis:{get:function(){return t},set:function(a){t=a,g.orient(t?"right":"left")}},useInteractiveGuideline:{get:function(){return u},set:function(a){u=!!a,b.interactive(!a),b.useVoronoi(!a),e.scatter.interactive(!a)}}}),a.utils.inheritOptions(b,e),a.utils.initOptions(b),b},a.models.sunburst=function(){"use strict";function b(u){return t.reset(),u.each(function(b){function t(a){a.x0=a.x,a.dx0=a.dx}function u(a){var b=d3.interpolate(p.domain(),[a.x,a.x+a.dx]),c=d3.interpolate(q.domain(),[a.y,1]),d=d3.interpolate(q.range(),[a.y?20:0,y]);return function(a,e){return e?function(){return s(a)}:function(e){return p.domain(b(e)),q.domain(c(e)).range(d(e)),s(a)}}}l=d3.select(this);var v,w=a.utils.availableWidth(g,l,f),x=a.utils.availableHeight(h,l,f),y=Math.min(w,x)/2;a.utils.initSVG(l);var z=l.selectAll(".nv-wrap.nv-sunburst").data(b),A=z.enter().append("g").attr("class","nvd3 nv-wrap nv-sunburst nv-chart-"+k),B=A.selectAll("nv-sunburst");z.attr("transform","translate("+w/2+","+x/2+")"),l.on("click",function(a,b){o.chartClick({data:a,index:b,pos:d3.event,id:k})}),q.range([0,y]),c=c||b,e=b[0],r.value(j[i]||j.count),v=B.data(r.nodes).enter().append("path").attr("d",s).style("fill",function(a){return m((a.children?a:a.parent).name)}).style("stroke","#FFF").on("click",function(a){d!==c&&c!==a&&(d=c),c=a,v.transition().duration(n).attrTween("d",u(a))}).each(t).on("dblclick",function(a){d.parent==a&&v.transition().duration(n).attrTween("d",u(e))}).each(t).on("mouseover",function(a){d3.select(this).classed("hover",!0).style("opacity",.8),o.elementMouseover({data:a,color:d3.select(this).style("fill")})}).on("mouseout",function(a){d3.select(this).classed("hover",!1).style("opacity",1),o.elementMouseout({data:a})}).on("mousemove",function(a){o.elementMousemove({data:a})})}),t.renderEnd("sunburst immediate"),b}var c,d,e,f={top:0,right:0,bottom:0,left:0},g=null,h=null,i="count",j={count:function(){return 1},size:function(a){return a.size}},k=Math.floor(1e4*Math.random()),l=null,m=a.utils.defaultColor(),n=500,o=d3.dispatch("chartClick","elementClick","elementDblClick","elementMousemove","elementMouseover","elementMouseout","renderEnd"),p=d3.scale.linear().range([0,2*Math.PI]),q=d3.scale.sqrt(),r=d3.layout.partition().sort(null).value(function(){return 1}),s=d3.svg.arc().startAngle(function(a){return Math.max(0,Math.min(2*Math.PI,p(a.x)))}).endAngle(function(a){return Math.max(0,Math.min(2*Math.PI,p(a.x+a.dx)))}).innerRadius(function(a){return Math.max(0,q(a.y))}).outerRadius(function(a){return Math.max(0,q(a.y+a.dy))}),t=a.utils.renderWatch(o);return b.dispatch=o,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return g},set:function(a){g=a}},height:{get:function(){return h},set:function(a){h=a}},mode:{get:function(){return i},set:function(a){i=a}},id:{get:function(){return k},set:function(a){k=a}},duration:{get:function(){return n},set:function(a){n=a}},margin:{get:function(){return f},set:function(a){f.top=void 0!=a.top?a.top:f.top,f.right=void 0!=a.right?a.right:f.right,f.bottom=void 0!=a.bottom?a.bottom:f.bottom,f.left=void 0!=a.left?a.left:f.left}},color:{get:function(){return m},set:function(b){m=a.utils.getColor(b)}}}),a.utils.initOptions(b),b},a.models.sunburstChart=function(){"use strict";function b(d){return m.reset(),m.models(c),d.each(function(d){var h=d3.select(this);a.utils.initSVG(h);var i=a.utils.availableWidth(f,h,e),j=a.utils.availableHeight(g,h,e);if(b.update=function(){0===k?h.call(b):h.transition().duration(k).call(b)},b.container=this,!d||!d.length)return a.utils.noData(b,h),b;h.selectAll(".nv-noData").remove();var l=h.selectAll("g.nv-wrap.nv-sunburstChart").data(d),m=l.enter().append("g").attr("class","nvd3 nv-wrap nv-sunburstChart").append("g"),n=l.select("g");m.append("g").attr("class","nv-sunburstWrap"),l.attr("transform","translate("+e.left+","+e.top+")"),c.width(i).height(j);var o=n.select(".nv-sunburstWrap").datum(d);d3.transition(o).call(c)}),m.renderEnd("sunburstChart immediate"),b}var c=a.models.sunburst(),d=a.models.tooltip(),e={top:30,right:20,bottom:20,left:20},f=null,g=null,h=a.utils.defaultColor(),i=(Math.round(1e5*Math.random()),null),j=null,k=250,l=d3.dispatch("tooltipShow","tooltipHide","stateChange","changeState","renderEnd"),m=a.utils.renderWatch(l);return d.headerEnabled(!1).duration(0).valueFormatter(function(a){return a}),c.dispatch.on("elementMouseover.tooltip",function(a){a.series={key:a.data.name,value:a.data.size,color:a.color},d.data(a).hidden(!1)}),c.dispatch.on("elementMouseout.tooltip",function(){d.hidden(!0)}),c.dispatch.on("elementMousemove.tooltip",function(){d.position({top:d3.event.pageY,left:d3.event.pageX})()}),b.dispatch=l,b.sunburst=c,b.tooltip=d,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{noData:{get:function(){return j},set:function(a){j=a}},defaultState:{get:function(){return i},set:function(a){i=a}},color:{get:function(){return h},set:function(a){h=a,c.color(h)}},duration:{get:function(){return k},set:function(a){k=a,m.reset(k),c.duration(k)}},margin:{get:function(){return e},set:function(a){e.top=void 0!==a.top?a.top:e.top,e.right=void 0!==a.right?a.right:e.right,e.bottom=void 0!==a.bottom?a.bottom:e.bottom,e.left=void 0!==a.left?a.left:e.left}}}),a.utils.inheritOptions(b,c),a.utils.initOptions(b),b},a.version="1.8.1"}(); \ No newline at end of file diff --git a/backend/coverage-report-progress/dashboard.html b/backend/coverage-report-progress/dashboard.html deleted file mode 100644 index a61b3fa3..00000000 --- a/backend/coverage-report-progress/dashboard.html +++ /dev/null @@ -1,741 +0,0 @@ - - - - - Dashboard for /var/www/html/backend/app - - - - - - - -
-
-
-
- -
-
-
-
-
-
-
-

Classes

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
-
-
-

Insufficient Coverage

-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
ClassCoverage
App\Console\Commands\FetchNewArticlesCommand0%
App\Console\Commands\SyncChannelPostsCommand0%
App\Events\ArticleReadyToPublish0%
App\Events\ExceptionLogged0%
App\Events\ExceptionOccurred0%
App\Exceptions\PlatformAuthException0%
App\Exceptions\PublishException0%
App\Exceptions\RoutingMismatchException0%
App\Http\Controllers\Api\V1\AuthController0%
App\Http\Controllers\Api\V1\FeedsController0%
App\Http\Controllers\Api\V1\LogsController0%
App\Http\Controllers\Api\V1\PlatformAccountsController0%
App\Http\Controllers\Api\V1\PlatformChannelsController0%
App\Http\Controllers\Api\V1\RoutingController0%
App\Http\Controllers\Api\V1\SettingsController0%
App\Http\Controllers\ArticlesController0%
App\Http\Controllers\FeedsController0%
App\Http\Controllers\LogsController0%
App\Http\Controllers\OnboardingController0%
App\Http\Controllers\PlatformAccountsController0%
App\Http\Controllers\PlatformChannelsController0%
App\Http\Controllers\RoutingController0%
App\Http\Controllers\SettingsController0%
App\Http\Middleware\HandleAppearance0%
App\Http\Middleware\HandleInertiaRequests0%
App\Http\Requests\StoreFeedRequest0%
App\Http\Requests\UpdateFeedRequest0%
App\Http\Resources\ArticlePublicationResource0%
App\Http\Resources\PlatformAccountResource0%
App\Http\Resources\PlatformChannelResource0%
App\Http\Resources\PlatformInstanceResource0%
App\Http\Resources\RouteResource0%
App\Jobs\ArticleDiscoveryForFeedJob0%
App\Jobs\ArticleDiscoveryJob0%
App\Jobs\PublishToLemmyJob0%
App\Jobs\SyncChannelPostsJob0%
App\Listeners\LogExceptionToDatabase0%
App\Listeners\PublishApprovedArticle0%
App\Listeners\PublishArticle0%
App\Listeners\ValidateArticleListener0%
App\Models\ArticlePublication0%
App\Models\Feed0%
App\Models\Keyword0%
App\Models\Language0%
App\Models\PlatformAccount0%
App\Models\PlatformChannel0%
App\Models\PlatformChannelPost0%
App\Models\PlatformInstance0%
App\Models\Route0%
App\Models\User0%
App\Modules\Lemmy\LemmyRequest0%
App\Modules\Lemmy\Services\LemmyApiService0%
App\Modules\Lemmy\Services\LemmyPublisher0%
App\Services\Article\ArticleFetcher0%
App\Services\Article\ValidationService0%
App\Services\Auth\LemmyAuthService0%
App\Services\Factories\ArticleParserFactory0%
App\Services\Factories\HomepageParserFactory0%
App\Services\Http\HttpFetcher0%
App\Services\Log\LogSaver0%
App\Services\OnboardingRedirectService0%
App\Services\Parsers\BelgaArticlePageParser0%
App\Services\Parsers\BelgaArticleParser0%
App\Services\Parsers\BelgaHomepageParser0%
App\Services\Parsers\BelgaHomepageParserAdapter0%
App\Services\Parsers\VrtArticlePageParser0%
App\Services\Parsers\VrtArticleParser0%
App\Services\Parsers\VrtHomepageParser0%
App\Services\Parsers\VrtHomepageParserAdapter0%
App\Services\Publishing\ArticlePublishingService0%
App\Services\RoutingValidationService0%
App\Services\SystemStatusService0%
App\Http\Controllers\Api\V1\BaseController37%
App\Models\Setting50%
App\Models\Article66%
App\Providers\HorizonServiceProvider75%
App\Providers\AppServiceProvider82%
App\Http\Controllers\Api\V1\DashboardController84%
App\Http\Controllers\Api\V1\ArticlesController87%
-
-
-
-

Project Risks

-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
ClassCRAP
App\Http\Controllers\OnboardingController506
App\Modules\Lemmy\Services\LemmyApiService462
App\Http\Controllers\Api\V1\RoutingController306
App\Services\Parsers\BelgaArticlePageParser306
App\Http\Controllers\RoutingController240
App\Http\Controllers\Api\V1\PlatformAccountsController210
App\Services\Parsers\VrtArticlePageParser210
App\Http\Controllers\Api\V1\FeedsController182
App\Http\Controllers\Api\V1\PlatformChannelsController182
App\Jobs\SyncChannelPostsJob182
App\Models\Feed182
App\Http\Controllers\Api\V1\AuthController132
App\Services\Article\ArticleFetcher132
App\Http\Controllers\PlatformAccountsController110
App\Http\Controllers\PlatformChannelsController110
App\Models\PlatformAccount110
App\Http\Controllers\FeedsController90
App\Services\Http\HttpFetcher90
App\Services\SystemStatusService72
App\Http\Controllers\Api\V1\SettingsController56
App\Listeners\ValidateArticleListener56
App\Modules\Lemmy\LemmyRequest42
App\Services\Auth\LemmyAuthService42
App\Services\Factories\ArticleParserFactory42
App\Services\Log\LogSaver42
App\Exceptions\PublishException30
App\Services\Article\ValidationService30
App\Services\Factories\HomepageParserFactory30
App\Services\Publishing\ArticlePublishingService30
App\Services\RoutingValidationService30
App\Models\Article23
App\Models\Setting22
App\Listeners\PublishApprovedArticle20
App\Http\Controllers\Api\V1\BaseController14
App\Console\Commands\FetchNewArticlesCommand12
App\Console\Commands\SyncChannelPostsCommand12
App\Http\Controllers\Api\V1\LogsController12
App\Http\Controllers\SettingsController12
App\Http\Requests\UpdateFeedRequest12
App\Jobs\ArticleDiscoveryJob12
App\Jobs\PublishToLemmyJob12
App\Listeners\PublishArticle12
App\Providers\AppServiceProvider6
App\Services\OnboardingRedirectService6
App\Http\Controllers\Api\V1\ArticlesController5
App\Http\Controllers\Api\V1\DashboardController3
-
-
-
-
-
-

Methods

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
-
-
-

Insufficient Coverage

-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
MethodCoverage
handle0%
handle0%
syncLemmy0%
__construct0%
__construct0%
__construct0%
__construct0%
getPlatform0%
__construct0%
getArticle0%
getPlatform0%
__construct0%
login0%
register0%
logout0%
me0%
sendError0%
sendValidationError0%
sendNotFound0%
sendUnauthorized0%
index0%
store0%
show0%
update0%
destroy0%
toggle0%
index0%
index0%
store0%
show0%
update0%
destroy0%
setActive0%
index0%
store0%
show0%
update0%
destroy0%
toggle0%
index0%
store0%
show0%
update0%
destroy0%
toggle0%
index0%
update0%
__invoke0%
approve0%
reject0%
index0%
create0%
store0%
show0%
edit0%
update0%
destroy0%
toggle0%
__invoke0%
index0%
platform0%
feed0%
channel0%
complete0%
needsOnboarding0%
hasPlatformAccount0%
hasFeed0%
hasChannel0%
index0%
create0%
store0%
edit0%
update0%
destroy0%
setActive0%
index0%
create0%
store0%
show0%
edit0%
update0%
destroy0%
toggle0%
index0%
create0%
store0%
edit0%
update0%
destroy0%
toggle0%
parseJsonFilters0%
index0%
update0%
handle0%
version0%
share0%
authorize0%
rules0%
authorize0%
rules0%
toArray0%
toArray0%
toArray0%
toArray0%
toArray0%
__construct0%
handle0%
dispatchForAllActiveFeeds0%
__construct0%
handle0%
__construct0%
handle0%
__construct0%
dispatchForAllActiveChannels0%
handle0%
syncLemmyChannelPosts0%
getAuthToken0%
handle0%
handle0%
__construct0%
handle0%
handle0%
isValid0%
isApproved0%
isPending0%
isRejected0%
canBePublished0%
article0%
getTypeDisplayAttribute0%
getStatusAttribute0%
channels0%
activeChannels0%
articles0%
language0%
feed0%
platformChannel0%
platformInstances0%
platformChannels0%
feeds0%
password0%
apiToken0%
getActive0%
setAsActive0%
channels0%
activeChannels0%
platformInstance0%
platformAccounts0%
activePlatformAccounts0%
getFullNameAttribute0%
feeds0%
activeFeeds0%
language0%
casts0%
urlExists0%
storePost0%
channels0%
languages0%
findByUrl0%
feed0%
platformChannel0%
keywords0%
set0%
setBool0%
isArticleProcessingEnabled0%
setArticleProcessingEnabled0%
setPublishingApprovalsEnabled0%
casts0%
__construct0%
get0%
post0%
withToken0%
__construct0%
login0%
getCommunityId0%
syncChannelPosts0%
createPost0%
getLanguages0%
__construct0%
publishToChannel0%
mapExceptionToLogLevel0%
getArticlesFromFeed0%
getArticlesFromRssFeed0%
getArticlesFromWebsiteFeed0%
fetchArticleData0%
saveArticle0%
validate0%
validateByKeywords0%
getToken0%
getParser0%
getSupportedSources0%
registerParser0%
getParser0%
getParserForFeed0%
fetchHtml0%
fetchMultipleUrls0%
info0%
error0%
warning0%
debug0%
log0%
handleRedirect0%
extractTitle0%
extractDescription0%
extractFullArticle0%
extractThumbnail0%
extractData0%
canParse0%
extractData0%
getSourceName0%
extractArticleUrls0%
canParse0%
extractArticleUrls0%
getHomepageUrl0%
getSourceName0%
extractTitle0%
extractDescription0%
extractFullArticle0%
extractThumbnail0%
extractData0%
canParse0%
extractData0%
getSourceName0%
extractArticleUrls0%
canParse0%
extractArticleUrls0%
getHomepageUrl0%
getSourceName0%
publishToRoutedChannels0%
publishToChannel0%
validateLanguageCompatibility0%
getSystemStatus0%
canProcessArticles0%
gate66%
approve71%
reject71%
stats83%
-
-
- -
- -
- - - - - - diff --git a/backend/coverage-report-progress/index.html b/backend/coverage-report-progress/index.html deleted file mode 100644 index 9a70f51a..00000000 --- a/backend/coverage-report-progress/index.html +++ /dev/null @@ -1,424 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 11.00% covered (danger) -
-
-
11.00%
183 / 1664
-
- 8.46% covered (danger) -
-
-
8.46%
22 / 260
-
- 5.88% covered (danger) -
-
-
5.88%
5 / 85
Console
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 16
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
Contracts
n/a
0 / 0
n/a
0 / 0
n/a
0 / 0
Enums
n/a
0 / 0
n/a
0 / 0
n/a
0 / 0
Events
-
- 40.00% covered (danger) -
-
-
40.00%
2 / 5
-
- 40.00% covered (danger) -
-
-
40.00%
2 / 5
-
- 40.00% covered (danger) -
-
-
40.00%
2 / 5
Exceptions
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 19
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 6
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
Http
-
- 9.30% covered (danger) -
-
-
9.30%
76 / 817
-
- 3.96% covered (danger) -
-
-
3.96%
4 / 101
-
- 3.45% covered (danger) -
-
-
3.45%
1 / 29
Jobs
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 81
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 12
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 4
Listeners
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 43
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 5
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 4
Models
-
- 20.39% covered (danger) -
-
-
20.39%
31 / 152
-
- 16.67% covered (danger) -
-
-
16.67%
9 / 54
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 12
Modules
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 120
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 12
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
Providers
-
- 81.82% covered (warning) -
-
-
81.82%
27 / 33
-
- 40.00% covered (danger) -
-
-
40.00%
2 / 5
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
Services
-
- 10.78% covered (danger) -
-
-
10.78%
40 / 371
-
- 7.14% covered (danger) -
-
-
7.14%
4 / 56
-
- 5.00% covered (danger) -
-
-
5.00%
1 / 20
LogLevelEnum.php
-
- 100.00% covered (success) -
-
-
100.00%
7 / 7
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
-
- -
- - diff --git a/backend/coverage-report-with-models/Console/Commands/FetchNewArticlesCommand.php.html b/backend/coverage-report-with-models/Console/Commands/FetchNewArticlesCommand.php.html deleted file mode 100644 index 2b7e6f3c..00000000 --- a/backend/coverage-report-with-models/Console/Commands/FetchNewArticlesCommand.php.html +++ /dev/null @@ -1,187 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Console/Commands/FetchNewArticlesCommand.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 8
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
FetchNewArticlesCommand
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 8
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
12
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 handle
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 8
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
12
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Console\Commands;
4
5use App\Jobs\ArticleDiscoveryJob;
6use App\Models\Feed;
7use App\Models\Setting;
8use Illuminate\Console\Command;
9
10class FetchNewArticlesCommand extends Command
11{
12    protected $signature = 'article:refresh';
13
14    protected $description = 'Fetches latest articles';
15
16    public function handle(): int
17    {
18        if (!Setting::isArticleProcessingEnabled()) {
19            $this->info('Article processing is disabled. Article discovery skipped.');
20
21            return self::SUCCESS;
22        }
23
24        if (!Feed::where('is_active', true)->exists()) {
25            $this->info('No active feeds found. Article discovery skipped.');
26
27            return self::SUCCESS;
28        }
29
30        ArticleDiscoveryJob::dispatch();
31
32        return self::SUCCESS;
33    }
34}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:52:46 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-with-models/Console/Commands/SyncChannelPostsCommand.php.html b/backend/coverage-report-with-models/Console/Commands/SyncChannelPostsCommand.php.html deleted file mode 100644 index a468986f..00000000 --- a/backend/coverage-report-with-models/Console/Commands/SyncChannelPostsCommand.php.html +++ /dev/null @@ -1,209 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Console/Commands/SyncChannelPostsCommand.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 8
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
SyncChannelPostsCommand
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 8
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
12
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 handle
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 5
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
6
 syncLemmy
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Console\Commands;
4
5use App\Jobs\SyncChannelPostsJob;
6use Illuminate\Console\Command;
7
8class SyncChannelPostsCommand extends Command
9{
10    protected $signature = 'channel:sync {platform=lemmy}';
11
12    protected $description = 'Manually sync channel posts for a platform';
13
14    public function handle(): int
15    {
16        $platform = $this->argument('platform');
17
18        if ($platform === 'lemmy') {
19            return $this->syncLemmy();
20        }
21
22        $this->error("Unsupported platform: {$platform}");
23
24        return self::FAILURE;
25    }
26
27    private function syncLemmy(): int
28    {
29        SyncChannelPostsJob::dispatchForAllActiveChannels();
30        $this->info('Successfully dispatched sync jobs for all active Lemmy channels');
31
32        return self::SUCCESS;
33    }
34}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:52:46 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-with-models/Console/Commands/dashboard.html b/backend/coverage-report-with-models/Console/Commands/dashboard.html deleted file mode 100644 index 4fab8eef..00000000 --- a/backend/coverage-report-with-models/Console/Commands/dashboard.html +++ /dev/null @@ -1,294 +0,0 @@ - - - - - Dashboard for /var/www/html/backend/app/Console/Commands - - - - - - - -
-
-
-
- -
-
-
-
-
-
-
-

Classes

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
-
-
-

Insufficient Coverage

- -
-
-

Project Risks

- -
-
-
-
-

Methods

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
-
-
-

Insufficient Coverage

-
- - - - - - - - - - - - - -
MethodCoverage
handle0%
handle0%
syncLemmy0%
-
-
-
-

Project Risks

-
- - - - - - - - - - - - -
MethodCRAP
handle12
handle6
-
-
-
- -
- - - - - - diff --git a/backend/coverage-report-with-models/Console/Commands/index.html b/backend/coverage-report-with-models/Console/Commands/index.html deleted file mode 100644 index 55a13f96..00000000 --- a/backend/coverage-report-with-models/Console/Commands/index.html +++ /dev/null @@ -1,148 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Console/Commands - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 16
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
FetchNewArticlesCommand.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 8
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
SyncChannelPostsCommand.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 8
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- -
- - diff --git a/backend/coverage-report-with-models/Console/dashboard.html b/backend/coverage-report-with-models/Console/dashboard.html deleted file mode 100644 index b6593dbd..00000000 --- a/backend/coverage-report-with-models/Console/dashboard.html +++ /dev/null @@ -1,293 +0,0 @@ - - - - - Dashboard for /var/www/html/backend/app/Console - - - - - - - -
-
-
-
- -
-
-
-
-
-
-
-

Classes

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
-
-
-

Insufficient Coverage

- -
-
-

Project Risks

- -
-
-
-
-

Methods

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
-
-
-

Insufficient Coverage

-
- - - - - - - - - - - - - -
MethodCoverage
handle0%
handle0%
syncLemmy0%
-
-
-
-

Project Risks

-
- - - - - - - - - - - - -
MethodCRAP
handle12
handle6
-
-
-
- -
- - - - - - diff --git a/backend/coverage-report-with-models/Console/index.html b/backend/coverage-report-with-models/Console/index.html deleted file mode 100644 index 184bc3e1..00000000 --- a/backend/coverage-report-with-models/Console/index.html +++ /dev/null @@ -1,119 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Console - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 16
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
Commands
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 16
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
-
- -
- - diff --git a/backend/coverage-report-with-models/Contracts/ArticleParserInterface.php.html b/backend/coverage-report-with-models/Contracts/ArticleParserInterface.php.html deleted file mode 100644 index f2df8910..00000000 --- a/backend/coverage-report-with-models/Contracts/ArticleParserInterface.php.html +++ /dev/null @@ -1,108 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Contracts/ArticleParserInterface.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
n/a
0 / 0
n/a
0 / 0
CRAP
n/a
0 / 0
-
- - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Contracts;
4
5interface ArticleParserInterface
6{
7    /**
8     * Check if this parser can handle the given URL
9     */
10    public function canParse(string $url): bool;
11
12    /**
13     * Extract article data from HTML
14     * @return array<string, mixed>
15     */
16    public function extractData(string $html): array;
17
18    /**
19     * Get the source name for this parser
20     */
21    public function getSourceName(): string;
22}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:52:46 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-with-models/Contracts/HomepageParserInterface.php.html b/backend/coverage-report-with-models/Contracts/HomepageParserInterface.php.html deleted file mode 100644 index 4c7d8932..00000000 --- a/backend/coverage-report-with-models/Contracts/HomepageParserInterface.php.html +++ /dev/null @@ -1,113 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Contracts/HomepageParserInterface.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
n/a
0 / 0
n/a
0 / 0
CRAP
n/a
0 / 0
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Contracts;
4
5interface HomepageParserInterface
6{
7    /**
8     * Check if this parser can handle the given homepage URL
9     */
10    public function canParse(string $url): bool;
11
12    /**
13     * Extract article URLs from homepage HTML
14     * @return array<int, string>
15     */
16    public function extractArticleUrls(string $html): array;
17
18    /**
19     * Get the homepage URL for this source
20     */
21    public function getHomepageUrl(): string;
22
23    /**
24     * Get the source name for this parser
25     */
26    public function getSourceName(): string;
27}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:52:46 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-with-models/Contracts/dashboard.html b/backend/coverage-report-with-models/Contracts/dashboard.html deleted file mode 100644 index e1d0efbc..00000000 --- a/backend/coverage-report-with-models/Contracts/dashboard.html +++ /dev/null @@ -1,284 +0,0 @@ - - - - - Dashboard for /var/www/html/backend/app/Contracts - - - - - - - -
-
-
-
- -
-
-
-
-
-
-
-

Classes

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
-
-
-

Insufficient Coverage

-
- - - - - - - - - - -
ClassCoverage
-
-
-
-

Project Risks

-
- - - - - - - - - - -
ClassCRAP
-
-
-
-
-
-

Methods

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
-
-
-

Insufficient Coverage

-
- - - - - - - - - - -
MethodCoverage
-
-
-
-

Project Risks

-
- - - - - - - - - - -
MethodCRAP
-
-
-
- -
- - - - - - diff --git a/backend/coverage-report-with-models/Contracts/index.html b/backend/coverage-report-with-models/Contracts/index.html deleted file mode 100644 index 53f1519e..00000000 --- a/backend/coverage-report-with-models/Contracts/index.html +++ /dev/null @@ -1,102 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Contracts - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
n/a
0 / 0
n/a
0 / 0
n/a
0 / 0
ArticleParserInterface.php
n/a
0 / 0
n/a
0 / 0
n/a
0 / 0
HomepageParserInterface.php
n/a
0 / 0
n/a
0 / 0
n/a
0 / 0
-
- -
- - diff --git a/backend/coverage-report-with-models/Enums/PlatformEnum.php.html b/backend/coverage-report-with-models/Enums/PlatformEnum.php.html deleted file mode 100644 index 4fb8de3f..00000000 --- a/backend/coverage-report-with-models/Enums/PlatformEnum.php.html +++ /dev/null @@ -1,94 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Enums/PlatformEnum.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
n/a
0 / 0
n/a
0 / 0
CRAP
n/a
0 / 0
-
- - - - - - - - - - - - -
1<?php
2
3namespace App\Enums;
4
5enum PlatformEnum: string
6{
7    case LEMMY = 'lemmy';
8}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:52:46 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-with-models/Enums/dashboard.html b/backend/coverage-report-with-models/Enums/dashboard.html deleted file mode 100644 index d8391c32..00000000 --- a/backend/coverage-report-with-models/Enums/dashboard.html +++ /dev/null @@ -1,284 +0,0 @@ - - - - - Dashboard for /var/www/html/backend/app/Enums - - - - - - - -
-
-
-
- -
-
-
-
-
-
-
-

Classes

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
-
-
-

Insufficient Coverage

-
- - - - - - - - - - -
ClassCoverage
-
-
-
-

Project Risks

-
- - - - - - - - - - -
ClassCRAP
-
-
-
-
-
-

Methods

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
-
-
-

Insufficient Coverage

-
- - - - - - - - - - -
MethodCoverage
-
-
-
-

Project Risks

-
- - - - - - - - - - -
MethodCRAP
-
-
-
- -
- - - - - - diff --git a/backend/coverage-report-with-models/Enums/index.html b/backend/coverage-report-with-models/Enums/index.html deleted file mode 100644 index 981d2c67..00000000 --- a/backend/coverage-report-with-models/Enums/index.html +++ /dev/null @@ -1,89 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Enums - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
n/a
0 / 0
n/a
0 / 0
n/a
0 / 0
PlatformEnum.php
n/a
0 / 0
n/a
0 / 0
n/a
0 / 0
-
- -
- - diff --git a/backend/coverage-report-with-models/Events/ArticleApproved.php.html b/backend/coverage-report-with-models/Events/ArticleApproved.php.html deleted file mode 100644 index 04a5cff9..00000000 --- a/backend/coverage-report-with-models/Events/ArticleApproved.php.html +++ /dev/null @@ -1,169 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Events/ArticleApproved.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
CRAP
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
ArticleApproved
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
1
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
 __construct
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
1
-
- - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Events;
4
5use App\Models\Article;
6use Illuminate\Foundation\Events\Dispatchable;
7use Illuminate\Queue\SerializesModels;
8
9class ArticleApproved
10{
11    use Dispatchable, SerializesModels;
12
13    public function __construct(public Article $article)
14    {
15        //
16    }
17}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:52:46 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-with-models/Events/ArticleReadyToPublish.php.html b/backend/coverage-report-with-models/Events/ArticleReadyToPublish.php.html deleted file mode 100644 index c288a89c..00000000 --- a/backend/coverage-report-with-models/Events/ArticleReadyToPublish.php.html +++ /dev/null @@ -1,170 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Events/ArticleReadyToPublish.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
ArticleReadyToPublish
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 __construct
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Events;
4
5use App\Models\Article;
6use Illuminate\Broadcasting\InteractsWithSockets;
7use Illuminate\Foundation\Events\Dispatchable;
8use Illuminate\Queue\SerializesModels;
9
10class ArticleReadyToPublish
11{
12    use Dispatchable, InteractsWithSockets, SerializesModels;
13
14    public function __construct(public Article $article)
15    {
16
17    }
18}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:52:46 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-with-models/Events/ExceptionLogged.php.html b/backend/coverage-report-with-models/Events/ExceptionLogged.php.html deleted file mode 100644 index d0a9c693..00000000 --- a/backend/coverage-report-with-models/Events/ExceptionLogged.php.html +++ /dev/null @@ -1,169 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Events/ExceptionLogged.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
ExceptionLogged
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 __construct
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Events;
4
5use App\Models\Log;
6use Illuminate\Foundation\Events\Dispatchable;
7use Illuminate\Queue\SerializesModels;
8
9class ExceptionLogged
10{
11    use Dispatchable, SerializesModels;
12
13    public function __construct(
14        public Log $log
15    ) {
16    }
17}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:52:46 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-with-models/Events/ExceptionOccurred.php.html b/backend/coverage-report-with-models/Events/ExceptionOccurred.php.html deleted file mode 100644 index 73168bb6..00000000 --- a/backend/coverage-report-with-models/Events/ExceptionOccurred.php.html +++ /dev/null @@ -1,174 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Events/ExceptionOccurred.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
ExceptionOccurred
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 __construct
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Events;
4
5use App\LogLevelEnum;
6use Illuminate\Foundation\Events\Dispatchable;
7use Illuminate\Queue\SerializesModels;
8use Throwable;
9
10class ExceptionOccurred
11{
12    use Dispatchable, SerializesModels;
13
14    public function __construct(
15        public Throwable $exception,
16        public LogLevelEnum $level,
17        public string $message,
18        /** @var array<string, mixed> */
19        public array $context = []
20    ) {
21    }
22}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:52:46 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-with-models/Events/NewArticleFetched.php.html b/backend/coverage-report-with-models/Events/NewArticleFetched.php.html deleted file mode 100644 index db23432a..00000000 --- a/backend/coverage-report-with-models/Events/NewArticleFetched.php.html +++ /dev/null @@ -1,169 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Events/NewArticleFetched.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
CRAP
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
NewArticleFetched
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
1
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
 __construct
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
1
-
- - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Events;
4
5use App\Models\Article;
6use Illuminate\Broadcasting\InteractsWithSockets;
7use Illuminate\Foundation\Events\Dispatchable;
8use Illuminate\Queue\SerializesModels;
9
10class NewArticleFetched
11{
12    use Dispatchable, InteractsWithSockets, SerializesModels;
13
14    public function __construct(public Article $article)
15    {
16    }
17}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:52:46 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-with-models/Events/dashboard.html b/backend/coverage-report-with-models/Events/dashboard.html deleted file mode 100644 index 83f965fd..00000000 --- a/backend/coverage-report-with-models/Events/dashboard.html +++ /dev/null @@ -1,290 +0,0 @@ - - - - - Dashboard for /var/www/html/backend/app/Events - - - - - - - -
-
-
-
- -
-
-
-
-
-
-
-

Classes

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
-
-
-

Insufficient Coverage

- -
-
-

Project Risks

-
- - - - - - - - - - -
ClassCRAP
-
-
-
-
-
-

Methods

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
-
-
-

Insufficient Coverage

-
- - - - - - - - - - - - - -
MethodCoverage
__construct0%
__construct0%
__construct0%
-
-
-
-

Project Risks

-
- - - - - - - - - - -
MethodCRAP
-
-
-
- -
- - - - - - diff --git a/backend/coverage-report-with-models/Events/index.html b/backend/coverage-report-with-models/Events/index.html deleted file mode 100644 index 90b4bfeb..00000000 --- a/backend/coverage-report-with-models/Events/index.html +++ /dev/null @@ -1,231 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Events - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 40.00% covered (danger) -
-
-
40.00%
2 / 5
-
- 40.00% covered (danger) -
-
-
40.00%
2 / 5
-
- 40.00% covered (danger) -
-
-
40.00%
2 / 5
ArticleApproved.php
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
ArticleReadyToPublish.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
ExceptionLogged.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
ExceptionOccurred.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
NewArticleFetched.php
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
-
- -
- - diff --git a/backend/coverage-report-with-models/Exceptions/ChannelException.php.html b/backend/coverage-report-with-models/Exceptions/ChannelException.php.html deleted file mode 100644 index 8fdcd9a1..00000000 --- a/backend/coverage-report-with-models/Exceptions/ChannelException.php.html +++ /dev/null @@ -1,109 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Exceptions/ChannelException.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
n/a
0 / 0
n/a
0 / 0
CRAP
n/a
0 / 0
ChannelException
n/a
0 / 0
n/a
0 / 0
0
n/a
0 / 0
-
- - - - - - - - - - - - - -
1<?php
2
3namespace App\Exceptions;
4
5use Exception;
6
7class ChannelException extends Exception
8{
9}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:52:46 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-with-models/Exceptions/PlatformAuthException.php.html b/backend/coverage-report-with-models/Exceptions/PlatformAuthException.php.html deleted file mode 100644 index a9d0b38a..00000000 --- a/backend/coverage-report-with-models/Exceptions/PlatformAuthException.php.html +++ /dev/null @@ -1,197 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Exceptions/PlatformAuthException.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
PlatformAuthException
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
6
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 __construct
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 getPlatform
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Exceptions;
4
5use App\Enums\PlatformEnum;
6use Exception;
7
8class PlatformAuthException extends Exception
9{
10    public function __construct(
11        private readonly PlatformEnum $platform,
12        string $reason = 'Authentication failed'
13    ) {
14        $message = "Failed to authenticate with {$platform->value}: {$reason}";
15
16        parent::__construct($message);
17    }
18
19    public function getPlatform(): PlatformEnum
20    {
21        return $this->platform;
22    }
23}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:52:46 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-with-models/Exceptions/PublishException.php.html b/backend/coverage-report-with-models/Exceptions/PublishException.php.html deleted file mode 100644 index 7772473e..00000000 --- a/backend/coverage-report-with-models/Exceptions/PublishException.php.html +++ /dev/null @@ -1,235 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Exceptions/PublishException.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 8
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
PublishException
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 8
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
30
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 __construct
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 6
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
12
 getArticle
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 getPlatform
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Exceptions;
4
5use App\Enums\PlatformEnum;
6use App\Models\Article;
7use Exception;
8use Throwable;
9
10class PublishException extends Exception
11{
12    public function __construct(
13        private readonly Article $article,
14        private readonly PlatformEnum|null $platform,
15        ?Throwable $previous = null
16    ) {
17        $message = "Failed to publish article #$article->id";
18
19        if ($this->platform) {
20            $message .= "  to $platform->value";
21        }
22
23        if ($previous) {
24            $message .= ": {$previous->getMessage()}";
25        }
26
27        parent::__construct($message, 0, $previous);
28    }
29
30    public function getArticle(): Article
31    {
32        return $this->article;
33    }
34
35    public function getPlatform(): ?PlatformEnum
36    {
37        return $this->platform;
38    }
39}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:52:46 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-with-models/Exceptions/RoutingException.php.html b/backend/coverage-report-with-models/Exceptions/RoutingException.php.html deleted file mode 100644 index 1a041d87..00000000 --- a/backend/coverage-report-with-models/Exceptions/RoutingException.php.html +++ /dev/null @@ -1,109 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Exceptions/RoutingException.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
n/a
0 / 0
n/a
0 / 0
CRAP
n/a
0 / 0
RoutingException
n/a
0 / 0
n/a
0 / 0
0
n/a
0 / 0
-
- - - - - - - - - - - - - -
1<?php
2
3namespace App\Exceptions;
4
5use Exception;
6
7class RoutingException extends Exception
8{
9}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:52:46 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-with-models/Exceptions/RoutingMismatchException.php.html b/backend/coverage-report-with-models/Exceptions/RoutingMismatchException.php.html deleted file mode 100644 index 3a5c2ec6..00000000 --- a/backend/coverage-report-with-models/Exceptions/RoutingMismatchException.php.html +++ /dev/null @@ -1,174 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Exceptions/RoutingMismatchException.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 8
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
RoutingMismatchException
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 8
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 __construct
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 8
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Exceptions;
4
5use App\Models\Feed;
6use App\Models\PlatformChannel;
7
8class RoutingMismatchException extends RoutingException
9{
10    public function __construct(Feed $feed, PlatformChannel $channel)
11    {
12        $message = sprintf(
13            "Language mismatch: Feed '%s' is in '%s' but channel '%s' is set to '%s'. Feed and channel languages must match for proper content routing.",
14            $feed->name,
15            $feed->language,
16            $channel->name,
17            $channel->language
18        );
19
20        parent::__construct($message);
21    }
22}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:52:46 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-with-models/Exceptions/dashboard.html b/backend/coverage-report-with-models/Exceptions/dashboard.html deleted file mode 100644 index f120196b..00000000 --- a/backend/coverage-report-with-models/Exceptions/dashboard.html +++ /dev/null @@ -1,295 +0,0 @@ - - - - - Dashboard for /var/www/html/backend/app/Exceptions - - - - - - - -
-
-
-
- -
-
-
-
-
-
-
-

Classes

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
-
-
-

Insufficient Coverage

- -
-
-

Project Risks

-
- - - - - - - - - - - -
ClassCRAP
App\Exceptions\PublishException30
-
-
-
-
-
-

Methods

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
-
-
-

Insufficient Coverage

-
- - - - - - - - - - - - - - - - -
MethodCoverage
__construct0%
getPlatform0%
__construct0%
getArticle0%
getPlatform0%
__construct0%
-
-
-
-

Project Risks

-
- - - - - - - - - - - -
MethodCRAP
__construct12
-
-
-
- -
- - - - - - diff --git a/backend/coverage-report-with-models/Exceptions/index.html b/backend/coverage-report-with-models/Exceptions/index.html deleted file mode 100644 index 37b59302..00000000 --- a/backend/coverage-report-with-models/Exceptions/index.html +++ /dev/null @@ -1,201 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Exceptions - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 19
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 6
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
ChannelException.php
n/a
0 / 0
n/a
0 / 0
n/a
0 / 0
PlatformAuthException.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
PublishException.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 8
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
RoutingException.php
n/a
0 / 0
n/a
0 / 0
n/a
0 / 0
RoutingMismatchException.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 8
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- -
- - diff --git a/backend/coverage-report-with-models/Http/Controllers/Api/V1/ArticlesController.php.html b/backend/coverage-report-with-models/Http/Controllers/Api/V1/ArticlesController.php.html deleted file mode 100644 index 140697df..00000000 --- a/backend/coverage-report-with-models/Http/Controllers/Api/V1/ArticlesController.php.html +++ /dev/null @@ -1,273 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Http/Controllers/Api/V1/ArticlesController.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 87.88% covered (warning) -
-
-
87.88%
29 / 33
-
- 33.33% covered (danger) -
-
-
33.33%
1 / 3
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
ArticlesController
-
- 87.88% covered (warning) -
-
-
87.88%
29 / 33
-
- 33.33% covered (danger) -
-
-
33.33%
1 / 3
5.04
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 index
-
- 100.00% covered (success) -
-
-
100.00%
19 / 19
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
1
 approve
-
- 71.43% covered (warning) -
-
-
71.43%
5 / 7
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2.09
 reject
-
- 71.43% covered (warning) -
-
-
71.43%
5 / 7
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2.09
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Http\Controllers\Api\V1;
4
5use App\Http\Resources\ArticleResource;
6use App\Models\Article;
7use App\Models\Setting;
8use Illuminate\Http\JsonResponse;
9use Illuminate\Http\Request;
10
11class ArticlesController extends BaseController
12{
13    /**
14     * Display a listing of articles
15     */
16    public function index(Request $request): JsonResponse
17    {
18        $perPage = min($request->get('per_page', 15), 100); // Max 100 items per page
19        $articles = Article::with(['feed', 'articlePublication'])
20            ->orderBy('created_at', 'desc')
21            ->paginate($perPage);
22
23        $publishingApprovalsEnabled = Setting::isPublishingApprovalsEnabled();
24
25        return $this->sendResponse([
26            'articles' => ArticleResource::collection($articles->items()),
27            'pagination' => [
28                'current_page' => $articles->currentPage(),
29                'last_page' => $articles->lastPage(),
30                'per_page' => $articles->perPage(),
31                'total' => $articles->total(),
32                'from' => $articles->firstItem(),
33                'to' => $articles->lastItem(),
34            ],
35            'settings' => [
36                'publishing_approvals_enabled' => $publishingApprovalsEnabled,
37            ],
38        ]);
39    }
40
41    /**
42     * Approve an article
43     */
44    public function approve(Article $article): JsonResponse
45    {
46        try {
47            $article->approve('manual');
48            
49            return $this->sendResponse(
50                new ArticleResource($article->fresh(['feed', 'articlePublication'])),
51                'Article approved and queued for publishing.'
52            );
53        } catch (\Exception $e) {
54            return $this->sendError('Failed to approve article: ' . $e->getMessage(), [], 500);
55        }
56    }
57
58    /**
59     * Reject an article
60     */
61    public function reject(Article $article): JsonResponse
62    {
63        try {
64            $article->reject('manual');
65            
66            return $this->sendResponse(
67                new ArticleResource($article->fresh(['feed', 'articlePublication'])),
68                'Article rejected.'
69            );
70        } catch (\Exception $e) {
71            return $this->sendError('Failed to reject article: ' . $e->getMessage(), [], 500);
72        }
73    }
74}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:52:46 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-with-models/Http/Controllers/Api/V1/AuthController.php.html b/backend/coverage-report-with-models/Http/Controllers/Api/V1/AuthController.php.html deleted file mode 100644 index 0d09b5b6..00000000 --- a/backend/coverage-report-with-models/Http/Controllers/Api/V1/AuthController.php.html +++ /dev/null @@ -1,333 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Http/Controllers/Api/V1/AuthController.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 56
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 4
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
AuthController
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 56
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 4
132
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 login
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 21
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
30
 register
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 24
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
12
 logout
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 4
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
6
 me
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 7
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Http\Controllers\Api\V1;
4
5use App\Models\User;
6use Illuminate\Http\JsonResponse;
7use Illuminate\Http\Request;
8use Illuminate\Support\Facades\Auth;
9use Illuminate\Support\Facades\Hash;
10use Illuminate\Validation\ValidationException;
11
12class AuthController extends BaseController
13{
14    /**
15     * Login user and create token
16     */
17    public function login(Request $request): JsonResponse
18    {
19        try {
20            $request->validate([
21                'email' => 'required|email',
22                'password' => 'required',
23            ]);
24
25            $user = User::where('email', $request->email)->first();
26
27            if (!$user || !Hash::check($request->password, $user->password)) {
28                return $this->sendError('Invalid credentials', [], 401);
29            }
30
31            $token = $user->createToken('api-token')->plainTextToken;
32
33            return $this->sendResponse([
34                'user' => [
35                    'id' => $user->id,
36                    'name' => $user->name,
37                    'email' => $user->email,
38                ],
39                'token' => $token,
40                'token_type' => 'Bearer',
41            ], 'Login successful');
42        } catch (ValidationException $e) {
43            return $this->sendValidationError($e->errors());
44        } catch (\Exception $e) {
45            return $this->sendError('Login failed: ' . $e->getMessage(), [], 500);
46        }
47    }
48
49    /**
50     * Register a new user
51     */
52    public function register(Request $request): JsonResponse
53    {
54        try {
55            $validated = $request->validate([
56                'name' => 'required|string|max:255',
57                'email' => 'required|string|email|max:255|unique:users',
58                'password' => 'required|string|min:8|confirmed',
59            ]);
60
61            $user = User::create([
62                'name' => $validated['name'],
63                'email' => $validated['email'],
64                'password' => Hash::make($validated['password']),
65            ]);
66
67            $token = $user->createToken('api-token')->plainTextToken;
68
69            return $this->sendResponse([
70                'user' => [
71                    'id' => $user->id,
72                    'name' => $user->name,
73                    'email' => $user->email,
74                ],
75                'token' => $token,
76                'token_type' => 'Bearer',
77            ], 'Registration successful', 201);
78        } catch (ValidationException $e) {
79            return $this->sendValidationError($e->errors());
80        } catch (\Exception $e) {
81            return $this->sendError('Registration failed: ' . $e->getMessage(), [], 500);
82        }
83    }
84
85    /**
86     * Logout user (revoke token)
87     */
88    public function logout(Request $request): JsonResponse
89    {
90        try {
91            $request->user()->currentAccessToken()->delete();
92
93            return $this->sendResponse(null, 'Logged out successfully');
94        } catch (\Exception $e) {
95            return $this->sendError('Logout failed: ' . $e->getMessage(), [], 500);
96        }
97    }
98
99    /**
100     * Get current authenticated user
101     */
102    public function me(Request $request): JsonResponse
103    {
104        return $this->sendResponse([
105            'user' => [
106                'id' => $request->user()->id,
107                'name' => $request->user()->name,
108                'email' => $request->user()->email,
109            ],
110        ], 'User retrieved successfully');
111    }
112}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:52:46 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-with-models/Http/Controllers/Api/V1/BaseController.php.html b/backend/coverage-report-with-models/Http/Controllers/Api/V1/BaseController.php.html deleted file mode 100644 index 93a424c7..00000000 --- a/backend/coverage-report-with-models/Http/Controllers/Api/V1/BaseController.php.html +++ /dev/null @@ -1,307 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Http/Controllers/Api/V1/BaseController.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 87.50% covered (warning) -
-
-
87.50%
14 / 16
-
- 60.00% covered (warning) -
-
-
60.00%
3 / 5
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
BaseController
-
- 87.50% covered (warning) -
-
-
87.50%
14 / 16
-
- 60.00% covered (warning) -
-
-
60.00%
3 / 5
6.07
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 sendResponse
-
- 100.00% covered (success) -
-
-
100.00%
6 / 6
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
1
 sendError
-
- 100.00% covered (success) -
-
-
100.00%
7 / 7
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
2
 sendValidationError
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
1
 sendNotFound
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 sendUnauthorized
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Http\Controllers\Api\V1;
4
5use App\Http\Controllers\Controller;
6use Illuminate\Http\JsonResponse;
7
8class BaseController extends Controller
9{
10    /**
11     * Success response method
12     */
13    public function sendResponse(mixed $result, string $message = 'Success', int $code = 200): JsonResponse
14    {
15        $response = [
16            'success' => true,
17            'data' => $result,
18            'message' => $message,
19        ];
20
21        return response()->json($response, $code);
22    }
23
24    /**
25     * Error response method
26     */
27    public function sendError(string $error, array $errorMessages = [], int $code = 400): JsonResponse
28    {
29        $response = [
30            'success' => false,
31            'message' => $error,
32        ];
33
34        if (!empty($errorMessages)) {
35            $response['errors'] = $errorMessages;
36        }
37
38        return response()->json($response, $code);
39    }
40
41    /**
42     * Validation error response method
43     */
44    public function sendValidationError(array $errors): JsonResponse
45    {
46        return $this->sendError('Validation failed', $errors, 422);
47    }
48
49    /**
50     * Not found response method
51     */
52    public function sendNotFound(string $message = 'Resource not found'): JsonResponse
53    {
54        return $this->sendError($message, [], 404);
55    }
56
57    /**
58     * Unauthorized response method
59     */
60    public function sendUnauthorized(string $message = 'Unauthorized'): JsonResponse
61    {
62        return $this->sendError($message, [], 401);
63    }
64}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:52:46 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-with-models/Http/Controllers/Api/V1/DashboardController.php.html b/backend/coverage-report-with-models/Http/Controllers/Api/V1/DashboardController.php.html deleted file mode 100644 index 570a6bd8..00000000 --- a/backend/coverage-report-with-models/Http/Controllers/Api/V1/DashboardController.php.html +++ /dev/null @@ -1,223 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Http/Controllers/Api/V1/DashboardController.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 84.62% covered (warning) -
-
-
84.62%
11 / 13
-
- 50.00% covered (danger) -
-
-
50.00%
1 / 2
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
DashboardController
-
- 84.62% covered (warning) -
-
-
84.62%
11 / 13
-
- 50.00% covered (danger) -
-
-
50.00%
1 / 2
3.03
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 __construct
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
1
 stats
-
- 83.33% covered (warning) -
-
-
83.33%
10 / 12
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2.02
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Http\Controllers\Api\V1;
4
5use App\Models\Article;
6use App\Models\Feed;
7use App\Models\PlatformAccount;
8use App\Models\PlatformChannel;
9use App\Services\DashboardStatsService;
10use Illuminate\Http\JsonResponse;
11use Illuminate\Http\Request;
12
13class DashboardController extends BaseController
14{
15    public function __construct(
16        private DashboardStatsService $dashboardStatsService
17    ) {}
18
19    /**
20     * Get dashboard statistics
21     */
22    public function stats(Request $request): JsonResponse
23    {
24        $period = $request->get('period', 'today');
25        
26        try {
27            // Get article stats from service
28            $articleStats = $this->dashboardStatsService->getStats($period);
29            
30            // Get system stats
31            $systemStats = $this->dashboardStatsService->getSystemStats();
32            
33            // Get available periods
34            $availablePeriods = $this->dashboardStatsService->getAvailablePeriods();
35            
36            return $this->sendResponse([
37                'article_stats' => $articleStats,
38                'system_stats' => $systemStats,
39                'available_periods' => $availablePeriods,
40                'current_period' => $period,
41            ]);
42        } catch (\Exception $e) {
43            return $this->sendError('Failed to fetch dashboard stats: ' . $e->getMessage(), [], 500);
44        }
45    }
46}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:52:46 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-with-models/Http/Controllers/Api/V1/FeedsController.php.html b/backend/coverage-report-with-models/Http/Controllers/Api/V1/FeedsController.php.html deleted file mode 100644 index 2e97b365..00000000 --- a/backend/coverage-report-with-models/Http/Controllers/Api/V1/FeedsController.php.html +++ /dev/null @@ -1,387 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Http/Controllers/Api/V1/FeedsController.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 76.00% covered (warning) -
-
-
76.00%
38 / 50
-
- 33.33% covered (danger) -
-
-
33.33%
2 / 6
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
FeedsController
-
- 76.00% covered (warning) -
-
-
76.00%
38 / 50
-
- 33.33% covered (danger) -
-
-
33.33%
2 / 6
15.34
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 index
-
- 100.00% covered (success) -
-
-
100.00%
7 / 7
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
1
 store
-
- 66.67% covered (warning) -
-
-
66.67%
8 / 12
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
3.33
 show
-
- 100.00% covered (success) -
-
-
100.00%
4 / 4
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
1
 update
-
- 63.64% covered (warning) -
-
-
63.64%
7 / 11
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
3.43
 destroy
-
- 71.43% covered (warning) -
-
-
71.43%
5 / 7
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2.09
 toggle
-
- 77.78% covered (warning) -
-
-
77.78%
7 / 9
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
3.10
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Http\Controllers\Api\V1;
4
5use App\Http\Requests\StoreFeedRequest;
6use App\Http\Requests\UpdateFeedRequest;
7use App\Http\Resources\FeedResource;
8use App\Models\Feed;
9use Illuminate\Http\JsonResponse;
10use Illuminate\Http\Request;
11use Illuminate\Validation\ValidationException;
12
13class FeedsController extends BaseController
14{
15    /**
16     * Display a listing of feeds
17     */
18    public function index(Request $request): JsonResponse
19    {
20        $feeds = Feed::orderBy('is_active', 'desc')
21            ->orderBy('name')
22            ->get();
23
24        return $this->sendResponse(
25            FeedResource::collection($feeds),
26            'Feeds retrieved successfully.'
27        );
28    }
29
30    /**
31     * Store a newly created feed
32     */
33    public function store(StoreFeedRequest $request): JsonResponse
34    {
35        try {
36            $validated = $request->validated();
37            $validated['is_active'] = $validated['is_active'] ?? true;
38
39            $feed = Feed::create($validated);
40
41            return $this->sendResponse(
42                new FeedResource($feed),
43                'Feed created successfully!',
44                201
45            );
46        } catch (ValidationException $e) {
47            return $this->sendValidationError($e->errors());
48        } catch (\Exception $e) {
49            return $this->sendError('Failed to create feed: ' . $e->getMessage(), [], 500);
50        }
51    }
52
53    /**
54     * Display the specified feed
55     */
56    public function show(Feed $feed): JsonResponse
57    {
58        return $this->sendResponse(
59            new FeedResource($feed),
60            'Feed retrieved successfully.'
61        );
62    }
63
64    /**
65     * Update the specified feed
66     */
67    public function update(UpdateFeedRequest $request, Feed $feed): JsonResponse
68    {
69        try {
70            $validated = $request->validated();
71            $validated['is_active'] = $validated['is_active'] ?? $feed->is_active;
72
73            $feed->update($validated);
74
75            return $this->sendResponse(
76                new FeedResource($feed->fresh()),
77                'Feed updated successfully!'
78            );
79        } catch (ValidationException $e) {
80            return $this->sendValidationError($e->errors());
81        } catch (\Exception $e) {
82            return $this->sendError('Failed to update feed: ' . $e->getMessage(), [], 500);
83        }
84    }
85
86    /**
87     * Remove the specified feed
88     */
89    public function destroy(Feed $feed): JsonResponse
90    {
91        try {
92            $feed->delete();
93
94            return $this->sendResponse(
95                null,
96                'Feed deleted successfully!'
97            );
98        } catch (\Exception $e) {
99            return $this->sendError('Failed to delete feed: ' . $e->getMessage(), [], 500);
100        }
101    }
102
103    /**
104     * Toggle feed active status
105     */
106    public function toggle(Feed $feed): JsonResponse
107    {
108        try {
109            $newStatus = !$feed->is_active;
110            $feed->update(['is_active' => $newStatus]);
111
112            $status = $newStatus ? 'activated' : 'deactivated';
113
114            return $this->sendResponse(
115                new FeedResource($feed->fresh()),
116                "Feed {$status} successfully!"
117            );
118        } catch (\Exception $e) {
119            return $this->sendError('Failed to toggle feed status: ' . $e->getMessage(), [], 500);
120        }
121    }
122}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:52:46 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-with-models/Http/Controllers/Api/V1/LogsController.php.html b/backend/coverage-report-with-models/Http/Controllers/Api/V1/LogsController.php.html deleted file mode 100644 index eb352f22..00000000 --- a/backend/coverage-report-with-models/Http/Controllers/Api/V1/LogsController.php.html +++ /dev/null @@ -1,198 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Http/Controllers/Api/V1/LogsController.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 19
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
LogsController
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 19
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
12
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 index
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 19
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
12
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Http\Controllers\Api\V1;
4
5use App\Models\Log;
6use Illuminate\Http\JsonResponse;
7use Illuminate\Http\Request;
8
9class LogsController extends BaseController
10{
11    /**
12     * Display a listing of logs
13     */
14    public function index(Request $request): JsonResponse
15    {
16        try {
17            $perPage = min($request->get('per_page', 20), 100);
18            $level = $request->get('level');
19            
20            $query = Log::orderBy('created_at', 'desc');
21            
22            if ($level) {
23                $query->where('level', $level);
24            }
25            
26            $logs = $query->paginate($perPage);
27
28            return $this->sendResponse([
29                'logs' => $logs->items(),
30                'pagination' => [
31                    'current_page' => $logs->currentPage(),
32                    'last_page' => $logs->lastPage(),
33                    'per_page' => $logs->perPage(),
34                    'total' => $logs->total(),
35                    'from' => $logs->firstItem(),
36                    'to' => $logs->lastItem(),
37                ],
38            ], 'Logs retrieved successfully.');
39        } catch (\Exception $e) {
40            return $this->sendError('Failed to retrieve logs: ' . $e->getMessage(), [], 500);
41        }
42    }
43}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:52:46 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-with-models/Http/Controllers/Api/V1/PlatformAccountsController.php.html b/backend/coverage-report-with-models/Http/Controllers/Api/V1/PlatformAccountsController.php.html deleted file mode 100644 index e2d6eb8a..00000000 --- a/backend/coverage-report-with-models/Http/Controllers/Api/V1/PlatformAccountsController.php.html +++ /dev/null @@ -1,417 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Http/Controllers/Api/V1/PlatformAccountsController.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 73
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 6
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
PlatformAccountsController
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 73
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 6
210
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 index
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 8
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 store
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 30
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
20
 show
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 4
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 update
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 17
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
20
 destroy
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 7
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
6
 setActive
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 7
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
6
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Http\Controllers\Api\V1;
4
5use App\Enums\PlatformEnum;
6use App\Http\Resources\PlatformAccountResource;
7use App\Models\PlatformAccount;
8use App\Models\PlatformInstance;
9use Illuminate\Http\JsonResponse;
10use Illuminate\Http\Request;
11use Illuminate\Validation\ValidationException;
12
13class PlatformAccountsController extends BaseController
14{
15    /**
16     * Display a listing of platform accounts
17     */
18    public function index(): JsonResponse
19    {
20        $accounts = PlatformAccount::with(['platformInstance'])
21            ->orderBy('platform')
22            ->orderBy('created_at', 'desc')
23            ->get();
24
25        return $this->sendResponse(
26            PlatformAccountResource::collection($accounts),
27            'Platform accounts retrieved successfully.'
28        );
29    }
30
31    /**
32     * Store a newly created platform account
33     */
34    public function store(Request $request): JsonResponse
35    {
36        try {
37            $validated = $request->validate([
38                'platform' => 'required|in:lemmy,mastodon,reddit',
39                'instance_url' => 'required|url',
40                'username' => 'required|string|max:255',
41                'password' => 'required|string',
42                'settings' => 'nullable|array',
43            ]);
44
45            // Create or find platform instance
46            $platformEnum = PlatformEnum::from($validated['platform']);
47            $instance = PlatformInstance::firstOrCreate([
48                'platform' => $platformEnum,
49                'url' => $validated['instance_url'],
50            ], [
51                'name' => parse_url($validated['instance_url'], PHP_URL_HOST),
52                'description' => ucfirst($validated['platform']) . ' instance',
53                'is_active' => true,
54            ]);
55
56            $account = PlatformAccount::create($validated);
57
58            // If this is the first account for this platform, make it active
59            if (!PlatformAccount::where('platform', $validated['platform'])
60                ->where('is_active', true)
61                ->exists()) {
62                $account->setAsActive();
63            }
64
65            return $this->sendResponse(
66                new PlatformAccountResource($account->load('platformInstance')),
67                'Platform account created successfully!',
68                201
69            );
70        } catch (ValidationException $e) {
71            return $this->sendValidationError($e->errors());
72        } catch (\Exception $e) {
73            return $this->sendError('Failed to create platform account: ' . $e->getMessage(), [], 500);
74        }
75    }
76
77    /**
78     * Display the specified platform account
79     */
80    public function show(PlatformAccount $platformAccount): JsonResponse
81    {
82        return $this->sendResponse(
83            new PlatformAccountResource($platformAccount->load('platformInstance')),
84            'Platform account retrieved successfully.'
85        );
86    }
87
88    /**
89     * Update the specified platform account
90     */
91    public function update(Request $request, PlatformAccount $platformAccount): JsonResponse
92    {
93        try {
94            $validated = $request->validate([
95                'instance_url' => 'required|url',
96                'username' => 'required|string|max:255',
97                'password' => 'nullable|string',
98                'settings' => 'nullable|array',
99            ]);
100
101            // Don't update password if not provided
102            if (empty($validated['password'])) {
103                unset($validated['password']);
104            }
105
106            $platformAccount->update($validated);
107
108            return $this->sendResponse(
109                new PlatformAccountResource($platformAccount->fresh(['platformInstance'])),
110                'Platform account updated successfully!'
111            );
112        } catch (ValidationException $e) {
113            return $this->sendValidationError($e->errors());
114        } catch (\Exception $e) {
115            return $this->sendError('Failed to update platform account: ' . $e->getMessage(), [], 500);
116        }
117    }
118
119    /**
120     * Remove the specified platform account
121     */
122    public function destroy(PlatformAccount $platformAccount): JsonResponse
123    {
124        try {
125            $platformAccount->delete();
126
127            return $this->sendResponse(
128                null,
129                'Platform account deleted successfully!'
130            );
131        } catch (\Exception $e) {
132            return $this->sendError('Failed to delete platform account: ' . $e->getMessage(), [], 500);
133        }
134    }
135
136    /**
137     * Set platform account as active
138     */
139    public function setActive(PlatformAccount $platformAccount): JsonResponse
140    {
141        try {
142            $platformAccount->setAsActive();
143
144            return $this->sendResponse(
145                new PlatformAccountResource($platformAccount->fresh(['platformInstance'])),
146                "Set {$platformAccount->username}@{$platformAccount->instance_url} as active for {$platformAccount->platform->value}!"
147            );
148        } catch (\Exception $e) {
149            return $this->sendError('Failed to set platform account as active: ' . $e->getMessage(), [], 500);
150        }
151    }
152}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:52:46 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-with-models/Http/Controllers/Api/V1/PlatformChannelsController.php.html b/backend/coverage-report-with-models/Http/Controllers/Api/V1/PlatformChannelsController.php.html deleted file mode 100644 index fc65e054..00000000 --- a/backend/coverage-report-with-models/Http/Controllers/Api/V1/PlatformChannelsController.php.html +++ /dev/null @@ -1,398 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Http/Controllers/Api/V1/PlatformChannelsController.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 62
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 6
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
PlatformChannelsController
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 62
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 6
182
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 index
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 8
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 store
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 19
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
12
 show
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 4
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 update
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 15
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
12
 destroy
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 7
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
6
 toggle
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 9
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
12
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Http\Controllers\Api\V1;
4
5use App\Http\Resources\PlatformChannelResource;
6use App\Models\PlatformChannel;
7use Illuminate\Http\JsonResponse;
8use Illuminate\Http\Request;
9use Illuminate\Validation\ValidationException;
10
11class PlatformChannelsController extends BaseController
12{
13    /**
14     * Display a listing of platform channels
15     */
16    public function index(): JsonResponse
17    {
18        $channels = PlatformChannel::with(['platformInstance'])
19            ->orderBy('is_active', 'desc')
20            ->orderBy('name')
21            ->get();
22
23        return $this->sendResponse(
24            PlatformChannelResource::collection($channels),
25            'Platform channels retrieved successfully.'
26        );
27    }
28
29    /**
30     * Store a newly created platform channel
31     */
32    public function store(Request $request): JsonResponse
33    {
34        try {
35            $validated = $request->validate([
36                'platform_instance_id' => 'required|exists:platform_instances,id',
37                'channel_id' => 'required|string|max:255',
38                'name' => 'required|string|max:255',
39                'display_name' => 'nullable|string|max:255',
40                'description' => 'nullable|string',
41                'is_active' => 'boolean',
42            ]);
43
44            $validated['is_active'] = $validated['is_active'] ?? true;
45
46            $channel = PlatformChannel::create($validated);
47
48            return $this->sendResponse(
49                new PlatformChannelResource($channel->load('platformInstance')),
50                'Platform channel created successfully!',
51                201
52            );
53        } catch (ValidationException $e) {
54            return $this->sendValidationError($e->errors());
55        } catch (\Exception $e) {
56            return $this->sendError('Failed to create platform channel: ' . $e->getMessage(), [], 500);
57        }
58    }
59
60    /**
61     * Display the specified platform channel
62     */
63    public function show(PlatformChannel $channel): JsonResponse
64    {
65        return $this->sendResponse(
66            new PlatformChannelResource($channel->load('platformInstance')),
67            'Platform channel retrieved successfully.'
68        );
69    }
70
71    /**
72     * Update the specified platform channel
73     */
74    public function update(Request $request, PlatformChannel $channel): JsonResponse
75    {
76        try {
77            $validated = $request->validate([
78                'name' => 'required|string|max:255',
79                'display_name' => 'nullable|string|max:255',
80                'description' => 'nullable|string',
81                'is_active' => 'boolean',
82            ]);
83
84            $channel->update($validated);
85
86            return $this->sendResponse(
87                new PlatformChannelResource($channel->fresh(['platformInstance'])),
88                'Platform channel updated successfully!'
89            );
90        } catch (ValidationException $e) {
91            return $this->sendValidationError($e->errors());
92        } catch (\Exception $e) {
93            return $this->sendError('Failed to update platform channel: ' . $e->getMessage(), [], 500);
94        }
95    }
96
97    /**
98     * Remove the specified platform channel
99     */
100    public function destroy(PlatformChannel $channel): JsonResponse
101    {
102        try {
103            $channel->delete();
104
105            return $this->sendResponse(
106                null,
107                'Platform channel deleted successfully!'
108            );
109        } catch (\Exception $e) {
110            return $this->sendError('Failed to delete platform channel: ' . $e->getMessage(), [], 500);
111        }
112    }
113
114    /**
115     * Toggle platform channel active status
116     */
117    public function toggle(PlatformChannel $channel): JsonResponse
118    {
119        try {
120            $newStatus = !$channel->is_active;
121            $channel->update(['is_active' => $newStatus]);
122
123            $status = $newStatus ? 'activated' : 'deactivated';
124
125            return $this->sendResponse(
126                new PlatformChannelResource($channel->fresh(['platformInstance'])),
127                "Platform channel {$status} successfully!"
128            );
129        } catch (\Exception $e) {
130            return $this->sendError('Failed to toggle platform channel status: ' . $e->getMessage(), [], 500);
131        }
132    }
133}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:52:46 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-with-models/Http/Controllers/Api/V1/RoutingController.php.html b/backend/coverage-report-with-models/Http/Controllers/Api/V1/RoutingController.php.html deleted file mode 100644 index 9b5a8dcb..00000000 --- a/backend/coverage-report-with-models/Http/Controllers/Api/V1/RoutingController.php.html +++ /dev/null @@ -1,430 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Http/Controllers/Api/V1/RoutingController.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 80
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 6
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
RoutingController
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 80
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 6
306
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 index
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 8
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 store
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 18
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
12
 show
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 10
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
6
 update
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 18
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
20
 destroy
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 12
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
12
 toggle
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 14
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
20
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Http\Controllers\Api\V1;
4
5use App\Http\Resources\RouteResource;
6use App\Models\Feed;
7use App\Models\PlatformChannel;
8use App\Models\Route;
9use Illuminate\Http\JsonResponse;
10use Illuminate\Http\Request;
11use Illuminate\Validation\ValidationException;
12
13class RoutingController extends BaseController
14{
15    /**
16     * Display a listing of routing configurations
17     */
18    public function index(): JsonResponse
19    {
20        $routes = Route::with(['feed', 'platformChannel'])
21            ->orderBy('is_active', 'desc')
22            ->orderBy('priority', 'asc')
23            ->get();
24
25        return $this->sendResponse(
26            RouteResource::collection($routes),
27            'Routing configurations retrieved successfully.'
28        );
29    }
30
31    /**
32     * Store a newly created routing configuration
33     */
34    public function store(Request $request): JsonResponse
35    {
36        try {
37            $validated = $request->validate([
38                'feed_id' => 'required|exists:feeds,id',
39                'platform_channel_id' => 'required|exists:platform_channels,id',
40                'is_active' => 'boolean',
41                'priority' => 'nullable|integer|min:0',
42            ]);
43
44            $validated['is_active'] = $validated['is_active'] ?? true;
45            $validated['priority'] = $validated['priority'] ?? 0;
46
47            $route = Route::create($validated);
48
49            return $this->sendResponse(
50                new RouteResource($route->load(['feed', 'platformChannel'])),
51                'Routing configuration created successfully!',
52                201
53            );
54        } catch (ValidationException $e) {
55            return $this->sendValidationError($e->errors());
56        } catch (\Exception $e) {
57            return $this->sendError('Failed to create routing configuration: ' . $e->getMessage(), [], 500);
58        }
59    }
60
61    /**
62     * Display the specified routing configuration
63     */
64    public function show(Feed $feed, PlatformChannel $channel): JsonResponse
65    {
66        $route = Route::where('feed_id', $feed->id)
67            ->where('platform_channel_id', $channel->id)
68            ->with(['feed', 'platformChannel'])
69            ->first();
70
71        if (!$route) {
72            return $this->sendNotFound('Routing configuration not found.');
73        }
74
75        return $this->sendResponse(
76            new RouteResource($route),
77            'Routing configuration retrieved successfully.'
78        );
79    }
80
81    /**
82     * Update the specified routing configuration
83     */
84    public function update(Request $request, Feed $feed, PlatformChannel $channel): JsonResponse
85    {
86        try {
87            $route = Route::where('feed_id', $feed->id)
88                ->where('platform_channel_id', $channel->id)
89                ->first();
90
91            if (!$route) {
92                return $this->sendNotFound('Routing configuration not found.');
93            }
94
95            $validated = $request->validate([
96                'is_active' => 'boolean',
97                'priority' => 'nullable|integer|min:0',
98            ]);
99
100            $route->update($validated);
101
102            return $this->sendResponse(
103                new RouteResource($route->fresh(['feed', 'platformChannel'])),
104                'Routing configuration updated successfully!'
105            );
106        } catch (ValidationException $e) {
107            return $this->sendValidationError($e->errors());
108        } catch (\Exception $e) {
109            return $this->sendError('Failed to update routing configuration: ' . $e->getMessage(), [], 500);
110        }
111    }
112
113    /**
114     * Remove the specified routing configuration
115     */
116    public function destroy(Feed $feed, PlatformChannel $channel): JsonResponse
117    {
118        try {
119            $route = Route::where('feed_id', $feed->id)
120                ->where('platform_channel_id', $channel->id)
121                ->first();
122
123            if (!$route) {
124                return $this->sendNotFound('Routing configuration not found.');
125            }
126
127            $route->delete();
128
129            return $this->sendResponse(
130                null,
131                'Routing configuration deleted successfully!'
132            );
133        } catch (\Exception $e) {
134            return $this->sendError('Failed to delete routing configuration: ' . $e->getMessage(), [], 500);
135        }
136    }
137
138    /**
139     * Toggle routing configuration active status
140     */
141    public function toggle(Feed $feed, PlatformChannel $channel): JsonResponse
142    {
143        try {
144            $route = Route::where('feed_id', $feed->id)
145                ->where('platform_channel_id', $channel->id)
146                ->first();
147
148            if (!$route) {
149                return $this->sendNotFound('Routing configuration not found.');
150            }
151
152            $newStatus = !$route->is_active;
153            $route->update(['is_active' => $newStatus]);
154
155            $status = $newStatus ? 'activated' : 'deactivated';
156
157            return $this->sendResponse(
158                new RouteResource($route->fresh(['feed', 'platformChannel'])),
159                "Routing configuration {$status} successfully!"
160            );
161        } catch (\Exception $e) {
162            return $this->sendError('Failed to toggle routing configuration status: ' . $e->getMessage(), [], 500);
163        }
164    }
165}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:52:46 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-with-models/Http/Controllers/Api/V1/SettingsController.php.html b/backend/coverage-report-with-models/Http/Controllers/Api/V1/SettingsController.php.html deleted file mode 100644 index df6a11ad..00000000 --- a/backend/coverage-report-with-models/Http/Controllers/Api/V1/SettingsController.php.html +++ /dev/null @@ -1,240 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Http/Controllers/Api/V1/SettingsController.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 85.19% covered (warning) -
-
-
85.19%
23 / 27
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
SettingsController
-
- 85.19% covered (warning) -
-
-
85.19%
23 / 27
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
7.16
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 index
-
- 71.43% covered (warning) -
-
-
71.43%
5 / 7
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2.09
 update
-
- 90.00% covered (success) -
-
-
90.00%
18 / 20
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
5.03
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Http\Controllers\Api\V1;
4
5use App\Models\Setting;
6use Illuminate\Http\JsonResponse;
7use Illuminate\Http\Request;
8use Illuminate\Validation\ValidationException;
9
10class SettingsController extends BaseController
11{
12    /**
13     * Display current settings
14     */
15    public function index(): JsonResponse
16    {
17        try {
18            $settings = [
19                'article_processing_enabled' => Setting::isArticleProcessingEnabled(),
20                'publishing_approvals_enabled' => Setting::isPublishingApprovalsEnabled(),
21            ];
22
23            return $this->sendResponse($settings, 'Settings retrieved successfully.');
24        } catch (\Exception $e) {
25            return $this->sendError('Failed to retrieve settings: ' . $e->getMessage(), [], 500);
26        }
27    }
28
29    /**
30     * Update settings
31     */
32    public function update(Request $request): JsonResponse
33    {
34        try {
35            $validated = $request->validate([
36                'article_processing_enabled' => 'boolean',
37                'enable_publishing_approvals' => 'boolean',
38            ]);
39
40            if (isset($validated['article_processing_enabled'])) {
41                Setting::setArticleProcessingEnabled($validated['article_processing_enabled']);
42            }
43
44            if (isset($validated['enable_publishing_approvals'])) {
45                Setting::setPublishingApprovalsEnabled($validated['enable_publishing_approvals']);
46            }
47
48            $updatedSettings = [
49                'article_processing_enabled' => Setting::isArticleProcessingEnabled(),
50                'publishing_approvals_enabled' => Setting::isPublishingApprovalsEnabled(),
51            ];
52
53            return $this->sendResponse(
54                $updatedSettings,
55                'Settings updated successfully.'
56            );
57        } catch (ValidationException $e) {
58            return $this->sendValidationError($e->errors());
59        } catch (\Exception $e) {
60            return $this->sendError('Failed to update settings: ' . $e->getMessage(), [], 500);
61        }
62    }
63}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:52:46 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-with-models/Http/Controllers/Api/V1/dashboard.html b/backend/coverage-report-with-models/Http/Controllers/Api/V1/dashboard.html deleted file mode 100644 index c0d27299..00000000 --- a/backend/coverage-report-with-models/Http/Controllers/Api/V1/dashboard.html +++ /dev/null @@ -1,365 +0,0 @@ - - - - - Dashboard for /var/www/html/backend/app/Http/Controllers/Api/V1 - - - - - - - -
-
-
-
- -
-
-
-
-
-
-
-

Classes

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
- -
-
-

Methods

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
-
-
-

Insufficient Coverage

-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
MethodCoverage
login0%
register0%
logout0%
me0%
sendNotFound0%
sendUnauthorized0%
index0%
index0%
store0%
show0%
update0%
destroy0%
setActive0%
index0%
store0%
show0%
update0%
destroy0%
toggle0%
index0%
store0%
show0%
update0%
destroy0%
toggle0%
update63%
store66%
approve71%
reject71%
destroy71%
index71%
toggle77%
stats83%
-
-
-
-

Project Risks

-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
MethodCRAP
login30
store20
update20
update20
toggle20
register12
index12
store12
update12
toggle12
store12
destroy12
logout6
destroy6
setActive6
destroy6
show6
update3
store3
toggle3
approve2
reject2
destroy2
index2
stats2
-
-
-
- -
- - - - - - diff --git a/backend/coverage-report-with-models/Http/Controllers/Api/V1/index.html b/backend/coverage-report-with-models/Http/Controllers/Api/V1/index.html deleted file mode 100644 index e356048d..00000000 --- a/backend/coverage-report-with-models/Http/Controllers/Api/V1/index.html +++ /dev/null @@ -1,374 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Http/Controllers/Api/V1 - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 26.81% covered (danger) -
-
-
26.81%
115 / 429
-
- 17.07% covered (danger) -
-
-
17.07%
7 / 41
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 10
ArticlesController.php
-
- 87.88% covered (warning) -
-
-
87.88%
29 / 33
-
- 33.33% covered (danger) -
-
-
33.33%
1 / 3
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
AuthController.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 56
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 4
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
BaseController.php
-
- 87.50% covered (warning) -
-
-
87.50%
14 / 16
-
- 60.00% covered (warning) -
-
-
60.00%
3 / 5
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
DashboardController.php
-
- 84.62% covered (warning) -
-
-
84.62%
11 / 13
-
- 50.00% covered (danger) -
-
-
50.00%
1 / 2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
FeedsController.php
-
- 76.00% covered (warning) -
-
-
76.00%
38 / 50
-
- 33.33% covered (danger) -
-
-
33.33%
2 / 6
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
LogsController.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 19
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
PlatformAccountsController.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 73
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 6
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
PlatformChannelsController.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 62
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 6
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
RoutingController.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 80
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 6
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
SettingsController.php
-
- 85.19% covered (warning) -
-
-
85.19%
23 / 27
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- -
- - diff --git a/backend/coverage-report-with-models/Http/Controllers/Api/dashboard.html b/backend/coverage-report-with-models/Http/Controllers/Api/dashboard.html deleted file mode 100644 index 1b75dc74..00000000 --- a/backend/coverage-report-with-models/Http/Controllers/Api/dashboard.html +++ /dev/null @@ -1,364 +0,0 @@ - - - - - Dashboard for /var/www/html/backend/app/Http/Controllers/Api - - - - - - - -
-
-
-
- -
-
-
-
-
-
-
-

Classes

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
- -
-
-

Methods

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
-
-
-

Insufficient Coverage

-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
MethodCoverage
login0%
register0%
logout0%
me0%
sendNotFound0%
sendUnauthorized0%
index0%
index0%
store0%
show0%
update0%
destroy0%
setActive0%
index0%
store0%
show0%
update0%
destroy0%
toggle0%
index0%
store0%
show0%
update0%
destroy0%
toggle0%
update63%
store66%
approve71%
reject71%
destroy71%
index71%
toggle77%
stats83%
-
-
-
-

Project Risks

-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
MethodCRAP
login30
store20
update20
update20
toggle20
register12
index12
store12
update12
toggle12
store12
destroy12
logout6
destroy6
setActive6
destroy6
show6
update3
store3
toggle3
approve2
reject2
destroy2
index2
stats2
-
-
-
- -
- - - - - - diff --git a/backend/coverage-report-with-models/Http/Controllers/Api/index.html b/backend/coverage-report-with-models/Http/Controllers/Api/index.html deleted file mode 100644 index adeffc3b..00000000 --- a/backend/coverage-report-with-models/Http/Controllers/Api/index.html +++ /dev/null @@ -1,121 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Http/Controllers/Api - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 26.81% covered (danger) -
-
-
26.81%
115 / 429
-
- 17.07% covered (danger) -
-
-
17.07%
7 / 41
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 10
V1
-
- 26.81% covered (danger) -
-
-
26.81%
115 / 429
-
- 17.07% covered (danger) -
-
-
17.07%
7 / 41
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 10
-
- -
- - diff --git a/backend/coverage-report-with-models/Http/Controllers/ArticlesController.php.html b/backend/coverage-report-with-models/Http/Controllers/ArticlesController.php.html deleted file mode 100644 index b88a9e73..00000000 --- a/backend/coverage-report-with-models/Http/Controllers/ArticlesController.php.html +++ /dev/null @@ -1,234 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Http/Controllers/ArticlesController.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 9
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
ArticlesController
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 9
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
12
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 __invoke
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 5
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 approve
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 reject
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Http\Controllers;
4
5use App\Models\Article;
6use App\Models\Setting;
7use Illuminate\Contracts\View\View;
8use Illuminate\Http\RedirectResponse;
9use Illuminate\Http\Request;
10
11class ArticlesController extends Controller
12{
13    public function __invoke(Request $request): View
14    {
15        $articles = Article::with('articlePublication')
16            ->orderBy('created_at', 'desc')
17            ->paginate(15);
18
19        $publishingApprovalsEnabled = Setting::isPublishingApprovalsEnabled();
20
21        return view('pages.articles.index', compact('articles', 'publishingApprovalsEnabled'));
22    }
23
24    public function approve(Article $article): RedirectResponse
25    {
26        $article->approve('manual');
27
28        return redirect()->back()->with('success', 'Article approved and queued for publishing.');
29    }
30
31    public function reject(Article $article): RedirectResponse
32    {
33        $article->reject('manual');
34
35        return redirect()->back()->with('success', 'Article rejected.');
36    }
37}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:52:46 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-with-models/Http/Controllers/Controller.php.html b/backend/coverage-report-with-models/Http/Controllers/Controller.php.html deleted file mode 100644 index cf4f8383..00000000 --- a/backend/coverage-report-with-models/Http/Controllers/Controller.php.html +++ /dev/null @@ -1,109 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Http/Controllers/Controller.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
n/a
0 / 0
n/a
0 / 0
CRAP
n/a
0 / 0
Controller
n/a
0 / 0
n/a
0 / 0
0
n/a
0 / 0
-
- - - - - - - - - - - - -
1<?php
2
3namespace App\Http\Controllers;
4
5abstract class Controller
6{
7    //
8}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:52:46 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-with-models/Http/Controllers/FeedsController.php.html b/backend/coverage-report-with-models/Http/Controllers/FeedsController.php.html deleted file mode 100644 index b5b05915..00000000 --- a/backend/coverage-report-with-models/Http/Controllers/FeedsController.php.html +++ /dev/null @@ -1,388 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Http/Controllers/FeedsController.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 28
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 8
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
FeedsController
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 28
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 8
90
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 index
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 4
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 create
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 store
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 8
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 show
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 edit
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 update
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 5
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 destroy
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 toggle
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 5
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
6
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Http\Controllers;
4
5use App\Models\Feed;
6use App\Http\Requests\StoreFeedRequest;
7use App\Http\Requests\UpdateFeedRequest;
8use App\Services\OnboardingRedirectService;
9use Illuminate\Contracts\View\View;
10use Illuminate\Http\RedirectResponse;
11
12class FeedsController extends Controller
13{
14    public function index(): View
15    {
16        $feeds = Feed::orderBy('is_active', 'desc')
17            ->orderBy('name')
18            ->get();
19
20        return view('pages.feeds.index', compact('feeds'));
21    }
22
23    public function create(): View
24    {
25        return view('pages.feeds.create');
26    }
27
28    public function store(StoreFeedRequest $request): RedirectResponse
29    {
30        $validated = $request->validated();
31        $validated['is_active'] = $validated['is_active'] ?? true;
32
33        Feed::create($validated);
34
35        return OnboardingRedirectService::handleRedirect(
36            $request,
37            'feeds.index',
38            'Feed created successfully!'
39        );
40    }
41
42    public function show(Feed $feed): View
43    {
44        return view('pages.feeds.show', compact('feed'));
45    }
46
47    public function edit(Feed $feed): View
48    {
49        return view('pages.feeds.edit', compact('feed'));
50    }
51
52    public function update(UpdateFeedRequest $request, Feed $feed): RedirectResponse
53    {
54        $validated = $request->validated();
55        $validated['is_active'] = $validated['is_active'] ?? $feed->is_active;
56
57        $feed->update($validated);
58
59        return redirect()->route('feeds.index')
60            ->with('success', 'Feed updated successfully!');
61    }
62
63    public function destroy(Feed $feed): RedirectResponse
64    {
65        $feed->delete();
66
67        return redirect()->route('feeds.index')
68            ->with('success', 'Feed deleted successfully!');
69    }
70
71    public function toggle(Feed $feed): RedirectResponse
72    {
73        $newStatus = !$feed->is_active;
74        $feed->update(['is_active' => $newStatus]);
75
76        $status = $newStatus ? 'activated' : 'deactivated';
77
78        return redirect()->route('feeds.index')
79            ->with('success', "Feed {$status} successfully!");
80    }
81}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:52:46 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-with-models/Http/Controllers/LogsController.php.html b/backend/coverage-report-with-models/Http/Controllers/LogsController.php.html deleted file mode 100644 index 1c2bd49e..00000000 --- a/backend/coverage-report-with-models/Http/Controllers/LogsController.php.html +++ /dev/null @@ -1,170 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Http/Controllers/LogsController.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
LogsController
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 __invoke
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Http\Controllers;
4
5use App\Models\Log;
6use Illuminate\Contracts\View\View;
7use Illuminate\Http\Request;
8
9class LogsController extends Controller
10{
11    public function __invoke(Request $request): View
12    {
13        $logs = Log::orderBy('created_at', 'desc')->paginate(50);
14
15        return view('pages.logs.index', compact('logs'));
16    }
17}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:52:46 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-with-models/Http/Controllers/OnboardingController.php.html b/backend/coverage-report-with-models/Http/Controllers/OnboardingController.php.html deleted file mode 100644 index 7df7375f..00000000 --- a/backend/coverage-report-with-models/Http/Controllers/OnboardingController.php.html +++ /dev/null @@ -1,443 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Http/Controllers/OnboardingController.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 40
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 9
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
OnboardingController
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 40
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 9
506
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 index
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 15
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
6
 platform
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
6
 feed
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 5
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
12
 channel
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 7
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
20
 complete
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 6
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
30
 needsOnboarding
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
12
 hasPlatformAccount
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 hasFeed
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 hasChannel
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Http\Controllers;
4
5use App\Models\Feed;
6use App\Models\PlatformAccount;
7use App\Models\PlatformChannel;
8use App\Models\PlatformInstance;
9use App\Services\SystemStatusService;
10use App\Services\DashboardStatsService;
11use Illuminate\Http\Request;
12use Illuminate\View\View;
13use Illuminate\Http\RedirectResponse;
14
15class OnboardingController extends Controller
16{
17    public function index(Request $request): View|RedirectResponse
18    {
19        // Check if user needs onboarding
20        if (!$this->needsOnboarding()) {
21            $systemStatus = resolve(SystemStatusService::class)->getSystemStatus();
22            $statsService = resolve(DashboardStatsService::class);
23            
24            $period = $request->get('period', 'today');
25            $stats = $statsService->getStats($period);
26            $systemStats = $statsService->getSystemStats();
27            $availablePeriods = $statsService->getAvailablePeriods();
28
29            return view('pages.dashboard', compact(
30                'systemStatus', 
31                'stats', 
32                'systemStats', 
33                'availablePeriods', 
34                'period'
35            ));
36        }
37
38        return view('onboarding.welcome');
39    }
40
41    public function platform(): View|RedirectResponse
42    {
43        if (!$this->needsOnboarding()) {
44            return redirect()->route('feeds.index');
45        }
46
47        return view('onboarding.platform');
48    }
49
50    public function feed(): View|RedirectResponse
51    {
52        if (!$this->needsOnboarding()) {
53            return redirect()->route('feeds.index');
54        }
55
56        if (!$this->hasPlatformAccount()) {
57            return redirect()->route('onboarding.platform');
58        }
59
60        return view('onboarding.feed');
61    }
62
63    public function channel(): View|RedirectResponse
64    {
65        if (!$this->needsOnboarding()) {
66            return redirect()->route('feeds.index');
67        }
68
69        if (!$this->hasPlatformAccount()) {
70            return redirect()->route('onboarding.platform');
71        }
72
73        if (!$this->hasFeed()) {
74            return redirect()->route('onboarding.feed');
75        }
76
77        return view('onboarding.channel');
78    }
79
80    public function complete(): View|RedirectResponse
81    {
82        if (!$this->needsOnboarding()) {
83            return redirect()->route('feeds.index');
84        }
85
86        if (!$this->hasPlatformAccount() || !$this->hasFeed() || !$this->hasChannel()) {
87            return redirect()->route('onboarding.index');
88        }
89
90        $systemStatus = resolve(SystemStatusService::class)->getSystemStatus();
91
92        return view('onboarding.complete', compact('systemStatus'));
93    }
94
95    private function needsOnboarding(): bool
96    {
97        return !$this->hasPlatformAccount() || !$this->hasFeed() || !$this->hasChannel();
98    }
99
100    private function hasPlatformAccount(): bool
101    {
102        return PlatformAccount::where('is_active', true)->exists();
103    }
104
105    private function hasFeed(): bool
106    {
107        return Feed::where('is_active', true)->exists();
108    }
109
110    private function hasChannel(): bool
111    {
112        return PlatformChannel::where('is_active', true)->exists();
113    }
114}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:52:46 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-with-models/Http/Controllers/PlatformAccountsController.php.html b/backend/coverage-report-with-models/Http/Controllers/PlatformAccountsController.php.html deleted file mode 100644 index 22d25bf3..00000000 --- a/backend/coverage-report-with-models/Http/Controllers/PlatformAccountsController.php.html +++ /dev/null @@ -1,391 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Http/Controllers/PlatformAccountsController.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 46
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 7
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
PlatformAccountsController
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 46
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 7
110
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 index
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 create
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 store
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 25
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
12
 edit
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 update
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 11
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
6
 destroy
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 setActive
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Http\Controllers;
4
5use App\Models\PlatformAccount;
6use App\Models\PlatformInstance;
7use App\Enums\PlatformEnum;
8use Illuminate\Http\Request;
9use Illuminate\Contracts\View\View;
10use Illuminate\Http\RedirectResponse;
11use Illuminate\Support\Facades\View as ViewFacade;
12
13class PlatformAccountsController extends Controller
14{
15    public function index(): View
16    {
17        $accounts = PlatformAccount::orderBy('platform')->orderBy('created_at', 'desc')->get();
18
19        return view('pages.platforms.index', compact('accounts'));
20    }
21
22    public function create(): View
23    {
24        return ViewFacade::make('pages.platforms.create');
25    }
26
27    public function store(Request $request): RedirectResponse
28    {
29        $validated = $request->validate([
30            'platform' => 'required|in:lemmy,mastodon,reddit',
31            'instance_url' => 'required|url',
32            'username' => 'required|string|max:255',
33            'password' => 'required|string',
34            'settings' => 'nullable|array',
35        ]);
36
37        // Create or find platform instance
38        $platformEnum = PlatformEnum::from($validated['platform']);
39        $instance = PlatformInstance::firstOrCreate([
40            'platform' => $platformEnum,
41            'url' => $validated['instance_url'],
42        ], [
43            'name' => parse_url($validated['instance_url'], PHP_URL_HOST),
44            'description' => ucfirst($validated['platform']) . ' instance',
45            'is_active' => true,
46        ]);
47
48        $account = PlatformAccount::create($validated);
49
50        // If this is the first account for this platform, make it active
51        if (! PlatformAccount::where('platform', $validated['platform'])->where('is_active', true)->exists()) {
52            $account->setAsActive();
53        }
54
55        // Check if there's a redirect_to parameter for onboarding flow
56        $redirectTo = $request->input('redirect_to');
57        if ($redirectTo) {
58            return redirect($redirectTo)
59                ->with('success', 'Platform account created successfully!');
60        }
61
62        return redirect()->route('platforms.index')
63            ->with('success', 'Platform account created successfully!');
64    }
65
66    public function edit(PlatformAccount $platformAccount): View
67    {
68        return ViewFacade::make('pages.platforms.edit', compact('platformAccount'));
69    }
70
71    public function update(Request $request, PlatformAccount $platformAccount): RedirectResponse
72    {
73        $validated = $request->validate([
74            'instance_url' => 'required|url',
75            'username' => 'required|string|max:255',
76            'password' => 'nullable|string',
77            'settings' => 'nullable|array',
78        ]);
79
80        // Don't update password if not provided
81        if (empty($validated['password'])) {
82            unset($validated['password']);
83        }
84
85        $platformAccount->update($validated);
86
87        return redirect()->route('platforms.index')
88            ->with('success', 'Platform account updated successfully!');
89    }
90
91    public function destroy(PlatformAccount $platformAccount): RedirectResponse
92    {
93        $platformAccount->delete();
94
95        return redirect()->route('platforms.index')
96            ->with('success', 'Platform account deleted successfully!');
97    }
98
99    public function setActive(PlatformAccount $platformAccount): RedirectResponse
100    {
101        $platformAccount->setAsActive();
102
103        return redirect()->route('platforms.index')
104            ->with('success', "Set $platformAccount->username@$platformAccount->instance_url as active for {$platformAccount->platform->value}!");
105    }
106}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:52:46 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-with-models/Http/Controllers/PlatformChannelsController.php.html b/backend/coverage-report-with-models/Http/Controllers/PlatformChannelsController.php.html deleted file mode 100644 index 7c042841..00000000 --- a/backend/coverage-report-with-models/Http/Controllers/PlatformChannelsController.php.html +++ /dev/null @@ -1,423 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Http/Controllers/PlatformChannelsController.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 53
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 8
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
PlatformChannelsController
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 53
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 8
110
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 index
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 5
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 create
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 4
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 store
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 18
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
6
 show
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 edit
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 4
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 update
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 12
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 destroy
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 toggle
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 5
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
6
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Http\Controllers;
4
5use App\Models\PlatformChannel;
6use App\Models\PlatformInstance;
7use Illuminate\Http\Request;
8use Illuminate\Contracts\View\View;
9use Illuminate\Http\RedirectResponse;
10use Illuminate\Support\Facades\View as ViewFacade;
11
12class PlatformChannelsController extends Controller
13{
14    public function index(): View
15    {
16        $channels = PlatformChannel::with('platformInstance')
17            ->orderBy('platform_instance_id')
18            ->orderBy('name')
19            ->get();
20        
21        return ViewFacade::make('pages.channels.index', compact('channels'));
22    }
23
24    public function create(): View
25    {
26        $instances = PlatformInstance::where('is_active', true)
27            ->orderBy('name')
28            ->get();
29            
30        return ViewFacade::make('pages.channels.create', compact('instances'));
31    }
32
33    public function store(Request $request): RedirectResponse
34    {
35        $validated = $request->validate([
36            'platform_instance_id' => 'required|exists:platform_instances,id',
37            'name' => 'required|string|max:255',
38            'display_name' => 'nullable|string|max:255',
39            'channel_id' => 'nullable|string|max:255',
40            'description' => 'nullable|string',
41            'language_id' => 'required|exists:languages,id',
42            'is_active' => 'boolean',
43        ]);
44
45        // Default is_active to true if not provided
46        $validated['is_active'] = $validated['is_active'] ?? true;
47        
48        // Set display_name to name if not provided
49        $validated['display_name'] = $validated['display_name'] ?? $validated['name'];
50
51        PlatformChannel::create($validated);
52
53        // Check if there's a redirect_to parameter for onboarding flow
54        $redirectTo = $request->input('redirect_to');
55        if ($redirectTo) {
56            return redirect($redirectTo)
57                ->with('success', 'Channel created successfully!');
58        }
59
60        return redirect()->route('channels.index')
61            ->with('success', 'Channel created successfully!');
62    }
63
64    public function show(PlatformChannel $channel): View
65    {
66        $channel->load(['platformInstance', 'feeds']);
67        
68        return ViewFacade::make('pages.channels.show', compact('channel'));
69    }
70
71    public function edit(PlatformChannel $channel): View
72    {
73        $instances = PlatformInstance::where('is_active', true)
74            ->orderBy('name')
75            ->get();
76            
77        return ViewFacade::make('pages.channels.edit', compact('channel', 'instances'));
78    }
79
80    public function update(Request $request, PlatformChannel $channel): RedirectResponse
81    {
82        $validated = $request->validate([
83            'platform_instance_id' => 'required|exists:platform_instances,id',
84            'name' => 'required|string|max:255',
85            'display_name' => 'nullable|string|max:255',
86            'channel_id' => 'nullable|string|max:255',
87            'description' => 'nullable|string',
88            'language_id' => 'required|exists:languages,id',
89            'is_active' => 'boolean',
90        ]);
91
92        $channel->update($validated);
93
94        return redirect()->route('channels.index')
95            ->with('success', 'Channel updated successfully!');
96    }
97
98    public function destroy(PlatformChannel $channel): RedirectResponse
99    {
100        $channel->delete();
101
102        return redirect()->route('channels.index')
103            ->with('success', 'Channel deleted successfully!');
104    }
105
106    public function toggle(PlatformChannel $channel): RedirectResponse
107    {
108        $newStatus = !$channel->is_active;
109        $channel->update(['is_active' => $newStatus]);
110
111        $status = $newStatus ? 'activated' : 'deactivated';
112
113        return redirect()->route('channels.index')
114            ->with('success', "Channel {$status} successfully!");
115    }
116}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:52:46 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-with-models/Http/Controllers/RoutingController.php.html b/backend/coverage-report-with-models/Http/Controllers/RoutingController.php.html deleted file mode 100644 index 767132d1..00000000 --- a/backend/coverage-report-with-models/Http/Controllers/RoutingController.php.html +++ /dev/null @@ -1,480 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Http/Controllers/RoutingController.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 87
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 8
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
RoutingController
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 87
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 8
240
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 index
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 9
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 create
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 8
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 store
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 28
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
12
 edit
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 6
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
6
 update
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 14
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 destroy
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 toggle
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 13
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
12
 parseJsonFilters
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 6
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
12
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Http\Controllers;
4
5use App\Models\Feed;
6use App\Models\Route;
7use App\Models\PlatformChannel;
8use App\Services\RoutingValidationService;
9use App\Exceptions\RoutingMismatchException;
10use Illuminate\Database\Eloquent\Collection;
11use Illuminate\Http\Request;
12use Illuminate\Contracts\View\View;
13use Illuminate\Http\RedirectResponse;
14
15class RoutingController extends Controller
16{
17    public function index(): View
18    {
19        $feeds = Feed::with(['channels.platformInstance'])
20            ->where('is_active', true)
21            ->orderBy('name')
22            ->get();
23
24        $channels = PlatformChannel::with(['platformInstance', 'feeds'])
25            ->where('is_active', true)
26            ->orderBy('name')
27            ->get();
28
29        return view('pages.routing.index', compact('feeds', 'channels'));
30    }
31
32    public function create(): View
33    {
34        $feeds = Feed::where('is_active', true)
35            ->orderBy('name')
36            ->get();
37
38        $channels = PlatformChannel::with('platformInstance')
39            ->where('is_active', true)
40            ->orderBy('name')
41            ->get();
42
43        return view('pages.routing.create', compact('feeds', 'channels'));
44    }
45
46    public function store(Request $request): RedirectResponse
47    {
48        $validated = $request->validate([
49            'feed_id' => 'required|exists:feeds,id',
50            'channel_ids' => 'required|array|min:1',
51            'channel_ids.*' => 'exists:platform_channels,id',
52            'priority' => 'integer|min:0|max:100',
53            'filters' => 'nullable|string'
54        ]);
55
56        /** @var Feed $feed */
57        $feed = Feed::findOrFail($validated['feed_id']);
58        
59        /** @var Collection<int, PlatformChannel> $channels */
60        $channels = PlatformChannel::findMany($validated['channel_ids']);
61        $priority = $validated['priority'] ?? 0;
62
63        try {
64            app(RoutingValidationService::class)->validateLanguageCompatibility($feed, $channels);
65        } catch (RoutingMismatchException $e) {
66            return redirect()->back()
67                ->withInput()
68                ->withErrors(['language' => $e->getMessage()]);
69        }
70
71        $filters = $this->parseJsonFilters($validated['filters'] ?? null);
72
73        // Attach channels to feed
74        $syncData = [];
75        foreach ($validated['channel_ids'] as $channelId) {
76            $syncData[$channelId] = [
77                'is_active' => true,
78                'priority' => $priority,
79                'filters' => $filters,
80                'created_at' => now(),
81                'updated_at' => now()
82            ];
83        }
84
85        $feed->channels()->syncWithoutDetaching($syncData);
86
87        return redirect()->route('routing.index')
88            ->with('success', 'Feed routing created successfully!');
89    }
90
91    public function edit(Feed $feed, PlatformChannel $channel): View
92    {
93        $routing = $feed->channels()
94            ->wherePivot('platform_channel_id', $channel->id)
95            ->first();
96
97        if (! $routing) {
98            abort(404, 'Routing not found');
99        }
100
101        return view('pages.routing.edit', compact('feed', 'channel', 'routing'));
102    }
103
104    public function update(Request $request, Feed $feed, PlatformChannel $channel): RedirectResponse
105    {
106        $validated = $request->validate([
107            'is_active' => 'boolean',
108            'priority' => 'integer|min:0|max:100',
109            'filters' => 'nullable|string'
110        ]);
111
112        $filters = $this->parseJsonFilters($validated['filters'] ?? null);
113
114        $feed->channels()->updateExistingPivot($channel->id, [
115            'is_active' => $validated['is_active'] ?? true,
116            'priority' => $validated['priority'] ?? 0,
117            'filters' => $filters,
118            'updated_at' => now()
119        ]);
120
121        return redirect()->route('routing.index')
122            ->with('success', 'Routing updated successfully!');
123    }
124
125    public function destroy(Feed $feed, PlatformChannel $channel): RedirectResponse
126    {
127        $feed->channels()->detach($channel->id);
128
129        return redirect()->route('routing.index')
130            ->with('success', 'Routing deleted successfully!');
131    }
132
133    public function toggle(Request $request, Feed $feed, PlatformChannel $channel): RedirectResponse
134    {
135        $routing = Route::where('feed_id', $feed->id)
136            ->where('platform_channel_id', $channel->id)
137            ->first();
138
139        if (! $routing) {
140            abort(404, 'Routing not found');
141        }
142
143        $newStatus = ! $routing->is_active;
144
145        $feed->channels()->updateExistingPivot($channel->id, [
146            'is_active' => $newStatus,
147            'updated_at' => now()
148        ]);
149
150        $status = $newStatus ? 'activated' : 'deactivated';
151
152        return redirect()->route('routing.index')
153            ->with('success', "Routing {$status} successfully!");
154    }
155
156    /**
157     * @return array<string, mixed>|null
158     */
159    private function parseJsonFilters(?string $json): ?array
160    {
161        if (empty($json)) {
162            return null;
163        }
164
165        $decoded = json_decode($json, true);
166
167        if (json_last_error() === JSON_ERROR_NONE) {
168            return $decoded;
169        }
170
171        return null;
172    }
173}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:52:46 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-with-models/Http/Controllers/SettingsController.php.html b/backend/coverage-report-with-models/Http/Controllers/SettingsController.php.html deleted file mode 100644 index 821f7a66..00000000 --- a/backend/coverage-report-with-models/Http/Controllers/SettingsController.php.html +++ /dev/null @@ -1,214 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Http/Controllers/SettingsController.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 14
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
SettingsController
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 14
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
12
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 index
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 update
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 11
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
6
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Http\Controllers;
4
5use App\Models\Setting;
6use Illuminate\Contracts\View\View;
7use Illuminate\Http\RedirectResponse;
8use Illuminate\Http\Request;
9
10class SettingsController extends Controller
11{
12    public function index(): View
13    {
14        $articleProcessingEnabled = Setting::isArticleProcessingEnabled();
15        $publishingApprovalsEnabled = Setting::isPublishingApprovalsEnabled();
16        
17        return view('pages.settings.index', compact('articleProcessingEnabled', 'publishingApprovalsEnabled'));
18    }
19
20    public function update(Request $request): RedirectResponse
21    {
22        $request->validate([
23            'article_processing_enabled' => 'boolean',
24            'enable_publishing_approvals' => 'boolean',
25        ]);
26
27        Setting::setArticleProcessingEnabled($request->boolean('article_processing_enabled'));
28        Setting::setPublishingApprovalsEnabled($request->boolean('enable_publishing_approvals'));
29
30        // If redirected from onboarding, go to dashboard
31        if ($request->get('from') === 'onboarding') {
32            return redirect()->route('onboarding.index')
33                ->with('success', 'System activated successfully! Welcome to Lemmy Poster.');
34        }
35
36        return redirect()->route('settings.index')
37            ->with('success', 'Settings updated successfully.');
38    }
39}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:52:46 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-with-models/Http/Controllers/dashboard.html b/backend/coverage-report-with-models/Http/Controllers/dashboard.html deleted file mode 100644 index aa7b2cab..00000000 --- a/backend/coverage-report-with-models/Http/Controllers/dashboard.html +++ /dev/null @@ -1,439 +0,0 @@ - - - - - Dashboard for /var/www/html/backend/app/Http/Controllers - - - - - - - -
-
-
-
- -
-
-
-
-
-
-
-

Classes

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
-
- - -
-
-
-

Methods

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
-
-
-

Insufficient Coverage

-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
MethodCoverage
login0%
register0%
logout0%
me0%
sendNotFound0%
sendUnauthorized0%
index0%
index0%
store0%
show0%
update0%
destroy0%
setActive0%
index0%
store0%
show0%
update0%
destroy0%
toggle0%
index0%
store0%
show0%
update0%
destroy0%
toggle0%
__invoke0%
approve0%
reject0%
index0%
create0%
store0%
show0%
edit0%
update0%
destroy0%
toggle0%
__invoke0%
index0%
platform0%
feed0%
channel0%
complete0%
needsOnboarding0%
hasPlatformAccount0%
hasFeed0%
hasChannel0%
index0%
create0%
store0%
edit0%
update0%
destroy0%
setActive0%
index0%
create0%
store0%
show0%
edit0%
update0%
destroy0%
toggle0%
index0%
create0%
store0%
edit0%
update0%
destroy0%
toggle0%
parseJsonFilters0%
index0%
update0%
update63%
store66%
approve71%
reject71%
destroy71%
index71%
toggle77%
stats83%
-
-
-
-

Project Risks

-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
MethodCRAP
login30
complete30
store20
update20
update20
toggle20
channel20
register12
index12
store12
update12
toggle12
store12
destroy12
feed12
needsOnboarding12
store12
store12
toggle12
parseJsonFilters12
logout6
destroy6
setActive6
destroy6
show6
toggle6
index6
platform6
update6
store6
toggle6
edit6
update6
update3
store3
toggle3
approve2
reject2
destroy2
index2
stats2
-
-
-
- -
- - - - - - diff --git a/backend/coverage-report-with-models/Http/Controllers/index.html b/backend/coverage-report-with-models/Http/Controllers/index.html deleted file mode 100644 index 4464da41..00000000 --- a/backend/coverage-report-with-models/Http/Controllers/index.html +++ /dev/null @@ -1,357 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Http/Controllers - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 16.24% covered (danger) -
-
-
16.24%
115 / 708
-
- 8.05% covered (danger) -
-
-
8.05%
7 / 87
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 18
Api
-
- 26.81% covered (danger) -
-
-
26.81%
115 / 429
-
- 17.07% covered (danger) -
-
-
17.07%
7 / 41
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 10
ArticlesController.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 9
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
Controller.php
n/a
0 / 0
n/a
0 / 0
n/a
0 / 0
FeedsController.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 28
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 8
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
LogsController.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
OnboardingController.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 40
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 9
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
PlatformAccountsController.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 46
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 7
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
PlatformChannelsController.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 53
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 8
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
RoutingController.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 87
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 8
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
SettingsController.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 14
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- -
- - diff --git a/backend/coverage-report-with-models/Http/Middleware/HandleAppearance.php.html b/backend/coverage-report-with-models/Http/Middleware/HandleAppearance.php.html deleted file mode 100644 index e3e8bdde..00000000 --- a/backend/coverage-report-with-models/Http/Middleware/HandleAppearance.php.html +++ /dev/null @@ -1,176 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Http/Middleware/HandleAppearance.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
HandleAppearance
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 handle
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Http\Middleware;
4
5use Closure;
6use Illuminate\Http\Request;
7use Illuminate\Support\Facades\View;
8use Symfony\Component\HttpFoundation\Response;
9
10class HandleAppearance
11{
12    /**
13     * Handle an incoming request.
14     *
15     * @param  \Closure(\Illuminate\Http\Request): (\Symfony\Component\HttpFoundation\Response)  $next
16     */
17    public function handle(Request $request, Closure $next): Response
18    {
19        View::share('appearance', $request->cookie('appearance') ?? 'system');
20
21        return $next($request);
22    }
23}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:52:46 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-with-models/Http/Middleware/HandleInertiaRequests.php.html b/backend/coverage-report-with-models/Http/Middleware/HandleInertiaRequests.php.html deleted file mode 100644 index 678f6dbb..00000000 --- a/backend/coverage-report-with-models/Http/Middleware/HandleInertiaRequests.php.html +++ /dev/null @@ -1,217 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Http/Middleware/HandleInertiaRequests.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 4
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
HandleInertiaRequests
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 4
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
6
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 version
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 share
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Http\Middleware;
4
5use Illuminate\Http\Request;
6use Inertia\Middleware;
7
8class HandleInertiaRequests extends Middleware
9{
10    /**
11     * The root template that's loaded on the first page visit.
12     *
13     * @see https://inertiajs.com/server-side-setup#root-template
14     *
15     * @var string
16     */
17    protected $rootView = 'app';
18
19    /**
20     * Determines the current asset version.
21     *
22     * @see https://inertiajs.com/asset-versioning
23     */
24    public function version(Request $request): ?string
25    {
26        return parent::version($request);
27    }
28
29    /**
30     * Define the props that are shared by default.
31     *
32     * @see https://inertiajs.com/shared-data
33     *
34     * @return array<string, mixed>
35     */
36    public function share(Request $request): array
37    {
38        return array_merge(parent::share($request), [
39            //
40        ]);
41    }
42}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:52:46 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-with-models/Http/Middleware/dashboard.html b/backend/coverage-report-with-models/Http/Middleware/dashboard.html deleted file mode 100644 index 8bed7ec9..00000000 --- a/backend/coverage-report-with-models/Http/Middleware/dashboard.html +++ /dev/null @@ -1,290 +0,0 @@ - - - - - Dashboard for /var/www/html/backend/app/Http/Middleware - - - - - - - -
-
-
-
- -
-
-
-
-
-
-
-

Classes

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
-
-
-

Insufficient Coverage

- -
-
-

Project Risks

-
- - - - - - - - - - -
ClassCRAP
-
-
-
-
-
-

Methods

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
-
-
-

Insufficient Coverage

-
- - - - - - - - - - - - - -
MethodCoverage
handle0%
version0%
share0%
-
-
-
-

Project Risks

-
- - - - - - - - - - -
MethodCRAP
-
-
-
- -
- - - - - - diff --git a/backend/coverage-report-with-models/Http/Middleware/index.html b/backend/coverage-report-with-models/Http/Middleware/index.html deleted file mode 100644 index 56332ccf..00000000 --- a/backend/coverage-report-with-models/Http/Middleware/index.html +++ /dev/null @@ -1,148 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Http/Middleware - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 6
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
HandleAppearance.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
HandleInertiaRequests.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 4
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- -
- - diff --git a/backend/coverage-report-with-models/Http/Requests/StoreFeedRequest.php.html b/backend/coverage-report-with-models/Http/Requests/StoreFeedRequest.php.html deleted file mode 100644 index 9c6d1388..00000000 --- a/backend/coverage-report-with-models/Http/Requests/StoreFeedRequest.php.html +++ /dev/null @@ -1,203 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Http/Requests/StoreFeedRequest.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 100.00% covered (success) -
-
-
100.00%
9 / 9
-
- 100.00% covered (success) -
-
-
100.00%
2 / 2
CRAP
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
StoreFeedRequest
-
- 100.00% covered (success) -
-
-
100.00%
9 / 9
-
- 100.00% covered (success) -
-
-
100.00%
2 / 2
2
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
 authorize
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
1
 rules
-
- 100.00% covered (success) -
-
-
100.00%
8 / 8
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
1
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Http\Requests;
4
5use Illuminate\Foundation\Http\FormRequest;
6
7class StoreFeedRequest extends FormRequest
8{
9    public function authorize(): bool
10    {
11        return true;
12    }
13
14    /**
15     * @return array<string, string>
16     */
17    public function rules(): array
18    {
19        return [
20            'name' => 'required|string|max:255',
21            'url' => 'required|url|unique:feeds,url',
22            'type' => 'required|in:website,rss',
23            'language_id' => 'required|exists:languages,id',
24            'description' => 'nullable|string',
25            'is_active' => 'boolean'
26        ];
27    }
28}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:52:46 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-with-models/Http/Requests/UpdateFeedRequest.php.html b/backend/coverage-report-with-models/Http/Requests/UpdateFeedRequest.php.html deleted file mode 100644 index 16172751..00000000 --- a/backend/coverage-report-with-models/Http/Requests/UpdateFeedRequest.php.html +++ /dev/null @@ -1,204 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Http/Requests/UpdateFeedRequest.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 100.00% covered (success) -
-
-
100.00%
9 / 9
-
- 100.00% covered (success) -
-
-
100.00%
2 / 2
CRAP
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
UpdateFeedRequest
-
- 100.00% covered (success) -
-
-
100.00%
9 / 9
-
- 100.00% covered (success) -
-
-
100.00%
2 / 2
3
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
 authorize
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
1
 rules
-
- 100.00% covered (success) -
-
-
100.00%
8 / 8
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
2
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Http\Requests;
4
5use App\Models\Feed;
6use Illuminate\Foundation\Http\FormRequest;
7
8class UpdateFeedRequest extends FormRequest
9{
10    public function authorize(): bool
11    {
12        return true;
13    }
14
15    /**
16     * @return array<string, string>
17     */
18    public function rules(): array
19    {
20        return [
21            'name' => 'required|string|max:255',
22            'url' => 'required|url|unique:feeds,url,' . ($this->route('feed') instanceof Feed ? (string)$this->route('feed')->id : (string)$this->route('feed')),
23            'type' => 'required|in:website,rss',
24            'language_id' => 'required|exists:languages,id',
25            'description' => 'nullable|string',
26            'is_active' => 'boolean'
27        ];
28    }
29}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:52:46 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-with-models/Http/Requests/dashboard.html b/backend/coverage-report-with-models/Http/Requests/dashboard.html deleted file mode 100644 index a3594e0a..00000000 --- a/backend/coverage-report-with-models/Http/Requests/dashboard.html +++ /dev/null @@ -1,285 +0,0 @@ - - - - - Dashboard for /var/www/html/backend/app/Http/Requests - - - - - - - -
-
-
-
- -
-
-
-
-
-
-
-

Classes

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
-
-
-

Insufficient Coverage

-
- - - - - - - - - - -
ClassCoverage
-
-
-
-

Project Risks

-
- - - - - - - - - - -
ClassCRAP
-
-
-
-
-
-

Methods

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
-
-
-

Insufficient Coverage

-
- - - - - - - - - - -
MethodCoverage
-
-
-
-

Project Risks

-
- - - - - - - - - - -
MethodCRAP
-
-
-
- -
- - - - - - diff --git a/backend/coverage-report-with-models/Http/Requests/index.html b/backend/coverage-report-with-models/Http/Requests/index.html deleted file mode 100644 index 26f356b4..00000000 --- a/backend/coverage-report-with-models/Http/Requests/index.html +++ /dev/null @@ -1,148 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Http/Requests - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 100.00% covered (success) -
-
-
100.00%
18 / 18
-
- 100.00% covered (success) -
-
-
100.00%
4 / 4
-
- 100.00% covered (success) -
-
-
100.00%
2 / 2
StoreFeedRequest.php
-
- 100.00% covered (success) -
-
-
100.00%
9 / 9
-
- 100.00% covered (success) -
-
-
100.00%
2 / 2
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
UpdateFeedRequest.php
-
- 100.00% covered (success) -
-
-
100.00%
9 / 9
-
- 100.00% covered (success) -
-
-
100.00%
2 / 2
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
-
- -
- - diff --git a/backend/coverage-report-with-models/Http/Resources/ArticlePublicationResource.php.html b/backend/coverage-report-with-models/Http/Resources/ArticlePublicationResource.php.html deleted file mode 100644 index 024a8ba3..00000000 --- a/backend/coverage-report-with-models/Http/Resources/ArticlePublicationResource.php.html +++ /dev/null @@ -1,179 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Http/Resources/ArticlePublicationResource.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 8
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
ArticlePublicationResource
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 8
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 toArray
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 8
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Http\Resources;
4
5use Illuminate\Http\Request;
6use Illuminate\Http\Resources\Json\JsonResource;
7
8class ArticlePublicationResource extends JsonResource
9{
10    /**
11     * Transform the resource into an array.
12     *
13     * @return array<string, mixed>
14     */
15    public function toArray(Request $request): array
16    {
17        return [
18            'id' => $this->id,
19            'article_id' => $this->article_id,
20            'status' => $this->status,
21            'published_at' => $this->published_at?->toISOString(),
22            'created_at' => $this->created_at->toISOString(),
23            'updated_at' => $this->updated_at->toISOString(),
24        ];
25    }
26}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:52:46 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-with-models/Http/Resources/ArticleResource.php.html b/backend/coverage-report-with-models/Http/Resources/ArticleResource.php.html deleted file mode 100644 index eafeb1b4..00000000 --- a/backend/coverage-report-with-models/Http/Resources/ArticleResource.php.html +++ /dev/null @@ -1,189 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Http/Resources/ArticleResource.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 100.00% covered (success) -
-
-
100.00%
18 / 18
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
CRAP
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
ArticleResource
-
- 100.00% covered (success) -
-
-
100.00%
18 / 18
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
1
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
 toArray
-
- 100.00% covered (success) -
-
-
100.00%
18 / 18
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
1
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Http\Resources;
4
5use Illuminate\Http\Request;
6use Illuminate\Http\Resources\Json\JsonResource;
7
8class ArticleResource extends JsonResource
9{
10    /**
11     * Transform the resource into an array.
12     *
13     * @return array<string, mixed>
14     */
15    public function toArray(Request $request): array
16    {
17        return [
18            'id' => $this->id,
19            'feed_id' => $this->feed_id,
20            'url' => $this->url,
21            'title' => $this->title,
22            'description' => $this->description,
23            'is_valid' => $this->is_valid,
24            'is_duplicate' => $this->is_duplicate,
25            'approval_status' => $this->approval_status,
26            'approved_at' => $this->approved_at?->toISOString(),
27            'approved_by' => $this->approved_by,
28            'fetched_at' => $this->fetched_at?->toISOString(),
29            'validated_at' => $this->validated_at?->toISOString(),
30            'created_at' => $this->created_at->toISOString(),
31            'updated_at' => $this->updated_at->toISOString(),
32            'feed' => new FeedResource($this->whenLoaded('feed')),
33            'article_publication' => new ArticlePublicationResource($this->whenLoaded('articlePublication')),
34        ];
35    }
36}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:52:46 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-with-models/Http/Resources/FeedResource.php.html b/backend/coverage-report-with-models/Http/Resources/FeedResource.php.html deleted file mode 100644 index ccd1a093..00000000 --- a/backend/coverage-report-with-models/Http/Resources/FeedResource.php.html +++ /dev/null @@ -1,184 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Http/Resources/FeedResource.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 100.00% covered (success) -
-
-
100.00%
13 / 13
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
CRAP
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
FeedResource
-
- 100.00% covered (success) -
-
-
100.00%
13 / 13
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
1
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
 toArray
-
- 100.00% covered (success) -
-
-
100.00%
13 / 13
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
1
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Http\Resources;
4
5use Illuminate\Http\Request;
6use Illuminate\Http\Resources\Json\JsonResource;
7
8class FeedResource extends JsonResource
9{
10    /**
11     * Transform the resource into an array.
12     *
13     * @return array<string, mixed>
14     */
15    public function toArray(Request $request): array
16    {
17        return [
18            'id' => $this->id,
19            'name' => $this->name,
20            'url' => $this->url,
21            'type' => $this->type,
22            'is_active' => $this->is_active,
23            'description' => $this->description,
24            'created_at' => $this->created_at->toISOString(),
25            'updated_at' => $this->updated_at->toISOString(),
26            'articles_count' => $this->when($request->routeIs('api.feeds.*'), function () {
27                return $this->articles()->count();
28            }),
29        ];
30    }
31}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:52:46 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-with-models/Http/Resources/PlatformAccountResource.php.html b/backend/coverage-report-with-models/Http/Resources/PlatformAccountResource.php.html deleted file mode 100644 index c958cd81..00000000 --- a/backend/coverage-report-with-models/Http/Resources/PlatformAccountResource.php.html +++ /dev/null @@ -1,184 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Http/Resources/PlatformAccountResource.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 13
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
PlatformAccountResource
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 13
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 toArray
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 13
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Http\Resources;
4
5use Illuminate\Http\Request;
6use Illuminate\Http\Resources\Json\JsonResource;
7
8class PlatformAccountResource extends JsonResource
9{
10    /**
11     * Transform the resource into an array.
12     *
13     * @return array<string, mixed>
14     */
15    public function toArray(Request $request): array
16    {
17        return [
18            'id' => $this->id,
19            'platform_instance_id' => $this->platform_instance_id,
20            'account_id' => $this->account_id,
21            'username' => $this->username,
22            'display_name' => $this->display_name,
23            'description' => $this->description,
24            'is_active' => $this->is_active,
25            'created_at' => $this->created_at->toISOString(),
26            'updated_at' => $this->updated_at->toISOString(),
27            'platform_instance' => new PlatformInstanceResource($this->whenLoaded('platformInstance')),
28            'channels' => PlatformChannelResource::collection($this->whenLoaded('channels')),
29        ];
30    }
31}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:52:46 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-with-models/Http/Resources/PlatformChannelResource.php.html b/backend/coverage-report-with-models/Http/Resources/PlatformChannelResource.php.html deleted file mode 100644 index fd9ba247..00000000 --- a/backend/coverage-report-with-models/Http/Resources/PlatformChannelResource.php.html +++ /dev/null @@ -1,184 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Http/Resources/PlatformChannelResource.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 13
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
PlatformChannelResource
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 13
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 toArray
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 13
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Http\Resources;
4
5use Illuminate\Http\Request;
6use Illuminate\Http\Resources\Json\JsonResource;
7
8class PlatformChannelResource extends JsonResource
9{
10    /**
11     * Transform the resource into an array.
12     *
13     * @return array<string, mixed>
14     */
15    public function toArray(Request $request): array
16    {
17        return [
18            'id' => $this->id,
19            'platform_instance_id' => $this->platform_instance_id,
20            'channel_id' => $this->channel_id,
21            'name' => $this->name,
22            'display_name' => $this->display_name,
23            'description' => $this->description,
24            'is_active' => $this->is_active,
25            'created_at' => $this->created_at->toISOString(),
26            'updated_at' => $this->updated_at->toISOString(),
27            'platform_instance' => new PlatformInstanceResource($this->whenLoaded('platformInstance')),
28            'routes' => RouteResource::collection($this->whenLoaded('routes')),
29        ];
30    }
31}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:52:46 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-with-models/Http/Resources/PlatformInstanceResource.php.html b/backend/coverage-report-with-models/Http/Resources/PlatformInstanceResource.php.html deleted file mode 100644 index a1e0a9e5..00000000 --- a/backend/coverage-report-with-models/Http/Resources/PlatformInstanceResource.php.html +++ /dev/null @@ -1,180 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Http/Resources/PlatformInstanceResource.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 9
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
PlatformInstanceResource
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 9
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 toArray
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 9
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Http\Resources;
4
5use Illuminate\Http\Request;
6use Illuminate\Http\Resources\Json\JsonResource;
7
8class PlatformInstanceResource extends JsonResource
9{
10    /**
11     * Transform the resource into an array.
12     *
13     * @return array<string, mixed>
14     */
15    public function toArray(Request $request): array
16    {
17        return [
18            'id' => $this->id,
19            'name' => $this->name,
20            'url' => $this->url,
21            'description' => $this->description,
22            'is_active' => $this->is_active,
23            'created_at' => $this->created_at->toISOString(),
24            'updated_at' => $this->updated_at->toISOString(),
25        ];
26    }
27}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:52:46 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-with-models/Http/Resources/RouteResource.php.html b/backend/coverage-report-with-models/Http/Resources/RouteResource.php.html deleted file mode 100644 index 2f544ec6..00000000 --- a/backend/coverage-report-with-models/Http/Resources/RouteResource.php.html +++ /dev/null @@ -1,182 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Http/Resources/RouteResource.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 11
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
RouteResource
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 11
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 toArray
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 11
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Http\Resources;
4
5use Illuminate\Http\Request;
6use Illuminate\Http\Resources\Json\JsonResource;
7
8class RouteResource extends JsonResource
9{
10    /**
11     * Transform the resource into an array.
12     *
13     * @return array<string, mixed>
14     */
15    public function toArray(Request $request): array
16    {
17        return [
18            'id' => $this->id,
19            'feed_id' => $this->feed_id,
20            'platform_channel_id' => $this->platform_channel_id,
21            'is_active' => $this->is_active,
22            'priority' => $this->priority,
23            'created_at' => $this->created_at->toISOString(),
24            'updated_at' => $this->updated_at->toISOString(),
25            'feed' => new FeedResource($this->whenLoaded('feed')),
26            'platform_channel' => new PlatformChannelResource($this->whenLoaded('platformChannel')),
27        ];
28    }
29}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:52:46 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-with-models/Http/Resources/dashboard.html b/backend/coverage-report-with-models/Http/Resources/dashboard.html deleted file mode 100644 index 6452d1be..00000000 --- a/backend/coverage-report-with-models/Http/Resources/dashboard.html +++ /dev/null @@ -1,295 +0,0 @@ - - - - - Dashboard for /var/www/html/backend/app/Http/Resources - - - - - - - -
-
-
-
- -
-
-
-
-
-
-
-

Classes

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
-
- -
-

Project Risks

-
- - - - - - - - - - -
ClassCRAP
-
-
-
-
-
-

Methods

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
-
-
-

Insufficient Coverage

-
- - - - - - - - - - - - - - - -
MethodCoverage
toArray0%
toArray0%
toArray0%
toArray0%
toArray0%
-
-
-
-

Project Risks

-
- - - - - - - - - - -
MethodCRAP
-
-
-
- -
- - - - - - diff --git a/backend/coverage-report-with-models/Http/Resources/index.html b/backend/coverage-report-with-models/Http/Resources/index.html deleted file mode 100644 index d9d4d481..00000000 --- a/backend/coverage-report-with-models/Http/Resources/index.html +++ /dev/null @@ -1,288 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Http/Resources - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 36.47% covered (danger) -
-
-
36.47%
31 / 85
-
- 28.57% covered (danger) -
-
-
28.57%
2 / 7
-
- 28.57% covered (danger) -
-
-
28.57%
2 / 7
ArticlePublicationResource.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 8
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
ArticleResource.php
-
- 100.00% covered (success) -
-
-
100.00%
18 / 18
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
FeedResource.php
-
- 100.00% covered (success) -
-
-
100.00%
13 / 13
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
PlatformAccountResource.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 13
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
PlatformChannelResource.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 13
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
PlatformInstanceResource.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 9
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
RouteResource.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 11
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- -
- - diff --git a/backend/coverage-report-with-models/Http/dashboard.html b/backend/coverage-report-with-models/Http/dashboard.html deleted file mode 100644 index 4be33fa2..00000000 --- a/backend/coverage-report-with-models/Http/dashboard.html +++ /dev/null @@ -1,453 +0,0 @@ - - - - - Dashboard for /var/www/html/backend/app/Http - - - - - - - -
-
-
-
- -
-
-
-
-
-
-
-

Classes

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
-
- - -
-
-
-

Methods

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
-
-
-

Insufficient Coverage

-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
MethodCoverage
login0%
register0%
logout0%
me0%
sendNotFound0%
sendUnauthorized0%
index0%
index0%
store0%
show0%
update0%
destroy0%
setActive0%
index0%
store0%
show0%
update0%
destroy0%
toggle0%
index0%
store0%
show0%
update0%
destroy0%
toggle0%
__invoke0%
approve0%
reject0%
index0%
create0%
store0%
show0%
edit0%
update0%
destroy0%
toggle0%
__invoke0%
index0%
platform0%
feed0%
channel0%
complete0%
needsOnboarding0%
hasPlatformAccount0%
hasFeed0%
hasChannel0%
index0%
create0%
store0%
edit0%
update0%
destroy0%
setActive0%
index0%
create0%
store0%
show0%
edit0%
update0%
destroy0%
toggle0%
index0%
create0%
store0%
edit0%
update0%
destroy0%
toggle0%
parseJsonFilters0%
index0%
update0%
handle0%
version0%
share0%
toArray0%
toArray0%
toArray0%
toArray0%
toArray0%
update63%
store66%
approve71%
reject71%
destroy71%
index71%
toggle77%
stats83%
-
-
-
-

Project Risks

-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
MethodCRAP
login30
complete30
store20
update20
update20
toggle20
channel20
register12
index12
store12
update12
toggle12
store12
destroy12
feed12
needsOnboarding12
store12
store12
toggle12
parseJsonFilters12
logout6
destroy6
setActive6
destroy6
show6
toggle6
index6
platform6
update6
store6
toggle6
edit6
update6
update3
store3
toggle3
approve2
reject2
destroy2
index2
stats2
-
-
-
- -
- - - - - - diff --git a/backend/coverage-report-with-models/Http/index.html b/backend/coverage-report-with-models/Http/index.html deleted file mode 100644 index 3f0f23e3..00000000 --- a/backend/coverage-report-with-models/Http/index.html +++ /dev/null @@ -1,203 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Http - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 20.07% covered (danger) -
-
-
20.07%
164 / 817
-
- 12.87% covered (danger) -
-
-
12.87%
13 / 101
-
- 13.79% covered (danger) -
-
-
13.79%
4 / 29
Controllers
-
- 16.24% covered (danger) -
-
-
16.24%
115 / 708
-
- 8.05% covered (danger) -
-
-
8.05%
7 / 87
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 18
Middleware
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 6
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
Requests
-
- 100.00% covered (success) -
-
-
100.00%
18 / 18
-
- 100.00% covered (success) -
-
-
100.00%
4 / 4
-
- 100.00% covered (success) -
-
-
100.00%
2 / 2
Resources
-
- 36.47% covered (danger) -
-
-
36.47%
31 / 85
-
- 28.57% covered (danger) -
-
-
28.57%
2 / 7
-
- 28.57% covered (danger) -
-
-
28.57%
2 / 7
-
- -
- - diff --git a/backend/coverage-report-with-models/Jobs/ArticleDiscoveryForFeedJob.php.html b/backend/coverage-report-with-models/Jobs/ArticleDiscoveryForFeedJob.php.html deleted file mode 100644 index 6891964e..00000000 --- a/backend/coverage-report-with-models/Jobs/ArticleDiscoveryForFeedJob.php.html +++ /dev/null @@ -1,257 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Jobs/ArticleDiscoveryForFeedJob.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 26
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
ArticleDiscoveryForFeedJob
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 26
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
12
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 __construct
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 handle
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 12
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 dispatchForAllActiveFeeds
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 13
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Jobs;
4
5use App\Models\Feed;
6use App\Services\Article\ArticleFetcher;
7use App\Services\Log\LogSaver;
8use Illuminate\Contracts\Queue\ShouldQueue;
9use Illuminate\Foundation\Queue\Queueable;
10
11class ArticleDiscoveryForFeedJob implements ShouldQueue
12{
13    use Queueable;
14
15    private const FEED_DISCOVERY_DELAY_MINUTES = 5;
16
17    public function __construct(
18        private readonly Feed $feed
19    ) {
20        $this->onQueue('feed-discovery');
21    }
22
23    public function handle(): void
24    {
25        LogSaver::info('Starting feed article fetch', null, [
26            'feed_id' => $this->feed->id,
27            'feed_name' => $this->feed->name,
28            'feed_url' => $this->feed->url
29        ]);
30
31        $articles = ArticleFetcher::getArticlesFromFeed($this->feed);
32
33        LogSaver::info('Feed article fetch completed', null, [
34            'feed_id' => $this->feed->id,
35            'feed_name' => $this->feed->name,
36            'articles_count' => $articles->count()
37        ]);
38
39        $this->feed->update(['last_fetched_at' => now()]);
40    }
41
42    public static function dispatchForAllActiveFeeds(): void
43    {
44        Feed::where('is_active', true)
45            ->get()
46            ->each(function (Feed $feed, $index) {
47                // Space jobs apart to avoid overwhelming feeds
48                $delayMinutes = $index * self::FEED_DISCOVERY_DELAY_MINUTES;
49
50                self::dispatch($feed)
51                    ->delay(now()->addMinutes($delayMinutes))
52                    ->onQueue('feed-discovery');
53
54                LogSaver::info('Dispatched feed discovery job', null, [
55                    'feed_id' => $feed->id,
56                    'feed_name' => $feed->name,
57                    'delay_minutes' => $delayMinutes
58                ]);
59            });
60    }
61}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:52:46 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-with-models/Jobs/ArticleDiscoveryJob.php.html b/backend/coverage-report-with-models/Jobs/ArticleDiscoveryJob.php.html deleted file mode 100644 index b0774c26..00000000 --- a/backend/coverage-report-with-models/Jobs/ArticleDiscoveryJob.php.html +++ /dev/null @@ -1,207 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Jobs/ArticleDiscoveryJob.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 7
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
ArticleDiscoveryJob
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 7
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
12
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 __construct
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 handle
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 6
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
6
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Jobs;
4
5use App\Models\Setting;
6use App\Services\Log\LogSaver;
7use Illuminate\Contracts\Queue\ShouldQueue;
8use Illuminate\Foundation\Queue\Queueable;
9
10class ArticleDiscoveryJob implements ShouldQueue
11{
12    use Queueable;
13
14    public function __construct()
15    {
16        $this->onQueue('feed-discovery');
17    }
18
19    public function handle(): void
20    {
21        if (!Setting::isArticleProcessingEnabled()) {
22            LogSaver::info('Article processing is disabled. Article discovery skipped.');
23
24            return;
25        }
26
27        LogSaver::info('Starting article discovery for all active feeds');
28
29        ArticleDiscoveryForFeedJob::dispatchForAllActiveFeeds();
30
31        LogSaver::info('Article discovery jobs dispatched for all active feeds');
32    }
33}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:52:46 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-with-models/Jobs/PublishToLemmyJob.php.html b/backend/coverage-report-with-models/Jobs/PublishToLemmyJob.php.html deleted file mode 100644 index 4ab24639..00000000 --- a/backend/coverage-report-with-models/Jobs/PublishToLemmyJob.php.html +++ /dev/null @@ -1,212 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Jobs/PublishToLemmyJob.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 6
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
PublishToLemmyJob
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 6
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
12
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 __construct
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 handle
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 5
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
6
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Jobs;
4
5use App\Exceptions\PublishException;
6use App\Models\Article;
7use App\Services\Article\ArticleFetcher;
8use App\Services\Publishing\ArticlePublishingService;
9use Illuminate\Contracts\Queue\ShouldQueue;
10use Illuminate\Foundation\Queue\Queueable;
11
12class PublishToLemmyJob implements ShouldQueue
13{
14    use Queueable;
15
16    public int $tries = 3;
17    public array $backoff = [60, 120, 300];
18
19    public function __construct(
20        private readonly Article $article
21    ) {
22        $this->onQueue('lemmy-posts');
23    }
24
25    public function handle(): void
26    {
27        $extractedData = ArticleFetcher::fetchArticleData($this->article);
28
29        /** @var ArticlePublishingService $publishingService */
30        $publishingService = resolve(ArticlePublishingService::class);
31
32        try {
33            $publishingService->publishToRoutedChannels($this->article, $extractedData);
34        } catch (PublishException $e) {
35            $this->fail($e);
36        }
37    }
38}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:52:46 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-with-models/Jobs/SyncChannelPostsJob.php.html b/backend/coverage-report-with-models/Jobs/SyncChannelPostsJob.php.html deleted file mode 100644 index deb862c8..00000000 --- a/backend/coverage-report-with-models/Jobs/SyncChannelPostsJob.php.html +++ /dev/null @@ -1,352 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Jobs/SyncChannelPostsJob.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 42
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 5
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
SyncChannelPostsJob
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 42
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 5
182
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 __construct
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 dispatchForAllActiveChannels
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 9
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 handle
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 5
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
6
 syncLemmyChannelPosts
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 16
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
20
 getAuthToken
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 11
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
30
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Jobs;
4
5use App\Enums\PlatformEnum;
6use App\Exceptions\PlatformAuthException;
7use App\Models\PlatformAccount;
8use App\Models\PlatformChannel;
9use App\Modules\Lemmy\Services\LemmyApiService;
10use App\Services\Log\LogSaver;
11use Exception;
12use Illuminate\Contracts\Queue\ShouldBeUnique;
13use Illuminate\Contracts\Queue\ShouldQueue;
14use Illuminate\Database\Eloquent\Collection;
15use Illuminate\Foundation\Queue\Queueable;
16use Illuminate\Support\Facades\Cache;
17
18class SyncChannelPostsJob implements ShouldQueue, ShouldBeUnique
19{
20    use Queueable;
21
22    public function __construct(
23        private readonly PlatformChannel $channel
24    ) {
25        $this->onQueue('sync');
26    }
27
28    public static function dispatchForAllActiveChannels(): void
29    {
30        PlatformChannel::with(['platformInstance', 'platformAccounts'])
31            ->whereHas('platformInstance', fn ($query) => $query->where('platform', PlatformEnum::LEMMY))
32            ->whereHas('platformAccounts', fn ($query) => $query->where('is_active', true))
33            ->where('is_active', true)
34            ->get()
35            ->each(function (PlatformChannel $channel) {
36                self::dispatch($channel);
37                LogSaver::info('Dispatched sync job for channel', $channel);
38            });
39    }
40
41    public function handle(): void
42    {
43        LogSaver::info('Starting channel posts sync job', $this->channel);
44
45        match ($this->channel->platformInstance->platform) {
46            PlatformEnum::LEMMY => $this->syncLemmyChannelPosts(),
47        };
48
49        LogSaver::info('Channel posts sync job completed', $this->channel);
50    }
51
52    /**
53     * @throws PlatformAuthException
54     */
55    private function syncLemmyChannelPosts(): void
56    {
57        try {
58            /** @var Collection<int, PlatformAccount> $accounts */
59            $accounts = $this->channel->activePlatformAccounts()->get();
60            $account = $accounts->first();
61
62            if (! $account) {
63                throw new PlatformAuthException(PlatformEnum::LEMMY, 'No active account found for channel');
64            }
65
66            $api = new LemmyApiService($this->channel->platformInstance->url);
67            $token = $this->getAuthToken($api, $account);
68
69            $platformChannelId = $this->channel->channel_id
70                ? $this->channel->channel_id
71                : $api->getCommunityId($this->channel->name, $token);
72
73            $api->syncChannelPosts($token, $platformChannelId, $this->channel->name);
74
75            LogSaver::info('Channel posts synced successfully', $this->channel);
76
77        } catch (Exception $e) {
78            LogSaver::error('Failed to sync channel posts', $this->channel, [
79                'error' => $e->getMessage()
80            ]);
81
82            throw $e;
83        }
84    }
85
86    /**
87     * @throws PlatformAuthException
88     */
89    private function getAuthToken(LemmyApiService $api, PlatformAccount $account): string
90    {
91        $cacheKey = "lemmy_jwt_token_{$account->id}";
92        $cachedToken = Cache::get($cacheKey);
93
94        if ($cachedToken) {
95            return $cachedToken;
96        }
97
98        if (!$account->username || !$account->password) {
99            throw new PlatformAuthException(PlatformEnum::LEMMY, 'Missing credentials for account');
100        }
101
102        $token = $api->login($account->username, $account->password);
103
104        if (!$token) {
105            throw new PlatformAuthException(PlatformEnum::LEMMY, 'Login failed for account');
106        }
107
108        Cache::put($cacheKey, $token, 3600);
109
110        return $token;
111    }
112}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:52:46 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-with-models/Jobs/dashboard.html b/backend/coverage-report-with-models/Jobs/dashboard.html deleted file mode 100644 index 9fd08277..00000000 --- a/backend/coverage-report-with-models/Jobs/dashboard.html +++ /dev/null @@ -1,308 +0,0 @@ - - - - - Dashboard for /var/www/html/backend/app/Jobs - - - - - - - -
-
-
-
- -
-
-
-
-
-
-
-

Classes

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
-
-
-

Insufficient Coverage

- -
-
-

Project Risks

- -
-
-
-
-

Methods

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
-
-
-

Insufficient Coverage

- -
-
-

Project Risks

-
- - - - - - - - - - - - - - - -
MethodCRAP
getAuthToken30
syncLemmyChannelPosts20
handle6
handle6
handle6
-
-
-
- -
- - - - - - diff --git a/backend/coverage-report-with-models/Jobs/index.html b/backend/coverage-report-with-models/Jobs/index.html deleted file mode 100644 index 5d4e292f..00000000 --- a/backend/coverage-report-with-models/Jobs/index.html +++ /dev/null @@ -1,203 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Jobs - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 81
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 12
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 4
ArticleDiscoveryForFeedJob.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 26
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
ArticleDiscoveryJob.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 7
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
PublishToLemmyJob.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 6
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
SyncChannelPostsJob.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 42
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 5
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- -
- - diff --git a/backend/coverage-report-with-models/Listeners/LogExceptionToDatabase.php.html b/backend/coverage-report-with-models/Listeners/LogExceptionToDatabase.php.html deleted file mode 100644 index a3fe81ec..00000000 --- a/backend/coverage-report-with-models/Listeners/LogExceptionToDatabase.php.html +++ /dev/null @@ -1,179 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Listeners/LogExceptionToDatabase.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 12
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
LogExceptionToDatabase
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 12
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 handle
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 12
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Listeners;
4
5use App\Events\ExceptionLogged;
6use App\Events\ExceptionOccurred;
7use App\Models\Log;
8class LogExceptionToDatabase
9{
10
11    public function handle(ExceptionOccurred $event): void
12    {
13        $log = Log::create([
14            'level' => $event->level,
15            'message' => $event->message,
16            'context' => [
17                'exception_class' => get_class($event->exception),
18                'file' => $event->exception->getFile(),
19                'line' => $event->exception->getLine(),
20                'trace' => $event->exception->getTraceAsString(),
21                ...$event->context
22            ]
23        ]);
24
25        ExceptionLogged::dispatch($log);
26    }
27}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:52:46 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-with-models/Listeners/PublishApprovedArticle.php.html b/backend/coverage-report-with-models/Listeners/PublishApprovedArticle.php.html deleted file mode 100644 index bccac177..00000000 --- a/backend/coverage-report-with-models/Listeners/PublishApprovedArticle.php.html +++ /dev/null @@ -1,179 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Listeners/PublishApprovedArticle.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 5
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
PublishApprovedArticle
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 5
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
20
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 handle
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 5
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
20
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Listeners;
4
5use App\Events\ArticleApproved;
6use App\Events\ArticleReadyToPublish;
7use Illuminate\Contracts\Queue\ShouldQueue;
8
9class PublishApprovedArticle implements ShouldQueue
10{
11    public string $queue = 'default';
12
13    public function handle(ArticleApproved $event): void
14    {
15        $article = $event->article;
16
17        // Skip if already has publication (prevents duplicate processing)
18        if ($article->articlePublication()->exists()) {
19            return;
20        }
21
22        // Only publish if the article is valid and approved
23        if ($article->isValid() && $article->isApproved()) {
24            event(new ArticleReadyToPublish($article));
25        }
26    }
27}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:52:46 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-with-models/Listeners/PublishArticle.php.html b/backend/coverage-report-with-models/Listeners/PublishArticle.php.html deleted file mode 100644 index ca5375b4..00000000 --- a/backend/coverage-report-with-models/Listeners/PublishArticle.php.html +++ /dev/null @@ -1,213 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Listeners/PublishArticle.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 13
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
PublishArticle
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 13
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
12
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 __construct
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 handle
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 12
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
6
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Listeners;
4
5use App\Events\ArticleReadyToPublish;
6use App\Jobs\PublishToLemmyJob;
7use Illuminate\Contracts\Queue\ShouldQueue;
8
9class PublishArticle implements ShouldQueue
10{
11    public string|null $queue = 'lemmy-publish';
12    public int $delay = 300;
13    public int $tries = 3;
14    public int $backoff = 300;
15
16    public function __construct()
17    {}
18
19    public function handle(ArticleReadyToPublish $event): void
20    {
21        $article = $event->article;
22
23        if ($article->articlePublication()->exists()) {
24            logger()->info('Article already published, skipping job dispatch', [
25                'article_id' => $article->id,
26                'url' => $article->url
27            ]);
28
29            return;
30        }
31
32        logger()->info('Article queued for publishing to Lemmy', [
33            'article_id' => $article->id,
34            'url' => $article->url
35        ]);
36
37        PublishToLemmyJob::dispatch($article);
38    }
39}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:52:46 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-with-models/Listeners/ValidateArticleListener.php.html b/backend/coverage-report-with-models/Listeners/ValidateArticleListener.php.html deleted file mode 100644 index 38dc082e..00000000 --- a/backend/coverage-report-with-models/Listeners/ValidateArticleListener.php.html +++ /dev/null @@ -1,201 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Listeners/ValidateArticleListener.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 13
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
ValidateArticleListener
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 13
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
56
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 handle
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 13
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
56
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Listeners;
4
5use App\Events\NewArticleFetched;
6use App\Events\ArticleReadyToPublish;
7use App\Models\Setting;
8use App\Services\Article\ValidationService;
9use Illuminate\Contracts\Queue\ShouldQueue;
10
11class ValidateArticleListener implements ShouldQueue
12{
13    public string $queue = 'default';
14
15    public function handle(NewArticleFetched $event): void
16    {
17        $article = $event->article;
18
19        if (! is_null($article->validated_at)) {
20            return;
21        }
22
23        // Skip if already has publication (prevents duplicate processing)
24        if ($article->articlePublication()->exists()) {
25            return;
26        }
27
28        $article = ValidationService::validate($article);
29
30        if ($article->isValid()) {
31            // Double-check publication doesn't exist (race condition protection)
32            if ($article->articlePublication()->exists()) {
33                return;
34            }
35
36            // Check if approval system is enabled
37            if (Setting::isPublishingApprovalsEnabled()) {
38                // If approvals are enabled, only proceed if article is approved
39                if ($article->isApproved()) {
40                    event(new ArticleReadyToPublish($article));
41                }
42                // If not approved, article will wait for manual approval
43            } else {
44                // If approvals are disabled, proceed with publishing
45                event(new ArticleReadyToPublish($article));
46            }
47        }
48    }
49}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:52:46 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-with-models/Listeners/dashboard.html b/backend/coverage-report-with-models/Listeners/dashboard.html deleted file mode 100644 index f07230ca..00000000 --- a/backend/coverage-report-with-models/Listeners/dashboard.html +++ /dev/null @@ -1,299 +0,0 @@ - - - - - Dashboard for /var/www/html/backend/app/Listeners - - - - - - - -
-
-
-
- -
-
-
-
-
-
-
-

Classes

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
- -
-
-

Methods

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
-
-
-

Insufficient Coverage

-
- - - - - - - - - - - - - - - -
MethodCoverage
handle0%
handle0%
__construct0%
handle0%
handle0%
-
-
-
-

Project Risks

-
- - - - - - - - - - - - - -
MethodCRAP
handle56
handle20
handle6
-
-
-
- -
- - - - - - diff --git a/backend/coverage-report-with-models/Listeners/index.html b/backend/coverage-report-with-models/Listeners/index.html deleted file mode 100644 index 6e65dcaf..00000000 --- a/backend/coverage-report-with-models/Listeners/index.html +++ /dev/null @@ -1,203 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Listeners - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 43
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 5
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 4
LogExceptionToDatabase.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 12
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
PublishApprovedArticle.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 5
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
PublishArticle.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 13
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
ValidateArticleListener.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 13
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- -
- - diff --git a/backend/coverage-report-with-models/LogLevelEnum.php.html b/backend/coverage-report-with-models/LogLevelEnum.php.html deleted file mode 100644 index 2fd9b654..00000000 --- a/backend/coverage-report-with-models/LogLevelEnum.php.html +++ /dev/null @@ -1,177 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/LogLevelEnum.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 100.00% covered (success) -
-
-
100.00%
7 / 7
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
CRAP
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
LogLevelEnum
-
- 100.00% covered (success) -
-
-
100.00%
7 / 7
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
1
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
 toArray
-
- 100.00% covered (success) -
-
-
100.00%
7 / 7
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
1
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App;
4
5enum LogLevelEnum: string
6{
7    case DEBUG = 'debug';
8    case INFO = 'info';
9    case WARNING = 'warning';
10    case ERROR = 'error';
11    case CRITICAL = 'critical';
12
13    /**
14     * @return array<int, string>
15     */
16    public static function toArray(): array
17    {
18        return [
19            self::DEBUG->value,
20            self::INFO->value,
21            self::WARNING->value,
22            self::ERROR->value,
23            self::CRITICAL->value,
24        ];
25    }
26}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:52:46 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-with-models/Models/Article.php.html b/backend/coverage-report-with-models/Models/Article.php.html deleted file mode 100644 index a7cd7620..00000000 --- a/backend/coverage-report-with-models/Models/Article.php.html +++ /dev/null @@ -1,522 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Models/Article.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 66.67% covered (warning) -
-
-
66.67%
26 / 39
-
- 54.55% covered (warning) -
-
-
54.55%
6 / 11
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
Article
-
- 66.67% covered (warning) -
-
-
66.67%
26 / 39
-
- 54.55% covered (warning) -
-
-
54.55%
6 / 11
23.33
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 casts
-
- 100.00% covered (success) -
-
-
100.00%
10 / 10
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
1
 isValid
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 5
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
12
 isApproved
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 isPending
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 isRejected
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 approve
-
- 100.00% covered (success) -
-
-
100.00%
6 / 6
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
1
 reject
-
- 100.00% covered (success) -
-
-
100.00%
5 / 5
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
1
 canBePublished
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 5
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
12
 articlePublication
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
1
 feed
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
1
 booted
-
- 100.00% covered (success) -
-
-
100.00%
3 / 3
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
1
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Models;
4
5use App\Events\ArticleApproved;
6use App\Events\NewArticleFetched;
7use Database\Factories\ArticleFactory;
8use Illuminate\Database\Eloquent\Factories\HasFactory;
9use Illuminate\Database\Eloquent\Model;
10use Illuminate\Database\Eloquent\Relations\BelongsTo;
11use Illuminate\Database\Eloquent\Relations\HasOne;
12use Illuminate\Support\Carbon;
13
14/**
15 * @method static firstOrCreate(array<string, mixed> $array)
16 * @method static where(string $string, string $url)
17 * @method static create(array<string, mixed> $array)
18 * @property integer $id
19 * @property int $feed_id
20 * @property Feed $feed
21 * @property string $url
22 * @property bool|null $is_valid
23 * @property Carbon|null $validated_at
24 * @property Carbon $created_at
25 * @property Carbon $updated_at
26 * @property ArticlePublication $articlePublication
27 */
28class Article extends Model
29{
30    /** @use HasFactory<ArticleFactory> */
31    use HasFactory;
32
33    protected $fillable = [
34        'feed_id',
35        'url',
36        'title',
37        'description',
38        'is_valid',
39        'is_duplicate',
40        'approval_status',
41        'approved_at',
42        'approved_by',
43        'fetched_at',
44        'validated_at',
45    ];
46
47    /**
48     * @return array<string, string>
49     */
50    public function casts(): array
51    {
52        return [
53            'is_valid' => 'boolean',
54            'is_duplicate' => 'boolean',
55            'approval_status' => 'string',
56            'approved_at' => 'datetime',
57            'fetched_at' => 'datetime',
58            'validated_at' => 'datetime',
59            'created_at' => 'datetime',
60            'updated_at' => 'datetime',
61        ];
62    }
63
64    public function isValid(): bool
65    {
66        if (is_null($this->validated_at)) {
67            return false;
68        }
69
70        if (is_null($this->is_valid)) {
71            return false;
72        }
73
74        return $this->is_valid;
75    }
76
77    public function isApproved(): bool
78    {
79        return $this->approval_status === 'approved';
80    }
81
82    public function isPending(): bool
83    {
84        return $this->approval_status === 'pending';
85    }
86
87    public function isRejected(): bool
88    {
89        return $this->approval_status === 'rejected';
90    }
91
92    public function approve(string $approvedBy = null): void
93    {
94        $this->update([
95            'approval_status' => 'approved',
96            'approved_at' => now(),
97            'approved_by' => $approvedBy,
98        ]);
99
100        // Fire event to trigger publishing
101        event(new ArticleApproved($this));
102    }
103
104    public function reject(string $rejectedBy = null): void
105    {
106        $this->update([
107            'approval_status' => 'rejected',
108            'approved_at' => now(),
109            'approved_by' => $rejectedBy,
110        ]);
111    }
112
113    public function canBePublished(): bool
114    {
115        if (!$this->isValid()) {
116            return false;
117        }
118
119        // If approval system is disabled, auto-approve valid articles
120        if (!\App\Models\Setting::isPublishingApprovalsEnabled()) {
121            return true;
122        }
123
124        // If approval system is enabled, only approved articles can be published
125        return $this->isApproved();
126    }
127
128    /**
129     * @return HasOne<ArticlePublication, $this>
130     */
131    public function articlePublication(): HasOne
132    {
133        return $this->hasOne(ArticlePublication::class);
134    }
135
136    /**
137     * @return BelongsTo<Feed, $this>
138     */
139    public function feed(): BelongsTo
140    {
141        return $this->belongsTo(Feed::class);
142    }
143
144    protected static function booted(): void
145    {
146        static::created(function ($article) {
147            event(new NewArticleFetched($article));
148        });
149    }
150}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:52:46 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-with-models/Models/ArticlePublication.php.html b/backend/coverage-report-with-models/Models/ArticlePublication.php.html deleted file mode 100644 index 9ce7c530..00000000 --- a/backend/coverage-report-with-models/Models/ArticlePublication.php.html +++ /dev/null @@ -1,196 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Models/ArticlePublication.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
ArticlePublication
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 article
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Models;
4
5use Database\Factories\ArticlePublicationFactory;
6use Illuminate\Database\Eloquent\Factories\HasFactory;
7use Illuminate\Database\Eloquent\Model;
8use Illuminate\Database\Eloquent\Relations\BelongsTo;
9
10/**
11 * @property integer $article_id
12 * @property integer $platform_channel_id
13 * @property integer $post_id
14 *
15 * @method static create(array<string, mixed> $array)
16 */
17class ArticlePublication extends Model
18{
19    /** @use HasFactory<ArticlePublicationFactory> */
20    use HasFactory;
21    
22    protected $fillable = [
23        'article_id',
24        'platform_channel_id',
25        'post_id',
26        'published_at',
27        'published_by',
28        'platform',
29        'publication_data',
30    ];
31
32    protected $casts = [
33        'published_at' => 'datetime',
34        'publication_data' => 'array',
35    ];
36
37    /**
38     * @return BelongsTo<Article, $this>
39     */
40    public function article(): BelongsTo
41    {
42        return $this->belongsTo(Article::class);
43    }
44}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:52:46 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-with-models/Models/Feed.php.html b/backend/coverage-report-with-models/Models/Feed.php.html deleted file mode 100644 index d1c5559a..00000000 --- a/backend/coverage-report-with-models/Models/Feed.php.html +++ /dev/null @@ -1,382 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Models/Feed.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 4.17% covered (danger) -
-
-
4.17%
1 / 24
-
- 16.67% covered (danger) -
-
-
16.67%
1 / 6
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
Feed
-
- 4.17% covered (danger) -
-
-
4.17%
1 / 24
-
- 16.67% covered (danger) -
-
-
16.67%
1 / 6
161.74
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 getTypeDisplayAttribute
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 5
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
20
 getStatusAttribute
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 10
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
30
 channels
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 4
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 activeChannels
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 articles
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
1
 language
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Models;
4
5use Database\Factories\FeedFactory;
6use Illuminate\Database\Eloquent\Factories\HasFactory;
7use Illuminate\Database\Eloquent\Model;
8use Illuminate\Database\Eloquent\Relations\BelongsTo;
9use Illuminate\Database\Eloquent\Relations\BelongsToMany;
10use Illuminate\Database\Eloquent\Relations\HasMany;
11use Illuminate\Support\Carbon;
12
13/**
14 * @property int $id
15 * @property string $name
16 * @property string $url
17 * @property string $type
18 * @property int $language_id
19 * @property Language|null $language
20 * @property string $description
21 * @property array<string, mixed> $settings
22 * @property bool $is_active
23 * @property Carbon|null $last_fetched_at
24 * @property Carbon $created_at
25 * @property Carbon $updated_at
26 * @method static orderBy(string $string, string $string1)
27 * @method static where(string $string, true $true)
28 * @method static findOrFail(mixed $feed_id)
29 */
30class Feed extends Model
31{
32    /** @use HasFactory<FeedFactory> */
33    use HasFactory;
34    private const RECENT_FETCH_THRESHOLD_HOURS = 2;
35    private const DAILY_FETCH_THRESHOLD_HOURS = 24;
36
37    protected $fillable = [
38        'name',
39        'url',
40        'type',
41        'language_id',
42        'description',
43        'settings',
44        'is_active',
45        'last_fetched_at'
46    ];
47
48    protected $casts = [
49        'settings' => 'array',
50        'is_active' => 'boolean',
51        'last_fetched_at' => 'datetime'
52    ];
53
54    public function getTypeDisplayAttribute(): string
55    {
56        return match ($this->type) {
57            'website' => 'Website',
58            'rss' => 'RSS Feed',
59            default => 'Unknown'
60        };
61    }
62
63    public function getStatusAttribute(): string
64    {
65        if (!$this->is_active) {
66            return 'Inactive';
67        }
68
69        if (!$this->last_fetched_at) {
70            return 'Never fetched';
71        }
72
73        $hoursAgo = $this->last_fetched_at->diffInHours(now());
74
75        if ($hoursAgo < self::RECENT_FETCH_THRESHOLD_HOURS) {
76            return 'Recently fetched';
77        } elseif ($hoursAgo < self::DAILY_FETCH_THRESHOLD_HOURS) {
78            return "Fetched {$hoursAgo}h ago";
79        } else {
80            return "Fetched " . $this->last_fetched_at->diffForHumans();
81        }
82    }
83
84    /**
85     * @return BelongsToMany<PlatformChannel, $this, Route>
86     */
87    public function channels(): BelongsToMany
88    {
89        return $this->belongsToMany(PlatformChannel::class, 'routes')
90            ->using(Route::class)
91            ->withPivot(['is_active', 'priority', 'filters'])
92            ->withTimestamps();
93    }
94
95    /**
96     * @return BelongsToMany<PlatformChannel, $this, Route>
97     */
98    public function activeChannels(): BelongsToMany
99    {
100        return $this->channels()
101            ->wherePivot('is_active', true)
102            ->orderByPivot('priority', 'desc');
103    }
104
105    /**
106     * @return HasMany<Article, $this>
107     */
108    public function articles(): HasMany
109    {
110        return $this->hasMany(Article::class);
111    }
112
113    /**
114     * @return BelongsTo<Language, $this>
115     */
116    public function language(): BelongsTo
117    {
118        return $this->belongsTo(Language::class);
119    }
120}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:52:46 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-with-models/Models/Keyword.php.html b/backend/coverage-report-with-models/Models/Keyword.php.html deleted file mode 100644 index 92323d4a..00000000 --- a/backend/coverage-report-with-models/Models/Keyword.php.html +++ /dev/null @@ -1,223 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Models/Keyword.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
Keyword
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
6
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 feed
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 platformChannel
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Models;
4
5use Illuminate\Database\Eloquent\Model;
6use Illuminate\Database\Eloquent\Relations\BelongsTo;
7use Illuminate\Support\Carbon;
8
9/**
10 * @property int $id
11 * @property int $feed_id
12 * @property Feed $feed
13 * @property int $platform_channel_id
14 * @property PlatformChannel $platformChannel
15 * @property string $keyword
16 * @property bool $is_active
17 * @property Carbon $created_at
18 * @property Carbon $updated_at
19 */
20class Keyword extends Model
21{
22    protected $fillable = [
23        'feed_id',
24        'platform_channel_id',
25        'keyword',
26        'is_active'
27    ];
28
29    protected $casts = [
30        'is_active' => 'boolean'
31    ];
32
33    /**
34     * @return BelongsTo<Feed, $this>
35     */
36    public function feed(): BelongsTo
37    {
38        return $this->belongsTo(Feed::class);
39    }
40
41    /**
42     * @return BelongsTo<PlatformChannel, $this>
43     */
44    public function platformChannel(): BelongsTo
45    {
46        return $this->belongsTo(PlatformChannel::class);
47    }
48
49}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:52:46 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-with-models/Models/Language.php.html b/backend/coverage-report-with-models/Models/Language.php.html deleted file mode 100644 index 69099c4d..00000000 --- a/backend/coverage-report-with-models/Models/Language.php.html +++ /dev/null @@ -1,248 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Models/Language.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 5
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
Language
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 5
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
12
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 platformInstances
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 platformChannels
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 feeds
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Models;
4
5use Database\Factories\LanguageFactory;
6use Illuminate\Database\Eloquent\Factories\HasFactory;
7use Illuminate\Database\Eloquent\Model;
8use Illuminate\Database\Eloquent\Relations\BelongsToMany;
9use Illuminate\Database\Eloquent\Relations\HasMany;
10
11class Language extends Model
12{
13    /** @use HasFactory<LanguageFactory> */
14    use HasFactory;
15
16    protected $fillable = [
17        'short_code',
18        'name', 
19        'native_name',
20        'is_active'
21    ];
22
23    protected $casts = [
24        'is_active' => 'boolean'
25    ];
26
27    /**
28     * @return BelongsToMany<PlatformInstance, $this>
29     */
30    public function platformInstances(): BelongsToMany
31    {
32        return $this->belongsToMany(PlatformInstance::class)
33            ->withPivot(['platform_language_id', 'is_default'])
34            ->withTimestamps();
35    }
36
37    /**
38     * @return HasMany<PlatformChannel, $this>
39     */
40    public function platformChannels(): HasMany
41    {
42        return $this->hasMany(PlatformChannel::class);
43    }
44
45    /**
46     * @return HasMany<Feed, $this>
47     */
48    public function feeds(): HasMany
49    {
50        return $this->hasMany(Feed::class);
51    }
52}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:52:46 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-with-models/Models/Log.php.html b/backend/coverage-report-with-models/Models/Log.php.html deleted file mode 100644 index 52536eaa..00000000 --- a/backend/coverage-report-with-models/Models/Log.php.html +++ /dev/null @@ -1,136 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Models/Log.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
n/a
0 / 0
n/a
0 / 0
CRAP
n/a
0 / 0
Log
n/a
0 / 0
n/a
0 / 0
0
n/a
0 / 0
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Models;
4
5use App\LogLevelEnum;
6use Illuminate\Database\Eloquent\Factories\HasFactory;
7use Illuminate\Database\Eloquent\Model;
8use Illuminate\Support\Carbon;
9
10/**
11 * @method static create(array<string, mixed> $array)
12 * @property LogLevelEnum $level
13 * @property string $message
14 * @property array<string, mixed> $context
15 * @property Carbon $created_at
16 * @property Carbon $updated_at
17 */
18class Log extends Model
19{
20    use HasFactory;
21    
22    protected $table = 'logs';
23
24    protected $fillable = [
25        'level',
26        'message',
27        'context',
28    ];
29
30    protected $casts = [
31        'level' => LogLevelEnum::class,
32        'context' => 'array',
33        'created_at' => 'datetime',
34        'updated_at' => 'datetime',
35    ];
36}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:52:46 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-with-models/Models/PlatformAccount.php.html b/backend/coverage-report-with-models/Models/PlatformAccount.php.html deleted file mode 100644 index f401728a..00000000 --- a/backend/coverage-report-with-models/Models/PlatformAccount.php.html +++ /dev/null @@ -1,384 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Models/PlatformAccount.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 21
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 6
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
PlatformAccount
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 21
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 6
110
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 password
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 4
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
12
 apiToken
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 4
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
12
 getActive
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 setAsActive
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 4
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 channels
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 activeChannels
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Models;
4
5use Database\Factories\PlatformAccountFactory;
6use Illuminate\Database\Eloquent\Factories\HasFactory;
7use Illuminate\Database\Eloquent\Model;
8use Illuminate\Database\Eloquent\Casts\Attribute;
9use Illuminate\Database\Eloquent\Collection;
10use Illuminate\Database\Eloquent\Relations\BelongsToMany;
11use Illuminate\Support\Carbon;
12use Illuminate\Support\Facades\Crypt;
13use App\Enums\PlatformEnum;
14
15/**
16 * @property int $id
17 * @property PlatformEnum $platform
18 * @property string $instance_url
19 * @property string $username
20 * @property string $password
21 * @property string $settings
22 * @property bool $is_active
23 * @property Carbon $last_tested_at
24 * @property string $status
25 * @property Carbon $created_at
26 * @property Carbon $updated_at
27 * @property Collection<int, PlatformChannel> $activeChannels
28 * @method static where(string $string, PlatformEnum $platform)
29 * @method static orderBy(string $string)
30 * @method static create(array<string, mixed> $validated)
31 */
32class PlatformAccount extends Model
33{
34    /** @use HasFactory<PlatformAccountFactory> */
35    use HasFactory;
36
37    protected $fillable = [
38        'platform',
39        'instance_url',
40        'username',
41        'password',
42        'api_token',
43        'settings',
44        'is_active',
45        'last_tested_at',
46        'status'
47    ];
48
49    protected $casts = [
50        'platform' => PlatformEnum::class,
51        'settings' => 'array',
52        'is_active' => 'boolean',
53        'last_tested_at' => 'datetime'
54    ];
55
56    // Encrypt password when storing
57    /**
58     * @return Attribute<string|null, string|null>
59     */
60    protected function password(): Attribute
61    {
62        return Attribute::make(
63            get: fn ($value) => $value ? Crypt::decryptString($value) : null,
64            set: fn ($value) => $value ? Crypt::encryptString($value) : null,
65        );
66    }
67
68    // Encrypt API token when storing
69    /**
70     * @return Attribute<string|null, string|null>
71     */
72    protected function apiToken(): Attribute
73    {
74        return Attribute::make(
75            get: fn ($value) => $value ? Crypt::decryptString($value) : null,
76            set: fn ($value) => $value ? Crypt::encryptString($value) : null,
77        );
78    }
79
80    // Get the active accounts for a platform (returns collection)
81    /**
82     * @return Collection<int, PlatformAccount>
83     */
84    public static function getActive(PlatformEnum $platform): Collection
85    {
86        return static::where('platform', $platform)
87            ->where('is_active', true)
88            ->get();
89    }
90
91    // Set this account as active (deactivates others for same platform)
92    public function setAsActive(): void
93    {
94        // Deactivate other accounts for this platform
95        static::where('platform', $this->platform)
96            ->where('id', '!=', $this->id)
97            ->update(['is_active' => false]);
98
99        // Activate this account
100        $this->update(['is_active' => true]);
101    }
102
103    /**
104     * @return BelongsToMany<PlatformChannel, $this>
105     */
106    public function channels(): BelongsToMany
107    {
108        return $this->belongsToMany(PlatformChannel::class, 'platform_account_channels')
109            ->withPivot(['is_active', 'priority'])
110            ->withTimestamps();
111    }
112
113    /**
114     * @return BelongsToMany<PlatformChannel, $this>
115     */
116    public function activeChannels(): BelongsToMany
117    {
118        return $this->channels()
119            ->wherePivot('is_active', true)
120            ->orderByPivot('priority', 'desc');
121    }
122}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:52:46 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-with-models/Models/PlatformChannel.php.html b/backend/coverage-report-with-models/Models/PlatformChannel.php.html deleted file mode 100644 index 3fb9971d..00000000 --- a/backend/coverage-report-with-models/Models/PlatformChannel.php.html +++ /dev/null @@ -1,387 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Models/PlatformChannel.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 14
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 7
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
PlatformChannel
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 14
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 7
56
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 platformInstance
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 platformAccounts
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 activePlatformAccounts
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 getFullNameAttribute
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 feeds
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 4
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 activeFeeds
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 language
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Models;
4
5use Database\Factories\PlatformChannelFactory;
6use Illuminate\Database\Eloquent\Factories\HasFactory;
7use Illuminate\Database\Eloquent\Model;
8use Illuminate\Database\Eloquent\Relations\BelongsTo;
9use Illuminate\Database\Eloquent\Relations\BelongsToMany;
10
11/**
12 * @method static findMany(mixed $channel_ids)
13 * @property integer $id
14 * @property integer $platform_instance_id
15 * @property PlatformInstance $platformInstance
16 * @property integer $channel_id
17 * @property string $name
18 * @property int $language_id
19 * @property Language|null $language
20 * @property boolean $is_active
21 */
22class PlatformChannel extends Model
23{
24    /** @use HasFactory<PlatformChannelFactory> */
25    use HasFactory;
26
27    protected $table = 'platform_channels';
28
29    protected $fillable = [
30        'platform_instance_id',
31        'name',
32        'display_name',
33        'channel_id',
34        'description',
35        'language_id',
36        'is_active'
37    ];
38
39    protected $casts = [
40        'is_active' => 'boolean'
41    ];
42
43    /**
44     * @return BelongsTo<PlatformInstance, $this>
45     */
46    public function platformInstance(): BelongsTo
47    {
48        return $this->belongsTo(PlatformInstance::class);
49    }
50
51    /**
52     * @return BelongsToMany<PlatformAccount, $this>
53     */
54    public function platformAccounts(): BelongsToMany
55    {
56        return $this->belongsToMany(PlatformAccount::class, 'platform_account_channels')
57            ->withPivot(['is_active', 'priority'])
58            ->withTimestamps();
59    }
60
61    /**
62     * @return BelongsToMany<PlatformAccount, $this>
63     */
64    public function activePlatformAccounts(): BelongsToMany
65    {
66        return $this->platformAccounts()->wherePivot('is_active', true);
67    }
68
69    public function getFullNameAttribute(): string
70    {
71        // For Lemmy, use /c/ prefix
72        return $this->platformInstance->url . '/c/' . $this->name;
73    }
74
75    /**
76     * @return BelongsToMany<Feed, $this, Route>
77     */
78    public function feeds(): BelongsToMany
79    {
80        return $this->belongsToMany(Feed::class, 'routes')
81            ->using(Route::class)
82            ->withPivot(['is_active', 'priority', 'filters'])
83            ->withTimestamps();
84    }
85
86    /**
87     * @return BelongsToMany<Feed, $this, Route>
88     */
89    public function activeFeeds(): BelongsToMany
90    {
91        return $this->feeds()
92            ->wherePivot('is_active', true)
93            ->orderByPivot('priority', 'desc');
94    }
95
96    /**
97     * @return BelongsTo<Language, $this>
98     */
99    public function language(): BelongsTo
100    {
101        return $this->belongsTo(Language::class);
102    }
103}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:52:46 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-with-models/Models/PlatformChannelPost.php.html b/backend/coverage-report-with-models/Models/PlatformChannelPost.php.html deleted file mode 100644 index b0efe196..00000000 --- a/backend/coverage-report-with-models/Models/PlatformChannelPost.php.html +++ /dev/null @@ -1,255 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Models/PlatformChannelPost.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 21
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
PlatformChannelPost
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 21
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
12
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 casts
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 4
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 urlExists
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 4
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 storePost
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 13
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Models;
4
5use App\Enums\PlatformEnum;
6use Illuminate\Database\Eloquent\Model;
7
8/**
9 * @method static where(string $string, PlatformEnum $platform)
10 * @method static updateOrCreate(array<string, mixed> $array, array<string, mixed> $array1)
11 */
12class PlatformChannelPost extends Model
13{
14    protected $fillable = [
15        'platform',
16        'channel_id',
17        'channel_name',
18        'post_id',
19        'url',
20        'title',
21        'posted_at',
22    ];
23
24    /**
25     * @return array<string, string>
26     */
27    protected function casts(): array
28    {
29        return [
30            'posted_at' => 'datetime',
31            'platform' => PlatformEnum::class,
32        ];
33    }
34
35    public static function urlExists(PlatformEnum $platform, string $channelId, string $url): bool
36    {
37        return self::where('platform', $platform)
38            ->where('channel_id', $channelId)
39            ->where('url', $url)
40            ->exists();
41    }
42
43    public static function storePost(PlatformEnum $platform, string $channelId, ?string $channelName, string $postId, ?string $url, ?string $title, ?\DateTime $postedAt = null): self
44    {
45        return self::updateOrCreate(
46            [
47                'platform' => $platform,
48                'channel_id' => $channelId,
49                'post_id' => $postId,
50            ],
51            [
52                'channel_name' => $channelName,
53                'url' => $url,
54                'title' => $title,
55                'posted_at' => $postedAt ?? now(),
56            ]
57        );
58    }
59}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:52:46 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-with-models/Models/PlatformInstance.php.html b/backend/coverage-report-with-models/Models/PlatformInstance.php.html deleted file mode 100644 index b51e2d8d..00000000 --- a/backend/coverage-report-with-models/Models/PlatformInstance.php.html +++ /dev/null @@ -1,259 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Models/PlatformInstance.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 7
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
PlatformInstance
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 7
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
12
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 channels
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 languages
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 findByUrl
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Models;
4
5use App\Enums\PlatformEnum;
6use Database\Factories\PlatformInstanceFactory;
7use Illuminate\Database\Eloquent\Factories\HasFactory;
8use Illuminate\Database\Eloquent\Model;
9use Illuminate\Database\Eloquent\Relations\BelongsToMany;
10use Illuminate\Database\Eloquent\Relations\HasMany;
11
12/**
13 * @method static updateOrCreate(array<string, mixed> $array, $instanceData)
14 * @method static where(string $string, mixed $operator)
15 * @property PlatformEnum $platform
16 * @property string $url
17 * @property string $name
18 * @property string $description
19 * @property boolean $is_active
20 */
21class PlatformInstance extends Model
22{
23    /** @use HasFactory<PlatformInstanceFactory> */
24    use HasFactory;
25    
26    protected $fillable = [
27        'platform',
28        'url',
29        'name',
30        'description',
31        'is_active'
32    ];
33
34    protected $casts = [
35        'platform' => PlatformEnum::class,
36        'is_active' => 'boolean'
37    ];
38
39    /**
40     * @return HasMany<PlatformChannel, $this>
41     */
42    public function channels(): HasMany
43    {
44        return $this->hasMany(PlatformChannel::class);
45    }
46
47    /**
48     * @return BelongsToMany<Language, $this>
49     */
50    public function languages(): BelongsToMany
51    {
52        return $this->belongsToMany(Language::class)
53            ->withPivot(['platform_language_id', 'is_default'])
54            ->withTimestamps();
55    }
56
57    public static function findByUrl(PlatformEnum $platform, string $url): ?self
58    {
59        return static::where('platform', $platform)
60            ->where('url', $url)
61            ->first();
62    }
63}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:52:46 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-with-models/Models/Route.php.html b/backend/coverage-report-with-models/Models/Route.php.html deleted file mode 100644 index f7b0f445..00000000 --- a/backend/coverage-report-with-models/Models/Route.php.html +++ /dev/null @@ -1,263 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Models/Route.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 4
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
Route
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 4
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
12
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 feed
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 platformChannel
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 keywords
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Models;
4
5use Database\Factories\RouteFactory;
6use Illuminate\Database\Eloquent\Factories\HasFactory;
7use Illuminate\Database\Eloquent\Relations\BelongsTo;
8use Illuminate\Database\Eloquent\Relations\HasMany;
9use Illuminate\Database\Eloquent\Relations\Pivot;
10use Illuminate\Support\Carbon;
11
12/**
13 * @property int $feed_id
14 * @property int $platform_channel_id
15 * @property bool $is_active
16 * @property int $priority
17 * @property array<string, mixed> $filters
18 * @property Carbon $created_at
19 * @property Carbon $updated_at
20 */
21class Route extends Pivot
22{
23    /** @use HasFactory<RouteFactory> */
24    use HasFactory;
25    
26    protected $table = 'routes';
27
28    public $incrementing = false;
29
30    protected $fillable = [
31        'feed_id',
32        'platform_channel_id',
33        'is_active',
34        'priority',
35        'filters'
36    ];
37
38    protected $casts = [
39        'is_active' => 'boolean',
40        'filters' => 'array'
41    ];
42
43    /**
44     * @return BelongsTo<Feed, $this>
45     */
46    public function feed(): BelongsTo
47    {
48        return $this->belongsTo(Feed::class);
49    }
50
51    /**
52     * @return BelongsTo<PlatformChannel, $this>
53     */
54    public function platformChannel(): BelongsTo
55    {
56        return $this->belongsTo(PlatformChannel::class);
57    }
58
59    /**
60     * @return HasMany<Keyword, $this>
61     */
62    public function keywords(): HasMany
63    {
64        return $this->hasMany(Keyword::class, 'feed_id', 'feed_id')
65            ->where('platform_channel_id', $this->platform_channel_id);
66    }
67}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:52:46 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-with-models/Models/Setting.php.html b/backend/coverage-report-with-models/Models/Setting.php.html deleted file mode 100644 index 5341d9d8..00000000 --- a/backend/coverage-report-with-models/Models/Setting.php.html +++ /dev/null @@ -1,360 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Models/Setting.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 100.00% covered (success) -
-
-
100.00%
10 / 10
-
- 100.00% covered (success) -
-
-
100.00%
8 / 8
CRAP
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
Setting
-
- 100.00% covered (success) -
-
-
100.00%
10 / 10
-
- 100.00% covered (success) -
-
-
100.00%
8 / 8
10
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
 get
-
- 100.00% covered (success) -
-
-
100.00%
2 / 2
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
2
 set
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
1
 getBool
-
- 100.00% covered (success) -
-
-
100.00%
2 / 2
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
1
 setBool
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
2
 isArticleProcessingEnabled
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
1
 setArticleProcessingEnabled
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
1
 isPublishingApprovalsEnabled
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
1
 setPublishingApprovalsEnabled
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
1
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Models;
4
5use Illuminate\Database\Eloquent\Model;
6
7class Setting extends Model
8{
9    protected $fillable = ['key', 'value'];
10
11    public static function get(string $key, mixed $default = null): mixed
12    {
13        $setting = static::where('key', $key)->first();
14        
15        return $setting ? $setting->value : $default;
16    }
17
18    public static function set(string $key, mixed $value): void
19    {
20        static::updateOrCreate(['key' => $key], ['value' => $value]);
21    }
22
23    public static function getBool(string $key, bool $default = false): bool
24    {
25        $value = static::get($key, $default);
26        
27        return filter_var($value, FILTER_VALIDATE_BOOLEAN);
28    }
29
30    public static function setBool(string $key, bool $value): void
31    {
32        static::set($key, $value ? '1' : '0');
33    }
34
35    public static function isArticleProcessingEnabled(): bool
36    {
37        return static::getBool('article_processing_enabled', true);
38    }
39
40    public static function setArticleProcessingEnabled(bool $enabled): void
41    {
42        static::setBool('article_processing_enabled', $enabled);
43    }
44
45    public static function isPublishingApprovalsEnabled(): bool
46    {
47        return static::getBool('enable_publishing_approvals', false);
48    }
49
50    public static function setPublishingApprovalsEnabled(bool $enabled): void
51    {
52        static::setBool('enable_publishing_approvals', $enabled);
53    }
54}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:52:46 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-with-models/Models/User.php.html b/backend/coverage-report-with-models/Models/User.php.html deleted file mode 100644 index 873a9eb1..00000000 --- a/backend/coverage-report-with-models/Models/User.php.html +++ /dev/null @@ -1,201 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Models/User.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 4
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
User
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 4
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 casts
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 4
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Models;
4
5// use Illuminate\Contracts\Auth\MustVerifyEmail;
6use Illuminate\Database\Eloquent\Factories\HasFactory;
7use Illuminate\Foundation\Auth\User as Authenticatable;
8use Illuminate\Notifications\Notifiable;
9use Laravel\Sanctum\HasApiTokens;
10
11class User extends Authenticatable
12{
13    /** @use HasFactory<\Database\Factories\UserFactory> */
14    use HasFactory, Notifiable, HasApiTokens;
15
16    /**
17     * The attributes that are mass assignable.
18     *
19     * @var list<string>
20     */
21    protected $fillable = [
22        'name',
23        'email',
24        'password',
25    ];
26
27    /**
28     * The attributes that should be hidden for serialization.
29     *
30     * @var list<string>
31     */
32    protected $hidden = [
33        'password',
34        'remember_token',
35    ];
36
37    /**
38     * Get the attributes that should be cast.
39     *
40     * @return array<string, string>
41     */
42    protected function casts(): array
43    {
44        return [
45            'email_verified_at' => 'datetime',
46            'password' => 'hashed',
47        ];
48    }
49}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:52:46 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-with-models/Models/dashboard.html b/backend/coverage-report-with-models/Models/dashboard.html deleted file mode 100644 index 026e8595..00000000 --- a/backend/coverage-report-with-models/Models/dashboard.html +++ /dev/null @@ -1,343 +0,0 @@ - - - - - Dashboard for /var/www/html/backend/app/Models - - - - - - - -
-
-
-
- -
-
-
-
-
-
-
-

Classes

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
- -
-
-

Methods

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
- - -
- - - - - - diff --git a/backend/coverage-report-with-models/Models/index.html b/backend/coverage-report-with-models/Models/index.html deleted file mode 100644 index 083349ff..00000000 --- a/backend/coverage-report-with-models/Models/index.html +++ /dev/null @@ -1,440 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Models - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 24.34% covered (danger) -
-
-
24.34%
37 / 152
-
- 27.78% covered (danger) -
-
-
27.78%
15 / 54
-
- 8.33% covered (danger) -
-
-
8.33%
1 / 12
Article.php
-
- 66.67% covered (warning) -
-
-
66.67%
26 / 39
-
- 54.55% covered (warning) -
-
-
54.55%
6 / 11
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
ArticlePublication.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
Feed.php
-
- 4.17% covered (danger) -
-
-
4.17%
1 / 24
-
- 16.67% covered (danger) -
-
-
16.67%
1 / 6
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
Keyword.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
Language.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 5
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
Log.php
n/a
0 / 0
n/a
0 / 0
n/a
0 / 0
PlatformAccount.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 21
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 6
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
PlatformChannel.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 14
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 7
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
PlatformChannelPost.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 21
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
PlatformInstance.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 7
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
Route.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 4
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
Setting.php
-
- 100.00% covered (success) -
-
-
100.00%
10 / 10
-
- 100.00% covered (success) -
-
-
100.00%
8 / 8
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
User.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 4
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- -
- - diff --git a/backend/coverage-report-with-models/Modules/Lemmy/LemmyRequest.php.html b/backend/coverage-report-with-models/Modules/Lemmy/LemmyRequest.php.html deleted file mode 100644 index 5b46b4f0..00000000 --- a/backend/coverage-report-with-models/Modules/Lemmy/LemmyRequest.php.html +++ /dev/null @@ -1,275 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Modules/Lemmy/LemmyRequest.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 14
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 4
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
LemmyRequest
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 14
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 4
42
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 __construct
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 get
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 5
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
6
 post
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 5
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
6
 withToken
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Modules\Lemmy;
4
5use Illuminate\Support\Facades\Http;
6use Illuminate\Http\Client\Response;
7
8class LemmyRequest
9{
10    private string $instance;
11    private ?string $token;
12
13    public function __construct(string $instance, ?string $token = null)
14    {
15        $this->instance = $instance;
16        $this->token = $token;
17    }
18
19    /**
20     * @param array<string, mixed> $params
21     */
22    public function get(string $endpoint, array $params = []): Response
23    {
24        $url = "https://{$this->instance}/api/v3/{$endpoint}";
25        
26        $request = Http::timeout(30);
27        
28        if ($this->token) {
29            $request = $request->withToken($this->token);
30        }
31        
32        return $request->get($url, $params);
33    }
34
35    /**
36     * @param array<string, mixed> $data
37     */
38    public function post(string $endpoint, array $data = []): Response
39    {
40        $url = "https://{$this->instance}/api/v3/{$endpoint}";
41        
42        $request = Http::timeout(30);
43        
44        if ($this->token) {
45            $request = $request->withToken($this->token);
46        }
47        
48        return $request->post($url, $data);
49    }
50
51    public function withToken(string $token): self
52    {
53        $this->token = $token;
54        return $this;
55    }
56}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:52:46 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-with-models/Modules/Lemmy/Services/LemmyApiService.php.html b/backend/coverage-report-with-models/Modules/Lemmy/Services/LemmyApiService.php.html deleted file mode 100644 index 0a10b295..00000000 --- a/backend/coverage-report-with-models/Modules/Lemmy/Services/LemmyApiService.php.html +++ /dev/null @@ -1,438 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Modules/Lemmy/Services/LemmyApiService.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 93
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 6
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
LemmyApiService
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 93
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 6
462
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 __construct
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 login
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 16
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
12
 getCommunityId
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 9
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
12
 syncChannelPosts
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 34
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
30
 createPost
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 19
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
42
 getLanguages
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 14
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
12
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Modules\Lemmy\Services;
4
5use App\Enums\PlatformEnum;
6use App\Models\PlatformChannelPost;
7use App\Modules\Lemmy\LemmyRequest;
8use Exception;
9
10class LemmyApiService
11{
12    private string $instance;
13
14    public function __construct(string $instance)
15    {
16        $this->instance = $instance;
17    }
18
19    public function login(string $username, string $password): ?string
20    {
21        try {
22            $request = new LemmyRequest($this->instance);
23            $response = $request->post('user/login', [
24                'username_or_email' => $username,
25                'password' => $password,
26            ]);
27
28            if (!$response->successful()) {
29                logger()->error('Lemmy login failed', [
30                    'status' => $response->status(),
31                    'body' => $response->body()
32                ]);
33                return null;
34            }
35
36            $data = $response->json();
37            return $data['jwt'] ?? null;
38        } catch (Exception $e) {
39            logger()->error('Lemmy login exception', ['error' => $e->getMessage()]);
40            return null;
41        }
42    }
43
44    public function getCommunityId(string $communityName, string $token): int
45    {
46        try {
47            $request = new LemmyRequest($this->instance, $token);
48            $response = $request->get('community', ['name' => $communityName]);
49
50            if (!$response->successful()) {
51                throw new Exception('Failed to fetch community: ' . $response->status());
52            }
53
54            $data = $response->json();
55            return $data['community_view']['community']['id'] ?? throw new Exception('Community not found');
56        } catch (Exception $e) {
57            logger()->error('Community lookup failed', ['error' => $e->getMessage()]);
58            throw $e;
59        }
60    }
61
62    public function syncChannelPosts(string $token, int $platformChannelId, string $communityName): void
63    {
64        try {
65            $request = new LemmyRequest($this->instance, $token);
66            $response = $request->get('post/list', [
67                'community_id' => $platformChannelId,
68                'limit' => 50,
69                'sort' => 'New'
70            ]);
71
72            if (!$response->successful()) {
73                logger()->warning('Failed to sync channel posts', [
74                    'status' => $response->status(),
75                    'platform_channel_id' => $platformChannelId
76                ]);
77                return;
78            }
79
80            $data = $response->json();
81            $posts = $data['posts'] ?? [];
82
83            foreach ($posts as $postData) {
84                $post = $postData['post'];
85
86                PlatformChannelPost::storePost(
87                    PlatformEnum::LEMMY,
88                    (string) $platformChannelId,
89                    $communityName,
90                    (string) $post['id'],
91                    $post['url'] ?? null,
92                    $post['name'] ?? null,
93                    isset($post['published']) ? new \DateTime($post['published']) : null
94                );
95            }
96
97            logger()->info('Synced channel posts', [
98                'platform_channel_id' => $platformChannelId,
99                'posts_count' => count($posts)
100            ]);
101
102        } catch (Exception $e) {
103            logger()->error('Exception while syncing channel posts', [
104                'error' => $e->getMessage(),
105                'platform_channel_id' => $platformChannelId
106            ]);
107        }
108    }
109
110    /**
111     * @return array<string, mixed>
112     */
113    public function createPost(string $token, string $title, string $body, int $platformChannelId, ?string $url = null, ?string $thumbnail = null, ?int $languageId = null): array
114    {
115        try {
116            $request = new LemmyRequest($this->instance, $token);
117
118            $postData = [
119                'name' => $title,
120                'body' => $body,
121                'community_id' => $platformChannelId,
122            ];
123
124            if ($url) {
125                $postData['url'] = $url;
126            }
127
128            if ($thumbnail) {
129                $postData['custom_thumbnail'] = $thumbnail;
130            }
131
132            if ($languageId) {
133                $postData['language_id'] = $languageId;
134            }
135
136            $response = $request->post('post', $postData);
137
138            if (!$response->successful()) {
139                throw new Exception('Failed to create post: ' . $response->status() . ' - ' . $response->body());
140            }
141
142            return $response->json();
143        } catch (Exception $e) {
144            logger()->error('Post creation failed', ['error' => $e->getMessage()]);
145            throw $e;
146        }
147    }
148
149    /**
150     * @return array<int, mixed>
151     */
152    public function getLanguages(): array
153    {
154        try {
155            $request = new LemmyRequest($this->instance);
156            $response = $request->get('site');
157
158            if (!$response->successful()) {
159                logger()->warning('Failed to fetch site languages', [
160                    'status' => $response->status()
161                ]);
162                return [];
163            }
164
165            $data = $response->json();
166            return $data['all_languages'] ?? [];
167        } catch (Exception $e) {
168            logger()->error('Exception while fetching languages', [
169                'error' => $e->getMessage()
170            ]);
171            return [];
172        }
173    }
174}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:52:46 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-with-models/Modules/Lemmy/Services/LemmyPublisher.php.html b/backend/coverage-report-with-models/Modules/Lemmy/Services/LemmyPublisher.php.html deleted file mode 100644 index 3e822e4d..00000000 --- a/backend/coverage-report-with-models/Modules/Lemmy/Services/LemmyPublisher.php.html +++ /dev/null @@ -1,223 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Modules/Lemmy/Services/LemmyPublisher.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 13
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
LemmyPublisher
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 13
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
6
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 __construct
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 publishToChannel
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 11
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Modules\Lemmy\Services;
4
5use App\Exceptions\PlatformAuthException;
6use App\Models\Article;
7use App\Models\PlatformAccount;
8use App\Models\PlatformChannel;
9use App\Services\Auth\LemmyAuthService;
10use Exception;
11
12class LemmyPublisher
13{
14    private LemmyApiService $api;
15    private PlatformAccount $account;
16
17    public function __construct(PlatformAccount $account)
18    {
19        $this->api = new LemmyApiService($account->instance_url);
20        $this->account = $account;
21    }
22
23    /**
24     * @param array<string, mixed> $extractedData
25     * @return array<string, mixed>
26     * @throws PlatformAuthException
27     * @throws Exception
28     */
29    public function publishToChannel(Article $article, array $extractedData, PlatformChannel $channel): array
30    {
31        $token = LemmyAuthService::getToken($this->account);
32
33        // Use the language ID from extracted data (should be set during validation)
34        $languageId = $extractedData['language_id'] ?? null;
35
36        return $this->api->createPost(
37            $token,
38            $extractedData['title'] ?? 'Untitled',
39            $extractedData['description'] ?? '',
40            $channel->channel_id,
41            $article->url,
42            $extractedData['thumbnail'] ?? null,
43            $languageId
44        );
45    }
46
47}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:52:46 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-with-models/Modules/Lemmy/Services/dashboard.html b/backend/coverage-report-with-models/Modules/Lemmy/Services/dashboard.html deleted file mode 100644 index 4fca3f90..00000000 --- a/backend/coverage-report-with-models/Modules/Lemmy/Services/dashboard.html +++ /dev/null @@ -1,302 +0,0 @@ - - - - - Dashboard for /var/www/html/backend/app/Modules/Lemmy/Services - - - - - - - -
-
-
-
- -
-
-
-
-
-
-
-

Classes

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
-
-
-

Insufficient Coverage

- -
-
-

Project Risks

-
- - - - - - - - - - - -
ClassCRAP
App\Modules\Lemmy\Services\LemmyApiService462
-
-
-
-
-
-

Methods

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
-
-
-

Insufficient Coverage

-
- - - - - - - - - - - - - - - - - - -
MethodCoverage
__construct0%
login0%
getCommunityId0%
syncChannelPosts0%
createPost0%
getLanguages0%
__construct0%
publishToChannel0%
-
-
-
-

Project Risks

-
- - - - - - - - - - - - - - - -
MethodCRAP
createPost42
syncChannelPosts30
login12
getCommunityId12
getLanguages12
-
-
-
- -
- - - - - - diff --git a/backend/coverage-report-with-models/Modules/Lemmy/Services/index.html b/backend/coverage-report-with-models/Modules/Lemmy/Services/index.html deleted file mode 100644 index eabf5fd9..00000000 --- a/backend/coverage-report-with-models/Modules/Lemmy/Services/index.html +++ /dev/null @@ -1,149 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Modules/Lemmy/Services - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 106
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 8
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
LemmyApiService.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 93
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 6
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
LemmyPublisher.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 13
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- -
- - diff --git a/backend/coverage-report-with-models/Modules/Lemmy/dashboard.html b/backend/coverage-report-with-models/Modules/Lemmy/dashboard.html deleted file mode 100644 index 52dac69b..00000000 --- a/backend/coverage-report-with-models/Modules/Lemmy/dashboard.html +++ /dev/null @@ -1,309 +0,0 @@ - - - - - Dashboard for /var/www/html/backend/app/Modules/Lemmy - - - - - - - -
-
-
-
- -
-
-
-
-
-
-
-

Classes

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
-
-
-

Insufficient Coverage

- -
-
-

Project Risks

- -
-
-
-
-

Methods

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
-
-
-

Insufficient Coverage

-
- - - - - - - - - - - - - - - - - - - - - - -
MethodCoverage
__construct0%
get0%
post0%
withToken0%
__construct0%
login0%
getCommunityId0%
syncChannelPosts0%
createPost0%
getLanguages0%
__construct0%
publishToChannel0%
-
-
-
-

Project Risks

-
- - - - - - - - - - - - - - - - - -
MethodCRAP
createPost42
syncChannelPosts30
login12
getCommunityId12
getLanguages12
get6
post6
-
-
-
- -
- - - - - - diff --git a/backend/coverage-report-with-models/Modules/Lemmy/index.html b/backend/coverage-report-with-models/Modules/Lemmy/index.html deleted file mode 100644 index dd51b5d3..00000000 --- a/backend/coverage-report-with-models/Modules/Lemmy/index.html +++ /dev/null @@ -1,148 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Modules/Lemmy - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 120
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 12
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
Services
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 106
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 8
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
LemmyRequest.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 14
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 4
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- -
- - diff --git a/backend/coverage-report-with-models/Modules/dashboard.html b/backend/coverage-report-with-models/Modules/dashboard.html deleted file mode 100644 index c7f0d860..00000000 --- a/backend/coverage-report-with-models/Modules/dashboard.html +++ /dev/null @@ -1,308 +0,0 @@ - - - - - Dashboard for /var/www/html/backend/app/Modules - - - - - - - -
-
-
-
- -
-
-
-
-
-
-
-

Classes

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
-
-
-

Insufficient Coverage

- -
-
-

Project Risks

- -
-
-
-
-

Methods

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
-
-
-

Insufficient Coverage

-
- - - - - - - - - - - - - - - - - - - - - - -
MethodCoverage
__construct0%
get0%
post0%
withToken0%
__construct0%
login0%
getCommunityId0%
syncChannelPosts0%
createPost0%
getLanguages0%
__construct0%
publishToChannel0%
-
-
-
-

Project Risks

-
- - - - - - - - - - - - - - - - - -
MethodCRAP
createPost42
syncChannelPosts30
login12
getCommunityId12
getLanguages12
get6
post6
-
-
-
- -
- - - - - - diff --git a/backend/coverage-report-with-models/Modules/index.html b/backend/coverage-report-with-models/Modules/index.html deleted file mode 100644 index 16ba2572..00000000 --- a/backend/coverage-report-with-models/Modules/index.html +++ /dev/null @@ -1,119 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Modules - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 120
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 12
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
Lemmy
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 120
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 12
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
-
- -
- - diff --git a/backend/coverage-report-with-models/Providers/AppServiceProvider.php.html b/backend/coverage-report-with-models/Providers/AppServiceProvider.php.html deleted file mode 100644 index c834e1b8..00000000 --- a/backend/coverage-report-with-models/Providers/AppServiceProvider.php.html +++ /dev/null @@ -1,260 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Providers/AppServiceProvider.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 82.76% covered (warning) -
-
-
82.76%
24 / 29
-
- 33.33% covered (danger) -
-
-
33.33%
1 / 3
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
AppServiceProvider
-
- 82.76% covered (warning) -
-
-
82.76%
24 / 29
-
- 33.33% covered (danger) -
-
-
33.33%
1 / 3
6.18
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 register
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
1
 boot
-
- 92.00% covered (success) -
-
-
92.00%
23 / 25
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
1.00
 mapExceptionToLogLevel
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
20
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Providers;
4
5use App\Events\ExceptionOccurred;
6use App\Listeners\LogExceptionToDatabase;
7use App\LogLevelEnum;
8use Error;
9use Illuminate\Contracts\Debug\ExceptionHandler;
10use Illuminate\Support\Facades\Event;
11use Illuminate\Support\ServiceProvider;
12use InvalidArgumentException;
13use Throwable;
14
15class AppServiceProvider extends ServiceProvider
16{
17    public function register(): void
18    {
19    }
20
21    public function boot(): void
22    {
23        Event::listen(
24            ExceptionOccurred::class,
25            LogExceptionToDatabase::class,
26        );
27
28        Event::listen(
29            \App\Events\NewArticleFetched::class,
30            \App\Listeners\ValidateArticleListener::class,
31        );
32
33        Event::listen(
34            \App\Events\ArticleApproved::class,
35            \App\Listeners\PublishApprovedArticle::class,
36        );
37
38        Event::listen(
39            \App\Events\ArticleReadyToPublish::class,
40            \App\Listeners\PublishArticle::class,
41        );
42
43        Event::listen(
44            \App\Events\ExceptionLogged::class,
45            \App\Listeners\LogExceptionToDatabase::class,
46        );
47
48        app()->make(ExceptionHandler::class)
49            ->reportable(function (Throwable $e) {
50                $level = $this->mapExceptionToLogLevel($e);
51
52                ExceptionOccurred::dispatch($e, $level, $e->getMessage(), []);
53            });
54    }
55
56    private function mapExceptionToLogLevel(Throwable $exception): LogLevelEnum
57    {
58        return match (true) {
59            $exception instanceof Error => LogLevelEnum::CRITICAL,
60            $exception instanceof InvalidArgumentException => LogLevelEnum::WARNING,
61            default => LogLevelEnum::ERROR,
62        };
63    }
64}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:52:46 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-with-models/Providers/HorizonServiceProvider.php.html b/backend/coverage-report-with-models/Providers/HorizonServiceProvider.php.html deleted file mode 100644 index df8a3f73..00000000 --- a/backend/coverage-report-with-models/Providers/HorizonServiceProvider.php.html +++ /dev/null @@ -1,208 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Providers/HorizonServiceProvider.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 75.00% covered (warning) -
-
-
75.00%
3 / 4
-
- 50.00% covered (danger) -
-
-
50.00%
1 / 2
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
HorizonServiceProvider
-
- 75.00% covered (warning) -
-
-
75.00%
3 / 4
-
- 50.00% covered (danger) -
-
-
50.00%
1 / 2
2.06
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 boot
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
1
 gate
-
- 66.67% covered (warning) -
-
-
66.67%
2 / 3
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
1.04
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Providers;
4
5use Illuminate\Support\Facades\Gate;
6use Laravel\Horizon\Horizon;
7use Laravel\Horizon\HorizonApplicationServiceProvider;
8
9class HorizonServiceProvider extends HorizonApplicationServiceProvider
10{
11    /**
12     * Bootstrap any application services.
13     */
14    public function boot(): void
15    {
16        parent::boot();
17
18        // Horizon::routeSmsNotificationsTo('15556667777');
19        // Horizon::routeMailNotificationsTo('example@example.com');
20        // Horizon::routeSlackNotificationsTo('slack-webhook-url', '#channel');
21    }
22
23    /**
24     * Register the Horizon gate.
25     *
26     * This gate determines who can access Horizon in non-local environments.
27     */
28    protected function gate(): void
29    {
30        Gate::define('viewHorizon', function ($user = null) {
31            return true;
32        });
33    }
34}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:52:46 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-with-models/Providers/dashboard.html b/backend/coverage-report-with-models/Providers/dashboard.html deleted file mode 100644 index 0f64caa5..00000000 --- a/backend/coverage-report-with-models/Providers/dashboard.html +++ /dev/null @@ -1,290 +0,0 @@ - - - - - Dashboard for /var/www/html/backend/app/Providers - - - - - - - -
-
-
-
- -
-
-
-
-
-
-
-

Classes

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
-
-
-

Insufficient Coverage

-
- - - - - - - - - - - - -
ClassCoverage
App\Providers\HorizonServiceProvider75%
App\Providers\AppServiceProvider82%
-
-
-
-

Project Risks

-
- - - - - - - - - - - -
ClassCRAP
App\Providers\AppServiceProvider6
-
-
-
-
-
-

Methods

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
-
-
-

Insufficient Coverage

-
- - - - - - - - - - - - -
MethodCoverage
mapExceptionToLogLevel0%
gate66%
-
-
-
-

Project Risks

-
- - - - - - - - - - - -
MethodCRAP
mapExceptionToLogLevel20
-
-
-
- -
- - - - - - diff --git a/backend/coverage-report-with-models/Providers/index.html b/backend/coverage-report-with-models/Providers/index.html deleted file mode 100644 index b419d8a4..00000000 --- a/backend/coverage-report-with-models/Providers/index.html +++ /dev/null @@ -1,147 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Providers - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 81.82% covered (warning) -
-
-
81.82%
27 / 33
-
- 40.00% covered (danger) -
-
-
40.00%
2 / 5
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
AppServiceProvider.php
-
- 82.76% covered (warning) -
-
-
82.76%
24 / 29
-
- 33.33% covered (danger) -
-
-
33.33%
1 / 3
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
HorizonServiceProvider.php
-
- 75.00% covered (warning) -
-
-
75.00%
3 / 4
-
- 50.00% covered (danger) -
-
-
50.00%
1 / 2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- -
- - diff --git a/backend/coverage-report-with-models/Services/Article/ArticleFetcher.php.html b/backend/coverage-report-with-models/Services/Article/ArticleFetcher.php.html deleted file mode 100644 index 1880e4f7..00000000 --- a/backend/coverage-report-with-models/Services/Article/ArticleFetcher.php.html +++ /dev/null @@ -1,354 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Services/Article/ArticleFetcher.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 44
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 5
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
ArticleFetcher
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 44
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 5
132
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 getArticlesFromFeed
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 9
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
12
 getArticlesFromRssFeed
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 getArticlesFromWebsiteFeed
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 18
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
12
 fetchArticleData
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 9
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
6
 saveArticle
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 7
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
6
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Services\Article;
4
5use App\Models\Article;
6use App\Models\Feed;
7use App\Services\Http\HttpFetcher;
8use App\Services\Factories\ArticleParserFactory;
9use App\Services\Factories\HomepageParserFactory;
10use App\Services\Log\LogSaver;
11use Exception;
12use Illuminate\Support\Collection;
13
14class ArticleFetcher
15{
16    /**
17     * @return Collection<int, Article>
18     */
19    public static function getArticlesFromFeed(Feed $feed): Collection
20    {
21        if ($feed->type === 'rss') {
22            return self::getArticlesFromRssFeed($feed);
23        } elseif ($feed->type === 'website') {
24            return self::getArticlesFromWebsiteFeed($feed);
25        }
26
27        LogSaver::warning("Unsupported feed type", null, [
28            'feed_id' => $feed->id,
29            'feed_type' => $feed->type
30        ]);
31
32        return collect();
33    }
34
35    /**
36     * @return Collection<int, Article>
37     */
38    private static function getArticlesFromRssFeed(Feed $feed): Collection
39    {
40        // TODO: Implement RSS feed parsing
41        // For now, return empty collection
42        return collect();
43    }
44
45    /**
46     * @return Collection<int, Article>
47     */
48    private static function getArticlesFromWebsiteFeed(Feed $feed): Collection
49    {
50        try {
51            // Try to get parser for this feed
52            $parser = HomepageParserFactory::getParserForFeed($feed);
53
54            if (! $parser) {
55                LogSaver::warning("No parser available for feed URL", null, [
56                    'feed_id' => $feed->id,
57                    'feed_url' => $feed->url
58                ]);
59
60                return collect();
61            }
62
63            $html = HttpFetcher::fetchHtml($feed->url);
64            $urls = $parser->extractArticleUrls($html);
65
66            return collect($urls)
67                ->map(fn (string $url) => self::saveArticle($url, $feed->id));
68
69        } catch (Exception $e) {
70            LogSaver::error("Failed to fetch articles from website feed", null, [
71                'feed_id' => $feed->id,
72                'feed_url' => $feed->url,
73                'error' => $e->getMessage()
74            ]);
75
76            return collect();
77        }
78    }
79
80    /**
81     * @return array<string, mixed>
82     */
83    public static function fetchArticleData(Article $article): array
84    {
85        try {
86            $html = HttpFetcher::fetchHtml($article->url);
87            $parser = ArticleParserFactory::getParser($article->url);
88
89            return $parser->extractData($html);
90        } catch (Exception $e) {
91            LogSaver::error('Exception while fetching article data', null, [
92                'url' => $article->url,
93                'error' => $e->getMessage()
94            ]);
95
96            return [];
97        }
98    }
99
100    private static function saveArticle(string $url, ?int $feedId = null): Article
101    {
102        $existingArticle = Article::where('url', $url)->first();
103
104        if ($existingArticle) {
105            return $existingArticle;
106        }
107
108        return Article::create([
109            'url' => $url,
110            'feed_id' => $feedId
111        ]);
112    }
113}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:52:46 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-with-models/Services/Article/ValidationService.php.html b/backend/coverage-report-with-models/Services/Article/ValidationService.php.html deleted file mode 100644 index cbf6bac2..00000000 --- a/backend/coverage-report-with-models/Services/Article/ValidationService.php.html +++ /dev/null @@ -1,228 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Services/Article/ValidationService.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 25
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
ValidationService
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 25
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
30
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 validate
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 18
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
6
 validateByKeywords
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 7
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
12
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Services\Article;
4
5use App\Models\Article;
6
7class ValidationService
8{
9    public static function validate(Article $article): Article
10    {
11        logger('Checking keywords for article: ' . $article->id);
12
13        $articleData = ArticleFetcher::fetchArticleData($article);
14        
15        if (!isset($articleData['full_article'])) {
16            logger()->warning('Article data missing full_article key', [
17                'article_id' => $article->id,
18                'url' => $article->url
19            ]);
20            
21            $article->update([
22                'is_valid' => false,
23                'validated_at' => now(),
24            ]);
25            
26            return $article->refresh();
27        }
28        
29        $validationResult = self::validateByKeywords($articleData['full_article']);
30
31        $article->update([
32            'is_valid' => $validationResult,
33            'validated_at' => now(),
34        ]);
35
36        return $article->refresh();
37    }
38
39    private static function validateByKeywords(string $full_article): bool
40    {
41        $keywords = [
42            'N-VA', 'Bart De Wever', 'Frank Vandenbroucke',
43        ];
44
45        foreach ($keywords as $keyword) {
46            if (stripos($full_article, $keyword) !== false) {
47                return true;
48            }
49        }
50
51        return false;
52    }
53}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:52:46 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-with-models/Services/Article/dashboard.html b/backend/coverage-report-with-models/Services/Article/dashboard.html deleted file mode 100644 index 14062c9f..00000000 --- a/backend/coverage-report-with-models/Services/Article/dashboard.html +++ /dev/null @@ -1,302 +0,0 @@ - - - - - Dashboard for /var/www/html/backend/app/Services/Article - - - - - - - -
-
-
-
- -
-
-
-
-
-
-
-

Classes

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
-
-
-

Insufficient Coverage

- -
-
-

Project Risks

- -
-
-
-
-

Methods

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
-
-
-

Insufficient Coverage

- -
-
-

Project Risks

- -
-
- -
- - - - - - diff --git a/backend/coverage-report-with-models/Services/Article/index.html b/backend/coverage-report-with-models/Services/Article/index.html deleted file mode 100644 index 6aacd9dc..00000000 --- a/backend/coverage-report-with-models/Services/Article/index.html +++ /dev/null @@ -1,148 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Services/Article - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 69
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 7
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
ArticleFetcher.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 44
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 5
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
ValidationService.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 25
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- -
- - diff --git a/backend/coverage-report-with-models/Services/Auth/LemmyAuthService.php.html b/backend/coverage-report-with-models/Services/Auth/LemmyAuthService.php.html deleted file mode 100644 index 407e919d..00000000 --- a/backend/coverage-report-with-models/Services/Auth/LemmyAuthService.php.html +++ /dev/null @@ -1,194 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Services/Auth/LemmyAuthService.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 12
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
LemmyAuthService
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 12
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
42
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 getToken
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 12
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
42
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Services\Auth;
4
5use App\Enums\PlatformEnum;
6use App\Exceptions\PlatformAuthException;
7use App\Models\PlatformAccount;
8use App\Modules\Lemmy\Services\LemmyApiService;
9use Illuminate\Support\Facades\Cache;
10
11class LemmyAuthService
12{
13    /**
14     * @throws PlatformAuthException
15     */
16    public static function getToken(PlatformAccount $account): string
17    {
18        $cacheKey = "lemmy_jwt_token_$account->id";
19        $cachedToken = Cache::get($cacheKey);
20
21        if ($cachedToken) {
22            return $cachedToken;
23        }
24
25        if (! $account->username || ! $account->password || ! $account->instance_url) {
26            throw new PlatformAuthException(PlatformEnum::LEMMY, 'Missing credentials for account: ' . $account->username);
27        }
28
29        $api = new LemmyApiService($account->instance_url);
30        $token = $api->login($account->username, $account->password);
31
32        if (!$token) {
33            throw new PlatformAuthException(PlatformEnum::LEMMY, 'Login failed for account: ' . $account->username);
34        }
35
36        // Cache for 50 minutes (3000 seconds) to allow buffer before token expires
37        Cache::put($cacheKey, $token, 3000);
38
39        return $token;
40    }
41}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:52:46 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-with-models/Services/Auth/dashboard.html b/backend/coverage-report-with-models/Services/Auth/dashboard.html deleted file mode 100644 index e98fe0c9..00000000 --- a/backend/coverage-report-with-models/Services/Auth/dashboard.html +++ /dev/null @@ -1,289 +0,0 @@ - - - - - Dashboard for /var/www/html/backend/app/Services/Auth - - - - - - - -
-
-
-
- -
-
-
-
-
-
-
-

Classes

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
-
-
-

Insufficient Coverage

-
- - - - - - - - - - - -
ClassCoverage
App\Services\Auth\LemmyAuthService0%
-
-
-
-

Project Risks

-
- - - - - - - - - - - -
ClassCRAP
App\Services\Auth\LemmyAuthService42
-
-
-
-
-
-

Methods

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
-
-
-

Insufficient Coverage

-
- - - - - - - - - - - -
MethodCoverage
getToken0%
-
-
-
-

Project Risks

-
- - - - - - - - - - - -
MethodCRAP
getToken42
-
-
-
- -
- - - - - - diff --git a/backend/coverage-report-with-models/Services/Auth/index.html b/backend/coverage-report-with-models/Services/Auth/index.html deleted file mode 100644 index f365d403..00000000 --- a/backend/coverage-report-with-models/Services/Auth/index.html +++ /dev/null @@ -1,120 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Services/Auth - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 12
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
LemmyAuthService.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 12
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- -
- - diff --git a/backend/coverage-report-with-models/Services/DashboardStatsService.php.html b/backend/coverage-report-with-models/Services/DashboardStatsService.php.html deleted file mode 100644 index c4c4e87c..00000000 --- a/backend/coverage-report-with-models/Services/DashboardStatsService.php.html +++ /dev/null @@ -1,306 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Services/DashboardStatsService.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 100.00% covered (success) -
-
-
100.00%
40 / 40
-
- 100.00% covered (success) -
-
-
100.00%
4 / 4
CRAP
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
DashboardStatsService
-
- 100.00% covered (success) -
-
-
100.00%
40 / 40
-
- 100.00% covered (success) -
-
-
100.00%
4 / 4
13
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
 getStats
-
- 100.00% covered (success) -
-
-
100.00%
16 / 16
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
4
 getAvailablePeriods
-
- 100.00% covered (success) -
-
-
100.00%
7 / 7
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
1
 getDateRange
-
- 100.00% covered (success) -
-
-
100.00%
9 / 9
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
7
 getSystemStats
-
- 100.00% covered (success) -
-
-
100.00%
8 / 8
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
1
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Services;
4
5use App\Models\Article;
6use App\Models\ArticlePublication;
7use Carbon\Carbon;
8
9class DashboardStatsService
10{
11    /**
12     * @return array
13     */
14    public function getStats(string $period = 'today'): array
15    {
16        $dateRange = $this->getDateRange($period);
17        
18        // Get articles fetched for the period
19        $articlesFetchedQuery = Article::query();
20        if ($dateRange) {
21            $articlesFetchedQuery->whereBetween('created_at', $dateRange);
22        }
23        $articlesFetched = $articlesFetchedQuery->count();
24
25        // Get articles published for the period
26        $articlesPublishedQuery = ArticlePublication::query()
27            ->whereNotNull('published_at');
28        if ($dateRange) {
29            $articlesPublishedQuery->whereBetween('published_at', $dateRange);
30        }
31        $articlesPublished = $articlesPublishedQuery->count();
32
33        // Calculate published percentage
34        $publishedPercentage = $articlesFetched > 0 ? round(($articlesPublished / $articlesFetched) * 100, 1) : 0.0;
35
36        return [
37            'articles_fetched' => $articlesFetched,
38            'articles_published' => $articlesPublished,
39            'published_percentage' => $publishedPercentage,
40        ];
41    }
42
43    /**
44     * @return array<string, string>
45     */
46    public function getAvailablePeriods(): array
47    {
48        return [
49            'today' => 'Today',
50            'week' => 'This Week',
51            'month' => 'This Month',
52            'year' => 'This Year',
53            'all' => 'All Time',
54        ];
55    }
56
57    /**
58     * @return array{0: Carbon, 1: Carbon}|null
59     */
60    private function getDateRange(string $period): ?array
61    {
62        $now = Carbon::now();
63        
64        return match ($period) {
65            'today' => [$now->copy()->startOfDay(), $now->copy()->endOfDay()],
66            'week' => [$now->copy()->startOfWeek(), $now->copy()->endOfWeek()],
67            'month' => [$now->copy()->startOfMonth(), $now->copy()->endOfMonth()],
68            'year' => [$now->copy()->startOfYear(), $now->copy()->endOfYear()],
69            'all' => null, // No date filtering for all-time stats
70            default => [$now->copy()->startOfDay(), $now->copy()->endOfDay()],
71        };
72    }
73
74    /**
75     * Get additional stats for dashboard
76     */
77    public function getSystemStats(): array
78    {
79        return [
80            'total_feeds' => \App\Models\Feed::count(),
81            'active_feeds' => \App\Models\Feed::where('is_active', true)->count(),
82            'total_channels' => \App\Models\PlatformChannel::count(),
83            'active_channels' => \App\Models\PlatformChannel::where('is_active', true)->count(),
84            'total_routes' => \App\Models\Route::count(),
85            'active_routes' => \App\Models\Route::where('is_active', true)->count(),
86        ];
87    }
88}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:52:46 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-with-models/Services/Factories/ArticleParserFactory.php.html b/backend/coverage-report-with-models/Services/Factories/ArticleParserFactory.php.html deleted file mode 100644 index 560f80cd..00000000 --- a/backend/coverage-report-with-models/Services/Factories/ArticleParserFactory.php.html +++ /dev/null @@ -1,250 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Services/Factories/ArticleParserFactory.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 11
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
ArticleParserFactory
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 11
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
42
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 getParser
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 5
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
12
 getSupportedSources
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 4
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 registerParser
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
6
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Services\Factories;
4
5use App\Contracts\ArticleParserInterface;
6use App\Services\Parsers\VrtArticleParser;
7use App\Services\Parsers\BelgaArticleParser;
8use Exception;
9
10class ArticleParserFactory
11{
12    /**
13     * @var array<int, class-string<ArticleParserInterface>>
14     */
15    private static array $parsers = [
16        VrtArticleParser::class,
17        BelgaArticleParser::class,
18    ];
19
20    public static function getParser(string $url): ArticleParserInterface
21    {
22        foreach (self::$parsers as $parserClass) {
23            $parser = new $parserClass();
24            
25            if ($parser->canParse($url)) {
26                return $parser;
27            }
28        }
29
30        throw new Exception("No parser found for URL: {$url}");
31    }
32
33    /**
34     * @return array<int, string>
35     */
36    public static function getSupportedSources(): array
37    {
38        return array_map(function($parserClass) {
39            $parser = new $parserClass();
40            return $parser->getSourceName();
41        }, self::$parsers);
42    }
43
44    /**
45     * @param class-string<ArticleParserInterface> $parserClass
46     */
47    public static function registerParser(string $parserClass): void
48    {
49        if (!in_array($parserClass, self::$parsers)) {
50            self::$parsers[] = $parserClass;
51        }
52    }
53}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:52:46 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-with-models/Services/Factories/HomepageParserFactory.php.html b/backend/coverage-report-with-models/Services/Factories/HomepageParserFactory.php.html deleted file mode 100644 index c1fb56e1..00000000 --- a/backend/coverage-report-with-models/Services/Factories/HomepageParserFactory.php.html +++ /dev/null @@ -1,220 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Services/Factories/HomepageParserFactory.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 8
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
HomepageParserFactory
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 8
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
30
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 getParser
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 5
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
12
 getParserForFeed
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
6
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Services\Factories;
4
5use App\Contracts\HomepageParserInterface;
6use App\Models\Feed;
7use App\Services\Parsers\VrtHomepageParserAdapter;
8use App\Services\Parsers\BelgaHomepageParserAdapter;
9use Exception;
10
11class HomepageParserFactory
12{
13    /**
14     * @var array<int, class-string<HomepageParserInterface>>
15     */
16    private static array $parsers = [
17        VrtHomepageParserAdapter::class,
18        BelgaHomepageParserAdapter::class,
19    ];
20
21    /**
22     * @throws Exception
23     */
24    public static function getParser(string $url): HomepageParserInterface
25    {
26        foreach (self::$parsers as $parserClass) {
27            $parser = new $parserClass();
28
29            if ($parser->canParse($url)) {
30                return $parser;
31            }
32        }
33
34        throw new Exception("No homepage parser found for URL: {$url}");
35    }
36
37    public static function getParserForFeed(Feed $feed): ?HomepageParserInterface
38    {
39        try {
40            return self::getParser($feed->url);
41        } catch (Exception) {
42            return null;
43        }
44    }
45}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:52:46 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-with-models/Services/Factories/dashboard.html b/backend/coverage-report-with-models/Services/Factories/dashboard.html deleted file mode 100644 index 23bbabab..00000000 --- a/backend/coverage-report-with-models/Services/Factories/dashboard.html +++ /dev/null @@ -1,298 +0,0 @@ - - - - - Dashboard for /var/www/html/backend/app/Services/Factories - - - - - - - -
-
-
-
- -
-
-
-
-
-
-
-

Classes

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
-
-
-

Insufficient Coverage

- -
-
-

Project Risks

- -
-
-
-
-

Methods

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
-
-
-

Insufficient Coverage

-
- - - - - - - - - - - - - - - -
MethodCoverage
getParser0%
getSupportedSources0%
registerParser0%
getParser0%
getParserForFeed0%
-
-
-
-

Project Risks

-
- - - - - - - - - - - - - - -
MethodCRAP
getParser12
getParser12
registerParser6
getParserForFeed6
-
-
-
- -
- - - - - - diff --git a/backend/coverage-report-with-models/Services/Factories/index.html b/backend/coverage-report-with-models/Services/Factories/index.html deleted file mode 100644 index 250677d0..00000000 --- a/backend/coverage-report-with-models/Services/Factories/index.html +++ /dev/null @@ -1,148 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Services/Factories - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 19
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 5
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
ArticleParserFactory.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 11
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
HomepageParserFactory.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 8
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- -
- - diff --git a/backend/coverage-report-with-models/Services/Http/HttpFetcher.php.html b/backend/coverage-report-with-models/Services/Http/HttpFetcher.php.html deleted file mode 100644 index bf74d58d..00000000 --- a/backend/coverage-report-with-models/Services/Http/HttpFetcher.php.html +++ /dev/null @@ -1,256 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Services/Http/HttpFetcher.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 44
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
HttpFetcher
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 44
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
90
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 fetchHtml
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 10
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
12
 fetchMultipleUrls
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 34
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
42
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Services\Http;
4
5use Illuminate\Support\Facades\Http;
6use Exception;
7
8class HttpFetcher
9{
10    public static function fetchHtml(string $url): string
11    {
12        try {
13            $response = Http::get($url);
14            
15            if (!$response->successful()) {
16                throw new Exception("Failed to fetch URL: {$url} - Status: {$response->status()}");
17            }
18            
19            return $response->body();
20        } catch (Exception $e) {
21            logger()->error('HTTP fetch failed', [
22                'url' => $url,
23                'error' => $e->getMessage()
24            ]);
25            throw $e;
26        }
27    }
28
29    /**
30     * @param array<int, string> $urls
31     * @return array<int, array<string, mixed>>
32     */
33    public static function fetchMultipleUrls(array $urls): array
34    {
35        try {
36            $responses = Http::pool(function ($pool) use ($urls) {
37                foreach ($urls as $url) {
38                    $pool->get($url);
39                }
40            });
41
42            return collect($responses)
43                ->map(function ($response, $index) use ($urls) {
44                    if (!isset($urls[$index])) {
45                        return null;
46                    }
47                    
48                    $url = $urls[$index];
49                    
50                    try {
51                        if ($response->successful()) {
52                            return [
53                                'url' => $url,
54                                'html' => $response->body(),
55                                'success' => true
56                            ];
57                        } else {
58                            return [
59                                'url' => $url,
60                                'html' => null,
61                                'success' => false,
62                                'status' => $response->status()
63                            ];
64                        }
65                    } catch (Exception) {
66                        return [
67                            'url' => $url,
68                            'html' => null,
69                            'success' => false,
70                            'error' => 'Exception occurred'
71                        ];
72                    }
73                })
74                ->filter(fn($result) => $result !== null)
75                ->toArray();
76        } catch (Exception $e) {
77            logger()->error('Multiple URL fetch failed', ['error' => $e->getMessage()]);
78            return [];
79        }
80    }
81}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:52:46 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-with-models/Services/Http/dashboard.html b/backend/coverage-report-with-models/Services/Http/dashboard.html deleted file mode 100644 index bc325c8d..00000000 --- a/backend/coverage-report-with-models/Services/Http/dashboard.html +++ /dev/null @@ -1,291 +0,0 @@ - - - - - Dashboard for /var/www/html/backend/app/Services/Http - - - - - - - -
-
-
-
- -
-
-
-
-
-
-
-

Classes

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
-
-
-

Insufficient Coverage

-
- - - - - - - - - - - -
ClassCoverage
App\Services\Http\HttpFetcher0%
-
-
-
-

Project Risks

-
- - - - - - - - - - - -
ClassCRAP
App\Services\Http\HttpFetcher90
-
-
-
-
-
-

Methods

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
-
-
-

Insufficient Coverage

-
- - - - - - - - - - - - -
MethodCoverage
fetchHtml0%
fetchMultipleUrls0%
-
-
-
-

Project Risks

-
- - - - - - - - - - - - -
MethodCRAP
fetchMultipleUrls42
fetchHtml12
-
-
-
- -
- - - - - - diff --git a/backend/coverage-report-with-models/Services/Http/index.html b/backend/coverage-report-with-models/Services/Http/index.html deleted file mode 100644 index 62e78bdf..00000000 --- a/backend/coverage-report-with-models/Services/Http/index.html +++ /dev/null @@ -1,120 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Services/Http - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 44
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
HttpFetcher.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 44
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- -
- - diff --git a/backend/coverage-report-with-models/Services/Log/LogSaver.php.html b/backend/coverage-report-with-models/Services/Log/LogSaver.php.html deleted file mode 100644 index d03b3574..00000000 --- a/backend/coverage-report-with-models/Services/Log/LogSaver.php.html +++ /dev/null @@ -1,306 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Services/Log/LogSaver.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 17
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 5
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
LogSaver
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 17
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 5
42
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 info
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 error
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 warning
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 debug
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 log
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 13
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
6
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Services\Log;
4
5use App\LogLevelEnum;
6use App\Models\Log;
7use App\Models\PlatformChannel;
8
9class LogSaver
10{
11    /**
12     * @param array<string, mixed> $context
13     */
14    public static function info(string $message, ?PlatformChannel $channel = null, array $context = []): void
15    {
16        self::log(LogLevelEnum::INFO, $message, $channel, $context);
17    }
18
19    /**
20     * @param array<string, mixed> $context
21     */
22    public static function error(string $message, ?PlatformChannel $channel = null, array $context = []): void
23    {
24        self::log(LogLevelEnum::ERROR, $message, $channel, $context);
25    }
26
27    /**
28     * @param array<string, mixed> $context
29     */
30    public static function warning(string $message, ?PlatformChannel $channel = null, array $context = []): void
31    {
32        self::log(LogLevelEnum::WARNING, $message, $channel, $context);
33    }
34
35    /**
36     * @param array<string, mixed> $context
37     */
38    public static function debug(string $message, ?PlatformChannel $channel = null, array $context = []): void
39    {
40        self::log(LogLevelEnum::DEBUG, $message, $channel, $context);
41    }
42
43    /**
44     * @param array<string, mixed> $context
45     */
46    private static function log(LogLevelEnum $level, string $message, ?PlatformChannel $channel = null, array $context = []): void
47    {
48        $logContext = $context;
49
50        if ($channel) {
51            $logContext = array_merge($logContext, [
52                'channel_id' => $channel->id,
53                'channel_name' => $channel->name,
54                'platform' => $channel->platformInstance->platform->value,
55                'instance_url' => $channel->platformInstance->url,
56            ]);
57        }
58
59        Log::create([
60            'level' => $level,
61            'message' => $message,
62            'context' => $logContext,
63        ]);
64    }
65}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:52:46 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-with-models/Services/Log/dashboard.html b/backend/coverage-report-with-models/Services/Log/dashboard.html deleted file mode 100644 index 6c9b26d9..00000000 --- a/backend/coverage-report-with-models/Services/Log/dashboard.html +++ /dev/null @@ -1,293 +0,0 @@ - - - - - Dashboard for /var/www/html/backend/app/Services/Log - - - - - - - -
-
-
-
- -
-
-
-
-
-
-
-

Classes

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
-
-
-

Insufficient Coverage

-
- - - - - - - - - - - -
ClassCoverage
App\Services\Log\LogSaver0%
-
-
-
-

Project Risks

-
- - - - - - - - - - - -
ClassCRAP
App\Services\Log\LogSaver42
-
-
-
-
-
-

Methods

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
-
-
-

Insufficient Coverage

-
- - - - - - - - - - - - - - - -
MethodCoverage
info0%
error0%
warning0%
debug0%
log0%
-
-
-
-

Project Risks

-
- - - - - - - - - - - -
MethodCRAP
log6
-
-
-
- -
- - - - - - diff --git a/backend/coverage-report-with-models/Services/Log/index.html b/backend/coverage-report-with-models/Services/Log/index.html deleted file mode 100644 index f302eda4..00000000 --- a/backend/coverage-report-with-models/Services/Log/index.html +++ /dev/null @@ -1,120 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Services/Log - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 17
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 5
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
LogSaver.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 17
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 5
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- -
- - diff --git a/backend/coverage-report-with-models/Services/OnboardingRedirectService.php.html b/backend/coverage-report-with-models/Services/OnboardingRedirectService.php.html deleted file mode 100644 index 39595975..00000000 --- a/backend/coverage-report-with-models/Services/OnboardingRedirectService.php.html +++ /dev/null @@ -1,172 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Services/OnboardingRedirectService.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 4
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
OnboardingRedirectService
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 4
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
6
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 handleRedirect
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 4
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
6
-
- - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Services;
4
5use Illuminate\Http\RedirectResponse;
6use Illuminate\Http\Request;
7
8class OnboardingRedirectService
9{
10    public static function handleRedirect(Request $request, string $defaultRoute, string $successMessage): RedirectResponse
11    {
12        $redirectTo = $request->input('redirect_to');
13        
14        if ($redirectTo) {
15            return redirect($redirectTo)->with('success', $successMessage);
16        }
17
18        return redirect()->route($defaultRoute)->with('success', $successMessage);
19    }
20}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:52:46 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-with-models/Services/Parsers/BelgaArticlePageParser.php.html b/backend/coverage-report-with-models/Services/Parsers/BelgaArticlePageParser.php.html deleted file mode 100644 index 8d533c9e..00000000 --- a/backend/coverage-report-with-models/Services/Parsers/BelgaArticlePageParser.php.html +++ /dev/null @@ -1,351 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Services/Parsers/BelgaArticlePageParser.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 42
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 5
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
BelgaArticlePageParser
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 42
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 5
306
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 extractTitle
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 9
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
30
 extractDescription
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 7
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
20
 extractFullArticle
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 15
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
20
 extractThumbnail
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 5
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
12
 extractData
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 6
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Services\Parsers;
4
5class BelgaArticlePageParser
6{
7    public static function extractTitle(string $html): ?string
8    {
9        // Try h1 with Belga-specific class first
10        if (preg_match('/<h1[^>]*class="[^"]*prezly-slate-heading--heading-1[^"]*"[^>]*>([^<]+)<\/h1>/i', $html, $matches)) {
11            return html_entity_decode(strip_tags($matches[1]), ENT_QUOTES, 'UTF-8');
12        }
13        
14        // Try meta title
15        if (preg_match('/<meta property="og:title" content="([^"]+)"/i', $html, $matches)) {
16            return html_entity_decode($matches[1], ENT_QUOTES, 'UTF-8');
17        }
18        
19        // Try any h1 tag
20        if (preg_match('/<h1[^>]*>([^<]+)<\/h1>/i', $html, $matches)) {
21            return html_entity_decode(strip_tags($matches[1]), ENT_QUOTES, 'UTF-8');
22        }
23        
24        // Try title tag
25        if (preg_match('/<title>([^<]+)<\/title>/i', $html, $matches)) {
26            return html_entity_decode($matches[1], ENT_QUOTES, 'UTF-8');
27        }
28        
29        return null;
30    }
31    
32    public static function extractDescription(string $html): ?string
33    {
34        // Try meta description first
35        if (preg_match('/<meta property="og:description" content="([^"]+)"/i', $html, $matches)) {
36            return html_entity_decode($matches[1], ENT_QUOTES, 'UTF-8');
37        }
38        
39        // Try Belga-specific paragraph class
40        if (preg_match('/<p[^>]*class="[^"]*styles_paragraph__[^"]*"[^>]*>([^<]+(?:<[^\/](?!p)[^>]*>[^<]*<\/[^>]*>[^<]*)*)<\/p>/i', $html, $matches)) {
41            return html_entity_decode(strip_tags($matches[1]), ENT_QUOTES, 'UTF-8');
42        }
43        
44        // Try to find first paragraph in article content
45        if (preg_match('/<p[^>]*>([^<]+(?:<[^\/](?!p)[^>]*>[^<]*<\/[^>]*>[^<]*)*)<\/p>/i', $html, $matches)) {
46            return html_entity_decode(strip_tags($matches[1]), ENT_QUOTES, 'UTF-8');
47        }
48        
49        return null;
50    }
51    
52    public static function extractFullArticle(string $html): ?string
53    {
54        // Remove scripts, styles, and other non-content elements
55        $cleanHtml = preg_replace('/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/mi', '', $html);
56        $cleanHtml = preg_replace('/<style\b[^<]*(?:(?!<\/style>)<[^<]*)*<\/style>/mi', '', $cleanHtml);
57        
58        // Try to extract content from Belga-specific document section
59        if (preg_match('/<section[^>]*class="[^"]*prezly-slate-document[^"]*"[^>]*>(.*?)<\/section>/is', $cleanHtml, $sectionMatches)) {
60            $sectionHtml = $sectionMatches[1];
61            preg_match_all('/<p[^>]*>(.*?)<\/p>/is', $sectionHtml, $matches);
62        } else {
63            // Fallback: Extract all paragraph content
64            preg_match_all('/<p[^>]*>(.*?)<\/p>/is', $cleanHtml, $matches);
65        }
66        
67        if (!empty($matches[1])) {
68            $paragraphs = array_map(function($paragraph) {
69                return html_entity_decode(strip_tags($paragraph), ENT_QUOTES, 'UTF-8');
70            }, $matches[1]);
71            
72            // Filter out empty paragraphs and join with double newlines
73            $fullText = implode("\n\n", array_filter($paragraphs, function($p) {
74                return trim($p) !== '';
75            }));
76            
77            return $fullText ?: null;
78        }
79        
80        return null;
81    }
82    
83    public static function extractThumbnail(string $html): ?string
84    {
85        // Try OpenGraph image first
86        if (preg_match('/<meta property="og:image" content="([^"]+)"/i', $html, $matches)) {
87            return $matches[1];
88        }
89        
90        // Try first image in article content
91        if (preg_match('/<img[^>]+src="([^"]+)"/i', $html, $matches)) {
92            return $matches[1];
93        }
94        
95        return null;
96    }
97
98    /**
99     * @return array<string, string|null>
100     */
101    public static function extractData(string $html): array
102    {
103        return [
104            'title' => self::extractTitle($html),
105            'description' => self::extractDescription($html),
106            'full_article' => self::extractFullArticle($html),
107            'thumbnail' => self::extractThumbnail($html),
108        ];
109    }
110}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:52:46 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-with-models/Services/Parsers/BelgaArticleParser.php.html b/backend/coverage-report-with-models/Services/Parsers/BelgaArticleParser.php.html deleted file mode 100644 index dd9848d6..00000000 --- a/backend/coverage-report-with-models/Services/Parsers/BelgaArticleParser.php.html +++ /dev/null @@ -1,220 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Services/Parsers/BelgaArticleParser.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
BelgaArticleParser
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
12
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 canParse
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 extractData
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 getSourceName
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Services\Parsers;
4
5use App\Contracts\ArticleParserInterface;
6
7class BelgaArticleParser implements ArticleParserInterface
8{
9    public function canParse(string $url): bool
10    {
11        return str_contains($url, 'belganewsagency.eu');
12    }
13
14    public function extractData(string $html): array
15    {
16        return BelgaArticlePageParser::extractData($html);
17    }
18
19    public function getSourceName(): string
20    {
21        return 'Belga News Agency';
22    }
23}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:52:46 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-with-models/Services/Parsers/BelgaHomepageParser.php.html b/backend/coverage-report-with-models/Services/Parsers/BelgaHomepageParser.php.html deleted file mode 100644 index d6e8aaaa..00000000 --- a/backend/coverage-report-with-models/Services/Parsers/BelgaHomepageParser.php.html +++ /dev/null @@ -1,173 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Services/Parsers/BelgaHomepageParser.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 5
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
BelgaHomepageParser
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 5
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 extractArticleUrls
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 5
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Services\Parsers;
4
5class BelgaHomepageParser
6{
7    /**
8     * @return array<int, string>
9     */
10    public static function extractArticleUrls(string $html): array
11    {
12        preg_match_all('/href="(https:\/\/www\.belganewsagency\.eu\/[a-z0-9-]+)"/', $html, $matches);
13
14        $urls = collect($matches[1])
15            ->unique()
16            ->toArray();
17
18        return $urls;
19    }
20}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:52:46 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-with-models/Services/Parsers/BelgaHomepageParserAdapter.php.html b/backend/coverage-report-with-models/Services/Parsers/BelgaHomepageParserAdapter.php.html deleted file mode 100644 index 0a675ec3..00000000 --- a/backend/coverage-report-with-models/Services/Parsers/BelgaHomepageParserAdapter.php.html +++ /dev/null @@ -1,247 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Services/Parsers/BelgaHomepageParserAdapter.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 4
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 4
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
BelgaHomepageParserAdapter
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 4
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 4
20
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 canParse
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 extractArticleUrls
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 getHomepageUrl
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 getSourceName
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Services\Parsers;
4
5use App\Contracts\HomepageParserInterface;
6
7class BelgaHomepageParserAdapter implements HomepageParserInterface
8{
9    public function canParse(string $url): bool
10    {
11        return str_contains($url, 'belganewsagency.eu');
12    }
13
14    public function extractArticleUrls(string $html): array
15    {
16        return BelgaHomepageParser::extractArticleUrls($html);
17    }
18
19    public function getHomepageUrl(): string
20    {
21        return 'https://www.belganewsagency.eu/';
22    }
23
24    public function getSourceName(): string
25    {
26        return 'Belga News Agency';
27    }
28}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:52:46 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-with-models/Services/Parsers/VrtArticlePageParser.php.html b/backend/coverage-report-with-models/Services/Parsers/VrtArticlePageParser.php.html deleted file mode 100644 index 82bdc5e3..00000000 --- a/backend/coverage-report-with-models/Services/Parsers/VrtArticlePageParser.php.html +++ /dev/null @@ -1,333 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Services/Parsers/VrtArticlePageParser.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 35
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 5
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
VrtArticlePageParser
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 35
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 5
210
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 extractTitle
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 7
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
20
 extractDescription
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 5
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
12
 extractFullArticle
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 12
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
12
 extractThumbnail
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 5
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
12
 extractData
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 6
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Services\Parsers;
4
5class VrtArticlePageParser
6{
7    public static function extractTitle(string $html): ?string
8    {
9        // Try meta title first
10        if (preg_match('/<meta property="og:title" content="([^"]+)"/i', $html, $matches)) {
11            return html_entity_decode($matches[1], ENT_QUOTES, 'UTF-8');
12        }
13
14        // Try h1 tag
15        if (preg_match('/<h1[^>]*>([^<]+)<\/h1>/i', $html, $matches)) {
16            return html_entity_decode(strip_tags($matches[1]), ENT_QUOTES, 'UTF-8');
17        }
18
19        // Try title tag
20        if (preg_match('/<title>([^<]+)<\/title>/i', $html, $matches)) {
21            return html_entity_decode($matches[1], ENT_QUOTES, 'UTF-8');
22        }
23
24        return null;
25    }
26
27    public static function extractDescription(string $html): ?string
28    {
29        // Try meta description first
30        if (preg_match('/<meta property="og:description" content="([^"]+)"/i', $html, $matches)) {
31            return html_entity_decode($matches[1], ENT_QUOTES, 'UTF-8');
32        }
33
34        // Try to find first paragraph in article content
35        if (preg_match('/<p[^>]*>([^<]+(?:<[^\/](?!p)[^>]*>[^<]*<\/[^>]*>[^<]*)*)<\/p>/i', $html, $matches)) {
36            return html_entity_decode(strip_tags($matches[1]), ENT_QUOTES, 'UTF-8');
37        }
38
39        return null;
40    }
41
42    public static function extractFullArticle(string $html): ?string
43    {
44        // Remove scripts, styles, and other non-content elements
45        $cleanHtml = preg_replace('/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/mi', '', $html);
46        $cleanHtml = preg_replace('/<style\b[^<]*(?:(?!<\/style>)<[^<]*)*<\/style>/mi', '', $cleanHtml);
47
48        // Extract all paragraph content
49        preg_match_all('/<p[^>]*>(.*?)<\/p>/is', $cleanHtml, $matches);
50
51        if (!empty($matches[1])) {
52            $paragraphs = array_map(function($paragraph) {
53                return html_entity_decode(strip_tags($paragraph), ENT_QUOTES, 'UTF-8');
54            }, $matches[1]);
55
56            // Filter out empty paragraphs and join with double newlines
57            $fullText = implode("\n\n", array_filter($paragraphs, function($p) {
58                return trim($p) !== '';
59            }));
60
61            return $fullText ?: null;
62        }
63
64        return null;
65    }
66
67    public static function extractThumbnail(string $html): ?string
68    {
69        if (preg_match('/<meta property="og:image" content="([^"]+)"/i', $html, $matches)) {
70            return $matches[1];
71        }
72
73        if (preg_match('/<img[^>]+src="([^"]+)"/i', $html, $matches)) {
74            return $matches[1];
75        }
76
77        return null;
78    }
79
80    /**
81     * @return array<string, string|null>
82     */
83    public static function extractData(string $html): array
84    {
85        return [
86            'title' => self::extractTitle($html),
87            'description' => self::extractDescription($html),
88            'full_article' => self::extractFullArticle($html),
89            'thumbnail' => self::extractThumbnail($html),
90        ];
91    }
92}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:52:46 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-with-models/Services/Parsers/VrtArticleParser.php.html b/backend/coverage-report-with-models/Services/Parsers/VrtArticleParser.php.html deleted file mode 100644 index 18ed1094..00000000 --- a/backend/coverage-report-with-models/Services/Parsers/VrtArticleParser.php.html +++ /dev/null @@ -1,220 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Services/Parsers/VrtArticleParser.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
VrtArticleParser
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
12
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 canParse
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 extractData
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 getSourceName
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Services\Parsers;
4
5use App\Contracts\ArticleParserInterface;
6
7class VrtArticleParser implements ArticleParserInterface
8{
9    public function canParse(string $url): bool
10    {
11        return str_contains($url, 'vrt.be');
12    }
13
14    public function extractData(string $html): array
15    {
16        return VrtArticlePageParser::extractData($html);
17    }
18
19    public function getSourceName(): string
20    {
21        return 'VRT News';
22    }
23}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:52:46 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-with-models/Services/Parsers/VrtHomepageParser.php.html b/backend/coverage-report-with-models/Services/Parsers/VrtHomepageParser.php.html deleted file mode 100644 index 66f2f5ea..00000000 --- a/backend/coverage-report-with-models/Services/Parsers/VrtHomepageParser.php.html +++ /dev/null @@ -1,175 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Services/Parsers/VrtHomepageParser.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 6
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
VrtHomepageParser
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 6
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 extractArticleUrls
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 6
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Services\Parsers;
4
5class VrtHomepageParser
6{
7    /**
8     * @return array<int, string>
9     */
10    public static function extractArticleUrls(string $html): array
11    {
12        // Extract article links using regex
13        preg_match_all('/href="(\/vrtnws\/en\/\d{4}\/\d{2}\/\d{2}\/[^"]+)"/', $html, $matches);
14
15        $urls = collect($matches[1])
16            ->unique()
17            ->map(fn ($path) => 'https://www.vrt.be' . $path)
18            ->toArray();
19
20        return $urls;
21    }
22}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:52:46 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-with-models/Services/Parsers/VrtHomepageParserAdapter.php.html b/backend/coverage-report-with-models/Services/Parsers/VrtHomepageParserAdapter.php.html deleted file mode 100644 index 93e74150..00000000 --- a/backend/coverage-report-with-models/Services/Parsers/VrtHomepageParserAdapter.php.html +++ /dev/null @@ -1,247 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Services/Parsers/VrtHomepageParserAdapter.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 4
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 4
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
VrtHomepageParserAdapter
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 4
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 4
20
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 canParse
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 extractArticleUrls
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 getHomepageUrl
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 getSourceName
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Services\Parsers;
4
5use App\Contracts\HomepageParserInterface;
6
7class VrtHomepageParserAdapter implements HomepageParserInterface
8{
9    public function canParse(string $url): bool
10    {
11        return str_contains($url, 'vrt.be');
12    }
13
14    public function extractArticleUrls(string $html): array
15    {
16        return VrtHomepageParser::extractArticleUrls($html);
17    }
18
19    public function getHomepageUrl(): string
20    {
21        return 'https://www.vrt.be/vrtnws/en/';
22    }
23
24    public function getSourceName(): string
25    {
26        return 'VRT News';
27    }
28}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:52:46 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-with-models/Services/Parsers/dashboard.html b/backend/coverage-report-with-models/Services/Parsers/dashboard.html deleted file mode 100644 index d1c9ff53..00000000 --- a/backend/coverage-report-with-models/Services/Parsers/dashboard.html +++ /dev/null @@ -1,329 +0,0 @@ - - - - - Dashboard for /var/www/html/backend/app/Services/Parsers - - - - - - - -
-
-
-
- -
-
-
-
-
-
-
-

Classes

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
- -
-
-

Methods

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
- - -
- - - - - - diff --git a/backend/coverage-report-with-models/Services/Parsers/index.html b/backend/coverage-report-with-models/Services/Parsers/index.html deleted file mode 100644 index 334cd7c2..00000000 --- a/backend/coverage-report-with-models/Services/Parsers/index.html +++ /dev/null @@ -1,316 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Services/Parsers - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 102
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 26
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 8
BelgaArticlePageParser.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 42
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 5
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
BelgaArticleParser.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
BelgaHomepageParser.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 5
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
BelgaHomepageParserAdapter.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 4
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 4
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
VrtArticlePageParser.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 35
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 5
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
VrtArticleParser.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
VrtHomepageParser.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 6
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
VrtHomepageParserAdapter.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 4
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 4
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- -
- - diff --git a/backend/coverage-report-with-models/Services/Publishing/ArticlePublishingService.php.html b/backend/coverage-report-with-models/Services/Publishing/ArticlePublishingService.php.html deleted file mode 100644 index 6ddf4781..00000000 --- a/backend/coverage-report-with-models/Services/Publishing/ArticlePublishingService.php.html +++ /dev/null @@ -1,260 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Services/Publishing/ArticlePublishingService.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 36
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
ArticlePublishingService
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 36
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
30
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 publishToRoutedChannels
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 14
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
12
 publishToChannel
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 22
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
6
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Services\Publishing;
4
5use App\Enums\PlatformEnum;
6use App\Exceptions\PublishException;
7use App\Models\Article;
8use App\Models\ArticlePublication;
9use App\Models\PlatformChannel;
10use App\Modules\Lemmy\Services\LemmyPublisher;
11use App\Services\Log\LogSaver;
12use Exception;
13use Illuminate\Database\Eloquent\Collection as EloquentCollection;
14use Illuminate\Support\Collection;
15use RuntimeException;
16
17class ArticlePublishingService
18{
19    /**
20     * @param array<string, mixed> $extractedData
21     * @return EloquentCollection<int, ArticlePublication>
22     * @throws PublishException
23     */
24    public function publishToRoutedChannels(Article $article, array $extractedData): EloquentCollection
25    {
26        if (! $article->is_valid) {
27            throw new PublishException($article, PlatformEnum::LEMMY, new RuntimeException('CANNOT_PUBLISH_INVALID_ARTICLE'));
28        }
29
30        $feed = $article->feed;
31        
32        /** @var EloquentCollection<int, PlatformChannel> $activeChannels */
33        $activeChannels = $feed->activeChannels()->with(['platformInstance', 'activePlatformAccounts'])->get();
34
35        return $activeChannels->map(function (PlatformChannel $channel) use ($article, $extractedData) {
36            $account = $channel->activePlatformAccounts()->first();
37
38            if (! $account) {
39                LogSaver::warning('No active account for channel', $channel, [
40                    'article_id' => $article->id
41                ]);
42
43                return null;
44            }
45
46            return $this->publishToChannel($article, $extractedData, $channel, $account);
47        })
48        ->filter();
49    }
50
51    /**
52     * @param array<string, mixed> $extractedData
53     */
54    private function publishToChannel(Article $article, array $extractedData, PlatformChannel $channel, mixed $account): ?ArticlePublication
55    {
56        try {
57            $publisher = new LemmyPublisher($account);
58            $postData = $publisher->publishToChannel($article, $extractedData, $channel);
59
60            $publication = ArticlePublication::create([
61                'article_id' => $article->id,
62                'post_id' => $postData['post_view']['post']['id'],
63                'platform_channel_id' => $channel->id,
64                'published_by' => $account->username,
65                'published_at' => now(),
66                'platform' => $channel->platformInstance->platform->value,
67                'publication_data' => $postData,
68            ]);
69
70            LogSaver::info('Published to channel via routing', $channel, [
71                'article_id' => $article->id,
72                'priority' => $channel->pivot->priority ?? null
73            ]);
74
75            return $publication;
76        } catch (Exception $e) {
77            LogSaver::warning('Failed to publish to channel', $channel, [
78                'article_id' => $article->id,
79                'error' => $e->getMessage()
80            ]);
81
82            return null;
83        }
84    }
85}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:52:46 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-with-models/Services/Publishing/dashboard.html b/backend/coverage-report-with-models/Services/Publishing/dashboard.html deleted file mode 100644 index 612d3b1e..00000000 --- a/backend/coverage-report-with-models/Services/Publishing/dashboard.html +++ /dev/null @@ -1,291 +0,0 @@ - - - - - Dashboard for /var/www/html/backend/app/Services/Publishing - - - - - - - -
-
-
-
- -
-
-
-
-
-
-
-

Classes

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
-
-
-

Insufficient Coverage

-
- - - - - - - - - - - -
ClassCoverage
App\Services\Publishing\ArticlePublishingService0%
-
-
-
-

Project Risks

-
- - - - - - - - - - - -
ClassCRAP
App\Services\Publishing\ArticlePublishingService30
-
-
-
-
-
-

Methods

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
-
-
-

Insufficient Coverage

-
- - - - - - - - - - - - -
MethodCoverage
publishToRoutedChannels0%
publishToChannel0%
-
-
-
-

Project Risks

-
- - - - - - - - - - - - -
MethodCRAP
publishToRoutedChannels12
publishToChannel6
-
-
-
- -
- - - - - - diff --git a/backend/coverage-report-with-models/Services/Publishing/index.html b/backend/coverage-report-with-models/Services/Publishing/index.html deleted file mode 100644 index 7e53cd20..00000000 --- a/backend/coverage-report-with-models/Services/Publishing/index.html +++ /dev/null @@ -1,120 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Services/Publishing - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 36
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
ArticlePublishingService.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 36
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- -
- - diff --git a/backend/coverage-report-with-models/Services/RoutingValidationService.php.html b/backend/coverage-report-with-models/Services/RoutingValidationService.php.html deleted file mode 100644 index 137c2ff6..00000000 --- a/backend/coverage-report-with-models/Services/RoutingValidationService.php.html +++ /dev/null @@ -1,184 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Services/RoutingValidationService.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 7
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
RoutingValidationService
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 7
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
30
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 validateLanguageCompatibility
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 7
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
30
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Services;
4
5use App\Exceptions\RoutingMismatchException;
6use App\Models\Feed;
7use App\Models\PlatformChannel;
8use Illuminate\Support\Collection;
9
10class RoutingValidationService
11{
12    /**
13     * @param Collection<int, PlatformChannel> $channels
14     * @throws RoutingMismatchException
15     */
16    public function validateLanguageCompatibility(Feed $feed, Collection $channels): void
17    {
18        if (! $feed->language) {
19            return;
20        }
21
22        foreach ($channels as $channel) {
23            if (! $channel->language) {
24                continue;
25            }
26
27            if ($feed->language !== $channel->language) {
28                throw new RoutingMismatchException($feed, $channel);
29            }
30        }
31    }
32}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:52:46 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-with-models/Services/SystemStatusService.php.html b/backend/coverage-report-with-models/Services/SystemStatusService.php.html deleted file mode 100644 index c16cdf2b..00000000 --- a/backend/coverage-report-with-models/Services/SystemStatusService.php.html +++ /dev/null @@ -1,226 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Services/SystemStatusService.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 21
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
SystemStatusService
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 21
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
72
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 getSystemStatus
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 20
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
56
 canProcessArticles
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Services;
4
5use App\Models\Feed;
6use App\Models\Route;
7use App\Models\PlatformChannel;
8use App\Models\Setting;
9
10class SystemStatusService
11{
12    /**
13     * @return array{is_enabled: bool, status: string, status_class: string, reasons: array<int, string>}
14     */
15    public function getSystemStatus(): array
16    {
17        $reasons = [];
18        $isEnabled = true;
19
20        if (!Setting::isArticleProcessingEnabled()) {
21            $isEnabled = false;
22            $reasons[] = 'Manually disabled by user';
23        }
24
25        if (!Feed::where('is_active', true)->exists()) {
26            $isEnabled = false;
27            $reasons[] = 'No active feeds configured';
28        }
29
30        if (!PlatformChannel::where('is_active', true)->exists()) {
31            $isEnabled = false;
32            $reasons[] = 'No active platform channels configured';
33        }
34
35        if (!Route::where('is_active', true)->exists()) {
36            $isEnabled = false;
37            $reasons[] = 'No active feed-to-channel routes configured';
38        }
39
40        return [
41            'is_enabled' => $isEnabled,
42            'status' => $isEnabled ? 'Enabled' : 'Disabled',
43            'status_class' => $isEnabled ? 'text-green-600' : 'text-red-600',
44            'reasons' => $reasons,
45        ];
46    }
47
48    public function canProcessArticles(): bool
49    {
50        return $this->getSystemStatus()['is_enabled'];
51    }
52}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 18:52:46 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report-with-models/Services/dashboard.html b/backend/coverage-report-with-models/Services/dashboard.html deleted file mode 100644 index 515f23da..00000000 --- a/backend/coverage-report-with-models/Services/dashboard.html +++ /dev/null @@ -1,395 +0,0 @@ - - - - - Dashboard for /var/www/html/backend/app/Services - - - - - - - -
-
-
-
- -
-
-
-
-
-
-
-

Classes

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
- -
-
-

Methods

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
-
- - -
- -
- - - - - - diff --git a/backend/coverage-report-with-models/Services/index.html b/backend/coverage-report-with-models/Services/index.html deleted file mode 100644 index 8db9f22d..00000000 --- a/backend/coverage-report-with-models/Services/index.html +++ /dev/null @@ -1,399 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Services - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 10.78% covered (danger) -
-
-
10.78%
40 / 371
-
- 7.14% covered (danger) -
-
-
7.14%
4 / 56
-
- 5.00% covered (danger) -
-
-
5.00%
1 / 20
Article
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 69
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 7
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
Auth
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 12
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
Factories
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 19
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 5
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
Http
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 44
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
Log
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 17
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 5
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
Parsers
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 102
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 26
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 8
Publishing
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 36
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
DashboardStatsService.php
-
- 100.00% covered (success) -
-
-
100.00%
40 / 40
-
- 100.00% covered (success) -
-
-
100.00%
4 / 4
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
OnboardingRedirectService.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 4
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
RoutingValidationService.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 7
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
SystemStatusService.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 21
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- -
- - diff --git a/backend/coverage-report-with-models/_css/bootstrap.min.css b/backend/coverage-report-with-models/_css/bootstrap.min.css deleted file mode 100644 index 27d4921c..00000000 --- a/backend/coverage-report-with-models/_css/bootstrap.min.css +++ /dev/null @@ -1,6 +0,0 @@ -@charset "UTF-8";/*! - * Bootstrap v5.3.6 (https://getbootstrap.com/) - * Copyright 2011-2025 The Bootstrap Authors - * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) - */:root,[data-bs-theme=light]{--bs-blue:#0d6efd;--bs-indigo:#6610f2;--bs-purple:#6f42c1;--bs-pink:#d63384;--bs-red:#dc3545;--bs-orange:#fd7e14;--bs-yellow:#ffc107;--bs-green:#198754;--bs-teal:#20c997;--bs-cyan:#0dcaf0;--bs-black:#000;--bs-white:#fff;--bs-gray:#6c757d;--bs-gray-dark:#343a40;--bs-gray-100:#f8f9fa;--bs-gray-200:#e9ecef;--bs-gray-300:#dee2e6;--bs-gray-400:#ced4da;--bs-gray-500:#adb5bd;--bs-gray-600:#6c757d;--bs-gray-700:#495057;--bs-gray-800:#343a40;--bs-gray-900:#212529;--bs-primary:#0d6efd;--bs-secondary:#6c757d;--bs-success:#198754;--bs-info:#0dcaf0;--bs-warning:#ffc107;--bs-danger:#dc3545;--bs-light:#f8f9fa;--bs-dark:#212529;--bs-primary-rgb:13,110,253;--bs-secondary-rgb:108,117,125;--bs-success-rgb:25,135,84;--bs-info-rgb:13,202,240;--bs-warning-rgb:255,193,7;--bs-danger-rgb:220,53,69;--bs-light-rgb:248,249,250;--bs-dark-rgb:33,37,41;--bs-primary-text-emphasis:#052c65;--bs-secondary-text-emphasis:#2b2f32;--bs-success-text-emphasis:#0a3622;--bs-info-text-emphasis:#055160;--bs-warning-text-emphasis:#664d03;--bs-danger-text-emphasis:#58151c;--bs-light-text-emphasis:#495057;--bs-dark-text-emphasis:#495057;--bs-primary-bg-subtle:#cfe2ff;--bs-secondary-bg-subtle:#e2e3e5;--bs-success-bg-subtle:#d1e7dd;--bs-info-bg-subtle:#cff4fc;--bs-warning-bg-subtle:#fff3cd;--bs-danger-bg-subtle:#f8d7da;--bs-light-bg-subtle:#fcfcfd;--bs-dark-bg-subtle:#ced4da;--bs-primary-border-subtle:#9ec5fe;--bs-secondary-border-subtle:#c4c8cb;--bs-success-border-subtle:#a3cfbb;--bs-info-border-subtle:#9eeaf9;--bs-warning-border-subtle:#ffe69c;--bs-danger-border-subtle:#f1aeb5;--bs-light-border-subtle:#e9ecef;--bs-dark-border-subtle:#adb5bd;--bs-white-rgb:255,255,255;--bs-black-rgb:0,0,0;--bs-font-sans-serif:system-ui,-apple-system,"Segoe UI",Roboto,"Helvetica Neue","Noto Sans","Liberation Sans",Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";--bs-font-monospace:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;--bs-gradient:linear-gradient(180deg, rgba(255, 255, 255, 0.15), rgba(255, 255, 255, 0));--bs-body-font-family:var(--bs-font-sans-serif);--bs-body-font-size:1rem;--bs-body-font-weight:400;--bs-body-line-height:1.5;--bs-body-color:#212529;--bs-body-color-rgb:33,37,41;--bs-body-bg:#fff;--bs-body-bg-rgb:255,255,255;--bs-emphasis-color:#000;--bs-emphasis-color-rgb:0,0,0;--bs-secondary-color:rgba(33, 37, 41, 0.75);--bs-secondary-color-rgb:33,37,41;--bs-secondary-bg:#e9ecef;--bs-secondary-bg-rgb:233,236,239;--bs-tertiary-color:rgba(33, 37, 41, 0.5);--bs-tertiary-color-rgb:33,37,41;--bs-tertiary-bg:#f8f9fa;--bs-tertiary-bg-rgb:248,249,250;--bs-heading-color:inherit;--bs-link-color:#0d6efd;--bs-link-color-rgb:13,110,253;--bs-link-decoration:underline;--bs-link-hover-color:#0a58ca;--bs-link-hover-color-rgb:10,88,202;--bs-code-color:#d63384;--bs-highlight-color:#212529;--bs-highlight-bg:#fff3cd;--bs-border-width:1px;--bs-border-style:solid;--bs-border-color:#dee2e6;--bs-border-color-translucent:rgba(0, 0, 0, 0.175);--bs-border-radius:0.375rem;--bs-border-radius-sm:0.25rem;--bs-border-radius-lg:0.5rem;--bs-border-radius-xl:1rem;--bs-border-radius-xxl:2rem;--bs-border-radius-2xl:var(--bs-border-radius-xxl);--bs-border-radius-pill:50rem;--bs-box-shadow:0 0.5rem 1rem rgba(0, 0, 0, 0.15);--bs-box-shadow-sm:0 0.125rem 0.25rem rgba(0, 0, 0, 0.075);--bs-box-shadow-lg:0 1rem 3rem rgba(0, 0, 0, 0.175);--bs-box-shadow-inset:inset 0 1px 2px rgba(0, 0, 0, 0.075);--bs-focus-ring-width:0.25rem;--bs-focus-ring-opacity:0.25;--bs-focus-ring-color:rgba(13, 110, 253, 0.25);--bs-form-valid-color:#198754;--bs-form-valid-border-color:#198754;--bs-form-invalid-color:#dc3545;--bs-form-invalid-border-color:#dc3545}[data-bs-theme=dark]{color-scheme:dark;--bs-body-color:#dee2e6;--bs-body-color-rgb:222,226,230;--bs-body-bg:#212529;--bs-body-bg-rgb:33,37,41;--bs-emphasis-color:#fff;--bs-emphasis-color-rgb:255,255,255;--bs-secondary-color:rgba(222, 226, 230, 0.75);--bs-secondary-color-rgb:222,226,230;--bs-secondary-bg:#343a40;--bs-secondary-bg-rgb:52,58,64;--bs-tertiary-color:rgba(222, 226, 230, 0.5);--bs-tertiary-color-rgb:222,226,230;--bs-tertiary-bg:#2b3035;--bs-tertiary-bg-rgb:43,48,53;--bs-primary-text-emphasis:#6ea8fe;--bs-secondary-text-emphasis:#a7acb1;--bs-success-text-emphasis:#75b798;--bs-info-text-emphasis:#6edff6;--bs-warning-text-emphasis:#ffda6a;--bs-danger-text-emphasis:#ea868f;--bs-light-text-emphasis:#f8f9fa;--bs-dark-text-emphasis:#dee2e6;--bs-primary-bg-subtle:#031633;--bs-secondary-bg-subtle:#161719;--bs-success-bg-subtle:#051b11;--bs-info-bg-subtle:#032830;--bs-warning-bg-subtle:#332701;--bs-danger-bg-subtle:#2c0b0e;--bs-light-bg-subtle:#343a40;--bs-dark-bg-subtle:#1a1d20;--bs-primary-border-subtle:#084298;--bs-secondary-border-subtle:#41464b;--bs-success-border-subtle:#0f5132;--bs-info-border-subtle:#087990;--bs-warning-border-subtle:#997404;--bs-danger-border-subtle:#842029;--bs-light-border-subtle:#495057;--bs-dark-border-subtle:#343a40;--bs-heading-color:inherit;--bs-link-color:#6ea8fe;--bs-link-hover-color:#8bb9fe;--bs-link-color-rgb:110,168,254;--bs-link-hover-color-rgb:139,185,254;--bs-code-color:#e685b5;--bs-highlight-color:#dee2e6;--bs-highlight-bg:#664d03;--bs-border-color:#495057;--bs-border-color-translucent:rgba(255, 255, 255, 0.15);--bs-form-valid-color:#75b798;--bs-form-valid-border-color:#75b798;--bs-form-invalid-color:#ea868f;--bs-form-invalid-border-color:#ea868f}*,::after,::before{box-sizing:border-box}@media (prefers-reduced-motion:no-preference){:root{scroll-behavior:smooth}}body{margin:0;font-family:var(--bs-body-font-family);font-size:var(--bs-body-font-size);font-weight:var(--bs-body-font-weight);line-height:var(--bs-body-line-height);color:var(--bs-body-color);text-align:var(--bs-body-text-align);background-color:var(--bs-body-bg);-webkit-text-size-adjust:100%;-webkit-tap-highlight-color:transparent}hr{margin:1rem 0;color:inherit;border:0;border-top:var(--bs-border-width) solid;opacity:.25}.h1,.h2,.h3,.h4,.h5,.h6,h1,h2,h3,h4,h5,h6{margin-top:0;margin-bottom:.5rem;font-weight:500;line-height:1.2;color:var(--bs-heading-color)}.h1,h1{font-size:calc(1.375rem + 1.5vw)}@media (min-width:1200px){.h1,h1{font-size:2.5rem}}.h2,h2{font-size:calc(1.325rem + .9vw)}@media (min-width:1200px){.h2,h2{font-size:2rem}}.h3,h3{font-size:calc(1.3rem + .6vw)}@media (min-width:1200px){.h3,h3{font-size:1.75rem}}.h4,h4{font-size:calc(1.275rem + .3vw)}@media (min-width:1200px){.h4,h4{font-size:1.5rem}}.h5,h5{font-size:1.25rem}.h6,h6{font-size:1rem}p{margin-top:0;margin-bottom:1rem}abbr[title]{-webkit-text-decoration:underline dotted;text-decoration:underline dotted;cursor:help;-webkit-text-decoration-skip-ink:none;text-decoration-skip-ink:none}address{margin-bottom:1rem;font-style:normal;line-height:inherit}ol,ul{padding-left:2rem}dl,ol,ul{margin-top:0;margin-bottom:1rem}ol ol,ol ul,ul ol,ul ul{margin-bottom:0}dt{font-weight:700}dd{margin-bottom:.5rem;margin-left:0}blockquote{margin:0 0 1rem}b,strong{font-weight:bolder}.small,small{font-size:.875em}.mark,mark{padding:.1875em;color:var(--bs-highlight-color);background-color:var(--bs-highlight-bg)}sub,sup{position:relative;font-size:.75em;line-height:0;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}a{color:rgba(var(--bs-link-color-rgb),var(--bs-link-opacity,1));text-decoration:underline}a:hover{--bs-link-color-rgb:var(--bs-link-hover-color-rgb)}a:not([href]):not([class]),a:not([href]):not([class]):hover{color:inherit;text-decoration:none}code,kbd,pre,samp{font-family:var(--bs-font-monospace);font-size:1em}pre{display:block;margin-top:0;margin-bottom:1rem;overflow:auto;font-size:.875em}pre code{font-size:inherit;color:inherit;word-break:normal}code{font-size:.875em;color:var(--bs-code-color);word-wrap:break-word}a>code{color:inherit}kbd{padding:.1875rem .375rem;font-size:.875em;color:var(--bs-body-bg);background-color:var(--bs-body-color);border-radius:.25rem}kbd kbd{padding:0;font-size:1em}figure{margin:0 0 1rem}img,svg{vertical-align:middle}table{caption-side:bottom;border-collapse:collapse}caption{padding-top:.5rem;padding-bottom:.5rem;color:var(--bs-secondary-color);text-align:left}th{text-align:inherit;text-align:-webkit-match-parent}tbody,td,tfoot,th,thead,tr{border-color:inherit;border-style:solid;border-width:0}label{display:inline-block}button{border-radius:0}button:focus:not(:focus-visible){outline:0}button,input,optgroup,select,textarea{margin:0;font-family:inherit;font-size:inherit;line-height:inherit}button,select{text-transform:none}[role=button]{cursor:pointer}select{word-wrap:normal}select:disabled{opacity:1}[list]:not([type=date]):not([type=datetime-local]):not([type=month]):not([type=week]):not([type=time])::-webkit-calendar-picker-indicator{display:none!important}[type=button],[type=reset],[type=submit],button{-webkit-appearance:button}[type=button]:not(:disabled),[type=reset]:not(:disabled),[type=submit]:not(:disabled),button:not(:disabled){cursor:pointer}::-moz-focus-inner{padding:0;border-style:none}textarea{resize:vertical}fieldset{min-width:0;padding:0;margin:0;border:0}legend{float:left;width:100%;padding:0;margin-bottom:.5rem;line-height:inherit;font-size:calc(1.275rem + .3vw)}@media (min-width:1200px){legend{font-size:1.5rem}}legend+*{clear:left}::-webkit-datetime-edit-day-field,::-webkit-datetime-edit-fields-wrapper,::-webkit-datetime-edit-hour-field,::-webkit-datetime-edit-minute,::-webkit-datetime-edit-month-field,::-webkit-datetime-edit-text,::-webkit-datetime-edit-year-field{padding:0}::-webkit-inner-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-color-swatch-wrapper{padding:0}::-webkit-file-upload-button{font:inherit;-webkit-appearance:button}::file-selector-button{font:inherit;-webkit-appearance:button}output{display:inline-block}iframe{border:0}summary{display:list-item;cursor:pointer}progress{vertical-align:baseline}[hidden]{display:none!important}.lead{font-size:1.25rem;font-weight:300}.display-1{font-weight:300;line-height:1.2;font-size:calc(1.625rem + 4.5vw)}@media (min-width:1200px){.display-1{font-size:5rem}}.display-2{font-weight:300;line-height:1.2;font-size:calc(1.575rem + 3.9vw)}@media (min-width:1200px){.display-2{font-size:4.5rem}}.display-3{font-weight:300;line-height:1.2;font-size:calc(1.525rem + 3.3vw)}@media (min-width:1200px){.display-3{font-size:4rem}}.display-4{font-weight:300;line-height:1.2;font-size:calc(1.475rem + 2.7vw)}@media (min-width:1200px){.display-4{font-size:3.5rem}}.display-5{font-weight:300;line-height:1.2;font-size:calc(1.425rem + 2.1vw)}@media (min-width:1200px){.display-5{font-size:3rem}}.display-6{font-weight:300;line-height:1.2;font-size:calc(1.375rem + 1.5vw)}@media (min-width:1200px){.display-6{font-size:2.5rem}}.list-unstyled{padding-left:0;list-style:none}.list-inline{padding-left:0;list-style:none}.list-inline-item{display:inline-block}.list-inline-item:not(:last-child){margin-right:.5rem}.initialism{font-size:.875em;text-transform:uppercase}.blockquote{margin-bottom:1rem;font-size:1.25rem}.blockquote>:last-child{margin-bottom:0}.blockquote-footer{margin-top:-1rem;margin-bottom:1rem;font-size:.875em;color:#6c757d}.blockquote-footer::before{content:"— "}.img-fluid{max-width:100%;height:auto}.img-thumbnail{padding:.25rem;background-color:var(--bs-body-bg);border:var(--bs-border-width) solid var(--bs-border-color);border-radius:var(--bs-border-radius);max-width:100%;height:auto}.figure{display:inline-block}.figure-img{margin-bottom:.5rem;line-height:1}.figure-caption{font-size:.875em;color:var(--bs-secondary-color)}.container,.container-fluid,.container-lg,.container-md,.container-sm,.container-xl,.container-xxl{--bs-gutter-x:1.5rem;--bs-gutter-y:0;width:100%;padding-right:calc(var(--bs-gutter-x) * .5);padding-left:calc(var(--bs-gutter-x) * .5);margin-right:auto;margin-left:auto}@media (min-width:576px){.container,.container-sm{max-width:540px}}@media (min-width:768px){.container,.container-md,.container-sm{max-width:720px}}@media (min-width:992px){.container,.container-lg,.container-md,.container-sm{max-width:960px}}@media (min-width:1200px){.container,.container-lg,.container-md,.container-sm,.container-xl{max-width:1140px}}@media (min-width:1400px){.container,.container-lg,.container-md,.container-sm,.container-xl,.container-xxl{max-width:1320px}}:root{--bs-breakpoint-xs:0;--bs-breakpoint-sm:576px;--bs-breakpoint-md:768px;--bs-breakpoint-lg:992px;--bs-breakpoint-xl:1200px;--bs-breakpoint-xxl:1400px}.row{--bs-gutter-x:1.5rem;--bs-gutter-y:0;display:flex;flex-wrap:wrap;margin-top:calc(-1 * var(--bs-gutter-y));margin-right:calc(-.5 * var(--bs-gutter-x));margin-left:calc(-.5 * var(--bs-gutter-x))}.row>*{flex-shrink:0;width:100%;max-width:100%;padding-right:calc(var(--bs-gutter-x) * .5);padding-left:calc(var(--bs-gutter-x) * .5);margin-top:var(--bs-gutter-y)}.col{flex:1 0 0}.row-cols-auto>*{flex:0 0 auto;width:auto}.row-cols-1>*{flex:0 0 auto;width:100%}.row-cols-2>*{flex:0 0 auto;width:50%}.row-cols-3>*{flex:0 0 auto;width:33.33333333%}.row-cols-4>*{flex:0 0 auto;width:25%}.row-cols-5>*{flex:0 0 auto;width:20%}.row-cols-6>*{flex:0 0 auto;width:16.66666667%}.col-auto{flex:0 0 auto;width:auto}.col-1{flex:0 0 auto;width:8.33333333%}.col-2{flex:0 0 auto;width:16.66666667%}.col-3{flex:0 0 auto;width:25%}.col-4{flex:0 0 auto;width:33.33333333%}.col-5{flex:0 0 auto;width:41.66666667%}.col-6{flex:0 0 auto;width:50%}.col-7{flex:0 0 auto;width:58.33333333%}.col-8{flex:0 0 auto;width:66.66666667%}.col-9{flex:0 0 auto;width:75%}.col-10{flex:0 0 auto;width:83.33333333%}.col-11{flex:0 0 auto;width:91.66666667%}.col-12{flex:0 0 auto;width:100%}.offset-1{margin-left:8.33333333%}.offset-2{margin-left:16.66666667%}.offset-3{margin-left:25%}.offset-4{margin-left:33.33333333%}.offset-5{margin-left:41.66666667%}.offset-6{margin-left:50%}.offset-7{margin-left:58.33333333%}.offset-8{margin-left:66.66666667%}.offset-9{margin-left:75%}.offset-10{margin-left:83.33333333%}.offset-11{margin-left:91.66666667%}.g-0,.gx-0{--bs-gutter-x:0}.g-0,.gy-0{--bs-gutter-y:0}.g-1,.gx-1{--bs-gutter-x:0.25rem}.g-1,.gy-1{--bs-gutter-y:0.25rem}.g-2,.gx-2{--bs-gutter-x:0.5rem}.g-2,.gy-2{--bs-gutter-y:0.5rem}.g-3,.gx-3{--bs-gutter-x:1rem}.g-3,.gy-3{--bs-gutter-y:1rem}.g-4,.gx-4{--bs-gutter-x:1.5rem}.g-4,.gy-4{--bs-gutter-y:1.5rem}.g-5,.gx-5{--bs-gutter-x:3rem}.g-5,.gy-5{--bs-gutter-y:3rem}@media (min-width:576px){.col-sm{flex:1 0 0}.row-cols-sm-auto>*{flex:0 0 auto;width:auto}.row-cols-sm-1>*{flex:0 0 auto;width:100%}.row-cols-sm-2>*{flex:0 0 auto;width:50%}.row-cols-sm-3>*{flex:0 0 auto;width:33.33333333%}.row-cols-sm-4>*{flex:0 0 auto;width:25%}.row-cols-sm-5>*{flex:0 0 auto;width:20%}.row-cols-sm-6>*{flex:0 0 auto;width:16.66666667%}.col-sm-auto{flex:0 0 auto;width:auto}.col-sm-1{flex:0 0 auto;width:8.33333333%}.col-sm-2{flex:0 0 auto;width:16.66666667%}.col-sm-3{flex:0 0 auto;width:25%}.col-sm-4{flex:0 0 auto;width:33.33333333%}.col-sm-5{flex:0 0 auto;width:41.66666667%}.col-sm-6{flex:0 0 auto;width:50%}.col-sm-7{flex:0 0 auto;width:58.33333333%}.col-sm-8{flex:0 0 auto;width:66.66666667%}.col-sm-9{flex:0 0 auto;width:75%}.col-sm-10{flex:0 0 auto;width:83.33333333%}.col-sm-11{flex:0 0 auto;width:91.66666667%}.col-sm-12{flex:0 0 auto;width:100%}.offset-sm-0{margin-left:0}.offset-sm-1{margin-left:8.33333333%}.offset-sm-2{margin-left:16.66666667%}.offset-sm-3{margin-left:25%}.offset-sm-4{margin-left:33.33333333%}.offset-sm-5{margin-left:41.66666667%}.offset-sm-6{margin-left:50%}.offset-sm-7{margin-left:58.33333333%}.offset-sm-8{margin-left:66.66666667%}.offset-sm-9{margin-left:75%}.offset-sm-10{margin-left:83.33333333%}.offset-sm-11{margin-left:91.66666667%}.g-sm-0,.gx-sm-0{--bs-gutter-x:0}.g-sm-0,.gy-sm-0{--bs-gutter-y:0}.g-sm-1,.gx-sm-1{--bs-gutter-x:0.25rem}.g-sm-1,.gy-sm-1{--bs-gutter-y:0.25rem}.g-sm-2,.gx-sm-2{--bs-gutter-x:0.5rem}.g-sm-2,.gy-sm-2{--bs-gutter-y:0.5rem}.g-sm-3,.gx-sm-3{--bs-gutter-x:1rem}.g-sm-3,.gy-sm-3{--bs-gutter-y:1rem}.g-sm-4,.gx-sm-4{--bs-gutter-x:1.5rem}.g-sm-4,.gy-sm-4{--bs-gutter-y:1.5rem}.g-sm-5,.gx-sm-5{--bs-gutter-x:3rem}.g-sm-5,.gy-sm-5{--bs-gutter-y:3rem}}@media (min-width:768px){.col-md{flex:1 0 0}.row-cols-md-auto>*{flex:0 0 auto;width:auto}.row-cols-md-1>*{flex:0 0 auto;width:100%}.row-cols-md-2>*{flex:0 0 auto;width:50%}.row-cols-md-3>*{flex:0 0 auto;width:33.33333333%}.row-cols-md-4>*{flex:0 0 auto;width:25%}.row-cols-md-5>*{flex:0 0 auto;width:20%}.row-cols-md-6>*{flex:0 0 auto;width:16.66666667%}.col-md-auto{flex:0 0 auto;width:auto}.col-md-1{flex:0 0 auto;width:8.33333333%}.col-md-2{flex:0 0 auto;width:16.66666667%}.col-md-3{flex:0 0 auto;width:25%}.col-md-4{flex:0 0 auto;width:33.33333333%}.col-md-5{flex:0 0 auto;width:41.66666667%}.col-md-6{flex:0 0 auto;width:50%}.col-md-7{flex:0 0 auto;width:58.33333333%}.col-md-8{flex:0 0 auto;width:66.66666667%}.col-md-9{flex:0 0 auto;width:75%}.col-md-10{flex:0 0 auto;width:83.33333333%}.col-md-11{flex:0 0 auto;width:91.66666667%}.col-md-12{flex:0 0 auto;width:100%}.offset-md-0{margin-left:0}.offset-md-1{margin-left:8.33333333%}.offset-md-2{margin-left:16.66666667%}.offset-md-3{margin-left:25%}.offset-md-4{margin-left:33.33333333%}.offset-md-5{margin-left:41.66666667%}.offset-md-6{margin-left:50%}.offset-md-7{margin-left:58.33333333%}.offset-md-8{margin-left:66.66666667%}.offset-md-9{margin-left:75%}.offset-md-10{margin-left:83.33333333%}.offset-md-11{margin-left:91.66666667%}.g-md-0,.gx-md-0{--bs-gutter-x:0}.g-md-0,.gy-md-0{--bs-gutter-y:0}.g-md-1,.gx-md-1{--bs-gutter-x:0.25rem}.g-md-1,.gy-md-1{--bs-gutter-y:0.25rem}.g-md-2,.gx-md-2{--bs-gutter-x:0.5rem}.g-md-2,.gy-md-2{--bs-gutter-y:0.5rem}.g-md-3,.gx-md-3{--bs-gutter-x:1rem}.g-md-3,.gy-md-3{--bs-gutter-y:1rem}.g-md-4,.gx-md-4{--bs-gutter-x:1.5rem}.g-md-4,.gy-md-4{--bs-gutter-y:1.5rem}.g-md-5,.gx-md-5{--bs-gutter-x:3rem}.g-md-5,.gy-md-5{--bs-gutter-y:3rem}}@media (min-width:992px){.col-lg{flex:1 0 0}.row-cols-lg-auto>*{flex:0 0 auto;width:auto}.row-cols-lg-1>*{flex:0 0 auto;width:100%}.row-cols-lg-2>*{flex:0 0 auto;width:50%}.row-cols-lg-3>*{flex:0 0 auto;width:33.33333333%}.row-cols-lg-4>*{flex:0 0 auto;width:25%}.row-cols-lg-5>*{flex:0 0 auto;width:20%}.row-cols-lg-6>*{flex:0 0 auto;width:16.66666667%}.col-lg-auto{flex:0 0 auto;width:auto}.col-lg-1{flex:0 0 auto;width:8.33333333%}.col-lg-2{flex:0 0 auto;width:16.66666667%}.col-lg-3{flex:0 0 auto;width:25%}.col-lg-4{flex:0 0 auto;width:33.33333333%}.col-lg-5{flex:0 0 auto;width:41.66666667%}.col-lg-6{flex:0 0 auto;width:50%}.col-lg-7{flex:0 0 auto;width:58.33333333%}.col-lg-8{flex:0 0 auto;width:66.66666667%}.col-lg-9{flex:0 0 auto;width:75%}.col-lg-10{flex:0 0 auto;width:83.33333333%}.col-lg-11{flex:0 0 auto;width:91.66666667%}.col-lg-12{flex:0 0 auto;width:100%}.offset-lg-0{margin-left:0}.offset-lg-1{margin-left:8.33333333%}.offset-lg-2{margin-left:16.66666667%}.offset-lg-3{margin-left:25%}.offset-lg-4{margin-left:33.33333333%}.offset-lg-5{margin-left:41.66666667%}.offset-lg-6{margin-left:50%}.offset-lg-7{margin-left:58.33333333%}.offset-lg-8{margin-left:66.66666667%}.offset-lg-9{margin-left:75%}.offset-lg-10{margin-left:83.33333333%}.offset-lg-11{margin-left:91.66666667%}.g-lg-0,.gx-lg-0{--bs-gutter-x:0}.g-lg-0,.gy-lg-0{--bs-gutter-y:0}.g-lg-1,.gx-lg-1{--bs-gutter-x:0.25rem}.g-lg-1,.gy-lg-1{--bs-gutter-y:0.25rem}.g-lg-2,.gx-lg-2{--bs-gutter-x:0.5rem}.g-lg-2,.gy-lg-2{--bs-gutter-y:0.5rem}.g-lg-3,.gx-lg-3{--bs-gutter-x:1rem}.g-lg-3,.gy-lg-3{--bs-gutter-y:1rem}.g-lg-4,.gx-lg-4{--bs-gutter-x:1.5rem}.g-lg-4,.gy-lg-4{--bs-gutter-y:1.5rem}.g-lg-5,.gx-lg-5{--bs-gutter-x:3rem}.g-lg-5,.gy-lg-5{--bs-gutter-y:3rem}}@media (min-width:1200px){.col-xl{flex:1 0 0}.row-cols-xl-auto>*{flex:0 0 auto;width:auto}.row-cols-xl-1>*{flex:0 0 auto;width:100%}.row-cols-xl-2>*{flex:0 0 auto;width:50%}.row-cols-xl-3>*{flex:0 0 auto;width:33.33333333%}.row-cols-xl-4>*{flex:0 0 auto;width:25%}.row-cols-xl-5>*{flex:0 0 auto;width:20%}.row-cols-xl-6>*{flex:0 0 auto;width:16.66666667%}.col-xl-auto{flex:0 0 auto;width:auto}.col-xl-1{flex:0 0 auto;width:8.33333333%}.col-xl-2{flex:0 0 auto;width:16.66666667%}.col-xl-3{flex:0 0 auto;width:25%}.col-xl-4{flex:0 0 auto;width:33.33333333%}.col-xl-5{flex:0 0 auto;width:41.66666667%}.col-xl-6{flex:0 0 auto;width:50%}.col-xl-7{flex:0 0 auto;width:58.33333333%}.col-xl-8{flex:0 0 auto;width:66.66666667%}.col-xl-9{flex:0 0 auto;width:75%}.col-xl-10{flex:0 0 auto;width:83.33333333%}.col-xl-11{flex:0 0 auto;width:91.66666667%}.col-xl-12{flex:0 0 auto;width:100%}.offset-xl-0{margin-left:0}.offset-xl-1{margin-left:8.33333333%}.offset-xl-2{margin-left:16.66666667%}.offset-xl-3{margin-left:25%}.offset-xl-4{margin-left:33.33333333%}.offset-xl-5{margin-left:41.66666667%}.offset-xl-6{margin-left:50%}.offset-xl-7{margin-left:58.33333333%}.offset-xl-8{margin-left:66.66666667%}.offset-xl-9{margin-left:75%}.offset-xl-10{margin-left:83.33333333%}.offset-xl-11{margin-left:91.66666667%}.g-xl-0,.gx-xl-0{--bs-gutter-x:0}.g-xl-0,.gy-xl-0{--bs-gutter-y:0}.g-xl-1,.gx-xl-1{--bs-gutter-x:0.25rem}.g-xl-1,.gy-xl-1{--bs-gutter-y:0.25rem}.g-xl-2,.gx-xl-2{--bs-gutter-x:0.5rem}.g-xl-2,.gy-xl-2{--bs-gutter-y:0.5rem}.g-xl-3,.gx-xl-3{--bs-gutter-x:1rem}.g-xl-3,.gy-xl-3{--bs-gutter-y:1rem}.g-xl-4,.gx-xl-4{--bs-gutter-x:1.5rem}.g-xl-4,.gy-xl-4{--bs-gutter-y:1.5rem}.g-xl-5,.gx-xl-5{--bs-gutter-x:3rem}.g-xl-5,.gy-xl-5{--bs-gutter-y:3rem}}@media (min-width:1400px){.col-xxl{flex:1 0 0}.row-cols-xxl-auto>*{flex:0 0 auto;width:auto}.row-cols-xxl-1>*{flex:0 0 auto;width:100%}.row-cols-xxl-2>*{flex:0 0 auto;width:50%}.row-cols-xxl-3>*{flex:0 0 auto;width:33.33333333%}.row-cols-xxl-4>*{flex:0 0 auto;width:25%}.row-cols-xxl-5>*{flex:0 0 auto;width:20%}.row-cols-xxl-6>*{flex:0 0 auto;width:16.66666667%}.col-xxl-auto{flex:0 0 auto;width:auto}.col-xxl-1{flex:0 0 auto;width:8.33333333%}.col-xxl-2{flex:0 0 auto;width:16.66666667%}.col-xxl-3{flex:0 0 auto;width:25%}.col-xxl-4{flex:0 0 auto;width:33.33333333%}.col-xxl-5{flex:0 0 auto;width:41.66666667%}.col-xxl-6{flex:0 0 auto;width:50%}.col-xxl-7{flex:0 0 auto;width:58.33333333%}.col-xxl-8{flex:0 0 auto;width:66.66666667%}.col-xxl-9{flex:0 0 auto;width:75%}.col-xxl-10{flex:0 0 auto;width:83.33333333%}.col-xxl-11{flex:0 0 auto;width:91.66666667%}.col-xxl-12{flex:0 0 auto;width:100%}.offset-xxl-0{margin-left:0}.offset-xxl-1{margin-left:8.33333333%}.offset-xxl-2{margin-left:16.66666667%}.offset-xxl-3{margin-left:25%}.offset-xxl-4{margin-left:33.33333333%}.offset-xxl-5{margin-left:41.66666667%}.offset-xxl-6{margin-left:50%}.offset-xxl-7{margin-left:58.33333333%}.offset-xxl-8{margin-left:66.66666667%}.offset-xxl-9{margin-left:75%}.offset-xxl-10{margin-left:83.33333333%}.offset-xxl-11{margin-left:91.66666667%}.g-xxl-0,.gx-xxl-0{--bs-gutter-x:0}.g-xxl-0,.gy-xxl-0{--bs-gutter-y:0}.g-xxl-1,.gx-xxl-1{--bs-gutter-x:0.25rem}.g-xxl-1,.gy-xxl-1{--bs-gutter-y:0.25rem}.g-xxl-2,.gx-xxl-2{--bs-gutter-x:0.5rem}.g-xxl-2,.gy-xxl-2{--bs-gutter-y:0.5rem}.g-xxl-3,.gx-xxl-3{--bs-gutter-x:1rem}.g-xxl-3,.gy-xxl-3{--bs-gutter-y:1rem}.g-xxl-4,.gx-xxl-4{--bs-gutter-x:1.5rem}.g-xxl-4,.gy-xxl-4{--bs-gutter-y:1.5rem}.g-xxl-5,.gx-xxl-5{--bs-gutter-x:3rem}.g-xxl-5,.gy-xxl-5{--bs-gutter-y:3rem}}.table{--bs-table-color-type:initial;--bs-table-bg-type:initial;--bs-table-color-state:initial;--bs-table-bg-state:initial;--bs-table-color:var(--bs-emphasis-color);--bs-table-bg:var(--bs-body-bg);--bs-table-border-color:var(--bs-border-color);--bs-table-accent-bg:transparent;--bs-table-striped-color:var(--bs-emphasis-color);--bs-table-striped-bg:rgba(var(--bs-emphasis-color-rgb), 0.05);--bs-table-active-color:var(--bs-emphasis-color);--bs-table-active-bg:rgba(var(--bs-emphasis-color-rgb), 0.1);--bs-table-hover-color:var(--bs-emphasis-color);--bs-table-hover-bg:rgba(var(--bs-emphasis-color-rgb), 0.075);width:100%;margin-bottom:1rem;vertical-align:top;border-color:var(--bs-table-border-color)}.table>:not(caption)>*>*{padding:.5rem .5rem;color:var(--bs-table-color-state,var(--bs-table-color-type,var(--bs-table-color)));background-color:var(--bs-table-bg);border-bottom-width:var(--bs-border-width);box-shadow:inset 0 0 0 9999px var(--bs-table-bg-state,var(--bs-table-bg-type,var(--bs-table-accent-bg)))}.table>tbody{vertical-align:inherit}.table>thead{vertical-align:bottom}.table-group-divider{border-top:calc(var(--bs-border-width) * 2) solid currentcolor}.caption-top{caption-side:top}.table-sm>:not(caption)>*>*{padding:.25rem .25rem}.table-bordered>:not(caption)>*{border-width:var(--bs-border-width) 0}.table-bordered>:not(caption)>*>*{border-width:0 var(--bs-border-width)}.table-borderless>:not(caption)>*>*{border-bottom-width:0}.table-borderless>:not(:first-child){border-top-width:0}.table-striped>tbody>tr:nth-of-type(odd)>*{--bs-table-color-type:var(--bs-table-striped-color);--bs-table-bg-type:var(--bs-table-striped-bg)}.table-striped-columns>:not(caption)>tr>:nth-child(2n){--bs-table-color-type:var(--bs-table-striped-color);--bs-table-bg-type:var(--bs-table-striped-bg)}.table-active{--bs-table-color-state:var(--bs-table-active-color);--bs-table-bg-state:var(--bs-table-active-bg)}.table-hover>tbody>tr:hover>*{--bs-table-color-state:var(--bs-table-hover-color);--bs-table-bg-state:var(--bs-table-hover-bg)}.table-primary{--bs-table-color:#000;--bs-table-bg:#cfe2ff;--bs-table-border-color:#a6b5cc;--bs-table-striped-bg:#c5d7f2;--bs-table-striped-color:#000;--bs-table-active-bg:#bacbe6;--bs-table-active-color:#000;--bs-table-hover-bg:#bfd1ec;--bs-table-hover-color:#000;color:var(--bs-table-color);border-color:var(--bs-table-border-color)}.table-secondary{--bs-table-color:#000;--bs-table-bg:#e2e3e5;--bs-table-border-color:#b5b6b7;--bs-table-striped-bg:#d7d8da;--bs-table-striped-color:#000;--bs-table-active-bg:#cbccce;--bs-table-active-color:#000;--bs-table-hover-bg:#d1d2d4;--bs-table-hover-color:#000;color:var(--bs-table-color);border-color:var(--bs-table-border-color)}.table-success{--bs-table-color:#000;--bs-table-bg:#d1e7dd;--bs-table-border-color:#a7b9b1;--bs-table-striped-bg:#c7dbd2;--bs-table-striped-color:#000;--bs-table-active-bg:#bcd0c7;--bs-table-active-color:#000;--bs-table-hover-bg:#c1d6cc;--bs-table-hover-color:#000;color:var(--bs-table-color);border-color:var(--bs-table-border-color)}.table-info{--bs-table-color:#000;--bs-table-bg:#cff4fc;--bs-table-border-color:#a6c3ca;--bs-table-striped-bg:#c5e8ef;--bs-table-striped-color:#000;--bs-table-active-bg:#badce3;--bs-table-active-color:#000;--bs-table-hover-bg:#bfe2e9;--bs-table-hover-color:#000;color:var(--bs-table-color);border-color:var(--bs-table-border-color)}.table-warning{--bs-table-color:#000;--bs-table-bg:#fff3cd;--bs-table-border-color:#ccc2a4;--bs-table-striped-bg:#f2e7c3;--bs-table-striped-color:#000;--bs-table-active-bg:#e6dbb9;--bs-table-active-color:#000;--bs-table-hover-bg:#ece1be;--bs-table-hover-color:#000;color:var(--bs-table-color);border-color:var(--bs-table-border-color)}.table-danger{--bs-table-color:#000;--bs-table-bg:#f8d7da;--bs-table-border-color:#c6acae;--bs-table-striped-bg:#eccccf;--bs-table-striped-color:#000;--bs-table-active-bg:#dfc2c4;--bs-table-active-color:#000;--bs-table-hover-bg:#e5c7ca;--bs-table-hover-color:#000;color:var(--bs-table-color);border-color:var(--bs-table-border-color)}.table-light{--bs-table-color:#000;--bs-table-bg:#f8f9fa;--bs-table-border-color:#c6c7c8;--bs-table-striped-bg:#ecedee;--bs-table-striped-color:#000;--bs-table-active-bg:#dfe0e1;--bs-table-active-color:#000;--bs-table-hover-bg:#e5e6e7;--bs-table-hover-color:#000;color:var(--bs-table-color);border-color:var(--bs-table-border-color)}.table-dark{--bs-table-color:#fff;--bs-table-bg:#212529;--bs-table-border-color:#4d5154;--bs-table-striped-bg:#2c3034;--bs-table-striped-color:#fff;--bs-table-active-bg:#373b3e;--bs-table-active-color:#fff;--bs-table-hover-bg:#323539;--bs-table-hover-color:#fff;color:var(--bs-table-color);border-color:var(--bs-table-border-color)}.table-responsive{overflow-x:auto;-webkit-overflow-scrolling:touch}@media (max-width:575.98px){.table-responsive-sm{overflow-x:auto;-webkit-overflow-scrolling:touch}}@media (max-width:767.98px){.table-responsive-md{overflow-x:auto;-webkit-overflow-scrolling:touch}}@media (max-width:991.98px){.table-responsive-lg{overflow-x:auto;-webkit-overflow-scrolling:touch}}@media (max-width:1199.98px){.table-responsive-xl{overflow-x:auto;-webkit-overflow-scrolling:touch}}@media (max-width:1399.98px){.table-responsive-xxl{overflow-x:auto;-webkit-overflow-scrolling:touch}}.form-label{margin-bottom:.5rem}.col-form-label{padding-top:calc(.375rem + var(--bs-border-width));padding-bottom:calc(.375rem + var(--bs-border-width));margin-bottom:0;font-size:inherit;line-height:1.5}.col-form-label-lg{padding-top:calc(.5rem + var(--bs-border-width));padding-bottom:calc(.5rem + var(--bs-border-width));font-size:1.25rem}.col-form-label-sm{padding-top:calc(.25rem + var(--bs-border-width));padding-bottom:calc(.25rem + var(--bs-border-width));font-size:.875rem}.form-text{margin-top:.25rem;font-size:.875em;color:var(--bs-secondary-color)}.form-control{display:block;width:100%;padding:.375rem .75rem;font-size:1rem;font-weight:400;line-height:1.5;color:var(--bs-body-color);-webkit-appearance:none;-moz-appearance:none;appearance:none;background-color:var(--bs-body-bg);background-clip:padding-box;border:var(--bs-border-width) solid var(--bs-border-color);border-radius:var(--bs-border-radius);transition:border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.form-control{transition:none}}.form-control[type=file]{overflow:hidden}.form-control[type=file]:not(:disabled):not([readonly]){cursor:pointer}.form-control:focus{color:var(--bs-body-color);background-color:var(--bs-body-bg);border-color:#86b7fe;outline:0;box-shadow:0 0 0 .25rem rgba(13,110,253,.25)}.form-control::-webkit-date-and-time-value{min-width:85px;height:1.5em;margin:0}.form-control::-webkit-datetime-edit{display:block;padding:0}.form-control::placeholder{color:var(--bs-secondary-color);opacity:1}.form-control:disabled{background-color:var(--bs-secondary-bg);opacity:1}.form-control::-webkit-file-upload-button{padding:.375rem .75rem;margin:-.375rem -.75rem;-webkit-margin-end:.75rem;margin-inline-end:.75rem;color:var(--bs-body-color);background-color:var(--bs-tertiary-bg);pointer-events:none;border-color:inherit;border-style:solid;border-width:0;border-inline-end-width:var(--bs-border-width);border-radius:0;-webkit-transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}.form-control::file-selector-button{padding:.375rem .75rem;margin:-.375rem -.75rem;-webkit-margin-end:.75rem;margin-inline-end:.75rem;color:var(--bs-body-color);background-color:var(--bs-tertiary-bg);pointer-events:none;border-color:inherit;border-style:solid;border-width:0;border-inline-end-width:var(--bs-border-width);border-radius:0;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.form-control::-webkit-file-upload-button{-webkit-transition:none;transition:none}.form-control::file-selector-button{transition:none}}.form-control:hover:not(:disabled):not([readonly])::-webkit-file-upload-button{background-color:var(--bs-secondary-bg)}.form-control:hover:not(:disabled):not([readonly])::file-selector-button{background-color:var(--bs-secondary-bg)}.form-control-plaintext{display:block;width:100%;padding:.375rem 0;margin-bottom:0;line-height:1.5;color:var(--bs-body-color);background-color:transparent;border:solid transparent;border-width:var(--bs-border-width) 0}.form-control-plaintext:focus{outline:0}.form-control-plaintext.form-control-lg,.form-control-plaintext.form-control-sm{padding-right:0;padding-left:0}.form-control-sm{min-height:calc(1.5em + .5rem + calc(var(--bs-border-width) * 2));padding:.25rem .5rem;font-size:.875rem;border-radius:var(--bs-border-radius-sm)}.form-control-sm::-webkit-file-upload-button{padding:.25rem .5rem;margin:-.25rem -.5rem;-webkit-margin-end:.5rem;margin-inline-end:.5rem}.form-control-sm::file-selector-button{padding:.25rem .5rem;margin:-.25rem -.5rem;-webkit-margin-end:.5rem;margin-inline-end:.5rem}.form-control-lg{min-height:calc(1.5em + 1rem + calc(var(--bs-border-width) * 2));padding:.5rem 1rem;font-size:1.25rem;border-radius:var(--bs-border-radius-lg)}.form-control-lg::-webkit-file-upload-button{padding:.5rem 1rem;margin:-.5rem -1rem;-webkit-margin-end:1rem;margin-inline-end:1rem}.form-control-lg::file-selector-button{padding:.5rem 1rem;margin:-.5rem -1rem;-webkit-margin-end:1rem;margin-inline-end:1rem}textarea.form-control{min-height:calc(1.5em + .75rem + calc(var(--bs-border-width) * 2))}textarea.form-control-sm{min-height:calc(1.5em + .5rem + calc(var(--bs-border-width) * 2))}textarea.form-control-lg{min-height:calc(1.5em + 1rem + calc(var(--bs-border-width) * 2))}.form-control-color{width:3rem;height:calc(1.5em + .75rem + calc(var(--bs-border-width) * 2));padding:.375rem}.form-control-color:not(:disabled):not([readonly]){cursor:pointer}.form-control-color::-moz-color-swatch{border:0!important;border-radius:var(--bs-border-radius)}.form-control-color::-webkit-color-swatch{border:0!important;border-radius:var(--bs-border-radius)}.form-control-color.form-control-sm{height:calc(1.5em + .5rem + calc(var(--bs-border-width) * 2))}.form-control-color.form-control-lg{height:calc(1.5em + 1rem + calc(var(--bs-border-width) * 2))}.form-select{--bs-form-select-bg-img:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%23343a40' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='m2 5 6 6 6-6'/%3e%3c/svg%3e");display:block;width:100%;padding:.375rem 2.25rem .375rem .75rem;font-size:1rem;font-weight:400;line-height:1.5;color:var(--bs-body-color);-webkit-appearance:none;-moz-appearance:none;appearance:none;background-color:var(--bs-body-bg);background-image:var(--bs-form-select-bg-img),var(--bs-form-select-bg-icon,none);background-repeat:no-repeat;background-position:right .75rem center;background-size:16px 12px;border:var(--bs-border-width) solid var(--bs-border-color);border-radius:var(--bs-border-radius);transition:border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.form-select{transition:none}}.form-select:focus{border-color:#86b7fe;outline:0;box-shadow:0 0 0 .25rem rgba(13,110,253,.25)}.form-select[multiple],.form-select[size]:not([size="1"]){padding-right:.75rem;background-image:none}.form-select:disabled{background-color:var(--bs-secondary-bg)}.form-select:-moz-focusring{color:transparent;text-shadow:0 0 0 var(--bs-body-color)}.form-select-sm{padding-top:.25rem;padding-bottom:.25rem;padding-left:.5rem;font-size:.875rem;border-radius:var(--bs-border-radius-sm)}.form-select-lg{padding-top:.5rem;padding-bottom:.5rem;padding-left:1rem;font-size:1.25rem;border-radius:var(--bs-border-radius-lg)}[data-bs-theme=dark] .form-select{--bs-form-select-bg-img:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%23dee2e6' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='m2 5 6 6 6-6'/%3e%3c/svg%3e")}.form-check{display:block;min-height:1.5rem;padding-left:1.5em;margin-bottom:.125rem}.form-check .form-check-input{float:left;margin-left:-1.5em}.form-check-reverse{padding-right:1.5em;padding-left:0;text-align:right}.form-check-reverse .form-check-input{float:right;margin-right:-1.5em;margin-left:0}.form-check-input{--bs-form-check-bg:var(--bs-body-bg);flex-shrink:0;width:1em;height:1em;margin-top:.25em;vertical-align:top;-webkit-appearance:none;-moz-appearance:none;appearance:none;background-color:var(--bs-form-check-bg);background-image:var(--bs-form-check-bg-image);background-repeat:no-repeat;background-position:center;background-size:contain;border:var(--bs-border-width) solid var(--bs-border-color);-webkit-print-color-adjust:exact;color-adjust:exact;print-color-adjust:exact}.form-check-input[type=checkbox]{border-radius:.25em}.form-check-input[type=radio]{border-radius:50%}.form-check-input:active{filter:brightness(90%)}.form-check-input:focus{border-color:#86b7fe;outline:0;box-shadow:0 0 0 .25rem rgba(13,110,253,.25)}.form-check-input:checked{background-color:#0d6efd;border-color:#0d6efd}.form-check-input:checked[type=checkbox]{--bs-form-check-bg-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3e%3cpath fill='none' stroke='%23fff' stroke-linecap='round' stroke-linejoin='round' stroke-width='3' d='m6 10 3 3 6-6'/%3e%3c/svg%3e")}.form-check-input:checked[type=radio]{--bs-form-check-bg-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='2' fill='%23fff'/%3e%3c/svg%3e")}.form-check-input[type=checkbox]:indeterminate{background-color:#0d6efd;border-color:#0d6efd;--bs-form-check-bg-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3e%3cpath fill='none' stroke='%23fff' stroke-linecap='round' stroke-linejoin='round' stroke-width='3' d='M6 10h8'/%3e%3c/svg%3e")}.form-check-input:disabled{pointer-events:none;filter:none;opacity:.5}.form-check-input:disabled~.form-check-label,.form-check-input[disabled]~.form-check-label{cursor:default;opacity:.5}.form-switch{padding-left:2.5em}.form-switch .form-check-input{--bs-form-switch-bg:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='rgba%280, 0, 0, 0.25%29'/%3e%3c/svg%3e");width:2em;margin-left:-2.5em;background-image:var(--bs-form-switch-bg);background-position:left center;border-radius:2em;transition:background-position .15s ease-in-out}@media (prefers-reduced-motion:reduce){.form-switch .form-check-input{transition:none}}.form-switch .form-check-input:focus{--bs-form-switch-bg:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='%2386b7fe'/%3e%3c/svg%3e")}.form-switch .form-check-input:checked{background-position:right center;--bs-form-switch-bg:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='%23fff'/%3e%3c/svg%3e")}.form-switch.form-check-reverse{padding-right:2.5em;padding-left:0}.form-switch.form-check-reverse .form-check-input{margin-right:-2.5em;margin-left:0}.form-check-inline{display:inline-block;margin-right:1rem}.btn-check{position:absolute;clip:rect(0,0,0,0);pointer-events:none}.btn-check:disabled+.btn,.btn-check[disabled]+.btn{pointer-events:none;filter:none;opacity:.65}[data-bs-theme=dark] .form-switch .form-check-input:not(:checked):not(:focus){--bs-form-switch-bg:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='rgba%28255, 255, 255, 0.25%29'/%3e%3c/svg%3e")}.form-range{width:100%;height:1.5rem;padding:0;-webkit-appearance:none;-moz-appearance:none;appearance:none;background-color:transparent}.form-range:focus{outline:0}.form-range:focus::-webkit-slider-thumb{box-shadow:0 0 0 1px #fff,0 0 0 .25rem rgba(13,110,253,.25)}.form-range:focus::-moz-range-thumb{box-shadow:0 0 0 1px #fff,0 0 0 .25rem rgba(13,110,253,.25)}.form-range::-moz-focus-outer{border:0}.form-range::-webkit-slider-thumb{width:1rem;height:1rem;margin-top:-.25rem;-webkit-appearance:none;appearance:none;background-color:#0d6efd;border:0;border-radius:1rem;-webkit-transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.form-range::-webkit-slider-thumb{-webkit-transition:none;transition:none}}.form-range::-webkit-slider-thumb:active{background-color:#b6d4fe}.form-range::-webkit-slider-runnable-track{width:100%;height:.5rem;color:transparent;cursor:pointer;background-color:var(--bs-secondary-bg);border-color:transparent;border-radius:1rem}.form-range::-moz-range-thumb{width:1rem;height:1rem;-moz-appearance:none;appearance:none;background-color:#0d6efd;border:0;border-radius:1rem;-moz-transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.form-range::-moz-range-thumb{-moz-transition:none;transition:none}}.form-range::-moz-range-thumb:active{background-color:#b6d4fe}.form-range::-moz-range-track{width:100%;height:.5rem;color:transparent;cursor:pointer;background-color:var(--bs-secondary-bg);border-color:transparent;border-radius:1rem}.form-range:disabled{pointer-events:none}.form-range:disabled::-webkit-slider-thumb{background-color:var(--bs-secondary-color)}.form-range:disabled::-moz-range-thumb{background-color:var(--bs-secondary-color)}.form-floating{position:relative}.form-floating>.form-control,.form-floating>.form-control-plaintext,.form-floating>.form-select{height:calc(3.5rem + calc(var(--bs-border-width) * 2));min-height:calc(3.5rem + calc(var(--bs-border-width) * 2));line-height:1.25}.form-floating>label{position:absolute;top:0;left:0;z-index:2;max-width:100%;height:100%;padding:1rem .75rem;overflow:hidden;color:rgba(var(--bs-body-color-rgb),.65);text-align:start;text-overflow:ellipsis;white-space:nowrap;pointer-events:none;border:var(--bs-border-width) solid transparent;transform-origin:0 0;transition:opacity .1s ease-in-out,transform .1s ease-in-out}@media (prefers-reduced-motion:reduce){.form-floating>label{transition:none}}.form-floating>.form-control,.form-floating>.form-control-plaintext{padding:1rem .75rem}.form-floating>.form-control-plaintext::placeholder,.form-floating>.form-control::placeholder{color:transparent}.form-floating>.form-control-plaintext:focus,.form-floating>.form-control-plaintext:not(:placeholder-shown),.form-floating>.form-control:focus,.form-floating>.form-control:not(:placeholder-shown){padding-top:1.625rem;padding-bottom:.625rem}.form-floating>.form-control-plaintext:-webkit-autofill,.form-floating>.form-control:-webkit-autofill{padding-top:1.625rem;padding-bottom:.625rem}.form-floating>.form-select{padding-top:1.625rem;padding-bottom:.625rem;padding-left:.75rem}.form-floating>.form-control-plaintext~label,.form-floating>.form-control:focus~label,.form-floating>.form-control:not(:placeholder-shown)~label,.form-floating>.form-select~label{transform:scale(.85) translateY(-.5rem) translateX(.15rem)}.form-floating>.form-control:-webkit-autofill~label{transform:scale(.85) translateY(-.5rem) translateX(.15rem)}.form-floating>textarea:focus~label::after,.form-floating>textarea:not(:placeholder-shown)~label::after{position:absolute;inset:1rem 0.375rem;z-index:-1;height:1.5em;content:"";background-color:var(--bs-body-bg);border-radius:var(--bs-border-radius)}.form-floating>textarea:disabled~label::after{background-color:var(--bs-secondary-bg)}.form-floating>.form-control-plaintext~label{border-width:var(--bs-border-width) 0}.form-floating>.form-control:disabled~label,.form-floating>:disabled~label{color:#6c757d}.input-group{position:relative;display:flex;flex-wrap:wrap;align-items:stretch;width:100%}.input-group>.form-control,.input-group>.form-floating,.input-group>.form-select{position:relative;flex:1 1 auto;width:1%;min-width:0}.input-group>.form-control:focus,.input-group>.form-floating:focus-within,.input-group>.form-select:focus{z-index:5}.input-group .btn{position:relative;z-index:2}.input-group .btn:focus{z-index:5}.input-group-text{display:flex;align-items:center;padding:.375rem .75rem;font-size:1rem;font-weight:400;line-height:1.5;color:var(--bs-body-color);text-align:center;white-space:nowrap;background-color:var(--bs-tertiary-bg);border:var(--bs-border-width) solid var(--bs-border-color);border-radius:var(--bs-border-radius)}.input-group-lg>.btn,.input-group-lg>.form-control,.input-group-lg>.form-select,.input-group-lg>.input-group-text{padding:.5rem 1rem;font-size:1.25rem;border-radius:var(--bs-border-radius-lg)}.input-group-sm>.btn,.input-group-sm>.form-control,.input-group-sm>.form-select,.input-group-sm>.input-group-text{padding:.25rem .5rem;font-size:.875rem;border-radius:var(--bs-border-radius-sm)}.input-group-lg>.form-select,.input-group-sm>.form-select{padding-right:3rem}.input-group:not(.has-validation)>.dropdown-toggle:nth-last-child(n+3),.input-group:not(.has-validation)>.form-floating:not(:last-child)>.form-control,.input-group:not(.has-validation)>.form-floating:not(:last-child)>.form-select,.input-group:not(.has-validation)>:not(:last-child):not(.dropdown-toggle):not(.dropdown-menu):not(.form-floating){border-top-right-radius:0;border-bottom-right-radius:0}.input-group.has-validation>.dropdown-toggle:nth-last-child(n+4),.input-group.has-validation>.form-floating:nth-last-child(n+3)>.form-control,.input-group.has-validation>.form-floating:nth-last-child(n+3)>.form-select,.input-group.has-validation>:nth-last-child(n+3):not(.dropdown-toggle):not(.dropdown-menu):not(.form-floating){border-top-right-radius:0;border-bottom-right-radius:0}.input-group>:not(:first-child):not(.dropdown-menu):not(.valid-tooltip):not(.valid-feedback):not(.invalid-tooltip):not(.invalid-feedback){margin-left:calc(-1 * var(--bs-border-width));border-top-left-radius:0;border-bottom-left-radius:0}.input-group>.form-floating:not(:first-child)>.form-control,.input-group>.form-floating:not(:first-child)>.form-select{border-top-left-radius:0;border-bottom-left-radius:0}.valid-feedback{display:none;width:100%;margin-top:.25rem;font-size:.875em;color:var(--bs-form-valid-color)}.valid-tooltip{position:absolute;top:100%;z-index:5;display:none;max-width:100%;padding:.25rem .5rem;margin-top:.1rem;font-size:.875rem;color:#fff;background-color:var(--bs-success);border-radius:var(--bs-border-radius)}.is-valid~.valid-feedback,.is-valid~.valid-tooltip,.was-validated :valid~.valid-feedback,.was-validated :valid~.valid-tooltip{display:block}.form-control.is-valid,.was-validated .form-control:valid{border-color:var(--bs-form-valid-border-color);padding-right:calc(1.5em + .75rem);background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3e%3cpath fill='%23198754' d='M2.3 6.73.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1'/%3e%3c/svg%3e");background-repeat:no-repeat;background-position:right calc(.375em + .1875rem) center;background-size:calc(.75em + .375rem) calc(.75em + .375rem)}.form-control.is-valid:focus,.was-validated .form-control:valid:focus{border-color:var(--bs-form-valid-border-color);box-shadow:0 0 0 .25rem rgba(var(--bs-success-rgb),.25)}.was-validated textarea.form-control:valid,textarea.form-control.is-valid{padding-right:calc(1.5em + .75rem);background-position:top calc(.375em + .1875rem) right calc(.375em + .1875rem)}.form-select.is-valid,.was-validated .form-select:valid{border-color:var(--bs-form-valid-border-color)}.form-select.is-valid:not([multiple]):not([size]),.form-select.is-valid:not([multiple])[size="1"],.was-validated .form-select:valid:not([multiple]):not([size]),.was-validated .form-select:valid:not([multiple])[size="1"]{--bs-form-select-bg-icon:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3e%3cpath fill='%23198754' d='M2.3 6.73.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1'/%3e%3c/svg%3e");padding-right:4.125rem;background-position:right .75rem center,center right 2.25rem;background-size:16px 12px,calc(.75em + .375rem) calc(.75em + .375rem)}.form-select.is-valid:focus,.was-validated .form-select:valid:focus{border-color:var(--bs-form-valid-border-color);box-shadow:0 0 0 .25rem rgba(var(--bs-success-rgb),.25)}.form-control-color.is-valid,.was-validated .form-control-color:valid{width:calc(3rem + calc(1.5em + .75rem))}.form-check-input.is-valid,.was-validated .form-check-input:valid{border-color:var(--bs-form-valid-border-color)}.form-check-input.is-valid:checked,.was-validated .form-check-input:valid:checked{background-color:var(--bs-form-valid-color)}.form-check-input.is-valid:focus,.was-validated .form-check-input:valid:focus{box-shadow:0 0 0 .25rem rgba(var(--bs-success-rgb),.25)}.form-check-input.is-valid~.form-check-label,.was-validated .form-check-input:valid~.form-check-label{color:var(--bs-form-valid-color)}.form-check-inline .form-check-input~.valid-feedback{margin-left:.5em}.input-group>.form-control:not(:focus).is-valid,.input-group>.form-floating:not(:focus-within).is-valid,.input-group>.form-select:not(:focus).is-valid,.was-validated .input-group>.form-control:not(:focus):valid,.was-validated .input-group>.form-floating:not(:focus-within):valid,.was-validated .input-group>.form-select:not(:focus):valid{z-index:3}.invalid-feedback{display:none;width:100%;margin-top:.25rem;font-size:.875em;color:var(--bs-form-invalid-color)}.invalid-tooltip{position:absolute;top:100%;z-index:5;display:none;max-width:100%;padding:.25rem .5rem;margin-top:.1rem;font-size:.875rem;color:#fff;background-color:var(--bs-danger);border-radius:var(--bs-border-radius)}.is-invalid~.invalid-feedback,.is-invalid~.invalid-tooltip,.was-validated :invalid~.invalid-feedback,.was-validated :invalid~.invalid-tooltip{display:block}.form-control.is-invalid,.was-validated .form-control:invalid{border-color:var(--bs-form-invalid-border-color);padding-right:calc(1.5em + .75rem);background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12' width='12' height='12' fill='none' stroke='%23dc3545'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%23dc3545' stroke='none'/%3e%3c/svg%3e");background-repeat:no-repeat;background-position:right calc(.375em + .1875rem) center;background-size:calc(.75em + .375rem) calc(.75em + .375rem)}.form-control.is-invalid:focus,.was-validated .form-control:invalid:focus{border-color:var(--bs-form-invalid-border-color);box-shadow:0 0 0 .25rem rgba(var(--bs-danger-rgb),.25)}.was-validated textarea.form-control:invalid,textarea.form-control.is-invalid{padding-right:calc(1.5em + .75rem);background-position:top calc(.375em + .1875rem) right calc(.375em + .1875rem)}.form-select.is-invalid,.was-validated .form-select:invalid{border-color:var(--bs-form-invalid-border-color)}.form-select.is-invalid:not([multiple]):not([size]),.form-select.is-invalid:not([multiple])[size="1"],.was-validated .form-select:invalid:not([multiple]):not([size]),.was-validated .form-select:invalid:not([multiple])[size="1"]{--bs-form-select-bg-icon:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12' width='12' height='12' fill='none' stroke='%23dc3545'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%23dc3545' stroke='none'/%3e%3c/svg%3e");padding-right:4.125rem;background-position:right .75rem center,center right 2.25rem;background-size:16px 12px,calc(.75em + .375rem) calc(.75em + .375rem)}.form-select.is-invalid:focus,.was-validated .form-select:invalid:focus{border-color:var(--bs-form-invalid-border-color);box-shadow:0 0 0 .25rem rgba(var(--bs-danger-rgb),.25)}.form-control-color.is-invalid,.was-validated .form-control-color:invalid{width:calc(3rem + calc(1.5em + .75rem))}.form-check-input.is-invalid,.was-validated .form-check-input:invalid{border-color:var(--bs-form-invalid-border-color)}.form-check-input.is-invalid:checked,.was-validated .form-check-input:invalid:checked{background-color:var(--bs-form-invalid-color)}.form-check-input.is-invalid:focus,.was-validated .form-check-input:invalid:focus{box-shadow:0 0 0 .25rem rgba(var(--bs-danger-rgb),.25)}.form-check-input.is-invalid~.form-check-label,.was-validated .form-check-input:invalid~.form-check-label{color:var(--bs-form-invalid-color)}.form-check-inline .form-check-input~.invalid-feedback{margin-left:.5em}.input-group>.form-control:not(:focus).is-invalid,.input-group>.form-floating:not(:focus-within).is-invalid,.input-group>.form-select:not(:focus).is-invalid,.was-validated .input-group>.form-control:not(:focus):invalid,.was-validated .input-group>.form-floating:not(:focus-within):invalid,.was-validated .input-group>.form-select:not(:focus):invalid{z-index:4}.btn{--bs-btn-padding-x:0.75rem;--bs-btn-padding-y:0.375rem;--bs-btn-font-family: ;--bs-btn-font-size:1rem;--bs-btn-font-weight:400;--bs-btn-line-height:1.5;--bs-btn-color:var(--bs-body-color);--bs-btn-bg:transparent;--bs-btn-border-width:var(--bs-border-width);--bs-btn-border-color:transparent;--bs-btn-border-radius:var(--bs-border-radius);--bs-btn-hover-border-color:transparent;--bs-btn-box-shadow:inset 0 1px 0 rgba(255, 255, 255, 0.15),0 1px 1px rgba(0, 0, 0, 0.075);--bs-btn-disabled-opacity:0.65;--bs-btn-focus-box-shadow:0 0 0 0.25rem rgba(var(--bs-btn-focus-shadow-rgb), .5);display:inline-block;padding:var(--bs-btn-padding-y) var(--bs-btn-padding-x);font-family:var(--bs-btn-font-family);font-size:var(--bs-btn-font-size);font-weight:var(--bs-btn-font-weight);line-height:var(--bs-btn-line-height);color:var(--bs-btn-color);text-align:center;text-decoration:none;vertical-align:middle;cursor:pointer;-webkit-user-select:none;-moz-user-select:none;user-select:none;border:var(--bs-btn-border-width) solid var(--bs-btn-border-color);border-radius:var(--bs-btn-border-radius);background-color:var(--bs-btn-bg);transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.btn{transition:none}}.btn:hover{color:var(--bs-btn-hover-color);background-color:var(--bs-btn-hover-bg);border-color:var(--bs-btn-hover-border-color)}.btn-check+.btn:hover{color:var(--bs-btn-color);background-color:var(--bs-btn-bg);border-color:var(--bs-btn-border-color)}.btn:focus-visible{color:var(--bs-btn-hover-color);background-color:var(--bs-btn-hover-bg);border-color:var(--bs-btn-hover-border-color);outline:0;box-shadow:var(--bs-btn-focus-box-shadow)}.btn-check:focus-visible+.btn{border-color:var(--bs-btn-hover-border-color);outline:0;box-shadow:var(--bs-btn-focus-box-shadow)}.btn-check:checked+.btn,.btn.active,.btn.show,.btn:first-child:active,:not(.btn-check)+.btn:active{color:var(--bs-btn-active-color);background-color:var(--bs-btn-active-bg);border-color:var(--bs-btn-active-border-color)}.btn-check:checked+.btn:focus-visible,.btn.active:focus-visible,.btn.show:focus-visible,.btn:first-child:active:focus-visible,:not(.btn-check)+.btn:active:focus-visible{box-shadow:var(--bs-btn-focus-box-shadow)}.btn-check:checked:focus-visible+.btn{box-shadow:var(--bs-btn-focus-box-shadow)}.btn.disabled,.btn:disabled,fieldset:disabled .btn{color:var(--bs-btn-disabled-color);pointer-events:none;background-color:var(--bs-btn-disabled-bg);border-color:var(--bs-btn-disabled-border-color);opacity:var(--bs-btn-disabled-opacity)}.btn-primary{--bs-btn-color:#fff;--bs-btn-bg:#0d6efd;--bs-btn-border-color:#0d6efd;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#0b5ed7;--bs-btn-hover-border-color:#0a58ca;--bs-btn-focus-shadow-rgb:49,132,253;--bs-btn-active-color:#fff;--bs-btn-active-bg:#0a58ca;--bs-btn-active-border-color:#0a53be;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#fff;--bs-btn-disabled-bg:#0d6efd;--bs-btn-disabled-border-color:#0d6efd}.btn-secondary{--bs-btn-color:#fff;--bs-btn-bg:#6c757d;--bs-btn-border-color:#6c757d;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#5c636a;--bs-btn-hover-border-color:#565e64;--bs-btn-focus-shadow-rgb:130,138,145;--bs-btn-active-color:#fff;--bs-btn-active-bg:#565e64;--bs-btn-active-border-color:#51585e;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#fff;--bs-btn-disabled-bg:#6c757d;--bs-btn-disabled-border-color:#6c757d}.btn-success{--bs-btn-color:#fff;--bs-btn-bg:#198754;--bs-btn-border-color:#198754;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#157347;--bs-btn-hover-border-color:#146c43;--bs-btn-focus-shadow-rgb:60,153,110;--bs-btn-active-color:#fff;--bs-btn-active-bg:#146c43;--bs-btn-active-border-color:#13653f;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#fff;--bs-btn-disabled-bg:#198754;--bs-btn-disabled-border-color:#198754}.btn-info{--bs-btn-color:#000;--bs-btn-bg:#0dcaf0;--bs-btn-border-color:#0dcaf0;--bs-btn-hover-color:#000;--bs-btn-hover-bg:#31d2f2;--bs-btn-hover-border-color:#25cff2;--bs-btn-focus-shadow-rgb:11,172,204;--bs-btn-active-color:#000;--bs-btn-active-bg:#3dd5f3;--bs-btn-active-border-color:#25cff2;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#000;--bs-btn-disabled-bg:#0dcaf0;--bs-btn-disabled-border-color:#0dcaf0}.btn-warning{--bs-btn-color:#000;--bs-btn-bg:#ffc107;--bs-btn-border-color:#ffc107;--bs-btn-hover-color:#000;--bs-btn-hover-bg:#ffca2c;--bs-btn-hover-border-color:#ffc720;--bs-btn-focus-shadow-rgb:217,164,6;--bs-btn-active-color:#000;--bs-btn-active-bg:#ffcd39;--bs-btn-active-border-color:#ffc720;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#000;--bs-btn-disabled-bg:#ffc107;--bs-btn-disabled-border-color:#ffc107}.btn-danger{--bs-btn-color:#fff;--bs-btn-bg:#dc3545;--bs-btn-border-color:#dc3545;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#bb2d3b;--bs-btn-hover-border-color:#b02a37;--bs-btn-focus-shadow-rgb:225,83,97;--bs-btn-active-color:#fff;--bs-btn-active-bg:#b02a37;--bs-btn-active-border-color:#a52834;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#fff;--bs-btn-disabled-bg:#dc3545;--bs-btn-disabled-border-color:#dc3545}.btn-light{--bs-btn-color:#000;--bs-btn-bg:#f8f9fa;--bs-btn-border-color:#f8f9fa;--bs-btn-hover-color:#000;--bs-btn-hover-bg:#d3d4d5;--bs-btn-hover-border-color:#c6c7c8;--bs-btn-focus-shadow-rgb:211,212,213;--bs-btn-active-color:#000;--bs-btn-active-bg:#c6c7c8;--bs-btn-active-border-color:#babbbc;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#000;--bs-btn-disabled-bg:#f8f9fa;--bs-btn-disabled-border-color:#f8f9fa}.btn-dark{--bs-btn-color:#fff;--bs-btn-bg:#212529;--bs-btn-border-color:#212529;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#424649;--bs-btn-hover-border-color:#373b3e;--bs-btn-focus-shadow-rgb:66,70,73;--bs-btn-active-color:#fff;--bs-btn-active-bg:#4d5154;--bs-btn-active-border-color:#373b3e;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#fff;--bs-btn-disabled-bg:#212529;--bs-btn-disabled-border-color:#212529}.btn-outline-primary{--bs-btn-color:#0d6efd;--bs-btn-border-color:#0d6efd;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#0d6efd;--bs-btn-hover-border-color:#0d6efd;--bs-btn-focus-shadow-rgb:13,110,253;--bs-btn-active-color:#fff;--bs-btn-active-bg:#0d6efd;--bs-btn-active-border-color:#0d6efd;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#0d6efd;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#0d6efd;--bs-gradient:none}.btn-outline-secondary{--bs-btn-color:#6c757d;--bs-btn-border-color:#6c757d;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#6c757d;--bs-btn-hover-border-color:#6c757d;--bs-btn-focus-shadow-rgb:108,117,125;--bs-btn-active-color:#fff;--bs-btn-active-bg:#6c757d;--bs-btn-active-border-color:#6c757d;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#6c757d;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#6c757d;--bs-gradient:none}.btn-outline-success{--bs-btn-color:#198754;--bs-btn-border-color:#198754;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#198754;--bs-btn-hover-border-color:#198754;--bs-btn-focus-shadow-rgb:25,135,84;--bs-btn-active-color:#fff;--bs-btn-active-bg:#198754;--bs-btn-active-border-color:#198754;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#198754;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#198754;--bs-gradient:none}.btn-outline-info{--bs-btn-color:#0dcaf0;--bs-btn-border-color:#0dcaf0;--bs-btn-hover-color:#000;--bs-btn-hover-bg:#0dcaf0;--bs-btn-hover-border-color:#0dcaf0;--bs-btn-focus-shadow-rgb:13,202,240;--bs-btn-active-color:#000;--bs-btn-active-bg:#0dcaf0;--bs-btn-active-border-color:#0dcaf0;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#0dcaf0;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#0dcaf0;--bs-gradient:none}.btn-outline-warning{--bs-btn-color:#ffc107;--bs-btn-border-color:#ffc107;--bs-btn-hover-color:#000;--bs-btn-hover-bg:#ffc107;--bs-btn-hover-border-color:#ffc107;--bs-btn-focus-shadow-rgb:255,193,7;--bs-btn-active-color:#000;--bs-btn-active-bg:#ffc107;--bs-btn-active-border-color:#ffc107;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#ffc107;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#ffc107;--bs-gradient:none}.btn-outline-danger{--bs-btn-color:#dc3545;--bs-btn-border-color:#dc3545;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#dc3545;--bs-btn-hover-border-color:#dc3545;--bs-btn-focus-shadow-rgb:220,53,69;--bs-btn-active-color:#fff;--bs-btn-active-bg:#dc3545;--bs-btn-active-border-color:#dc3545;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#dc3545;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#dc3545;--bs-gradient:none}.btn-outline-light{--bs-btn-color:#f8f9fa;--bs-btn-border-color:#f8f9fa;--bs-btn-hover-color:#000;--bs-btn-hover-bg:#f8f9fa;--bs-btn-hover-border-color:#f8f9fa;--bs-btn-focus-shadow-rgb:248,249,250;--bs-btn-active-color:#000;--bs-btn-active-bg:#f8f9fa;--bs-btn-active-border-color:#f8f9fa;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#f8f9fa;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#f8f9fa;--bs-gradient:none}.btn-outline-dark{--bs-btn-color:#212529;--bs-btn-border-color:#212529;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#212529;--bs-btn-hover-border-color:#212529;--bs-btn-focus-shadow-rgb:33,37,41;--bs-btn-active-color:#fff;--bs-btn-active-bg:#212529;--bs-btn-active-border-color:#212529;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#212529;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#212529;--bs-gradient:none}.btn-link{--bs-btn-font-weight:400;--bs-btn-color:var(--bs-link-color);--bs-btn-bg:transparent;--bs-btn-border-color:transparent;--bs-btn-hover-color:var(--bs-link-hover-color);--bs-btn-hover-border-color:transparent;--bs-btn-active-color:var(--bs-link-hover-color);--bs-btn-active-border-color:transparent;--bs-btn-disabled-color:#6c757d;--bs-btn-disabled-border-color:transparent;--bs-btn-box-shadow:0 0 0 #000;--bs-btn-focus-shadow-rgb:49,132,253;text-decoration:underline}.btn-link:focus-visible{color:var(--bs-btn-color)}.btn-link:hover{color:var(--bs-btn-hover-color)}.btn-group-lg>.btn,.btn-lg{--bs-btn-padding-y:0.5rem;--bs-btn-padding-x:1rem;--bs-btn-font-size:1.25rem;--bs-btn-border-radius:var(--bs-border-radius-lg)}.btn-group-sm>.btn,.btn-sm{--bs-btn-padding-y:0.25rem;--bs-btn-padding-x:0.5rem;--bs-btn-font-size:0.875rem;--bs-btn-border-radius:var(--bs-border-radius-sm)}.fade{transition:opacity .15s linear}@media (prefers-reduced-motion:reduce){.fade{transition:none}}.fade:not(.show){opacity:0}.collapse:not(.show){display:none}.collapsing{height:0;overflow:hidden;transition:height .35s ease}@media (prefers-reduced-motion:reduce){.collapsing{transition:none}}.collapsing.collapse-horizontal{width:0;height:auto;transition:width .35s ease}@media (prefers-reduced-motion:reduce){.collapsing.collapse-horizontal{transition:none}}.dropdown,.dropdown-center,.dropend,.dropstart,.dropup,.dropup-center{position:relative}.dropdown-toggle{white-space:nowrap}.dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:"";border-top:.3em solid;border-right:.3em solid transparent;border-bottom:0;border-left:.3em solid transparent}.dropdown-toggle:empty::after{margin-left:0}.dropdown-menu{--bs-dropdown-zindex:1000;--bs-dropdown-min-width:10rem;--bs-dropdown-padding-x:0;--bs-dropdown-padding-y:0.5rem;--bs-dropdown-spacer:0.125rem;--bs-dropdown-font-size:1rem;--bs-dropdown-color:var(--bs-body-color);--bs-dropdown-bg:var(--bs-body-bg);--bs-dropdown-border-color:var(--bs-border-color-translucent);--bs-dropdown-border-radius:var(--bs-border-radius);--bs-dropdown-border-width:var(--bs-border-width);--bs-dropdown-inner-border-radius:calc(var(--bs-border-radius) - var(--bs-border-width));--bs-dropdown-divider-bg:var(--bs-border-color-translucent);--bs-dropdown-divider-margin-y:0.5rem;--bs-dropdown-box-shadow:var(--bs-box-shadow);--bs-dropdown-link-color:var(--bs-body-color);--bs-dropdown-link-hover-color:var(--bs-body-color);--bs-dropdown-link-hover-bg:var(--bs-tertiary-bg);--bs-dropdown-link-active-color:#fff;--bs-dropdown-link-active-bg:#0d6efd;--bs-dropdown-link-disabled-color:var(--bs-tertiary-color);--bs-dropdown-item-padding-x:1rem;--bs-dropdown-item-padding-y:0.25rem;--bs-dropdown-header-color:#6c757d;--bs-dropdown-header-padding-x:1rem;--bs-dropdown-header-padding-y:0.5rem;position:absolute;z-index:var(--bs-dropdown-zindex);display:none;min-width:var(--bs-dropdown-min-width);padding:var(--bs-dropdown-padding-y) var(--bs-dropdown-padding-x);margin:0;font-size:var(--bs-dropdown-font-size);color:var(--bs-dropdown-color);text-align:left;list-style:none;background-color:var(--bs-dropdown-bg);background-clip:padding-box;border:var(--bs-dropdown-border-width) solid var(--bs-dropdown-border-color);border-radius:var(--bs-dropdown-border-radius)}.dropdown-menu[data-bs-popper]{top:100%;left:0;margin-top:var(--bs-dropdown-spacer)}.dropdown-menu-start{--bs-position:start}.dropdown-menu-start[data-bs-popper]{right:auto;left:0}.dropdown-menu-end{--bs-position:end}.dropdown-menu-end[data-bs-popper]{right:0;left:auto}@media (min-width:576px){.dropdown-menu-sm-start{--bs-position:start}.dropdown-menu-sm-start[data-bs-popper]{right:auto;left:0}.dropdown-menu-sm-end{--bs-position:end}.dropdown-menu-sm-end[data-bs-popper]{right:0;left:auto}}@media (min-width:768px){.dropdown-menu-md-start{--bs-position:start}.dropdown-menu-md-start[data-bs-popper]{right:auto;left:0}.dropdown-menu-md-end{--bs-position:end}.dropdown-menu-md-end[data-bs-popper]{right:0;left:auto}}@media (min-width:992px){.dropdown-menu-lg-start{--bs-position:start}.dropdown-menu-lg-start[data-bs-popper]{right:auto;left:0}.dropdown-menu-lg-end{--bs-position:end}.dropdown-menu-lg-end[data-bs-popper]{right:0;left:auto}}@media (min-width:1200px){.dropdown-menu-xl-start{--bs-position:start}.dropdown-menu-xl-start[data-bs-popper]{right:auto;left:0}.dropdown-menu-xl-end{--bs-position:end}.dropdown-menu-xl-end[data-bs-popper]{right:0;left:auto}}@media (min-width:1400px){.dropdown-menu-xxl-start{--bs-position:start}.dropdown-menu-xxl-start[data-bs-popper]{right:auto;left:0}.dropdown-menu-xxl-end{--bs-position:end}.dropdown-menu-xxl-end[data-bs-popper]{right:0;left:auto}}.dropup .dropdown-menu[data-bs-popper]{top:auto;bottom:100%;margin-top:0;margin-bottom:var(--bs-dropdown-spacer)}.dropup .dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:"";border-top:0;border-right:.3em solid transparent;border-bottom:.3em solid;border-left:.3em solid transparent}.dropup .dropdown-toggle:empty::after{margin-left:0}.dropend .dropdown-menu[data-bs-popper]{top:0;right:auto;left:100%;margin-top:0;margin-left:var(--bs-dropdown-spacer)}.dropend .dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:"";border-top:.3em solid transparent;border-right:0;border-bottom:.3em solid transparent;border-left:.3em solid}.dropend .dropdown-toggle:empty::after{margin-left:0}.dropend .dropdown-toggle::after{vertical-align:0}.dropstart .dropdown-menu[data-bs-popper]{top:0;right:100%;left:auto;margin-top:0;margin-right:var(--bs-dropdown-spacer)}.dropstart .dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:""}.dropstart .dropdown-toggle::after{display:none}.dropstart .dropdown-toggle::before{display:inline-block;margin-right:.255em;vertical-align:.255em;content:"";border-top:.3em solid transparent;border-right:.3em solid;border-bottom:.3em solid transparent}.dropstart .dropdown-toggle:empty::after{margin-left:0}.dropstart .dropdown-toggle::before{vertical-align:0}.dropdown-divider{height:0;margin:var(--bs-dropdown-divider-margin-y) 0;overflow:hidden;border-top:1px solid var(--bs-dropdown-divider-bg);opacity:1}.dropdown-item{display:block;width:100%;padding:var(--bs-dropdown-item-padding-y) var(--bs-dropdown-item-padding-x);clear:both;font-weight:400;color:var(--bs-dropdown-link-color);text-align:inherit;text-decoration:none;white-space:nowrap;background-color:transparent;border:0;border-radius:var(--bs-dropdown-item-border-radius,0)}.dropdown-item:focus,.dropdown-item:hover{color:var(--bs-dropdown-link-hover-color);background-color:var(--bs-dropdown-link-hover-bg)}.dropdown-item.active,.dropdown-item:active{color:var(--bs-dropdown-link-active-color);text-decoration:none;background-color:var(--bs-dropdown-link-active-bg)}.dropdown-item.disabled,.dropdown-item:disabled{color:var(--bs-dropdown-link-disabled-color);pointer-events:none;background-color:transparent}.dropdown-menu.show{display:block}.dropdown-header{display:block;padding:var(--bs-dropdown-header-padding-y) var(--bs-dropdown-header-padding-x);margin-bottom:0;font-size:.875rem;color:var(--bs-dropdown-header-color);white-space:nowrap}.dropdown-item-text{display:block;padding:var(--bs-dropdown-item-padding-y) var(--bs-dropdown-item-padding-x);color:var(--bs-dropdown-link-color)}.dropdown-menu-dark{--bs-dropdown-color:#dee2e6;--bs-dropdown-bg:#343a40;--bs-dropdown-border-color:var(--bs-border-color-translucent);--bs-dropdown-box-shadow: ;--bs-dropdown-link-color:#dee2e6;--bs-dropdown-link-hover-color:#fff;--bs-dropdown-divider-bg:var(--bs-border-color-translucent);--bs-dropdown-link-hover-bg:rgba(255, 255, 255, 0.15);--bs-dropdown-link-active-color:#fff;--bs-dropdown-link-active-bg:#0d6efd;--bs-dropdown-link-disabled-color:#adb5bd;--bs-dropdown-header-color:#adb5bd}.btn-group,.btn-group-vertical{position:relative;display:inline-flex;vertical-align:middle}.btn-group-vertical>.btn,.btn-group>.btn{position:relative;flex:1 1 auto}.btn-group-vertical>.btn-check:checked+.btn,.btn-group-vertical>.btn-check:focus+.btn,.btn-group-vertical>.btn.active,.btn-group-vertical>.btn:active,.btn-group-vertical>.btn:focus,.btn-group-vertical>.btn:hover,.btn-group>.btn-check:checked+.btn,.btn-group>.btn-check:focus+.btn,.btn-group>.btn.active,.btn-group>.btn:active,.btn-group>.btn:focus,.btn-group>.btn:hover{z-index:1}.btn-toolbar{display:flex;flex-wrap:wrap;justify-content:flex-start}.btn-toolbar .input-group{width:auto}.btn-group{border-radius:var(--bs-border-radius)}.btn-group>.btn-group:not(:first-child),.btn-group>:not(.btn-check:first-child)+.btn{margin-left:calc(-1 * var(--bs-border-width))}.btn-group>.btn-group:not(:last-child)>.btn,.btn-group>.btn.dropdown-toggle-split:first-child,.btn-group>.btn:not(:last-child):not(.dropdown-toggle){border-top-right-radius:0;border-bottom-right-radius:0}.btn-group>.btn-group:not(:first-child)>.btn,.btn-group>.btn:nth-child(n+3),.btn-group>:not(.btn-check)+.btn{border-top-left-radius:0;border-bottom-left-radius:0}.dropdown-toggle-split{padding-right:.5625rem;padding-left:.5625rem}.dropdown-toggle-split::after,.dropend .dropdown-toggle-split::after,.dropup .dropdown-toggle-split::after{margin-left:0}.dropstart .dropdown-toggle-split::before{margin-right:0}.btn-group-sm>.btn+.dropdown-toggle-split,.btn-sm+.dropdown-toggle-split{padding-right:.375rem;padding-left:.375rem}.btn-group-lg>.btn+.dropdown-toggle-split,.btn-lg+.dropdown-toggle-split{padding-right:.75rem;padding-left:.75rem}.btn-group-vertical{flex-direction:column;align-items:flex-start;justify-content:center}.btn-group-vertical>.btn,.btn-group-vertical>.btn-group{width:100%}.btn-group-vertical>.btn-group:not(:first-child),.btn-group-vertical>.btn:not(:first-child){margin-top:calc(-1 * var(--bs-border-width))}.btn-group-vertical>.btn-group:not(:last-child)>.btn,.btn-group-vertical>.btn:not(:last-child):not(.dropdown-toggle){border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn-group:not(:first-child)>.btn,.btn-group-vertical>.btn:nth-child(n+3),.btn-group-vertical>:not(.btn-check)+.btn{border-top-left-radius:0;border-top-right-radius:0}.nav{--bs-nav-link-padding-x:1rem;--bs-nav-link-padding-y:0.5rem;--bs-nav-link-font-weight: ;--bs-nav-link-color:var(--bs-link-color);--bs-nav-link-hover-color:var(--bs-link-hover-color);--bs-nav-link-disabled-color:var(--bs-secondary-color);display:flex;flex-wrap:wrap;padding-left:0;margin-bottom:0;list-style:none}.nav-link{display:block;padding:var(--bs-nav-link-padding-y) var(--bs-nav-link-padding-x);font-size:var(--bs-nav-link-font-size);font-weight:var(--bs-nav-link-font-weight);color:var(--bs-nav-link-color);text-decoration:none;background:0 0;border:0;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out}@media (prefers-reduced-motion:reduce){.nav-link{transition:none}}.nav-link:focus,.nav-link:hover{color:var(--bs-nav-link-hover-color)}.nav-link:focus-visible{outline:0;box-shadow:0 0 0 .25rem rgba(13,110,253,.25)}.nav-link.disabled,.nav-link:disabled{color:var(--bs-nav-link-disabled-color);pointer-events:none;cursor:default}.nav-tabs{--bs-nav-tabs-border-width:var(--bs-border-width);--bs-nav-tabs-border-color:var(--bs-border-color);--bs-nav-tabs-border-radius:var(--bs-border-radius);--bs-nav-tabs-link-hover-border-color:var(--bs-secondary-bg) var(--bs-secondary-bg) var(--bs-border-color);--bs-nav-tabs-link-active-color:var(--bs-emphasis-color);--bs-nav-tabs-link-active-bg:var(--bs-body-bg);--bs-nav-tabs-link-active-border-color:var(--bs-border-color) var(--bs-border-color) var(--bs-body-bg);border-bottom:var(--bs-nav-tabs-border-width) solid var(--bs-nav-tabs-border-color)}.nav-tabs .nav-link{margin-bottom:calc(-1 * var(--bs-nav-tabs-border-width));border:var(--bs-nav-tabs-border-width) solid transparent;border-top-left-radius:var(--bs-nav-tabs-border-radius);border-top-right-radius:var(--bs-nav-tabs-border-radius)}.nav-tabs .nav-link:focus,.nav-tabs .nav-link:hover{isolation:isolate;border-color:var(--bs-nav-tabs-link-hover-border-color)}.nav-tabs .nav-item.show .nav-link,.nav-tabs .nav-link.active{color:var(--bs-nav-tabs-link-active-color);background-color:var(--bs-nav-tabs-link-active-bg);border-color:var(--bs-nav-tabs-link-active-border-color)}.nav-tabs .dropdown-menu{margin-top:calc(-1 * var(--bs-nav-tabs-border-width));border-top-left-radius:0;border-top-right-radius:0}.nav-pills{--bs-nav-pills-border-radius:var(--bs-border-radius);--bs-nav-pills-link-active-color:#fff;--bs-nav-pills-link-active-bg:#0d6efd}.nav-pills .nav-link{border-radius:var(--bs-nav-pills-border-radius)}.nav-pills .nav-link.active,.nav-pills .show>.nav-link{color:var(--bs-nav-pills-link-active-color);background-color:var(--bs-nav-pills-link-active-bg)}.nav-underline{--bs-nav-underline-gap:1rem;--bs-nav-underline-border-width:0.125rem;--bs-nav-underline-link-active-color:var(--bs-emphasis-color);gap:var(--bs-nav-underline-gap)}.nav-underline .nav-link{padding-right:0;padding-left:0;border-bottom:var(--bs-nav-underline-border-width) solid transparent}.nav-underline .nav-link:focus,.nav-underline .nav-link:hover{border-bottom-color:currentcolor}.nav-underline .nav-link.active,.nav-underline .show>.nav-link{font-weight:700;color:var(--bs-nav-underline-link-active-color);border-bottom-color:currentcolor}.nav-fill .nav-item,.nav-fill>.nav-link{flex:1 1 auto;text-align:center}.nav-justified .nav-item,.nav-justified>.nav-link{flex-grow:1;flex-basis:0;text-align:center}.nav-fill .nav-item .nav-link,.nav-justified .nav-item .nav-link{width:100%}.tab-content>.tab-pane{display:none}.tab-content>.active{display:block}.navbar{--bs-navbar-padding-x:0;--bs-navbar-padding-y:0.5rem;--bs-navbar-color:rgba(var(--bs-emphasis-color-rgb), 0.65);--bs-navbar-hover-color:rgba(var(--bs-emphasis-color-rgb), 0.8);--bs-navbar-disabled-color:rgba(var(--bs-emphasis-color-rgb), 0.3);--bs-navbar-active-color:rgba(var(--bs-emphasis-color-rgb), 1);--bs-navbar-brand-padding-y:0.3125rem;--bs-navbar-brand-margin-end:1rem;--bs-navbar-brand-font-size:1.25rem;--bs-navbar-brand-color:rgba(var(--bs-emphasis-color-rgb), 1);--bs-navbar-brand-hover-color:rgba(var(--bs-emphasis-color-rgb), 1);--bs-navbar-nav-link-padding-x:0.5rem;--bs-navbar-toggler-padding-y:0.25rem;--bs-navbar-toggler-padding-x:0.75rem;--bs-navbar-toggler-font-size:1.25rem;--bs-navbar-toggler-icon-bg:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 30 30'%3e%3cpath stroke='rgba%2833, 37, 41, 0.75%29' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e");--bs-navbar-toggler-border-color:rgba(var(--bs-emphasis-color-rgb), 0.15);--bs-navbar-toggler-border-radius:var(--bs-border-radius);--bs-navbar-toggler-focus-width:0.25rem;--bs-navbar-toggler-transition:box-shadow 0.15s ease-in-out;position:relative;display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;padding:var(--bs-navbar-padding-y) var(--bs-navbar-padding-x)}.navbar>.container,.navbar>.container-fluid,.navbar>.container-lg,.navbar>.container-md,.navbar>.container-sm,.navbar>.container-xl,.navbar>.container-xxl{display:flex;flex-wrap:inherit;align-items:center;justify-content:space-between}.navbar-brand{padding-top:var(--bs-navbar-brand-padding-y);padding-bottom:var(--bs-navbar-brand-padding-y);margin-right:var(--bs-navbar-brand-margin-end);font-size:var(--bs-navbar-brand-font-size);color:var(--bs-navbar-brand-color);text-decoration:none;white-space:nowrap}.navbar-brand:focus,.navbar-brand:hover{color:var(--bs-navbar-brand-hover-color)}.navbar-nav{--bs-nav-link-padding-x:0;--bs-nav-link-padding-y:0.5rem;--bs-nav-link-font-weight: ;--bs-nav-link-color:var(--bs-navbar-color);--bs-nav-link-hover-color:var(--bs-navbar-hover-color);--bs-nav-link-disabled-color:var(--bs-navbar-disabled-color);display:flex;flex-direction:column;padding-left:0;margin-bottom:0;list-style:none}.navbar-nav .nav-link.active,.navbar-nav .nav-link.show{color:var(--bs-navbar-active-color)}.navbar-nav .dropdown-menu{position:static}.navbar-text{padding-top:.5rem;padding-bottom:.5rem;color:var(--bs-navbar-color)}.navbar-text a,.navbar-text a:focus,.navbar-text a:hover{color:var(--bs-navbar-active-color)}.navbar-collapse{flex-grow:1;flex-basis:100%;align-items:center}.navbar-toggler{padding:var(--bs-navbar-toggler-padding-y) var(--bs-navbar-toggler-padding-x);font-size:var(--bs-navbar-toggler-font-size);line-height:1;color:var(--bs-navbar-color);background-color:transparent;border:var(--bs-border-width) solid var(--bs-navbar-toggler-border-color);border-radius:var(--bs-navbar-toggler-border-radius);transition:var(--bs-navbar-toggler-transition)}@media (prefers-reduced-motion:reduce){.navbar-toggler{transition:none}}.navbar-toggler:hover{text-decoration:none}.navbar-toggler:focus{text-decoration:none;outline:0;box-shadow:0 0 0 var(--bs-navbar-toggler-focus-width)}.navbar-toggler-icon{display:inline-block;width:1.5em;height:1.5em;vertical-align:middle;background-image:var(--bs-navbar-toggler-icon-bg);background-repeat:no-repeat;background-position:center;background-size:100%}.navbar-nav-scroll{max-height:var(--bs-scroll-height,75vh);overflow-y:auto}@media (min-width:576px){.navbar-expand-sm{flex-wrap:nowrap;justify-content:flex-start}.navbar-expand-sm .navbar-nav{flex-direction:row}.navbar-expand-sm .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-sm .navbar-nav .nav-link{padding-right:var(--bs-navbar-nav-link-padding-x);padding-left:var(--bs-navbar-nav-link-padding-x)}.navbar-expand-sm .navbar-nav-scroll{overflow:visible}.navbar-expand-sm .navbar-collapse{display:flex!important;flex-basis:auto}.navbar-expand-sm .navbar-toggler{display:none}.navbar-expand-sm .offcanvas{position:static;z-index:auto;flex-grow:1;width:auto!important;height:auto!important;visibility:visible!important;background-color:transparent!important;border:0!important;transform:none!important;transition:none}.navbar-expand-sm .offcanvas .offcanvas-header{display:none}.navbar-expand-sm .offcanvas .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible}}@media (min-width:768px){.navbar-expand-md{flex-wrap:nowrap;justify-content:flex-start}.navbar-expand-md .navbar-nav{flex-direction:row}.navbar-expand-md .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-md .navbar-nav .nav-link{padding-right:var(--bs-navbar-nav-link-padding-x);padding-left:var(--bs-navbar-nav-link-padding-x)}.navbar-expand-md .navbar-nav-scroll{overflow:visible}.navbar-expand-md .navbar-collapse{display:flex!important;flex-basis:auto}.navbar-expand-md .navbar-toggler{display:none}.navbar-expand-md .offcanvas{position:static;z-index:auto;flex-grow:1;width:auto!important;height:auto!important;visibility:visible!important;background-color:transparent!important;border:0!important;transform:none!important;transition:none}.navbar-expand-md .offcanvas .offcanvas-header{display:none}.navbar-expand-md .offcanvas .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible}}@media (min-width:992px){.navbar-expand-lg{flex-wrap:nowrap;justify-content:flex-start}.navbar-expand-lg .navbar-nav{flex-direction:row}.navbar-expand-lg .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-lg .navbar-nav .nav-link{padding-right:var(--bs-navbar-nav-link-padding-x);padding-left:var(--bs-navbar-nav-link-padding-x)}.navbar-expand-lg .navbar-nav-scroll{overflow:visible}.navbar-expand-lg .navbar-collapse{display:flex!important;flex-basis:auto}.navbar-expand-lg .navbar-toggler{display:none}.navbar-expand-lg .offcanvas{position:static;z-index:auto;flex-grow:1;width:auto!important;height:auto!important;visibility:visible!important;background-color:transparent!important;border:0!important;transform:none!important;transition:none}.navbar-expand-lg .offcanvas .offcanvas-header{display:none}.navbar-expand-lg .offcanvas .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible}}@media (min-width:1200px){.navbar-expand-xl{flex-wrap:nowrap;justify-content:flex-start}.navbar-expand-xl .navbar-nav{flex-direction:row}.navbar-expand-xl .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-xl .navbar-nav .nav-link{padding-right:var(--bs-navbar-nav-link-padding-x);padding-left:var(--bs-navbar-nav-link-padding-x)}.navbar-expand-xl .navbar-nav-scroll{overflow:visible}.navbar-expand-xl .navbar-collapse{display:flex!important;flex-basis:auto}.navbar-expand-xl .navbar-toggler{display:none}.navbar-expand-xl .offcanvas{position:static;z-index:auto;flex-grow:1;width:auto!important;height:auto!important;visibility:visible!important;background-color:transparent!important;border:0!important;transform:none!important;transition:none}.navbar-expand-xl .offcanvas .offcanvas-header{display:none}.navbar-expand-xl .offcanvas .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible}}@media (min-width:1400px){.navbar-expand-xxl{flex-wrap:nowrap;justify-content:flex-start}.navbar-expand-xxl .navbar-nav{flex-direction:row}.navbar-expand-xxl .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-xxl .navbar-nav .nav-link{padding-right:var(--bs-navbar-nav-link-padding-x);padding-left:var(--bs-navbar-nav-link-padding-x)}.navbar-expand-xxl .navbar-nav-scroll{overflow:visible}.navbar-expand-xxl .navbar-collapse{display:flex!important;flex-basis:auto}.navbar-expand-xxl .navbar-toggler{display:none}.navbar-expand-xxl .offcanvas{position:static;z-index:auto;flex-grow:1;width:auto!important;height:auto!important;visibility:visible!important;background-color:transparent!important;border:0!important;transform:none!important;transition:none}.navbar-expand-xxl .offcanvas .offcanvas-header{display:none}.navbar-expand-xxl .offcanvas .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible}}.navbar-expand{flex-wrap:nowrap;justify-content:flex-start}.navbar-expand .navbar-nav{flex-direction:row}.navbar-expand .navbar-nav .dropdown-menu{position:absolute}.navbar-expand .navbar-nav .nav-link{padding-right:var(--bs-navbar-nav-link-padding-x);padding-left:var(--bs-navbar-nav-link-padding-x)}.navbar-expand .navbar-nav-scroll{overflow:visible}.navbar-expand .navbar-collapse{display:flex!important;flex-basis:auto}.navbar-expand .navbar-toggler{display:none}.navbar-expand .offcanvas{position:static;z-index:auto;flex-grow:1;width:auto!important;height:auto!important;visibility:visible!important;background-color:transparent!important;border:0!important;transform:none!important;transition:none}.navbar-expand .offcanvas .offcanvas-header{display:none}.navbar-expand .offcanvas .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible}.navbar-dark,.navbar[data-bs-theme=dark]{--bs-navbar-color:rgba(255, 255, 255, 0.55);--bs-navbar-hover-color:rgba(255, 255, 255, 0.75);--bs-navbar-disabled-color:rgba(255, 255, 255, 0.25);--bs-navbar-active-color:#fff;--bs-navbar-brand-color:#fff;--bs-navbar-brand-hover-color:#fff;--bs-navbar-toggler-border-color:rgba(255, 255, 255, 0.1);--bs-navbar-toggler-icon-bg:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 30 30'%3e%3cpath stroke='rgba%28255, 255, 255, 0.55%29' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e")}[data-bs-theme=dark] .navbar-toggler-icon{--bs-navbar-toggler-icon-bg:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 30 30'%3e%3cpath stroke='rgba%28255, 255, 255, 0.55%29' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e")}.card{--bs-card-spacer-y:1rem;--bs-card-spacer-x:1rem;--bs-card-title-spacer-y:0.5rem;--bs-card-title-color: ;--bs-card-subtitle-color: ;--bs-card-border-width:var(--bs-border-width);--bs-card-border-color:var(--bs-border-color-translucent);--bs-card-border-radius:var(--bs-border-radius);--bs-card-box-shadow: ;--bs-card-inner-border-radius:calc(var(--bs-border-radius) - (var(--bs-border-width)));--bs-card-cap-padding-y:0.5rem;--bs-card-cap-padding-x:1rem;--bs-card-cap-bg:rgba(var(--bs-body-color-rgb), 0.03);--bs-card-cap-color: ;--bs-card-height: ;--bs-card-color: ;--bs-card-bg:var(--bs-body-bg);--bs-card-img-overlay-padding:1rem;--bs-card-group-margin:0.75rem;position:relative;display:flex;flex-direction:column;min-width:0;height:var(--bs-card-height);color:var(--bs-body-color);word-wrap:break-word;background-color:var(--bs-card-bg);background-clip:border-box;border:var(--bs-card-border-width) solid var(--bs-card-border-color);border-radius:var(--bs-card-border-radius)}.card>hr{margin-right:0;margin-left:0}.card>.list-group{border-top:inherit;border-bottom:inherit}.card>.list-group:first-child{border-top-width:0;border-top-left-radius:var(--bs-card-inner-border-radius);border-top-right-radius:var(--bs-card-inner-border-radius)}.card>.list-group:last-child{border-bottom-width:0;border-bottom-right-radius:var(--bs-card-inner-border-radius);border-bottom-left-radius:var(--bs-card-inner-border-radius)}.card>.card-header+.list-group,.card>.list-group+.card-footer{border-top:0}.card-body{flex:1 1 auto;padding:var(--bs-card-spacer-y) var(--bs-card-spacer-x);color:var(--bs-card-color)}.card-title{margin-bottom:var(--bs-card-title-spacer-y);color:var(--bs-card-title-color)}.card-subtitle{margin-top:calc(-.5 * var(--bs-card-title-spacer-y));margin-bottom:0;color:var(--bs-card-subtitle-color)}.card-text:last-child{margin-bottom:0}.card-link+.card-link{margin-left:var(--bs-card-spacer-x)}.card-header{padding:var(--bs-card-cap-padding-y) var(--bs-card-cap-padding-x);margin-bottom:0;color:var(--bs-card-cap-color);background-color:var(--bs-card-cap-bg);border-bottom:var(--bs-card-border-width) solid var(--bs-card-border-color)}.card-header:first-child{border-radius:var(--bs-card-inner-border-radius) var(--bs-card-inner-border-radius) 0 0}.card-footer{padding:var(--bs-card-cap-padding-y) var(--bs-card-cap-padding-x);color:var(--bs-card-cap-color);background-color:var(--bs-card-cap-bg);border-top:var(--bs-card-border-width) solid var(--bs-card-border-color)}.card-footer:last-child{border-radius:0 0 var(--bs-card-inner-border-radius) var(--bs-card-inner-border-radius)}.card-header-tabs{margin-right:calc(-.5 * var(--bs-card-cap-padding-x));margin-bottom:calc(-1 * var(--bs-card-cap-padding-y));margin-left:calc(-.5 * var(--bs-card-cap-padding-x));border-bottom:0}.card-header-tabs .nav-link.active{background-color:var(--bs-card-bg);border-bottom-color:var(--bs-card-bg)}.card-header-pills{margin-right:calc(-.5 * var(--bs-card-cap-padding-x));margin-left:calc(-.5 * var(--bs-card-cap-padding-x))}.card-img-overlay{position:absolute;top:0;right:0;bottom:0;left:0;padding:var(--bs-card-img-overlay-padding);border-radius:var(--bs-card-inner-border-radius)}.card-img,.card-img-bottom,.card-img-top{width:100%}.card-img,.card-img-top{border-top-left-radius:var(--bs-card-inner-border-radius);border-top-right-radius:var(--bs-card-inner-border-radius)}.card-img,.card-img-bottom{border-bottom-right-radius:var(--bs-card-inner-border-radius);border-bottom-left-radius:var(--bs-card-inner-border-radius)}.card-group>.card{margin-bottom:var(--bs-card-group-margin)}@media (min-width:576px){.card-group{display:flex;flex-flow:row wrap}.card-group>.card{flex:1 0 0;margin-bottom:0}.card-group>.card+.card{margin-left:0;border-left:0}.card-group>.card:not(:last-child){border-top-right-radius:0;border-bottom-right-radius:0}.card-group>.card:not(:last-child)>.card-header,.card-group>.card:not(:last-child)>.card-img-top{border-top-right-radius:0}.card-group>.card:not(:last-child)>.card-footer,.card-group>.card:not(:last-child)>.card-img-bottom{border-bottom-right-radius:0}.card-group>.card:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0}.card-group>.card:not(:first-child)>.card-header,.card-group>.card:not(:first-child)>.card-img-top{border-top-left-radius:0}.card-group>.card:not(:first-child)>.card-footer,.card-group>.card:not(:first-child)>.card-img-bottom{border-bottom-left-radius:0}}.accordion{--bs-accordion-color:var(--bs-body-color);--bs-accordion-bg:var(--bs-body-bg);--bs-accordion-transition:color 0.15s ease-in-out,background-color 0.15s ease-in-out,border-color 0.15s ease-in-out,box-shadow 0.15s ease-in-out,border-radius 0.15s ease;--bs-accordion-border-color:var(--bs-border-color);--bs-accordion-border-width:var(--bs-border-width);--bs-accordion-border-radius:var(--bs-border-radius);--bs-accordion-inner-border-radius:calc(var(--bs-border-radius) - (var(--bs-border-width)));--bs-accordion-btn-padding-x:1.25rem;--bs-accordion-btn-padding-y:1rem;--bs-accordion-btn-color:var(--bs-body-color);--bs-accordion-btn-bg:var(--bs-accordion-bg);--bs-accordion-btn-icon:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='%23212529' stroke-linecap='round' stroke-linejoin='round'%3e%3cpath d='m2 5 6 6 6-6'/%3e%3c/svg%3e");--bs-accordion-btn-icon-width:1.25rem;--bs-accordion-btn-icon-transform:rotate(-180deg);--bs-accordion-btn-icon-transition:transform 0.2s ease-in-out;--bs-accordion-btn-active-icon:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='%23052c65' stroke-linecap='round' stroke-linejoin='round'%3e%3cpath d='m2 5 6 6 6-6'/%3e%3c/svg%3e");--bs-accordion-btn-focus-box-shadow:0 0 0 0.25rem rgba(13, 110, 253, 0.25);--bs-accordion-body-padding-x:1.25rem;--bs-accordion-body-padding-y:1rem;--bs-accordion-active-color:var(--bs-primary-text-emphasis);--bs-accordion-active-bg:var(--bs-primary-bg-subtle)}.accordion-button{position:relative;display:flex;align-items:center;width:100%;padding:var(--bs-accordion-btn-padding-y) var(--bs-accordion-btn-padding-x);font-size:1rem;color:var(--bs-accordion-btn-color);text-align:left;background-color:var(--bs-accordion-btn-bg);border:0;border-radius:0;overflow-anchor:none;transition:var(--bs-accordion-transition)}@media (prefers-reduced-motion:reduce){.accordion-button{transition:none}}.accordion-button:not(.collapsed){color:var(--bs-accordion-active-color);background-color:var(--bs-accordion-active-bg);box-shadow:inset 0 calc(-1 * var(--bs-accordion-border-width)) 0 var(--bs-accordion-border-color)}.accordion-button:not(.collapsed)::after{background-image:var(--bs-accordion-btn-active-icon);transform:var(--bs-accordion-btn-icon-transform)}.accordion-button::after{flex-shrink:0;width:var(--bs-accordion-btn-icon-width);height:var(--bs-accordion-btn-icon-width);margin-left:auto;content:"";background-image:var(--bs-accordion-btn-icon);background-repeat:no-repeat;background-size:var(--bs-accordion-btn-icon-width);transition:var(--bs-accordion-btn-icon-transition)}@media (prefers-reduced-motion:reduce){.accordion-button::after{transition:none}}.accordion-button:hover{z-index:2}.accordion-button:focus{z-index:3;outline:0;box-shadow:var(--bs-accordion-btn-focus-box-shadow)}.accordion-header{margin-bottom:0}.accordion-item{color:var(--bs-accordion-color);background-color:var(--bs-accordion-bg);border:var(--bs-accordion-border-width) solid var(--bs-accordion-border-color)}.accordion-item:first-of-type{border-top-left-radius:var(--bs-accordion-border-radius);border-top-right-radius:var(--bs-accordion-border-radius)}.accordion-item:first-of-type>.accordion-header .accordion-button{border-top-left-radius:var(--bs-accordion-inner-border-radius);border-top-right-radius:var(--bs-accordion-inner-border-radius)}.accordion-item:not(:first-of-type){border-top:0}.accordion-item:last-of-type{border-bottom-right-radius:var(--bs-accordion-border-radius);border-bottom-left-radius:var(--bs-accordion-border-radius)}.accordion-item:last-of-type>.accordion-header .accordion-button.collapsed{border-bottom-right-radius:var(--bs-accordion-inner-border-radius);border-bottom-left-radius:var(--bs-accordion-inner-border-radius)}.accordion-item:last-of-type>.accordion-collapse{border-bottom-right-radius:var(--bs-accordion-border-radius);border-bottom-left-radius:var(--bs-accordion-border-radius)}.accordion-body{padding:var(--bs-accordion-body-padding-y) var(--bs-accordion-body-padding-x)}.accordion-flush>.accordion-item{border-right:0;border-left:0;border-radius:0}.accordion-flush>.accordion-item:first-child{border-top:0}.accordion-flush>.accordion-item:last-child{border-bottom:0}.accordion-flush>.accordion-item>.accordion-collapse,.accordion-flush>.accordion-item>.accordion-header .accordion-button,.accordion-flush>.accordion-item>.accordion-header .accordion-button.collapsed{border-radius:0}[data-bs-theme=dark] .accordion-button::after{--bs-accordion-btn-icon:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%236ea8fe'%3e%3cpath fill-rule='evenodd' d='M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708'/%3e%3c/svg%3e");--bs-accordion-btn-active-icon:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%236ea8fe'%3e%3cpath fill-rule='evenodd' d='M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708'/%3e%3c/svg%3e")}.breadcrumb{--bs-breadcrumb-padding-x:0;--bs-breadcrumb-padding-y:0;--bs-breadcrumb-margin-bottom:1rem;--bs-breadcrumb-bg: ;--bs-breadcrumb-border-radius: ;--bs-breadcrumb-divider-color:var(--bs-secondary-color);--bs-breadcrumb-item-padding-x:0.5rem;--bs-breadcrumb-item-active-color:var(--bs-secondary-color);display:flex;flex-wrap:wrap;padding:var(--bs-breadcrumb-padding-y) var(--bs-breadcrumb-padding-x);margin-bottom:var(--bs-breadcrumb-margin-bottom);font-size:var(--bs-breadcrumb-font-size);list-style:none;background-color:var(--bs-breadcrumb-bg);border-radius:var(--bs-breadcrumb-border-radius)}.breadcrumb-item+.breadcrumb-item{padding-left:var(--bs-breadcrumb-item-padding-x)}.breadcrumb-item+.breadcrumb-item::before{float:left;padding-right:var(--bs-breadcrumb-item-padding-x);color:var(--bs-breadcrumb-divider-color);content:var(--bs-breadcrumb-divider, "/")}.breadcrumb-item.active{color:var(--bs-breadcrumb-item-active-color)}.pagination{--bs-pagination-padding-x:0.75rem;--bs-pagination-padding-y:0.375rem;--bs-pagination-font-size:1rem;--bs-pagination-color:var(--bs-link-color);--bs-pagination-bg:var(--bs-body-bg);--bs-pagination-border-width:var(--bs-border-width);--bs-pagination-border-color:var(--bs-border-color);--bs-pagination-border-radius:var(--bs-border-radius);--bs-pagination-hover-color:var(--bs-link-hover-color);--bs-pagination-hover-bg:var(--bs-tertiary-bg);--bs-pagination-hover-border-color:var(--bs-border-color);--bs-pagination-focus-color:var(--bs-link-hover-color);--bs-pagination-focus-bg:var(--bs-secondary-bg);--bs-pagination-focus-box-shadow:0 0 0 0.25rem rgba(13, 110, 253, 0.25);--bs-pagination-active-color:#fff;--bs-pagination-active-bg:#0d6efd;--bs-pagination-active-border-color:#0d6efd;--bs-pagination-disabled-color:var(--bs-secondary-color);--bs-pagination-disabled-bg:var(--bs-secondary-bg);--bs-pagination-disabled-border-color:var(--bs-border-color);display:flex;padding-left:0;list-style:none}.page-link{position:relative;display:block;padding:var(--bs-pagination-padding-y) var(--bs-pagination-padding-x);font-size:var(--bs-pagination-font-size);color:var(--bs-pagination-color);text-decoration:none;background-color:var(--bs-pagination-bg);border:var(--bs-pagination-border-width) solid var(--bs-pagination-border-color);transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.page-link{transition:none}}.page-link:hover{z-index:2;color:var(--bs-pagination-hover-color);background-color:var(--bs-pagination-hover-bg);border-color:var(--bs-pagination-hover-border-color)}.page-link:focus{z-index:3;color:var(--bs-pagination-focus-color);background-color:var(--bs-pagination-focus-bg);outline:0;box-shadow:var(--bs-pagination-focus-box-shadow)}.active>.page-link,.page-link.active{z-index:3;color:var(--bs-pagination-active-color);background-color:var(--bs-pagination-active-bg);border-color:var(--bs-pagination-active-border-color)}.disabled>.page-link,.page-link.disabled{color:var(--bs-pagination-disabled-color);pointer-events:none;background-color:var(--bs-pagination-disabled-bg);border-color:var(--bs-pagination-disabled-border-color)}.page-item:not(:first-child) .page-link{margin-left:calc(-1 * var(--bs-border-width))}.page-item:first-child .page-link{border-top-left-radius:var(--bs-pagination-border-radius);border-bottom-left-radius:var(--bs-pagination-border-radius)}.page-item:last-child .page-link{border-top-right-radius:var(--bs-pagination-border-radius);border-bottom-right-radius:var(--bs-pagination-border-radius)}.pagination-lg{--bs-pagination-padding-x:1.5rem;--bs-pagination-padding-y:0.75rem;--bs-pagination-font-size:1.25rem;--bs-pagination-border-radius:var(--bs-border-radius-lg)}.pagination-sm{--bs-pagination-padding-x:0.5rem;--bs-pagination-padding-y:0.25rem;--bs-pagination-font-size:0.875rem;--bs-pagination-border-radius:var(--bs-border-radius-sm)}.badge{--bs-badge-padding-x:0.65em;--bs-badge-padding-y:0.35em;--bs-badge-font-size:0.75em;--bs-badge-font-weight:700;--bs-badge-color:#fff;--bs-badge-border-radius:var(--bs-border-radius);display:inline-block;padding:var(--bs-badge-padding-y) var(--bs-badge-padding-x);font-size:var(--bs-badge-font-size);font-weight:var(--bs-badge-font-weight);line-height:1;color:var(--bs-badge-color);text-align:center;white-space:nowrap;vertical-align:baseline;border-radius:var(--bs-badge-border-radius)}.badge:empty{display:none}.btn .badge{position:relative;top:-1px}.alert{--bs-alert-bg:transparent;--bs-alert-padding-x:1rem;--bs-alert-padding-y:1rem;--bs-alert-margin-bottom:1rem;--bs-alert-color:inherit;--bs-alert-border-color:transparent;--bs-alert-border:var(--bs-border-width) solid var(--bs-alert-border-color);--bs-alert-border-radius:var(--bs-border-radius);--bs-alert-link-color:inherit;position:relative;padding:var(--bs-alert-padding-y) var(--bs-alert-padding-x);margin-bottom:var(--bs-alert-margin-bottom);color:var(--bs-alert-color);background-color:var(--bs-alert-bg);border:var(--bs-alert-border);border-radius:var(--bs-alert-border-radius)}.alert-heading{color:inherit}.alert-link{font-weight:700;color:var(--bs-alert-link-color)}.alert-dismissible{padding-right:3rem}.alert-dismissible .btn-close{position:absolute;top:0;right:0;z-index:2;padding:1.25rem 1rem}.alert-primary{--bs-alert-color:var(--bs-primary-text-emphasis);--bs-alert-bg:var(--bs-primary-bg-subtle);--bs-alert-border-color:var(--bs-primary-border-subtle);--bs-alert-link-color:var(--bs-primary-text-emphasis)}.alert-secondary{--bs-alert-color:var(--bs-secondary-text-emphasis);--bs-alert-bg:var(--bs-secondary-bg-subtle);--bs-alert-border-color:var(--bs-secondary-border-subtle);--bs-alert-link-color:var(--bs-secondary-text-emphasis)}.alert-success{--bs-alert-color:var(--bs-success-text-emphasis);--bs-alert-bg:var(--bs-success-bg-subtle);--bs-alert-border-color:var(--bs-success-border-subtle);--bs-alert-link-color:var(--bs-success-text-emphasis)}.alert-info{--bs-alert-color:var(--bs-info-text-emphasis);--bs-alert-bg:var(--bs-info-bg-subtle);--bs-alert-border-color:var(--bs-info-border-subtle);--bs-alert-link-color:var(--bs-info-text-emphasis)}.alert-warning{--bs-alert-color:var(--bs-warning-text-emphasis);--bs-alert-bg:var(--bs-warning-bg-subtle);--bs-alert-border-color:var(--bs-warning-border-subtle);--bs-alert-link-color:var(--bs-warning-text-emphasis)}.alert-danger{--bs-alert-color:var(--bs-danger-text-emphasis);--bs-alert-bg:var(--bs-danger-bg-subtle);--bs-alert-border-color:var(--bs-danger-border-subtle);--bs-alert-link-color:var(--bs-danger-text-emphasis)}.alert-light{--bs-alert-color:var(--bs-light-text-emphasis);--bs-alert-bg:var(--bs-light-bg-subtle);--bs-alert-border-color:var(--bs-light-border-subtle);--bs-alert-link-color:var(--bs-light-text-emphasis)}.alert-dark{--bs-alert-color:var(--bs-dark-text-emphasis);--bs-alert-bg:var(--bs-dark-bg-subtle);--bs-alert-border-color:var(--bs-dark-border-subtle);--bs-alert-link-color:var(--bs-dark-text-emphasis)}@keyframes progress-bar-stripes{0%{background-position-x:var(--bs-progress-height)}}.progress,.progress-stacked{--bs-progress-height:1rem;--bs-progress-font-size:0.75rem;--bs-progress-bg:var(--bs-secondary-bg);--bs-progress-border-radius:var(--bs-border-radius);--bs-progress-box-shadow:var(--bs-box-shadow-inset);--bs-progress-bar-color:#fff;--bs-progress-bar-bg:#0d6efd;--bs-progress-bar-transition:width 0.6s ease;display:flex;height:var(--bs-progress-height);overflow:hidden;font-size:var(--bs-progress-font-size);background-color:var(--bs-progress-bg);border-radius:var(--bs-progress-border-radius)}.progress-bar{display:flex;flex-direction:column;justify-content:center;overflow:hidden;color:var(--bs-progress-bar-color);text-align:center;white-space:nowrap;background-color:var(--bs-progress-bar-bg);transition:var(--bs-progress-bar-transition)}@media (prefers-reduced-motion:reduce){.progress-bar{transition:none}}.progress-bar-striped{background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-size:var(--bs-progress-height) var(--bs-progress-height)}.progress-stacked>.progress{overflow:visible}.progress-stacked>.progress>.progress-bar{width:100%}.progress-bar-animated{animation:1s linear infinite progress-bar-stripes}@media (prefers-reduced-motion:reduce){.progress-bar-animated{animation:none}}.list-group{--bs-list-group-color:var(--bs-body-color);--bs-list-group-bg:var(--bs-body-bg);--bs-list-group-border-color:var(--bs-border-color);--bs-list-group-border-width:var(--bs-border-width);--bs-list-group-border-radius:var(--bs-border-radius);--bs-list-group-item-padding-x:1rem;--bs-list-group-item-padding-y:0.5rem;--bs-list-group-action-color:var(--bs-secondary-color);--bs-list-group-action-hover-color:var(--bs-emphasis-color);--bs-list-group-action-hover-bg:var(--bs-tertiary-bg);--bs-list-group-action-active-color:var(--bs-body-color);--bs-list-group-action-active-bg:var(--bs-secondary-bg);--bs-list-group-disabled-color:var(--bs-secondary-color);--bs-list-group-disabled-bg:var(--bs-body-bg);--bs-list-group-active-color:#fff;--bs-list-group-active-bg:#0d6efd;--bs-list-group-active-border-color:#0d6efd;display:flex;flex-direction:column;padding-left:0;margin-bottom:0;border-radius:var(--bs-list-group-border-radius)}.list-group-numbered{list-style-type:none;counter-reset:section}.list-group-numbered>.list-group-item::before{content:counters(section, ".") ". ";counter-increment:section}.list-group-item{position:relative;display:block;padding:var(--bs-list-group-item-padding-y) var(--bs-list-group-item-padding-x);color:var(--bs-list-group-color);text-decoration:none;background-color:var(--bs-list-group-bg);border:var(--bs-list-group-border-width) solid var(--bs-list-group-border-color)}.list-group-item:first-child{border-top-left-radius:inherit;border-top-right-radius:inherit}.list-group-item:last-child{border-bottom-right-radius:inherit;border-bottom-left-radius:inherit}.list-group-item.disabled,.list-group-item:disabled{color:var(--bs-list-group-disabled-color);pointer-events:none;background-color:var(--bs-list-group-disabled-bg)}.list-group-item.active{z-index:2;color:var(--bs-list-group-active-color);background-color:var(--bs-list-group-active-bg);border-color:var(--bs-list-group-active-border-color)}.list-group-item+.list-group-item{border-top-width:0}.list-group-item+.list-group-item.active{margin-top:calc(-1 * var(--bs-list-group-border-width));border-top-width:var(--bs-list-group-border-width)}.list-group-item-action{width:100%;color:var(--bs-list-group-action-color);text-align:inherit}.list-group-item-action:not(.active):focus,.list-group-item-action:not(.active):hover{z-index:1;color:var(--bs-list-group-action-hover-color);text-decoration:none;background-color:var(--bs-list-group-action-hover-bg)}.list-group-item-action:not(.active):active{color:var(--bs-list-group-action-active-color);background-color:var(--bs-list-group-action-active-bg)}.list-group-horizontal{flex-direction:row}.list-group-horizontal>.list-group-item:first-child:not(:last-child){border-bottom-left-radius:var(--bs-list-group-border-radius);border-top-right-radius:0}.list-group-horizontal>.list-group-item:last-child:not(:first-child){border-top-right-radius:var(--bs-list-group-border-radius);border-bottom-left-radius:0}.list-group-horizontal>.list-group-item.active{margin-top:0}.list-group-horizontal>.list-group-item+.list-group-item{border-top-width:var(--bs-list-group-border-width);border-left-width:0}.list-group-horizontal>.list-group-item+.list-group-item.active{margin-left:calc(-1 * var(--bs-list-group-border-width));border-left-width:var(--bs-list-group-border-width)}@media (min-width:576px){.list-group-horizontal-sm{flex-direction:row}.list-group-horizontal-sm>.list-group-item:first-child:not(:last-child){border-bottom-left-radius:var(--bs-list-group-border-radius);border-top-right-radius:0}.list-group-horizontal-sm>.list-group-item:last-child:not(:first-child){border-top-right-radius:var(--bs-list-group-border-radius);border-bottom-left-radius:0}.list-group-horizontal-sm>.list-group-item.active{margin-top:0}.list-group-horizontal-sm>.list-group-item+.list-group-item{border-top-width:var(--bs-list-group-border-width);border-left-width:0}.list-group-horizontal-sm>.list-group-item+.list-group-item.active{margin-left:calc(-1 * var(--bs-list-group-border-width));border-left-width:var(--bs-list-group-border-width)}}@media (min-width:768px){.list-group-horizontal-md{flex-direction:row}.list-group-horizontal-md>.list-group-item:first-child:not(:last-child){border-bottom-left-radius:var(--bs-list-group-border-radius);border-top-right-radius:0}.list-group-horizontal-md>.list-group-item:last-child:not(:first-child){border-top-right-radius:var(--bs-list-group-border-radius);border-bottom-left-radius:0}.list-group-horizontal-md>.list-group-item.active{margin-top:0}.list-group-horizontal-md>.list-group-item+.list-group-item{border-top-width:var(--bs-list-group-border-width);border-left-width:0}.list-group-horizontal-md>.list-group-item+.list-group-item.active{margin-left:calc(-1 * var(--bs-list-group-border-width));border-left-width:var(--bs-list-group-border-width)}}@media (min-width:992px){.list-group-horizontal-lg{flex-direction:row}.list-group-horizontal-lg>.list-group-item:first-child:not(:last-child){border-bottom-left-radius:var(--bs-list-group-border-radius);border-top-right-radius:0}.list-group-horizontal-lg>.list-group-item:last-child:not(:first-child){border-top-right-radius:var(--bs-list-group-border-radius);border-bottom-left-radius:0}.list-group-horizontal-lg>.list-group-item.active{margin-top:0}.list-group-horizontal-lg>.list-group-item+.list-group-item{border-top-width:var(--bs-list-group-border-width);border-left-width:0}.list-group-horizontal-lg>.list-group-item+.list-group-item.active{margin-left:calc(-1 * var(--bs-list-group-border-width));border-left-width:var(--bs-list-group-border-width)}}@media (min-width:1200px){.list-group-horizontal-xl{flex-direction:row}.list-group-horizontal-xl>.list-group-item:first-child:not(:last-child){border-bottom-left-radius:var(--bs-list-group-border-radius);border-top-right-radius:0}.list-group-horizontal-xl>.list-group-item:last-child:not(:first-child){border-top-right-radius:var(--bs-list-group-border-radius);border-bottom-left-radius:0}.list-group-horizontal-xl>.list-group-item.active{margin-top:0}.list-group-horizontal-xl>.list-group-item+.list-group-item{border-top-width:var(--bs-list-group-border-width);border-left-width:0}.list-group-horizontal-xl>.list-group-item+.list-group-item.active{margin-left:calc(-1 * var(--bs-list-group-border-width));border-left-width:var(--bs-list-group-border-width)}}@media (min-width:1400px){.list-group-horizontal-xxl{flex-direction:row}.list-group-horizontal-xxl>.list-group-item:first-child:not(:last-child){border-bottom-left-radius:var(--bs-list-group-border-radius);border-top-right-radius:0}.list-group-horizontal-xxl>.list-group-item:last-child:not(:first-child){border-top-right-radius:var(--bs-list-group-border-radius);border-bottom-left-radius:0}.list-group-horizontal-xxl>.list-group-item.active{margin-top:0}.list-group-horizontal-xxl>.list-group-item+.list-group-item{border-top-width:var(--bs-list-group-border-width);border-left-width:0}.list-group-horizontal-xxl>.list-group-item+.list-group-item.active{margin-left:calc(-1 * var(--bs-list-group-border-width));border-left-width:var(--bs-list-group-border-width)}}.list-group-flush{border-radius:0}.list-group-flush>.list-group-item{border-width:0 0 var(--bs-list-group-border-width)}.list-group-flush>.list-group-item:last-child{border-bottom-width:0}.list-group-item-primary{--bs-list-group-color:var(--bs-primary-text-emphasis);--bs-list-group-bg:var(--bs-primary-bg-subtle);--bs-list-group-border-color:var(--bs-primary-border-subtle);--bs-list-group-action-hover-color:var(--bs-emphasis-color);--bs-list-group-action-hover-bg:var(--bs-primary-border-subtle);--bs-list-group-action-active-color:var(--bs-emphasis-color);--bs-list-group-action-active-bg:var(--bs-primary-border-subtle);--bs-list-group-active-color:var(--bs-primary-bg-subtle);--bs-list-group-active-bg:var(--bs-primary-text-emphasis);--bs-list-group-active-border-color:var(--bs-primary-text-emphasis)}.list-group-item-secondary{--bs-list-group-color:var(--bs-secondary-text-emphasis);--bs-list-group-bg:var(--bs-secondary-bg-subtle);--bs-list-group-border-color:var(--bs-secondary-border-subtle);--bs-list-group-action-hover-color:var(--bs-emphasis-color);--bs-list-group-action-hover-bg:var(--bs-secondary-border-subtle);--bs-list-group-action-active-color:var(--bs-emphasis-color);--bs-list-group-action-active-bg:var(--bs-secondary-border-subtle);--bs-list-group-active-color:var(--bs-secondary-bg-subtle);--bs-list-group-active-bg:var(--bs-secondary-text-emphasis);--bs-list-group-active-border-color:var(--bs-secondary-text-emphasis)}.list-group-item-success{--bs-list-group-color:var(--bs-success-text-emphasis);--bs-list-group-bg:var(--bs-success-bg-subtle);--bs-list-group-border-color:var(--bs-success-border-subtle);--bs-list-group-action-hover-color:var(--bs-emphasis-color);--bs-list-group-action-hover-bg:var(--bs-success-border-subtle);--bs-list-group-action-active-color:var(--bs-emphasis-color);--bs-list-group-action-active-bg:var(--bs-success-border-subtle);--bs-list-group-active-color:var(--bs-success-bg-subtle);--bs-list-group-active-bg:var(--bs-success-text-emphasis);--bs-list-group-active-border-color:var(--bs-success-text-emphasis)}.list-group-item-info{--bs-list-group-color:var(--bs-info-text-emphasis);--bs-list-group-bg:var(--bs-info-bg-subtle);--bs-list-group-border-color:var(--bs-info-border-subtle);--bs-list-group-action-hover-color:var(--bs-emphasis-color);--bs-list-group-action-hover-bg:var(--bs-info-border-subtle);--bs-list-group-action-active-color:var(--bs-emphasis-color);--bs-list-group-action-active-bg:var(--bs-info-border-subtle);--bs-list-group-active-color:var(--bs-info-bg-subtle);--bs-list-group-active-bg:var(--bs-info-text-emphasis);--bs-list-group-active-border-color:var(--bs-info-text-emphasis)}.list-group-item-warning{--bs-list-group-color:var(--bs-warning-text-emphasis);--bs-list-group-bg:var(--bs-warning-bg-subtle);--bs-list-group-border-color:var(--bs-warning-border-subtle);--bs-list-group-action-hover-color:var(--bs-emphasis-color);--bs-list-group-action-hover-bg:var(--bs-warning-border-subtle);--bs-list-group-action-active-color:var(--bs-emphasis-color);--bs-list-group-action-active-bg:var(--bs-warning-border-subtle);--bs-list-group-active-color:var(--bs-warning-bg-subtle);--bs-list-group-active-bg:var(--bs-warning-text-emphasis);--bs-list-group-active-border-color:var(--bs-warning-text-emphasis)}.list-group-item-danger{--bs-list-group-color:var(--bs-danger-text-emphasis);--bs-list-group-bg:var(--bs-danger-bg-subtle);--bs-list-group-border-color:var(--bs-danger-border-subtle);--bs-list-group-action-hover-color:var(--bs-emphasis-color);--bs-list-group-action-hover-bg:var(--bs-danger-border-subtle);--bs-list-group-action-active-color:var(--bs-emphasis-color);--bs-list-group-action-active-bg:var(--bs-danger-border-subtle);--bs-list-group-active-color:var(--bs-danger-bg-subtle);--bs-list-group-active-bg:var(--bs-danger-text-emphasis);--bs-list-group-active-border-color:var(--bs-danger-text-emphasis)}.list-group-item-light{--bs-list-group-color:var(--bs-light-text-emphasis);--bs-list-group-bg:var(--bs-light-bg-subtle);--bs-list-group-border-color:var(--bs-light-border-subtle);--bs-list-group-action-hover-color:var(--bs-emphasis-color);--bs-list-group-action-hover-bg:var(--bs-light-border-subtle);--bs-list-group-action-active-color:var(--bs-emphasis-color);--bs-list-group-action-active-bg:var(--bs-light-border-subtle);--bs-list-group-active-color:var(--bs-light-bg-subtle);--bs-list-group-active-bg:var(--bs-light-text-emphasis);--bs-list-group-active-border-color:var(--bs-light-text-emphasis)}.list-group-item-dark{--bs-list-group-color:var(--bs-dark-text-emphasis);--bs-list-group-bg:var(--bs-dark-bg-subtle);--bs-list-group-border-color:var(--bs-dark-border-subtle);--bs-list-group-action-hover-color:var(--bs-emphasis-color);--bs-list-group-action-hover-bg:var(--bs-dark-border-subtle);--bs-list-group-action-active-color:var(--bs-emphasis-color);--bs-list-group-action-active-bg:var(--bs-dark-border-subtle);--bs-list-group-active-color:var(--bs-dark-bg-subtle);--bs-list-group-active-bg:var(--bs-dark-text-emphasis);--bs-list-group-active-border-color:var(--bs-dark-text-emphasis)}.btn-close{--bs-btn-close-color:#000;--bs-btn-close-bg:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23000'%3e%3cpath d='M.293.293a1 1 0 0 1 1.414 0L8 6.586 14.293.293a1 1 0 1 1 1.414 1.414L9.414 8l6.293 6.293a1 1 0 0 1-1.414 1.414L8 9.414l-6.293 6.293a1 1 0 0 1-1.414-1.414L6.586 8 .293 1.707a1 1 0 0 1 0-1.414'/%3e%3c/svg%3e");--bs-btn-close-opacity:0.5;--bs-btn-close-hover-opacity:0.75;--bs-btn-close-focus-shadow:0 0 0 0.25rem rgba(13, 110, 253, 0.25);--bs-btn-close-focus-opacity:1;--bs-btn-close-disabled-opacity:0.25;box-sizing:content-box;width:1em;height:1em;padding:.25em .25em;color:var(--bs-btn-close-color);background:transparent var(--bs-btn-close-bg) center/1em auto no-repeat;filter:var(--bs-btn-close-filter);border:0;border-radius:.375rem;opacity:var(--bs-btn-close-opacity)}.btn-close:hover{color:var(--bs-btn-close-color);text-decoration:none;opacity:var(--bs-btn-close-hover-opacity)}.btn-close:focus{outline:0;box-shadow:var(--bs-btn-close-focus-shadow);opacity:var(--bs-btn-close-focus-opacity)}.btn-close.disabled,.btn-close:disabled{pointer-events:none;-webkit-user-select:none;-moz-user-select:none;user-select:none;opacity:var(--bs-btn-close-disabled-opacity)}.btn-close-white{--bs-btn-close-filter:invert(1) grayscale(100%) brightness(200%)}:root,[data-bs-theme=light]{--bs-btn-close-filter: }[data-bs-theme=dark]{--bs-btn-close-filter:invert(1) grayscale(100%) brightness(200%)}.toast{--bs-toast-zindex:1090;--bs-toast-padding-x:0.75rem;--bs-toast-padding-y:0.5rem;--bs-toast-spacing:1.5rem;--bs-toast-max-width:350px;--bs-toast-font-size:0.875rem;--bs-toast-color: ;--bs-toast-bg:rgba(var(--bs-body-bg-rgb), 0.85);--bs-toast-border-width:var(--bs-border-width);--bs-toast-border-color:var(--bs-border-color-translucent);--bs-toast-border-radius:var(--bs-border-radius);--bs-toast-box-shadow:var(--bs-box-shadow);--bs-toast-header-color:var(--bs-secondary-color);--bs-toast-header-bg:rgba(var(--bs-body-bg-rgb), 0.85);--bs-toast-header-border-color:var(--bs-border-color-translucent);width:var(--bs-toast-max-width);max-width:100%;font-size:var(--bs-toast-font-size);color:var(--bs-toast-color);pointer-events:auto;background-color:var(--bs-toast-bg);background-clip:padding-box;border:var(--bs-toast-border-width) solid var(--bs-toast-border-color);box-shadow:var(--bs-toast-box-shadow);border-radius:var(--bs-toast-border-radius)}.toast.showing{opacity:0}.toast:not(.show){display:none}.toast-container{--bs-toast-zindex:1090;position:absolute;z-index:var(--bs-toast-zindex);width:-webkit-max-content;width:-moz-max-content;width:max-content;max-width:100%;pointer-events:none}.toast-container>:not(:last-child){margin-bottom:var(--bs-toast-spacing)}.toast-header{display:flex;align-items:center;padding:var(--bs-toast-padding-y) var(--bs-toast-padding-x);color:var(--bs-toast-header-color);background-color:var(--bs-toast-header-bg);background-clip:padding-box;border-bottom:var(--bs-toast-border-width) solid var(--bs-toast-header-border-color);border-top-left-radius:calc(var(--bs-toast-border-radius) - var(--bs-toast-border-width));border-top-right-radius:calc(var(--bs-toast-border-radius) - var(--bs-toast-border-width))}.toast-header .btn-close{margin-right:calc(-.5 * var(--bs-toast-padding-x));margin-left:var(--bs-toast-padding-x)}.toast-body{padding:var(--bs-toast-padding-x);word-wrap:break-word}.modal{--bs-modal-zindex:1055;--bs-modal-width:500px;--bs-modal-padding:1rem;--bs-modal-margin:0.5rem;--bs-modal-color:var(--bs-body-color);--bs-modal-bg:var(--bs-body-bg);--bs-modal-border-color:var(--bs-border-color-translucent);--bs-modal-border-width:var(--bs-border-width);--bs-modal-border-radius:var(--bs-border-radius-lg);--bs-modal-box-shadow:var(--bs-box-shadow-sm);--bs-modal-inner-border-radius:calc(var(--bs-border-radius-lg) - (var(--bs-border-width)));--bs-modal-header-padding-x:1rem;--bs-modal-header-padding-y:1rem;--bs-modal-header-padding:1rem 1rem;--bs-modal-header-border-color:var(--bs-border-color);--bs-modal-header-border-width:var(--bs-border-width);--bs-modal-title-line-height:1.5;--bs-modal-footer-gap:0.5rem;--bs-modal-footer-bg: ;--bs-modal-footer-border-color:var(--bs-border-color);--bs-modal-footer-border-width:var(--bs-border-width);position:fixed;top:0;left:0;z-index:var(--bs-modal-zindex);display:none;width:100%;height:100%;overflow-x:hidden;overflow-y:auto;outline:0}.modal-dialog{position:relative;width:auto;margin:var(--bs-modal-margin);pointer-events:none}.modal.fade .modal-dialog{transform:translate(0,-50px);transition:transform .3s ease-out}@media (prefers-reduced-motion:reduce){.modal.fade .modal-dialog{transition:none}}.modal.show .modal-dialog{transform:none}.modal.modal-static .modal-dialog{transform:scale(1.02)}.modal-dialog-scrollable{height:calc(100% - var(--bs-modal-margin) * 2)}.modal-dialog-scrollable .modal-content{max-height:100%;overflow:hidden}.modal-dialog-scrollable .modal-body{overflow-y:auto}.modal-dialog-centered{display:flex;align-items:center;min-height:calc(100% - var(--bs-modal-margin) * 2)}.modal-content{position:relative;display:flex;flex-direction:column;width:100%;color:var(--bs-modal-color);pointer-events:auto;background-color:var(--bs-modal-bg);background-clip:padding-box;border:var(--bs-modal-border-width) solid var(--bs-modal-border-color);border-radius:var(--bs-modal-border-radius);outline:0}.modal-backdrop{--bs-backdrop-zindex:1050;--bs-backdrop-bg:#000;--bs-backdrop-opacity:0.5;position:fixed;top:0;left:0;z-index:var(--bs-backdrop-zindex);width:100vw;height:100vh;background-color:var(--bs-backdrop-bg)}.modal-backdrop.fade{opacity:0}.modal-backdrop.show{opacity:var(--bs-backdrop-opacity)}.modal-header{display:flex;flex-shrink:0;align-items:center;padding:var(--bs-modal-header-padding);border-bottom:var(--bs-modal-header-border-width) solid var(--bs-modal-header-border-color);border-top-left-radius:var(--bs-modal-inner-border-radius);border-top-right-radius:var(--bs-modal-inner-border-radius)}.modal-header .btn-close{padding:calc(var(--bs-modal-header-padding-y) * .5) calc(var(--bs-modal-header-padding-x) * .5);margin-top:calc(-.5 * var(--bs-modal-header-padding-y));margin-right:calc(-.5 * var(--bs-modal-header-padding-x));margin-bottom:calc(-.5 * var(--bs-modal-header-padding-y));margin-left:auto}.modal-title{margin-bottom:0;line-height:var(--bs-modal-title-line-height)}.modal-body{position:relative;flex:1 1 auto;padding:var(--bs-modal-padding)}.modal-footer{display:flex;flex-shrink:0;flex-wrap:wrap;align-items:center;justify-content:flex-end;padding:calc(var(--bs-modal-padding) - var(--bs-modal-footer-gap) * .5);background-color:var(--bs-modal-footer-bg);border-top:var(--bs-modal-footer-border-width) solid var(--bs-modal-footer-border-color);border-bottom-right-radius:var(--bs-modal-inner-border-radius);border-bottom-left-radius:var(--bs-modal-inner-border-radius)}.modal-footer>*{margin:calc(var(--bs-modal-footer-gap) * .5)}@media (min-width:576px){.modal{--bs-modal-margin:1.75rem;--bs-modal-box-shadow:var(--bs-box-shadow)}.modal-dialog{max-width:var(--bs-modal-width);margin-right:auto;margin-left:auto}.modal-sm{--bs-modal-width:300px}}@media (min-width:992px){.modal-lg,.modal-xl{--bs-modal-width:800px}}@media (min-width:1200px){.modal-xl{--bs-modal-width:1140px}}.modal-fullscreen{width:100vw;max-width:none;height:100%;margin:0}.modal-fullscreen .modal-content{height:100%;border:0;border-radius:0}.modal-fullscreen .modal-footer,.modal-fullscreen .modal-header{border-radius:0}.modal-fullscreen .modal-body{overflow-y:auto}@media (max-width:575.98px){.modal-fullscreen-sm-down{width:100vw;max-width:none;height:100%;margin:0}.modal-fullscreen-sm-down .modal-content{height:100%;border:0;border-radius:0}.modal-fullscreen-sm-down .modal-footer,.modal-fullscreen-sm-down .modal-header{border-radius:0}.modal-fullscreen-sm-down .modal-body{overflow-y:auto}}@media (max-width:767.98px){.modal-fullscreen-md-down{width:100vw;max-width:none;height:100%;margin:0}.modal-fullscreen-md-down .modal-content{height:100%;border:0;border-radius:0}.modal-fullscreen-md-down .modal-footer,.modal-fullscreen-md-down .modal-header{border-radius:0}.modal-fullscreen-md-down .modal-body{overflow-y:auto}}@media (max-width:991.98px){.modal-fullscreen-lg-down{width:100vw;max-width:none;height:100%;margin:0}.modal-fullscreen-lg-down .modal-content{height:100%;border:0;border-radius:0}.modal-fullscreen-lg-down .modal-footer,.modal-fullscreen-lg-down .modal-header{border-radius:0}.modal-fullscreen-lg-down .modal-body{overflow-y:auto}}@media (max-width:1199.98px){.modal-fullscreen-xl-down{width:100vw;max-width:none;height:100%;margin:0}.modal-fullscreen-xl-down .modal-content{height:100%;border:0;border-radius:0}.modal-fullscreen-xl-down .modal-footer,.modal-fullscreen-xl-down .modal-header{border-radius:0}.modal-fullscreen-xl-down .modal-body{overflow-y:auto}}@media (max-width:1399.98px){.modal-fullscreen-xxl-down{width:100vw;max-width:none;height:100%;margin:0}.modal-fullscreen-xxl-down .modal-content{height:100%;border:0;border-radius:0}.modal-fullscreen-xxl-down .modal-footer,.modal-fullscreen-xxl-down .modal-header{border-radius:0}.modal-fullscreen-xxl-down .modal-body{overflow-y:auto}}.tooltip{--bs-tooltip-zindex:1080;--bs-tooltip-max-width:200px;--bs-tooltip-padding-x:0.5rem;--bs-tooltip-padding-y:0.25rem;--bs-tooltip-margin: ;--bs-tooltip-font-size:0.875rem;--bs-tooltip-color:var(--bs-body-bg);--bs-tooltip-bg:var(--bs-emphasis-color);--bs-tooltip-border-radius:var(--bs-border-radius);--bs-tooltip-opacity:0.9;--bs-tooltip-arrow-width:0.8rem;--bs-tooltip-arrow-height:0.4rem;z-index:var(--bs-tooltip-zindex);display:block;margin:var(--bs-tooltip-margin);font-family:var(--bs-font-sans-serif);font-style:normal;font-weight:400;line-height:1.5;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;white-space:normal;word-spacing:normal;line-break:auto;font-size:var(--bs-tooltip-font-size);word-wrap:break-word;opacity:0}.tooltip.show{opacity:var(--bs-tooltip-opacity)}.tooltip .tooltip-arrow{display:block;width:var(--bs-tooltip-arrow-width);height:var(--bs-tooltip-arrow-height)}.tooltip .tooltip-arrow::before{position:absolute;content:"";border-color:transparent;border-style:solid}.bs-tooltip-auto[data-popper-placement^=top] .tooltip-arrow,.bs-tooltip-top .tooltip-arrow{bottom:calc(-1 * var(--bs-tooltip-arrow-height))}.bs-tooltip-auto[data-popper-placement^=top] .tooltip-arrow::before,.bs-tooltip-top .tooltip-arrow::before{top:-1px;border-width:var(--bs-tooltip-arrow-height) calc(var(--bs-tooltip-arrow-width) * .5) 0;border-top-color:var(--bs-tooltip-bg)}.bs-tooltip-auto[data-popper-placement^=right] .tooltip-arrow,.bs-tooltip-end .tooltip-arrow{left:calc(-1 * var(--bs-tooltip-arrow-height));width:var(--bs-tooltip-arrow-height);height:var(--bs-tooltip-arrow-width)}.bs-tooltip-auto[data-popper-placement^=right] .tooltip-arrow::before,.bs-tooltip-end .tooltip-arrow::before{right:-1px;border-width:calc(var(--bs-tooltip-arrow-width) * .5) var(--bs-tooltip-arrow-height) calc(var(--bs-tooltip-arrow-width) * .5) 0;border-right-color:var(--bs-tooltip-bg)}.bs-tooltip-auto[data-popper-placement^=bottom] .tooltip-arrow,.bs-tooltip-bottom .tooltip-arrow{top:calc(-1 * var(--bs-tooltip-arrow-height))}.bs-tooltip-auto[data-popper-placement^=bottom] .tooltip-arrow::before,.bs-tooltip-bottom .tooltip-arrow::before{bottom:-1px;border-width:0 calc(var(--bs-tooltip-arrow-width) * .5) var(--bs-tooltip-arrow-height);border-bottom-color:var(--bs-tooltip-bg)}.bs-tooltip-auto[data-popper-placement^=left] .tooltip-arrow,.bs-tooltip-start .tooltip-arrow{right:calc(-1 * var(--bs-tooltip-arrow-height));width:var(--bs-tooltip-arrow-height);height:var(--bs-tooltip-arrow-width)}.bs-tooltip-auto[data-popper-placement^=left] .tooltip-arrow::before,.bs-tooltip-start .tooltip-arrow::before{left:-1px;border-width:calc(var(--bs-tooltip-arrow-width) * .5) 0 calc(var(--bs-tooltip-arrow-width) * .5) var(--bs-tooltip-arrow-height);border-left-color:var(--bs-tooltip-bg)}.tooltip-inner{max-width:var(--bs-tooltip-max-width);padding:var(--bs-tooltip-padding-y) var(--bs-tooltip-padding-x);color:var(--bs-tooltip-color);text-align:center;background-color:var(--bs-tooltip-bg);border-radius:var(--bs-tooltip-border-radius)}.popover{--bs-popover-zindex:1070;--bs-popover-max-width:276px;--bs-popover-font-size:0.875rem;--bs-popover-bg:var(--bs-body-bg);--bs-popover-border-width:var(--bs-border-width);--bs-popover-border-color:var(--bs-border-color-translucent);--bs-popover-border-radius:var(--bs-border-radius-lg);--bs-popover-inner-border-radius:calc(var(--bs-border-radius-lg) - var(--bs-border-width));--bs-popover-box-shadow:var(--bs-box-shadow);--bs-popover-header-padding-x:1rem;--bs-popover-header-padding-y:0.5rem;--bs-popover-header-font-size:1rem;--bs-popover-header-color:inherit;--bs-popover-header-bg:var(--bs-secondary-bg);--bs-popover-body-padding-x:1rem;--bs-popover-body-padding-y:1rem;--bs-popover-body-color:var(--bs-body-color);--bs-popover-arrow-width:1rem;--bs-popover-arrow-height:0.5rem;--bs-popover-arrow-border:var(--bs-popover-border-color);z-index:var(--bs-popover-zindex);display:block;max-width:var(--bs-popover-max-width);font-family:var(--bs-font-sans-serif);font-style:normal;font-weight:400;line-height:1.5;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;white-space:normal;word-spacing:normal;line-break:auto;font-size:var(--bs-popover-font-size);word-wrap:break-word;background-color:var(--bs-popover-bg);background-clip:padding-box;border:var(--bs-popover-border-width) solid var(--bs-popover-border-color);border-radius:var(--bs-popover-border-radius)}.popover .popover-arrow{display:block;width:var(--bs-popover-arrow-width);height:var(--bs-popover-arrow-height)}.popover .popover-arrow::after,.popover .popover-arrow::before{position:absolute;display:block;content:"";border-color:transparent;border-style:solid;border-width:0}.bs-popover-auto[data-popper-placement^=top]>.popover-arrow,.bs-popover-top>.popover-arrow{bottom:calc(-1 * (var(--bs-popover-arrow-height)) - var(--bs-popover-border-width))}.bs-popover-auto[data-popper-placement^=top]>.popover-arrow::after,.bs-popover-auto[data-popper-placement^=top]>.popover-arrow::before,.bs-popover-top>.popover-arrow::after,.bs-popover-top>.popover-arrow::before{border-width:var(--bs-popover-arrow-height) calc(var(--bs-popover-arrow-width) * .5) 0}.bs-popover-auto[data-popper-placement^=top]>.popover-arrow::before,.bs-popover-top>.popover-arrow::before{bottom:0;border-top-color:var(--bs-popover-arrow-border)}.bs-popover-auto[data-popper-placement^=top]>.popover-arrow::after,.bs-popover-top>.popover-arrow::after{bottom:var(--bs-popover-border-width);border-top-color:var(--bs-popover-bg)}.bs-popover-auto[data-popper-placement^=right]>.popover-arrow,.bs-popover-end>.popover-arrow{left:calc(-1 * (var(--bs-popover-arrow-height)) - var(--bs-popover-border-width));width:var(--bs-popover-arrow-height);height:var(--bs-popover-arrow-width)}.bs-popover-auto[data-popper-placement^=right]>.popover-arrow::after,.bs-popover-auto[data-popper-placement^=right]>.popover-arrow::before,.bs-popover-end>.popover-arrow::after,.bs-popover-end>.popover-arrow::before{border-width:calc(var(--bs-popover-arrow-width) * .5) var(--bs-popover-arrow-height) calc(var(--bs-popover-arrow-width) * .5) 0}.bs-popover-auto[data-popper-placement^=right]>.popover-arrow::before,.bs-popover-end>.popover-arrow::before{left:0;border-right-color:var(--bs-popover-arrow-border)}.bs-popover-auto[data-popper-placement^=right]>.popover-arrow::after,.bs-popover-end>.popover-arrow::after{left:var(--bs-popover-border-width);border-right-color:var(--bs-popover-bg)}.bs-popover-auto[data-popper-placement^=bottom]>.popover-arrow,.bs-popover-bottom>.popover-arrow{top:calc(-1 * (var(--bs-popover-arrow-height)) - var(--bs-popover-border-width))}.bs-popover-auto[data-popper-placement^=bottom]>.popover-arrow::after,.bs-popover-auto[data-popper-placement^=bottom]>.popover-arrow::before,.bs-popover-bottom>.popover-arrow::after,.bs-popover-bottom>.popover-arrow::before{border-width:0 calc(var(--bs-popover-arrow-width) * .5) var(--bs-popover-arrow-height)}.bs-popover-auto[data-popper-placement^=bottom]>.popover-arrow::before,.bs-popover-bottom>.popover-arrow::before{top:0;border-bottom-color:var(--bs-popover-arrow-border)}.bs-popover-auto[data-popper-placement^=bottom]>.popover-arrow::after,.bs-popover-bottom>.popover-arrow::after{top:var(--bs-popover-border-width);border-bottom-color:var(--bs-popover-bg)}.bs-popover-auto[data-popper-placement^=bottom] .popover-header::before,.bs-popover-bottom .popover-header::before{position:absolute;top:0;left:50%;display:block;width:var(--bs-popover-arrow-width);margin-left:calc(-.5 * var(--bs-popover-arrow-width));content:"";border-bottom:var(--bs-popover-border-width) solid var(--bs-popover-header-bg)}.bs-popover-auto[data-popper-placement^=left]>.popover-arrow,.bs-popover-start>.popover-arrow{right:calc(-1 * (var(--bs-popover-arrow-height)) - var(--bs-popover-border-width));width:var(--bs-popover-arrow-height);height:var(--bs-popover-arrow-width)}.bs-popover-auto[data-popper-placement^=left]>.popover-arrow::after,.bs-popover-auto[data-popper-placement^=left]>.popover-arrow::before,.bs-popover-start>.popover-arrow::after,.bs-popover-start>.popover-arrow::before{border-width:calc(var(--bs-popover-arrow-width) * .5) 0 calc(var(--bs-popover-arrow-width) * .5) var(--bs-popover-arrow-height)}.bs-popover-auto[data-popper-placement^=left]>.popover-arrow::before,.bs-popover-start>.popover-arrow::before{right:0;border-left-color:var(--bs-popover-arrow-border)}.bs-popover-auto[data-popper-placement^=left]>.popover-arrow::after,.bs-popover-start>.popover-arrow::after{right:var(--bs-popover-border-width);border-left-color:var(--bs-popover-bg)}.popover-header{padding:var(--bs-popover-header-padding-y) var(--bs-popover-header-padding-x);margin-bottom:0;font-size:var(--bs-popover-header-font-size);color:var(--bs-popover-header-color);background-color:var(--bs-popover-header-bg);border-bottom:var(--bs-popover-border-width) solid var(--bs-popover-border-color);border-top-left-radius:var(--bs-popover-inner-border-radius);border-top-right-radius:var(--bs-popover-inner-border-radius)}.popover-header:empty{display:none}.popover-body{padding:var(--bs-popover-body-padding-y) var(--bs-popover-body-padding-x);color:var(--bs-popover-body-color)}.carousel{position:relative}.carousel.pointer-event{touch-action:pan-y}.carousel-inner{position:relative;width:100%;overflow:hidden}.carousel-inner::after{display:block;clear:both;content:""}.carousel-item{position:relative;display:none;float:left;width:100%;margin-right:-100%;-webkit-backface-visibility:hidden;backface-visibility:hidden;transition:transform .6s ease-in-out}@media (prefers-reduced-motion:reduce){.carousel-item{transition:none}}.carousel-item-next,.carousel-item-prev,.carousel-item.active{display:block}.active.carousel-item-end,.carousel-item-next:not(.carousel-item-start){transform:translateX(100%)}.active.carousel-item-start,.carousel-item-prev:not(.carousel-item-end){transform:translateX(-100%)}.carousel-fade .carousel-item{opacity:0;transition-property:opacity;transform:none}.carousel-fade .carousel-item-next.carousel-item-start,.carousel-fade .carousel-item-prev.carousel-item-end,.carousel-fade .carousel-item.active{z-index:1;opacity:1}.carousel-fade .active.carousel-item-end,.carousel-fade .active.carousel-item-start{z-index:0;opacity:0;transition:opacity 0s .6s}@media (prefers-reduced-motion:reduce){.carousel-fade .active.carousel-item-end,.carousel-fade .active.carousel-item-start{transition:none}}.carousel-control-next,.carousel-control-prev{position:absolute;top:0;bottom:0;z-index:1;display:flex;align-items:center;justify-content:center;width:15%;padding:0;color:#fff;text-align:center;background:0 0;filter:var(--bs-carousel-control-icon-filter);border:0;opacity:.5;transition:opacity .15s ease}@media (prefers-reduced-motion:reduce){.carousel-control-next,.carousel-control-prev{transition:none}}.carousel-control-next:focus,.carousel-control-next:hover,.carousel-control-prev:focus,.carousel-control-prev:hover{color:#fff;text-decoration:none;outline:0;opacity:.9}.carousel-control-prev{left:0}.carousel-control-next{right:0}.carousel-control-next-icon,.carousel-control-prev-icon{display:inline-block;width:2rem;height:2rem;background-repeat:no-repeat;background-position:50%;background-size:100% 100%}.carousel-control-prev-icon{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23fff'%3e%3cpath d='M11.354 1.646a.5.5 0 0 1 0 .708L5.707 8l5.647 5.646a.5.5 0 0 1-.708.708l-6-6a.5.5 0 0 1 0-.708l6-6a.5.5 0 0 1 .708 0'/%3e%3c/svg%3e")}.carousel-control-next-icon{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23fff'%3e%3cpath d='M4.646 1.646a.5.5 0 0 1 .708 0l6 6a.5.5 0 0 1 0 .708l-6 6a.5.5 0 0 1-.708-.708L10.293 8 4.646 2.354a.5.5 0 0 1 0-.708'/%3e%3c/svg%3e")}.carousel-indicators{position:absolute;right:0;bottom:0;left:0;z-index:2;display:flex;justify-content:center;padding:0;margin-right:15%;margin-bottom:1rem;margin-left:15%}.carousel-indicators [data-bs-target]{box-sizing:content-box;flex:0 1 auto;width:30px;height:3px;padding:0;margin-right:3px;margin-left:3px;text-indent:-999px;cursor:pointer;background-color:var(--bs-carousel-indicator-active-bg);background-clip:padding-box;border:0;border-top:10px solid transparent;border-bottom:10px solid transparent;opacity:.5;transition:opacity .6s ease}@media (prefers-reduced-motion:reduce){.carousel-indicators [data-bs-target]{transition:none}}.carousel-indicators .active{opacity:1}.carousel-caption{position:absolute;right:15%;bottom:1.25rem;left:15%;padding-top:1.25rem;padding-bottom:1.25rem;color:var(--bs-carousel-caption-color);text-align:center}.carousel-dark{--bs-carousel-indicator-active-bg:#000;--bs-carousel-caption-color:#000;--bs-carousel-control-icon-filter:invert(1) grayscale(100)}:root,[data-bs-theme=light]{--bs-carousel-indicator-active-bg:#fff;--bs-carousel-caption-color:#fff;--bs-carousel-control-icon-filter: }[data-bs-theme=dark]{--bs-carousel-indicator-active-bg:#000;--bs-carousel-caption-color:#000;--bs-carousel-control-icon-filter:invert(1) grayscale(100)}.spinner-border,.spinner-grow{display:inline-block;width:var(--bs-spinner-width);height:var(--bs-spinner-height);vertical-align:var(--bs-spinner-vertical-align);border-radius:50%;animation:var(--bs-spinner-animation-speed) linear infinite var(--bs-spinner-animation-name)}@keyframes spinner-border{to{transform:rotate(360deg)}}.spinner-border{--bs-spinner-width:2rem;--bs-spinner-height:2rem;--bs-spinner-vertical-align:-0.125em;--bs-spinner-border-width:0.25em;--bs-spinner-animation-speed:0.75s;--bs-spinner-animation-name:spinner-border;border:var(--bs-spinner-border-width) solid currentcolor;border-right-color:transparent}.spinner-border-sm{--bs-spinner-width:1rem;--bs-spinner-height:1rem;--bs-spinner-border-width:0.2em}@keyframes spinner-grow{0%{transform:scale(0)}50%{opacity:1;transform:none}}.spinner-grow{--bs-spinner-width:2rem;--bs-spinner-height:2rem;--bs-spinner-vertical-align:-0.125em;--bs-spinner-animation-speed:0.75s;--bs-spinner-animation-name:spinner-grow;background-color:currentcolor;opacity:0}.spinner-grow-sm{--bs-spinner-width:1rem;--bs-spinner-height:1rem}@media (prefers-reduced-motion:reduce){.spinner-border,.spinner-grow{--bs-spinner-animation-speed:1.5s}}.offcanvas,.offcanvas-lg,.offcanvas-md,.offcanvas-sm,.offcanvas-xl,.offcanvas-xxl{--bs-offcanvas-zindex:1045;--bs-offcanvas-width:400px;--bs-offcanvas-height:30vh;--bs-offcanvas-padding-x:1rem;--bs-offcanvas-padding-y:1rem;--bs-offcanvas-color:var(--bs-body-color);--bs-offcanvas-bg:var(--bs-body-bg);--bs-offcanvas-border-width:var(--bs-border-width);--bs-offcanvas-border-color:var(--bs-border-color-translucent);--bs-offcanvas-box-shadow:var(--bs-box-shadow-sm);--bs-offcanvas-transition:transform 0.3s ease-in-out;--bs-offcanvas-title-line-height:1.5}@media (max-width:575.98px){.offcanvas-sm{position:fixed;bottom:0;z-index:var(--bs-offcanvas-zindex);display:flex;flex-direction:column;max-width:100%;color:var(--bs-offcanvas-color);visibility:hidden;background-color:var(--bs-offcanvas-bg);background-clip:padding-box;outline:0;transition:var(--bs-offcanvas-transition)}}@media (max-width:575.98px) and (prefers-reduced-motion:reduce){.offcanvas-sm{transition:none}}@media (max-width:575.98px){.offcanvas-sm.offcanvas-start{top:0;left:0;width:var(--bs-offcanvas-width);border-right:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateX(-100%)}.offcanvas-sm.offcanvas-end{top:0;right:0;width:var(--bs-offcanvas-width);border-left:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateX(100%)}.offcanvas-sm.offcanvas-top{top:0;right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-bottom:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(-100%)}.offcanvas-sm.offcanvas-bottom{right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-top:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(100%)}.offcanvas-sm.show:not(.hiding),.offcanvas-sm.showing{transform:none}.offcanvas-sm.hiding,.offcanvas-sm.show,.offcanvas-sm.showing{visibility:visible}}@media (min-width:576px){.offcanvas-sm{--bs-offcanvas-height:auto;--bs-offcanvas-border-width:0;background-color:transparent!important}.offcanvas-sm .offcanvas-header{display:none}.offcanvas-sm .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible;background-color:transparent!important}}@media (max-width:767.98px){.offcanvas-md{position:fixed;bottom:0;z-index:var(--bs-offcanvas-zindex);display:flex;flex-direction:column;max-width:100%;color:var(--bs-offcanvas-color);visibility:hidden;background-color:var(--bs-offcanvas-bg);background-clip:padding-box;outline:0;transition:var(--bs-offcanvas-transition)}}@media (max-width:767.98px) and (prefers-reduced-motion:reduce){.offcanvas-md{transition:none}}@media (max-width:767.98px){.offcanvas-md.offcanvas-start{top:0;left:0;width:var(--bs-offcanvas-width);border-right:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateX(-100%)}.offcanvas-md.offcanvas-end{top:0;right:0;width:var(--bs-offcanvas-width);border-left:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateX(100%)}.offcanvas-md.offcanvas-top{top:0;right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-bottom:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(-100%)}.offcanvas-md.offcanvas-bottom{right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-top:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(100%)}.offcanvas-md.show:not(.hiding),.offcanvas-md.showing{transform:none}.offcanvas-md.hiding,.offcanvas-md.show,.offcanvas-md.showing{visibility:visible}}@media (min-width:768px){.offcanvas-md{--bs-offcanvas-height:auto;--bs-offcanvas-border-width:0;background-color:transparent!important}.offcanvas-md .offcanvas-header{display:none}.offcanvas-md .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible;background-color:transparent!important}}@media (max-width:991.98px){.offcanvas-lg{position:fixed;bottom:0;z-index:var(--bs-offcanvas-zindex);display:flex;flex-direction:column;max-width:100%;color:var(--bs-offcanvas-color);visibility:hidden;background-color:var(--bs-offcanvas-bg);background-clip:padding-box;outline:0;transition:var(--bs-offcanvas-transition)}}@media (max-width:991.98px) and (prefers-reduced-motion:reduce){.offcanvas-lg{transition:none}}@media (max-width:991.98px){.offcanvas-lg.offcanvas-start{top:0;left:0;width:var(--bs-offcanvas-width);border-right:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateX(-100%)}.offcanvas-lg.offcanvas-end{top:0;right:0;width:var(--bs-offcanvas-width);border-left:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateX(100%)}.offcanvas-lg.offcanvas-top{top:0;right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-bottom:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(-100%)}.offcanvas-lg.offcanvas-bottom{right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-top:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(100%)}.offcanvas-lg.show:not(.hiding),.offcanvas-lg.showing{transform:none}.offcanvas-lg.hiding,.offcanvas-lg.show,.offcanvas-lg.showing{visibility:visible}}@media (min-width:992px){.offcanvas-lg{--bs-offcanvas-height:auto;--bs-offcanvas-border-width:0;background-color:transparent!important}.offcanvas-lg .offcanvas-header{display:none}.offcanvas-lg .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible;background-color:transparent!important}}@media (max-width:1199.98px){.offcanvas-xl{position:fixed;bottom:0;z-index:var(--bs-offcanvas-zindex);display:flex;flex-direction:column;max-width:100%;color:var(--bs-offcanvas-color);visibility:hidden;background-color:var(--bs-offcanvas-bg);background-clip:padding-box;outline:0;transition:var(--bs-offcanvas-transition)}}@media (max-width:1199.98px) and (prefers-reduced-motion:reduce){.offcanvas-xl{transition:none}}@media (max-width:1199.98px){.offcanvas-xl.offcanvas-start{top:0;left:0;width:var(--bs-offcanvas-width);border-right:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateX(-100%)}.offcanvas-xl.offcanvas-end{top:0;right:0;width:var(--bs-offcanvas-width);border-left:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateX(100%)}.offcanvas-xl.offcanvas-top{top:0;right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-bottom:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(-100%)}.offcanvas-xl.offcanvas-bottom{right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-top:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(100%)}.offcanvas-xl.show:not(.hiding),.offcanvas-xl.showing{transform:none}.offcanvas-xl.hiding,.offcanvas-xl.show,.offcanvas-xl.showing{visibility:visible}}@media (min-width:1200px){.offcanvas-xl{--bs-offcanvas-height:auto;--bs-offcanvas-border-width:0;background-color:transparent!important}.offcanvas-xl .offcanvas-header{display:none}.offcanvas-xl .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible;background-color:transparent!important}}@media (max-width:1399.98px){.offcanvas-xxl{position:fixed;bottom:0;z-index:var(--bs-offcanvas-zindex);display:flex;flex-direction:column;max-width:100%;color:var(--bs-offcanvas-color);visibility:hidden;background-color:var(--bs-offcanvas-bg);background-clip:padding-box;outline:0;transition:var(--bs-offcanvas-transition)}}@media (max-width:1399.98px) and (prefers-reduced-motion:reduce){.offcanvas-xxl{transition:none}}@media (max-width:1399.98px){.offcanvas-xxl.offcanvas-start{top:0;left:0;width:var(--bs-offcanvas-width);border-right:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateX(-100%)}.offcanvas-xxl.offcanvas-end{top:0;right:0;width:var(--bs-offcanvas-width);border-left:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateX(100%)}.offcanvas-xxl.offcanvas-top{top:0;right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-bottom:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(-100%)}.offcanvas-xxl.offcanvas-bottom{right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-top:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(100%)}.offcanvas-xxl.show:not(.hiding),.offcanvas-xxl.showing{transform:none}.offcanvas-xxl.hiding,.offcanvas-xxl.show,.offcanvas-xxl.showing{visibility:visible}}@media (min-width:1400px){.offcanvas-xxl{--bs-offcanvas-height:auto;--bs-offcanvas-border-width:0;background-color:transparent!important}.offcanvas-xxl .offcanvas-header{display:none}.offcanvas-xxl .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible;background-color:transparent!important}}.offcanvas{position:fixed;bottom:0;z-index:var(--bs-offcanvas-zindex);display:flex;flex-direction:column;max-width:100%;color:var(--bs-offcanvas-color);visibility:hidden;background-color:var(--bs-offcanvas-bg);background-clip:padding-box;outline:0;transition:var(--bs-offcanvas-transition)}@media (prefers-reduced-motion:reduce){.offcanvas{transition:none}}.offcanvas.offcanvas-start{top:0;left:0;width:var(--bs-offcanvas-width);border-right:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateX(-100%)}.offcanvas.offcanvas-end{top:0;right:0;width:var(--bs-offcanvas-width);border-left:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateX(100%)}.offcanvas.offcanvas-top{top:0;right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-bottom:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(-100%)}.offcanvas.offcanvas-bottom{right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-top:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(100%)}.offcanvas.show:not(.hiding),.offcanvas.showing{transform:none}.offcanvas.hiding,.offcanvas.show,.offcanvas.showing{visibility:visible}.offcanvas-backdrop{position:fixed;top:0;left:0;z-index:1040;width:100vw;height:100vh;background-color:#000}.offcanvas-backdrop.fade{opacity:0}.offcanvas-backdrop.show{opacity:.5}.offcanvas-header{display:flex;align-items:center;padding:var(--bs-offcanvas-padding-y) var(--bs-offcanvas-padding-x)}.offcanvas-header .btn-close{padding:calc(var(--bs-offcanvas-padding-y) * .5) calc(var(--bs-offcanvas-padding-x) * .5);margin-top:calc(-.5 * var(--bs-offcanvas-padding-y));margin-right:calc(-.5 * var(--bs-offcanvas-padding-x));margin-bottom:calc(-.5 * var(--bs-offcanvas-padding-y));margin-left:auto}.offcanvas-title{margin-bottom:0;line-height:var(--bs-offcanvas-title-line-height)}.offcanvas-body{flex-grow:1;padding:var(--bs-offcanvas-padding-y) var(--bs-offcanvas-padding-x);overflow-y:auto}.placeholder{display:inline-block;min-height:1em;vertical-align:middle;cursor:wait;background-color:currentcolor;opacity:.5}.placeholder.btn::before{display:inline-block;content:""}.placeholder-xs{min-height:.6em}.placeholder-sm{min-height:.8em}.placeholder-lg{min-height:1.2em}.placeholder-glow .placeholder{animation:placeholder-glow 2s ease-in-out infinite}@keyframes placeholder-glow{50%{opacity:.2}}.placeholder-wave{-webkit-mask-image:linear-gradient(130deg,#000 55%,rgba(0,0,0,0.8) 75%,#000 95%);mask-image:linear-gradient(130deg,#000 55%,rgba(0,0,0,0.8) 75%,#000 95%);-webkit-mask-size:200% 100%;mask-size:200% 100%;animation:placeholder-wave 2s linear infinite}@keyframes placeholder-wave{100%{-webkit-mask-position:-200% 0%;mask-position:-200% 0%}}.clearfix::after{display:block;clear:both;content:""}.text-bg-primary{color:#fff!important;background-color:RGBA(var(--bs-primary-rgb),var(--bs-bg-opacity,1))!important}.text-bg-secondary{color:#fff!important;background-color:RGBA(var(--bs-secondary-rgb),var(--bs-bg-opacity,1))!important}.text-bg-success{color:#fff!important;background-color:RGBA(var(--bs-success-rgb),var(--bs-bg-opacity,1))!important}.text-bg-info{color:#000!important;background-color:RGBA(var(--bs-info-rgb),var(--bs-bg-opacity,1))!important}.text-bg-warning{color:#000!important;background-color:RGBA(var(--bs-warning-rgb),var(--bs-bg-opacity,1))!important}.text-bg-danger{color:#fff!important;background-color:RGBA(var(--bs-danger-rgb),var(--bs-bg-opacity,1))!important}.text-bg-light{color:#000!important;background-color:RGBA(var(--bs-light-rgb),var(--bs-bg-opacity,1))!important}.text-bg-dark{color:#fff!important;background-color:RGBA(var(--bs-dark-rgb),var(--bs-bg-opacity,1))!important}.link-primary{color:RGBA(var(--bs-primary-rgb),var(--bs-link-opacity,1))!important;-webkit-text-decoration-color:RGBA(var(--bs-primary-rgb),var(--bs-link-underline-opacity,1))!important;text-decoration-color:RGBA(var(--bs-primary-rgb),var(--bs-link-underline-opacity,1))!important}.link-primary:focus,.link-primary:hover{color:RGBA(10,88,202,var(--bs-link-opacity,1))!important;-webkit-text-decoration-color:RGBA(10,88,202,var(--bs-link-underline-opacity,1))!important;text-decoration-color:RGBA(10,88,202,var(--bs-link-underline-opacity,1))!important}.link-secondary{color:RGBA(var(--bs-secondary-rgb),var(--bs-link-opacity,1))!important;-webkit-text-decoration-color:RGBA(var(--bs-secondary-rgb),var(--bs-link-underline-opacity,1))!important;text-decoration-color:RGBA(var(--bs-secondary-rgb),var(--bs-link-underline-opacity,1))!important}.link-secondary:focus,.link-secondary:hover{color:RGBA(86,94,100,var(--bs-link-opacity,1))!important;-webkit-text-decoration-color:RGBA(86,94,100,var(--bs-link-underline-opacity,1))!important;text-decoration-color:RGBA(86,94,100,var(--bs-link-underline-opacity,1))!important}.link-success{color:RGBA(var(--bs-success-rgb),var(--bs-link-opacity,1))!important;-webkit-text-decoration-color:RGBA(var(--bs-success-rgb),var(--bs-link-underline-opacity,1))!important;text-decoration-color:RGBA(var(--bs-success-rgb),var(--bs-link-underline-opacity,1))!important}.link-success:focus,.link-success:hover{color:RGBA(20,108,67,var(--bs-link-opacity,1))!important;-webkit-text-decoration-color:RGBA(20,108,67,var(--bs-link-underline-opacity,1))!important;text-decoration-color:RGBA(20,108,67,var(--bs-link-underline-opacity,1))!important}.link-info{color:RGBA(var(--bs-info-rgb),var(--bs-link-opacity,1))!important;-webkit-text-decoration-color:RGBA(var(--bs-info-rgb),var(--bs-link-underline-opacity,1))!important;text-decoration-color:RGBA(var(--bs-info-rgb),var(--bs-link-underline-opacity,1))!important}.link-info:focus,.link-info:hover{color:RGBA(61,213,243,var(--bs-link-opacity,1))!important;-webkit-text-decoration-color:RGBA(61,213,243,var(--bs-link-underline-opacity,1))!important;text-decoration-color:RGBA(61,213,243,var(--bs-link-underline-opacity,1))!important}.link-warning{color:RGBA(var(--bs-warning-rgb),var(--bs-link-opacity,1))!important;-webkit-text-decoration-color:RGBA(var(--bs-warning-rgb),var(--bs-link-underline-opacity,1))!important;text-decoration-color:RGBA(var(--bs-warning-rgb),var(--bs-link-underline-opacity,1))!important}.link-warning:focus,.link-warning:hover{color:RGBA(255,205,57,var(--bs-link-opacity,1))!important;-webkit-text-decoration-color:RGBA(255,205,57,var(--bs-link-underline-opacity,1))!important;text-decoration-color:RGBA(255,205,57,var(--bs-link-underline-opacity,1))!important}.link-danger{color:RGBA(var(--bs-danger-rgb),var(--bs-link-opacity,1))!important;-webkit-text-decoration-color:RGBA(var(--bs-danger-rgb),var(--bs-link-underline-opacity,1))!important;text-decoration-color:RGBA(var(--bs-danger-rgb),var(--bs-link-underline-opacity,1))!important}.link-danger:focus,.link-danger:hover{color:RGBA(176,42,55,var(--bs-link-opacity,1))!important;-webkit-text-decoration-color:RGBA(176,42,55,var(--bs-link-underline-opacity,1))!important;text-decoration-color:RGBA(176,42,55,var(--bs-link-underline-opacity,1))!important}.link-light{color:RGBA(var(--bs-light-rgb),var(--bs-link-opacity,1))!important;-webkit-text-decoration-color:RGBA(var(--bs-light-rgb),var(--bs-link-underline-opacity,1))!important;text-decoration-color:RGBA(var(--bs-light-rgb),var(--bs-link-underline-opacity,1))!important}.link-light:focus,.link-light:hover{color:RGBA(249,250,251,var(--bs-link-opacity,1))!important;-webkit-text-decoration-color:RGBA(249,250,251,var(--bs-link-underline-opacity,1))!important;text-decoration-color:RGBA(249,250,251,var(--bs-link-underline-opacity,1))!important}.link-dark{color:RGBA(var(--bs-dark-rgb),var(--bs-link-opacity,1))!important;-webkit-text-decoration-color:RGBA(var(--bs-dark-rgb),var(--bs-link-underline-opacity,1))!important;text-decoration-color:RGBA(var(--bs-dark-rgb),var(--bs-link-underline-opacity,1))!important}.link-dark:focus,.link-dark:hover{color:RGBA(26,30,33,var(--bs-link-opacity,1))!important;-webkit-text-decoration-color:RGBA(26,30,33,var(--bs-link-underline-opacity,1))!important;text-decoration-color:RGBA(26,30,33,var(--bs-link-underline-opacity,1))!important}.link-body-emphasis{color:RGBA(var(--bs-emphasis-color-rgb),var(--bs-link-opacity,1))!important;-webkit-text-decoration-color:RGBA(var(--bs-emphasis-color-rgb),var(--bs-link-underline-opacity,1))!important;text-decoration-color:RGBA(var(--bs-emphasis-color-rgb),var(--bs-link-underline-opacity,1))!important}.link-body-emphasis:focus,.link-body-emphasis:hover{color:RGBA(var(--bs-emphasis-color-rgb),var(--bs-link-opacity,.75))!important;-webkit-text-decoration-color:RGBA(var(--bs-emphasis-color-rgb),var(--bs-link-underline-opacity,0.75))!important;text-decoration-color:RGBA(var(--bs-emphasis-color-rgb),var(--bs-link-underline-opacity,0.75))!important}.focus-ring:focus{outline:0;box-shadow:var(--bs-focus-ring-x,0) var(--bs-focus-ring-y,0) var(--bs-focus-ring-blur,0) var(--bs-focus-ring-width) var(--bs-focus-ring-color)}.icon-link{display:inline-flex;gap:.375rem;align-items:center;-webkit-text-decoration-color:rgba(var(--bs-link-color-rgb),var(--bs-link-opacity,0.5));text-decoration-color:rgba(var(--bs-link-color-rgb),var(--bs-link-opacity,0.5));text-underline-offset:0.25em;-webkit-backface-visibility:hidden;backface-visibility:hidden}.icon-link>.bi{flex-shrink:0;width:1em;height:1em;fill:currentcolor;transition:.2s ease-in-out transform}@media (prefers-reduced-motion:reduce){.icon-link>.bi{transition:none}}.icon-link-hover:focus-visible>.bi,.icon-link-hover:hover>.bi{transform:var(--bs-icon-link-transform,translate3d(.25em,0,0))}.ratio{position:relative;width:100%}.ratio::before{display:block;padding-top:var(--bs-aspect-ratio);content:""}.ratio>*{position:absolute;top:0;left:0;width:100%;height:100%}.ratio-1x1{--bs-aspect-ratio:100%}.ratio-4x3{--bs-aspect-ratio:75%}.ratio-16x9{--bs-aspect-ratio:56.25%}.ratio-21x9{--bs-aspect-ratio:42.8571428571%}.fixed-top{position:fixed;top:0;right:0;left:0;z-index:1030}.fixed-bottom{position:fixed;right:0;bottom:0;left:0;z-index:1030}.sticky-top{position:-webkit-sticky;position:sticky;top:0;z-index:1020}.sticky-bottom{position:-webkit-sticky;position:sticky;bottom:0;z-index:1020}@media (min-width:576px){.sticky-sm-top{position:-webkit-sticky;position:sticky;top:0;z-index:1020}.sticky-sm-bottom{position:-webkit-sticky;position:sticky;bottom:0;z-index:1020}}@media (min-width:768px){.sticky-md-top{position:-webkit-sticky;position:sticky;top:0;z-index:1020}.sticky-md-bottom{position:-webkit-sticky;position:sticky;bottom:0;z-index:1020}}@media (min-width:992px){.sticky-lg-top{position:-webkit-sticky;position:sticky;top:0;z-index:1020}.sticky-lg-bottom{position:-webkit-sticky;position:sticky;bottom:0;z-index:1020}}@media (min-width:1200px){.sticky-xl-top{position:-webkit-sticky;position:sticky;top:0;z-index:1020}.sticky-xl-bottom{position:-webkit-sticky;position:sticky;bottom:0;z-index:1020}}@media (min-width:1400px){.sticky-xxl-top{position:-webkit-sticky;position:sticky;top:0;z-index:1020}.sticky-xxl-bottom{position:-webkit-sticky;position:sticky;bottom:0;z-index:1020}}.hstack{display:flex;flex-direction:row;align-items:center;align-self:stretch}.vstack{display:flex;flex:1 1 auto;flex-direction:column;align-self:stretch}.visually-hidden,.visually-hidden-focusable:not(:focus):not(:focus-within){width:1px!important;height:1px!important;padding:0!important;margin:-1px!important;overflow:hidden!important;clip:rect(0,0,0,0)!important;white-space:nowrap!important;border:0!important}.visually-hidden-focusable:not(:focus):not(:focus-within):not(caption),.visually-hidden:not(caption){position:absolute!important}.visually-hidden *,.visually-hidden-focusable:not(:focus):not(:focus-within) *{overflow:hidden!important}.stretched-link::after{position:absolute;top:0;right:0;bottom:0;left:0;z-index:1;content:""}.text-truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.vr{display:inline-block;align-self:stretch;width:var(--bs-border-width);min-height:1em;background-color:currentcolor;opacity:.25}.align-baseline{vertical-align:baseline!important}.align-top{vertical-align:top!important}.align-middle{vertical-align:middle!important}.align-bottom{vertical-align:bottom!important}.align-text-bottom{vertical-align:text-bottom!important}.align-text-top{vertical-align:text-top!important}.float-start{float:left!important}.float-end{float:right!important}.float-none{float:none!important}.object-fit-contain{-o-object-fit:contain!important;object-fit:contain!important}.object-fit-cover{-o-object-fit:cover!important;object-fit:cover!important}.object-fit-fill{-o-object-fit:fill!important;object-fit:fill!important}.object-fit-scale{-o-object-fit:scale-down!important;object-fit:scale-down!important}.object-fit-none{-o-object-fit:none!important;object-fit:none!important}.opacity-0{opacity:0!important}.opacity-25{opacity:.25!important}.opacity-50{opacity:.5!important}.opacity-75{opacity:.75!important}.opacity-100{opacity:1!important}.overflow-auto{overflow:auto!important}.overflow-hidden{overflow:hidden!important}.overflow-visible{overflow:visible!important}.overflow-scroll{overflow:scroll!important}.overflow-x-auto{overflow-x:auto!important}.overflow-x-hidden{overflow-x:hidden!important}.overflow-x-visible{overflow-x:visible!important}.overflow-x-scroll{overflow-x:scroll!important}.overflow-y-auto{overflow-y:auto!important}.overflow-y-hidden{overflow-y:hidden!important}.overflow-y-visible{overflow-y:visible!important}.overflow-y-scroll{overflow-y:scroll!important}.d-inline{display:inline!important}.d-inline-block{display:inline-block!important}.d-block{display:block!important}.d-grid{display:grid!important}.d-inline-grid{display:inline-grid!important}.d-table{display:table!important}.d-table-row{display:table-row!important}.d-table-cell{display:table-cell!important}.d-flex{display:flex!important}.d-inline-flex{display:inline-flex!important}.d-none{display:none!important}.shadow{box-shadow:var(--bs-box-shadow)!important}.shadow-sm{box-shadow:var(--bs-box-shadow-sm)!important}.shadow-lg{box-shadow:var(--bs-box-shadow-lg)!important}.shadow-none{box-shadow:none!important}.focus-ring-primary{--bs-focus-ring-color:rgba(var(--bs-primary-rgb), var(--bs-focus-ring-opacity))}.focus-ring-secondary{--bs-focus-ring-color:rgba(var(--bs-secondary-rgb), var(--bs-focus-ring-opacity))}.focus-ring-success{--bs-focus-ring-color:rgba(var(--bs-success-rgb), var(--bs-focus-ring-opacity))}.focus-ring-info{--bs-focus-ring-color:rgba(var(--bs-info-rgb), var(--bs-focus-ring-opacity))}.focus-ring-warning{--bs-focus-ring-color:rgba(var(--bs-warning-rgb), var(--bs-focus-ring-opacity))}.focus-ring-danger{--bs-focus-ring-color:rgba(var(--bs-danger-rgb), var(--bs-focus-ring-opacity))}.focus-ring-light{--bs-focus-ring-color:rgba(var(--bs-light-rgb), var(--bs-focus-ring-opacity))}.focus-ring-dark{--bs-focus-ring-color:rgba(var(--bs-dark-rgb), var(--bs-focus-ring-opacity))}.position-static{position:static!important}.position-relative{position:relative!important}.position-absolute{position:absolute!important}.position-fixed{position:fixed!important}.position-sticky{position:-webkit-sticky!important;position:sticky!important}.top-0{top:0!important}.top-50{top:50%!important}.top-100{top:100%!important}.bottom-0{bottom:0!important}.bottom-50{bottom:50%!important}.bottom-100{bottom:100%!important}.start-0{left:0!important}.start-50{left:50%!important}.start-100{left:100%!important}.end-0{right:0!important}.end-50{right:50%!important}.end-100{right:100%!important}.translate-middle{transform:translate(-50%,-50%)!important}.translate-middle-x{transform:translateX(-50%)!important}.translate-middle-y{transform:translateY(-50%)!important}.border{border:var(--bs-border-width) var(--bs-border-style) var(--bs-border-color)!important}.border-0{border:0!important}.border-top{border-top:var(--bs-border-width) var(--bs-border-style) var(--bs-border-color)!important}.border-top-0{border-top:0!important}.border-end{border-right:var(--bs-border-width) var(--bs-border-style) var(--bs-border-color)!important}.border-end-0{border-right:0!important}.border-bottom{border-bottom:var(--bs-border-width) var(--bs-border-style) var(--bs-border-color)!important}.border-bottom-0{border-bottom:0!important}.border-start{border-left:var(--bs-border-width) var(--bs-border-style) var(--bs-border-color)!important}.border-start-0{border-left:0!important}.border-primary{--bs-border-opacity:1;border-color:rgba(var(--bs-primary-rgb),var(--bs-border-opacity))!important}.border-secondary{--bs-border-opacity:1;border-color:rgba(var(--bs-secondary-rgb),var(--bs-border-opacity))!important}.border-success{--bs-border-opacity:1;border-color:rgba(var(--bs-success-rgb),var(--bs-border-opacity))!important}.border-info{--bs-border-opacity:1;border-color:rgba(var(--bs-info-rgb),var(--bs-border-opacity))!important}.border-warning{--bs-border-opacity:1;border-color:rgba(var(--bs-warning-rgb),var(--bs-border-opacity))!important}.border-danger{--bs-border-opacity:1;border-color:rgba(var(--bs-danger-rgb),var(--bs-border-opacity))!important}.border-light{--bs-border-opacity:1;border-color:rgba(var(--bs-light-rgb),var(--bs-border-opacity))!important}.border-dark{--bs-border-opacity:1;border-color:rgba(var(--bs-dark-rgb),var(--bs-border-opacity))!important}.border-black{--bs-border-opacity:1;border-color:rgba(var(--bs-black-rgb),var(--bs-border-opacity))!important}.border-white{--bs-border-opacity:1;border-color:rgba(var(--bs-white-rgb),var(--bs-border-opacity))!important}.border-primary-subtle{border-color:var(--bs-primary-border-subtle)!important}.border-secondary-subtle{border-color:var(--bs-secondary-border-subtle)!important}.border-success-subtle{border-color:var(--bs-success-border-subtle)!important}.border-info-subtle{border-color:var(--bs-info-border-subtle)!important}.border-warning-subtle{border-color:var(--bs-warning-border-subtle)!important}.border-danger-subtle{border-color:var(--bs-danger-border-subtle)!important}.border-light-subtle{border-color:var(--bs-light-border-subtle)!important}.border-dark-subtle{border-color:var(--bs-dark-border-subtle)!important}.border-1{border-width:1px!important}.border-2{border-width:2px!important}.border-3{border-width:3px!important}.border-4{border-width:4px!important}.border-5{border-width:5px!important}.border-opacity-10{--bs-border-opacity:0.1}.border-opacity-25{--bs-border-opacity:0.25}.border-opacity-50{--bs-border-opacity:0.5}.border-opacity-75{--bs-border-opacity:0.75}.border-opacity-100{--bs-border-opacity:1}.w-25{width:25%!important}.w-50{width:50%!important}.w-75{width:75%!important}.w-100{width:100%!important}.w-auto{width:auto!important}.mw-100{max-width:100%!important}.vw-100{width:100vw!important}.min-vw-100{min-width:100vw!important}.h-25{height:25%!important}.h-50{height:50%!important}.h-75{height:75%!important}.h-100{height:100%!important}.h-auto{height:auto!important}.mh-100{max-height:100%!important}.vh-100{height:100vh!important}.min-vh-100{min-height:100vh!important}.flex-fill{flex:1 1 auto!important}.flex-row{flex-direction:row!important}.flex-column{flex-direction:column!important}.flex-row-reverse{flex-direction:row-reverse!important}.flex-column-reverse{flex-direction:column-reverse!important}.flex-grow-0{flex-grow:0!important}.flex-grow-1{flex-grow:1!important}.flex-shrink-0{flex-shrink:0!important}.flex-shrink-1{flex-shrink:1!important}.flex-wrap{flex-wrap:wrap!important}.flex-nowrap{flex-wrap:nowrap!important}.flex-wrap-reverse{flex-wrap:wrap-reverse!important}.justify-content-start{justify-content:flex-start!important}.justify-content-end{justify-content:flex-end!important}.justify-content-center{justify-content:center!important}.justify-content-between{justify-content:space-between!important}.justify-content-around{justify-content:space-around!important}.justify-content-evenly{justify-content:space-evenly!important}.align-items-start{align-items:flex-start!important}.align-items-end{align-items:flex-end!important}.align-items-center{align-items:center!important}.align-items-baseline{align-items:baseline!important}.align-items-stretch{align-items:stretch!important}.align-content-start{align-content:flex-start!important}.align-content-end{align-content:flex-end!important}.align-content-center{align-content:center!important}.align-content-between{align-content:space-between!important}.align-content-around{align-content:space-around!important}.align-content-stretch{align-content:stretch!important}.align-self-auto{align-self:auto!important}.align-self-start{align-self:flex-start!important}.align-self-end{align-self:flex-end!important}.align-self-center{align-self:center!important}.align-self-baseline{align-self:baseline!important}.align-self-stretch{align-self:stretch!important}.order-first{order:-1!important}.order-0{order:0!important}.order-1{order:1!important}.order-2{order:2!important}.order-3{order:3!important}.order-4{order:4!important}.order-5{order:5!important}.order-last{order:6!important}.m-0{margin:0!important}.m-1{margin:.25rem!important}.m-2{margin:.5rem!important}.m-3{margin:1rem!important}.m-4{margin:1.5rem!important}.m-5{margin:3rem!important}.m-auto{margin:auto!important}.mx-0{margin-right:0!important;margin-left:0!important}.mx-1{margin-right:.25rem!important;margin-left:.25rem!important}.mx-2{margin-right:.5rem!important;margin-left:.5rem!important}.mx-3{margin-right:1rem!important;margin-left:1rem!important}.mx-4{margin-right:1.5rem!important;margin-left:1.5rem!important}.mx-5{margin-right:3rem!important;margin-left:3rem!important}.mx-auto{margin-right:auto!important;margin-left:auto!important}.my-0{margin-top:0!important;margin-bottom:0!important}.my-1{margin-top:.25rem!important;margin-bottom:.25rem!important}.my-2{margin-top:.5rem!important;margin-bottom:.5rem!important}.my-3{margin-top:1rem!important;margin-bottom:1rem!important}.my-4{margin-top:1.5rem!important;margin-bottom:1.5rem!important}.my-5{margin-top:3rem!important;margin-bottom:3rem!important}.my-auto{margin-top:auto!important;margin-bottom:auto!important}.mt-0{margin-top:0!important}.mt-1{margin-top:.25rem!important}.mt-2{margin-top:.5rem!important}.mt-3{margin-top:1rem!important}.mt-4{margin-top:1.5rem!important}.mt-5{margin-top:3rem!important}.mt-auto{margin-top:auto!important}.me-0{margin-right:0!important}.me-1{margin-right:.25rem!important}.me-2{margin-right:.5rem!important}.me-3{margin-right:1rem!important}.me-4{margin-right:1.5rem!important}.me-5{margin-right:3rem!important}.me-auto{margin-right:auto!important}.mb-0{margin-bottom:0!important}.mb-1{margin-bottom:.25rem!important}.mb-2{margin-bottom:.5rem!important}.mb-3{margin-bottom:1rem!important}.mb-4{margin-bottom:1.5rem!important}.mb-5{margin-bottom:3rem!important}.mb-auto{margin-bottom:auto!important}.ms-0{margin-left:0!important}.ms-1{margin-left:.25rem!important}.ms-2{margin-left:.5rem!important}.ms-3{margin-left:1rem!important}.ms-4{margin-left:1.5rem!important}.ms-5{margin-left:3rem!important}.ms-auto{margin-left:auto!important}.p-0{padding:0!important}.p-1{padding:.25rem!important}.p-2{padding:.5rem!important}.p-3{padding:1rem!important}.p-4{padding:1.5rem!important}.p-5{padding:3rem!important}.px-0{padding-right:0!important;padding-left:0!important}.px-1{padding-right:.25rem!important;padding-left:.25rem!important}.px-2{padding-right:.5rem!important;padding-left:.5rem!important}.px-3{padding-right:1rem!important;padding-left:1rem!important}.px-4{padding-right:1.5rem!important;padding-left:1.5rem!important}.px-5{padding-right:3rem!important;padding-left:3rem!important}.py-0{padding-top:0!important;padding-bottom:0!important}.py-1{padding-top:.25rem!important;padding-bottom:.25rem!important}.py-2{padding-top:.5rem!important;padding-bottom:.5rem!important}.py-3{padding-top:1rem!important;padding-bottom:1rem!important}.py-4{padding-top:1.5rem!important;padding-bottom:1.5rem!important}.py-5{padding-top:3rem!important;padding-bottom:3rem!important}.pt-0{padding-top:0!important}.pt-1{padding-top:.25rem!important}.pt-2{padding-top:.5rem!important}.pt-3{padding-top:1rem!important}.pt-4{padding-top:1.5rem!important}.pt-5{padding-top:3rem!important}.pe-0{padding-right:0!important}.pe-1{padding-right:.25rem!important}.pe-2{padding-right:.5rem!important}.pe-3{padding-right:1rem!important}.pe-4{padding-right:1.5rem!important}.pe-5{padding-right:3rem!important}.pb-0{padding-bottom:0!important}.pb-1{padding-bottom:.25rem!important}.pb-2{padding-bottom:.5rem!important}.pb-3{padding-bottom:1rem!important}.pb-4{padding-bottom:1.5rem!important}.pb-5{padding-bottom:3rem!important}.ps-0{padding-left:0!important}.ps-1{padding-left:.25rem!important}.ps-2{padding-left:.5rem!important}.ps-3{padding-left:1rem!important}.ps-4{padding-left:1.5rem!important}.ps-5{padding-left:3rem!important}.gap-0{gap:0!important}.gap-1{gap:.25rem!important}.gap-2{gap:.5rem!important}.gap-3{gap:1rem!important}.gap-4{gap:1.5rem!important}.gap-5{gap:3rem!important}.row-gap-0{row-gap:0!important}.row-gap-1{row-gap:.25rem!important}.row-gap-2{row-gap:.5rem!important}.row-gap-3{row-gap:1rem!important}.row-gap-4{row-gap:1.5rem!important}.row-gap-5{row-gap:3rem!important}.column-gap-0{-moz-column-gap:0!important;column-gap:0!important}.column-gap-1{-moz-column-gap:0.25rem!important;column-gap:.25rem!important}.column-gap-2{-moz-column-gap:0.5rem!important;column-gap:.5rem!important}.column-gap-3{-moz-column-gap:1rem!important;column-gap:1rem!important}.column-gap-4{-moz-column-gap:1.5rem!important;column-gap:1.5rem!important}.column-gap-5{-moz-column-gap:3rem!important;column-gap:3rem!important}.font-monospace{font-family:var(--bs-font-monospace)!important}.fs-1{font-size:calc(1.375rem + 1.5vw)!important}.fs-2{font-size:calc(1.325rem + .9vw)!important}.fs-3{font-size:calc(1.3rem + .6vw)!important}.fs-4{font-size:calc(1.275rem + .3vw)!important}.fs-5{font-size:1.25rem!important}.fs-6{font-size:1rem!important}.fst-italic{font-style:italic!important}.fst-normal{font-style:normal!important}.fw-lighter{font-weight:lighter!important}.fw-light{font-weight:300!important}.fw-normal{font-weight:400!important}.fw-medium{font-weight:500!important}.fw-semibold{font-weight:600!important}.fw-bold{font-weight:700!important}.fw-bolder{font-weight:bolder!important}.lh-1{line-height:1!important}.lh-sm{line-height:1.25!important}.lh-base{line-height:1.5!important}.lh-lg{line-height:2!important}.text-start{text-align:left!important}.text-end{text-align:right!important}.text-center{text-align:center!important}.text-decoration-none{text-decoration:none!important}.text-decoration-underline{text-decoration:underline!important}.text-decoration-line-through{text-decoration:line-through!important}.text-lowercase{text-transform:lowercase!important}.text-uppercase{text-transform:uppercase!important}.text-capitalize{text-transform:capitalize!important}.text-wrap{white-space:normal!important}.text-nowrap{white-space:nowrap!important}.text-break{word-wrap:break-word!important;word-break:break-word!important}.text-primary{--bs-text-opacity:1;color:rgba(var(--bs-primary-rgb),var(--bs-text-opacity))!important}.text-secondary{--bs-text-opacity:1;color:rgba(var(--bs-secondary-rgb),var(--bs-text-opacity))!important}.text-success{--bs-text-opacity:1;color:rgba(var(--bs-success-rgb),var(--bs-text-opacity))!important}.text-info{--bs-text-opacity:1;color:rgba(var(--bs-info-rgb),var(--bs-text-opacity))!important}.text-warning{--bs-text-opacity:1;color:rgba(var(--bs-warning-rgb),var(--bs-text-opacity))!important}.text-danger{--bs-text-opacity:1;color:rgba(var(--bs-danger-rgb),var(--bs-text-opacity))!important}.text-light{--bs-text-opacity:1;color:rgba(var(--bs-light-rgb),var(--bs-text-opacity))!important}.text-dark{--bs-text-opacity:1;color:rgba(var(--bs-dark-rgb),var(--bs-text-opacity))!important}.text-black{--bs-text-opacity:1;color:rgba(var(--bs-black-rgb),var(--bs-text-opacity))!important}.text-white{--bs-text-opacity:1;color:rgba(var(--bs-white-rgb),var(--bs-text-opacity))!important}.text-body{--bs-text-opacity:1;color:rgba(var(--bs-body-color-rgb),var(--bs-text-opacity))!important}.text-muted{--bs-text-opacity:1;color:var(--bs-secondary-color)!important}.text-black-50{--bs-text-opacity:1;color:rgba(0,0,0,.5)!important}.text-white-50{--bs-text-opacity:1;color:rgba(255,255,255,.5)!important}.text-body-secondary{--bs-text-opacity:1;color:var(--bs-secondary-color)!important}.text-body-tertiary{--bs-text-opacity:1;color:var(--bs-tertiary-color)!important}.text-body-emphasis{--bs-text-opacity:1;color:var(--bs-emphasis-color)!important}.text-reset{--bs-text-opacity:1;color:inherit!important}.text-opacity-25{--bs-text-opacity:0.25}.text-opacity-50{--bs-text-opacity:0.5}.text-opacity-75{--bs-text-opacity:0.75}.text-opacity-100{--bs-text-opacity:1}.text-primary-emphasis{color:var(--bs-primary-text-emphasis)!important}.text-secondary-emphasis{color:var(--bs-secondary-text-emphasis)!important}.text-success-emphasis{color:var(--bs-success-text-emphasis)!important}.text-info-emphasis{color:var(--bs-info-text-emphasis)!important}.text-warning-emphasis{color:var(--bs-warning-text-emphasis)!important}.text-danger-emphasis{color:var(--bs-danger-text-emphasis)!important}.text-light-emphasis{color:var(--bs-light-text-emphasis)!important}.text-dark-emphasis{color:var(--bs-dark-text-emphasis)!important}.link-opacity-10{--bs-link-opacity:0.1}.link-opacity-10-hover:hover{--bs-link-opacity:0.1}.link-opacity-25{--bs-link-opacity:0.25}.link-opacity-25-hover:hover{--bs-link-opacity:0.25}.link-opacity-50{--bs-link-opacity:0.5}.link-opacity-50-hover:hover{--bs-link-opacity:0.5}.link-opacity-75{--bs-link-opacity:0.75}.link-opacity-75-hover:hover{--bs-link-opacity:0.75}.link-opacity-100{--bs-link-opacity:1}.link-opacity-100-hover:hover{--bs-link-opacity:1}.link-offset-1{text-underline-offset:0.125em!important}.link-offset-1-hover:hover{text-underline-offset:0.125em!important}.link-offset-2{text-underline-offset:0.25em!important}.link-offset-2-hover:hover{text-underline-offset:0.25em!important}.link-offset-3{text-underline-offset:0.375em!important}.link-offset-3-hover:hover{text-underline-offset:0.375em!important}.link-underline-primary{--bs-link-underline-opacity:1;-webkit-text-decoration-color:rgba(var(--bs-primary-rgb),var(--bs-link-underline-opacity))!important;text-decoration-color:rgba(var(--bs-primary-rgb),var(--bs-link-underline-opacity))!important}.link-underline-secondary{--bs-link-underline-opacity:1;-webkit-text-decoration-color:rgba(var(--bs-secondary-rgb),var(--bs-link-underline-opacity))!important;text-decoration-color:rgba(var(--bs-secondary-rgb),var(--bs-link-underline-opacity))!important}.link-underline-success{--bs-link-underline-opacity:1;-webkit-text-decoration-color:rgba(var(--bs-success-rgb),var(--bs-link-underline-opacity))!important;text-decoration-color:rgba(var(--bs-success-rgb),var(--bs-link-underline-opacity))!important}.link-underline-info{--bs-link-underline-opacity:1;-webkit-text-decoration-color:rgba(var(--bs-info-rgb),var(--bs-link-underline-opacity))!important;text-decoration-color:rgba(var(--bs-info-rgb),var(--bs-link-underline-opacity))!important}.link-underline-warning{--bs-link-underline-opacity:1;-webkit-text-decoration-color:rgba(var(--bs-warning-rgb),var(--bs-link-underline-opacity))!important;text-decoration-color:rgba(var(--bs-warning-rgb),var(--bs-link-underline-opacity))!important}.link-underline-danger{--bs-link-underline-opacity:1;-webkit-text-decoration-color:rgba(var(--bs-danger-rgb),var(--bs-link-underline-opacity))!important;text-decoration-color:rgba(var(--bs-danger-rgb),var(--bs-link-underline-opacity))!important}.link-underline-light{--bs-link-underline-opacity:1;-webkit-text-decoration-color:rgba(var(--bs-light-rgb),var(--bs-link-underline-opacity))!important;text-decoration-color:rgba(var(--bs-light-rgb),var(--bs-link-underline-opacity))!important}.link-underline-dark{--bs-link-underline-opacity:1;-webkit-text-decoration-color:rgba(var(--bs-dark-rgb),var(--bs-link-underline-opacity))!important;text-decoration-color:rgba(var(--bs-dark-rgb),var(--bs-link-underline-opacity))!important}.link-underline{--bs-link-underline-opacity:1;-webkit-text-decoration-color:rgba(var(--bs-link-color-rgb),var(--bs-link-underline-opacity,1))!important;text-decoration-color:rgba(var(--bs-link-color-rgb),var(--bs-link-underline-opacity,1))!important}.link-underline-opacity-0{--bs-link-underline-opacity:0}.link-underline-opacity-0-hover:hover{--bs-link-underline-opacity:0}.link-underline-opacity-10{--bs-link-underline-opacity:0.1}.link-underline-opacity-10-hover:hover{--bs-link-underline-opacity:0.1}.link-underline-opacity-25{--bs-link-underline-opacity:0.25}.link-underline-opacity-25-hover:hover{--bs-link-underline-opacity:0.25}.link-underline-opacity-50{--bs-link-underline-opacity:0.5}.link-underline-opacity-50-hover:hover{--bs-link-underline-opacity:0.5}.link-underline-opacity-75{--bs-link-underline-opacity:0.75}.link-underline-opacity-75-hover:hover{--bs-link-underline-opacity:0.75}.link-underline-opacity-100{--bs-link-underline-opacity:1}.link-underline-opacity-100-hover:hover{--bs-link-underline-opacity:1}.bg-primary{--bs-bg-opacity:1;background-color:rgba(var(--bs-primary-rgb),var(--bs-bg-opacity))!important}.bg-secondary{--bs-bg-opacity:1;background-color:rgba(var(--bs-secondary-rgb),var(--bs-bg-opacity))!important}.bg-success{--bs-bg-opacity:1;background-color:rgba(var(--bs-success-rgb),var(--bs-bg-opacity))!important}.bg-info{--bs-bg-opacity:1;background-color:rgba(var(--bs-info-rgb),var(--bs-bg-opacity))!important}.bg-warning{--bs-bg-opacity:1;background-color:rgba(var(--bs-warning-rgb),var(--bs-bg-opacity))!important}.bg-danger{--bs-bg-opacity:1;background-color:rgba(var(--bs-danger-rgb),var(--bs-bg-opacity))!important}.bg-light{--bs-bg-opacity:1;background-color:rgba(var(--bs-light-rgb),var(--bs-bg-opacity))!important}.bg-dark{--bs-bg-opacity:1;background-color:rgba(var(--bs-dark-rgb),var(--bs-bg-opacity))!important}.bg-black{--bs-bg-opacity:1;background-color:rgba(var(--bs-black-rgb),var(--bs-bg-opacity))!important}.bg-white{--bs-bg-opacity:1;background-color:rgba(var(--bs-white-rgb),var(--bs-bg-opacity))!important}.bg-body{--bs-bg-opacity:1;background-color:rgba(var(--bs-body-bg-rgb),var(--bs-bg-opacity))!important}.bg-transparent{--bs-bg-opacity:1;background-color:transparent!important}.bg-body-secondary{--bs-bg-opacity:1;background-color:rgba(var(--bs-secondary-bg-rgb),var(--bs-bg-opacity))!important}.bg-body-tertiary{--bs-bg-opacity:1;background-color:rgba(var(--bs-tertiary-bg-rgb),var(--bs-bg-opacity))!important}.bg-opacity-10{--bs-bg-opacity:0.1}.bg-opacity-25{--bs-bg-opacity:0.25}.bg-opacity-50{--bs-bg-opacity:0.5}.bg-opacity-75{--bs-bg-opacity:0.75}.bg-opacity-100{--bs-bg-opacity:1}.bg-primary-subtle{background-color:var(--bs-primary-bg-subtle)!important}.bg-secondary-subtle{background-color:var(--bs-secondary-bg-subtle)!important}.bg-success-subtle{background-color:var(--bs-success-bg-subtle)!important}.bg-info-subtle{background-color:var(--bs-info-bg-subtle)!important}.bg-warning-subtle{background-color:var(--bs-warning-bg-subtle)!important}.bg-danger-subtle{background-color:var(--bs-danger-bg-subtle)!important}.bg-light-subtle{background-color:var(--bs-light-bg-subtle)!important}.bg-dark-subtle{background-color:var(--bs-dark-bg-subtle)!important}.bg-gradient{background-image:var(--bs-gradient)!important}.user-select-all{-webkit-user-select:all!important;-moz-user-select:all!important;user-select:all!important}.user-select-auto{-webkit-user-select:auto!important;-moz-user-select:auto!important;user-select:auto!important}.user-select-none{-webkit-user-select:none!important;-moz-user-select:none!important;user-select:none!important}.pe-none{pointer-events:none!important}.pe-auto{pointer-events:auto!important}.rounded{border-radius:var(--bs-border-radius)!important}.rounded-0{border-radius:0!important}.rounded-1{border-radius:var(--bs-border-radius-sm)!important}.rounded-2{border-radius:var(--bs-border-radius)!important}.rounded-3{border-radius:var(--bs-border-radius-lg)!important}.rounded-4{border-radius:var(--bs-border-radius-xl)!important}.rounded-5{border-radius:var(--bs-border-radius-xxl)!important}.rounded-circle{border-radius:50%!important}.rounded-pill{border-radius:var(--bs-border-radius-pill)!important}.rounded-top{border-top-left-radius:var(--bs-border-radius)!important;border-top-right-radius:var(--bs-border-radius)!important}.rounded-top-0{border-top-left-radius:0!important;border-top-right-radius:0!important}.rounded-top-1{border-top-left-radius:var(--bs-border-radius-sm)!important;border-top-right-radius:var(--bs-border-radius-sm)!important}.rounded-top-2{border-top-left-radius:var(--bs-border-radius)!important;border-top-right-radius:var(--bs-border-radius)!important}.rounded-top-3{border-top-left-radius:var(--bs-border-radius-lg)!important;border-top-right-radius:var(--bs-border-radius-lg)!important}.rounded-top-4{border-top-left-radius:var(--bs-border-radius-xl)!important;border-top-right-radius:var(--bs-border-radius-xl)!important}.rounded-top-5{border-top-left-radius:var(--bs-border-radius-xxl)!important;border-top-right-radius:var(--bs-border-radius-xxl)!important}.rounded-top-circle{border-top-left-radius:50%!important;border-top-right-radius:50%!important}.rounded-top-pill{border-top-left-radius:var(--bs-border-radius-pill)!important;border-top-right-radius:var(--bs-border-radius-pill)!important}.rounded-end{border-top-right-radius:var(--bs-border-radius)!important;border-bottom-right-radius:var(--bs-border-radius)!important}.rounded-end-0{border-top-right-radius:0!important;border-bottom-right-radius:0!important}.rounded-end-1{border-top-right-radius:var(--bs-border-radius-sm)!important;border-bottom-right-radius:var(--bs-border-radius-sm)!important}.rounded-end-2{border-top-right-radius:var(--bs-border-radius)!important;border-bottom-right-radius:var(--bs-border-radius)!important}.rounded-end-3{border-top-right-radius:var(--bs-border-radius-lg)!important;border-bottom-right-radius:var(--bs-border-radius-lg)!important}.rounded-end-4{border-top-right-radius:var(--bs-border-radius-xl)!important;border-bottom-right-radius:var(--bs-border-radius-xl)!important}.rounded-end-5{border-top-right-radius:var(--bs-border-radius-xxl)!important;border-bottom-right-radius:var(--bs-border-radius-xxl)!important}.rounded-end-circle{border-top-right-radius:50%!important;border-bottom-right-radius:50%!important}.rounded-end-pill{border-top-right-radius:var(--bs-border-radius-pill)!important;border-bottom-right-radius:var(--bs-border-radius-pill)!important}.rounded-bottom{border-bottom-right-radius:var(--bs-border-radius)!important;border-bottom-left-radius:var(--bs-border-radius)!important}.rounded-bottom-0{border-bottom-right-radius:0!important;border-bottom-left-radius:0!important}.rounded-bottom-1{border-bottom-right-radius:var(--bs-border-radius-sm)!important;border-bottom-left-radius:var(--bs-border-radius-sm)!important}.rounded-bottom-2{border-bottom-right-radius:var(--bs-border-radius)!important;border-bottom-left-radius:var(--bs-border-radius)!important}.rounded-bottom-3{border-bottom-right-radius:var(--bs-border-radius-lg)!important;border-bottom-left-radius:var(--bs-border-radius-lg)!important}.rounded-bottom-4{border-bottom-right-radius:var(--bs-border-radius-xl)!important;border-bottom-left-radius:var(--bs-border-radius-xl)!important}.rounded-bottom-5{border-bottom-right-radius:var(--bs-border-radius-xxl)!important;border-bottom-left-radius:var(--bs-border-radius-xxl)!important}.rounded-bottom-circle{border-bottom-right-radius:50%!important;border-bottom-left-radius:50%!important}.rounded-bottom-pill{border-bottom-right-radius:var(--bs-border-radius-pill)!important;border-bottom-left-radius:var(--bs-border-radius-pill)!important}.rounded-start{border-bottom-left-radius:var(--bs-border-radius)!important;border-top-left-radius:var(--bs-border-radius)!important}.rounded-start-0{border-bottom-left-radius:0!important;border-top-left-radius:0!important}.rounded-start-1{border-bottom-left-radius:var(--bs-border-radius-sm)!important;border-top-left-radius:var(--bs-border-radius-sm)!important}.rounded-start-2{border-bottom-left-radius:var(--bs-border-radius)!important;border-top-left-radius:var(--bs-border-radius)!important}.rounded-start-3{border-bottom-left-radius:var(--bs-border-radius-lg)!important;border-top-left-radius:var(--bs-border-radius-lg)!important}.rounded-start-4{border-bottom-left-radius:var(--bs-border-radius-xl)!important;border-top-left-radius:var(--bs-border-radius-xl)!important}.rounded-start-5{border-bottom-left-radius:var(--bs-border-radius-xxl)!important;border-top-left-radius:var(--bs-border-radius-xxl)!important}.rounded-start-circle{border-bottom-left-radius:50%!important;border-top-left-radius:50%!important}.rounded-start-pill{border-bottom-left-radius:var(--bs-border-radius-pill)!important;border-top-left-radius:var(--bs-border-radius-pill)!important}.visible{visibility:visible!important}.invisible{visibility:hidden!important}.z-n1{z-index:-1!important}.z-0{z-index:0!important}.z-1{z-index:1!important}.z-2{z-index:2!important}.z-3{z-index:3!important}@media (min-width:576px){.float-sm-start{float:left!important}.float-sm-end{float:right!important}.float-sm-none{float:none!important}.object-fit-sm-contain{-o-object-fit:contain!important;object-fit:contain!important}.object-fit-sm-cover{-o-object-fit:cover!important;object-fit:cover!important}.object-fit-sm-fill{-o-object-fit:fill!important;object-fit:fill!important}.object-fit-sm-scale{-o-object-fit:scale-down!important;object-fit:scale-down!important}.object-fit-sm-none{-o-object-fit:none!important;object-fit:none!important}.d-sm-inline{display:inline!important}.d-sm-inline-block{display:inline-block!important}.d-sm-block{display:block!important}.d-sm-grid{display:grid!important}.d-sm-inline-grid{display:inline-grid!important}.d-sm-table{display:table!important}.d-sm-table-row{display:table-row!important}.d-sm-table-cell{display:table-cell!important}.d-sm-flex{display:flex!important}.d-sm-inline-flex{display:inline-flex!important}.d-sm-none{display:none!important}.flex-sm-fill{flex:1 1 auto!important}.flex-sm-row{flex-direction:row!important}.flex-sm-column{flex-direction:column!important}.flex-sm-row-reverse{flex-direction:row-reverse!important}.flex-sm-column-reverse{flex-direction:column-reverse!important}.flex-sm-grow-0{flex-grow:0!important}.flex-sm-grow-1{flex-grow:1!important}.flex-sm-shrink-0{flex-shrink:0!important}.flex-sm-shrink-1{flex-shrink:1!important}.flex-sm-wrap{flex-wrap:wrap!important}.flex-sm-nowrap{flex-wrap:nowrap!important}.flex-sm-wrap-reverse{flex-wrap:wrap-reverse!important}.justify-content-sm-start{justify-content:flex-start!important}.justify-content-sm-end{justify-content:flex-end!important}.justify-content-sm-center{justify-content:center!important}.justify-content-sm-between{justify-content:space-between!important}.justify-content-sm-around{justify-content:space-around!important}.justify-content-sm-evenly{justify-content:space-evenly!important}.align-items-sm-start{align-items:flex-start!important}.align-items-sm-end{align-items:flex-end!important}.align-items-sm-center{align-items:center!important}.align-items-sm-baseline{align-items:baseline!important}.align-items-sm-stretch{align-items:stretch!important}.align-content-sm-start{align-content:flex-start!important}.align-content-sm-end{align-content:flex-end!important}.align-content-sm-center{align-content:center!important}.align-content-sm-between{align-content:space-between!important}.align-content-sm-around{align-content:space-around!important}.align-content-sm-stretch{align-content:stretch!important}.align-self-sm-auto{align-self:auto!important}.align-self-sm-start{align-self:flex-start!important}.align-self-sm-end{align-self:flex-end!important}.align-self-sm-center{align-self:center!important}.align-self-sm-baseline{align-self:baseline!important}.align-self-sm-stretch{align-self:stretch!important}.order-sm-first{order:-1!important}.order-sm-0{order:0!important}.order-sm-1{order:1!important}.order-sm-2{order:2!important}.order-sm-3{order:3!important}.order-sm-4{order:4!important}.order-sm-5{order:5!important}.order-sm-last{order:6!important}.m-sm-0{margin:0!important}.m-sm-1{margin:.25rem!important}.m-sm-2{margin:.5rem!important}.m-sm-3{margin:1rem!important}.m-sm-4{margin:1.5rem!important}.m-sm-5{margin:3rem!important}.m-sm-auto{margin:auto!important}.mx-sm-0{margin-right:0!important;margin-left:0!important}.mx-sm-1{margin-right:.25rem!important;margin-left:.25rem!important}.mx-sm-2{margin-right:.5rem!important;margin-left:.5rem!important}.mx-sm-3{margin-right:1rem!important;margin-left:1rem!important}.mx-sm-4{margin-right:1.5rem!important;margin-left:1.5rem!important}.mx-sm-5{margin-right:3rem!important;margin-left:3rem!important}.mx-sm-auto{margin-right:auto!important;margin-left:auto!important}.my-sm-0{margin-top:0!important;margin-bottom:0!important}.my-sm-1{margin-top:.25rem!important;margin-bottom:.25rem!important}.my-sm-2{margin-top:.5rem!important;margin-bottom:.5rem!important}.my-sm-3{margin-top:1rem!important;margin-bottom:1rem!important}.my-sm-4{margin-top:1.5rem!important;margin-bottom:1.5rem!important}.my-sm-5{margin-top:3rem!important;margin-bottom:3rem!important}.my-sm-auto{margin-top:auto!important;margin-bottom:auto!important}.mt-sm-0{margin-top:0!important}.mt-sm-1{margin-top:.25rem!important}.mt-sm-2{margin-top:.5rem!important}.mt-sm-3{margin-top:1rem!important}.mt-sm-4{margin-top:1.5rem!important}.mt-sm-5{margin-top:3rem!important}.mt-sm-auto{margin-top:auto!important}.me-sm-0{margin-right:0!important}.me-sm-1{margin-right:.25rem!important}.me-sm-2{margin-right:.5rem!important}.me-sm-3{margin-right:1rem!important}.me-sm-4{margin-right:1.5rem!important}.me-sm-5{margin-right:3rem!important}.me-sm-auto{margin-right:auto!important}.mb-sm-0{margin-bottom:0!important}.mb-sm-1{margin-bottom:.25rem!important}.mb-sm-2{margin-bottom:.5rem!important}.mb-sm-3{margin-bottom:1rem!important}.mb-sm-4{margin-bottom:1.5rem!important}.mb-sm-5{margin-bottom:3rem!important}.mb-sm-auto{margin-bottom:auto!important}.ms-sm-0{margin-left:0!important}.ms-sm-1{margin-left:.25rem!important}.ms-sm-2{margin-left:.5rem!important}.ms-sm-3{margin-left:1rem!important}.ms-sm-4{margin-left:1.5rem!important}.ms-sm-5{margin-left:3rem!important}.ms-sm-auto{margin-left:auto!important}.p-sm-0{padding:0!important}.p-sm-1{padding:.25rem!important}.p-sm-2{padding:.5rem!important}.p-sm-3{padding:1rem!important}.p-sm-4{padding:1.5rem!important}.p-sm-5{padding:3rem!important}.px-sm-0{padding-right:0!important;padding-left:0!important}.px-sm-1{padding-right:.25rem!important;padding-left:.25rem!important}.px-sm-2{padding-right:.5rem!important;padding-left:.5rem!important}.px-sm-3{padding-right:1rem!important;padding-left:1rem!important}.px-sm-4{padding-right:1.5rem!important;padding-left:1.5rem!important}.px-sm-5{padding-right:3rem!important;padding-left:3rem!important}.py-sm-0{padding-top:0!important;padding-bottom:0!important}.py-sm-1{padding-top:.25rem!important;padding-bottom:.25rem!important}.py-sm-2{padding-top:.5rem!important;padding-bottom:.5rem!important}.py-sm-3{padding-top:1rem!important;padding-bottom:1rem!important}.py-sm-4{padding-top:1.5rem!important;padding-bottom:1.5rem!important}.py-sm-5{padding-top:3rem!important;padding-bottom:3rem!important}.pt-sm-0{padding-top:0!important}.pt-sm-1{padding-top:.25rem!important}.pt-sm-2{padding-top:.5rem!important}.pt-sm-3{padding-top:1rem!important}.pt-sm-4{padding-top:1.5rem!important}.pt-sm-5{padding-top:3rem!important}.pe-sm-0{padding-right:0!important}.pe-sm-1{padding-right:.25rem!important}.pe-sm-2{padding-right:.5rem!important}.pe-sm-3{padding-right:1rem!important}.pe-sm-4{padding-right:1.5rem!important}.pe-sm-5{padding-right:3rem!important}.pb-sm-0{padding-bottom:0!important}.pb-sm-1{padding-bottom:.25rem!important}.pb-sm-2{padding-bottom:.5rem!important}.pb-sm-3{padding-bottom:1rem!important}.pb-sm-4{padding-bottom:1.5rem!important}.pb-sm-5{padding-bottom:3rem!important}.ps-sm-0{padding-left:0!important}.ps-sm-1{padding-left:.25rem!important}.ps-sm-2{padding-left:.5rem!important}.ps-sm-3{padding-left:1rem!important}.ps-sm-4{padding-left:1.5rem!important}.ps-sm-5{padding-left:3rem!important}.gap-sm-0{gap:0!important}.gap-sm-1{gap:.25rem!important}.gap-sm-2{gap:.5rem!important}.gap-sm-3{gap:1rem!important}.gap-sm-4{gap:1.5rem!important}.gap-sm-5{gap:3rem!important}.row-gap-sm-0{row-gap:0!important}.row-gap-sm-1{row-gap:.25rem!important}.row-gap-sm-2{row-gap:.5rem!important}.row-gap-sm-3{row-gap:1rem!important}.row-gap-sm-4{row-gap:1.5rem!important}.row-gap-sm-5{row-gap:3rem!important}.column-gap-sm-0{-moz-column-gap:0!important;column-gap:0!important}.column-gap-sm-1{-moz-column-gap:0.25rem!important;column-gap:.25rem!important}.column-gap-sm-2{-moz-column-gap:0.5rem!important;column-gap:.5rem!important}.column-gap-sm-3{-moz-column-gap:1rem!important;column-gap:1rem!important}.column-gap-sm-4{-moz-column-gap:1.5rem!important;column-gap:1.5rem!important}.column-gap-sm-5{-moz-column-gap:3rem!important;column-gap:3rem!important}.text-sm-start{text-align:left!important}.text-sm-end{text-align:right!important}.text-sm-center{text-align:center!important}}@media (min-width:768px){.float-md-start{float:left!important}.float-md-end{float:right!important}.float-md-none{float:none!important}.object-fit-md-contain{-o-object-fit:contain!important;object-fit:contain!important}.object-fit-md-cover{-o-object-fit:cover!important;object-fit:cover!important}.object-fit-md-fill{-o-object-fit:fill!important;object-fit:fill!important}.object-fit-md-scale{-o-object-fit:scale-down!important;object-fit:scale-down!important}.object-fit-md-none{-o-object-fit:none!important;object-fit:none!important}.d-md-inline{display:inline!important}.d-md-inline-block{display:inline-block!important}.d-md-block{display:block!important}.d-md-grid{display:grid!important}.d-md-inline-grid{display:inline-grid!important}.d-md-table{display:table!important}.d-md-table-row{display:table-row!important}.d-md-table-cell{display:table-cell!important}.d-md-flex{display:flex!important}.d-md-inline-flex{display:inline-flex!important}.d-md-none{display:none!important}.flex-md-fill{flex:1 1 auto!important}.flex-md-row{flex-direction:row!important}.flex-md-column{flex-direction:column!important}.flex-md-row-reverse{flex-direction:row-reverse!important}.flex-md-column-reverse{flex-direction:column-reverse!important}.flex-md-grow-0{flex-grow:0!important}.flex-md-grow-1{flex-grow:1!important}.flex-md-shrink-0{flex-shrink:0!important}.flex-md-shrink-1{flex-shrink:1!important}.flex-md-wrap{flex-wrap:wrap!important}.flex-md-nowrap{flex-wrap:nowrap!important}.flex-md-wrap-reverse{flex-wrap:wrap-reverse!important}.justify-content-md-start{justify-content:flex-start!important}.justify-content-md-end{justify-content:flex-end!important}.justify-content-md-center{justify-content:center!important}.justify-content-md-between{justify-content:space-between!important}.justify-content-md-around{justify-content:space-around!important}.justify-content-md-evenly{justify-content:space-evenly!important}.align-items-md-start{align-items:flex-start!important}.align-items-md-end{align-items:flex-end!important}.align-items-md-center{align-items:center!important}.align-items-md-baseline{align-items:baseline!important}.align-items-md-stretch{align-items:stretch!important}.align-content-md-start{align-content:flex-start!important}.align-content-md-end{align-content:flex-end!important}.align-content-md-center{align-content:center!important}.align-content-md-between{align-content:space-between!important}.align-content-md-around{align-content:space-around!important}.align-content-md-stretch{align-content:stretch!important}.align-self-md-auto{align-self:auto!important}.align-self-md-start{align-self:flex-start!important}.align-self-md-end{align-self:flex-end!important}.align-self-md-center{align-self:center!important}.align-self-md-baseline{align-self:baseline!important}.align-self-md-stretch{align-self:stretch!important}.order-md-first{order:-1!important}.order-md-0{order:0!important}.order-md-1{order:1!important}.order-md-2{order:2!important}.order-md-3{order:3!important}.order-md-4{order:4!important}.order-md-5{order:5!important}.order-md-last{order:6!important}.m-md-0{margin:0!important}.m-md-1{margin:.25rem!important}.m-md-2{margin:.5rem!important}.m-md-3{margin:1rem!important}.m-md-4{margin:1.5rem!important}.m-md-5{margin:3rem!important}.m-md-auto{margin:auto!important}.mx-md-0{margin-right:0!important;margin-left:0!important}.mx-md-1{margin-right:.25rem!important;margin-left:.25rem!important}.mx-md-2{margin-right:.5rem!important;margin-left:.5rem!important}.mx-md-3{margin-right:1rem!important;margin-left:1rem!important}.mx-md-4{margin-right:1.5rem!important;margin-left:1.5rem!important}.mx-md-5{margin-right:3rem!important;margin-left:3rem!important}.mx-md-auto{margin-right:auto!important;margin-left:auto!important}.my-md-0{margin-top:0!important;margin-bottom:0!important}.my-md-1{margin-top:.25rem!important;margin-bottom:.25rem!important}.my-md-2{margin-top:.5rem!important;margin-bottom:.5rem!important}.my-md-3{margin-top:1rem!important;margin-bottom:1rem!important}.my-md-4{margin-top:1.5rem!important;margin-bottom:1.5rem!important}.my-md-5{margin-top:3rem!important;margin-bottom:3rem!important}.my-md-auto{margin-top:auto!important;margin-bottom:auto!important}.mt-md-0{margin-top:0!important}.mt-md-1{margin-top:.25rem!important}.mt-md-2{margin-top:.5rem!important}.mt-md-3{margin-top:1rem!important}.mt-md-4{margin-top:1.5rem!important}.mt-md-5{margin-top:3rem!important}.mt-md-auto{margin-top:auto!important}.me-md-0{margin-right:0!important}.me-md-1{margin-right:.25rem!important}.me-md-2{margin-right:.5rem!important}.me-md-3{margin-right:1rem!important}.me-md-4{margin-right:1.5rem!important}.me-md-5{margin-right:3rem!important}.me-md-auto{margin-right:auto!important}.mb-md-0{margin-bottom:0!important}.mb-md-1{margin-bottom:.25rem!important}.mb-md-2{margin-bottom:.5rem!important}.mb-md-3{margin-bottom:1rem!important}.mb-md-4{margin-bottom:1.5rem!important}.mb-md-5{margin-bottom:3rem!important}.mb-md-auto{margin-bottom:auto!important}.ms-md-0{margin-left:0!important}.ms-md-1{margin-left:.25rem!important}.ms-md-2{margin-left:.5rem!important}.ms-md-3{margin-left:1rem!important}.ms-md-4{margin-left:1.5rem!important}.ms-md-5{margin-left:3rem!important}.ms-md-auto{margin-left:auto!important}.p-md-0{padding:0!important}.p-md-1{padding:.25rem!important}.p-md-2{padding:.5rem!important}.p-md-3{padding:1rem!important}.p-md-4{padding:1.5rem!important}.p-md-5{padding:3rem!important}.px-md-0{padding-right:0!important;padding-left:0!important}.px-md-1{padding-right:.25rem!important;padding-left:.25rem!important}.px-md-2{padding-right:.5rem!important;padding-left:.5rem!important}.px-md-3{padding-right:1rem!important;padding-left:1rem!important}.px-md-4{padding-right:1.5rem!important;padding-left:1.5rem!important}.px-md-5{padding-right:3rem!important;padding-left:3rem!important}.py-md-0{padding-top:0!important;padding-bottom:0!important}.py-md-1{padding-top:.25rem!important;padding-bottom:.25rem!important}.py-md-2{padding-top:.5rem!important;padding-bottom:.5rem!important}.py-md-3{padding-top:1rem!important;padding-bottom:1rem!important}.py-md-4{padding-top:1.5rem!important;padding-bottom:1.5rem!important}.py-md-5{padding-top:3rem!important;padding-bottom:3rem!important}.pt-md-0{padding-top:0!important}.pt-md-1{padding-top:.25rem!important}.pt-md-2{padding-top:.5rem!important}.pt-md-3{padding-top:1rem!important}.pt-md-4{padding-top:1.5rem!important}.pt-md-5{padding-top:3rem!important}.pe-md-0{padding-right:0!important}.pe-md-1{padding-right:.25rem!important}.pe-md-2{padding-right:.5rem!important}.pe-md-3{padding-right:1rem!important}.pe-md-4{padding-right:1.5rem!important}.pe-md-5{padding-right:3rem!important}.pb-md-0{padding-bottom:0!important}.pb-md-1{padding-bottom:.25rem!important}.pb-md-2{padding-bottom:.5rem!important}.pb-md-3{padding-bottom:1rem!important}.pb-md-4{padding-bottom:1.5rem!important}.pb-md-5{padding-bottom:3rem!important}.ps-md-0{padding-left:0!important}.ps-md-1{padding-left:.25rem!important}.ps-md-2{padding-left:.5rem!important}.ps-md-3{padding-left:1rem!important}.ps-md-4{padding-left:1.5rem!important}.ps-md-5{padding-left:3rem!important}.gap-md-0{gap:0!important}.gap-md-1{gap:.25rem!important}.gap-md-2{gap:.5rem!important}.gap-md-3{gap:1rem!important}.gap-md-4{gap:1.5rem!important}.gap-md-5{gap:3rem!important}.row-gap-md-0{row-gap:0!important}.row-gap-md-1{row-gap:.25rem!important}.row-gap-md-2{row-gap:.5rem!important}.row-gap-md-3{row-gap:1rem!important}.row-gap-md-4{row-gap:1.5rem!important}.row-gap-md-5{row-gap:3rem!important}.column-gap-md-0{-moz-column-gap:0!important;column-gap:0!important}.column-gap-md-1{-moz-column-gap:0.25rem!important;column-gap:.25rem!important}.column-gap-md-2{-moz-column-gap:0.5rem!important;column-gap:.5rem!important}.column-gap-md-3{-moz-column-gap:1rem!important;column-gap:1rem!important}.column-gap-md-4{-moz-column-gap:1.5rem!important;column-gap:1.5rem!important}.column-gap-md-5{-moz-column-gap:3rem!important;column-gap:3rem!important}.text-md-start{text-align:left!important}.text-md-end{text-align:right!important}.text-md-center{text-align:center!important}}@media (min-width:992px){.float-lg-start{float:left!important}.float-lg-end{float:right!important}.float-lg-none{float:none!important}.object-fit-lg-contain{-o-object-fit:contain!important;object-fit:contain!important}.object-fit-lg-cover{-o-object-fit:cover!important;object-fit:cover!important}.object-fit-lg-fill{-o-object-fit:fill!important;object-fit:fill!important}.object-fit-lg-scale{-o-object-fit:scale-down!important;object-fit:scale-down!important}.object-fit-lg-none{-o-object-fit:none!important;object-fit:none!important}.d-lg-inline{display:inline!important}.d-lg-inline-block{display:inline-block!important}.d-lg-block{display:block!important}.d-lg-grid{display:grid!important}.d-lg-inline-grid{display:inline-grid!important}.d-lg-table{display:table!important}.d-lg-table-row{display:table-row!important}.d-lg-table-cell{display:table-cell!important}.d-lg-flex{display:flex!important}.d-lg-inline-flex{display:inline-flex!important}.d-lg-none{display:none!important}.flex-lg-fill{flex:1 1 auto!important}.flex-lg-row{flex-direction:row!important}.flex-lg-column{flex-direction:column!important}.flex-lg-row-reverse{flex-direction:row-reverse!important}.flex-lg-column-reverse{flex-direction:column-reverse!important}.flex-lg-grow-0{flex-grow:0!important}.flex-lg-grow-1{flex-grow:1!important}.flex-lg-shrink-0{flex-shrink:0!important}.flex-lg-shrink-1{flex-shrink:1!important}.flex-lg-wrap{flex-wrap:wrap!important}.flex-lg-nowrap{flex-wrap:nowrap!important}.flex-lg-wrap-reverse{flex-wrap:wrap-reverse!important}.justify-content-lg-start{justify-content:flex-start!important}.justify-content-lg-end{justify-content:flex-end!important}.justify-content-lg-center{justify-content:center!important}.justify-content-lg-between{justify-content:space-between!important}.justify-content-lg-around{justify-content:space-around!important}.justify-content-lg-evenly{justify-content:space-evenly!important}.align-items-lg-start{align-items:flex-start!important}.align-items-lg-end{align-items:flex-end!important}.align-items-lg-center{align-items:center!important}.align-items-lg-baseline{align-items:baseline!important}.align-items-lg-stretch{align-items:stretch!important}.align-content-lg-start{align-content:flex-start!important}.align-content-lg-end{align-content:flex-end!important}.align-content-lg-center{align-content:center!important}.align-content-lg-between{align-content:space-between!important}.align-content-lg-around{align-content:space-around!important}.align-content-lg-stretch{align-content:stretch!important}.align-self-lg-auto{align-self:auto!important}.align-self-lg-start{align-self:flex-start!important}.align-self-lg-end{align-self:flex-end!important}.align-self-lg-center{align-self:center!important}.align-self-lg-baseline{align-self:baseline!important}.align-self-lg-stretch{align-self:stretch!important}.order-lg-first{order:-1!important}.order-lg-0{order:0!important}.order-lg-1{order:1!important}.order-lg-2{order:2!important}.order-lg-3{order:3!important}.order-lg-4{order:4!important}.order-lg-5{order:5!important}.order-lg-last{order:6!important}.m-lg-0{margin:0!important}.m-lg-1{margin:.25rem!important}.m-lg-2{margin:.5rem!important}.m-lg-3{margin:1rem!important}.m-lg-4{margin:1.5rem!important}.m-lg-5{margin:3rem!important}.m-lg-auto{margin:auto!important}.mx-lg-0{margin-right:0!important;margin-left:0!important}.mx-lg-1{margin-right:.25rem!important;margin-left:.25rem!important}.mx-lg-2{margin-right:.5rem!important;margin-left:.5rem!important}.mx-lg-3{margin-right:1rem!important;margin-left:1rem!important}.mx-lg-4{margin-right:1.5rem!important;margin-left:1.5rem!important}.mx-lg-5{margin-right:3rem!important;margin-left:3rem!important}.mx-lg-auto{margin-right:auto!important;margin-left:auto!important}.my-lg-0{margin-top:0!important;margin-bottom:0!important}.my-lg-1{margin-top:.25rem!important;margin-bottom:.25rem!important}.my-lg-2{margin-top:.5rem!important;margin-bottom:.5rem!important}.my-lg-3{margin-top:1rem!important;margin-bottom:1rem!important}.my-lg-4{margin-top:1.5rem!important;margin-bottom:1.5rem!important}.my-lg-5{margin-top:3rem!important;margin-bottom:3rem!important}.my-lg-auto{margin-top:auto!important;margin-bottom:auto!important}.mt-lg-0{margin-top:0!important}.mt-lg-1{margin-top:.25rem!important}.mt-lg-2{margin-top:.5rem!important}.mt-lg-3{margin-top:1rem!important}.mt-lg-4{margin-top:1.5rem!important}.mt-lg-5{margin-top:3rem!important}.mt-lg-auto{margin-top:auto!important}.me-lg-0{margin-right:0!important}.me-lg-1{margin-right:.25rem!important}.me-lg-2{margin-right:.5rem!important}.me-lg-3{margin-right:1rem!important}.me-lg-4{margin-right:1.5rem!important}.me-lg-5{margin-right:3rem!important}.me-lg-auto{margin-right:auto!important}.mb-lg-0{margin-bottom:0!important}.mb-lg-1{margin-bottom:.25rem!important}.mb-lg-2{margin-bottom:.5rem!important}.mb-lg-3{margin-bottom:1rem!important}.mb-lg-4{margin-bottom:1.5rem!important}.mb-lg-5{margin-bottom:3rem!important}.mb-lg-auto{margin-bottom:auto!important}.ms-lg-0{margin-left:0!important}.ms-lg-1{margin-left:.25rem!important}.ms-lg-2{margin-left:.5rem!important}.ms-lg-3{margin-left:1rem!important}.ms-lg-4{margin-left:1.5rem!important}.ms-lg-5{margin-left:3rem!important}.ms-lg-auto{margin-left:auto!important}.p-lg-0{padding:0!important}.p-lg-1{padding:.25rem!important}.p-lg-2{padding:.5rem!important}.p-lg-3{padding:1rem!important}.p-lg-4{padding:1.5rem!important}.p-lg-5{padding:3rem!important}.px-lg-0{padding-right:0!important;padding-left:0!important}.px-lg-1{padding-right:.25rem!important;padding-left:.25rem!important}.px-lg-2{padding-right:.5rem!important;padding-left:.5rem!important}.px-lg-3{padding-right:1rem!important;padding-left:1rem!important}.px-lg-4{padding-right:1.5rem!important;padding-left:1.5rem!important}.px-lg-5{padding-right:3rem!important;padding-left:3rem!important}.py-lg-0{padding-top:0!important;padding-bottom:0!important}.py-lg-1{padding-top:.25rem!important;padding-bottom:.25rem!important}.py-lg-2{padding-top:.5rem!important;padding-bottom:.5rem!important}.py-lg-3{padding-top:1rem!important;padding-bottom:1rem!important}.py-lg-4{padding-top:1.5rem!important;padding-bottom:1.5rem!important}.py-lg-5{padding-top:3rem!important;padding-bottom:3rem!important}.pt-lg-0{padding-top:0!important}.pt-lg-1{padding-top:.25rem!important}.pt-lg-2{padding-top:.5rem!important}.pt-lg-3{padding-top:1rem!important}.pt-lg-4{padding-top:1.5rem!important}.pt-lg-5{padding-top:3rem!important}.pe-lg-0{padding-right:0!important}.pe-lg-1{padding-right:.25rem!important}.pe-lg-2{padding-right:.5rem!important}.pe-lg-3{padding-right:1rem!important}.pe-lg-4{padding-right:1.5rem!important}.pe-lg-5{padding-right:3rem!important}.pb-lg-0{padding-bottom:0!important}.pb-lg-1{padding-bottom:.25rem!important}.pb-lg-2{padding-bottom:.5rem!important}.pb-lg-3{padding-bottom:1rem!important}.pb-lg-4{padding-bottom:1.5rem!important}.pb-lg-5{padding-bottom:3rem!important}.ps-lg-0{padding-left:0!important}.ps-lg-1{padding-left:.25rem!important}.ps-lg-2{padding-left:.5rem!important}.ps-lg-3{padding-left:1rem!important}.ps-lg-4{padding-left:1.5rem!important}.ps-lg-5{padding-left:3rem!important}.gap-lg-0{gap:0!important}.gap-lg-1{gap:.25rem!important}.gap-lg-2{gap:.5rem!important}.gap-lg-3{gap:1rem!important}.gap-lg-4{gap:1.5rem!important}.gap-lg-5{gap:3rem!important}.row-gap-lg-0{row-gap:0!important}.row-gap-lg-1{row-gap:.25rem!important}.row-gap-lg-2{row-gap:.5rem!important}.row-gap-lg-3{row-gap:1rem!important}.row-gap-lg-4{row-gap:1.5rem!important}.row-gap-lg-5{row-gap:3rem!important}.column-gap-lg-0{-moz-column-gap:0!important;column-gap:0!important}.column-gap-lg-1{-moz-column-gap:0.25rem!important;column-gap:.25rem!important}.column-gap-lg-2{-moz-column-gap:0.5rem!important;column-gap:.5rem!important}.column-gap-lg-3{-moz-column-gap:1rem!important;column-gap:1rem!important}.column-gap-lg-4{-moz-column-gap:1.5rem!important;column-gap:1.5rem!important}.column-gap-lg-5{-moz-column-gap:3rem!important;column-gap:3rem!important}.text-lg-start{text-align:left!important}.text-lg-end{text-align:right!important}.text-lg-center{text-align:center!important}}@media (min-width:1200px){.float-xl-start{float:left!important}.float-xl-end{float:right!important}.float-xl-none{float:none!important}.object-fit-xl-contain{-o-object-fit:contain!important;object-fit:contain!important}.object-fit-xl-cover{-o-object-fit:cover!important;object-fit:cover!important}.object-fit-xl-fill{-o-object-fit:fill!important;object-fit:fill!important}.object-fit-xl-scale{-o-object-fit:scale-down!important;object-fit:scale-down!important}.object-fit-xl-none{-o-object-fit:none!important;object-fit:none!important}.d-xl-inline{display:inline!important}.d-xl-inline-block{display:inline-block!important}.d-xl-block{display:block!important}.d-xl-grid{display:grid!important}.d-xl-inline-grid{display:inline-grid!important}.d-xl-table{display:table!important}.d-xl-table-row{display:table-row!important}.d-xl-table-cell{display:table-cell!important}.d-xl-flex{display:flex!important}.d-xl-inline-flex{display:inline-flex!important}.d-xl-none{display:none!important}.flex-xl-fill{flex:1 1 auto!important}.flex-xl-row{flex-direction:row!important}.flex-xl-column{flex-direction:column!important}.flex-xl-row-reverse{flex-direction:row-reverse!important}.flex-xl-column-reverse{flex-direction:column-reverse!important}.flex-xl-grow-0{flex-grow:0!important}.flex-xl-grow-1{flex-grow:1!important}.flex-xl-shrink-0{flex-shrink:0!important}.flex-xl-shrink-1{flex-shrink:1!important}.flex-xl-wrap{flex-wrap:wrap!important}.flex-xl-nowrap{flex-wrap:nowrap!important}.flex-xl-wrap-reverse{flex-wrap:wrap-reverse!important}.justify-content-xl-start{justify-content:flex-start!important}.justify-content-xl-end{justify-content:flex-end!important}.justify-content-xl-center{justify-content:center!important}.justify-content-xl-between{justify-content:space-between!important}.justify-content-xl-around{justify-content:space-around!important}.justify-content-xl-evenly{justify-content:space-evenly!important}.align-items-xl-start{align-items:flex-start!important}.align-items-xl-end{align-items:flex-end!important}.align-items-xl-center{align-items:center!important}.align-items-xl-baseline{align-items:baseline!important}.align-items-xl-stretch{align-items:stretch!important}.align-content-xl-start{align-content:flex-start!important}.align-content-xl-end{align-content:flex-end!important}.align-content-xl-center{align-content:center!important}.align-content-xl-between{align-content:space-between!important}.align-content-xl-around{align-content:space-around!important}.align-content-xl-stretch{align-content:stretch!important}.align-self-xl-auto{align-self:auto!important}.align-self-xl-start{align-self:flex-start!important}.align-self-xl-end{align-self:flex-end!important}.align-self-xl-center{align-self:center!important}.align-self-xl-baseline{align-self:baseline!important}.align-self-xl-stretch{align-self:stretch!important}.order-xl-first{order:-1!important}.order-xl-0{order:0!important}.order-xl-1{order:1!important}.order-xl-2{order:2!important}.order-xl-3{order:3!important}.order-xl-4{order:4!important}.order-xl-5{order:5!important}.order-xl-last{order:6!important}.m-xl-0{margin:0!important}.m-xl-1{margin:.25rem!important}.m-xl-2{margin:.5rem!important}.m-xl-3{margin:1rem!important}.m-xl-4{margin:1.5rem!important}.m-xl-5{margin:3rem!important}.m-xl-auto{margin:auto!important}.mx-xl-0{margin-right:0!important;margin-left:0!important}.mx-xl-1{margin-right:.25rem!important;margin-left:.25rem!important}.mx-xl-2{margin-right:.5rem!important;margin-left:.5rem!important}.mx-xl-3{margin-right:1rem!important;margin-left:1rem!important}.mx-xl-4{margin-right:1.5rem!important;margin-left:1.5rem!important}.mx-xl-5{margin-right:3rem!important;margin-left:3rem!important}.mx-xl-auto{margin-right:auto!important;margin-left:auto!important}.my-xl-0{margin-top:0!important;margin-bottom:0!important}.my-xl-1{margin-top:.25rem!important;margin-bottom:.25rem!important}.my-xl-2{margin-top:.5rem!important;margin-bottom:.5rem!important}.my-xl-3{margin-top:1rem!important;margin-bottom:1rem!important}.my-xl-4{margin-top:1.5rem!important;margin-bottom:1.5rem!important}.my-xl-5{margin-top:3rem!important;margin-bottom:3rem!important}.my-xl-auto{margin-top:auto!important;margin-bottom:auto!important}.mt-xl-0{margin-top:0!important}.mt-xl-1{margin-top:.25rem!important}.mt-xl-2{margin-top:.5rem!important}.mt-xl-3{margin-top:1rem!important}.mt-xl-4{margin-top:1.5rem!important}.mt-xl-5{margin-top:3rem!important}.mt-xl-auto{margin-top:auto!important}.me-xl-0{margin-right:0!important}.me-xl-1{margin-right:.25rem!important}.me-xl-2{margin-right:.5rem!important}.me-xl-3{margin-right:1rem!important}.me-xl-4{margin-right:1.5rem!important}.me-xl-5{margin-right:3rem!important}.me-xl-auto{margin-right:auto!important}.mb-xl-0{margin-bottom:0!important}.mb-xl-1{margin-bottom:.25rem!important}.mb-xl-2{margin-bottom:.5rem!important}.mb-xl-3{margin-bottom:1rem!important}.mb-xl-4{margin-bottom:1.5rem!important}.mb-xl-5{margin-bottom:3rem!important}.mb-xl-auto{margin-bottom:auto!important}.ms-xl-0{margin-left:0!important}.ms-xl-1{margin-left:.25rem!important}.ms-xl-2{margin-left:.5rem!important}.ms-xl-3{margin-left:1rem!important}.ms-xl-4{margin-left:1.5rem!important}.ms-xl-5{margin-left:3rem!important}.ms-xl-auto{margin-left:auto!important}.p-xl-0{padding:0!important}.p-xl-1{padding:.25rem!important}.p-xl-2{padding:.5rem!important}.p-xl-3{padding:1rem!important}.p-xl-4{padding:1.5rem!important}.p-xl-5{padding:3rem!important}.px-xl-0{padding-right:0!important;padding-left:0!important}.px-xl-1{padding-right:.25rem!important;padding-left:.25rem!important}.px-xl-2{padding-right:.5rem!important;padding-left:.5rem!important}.px-xl-3{padding-right:1rem!important;padding-left:1rem!important}.px-xl-4{padding-right:1.5rem!important;padding-left:1.5rem!important}.px-xl-5{padding-right:3rem!important;padding-left:3rem!important}.py-xl-0{padding-top:0!important;padding-bottom:0!important}.py-xl-1{padding-top:.25rem!important;padding-bottom:.25rem!important}.py-xl-2{padding-top:.5rem!important;padding-bottom:.5rem!important}.py-xl-3{padding-top:1rem!important;padding-bottom:1rem!important}.py-xl-4{padding-top:1.5rem!important;padding-bottom:1.5rem!important}.py-xl-5{padding-top:3rem!important;padding-bottom:3rem!important}.pt-xl-0{padding-top:0!important}.pt-xl-1{padding-top:.25rem!important}.pt-xl-2{padding-top:.5rem!important}.pt-xl-3{padding-top:1rem!important}.pt-xl-4{padding-top:1.5rem!important}.pt-xl-5{padding-top:3rem!important}.pe-xl-0{padding-right:0!important}.pe-xl-1{padding-right:.25rem!important}.pe-xl-2{padding-right:.5rem!important}.pe-xl-3{padding-right:1rem!important}.pe-xl-4{padding-right:1.5rem!important}.pe-xl-5{padding-right:3rem!important}.pb-xl-0{padding-bottom:0!important}.pb-xl-1{padding-bottom:.25rem!important}.pb-xl-2{padding-bottom:.5rem!important}.pb-xl-3{padding-bottom:1rem!important}.pb-xl-4{padding-bottom:1.5rem!important}.pb-xl-5{padding-bottom:3rem!important}.ps-xl-0{padding-left:0!important}.ps-xl-1{padding-left:.25rem!important}.ps-xl-2{padding-left:.5rem!important}.ps-xl-3{padding-left:1rem!important}.ps-xl-4{padding-left:1.5rem!important}.ps-xl-5{padding-left:3rem!important}.gap-xl-0{gap:0!important}.gap-xl-1{gap:.25rem!important}.gap-xl-2{gap:.5rem!important}.gap-xl-3{gap:1rem!important}.gap-xl-4{gap:1.5rem!important}.gap-xl-5{gap:3rem!important}.row-gap-xl-0{row-gap:0!important}.row-gap-xl-1{row-gap:.25rem!important}.row-gap-xl-2{row-gap:.5rem!important}.row-gap-xl-3{row-gap:1rem!important}.row-gap-xl-4{row-gap:1.5rem!important}.row-gap-xl-5{row-gap:3rem!important}.column-gap-xl-0{-moz-column-gap:0!important;column-gap:0!important}.column-gap-xl-1{-moz-column-gap:0.25rem!important;column-gap:.25rem!important}.column-gap-xl-2{-moz-column-gap:0.5rem!important;column-gap:.5rem!important}.column-gap-xl-3{-moz-column-gap:1rem!important;column-gap:1rem!important}.column-gap-xl-4{-moz-column-gap:1.5rem!important;column-gap:1.5rem!important}.column-gap-xl-5{-moz-column-gap:3rem!important;column-gap:3rem!important}.text-xl-start{text-align:left!important}.text-xl-end{text-align:right!important}.text-xl-center{text-align:center!important}}@media (min-width:1400px){.float-xxl-start{float:left!important}.float-xxl-end{float:right!important}.float-xxl-none{float:none!important}.object-fit-xxl-contain{-o-object-fit:contain!important;object-fit:contain!important}.object-fit-xxl-cover{-o-object-fit:cover!important;object-fit:cover!important}.object-fit-xxl-fill{-o-object-fit:fill!important;object-fit:fill!important}.object-fit-xxl-scale{-o-object-fit:scale-down!important;object-fit:scale-down!important}.object-fit-xxl-none{-o-object-fit:none!important;object-fit:none!important}.d-xxl-inline{display:inline!important}.d-xxl-inline-block{display:inline-block!important}.d-xxl-block{display:block!important}.d-xxl-grid{display:grid!important}.d-xxl-inline-grid{display:inline-grid!important}.d-xxl-table{display:table!important}.d-xxl-table-row{display:table-row!important}.d-xxl-table-cell{display:table-cell!important}.d-xxl-flex{display:flex!important}.d-xxl-inline-flex{display:inline-flex!important}.d-xxl-none{display:none!important}.flex-xxl-fill{flex:1 1 auto!important}.flex-xxl-row{flex-direction:row!important}.flex-xxl-column{flex-direction:column!important}.flex-xxl-row-reverse{flex-direction:row-reverse!important}.flex-xxl-column-reverse{flex-direction:column-reverse!important}.flex-xxl-grow-0{flex-grow:0!important}.flex-xxl-grow-1{flex-grow:1!important}.flex-xxl-shrink-0{flex-shrink:0!important}.flex-xxl-shrink-1{flex-shrink:1!important}.flex-xxl-wrap{flex-wrap:wrap!important}.flex-xxl-nowrap{flex-wrap:nowrap!important}.flex-xxl-wrap-reverse{flex-wrap:wrap-reverse!important}.justify-content-xxl-start{justify-content:flex-start!important}.justify-content-xxl-end{justify-content:flex-end!important}.justify-content-xxl-center{justify-content:center!important}.justify-content-xxl-between{justify-content:space-between!important}.justify-content-xxl-around{justify-content:space-around!important}.justify-content-xxl-evenly{justify-content:space-evenly!important}.align-items-xxl-start{align-items:flex-start!important}.align-items-xxl-end{align-items:flex-end!important}.align-items-xxl-center{align-items:center!important}.align-items-xxl-baseline{align-items:baseline!important}.align-items-xxl-stretch{align-items:stretch!important}.align-content-xxl-start{align-content:flex-start!important}.align-content-xxl-end{align-content:flex-end!important}.align-content-xxl-center{align-content:center!important}.align-content-xxl-between{align-content:space-between!important}.align-content-xxl-around{align-content:space-around!important}.align-content-xxl-stretch{align-content:stretch!important}.align-self-xxl-auto{align-self:auto!important}.align-self-xxl-start{align-self:flex-start!important}.align-self-xxl-end{align-self:flex-end!important}.align-self-xxl-center{align-self:center!important}.align-self-xxl-baseline{align-self:baseline!important}.align-self-xxl-stretch{align-self:stretch!important}.order-xxl-first{order:-1!important}.order-xxl-0{order:0!important}.order-xxl-1{order:1!important}.order-xxl-2{order:2!important}.order-xxl-3{order:3!important}.order-xxl-4{order:4!important}.order-xxl-5{order:5!important}.order-xxl-last{order:6!important}.m-xxl-0{margin:0!important}.m-xxl-1{margin:.25rem!important}.m-xxl-2{margin:.5rem!important}.m-xxl-3{margin:1rem!important}.m-xxl-4{margin:1.5rem!important}.m-xxl-5{margin:3rem!important}.m-xxl-auto{margin:auto!important}.mx-xxl-0{margin-right:0!important;margin-left:0!important}.mx-xxl-1{margin-right:.25rem!important;margin-left:.25rem!important}.mx-xxl-2{margin-right:.5rem!important;margin-left:.5rem!important}.mx-xxl-3{margin-right:1rem!important;margin-left:1rem!important}.mx-xxl-4{margin-right:1.5rem!important;margin-left:1.5rem!important}.mx-xxl-5{margin-right:3rem!important;margin-left:3rem!important}.mx-xxl-auto{margin-right:auto!important;margin-left:auto!important}.my-xxl-0{margin-top:0!important;margin-bottom:0!important}.my-xxl-1{margin-top:.25rem!important;margin-bottom:.25rem!important}.my-xxl-2{margin-top:.5rem!important;margin-bottom:.5rem!important}.my-xxl-3{margin-top:1rem!important;margin-bottom:1rem!important}.my-xxl-4{margin-top:1.5rem!important;margin-bottom:1.5rem!important}.my-xxl-5{margin-top:3rem!important;margin-bottom:3rem!important}.my-xxl-auto{margin-top:auto!important;margin-bottom:auto!important}.mt-xxl-0{margin-top:0!important}.mt-xxl-1{margin-top:.25rem!important}.mt-xxl-2{margin-top:.5rem!important}.mt-xxl-3{margin-top:1rem!important}.mt-xxl-4{margin-top:1.5rem!important}.mt-xxl-5{margin-top:3rem!important}.mt-xxl-auto{margin-top:auto!important}.me-xxl-0{margin-right:0!important}.me-xxl-1{margin-right:.25rem!important}.me-xxl-2{margin-right:.5rem!important}.me-xxl-3{margin-right:1rem!important}.me-xxl-4{margin-right:1.5rem!important}.me-xxl-5{margin-right:3rem!important}.me-xxl-auto{margin-right:auto!important}.mb-xxl-0{margin-bottom:0!important}.mb-xxl-1{margin-bottom:.25rem!important}.mb-xxl-2{margin-bottom:.5rem!important}.mb-xxl-3{margin-bottom:1rem!important}.mb-xxl-4{margin-bottom:1.5rem!important}.mb-xxl-5{margin-bottom:3rem!important}.mb-xxl-auto{margin-bottom:auto!important}.ms-xxl-0{margin-left:0!important}.ms-xxl-1{margin-left:.25rem!important}.ms-xxl-2{margin-left:.5rem!important}.ms-xxl-3{margin-left:1rem!important}.ms-xxl-4{margin-left:1.5rem!important}.ms-xxl-5{margin-left:3rem!important}.ms-xxl-auto{margin-left:auto!important}.p-xxl-0{padding:0!important}.p-xxl-1{padding:.25rem!important}.p-xxl-2{padding:.5rem!important}.p-xxl-3{padding:1rem!important}.p-xxl-4{padding:1.5rem!important}.p-xxl-5{padding:3rem!important}.px-xxl-0{padding-right:0!important;padding-left:0!important}.px-xxl-1{padding-right:.25rem!important;padding-left:.25rem!important}.px-xxl-2{padding-right:.5rem!important;padding-left:.5rem!important}.px-xxl-3{padding-right:1rem!important;padding-left:1rem!important}.px-xxl-4{padding-right:1.5rem!important;padding-left:1.5rem!important}.px-xxl-5{padding-right:3rem!important;padding-left:3rem!important}.py-xxl-0{padding-top:0!important;padding-bottom:0!important}.py-xxl-1{padding-top:.25rem!important;padding-bottom:.25rem!important}.py-xxl-2{padding-top:.5rem!important;padding-bottom:.5rem!important}.py-xxl-3{padding-top:1rem!important;padding-bottom:1rem!important}.py-xxl-4{padding-top:1.5rem!important;padding-bottom:1.5rem!important}.py-xxl-5{padding-top:3rem!important;padding-bottom:3rem!important}.pt-xxl-0{padding-top:0!important}.pt-xxl-1{padding-top:.25rem!important}.pt-xxl-2{padding-top:.5rem!important}.pt-xxl-3{padding-top:1rem!important}.pt-xxl-4{padding-top:1.5rem!important}.pt-xxl-5{padding-top:3rem!important}.pe-xxl-0{padding-right:0!important}.pe-xxl-1{padding-right:.25rem!important}.pe-xxl-2{padding-right:.5rem!important}.pe-xxl-3{padding-right:1rem!important}.pe-xxl-4{padding-right:1.5rem!important}.pe-xxl-5{padding-right:3rem!important}.pb-xxl-0{padding-bottom:0!important}.pb-xxl-1{padding-bottom:.25rem!important}.pb-xxl-2{padding-bottom:.5rem!important}.pb-xxl-3{padding-bottom:1rem!important}.pb-xxl-4{padding-bottom:1.5rem!important}.pb-xxl-5{padding-bottom:3rem!important}.ps-xxl-0{padding-left:0!important}.ps-xxl-1{padding-left:.25rem!important}.ps-xxl-2{padding-left:.5rem!important}.ps-xxl-3{padding-left:1rem!important}.ps-xxl-4{padding-left:1.5rem!important}.ps-xxl-5{padding-left:3rem!important}.gap-xxl-0{gap:0!important}.gap-xxl-1{gap:.25rem!important}.gap-xxl-2{gap:.5rem!important}.gap-xxl-3{gap:1rem!important}.gap-xxl-4{gap:1.5rem!important}.gap-xxl-5{gap:3rem!important}.row-gap-xxl-0{row-gap:0!important}.row-gap-xxl-1{row-gap:.25rem!important}.row-gap-xxl-2{row-gap:.5rem!important}.row-gap-xxl-3{row-gap:1rem!important}.row-gap-xxl-4{row-gap:1.5rem!important}.row-gap-xxl-5{row-gap:3rem!important}.column-gap-xxl-0{-moz-column-gap:0!important;column-gap:0!important}.column-gap-xxl-1{-moz-column-gap:0.25rem!important;column-gap:.25rem!important}.column-gap-xxl-2{-moz-column-gap:0.5rem!important;column-gap:.5rem!important}.column-gap-xxl-3{-moz-column-gap:1rem!important;column-gap:1rem!important}.column-gap-xxl-4{-moz-column-gap:1.5rem!important;column-gap:1.5rem!important}.column-gap-xxl-5{-moz-column-gap:3rem!important;column-gap:3rem!important}.text-xxl-start{text-align:left!important}.text-xxl-end{text-align:right!important}.text-xxl-center{text-align:center!important}}@media (min-width:1200px){.fs-1{font-size:2.5rem!important}.fs-2{font-size:2rem!important}.fs-3{font-size:1.75rem!important}.fs-4{font-size:1.5rem!important}}@media print{.d-print-inline{display:inline!important}.d-print-inline-block{display:inline-block!important}.d-print-block{display:block!important}.d-print-grid{display:grid!important}.d-print-inline-grid{display:inline-grid!important}.d-print-table{display:table!important}.d-print-table-row{display:table-row!important}.d-print-table-cell{display:table-cell!important}.d-print-flex{display:flex!important}.d-print-inline-flex{display:inline-flex!important}.d-print-none{display:none!important}} -/*# sourceMappingURL=bootstrap.min.css.map */ \ No newline at end of file diff --git a/backend/coverage-report-with-models/_css/custom.css b/backend/coverage-report-with-models/_css/custom.css deleted file mode 100644 index e69de29b..00000000 diff --git a/backend/coverage-report-with-models/_css/nv.d3.min.css b/backend/coverage-report-with-models/_css/nv.d3.min.css deleted file mode 100644 index 7a6f7fe9..00000000 --- a/backend/coverage-report-with-models/_css/nv.d3.min.css +++ /dev/null @@ -1 +0,0 @@ -.nvd3 .nv-axis{pointer-events:none;opacity:1}.nvd3 .nv-axis path{fill:none;stroke:#000;stroke-opacity:.75;shape-rendering:crispEdges}.nvd3 .nv-axis path.domain{stroke-opacity:.75}.nvd3 .nv-axis.nv-x path.domain{stroke-opacity:0}.nvd3 .nv-axis line{fill:none;stroke:#e5e5e5;shape-rendering:crispEdges}.nvd3 .nv-axis .zero line,.nvd3 .nv-axis line.zero{stroke-opacity:.75}.nvd3 .nv-axis .nv-axisMaxMin text{font-weight:700}.nvd3 .x .nv-axis .nv-axisMaxMin text,.nvd3 .x2 .nv-axis .nv-axisMaxMin text,.nvd3 .x3 .nv-axis .nv-axisMaxMin text{text-anchor:middle}.nvd3 .nv-axis.nv-disabled{opacity:0}.nvd3 .nv-bars rect{fill-opacity:.75;transition:fill-opacity 250ms linear;-moz-transition:fill-opacity 250ms linear;-webkit-transition:fill-opacity 250ms linear}.nvd3 .nv-bars rect.hover{fill-opacity:1}.nvd3 .nv-bars .hover rect{fill:#add8e6}.nvd3 .nv-bars text{fill:rgba(0,0,0,0)}.nvd3 .nv-bars .hover text{fill:rgba(0,0,0,1)}.nvd3 .nv-multibar .nv-groups rect,.nvd3 .nv-multibarHorizontal .nv-groups rect,.nvd3 .nv-discretebar .nv-groups rect{stroke-opacity:0;transition:fill-opacity 250ms linear;-moz-transition:fill-opacity 250ms linear;-webkit-transition:fill-opacity 250ms linear}.nvd3 .nv-multibar .nv-groups rect:hover,.nvd3 .nv-multibarHorizontal .nv-groups rect:hover,.nvd3 .nv-candlestickBar .nv-ticks rect:hover,.nvd3 .nv-discretebar .nv-groups rect:hover{fill-opacity:1}.nvd3 .nv-discretebar .nv-groups text,.nvd3 .nv-multibarHorizontal .nv-groups text{font-weight:700;fill:rgba(0,0,0,1);stroke:rgba(0,0,0,0)}.nvd3 .nv-boxplot circle{fill-opacity:.5}.nvd3 .nv-boxplot circle:hover{fill-opacity:1}.nvd3 .nv-boxplot rect:hover{fill-opacity:1}.nvd3 line.nv-boxplot-median{stroke:#000}.nv-boxplot-tick:hover{stroke-width:2.5px}.nvd3.nv-bullet{font:10px sans-serif}.nvd3.nv-bullet .nv-measure{fill-opacity:.8}.nvd3.nv-bullet .nv-measure:hover{fill-opacity:1}.nvd3.nv-bullet .nv-marker{stroke:#000;stroke-width:2px}.nvd3.nv-bullet .nv-markerTriangle{stroke:#000;fill:#fff;stroke-width:1.5px}.nvd3.nv-bullet .nv-tick line{stroke:#666;stroke-width:.5px}.nvd3.nv-bullet .nv-range.nv-s0{fill:#eee}.nvd3.nv-bullet .nv-range.nv-s1{fill:#ddd}.nvd3.nv-bullet .nv-range.nv-s2{fill:#ccc}.nvd3.nv-bullet .nv-title{font-size:14px;font-weight:700}.nvd3.nv-bullet .nv-subtitle{fill:#999}.nvd3.nv-bullet .nv-range{fill:#bababa;fill-opacity:.4}.nvd3.nv-bullet .nv-range:hover{fill-opacity:.7}.nvd3.nv-candlestickBar .nv-ticks .nv-tick{stroke-width:1px}.nvd3.nv-candlestickBar .nv-ticks .nv-tick.hover{stroke-width:2px}.nvd3.nv-candlestickBar .nv-ticks .nv-tick.positive rect{stroke:#2ca02c;fill:#2ca02c}.nvd3.nv-candlestickBar .nv-ticks .nv-tick.negative rect{stroke:#d62728;fill:#d62728}.with-transitions .nv-candlestickBar .nv-ticks .nv-tick{transition:stroke-width 250ms linear,stroke-opacity 250ms linear;-moz-transition:stroke-width 250ms linear,stroke-opacity 250ms linear;-webkit-transition:stroke-width 250ms linear,stroke-opacity 250ms linear}.nvd3.nv-candlestickBar .nv-ticks line{stroke:#333}.nvd3 .nv-legend .nv-disabled rect{}.nvd3 .nv-check-box .nv-box{fill-opacity:0;stroke-width:2}.nvd3 .nv-check-box .nv-check{fill-opacity:0;stroke-width:4}.nvd3 .nv-series.nv-disabled .nv-check-box .nv-check{fill-opacity:0;stroke-opacity:0}.nvd3 .nv-controlsWrap .nv-legend .nv-check-box .nv-check{opacity:0}.nvd3.nv-linePlusBar .nv-bar rect{fill-opacity:.75}.nvd3.nv-linePlusBar .nv-bar rect:hover{fill-opacity:1}.nvd3 .nv-groups path.nv-line{fill:none}.nvd3 .nv-groups path.nv-area{stroke:none}.nvd3.nv-line .nvd3.nv-scatter .nv-groups .nv-point{fill-opacity:0;stroke-opacity:0}.nvd3.nv-scatter.nv-single-point .nv-groups .nv-point{fill-opacity:.5!important;stroke-opacity:.5!important}.with-transitions .nvd3 .nv-groups .nv-point{transition:stroke-width 250ms linear,stroke-opacity 250ms linear;-moz-transition:stroke-width 250ms linear,stroke-opacity 250ms linear;-webkit-transition:stroke-width 250ms linear,stroke-opacity 250ms linear}.nvd3.nv-scatter .nv-groups .nv-point.hover,.nvd3 .nv-groups .nv-point.hover{stroke-width:7px;fill-opacity:.95!important;stroke-opacity:.95!important}.nvd3 .nv-point-paths path{stroke:#aaa;stroke-opacity:0;fill:#eee;fill-opacity:0}.nvd3 .nv-indexLine{cursor:ew-resize}svg.nvd3-svg{-webkit-touch-callout:none;-webkit-user-select:none;-khtml-user-select:none;-ms-user-select:none;-moz-user-select:none;user-select:none;display:block;width:100%;height:100%}.nvtooltip.with-3d-shadow,.with-3d-shadow .nvtooltip{-moz-box-shadow:0 5px 10px rgba(0,0,0,.2);-webkit-box-shadow:0 5px 10px rgba(0,0,0,.2);box-shadow:0 5px 10px rgba(0,0,0,.2);-webkit-border-radius:5px;-moz-border-radius:5px;border-radius:5px}.nvd3 text{font:400 12px Arial}.nvd3 .title{font:700 14px Arial}.nvd3 .nv-background{fill:#fff;fill-opacity:0}.nvd3.nv-noData{font-size:18px;font-weight:700}.nv-brush .extent{fill-opacity:.125;shape-rendering:crispEdges}.nv-brush .resize path{fill:#eee;stroke:#666}.nvd3 .nv-legend .nv-series{cursor:pointer}.nvd3 .nv-legend .nv-disabled circle{fill-opacity:0}.nvd3 .nv-brush .extent{fill-opacity:0!important}.nvd3 .nv-brushBackground rect{stroke:#000;stroke-width:.4;fill:#fff;fill-opacity:.7}.nvd3.nv-ohlcBar .nv-ticks .nv-tick{stroke-width:1px}.nvd3.nv-ohlcBar .nv-ticks .nv-tick.hover{stroke-width:2px}.nvd3.nv-ohlcBar .nv-ticks .nv-tick.positive{stroke:#2ca02c}.nvd3.nv-ohlcBar .nv-ticks .nv-tick.negative{stroke:#d62728}.nvd3 .background path{fill:none;stroke:#EEE;stroke-opacity:.4;shape-rendering:crispEdges}.nvd3 .foreground path{fill:none;stroke-opacity:.7}.nvd3 .nv-parallelCoordinates-brush .extent{fill:#fff;fill-opacity:.6;stroke:gray;shape-rendering:crispEdges}.nvd3 .nv-parallelCoordinates .hover{fill-opacity:1;stroke-width:3px}.nvd3 .missingValuesline line{fill:none;stroke:#000;stroke-width:1;stroke-opacity:1;stroke-dasharray:5,5}.nvd3.nv-pie path{stroke-opacity:0;transition:fill-opacity 250ms linear,stroke-width 250ms linear,stroke-opacity 250ms linear;-moz-transition:fill-opacity 250ms linear,stroke-width 250ms linear,stroke-opacity 250ms linear;-webkit-transition:fill-opacity 250ms linear,stroke-width 250ms linear,stroke-opacity 250ms linear}.nvd3.nv-pie .nv-pie-title{font-size:24px;fill:rgba(19,196,249,.59)}.nvd3.nv-pie .nv-slice text{stroke:#000;stroke-width:0}.nvd3.nv-pie path{stroke:#fff;stroke-width:1px;stroke-opacity:1}.nvd3.nv-pie .hover path{fill-opacity:.7}.nvd3.nv-pie .nv-label{pointer-events:none}.nvd3.nv-pie .nv-label rect{fill-opacity:0;stroke-opacity:0}.nvd3 .nv-groups .nv-point.hover{stroke-width:20px;stroke-opacity:.5}.nvd3 .nv-scatter .nv-point.hover{fill-opacity:1}.nv-noninteractive{pointer-events:none}.nv-distx,.nv-disty{pointer-events:none}.nvd3.nv-sparkline path{fill:none}.nvd3.nv-sparklineplus g.nv-hoverValue{pointer-events:none}.nvd3.nv-sparklineplus .nv-hoverValue line{stroke:#333;stroke-width:1.5px}.nvd3.nv-sparklineplus,.nvd3.nv-sparklineplus g{pointer-events:all}.nvd3 .nv-hoverArea{fill-opacity:0;stroke-opacity:0}.nvd3.nv-sparklineplus .nv-xValue,.nvd3.nv-sparklineplus .nv-yValue{stroke-width:0;font-size:.9em;font-weight:400}.nvd3.nv-sparklineplus .nv-yValue{stroke:#f66}.nvd3.nv-sparklineplus .nv-maxValue{stroke:#2ca02c;fill:#2ca02c}.nvd3.nv-sparklineplus .nv-minValue{stroke:#d62728;fill:#d62728}.nvd3.nv-sparklineplus .nv-currentValue{font-weight:700;font-size:1.1em}.nvd3.nv-stackedarea path.nv-area{fill-opacity:.7;stroke-opacity:0;transition:fill-opacity 250ms linear,stroke-opacity 250ms linear;-moz-transition:fill-opacity 250ms linear,stroke-opacity 250ms linear;-webkit-transition:fill-opacity 250ms linear,stroke-opacity 250ms linear}.nvd3.nv-stackedarea path.nv-area.hover{fill-opacity:.9}.nvd3.nv-stackedarea .nv-groups .nv-point{stroke-opacity:0;fill-opacity:0}.nvtooltip{position:absolute;background-color:rgba(255,255,255,1);color:rgba(0,0,0,1);padding:1px;border:1px solid rgba(0,0,0,.2);z-index:10000;display:block;font-family:Arial;font-size:13px;text-align:left;pointer-events:none;white-space:nowrap;-webkit-touch-callout:none;-webkit-user-select:none;-khtml-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.nvtooltip{background:rgba(255,255,255,.8);border:1px solid rgba(0,0,0,.5);border-radius:4px}.nvtooltip.with-transitions,.with-transitions .nvtooltip{transition:opacity 50ms linear;-moz-transition:opacity 50ms linear;-webkit-transition:opacity 50ms linear;transition-delay:200ms;-moz-transition-delay:200ms;-webkit-transition-delay:200ms}.nvtooltip.x-nvtooltip,.nvtooltip.y-nvtooltip{padding:8px}.nvtooltip h3{margin:0;padding:4px 14px;line-height:18px;font-weight:400;background-color:rgba(247,247,247,.75);color:rgba(0,0,0,1);text-align:center;border-bottom:1px solid #ebebeb;-webkit-border-radius:5px 5px 0 0;-moz-border-radius:5px 5px 0 0;border-radius:5px 5px 0 0}.nvtooltip p{margin:0;padding:5px 14px;text-align:center}.nvtooltip span{display:inline-block;margin:2px 0}.nvtooltip table{margin:6px;border-spacing:0}.nvtooltip table td{padding:2px 9px 2px 0;vertical-align:middle}.nvtooltip table td.key{font-weight:400}.nvtooltip table td.value{text-align:right;font-weight:700}.nvtooltip table tr.highlight td{padding:1px 9px 1px 0;border-bottom-style:solid;border-bottom-width:1px;border-top-style:solid;border-top-width:1px}.nvtooltip table td.legend-color-guide div{width:8px;height:8px;vertical-align:middle}.nvtooltip table td.legend-color-guide div{width:12px;height:12px;border:1px solid #999}.nvtooltip .footer{padding:3px;text-align:center}.nvtooltip-pending-removal{pointer-events:none;display:none}.nvd3 .nv-interactiveGuideLine{pointer-events:none}.nvd3 line.nv-guideline{stroke:#ccc} \ No newline at end of file diff --git a/backend/coverage-report-with-models/_css/octicons.css b/backend/coverage-report-with-models/_css/octicons.css deleted file mode 100644 index 31d97867..00000000 --- a/backend/coverage-report-with-models/_css/octicons.css +++ /dev/null @@ -1,5 +0,0 @@ -.octicon { - display: inline-block; - vertical-align: text-top; - fill: currentColor; -} diff --git a/backend/coverage-report-with-models/_css/style.css b/backend/coverage-report-with-models/_css/style.css deleted file mode 100644 index b007558e..00000000 --- a/backend/coverage-report-with-models/_css/style.css +++ /dev/null @@ -1,201 +0,0 @@ -:root { - --phpunit-breadcrumbs: var(--bs-gray-200); - --phpunit-success-bar: #28a745; - --phpunit-success-high: #99cb84; - --phpunit-success-medium: #c3e3b5; - --phpunit-success-low: #dff0d8; - --phpunit-warning: #fcf8e3; - --phpunit-warning-bar: #ffc107; - --phpunit-danger: #f2dede; - --phpunit-danger-bar: #dc3545; -} - -body { - font-family: sans-serif; - font-size: 1em; - font-kerning: normal; - text-rendering: optimizeLegibility; - padding-top: 10px; -} - -nav .breadcrumb { - border-radius: var(--bs-border-radius); - background-color: var(--phpunit-breadcrumbs); - padding: .75rem 1rem; -} - -.popover { - max-width: none; -} - -.popover-body { - max-height: 90vh; - overflow-y: auto; -} - -.octicon { - margin-right:.25em; - vertical-align: baseline; - width: 0.75em; -} - -.table-bordered>thead>tr>td { - border-bottom-width: 1px; -} - -.table tbody>tr>td, .table thead>tr>td { - padding-top: 3px; - padding-bottom: 3px; -} - -.table-condensed tbody>tr>td { - padding-top: 0; - padding-bottom: 0; -} - -.table .progress { - margin-bottom: inherit; -} - -.table-borderless th, .table-borderless td { - border: 0 !important; -} - -.table tbody tr.covered-by-large-tests, .table tbody tr.covered-by-large-tests td, li.covered-by-large-tests, tr.success, tr.success td, td.success, li.success, span.success { - background-color: var(--phpunit-success-low); -} - -.table tbody tr.covered-by-medium-tests, .table tbody tr.covered-by-medium-tests td, li.covered-by-medium-tests { - background-color: var(--phpunit-success-medium); -} - -.table tbody tr.covered-by-small-tests, .table tbody tr.covered-by-small-tests td, li.covered-by-small-tests { - background-color: var(--phpunit-success-high); -} - -.table tbody tr.warning, .table tbody tr.warning td, .table tbody td.warning, li.warning, span.warning { - background-color: var(--phpunit-warning); -} - -.table tbody tr.danger, .table tbody tr.danger td, .table tbody td.danger, li.danger, span.danger { - background-color: var(--phpunit-danger); -} - -.table tbody td.info { - background-color: rgb(from var(--bs-info) r g b / 0.25); -} - -td.big { - vertical-align: middle; - width: 117px; -} - -td.small { -} - -td.codeLine { - font-family: "Source Code Pro", var(--bs-font-monospace); - white-space: pre-wrap; -} - -td span.comment { - color: var(--bs-secondary-color); -} - -td span.default { - color: var(--bs-body-color); -} - -td span.html { - color: var(--bs-secondary-color); -} - -td span.keyword { - color: var(--bs-body-color); - font-weight: bold; -} - -pre span.string { - color: var(--bs-body-color); -} - -span.success, span.warning, span.danger { - margin-right: 2px; - padding-left: 10px; - padding-right: 10px; - text-align: center; -} - -#toplink { - position: fixed; - left: 5px; - bottom: 5px; - outline: 0; -} - -svg text { - font-family: var(--bs-font-sans-serif); - font-size: 11px; - color: var(--bs-gray); - fill: var(--bs-gray); -} - -.scrollbox { - height:245px; - overflow-x:scroll; - overflow-y:scroll; -} - -table + .structure-heading { - border-top: 1px solid var(--bs-gray-200); - padding-top: 0.5em; -} - -table#code td:first-of-type { - padding-left: .75em; - padding-right: .75em; -} - -table#code td:first-of-type a { - text-decoration: none; -} - -.legend { - font-weight: bold; - margin-right: 2px; - padding-left: 10px; - padding-right: 10px; - text-align: center; -} - -.covered-by-small-tests { - background-color: var(--phpunit-success-high); -} - -.covered-by-medium-tests { - background-color: var(--phpunit-success-medium); -} - -.covered-by-large-tests { - background-color: var(--phpunit-success-low); -} - -.not-covered { - background-color: var(--phpunit-danger); -} - -.not-coverable { - background-color: var(--phpunit-warning); -} - -.progress-bar.bg-success { - background-color: var(--phpunit-success-bar) !important; -} - -.progress-bar.bg-warning { - background-color: var(--phpunit-warning-bar) !important; -} - -.progress-bar.bg-danger { - background-color: var(--phpunit-danger-bar) !important; -} \ No newline at end of file diff --git a/backend/coverage-report-with-models/_icons/file-code.svg b/backend/coverage-report-with-models/_icons/file-code.svg deleted file mode 100644 index 5b4b1995..00000000 --- a/backend/coverage-report-with-models/_icons/file-code.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/backend/coverage-report-with-models/_icons/file-directory.svg b/backend/coverage-report-with-models/_icons/file-directory.svg deleted file mode 100644 index 4bf1f1ca..00000000 --- a/backend/coverage-report-with-models/_icons/file-directory.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/backend/coverage-report-with-models/_js/bootstrap.bundle.min.js b/backend/coverage-report-with-models/_js/bootstrap.bundle.min.js deleted file mode 100644 index 8739c91c..00000000 --- a/backend/coverage-report-with-models/_js/bootstrap.bundle.min.js +++ /dev/null @@ -1,7 +0,0 @@ -/*! - * Bootstrap v5.3.6 (https://getbootstrap.com/) - * Copyright 2011-2025 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors) - * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) - */ -!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):(t="undefined"!=typeof globalThis?globalThis:t||self).bootstrap=e()}(this,(function(){"use strict";const t=new Map,e={set(e,i,n){t.has(e)||t.set(e,new Map);const s=t.get(e);s.has(i)||0===s.size?s.set(i,n):console.error(`Bootstrap doesn't allow more than one instance per element. Bound instance: ${Array.from(s.keys())[0]}.`)},get:(e,i)=>t.has(e)&&t.get(e).get(i)||null,remove(e,i){if(!t.has(e))return;const n=t.get(e);n.delete(i),0===n.size&&t.delete(e)}},i="transitionend",n=t=>(t&&window.CSS&&window.CSS.escape&&(t=t.replace(/#([^\s"#']+)/g,((t,e)=>`#${CSS.escape(e)}`))),t),s=t=>{t.dispatchEvent(new Event(i))},o=t=>!(!t||"object"!=typeof t)&&(void 0!==t.jquery&&(t=t[0]),void 0!==t.nodeType),r=t=>o(t)?t.jquery?t[0]:t:"string"==typeof t&&t.length>0?document.querySelector(n(t)):null,a=t=>{if(!o(t)||0===t.getClientRects().length)return!1;const e="visible"===getComputedStyle(t).getPropertyValue("visibility"),i=t.closest("details:not([open])");if(!i)return e;if(i!==t){const e=t.closest("summary");if(e&&e.parentNode!==i)return!1;if(null===e)return!1}return e},l=t=>!t||t.nodeType!==Node.ELEMENT_NODE||!!t.classList.contains("disabled")||(void 0!==t.disabled?t.disabled:t.hasAttribute("disabled")&&"false"!==t.getAttribute("disabled")),c=t=>{if(!document.documentElement.attachShadow)return null;if("function"==typeof t.getRootNode){const e=t.getRootNode();return e instanceof ShadowRoot?e:null}return t instanceof ShadowRoot?t:t.parentNode?c(t.parentNode):null},h=()=>{},d=t=>{t.offsetHeight},u=()=>window.jQuery&&!document.body.hasAttribute("data-bs-no-jquery")?window.jQuery:null,f=[],p=()=>"rtl"===document.documentElement.dir,m=t=>{var e;e=()=>{const e=u();if(e){const i=t.NAME,n=e.fn[i];e.fn[i]=t.jQueryInterface,e.fn[i].Constructor=t,e.fn[i].noConflict=()=>(e.fn[i]=n,t.jQueryInterface)}},"loading"===document.readyState?(f.length||document.addEventListener("DOMContentLoaded",(()=>{for(const t of f)t()})),f.push(e)):e()},g=(t,e=[],i=t)=>"function"==typeof t?t.call(...e):i,_=(t,e,n=!0)=>{if(!n)return void g(t);const o=(t=>{if(!t)return 0;let{transitionDuration:e,transitionDelay:i}=window.getComputedStyle(t);const n=Number.parseFloat(e),s=Number.parseFloat(i);return n||s?(e=e.split(",")[0],i=i.split(",")[0],1e3*(Number.parseFloat(e)+Number.parseFloat(i))):0})(e)+5;let r=!1;const a=({target:n})=>{n===e&&(r=!0,e.removeEventListener(i,a),g(t))};e.addEventListener(i,a),setTimeout((()=>{r||s(e)}),o)},b=(t,e,i,n)=>{const s=t.length;let o=t.indexOf(e);return-1===o?!i&&n?t[s-1]:t[0]:(o+=i?1:-1,n&&(o=(o+s)%s),t[Math.max(0,Math.min(o,s-1))])},v=/[^.]*(?=\..*)\.|.*/,y=/\..*/,w=/::\d+$/,A={};let E=1;const T={mouseenter:"mouseover",mouseleave:"mouseout"},C=new Set(["click","dblclick","mouseup","mousedown","contextmenu","mousewheel","DOMMouseScroll","mouseover","mouseout","mousemove","selectstart","selectend","keydown","keypress","keyup","orientationchange","touchstart","touchmove","touchend","touchcancel","pointerdown","pointermove","pointerup","pointerleave","pointercancel","gesturestart","gesturechange","gestureend","focus","blur","change","reset","select","submit","focusin","focusout","load","unload","beforeunload","resize","move","DOMContentLoaded","readystatechange","error","abort","scroll"]);function O(t,e){return e&&`${e}::${E++}`||t.uidEvent||E++}function x(t){const e=O(t);return t.uidEvent=e,A[e]=A[e]||{},A[e]}function k(t,e,i=null){return Object.values(t).find((t=>t.callable===e&&t.delegationSelector===i))}function L(t,e,i){const n="string"==typeof e,s=n?i:e||i;let o=I(t);return C.has(o)||(o=t),[n,s,o]}function S(t,e,i,n,s){if("string"!=typeof e||!t)return;let[o,r,a]=L(e,i,n);if(e in T){const t=t=>function(e){if(!e.relatedTarget||e.relatedTarget!==e.delegateTarget&&!e.delegateTarget.contains(e.relatedTarget))return t.call(this,e)};r=t(r)}const l=x(t),c=l[a]||(l[a]={}),h=k(c,r,o?i:null);if(h)return void(h.oneOff=h.oneOff&&s);const d=O(r,e.replace(v,"")),u=o?function(t,e,i){return function n(s){const o=t.querySelectorAll(e);for(let{target:r}=s;r&&r!==this;r=r.parentNode)for(const a of o)if(a===r)return P(s,{delegateTarget:r}),n.oneOff&&N.off(t,s.type,e,i),i.apply(r,[s])}}(t,i,r):function(t,e){return function i(n){return P(n,{delegateTarget:t}),i.oneOff&&N.off(t,n.type,e),e.apply(t,[n])}}(t,r);u.delegationSelector=o?i:null,u.callable=r,u.oneOff=s,u.uidEvent=d,c[d]=u,t.addEventListener(a,u,o)}function D(t,e,i,n,s){const o=k(e[i],n,s);o&&(t.removeEventListener(i,o,Boolean(s)),delete e[i][o.uidEvent])}function $(t,e,i,n){const s=e[i]||{};for(const[o,r]of Object.entries(s))o.includes(n)&&D(t,e,i,r.callable,r.delegationSelector)}function I(t){return t=t.replace(y,""),T[t]||t}const N={on(t,e,i,n){S(t,e,i,n,!1)},one(t,e,i,n){S(t,e,i,n,!0)},off(t,e,i,n){if("string"!=typeof e||!t)return;const[s,o,r]=L(e,i,n),a=r!==e,l=x(t),c=l[r]||{},h=e.startsWith(".");if(void 0===o){if(h)for(const i of Object.keys(l))$(t,l,i,e.slice(1));for(const[i,n]of Object.entries(c)){const s=i.replace(w,"");a&&!e.includes(s)||D(t,l,r,n.callable,n.delegationSelector)}}else{if(!Object.keys(c).length)return;D(t,l,r,o,s?i:null)}},trigger(t,e,i){if("string"!=typeof e||!t)return null;const n=u();let s=null,o=!0,r=!0,a=!1;e!==I(e)&&n&&(s=n.Event(e,i),n(t).trigger(s),o=!s.isPropagationStopped(),r=!s.isImmediatePropagationStopped(),a=s.isDefaultPrevented());const l=P(new Event(e,{bubbles:o,cancelable:!0}),i);return a&&l.preventDefault(),r&&t.dispatchEvent(l),l.defaultPrevented&&s&&s.preventDefault(),l}};function P(t,e={}){for(const[i,n]of Object.entries(e))try{t[i]=n}catch(e){Object.defineProperty(t,i,{configurable:!0,get:()=>n})}return t}function j(t){if("true"===t)return!0;if("false"===t)return!1;if(t===Number(t).toString())return Number(t);if(""===t||"null"===t)return null;if("string"!=typeof t)return t;try{return JSON.parse(decodeURIComponent(t))}catch(e){return t}}function M(t){return t.replace(/[A-Z]/g,(t=>`-${t.toLowerCase()}`))}const F={setDataAttribute(t,e,i){t.setAttribute(`data-bs-${M(e)}`,i)},removeDataAttribute(t,e){t.removeAttribute(`data-bs-${M(e)}`)},getDataAttributes(t){if(!t)return{};const e={},i=Object.keys(t.dataset).filter((t=>t.startsWith("bs")&&!t.startsWith("bsConfig")));for(const n of i){let i=n.replace(/^bs/,"");i=i.charAt(0).toLowerCase()+i.slice(1),e[i]=j(t.dataset[n])}return e},getDataAttribute:(t,e)=>j(t.getAttribute(`data-bs-${M(e)}`))};class H{static get Default(){return{}}static get DefaultType(){return{}}static get NAME(){throw new Error('You have to implement the static method "NAME", for each component!')}_getConfig(t){return t=this._mergeConfigObj(t),t=this._configAfterMerge(t),this._typeCheckConfig(t),t}_configAfterMerge(t){return t}_mergeConfigObj(t,e){const i=o(e)?F.getDataAttribute(e,"config"):{};return{...this.constructor.Default,..."object"==typeof i?i:{},...o(e)?F.getDataAttributes(e):{},..."object"==typeof t?t:{}}}_typeCheckConfig(t,e=this.constructor.DefaultType){for(const[n,s]of Object.entries(e)){const e=t[n],r=o(e)?"element":null==(i=e)?`${i}`:Object.prototype.toString.call(i).match(/\s([a-z]+)/i)[1].toLowerCase();if(!new RegExp(s).test(r))throw new TypeError(`${this.constructor.NAME.toUpperCase()}: Option "${n}" provided type "${r}" but expected type "${s}".`)}var i}}class W extends H{constructor(t,i){super(),(t=r(t))&&(this._element=t,this._config=this._getConfig(i),e.set(this._element,this.constructor.DATA_KEY,this))}dispose(){e.remove(this._element,this.constructor.DATA_KEY),N.off(this._element,this.constructor.EVENT_KEY);for(const t of Object.getOwnPropertyNames(this))this[t]=null}_queueCallback(t,e,i=!0){_(t,e,i)}_getConfig(t){return t=this._mergeConfigObj(t,this._element),t=this._configAfterMerge(t),this._typeCheckConfig(t),t}static getInstance(t){return e.get(r(t),this.DATA_KEY)}static getOrCreateInstance(t,e={}){return this.getInstance(t)||new this(t,"object"==typeof e?e:null)}static get VERSION(){return"5.3.6"}static get DATA_KEY(){return`bs.${this.NAME}`}static get EVENT_KEY(){return`.${this.DATA_KEY}`}static eventName(t){return`${t}${this.EVENT_KEY}`}}const B=t=>{let e=t.getAttribute("data-bs-target");if(!e||"#"===e){let i=t.getAttribute("href");if(!i||!i.includes("#")&&!i.startsWith("."))return null;i.includes("#")&&!i.startsWith("#")&&(i=`#${i.split("#")[1]}`),e=i&&"#"!==i?i.trim():null}return e?e.split(",").map((t=>n(t))).join(","):null},z={find:(t,e=document.documentElement)=>[].concat(...Element.prototype.querySelectorAll.call(e,t)),findOne:(t,e=document.documentElement)=>Element.prototype.querySelector.call(e,t),children:(t,e)=>[].concat(...t.children).filter((t=>t.matches(e))),parents(t,e){const i=[];let n=t.parentNode.closest(e);for(;n;)i.push(n),n=n.parentNode.closest(e);return i},prev(t,e){let i=t.previousElementSibling;for(;i;){if(i.matches(e))return[i];i=i.previousElementSibling}return[]},next(t,e){let i=t.nextElementSibling;for(;i;){if(i.matches(e))return[i];i=i.nextElementSibling}return[]},focusableChildren(t){const e=["a","button","input","textarea","select","details","[tabindex]",'[contenteditable="true"]'].map((t=>`${t}:not([tabindex^="-"])`)).join(",");return this.find(e,t).filter((t=>!l(t)&&a(t)))},getSelectorFromElement(t){const e=B(t);return e&&z.findOne(e)?e:null},getElementFromSelector(t){const e=B(t);return e?z.findOne(e):null},getMultipleElementsFromSelector(t){const e=B(t);return e?z.find(e):[]}},R=(t,e="hide")=>{const i=`click.dismiss${t.EVENT_KEY}`,n=t.NAME;N.on(document,i,`[data-bs-dismiss="${n}"]`,(function(i){if(["A","AREA"].includes(this.tagName)&&i.preventDefault(),l(this))return;const s=z.getElementFromSelector(this)||this.closest(`.${n}`);t.getOrCreateInstance(s)[e]()}))},q=".bs.alert",V=`close${q}`,K=`closed${q}`;class Q extends W{static get NAME(){return"alert"}close(){if(N.trigger(this._element,V).defaultPrevented)return;this._element.classList.remove("show");const t=this._element.classList.contains("fade");this._queueCallback((()=>this._destroyElement()),this._element,t)}_destroyElement(){this._element.remove(),N.trigger(this._element,K),this.dispose()}static jQueryInterface(t){return this.each((function(){const e=Q.getOrCreateInstance(this);if("string"==typeof t){if(void 0===e[t]||t.startsWith("_")||"constructor"===t)throw new TypeError(`No method named "${t}"`);e[t](this)}}))}}R(Q,"close"),m(Q);const X='[data-bs-toggle="button"]';class Y extends W{static get NAME(){return"button"}toggle(){this._element.setAttribute("aria-pressed",this._element.classList.toggle("active"))}static jQueryInterface(t){return this.each((function(){const e=Y.getOrCreateInstance(this);"toggle"===t&&e[t]()}))}}N.on(document,"click.bs.button.data-api",X,(t=>{t.preventDefault();const e=t.target.closest(X);Y.getOrCreateInstance(e).toggle()})),m(Y);const U=".bs.swipe",G=`touchstart${U}`,J=`touchmove${U}`,Z=`touchend${U}`,tt=`pointerdown${U}`,et=`pointerup${U}`,it={endCallback:null,leftCallback:null,rightCallback:null},nt={endCallback:"(function|null)",leftCallback:"(function|null)",rightCallback:"(function|null)"};class st extends H{constructor(t,e){super(),this._element=t,t&&st.isSupported()&&(this._config=this._getConfig(e),this._deltaX=0,this._supportPointerEvents=Boolean(window.PointerEvent),this._initEvents())}static get Default(){return it}static get DefaultType(){return nt}static get NAME(){return"swipe"}dispose(){N.off(this._element,U)}_start(t){this._supportPointerEvents?this._eventIsPointerPenTouch(t)&&(this._deltaX=t.clientX):this._deltaX=t.touches[0].clientX}_end(t){this._eventIsPointerPenTouch(t)&&(this._deltaX=t.clientX-this._deltaX),this._handleSwipe(),g(this._config.endCallback)}_move(t){this._deltaX=t.touches&&t.touches.length>1?0:t.touches[0].clientX-this._deltaX}_handleSwipe(){const t=Math.abs(this._deltaX);if(t<=40)return;const e=t/this._deltaX;this._deltaX=0,e&&g(e>0?this._config.rightCallback:this._config.leftCallback)}_initEvents(){this._supportPointerEvents?(N.on(this._element,tt,(t=>this._start(t))),N.on(this._element,et,(t=>this._end(t))),this._element.classList.add("pointer-event")):(N.on(this._element,G,(t=>this._start(t))),N.on(this._element,J,(t=>this._move(t))),N.on(this._element,Z,(t=>this._end(t))))}_eventIsPointerPenTouch(t){return this._supportPointerEvents&&("pen"===t.pointerType||"touch"===t.pointerType)}static isSupported(){return"ontouchstart"in document.documentElement||navigator.maxTouchPoints>0}}const ot=".bs.carousel",rt=".data-api",at="ArrowLeft",lt="ArrowRight",ct="next",ht="prev",dt="left",ut="right",ft=`slide${ot}`,pt=`slid${ot}`,mt=`keydown${ot}`,gt=`mouseenter${ot}`,_t=`mouseleave${ot}`,bt=`dragstart${ot}`,vt=`load${ot}${rt}`,yt=`click${ot}${rt}`,wt="carousel",At="active",Et=".active",Tt=".carousel-item",Ct=Et+Tt,Ot={[at]:ut,[lt]:dt},xt={interval:5e3,keyboard:!0,pause:"hover",ride:!1,touch:!0,wrap:!0},kt={interval:"(number|boolean)",keyboard:"boolean",pause:"(string|boolean)",ride:"(boolean|string)",touch:"boolean",wrap:"boolean"};class Lt extends W{constructor(t,e){super(t,e),this._interval=null,this._activeElement=null,this._isSliding=!1,this.touchTimeout=null,this._swipeHelper=null,this._indicatorsElement=z.findOne(".carousel-indicators",this._element),this._addEventListeners(),this._config.ride===wt&&this.cycle()}static get Default(){return xt}static get DefaultType(){return kt}static get NAME(){return"carousel"}next(){this._slide(ct)}nextWhenVisible(){!document.hidden&&a(this._element)&&this.next()}prev(){this._slide(ht)}pause(){this._isSliding&&s(this._element),this._clearInterval()}cycle(){this._clearInterval(),this._updateInterval(),this._interval=setInterval((()=>this.nextWhenVisible()),this._config.interval)}_maybeEnableCycle(){this._config.ride&&(this._isSliding?N.one(this._element,pt,(()=>this.cycle())):this.cycle())}to(t){const e=this._getItems();if(t>e.length-1||t<0)return;if(this._isSliding)return void N.one(this._element,pt,(()=>this.to(t)));const i=this._getItemIndex(this._getActive());if(i===t)return;const n=t>i?ct:ht;this._slide(n,e[t])}dispose(){this._swipeHelper&&this._swipeHelper.dispose(),super.dispose()}_configAfterMerge(t){return t.defaultInterval=t.interval,t}_addEventListeners(){this._config.keyboard&&N.on(this._element,mt,(t=>this._keydown(t))),"hover"===this._config.pause&&(N.on(this._element,gt,(()=>this.pause())),N.on(this._element,_t,(()=>this._maybeEnableCycle()))),this._config.touch&&st.isSupported()&&this._addTouchEventListeners()}_addTouchEventListeners(){for(const t of z.find(".carousel-item img",this._element))N.on(t,bt,(t=>t.preventDefault()));const t={leftCallback:()=>this._slide(this._directionToOrder(dt)),rightCallback:()=>this._slide(this._directionToOrder(ut)),endCallback:()=>{"hover"===this._config.pause&&(this.pause(),this.touchTimeout&&clearTimeout(this.touchTimeout),this.touchTimeout=setTimeout((()=>this._maybeEnableCycle()),500+this._config.interval))}};this._swipeHelper=new st(this._element,t)}_keydown(t){if(/input|textarea/i.test(t.target.tagName))return;const e=Ot[t.key];e&&(t.preventDefault(),this._slide(this._directionToOrder(e)))}_getItemIndex(t){return this._getItems().indexOf(t)}_setActiveIndicatorElement(t){if(!this._indicatorsElement)return;const e=z.findOne(Et,this._indicatorsElement);e.classList.remove(At),e.removeAttribute("aria-current");const i=z.findOne(`[data-bs-slide-to="${t}"]`,this._indicatorsElement);i&&(i.classList.add(At),i.setAttribute("aria-current","true"))}_updateInterval(){const t=this._activeElement||this._getActive();if(!t)return;const e=Number.parseInt(t.getAttribute("data-bs-interval"),10);this._config.interval=e||this._config.defaultInterval}_slide(t,e=null){if(this._isSliding)return;const i=this._getActive(),n=t===ct,s=e||b(this._getItems(),i,n,this._config.wrap);if(s===i)return;const o=this._getItemIndex(s),r=e=>N.trigger(this._element,e,{relatedTarget:s,direction:this._orderToDirection(t),from:this._getItemIndex(i),to:o});if(r(ft).defaultPrevented)return;if(!i||!s)return;const a=Boolean(this._interval);this.pause(),this._isSliding=!0,this._setActiveIndicatorElement(o),this._activeElement=s;const l=n?"carousel-item-start":"carousel-item-end",c=n?"carousel-item-next":"carousel-item-prev";s.classList.add(c),d(s),i.classList.add(l),s.classList.add(l),this._queueCallback((()=>{s.classList.remove(l,c),s.classList.add(At),i.classList.remove(At,c,l),this._isSliding=!1,r(pt)}),i,this._isAnimated()),a&&this.cycle()}_isAnimated(){return this._element.classList.contains("slide")}_getActive(){return z.findOne(Ct,this._element)}_getItems(){return z.find(Tt,this._element)}_clearInterval(){this._interval&&(clearInterval(this._interval),this._interval=null)}_directionToOrder(t){return p()?t===dt?ht:ct:t===dt?ct:ht}_orderToDirection(t){return p()?t===ht?dt:ut:t===ht?ut:dt}static jQueryInterface(t){return this.each((function(){const e=Lt.getOrCreateInstance(this,t);if("number"!=typeof t){if("string"==typeof t){if(void 0===e[t]||t.startsWith("_")||"constructor"===t)throw new TypeError(`No method named "${t}"`);e[t]()}}else e.to(t)}))}}N.on(document,yt,"[data-bs-slide], [data-bs-slide-to]",(function(t){const e=z.getElementFromSelector(this);if(!e||!e.classList.contains(wt))return;t.preventDefault();const i=Lt.getOrCreateInstance(e),n=this.getAttribute("data-bs-slide-to");return n?(i.to(n),void i._maybeEnableCycle()):"next"===F.getDataAttribute(this,"slide")?(i.next(),void i._maybeEnableCycle()):(i.prev(),void i._maybeEnableCycle())})),N.on(window,vt,(()=>{const t=z.find('[data-bs-ride="carousel"]');for(const e of t)Lt.getOrCreateInstance(e)})),m(Lt);const St=".bs.collapse",Dt=`show${St}`,$t=`shown${St}`,It=`hide${St}`,Nt=`hidden${St}`,Pt=`click${St}.data-api`,jt="show",Mt="collapse",Ft="collapsing",Ht=`:scope .${Mt} .${Mt}`,Wt='[data-bs-toggle="collapse"]',Bt={parent:null,toggle:!0},zt={parent:"(null|element)",toggle:"boolean"};class Rt extends W{constructor(t,e){super(t,e),this._isTransitioning=!1,this._triggerArray=[];const i=z.find(Wt);for(const t of i){const e=z.getSelectorFromElement(t),i=z.find(e).filter((t=>t===this._element));null!==e&&i.length&&this._triggerArray.push(t)}this._initializeChildren(),this._config.parent||this._addAriaAndCollapsedClass(this._triggerArray,this._isShown()),this._config.toggle&&this.toggle()}static get Default(){return Bt}static get DefaultType(){return zt}static get NAME(){return"collapse"}toggle(){this._isShown()?this.hide():this.show()}show(){if(this._isTransitioning||this._isShown())return;let t=[];if(this._config.parent&&(t=this._getFirstLevelChildren(".collapse.show, .collapse.collapsing").filter((t=>t!==this._element)).map((t=>Rt.getOrCreateInstance(t,{toggle:!1})))),t.length&&t[0]._isTransitioning)return;if(N.trigger(this._element,Dt).defaultPrevented)return;for(const e of t)e.hide();const e=this._getDimension();this._element.classList.remove(Mt),this._element.classList.add(Ft),this._element.style[e]=0,this._addAriaAndCollapsedClass(this._triggerArray,!0),this._isTransitioning=!0;const i=`scroll${e[0].toUpperCase()+e.slice(1)}`;this._queueCallback((()=>{this._isTransitioning=!1,this._element.classList.remove(Ft),this._element.classList.add(Mt,jt),this._element.style[e]="",N.trigger(this._element,$t)}),this._element,!0),this._element.style[e]=`${this._element[i]}px`}hide(){if(this._isTransitioning||!this._isShown())return;if(N.trigger(this._element,It).defaultPrevented)return;const t=this._getDimension();this._element.style[t]=`${this._element.getBoundingClientRect()[t]}px`,d(this._element),this._element.classList.add(Ft),this._element.classList.remove(Mt,jt);for(const t of this._triggerArray){const e=z.getElementFromSelector(t);e&&!this._isShown(e)&&this._addAriaAndCollapsedClass([t],!1)}this._isTransitioning=!0,this._element.style[t]="",this._queueCallback((()=>{this._isTransitioning=!1,this._element.classList.remove(Ft),this._element.classList.add(Mt),N.trigger(this._element,Nt)}),this._element,!0)}_isShown(t=this._element){return t.classList.contains(jt)}_configAfterMerge(t){return t.toggle=Boolean(t.toggle),t.parent=r(t.parent),t}_getDimension(){return this._element.classList.contains("collapse-horizontal")?"width":"height"}_initializeChildren(){if(!this._config.parent)return;const t=this._getFirstLevelChildren(Wt);for(const e of t){const t=z.getElementFromSelector(e);t&&this._addAriaAndCollapsedClass([e],this._isShown(t))}}_getFirstLevelChildren(t){const e=z.find(Ht,this._config.parent);return z.find(t,this._config.parent).filter((t=>!e.includes(t)))}_addAriaAndCollapsedClass(t,e){if(t.length)for(const i of t)i.classList.toggle("collapsed",!e),i.setAttribute("aria-expanded",e)}static jQueryInterface(t){const e={};return"string"==typeof t&&/show|hide/.test(t)&&(e.toggle=!1),this.each((function(){const i=Rt.getOrCreateInstance(this,e);if("string"==typeof t){if(void 0===i[t])throw new TypeError(`No method named "${t}"`);i[t]()}}))}}N.on(document,Pt,Wt,(function(t){("A"===t.target.tagName||t.delegateTarget&&"A"===t.delegateTarget.tagName)&&t.preventDefault();for(const t of z.getMultipleElementsFromSelector(this))Rt.getOrCreateInstance(t,{toggle:!1}).toggle()})),m(Rt);var qt="top",Vt="bottom",Kt="right",Qt="left",Xt="auto",Yt=[qt,Vt,Kt,Qt],Ut="start",Gt="end",Jt="clippingParents",Zt="viewport",te="popper",ee="reference",ie=Yt.reduce((function(t,e){return t.concat([e+"-"+Ut,e+"-"+Gt])}),[]),ne=[].concat(Yt,[Xt]).reduce((function(t,e){return t.concat([e,e+"-"+Ut,e+"-"+Gt])}),[]),se="beforeRead",oe="read",re="afterRead",ae="beforeMain",le="main",ce="afterMain",he="beforeWrite",de="write",ue="afterWrite",fe=[se,oe,re,ae,le,ce,he,de,ue];function pe(t){return t?(t.nodeName||"").toLowerCase():null}function me(t){if(null==t)return window;if("[object Window]"!==t.toString()){var e=t.ownerDocument;return e&&e.defaultView||window}return t}function ge(t){return t instanceof me(t).Element||t instanceof Element}function _e(t){return t instanceof me(t).HTMLElement||t instanceof HTMLElement}function be(t){return"undefined"!=typeof ShadowRoot&&(t instanceof me(t).ShadowRoot||t instanceof ShadowRoot)}const ve={name:"applyStyles",enabled:!0,phase:"write",fn:function(t){var e=t.state;Object.keys(e.elements).forEach((function(t){var i=e.styles[t]||{},n=e.attributes[t]||{},s=e.elements[t];_e(s)&&pe(s)&&(Object.assign(s.style,i),Object.keys(n).forEach((function(t){var e=n[t];!1===e?s.removeAttribute(t):s.setAttribute(t,!0===e?"":e)})))}))},effect:function(t){var e=t.state,i={popper:{position:e.options.strategy,left:"0",top:"0",margin:"0"},arrow:{position:"absolute"},reference:{}};return Object.assign(e.elements.popper.style,i.popper),e.styles=i,e.elements.arrow&&Object.assign(e.elements.arrow.style,i.arrow),function(){Object.keys(e.elements).forEach((function(t){var n=e.elements[t],s=e.attributes[t]||{},o=Object.keys(e.styles.hasOwnProperty(t)?e.styles[t]:i[t]).reduce((function(t,e){return t[e]="",t}),{});_e(n)&&pe(n)&&(Object.assign(n.style,o),Object.keys(s).forEach((function(t){n.removeAttribute(t)})))}))}},requires:["computeStyles"]};function ye(t){return t.split("-")[0]}var we=Math.max,Ae=Math.min,Ee=Math.round;function Te(){var t=navigator.userAgentData;return null!=t&&t.brands&&Array.isArray(t.brands)?t.brands.map((function(t){return t.brand+"/"+t.version})).join(" "):navigator.userAgent}function Ce(){return!/^((?!chrome|android).)*safari/i.test(Te())}function Oe(t,e,i){void 0===e&&(e=!1),void 0===i&&(i=!1);var n=t.getBoundingClientRect(),s=1,o=1;e&&_e(t)&&(s=t.offsetWidth>0&&Ee(n.width)/t.offsetWidth||1,o=t.offsetHeight>0&&Ee(n.height)/t.offsetHeight||1);var r=(ge(t)?me(t):window).visualViewport,a=!Ce()&&i,l=(n.left+(a&&r?r.offsetLeft:0))/s,c=(n.top+(a&&r?r.offsetTop:0))/o,h=n.width/s,d=n.height/o;return{width:h,height:d,top:c,right:l+h,bottom:c+d,left:l,x:l,y:c}}function xe(t){var e=Oe(t),i=t.offsetWidth,n=t.offsetHeight;return Math.abs(e.width-i)<=1&&(i=e.width),Math.abs(e.height-n)<=1&&(n=e.height),{x:t.offsetLeft,y:t.offsetTop,width:i,height:n}}function ke(t,e){var i=e.getRootNode&&e.getRootNode();if(t.contains(e))return!0;if(i&&be(i)){var n=e;do{if(n&&t.isSameNode(n))return!0;n=n.parentNode||n.host}while(n)}return!1}function Le(t){return me(t).getComputedStyle(t)}function Se(t){return["table","td","th"].indexOf(pe(t))>=0}function De(t){return((ge(t)?t.ownerDocument:t.document)||window.document).documentElement}function $e(t){return"html"===pe(t)?t:t.assignedSlot||t.parentNode||(be(t)?t.host:null)||De(t)}function Ie(t){return _e(t)&&"fixed"!==Le(t).position?t.offsetParent:null}function Ne(t){for(var e=me(t),i=Ie(t);i&&Se(i)&&"static"===Le(i).position;)i=Ie(i);return i&&("html"===pe(i)||"body"===pe(i)&&"static"===Le(i).position)?e:i||function(t){var e=/firefox/i.test(Te());if(/Trident/i.test(Te())&&_e(t)&&"fixed"===Le(t).position)return null;var i=$e(t);for(be(i)&&(i=i.host);_e(i)&&["html","body"].indexOf(pe(i))<0;){var n=Le(i);if("none"!==n.transform||"none"!==n.perspective||"paint"===n.contain||-1!==["transform","perspective"].indexOf(n.willChange)||e&&"filter"===n.willChange||e&&n.filter&&"none"!==n.filter)return i;i=i.parentNode}return null}(t)||e}function Pe(t){return["top","bottom"].indexOf(t)>=0?"x":"y"}function je(t,e,i){return we(t,Ae(e,i))}function Me(t){return Object.assign({},{top:0,right:0,bottom:0,left:0},t)}function Fe(t,e){return e.reduce((function(e,i){return e[i]=t,e}),{})}const He={name:"arrow",enabled:!0,phase:"main",fn:function(t){var e,i=t.state,n=t.name,s=t.options,o=i.elements.arrow,r=i.modifiersData.popperOffsets,a=ye(i.placement),l=Pe(a),c=[Qt,Kt].indexOf(a)>=0?"height":"width";if(o&&r){var h=function(t,e){return Me("number"!=typeof(t="function"==typeof t?t(Object.assign({},e.rects,{placement:e.placement})):t)?t:Fe(t,Yt))}(s.padding,i),d=xe(o),u="y"===l?qt:Qt,f="y"===l?Vt:Kt,p=i.rects.reference[c]+i.rects.reference[l]-r[l]-i.rects.popper[c],m=r[l]-i.rects.reference[l],g=Ne(o),_=g?"y"===l?g.clientHeight||0:g.clientWidth||0:0,b=p/2-m/2,v=h[u],y=_-d[c]-h[f],w=_/2-d[c]/2+b,A=je(v,w,y),E=l;i.modifiersData[n]=((e={})[E]=A,e.centerOffset=A-w,e)}},effect:function(t){var e=t.state,i=t.options.element,n=void 0===i?"[data-popper-arrow]":i;null!=n&&("string"!=typeof n||(n=e.elements.popper.querySelector(n)))&&ke(e.elements.popper,n)&&(e.elements.arrow=n)},requires:["popperOffsets"],requiresIfExists:["preventOverflow"]};function We(t){return t.split("-")[1]}var Be={top:"auto",right:"auto",bottom:"auto",left:"auto"};function ze(t){var e,i=t.popper,n=t.popperRect,s=t.placement,o=t.variation,r=t.offsets,a=t.position,l=t.gpuAcceleration,c=t.adaptive,h=t.roundOffsets,d=t.isFixed,u=r.x,f=void 0===u?0:u,p=r.y,m=void 0===p?0:p,g="function"==typeof h?h({x:f,y:m}):{x:f,y:m};f=g.x,m=g.y;var _=r.hasOwnProperty("x"),b=r.hasOwnProperty("y"),v=Qt,y=qt,w=window;if(c){var A=Ne(i),E="clientHeight",T="clientWidth";A===me(i)&&"static"!==Le(A=De(i)).position&&"absolute"===a&&(E="scrollHeight",T="scrollWidth"),(s===qt||(s===Qt||s===Kt)&&o===Gt)&&(y=Vt,m-=(d&&A===w&&w.visualViewport?w.visualViewport.height:A[E])-n.height,m*=l?1:-1),s!==Qt&&(s!==qt&&s!==Vt||o!==Gt)||(v=Kt,f-=(d&&A===w&&w.visualViewport?w.visualViewport.width:A[T])-n.width,f*=l?1:-1)}var C,O=Object.assign({position:a},c&&Be),x=!0===h?function(t,e){var i=t.x,n=t.y,s=e.devicePixelRatio||1;return{x:Ee(i*s)/s||0,y:Ee(n*s)/s||0}}({x:f,y:m},me(i)):{x:f,y:m};return f=x.x,m=x.y,l?Object.assign({},O,((C={})[y]=b?"0":"",C[v]=_?"0":"",C.transform=(w.devicePixelRatio||1)<=1?"translate("+f+"px, "+m+"px)":"translate3d("+f+"px, "+m+"px, 0)",C)):Object.assign({},O,((e={})[y]=b?m+"px":"",e[v]=_?f+"px":"",e.transform="",e))}const Re={name:"computeStyles",enabled:!0,phase:"beforeWrite",fn:function(t){var e=t.state,i=t.options,n=i.gpuAcceleration,s=void 0===n||n,o=i.adaptive,r=void 0===o||o,a=i.roundOffsets,l=void 0===a||a,c={placement:ye(e.placement),variation:We(e.placement),popper:e.elements.popper,popperRect:e.rects.popper,gpuAcceleration:s,isFixed:"fixed"===e.options.strategy};null!=e.modifiersData.popperOffsets&&(e.styles.popper=Object.assign({},e.styles.popper,ze(Object.assign({},c,{offsets:e.modifiersData.popperOffsets,position:e.options.strategy,adaptive:r,roundOffsets:l})))),null!=e.modifiersData.arrow&&(e.styles.arrow=Object.assign({},e.styles.arrow,ze(Object.assign({},c,{offsets:e.modifiersData.arrow,position:"absolute",adaptive:!1,roundOffsets:l})))),e.attributes.popper=Object.assign({},e.attributes.popper,{"data-popper-placement":e.placement})},data:{}};var qe={passive:!0};const Ve={name:"eventListeners",enabled:!0,phase:"write",fn:function(){},effect:function(t){var e=t.state,i=t.instance,n=t.options,s=n.scroll,o=void 0===s||s,r=n.resize,a=void 0===r||r,l=me(e.elements.popper),c=[].concat(e.scrollParents.reference,e.scrollParents.popper);return o&&c.forEach((function(t){t.addEventListener("scroll",i.update,qe)})),a&&l.addEventListener("resize",i.update,qe),function(){o&&c.forEach((function(t){t.removeEventListener("scroll",i.update,qe)})),a&&l.removeEventListener("resize",i.update,qe)}},data:{}};var Ke={left:"right",right:"left",bottom:"top",top:"bottom"};function Qe(t){return t.replace(/left|right|bottom|top/g,(function(t){return Ke[t]}))}var Xe={start:"end",end:"start"};function Ye(t){return t.replace(/start|end/g,(function(t){return Xe[t]}))}function Ue(t){var e=me(t);return{scrollLeft:e.pageXOffset,scrollTop:e.pageYOffset}}function Ge(t){return Oe(De(t)).left+Ue(t).scrollLeft}function Je(t){var e=Le(t),i=e.overflow,n=e.overflowX,s=e.overflowY;return/auto|scroll|overlay|hidden/.test(i+s+n)}function Ze(t){return["html","body","#document"].indexOf(pe(t))>=0?t.ownerDocument.body:_e(t)&&Je(t)?t:Ze($e(t))}function ti(t,e){var i;void 0===e&&(e=[]);var n=Ze(t),s=n===(null==(i=t.ownerDocument)?void 0:i.body),o=me(n),r=s?[o].concat(o.visualViewport||[],Je(n)?n:[]):n,a=e.concat(r);return s?a:a.concat(ti($e(r)))}function ei(t){return Object.assign({},t,{left:t.x,top:t.y,right:t.x+t.width,bottom:t.y+t.height})}function ii(t,e,i){return e===Zt?ei(function(t,e){var i=me(t),n=De(t),s=i.visualViewport,o=n.clientWidth,r=n.clientHeight,a=0,l=0;if(s){o=s.width,r=s.height;var c=Ce();(c||!c&&"fixed"===e)&&(a=s.offsetLeft,l=s.offsetTop)}return{width:o,height:r,x:a+Ge(t),y:l}}(t,i)):ge(e)?function(t,e){var i=Oe(t,!1,"fixed"===e);return i.top=i.top+t.clientTop,i.left=i.left+t.clientLeft,i.bottom=i.top+t.clientHeight,i.right=i.left+t.clientWidth,i.width=t.clientWidth,i.height=t.clientHeight,i.x=i.left,i.y=i.top,i}(e,i):ei(function(t){var e,i=De(t),n=Ue(t),s=null==(e=t.ownerDocument)?void 0:e.body,o=we(i.scrollWidth,i.clientWidth,s?s.scrollWidth:0,s?s.clientWidth:0),r=we(i.scrollHeight,i.clientHeight,s?s.scrollHeight:0,s?s.clientHeight:0),a=-n.scrollLeft+Ge(t),l=-n.scrollTop;return"rtl"===Le(s||i).direction&&(a+=we(i.clientWidth,s?s.clientWidth:0)-o),{width:o,height:r,x:a,y:l}}(De(t)))}function ni(t){var e,i=t.reference,n=t.element,s=t.placement,o=s?ye(s):null,r=s?We(s):null,a=i.x+i.width/2-n.width/2,l=i.y+i.height/2-n.height/2;switch(o){case qt:e={x:a,y:i.y-n.height};break;case Vt:e={x:a,y:i.y+i.height};break;case Kt:e={x:i.x+i.width,y:l};break;case Qt:e={x:i.x-n.width,y:l};break;default:e={x:i.x,y:i.y}}var c=o?Pe(o):null;if(null!=c){var h="y"===c?"height":"width";switch(r){case Ut:e[c]=e[c]-(i[h]/2-n[h]/2);break;case Gt:e[c]=e[c]+(i[h]/2-n[h]/2)}}return e}function si(t,e){void 0===e&&(e={});var i=e,n=i.placement,s=void 0===n?t.placement:n,o=i.strategy,r=void 0===o?t.strategy:o,a=i.boundary,l=void 0===a?Jt:a,c=i.rootBoundary,h=void 0===c?Zt:c,d=i.elementContext,u=void 0===d?te:d,f=i.altBoundary,p=void 0!==f&&f,m=i.padding,g=void 0===m?0:m,_=Me("number"!=typeof g?g:Fe(g,Yt)),b=u===te?ee:te,v=t.rects.popper,y=t.elements[p?b:u],w=function(t,e,i,n){var s="clippingParents"===e?function(t){var e=ti($e(t)),i=["absolute","fixed"].indexOf(Le(t).position)>=0&&_e(t)?Ne(t):t;return ge(i)?e.filter((function(t){return ge(t)&&ke(t,i)&&"body"!==pe(t)})):[]}(t):[].concat(e),o=[].concat(s,[i]),r=o[0],a=o.reduce((function(e,i){var s=ii(t,i,n);return e.top=we(s.top,e.top),e.right=Ae(s.right,e.right),e.bottom=Ae(s.bottom,e.bottom),e.left=we(s.left,e.left),e}),ii(t,r,n));return a.width=a.right-a.left,a.height=a.bottom-a.top,a.x=a.left,a.y=a.top,a}(ge(y)?y:y.contextElement||De(t.elements.popper),l,h,r),A=Oe(t.elements.reference),E=ni({reference:A,element:v,placement:s}),T=ei(Object.assign({},v,E)),C=u===te?T:A,O={top:w.top-C.top+_.top,bottom:C.bottom-w.bottom+_.bottom,left:w.left-C.left+_.left,right:C.right-w.right+_.right},x=t.modifiersData.offset;if(u===te&&x){var k=x[s];Object.keys(O).forEach((function(t){var e=[Kt,Vt].indexOf(t)>=0?1:-1,i=[qt,Vt].indexOf(t)>=0?"y":"x";O[t]+=k[i]*e}))}return O}function oi(t,e){void 0===e&&(e={});var i=e,n=i.placement,s=i.boundary,o=i.rootBoundary,r=i.padding,a=i.flipVariations,l=i.allowedAutoPlacements,c=void 0===l?ne:l,h=We(n),d=h?a?ie:ie.filter((function(t){return We(t)===h})):Yt,u=d.filter((function(t){return c.indexOf(t)>=0}));0===u.length&&(u=d);var f=u.reduce((function(e,i){return e[i]=si(t,{placement:i,boundary:s,rootBoundary:o,padding:r})[ye(i)],e}),{});return Object.keys(f).sort((function(t,e){return f[t]-f[e]}))}const ri={name:"flip",enabled:!0,phase:"main",fn:function(t){var e=t.state,i=t.options,n=t.name;if(!e.modifiersData[n]._skip){for(var s=i.mainAxis,o=void 0===s||s,r=i.altAxis,a=void 0===r||r,l=i.fallbackPlacements,c=i.padding,h=i.boundary,d=i.rootBoundary,u=i.altBoundary,f=i.flipVariations,p=void 0===f||f,m=i.allowedAutoPlacements,g=e.options.placement,_=ye(g),b=l||(_!==g&&p?function(t){if(ye(t)===Xt)return[];var e=Qe(t);return[Ye(t),e,Ye(e)]}(g):[Qe(g)]),v=[g].concat(b).reduce((function(t,i){return t.concat(ye(i)===Xt?oi(e,{placement:i,boundary:h,rootBoundary:d,padding:c,flipVariations:p,allowedAutoPlacements:m}):i)}),[]),y=e.rects.reference,w=e.rects.popper,A=new Map,E=!0,T=v[0],C=0;C=0,S=L?"width":"height",D=si(e,{placement:O,boundary:h,rootBoundary:d,altBoundary:u,padding:c}),$=L?k?Kt:Qt:k?Vt:qt;y[S]>w[S]&&($=Qe($));var I=Qe($),N=[];if(o&&N.push(D[x]<=0),a&&N.push(D[$]<=0,D[I]<=0),N.every((function(t){return t}))){T=O,E=!1;break}A.set(O,N)}if(E)for(var P=function(t){var e=v.find((function(e){var i=A.get(e);if(i)return i.slice(0,t).every((function(t){return t}))}));if(e)return T=e,"break"},j=p?3:1;j>0&&"break"!==P(j);j--);e.placement!==T&&(e.modifiersData[n]._skip=!0,e.placement=T,e.reset=!0)}},requiresIfExists:["offset"],data:{_skip:!1}};function ai(t,e,i){return void 0===i&&(i={x:0,y:0}),{top:t.top-e.height-i.y,right:t.right-e.width+i.x,bottom:t.bottom-e.height+i.y,left:t.left-e.width-i.x}}function li(t){return[qt,Kt,Vt,Qt].some((function(e){return t[e]>=0}))}const ci={name:"hide",enabled:!0,phase:"main",requiresIfExists:["preventOverflow"],fn:function(t){var e=t.state,i=t.name,n=e.rects.reference,s=e.rects.popper,o=e.modifiersData.preventOverflow,r=si(e,{elementContext:"reference"}),a=si(e,{altBoundary:!0}),l=ai(r,n),c=ai(a,s,o),h=li(l),d=li(c);e.modifiersData[i]={referenceClippingOffsets:l,popperEscapeOffsets:c,isReferenceHidden:h,hasPopperEscaped:d},e.attributes.popper=Object.assign({},e.attributes.popper,{"data-popper-reference-hidden":h,"data-popper-escaped":d})}},hi={name:"offset",enabled:!0,phase:"main",requires:["popperOffsets"],fn:function(t){var e=t.state,i=t.options,n=t.name,s=i.offset,o=void 0===s?[0,0]:s,r=ne.reduce((function(t,i){return t[i]=function(t,e,i){var n=ye(t),s=[Qt,qt].indexOf(n)>=0?-1:1,o="function"==typeof i?i(Object.assign({},e,{placement:t})):i,r=o[0],a=o[1];return r=r||0,a=(a||0)*s,[Qt,Kt].indexOf(n)>=0?{x:a,y:r}:{x:r,y:a}}(i,e.rects,o),t}),{}),a=r[e.placement],l=a.x,c=a.y;null!=e.modifiersData.popperOffsets&&(e.modifiersData.popperOffsets.x+=l,e.modifiersData.popperOffsets.y+=c),e.modifiersData[n]=r}},di={name:"popperOffsets",enabled:!0,phase:"read",fn:function(t){var e=t.state,i=t.name;e.modifiersData[i]=ni({reference:e.rects.reference,element:e.rects.popper,placement:e.placement})},data:{}},ui={name:"preventOverflow",enabled:!0,phase:"main",fn:function(t){var e=t.state,i=t.options,n=t.name,s=i.mainAxis,o=void 0===s||s,r=i.altAxis,a=void 0!==r&&r,l=i.boundary,c=i.rootBoundary,h=i.altBoundary,d=i.padding,u=i.tether,f=void 0===u||u,p=i.tetherOffset,m=void 0===p?0:p,g=si(e,{boundary:l,rootBoundary:c,padding:d,altBoundary:h}),_=ye(e.placement),b=We(e.placement),v=!b,y=Pe(_),w="x"===y?"y":"x",A=e.modifiersData.popperOffsets,E=e.rects.reference,T=e.rects.popper,C="function"==typeof m?m(Object.assign({},e.rects,{placement:e.placement})):m,O="number"==typeof C?{mainAxis:C,altAxis:C}:Object.assign({mainAxis:0,altAxis:0},C),x=e.modifiersData.offset?e.modifiersData.offset[e.placement]:null,k={x:0,y:0};if(A){if(o){var L,S="y"===y?qt:Qt,D="y"===y?Vt:Kt,$="y"===y?"height":"width",I=A[y],N=I+g[S],P=I-g[D],j=f?-T[$]/2:0,M=b===Ut?E[$]:T[$],F=b===Ut?-T[$]:-E[$],H=e.elements.arrow,W=f&&H?xe(H):{width:0,height:0},B=e.modifiersData["arrow#persistent"]?e.modifiersData["arrow#persistent"].padding:{top:0,right:0,bottom:0,left:0},z=B[S],R=B[D],q=je(0,E[$],W[$]),V=v?E[$]/2-j-q-z-O.mainAxis:M-q-z-O.mainAxis,K=v?-E[$]/2+j+q+R+O.mainAxis:F+q+R+O.mainAxis,Q=e.elements.arrow&&Ne(e.elements.arrow),X=Q?"y"===y?Q.clientTop||0:Q.clientLeft||0:0,Y=null!=(L=null==x?void 0:x[y])?L:0,U=I+K-Y,G=je(f?Ae(N,I+V-Y-X):N,I,f?we(P,U):P);A[y]=G,k[y]=G-I}if(a){var J,Z="x"===y?qt:Qt,tt="x"===y?Vt:Kt,et=A[w],it="y"===w?"height":"width",nt=et+g[Z],st=et-g[tt],ot=-1!==[qt,Qt].indexOf(_),rt=null!=(J=null==x?void 0:x[w])?J:0,at=ot?nt:et-E[it]-T[it]-rt+O.altAxis,lt=ot?et+E[it]+T[it]-rt-O.altAxis:st,ct=f&&ot?function(t,e,i){var n=je(t,e,i);return n>i?i:n}(at,et,lt):je(f?at:nt,et,f?lt:st);A[w]=ct,k[w]=ct-et}e.modifiersData[n]=k}},requiresIfExists:["offset"]};function fi(t,e,i){void 0===i&&(i=!1);var n,s,o=_e(e),r=_e(e)&&function(t){var e=t.getBoundingClientRect(),i=Ee(e.width)/t.offsetWidth||1,n=Ee(e.height)/t.offsetHeight||1;return 1!==i||1!==n}(e),a=De(e),l=Oe(t,r,i),c={scrollLeft:0,scrollTop:0},h={x:0,y:0};return(o||!o&&!i)&&(("body"!==pe(e)||Je(a))&&(c=(n=e)!==me(n)&&_e(n)?{scrollLeft:(s=n).scrollLeft,scrollTop:s.scrollTop}:Ue(n)),_e(e)?((h=Oe(e,!0)).x+=e.clientLeft,h.y+=e.clientTop):a&&(h.x=Ge(a))),{x:l.left+c.scrollLeft-h.x,y:l.top+c.scrollTop-h.y,width:l.width,height:l.height}}function pi(t){var e=new Map,i=new Set,n=[];function s(t){i.add(t.name),[].concat(t.requires||[],t.requiresIfExists||[]).forEach((function(t){if(!i.has(t)){var n=e.get(t);n&&s(n)}})),n.push(t)}return t.forEach((function(t){e.set(t.name,t)})),t.forEach((function(t){i.has(t.name)||s(t)})),n}var mi={placement:"bottom",modifiers:[],strategy:"absolute"};function gi(){for(var t=arguments.length,e=new Array(t),i=0;iNumber.parseInt(t,10))):"function"==typeof t?e=>t(e,this._element):t}_getPopperConfig(){const t={placement:this._getPlacement(),modifiers:[{name:"preventOverflow",options:{boundary:this._config.boundary}},{name:"offset",options:{offset:this._getOffset()}}]};return(this._inNavbar||"static"===this._config.display)&&(F.setDataAttribute(this._menu,"popper","static"),t.modifiers=[{name:"applyStyles",enabled:!1}]),{...t,...g(this._config.popperConfig,[void 0,t])}}_selectMenuItem({key:t,target:e}){const i=z.find(".dropdown-menu .dropdown-item:not(.disabled):not(:disabled)",this._menu).filter((t=>a(t)));i.length&&b(i,e,t===Oi,!i.includes(e)).focus()}static jQueryInterface(t){return this.each((function(){const e=Ki.getOrCreateInstance(this,t);if("string"==typeof t){if(void 0===e[t])throw new TypeError(`No method named "${t}"`);e[t]()}}))}static clearMenus(t){if(2===t.button||"keyup"===t.type&&"Tab"!==t.key)return;const e=z.find(ji);for(const i of e){const e=Ki.getInstance(i);if(!e||!1===e._config.autoClose)continue;const n=t.composedPath(),s=n.includes(e._menu);if(n.includes(e._element)||"inside"===e._config.autoClose&&!s||"outside"===e._config.autoClose&&s)continue;if(e._menu.contains(t.target)&&("keyup"===t.type&&"Tab"===t.key||/input|select|option|textarea|form/i.test(t.target.tagName)))continue;const o={relatedTarget:e._element};"click"===t.type&&(o.clickEvent=t),e._completeHide(o)}}static dataApiKeydownHandler(t){const e=/input|textarea/i.test(t.target.tagName),i="Escape"===t.key,n=[Ci,Oi].includes(t.key);if(!n&&!i)return;if(e&&!i)return;t.preventDefault();const s=this.matches(Pi)?this:z.prev(this,Pi)[0]||z.next(this,Pi)[0]||z.findOne(Pi,t.delegateTarget.parentNode),o=Ki.getOrCreateInstance(s);if(n)return t.stopPropagation(),o.show(),void o._selectMenuItem(t);o._isShown()&&(t.stopPropagation(),o.hide(),s.focus())}}N.on(document,$i,Pi,Ki.dataApiKeydownHandler),N.on(document,$i,Mi,Ki.dataApiKeydownHandler),N.on(document,Di,Ki.clearMenus),N.on(document,Ii,Ki.clearMenus),N.on(document,Di,Pi,(function(t){t.preventDefault(),Ki.getOrCreateInstance(this).toggle()})),m(Ki);const Qi="backdrop",Xi="show",Yi=`mousedown.bs.${Qi}`,Ui={className:"modal-backdrop",clickCallback:null,isAnimated:!1,isVisible:!0,rootElement:"body"},Gi={className:"string",clickCallback:"(function|null)",isAnimated:"boolean",isVisible:"boolean",rootElement:"(element|string)"};class Ji extends H{constructor(t){super(),this._config=this._getConfig(t),this._isAppended=!1,this._element=null}static get Default(){return Ui}static get DefaultType(){return Gi}static get NAME(){return Qi}show(t){if(!this._config.isVisible)return void g(t);this._append();const e=this._getElement();this._config.isAnimated&&d(e),e.classList.add(Xi),this._emulateAnimation((()=>{g(t)}))}hide(t){this._config.isVisible?(this._getElement().classList.remove(Xi),this._emulateAnimation((()=>{this.dispose(),g(t)}))):g(t)}dispose(){this._isAppended&&(N.off(this._element,Yi),this._element.remove(),this._isAppended=!1)}_getElement(){if(!this._element){const t=document.createElement("div");t.className=this._config.className,this._config.isAnimated&&t.classList.add("fade"),this._element=t}return this._element}_configAfterMerge(t){return t.rootElement=r(t.rootElement),t}_append(){if(this._isAppended)return;const t=this._getElement();this._config.rootElement.append(t),N.on(t,Yi,(()=>{g(this._config.clickCallback)})),this._isAppended=!0}_emulateAnimation(t){_(t,this._getElement(),this._config.isAnimated)}}const Zi=".bs.focustrap",tn=`focusin${Zi}`,en=`keydown.tab${Zi}`,nn="backward",sn={autofocus:!0,trapElement:null},on={autofocus:"boolean",trapElement:"element"};class rn extends H{constructor(t){super(),this._config=this._getConfig(t),this._isActive=!1,this._lastTabNavDirection=null}static get Default(){return sn}static get DefaultType(){return on}static get NAME(){return"focustrap"}activate(){this._isActive||(this._config.autofocus&&this._config.trapElement.focus(),N.off(document,Zi),N.on(document,tn,(t=>this._handleFocusin(t))),N.on(document,en,(t=>this._handleKeydown(t))),this._isActive=!0)}deactivate(){this._isActive&&(this._isActive=!1,N.off(document,Zi))}_handleFocusin(t){const{trapElement:e}=this._config;if(t.target===document||t.target===e||e.contains(t.target))return;const i=z.focusableChildren(e);0===i.length?e.focus():this._lastTabNavDirection===nn?i[i.length-1].focus():i[0].focus()}_handleKeydown(t){"Tab"===t.key&&(this._lastTabNavDirection=t.shiftKey?nn:"forward")}}const an=".fixed-top, .fixed-bottom, .is-fixed, .sticky-top",ln=".sticky-top",cn="padding-right",hn="margin-right";class dn{constructor(){this._element=document.body}getWidth(){const t=document.documentElement.clientWidth;return Math.abs(window.innerWidth-t)}hide(){const t=this.getWidth();this._disableOverFlow(),this._setElementAttributes(this._element,cn,(e=>e+t)),this._setElementAttributes(an,cn,(e=>e+t)),this._setElementAttributes(ln,hn,(e=>e-t))}reset(){this._resetElementAttributes(this._element,"overflow"),this._resetElementAttributes(this._element,cn),this._resetElementAttributes(an,cn),this._resetElementAttributes(ln,hn)}isOverflowing(){return this.getWidth()>0}_disableOverFlow(){this._saveInitialAttribute(this._element,"overflow"),this._element.style.overflow="hidden"}_setElementAttributes(t,e,i){const n=this.getWidth();this._applyManipulationCallback(t,(t=>{if(t!==this._element&&window.innerWidth>t.clientWidth+n)return;this._saveInitialAttribute(t,e);const s=window.getComputedStyle(t).getPropertyValue(e);t.style.setProperty(e,`${i(Number.parseFloat(s))}px`)}))}_saveInitialAttribute(t,e){const i=t.style.getPropertyValue(e);i&&F.setDataAttribute(t,e,i)}_resetElementAttributes(t,e){this._applyManipulationCallback(t,(t=>{const i=F.getDataAttribute(t,e);null!==i?(F.removeDataAttribute(t,e),t.style.setProperty(e,i)):t.style.removeProperty(e)}))}_applyManipulationCallback(t,e){if(o(t))e(t);else for(const i of z.find(t,this._element))e(i)}}const un=".bs.modal",fn=`hide${un}`,pn=`hidePrevented${un}`,mn=`hidden${un}`,gn=`show${un}`,_n=`shown${un}`,bn=`resize${un}`,vn=`click.dismiss${un}`,yn=`mousedown.dismiss${un}`,wn=`keydown.dismiss${un}`,An=`click${un}.data-api`,En="modal-open",Tn="show",Cn="modal-static",On={backdrop:!0,focus:!0,keyboard:!0},xn={backdrop:"(boolean|string)",focus:"boolean",keyboard:"boolean"};class kn extends W{constructor(t,e){super(t,e),this._dialog=z.findOne(".modal-dialog",this._element),this._backdrop=this._initializeBackDrop(),this._focustrap=this._initializeFocusTrap(),this._isShown=!1,this._isTransitioning=!1,this._scrollBar=new dn,this._addEventListeners()}static get Default(){return On}static get DefaultType(){return xn}static get NAME(){return"modal"}toggle(t){return this._isShown?this.hide():this.show(t)}show(t){this._isShown||this._isTransitioning||N.trigger(this._element,gn,{relatedTarget:t}).defaultPrevented||(this._isShown=!0,this._isTransitioning=!0,this._scrollBar.hide(),document.body.classList.add(En),this._adjustDialog(),this._backdrop.show((()=>this._showElement(t))))}hide(){this._isShown&&!this._isTransitioning&&(N.trigger(this._element,fn).defaultPrevented||(this._isShown=!1,this._isTransitioning=!0,this._focustrap.deactivate(),this._element.classList.remove(Tn),this._queueCallback((()=>this._hideModal()),this._element,this._isAnimated())))}dispose(){N.off(window,un),N.off(this._dialog,un),this._backdrop.dispose(),this._focustrap.deactivate(),super.dispose()}handleUpdate(){this._adjustDialog()}_initializeBackDrop(){return new Ji({isVisible:Boolean(this._config.backdrop),isAnimated:this._isAnimated()})}_initializeFocusTrap(){return new rn({trapElement:this._element})}_showElement(t){document.body.contains(this._element)||document.body.append(this._element),this._element.style.display="block",this._element.removeAttribute("aria-hidden"),this._element.setAttribute("aria-modal",!0),this._element.setAttribute("role","dialog"),this._element.scrollTop=0;const e=z.findOne(".modal-body",this._dialog);e&&(e.scrollTop=0),d(this._element),this._element.classList.add(Tn),this._queueCallback((()=>{this._config.focus&&this._focustrap.activate(),this._isTransitioning=!1,N.trigger(this._element,_n,{relatedTarget:t})}),this._dialog,this._isAnimated())}_addEventListeners(){N.on(this._element,wn,(t=>{"Escape"===t.key&&(this._config.keyboard?this.hide():this._triggerBackdropTransition())})),N.on(window,bn,(()=>{this._isShown&&!this._isTransitioning&&this._adjustDialog()})),N.on(this._element,yn,(t=>{N.one(this._element,vn,(e=>{this._element===t.target&&this._element===e.target&&("static"!==this._config.backdrop?this._config.backdrop&&this.hide():this._triggerBackdropTransition())}))}))}_hideModal(){this._element.style.display="none",this._element.setAttribute("aria-hidden",!0),this._element.removeAttribute("aria-modal"),this._element.removeAttribute("role"),this._isTransitioning=!1,this._backdrop.hide((()=>{document.body.classList.remove(En),this._resetAdjustments(),this._scrollBar.reset(),N.trigger(this._element,mn)}))}_isAnimated(){return this._element.classList.contains("fade")}_triggerBackdropTransition(){if(N.trigger(this._element,pn).defaultPrevented)return;const t=this._element.scrollHeight>document.documentElement.clientHeight,e=this._element.style.overflowY;"hidden"===e||this._element.classList.contains(Cn)||(t||(this._element.style.overflowY="hidden"),this._element.classList.add(Cn),this._queueCallback((()=>{this._element.classList.remove(Cn),this._queueCallback((()=>{this._element.style.overflowY=e}),this._dialog)}),this._dialog),this._element.focus())}_adjustDialog(){const t=this._element.scrollHeight>document.documentElement.clientHeight,e=this._scrollBar.getWidth(),i=e>0;if(i&&!t){const t=p()?"paddingLeft":"paddingRight";this._element.style[t]=`${e}px`}if(!i&&t){const t=p()?"paddingRight":"paddingLeft";this._element.style[t]=`${e}px`}}_resetAdjustments(){this._element.style.paddingLeft="",this._element.style.paddingRight=""}static jQueryInterface(t,e){return this.each((function(){const i=kn.getOrCreateInstance(this,t);if("string"==typeof t){if(void 0===i[t])throw new TypeError(`No method named "${t}"`);i[t](e)}}))}}N.on(document,An,'[data-bs-toggle="modal"]',(function(t){const e=z.getElementFromSelector(this);["A","AREA"].includes(this.tagName)&&t.preventDefault(),N.one(e,gn,(t=>{t.defaultPrevented||N.one(e,mn,(()=>{a(this)&&this.focus()}))}));const i=z.findOne(".modal.show");i&&kn.getInstance(i).hide(),kn.getOrCreateInstance(e).toggle(this)})),R(kn),m(kn);const Ln=".bs.offcanvas",Sn=".data-api",Dn=`load${Ln}${Sn}`,$n="show",In="showing",Nn="hiding",Pn=".offcanvas.show",jn=`show${Ln}`,Mn=`shown${Ln}`,Fn=`hide${Ln}`,Hn=`hidePrevented${Ln}`,Wn=`hidden${Ln}`,Bn=`resize${Ln}`,zn=`click${Ln}${Sn}`,Rn=`keydown.dismiss${Ln}`,qn={backdrop:!0,keyboard:!0,scroll:!1},Vn={backdrop:"(boolean|string)",keyboard:"boolean",scroll:"boolean"};class Kn extends W{constructor(t,e){super(t,e),this._isShown=!1,this._backdrop=this._initializeBackDrop(),this._focustrap=this._initializeFocusTrap(),this._addEventListeners()}static get Default(){return qn}static get DefaultType(){return Vn}static get NAME(){return"offcanvas"}toggle(t){return this._isShown?this.hide():this.show(t)}show(t){this._isShown||N.trigger(this._element,jn,{relatedTarget:t}).defaultPrevented||(this._isShown=!0,this._backdrop.show(),this._config.scroll||(new dn).hide(),this._element.setAttribute("aria-modal",!0),this._element.setAttribute("role","dialog"),this._element.classList.add(In),this._queueCallback((()=>{this._config.scroll&&!this._config.backdrop||this._focustrap.activate(),this._element.classList.add($n),this._element.classList.remove(In),N.trigger(this._element,Mn,{relatedTarget:t})}),this._element,!0))}hide(){this._isShown&&(N.trigger(this._element,Fn).defaultPrevented||(this._focustrap.deactivate(),this._element.blur(),this._isShown=!1,this._element.classList.add(Nn),this._backdrop.hide(),this._queueCallback((()=>{this._element.classList.remove($n,Nn),this._element.removeAttribute("aria-modal"),this._element.removeAttribute("role"),this._config.scroll||(new dn).reset(),N.trigger(this._element,Wn)}),this._element,!0)))}dispose(){this._backdrop.dispose(),this._focustrap.deactivate(),super.dispose()}_initializeBackDrop(){const t=Boolean(this._config.backdrop);return new Ji({className:"offcanvas-backdrop",isVisible:t,isAnimated:!0,rootElement:this._element.parentNode,clickCallback:t?()=>{"static"!==this._config.backdrop?this.hide():N.trigger(this._element,Hn)}:null})}_initializeFocusTrap(){return new rn({trapElement:this._element})}_addEventListeners(){N.on(this._element,Rn,(t=>{"Escape"===t.key&&(this._config.keyboard?this.hide():N.trigger(this._element,Hn))}))}static jQueryInterface(t){return this.each((function(){const e=Kn.getOrCreateInstance(this,t);if("string"==typeof t){if(void 0===e[t]||t.startsWith("_")||"constructor"===t)throw new TypeError(`No method named "${t}"`);e[t](this)}}))}}N.on(document,zn,'[data-bs-toggle="offcanvas"]',(function(t){const e=z.getElementFromSelector(this);if(["A","AREA"].includes(this.tagName)&&t.preventDefault(),l(this))return;N.one(e,Wn,(()=>{a(this)&&this.focus()}));const i=z.findOne(Pn);i&&i!==e&&Kn.getInstance(i).hide(),Kn.getOrCreateInstance(e).toggle(this)})),N.on(window,Dn,(()=>{for(const t of z.find(Pn))Kn.getOrCreateInstance(t).show()})),N.on(window,Bn,(()=>{for(const t of z.find("[aria-modal][class*=show][class*=offcanvas-]"))"fixed"!==getComputedStyle(t).position&&Kn.getOrCreateInstance(t).hide()})),R(Kn),m(Kn);const Qn={"*":["class","dir","id","lang","role",/^aria-[\w-]*$/i],a:["target","href","title","rel"],area:[],b:[],br:[],col:[],code:[],dd:[],div:[],dl:[],dt:[],em:[],hr:[],h1:[],h2:[],h3:[],h4:[],h5:[],h6:[],i:[],img:["src","srcset","alt","title","width","height"],li:[],ol:[],p:[],pre:[],s:[],small:[],span:[],sub:[],sup:[],strong:[],u:[],ul:[]},Xn=new Set(["background","cite","href","itemtype","longdesc","poster","src","xlink:href"]),Yn=/^(?!javascript:)(?:[a-z0-9+.-]+:|[^&:/?#]*(?:[/?#]|$))/i,Un=(t,e)=>{const i=t.nodeName.toLowerCase();return e.includes(i)?!Xn.has(i)||Boolean(Yn.test(t.nodeValue)):e.filter((t=>t instanceof RegExp)).some((t=>t.test(i)))},Gn={allowList:Qn,content:{},extraClass:"",html:!1,sanitize:!0,sanitizeFn:null,template:"
"},Jn={allowList:"object",content:"object",extraClass:"(string|function)",html:"boolean",sanitize:"boolean",sanitizeFn:"(null|function)",template:"string"},Zn={entry:"(string|element|function|null)",selector:"(string|element)"};class ts extends H{constructor(t){super(),this._config=this._getConfig(t)}static get Default(){return Gn}static get DefaultType(){return Jn}static get NAME(){return"TemplateFactory"}getContent(){return Object.values(this._config.content).map((t=>this._resolvePossibleFunction(t))).filter(Boolean)}hasContent(){return this.getContent().length>0}changeContent(t){return this._checkContent(t),this._config.content={...this._config.content,...t},this}toHtml(){const t=document.createElement("div");t.innerHTML=this._maybeSanitize(this._config.template);for(const[e,i]of Object.entries(this._config.content))this._setContent(t,i,e);const e=t.children[0],i=this._resolvePossibleFunction(this._config.extraClass);return i&&e.classList.add(...i.split(" ")),e}_typeCheckConfig(t){super._typeCheckConfig(t),this._checkContent(t.content)}_checkContent(t){for(const[e,i]of Object.entries(t))super._typeCheckConfig({selector:e,entry:i},Zn)}_setContent(t,e,i){const n=z.findOne(i,t);n&&((e=this._resolvePossibleFunction(e))?o(e)?this._putElementInTemplate(r(e),n):this._config.html?n.innerHTML=this._maybeSanitize(e):n.textContent=e:n.remove())}_maybeSanitize(t){return this._config.sanitize?function(t,e,i){if(!t.length)return t;if(i&&"function"==typeof i)return i(t);const n=(new window.DOMParser).parseFromString(t,"text/html"),s=[].concat(...n.body.querySelectorAll("*"));for(const t of s){const i=t.nodeName.toLowerCase();if(!Object.keys(e).includes(i)){t.remove();continue}const n=[].concat(...t.attributes),s=[].concat(e["*"]||[],e[i]||[]);for(const e of n)Un(e,s)||t.removeAttribute(e.nodeName)}return n.body.innerHTML}(t,this._config.allowList,this._config.sanitizeFn):t}_resolvePossibleFunction(t){return g(t,[void 0,this])}_putElementInTemplate(t,e){if(this._config.html)return e.innerHTML="",void e.append(t);e.textContent=t.textContent}}const es=new Set(["sanitize","allowList","sanitizeFn"]),is="fade",ns="show",ss=".tooltip-inner",os=".modal",rs="hide.bs.modal",as="hover",ls="focus",cs={AUTO:"auto",TOP:"top",RIGHT:p()?"left":"right",BOTTOM:"bottom",LEFT:p()?"right":"left"},hs={allowList:Qn,animation:!0,boundary:"clippingParents",container:!1,customClass:"",delay:0,fallbackPlacements:["top","right","bottom","left"],html:!1,offset:[0,6],placement:"top",popperConfig:null,sanitize:!0,sanitizeFn:null,selector:!1,template:'',title:"",trigger:"hover focus"},ds={allowList:"object",animation:"boolean",boundary:"(string|element)",container:"(string|element|boolean)",customClass:"(string|function)",delay:"(number|object)",fallbackPlacements:"array",html:"boolean",offset:"(array|string|function)",placement:"(string|function)",popperConfig:"(null|object|function)",sanitize:"boolean",sanitizeFn:"(null|function)",selector:"(string|boolean)",template:"string",title:"(string|element|function)",trigger:"string"};class us extends W{constructor(t,e){if(void 0===wi)throw new TypeError("Bootstrap's tooltips require Popper (https://popper.js.org/docs/v2/)");super(t,e),this._isEnabled=!0,this._timeout=0,this._isHovered=null,this._activeTrigger={},this._popper=null,this._templateFactory=null,this._newContent=null,this.tip=null,this._setListeners(),this._config.selector||this._fixTitle()}static get Default(){return hs}static get DefaultType(){return ds}static get NAME(){return"tooltip"}enable(){this._isEnabled=!0}disable(){this._isEnabled=!1}toggleEnabled(){this._isEnabled=!this._isEnabled}toggle(){this._isEnabled&&(this._isShown()?this._leave():this._enter())}dispose(){clearTimeout(this._timeout),N.off(this._element.closest(os),rs,this._hideModalHandler),this._element.getAttribute("data-bs-original-title")&&this._element.setAttribute("title",this._element.getAttribute("data-bs-original-title")),this._disposePopper(),super.dispose()}show(){if("none"===this._element.style.display)throw new Error("Please use show on visible elements");if(!this._isWithContent()||!this._isEnabled)return;const t=N.trigger(this._element,this.constructor.eventName("show")),e=(c(this._element)||this._element.ownerDocument.documentElement).contains(this._element);if(t.defaultPrevented||!e)return;this._disposePopper();const i=this._getTipElement();this._element.setAttribute("aria-describedby",i.getAttribute("id"));const{container:n}=this._config;if(this._element.ownerDocument.documentElement.contains(this.tip)||(n.append(i),N.trigger(this._element,this.constructor.eventName("inserted"))),this._popper=this._createPopper(i),i.classList.add(ns),"ontouchstart"in document.documentElement)for(const t of[].concat(...document.body.children))N.on(t,"mouseover",h);this._queueCallback((()=>{N.trigger(this._element,this.constructor.eventName("shown")),!1===this._isHovered&&this._leave(),this._isHovered=!1}),this.tip,this._isAnimated())}hide(){if(this._isShown()&&!N.trigger(this._element,this.constructor.eventName("hide")).defaultPrevented){if(this._getTipElement().classList.remove(ns),"ontouchstart"in document.documentElement)for(const t of[].concat(...document.body.children))N.off(t,"mouseover",h);this._activeTrigger.click=!1,this._activeTrigger[ls]=!1,this._activeTrigger[as]=!1,this._isHovered=null,this._queueCallback((()=>{this._isWithActiveTrigger()||(this._isHovered||this._disposePopper(),this._element.removeAttribute("aria-describedby"),N.trigger(this._element,this.constructor.eventName("hidden")))}),this.tip,this._isAnimated())}}update(){this._popper&&this._popper.update()}_isWithContent(){return Boolean(this._getTitle())}_getTipElement(){return this.tip||(this.tip=this._createTipElement(this._newContent||this._getContentForTemplate())),this.tip}_createTipElement(t){const e=this._getTemplateFactory(t).toHtml();if(!e)return null;e.classList.remove(is,ns),e.classList.add(`bs-${this.constructor.NAME}-auto`);const i=(t=>{do{t+=Math.floor(1e6*Math.random())}while(document.getElementById(t));return t})(this.constructor.NAME).toString();return e.setAttribute("id",i),this._isAnimated()&&e.classList.add(is),e}setContent(t){this._newContent=t,this._isShown()&&(this._disposePopper(),this.show())}_getTemplateFactory(t){return this._templateFactory?this._templateFactory.changeContent(t):this._templateFactory=new ts({...this._config,content:t,extraClass:this._resolvePossibleFunction(this._config.customClass)}),this._templateFactory}_getContentForTemplate(){return{[ss]:this._getTitle()}}_getTitle(){return this._resolvePossibleFunction(this._config.title)||this._element.getAttribute("data-bs-original-title")}_initializeOnDelegatedTarget(t){return this.constructor.getOrCreateInstance(t.delegateTarget,this._getDelegateConfig())}_isAnimated(){return this._config.animation||this.tip&&this.tip.classList.contains(is)}_isShown(){return this.tip&&this.tip.classList.contains(ns)}_createPopper(t){const e=g(this._config.placement,[this,t,this._element]),i=cs[e.toUpperCase()];return yi(this._element,t,this._getPopperConfig(i))}_getOffset(){const{offset:t}=this._config;return"string"==typeof t?t.split(",").map((t=>Number.parseInt(t,10))):"function"==typeof t?e=>t(e,this._element):t}_resolvePossibleFunction(t){return g(t,[this._element,this._element])}_getPopperConfig(t){const e={placement:t,modifiers:[{name:"flip",options:{fallbackPlacements:this._config.fallbackPlacements}},{name:"offset",options:{offset:this._getOffset()}},{name:"preventOverflow",options:{boundary:this._config.boundary}},{name:"arrow",options:{element:`.${this.constructor.NAME}-arrow`}},{name:"preSetPlacement",enabled:!0,phase:"beforeMain",fn:t=>{this._getTipElement().setAttribute("data-popper-placement",t.state.placement)}}]};return{...e,...g(this._config.popperConfig,[void 0,e])}}_setListeners(){const t=this._config.trigger.split(" ");for(const e of t)if("click"===e)N.on(this._element,this.constructor.eventName("click"),this._config.selector,(t=>{this._initializeOnDelegatedTarget(t).toggle()}));else if("manual"!==e){const t=e===as?this.constructor.eventName("mouseenter"):this.constructor.eventName("focusin"),i=e===as?this.constructor.eventName("mouseleave"):this.constructor.eventName("focusout");N.on(this._element,t,this._config.selector,(t=>{const e=this._initializeOnDelegatedTarget(t);e._activeTrigger["focusin"===t.type?ls:as]=!0,e._enter()})),N.on(this._element,i,this._config.selector,(t=>{const e=this._initializeOnDelegatedTarget(t);e._activeTrigger["focusout"===t.type?ls:as]=e._element.contains(t.relatedTarget),e._leave()}))}this._hideModalHandler=()=>{this._element&&this.hide()},N.on(this._element.closest(os),rs,this._hideModalHandler)}_fixTitle(){const t=this._element.getAttribute("title");t&&(this._element.getAttribute("aria-label")||this._element.textContent.trim()||this._element.setAttribute("aria-label",t),this._element.setAttribute("data-bs-original-title",t),this._element.removeAttribute("title"))}_enter(){this._isShown()||this._isHovered?this._isHovered=!0:(this._isHovered=!0,this._setTimeout((()=>{this._isHovered&&this.show()}),this._config.delay.show))}_leave(){this._isWithActiveTrigger()||(this._isHovered=!1,this._setTimeout((()=>{this._isHovered||this.hide()}),this._config.delay.hide))}_setTimeout(t,e){clearTimeout(this._timeout),this._timeout=setTimeout(t,e)}_isWithActiveTrigger(){return Object.values(this._activeTrigger).includes(!0)}_getConfig(t){const e=F.getDataAttributes(this._element);for(const t of Object.keys(e))es.has(t)&&delete e[t];return t={...e,..."object"==typeof t&&t?t:{}},t=this._mergeConfigObj(t),t=this._configAfterMerge(t),this._typeCheckConfig(t),t}_configAfterMerge(t){return t.container=!1===t.container?document.body:r(t.container),"number"==typeof t.delay&&(t.delay={show:t.delay,hide:t.delay}),"number"==typeof t.title&&(t.title=t.title.toString()),"number"==typeof t.content&&(t.content=t.content.toString()),t}_getDelegateConfig(){const t={};for(const[e,i]of Object.entries(this._config))this.constructor.Default[e]!==i&&(t[e]=i);return t.selector=!1,t.trigger="manual",t}_disposePopper(){this._popper&&(this._popper.destroy(),this._popper=null),this.tip&&(this.tip.remove(),this.tip=null)}static jQueryInterface(t){return this.each((function(){const e=us.getOrCreateInstance(this,t);if("string"==typeof t){if(void 0===e[t])throw new TypeError(`No method named "${t}"`);e[t]()}}))}}m(us);const fs=".popover-header",ps=".popover-body",ms={...us.Default,content:"",offset:[0,8],placement:"right",template:'',trigger:"click"},gs={...us.DefaultType,content:"(null|string|element|function)"};class _s extends us{static get Default(){return ms}static get DefaultType(){return gs}static get NAME(){return"popover"}_isWithContent(){return this._getTitle()||this._getContent()}_getContentForTemplate(){return{[fs]:this._getTitle(),[ps]:this._getContent()}}_getContent(){return this._resolvePossibleFunction(this._config.content)}static jQueryInterface(t){return this.each((function(){const e=_s.getOrCreateInstance(this,t);if("string"==typeof t){if(void 0===e[t])throw new TypeError(`No method named "${t}"`);e[t]()}}))}}m(_s);const bs=".bs.scrollspy",vs=`activate${bs}`,ys=`click${bs}`,ws=`load${bs}.data-api`,As="active",Es="[href]",Ts=".nav-link",Cs=`${Ts}, .nav-item > ${Ts}, .list-group-item`,Os={offset:null,rootMargin:"0px 0px -25%",smoothScroll:!1,target:null,threshold:[.1,.5,1]},xs={offset:"(number|null)",rootMargin:"string",smoothScroll:"boolean",target:"element",threshold:"array"};class ks extends W{constructor(t,e){super(t,e),this._targetLinks=new Map,this._observableSections=new Map,this._rootElement="visible"===getComputedStyle(this._element).overflowY?null:this._element,this._activeTarget=null,this._observer=null,this._previousScrollData={visibleEntryTop:0,parentScrollTop:0},this.refresh()}static get Default(){return Os}static get DefaultType(){return xs}static get NAME(){return"scrollspy"}refresh(){this._initializeTargetsAndObservables(),this._maybeEnableSmoothScroll(),this._observer?this._observer.disconnect():this._observer=this._getNewObserver();for(const t of this._observableSections.values())this._observer.observe(t)}dispose(){this._observer.disconnect(),super.dispose()}_configAfterMerge(t){return t.target=r(t.target)||document.body,t.rootMargin=t.offset?`${t.offset}px 0px -30%`:t.rootMargin,"string"==typeof t.threshold&&(t.threshold=t.threshold.split(",").map((t=>Number.parseFloat(t)))),t}_maybeEnableSmoothScroll(){this._config.smoothScroll&&(N.off(this._config.target,ys),N.on(this._config.target,ys,Es,(t=>{const e=this._observableSections.get(t.target.hash);if(e){t.preventDefault();const i=this._rootElement||window,n=e.offsetTop-this._element.offsetTop;if(i.scrollTo)return void i.scrollTo({top:n,behavior:"smooth"});i.scrollTop=n}})))}_getNewObserver(){const t={root:this._rootElement,threshold:this._config.threshold,rootMargin:this._config.rootMargin};return new IntersectionObserver((t=>this._observerCallback(t)),t)}_observerCallback(t){const e=t=>this._targetLinks.get(`#${t.target.id}`),i=t=>{this._previousScrollData.visibleEntryTop=t.target.offsetTop,this._process(e(t))},n=(this._rootElement||document.documentElement).scrollTop,s=n>=this._previousScrollData.parentScrollTop;this._previousScrollData.parentScrollTop=n;for(const o of t){if(!o.isIntersecting){this._activeTarget=null,this._clearActiveClass(e(o));continue}const t=o.target.offsetTop>=this._previousScrollData.visibleEntryTop;if(s&&t){if(i(o),!n)return}else s||t||i(o)}}_initializeTargetsAndObservables(){this._targetLinks=new Map,this._observableSections=new Map;const t=z.find(Es,this._config.target);for(const e of t){if(!e.hash||l(e))continue;const t=z.findOne(decodeURI(e.hash),this._element);a(t)&&(this._targetLinks.set(decodeURI(e.hash),e),this._observableSections.set(e.hash,t))}}_process(t){this._activeTarget!==t&&(this._clearActiveClass(this._config.target),this._activeTarget=t,t.classList.add(As),this._activateParents(t),N.trigger(this._element,vs,{relatedTarget:t}))}_activateParents(t){if(t.classList.contains("dropdown-item"))z.findOne(".dropdown-toggle",t.closest(".dropdown")).classList.add(As);else for(const e of z.parents(t,".nav, .list-group"))for(const t of z.prev(e,Cs))t.classList.add(As)}_clearActiveClass(t){t.classList.remove(As);const e=z.find(`${Es}.${As}`,t);for(const t of e)t.classList.remove(As)}static jQueryInterface(t){return this.each((function(){const e=ks.getOrCreateInstance(this,t);if("string"==typeof t){if(void 0===e[t]||t.startsWith("_")||"constructor"===t)throw new TypeError(`No method named "${t}"`);e[t]()}}))}}N.on(window,ws,(()=>{for(const t of z.find('[data-bs-spy="scroll"]'))ks.getOrCreateInstance(t)})),m(ks);const Ls=".bs.tab",Ss=`hide${Ls}`,Ds=`hidden${Ls}`,$s=`show${Ls}`,Is=`shown${Ls}`,Ns=`click${Ls}`,Ps=`keydown${Ls}`,js=`load${Ls}`,Ms="ArrowLeft",Fs="ArrowRight",Hs="ArrowUp",Ws="ArrowDown",Bs="Home",zs="End",Rs="active",qs="fade",Vs="show",Ks=".dropdown-toggle",Qs=`:not(${Ks})`,Xs='[data-bs-toggle="tab"], [data-bs-toggle="pill"], [data-bs-toggle="list"]',Ys=`.nav-link${Qs}, .list-group-item${Qs}, [role="tab"]${Qs}, ${Xs}`,Us=`.${Rs}[data-bs-toggle="tab"], .${Rs}[data-bs-toggle="pill"], .${Rs}[data-bs-toggle="list"]`;class Gs extends W{constructor(t){super(t),this._parent=this._element.closest('.list-group, .nav, [role="tablist"]'),this._parent&&(this._setInitialAttributes(this._parent,this._getChildren()),N.on(this._element,Ps,(t=>this._keydown(t))))}static get NAME(){return"tab"}show(){const t=this._element;if(this._elemIsActive(t))return;const e=this._getActiveElem(),i=e?N.trigger(e,Ss,{relatedTarget:t}):null;N.trigger(t,$s,{relatedTarget:e}).defaultPrevented||i&&i.defaultPrevented||(this._deactivate(e,t),this._activate(t,e))}_activate(t,e){t&&(t.classList.add(Rs),this._activate(z.getElementFromSelector(t)),this._queueCallback((()=>{"tab"===t.getAttribute("role")?(t.removeAttribute("tabindex"),t.setAttribute("aria-selected",!0),this._toggleDropDown(t,!0),N.trigger(t,Is,{relatedTarget:e})):t.classList.add(Vs)}),t,t.classList.contains(qs)))}_deactivate(t,e){t&&(t.classList.remove(Rs),t.blur(),this._deactivate(z.getElementFromSelector(t)),this._queueCallback((()=>{"tab"===t.getAttribute("role")?(t.setAttribute("aria-selected",!1),t.setAttribute("tabindex","-1"),this._toggleDropDown(t,!1),N.trigger(t,Ds,{relatedTarget:e})):t.classList.remove(Vs)}),t,t.classList.contains(qs)))}_keydown(t){if(![Ms,Fs,Hs,Ws,Bs,zs].includes(t.key))return;t.stopPropagation(),t.preventDefault();const e=this._getChildren().filter((t=>!l(t)));let i;if([Bs,zs].includes(t.key))i=e[t.key===Bs?0:e.length-1];else{const n=[Fs,Ws].includes(t.key);i=b(e,t.target,n,!0)}i&&(i.focus({preventScroll:!0}),Gs.getOrCreateInstance(i).show())}_getChildren(){return z.find(Ys,this._parent)}_getActiveElem(){return this._getChildren().find((t=>this._elemIsActive(t)))||null}_setInitialAttributes(t,e){this._setAttributeIfNotExists(t,"role","tablist");for(const t of e)this._setInitialAttributesOnChild(t)}_setInitialAttributesOnChild(t){t=this._getInnerElement(t);const e=this._elemIsActive(t),i=this._getOuterElement(t);t.setAttribute("aria-selected",e),i!==t&&this._setAttributeIfNotExists(i,"role","presentation"),e||t.setAttribute("tabindex","-1"),this._setAttributeIfNotExists(t,"role","tab"),this._setInitialAttributesOnTargetPanel(t)}_setInitialAttributesOnTargetPanel(t){const e=z.getElementFromSelector(t);e&&(this._setAttributeIfNotExists(e,"role","tabpanel"),t.id&&this._setAttributeIfNotExists(e,"aria-labelledby",`${t.id}`))}_toggleDropDown(t,e){const i=this._getOuterElement(t);if(!i.classList.contains("dropdown"))return;const n=(t,n)=>{const s=z.findOne(t,i);s&&s.classList.toggle(n,e)};n(Ks,Rs),n(".dropdown-menu",Vs),i.setAttribute("aria-expanded",e)}_setAttributeIfNotExists(t,e,i){t.hasAttribute(e)||t.setAttribute(e,i)}_elemIsActive(t){return t.classList.contains(Rs)}_getInnerElement(t){return t.matches(Ys)?t:z.findOne(Ys,t)}_getOuterElement(t){return t.closest(".nav-item, .list-group-item")||t}static jQueryInterface(t){return this.each((function(){const e=Gs.getOrCreateInstance(this);if("string"==typeof t){if(void 0===e[t]||t.startsWith("_")||"constructor"===t)throw new TypeError(`No method named "${t}"`);e[t]()}}))}}N.on(document,Ns,Xs,(function(t){["A","AREA"].includes(this.tagName)&&t.preventDefault(),l(this)||Gs.getOrCreateInstance(this).show()})),N.on(window,js,(()=>{for(const t of z.find(Us))Gs.getOrCreateInstance(t)})),m(Gs);const Js=".bs.toast",Zs=`mouseover${Js}`,to=`mouseout${Js}`,eo=`focusin${Js}`,io=`focusout${Js}`,no=`hide${Js}`,so=`hidden${Js}`,oo=`show${Js}`,ro=`shown${Js}`,ao="hide",lo="show",co="showing",ho={animation:"boolean",autohide:"boolean",delay:"number"},uo={animation:!0,autohide:!0,delay:5e3};class fo extends W{constructor(t,e){super(t,e),this._timeout=null,this._hasMouseInteraction=!1,this._hasKeyboardInteraction=!1,this._setListeners()}static get Default(){return uo}static get DefaultType(){return ho}static get NAME(){return"toast"}show(){N.trigger(this._element,oo).defaultPrevented||(this._clearTimeout(),this._config.animation&&this._element.classList.add("fade"),this._element.classList.remove(ao),d(this._element),this._element.classList.add(lo,co),this._queueCallback((()=>{this._element.classList.remove(co),N.trigger(this._element,ro),this._maybeScheduleHide()}),this._element,this._config.animation))}hide(){this.isShown()&&(N.trigger(this._element,no).defaultPrevented||(this._element.classList.add(co),this._queueCallback((()=>{this._element.classList.add(ao),this._element.classList.remove(co,lo),N.trigger(this._element,so)}),this._element,this._config.animation)))}dispose(){this._clearTimeout(),this.isShown()&&this._element.classList.remove(lo),super.dispose()}isShown(){return this._element.classList.contains(lo)}_maybeScheduleHide(){this._config.autohide&&(this._hasMouseInteraction||this._hasKeyboardInteraction||(this._timeout=setTimeout((()=>{this.hide()}),this._config.delay)))}_onInteraction(t,e){switch(t.type){case"mouseover":case"mouseout":this._hasMouseInteraction=e;break;case"focusin":case"focusout":this._hasKeyboardInteraction=e}if(e)return void this._clearTimeout();const i=t.relatedTarget;this._element===i||this._element.contains(i)||this._maybeScheduleHide()}_setListeners(){N.on(this._element,Zs,(t=>this._onInteraction(t,!0))),N.on(this._element,to,(t=>this._onInteraction(t,!1))),N.on(this._element,eo,(t=>this._onInteraction(t,!0))),N.on(this._element,io,(t=>this._onInteraction(t,!1)))}_clearTimeout(){clearTimeout(this._timeout),this._timeout=null}static jQueryInterface(t){return this.each((function(){const e=fo.getOrCreateInstance(this,t);if("string"==typeof t){if(void 0===e[t])throw new TypeError(`No method named "${t}"`);e[t](this)}}))}}return R(fo),m(fo),{Alert:Q,Button:Y,Carousel:Lt,Collapse:Rt,Dropdown:Ki,Modal:kn,Offcanvas:Kn,Popover:_s,ScrollSpy:ks,Tab:Gs,Toast:fo,Tooltip:us}})); -//# sourceMappingURL=bootstrap.bundle.min.js.map \ No newline at end of file diff --git a/backend/coverage-report-with-models/_js/d3.min.js b/backend/coverage-report-with-models/_js/d3.min.js deleted file mode 100644 index 16648730..00000000 --- a/backend/coverage-report-with-models/_js/d3.min.js +++ /dev/null @@ -1,5 +0,0 @@ -!function(){function n(n){return n&&(n.ownerDocument||n.document||n).documentElement}function t(n){return n&&(n.ownerDocument&&n.ownerDocument.defaultView||n.document&&n||n.defaultView)}function e(n,t){return t>n?-1:n>t?1:n>=t?0:NaN}function r(n){return null===n?NaN:+n}function i(n){return!isNaN(n)}function u(n){return{left:function(t,e,r,i){for(arguments.length<3&&(r=0),arguments.length<4&&(i=t.length);i>r;){var u=r+i>>>1;n(t[u],e)<0?r=u+1:i=u}return r},right:function(t,e,r,i){for(arguments.length<3&&(r=0),arguments.length<4&&(i=t.length);i>r;){var u=r+i>>>1;n(t[u],e)>0?i=u:r=u+1}return r}}}function o(n){return n.length}function a(n){for(var t=1;n*t%1;)t*=10;return t}function l(n,t){for(var e in t)Object.defineProperty(n.prototype,e,{value:t[e],enumerable:!1})}function c(){this._=Object.create(null)}function f(n){return(n+="")===bo||n[0]===_o?_o+n:n}function s(n){return(n+="")[0]===_o?n.slice(1):n}function h(n){return f(n)in this._}function p(n){return(n=f(n))in this._&&delete this._[n]}function g(){var n=[];for(var t in this._)n.push(s(t));return n}function v(){var n=0;for(var t in this._)++n;return n}function d(){for(var n in this._)return!1;return!0}function y(){this._=Object.create(null)}function m(n){return n}function M(n,t,e){return function(){var r=e.apply(t,arguments);return r===t?n:r}}function x(n,t){if(t in n)return t;t=t.charAt(0).toUpperCase()+t.slice(1);for(var e=0,r=wo.length;r>e;++e){var i=wo[e]+t;if(i in n)return i}}function b(){}function _(){}function w(n){function t(){for(var t,r=e,i=-1,u=r.length;++ie;e++)for(var i,u=n[e],o=0,a=u.length;a>o;o++)(i=u[o])&&t(i,o,e);return n}function Z(n){return ko(n,qo),n}function V(n){var t,e;return function(r,i,u){var o,a=n[u].update,l=a.length;for(u!=e&&(e=u,t=0),i>=t&&(t=i+1);!(o=a[t])&&++t0&&(n=n.slice(0,a));var c=To.get(n);return c&&(n=c,l=B),a?t?i:r:t?b:u}function $(n,t){return function(e){var r=ao.event;ao.event=e,t[0]=this.__data__;try{n.apply(this,t)}finally{ao.event=r}}}function B(n,t){var e=$(n,t);return function(n){var t=this,r=n.relatedTarget;r&&(r===t||8&r.compareDocumentPosition(t))||e.call(t,n)}}function W(e){var r=".dragsuppress-"+ ++Do,i="click"+r,u=ao.select(t(e)).on("touchmove"+r,S).on("dragstart"+r,S).on("selectstart"+r,S);if(null==Ro&&(Ro="onselectstart"in e?!1:x(e.style,"userSelect")),Ro){var o=n(e).style,a=o[Ro];o[Ro]="none"}return function(n){if(u.on(r,null),Ro&&(o[Ro]=a),n){var t=function(){u.on(i,null)};u.on(i,function(){S(),t()},!0),setTimeout(t,0)}}}function J(n,e){e.changedTouches&&(e=e.changedTouches[0]);var r=n.ownerSVGElement||n;if(r.createSVGPoint){var i=r.createSVGPoint();if(0>Po){var u=t(n);if(u.scrollX||u.scrollY){r=ao.select("body").append("svg").style({position:"absolute",top:0,left:0,margin:0,padding:0,border:"none"},"important");var o=r[0][0].getScreenCTM();Po=!(o.f||o.e),r.remove()}}return Po?(i.x=e.pageX,i.y=e.pageY):(i.x=e.clientX,i.y=e.clientY),i=i.matrixTransform(n.getScreenCTM().inverse()),[i.x,i.y]}var a=n.getBoundingClientRect();return[e.clientX-a.left-n.clientLeft,e.clientY-a.top-n.clientTop]}function G(){return ao.event.changedTouches[0].identifier}function K(n){return n>0?1:0>n?-1:0}function Q(n,t,e){return(t[0]-n[0])*(e[1]-n[1])-(t[1]-n[1])*(e[0]-n[0])}function nn(n){return n>1?0:-1>n?Fo:Math.acos(n)}function tn(n){return n>1?Io:-1>n?-Io:Math.asin(n)}function en(n){return((n=Math.exp(n))-1/n)/2}function rn(n){return((n=Math.exp(n))+1/n)/2}function un(n){return((n=Math.exp(2*n))-1)/(n+1)}function on(n){return(n=Math.sin(n/2))*n}function an(){}function ln(n,t,e){return this instanceof ln?(this.h=+n,this.s=+t,void(this.l=+e)):arguments.length<2?n instanceof ln?new ln(n.h,n.s,n.l):_n(""+n,wn,ln):new ln(n,t,e)}function cn(n,t,e){function r(n){return n>360?n-=360:0>n&&(n+=360),60>n?u+(o-u)*n/60:180>n?o:240>n?u+(o-u)*(240-n)/60:u}function i(n){return Math.round(255*r(n))}var u,o;return n=isNaN(n)?0:(n%=360)<0?n+360:n,t=isNaN(t)?0:0>t?0:t>1?1:t,e=0>e?0:e>1?1:e,o=.5>=e?e*(1+t):e+t-e*t,u=2*e-o,new mn(i(n+120),i(n),i(n-120))}function fn(n,t,e){return this instanceof fn?(this.h=+n,this.c=+t,void(this.l=+e)):arguments.length<2?n instanceof fn?new fn(n.h,n.c,n.l):n instanceof hn?gn(n.l,n.a,n.b):gn((n=Sn((n=ao.rgb(n)).r,n.g,n.b)).l,n.a,n.b):new fn(n,t,e)}function sn(n,t,e){return isNaN(n)&&(n=0),isNaN(t)&&(t=0),new hn(e,Math.cos(n*=Yo)*t,Math.sin(n)*t)}function hn(n,t,e){return this instanceof hn?(this.l=+n,this.a=+t,void(this.b=+e)):arguments.length<2?n instanceof hn?new hn(n.l,n.a,n.b):n instanceof fn?sn(n.h,n.c,n.l):Sn((n=mn(n)).r,n.g,n.b):new hn(n,t,e)}function pn(n,t,e){var r=(n+16)/116,i=r+t/500,u=r-e/200;return i=vn(i)*na,r=vn(r)*ta,u=vn(u)*ea,new mn(yn(3.2404542*i-1.5371385*r-.4985314*u),yn(-.969266*i+1.8760108*r+.041556*u),yn(.0556434*i-.2040259*r+1.0572252*u))}function gn(n,t,e){return n>0?new fn(Math.atan2(e,t)*Zo,Math.sqrt(t*t+e*e),n):new fn(NaN,NaN,n)}function vn(n){return n>.206893034?n*n*n:(n-4/29)/7.787037}function dn(n){return n>.008856?Math.pow(n,1/3):7.787037*n+4/29}function yn(n){return Math.round(255*(.00304>=n?12.92*n:1.055*Math.pow(n,1/2.4)-.055))}function mn(n,t,e){return this instanceof mn?(this.r=~~n,this.g=~~t,void(this.b=~~e)):arguments.length<2?n instanceof mn?new mn(n.r,n.g,n.b):_n(""+n,mn,cn):new mn(n,t,e)}function Mn(n){return new mn(n>>16,n>>8&255,255&n)}function xn(n){return Mn(n)+""}function bn(n){return 16>n?"0"+Math.max(0,n).toString(16):Math.min(255,n).toString(16)}function _n(n,t,e){var r,i,u,o=0,a=0,l=0;if(r=/([a-z]+)\((.*)\)/.exec(n=n.toLowerCase()))switch(i=r[2].split(","),r[1]){case"hsl":return e(parseFloat(i[0]),parseFloat(i[1])/100,parseFloat(i[2])/100);case"rgb":return t(Nn(i[0]),Nn(i[1]),Nn(i[2]))}return(u=ua.get(n))?t(u.r,u.g,u.b):(null==n||"#"!==n.charAt(0)||isNaN(u=parseInt(n.slice(1),16))||(4===n.length?(o=(3840&u)>>4,o=o>>4|o,a=240&u,a=a>>4|a,l=15&u,l=l<<4|l):7===n.length&&(o=(16711680&u)>>16,a=(65280&u)>>8,l=255&u)),t(o,a,l))}function wn(n,t,e){var r,i,u=Math.min(n/=255,t/=255,e/=255),o=Math.max(n,t,e),a=o-u,l=(o+u)/2;return a?(i=.5>l?a/(o+u):a/(2-o-u),r=n==o?(t-e)/a+(e>t?6:0):t==o?(e-n)/a+2:(n-t)/a+4,r*=60):(r=NaN,i=l>0&&1>l?0:r),new ln(r,i,l)}function Sn(n,t,e){n=kn(n),t=kn(t),e=kn(e);var r=dn((.4124564*n+.3575761*t+.1804375*e)/na),i=dn((.2126729*n+.7151522*t+.072175*e)/ta),u=dn((.0193339*n+.119192*t+.9503041*e)/ea);return hn(116*i-16,500*(r-i),200*(i-u))}function kn(n){return(n/=255)<=.04045?n/12.92:Math.pow((n+.055)/1.055,2.4)}function Nn(n){var t=parseFloat(n);return"%"===n.charAt(n.length-1)?Math.round(2.55*t):t}function En(n){return"function"==typeof n?n:function(){return n}}function An(n){return function(t,e,r){return 2===arguments.length&&"function"==typeof e&&(r=e,e=null),Cn(t,e,n,r)}}function Cn(n,t,e,r){function i(){var n,t=l.status;if(!t&&Ln(l)||t>=200&&300>t||304===t){try{n=e.call(u,l)}catch(r){return void o.error.call(u,r)}o.load.call(u,n)}else o.error.call(u,l)}var u={},o=ao.dispatch("beforesend","progress","load","error"),a={},l=new XMLHttpRequest,c=null;return!this.XDomainRequest||"withCredentials"in l||!/^(http(s)?:)?\/\//.test(n)||(l=new XDomainRequest),"onload"in l?l.onload=l.onerror=i:l.onreadystatechange=function(){l.readyState>3&&i()},l.onprogress=function(n){var t=ao.event;ao.event=n;try{o.progress.call(u,l)}finally{ao.event=t}},u.header=function(n,t){return n=(n+"").toLowerCase(),arguments.length<2?a[n]:(null==t?delete a[n]:a[n]=t+"",u)},u.mimeType=function(n){return arguments.length?(t=null==n?null:n+"",u):t},u.responseType=function(n){return arguments.length?(c=n,u):c},u.response=function(n){return e=n,u},["get","post"].forEach(function(n){u[n]=function(){return u.send.apply(u,[n].concat(co(arguments)))}}),u.send=function(e,r,i){if(2===arguments.length&&"function"==typeof r&&(i=r,r=null),l.open(e,n,!0),null==t||"accept"in a||(a.accept=t+",*/*"),l.setRequestHeader)for(var f in a)l.setRequestHeader(f,a[f]);return null!=t&&l.overrideMimeType&&l.overrideMimeType(t),null!=c&&(l.responseType=c),null!=i&&u.on("error",i).on("load",function(n){i(null,n)}),o.beforesend.call(u,l),l.send(null==r?null:r),u},u.abort=function(){return l.abort(),u},ao.rebind(u,o,"on"),null==r?u:u.get(zn(r))}function zn(n){return 1===n.length?function(t,e){n(null==t?e:null)}:n}function Ln(n){var t=n.responseType;return t&&"text"!==t?n.response:n.responseText}function qn(n,t,e){var r=arguments.length;2>r&&(t=0),3>r&&(e=Date.now());var i=e+t,u={c:n,t:i,n:null};return aa?aa.n=u:oa=u,aa=u,la||(ca=clearTimeout(ca),la=1,fa(Tn)),u}function Tn(){var n=Rn(),t=Dn()-n;t>24?(isFinite(t)&&(clearTimeout(ca),ca=setTimeout(Tn,t)),la=0):(la=1,fa(Tn))}function Rn(){for(var n=Date.now(),t=oa;t;)n>=t.t&&t.c(n-t.t)&&(t.c=null),t=t.n;return n}function Dn(){for(var n,t=oa,e=1/0;t;)t.c?(t.t8?function(n){return n/e}:function(n){return n*e},symbol:n}}function jn(n){var t=n.decimal,e=n.thousands,r=n.grouping,i=n.currency,u=r&&e?function(n,t){for(var i=n.length,u=[],o=0,a=r[0],l=0;i>0&&a>0&&(l+a+1>t&&(a=Math.max(1,t-l)),u.push(n.substring(i-=a,i+a)),!((l+=a+1)>t));)a=r[o=(o+1)%r.length];return u.reverse().join(e)}:m;return function(n){var e=ha.exec(n),r=e[1]||" ",o=e[2]||">",a=e[3]||"-",l=e[4]||"",c=e[5],f=+e[6],s=e[7],h=e[8],p=e[9],g=1,v="",d="",y=!1,m=!0;switch(h&&(h=+h.substring(1)),(c||"0"===r&&"="===o)&&(c=r="0",o="="),p){case"n":s=!0,p="g";break;case"%":g=100,d="%",p="f";break;case"p":g=100,d="%",p="r";break;case"b":case"o":case"x":case"X":"#"===l&&(v="0"+p.toLowerCase());case"c":m=!1;case"d":y=!0,h=0;break;case"s":g=-1,p="r"}"$"===l&&(v=i[0],d=i[1]),"r"!=p||h||(p="g"),null!=h&&("g"==p?h=Math.max(1,Math.min(21,h)):"e"!=p&&"f"!=p||(h=Math.max(0,Math.min(20,h)))),p=pa.get(p)||Fn;var M=c&&s;return function(n){var e=d;if(y&&n%1)return"";var i=0>n||0===n&&0>1/n?(n=-n,"-"):"-"===a?"":a;if(0>g){var l=ao.formatPrefix(n,h);n=l.scale(n),e=l.symbol+d}else n*=g;n=p(n,h);var x,b,_=n.lastIndexOf(".");if(0>_){var w=m?n.lastIndexOf("e"):-1;0>w?(x=n,b=""):(x=n.substring(0,w),b=n.substring(w))}else x=n.substring(0,_),b=t+n.substring(_+1);!c&&s&&(x=u(x,1/0));var S=v.length+x.length+b.length+(M?0:i.length),k=f>S?new Array(S=f-S+1).join(r):"";return M&&(x=u(k+x,k.length?f-b.length:1/0)),i+=v,n=x+b,("<"===o?i+n+k:">"===o?k+i+n:"^"===o?k.substring(0,S>>=1)+i+n+k.substring(S):i+(M?n:k+n))+e}}}function Fn(n){return n+""}function Hn(){this._=new Date(arguments.length>1?Date.UTC.apply(this,arguments):arguments[0])}function On(n,t,e){function r(t){var e=n(t),r=u(e,1);return r-t>t-e?e:r}function i(e){return t(e=n(new va(e-1)),1),e}function u(n,e){return t(n=new va(+n),e),n}function o(n,r,u){var o=i(n),a=[];if(u>1)for(;r>o;)e(o)%u||a.push(new Date(+o)),t(o,1);else for(;r>o;)a.push(new Date(+o)),t(o,1);return a}function a(n,t,e){try{va=Hn;var r=new Hn;return r._=n,o(r,t,e)}finally{va=Date}}n.floor=n,n.round=r,n.ceil=i,n.offset=u,n.range=o;var l=n.utc=In(n);return l.floor=l,l.round=In(r),l.ceil=In(i),l.offset=In(u),l.range=a,n}function In(n){return function(t,e){try{va=Hn;var r=new Hn;return r._=t,n(r,e)._}finally{va=Date}}}function Yn(n){function t(n){function t(t){for(var e,i,u,o=[],a=-1,l=0;++aa;){if(r>=c)return-1;if(i=t.charCodeAt(a++),37===i){if(o=t.charAt(a++),u=C[o in ya?t.charAt(a++):o],!u||(r=u(n,e,r))<0)return-1}else if(i!=e.charCodeAt(r++))return-1}return r}function r(n,t,e){_.lastIndex=0;var r=_.exec(t.slice(e));return r?(n.w=w.get(r[0].toLowerCase()),e+r[0].length):-1}function i(n,t,e){x.lastIndex=0;var r=x.exec(t.slice(e));return r?(n.w=b.get(r[0].toLowerCase()),e+r[0].length):-1}function u(n,t,e){N.lastIndex=0;var r=N.exec(t.slice(e));return r?(n.m=E.get(r[0].toLowerCase()),e+r[0].length):-1}function o(n,t,e){S.lastIndex=0;var r=S.exec(t.slice(e));return r?(n.m=k.get(r[0].toLowerCase()),e+r[0].length):-1}function a(n,t,r){return e(n,A.c.toString(),t,r)}function l(n,t,r){return e(n,A.x.toString(),t,r)}function c(n,t,r){return e(n,A.X.toString(),t,r)}function f(n,t,e){var r=M.get(t.slice(e,e+=2).toLowerCase());return null==r?-1:(n.p=r,e)}var s=n.dateTime,h=n.date,p=n.time,g=n.periods,v=n.days,d=n.shortDays,y=n.months,m=n.shortMonths;t.utc=function(n){function e(n){try{va=Hn;var t=new va;return t._=n,r(t)}finally{va=Date}}var r=t(n);return e.parse=function(n){try{va=Hn;var t=r.parse(n);return t&&t._}finally{va=Date}},e.toString=r.toString,e},t.multi=t.utc.multi=ct;var M=ao.map(),x=Vn(v),b=Xn(v),_=Vn(d),w=Xn(d),S=Vn(y),k=Xn(y),N=Vn(m),E=Xn(m);g.forEach(function(n,t){M.set(n.toLowerCase(),t)});var A={a:function(n){return d[n.getDay()]},A:function(n){return v[n.getDay()]},b:function(n){return m[n.getMonth()]},B:function(n){return y[n.getMonth()]},c:t(s),d:function(n,t){return Zn(n.getDate(),t,2)},e:function(n,t){return Zn(n.getDate(),t,2)},H:function(n,t){return Zn(n.getHours(),t,2)},I:function(n,t){return Zn(n.getHours()%12||12,t,2)},j:function(n,t){return Zn(1+ga.dayOfYear(n),t,3)},L:function(n,t){return Zn(n.getMilliseconds(),t,3)},m:function(n,t){return Zn(n.getMonth()+1,t,2)},M:function(n,t){return Zn(n.getMinutes(),t,2)},p:function(n){return g[+(n.getHours()>=12)]},S:function(n,t){return Zn(n.getSeconds(),t,2)},U:function(n,t){return Zn(ga.sundayOfYear(n),t,2)},w:function(n){return n.getDay()},W:function(n,t){return Zn(ga.mondayOfYear(n),t,2)},x:t(h),X:t(p),y:function(n,t){return Zn(n.getFullYear()%100,t,2)},Y:function(n,t){return Zn(n.getFullYear()%1e4,t,4)},Z:at,"%":function(){return"%"}},C={a:r,A:i,b:u,B:o,c:a,d:tt,e:tt,H:rt,I:rt,j:et,L:ot,m:nt,M:it,p:f,S:ut,U:Bn,w:$n,W:Wn,x:l,X:c,y:Gn,Y:Jn,Z:Kn,"%":lt};return t}function Zn(n,t,e){var r=0>n?"-":"",i=(r?-n:n)+"",u=i.length;return r+(e>u?new Array(e-u+1).join(t)+i:i)}function Vn(n){return new RegExp("^(?:"+n.map(ao.requote).join("|")+")","i")}function Xn(n){for(var t=new c,e=-1,r=n.length;++e68?1900:2e3)}function nt(n,t,e){ma.lastIndex=0;var r=ma.exec(t.slice(e,e+2));return r?(n.m=r[0]-1,e+r[0].length):-1}function tt(n,t,e){ma.lastIndex=0;var r=ma.exec(t.slice(e,e+2));return r?(n.d=+r[0],e+r[0].length):-1}function et(n,t,e){ma.lastIndex=0;var r=ma.exec(t.slice(e,e+3));return r?(n.j=+r[0],e+r[0].length):-1}function rt(n,t,e){ma.lastIndex=0;var r=ma.exec(t.slice(e,e+2));return r?(n.H=+r[0],e+r[0].length):-1}function it(n,t,e){ma.lastIndex=0;var r=ma.exec(t.slice(e,e+2));return r?(n.M=+r[0],e+r[0].length):-1}function ut(n,t,e){ma.lastIndex=0;var r=ma.exec(t.slice(e,e+2));return r?(n.S=+r[0],e+r[0].length):-1}function ot(n,t,e){ma.lastIndex=0;var r=ma.exec(t.slice(e,e+3));return r?(n.L=+r[0],e+r[0].length):-1}function at(n){var t=n.getTimezoneOffset(),e=t>0?"-":"+",r=xo(t)/60|0,i=xo(t)%60;return e+Zn(r,"0",2)+Zn(i,"0",2)}function lt(n,t,e){Ma.lastIndex=0;var r=Ma.exec(t.slice(e,e+1));return r?e+r[0].length:-1}function ct(n){for(var t=n.length,e=-1;++e=0?1:-1,a=o*e,l=Math.cos(t),c=Math.sin(t),f=u*c,s=i*l+f*Math.cos(a),h=f*o*Math.sin(a);ka.add(Math.atan2(h,s)),r=n,i=l,u=c}var t,e,r,i,u;Na.point=function(o,a){Na.point=n,r=(t=o)*Yo,i=Math.cos(a=(e=a)*Yo/2+Fo/4),u=Math.sin(a)},Na.lineEnd=function(){n(t,e)}}function dt(n){var t=n[0],e=n[1],r=Math.cos(e);return[r*Math.cos(t),r*Math.sin(t),Math.sin(e)]}function yt(n,t){return n[0]*t[0]+n[1]*t[1]+n[2]*t[2]}function mt(n,t){return[n[1]*t[2]-n[2]*t[1],n[2]*t[0]-n[0]*t[2],n[0]*t[1]-n[1]*t[0]]}function Mt(n,t){n[0]+=t[0],n[1]+=t[1],n[2]+=t[2]}function xt(n,t){return[n[0]*t,n[1]*t,n[2]*t]}function bt(n){var t=Math.sqrt(n[0]*n[0]+n[1]*n[1]+n[2]*n[2]);n[0]/=t,n[1]/=t,n[2]/=t}function _t(n){return[Math.atan2(n[1],n[0]),tn(n[2])]}function wt(n,t){return xo(n[0]-t[0])a;++a)i.point((e=n[a])[0],e[1]);return void i.lineEnd()}var l=new Tt(e,n,null,!0),c=new Tt(e,null,l,!1);l.o=c,u.push(l),o.push(c),l=new Tt(r,n,null,!1),c=new Tt(r,null,l,!0),l.o=c,u.push(l),o.push(c)}}),o.sort(t),qt(u),qt(o),u.length){for(var a=0,l=e,c=o.length;c>a;++a)o[a].e=l=!l;for(var f,s,h=u[0];;){for(var p=h,g=!0;p.v;)if((p=p.n)===h)return;f=p.z,i.lineStart();do{if(p.v=p.o.v=!0,p.e){if(g)for(var a=0,c=f.length;c>a;++a)i.point((s=f[a])[0],s[1]);else r(p.x,p.n.x,1,i);p=p.n}else{if(g){f=p.p.z;for(var a=f.length-1;a>=0;--a)i.point((s=f[a])[0],s[1])}else r(p.x,p.p.x,-1,i);p=p.p}p=p.o,f=p.z,g=!g}while(!p.v);i.lineEnd()}}}function qt(n){if(t=n.length){for(var t,e,r=0,i=n[0];++r0){for(b||(u.polygonStart(),b=!0),u.lineStart();++o1&&2&t&&e.push(e.pop().concat(e.shift())),p.push(e.filter(Dt))}var p,g,v,d=t(u),y=i.invert(r[0],r[1]),m={point:o,lineStart:l,lineEnd:c,polygonStart:function(){m.point=f,m.lineStart=s,m.lineEnd=h,p=[],g=[]},polygonEnd:function(){m.point=o,m.lineStart=l,m.lineEnd=c,p=ao.merge(p);var n=Ot(y,g);p.length?(b||(u.polygonStart(),b=!0),Lt(p,Ut,n,e,u)):n&&(b||(u.polygonStart(),b=!0),u.lineStart(),e(null,null,1,u),u.lineEnd()),b&&(u.polygonEnd(),b=!1),p=g=null},sphere:function(){u.polygonStart(),u.lineStart(),e(null,null,1,u),u.lineEnd(),u.polygonEnd()}},M=Pt(),x=t(M),b=!1;return m}}function Dt(n){return n.length>1}function Pt(){var n,t=[];return{lineStart:function(){t.push(n=[])},point:function(t,e){n.push([t,e])},lineEnd:b,buffer:function(){var e=t;return t=[],n=null,e},rejoin:function(){t.length>1&&t.push(t.pop().concat(t.shift()))}}}function Ut(n,t){return((n=n.x)[0]<0?n[1]-Io-Uo:Io-n[1])-((t=t.x)[0]<0?t[1]-Io-Uo:Io-t[1])}function jt(n){var t,e=NaN,r=NaN,i=NaN;return{lineStart:function(){n.lineStart(),t=1},point:function(u,o){var a=u>0?Fo:-Fo,l=xo(u-e);xo(l-Fo)0?Io:-Io),n.point(i,r),n.lineEnd(),n.lineStart(),n.point(a,r),n.point(u,r),t=0):i!==a&&l>=Fo&&(xo(e-i)Uo?Math.atan((Math.sin(t)*(u=Math.cos(r))*Math.sin(e)-Math.sin(r)*(i=Math.cos(t))*Math.sin(n))/(i*u*o)):(t+r)/2}function Ht(n,t,e,r){var i;if(null==n)i=e*Io,r.point(-Fo,i),r.point(0,i),r.point(Fo,i),r.point(Fo,0),r.point(Fo,-i),r.point(0,-i),r.point(-Fo,-i),r.point(-Fo,0),r.point(-Fo,i);else if(xo(n[0]-t[0])>Uo){var u=n[0]a;++a){var c=t[a],f=c.length;if(f)for(var s=c[0],h=s[0],p=s[1]/2+Fo/4,g=Math.sin(p),v=Math.cos(p),d=1;;){d===f&&(d=0),n=c[d];var y=n[0],m=n[1]/2+Fo/4,M=Math.sin(m),x=Math.cos(m),b=y-h,_=b>=0?1:-1,w=_*b,S=w>Fo,k=g*M;if(ka.add(Math.atan2(k*_*Math.sin(w),v*x+k*Math.cos(w))),u+=S?b+_*Ho:b,S^h>=e^y>=e){var N=mt(dt(s),dt(n));bt(N);var E=mt(i,N);bt(E);var A=(S^b>=0?-1:1)*tn(E[2]);(r>A||r===A&&(N[0]||N[1]))&&(o+=S^b>=0?1:-1)}if(!d++)break;h=y,g=M,v=x,s=n}}return(-Uo>u||Uo>u&&-Uo>ka)^1&o}function It(n){function t(n,t){return Math.cos(n)*Math.cos(t)>u}function e(n){var e,u,l,c,f;return{lineStart:function(){c=l=!1,f=1},point:function(s,h){var p,g=[s,h],v=t(s,h),d=o?v?0:i(s,h):v?i(s+(0>s?Fo:-Fo),h):0;if(!e&&(c=l=v)&&n.lineStart(),v!==l&&(p=r(e,g),(wt(e,p)||wt(g,p))&&(g[0]+=Uo,g[1]+=Uo,v=t(g[0],g[1]))),v!==l)f=0,v?(n.lineStart(),p=r(g,e),n.point(p[0],p[1])):(p=r(e,g),n.point(p[0],p[1]),n.lineEnd()),e=p;else if(a&&e&&o^v){var y;d&u||!(y=r(g,e,!0))||(f=0,o?(n.lineStart(),n.point(y[0][0],y[0][1]),n.point(y[1][0],y[1][1]),n.lineEnd()):(n.point(y[1][0],y[1][1]),n.lineEnd(),n.lineStart(),n.point(y[0][0],y[0][1])))}!v||e&&wt(e,g)||n.point(g[0],g[1]),e=g,l=v,u=d},lineEnd:function(){l&&n.lineEnd(),e=null},clean:function(){return f|(c&&l)<<1}}}function r(n,t,e){var r=dt(n),i=dt(t),o=[1,0,0],a=mt(r,i),l=yt(a,a),c=a[0],f=l-c*c;if(!f)return!e&&n;var s=u*l/f,h=-u*c/f,p=mt(o,a),g=xt(o,s),v=xt(a,h);Mt(g,v);var d=p,y=yt(g,d),m=yt(d,d),M=y*y-m*(yt(g,g)-1);if(!(0>M)){var x=Math.sqrt(M),b=xt(d,(-y-x)/m);if(Mt(b,g),b=_t(b),!e)return b;var _,w=n[0],S=t[0],k=n[1],N=t[1];w>S&&(_=w,w=S,S=_);var E=S-w,A=xo(E-Fo)E;if(!A&&k>N&&(_=k,k=N,N=_),C?A?k+N>0^b[1]<(xo(b[0]-w)Fo^(w<=b[0]&&b[0]<=S)){var z=xt(d,(-y+x)/m);return Mt(z,g),[b,_t(z)]}}}function i(t,e){var r=o?n:Fo-n,i=0;return-r>t?i|=1:t>r&&(i|=2),-r>e?i|=4:e>r&&(i|=8),i}var u=Math.cos(n),o=u>0,a=xo(u)>Uo,l=ve(n,6*Yo);return Rt(t,e,l,o?[0,-n]:[-Fo,n-Fo])}function Yt(n,t,e,r){return function(i){var u,o=i.a,a=i.b,l=o.x,c=o.y,f=a.x,s=a.y,h=0,p=1,g=f-l,v=s-c;if(u=n-l,g||!(u>0)){if(u/=g,0>g){if(h>u)return;p>u&&(p=u)}else if(g>0){if(u>p)return;u>h&&(h=u)}if(u=e-l,g||!(0>u)){if(u/=g,0>g){if(u>p)return;u>h&&(h=u)}else if(g>0){if(h>u)return;p>u&&(p=u)}if(u=t-c,v||!(u>0)){if(u/=v,0>v){if(h>u)return;p>u&&(p=u)}else if(v>0){if(u>p)return;u>h&&(h=u)}if(u=r-c,v||!(0>u)){if(u/=v,0>v){if(u>p)return;u>h&&(h=u)}else if(v>0){if(h>u)return;p>u&&(p=u)}return h>0&&(i.a={x:l+h*g,y:c+h*v}),1>p&&(i.b={x:l+p*g,y:c+p*v}),i}}}}}}function Zt(n,t,e,r){function i(r,i){return xo(r[0]-n)0?0:3:xo(r[0]-e)0?2:1:xo(r[1]-t)0?1:0:i>0?3:2}function u(n,t){return o(n.x,t.x)}function o(n,t){var e=i(n,1),r=i(t,1);return e!==r?e-r:0===e?t[1]-n[1]:1===e?n[0]-t[0]:2===e?n[1]-t[1]:t[0]-n[0]}return function(a){function l(n){for(var t=0,e=d.length,r=n[1],i=0;e>i;++i)for(var u,o=1,a=d[i],l=a.length,c=a[0];l>o;++o)u=a[o],c[1]<=r?u[1]>r&&Q(c,u,n)>0&&++t:u[1]<=r&&Q(c,u,n)<0&&--t,c=u;return 0!==t}function c(u,a,l,c){var f=0,s=0;if(null==u||(f=i(u,l))!==(s=i(a,l))||o(u,a)<0^l>0){do c.point(0===f||3===f?n:e,f>1?r:t);while((f=(f+l+4)%4)!==s)}else c.point(a[0],a[1])}function f(i,u){return i>=n&&e>=i&&u>=t&&r>=u}function s(n,t){f(n,t)&&a.point(n,t)}function h(){C.point=g,d&&d.push(y=[]),S=!0,w=!1,b=_=NaN}function p(){v&&(g(m,M),x&&w&&E.rejoin(),v.push(E.buffer())),C.point=s,w&&a.lineEnd()}function g(n,t){n=Math.max(-Ha,Math.min(Ha,n)),t=Math.max(-Ha,Math.min(Ha,t));var e=f(n,t);if(d&&y.push([n,t]),S)m=n,M=t,x=e,S=!1,e&&(a.lineStart(),a.point(n,t));else if(e&&w)a.point(n,t);else{var r={a:{x:b,y:_},b:{x:n,y:t}};A(r)?(w||(a.lineStart(),a.point(r.a.x,r.a.y)),a.point(r.b.x,r.b.y),e||a.lineEnd(),k=!1):e&&(a.lineStart(),a.point(n,t),k=!1)}b=n,_=t,w=e}var v,d,y,m,M,x,b,_,w,S,k,N=a,E=Pt(),A=Yt(n,t,e,r),C={point:s,lineStart:h,lineEnd:p,polygonStart:function(){a=E,v=[],d=[],k=!0},polygonEnd:function(){a=N,v=ao.merge(v);var t=l([n,r]),e=k&&t,i=v.length;(e||i)&&(a.polygonStart(),e&&(a.lineStart(),c(null,null,1,a),a.lineEnd()),i&&Lt(v,u,t,c,a),a.polygonEnd()),v=d=y=null}};return C}}function Vt(n){var t=0,e=Fo/3,r=ae(n),i=r(t,e);return i.parallels=function(n){return arguments.length?r(t=n[0]*Fo/180,e=n[1]*Fo/180):[t/Fo*180,e/Fo*180]},i}function Xt(n,t){function e(n,t){var e=Math.sqrt(u-2*i*Math.sin(t))/i;return[e*Math.sin(n*=i),o-e*Math.cos(n)]}var r=Math.sin(n),i=(r+Math.sin(t))/2,u=1+r*(2*i-r),o=Math.sqrt(u)/i;return e.invert=function(n,t){var e=o-t;return[Math.atan2(n,e)/i,tn((u-(n*n+e*e)*i*i)/(2*i))]},e}function $t(){function n(n,t){Ia+=i*n-r*t,r=n,i=t}var t,e,r,i;$a.point=function(u,o){$a.point=n,t=r=u,e=i=o},$a.lineEnd=function(){n(t,e)}}function Bt(n,t){Ya>n&&(Ya=n),n>Va&&(Va=n),Za>t&&(Za=t),t>Xa&&(Xa=t)}function Wt(){function n(n,t){o.push("M",n,",",t,u)}function t(n,t){o.push("M",n,",",t),a.point=e}function e(n,t){o.push("L",n,",",t)}function r(){a.point=n}function i(){o.push("Z")}var u=Jt(4.5),o=[],a={point:n,lineStart:function(){a.point=t},lineEnd:r,polygonStart:function(){a.lineEnd=i},polygonEnd:function(){a.lineEnd=r,a.point=n},pointRadius:function(n){return u=Jt(n),a},result:function(){if(o.length){var n=o.join("");return o=[],n}}};return a}function Jt(n){return"m0,"+n+"a"+n+","+n+" 0 1,1 0,"+-2*n+"a"+n+","+n+" 0 1,1 0,"+2*n+"z"}function Gt(n,t){Ca+=n,za+=t,++La}function Kt(){function n(n,r){var i=n-t,u=r-e,o=Math.sqrt(i*i+u*u);qa+=o*(t+n)/2,Ta+=o*(e+r)/2,Ra+=o,Gt(t=n,e=r)}var t,e;Wa.point=function(r,i){Wa.point=n,Gt(t=r,e=i)}}function Qt(){Wa.point=Gt}function ne(){function n(n,t){var e=n-r,u=t-i,o=Math.sqrt(e*e+u*u);qa+=o*(r+n)/2,Ta+=o*(i+t)/2,Ra+=o,o=i*n-r*t,Da+=o*(r+n),Pa+=o*(i+t),Ua+=3*o,Gt(r=n,i=t)}var t,e,r,i;Wa.point=function(u,o){Wa.point=n,Gt(t=r=u,e=i=o)},Wa.lineEnd=function(){n(t,e)}}function te(n){function t(t,e){n.moveTo(t+o,e),n.arc(t,e,o,0,Ho)}function e(t,e){n.moveTo(t,e),a.point=r}function r(t,e){n.lineTo(t,e)}function i(){a.point=t}function u(){n.closePath()}var o=4.5,a={point:t,lineStart:function(){a.point=e},lineEnd:i,polygonStart:function(){a.lineEnd=u},polygonEnd:function(){a.lineEnd=i,a.point=t},pointRadius:function(n){return o=n,a},result:b};return a}function ee(n){function t(n){return(a?r:e)(n)}function e(t){return ue(t,function(e,r){e=n(e,r),t.point(e[0],e[1])})}function r(t){function e(e,r){e=n(e,r),t.point(e[0],e[1])}function r(){M=NaN,S.point=u,t.lineStart()}function u(e,r){var u=dt([e,r]),o=n(e,r);i(M,x,m,b,_,w,M=o[0],x=o[1],m=e,b=u[0],_=u[1],w=u[2],a,t),t.point(M,x)}function o(){S.point=e,t.lineEnd()}function l(){ -r(),S.point=c,S.lineEnd=f}function c(n,t){u(s=n,h=t),p=M,g=x,v=b,d=_,y=w,S.point=u}function f(){i(M,x,m,b,_,w,p,g,s,v,d,y,a,t),S.lineEnd=o,o()}var s,h,p,g,v,d,y,m,M,x,b,_,w,S={point:e,lineStart:r,lineEnd:o,polygonStart:function(){t.polygonStart(),S.lineStart=l},polygonEnd:function(){t.polygonEnd(),S.lineStart=r}};return S}function i(t,e,r,a,l,c,f,s,h,p,g,v,d,y){var m=f-t,M=s-e,x=m*m+M*M;if(x>4*u&&d--){var b=a+p,_=l+g,w=c+v,S=Math.sqrt(b*b+_*_+w*w),k=Math.asin(w/=S),N=xo(xo(w)-1)u||xo((m*z+M*L)/x-.5)>.3||o>a*p+l*g+c*v)&&(i(t,e,r,a,l,c,A,C,N,b/=S,_/=S,w,d,y),y.point(A,C),i(A,C,N,b,_,w,f,s,h,p,g,v,d,y))}}var u=.5,o=Math.cos(30*Yo),a=16;return t.precision=function(n){return arguments.length?(a=(u=n*n)>0&&16,t):Math.sqrt(u)},t}function re(n){var t=ee(function(t,e){return n([t*Zo,e*Zo])});return function(n){return le(t(n))}}function ie(n){this.stream=n}function ue(n,t){return{point:t,sphere:function(){n.sphere()},lineStart:function(){n.lineStart()},lineEnd:function(){n.lineEnd()},polygonStart:function(){n.polygonStart()},polygonEnd:function(){n.polygonEnd()}}}function oe(n){return ae(function(){return n})()}function ae(n){function t(n){return n=a(n[0]*Yo,n[1]*Yo),[n[0]*h+l,c-n[1]*h]}function e(n){return n=a.invert((n[0]-l)/h,(c-n[1])/h),n&&[n[0]*Zo,n[1]*Zo]}function r(){a=Ct(o=se(y,M,x),u);var n=u(v,d);return l=p-n[0]*h,c=g+n[1]*h,i()}function i(){return f&&(f.valid=!1,f=null),t}var u,o,a,l,c,f,s=ee(function(n,t){return n=u(n,t),[n[0]*h+l,c-n[1]*h]}),h=150,p=480,g=250,v=0,d=0,y=0,M=0,x=0,b=Fa,_=m,w=null,S=null;return t.stream=function(n){return f&&(f.valid=!1),f=le(b(o,s(_(n)))),f.valid=!0,f},t.clipAngle=function(n){return arguments.length?(b=null==n?(w=n,Fa):It((w=+n)*Yo),i()):w},t.clipExtent=function(n){return arguments.length?(S=n,_=n?Zt(n[0][0],n[0][1],n[1][0],n[1][1]):m,i()):S},t.scale=function(n){return arguments.length?(h=+n,r()):h},t.translate=function(n){return arguments.length?(p=+n[0],g=+n[1],r()):[p,g]},t.center=function(n){return arguments.length?(v=n[0]%360*Yo,d=n[1]%360*Yo,r()):[v*Zo,d*Zo]},t.rotate=function(n){return arguments.length?(y=n[0]%360*Yo,M=n[1]%360*Yo,x=n.length>2?n[2]%360*Yo:0,r()):[y*Zo,M*Zo,x*Zo]},ao.rebind(t,s,"precision"),function(){return u=n.apply(this,arguments),t.invert=u.invert&&e,r()}}function le(n){return ue(n,function(t,e){n.point(t*Yo,e*Yo)})}function ce(n,t){return[n,t]}function fe(n,t){return[n>Fo?n-Ho:-Fo>n?n+Ho:n,t]}function se(n,t,e){return n?t||e?Ct(pe(n),ge(t,e)):pe(n):t||e?ge(t,e):fe}function he(n){return function(t,e){return t+=n,[t>Fo?t-Ho:-Fo>t?t+Ho:t,e]}}function pe(n){var t=he(n);return t.invert=he(-n),t}function ge(n,t){function e(n,t){var e=Math.cos(t),a=Math.cos(n)*e,l=Math.sin(n)*e,c=Math.sin(t),f=c*r+a*i;return[Math.atan2(l*u-f*o,a*r-c*i),tn(f*u+l*o)]}var r=Math.cos(n),i=Math.sin(n),u=Math.cos(t),o=Math.sin(t);return e.invert=function(n,t){var e=Math.cos(t),a=Math.cos(n)*e,l=Math.sin(n)*e,c=Math.sin(t),f=c*u-l*o;return[Math.atan2(l*u+c*o,a*r+f*i),tn(f*r-a*i)]},e}function ve(n,t){var e=Math.cos(n),r=Math.sin(n);return function(i,u,o,a){var l=o*t;null!=i?(i=de(e,i),u=de(e,u),(o>0?u>i:i>u)&&(i+=o*Ho)):(i=n+o*Ho,u=n-.5*l);for(var c,f=i;o>0?f>u:u>f;f-=l)a.point((c=_t([e,-r*Math.cos(f),-r*Math.sin(f)]))[0],c[1])}}function de(n,t){var e=dt(t);e[0]-=n,bt(e);var r=nn(-e[1]);return((-e[2]<0?-r:r)+2*Math.PI-Uo)%(2*Math.PI)}function ye(n,t,e){var r=ao.range(n,t-Uo,e).concat(t);return function(n){return r.map(function(t){return[n,t]})}}function me(n,t,e){var r=ao.range(n,t-Uo,e).concat(t);return function(n){return r.map(function(t){return[t,n]})}}function Me(n){return n.source}function xe(n){return n.target}function be(n,t,e,r){var i=Math.cos(t),u=Math.sin(t),o=Math.cos(r),a=Math.sin(r),l=i*Math.cos(n),c=i*Math.sin(n),f=o*Math.cos(e),s=o*Math.sin(e),h=2*Math.asin(Math.sqrt(on(r-t)+i*o*on(e-n))),p=1/Math.sin(h),g=h?function(n){var t=Math.sin(n*=h)*p,e=Math.sin(h-n)*p,r=e*l+t*f,i=e*c+t*s,o=e*u+t*a;return[Math.atan2(i,r)*Zo,Math.atan2(o,Math.sqrt(r*r+i*i))*Zo]}:function(){return[n*Zo,t*Zo]};return g.distance=h,g}function _e(){function n(n,i){var u=Math.sin(i*=Yo),o=Math.cos(i),a=xo((n*=Yo)-t),l=Math.cos(a);Ja+=Math.atan2(Math.sqrt((a=o*Math.sin(a))*a+(a=r*u-e*o*l)*a),e*u+r*o*l),t=n,e=u,r=o}var t,e,r;Ga.point=function(i,u){t=i*Yo,e=Math.sin(u*=Yo),r=Math.cos(u),Ga.point=n},Ga.lineEnd=function(){Ga.point=Ga.lineEnd=b}}function we(n,t){function e(t,e){var r=Math.cos(t),i=Math.cos(e),u=n(r*i);return[u*i*Math.sin(t),u*Math.sin(e)]}return e.invert=function(n,e){var r=Math.sqrt(n*n+e*e),i=t(r),u=Math.sin(i),o=Math.cos(i);return[Math.atan2(n*u,r*o),Math.asin(r&&e*u/r)]},e}function Se(n,t){function e(n,t){o>0?-Io+Uo>t&&(t=-Io+Uo):t>Io-Uo&&(t=Io-Uo);var e=o/Math.pow(i(t),u);return[e*Math.sin(u*n),o-e*Math.cos(u*n)]}var r=Math.cos(n),i=function(n){return Math.tan(Fo/4+n/2)},u=n===t?Math.sin(n):Math.log(r/Math.cos(t))/Math.log(i(t)/i(n)),o=r*Math.pow(i(n),u)/u;return u?(e.invert=function(n,t){var e=o-t,r=K(u)*Math.sqrt(n*n+e*e);return[Math.atan2(n,e)/u,2*Math.atan(Math.pow(o/r,1/u))-Io]},e):Ne}function ke(n,t){function e(n,t){var e=u-t;return[e*Math.sin(i*n),u-e*Math.cos(i*n)]}var r=Math.cos(n),i=n===t?Math.sin(n):(r-Math.cos(t))/(t-n),u=r/i+n;return xo(i)i;i++){for(;r>1&&Q(n[e[r-2]],n[e[r-1]],n[i])<=0;)--r;e[r++]=i}return e.slice(0,r)}function qe(n,t){return n[0]-t[0]||n[1]-t[1]}function Te(n,t,e){return(e[0]-t[0])*(n[1]-t[1])<(e[1]-t[1])*(n[0]-t[0])}function Re(n,t,e,r){var i=n[0],u=e[0],o=t[0]-i,a=r[0]-u,l=n[1],c=e[1],f=t[1]-l,s=r[1]-c,h=(a*(l-c)-s*(i-u))/(s*o-a*f);return[i+h*o,l+h*f]}function De(n){var t=n[0],e=n[n.length-1];return!(t[0]-e[0]||t[1]-e[1])}function Pe(){rr(this),this.edge=this.site=this.circle=null}function Ue(n){var t=cl.pop()||new Pe;return t.site=n,t}function je(n){Be(n),ol.remove(n),cl.push(n),rr(n)}function Fe(n){var t=n.circle,e=t.x,r=t.cy,i={x:e,y:r},u=n.P,o=n.N,a=[n];je(n);for(var l=u;l.circle&&xo(e-l.circle.x)f;++f)c=a[f],l=a[f-1],nr(c.edge,l.site,c.site,i);l=a[0],c=a[s-1],c.edge=Ke(l.site,c.site,null,i),$e(l),$e(c)}function He(n){for(var t,e,r,i,u=n.x,o=n.y,a=ol._;a;)if(r=Oe(a,o)-u,r>Uo)a=a.L;else{if(i=u-Ie(a,o),!(i>Uo)){r>-Uo?(t=a.P,e=a):i>-Uo?(t=a,e=a.N):t=e=a;break}if(!a.R){t=a;break}a=a.R}var l=Ue(n);if(ol.insert(t,l),t||e){if(t===e)return Be(t),e=Ue(t.site),ol.insert(l,e),l.edge=e.edge=Ke(t.site,l.site),$e(t),void $e(e);if(!e)return void(l.edge=Ke(t.site,l.site));Be(t),Be(e);var c=t.site,f=c.x,s=c.y,h=n.x-f,p=n.y-s,g=e.site,v=g.x-f,d=g.y-s,y=2*(h*d-p*v),m=h*h+p*p,M=v*v+d*d,x={x:(d*m-p*M)/y+f,y:(h*M-v*m)/y+s};nr(e.edge,c,g,x),l.edge=Ke(c,n,null,x),e.edge=Ke(n,g,null,x),$e(t),$e(e)}}function Oe(n,t){var e=n.site,r=e.x,i=e.y,u=i-t;if(!u)return r;var o=n.P;if(!o)return-(1/0);e=o.site;var a=e.x,l=e.y,c=l-t;if(!c)return a;var f=a-r,s=1/u-1/c,h=f/c;return s?(-h+Math.sqrt(h*h-2*s*(f*f/(-2*c)-l+c/2+i-u/2)))/s+r:(r+a)/2}function Ie(n,t){var e=n.N;if(e)return Oe(e,t);var r=n.site;return r.y===t?r.x:1/0}function Ye(n){this.site=n,this.edges=[]}function Ze(n){for(var t,e,r,i,u,o,a,l,c,f,s=n[0][0],h=n[1][0],p=n[0][1],g=n[1][1],v=ul,d=v.length;d--;)if(u=v[d],u&&u.prepare())for(a=u.edges,l=a.length,o=0;l>o;)f=a[o].end(),r=f.x,i=f.y,c=a[++o%l].start(),t=c.x,e=c.y,(xo(r-t)>Uo||xo(i-e)>Uo)&&(a.splice(o,0,new tr(Qe(u.site,f,xo(r-s)Uo?{x:s,y:xo(t-s)Uo?{x:xo(e-g)Uo?{x:h,y:xo(t-h)Uo?{x:xo(e-p)=-jo)){var p=l*l+c*c,g=f*f+s*s,v=(s*p-c*g)/h,d=(l*g-f*p)/h,s=d+a,y=fl.pop()||new Xe;y.arc=n,y.site=i,y.x=v+o,y.y=s+Math.sqrt(v*v+d*d),y.cy=s,n.circle=y;for(var m=null,M=ll._;M;)if(y.yd||d>=a)return;if(h>g){if(u){if(u.y>=c)return}else u={x:d,y:l};e={x:d,y:c}}else{if(u){if(u.yr||r>1)if(h>g){if(u){if(u.y>=c)return}else u={x:(l-i)/r,y:l};e={x:(c-i)/r,y:c}}else{if(u){if(u.yp){if(u){if(u.x>=a)return}else u={x:o,y:r*o+i};e={x:a,y:r*a+i}}else{if(u){if(u.xu||s>o||r>h||i>p)){if(g=n.point){var g,v=t-n.x,d=e-n.y,y=v*v+d*d;if(l>y){var m=Math.sqrt(l=y);r=t-m,i=e-m,u=t+m,o=e+m,a=g}}for(var M=n.nodes,x=.5*(f+h),b=.5*(s+p),_=t>=x,w=e>=b,S=w<<1|_,k=S+4;k>S;++S)if(n=M[3&S])switch(3&S){case 0:c(n,f,s,x,b);break;case 1:c(n,x,s,h,b);break;case 2:c(n,f,b,x,p);break;case 3:c(n,x,b,h,p)}}}(n,r,i,u,o),a}function vr(n,t){n=ao.rgb(n),t=ao.rgb(t);var e=n.r,r=n.g,i=n.b,u=t.r-e,o=t.g-r,a=t.b-i;return function(n){return"#"+bn(Math.round(e+u*n))+bn(Math.round(r+o*n))+bn(Math.round(i+a*n))}}function dr(n,t){var e,r={},i={};for(e in n)e in t?r[e]=Mr(n[e],t[e]):i[e]=n[e];for(e in t)e in n||(i[e]=t[e]);return function(n){for(e in r)i[e]=r[e](n);return i}}function yr(n,t){return n=+n,t=+t,function(e){return n*(1-e)+t*e}}function mr(n,t){var e,r,i,u=hl.lastIndex=pl.lastIndex=0,o=-1,a=[],l=[];for(n+="",t+="";(e=hl.exec(n))&&(r=pl.exec(t));)(i=r.index)>u&&(i=t.slice(u,i),a[o]?a[o]+=i:a[++o]=i),(e=e[0])===(r=r[0])?a[o]?a[o]+=r:a[++o]=r:(a[++o]=null,l.push({i:o,x:yr(e,r)})),u=pl.lastIndex;return ur;++r)a[(e=l[r]).i]=e.x(n);return a.join("")})}function Mr(n,t){for(var e,r=ao.interpolators.length;--r>=0&&!(e=ao.interpolators[r](n,t)););return e}function xr(n,t){var e,r=[],i=[],u=n.length,o=t.length,a=Math.min(n.length,t.length);for(e=0;a>e;++e)r.push(Mr(n[e],t[e]));for(;u>e;++e)i[e]=n[e];for(;o>e;++e)i[e]=t[e];return function(n){for(e=0;a>e;++e)i[e]=r[e](n);return i}}function br(n){return function(t){return 0>=t?0:t>=1?1:n(t)}}function _r(n){return function(t){return 1-n(1-t)}}function wr(n){return function(t){return.5*(.5>t?n(2*t):2-n(2-2*t))}}function Sr(n){return n*n}function kr(n){return n*n*n}function Nr(n){if(0>=n)return 0;if(n>=1)return 1;var t=n*n,e=t*n;return 4*(.5>n?e:3*(n-t)+e-.75)}function Er(n){return function(t){return Math.pow(t,n)}}function Ar(n){return 1-Math.cos(n*Io)}function Cr(n){return Math.pow(2,10*(n-1))}function zr(n){return 1-Math.sqrt(1-n*n)}function Lr(n,t){var e;return arguments.length<2&&(t=.45),arguments.length?e=t/Ho*Math.asin(1/n):(n=1,e=t/4),function(r){return 1+n*Math.pow(2,-10*r)*Math.sin((r-e)*Ho/t)}}function qr(n){return n||(n=1.70158),function(t){return t*t*((n+1)*t-n)}}function Tr(n){return 1/2.75>n?7.5625*n*n:2/2.75>n?7.5625*(n-=1.5/2.75)*n+.75:2.5/2.75>n?7.5625*(n-=2.25/2.75)*n+.9375:7.5625*(n-=2.625/2.75)*n+.984375}function Rr(n,t){n=ao.hcl(n),t=ao.hcl(t);var e=n.h,r=n.c,i=n.l,u=t.h-e,o=t.c-r,a=t.l-i;return isNaN(o)&&(o=0,r=isNaN(r)?t.c:r),isNaN(u)?(u=0,e=isNaN(e)?t.h:e):u>180?u-=360:-180>u&&(u+=360),function(n){return sn(e+u*n,r+o*n,i+a*n)+""}}function Dr(n,t){n=ao.hsl(n),t=ao.hsl(t);var e=n.h,r=n.s,i=n.l,u=t.h-e,o=t.s-r,a=t.l-i;return isNaN(o)&&(o=0,r=isNaN(r)?t.s:r),isNaN(u)?(u=0,e=isNaN(e)?t.h:e):u>180?u-=360:-180>u&&(u+=360),function(n){return cn(e+u*n,r+o*n,i+a*n)+""}}function Pr(n,t){n=ao.lab(n),t=ao.lab(t);var e=n.l,r=n.a,i=n.b,u=t.l-e,o=t.a-r,a=t.b-i;return function(n){return pn(e+u*n,r+o*n,i+a*n)+""}}function Ur(n,t){return t-=n,function(e){return Math.round(n+t*e)}}function jr(n){var t=[n.a,n.b],e=[n.c,n.d],r=Hr(t),i=Fr(t,e),u=Hr(Or(e,t,-i))||0;t[0]*e[1]180?t+=360:t-n>180&&(n+=360),r.push({i:e.push(Ir(e)+"rotate(",null,")")-2,x:yr(n,t)})):t&&e.push(Ir(e)+"rotate("+t+")")}function Vr(n,t,e,r){n!==t?r.push({i:e.push(Ir(e)+"skewX(",null,")")-2,x:yr(n,t)}):t&&e.push(Ir(e)+"skewX("+t+")")}function Xr(n,t,e,r){if(n[0]!==t[0]||n[1]!==t[1]){var i=e.push(Ir(e)+"scale(",null,",",null,")");r.push({i:i-4,x:yr(n[0],t[0])},{i:i-2,x:yr(n[1],t[1])})}else 1===t[0]&&1===t[1]||e.push(Ir(e)+"scale("+t+")")}function $r(n,t){var e=[],r=[];return n=ao.transform(n),t=ao.transform(t),Yr(n.translate,t.translate,e,r),Zr(n.rotate,t.rotate,e,r),Vr(n.skew,t.skew,e,r),Xr(n.scale,t.scale,e,r),n=t=null,function(n){for(var t,i=-1,u=r.length;++i=0;)e.push(i[r])}function oi(n,t){for(var e=[n],r=[];null!=(n=e.pop());)if(r.push(n),(u=n.children)&&(i=u.length))for(var i,u,o=-1;++oe;++e)(t=n[e][1])>i&&(r=e,i=t);return r}function yi(n){return n.reduce(mi,0)}function mi(n,t){return n+t[1]}function Mi(n,t){return xi(n,Math.ceil(Math.log(t.length)/Math.LN2+1))}function xi(n,t){for(var e=-1,r=+n[0],i=(n[1]-r)/t,u=[];++e<=t;)u[e]=i*e+r;return u}function bi(n){return[ao.min(n),ao.max(n)]}function _i(n,t){return n.value-t.value}function wi(n,t){var e=n._pack_next;n._pack_next=t,t._pack_prev=n,t._pack_next=e,e._pack_prev=t}function Si(n,t){n._pack_next=t,t._pack_prev=n}function ki(n,t){var e=t.x-n.x,r=t.y-n.y,i=n.r+t.r;return.999*i*i>e*e+r*r}function Ni(n){function t(n){f=Math.min(n.x-n.r,f),s=Math.max(n.x+n.r,s),h=Math.min(n.y-n.r,h),p=Math.max(n.y+n.r,p)}if((e=n.children)&&(c=e.length)){var e,r,i,u,o,a,l,c,f=1/0,s=-(1/0),h=1/0,p=-(1/0);if(e.forEach(Ei),r=e[0],r.x=-r.r,r.y=0,t(r),c>1&&(i=e[1],i.x=i.r,i.y=0,t(i),c>2))for(u=e[2],zi(r,i,u),t(u),wi(r,u),r._pack_prev=u,wi(u,i),i=r._pack_next,o=3;c>o;o++){zi(r,i,u=e[o]);var g=0,v=1,d=1;for(a=i._pack_next;a!==i;a=a._pack_next,v++)if(ki(a,u)){g=1;break}if(1==g)for(l=r._pack_prev;l!==a._pack_prev&&!ki(l,u);l=l._pack_prev,d++);g?(d>v||v==d&&i.ro;o++)u=e[o],u.x-=y,u.y-=m,M=Math.max(M,u.r+Math.sqrt(u.x*u.x+u.y*u.y));n.r=M,e.forEach(Ai)}}function Ei(n){n._pack_next=n._pack_prev=n}function Ai(n){delete n._pack_next,delete n._pack_prev}function Ci(n,t,e,r){var i=n.children;if(n.x=t+=r*n.x,n.y=e+=r*n.y,n.r*=r,i)for(var u=-1,o=i.length;++u=0;)t=i[u],t.z+=e,t.m+=e,e+=t.s+(r+=t.c)}function Pi(n,t,e){return n.a.parent===t.parent?n.a:e}function Ui(n){return 1+ao.max(n,function(n){return n.y})}function ji(n){return n.reduce(function(n,t){return n+t.x},0)/n.length}function Fi(n){var t=n.children;return t&&t.length?Fi(t[0]):n}function Hi(n){var t,e=n.children;return e&&(t=e.length)?Hi(e[t-1]):n}function Oi(n){return{x:n.x,y:n.y,dx:n.dx,dy:n.dy}}function Ii(n,t){var e=n.x+t[3],r=n.y+t[0],i=n.dx-t[1]-t[3],u=n.dy-t[0]-t[2];return 0>i&&(e+=i/2,i=0),0>u&&(r+=u/2,u=0),{x:e,y:r,dx:i,dy:u}}function Yi(n){var t=n[0],e=n[n.length-1];return e>t?[t,e]:[e,t]}function Zi(n){return n.rangeExtent?n.rangeExtent():Yi(n.range())}function Vi(n,t,e,r){var i=e(n[0],n[1]),u=r(t[0],t[1]);return function(n){return u(i(n))}}function Xi(n,t){var e,r=0,i=n.length-1,u=n[r],o=n[i];return u>o&&(e=r,r=i,i=e,e=u,u=o,o=e),n[r]=t.floor(u),n[i]=t.ceil(o),n}function $i(n){return n?{floor:function(t){return Math.floor(t/n)*n},ceil:function(t){return Math.ceil(t/n)*n}}:Sl}function Bi(n,t,e,r){var i=[],u=[],o=0,a=Math.min(n.length,t.length)-1;for(n[a]2?Bi:Vi,l=r?Wr:Br;return o=i(n,t,l,e),a=i(t,n,l,Mr),u}function u(n){return o(n)}var o,a;return u.invert=function(n){return a(n)},u.domain=function(t){return arguments.length?(n=t.map(Number),i()):n},u.range=function(n){return arguments.length?(t=n,i()):t},u.rangeRound=function(n){return u.range(n).interpolate(Ur)},u.clamp=function(n){return arguments.length?(r=n,i()):r},u.interpolate=function(n){return arguments.length?(e=n,i()):e},u.ticks=function(t){return Qi(n,t)},u.tickFormat=function(t,e){return nu(n,t,e)},u.nice=function(t){return Gi(n,t),i()},u.copy=function(){return Wi(n,t,e,r)},i()}function Ji(n,t){return ao.rebind(n,t,"range","rangeRound","interpolate","clamp")}function Gi(n,t){return Xi(n,$i(Ki(n,t)[2])),Xi(n,$i(Ki(n,t)[2])),n}function Ki(n,t){null==t&&(t=10);var e=Yi(n),r=e[1]-e[0],i=Math.pow(10,Math.floor(Math.log(r/t)/Math.LN10)),u=t/r*i;return.15>=u?i*=10:.35>=u?i*=5:.75>=u&&(i*=2),e[0]=Math.ceil(e[0]/i)*i,e[1]=Math.floor(e[1]/i)*i+.5*i,e[2]=i,e}function Qi(n,t){return ao.range.apply(ao,Ki(n,t))}function nu(n,t,e){var r=Ki(n,t);if(e){var i=ha.exec(e);if(i.shift(),"s"===i[8]){var u=ao.formatPrefix(Math.max(xo(r[0]),xo(r[1])));return i[7]||(i[7]="."+tu(u.scale(r[2]))),i[8]="f",e=ao.format(i.join("")),function(n){return e(u.scale(n))+u.symbol}}i[7]||(i[7]="."+eu(i[8],r)),e=i.join("")}else e=",."+tu(r[2])+"f";return ao.format(e)}function tu(n){return-Math.floor(Math.log(n)/Math.LN10+.01)}function eu(n,t){var e=tu(t[2]);return n in kl?Math.abs(e-tu(Math.max(xo(t[0]),xo(t[1]))))+ +("e"!==n):e-2*("%"===n)}function ru(n,t,e,r){function i(n){return(e?Math.log(0>n?0:n):-Math.log(n>0?0:-n))/Math.log(t)}function u(n){return e?Math.pow(t,n):-Math.pow(t,-n)}function o(t){return n(i(t))}return o.invert=function(t){return u(n.invert(t))},o.domain=function(t){return arguments.length?(e=t[0]>=0,n.domain((r=t.map(Number)).map(i)),o):r},o.base=function(e){return arguments.length?(t=+e,n.domain(r.map(i)),o):t},o.nice=function(){var t=Xi(r.map(i),e?Math:El);return n.domain(t),r=t.map(u),o},o.ticks=function(){var n=Yi(r),o=[],a=n[0],l=n[1],c=Math.floor(i(a)),f=Math.ceil(i(l)),s=t%1?2:t;if(isFinite(f-c)){if(e){for(;f>c;c++)for(var h=1;s>h;h++)o.push(u(c)*h);o.push(u(c))}else for(o.push(u(c));c++0;h--)o.push(u(c)*h);for(c=0;o[c]l;f--);o=o.slice(c,f)}return o},o.tickFormat=function(n,e){if(!arguments.length)return Nl;arguments.length<2?e=Nl:"function"!=typeof e&&(e=ao.format(e));var r=Math.max(1,t*n/o.ticks().length);return function(n){var o=n/u(Math.round(i(n)));return t-.5>o*t&&(o*=t),r>=o?e(n):""}},o.copy=function(){return ru(n.copy(),t,e,r)},Ji(o,n)}function iu(n,t,e){function r(t){return n(i(t))}var i=uu(t),u=uu(1/t);return r.invert=function(t){return u(n.invert(t))},r.domain=function(t){return arguments.length?(n.domain((e=t.map(Number)).map(i)),r):e},r.ticks=function(n){return Qi(e,n)},r.tickFormat=function(n,t){return nu(e,n,t)},r.nice=function(n){return r.domain(Gi(e,n))},r.exponent=function(o){return arguments.length?(i=uu(t=o),u=uu(1/t),n.domain(e.map(i)),r):t},r.copy=function(){return iu(n.copy(),t,e)},Ji(r,n)}function uu(n){return function(t){return 0>t?-Math.pow(-t,n):Math.pow(t,n)}}function ou(n,t){function e(e){return u[((i.get(e)||("range"===t.t?i.set(e,n.push(e)):NaN))-1)%u.length]}function r(t,e){return ao.range(n.length).map(function(n){return t+e*n})}var i,u,o;return e.domain=function(r){if(!arguments.length)return n;n=[],i=new c;for(var u,o=-1,a=r.length;++oe?[NaN,NaN]:[e>0?a[e-1]:n[0],et?NaN:t/u+n,[t,t+1/u]},r.copy=function(){return lu(n,t,e)},i()}function cu(n,t){function e(e){return e>=e?t[ao.bisect(n,e)]:void 0}return e.domain=function(t){return arguments.length?(n=t,e):n},e.range=function(n){return arguments.length?(t=n,e):t},e.invertExtent=function(e){return e=t.indexOf(e),[n[e-1],n[e]]},e.copy=function(){return cu(n,t)},e}function fu(n){function t(n){return+n}return t.invert=t,t.domain=t.range=function(e){return arguments.length?(n=e.map(t),t):n},t.ticks=function(t){return Qi(n,t)},t.tickFormat=function(t,e){return nu(n,t,e)},t.copy=function(){return fu(n)},t}function su(){return 0}function hu(n){return n.innerRadius}function pu(n){return n.outerRadius}function gu(n){return n.startAngle}function vu(n){return n.endAngle}function du(n){return n&&n.padAngle}function yu(n,t,e,r){return(n-e)*t-(t-r)*n>0?0:1}function mu(n,t,e,r,i){var u=n[0]-t[0],o=n[1]-t[1],a=(i?r:-r)/Math.sqrt(u*u+o*o),l=a*o,c=-a*u,f=n[0]+l,s=n[1]+c,h=t[0]+l,p=t[1]+c,g=(f+h)/2,v=(s+p)/2,d=h-f,y=p-s,m=d*d+y*y,M=e-r,x=f*p-h*s,b=(0>y?-1:1)*Math.sqrt(Math.max(0,M*M*m-x*x)),_=(x*y-d*b)/m,w=(-x*d-y*b)/m,S=(x*y+d*b)/m,k=(-x*d+y*b)/m,N=_-g,E=w-v,A=S-g,C=k-v;return N*N+E*E>A*A+C*C&&(_=S,w=k),[[_-l,w-c],[_*e/M,w*e/M]]}function Mu(n){function t(t){function o(){c.push("M",u(n(f),a))}for(var l,c=[],f=[],s=-1,h=t.length,p=En(e),g=En(r);++s1?n.join("L"):n+"Z"}function bu(n){return n.join("L")+"Z"}function _u(n){for(var t=0,e=n.length,r=n[0],i=[r[0],",",r[1]];++t1&&i.push("H",r[0]),i.join("")}function wu(n){for(var t=0,e=n.length,r=n[0],i=[r[0],",",r[1]];++t1){a=t[1],u=n[l],l++,r+="C"+(i[0]+o[0])+","+(i[1]+o[1])+","+(u[0]-a[0])+","+(u[1]-a[1])+","+u[0]+","+u[1];for(var c=2;c9&&(i=3*t/Math.sqrt(i),o[a]=i*e,o[a+1]=i*r));for(a=-1;++a<=l;)i=(n[Math.min(l,a+1)][0]-n[Math.max(0,a-1)][0])/(6*(1+o[a]*o[a])),u.push([i||0,o[a]*i||0]);return u}function Fu(n){return n.length<3?xu(n):n[0]+Au(n,ju(n))}function Hu(n){for(var t,e,r,i=-1,u=n.length;++i=t?o(n-t):void(f.c=o)}function o(e){var i=g.active,u=g[i];u&&(u.timer.c=null,u.timer.t=NaN,--g.count,delete g[i],u.event&&u.event.interrupt.call(n,n.__data__,u.index));for(var o in g)if(r>+o){var c=g[o];c.timer.c=null,c.timer.t=NaN,--g.count,delete g[o]}f.c=a,qn(function(){return f.c&&a(e||1)&&(f.c=null,f.t=NaN),1},0,l),g.active=r,v.event&&v.event.start.call(n,n.__data__,t),p=[],v.tween.forEach(function(e,r){(r=r.call(n,n.__data__,t))&&p.push(r)}),h=v.ease,s=v.duration}function a(i){for(var u=i/s,o=h(u),a=p.length;a>0;)p[--a].call(n,o);return u>=1?(v.event&&v.event.end.call(n,n.__data__,t),--g.count?delete g[r]:delete n[e],1):void 0}var l,f,s,h,p,g=n[e]||(n[e]={active:0,count:0}),v=g[r];v||(l=i.time,f=qn(u,0,l),v=g[r]={tween:new c,time:l,timer:f,delay:i.delay,duration:i.duration,ease:i.ease,index:t},i=null,++g.count)}function no(n,t,e){n.attr("transform",function(n){var r=t(n);return"translate("+(isFinite(r)?r:e(n))+",0)"})}function to(n,t,e){n.attr("transform",function(n){var r=t(n);return"translate(0,"+(isFinite(r)?r:e(n))+")"})}function eo(n){return n.toISOString()}function ro(n,t,e){function r(t){return n(t)}function i(n,e){var r=n[1]-n[0],i=r/e,u=ao.bisect(Kl,i);return u==Kl.length?[t.year,Ki(n.map(function(n){return n/31536e6}),e)[2]]:u?t[i/Kl[u-1]1?{floor:function(t){for(;e(t=n.floor(t));)t=io(t-1);return t},ceil:function(t){for(;e(t=n.ceil(t));)t=io(+t+1);return t}}:n))},r.ticks=function(n,t){var e=Yi(r.domain()),u=null==n?i(e,10):"number"==typeof n?i(e,n):!n.range&&[{range:n},t];return u&&(n=u[0],t=u[1]),n.range(e[0],io(+e[1]+1),1>t?1:t)},r.tickFormat=function(){return e},r.copy=function(){return ro(n.copy(),t,e)},Ji(r,n)}function io(n){return new Date(n)}function uo(n){return JSON.parse(n.responseText)}function oo(n){var t=fo.createRange();return t.selectNode(fo.body),t.createContextualFragment(n.responseText)}var ao={version:"3.5.17"},lo=[].slice,co=function(n){return lo.call(n)},fo=this.document;if(fo)try{co(fo.documentElement.childNodes)[0].nodeType}catch(so){co=function(n){for(var t=n.length,e=new Array(t);t--;)e[t]=n[t];return e}}if(Date.now||(Date.now=function(){return+new Date}),fo)try{fo.createElement("DIV").style.setProperty("opacity",0,"")}catch(ho){var po=this.Element.prototype,go=po.setAttribute,vo=po.setAttributeNS,yo=this.CSSStyleDeclaration.prototype,mo=yo.setProperty;po.setAttribute=function(n,t){go.call(this,n,t+"")},po.setAttributeNS=function(n,t,e){vo.call(this,n,t,e+"")},yo.setProperty=function(n,t,e){mo.call(this,n,t+"",e)}}ao.ascending=e,ao.descending=function(n,t){return n>t?-1:t>n?1:t>=n?0:NaN},ao.min=function(n,t){var e,r,i=-1,u=n.length;if(1===arguments.length){for(;++i=r){e=r;break}for(;++ir&&(e=r)}else{for(;++i=r){e=r;break}for(;++ir&&(e=r)}return e},ao.max=function(n,t){var e,r,i=-1,u=n.length;if(1===arguments.length){for(;++i=r){e=r;break}for(;++ie&&(e=r)}else{for(;++i=r){e=r;break}for(;++ie&&(e=r)}return e},ao.extent=function(n,t){var e,r,i,u=-1,o=n.length;if(1===arguments.length){for(;++u=r){e=i=r;break}for(;++ur&&(e=r),r>i&&(i=r))}else{for(;++u=r){e=i=r;break}for(;++ur&&(e=r),r>i&&(i=r))}return[e,i]},ao.sum=function(n,t){var e,r=0,u=n.length,o=-1;if(1===arguments.length)for(;++o1?l/(f-1):void 0},ao.deviation=function(){var n=ao.variance.apply(this,arguments);return n?Math.sqrt(n):n};var Mo=u(e);ao.bisectLeft=Mo.left,ao.bisect=ao.bisectRight=Mo.right,ao.bisector=function(n){return u(1===n.length?function(t,r){return e(n(t),r)}:n)},ao.shuffle=function(n,t,e){(u=arguments.length)<3&&(e=n.length,2>u&&(t=0));for(var r,i,u=e-t;u;)i=Math.random()*u--|0,r=n[u+t],n[u+t]=n[i+t],n[i+t]=r;return n},ao.permute=function(n,t){for(var e=t.length,r=new Array(e);e--;)r[e]=n[t[e]];return r},ao.pairs=function(n){for(var t,e=0,r=n.length-1,i=n[0],u=new Array(0>r?0:r);r>e;)u[e]=[t=i,i=n[++e]];return u},ao.transpose=function(n){if(!(i=n.length))return[];for(var t=-1,e=ao.min(n,o),r=new Array(e);++t=0;)for(r=n[i],t=r.length;--t>=0;)e[--o]=r[t];return e};var xo=Math.abs;ao.range=function(n,t,e){if(arguments.length<3&&(e=1,arguments.length<2&&(t=n,n=0)),(t-n)/e===1/0)throw new Error("infinite range");var r,i=[],u=a(xo(e)),o=-1;if(n*=u,t*=u,e*=u,0>e)for(;(r=n+e*++o)>t;)i.push(r/u);else for(;(r=n+e*++o)=u.length)return r?r.call(i,o):e?o.sort(e):o;for(var l,f,s,h,p=-1,g=o.length,v=u[a++],d=new c;++p=u.length)return n;var r=[],i=o[e++];return n.forEach(function(n,i){r.push({key:n,values:t(i,e)})}),i?r.sort(function(n,t){return i(n.key,t.key)}):r}var e,r,i={},u=[],o=[];return i.map=function(t,e){return n(e,t,0)},i.entries=function(e){return t(n(ao.map,e,0),0)},i.key=function(n){return u.push(n),i},i.sortKeys=function(n){return o[u.length-1]=n,i},i.sortValues=function(n){return e=n,i},i.rollup=function(n){return r=n,i},i},ao.set=function(n){var t=new y;if(n)for(var e=0,r=n.length;r>e;++e)t.add(n[e]);return t},l(y,{has:h,add:function(n){return this._[f(n+="")]=!0,n},remove:p,values:g,size:v,empty:d,forEach:function(n){for(var t in this._)n.call(this,s(t))}}),ao.behavior={},ao.rebind=function(n,t){for(var e,r=1,i=arguments.length;++r=0&&(r=n.slice(e+1),n=n.slice(0,e)),n)return arguments.length<2?this[n].on(r):this[n].on(r,t);if(2===arguments.length){if(null==t)for(n in this)this.hasOwnProperty(n)&&this[n].on(r,null);return this}},ao.event=null,ao.requote=function(n){return n.replace(So,"\\$&")};var So=/[\\\^\$\*\+\?\|\[\]\(\)\.\{\}]/g,ko={}.__proto__?function(n,t){n.__proto__=t}:function(n,t){for(var e in t)n[e]=t[e]},No=function(n,t){return t.querySelector(n)},Eo=function(n,t){return t.querySelectorAll(n)},Ao=function(n,t){var e=n.matches||n[x(n,"matchesSelector")];return(Ao=function(n,t){return e.call(n,t)})(n,t)};"function"==typeof Sizzle&&(No=function(n,t){return Sizzle(n,t)[0]||null},Eo=Sizzle,Ao=Sizzle.matchesSelector),ao.selection=function(){return ao.select(fo.documentElement)};var Co=ao.selection.prototype=[];Co.select=function(n){var t,e,r,i,u=[];n=A(n);for(var o=-1,a=this.length;++o=0&&"xmlns"!==(e=n.slice(0,t))&&(n=n.slice(t+1)),Lo.hasOwnProperty(e)?{space:Lo[e],local:n}:n}},Co.attr=function(n,t){if(arguments.length<2){if("string"==typeof n){var e=this.node();return n=ao.ns.qualify(n),n.local?e.getAttributeNS(n.space,n.local):e.getAttribute(n)}for(t in n)this.each(z(t,n[t]));return this}return this.each(z(n,t))},Co.classed=function(n,t){if(arguments.length<2){if("string"==typeof n){var e=this.node(),r=(n=T(n)).length,i=-1;if(t=e.classList){for(;++ii){if("string"!=typeof n){2>i&&(e="");for(r in n)this.each(P(r,n[r],e));return this}if(2>i){var u=this.node();return t(u).getComputedStyle(u,null).getPropertyValue(n)}r=""}return this.each(P(n,e,r))},Co.property=function(n,t){if(arguments.length<2){if("string"==typeof n)return this.node()[n];for(t in n)this.each(U(t,n[t]));return this}return this.each(U(n,t))},Co.text=function(n){return arguments.length?this.each("function"==typeof n?function(){var t=n.apply(this,arguments);this.textContent=null==t?"":t}:null==n?function(){this.textContent=""}:function(){this.textContent=n}):this.node().textContent},Co.html=function(n){return arguments.length?this.each("function"==typeof n?function(){var t=n.apply(this,arguments);this.innerHTML=null==t?"":t}:null==n?function(){this.innerHTML=""}:function(){this.innerHTML=n}):this.node().innerHTML},Co.append=function(n){return n=j(n),this.select(function(){return this.appendChild(n.apply(this,arguments))})},Co.insert=function(n,t){return n=j(n),t=A(t),this.select(function(){return this.insertBefore(n.apply(this,arguments),t.apply(this,arguments)||null)})},Co.remove=function(){return this.each(F)},Co.data=function(n,t){function e(n,e){var r,i,u,o=n.length,s=e.length,h=Math.min(o,s),p=new Array(s),g=new Array(s),v=new Array(o);if(t){var d,y=new c,m=new Array(o);for(r=-1;++rr;++r)g[r]=H(e[r]);for(;o>r;++r)v[r]=n[r]}g.update=p,g.parentNode=p.parentNode=v.parentNode=n.parentNode,a.push(g),l.push(p),f.push(v)}var r,i,u=-1,o=this.length;if(!arguments.length){for(n=new Array(o=(r=this[0]).length);++uu;u++){i.push(t=[]),t.parentNode=(e=this[u]).parentNode;for(var a=0,l=e.length;l>a;a++)(r=e[a])&&n.call(r,r.__data__,a,u)&&t.push(r)}return E(i)},Co.order=function(){for(var n=-1,t=this.length;++n=0;)(e=r[i])&&(u&&u!==e.nextSibling&&u.parentNode.insertBefore(e,u),u=e);return this},Co.sort=function(n){n=I.apply(this,arguments);for(var t=-1,e=this.length;++tn;n++)for(var e=this[n],r=0,i=e.length;i>r;r++){var u=e[r];if(u)return u}return null},Co.size=function(){var n=0;return Y(this,function(){++n}),n};var qo=[];ao.selection.enter=Z,ao.selection.enter.prototype=qo,qo.append=Co.append,qo.empty=Co.empty,qo.node=Co.node,qo.call=Co.call,qo.size=Co.size,qo.select=function(n){for(var t,e,r,i,u,o=[],a=-1,l=this.length;++ar){if("string"!=typeof n){2>r&&(t=!1);for(e in n)this.each(X(e,n[e],t));return this}if(2>r)return(r=this.node()["__on"+n])&&r._;e=!1}return this.each(X(n,t,e))};var To=ao.map({mouseenter:"mouseover",mouseleave:"mouseout"});fo&&To.forEach(function(n){"on"+n in fo&&To.remove(n)});var Ro,Do=0;ao.mouse=function(n){return J(n,k())};var Po=this.navigator&&/WebKit/.test(this.navigator.userAgent)?-1:0;ao.touch=function(n,t,e){if(arguments.length<3&&(e=t,t=k().changedTouches),t)for(var r,i=0,u=t.length;u>i;++i)if((r=t[i]).identifier===e)return J(n,r)},ao.behavior.drag=function(){function n(){this.on("mousedown.drag",u).on("touchstart.drag",o)}function e(n,t,e,u,o){return function(){function a(){var n,e,r=t(h,v);r&&(n=r[0]-M[0],e=r[1]-M[1],g|=n|e,M=r,p({type:"drag",x:r[0]+c[0],y:r[1]+c[1],dx:n,dy:e}))}function l(){t(h,v)&&(y.on(u+d,null).on(o+d,null),m(g),p({type:"dragend"}))}var c,f=this,s=ao.event.target.correspondingElement||ao.event.target,h=f.parentNode,p=r.of(f,arguments),g=0,v=n(),d=".drag"+(null==v?"":"-"+v),y=ao.select(e(s)).on(u+d,a).on(o+d,l),m=W(s),M=t(h,v);i?(c=i.apply(f,arguments),c=[c.x-M[0],c.y-M[1]]):c=[0,0],p({type:"dragstart"})}}var r=N(n,"drag","dragstart","dragend"),i=null,u=e(b,ao.mouse,t,"mousemove","mouseup"),o=e(G,ao.touch,m,"touchmove","touchend");return n.origin=function(t){return arguments.length?(i=t,n):i},ao.rebind(n,r,"on")},ao.touches=function(n,t){return arguments.length<2&&(t=k().touches),t?co(t).map(function(t){var e=J(n,t);return e.identifier=t.identifier,e}):[]};var Uo=1e-6,jo=Uo*Uo,Fo=Math.PI,Ho=2*Fo,Oo=Ho-Uo,Io=Fo/2,Yo=Fo/180,Zo=180/Fo,Vo=Math.SQRT2,Xo=2,$o=4;ao.interpolateZoom=function(n,t){var e,r,i=n[0],u=n[1],o=n[2],a=t[0],l=t[1],c=t[2],f=a-i,s=l-u,h=f*f+s*s;if(jo>h)r=Math.log(c/o)/Vo,e=function(n){return[i+n*f,u+n*s,o*Math.exp(Vo*n*r)]};else{var p=Math.sqrt(h),g=(c*c-o*o+$o*h)/(2*o*Xo*p),v=(c*c-o*o-$o*h)/(2*c*Xo*p),d=Math.log(Math.sqrt(g*g+1)-g),y=Math.log(Math.sqrt(v*v+1)-v);r=(y-d)/Vo,e=function(n){var t=n*r,e=rn(d),a=o/(Xo*p)*(e*un(Vo*t+d)-en(d));return[i+a*f,u+a*s,o*e/rn(Vo*t+d)]}}return e.duration=1e3*r,e},ao.behavior.zoom=function(){function n(n){n.on(L,s).on(Wo+".zoom",p).on("dblclick.zoom",g).on(R,h)}function e(n){return[(n[0]-k.x)/k.k,(n[1]-k.y)/k.k]}function r(n){return[n[0]*k.k+k.x,n[1]*k.k+k.y]}function i(n){k.k=Math.max(A[0],Math.min(A[1],n))}function u(n,t){t=r(t),k.x+=n[0]-t[0],k.y+=n[1]-t[1]}function o(t,e,r,o){t.__chart__={x:k.x,y:k.y,k:k.k},i(Math.pow(2,o)),u(d=e,r),t=ao.select(t),C>0&&(t=t.transition().duration(C)),t.call(n.event)}function a(){b&&b.domain(x.range().map(function(n){return(n-k.x)/k.k}).map(x.invert)),w&&w.domain(_.range().map(function(n){return(n-k.y)/k.k}).map(_.invert))}function l(n){z++||n({type:"zoomstart"})}function c(n){a(),n({type:"zoom",scale:k.k,translate:[k.x,k.y]})}function f(n){--z||(n({type:"zoomend"}),d=null)}function s(){function n(){a=1,u(ao.mouse(i),h),c(o)}function r(){s.on(q,null).on(T,null),p(a),f(o)}var i=this,o=D.of(i,arguments),a=0,s=ao.select(t(i)).on(q,n).on(T,r),h=e(ao.mouse(i)),p=W(i);Il.call(i),l(o)}function h(){function n(){var n=ao.touches(g);return p=k.k,n.forEach(function(n){n.identifier in d&&(d[n.identifier]=e(n))}),n}function t(){var t=ao.event.target;ao.select(t).on(x,r).on(b,a),_.push(t);for(var e=ao.event.changedTouches,i=0,u=e.length;u>i;++i)d[e[i].identifier]=null;var l=n(),c=Date.now();if(1===l.length){if(500>c-M){var f=l[0];o(g,f,d[f.identifier],Math.floor(Math.log(k.k)/Math.LN2)+1),S()}M=c}else if(l.length>1){var f=l[0],s=l[1],h=f[0]-s[0],p=f[1]-s[1];y=h*h+p*p}}function r(){var n,t,e,r,o=ao.touches(g);Il.call(g);for(var a=0,l=o.length;l>a;++a,r=null)if(e=o[a],r=d[e.identifier]){if(t)break;n=e,t=r}if(r){var f=(f=e[0]-n[0])*f+(f=e[1]-n[1])*f,s=y&&Math.sqrt(f/y);n=[(n[0]+e[0])/2,(n[1]+e[1])/2],t=[(t[0]+r[0])/2,(t[1]+r[1])/2],i(s*p)}M=null,u(n,t),c(v)}function a(){if(ao.event.touches.length){for(var t=ao.event.changedTouches,e=0,r=t.length;r>e;++e)delete d[t[e].identifier];for(var i in d)return void n()}ao.selectAll(_).on(m,null),w.on(L,s).on(R,h),N(),f(v)}var p,g=this,v=D.of(g,arguments),d={},y=0,m=".zoom-"+ao.event.changedTouches[0].identifier,x="touchmove"+m,b="touchend"+m,_=[],w=ao.select(g),N=W(g);t(),l(v),w.on(L,null).on(R,t)}function p(){var n=D.of(this,arguments);m?clearTimeout(m):(Il.call(this),v=e(d=y||ao.mouse(this)),l(n)),m=setTimeout(function(){m=null,f(n)},50),S(),i(Math.pow(2,.002*Bo())*k.k),u(d,v),c(n)}function g(){var n=ao.mouse(this),t=Math.log(k.k)/Math.LN2;o(this,n,e(n),ao.event.shiftKey?Math.ceil(t)-1:Math.floor(t)+1)}var v,d,y,m,M,x,b,_,w,k={x:0,y:0,k:1},E=[960,500],A=Jo,C=250,z=0,L="mousedown.zoom",q="mousemove.zoom",T="mouseup.zoom",R="touchstart.zoom",D=N(n,"zoomstart","zoom","zoomend");return Wo||(Wo="onwheel"in fo?(Bo=function(){return-ao.event.deltaY*(ao.event.deltaMode?120:1)},"wheel"):"onmousewheel"in fo?(Bo=function(){return ao.event.wheelDelta},"mousewheel"):(Bo=function(){return-ao.event.detail},"MozMousePixelScroll")),n.event=function(n){n.each(function(){var n=D.of(this,arguments),t=k;Hl?ao.select(this).transition().each("start.zoom",function(){k=this.__chart__||{x:0,y:0,k:1},l(n)}).tween("zoom:zoom",function(){var e=E[0],r=E[1],i=d?d[0]:e/2,u=d?d[1]:r/2,o=ao.interpolateZoom([(i-k.x)/k.k,(u-k.y)/k.k,e/k.k],[(i-t.x)/t.k,(u-t.y)/t.k,e/t.k]);return function(t){var r=o(t),a=e/r[2];this.__chart__=k={x:i-r[0]*a,y:u-r[1]*a,k:a},c(n)}}).each("interrupt.zoom",function(){f(n)}).each("end.zoom",function(){f(n)}):(this.__chart__=k,l(n),c(n),f(n))})},n.translate=function(t){return arguments.length?(k={x:+t[0],y:+t[1],k:k.k},a(),n):[k.x,k.y]},n.scale=function(t){return arguments.length?(k={x:k.x,y:k.y,k:null},i(+t),a(),n):k.k},n.scaleExtent=function(t){return arguments.length?(A=null==t?Jo:[+t[0],+t[1]],n):A},n.center=function(t){return arguments.length?(y=t&&[+t[0],+t[1]],n):y},n.size=function(t){return arguments.length?(E=t&&[+t[0],+t[1]],n):E},n.duration=function(t){return arguments.length?(C=+t,n):C},n.x=function(t){return arguments.length?(b=t,x=t.copy(),k={x:0,y:0,k:1},n):b},n.y=function(t){return arguments.length?(w=t,_=t.copy(),k={x:0,y:0,k:1},n):w},ao.rebind(n,D,"on")};var Bo,Wo,Jo=[0,1/0];ao.color=an,an.prototype.toString=function(){return this.rgb()+""},ao.hsl=ln;var Go=ln.prototype=new an;Go.brighter=function(n){return n=Math.pow(.7,arguments.length?n:1),new ln(this.h,this.s,this.l/n)},Go.darker=function(n){return n=Math.pow(.7,arguments.length?n:1),new ln(this.h,this.s,n*this.l)},Go.rgb=function(){return cn(this.h,this.s,this.l)},ao.hcl=fn;var Ko=fn.prototype=new an;Ko.brighter=function(n){return new fn(this.h,this.c,Math.min(100,this.l+Qo*(arguments.length?n:1)))},Ko.darker=function(n){return new fn(this.h,this.c,Math.max(0,this.l-Qo*(arguments.length?n:1)))},Ko.rgb=function(){return sn(this.h,this.c,this.l).rgb()},ao.lab=hn;var Qo=18,na=.95047,ta=1,ea=1.08883,ra=hn.prototype=new an;ra.brighter=function(n){return new hn(Math.min(100,this.l+Qo*(arguments.length?n:1)),this.a,this.b)},ra.darker=function(n){return new hn(Math.max(0,this.l-Qo*(arguments.length?n:1)),this.a,this.b)},ra.rgb=function(){return pn(this.l,this.a,this.b)},ao.rgb=mn;var ia=mn.prototype=new an;ia.brighter=function(n){n=Math.pow(.7,arguments.length?n:1);var t=this.r,e=this.g,r=this.b,i=30;return t||e||r?(t&&i>t&&(t=i),e&&i>e&&(e=i),r&&i>r&&(r=i),new mn(Math.min(255,t/n),Math.min(255,e/n),Math.min(255,r/n))):new mn(i,i,i)},ia.darker=function(n){return n=Math.pow(.7,arguments.length?n:1),new mn(n*this.r,n*this.g,n*this.b)},ia.hsl=function(){return wn(this.r,this.g,this.b)},ia.toString=function(){return"#"+bn(this.r)+bn(this.g)+bn(this.b)};var ua=ao.map({aliceblue:15792383,antiquewhite:16444375,aqua:65535,aquamarine:8388564,azure:15794175,beige:16119260,bisque:16770244,black:0,blanchedalmond:16772045,blue:255,blueviolet:9055202,brown:10824234,burlywood:14596231,cadetblue:6266528,chartreuse:8388352,chocolate:13789470,coral:16744272,cornflowerblue:6591981,cornsilk:16775388,crimson:14423100,cyan:65535,darkblue:139,darkcyan:35723,darkgoldenrod:12092939,darkgray:11119017,darkgreen:25600,darkgrey:11119017,darkkhaki:12433259,darkmagenta:9109643,darkolivegreen:5597999,darkorange:16747520,darkorchid:10040012,darkred:9109504,darksalmon:15308410,darkseagreen:9419919,darkslateblue:4734347,darkslategray:3100495,darkslategrey:3100495,darkturquoise:52945,darkviolet:9699539,deeppink:16716947,deepskyblue:49151,dimgray:6908265,dimgrey:6908265,dodgerblue:2003199,firebrick:11674146,floralwhite:16775920,forestgreen:2263842,fuchsia:16711935,gainsboro:14474460,ghostwhite:16316671,gold:16766720,goldenrod:14329120,gray:8421504,green:32768,greenyellow:11403055,grey:8421504,honeydew:15794160,hotpink:16738740,indianred:13458524,indigo:4915330,ivory:16777200,khaki:15787660,lavender:15132410,lavenderblush:16773365,lawngreen:8190976,lemonchiffon:16775885,lightblue:11393254,lightcoral:15761536,lightcyan:14745599,lightgoldenrodyellow:16448210,lightgray:13882323,lightgreen:9498256,lightgrey:13882323,lightpink:16758465,lightsalmon:16752762,lightseagreen:2142890,lightskyblue:8900346,lightslategray:7833753,lightslategrey:7833753,lightsteelblue:11584734,lightyellow:16777184,lime:65280,limegreen:3329330,linen:16445670,magenta:16711935,maroon:8388608,mediumaquamarine:6737322,mediumblue:205,mediumorchid:12211667,mediumpurple:9662683,mediumseagreen:3978097,mediumslateblue:8087790,mediumspringgreen:64154,mediumturquoise:4772300,mediumvioletred:13047173,midnightblue:1644912,mintcream:16121850,mistyrose:16770273,moccasin:16770229,navajowhite:16768685,navy:128,oldlace:16643558,olive:8421376,olivedrab:7048739,orange:16753920,orangered:16729344,orchid:14315734,palegoldenrod:15657130,palegreen:10025880,paleturquoise:11529966,palevioletred:14381203,papayawhip:16773077,peachpuff:16767673,peru:13468991,pink:16761035,plum:14524637,powderblue:11591910,purple:8388736,rebeccapurple:6697881,red:16711680,rosybrown:12357519,royalblue:4286945,saddlebrown:9127187,salmon:16416882,sandybrown:16032864,seagreen:3050327,seashell:16774638,sienna:10506797,silver:12632256,skyblue:8900331,slateblue:6970061,slategray:7372944,slategrey:7372944,snow:16775930,springgreen:65407,steelblue:4620980,tan:13808780,teal:32896,thistle:14204888,tomato:16737095,turquoise:4251856,violet:15631086,wheat:16113331,white:16777215,whitesmoke:16119285,yellow:16776960,yellowgreen:10145074});ua.forEach(function(n,t){ua.set(n,Mn(t))}),ao.functor=En,ao.xhr=An(m),ao.dsv=function(n,t){function e(n,e,u){arguments.length<3&&(u=e,e=null);var o=Cn(n,t,null==e?r:i(e),u);return o.row=function(n){return arguments.length?o.response(null==(e=n)?r:i(n)):e},o}function r(n){return e.parse(n.responseText)}function i(n){return function(t){return e.parse(t.responseText,n)}}function u(t){return t.map(o).join(n)}function o(n){return a.test(n)?'"'+n.replace(/\"/g,'""')+'"':n}var a=new RegExp('["'+n+"\n]"),l=n.charCodeAt(0);return e.parse=function(n,t){var r;return e.parseRows(n,function(n,e){if(r)return r(n,e-1);var i=new Function("d","return {"+n.map(function(n,t){return JSON.stringify(n)+": d["+t+"]"}).join(",")+"}");r=t?function(n,e){return t(i(n),e)}:i})},e.parseRows=function(n,t){function e(){if(f>=c)return o;if(i)return i=!1,u;var t=f;if(34===n.charCodeAt(t)){for(var e=t;e++f;){var r=n.charCodeAt(f++),a=1;if(10===r)i=!0;else if(13===r)i=!0,10===n.charCodeAt(f)&&(++f,++a);else if(r!==l)continue;return n.slice(t,f-a)}return n.slice(t)}for(var r,i,u={},o={},a=[],c=n.length,f=0,s=0;(r=e())!==o;){for(var h=[];r!==u&&r!==o;)h.push(r),r=e();t&&null==(h=t(h,s++))||a.push(h)}return a},e.format=function(t){if(Array.isArray(t[0]))return e.formatRows(t);var r=new y,i=[];return t.forEach(function(n){for(var t in n)r.has(t)||i.push(r.add(t))}),[i.map(o).join(n)].concat(t.map(function(t){return i.map(function(n){return o(t[n])}).join(n)})).join("\n")},e.formatRows=function(n){return n.map(u).join("\n")},e},ao.csv=ao.dsv(",","text/csv"),ao.tsv=ao.dsv(" ","text/tab-separated-values");var oa,aa,la,ca,fa=this[x(this,"requestAnimationFrame")]||function(n){setTimeout(n,17)};ao.timer=function(){qn.apply(this,arguments)},ao.timer.flush=function(){Rn(),Dn()},ao.round=function(n,t){return t?Math.round(n*(t=Math.pow(10,t)))/t:Math.round(n)};var sa=["y","z","a","f","p","n","\xb5","m","","k","M","G","T","P","E","Z","Y"].map(Un);ao.formatPrefix=function(n,t){var e=0;return(n=+n)&&(0>n&&(n*=-1),t&&(n=ao.round(n,Pn(n,t))),e=1+Math.floor(1e-12+Math.log(n)/Math.LN10),e=Math.max(-24,Math.min(24,3*Math.floor((e-1)/3)))),sa[8+e/3]};var ha=/(?:([^{])?([<>=^]))?([+\- ])?([$#])?(0)?(\d+)?(,)?(\.-?\d+)?([a-z%])?/i,pa=ao.map({b:function(n){return n.toString(2)},c:function(n){return String.fromCharCode(n)},o:function(n){return n.toString(8)},x:function(n){return n.toString(16)},X:function(n){return n.toString(16).toUpperCase()},g:function(n,t){return n.toPrecision(t)},e:function(n,t){return n.toExponential(t)},f:function(n,t){return n.toFixed(t)},r:function(n,t){return(n=ao.round(n,Pn(n,t))).toFixed(Math.max(0,Math.min(20,Pn(n*(1+1e-15),t))))}}),ga=ao.time={},va=Date;Hn.prototype={getDate:function(){return this._.getUTCDate()},getDay:function(){return this._.getUTCDay()},getFullYear:function(){return this._.getUTCFullYear()},getHours:function(){return this._.getUTCHours()},getMilliseconds:function(){return this._.getUTCMilliseconds()},getMinutes:function(){return this._.getUTCMinutes()},getMonth:function(){return this._.getUTCMonth()},getSeconds:function(){return this._.getUTCSeconds()},getTime:function(){return this._.getTime()},getTimezoneOffset:function(){return 0},valueOf:function(){return this._.valueOf()},setDate:function(){da.setUTCDate.apply(this._,arguments)},setDay:function(){da.setUTCDay.apply(this._,arguments)},setFullYear:function(){da.setUTCFullYear.apply(this._,arguments)},setHours:function(){da.setUTCHours.apply(this._,arguments)},setMilliseconds:function(){da.setUTCMilliseconds.apply(this._,arguments)},setMinutes:function(){da.setUTCMinutes.apply(this._,arguments)},setMonth:function(){da.setUTCMonth.apply(this._,arguments)},setSeconds:function(){da.setUTCSeconds.apply(this._,arguments)},setTime:function(){da.setTime.apply(this._,arguments)}};var da=Date.prototype;ga.year=On(function(n){return n=ga.day(n),n.setMonth(0,1),n},function(n,t){n.setFullYear(n.getFullYear()+t)},function(n){return n.getFullYear()}),ga.years=ga.year.range,ga.years.utc=ga.year.utc.range,ga.day=On(function(n){var t=new va(2e3,0);return t.setFullYear(n.getFullYear(),n.getMonth(),n.getDate()),t},function(n,t){n.setDate(n.getDate()+t)},function(n){return n.getDate()-1}),ga.days=ga.day.range,ga.days.utc=ga.day.utc.range,ga.dayOfYear=function(n){var t=ga.year(n);return Math.floor((n-t-6e4*(n.getTimezoneOffset()-t.getTimezoneOffset()))/864e5)},["sunday","monday","tuesday","wednesday","thursday","friday","saturday"].forEach(function(n,t){t=7-t;var e=ga[n]=On(function(n){return(n=ga.day(n)).setDate(n.getDate()-(n.getDay()+t)%7),n},function(n,t){n.setDate(n.getDate()+7*Math.floor(t))},function(n){var e=ga.year(n).getDay();return Math.floor((ga.dayOfYear(n)+(e+t)%7)/7)-(e!==t)});ga[n+"s"]=e.range,ga[n+"s"].utc=e.utc.range,ga[n+"OfYear"]=function(n){var e=ga.year(n).getDay();return Math.floor((ga.dayOfYear(n)+(e+t)%7)/7)}}),ga.week=ga.sunday,ga.weeks=ga.sunday.range,ga.weeks.utc=ga.sunday.utc.range,ga.weekOfYear=ga.sundayOfYear;var ya={"-":"",_:" ",0:"0"},ma=/^\s*\d+/,Ma=/^%/;ao.locale=function(n){return{numberFormat:jn(n),timeFormat:Yn(n)}};var xa=ao.locale({decimal:".",thousands:",",grouping:[3],currency:["$",""],dateTime:"%a %b %e %X %Y",date:"%m/%d/%Y",time:"%H:%M:%S",periods:["AM","PM"],days:["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"], -shortDays:["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],months:["January","February","March","April","May","June","July","August","September","October","November","December"],shortMonths:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"]});ao.format=xa.numberFormat,ao.geo={},ft.prototype={s:0,t:0,add:function(n){st(n,this.t,ba),st(ba.s,this.s,this),this.s?this.t+=ba.t:this.s=ba.t},reset:function(){this.s=this.t=0},valueOf:function(){return this.s}};var ba=new ft;ao.geo.stream=function(n,t){n&&_a.hasOwnProperty(n.type)?_a[n.type](n,t):ht(n,t)};var _a={Feature:function(n,t){ht(n.geometry,t)},FeatureCollection:function(n,t){for(var e=n.features,r=-1,i=e.length;++rn?4*Fo+n:n,Na.lineStart=Na.lineEnd=Na.point=b}};ao.geo.bounds=function(){function n(n,t){M.push(x=[f=n,h=n]),s>t&&(s=t),t>p&&(p=t)}function t(t,e){var r=dt([t*Yo,e*Yo]);if(y){var i=mt(y,r),u=[i[1],-i[0],0],o=mt(u,i);bt(o),o=_t(o);var l=t-g,c=l>0?1:-1,v=o[0]*Zo*c,d=xo(l)>180;if(d^(v>c*g&&c*t>v)){var m=o[1]*Zo;m>p&&(p=m)}else if(v=(v+360)%360-180,d^(v>c*g&&c*t>v)){var m=-o[1]*Zo;s>m&&(s=m)}else s>e&&(s=e),e>p&&(p=e);d?g>t?a(f,t)>a(f,h)&&(h=t):a(t,h)>a(f,h)&&(f=t):h>=f?(f>t&&(f=t),t>h&&(h=t)):t>g?a(f,t)>a(f,h)&&(h=t):a(t,h)>a(f,h)&&(f=t)}else n(t,e);y=r,g=t}function e(){b.point=t}function r(){x[0]=f,x[1]=h,b.point=n,y=null}function i(n,e){if(y){var r=n-g;m+=xo(r)>180?r+(r>0?360:-360):r}else v=n,d=e;Na.point(n,e),t(n,e)}function u(){Na.lineStart()}function o(){i(v,d),Na.lineEnd(),xo(m)>Uo&&(f=-(h=180)),x[0]=f,x[1]=h,y=null}function a(n,t){return(t-=n)<0?t+360:t}function l(n,t){return n[0]-t[0]}function c(n,t){return t[0]<=t[1]?t[0]<=n&&n<=t[1]:nka?(f=-(h=180),s=-(p=90)):m>Uo?p=90:-Uo>m&&(s=-90),x[0]=f,x[1]=h}};return function(n){p=h=-(f=s=1/0),M=[],ao.geo.stream(n,b);var t=M.length;if(t){M.sort(l);for(var e,r=1,i=M[0],u=[i];t>r;++r)e=M[r],c(e[0],i)||c(e[1],i)?(a(i[0],e[1])>a(i[0],i[1])&&(i[1]=e[1]),a(e[0],i[1])>a(i[0],i[1])&&(i[0]=e[0])):u.push(i=e);for(var o,e,g=-(1/0),t=u.length-1,r=0,i=u[t];t>=r;i=e,++r)e=u[r],(o=a(i[1],e[0]))>g&&(g=o,f=e[0],h=i[1])}return M=x=null,f===1/0||s===1/0?[[NaN,NaN],[NaN,NaN]]:[[f,s],[h,p]]}}(),ao.geo.centroid=function(n){Ea=Aa=Ca=za=La=qa=Ta=Ra=Da=Pa=Ua=0,ao.geo.stream(n,ja);var t=Da,e=Pa,r=Ua,i=t*t+e*e+r*r;return jo>i&&(t=qa,e=Ta,r=Ra,Uo>Aa&&(t=Ca,e=za,r=La),i=t*t+e*e+r*r,jo>i)?[NaN,NaN]:[Math.atan2(e,t)*Zo,tn(r/Math.sqrt(i))*Zo]};var Ea,Aa,Ca,za,La,qa,Ta,Ra,Da,Pa,Ua,ja={sphere:b,point:St,lineStart:Nt,lineEnd:Et,polygonStart:function(){ja.lineStart=At},polygonEnd:function(){ja.lineStart=Nt}},Fa=Rt(zt,jt,Ht,[-Fo,-Fo/2]),Ha=1e9;ao.geo.clipExtent=function(){var n,t,e,r,i,u,o={stream:function(n){return i&&(i.valid=!1),i=u(n),i.valid=!0,i},extent:function(a){return arguments.length?(u=Zt(n=+a[0][0],t=+a[0][1],e=+a[1][0],r=+a[1][1]),i&&(i.valid=!1,i=null),o):[[n,t],[e,r]]}};return o.extent([[0,0],[960,500]])},(ao.geo.conicEqualArea=function(){return Vt(Xt)}).raw=Xt,ao.geo.albers=function(){return ao.geo.conicEqualArea().rotate([96,0]).center([-.6,38.7]).parallels([29.5,45.5]).scale(1070)},ao.geo.albersUsa=function(){function n(n){var u=n[0],o=n[1];return t=null,e(u,o),t||(r(u,o),t)||i(u,o),t}var t,e,r,i,u=ao.geo.albers(),o=ao.geo.conicEqualArea().rotate([154,0]).center([-2,58.5]).parallels([55,65]),a=ao.geo.conicEqualArea().rotate([157,0]).center([-3,19.9]).parallels([8,18]),l={point:function(n,e){t=[n,e]}};return n.invert=function(n){var t=u.scale(),e=u.translate(),r=(n[0]-e[0])/t,i=(n[1]-e[1])/t;return(i>=.12&&.234>i&&r>=-.425&&-.214>r?o:i>=.166&&.234>i&&r>=-.214&&-.115>r?a:u).invert(n)},n.stream=function(n){var t=u.stream(n),e=o.stream(n),r=a.stream(n);return{point:function(n,i){t.point(n,i),e.point(n,i),r.point(n,i)},sphere:function(){t.sphere(),e.sphere(),r.sphere()},lineStart:function(){t.lineStart(),e.lineStart(),r.lineStart()},lineEnd:function(){t.lineEnd(),e.lineEnd(),r.lineEnd()},polygonStart:function(){t.polygonStart(),e.polygonStart(),r.polygonStart()},polygonEnd:function(){t.polygonEnd(),e.polygonEnd(),r.polygonEnd()}}},n.precision=function(t){return arguments.length?(u.precision(t),o.precision(t),a.precision(t),n):u.precision()},n.scale=function(t){return arguments.length?(u.scale(t),o.scale(.35*t),a.scale(t),n.translate(u.translate())):u.scale()},n.translate=function(t){if(!arguments.length)return u.translate();var c=u.scale(),f=+t[0],s=+t[1];return e=u.translate(t).clipExtent([[f-.455*c,s-.238*c],[f+.455*c,s+.238*c]]).stream(l).point,r=o.translate([f-.307*c,s+.201*c]).clipExtent([[f-.425*c+Uo,s+.12*c+Uo],[f-.214*c-Uo,s+.234*c-Uo]]).stream(l).point,i=a.translate([f-.205*c,s+.212*c]).clipExtent([[f-.214*c+Uo,s+.166*c+Uo],[f-.115*c-Uo,s+.234*c-Uo]]).stream(l).point,n},n.scale(1070)};var Oa,Ia,Ya,Za,Va,Xa,$a={point:b,lineStart:b,lineEnd:b,polygonStart:function(){Ia=0,$a.lineStart=$t},polygonEnd:function(){$a.lineStart=$a.lineEnd=$a.point=b,Oa+=xo(Ia/2)}},Ba={point:Bt,lineStart:b,lineEnd:b,polygonStart:b,polygonEnd:b},Wa={point:Gt,lineStart:Kt,lineEnd:Qt,polygonStart:function(){Wa.lineStart=ne},polygonEnd:function(){Wa.point=Gt,Wa.lineStart=Kt,Wa.lineEnd=Qt}};ao.geo.path=function(){function n(n){return n&&("function"==typeof a&&u.pointRadius(+a.apply(this,arguments)),o&&o.valid||(o=i(u)),ao.geo.stream(n,o)),u.result()}function t(){return o=null,n}var e,r,i,u,o,a=4.5;return n.area=function(n){return Oa=0,ao.geo.stream(n,i($a)),Oa},n.centroid=function(n){return Ca=za=La=qa=Ta=Ra=Da=Pa=Ua=0,ao.geo.stream(n,i(Wa)),Ua?[Da/Ua,Pa/Ua]:Ra?[qa/Ra,Ta/Ra]:La?[Ca/La,za/La]:[NaN,NaN]},n.bounds=function(n){return Va=Xa=-(Ya=Za=1/0),ao.geo.stream(n,i(Ba)),[[Ya,Za],[Va,Xa]]},n.projection=function(n){return arguments.length?(i=(e=n)?n.stream||re(n):m,t()):e},n.context=function(n){return arguments.length?(u=null==(r=n)?new Wt:new te(n),"function"!=typeof a&&u.pointRadius(a),t()):r},n.pointRadius=function(t){return arguments.length?(a="function"==typeof t?t:(u.pointRadius(+t),+t),n):a},n.projection(ao.geo.albersUsa()).context(null)},ao.geo.transform=function(n){return{stream:function(t){var e=new ie(t);for(var r in n)e[r]=n[r];return e}}},ie.prototype={point:function(n,t){this.stream.point(n,t)},sphere:function(){this.stream.sphere()},lineStart:function(){this.stream.lineStart()},lineEnd:function(){this.stream.lineEnd()},polygonStart:function(){this.stream.polygonStart()},polygonEnd:function(){this.stream.polygonEnd()}},ao.geo.projection=oe,ao.geo.projectionMutator=ae,(ao.geo.equirectangular=function(){return oe(ce)}).raw=ce.invert=ce,ao.geo.rotation=function(n){function t(t){return t=n(t[0]*Yo,t[1]*Yo),t[0]*=Zo,t[1]*=Zo,t}return n=se(n[0]%360*Yo,n[1]*Yo,n.length>2?n[2]*Yo:0),t.invert=function(t){return t=n.invert(t[0]*Yo,t[1]*Yo),t[0]*=Zo,t[1]*=Zo,t},t},fe.invert=ce,ao.geo.circle=function(){function n(){var n="function"==typeof r?r.apply(this,arguments):r,t=se(-n[0]*Yo,-n[1]*Yo,0).invert,i=[];return e(null,null,1,{point:function(n,e){i.push(n=t(n,e)),n[0]*=Zo,n[1]*=Zo}}),{type:"Polygon",coordinates:[i]}}var t,e,r=[0,0],i=6;return n.origin=function(t){return arguments.length?(r=t,n):r},n.angle=function(r){return arguments.length?(e=ve((t=+r)*Yo,i*Yo),n):t},n.precision=function(r){return arguments.length?(e=ve(t*Yo,(i=+r)*Yo),n):i},n.angle(90)},ao.geo.distance=function(n,t){var e,r=(t[0]-n[0])*Yo,i=n[1]*Yo,u=t[1]*Yo,o=Math.sin(r),a=Math.cos(r),l=Math.sin(i),c=Math.cos(i),f=Math.sin(u),s=Math.cos(u);return Math.atan2(Math.sqrt((e=s*o)*e+(e=c*f-l*s*a)*e),l*f+c*s*a)},ao.geo.graticule=function(){function n(){return{type:"MultiLineString",coordinates:t()}}function t(){return ao.range(Math.ceil(u/d)*d,i,d).map(h).concat(ao.range(Math.ceil(c/y)*y,l,y).map(p)).concat(ao.range(Math.ceil(r/g)*g,e,g).filter(function(n){return xo(n%d)>Uo}).map(f)).concat(ao.range(Math.ceil(a/v)*v,o,v).filter(function(n){return xo(n%y)>Uo}).map(s))}var e,r,i,u,o,a,l,c,f,s,h,p,g=10,v=g,d=90,y=360,m=2.5;return n.lines=function(){return t().map(function(n){return{type:"LineString",coordinates:n}})},n.outline=function(){return{type:"Polygon",coordinates:[h(u).concat(p(l).slice(1),h(i).reverse().slice(1),p(c).reverse().slice(1))]}},n.extent=function(t){return arguments.length?n.majorExtent(t).minorExtent(t):n.minorExtent()},n.majorExtent=function(t){return arguments.length?(u=+t[0][0],i=+t[1][0],c=+t[0][1],l=+t[1][1],u>i&&(t=u,u=i,i=t),c>l&&(t=c,c=l,l=t),n.precision(m)):[[u,c],[i,l]]},n.minorExtent=function(t){return arguments.length?(r=+t[0][0],e=+t[1][0],a=+t[0][1],o=+t[1][1],r>e&&(t=r,r=e,e=t),a>o&&(t=a,a=o,o=t),n.precision(m)):[[r,a],[e,o]]},n.step=function(t){return arguments.length?n.majorStep(t).minorStep(t):n.minorStep()},n.majorStep=function(t){return arguments.length?(d=+t[0],y=+t[1],n):[d,y]},n.minorStep=function(t){return arguments.length?(g=+t[0],v=+t[1],n):[g,v]},n.precision=function(t){return arguments.length?(m=+t,f=ye(a,o,90),s=me(r,e,m),h=ye(c,l,90),p=me(u,i,m),n):m},n.majorExtent([[-180,-90+Uo],[180,90-Uo]]).minorExtent([[-180,-80-Uo],[180,80+Uo]])},ao.geo.greatArc=function(){function n(){return{type:"LineString",coordinates:[t||r.apply(this,arguments),e||i.apply(this,arguments)]}}var t,e,r=Me,i=xe;return n.distance=function(){return ao.geo.distance(t||r.apply(this,arguments),e||i.apply(this,arguments))},n.source=function(e){return arguments.length?(r=e,t="function"==typeof e?null:e,n):r},n.target=function(t){return arguments.length?(i=t,e="function"==typeof t?null:t,n):i},n.precision=function(){return arguments.length?n:0},n},ao.geo.interpolate=function(n,t){return be(n[0]*Yo,n[1]*Yo,t[0]*Yo,t[1]*Yo)},ao.geo.length=function(n){return Ja=0,ao.geo.stream(n,Ga),Ja};var Ja,Ga={sphere:b,point:b,lineStart:_e,lineEnd:b,polygonStart:b,polygonEnd:b},Ka=we(function(n){return Math.sqrt(2/(1+n))},function(n){return 2*Math.asin(n/2)});(ao.geo.azimuthalEqualArea=function(){return oe(Ka)}).raw=Ka;var Qa=we(function(n){var t=Math.acos(n);return t&&t/Math.sin(t)},m);(ao.geo.azimuthalEquidistant=function(){return oe(Qa)}).raw=Qa,(ao.geo.conicConformal=function(){return Vt(Se)}).raw=Se,(ao.geo.conicEquidistant=function(){return Vt(ke)}).raw=ke;var nl=we(function(n){return 1/n},Math.atan);(ao.geo.gnomonic=function(){return oe(nl)}).raw=nl,Ne.invert=function(n,t){return[n,2*Math.atan(Math.exp(t))-Io]},(ao.geo.mercator=function(){return Ee(Ne)}).raw=Ne;var tl=we(function(){return 1},Math.asin);(ao.geo.orthographic=function(){return oe(tl)}).raw=tl;var el=we(function(n){return 1/(1+n)},function(n){return 2*Math.atan(n)});(ao.geo.stereographic=function(){return oe(el)}).raw=el,Ae.invert=function(n,t){return[-t,2*Math.atan(Math.exp(n))-Io]},(ao.geo.transverseMercator=function(){var n=Ee(Ae),t=n.center,e=n.rotate;return n.center=function(n){return n?t([-n[1],n[0]]):(n=t(),[n[1],-n[0]])},n.rotate=function(n){return n?e([n[0],n[1],n.length>2?n[2]+90:90]):(n=e(),[n[0],n[1],n[2]-90])},e([0,0,90])}).raw=Ae,ao.geom={},ao.geom.hull=function(n){function t(n){if(n.length<3)return[];var t,i=En(e),u=En(r),o=n.length,a=[],l=[];for(t=0;o>t;t++)a.push([+i.call(this,n[t],t),+u.call(this,n[t],t),t]);for(a.sort(qe),t=0;o>t;t++)l.push([a[t][0],-a[t][1]]);var c=Le(a),f=Le(l),s=f[0]===c[0],h=f[f.length-1]===c[c.length-1],p=[];for(t=c.length-1;t>=0;--t)p.push(n[a[c[t]][2]]);for(t=+s;t=r&&c.x<=u&&c.y>=i&&c.y<=o?[[r,o],[u,o],[u,i],[r,i]]:[];f.point=n[a]}),t}function e(n){return n.map(function(n,t){return{x:Math.round(u(n,t)/Uo)*Uo,y:Math.round(o(n,t)/Uo)*Uo,i:t}})}var r=Ce,i=ze,u=r,o=i,a=sl;return n?t(n):(t.links=function(n){return ar(e(n)).edges.filter(function(n){return n.l&&n.r}).map(function(t){return{source:n[t.l.i],target:n[t.r.i]}})},t.triangles=function(n){var t=[];return ar(e(n)).cells.forEach(function(e,r){for(var i,u,o=e.site,a=e.edges.sort(Ve),l=-1,c=a.length,f=a[c-1].edge,s=f.l===o?f.r:f.l;++l=c,h=r>=f,p=h<<1|s;n.leaf=!1,n=n.nodes[p]||(n.nodes[p]=hr()),s?i=c:a=c,h?o=f:l=f,u(n,t,e,r,i,o,a,l)}var f,s,h,p,g,v,d,y,m,M=En(a),x=En(l);if(null!=t)v=t,d=e,y=r,m=i;else if(y=m=-(v=d=1/0),s=[],h=[],g=n.length,o)for(p=0;g>p;++p)f=n[p],f.xy&&(y=f.x),f.y>m&&(m=f.y),s.push(f.x),h.push(f.y);else for(p=0;g>p;++p){var b=+M(f=n[p],p),_=+x(f,p);v>b&&(v=b),d>_&&(d=_),b>y&&(y=b),_>m&&(m=_),s.push(b),h.push(_)}var w=y-v,S=m-d;w>S?m=d+w:y=v+S;var k=hr();if(k.add=function(n){u(k,n,+M(n,++p),+x(n,p),v,d,y,m)},k.visit=function(n){pr(n,k,v,d,y,m)},k.find=function(n){return gr(k,n[0],n[1],v,d,y,m)},p=-1,null==t){for(;++p=0?n.slice(0,t):n,r=t>=0?n.slice(t+1):"in";return e=vl.get(e)||gl,r=dl.get(r)||m,br(r(e.apply(null,lo.call(arguments,1))))},ao.interpolateHcl=Rr,ao.interpolateHsl=Dr,ao.interpolateLab=Pr,ao.interpolateRound=Ur,ao.transform=function(n){var t=fo.createElementNS(ao.ns.prefix.svg,"g");return(ao.transform=function(n){if(null!=n){t.setAttribute("transform",n);var e=t.transform.baseVal.consolidate()}return new jr(e?e.matrix:yl)})(n)},jr.prototype.toString=function(){return"translate("+this.translate+")rotate("+this.rotate+")skewX("+this.skew+")scale("+this.scale+")"};var yl={a:1,b:0,c:0,d:1,e:0,f:0};ao.interpolateTransform=$r,ao.layout={},ao.layout.bundle=function(){return function(n){for(var t=[],e=-1,r=n.length;++ea*a/y){if(v>l){var c=t.charge/l;n.px-=u*c,n.py-=o*c}return!0}if(t.point&&l&&v>l){var c=t.pointCharge/l;n.px-=u*c,n.py-=o*c}}return!t.charge}}function t(n){n.px=ao.event.x,n.py=ao.event.y,l.resume()}var e,r,i,u,o,a,l={},c=ao.dispatch("start","tick","end"),f=[1,1],s=.9,h=ml,p=Ml,g=-30,v=xl,d=.1,y=.64,M=[],x=[];return l.tick=function(){if((i*=.99)<.005)return e=null,c.end({type:"end",alpha:i=0}),!0;var t,r,l,h,p,v,y,m,b,_=M.length,w=x.length;for(r=0;w>r;++r)l=x[r],h=l.source,p=l.target,m=p.x-h.x,b=p.y-h.y,(v=m*m+b*b)&&(v=i*o[r]*((v=Math.sqrt(v))-u[r])/v,m*=v,b*=v,p.x-=m*(y=h.weight+p.weight?h.weight/(h.weight+p.weight):.5),p.y-=b*y,h.x+=m*(y=1-y),h.y+=b*y);if((y=i*d)&&(m=f[0]/2,b=f[1]/2,r=-1,y))for(;++r<_;)l=M[r],l.x+=(m-l.x)*y,l.y+=(b-l.y)*y;if(g)for(ri(t=ao.geom.quadtree(M),i,a),r=-1;++r<_;)(l=M[r]).fixed||t.visit(n(l));for(r=-1;++r<_;)l=M[r],l.fixed?(l.x=l.px,l.y=l.py):(l.x-=(l.px-(l.px=l.x))*s,l.y-=(l.py-(l.py=l.y))*s);c.tick({type:"tick",alpha:i})},l.nodes=function(n){return arguments.length?(M=n,l):M},l.links=function(n){return arguments.length?(x=n,l):x},l.size=function(n){return arguments.length?(f=n,l):f},l.linkDistance=function(n){return arguments.length?(h="function"==typeof n?n:+n,l):h},l.distance=l.linkDistance,l.linkStrength=function(n){return arguments.length?(p="function"==typeof n?n:+n,l):p},l.friction=function(n){return arguments.length?(s=+n,l):s},l.charge=function(n){return arguments.length?(g="function"==typeof n?n:+n,l):g},l.chargeDistance=function(n){return arguments.length?(v=n*n,l):Math.sqrt(v)},l.gravity=function(n){return arguments.length?(d=+n,l):d},l.theta=function(n){return arguments.length?(y=n*n,l):Math.sqrt(y)},l.alpha=function(n){return arguments.length?(n=+n,i?n>0?i=n:(e.c=null,e.t=NaN,e=null,c.end({type:"end",alpha:i=0})):n>0&&(c.start({type:"start",alpha:i=n}),e=qn(l.tick)),l):i},l.start=function(){function n(n,r){if(!e){for(e=new Array(i),l=0;i>l;++l)e[l]=[];for(l=0;c>l;++l){var u=x[l];e[u.source.index].push(u.target),e[u.target.index].push(u.source)}}for(var o,a=e[t],l=-1,f=a.length;++lt;++t)(r=M[t]).index=t,r.weight=0;for(t=0;c>t;++t)r=x[t],"number"==typeof r.source&&(r.source=M[r.source]),"number"==typeof r.target&&(r.target=M[r.target]),++r.source.weight,++r.target.weight;for(t=0;i>t;++t)r=M[t],isNaN(r.x)&&(r.x=n("x",s)),isNaN(r.y)&&(r.y=n("y",v)),isNaN(r.px)&&(r.px=r.x),isNaN(r.py)&&(r.py=r.y);if(u=[],"function"==typeof h)for(t=0;c>t;++t)u[t]=+h.call(this,x[t],t);else for(t=0;c>t;++t)u[t]=h;if(o=[],"function"==typeof p)for(t=0;c>t;++t)o[t]=+p.call(this,x[t],t);else for(t=0;c>t;++t)o[t]=p;if(a=[],"function"==typeof g)for(t=0;i>t;++t)a[t]=+g.call(this,M[t],t);else for(t=0;i>t;++t)a[t]=g;return l.resume()},l.resume=function(){return l.alpha(.1)},l.stop=function(){return l.alpha(0)},l.drag=function(){return r||(r=ao.behavior.drag().origin(m).on("dragstart.force",Qr).on("drag.force",t).on("dragend.force",ni)),arguments.length?void this.on("mouseover.force",ti).on("mouseout.force",ei).call(r):r},ao.rebind(l,c,"on")};var ml=20,Ml=1,xl=1/0;ao.layout.hierarchy=function(){function n(i){var u,o=[i],a=[];for(i.depth=0;null!=(u=o.pop());)if(a.push(u),(c=e.call(n,u,u.depth))&&(l=c.length)){for(var l,c,f;--l>=0;)o.push(f=c[l]),f.parent=u,f.depth=u.depth+1;r&&(u.value=0),u.children=c}else r&&(u.value=+r.call(n,u,u.depth)||0),delete u.children;return oi(i,function(n){var e,i;t&&(e=n.children)&&e.sort(t),r&&(i=n.parent)&&(i.value+=n.value)}),a}var t=ci,e=ai,r=li;return n.sort=function(e){return arguments.length?(t=e,n):t},n.children=function(t){return arguments.length?(e=t,n):e},n.value=function(t){return arguments.length?(r=t,n):r},n.revalue=function(t){return r&&(ui(t,function(n){n.children&&(n.value=0)}),oi(t,function(t){var e;t.children||(t.value=+r.call(n,t,t.depth)||0),(e=t.parent)&&(e.value+=t.value)})),t},n},ao.layout.partition=function(){function n(t,e,r,i){var u=t.children;if(t.x=e,t.y=t.depth*i,t.dx=r,t.dy=i,u&&(o=u.length)){var o,a,l,c=-1;for(r=t.value?r/t.value:0;++cs?-1:1),g=ao.sum(c),v=g?(s-l*p)/g:0,d=ao.range(l),y=[];return null!=e&&d.sort(e===bl?function(n,t){return c[t]-c[n]}:function(n,t){return e(o[n],o[t])}),d.forEach(function(n){y[n]={data:o[n],value:a=c[n],startAngle:f,endAngle:f+=a*v+p,padAngle:h}}),y}var t=Number,e=bl,r=0,i=Ho,u=0;return n.value=function(e){return arguments.length?(t=e,n):t},n.sort=function(t){return arguments.length?(e=t,n):e},n.startAngle=function(t){return arguments.length?(r=t,n):r},n.endAngle=function(t){return arguments.length?(i=t,n):i},n.padAngle=function(t){return arguments.length?(u=t,n):u},n};var bl={};ao.layout.stack=function(){function n(a,l){if(!(h=a.length))return a;var c=a.map(function(e,r){return t.call(n,e,r)}),f=c.map(function(t){return t.map(function(t,e){return[u.call(n,t,e),o.call(n,t,e)]})}),s=e.call(n,f,l);c=ao.permute(c,s),f=ao.permute(f,s);var h,p,g,v,d=r.call(n,f,l),y=c[0].length;for(g=0;y>g;++g)for(i.call(n,c[0][g],v=d[g],f[0][g][1]),p=1;h>p;++p)i.call(n,c[p][g],v+=f[p-1][g][1],f[p][g][1]);return a}var t=m,e=gi,r=vi,i=pi,u=si,o=hi;return n.values=function(e){return arguments.length?(t=e,n):t},n.order=function(t){return arguments.length?(e="function"==typeof t?t:_l.get(t)||gi,n):e},n.offset=function(t){return arguments.length?(r="function"==typeof t?t:wl.get(t)||vi,n):r},n.x=function(t){return arguments.length?(u=t,n):u},n.y=function(t){return arguments.length?(o=t,n):o},n.out=function(t){return arguments.length?(i=t,n):i},n};var _l=ao.map({"inside-out":function(n){var t,e,r=n.length,i=n.map(di),u=n.map(yi),o=ao.range(r).sort(function(n,t){return i[n]-i[t]}),a=0,l=0,c=[],f=[];for(t=0;r>t;++t)e=o[t],l>a?(a+=u[e],c.push(e)):(l+=u[e],f.push(e));return f.reverse().concat(c)},reverse:function(n){return ao.range(n.length).reverse()},"default":gi}),wl=ao.map({silhouette:function(n){var t,e,r,i=n.length,u=n[0].length,o=[],a=0,l=[];for(e=0;u>e;++e){for(t=0,r=0;i>t;t++)r+=n[t][e][1];r>a&&(a=r),o.push(r)}for(e=0;u>e;++e)l[e]=(a-o[e])/2;return l},wiggle:function(n){var t,e,r,i,u,o,a,l,c,f=n.length,s=n[0],h=s.length,p=[];for(p[0]=l=c=0,e=1;h>e;++e){for(t=0,i=0;f>t;++t)i+=n[t][e][1];for(t=0,u=0,a=s[e][0]-s[e-1][0];f>t;++t){for(r=0,o=(n[t][e][1]-n[t][e-1][1])/(2*a);t>r;++r)o+=(n[r][e][1]-n[r][e-1][1])/a;u+=o*n[t][e][1]}p[e]=l-=i?u/i*a:0,c>l&&(c=l)}for(e=0;h>e;++e)p[e]-=c;return p},expand:function(n){var t,e,r,i=n.length,u=n[0].length,o=1/i,a=[];for(e=0;u>e;++e){for(t=0,r=0;i>t;t++)r+=n[t][e][1];if(r)for(t=0;i>t;t++)n[t][e][1]/=r;else for(t=0;i>t;t++)n[t][e][1]=o}for(e=0;u>e;++e)a[e]=0;return a},zero:vi});ao.layout.histogram=function(){function n(n,u){for(var o,a,l=[],c=n.map(e,this),f=r.call(this,c,u),s=i.call(this,f,c,u),u=-1,h=c.length,p=s.length-1,g=t?1:1/h;++u0)for(u=-1;++u=f[0]&&a<=f[1]&&(o=l[ao.bisect(s,a,1,p)-1],o.y+=g,o.push(n[u]));return l}var t=!0,e=Number,r=bi,i=Mi;return n.value=function(t){return arguments.length?(e=t,n):e},n.range=function(t){return arguments.length?(r=En(t),n):r},n.bins=function(t){return arguments.length?(i="number"==typeof t?function(n){return xi(n,t)}:En(t),n):i},n.frequency=function(e){return arguments.length?(t=!!e,n):t},n},ao.layout.pack=function(){function n(n,u){var o=e.call(this,n,u),a=o[0],l=i[0],c=i[1],f=null==t?Math.sqrt:"function"==typeof t?t:function(){return t};if(a.x=a.y=0,oi(a,function(n){n.r=+f(n.value)}),oi(a,Ni),r){var s=r*(t?1:Math.max(2*a.r/l,2*a.r/c))/2;oi(a,function(n){n.r+=s}),oi(a,Ni),oi(a,function(n){n.r-=s})}return Ci(a,l/2,c/2,t?1:1/Math.max(2*a.r/l,2*a.r/c)),o}var t,e=ao.layout.hierarchy().sort(_i),r=0,i=[1,1];return n.size=function(t){return arguments.length?(i=t,n):i},n.radius=function(e){return arguments.length?(t=null==e||"function"==typeof e?e:+e,n):t},n.padding=function(t){return arguments.length?(r=+t,n):r},ii(n,e)},ao.layout.tree=function(){function n(n,i){var f=o.call(this,n,i),s=f[0],h=t(s);if(oi(h,e),h.parent.m=-h.z,ui(h,r),c)ui(s,u);else{var p=s,g=s,v=s;ui(s,function(n){n.xg.x&&(g=n),n.depth>v.depth&&(v=n)});var d=a(p,g)/2-p.x,y=l[0]/(g.x+a(g,p)/2+d),m=l[1]/(v.depth||1);ui(s,function(n){n.x=(n.x+d)*y,n.y=n.depth*m})}return f}function t(n){for(var t,e={A:null,children:[n]},r=[e];null!=(t=r.pop());)for(var i,u=t.children,o=0,a=u.length;a>o;++o)r.push((u[o]=i={_:u[o],parent:t,children:(i=u[o].children)&&i.slice()||[],A:null,a:null,z:0,m:0,c:0,s:0,t:null,i:o}).a=i);return e.children[0]}function e(n){var t=n.children,e=n.parent.children,r=n.i?e[n.i-1]:null;if(t.length){Di(n);var u=(t[0].z+t[t.length-1].z)/2;r?(n.z=r.z+a(n._,r._),n.m=n.z-u):n.z=u}else r&&(n.z=r.z+a(n._,r._));n.parent.A=i(n,r,n.parent.A||e[0])}function r(n){n._.x=n.z+n.parent.m,n.m+=n.parent.m}function i(n,t,e){if(t){for(var r,i=n,u=n,o=t,l=i.parent.children[0],c=i.m,f=u.m,s=o.m,h=l.m;o=Ti(o),i=qi(i),o&&i;)l=qi(l),u=Ti(u),u.a=n,r=o.z+s-i.z-c+a(o._,i._),r>0&&(Ri(Pi(o,n,e),n,r),c+=r,f+=r),s+=o.m,c+=i.m,h+=l.m,f+=u.m;o&&!Ti(u)&&(u.t=o,u.m+=s-f),i&&!qi(l)&&(l.t=i,l.m+=c-h,e=n)}return e}function u(n){n.x*=l[0],n.y=n.depth*l[1]}var o=ao.layout.hierarchy().sort(null).value(null),a=Li,l=[1,1],c=null;return n.separation=function(t){return arguments.length?(a=t,n):a},n.size=function(t){return arguments.length?(c=null==(l=t)?u:null,n):c?null:l},n.nodeSize=function(t){return arguments.length?(c=null==(l=t)?null:u,n):c?l:null},ii(n,o)},ao.layout.cluster=function(){function n(n,u){var o,a=t.call(this,n,u),l=a[0],c=0;oi(l,function(n){var t=n.children;t&&t.length?(n.x=ji(t),n.y=Ui(t)):(n.x=o?c+=e(n,o):0,n.y=0,o=n)});var f=Fi(l),s=Hi(l),h=f.x-e(f,s)/2,p=s.x+e(s,f)/2;return oi(l,i?function(n){n.x=(n.x-l.x)*r[0],n.y=(l.y-n.y)*r[1]}:function(n){n.x=(n.x-h)/(p-h)*r[0],n.y=(1-(l.y?n.y/l.y:1))*r[1]}),a}var t=ao.layout.hierarchy().sort(null).value(null),e=Li,r=[1,1],i=!1;return n.separation=function(t){return arguments.length?(e=t,n):e},n.size=function(t){return arguments.length?(i=null==(r=t),n):i?null:r},n.nodeSize=function(t){return arguments.length?(i=null!=(r=t),n):i?r:null},ii(n,t)},ao.layout.treemap=function(){function n(n,t){for(var e,r,i=-1,u=n.length;++it?0:t),e.area=isNaN(r)||0>=r?0:r}function t(e){var u=e.children;if(u&&u.length){var o,a,l,c=s(e),f=[],h=u.slice(),g=1/0,v="slice"===p?c.dx:"dice"===p?c.dy:"slice-dice"===p?1&e.depth?c.dy:c.dx:Math.min(c.dx,c.dy);for(n(h,c.dx*c.dy/e.value),f.area=0;(l=h.length)>0;)f.push(o=h[l-1]),f.area+=o.area,"squarify"!==p||(a=r(f,v))<=g?(h.pop(),g=a):(f.area-=f.pop().area,i(f,v,c,!1),v=Math.min(c.dx,c.dy),f.length=f.area=0,g=1/0);f.length&&(i(f,v,c,!0),f.length=f.area=0),u.forEach(t)}}function e(t){var r=t.children;if(r&&r.length){var u,o=s(t),a=r.slice(),l=[];for(n(a,o.dx*o.dy/t.value),l.area=0;u=a.pop();)l.push(u),l.area+=u.area,null!=u.z&&(i(l,u.z?o.dx:o.dy,o,!a.length),l.length=l.area=0);r.forEach(e)}}function r(n,t){for(var e,r=n.area,i=0,u=1/0,o=-1,a=n.length;++oe&&(u=e),e>i&&(i=e));return r*=r,t*=t,r?Math.max(t*i*g/r,r/(t*u*g)):1/0}function i(n,t,e,r){var i,u=-1,o=n.length,a=e.x,c=e.y,f=t?l(n.area/t):0; -if(t==e.dx){for((r||f>e.dy)&&(f=e.dy);++ue.dx)&&(f=e.dx);++ue&&(t=1),1>e&&(n=0),function(){var e,r,i;do e=2*Math.random()-1,r=2*Math.random()-1,i=e*e+r*r;while(!i||i>1);return n+t*e*Math.sqrt(-2*Math.log(i)/i)}},logNormal:function(){var n=ao.random.normal.apply(ao,arguments);return function(){return Math.exp(n())}},bates:function(n){var t=ao.random.irwinHall(n);return function(){return t()/n}},irwinHall:function(n){return function(){for(var t=0,e=0;n>e;e++)t+=Math.random();return t}}},ao.scale={};var Sl={floor:m,ceil:m};ao.scale.linear=function(){return Wi([0,1],[0,1],Mr,!1)};var kl={s:1,g:1,p:1,r:1,e:1};ao.scale.log=function(){return ru(ao.scale.linear().domain([0,1]),10,!0,[1,10])};var Nl=ao.format(".0e"),El={floor:function(n){return-Math.ceil(-n)},ceil:function(n){return-Math.floor(-n)}};ao.scale.pow=function(){return iu(ao.scale.linear(),1,[0,1])},ao.scale.sqrt=function(){return ao.scale.pow().exponent(.5)},ao.scale.ordinal=function(){return ou([],{t:"range",a:[[]]})},ao.scale.category10=function(){return ao.scale.ordinal().range(Al)},ao.scale.category20=function(){return ao.scale.ordinal().range(Cl)},ao.scale.category20b=function(){return ao.scale.ordinal().range(zl)},ao.scale.category20c=function(){return ao.scale.ordinal().range(Ll)};var Al=[2062260,16744206,2924588,14034728,9725885,9197131,14907330,8355711,12369186,1556175].map(xn),Cl=[2062260,11454440,16744206,16759672,2924588,10018698,14034728,16750742,9725885,12955861,9197131,12885140,14907330,16234194,8355711,13092807,12369186,14408589,1556175,10410725].map(xn),zl=[3750777,5395619,7040719,10264286,6519097,9216594,11915115,13556636,9202993,12426809,15186514,15190932,8666169,11356490,14049643,15177372,8077683,10834324,13528509,14589654].map(xn),Ll=[3244733,7057110,10406625,13032431,15095053,16616764,16625259,16634018,3253076,7652470,10607003,13101504,7695281,10394312,12369372,14342891,6513507,9868950,12434877,14277081].map(xn);ao.scale.quantile=function(){return au([],[])},ao.scale.quantize=function(){return lu(0,1,[0,1])},ao.scale.threshold=function(){return cu([.5],[0,1])},ao.scale.identity=function(){return fu([0,1])},ao.svg={},ao.svg.arc=function(){function n(){var n=Math.max(0,+e.apply(this,arguments)),c=Math.max(0,+r.apply(this,arguments)),f=o.apply(this,arguments)-Io,s=a.apply(this,arguments)-Io,h=Math.abs(s-f),p=f>s?0:1;if(n>c&&(g=c,c=n,n=g),h>=Oo)return t(c,p)+(n?t(n,1-p):"")+"Z";var g,v,d,y,m,M,x,b,_,w,S,k,N=0,E=0,A=[];if((y=(+l.apply(this,arguments)||0)/2)&&(d=u===ql?Math.sqrt(n*n+c*c):+u.apply(this,arguments),p||(E*=-1),c&&(E=tn(d/c*Math.sin(y))),n&&(N=tn(d/n*Math.sin(y)))),c){m=c*Math.cos(f+E),M=c*Math.sin(f+E),x=c*Math.cos(s-E),b=c*Math.sin(s-E);var C=Math.abs(s-f-2*E)<=Fo?0:1;if(E&&yu(m,M,x,b)===p^C){var z=(f+s)/2;m=c*Math.cos(z),M=c*Math.sin(z),x=b=null}}else m=M=0;if(n){_=n*Math.cos(s-N),w=n*Math.sin(s-N),S=n*Math.cos(f+N),k=n*Math.sin(f+N);var L=Math.abs(f-s+2*N)<=Fo?0:1;if(N&&yu(_,w,S,k)===1-p^L){var q=(f+s)/2;_=n*Math.cos(q),w=n*Math.sin(q),S=k=null}}else _=w=0;if(h>Uo&&(g=Math.min(Math.abs(c-n)/2,+i.apply(this,arguments)))>.001){v=c>n^p?0:1;var T=g,R=g;if(Fo>h){var D=null==S?[_,w]:null==x?[m,M]:Re([m,M],[S,k],[x,b],[_,w]),P=m-D[0],U=M-D[1],j=x-D[0],F=b-D[1],H=1/Math.sin(Math.acos((P*j+U*F)/(Math.sqrt(P*P+U*U)*Math.sqrt(j*j+F*F)))/2),O=Math.sqrt(D[0]*D[0]+D[1]*D[1]);R=Math.min(g,(n-O)/(H-1)),T=Math.min(g,(c-O)/(H+1))}if(null!=x){var I=mu(null==S?[_,w]:[S,k],[m,M],c,T,p),Y=mu([x,b],[_,w],c,T,p);g===T?A.push("M",I[0],"A",T,",",T," 0 0,",v," ",I[1],"A",c,",",c," 0 ",1-p^yu(I[1][0],I[1][1],Y[1][0],Y[1][1]),",",p," ",Y[1],"A",T,",",T," 0 0,",v," ",Y[0]):A.push("M",I[0],"A",T,",",T," 0 1,",v," ",Y[0])}else A.push("M",m,",",M);if(null!=S){var Z=mu([m,M],[S,k],n,-R,p),V=mu([_,w],null==x?[m,M]:[x,b],n,-R,p);g===R?A.push("L",V[0],"A",R,",",R," 0 0,",v," ",V[1],"A",n,",",n," 0 ",p^yu(V[1][0],V[1][1],Z[1][0],Z[1][1]),",",1-p," ",Z[1],"A",R,",",R," 0 0,",v," ",Z[0]):A.push("L",V[0],"A",R,",",R," 0 0,",v," ",Z[0])}else A.push("L",_,",",w)}else A.push("M",m,",",M),null!=x&&A.push("A",c,",",c," 0 ",C,",",p," ",x,",",b),A.push("L",_,",",w),null!=S&&A.push("A",n,",",n," 0 ",L,",",1-p," ",S,",",k);return A.push("Z"),A.join("")}function t(n,t){return"M0,"+n+"A"+n+","+n+" 0 1,"+t+" 0,"+-n+"A"+n+","+n+" 0 1,"+t+" 0,"+n}var e=hu,r=pu,i=su,u=ql,o=gu,a=vu,l=du;return n.innerRadius=function(t){return arguments.length?(e=En(t),n):e},n.outerRadius=function(t){return arguments.length?(r=En(t),n):r},n.cornerRadius=function(t){return arguments.length?(i=En(t),n):i},n.padRadius=function(t){return arguments.length?(u=t==ql?ql:En(t),n):u},n.startAngle=function(t){return arguments.length?(o=En(t),n):o},n.endAngle=function(t){return arguments.length?(a=En(t),n):a},n.padAngle=function(t){return arguments.length?(l=En(t),n):l},n.centroid=function(){var n=(+e.apply(this,arguments)+ +r.apply(this,arguments))/2,t=(+o.apply(this,arguments)+ +a.apply(this,arguments))/2-Io;return[Math.cos(t)*n,Math.sin(t)*n]},n};var ql="auto";ao.svg.line=function(){return Mu(m)};var Tl=ao.map({linear:xu,"linear-closed":bu,step:_u,"step-before":wu,"step-after":Su,basis:zu,"basis-open":Lu,"basis-closed":qu,bundle:Tu,cardinal:Eu,"cardinal-open":ku,"cardinal-closed":Nu,monotone:Fu});Tl.forEach(function(n,t){t.key=n,t.closed=/-closed$/.test(n)});var Rl=[0,2/3,1/3,0],Dl=[0,1/3,2/3,0],Pl=[0,1/6,2/3,1/6];ao.svg.line.radial=function(){var n=Mu(Hu);return n.radius=n.x,delete n.x,n.angle=n.y,delete n.y,n},wu.reverse=Su,Su.reverse=wu,ao.svg.area=function(){return Ou(m)},ao.svg.area.radial=function(){var n=Ou(Hu);return n.radius=n.x,delete n.x,n.innerRadius=n.x0,delete n.x0,n.outerRadius=n.x1,delete n.x1,n.angle=n.y,delete n.y,n.startAngle=n.y0,delete n.y0,n.endAngle=n.y1,delete n.y1,n},ao.svg.chord=function(){function n(n,a){var l=t(this,u,n,a),c=t(this,o,n,a);return"M"+l.p0+r(l.r,l.p1,l.a1-l.a0)+(e(l,c)?i(l.r,l.p1,l.r,l.p0):i(l.r,l.p1,c.r,c.p0)+r(c.r,c.p1,c.a1-c.a0)+i(c.r,c.p1,l.r,l.p0))+"Z"}function t(n,t,e,r){var i=t.call(n,e,r),u=a.call(n,i,r),o=l.call(n,i,r)-Io,f=c.call(n,i,r)-Io;return{r:u,a0:o,a1:f,p0:[u*Math.cos(o),u*Math.sin(o)],p1:[u*Math.cos(f),u*Math.sin(f)]}}function e(n,t){return n.a0==t.a0&&n.a1==t.a1}function r(n,t,e){return"A"+n+","+n+" 0 "+ +(e>Fo)+",1 "+t}function i(n,t,e,r){return"Q 0,0 "+r}var u=Me,o=xe,a=Iu,l=gu,c=vu;return n.radius=function(t){return arguments.length?(a=En(t),n):a},n.source=function(t){return arguments.length?(u=En(t),n):u},n.target=function(t){return arguments.length?(o=En(t),n):o},n.startAngle=function(t){return arguments.length?(l=En(t),n):l},n.endAngle=function(t){return arguments.length?(c=En(t),n):c},n},ao.svg.diagonal=function(){function n(n,i){var u=t.call(this,n,i),o=e.call(this,n,i),a=(u.y+o.y)/2,l=[u,{x:u.x,y:a},{x:o.x,y:a},o];return l=l.map(r),"M"+l[0]+"C"+l[1]+" "+l[2]+" "+l[3]}var t=Me,e=xe,r=Yu;return n.source=function(e){return arguments.length?(t=En(e),n):t},n.target=function(t){return arguments.length?(e=En(t),n):e},n.projection=function(t){return arguments.length?(r=t,n):r},n},ao.svg.diagonal.radial=function(){var n=ao.svg.diagonal(),t=Yu,e=n.projection;return n.projection=function(n){return arguments.length?e(Zu(t=n)):t},n},ao.svg.symbol=function(){function n(n,r){return(Ul.get(t.call(this,n,r))||$u)(e.call(this,n,r))}var t=Xu,e=Vu;return n.type=function(e){return arguments.length?(t=En(e),n):t},n.size=function(t){return arguments.length?(e=En(t),n):e},n};var Ul=ao.map({circle:$u,cross:function(n){var t=Math.sqrt(n/5)/2;return"M"+-3*t+","+-t+"H"+-t+"V"+-3*t+"H"+t+"V"+-t+"H"+3*t+"V"+t+"H"+t+"V"+3*t+"H"+-t+"V"+t+"H"+-3*t+"Z"},diamond:function(n){var t=Math.sqrt(n/(2*Fl)),e=t*Fl;return"M0,"+-t+"L"+e+",0 0,"+t+" "+-e+",0Z"},square:function(n){var t=Math.sqrt(n)/2;return"M"+-t+","+-t+"L"+t+","+-t+" "+t+","+t+" "+-t+","+t+"Z"},"triangle-down":function(n){var t=Math.sqrt(n/jl),e=t*jl/2;return"M0,"+e+"L"+t+","+-e+" "+-t+","+-e+"Z"},"triangle-up":function(n){var t=Math.sqrt(n/jl),e=t*jl/2;return"M0,"+-e+"L"+t+","+e+" "+-t+","+e+"Z"}});ao.svg.symbolTypes=Ul.keys();var jl=Math.sqrt(3),Fl=Math.tan(30*Yo);Co.transition=function(n){for(var t,e,r=Hl||++Zl,i=Ku(n),u=[],o=Ol||{time:Date.now(),ease:Nr,delay:0,duration:250},a=-1,l=this.length;++au;u++){i.push(t=[]);for(var e=this[u],a=0,l=e.length;l>a;a++)(r=e[a])&&n.call(r,r.__data__,a,u)&&t.push(r)}return Wu(i,this.namespace,this.id)},Yl.tween=function(n,t){var e=this.id,r=this.namespace;return arguments.length<2?this.node()[r][e].tween.get(n):Y(this,null==t?function(t){t[r][e].tween.remove(n)}:function(i){i[r][e].tween.set(n,t)})},Yl.attr=function(n,t){function e(){this.removeAttribute(a)}function r(){this.removeAttributeNS(a.space,a.local)}function i(n){return null==n?e:(n+="",function(){var t,e=this.getAttribute(a);return e!==n&&(t=o(e,n),function(n){this.setAttribute(a,t(n))})})}function u(n){return null==n?r:(n+="",function(){var t,e=this.getAttributeNS(a.space,a.local);return e!==n&&(t=o(e,n),function(n){this.setAttributeNS(a.space,a.local,t(n))})})}if(arguments.length<2){for(t in n)this.attr(t,n[t]);return this}var o="transform"==n?$r:Mr,a=ao.ns.qualify(n);return Ju(this,"attr."+n,t,a.local?u:i)},Yl.attrTween=function(n,t){function e(n,e){var r=t.call(this,n,e,this.getAttribute(i));return r&&function(n){this.setAttribute(i,r(n))}}function r(n,e){var r=t.call(this,n,e,this.getAttributeNS(i.space,i.local));return r&&function(n){this.setAttributeNS(i.space,i.local,r(n))}}var i=ao.ns.qualify(n);return this.tween("attr."+n,i.local?r:e)},Yl.style=function(n,e,r){function i(){this.style.removeProperty(n)}function u(e){return null==e?i:(e+="",function(){var i,u=t(this).getComputedStyle(this,null).getPropertyValue(n);return u!==e&&(i=Mr(u,e),function(t){this.style.setProperty(n,i(t),r)})})}var o=arguments.length;if(3>o){if("string"!=typeof n){2>o&&(e="");for(r in n)this.style(r,n[r],e);return this}r=""}return Ju(this,"style."+n,e,u)},Yl.styleTween=function(n,e,r){function i(i,u){var o=e.call(this,i,u,t(this).getComputedStyle(this,null).getPropertyValue(n));return o&&function(t){this.style.setProperty(n,o(t),r)}}return arguments.length<3&&(r=""),this.tween("style."+n,i)},Yl.text=function(n){return Ju(this,"text",n,Gu)},Yl.remove=function(){var n=this.namespace;return this.each("end.transition",function(){var t;this[n].count<2&&(t=this.parentNode)&&t.removeChild(this)})},Yl.ease=function(n){var t=this.id,e=this.namespace;return arguments.length<1?this.node()[e][t].ease:("function"!=typeof n&&(n=ao.ease.apply(ao,arguments)),Y(this,function(r){r[e][t].ease=n}))},Yl.delay=function(n){var t=this.id,e=this.namespace;return arguments.length<1?this.node()[e][t].delay:Y(this,"function"==typeof n?function(r,i,u){r[e][t].delay=+n.call(r,r.__data__,i,u)}:(n=+n,function(r){r[e][t].delay=n}))},Yl.duration=function(n){var t=this.id,e=this.namespace;return arguments.length<1?this.node()[e][t].duration:Y(this,"function"==typeof n?function(r,i,u){r[e][t].duration=Math.max(1,n.call(r,r.__data__,i,u))}:(n=Math.max(1,n),function(r){r[e][t].duration=n}))},Yl.each=function(n,t){var e=this.id,r=this.namespace;if(arguments.length<2){var i=Ol,u=Hl;try{Hl=e,Y(this,function(t,i,u){Ol=t[r][e],n.call(t,t.__data__,i,u)})}finally{Ol=i,Hl=u}}else Y(this,function(i){var u=i[r][e];(u.event||(u.event=ao.dispatch("start","end","interrupt"))).on(n,t)});return this},Yl.transition=function(){for(var n,t,e,r,i=this.id,u=++Zl,o=this.namespace,a=[],l=0,c=this.length;c>l;l++){a.push(n=[]);for(var t=this[l],f=0,s=t.length;s>f;f++)(e=t[f])&&(r=e[o][i],Qu(e,f,o,u,{time:r.time,ease:r.ease,delay:r.delay+r.duration,duration:r.duration})),n.push(e)}return Wu(a,o,u)},ao.svg.axis=function(){function n(n){n.each(function(){var n,c=ao.select(this),f=this.__chart__||e,s=this.__chart__=e.copy(),h=null==l?s.ticks?s.ticks.apply(s,a):s.domain():l,p=null==t?s.tickFormat?s.tickFormat.apply(s,a):m:t,g=c.selectAll(".tick").data(h,s),v=g.enter().insert("g",".domain").attr("class","tick").style("opacity",Uo),d=ao.transition(g.exit()).style("opacity",Uo).remove(),y=ao.transition(g.order()).style("opacity",1),M=Math.max(i,0)+o,x=Zi(s),b=c.selectAll(".domain").data([0]),_=(b.enter().append("path").attr("class","domain"),ao.transition(b));v.append("line"),v.append("text");var w,S,k,N,E=v.select("line"),A=y.select("line"),C=g.select("text").text(p),z=v.select("text"),L=y.select("text"),q="top"===r||"left"===r?-1:1;if("bottom"===r||"top"===r?(n=no,w="x",k="y",S="x2",N="y2",C.attr("dy",0>q?"0em":".71em").style("text-anchor","middle"),_.attr("d","M"+x[0]+","+q*u+"V0H"+x[1]+"V"+q*u)):(n=to,w="y",k="x",S="y2",N="x2",C.attr("dy",".32em").style("text-anchor",0>q?"end":"start"),_.attr("d","M"+q*u+","+x[0]+"H0V"+x[1]+"H"+q*u)),E.attr(N,q*i),z.attr(k,q*M),A.attr(S,0).attr(N,q*i),L.attr(w,0).attr(k,q*M),s.rangeBand){var T=s,R=T.rangeBand()/2;f=s=function(n){return T(n)+R}}else f.rangeBand?f=s:d.call(n,s,f);v.call(n,f,s),y.call(n,s,s)})}var t,e=ao.scale.linear(),r=Vl,i=6,u=6,o=3,a=[10],l=null;return n.scale=function(t){return arguments.length?(e=t,n):e},n.orient=function(t){return arguments.length?(r=t in Xl?t+"":Vl,n):r},n.ticks=function(){return arguments.length?(a=co(arguments),n):a},n.tickValues=function(t){return arguments.length?(l=t,n):l},n.tickFormat=function(e){return arguments.length?(t=e,n):t},n.tickSize=function(t){var e=arguments.length;return e?(i=+t,u=+arguments[e-1],n):i},n.innerTickSize=function(t){return arguments.length?(i=+t,n):i},n.outerTickSize=function(t){return arguments.length?(u=+t,n):u},n.tickPadding=function(t){return arguments.length?(o=+t,n):o},n.tickSubdivide=function(){return arguments.length&&n},n};var Vl="bottom",Xl={top:1,right:1,bottom:1,left:1};ao.svg.brush=function(){function n(t){t.each(function(){var t=ao.select(this).style("pointer-events","all").style("-webkit-tap-highlight-color","rgba(0,0,0,0)").on("mousedown.brush",u).on("touchstart.brush",u),o=t.selectAll(".background").data([0]);o.enter().append("rect").attr("class","background").style("visibility","hidden").style("cursor","crosshair"),t.selectAll(".extent").data([0]).enter().append("rect").attr("class","extent").style("cursor","move");var a=t.selectAll(".resize").data(v,m);a.exit().remove(),a.enter().append("g").attr("class",function(n){return"resize "+n}).style("cursor",function(n){return $l[n]}).append("rect").attr("x",function(n){return/[ew]$/.test(n)?-3:null}).attr("y",function(n){return/^[ns]/.test(n)?-3:null}).attr("width",6).attr("height",6).style("visibility","hidden"),a.style("display",n.empty()?"none":null);var l,s=ao.transition(t),h=ao.transition(o);c&&(l=Zi(c),h.attr("x",l[0]).attr("width",l[1]-l[0]),r(s)),f&&(l=Zi(f),h.attr("y",l[0]).attr("height",l[1]-l[0]),i(s)),e(s)})}function e(n){n.selectAll(".resize").attr("transform",function(n){return"translate("+s[+/e$/.test(n)]+","+h[+/^s/.test(n)]+")"})}function r(n){n.select(".extent").attr("x",s[0]),n.selectAll(".extent,.n>rect,.s>rect").attr("width",s[1]-s[0])}function i(n){n.select(".extent").attr("y",h[0]),n.selectAll(".extent,.e>rect,.w>rect").attr("height",h[1]-h[0])}function u(){function u(){32==ao.event.keyCode&&(C||(M=null,L[0]-=s[1],L[1]-=h[1],C=2),S())}function v(){32==ao.event.keyCode&&2==C&&(L[0]+=s[1],L[1]+=h[1],C=0,S())}function d(){var n=ao.mouse(b),t=!1;x&&(n[0]+=x[0],n[1]+=x[1]),C||(ao.event.altKey?(M||(M=[(s[0]+s[1])/2,(h[0]+h[1])/2]),L[0]=s[+(n[0]f?(i=r,r=f):i=f),v[0]!=r||v[1]!=i?(e?a=null:o=null,v[0]=r,v[1]=i,!0):void 0}function m(){d(),k.style("pointer-events","all").selectAll(".resize").style("display",n.empty()?"none":null),ao.select("body").style("cursor",null),q.on("mousemove.brush",null).on("mouseup.brush",null).on("touchmove.brush",null).on("touchend.brush",null).on("keydown.brush",null).on("keyup.brush",null),z(),w({type:"brushend"})}var M,x,b=this,_=ao.select(ao.event.target),w=l.of(b,arguments),k=ao.select(b),N=_.datum(),E=!/^(n|s)$/.test(N)&&c,A=!/^(e|w)$/.test(N)&&f,C=_.classed("extent"),z=W(b),L=ao.mouse(b),q=ao.select(t(b)).on("keydown.brush",u).on("keyup.brush",v);if(ao.event.changedTouches?q.on("touchmove.brush",d).on("touchend.brush",m):q.on("mousemove.brush",d).on("mouseup.brush",m),k.interrupt().selectAll("*").interrupt(),C)L[0]=s[0]-L[0],L[1]=h[0]-L[1];else if(N){var T=+/w$/.test(N),R=+/^n/.test(N);x=[s[1-T]-L[0],h[1-R]-L[1]],L[0]=s[T],L[1]=h[R]}else ao.event.altKey&&(M=L.slice());k.style("pointer-events","none").selectAll(".resize").style("display",null),ao.select("body").style("cursor",_.style("cursor")),w({type:"brushstart"}),d()}var o,a,l=N(n,"brushstart","brush","brushend"),c=null,f=null,s=[0,0],h=[0,0],p=!0,g=!0,v=Bl[0];return n.event=function(n){n.each(function(){var n=l.of(this,arguments),t={x:s,y:h,i:o,j:a},e=this.__chart__||t;this.__chart__=t,Hl?ao.select(this).transition().each("start.brush",function(){o=e.i,a=e.j,s=e.x,h=e.y,n({type:"brushstart"})}).tween("brush:brush",function(){var e=xr(s,t.x),r=xr(h,t.y);return o=a=null,function(i){s=t.x=e(i),h=t.y=r(i),n({type:"brush",mode:"resize"})}}).each("end.brush",function(){o=t.i,a=t.j,n({type:"brush",mode:"resize"}),n({type:"brushend"})}):(n({type:"brushstart"}),n({type:"brush",mode:"resize"}),n({type:"brushend"}))})},n.x=function(t){return arguments.length?(c=t,v=Bl[!c<<1|!f],n):c},n.y=function(t){return arguments.length?(f=t,v=Bl[!c<<1|!f],n):f},n.clamp=function(t){return arguments.length?(c&&f?(p=!!t[0],g=!!t[1]):c?p=!!t:f&&(g=!!t),n):c&&f?[p,g]:c?p:f?g:null},n.extent=function(t){var e,r,i,u,l;return arguments.length?(c&&(e=t[0],r=t[1],f&&(e=e[0],r=r[0]),o=[e,r],c.invert&&(e=c(e),r=c(r)),e>r&&(l=e,e=r,r=l),e==s[0]&&r==s[1]||(s=[e,r])),f&&(i=t[0],u=t[1],c&&(i=i[1],u=u[1]),a=[i,u],f.invert&&(i=f(i),u=f(u)),i>u&&(l=i,i=u,u=l),i==h[0]&&u==h[1]||(h=[i,u])),n):(c&&(o?(e=o[0],r=o[1]):(e=s[0],r=s[1],c.invert&&(e=c.invert(e),r=c.invert(r)),e>r&&(l=e,e=r,r=l))),f&&(a?(i=a[0],u=a[1]):(i=h[0],u=h[1],f.invert&&(i=f.invert(i),u=f.invert(u)),i>u&&(l=i,i=u,u=l))),c&&f?[[e,i],[r,u]]:c?[e,r]:f&&[i,u])},n.clear=function(){return n.empty()||(s=[0,0],h=[0,0],o=a=null),n},n.empty=function(){return!!c&&s[0]==s[1]||!!f&&h[0]==h[1]},ao.rebind(n,l,"on")};var $l={n:"ns-resize",e:"ew-resize",s:"ns-resize",w:"ew-resize",nw:"nwse-resize",ne:"nesw-resize",se:"nwse-resize",sw:"nesw-resize"},Bl=[["n","e","s","w","nw","ne","se","sw"],["e","w"],["n","s"],[]],Wl=ga.format=xa.timeFormat,Jl=Wl.utc,Gl=Jl("%Y-%m-%dT%H:%M:%S.%LZ");Wl.iso=Date.prototype.toISOString&&+new Date("2000-01-01T00:00:00.000Z")?eo:Gl,eo.parse=function(n){var t=new Date(n);return isNaN(t)?null:t},eo.toString=Gl.toString,ga.second=On(function(n){return new va(1e3*Math.floor(n/1e3))},function(n,t){n.setTime(n.getTime()+1e3*Math.floor(t))},function(n){return n.getSeconds()}),ga.seconds=ga.second.range,ga.seconds.utc=ga.second.utc.range,ga.minute=On(function(n){return new va(6e4*Math.floor(n/6e4))},function(n,t){n.setTime(n.getTime()+6e4*Math.floor(t))},function(n){return n.getMinutes()}),ga.minutes=ga.minute.range,ga.minutes.utc=ga.minute.utc.range,ga.hour=On(function(n){var t=n.getTimezoneOffset()/60;return new va(36e5*(Math.floor(n/36e5-t)+t))},function(n,t){n.setTime(n.getTime()+36e5*Math.floor(t))},function(n){return n.getHours()}),ga.hours=ga.hour.range,ga.hours.utc=ga.hour.utc.range,ga.month=On(function(n){return n=ga.day(n),n.setDate(1),n},function(n,t){n.setMonth(n.getMonth()+t)},function(n){return n.getMonth()}),ga.months=ga.month.range,ga.months.utc=ga.month.utc.range;var Kl=[1e3,5e3,15e3,3e4,6e4,3e5,9e5,18e5,36e5,108e5,216e5,432e5,864e5,1728e5,6048e5,2592e6,7776e6,31536e6],Ql=[[ga.second,1],[ga.second,5],[ga.second,15],[ga.second,30],[ga.minute,1],[ga.minute,5],[ga.minute,15],[ga.minute,30],[ga.hour,1],[ga.hour,3],[ga.hour,6],[ga.hour,12],[ga.day,1],[ga.day,2],[ga.week,1],[ga.month,1],[ga.month,3],[ga.year,1]],nc=Wl.multi([[".%L",function(n){return n.getMilliseconds()}],[":%S",function(n){return n.getSeconds()}],["%I:%M",function(n){return n.getMinutes()}],["%I %p",function(n){return n.getHours()}],["%a %d",function(n){return n.getDay()&&1!=n.getDate()}],["%b %d",function(n){return 1!=n.getDate()}],["%B",function(n){return n.getMonth()}],["%Y",zt]]),tc={range:function(n,t,e){return ao.range(Math.ceil(n/e)*e,+t,e).map(io)},floor:m,ceil:m};Ql.year=ga.year,ga.scale=function(){return ro(ao.scale.linear(),Ql,nc)};var ec=Ql.map(function(n){return[n[0].utc,n[1]]}),rc=Jl.multi([[".%L",function(n){return n.getUTCMilliseconds()}],[":%S",function(n){return n.getUTCSeconds()}],["%I:%M",function(n){return n.getUTCMinutes()}],["%I %p",function(n){return n.getUTCHours()}],["%a %d",function(n){return n.getUTCDay()&&1!=n.getUTCDate()}],["%b %d",function(n){return 1!=n.getUTCDate()}],["%B",function(n){return n.getUTCMonth()}],["%Y",zt]]);ec.year=ga.year.utc,ga.scale.utc=function(){return ro(ao.scale.linear(),ec,rc)},ao.text=An(function(n){return n.responseText}),ao.json=function(n,t){return Cn(n,"application/json",uo,t)},ao.html=function(n,t){return Cn(n,"text/html",oo,t)},ao.xml=An(function(n){return n.responseXML}),"function"==typeof define&&define.amd?(this.d3=ao,define(ao)):"object"==typeof module&&module.exports?module.exports=ao:this.d3=ao}(); \ No newline at end of file diff --git a/backend/coverage-report-with-models/_js/file.js b/backend/coverage-report-with-models/_js/file.js deleted file mode 100644 index 124a8a18..00000000 --- a/backend/coverage-report-with-models/_js/file.js +++ /dev/null @@ -1,53 +0,0 @@ -$(function () { - var $window = $(window) - , $top_link = $('#toplink') - , $body = $('body, html') - , offset = $('#code').offset().top; - - $top_link.hide().click(function (event) { - event.preventDefault(); - $body.animate({scrollTop: 0}, 800); - }); - - $window.scroll(function () { - if ($window.scrollTop() > offset) { - $top_link.fadeIn(); - } else { - $top_link.fadeOut(); - } - }); - - var $popovers = $('.popin > :first-child'); - $('.popin').on({ - 'click.popover': function (event) { - event.stopPropagation(); - - var $container = $(this).children().first(); - - //Close all other popovers: - $popovers.each(function () { - var $current = $(this); - if (!$current.is($container)) { - $current.popover('hide'); - } - }); - - // Toggle this popover: - $container.popover('toggle'); - }, - }); - - //Hide all popovers on outside click: - $(document).click(function (event) { - if ($(event.target).closest($('.popover')).length === 0) { - $popovers.popover('hide'); - } - }); - - //Hide all popovers on escape: - $(document).keyup(function (event) { - if (event.key === 'Escape') { - $popovers.popover('hide'); - } - }); -}); diff --git a/backend/coverage-report-with-models/_js/jquery.min.js b/backend/coverage-report-with-models/_js/jquery.min.js deleted file mode 100644 index 798cc8bf..00000000 --- a/backend/coverage-report-with-models/_js/jquery.min.js +++ /dev/null @@ -1,2 +0,0 @@ -/*! jQuery v3.7.1 | (c) OpenJS Foundation and other contributors | jquery.org/license */ -!function(e,t){"use strict";"object"==typeof module&&"object"==typeof module.exports?module.exports=e.document?t(e,!0):function(e){if(!e.document)throw new Error("jQuery requires a window with a document");return t(e)}:t(e)}("undefined"!=typeof window?window:this,function(ie,e){"use strict";var oe=[],r=Object.getPrototypeOf,ae=oe.slice,g=oe.flat?function(e){return oe.flat.call(e)}:function(e){return oe.concat.apply([],e)},s=oe.push,se=oe.indexOf,n={},i=n.toString,ue=n.hasOwnProperty,o=ue.toString,a=o.call(Object),le={},v=function(e){return"function"==typeof e&&"number"!=typeof e.nodeType&&"function"!=typeof e.item},y=function(e){return null!=e&&e===e.window},C=ie.document,u={type:!0,src:!0,nonce:!0,noModule:!0};function m(e,t,n){var r,i,o=(n=n||C).createElement("script");if(o.text=e,t)for(r in u)(i=t[r]||t.getAttribute&&t.getAttribute(r))&&o.setAttribute(r,i);n.head.appendChild(o).parentNode.removeChild(o)}function x(e){return null==e?e+"":"object"==typeof e||"function"==typeof e?n[i.call(e)]||"object":typeof e}var t="3.7.1",l=/HTML$/i,ce=function(e,t){return new ce.fn.init(e,t)};function c(e){var t=!!e&&"length"in e&&e.length,n=x(e);return!v(e)&&!y(e)&&("array"===n||0===t||"number"==typeof t&&0+~]|"+ge+")"+ge+"*"),x=new RegExp(ge+"|>"),j=new RegExp(g),A=new RegExp("^"+t+"$"),D={ID:new RegExp("^#("+t+")"),CLASS:new RegExp("^\\.("+t+")"),TAG:new RegExp("^("+t+"|[*])"),ATTR:new RegExp("^"+p),PSEUDO:new RegExp("^"+g),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+ge+"*(even|odd|(([+-]|)(\\d*)n|)"+ge+"*(?:([+-]|)"+ge+"*(\\d+)|))"+ge+"*\\)|)","i"),bool:new RegExp("^(?:"+f+")$","i"),needsContext:new RegExp("^"+ge+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+ge+"*((?:-\\d)?\\d*)"+ge+"*\\)|)(?=[^-]|$)","i")},N=/^(?:input|select|textarea|button)$/i,q=/^h\d$/i,L=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,H=/[+~]/,O=new RegExp("\\\\[\\da-fA-F]{1,6}"+ge+"?|\\\\([^\\r\\n\\f])","g"),P=function(e,t){var n="0x"+e.slice(1)-65536;return t||(n<0?String.fromCharCode(n+65536):String.fromCharCode(n>>10|55296,1023&n|56320))},M=function(){V()},R=J(function(e){return!0===e.disabled&&fe(e,"fieldset")},{dir:"parentNode",next:"legend"});try{k.apply(oe=ae.call(ye.childNodes),ye.childNodes),oe[ye.childNodes.length].nodeType}catch(e){k={apply:function(e,t){me.apply(e,ae.call(t))},call:function(e){me.apply(e,ae.call(arguments,1))}}}function I(t,e,n,r){var i,o,a,s,u,l,c,f=e&&e.ownerDocument,p=e?e.nodeType:9;if(n=n||[],"string"!=typeof t||!t||1!==p&&9!==p&&11!==p)return n;if(!r&&(V(e),e=e||T,C)){if(11!==p&&(u=L.exec(t)))if(i=u[1]){if(9===p){if(!(a=e.getElementById(i)))return n;if(a.id===i)return k.call(n,a),n}else if(f&&(a=f.getElementById(i))&&I.contains(e,a)&&a.id===i)return k.call(n,a),n}else{if(u[2])return k.apply(n,e.getElementsByTagName(t)),n;if((i=u[3])&&e.getElementsByClassName)return k.apply(n,e.getElementsByClassName(i)),n}if(!(h[t+" "]||d&&d.test(t))){if(c=t,f=e,1===p&&(x.test(t)||m.test(t))){(f=H.test(t)&&U(e.parentNode)||e)==e&&le.scope||((s=e.getAttribute("id"))?s=ce.escapeSelector(s):e.setAttribute("id",s=S)),o=(l=Y(t)).length;while(o--)l[o]=(s?"#"+s:":scope")+" "+Q(l[o]);c=l.join(",")}try{return k.apply(n,f.querySelectorAll(c)),n}catch(e){h(t,!0)}finally{s===S&&e.removeAttribute("id")}}}return re(t.replace(ve,"$1"),e,n,r)}function W(){var r=[];return function e(t,n){return r.push(t+" ")>b.cacheLength&&delete e[r.shift()],e[t+" "]=n}}function F(e){return e[S]=!0,e}function $(e){var t=T.createElement("fieldset");try{return!!e(t)}catch(e){return!1}finally{t.parentNode&&t.parentNode.removeChild(t),t=null}}function B(t){return function(e){return fe(e,"input")&&e.type===t}}function _(t){return function(e){return(fe(e,"input")||fe(e,"button"))&&e.type===t}}function z(t){return function(e){return"form"in e?e.parentNode&&!1===e.disabled?"label"in e?"label"in e.parentNode?e.parentNode.disabled===t:e.disabled===t:e.isDisabled===t||e.isDisabled!==!t&&R(e)===t:e.disabled===t:"label"in e&&e.disabled===t}}function X(a){return F(function(o){return o=+o,F(function(e,t){var n,r=a([],e.length,o),i=r.length;while(i--)e[n=r[i]]&&(e[n]=!(t[n]=e[n]))})})}function U(e){return e&&"undefined"!=typeof e.getElementsByTagName&&e}function V(e){var t,n=e?e.ownerDocument||e:ye;return n!=T&&9===n.nodeType&&n.documentElement&&(r=(T=n).documentElement,C=!ce.isXMLDoc(T),i=r.matches||r.webkitMatchesSelector||r.msMatchesSelector,r.msMatchesSelector&&ye!=T&&(t=T.defaultView)&&t.top!==t&&t.addEventListener("unload",M),le.getById=$(function(e){return r.appendChild(e).id=ce.expando,!T.getElementsByName||!T.getElementsByName(ce.expando).length}),le.disconnectedMatch=$(function(e){return i.call(e,"*")}),le.scope=$(function(){return T.querySelectorAll(":scope")}),le.cssHas=$(function(){try{return T.querySelector(":has(*,:jqfake)"),!1}catch(e){return!0}}),le.getById?(b.filter.ID=function(e){var t=e.replace(O,P);return function(e){return e.getAttribute("id")===t}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&C){var n=t.getElementById(e);return n?[n]:[]}}):(b.filter.ID=function(e){var n=e.replace(O,P);return function(e){var t="undefined"!=typeof e.getAttributeNode&&e.getAttributeNode("id");return t&&t.value===n}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&C){var n,r,i,o=t.getElementById(e);if(o){if((n=o.getAttributeNode("id"))&&n.value===e)return[o];i=t.getElementsByName(e),r=0;while(o=i[r++])if((n=o.getAttributeNode("id"))&&n.value===e)return[o]}return[]}}),b.find.TAG=function(e,t){return"undefined"!=typeof t.getElementsByTagName?t.getElementsByTagName(e):t.querySelectorAll(e)},b.find.CLASS=function(e,t){if("undefined"!=typeof t.getElementsByClassName&&C)return t.getElementsByClassName(e)},d=[],$(function(e){var t;r.appendChild(e).innerHTML="",e.querySelectorAll("[selected]").length||d.push("\\["+ge+"*(?:value|"+f+")"),e.querySelectorAll("[id~="+S+"-]").length||d.push("~="),e.querySelectorAll("a#"+S+"+*").length||d.push(".#.+[+~]"),e.querySelectorAll(":checked").length||d.push(":checked"),(t=T.createElement("input")).setAttribute("type","hidden"),e.appendChild(t).setAttribute("name","D"),r.appendChild(e).disabled=!0,2!==e.querySelectorAll(":disabled").length&&d.push(":enabled",":disabled"),(t=T.createElement("input")).setAttribute("name",""),e.appendChild(t),e.querySelectorAll("[name='']").length||d.push("\\["+ge+"*name"+ge+"*="+ge+"*(?:''|\"\")")}),le.cssHas||d.push(":has"),d=d.length&&new RegExp(d.join("|")),l=function(e,t){if(e===t)return a=!0,0;var n=!e.compareDocumentPosition-!t.compareDocumentPosition;return n||(1&(n=(e.ownerDocument||e)==(t.ownerDocument||t)?e.compareDocumentPosition(t):1)||!le.sortDetached&&t.compareDocumentPosition(e)===n?e===T||e.ownerDocument==ye&&I.contains(ye,e)?-1:t===T||t.ownerDocument==ye&&I.contains(ye,t)?1:o?se.call(o,e)-se.call(o,t):0:4&n?-1:1)}),T}for(e in I.matches=function(e,t){return I(e,null,null,t)},I.matchesSelector=function(e,t){if(V(e),C&&!h[t+" "]&&(!d||!d.test(t)))try{var n=i.call(e,t);if(n||le.disconnectedMatch||e.document&&11!==e.document.nodeType)return n}catch(e){h(t,!0)}return 0":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(O,P),e[3]=(e[3]||e[4]||e[5]||"").replace(O,P),"~="===e[2]&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),"nth"===e[1].slice(0,3)?(e[3]||I.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*("even"===e[3]||"odd"===e[3])),e[5]=+(e[7]+e[8]||"odd"===e[3])):e[3]&&I.error(e[0]),e},PSEUDO:function(e){var t,n=!e[6]&&e[2];return D.CHILD.test(e[0])?null:(e[3]?e[2]=e[4]||e[5]||"":n&&j.test(n)&&(t=Y(n,!0))&&(t=n.indexOf(")",n.length-t)-n.length)&&(e[0]=e[0].slice(0,t),e[2]=n.slice(0,t)),e.slice(0,3))}},filter:{TAG:function(e){var t=e.replace(O,P).toLowerCase();return"*"===e?function(){return!0}:function(e){return fe(e,t)}},CLASS:function(e){var t=s[e+" "];return t||(t=new RegExp("(^|"+ge+")"+e+"("+ge+"|$)"))&&s(e,function(e){return t.test("string"==typeof e.className&&e.className||"undefined"!=typeof e.getAttribute&&e.getAttribute("class")||"")})},ATTR:function(n,r,i){return function(e){var t=I.attr(e,n);return null==t?"!="===r:!r||(t+="","="===r?t===i:"!="===r?t!==i:"^="===r?i&&0===t.indexOf(i):"*="===r?i&&-1:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i;function T(e,n,r){return v(n)?ce.grep(e,function(e,t){return!!n.call(e,t,e)!==r}):n.nodeType?ce.grep(e,function(e){return e===n!==r}):"string"!=typeof n?ce.grep(e,function(e){return-1)[^>]*|#([\w-]+))$/;(ce.fn.init=function(e,t,n){var r,i;if(!e)return this;if(n=n||k,"string"==typeof e){if(!(r="<"===e[0]&&">"===e[e.length-1]&&3<=e.length?[null,e,null]:S.exec(e))||!r[1]&&t)return!t||t.jquery?(t||n).find(e):this.constructor(t).find(e);if(r[1]){if(t=t instanceof ce?t[0]:t,ce.merge(this,ce.parseHTML(r[1],t&&t.nodeType?t.ownerDocument||t:C,!0)),w.test(r[1])&&ce.isPlainObject(t))for(r in t)v(this[r])?this[r](t[r]):this.attr(r,t[r]);return this}return(i=C.getElementById(r[2]))&&(this[0]=i,this.length=1),this}return e.nodeType?(this[0]=e,this.length=1,this):v(e)?void 0!==n.ready?n.ready(e):e(ce):ce.makeArray(e,this)}).prototype=ce.fn,k=ce(C);var E=/^(?:parents|prev(?:Until|All))/,j={children:!0,contents:!0,next:!0,prev:!0};function A(e,t){while((e=e[t])&&1!==e.nodeType);return e}ce.fn.extend({has:function(e){var t=ce(e,this),n=t.length;return this.filter(function(){for(var e=0;e\x20\t\r\n\f]*)/i,Ce=/^$|^module$|\/(?:java|ecma)script/i;xe=C.createDocumentFragment().appendChild(C.createElement("div")),(be=C.createElement("input")).setAttribute("type","radio"),be.setAttribute("checked","checked"),be.setAttribute("name","t"),xe.appendChild(be),le.checkClone=xe.cloneNode(!0).cloneNode(!0).lastChild.checked,xe.innerHTML="",le.noCloneChecked=!!xe.cloneNode(!0).lastChild.defaultValue,xe.innerHTML="",le.option=!!xe.lastChild;var ke={thead:[1,"","
"],col:[2,"","
"],tr:[2,"","
"],td:[3,"","
"],_default:[0,"",""]};function Se(e,t){var n;return n="undefined"!=typeof e.getElementsByTagName?e.getElementsByTagName(t||"*"):"undefined"!=typeof e.querySelectorAll?e.querySelectorAll(t||"*"):[],void 0===t||t&&fe(e,t)?ce.merge([e],n):n}function Ee(e,t){for(var n=0,r=e.length;n",""]);var je=/<|&#?\w+;/;function Ae(e,t,n,r,i){for(var o,a,s,u,l,c,f=t.createDocumentFragment(),p=[],d=0,h=e.length;d\s*$/g;function Re(e,t){return fe(e,"table")&&fe(11!==t.nodeType?t:t.firstChild,"tr")&&ce(e).children("tbody")[0]||e}function Ie(e){return e.type=(null!==e.getAttribute("type"))+"/"+e.type,e}function We(e){return"true/"===(e.type||"").slice(0,5)?e.type=e.type.slice(5):e.removeAttribute("type"),e}function Fe(e,t){var n,r,i,o,a,s;if(1===t.nodeType){if(_.hasData(e)&&(s=_.get(e).events))for(i in _.remove(t,"handle events"),s)for(n=0,r=s[i].length;n").attr(n.scriptAttrs||{}).prop({charset:n.scriptCharset,src:n.url}).on("load error",i=function(e){r.remove(),i=null,e&&t("error"===e.type?404:200,e.type)}),C.head.appendChild(r[0])},abort:function(){i&&i()}}});var Jt,Kt=[],Zt=/(=)\?(?=&|$)|\?\?/;ce.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var e=Kt.pop()||ce.expando+"_"+jt.guid++;return this[e]=!0,e}}),ce.ajaxPrefilter("json jsonp",function(e,t,n){var r,i,o,a=!1!==e.jsonp&&(Zt.test(e.url)?"url":"string"==typeof e.data&&0===(e.contentType||"").indexOf("application/x-www-form-urlencoded")&&Zt.test(e.data)&&"data");if(a||"jsonp"===e.dataTypes[0])return r=e.jsonpCallback=v(e.jsonpCallback)?e.jsonpCallback():e.jsonpCallback,a?e[a]=e[a].replace(Zt,"$1"+r):!1!==e.jsonp&&(e.url+=(At.test(e.url)?"&":"?")+e.jsonp+"="+r),e.converters["script json"]=function(){return o||ce.error(r+" was not called"),o[0]},e.dataTypes[0]="json",i=ie[r],ie[r]=function(){o=arguments},n.always(function(){void 0===i?ce(ie).removeProp(r):ie[r]=i,e[r]&&(e.jsonpCallback=t.jsonpCallback,Kt.push(r)),o&&v(i)&&i(o[0]),o=i=void 0}),"script"}),le.createHTMLDocument=((Jt=C.implementation.createHTMLDocument("").body).innerHTML="
",2===Jt.childNodes.length),ce.parseHTML=function(e,t,n){return"string"!=typeof e?[]:("boolean"==typeof t&&(n=t,t=!1),t||(le.createHTMLDocument?((r=(t=C.implementation.createHTMLDocument("")).createElement("base")).href=C.location.href,t.head.appendChild(r)):t=C),o=!n&&[],(i=w.exec(e))?[t.createElement(i[1])]:(i=Ae([e],t,o),o&&o.length&&ce(o).remove(),ce.merge([],i.childNodes)));var r,i,o},ce.fn.load=function(e,t,n){var r,i,o,a=this,s=e.indexOf(" ");return-1").append(ce.parseHTML(e)).find(r):e)}).always(n&&function(e,t){a.each(function(){n.apply(this,o||[e.responseText,t,e])})}),this},ce.expr.pseudos.animated=function(t){return ce.grep(ce.timers,function(e){return t===e.elem}).length},ce.offset={setOffset:function(e,t,n){var r,i,o,a,s,u,l=ce.css(e,"position"),c=ce(e),f={};"static"===l&&(e.style.position="relative"),s=c.offset(),o=ce.css(e,"top"),u=ce.css(e,"left"),("absolute"===l||"fixed"===l)&&-1<(o+u).indexOf("auto")?(a=(r=c.position()).top,i=r.left):(a=parseFloat(o)||0,i=parseFloat(u)||0),v(t)&&(t=t.call(e,n,ce.extend({},s))),null!=t.top&&(f.top=t.top-s.top+a),null!=t.left&&(f.left=t.left-s.left+i),"using"in t?t.using.call(e,f):c.css(f)}},ce.fn.extend({offset:function(t){if(arguments.length)return void 0===t?this:this.each(function(e){ce.offset.setOffset(this,t,e)});var e,n,r=this[0];return r?r.getClientRects().length?(e=r.getBoundingClientRect(),n=r.ownerDocument.defaultView,{top:e.top+n.pageYOffset,left:e.left+n.pageXOffset}):{top:0,left:0}:void 0},position:function(){if(this[0]){var e,t,n,r=this[0],i={top:0,left:0};if("fixed"===ce.css(r,"position"))t=r.getBoundingClientRect();else{t=this.offset(),n=r.ownerDocument,e=r.offsetParent||n.documentElement;while(e&&(e===n.body||e===n.documentElement)&&"static"===ce.css(e,"position"))e=e.parentNode;e&&e!==r&&1===e.nodeType&&((i=ce(e).offset()).top+=ce.css(e,"borderTopWidth",!0),i.left+=ce.css(e,"borderLeftWidth",!0))}return{top:t.top-i.top-ce.css(r,"marginTop",!0),left:t.left-i.left-ce.css(r,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var e=this.offsetParent;while(e&&"static"===ce.css(e,"position"))e=e.offsetParent;return e||J})}}),ce.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(t,i){var o="pageYOffset"===i;ce.fn[t]=function(e){return M(this,function(e,t,n){var r;if(y(e)?r=e:9===e.nodeType&&(r=e.defaultView),void 0===n)return r?r[i]:e[t];r?r.scrollTo(o?r.pageXOffset:n,o?n:r.pageYOffset):e[t]=n},t,e,arguments.length)}}),ce.each(["top","left"],function(e,n){ce.cssHooks[n]=Ye(le.pixelPosition,function(e,t){if(t)return t=Ge(e,n),_e.test(t)?ce(e).position()[n]+"px":t})}),ce.each({Height:"height",Width:"width"},function(a,s){ce.each({padding:"inner"+a,content:s,"":"outer"+a},function(r,o){ce.fn[o]=function(e,t){var n=arguments.length&&(r||"boolean"!=typeof e),i=r||(!0===e||!0===t?"margin":"border");return M(this,function(e,t,n){var r;return y(e)?0===o.indexOf("outer")?e["inner"+a]:e.document.documentElement["client"+a]:9===e.nodeType?(r=e.documentElement,Math.max(e.body["scroll"+a],r["scroll"+a],e.body["offset"+a],r["offset"+a],r["client"+a])):void 0===n?ce.css(e,t,i):ce.style(e,t,n,i)},s,n?e:void 0,n)}})}),ce.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(e,t){ce.fn[t]=function(e){return this.on(t,e)}}),ce.fn.extend({bind:function(e,t,n){return this.on(e,null,t,n)},unbind:function(e,t){return this.off(e,null,t)},delegate:function(e,t,n,r){return this.on(t,e,n,r)},undelegate:function(e,t,n){return 1===arguments.length?this.off(e,"**"):this.off(t,e||"**",n)},hover:function(e,t){return this.on("mouseenter",e).on("mouseleave",t||e)}}),ce.each("blur focus focusin focusout resize scroll click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup contextmenu".split(" "),function(e,n){ce.fn[n]=function(e,t){return 0f&&(e=a.render.queue[f]);f++)d=e.generate(),typeof e.callback==typeof Function&&e.callback(d);a.render.queue.splice(0,f),a.render.queue.length?setTimeout(c):(a.dispatch.render_end(),a.render.active=!1)};setTimeout(c)},a.render.active=!1,a.render.queue=[],a.addGraph=function(b){typeof arguments[0]==typeof Function&&(b={generate:arguments[0],callback:arguments[1]}),a.render.queue.push(b),a.render.active||a.render()},"undefined"!=typeof module&&"undefined"!=typeof exports&&(module.exports=a),"undefined"!=typeof window&&(window.nv=a),a.dom.write=function(a){return void 0!==window.fastdom?fastdom.write(a):a()},a.dom.read=function(a){return void 0!==window.fastdom?fastdom.read(a):a()},a.interactiveGuideline=function(){"use strict";function b(l){l.each(function(l){function m(){var a=d3.mouse(this),d=a[0],e=a[1],i=!0,j=!1;if(k&&(d=d3.event.offsetX,e=d3.event.offsetY,"svg"!==d3.event.target.tagName&&(i=!1),d3.event.target.className.baseVal.match("nv-legend")&&(j=!0)),i&&(d-=f.left,e-=f.top),0>d||0>e||d>o||e>p||d3.event.relatedTarget&&void 0===d3.event.relatedTarget.ownerSVGElement||j){if(k&&d3.event.relatedTarget&&void 0===d3.event.relatedTarget.ownerSVGElement&&(void 0===d3.event.relatedTarget.className||d3.event.relatedTarget.className.match(c.nvPointerEventsClass)))return;return h.elementMouseout({mouseX:d,mouseY:e}),b.renderGuideLine(null),void c.hidden(!0)}c.hidden(!1);var l=g.invert(d);h.elementMousemove({mouseX:d,mouseY:e,pointXValue:l}),"dblclick"===d3.event.type&&h.elementDblclick({mouseX:d,mouseY:e,pointXValue:l}),"click"===d3.event.type&&h.elementClick({mouseX:d,mouseY:e,pointXValue:l})}var n=d3.select(this),o=d||960,p=e||400,q=n.selectAll("g.nv-wrap.nv-interactiveLineLayer").data([l]),r=q.enter().append("g").attr("class"," nv-wrap nv-interactiveLineLayer");r.append("g").attr("class","nv-interactiveGuideLine"),j&&(j.on("touchmove",m).on("mousemove",m,!0).on("mouseout",m,!0).on("dblclick",m).on("click",m),b.guideLine=null,b.renderGuideLine=function(c){i&&(b.guideLine&&b.guideLine.attr("x1")===c||a.dom.write(function(){var b=q.select(".nv-interactiveGuideLine").selectAll("line").data(null!=c?[a.utils.NaNtoZero(c)]:[],String);b.enter().append("line").attr("class","nv-guideline").attr("x1",function(a){return a}).attr("x2",function(a){return a}).attr("y1",p).attr("y2",0),b.exit().remove()}))})})}var c=a.models.tooltip();c.duration(0).hideDelay(0)._isInteractiveLayer(!0).hidden(!1);var d=null,e=null,f={left:0,top:0},g=d3.scale.linear(),h=d3.dispatch("elementMousemove","elementMouseout","elementClick","elementDblclick"),i=!0,j=null,k="ActiveXObject"in window;return b.dispatch=h,b.tooltip=c,b.margin=function(a){return arguments.length?(f.top="undefined"!=typeof a.top?a.top:f.top,f.left="undefined"!=typeof a.left?a.left:f.left,b):f},b.width=function(a){return arguments.length?(d=a,b):d},b.height=function(a){return arguments.length?(e=a,b):e},b.xScale=function(a){return arguments.length?(g=a,b):g},b.showGuideLine=function(a){return arguments.length?(i=a,b):i},b.svgContainer=function(a){return arguments.length?(j=a,b):j},b},a.interactiveBisect=function(a,b,c){"use strict";if(!(a instanceof Array))return null;var d;d="function"!=typeof c?function(a){return a.x}:c;var e=function(a,b){return d(a)-b},f=d3.bisector(e).left,g=d3.max([0,f(a,b)-1]),h=d(a[g]);if("undefined"==typeof h&&(h=g),h===b)return g;var i=d3.min([g+1,a.length-1]),j=d(a[i]);return"undefined"==typeof j&&(j=i),Math.abs(j-b)>=Math.abs(h-b)?g:i},a.nearestValueIndex=function(a,b,c){"use strict";var d=1/0,e=null;return a.forEach(function(a,f){var g=Math.abs(b-a);null!=a&&d>=g&&c>g&&(d=g,e=f)}),e},function(){"use strict";a.models.tooltip=function(){function b(){if(k){var a=d3.select(k);"svg"!==a.node().tagName&&(a=a.select("svg"));var b=a.node()?a.attr("viewBox"):null;if(b){b=b.split(" ");var c=parseInt(a.style("width"),10)/b[2];p.left=p.left*c,p.top=p.top*c}}}function c(){if(!n){var a;a=k?k:document.body,n=d3.select(a).append("div").attr("class","nvtooltip "+(j?j:"xy-tooltip")).attr("id",v),n.style("top",0).style("left",0),n.style("opacity",0),n.selectAll("div, table, td, tr").classed(w,!0),n.classed(w,!0),o=n.node()}}function d(){if(r&&B(e)){b();var f=p.left,g=null!==i?i:p.top;return a.dom.write(function(){c();var b=A(e);b&&(o.innerHTML=b),k&&u?a.dom.read(function(){var a=k.getElementsByTagName("svg")[0],b={left:0,top:0};if(a){var c=a.getBoundingClientRect(),d=k.getBoundingClientRect(),e=c.top;if(0>e){var i=k.getBoundingClientRect();e=Math.abs(e)>i.height?0:e}b.top=Math.abs(e-d.top),b.left=Math.abs(c.left-d.left)}f+=k.offsetLeft+b.left-2*k.scrollLeft,g+=k.offsetTop+b.top-2*k.scrollTop,h&&h>0&&(g=Math.floor(g/h)*h),C([f,g])}):C([f,g])}),d}}var e=null,f="w",g=25,h=0,i=null,j=null,k=null,l=!0,m=400,n=null,o=null,p={left:null,top:null},q={left:0,top:0},r=!0,s=100,t=!0,u=!1,v="nvtooltip-"+Math.floor(1e5*Math.random()),w="nv-pointer-events-none",x=function(a){return a},y=function(a){return a},z=function(a){return a},A=function(a){if(null===a)return"";var b=d3.select(document.createElement("table"));if(t){var c=b.selectAll("thead").data([a]).enter().append("thead");c.append("tr").append("td").attr("colspan",3).append("strong").classed("x-value",!0).html(y(a.value))}var d=b.selectAll("tbody").data([a]).enter().append("tbody"),e=d.selectAll("tr").data(function(a){return a.series}).enter().append("tr").classed("highlight",function(a){return a.highlight});e.append("td").classed("legend-color-guide",!0).append("div").style("background-color",function(a){return a.color}),e.append("td").classed("key",!0).html(function(a,b){return z(a.key,b)}),e.append("td").classed("value",!0).html(function(a,b){return x(a.value,b)}),e.selectAll("td").each(function(a){if(a.highlight){var b=d3.scale.linear().domain([0,1]).range(["#fff",a.color]),c=.6;d3.select(this).style("border-bottom-color",b(c)).style("border-top-color",b(c))}});var f=b.node().outerHTML;return void 0!==a.footer&&(f+=""),f},B=function(a){if(a&&a.series){if(a.series instanceof Array)return!!a.series.length;if(a.series instanceof Object)return a.series=[a.series],!0}return!1},C=function(b){o&&a.dom.read(function(){var c,d,e=parseInt(o.offsetHeight,10),h=parseInt(o.offsetWidth,10),i=a.utils.windowSize().width,j=a.utils.windowSize().height,k=window.pageYOffset,p=window.pageXOffset;j=window.innerWidth>=document.body.scrollWidth?j:j-16,i=window.innerHeight>=document.body.scrollHeight?i:i-16;var r,t,u=function(a){var b=d;do isNaN(a.offsetTop)||(b+=a.offsetTop),a=a.offsetParent;while(a);return b},v=function(a){var b=c;do isNaN(a.offsetLeft)||(b+=a.offsetLeft),a=a.offsetParent;while(a);return b};switch(f){case"e":c=b[0]-h-g,d=b[1]-e/2,r=v(o),t=u(o),p>r&&(c=b[0]+g>p?b[0]+g:p-r+c),k>t&&(d=k-t+d),t+e>k+j&&(d=k+j-t+d-e);break;case"w":c=b[0]+g,d=b[1]-e/2,r=v(o),t=u(o),r+h>i&&(c=b[0]-h-g),k>t&&(d=k+5),t+e>k+j&&(d=k+j-t+d-e);break;case"n":c=b[0]-h/2-5,d=b[1]+g,r=v(o),t=u(o),p>r&&(c=p+5),r+h>i&&(c=c-h/2+5),t+e>k+j&&(d=k+j-t+d-e);break;case"s":c=b[0]-h/2,d=b[1]-e-g,r=v(o),t=u(o),p>r&&(c=p+5),r+h>i&&(c=c-h/2+5),k>t&&(d=k);break;case"none":c=b[0],d=b[1]-g,r=v(o),t=u(o)}c-=q.left,d-=q.top;var w=o.getBoundingClientRect(),k=window.pageYOffset||document.documentElement.scrollTop,p=window.pageXOffset||document.documentElement.scrollLeft,x="translate("+(w.left+p)+"px, "+(w.top+k)+"px)",y="translate("+c+"px, "+d+"px)",z=d3.interpolateString(x,y),A=n.style("opacity")<.1;l?n.transition().delay(m).duration(0).style("opacity",0):n.interrupt().transition().duration(A?0:s).styleTween("transform",function(){return z},"important").style("-webkit-transform",y).style("opacity",1)})};return d.nvPointerEventsClass=w,d.options=a.utils.optionsFunc.bind(d),d._options=Object.create({},{duration:{get:function(){return s},set:function(a){s=a}},gravity:{get:function(){return f},set:function(a){f=a}},distance:{get:function(){return g},set:function(a){g=a}},snapDistance:{get:function(){return h},set:function(a){h=a}},classes:{get:function(){return j},set:function(a){j=a}},chartContainer:{get:function(){return k},set:function(a){k=a}},fixedTop:{get:function(){return i},set:function(a){i=a}},enabled:{get:function(){return r},set:function(a){r=a}},hideDelay:{get:function(){return m},set:function(a){m=a}},contentGenerator:{get:function(){return A},set:function(a){A=a}},valueFormatter:{get:function(){return x},set:function(a){x=a}},headerFormatter:{get:function(){return y},set:function(a){y=a}},keyFormatter:{get:function(){return z},set:function(a){z=a}},headerEnabled:{get:function(){return t},set:function(a){t=a}},_isInteractiveLayer:{get:function(){return u},set:function(a){u=!!a}},position:{get:function(){return p},set:function(a){p.left=void 0!==a.left?a.left:p.left,p.top=void 0!==a.top?a.top:p.top}},offset:{get:function(){return q},set:function(a){q.left=void 0!==a.left?a.left:q.left,q.top=void 0!==a.top?a.top:q.top}},hidden:{get:function(){return l},set:function(a){l!=a&&(l=!!a,d())}},data:{get:function(){return e},set:function(a){a.point&&(a.value=a.point.x,a.series=a.series||{},a.series.value=a.point.y,a.series.color=a.point.color||a.series.color),e=a}},tooltipElem:{get:function(){return o},set:function(){}},id:{get:function(){return v},set:function(){}}}),a.utils.initOptions(d),d}}(),a.utils.windowSize=function(){var a={width:640,height:480};return window.innerWidth&&window.innerHeight?(a.width=window.innerWidth,a.height=window.innerHeight,a):"CSS1Compat"==document.compatMode&&document.documentElement&&document.documentElement.offsetWidth?(a.width=document.documentElement.offsetWidth,a.height=document.documentElement.offsetHeight,a):document.body&&document.body.offsetWidth?(a.width=document.body.offsetWidth,a.height=document.body.offsetHeight,a):a},a.utils.windowResize=function(b){return window.addEventListener?window.addEventListener("resize",b):a.log("ERROR: Failed to bind to window.resize with: ",b),{callback:b,clear:function(){window.removeEventListener("resize",b)}}},a.utils.getColor=function(b){if(void 0===b)return a.utils.defaultColor();if(Array.isArray(b)){var c=d3.scale.ordinal().range(b);return function(a,b){var d=void 0===b?a:b;return a.color||c(d)}}return b},a.utils.defaultColor=function(){return a.utils.getColor(d3.scale.category20().range())},a.utils.customTheme=function(a,b,c){b=b||function(a){return a.key},c=c||d3.scale.category20().range();var d=c.length;return function(e){var f=b(e);return"function"==typeof a[f]?a[f]():void 0!==a[f]?a[f]:(d||(d=c.length),d-=1,c[d])}},a.utils.pjax=function(b,c){var d=function(d){d3.html(d,function(d){var e=d3.select(c).node();e.parentNode.replaceChild(d3.select(d).select(c).node(),e),a.utils.pjax(b,c)})};d3.selectAll(b).on("click",function(){history.pushState(this.href,this.textContent,this.href),d(this.href),d3.event.preventDefault()}),d3.select(window).on("popstate",function(){d3.event.state&&d(d3.event.state)})},a.utils.calcApproxTextWidth=function(a){if("function"==typeof a.style&&"function"==typeof a.text){var b=parseInt(a.style("font-size").replace("px",""),10),c=a.text().length;return c*b*.5}return 0},a.utils.NaNtoZero=function(a){return"number"!=typeof a||isNaN(a)||null===a||1/0===a||a===-1/0?0:a},d3.selection.prototype.watchTransition=function(a){var b=[this].concat([].slice.call(arguments,1));return a.transition.apply(a,b)},a.utils.renderWatch=function(b,c){if(!(this instanceof a.utils.renderWatch))return new a.utils.renderWatch(b,c);var d=void 0!==c?c:250,e=[],f=this;this.models=function(a){return a=[].slice.call(arguments,0),a.forEach(function(a){a.__rendered=!1,function(a){a.dispatch.on("renderEnd",function(){a.__rendered=!0,f.renderEnd("model")})}(a),e.indexOf(a)<0&&e.push(a)}),this},this.reset=function(a){void 0!==a&&(d=a),e=[]},this.transition=function(a,b,c){if(b=arguments.length>1?[].slice.call(arguments,1):[],c=b.length>1?b.pop():void 0!==d?d:250,a.__rendered=!1,e.indexOf(a)<0&&e.push(a),0===c)return a.__rendered=!0,a.delay=function(){return this},a.duration=function(){return this},a;a.__rendered=0===a.length?!0:a.every(function(a){return!a.length})?!0:!1;var g=0;return a.transition().duration(c).each(function(){++g}).each("end",function(){0===--g&&(a.__rendered=!0,f.renderEnd.apply(this,b))})},this.renderEnd=function(){e.every(function(a){return a.__rendered})&&(e.forEach(function(a){a.__rendered=!1}),b.renderEnd.apply(this,arguments))}},a.utils.deepExtend=function(b){var c=arguments.length>1?[].slice.call(arguments,1):[];c.forEach(function(c){for(var d in c){var e=b[d]instanceof Array,f="object"==typeof b[d],g="object"==typeof c[d];f&&!e&&g?a.utils.deepExtend(b[d],c[d]):b[d]=c[d]}})},a.utils.state=function(){if(!(this instanceof a.utils.state))return new a.utils.state;var b={},c=function(){},d=function(){return{}},e=null,f=null;this.dispatch=d3.dispatch("change","set"),this.dispatch.on("set",function(a){c(a,!0)}),this.getter=function(a){return d=a,this},this.setter=function(a,b){return b||(b=function(){}),c=function(c,d){a(c),d&&b()},this},this.init=function(b){e=e||{},a.utils.deepExtend(e,b)};var g=function(){var a=d();if(JSON.stringify(a)===JSON.stringify(b))return!1;for(var c in a)void 0===b[c]&&(b[c]={}),b[c]=a[c],f=!0;return!0};this.update=function(){e&&(c(e,!1),e=null),g.call(this)&&this.dispatch.change(b)}},a.utils.optionsFunc=function(a){return a&&d3.map(a).forEach(function(a,b){"function"==typeof this[a]&&this[a](b)}.bind(this)),this},a.utils.calcTicksX=function(b,c){var d=1,e=0;for(e;ed?f:d}return a.log("Requested number of ticks: ",b),a.log("Calculated max values to be: ",d),b=b>d?b=d-1:b,b=1>b?1:b,b=Math.floor(b),a.log("Calculating tick count as: ",b),b},a.utils.calcTicksY=function(b,c){return a.utils.calcTicksX(b,c)},a.utils.initOption=function(a,b){a._calls&&a._calls[b]?a[b]=a._calls[b]:(a[b]=function(c){return arguments.length?(a._overrides[b]=!0,a._options[b]=c,a):a._options[b]},a["_"+b]=function(c){return arguments.length?(a._overrides[b]||(a._options[b]=c),a):a._options[b]})},a.utils.initOptions=function(b){b._overrides=b._overrides||{};var c=Object.getOwnPropertyNames(b._options||{}),d=Object.getOwnPropertyNames(b._calls||{});c=c.concat(d);for(var e in c)a.utils.initOption(b,c[e])},a.utils.inheritOptionsD3=function(a,b,c){a._d3options=c.concat(a._d3options||[]),c.unshift(b),c.unshift(a),d3.rebind.apply(this,c)},a.utils.arrayUnique=function(a){return a.sort().filter(function(b,c){return!c||b!=a[c-1]})},a.utils.symbolMap=d3.map(),a.utils.symbol=function(){function b(b,e){var f=c.call(this,b,e),g=d.call(this,b,e);return-1!==d3.svg.symbolTypes.indexOf(f)?d3.svg.symbol().type(f).size(g)():a.utils.symbolMap.get(f)(g)}var c,d=64;return b.type=function(a){return arguments.length?(c=d3.functor(a),b):c},b.size=function(a){return arguments.length?(d=d3.functor(a),b):d},b},a.utils.inheritOptions=function(b,c){var d=Object.getOwnPropertyNames(c._options||{}),e=Object.getOwnPropertyNames(c._calls||{}),f=c._inherited||[],g=c._d3options||[],h=d.concat(e).concat(f).concat(g);h.unshift(c),h.unshift(b),d3.rebind.apply(this,h),b._inherited=a.utils.arrayUnique(d.concat(e).concat(f).concat(d).concat(b._inherited||[])),b._d3options=a.utils.arrayUnique(g.concat(b._d3options||[]))},a.utils.initSVG=function(a){a.classed({"nvd3-svg":!0})},a.utils.sanitizeHeight=function(a,b){return a||parseInt(b.style("height"),10)||400},a.utils.sanitizeWidth=function(a,b){return a||parseInt(b.style("width"),10)||960},a.utils.availableHeight=function(b,c,d){return a.utils.sanitizeHeight(b,c)-d.top-d.bottom},a.utils.availableWidth=function(b,c,d){return a.utils.sanitizeWidth(b,c)-d.left-d.right},a.utils.noData=function(b,c){var d=b.options(),e=d.margin(),f=d.noData(),g=null==f?["No Data Available."]:[f],h=a.utils.availableHeight(d.height(),c,e),i=a.utils.availableWidth(d.width(),c,e),j=e.left+i/2,k=e.top+h/2;c.selectAll("g").remove();var l=c.selectAll(".nv-noData").data(g);l.enter().append("text").attr("class","nvd3 nv-noData").attr("dy","-.7em").style("text-anchor","middle"),l.attr("x",j).attr("y",k).text(function(a){return a})},a.models.axis=function(){"use strict";function b(g){return s.reset(),g.each(function(b){var g=d3.select(this);a.utils.initSVG(g);var p=g.selectAll("g.nv-wrap.nv-axis").data([b]),q=p.enter().append("g").attr("class","nvd3 nv-wrap nv-axis"),t=(q.append("g"),p.select("g"));null!==n?c.ticks(n):("top"==c.orient()||"bottom"==c.orient())&&c.ticks(Math.abs(d.range()[1]-d.range()[0])/100),t.watchTransition(s,"axis").call(c),r=r||c.scale();var u=c.tickFormat();null==u&&(u=r.tickFormat());var v=t.selectAll("text.nv-axislabel").data([h||null]);v.exit().remove();var w,x,y;switch(c.orient()){case"top":v.enter().append("text").attr("class","nv-axislabel"),y=d.range().length<2?0:2===d.range().length?d.range()[1]:d.range()[d.range().length-1]+(d.range()[1]-d.range()[0]),v.attr("text-anchor","middle").attr("y",0).attr("x",y/2),i&&(x=p.selectAll("g.nv-axisMaxMin").data(d.domain()),x.enter().append("g").attr("class",function(a,b){return["nv-axisMaxMin","nv-axisMaxMin-x",0==b?"nv-axisMin-x":"nv-axisMax-x"].join(" ")}).append("text"),x.exit().remove(),x.attr("transform",function(b){return"translate("+a.utils.NaNtoZero(d(b))+",0)"}).select("text").attr("dy","-0.5em").attr("y",-c.tickPadding()).attr("text-anchor","middle").text(function(a){var b=u(a);return(""+b).match("NaN")?"":b}),x.watchTransition(s,"min-max top").attr("transform",function(b,c){return"translate("+a.utils.NaNtoZero(d.range()[c])+",0)"}));break;case"bottom":w=o+36;var z=30,A=0,B=t.selectAll("g").select("text"),C="";if(j%360){B.each(function(){var a=this.getBoundingClientRect(),b=a.width;A=a.height,b>z&&(z=b)}),C="rotate("+j+" 0,"+(A/2+c.tickPadding())+")";var D=Math.abs(Math.sin(j*Math.PI/180));w=(D?D*z:z)+30,B.attr("transform",C).style("text-anchor",j%360>0?"start":"end")}v.enter().append("text").attr("class","nv-axislabel"),y=d.range().length<2?0:2===d.range().length?d.range()[1]:d.range()[d.range().length-1]+(d.range()[1]-d.range()[0]),v.attr("text-anchor","middle").attr("y",w).attr("x",y/2),i&&(x=p.selectAll("g.nv-axisMaxMin").data([d.domain()[0],d.domain()[d.domain().length-1]]),x.enter().append("g").attr("class",function(a,b){return["nv-axisMaxMin","nv-axisMaxMin-x",0==b?"nv-axisMin-x":"nv-axisMax-x"].join(" ")}).append("text"),x.exit().remove(),x.attr("transform",function(b){return"translate("+a.utils.NaNtoZero(d(b)+(m?d.rangeBand()/2:0))+",0)"}).select("text").attr("dy",".71em").attr("y",c.tickPadding()).attr("transform",C).style("text-anchor",j?j%360>0?"start":"end":"middle").text(function(a){var b=u(a);return(""+b).match("NaN")?"":b}),x.watchTransition(s,"min-max bottom").attr("transform",function(b){return"translate("+a.utils.NaNtoZero(d(b)+(m?d.rangeBand()/2:0))+",0)"})),l&&B.attr("transform",function(a,b){return"translate(0,"+(b%2==0?"0":"12")+")"});break;case"right":v.enter().append("text").attr("class","nv-axislabel"),v.style("text-anchor",k?"middle":"begin").attr("transform",k?"rotate(90)":"").attr("y",k?-Math.max(e.right,f)+12:-10).attr("x",k?d3.max(d.range())/2:c.tickPadding()),i&&(x=p.selectAll("g.nv-axisMaxMin").data(d.domain()),x.enter().append("g").attr("class",function(a,b){return["nv-axisMaxMin","nv-axisMaxMin-y",0==b?"nv-axisMin-y":"nv-axisMax-y"].join(" ")}).append("text").style("opacity",0),x.exit().remove(),x.attr("transform",function(b){return"translate(0,"+a.utils.NaNtoZero(d(b))+")"}).select("text").attr("dy",".32em").attr("y",0).attr("x",c.tickPadding()).style("text-anchor","start").text(function(a){var b=u(a);return(""+b).match("NaN")?"":b}),x.watchTransition(s,"min-max right").attr("transform",function(b,c){return"translate(0,"+a.utils.NaNtoZero(d.range()[c])+")"}).select("text").style("opacity",1));break;case"left":v.enter().append("text").attr("class","nv-axislabel"),v.style("text-anchor",k?"middle":"end").attr("transform",k?"rotate(-90)":"").attr("y",k?-Math.max(e.left,f)+25-(o||0):-10).attr("x",k?-d3.max(d.range())/2:-c.tickPadding()),i&&(x=p.selectAll("g.nv-axisMaxMin").data(d.domain()),x.enter().append("g").attr("class",function(a,b){return["nv-axisMaxMin","nv-axisMaxMin-y",0==b?"nv-axisMin-y":"nv-axisMax-y"].join(" ")}).append("text").style("opacity",0),x.exit().remove(),x.attr("transform",function(b){return"translate(0,"+a.utils.NaNtoZero(r(b))+")"}).select("text").attr("dy",".32em").attr("y",0).attr("x",-c.tickPadding()).attr("text-anchor","end").text(function(a){var b=u(a);return(""+b).match("NaN")?"":b}),x.watchTransition(s,"min-max right").attr("transform",function(b,c){return"translate(0,"+a.utils.NaNtoZero(d.range()[c])+")"}).select("text").style("opacity",1))}if(v.text(function(a){return a}),!i||"left"!==c.orient()&&"right"!==c.orient()||(t.selectAll("g").each(function(a){d3.select(this).select("text").attr("opacity",1),(d(a)d.range()[0]-10)&&((a>1e-10||-1e-10>a)&&d3.select(this).attr("opacity",0),d3.select(this).select("text").attr("opacity",0))}),d.domain()[0]==d.domain()[1]&&0==d.domain()[0]&&p.selectAll("g.nv-axisMaxMin").style("opacity",function(a,b){return b?0:1})),i&&("top"===c.orient()||"bottom"===c.orient())){var E=[];p.selectAll("g.nv-axisMaxMin").each(function(a,b){try{E.push(b?d(a)-this.getBoundingClientRect().width-4:d(a)+this.getBoundingClientRect().width+4)}catch(c){E.push(b?d(a)-4:d(a)+4)}}),t.selectAll("g").each(function(a){(d(a)E[1])&&(a>1e-10||-1e-10>a?d3.select(this).remove():d3.select(this).select("text").remove())})}t.selectAll(".tick").filter(function(a){return!parseFloat(Math.round(1e5*a)/1e6)&&void 0!==a}).classed("zero",!0),r=d.copy()}),s.renderEnd("axis immediate"),b}var c=d3.svg.axis(),d=d3.scale.linear(),e={top:0,right:0,bottom:0,left:0},f=75,g=60,h=null,i=!0,j=0,k=!0,l=!1,m=!1,n=null,o=0,p=250,q=d3.dispatch("renderEnd");c.scale(d).orient("bottom").tickFormat(function(a){return a});var r,s=a.utils.renderWatch(q,p);return b.axis=c,b.dispatch=q,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{axisLabelDistance:{get:function(){return o},set:function(a){o=a}},staggerLabels:{get:function(){return l},set:function(a){l=a}},rotateLabels:{get:function(){return j},set:function(a){j=a}},rotateYLabel:{get:function(){return k},set:function(a){k=a}},showMaxMin:{get:function(){return i},set:function(a){i=a}},axisLabel:{get:function(){return h},set:function(a){h=a}},height:{get:function(){return g},set:function(a){g=a}},ticks:{get:function(){return n},set:function(a){n=a}},width:{get:function(){return f},set:function(a){f=a}},margin:{get:function(){return e},set:function(a){e.top=void 0!==a.top?a.top:e.top,e.right=void 0!==a.right?a.right:e.right,e.bottom=void 0!==a.bottom?a.bottom:e.bottom,e.left=void 0!==a.left?a.left:e.left}},duration:{get:function(){return p},set:function(a){p=a,s.reset(p)}},scale:{get:function(){return d},set:function(e){d=e,c.scale(d),m="function"==typeof d.rangeBands,a.utils.inheritOptionsD3(b,d,["domain","range","rangeBand","rangeBands"])}}}),a.utils.initOptions(b),a.utils.inheritOptionsD3(b,c,["orient","tickValues","tickSubdivide","tickSize","tickPadding","tickFormat"]),a.utils.inheritOptionsD3(b,d,["domain","range","rangeBand","rangeBands"]),b},a.models.boxPlot=function(){"use strict";function b(l){return v.reset(),l.each(function(b){var l=j-i.left-i.right,p=k-i.top-i.bottom;r=d3.select(this),a.utils.initSVG(r),m.domain(c||b.map(function(a,b){return o(a,b)})).rangeBands(e||[0,l],.1);var w=[];if(!d){var x=d3.min(b.map(function(a){var b=[];return b.push(a.values.Q1),a.values.hasOwnProperty("whisker_low")&&null!==a.values.whisker_low&&b.push(a.values.whisker_low),a.values.hasOwnProperty("outliers")&&null!==a.values.outliers&&(b=b.concat(a.values.outliers)),d3.min(b)})),y=d3.max(b.map(function(a){var b=[];return b.push(a.values.Q3),a.values.hasOwnProperty("whisker_high")&&null!==a.values.whisker_high&&b.push(a.values.whisker_high),a.values.hasOwnProperty("outliers")&&null!==a.values.outliers&&(b=b.concat(a.values.outliers)),d3.max(b)}));w=[x,y]}n.domain(d||w),n.range(f||[p,0]),g=g||m,h=h||n.copy().range([n(0),n(0)]);{var z=r.selectAll("g.nv-wrap").data([b]);z.enter().append("g").attr("class","nvd3 nv-wrap")}z.attr("transform","translate("+i.left+","+i.top+")");var A=z.selectAll(".nv-boxplot").data(function(a){return a}),B=A.enter().append("g").style("stroke-opacity",1e-6).style("fill-opacity",1e-6);A.attr("class","nv-boxplot").attr("transform",function(a,b){return"translate("+(m(o(a,b))+.05*m.rangeBand())+", 0)"}).classed("hover",function(a){return a.hover}),A.watchTransition(v,"nv-boxplot: boxplots").style("stroke-opacity",1).style("fill-opacity",.75).delay(function(a,c){return c*t/b.length}).attr("transform",function(a,b){return"translate("+(m(o(a,b))+.05*m.rangeBand())+", 0)"}),A.exit().remove(),B.each(function(a,b){var c=d3.select(this);["low","high"].forEach(function(d){a.values.hasOwnProperty("whisker_"+d)&&null!==a.values["whisker_"+d]&&(c.append("line").style("stroke",a.color?a.color:q(a,b)).attr("class","nv-boxplot-whisker nv-boxplot-"+d),c.append("line").style("stroke",a.color?a.color:q(a,b)).attr("class","nv-boxplot-tick nv-boxplot-"+d))})});var C=A.selectAll(".nv-boxplot-outlier").data(function(a){return a.values.hasOwnProperty("outliers")&&null!==a.values.outliers?a.values.outliers:[]});C.enter().append("circle").style("fill",function(a,b,c){return q(a,c)}).style("stroke",function(a,b,c){return q(a,c)}).on("mouseover",function(a,b,c){d3.select(this).classed("hover",!0),s.elementMouseover({series:{key:a,color:q(a,c)},e:d3.event})}).on("mouseout",function(a,b,c){d3.select(this).classed("hover",!1),s.elementMouseout({series:{key:a,color:q(a,c)},e:d3.event})}).on("mousemove",function(){s.elementMousemove({e:d3.event})}),C.attr("class","nv-boxplot-outlier"),C.watchTransition(v,"nv-boxplot: nv-boxplot-outlier").attr("cx",.45*m.rangeBand()).attr("cy",function(a){return n(a)}).attr("r","3"),C.exit().remove();var D=function(){return null===u?.9*m.rangeBand():Math.min(75,.9*m.rangeBand())},E=function(){return.45*m.rangeBand()-D()/2},F=function(){return.45*m.rangeBand()+D()/2};["low","high"].forEach(function(a){var b="low"===a?"Q1":"Q3";A.select("line.nv-boxplot-whisker.nv-boxplot-"+a).watchTransition(v,"nv-boxplot: boxplots").attr("x1",.45*m.rangeBand()).attr("y1",function(b){return n(b.values["whisker_"+a])}).attr("x2",.45*m.rangeBand()).attr("y2",function(a){return n(a.values[b])}),A.select("line.nv-boxplot-tick.nv-boxplot-"+a).watchTransition(v,"nv-boxplot: boxplots").attr("x1",E).attr("y1",function(b){return n(b.values["whisker_"+a])}).attr("x2",F).attr("y2",function(b){return n(b.values["whisker_"+a])})}),["low","high"].forEach(function(a){B.selectAll(".nv-boxplot-"+a).on("mouseover",function(b,c,d){d3.select(this).classed("hover",!0),s.elementMouseover({series:{key:b.values["whisker_"+a],color:q(b,d)},e:d3.event})}).on("mouseout",function(b,c,d){d3.select(this).classed("hover",!1),s.elementMouseout({series:{key:b.values["whisker_"+a],color:q(b,d)},e:d3.event})}).on("mousemove",function(){s.elementMousemove({e:d3.event})})}),B.append("rect").attr("class","nv-boxplot-box").on("mouseover",function(a,b){d3.select(this).classed("hover",!0),s.elementMouseover({key:a.label,value:a.label,series:[{key:"Q3",value:a.values.Q3,color:a.color||q(a,b)},{key:"Q2",value:a.values.Q2,color:a.color||q(a,b)},{key:"Q1",value:a.values.Q1,color:a.color||q(a,b)}],data:a,index:b,e:d3.event})}).on("mouseout",function(a,b){d3.select(this).classed("hover",!1),s.elementMouseout({key:a.label,value:a.label,series:[{key:"Q3",value:a.values.Q3,color:a.color||q(a,b)},{key:"Q2",value:a.values.Q2,color:a.color||q(a,b)},{key:"Q1",value:a.values.Q1,color:a.color||q(a,b)}],data:a,index:b,e:d3.event})}).on("mousemove",function(){s.elementMousemove({e:d3.event})}),A.select("rect.nv-boxplot-box").watchTransition(v,"nv-boxplot: boxes").attr("y",function(a){return n(a.values.Q3)}).attr("width",D).attr("x",E).attr("height",function(a){return Math.abs(n(a.values.Q3)-n(a.values.Q1))||1}).style("fill",function(a,b){return a.color||q(a,b)}).style("stroke",function(a,b){return a.color||q(a,b)}),B.append("line").attr("class","nv-boxplot-median"),A.select("line.nv-boxplot-median").watchTransition(v,"nv-boxplot: boxplots line").attr("x1",E).attr("y1",function(a){return n(a.values.Q2)}).attr("x2",F).attr("y2",function(a){return n(a.values.Q2)}),g=m.copy(),h=n.copy()}),v.renderEnd("nv-boxplot immediate"),b}var c,d,e,f,g,h,i={top:0,right:0,bottom:0,left:0},j=960,k=500,l=Math.floor(1e4*Math.random()),m=d3.scale.ordinal(),n=d3.scale.linear(),o=function(a){return a.x},p=function(a){return a.y},q=a.utils.defaultColor(),r=null,s=d3.dispatch("elementMouseover","elementMouseout","elementMousemove","renderEnd"),t=250,u=null,v=a.utils.renderWatch(s,t);return b.dispatch=s,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return j},set:function(a){j=a}},height:{get:function(){return k},set:function(a){k=a}},maxBoxWidth:{get:function(){return u},set:function(a){u=a}},x:{get:function(){return o},set:function(a){o=a}},y:{get:function(){return p},set:function(a){p=a}},xScale:{get:function(){return m},set:function(a){m=a}},yScale:{get:function(){return n},set:function(a){n=a}},xDomain:{get:function(){return c},set:function(a){c=a}},yDomain:{get:function(){return d},set:function(a){d=a}},xRange:{get:function(){return e},set:function(a){e=a}},yRange:{get:function(){return f},set:function(a){f=a}},id:{get:function(){return l},set:function(a){l=a}},margin:{get:function(){return i},set:function(a){i.top=void 0!==a.top?a.top:i.top,i.right=void 0!==a.right?a.right:i.right,i.bottom=void 0!==a.bottom?a.bottom:i.bottom,i.left=void 0!==a.left?a.left:i.left}},color:{get:function(){return q},set:function(b){q=a.utils.getColor(b)}},duration:{get:function(){return t},set:function(a){t=a,v.reset(t)}}}),a.utils.initOptions(b),b},a.models.boxPlotChart=function(){"use strict";function b(k){return t.reset(),t.models(e),l&&t.models(f),m&&t.models(g),k.each(function(k){var p=d3.select(this);a.utils.initSVG(p);var t=(i||parseInt(p.style("width"))||960)-h.left-h.right,u=(j||parseInt(p.style("height"))||400)-h.top-h.bottom;if(b.update=function(){r.beforeUpdate(),p.transition().duration(s).call(b)},b.container=this,!(k&&k.length&&k.filter(function(a){return a.values.hasOwnProperty("Q1")&&a.values.hasOwnProperty("Q2")&&a.values.hasOwnProperty("Q3")}).length)){var v=p.selectAll(".nv-noData").data([q]);return v.enter().append("text").attr("class","nvd3 nv-noData").attr("dy","-.7em").style("text-anchor","middle"),v.attr("x",h.left+t/2).attr("y",h.top+u/2).text(function(a){return a}),b}p.selectAll(".nv-noData").remove(),c=e.xScale(),d=e.yScale().clamp(!0);var w=p.selectAll("g.nv-wrap.nv-boxPlotWithAxes").data([k]),x=w.enter().append("g").attr("class","nvd3 nv-wrap nv-boxPlotWithAxes").append("g"),y=x.append("defs"),z=w.select("g"); -x.append("g").attr("class","nv-x nv-axis"),x.append("g").attr("class","nv-y nv-axis").append("g").attr("class","nv-zeroLine").append("line"),x.append("g").attr("class","nv-barsWrap"),z.attr("transform","translate("+h.left+","+h.top+")"),n&&z.select(".nv-y.nv-axis").attr("transform","translate("+t+",0)"),e.width(t).height(u);var A=z.select(".nv-barsWrap").datum(k.filter(function(a){return!a.disabled}));if(A.transition().call(e),y.append("clipPath").attr("id","nv-x-label-clip-"+e.id()).append("rect"),z.select("#nv-x-label-clip-"+e.id()+" rect").attr("width",c.rangeBand()*(o?2:1)).attr("height",16).attr("x",-c.rangeBand()/(o?1:2)),l){f.scale(c).ticks(a.utils.calcTicksX(t/100,k)).tickSize(-u,0),z.select(".nv-x.nv-axis").attr("transform","translate(0,"+d.range()[0]+")"),z.select(".nv-x.nv-axis").call(f);var B=z.select(".nv-x.nv-axis").selectAll("g");o&&B.selectAll("text").attr("transform",function(a,b,c){return"translate(0,"+(c%2==0?"5":"17")+")"})}m&&(g.scale(d).ticks(Math.floor(u/36)).tickSize(-t,0),z.select(".nv-y.nv-axis").call(g)),z.select(".nv-zeroLine line").attr("x1",0).attr("x2",t).attr("y1",d(0)).attr("y2",d(0))}),t.renderEnd("nv-boxplot chart immediate"),b}var c,d,e=a.models.boxPlot(),f=a.models.axis(),g=a.models.axis(),h={top:15,right:10,bottom:50,left:60},i=null,j=null,k=a.utils.getColor(),l=!0,m=!0,n=!1,o=!1,p=a.models.tooltip(),q="No Data Available.",r=d3.dispatch("tooltipShow","tooltipHide","beforeUpdate","renderEnd"),s=250;f.orient("bottom").showMaxMin(!1).tickFormat(function(a){return a}),g.orient(n?"right":"left").tickFormat(d3.format(",.1f")),p.duration(0);var t=a.utils.renderWatch(r,s);return e.dispatch.on("elementMouseover.tooltip",function(a){p.data(a).hidden(!1)}),e.dispatch.on("elementMouseout.tooltip",function(a){p.data(a).hidden(!0)}),e.dispatch.on("elementMousemove.tooltip",function(){p.position({top:d3.event.pageY,left:d3.event.pageX})()}),b.dispatch=r,b.boxplot=e,b.xAxis=f,b.yAxis=g,b.tooltip=p,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return i},set:function(a){i=a}},height:{get:function(){return j},set:function(a){j=a}},staggerLabels:{get:function(){return o},set:function(a){o=a}},showXAxis:{get:function(){return l},set:function(a){l=a}},showYAxis:{get:function(){return m},set:function(a){m=a}},tooltips:{get:function(){return tooltips},set:function(a){tooltips=a}},tooltipContent:{get:function(){return p},set:function(a){p=a}},noData:{get:function(){return q},set:function(a){q=a}},margin:{get:function(){return h},set:function(a){h.top=void 0!==a.top?a.top:h.top,h.right=void 0!==a.right?a.right:h.right,h.bottom=void 0!==a.bottom?a.bottom:h.bottom,h.left=void 0!==a.left?a.left:h.left}},duration:{get:function(){return s},set:function(a){s=a,t.reset(s),e.duration(s),f.duration(s),g.duration(s)}},color:{get:function(){return k},set:function(b){k=a.utils.getColor(b),e.color(k)}},rightAlignYAxis:{get:function(){return n},set:function(a){n=a,g.orient(a?"right":"left")}}}),a.utils.inheritOptions(b,e),a.utils.initOptions(b),b},a.models.bullet=function(){"use strict";function b(d){return d.each(function(b,d){var p=m-c.left-c.right,s=n-c.top-c.bottom;o=d3.select(this),a.utils.initSVG(o);{var t=f.call(this,b,d).slice().sort(d3.descending),u=g.call(this,b,d).slice().sort(d3.descending),v=h.call(this,b,d).slice().sort(d3.descending),w=i.call(this,b,d).slice(),x=j.call(this,b,d).slice(),y=k.call(this,b,d).slice(),z=d3.scale.linear().domain(d3.extent(d3.merge([l,t]))).range(e?[p,0]:[0,p]);this.__chart__||d3.scale.linear().domain([0,1/0]).range(z.range())}this.__chart__=z;var A=d3.min(t),B=d3.max(t),C=t[1],D=o.selectAll("g.nv-wrap.nv-bullet").data([b]),E=D.enter().append("g").attr("class","nvd3 nv-wrap nv-bullet"),F=E.append("g"),G=D.select("g");F.append("rect").attr("class","nv-range nv-rangeMax"),F.append("rect").attr("class","nv-range nv-rangeAvg"),F.append("rect").attr("class","nv-range nv-rangeMin"),F.append("rect").attr("class","nv-measure"),D.attr("transform","translate("+c.left+","+c.top+")");var H=function(a){return Math.abs(z(a)-z(0))},I=function(a){return z(0>a?a:0)};G.select("rect.nv-rangeMax").attr("height",s).attr("width",H(B>0?B:A)).attr("x",I(B>0?B:A)).datum(B>0?B:A),G.select("rect.nv-rangeAvg").attr("height",s).attr("width",H(C)).attr("x",I(C)).datum(C),G.select("rect.nv-rangeMin").attr("height",s).attr("width",H(B)).attr("x",I(B)).attr("width",H(B>0?A:B)).attr("x",I(B>0?A:B)).datum(B>0?A:B),G.select("rect.nv-measure").style("fill",q).attr("height",s/3).attr("y",s/3).attr("width",0>v?z(0)-z(v[0]):z(v[0])-z(0)).attr("x",I(v)).on("mouseover",function(){r.elementMouseover({value:v[0],label:y[0]||"Current",color:d3.select(this).style("fill")})}).on("mousemove",function(){r.elementMousemove({value:v[0],label:y[0]||"Current",color:d3.select(this).style("fill")})}).on("mouseout",function(){r.elementMouseout({value:v[0],label:y[0]||"Current",color:d3.select(this).style("fill")})});var J=s/6,K=u.map(function(a,b){return{value:a,label:x[b]}});F.selectAll("path.nv-markerTriangle").data(K).enter().append("path").attr("class","nv-markerTriangle").attr("transform",function(a){return"translate("+z(a.value)+","+s/2+")"}).attr("d","M0,"+J+"L"+J+","+-J+" "+-J+","+-J+"Z").on("mouseover",function(a){r.elementMouseover({value:a.value,label:a.label||"Previous",color:d3.select(this).style("fill"),pos:[z(a.value),s/2]})}).on("mousemove",function(a){r.elementMousemove({value:a.value,label:a.label||"Previous",color:d3.select(this).style("fill")})}).on("mouseout",function(a){r.elementMouseout({value:a.value,label:a.label||"Previous",color:d3.select(this).style("fill")})}),D.selectAll(".nv-range").on("mouseover",function(a,b){var c=w[b]||(b?1==b?"Mean":"Minimum":"Maximum");r.elementMouseover({value:a,label:c,color:d3.select(this).style("fill")})}).on("mousemove",function(){r.elementMousemove({value:v[0],label:y[0]||"Previous",color:d3.select(this).style("fill")})}).on("mouseout",function(a,b){var c=w[b]||(b?1==b?"Mean":"Minimum":"Maximum");r.elementMouseout({value:a,label:c,color:d3.select(this).style("fill")})})}),b}var c={top:0,right:0,bottom:0,left:0},d="left",e=!1,f=function(a){return a.ranges},g=function(a){return a.markers?a.markers:[0]},h=function(a){return a.measures},i=function(a){return a.rangeLabels?a.rangeLabels:[]},j=function(a){return a.markerLabels?a.markerLabels:[]},k=function(a){return a.measureLabels?a.measureLabels:[]},l=[0],m=380,n=30,o=null,p=null,q=a.utils.getColor(["#1f77b4"]),r=d3.dispatch("elementMouseover","elementMouseout","elementMousemove");return b.dispatch=r,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{ranges:{get:function(){return f},set:function(a){f=a}},markers:{get:function(){return g},set:function(a){g=a}},measures:{get:function(){return h},set:function(a){h=a}},forceX:{get:function(){return l},set:function(a){l=a}},width:{get:function(){return m},set:function(a){m=a}},height:{get:function(){return n},set:function(a){n=a}},tickFormat:{get:function(){return p},set:function(a){p=a}},margin:{get:function(){return c},set:function(a){c.top=void 0!==a.top?a.top:c.top,c.right=void 0!==a.right?a.right:c.right,c.bottom=void 0!==a.bottom?a.bottom:c.bottom,c.left=void 0!==a.left?a.left:c.left}},orient:{get:function(){return d},set:function(a){d=a,e="right"==d||"bottom"==d}},color:{get:function(){return q},set:function(b){q=a.utils.getColor(b)}}}),a.utils.initOptions(b),b},a.models.bulletChart=function(){"use strict";function b(d){return d.each(function(e,o){var p=d3.select(this);a.utils.initSVG(p);var q=a.utils.availableWidth(k,p,g),r=l-g.top-g.bottom;if(b.update=function(){b(d)},b.container=this,!e||!h.call(this,e,o))return a.utils.noData(b,p),b;p.selectAll(".nv-noData").remove();var s=h.call(this,e,o).slice().sort(d3.descending),t=i.call(this,e,o).slice().sort(d3.descending),u=j.call(this,e,o).slice().sort(d3.descending),v=p.selectAll("g.nv-wrap.nv-bulletChart").data([e]),w=v.enter().append("g").attr("class","nvd3 nv-wrap nv-bulletChart"),x=w.append("g"),y=v.select("g");x.append("g").attr("class","nv-bulletWrap"),x.append("g").attr("class","nv-titles"),v.attr("transform","translate("+g.left+","+g.top+")");var z=d3.scale.linear().domain([0,Math.max(s[0],t[0],u[0])]).range(f?[q,0]:[0,q]),A=this.__chart__||d3.scale.linear().domain([0,1/0]).range(z.range());this.__chart__=z;var B=x.select(".nv-titles").append("g").attr("text-anchor","end").attr("transform","translate(-6,"+(l-g.top-g.bottom)/2+")");B.append("text").attr("class","nv-title").text(function(a){return a.title}),B.append("text").attr("class","nv-subtitle").attr("dy","1em").text(function(a){return a.subtitle}),c.width(q).height(r);var C=y.select(".nv-bulletWrap");d3.transition(C).call(c);var D=m||z.tickFormat(q/100),E=y.selectAll("g.nv-tick").data(z.ticks(n?n:q/50),function(a){return this.textContent||D(a)}),F=E.enter().append("g").attr("class","nv-tick").attr("transform",function(a){return"translate("+A(a)+",0)"}).style("opacity",1e-6);F.append("line").attr("y1",r).attr("y2",7*r/6),F.append("text").attr("text-anchor","middle").attr("dy","1em").attr("y",7*r/6).text(D);var G=d3.transition(E).attr("transform",function(a){return"translate("+z(a)+",0)"}).style("opacity",1);G.select("line").attr("y1",r).attr("y2",7*r/6),G.select("text").attr("y",7*r/6),d3.transition(E.exit()).attr("transform",function(a){return"translate("+z(a)+",0)"}).style("opacity",1e-6).remove()}),d3.timer.flush(),b}var c=a.models.bullet(),d=a.models.tooltip(),e="left",f=!1,g={top:5,right:40,bottom:20,left:120},h=function(a){return a.ranges},i=function(a){return a.markers?a.markers:[0]},j=function(a){return a.measures},k=null,l=55,m=null,n=null,o=null,p=d3.dispatch("tooltipShow","tooltipHide");return d.duration(0).headerEnabled(!1),c.dispatch.on("elementMouseover.tooltip",function(a){a.series={key:a.label,value:a.value,color:a.color},d.data(a).hidden(!1)}),c.dispatch.on("elementMouseout.tooltip",function(){d.hidden(!0)}),c.dispatch.on("elementMousemove.tooltip",function(){d.position({top:d3.event.pageY,left:d3.event.pageX})()}),b.bullet=c,b.dispatch=p,b.tooltip=d,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{ranges:{get:function(){return h},set:function(a){h=a}},markers:{get:function(){return i},set:function(a){i=a}},measures:{get:function(){return j},set:function(a){j=a}},width:{get:function(){return k},set:function(a){k=a}},height:{get:function(){return l},set:function(a){l=a}},tickFormat:{get:function(){return m},set:function(a){m=a}},ticks:{get:function(){return n},set:function(a){n=a}},noData:{get:function(){return o},set:function(a){o=a}},tooltips:{get:function(){return d.enabled()},set:function(b){a.deprecated("tooltips","use chart.tooltip.enabled() instead"),d.enabled(!!b)}},tooltipContent:{get:function(){return d.contentGenerator()},set:function(b){a.deprecated("tooltipContent","use chart.tooltip.contentGenerator() instead"),d.contentGenerator(b)}},margin:{get:function(){return g},set:function(a){g.top=void 0!==a.top?a.top:g.top,g.right=void 0!==a.right?a.right:g.right,g.bottom=void 0!==a.bottom?a.bottom:g.bottom,g.left=void 0!==a.left?a.left:g.left}},orient:{get:function(){return e},set:function(a){e=a,f="right"==e||"bottom"==e}}}),a.utils.inheritOptions(b,c),a.utils.initOptions(b),b},a.models.candlestickBar=function(){"use strict";function b(x){return x.each(function(b){c=d3.select(this);var x=a.utils.availableWidth(i,c,h),y=a.utils.availableHeight(j,c,h);a.utils.initSVG(c);var A=x/b[0].values.length*.45;l.domain(d||d3.extent(b[0].values.map(n).concat(t))),l.range(v?f||[.5*x/b[0].values.length,x*(b[0].values.length-.5)/b[0].values.length]:f||[5+A/2,x-A/2-5]),m.domain(e||[d3.min(b[0].values.map(s).concat(u)),d3.max(b[0].values.map(r).concat(u))]).range(g||[y,0]),l.domain()[0]===l.domain()[1]&&l.domain(l.domain()[0]?[l.domain()[0]-.01*l.domain()[0],l.domain()[1]+.01*l.domain()[1]]:[-1,1]),m.domain()[0]===m.domain()[1]&&m.domain(m.domain()[0]?[m.domain()[0]+.01*m.domain()[0],m.domain()[1]-.01*m.domain()[1]]:[-1,1]);var B=d3.select(this).selectAll("g.nv-wrap.nv-candlestickBar").data([b[0].values]),C=B.enter().append("g").attr("class","nvd3 nv-wrap nv-candlestickBar"),D=C.append("defs"),E=C.append("g"),F=B.select("g");E.append("g").attr("class","nv-ticks"),B.attr("transform","translate("+h.left+","+h.top+")"),c.on("click",function(a,b){z.chartClick({data:a,index:b,pos:d3.event,id:k})}),D.append("clipPath").attr("id","nv-chart-clip-path-"+k).append("rect"),B.select("#nv-chart-clip-path-"+k+" rect").attr("width",x).attr("height",y),F.attr("clip-path",w?"url(#nv-chart-clip-path-"+k+")":"");var G=B.select(".nv-ticks").selectAll(".nv-tick").data(function(a){return a});G.exit().remove();{var H=G.enter().append("g").attr("class",function(a,b,c){return(p(a,b)>q(a,b)?"nv-tick negative":"nv-tick positive")+" nv-tick-"+c+"-"+b});H.append("line").attr("class","nv-candlestick-lines").attr("transform",function(a,b){return"translate("+l(n(a,b))+",0)"}).attr("x1",0).attr("y1",function(a,b){return m(r(a,b))}).attr("x2",0).attr("y2",function(a,b){return m(s(a,b))}),H.append("rect").attr("class","nv-candlestick-rects nv-bars").attr("transform",function(a,b){return"translate("+(l(n(a,b))-A/2)+","+(m(o(a,b))-(p(a,b)>q(a,b)?m(q(a,b))-m(p(a,b)):0))+")"}).attr("x",0).attr("y",0).attr("width",A).attr("height",function(a,b){var c=p(a,b),d=q(a,b);return c>d?m(d)-m(c):m(c)-m(d)})}c.selectAll(".nv-candlestick-lines").transition().attr("transform",function(a,b){return"translate("+l(n(a,b))+",0)"}).attr("x1",0).attr("y1",function(a,b){return m(r(a,b))}).attr("x2",0).attr("y2",function(a,b){return m(s(a,b))}),c.selectAll(".nv-candlestick-rects").transition().attr("transform",function(a,b){return"translate("+(l(n(a,b))-A/2)+","+(m(o(a,b))-(p(a,b)>q(a,b)?m(q(a,b))-m(p(a,b)):0))+")"}).attr("x",0).attr("y",0).attr("width",A).attr("height",function(a,b){var c=p(a,b),d=q(a,b);return c>d?m(d)-m(c):m(c)-m(d)})}),b}var c,d,e,f,g,h={top:0,right:0,bottom:0,left:0},i=null,j=null,k=Math.floor(1e4*Math.random()),l=d3.scale.linear(),m=d3.scale.linear(),n=function(a){return a.x},o=function(a){return a.y},p=function(a){return a.open},q=function(a){return a.close},r=function(a){return a.high},s=function(a){return a.low},t=[],u=[],v=!1,w=!0,x=a.utils.defaultColor(),y=!1,z=d3.dispatch("tooltipShow","tooltipHide","stateChange","changeState","renderEnd","chartClick","elementClick","elementDblClick","elementMouseover","elementMouseout","elementMousemove");return b.highlightPoint=function(a,d){b.clearHighlights(),c.select(".nv-candlestickBar .nv-tick-0-"+a).classed("hover",d)},b.clearHighlights=function(){c.select(".nv-candlestickBar .nv-tick.hover").classed("hover",!1)},b.dispatch=z,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return i},set:function(a){i=a}},height:{get:function(){return j},set:function(a){j=a}},xScale:{get:function(){return l},set:function(a){l=a}},yScale:{get:function(){return m},set:function(a){m=a}},xDomain:{get:function(){return d},set:function(a){d=a}},yDomain:{get:function(){return e},set:function(a){e=a}},xRange:{get:function(){return f},set:function(a){f=a}},yRange:{get:function(){return g},set:function(a){g=a}},forceX:{get:function(){return t},set:function(a){t=a}},forceY:{get:function(){return u},set:function(a){u=a}},padData:{get:function(){return v},set:function(a){v=a}},clipEdge:{get:function(){return w},set:function(a){w=a}},id:{get:function(){return k},set:function(a){k=a}},interactive:{get:function(){return y},set:function(a){y=a}},x:{get:function(){return n},set:function(a){n=a}},y:{get:function(){return o},set:function(a){o=a}},open:{get:function(){return p()},set:function(a){p=a}},close:{get:function(){return q()},set:function(a){q=a}},high:{get:function(){return r},set:function(a){r=a}},low:{get:function(){return s},set:function(a){s=a}},margin:{get:function(){return h},set:function(a){h.top=void 0!=a.top?a.top:h.top,h.right=void 0!=a.right?a.right:h.right,h.bottom=void 0!=a.bottom?a.bottom:h.bottom,h.left=void 0!=a.left?a.left:h.left}},color:{get:function(){return x},set:function(b){x=a.utils.getColor(b)}}}),a.utils.initOptions(b),b},a.models.cumulativeLineChart=function(){"use strict";function b(l){return H.reset(),H.models(f),r&&H.models(g),s&&H.models(h),l.each(function(l){function A(){d3.select(b.container).style("cursor","ew-resize")}function E(){G.x=d3.event.x,G.i=Math.round(F.invert(G.x)),K()}function H(){d3.select(b.container).style("cursor","auto"),y.index=G.i,C.stateChange(y)}function K(){bb.data([G]);var a=b.duration();b.duration(0),b.update(),b.duration(a)}var L=d3.select(this);a.utils.initSVG(L),L.classed("nv-chart-"+x,!0);var M=this,N=a.utils.availableWidth(o,L,m),O=a.utils.availableHeight(p,L,m);if(b.update=function(){0===D?L.call(b):L.transition().duration(D).call(b)},b.container=this,y.setter(J(l),b.update).getter(I(l)).update(),y.disabled=l.map(function(a){return!!a.disabled}),!z){var P;z={};for(P in y)z[P]=y[P]instanceof Array?y[P].slice(0):y[P]}var Q=d3.behavior.drag().on("dragstart",A).on("drag",E).on("dragend",H);if(!(l&&l.length&&l.filter(function(a){return a.values.length}).length))return a.utils.noData(b,L),b;if(L.selectAll(".nv-noData").remove(),d=f.xScale(),e=f.yScale(),w)f.yDomain(null);else{var R=l.filter(function(a){return!a.disabled}).map(function(a){var b=d3.extent(a.values,f.y());return b[0]<-.95&&(b[0]=-.95),[(b[0]-b[1])/(1+b[1]),(b[1]-b[0])/(1+b[0])]}),S=[d3.min(R,function(a){return a[0]}),d3.max(R,function(a){return a[1]})];f.yDomain(S)}F.domain([0,l[0].values.length-1]).range([0,N]).clamp(!0);var l=c(G.i,l),T=v?"none":"all",U=L.selectAll("g.nv-wrap.nv-cumulativeLine").data([l]),V=U.enter().append("g").attr("class","nvd3 nv-wrap nv-cumulativeLine").append("g"),W=U.select("g");if(V.append("g").attr("class","nv-interactive"),V.append("g").attr("class","nv-x nv-axis").style("pointer-events","none"),V.append("g").attr("class","nv-y nv-axis"),V.append("g").attr("class","nv-background"),V.append("g").attr("class","nv-linesWrap").style("pointer-events",T),V.append("g").attr("class","nv-avgLinesWrap").style("pointer-events","none"),V.append("g").attr("class","nv-legendWrap"),V.append("g").attr("class","nv-controlsWrap"),q&&(i.width(N),W.select(".nv-legendWrap").datum(l).call(i),m.top!=i.height()&&(m.top=i.height(),O=a.utils.availableHeight(p,L,m)),W.select(".nv-legendWrap").attr("transform","translate(0,"+-m.top+")")),u){var X=[{key:"Re-scale y-axis",disabled:!w}];j.width(140).color(["#444","#444","#444"]).rightAlign(!1).margin({top:5,right:0,bottom:5,left:20}),W.select(".nv-controlsWrap").datum(X).attr("transform","translate(0,"+-m.top+")").call(j)}U.attr("transform","translate("+m.left+","+m.top+")"),t&&W.select(".nv-y.nv-axis").attr("transform","translate("+N+",0)");var Y=l.filter(function(a){return a.tempDisabled});U.select(".tempDisabled").remove(),Y.length&&U.append("text").attr("class","tempDisabled").attr("x",N/2).attr("y","-.71em").style("text-anchor","end").text(Y.map(function(a){return a.key}).join(", ")+" values cannot be calculated for this time period."),v&&(k.width(N).height(O).margin({left:m.left,top:m.top}).svgContainer(L).xScale(d),U.select(".nv-interactive").call(k)),V.select(".nv-background").append("rect"),W.select(".nv-background rect").attr("width",N).attr("height",O),f.y(function(a){return a.display.y}).width(N).height(O).color(l.map(function(a,b){return a.color||n(a,b)}).filter(function(a,b){return!l[b].disabled&&!l[b].tempDisabled}));var Z=W.select(".nv-linesWrap").datum(l.filter(function(a){return!a.disabled&&!a.tempDisabled}));Z.call(f),l.forEach(function(a,b){a.seriesIndex=b});var $=l.filter(function(a){return!a.disabled&&!!B(a)}),_=W.select(".nv-avgLinesWrap").selectAll("line").data($,function(a){return a.key}),ab=function(a){var b=e(B(a));return 0>b?0:b>O?O:b};_.enter().append("line").style("stroke-width",2).style("stroke-dasharray","10,10").style("stroke",function(a){return f.color()(a,a.seriesIndex)}).attr("x1",0).attr("x2",N).attr("y1",ab).attr("y2",ab),_.style("stroke-opacity",function(a){var b=e(B(a));return 0>b||b>O?0:1}).attr("x1",0).attr("x2",N).attr("y1",ab).attr("y2",ab),_.exit().remove();var bb=Z.selectAll(".nv-indexLine").data([G]);bb.enter().append("rect").attr("class","nv-indexLine").attr("width",3).attr("x",-2).attr("fill","red").attr("fill-opacity",.5).style("pointer-events","all").call(Q),bb.attr("transform",function(a){return"translate("+F(a.i)+",0)"}).attr("height",O),r&&(g.scale(d)._ticks(a.utils.calcTicksX(N/70,l)).tickSize(-O,0),W.select(".nv-x.nv-axis").attr("transform","translate(0,"+e.range()[0]+")"),W.select(".nv-x.nv-axis").call(g)),s&&(h.scale(e)._ticks(a.utils.calcTicksY(O/36,l)).tickSize(-N,0),W.select(".nv-y.nv-axis").call(h)),W.select(".nv-background rect").on("click",function(){G.x=d3.mouse(this)[0],G.i=Math.round(F.invert(G.x)),y.index=G.i,C.stateChange(y),K()}),f.dispatch.on("elementClick",function(a){G.i=a.pointIndex,G.x=F(G.i),y.index=G.i,C.stateChange(y),K()}),j.dispatch.on("legendClick",function(a){a.disabled=!a.disabled,w=!a.disabled,y.rescaleY=w,C.stateChange(y),b.update()}),i.dispatch.on("stateChange",function(a){for(var c in a)y[c]=a[c];C.stateChange(y),b.update()}),k.dispatch.on("elementMousemove",function(c){f.clearHighlights();var d,e,i,j=[];if(l.filter(function(a,b){return a.seriesIndex=b,!a.disabled}).forEach(function(g,h){e=a.interactiveBisect(g.values,c.pointXValue,b.x()),f.highlightPoint(h,e,!0);var k=g.values[e];"undefined"!=typeof k&&("undefined"==typeof d&&(d=k),"undefined"==typeof i&&(i=b.xScale()(b.x()(k,e))),j.push({key:g.key,value:b.y()(k,e),color:n(g,g.seriesIndex)}))}),j.length>2){var o=b.yScale().invert(c.mouseY),p=Math.abs(b.yScale().domain()[0]-b.yScale().domain()[1]),q=.03*p,r=a.nearestValueIndex(j.map(function(a){return a.value}),o,q);null!==r&&(j[r].highlight=!0)}var s=g.tickFormat()(b.x()(d,e),e);k.tooltip.position({left:i+m.left,top:c.mouseY+m.top}).chartContainer(M.parentNode).valueFormatter(function(a){return h.tickFormat()(a)}).data({value:s,series:j})(),k.renderGuideLine(i)}),k.dispatch.on("elementMouseout",function(){f.clearHighlights()}),C.on("changeState",function(a){"undefined"!=typeof a.disabled&&(l.forEach(function(b,c){b.disabled=a.disabled[c]}),y.disabled=a.disabled),"undefined"!=typeof a.index&&(G.i=a.index,G.x=F(G.i),y.index=a.index,bb.data([G])),"undefined"!=typeof a.rescaleY&&(w=a.rescaleY),b.update()})}),H.renderEnd("cumulativeLineChart immediate"),b}function c(a,b){return K||(K=f.y()),b.map(function(b){if(!b.values)return b;var c=b.values[a];if(null==c)return b;var d=K(c,a);return-.95>d&&!E?(b.tempDisabled=!0,b):(b.tempDisabled=!1,b.values=b.values.map(function(a,b){return a.display={y:(K(a,b)-d)/(1+d)},a}),b)})}var d,e,f=a.models.line(),g=a.models.axis(),h=a.models.axis(),i=a.models.legend(),j=a.models.legend(),k=a.interactiveGuideline(),l=a.models.tooltip(),m={top:30,right:30,bottom:50,left:60},n=a.utils.defaultColor(),o=null,p=null,q=!0,r=!0,s=!0,t=!1,u=!0,v=!1,w=!0,x=f.id(),y=a.utils.state(),z=null,A=null,B=function(a){return a.average},C=d3.dispatch("stateChange","changeState","renderEnd"),D=250,E=!1;y.index=0,y.rescaleY=w,g.orient("bottom").tickPadding(7),h.orient(t?"right":"left"),l.valueFormatter(function(a,b){return h.tickFormat()(a,b)}).headerFormatter(function(a,b){return g.tickFormat()(a,b)}),j.updateState(!1);var F=d3.scale.linear(),G={i:0,x:0},H=a.utils.renderWatch(C,D),I=function(a){return function(){return{active:a.map(function(a){return!a.disabled}),index:G.i,rescaleY:w}}},J=function(a){return function(b){void 0!==b.index&&(G.i=b.index),void 0!==b.rescaleY&&(w=b.rescaleY),void 0!==b.active&&a.forEach(function(a,c){a.disabled=!b.active[c]})}};f.dispatch.on("elementMouseover.tooltip",function(a){var c={x:b.x()(a.point),y:b.y()(a.point),color:a.point.color};a.point=c,l.data(a).position(a.pos).hidden(!1)}),f.dispatch.on("elementMouseout.tooltip",function(){l.hidden(!0)});var K=null;return b.dispatch=C,b.lines=f,b.legend=i,b.controls=j,b.xAxis=g,b.yAxis=h,b.interactiveLayer=k,b.state=y,b.tooltip=l,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return o},set:function(a){o=a}},height:{get:function(){return p},set:function(a){p=a}},rescaleY:{get:function(){return w},set:function(a){w=a}},showControls:{get:function(){return u},set:function(a){u=a}},showLegend:{get:function(){return q},set:function(a){q=a}},average:{get:function(){return B},set:function(a){B=a}},defaultState:{get:function(){return z},set:function(a){z=a}},noData:{get:function(){return A},set:function(a){A=a}},showXAxis:{get:function(){return r},set:function(a){r=a}},showYAxis:{get:function(){return s},set:function(a){s=a}},noErrorCheck:{get:function(){return E},set:function(a){E=a}},tooltips:{get:function(){return l.enabled()},set:function(b){a.deprecated("tooltips","use chart.tooltip.enabled() instead"),l.enabled(!!b)}},tooltipContent:{get:function(){return l.contentGenerator()},set:function(b){a.deprecated("tooltipContent","use chart.tooltip.contentGenerator() instead"),l.contentGenerator(b)}},margin:{get:function(){return m},set:function(a){m.top=void 0!==a.top?a.top:m.top,m.right=void 0!==a.right?a.right:m.right,m.bottom=void 0!==a.bottom?a.bottom:m.bottom,m.left=void 0!==a.left?a.left:m.left}},color:{get:function(){return n},set:function(b){n=a.utils.getColor(b),i.color(n)}},useInteractiveGuideline:{get:function(){return v},set:function(a){v=a,a===!0&&(b.interactive(!1),b.useVoronoi(!1))}},rightAlignYAxis:{get:function(){return t},set:function(a){t=a,h.orient(a?"right":"left")}},duration:{get:function(){return D},set:function(a){D=a,f.duration(D),g.duration(D),h.duration(D),H.reset(D)}}}),a.utils.inheritOptions(b,f),a.utils.initOptions(b),b},a.models.discreteBar=function(){"use strict";function b(m){return y.reset(),m.each(function(b){var m=k-j.left-j.right,x=l-j.top-j.bottom;c=d3.select(this),a.utils.initSVG(c),b.forEach(function(a,b){a.values.forEach(function(a){a.series=b})});var z=d&&e?[]:b.map(function(a){return a.values.map(function(a,b){return{x:p(a,b),y:q(a,b),y0:a.y0}})});n.domain(d||d3.merge(z).map(function(a){return a.x})).rangeBands(f||[0,m],.1),o.domain(e||d3.extent(d3.merge(z).map(function(a){return a.y}).concat(r))),o.range(t?g||[x-(o.domain()[0]<0?12:0),o.domain()[1]>0?12:0]:g||[x,0]),h=h||n,i=i||o.copy().range([o(0),o(0)]);{var A=c.selectAll("g.nv-wrap.nv-discretebar").data([b]),B=A.enter().append("g").attr("class","nvd3 nv-wrap nv-discretebar"),C=B.append("g");A.select("g")}C.append("g").attr("class","nv-groups"),A.attr("transform","translate("+j.left+","+j.top+")");var D=A.select(".nv-groups").selectAll(".nv-group").data(function(a){return a},function(a){return a.key});D.enter().append("g").style("stroke-opacity",1e-6).style("fill-opacity",1e-6),D.exit().watchTransition(y,"discreteBar: exit groups").style("stroke-opacity",1e-6).style("fill-opacity",1e-6).remove(),D.attr("class",function(a,b){return"nv-group nv-series-"+b}).classed("hover",function(a){return a.hover}),D.watchTransition(y,"discreteBar: groups").style("stroke-opacity",1).style("fill-opacity",.75);var E=D.selectAll("g.nv-bar").data(function(a){return a.values});E.exit().remove();var F=E.enter().append("g").attr("transform",function(a,b){return"translate("+(n(p(a,b))+.05*n.rangeBand())+", "+o(0)+")"}).on("mouseover",function(a,b){d3.select(this).classed("hover",!0),v.elementMouseover({data:a,index:b,color:d3.select(this).style("fill")})}).on("mouseout",function(a,b){d3.select(this).classed("hover",!1),v.elementMouseout({data:a,index:b,color:d3.select(this).style("fill")})}).on("mousemove",function(a,b){v.elementMousemove({data:a,index:b,color:d3.select(this).style("fill")})}).on("click",function(a,b){v.elementClick({data:a,index:b,color:d3.select(this).style("fill")}),d3.event.stopPropagation()}).on("dblclick",function(a,b){v.elementDblClick({data:a,index:b,color:d3.select(this).style("fill")}),d3.event.stopPropagation()});F.append("rect").attr("height",0).attr("width",.9*n.rangeBand()/b.length),t?(F.append("text").attr("text-anchor","middle"),E.select("text").text(function(a,b){return u(q(a,b))}).watchTransition(y,"discreteBar: bars text").attr("x",.9*n.rangeBand()/2).attr("y",function(a,b){return q(a,b)<0?o(q(a,b))-o(0)+12:-4})):E.selectAll("text").remove(),E.attr("class",function(a,b){return q(a,b)<0?"nv-bar negative":"nv-bar positive"}).style("fill",function(a,b){return a.color||s(a,b)}).style("stroke",function(a,b){return a.color||s(a,b)}).select("rect").attr("class",w).watchTransition(y,"discreteBar: bars rect").attr("width",.9*n.rangeBand()/b.length),E.watchTransition(y,"discreteBar: bars").attr("transform",function(a,b){var c=n(p(a,b))+.05*n.rangeBand(),d=q(a,b)<0?o(0):o(0)-o(q(a,b))<1?o(0)-1:o(q(a,b));return"translate("+c+", "+d+")"}).select("rect").attr("height",function(a,b){return Math.max(Math.abs(o(q(a,b))-o(e&&e[0]||0))||1)}),h=n.copy(),i=o.copy()}),y.renderEnd("discreteBar immediate"),b}var c,d,e,f,g,h,i,j={top:0,right:0,bottom:0,left:0},k=960,l=500,m=Math.floor(1e4*Math.random()),n=d3.scale.ordinal(),o=d3.scale.linear(),p=function(a){return a.x},q=function(a){return a.y},r=[0],s=a.utils.defaultColor(),t=!1,u=d3.format(",.2f"),v=d3.dispatch("chartClick","elementClick","elementDblClick","elementMouseover","elementMouseout","elementMousemove","renderEnd"),w="discreteBar",x=250,y=a.utils.renderWatch(v,x);return b.dispatch=v,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return k},set:function(a){k=a}},height:{get:function(){return l},set:function(a){l=a}},forceY:{get:function(){return r},set:function(a){r=a}},showValues:{get:function(){return t},set:function(a){t=a}},x:{get:function(){return p},set:function(a){p=a}},y:{get:function(){return q},set:function(a){q=a}},xScale:{get:function(){return n},set:function(a){n=a}},yScale:{get:function(){return o},set:function(a){o=a}},xDomain:{get:function(){return d},set:function(a){d=a}},yDomain:{get:function(){return e},set:function(a){e=a}},xRange:{get:function(){return f},set:function(a){f=a}},yRange:{get:function(){return g},set:function(a){g=a}},valueFormat:{get:function(){return u},set:function(a){u=a}},id:{get:function(){return m},set:function(a){m=a}},rectClass:{get:function(){return w},set:function(a){w=a}},margin:{get:function(){return j},set:function(a){j.top=void 0!==a.top?a.top:j.top,j.right=void 0!==a.right?a.right:j.right,j.bottom=void 0!==a.bottom?a.bottom:j.bottom,j.left=void 0!==a.left?a.left:j.left}},color:{get:function(){return s},set:function(b){s=a.utils.getColor(b)}},duration:{get:function(){return x},set:function(a){x=a,y.reset(x)}}}),a.utils.initOptions(b),b},a.models.discreteBarChart=function(){"use strict";function b(h){return t.reset(),t.models(e),m&&t.models(f),n&&t.models(g),h.each(function(h){var l=d3.select(this);a.utils.initSVG(l);var q=a.utils.availableWidth(j,l,i),t=a.utils.availableHeight(k,l,i);if(b.update=function(){r.beforeUpdate(),l.transition().duration(s).call(b)},b.container=this,!(h&&h.length&&h.filter(function(a){return a.values.length}).length))return a.utils.noData(b,l),b;l.selectAll(".nv-noData").remove(),c=e.xScale(),d=e.yScale().clamp(!0);var u=l.selectAll("g.nv-wrap.nv-discreteBarWithAxes").data([h]),v=u.enter().append("g").attr("class","nvd3 nv-wrap nv-discreteBarWithAxes").append("g"),w=v.append("defs"),x=u.select("g");v.append("g").attr("class","nv-x nv-axis"),v.append("g").attr("class","nv-y nv-axis").append("g").attr("class","nv-zeroLine").append("line"),v.append("g").attr("class","nv-barsWrap"),x.attr("transform","translate("+i.left+","+i.top+")"),o&&x.select(".nv-y.nv-axis").attr("transform","translate("+q+",0)"),e.width(q).height(t);var y=x.select(".nv-barsWrap").datum(h.filter(function(a){return!a.disabled}));if(y.transition().call(e),w.append("clipPath").attr("id","nv-x-label-clip-"+e.id()).append("rect"),x.select("#nv-x-label-clip-"+e.id()+" rect").attr("width",c.rangeBand()*(p?2:1)).attr("height",16).attr("x",-c.rangeBand()/(p?1:2)),m){f.scale(c)._ticks(a.utils.calcTicksX(q/100,h)).tickSize(-t,0),x.select(".nv-x.nv-axis").attr("transform","translate(0,"+(d.range()[0]+(e.showValues()&&d.domain()[0]<0?16:0))+")"),x.select(".nv-x.nv-axis").call(f); -var z=x.select(".nv-x.nv-axis").selectAll("g");p&&z.selectAll("text").attr("transform",function(a,b,c){return"translate(0,"+(c%2==0?"5":"17")+")"})}n&&(g.scale(d)._ticks(a.utils.calcTicksY(t/36,h)).tickSize(-q,0),x.select(".nv-y.nv-axis").call(g)),x.select(".nv-zeroLine line").attr("x1",0).attr("x2",q).attr("y1",d(0)).attr("y2",d(0))}),t.renderEnd("discreteBar chart immediate"),b}var c,d,e=a.models.discreteBar(),f=a.models.axis(),g=a.models.axis(),h=a.models.tooltip(),i={top:15,right:10,bottom:50,left:60},j=null,k=null,l=a.utils.getColor(),m=!0,n=!0,o=!1,p=!1,q=null,r=d3.dispatch("beforeUpdate","renderEnd"),s=250;f.orient("bottom").showMaxMin(!1).tickFormat(function(a){return a}),g.orient(o?"right":"left").tickFormat(d3.format(",.1f")),h.duration(0).headerEnabled(!1).valueFormatter(function(a,b){return g.tickFormat()(a,b)}).keyFormatter(function(a,b){return f.tickFormat()(a,b)});var t=a.utils.renderWatch(r,s);return e.dispatch.on("elementMouseover.tooltip",function(a){a.series={key:b.x()(a.data),value:b.y()(a.data),color:a.color},h.data(a).hidden(!1)}),e.dispatch.on("elementMouseout.tooltip",function(){h.hidden(!0)}),e.dispatch.on("elementMousemove.tooltip",function(){h.position({top:d3.event.pageY,left:d3.event.pageX})()}),b.dispatch=r,b.discretebar=e,b.xAxis=f,b.yAxis=g,b.tooltip=h,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return j},set:function(a){j=a}},height:{get:function(){return k},set:function(a){k=a}},staggerLabels:{get:function(){return p},set:function(a){p=a}},showXAxis:{get:function(){return m},set:function(a){m=a}},showYAxis:{get:function(){return n},set:function(a){n=a}},noData:{get:function(){return q},set:function(a){q=a}},tooltips:{get:function(){return h.enabled()},set:function(b){a.deprecated("tooltips","use chart.tooltip.enabled() instead"),h.enabled(!!b)}},tooltipContent:{get:function(){return h.contentGenerator()},set:function(b){a.deprecated("tooltipContent","use chart.tooltip.contentGenerator() instead"),h.contentGenerator(b)}},margin:{get:function(){return i},set:function(a){i.top=void 0!==a.top?a.top:i.top,i.right=void 0!==a.right?a.right:i.right,i.bottom=void 0!==a.bottom?a.bottom:i.bottom,i.left=void 0!==a.left?a.left:i.left}},duration:{get:function(){return s},set:function(a){s=a,t.reset(s),e.duration(s),f.duration(s),g.duration(s)}},color:{get:function(){return l},set:function(b){l=a.utils.getColor(b),e.color(l)}},rightAlignYAxis:{get:function(){return o},set:function(a){o=a,g.orient(a?"right":"left")}}}),a.utils.inheritOptions(b,e),a.utils.initOptions(b),b},a.models.distribution=function(){"use strict";function b(k){return m.reset(),k.each(function(b){var k=(e-("x"===g?d.left+d.right:d.top+d.bottom),"x"==g?"y":"x"),l=d3.select(this);a.utils.initSVG(l),c=c||j;var n=l.selectAll("g.nv-distribution").data([b]),o=n.enter().append("g").attr("class","nvd3 nv-distribution"),p=(o.append("g"),n.select("g"));n.attr("transform","translate("+d.left+","+d.top+")");var q=p.selectAll("g.nv-dist").data(function(a){return a},function(a){return a.key});q.enter().append("g"),q.attr("class",function(a,b){return"nv-dist nv-series-"+b}).style("stroke",function(a,b){return i(a,b)});var r=q.selectAll("line.nv-dist"+g).data(function(a){return a.values});r.enter().append("line").attr(g+"1",function(a,b){return c(h(a,b))}).attr(g+"2",function(a,b){return c(h(a,b))}),m.transition(q.exit().selectAll("line.nv-dist"+g),"dist exit").attr(g+"1",function(a,b){return j(h(a,b))}).attr(g+"2",function(a,b){return j(h(a,b))}).style("stroke-opacity",0).remove(),r.attr("class",function(a,b){return"nv-dist"+g+" nv-dist"+g+"-"+b}).attr(k+"1",0).attr(k+"2",f),m.transition(r,"dist").attr(g+"1",function(a,b){return j(h(a,b))}).attr(g+"2",function(a,b){return j(h(a,b))}),c=j.copy()}),m.renderEnd("distribution immediate"),b}var c,d={top:0,right:0,bottom:0,left:0},e=400,f=8,g="x",h=function(a){return a[g]},i=a.utils.defaultColor(),j=d3.scale.linear(),k=250,l=d3.dispatch("renderEnd"),m=a.utils.renderWatch(l,k);return b.options=a.utils.optionsFunc.bind(b),b.dispatch=l,b.margin=function(a){return arguments.length?(d.top="undefined"!=typeof a.top?a.top:d.top,d.right="undefined"!=typeof a.right?a.right:d.right,d.bottom="undefined"!=typeof a.bottom?a.bottom:d.bottom,d.left="undefined"!=typeof a.left?a.left:d.left,b):d},b.width=function(a){return arguments.length?(e=a,b):e},b.axis=function(a){return arguments.length?(g=a,b):g},b.size=function(a){return arguments.length?(f=a,b):f},b.getData=function(a){return arguments.length?(h=d3.functor(a),b):h},b.scale=function(a){return arguments.length?(j=a,b):j},b.color=function(c){return arguments.length?(i=a.utils.getColor(c),b):i},b.duration=function(a){return arguments.length?(k=a,m.reset(k),b):k},b},a.models.furiousLegend=function(){"use strict";function b(p){function q(a,b){return"furious"!=o?"#000":m?a.disengaged?g(a,b):"#fff":m?void 0:a.disabled?g(a,b):"#fff"}function r(a,b){return m&&"furious"==o?a.disengaged?"#fff":g(a,b):a.disabled?"#fff":g(a,b)}return p.each(function(b){var p=d-c.left-c.right,s=d3.select(this);a.utils.initSVG(s);var t=s.selectAll("g.nv-legend").data([b]),u=(t.enter().append("g").attr("class","nvd3 nv-legend").append("g"),t.select("g"));t.attr("transform","translate("+c.left+","+c.top+")");var v,w=u.selectAll(".nv-series").data(function(a){return"furious"!=o?a:a.filter(function(a){return m?!0:!a.disengaged})}),x=w.enter().append("g").attr("class","nv-series");if("classic"==o)x.append("circle").style("stroke-width",2).attr("class","nv-legend-symbol").attr("r",5),v=w.select("circle");else if("furious"==o){x.append("rect").style("stroke-width",2).attr("class","nv-legend-symbol").attr("rx",3).attr("ry",3),v=w.select("rect"),x.append("g").attr("class","nv-check-box").property("innerHTML",'').attr("transform","translate(-10,-8)scale(0.5)");var y=w.select(".nv-check-box");y.each(function(a,b){d3.select(this).selectAll("path").attr("stroke",q(a,b))})}x.append("text").attr("text-anchor","start").attr("class","nv-legend-text").attr("dy",".32em").attr("dx","8");var z=w.select("text.nv-legend-text");w.on("mouseover",function(a,b){n.legendMouseover(a,b)}).on("mouseout",function(a,b){n.legendMouseout(a,b)}).on("click",function(a,b){n.legendClick(a,b);var c=w.data();if(k){if("classic"==o)l?(c.forEach(function(a){a.disabled=!0}),a.disabled=!1):(a.disabled=!a.disabled,c.every(function(a){return a.disabled})&&c.forEach(function(a){a.disabled=!1}));else if("furious"==o)if(m)a.disengaged=!a.disengaged,a.userDisabled=void 0==a.userDisabled?!!a.disabled:a.userDisabled,a.disabled=a.disengaged||a.userDisabled;else if(!m){a.disabled=!a.disabled,a.userDisabled=a.disabled;var d=c.filter(function(a){return!a.disengaged});d.every(function(a){return a.userDisabled})&&c.forEach(function(a){a.disabled=a.userDisabled=!1})}n.stateChange({disabled:c.map(function(a){return!!a.disabled}),disengaged:c.map(function(a){return!!a.disengaged})})}}).on("dblclick",function(a,b){if(("furious"!=o||!m)&&(n.legendDblclick(a,b),k)){var c=w.data();c.forEach(function(a){a.disabled=!0,"furious"==o&&(a.userDisabled=a.disabled)}),a.disabled=!1,"furious"==o&&(a.userDisabled=a.disabled),n.stateChange({disabled:c.map(function(a){return!!a.disabled})})}}),w.classed("nv-disabled",function(a){return a.userDisabled}),w.exit().remove(),z.attr("fill",q).text(f);var A;switch(o){case"furious":A=23;break;case"classic":A=20}if(h){var B=[];w.each(function(){var b,c=d3.select(this).select("text");try{if(b=c.node().getComputedTextLength(),0>=b)throw Error()}catch(d){b=a.utils.calcApproxTextWidth(c)}B.push(b+i)});for(var C=0,D=0,E=[];p>D&&Cp&&C>1;){E=[],C--;for(var F=0;F(E[F%C]||0)&&(E[F%C]=B[F]);D=E.reduce(function(a,b){return a+b})}for(var G=[],H=0,I=0;C>H;H++)G[H]=I,I+=E[H];w.attr("transform",function(a,b){return"translate("+G[b%C]+","+(5+Math.floor(b/C)*A)+")"}),j?u.attr("transform","translate("+(d-c.right-D)+","+c.top+")"):u.attr("transform","translate(0,"+c.top+")"),e=c.top+c.bottom+Math.ceil(B.length/C)*A}else{var J,K=5,L=5,M=0;w.attr("transform",function(){var a=d3.select(this).select("text").node().getComputedTextLength()+i;return J=L,dM&&(M=L),"translate("+J+","+K+")"}),u.attr("transform","translate("+(d-c.right-M)+","+c.top+")"),e=c.top+c.bottom+K+15}"furious"==o&&v.attr("width",function(a,b){return z[0][b].getComputedTextLength()+27}).attr("height",18).attr("y",-9).attr("x",-15),v.style("fill",r).style("stroke",function(a,b){return a.color||g(a,b)})}),b}var c={top:5,right:0,bottom:5,left:0},d=400,e=20,f=function(a){return a.key},g=a.utils.getColor(),h=!0,i=28,j=!0,k=!0,l=!1,m=!1,n=d3.dispatch("legendClick","legendDblclick","legendMouseover","legendMouseout","stateChange"),o="classic";return b.dispatch=n,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return d},set:function(a){d=a}},height:{get:function(){return e},set:function(a){e=a}},key:{get:function(){return f},set:function(a){f=a}},align:{get:function(){return h},set:function(a){h=a}},rightAlign:{get:function(){return j},set:function(a){j=a}},padding:{get:function(){return i},set:function(a){i=a}},updateState:{get:function(){return k},set:function(a){k=a}},radioButtonMode:{get:function(){return l},set:function(a){l=a}},expanded:{get:function(){return m},set:function(a){m=a}},vers:{get:function(){return o},set:function(a){o=a}},margin:{get:function(){return c},set:function(a){c.top=void 0!==a.top?a.top:c.top,c.right=void 0!==a.right?a.right:c.right,c.bottom=void 0!==a.bottom?a.bottom:c.bottom,c.left=void 0!==a.left?a.left:c.left}},color:{get:function(){return g},set:function(b){g=a.utils.getColor(b)}}}),a.utils.initOptions(b),b},a.models.historicalBar=function(){"use strict";function b(x){return x.each(function(b){w.reset(),k=d3.select(this);var x=a.utils.availableWidth(h,k,g),y=a.utils.availableHeight(i,k,g);a.utils.initSVG(k),l.domain(c||d3.extent(b[0].values.map(n).concat(p))),l.range(r?e||[.5*x/b[0].values.length,x*(b[0].values.length-.5)/b[0].values.length]:e||[0,x]),m.domain(d||d3.extent(b[0].values.map(o).concat(q))).range(f||[y,0]),l.domain()[0]===l.domain()[1]&&l.domain(l.domain()[0]?[l.domain()[0]-.01*l.domain()[0],l.domain()[1]+.01*l.domain()[1]]:[-1,1]),m.domain()[0]===m.domain()[1]&&m.domain(m.domain()[0]?[m.domain()[0]+.01*m.domain()[0],m.domain()[1]-.01*m.domain()[1]]:[-1,1]);var z=k.selectAll("g.nv-wrap.nv-historicalBar-"+j).data([b[0].values]),A=z.enter().append("g").attr("class","nvd3 nv-wrap nv-historicalBar-"+j),B=A.append("defs"),C=A.append("g"),D=z.select("g");C.append("g").attr("class","nv-bars"),z.attr("transform","translate("+g.left+","+g.top+")"),k.on("click",function(a,b){u.chartClick({data:a,index:b,pos:d3.event,id:j})}),B.append("clipPath").attr("id","nv-chart-clip-path-"+j).append("rect"),z.select("#nv-chart-clip-path-"+j+" rect").attr("width",x).attr("height",y),D.attr("clip-path",s?"url(#nv-chart-clip-path-"+j+")":"");var E=z.select(".nv-bars").selectAll(".nv-bar").data(function(a){return a},function(a,b){return n(a,b)});E.exit().remove(),E.enter().append("rect").attr("x",0).attr("y",function(b,c){return a.utils.NaNtoZero(m(Math.max(0,o(b,c))))}).attr("height",function(b,c){return a.utils.NaNtoZero(Math.abs(m(o(b,c))-m(0)))}).attr("transform",function(a,c){return"translate("+(l(n(a,c))-x/b[0].values.length*.45)+",0)"}).on("mouseover",function(a,b){v&&(d3.select(this).classed("hover",!0),u.elementMouseover({data:a,index:b,color:d3.select(this).style("fill")}))}).on("mouseout",function(a,b){v&&(d3.select(this).classed("hover",!1),u.elementMouseout({data:a,index:b,color:d3.select(this).style("fill")}))}).on("mousemove",function(a,b){v&&u.elementMousemove({data:a,index:b,color:d3.select(this).style("fill")})}).on("click",function(a,b){v&&(u.elementClick({data:a,index:b,color:d3.select(this).style("fill")}),d3.event.stopPropagation())}).on("dblclick",function(a,b){v&&(u.elementDblClick({data:a,index:b,color:d3.select(this).style("fill")}),d3.event.stopPropagation())}),E.attr("fill",function(a,b){return t(a,b)}).attr("class",function(a,b,c){return(o(a,b)<0?"nv-bar negative":"nv-bar positive")+" nv-bar-"+c+"-"+b}).watchTransition(w,"bars").attr("transform",function(a,c){return"translate("+(l(n(a,c))-x/b[0].values.length*.45)+",0)"}).attr("width",x/b[0].values.length*.9),E.watchTransition(w,"bars").attr("y",function(b,c){var d=o(b,c)<0?m(0):m(0)-m(o(b,c))<1?m(0)-1:m(o(b,c));return a.utils.NaNtoZero(d)}).attr("height",function(b,c){return a.utils.NaNtoZero(Math.max(Math.abs(m(o(b,c))-m(0)),1))})}),w.renderEnd("historicalBar immediate"),b}var c,d,e,f,g={top:0,right:0,bottom:0,left:0},h=null,i=null,j=Math.floor(1e4*Math.random()),k=null,l=d3.scale.linear(),m=d3.scale.linear(),n=function(a){return a.x},o=function(a){return a.y},p=[],q=[0],r=!1,s=!0,t=a.utils.defaultColor(),u=d3.dispatch("chartClick","elementClick","elementDblClick","elementMouseover","elementMouseout","elementMousemove","renderEnd"),v=!0,w=a.utils.renderWatch(u,0);return b.highlightPoint=function(a,b){k.select(".nv-bars .nv-bar-0-"+a).classed("hover",b)},b.clearHighlights=function(){k.select(".nv-bars .nv-bar.hover").classed("hover",!1)},b.dispatch=u,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return h},set:function(a){h=a}},height:{get:function(){return i},set:function(a){i=a}},forceX:{get:function(){return p},set:function(a){p=a}},forceY:{get:function(){return q},set:function(a){q=a}},padData:{get:function(){return r},set:function(a){r=a}},x:{get:function(){return n},set:function(a){n=a}},y:{get:function(){return o},set:function(a){o=a}},xScale:{get:function(){return l},set:function(a){l=a}},yScale:{get:function(){return m},set:function(a){m=a}},xDomain:{get:function(){return c},set:function(a){c=a}},yDomain:{get:function(){return d},set:function(a){d=a}},xRange:{get:function(){return e},set:function(a){e=a}},yRange:{get:function(){return f},set:function(a){f=a}},clipEdge:{get:function(){return s},set:function(a){s=a}},id:{get:function(){return j},set:function(a){j=a}},interactive:{get:function(){return v},set:function(a){v=a}},margin:{get:function(){return g},set:function(a){g.top=void 0!==a.top?a.top:g.top,g.right=void 0!==a.right?a.right:g.right,g.bottom=void 0!==a.bottom?a.bottom:g.bottom,g.left=void 0!==a.left?a.left:g.left}},color:{get:function(){return t},set:function(b){t=a.utils.getColor(b)}}}),a.utils.initOptions(b),b},a.models.historicalBarChart=function(b){"use strict";function c(b){return b.each(function(k){z.reset(),z.models(f),q&&z.models(g),r&&z.models(h);var w=d3.select(this),A=this;a.utils.initSVG(w);var B=a.utils.availableWidth(n,w,l),C=a.utils.availableHeight(o,w,l);if(c.update=function(){w.transition().duration(y).call(c)},c.container=this,u.disabled=k.map(function(a){return!!a.disabled}),!v){var D;v={};for(D in u)v[D]=u[D]instanceof Array?u[D].slice(0):u[D]}if(!(k&&k.length&&k.filter(function(a){return a.values.length}).length))return a.utils.noData(c,w),c;w.selectAll(".nv-noData").remove(),d=f.xScale(),e=f.yScale();var E=w.selectAll("g.nv-wrap.nv-historicalBarChart").data([k]),F=E.enter().append("g").attr("class","nvd3 nv-wrap nv-historicalBarChart").append("g"),G=E.select("g");F.append("g").attr("class","nv-x nv-axis"),F.append("g").attr("class","nv-y nv-axis"),F.append("g").attr("class","nv-barsWrap"),F.append("g").attr("class","nv-legendWrap"),F.append("g").attr("class","nv-interactive"),p&&(i.width(B),G.select(".nv-legendWrap").datum(k).call(i),l.top!=i.height()&&(l.top=i.height(),C=a.utils.availableHeight(o,w,l)),E.select(".nv-legendWrap").attr("transform","translate(0,"+-l.top+")")),E.attr("transform","translate("+l.left+","+l.top+")"),s&&G.select(".nv-y.nv-axis").attr("transform","translate("+B+",0)"),t&&(j.width(B).height(C).margin({left:l.left,top:l.top}).svgContainer(w).xScale(d),E.select(".nv-interactive").call(j)),f.width(B).height(C).color(k.map(function(a,b){return a.color||m(a,b)}).filter(function(a,b){return!k[b].disabled}));var H=G.select(".nv-barsWrap").datum(k.filter(function(a){return!a.disabled}));H.transition().call(f),q&&(g.scale(d)._ticks(a.utils.calcTicksX(B/100,k)).tickSize(-C,0),G.select(".nv-x.nv-axis").attr("transform","translate(0,"+e.range()[0]+")"),G.select(".nv-x.nv-axis").transition().call(g)),r&&(h.scale(e)._ticks(a.utils.calcTicksY(C/36,k)).tickSize(-B,0),G.select(".nv-y.nv-axis").transition().call(h)),j.dispatch.on("elementMousemove",function(b){f.clearHighlights();var d,e,i,n=[];k.filter(function(a,b){return a.seriesIndex=b,!a.disabled}).forEach(function(g){e=a.interactiveBisect(g.values,b.pointXValue,c.x()),f.highlightPoint(e,!0);var h=g.values[e];void 0!==h&&(void 0===d&&(d=h),void 0===i&&(i=c.xScale()(c.x()(h,e))),n.push({key:g.key,value:c.y()(h,e),color:m(g,g.seriesIndex),data:g.values[e]}))});var o=g.tickFormat()(c.x()(d,e));j.tooltip.position({left:i+l.left,top:b.mouseY+l.top}).chartContainer(A.parentNode).valueFormatter(function(a){return h.tickFormat()(a)}).data({value:o,index:e,series:n})(),j.renderGuideLine(i)}),j.dispatch.on("elementMouseout",function(){x.tooltipHide(),f.clearHighlights()}),i.dispatch.on("legendClick",function(a){a.disabled=!a.disabled,k.filter(function(a){return!a.disabled}).length||k.map(function(a){return a.disabled=!1,E.selectAll(".nv-series").classed("disabled",!1),a}),u.disabled=k.map(function(a){return!!a.disabled}),x.stateChange(u),b.transition().call(c)}),i.dispatch.on("legendDblclick",function(a){k.forEach(function(a){a.disabled=!0}),a.disabled=!1,u.disabled=k.map(function(a){return!!a.disabled}),x.stateChange(u),c.update()}),x.on("changeState",function(a){"undefined"!=typeof a.disabled&&(k.forEach(function(b,c){b.disabled=a.disabled[c]}),u.disabled=a.disabled),c.update()})}),z.renderEnd("historicalBarChart immediate"),c}var d,e,f=b||a.models.historicalBar(),g=a.models.axis(),h=a.models.axis(),i=a.models.legend(),j=a.interactiveGuideline(),k=a.models.tooltip(),l={top:30,right:90,bottom:50,left:90},m=a.utils.defaultColor(),n=null,o=null,p=!1,q=!0,r=!0,s=!1,t=!1,u={},v=null,w=null,x=d3.dispatch("tooltipHide","stateChange","changeState","renderEnd"),y=250;g.orient("bottom").tickPadding(7),h.orient(s?"right":"left"),k.duration(0).headerEnabled(!1).valueFormatter(function(a,b){return h.tickFormat()(a,b)}).headerFormatter(function(a,b){return g.tickFormat()(a,b)});var z=a.utils.renderWatch(x,0);return f.dispatch.on("elementMouseover.tooltip",function(a){a.series={key:c.x()(a.data),value:c.y()(a.data),color:a.color},k.data(a).hidden(!1)}),f.dispatch.on("elementMouseout.tooltip",function(){k.hidden(!0)}),f.dispatch.on("elementMousemove.tooltip",function(){k.position({top:d3.event.pageY,left:d3.event.pageX})()}),c.dispatch=x,c.bars=f,c.legend=i,c.xAxis=g,c.yAxis=h,c.interactiveLayer=j,c.tooltip=k,c.options=a.utils.optionsFunc.bind(c),c._options=Object.create({},{width:{get:function(){return n},set:function(a){n=a}},height:{get:function(){return o},set:function(a){o=a}},showLegend:{get:function(){return p},set:function(a){p=a}},showXAxis:{get:function(){return q},set:function(a){q=a}},showYAxis:{get:function(){return r},set:function(a){r=a}},defaultState:{get:function(){return v},set:function(a){v=a}},noData:{get:function(){return w},set:function(a){w=a}},tooltips:{get:function(){return k.enabled()},set:function(b){a.deprecated("tooltips","use chart.tooltip.enabled() instead"),k.enabled(!!b)}},tooltipContent:{get:function(){return k.contentGenerator()},set:function(b){a.deprecated("tooltipContent","use chart.tooltip.contentGenerator() instead"),k.contentGenerator(b)}},margin:{get:function(){return l},set:function(a){l.top=void 0!==a.top?a.top:l.top,l.right=void 0!==a.right?a.right:l.right,l.bottom=void 0!==a.bottom?a.bottom:l.bottom,l.left=void 0!==a.left?a.left:l.left}},color:{get:function(){return m},set:function(b){m=a.utils.getColor(b),i.color(m),f.color(m)}},duration:{get:function(){return y},set:function(a){y=a,z.reset(y),h.duration(y),g.duration(y)}},rightAlignYAxis:{get:function(){return s},set:function(a){s=a,h.orient(a?"right":"left")}},useInteractiveGuideline:{get:function(){return t},set:function(a){t=a,a===!0&&c.interactive(!1)}}}),a.utils.inheritOptions(c,f),a.utils.initOptions(c),c},a.models.ohlcBarChart=function(){var b=a.models.historicalBarChart(a.models.ohlcBar());return b.useInteractiveGuideline(!0),b.interactiveLayer.tooltip.contentGenerator(function(a){var c=a.series[0].data,d=c.open'+a.value+"
open:"+b.yAxis.tickFormat()(c.open)+"
close:"+b.yAxis.tickFormat()(c.close)+"
high"+b.yAxis.tickFormat()(c.high)+"
low:"+b.yAxis.tickFormat()(c.low)+"
"}),b},a.models.candlestickBarChart=function(){var b=a.models.historicalBarChart(a.models.candlestickBar());return b.useInteractiveGuideline(!0),b.interactiveLayer.tooltip.contentGenerator(function(a){var c=a.series[0].data,d=c.open'+a.value+"
open:"+b.yAxis.tickFormat()(c.open)+"
close:"+b.yAxis.tickFormat()(c.close)+"
high"+b.yAxis.tickFormat()(c.high)+"
low:"+b.yAxis.tickFormat()(c.low)+"
"}),b},a.models.legend=function(){"use strict";function b(p){function q(a,b){return"furious"!=o?"#000":m?a.disengaged?"#000":"#fff":m?void 0:(a.color||(a.color=g(a,b)),a.disabled?a.color:"#fff")}function r(a,b){return m&&"furious"==o&&a.disengaged?"#eee":a.color||g(a,b)}function s(a){return m&&"furious"==o?1:a.disabled?0:1}return p.each(function(b){var g=d-c.left-c.right,p=d3.select(this);a.utils.initSVG(p);var t=p.selectAll("g.nv-legend").data([b]),u=t.enter().append("g").attr("class","nvd3 nv-legend").append("g"),v=t.select("g");t.attr("transform","translate("+c.left+","+c.top+")");var w,x,y=v.selectAll(".nv-series").data(function(a){return"furious"!=o?a:a.filter(function(a){return m?!0:!a.disengaged})}),z=y.enter().append("g").attr("class","nv-series");switch(o){case"furious":x=23;break;case"classic":x=20}if("classic"==o)z.append("circle").style("stroke-width",2).attr("class","nv-legend-symbol").attr("r",5),w=y.select("circle");else if("furious"==o){z.append("rect").style("stroke-width",2).attr("class","nv-legend-symbol").attr("rx",3).attr("ry",3),w=y.select(".nv-legend-symbol"),z.append("g").attr("class","nv-check-box").property("innerHTML",'').attr("transform","translate(-10,-8)scale(0.5)");var A=y.select(".nv-check-box");A.each(function(a,b){d3.select(this).selectAll("path").attr("stroke",q(a,b))})}z.append("text").attr("text-anchor","start").attr("class","nv-legend-text").attr("dy",".32em").attr("dx","8");var B=y.select("text.nv-legend-text");y.on("mouseover",function(a,b){n.legendMouseover(a,b)}).on("mouseout",function(a,b){n.legendMouseout(a,b)}).on("click",function(a,b){n.legendClick(a,b);var c=y.data();if(k){if("classic"==o)l?(c.forEach(function(a){a.disabled=!0}),a.disabled=!1):(a.disabled=!a.disabled,c.every(function(a){return a.disabled})&&c.forEach(function(a){a.disabled=!1}));else if("furious"==o)if(m)a.disengaged=!a.disengaged,a.userDisabled=void 0==a.userDisabled?!!a.disabled:a.userDisabled,a.disabled=a.disengaged||a.userDisabled;else if(!m){a.disabled=!a.disabled,a.userDisabled=a.disabled;var d=c.filter(function(a){return!a.disengaged});d.every(function(a){return a.userDisabled})&&c.forEach(function(a){a.disabled=a.userDisabled=!1})}n.stateChange({disabled:c.map(function(a){return!!a.disabled}),disengaged:c.map(function(a){return!!a.disengaged})})}}).on("dblclick",function(a,b){if(("furious"!=o||!m)&&(n.legendDblclick(a,b),k)){var c=y.data();c.forEach(function(a){a.disabled=!0,"furious"==o&&(a.userDisabled=a.disabled)}),a.disabled=!1,"furious"==o&&(a.userDisabled=a.disabled),n.stateChange({disabled:c.map(function(a){return!!a.disabled})})}}),y.classed("nv-disabled",function(a){return a.userDisabled}),y.exit().remove(),B.attr("fill",q).text(f);var C=0;if(h){var D=[];y.each(function(){var b,c=d3.select(this).select("text");try{if(b=c.node().getComputedTextLength(),0>=b)throw Error()}catch(d){b=a.utils.calcApproxTextWidth(c)}D.push(b+i)});var E=0,F=[];for(C=0;g>C&&Eg&&E>1;){F=[],E--;for(var G=0;G(F[G%E]||0)&&(F[G%E]=D[G]);C=F.reduce(function(a,b){return a+b})}for(var H=[],I=0,J=0;E>I;I++)H[I]=J,J+=F[I];y.attr("transform",function(a,b){return"translate("+H[b%E]+","+(5+Math.floor(b/E)*x)+")"}),j?v.attr("transform","translate("+(d-c.right-C)+","+c.top+")"):v.attr("transform","translate(0,"+c.top+")"),e=c.top+c.bottom+Math.ceil(D.length/E)*x}else{var K,L=5,M=5,N=0;y.attr("transform",function(){var a=d3.select(this).select("text").node().getComputedTextLength()+i;return K=M,dN&&(N=M),K+N>C&&(C=K+N),"translate("+K+","+L+")"}),v.attr("transform","translate("+(d-c.right-N)+","+c.top+")"),e=c.top+c.bottom+L+15}if("furious"==o){w.attr("width",function(a,b){return B[0][b].getComputedTextLength()+27}).attr("height",18).attr("y",-9).attr("x",-15),u.insert("rect",":first-child").attr("class","nv-legend-bg").attr("fill","#eee").attr("opacity",0);var O=v.select(".nv-legend-bg");O.transition().duration(300).attr("x",-x).attr("width",C+x-12).attr("height",e+10).attr("y",-c.top-10).attr("opacity",m?1:0)}w.style("fill",r).style("fill-opacity",s).style("stroke",r)}),b}var c={top:5,right:0,bottom:5,left:0},d=400,e=20,f=function(a){return a.key},g=a.utils.getColor(),h=!0,i=32,j=!0,k=!0,l=!1,m=!1,n=d3.dispatch("legendClick","legendDblclick","legendMouseover","legendMouseout","stateChange"),o="classic";return b.dispatch=n,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return d},set:function(a){d=a}},height:{get:function(){return e},set:function(a){e=a}},key:{get:function(){return f},set:function(a){f=a}},align:{get:function(){return h},set:function(a){h=a}},rightAlign:{get:function(){return j},set:function(a){j=a}},padding:{get:function(){return i},set:function(a){i=a}},updateState:{get:function(){return k},set:function(a){k=a}},radioButtonMode:{get:function(){return l},set:function(a){l=a}},expanded:{get:function(){return m},set:function(a){m=a}},vers:{get:function(){return o},set:function(a){o=a}},margin:{get:function(){return c},set:function(a){c.top=void 0!==a.top?a.top:c.top,c.right=void 0!==a.right?a.right:c.right,c.bottom=void 0!==a.bottom?a.bottom:c.bottom,c.left=void 0!==a.left?a.left:c.left}},color:{get:function(){return g},set:function(b){g=a.utils.getColor(b)}}}),a.utils.initOptions(b),b},a.models.line=function(){"use strict";function b(r){return v.reset(),v.models(e),r.each(function(b){i=d3.select(this);var r=a.utils.availableWidth(g,i,f),s=a.utils.availableHeight(h,i,f);a.utils.initSVG(i),c=e.xScale(),d=e.yScale(),t=t||c,u=u||d;var w=i.selectAll("g.nv-wrap.nv-line").data([b]),x=w.enter().append("g").attr("class","nvd3 nv-wrap nv-line"),y=x.append("defs"),z=x.append("g"),A=w.select("g");z.append("g").attr("class","nv-groups"),z.append("g").attr("class","nv-scatterWrap"),w.attr("transform","translate("+f.left+","+f.top+")"),e.width(r).height(s);var B=w.select(".nv-scatterWrap");B.call(e),y.append("clipPath").attr("id","nv-edge-clip-"+e.id()).append("rect"),w.select("#nv-edge-clip-"+e.id()+" rect").attr("width",r).attr("height",s>0?s:0),A.attr("clip-path",p?"url(#nv-edge-clip-"+e.id()+")":""),B.attr("clip-path",p?"url(#nv-edge-clip-"+e.id()+")":"");var C=w.select(".nv-groups").selectAll(".nv-group").data(function(a){return a},function(a){return a.key});C.enter().append("g").style("stroke-opacity",1e-6).style("stroke-width",function(a){return a.strokeWidth||j}).style("fill-opacity",1e-6),C.exit().remove(),C.attr("class",function(a,b){return(a.classed||"")+" nv-group nv-series-"+b}).classed("hover",function(a){return a.hover}).style("fill",function(a,b){return k(a,b)}).style("stroke",function(a,b){return k(a,b)}),C.watchTransition(v,"line: groups").style("stroke-opacity",1).style("fill-opacity",function(a){return a.fillOpacity||.5});var D=C.selectAll("path.nv-area").data(function(a){return o(a)?[a]:[]});D.enter().append("path").attr("class","nv-area").attr("d",function(b){return d3.svg.area().interpolate(q).defined(n).x(function(b,c){return a.utils.NaNtoZero(t(l(b,c)))}).y0(function(b,c){return a.utils.NaNtoZero(u(m(b,c)))}).y1(function(){return u(d.domain()[0]<=0?d.domain()[1]>=0?0:d.domain()[1]:d.domain()[0])}).apply(this,[b.values])}),C.exit().selectAll("path.nv-area").remove(),D.watchTransition(v,"line: areaPaths").attr("d",function(b){return d3.svg.area().interpolate(q).defined(n).x(function(b,d){return a.utils.NaNtoZero(c(l(b,d)))}).y0(function(b,c){return a.utils.NaNtoZero(d(m(b,c)))}).y1(function(){return d(d.domain()[0]<=0?d.domain()[1]>=0?0:d.domain()[1]:d.domain()[0])}).apply(this,[b.values])});var E=C.selectAll("path.nv-line").data(function(a){return[a.values]});E.enter().append("path").attr("class","nv-line").attr("d",d3.svg.line().interpolate(q).defined(n).x(function(b,c){return a.utils.NaNtoZero(t(l(b,c)))}).y(function(b,c){return a.utils.NaNtoZero(u(m(b,c)))})),E.watchTransition(v,"line: linePaths").attr("d",d3.svg.line().interpolate(q).defined(n).x(function(b,d){return a.utils.NaNtoZero(c(l(b,d)))}).y(function(b,c){return a.utils.NaNtoZero(d(m(b,c)))})),t=c.copy(),u=d.copy()}),v.renderEnd("line immediate"),b}var c,d,e=a.models.scatter(),f={top:0,right:0,bottom:0,left:0},g=960,h=500,i=null,j=1.5,k=a.utils.defaultColor(),l=function(a){return a.x},m=function(a){return a.y},n=function(a,b){return!isNaN(m(a,b))&&null!==m(a,b)},o=function(a){return a.area},p=!1,q="linear",r=250,s=d3.dispatch("elementClick","elementMouseover","elementMouseout","renderEnd");e.pointSize(16).pointDomain([16,256]);var t,u,v=a.utils.renderWatch(s,r);return b.dispatch=s,b.scatter=e,e.dispatch.on("elementClick",function(){s.elementClick.apply(this,arguments)}),e.dispatch.on("elementMouseover",function(){s.elementMouseover.apply(this,arguments)}),e.dispatch.on("elementMouseout",function(){s.elementMouseout.apply(this,arguments)}),b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return g},set:function(a){g=a}},height:{get:function(){return h},set:function(a){h=a}},defined:{get:function(){return n},set:function(a){n=a}},interpolate:{get:function(){return q},set:function(a){q=a}},clipEdge:{get:function(){return p},set:function(a){p=a}},margin:{get:function(){return f},set:function(a){f.top=void 0!==a.top?a.top:f.top,f.right=void 0!==a.right?a.right:f.right,f.bottom=void 0!==a.bottom?a.bottom:f.bottom,f.left=void 0!==a.left?a.left:f.left}},duration:{get:function(){return r},set:function(a){r=a,v.reset(r),e.duration(r)}},isArea:{get:function(){return o},set:function(a){o=d3.functor(a)}},x:{get:function(){return l},set:function(a){l=a,e.x(a)}},y:{get:function(){return m},set:function(a){m=a,e.y(a)}},color:{get:function(){return k},set:function(b){k=a.utils.getColor(b),e.color(k)}}}),a.utils.inheritOptions(b,e),a.utils.initOptions(b),b},a.models.lineChart=function(){"use strict";function b(j){return y.reset(),y.models(e),p&&y.models(f),q&&y.models(g),j.each(function(j){var v=d3.select(this),y=this;a.utils.initSVG(v);var B=a.utils.availableWidth(m,v,k),C=a.utils.availableHeight(n,v,k);if(b.update=function(){0===x?v.call(b):v.transition().duration(x).call(b)},b.container=this,t.setter(A(j),b.update).getter(z(j)).update(),t.disabled=j.map(function(a){return!!a.disabled}),!u){var D;u={};for(D in t)u[D]=t[D]instanceof Array?t[D].slice(0):t[D] -}if(!(j&&j.length&&j.filter(function(a){return a.values.length}).length))return a.utils.noData(b,v),b;v.selectAll(".nv-noData").remove(),c=e.xScale(),d=e.yScale();var E=v.selectAll("g.nv-wrap.nv-lineChart").data([j]),F=E.enter().append("g").attr("class","nvd3 nv-wrap nv-lineChart").append("g"),G=E.select("g");F.append("rect").style("opacity",0),F.append("g").attr("class","nv-x nv-axis"),F.append("g").attr("class","nv-y nv-axis"),F.append("g").attr("class","nv-linesWrap"),F.append("g").attr("class","nv-legendWrap"),F.append("g").attr("class","nv-interactive"),G.select("rect").attr("width",B).attr("height",C>0?C:0),o&&(h.width(B),G.select(".nv-legendWrap").datum(j).call(h),k.top!=h.height()&&(k.top=h.height(),C=a.utils.availableHeight(n,v,k)),E.select(".nv-legendWrap").attr("transform","translate(0,"+-k.top+")")),E.attr("transform","translate("+k.left+","+k.top+")"),r&&G.select(".nv-y.nv-axis").attr("transform","translate("+B+",0)"),s&&(i.width(B).height(C).margin({left:k.left,top:k.top}).svgContainer(v).xScale(c),E.select(".nv-interactive").call(i)),e.width(B).height(C).color(j.map(function(a,b){return a.color||l(a,b)}).filter(function(a,b){return!j[b].disabled}));var H=G.select(".nv-linesWrap").datum(j.filter(function(a){return!a.disabled}));H.call(e),p&&(f.scale(c)._ticks(a.utils.calcTicksX(B/100,j)).tickSize(-C,0),G.select(".nv-x.nv-axis").attr("transform","translate(0,"+d.range()[0]+")"),G.select(".nv-x.nv-axis").call(f)),q&&(g.scale(d)._ticks(a.utils.calcTicksY(C/36,j)).tickSize(-B,0),G.select(".nv-y.nv-axis").call(g)),h.dispatch.on("stateChange",function(a){for(var c in a)t[c]=a[c];w.stateChange(t),b.update()}),i.dispatch.on("elementMousemove",function(c){e.clearHighlights();var d,h,m,n=[];if(j.filter(function(a,b){return a.seriesIndex=b,!a.disabled}).forEach(function(f,g){h=a.interactiveBisect(f.values,c.pointXValue,b.x());var i=f.values[h],j=b.y()(i,h);null!=j&&e.highlightPoint(g,h,!0),void 0!==i&&(void 0===d&&(d=i),void 0===m&&(m=b.xScale()(b.x()(i,h))),n.push({key:f.key,value:j,color:l(f,f.seriesIndex)}))}),n.length>2){var o=b.yScale().invert(c.mouseY),p=Math.abs(b.yScale().domain()[0]-b.yScale().domain()[1]),q=.03*p,r=a.nearestValueIndex(n.map(function(a){return a.value}),o,q);null!==r&&(n[r].highlight=!0)}var s=f.tickFormat()(b.x()(d,h));i.tooltip.position({left:c.mouseX+k.left,top:c.mouseY+k.top}).chartContainer(y.parentNode).valueFormatter(function(a){return null==a?"N/A":g.tickFormat()(a)}).data({value:s,index:h,series:n})(),i.renderGuideLine(m)}),i.dispatch.on("elementClick",function(c){var d,f=[];j.filter(function(a,b){return a.seriesIndex=b,!a.disabled}).forEach(function(e){var g=a.interactiveBisect(e.values,c.pointXValue,b.x()),h=e.values[g];if("undefined"!=typeof h){"undefined"==typeof d&&(d=b.xScale()(b.x()(h,g)));var i=b.yScale()(b.y()(h,g));f.push({point:h,pointIndex:g,pos:[d,i],seriesIndex:e.seriesIndex,series:e})}}),e.dispatch.elementClick(f)}),i.dispatch.on("elementMouseout",function(){e.clearHighlights()}),w.on("changeState",function(a){"undefined"!=typeof a.disabled&&j.length===a.disabled.length&&(j.forEach(function(b,c){b.disabled=a.disabled[c]}),t.disabled=a.disabled),b.update()})}),y.renderEnd("lineChart immediate"),b}var c,d,e=a.models.line(),f=a.models.axis(),g=a.models.axis(),h=a.models.legend(),i=a.interactiveGuideline(),j=a.models.tooltip(),k={top:30,right:20,bottom:50,left:60},l=a.utils.defaultColor(),m=null,n=null,o=!0,p=!0,q=!0,r=!1,s=!1,t=a.utils.state(),u=null,v=null,w=d3.dispatch("tooltipShow","tooltipHide","stateChange","changeState","renderEnd"),x=250;f.orient("bottom").tickPadding(7),g.orient(r?"right":"left"),j.valueFormatter(function(a,b){return g.tickFormat()(a,b)}).headerFormatter(function(a,b){return f.tickFormat()(a,b)});var y=a.utils.renderWatch(w,x),z=function(a){return function(){return{active:a.map(function(a){return!a.disabled})}}},A=function(a){return function(b){void 0!==b.active&&a.forEach(function(a,c){a.disabled=!b.active[c]})}};return e.dispatch.on("elementMouseover.tooltip",function(a){j.data(a).position(a.pos).hidden(!1)}),e.dispatch.on("elementMouseout.tooltip",function(){j.hidden(!0)}),b.dispatch=w,b.lines=e,b.legend=h,b.xAxis=f,b.yAxis=g,b.interactiveLayer=i,b.tooltip=j,b.dispatch=w,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return m},set:function(a){m=a}},height:{get:function(){return n},set:function(a){n=a}},showLegend:{get:function(){return o},set:function(a){o=a}},showXAxis:{get:function(){return p},set:function(a){p=a}},showYAxis:{get:function(){return q},set:function(a){q=a}},defaultState:{get:function(){return u},set:function(a){u=a}},noData:{get:function(){return v},set:function(a){v=a}},tooltips:{get:function(){return j.enabled()},set:function(b){a.deprecated("tooltips","use chart.tooltip.enabled() instead"),j.enabled(!!b)}},tooltipContent:{get:function(){return j.contentGenerator()},set:function(b){a.deprecated("tooltipContent","use chart.tooltip.contentGenerator() instead"),j.contentGenerator(b)}},margin:{get:function(){return k},set:function(a){k.top=void 0!==a.top?a.top:k.top,k.right=void 0!==a.right?a.right:k.right,k.bottom=void 0!==a.bottom?a.bottom:k.bottom,k.left=void 0!==a.left?a.left:k.left}},duration:{get:function(){return x},set:function(a){x=a,y.reset(x),e.duration(x),f.duration(x),g.duration(x)}},color:{get:function(){return l},set:function(b){l=a.utils.getColor(b),h.color(l),e.color(l)}},rightAlignYAxis:{get:function(){return r},set:function(a){r=a,g.orient(r?"right":"left")}},useInteractiveGuideline:{get:function(){return s},set:function(a){s=a,s&&(e.interactive(!1),e.useVoronoi(!1))}}}),a.utils.inheritOptions(b,e),a.utils.initOptions(b),b},a.models.linePlusBarChart=function(){"use strict";function b(v){return v.each(function(v){function J(a){var b=+("e"==a),c=b?1:-1,d=X/3;return"M"+.5*c+","+d+"A6,6 0 0 "+b+" "+6.5*c+","+(d+6)+"V"+(2*d-6)+"A6,6 0 0 "+b+" "+.5*c+","+2*d+"ZM"+2.5*c+","+(d+8)+"V"+(2*d-8)+"M"+4.5*c+","+(d+8)+"V"+(2*d-8)}function S(){u.empty()||u.extent(I),kb.data([u.empty()?e.domain():I]).each(function(a){var b=e(a[0])-e.range()[0],c=e.range()[1]-e(a[1]);d3.select(this).select(".left").attr("width",0>b?0:b),d3.select(this).select(".right").attr("x",e(a[1])).attr("width",0>c?0:c)})}function T(){I=u.empty()?null:u.extent(),c=u.empty()?e.domain():u.extent(),K.brush({extent:c,brush:u}),S(),l.width(V).height(W).color(v.map(function(a,b){return a.color||C(a,b)}).filter(function(a,b){return!v[b].disabled&&v[b].bar})),j.width(V).height(W).color(v.map(function(a,b){return a.color||C(a,b)}).filter(function(a,b){return!v[b].disabled&&!v[b].bar}));var b=db.select(".nv-focus .nv-barsWrap").datum(Z.length?Z.map(function(a){return{key:a.key,values:a.values.filter(function(a,b){return l.x()(a,b)>=c[0]&&l.x()(a,b)<=c[1]})}}):[{values:[]}]),h=db.select(".nv-focus .nv-linesWrap").datum($[0].disabled?[{values:[]}]:$.map(function(a){return{area:a.area,fillOpacity:a.fillOpacity,key:a.key,values:a.values.filter(function(a,b){return j.x()(a,b)>=c[0]&&j.x()(a,b)<=c[1]})}}));d=Z.length?l.xScale():j.xScale(),n.scale(d)._ticks(a.utils.calcTicksX(V/100,v)).tickSize(-W,0),n.domain([Math.ceil(c[0]),Math.floor(c[1])]),db.select(".nv-x.nv-axis").transition().duration(L).call(n),b.transition().duration(L).call(l),h.transition().duration(L).call(j),db.select(".nv-focus .nv-x.nv-axis").attr("transform","translate(0,"+f.range()[0]+")"),p.scale(f)._ticks(a.utils.calcTicksY(W/36,v)).tickSize(-V,0),q.scale(g)._ticks(a.utils.calcTicksY(W/36,v)).tickSize(Z.length?0:-V,0),db.select(".nv-focus .nv-y1.nv-axis").style("opacity",Z.length?1:0),db.select(".nv-focus .nv-y2.nv-axis").style("opacity",$.length&&!$[0].disabled?1:0).attr("transform","translate("+d.range()[1]+",0)"),db.select(".nv-focus .nv-y1.nv-axis").transition().duration(L).call(p),db.select(".nv-focus .nv-y2.nv-axis").transition().duration(L).call(q)}var U=d3.select(this);a.utils.initSVG(U);var V=a.utils.availableWidth(y,U,w),W=a.utils.availableHeight(z,U,w)-(E?H:0),X=H-x.top-x.bottom;if(b.update=function(){U.transition().duration(L).call(b)},b.container=this,M.setter(R(v),b.update).getter(Q(v)).update(),M.disabled=v.map(function(a){return!!a.disabled}),!N){var Y;N={};for(Y in M)N[Y]=M[Y]instanceof Array?M[Y].slice(0):M[Y]}if(!(v&&v.length&&v.filter(function(a){return a.values.length}).length))return a.utils.noData(b,U),b;U.selectAll(".nv-noData").remove();var Z=v.filter(function(a){return!a.disabled&&a.bar}),$=v.filter(function(a){return!a.bar});d=l.xScale(),e=o.scale(),f=l.yScale(),g=j.yScale(),h=m.yScale(),i=k.yScale();var _=v.filter(function(a){return!a.disabled&&a.bar}).map(function(a){return a.values.map(function(a,b){return{x:A(a,b),y:B(a,b)}})}),ab=v.filter(function(a){return!a.disabled&&!a.bar}).map(function(a){return a.values.map(function(a,b){return{x:A(a,b),y:B(a,b)}})});d.range([0,V]),e.domain(d3.extent(d3.merge(_.concat(ab)),function(a){return a.x})).range([0,V]);var bb=U.selectAll("g.nv-wrap.nv-linePlusBar").data([v]),cb=bb.enter().append("g").attr("class","nvd3 nv-wrap nv-linePlusBar").append("g"),db=bb.select("g");cb.append("g").attr("class","nv-legendWrap");var eb=cb.append("g").attr("class","nv-focus");eb.append("g").attr("class","nv-x nv-axis"),eb.append("g").attr("class","nv-y1 nv-axis"),eb.append("g").attr("class","nv-y2 nv-axis"),eb.append("g").attr("class","nv-barsWrap"),eb.append("g").attr("class","nv-linesWrap");var fb=cb.append("g").attr("class","nv-context");if(fb.append("g").attr("class","nv-x nv-axis"),fb.append("g").attr("class","nv-y1 nv-axis"),fb.append("g").attr("class","nv-y2 nv-axis"),fb.append("g").attr("class","nv-barsWrap"),fb.append("g").attr("class","nv-linesWrap"),fb.append("g").attr("class","nv-brushBackground"),fb.append("g").attr("class","nv-x nv-brush"),D){var gb=t.align()?V/2:V,hb=t.align()?gb:0;t.width(gb),db.select(".nv-legendWrap").datum(v.map(function(a){return a.originalKey=void 0===a.originalKey?a.key:a.originalKey,a.key=a.originalKey+(a.bar?O:P),a})).call(t),w.top!=t.height()&&(w.top=t.height(),W=a.utils.availableHeight(z,U,w)-H),db.select(".nv-legendWrap").attr("transform","translate("+hb+","+-w.top+")")}bb.attr("transform","translate("+w.left+","+w.top+")"),db.select(".nv-context").style("display",E?"initial":"none"),m.width(V).height(X).color(v.map(function(a,b){return a.color||C(a,b)}).filter(function(a,b){return!v[b].disabled&&v[b].bar})),k.width(V).height(X).color(v.map(function(a,b){return a.color||C(a,b)}).filter(function(a,b){return!v[b].disabled&&!v[b].bar}));var ib=db.select(".nv-context .nv-barsWrap").datum(Z.length?Z:[{values:[]}]),jb=db.select(".nv-context .nv-linesWrap").datum($[0].disabled?[{values:[]}]:$);db.select(".nv-context").attr("transform","translate(0,"+(W+w.bottom+x.top)+")"),ib.transition().call(m),jb.transition().call(k),G&&(o._ticks(a.utils.calcTicksX(V/100,v)).tickSize(-X,0),db.select(".nv-context .nv-x.nv-axis").attr("transform","translate(0,"+h.range()[0]+")"),db.select(".nv-context .nv-x.nv-axis").transition().call(o)),F&&(r.scale(h)._ticks(X/36).tickSize(-V,0),s.scale(i)._ticks(X/36).tickSize(Z.length?0:-V,0),db.select(".nv-context .nv-y3.nv-axis").style("opacity",Z.length?1:0).attr("transform","translate(0,"+e.range()[0]+")"),db.select(".nv-context .nv-y2.nv-axis").style("opacity",$.length?1:0).attr("transform","translate("+e.range()[1]+",0)"),db.select(".nv-context .nv-y1.nv-axis").transition().call(r),db.select(".nv-context .nv-y2.nv-axis").transition().call(s)),u.x(e).on("brush",T),I&&u.extent(I);var kb=db.select(".nv-brushBackground").selectAll("g").data([I||u.extent()]),lb=kb.enter().append("g");lb.append("rect").attr("class","left").attr("x",0).attr("y",0).attr("height",X),lb.append("rect").attr("class","right").attr("x",0).attr("y",0).attr("height",X);var mb=db.select(".nv-x.nv-brush").call(u);mb.selectAll("rect").attr("height",X),mb.selectAll(".resize").append("path").attr("d",J),t.dispatch.on("stateChange",function(a){for(var c in a)M[c]=a[c];K.stateChange(M),b.update()}),K.on("changeState",function(a){"undefined"!=typeof a.disabled&&(v.forEach(function(b,c){b.disabled=a.disabled[c]}),M.disabled=a.disabled),b.update()}),T()}),b}var c,d,e,f,g,h,i,j=a.models.line(),k=a.models.line(),l=a.models.historicalBar(),m=a.models.historicalBar(),n=a.models.axis(),o=a.models.axis(),p=a.models.axis(),q=a.models.axis(),r=a.models.axis(),s=a.models.axis(),t=a.models.legend(),u=d3.svg.brush(),v=a.models.tooltip(),w={top:30,right:30,bottom:30,left:60},x={top:0,right:30,bottom:20,left:60},y=null,z=null,A=function(a){return a.x},B=function(a){return a.y},C=a.utils.defaultColor(),D=!0,E=!0,F=!1,G=!0,H=50,I=null,J=null,K=d3.dispatch("brush","stateChange","changeState"),L=0,M=a.utils.state(),N=null,O=" (left axis)",P=" (right axis)";j.clipEdge(!0),k.interactive(!1),n.orient("bottom").tickPadding(5),p.orient("left"),q.orient("right"),o.orient("bottom").tickPadding(5),r.orient("left"),s.orient("right"),v.headerEnabled(!0).headerFormatter(function(a,b){return n.tickFormat()(a,b)});var Q=function(a){return function(){return{active:a.map(function(a){return!a.disabled})}}},R=function(a){return function(b){void 0!==b.active&&a.forEach(function(a,c){a.disabled=!b.active[c]})}};return j.dispatch.on("elementMouseover.tooltip",function(a){v.duration(100).valueFormatter(function(a,b){return q.tickFormat()(a,b)}).data(a).position(a.pos).hidden(!1)}),j.dispatch.on("elementMouseout.tooltip",function(){v.hidden(!0)}),l.dispatch.on("elementMouseover.tooltip",function(a){a.value=b.x()(a.data),a.series={value:b.y()(a.data),color:a.color},v.duration(0).valueFormatter(function(a,b){return p.tickFormat()(a,b)}).data(a).hidden(!1)}),l.dispatch.on("elementMouseout.tooltip",function(){v.hidden(!0)}),l.dispatch.on("elementMousemove.tooltip",function(){v.position({top:d3.event.pageY,left:d3.event.pageX})()}),b.dispatch=K,b.legend=t,b.lines=j,b.lines2=k,b.bars=l,b.bars2=m,b.xAxis=n,b.x2Axis=o,b.y1Axis=p,b.y2Axis=q,b.y3Axis=r,b.y4Axis=s,b.tooltip=v,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return y},set:function(a){y=a}},height:{get:function(){return z},set:function(a){z=a}},showLegend:{get:function(){return D},set:function(a){D=a}},brushExtent:{get:function(){return I},set:function(a){I=a}},noData:{get:function(){return J},set:function(a){J=a}},focusEnable:{get:function(){return E},set:function(a){E=a}},focusHeight:{get:function(){return H},set:function(a){H=a}},focusShowAxisX:{get:function(){return G},set:function(a){G=a}},focusShowAxisY:{get:function(){return F},set:function(a){F=a}},legendLeftAxisHint:{get:function(){return O},set:function(a){O=a}},legendRightAxisHint:{get:function(){return P},set:function(a){P=a}},tooltips:{get:function(){return v.enabled()},set:function(b){a.deprecated("tooltips","use chart.tooltip.enabled() instead"),v.enabled(!!b)}},tooltipContent:{get:function(){return v.contentGenerator()},set:function(b){a.deprecated("tooltipContent","use chart.tooltip.contentGenerator() instead"),v.contentGenerator(b)}},margin:{get:function(){return w},set:function(a){w.top=void 0!==a.top?a.top:w.top,w.right=void 0!==a.right?a.right:w.right,w.bottom=void 0!==a.bottom?a.bottom:w.bottom,w.left=void 0!==a.left?a.left:w.left}},duration:{get:function(){return L},set:function(a){L=a}},color:{get:function(){return C},set:function(b){C=a.utils.getColor(b),t.color(C)}},x:{get:function(){return A},set:function(a){A=a,j.x(a),k.x(a),l.x(a),m.x(a)}},y:{get:function(){return B},set:function(a){B=a,j.y(a),k.y(a),l.y(a),m.y(a)}}}),a.utils.inheritOptions(b,j),a.utils.initOptions(b),b},a.models.lineWithFocusChart=function(){"use strict";function b(o){return o.each(function(o){function z(a){var b=+("e"==a),c=b?1:-1,d=M/3;return"M"+.5*c+","+d+"A6,6 0 0 "+b+" "+6.5*c+","+(d+6)+"V"+(2*d-6)+"A6,6 0 0 "+b+" "+.5*c+","+2*d+"ZM"+2.5*c+","+(d+8)+"V"+(2*d-8)+"M"+4.5*c+","+(d+8)+"V"+(2*d-8)}function G(){n.empty()||n.extent(y),U.data([n.empty()?e.domain():y]).each(function(a){var b=e(a[0])-c.range()[0],d=K-e(a[1]);d3.select(this).select(".left").attr("width",0>b?0:b),d3.select(this).select(".right").attr("x",e(a[1])).attr("width",0>d?0:d)})}function H(){y=n.empty()?null:n.extent();var a=n.empty()?e.domain():n.extent();if(!(Math.abs(a[0]-a[1])<=1)){A.brush({extent:a,brush:n}),G();var b=Q.select(".nv-focus .nv-linesWrap").datum(o.filter(function(a){return!a.disabled}).map(function(b){return{key:b.key,area:b.area,values:b.values.filter(function(b,c){return g.x()(b,c)>=a[0]&&g.x()(b,c)<=a[1]})}}));b.transition().duration(B).call(g),Q.select(".nv-focus .nv-x.nv-axis").transition().duration(B).call(i),Q.select(".nv-focus .nv-y.nv-axis").transition().duration(B).call(j)}}var I=d3.select(this),J=this;a.utils.initSVG(I);var K=a.utils.availableWidth(t,I,q),L=a.utils.availableHeight(u,I,q)-v,M=v-r.top-r.bottom;if(b.update=function(){I.transition().duration(B).call(b)},b.container=this,C.setter(F(o),b.update).getter(E(o)).update(),C.disabled=o.map(function(a){return!!a.disabled}),!D){var N;D={};for(N in C)D[N]=C[N]instanceof Array?C[N].slice(0):C[N]}if(!(o&&o.length&&o.filter(function(a){return a.values.length}).length))return a.utils.noData(b,I),b;I.selectAll(".nv-noData").remove(),c=g.xScale(),d=g.yScale(),e=h.xScale(),f=h.yScale();var O=I.selectAll("g.nv-wrap.nv-lineWithFocusChart").data([o]),P=O.enter().append("g").attr("class","nvd3 nv-wrap nv-lineWithFocusChart").append("g"),Q=O.select("g");P.append("g").attr("class","nv-legendWrap");var R=P.append("g").attr("class","nv-focus");R.append("g").attr("class","nv-x nv-axis"),R.append("g").attr("class","nv-y nv-axis"),R.append("g").attr("class","nv-linesWrap"),R.append("g").attr("class","nv-interactive");var S=P.append("g").attr("class","nv-context");S.append("g").attr("class","nv-x nv-axis"),S.append("g").attr("class","nv-y nv-axis"),S.append("g").attr("class","nv-linesWrap"),S.append("g").attr("class","nv-brushBackground"),S.append("g").attr("class","nv-x nv-brush"),x&&(m.width(K),Q.select(".nv-legendWrap").datum(o).call(m),q.top!=m.height()&&(q.top=m.height(),L=a.utils.availableHeight(u,I,q)-v),Q.select(".nv-legendWrap").attr("transform","translate(0,"+-q.top+")")),O.attr("transform","translate("+q.left+","+q.top+")"),w&&(p.width(K).height(L).margin({left:q.left,top:q.top}).svgContainer(I).xScale(c),O.select(".nv-interactive").call(p)),g.width(K).height(L).color(o.map(function(a,b){return a.color||s(a,b)}).filter(function(a,b){return!o[b].disabled})),h.defined(g.defined()).width(K).height(M).color(o.map(function(a,b){return a.color||s(a,b)}).filter(function(a,b){return!o[b].disabled})),Q.select(".nv-context").attr("transform","translate(0,"+(L+q.bottom+r.top)+")");var T=Q.select(".nv-context .nv-linesWrap").datum(o.filter(function(a){return!a.disabled}));d3.transition(T).call(h),i.scale(c)._ticks(a.utils.calcTicksX(K/100,o)).tickSize(-L,0),j.scale(d)._ticks(a.utils.calcTicksY(L/36,o)).tickSize(-K,0),Q.select(".nv-focus .nv-x.nv-axis").attr("transform","translate(0,"+L+")"),n.x(e).on("brush",function(){H()}),y&&n.extent(y);var U=Q.select(".nv-brushBackground").selectAll("g").data([y||n.extent()]),V=U.enter().append("g");V.append("rect").attr("class","left").attr("x",0).attr("y",0).attr("height",M),V.append("rect").attr("class","right").attr("x",0).attr("y",0).attr("height",M);var W=Q.select(".nv-x.nv-brush").call(n);W.selectAll("rect").attr("height",M),W.selectAll(".resize").append("path").attr("d",z),H(),k.scale(e)._ticks(a.utils.calcTicksX(K/100,o)).tickSize(-M,0),Q.select(".nv-context .nv-x.nv-axis").attr("transform","translate(0,"+f.range()[0]+")"),d3.transition(Q.select(".nv-context .nv-x.nv-axis")).call(k),l.scale(f)._ticks(a.utils.calcTicksY(M/36,o)).tickSize(-K,0),d3.transition(Q.select(".nv-context .nv-y.nv-axis")).call(l),Q.select(".nv-context .nv-x.nv-axis").attr("transform","translate(0,"+f.range()[0]+")"),m.dispatch.on("stateChange",function(a){for(var c in a)C[c]=a[c];A.stateChange(C),b.update()}),p.dispatch.on("elementMousemove",function(c){g.clearHighlights();var d,f,h,k=[];if(o.filter(function(a,b){return a.seriesIndex=b,!a.disabled}).forEach(function(i,j){var l=n.empty()?e.domain():n.extent(),m=i.values.filter(function(a,b){return g.x()(a,b)>=l[0]&&g.x()(a,b)<=l[1]});f=a.interactiveBisect(m,c.pointXValue,g.x());var o=m[f],p=b.y()(o,f);null!=p&&g.highlightPoint(j,f,!0),void 0!==o&&(void 0===d&&(d=o),void 0===h&&(h=b.xScale()(b.x()(o,f))),k.push({key:i.key,value:b.y()(o,f),color:s(i,i.seriesIndex)}))}),k.length>2){var l=b.yScale().invert(c.mouseY),m=Math.abs(b.yScale().domain()[0]-b.yScale().domain()[1]),r=.03*m,t=a.nearestValueIndex(k.map(function(a){return a.value}),l,r);null!==t&&(k[t].highlight=!0)}var u=i.tickFormat()(b.x()(d,f));p.tooltip.position({left:c.mouseX+q.left,top:c.mouseY+q.top}).chartContainer(J.parentNode).valueFormatter(function(a){return null==a?"N/A":j.tickFormat()(a)}).data({value:u,index:f,series:k})(),p.renderGuideLine(h)}),p.dispatch.on("elementMouseout",function(){g.clearHighlights()}),A.on("changeState",function(a){"undefined"!=typeof a.disabled&&o.forEach(function(b,c){b.disabled=a.disabled[c]}),b.update()})}),b}var c,d,e,f,g=a.models.line(),h=a.models.line(),i=a.models.axis(),j=a.models.axis(),k=a.models.axis(),l=a.models.axis(),m=a.models.legend(),n=d3.svg.brush(),o=a.models.tooltip(),p=a.interactiveGuideline(),q={top:30,right:30,bottom:30,left:60},r={top:0,right:30,bottom:20,left:60},s=a.utils.defaultColor(),t=null,u=null,v=50,w=!1,x=!0,y=null,z=null,A=d3.dispatch("brush","stateChange","changeState"),B=250,C=a.utils.state(),D=null;g.clipEdge(!0).duration(0),h.interactive(!1),i.orient("bottom").tickPadding(5),j.orient("left"),k.orient("bottom").tickPadding(5),l.orient("left"),o.valueFormatter(function(a,b){return j.tickFormat()(a,b)}).headerFormatter(function(a,b){return i.tickFormat()(a,b)});var E=function(a){return function(){return{active:a.map(function(a){return!a.disabled})}}},F=function(a){return function(b){void 0!==b.active&&a.forEach(function(a,c){a.disabled=!b.active[c]})}};return g.dispatch.on("elementMouseover.tooltip",function(a){o.data(a).position(a.pos).hidden(!1)}),g.dispatch.on("elementMouseout.tooltip",function(){o.hidden(!0)}),b.dispatch=A,b.legend=m,b.lines=g,b.lines2=h,b.xAxis=i,b.yAxis=j,b.x2Axis=k,b.y2Axis=l,b.interactiveLayer=p,b.tooltip=o,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return t},set:function(a){t=a}},height:{get:function(){return u},set:function(a){u=a}},focusHeight:{get:function(){return v},set:function(a){v=a}},showLegend:{get:function(){return x},set:function(a){x=a}},brushExtent:{get:function(){return y},set:function(a){y=a}},defaultState:{get:function(){return D},set:function(a){D=a}},noData:{get:function(){return z},set:function(a){z=a}},tooltips:{get:function(){return o.enabled()},set:function(b){a.deprecated("tooltips","use chart.tooltip.enabled() instead"),o.enabled(!!b)}},tooltipContent:{get:function(){return o.contentGenerator()},set:function(b){a.deprecated("tooltipContent","use chart.tooltip.contentGenerator() instead"),o.contentGenerator(b)}},margin:{get:function(){return q},set:function(a){q.top=void 0!==a.top?a.top:q.top,q.right=void 0!==a.right?a.right:q.right,q.bottom=void 0!==a.bottom?a.bottom:q.bottom,q.left=void 0!==a.left?a.left:q.left}},color:{get:function(){return s},set:function(b){s=a.utils.getColor(b),m.color(s)}},interpolate:{get:function(){return g.interpolate()},set:function(a){g.interpolate(a),h.interpolate(a)}},xTickFormat:{get:function(){return i.tickFormat()},set:function(a){i.tickFormat(a),k.tickFormat(a)}},yTickFormat:{get:function(){return j.tickFormat()},set:function(a){j.tickFormat(a),l.tickFormat(a)}},duration:{get:function(){return B},set:function(a){B=a,j.duration(B),l.duration(B),i.duration(B),k.duration(B)}},x:{get:function(){return g.x()},set:function(a){g.x(a),h.x(a)}},y:{get:function(){return g.y()},set:function(a){g.y(a),h.y(a)}},useInteractiveGuideline:{get:function(){return w},set:function(a){w=a,w&&(g.interactive(!1),g.useVoronoi(!1))}}}),a.utils.inheritOptions(b,g),a.utils.initOptions(b),b},a.models.multiBar=function(){"use strict";function b(E){return C.reset(),E.each(function(b){var E=k-j.left-j.right,F=l-j.top-j.bottom;p=d3.select(this),a.utils.initSVG(p);var G=0;if(x&&b.length&&(x=[{values:b[0].values.map(function(a){return{x:a.x,y:0,series:a.series,size:.01}})}]),u){var H=d3.layout.stack().offset(v).values(function(a){return a.values}).y(r)(!b.length&&x?x:b);H.forEach(function(a,c){a.nonStackable?(b[c].nonStackableSeries=G++,H[c]=b[c]):c>0&&H[c-1].nonStackable&&H[c].values.map(function(a,b){a.y0-=H[c-1].values[b].y,a.y1=a.y0+a.y})}),b=H}b.forEach(function(a,b){a.values.forEach(function(c){c.series=b,c.key=a.key})}),u&&b[0].values.map(function(a,c){var d=0,e=0;b.map(function(a,f){if(!b[f].nonStackable){var g=a.values[c];g.size=Math.abs(g.y),g.y<0?(g.y1=e,e-=g.size):(g.y1=g.size+d,d+=g.size)}})});var I=d&&e?[]:b.map(function(a,b){return a.values.map(function(a,c){return{x:q(a,c),y:r(a,c),y0:a.y0,y1:a.y1,idx:b}})});m.domain(d||d3.merge(I).map(function(a){return a.x})).rangeBands(f||[0,E],A),n.domain(e||d3.extent(d3.merge(I).map(function(a){var c=a.y;return u&&!b[a.idx].nonStackable&&(c=a.y>0?a.y1:a.y1+a.y),c}).concat(s))).range(g||[F,0]),m.domain()[0]===m.domain()[1]&&m.domain(m.domain()[0]?[m.domain()[0]-.01*m.domain()[0],m.domain()[1]+.01*m.domain()[1]]:[-1,1]),n.domain()[0]===n.domain()[1]&&n.domain(n.domain()[0]?[n.domain()[0]+.01*n.domain()[0],n.domain()[1]-.01*n.domain()[1]]:[-1,1]),h=h||m,i=i||n;var J=p.selectAll("g.nv-wrap.nv-multibar").data([b]),K=J.enter().append("g").attr("class","nvd3 nv-wrap nv-multibar"),L=K.append("defs"),M=K.append("g"),N=J.select("g");M.append("g").attr("class","nv-groups"),J.attr("transform","translate("+j.left+","+j.top+")"),L.append("clipPath").attr("id","nv-edge-clip-"+o).append("rect"),J.select("#nv-edge-clip-"+o+" rect").attr("width",E).attr("height",F),N.attr("clip-path",t?"url(#nv-edge-clip-"+o+")":"");var O=J.select(".nv-groups").selectAll(".nv-group").data(function(a){return a},function(a,b){return b});O.enter().append("g").style("stroke-opacity",1e-6).style("fill-opacity",1e-6);var P=C.transition(O.exit().selectAll("rect.nv-bar"),"multibarExit",Math.min(100,z)).attr("y",function(a){var c=i(0)||0;return u&&b[a.series]&&!b[a.series].nonStackable&&(c=i(a.y0)),c}).attr("height",0).remove();P.delay&&P.delay(function(a,b){var c=b*(z/(D+1))-b;return c}),O.attr("class",function(a,b){return"nv-group nv-series-"+b}).classed("hover",function(a){return a.hover}).style("fill",function(a,b){return w(a,b)}).style("stroke",function(a,b){return w(a,b)}),O.style("stroke-opacity",1).style("fill-opacity",.75);var Q=O.selectAll("rect.nv-bar").data(function(a){return x&&!b.length?x.values:a.values});Q.exit().remove();Q.enter().append("rect").attr("class",function(a,b){return r(a,b)<0?"nv-bar negative":"nv-bar positive"}).attr("x",function(a,c,d){return u&&!b[d].nonStackable?0:d*m.rangeBand()/b.length}).attr("y",function(a,c,d){return i(u&&!b[d].nonStackable?a.y0:0)||0}).attr("height",0).attr("width",function(a,c,d){return m.rangeBand()/(u&&!b[d].nonStackable?1:b.length)}).attr("transform",function(a,b){return"translate("+m(q(a,b))+",0)"});Q.style("fill",function(a,b,c){return w(a,c,b)}).style("stroke",function(a,b,c){return w(a,c,b)}).on("mouseover",function(a,b){d3.select(this).classed("hover",!0),B.elementMouseover({data:a,index:b,color:d3.select(this).style("fill")})}).on("mouseout",function(a,b){d3.select(this).classed("hover",!1),B.elementMouseout({data:a,index:b,color:d3.select(this).style("fill")})}).on("mousemove",function(a,b){B.elementMousemove({data:a,index:b,color:d3.select(this).style("fill")})}).on("click",function(a,b){B.elementClick({data:a,index:b,color:d3.select(this).style("fill")}),d3.event.stopPropagation()}).on("dblclick",function(a,b){B.elementDblClick({data:a,index:b,color:d3.select(this).style("fill")}),d3.event.stopPropagation()}),Q.attr("class",function(a,b){return r(a,b)<0?"nv-bar negative":"nv-bar positive"}).attr("transform",function(a,b){return"translate("+m(q(a,b))+",0)"}),y&&(c||(c=b.map(function(){return!0})),Q.style("fill",function(a,b,d){return d3.rgb(y(a,b)).darker(c.map(function(a,b){return b}).filter(function(a,b){return!c[b]})[d]).toString()}).style("stroke",function(a,b,d){return d3.rgb(y(a,b)).darker(c.map(function(a,b){return b}).filter(function(a,b){return!c[b]})[d]).toString()}));var R=Q.watchTransition(C,"multibar",Math.min(250,z)).delay(function(a,c){return c*z/b[0].values.length});u?R.attr("y",function(a,c,d){var e=0;return e=b[d].nonStackable?r(a,c)<0?n(0):n(0)-n(r(a,c))<-1?n(0)-1:n(r(a,c))||0:n(a.y1)}).attr("height",function(a,c,d){return b[d].nonStackable?Math.max(Math.abs(n(r(a,c))-n(0)),1)||0:Math.max(Math.abs(n(a.y+a.y0)-n(a.y0)),1)}).attr("x",function(a,c,d){var e=0;return b[d].nonStackable&&(e=a.series*m.rangeBand()/b.length,b.length!==G&&(e=b[d].nonStackableSeries*m.rangeBand()/(2*G))),e}).attr("width",function(a,c,d){if(b[d].nonStackable){var e=m.rangeBand()/G;return b.length!==G&&(e=m.rangeBand()/(2*G)),e}return m.rangeBand()}):R.attr("x",function(a){return a.series*m.rangeBand()/b.length}).attr("width",m.rangeBand()/b.length).attr("y",function(a,b){return r(a,b)<0?n(0):n(0)-n(r(a,b))<1?n(0)-1:n(r(a,b))||0}).attr("height",function(a,b){return Math.max(Math.abs(n(r(a,b))-n(0)),1)||0}),h=m.copy(),i=n.copy(),b[0]&&b[0].values&&(D=b[0].values.length)}),C.renderEnd("multibar immediate"),b}var c,d,e,f,g,h,i,j={top:0,right:0,bottom:0,left:0},k=960,l=500,m=d3.scale.ordinal(),n=d3.scale.linear(),o=Math.floor(1e4*Math.random()),p=null,q=function(a){return a.x},r=function(a){return a.y},s=[0],t=!0,u=!1,v="zero",w=a.utils.defaultColor(),x=!1,y=null,z=500,A=.1,B=d3.dispatch("chartClick","elementClick","elementDblClick","elementMouseover","elementMouseout","elementMousemove","renderEnd"),C=a.utils.renderWatch(B,z),D=0;return b.dispatch=B,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return k},set:function(a){k=a}},height:{get:function(){return l},set:function(a){l=a}},x:{get:function(){return q},set:function(a){q=a}},y:{get:function(){return r},set:function(a){r=a}},xScale:{get:function(){return m},set:function(a){m=a}},yScale:{get:function(){return n},set:function(a){n=a}},xDomain:{get:function(){return d},set:function(a){d=a}},yDomain:{get:function(){return e},set:function(a){e=a}},xRange:{get:function(){return f},set:function(a){f=a}},yRange:{get:function(){return g},set:function(a){g=a}},forceY:{get:function(){return s},set:function(a){s=a}},stacked:{get:function(){return u},set:function(a){u=a}},stackOffset:{get:function(){return v},set:function(a){v=a}},clipEdge:{get:function(){return t},set:function(a){t=a}},disabled:{get:function(){return c},set:function(a){c=a}},id:{get:function(){return o},set:function(a){o=a}},hideable:{get:function(){return x},set:function(a){x=a}},groupSpacing:{get:function(){return A},set:function(a){A=a}},margin:{get:function(){return j},set:function(a){j.top=void 0!==a.top?a.top:j.top,j.right=void 0!==a.right?a.right:j.right,j.bottom=void 0!==a.bottom?a.bottom:j.bottom,j.left=void 0!==a.left?a.left:j.left}},duration:{get:function(){return z},set:function(a){z=a,C.reset(z)}},color:{get:function(){return w},set:function(b){w=a.utils.getColor(b)}},barColor:{get:function(){return y},set:function(b){y=b?a.utils.getColor(b):null}}}),a.utils.initOptions(b),b},a.models.multiBarChart=function(){"use strict";function b(j){return D.reset(),D.models(e),r&&D.models(f),s&&D.models(g),j.each(function(j){var z=d3.select(this);a.utils.initSVG(z);var D=a.utils.availableWidth(l,z,k),H=a.utils.availableHeight(m,z,k);if(b.update=function(){0===C?z.call(b):z.transition().duration(C).call(b)},b.container=this,x.setter(G(j),b.update).getter(F(j)).update(),x.disabled=j.map(function(a){return!!a.disabled}),!y){var I;y={};for(I in x)y[I]=x[I]instanceof Array?x[I].slice(0):x[I]}if(!(j&&j.length&&j.filter(function(a){return a.values.length}).length))return a.utils.noData(b,z),b;z.selectAll(".nv-noData").remove(),c=e.xScale(),d=e.yScale(); -var J=z.selectAll("g.nv-wrap.nv-multiBarWithLegend").data([j]),K=J.enter().append("g").attr("class","nvd3 nv-wrap nv-multiBarWithLegend").append("g"),L=J.select("g");if(K.append("g").attr("class","nv-x nv-axis"),K.append("g").attr("class","nv-y nv-axis"),K.append("g").attr("class","nv-barsWrap"),K.append("g").attr("class","nv-legendWrap"),K.append("g").attr("class","nv-controlsWrap"),q&&(h.width(D-B()),L.select(".nv-legendWrap").datum(j).call(h),k.top!=h.height()&&(k.top=h.height(),H=a.utils.availableHeight(m,z,k)),L.select(".nv-legendWrap").attr("transform","translate("+B()+","+-k.top+")")),o){var M=[{key:p.grouped||"Grouped",disabled:e.stacked()},{key:p.stacked||"Stacked",disabled:!e.stacked()}];i.width(B()).color(["#444","#444","#444"]),L.select(".nv-controlsWrap").datum(M).attr("transform","translate(0,"+-k.top+")").call(i)}J.attr("transform","translate("+k.left+","+k.top+")"),t&&L.select(".nv-y.nv-axis").attr("transform","translate("+D+",0)"),e.disabled(j.map(function(a){return a.disabled})).width(D).height(H).color(j.map(function(a,b){return a.color||n(a,b)}).filter(function(a,b){return!j[b].disabled}));var N=L.select(".nv-barsWrap").datum(j.filter(function(a){return!a.disabled}));if(N.call(e),r){f.scale(c)._ticks(a.utils.calcTicksX(D/100,j)).tickSize(-H,0),L.select(".nv-x.nv-axis").attr("transform","translate(0,"+d.range()[0]+")"),L.select(".nv-x.nv-axis").call(f);var O=L.select(".nv-x.nv-axis > g").selectAll("g");if(O.selectAll("line, text").style("opacity",1),v){var P=function(a,b){return"translate("+a+","+b+")"},Q=5,R=17;O.selectAll("text").attr("transform",function(a,b,c){return P(0,c%2==0?Q:R)});var S=d3.selectAll(".nv-x.nv-axis .nv-wrap g g text")[0].length;L.selectAll(".nv-x.nv-axis .nv-axisMaxMin text").attr("transform",function(a,b){return P(0,0===b||S%2!==0?R:Q)})}u&&O.filter(function(a,b){return b%Math.ceil(j[0].values.length/(D/100))!==0}).selectAll("text, line").style("opacity",0),w&&O.selectAll(".tick text").attr("transform","rotate("+w+" 0,0)").style("text-anchor",w>0?"start":"end"),L.select(".nv-x.nv-axis").selectAll("g.nv-axisMaxMin text").style("opacity",1)}s&&(g.scale(d)._ticks(a.utils.calcTicksY(H/36,j)).tickSize(-D,0),L.select(".nv-y.nv-axis").call(g)),h.dispatch.on("stateChange",function(a){for(var c in a)x[c]=a[c];A.stateChange(x),b.update()}),i.dispatch.on("legendClick",function(a){if(a.disabled){switch(M=M.map(function(a){return a.disabled=!0,a}),a.disabled=!1,a.key){case"Grouped":case p.grouped:e.stacked(!1);break;case"Stacked":case p.stacked:e.stacked(!0)}x.stacked=e.stacked(),A.stateChange(x),b.update()}}),A.on("changeState",function(a){"undefined"!=typeof a.disabled&&(j.forEach(function(b,c){b.disabled=a.disabled[c]}),x.disabled=a.disabled),"undefined"!=typeof a.stacked&&(e.stacked(a.stacked),x.stacked=a.stacked,E=a.stacked),b.update()})}),D.renderEnd("multibarchart immediate"),b}var c,d,e=a.models.multiBar(),f=a.models.axis(),g=a.models.axis(),h=a.models.legend(),i=a.models.legend(),j=a.models.tooltip(),k={top:30,right:20,bottom:50,left:60},l=null,m=null,n=a.utils.defaultColor(),o=!0,p={},q=!0,r=!0,s=!0,t=!1,u=!0,v=!1,w=0,x=a.utils.state(),y=null,z=null,A=d3.dispatch("stateChange","changeState","renderEnd"),B=function(){return o?180:0},C=250;x.stacked=!1,e.stacked(!1),f.orient("bottom").tickPadding(7).showMaxMin(!1).tickFormat(function(a){return a}),g.orient(t?"right":"left").tickFormat(d3.format(",.1f")),j.duration(0).valueFormatter(function(a,b){return g.tickFormat()(a,b)}).headerFormatter(function(a,b){return f.tickFormat()(a,b)}),i.updateState(!1);var D=a.utils.renderWatch(A),E=!1,F=function(a){return function(){return{active:a.map(function(a){return!a.disabled}),stacked:E}}},G=function(a){return function(b){void 0!==b.stacked&&(E=b.stacked),void 0!==b.active&&a.forEach(function(a,c){a.disabled=!b.active[c]})}};return e.dispatch.on("elementMouseover.tooltip",function(a){a.value=b.x()(a.data),a.series={key:a.data.key,value:b.y()(a.data),color:a.color},j.data(a).hidden(!1)}),e.dispatch.on("elementMouseout.tooltip",function(){j.hidden(!0)}),e.dispatch.on("elementMousemove.tooltip",function(){j.position({top:d3.event.pageY,left:d3.event.pageX})()}),b.dispatch=A,b.multibar=e,b.legend=h,b.controls=i,b.xAxis=f,b.yAxis=g,b.state=x,b.tooltip=j,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return l},set:function(a){l=a}},height:{get:function(){return m},set:function(a){m=a}},showLegend:{get:function(){return q},set:function(a){q=a}},showControls:{get:function(){return o},set:function(a){o=a}},controlLabels:{get:function(){return p},set:function(a){p=a}},showXAxis:{get:function(){return r},set:function(a){r=a}},showYAxis:{get:function(){return s},set:function(a){s=a}},defaultState:{get:function(){return y},set:function(a){y=a}},noData:{get:function(){return z},set:function(a){z=a}},reduceXTicks:{get:function(){return u},set:function(a){u=a}},rotateLabels:{get:function(){return w},set:function(a){w=a}},staggerLabels:{get:function(){return v},set:function(a){v=a}},tooltips:{get:function(){return j.enabled()},set:function(b){a.deprecated("tooltips","use chart.tooltip.enabled() instead"),j.enabled(!!b)}},tooltipContent:{get:function(){return j.contentGenerator()},set:function(b){a.deprecated("tooltipContent","use chart.tooltip.contentGenerator() instead"),j.contentGenerator(b)}},margin:{get:function(){return k},set:function(a){k.top=void 0!==a.top?a.top:k.top,k.right=void 0!==a.right?a.right:k.right,k.bottom=void 0!==a.bottom?a.bottom:k.bottom,k.left=void 0!==a.left?a.left:k.left}},duration:{get:function(){return C},set:function(a){C=a,e.duration(C),f.duration(C),g.duration(C),D.reset(C)}},color:{get:function(){return n},set:function(b){n=a.utils.getColor(b),h.color(n)}},rightAlignYAxis:{get:function(){return t},set:function(a){t=a,g.orient(t?"right":"left")}},barColor:{get:function(){return e.barColor},set:function(a){e.barColor(a),h.color(function(a,b){return d3.rgb("#ccc").darker(1.5*b).toString()})}}}),a.utils.inheritOptions(b,e),a.utils.initOptions(b),b},a.models.multiBarHorizontal=function(){"use strict";function b(m){return E.reset(),m.each(function(b){var m=k-j.left-j.right,C=l-j.top-j.bottom;n=d3.select(this),a.utils.initSVG(n),w&&(b=d3.layout.stack().offset("zero").values(function(a){return a.values}).y(r)(b)),b.forEach(function(a,b){a.values.forEach(function(c){c.series=b,c.key=a.key})}),w&&b[0].values.map(function(a,c){var d=0,e=0;b.map(function(a){var b=a.values[c];b.size=Math.abs(b.y),b.y<0?(b.y1=e-b.size,e-=b.size):(b.y1=d,d+=b.size)})});var F=d&&e?[]:b.map(function(a){return a.values.map(function(a,b){return{x:q(a,b),y:r(a,b),y0:a.y0,y1:a.y1}})});o.domain(d||d3.merge(F).map(function(a){return a.x})).rangeBands(f||[0,C],A),p.domain(e||d3.extent(d3.merge(F).map(function(a){return w?a.y>0?a.y1+a.y:a.y1:a.y}).concat(t))),p.range(x&&!w?g||[p.domain()[0]<0?z:0,m-(p.domain()[1]>0?z:0)]:g||[0,m]),h=h||o,i=i||d3.scale.linear().domain(p.domain()).range([p(0),p(0)]);{var G=d3.select(this).selectAll("g.nv-wrap.nv-multibarHorizontal").data([b]),H=G.enter().append("g").attr("class","nvd3 nv-wrap nv-multibarHorizontal"),I=(H.append("defs"),H.append("g"));G.select("g")}I.append("g").attr("class","nv-groups"),G.attr("transform","translate("+j.left+","+j.top+")");var J=G.select(".nv-groups").selectAll(".nv-group").data(function(a){return a},function(a,b){return b});J.enter().append("g").style("stroke-opacity",1e-6).style("fill-opacity",1e-6),J.exit().watchTransition(E,"multibarhorizontal: exit groups").style("stroke-opacity",1e-6).style("fill-opacity",1e-6).remove(),J.attr("class",function(a,b){return"nv-group nv-series-"+b}).classed("hover",function(a){return a.hover}).style("fill",function(a,b){return u(a,b)}).style("stroke",function(a,b){return u(a,b)}),J.watchTransition(E,"multibarhorizontal: groups").style("stroke-opacity",1).style("fill-opacity",.75);var K=J.selectAll("g.nv-bar").data(function(a){return a.values});K.exit().remove();var L=K.enter().append("g").attr("transform",function(a,c,d){return"translate("+i(w?a.y0:0)+","+(w?0:d*o.rangeBand()/b.length+o(q(a,c)))+")"});L.append("rect").attr("width",0).attr("height",o.rangeBand()/(w?1:b.length)),K.on("mouseover",function(a,b){d3.select(this).classed("hover",!0),D.elementMouseover({data:a,index:b,color:d3.select(this).style("fill")})}).on("mouseout",function(a,b){d3.select(this).classed("hover",!1),D.elementMouseout({data:a,index:b,color:d3.select(this).style("fill")})}).on("mouseout",function(a,b){D.elementMouseout({data:a,index:b,color:d3.select(this).style("fill")})}).on("mousemove",function(a,b){D.elementMousemove({data:a,index:b,color:d3.select(this).style("fill")})}).on("click",function(a,b){D.elementClick({data:a,index:b,color:d3.select(this).style("fill")}),d3.event.stopPropagation()}).on("dblclick",function(a,b){D.elementDblClick({data:a,index:b,color:d3.select(this).style("fill")}),d3.event.stopPropagation()}),s(b[0],0)&&(L.append("polyline"),K.select("polyline").attr("fill","none").attr("points",function(a,c){var d=s(a,c),e=.8*o.rangeBand()/(2*(w?1:b.length));d=d.length?d:[-Math.abs(d),Math.abs(d)],d=d.map(function(a){return p(a)-p(0)});var f=[[d[0],-e],[d[0],e],[d[0],0],[d[1],0],[d[1],-e],[d[1],e]];return f.map(function(a){return a.join(",")}).join(" ")}).attr("transform",function(a,c){var d=o.rangeBand()/(2*(w?1:b.length));return"translate("+(r(a,c)<0?0:p(r(a,c))-p(0))+", "+d+")"})),L.append("text"),x&&!w?(K.select("text").attr("text-anchor",function(a,b){return r(a,b)<0?"end":"start"}).attr("y",o.rangeBand()/(2*b.length)).attr("dy",".32em").text(function(a,b){var c=B(r(a,b)),d=s(a,b);return void 0===d?c:d.length?c+"+"+B(Math.abs(d[1]))+"-"+B(Math.abs(d[0])):c+"±"+B(Math.abs(d))}),K.watchTransition(E,"multibarhorizontal: bars").select("text").attr("x",function(a,b){return r(a,b)<0?-4:p(r(a,b))-p(0)+4})):K.selectAll("text").text(""),y&&!w?(L.append("text").classed("nv-bar-label",!0),K.select("text.nv-bar-label").attr("text-anchor",function(a,b){return r(a,b)<0?"start":"end"}).attr("y",o.rangeBand()/(2*b.length)).attr("dy",".32em").text(function(a,b){return q(a,b)}),K.watchTransition(E,"multibarhorizontal: bars").select("text.nv-bar-label").attr("x",function(a,b){return r(a,b)<0?p(0)-p(r(a,b))+4:-4})):K.selectAll("text.nv-bar-label").text(""),K.attr("class",function(a,b){return r(a,b)<0?"nv-bar negative":"nv-bar positive"}),v&&(c||(c=b.map(function(){return!0})),K.style("fill",function(a,b,d){return d3.rgb(v(a,b)).darker(c.map(function(a,b){return b}).filter(function(a,b){return!c[b]})[d]).toString()}).style("stroke",function(a,b,d){return d3.rgb(v(a,b)).darker(c.map(function(a,b){return b}).filter(function(a,b){return!c[b]})[d]).toString()})),w?K.watchTransition(E,"multibarhorizontal: bars").attr("transform",function(a,b){return"translate("+p(a.y1)+","+o(q(a,b))+")"}).select("rect").attr("width",function(a,b){return Math.abs(p(r(a,b)+a.y0)-p(a.y0))}).attr("height",o.rangeBand()):K.watchTransition(E,"multibarhorizontal: bars").attr("transform",function(a,c){return"translate("+p(r(a,c)<0?r(a,c):0)+","+(a.series*o.rangeBand()/b.length+o(q(a,c)))+")"}).select("rect").attr("height",o.rangeBand()/b.length).attr("width",function(a,b){return Math.max(Math.abs(p(r(a,b))-p(0)),1)}),h=o.copy(),i=p.copy()}),E.renderEnd("multibarHorizontal immediate"),b}var c,d,e,f,g,h,i,j={top:0,right:0,bottom:0,left:0},k=960,l=500,m=Math.floor(1e4*Math.random()),n=null,o=d3.scale.ordinal(),p=d3.scale.linear(),q=function(a){return a.x},r=function(a){return a.y},s=function(a){return a.yErr},t=[0],u=a.utils.defaultColor(),v=null,w=!1,x=!1,y=!1,z=60,A=.1,B=d3.format(",.2f"),C=250,D=d3.dispatch("chartClick","elementClick","elementDblClick","elementMouseover","elementMouseout","elementMousemove","renderEnd"),E=a.utils.renderWatch(D,C);return b.dispatch=D,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return k},set:function(a){k=a}},height:{get:function(){return l},set:function(a){l=a}},x:{get:function(){return q},set:function(a){q=a}},y:{get:function(){return r},set:function(a){r=a}},yErr:{get:function(){return s},set:function(a){s=a}},xScale:{get:function(){return o},set:function(a){o=a}},yScale:{get:function(){return p},set:function(a){p=a}},xDomain:{get:function(){return d},set:function(a){d=a}},yDomain:{get:function(){return e},set:function(a){e=a}},xRange:{get:function(){return f},set:function(a){f=a}},yRange:{get:function(){return g},set:function(a){g=a}},forceY:{get:function(){return t},set:function(a){t=a}},stacked:{get:function(){return w},set:function(a){w=a}},showValues:{get:function(){return x},set:function(a){x=a}},disabled:{get:function(){return c},set:function(a){c=a}},id:{get:function(){return m},set:function(a){m=a}},valueFormat:{get:function(){return B},set:function(a){B=a}},valuePadding:{get:function(){return z},set:function(a){z=a}},groupSpacing:{get:function(){return A},set:function(a){A=a}},margin:{get:function(){return j},set:function(a){j.top=void 0!==a.top?a.top:j.top,j.right=void 0!==a.right?a.right:j.right,j.bottom=void 0!==a.bottom?a.bottom:j.bottom,j.left=void 0!==a.left?a.left:j.left}},duration:{get:function(){return C},set:function(a){C=a,E.reset(C)}},color:{get:function(){return u},set:function(b){u=a.utils.getColor(b)}},barColor:{get:function(){return v},set:function(b){v=b?a.utils.getColor(b):null}}}),a.utils.initOptions(b),b},a.models.multiBarHorizontalChart=function(){"use strict";function b(j){return C.reset(),C.models(e),r&&C.models(f),s&&C.models(g),j.each(function(j){var w=d3.select(this);a.utils.initSVG(w);var C=a.utils.availableWidth(l,w,k),D=a.utils.availableHeight(m,w,k);if(b.update=function(){w.transition().duration(z).call(b)},b.container=this,t=e.stacked(),u.setter(B(j),b.update).getter(A(j)).update(),u.disabled=j.map(function(a){return!!a.disabled}),!v){var E;v={};for(E in u)v[E]=u[E]instanceof Array?u[E].slice(0):u[E]}if(!(j&&j.length&&j.filter(function(a){return a.values.length}).length))return a.utils.noData(b,w),b;w.selectAll(".nv-noData").remove(),c=e.xScale(),d=e.yScale();var F=w.selectAll("g.nv-wrap.nv-multiBarHorizontalChart").data([j]),G=F.enter().append("g").attr("class","nvd3 nv-wrap nv-multiBarHorizontalChart").append("g"),H=F.select("g");if(G.append("g").attr("class","nv-x nv-axis"),G.append("g").attr("class","nv-y nv-axis").append("g").attr("class","nv-zeroLine").append("line"),G.append("g").attr("class","nv-barsWrap"),G.append("g").attr("class","nv-legendWrap"),G.append("g").attr("class","nv-controlsWrap"),q&&(h.width(C-y()),H.select(".nv-legendWrap").datum(j).call(h),k.top!=h.height()&&(k.top=h.height(),D=a.utils.availableHeight(m,w,k)),H.select(".nv-legendWrap").attr("transform","translate("+y()+","+-k.top+")")),o){var I=[{key:p.grouped||"Grouped",disabled:e.stacked()},{key:p.stacked||"Stacked",disabled:!e.stacked()}];i.width(y()).color(["#444","#444","#444"]),H.select(".nv-controlsWrap").datum(I).attr("transform","translate(0,"+-k.top+")").call(i)}F.attr("transform","translate("+k.left+","+k.top+")"),e.disabled(j.map(function(a){return a.disabled})).width(C).height(D).color(j.map(function(a,b){return a.color||n(a,b)}).filter(function(a,b){return!j[b].disabled}));var J=H.select(".nv-barsWrap").datum(j.filter(function(a){return!a.disabled}));if(J.transition().call(e),r){f.scale(c)._ticks(a.utils.calcTicksY(D/24,j)).tickSize(-C,0),H.select(".nv-x.nv-axis").call(f);var K=H.select(".nv-x.nv-axis").selectAll("g");K.selectAll("line, text")}s&&(g.scale(d)._ticks(a.utils.calcTicksX(C/100,j)).tickSize(-D,0),H.select(".nv-y.nv-axis").attr("transform","translate(0,"+D+")"),H.select(".nv-y.nv-axis").call(g)),H.select(".nv-zeroLine line").attr("x1",d(0)).attr("x2",d(0)).attr("y1",0).attr("y2",-D),h.dispatch.on("stateChange",function(a){for(var c in a)u[c]=a[c];x.stateChange(u),b.update()}),i.dispatch.on("legendClick",function(a){if(a.disabled){switch(I=I.map(function(a){return a.disabled=!0,a}),a.disabled=!1,a.key){case"Grouped":e.stacked(!1);break;case"Stacked":e.stacked(!0)}u.stacked=e.stacked(),x.stateChange(u),t=e.stacked(),b.update()}}),x.on("changeState",function(a){"undefined"!=typeof a.disabled&&(j.forEach(function(b,c){b.disabled=a.disabled[c]}),u.disabled=a.disabled),"undefined"!=typeof a.stacked&&(e.stacked(a.stacked),u.stacked=a.stacked,t=a.stacked),b.update()})}),C.renderEnd("multibar horizontal chart immediate"),b}var c,d,e=a.models.multiBarHorizontal(),f=a.models.axis(),g=a.models.axis(),h=a.models.legend().height(30),i=a.models.legend().height(30),j=a.models.tooltip(),k={top:30,right:20,bottom:50,left:60},l=null,m=null,n=a.utils.defaultColor(),o=!0,p={},q=!0,r=!0,s=!0,t=!1,u=a.utils.state(),v=null,w=null,x=d3.dispatch("stateChange","changeState","renderEnd"),y=function(){return o?180:0},z=250;u.stacked=!1,e.stacked(t),f.orient("left").tickPadding(5).showMaxMin(!1).tickFormat(function(a){return a}),g.orient("bottom").tickFormat(d3.format(",.1f")),j.duration(0).valueFormatter(function(a,b){return g.tickFormat()(a,b)}).headerFormatter(function(a,b){return f.tickFormat()(a,b)}),i.updateState(!1);var A=function(a){return function(){return{active:a.map(function(a){return!a.disabled}),stacked:t}}},B=function(a){return function(b){void 0!==b.stacked&&(t=b.stacked),void 0!==b.active&&a.forEach(function(a,c){a.disabled=!b.active[c]})}},C=a.utils.renderWatch(x,z);return e.dispatch.on("elementMouseover.tooltip",function(a){a.value=b.x()(a.data),a.series={key:a.data.key,value:b.y()(a.data),color:a.color},j.data(a).hidden(!1)}),e.dispatch.on("elementMouseout.tooltip",function(){j.hidden(!0)}),e.dispatch.on("elementMousemove.tooltip",function(){j.position({top:d3.event.pageY,left:d3.event.pageX})()}),b.dispatch=x,b.multibar=e,b.legend=h,b.controls=i,b.xAxis=f,b.yAxis=g,b.state=u,b.tooltip=j,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return l},set:function(a){l=a}},height:{get:function(){return m},set:function(a){m=a}},showLegend:{get:function(){return q},set:function(a){q=a}},showControls:{get:function(){return o},set:function(a){o=a}},controlLabels:{get:function(){return p},set:function(a){p=a}},showXAxis:{get:function(){return r},set:function(a){r=a}},showYAxis:{get:function(){return s},set:function(a){s=a}},defaultState:{get:function(){return v},set:function(a){v=a}},noData:{get:function(){return w},set:function(a){w=a}},tooltips:{get:function(){return j.enabled()},set:function(b){a.deprecated("tooltips","use chart.tooltip.enabled() instead"),j.enabled(!!b)}},tooltipContent:{get:function(){return j.contentGenerator()},set:function(b){a.deprecated("tooltipContent","use chart.tooltip.contentGenerator() instead"),j.contentGenerator(b)}},margin:{get:function(){return k},set:function(a){k.top=void 0!==a.top?a.top:k.top,k.right=void 0!==a.right?a.right:k.right,k.bottom=void 0!==a.bottom?a.bottom:k.bottom,k.left=void 0!==a.left?a.left:k.left}},duration:{get:function(){return z},set:function(a){z=a,C.reset(z),e.duration(z),f.duration(z),g.duration(z)}},color:{get:function(){return n},set:function(b){n=a.utils.getColor(b),h.color(n)}},barColor:{get:function(){return e.barColor},set:function(a){e.barColor(a),h.color(function(a,b){return d3.rgb("#ccc").darker(1.5*b).toString()})}}}),a.utils.inheritOptions(b,e),a.utils.initOptions(b),b},a.models.multiChart=function(){"use strict";function b(j){return j.each(function(j){function k(a){var b=2===j[a.seriesIndex].yAxis?z:y;a.value=a.point.x,a.series={value:a.point.y,color:a.point.color},B.duration(100).valueFormatter(function(a,c){return b.tickFormat()(a,c)}).data(a).position(a.pos).hidden(!1)}function l(a){var b=2===j[a.seriesIndex].yAxis?z:y;a.point.x=v.x()(a.point),a.point.y=v.y()(a.point),B.duration(100).valueFormatter(function(a,c){return b.tickFormat()(a,c)}).data(a).position(a.pos).hidden(!1)}function n(a){var b=2===j[a.data.series].yAxis?z:y;a.value=t.x()(a.data),a.series={value:t.y()(a.data),color:a.color},B.duration(0).valueFormatter(function(a,c){return b.tickFormat()(a,c)}).data(a).hidden(!1)}var C=d3.select(this);a.utils.initSVG(C),b.update=function(){C.transition().call(b)},b.container=this;var D=a.utils.availableWidth(g,C,e),E=a.utils.availableHeight(h,C,e),F=j.filter(function(a){return"line"==a.type&&1==a.yAxis}),G=j.filter(function(a){return"line"==a.type&&2==a.yAxis}),H=j.filter(function(a){return"bar"==a.type&&1==a.yAxis}),I=j.filter(function(a){return"bar"==a.type&&2==a.yAxis}),J=j.filter(function(a){return"area"==a.type&&1==a.yAxis}),K=j.filter(function(a){return"area"==a.type&&2==a.yAxis});if(!(j&&j.length&&j.filter(function(a){return a.values.length}).length))return a.utils.noData(b,C),b;C.selectAll(".nv-noData").remove();var L=j.filter(function(a){return!a.disabled&&1==a.yAxis}).map(function(a){return a.values.map(function(a){return{x:a.x,y:a.y}})}),M=j.filter(function(a){return!a.disabled&&2==a.yAxis}).map(function(a){return a.values.map(function(a){return{x:a.x,y:a.y}})});o.domain(d3.extent(d3.merge(L.concat(M)),function(a){return a.x})).range([0,D]);var N=C.selectAll("g.wrap.multiChart").data([j]),O=N.enter().append("g").attr("class","wrap nvd3 multiChart").append("g");O.append("g").attr("class","nv-x nv-axis"),O.append("g").attr("class","nv-y1 nv-axis"),O.append("g").attr("class","nv-y2 nv-axis"),O.append("g").attr("class","lines1Wrap"),O.append("g").attr("class","lines2Wrap"),O.append("g").attr("class","bars1Wrap"),O.append("g").attr("class","bars2Wrap"),O.append("g").attr("class","stack1Wrap"),O.append("g").attr("class","stack2Wrap"),O.append("g").attr("class","legendWrap");var P=N.select("g"),Q=j.map(function(a,b){return j[b].color||f(a,b)});if(i){var R=A.align()?D/2:D,S=A.align()?R:0;A.width(R),A.color(Q),P.select(".legendWrap").datum(j.map(function(a){return a.originalKey=void 0===a.originalKey?a.key:a.originalKey,a.key=a.originalKey+(1==a.yAxis?"":" (right axis)"),a})).call(A),e.top!=A.height()&&(e.top=A.height(),E=a.utils.availableHeight(h,C,e)),P.select(".legendWrap").attr("transform","translate("+S+","+-e.top+")")}r.width(D).height(E).interpolate(m).color(Q.filter(function(a,b){return!j[b].disabled&&1==j[b].yAxis&&"line"==j[b].type})),s.width(D).height(E).interpolate(m).color(Q.filter(function(a,b){return!j[b].disabled&&2==j[b].yAxis&&"line"==j[b].type})),t.width(D).height(E).color(Q.filter(function(a,b){return!j[b].disabled&&1==j[b].yAxis&&"bar"==j[b].type})),u.width(D).height(E).color(Q.filter(function(a,b){return!j[b].disabled&&2==j[b].yAxis&&"bar"==j[b].type})),v.width(D).height(E).color(Q.filter(function(a,b){return!j[b].disabled&&1==j[b].yAxis&&"area"==j[b].type})),w.width(D).height(E).color(Q.filter(function(a,b){return!j[b].disabled&&2==j[b].yAxis&&"area"==j[b].type})),P.attr("transform","translate("+e.left+","+e.top+")");var T=P.select(".lines1Wrap").datum(F.filter(function(a){return!a.disabled})),U=P.select(".bars1Wrap").datum(H.filter(function(a){return!a.disabled})),V=P.select(".stack1Wrap").datum(J.filter(function(a){return!a.disabled})),W=P.select(".lines2Wrap").datum(G.filter(function(a){return!a.disabled})),X=P.select(".bars2Wrap").datum(I.filter(function(a){return!a.disabled})),Y=P.select(".stack2Wrap").datum(K.filter(function(a){return!a.disabled})),Z=J.length?J.map(function(a){return a.values}).reduce(function(a,b){return a.map(function(a,c){return{x:a.x,y:a.y+b[c].y}})}).concat([{x:0,y:0}]):[],$=K.length?K.map(function(a){return a.values}).reduce(function(a,b){return a.map(function(a,c){return{x:a.x,y:a.y+b[c].y}})}).concat([{x:0,y:0}]):[];p.domain(c||d3.extent(d3.merge(L).concat(Z),function(a){return a.y})).range([0,E]),q.domain(d||d3.extent(d3.merge(M).concat($),function(a){return a.y})).range([0,E]),r.yDomain(p.domain()),t.yDomain(p.domain()),v.yDomain(p.domain()),s.yDomain(q.domain()),u.yDomain(q.domain()),w.yDomain(q.domain()),J.length&&d3.transition(V).call(v),K.length&&d3.transition(Y).call(w),H.length&&d3.transition(U).call(t),I.length&&d3.transition(X).call(u),F.length&&d3.transition(T).call(r),G.length&&d3.transition(W).call(s),x._ticks(a.utils.calcTicksX(D/100,j)).tickSize(-E,0),P.select(".nv-x.nv-axis").attr("transform","translate(0,"+E+")"),d3.transition(P.select(".nv-x.nv-axis")).call(x),y._ticks(a.utils.calcTicksY(E/36,j)).tickSize(-D,0),d3.transition(P.select(".nv-y1.nv-axis")).call(y),z._ticks(a.utils.calcTicksY(E/36,j)).tickSize(-D,0),d3.transition(P.select(".nv-y2.nv-axis")).call(z),P.select(".nv-y1.nv-axis").classed("nv-disabled",L.length?!1:!0).attr("transform","translate("+o.range()[0]+",0)"),P.select(".nv-y2.nv-axis").classed("nv-disabled",M.length?!1:!0).attr("transform","translate("+o.range()[1]+",0)"),A.dispatch.on("stateChange",function(){b.update()}),r.dispatch.on("elementMouseover.tooltip",k),s.dispatch.on("elementMouseover.tooltip",k),r.dispatch.on("elementMouseout.tooltip",function(){B.hidden(!0)}),s.dispatch.on("elementMouseout.tooltip",function(){B.hidden(!0)}),v.dispatch.on("elementMouseover.tooltip",l),w.dispatch.on("elementMouseover.tooltip",l),v.dispatch.on("elementMouseout.tooltip",function(){B.hidden(!0)}),w.dispatch.on("elementMouseout.tooltip",function(){B.hidden(!0)}),t.dispatch.on("elementMouseover.tooltip",n),u.dispatch.on("elementMouseover.tooltip",n),t.dispatch.on("elementMouseout.tooltip",function(){B.hidden(!0)}),u.dispatch.on("elementMouseout.tooltip",function(){B.hidden(!0)}),t.dispatch.on("elementMousemove.tooltip",function(){B.position({top:d3.event.pageY,left:d3.event.pageX})()}),u.dispatch.on("elementMousemove.tooltip",function(){B.position({top:d3.event.pageY,left:d3.event.pageX})()})}),b}var c,d,e={top:30,right:20,bottom:50,left:60},f=a.utils.defaultColor(),g=null,h=null,i=!0,j=null,k=function(a){return a.x},l=function(a){return a.y},m="monotone",n=!0,o=d3.scale.linear(),p=d3.scale.linear(),q=d3.scale.linear(),r=a.models.line().yScale(p),s=a.models.line().yScale(q),t=a.models.multiBar().stacked(!1).yScale(p),u=a.models.multiBar().stacked(!1).yScale(q),v=a.models.stackedArea().yScale(p),w=a.models.stackedArea().yScale(q),x=a.models.axis().scale(o).orient("bottom").tickPadding(5),y=a.models.axis().scale(p).orient("left"),z=a.models.axis().scale(q).orient("right"),A=a.models.legend().height(30),B=a.models.tooltip(),C=d3.dispatch();return b.dispatch=C,b.lines1=r,b.lines2=s,b.bars1=t,b.bars2=u,b.stack1=v,b.stack2=w,b.xAxis=x,b.yAxis1=y,b.yAxis2=z,b.tooltip=B,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return g},set:function(a){g=a}},height:{get:function(){return h},set:function(a){h=a}},showLegend:{get:function(){return i},set:function(a){i=a}},yDomain1:{get:function(){return c},set:function(a){c=a}},yDomain2:{get:function(){return d},set:function(a){d=a}},noData:{get:function(){return j},set:function(a){j=a}},interpolate:{get:function(){return m},set:function(a){m=a}},tooltips:{get:function(){return B.enabled()},set:function(b){a.deprecated("tooltips","use chart.tooltip.enabled() instead"),B.enabled(!!b)}},tooltipContent:{get:function(){return B.contentGenerator()},set:function(b){a.deprecated("tooltipContent","use chart.tooltip.contentGenerator() instead"),B.contentGenerator(b)}},margin:{get:function(){return e},set:function(a){e.top=void 0!==a.top?a.top:e.top,e.right=void 0!==a.right?a.right:e.right,e.bottom=void 0!==a.bottom?a.bottom:e.bottom,e.left=void 0!==a.left?a.left:e.left}},color:{get:function(){return f},set:function(b){f=a.utils.getColor(b)}},x:{get:function(){return k},set:function(a){k=a,r.x(a),s.x(a),t.x(a),u.x(a),v.x(a),w.x(a)}},y:{get:function(){return l},set:function(a){l=a,r.y(a),s.y(a),v.y(a),w.y(a),t.y(a),u.y(a)}},useVoronoi:{get:function(){return n},set:function(a){n=a,r.useVoronoi(a),s.useVoronoi(a),v.useVoronoi(a),w.useVoronoi(a)}}}),a.utils.initOptions(b),b},a.models.ohlcBar=function(){"use strict";function b(y){return y.each(function(b){k=d3.select(this);var y=a.utils.availableWidth(h,k,g),A=a.utils.availableHeight(i,k,g);a.utils.initSVG(k);var B=y/b[0].values.length*.9;l.domain(c||d3.extent(b[0].values.map(n).concat(t))),l.range(v?e||[.5*y/b[0].values.length,y*(b[0].values.length-.5)/b[0].values.length]:e||[5+B/2,y-B/2-5]),m.domain(d||[d3.min(b[0].values.map(s).concat(u)),d3.max(b[0].values.map(r).concat(u))]).range(f||[A,0]),l.domain()[0]===l.domain()[1]&&l.domain(l.domain()[0]?[l.domain()[0]-.01*l.domain()[0],l.domain()[1]+.01*l.domain()[1]]:[-1,1]),m.domain()[0]===m.domain()[1]&&m.domain(m.domain()[0]?[m.domain()[0]+.01*m.domain()[0],m.domain()[1]-.01*m.domain()[1]]:[-1,1]);var C=d3.select(this).selectAll("g.nv-wrap.nv-ohlcBar").data([b[0].values]),D=C.enter().append("g").attr("class","nvd3 nv-wrap nv-ohlcBar"),E=D.append("defs"),F=D.append("g"),G=C.select("g");F.append("g").attr("class","nv-ticks"),C.attr("transform","translate("+g.left+","+g.top+")"),k.on("click",function(a,b){z.chartClick({data:a,index:b,pos:d3.event,id:j})}),E.append("clipPath").attr("id","nv-chart-clip-path-"+j).append("rect"),C.select("#nv-chart-clip-path-"+j+" rect").attr("width",y).attr("height",A),G.attr("clip-path",w?"url(#nv-chart-clip-path-"+j+")":"");var H=C.select(".nv-ticks").selectAll(".nv-tick").data(function(a){return a});H.exit().remove(),H.enter().append("path").attr("class",function(a,b,c){return(p(a,b)>q(a,b)?"nv-tick negative":"nv-tick positive")+" nv-tick-"+c+"-"+b}).attr("d",function(a,b){return"m0,0l0,"+(m(p(a,b))-m(r(a,b)))+"l"+-B/2+",0l"+B/2+",0l0,"+(m(s(a,b))-m(p(a,b)))+"l0,"+(m(q(a,b))-m(s(a,b)))+"l"+B/2+",0l"+-B/2+",0z"}).attr("transform",function(a,b){return"translate("+l(n(a,b))+","+m(r(a,b))+")"}).attr("fill",function(){return x[0]}).attr("stroke",function(){return x[0]}).attr("x",0).attr("y",function(a,b){return m(Math.max(0,o(a,b)))}).attr("height",function(a,b){return Math.abs(m(o(a,b))-m(0))}),H.attr("class",function(a,b,c){return(p(a,b)>q(a,b)?"nv-tick negative":"nv-tick positive")+" nv-tick-"+c+"-"+b}),d3.transition(H).attr("transform",function(a,b){return"translate("+l(n(a,b))+","+m(r(a,b))+")"}).attr("d",function(a,c){var d=y/b[0].values.length*.9;return"m0,0l0,"+(m(p(a,c))-m(r(a,c)))+"l"+-d/2+",0l"+d/2+",0l0,"+(m(s(a,c))-m(p(a,c)))+"l0,"+(m(q(a,c))-m(s(a,c)))+"l"+d/2+",0l"+-d/2+",0z"})}),b}var c,d,e,f,g={top:0,right:0,bottom:0,left:0},h=null,i=null,j=Math.floor(1e4*Math.random()),k=null,l=d3.scale.linear(),m=d3.scale.linear(),n=function(a){return a.x},o=function(a){return a.y},p=function(a){return a.open},q=function(a){return a.close},r=function(a){return a.high},s=function(a){return a.low},t=[],u=[],v=!1,w=!0,x=a.utils.defaultColor(),y=!1,z=d3.dispatch("tooltipShow","tooltipHide","stateChange","changeState","renderEnd","chartClick","elementClick","elementDblClick","elementMouseover","elementMouseout","elementMousemove");return b.highlightPoint=function(a,c){b.clearHighlights(),k.select(".nv-ohlcBar .nv-tick-0-"+a).classed("hover",c)},b.clearHighlights=function(){k.select(".nv-ohlcBar .nv-tick.hover").classed("hover",!1)},b.dispatch=z,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return h},set:function(a){h=a}},height:{get:function(){return i},set:function(a){i=a}},xScale:{get:function(){return l},set:function(a){l=a}},yScale:{get:function(){return m},set:function(a){m=a}},xDomain:{get:function(){return c},set:function(a){c=a}},yDomain:{get:function(){return d},set:function(a){d=a}},xRange:{get:function(){return e},set:function(a){e=a}},yRange:{get:function(){return f},set:function(a){f=a}},forceX:{get:function(){return t},set:function(a){t=a}},forceY:{get:function(){return u},set:function(a){u=a}},padData:{get:function(){return v},set:function(a){v=a}},clipEdge:{get:function(){return w},set:function(a){w=a}},id:{get:function(){return j},set:function(a){j=a}},interactive:{get:function(){return y},set:function(a){y=a}},x:{get:function(){return n},set:function(a){n=a}},y:{get:function(){return o},set:function(a){o=a}},open:{get:function(){return p()},set:function(a){p=a}},close:{get:function(){return q()},set:function(a){q=a}},high:{get:function(){return r},set:function(a){r=a}},low:{get:function(){return s},set:function(a){s=a}},margin:{get:function(){return g},set:function(a){g.top=void 0!=a.top?a.top:g.top,g.right=void 0!=a.right?a.right:g.right,g.bottom=void 0!=a.bottom?a.bottom:g.bottom,g.left=void 0!=a.left?a.left:g.left -}},color:{get:function(){return x},set:function(b){x=a.utils.getColor(b)}}}),a.utils.initOptions(b),b},a.models.parallelCoordinates=function(){"use strict";function b(p){return p.each(function(b){function p(a){return F(h.map(function(b){if(isNaN(a[b])||isNaN(parseFloat(a[b]))){var c=g[b].domain(),d=g[b].range(),e=c[0]-(c[1]-c[0])/9;if(J.indexOf(b)<0){var h=d3.scale.linear().domain([e,c[1]]).range([x-12,d[1]]);g[b].brush.y(h),J.push(b)}return[f(b),g[b](e)]}return J.length>0?(D.style("display","inline"),E.style("display","inline")):(D.style("display","none"),E.style("display","none")),[f(b),g[b](a[b])]}))}function q(){var a=h.filter(function(a){return!g[a].brush.empty()}),b=a.map(function(a){return g[a].brush.extent()});k=[],a.forEach(function(a,c){k[c]={dimension:a,extent:b[c]}}),l=[],M.style("display",function(c){var d=a.every(function(a,d){return isNaN(c[a])&&b[d][0]==g[a].brush.y().domain()[0]?!0:b[d][0]<=c[a]&&c[a]<=b[d][1]});return d&&l.push(c),d?null:"none"}),o.brush({filters:k,active:l})}function r(a){m[a]=this.parentNode.__origin__=f(a),L.attr("visibility","hidden")}function s(a){m[a]=Math.min(w,Math.max(0,this.parentNode.__origin__+=d3.event.x)),M.attr("d",p),h.sort(function(a,b){return u(a)-u(b)}),f.domain(h),N.attr("transform",function(a){return"translate("+u(a)+")"})}function t(a){delete this.parentNode.__origin__,delete m[a],d3.select(this.parentNode).attr("transform","translate("+f(a)+")"),M.attr("d",p),L.attr("d",p).attr("visibility",null)}function u(a){var b=m[a];return null==b?f(a):b}var v=d3.select(this),w=a.utils.availableWidth(d,v,c),x=a.utils.availableHeight(e,v,c);a.utils.initSVG(v),l=b,f.rangePoints([0,w],1).domain(h);var y={};h.forEach(function(a){var c=d3.extent(b,function(b){return+b[a]});return y[a]=!1,void 0===c[0]&&(y[a]=!0,c[0]=0,c[1]=0),c[0]===c[1]&&(c[0]=c[0]-1,c[1]=c[1]+1),g[a]=d3.scale.linear().domain(c).range([.9*(x-12),0]),g[a].brush=d3.svg.brush().y(g[a]).on("brush",q),"name"!=a});var z=v.selectAll("g.nv-wrap.nv-parallelCoordinates").data([b]),A=z.enter().append("g").attr("class","nvd3 nv-wrap nv-parallelCoordinates"),B=A.append("g"),C=z.select("g");B.append("g").attr("class","nv-parallelCoordinates background"),B.append("g").attr("class","nv-parallelCoordinates foreground"),B.append("g").attr("class","nv-parallelCoordinates missingValuesline"),z.attr("transform","translate("+c.left+","+c.top+")");var D,E,F=d3.svg.line().interpolate("cardinal").tension(n),G=d3.svg.axis().orient("left"),H=d3.behavior.drag().on("dragstart",r).on("drag",s).on("dragend",t),I=f.range()[1]-f.range()[0],J=[],K=[0+I/2,x-12,w-I/2,x-12];D=z.select(".missingValuesline").selectAll("line").data([K]),D.enter().append("line"),D.exit().remove(),D.attr("x1",function(a){return a[0]}).attr("y1",function(a){return a[1]}).attr("x2",function(a){return a[2]}).attr("y2",function(a){return a[3]}),E=z.select(".missingValuesline").selectAll("text").data(["undefined values"]),E.append("text").data(["undefined values"]),E.enter().append("text"),E.exit().remove(),E.attr("y",x).attr("x",w-92-I/2).text(function(a){return a});var L=z.select(".background").selectAll("path").data(b);L.enter().append("path"),L.exit().remove(),L.attr("d",p);var M=z.select(".foreground").selectAll("path").data(b);M.enter().append("path"),M.exit().remove(),M.attr("d",p).attr("stroke",j),M.on("mouseover",function(a,b){d3.select(this).classed("hover",!0),o.elementMouseover({label:a.name,data:a.data,index:b,pos:[d3.mouse(this.parentNode)[0],d3.mouse(this.parentNode)[1]]})}),M.on("mouseout",function(a,b){d3.select(this).classed("hover",!1),o.elementMouseout({label:a.name,data:a.data,index:b})});var N=C.selectAll(".dimension").data(h),O=N.enter().append("g").attr("class","nv-parallelCoordinates dimension");O.append("g").attr("class","nv-parallelCoordinates nv-axis"),O.append("g").attr("class","nv-parallelCoordinates-brush"),O.append("text").attr("class","nv-parallelCoordinates nv-label"),N.attr("transform",function(a){return"translate("+f(a)+",0)"}),N.exit().remove(),N.select(".nv-label").style("cursor","move").attr("dy","-1em").attr("text-anchor","middle").text(String).on("mouseover",function(a){o.elementMouseover({dim:a,pos:[d3.mouse(this.parentNode.parentNode)[0],d3.mouse(this.parentNode.parentNode)[1]]})}).on("mouseout",function(a){o.elementMouseout({dim:a})}).call(H),N.select(".nv-axis").each(function(a,b){d3.select(this).call(G.scale(g[a]).tickFormat(d3.format(i[b])))}),N.select(".nv-parallelCoordinates-brush").each(function(a){d3.select(this).call(g[a].brush)}).selectAll("rect").attr("x",-8).attr("width",16)}),b}var c={top:30,right:0,bottom:10,left:0},d=null,e=null,f=d3.scale.ordinal(),g={},h=[],i=[],j=a.utils.defaultColor(),k=[],l=[],m=[],n=1,o=d3.dispatch("brush","elementMouseover","elementMouseout");return b.dispatch=o,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return d},set:function(a){d=a}},height:{get:function(){return e},set:function(a){e=a}},dimensionNames:{get:function(){return h},set:function(a){h=a}},dimensionFormats:{get:function(){return i},set:function(a){i=a}},lineTension:{get:function(){return n},set:function(a){n=a}},dimensions:{get:function(){return h},set:function(b){a.deprecated("dimensions","use dimensionNames instead"),h=b}},margin:{get:function(){return c},set:function(a){c.top=void 0!==a.top?a.top:c.top,c.right=void 0!==a.right?a.right:c.right,c.bottom=void 0!==a.bottom?a.bottom:c.bottom,c.left=void 0!==a.left?a.left:c.left}},color:{get:function(){return j},set:function(b){j=a.utils.getColor(b)}}}),a.utils.initOptions(b),b},a.models.pie=function(){"use strict";function b(E){return D.reset(),E.each(function(b){function E(a,b){a.endAngle=isNaN(a.endAngle)?0:a.endAngle,a.startAngle=isNaN(a.startAngle)?0:a.startAngle,p||(a.innerRadius=0);var c=d3.interpolate(this._current,a);return this._current=c(0),function(a){return B[b](c(a))}}var F=d-c.left-c.right,G=e-c.top-c.bottom,H=Math.min(F,G)/2,I=[],J=[];if(i=d3.select(this),0===z.length)for(var K=H-H/5,L=y*H,M=0;Mc)return"";if("function"==typeof n)d=n(a,b,{key:f(a.data),value:g(a.data),percent:k(c)});else switch(n){case"key":d=f(a.data);break;case"value":d=k(g(a.data));break;case"percent":d=d3.format("%")(c)}return d})}}),D.renderEnd("pie immediate"),b}var c={top:0,right:0,bottom:0,left:0},d=500,e=500,f=function(a){return a.x},g=function(a){return a.y},h=Math.floor(1e4*Math.random()),i=null,j=a.utils.defaultColor(),k=d3.format(",.2f"),l=!0,m=!1,n="key",o=.02,p=!1,q=!1,r=!0,s=0,t=!1,u=!1,v=!1,w=!1,x=0,y=.5,z=[],A=d3.dispatch("chartClick","elementClick","elementDblClick","elementMouseover","elementMouseout","elementMousemove","renderEnd"),B=[],C=[],D=a.utils.renderWatch(A);return b.dispatch=A,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{arcsRadius:{get:function(){return z},set:function(a){z=a}},width:{get:function(){return d},set:function(a){d=a}},height:{get:function(){return e},set:function(a){e=a}},showLabels:{get:function(){return l},set:function(a){l=a}},title:{get:function(){return q},set:function(a){q=a}},titleOffset:{get:function(){return s},set:function(a){s=a}},labelThreshold:{get:function(){return o},set:function(a){o=a}},valueFormat:{get:function(){return k},set:function(a){k=a}},x:{get:function(){return f},set:function(a){f=a}},id:{get:function(){return h},set:function(a){h=a}},endAngle:{get:function(){return w},set:function(a){w=a}},startAngle:{get:function(){return u},set:function(a){u=a}},padAngle:{get:function(){return v},set:function(a){v=a}},cornerRadius:{get:function(){return x},set:function(a){x=a}},donutRatio:{get:function(){return y},set:function(a){y=a}},labelsOutside:{get:function(){return m},set:function(a){m=a}},labelSunbeamLayout:{get:function(){return t},set:function(a){t=a}},donut:{get:function(){return p},set:function(a){p=a}},growOnHover:{get:function(){return r},set:function(a){r=a}},pieLabelsOutside:{get:function(){return m},set:function(b){m=b,a.deprecated("pieLabelsOutside","use labelsOutside instead")}},donutLabelsOutside:{get:function(){return m},set:function(b){m=b,a.deprecated("donutLabelsOutside","use labelsOutside instead")}},labelFormat:{get:function(){return k},set:function(b){k=b,a.deprecated("labelFormat","use valueFormat instead")}},margin:{get:function(){return c},set:function(a){c.top="undefined"!=typeof a.top?a.top:c.top,c.right="undefined"!=typeof a.right?a.right:c.right,c.bottom="undefined"!=typeof a.bottom?a.bottom:c.bottom,c.left="undefined"!=typeof a.left?a.left:c.left}},y:{get:function(){return g},set:function(a){g=d3.functor(a)}},color:{get:function(){return j},set:function(b){j=a.utils.getColor(b)}},labelType:{get:function(){return n},set:function(a){n=a||"key"}}}),a.utils.initOptions(b),b},a.models.pieChart=function(){"use strict";function b(e){return q.reset(),q.models(c),e.each(function(e){var k=d3.select(this);a.utils.initSVG(k);var n=a.utils.availableWidth(g,k,f),o=a.utils.availableHeight(h,k,f);if(b.update=function(){k.transition().call(b)},b.container=this,l.setter(s(e),b.update).getter(r(e)).update(),l.disabled=e.map(function(a){return!!a.disabled}),!m){var q;m={};for(q in l)m[q]=l[q]instanceof Array?l[q].slice(0):l[q]}if(!e||!e.length)return a.utils.noData(b,k),b;k.selectAll(".nv-noData").remove();var t=k.selectAll("g.nv-wrap.nv-pieChart").data([e]),u=t.enter().append("g").attr("class","nvd3 nv-wrap nv-pieChart").append("g"),v=t.select("g");if(u.append("g").attr("class","nv-pieWrap"),u.append("g").attr("class","nv-legendWrap"),i)if("top"===j)d.width(n).key(c.x()),t.select(".nv-legendWrap").datum(e).call(d),f.top!=d.height()&&(f.top=d.height(),o=a.utils.availableHeight(h,k,f)),t.select(".nv-legendWrap").attr("transform","translate(0,"+-f.top+")");else if("right"===j){var w=a.models.legend().width();w>n/2&&(w=n/2),d.height(o).key(c.x()),d.width(w),n-=d.width(),t.select(".nv-legendWrap").datum(e).call(d).attr("transform","translate("+n+",0)")}t.attr("transform","translate("+f.left+","+f.top+")"),c.width(n).height(o);var x=v.select(".nv-pieWrap").datum([e]);d3.transition(x).call(c),d.dispatch.on("stateChange",function(a){for(var c in a)l[c]=a[c];p.stateChange(l),b.update()}),p.on("changeState",function(a){"undefined"!=typeof a.disabled&&(e.forEach(function(b,c){b.disabled=a.disabled[c]}),l.disabled=a.disabled),b.update()})}),q.renderEnd("pieChart immediate"),b}var c=a.models.pie(),d=a.models.legend(),e=a.models.tooltip(),f={top:30,right:20,bottom:20,left:20},g=null,h=null,i=!0,j="top",k=a.utils.defaultColor(),l=a.utils.state(),m=null,n=null,o=250,p=d3.dispatch("tooltipShow","tooltipHide","stateChange","changeState","renderEnd");e.headerEnabled(!1).duration(0).valueFormatter(function(a,b){return c.valueFormat()(a,b)});var q=a.utils.renderWatch(p),r=function(a){return function(){return{active:a.map(function(a){return!a.disabled})}}},s=function(a){return function(b){void 0!==b.active&&a.forEach(function(a,c){a.disabled=!b.active[c]})}};return c.dispatch.on("elementMouseover.tooltip",function(a){a.series={key:b.x()(a.data),value:b.y()(a.data),color:a.color},e.data(a).hidden(!1)}),c.dispatch.on("elementMouseout.tooltip",function(){e.hidden(!0)}),c.dispatch.on("elementMousemove.tooltip",function(){e.position({top:d3.event.pageY,left:d3.event.pageX})()}),b.legend=d,b.dispatch=p,b.pie=c,b.tooltip=e,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{noData:{get:function(){return n},set:function(a){n=a}},showLegend:{get:function(){return i},set:function(a){i=a}},legendPosition:{get:function(){return j},set:function(a){j=a}},defaultState:{get:function(){return m},set:function(a){m=a}},tooltips:{get:function(){return e.enabled()},set:function(b){a.deprecated("tooltips","use chart.tooltip.enabled() instead"),e.enabled(!!b)}},tooltipContent:{get:function(){return e.contentGenerator()},set:function(b){a.deprecated("tooltipContent","use chart.tooltip.contentGenerator() instead"),e.contentGenerator(b)}},color:{get:function(){return k},set:function(a){k=a,d.color(k),c.color(k)}},duration:{get:function(){return o},set:function(a){o=a,q.reset(o)}},margin:{get:function(){return f},set:function(a){f.top=void 0!==a.top?a.top:f.top,f.right=void 0!==a.right?a.right:f.right,f.bottom=void 0!==a.bottom?a.bottom:f.bottom,f.left=void 0!==a.left?a.left:f.left}}}),a.utils.inheritOptions(b,c),a.utils.initOptions(b),b},a.models.scatter=function(){"use strict";function b(N){return P.reset(),N.each(function(b){function N(){if(O=!1,!w)return!1;if(M===!0){var a=d3.merge(b.map(function(a,b){return a.values.map(function(a,c){var d=p(a,c),e=q(a,c);return[m(d)+1e-4*Math.random(),n(e)+1e-4*Math.random(),b,c,a]}).filter(function(a,b){return x(a[4],b)})}));if(0==a.length)return!1;a.length<3&&(a.push([m.range()[0]-20,n.range()[0]-20,null,null]),a.push([m.range()[1]+20,n.range()[1]+20,null,null]),a.push([m.range()[0]-20,n.range()[0]+20,null,null]),a.push([m.range()[1]+20,n.range()[1]-20,null,null]));var c=d3.geom.polygon([[-10,-10],[-10,i+10],[h+10,i+10],[h+10,-10]]),d=d3.geom.voronoi(a).map(function(b,d){return{data:c.clip(b),series:a[d][2],point:a[d][3]}});U.select(".nv-point-paths").selectAll("path").remove();var e=U.select(".nv-point-paths").selectAll("path").data(d),f=e.enter().append("svg:path").attr("d",function(a){return a&&a.data&&0!==a.data.length?"M"+a.data.join(",")+"Z":"M 0 0"}).attr("id",function(a,b){return"nv-path-"+b}).attr("clip-path",function(a,b){return"url(#nv-clip-"+b+")"});C&&f.style("fill",d3.rgb(230,230,230)).style("fill-opacity",.4).style("stroke-opacity",1).style("stroke",d3.rgb(200,200,200)),B&&(U.select(".nv-point-clips").selectAll("clipPath").remove(),U.select(".nv-point-clips").selectAll("clipPath").data(a).enter().append("svg:clipPath").attr("id",function(a,b){return"nv-clip-"+b}).append("svg:circle").attr("cx",function(a){return a[0]}).attr("cy",function(a){return a[1]}).attr("r",D));var k=function(a,c){if(O)return 0;var d=b[a.series];if(void 0!==d){var e=d.values[a.point];e.color=j(d,a.series),e.x=p(e),e.y=q(e);var f=l.node().getBoundingClientRect(),h=window.pageYOffset||document.documentElement.scrollTop,i=window.pageXOffset||document.documentElement.scrollLeft,k={left:m(p(e,a.point))+f.left+i+g.left+10,top:n(q(e,a.point))+f.top+h+g.top+10};c({point:e,series:d,pos:k,seriesIndex:a.series,pointIndex:a.point})}};e.on("click",function(a){k(a,L.elementClick)}).on("dblclick",function(a){k(a,L.elementDblClick)}).on("mouseover",function(a){k(a,L.elementMouseover)}).on("mouseout",function(a){k(a,L.elementMouseout)})}else U.select(".nv-groups").selectAll(".nv-group").selectAll(".nv-point").on("click",function(a,c){if(O||!b[a.series])return 0;var d=b[a.series],e=d.values[c];L.elementClick({point:e,series:d,pos:[m(p(e,c))+g.left,n(q(e,c))+g.top],seriesIndex:a.series,pointIndex:c})}).on("dblclick",function(a,c){if(O||!b[a.series])return 0;var d=b[a.series],e=d.values[c];L.elementDblClick({point:e,series:d,pos:[m(p(e,c))+g.left,n(q(e,c))+g.top],seriesIndex:a.series,pointIndex:c})}).on("mouseover",function(a,c){if(O||!b[a.series])return 0;var d=b[a.series],e=d.values[c];L.elementMouseover({point:e,series:d,pos:[m(p(e,c))+g.left,n(q(e,c))+g.top],seriesIndex:a.series,pointIndex:c,color:j(a,c)})}).on("mouseout",function(a,c){if(O||!b[a.series])return 0;var d=b[a.series],e=d.values[c];L.elementMouseout({point:e,series:d,seriesIndex:a.series,pointIndex:c,color:j(a,c)})})}l=d3.select(this);var R=a.utils.availableWidth(h,l,g),S=a.utils.availableHeight(i,l,g);a.utils.initSVG(l),b.forEach(function(a,b){a.values.forEach(function(a){a.series=b})});var T=E&&F&&I?[]:d3.merge(b.map(function(a){return a.values.map(function(a,b){return{x:p(a,b),y:q(a,b),size:r(a,b)}})}));m.domain(E||d3.extent(T.map(function(a){return a.x}).concat(t))),m.range(y&&b[0]?G||[(R*z+R)/(2*b[0].values.length),R-R*(1+z)/(2*b[0].values.length)]:G||[0,R]),n.domain(F||d3.extent(T.map(function(a){return a.y}).concat(u))).range(H||[S,0]),o.domain(I||d3.extent(T.map(function(a){return a.size}).concat(v))).range(J||Q),K=m.domain()[0]===m.domain()[1]||n.domain()[0]===n.domain()[1],m.domain()[0]===m.domain()[1]&&m.domain(m.domain()[0]?[m.domain()[0]-.01*m.domain()[0],m.domain()[1]+.01*m.domain()[1]]:[-1,1]),n.domain()[0]===n.domain()[1]&&n.domain(n.domain()[0]?[n.domain()[0]-.01*n.domain()[0],n.domain()[1]+.01*n.domain()[1]]:[-1,1]),isNaN(m.domain()[0])&&m.domain([-1,1]),isNaN(n.domain()[0])&&n.domain([-1,1]),c=c||m,d=d||n,e=e||o;var U=l.selectAll("g.nv-wrap.nv-scatter").data([b]),V=U.enter().append("g").attr("class","nvd3 nv-wrap nv-scatter nv-chart-"+k),W=V.append("defs"),X=V.append("g"),Y=U.select("g");U.classed("nv-single-point",K),X.append("g").attr("class","nv-groups"),X.append("g").attr("class","nv-point-paths"),V.append("g").attr("class","nv-point-clips"),U.attr("transform","translate("+g.left+","+g.top+")"),W.append("clipPath").attr("id","nv-edge-clip-"+k).append("rect"),U.select("#nv-edge-clip-"+k+" rect").attr("width",R).attr("height",S>0?S:0),Y.attr("clip-path",A?"url(#nv-edge-clip-"+k+")":""),O=!0;var Z=U.select(".nv-groups").selectAll(".nv-group").data(function(a){return a},function(a){return a.key});Z.enter().append("g").style("stroke-opacity",1e-6).style("fill-opacity",1e-6),Z.exit().remove(),Z.attr("class",function(a,b){return"nv-group nv-series-"+b}).classed("hover",function(a){return a.hover}),Z.watchTransition(P,"scatter: groups").style("fill",function(a,b){return j(a,b)}).style("stroke",function(a,b){return j(a,b)}).style("stroke-opacity",1).style("fill-opacity",.5);var $=Z.selectAll("path.nv-point").data(function(a){return a.values.map(function(a,b){return[a,b]}).filter(function(a,b){return x(a[0],b)})});$.enter().append("path").style("fill",function(a){return a.color}).style("stroke",function(a){return a.color}).attr("transform",function(a){return"translate("+c(p(a[0],a[1]))+","+d(q(a[0],a[1]))+")"}).attr("d",a.utils.symbol().type(function(a){return s(a[0])}).size(function(a){return o(r(a[0],a[1]))})),$.exit().remove(),Z.exit().selectAll("path.nv-point").watchTransition(P,"scatter exit").attr("transform",function(a){return"translate("+m(p(a[0],a[1]))+","+n(q(a[0],a[1]))+")"}).remove(),$.each(function(a){d3.select(this).classed("nv-point",!0).classed("nv-point-"+a[1],!0).classed("nv-noninteractive",!w).classed("hover",!1)}),$.watchTransition(P,"scatter points").attr("transform",function(a){return"translate("+m(p(a[0],a[1]))+","+n(q(a[0],a[1]))+")"}).attr("d",a.utils.symbol().type(function(a){return s(a[0])}).size(function(a){return o(r(a[0],a[1]))})),clearTimeout(f),f=setTimeout(N,300),c=m.copy(),d=n.copy(),e=o.copy()}),P.renderEnd("scatter immediate"),b}var c,d,e,f,g={top:0,right:0,bottom:0,left:0},h=null,i=null,j=a.utils.defaultColor(),k=Math.floor(1e5*Math.random()),l=null,m=d3.scale.linear(),n=d3.scale.linear(),o=d3.scale.linear(),p=function(a){return a.x},q=function(a){return a.y},r=function(a){return a.size||1},s=function(a){return a.shape||"circle"},t=[],u=[],v=[],w=!0,x=function(a){return!a.notActive},y=!1,z=.1,A=!1,B=!0,C=!1,D=function(){return 25},E=null,F=null,G=null,H=null,I=null,J=null,K=!1,L=d3.dispatch("elementClick","elementDblClick","elementMouseover","elementMouseout","renderEnd"),M=!0,N=250,O=!1,P=a.utils.renderWatch(L,N),Q=[16,256];return b.dispatch=L,b.options=a.utils.optionsFunc.bind(b),b._calls=new function(){this.clearHighlights=function(){return a.dom.write(function(){l.selectAll(".nv-point.hover").classed("hover",!1)}),null},this.highlightPoint=function(b,c,d){a.dom.write(function(){l.select(" .nv-series-"+b+" .nv-point-"+c).classed("hover",d)})}},L.on("elementMouseover.point",function(a){w&&b._calls.highlightPoint(a.seriesIndex,a.pointIndex,!0)}),L.on("elementMouseout.point",function(a){w&&b._calls.highlightPoint(a.seriesIndex,a.pointIndex,!1)}),b._options=Object.create({},{width:{get:function(){return h},set:function(a){h=a}},height:{get:function(){return i},set:function(a){i=a}},xScale:{get:function(){return m},set:function(a){m=a}},yScale:{get:function(){return n},set:function(a){n=a}},pointScale:{get:function(){return o},set:function(a){o=a}},xDomain:{get:function(){return E},set:function(a){E=a}},yDomain:{get:function(){return F},set:function(a){F=a}},pointDomain:{get:function(){return I},set:function(a){I=a}},xRange:{get:function(){return G},set:function(a){G=a}},yRange:{get:function(){return H},set:function(a){H=a}},pointRange:{get:function(){return J},set:function(a){J=a}},forceX:{get:function(){return t},set:function(a){t=a}},forceY:{get:function(){return u},set:function(a){u=a}},forcePoint:{get:function(){return v},set:function(a){v=a}},interactive:{get:function(){return w},set:function(a){w=a}},pointActive:{get:function(){return x},set:function(a){x=a}},padDataOuter:{get:function(){return z},set:function(a){z=a}},padData:{get:function(){return y},set:function(a){y=a}},clipEdge:{get:function(){return A},set:function(a){A=a}},clipVoronoi:{get:function(){return B},set:function(a){B=a}},clipRadius:{get:function(){return D},set:function(a){D=a}},showVoronoi:{get:function(){return C},set:function(a){C=a}},id:{get:function(){return k},set:function(a){k=a}},x:{get:function(){return p},set:function(a){p=d3.functor(a)}},y:{get:function(){return q},set:function(a){q=d3.functor(a)}},pointSize:{get:function(){return r},set:function(a){r=d3.functor(a)}},pointShape:{get:function(){return s},set:function(a){s=d3.functor(a)}},margin:{get:function(){return g},set:function(a){g.top=void 0!==a.top?a.top:g.top,g.right=void 0!==a.right?a.right:g.right,g.bottom=void 0!==a.bottom?a.bottom:g.bottom,g.left=void 0!==a.left?a.left:g.left}},duration:{get:function(){return N},set:function(a){N=a,P.reset(N)}},color:{get:function(){return j},set:function(b){j=a.utils.getColor(b)}},useVoronoi:{get:function(){return M},set:function(a){M=a,M===!1&&(B=!1)}}}),a.utils.initOptions(b),b},a.models.scatterChart=function(){"use strict";function b(z){return D.reset(),D.models(c),t&&D.models(d),u&&D.models(e),q&&D.models(g),r&&D.models(h),z.each(function(z){m=d3.select(this),a.utils.initSVG(m);var G=a.utils.availableWidth(k,m,j),H=a.utils.availableHeight(l,m,j);if(b.update=function(){0===A?m.call(b):m.transition().duration(A).call(b)},b.container=this,w.setter(F(z),b.update).getter(E(z)).update(),w.disabled=z.map(function(a){return!!a.disabled}),!x){var I;x={};for(I in w)x[I]=w[I]instanceof Array?w[I].slice(0):w[I]}if(!(z&&z.length&&z.filter(function(a){return a.values.length}).length))return a.utils.noData(b,m),D.renderEnd("scatter immediate"),b;m.selectAll(".nv-noData").remove(),o=c.xScale(),p=c.yScale();var J=m.selectAll("g.nv-wrap.nv-scatterChart").data([z]),K=J.enter().append("g").attr("class","nvd3 nv-wrap nv-scatterChart nv-chart-"+c.id()),L=K.append("g"),M=J.select("g");if(L.append("rect").attr("class","nvd3 nv-background").style("pointer-events","none"),L.append("g").attr("class","nv-x nv-axis"),L.append("g").attr("class","nv-y nv-axis"),L.append("g").attr("class","nv-scatterWrap"),L.append("g").attr("class","nv-regressionLinesWrap"),L.append("g").attr("class","nv-distWrap"),L.append("g").attr("class","nv-legendWrap"),v&&M.select(".nv-y.nv-axis").attr("transform","translate("+G+",0)"),s){var N=G;f.width(N),J.select(".nv-legendWrap").datum(z).call(f),j.top!=f.height()&&(j.top=f.height(),H=a.utils.availableHeight(l,m,j)),J.select(".nv-legendWrap").attr("transform","translate(0,"+-j.top+")")}J.attr("transform","translate("+j.left+","+j.top+")"),c.width(G).height(H).color(z.map(function(a,b){return a.color=a.color||n(a,b),a.color}).filter(function(a,b){return!z[b].disabled})),J.select(".nv-scatterWrap").datum(z.filter(function(a){return!a.disabled})).call(c),J.select(".nv-regressionLinesWrap").attr("clip-path","url(#nv-edge-clip-"+c.id()+")");var O=J.select(".nv-regressionLinesWrap").selectAll(".nv-regLines").data(function(a){return a});O.enter().append("g").attr("class","nv-regLines");var P=O.selectAll(".nv-regLine").data(function(a){return[a]});P.enter().append("line").attr("class","nv-regLine").style("stroke-opacity",0),P.filter(function(a){return a.intercept&&a.slope}).watchTransition(D,"scatterPlusLineChart: regline").attr("x1",o.range()[0]).attr("x2",o.range()[1]).attr("y1",function(a){return p(o.domain()[0]*a.slope+a.intercept)}).attr("y2",function(a){return p(o.domain()[1]*a.slope+a.intercept)}).style("stroke",function(a,b,c){return n(a,c)}).style("stroke-opacity",function(a){return a.disabled||"undefined"==typeof a.slope||"undefined"==typeof a.intercept?0:1}),t&&(d.scale(o)._ticks(a.utils.calcTicksX(G/100,z)).tickSize(-H,0),M.select(".nv-x.nv-axis").attr("transform","translate(0,"+p.range()[0]+")").call(d)),u&&(e.scale(p)._ticks(a.utils.calcTicksY(H/36,z)).tickSize(-G,0),M.select(".nv-y.nv-axis").call(e)),q&&(g.getData(c.x()).scale(o).width(G).color(z.map(function(a,b){return a.color||n(a,b)}).filter(function(a,b){return!z[b].disabled})),L.select(".nv-distWrap").append("g").attr("class","nv-distributionX"),M.select(".nv-distributionX").attr("transform","translate(0,"+p.range()[0]+")").datum(z.filter(function(a){return!a.disabled})).call(g)),r&&(h.getData(c.y()).scale(p).width(H).color(z.map(function(a,b){return a.color||n(a,b)}).filter(function(a,b){return!z[b].disabled})),L.select(".nv-distWrap").append("g").attr("class","nv-distributionY"),M.select(".nv-distributionY").attr("transform","translate("+(v?G:-h.size())+",0)").datum(z.filter(function(a){return!a.disabled})).call(h)),f.dispatch.on("stateChange",function(a){for(var c in a)w[c]=a[c];y.stateChange(w),b.update()}),y.on("changeState",function(a){"undefined"!=typeof a.disabled&&(z.forEach(function(b,c){b.disabled=a.disabled[c]}),w.disabled=a.disabled),b.update()}),c.dispatch.on("elementMouseout.tooltip",function(a){i.hidden(!0),m.select(".nv-chart-"+c.id()+" .nv-series-"+a.seriesIndex+" .nv-distx-"+a.pointIndex).attr("y1",0),m.select(".nv-chart-"+c.id()+" .nv-series-"+a.seriesIndex+" .nv-disty-"+a.pointIndex).attr("x2",h.size())}),c.dispatch.on("elementMouseover.tooltip",function(a){m.select(".nv-series-"+a.seriesIndex+" .nv-distx-"+a.pointIndex).attr("y1",a.pos.top-H-j.top),m.select(".nv-series-"+a.seriesIndex+" .nv-disty-"+a.pointIndex).attr("x2",a.pos.left+g.size()-j.left),i.position(a.pos).data(a).hidden(!1)}),B=o.copy(),C=p.copy()}),D.renderEnd("scatter with line immediate"),b}var c=a.models.scatter(),d=a.models.axis(),e=a.models.axis(),f=a.models.legend(),g=a.models.distribution(),h=a.models.distribution(),i=a.models.tooltip(),j={top:30,right:20,bottom:50,left:75},k=null,l=null,m=null,n=a.utils.defaultColor(),o=c.xScale(),p=c.yScale(),q=!1,r=!1,s=!0,t=!0,u=!0,v=!1,w=a.utils.state(),x=null,y=d3.dispatch("stateChange","changeState","renderEnd"),z=null,A=250;c.xScale(o).yScale(p),d.orient("bottom").tickPadding(10),e.orient(v?"right":"left").tickPadding(10),g.axis("x"),h.axis("y"),i.headerFormatter(function(a,b){return d.tickFormat()(a,b)}).valueFormatter(function(a,b){return e.tickFormat()(a,b)});var B,C,D=a.utils.renderWatch(y,A),E=function(a){return function(){return{active:a.map(function(a){return!a.disabled})}}},F=function(a){return function(b){void 0!==b.active&&a.forEach(function(a,c){a.disabled=!b.active[c]})}};return b.dispatch=y,b.scatter=c,b.legend=f,b.xAxis=d,b.yAxis=e,b.distX=g,b.distY=h,b.tooltip=i,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return k},set:function(a){k=a}},height:{get:function(){return l},set:function(a){l=a}},container:{get:function(){return m},set:function(a){m=a}},showDistX:{get:function(){return q},set:function(a){q=a}},showDistY:{get:function(){return r},set:function(a){r=a}},showLegend:{get:function(){return s},set:function(a){s=a}},showXAxis:{get:function(){return t},set:function(a){t=a}},showYAxis:{get:function(){return u},set:function(a){u=a}},defaultState:{get:function(){return x},set:function(a){x=a}},noData:{get:function(){return z},set:function(a){z=a}},duration:{get:function(){return A},set:function(a){A=a}},tooltips:{get:function(){return i.enabled()},set:function(b){a.deprecated("tooltips","use chart.tooltip.enabled() instead"),i.enabled(!!b) -}},tooltipContent:{get:function(){return i.contentGenerator()},set:function(b){a.deprecated("tooltipContent","use chart.tooltip.contentGenerator() instead"),i.contentGenerator(b)}},tooltipXContent:{get:function(){return i.contentGenerator()},set:function(){a.deprecated("tooltipContent","This option is removed, put values into main tooltip.")}},tooltipYContent:{get:function(){return i.contentGenerator()},set:function(){a.deprecated("tooltipContent","This option is removed, put values into main tooltip.")}},margin:{get:function(){return j},set:function(a){j.top=void 0!==a.top?a.top:j.top,j.right=void 0!==a.right?a.right:j.right,j.bottom=void 0!==a.bottom?a.bottom:j.bottom,j.left=void 0!==a.left?a.left:j.left}},rightAlignYAxis:{get:function(){return v},set:function(a){v=a,e.orient(a?"right":"left")}},color:{get:function(){return n},set:function(b){n=a.utils.getColor(b),f.color(n),g.color(n),h.color(n)}}}),a.utils.inheritOptions(b,c),a.utils.initOptions(b),b},a.models.sparkline=function(){"use strict";function b(k){return k.each(function(b){var k=h-g.left-g.right,q=i-g.top-g.bottom;j=d3.select(this),a.utils.initSVG(j),l.domain(c||d3.extent(b,n)).range(e||[0,k]),m.domain(d||d3.extent(b,o)).range(f||[q,0]);{var r=j.selectAll("g.nv-wrap.nv-sparkline").data([b]),s=r.enter().append("g").attr("class","nvd3 nv-wrap nv-sparkline");s.append("g"),r.select("g")}r.attr("transform","translate("+g.left+","+g.top+")");var t=r.selectAll("path").data(function(a){return[a]});t.enter().append("path"),t.exit().remove(),t.style("stroke",function(a,b){return a.color||p(a,b)}).attr("d",d3.svg.line().x(function(a,b){return l(n(a,b))}).y(function(a,b){return m(o(a,b))}));var u=r.selectAll("circle.nv-point").data(function(a){function b(b){if(-1!=b){var c=a[b];return c.pointIndex=b,c}return null}var c=a.map(function(a,b){return o(a,b)}),d=b(c.lastIndexOf(m.domain()[1])),e=b(c.indexOf(m.domain()[0])),f=b(c.length-1);return[e,d,f].filter(function(a){return null!=a})});u.enter().append("circle"),u.exit().remove(),u.attr("cx",function(a){return l(n(a,a.pointIndex))}).attr("cy",function(a){return m(o(a,a.pointIndex))}).attr("r",2).attr("class",function(a){return n(a,a.pointIndex)==l.domain()[1]?"nv-point nv-currentValue":o(a,a.pointIndex)==m.domain()[0]?"nv-point nv-minValue":"nv-point nv-maxValue"})}),b}var c,d,e,f,g={top:2,right:0,bottom:2,left:0},h=400,i=32,j=null,k=!0,l=d3.scale.linear(),m=d3.scale.linear(),n=function(a){return a.x},o=function(a){return a.y},p=a.utils.getColor(["#000"]);return b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return h},set:function(a){h=a}},height:{get:function(){return i},set:function(a){i=a}},xDomain:{get:function(){return c},set:function(a){c=a}},yDomain:{get:function(){return d},set:function(a){d=a}},xRange:{get:function(){return e},set:function(a){e=a}},yRange:{get:function(){return f},set:function(a){f=a}},xScale:{get:function(){return l},set:function(a){l=a}},yScale:{get:function(){return m},set:function(a){m=a}},animate:{get:function(){return k},set:function(a){k=a}},x:{get:function(){return n},set:function(a){n=d3.functor(a)}},y:{get:function(){return o},set:function(a){o=d3.functor(a)}},margin:{get:function(){return g},set:function(a){g.top=void 0!==a.top?a.top:g.top,g.right=void 0!==a.right?a.right:g.right,g.bottom=void 0!==a.bottom?a.bottom:g.bottom,g.left=void 0!==a.left?a.left:g.left}},color:{get:function(){return p},set:function(b){p=a.utils.getColor(b)}}}),a.utils.initOptions(b),b},a.models.sparklinePlus=function(){"use strict";function b(p){return p.each(function(p){function q(){if(!j){var a=z.selectAll(".nv-hoverValue").data(i),b=a.enter().append("g").attr("class","nv-hoverValue").style("stroke-opacity",0).style("fill-opacity",0);a.exit().transition().duration(250).style("stroke-opacity",0).style("fill-opacity",0).remove(),a.attr("transform",function(a){return"translate("+c(e.x()(p[a],a))+",0)"}).transition().duration(250).style("stroke-opacity",1).style("fill-opacity",1),i.length&&(b.append("line").attr("x1",0).attr("y1",-f.top).attr("x2",0).attr("y2",u),b.append("text").attr("class","nv-xValue").attr("x",-6).attr("y",-f.top).attr("text-anchor","end").attr("dy",".9em"),z.select(".nv-hoverValue .nv-xValue").text(k(e.x()(p[i[0]],i[0]))),b.append("text").attr("class","nv-yValue").attr("x",6).attr("y",-f.top).attr("text-anchor","start").attr("dy",".9em"),z.select(".nv-hoverValue .nv-yValue").text(l(e.y()(p[i[0]],i[0]))))}}function r(){function a(a,b){for(var c=Math.abs(e.x()(a[0],0)-b),d=0,f=0;fc;++c){for(b=0,d=0;bb;b++)a[b][c][1]/=d;else for(b=0;e>b;b++)a[b][c][1]=0}for(c=0;f>c;++c)g[c]=0;return g}}),u.renderEnd("stackedArea immediate"),b}var c,d,e={top:0,right:0,bottom:0,left:0},f=960,g=500,h=a.utils.defaultColor(),i=Math.floor(1e5*Math.random()),j=null,k=function(a){return a.x},l=function(a){return a.y},m="stack",n="zero",o="default",p="linear",q=!1,r=a.models.scatter(),s=250,t=d3.dispatch("areaClick","areaMouseover","areaMouseout","renderEnd","elementClick","elementMouseover","elementMouseout");r.pointSize(2.2).pointDomain([2.2,2.2]);var u=a.utils.renderWatch(t,s);return b.dispatch=t,b.scatter=r,r.dispatch.on("elementClick",function(){t.elementClick.apply(this,arguments)}),r.dispatch.on("elementMouseover",function(){t.elementMouseover.apply(this,arguments)}),r.dispatch.on("elementMouseout",function(){t.elementMouseout.apply(this,arguments)}),b.interpolate=function(a){return arguments.length?(p=a,b):p},b.duration=function(a){return arguments.length?(s=a,u.reset(s),r.duration(s),b):s},b.dispatch=t,b.scatter=r,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return f},set:function(a){f=a}},height:{get:function(){return g},set:function(a){g=a}},clipEdge:{get:function(){return q},set:function(a){q=a}},offset:{get:function(){return n},set:function(a){n=a}},order:{get:function(){return o},set:function(a){o=a}},interpolate:{get:function(){return p},set:function(a){p=a}},x:{get:function(){return k},set:function(a){k=d3.functor(a)}},y:{get:function(){return l},set:function(a){l=d3.functor(a)}},margin:{get:function(){return e},set:function(a){e.top=void 0!==a.top?a.top:e.top,e.right=void 0!==a.right?a.right:e.right,e.bottom=void 0!==a.bottom?a.bottom:e.bottom,e.left=void 0!==a.left?a.left:e.left}},color:{get:function(){return h},set:function(b){h=a.utils.getColor(b)}},style:{get:function(){return m},set:function(a){switch(m=a){case"stack":b.offset("zero"),b.order("default");break;case"stream":b.offset("wiggle"),b.order("inside-out");break;case"stream-center":b.offset("silhouette"),b.order("inside-out");break;case"expand":b.offset("expand"),b.order("default");break;case"stack_percent":b.offset(b.d3_stackedOffset_stackPercent),b.order("default")}}},duration:{get:function(){return s},set:function(a){s=a,u.reset(s),r.duration(s)}}}),a.utils.inheritOptions(b,r),a.utils.initOptions(b),b},a.models.stackedAreaChart=function(){"use strict";function b(k){return F.reset(),F.models(e),r&&F.models(f),s&&F.models(g),k.each(function(k){var x=d3.select(this),F=this;a.utils.initSVG(x);var K=a.utils.availableWidth(m,x,l),L=a.utils.availableHeight(n,x,l);if(b.update=function(){x.transition().duration(C).call(b)},b.container=this,v.setter(I(k),b.update).getter(H(k)).update(),v.disabled=k.map(function(a){return!!a.disabled}),!w){var M;w={};for(M in v)w[M]=v[M]instanceof Array?v[M].slice(0):v[M]}if(!(k&&k.length&&k.filter(function(a){return a.values.length}).length))return a.utils.noData(b,x),b;x.selectAll(".nv-noData").remove(),c=e.xScale(),d=e.yScale();var N=x.selectAll("g.nv-wrap.nv-stackedAreaChart").data([k]),O=N.enter().append("g").attr("class","nvd3 nv-wrap nv-stackedAreaChart").append("g"),P=N.select("g");if(O.append("rect").style("opacity",0),O.append("g").attr("class","nv-x nv-axis"),O.append("g").attr("class","nv-y nv-axis"),O.append("g").attr("class","nv-stackedWrap"),O.append("g").attr("class","nv-legendWrap"),O.append("g").attr("class","nv-controlsWrap"),O.append("g").attr("class","nv-interactive"),P.select("rect").attr("width",K).attr("height",L),q){var Q=p?K-z:K;h.width(Q),P.select(".nv-legendWrap").datum(k).call(h),l.top!=h.height()&&(l.top=h.height(),L=a.utils.availableHeight(n,x,l)),P.select(".nv-legendWrap").attr("transform","translate("+(K-Q)+","+-l.top+")")}if(p){var R=[{key:B.stacked||"Stacked",metaKey:"Stacked",disabled:"stack"!=e.style(),style:"stack"},{key:B.stream||"Stream",metaKey:"Stream",disabled:"stream"!=e.style(),style:"stream"},{key:B.expanded||"Expanded",metaKey:"Expanded",disabled:"expand"!=e.style(),style:"expand"},{key:B.stack_percent||"Stack %",metaKey:"Stack_Percent",disabled:"stack_percent"!=e.style(),style:"stack_percent"}];z=A.length/3*260,R=R.filter(function(a){return-1!==A.indexOf(a.metaKey)}),i.width(z).color(["#444","#444","#444"]),P.select(".nv-controlsWrap").datum(R).call(i),l.top!=Math.max(i.height(),h.height())&&(l.top=Math.max(i.height(),h.height()),L=a.utils.availableHeight(n,x,l)),P.select(".nv-controlsWrap").attr("transform","translate(0,"+-l.top+")")}N.attr("transform","translate("+l.left+","+l.top+")"),t&&P.select(".nv-y.nv-axis").attr("transform","translate("+K+",0)"),u&&(j.width(K).height(L).margin({left:l.left,top:l.top}).svgContainer(x).xScale(c),N.select(".nv-interactive").call(j)),e.width(K).height(L);var S=P.select(".nv-stackedWrap").datum(k);if(S.transition().call(e),r&&(f.scale(c)._ticks(a.utils.calcTicksX(K/100,k)).tickSize(-L,0),P.select(".nv-x.nv-axis").attr("transform","translate(0,"+L+")"),P.select(".nv-x.nv-axis").transition().duration(0).call(f)),s){var T;if(T="wiggle"===e.offset()?0:a.utils.calcTicksY(L/36,k),g.scale(d)._ticks(T).tickSize(-K,0),"expand"===e.style()||"stack_percent"===e.style()){var U=g.tickFormat();D&&U===J||(D=U),g.tickFormat(J)}else D&&(g.tickFormat(D),D=null);P.select(".nv-y.nv-axis").transition().duration(0).call(g)}e.dispatch.on("areaClick.toggle",function(a){k.forEach(1===k.filter(function(a){return!a.disabled}).length?function(a){a.disabled=!1}:function(b,c){b.disabled=c!=a.seriesIndex}),v.disabled=k.map(function(a){return!!a.disabled}),y.stateChange(v),b.update()}),h.dispatch.on("stateChange",function(a){for(var c in a)v[c]=a[c];y.stateChange(v),b.update()}),i.dispatch.on("legendClick",function(a){a.disabled&&(R=R.map(function(a){return a.disabled=!0,a}),a.disabled=!1,e.style(a.style),v.style=e.style(),y.stateChange(v),b.update())}),j.dispatch.on("elementMousemove",function(c){e.clearHighlights();var d,g,h,i=[];if(k.filter(function(a,b){return a.seriesIndex=b,!a.disabled}).forEach(function(f,j){g=a.interactiveBisect(f.values,c.pointXValue,b.x());var k=f.values[g],l=b.y()(k,g);if(null!=l&&e.highlightPoint(j,g,!0),"undefined"!=typeof k){"undefined"==typeof d&&(d=k),"undefined"==typeof h&&(h=b.xScale()(b.x()(k,g)));var m="expand"==e.style()?k.display.y:b.y()(k,g);i.push({key:f.key,value:m,color:o(f,f.seriesIndex),stackedValue:k.display})}}),i.reverse(),i.length>2){var m=b.yScale().invert(c.mouseY),n=null;i.forEach(function(a,b){m=Math.abs(m);var c=Math.abs(a.stackedValue.y0),d=Math.abs(a.stackedValue.y);return m>=c&&d+c>=m?void(n=b):void 0}),null!=n&&(i[n].highlight=!0)}var p=f.tickFormat()(b.x()(d,g)),q=j.tooltip.valueFormatter();"expand"===e.style()||"stack_percent"===e.style()?(E||(E=q),q=d3.format(".1%")):E&&(q=E,E=null),j.tooltip.position({left:h+l.left,top:c.mouseY+l.top}).chartContainer(F.parentNode).valueFormatter(q).data({value:p,series:i})(),j.renderGuideLine(h)}),j.dispatch.on("elementMouseout",function(){e.clearHighlights()}),y.on("changeState",function(a){"undefined"!=typeof a.disabled&&k.length===a.disabled.length&&(k.forEach(function(b,c){b.disabled=a.disabled[c]}),v.disabled=a.disabled),"undefined"!=typeof a.style&&(e.style(a.style),G=a.style),b.update()})}),F.renderEnd("stacked Area chart immediate"),b}var c,d,e=a.models.stackedArea(),f=a.models.axis(),g=a.models.axis(),h=a.models.legend(),i=a.models.legend(),j=a.interactiveGuideline(),k=a.models.tooltip(),l={top:30,right:25,bottom:50,left:60},m=null,n=null,o=a.utils.defaultColor(),p=!0,q=!0,r=!0,s=!0,t=!1,u=!1,v=a.utils.state(),w=null,x=null,y=d3.dispatch("stateChange","changeState","renderEnd"),z=250,A=["Stacked","Stream","Expanded"],B={},C=250;v.style=e.style(),f.orient("bottom").tickPadding(7),g.orient(t?"right":"left"),k.headerFormatter(function(a,b){return f.tickFormat()(a,b)}).valueFormatter(function(a,b){return g.tickFormat()(a,b)}),j.tooltip.headerFormatter(function(a,b){return f.tickFormat()(a,b)}).valueFormatter(function(a,b){return g.tickFormat()(a,b)});var D=null,E=null;i.updateState(!1);var F=a.utils.renderWatch(y),G=e.style(),H=function(a){return function(){return{active:a.map(function(a){return!a.disabled}),style:e.style()}}},I=function(a){return function(b){void 0!==b.style&&(G=b.style),void 0!==b.active&&a.forEach(function(a,c){a.disabled=!b.active[c]})}},J=d3.format("%");return e.dispatch.on("elementMouseover.tooltip",function(a){a.point.x=e.x()(a.point),a.point.y=e.y()(a.point),k.data(a).position(a.pos).hidden(!1)}),e.dispatch.on("elementMouseout.tooltip",function(){k.hidden(!0)}),b.dispatch=y,b.stacked=e,b.legend=h,b.controls=i,b.xAxis=f,b.yAxis=g,b.interactiveLayer=j,b.tooltip=k,b.dispatch=y,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return m},set:function(a){m=a}},height:{get:function(){return n},set:function(a){n=a}},showLegend:{get:function(){return q},set:function(a){q=a}},showXAxis:{get:function(){return r},set:function(a){r=a}},showYAxis:{get:function(){return s},set:function(a){s=a}},defaultState:{get:function(){return w},set:function(a){w=a}},noData:{get:function(){return x},set:function(a){x=a}},showControls:{get:function(){return p},set:function(a){p=a}},controlLabels:{get:function(){return B},set:function(a){B=a}},controlOptions:{get:function(){return A},set:function(a){A=a}},tooltips:{get:function(){return k.enabled()},set:function(b){a.deprecated("tooltips","use chart.tooltip.enabled() instead"),k.enabled(!!b)}},tooltipContent:{get:function(){return k.contentGenerator()},set:function(b){a.deprecated("tooltipContent","use chart.tooltip.contentGenerator() instead"),k.contentGenerator(b)}},margin:{get:function(){return l},set:function(a){l.top=void 0!==a.top?a.top:l.top,l.right=void 0!==a.right?a.right:l.right,l.bottom=void 0!==a.bottom?a.bottom:l.bottom,l.left=void 0!==a.left?a.left:l.left}},duration:{get:function(){return C},set:function(a){C=a,F.reset(C),e.duration(C),f.duration(C),g.duration(C)}},color:{get:function(){return o},set:function(b){o=a.utils.getColor(b),h.color(o),e.color(o)}},rightAlignYAxis:{get:function(){return t},set:function(a){t=a,g.orient(t?"right":"left")}},useInteractiveGuideline:{get:function(){return u},set:function(a){u=!!a,b.interactive(!a),b.useVoronoi(!a),e.scatter.interactive(!a)}}}),a.utils.inheritOptions(b,e),a.utils.initOptions(b),b},a.models.sunburst=function(){"use strict";function b(u){return t.reset(),u.each(function(b){function t(a){a.x0=a.x,a.dx0=a.dx}function u(a){var b=d3.interpolate(p.domain(),[a.x,a.x+a.dx]),c=d3.interpolate(q.domain(),[a.y,1]),d=d3.interpolate(q.range(),[a.y?20:0,y]);return function(a,e){return e?function(){return s(a)}:function(e){return p.domain(b(e)),q.domain(c(e)).range(d(e)),s(a)}}}l=d3.select(this);var v,w=a.utils.availableWidth(g,l,f),x=a.utils.availableHeight(h,l,f),y=Math.min(w,x)/2;a.utils.initSVG(l);var z=l.selectAll(".nv-wrap.nv-sunburst").data(b),A=z.enter().append("g").attr("class","nvd3 nv-wrap nv-sunburst nv-chart-"+k),B=A.selectAll("nv-sunburst");z.attr("transform","translate("+w/2+","+x/2+")"),l.on("click",function(a,b){o.chartClick({data:a,index:b,pos:d3.event,id:k})}),q.range([0,y]),c=c||b,e=b[0],r.value(j[i]||j.count),v=B.data(r.nodes).enter().append("path").attr("d",s).style("fill",function(a){return m((a.children?a:a.parent).name)}).style("stroke","#FFF").on("click",function(a){d!==c&&c!==a&&(d=c),c=a,v.transition().duration(n).attrTween("d",u(a))}).each(t).on("dblclick",function(a){d.parent==a&&v.transition().duration(n).attrTween("d",u(e))}).each(t).on("mouseover",function(a){d3.select(this).classed("hover",!0).style("opacity",.8),o.elementMouseover({data:a,color:d3.select(this).style("fill")})}).on("mouseout",function(a){d3.select(this).classed("hover",!1).style("opacity",1),o.elementMouseout({data:a})}).on("mousemove",function(a){o.elementMousemove({data:a})})}),t.renderEnd("sunburst immediate"),b}var c,d,e,f={top:0,right:0,bottom:0,left:0},g=null,h=null,i="count",j={count:function(){return 1},size:function(a){return a.size}},k=Math.floor(1e4*Math.random()),l=null,m=a.utils.defaultColor(),n=500,o=d3.dispatch("chartClick","elementClick","elementDblClick","elementMousemove","elementMouseover","elementMouseout","renderEnd"),p=d3.scale.linear().range([0,2*Math.PI]),q=d3.scale.sqrt(),r=d3.layout.partition().sort(null).value(function(){return 1}),s=d3.svg.arc().startAngle(function(a){return Math.max(0,Math.min(2*Math.PI,p(a.x)))}).endAngle(function(a){return Math.max(0,Math.min(2*Math.PI,p(a.x+a.dx)))}).innerRadius(function(a){return Math.max(0,q(a.y))}).outerRadius(function(a){return Math.max(0,q(a.y+a.dy))}),t=a.utils.renderWatch(o);return b.dispatch=o,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return g},set:function(a){g=a}},height:{get:function(){return h},set:function(a){h=a}},mode:{get:function(){return i},set:function(a){i=a}},id:{get:function(){return k},set:function(a){k=a}},duration:{get:function(){return n},set:function(a){n=a}},margin:{get:function(){return f},set:function(a){f.top=void 0!=a.top?a.top:f.top,f.right=void 0!=a.right?a.right:f.right,f.bottom=void 0!=a.bottom?a.bottom:f.bottom,f.left=void 0!=a.left?a.left:f.left}},color:{get:function(){return m},set:function(b){m=a.utils.getColor(b)}}}),a.utils.initOptions(b),b},a.models.sunburstChart=function(){"use strict";function b(d){return m.reset(),m.models(c),d.each(function(d){var h=d3.select(this);a.utils.initSVG(h);var i=a.utils.availableWidth(f,h,e),j=a.utils.availableHeight(g,h,e);if(b.update=function(){0===k?h.call(b):h.transition().duration(k).call(b)},b.container=this,!d||!d.length)return a.utils.noData(b,h),b;h.selectAll(".nv-noData").remove();var l=h.selectAll("g.nv-wrap.nv-sunburstChart").data(d),m=l.enter().append("g").attr("class","nvd3 nv-wrap nv-sunburstChart").append("g"),n=l.select("g");m.append("g").attr("class","nv-sunburstWrap"),l.attr("transform","translate("+e.left+","+e.top+")"),c.width(i).height(j);var o=n.select(".nv-sunburstWrap").datum(d);d3.transition(o).call(c)}),m.renderEnd("sunburstChart immediate"),b}var c=a.models.sunburst(),d=a.models.tooltip(),e={top:30,right:20,bottom:20,left:20},f=null,g=null,h=a.utils.defaultColor(),i=(Math.round(1e5*Math.random()),null),j=null,k=250,l=d3.dispatch("tooltipShow","tooltipHide","stateChange","changeState","renderEnd"),m=a.utils.renderWatch(l);return d.headerEnabled(!1).duration(0).valueFormatter(function(a){return a}),c.dispatch.on("elementMouseover.tooltip",function(a){a.series={key:a.data.name,value:a.data.size,color:a.color},d.data(a).hidden(!1)}),c.dispatch.on("elementMouseout.tooltip",function(){d.hidden(!0)}),c.dispatch.on("elementMousemove.tooltip",function(){d.position({top:d3.event.pageY,left:d3.event.pageX})()}),b.dispatch=l,b.sunburst=c,b.tooltip=d,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{noData:{get:function(){return j},set:function(a){j=a}},defaultState:{get:function(){return i},set:function(a){i=a}},color:{get:function(){return h},set:function(a){h=a,c.color(h)}},duration:{get:function(){return k},set:function(a){k=a,m.reset(k),c.duration(k)}},margin:{get:function(){return e},set:function(a){e.top=void 0!==a.top?a.top:e.top,e.right=void 0!==a.right?a.right:e.right,e.bottom=void 0!==a.bottom?a.bottom:e.bottom,e.left=void 0!==a.left?a.left:e.left}}}),a.utils.inheritOptions(b,c),a.utils.initOptions(b),b},a.version="1.8.1"}(); \ No newline at end of file diff --git a/backend/coverage-report-with-models/dashboard.html b/backend/coverage-report-with-models/dashboard.html deleted file mode 100644 index b2d75154..00000000 --- a/backend/coverage-report-with-models/dashboard.html +++ /dev/null @@ -1,717 +0,0 @@ - - - - - Dashboard for /var/www/html/backend/app - - - - - - - -
-
-
-
- -
-
-
-
-
-
-
-

Classes

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
-
-
-

Insufficient Coverage

-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
ClassCoverage
App\Console\Commands\FetchNewArticlesCommand0%
App\Console\Commands\SyncChannelPostsCommand0%
App\Events\ArticleReadyToPublish0%
App\Events\ExceptionLogged0%
App\Events\ExceptionOccurred0%
App\Exceptions\PlatformAuthException0%
App\Exceptions\PublishException0%
App\Exceptions\RoutingMismatchException0%
App\Http\Controllers\Api\V1\AuthController0%
App\Http\Controllers\Api\V1\LogsController0%
App\Http\Controllers\Api\V1\PlatformAccountsController0%
App\Http\Controllers\Api\V1\PlatformChannelsController0%
App\Http\Controllers\Api\V1\RoutingController0%
App\Http\Controllers\ArticlesController0%
App\Http\Controllers\FeedsController0%
App\Http\Controllers\LogsController0%
App\Http\Controllers\OnboardingController0%
App\Http\Controllers\PlatformAccountsController0%
App\Http\Controllers\PlatformChannelsController0%
App\Http\Controllers\RoutingController0%
App\Http\Controllers\SettingsController0%
App\Http\Middleware\HandleAppearance0%
App\Http\Middleware\HandleInertiaRequests0%
App\Http\Resources\ArticlePublicationResource0%
App\Http\Resources\PlatformAccountResource0%
App\Http\Resources\PlatformChannelResource0%
App\Http\Resources\PlatformInstanceResource0%
App\Http\Resources\RouteResource0%
App\Jobs\ArticleDiscoveryForFeedJob0%
App\Jobs\ArticleDiscoveryJob0%
App\Jobs\PublishToLemmyJob0%
App\Jobs\SyncChannelPostsJob0%
App\Listeners\LogExceptionToDatabase0%
App\Listeners\PublishApprovedArticle0%
App\Listeners\PublishArticle0%
App\Listeners\ValidateArticleListener0%
App\Models\ArticlePublication0%
App\Models\Keyword0%
App\Models\Language0%
App\Models\PlatformAccount0%
App\Models\PlatformChannel0%
App\Models\PlatformChannelPost0%
App\Models\PlatformInstance0%
App\Models\Route0%
App\Models\User0%
App\Modules\Lemmy\LemmyRequest0%
App\Modules\Lemmy\Services\LemmyApiService0%
App\Modules\Lemmy\Services\LemmyPublisher0%
App\Services\Article\ArticleFetcher0%
App\Services\Article\ValidationService0%
App\Services\Auth\LemmyAuthService0%
App\Services\Factories\ArticleParserFactory0%
App\Services\Factories\HomepageParserFactory0%
App\Services\Http\HttpFetcher0%
App\Services\Log\LogSaver0%
App\Services\OnboardingRedirectService0%
App\Services\Parsers\BelgaArticlePageParser0%
App\Services\Parsers\BelgaArticleParser0%
App\Services\Parsers\BelgaHomepageParser0%
App\Services\Parsers\BelgaHomepageParserAdapter0%
App\Services\Parsers\VrtArticlePageParser0%
App\Services\Parsers\VrtArticleParser0%
App\Services\Parsers\VrtHomepageParser0%
App\Services\Parsers\VrtHomepageParserAdapter0%
App\Services\Publishing\ArticlePublishingService0%
App\Services\RoutingValidationService0%
App\Services\SystemStatusService0%
App\Models\Feed4%
App\Models\Article66%
App\Providers\HorizonServiceProvider75%
App\Http\Controllers\Api\V1\FeedsController76%
App\Providers\AppServiceProvider82%
App\Http\Controllers\Api\V1\DashboardController84%
App\Http\Controllers\Api\V1\SettingsController85%
App\Http\Controllers\Api\V1\BaseController87%
App\Http\Controllers\Api\V1\ArticlesController87%
-
-
-
-

Project Risks

-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
ClassCRAP
App\Http\Controllers\OnboardingController506
App\Modules\Lemmy\Services\LemmyApiService462
App\Http\Controllers\Api\V1\RoutingController306
App\Services\Parsers\BelgaArticlePageParser306
App\Http\Controllers\RoutingController240
App\Http\Controllers\Api\V1\PlatformAccountsController210
App\Services\Parsers\VrtArticlePageParser210
App\Http\Controllers\Api\V1\PlatformChannelsController182
App\Jobs\SyncChannelPostsJob182
App\Models\Feed161
App\Http\Controllers\Api\V1\AuthController132
App\Services\Article\ArticleFetcher132
App\Http\Controllers\PlatformAccountsController110
App\Http\Controllers\PlatformChannelsController110
App\Models\PlatformAccount110
App\Http\Controllers\FeedsController90
App\Services\Http\HttpFetcher90
App\Services\SystemStatusService72
App\Listeners\ValidateArticleListener56
App\Modules\Lemmy\LemmyRequest42
App\Services\Auth\LemmyAuthService42
App\Services\Factories\ArticleParserFactory42
App\Services\Log\LogSaver42
App\Exceptions\PublishException30
App\Services\Article\ValidationService30
App\Services\Factories\HomepageParserFactory30
App\Services\Publishing\ArticlePublishingService30
App\Services\RoutingValidationService30
App\Models\Article23
App\Listeners\PublishApprovedArticle20
App\Http\Controllers\Api\V1\FeedsController15
App\Console\Commands\FetchNewArticlesCommand12
App\Console\Commands\SyncChannelPostsCommand12
App\Http\Controllers\Api\V1\LogsController12
App\Http\Controllers\SettingsController12
App\Jobs\ArticleDiscoveryJob12
App\Jobs\PublishToLemmyJob12
App\Listeners\PublishArticle12
App\Http\Controllers\Api\V1\SettingsController7
App\Providers\AppServiceProvider6
App\Http\Controllers\Api\V1\BaseController6
App\Services\OnboardingRedirectService6
App\Http\Controllers\Api\V1\ArticlesController5
App\Http\Controllers\Api\V1\DashboardController3
-
-
-
-
-
-

Methods

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
-
-
-

Insufficient Coverage

-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
MethodCoverage
handle0%
handle0%
syncLemmy0%
__construct0%
__construct0%
__construct0%
__construct0%
getPlatform0%
__construct0%
getArticle0%
getPlatform0%
__construct0%
login0%
register0%
logout0%
me0%
sendNotFound0%
sendUnauthorized0%
index0%
index0%
store0%
show0%
update0%
destroy0%
setActive0%
index0%
store0%
show0%
update0%
destroy0%
toggle0%
index0%
store0%
show0%
update0%
destroy0%
toggle0%
__invoke0%
approve0%
reject0%
index0%
create0%
store0%
show0%
edit0%
update0%
destroy0%
toggle0%
__invoke0%
index0%
platform0%
feed0%
channel0%
complete0%
needsOnboarding0%
hasPlatformAccount0%
hasFeed0%
hasChannel0%
index0%
create0%
store0%
edit0%
update0%
destroy0%
setActive0%
index0%
create0%
store0%
show0%
edit0%
update0%
destroy0%
toggle0%
index0%
create0%
store0%
edit0%
update0%
destroy0%
toggle0%
parseJsonFilters0%
index0%
update0%
handle0%
version0%
share0%
toArray0%
toArray0%
toArray0%
toArray0%
toArray0%
__construct0%
handle0%
dispatchForAllActiveFeeds0%
__construct0%
handle0%
__construct0%
handle0%
__construct0%
dispatchForAllActiveChannels0%
handle0%
syncLemmyChannelPosts0%
getAuthToken0%
handle0%
handle0%
__construct0%
handle0%
handle0%
isValid0%
isApproved0%
isPending0%
isRejected0%
canBePublished0%
article0%
getTypeDisplayAttribute0%
getStatusAttribute0%
channels0%
activeChannels0%
language0%
feed0%
platformChannel0%
platformInstances0%
platformChannels0%
feeds0%
password0%
apiToken0%
getActive0%
setAsActive0%
channels0%
activeChannels0%
platformInstance0%
platformAccounts0%
activePlatformAccounts0%
getFullNameAttribute0%
feeds0%
activeFeeds0%
language0%
casts0%
urlExists0%
storePost0%
channels0%
languages0%
findByUrl0%
feed0%
platformChannel0%
keywords0%
casts0%
__construct0%
get0%
post0%
withToken0%
__construct0%
login0%
getCommunityId0%
syncChannelPosts0%
createPost0%
getLanguages0%
__construct0%
publishToChannel0%
mapExceptionToLogLevel0%
getArticlesFromFeed0%
getArticlesFromRssFeed0%
getArticlesFromWebsiteFeed0%
fetchArticleData0%
saveArticle0%
validate0%
validateByKeywords0%
getToken0%
getParser0%
getSupportedSources0%
registerParser0%
getParser0%
getParserForFeed0%
fetchHtml0%
fetchMultipleUrls0%
info0%
error0%
warning0%
debug0%
log0%
handleRedirect0%
extractTitle0%
extractDescription0%
extractFullArticle0%
extractThumbnail0%
extractData0%
canParse0%
extractData0%
getSourceName0%
extractArticleUrls0%
canParse0%
extractArticleUrls0%
getHomepageUrl0%
getSourceName0%
extractTitle0%
extractDescription0%
extractFullArticle0%
extractThumbnail0%
extractData0%
canParse0%
extractData0%
getSourceName0%
extractArticleUrls0%
canParse0%
extractArticleUrls0%
getHomepageUrl0%
getSourceName0%
publishToRoutedChannels0%
publishToChannel0%
validateLanguageCompatibility0%
getSystemStatus0%
canProcessArticles0%
update63%
store66%
gate66%
approve71%
reject71%
destroy71%
index71%
toggle77%
stats83%
-
-
- -
- -
- - - - - - diff --git a/backend/coverage-report-with-models/index.html b/backend/coverage-report-with-models/index.html deleted file mode 100644 index 3d8a3a8f..00000000 --- a/backend/coverage-report-with-models/index.html +++ /dev/null @@ -1,424 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 16.65% covered (danger) -
-
-
16.65%
277 / 1664
-
- 14.23% covered (danger) -
-
-
14.23%
37 / 260
-
- 10.59% covered (danger) -
-
-
10.59%
9 / 85
Console
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 16
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
Contracts
n/a
0 / 0
n/a
0 / 0
n/a
0 / 0
Enums
n/a
0 / 0
n/a
0 / 0
n/a
0 / 0
Events
-
- 40.00% covered (danger) -
-
-
40.00%
2 / 5
-
- 40.00% covered (danger) -
-
-
40.00%
2 / 5
-
- 40.00% covered (danger) -
-
-
40.00%
2 / 5
Exceptions
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 19
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 6
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
Http
-
- 20.07% covered (danger) -
-
-
20.07%
164 / 817
-
- 12.87% covered (danger) -
-
-
12.87%
13 / 101
-
- 13.79% covered (danger) -
-
-
13.79%
4 / 29
Jobs
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 81
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 12
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 4
Listeners
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 43
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 5
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 4
Models
-
- 24.34% covered (danger) -
-
-
24.34%
37 / 152
-
- 27.78% covered (danger) -
-
-
27.78%
15 / 54
-
- 8.33% covered (danger) -
-
-
8.33%
1 / 12
Modules
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 120
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 12
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
Providers
-
- 81.82% covered (warning) -
-
-
81.82%
27 / 33
-
- 40.00% covered (danger) -
-
-
40.00%
2 / 5
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
Services
-
- 10.78% covered (danger) -
-
-
10.78%
40 / 371
-
- 7.14% covered (danger) -
-
-
7.14%
4 / 56
-
- 5.00% covered (danger) -
-
-
5.00%
1 / 20
LogLevelEnum.php
-
- 100.00% covered (success) -
-
-
100.00%
7 / 7
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
-
- -
- - diff --git a/backend/coverage-report/Console/Commands/FetchNewArticlesCommand.php.html b/backend/coverage-report/Console/Commands/FetchNewArticlesCommand.php.html deleted file mode 100644 index 091d19e3..00000000 --- a/backend/coverage-report/Console/Commands/FetchNewArticlesCommand.php.html +++ /dev/null @@ -1,187 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Console/Commands/FetchNewArticlesCommand.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 75.00% covered (warning) -
-
-
75.00%
6 / 8
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
FetchNewArticlesCommand
-
- 75.00% covered (warning) -
-
-
75.00%
6 / 8
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
3.14
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 handle
-
- 75.00% covered (warning) -
-
-
75.00%
6 / 8
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
3.14
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Console\Commands;
4
5use App\Jobs\ArticleDiscoveryJob;
6use App\Models\Feed;
7use App\Models\Setting;
8use Illuminate\Console\Command;
9
10class FetchNewArticlesCommand extends Command
11{
12    protected $signature = 'article:refresh';
13
14    protected $description = 'Fetches latest articles';
15
16    public function handle(): int
17    {
18        if (!Setting::isArticleProcessingEnabled()) {
19            $this->info('Article processing is disabled. Article discovery skipped.');
20
21            return self::SUCCESS;
22        }
23
24        if (!Feed::where('is_active', true)->exists()) {
25            $this->info('No active feeds found. Article discovery skipped.');
26
27            return self::SUCCESS;
28        }
29
30        ArticleDiscoveryJob::dispatch();
31
32        return self::SUCCESS;
33    }
34}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 19:15:34 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report/Console/Commands/SyncChannelPostsCommand.php.html b/backend/coverage-report/Console/Commands/SyncChannelPostsCommand.php.html deleted file mode 100644 index 9feb9db3..00000000 --- a/backend/coverage-report/Console/Commands/SyncChannelPostsCommand.php.html +++ /dev/null @@ -1,209 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Console/Commands/SyncChannelPostsCommand.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 8
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
SyncChannelPostsCommand
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 8
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
12
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 handle
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 5
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
6
 syncLemmy
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Console\Commands;
4
5use App\Jobs\SyncChannelPostsJob;
6use Illuminate\Console\Command;
7
8class SyncChannelPostsCommand extends Command
9{
10    protected $signature = 'channel:sync {platform=lemmy}';
11
12    protected $description = 'Manually sync channel posts for a platform';
13
14    public function handle(): int
15    {
16        $platform = $this->argument('platform');
17
18        if ($platform === 'lemmy') {
19            return $this->syncLemmy();
20        }
21
22        $this->error("Unsupported platform: {$platform}");
23
24        return self::FAILURE;
25    }
26
27    private function syncLemmy(): int
28    {
29        SyncChannelPostsJob::dispatchForAllActiveChannels();
30        $this->info('Successfully dispatched sync jobs for all active Lemmy channels');
31
32        return self::SUCCESS;
33    }
34}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 19:15:34 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report/Console/Commands/dashboard.html b/backend/coverage-report/Console/Commands/dashboard.html deleted file mode 100644 index 9bc83c1a..00000000 --- a/backend/coverage-report/Console/Commands/dashboard.html +++ /dev/null @@ -1,294 +0,0 @@ - - - - - Dashboard for /var/www/html/backend/app/Console/Commands - - - - - - - -
-
-
-
- -
-
-
-
-
-
-
-

Classes

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
-
-
-

Insufficient Coverage

- -
-
-

Project Risks

- -
-
-
-
-

Methods

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
-
-
-

Insufficient Coverage

-
- - - - - - - - - - - - - -
MethodCoverage
handle0%
syncLemmy0%
handle75%
-
-
-
-

Project Risks

-
- - - - - - - - - - - - -
MethodCRAP
handle6
handle3
-
-
-
- -
- - - - - - diff --git a/backend/coverage-report/Console/Commands/index.html b/backend/coverage-report/Console/Commands/index.html deleted file mode 100644 index f9bb6879..00000000 --- a/backend/coverage-report/Console/Commands/index.html +++ /dev/null @@ -1,148 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Console/Commands - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 37.50% covered (danger) -
-
-
37.50%
6 / 16
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
FetchNewArticlesCommand.php
-
- 75.00% covered (warning) -
-
-
75.00%
6 / 8
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
SyncChannelPostsCommand.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 8
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- -
- - diff --git a/backend/coverage-report/Console/dashboard.html b/backend/coverage-report/Console/dashboard.html deleted file mode 100644 index ed51e558..00000000 --- a/backend/coverage-report/Console/dashboard.html +++ /dev/null @@ -1,293 +0,0 @@ - - - - - Dashboard for /var/www/html/backend/app/Console - - - - - - - -
-
-
-
- -
-
-
-
-
-
-
-

Classes

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
-
-
-

Insufficient Coverage

- -
-
-

Project Risks

- -
-
-
-
-

Methods

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
-
-
-

Insufficient Coverage

-
- - - - - - - - - - - - - -
MethodCoverage
handle0%
syncLemmy0%
handle75%
-
-
-
-

Project Risks

-
- - - - - - - - - - - - -
MethodCRAP
handle6
handle3
-
-
-
- -
- - - - - - diff --git a/backend/coverage-report/Console/index.html b/backend/coverage-report/Console/index.html deleted file mode 100644 index 6534a168..00000000 --- a/backend/coverage-report/Console/index.html +++ /dev/null @@ -1,119 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Console - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 37.50% covered (danger) -
-
-
37.50%
6 / 16
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
Commands
-
- 37.50% covered (danger) -
-
-
37.50%
6 / 16
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
-
- -
- - diff --git a/backend/coverage-report/Contracts/ArticleParserInterface.php.html b/backend/coverage-report/Contracts/ArticleParserInterface.php.html deleted file mode 100644 index 4e869064..00000000 --- a/backend/coverage-report/Contracts/ArticleParserInterface.php.html +++ /dev/null @@ -1,108 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Contracts/ArticleParserInterface.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
n/a
0 / 0
n/a
0 / 0
CRAP
n/a
0 / 0
-
- - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Contracts;
4
5interface ArticleParserInterface
6{
7    /**
8     * Check if this parser can handle the given URL
9     */
10    public function canParse(string $url): bool;
11
12    /**
13     * Extract article data from HTML
14     * @return array<string, mixed>
15     */
16    public function extractData(string $html): array;
17
18    /**
19     * Get the source name for this parser
20     */
21    public function getSourceName(): string;
22}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 19:15:34 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report/Contracts/HomepageParserInterface.php.html b/backend/coverage-report/Contracts/HomepageParserInterface.php.html deleted file mode 100644 index 4791edb3..00000000 --- a/backend/coverage-report/Contracts/HomepageParserInterface.php.html +++ /dev/null @@ -1,113 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Contracts/HomepageParserInterface.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
n/a
0 / 0
n/a
0 / 0
CRAP
n/a
0 / 0
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Contracts;
4
5interface HomepageParserInterface
6{
7    /**
8     * Check if this parser can handle the given homepage URL
9     */
10    public function canParse(string $url): bool;
11
12    /**
13     * Extract article URLs from homepage HTML
14     * @return array<int, string>
15     */
16    public function extractArticleUrls(string $html): array;
17
18    /**
19     * Get the homepage URL for this source
20     */
21    public function getHomepageUrl(): string;
22
23    /**
24     * Get the source name for this parser
25     */
26    public function getSourceName(): string;
27}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 19:15:34 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report/Contracts/dashboard.html b/backend/coverage-report/Contracts/dashboard.html deleted file mode 100644 index 5f19bce1..00000000 --- a/backend/coverage-report/Contracts/dashboard.html +++ /dev/null @@ -1,284 +0,0 @@ - - - - - Dashboard for /var/www/html/backend/app/Contracts - - - - - - - -
-
-
-
- -
-
-
-
-
-
-
-

Classes

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
-
-
-

Insufficient Coverage

-
- - - - - - - - - - -
ClassCoverage
-
-
-
-

Project Risks

-
- - - - - - - - - - -
ClassCRAP
-
-
-
-
-
-

Methods

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
-
-
-

Insufficient Coverage

-
- - - - - - - - - - -
MethodCoverage
-
-
-
-

Project Risks

-
- - - - - - - - - - -
MethodCRAP
-
-
-
- -
- - - - - - diff --git a/backend/coverage-report/Contracts/index.html b/backend/coverage-report/Contracts/index.html deleted file mode 100644 index c305a549..00000000 --- a/backend/coverage-report/Contracts/index.html +++ /dev/null @@ -1,102 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Contracts - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
n/a
0 / 0
n/a
0 / 0
n/a
0 / 0
ArticleParserInterface.php
n/a
0 / 0
n/a
0 / 0
n/a
0 / 0
HomepageParserInterface.php
n/a
0 / 0
n/a
0 / 0
n/a
0 / 0
-
- -
- - diff --git a/backend/coverage-report/Enums/PlatformEnum.php.html b/backend/coverage-report/Enums/PlatformEnum.php.html deleted file mode 100644 index 3ce03f6e..00000000 --- a/backend/coverage-report/Enums/PlatformEnum.php.html +++ /dev/null @@ -1,94 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Enums/PlatformEnum.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
n/a
0 / 0
n/a
0 / 0
CRAP
n/a
0 / 0
-
- - - - - - - - - - - - -
1<?php
2
3namespace App\Enums;
4
5enum PlatformEnum: string
6{
7    case LEMMY = 'lemmy';
8}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 19:15:34 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report/Enums/dashboard.html b/backend/coverage-report/Enums/dashboard.html deleted file mode 100644 index 5c4b9f0b..00000000 --- a/backend/coverage-report/Enums/dashboard.html +++ /dev/null @@ -1,284 +0,0 @@ - - - - - Dashboard for /var/www/html/backend/app/Enums - - - - - - - -
-
-
-
- -
-
-
-
-
-
-
-

Classes

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
-
-
-

Insufficient Coverage

-
- - - - - - - - - - -
ClassCoverage
-
-
-
-

Project Risks

-
- - - - - - - - - - -
ClassCRAP
-
-
-
-
-
-

Methods

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
-
-
-

Insufficient Coverage

-
- - - - - - - - - - -
MethodCoverage
-
-
-
-

Project Risks

-
- - - - - - - - - - -
MethodCRAP
-
-
-
- -
- - - - - - diff --git a/backend/coverage-report/Enums/index.html b/backend/coverage-report/Enums/index.html deleted file mode 100644 index 1d8bbe19..00000000 --- a/backend/coverage-report/Enums/index.html +++ /dev/null @@ -1,89 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Enums - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
n/a
0 / 0
n/a
0 / 0
n/a
0 / 0
PlatformEnum.php
n/a
0 / 0
n/a
0 / 0
n/a
0 / 0
-
- -
- - diff --git a/backend/coverage-report/Events/ArticleApproved.php.html b/backend/coverage-report/Events/ArticleApproved.php.html deleted file mode 100644 index c3befddf..00000000 --- a/backend/coverage-report/Events/ArticleApproved.php.html +++ /dev/null @@ -1,169 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Events/ArticleApproved.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
CRAP
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
ArticleApproved
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
1
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
 __construct
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
1
-
- - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Events;
4
5use App\Models\Article;
6use Illuminate\Foundation\Events\Dispatchable;
7use Illuminate\Queue\SerializesModels;
8
9class ArticleApproved
10{
11    use Dispatchable, SerializesModels;
12
13    public function __construct(public Article $article)
14    {
15        //
16    }
17}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 19:15:34 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report/Events/ArticleReadyToPublish.php.html b/backend/coverage-report/Events/ArticleReadyToPublish.php.html deleted file mode 100644 index 73788af6..00000000 --- a/backend/coverage-report/Events/ArticleReadyToPublish.php.html +++ /dev/null @@ -1,170 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Events/ArticleReadyToPublish.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
CRAP
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
ArticleReadyToPublish
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
1
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
 __construct
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
1
-
- - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Events;
4
5use App\Models\Article;
6use Illuminate\Broadcasting\InteractsWithSockets;
7use Illuminate\Foundation\Events\Dispatchable;
8use Illuminate\Queue\SerializesModels;
9
10class ArticleReadyToPublish
11{
12    use Dispatchable, InteractsWithSockets, SerializesModels;
13
14    public function __construct(public Article $article)
15    {
16
17    }
18}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 19:15:34 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report/Events/ExceptionLogged.php.html b/backend/coverage-report/Events/ExceptionLogged.php.html deleted file mode 100644 index a9ffb8b5..00000000 --- a/backend/coverage-report/Events/ExceptionLogged.php.html +++ /dev/null @@ -1,169 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Events/ExceptionLogged.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
CRAP
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
ExceptionLogged
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
1
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
 __construct
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
1
-
- - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Events;
4
5use App\Models\Log;
6use Illuminate\Foundation\Events\Dispatchable;
7use Illuminate\Queue\SerializesModels;
8
9class ExceptionLogged
10{
11    use Dispatchable, SerializesModels;
12
13    public function __construct(
14        public Log $log
15    ) {
16    }
17}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 19:15:34 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report/Events/ExceptionOccurred.php.html b/backend/coverage-report/Events/ExceptionOccurred.php.html deleted file mode 100644 index a2e64008..00000000 --- a/backend/coverage-report/Events/ExceptionOccurred.php.html +++ /dev/null @@ -1,174 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Events/ExceptionOccurred.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
CRAP
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
ExceptionOccurred
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
1
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
 __construct
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
1
-
- - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Events;
4
5use App\LogLevelEnum;
6use Illuminate\Foundation\Events\Dispatchable;
7use Illuminate\Queue\SerializesModels;
8use Throwable;
9
10class ExceptionOccurred
11{
12    use Dispatchable, SerializesModels;
13
14    public function __construct(
15        public Throwable $exception,
16        public LogLevelEnum $level,
17        public string $message,
18        /** @var array<string, mixed> */
19        public array $context = []
20    ) {
21    }
22}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 19:15:34 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report/Events/NewArticleFetched.php.html b/backend/coverage-report/Events/NewArticleFetched.php.html deleted file mode 100644 index e237a9ea..00000000 --- a/backend/coverage-report/Events/NewArticleFetched.php.html +++ /dev/null @@ -1,169 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Events/NewArticleFetched.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
CRAP
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
NewArticleFetched
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
1
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
 __construct
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
1
-
- - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Events;
4
5use App\Models\Article;
6use Illuminate\Broadcasting\InteractsWithSockets;
7use Illuminate\Foundation\Events\Dispatchable;
8use Illuminate\Queue\SerializesModels;
9
10class NewArticleFetched
11{
12    use Dispatchable, InteractsWithSockets, SerializesModels;
13
14    public function __construct(public Article $article)
15    {
16    }
17}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 19:15:34 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report/Events/dashboard.html b/backend/coverage-report/Events/dashboard.html deleted file mode 100644 index c2142716..00000000 --- a/backend/coverage-report/Events/dashboard.html +++ /dev/null @@ -1,284 +0,0 @@ - - - - - Dashboard for /var/www/html/backend/app/Events - - - - - - - -
-
-
-
- -
-
-
-
-
-
-
-

Classes

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
-
-
-

Insufficient Coverage

-
- - - - - - - - - - -
ClassCoverage
-
-
-
-

Project Risks

-
- - - - - - - - - - -
ClassCRAP
-
-
-
-
-
-

Methods

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
-
-
-

Insufficient Coverage

-
- - - - - - - - - - -
MethodCoverage
-
-
-
-

Project Risks

-
- - - - - - - - - - -
MethodCRAP
-
-
-
- -
- - - - - - diff --git a/backend/coverage-report/Events/index.html b/backend/coverage-report/Events/index.html deleted file mode 100644 index 9a531add..00000000 --- a/backend/coverage-report/Events/index.html +++ /dev/null @@ -1,231 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Events - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 100.00% covered (success) -
-
-
100.00%
5 / 5
-
- 100.00% covered (success) -
-
-
100.00%
5 / 5
-
- 100.00% covered (success) -
-
-
100.00%
5 / 5
ArticleApproved.php
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
ArticleReadyToPublish.php
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
ExceptionLogged.php
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
ExceptionOccurred.php
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
NewArticleFetched.php
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
-
- -
- - diff --git a/backend/coverage-report/Exceptions/ChannelException.php.html b/backend/coverage-report/Exceptions/ChannelException.php.html deleted file mode 100644 index b5aeb0e5..00000000 --- a/backend/coverage-report/Exceptions/ChannelException.php.html +++ /dev/null @@ -1,109 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Exceptions/ChannelException.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
n/a
0 / 0
n/a
0 / 0
CRAP
n/a
0 / 0
ChannelException
n/a
0 / 0
n/a
0 / 0
0
n/a
0 / 0
-
- - - - - - - - - - - - - -
1<?php
2
3namespace App\Exceptions;
4
5use Exception;
6
7class ChannelException extends Exception
8{
9}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 19:15:34 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report/Exceptions/PlatformAuthException.php.html b/backend/coverage-report/Exceptions/PlatformAuthException.php.html deleted file mode 100644 index fce4ca20..00000000 --- a/backend/coverage-report/Exceptions/PlatformAuthException.php.html +++ /dev/null @@ -1,197 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Exceptions/PlatformAuthException.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
PlatformAuthException
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
6
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 __construct
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 getPlatform
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Exceptions;
4
5use App\Enums\PlatformEnum;
6use Exception;
7
8class PlatformAuthException extends Exception
9{
10    public function __construct(
11        private readonly PlatformEnum $platform,
12        string $reason = 'Authentication failed'
13    ) {
14        $message = "Failed to authenticate with {$platform->value}: {$reason}";
15
16        parent::__construct($message);
17    }
18
19    public function getPlatform(): PlatformEnum
20    {
21        return $this->platform;
22    }
23}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 19:15:34 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report/Exceptions/PublishException.php.html b/backend/coverage-report/Exceptions/PublishException.php.html deleted file mode 100644 index f383a1c7..00000000 --- a/backend/coverage-report/Exceptions/PublishException.php.html +++ /dev/null @@ -1,235 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Exceptions/PublishException.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 8
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
PublishException
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 8
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
30
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 __construct
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 6
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
12
 getArticle
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 getPlatform
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Exceptions;
4
5use App\Enums\PlatformEnum;
6use App\Models\Article;
7use Exception;
8use Throwable;
9
10class PublishException extends Exception
11{
12    public function __construct(
13        private readonly Article $article,
14        private readonly PlatformEnum|null $platform,
15        ?Throwable $previous = null
16    ) {
17        $message = "Failed to publish article #$article->id";
18
19        if ($this->platform) {
20            $message .= "  to $platform->value";
21        }
22
23        if ($previous) {
24            $message .= ": {$previous->getMessage()}";
25        }
26
27        parent::__construct($message, 0, $previous);
28    }
29
30    public function getArticle(): Article
31    {
32        return $this->article;
33    }
34
35    public function getPlatform(): ?PlatformEnum
36    {
37        return $this->platform;
38    }
39}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 19:15:34 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report/Exceptions/RoutingException.php.html b/backend/coverage-report/Exceptions/RoutingException.php.html deleted file mode 100644 index f715bf16..00000000 --- a/backend/coverage-report/Exceptions/RoutingException.php.html +++ /dev/null @@ -1,109 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Exceptions/RoutingException.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
n/a
0 / 0
n/a
0 / 0
CRAP
n/a
0 / 0
RoutingException
n/a
0 / 0
n/a
0 / 0
0
n/a
0 / 0
-
- - - - - - - - - - - - - -
1<?php
2
3namespace App\Exceptions;
4
5use Exception;
6
7class RoutingException extends Exception
8{
9}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 19:15:34 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report/Exceptions/RoutingMismatchException.php.html b/backend/coverage-report/Exceptions/RoutingMismatchException.php.html deleted file mode 100644 index 2aa09640..00000000 --- a/backend/coverage-report/Exceptions/RoutingMismatchException.php.html +++ /dev/null @@ -1,174 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Exceptions/RoutingMismatchException.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 8
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
RoutingMismatchException
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 8
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 __construct
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 8
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Exceptions;
4
5use App\Models\Feed;
6use App\Models\PlatformChannel;
7
8class RoutingMismatchException extends RoutingException
9{
10    public function __construct(Feed $feed, PlatformChannel $channel)
11    {
12        $message = sprintf(
13            "Language mismatch: Feed '%s' is in '%s' but channel '%s' is set to '%s'. Feed and channel languages must match for proper content routing.",
14            $feed->name,
15            $feed->language,
16            $channel->name,
17            $channel->language
18        );
19
20        parent::__construct($message);
21    }
22}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 19:15:34 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report/Exceptions/dashboard.html b/backend/coverage-report/Exceptions/dashboard.html deleted file mode 100644 index 02e84c85..00000000 --- a/backend/coverage-report/Exceptions/dashboard.html +++ /dev/null @@ -1,295 +0,0 @@ - - - - - Dashboard for /var/www/html/backend/app/Exceptions - - - - - - - -
-
-
-
- -
-
-
-
-
-
-
-

Classes

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
-
-
-

Insufficient Coverage

- -
-
-

Project Risks

-
- - - - - - - - - - - -
ClassCRAP
App\Exceptions\PublishException30
-
-
-
-
-
-

Methods

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
-
-
-

Insufficient Coverage

-
- - - - - - - - - - - - - - - - -
MethodCoverage
__construct0%
getPlatform0%
__construct0%
getArticle0%
getPlatform0%
__construct0%
-
-
-
-

Project Risks

-
- - - - - - - - - - - -
MethodCRAP
__construct12
-
-
-
- -
- - - - - - diff --git a/backend/coverage-report/Exceptions/index.html b/backend/coverage-report/Exceptions/index.html deleted file mode 100644 index ef7151fe..00000000 --- a/backend/coverage-report/Exceptions/index.html +++ /dev/null @@ -1,201 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Exceptions - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 19
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 6
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
ChannelException.php
n/a
0 / 0
n/a
0 / 0
n/a
0 / 0
PlatformAuthException.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
PublishException.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 8
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
RoutingException.php
n/a
0 / 0
n/a
0 / 0
n/a
0 / 0
RoutingMismatchException.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 8
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- -
- - diff --git a/backend/coverage-report/Http/Controllers/Api/V1/ArticlesController.php.html b/backend/coverage-report/Http/Controllers/Api/V1/ArticlesController.php.html deleted file mode 100644 index 59e21bfb..00000000 --- a/backend/coverage-report/Http/Controllers/Api/V1/ArticlesController.php.html +++ /dev/null @@ -1,273 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Http/Controllers/Api/V1/ArticlesController.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 87.88% covered (warning) -
-
-
87.88%
29 / 33
-
- 33.33% covered (danger) -
-
-
33.33%
1 / 3
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
ArticlesController
-
- 87.88% covered (warning) -
-
-
87.88%
29 / 33
-
- 33.33% covered (danger) -
-
-
33.33%
1 / 3
5.04
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 index
-
- 100.00% covered (success) -
-
-
100.00%
19 / 19
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
1
 approve
-
- 71.43% covered (warning) -
-
-
71.43%
5 / 7
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2.09
 reject
-
- 71.43% covered (warning) -
-
-
71.43%
5 / 7
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2.09
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Http\Controllers\Api\V1;
4
5use App\Http\Resources\ArticleResource;
6use App\Models\Article;
7use App\Models\Setting;
8use Illuminate\Http\JsonResponse;
9use Illuminate\Http\Request;
10
11class ArticlesController extends BaseController
12{
13    /**
14     * Display a listing of articles
15     */
16    public function index(Request $request): JsonResponse
17    {
18        $perPage = min($request->get('per_page', 15), 100); // Max 100 items per page
19        $articles = Article::with(['feed', 'articlePublication'])
20            ->orderBy('created_at', 'desc')
21            ->paginate($perPage);
22
23        $publishingApprovalsEnabled = Setting::isPublishingApprovalsEnabled();
24
25        return $this->sendResponse([
26            'articles' => ArticleResource::collection($articles->items()),
27            'pagination' => [
28                'current_page' => $articles->currentPage(),
29                'last_page' => $articles->lastPage(),
30                'per_page' => $articles->perPage(),
31                'total' => $articles->total(),
32                'from' => $articles->firstItem(),
33                'to' => $articles->lastItem(),
34            ],
35            'settings' => [
36                'publishing_approvals_enabled' => $publishingApprovalsEnabled,
37            ],
38        ]);
39    }
40
41    /**
42     * Approve an article
43     */
44    public function approve(Article $article): JsonResponse
45    {
46        try {
47            $article->approve('manual');
48            
49            return $this->sendResponse(
50                new ArticleResource($article->fresh(['feed', 'articlePublication'])),
51                'Article approved and queued for publishing.'
52            );
53        } catch (\Exception $e) {
54            return $this->sendError('Failed to approve article: ' . $e->getMessage(), [], 500);
55        }
56    }
57
58    /**
59     * Reject an article
60     */
61    public function reject(Article $article): JsonResponse
62    {
63        try {
64            $article->reject('manual');
65            
66            return $this->sendResponse(
67                new ArticleResource($article->fresh(['feed', 'articlePublication'])),
68                'Article rejected.'
69            );
70        } catch (\Exception $e) {
71            return $this->sendError('Failed to reject article: ' . $e->getMessage(), [], 500);
72        }
73    }
74}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 19:15:34 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report/Http/Controllers/Api/V1/AuthController.php.html b/backend/coverage-report/Http/Controllers/Api/V1/AuthController.php.html deleted file mode 100644 index 1dcce1c6..00000000 --- a/backend/coverage-report/Http/Controllers/Api/V1/AuthController.php.html +++ /dev/null @@ -1,333 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Http/Controllers/Api/V1/AuthController.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 56
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 4
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
AuthController
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 56
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 4
132
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 login
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 21
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
30
 register
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 24
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
12
 logout
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 4
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
6
 me
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 7
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Http\Controllers\Api\V1;
4
5use App\Models\User;
6use Illuminate\Http\JsonResponse;
7use Illuminate\Http\Request;
8use Illuminate\Support\Facades\Auth;
9use Illuminate\Support\Facades\Hash;
10use Illuminate\Validation\ValidationException;
11
12class AuthController extends BaseController
13{
14    /**
15     * Login user and create token
16     */
17    public function login(Request $request): JsonResponse
18    {
19        try {
20            $request->validate([
21                'email' => 'required|email',
22                'password' => 'required',
23            ]);
24
25            $user = User::where('email', $request->email)->first();
26
27            if (!$user || !Hash::check($request->password, $user->password)) {
28                return $this->sendError('Invalid credentials', [], 401);
29            }
30
31            $token = $user->createToken('api-token')->plainTextToken;
32
33            return $this->sendResponse([
34                'user' => [
35                    'id' => $user->id,
36                    'name' => $user->name,
37                    'email' => $user->email,
38                ],
39                'token' => $token,
40                'token_type' => 'Bearer',
41            ], 'Login successful');
42        } catch (ValidationException $e) {
43            return $this->sendValidationError($e->errors());
44        } catch (\Exception $e) {
45            return $this->sendError('Login failed: ' . $e->getMessage(), [], 500);
46        }
47    }
48
49    /**
50     * Register a new user
51     */
52    public function register(Request $request): JsonResponse
53    {
54        try {
55            $validated = $request->validate([
56                'name' => 'required|string|max:255',
57                'email' => 'required|string|email|max:255|unique:users',
58                'password' => 'required|string|min:8|confirmed',
59            ]);
60
61            $user = User::create([
62                'name' => $validated['name'],
63                'email' => $validated['email'],
64                'password' => Hash::make($validated['password']),
65            ]);
66
67            $token = $user->createToken('api-token')->plainTextToken;
68
69            return $this->sendResponse([
70                'user' => [
71                    'id' => $user->id,
72                    'name' => $user->name,
73                    'email' => $user->email,
74                ],
75                'token' => $token,
76                'token_type' => 'Bearer',
77            ], 'Registration successful', 201);
78        } catch (ValidationException $e) {
79            return $this->sendValidationError($e->errors());
80        } catch (\Exception $e) {
81            return $this->sendError('Registration failed: ' . $e->getMessage(), [], 500);
82        }
83    }
84
85    /**
86     * Logout user (revoke token)
87     */
88    public function logout(Request $request): JsonResponse
89    {
90        try {
91            $request->user()->currentAccessToken()->delete();
92
93            return $this->sendResponse(null, 'Logged out successfully');
94        } catch (\Exception $e) {
95            return $this->sendError('Logout failed: ' . $e->getMessage(), [], 500);
96        }
97    }
98
99    /**
100     * Get current authenticated user
101     */
102    public function me(Request $request): JsonResponse
103    {
104        return $this->sendResponse([
105            'user' => [
106                'id' => $request->user()->id,
107                'name' => $request->user()->name,
108                'email' => $request->user()->email,
109            ],
110        ], 'User retrieved successfully');
111    }
112}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 19:15:34 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report/Http/Controllers/Api/V1/BaseController.php.html b/backend/coverage-report/Http/Controllers/Api/V1/BaseController.php.html deleted file mode 100644 index 4fb407bf..00000000 --- a/backend/coverage-report/Http/Controllers/Api/V1/BaseController.php.html +++ /dev/null @@ -1,307 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Http/Controllers/Api/V1/BaseController.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 87.50% covered (warning) -
-
-
87.50%
14 / 16
-
- 60.00% covered (warning) -
-
-
60.00%
3 / 5
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
BaseController
-
- 87.50% covered (warning) -
-
-
87.50%
14 / 16
-
- 60.00% covered (warning) -
-
-
60.00%
3 / 5
6.07
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 sendResponse
-
- 100.00% covered (success) -
-
-
100.00%
6 / 6
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
1
 sendError
-
- 100.00% covered (success) -
-
-
100.00%
7 / 7
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
2
 sendValidationError
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
1
 sendNotFound
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 sendUnauthorized
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Http\Controllers\Api\V1;
4
5use App\Http\Controllers\Controller;
6use Illuminate\Http\JsonResponse;
7
8class BaseController extends Controller
9{
10    /**
11     * Success response method
12     */
13    public function sendResponse(mixed $result, string $message = 'Success', int $code = 200): JsonResponse
14    {
15        $response = [
16            'success' => true,
17            'data' => $result,
18            'message' => $message,
19        ];
20
21        return response()->json($response, $code);
22    }
23
24    /**
25     * Error response method
26     */
27    public function sendError(string $error, array $errorMessages = [], int $code = 400): JsonResponse
28    {
29        $response = [
30            'success' => false,
31            'message' => $error,
32        ];
33
34        if (!empty($errorMessages)) {
35            $response['errors'] = $errorMessages;
36        }
37
38        return response()->json($response, $code);
39    }
40
41    /**
42     * Validation error response method
43     */
44    public function sendValidationError(array $errors): JsonResponse
45    {
46        return $this->sendError('Validation failed', $errors, 422);
47    }
48
49    /**
50     * Not found response method
51     */
52    public function sendNotFound(string $message = 'Resource not found'): JsonResponse
53    {
54        return $this->sendError($message, [], 404);
55    }
56
57    /**
58     * Unauthorized response method
59     */
60    public function sendUnauthorized(string $message = 'Unauthorized'): JsonResponse
61    {
62        return $this->sendError($message, [], 401);
63    }
64}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 19:15:34 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report/Http/Controllers/Api/V1/DashboardController.php.html b/backend/coverage-report/Http/Controllers/Api/V1/DashboardController.php.html deleted file mode 100644 index 3fb3e04b..00000000 --- a/backend/coverage-report/Http/Controllers/Api/V1/DashboardController.php.html +++ /dev/null @@ -1,223 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Http/Controllers/Api/V1/DashboardController.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 84.62% covered (warning) -
-
-
84.62%
11 / 13
-
- 50.00% covered (danger) -
-
-
50.00%
1 / 2
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
DashboardController
-
- 84.62% covered (warning) -
-
-
84.62%
11 / 13
-
- 50.00% covered (danger) -
-
-
50.00%
1 / 2
3.03
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 __construct
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
1
 stats
-
- 83.33% covered (warning) -
-
-
83.33%
10 / 12
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2.02
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Http\Controllers\Api\V1;
4
5use App\Models\Article;
6use App\Models\Feed;
7use App\Models\PlatformAccount;
8use App\Models\PlatformChannel;
9use App\Services\DashboardStatsService;
10use Illuminate\Http\JsonResponse;
11use Illuminate\Http\Request;
12
13class DashboardController extends BaseController
14{
15    public function __construct(
16        private DashboardStatsService $dashboardStatsService
17    ) {}
18
19    /**
20     * Get dashboard statistics
21     */
22    public function stats(Request $request): JsonResponse
23    {
24        $period = $request->get('period', 'today');
25        
26        try {
27            // Get article stats from service
28            $articleStats = $this->dashboardStatsService->getStats($period);
29            
30            // Get system stats
31            $systemStats = $this->dashboardStatsService->getSystemStats();
32            
33            // Get available periods
34            $availablePeriods = $this->dashboardStatsService->getAvailablePeriods();
35            
36            return $this->sendResponse([
37                'article_stats' => $articleStats,
38                'system_stats' => $systemStats,
39                'available_periods' => $availablePeriods,
40                'current_period' => $period,
41            ]);
42        } catch (\Exception $e) {
43            return $this->sendError('Failed to fetch dashboard stats: ' . $e->getMessage(), [], 500);
44        }
45    }
46}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 19:15:34 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report/Http/Controllers/Api/V1/FeedsController.php.html b/backend/coverage-report/Http/Controllers/Api/V1/FeedsController.php.html deleted file mode 100644 index 591c3ba1..00000000 --- a/backend/coverage-report/Http/Controllers/Api/V1/FeedsController.php.html +++ /dev/null @@ -1,387 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Http/Controllers/Api/V1/FeedsController.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 76.00% covered (warning) -
-
-
76.00%
38 / 50
-
- 33.33% covered (danger) -
-
-
33.33%
2 / 6
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
FeedsController
-
- 76.00% covered (warning) -
-
-
76.00%
38 / 50
-
- 33.33% covered (danger) -
-
-
33.33%
2 / 6
15.34
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 index
-
- 100.00% covered (success) -
-
-
100.00%
7 / 7
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
1
 store
-
- 66.67% covered (warning) -
-
-
66.67%
8 / 12
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
3.33
 show
-
- 100.00% covered (success) -
-
-
100.00%
4 / 4
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
1
 update
-
- 63.64% covered (warning) -
-
-
63.64%
7 / 11
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
3.43
 destroy
-
- 71.43% covered (warning) -
-
-
71.43%
5 / 7
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2.09
 toggle
-
- 77.78% covered (warning) -
-
-
77.78%
7 / 9
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
3.10
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Http\Controllers\Api\V1;
4
5use App\Http\Requests\StoreFeedRequest;
6use App\Http\Requests\UpdateFeedRequest;
7use App\Http\Resources\FeedResource;
8use App\Models\Feed;
9use Illuminate\Http\JsonResponse;
10use Illuminate\Http\Request;
11use Illuminate\Validation\ValidationException;
12
13class FeedsController extends BaseController
14{
15    /**
16     * Display a listing of feeds
17     */
18    public function index(Request $request): JsonResponse
19    {
20        $feeds = Feed::orderBy('is_active', 'desc')
21            ->orderBy('name')
22            ->get();
23
24        return $this->sendResponse(
25            FeedResource::collection($feeds),
26            'Feeds retrieved successfully.'
27        );
28    }
29
30    /**
31     * Store a newly created feed
32     */
33    public function store(StoreFeedRequest $request): JsonResponse
34    {
35        try {
36            $validated = $request->validated();
37            $validated['is_active'] = $validated['is_active'] ?? true;
38
39            $feed = Feed::create($validated);
40
41            return $this->sendResponse(
42                new FeedResource($feed),
43                'Feed created successfully!',
44                201
45            );
46        } catch (ValidationException $e) {
47            return $this->sendValidationError($e->errors());
48        } catch (\Exception $e) {
49            return $this->sendError('Failed to create feed: ' . $e->getMessage(), [], 500);
50        }
51    }
52
53    /**
54     * Display the specified feed
55     */
56    public function show(Feed $feed): JsonResponse
57    {
58        return $this->sendResponse(
59            new FeedResource($feed),
60            'Feed retrieved successfully.'
61        );
62    }
63
64    /**
65     * Update the specified feed
66     */
67    public function update(UpdateFeedRequest $request, Feed $feed): JsonResponse
68    {
69        try {
70            $validated = $request->validated();
71            $validated['is_active'] = $validated['is_active'] ?? $feed->is_active;
72
73            $feed->update($validated);
74
75            return $this->sendResponse(
76                new FeedResource($feed->fresh()),
77                'Feed updated successfully!'
78            );
79        } catch (ValidationException $e) {
80            return $this->sendValidationError($e->errors());
81        } catch (\Exception $e) {
82            return $this->sendError('Failed to update feed: ' . $e->getMessage(), [], 500);
83        }
84    }
85
86    /**
87     * Remove the specified feed
88     */
89    public function destroy(Feed $feed): JsonResponse
90    {
91        try {
92            $feed->delete();
93
94            return $this->sendResponse(
95                null,
96                'Feed deleted successfully!'
97            );
98        } catch (\Exception $e) {
99            return $this->sendError('Failed to delete feed: ' . $e->getMessage(), [], 500);
100        }
101    }
102
103    /**
104     * Toggle feed active status
105     */
106    public function toggle(Feed $feed): JsonResponse
107    {
108        try {
109            $newStatus = !$feed->is_active;
110            $feed->update(['is_active' => $newStatus]);
111
112            $status = $newStatus ? 'activated' : 'deactivated';
113
114            return $this->sendResponse(
115                new FeedResource($feed->fresh()),
116                "Feed {$status} successfully!"
117            );
118        } catch (\Exception $e) {
119            return $this->sendError('Failed to toggle feed status: ' . $e->getMessage(), [], 500);
120        }
121    }
122}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 19:15:34 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report/Http/Controllers/Api/V1/LogsController.php.html b/backend/coverage-report/Http/Controllers/Api/V1/LogsController.php.html deleted file mode 100644 index c0ed600c..00000000 --- a/backend/coverage-report/Http/Controllers/Api/V1/LogsController.php.html +++ /dev/null @@ -1,198 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Http/Controllers/Api/V1/LogsController.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 19
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
LogsController
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 19
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
12
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 index
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 19
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
12
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Http\Controllers\Api\V1;
4
5use App\Models\Log;
6use Illuminate\Http\JsonResponse;
7use Illuminate\Http\Request;
8
9class LogsController extends BaseController
10{
11    /**
12     * Display a listing of logs
13     */
14    public function index(Request $request): JsonResponse
15    {
16        try {
17            $perPage = min($request->get('per_page', 20), 100);
18            $level = $request->get('level');
19            
20            $query = Log::orderBy('created_at', 'desc');
21            
22            if ($level) {
23                $query->where('level', $level);
24            }
25            
26            $logs = $query->paginate($perPage);
27
28            return $this->sendResponse([
29                'logs' => $logs->items(),
30                'pagination' => [
31                    'current_page' => $logs->currentPage(),
32                    'last_page' => $logs->lastPage(),
33                    'per_page' => $logs->perPage(),
34                    'total' => $logs->total(),
35                    'from' => $logs->firstItem(),
36                    'to' => $logs->lastItem(),
37                ],
38            ], 'Logs retrieved successfully.');
39        } catch (\Exception $e) {
40            return $this->sendError('Failed to retrieve logs: ' . $e->getMessage(), [], 500);
41        }
42    }
43}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 19:15:34 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report/Http/Controllers/Api/V1/PlatformAccountsController.php.html b/backend/coverage-report/Http/Controllers/Api/V1/PlatformAccountsController.php.html deleted file mode 100644 index 19b6a339..00000000 --- a/backend/coverage-report/Http/Controllers/Api/V1/PlatformAccountsController.php.html +++ /dev/null @@ -1,417 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Http/Controllers/Api/V1/PlatformAccountsController.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 73
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 6
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
PlatformAccountsController
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 73
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 6
210
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 index
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 8
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 store
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 30
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
20
 show
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 4
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 update
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 17
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
20
 destroy
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 7
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
6
 setActive
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 7
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
6
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Http\Controllers\Api\V1;
4
5use App\Enums\PlatformEnum;
6use App\Http\Resources\PlatformAccountResource;
7use App\Models\PlatformAccount;
8use App\Models\PlatformInstance;
9use Illuminate\Http\JsonResponse;
10use Illuminate\Http\Request;
11use Illuminate\Validation\ValidationException;
12
13class PlatformAccountsController extends BaseController
14{
15    /**
16     * Display a listing of platform accounts
17     */
18    public function index(): JsonResponse
19    {
20        $accounts = PlatformAccount::with(['platformInstance'])
21            ->orderBy('platform')
22            ->orderBy('created_at', 'desc')
23            ->get();
24
25        return $this->sendResponse(
26            PlatformAccountResource::collection($accounts),
27            'Platform accounts retrieved successfully.'
28        );
29    }
30
31    /**
32     * Store a newly created platform account
33     */
34    public function store(Request $request): JsonResponse
35    {
36        try {
37            $validated = $request->validate([
38                'platform' => 'required|in:lemmy,mastodon,reddit',
39                'instance_url' => 'required|url',
40                'username' => 'required|string|max:255',
41                'password' => 'required|string',
42                'settings' => 'nullable|array',
43            ]);
44
45            // Create or find platform instance
46            $platformEnum = PlatformEnum::from($validated['platform']);
47            $instance = PlatformInstance::firstOrCreate([
48                'platform' => $platformEnum,
49                'url' => $validated['instance_url'],
50            ], [
51                'name' => parse_url($validated['instance_url'], PHP_URL_HOST),
52                'description' => ucfirst($validated['platform']) . ' instance',
53                'is_active' => true,
54            ]);
55
56            $account = PlatformAccount::create($validated);
57
58            // If this is the first account for this platform, make it active
59            if (!PlatformAccount::where('platform', $validated['platform'])
60                ->where('is_active', true)
61                ->exists()) {
62                $account->setAsActive();
63            }
64
65            return $this->sendResponse(
66                new PlatformAccountResource($account->load('platformInstance')),
67                'Platform account created successfully!',
68                201
69            );
70        } catch (ValidationException $e) {
71            return $this->sendValidationError($e->errors());
72        } catch (\Exception $e) {
73            return $this->sendError('Failed to create platform account: ' . $e->getMessage(), [], 500);
74        }
75    }
76
77    /**
78     * Display the specified platform account
79     */
80    public function show(PlatformAccount $platformAccount): JsonResponse
81    {
82        return $this->sendResponse(
83            new PlatformAccountResource($platformAccount->load('platformInstance')),
84            'Platform account retrieved successfully.'
85        );
86    }
87
88    /**
89     * Update the specified platform account
90     */
91    public function update(Request $request, PlatformAccount $platformAccount): JsonResponse
92    {
93        try {
94            $validated = $request->validate([
95                'instance_url' => 'required|url',
96                'username' => 'required|string|max:255',
97                'password' => 'nullable|string',
98                'settings' => 'nullable|array',
99            ]);
100
101            // Don't update password if not provided
102            if (empty($validated['password'])) {
103                unset($validated['password']);
104            }
105
106            $platformAccount->update($validated);
107
108            return $this->sendResponse(
109                new PlatformAccountResource($platformAccount->fresh(['platformInstance'])),
110                'Platform account updated successfully!'
111            );
112        } catch (ValidationException $e) {
113            return $this->sendValidationError($e->errors());
114        } catch (\Exception $e) {
115            return $this->sendError('Failed to update platform account: ' . $e->getMessage(), [], 500);
116        }
117    }
118
119    /**
120     * Remove the specified platform account
121     */
122    public function destroy(PlatformAccount $platformAccount): JsonResponse
123    {
124        try {
125            $platformAccount->delete();
126
127            return $this->sendResponse(
128                null,
129                'Platform account deleted successfully!'
130            );
131        } catch (\Exception $e) {
132            return $this->sendError('Failed to delete platform account: ' . $e->getMessage(), [], 500);
133        }
134    }
135
136    /**
137     * Set platform account as active
138     */
139    public function setActive(PlatformAccount $platformAccount): JsonResponse
140    {
141        try {
142            $platformAccount->setAsActive();
143
144            return $this->sendResponse(
145                new PlatformAccountResource($platformAccount->fresh(['platformInstance'])),
146                "Set {$platformAccount->username}@{$platformAccount->instance_url} as active for {$platformAccount->platform->value}!"
147            );
148        } catch (\Exception $e) {
149            return $this->sendError('Failed to set platform account as active: ' . $e->getMessage(), [], 500);
150        }
151    }
152}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 19:15:34 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report/Http/Controllers/Api/V1/PlatformChannelsController.php.html b/backend/coverage-report/Http/Controllers/Api/V1/PlatformChannelsController.php.html deleted file mode 100644 index 84615aca..00000000 --- a/backend/coverage-report/Http/Controllers/Api/V1/PlatformChannelsController.php.html +++ /dev/null @@ -1,398 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Http/Controllers/Api/V1/PlatformChannelsController.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 62
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 6
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
PlatformChannelsController
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 62
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 6
182
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 index
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 8
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 store
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 19
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
12
 show
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 4
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 update
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 15
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
12
 destroy
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 7
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
6
 toggle
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 9
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
12
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Http\Controllers\Api\V1;
4
5use App\Http\Resources\PlatformChannelResource;
6use App\Models\PlatformChannel;
7use Illuminate\Http\JsonResponse;
8use Illuminate\Http\Request;
9use Illuminate\Validation\ValidationException;
10
11class PlatformChannelsController extends BaseController
12{
13    /**
14     * Display a listing of platform channels
15     */
16    public function index(): JsonResponse
17    {
18        $channels = PlatformChannel::with(['platformInstance'])
19            ->orderBy('is_active', 'desc')
20            ->orderBy('name')
21            ->get();
22
23        return $this->sendResponse(
24            PlatformChannelResource::collection($channels),
25            'Platform channels retrieved successfully.'
26        );
27    }
28
29    /**
30     * Store a newly created platform channel
31     */
32    public function store(Request $request): JsonResponse
33    {
34        try {
35            $validated = $request->validate([
36                'platform_instance_id' => 'required|exists:platform_instances,id',
37                'channel_id' => 'required|string|max:255',
38                'name' => 'required|string|max:255',
39                'display_name' => 'nullable|string|max:255',
40                'description' => 'nullable|string',
41                'is_active' => 'boolean',
42            ]);
43
44            $validated['is_active'] = $validated['is_active'] ?? true;
45
46            $channel = PlatformChannel::create($validated);
47
48            return $this->sendResponse(
49                new PlatformChannelResource($channel->load('platformInstance')),
50                'Platform channel created successfully!',
51                201
52            );
53        } catch (ValidationException $e) {
54            return $this->sendValidationError($e->errors());
55        } catch (\Exception $e) {
56            return $this->sendError('Failed to create platform channel: ' . $e->getMessage(), [], 500);
57        }
58    }
59
60    /**
61     * Display the specified platform channel
62     */
63    public function show(PlatformChannel $channel): JsonResponse
64    {
65        return $this->sendResponse(
66            new PlatformChannelResource($channel->load('platformInstance')),
67            'Platform channel retrieved successfully.'
68        );
69    }
70
71    /**
72     * Update the specified platform channel
73     */
74    public function update(Request $request, PlatformChannel $channel): JsonResponse
75    {
76        try {
77            $validated = $request->validate([
78                'name' => 'required|string|max:255',
79                'display_name' => 'nullable|string|max:255',
80                'description' => 'nullable|string',
81                'is_active' => 'boolean',
82            ]);
83
84            $channel->update($validated);
85
86            return $this->sendResponse(
87                new PlatformChannelResource($channel->fresh(['platformInstance'])),
88                'Platform channel updated successfully!'
89            );
90        } catch (ValidationException $e) {
91            return $this->sendValidationError($e->errors());
92        } catch (\Exception $e) {
93            return $this->sendError('Failed to update platform channel: ' . $e->getMessage(), [], 500);
94        }
95    }
96
97    /**
98     * Remove the specified platform channel
99     */
100    public function destroy(PlatformChannel $channel): JsonResponse
101    {
102        try {
103            $channel->delete();
104
105            return $this->sendResponse(
106                null,
107                'Platform channel deleted successfully!'
108            );
109        } catch (\Exception $e) {
110            return $this->sendError('Failed to delete platform channel: ' . $e->getMessage(), [], 500);
111        }
112    }
113
114    /**
115     * Toggle platform channel active status
116     */
117    public function toggle(PlatformChannel $channel): JsonResponse
118    {
119        try {
120            $newStatus = !$channel->is_active;
121            $channel->update(['is_active' => $newStatus]);
122
123            $status = $newStatus ? 'activated' : 'deactivated';
124
125            return $this->sendResponse(
126                new PlatformChannelResource($channel->fresh(['platformInstance'])),
127                "Platform channel {$status} successfully!"
128            );
129        } catch (\Exception $e) {
130            return $this->sendError('Failed to toggle platform channel status: ' . $e->getMessage(), [], 500);
131        }
132    }
133}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 19:15:34 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report/Http/Controllers/Api/V1/RoutingController.php.html b/backend/coverage-report/Http/Controllers/Api/V1/RoutingController.php.html deleted file mode 100644 index b0079de9..00000000 --- a/backend/coverage-report/Http/Controllers/Api/V1/RoutingController.php.html +++ /dev/null @@ -1,430 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Http/Controllers/Api/V1/RoutingController.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 80
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 6
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
RoutingController
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 80
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 6
306
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 index
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 8
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 store
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 18
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
12
 show
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 10
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
6
 update
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 18
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
20
 destroy
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 12
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
12
 toggle
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 14
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
20
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Http\Controllers\Api\V1;
4
5use App\Http\Resources\RouteResource;
6use App\Models\Feed;
7use App\Models\PlatformChannel;
8use App\Models\Route;
9use Illuminate\Http\JsonResponse;
10use Illuminate\Http\Request;
11use Illuminate\Validation\ValidationException;
12
13class RoutingController extends BaseController
14{
15    /**
16     * Display a listing of routing configurations
17     */
18    public function index(): JsonResponse
19    {
20        $routes = Route::with(['feed', 'platformChannel'])
21            ->orderBy('is_active', 'desc')
22            ->orderBy('priority', 'asc')
23            ->get();
24
25        return $this->sendResponse(
26            RouteResource::collection($routes),
27            'Routing configurations retrieved successfully.'
28        );
29    }
30
31    /**
32     * Store a newly created routing configuration
33     */
34    public function store(Request $request): JsonResponse
35    {
36        try {
37            $validated = $request->validate([
38                'feed_id' => 'required|exists:feeds,id',
39                'platform_channel_id' => 'required|exists:platform_channels,id',
40                'is_active' => 'boolean',
41                'priority' => 'nullable|integer|min:0',
42            ]);
43
44            $validated['is_active'] = $validated['is_active'] ?? true;
45            $validated['priority'] = $validated['priority'] ?? 0;
46
47            $route = Route::create($validated);
48
49            return $this->sendResponse(
50                new RouteResource($route->load(['feed', 'platformChannel'])),
51                'Routing configuration created successfully!',
52                201
53            );
54        } catch (ValidationException $e) {
55            return $this->sendValidationError($e->errors());
56        } catch (\Exception $e) {
57            return $this->sendError('Failed to create routing configuration: ' . $e->getMessage(), [], 500);
58        }
59    }
60
61    /**
62     * Display the specified routing configuration
63     */
64    public function show(Feed $feed, PlatformChannel $channel): JsonResponse
65    {
66        $route = Route::where('feed_id', $feed->id)
67            ->where('platform_channel_id', $channel->id)
68            ->with(['feed', 'platformChannel'])
69            ->first();
70
71        if (!$route) {
72            return $this->sendNotFound('Routing configuration not found.');
73        }
74
75        return $this->sendResponse(
76            new RouteResource($route),
77            'Routing configuration retrieved successfully.'
78        );
79    }
80
81    /**
82     * Update the specified routing configuration
83     */
84    public function update(Request $request, Feed $feed, PlatformChannel $channel): JsonResponse
85    {
86        try {
87            $route = Route::where('feed_id', $feed->id)
88                ->where('platform_channel_id', $channel->id)
89                ->first();
90
91            if (!$route) {
92                return $this->sendNotFound('Routing configuration not found.');
93            }
94
95            $validated = $request->validate([
96                'is_active' => 'boolean',
97                'priority' => 'nullable|integer|min:0',
98            ]);
99
100            $route->update($validated);
101
102            return $this->sendResponse(
103                new RouteResource($route->fresh(['feed', 'platformChannel'])),
104                'Routing configuration updated successfully!'
105            );
106        } catch (ValidationException $e) {
107            return $this->sendValidationError($e->errors());
108        } catch (\Exception $e) {
109            return $this->sendError('Failed to update routing configuration: ' . $e->getMessage(), [], 500);
110        }
111    }
112
113    /**
114     * Remove the specified routing configuration
115     */
116    public function destroy(Feed $feed, PlatformChannel $channel): JsonResponse
117    {
118        try {
119            $route = Route::where('feed_id', $feed->id)
120                ->where('platform_channel_id', $channel->id)
121                ->first();
122
123            if (!$route) {
124                return $this->sendNotFound('Routing configuration not found.');
125            }
126
127            $route->delete();
128
129            return $this->sendResponse(
130                null,
131                'Routing configuration deleted successfully!'
132            );
133        } catch (\Exception $e) {
134            return $this->sendError('Failed to delete routing configuration: ' . $e->getMessage(), [], 500);
135        }
136    }
137
138    /**
139     * Toggle routing configuration active status
140     */
141    public function toggle(Feed $feed, PlatformChannel $channel): JsonResponse
142    {
143        try {
144            $route = Route::where('feed_id', $feed->id)
145                ->where('platform_channel_id', $channel->id)
146                ->first();
147
148            if (!$route) {
149                return $this->sendNotFound('Routing configuration not found.');
150            }
151
152            $newStatus = !$route->is_active;
153            $route->update(['is_active' => $newStatus]);
154
155            $status = $newStatus ? 'activated' : 'deactivated';
156
157            return $this->sendResponse(
158                new RouteResource($route->fresh(['feed', 'platformChannel'])),
159                "Routing configuration {$status} successfully!"
160            );
161        } catch (\Exception $e) {
162            return $this->sendError('Failed to toggle routing configuration status: ' . $e->getMessage(), [], 500);
163        }
164    }
165}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 19:15:34 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report/Http/Controllers/Api/V1/SettingsController.php.html b/backend/coverage-report/Http/Controllers/Api/V1/SettingsController.php.html deleted file mode 100644 index 656cbe73..00000000 --- a/backend/coverage-report/Http/Controllers/Api/V1/SettingsController.php.html +++ /dev/null @@ -1,240 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Http/Controllers/Api/V1/SettingsController.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 85.19% covered (warning) -
-
-
85.19%
23 / 27
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
SettingsController
-
- 85.19% covered (warning) -
-
-
85.19%
23 / 27
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
7.16
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 index
-
- 71.43% covered (warning) -
-
-
71.43%
5 / 7
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2.09
 update
-
- 90.00% covered (success) -
-
-
90.00%
18 / 20
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
5.03
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Http\Controllers\Api\V1;
4
5use App\Models\Setting;
6use Illuminate\Http\JsonResponse;
7use Illuminate\Http\Request;
8use Illuminate\Validation\ValidationException;
9
10class SettingsController extends BaseController
11{
12    /**
13     * Display current settings
14     */
15    public function index(): JsonResponse
16    {
17        try {
18            $settings = [
19                'article_processing_enabled' => Setting::isArticleProcessingEnabled(),
20                'publishing_approvals_enabled' => Setting::isPublishingApprovalsEnabled(),
21            ];
22
23            return $this->sendResponse($settings, 'Settings retrieved successfully.');
24        } catch (\Exception $e) {
25            return $this->sendError('Failed to retrieve settings: ' . $e->getMessage(), [], 500);
26        }
27    }
28
29    /**
30     * Update settings
31     */
32    public function update(Request $request): JsonResponse
33    {
34        try {
35            $validated = $request->validate([
36                'article_processing_enabled' => 'boolean',
37                'enable_publishing_approvals' => 'boolean',
38            ]);
39
40            if (isset($validated['article_processing_enabled'])) {
41                Setting::setArticleProcessingEnabled($validated['article_processing_enabled']);
42            }
43
44            if (isset($validated['enable_publishing_approvals'])) {
45                Setting::setPublishingApprovalsEnabled($validated['enable_publishing_approvals']);
46            }
47
48            $updatedSettings = [
49                'article_processing_enabled' => Setting::isArticleProcessingEnabled(),
50                'publishing_approvals_enabled' => Setting::isPublishingApprovalsEnabled(),
51            ];
52
53            return $this->sendResponse(
54                $updatedSettings,
55                'Settings updated successfully.'
56            );
57        } catch (ValidationException $e) {
58            return $this->sendValidationError($e->errors());
59        } catch (\Exception $e) {
60            return $this->sendError('Failed to update settings: ' . $e->getMessage(), [], 500);
61        }
62    }
63}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 19:15:34 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report/Http/Controllers/Api/V1/dashboard.html b/backend/coverage-report/Http/Controllers/Api/V1/dashboard.html deleted file mode 100644 index bf963ed3..00000000 --- a/backend/coverage-report/Http/Controllers/Api/V1/dashboard.html +++ /dev/null @@ -1,365 +0,0 @@ - - - - - Dashboard for /var/www/html/backend/app/Http/Controllers/Api/V1 - - - - - - - -
-
-
-
- -
-
-
-
-
-
-
-

Classes

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
- -
-
-

Methods

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
-
-
-

Insufficient Coverage

-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
MethodCoverage
login0%
register0%
logout0%
me0%
sendNotFound0%
sendUnauthorized0%
index0%
index0%
store0%
show0%
update0%
destroy0%
setActive0%
index0%
store0%
show0%
update0%
destroy0%
toggle0%
index0%
store0%
show0%
update0%
destroy0%
toggle0%
update63%
store66%
approve71%
reject71%
destroy71%
index71%
toggle77%
stats83%
-
-
-
-

Project Risks

-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
MethodCRAP
login30
store20
update20
update20
toggle20
register12
index12
store12
update12
toggle12
store12
destroy12
logout6
destroy6
setActive6
destroy6
show6
update3
store3
toggle3
approve2
reject2
destroy2
index2
stats2
-
-
-
- -
- - - - - - diff --git a/backend/coverage-report/Http/Controllers/Api/V1/index.html b/backend/coverage-report/Http/Controllers/Api/V1/index.html deleted file mode 100644 index 75a828bc..00000000 --- a/backend/coverage-report/Http/Controllers/Api/V1/index.html +++ /dev/null @@ -1,374 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Http/Controllers/Api/V1 - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 26.81% covered (danger) -
-
-
26.81%
115 / 429
-
- 17.07% covered (danger) -
-
-
17.07%
7 / 41
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 10
ArticlesController.php
-
- 87.88% covered (warning) -
-
-
87.88%
29 / 33
-
- 33.33% covered (danger) -
-
-
33.33%
1 / 3
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
AuthController.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 56
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 4
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
BaseController.php
-
- 87.50% covered (warning) -
-
-
87.50%
14 / 16
-
- 60.00% covered (warning) -
-
-
60.00%
3 / 5
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
DashboardController.php
-
- 84.62% covered (warning) -
-
-
84.62%
11 / 13
-
- 50.00% covered (danger) -
-
-
50.00%
1 / 2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
FeedsController.php
-
- 76.00% covered (warning) -
-
-
76.00%
38 / 50
-
- 33.33% covered (danger) -
-
-
33.33%
2 / 6
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
LogsController.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 19
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
PlatformAccountsController.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 73
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 6
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
PlatformChannelsController.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 62
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 6
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
RoutingController.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 80
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 6
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
SettingsController.php
-
- 85.19% covered (warning) -
-
-
85.19%
23 / 27
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- -
- - diff --git a/backend/coverage-report/Http/Controllers/Api/dashboard.html b/backend/coverage-report/Http/Controllers/Api/dashboard.html deleted file mode 100644 index c41629e0..00000000 --- a/backend/coverage-report/Http/Controllers/Api/dashboard.html +++ /dev/null @@ -1,364 +0,0 @@ - - - - - Dashboard for /var/www/html/backend/app/Http/Controllers/Api - - - - - - - -
-
-
-
- -
-
-
-
-
-
-
-

Classes

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
- -
-
-

Methods

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
-
-
-

Insufficient Coverage

-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
MethodCoverage
login0%
register0%
logout0%
me0%
sendNotFound0%
sendUnauthorized0%
index0%
index0%
store0%
show0%
update0%
destroy0%
setActive0%
index0%
store0%
show0%
update0%
destroy0%
toggle0%
index0%
store0%
show0%
update0%
destroy0%
toggle0%
update63%
store66%
approve71%
reject71%
destroy71%
index71%
toggle77%
stats83%
-
-
-
-

Project Risks

-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
MethodCRAP
login30
store20
update20
update20
toggle20
register12
index12
store12
update12
toggle12
store12
destroy12
logout6
destroy6
setActive6
destroy6
show6
update3
store3
toggle3
approve2
reject2
destroy2
index2
stats2
-
-
-
- -
- - - - - - diff --git a/backend/coverage-report/Http/Controllers/Api/index.html b/backend/coverage-report/Http/Controllers/Api/index.html deleted file mode 100644 index d5a9acbb..00000000 --- a/backend/coverage-report/Http/Controllers/Api/index.html +++ /dev/null @@ -1,121 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Http/Controllers/Api - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 26.81% covered (danger) -
-
-
26.81%
115 / 429
-
- 17.07% covered (danger) -
-
-
17.07%
7 / 41
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 10
V1
-
- 26.81% covered (danger) -
-
-
26.81%
115 / 429
-
- 17.07% covered (danger) -
-
-
17.07%
7 / 41
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 10
-
- -
- - diff --git a/backend/coverage-report/Http/Controllers/ArticlesController.php.html b/backend/coverage-report/Http/Controllers/ArticlesController.php.html deleted file mode 100644 index 19b58e3b..00000000 --- a/backend/coverage-report/Http/Controllers/ArticlesController.php.html +++ /dev/null @@ -1,234 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Http/Controllers/ArticlesController.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 9
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
ArticlesController
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 9
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
12
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 __invoke
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 5
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 approve
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 reject
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Http\Controllers;
4
5use App\Models\Article;
6use App\Models\Setting;
7use Illuminate\Contracts\View\View;
8use Illuminate\Http\RedirectResponse;
9use Illuminate\Http\Request;
10
11class ArticlesController extends Controller
12{
13    public function __invoke(Request $request): View
14    {
15        $articles = Article::with('articlePublication')
16            ->orderBy('created_at', 'desc')
17            ->paginate(15);
18
19        $publishingApprovalsEnabled = Setting::isPublishingApprovalsEnabled();
20
21        return view('pages.articles.index', compact('articles', 'publishingApprovalsEnabled'));
22    }
23
24    public function approve(Article $article): RedirectResponse
25    {
26        $article->approve('manual');
27
28        return redirect()->back()->with('success', 'Article approved and queued for publishing.');
29    }
30
31    public function reject(Article $article): RedirectResponse
32    {
33        $article->reject('manual');
34
35        return redirect()->back()->with('success', 'Article rejected.');
36    }
37}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 19:15:34 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report/Http/Controllers/Controller.php.html b/backend/coverage-report/Http/Controllers/Controller.php.html deleted file mode 100644 index d55ace27..00000000 --- a/backend/coverage-report/Http/Controllers/Controller.php.html +++ /dev/null @@ -1,109 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Http/Controllers/Controller.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
n/a
0 / 0
n/a
0 / 0
CRAP
n/a
0 / 0
Controller
n/a
0 / 0
n/a
0 / 0
0
n/a
0 / 0
-
- - - - - - - - - - - - -
1<?php
2
3namespace App\Http\Controllers;
4
5abstract class Controller
6{
7    //
8}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 19:15:34 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report/Http/Controllers/FeedsController.php.html b/backend/coverage-report/Http/Controllers/FeedsController.php.html deleted file mode 100644 index 813f2ad8..00000000 --- a/backend/coverage-report/Http/Controllers/FeedsController.php.html +++ /dev/null @@ -1,388 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Http/Controllers/FeedsController.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 28
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 8
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
FeedsController
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 28
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 8
90
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 index
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 4
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 create
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 store
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 8
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 show
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 edit
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 update
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 5
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 destroy
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 toggle
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 5
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
6
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Http\Controllers;
4
5use App\Models\Feed;
6use App\Http\Requests\StoreFeedRequest;
7use App\Http\Requests\UpdateFeedRequest;
8use App\Services\OnboardingRedirectService;
9use Illuminate\Contracts\View\View;
10use Illuminate\Http\RedirectResponse;
11
12class FeedsController extends Controller
13{
14    public function index(): View
15    {
16        $feeds = Feed::orderBy('is_active', 'desc')
17            ->orderBy('name')
18            ->get();
19
20        return view('pages.feeds.index', compact('feeds'));
21    }
22
23    public function create(): View
24    {
25        return view('pages.feeds.create');
26    }
27
28    public function store(StoreFeedRequest $request): RedirectResponse
29    {
30        $validated = $request->validated();
31        $validated['is_active'] = $validated['is_active'] ?? true;
32
33        Feed::create($validated);
34
35        return OnboardingRedirectService::handleRedirect(
36            $request,
37            'feeds.index',
38            'Feed created successfully!'
39        );
40    }
41
42    public function show(Feed $feed): View
43    {
44        return view('pages.feeds.show', compact('feed'));
45    }
46
47    public function edit(Feed $feed): View
48    {
49        return view('pages.feeds.edit', compact('feed'));
50    }
51
52    public function update(UpdateFeedRequest $request, Feed $feed): RedirectResponse
53    {
54        $validated = $request->validated();
55        $validated['is_active'] = $validated['is_active'] ?? $feed->is_active;
56
57        $feed->update($validated);
58
59        return redirect()->route('feeds.index')
60            ->with('success', 'Feed updated successfully!');
61    }
62
63    public function destroy(Feed $feed): RedirectResponse
64    {
65        $feed->delete();
66
67        return redirect()->route('feeds.index')
68            ->with('success', 'Feed deleted successfully!');
69    }
70
71    public function toggle(Feed $feed): RedirectResponse
72    {
73        $newStatus = !$feed->is_active;
74        $feed->update(['is_active' => $newStatus]);
75
76        $status = $newStatus ? 'activated' : 'deactivated';
77
78        return redirect()->route('feeds.index')
79            ->with('success', "Feed {$status} successfully!");
80    }
81}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 19:15:34 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report/Http/Controllers/LogsController.php.html b/backend/coverage-report/Http/Controllers/LogsController.php.html deleted file mode 100644 index 55c0e421..00000000 --- a/backend/coverage-report/Http/Controllers/LogsController.php.html +++ /dev/null @@ -1,170 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Http/Controllers/LogsController.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
LogsController
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 __invoke
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Http\Controllers;
4
5use App\Models\Log;
6use Illuminate\Contracts\View\View;
7use Illuminate\Http\Request;
8
9class LogsController extends Controller
10{
11    public function __invoke(Request $request): View
12    {
13        $logs = Log::orderBy('created_at', 'desc')->paginate(50);
14
15        return view('pages.logs.index', compact('logs'));
16    }
17}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 19:15:34 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report/Http/Controllers/OnboardingController.php.html b/backend/coverage-report/Http/Controllers/OnboardingController.php.html deleted file mode 100644 index 28fc7288..00000000 --- a/backend/coverage-report/Http/Controllers/OnboardingController.php.html +++ /dev/null @@ -1,443 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Http/Controllers/OnboardingController.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 40
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 9
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
OnboardingController
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 40
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 9
506
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 index
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 15
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
6
 platform
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
6
 feed
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 5
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
12
 channel
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 7
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
20
 complete
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 6
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
30
 needsOnboarding
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
12
 hasPlatformAccount
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 hasFeed
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 hasChannel
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Http\Controllers;
4
5use App\Models\Feed;
6use App\Models\PlatformAccount;
7use App\Models\PlatformChannel;
8use App\Models\PlatformInstance;
9use App\Services\SystemStatusService;
10use App\Services\DashboardStatsService;
11use Illuminate\Http\Request;
12use Illuminate\View\View;
13use Illuminate\Http\RedirectResponse;
14
15class OnboardingController extends Controller
16{
17    public function index(Request $request): View|RedirectResponse
18    {
19        // Check if user needs onboarding
20        if (!$this->needsOnboarding()) {
21            $systemStatus = resolve(SystemStatusService::class)->getSystemStatus();
22            $statsService = resolve(DashboardStatsService::class);
23            
24            $period = $request->get('period', 'today');
25            $stats = $statsService->getStats($period);
26            $systemStats = $statsService->getSystemStats();
27            $availablePeriods = $statsService->getAvailablePeriods();
28
29            return view('pages.dashboard', compact(
30                'systemStatus', 
31                'stats', 
32                'systemStats', 
33                'availablePeriods', 
34                'period'
35            ));
36        }
37
38        return view('onboarding.welcome');
39    }
40
41    public function platform(): View|RedirectResponse
42    {
43        if (!$this->needsOnboarding()) {
44            return redirect()->route('feeds.index');
45        }
46
47        return view('onboarding.platform');
48    }
49
50    public function feed(): View|RedirectResponse
51    {
52        if (!$this->needsOnboarding()) {
53            return redirect()->route('feeds.index');
54        }
55
56        if (!$this->hasPlatformAccount()) {
57            return redirect()->route('onboarding.platform');
58        }
59
60        return view('onboarding.feed');
61    }
62
63    public function channel(): View|RedirectResponse
64    {
65        if (!$this->needsOnboarding()) {
66            return redirect()->route('feeds.index');
67        }
68
69        if (!$this->hasPlatformAccount()) {
70            return redirect()->route('onboarding.platform');
71        }
72
73        if (!$this->hasFeed()) {
74            return redirect()->route('onboarding.feed');
75        }
76
77        return view('onboarding.channel');
78    }
79
80    public function complete(): View|RedirectResponse
81    {
82        if (!$this->needsOnboarding()) {
83            return redirect()->route('feeds.index');
84        }
85
86        if (!$this->hasPlatformAccount() || !$this->hasFeed() || !$this->hasChannel()) {
87            return redirect()->route('onboarding.index');
88        }
89
90        $systemStatus = resolve(SystemStatusService::class)->getSystemStatus();
91
92        return view('onboarding.complete', compact('systemStatus'));
93    }
94
95    private function needsOnboarding(): bool
96    {
97        return !$this->hasPlatformAccount() || !$this->hasFeed() || !$this->hasChannel();
98    }
99
100    private function hasPlatformAccount(): bool
101    {
102        return PlatformAccount::where('is_active', true)->exists();
103    }
104
105    private function hasFeed(): bool
106    {
107        return Feed::where('is_active', true)->exists();
108    }
109
110    private function hasChannel(): bool
111    {
112        return PlatformChannel::where('is_active', true)->exists();
113    }
114}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 19:15:34 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report/Http/Controllers/PlatformAccountsController.php.html b/backend/coverage-report/Http/Controllers/PlatformAccountsController.php.html deleted file mode 100644 index 75efd568..00000000 --- a/backend/coverage-report/Http/Controllers/PlatformAccountsController.php.html +++ /dev/null @@ -1,391 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Http/Controllers/PlatformAccountsController.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 46
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 7
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
PlatformAccountsController
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 46
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 7
110
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 index
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 create
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 store
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 25
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
12
 edit
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 update
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 11
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
6
 destroy
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 setActive
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Http\Controllers;
4
5use App\Models\PlatformAccount;
6use App\Models\PlatformInstance;
7use App\Enums\PlatformEnum;
8use Illuminate\Http\Request;
9use Illuminate\Contracts\View\View;
10use Illuminate\Http\RedirectResponse;
11use Illuminate\Support\Facades\View as ViewFacade;
12
13class PlatformAccountsController extends Controller
14{
15    public function index(): View
16    {
17        $accounts = PlatformAccount::orderBy('platform')->orderBy('created_at', 'desc')->get();
18
19        return view('pages.platforms.index', compact('accounts'));
20    }
21
22    public function create(): View
23    {
24        return ViewFacade::make('pages.platforms.create');
25    }
26
27    public function store(Request $request): RedirectResponse
28    {
29        $validated = $request->validate([
30            'platform' => 'required|in:lemmy,mastodon,reddit',
31            'instance_url' => 'required|url',
32            'username' => 'required|string|max:255',
33            'password' => 'required|string',
34            'settings' => 'nullable|array',
35        ]);
36
37        // Create or find platform instance
38        $platformEnum = PlatformEnum::from($validated['platform']);
39        $instance = PlatformInstance::firstOrCreate([
40            'platform' => $platformEnum,
41            'url' => $validated['instance_url'],
42        ], [
43            'name' => parse_url($validated['instance_url'], PHP_URL_HOST),
44            'description' => ucfirst($validated['platform']) . ' instance',
45            'is_active' => true,
46        ]);
47
48        $account = PlatformAccount::create($validated);
49
50        // If this is the first account for this platform, make it active
51        if (! PlatformAccount::where('platform', $validated['platform'])->where('is_active', true)->exists()) {
52            $account->setAsActive();
53        }
54
55        // Check if there's a redirect_to parameter for onboarding flow
56        $redirectTo = $request->input('redirect_to');
57        if ($redirectTo) {
58            return redirect($redirectTo)
59                ->with('success', 'Platform account created successfully!');
60        }
61
62        return redirect()->route('platforms.index')
63            ->with('success', 'Platform account created successfully!');
64    }
65
66    public function edit(PlatformAccount $platformAccount): View
67    {
68        return ViewFacade::make('pages.platforms.edit', compact('platformAccount'));
69    }
70
71    public function update(Request $request, PlatformAccount $platformAccount): RedirectResponse
72    {
73        $validated = $request->validate([
74            'instance_url' => 'required|url',
75            'username' => 'required|string|max:255',
76            'password' => 'nullable|string',
77            'settings' => 'nullable|array',
78        ]);
79
80        // Don't update password if not provided
81        if (empty($validated['password'])) {
82            unset($validated['password']);
83        }
84
85        $platformAccount->update($validated);
86
87        return redirect()->route('platforms.index')
88            ->with('success', 'Platform account updated successfully!');
89    }
90
91    public function destroy(PlatformAccount $platformAccount): RedirectResponse
92    {
93        $platformAccount->delete();
94
95        return redirect()->route('platforms.index')
96            ->with('success', 'Platform account deleted successfully!');
97    }
98
99    public function setActive(PlatformAccount $platformAccount): RedirectResponse
100    {
101        $platformAccount->setAsActive();
102
103        return redirect()->route('platforms.index')
104            ->with('success', "Set $platformAccount->username@$platformAccount->instance_url as active for {$platformAccount->platform->value}!");
105    }
106}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 19:15:34 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report/Http/Controllers/PlatformChannelsController.php.html b/backend/coverage-report/Http/Controllers/PlatformChannelsController.php.html deleted file mode 100644 index 897a3d92..00000000 --- a/backend/coverage-report/Http/Controllers/PlatformChannelsController.php.html +++ /dev/null @@ -1,423 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Http/Controllers/PlatformChannelsController.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 53
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 8
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
PlatformChannelsController
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 53
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 8
110
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 index
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 5
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 create
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 4
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 store
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 18
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
6
 show
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 edit
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 4
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 update
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 12
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 destroy
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 toggle
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 5
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
6
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Http\Controllers;
4
5use App\Models\PlatformChannel;
6use App\Models\PlatformInstance;
7use Illuminate\Http\Request;
8use Illuminate\Contracts\View\View;
9use Illuminate\Http\RedirectResponse;
10use Illuminate\Support\Facades\View as ViewFacade;
11
12class PlatformChannelsController extends Controller
13{
14    public function index(): View
15    {
16        $channels = PlatformChannel::with('platformInstance')
17            ->orderBy('platform_instance_id')
18            ->orderBy('name')
19            ->get();
20        
21        return ViewFacade::make('pages.channels.index', compact('channels'));
22    }
23
24    public function create(): View
25    {
26        $instances = PlatformInstance::where('is_active', true)
27            ->orderBy('name')
28            ->get();
29            
30        return ViewFacade::make('pages.channels.create', compact('instances'));
31    }
32
33    public function store(Request $request): RedirectResponse
34    {
35        $validated = $request->validate([
36            'platform_instance_id' => 'required|exists:platform_instances,id',
37            'name' => 'required|string|max:255',
38            'display_name' => 'nullable|string|max:255',
39            'channel_id' => 'nullable|string|max:255',
40            'description' => 'nullable|string',
41            'language_id' => 'required|exists:languages,id',
42            'is_active' => 'boolean',
43        ]);
44
45        // Default is_active to true if not provided
46        $validated['is_active'] = $validated['is_active'] ?? true;
47        
48        // Set display_name to name if not provided
49        $validated['display_name'] = $validated['display_name'] ?? $validated['name'];
50
51        PlatformChannel::create($validated);
52
53        // Check if there's a redirect_to parameter for onboarding flow
54        $redirectTo = $request->input('redirect_to');
55        if ($redirectTo) {
56            return redirect($redirectTo)
57                ->with('success', 'Channel created successfully!');
58        }
59
60        return redirect()->route('channels.index')
61            ->with('success', 'Channel created successfully!');
62    }
63
64    public function show(PlatformChannel $channel): View
65    {
66        $channel->load(['platformInstance', 'feeds']);
67        
68        return ViewFacade::make('pages.channels.show', compact('channel'));
69    }
70
71    public function edit(PlatformChannel $channel): View
72    {
73        $instances = PlatformInstance::where('is_active', true)
74            ->orderBy('name')
75            ->get();
76            
77        return ViewFacade::make('pages.channels.edit', compact('channel', 'instances'));
78    }
79
80    public function update(Request $request, PlatformChannel $channel): RedirectResponse
81    {
82        $validated = $request->validate([
83            'platform_instance_id' => 'required|exists:platform_instances,id',
84            'name' => 'required|string|max:255',
85            'display_name' => 'nullable|string|max:255',
86            'channel_id' => 'nullable|string|max:255',
87            'description' => 'nullable|string',
88            'language_id' => 'required|exists:languages,id',
89            'is_active' => 'boolean',
90        ]);
91
92        $channel->update($validated);
93
94        return redirect()->route('channels.index')
95            ->with('success', 'Channel updated successfully!');
96    }
97
98    public function destroy(PlatformChannel $channel): RedirectResponse
99    {
100        $channel->delete();
101
102        return redirect()->route('channels.index')
103            ->with('success', 'Channel deleted successfully!');
104    }
105
106    public function toggle(PlatformChannel $channel): RedirectResponse
107    {
108        $newStatus = !$channel->is_active;
109        $channel->update(['is_active' => $newStatus]);
110
111        $status = $newStatus ? 'activated' : 'deactivated';
112
113        return redirect()->route('channels.index')
114            ->with('success', "Channel {$status} successfully!");
115    }
116}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 19:15:34 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report/Http/Controllers/RoutingController.php.html b/backend/coverage-report/Http/Controllers/RoutingController.php.html deleted file mode 100644 index b611b864..00000000 --- a/backend/coverage-report/Http/Controllers/RoutingController.php.html +++ /dev/null @@ -1,480 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Http/Controllers/RoutingController.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 87
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 8
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
RoutingController
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 87
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 8
240
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 index
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 9
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 create
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 8
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 store
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 28
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
12
 edit
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 6
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
6
 update
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 14
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 destroy
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 toggle
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 13
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
12
 parseJsonFilters
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 6
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
12
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Http\Controllers;
4
5use App\Models\Feed;
6use App\Models\Route;
7use App\Models\PlatformChannel;
8use App\Services\RoutingValidationService;
9use App\Exceptions\RoutingMismatchException;
10use Illuminate\Database\Eloquent\Collection;
11use Illuminate\Http\Request;
12use Illuminate\Contracts\View\View;
13use Illuminate\Http\RedirectResponse;
14
15class RoutingController extends Controller
16{
17    public function index(): View
18    {
19        $feeds = Feed::with(['channels.platformInstance'])
20            ->where('is_active', true)
21            ->orderBy('name')
22            ->get();
23
24        $channels = PlatformChannel::with(['platformInstance', 'feeds'])
25            ->where('is_active', true)
26            ->orderBy('name')
27            ->get();
28
29        return view('pages.routing.index', compact('feeds', 'channels'));
30    }
31
32    public function create(): View
33    {
34        $feeds = Feed::where('is_active', true)
35            ->orderBy('name')
36            ->get();
37
38        $channels = PlatformChannel::with('platformInstance')
39            ->where('is_active', true)
40            ->orderBy('name')
41            ->get();
42
43        return view('pages.routing.create', compact('feeds', 'channels'));
44    }
45
46    public function store(Request $request): RedirectResponse
47    {
48        $validated = $request->validate([
49            'feed_id' => 'required|exists:feeds,id',
50            'channel_ids' => 'required|array|min:1',
51            'channel_ids.*' => 'exists:platform_channels,id',
52            'priority' => 'integer|min:0|max:100',
53            'filters' => 'nullable|string'
54        ]);
55
56        /** @var Feed $feed */
57        $feed = Feed::findOrFail($validated['feed_id']);
58        
59        /** @var Collection<int, PlatformChannel> $channels */
60        $channels = PlatformChannel::findMany($validated['channel_ids']);
61        $priority = $validated['priority'] ?? 0;
62
63        try {
64            app(RoutingValidationService::class)->validateLanguageCompatibility($feed, $channels);
65        } catch (RoutingMismatchException $e) {
66            return redirect()->back()
67                ->withInput()
68                ->withErrors(['language' => $e->getMessage()]);
69        }
70
71        $filters = $this->parseJsonFilters($validated['filters'] ?? null);
72
73        // Attach channels to feed
74        $syncData = [];
75        foreach ($validated['channel_ids'] as $channelId) {
76            $syncData[$channelId] = [
77                'is_active' => true,
78                'priority' => $priority,
79                'filters' => $filters,
80                'created_at' => now(),
81                'updated_at' => now()
82            ];
83        }
84
85        $feed->channels()->syncWithoutDetaching($syncData);
86
87        return redirect()->route('routing.index')
88            ->with('success', 'Feed routing created successfully!');
89    }
90
91    public function edit(Feed $feed, PlatformChannel $channel): View
92    {
93        $routing = $feed->channels()
94            ->wherePivot('platform_channel_id', $channel->id)
95            ->first();
96
97        if (! $routing) {
98            abort(404, 'Routing not found');
99        }
100
101        return view('pages.routing.edit', compact('feed', 'channel', 'routing'));
102    }
103
104    public function update(Request $request, Feed $feed, PlatformChannel $channel): RedirectResponse
105    {
106        $validated = $request->validate([
107            'is_active' => 'boolean',
108            'priority' => 'integer|min:0|max:100',
109            'filters' => 'nullable|string'
110        ]);
111
112        $filters = $this->parseJsonFilters($validated['filters'] ?? null);
113
114        $feed->channels()->updateExistingPivot($channel->id, [
115            'is_active' => $validated['is_active'] ?? true,
116            'priority' => $validated['priority'] ?? 0,
117            'filters' => $filters,
118            'updated_at' => now()
119        ]);
120
121        return redirect()->route('routing.index')
122            ->with('success', 'Routing updated successfully!');
123    }
124
125    public function destroy(Feed $feed, PlatformChannel $channel): RedirectResponse
126    {
127        $feed->channels()->detach($channel->id);
128
129        return redirect()->route('routing.index')
130            ->with('success', 'Routing deleted successfully!');
131    }
132
133    public function toggle(Request $request, Feed $feed, PlatformChannel $channel): RedirectResponse
134    {
135        $routing = Route::where('feed_id', $feed->id)
136            ->where('platform_channel_id', $channel->id)
137            ->first();
138
139        if (! $routing) {
140            abort(404, 'Routing not found');
141        }
142
143        $newStatus = ! $routing->is_active;
144
145        $feed->channels()->updateExistingPivot($channel->id, [
146            'is_active' => $newStatus,
147            'updated_at' => now()
148        ]);
149
150        $status = $newStatus ? 'activated' : 'deactivated';
151
152        return redirect()->route('routing.index')
153            ->with('success', "Routing {$status} successfully!");
154    }
155
156    /**
157     * @return array<string, mixed>|null
158     */
159    private function parseJsonFilters(?string $json): ?array
160    {
161        if (empty($json)) {
162            return null;
163        }
164
165        $decoded = json_decode($json, true);
166
167        if (json_last_error() === JSON_ERROR_NONE) {
168            return $decoded;
169        }
170
171        return null;
172    }
173}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 19:15:34 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report/Http/Controllers/SettingsController.php.html b/backend/coverage-report/Http/Controllers/SettingsController.php.html deleted file mode 100644 index 69f4f996..00000000 --- a/backend/coverage-report/Http/Controllers/SettingsController.php.html +++ /dev/null @@ -1,214 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Http/Controllers/SettingsController.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 14
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
SettingsController
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 14
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
12
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 index
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 update
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 11
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
6
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Http\Controllers;
4
5use App\Models\Setting;
6use Illuminate\Contracts\View\View;
7use Illuminate\Http\RedirectResponse;
8use Illuminate\Http\Request;
9
10class SettingsController extends Controller
11{
12    public function index(): View
13    {
14        $articleProcessingEnabled = Setting::isArticleProcessingEnabled();
15        $publishingApprovalsEnabled = Setting::isPublishingApprovalsEnabled();
16        
17        return view('pages.settings.index', compact('articleProcessingEnabled', 'publishingApprovalsEnabled'));
18    }
19
20    public function update(Request $request): RedirectResponse
21    {
22        $request->validate([
23            'article_processing_enabled' => 'boolean',
24            'enable_publishing_approvals' => 'boolean',
25        ]);
26
27        Setting::setArticleProcessingEnabled($request->boolean('article_processing_enabled'));
28        Setting::setPublishingApprovalsEnabled($request->boolean('enable_publishing_approvals'));
29
30        // If redirected from onboarding, go to dashboard
31        if ($request->get('from') === 'onboarding') {
32            return redirect()->route('onboarding.index')
33                ->with('success', 'System activated successfully! Welcome to Lemmy Poster.');
34        }
35
36        return redirect()->route('settings.index')
37            ->with('success', 'Settings updated successfully.');
38    }
39}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 19:15:34 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report/Http/Controllers/dashboard.html b/backend/coverage-report/Http/Controllers/dashboard.html deleted file mode 100644 index 571867ad..00000000 --- a/backend/coverage-report/Http/Controllers/dashboard.html +++ /dev/null @@ -1,439 +0,0 @@ - - - - - Dashboard for /var/www/html/backend/app/Http/Controllers - - - - - - - -
-
-
-
- -
-
-
-
-
-
-
-

Classes

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
-
- - -
-
-
-

Methods

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
-
-
-

Insufficient Coverage

-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
MethodCoverage
login0%
register0%
logout0%
me0%
sendNotFound0%
sendUnauthorized0%
index0%
index0%
store0%
show0%
update0%
destroy0%
setActive0%
index0%
store0%
show0%
update0%
destroy0%
toggle0%
index0%
store0%
show0%
update0%
destroy0%
toggle0%
__invoke0%
approve0%
reject0%
index0%
create0%
store0%
show0%
edit0%
update0%
destroy0%
toggle0%
__invoke0%
index0%
platform0%
feed0%
channel0%
complete0%
needsOnboarding0%
hasPlatformAccount0%
hasFeed0%
hasChannel0%
index0%
create0%
store0%
edit0%
update0%
destroy0%
setActive0%
index0%
create0%
store0%
show0%
edit0%
update0%
destroy0%
toggle0%
index0%
create0%
store0%
edit0%
update0%
destroy0%
toggle0%
parseJsonFilters0%
index0%
update0%
update63%
store66%
approve71%
reject71%
destroy71%
index71%
toggle77%
stats83%
-
-
-
-

Project Risks

-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
MethodCRAP
login30
complete30
store20
update20
update20
toggle20
channel20
register12
index12
store12
update12
toggle12
store12
destroy12
feed12
needsOnboarding12
store12
store12
toggle12
parseJsonFilters12
logout6
destroy6
setActive6
destroy6
show6
toggle6
index6
platform6
update6
store6
toggle6
edit6
update6
update3
store3
toggle3
approve2
reject2
destroy2
index2
stats2
-
-
-
- -
- - - - - - diff --git a/backend/coverage-report/Http/Controllers/index.html b/backend/coverage-report/Http/Controllers/index.html deleted file mode 100644 index 705a2f24..00000000 --- a/backend/coverage-report/Http/Controllers/index.html +++ /dev/null @@ -1,357 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Http/Controllers - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 16.24% covered (danger) -
-
-
16.24%
115 / 708
-
- 8.05% covered (danger) -
-
-
8.05%
7 / 87
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 18
Api
-
- 26.81% covered (danger) -
-
-
26.81%
115 / 429
-
- 17.07% covered (danger) -
-
-
17.07%
7 / 41
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 10
ArticlesController.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 9
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
Controller.php
n/a
0 / 0
n/a
0 / 0
n/a
0 / 0
FeedsController.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 28
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 8
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
LogsController.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
OnboardingController.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 40
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 9
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
PlatformAccountsController.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 46
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 7
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
PlatformChannelsController.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 53
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 8
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
RoutingController.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 87
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 8
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
SettingsController.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 14
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- -
- - diff --git a/backend/coverage-report/Http/Middleware/HandleAppearance.php.html b/backend/coverage-report/Http/Middleware/HandleAppearance.php.html deleted file mode 100644 index 261a3643..00000000 --- a/backend/coverage-report/Http/Middleware/HandleAppearance.php.html +++ /dev/null @@ -1,176 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Http/Middleware/HandleAppearance.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
HandleAppearance
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 handle
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Http\Middleware;
4
5use Closure;
6use Illuminate\Http\Request;
7use Illuminate\Support\Facades\View;
8use Symfony\Component\HttpFoundation\Response;
9
10class HandleAppearance
11{
12    /**
13     * Handle an incoming request.
14     *
15     * @param  \Closure(\Illuminate\Http\Request): (\Symfony\Component\HttpFoundation\Response)  $next
16     */
17    public function handle(Request $request, Closure $next): Response
18    {
19        View::share('appearance', $request->cookie('appearance') ?? 'system');
20
21        return $next($request);
22    }
23}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 19:15:34 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report/Http/Middleware/HandleInertiaRequests.php.html b/backend/coverage-report/Http/Middleware/HandleInertiaRequests.php.html deleted file mode 100644 index ba62183f..00000000 --- a/backend/coverage-report/Http/Middleware/HandleInertiaRequests.php.html +++ /dev/null @@ -1,217 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Http/Middleware/HandleInertiaRequests.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 4
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
HandleInertiaRequests
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 4
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
6
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 version
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 share
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Http\Middleware;
4
5use Illuminate\Http\Request;
6use Inertia\Middleware;
7
8class HandleInertiaRequests extends Middleware
9{
10    /**
11     * The root template that's loaded on the first page visit.
12     *
13     * @see https://inertiajs.com/server-side-setup#root-template
14     *
15     * @var string
16     */
17    protected $rootView = 'app';
18
19    /**
20     * Determines the current asset version.
21     *
22     * @see https://inertiajs.com/asset-versioning
23     */
24    public function version(Request $request): ?string
25    {
26        return parent::version($request);
27    }
28
29    /**
30     * Define the props that are shared by default.
31     *
32     * @see https://inertiajs.com/shared-data
33     *
34     * @return array<string, mixed>
35     */
36    public function share(Request $request): array
37    {
38        return array_merge(parent::share($request), [
39            //
40        ]);
41    }
42}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 19:15:34 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report/Http/Middleware/dashboard.html b/backend/coverage-report/Http/Middleware/dashboard.html deleted file mode 100644 index 41bcd7b2..00000000 --- a/backend/coverage-report/Http/Middleware/dashboard.html +++ /dev/null @@ -1,290 +0,0 @@ - - - - - Dashboard for /var/www/html/backend/app/Http/Middleware - - - - - - - -
-
-
-
- -
-
-
-
-
-
-
-

Classes

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
-
-
-

Insufficient Coverage

- -
-
-

Project Risks

-
- - - - - - - - - - -
ClassCRAP
-
-
-
-
-
-

Methods

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
-
-
-

Insufficient Coverage

-
- - - - - - - - - - - - - -
MethodCoverage
handle0%
version0%
share0%
-
-
-
-

Project Risks

-
- - - - - - - - - - -
MethodCRAP
-
-
-
- -
- - - - - - diff --git a/backend/coverage-report/Http/Middleware/index.html b/backend/coverage-report/Http/Middleware/index.html deleted file mode 100644 index f07f1487..00000000 --- a/backend/coverage-report/Http/Middleware/index.html +++ /dev/null @@ -1,148 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Http/Middleware - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 6
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
HandleAppearance.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
HandleInertiaRequests.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 4
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- -
- - diff --git a/backend/coverage-report/Http/Requests/StoreFeedRequest.php.html b/backend/coverage-report/Http/Requests/StoreFeedRequest.php.html deleted file mode 100644 index 923f98bb..00000000 --- a/backend/coverage-report/Http/Requests/StoreFeedRequest.php.html +++ /dev/null @@ -1,203 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Http/Requests/StoreFeedRequest.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 100.00% covered (success) -
-
-
100.00%
9 / 9
-
- 100.00% covered (success) -
-
-
100.00%
2 / 2
CRAP
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
StoreFeedRequest
-
- 100.00% covered (success) -
-
-
100.00%
9 / 9
-
- 100.00% covered (success) -
-
-
100.00%
2 / 2
2
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
 authorize
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
1
 rules
-
- 100.00% covered (success) -
-
-
100.00%
8 / 8
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
1
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Http\Requests;
4
5use Illuminate\Foundation\Http\FormRequest;
6
7class StoreFeedRequest extends FormRequest
8{
9    public function authorize(): bool
10    {
11        return true;
12    }
13
14    /**
15     * @return array<string, string>
16     */
17    public function rules(): array
18    {
19        return [
20            'name' => 'required|string|max:255',
21            'url' => 'required|url|unique:feeds,url',
22            'type' => 'required|in:website,rss',
23            'language_id' => 'required|exists:languages,id',
24            'description' => 'nullable|string',
25            'is_active' => 'boolean'
26        ];
27    }
28}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 19:15:34 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report/Http/Requests/UpdateFeedRequest.php.html b/backend/coverage-report/Http/Requests/UpdateFeedRequest.php.html deleted file mode 100644 index 094589da..00000000 --- a/backend/coverage-report/Http/Requests/UpdateFeedRequest.php.html +++ /dev/null @@ -1,204 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Http/Requests/UpdateFeedRequest.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 100.00% covered (success) -
-
-
100.00%
9 / 9
-
- 100.00% covered (success) -
-
-
100.00%
2 / 2
CRAP
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
UpdateFeedRequest
-
- 100.00% covered (success) -
-
-
100.00%
9 / 9
-
- 100.00% covered (success) -
-
-
100.00%
2 / 2
3
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
 authorize
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
1
 rules
-
- 100.00% covered (success) -
-
-
100.00%
8 / 8
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
2
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Http\Requests;
4
5use App\Models\Feed;
6use Illuminate\Foundation\Http\FormRequest;
7
8class UpdateFeedRequest extends FormRequest
9{
10    public function authorize(): bool
11    {
12        return true;
13    }
14
15    /**
16     * @return array<string, string>
17     */
18    public function rules(): array
19    {
20        return [
21            'name' => 'required|string|max:255',
22            'url' => 'required|url|unique:feeds,url,' . ($this->route('feed') instanceof Feed ? (string)$this->route('feed')->id : (string)$this->route('feed')),
23            'type' => 'required|in:website,rss',
24            'language_id' => 'required|exists:languages,id',
25            'description' => 'nullable|string',
26            'is_active' => 'boolean'
27        ];
28    }
29}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 19:15:34 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report/Http/Requests/dashboard.html b/backend/coverage-report/Http/Requests/dashboard.html deleted file mode 100644 index 2574d433..00000000 --- a/backend/coverage-report/Http/Requests/dashboard.html +++ /dev/null @@ -1,285 +0,0 @@ - - - - - Dashboard for /var/www/html/backend/app/Http/Requests - - - - - - - -
-
-
-
- -
-
-
-
-
-
-
-

Classes

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
-
-
-

Insufficient Coverage

-
- - - - - - - - - - -
ClassCoverage
-
-
-
-

Project Risks

-
- - - - - - - - - - -
ClassCRAP
-
-
-
-
-
-

Methods

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
-
-
-

Insufficient Coverage

-
- - - - - - - - - - -
MethodCoverage
-
-
-
-

Project Risks

-
- - - - - - - - - - -
MethodCRAP
-
-
-
- -
- - - - - - diff --git a/backend/coverage-report/Http/Requests/index.html b/backend/coverage-report/Http/Requests/index.html deleted file mode 100644 index 7550c3cf..00000000 --- a/backend/coverage-report/Http/Requests/index.html +++ /dev/null @@ -1,148 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Http/Requests - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 100.00% covered (success) -
-
-
100.00%
18 / 18
-
- 100.00% covered (success) -
-
-
100.00%
4 / 4
-
- 100.00% covered (success) -
-
-
100.00%
2 / 2
StoreFeedRequest.php
-
- 100.00% covered (success) -
-
-
100.00%
9 / 9
-
- 100.00% covered (success) -
-
-
100.00%
2 / 2
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
UpdateFeedRequest.php
-
- 100.00% covered (success) -
-
-
100.00%
9 / 9
-
- 100.00% covered (success) -
-
-
100.00%
2 / 2
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
-
- -
- - diff --git a/backend/coverage-report/Http/Resources/ArticlePublicationResource.php.html b/backend/coverage-report/Http/Resources/ArticlePublicationResource.php.html deleted file mode 100644 index c92ce92e..00000000 --- a/backend/coverage-report/Http/Resources/ArticlePublicationResource.php.html +++ /dev/null @@ -1,179 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Http/Resources/ArticlePublicationResource.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 8
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
ArticlePublicationResource
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 8
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 toArray
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 8
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Http\Resources;
4
5use Illuminate\Http\Request;
6use Illuminate\Http\Resources\Json\JsonResource;
7
8class ArticlePublicationResource extends JsonResource
9{
10    /**
11     * Transform the resource into an array.
12     *
13     * @return array<string, mixed>
14     */
15    public function toArray(Request $request): array
16    {
17        return [
18            'id' => $this->id,
19            'article_id' => $this->article_id,
20            'status' => $this->status,
21            'published_at' => $this->published_at?->toISOString(),
22            'created_at' => $this->created_at->toISOString(),
23            'updated_at' => $this->updated_at->toISOString(),
24        ];
25    }
26}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 19:15:34 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report/Http/Resources/ArticleResource.php.html b/backend/coverage-report/Http/Resources/ArticleResource.php.html deleted file mode 100644 index 3a807397..00000000 --- a/backend/coverage-report/Http/Resources/ArticleResource.php.html +++ /dev/null @@ -1,189 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Http/Resources/ArticleResource.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 100.00% covered (success) -
-
-
100.00%
18 / 18
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
CRAP
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
ArticleResource
-
- 100.00% covered (success) -
-
-
100.00%
18 / 18
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
1
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
 toArray
-
- 100.00% covered (success) -
-
-
100.00%
18 / 18
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
1
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Http\Resources;
4
5use Illuminate\Http\Request;
6use Illuminate\Http\Resources\Json\JsonResource;
7
8class ArticleResource extends JsonResource
9{
10    /**
11     * Transform the resource into an array.
12     *
13     * @return array<string, mixed>
14     */
15    public function toArray(Request $request): array
16    {
17        return [
18            'id' => $this->id,
19            'feed_id' => $this->feed_id,
20            'url' => $this->url,
21            'title' => $this->title,
22            'description' => $this->description,
23            'is_valid' => $this->is_valid,
24            'is_duplicate' => $this->is_duplicate,
25            'approval_status' => $this->approval_status,
26            'approved_at' => $this->approved_at?->toISOString(),
27            'approved_by' => $this->approved_by,
28            'fetched_at' => $this->fetched_at?->toISOString(),
29            'validated_at' => $this->validated_at?->toISOString(),
30            'created_at' => $this->created_at->toISOString(),
31            'updated_at' => $this->updated_at->toISOString(),
32            'feed' => new FeedResource($this->whenLoaded('feed')),
33            'article_publication' => new ArticlePublicationResource($this->whenLoaded('articlePublication')),
34        ];
35    }
36}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 19:15:34 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report/Http/Resources/FeedResource.php.html b/backend/coverage-report/Http/Resources/FeedResource.php.html deleted file mode 100644 index ea9a6a9b..00000000 --- a/backend/coverage-report/Http/Resources/FeedResource.php.html +++ /dev/null @@ -1,184 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Http/Resources/FeedResource.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 100.00% covered (success) -
-
-
100.00%
13 / 13
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
CRAP
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
FeedResource
-
- 100.00% covered (success) -
-
-
100.00%
13 / 13
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
1
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
 toArray
-
- 100.00% covered (success) -
-
-
100.00%
13 / 13
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
1
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Http\Resources;
4
5use Illuminate\Http\Request;
6use Illuminate\Http\Resources\Json\JsonResource;
7
8class FeedResource extends JsonResource
9{
10    /**
11     * Transform the resource into an array.
12     *
13     * @return array<string, mixed>
14     */
15    public function toArray(Request $request): array
16    {
17        return [
18            'id' => $this->id,
19            'name' => $this->name,
20            'url' => $this->url,
21            'type' => $this->type,
22            'is_active' => $this->is_active,
23            'description' => $this->description,
24            'created_at' => $this->created_at->toISOString(),
25            'updated_at' => $this->updated_at->toISOString(),
26            'articles_count' => $this->when($request->routeIs('api.feeds.*'), function () {
27                return $this->articles()->count();
28            }),
29        ];
30    }
31}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 19:15:34 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report/Http/Resources/PlatformAccountResource.php.html b/backend/coverage-report/Http/Resources/PlatformAccountResource.php.html deleted file mode 100644 index 0eba1100..00000000 --- a/backend/coverage-report/Http/Resources/PlatformAccountResource.php.html +++ /dev/null @@ -1,184 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Http/Resources/PlatformAccountResource.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 13
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
PlatformAccountResource
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 13
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 toArray
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 13
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Http\Resources;
4
5use Illuminate\Http\Request;
6use Illuminate\Http\Resources\Json\JsonResource;
7
8class PlatformAccountResource extends JsonResource
9{
10    /**
11     * Transform the resource into an array.
12     *
13     * @return array<string, mixed>
14     */
15    public function toArray(Request $request): array
16    {
17        return [
18            'id' => $this->id,
19            'platform_instance_id' => $this->platform_instance_id,
20            'account_id' => $this->account_id,
21            'username' => $this->username,
22            'display_name' => $this->display_name,
23            'description' => $this->description,
24            'is_active' => $this->is_active,
25            'created_at' => $this->created_at->toISOString(),
26            'updated_at' => $this->updated_at->toISOString(),
27            'platform_instance' => new PlatformInstanceResource($this->whenLoaded('platformInstance')),
28            'channels' => PlatformChannelResource::collection($this->whenLoaded('channels')),
29        ];
30    }
31}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 19:15:34 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report/Http/Resources/PlatformChannelResource.php.html b/backend/coverage-report/Http/Resources/PlatformChannelResource.php.html deleted file mode 100644 index 40b9d0a6..00000000 --- a/backend/coverage-report/Http/Resources/PlatformChannelResource.php.html +++ /dev/null @@ -1,184 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Http/Resources/PlatformChannelResource.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 13
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
PlatformChannelResource
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 13
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 toArray
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 13
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Http\Resources;
4
5use Illuminate\Http\Request;
6use Illuminate\Http\Resources\Json\JsonResource;
7
8class PlatformChannelResource extends JsonResource
9{
10    /**
11     * Transform the resource into an array.
12     *
13     * @return array<string, mixed>
14     */
15    public function toArray(Request $request): array
16    {
17        return [
18            'id' => $this->id,
19            'platform_instance_id' => $this->platform_instance_id,
20            'channel_id' => $this->channel_id,
21            'name' => $this->name,
22            'display_name' => $this->display_name,
23            'description' => $this->description,
24            'is_active' => $this->is_active,
25            'created_at' => $this->created_at->toISOString(),
26            'updated_at' => $this->updated_at->toISOString(),
27            'platform_instance' => new PlatformInstanceResource($this->whenLoaded('platformInstance')),
28            'routes' => RouteResource::collection($this->whenLoaded('routes')),
29        ];
30    }
31}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 19:15:34 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report/Http/Resources/PlatformInstanceResource.php.html b/backend/coverage-report/Http/Resources/PlatformInstanceResource.php.html deleted file mode 100644 index 0df1c190..00000000 --- a/backend/coverage-report/Http/Resources/PlatformInstanceResource.php.html +++ /dev/null @@ -1,180 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Http/Resources/PlatformInstanceResource.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 9
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
PlatformInstanceResource
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 9
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 toArray
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 9
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Http\Resources;
4
5use Illuminate\Http\Request;
6use Illuminate\Http\Resources\Json\JsonResource;
7
8class PlatformInstanceResource extends JsonResource
9{
10    /**
11     * Transform the resource into an array.
12     *
13     * @return array<string, mixed>
14     */
15    public function toArray(Request $request): array
16    {
17        return [
18            'id' => $this->id,
19            'name' => $this->name,
20            'url' => $this->url,
21            'description' => $this->description,
22            'is_active' => $this->is_active,
23            'created_at' => $this->created_at->toISOString(),
24            'updated_at' => $this->updated_at->toISOString(),
25        ];
26    }
27}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 19:15:34 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report/Http/Resources/RouteResource.php.html b/backend/coverage-report/Http/Resources/RouteResource.php.html deleted file mode 100644 index 243fd66c..00000000 --- a/backend/coverage-report/Http/Resources/RouteResource.php.html +++ /dev/null @@ -1,182 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Http/Resources/RouteResource.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 11
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
RouteResource
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 11
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 toArray
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 11
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Http\Resources;
4
5use Illuminate\Http\Request;
6use Illuminate\Http\Resources\Json\JsonResource;
7
8class RouteResource extends JsonResource
9{
10    /**
11     * Transform the resource into an array.
12     *
13     * @return array<string, mixed>
14     */
15    public function toArray(Request $request): array
16    {
17        return [
18            'id' => $this->id,
19            'feed_id' => $this->feed_id,
20            'platform_channel_id' => $this->platform_channel_id,
21            'is_active' => $this->is_active,
22            'priority' => $this->priority,
23            'created_at' => $this->created_at->toISOString(),
24            'updated_at' => $this->updated_at->toISOString(),
25            'feed' => new FeedResource($this->whenLoaded('feed')),
26            'platform_channel' => new PlatformChannelResource($this->whenLoaded('platformChannel')),
27        ];
28    }
29}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 19:15:34 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report/Http/Resources/dashboard.html b/backend/coverage-report/Http/Resources/dashboard.html deleted file mode 100644 index 477f08c4..00000000 --- a/backend/coverage-report/Http/Resources/dashboard.html +++ /dev/null @@ -1,295 +0,0 @@ - - - - - Dashboard for /var/www/html/backend/app/Http/Resources - - - - - - - -
-
-
-
- -
-
-
-
-
-
-
-

Classes

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
-
- -
-

Project Risks

-
- - - - - - - - - - -
ClassCRAP
-
-
-
-
-
-

Methods

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
-
-
-

Insufficient Coverage

-
- - - - - - - - - - - - - - - -
MethodCoverage
toArray0%
toArray0%
toArray0%
toArray0%
toArray0%
-
-
-
-

Project Risks

-
- - - - - - - - - - -
MethodCRAP
-
-
-
- -
- - - - - - diff --git a/backend/coverage-report/Http/Resources/index.html b/backend/coverage-report/Http/Resources/index.html deleted file mode 100644 index a8fb1472..00000000 --- a/backend/coverage-report/Http/Resources/index.html +++ /dev/null @@ -1,288 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Http/Resources - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 36.47% covered (danger) -
-
-
36.47%
31 / 85
-
- 28.57% covered (danger) -
-
-
28.57%
2 / 7
-
- 28.57% covered (danger) -
-
-
28.57%
2 / 7
ArticlePublicationResource.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 8
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
ArticleResource.php
-
- 100.00% covered (success) -
-
-
100.00%
18 / 18
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
FeedResource.php
-
- 100.00% covered (success) -
-
-
100.00%
13 / 13
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
PlatformAccountResource.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 13
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
PlatformChannelResource.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 13
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
PlatformInstanceResource.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 9
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
RouteResource.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 11
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- -
- - diff --git a/backend/coverage-report/Http/dashboard.html b/backend/coverage-report/Http/dashboard.html deleted file mode 100644 index e48b613c..00000000 --- a/backend/coverage-report/Http/dashboard.html +++ /dev/null @@ -1,453 +0,0 @@ - - - - - Dashboard for /var/www/html/backend/app/Http - - - - - - - -
-
-
-
- -
-
-
-
-
-
-
-

Classes

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
-
- - -
-
-
-

Methods

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
-
-
-

Insufficient Coverage

-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
MethodCoverage
login0%
register0%
logout0%
me0%
sendNotFound0%
sendUnauthorized0%
index0%
index0%
store0%
show0%
update0%
destroy0%
setActive0%
index0%
store0%
show0%
update0%
destroy0%
toggle0%
index0%
store0%
show0%
update0%
destroy0%
toggle0%
__invoke0%
approve0%
reject0%
index0%
create0%
store0%
show0%
edit0%
update0%
destroy0%
toggle0%
__invoke0%
index0%
platform0%
feed0%
channel0%
complete0%
needsOnboarding0%
hasPlatformAccount0%
hasFeed0%
hasChannel0%
index0%
create0%
store0%
edit0%
update0%
destroy0%
setActive0%
index0%
create0%
store0%
show0%
edit0%
update0%
destroy0%
toggle0%
index0%
create0%
store0%
edit0%
update0%
destroy0%
toggle0%
parseJsonFilters0%
index0%
update0%
handle0%
version0%
share0%
toArray0%
toArray0%
toArray0%
toArray0%
toArray0%
update63%
store66%
approve71%
reject71%
destroy71%
index71%
toggle77%
stats83%
-
-
-
-

Project Risks

-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
MethodCRAP
login30
complete30
store20
update20
update20
toggle20
channel20
register12
index12
store12
update12
toggle12
store12
destroy12
feed12
needsOnboarding12
store12
store12
toggle12
parseJsonFilters12
logout6
destroy6
setActive6
destroy6
show6
toggle6
index6
platform6
update6
store6
toggle6
edit6
update6
update3
store3
toggle3
approve2
reject2
destroy2
index2
stats2
-
-
-
- -
- - - - - - diff --git a/backend/coverage-report/Http/index.html b/backend/coverage-report/Http/index.html deleted file mode 100644 index 447b1a4b..00000000 --- a/backend/coverage-report/Http/index.html +++ /dev/null @@ -1,203 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Http - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 20.07% covered (danger) -
-
-
20.07%
164 / 817
-
- 12.87% covered (danger) -
-
-
12.87%
13 / 101
-
- 13.79% covered (danger) -
-
-
13.79%
4 / 29
Controllers
-
- 16.24% covered (danger) -
-
-
16.24%
115 / 708
-
- 8.05% covered (danger) -
-
-
8.05%
7 / 87
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 18
Middleware
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 6
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
Requests
-
- 100.00% covered (success) -
-
-
100.00%
18 / 18
-
- 100.00% covered (success) -
-
-
100.00%
4 / 4
-
- 100.00% covered (success) -
-
-
100.00%
2 / 2
Resources
-
- 36.47% covered (danger) -
-
-
36.47%
31 / 85
-
- 28.57% covered (danger) -
-
-
28.57%
2 / 7
-
- 28.57% covered (danger) -
-
-
28.57%
2 / 7
-
- -
- - diff --git a/backend/coverage-report/Jobs/ArticleDiscoveryForFeedJob.php.html b/backend/coverage-report/Jobs/ArticleDiscoveryForFeedJob.php.html deleted file mode 100644 index a2d5d5c5..00000000 --- a/backend/coverage-report/Jobs/ArticleDiscoveryForFeedJob.php.html +++ /dev/null @@ -1,257 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Jobs/ArticleDiscoveryForFeedJob.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 100.00% covered (success) -
-
-
100.00%
26 / 26
-
- 100.00% covered (success) -
-
-
100.00%
3 / 3
CRAP
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
ArticleDiscoveryForFeedJob
-
- 100.00% covered (success) -
-
-
100.00%
26 / 26
-
- 100.00% covered (success) -
-
-
100.00%
3 / 3
3
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
 __construct
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
1
 handle
-
- 100.00% covered (success) -
-
-
100.00%
12 / 12
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
1
 dispatchForAllActiveFeeds
-
- 100.00% covered (success) -
-
-
100.00%
13 / 13
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
1
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Jobs;
4
5use App\Models\Feed;
6use App\Services\Article\ArticleFetcher;
7use App\Services\Log\LogSaver;
8use Illuminate\Contracts\Queue\ShouldQueue;
9use Illuminate\Foundation\Queue\Queueable;
10
11class ArticleDiscoveryForFeedJob implements ShouldQueue
12{
13    use Queueable;
14
15    private const FEED_DISCOVERY_DELAY_MINUTES = 5;
16
17    public function __construct(
18        private readonly Feed $feed
19    ) {
20        $this->onQueue('feed-discovery');
21    }
22
23    public function handle(): void
24    {
25        LogSaver::info('Starting feed article fetch', null, [
26            'feed_id' => $this->feed->id,
27            'feed_name' => $this->feed->name,
28            'feed_url' => $this->feed->url
29        ]);
30
31        $articles = ArticleFetcher::getArticlesFromFeed($this->feed);
32
33        LogSaver::info('Feed article fetch completed', null, [
34            'feed_id' => $this->feed->id,
35            'feed_name' => $this->feed->name,
36            'articles_count' => $articles->count()
37        ]);
38
39        $this->feed->update(['last_fetched_at' => now()]);
40    }
41
42    public static function dispatchForAllActiveFeeds(): void
43    {
44        Feed::where('is_active', true)
45            ->get()
46            ->each(function (Feed $feed, $index) {
47                // Space jobs apart to avoid overwhelming feeds
48                $delayMinutes = $index * self::FEED_DISCOVERY_DELAY_MINUTES;
49
50                self::dispatch($feed)
51                    ->delay(now()->addMinutes($delayMinutes))
52                    ->onQueue('feed-discovery');
53
54                LogSaver::info('Dispatched feed discovery job', null, [
55                    'feed_id' => $feed->id,
56                    'feed_name' => $feed->name,
57                    'delay_minutes' => $delayMinutes
58                ]);
59            });
60    }
61}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 19:15:34 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report/Jobs/ArticleDiscoveryJob.php.html b/backend/coverage-report/Jobs/ArticleDiscoveryJob.php.html deleted file mode 100644 index 98c103a6..00000000 --- a/backend/coverage-report/Jobs/ArticleDiscoveryJob.php.html +++ /dev/null @@ -1,207 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Jobs/ArticleDiscoveryJob.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 71.43% covered (warning) -
-
-
71.43%
5 / 7
-
- 50.00% covered (danger) -
-
-
50.00%
1 / 2
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
ArticleDiscoveryJob
-
- 71.43% covered (warning) -
-
-
71.43%
5 / 7
-
- 50.00% covered (danger) -
-
-
50.00%
1 / 2
3.21
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 __construct
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
1
 handle
-
- 66.67% covered (warning) -
-
-
66.67%
4 / 6
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2.15
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Jobs;
4
5use App\Models\Setting;
6use App\Services\Log\LogSaver;
7use Illuminate\Contracts\Queue\ShouldQueue;
8use Illuminate\Foundation\Queue\Queueable;
9
10class ArticleDiscoveryJob implements ShouldQueue
11{
12    use Queueable;
13
14    public function __construct()
15    {
16        $this->onQueue('feed-discovery');
17    }
18
19    public function handle(): void
20    {
21        if (!Setting::isArticleProcessingEnabled()) {
22            LogSaver::info('Article processing is disabled. Article discovery skipped.');
23
24            return;
25        }
26
27        LogSaver::info('Starting article discovery for all active feeds');
28
29        ArticleDiscoveryForFeedJob::dispatchForAllActiveFeeds();
30
31        LogSaver::info('Article discovery jobs dispatched for all active feeds');
32    }
33}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 19:15:34 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report/Jobs/PublishToLemmyJob.php.html b/backend/coverage-report/Jobs/PublishToLemmyJob.php.html deleted file mode 100644 index 13c4f6a2..00000000 --- a/backend/coverage-report/Jobs/PublishToLemmyJob.php.html +++ /dev/null @@ -1,212 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Jobs/PublishToLemmyJob.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 16.67% covered (danger) -
-
-
16.67%
1 / 6
-
- 50.00% covered (danger) -
-
-
50.00%
1 / 2
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
PublishToLemmyJob
-
- 16.67% covered (danger) -
-
-
16.67%
1 / 6
-
- 50.00% covered (danger) -
-
-
50.00%
1 / 2
8.21
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 __construct
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
1
 handle
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 5
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
6
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Jobs;
4
5use App\Exceptions\PublishException;
6use App\Models\Article;
7use App\Services\Article\ArticleFetcher;
8use App\Services\Publishing\ArticlePublishingService;
9use Illuminate\Contracts\Queue\ShouldQueue;
10use Illuminate\Foundation\Queue\Queueable;
11
12class PublishToLemmyJob implements ShouldQueue
13{
14    use Queueable;
15
16    public int $tries = 3;
17    public array $backoff = [60, 120, 300];
18
19    public function __construct(
20        private readonly Article $article
21    ) {
22        $this->onQueue('lemmy-posts');
23    }
24
25    public function handle(): void
26    {
27        $extractedData = ArticleFetcher::fetchArticleData($this->article);
28
29        /** @var ArticlePublishingService $publishingService */
30        $publishingService = resolve(ArticlePublishingService::class);
31
32        try {
33            $publishingService->publishToRoutedChannels($this->article, $extractedData);
34        } catch (PublishException $e) {
35            $this->fail($e);
36        }
37    }
38}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 19:15:34 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report/Jobs/SyncChannelPostsJob.php.html b/backend/coverage-report/Jobs/SyncChannelPostsJob.php.html deleted file mode 100644 index ba1edb48..00000000 --- a/backend/coverage-report/Jobs/SyncChannelPostsJob.php.html +++ /dev/null @@ -1,352 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Jobs/SyncChannelPostsJob.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 2.38% covered (danger) -
-
-
2.38%
1 / 42
-
- 20.00% covered (danger) -
-
-
20.00%
1 / 5
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
SyncChannelPostsJob
-
- 2.38% covered (danger) -
-
-
2.38%
1 / 42
-
- 20.00% covered (danger) -
-
-
20.00%
1 / 5
170.21
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 __construct
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
1
 dispatchForAllActiveChannels
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 9
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 handle
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 5
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
6
 syncLemmyChannelPosts
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 16
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
20
 getAuthToken
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 11
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
30
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Jobs;
4
5use App\Enums\PlatformEnum;
6use App\Exceptions\PlatformAuthException;
7use App\Models\PlatformAccount;
8use App\Models\PlatformChannel;
9use App\Modules\Lemmy\Services\LemmyApiService;
10use App\Services\Log\LogSaver;
11use Exception;
12use Illuminate\Contracts\Queue\ShouldBeUnique;
13use Illuminate\Contracts\Queue\ShouldQueue;
14use Illuminate\Database\Eloquent\Collection;
15use Illuminate\Foundation\Queue\Queueable;
16use Illuminate\Support\Facades\Cache;
17
18class SyncChannelPostsJob implements ShouldQueue, ShouldBeUnique
19{
20    use Queueable;
21
22    public function __construct(
23        private readonly PlatformChannel $channel
24    ) {
25        $this->onQueue('sync');
26    }
27
28    public static function dispatchForAllActiveChannels(): void
29    {
30        PlatformChannel::with(['platformInstance', 'platformAccounts'])
31            ->whereHas('platformInstance', fn ($query) => $query->where('platform', PlatformEnum::LEMMY))
32            ->whereHas('platformAccounts', fn ($query) => $query->where('is_active', true))
33            ->where('is_active', true)
34            ->get()
35            ->each(function (PlatformChannel $channel) {
36                self::dispatch($channel);
37                LogSaver::info('Dispatched sync job for channel', $channel);
38            });
39    }
40
41    public function handle(): void
42    {
43        LogSaver::info('Starting channel posts sync job', $this->channel);
44
45        match ($this->channel->platformInstance->platform) {
46            PlatformEnum::LEMMY => $this->syncLemmyChannelPosts(),
47        };
48
49        LogSaver::info('Channel posts sync job completed', $this->channel);
50    }
51
52    /**
53     * @throws PlatformAuthException
54     */
55    private function syncLemmyChannelPosts(): void
56    {
57        try {
58            /** @var Collection<int, PlatformAccount> $accounts */
59            $accounts = $this->channel->activePlatformAccounts()->get();
60            $account = $accounts->first();
61
62            if (! $account) {
63                throw new PlatformAuthException(PlatformEnum::LEMMY, 'No active account found for channel');
64            }
65
66            $api = new LemmyApiService($this->channel->platformInstance->url);
67            $token = $this->getAuthToken($api, $account);
68
69            $platformChannelId = $this->channel->channel_id
70                ? $this->channel->channel_id
71                : $api->getCommunityId($this->channel->name, $token);
72
73            $api->syncChannelPosts($token, $platformChannelId, $this->channel->name);
74
75            LogSaver::info('Channel posts synced successfully', $this->channel);
76
77        } catch (Exception $e) {
78            LogSaver::error('Failed to sync channel posts', $this->channel, [
79                'error' => $e->getMessage()
80            ]);
81
82            throw $e;
83        }
84    }
85
86    /**
87     * @throws PlatformAuthException
88     */
89    private function getAuthToken(LemmyApiService $api, PlatformAccount $account): string
90    {
91        $cacheKey = "lemmy_jwt_token_{$account->id}";
92        $cachedToken = Cache::get($cacheKey);
93
94        if ($cachedToken) {
95            return $cachedToken;
96        }
97
98        if (!$account->username || !$account->password) {
99            throw new PlatformAuthException(PlatformEnum::LEMMY, 'Missing credentials for account');
100        }
101
102        $token = $api->login($account->username, $account->password);
103
104        if (!$token) {
105            throw new PlatformAuthException(PlatformEnum::LEMMY, 'Login failed for account');
106        }
107
108        Cache::put($cacheKey, $token, 3600);
109
110        return $token;
111    }
112}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 19:15:34 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report/Jobs/dashboard.html b/backend/coverage-report/Jobs/dashboard.html deleted file mode 100644 index 4160c828..00000000 --- a/backend/coverage-report/Jobs/dashboard.html +++ /dev/null @@ -1,301 +0,0 @@ - - - - - Dashboard for /var/www/html/backend/app/Jobs - - - - - - - -
-
-
-
- -
-
-
-
-
-
-
-

Classes

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
-
-
-

Insufficient Coverage

- -
-
-

Project Risks

- -
-
-
-
-

Methods

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
-
-
-

Insufficient Coverage

-
- - - - - - - - - - - - - - - - -
MethodCoverage
handle0%
dispatchForAllActiveChannels0%
handle0%
syncLemmyChannelPosts0%
getAuthToken0%
handle66%
-
-
-
-

Project Risks

-
- - - - - - - - - - - - - - - -
MethodCRAP
getAuthToken30
syncLemmyChannelPosts20
handle6
handle6
handle2
-
-
-
- -
- - - - - - diff --git a/backend/coverage-report/Jobs/index.html b/backend/coverage-report/Jobs/index.html deleted file mode 100644 index dbedb461..00000000 --- a/backend/coverage-report/Jobs/index.html +++ /dev/null @@ -1,203 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Jobs - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 40.74% covered (danger) -
-
-
40.74%
33 / 81
-
- 50.00% covered (danger) -
-
-
50.00%
6 / 12
-
- 25.00% covered (danger) -
-
-
25.00%
1 / 4
ArticleDiscoveryForFeedJob.php
-
- 100.00% covered (success) -
-
-
100.00%
26 / 26
-
- 100.00% covered (success) -
-
-
100.00%
3 / 3
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
ArticleDiscoveryJob.php
-
- 71.43% covered (warning) -
-
-
71.43%
5 / 7
-
- 50.00% covered (danger) -
-
-
50.00%
1 / 2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
PublishToLemmyJob.php
-
- 16.67% covered (danger) -
-
-
16.67%
1 / 6
-
- 50.00% covered (danger) -
-
-
50.00%
1 / 2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
SyncChannelPostsJob.php
-
- 2.38% covered (danger) -
-
-
2.38%
1 / 42
-
- 20.00% covered (danger) -
-
-
20.00%
1 / 5
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- -
- - diff --git a/backend/coverage-report/Listeners/LogExceptionToDatabase.php.html b/backend/coverage-report/Listeners/LogExceptionToDatabase.php.html deleted file mode 100644 index 6fd46ff9..00000000 --- a/backend/coverage-report/Listeners/LogExceptionToDatabase.php.html +++ /dev/null @@ -1,179 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Listeners/LogExceptionToDatabase.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 12
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
LogExceptionToDatabase
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 12
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 handle
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 12
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Listeners;
4
5use App\Events\ExceptionLogged;
6use App\Events\ExceptionOccurred;
7use App\Models\Log;
8class LogExceptionToDatabase
9{
10
11    public function handle(ExceptionOccurred $event): void
12    {
13        $log = Log::create([
14            'level' => $event->level,
15            'message' => $event->message,
16            'context' => [
17                'exception_class' => get_class($event->exception),
18                'file' => $event->exception->getFile(),
19                'line' => $event->exception->getLine(),
20                'trace' => $event->exception->getTraceAsString(),
21                ...$event->context
22            ]
23        ]);
24
25        ExceptionLogged::dispatch($log);
26    }
27}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 19:15:34 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report/Listeners/PublishApprovedArticle.php.html b/backend/coverage-report/Listeners/PublishApprovedArticle.php.html deleted file mode 100644 index 9e0898b1..00000000 --- a/backend/coverage-report/Listeners/PublishApprovedArticle.php.html +++ /dev/null @@ -1,179 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Listeners/PublishApprovedArticle.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 80.00% covered (warning) -
-
-
80.00%
4 / 5
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
PublishApprovedArticle
-
- 80.00% covered (warning) -
-
-
80.00%
4 / 5
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
4.13
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 handle
-
- 80.00% covered (warning) -
-
-
80.00%
4 / 5
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
4.13
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Listeners;
4
5use App\Events\ArticleApproved;
6use App\Events\ArticleReadyToPublish;
7use Illuminate\Contracts\Queue\ShouldQueue;
8
9class PublishApprovedArticle implements ShouldQueue
10{
11    public string $queue = 'default';
12
13    public function handle(ArticleApproved $event): void
14    {
15        $article = $event->article;
16
17        // Skip if already has publication (prevents duplicate processing)
18        if ($article->articlePublication()->exists()) {
19            return;
20        }
21
22        // Only publish if the article is valid and approved
23        if ($article->isValid() && $article->isApproved()) {
24            event(new ArticleReadyToPublish($article));
25        }
26    }
27}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 19:15:34 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report/Listeners/PublishArticle.php.html b/backend/coverage-report/Listeners/PublishArticle.php.html deleted file mode 100644 index 64a150c1..00000000 --- a/backend/coverage-report/Listeners/PublishArticle.php.html +++ /dev/null @@ -1,213 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Listeners/PublishArticle.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 100.00% covered (success) -
-
-
100.00%
13 / 13
-
- 100.00% covered (success) -
-
-
100.00%
2 / 2
CRAP
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
PublishArticle
-
- 100.00% covered (success) -
-
-
100.00%
13 / 13
-
- 100.00% covered (success) -
-
-
100.00%
2 / 2
3
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
 __construct
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
1
 handle
-
- 100.00% covered (success) -
-
-
100.00%
12 / 12
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
2
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Listeners;
4
5use App\Events\ArticleReadyToPublish;
6use App\Jobs\PublishToLemmyJob;
7use Illuminate\Contracts\Queue\ShouldQueue;
8
9class PublishArticle implements ShouldQueue
10{
11    public string|null $queue = 'lemmy-publish';
12    public int $delay = 300;
13    public int $tries = 3;
14    public int $backoff = 300;
15
16    public function __construct()
17    {}
18
19    public function handle(ArticleReadyToPublish $event): void
20    {
21        $article = $event->article;
22
23        if ($article->articlePublication()->exists()) {
24            logger()->info('Article already published, skipping job dispatch', [
25                'article_id' => $article->id,
26                'url' => $article->url
27            ]);
28
29            return;
30        }
31
32        logger()->info('Article queued for publishing to Lemmy', [
33            'article_id' => $article->id,
34            'url' => $article->url
35        ]);
36
37        PublishToLemmyJob::dispatch($article);
38    }
39}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 19:15:34 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report/Listeners/ValidateArticleListener.php.html b/backend/coverage-report/Listeners/ValidateArticleListener.php.html deleted file mode 100644 index d52f2c53..00000000 --- a/backend/coverage-report/Listeners/ValidateArticleListener.php.html +++ /dev/null @@ -1,201 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Listeners/ValidateArticleListener.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 53.85% covered (warning) -
-
-
53.85%
7 / 13
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
ValidateArticleListener
-
- 53.85% covered (warning) -
-
-
53.85%
7 / 13
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
11.82
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 handle
-
- 53.85% covered (warning) -
-
-
53.85%
7 / 13
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
11.82
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Listeners;
4
5use App\Events\NewArticleFetched;
6use App\Events\ArticleReadyToPublish;
7use App\Models\Setting;
8use App\Services\Article\ValidationService;
9use Illuminate\Contracts\Queue\ShouldQueue;
10
11class ValidateArticleListener implements ShouldQueue
12{
13    public string $queue = 'default';
14
15    public function handle(NewArticleFetched $event): void
16    {
17        $article = $event->article;
18
19        if (! is_null($article->validated_at)) {
20            return;
21        }
22
23        // Skip if already has publication (prevents duplicate processing)
24        if ($article->articlePublication()->exists()) {
25            return;
26        }
27
28        $article = ValidationService::validate($article);
29
30        if ($article->isValid()) {
31            // Double-check publication doesn't exist (race condition protection)
32            if ($article->articlePublication()->exists()) {
33                return;
34            }
35
36            // Check if approval system is enabled
37            if (Setting::isPublishingApprovalsEnabled()) {
38                // If approvals are enabled, only proceed if article is approved
39                if ($article->isApproved()) {
40                    event(new ArticleReadyToPublish($article));
41                }
42                // If not approved, article will wait for manual approval
43            } else {
44                // If approvals are disabled, proceed with publishing
45                event(new ArticleReadyToPublish($article));
46            }
47        }
48    }
49}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 19:15:34 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report/Listeners/dashboard.html b/backend/coverage-report/Listeners/dashboard.html deleted file mode 100644 index 14b5fb14..00000000 --- a/backend/coverage-report/Listeners/dashboard.html +++ /dev/null @@ -1,294 +0,0 @@ - - - - - Dashboard for /var/www/html/backend/app/Listeners - - - - - - - -
-
-
-
- -
-
-
-
-
-
-
-

Classes

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
-
-
-

Insufficient Coverage

- -
-
-

Project Risks

- -
-
-
-
-

Methods

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
-
-
-

Insufficient Coverage

-
- - - - - - - - - - - - - -
MethodCoverage
handle0%
handle53%
handle80%
-
-
-
-

Project Risks

-
- - - - - - - - - - - - -
MethodCRAP
handle11
handle4
-
-
-
- -
- - - - - - diff --git a/backend/coverage-report/Listeners/index.html b/backend/coverage-report/Listeners/index.html deleted file mode 100644 index 15f069f3..00000000 --- a/backend/coverage-report/Listeners/index.html +++ /dev/null @@ -1,203 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Listeners - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 55.81% covered (warning) -
-
-
55.81%
24 / 43
-
- 40.00% covered (danger) -
-
-
40.00%
2 / 5
-
- 25.00% covered (danger) -
-
-
25.00%
1 / 4
LogExceptionToDatabase.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 12
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
PublishApprovedArticle.php
-
- 80.00% covered (warning) -
-
-
80.00%
4 / 5
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
PublishArticle.php
-
- 100.00% covered (success) -
-
-
100.00%
13 / 13
-
- 100.00% covered (success) -
-
-
100.00%
2 / 2
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
ValidateArticleListener.php
-
- 53.85% covered (warning) -
-
-
53.85%
7 / 13
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- -
- - diff --git a/backend/coverage-report/LogLevelEnum.php.html b/backend/coverage-report/LogLevelEnum.php.html deleted file mode 100644 index e37ef500..00000000 --- a/backend/coverage-report/LogLevelEnum.php.html +++ /dev/null @@ -1,177 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/LogLevelEnum.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 100.00% covered (success) -
-
-
100.00%
7 / 7
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
CRAP
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
LogLevelEnum
-
- 100.00% covered (success) -
-
-
100.00%
7 / 7
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
1
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
 toArray
-
- 100.00% covered (success) -
-
-
100.00%
7 / 7
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
1
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App;
4
5enum LogLevelEnum: string
6{
7    case DEBUG = 'debug';
8    case INFO = 'info';
9    case WARNING = 'warning';
10    case ERROR = 'error';
11    case CRITICAL = 'critical';
12
13    /**
14     * @return array<int, string>
15     */
16    public static function toArray(): array
17    {
18        return [
19            self::DEBUG->value,
20            self::INFO->value,
21            self::WARNING->value,
22            self::ERROR->value,
23            self::CRITICAL->value,
24        ];
25    }
26}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 19:15:34 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report/Models/Article.php.html b/backend/coverage-report/Models/Article.php.html deleted file mode 100644 index 1a970958..00000000 --- a/backend/coverage-report/Models/Article.php.html +++ /dev/null @@ -1,522 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Models/Article.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 100.00% covered (success) -
-
-
100.00%
39 / 39
-
- 100.00% covered (success) -
-
-
100.00%
11 / 11
CRAP
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
Article
-
- 100.00% covered (success) -
-
-
100.00%
39 / 39
-
- 100.00% covered (success) -
-
-
100.00%
11 / 11
15
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
 casts
-
- 100.00% covered (success) -
-
-
100.00%
10 / 10
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
1
 isValid
-
- 100.00% covered (success) -
-
-
100.00%
5 / 5
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
3
 isApproved
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
1
 isPending
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
1
 isRejected
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
1
 approve
-
- 100.00% covered (success) -
-
-
100.00%
6 / 6
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
1
 reject
-
- 100.00% covered (success) -
-
-
100.00%
5 / 5
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
1
 canBePublished
-
- 100.00% covered (success) -
-
-
100.00%
5 / 5
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
3
 articlePublication
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
1
 feed
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
1
 booted
-
- 100.00% covered (success) -
-
-
100.00%
3 / 3
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
1
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Models;
4
5use App\Events\ArticleApproved;
6use App\Events\NewArticleFetched;
7use Database\Factories\ArticleFactory;
8use Illuminate\Database\Eloquent\Factories\HasFactory;
9use Illuminate\Database\Eloquent\Model;
10use Illuminate\Database\Eloquent\Relations\BelongsTo;
11use Illuminate\Database\Eloquent\Relations\HasOne;
12use Illuminate\Support\Carbon;
13
14/**
15 * @method static firstOrCreate(array<string, mixed> $array)
16 * @method static where(string $string, string $url)
17 * @method static create(array<string, mixed> $array)
18 * @property integer $id
19 * @property int $feed_id
20 * @property Feed $feed
21 * @property string $url
22 * @property bool|null $is_valid
23 * @property Carbon|null $validated_at
24 * @property Carbon $created_at
25 * @property Carbon $updated_at
26 * @property ArticlePublication $articlePublication
27 */
28class Article extends Model
29{
30    /** @use HasFactory<ArticleFactory> */
31    use HasFactory;
32
33    protected $fillable = [
34        'feed_id',
35        'url',
36        'title',
37        'description',
38        'is_valid',
39        'is_duplicate',
40        'approval_status',
41        'approved_at',
42        'approved_by',
43        'fetched_at',
44        'validated_at',
45    ];
46
47    /**
48     * @return array<string, string>
49     */
50    public function casts(): array
51    {
52        return [
53            'is_valid' => 'boolean',
54            'is_duplicate' => 'boolean',
55            'approval_status' => 'string',
56            'approved_at' => 'datetime',
57            'fetched_at' => 'datetime',
58            'validated_at' => 'datetime',
59            'created_at' => 'datetime',
60            'updated_at' => 'datetime',
61        ];
62    }
63
64    public function isValid(): bool
65    {
66        if (is_null($this->validated_at)) {
67            return false;
68        }
69
70        if (is_null($this->is_valid)) {
71            return false;
72        }
73
74        return $this->is_valid;
75    }
76
77    public function isApproved(): bool
78    {
79        return $this->approval_status === 'approved';
80    }
81
82    public function isPending(): bool
83    {
84        return $this->approval_status === 'pending';
85    }
86
87    public function isRejected(): bool
88    {
89        return $this->approval_status === 'rejected';
90    }
91
92    public function approve(string $approvedBy = null): void
93    {
94        $this->update([
95            'approval_status' => 'approved',
96            'approved_at' => now(),
97            'approved_by' => $approvedBy,
98        ]);
99
100        // Fire event to trigger publishing
101        event(new ArticleApproved($this));
102    }
103
104    public function reject(string $rejectedBy = null): void
105    {
106        $this->update([
107            'approval_status' => 'rejected',
108            'approved_at' => now(),
109            'approved_by' => $rejectedBy,
110        ]);
111    }
112
113    public function canBePublished(): bool
114    {
115        if (!$this->isValid()) {
116            return false;
117        }
118
119        // If approval system is disabled, auto-approve valid articles
120        if (!\App\Models\Setting::isPublishingApprovalsEnabled()) {
121            return true;
122        }
123
124        // If approval system is enabled, only approved articles can be published
125        return $this->isApproved();
126    }
127
128    /**
129     * @return HasOne<ArticlePublication, $this>
130     */
131    public function articlePublication(): HasOne
132    {
133        return $this->hasOne(ArticlePublication::class);
134    }
135
136    /**
137     * @return BelongsTo<Feed, $this>
138     */
139    public function feed(): BelongsTo
140    {
141        return $this->belongsTo(Feed::class);
142    }
143
144    protected static function booted(): void
145    {
146        static::created(function ($article) {
147            event(new NewArticleFetched($article));
148        });
149    }
150}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 19:15:34 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report/Models/ArticlePublication.php.html b/backend/coverage-report/Models/ArticlePublication.php.html deleted file mode 100644 index 8499f972..00000000 --- a/backend/coverage-report/Models/ArticlePublication.php.html +++ /dev/null @@ -1,196 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Models/ArticlePublication.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
CRAP
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
ArticlePublication
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
1
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
 article
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
1
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Models;
4
5use Database\Factories\ArticlePublicationFactory;
6use Illuminate\Database\Eloquent\Factories\HasFactory;
7use Illuminate\Database\Eloquent\Model;
8use Illuminate\Database\Eloquent\Relations\BelongsTo;
9
10/**
11 * @property integer $article_id
12 * @property integer $platform_channel_id
13 * @property integer $post_id
14 *
15 * @method static create(array<string, mixed> $array)
16 */
17class ArticlePublication extends Model
18{
19    /** @use HasFactory<ArticlePublicationFactory> */
20    use HasFactory;
21    
22    protected $fillable = [
23        'article_id',
24        'platform_channel_id',
25        'post_id',
26        'published_at',
27        'published_by',
28        'platform',
29        'publication_data',
30    ];
31
32    protected $casts = [
33        'published_at' => 'datetime',
34        'publication_data' => 'array',
35    ];
36
37    /**
38     * @return BelongsTo<Article, $this>
39     */
40    public function article(): BelongsTo
41    {
42        return $this->belongsTo(Article::class);
43    }
44}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 19:15:34 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report/Models/Feed.php.html b/backend/coverage-report/Models/Feed.php.html deleted file mode 100644 index bedfcc72..00000000 --- a/backend/coverage-report/Models/Feed.php.html +++ /dev/null @@ -1,382 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Models/Feed.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 8.33% covered (danger) -
-
-
8.33%
2 / 24
-
- 33.33% covered (danger) -
-
-
33.33%
2 / 6
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
Feed
-
- 8.33% covered (danger) -
-
-
8.33%
2 / 24
-
- 33.33% covered (danger) -
-
-
33.33%
2 / 6
143.17
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 getTypeDisplayAttribute
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 5
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
20
 getStatusAttribute
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 10
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
30
 channels
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 4
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 activeChannels
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 articles
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
1
 language
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
1
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Models;
4
5use Database\Factories\FeedFactory;
6use Illuminate\Database\Eloquent\Factories\HasFactory;
7use Illuminate\Database\Eloquent\Model;
8use Illuminate\Database\Eloquent\Relations\BelongsTo;
9use Illuminate\Database\Eloquent\Relations\BelongsToMany;
10use Illuminate\Database\Eloquent\Relations\HasMany;
11use Illuminate\Support\Carbon;
12
13/**
14 * @property int $id
15 * @property string $name
16 * @property string $url
17 * @property string $type
18 * @property int $language_id
19 * @property Language|null $language
20 * @property string $description
21 * @property array<string, mixed> $settings
22 * @property bool $is_active
23 * @property Carbon|null $last_fetched_at
24 * @property Carbon $created_at
25 * @property Carbon $updated_at
26 * @method static orderBy(string $string, string $string1)
27 * @method static where(string $string, true $true)
28 * @method static findOrFail(mixed $feed_id)
29 */
30class Feed extends Model
31{
32    /** @use HasFactory<FeedFactory> */
33    use HasFactory;
34    private const RECENT_FETCH_THRESHOLD_HOURS = 2;
35    private const DAILY_FETCH_THRESHOLD_HOURS = 24;
36
37    protected $fillable = [
38        'name',
39        'url',
40        'type',
41        'language_id',
42        'description',
43        'settings',
44        'is_active',
45        'last_fetched_at'
46    ];
47
48    protected $casts = [
49        'settings' => 'array',
50        'is_active' => 'boolean',
51        'last_fetched_at' => 'datetime'
52    ];
53
54    public function getTypeDisplayAttribute(): string
55    {
56        return match ($this->type) {
57            'website' => 'Website',
58            'rss' => 'RSS Feed',
59            default => 'Unknown'
60        };
61    }
62
63    public function getStatusAttribute(): string
64    {
65        if (!$this->is_active) {
66            return 'Inactive';
67        }
68
69        if (!$this->last_fetched_at) {
70            return 'Never fetched';
71        }
72
73        $hoursAgo = $this->last_fetched_at->diffInHours(now());
74
75        if ($hoursAgo < self::RECENT_FETCH_THRESHOLD_HOURS) {
76            return 'Recently fetched';
77        } elseif ($hoursAgo < self::DAILY_FETCH_THRESHOLD_HOURS) {
78            return "Fetched {$hoursAgo}h ago";
79        } else {
80            return "Fetched " . $this->last_fetched_at->diffForHumans();
81        }
82    }
83
84    /**
85     * @return BelongsToMany<PlatformChannel, $this, Route>
86     */
87    public function channels(): BelongsToMany
88    {
89        return $this->belongsToMany(PlatformChannel::class, 'routes')
90            ->using(Route::class)
91            ->withPivot(['is_active', 'priority', 'filters'])
92            ->withTimestamps();
93    }
94
95    /**
96     * @return BelongsToMany<PlatformChannel, $this, Route>
97     */
98    public function activeChannels(): BelongsToMany
99    {
100        return $this->channels()
101            ->wherePivot('is_active', true)
102            ->orderByPivot('priority', 'desc');
103    }
104
105    /**
106     * @return HasMany<Article, $this>
107     */
108    public function articles(): HasMany
109    {
110        return $this->hasMany(Article::class);
111    }
112
113    /**
114     * @return BelongsTo<Language, $this>
115     */
116    public function language(): BelongsTo
117    {
118        return $this->belongsTo(Language::class);
119    }
120}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 19:15:34 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report/Models/Keyword.php.html b/backend/coverage-report/Models/Keyword.php.html deleted file mode 100644 index 8e5f5371..00000000 --- a/backend/coverage-report/Models/Keyword.php.html +++ /dev/null @@ -1,223 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Models/Keyword.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
Keyword
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
6
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 feed
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 platformChannel
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Models;
4
5use Illuminate\Database\Eloquent\Model;
6use Illuminate\Database\Eloquent\Relations\BelongsTo;
7use Illuminate\Support\Carbon;
8
9/**
10 * @property int $id
11 * @property int $feed_id
12 * @property Feed $feed
13 * @property int $platform_channel_id
14 * @property PlatformChannel $platformChannel
15 * @property string $keyword
16 * @property bool $is_active
17 * @property Carbon $created_at
18 * @property Carbon $updated_at
19 */
20class Keyword extends Model
21{
22    protected $fillable = [
23        'feed_id',
24        'platform_channel_id',
25        'keyword',
26        'is_active'
27    ];
28
29    protected $casts = [
30        'is_active' => 'boolean'
31    ];
32
33    /**
34     * @return BelongsTo<Feed, $this>
35     */
36    public function feed(): BelongsTo
37    {
38        return $this->belongsTo(Feed::class);
39    }
40
41    /**
42     * @return BelongsTo<PlatformChannel, $this>
43     */
44    public function platformChannel(): BelongsTo
45    {
46        return $this->belongsTo(PlatformChannel::class);
47    }
48
49}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 19:15:34 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report/Models/Language.php.html b/backend/coverage-report/Models/Language.php.html deleted file mode 100644 index 3d09e113..00000000 --- a/backend/coverage-report/Models/Language.php.html +++ /dev/null @@ -1,248 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Models/Language.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 60.00% covered (warning) -
-
-
60.00%
3 / 5
-
- 33.33% covered (danger) -
-
-
33.33%
1 / 3
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
Language
-
- 60.00% covered (warning) -
-
-
60.00%
3 / 5
-
- 33.33% covered (danger) -
-
-
33.33%
1 / 3
3.58
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 platformInstances
-
- 100.00% covered (success) -
-
-
100.00%
3 / 3
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
1
 platformChannels
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 feeds
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Models;
4
5use Database\Factories\LanguageFactory;
6use Illuminate\Database\Eloquent\Factories\HasFactory;
7use Illuminate\Database\Eloquent\Model;
8use Illuminate\Database\Eloquent\Relations\BelongsToMany;
9use Illuminate\Database\Eloquent\Relations\HasMany;
10
11class Language extends Model
12{
13    /** @use HasFactory<LanguageFactory> */
14    use HasFactory;
15
16    protected $fillable = [
17        'short_code',
18        'name', 
19        'native_name',
20        'is_active'
21    ];
22
23    protected $casts = [
24        'is_active' => 'boolean'
25    ];
26
27    /**
28     * @return BelongsToMany<PlatformInstance, $this>
29     */
30    public function platformInstances(): BelongsToMany
31    {
32        return $this->belongsToMany(PlatformInstance::class)
33            ->withPivot(['platform_language_id', 'is_default'])
34            ->withTimestamps();
35    }
36
37    /**
38     * @return HasMany<PlatformChannel, $this>
39     */
40    public function platformChannels(): HasMany
41    {
42        return $this->hasMany(PlatformChannel::class);
43    }
44
45    /**
46     * @return HasMany<Feed, $this>
47     */
48    public function feeds(): HasMany
49    {
50        return $this->hasMany(Feed::class);
51    }
52}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 19:15:34 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report/Models/Log.php.html b/backend/coverage-report/Models/Log.php.html deleted file mode 100644 index 19071efc..00000000 --- a/backend/coverage-report/Models/Log.php.html +++ /dev/null @@ -1,136 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Models/Log.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
n/a
0 / 0
n/a
0 / 0
CRAP
n/a
0 / 0
Log
n/a
0 / 0
n/a
0 / 0
0
n/a
0 / 0
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Models;
4
5use App\LogLevelEnum;
6use Illuminate\Database\Eloquent\Factories\HasFactory;
7use Illuminate\Database\Eloquent\Model;
8use Illuminate\Support\Carbon;
9
10/**
11 * @method static create(array $array)
12 * @property LogLevelEnum $level
13 * @property string $message
14 * @property array<string, mixed> $context
15 * @property Carbon $created_at
16 * @property Carbon $updated_at
17 */
18class Log extends Model
19{
20    use HasFactory;
21
22    protected $table = 'logs';
23
24    protected $fillable = [
25        'level',
26        'message',
27        'context',
28    ];
29
30    protected $casts = [
31        'level' => LogLevelEnum::class,
32        'context' => 'array',
33        'created_at' => 'datetime',
34        'updated_at' => 'datetime',
35    ];
36}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 19:15:34 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report/Models/PlatformAccount.php.html b/backend/coverage-report/Models/PlatformAccount.php.html deleted file mode 100644 index d8f41a14..00000000 --- a/backend/coverage-report/Models/PlatformAccount.php.html +++ /dev/null @@ -1,384 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Models/PlatformAccount.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 21
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 6
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
PlatformAccount
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 21
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 6
110
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 password
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 4
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
12
 apiToken
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 4
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
12
 getActive
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 setAsActive
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 4
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 channels
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 activeChannels
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Models;
4
5use Database\Factories\PlatformAccountFactory;
6use Illuminate\Database\Eloquent\Factories\HasFactory;
7use Illuminate\Database\Eloquent\Model;
8use Illuminate\Database\Eloquent\Casts\Attribute;
9use Illuminate\Database\Eloquent\Collection;
10use Illuminate\Database\Eloquent\Relations\BelongsToMany;
11use Illuminate\Support\Carbon;
12use Illuminate\Support\Facades\Crypt;
13use App\Enums\PlatformEnum;
14
15/**
16 * @property int $id
17 * @property PlatformEnum $platform
18 * @property string $instance_url
19 * @property string $username
20 * @property string $password
21 * @property string $settings
22 * @property bool $is_active
23 * @property Carbon $last_tested_at
24 * @property string $status
25 * @property Carbon $created_at
26 * @property Carbon $updated_at
27 * @property Collection<int, PlatformChannel> $activeChannels
28 * @method static where(string $string, PlatformEnum $platform)
29 * @method static orderBy(string $string)
30 * @method static create(array<string, mixed> $validated)
31 */
32class PlatformAccount extends Model
33{
34    /** @use HasFactory<PlatformAccountFactory> */
35    use HasFactory;
36
37    protected $fillable = [
38        'platform',
39        'instance_url',
40        'username',
41        'password',
42        'api_token',
43        'settings',
44        'is_active',
45        'last_tested_at',
46        'status'
47    ];
48
49    protected $casts = [
50        'platform' => PlatformEnum::class,
51        'settings' => 'array',
52        'is_active' => 'boolean',
53        'last_tested_at' => 'datetime'
54    ];
55
56    // Encrypt password when storing
57    /**
58     * @return Attribute<string|null, string|null>
59     */
60    protected function password(): Attribute
61    {
62        return Attribute::make(
63            get: fn ($value) => $value ? Crypt::decryptString($value) : null,
64            set: fn ($value) => $value ? Crypt::encryptString($value) : null,
65        );
66    }
67
68    // Encrypt API token when storing
69    /**
70     * @return Attribute<string|null, string|null>
71     */
72    protected function apiToken(): Attribute
73    {
74        return Attribute::make(
75            get: fn ($value) => $value ? Crypt::decryptString($value) : null,
76            set: fn ($value) => $value ? Crypt::encryptString($value) : null,
77        );
78    }
79
80    // Get the active accounts for a platform (returns collection)
81    /**
82     * @return Collection<int, PlatformAccount>
83     */
84    public static function getActive(PlatformEnum $platform): Collection
85    {
86        return static::where('platform', $platform)
87            ->where('is_active', true)
88            ->get();
89    }
90
91    // Set this account as active (deactivates others for same platform)
92    public function setAsActive(): void
93    {
94        // Deactivate other accounts for this platform
95        static::where('platform', $this->platform)
96            ->where('id', '!=', $this->id)
97            ->update(['is_active' => false]);
98
99        // Activate this account
100        $this->update(['is_active' => true]);
101    }
102
103    /**
104     * @return BelongsToMany<PlatformChannel, $this>
105     */
106    public function channels(): BelongsToMany
107    {
108        return $this->belongsToMany(PlatformChannel::class, 'platform_account_channels')
109            ->withPivot(['is_active', 'priority'])
110            ->withTimestamps();
111    }
112
113    /**
114     * @return BelongsToMany<PlatformChannel, $this>
115     */
116    public function activeChannels(): BelongsToMany
117    {
118        return $this->channels()
119            ->wherePivot('is_active', true)
120            ->orderByPivot('priority', 'desc');
121    }
122}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 19:15:34 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report/Models/PlatformChannel.php.html b/backend/coverage-report/Models/PlatformChannel.php.html deleted file mode 100644 index 8578d20d..00000000 --- a/backend/coverage-report/Models/PlatformChannel.php.html +++ /dev/null @@ -1,387 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Models/PlatformChannel.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 14
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 7
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
PlatformChannel
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 14
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 7
56
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 platformInstance
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 platformAccounts
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 activePlatformAccounts
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 getFullNameAttribute
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 feeds
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 4
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 activeFeeds
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 language
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Models;
4
5use Database\Factories\PlatformChannelFactory;
6use Illuminate\Database\Eloquent\Factories\HasFactory;
7use Illuminate\Database\Eloquent\Model;
8use Illuminate\Database\Eloquent\Relations\BelongsTo;
9use Illuminate\Database\Eloquent\Relations\BelongsToMany;
10
11/**
12 * @method static findMany(mixed $channel_ids)
13 * @property integer $id
14 * @property integer $platform_instance_id
15 * @property PlatformInstance $platformInstance
16 * @property integer $channel_id
17 * @property string $name
18 * @property int $language_id
19 * @property Language|null $language
20 * @property boolean $is_active
21 */
22class PlatformChannel extends Model
23{
24    /** @use HasFactory<PlatformChannelFactory> */
25    use HasFactory;
26
27    protected $table = 'platform_channels';
28
29    protected $fillable = [
30        'platform_instance_id',
31        'name',
32        'display_name',
33        'channel_id',
34        'description',
35        'language_id',
36        'is_active'
37    ];
38
39    protected $casts = [
40        'is_active' => 'boolean'
41    ];
42
43    /**
44     * @return BelongsTo<PlatformInstance, $this>
45     */
46    public function platformInstance(): BelongsTo
47    {
48        return $this->belongsTo(PlatformInstance::class);
49    }
50
51    /**
52     * @return BelongsToMany<PlatformAccount, $this>
53     */
54    public function platformAccounts(): BelongsToMany
55    {
56        return $this->belongsToMany(PlatformAccount::class, 'platform_account_channels')
57            ->withPivot(['is_active', 'priority'])
58            ->withTimestamps();
59    }
60
61    /**
62     * @return BelongsToMany<PlatformAccount, $this>
63     */
64    public function activePlatformAccounts(): BelongsToMany
65    {
66        return $this->platformAccounts()->wherePivot('is_active', true);
67    }
68
69    public function getFullNameAttribute(): string
70    {
71        // For Lemmy, use /c/ prefix
72        return $this->platformInstance->url . '/c/' . $this->name;
73    }
74
75    /**
76     * @return BelongsToMany<Feed, $this, Route>
77     */
78    public function feeds(): BelongsToMany
79    {
80        return $this->belongsToMany(Feed::class, 'routes')
81            ->using(Route::class)
82            ->withPivot(['is_active', 'priority', 'filters'])
83            ->withTimestamps();
84    }
85
86    /**
87     * @return BelongsToMany<Feed, $this, Route>
88     */
89    public function activeFeeds(): BelongsToMany
90    {
91        return $this->feeds()
92            ->wherePivot('is_active', true)
93            ->orderByPivot('priority', 'desc');
94    }
95
96    /**
97     * @return BelongsTo<Language, $this>
98     */
99    public function language(): BelongsTo
100    {
101        return $this->belongsTo(Language::class);
102    }
103}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 19:15:34 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report/Models/PlatformChannelPost.php.html b/backend/coverage-report/Models/PlatformChannelPost.php.html deleted file mode 100644 index b6f644ef..00000000 --- a/backend/coverage-report/Models/PlatformChannelPost.php.html +++ /dev/null @@ -1,255 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Models/PlatformChannelPost.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 21
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
PlatformChannelPost
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 21
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
12
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 casts
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 4
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 urlExists
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 4
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 storePost
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 13
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Models;
4
5use App\Enums\PlatformEnum;
6use Illuminate\Database\Eloquent\Model;
7
8/**
9 * @method static where(string $string, PlatformEnum $platform)
10 * @method static updateOrCreate(array<string, mixed> $array, array<string, mixed> $array1)
11 */
12class PlatformChannelPost extends Model
13{
14    protected $fillable = [
15        'platform',
16        'channel_id',
17        'channel_name',
18        'post_id',
19        'url',
20        'title',
21        'posted_at',
22    ];
23
24    /**
25     * @return array<string, string>
26     */
27    protected function casts(): array
28    {
29        return [
30            'posted_at' => 'datetime',
31            'platform' => PlatformEnum::class,
32        ];
33    }
34
35    public static function urlExists(PlatformEnum $platform, string $channelId, string $url): bool
36    {
37        return self::where('platform', $platform)
38            ->where('channel_id', $channelId)
39            ->where('url', $url)
40            ->exists();
41    }
42
43    public static function storePost(PlatformEnum $platform, string $channelId, ?string $channelName, string $postId, ?string $url, ?string $title, ?\DateTime $postedAt = null): self
44    {
45        return self::updateOrCreate(
46            [
47                'platform' => $platform,
48                'channel_id' => $channelId,
49                'post_id' => $postId,
50            ],
51            [
52                'channel_name' => $channelName,
53                'url' => $url,
54                'title' => $title,
55                'posted_at' => $postedAt ?? now(),
56            ]
57        );
58    }
59}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 19:15:34 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report/Models/PlatformInstance.php.html b/backend/coverage-report/Models/PlatformInstance.php.html deleted file mode 100644 index 57c37998..00000000 --- a/backend/coverage-report/Models/PlatformInstance.php.html +++ /dev/null @@ -1,259 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Models/PlatformInstance.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 7
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
PlatformInstance
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 7
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
12
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 channels
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 languages
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 findByUrl
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Models;
4
5use App\Enums\PlatformEnum;
6use Database\Factories\PlatformInstanceFactory;
7use Illuminate\Database\Eloquent\Factories\HasFactory;
8use Illuminate\Database\Eloquent\Model;
9use Illuminate\Database\Eloquent\Relations\BelongsToMany;
10use Illuminate\Database\Eloquent\Relations\HasMany;
11
12/**
13 * @method static updateOrCreate(array<string, mixed> $array, $instanceData)
14 * @method static where(string $string, mixed $operator)
15 * @property PlatformEnum $platform
16 * @property string $url
17 * @property string $name
18 * @property string $description
19 * @property boolean $is_active
20 */
21class PlatformInstance extends Model
22{
23    /** @use HasFactory<PlatformInstanceFactory> */
24    use HasFactory;
25    
26    protected $fillable = [
27        'platform',
28        'url',
29        'name',
30        'description',
31        'is_active'
32    ];
33
34    protected $casts = [
35        'platform' => PlatformEnum::class,
36        'is_active' => 'boolean'
37    ];
38
39    /**
40     * @return HasMany<PlatformChannel, $this>
41     */
42    public function channels(): HasMany
43    {
44        return $this->hasMany(PlatformChannel::class);
45    }
46
47    /**
48     * @return BelongsToMany<Language, $this>
49     */
50    public function languages(): BelongsToMany
51    {
52        return $this->belongsToMany(Language::class)
53            ->withPivot(['platform_language_id', 'is_default'])
54            ->withTimestamps();
55    }
56
57    public static function findByUrl(PlatformEnum $platform, string $url): ?self
58    {
59        return static::where('platform', $platform)
60            ->where('url', $url)
61            ->first();
62    }
63}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 19:15:34 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report/Models/Route.php.html b/backend/coverage-report/Models/Route.php.html deleted file mode 100644 index 2df2c673..00000000 --- a/backend/coverage-report/Models/Route.php.html +++ /dev/null @@ -1,263 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Models/Route.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 50.00% covered (danger) -
-
-
50.00%
2 / 4
-
- 66.67% covered (warning) -
-
-
66.67%
2 / 3
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
Route
-
- 50.00% covered (danger) -
-
-
50.00%
2 / 4
-
- 66.67% covered (warning) -
-
-
66.67%
2 / 3
4.12
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 feed
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
1
 platformChannel
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
1
 keywords
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Models;
4
5use Database\Factories\RouteFactory;
6use Illuminate\Database\Eloquent\Factories\HasFactory;
7use Illuminate\Database\Eloquent\Relations\BelongsTo;
8use Illuminate\Database\Eloquent\Relations\HasMany;
9use Illuminate\Database\Eloquent\Relations\Pivot;
10use Illuminate\Support\Carbon;
11
12/**
13 * @property int $feed_id
14 * @property int $platform_channel_id
15 * @property bool $is_active
16 * @property int $priority
17 * @property array<string, mixed> $filters
18 * @property Carbon $created_at
19 * @property Carbon $updated_at
20 */
21class Route extends Pivot
22{
23    /** @use HasFactory<RouteFactory> */
24    use HasFactory;
25    
26    protected $table = 'routes';
27
28    public $incrementing = false;
29
30    protected $fillable = [
31        'feed_id',
32        'platform_channel_id',
33        'is_active',
34        'priority',
35        'filters'
36    ];
37
38    protected $casts = [
39        'is_active' => 'boolean',
40        'filters' => 'array'
41    ];
42
43    /**
44     * @return BelongsTo<Feed, $this>
45     */
46    public function feed(): BelongsTo
47    {
48        return $this->belongsTo(Feed::class);
49    }
50
51    /**
52     * @return BelongsTo<PlatformChannel, $this>
53     */
54    public function platformChannel(): BelongsTo
55    {
56        return $this->belongsTo(PlatformChannel::class);
57    }
58
59    /**
60     * @return HasMany<Keyword, $this>
61     */
62    public function keywords(): HasMany
63    {
64        return $this->hasMany(Keyword::class, 'feed_id', 'feed_id')
65            ->where('platform_channel_id', $this->platform_channel_id);
66    }
67}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 19:15:34 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report/Models/Setting.php.html b/backend/coverage-report/Models/Setting.php.html deleted file mode 100644 index 7b7a02db..00000000 --- a/backend/coverage-report/Models/Setting.php.html +++ /dev/null @@ -1,360 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Models/Setting.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 100.00% covered (success) -
-
-
100.00%
10 / 10
-
- 100.00% covered (success) -
-
-
100.00%
8 / 8
CRAP
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
Setting
-
- 100.00% covered (success) -
-
-
100.00%
10 / 10
-
- 100.00% covered (success) -
-
-
100.00%
8 / 8
10
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
 get
-
- 100.00% covered (success) -
-
-
100.00%
2 / 2
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
2
 set
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
1
 getBool
-
- 100.00% covered (success) -
-
-
100.00%
2 / 2
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
1
 setBool
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
2
 isArticleProcessingEnabled
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
1
 setArticleProcessingEnabled
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
1
 isPublishingApprovalsEnabled
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
1
 setPublishingApprovalsEnabled
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
1
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Models;
4
5use Illuminate\Database\Eloquent\Model;
6
7class Setting extends Model
8{
9    protected $fillable = ['key', 'value'];
10
11    public static function get(string $key, mixed $default = null): mixed
12    {
13        $setting = static::where('key', $key)->first();
14        
15        return $setting ? $setting->value : $default;
16    }
17
18    public static function set(string $key, mixed $value): void
19    {
20        static::updateOrCreate(['key' => $key], ['value' => $value]);
21    }
22
23    public static function getBool(string $key, bool $default = false): bool
24    {
25        $value = static::get($key, $default);
26        
27        return filter_var($value, FILTER_VALIDATE_BOOLEAN);
28    }
29
30    public static function setBool(string $key, bool $value): void
31    {
32        static::set($key, $value ? '1' : '0');
33    }
34
35    public static function isArticleProcessingEnabled(): bool
36    {
37        return static::getBool('article_processing_enabled', true);
38    }
39
40    public static function setArticleProcessingEnabled(bool $enabled): void
41    {
42        static::setBool('article_processing_enabled', $enabled);
43    }
44
45    public static function isPublishingApprovalsEnabled(): bool
46    {
47        return static::getBool('enable_publishing_approvals', false);
48    }
49
50    public static function setPublishingApprovalsEnabled(bool $enabled): void
51    {
52        static::setBool('enable_publishing_approvals', $enabled);
53    }
54}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 19:15:34 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report/Models/User.php.html b/backend/coverage-report/Models/User.php.html deleted file mode 100644 index 371f0398..00000000 --- a/backend/coverage-report/Models/User.php.html +++ /dev/null @@ -1,201 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Models/User.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 100.00% covered (success) -
-
-
100.00%
4 / 4
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
CRAP
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
User
-
- 100.00% covered (success) -
-
-
100.00%
4 / 4
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
1
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
 casts
-
- 100.00% covered (success) -
-
-
100.00%
4 / 4
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
1
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Models;
4
5// use Illuminate\Contracts\Auth\MustVerifyEmail;
6use Illuminate\Database\Eloquent\Factories\HasFactory;
7use Illuminate\Foundation\Auth\User as Authenticatable;
8use Illuminate\Notifications\Notifiable;
9use Laravel\Sanctum\HasApiTokens;
10
11class User extends Authenticatable
12{
13    /** @use HasFactory<\Database\Factories\UserFactory> */
14    use HasFactory, Notifiable, HasApiTokens;
15
16    /**
17     * The attributes that are mass assignable.
18     *
19     * @var list<string>
20     */
21    protected $fillable = [
22        'name',
23        'email',
24        'password',
25    ];
26
27    /**
28     * The attributes that should be hidden for serialization.
29     *
30     * @var list<string>
31     */
32    protected $hidden = [
33        'password',
34        'remember_token',
35    ];
36
37    /**
38     * Get the attributes that should be cast.
39     *
40     * @return array<string, string>
41     */
42    protected function casts(): array
43    {
44        return [
45            'email_verified_at' => 'datetime',
46            'password' => 'hashed',
47        ];
48    }
49}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 19:15:34 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report/Models/dashboard.html b/backend/coverage-report/Models/dashboard.html deleted file mode 100644 index 194c4daa..00000000 --- a/backend/coverage-report/Models/dashboard.html +++ /dev/null @@ -1,326 +0,0 @@ - - - - - Dashboard for /var/www/html/backend/app/Models - - - - - - - -
-
-
-
- -
-
-
-
-
-
-
-

Classes

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
-
- -
-

Project Risks

-
- - - - - - - - - - - - -
ClassCRAP
App\Models\Feed143
App\Models\PlatformAccount110
-
-
-
-
-
-

Methods

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
-
- -
-

Project Risks

-
- - - - - - - - - - - - - - -
MethodCRAP
getStatusAttribute30
getTypeDisplayAttribute20
password12
apiToken12
-
-
-
- -
- - - - - - diff --git a/backend/coverage-report/Models/index.html b/backend/coverage-report/Models/index.html deleted file mode 100644 index e798fd90..00000000 --- a/backend/coverage-report/Models/index.html +++ /dev/null @@ -1,440 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Models - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 40.13% covered (danger) -
-
-
40.13%
61 / 152
-
- 48.15% covered (danger) -
-
-
48.15%
26 / 54
-
- 33.33% covered (danger) -
-
-
33.33%
4 / 12
Article.php
-
- 100.00% covered (success) -
-
-
100.00%
39 / 39
-
- 100.00% covered (success) -
-
-
100.00%
11 / 11
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
ArticlePublication.php
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
Feed.php
-
- 8.33% covered (danger) -
-
-
8.33%
2 / 24
-
- 33.33% covered (danger) -
-
-
33.33%
2 / 6
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
Keyword.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
Language.php
-
- 60.00% covered (warning) -
-
-
60.00%
3 / 5
-
- 33.33% covered (danger) -
-
-
33.33%
1 / 3
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
Log.php
n/a
0 / 0
n/a
0 / 0
n/a
0 / 0
PlatformAccount.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 21
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 6
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
PlatformChannel.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 14
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 7
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
PlatformChannelPost.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 21
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
PlatformInstance.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 7
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
Route.php
-
- 50.00% covered (danger) -
-
-
50.00%
2 / 4
-
- 66.67% covered (warning) -
-
-
66.67%
2 / 3
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
Setting.php
-
- 100.00% covered (success) -
-
-
100.00%
10 / 10
-
- 100.00% covered (success) -
-
-
100.00%
8 / 8
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
User.php
-
- 100.00% covered (success) -
-
-
100.00%
4 / 4
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
-
- -
- - diff --git a/backend/coverage-report/Modules/Lemmy/LemmyRequest.php.html b/backend/coverage-report/Modules/Lemmy/LemmyRequest.php.html deleted file mode 100644 index 374289a3..00000000 --- a/backend/coverage-report/Modules/Lemmy/LemmyRequest.php.html +++ /dev/null @@ -1,275 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Modules/Lemmy/LemmyRequest.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 14
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 4
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
LemmyRequest
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 14
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 4
42
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 __construct
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 get
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 5
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
6
 post
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 5
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
6
 withToken
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Modules\Lemmy;
4
5use Illuminate\Support\Facades\Http;
6use Illuminate\Http\Client\Response;
7
8class LemmyRequest
9{
10    private string $instance;
11    private ?string $token;
12
13    public function __construct(string $instance, ?string $token = null)
14    {
15        $this->instance = $instance;
16        $this->token = $token;
17    }
18
19    /**
20     * @param array<string, mixed> $params
21     */
22    public function get(string $endpoint, array $params = []): Response
23    {
24        $url = "https://{$this->instance}/api/v3/{$endpoint}";
25        
26        $request = Http::timeout(30);
27        
28        if ($this->token) {
29            $request = $request->withToken($this->token);
30        }
31        
32        return $request->get($url, $params);
33    }
34
35    /**
36     * @param array<string, mixed> $data
37     */
38    public function post(string $endpoint, array $data = []): Response
39    {
40        $url = "https://{$this->instance}/api/v3/{$endpoint}";
41        
42        $request = Http::timeout(30);
43        
44        if ($this->token) {
45            $request = $request->withToken($this->token);
46        }
47        
48        return $request->post($url, $data);
49    }
50
51    public function withToken(string $token): self
52    {
53        $this->token = $token;
54        return $this;
55    }
56}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 19:15:34 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report/Modules/Lemmy/Services/LemmyApiService.php.html b/backend/coverage-report/Modules/Lemmy/Services/LemmyApiService.php.html deleted file mode 100644 index 6cda237a..00000000 --- a/backend/coverage-report/Modules/Lemmy/Services/LemmyApiService.php.html +++ /dev/null @@ -1,438 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Modules/Lemmy/Services/LemmyApiService.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 93
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 6
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
LemmyApiService
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 93
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 6
462
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 __construct
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 login
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 16
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
12
 getCommunityId
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 9
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
12
 syncChannelPosts
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 34
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
30
 createPost
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 19
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
42
 getLanguages
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 14
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
12
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Modules\Lemmy\Services;
4
5use App\Enums\PlatformEnum;
6use App\Models\PlatformChannelPost;
7use App\Modules\Lemmy\LemmyRequest;
8use Exception;
9
10class LemmyApiService
11{
12    private string $instance;
13
14    public function __construct(string $instance)
15    {
16        $this->instance = $instance;
17    }
18
19    public function login(string $username, string $password): ?string
20    {
21        try {
22            $request = new LemmyRequest($this->instance);
23            $response = $request->post('user/login', [
24                'username_or_email' => $username,
25                'password' => $password,
26            ]);
27
28            if (!$response->successful()) {
29                logger()->error('Lemmy login failed', [
30                    'status' => $response->status(),
31                    'body' => $response->body()
32                ]);
33                return null;
34            }
35
36            $data = $response->json();
37            return $data['jwt'] ?? null;
38        } catch (Exception $e) {
39            logger()->error('Lemmy login exception', ['error' => $e->getMessage()]);
40            return null;
41        }
42    }
43
44    public function getCommunityId(string $communityName, string $token): int
45    {
46        try {
47            $request = new LemmyRequest($this->instance, $token);
48            $response = $request->get('community', ['name' => $communityName]);
49
50            if (!$response->successful()) {
51                throw new Exception('Failed to fetch community: ' . $response->status());
52            }
53
54            $data = $response->json();
55            return $data['community_view']['community']['id'] ?? throw new Exception('Community not found');
56        } catch (Exception $e) {
57            logger()->error('Community lookup failed', ['error' => $e->getMessage()]);
58            throw $e;
59        }
60    }
61
62    public function syncChannelPosts(string $token, int $platformChannelId, string $communityName): void
63    {
64        try {
65            $request = new LemmyRequest($this->instance, $token);
66            $response = $request->get('post/list', [
67                'community_id' => $platformChannelId,
68                'limit' => 50,
69                'sort' => 'New'
70            ]);
71
72            if (!$response->successful()) {
73                logger()->warning('Failed to sync channel posts', [
74                    'status' => $response->status(),
75                    'platform_channel_id' => $platformChannelId
76                ]);
77                return;
78            }
79
80            $data = $response->json();
81            $posts = $data['posts'] ?? [];
82
83            foreach ($posts as $postData) {
84                $post = $postData['post'];
85
86                PlatformChannelPost::storePost(
87                    PlatformEnum::LEMMY,
88                    (string) $platformChannelId,
89                    $communityName,
90                    (string) $post['id'],
91                    $post['url'] ?? null,
92                    $post['name'] ?? null,
93                    isset($post['published']) ? new \DateTime($post['published']) : null
94                );
95            }
96
97            logger()->info('Synced channel posts', [
98                'platform_channel_id' => $platformChannelId,
99                'posts_count' => count($posts)
100            ]);
101
102        } catch (Exception $e) {
103            logger()->error('Exception while syncing channel posts', [
104                'error' => $e->getMessage(),
105                'platform_channel_id' => $platformChannelId
106            ]);
107        }
108    }
109
110    /**
111     * @return array<string, mixed>
112     */
113    public function createPost(string $token, string $title, string $body, int $platformChannelId, ?string $url = null, ?string $thumbnail = null, ?int $languageId = null): array
114    {
115        try {
116            $request = new LemmyRequest($this->instance, $token);
117
118            $postData = [
119                'name' => $title,
120                'body' => $body,
121                'community_id' => $platformChannelId,
122            ];
123
124            if ($url) {
125                $postData['url'] = $url;
126            }
127
128            if ($thumbnail) {
129                $postData['custom_thumbnail'] = $thumbnail;
130            }
131
132            if ($languageId) {
133                $postData['language_id'] = $languageId;
134            }
135
136            $response = $request->post('post', $postData);
137
138            if (!$response->successful()) {
139                throw new Exception('Failed to create post: ' . $response->status() . ' - ' . $response->body());
140            }
141
142            return $response->json();
143        } catch (Exception $e) {
144            logger()->error('Post creation failed', ['error' => $e->getMessage()]);
145            throw $e;
146        }
147    }
148
149    /**
150     * @return array<int, mixed>
151     */
152    public function getLanguages(): array
153    {
154        try {
155            $request = new LemmyRequest($this->instance);
156            $response = $request->get('site');
157
158            if (!$response->successful()) {
159                logger()->warning('Failed to fetch site languages', [
160                    'status' => $response->status()
161                ]);
162                return [];
163            }
164
165            $data = $response->json();
166            return $data['all_languages'] ?? [];
167        } catch (Exception $e) {
168            logger()->error('Exception while fetching languages', [
169                'error' => $e->getMessage()
170            ]);
171            return [];
172        }
173    }
174}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 19:15:34 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report/Modules/Lemmy/Services/LemmyPublisher.php.html b/backend/coverage-report/Modules/Lemmy/Services/LemmyPublisher.php.html deleted file mode 100644 index f4ba343e..00000000 --- a/backend/coverage-report/Modules/Lemmy/Services/LemmyPublisher.php.html +++ /dev/null @@ -1,223 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Modules/Lemmy/Services/LemmyPublisher.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 13
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
LemmyPublisher
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 13
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
6
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 __construct
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 publishToChannel
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 11
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Modules\Lemmy\Services;
4
5use App\Exceptions\PlatformAuthException;
6use App\Models\Article;
7use App\Models\PlatformAccount;
8use App\Models\PlatformChannel;
9use App\Services\Auth\LemmyAuthService;
10use Exception;
11
12class LemmyPublisher
13{
14    private LemmyApiService $api;
15    private PlatformAccount $account;
16
17    public function __construct(PlatformAccount $account)
18    {
19        $this->api = new LemmyApiService($account->instance_url);
20        $this->account = $account;
21    }
22
23    /**
24     * @param array<string, mixed> $extractedData
25     * @return array<string, mixed>
26     * @throws PlatformAuthException
27     * @throws Exception
28     */
29    public function publishToChannel(Article $article, array $extractedData, PlatformChannel $channel): array
30    {
31        $token = LemmyAuthService::getToken($this->account);
32
33        // Use the language ID from extracted data (should be set during validation)
34        $languageId = $extractedData['language_id'] ?? null;
35
36        return $this->api->createPost(
37            $token,
38            $extractedData['title'] ?? 'Untitled',
39            $extractedData['description'] ?? '',
40            $channel->channel_id,
41            $article->url,
42            $extractedData['thumbnail'] ?? null,
43            $languageId
44        );
45    }
46
47}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 19:15:34 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report/Modules/Lemmy/Services/dashboard.html b/backend/coverage-report/Modules/Lemmy/Services/dashboard.html deleted file mode 100644 index 4d3274fc..00000000 --- a/backend/coverage-report/Modules/Lemmy/Services/dashboard.html +++ /dev/null @@ -1,302 +0,0 @@ - - - - - Dashboard for /var/www/html/backend/app/Modules/Lemmy/Services - - - - - - - -
-
-
-
- -
-
-
-
-
-
-
-

Classes

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
-
-
-

Insufficient Coverage

- -
-
-

Project Risks

-
- - - - - - - - - - - -
ClassCRAP
App\Modules\Lemmy\Services\LemmyApiService462
-
-
-
-
-
-

Methods

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
-
-
-

Insufficient Coverage

-
- - - - - - - - - - - - - - - - - - -
MethodCoverage
__construct0%
login0%
getCommunityId0%
syncChannelPosts0%
createPost0%
getLanguages0%
__construct0%
publishToChannel0%
-
-
-
-

Project Risks

-
- - - - - - - - - - - - - - - -
MethodCRAP
createPost42
syncChannelPosts30
login12
getCommunityId12
getLanguages12
-
-
-
- -
- - - - - - diff --git a/backend/coverage-report/Modules/Lemmy/Services/index.html b/backend/coverage-report/Modules/Lemmy/Services/index.html deleted file mode 100644 index c79b70ee..00000000 --- a/backend/coverage-report/Modules/Lemmy/Services/index.html +++ /dev/null @@ -1,149 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Modules/Lemmy/Services - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 106
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 8
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
LemmyApiService.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 93
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 6
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
LemmyPublisher.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 13
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- -
- - diff --git a/backend/coverage-report/Modules/Lemmy/dashboard.html b/backend/coverage-report/Modules/Lemmy/dashboard.html deleted file mode 100644 index a1e44198..00000000 --- a/backend/coverage-report/Modules/Lemmy/dashboard.html +++ /dev/null @@ -1,309 +0,0 @@ - - - - - Dashboard for /var/www/html/backend/app/Modules/Lemmy - - - - - - - -
-
-
-
- -
-
-
-
-
-
-
-

Classes

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
-
-
-

Insufficient Coverage

- -
-
-

Project Risks

- -
-
-
-
-

Methods

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
-
-
-

Insufficient Coverage

-
- - - - - - - - - - - - - - - - - - - - - - -
MethodCoverage
__construct0%
get0%
post0%
withToken0%
__construct0%
login0%
getCommunityId0%
syncChannelPosts0%
createPost0%
getLanguages0%
__construct0%
publishToChannel0%
-
-
-
-

Project Risks

-
- - - - - - - - - - - - - - - - - -
MethodCRAP
createPost42
syncChannelPosts30
login12
getCommunityId12
getLanguages12
get6
post6
-
-
-
- -
- - - - - - diff --git a/backend/coverage-report/Modules/Lemmy/index.html b/backend/coverage-report/Modules/Lemmy/index.html deleted file mode 100644 index 4392be7a..00000000 --- a/backend/coverage-report/Modules/Lemmy/index.html +++ /dev/null @@ -1,148 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Modules/Lemmy - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 120
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 12
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
Services
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 106
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 8
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
LemmyRequest.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 14
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 4
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- -
- - diff --git a/backend/coverage-report/Modules/dashboard.html b/backend/coverage-report/Modules/dashboard.html deleted file mode 100644 index 4535c465..00000000 --- a/backend/coverage-report/Modules/dashboard.html +++ /dev/null @@ -1,308 +0,0 @@ - - - - - Dashboard for /var/www/html/backend/app/Modules - - - - - - - -
-
-
-
- -
-
-
-
-
-
-
-

Classes

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
-
-
-

Insufficient Coverage

- -
-
-

Project Risks

- -
-
-
-
-

Methods

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
-
-
-

Insufficient Coverage

-
- - - - - - - - - - - - - - - - - - - - - - -
MethodCoverage
__construct0%
get0%
post0%
withToken0%
__construct0%
login0%
getCommunityId0%
syncChannelPosts0%
createPost0%
getLanguages0%
__construct0%
publishToChannel0%
-
-
-
-

Project Risks

-
- - - - - - - - - - - - - - - - - -
MethodCRAP
createPost42
syncChannelPosts30
login12
getCommunityId12
getLanguages12
get6
post6
-
-
-
- -
- - - - - - diff --git a/backend/coverage-report/Modules/index.html b/backend/coverage-report/Modules/index.html deleted file mode 100644 index 7781b5da..00000000 --- a/backend/coverage-report/Modules/index.html +++ /dev/null @@ -1,119 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Modules - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 120
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 12
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
Lemmy
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 120
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 12
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
-
- -
- - diff --git a/backend/coverage-report/Providers/AppServiceProvider.php.html b/backend/coverage-report/Providers/AppServiceProvider.php.html deleted file mode 100644 index 727e57cb..00000000 --- a/backend/coverage-report/Providers/AppServiceProvider.php.html +++ /dev/null @@ -1,260 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Providers/AppServiceProvider.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 82.76% covered (warning) -
-
-
82.76%
24 / 29
-
- 33.33% covered (danger) -
-
-
33.33%
1 / 3
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
AppServiceProvider
-
- 82.76% covered (warning) -
-
-
82.76%
24 / 29
-
- 33.33% covered (danger) -
-
-
33.33%
1 / 3
6.18
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 register
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
1
 boot
-
- 92.00% covered (success) -
-
-
92.00%
23 / 25
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
1.00
 mapExceptionToLogLevel
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
20
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Providers;
4
5use App\Events\ExceptionOccurred;
6use App\Listeners\LogExceptionToDatabase;
7use App\LogLevelEnum;
8use Error;
9use Illuminate\Contracts\Debug\ExceptionHandler;
10use Illuminate\Support\Facades\Event;
11use Illuminate\Support\ServiceProvider;
12use InvalidArgumentException;
13use Throwable;
14
15class AppServiceProvider extends ServiceProvider
16{
17    public function register(): void
18    {
19    }
20
21    public function boot(): void
22    {
23        Event::listen(
24            ExceptionOccurred::class,
25            LogExceptionToDatabase::class,
26        );
27
28        Event::listen(
29            \App\Events\NewArticleFetched::class,
30            \App\Listeners\ValidateArticleListener::class,
31        );
32
33        Event::listen(
34            \App\Events\ArticleApproved::class,
35            \App\Listeners\PublishApprovedArticle::class,
36        );
37
38        Event::listen(
39            \App\Events\ArticleReadyToPublish::class,
40            \App\Listeners\PublishArticle::class,
41        );
42
43        Event::listen(
44            \App\Events\ExceptionLogged::class,
45            \App\Listeners\LogExceptionToDatabase::class,
46        );
47
48        app()->make(ExceptionHandler::class)
49            ->reportable(function (Throwable $e) {
50                $level = $this->mapExceptionToLogLevel($e);
51
52                ExceptionOccurred::dispatch($e, $level, $e->getMessage(), []);
53            });
54    }
55
56    private function mapExceptionToLogLevel(Throwable $exception): LogLevelEnum
57    {
58        return match (true) {
59            $exception instanceof Error => LogLevelEnum::CRITICAL,
60            $exception instanceof InvalidArgumentException => LogLevelEnum::WARNING,
61            default => LogLevelEnum::ERROR,
62        };
63    }
64}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 19:15:34 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report/Providers/HorizonServiceProvider.php.html b/backend/coverage-report/Providers/HorizonServiceProvider.php.html deleted file mode 100644 index bf424d89..00000000 --- a/backend/coverage-report/Providers/HorizonServiceProvider.php.html +++ /dev/null @@ -1,208 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Providers/HorizonServiceProvider.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 75.00% covered (warning) -
-
-
75.00%
3 / 4
-
- 50.00% covered (danger) -
-
-
50.00%
1 / 2
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
HorizonServiceProvider
-
- 75.00% covered (warning) -
-
-
75.00%
3 / 4
-
- 50.00% covered (danger) -
-
-
50.00%
1 / 2
2.06
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 boot
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
1
 gate
-
- 66.67% covered (warning) -
-
-
66.67%
2 / 3
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
1.04
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Providers;
4
5use Illuminate\Support\Facades\Gate;
6use Laravel\Horizon\Horizon;
7use Laravel\Horizon\HorizonApplicationServiceProvider;
8
9class HorizonServiceProvider extends HorizonApplicationServiceProvider
10{
11    /**
12     * Bootstrap any application services.
13     */
14    public function boot(): void
15    {
16        parent::boot();
17
18        // Horizon::routeSmsNotificationsTo('15556667777');
19        // Horizon::routeMailNotificationsTo('example@example.com');
20        // Horizon::routeSlackNotificationsTo('slack-webhook-url', '#channel');
21    }
22
23    /**
24     * Register the Horizon gate.
25     *
26     * This gate determines who can access Horizon in non-local environments.
27     */
28    protected function gate(): void
29    {
30        Gate::define('viewHorizon', function ($user = null) {
31            return true;
32        });
33    }
34}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 19:15:34 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report/Providers/dashboard.html b/backend/coverage-report/Providers/dashboard.html deleted file mode 100644 index 7e80d480..00000000 --- a/backend/coverage-report/Providers/dashboard.html +++ /dev/null @@ -1,290 +0,0 @@ - - - - - Dashboard for /var/www/html/backend/app/Providers - - - - - - - -
-
-
-
- -
-
-
-
-
-
-
-

Classes

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
-
-
-

Insufficient Coverage

-
- - - - - - - - - - - - -
ClassCoverage
App\Providers\HorizonServiceProvider75%
App\Providers\AppServiceProvider82%
-
-
-
-

Project Risks

-
- - - - - - - - - - - -
ClassCRAP
App\Providers\AppServiceProvider6
-
-
-
-
-
-

Methods

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
-
-
-

Insufficient Coverage

-
- - - - - - - - - - - - -
MethodCoverage
mapExceptionToLogLevel0%
gate66%
-
-
-
-

Project Risks

-
- - - - - - - - - - - -
MethodCRAP
mapExceptionToLogLevel20
-
-
-
- -
- - - - - - diff --git a/backend/coverage-report/Providers/index.html b/backend/coverage-report/Providers/index.html deleted file mode 100644 index 02ee1784..00000000 --- a/backend/coverage-report/Providers/index.html +++ /dev/null @@ -1,147 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Providers - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 81.82% covered (warning) -
-
-
81.82%
27 / 33
-
- 40.00% covered (danger) -
-
-
40.00%
2 / 5
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
AppServiceProvider.php
-
- 82.76% covered (warning) -
-
-
82.76%
24 / 29
-
- 33.33% covered (danger) -
-
-
33.33%
1 / 3
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
HorizonServiceProvider.php
-
- 75.00% covered (warning) -
-
-
75.00%
3 / 4
-
- 50.00% covered (danger) -
-
-
50.00%
1 / 2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- -
- - diff --git a/backend/coverage-report/Services/Article/ArticleFetcher.php.html b/backend/coverage-report/Services/Article/ArticleFetcher.php.html deleted file mode 100644 index fc592b74..00000000 --- a/backend/coverage-report/Services/Article/ArticleFetcher.php.html +++ /dev/null @@ -1,354 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Services/Article/ArticleFetcher.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 45.45% covered (danger) -
-
-
45.45%
20 / 44
-
- 20.00% covered (danger) -
-
-
20.00%
1 / 5
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
ArticleFetcher
-
- 45.45% covered (danger) -
-
-
45.45%
20 / 44
-
- 20.00% covered (danger) -
-
-
20.00%
1 / 5
30.64
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 getArticlesFromFeed
-
- 44.44% covered (danger) -
-
-
44.44%
4 / 9
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
4.54
 getArticlesFromRssFeed
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
1
 getArticlesFromWebsiteFeed
-
- 38.89% covered (danger) -
-
-
38.89%
7 / 18
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
5.05
 fetchArticleData
-
- 88.89% covered (warning) -
-
-
88.89%
8 / 9
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2.01
 saveArticle
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 7
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
6
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Services\Article;
4
5use App\Models\Article;
6use App\Models\Feed;
7use App\Services\Http\HttpFetcher;
8use App\Services\Factories\ArticleParserFactory;
9use App\Services\Factories\HomepageParserFactory;
10use App\Services\Log\LogSaver;
11use Exception;
12use Illuminate\Support\Collection;
13
14class ArticleFetcher
15{
16    /**
17     * @return Collection<int, Article>
18     */
19    public static function getArticlesFromFeed(Feed $feed): Collection
20    {
21        if ($feed->type === 'rss') {
22            return self::getArticlesFromRssFeed($feed);
23        } elseif ($feed->type === 'website') {
24            return self::getArticlesFromWebsiteFeed($feed);
25        }
26
27        LogSaver::warning("Unsupported feed type", null, [
28            'feed_id' => $feed->id,
29            'feed_type' => $feed->type
30        ]);
31
32        return collect();
33    }
34
35    /**
36     * @return Collection<int, Article>
37     */
38    private static function getArticlesFromRssFeed(Feed $feed): Collection
39    {
40        // TODO: Implement RSS feed parsing
41        // For now, return empty collection
42        return collect();
43    }
44
45    /**
46     * @return Collection<int, Article>
47     */
48    private static function getArticlesFromWebsiteFeed(Feed $feed): Collection
49    {
50        try {
51            // Try to get parser for this feed
52            $parser = HomepageParserFactory::getParserForFeed($feed);
53
54            if (! $parser) {
55                LogSaver::warning("No parser available for feed URL", null, [
56                    'feed_id' => $feed->id,
57                    'feed_url' => $feed->url
58                ]);
59
60                return collect();
61            }
62
63            $html = HttpFetcher::fetchHtml($feed->url);
64            $urls = $parser->extractArticleUrls($html);
65
66            return collect($urls)
67                ->map(fn (string $url) => self::saveArticle($url, $feed->id));
68
69        } catch (Exception $e) {
70            LogSaver::error("Failed to fetch articles from website feed", null, [
71                'feed_id' => $feed->id,
72                'feed_url' => $feed->url,
73                'error' => $e->getMessage()
74            ]);
75
76            return collect();
77        }
78    }
79
80    /**
81     * @return array<string, mixed>
82     */
83    public static function fetchArticleData(Article $article): array
84    {
85        try {
86            $html = HttpFetcher::fetchHtml($article->url);
87            $parser = ArticleParserFactory::getParser($article->url);
88
89            return $parser->extractData($html);
90        } catch (Exception $e) {
91            LogSaver::error('Exception while fetching article data', null, [
92                'url' => $article->url,
93                'error' => $e->getMessage()
94            ]);
95
96            return [];
97        }
98    }
99
100    private static function saveArticle(string $url, ?int $feedId = null): Article
101    {
102        $existingArticle = Article::where('url', $url)->first();
103
104        if ($existingArticle) {
105            return $existingArticle;
106        }
107
108        return Article::create([
109            'url' => $url,
110            'feed_id' => $feedId
111        ]);
112    }
113}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 19:15:34 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report/Services/Article/ValidationService.php.html b/backend/coverage-report/Services/Article/ValidationService.php.html deleted file mode 100644 index 660c8d19..00000000 --- a/backend/coverage-report/Services/Article/ValidationService.php.html +++ /dev/null @@ -1,228 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Services/Article/ValidationService.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 48.00% covered (danger) -
-
-
48.00%
12 / 25
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
ValidationService
-
- 48.00% covered (danger) -
-
-
48.00%
12 / 25
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
8.52
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 validate
-
- 66.67% covered (warning) -
-
-
66.67%
12 / 18
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2.15
 validateByKeywords
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 7
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
12
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Services\Article;
4
5use App\Models\Article;
6
7class ValidationService
8{
9    public static function validate(Article $article): Article
10    {
11        logger('Checking keywords for article: ' . $article->id);
12
13        $articleData = ArticleFetcher::fetchArticleData($article);
14        
15        if (!isset($articleData['full_article'])) {
16            logger()->warning('Article data missing full_article key', [
17                'article_id' => $article->id,
18                'url' => $article->url
19            ]);
20            
21            $article->update([
22                'is_valid' => false,
23                'validated_at' => now(),
24            ]);
25            
26            return $article->refresh();
27        }
28        
29        $validationResult = self::validateByKeywords($articleData['full_article']);
30
31        $article->update([
32            'is_valid' => $validationResult,
33            'validated_at' => now(),
34        ]);
35
36        return $article->refresh();
37    }
38
39    private static function validateByKeywords(string $full_article): bool
40    {
41        $keywords = [
42            'N-VA', 'Bart De Wever', 'Frank Vandenbroucke',
43        ];
44
45        foreach ($keywords as $keyword) {
46            if (stripos($full_article, $keyword) !== false) {
47                return true;
48            }
49        }
50
51        return false;
52    }
53}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 19:15:34 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report/Services/Article/dashboard.html b/backend/coverage-report/Services/Article/dashboard.html deleted file mode 100644 index d5c22d07..00000000 --- a/backend/coverage-report/Services/Article/dashboard.html +++ /dev/null @@ -1,301 +0,0 @@ - - - - - Dashboard for /var/www/html/backend/app/Services/Article - - - - - - - -
-
-
-
- -
-
-
-
-
-
-
-

Classes

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
-
-
-

Insufficient Coverage

-
- - - - - - - - - - - - -
ClassCoverage
App\Services\Article\ArticleFetcher45%
App\Services\Article\ValidationService48%
-
-
-
-

Project Risks

- -
-
-
-
-

Methods

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
-
-
-

Insufficient Coverage

-
- - - - - - - - - - - - - - - - -
MethodCoverage
saveArticle0%
validateByKeywords0%
getArticlesFromWebsiteFeed38%
getArticlesFromFeed44%
validate66%
fetchArticleData88%
-
-
-
-

Project Risks

- -
-
- -
- - - - - - diff --git a/backend/coverage-report/Services/Article/index.html b/backend/coverage-report/Services/Article/index.html deleted file mode 100644 index 3ab0cec3..00000000 --- a/backend/coverage-report/Services/Article/index.html +++ /dev/null @@ -1,148 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Services/Article - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 46.38% covered (danger) -
-
-
46.38%
32 / 69
-
- 14.29% covered (danger) -
-
-
14.29%
1 / 7
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
ArticleFetcher.php
-
- 45.45% covered (danger) -
-
-
45.45%
20 / 44
-
- 20.00% covered (danger) -
-
-
20.00%
1 / 5
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
ValidationService.php
-
- 48.00% covered (danger) -
-
-
48.00%
12 / 25
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- -
- - diff --git a/backend/coverage-report/Services/Auth/LemmyAuthService.php.html b/backend/coverage-report/Services/Auth/LemmyAuthService.php.html deleted file mode 100644 index d12fbc4a..00000000 --- a/backend/coverage-report/Services/Auth/LemmyAuthService.php.html +++ /dev/null @@ -1,194 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Services/Auth/LemmyAuthService.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 12
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
LemmyAuthService
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 12
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
42
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 getToken
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 12
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
42
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Services\Auth;
4
5use App\Enums\PlatformEnum;
6use App\Exceptions\PlatformAuthException;
7use App\Models\PlatformAccount;
8use App\Modules\Lemmy\Services\LemmyApiService;
9use Illuminate\Support\Facades\Cache;
10
11class LemmyAuthService
12{
13    /**
14     * @throws PlatformAuthException
15     */
16    public static function getToken(PlatformAccount $account): string
17    {
18        $cacheKey = "lemmy_jwt_token_$account->id";
19        $cachedToken = Cache::get($cacheKey);
20
21        if ($cachedToken) {
22            return $cachedToken;
23        }
24
25        if (! $account->username || ! $account->password || ! $account->instance_url) {
26            throw new PlatformAuthException(PlatformEnum::LEMMY, 'Missing credentials for account: ' . $account->username);
27        }
28
29        $api = new LemmyApiService($account->instance_url);
30        $token = $api->login($account->username, $account->password);
31
32        if (!$token) {
33            throw new PlatformAuthException(PlatformEnum::LEMMY, 'Login failed for account: ' . $account->username);
34        }
35
36        // Cache for 50 minutes (3000 seconds) to allow buffer before token expires
37        Cache::put($cacheKey, $token, 3000);
38
39        return $token;
40    }
41}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 19:15:34 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report/Services/Auth/dashboard.html b/backend/coverage-report/Services/Auth/dashboard.html deleted file mode 100644 index 85de2651..00000000 --- a/backend/coverage-report/Services/Auth/dashboard.html +++ /dev/null @@ -1,289 +0,0 @@ - - - - - Dashboard for /var/www/html/backend/app/Services/Auth - - - - - - - -
-
-
-
- -
-
-
-
-
-
-
-

Classes

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
-
-
-

Insufficient Coverage

-
- - - - - - - - - - - -
ClassCoverage
App\Services\Auth\LemmyAuthService0%
-
-
-
-

Project Risks

-
- - - - - - - - - - - -
ClassCRAP
App\Services\Auth\LemmyAuthService42
-
-
-
-
-
-

Methods

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
-
-
-

Insufficient Coverage

-
- - - - - - - - - - - -
MethodCoverage
getToken0%
-
-
-
-

Project Risks

-
- - - - - - - - - - - -
MethodCRAP
getToken42
-
-
-
- -
- - - - - - diff --git a/backend/coverage-report/Services/Auth/index.html b/backend/coverage-report/Services/Auth/index.html deleted file mode 100644 index 20dbcce2..00000000 --- a/backend/coverage-report/Services/Auth/index.html +++ /dev/null @@ -1,120 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Services/Auth - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 12
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
LemmyAuthService.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 12
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- -
- - diff --git a/backend/coverage-report/Services/DashboardStatsService.php.html b/backend/coverage-report/Services/DashboardStatsService.php.html deleted file mode 100644 index 05064b0e..00000000 --- a/backend/coverage-report/Services/DashboardStatsService.php.html +++ /dev/null @@ -1,306 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Services/DashboardStatsService.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 100.00% covered (success) -
-
-
100.00%
40 / 40
-
- 100.00% covered (success) -
-
-
100.00%
4 / 4
CRAP
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
DashboardStatsService
-
- 100.00% covered (success) -
-
-
100.00%
40 / 40
-
- 100.00% covered (success) -
-
-
100.00%
4 / 4
13
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
 getStats
-
- 100.00% covered (success) -
-
-
100.00%
16 / 16
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
4
 getAvailablePeriods
-
- 100.00% covered (success) -
-
-
100.00%
7 / 7
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
1
 getDateRange
-
- 100.00% covered (success) -
-
-
100.00%
9 / 9
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
7
 getSystemStats
-
- 100.00% covered (success) -
-
-
100.00%
8 / 8
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
1
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Services;
4
5use App\Models\Article;
6use App\Models\ArticlePublication;
7use Carbon\Carbon;
8
9class DashboardStatsService
10{
11    /**
12     * @return array
13     */
14    public function getStats(string $period = 'today'): array
15    {
16        $dateRange = $this->getDateRange($period);
17        
18        // Get articles fetched for the period
19        $articlesFetchedQuery = Article::query();
20        if ($dateRange) {
21            $articlesFetchedQuery->whereBetween('created_at', $dateRange);
22        }
23        $articlesFetched = $articlesFetchedQuery->count();
24
25        // Get articles published for the period
26        $articlesPublishedQuery = ArticlePublication::query()
27            ->whereNotNull('published_at');
28        if ($dateRange) {
29            $articlesPublishedQuery->whereBetween('published_at', $dateRange);
30        }
31        $articlesPublished = $articlesPublishedQuery->count();
32
33        // Calculate published percentage
34        $publishedPercentage = $articlesFetched > 0 ? round(($articlesPublished / $articlesFetched) * 100, 1) : 0.0;
35
36        return [
37            'articles_fetched' => $articlesFetched,
38            'articles_published' => $articlesPublished,
39            'published_percentage' => $publishedPercentage,
40        ];
41    }
42
43    /**
44     * @return array<string, string>
45     */
46    public function getAvailablePeriods(): array
47    {
48        return [
49            'today' => 'Today',
50            'week' => 'This Week',
51            'month' => 'This Month',
52            'year' => 'This Year',
53            'all' => 'All Time',
54        ];
55    }
56
57    /**
58     * @return array{0: Carbon, 1: Carbon}|null
59     */
60    private function getDateRange(string $period): ?array
61    {
62        $now = Carbon::now();
63        
64        return match ($period) {
65            'today' => [$now->copy()->startOfDay(), $now->copy()->endOfDay()],
66            'week' => [$now->copy()->startOfWeek(), $now->copy()->endOfWeek()],
67            'month' => [$now->copy()->startOfMonth(), $now->copy()->endOfMonth()],
68            'year' => [$now->copy()->startOfYear(), $now->copy()->endOfYear()],
69            'all' => null, // No date filtering for all-time stats
70            default => [$now->copy()->startOfDay(), $now->copy()->endOfDay()],
71        };
72    }
73
74    /**
75     * Get additional stats for dashboard
76     */
77    public function getSystemStats(): array
78    {
79        return [
80            'total_feeds' => \App\Models\Feed::count(),
81            'active_feeds' => \App\Models\Feed::where('is_active', true)->count(),
82            'total_channels' => \App\Models\PlatformChannel::count(),
83            'active_channels' => \App\Models\PlatformChannel::where('is_active', true)->count(),
84            'total_routes' => \App\Models\Route::count(),
85            'active_routes' => \App\Models\Route::where('is_active', true)->count(),
86        ];
87    }
88}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 19:15:34 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report/Services/Factories/ArticleParserFactory.php.html b/backend/coverage-report/Services/Factories/ArticleParserFactory.php.html deleted file mode 100644 index 520b5b68..00000000 --- a/backend/coverage-report/Services/Factories/ArticleParserFactory.php.html +++ /dev/null @@ -1,250 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Services/Factories/ArticleParserFactory.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 36.36% covered (danger) -
-
-
36.36%
4 / 11
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
ArticleParserFactory
-
- 36.36% covered (danger) -
-
-
36.36%
4 / 11
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
15.28
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 getParser
-
- 80.00% covered (warning) -
-
-
80.00%
4 / 5
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
3.07
 getSupportedSources
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 4
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 registerParser
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
6
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Services\Factories;
4
5use App\Contracts\ArticleParserInterface;
6use App\Services\Parsers\VrtArticleParser;
7use App\Services\Parsers\BelgaArticleParser;
8use Exception;
9
10class ArticleParserFactory
11{
12    /**
13     * @var array<int, class-string<ArticleParserInterface>>
14     */
15    private static array $parsers = [
16        VrtArticleParser::class,
17        BelgaArticleParser::class,
18    ];
19
20    public static function getParser(string $url): ArticleParserInterface
21    {
22        foreach (self::$parsers as $parserClass) {
23            $parser = new $parserClass();
24            
25            if ($parser->canParse($url)) {
26                return $parser;
27            }
28        }
29
30        throw new Exception("No parser found for URL: {$url}");
31    }
32
33    /**
34     * @return array<int, string>
35     */
36    public static function getSupportedSources(): array
37    {
38        return array_map(function($parserClass) {
39            $parser = new $parserClass();
40            return $parser->getSourceName();
41        }, self::$parsers);
42    }
43
44    /**
45     * @param class-string<ArticleParserInterface> $parserClass
46     */
47    public static function registerParser(string $parserClass): void
48    {
49        if (!in_array($parserClass, self::$parsers)) {
50            self::$parsers[] = $parserClass;
51        }
52    }
53}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 19:15:34 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report/Services/Factories/HomepageParserFactory.php.html b/backend/coverage-report/Services/Factories/HomepageParserFactory.php.html deleted file mode 100644 index 4e69c558..00000000 --- a/backend/coverage-report/Services/Factories/HomepageParserFactory.php.html +++ /dev/null @@ -1,220 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Services/Factories/HomepageParserFactory.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 87.50% covered (warning) -
-
-
87.50%
7 / 8
-
- 50.00% covered (danger) -
-
-
50.00%
1 / 2
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
HomepageParserFactory
-
- 87.50% covered (warning) -
-
-
87.50%
7 / 8
-
- 50.00% covered (danger) -
-
-
50.00%
1 / 2
5.05
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 getParser
-
- 80.00% covered (warning) -
-
-
80.00%
4 / 5
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
3.07
 getParserForFeed
-
- 100.00% covered (success) -
-
-
100.00%
3 / 3
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
2
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Services\Factories;
4
5use App\Contracts\HomepageParserInterface;
6use App\Models\Feed;
7use App\Services\Parsers\VrtHomepageParserAdapter;
8use App\Services\Parsers\BelgaHomepageParserAdapter;
9use Exception;
10
11class HomepageParserFactory
12{
13    /**
14     * @var array<int, class-string<HomepageParserInterface>>
15     */
16    private static array $parsers = [
17        VrtHomepageParserAdapter::class,
18        BelgaHomepageParserAdapter::class,
19    ];
20
21    /**
22     * @throws Exception
23     */
24    public static function getParser(string $url): HomepageParserInterface
25    {
26        foreach (self::$parsers as $parserClass) {
27            $parser = new $parserClass();
28
29            if ($parser->canParse($url)) {
30                return $parser;
31            }
32        }
33
34        throw new Exception("No homepage parser found for URL: {$url}");
35    }
36
37    public static function getParserForFeed(Feed $feed): ?HomepageParserInterface
38    {
39        try {
40            return self::getParser($feed->url);
41        } catch (Exception) {
42            return null;
43        }
44    }
45}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 19:15:34 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report/Services/Factories/dashboard.html b/backend/coverage-report/Services/Factories/dashboard.html deleted file mode 100644 index 41b5ec16..00000000 --- a/backend/coverage-report/Services/Factories/dashboard.html +++ /dev/null @@ -1,296 +0,0 @@ - - - - - Dashboard for /var/www/html/backend/app/Services/Factories - - - - - - - -
-
-
-
- -
-
-
-
-
-
-
-

Classes

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
-
-
-

Insufficient Coverage

- -
-
-

Project Risks

- -
-
-
-
-

Methods

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
-
-
-

Insufficient Coverage

-
- - - - - - - - - - - - - - -
MethodCoverage
getSupportedSources0%
registerParser0%
getParser80%
getParser80%
-
-
-
-

Project Risks

-
- - - - - - - - - - - - - -
MethodCRAP
registerParser6
getParser3
getParser3
-
-
-
- -
- - - - - - diff --git a/backend/coverage-report/Services/Factories/index.html b/backend/coverage-report/Services/Factories/index.html deleted file mode 100644 index 8f96529a..00000000 --- a/backend/coverage-report/Services/Factories/index.html +++ /dev/null @@ -1,148 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Services/Factories - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 57.89% covered (warning) -
-
-
57.89%
11 / 19
-
- 20.00% covered (danger) -
-
-
20.00%
1 / 5
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
ArticleParserFactory.php
-
- 36.36% covered (danger) -
-
-
36.36%
4 / 11
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
HomepageParserFactory.php
-
- 87.50% covered (warning) -
-
-
87.50%
7 / 8
-
- 50.00% covered (danger) -
-
-
50.00%
1 / 2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- -
- - diff --git a/backend/coverage-report/Services/Http/HttpFetcher.php.html b/backend/coverage-report/Services/Http/HttpFetcher.php.html deleted file mode 100644 index 99a7ab61..00000000 --- a/backend/coverage-report/Services/Http/HttpFetcher.php.html +++ /dev/null @@ -1,256 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Services/Http/HttpFetcher.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 22.73% covered (danger) -
-
-
22.73%
10 / 44
-
- 50.00% covered (danger) -
-
-
50.00%
1 / 2
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
HttpFetcher
-
- 22.73% covered (danger) -
-
-
22.73%
10 / 44
-
- 50.00% covered (danger) -
-
-
50.00%
1 / 2
46.37
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 fetchHtml
-
- 100.00% covered (success) -
-
-
100.00%
10 / 10
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
3
 fetchMultipleUrls
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 34
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
42
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Services\Http;
4
5use Illuminate\Support\Facades\Http;
6use Exception;
7
8class HttpFetcher
9{
10    public static function fetchHtml(string $url): string
11    {
12        try {
13            $response = Http::get($url);
14            
15            if (!$response->successful()) {
16                throw new Exception("Failed to fetch URL: {$url} - Status: {$response->status()}");
17            }
18            
19            return $response->body();
20        } catch (Exception $e) {
21            logger()->error('HTTP fetch failed', [
22                'url' => $url,
23                'error' => $e->getMessage()
24            ]);
25            throw $e;
26        }
27    }
28
29    /**
30     * @param array<int, string> $urls
31     * @return array<int, array<string, mixed>>
32     */
33    public static function fetchMultipleUrls(array $urls): array
34    {
35        try {
36            $responses = Http::pool(function ($pool) use ($urls) {
37                foreach ($urls as $url) {
38                    $pool->get($url);
39                }
40            });
41
42            return collect($responses)
43                ->map(function ($response, $index) use ($urls) {
44                    if (!isset($urls[$index])) {
45                        return null;
46                    }
47                    
48                    $url = $urls[$index];
49                    
50                    try {
51                        if ($response->successful()) {
52                            return [
53                                'url' => $url,
54                                'html' => $response->body(),
55                                'success' => true
56                            ];
57                        } else {
58                            return [
59                                'url' => $url,
60                                'html' => null,
61                                'success' => false,
62                                'status' => $response->status()
63                            ];
64                        }
65                    } catch (Exception) {
66                        return [
67                            'url' => $url,
68                            'html' => null,
69                            'success' => false,
70                            'error' => 'Exception occurred'
71                        ];
72                    }
73                })
74                ->filter(fn($result) => $result !== null)
75                ->toArray();
76        } catch (Exception $e) {
77            logger()->error('Multiple URL fetch failed', ['error' => $e->getMessage()]);
78            return [];
79        }
80    }
81}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 19:15:34 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report/Services/Http/dashboard.html b/backend/coverage-report/Services/Http/dashboard.html deleted file mode 100644 index 99c26e6e..00000000 --- a/backend/coverage-report/Services/Http/dashboard.html +++ /dev/null @@ -1,289 +0,0 @@ - - - - - Dashboard for /var/www/html/backend/app/Services/Http - - - - - - - -
-
-
-
- -
-
-
-
-
-
-
-

Classes

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
-
-
-

Insufficient Coverage

-
- - - - - - - - - - - -
ClassCoverage
App\Services\Http\HttpFetcher22%
-
-
-
-

Project Risks

-
- - - - - - - - - - - -
ClassCRAP
App\Services\Http\HttpFetcher46
-
-
-
-
-
-

Methods

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
-
-
-

Insufficient Coverage

-
- - - - - - - - - - - -
MethodCoverage
fetchMultipleUrls0%
-
-
-
-

Project Risks

-
- - - - - - - - - - - -
MethodCRAP
fetchMultipleUrls42
-
-
-
- -
- - - - - - diff --git a/backend/coverage-report/Services/Http/index.html b/backend/coverage-report/Services/Http/index.html deleted file mode 100644 index b44b98f1..00000000 --- a/backend/coverage-report/Services/Http/index.html +++ /dev/null @@ -1,120 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Services/Http - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 22.73% covered (danger) -
-
-
22.73%
10 / 44
-
- 50.00% covered (danger) -
-
-
50.00%
1 / 2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
HttpFetcher.php
-
- 22.73% covered (danger) -
-
-
22.73%
10 / 44
-
- 50.00% covered (danger) -
-
-
50.00%
1 / 2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- -
- - diff --git a/backend/coverage-report/Services/Log/LogSaver.php.html b/backend/coverage-report/Services/Log/LogSaver.php.html deleted file mode 100644 index aeea0929..00000000 --- a/backend/coverage-report/Services/Log/LogSaver.php.html +++ /dev/null @@ -1,306 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Services/Log/LogSaver.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 58.82% covered (warning) -
-
-
58.82%
10 / 17
-
- 60.00% covered (warning) -
-
-
60.00%
3 / 5
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
LogSaver
-
- 58.82% covered (warning) -
-
-
58.82%
10 / 17
-
- 60.00% covered (warning) -
-
-
60.00%
3 / 5
8.51
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 info
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
1
 error
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
1
 warning
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
1
 debug
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 log
-
- 53.85% covered (warning) -
-
-
53.85%
7 / 13
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2.39
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Services\Log;
4
5use App\LogLevelEnum;
6use App\Models\Log;
7use App\Models\PlatformChannel;
8
9class LogSaver
10{
11    /**
12     * @param array<string, mixed> $context
13     */
14    public static function info(string $message, ?PlatformChannel $channel = null, array $context = []): void
15    {
16        self::log(LogLevelEnum::INFO, $message, $channel, $context);
17    }
18
19    /**
20     * @param array<string, mixed> $context
21     */
22    public static function error(string $message, ?PlatformChannel $channel = null, array $context = []): void
23    {
24        self::log(LogLevelEnum::ERROR, $message, $channel, $context);
25    }
26
27    /**
28     * @param array<string, mixed> $context
29     */
30    public static function warning(string $message, ?PlatformChannel $channel = null, array $context = []): void
31    {
32        self::log(LogLevelEnum::WARNING, $message, $channel, $context);
33    }
34
35    /**
36     * @param array<string, mixed> $context
37     */
38    public static function debug(string $message, ?PlatformChannel $channel = null, array $context = []): void
39    {
40        self::log(LogLevelEnum::DEBUG, $message, $channel, $context);
41    }
42
43    /**
44     * @param array<string, mixed> $context
45     */
46    private static function log(LogLevelEnum $level, string $message, ?PlatformChannel $channel = null, array $context = []): void
47    {
48        $logContext = $context;
49
50        if ($channel) {
51            $logContext = array_merge($logContext, [
52                'channel_id' => $channel->id,
53                'channel_name' => $channel->name,
54                'platform' => $channel->platformInstance->platform->value,
55                'instance_url' => $channel->platformInstance->url,
56            ]);
57        }
58
59        Log::create([
60            'level' => $level,
61            'message' => $message,
62            'context' => $logContext,
63        ]);
64    }
65}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 19:15:34 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report/Services/Log/dashboard.html b/backend/coverage-report/Services/Log/dashboard.html deleted file mode 100644 index ee6938ee..00000000 --- a/backend/coverage-report/Services/Log/dashboard.html +++ /dev/null @@ -1,290 +0,0 @@ - - - - - Dashboard for /var/www/html/backend/app/Services/Log - - - - - - - -
-
-
-
- -
-
-
-
-
-
-
-

Classes

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
-
-
-

Insufficient Coverage

-
- - - - - - - - - - - -
ClassCoverage
App\Services\Log\LogSaver58%
-
-
-
-

Project Risks

-
- - - - - - - - - - - -
ClassCRAP
App\Services\Log\LogSaver8
-
-
-
-
-
-

Methods

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
-
-
-

Insufficient Coverage

-
- - - - - - - - - - - - -
MethodCoverage
debug0%
log53%
-
-
-
-

Project Risks

-
- - - - - - - - - - - -
MethodCRAP
log2
-
-
-
- -
- - - - - - diff --git a/backend/coverage-report/Services/Log/index.html b/backend/coverage-report/Services/Log/index.html deleted file mode 100644 index 76655d4f..00000000 --- a/backend/coverage-report/Services/Log/index.html +++ /dev/null @@ -1,120 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Services/Log - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 58.82% covered (warning) -
-
-
58.82%
10 / 17
-
- 60.00% covered (warning) -
-
-
60.00%
3 / 5
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
LogSaver.php
-
- 58.82% covered (warning) -
-
-
58.82%
10 / 17
-
- 60.00% covered (warning) -
-
-
60.00%
3 / 5
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- -
- - diff --git a/backend/coverage-report/Services/OnboardingRedirectService.php.html b/backend/coverage-report/Services/OnboardingRedirectService.php.html deleted file mode 100644 index 1b67da43..00000000 --- a/backend/coverage-report/Services/OnboardingRedirectService.php.html +++ /dev/null @@ -1,172 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Services/OnboardingRedirectService.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 4
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
OnboardingRedirectService
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 4
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
6
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 handleRedirect
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 4
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
6
-
- - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Services;
4
5use Illuminate\Http\RedirectResponse;
6use Illuminate\Http\Request;
7
8class OnboardingRedirectService
9{
10    public static function handleRedirect(Request $request, string $defaultRoute, string $successMessage): RedirectResponse
11    {
12        $redirectTo = $request->input('redirect_to');
13        
14        if ($redirectTo) {
15            return redirect($redirectTo)->with('success', $successMessage);
16        }
17
18        return redirect()->route($defaultRoute)->with('success', $successMessage);
19    }
20}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 19:15:34 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report/Services/Parsers/BelgaArticlePageParser.php.html b/backend/coverage-report/Services/Parsers/BelgaArticlePageParser.php.html deleted file mode 100644 index 0987457f..00000000 --- a/backend/coverage-report/Services/Parsers/BelgaArticlePageParser.php.html +++ /dev/null @@ -1,351 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Services/Parsers/BelgaArticlePageParser.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 42
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 5
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
BelgaArticlePageParser
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 42
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 5
306
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 extractTitle
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 9
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
30
 extractDescription
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 7
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
20
 extractFullArticle
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 15
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
20
 extractThumbnail
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 5
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
12
 extractData
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 6
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Services\Parsers;
4
5class BelgaArticlePageParser
6{
7    public static function extractTitle(string $html): ?string
8    {
9        // Try h1 with Belga-specific class first
10        if (preg_match('/<h1[^>]*class="[^"]*prezly-slate-heading--heading-1[^"]*"[^>]*>([^<]+)<\/h1>/i', $html, $matches)) {
11            return html_entity_decode(strip_tags($matches[1]), ENT_QUOTES, 'UTF-8');
12        }
13        
14        // Try meta title
15        if (preg_match('/<meta property="og:title" content="([^"]+)"/i', $html, $matches)) {
16            return html_entity_decode($matches[1], ENT_QUOTES, 'UTF-8');
17        }
18        
19        // Try any h1 tag
20        if (preg_match('/<h1[^>]*>([^<]+)<\/h1>/i', $html, $matches)) {
21            return html_entity_decode(strip_tags($matches[1]), ENT_QUOTES, 'UTF-8');
22        }
23        
24        // Try title tag
25        if (preg_match('/<title>([^<]+)<\/title>/i', $html, $matches)) {
26            return html_entity_decode($matches[1], ENT_QUOTES, 'UTF-8');
27        }
28        
29        return null;
30    }
31    
32    public static function extractDescription(string $html): ?string
33    {
34        // Try meta description first
35        if (preg_match('/<meta property="og:description" content="([^"]+)"/i', $html, $matches)) {
36            return html_entity_decode($matches[1], ENT_QUOTES, 'UTF-8');
37        }
38        
39        // Try Belga-specific paragraph class
40        if (preg_match('/<p[^>]*class="[^"]*styles_paragraph__[^"]*"[^>]*>([^<]+(?:<[^\/](?!p)[^>]*>[^<]*<\/[^>]*>[^<]*)*)<\/p>/i', $html, $matches)) {
41            return html_entity_decode(strip_tags($matches[1]), ENT_QUOTES, 'UTF-8');
42        }
43        
44        // Try to find first paragraph in article content
45        if (preg_match('/<p[^>]*>([^<]+(?:<[^\/](?!p)[^>]*>[^<]*<\/[^>]*>[^<]*)*)<\/p>/i', $html, $matches)) {
46            return html_entity_decode(strip_tags($matches[1]), ENT_QUOTES, 'UTF-8');
47        }
48        
49        return null;
50    }
51    
52    public static function extractFullArticle(string $html): ?string
53    {
54        // Remove scripts, styles, and other non-content elements
55        $cleanHtml = preg_replace('/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/mi', '', $html);
56        $cleanHtml = preg_replace('/<style\b[^<]*(?:(?!<\/style>)<[^<]*)*<\/style>/mi', '', $cleanHtml);
57        
58        // Try to extract content from Belga-specific document section
59        if (preg_match('/<section[^>]*class="[^"]*prezly-slate-document[^"]*"[^>]*>(.*?)<\/section>/is', $cleanHtml, $sectionMatches)) {
60            $sectionHtml = $sectionMatches[1];
61            preg_match_all('/<p[^>]*>(.*?)<\/p>/is', $sectionHtml, $matches);
62        } else {
63            // Fallback: Extract all paragraph content
64            preg_match_all('/<p[^>]*>(.*?)<\/p>/is', $cleanHtml, $matches);
65        }
66        
67        if (!empty($matches[1])) {
68            $paragraphs = array_map(function($paragraph) {
69                return html_entity_decode(strip_tags($paragraph), ENT_QUOTES, 'UTF-8');
70            }, $matches[1]);
71            
72            // Filter out empty paragraphs and join with double newlines
73            $fullText = implode("\n\n", array_filter($paragraphs, function($p) {
74                return trim($p) !== '';
75            }));
76            
77            return $fullText ?: null;
78        }
79        
80        return null;
81    }
82    
83    public static function extractThumbnail(string $html): ?string
84    {
85        // Try OpenGraph image first
86        if (preg_match('/<meta property="og:image" content="([^"]+)"/i', $html, $matches)) {
87            return $matches[1];
88        }
89        
90        // Try first image in article content
91        if (preg_match('/<img[^>]+src="([^"]+)"/i', $html, $matches)) {
92            return $matches[1];
93        }
94        
95        return null;
96    }
97
98    /**
99     * @return array<string, string|null>
100     */
101    public static function extractData(string $html): array
102    {
103        return [
104            'title' => self::extractTitle($html),
105            'description' => self::extractDescription($html),
106            'full_article' => self::extractFullArticle($html),
107            'thumbnail' => self::extractThumbnail($html),
108        ];
109    }
110}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 19:15:34 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report/Services/Parsers/BelgaArticleParser.php.html b/backend/coverage-report/Services/Parsers/BelgaArticleParser.php.html deleted file mode 100644 index 1dd317df..00000000 --- a/backend/coverage-report/Services/Parsers/BelgaArticleParser.php.html +++ /dev/null @@ -1,220 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Services/Parsers/BelgaArticleParser.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 33.33% covered (danger) -
-
-
33.33%
1 / 3
-
- 33.33% covered (danger) -
-
-
33.33%
1 / 3
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
BelgaArticleParser
-
- 33.33% covered (danger) -
-
-
33.33%
1 / 3
-
- 33.33% covered (danger) -
-
-
33.33%
1 / 3
5.67
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 canParse
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
1
 extractData
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 getSourceName
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Services\Parsers;
4
5use App\Contracts\ArticleParserInterface;
6
7class BelgaArticleParser implements ArticleParserInterface
8{
9    public function canParse(string $url): bool
10    {
11        return str_contains($url, 'belganewsagency.eu');
12    }
13
14    public function extractData(string $html): array
15    {
16        return BelgaArticlePageParser::extractData($html);
17    }
18
19    public function getSourceName(): string
20    {
21        return 'Belga News Agency';
22    }
23}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 19:15:34 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report/Services/Parsers/BelgaHomepageParser.php.html b/backend/coverage-report/Services/Parsers/BelgaHomepageParser.php.html deleted file mode 100644 index 714d9cb6..00000000 --- a/backend/coverage-report/Services/Parsers/BelgaHomepageParser.php.html +++ /dev/null @@ -1,173 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Services/Parsers/BelgaHomepageParser.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 5
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
BelgaHomepageParser
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 5
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 extractArticleUrls
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 5
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Services\Parsers;
4
5class BelgaHomepageParser
6{
7    /**
8     * @return array<int, string>
9     */
10    public static function extractArticleUrls(string $html): array
11    {
12        preg_match_all('/href="(https:\/\/www\.belganewsagency\.eu\/[a-z0-9-]+)"/', $html, $matches);
13
14        $urls = collect($matches[1])
15            ->unique()
16            ->toArray();
17
18        return $urls;
19    }
20}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 19:15:34 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report/Services/Parsers/BelgaHomepageParserAdapter.php.html b/backend/coverage-report/Services/Parsers/BelgaHomepageParserAdapter.php.html deleted file mode 100644 index 59f0b04a..00000000 --- a/backend/coverage-report/Services/Parsers/BelgaHomepageParserAdapter.php.html +++ /dev/null @@ -1,247 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Services/Parsers/BelgaHomepageParserAdapter.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 25.00% covered (danger) -
-
-
25.00%
1 / 4
-
- 25.00% covered (danger) -
-
-
25.00%
1 / 4
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
BelgaHomepageParserAdapter
-
- 25.00% covered (danger) -
-
-
25.00%
1 / 4
-
- 25.00% covered (danger) -
-
-
25.00%
1 / 4
10.75
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 canParse
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
1
 extractArticleUrls
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 getHomepageUrl
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 getSourceName
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Services\Parsers;
4
5use App\Contracts\HomepageParserInterface;
6
7class BelgaHomepageParserAdapter implements HomepageParserInterface
8{
9    public function canParse(string $url): bool
10    {
11        return str_contains($url, 'belganewsagency.eu');
12    }
13
14    public function extractArticleUrls(string $html): array
15    {
16        return BelgaHomepageParser::extractArticleUrls($html);
17    }
18
19    public function getHomepageUrl(): string
20    {
21        return 'https://www.belganewsagency.eu/';
22    }
23
24    public function getSourceName(): string
25    {
26        return 'Belga News Agency';
27    }
28}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 19:15:34 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report/Services/Parsers/VrtArticlePageParser.php.html b/backend/coverage-report/Services/Parsers/VrtArticlePageParser.php.html deleted file mode 100644 index f766017a..00000000 --- a/backend/coverage-report/Services/Parsers/VrtArticlePageParser.php.html +++ /dev/null @@ -1,333 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Services/Parsers/VrtArticlePageParser.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 35
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 5
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
VrtArticlePageParser
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 35
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 5
210
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 extractTitle
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 7
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
20
 extractDescription
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 5
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
12
 extractFullArticle
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 12
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
12
 extractThumbnail
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 5
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
12
 extractData
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 6
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Services\Parsers;
4
5class VrtArticlePageParser
6{
7    public static function extractTitle(string $html): ?string
8    {
9        // Try meta title first
10        if (preg_match('/<meta property="og:title" content="([^"]+)"/i', $html, $matches)) {
11            return html_entity_decode($matches[1], ENT_QUOTES, 'UTF-8');
12        }
13
14        // Try h1 tag
15        if (preg_match('/<h1[^>]*>([^<]+)<\/h1>/i', $html, $matches)) {
16            return html_entity_decode(strip_tags($matches[1]), ENT_QUOTES, 'UTF-8');
17        }
18
19        // Try title tag
20        if (preg_match('/<title>([^<]+)<\/title>/i', $html, $matches)) {
21            return html_entity_decode($matches[1], ENT_QUOTES, 'UTF-8');
22        }
23
24        return null;
25    }
26
27    public static function extractDescription(string $html): ?string
28    {
29        // Try meta description first
30        if (preg_match('/<meta property="og:description" content="([^"]+)"/i', $html, $matches)) {
31            return html_entity_decode($matches[1], ENT_QUOTES, 'UTF-8');
32        }
33
34        // Try to find first paragraph in article content
35        if (preg_match('/<p[^>]*>([^<]+(?:<[^\/](?!p)[^>]*>[^<]*<\/[^>]*>[^<]*)*)<\/p>/i', $html, $matches)) {
36            return html_entity_decode(strip_tags($matches[1]), ENT_QUOTES, 'UTF-8');
37        }
38
39        return null;
40    }
41
42    public static function extractFullArticle(string $html): ?string
43    {
44        // Remove scripts, styles, and other non-content elements
45        $cleanHtml = preg_replace('/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/mi', '', $html);
46        $cleanHtml = preg_replace('/<style\b[^<]*(?:(?!<\/style>)<[^<]*)*<\/style>/mi', '', $cleanHtml);
47
48        // Extract all paragraph content
49        preg_match_all('/<p[^>]*>(.*?)<\/p>/is', $cleanHtml, $matches);
50
51        if (!empty($matches[1])) {
52            $paragraphs = array_map(function($paragraph) {
53                return html_entity_decode(strip_tags($paragraph), ENT_QUOTES, 'UTF-8');
54            }, $matches[1]);
55
56            // Filter out empty paragraphs and join with double newlines
57            $fullText = implode("\n\n", array_filter($paragraphs, function($p) {
58                return trim($p) !== '';
59            }));
60
61            return $fullText ?: null;
62        }
63
64        return null;
65    }
66
67    public static function extractThumbnail(string $html): ?string
68    {
69        if (preg_match('/<meta property="og:image" content="([^"]+)"/i', $html, $matches)) {
70            return $matches[1];
71        }
72
73        if (preg_match('/<img[^>]+src="([^"]+)"/i', $html, $matches)) {
74            return $matches[1];
75        }
76
77        return null;
78    }
79
80    /**
81     * @return array<string, string|null>
82     */
83    public static function extractData(string $html): array
84    {
85        return [
86            'title' => self::extractTitle($html),
87            'description' => self::extractDescription($html),
88            'full_article' => self::extractFullArticle($html),
89            'thumbnail' => self::extractThumbnail($html),
90        ];
91    }
92}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 19:15:34 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report/Services/Parsers/VrtArticleParser.php.html b/backend/coverage-report/Services/Parsers/VrtArticleParser.php.html deleted file mode 100644 index 209a8c85..00000000 --- a/backend/coverage-report/Services/Parsers/VrtArticleParser.php.html +++ /dev/null @@ -1,220 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Services/Parsers/VrtArticleParser.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 33.33% covered (danger) -
-
-
33.33%
1 / 3
-
- 33.33% covered (danger) -
-
-
33.33%
1 / 3
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
VrtArticleParser
-
- 33.33% covered (danger) -
-
-
33.33%
1 / 3
-
- 33.33% covered (danger) -
-
-
33.33%
1 / 3
5.67
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 canParse
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
1
 extractData
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 getSourceName
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Services\Parsers;
4
5use App\Contracts\ArticleParserInterface;
6
7class VrtArticleParser implements ArticleParserInterface
8{
9    public function canParse(string $url): bool
10    {
11        return str_contains($url, 'vrt.be');
12    }
13
14    public function extractData(string $html): array
15    {
16        return VrtArticlePageParser::extractData($html);
17    }
18
19    public function getSourceName(): string
20    {
21        return 'VRT News';
22    }
23}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 19:15:34 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report/Services/Parsers/VrtHomepageParser.php.html b/backend/coverage-report/Services/Parsers/VrtHomepageParser.php.html deleted file mode 100644 index b782f734..00000000 --- a/backend/coverage-report/Services/Parsers/VrtHomepageParser.php.html +++ /dev/null @@ -1,175 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Services/Parsers/VrtHomepageParser.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 6
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
VrtHomepageParser
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 6
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 extractArticleUrls
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 6
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Services\Parsers;
4
5class VrtHomepageParser
6{
7    /**
8     * @return array<int, string>
9     */
10    public static function extractArticleUrls(string $html): array
11    {
12        // Extract article links using regex
13        preg_match_all('/href="(\/vrtnws\/en\/\d{4}\/\d{2}\/\d{2}\/[^"]+)"/', $html, $matches);
14
15        $urls = collect($matches[1])
16            ->unique()
17            ->map(fn ($path) => 'https://www.vrt.be' . $path)
18            ->toArray();
19
20        return $urls;
21    }
22}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 19:15:34 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report/Services/Parsers/VrtHomepageParserAdapter.php.html b/backend/coverage-report/Services/Parsers/VrtHomepageParserAdapter.php.html deleted file mode 100644 index 5c21b893..00000000 --- a/backend/coverage-report/Services/Parsers/VrtHomepageParserAdapter.php.html +++ /dev/null @@ -1,247 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Services/Parsers/VrtHomepageParserAdapter.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 25.00% covered (danger) -
-
-
25.00%
1 / 4
-
- 25.00% covered (danger) -
-
-
25.00%
1 / 4
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
VrtHomepageParserAdapter
-
- 25.00% covered (danger) -
-
-
25.00%
1 / 4
-
- 25.00% covered (danger) -
-
-
25.00%
1 / 4
10.75
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 canParse
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
1
 extractArticleUrls
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 getHomepageUrl
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
 getSourceName
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Services\Parsers;
4
5use App\Contracts\HomepageParserInterface;
6
7class VrtHomepageParserAdapter implements HomepageParserInterface
8{
9    public function canParse(string $url): bool
10    {
11        return str_contains($url, 'vrt.be');
12    }
13
14    public function extractArticleUrls(string $html): array
15    {
16        return VrtHomepageParser::extractArticleUrls($html);
17    }
18
19    public function getHomepageUrl(): string
20    {
21        return 'https://www.vrt.be/vrtnws/en/';
22    }
23
24    public function getSourceName(): string
25    {
26        return 'VRT News';
27    }
28}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 19:15:34 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report/Services/Parsers/dashboard.html b/backend/coverage-report/Services/Parsers/dashboard.html deleted file mode 100644 index ce8138fd..00000000 --- a/backend/coverage-report/Services/Parsers/dashboard.html +++ /dev/null @@ -1,325 +0,0 @@ - - - - - Dashboard for /var/www/html/backend/app/Services/Parsers - - - - - - - -
-
-
-
- -
-
-
-
-
-
-
-

Classes

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
- -
-
-

Methods

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
- - -
- - - - - - diff --git a/backend/coverage-report/Services/Parsers/index.html b/backend/coverage-report/Services/Parsers/index.html deleted file mode 100644 index d97e0432..00000000 --- a/backend/coverage-report/Services/Parsers/index.html +++ /dev/null @@ -1,316 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Services/Parsers - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 3.92% covered (danger) -
-
-
3.92%
4 / 102
-
- 15.38% covered (danger) -
-
-
15.38%
4 / 26
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 8
BelgaArticlePageParser.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 42
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 5
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
BelgaArticleParser.php
-
- 33.33% covered (danger) -
-
-
33.33%
1 / 3
-
- 33.33% covered (danger) -
-
-
33.33%
1 / 3
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
BelgaHomepageParser.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 5
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
BelgaHomepageParserAdapter.php
-
- 25.00% covered (danger) -
-
-
25.00%
1 / 4
-
- 25.00% covered (danger) -
-
-
25.00%
1 / 4
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
VrtArticlePageParser.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 35
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 5
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
VrtArticleParser.php
-
- 33.33% covered (danger) -
-
-
33.33%
1 / 3
-
- 33.33% covered (danger) -
-
-
33.33%
1 / 3
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
VrtHomepageParser.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 6
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
VrtHomepageParserAdapter.php
-
- 25.00% covered (danger) -
-
-
25.00%
1 / 4
-
- 25.00% covered (danger) -
-
-
25.00%
1 / 4
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- -
- - diff --git a/backend/coverage-report/Services/Publishing/ArticlePublishingService.php.html b/backend/coverage-report/Services/Publishing/ArticlePublishingService.php.html deleted file mode 100644 index 5ec393aa..00000000 --- a/backend/coverage-report/Services/Publishing/ArticlePublishingService.php.html +++ /dev/null @@ -1,260 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Services/Publishing/ArticlePublishingService.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 36
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
ArticlePublishingService
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 36
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
30
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 publishToRoutedChannels
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 14
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
12
 publishToChannel
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 22
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
6
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Services\Publishing;
4
5use App\Enums\PlatformEnum;
6use App\Exceptions\PublishException;
7use App\Models\Article;
8use App\Models\ArticlePublication;
9use App\Models\PlatformChannel;
10use App\Modules\Lemmy\Services\LemmyPublisher;
11use App\Services\Log\LogSaver;
12use Exception;
13use Illuminate\Database\Eloquent\Collection as EloquentCollection;
14use Illuminate\Support\Collection;
15use RuntimeException;
16
17class ArticlePublishingService
18{
19    /**
20     * @param array<string, mixed> $extractedData
21     * @return EloquentCollection<int, ArticlePublication>
22     * @throws PublishException
23     */
24    public function publishToRoutedChannels(Article $article, array $extractedData): EloquentCollection
25    {
26        if (! $article->is_valid) {
27            throw new PublishException($article, PlatformEnum::LEMMY, new RuntimeException('CANNOT_PUBLISH_INVALID_ARTICLE'));
28        }
29
30        $feed = $article->feed;
31        
32        /** @var EloquentCollection<int, PlatformChannel> $activeChannels */
33        $activeChannels = $feed->activeChannels()->with(['platformInstance', 'activePlatformAccounts'])->get();
34
35        return $activeChannels->map(function (PlatformChannel $channel) use ($article, $extractedData) {
36            $account = $channel->activePlatformAccounts()->first();
37
38            if (! $account) {
39                LogSaver::warning('No active account for channel', $channel, [
40                    'article_id' => $article->id
41                ]);
42
43                return null;
44            }
45
46            return $this->publishToChannel($article, $extractedData, $channel, $account);
47        })
48        ->filter();
49    }
50
51    /**
52     * @param array<string, mixed> $extractedData
53     */
54    private function publishToChannel(Article $article, array $extractedData, PlatformChannel $channel, mixed $account): ?ArticlePublication
55    {
56        try {
57            $publisher = new LemmyPublisher($account);
58            $postData = $publisher->publishToChannel($article, $extractedData, $channel);
59
60            $publication = ArticlePublication::create([
61                'article_id' => $article->id,
62                'post_id' => $postData['post_view']['post']['id'],
63                'platform_channel_id' => $channel->id,
64                'published_by' => $account->username,
65                'published_at' => now(),
66                'platform' => $channel->platformInstance->platform->value,
67                'publication_data' => $postData,
68            ]);
69
70            LogSaver::info('Published to channel via routing', $channel, [
71                'article_id' => $article->id,
72                'priority' => $channel->pivot->priority ?? null
73            ]);
74
75            return $publication;
76        } catch (Exception $e) {
77            LogSaver::warning('Failed to publish to channel', $channel, [
78                'article_id' => $article->id,
79                'error' => $e->getMessage()
80            ]);
81
82            return null;
83        }
84    }
85}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 19:15:34 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report/Services/Publishing/dashboard.html b/backend/coverage-report/Services/Publishing/dashboard.html deleted file mode 100644 index 31197ece..00000000 --- a/backend/coverage-report/Services/Publishing/dashboard.html +++ /dev/null @@ -1,291 +0,0 @@ - - - - - Dashboard for /var/www/html/backend/app/Services/Publishing - - - - - - - -
-
-
-
- -
-
-
-
-
-
-
-

Classes

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
-
-
-

Insufficient Coverage

-
- - - - - - - - - - - -
ClassCoverage
App\Services\Publishing\ArticlePublishingService0%
-
-
-
-

Project Risks

-
- - - - - - - - - - - -
ClassCRAP
App\Services\Publishing\ArticlePublishingService30
-
-
-
-
-
-

Methods

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
-
-
-

Insufficient Coverage

-
- - - - - - - - - - - - -
MethodCoverage
publishToRoutedChannels0%
publishToChannel0%
-
-
-
-

Project Risks

-
- - - - - - - - - - - - -
MethodCRAP
publishToRoutedChannels12
publishToChannel6
-
-
-
- -
- - - - - - diff --git a/backend/coverage-report/Services/Publishing/index.html b/backend/coverage-report/Services/Publishing/index.html deleted file mode 100644 index f805620f..00000000 --- a/backend/coverage-report/Services/Publishing/index.html +++ /dev/null @@ -1,120 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Services/Publishing - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 36
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
ArticlePublishingService.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 36
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- -
- - diff --git a/backend/coverage-report/Services/RoutingValidationService.php.html b/backend/coverage-report/Services/RoutingValidationService.php.html deleted file mode 100644 index 352e2a09..00000000 --- a/backend/coverage-report/Services/RoutingValidationService.php.html +++ /dev/null @@ -1,184 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Services/RoutingValidationService.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 7
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
RoutingValidationService
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 7
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
30
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 validateLanguageCompatibility
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 7
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
30
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Services;
4
5use App\Exceptions\RoutingMismatchException;
6use App\Models\Feed;
7use App\Models\PlatformChannel;
8use Illuminate\Support\Collection;
9
10class RoutingValidationService
11{
12    /**
13     * @param Collection<int, PlatformChannel> $channels
14     * @throws RoutingMismatchException
15     */
16    public function validateLanguageCompatibility(Feed $feed, Collection $channels): void
17    {
18        if (! $feed->language) {
19            return;
20        }
21
22        foreach ($channels as $channel) {
23            if (! $channel->language) {
24                continue;
25            }
26
27            if ($feed->language !== $channel->language) {
28                throw new RoutingMismatchException($feed, $channel);
29            }
30        }
31    }
32}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 19:15:34 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report/Services/SystemStatusService.php.html b/backend/coverage-report/Services/SystemStatusService.php.html deleted file mode 100644 index e047639f..00000000 --- a/backend/coverage-report/Services/SystemStatusService.php.html +++ /dev/null @@ -1,226 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Services/SystemStatusService.php - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 21
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
CRAP
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
SystemStatusService
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 21
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
72
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
 getSystemStatus
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 20
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
56
 canProcessArticles
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
2
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1<?php
2
3namespace App\Services;
4
5use App\Models\Feed;
6use App\Models\Route;
7use App\Models\PlatformChannel;
8use App\Models\Setting;
9
10class SystemStatusService
11{
12    /**
13     * @return array{is_enabled: bool, status: string, status_class: string, reasons: array<int, string>}
14     */
15    public function getSystemStatus(): array
16    {
17        $reasons = [];
18        $isEnabled = true;
19
20        if (!Setting::isArticleProcessingEnabled()) {
21            $isEnabled = false;
22            $reasons[] = 'Manually disabled by user';
23        }
24
25        if (!Feed::where('is_active', true)->exists()) {
26            $isEnabled = false;
27            $reasons[] = 'No active feeds configured';
28        }
29
30        if (!PlatformChannel::where('is_active', true)->exists()) {
31            $isEnabled = false;
32            $reasons[] = 'No active platform channels configured';
33        }
34
35        if (!Route::where('is_active', true)->exists()) {
36            $isEnabled = false;
37            $reasons[] = 'No active feed-to-channel routes configured';
38        }
39
40        return [
41            'is_enabled' => $isEnabled,
42            'status' => $isEnabled ? 'Enabled' : 'Disabled',
43            'status_class' => $isEnabled ? 'text-green-600' : 'text-red-600',
44            'reasons' => $reasons,
45        ];
46    }
47
48    public function canProcessArticles(): bool
49    {
50        return $this->getSystemStatus()['is_enabled'];
51    }
52}
- - -
-
-

Legend

-

Covered by small (and larger) testsCovered by medium (and large) testsCovered by large tests (and tests of unknown size)Not coveredNot coverable

-

- Generated by php-code-coverage 11.0.10 using PHP 8.4.10 and PHPUnit 11.5.28 at Sun Aug 3 19:15:34 UTC 2025. -

- - - -
-
- - - - - diff --git a/backend/coverage-report/Services/dashboard.html b/backend/coverage-report/Services/dashboard.html deleted file mode 100644 index fc2184d2..00000000 --- a/backend/coverage-report/Services/dashboard.html +++ /dev/null @@ -1,383 +0,0 @@ - - - - - Dashboard for /var/www/html/backend/app/Services - - - - - - - -
-
-
-
- -
-
-
-
-
-
-
-

Classes

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
- -
-
-

Methods

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
- - -
- - - - - - diff --git a/backend/coverage-report/Services/index.html b/backend/coverage-report/Services/index.html deleted file mode 100644 index b2fcf4ad..00000000 --- a/backend/coverage-report/Services/index.html +++ /dev/null @@ -1,399 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app/Services - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 28.84% covered (danger) -
-
-
28.84%
107 / 371
-
- 25.00% covered (danger) -
-
-
25.00%
14 / 56
-
- 5.00% covered (danger) -
-
-
5.00%
1 / 20
Article
-
- 46.38% covered (danger) -
-
-
46.38%
32 / 69
-
- 14.29% covered (danger) -
-
-
14.29%
1 / 7
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
Auth
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 12
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
Factories
-
- 57.89% covered (warning) -
-
-
57.89%
11 / 19
-
- 20.00% covered (danger) -
-
-
20.00%
1 / 5
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
Http
-
- 22.73% covered (danger) -
-
-
22.73%
10 / 44
-
- 50.00% covered (danger) -
-
-
50.00%
1 / 2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
Log
-
- 58.82% covered (warning) -
-
-
58.82%
10 / 17
-
- 60.00% covered (warning) -
-
-
60.00%
3 / 5
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
Parsers
-
- 3.92% covered (danger) -
-
-
3.92%
4 / 102
-
- 15.38% covered (danger) -
-
-
15.38%
4 / 26
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 8
Publishing
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 36
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
DashboardStatsService.php
-
- 100.00% covered (success) -
-
-
100.00%
40 / 40
-
- 100.00% covered (success) -
-
-
100.00%
4 / 4
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
OnboardingRedirectService.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 4
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
RoutingValidationService.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 7
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
SystemStatusService.php
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 21
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 1
-
- -
- - diff --git a/backend/coverage-report/_css/bootstrap.min.css b/backend/coverage-report/_css/bootstrap.min.css deleted file mode 100644 index 27d4921c..00000000 --- a/backend/coverage-report/_css/bootstrap.min.css +++ /dev/null @@ -1,6 +0,0 @@ -@charset "UTF-8";/*! - * Bootstrap v5.3.6 (https://getbootstrap.com/) - * Copyright 2011-2025 The Bootstrap Authors - * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) - */:root,[data-bs-theme=light]{--bs-blue:#0d6efd;--bs-indigo:#6610f2;--bs-purple:#6f42c1;--bs-pink:#d63384;--bs-red:#dc3545;--bs-orange:#fd7e14;--bs-yellow:#ffc107;--bs-green:#198754;--bs-teal:#20c997;--bs-cyan:#0dcaf0;--bs-black:#000;--bs-white:#fff;--bs-gray:#6c757d;--bs-gray-dark:#343a40;--bs-gray-100:#f8f9fa;--bs-gray-200:#e9ecef;--bs-gray-300:#dee2e6;--bs-gray-400:#ced4da;--bs-gray-500:#adb5bd;--bs-gray-600:#6c757d;--bs-gray-700:#495057;--bs-gray-800:#343a40;--bs-gray-900:#212529;--bs-primary:#0d6efd;--bs-secondary:#6c757d;--bs-success:#198754;--bs-info:#0dcaf0;--bs-warning:#ffc107;--bs-danger:#dc3545;--bs-light:#f8f9fa;--bs-dark:#212529;--bs-primary-rgb:13,110,253;--bs-secondary-rgb:108,117,125;--bs-success-rgb:25,135,84;--bs-info-rgb:13,202,240;--bs-warning-rgb:255,193,7;--bs-danger-rgb:220,53,69;--bs-light-rgb:248,249,250;--bs-dark-rgb:33,37,41;--bs-primary-text-emphasis:#052c65;--bs-secondary-text-emphasis:#2b2f32;--bs-success-text-emphasis:#0a3622;--bs-info-text-emphasis:#055160;--bs-warning-text-emphasis:#664d03;--bs-danger-text-emphasis:#58151c;--bs-light-text-emphasis:#495057;--bs-dark-text-emphasis:#495057;--bs-primary-bg-subtle:#cfe2ff;--bs-secondary-bg-subtle:#e2e3e5;--bs-success-bg-subtle:#d1e7dd;--bs-info-bg-subtle:#cff4fc;--bs-warning-bg-subtle:#fff3cd;--bs-danger-bg-subtle:#f8d7da;--bs-light-bg-subtle:#fcfcfd;--bs-dark-bg-subtle:#ced4da;--bs-primary-border-subtle:#9ec5fe;--bs-secondary-border-subtle:#c4c8cb;--bs-success-border-subtle:#a3cfbb;--bs-info-border-subtle:#9eeaf9;--bs-warning-border-subtle:#ffe69c;--bs-danger-border-subtle:#f1aeb5;--bs-light-border-subtle:#e9ecef;--bs-dark-border-subtle:#adb5bd;--bs-white-rgb:255,255,255;--bs-black-rgb:0,0,0;--bs-font-sans-serif:system-ui,-apple-system,"Segoe UI",Roboto,"Helvetica Neue","Noto Sans","Liberation Sans",Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";--bs-font-monospace:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;--bs-gradient:linear-gradient(180deg, rgba(255, 255, 255, 0.15), rgba(255, 255, 255, 0));--bs-body-font-family:var(--bs-font-sans-serif);--bs-body-font-size:1rem;--bs-body-font-weight:400;--bs-body-line-height:1.5;--bs-body-color:#212529;--bs-body-color-rgb:33,37,41;--bs-body-bg:#fff;--bs-body-bg-rgb:255,255,255;--bs-emphasis-color:#000;--bs-emphasis-color-rgb:0,0,0;--bs-secondary-color:rgba(33, 37, 41, 0.75);--bs-secondary-color-rgb:33,37,41;--bs-secondary-bg:#e9ecef;--bs-secondary-bg-rgb:233,236,239;--bs-tertiary-color:rgba(33, 37, 41, 0.5);--bs-tertiary-color-rgb:33,37,41;--bs-tertiary-bg:#f8f9fa;--bs-tertiary-bg-rgb:248,249,250;--bs-heading-color:inherit;--bs-link-color:#0d6efd;--bs-link-color-rgb:13,110,253;--bs-link-decoration:underline;--bs-link-hover-color:#0a58ca;--bs-link-hover-color-rgb:10,88,202;--bs-code-color:#d63384;--bs-highlight-color:#212529;--bs-highlight-bg:#fff3cd;--bs-border-width:1px;--bs-border-style:solid;--bs-border-color:#dee2e6;--bs-border-color-translucent:rgba(0, 0, 0, 0.175);--bs-border-radius:0.375rem;--bs-border-radius-sm:0.25rem;--bs-border-radius-lg:0.5rem;--bs-border-radius-xl:1rem;--bs-border-radius-xxl:2rem;--bs-border-radius-2xl:var(--bs-border-radius-xxl);--bs-border-radius-pill:50rem;--bs-box-shadow:0 0.5rem 1rem rgba(0, 0, 0, 0.15);--bs-box-shadow-sm:0 0.125rem 0.25rem rgba(0, 0, 0, 0.075);--bs-box-shadow-lg:0 1rem 3rem rgba(0, 0, 0, 0.175);--bs-box-shadow-inset:inset 0 1px 2px rgba(0, 0, 0, 0.075);--bs-focus-ring-width:0.25rem;--bs-focus-ring-opacity:0.25;--bs-focus-ring-color:rgba(13, 110, 253, 0.25);--bs-form-valid-color:#198754;--bs-form-valid-border-color:#198754;--bs-form-invalid-color:#dc3545;--bs-form-invalid-border-color:#dc3545}[data-bs-theme=dark]{color-scheme:dark;--bs-body-color:#dee2e6;--bs-body-color-rgb:222,226,230;--bs-body-bg:#212529;--bs-body-bg-rgb:33,37,41;--bs-emphasis-color:#fff;--bs-emphasis-color-rgb:255,255,255;--bs-secondary-color:rgba(222, 226, 230, 0.75);--bs-secondary-color-rgb:222,226,230;--bs-secondary-bg:#343a40;--bs-secondary-bg-rgb:52,58,64;--bs-tertiary-color:rgba(222, 226, 230, 0.5);--bs-tertiary-color-rgb:222,226,230;--bs-tertiary-bg:#2b3035;--bs-tertiary-bg-rgb:43,48,53;--bs-primary-text-emphasis:#6ea8fe;--bs-secondary-text-emphasis:#a7acb1;--bs-success-text-emphasis:#75b798;--bs-info-text-emphasis:#6edff6;--bs-warning-text-emphasis:#ffda6a;--bs-danger-text-emphasis:#ea868f;--bs-light-text-emphasis:#f8f9fa;--bs-dark-text-emphasis:#dee2e6;--bs-primary-bg-subtle:#031633;--bs-secondary-bg-subtle:#161719;--bs-success-bg-subtle:#051b11;--bs-info-bg-subtle:#032830;--bs-warning-bg-subtle:#332701;--bs-danger-bg-subtle:#2c0b0e;--bs-light-bg-subtle:#343a40;--bs-dark-bg-subtle:#1a1d20;--bs-primary-border-subtle:#084298;--bs-secondary-border-subtle:#41464b;--bs-success-border-subtle:#0f5132;--bs-info-border-subtle:#087990;--bs-warning-border-subtle:#997404;--bs-danger-border-subtle:#842029;--bs-light-border-subtle:#495057;--bs-dark-border-subtle:#343a40;--bs-heading-color:inherit;--bs-link-color:#6ea8fe;--bs-link-hover-color:#8bb9fe;--bs-link-color-rgb:110,168,254;--bs-link-hover-color-rgb:139,185,254;--bs-code-color:#e685b5;--bs-highlight-color:#dee2e6;--bs-highlight-bg:#664d03;--bs-border-color:#495057;--bs-border-color-translucent:rgba(255, 255, 255, 0.15);--bs-form-valid-color:#75b798;--bs-form-valid-border-color:#75b798;--bs-form-invalid-color:#ea868f;--bs-form-invalid-border-color:#ea868f}*,::after,::before{box-sizing:border-box}@media (prefers-reduced-motion:no-preference){:root{scroll-behavior:smooth}}body{margin:0;font-family:var(--bs-body-font-family);font-size:var(--bs-body-font-size);font-weight:var(--bs-body-font-weight);line-height:var(--bs-body-line-height);color:var(--bs-body-color);text-align:var(--bs-body-text-align);background-color:var(--bs-body-bg);-webkit-text-size-adjust:100%;-webkit-tap-highlight-color:transparent}hr{margin:1rem 0;color:inherit;border:0;border-top:var(--bs-border-width) solid;opacity:.25}.h1,.h2,.h3,.h4,.h5,.h6,h1,h2,h3,h4,h5,h6{margin-top:0;margin-bottom:.5rem;font-weight:500;line-height:1.2;color:var(--bs-heading-color)}.h1,h1{font-size:calc(1.375rem + 1.5vw)}@media (min-width:1200px){.h1,h1{font-size:2.5rem}}.h2,h2{font-size:calc(1.325rem + .9vw)}@media (min-width:1200px){.h2,h2{font-size:2rem}}.h3,h3{font-size:calc(1.3rem + .6vw)}@media (min-width:1200px){.h3,h3{font-size:1.75rem}}.h4,h4{font-size:calc(1.275rem + .3vw)}@media (min-width:1200px){.h4,h4{font-size:1.5rem}}.h5,h5{font-size:1.25rem}.h6,h6{font-size:1rem}p{margin-top:0;margin-bottom:1rem}abbr[title]{-webkit-text-decoration:underline dotted;text-decoration:underline dotted;cursor:help;-webkit-text-decoration-skip-ink:none;text-decoration-skip-ink:none}address{margin-bottom:1rem;font-style:normal;line-height:inherit}ol,ul{padding-left:2rem}dl,ol,ul{margin-top:0;margin-bottom:1rem}ol ol,ol ul,ul ol,ul ul{margin-bottom:0}dt{font-weight:700}dd{margin-bottom:.5rem;margin-left:0}blockquote{margin:0 0 1rem}b,strong{font-weight:bolder}.small,small{font-size:.875em}.mark,mark{padding:.1875em;color:var(--bs-highlight-color);background-color:var(--bs-highlight-bg)}sub,sup{position:relative;font-size:.75em;line-height:0;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}a{color:rgba(var(--bs-link-color-rgb),var(--bs-link-opacity,1));text-decoration:underline}a:hover{--bs-link-color-rgb:var(--bs-link-hover-color-rgb)}a:not([href]):not([class]),a:not([href]):not([class]):hover{color:inherit;text-decoration:none}code,kbd,pre,samp{font-family:var(--bs-font-monospace);font-size:1em}pre{display:block;margin-top:0;margin-bottom:1rem;overflow:auto;font-size:.875em}pre code{font-size:inherit;color:inherit;word-break:normal}code{font-size:.875em;color:var(--bs-code-color);word-wrap:break-word}a>code{color:inherit}kbd{padding:.1875rem .375rem;font-size:.875em;color:var(--bs-body-bg);background-color:var(--bs-body-color);border-radius:.25rem}kbd kbd{padding:0;font-size:1em}figure{margin:0 0 1rem}img,svg{vertical-align:middle}table{caption-side:bottom;border-collapse:collapse}caption{padding-top:.5rem;padding-bottom:.5rem;color:var(--bs-secondary-color);text-align:left}th{text-align:inherit;text-align:-webkit-match-parent}tbody,td,tfoot,th,thead,tr{border-color:inherit;border-style:solid;border-width:0}label{display:inline-block}button{border-radius:0}button:focus:not(:focus-visible){outline:0}button,input,optgroup,select,textarea{margin:0;font-family:inherit;font-size:inherit;line-height:inherit}button,select{text-transform:none}[role=button]{cursor:pointer}select{word-wrap:normal}select:disabled{opacity:1}[list]:not([type=date]):not([type=datetime-local]):not([type=month]):not([type=week]):not([type=time])::-webkit-calendar-picker-indicator{display:none!important}[type=button],[type=reset],[type=submit],button{-webkit-appearance:button}[type=button]:not(:disabled),[type=reset]:not(:disabled),[type=submit]:not(:disabled),button:not(:disabled){cursor:pointer}::-moz-focus-inner{padding:0;border-style:none}textarea{resize:vertical}fieldset{min-width:0;padding:0;margin:0;border:0}legend{float:left;width:100%;padding:0;margin-bottom:.5rem;line-height:inherit;font-size:calc(1.275rem + .3vw)}@media (min-width:1200px){legend{font-size:1.5rem}}legend+*{clear:left}::-webkit-datetime-edit-day-field,::-webkit-datetime-edit-fields-wrapper,::-webkit-datetime-edit-hour-field,::-webkit-datetime-edit-minute,::-webkit-datetime-edit-month-field,::-webkit-datetime-edit-text,::-webkit-datetime-edit-year-field{padding:0}::-webkit-inner-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-color-swatch-wrapper{padding:0}::-webkit-file-upload-button{font:inherit;-webkit-appearance:button}::file-selector-button{font:inherit;-webkit-appearance:button}output{display:inline-block}iframe{border:0}summary{display:list-item;cursor:pointer}progress{vertical-align:baseline}[hidden]{display:none!important}.lead{font-size:1.25rem;font-weight:300}.display-1{font-weight:300;line-height:1.2;font-size:calc(1.625rem + 4.5vw)}@media (min-width:1200px){.display-1{font-size:5rem}}.display-2{font-weight:300;line-height:1.2;font-size:calc(1.575rem + 3.9vw)}@media (min-width:1200px){.display-2{font-size:4.5rem}}.display-3{font-weight:300;line-height:1.2;font-size:calc(1.525rem + 3.3vw)}@media (min-width:1200px){.display-3{font-size:4rem}}.display-4{font-weight:300;line-height:1.2;font-size:calc(1.475rem + 2.7vw)}@media (min-width:1200px){.display-4{font-size:3.5rem}}.display-5{font-weight:300;line-height:1.2;font-size:calc(1.425rem + 2.1vw)}@media (min-width:1200px){.display-5{font-size:3rem}}.display-6{font-weight:300;line-height:1.2;font-size:calc(1.375rem + 1.5vw)}@media (min-width:1200px){.display-6{font-size:2.5rem}}.list-unstyled{padding-left:0;list-style:none}.list-inline{padding-left:0;list-style:none}.list-inline-item{display:inline-block}.list-inline-item:not(:last-child){margin-right:.5rem}.initialism{font-size:.875em;text-transform:uppercase}.blockquote{margin-bottom:1rem;font-size:1.25rem}.blockquote>:last-child{margin-bottom:0}.blockquote-footer{margin-top:-1rem;margin-bottom:1rem;font-size:.875em;color:#6c757d}.blockquote-footer::before{content:"— "}.img-fluid{max-width:100%;height:auto}.img-thumbnail{padding:.25rem;background-color:var(--bs-body-bg);border:var(--bs-border-width) solid var(--bs-border-color);border-radius:var(--bs-border-radius);max-width:100%;height:auto}.figure{display:inline-block}.figure-img{margin-bottom:.5rem;line-height:1}.figure-caption{font-size:.875em;color:var(--bs-secondary-color)}.container,.container-fluid,.container-lg,.container-md,.container-sm,.container-xl,.container-xxl{--bs-gutter-x:1.5rem;--bs-gutter-y:0;width:100%;padding-right:calc(var(--bs-gutter-x) * .5);padding-left:calc(var(--bs-gutter-x) * .5);margin-right:auto;margin-left:auto}@media (min-width:576px){.container,.container-sm{max-width:540px}}@media (min-width:768px){.container,.container-md,.container-sm{max-width:720px}}@media (min-width:992px){.container,.container-lg,.container-md,.container-sm{max-width:960px}}@media (min-width:1200px){.container,.container-lg,.container-md,.container-sm,.container-xl{max-width:1140px}}@media (min-width:1400px){.container,.container-lg,.container-md,.container-sm,.container-xl,.container-xxl{max-width:1320px}}:root{--bs-breakpoint-xs:0;--bs-breakpoint-sm:576px;--bs-breakpoint-md:768px;--bs-breakpoint-lg:992px;--bs-breakpoint-xl:1200px;--bs-breakpoint-xxl:1400px}.row{--bs-gutter-x:1.5rem;--bs-gutter-y:0;display:flex;flex-wrap:wrap;margin-top:calc(-1 * var(--bs-gutter-y));margin-right:calc(-.5 * var(--bs-gutter-x));margin-left:calc(-.5 * var(--bs-gutter-x))}.row>*{flex-shrink:0;width:100%;max-width:100%;padding-right:calc(var(--bs-gutter-x) * .5);padding-left:calc(var(--bs-gutter-x) * .5);margin-top:var(--bs-gutter-y)}.col{flex:1 0 0}.row-cols-auto>*{flex:0 0 auto;width:auto}.row-cols-1>*{flex:0 0 auto;width:100%}.row-cols-2>*{flex:0 0 auto;width:50%}.row-cols-3>*{flex:0 0 auto;width:33.33333333%}.row-cols-4>*{flex:0 0 auto;width:25%}.row-cols-5>*{flex:0 0 auto;width:20%}.row-cols-6>*{flex:0 0 auto;width:16.66666667%}.col-auto{flex:0 0 auto;width:auto}.col-1{flex:0 0 auto;width:8.33333333%}.col-2{flex:0 0 auto;width:16.66666667%}.col-3{flex:0 0 auto;width:25%}.col-4{flex:0 0 auto;width:33.33333333%}.col-5{flex:0 0 auto;width:41.66666667%}.col-6{flex:0 0 auto;width:50%}.col-7{flex:0 0 auto;width:58.33333333%}.col-8{flex:0 0 auto;width:66.66666667%}.col-9{flex:0 0 auto;width:75%}.col-10{flex:0 0 auto;width:83.33333333%}.col-11{flex:0 0 auto;width:91.66666667%}.col-12{flex:0 0 auto;width:100%}.offset-1{margin-left:8.33333333%}.offset-2{margin-left:16.66666667%}.offset-3{margin-left:25%}.offset-4{margin-left:33.33333333%}.offset-5{margin-left:41.66666667%}.offset-6{margin-left:50%}.offset-7{margin-left:58.33333333%}.offset-8{margin-left:66.66666667%}.offset-9{margin-left:75%}.offset-10{margin-left:83.33333333%}.offset-11{margin-left:91.66666667%}.g-0,.gx-0{--bs-gutter-x:0}.g-0,.gy-0{--bs-gutter-y:0}.g-1,.gx-1{--bs-gutter-x:0.25rem}.g-1,.gy-1{--bs-gutter-y:0.25rem}.g-2,.gx-2{--bs-gutter-x:0.5rem}.g-2,.gy-2{--bs-gutter-y:0.5rem}.g-3,.gx-3{--bs-gutter-x:1rem}.g-3,.gy-3{--bs-gutter-y:1rem}.g-4,.gx-4{--bs-gutter-x:1.5rem}.g-4,.gy-4{--bs-gutter-y:1.5rem}.g-5,.gx-5{--bs-gutter-x:3rem}.g-5,.gy-5{--bs-gutter-y:3rem}@media (min-width:576px){.col-sm{flex:1 0 0}.row-cols-sm-auto>*{flex:0 0 auto;width:auto}.row-cols-sm-1>*{flex:0 0 auto;width:100%}.row-cols-sm-2>*{flex:0 0 auto;width:50%}.row-cols-sm-3>*{flex:0 0 auto;width:33.33333333%}.row-cols-sm-4>*{flex:0 0 auto;width:25%}.row-cols-sm-5>*{flex:0 0 auto;width:20%}.row-cols-sm-6>*{flex:0 0 auto;width:16.66666667%}.col-sm-auto{flex:0 0 auto;width:auto}.col-sm-1{flex:0 0 auto;width:8.33333333%}.col-sm-2{flex:0 0 auto;width:16.66666667%}.col-sm-3{flex:0 0 auto;width:25%}.col-sm-4{flex:0 0 auto;width:33.33333333%}.col-sm-5{flex:0 0 auto;width:41.66666667%}.col-sm-6{flex:0 0 auto;width:50%}.col-sm-7{flex:0 0 auto;width:58.33333333%}.col-sm-8{flex:0 0 auto;width:66.66666667%}.col-sm-9{flex:0 0 auto;width:75%}.col-sm-10{flex:0 0 auto;width:83.33333333%}.col-sm-11{flex:0 0 auto;width:91.66666667%}.col-sm-12{flex:0 0 auto;width:100%}.offset-sm-0{margin-left:0}.offset-sm-1{margin-left:8.33333333%}.offset-sm-2{margin-left:16.66666667%}.offset-sm-3{margin-left:25%}.offset-sm-4{margin-left:33.33333333%}.offset-sm-5{margin-left:41.66666667%}.offset-sm-6{margin-left:50%}.offset-sm-7{margin-left:58.33333333%}.offset-sm-8{margin-left:66.66666667%}.offset-sm-9{margin-left:75%}.offset-sm-10{margin-left:83.33333333%}.offset-sm-11{margin-left:91.66666667%}.g-sm-0,.gx-sm-0{--bs-gutter-x:0}.g-sm-0,.gy-sm-0{--bs-gutter-y:0}.g-sm-1,.gx-sm-1{--bs-gutter-x:0.25rem}.g-sm-1,.gy-sm-1{--bs-gutter-y:0.25rem}.g-sm-2,.gx-sm-2{--bs-gutter-x:0.5rem}.g-sm-2,.gy-sm-2{--bs-gutter-y:0.5rem}.g-sm-3,.gx-sm-3{--bs-gutter-x:1rem}.g-sm-3,.gy-sm-3{--bs-gutter-y:1rem}.g-sm-4,.gx-sm-4{--bs-gutter-x:1.5rem}.g-sm-4,.gy-sm-4{--bs-gutter-y:1.5rem}.g-sm-5,.gx-sm-5{--bs-gutter-x:3rem}.g-sm-5,.gy-sm-5{--bs-gutter-y:3rem}}@media (min-width:768px){.col-md{flex:1 0 0}.row-cols-md-auto>*{flex:0 0 auto;width:auto}.row-cols-md-1>*{flex:0 0 auto;width:100%}.row-cols-md-2>*{flex:0 0 auto;width:50%}.row-cols-md-3>*{flex:0 0 auto;width:33.33333333%}.row-cols-md-4>*{flex:0 0 auto;width:25%}.row-cols-md-5>*{flex:0 0 auto;width:20%}.row-cols-md-6>*{flex:0 0 auto;width:16.66666667%}.col-md-auto{flex:0 0 auto;width:auto}.col-md-1{flex:0 0 auto;width:8.33333333%}.col-md-2{flex:0 0 auto;width:16.66666667%}.col-md-3{flex:0 0 auto;width:25%}.col-md-4{flex:0 0 auto;width:33.33333333%}.col-md-5{flex:0 0 auto;width:41.66666667%}.col-md-6{flex:0 0 auto;width:50%}.col-md-7{flex:0 0 auto;width:58.33333333%}.col-md-8{flex:0 0 auto;width:66.66666667%}.col-md-9{flex:0 0 auto;width:75%}.col-md-10{flex:0 0 auto;width:83.33333333%}.col-md-11{flex:0 0 auto;width:91.66666667%}.col-md-12{flex:0 0 auto;width:100%}.offset-md-0{margin-left:0}.offset-md-1{margin-left:8.33333333%}.offset-md-2{margin-left:16.66666667%}.offset-md-3{margin-left:25%}.offset-md-4{margin-left:33.33333333%}.offset-md-5{margin-left:41.66666667%}.offset-md-6{margin-left:50%}.offset-md-7{margin-left:58.33333333%}.offset-md-8{margin-left:66.66666667%}.offset-md-9{margin-left:75%}.offset-md-10{margin-left:83.33333333%}.offset-md-11{margin-left:91.66666667%}.g-md-0,.gx-md-0{--bs-gutter-x:0}.g-md-0,.gy-md-0{--bs-gutter-y:0}.g-md-1,.gx-md-1{--bs-gutter-x:0.25rem}.g-md-1,.gy-md-1{--bs-gutter-y:0.25rem}.g-md-2,.gx-md-2{--bs-gutter-x:0.5rem}.g-md-2,.gy-md-2{--bs-gutter-y:0.5rem}.g-md-3,.gx-md-3{--bs-gutter-x:1rem}.g-md-3,.gy-md-3{--bs-gutter-y:1rem}.g-md-4,.gx-md-4{--bs-gutter-x:1.5rem}.g-md-4,.gy-md-4{--bs-gutter-y:1.5rem}.g-md-5,.gx-md-5{--bs-gutter-x:3rem}.g-md-5,.gy-md-5{--bs-gutter-y:3rem}}@media (min-width:992px){.col-lg{flex:1 0 0}.row-cols-lg-auto>*{flex:0 0 auto;width:auto}.row-cols-lg-1>*{flex:0 0 auto;width:100%}.row-cols-lg-2>*{flex:0 0 auto;width:50%}.row-cols-lg-3>*{flex:0 0 auto;width:33.33333333%}.row-cols-lg-4>*{flex:0 0 auto;width:25%}.row-cols-lg-5>*{flex:0 0 auto;width:20%}.row-cols-lg-6>*{flex:0 0 auto;width:16.66666667%}.col-lg-auto{flex:0 0 auto;width:auto}.col-lg-1{flex:0 0 auto;width:8.33333333%}.col-lg-2{flex:0 0 auto;width:16.66666667%}.col-lg-3{flex:0 0 auto;width:25%}.col-lg-4{flex:0 0 auto;width:33.33333333%}.col-lg-5{flex:0 0 auto;width:41.66666667%}.col-lg-6{flex:0 0 auto;width:50%}.col-lg-7{flex:0 0 auto;width:58.33333333%}.col-lg-8{flex:0 0 auto;width:66.66666667%}.col-lg-9{flex:0 0 auto;width:75%}.col-lg-10{flex:0 0 auto;width:83.33333333%}.col-lg-11{flex:0 0 auto;width:91.66666667%}.col-lg-12{flex:0 0 auto;width:100%}.offset-lg-0{margin-left:0}.offset-lg-1{margin-left:8.33333333%}.offset-lg-2{margin-left:16.66666667%}.offset-lg-3{margin-left:25%}.offset-lg-4{margin-left:33.33333333%}.offset-lg-5{margin-left:41.66666667%}.offset-lg-6{margin-left:50%}.offset-lg-7{margin-left:58.33333333%}.offset-lg-8{margin-left:66.66666667%}.offset-lg-9{margin-left:75%}.offset-lg-10{margin-left:83.33333333%}.offset-lg-11{margin-left:91.66666667%}.g-lg-0,.gx-lg-0{--bs-gutter-x:0}.g-lg-0,.gy-lg-0{--bs-gutter-y:0}.g-lg-1,.gx-lg-1{--bs-gutter-x:0.25rem}.g-lg-1,.gy-lg-1{--bs-gutter-y:0.25rem}.g-lg-2,.gx-lg-2{--bs-gutter-x:0.5rem}.g-lg-2,.gy-lg-2{--bs-gutter-y:0.5rem}.g-lg-3,.gx-lg-3{--bs-gutter-x:1rem}.g-lg-3,.gy-lg-3{--bs-gutter-y:1rem}.g-lg-4,.gx-lg-4{--bs-gutter-x:1.5rem}.g-lg-4,.gy-lg-4{--bs-gutter-y:1.5rem}.g-lg-5,.gx-lg-5{--bs-gutter-x:3rem}.g-lg-5,.gy-lg-5{--bs-gutter-y:3rem}}@media (min-width:1200px){.col-xl{flex:1 0 0}.row-cols-xl-auto>*{flex:0 0 auto;width:auto}.row-cols-xl-1>*{flex:0 0 auto;width:100%}.row-cols-xl-2>*{flex:0 0 auto;width:50%}.row-cols-xl-3>*{flex:0 0 auto;width:33.33333333%}.row-cols-xl-4>*{flex:0 0 auto;width:25%}.row-cols-xl-5>*{flex:0 0 auto;width:20%}.row-cols-xl-6>*{flex:0 0 auto;width:16.66666667%}.col-xl-auto{flex:0 0 auto;width:auto}.col-xl-1{flex:0 0 auto;width:8.33333333%}.col-xl-2{flex:0 0 auto;width:16.66666667%}.col-xl-3{flex:0 0 auto;width:25%}.col-xl-4{flex:0 0 auto;width:33.33333333%}.col-xl-5{flex:0 0 auto;width:41.66666667%}.col-xl-6{flex:0 0 auto;width:50%}.col-xl-7{flex:0 0 auto;width:58.33333333%}.col-xl-8{flex:0 0 auto;width:66.66666667%}.col-xl-9{flex:0 0 auto;width:75%}.col-xl-10{flex:0 0 auto;width:83.33333333%}.col-xl-11{flex:0 0 auto;width:91.66666667%}.col-xl-12{flex:0 0 auto;width:100%}.offset-xl-0{margin-left:0}.offset-xl-1{margin-left:8.33333333%}.offset-xl-2{margin-left:16.66666667%}.offset-xl-3{margin-left:25%}.offset-xl-4{margin-left:33.33333333%}.offset-xl-5{margin-left:41.66666667%}.offset-xl-6{margin-left:50%}.offset-xl-7{margin-left:58.33333333%}.offset-xl-8{margin-left:66.66666667%}.offset-xl-9{margin-left:75%}.offset-xl-10{margin-left:83.33333333%}.offset-xl-11{margin-left:91.66666667%}.g-xl-0,.gx-xl-0{--bs-gutter-x:0}.g-xl-0,.gy-xl-0{--bs-gutter-y:0}.g-xl-1,.gx-xl-1{--bs-gutter-x:0.25rem}.g-xl-1,.gy-xl-1{--bs-gutter-y:0.25rem}.g-xl-2,.gx-xl-2{--bs-gutter-x:0.5rem}.g-xl-2,.gy-xl-2{--bs-gutter-y:0.5rem}.g-xl-3,.gx-xl-3{--bs-gutter-x:1rem}.g-xl-3,.gy-xl-3{--bs-gutter-y:1rem}.g-xl-4,.gx-xl-4{--bs-gutter-x:1.5rem}.g-xl-4,.gy-xl-4{--bs-gutter-y:1.5rem}.g-xl-5,.gx-xl-5{--bs-gutter-x:3rem}.g-xl-5,.gy-xl-5{--bs-gutter-y:3rem}}@media (min-width:1400px){.col-xxl{flex:1 0 0}.row-cols-xxl-auto>*{flex:0 0 auto;width:auto}.row-cols-xxl-1>*{flex:0 0 auto;width:100%}.row-cols-xxl-2>*{flex:0 0 auto;width:50%}.row-cols-xxl-3>*{flex:0 0 auto;width:33.33333333%}.row-cols-xxl-4>*{flex:0 0 auto;width:25%}.row-cols-xxl-5>*{flex:0 0 auto;width:20%}.row-cols-xxl-6>*{flex:0 0 auto;width:16.66666667%}.col-xxl-auto{flex:0 0 auto;width:auto}.col-xxl-1{flex:0 0 auto;width:8.33333333%}.col-xxl-2{flex:0 0 auto;width:16.66666667%}.col-xxl-3{flex:0 0 auto;width:25%}.col-xxl-4{flex:0 0 auto;width:33.33333333%}.col-xxl-5{flex:0 0 auto;width:41.66666667%}.col-xxl-6{flex:0 0 auto;width:50%}.col-xxl-7{flex:0 0 auto;width:58.33333333%}.col-xxl-8{flex:0 0 auto;width:66.66666667%}.col-xxl-9{flex:0 0 auto;width:75%}.col-xxl-10{flex:0 0 auto;width:83.33333333%}.col-xxl-11{flex:0 0 auto;width:91.66666667%}.col-xxl-12{flex:0 0 auto;width:100%}.offset-xxl-0{margin-left:0}.offset-xxl-1{margin-left:8.33333333%}.offset-xxl-2{margin-left:16.66666667%}.offset-xxl-3{margin-left:25%}.offset-xxl-4{margin-left:33.33333333%}.offset-xxl-5{margin-left:41.66666667%}.offset-xxl-6{margin-left:50%}.offset-xxl-7{margin-left:58.33333333%}.offset-xxl-8{margin-left:66.66666667%}.offset-xxl-9{margin-left:75%}.offset-xxl-10{margin-left:83.33333333%}.offset-xxl-11{margin-left:91.66666667%}.g-xxl-0,.gx-xxl-0{--bs-gutter-x:0}.g-xxl-0,.gy-xxl-0{--bs-gutter-y:0}.g-xxl-1,.gx-xxl-1{--bs-gutter-x:0.25rem}.g-xxl-1,.gy-xxl-1{--bs-gutter-y:0.25rem}.g-xxl-2,.gx-xxl-2{--bs-gutter-x:0.5rem}.g-xxl-2,.gy-xxl-2{--bs-gutter-y:0.5rem}.g-xxl-3,.gx-xxl-3{--bs-gutter-x:1rem}.g-xxl-3,.gy-xxl-3{--bs-gutter-y:1rem}.g-xxl-4,.gx-xxl-4{--bs-gutter-x:1.5rem}.g-xxl-4,.gy-xxl-4{--bs-gutter-y:1.5rem}.g-xxl-5,.gx-xxl-5{--bs-gutter-x:3rem}.g-xxl-5,.gy-xxl-5{--bs-gutter-y:3rem}}.table{--bs-table-color-type:initial;--bs-table-bg-type:initial;--bs-table-color-state:initial;--bs-table-bg-state:initial;--bs-table-color:var(--bs-emphasis-color);--bs-table-bg:var(--bs-body-bg);--bs-table-border-color:var(--bs-border-color);--bs-table-accent-bg:transparent;--bs-table-striped-color:var(--bs-emphasis-color);--bs-table-striped-bg:rgba(var(--bs-emphasis-color-rgb), 0.05);--bs-table-active-color:var(--bs-emphasis-color);--bs-table-active-bg:rgba(var(--bs-emphasis-color-rgb), 0.1);--bs-table-hover-color:var(--bs-emphasis-color);--bs-table-hover-bg:rgba(var(--bs-emphasis-color-rgb), 0.075);width:100%;margin-bottom:1rem;vertical-align:top;border-color:var(--bs-table-border-color)}.table>:not(caption)>*>*{padding:.5rem .5rem;color:var(--bs-table-color-state,var(--bs-table-color-type,var(--bs-table-color)));background-color:var(--bs-table-bg);border-bottom-width:var(--bs-border-width);box-shadow:inset 0 0 0 9999px var(--bs-table-bg-state,var(--bs-table-bg-type,var(--bs-table-accent-bg)))}.table>tbody{vertical-align:inherit}.table>thead{vertical-align:bottom}.table-group-divider{border-top:calc(var(--bs-border-width) * 2) solid currentcolor}.caption-top{caption-side:top}.table-sm>:not(caption)>*>*{padding:.25rem .25rem}.table-bordered>:not(caption)>*{border-width:var(--bs-border-width) 0}.table-bordered>:not(caption)>*>*{border-width:0 var(--bs-border-width)}.table-borderless>:not(caption)>*>*{border-bottom-width:0}.table-borderless>:not(:first-child){border-top-width:0}.table-striped>tbody>tr:nth-of-type(odd)>*{--bs-table-color-type:var(--bs-table-striped-color);--bs-table-bg-type:var(--bs-table-striped-bg)}.table-striped-columns>:not(caption)>tr>:nth-child(2n){--bs-table-color-type:var(--bs-table-striped-color);--bs-table-bg-type:var(--bs-table-striped-bg)}.table-active{--bs-table-color-state:var(--bs-table-active-color);--bs-table-bg-state:var(--bs-table-active-bg)}.table-hover>tbody>tr:hover>*{--bs-table-color-state:var(--bs-table-hover-color);--bs-table-bg-state:var(--bs-table-hover-bg)}.table-primary{--bs-table-color:#000;--bs-table-bg:#cfe2ff;--bs-table-border-color:#a6b5cc;--bs-table-striped-bg:#c5d7f2;--bs-table-striped-color:#000;--bs-table-active-bg:#bacbe6;--bs-table-active-color:#000;--bs-table-hover-bg:#bfd1ec;--bs-table-hover-color:#000;color:var(--bs-table-color);border-color:var(--bs-table-border-color)}.table-secondary{--bs-table-color:#000;--bs-table-bg:#e2e3e5;--bs-table-border-color:#b5b6b7;--bs-table-striped-bg:#d7d8da;--bs-table-striped-color:#000;--bs-table-active-bg:#cbccce;--bs-table-active-color:#000;--bs-table-hover-bg:#d1d2d4;--bs-table-hover-color:#000;color:var(--bs-table-color);border-color:var(--bs-table-border-color)}.table-success{--bs-table-color:#000;--bs-table-bg:#d1e7dd;--bs-table-border-color:#a7b9b1;--bs-table-striped-bg:#c7dbd2;--bs-table-striped-color:#000;--bs-table-active-bg:#bcd0c7;--bs-table-active-color:#000;--bs-table-hover-bg:#c1d6cc;--bs-table-hover-color:#000;color:var(--bs-table-color);border-color:var(--bs-table-border-color)}.table-info{--bs-table-color:#000;--bs-table-bg:#cff4fc;--bs-table-border-color:#a6c3ca;--bs-table-striped-bg:#c5e8ef;--bs-table-striped-color:#000;--bs-table-active-bg:#badce3;--bs-table-active-color:#000;--bs-table-hover-bg:#bfe2e9;--bs-table-hover-color:#000;color:var(--bs-table-color);border-color:var(--bs-table-border-color)}.table-warning{--bs-table-color:#000;--bs-table-bg:#fff3cd;--bs-table-border-color:#ccc2a4;--bs-table-striped-bg:#f2e7c3;--bs-table-striped-color:#000;--bs-table-active-bg:#e6dbb9;--bs-table-active-color:#000;--bs-table-hover-bg:#ece1be;--bs-table-hover-color:#000;color:var(--bs-table-color);border-color:var(--bs-table-border-color)}.table-danger{--bs-table-color:#000;--bs-table-bg:#f8d7da;--bs-table-border-color:#c6acae;--bs-table-striped-bg:#eccccf;--bs-table-striped-color:#000;--bs-table-active-bg:#dfc2c4;--bs-table-active-color:#000;--bs-table-hover-bg:#e5c7ca;--bs-table-hover-color:#000;color:var(--bs-table-color);border-color:var(--bs-table-border-color)}.table-light{--bs-table-color:#000;--bs-table-bg:#f8f9fa;--bs-table-border-color:#c6c7c8;--bs-table-striped-bg:#ecedee;--bs-table-striped-color:#000;--bs-table-active-bg:#dfe0e1;--bs-table-active-color:#000;--bs-table-hover-bg:#e5e6e7;--bs-table-hover-color:#000;color:var(--bs-table-color);border-color:var(--bs-table-border-color)}.table-dark{--bs-table-color:#fff;--bs-table-bg:#212529;--bs-table-border-color:#4d5154;--bs-table-striped-bg:#2c3034;--bs-table-striped-color:#fff;--bs-table-active-bg:#373b3e;--bs-table-active-color:#fff;--bs-table-hover-bg:#323539;--bs-table-hover-color:#fff;color:var(--bs-table-color);border-color:var(--bs-table-border-color)}.table-responsive{overflow-x:auto;-webkit-overflow-scrolling:touch}@media (max-width:575.98px){.table-responsive-sm{overflow-x:auto;-webkit-overflow-scrolling:touch}}@media (max-width:767.98px){.table-responsive-md{overflow-x:auto;-webkit-overflow-scrolling:touch}}@media (max-width:991.98px){.table-responsive-lg{overflow-x:auto;-webkit-overflow-scrolling:touch}}@media (max-width:1199.98px){.table-responsive-xl{overflow-x:auto;-webkit-overflow-scrolling:touch}}@media (max-width:1399.98px){.table-responsive-xxl{overflow-x:auto;-webkit-overflow-scrolling:touch}}.form-label{margin-bottom:.5rem}.col-form-label{padding-top:calc(.375rem + var(--bs-border-width));padding-bottom:calc(.375rem + var(--bs-border-width));margin-bottom:0;font-size:inherit;line-height:1.5}.col-form-label-lg{padding-top:calc(.5rem + var(--bs-border-width));padding-bottom:calc(.5rem + var(--bs-border-width));font-size:1.25rem}.col-form-label-sm{padding-top:calc(.25rem + var(--bs-border-width));padding-bottom:calc(.25rem + var(--bs-border-width));font-size:.875rem}.form-text{margin-top:.25rem;font-size:.875em;color:var(--bs-secondary-color)}.form-control{display:block;width:100%;padding:.375rem .75rem;font-size:1rem;font-weight:400;line-height:1.5;color:var(--bs-body-color);-webkit-appearance:none;-moz-appearance:none;appearance:none;background-color:var(--bs-body-bg);background-clip:padding-box;border:var(--bs-border-width) solid var(--bs-border-color);border-radius:var(--bs-border-radius);transition:border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.form-control{transition:none}}.form-control[type=file]{overflow:hidden}.form-control[type=file]:not(:disabled):not([readonly]){cursor:pointer}.form-control:focus{color:var(--bs-body-color);background-color:var(--bs-body-bg);border-color:#86b7fe;outline:0;box-shadow:0 0 0 .25rem rgba(13,110,253,.25)}.form-control::-webkit-date-and-time-value{min-width:85px;height:1.5em;margin:0}.form-control::-webkit-datetime-edit{display:block;padding:0}.form-control::placeholder{color:var(--bs-secondary-color);opacity:1}.form-control:disabled{background-color:var(--bs-secondary-bg);opacity:1}.form-control::-webkit-file-upload-button{padding:.375rem .75rem;margin:-.375rem -.75rem;-webkit-margin-end:.75rem;margin-inline-end:.75rem;color:var(--bs-body-color);background-color:var(--bs-tertiary-bg);pointer-events:none;border-color:inherit;border-style:solid;border-width:0;border-inline-end-width:var(--bs-border-width);border-radius:0;-webkit-transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}.form-control::file-selector-button{padding:.375rem .75rem;margin:-.375rem -.75rem;-webkit-margin-end:.75rem;margin-inline-end:.75rem;color:var(--bs-body-color);background-color:var(--bs-tertiary-bg);pointer-events:none;border-color:inherit;border-style:solid;border-width:0;border-inline-end-width:var(--bs-border-width);border-radius:0;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.form-control::-webkit-file-upload-button{-webkit-transition:none;transition:none}.form-control::file-selector-button{transition:none}}.form-control:hover:not(:disabled):not([readonly])::-webkit-file-upload-button{background-color:var(--bs-secondary-bg)}.form-control:hover:not(:disabled):not([readonly])::file-selector-button{background-color:var(--bs-secondary-bg)}.form-control-plaintext{display:block;width:100%;padding:.375rem 0;margin-bottom:0;line-height:1.5;color:var(--bs-body-color);background-color:transparent;border:solid transparent;border-width:var(--bs-border-width) 0}.form-control-plaintext:focus{outline:0}.form-control-plaintext.form-control-lg,.form-control-plaintext.form-control-sm{padding-right:0;padding-left:0}.form-control-sm{min-height:calc(1.5em + .5rem + calc(var(--bs-border-width) * 2));padding:.25rem .5rem;font-size:.875rem;border-radius:var(--bs-border-radius-sm)}.form-control-sm::-webkit-file-upload-button{padding:.25rem .5rem;margin:-.25rem -.5rem;-webkit-margin-end:.5rem;margin-inline-end:.5rem}.form-control-sm::file-selector-button{padding:.25rem .5rem;margin:-.25rem -.5rem;-webkit-margin-end:.5rem;margin-inline-end:.5rem}.form-control-lg{min-height:calc(1.5em + 1rem + calc(var(--bs-border-width) * 2));padding:.5rem 1rem;font-size:1.25rem;border-radius:var(--bs-border-radius-lg)}.form-control-lg::-webkit-file-upload-button{padding:.5rem 1rem;margin:-.5rem -1rem;-webkit-margin-end:1rem;margin-inline-end:1rem}.form-control-lg::file-selector-button{padding:.5rem 1rem;margin:-.5rem -1rem;-webkit-margin-end:1rem;margin-inline-end:1rem}textarea.form-control{min-height:calc(1.5em + .75rem + calc(var(--bs-border-width) * 2))}textarea.form-control-sm{min-height:calc(1.5em + .5rem + calc(var(--bs-border-width) * 2))}textarea.form-control-lg{min-height:calc(1.5em + 1rem + calc(var(--bs-border-width) * 2))}.form-control-color{width:3rem;height:calc(1.5em + .75rem + calc(var(--bs-border-width) * 2));padding:.375rem}.form-control-color:not(:disabled):not([readonly]){cursor:pointer}.form-control-color::-moz-color-swatch{border:0!important;border-radius:var(--bs-border-radius)}.form-control-color::-webkit-color-swatch{border:0!important;border-radius:var(--bs-border-radius)}.form-control-color.form-control-sm{height:calc(1.5em + .5rem + calc(var(--bs-border-width) * 2))}.form-control-color.form-control-lg{height:calc(1.5em + 1rem + calc(var(--bs-border-width) * 2))}.form-select{--bs-form-select-bg-img:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%23343a40' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='m2 5 6 6 6-6'/%3e%3c/svg%3e");display:block;width:100%;padding:.375rem 2.25rem .375rem .75rem;font-size:1rem;font-weight:400;line-height:1.5;color:var(--bs-body-color);-webkit-appearance:none;-moz-appearance:none;appearance:none;background-color:var(--bs-body-bg);background-image:var(--bs-form-select-bg-img),var(--bs-form-select-bg-icon,none);background-repeat:no-repeat;background-position:right .75rem center;background-size:16px 12px;border:var(--bs-border-width) solid var(--bs-border-color);border-radius:var(--bs-border-radius);transition:border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.form-select{transition:none}}.form-select:focus{border-color:#86b7fe;outline:0;box-shadow:0 0 0 .25rem rgba(13,110,253,.25)}.form-select[multiple],.form-select[size]:not([size="1"]){padding-right:.75rem;background-image:none}.form-select:disabled{background-color:var(--bs-secondary-bg)}.form-select:-moz-focusring{color:transparent;text-shadow:0 0 0 var(--bs-body-color)}.form-select-sm{padding-top:.25rem;padding-bottom:.25rem;padding-left:.5rem;font-size:.875rem;border-radius:var(--bs-border-radius-sm)}.form-select-lg{padding-top:.5rem;padding-bottom:.5rem;padding-left:1rem;font-size:1.25rem;border-radius:var(--bs-border-radius-lg)}[data-bs-theme=dark] .form-select{--bs-form-select-bg-img:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%23dee2e6' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='m2 5 6 6 6-6'/%3e%3c/svg%3e")}.form-check{display:block;min-height:1.5rem;padding-left:1.5em;margin-bottom:.125rem}.form-check .form-check-input{float:left;margin-left:-1.5em}.form-check-reverse{padding-right:1.5em;padding-left:0;text-align:right}.form-check-reverse .form-check-input{float:right;margin-right:-1.5em;margin-left:0}.form-check-input{--bs-form-check-bg:var(--bs-body-bg);flex-shrink:0;width:1em;height:1em;margin-top:.25em;vertical-align:top;-webkit-appearance:none;-moz-appearance:none;appearance:none;background-color:var(--bs-form-check-bg);background-image:var(--bs-form-check-bg-image);background-repeat:no-repeat;background-position:center;background-size:contain;border:var(--bs-border-width) solid var(--bs-border-color);-webkit-print-color-adjust:exact;color-adjust:exact;print-color-adjust:exact}.form-check-input[type=checkbox]{border-radius:.25em}.form-check-input[type=radio]{border-radius:50%}.form-check-input:active{filter:brightness(90%)}.form-check-input:focus{border-color:#86b7fe;outline:0;box-shadow:0 0 0 .25rem rgba(13,110,253,.25)}.form-check-input:checked{background-color:#0d6efd;border-color:#0d6efd}.form-check-input:checked[type=checkbox]{--bs-form-check-bg-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3e%3cpath fill='none' stroke='%23fff' stroke-linecap='round' stroke-linejoin='round' stroke-width='3' d='m6 10 3 3 6-6'/%3e%3c/svg%3e")}.form-check-input:checked[type=radio]{--bs-form-check-bg-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='2' fill='%23fff'/%3e%3c/svg%3e")}.form-check-input[type=checkbox]:indeterminate{background-color:#0d6efd;border-color:#0d6efd;--bs-form-check-bg-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3e%3cpath fill='none' stroke='%23fff' stroke-linecap='round' stroke-linejoin='round' stroke-width='3' d='M6 10h8'/%3e%3c/svg%3e")}.form-check-input:disabled{pointer-events:none;filter:none;opacity:.5}.form-check-input:disabled~.form-check-label,.form-check-input[disabled]~.form-check-label{cursor:default;opacity:.5}.form-switch{padding-left:2.5em}.form-switch .form-check-input{--bs-form-switch-bg:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='rgba%280, 0, 0, 0.25%29'/%3e%3c/svg%3e");width:2em;margin-left:-2.5em;background-image:var(--bs-form-switch-bg);background-position:left center;border-radius:2em;transition:background-position .15s ease-in-out}@media (prefers-reduced-motion:reduce){.form-switch .form-check-input{transition:none}}.form-switch .form-check-input:focus{--bs-form-switch-bg:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='%2386b7fe'/%3e%3c/svg%3e")}.form-switch .form-check-input:checked{background-position:right center;--bs-form-switch-bg:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='%23fff'/%3e%3c/svg%3e")}.form-switch.form-check-reverse{padding-right:2.5em;padding-left:0}.form-switch.form-check-reverse .form-check-input{margin-right:-2.5em;margin-left:0}.form-check-inline{display:inline-block;margin-right:1rem}.btn-check{position:absolute;clip:rect(0,0,0,0);pointer-events:none}.btn-check:disabled+.btn,.btn-check[disabled]+.btn{pointer-events:none;filter:none;opacity:.65}[data-bs-theme=dark] .form-switch .form-check-input:not(:checked):not(:focus){--bs-form-switch-bg:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='rgba%28255, 255, 255, 0.25%29'/%3e%3c/svg%3e")}.form-range{width:100%;height:1.5rem;padding:0;-webkit-appearance:none;-moz-appearance:none;appearance:none;background-color:transparent}.form-range:focus{outline:0}.form-range:focus::-webkit-slider-thumb{box-shadow:0 0 0 1px #fff,0 0 0 .25rem rgba(13,110,253,.25)}.form-range:focus::-moz-range-thumb{box-shadow:0 0 0 1px #fff,0 0 0 .25rem rgba(13,110,253,.25)}.form-range::-moz-focus-outer{border:0}.form-range::-webkit-slider-thumb{width:1rem;height:1rem;margin-top:-.25rem;-webkit-appearance:none;appearance:none;background-color:#0d6efd;border:0;border-radius:1rem;-webkit-transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.form-range::-webkit-slider-thumb{-webkit-transition:none;transition:none}}.form-range::-webkit-slider-thumb:active{background-color:#b6d4fe}.form-range::-webkit-slider-runnable-track{width:100%;height:.5rem;color:transparent;cursor:pointer;background-color:var(--bs-secondary-bg);border-color:transparent;border-radius:1rem}.form-range::-moz-range-thumb{width:1rem;height:1rem;-moz-appearance:none;appearance:none;background-color:#0d6efd;border:0;border-radius:1rem;-moz-transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.form-range::-moz-range-thumb{-moz-transition:none;transition:none}}.form-range::-moz-range-thumb:active{background-color:#b6d4fe}.form-range::-moz-range-track{width:100%;height:.5rem;color:transparent;cursor:pointer;background-color:var(--bs-secondary-bg);border-color:transparent;border-radius:1rem}.form-range:disabled{pointer-events:none}.form-range:disabled::-webkit-slider-thumb{background-color:var(--bs-secondary-color)}.form-range:disabled::-moz-range-thumb{background-color:var(--bs-secondary-color)}.form-floating{position:relative}.form-floating>.form-control,.form-floating>.form-control-plaintext,.form-floating>.form-select{height:calc(3.5rem + calc(var(--bs-border-width) * 2));min-height:calc(3.5rem + calc(var(--bs-border-width) * 2));line-height:1.25}.form-floating>label{position:absolute;top:0;left:0;z-index:2;max-width:100%;height:100%;padding:1rem .75rem;overflow:hidden;color:rgba(var(--bs-body-color-rgb),.65);text-align:start;text-overflow:ellipsis;white-space:nowrap;pointer-events:none;border:var(--bs-border-width) solid transparent;transform-origin:0 0;transition:opacity .1s ease-in-out,transform .1s ease-in-out}@media (prefers-reduced-motion:reduce){.form-floating>label{transition:none}}.form-floating>.form-control,.form-floating>.form-control-plaintext{padding:1rem .75rem}.form-floating>.form-control-plaintext::placeholder,.form-floating>.form-control::placeholder{color:transparent}.form-floating>.form-control-plaintext:focus,.form-floating>.form-control-plaintext:not(:placeholder-shown),.form-floating>.form-control:focus,.form-floating>.form-control:not(:placeholder-shown){padding-top:1.625rem;padding-bottom:.625rem}.form-floating>.form-control-plaintext:-webkit-autofill,.form-floating>.form-control:-webkit-autofill{padding-top:1.625rem;padding-bottom:.625rem}.form-floating>.form-select{padding-top:1.625rem;padding-bottom:.625rem;padding-left:.75rem}.form-floating>.form-control-plaintext~label,.form-floating>.form-control:focus~label,.form-floating>.form-control:not(:placeholder-shown)~label,.form-floating>.form-select~label{transform:scale(.85) translateY(-.5rem) translateX(.15rem)}.form-floating>.form-control:-webkit-autofill~label{transform:scale(.85) translateY(-.5rem) translateX(.15rem)}.form-floating>textarea:focus~label::after,.form-floating>textarea:not(:placeholder-shown)~label::after{position:absolute;inset:1rem 0.375rem;z-index:-1;height:1.5em;content:"";background-color:var(--bs-body-bg);border-radius:var(--bs-border-radius)}.form-floating>textarea:disabled~label::after{background-color:var(--bs-secondary-bg)}.form-floating>.form-control-plaintext~label{border-width:var(--bs-border-width) 0}.form-floating>.form-control:disabled~label,.form-floating>:disabled~label{color:#6c757d}.input-group{position:relative;display:flex;flex-wrap:wrap;align-items:stretch;width:100%}.input-group>.form-control,.input-group>.form-floating,.input-group>.form-select{position:relative;flex:1 1 auto;width:1%;min-width:0}.input-group>.form-control:focus,.input-group>.form-floating:focus-within,.input-group>.form-select:focus{z-index:5}.input-group .btn{position:relative;z-index:2}.input-group .btn:focus{z-index:5}.input-group-text{display:flex;align-items:center;padding:.375rem .75rem;font-size:1rem;font-weight:400;line-height:1.5;color:var(--bs-body-color);text-align:center;white-space:nowrap;background-color:var(--bs-tertiary-bg);border:var(--bs-border-width) solid var(--bs-border-color);border-radius:var(--bs-border-radius)}.input-group-lg>.btn,.input-group-lg>.form-control,.input-group-lg>.form-select,.input-group-lg>.input-group-text{padding:.5rem 1rem;font-size:1.25rem;border-radius:var(--bs-border-radius-lg)}.input-group-sm>.btn,.input-group-sm>.form-control,.input-group-sm>.form-select,.input-group-sm>.input-group-text{padding:.25rem .5rem;font-size:.875rem;border-radius:var(--bs-border-radius-sm)}.input-group-lg>.form-select,.input-group-sm>.form-select{padding-right:3rem}.input-group:not(.has-validation)>.dropdown-toggle:nth-last-child(n+3),.input-group:not(.has-validation)>.form-floating:not(:last-child)>.form-control,.input-group:not(.has-validation)>.form-floating:not(:last-child)>.form-select,.input-group:not(.has-validation)>:not(:last-child):not(.dropdown-toggle):not(.dropdown-menu):not(.form-floating){border-top-right-radius:0;border-bottom-right-radius:0}.input-group.has-validation>.dropdown-toggle:nth-last-child(n+4),.input-group.has-validation>.form-floating:nth-last-child(n+3)>.form-control,.input-group.has-validation>.form-floating:nth-last-child(n+3)>.form-select,.input-group.has-validation>:nth-last-child(n+3):not(.dropdown-toggle):not(.dropdown-menu):not(.form-floating){border-top-right-radius:0;border-bottom-right-radius:0}.input-group>:not(:first-child):not(.dropdown-menu):not(.valid-tooltip):not(.valid-feedback):not(.invalid-tooltip):not(.invalid-feedback){margin-left:calc(-1 * var(--bs-border-width));border-top-left-radius:0;border-bottom-left-radius:0}.input-group>.form-floating:not(:first-child)>.form-control,.input-group>.form-floating:not(:first-child)>.form-select{border-top-left-radius:0;border-bottom-left-radius:0}.valid-feedback{display:none;width:100%;margin-top:.25rem;font-size:.875em;color:var(--bs-form-valid-color)}.valid-tooltip{position:absolute;top:100%;z-index:5;display:none;max-width:100%;padding:.25rem .5rem;margin-top:.1rem;font-size:.875rem;color:#fff;background-color:var(--bs-success);border-radius:var(--bs-border-radius)}.is-valid~.valid-feedback,.is-valid~.valid-tooltip,.was-validated :valid~.valid-feedback,.was-validated :valid~.valid-tooltip{display:block}.form-control.is-valid,.was-validated .form-control:valid{border-color:var(--bs-form-valid-border-color);padding-right:calc(1.5em + .75rem);background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3e%3cpath fill='%23198754' d='M2.3 6.73.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1'/%3e%3c/svg%3e");background-repeat:no-repeat;background-position:right calc(.375em + .1875rem) center;background-size:calc(.75em + .375rem) calc(.75em + .375rem)}.form-control.is-valid:focus,.was-validated .form-control:valid:focus{border-color:var(--bs-form-valid-border-color);box-shadow:0 0 0 .25rem rgba(var(--bs-success-rgb),.25)}.was-validated textarea.form-control:valid,textarea.form-control.is-valid{padding-right:calc(1.5em + .75rem);background-position:top calc(.375em + .1875rem) right calc(.375em + .1875rem)}.form-select.is-valid,.was-validated .form-select:valid{border-color:var(--bs-form-valid-border-color)}.form-select.is-valid:not([multiple]):not([size]),.form-select.is-valid:not([multiple])[size="1"],.was-validated .form-select:valid:not([multiple]):not([size]),.was-validated .form-select:valid:not([multiple])[size="1"]{--bs-form-select-bg-icon:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3e%3cpath fill='%23198754' d='M2.3 6.73.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1'/%3e%3c/svg%3e");padding-right:4.125rem;background-position:right .75rem center,center right 2.25rem;background-size:16px 12px,calc(.75em + .375rem) calc(.75em + .375rem)}.form-select.is-valid:focus,.was-validated .form-select:valid:focus{border-color:var(--bs-form-valid-border-color);box-shadow:0 0 0 .25rem rgba(var(--bs-success-rgb),.25)}.form-control-color.is-valid,.was-validated .form-control-color:valid{width:calc(3rem + calc(1.5em + .75rem))}.form-check-input.is-valid,.was-validated .form-check-input:valid{border-color:var(--bs-form-valid-border-color)}.form-check-input.is-valid:checked,.was-validated .form-check-input:valid:checked{background-color:var(--bs-form-valid-color)}.form-check-input.is-valid:focus,.was-validated .form-check-input:valid:focus{box-shadow:0 0 0 .25rem rgba(var(--bs-success-rgb),.25)}.form-check-input.is-valid~.form-check-label,.was-validated .form-check-input:valid~.form-check-label{color:var(--bs-form-valid-color)}.form-check-inline .form-check-input~.valid-feedback{margin-left:.5em}.input-group>.form-control:not(:focus).is-valid,.input-group>.form-floating:not(:focus-within).is-valid,.input-group>.form-select:not(:focus).is-valid,.was-validated .input-group>.form-control:not(:focus):valid,.was-validated .input-group>.form-floating:not(:focus-within):valid,.was-validated .input-group>.form-select:not(:focus):valid{z-index:3}.invalid-feedback{display:none;width:100%;margin-top:.25rem;font-size:.875em;color:var(--bs-form-invalid-color)}.invalid-tooltip{position:absolute;top:100%;z-index:5;display:none;max-width:100%;padding:.25rem .5rem;margin-top:.1rem;font-size:.875rem;color:#fff;background-color:var(--bs-danger);border-radius:var(--bs-border-radius)}.is-invalid~.invalid-feedback,.is-invalid~.invalid-tooltip,.was-validated :invalid~.invalid-feedback,.was-validated :invalid~.invalid-tooltip{display:block}.form-control.is-invalid,.was-validated .form-control:invalid{border-color:var(--bs-form-invalid-border-color);padding-right:calc(1.5em + .75rem);background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12' width='12' height='12' fill='none' stroke='%23dc3545'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%23dc3545' stroke='none'/%3e%3c/svg%3e");background-repeat:no-repeat;background-position:right calc(.375em + .1875rem) center;background-size:calc(.75em + .375rem) calc(.75em + .375rem)}.form-control.is-invalid:focus,.was-validated .form-control:invalid:focus{border-color:var(--bs-form-invalid-border-color);box-shadow:0 0 0 .25rem rgba(var(--bs-danger-rgb),.25)}.was-validated textarea.form-control:invalid,textarea.form-control.is-invalid{padding-right:calc(1.5em + .75rem);background-position:top calc(.375em + .1875rem) right calc(.375em + .1875rem)}.form-select.is-invalid,.was-validated .form-select:invalid{border-color:var(--bs-form-invalid-border-color)}.form-select.is-invalid:not([multiple]):not([size]),.form-select.is-invalid:not([multiple])[size="1"],.was-validated .form-select:invalid:not([multiple]):not([size]),.was-validated .form-select:invalid:not([multiple])[size="1"]{--bs-form-select-bg-icon:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12' width='12' height='12' fill='none' stroke='%23dc3545'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%23dc3545' stroke='none'/%3e%3c/svg%3e");padding-right:4.125rem;background-position:right .75rem center,center right 2.25rem;background-size:16px 12px,calc(.75em + .375rem) calc(.75em + .375rem)}.form-select.is-invalid:focus,.was-validated .form-select:invalid:focus{border-color:var(--bs-form-invalid-border-color);box-shadow:0 0 0 .25rem rgba(var(--bs-danger-rgb),.25)}.form-control-color.is-invalid,.was-validated .form-control-color:invalid{width:calc(3rem + calc(1.5em + .75rem))}.form-check-input.is-invalid,.was-validated .form-check-input:invalid{border-color:var(--bs-form-invalid-border-color)}.form-check-input.is-invalid:checked,.was-validated .form-check-input:invalid:checked{background-color:var(--bs-form-invalid-color)}.form-check-input.is-invalid:focus,.was-validated .form-check-input:invalid:focus{box-shadow:0 0 0 .25rem rgba(var(--bs-danger-rgb),.25)}.form-check-input.is-invalid~.form-check-label,.was-validated .form-check-input:invalid~.form-check-label{color:var(--bs-form-invalid-color)}.form-check-inline .form-check-input~.invalid-feedback{margin-left:.5em}.input-group>.form-control:not(:focus).is-invalid,.input-group>.form-floating:not(:focus-within).is-invalid,.input-group>.form-select:not(:focus).is-invalid,.was-validated .input-group>.form-control:not(:focus):invalid,.was-validated .input-group>.form-floating:not(:focus-within):invalid,.was-validated .input-group>.form-select:not(:focus):invalid{z-index:4}.btn{--bs-btn-padding-x:0.75rem;--bs-btn-padding-y:0.375rem;--bs-btn-font-family: ;--bs-btn-font-size:1rem;--bs-btn-font-weight:400;--bs-btn-line-height:1.5;--bs-btn-color:var(--bs-body-color);--bs-btn-bg:transparent;--bs-btn-border-width:var(--bs-border-width);--bs-btn-border-color:transparent;--bs-btn-border-radius:var(--bs-border-radius);--bs-btn-hover-border-color:transparent;--bs-btn-box-shadow:inset 0 1px 0 rgba(255, 255, 255, 0.15),0 1px 1px rgba(0, 0, 0, 0.075);--bs-btn-disabled-opacity:0.65;--bs-btn-focus-box-shadow:0 0 0 0.25rem rgba(var(--bs-btn-focus-shadow-rgb), .5);display:inline-block;padding:var(--bs-btn-padding-y) var(--bs-btn-padding-x);font-family:var(--bs-btn-font-family);font-size:var(--bs-btn-font-size);font-weight:var(--bs-btn-font-weight);line-height:var(--bs-btn-line-height);color:var(--bs-btn-color);text-align:center;text-decoration:none;vertical-align:middle;cursor:pointer;-webkit-user-select:none;-moz-user-select:none;user-select:none;border:var(--bs-btn-border-width) solid var(--bs-btn-border-color);border-radius:var(--bs-btn-border-radius);background-color:var(--bs-btn-bg);transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.btn{transition:none}}.btn:hover{color:var(--bs-btn-hover-color);background-color:var(--bs-btn-hover-bg);border-color:var(--bs-btn-hover-border-color)}.btn-check+.btn:hover{color:var(--bs-btn-color);background-color:var(--bs-btn-bg);border-color:var(--bs-btn-border-color)}.btn:focus-visible{color:var(--bs-btn-hover-color);background-color:var(--bs-btn-hover-bg);border-color:var(--bs-btn-hover-border-color);outline:0;box-shadow:var(--bs-btn-focus-box-shadow)}.btn-check:focus-visible+.btn{border-color:var(--bs-btn-hover-border-color);outline:0;box-shadow:var(--bs-btn-focus-box-shadow)}.btn-check:checked+.btn,.btn.active,.btn.show,.btn:first-child:active,:not(.btn-check)+.btn:active{color:var(--bs-btn-active-color);background-color:var(--bs-btn-active-bg);border-color:var(--bs-btn-active-border-color)}.btn-check:checked+.btn:focus-visible,.btn.active:focus-visible,.btn.show:focus-visible,.btn:first-child:active:focus-visible,:not(.btn-check)+.btn:active:focus-visible{box-shadow:var(--bs-btn-focus-box-shadow)}.btn-check:checked:focus-visible+.btn{box-shadow:var(--bs-btn-focus-box-shadow)}.btn.disabled,.btn:disabled,fieldset:disabled .btn{color:var(--bs-btn-disabled-color);pointer-events:none;background-color:var(--bs-btn-disabled-bg);border-color:var(--bs-btn-disabled-border-color);opacity:var(--bs-btn-disabled-opacity)}.btn-primary{--bs-btn-color:#fff;--bs-btn-bg:#0d6efd;--bs-btn-border-color:#0d6efd;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#0b5ed7;--bs-btn-hover-border-color:#0a58ca;--bs-btn-focus-shadow-rgb:49,132,253;--bs-btn-active-color:#fff;--bs-btn-active-bg:#0a58ca;--bs-btn-active-border-color:#0a53be;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#fff;--bs-btn-disabled-bg:#0d6efd;--bs-btn-disabled-border-color:#0d6efd}.btn-secondary{--bs-btn-color:#fff;--bs-btn-bg:#6c757d;--bs-btn-border-color:#6c757d;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#5c636a;--bs-btn-hover-border-color:#565e64;--bs-btn-focus-shadow-rgb:130,138,145;--bs-btn-active-color:#fff;--bs-btn-active-bg:#565e64;--bs-btn-active-border-color:#51585e;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#fff;--bs-btn-disabled-bg:#6c757d;--bs-btn-disabled-border-color:#6c757d}.btn-success{--bs-btn-color:#fff;--bs-btn-bg:#198754;--bs-btn-border-color:#198754;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#157347;--bs-btn-hover-border-color:#146c43;--bs-btn-focus-shadow-rgb:60,153,110;--bs-btn-active-color:#fff;--bs-btn-active-bg:#146c43;--bs-btn-active-border-color:#13653f;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#fff;--bs-btn-disabled-bg:#198754;--bs-btn-disabled-border-color:#198754}.btn-info{--bs-btn-color:#000;--bs-btn-bg:#0dcaf0;--bs-btn-border-color:#0dcaf0;--bs-btn-hover-color:#000;--bs-btn-hover-bg:#31d2f2;--bs-btn-hover-border-color:#25cff2;--bs-btn-focus-shadow-rgb:11,172,204;--bs-btn-active-color:#000;--bs-btn-active-bg:#3dd5f3;--bs-btn-active-border-color:#25cff2;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#000;--bs-btn-disabled-bg:#0dcaf0;--bs-btn-disabled-border-color:#0dcaf0}.btn-warning{--bs-btn-color:#000;--bs-btn-bg:#ffc107;--bs-btn-border-color:#ffc107;--bs-btn-hover-color:#000;--bs-btn-hover-bg:#ffca2c;--bs-btn-hover-border-color:#ffc720;--bs-btn-focus-shadow-rgb:217,164,6;--bs-btn-active-color:#000;--bs-btn-active-bg:#ffcd39;--bs-btn-active-border-color:#ffc720;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#000;--bs-btn-disabled-bg:#ffc107;--bs-btn-disabled-border-color:#ffc107}.btn-danger{--bs-btn-color:#fff;--bs-btn-bg:#dc3545;--bs-btn-border-color:#dc3545;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#bb2d3b;--bs-btn-hover-border-color:#b02a37;--bs-btn-focus-shadow-rgb:225,83,97;--bs-btn-active-color:#fff;--bs-btn-active-bg:#b02a37;--bs-btn-active-border-color:#a52834;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#fff;--bs-btn-disabled-bg:#dc3545;--bs-btn-disabled-border-color:#dc3545}.btn-light{--bs-btn-color:#000;--bs-btn-bg:#f8f9fa;--bs-btn-border-color:#f8f9fa;--bs-btn-hover-color:#000;--bs-btn-hover-bg:#d3d4d5;--bs-btn-hover-border-color:#c6c7c8;--bs-btn-focus-shadow-rgb:211,212,213;--bs-btn-active-color:#000;--bs-btn-active-bg:#c6c7c8;--bs-btn-active-border-color:#babbbc;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#000;--bs-btn-disabled-bg:#f8f9fa;--bs-btn-disabled-border-color:#f8f9fa}.btn-dark{--bs-btn-color:#fff;--bs-btn-bg:#212529;--bs-btn-border-color:#212529;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#424649;--bs-btn-hover-border-color:#373b3e;--bs-btn-focus-shadow-rgb:66,70,73;--bs-btn-active-color:#fff;--bs-btn-active-bg:#4d5154;--bs-btn-active-border-color:#373b3e;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#fff;--bs-btn-disabled-bg:#212529;--bs-btn-disabled-border-color:#212529}.btn-outline-primary{--bs-btn-color:#0d6efd;--bs-btn-border-color:#0d6efd;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#0d6efd;--bs-btn-hover-border-color:#0d6efd;--bs-btn-focus-shadow-rgb:13,110,253;--bs-btn-active-color:#fff;--bs-btn-active-bg:#0d6efd;--bs-btn-active-border-color:#0d6efd;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#0d6efd;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#0d6efd;--bs-gradient:none}.btn-outline-secondary{--bs-btn-color:#6c757d;--bs-btn-border-color:#6c757d;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#6c757d;--bs-btn-hover-border-color:#6c757d;--bs-btn-focus-shadow-rgb:108,117,125;--bs-btn-active-color:#fff;--bs-btn-active-bg:#6c757d;--bs-btn-active-border-color:#6c757d;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#6c757d;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#6c757d;--bs-gradient:none}.btn-outline-success{--bs-btn-color:#198754;--bs-btn-border-color:#198754;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#198754;--bs-btn-hover-border-color:#198754;--bs-btn-focus-shadow-rgb:25,135,84;--bs-btn-active-color:#fff;--bs-btn-active-bg:#198754;--bs-btn-active-border-color:#198754;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#198754;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#198754;--bs-gradient:none}.btn-outline-info{--bs-btn-color:#0dcaf0;--bs-btn-border-color:#0dcaf0;--bs-btn-hover-color:#000;--bs-btn-hover-bg:#0dcaf0;--bs-btn-hover-border-color:#0dcaf0;--bs-btn-focus-shadow-rgb:13,202,240;--bs-btn-active-color:#000;--bs-btn-active-bg:#0dcaf0;--bs-btn-active-border-color:#0dcaf0;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#0dcaf0;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#0dcaf0;--bs-gradient:none}.btn-outline-warning{--bs-btn-color:#ffc107;--bs-btn-border-color:#ffc107;--bs-btn-hover-color:#000;--bs-btn-hover-bg:#ffc107;--bs-btn-hover-border-color:#ffc107;--bs-btn-focus-shadow-rgb:255,193,7;--bs-btn-active-color:#000;--bs-btn-active-bg:#ffc107;--bs-btn-active-border-color:#ffc107;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#ffc107;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#ffc107;--bs-gradient:none}.btn-outline-danger{--bs-btn-color:#dc3545;--bs-btn-border-color:#dc3545;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#dc3545;--bs-btn-hover-border-color:#dc3545;--bs-btn-focus-shadow-rgb:220,53,69;--bs-btn-active-color:#fff;--bs-btn-active-bg:#dc3545;--bs-btn-active-border-color:#dc3545;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#dc3545;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#dc3545;--bs-gradient:none}.btn-outline-light{--bs-btn-color:#f8f9fa;--bs-btn-border-color:#f8f9fa;--bs-btn-hover-color:#000;--bs-btn-hover-bg:#f8f9fa;--bs-btn-hover-border-color:#f8f9fa;--bs-btn-focus-shadow-rgb:248,249,250;--bs-btn-active-color:#000;--bs-btn-active-bg:#f8f9fa;--bs-btn-active-border-color:#f8f9fa;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#f8f9fa;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#f8f9fa;--bs-gradient:none}.btn-outline-dark{--bs-btn-color:#212529;--bs-btn-border-color:#212529;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#212529;--bs-btn-hover-border-color:#212529;--bs-btn-focus-shadow-rgb:33,37,41;--bs-btn-active-color:#fff;--bs-btn-active-bg:#212529;--bs-btn-active-border-color:#212529;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#212529;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#212529;--bs-gradient:none}.btn-link{--bs-btn-font-weight:400;--bs-btn-color:var(--bs-link-color);--bs-btn-bg:transparent;--bs-btn-border-color:transparent;--bs-btn-hover-color:var(--bs-link-hover-color);--bs-btn-hover-border-color:transparent;--bs-btn-active-color:var(--bs-link-hover-color);--bs-btn-active-border-color:transparent;--bs-btn-disabled-color:#6c757d;--bs-btn-disabled-border-color:transparent;--bs-btn-box-shadow:0 0 0 #000;--bs-btn-focus-shadow-rgb:49,132,253;text-decoration:underline}.btn-link:focus-visible{color:var(--bs-btn-color)}.btn-link:hover{color:var(--bs-btn-hover-color)}.btn-group-lg>.btn,.btn-lg{--bs-btn-padding-y:0.5rem;--bs-btn-padding-x:1rem;--bs-btn-font-size:1.25rem;--bs-btn-border-radius:var(--bs-border-radius-lg)}.btn-group-sm>.btn,.btn-sm{--bs-btn-padding-y:0.25rem;--bs-btn-padding-x:0.5rem;--bs-btn-font-size:0.875rem;--bs-btn-border-radius:var(--bs-border-radius-sm)}.fade{transition:opacity .15s linear}@media (prefers-reduced-motion:reduce){.fade{transition:none}}.fade:not(.show){opacity:0}.collapse:not(.show){display:none}.collapsing{height:0;overflow:hidden;transition:height .35s ease}@media (prefers-reduced-motion:reduce){.collapsing{transition:none}}.collapsing.collapse-horizontal{width:0;height:auto;transition:width .35s ease}@media (prefers-reduced-motion:reduce){.collapsing.collapse-horizontal{transition:none}}.dropdown,.dropdown-center,.dropend,.dropstart,.dropup,.dropup-center{position:relative}.dropdown-toggle{white-space:nowrap}.dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:"";border-top:.3em solid;border-right:.3em solid transparent;border-bottom:0;border-left:.3em solid transparent}.dropdown-toggle:empty::after{margin-left:0}.dropdown-menu{--bs-dropdown-zindex:1000;--bs-dropdown-min-width:10rem;--bs-dropdown-padding-x:0;--bs-dropdown-padding-y:0.5rem;--bs-dropdown-spacer:0.125rem;--bs-dropdown-font-size:1rem;--bs-dropdown-color:var(--bs-body-color);--bs-dropdown-bg:var(--bs-body-bg);--bs-dropdown-border-color:var(--bs-border-color-translucent);--bs-dropdown-border-radius:var(--bs-border-radius);--bs-dropdown-border-width:var(--bs-border-width);--bs-dropdown-inner-border-radius:calc(var(--bs-border-radius) - var(--bs-border-width));--bs-dropdown-divider-bg:var(--bs-border-color-translucent);--bs-dropdown-divider-margin-y:0.5rem;--bs-dropdown-box-shadow:var(--bs-box-shadow);--bs-dropdown-link-color:var(--bs-body-color);--bs-dropdown-link-hover-color:var(--bs-body-color);--bs-dropdown-link-hover-bg:var(--bs-tertiary-bg);--bs-dropdown-link-active-color:#fff;--bs-dropdown-link-active-bg:#0d6efd;--bs-dropdown-link-disabled-color:var(--bs-tertiary-color);--bs-dropdown-item-padding-x:1rem;--bs-dropdown-item-padding-y:0.25rem;--bs-dropdown-header-color:#6c757d;--bs-dropdown-header-padding-x:1rem;--bs-dropdown-header-padding-y:0.5rem;position:absolute;z-index:var(--bs-dropdown-zindex);display:none;min-width:var(--bs-dropdown-min-width);padding:var(--bs-dropdown-padding-y) var(--bs-dropdown-padding-x);margin:0;font-size:var(--bs-dropdown-font-size);color:var(--bs-dropdown-color);text-align:left;list-style:none;background-color:var(--bs-dropdown-bg);background-clip:padding-box;border:var(--bs-dropdown-border-width) solid var(--bs-dropdown-border-color);border-radius:var(--bs-dropdown-border-radius)}.dropdown-menu[data-bs-popper]{top:100%;left:0;margin-top:var(--bs-dropdown-spacer)}.dropdown-menu-start{--bs-position:start}.dropdown-menu-start[data-bs-popper]{right:auto;left:0}.dropdown-menu-end{--bs-position:end}.dropdown-menu-end[data-bs-popper]{right:0;left:auto}@media (min-width:576px){.dropdown-menu-sm-start{--bs-position:start}.dropdown-menu-sm-start[data-bs-popper]{right:auto;left:0}.dropdown-menu-sm-end{--bs-position:end}.dropdown-menu-sm-end[data-bs-popper]{right:0;left:auto}}@media (min-width:768px){.dropdown-menu-md-start{--bs-position:start}.dropdown-menu-md-start[data-bs-popper]{right:auto;left:0}.dropdown-menu-md-end{--bs-position:end}.dropdown-menu-md-end[data-bs-popper]{right:0;left:auto}}@media (min-width:992px){.dropdown-menu-lg-start{--bs-position:start}.dropdown-menu-lg-start[data-bs-popper]{right:auto;left:0}.dropdown-menu-lg-end{--bs-position:end}.dropdown-menu-lg-end[data-bs-popper]{right:0;left:auto}}@media (min-width:1200px){.dropdown-menu-xl-start{--bs-position:start}.dropdown-menu-xl-start[data-bs-popper]{right:auto;left:0}.dropdown-menu-xl-end{--bs-position:end}.dropdown-menu-xl-end[data-bs-popper]{right:0;left:auto}}@media (min-width:1400px){.dropdown-menu-xxl-start{--bs-position:start}.dropdown-menu-xxl-start[data-bs-popper]{right:auto;left:0}.dropdown-menu-xxl-end{--bs-position:end}.dropdown-menu-xxl-end[data-bs-popper]{right:0;left:auto}}.dropup .dropdown-menu[data-bs-popper]{top:auto;bottom:100%;margin-top:0;margin-bottom:var(--bs-dropdown-spacer)}.dropup .dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:"";border-top:0;border-right:.3em solid transparent;border-bottom:.3em solid;border-left:.3em solid transparent}.dropup .dropdown-toggle:empty::after{margin-left:0}.dropend .dropdown-menu[data-bs-popper]{top:0;right:auto;left:100%;margin-top:0;margin-left:var(--bs-dropdown-spacer)}.dropend .dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:"";border-top:.3em solid transparent;border-right:0;border-bottom:.3em solid transparent;border-left:.3em solid}.dropend .dropdown-toggle:empty::after{margin-left:0}.dropend .dropdown-toggle::after{vertical-align:0}.dropstart .dropdown-menu[data-bs-popper]{top:0;right:100%;left:auto;margin-top:0;margin-right:var(--bs-dropdown-spacer)}.dropstart .dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:""}.dropstart .dropdown-toggle::after{display:none}.dropstart .dropdown-toggle::before{display:inline-block;margin-right:.255em;vertical-align:.255em;content:"";border-top:.3em solid transparent;border-right:.3em solid;border-bottom:.3em solid transparent}.dropstart .dropdown-toggle:empty::after{margin-left:0}.dropstart .dropdown-toggle::before{vertical-align:0}.dropdown-divider{height:0;margin:var(--bs-dropdown-divider-margin-y) 0;overflow:hidden;border-top:1px solid var(--bs-dropdown-divider-bg);opacity:1}.dropdown-item{display:block;width:100%;padding:var(--bs-dropdown-item-padding-y) var(--bs-dropdown-item-padding-x);clear:both;font-weight:400;color:var(--bs-dropdown-link-color);text-align:inherit;text-decoration:none;white-space:nowrap;background-color:transparent;border:0;border-radius:var(--bs-dropdown-item-border-radius,0)}.dropdown-item:focus,.dropdown-item:hover{color:var(--bs-dropdown-link-hover-color);background-color:var(--bs-dropdown-link-hover-bg)}.dropdown-item.active,.dropdown-item:active{color:var(--bs-dropdown-link-active-color);text-decoration:none;background-color:var(--bs-dropdown-link-active-bg)}.dropdown-item.disabled,.dropdown-item:disabled{color:var(--bs-dropdown-link-disabled-color);pointer-events:none;background-color:transparent}.dropdown-menu.show{display:block}.dropdown-header{display:block;padding:var(--bs-dropdown-header-padding-y) var(--bs-dropdown-header-padding-x);margin-bottom:0;font-size:.875rem;color:var(--bs-dropdown-header-color);white-space:nowrap}.dropdown-item-text{display:block;padding:var(--bs-dropdown-item-padding-y) var(--bs-dropdown-item-padding-x);color:var(--bs-dropdown-link-color)}.dropdown-menu-dark{--bs-dropdown-color:#dee2e6;--bs-dropdown-bg:#343a40;--bs-dropdown-border-color:var(--bs-border-color-translucent);--bs-dropdown-box-shadow: ;--bs-dropdown-link-color:#dee2e6;--bs-dropdown-link-hover-color:#fff;--bs-dropdown-divider-bg:var(--bs-border-color-translucent);--bs-dropdown-link-hover-bg:rgba(255, 255, 255, 0.15);--bs-dropdown-link-active-color:#fff;--bs-dropdown-link-active-bg:#0d6efd;--bs-dropdown-link-disabled-color:#adb5bd;--bs-dropdown-header-color:#adb5bd}.btn-group,.btn-group-vertical{position:relative;display:inline-flex;vertical-align:middle}.btn-group-vertical>.btn,.btn-group>.btn{position:relative;flex:1 1 auto}.btn-group-vertical>.btn-check:checked+.btn,.btn-group-vertical>.btn-check:focus+.btn,.btn-group-vertical>.btn.active,.btn-group-vertical>.btn:active,.btn-group-vertical>.btn:focus,.btn-group-vertical>.btn:hover,.btn-group>.btn-check:checked+.btn,.btn-group>.btn-check:focus+.btn,.btn-group>.btn.active,.btn-group>.btn:active,.btn-group>.btn:focus,.btn-group>.btn:hover{z-index:1}.btn-toolbar{display:flex;flex-wrap:wrap;justify-content:flex-start}.btn-toolbar .input-group{width:auto}.btn-group{border-radius:var(--bs-border-radius)}.btn-group>.btn-group:not(:first-child),.btn-group>:not(.btn-check:first-child)+.btn{margin-left:calc(-1 * var(--bs-border-width))}.btn-group>.btn-group:not(:last-child)>.btn,.btn-group>.btn.dropdown-toggle-split:first-child,.btn-group>.btn:not(:last-child):not(.dropdown-toggle){border-top-right-radius:0;border-bottom-right-radius:0}.btn-group>.btn-group:not(:first-child)>.btn,.btn-group>.btn:nth-child(n+3),.btn-group>:not(.btn-check)+.btn{border-top-left-radius:0;border-bottom-left-radius:0}.dropdown-toggle-split{padding-right:.5625rem;padding-left:.5625rem}.dropdown-toggle-split::after,.dropend .dropdown-toggle-split::after,.dropup .dropdown-toggle-split::after{margin-left:0}.dropstart .dropdown-toggle-split::before{margin-right:0}.btn-group-sm>.btn+.dropdown-toggle-split,.btn-sm+.dropdown-toggle-split{padding-right:.375rem;padding-left:.375rem}.btn-group-lg>.btn+.dropdown-toggle-split,.btn-lg+.dropdown-toggle-split{padding-right:.75rem;padding-left:.75rem}.btn-group-vertical{flex-direction:column;align-items:flex-start;justify-content:center}.btn-group-vertical>.btn,.btn-group-vertical>.btn-group{width:100%}.btn-group-vertical>.btn-group:not(:first-child),.btn-group-vertical>.btn:not(:first-child){margin-top:calc(-1 * var(--bs-border-width))}.btn-group-vertical>.btn-group:not(:last-child)>.btn,.btn-group-vertical>.btn:not(:last-child):not(.dropdown-toggle){border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn-group:not(:first-child)>.btn,.btn-group-vertical>.btn:nth-child(n+3),.btn-group-vertical>:not(.btn-check)+.btn{border-top-left-radius:0;border-top-right-radius:0}.nav{--bs-nav-link-padding-x:1rem;--bs-nav-link-padding-y:0.5rem;--bs-nav-link-font-weight: ;--bs-nav-link-color:var(--bs-link-color);--bs-nav-link-hover-color:var(--bs-link-hover-color);--bs-nav-link-disabled-color:var(--bs-secondary-color);display:flex;flex-wrap:wrap;padding-left:0;margin-bottom:0;list-style:none}.nav-link{display:block;padding:var(--bs-nav-link-padding-y) var(--bs-nav-link-padding-x);font-size:var(--bs-nav-link-font-size);font-weight:var(--bs-nav-link-font-weight);color:var(--bs-nav-link-color);text-decoration:none;background:0 0;border:0;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out}@media (prefers-reduced-motion:reduce){.nav-link{transition:none}}.nav-link:focus,.nav-link:hover{color:var(--bs-nav-link-hover-color)}.nav-link:focus-visible{outline:0;box-shadow:0 0 0 .25rem rgba(13,110,253,.25)}.nav-link.disabled,.nav-link:disabled{color:var(--bs-nav-link-disabled-color);pointer-events:none;cursor:default}.nav-tabs{--bs-nav-tabs-border-width:var(--bs-border-width);--bs-nav-tabs-border-color:var(--bs-border-color);--bs-nav-tabs-border-radius:var(--bs-border-radius);--bs-nav-tabs-link-hover-border-color:var(--bs-secondary-bg) var(--bs-secondary-bg) var(--bs-border-color);--bs-nav-tabs-link-active-color:var(--bs-emphasis-color);--bs-nav-tabs-link-active-bg:var(--bs-body-bg);--bs-nav-tabs-link-active-border-color:var(--bs-border-color) var(--bs-border-color) var(--bs-body-bg);border-bottom:var(--bs-nav-tabs-border-width) solid var(--bs-nav-tabs-border-color)}.nav-tabs .nav-link{margin-bottom:calc(-1 * var(--bs-nav-tabs-border-width));border:var(--bs-nav-tabs-border-width) solid transparent;border-top-left-radius:var(--bs-nav-tabs-border-radius);border-top-right-radius:var(--bs-nav-tabs-border-radius)}.nav-tabs .nav-link:focus,.nav-tabs .nav-link:hover{isolation:isolate;border-color:var(--bs-nav-tabs-link-hover-border-color)}.nav-tabs .nav-item.show .nav-link,.nav-tabs .nav-link.active{color:var(--bs-nav-tabs-link-active-color);background-color:var(--bs-nav-tabs-link-active-bg);border-color:var(--bs-nav-tabs-link-active-border-color)}.nav-tabs .dropdown-menu{margin-top:calc(-1 * var(--bs-nav-tabs-border-width));border-top-left-radius:0;border-top-right-radius:0}.nav-pills{--bs-nav-pills-border-radius:var(--bs-border-radius);--bs-nav-pills-link-active-color:#fff;--bs-nav-pills-link-active-bg:#0d6efd}.nav-pills .nav-link{border-radius:var(--bs-nav-pills-border-radius)}.nav-pills .nav-link.active,.nav-pills .show>.nav-link{color:var(--bs-nav-pills-link-active-color);background-color:var(--bs-nav-pills-link-active-bg)}.nav-underline{--bs-nav-underline-gap:1rem;--bs-nav-underline-border-width:0.125rem;--bs-nav-underline-link-active-color:var(--bs-emphasis-color);gap:var(--bs-nav-underline-gap)}.nav-underline .nav-link{padding-right:0;padding-left:0;border-bottom:var(--bs-nav-underline-border-width) solid transparent}.nav-underline .nav-link:focus,.nav-underline .nav-link:hover{border-bottom-color:currentcolor}.nav-underline .nav-link.active,.nav-underline .show>.nav-link{font-weight:700;color:var(--bs-nav-underline-link-active-color);border-bottom-color:currentcolor}.nav-fill .nav-item,.nav-fill>.nav-link{flex:1 1 auto;text-align:center}.nav-justified .nav-item,.nav-justified>.nav-link{flex-grow:1;flex-basis:0;text-align:center}.nav-fill .nav-item .nav-link,.nav-justified .nav-item .nav-link{width:100%}.tab-content>.tab-pane{display:none}.tab-content>.active{display:block}.navbar{--bs-navbar-padding-x:0;--bs-navbar-padding-y:0.5rem;--bs-navbar-color:rgba(var(--bs-emphasis-color-rgb), 0.65);--bs-navbar-hover-color:rgba(var(--bs-emphasis-color-rgb), 0.8);--bs-navbar-disabled-color:rgba(var(--bs-emphasis-color-rgb), 0.3);--bs-navbar-active-color:rgba(var(--bs-emphasis-color-rgb), 1);--bs-navbar-brand-padding-y:0.3125rem;--bs-navbar-brand-margin-end:1rem;--bs-navbar-brand-font-size:1.25rem;--bs-navbar-brand-color:rgba(var(--bs-emphasis-color-rgb), 1);--bs-navbar-brand-hover-color:rgba(var(--bs-emphasis-color-rgb), 1);--bs-navbar-nav-link-padding-x:0.5rem;--bs-navbar-toggler-padding-y:0.25rem;--bs-navbar-toggler-padding-x:0.75rem;--bs-navbar-toggler-font-size:1.25rem;--bs-navbar-toggler-icon-bg:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 30 30'%3e%3cpath stroke='rgba%2833, 37, 41, 0.75%29' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e");--bs-navbar-toggler-border-color:rgba(var(--bs-emphasis-color-rgb), 0.15);--bs-navbar-toggler-border-radius:var(--bs-border-radius);--bs-navbar-toggler-focus-width:0.25rem;--bs-navbar-toggler-transition:box-shadow 0.15s ease-in-out;position:relative;display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;padding:var(--bs-navbar-padding-y) var(--bs-navbar-padding-x)}.navbar>.container,.navbar>.container-fluid,.navbar>.container-lg,.navbar>.container-md,.navbar>.container-sm,.navbar>.container-xl,.navbar>.container-xxl{display:flex;flex-wrap:inherit;align-items:center;justify-content:space-between}.navbar-brand{padding-top:var(--bs-navbar-brand-padding-y);padding-bottom:var(--bs-navbar-brand-padding-y);margin-right:var(--bs-navbar-brand-margin-end);font-size:var(--bs-navbar-brand-font-size);color:var(--bs-navbar-brand-color);text-decoration:none;white-space:nowrap}.navbar-brand:focus,.navbar-brand:hover{color:var(--bs-navbar-brand-hover-color)}.navbar-nav{--bs-nav-link-padding-x:0;--bs-nav-link-padding-y:0.5rem;--bs-nav-link-font-weight: ;--bs-nav-link-color:var(--bs-navbar-color);--bs-nav-link-hover-color:var(--bs-navbar-hover-color);--bs-nav-link-disabled-color:var(--bs-navbar-disabled-color);display:flex;flex-direction:column;padding-left:0;margin-bottom:0;list-style:none}.navbar-nav .nav-link.active,.navbar-nav .nav-link.show{color:var(--bs-navbar-active-color)}.navbar-nav .dropdown-menu{position:static}.navbar-text{padding-top:.5rem;padding-bottom:.5rem;color:var(--bs-navbar-color)}.navbar-text a,.navbar-text a:focus,.navbar-text a:hover{color:var(--bs-navbar-active-color)}.navbar-collapse{flex-grow:1;flex-basis:100%;align-items:center}.navbar-toggler{padding:var(--bs-navbar-toggler-padding-y) var(--bs-navbar-toggler-padding-x);font-size:var(--bs-navbar-toggler-font-size);line-height:1;color:var(--bs-navbar-color);background-color:transparent;border:var(--bs-border-width) solid var(--bs-navbar-toggler-border-color);border-radius:var(--bs-navbar-toggler-border-radius);transition:var(--bs-navbar-toggler-transition)}@media (prefers-reduced-motion:reduce){.navbar-toggler{transition:none}}.navbar-toggler:hover{text-decoration:none}.navbar-toggler:focus{text-decoration:none;outline:0;box-shadow:0 0 0 var(--bs-navbar-toggler-focus-width)}.navbar-toggler-icon{display:inline-block;width:1.5em;height:1.5em;vertical-align:middle;background-image:var(--bs-navbar-toggler-icon-bg);background-repeat:no-repeat;background-position:center;background-size:100%}.navbar-nav-scroll{max-height:var(--bs-scroll-height,75vh);overflow-y:auto}@media (min-width:576px){.navbar-expand-sm{flex-wrap:nowrap;justify-content:flex-start}.navbar-expand-sm .navbar-nav{flex-direction:row}.navbar-expand-sm .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-sm .navbar-nav .nav-link{padding-right:var(--bs-navbar-nav-link-padding-x);padding-left:var(--bs-navbar-nav-link-padding-x)}.navbar-expand-sm .navbar-nav-scroll{overflow:visible}.navbar-expand-sm .navbar-collapse{display:flex!important;flex-basis:auto}.navbar-expand-sm .navbar-toggler{display:none}.navbar-expand-sm .offcanvas{position:static;z-index:auto;flex-grow:1;width:auto!important;height:auto!important;visibility:visible!important;background-color:transparent!important;border:0!important;transform:none!important;transition:none}.navbar-expand-sm .offcanvas .offcanvas-header{display:none}.navbar-expand-sm .offcanvas .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible}}@media (min-width:768px){.navbar-expand-md{flex-wrap:nowrap;justify-content:flex-start}.navbar-expand-md .navbar-nav{flex-direction:row}.navbar-expand-md .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-md .navbar-nav .nav-link{padding-right:var(--bs-navbar-nav-link-padding-x);padding-left:var(--bs-navbar-nav-link-padding-x)}.navbar-expand-md .navbar-nav-scroll{overflow:visible}.navbar-expand-md .navbar-collapse{display:flex!important;flex-basis:auto}.navbar-expand-md .navbar-toggler{display:none}.navbar-expand-md .offcanvas{position:static;z-index:auto;flex-grow:1;width:auto!important;height:auto!important;visibility:visible!important;background-color:transparent!important;border:0!important;transform:none!important;transition:none}.navbar-expand-md .offcanvas .offcanvas-header{display:none}.navbar-expand-md .offcanvas .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible}}@media (min-width:992px){.navbar-expand-lg{flex-wrap:nowrap;justify-content:flex-start}.navbar-expand-lg .navbar-nav{flex-direction:row}.navbar-expand-lg .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-lg .navbar-nav .nav-link{padding-right:var(--bs-navbar-nav-link-padding-x);padding-left:var(--bs-navbar-nav-link-padding-x)}.navbar-expand-lg .navbar-nav-scroll{overflow:visible}.navbar-expand-lg .navbar-collapse{display:flex!important;flex-basis:auto}.navbar-expand-lg .navbar-toggler{display:none}.navbar-expand-lg .offcanvas{position:static;z-index:auto;flex-grow:1;width:auto!important;height:auto!important;visibility:visible!important;background-color:transparent!important;border:0!important;transform:none!important;transition:none}.navbar-expand-lg .offcanvas .offcanvas-header{display:none}.navbar-expand-lg .offcanvas .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible}}@media (min-width:1200px){.navbar-expand-xl{flex-wrap:nowrap;justify-content:flex-start}.navbar-expand-xl .navbar-nav{flex-direction:row}.navbar-expand-xl .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-xl .navbar-nav .nav-link{padding-right:var(--bs-navbar-nav-link-padding-x);padding-left:var(--bs-navbar-nav-link-padding-x)}.navbar-expand-xl .navbar-nav-scroll{overflow:visible}.navbar-expand-xl .navbar-collapse{display:flex!important;flex-basis:auto}.navbar-expand-xl .navbar-toggler{display:none}.navbar-expand-xl .offcanvas{position:static;z-index:auto;flex-grow:1;width:auto!important;height:auto!important;visibility:visible!important;background-color:transparent!important;border:0!important;transform:none!important;transition:none}.navbar-expand-xl .offcanvas .offcanvas-header{display:none}.navbar-expand-xl .offcanvas .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible}}@media (min-width:1400px){.navbar-expand-xxl{flex-wrap:nowrap;justify-content:flex-start}.navbar-expand-xxl .navbar-nav{flex-direction:row}.navbar-expand-xxl .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-xxl .navbar-nav .nav-link{padding-right:var(--bs-navbar-nav-link-padding-x);padding-left:var(--bs-navbar-nav-link-padding-x)}.navbar-expand-xxl .navbar-nav-scroll{overflow:visible}.navbar-expand-xxl .navbar-collapse{display:flex!important;flex-basis:auto}.navbar-expand-xxl .navbar-toggler{display:none}.navbar-expand-xxl .offcanvas{position:static;z-index:auto;flex-grow:1;width:auto!important;height:auto!important;visibility:visible!important;background-color:transparent!important;border:0!important;transform:none!important;transition:none}.navbar-expand-xxl .offcanvas .offcanvas-header{display:none}.navbar-expand-xxl .offcanvas .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible}}.navbar-expand{flex-wrap:nowrap;justify-content:flex-start}.navbar-expand .navbar-nav{flex-direction:row}.navbar-expand .navbar-nav .dropdown-menu{position:absolute}.navbar-expand .navbar-nav .nav-link{padding-right:var(--bs-navbar-nav-link-padding-x);padding-left:var(--bs-navbar-nav-link-padding-x)}.navbar-expand .navbar-nav-scroll{overflow:visible}.navbar-expand .navbar-collapse{display:flex!important;flex-basis:auto}.navbar-expand .navbar-toggler{display:none}.navbar-expand .offcanvas{position:static;z-index:auto;flex-grow:1;width:auto!important;height:auto!important;visibility:visible!important;background-color:transparent!important;border:0!important;transform:none!important;transition:none}.navbar-expand .offcanvas .offcanvas-header{display:none}.navbar-expand .offcanvas .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible}.navbar-dark,.navbar[data-bs-theme=dark]{--bs-navbar-color:rgba(255, 255, 255, 0.55);--bs-navbar-hover-color:rgba(255, 255, 255, 0.75);--bs-navbar-disabled-color:rgba(255, 255, 255, 0.25);--bs-navbar-active-color:#fff;--bs-navbar-brand-color:#fff;--bs-navbar-brand-hover-color:#fff;--bs-navbar-toggler-border-color:rgba(255, 255, 255, 0.1);--bs-navbar-toggler-icon-bg:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 30 30'%3e%3cpath stroke='rgba%28255, 255, 255, 0.55%29' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e")}[data-bs-theme=dark] .navbar-toggler-icon{--bs-navbar-toggler-icon-bg:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 30 30'%3e%3cpath stroke='rgba%28255, 255, 255, 0.55%29' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e")}.card{--bs-card-spacer-y:1rem;--bs-card-spacer-x:1rem;--bs-card-title-spacer-y:0.5rem;--bs-card-title-color: ;--bs-card-subtitle-color: ;--bs-card-border-width:var(--bs-border-width);--bs-card-border-color:var(--bs-border-color-translucent);--bs-card-border-radius:var(--bs-border-radius);--bs-card-box-shadow: ;--bs-card-inner-border-radius:calc(var(--bs-border-radius) - (var(--bs-border-width)));--bs-card-cap-padding-y:0.5rem;--bs-card-cap-padding-x:1rem;--bs-card-cap-bg:rgba(var(--bs-body-color-rgb), 0.03);--bs-card-cap-color: ;--bs-card-height: ;--bs-card-color: ;--bs-card-bg:var(--bs-body-bg);--bs-card-img-overlay-padding:1rem;--bs-card-group-margin:0.75rem;position:relative;display:flex;flex-direction:column;min-width:0;height:var(--bs-card-height);color:var(--bs-body-color);word-wrap:break-word;background-color:var(--bs-card-bg);background-clip:border-box;border:var(--bs-card-border-width) solid var(--bs-card-border-color);border-radius:var(--bs-card-border-radius)}.card>hr{margin-right:0;margin-left:0}.card>.list-group{border-top:inherit;border-bottom:inherit}.card>.list-group:first-child{border-top-width:0;border-top-left-radius:var(--bs-card-inner-border-radius);border-top-right-radius:var(--bs-card-inner-border-radius)}.card>.list-group:last-child{border-bottom-width:0;border-bottom-right-radius:var(--bs-card-inner-border-radius);border-bottom-left-radius:var(--bs-card-inner-border-radius)}.card>.card-header+.list-group,.card>.list-group+.card-footer{border-top:0}.card-body{flex:1 1 auto;padding:var(--bs-card-spacer-y) var(--bs-card-spacer-x);color:var(--bs-card-color)}.card-title{margin-bottom:var(--bs-card-title-spacer-y);color:var(--bs-card-title-color)}.card-subtitle{margin-top:calc(-.5 * var(--bs-card-title-spacer-y));margin-bottom:0;color:var(--bs-card-subtitle-color)}.card-text:last-child{margin-bottom:0}.card-link+.card-link{margin-left:var(--bs-card-spacer-x)}.card-header{padding:var(--bs-card-cap-padding-y) var(--bs-card-cap-padding-x);margin-bottom:0;color:var(--bs-card-cap-color);background-color:var(--bs-card-cap-bg);border-bottom:var(--bs-card-border-width) solid var(--bs-card-border-color)}.card-header:first-child{border-radius:var(--bs-card-inner-border-radius) var(--bs-card-inner-border-radius) 0 0}.card-footer{padding:var(--bs-card-cap-padding-y) var(--bs-card-cap-padding-x);color:var(--bs-card-cap-color);background-color:var(--bs-card-cap-bg);border-top:var(--bs-card-border-width) solid var(--bs-card-border-color)}.card-footer:last-child{border-radius:0 0 var(--bs-card-inner-border-radius) var(--bs-card-inner-border-radius)}.card-header-tabs{margin-right:calc(-.5 * var(--bs-card-cap-padding-x));margin-bottom:calc(-1 * var(--bs-card-cap-padding-y));margin-left:calc(-.5 * var(--bs-card-cap-padding-x));border-bottom:0}.card-header-tabs .nav-link.active{background-color:var(--bs-card-bg);border-bottom-color:var(--bs-card-bg)}.card-header-pills{margin-right:calc(-.5 * var(--bs-card-cap-padding-x));margin-left:calc(-.5 * var(--bs-card-cap-padding-x))}.card-img-overlay{position:absolute;top:0;right:0;bottom:0;left:0;padding:var(--bs-card-img-overlay-padding);border-radius:var(--bs-card-inner-border-radius)}.card-img,.card-img-bottom,.card-img-top{width:100%}.card-img,.card-img-top{border-top-left-radius:var(--bs-card-inner-border-radius);border-top-right-radius:var(--bs-card-inner-border-radius)}.card-img,.card-img-bottom{border-bottom-right-radius:var(--bs-card-inner-border-radius);border-bottom-left-radius:var(--bs-card-inner-border-radius)}.card-group>.card{margin-bottom:var(--bs-card-group-margin)}@media (min-width:576px){.card-group{display:flex;flex-flow:row wrap}.card-group>.card{flex:1 0 0;margin-bottom:0}.card-group>.card+.card{margin-left:0;border-left:0}.card-group>.card:not(:last-child){border-top-right-radius:0;border-bottom-right-radius:0}.card-group>.card:not(:last-child)>.card-header,.card-group>.card:not(:last-child)>.card-img-top{border-top-right-radius:0}.card-group>.card:not(:last-child)>.card-footer,.card-group>.card:not(:last-child)>.card-img-bottom{border-bottom-right-radius:0}.card-group>.card:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0}.card-group>.card:not(:first-child)>.card-header,.card-group>.card:not(:first-child)>.card-img-top{border-top-left-radius:0}.card-group>.card:not(:first-child)>.card-footer,.card-group>.card:not(:first-child)>.card-img-bottom{border-bottom-left-radius:0}}.accordion{--bs-accordion-color:var(--bs-body-color);--bs-accordion-bg:var(--bs-body-bg);--bs-accordion-transition:color 0.15s ease-in-out,background-color 0.15s ease-in-out,border-color 0.15s ease-in-out,box-shadow 0.15s ease-in-out,border-radius 0.15s ease;--bs-accordion-border-color:var(--bs-border-color);--bs-accordion-border-width:var(--bs-border-width);--bs-accordion-border-radius:var(--bs-border-radius);--bs-accordion-inner-border-radius:calc(var(--bs-border-radius) - (var(--bs-border-width)));--bs-accordion-btn-padding-x:1.25rem;--bs-accordion-btn-padding-y:1rem;--bs-accordion-btn-color:var(--bs-body-color);--bs-accordion-btn-bg:var(--bs-accordion-bg);--bs-accordion-btn-icon:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='%23212529' stroke-linecap='round' stroke-linejoin='round'%3e%3cpath d='m2 5 6 6 6-6'/%3e%3c/svg%3e");--bs-accordion-btn-icon-width:1.25rem;--bs-accordion-btn-icon-transform:rotate(-180deg);--bs-accordion-btn-icon-transition:transform 0.2s ease-in-out;--bs-accordion-btn-active-icon:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='%23052c65' stroke-linecap='round' stroke-linejoin='round'%3e%3cpath d='m2 5 6 6 6-6'/%3e%3c/svg%3e");--bs-accordion-btn-focus-box-shadow:0 0 0 0.25rem rgba(13, 110, 253, 0.25);--bs-accordion-body-padding-x:1.25rem;--bs-accordion-body-padding-y:1rem;--bs-accordion-active-color:var(--bs-primary-text-emphasis);--bs-accordion-active-bg:var(--bs-primary-bg-subtle)}.accordion-button{position:relative;display:flex;align-items:center;width:100%;padding:var(--bs-accordion-btn-padding-y) var(--bs-accordion-btn-padding-x);font-size:1rem;color:var(--bs-accordion-btn-color);text-align:left;background-color:var(--bs-accordion-btn-bg);border:0;border-radius:0;overflow-anchor:none;transition:var(--bs-accordion-transition)}@media (prefers-reduced-motion:reduce){.accordion-button{transition:none}}.accordion-button:not(.collapsed){color:var(--bs-accordion-active-color);background-color:var(--bs-accordion-active-bg);box-shadow:inset 0 calc(-1 * var(--bs-accordion-border-width)) 0 var(--bs-accordion-border-color)}.accordion-button:not(.collapsed)::after{background-image:var(--bs-accordion-btn-active-icon);transform:var(--bs-accordion-btn-icon-transform)}.accordion-button::after{flex-shrink:0;width:var(--bs-accordion-btn-icon-width);height:var(--bs-accordion-btn-icon-width);margin-left:auto;content:"";background-image:var(--bs-accordion-btn-icon);background-repeat:no-repeat;background-size:var(--bs-accordion-btn-icon-width);transition:var(--bs-accordion-btn-icon-transition)}@media (prefers-reduced-motion:reduce){.accordion-button::after{transition:none}}.accordion-button:hover{z-index:2}.accordion-button:focus{z-index:3;outline:0;box-shadow:var(--bs-accordion-btn-focus-box-shadow)}.accordion-header{margin-bottom:0}.accordion-item{color:var(--bs-accordion-color);background-color:var(--bs-accordion-bg);border:var(--bs-accordion-border-width) solid var(--bs-accordion-border-color)}.accordion-item:first-of-type{border-top-left-radius:var(--bs-accordion-border-radius);border-top-right-radius:var(--bs-accordion-border-radius)}.accordion-item:first-of-type>.accordion-header .accordion-button{border-top-left-radius:var(--bs-accordion-inner-border-radius);border-top-right-radius:var(--bs-accordion-inner-border-radius)}.accordion-item:not(:first-of-type){border-top:0}.accordion-item:last-of-type{border-bottom-right-radius:var(--bs-accordion-border-radius);border-bottom-left-radius:var(--bs-accordion-border-radius)}.accordion-item:last-of-type>.accordion-header .accordion-button.collapsed{border-bottom-right-radius:var(--bs-accordion-inner-border-radius);border-bottom-left-radius:var(--bs-accordion-inner-border-radius)}.accordion-item:last-of-type>.accordion-collapse{border-bottom-right-radius:var(--bs-accordion-border-radius);border-bottom-left-radius:var(--bs-accordion-border-radius)}.accordion-body{padding:var(--bs-accordion-body-padding-y) var(--bs-accordion-body-padding-x)}.accordion-flush>.accordion-item{border-right:0;border-left:0;border-radius:0}.accordion-flush>.accordion-item:first-child{border-top:0}.accordion-flush>.accordion-item:last-child{border-bottom:0}.accordion-flush>.accordion-item>.accordion-collapse,.accordion-flush>.accordion-item>.accordion-header .accordion-button,.accordion-flush>.accordion-item>.accordion-header .accordion-button.collapsed{border-radius:0}[data-bs-theme=dark] .accordion-button::after{--bs-accordion-btn-icon:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%236ea8fe'%3e%3cpath fill-rule='evenodd' d='M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708'/%3e%3c/svg%3e");--bs-accordion-btn-active-icon:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%236ea8fe'%3e%3cpath fill-rule='evenodd' d='M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708'/%3e%3c/svg%3e")}.breadcrumb{--bs-breadcrumb-padding-x:0;--bs-breadcrumb-padding-y:0;--bs-breadcrumb-margin-bottom:1rem;--bs-breadcrumb-bg: ;--bs-breadcrumb-border-radius: ;--bs-breadcrumb-divider-color:var(--bs-secondary-color);--bs-breadcrumb-item-padding-x:0.5rem;--bs-breadcrumb-item-active-color:var(--bs-secondary-color);display:flex;flex-wrap:wrap;padding:var(--bs-breadcrumb-padding-y) var(--bs-breadcrumb-padding-x);margin-bottom:var(--bs-breadcrumb-margin-bottom);font-size:var(--bs-breadcrumb-font-size);list-style:none;background-color:var(--bs-breadcrumb-bg);border-radius:var(--bs-breadcrumb-border-radius)}.breadcrumb-item+.breadcrumb-item{padding-left:var(--bs-breadcrumb-item-padding-x)}.breadcrumb-item+.breadcrumb-item::before{float:left;padding-right:var(--bs-breadcrumb-item-padding-x);color:var(--bs-breadcrumb-divider-color);content:var(--bs-breadcrumb-divider, "/")}.breadcrumb-item.active{color:var(--bs-breadcrumb-item-active-color)}.pagination{--bs-pagination-padding-x:0.75rem;--bs-pagination-padding-y:0.375rem;--bs-pagination-font-size:1rem;--bs-pagination-color:var(--bs-link-color);--bs-pagination-bg:var(--bs-body-bg);--bs-pagination-border-width:var(--bs-border-width);--bs-pagination-border-color:var(--bs-border-color);--bs-pagination-border-radius:var(--bs-border-radius);--bs-pagination-hover-color:var(--bs-link-hover-color);--bs-pagination-hover-bg:var(--bs-tertiary-bg);--bs-pagination-hover-border-color:var(--bs-border-color);--bs-pagination-focus-color:var(--bs-link-hover-color);--bs-pagination-focus-bg:var(--bs-secondary-bg);--bs-pagination-focus-box-shadow:0 0 0 0.25rem rgba(13, 110, 253, 0.25);--bs-pagination-active-color:#fff;--bs-pagination-active-bg:#0d6efd;--bs-pagination-active-border-color:#0d6efd;--bs-pagination-disabled-color:var(--bs-secondary-color);--bs-pagination-disabled-bg:var(--bs-secondary-bg);--bs-pagination-disabled-border-color:var(--bs-border-color);display:flex;padding-left:0;list-style:none}.page-link{position:relative;display:block;padding:var(--bs-pagination-padding-y) var(--bs-pagination-padding-x);font-size:var(--bs-pagination-font-size);color:var(--bs-pagination-color);text-decoration:none;background-color:var(--bs-pagination-bg);border:var(--bs-pagination-border-width) solid var(--bs-pagination-border-color);transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.page-link{transition:none}}.page-link:hover{z-index:2;color:var(--bs-pagination-hover-color);background-color:var(--bs-pagination-hover-bg);border-color:var(--bs-pagination-hover-border-color)}.page-link:focus{z-index:3;color:var(--bs-pagination-focus-color);background-color:var(--bs-pagination-focus-bg);outline:0;box-shadow:var(--bs-pagination-focus-box-shadow)}.active>.page-link,.page-link.active{z-index:3;color:var(--bs-pagination-active-color);background-color:var(--bs-pagination-active-bg);border-color:var(--bs-pagination-active-border-color)}.disabled>.page-link,.page-link.disabled{color:var(--bs-pagination-disabled-color);pointer-events:none;background-color:var(--bs-pagination-disabled-bg);border-color:var(--bs-pagination-disabled-border-color)}.page-item:not(:first-child) .page-link{margin-left:calc(-1 * var(--bs-border-width))}.page-item:first-child .page-link{border-top-left-radius:var(--bs-pagination-border-radius);border-bottom-left-radius:var(--bs-pagination-border-radius)}.page-item:last-child .page-link{border-top-right-radius:var(--bs-pagination-border-radius);border-bottom-right-radius:var(--bs-pagination-border-radius)}.pagination-lg{--bs-pagination-padding-x:1.5rem;--bs-pagination-padding-y:0.75rem;--bs-pagination-font-size:1.25rem;--bs-pagination-border-radius:var(--bs-border-radius-lg)}.pagination-sm{--bs-pagination-padding-x:0.5rem;--bs-pagination-padding-y:0.25rem;--bs-pagination-font-size:0.875rem;--bs-pagination-border-radius:var(--bs-border-radius-sm)}.badge{--bs-badge-padding-x:0.65em;--bs-badge-padding-y:0.35em;--bs-badge-font-size:0.75em;--bs-badge-font-weight:700;--bs-badge-color:#fff;--bs-badge-border-radius:var(--bs-border-radius);display:inline-block;padding:var(--bs-badge-padding-y) var(--bs-badge-padding-x);font-size:var(--bs-badge-font-size);font-weight:var(--bs-badge-font-weight);line-height:1;color:var(--bs-badge-color);text-align:center;white-space:nowrap;vertical-align:baseline;border-radius:var(--bs-badge-border-radius)}.badge:empty{display:none}.btn .badge{position:relative;top:-1px}.alert{--bs-alert-bg:transparent;--bs-alert-padding-x:1rem;--bs-alert-padding-y:1rem;--bs-alert-margin-bottom:1rem;--bs-alert-color:inherit;--bs-alert-border-color:transparent;--bs-alert-border:var(--bs-border-width) solid var(--bs-alert-border-color);--bs-alert-border-radius:var(--bs-border-radius);--bs-alert-link-color:inherit;position:relative;padding:var(--bs-alert-padding-y) var(--bs-alert-padding-x);margin-bottom:var(--bs-alert-margin-bottom);color:var(--bs-alert-color);background-color:var(--bs-alert-bg);border:var(--bs-alert-border);border-radius:var(--bs-alert-border-radius)}.alert-heading{color:inherit}.alert-link{font-weight:700;color:var(--bs-alert-link-color)}.alert-dismissible{padding-right:3rem}.alert-dismissible .btn-close{position:absolute;top:0;right:0;z-index:2;padding:1.25rem 1rem}.alert-primary{--bs-alert-color:var(--bs-primary-text-emphasis);--bs-alert-bg:var(--bs-primary-bg-subtle);--bs-alert-border-color:var(--bs-primary-border-subtle);--bs-alert-link-color:var(--bs-primary-text-emphasis)}.alert-secondary{--bs-alert-color:var(--bs-secondary-text-emphasis);--bs-alert-bg:var(--bs-secondary-bg-subtle);--bs-alert-border-color:var(--bs-secondary-border-subtle);--bs-alert-link-color:var(--bs-secondary-text-emphasis)}.alert-success{--bs-alert-color:var(--bs-success-text-emphasis);--bs-alert-bg:var(--bs-success-bg-subtle);--bs-alert-border-color:var(--bs-success-border-subtle);--bs-alert-link-color:var(--bs-success-text-emphasis)}.alert-info{--bs-alert-color:var(--bs-info-text-emphasis);--bs-alert-bg:var(--bs-info-bg-subtle);--bs-alert-border-color:var(--bs-info-border-subtle);--bs-alert-link-color:var(--bs-info-text-emphasis)}.alert-warning{--bs-alert-color:var(--bs-warning-text-emphasis);--bs-alert-bg:var(--bs-warning-bg-subtle);--bs-alert-border-color:var(--bs-warning-border-subtle);--bs-alert-link-color:var(--bs-warning-text-emphasis)}.alert-danger{--bs-alert-color:var(--bs-danger-text-emphasis);--bs-alert-bg:var(--bs-danger-bg-subtle);--bs-alert-border-color:var(--bs-danger-border-subtle);--bs-alert-link-color:var(--bs-danger-text-emphasis)}.alert-light{--bs-alert-color:var(--bs-light-text-emphasis);--bs-alert-bg:var(--bs-light-bg-subtle);--bs-alert-border-color:var(--bs-light-border-subtle);--bs-alert-link-color:var(--bs-light-text-emphasis)}.alert-dark{--bs-alert-color:var(--bs-dark-text-emphasis);--bs-alert-bg:var(--bs-dark-bg-subtle);--bs-alert-border-color:var(--bs-dark-border-subtle);--bs-alert-link-color:var(--bs-dark-text-emphasis)}@keyframes progress-bar-stripes{0%{background-position-x:var(--bs-progress-height)}}.progress,.progress-stacked{--bs-progress-height:1rem;--bs-progress-font-size:0.75rem;--bs-progress-bg:var(--bs-secondary-bg);--bs-progress-border-radius:var(--bs-border-radius);--bs-progress-box-shadow:var(--bs-box-shadow-inset);--bs-progress-bar-color:#fff;--bs-progress-bar-bg:#0d6efd;--bs-progress-bar-transition:width 0.6s ease;display:flex;height:var(--bs-progress-height);overflow:hidden;font-size:var(--bs-progress-font-size);background-color:var(--bs-progress-bg);border-radius:var(--bs-progress-border-radius)}.progress-bar{display:flex;flex-direction:column;justify-content:center;overflow:hidden;color:var(--bs-progress-bar-color);text-align:center;white-space:nowrap;background-color:var(--bs-progress-bar-bg);transition:var(--bs-progress-bar-transition)}@media (prefers-reduced-motion:reduce){.progress-bar{transition:none}}.progress-bar-striped{background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-size:var(--bs-progress-height) var(--bs-progress-height)}.progress-stacked>.progress{overflow:visible}.progress-stacked>.progress>.progress-bar{width:100%}.progress-bar-animated{animation:1s linear infinite progress-bar-stripes}@media (prefers-reduced-motion:reduce){.progress-bar-animated{animation:none}}.list-group{--bs-list-group-color:var(--bs-body-color);--bs-list-group-bg:var(--bs-body-bg);--bs-list-group-border-color:var(--bs-border-color);--bs-list-group-border-width:var(--bs-border-width);--bs-list-group-border-radius:var(--bs-border-radius);--bs-list-group-item-padding-x:1rem;--bs-list-group-item-padding-y:0.5rem;--bs-list-group-action-color:var(--bs-secondary-color);--bs-list-group-action-hover-color:var(--bs-emphasis-color);--bs-list-group-action-hover-bg:var(--bs-tertiary-bg);--bs-list-group-action-active-color:var(--bs-body-color);--bs-list-group-action-active-bg:var(--bs-secondary-bg);--bs-list-group-disabled-color:var(--bs-secondary-color);--bs-list-group-disabled-bg:var(--bs-body-bg);--bs-list-group-active-color:#fff;--bs-list-group-active-bg:#0d6efd;--bs-list-group-active-border-color:#0d6efd;display:flex;flex-direction:column;padding-left:0;margin-bottom:0;border-radius:var(--bs-list-group-border-radius)}.list-group-numbered{list-style-type:none;counter-reset:section}.list-group-numbered>.list-group-item::before{content:counters(section, ".") ". ";counter-increment:section}.list-group-item{position:relative;display:block;padding:var(--bs-list-group-item-padding-y) var(--bs-list-group-item-padding-x);color:var(--bs-list-group-color);text-decoration:none;background-color:var(--bs-list-group-bg);border:var(--bs-list-group-border-width) solid var(--bs-list-group-border-color)}.list-group-item:first-child{border-top-left-radius:inherit;border-top-right-radius:inherit}.list-group-item:last-child{border-bottom-right-radius:inherit;border-bottom-left-radius:inherit}.list-group-item.disabled,.list-group-item:disabled{color:var(--bs-list-group-disabled-color);pointer-events:none;background-color:var(--bs-list-group-disabled-bg)}.list-group-item.active{z-index:2;color:var(--bs-list-group-active-color);background-color:var(--bs-list-group-active-bg);border-color:var(--bs-list-group-active-border-color)}.list-group-item+.list-group-item{border-top-width:0}.list-group-item+.list-group-item.active{margin-top:calc(-1 * var(--bs-list-group-border-width));border-top-width:var(--bs-list-group-border-width)}.list-group-item-action{width:100%;color:var(--bs-list-group-action-color);text-align:inherit}.list-group-item-action:not(.active):focus,.list-group-item-action:not(.active):hover{z-index:1;color:var(--bs-list-group-action-hover-color);text-decoration:none;background-color:var(--bs-list-group-action-hover-bg)}.list-group-item-action:not(.active):active{color:var(--bs-list-group-action-active-color);background-color:var(--bs-list-group-action-active-bg)}.list-group-horizontal{flex-direction:row}.list-group-horizontal>.list-group-item:first-child:not(:last-child){border-bottom-left-radius:var(--bs-list-group-border-radius);border-top-right-radius:0}.list-group-horizontal>.list-group-item:last-child:not(:first-child){border-top-right-radius:var(--bs-list-group-border-radius);border-bottom-left-radius:0}.list-group-horizontal>.list-group-item.active{margin-top:0}.list-group-horizontal>.list-group-item+.list-group-item{border-top-width:var(--bs-list-group-border-width);border-left-width:0}.list-group-horizontal>.list-group-item+.list-group-item.active{margin-left:calc(-1 * var(--bs-list-group-border-width));border-left-width:var(--bs-list-group-border-width)}@media (min-width:576px){.list-group-horizontal-sm{flex-direction:row}.list-group-horizontal-sm>.list-group-item:first-child:not(:last-child){border-bottom-left-radius:var(--bs-list-group-border-radius);border-top-right-radius:0}.list-group-horizontal-sm>.list-group-item:last-child:not(:first-child){border-top-right-radius:var(--bs-list-group-border-radius);border-bottom-left-radius:0}.list-group-horizontal-sm>.list-group-item.active{margin-top:0}.list-group-horizontal-sm>.list-group-item+.list-group-item{border-top-width:var(--bs-list-group-border-width);border-left-width:0}.list-group-horizontal-sm>.list-group-item+.list-group-item.active{margin-left:calc(-1 * var(--bs-list-group-border-width));border-left-width:var(--bs-list-group-border-width)}}@media (min-width:768px){.list-group-horizontal-md{flex-direction:row}.list-group-horizontal-md>.list-group-item:first-child:not(:last-child){border-bottom-left-radius:var(--bs-list-group-border-radius);border-top-right-radius:0}.list-group-horizontal-md>.list-group-item:last-child:not(:first-child){border-top-right-radius:var(--bs-list-group-border-radius);border-bottom-left-radius:0}.list-group-horizontal-md>.list-group-item.active{margin-top:0}.list-group-horizontal-md>.list-group-item+.list-group-item{border-top-width:var(--bs-list-group-border-width);border-left-width:0}.list-group-horizontal-md>.list-group-item+.list-group-item.active{margin-left:calc(-1 * var(--bs-list-group-border-width));border-left-width:var(--bs-list-group-border-width)}}@media (min-width:992px){.list-group-horizontal-lg{flex-direction:row}.list-group-horizontal-lg>.list-group-item:first-child:not(:last-child){border-bottom-left-radius:var(--bs-list-group-border-radius);border-top-right-radius:0}.list-group-horizontal-lg>.list-group-item:last-child:not(:first-child){border-top-right-radius:var(--bs-list-group-border-radius);border-bottom-left-radius:0}.list-group-horizontal-lg>.list-group-item.active{margin-top:0}.list-group-horizontal-lg>.list-group-item+.list-group-item{border-top-width:var(--bs-list-group-border-width);border-left-width:0}.list-group-horizontal-lg>.list-group-item+.list-group-item.active{margin-left:calc(-1 * var(--bs-list-group-border-width));border-left-width:var(--bs-list-group-border-width)}}@media (min-width:1200px){.list-group-horizontal-xl{flex-direction:row}.list-group-horizontal-xl>.list-group-item:first-child:not(:last-child){border-bottom-left-radius:var(--bs-list-group-border-radius);border-top-right-radius:0}.list-group-horizontal-xl>.list-group-item:last-child:not(:first-child){border-top-right-radius:var(--bs-list-group-border-radius);border-bottom-left-radius:0}.list-group-horizontal-xl>.list-group-item.active{margin-top:0}.list-group-horizontal-xl>.list-group-item+.list-group-item{border-top-width:var(--bs-list-group-border-width);border-left-width:0}.list-group-horizontal-xl>.list-group-item+.list-group-item.active{margin-left:calc(-1 * var(--bs-list-group-border-width));border-left-width:var(--bs-list-group-border-width)}}@media (min-width:1400px){.list-group-horizontal-xxl{flex-direction:row}.list-group-horizontal-xxl>.list-group-item:first-child:not(:last-child){border-bottom-left-radius:var(--bs-list-group-border-radius);border-top-right-radius:0}.list-group-horizontal-xxl>.list-group-item:last-child:not(:first-child){border-top-right-radius:var(--bs-list-group-border-radius);border-bottom-left-radius:0}.list-group-horizontal-xxl>.list-group-item.active{margin-top:0}.list-group-horizontal-xxl>.list-group-item+.list-group-item{border-top-width:var(--bs-list-group-border-width);border-left-width:0}.list-group-horizontal-xxl>.list-group-item+.list-group-item.active{margin-left:calc(-1 * var(--bs-list-group-border-width));border-left-width:var(--bs-list-group-border-width)}}.list-group-flush{border-radius:0}.list-group-flush>.list-group-item{border-width:0 0 var(--bs-list-group-border-width)}.list-group-flush>.list-group-item:last-child{border-bottom-width:0}.list-group-item-primary{--bs-list-group-color:var(--bs-primary-text-emphasis);--bs-list-group-bg:var(--bs-primary-bg-subtle);--bs-list-group-border-color:var(--bs-primary-border-subtle);--bs-list-group-action-hover-color:var(--bs-emphasis-color);--bs-list-group-action-hover-bg:var(--bs-primary-border-subtle);--bs-list-group-action-active-color:var(--bs-emphasis-color);--bs-list-group-action-active-bg:var(--bs-primary-border-subtle);--bs-list-group-active-color:var(--bs-primary-bg-subtle);--bs-list-group-active-bg:var(--bs-primary-text-emphasis);--bs-list-group-active-border-color:var(--bs-primary-text-emphasis)}.list-group-item-secondary{--bs-list-group-color:var(--bs-secondary-text-emphasis);--bs-list-group-bg:var(--bs-secondary-bg-subtle);--bs-list-group-border-color:var(--bs-secondary-border-subtle);--bs-list-group-action-hover-color:var(--bs-emphasis-color);--bs-list-group-action-hover-bg:var(--bs-secondary-border-subtle);--bs-list-group-action-active-color:var(--bs-emphasis-color);--bs-list-group-action-active-bg:var(--bs-secondary-border-subtle);--bs-list-group-active-color:var(--bs-secondary-bg-subtle);--bs-list-group-active-bg:var(--bs-secondary-text-emphasis);--bs-list-group-active-border-color:var(--bs-secondary-text-emphasis)}.list-group-item-success{--bs-list-group-color:var(--bs-success-text-emphasis);--bs-list-group-bg:var(--bs-success-bg-subtle);--bs-list-group-border-color:var(--bs-success-border-subtle);--bs-list-group-action-hover-color:var(--bs-emphasis-color);--bs-list-group-action-hover-bg:var(--bs-success-border-subtle);--bs-list-group-action-active-color:var(--bs-emphasis-color);--bs-list-group-action-active-bg:var(--bs-success-border-subtle);--bs-list-group-active-color:var(--bs-success-bg-subtle);--bs-list-group-active-bg:var(--bs-success-text-emphasis);--bs-list-group-active-border-color:var(--bs-success-text-emphasis)}.list-group-item-info{--bs-list-group-color:var(--bs-info-text-emphasis);--bs-list-group-bg:var(--bs-info-bg-subtle);--bs-list-group-border-color:var(--bs-info-border-subtle);--bs-list-group-action-hover-color:var(--bs-emphasis-color);--bs-list-group-action-hover-bg:var(--bs-info-border-subtle);--bs-list-group-action-active-color:var(--bs-emphasis-color);--bs-list-group-action-active-bg:var(--bs-info-border-subtle);--bs-list-group-active-color:var(--bs-info-bg-subtle);--bs-list-group-active-bg:var(--bs-info-text-emphasis);--bs-list-group-active-border-color:var(--bs-info-text-emphasis)}.list-group-item-warning{--bs-list-group-color:var(--bs-warning-text-emphasis);--bs-list-group-bg:var(--bs-warning-bg-subtle);--bs-list-group-border-color:var(--bs-warning-border-subtle);--bs-list-group-action-hover-color:var(--bs-emphasis-color);--bs-list-group-action-hover-bg:var(--bs-warning-border-subtle);--bs-list-group-action-active-color:var(--bs-emphasis-color);--bs-list-group-action-active-bg:var(--bs-warning-border-subtle);--bs-list-group-active-color:var(--bs-warning-bg-subtle);--bs-list-group-active-bg:var(--bs-warning-text-emphasis);--bs-list-group-active-border-color:var(--bs-warning-text-emphasis)}.list-group-item-danger{--bs-list-group-color:var(--bs-danger-text-emphasis);--bs-list-group-bg:var(--bs-danger-bg-subtle);--bs-list-group-border-color:var(--bs-danger-border-subtle);--bs-list-group-action-hover-color:var(--bs-emphasis-color);--bs-list-group-action-hover-bg:var(--bs-danger-border-subtle);--bs-list-group-action-active-color:var(--bs-emphasis-color);--bs-list-group-action-active-bg:var(--bs-danger-border-subtle);--bs-list-group-active-color:var(--bs-danger-bg-subtle);--bs-list-group-active-bg:var(--bs-danger-text-emphasis);--bs-list-group-active-border-color:var(--bs-danger-text-emphasis)}.list-group-item-light{--bs-list-group-color:var(--bs-light-text-emphasis);--bs-list-group-bg:var(--bs-light-bg-subtle);--bs-list-group-border-color:var(--bs-light-border-subtle);--bs-list-group-action-hover-color:var(--bs-emphasis-color);--bs-list-group-action-hover-bg:var(--bs-light-border-subtle);--bs-list-group-action-active-color:var(--bs-emphasis-color);--bs-list-group-action-active-bg:var(--bs-light-border-subtle);--bs-list-group-active-color:var(--bs-light-bg-subtle);--bs-list-group-active-bg:var(--bs-light-text-emphasis);--bs-list-group-active-border-color:var(--bs-light-text-emphasis)}.list-group-item-dark{--bs-list-group-color:var(--bs-dark-text-emphasis);--bs-list-group-bg:var(--bs-dark-bg-subtle);--bs-list-group-border-color:var(--bs-dark-border-subtle);--bs-list-group-action-hover-color:var(--bs-emphasis-color);--bs-list-group-action-hover-bg:var(--bs-dark-border-subtle);--bs-list-group-action-active-color:var(--bs-emphasis-color);--bs-list-group-action-active-bg:var(--bs-dark-border-subtle);--bs-list-group-active-color:var(--bs-dark-bg-subtle);--bs-list-group-active-bg:var(--bs-dark-text-emphasis);--bs-list-group-active-border-color:var(--bs-dark-text-emphasis)}.btn-close{--bs-btn-close-color:#000;--bs-btn-close-bg:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23000'%3e%3cpath d='M.293.293a1 1 0 0 1 1.414 0L8 6.586 14.293.293a1 1 0 1 1 1.414 1.414L9.414 8l6.293 6.293a1 1 0 0 1-1.414 1.414L8 9.414l-6.293 6.293a1 1 0 0 1-1.414-1.414L6.586 8 .293 1.707a1 1 0 0 1 0-1.414'/%3e%3c/svg%3e");--bs-btn-close-opacity:0.5;--bs-btn-close-hover-opacity:0.75;--bs-btn-close-focus-shadow:0 0 0 0.25rem rgba(13, 110, 253, 0.25);--bs-btn-close-focus-opacity:1;--bs-btn-close-disabled-opacity:0.25;box-sizing:content-box;width:1em;height:1em;padding:.25em .25em;color:var(--bs-btn-close-color);background:transparent var(--bs-btn-close-bg) center/1em auto no-repeat;filter:var(--bs-btn-close-filter);border:0;border-radius:.375rem;opacity:var(--bs-btn-close-opacity)}.btn-close:hover{color:var(--bs-btn-close-color);text-decoration:none;opacity:var(--bs-btn-close-hover-opacity)}.btn-close:focus{outline:0;box-shadow:var(--bs-btn-close-focus-shadow);opacity:var(--bs-btn-close-focus-opacity)}.btn-close.disabled,.btn-close:disabled{pointer-events:none;-webkit-user-select:none;-moz-user-select:none;user-select:none;opacity:var(--bs-btn-close-disabled-opacity)}.btn-close-white{--bs-btn-close-filter:invert(1) grayscale(100%) brightness(200%)}:root,[data-bs-theme=light]{--bs-btn-close-filter: }[data-bs-theme=dark]{--bs-btn-close-filter:invert(1) grayscale(100%) brightness(200%)}.toast{--bs-toast-zindex:1090;--bs-toast-padding-x:0.75rem;--bs-toast-padding-y:0.5rem;--bs-toast-spacing:1.5rem;--bs-toast-max-width:350px;--bs-toast-font-size:0.875rem;--bs-toast-color: ;--bs-toast-bg:rgba(var(--bs-body-bg-rgb), 0.85);--bs-toast-border-width:var(--bs-border-width);--bs-toast-border-color:var(--bs-border-color-translucent);--bs-toast-border-radius:var(--bs-border-radius);--bs-toast-box-shadow:var(--bs-box-shadow);--bs-toast-header-color:var(--bs-secondary-color);--bs-toast-header-bg:rgba(var(--bs-body-bg-rgb), 0.85);--bs-toast-header-border-color:var(--bs-border-color-translucent);width:var(--bs-toast-max-width);max-width:100%;font-size:var(--bs-toast-font-size);color:var(--bs-toast-color);pointer-events:auto;background-color:var(--bs-toast-bg);background-clip:padding-box;border:var(--bs-toast-border-width) solid var(--bs-toast-border-color);box-shadow:var(--bs-toast-box-shadow);border-radius:var(--bs-toast-border-radius)}.toast.showing{opacity:0}.toast:not(.show){display:none}.toast-container{--bs-toast-zindex:1090;position:absolute;z-index:var(--bs-toast-zindex);width:-webkit-max-content;width:-moz-max-content;width:max-content;max-width:100%;pointer-events:none}.toast-container>:not(:last-child){margin-bottom:var(--bs-toast-spacing)}.toast-header{display:flex;align-items:center;padding:var(--bs-toast-padding-y) var(--bs-toast-padding-x);color:var(--bs-toast-header-color);background-color:var(--bs-toast-header-bg);background-clip:padding-box;border-bottom:var(--bs-toast-border-width) solid var(--bs-toast-header-border-color);border-top-left-radius:calc(var(--bs-toast-border-radius) - var(--bs-toast-border-width));border-top-right-radius:calc(var(--bs-toast-border-radius) - var(--bs-toast-border-width))}.toast-header .btn-close{margin-right:calc(-.5 * var(--bs-toast-padding-x));margin-left:var(--bs-toast-padding-x)}.toast-body{padding:var(--bs-toast-padding-x);word-wrap:break-word}.modal{--bs-modal-zindex:1055;--bs-modal-width:500px;--bs-modal-padding:1rem;--bs-modal-margin:0.5rem;--bs-modal-color:var(--bs-body-color);--bs-modal-bg:var(--bs-body-bg);--bs-modal-border-color:var(--bs-border-color-translucent);--bs-modal-border-width:var(--bs-border-width);--bs-modal-border-radius:var(--bs-border-radius-lg);--bs-modal-box-shadow:var(--bs-box-shadow-sm);--bs-modal-inner-border-radius:calc(var(--bs-border-radius-lg) - (var(--bs-border-width)));--bs-modal-header-padding-x:1rem;--bs-modal-header-padding-y:1rem;--bs-modal-header-padding:1rem 1rem;--bs-modal-header-border-color:var(--bs-border-color);--bs-modal-header-border-width:var(--bs-border-width);--bs-modal-title-line-height:1.5;--bs-modal-footer-gap:0.5rem;--bs-modal-footer-bg: ;--bs-modal-footer-border-color:var(--bs-border-color);--bs-modal-footer-border-width:var(--bs-border-width);position:fixed;top:0;left:0;z-index:var(--bs-modal-zindex);display:none;width:100%;height:100%;overflow-x:hidden;overflow-y:auto;outline:0}.modal-dialog{position:relative;width:auto;margin:var(--bs-modal-margin);pointer-events:none}.modal.fade .modal-dialog{transform:translate(0,-50px);transition:transform .3s ease-out}@media (prefers-reduced-motion:reduce){.modal.fade .modal-dialog{transition:none}}.modal.show .modal-dialog{transform:none}.modal.modal-static .modal-dialog{transform:scale(1.02)}.modal-dialog-scrollable{height:calc(100% - var(--bs-modal-margin) * 2)}.modal-dialog-scrollable .modal-content{max-height:100%;overflow:hidden}.modal-dialog-scrollable .modal-body{overflow-y:auto}.modal-dialog-centered{display:flex;align-items:center;min-height:calc(100% - var(--bs-modal-margin) * 2)}.modal-content{position:relative;display:flex;flex-direction:column;width:100%;color:var(--bs-modal-color);pointer-events:auto;background-color:var(--bs-modal-bg);background-clip:padding-box;border:var(--bs-modal-border-width) solid var(--bs-modal-border-color);border-radius:var(--bs-modal-border-radius);outline:0}.modal-backdrop{--bs-backdrop-zindex:1050;--bs-backdrop-bg:#000;--bs-backdrop-opacity:0.5;position:fixed;top:0;left:0;z-index:var(--bs-backdrop-zindex);width:100vw;height:100vh;background-color:var(--bs-backdrop-bg)}.modal-backdrop.fade{opacity:0}.modal-backdrop.show{opacity:var(--bs-backdrop-opacity)}.modal-header{display:flex;flex-shrink:0;align-items:center;padding:var(--bs-modal-header-padding);border-bottom:var(--bs-modal-header-border-width) solid var(--bs-modal-header-border-color);border-top-left-radius:var(--bs-modal-inner-border-radius);border-top-right-radius:var(--bs-modal-inner-border-radius)}.modal-header .btn-close{padding:calc(var(--bs-modal-header-padding-y) * .5) calc(var(--bs-modal-header-padding-x) * .5);margin-top:calc(-.5 * var(--bs-modal-header-padding-y));margin-right:calc(-.5 * var(--bs-modal-header-padding-x));margin-bottom:calc(-.5 * var(--bs-modal-header-padding-y));margin-left:auto}.modal-title{margin-bottom:0;line-height:var(--bs-modal-title-line-height)}.modal-body{position:relative;flex:1 1 auto;padding:var(--bs-modal-padding)}.modal-footer{display:flex;flex-shrink:0;flex-wrap:wrap;align-items:center;justify-content:flex-end;padding:calc(var(--bs-modal-padding) - var(--bs-modal-footer-gap) * .5);background-color:var(--bs-modal-footer-bg);border-top:var(--bs-modal-footer-border-width) solid var(--bs-modal-footer-border-color);border-bottom-right-radius:var(--bs-modal-inner-border-radius);border-bottom-left-radius:var(--bs-modal-inner-border-radius)}.modal-footer>*{margin:calc(var(--bs-modal-footer-gap) * .5)}@media (min-width:576px){.modal{--bs-modal-margin:1.75rem;--bs-modal-box-shadow:var(--bs-box-shadow)}.modal-dialog{max-width:var(--bs-modal-width);margin-right:auto;margin-left:auto}.modal-sm{--bs-modal-width:300px}}@media (min-width:992px){.modal-lg,.modal-xl{--bs-modal-width:800px}}@media (min-width:1200px){.modal-xl{--bs-modal-width:1140px}}.modal-fullscreen{width:100vw;max-width:none;height:100%;margin:0}.modal-fullscreen .modal-content{height:100%;border:0;border-radius:0}.modal-fullscreen .modal-footer,.modal-fullscreen .modal-header{border-radius:0}.modal-fullscreen .modal-body{overflow-y:auto}@media (max-width:575.98px){.modal-fullscreen-sm-down{width:100vw;max-width:none;height:100%;margin:0}.modal-fullscreen-sm-down .modal-content{height:100%;border:0;border-radius:0}.modal-fullscreen-sm-down .modal-footer,.modal-fullscreen-sm-down .modal-header{border-radius:0}.modal-fullscreen-sm-down .modal-body{overflow-y:auto}}@media (max-width:767.98px){.modal-fullscreen-md-down{width:100vw;max-width:none;height:100%;margin:0}.modal-fullscreen-md-down .modal-content{height:100%;border:0;border-radius:0}.modal-fullscreen-md-down .modal-footer,.modal-fullscreen-md-down .modal-header{border-radius:0}.modal-fullscreen-md-down .modal-body{overflow-y:auto}}@media (max-width:991.98px){.modal-fullscreen-lg-down{width:100vw;max-width:none;height:100%;margin:0}.modal-fullscreen-lg-down .modal-content{height:100%;border:0;border-radius:0}.modal-fullscreen-lg-down .modal-footer,.modal-fullscreen-lg-down .modal-header{border-radius:0}.modal-fullscreen-lg-down .modal-body{overflow-y:auto}}@media (max-width:1199.98px){.modal-fullscreen-xl-down{width:100vw;max-width:none;height:100%;margin:0}.modal-fullscreen-xl-down .modal-content{height:100%;border:0;border-radius:0}.modal-fullscreen-xl-down .modal-footer,.modal-fullscreen-xl-down .modal-header{border-radius:0}.modal-fullscreen-xl-down .modal-body{overflow-y:auto}}@media (max-width:1399.98px){.modal-fullscreen-xxl-down{width:100vw;max-width:none;height:100%;margin:0}.modal-fullscreen-xxl-down .modal-content{height:100%;border:0;border-radius:0}.modal-fullscreen-xxl-down .modal-footer,.modal-fullscreen-xxl-down .modal-header{border-radius:0}.modal-fullscreen-xxl-down .modal-body{overflow-y:auto}}.tooltip{--bs-tooltip-zindex:1080;--bs-tooltip-max-width:200px;--bs-tooltip-padding-x:0.5rem;--bs-tooltip-padding-y:0.25rem;--bs-tooltip-margin: ;--bs-tooltip-font-size:0.875rem;--bs-tooltip-color:var(--bs-body-bg);--bs-tooltip-bg:var(--bs-emphasis-color);--bs-tooltip-border-radius:var(--bs-border-radius);--bs-tooltip-opacity:0.9;--bs-tooltip-arrow-width:0.8rem;--bs-tooltip-arrow-height:0.4rem;z-index:var(--bs-tooltip-zindex);display:block;margin:var(--bs-tooltip-margin);font-family:var(--bs-font-sans-serif);font-style:normal;font-weight:400;line-height:1.5;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;white-space:normal;word-spacing:normal;line-break:auto;font-size:var(--bs-tooltip-font-size);word-wrap:break-word;opacity:0}.tooltip.show{opacity:var(--bs-tooltip-opacity)}.tooltip .tooltip-arrow{display:block;width:var(--bs-tooltip-arrow-width);height:var(--bs-tooltip-arrow-height)}.tooltip .tooltip-arrow::before{position:absolute;content:"";border-color:transparent;border-style:solid}.bs-tooltip-auto[data-popper-placement^=top] .tooltip-arrow,.bs-tooltip-top .tooltip-arrow{bottom:calc(-1 * var(--bs-tooltip-arrow-height))}.bs-tooltip-auto[data-popper-placement^=top] .tooltip-arrow::before,.bs-tooltip-top .tooltip-arrow::before{top:-1px;border-width:var(--bs-tooltip-arrow-height) calc(var(--bs-tooltip-arrow-width) * .5) 0;border-top-color:var(--bs-tooltip-bg)}.bs-tooltip-auto[data-popper-placement^=right] .tooltip-arrow,.bs-tooltip-end .tooltip-arrow{left:calc(-1 * var(--bs-tooltip-arrow-height));width:var(--bs-tooltip-arrow-height);height:var(--bs-tooltip-arrow-width)}.bs-tooltip-auto[data-popper-placement^=right] .tooltip-arrow::before,.bs-tooltip-end .tooltip-arrow::before{right:-1px;border-width:calc(var(--bs-tooltip-arrow-width) * .5) var(--bs-tooltip-arrow-height) calc(var(--bs-tooltip-arrow-width) * .5) 0;border-right-color:var(--bs-tooltip-bg)}.bs-tooltip-auto[data-popper-placement^=bottom] .tooltip-arrow,.bs-tooltip-bottom .tooltip-arrow{top:calc(-1 * var(--bs-tooltip-arrow-height))}.bs-tooltip-auto[data-popper-placement^=bottom] .tooltip-arrow::before,.bs-tooltip-bottom .tooltip-arrow::before{bottom:-1px;border-width:0 calc(var(--bs-tooltip-arrow-width) * .5) var(--bs-tooltip-arrow-height);border-bottom-color:var(--bs-tooltip-bg)}.bs-tooltip-auto[data-popper-placement^=left] .tooltip-arrow,.bs-tooltip-start .tooltip-arrow{right:calc(-1 * var(--bs-tooltip-arrow-height));width:var(--bs-tooltip-arrow-height);height:var(--bs-tooltip-arrow-width)}.bs-tooltip-auto[data-popper-placement^=left] .tooltip-arrow::before,.bs-tooltip-start .tooltip-arrow::before{left:-1px;border-width:calc(var(--bs-tooltip-arrow-width) * .5) 0 calc(var(--bs-tooltip-arrow-width) * .5) var(--bs-tooltip-arrow-height);border-left-color:var(--bs-tooltip-bg)}.tooltip-inner{max-width:var(--bs-tooltip-max-width);padding:var(--bs-tooltip-padding-y) var(--bs-tooltip-padding-x);color:var(--bs-tooltip-color);text-align:center;background-color:var(--bs-tooltip-bg);border-radius:var(--bs-tooltip-border-radius)}.popover{--bs-popover-zindex:1070;--bs-popover-max-width:276px;--bs-popover-font-size:0.875rem;--bs-popover-bg:var(--bs-body-bg);--bs-popover-border-width:var(--bs-border-width);--bs-popover-border-color:var(--bs-border-color-translucent);--bs-popover-border-radius:var(--bs-border-radius-lg);--bs-popover-inner-border-radius:calc(var(--bs-border-radius-lg) - var(--bs-border-width));--bs-popover-box-shadow:var(--bs-box-shadow);--bs-popover-header-padding-x:1rem;--bs-popover-header-padding-y:0.5rem;--bs-popover-header-font-size:1rem;--bs-popover-header-color:inherit;--bs-popover-header-bg:var(--bs-secondary-bg);--bs-popover-body-padding-x:1rem;--bs-popover-body-padding-y:1rem;--bs-popover-body-color:var(--bs-body-color);--bs-popover-arrow-width:1rem;--bs-popover-arrow-height:0.5rem;--bs-popover-arrow-border:var(--bs-popover-border-color);z-index:var(--bs-popover-zindex);display:block;max-width:var(--bs-popover-max-width);font-family:var(--bs-font-sans-serif);font-style:normal;font-weight:400;line-height:1.5;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;white-space:normal;word-spacing:normal;line-break:auto;font-size:var(--bs-popover-font-size);word-wrap:break-word;background-color:var(--bs-popover-bg);background-clip:padding-box;border:var(--bs-popover-border-width) solid var(--bs-popover-border-color);border-radius:var(--bs-popover-border-radius)}.popover .popover-arrow{display:block;width:var(--bs-popover-arrow-width);height:var(--bs-popover-arrow-height)}.popover .popover-arrow::after,.popover .popover-arrow::before{position:absolute;display:block;content:"";border-color:transparent;border-style:solid;border-width:0}.bs-popover-auto[data-popper-placement^=top]>.popover-arrow,.bs-popover-top>.popover-arrow{bottom:calc(-1 * (var(--bs-popover-arrow-height)) - var(--bs-popover-border-width))}.bs-popover-auto[data-popper-placement^=top]>.popover-arrow::after,.bs-popover-auto[data-popper-placement^=top]>.popover-arrow::before,.bs-popover-top>.popover-arrow::after,.bs-popover-top>.popover-arrow::before{border-width:var(--bs-popover-arrow-height) calc(var(--bs-popover-arrow-width) * .5) 0}.bs-popover-auto[data-popper-placement^=top]>.popover-arrow::before,.bs-popover-top>.popover-arrow::before{bottom:0;border-top-color:var(--bs-popover-arrow-border)}.bs-popover-auto[data-popper-placement^=top]>.popover-arrow::after,.bs-popover-top>.popover-arrow::after{bottom:var(--bs-popover-border-width);border-top-color:var(--bs-popover-bg)}.bs-popover-auto[data-popper-placement^=right]>.popover-arrow,.bs-popover-end>.popover-arrow{left:calc(-1 * (var(--bs-popover-arrow-height)) - var(--bs-popover-border-width));width:var(--bs-popover-arrow-height);height:var(--bs-popover-arrow-width)}.bs-popover-auto[data-popper-placement^=right]>.popover-arrow::after,.bs-popover-auto[data-popper-placement^=right]>.popover-arrow::before,.bs-popover-end>.popover-arrow::after,.bs-popover-end>.popover-arrow::before{border-width:calc(var(--bs-popover-arrow-width) * .5) var(--bs-popover-arrow-height) calc(var(--bs-popover-arrow-width) * .5) 0}.bs-popover-auto[data-popper-placement^=right]>.popover-arrow::before,.bs-popover-end>.popover-arrow::before{left:0;border-right-color:var(--bs-popover-arrow-border)}.bs-popover-auto[data-popper-placement^=right]>.popover-arrow::after,.bs-popover-end>.popover-arrow::after{left:var(--bs-popover-border-width);border-right-color:var(--bs-popover-bg)}.bs-popover-auto[data-popper-placement^=bottom]>.popover-arrow,.bs-popover-bottom>.popover-arrow{top:calc(-1 * (var(--bs-popover-arrow-height)) - var(--bs-popover-border-width))}.bs-popover-auto[data-popper-placement^=bottom]>.popover-arrow::after,.bs-popover-auto[data-popper-placement^=bottom]>.popover-arrow::before,.bs-popover-bottom>.popover-arrow::after,.bs-popover-bottom>.popover-arrow::before{border-width:0 calc(var(--bs-popover-arrow-width) * .5) var(--bs-popover-arrow-height)}.bs-popover-auto[data-popper-placement^=bottom]>.popover-arrow::before,.bs-popover-bottom>.popover-arrow::before{top:0;border-bottom-color:var(--bs-popover-arrow-border)}.bs-popover-auto[data-popper-placement^=bottom]>.popover-arrow::after,.bs-popover-bottom>.popover-arrow::after{top:var(--bs-popover-border-width);border-bottom-color:var(--bs-popover-bg)}.bs-popover-auto[data-popper-placement^=bottom] .popover-header::before,.bs-popover-bottom .popover-header::before{position:absolute;top:0;left:50%;display:block;width:var(--bs-popover-arrow-width);margin-left:calc(-.5 * var(--bs-popover-arrow-width));content:"";border-bottom:var(--bs-popover-border-width) solid var(--bs-popover-header-bg)}.bs-popover-auto[data-popper-placement^=left]>.popover-arrow,.bs-popover-start>.popover-arrow{right:calc(-1 * (var(--bs-popover-arrow-height)) - var(--bs-popover-border-width));width:var(--bs-popover-arrow-height);height:var(--bs-popover-arrow-width)}.bs-popover-auto[data-popper-placement^=left]>.popover-arrow::after,.bs-popover-auto[data-popper-placement^=left]>.popover-arrow::before,.bs-popover-start>.popover-arrow::after,.bs-popover-start>.popover-arrow::before{border-width:calc(var(--bs-popover-arrow-width) * .5) 0 calc(var(--bs-popover-arrow-width) * .5) var(--bs-popover-arrow-height)}.bs-popover-auto[data-popper-placement^=left]>.popover-arrow::before,.bs-popover-start>.popover-arrow::before{right:0;border-left-color:var(--bs-popover-arrow-border)}.bs-popover-auto[data-popper-placement^=left]>.popover-arrow::after,.bs-popover-start>.popover-arrow::after{right:var(--bs-popover-border-width);border-left-color:var(--bs-popover-bg)}.popover-header{padding:var(--bs-popover-header-padding-y) var(--bs-popover-header-padding-x);margin-bottom:0;font-size:var(--bs-popover-header-font-size);color:var(--bs-popover-header-color);background-color:var(--bs-popover-header-bg);border-bottom:var(--bs-popover-border-width) solid var(--bs-popover-border-color);border-top-left-radius:var(--bs-popover-inner-border-radius);border-top-right-radius:var(--bs-popover-inner-border-radius)}.popover-header:empty{display:none}.popover-body{padding:var(--bs-popover-body-padding-y) var(--bs-popover-body-padding-x);color:var(--bs-popover-body-color)}.carousel{position:relative}.carousel.pointer-event{touch-action:pan-y}.carousel-inner{position:relative;width:100%;overflow:hidden}.carousel-inner::after{display:block;clear:both;content:""}.carousel-item{position:relative;display:none;float:left;width:100%;margin-right:-100%;-webkit-backface-visibility:hidden;backface-visibility:hidden;transition:transform .6s ease-in-out}@media (prefers-reduced-motion:reduce){.carousel-item{transition:none}}.carousel-item-next,.carousel-item-prev,.carousel-item.active{display:block}.active.carousel-item-end,.carousel-item-next:not(.carousel-item-start){transform:translateX(100%)}.active.carousel-item-start,.carousel-item-prev:not(.carousel-item-end){transform:translateX(-100%)}.carousel-fade .carousel-item{opacity:0;transition-property:opacity;transform:none}.carousel-fade .carousel-item-next.carousel-item-start,.carousel-fade .carousel-item-prev.carousel-item-end,.carousel-fade .carousel-item.active{z-index:1;opacity:1}.carousel-fade .active.carousel-item-end,.carousel-fade .active.carousel-item-start{z-index:0;opacity:0;transition:opacity 0s .6s}@media (prefers-reduced-motion:reduce){.carousel-fade .active.carousel-item-end,.carousel-fade .active.carousel-item-start{transition:none}}.carousel-control-next,.carousel-control-prev{position:absolute;top:0;bottom:0;z-index:1;display:flex;align-items:center;justify-content:center;width:15%;padding:0;color:#fff;text-align:center;background:0 0;filter:var(--bs-carousel-control-icon-filter);border:0;opacity:.5;transition:opacity .15s ease}@media (prefers-reduced-motion:reduce){.carousel-control-next,.carousel-control-prev{transition:none}}.carousel-control-next:focus,.carousel-control-next:hover,.carousel-control-prev:focus,.carousel-control-prev:hover{color:#fff;text-decoration:none;outline:0;opacity:.9}.carousel-control-prev{left:0}.carousel-control-next{right:0}.carousel-control-next-icon,.carousel-control-prev-icon{display:inline-block;width:2rem;height:2rem;background-repeat:no-repeat;background-position:50%;background-size:100% 100%}.carousel-control-prev-icon{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23fff'%3e%3cpath d='M11.354 1.646a.5.5 0 0 1 0 .708L5.707 8l5.647 5.646a.5.5 0 0 1-.708.708l-6-6a.5.5 0 0 1 0-.708l6-6a.5.5 0 0 1 .708 0'/%3e%3c/svg%3e")}.carousel-control-next-icon{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23fff'%3e%3cpath d='M4.646 1.646a.5.5 0 0 1 .708 0l6 6a.5.5 0 0 1 0 .708l-6 6a.5.5 0 0 1-.708-.708L10.293 8 4.646 2.354a.5.5 0 0 1 0-.708'/%3e%3c/svg%3e")}.carousel-indicators{position:absolute;right:0;bottom:0;left:0;z-index:2;display:flex;justify-content:center;padding:0;margin-right:15%;margin-bottom:1rem;margin-left:15%}.carousel-indicators [data-bs-target]{box-sizing:content-box;flex:0 1 auto;width:30px;height:3px;padding:0;margin-right:3px;margin-left:3px;text-indent:-999px;cursor:pointer;background-color:var(--bs-carousel-indicator-active-bg);background-clip:padding-box;border:0;border-top:10px solid transparent;border-bottom:10px solid transparent;opacity:.5;transition:opacity .6s ease}@media (prefers-reduced-motion:reduce){.carousel-indicators [data-bs-target]{transition:none}}.carousel-indicators .active{opacity:1}.carousel-caption{position:absolute;right:15%;bottom:1.25rem;left:15%;padding-top:1.25rem;padding-bottom:1.25rem;color:var(--bs-carousel-caption-color);text-align:center}.carousel-dark{--bs-carousel-indicator-active-bg:#000;--bs-carousel-caption-color:#000;--bs-carousel-control-icon-filter:invert(1) grayscale(100)}:root,[data-bs-theme=light]{--bs-carousel-indicator-active-bg:#fff;--bs-carousel-caption-color:#fff;--bs-carousel-control-icon-filter: }[data-bs-theme=dark]{--bs-carousel-indicator-active-bg:#000;--bs-carousel-caption-color:#000;--bs-carousel-control-icon-filter:invert(1) grayscale(100)}.spinner-border,.spinner-grow{display:inline-block;width:var(--bs-spinner-width);height:var(--bs-spinner-height);vertical-align:var(--bs-spinner-vertical-align);border-radius:50%;animation:var(--bs-spinner-animation-speed) linear infinite var(--bs-spinner-animation-name)}@keyframes spinner-border{to{transform:rotate(360deg)}}.spinner-border{--bs-spinner-width:2rem;--bs-spinner-height:2rem;--bs-spinner-vertical-align:-0.125em;--bs-spinner-border-width:0.25em;--bs-spinner-animation-speed:0.75s;--bs-spinner-animation-name:spinner-border;border:var(--bs-spinner-border-width) solid currentcolor;border-right-color:transparent}.spinner-border-sm{--bs-spinner-width:1rem;--bs-spinner-height:1rem;--bs-spinner-border-width:0.2em}@keyframes spinner-grow{0%{transform:scale(0)}50%{opacity:1;transform:none}}.spinner-grow{--bs-spinner-width:2rem;--bs-spinner-height:2rem;--bs-spinner-vertical-align:-0.125em;--bs-spinner-animation-speed:0.75s;--bs-spinner-animation-name:spinner-grow;background-color:currentcolor;opacity:0}.spinner-grow-sm{--bs-spinner-width:1rem;--bs-spinner-height:1rem}@media (prefers-reduced-motion:reduce){.spinner-border,.spinner-grow{--bs-spinner-animation-speed:1.5s}}.offcanvas,.offcanvas-lg,.offcanvas-md,.offcanvas-sm,.offcanvas-xl,.offcanvas-xxl{--bs-offcanvas-zindex:1045;--bs-offcanvas-width:400px;--bs-offcanvas-height:30vh;--bs-offcanvas-padding-x:1rem;--bs-offcanvas-padding-y:1rem;--bs-offcanvas-color:var(--bs-body-color);--bs-offcanvas-bg:var(--bs-body-bg);--bs-offcanvas-border-width:var(--bs-border-width);--bs-offcanvas-border-color:var(--bs-border-color-translucent);--bs-offcanvas-box-shadow:var(--bs-box-shadow-sm);--bs-offcanvas-transition:transform 0.3s ease-in-out;--bs-offcanvas-title-line-height:1.5}@media (max-width:575.98px){.offcanvas-sm{position:fixed;bottom:0;z-index:var(--bs-offcanvas-zindex);display:flex;flex-direction:column;max-width:100%;color:var(--bs-offcanvas-color);visibility:hidden;background-color:var(--bs-offcanvas-bg);background-clip:padding-box;outline:0;transition:var(--bs-offcanvas-transition)}}@media (max-width:575.98px) and (prefers-reduced-motion:reduce){.offcanvas-sm{transition:none}}@media (max-width:575.98px){.offcanvas-sm.offcanvas-start{top:0;left:0;width:var(--bs-offcanvas-width);border-right:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateX(-100%)}.offcanvas-sm.offcanvas-end{top:0;right:0;width:var(--bs-offcanvas-width);border-left:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateX(100%)}.offcanvas-sm.offcanvas-top{top:0;right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-bottom:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(-100%)}.offcanvas-sm.offcanvas-bottom{right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-top:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(100%)}.offcanvas-sm.show:not(.hiding),.offcanvas-sm.showing{transform:none}.offcanvas-sm.hiding,.offcanvas-sm.show,.offcanvas-sm.showing{visibility:visible}}@media (min-width:576px){.offcanvas-sm{--bs-offcanvas-height:auto;--bs-offcanvas-border-width:0;background-color:transparent!important}.offcanvas-sm .offcanvas-header{display:none}.offcanvas-sm .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible;background-color:transparent!important}}@media (max-width:767.98px){.offcanvas-md{position:fixed;bottom:0;z-index:var(--bs-offcanvas-zindex);display:flex;flex-direction:column;max-width:100%;color:var(--bs-offcanvas-color);visibility:hidden;background-color:var(--bs-offcanvas-bg);background-clip:padding-box;outline:0;transition:var(--bs-offcanvas-transition)}}@media (max-width:767.98px) and (prefers-reduced-motion:reduce){.offcanvas-md{transition:none}}@media (max-width:767.98px){.offcanvas-md.offcanvas-start{top:0;left:0;width:var(--bs-offcanvas-width);border-right:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateX(-100%)}.offcanvas-md.offcanvas-end{top:0;right:0;width:var(--bs-offcanvas-width);border-left:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateX(100%)}.offcanvas-md.offcanvas-top{top:0;right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-bottom:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(-100%)}.offcanvas-md.offcanvas-bottom{right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-top:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(100%)}.offcanvas-md.show:not(.hiding),.offcanvas-md.showing{transform:none}.offcanvas-md.hiding,.offcanvas-md.show,.offcanvas-md.showing{visibility:visible}}@media (min-width:768px){.offcanvas-md{--bs-offcanvas-height:auto;--bs-offcanvas-border-width:0;background-color:transparent!important}.offcanvas-md .offcanvas-header{display:none}.offcanvas-md .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible;background-color:transparent!important}}@media (max-width:991.98px){.offcanvas-lg{position:fixed;bottom:0;z-index:var(--bs-offcanvas-zindex);display:flex;flex-direction:column;max-width:100%;color:var(--bs-offcanvas-color);visibility:hidden;background-color:var(--bs-offcanvas-bg);background-clip:padding-box;outline:0;transition:var(--bs-offcanvas-transition)}}@media (max-width:991.98px) and (prefers-reduced-motion:reduce){.offcanvas-lg{transition:none}}@media (max-width:991.98px){.offcanvas-lg.offcanvas-start{top:0;left:0;width:var(--bs-offcanvas-width);border-right:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateX(-100%)}.offcanvas-lg.offcanvas-end{top:0;right:0;width:var(--bs-offcanvas-width);border-left:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateX(100%)}.offcanvas-lg.offcanvas-top{top:0;right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-bottom:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(-100%)}.offcanvas-lg.offcanvas-bottom{right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-top:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(100%)}.offcanvas-lg.show:not(.hiding),.offcanvas-lg.showing{transform:none}.offcanvas-lg.hiding,.offcanvas-lg.show,.offcanvas-lg.showing{visibility:visible}}@media (min-width:992px){.offcanvas-lg{--bs-offcanvas-height:auto;--bs-offcanvas-border-width:0;background-color:transparent!important}.offcanvas-lg .offcanvas-header{display:none}.offcanvas-lg .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible;background-color:transparent!important}}@media (max-width:1199.98px){.offcanvas-xl{position:fixed;bottom:0;z-index:var(--bs-offcanvas-zindex);display:flex;flex-direction:column;max-width:100%;color:var(--bs-offcanvas-color);visibility:hidden;background-color:var(--bs-offcanvas-bg);background-clip:padding-box;outline:0;transition:var(--bs-offcanvas-transition)}}@media (max-width:1199.98px) and (prefers-reduced-motion:reduce){.offcanvas-xl{transition:none}}@media (max-width:1199.98px){.offcanvas-xl.offcanvas-start{top:0;left:0;width:var(--bs-offcanvas-width);border-right:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateX(-100%)}.offcanvas-xl.offcanvas-end{top:0;right:0;width:var(--bs-offcanvas-width);border-left:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateX(100%)}.offcanvas-xl.offcanvas-top{top:0;right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-bottom:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(-100%)}.offcanvas-xl.offcanvas-bottom{right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-top:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(100%)}.offcanvas-xl.show:not(.hiding),.offcanvas-xl.showing{transform:none}.offcanvas-xl.hiding,.offcanvas-xl.show,.offcanvas-xl.showing{visibility:visible}}@media (min-width:1200px){.offcanvas-xl{--bs-offcanvas-height:auto;--bs-offcanvas-border-width:0;background-color:transparent!important}.offcanvas-xl .offcanvas-header{display:none}.offcanvas-xl .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible;background-color:transparent!important}}@media (max-width:1399.98px){.offcanvas-xxl{position:fixed;bottom:0;z-index:var(--bs-offcanvas-zindex);display:flex;flex-direction:column;max-width:100%;color:var(--bs-offcanvas-color);visibility:hidden;background-color:var(--bs-offcanvas-bg);background-clip:padding-box;outline:0;transition:var(--bs-offcanvas-transition)}}@media (max-width:1399.98px) and (prefers-reduced-motion:reduce){.offcanvas-xxl{transition:none}}@media (max-width:1399.98px){.offcanvas-xxl.offcanvas-start{top:0;left:0;width:var(--bs-offcanvas-width);border-right:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateX(-100%)}.offcanvas-xxl.offcanvas-end{top:0;right:0;width:var(--bs-offcanvas-width);border-left:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateX(100%)}.offcanvas-xxl.offcanvas-top{top:0;right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-bottom:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(-100%)}.offcanvas-xxl.offcanvas-bottom{right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-top:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(100%)}.offcanvas-xxl.show:not(.hiding),.offcanvas-xxl.showing{transform:none}.offcanvas-xxl.hiding,.offcanvas-xxl.show,.offcanvas-xxl.showing{visibility:visible}}@media (min-width:1400px){.offcanvas-xxl{--bs-offcanvas-height:auto;--bs-offcanvas-border-width:0;background-color:transparent!important}.offcanvas-xxl .offcanvas-header{display:none}.offcanvas-xxl .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible;background-color:transparent!important}}.offcanvas{position:fixed;bottom:0;z-index:var(--bs-offcanvas-zindex);display:flex;flex-direction:column;max-width:100%;color:var(--bs-offcanvas-color);visibility:hidden;background-color:var(--bs-offcanvas-bg);background-clip:padding-box;outline:0;transition:var(--bs-offcanvas-transition)}@media (prefers-reduced-motion:reduce){.offcanvas{transition:none}}.offcanvas.offcanvas-start{top:0;left:0;width:var(--bs-offcanvas-width);border-right:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateX(-100%)}.offcanvas.offcanvas-end{top:0;right:0;width:var(--bs-offcanvas-width);border-left:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateX(100%)}.offcanvas.offcanvas-top{top:0;right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-bottom:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(-100%)}.offcanvas.offcanvas-bottom{right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-top:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(100%)}.offcanvas.show:not(.hiding),.offcanvas.showing{transform:none}.offcanvas.hiding,.offcanvas.show,.offcanvas.showing{visibility:visible}.offcanvas-backdrop{position:fixed;top:0;left:0;z-index:1040;width:100vw;height:100vh;background-color:#000}.offcanvas-backdrop.fade{opacity:0}.offcanvas-backdrop.show{opacity:.5}.offcanvas-header{display:flex;align-items:center;padding:var(--bs-offcanvas-padding-y) var(--bs-offcanvas-padding-x)}.offcanvas-header .btn-close{padding:calc(var(--bs-offcanvas-padding-y) * .5) calc(var(--bs-offcanvas-padding-x) * .5);margin-top:calc(-.5 * var(--bs-offcanvas-padding-y));margin-right:calc(-.5 * var(--bs-offcanvas-padding-x));margin-bottom:calc(-.5 * var(--bs-offcanvas-padding-y));margin-left:auto}.offcanvas-title{margin-bottom:0;line-height:var(--bs-offcanvas-title-line-height)}.offcanvas-body{flex-grow:1;padding:var(--bs-offcanvas-padding-y) var(--bs-offcanvas-padding-x);overflow-y:auto}.placeholder{display:inline-block;min-height:1em;vertical-align:middle;cursor:wait;background-color:currentcolor;opacity:.5}.placeholder.btn::before{display:inline-block;content:""}.placeholder-xs{min-height:.6em}.placeholder-sm{min-height:.8em}.placeholder-lg{min-height:1.2em}.placeholder-glow .placeholder{animation:placeholder-glow 2s ease-in-out infinite}@keyframes placeholder-glow{50%{opacity:.2}}.placeholder-wave{-webkit-mask-image:linear-gradient(130deg,#000 55%,rgba(0,0,0,0.8) 75%,#000 95%);mask-image:linear-gradient(130deg,#000 55%,rgba(0,0,0,0.8) 75%,#000 95%);-webkit-mask-size:200% 100%;mask-size:200% 100%;animation:placeholder-wave 2s linear infinite}@keyframes placeholder-wave{100%{-webkit-mask-position:-200% 0%;mask-position:-200% 0%}}.clearfix::after{display:block;clear:both;content:""}.text-bg-primary{color:#fff!important;background-color:RGBA(var(--bs-primary-rgb),var(--bs-bg-opacity,1))!important}.text-bg-secondary{color:#fff!important;background-color:RGBA(var(--bs-secondary-rgb),var(--bs-bg-opacity,1))!important}.text-bg-success{color:#fff!important;background-color:RGBA(var(--bs-success-rgb),var(--bs-bg-opacity,1))!important}.text-bg-info{color:#000!important;background-color:RGBA(var(--bs-info-rgb),var(--bs-bg-opacity,1))!important}.text-bg-warning{color:#000!important;background-color:RGBA(var(--bs-warning-rgb),var(--bs-bg-opacity,1))!important}.text-bg-danger{color:#fff!important;background-color:RGBA(var(--bs-danger-rgb),var(--bs-bg-opacity,1))!important}.text-bg-light{color:#000!important;background-color:RGBA(var(--bs-light-rgb),var(--bs-bg-opacity,1))!important}.text-bg-dark{color:#fff!important;background-color:RGBA(var(--bs-dark-rgb),var(--bs-bg-opacity,1))!important}.link-primary{color:RGBA(var(--bs-primary-rgb),var(--bs-link-opacity,1))!important;-webkit-text-decoration-color:RGBA(var(--bs-primary-rgb),var(--bs-link-underline-opacity,1))!important;text-decoration-color:RGBA(var(--bs-primary-rgb),var(--bs-link-underline-opacity,1))!important}.link-primary:focus,.link-primary:hover{color:RGBA(10,88,202,var(--bs-link-opacity,1))!important;-webkit-text-decoration-color:RGBA(10,88,202,var(--bs-link-underline-opacity,1))!important;text-decoration-color:RGBA(10,88,202,var(--bs-link-underline-opacity,1))!important}.link-secondary{color:RGBA(var(--bs-secondary-rgb),var(--bs-link-opacity,1))!important;-webkit-text-decoration-color:RGBA(var(--bs-secondary-rgb),var(--bs-link-underline-opacity,1))!important;text-decoration-color:RGBA(var(--bs-secondary-rgb),var(--bs-link-underline-opacity,1))!important}.link-secondary:focus,.link-secondary:hover{color:RGBA(86,94,100,var(--bs-link-opacity,1))!important;-webkit-text-decoration-color:RGBA(86,94,100,var(--bs-link-underline-opacity,1))!important;text-decoration-color:RGBA(86,94,100,var(--bs-link-underline-opacity,1))!important}.link-success{color:RGBA(var(--bs-success-rgb),var(--bs-link-opacity,1))!important;-webkit-text-decoration-color:RGBA(var(--bs-success-rgb),var(--bs-link-underline-opacity,1))!important;text-decoration-color:RGBA(var(--bs-success-rgb),var(--bs-link-underline-opacity,1))!important}.link-success:focus,.link-success:hover{color:RGBA(20,108,67,var(--bs-link-opacity,1))!important;-webkit-text-decoration-color:RGBA(20,108,67,var(--bs-link-underline-opacity,1))!important;text-decoration-color:RGBA(20,108,67,var(--bs-link-underline-opacity,1))!important}.link-info{color:RGBA(var(--bs-info-rgb),var(--bs-link-opacity,1))!important;-webkit-text-decoration-color:RGBA(var(--bs-info-rgb),var(--bs-link-underline-opacity,1))!important;text-decoration-color:RGBA(var(--bs-info-rgb),var(--bs-link-underline-opacity,1))!important}.link-info:focus,.link-info:hover{color:RGBA(61,213,243,var(--bs-link-opacity,1))!important;-webkit-text-decoration-color:RGBA(61,213,243,var(--bs-link-underline-opacity,1))!important;text-decoration-color:RGBA(61,213,243,var(--bs-link-underline-opacity,1))!important}.link-warning{color:RGBA(var(--bs-warning-rgb),var(--bs-link-opacity,1))!important;-webkit-text-decoration-color:RGBA(var(--bs-warning-rgb),var(--bs-link-underline-opacity,1))!important;text-decoration-color:RGBA(var(--bs-warning-rgb),var(--bs-link-underline-opacity,1))!important}.link-warning:focus,.link-warning:hover{color:RGBA(255,205,57,var(--bs-link-opacity,1))!important;-webkit-text-decoration-color:RGBA(255,205,57,var(--bs-link-underline-opacity,1))!important;text-decoration-color:RGBA(255,205,57,var(--bs-link-underline-opacity,1))!important}.link-danger{color:RGBA(var(--bs-danger-rgb),var(--bs-link-opacity,1))!important;-webkit-text-decoration-color:RGBA(var(--bs-danger-rgb),var(--bs-link-underline-opacity,1))!important;text-decoration-color:RGBA(var(--bs-danger-rgb),var(--bs-link-underline-opacity,1))!important}.link-danger:focus,.link-danger:hover{color:RGBA(176,42,55,var(--bs-link-opacity,1))!important;-webkit-text-decoration-color:RGBA(176,42,55,var(--bs-link-underline-opacity,1))!important;text-decoration-color:RGBA(176,42,55,var(--bs-link-underline-opacity,1))!important}.link-light{color:RGBA(var(--bs-light-rgb),var(--bs-link-opacity,1))!important;-webkit-text-decoration-color:RGBA(var(--bs-light-rgb),var(--bs-link-underline-opacity,1))!important;text-decoration-color:RGBA(var(--bs-light-rgb),var(--bs-link-underline-opacity,1))!important}.link-light:focus,.link-light:hover{color:RGBA(249,250,251,var(--bs-link-opacity,1))!important;-webkit-text-decoration-color:RGBA(249,250,251,var(--bs-link-underline-opacity,1))!important;text-decoration-color:RGBA(249,250,251,var(--bs-link-underline-opacity,1))!important}.link-dark{color:RGBA(var(--bs-dark-rgb),var(--bs-link-opacity,1))!important;-webkit-text-decoration-color:RGBA(var(--bs-dark-rgb),var(--bs-link-underline-opacity,1))!important;text-decoration-color:RGBA(var(--bs-dark-rgb),var(--bs-link-underline-opacity,1))!important}.link-dark:focus,.link-dark:hover{color:RGBA(26,30,33,var(--bs-link-opacity,1))!important;-webkit-text-decoration-color:RGBA(26,30,33,var(--bs-link-underline-opacity,1))!important;text-decoration-color:RGBA(26,30,33,var(--bs-link-underline-opacity,1))!important}.link-body-emphasis{color:RGBA(var(--bs-emphasis-color-rgb),var(--bs-link-opacity,1))!important;-webkit-text-decoration-color:RGBA(var(--bs-emphasis-color-rgb),var(--bs-link-underline-opacity,1))!important;text-decoration-color:RGBA(var(--bs-emphasis-color-rgb),var(--bs-link-underline-opacity,1))!important}.link-body-emphasis:focus,.link-body-emphasis:hover{color:RGBA(var(--bs-emphasis-color-rgb),var(--bs-link-opacity,.75))!important;-webkit-text-decoration-color:RGBA(var(--bs-emphasis-color-rgb),var(--bs-link-underline-opacity,0.75))!important;text-decoration-color:RGBA(var(--bs-emphasis-color-rgb),var(--bs-link-underline-opacity,0.75))!important}.focus-ring:focus{outline:0;box-shadow:var(--bs-focus-ring-x,0) var(--bs-focus-ring-y,0) var(--bs-focus-ring-blur,0) var(--bs-focus-ring-width) var(--bs-focus-ring-color)}.icon-link{display:inline-flex;gap:.375rem;align-items:center;-webkit-text-decoration-color:rgba(var(--bs-link-color-rgb),var(--bs-link-opacity,0.5));text-decoration-color:rgba(var(--bs-link-color-rgb),var(--bs-link-opacity,0.5));text-underline-offset:0.25em;-webkit-backface-visibility:hidden;backface-visibility:hidden}.icon-link>.bi{flex-shrink:0;width:1em;height:1em;fill:currentcolor;transition:.2s ease-in-out transform}@media (prefers-reduced-motion:reduce){.icon-link>.bi{transition:none}}.icon-link-hover:focus-visible>.bi,.icon-link-hover:hover>.bi{transform:var(--bs-icon-link-transform,translate3d(.25em,0,0))}.ratio{position:relative;width:100%}.ratio::before{display:block;padding-top:var(--bs-aspect-ratio);content:""}.ratio>*{position:absolute;top:0;left:0;width:100%;height:100%}.ratio-1x1{--bs-aspect-ratio:100%}.ratio-4x3{--bs-aspect-ratio:75%}.ratio-16x9{--bs-aspect-ratio:56.25%}.ratio-21x9{--bs-aspect-ratio:42.8571428571%}.fixed-top{position:fixed;top:0;right:0;left:0;z-index:1030}.fixed-bottom{position:fixed;right:0;bottom:0;left:0;z-index:1030}.sticky-top{position:-webkit-sticky;position:sticky;top:0;z-index:1020}.sticky-bottom{position:-webkit-sticky;position:sticky;bottom:0;z-index:1020}@media (min-width:576px){.sticky-sm-top{position:-webkit-sticky;position:sticky;top:0;z-index:1020}.sticky-sm-bottom{position:-webkit-sticky;position:sticky;bottom:0;z-index:1020}}@media (min-width:768px){.sticky-md-top{position:-webkit-sticky;position:sticky;top:0;z-index:1020}.sticky-md-bottom{position:-webkit-sticky;position:sticky;bottom:0;z-index:1020}}@media (min-width:992px){.sticky-lg-top{position:-webkit-sticky;position:sticky;top:0;z-index:1020}.sticky-lg-bottom{position:-webkit-sticky;position:sticky;bottom:0;z-index:1020}}@media (min-width:1200px){.sticky-xl-top{position:-webkit-sticky;position:sticky;top:0;z-index:1020}.sticky-xl-bottom{position:-webkit-sticky;position:sticky;bottom:0;z-index:1020}}@media (min-width:1400px){.sticky-xxl-top{position:-webkit-sticky;position:sticky;top:0;z-index:1020}.sticky-xxl-bottom{position:-webkit-sticky;position:sticky;bottom:0;z-index:1020}}.hstack{display:flex;flex-direction:row;align-items:center;align-self:stretch}.vstack{display:flex;flex:1 1 auto;flex-direction:column;align-self:stretch}.visually-hidden,.visually-hidden-focusable:not(:focus):not(:focus-within){width:1px!important;height:1px!important;padding:0!important;margin:-1px!important;overflow:hidden!important;clip:rect(0,0,0,0)!important;white-space:nowrap!important;border:0!important}.visually-hidden-focusable:not(:focus):not(:focus-within):not(caption),.visually-hidden:not(caption){position:absolute!important}.visually-hidden *,.visually-hidden-focusable:not(:focus):not(:focus-within) *{overflow:hidden!important}.stretched-link::after{position:absolute;top:0;right:0;bottom:0;left:0;z-index:1;content:""}.text-truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.vr{display:inline-block;align-self:stretch;width:var(--bs-border-width);min-height:1em;background-color:currentcolor;opacity:.25}.align-baseline{vertical-align:baseline!important}.align-top{vertical-align:top!important}.align-middle{vertical-align:middle!important}.align-bottom{vertical-align:bottom!important}.align-text-bottom{vertical-align:text-bottom!important}.align-text-top{vertical-align:text-top!important}.float-start{float:left!important}.float-end{float:right!important}.float-none{float:none!important}.object-fit-contain{-o-object-fit:contain!important;object-fit:contain!important}.object-fit-cover{-o-object-fit:cover!important;object-fit:cover!important}.object-fit-fill{-o-object-fit:fill!important;object-fit:fill!important}.object-fit-scale{-o-object-fit:scale-down!important;object-fit:scale-down!important}.object-fit-none{-o-object-fit:none!important;object-fit:none!important}.opacity-0{opacity:0!important}.opacity-25{opacity:.25!important}.opacity-50{opacity:.5!important}.opacity-75{opacity:.75!important}.opacity-100{opacity:1!important}.overflow-auto{overflow:auto!important}.overflow-hidden{overflow:hidden!important}.overflow-visible{overflow:visible!important}.overflow-scroll{overflow:scroll!important}.overflow-x-auto{overflow-x:auto!important}.overflow-x-hidden{overflow-x:hidden!important}.overflow-x-visible{overflow-x:visible!important}.overflow-x-scroll{overflow-x:scroll!important}.overflow-y-auto{overflow-y:auto!important}.overflow-y-hidden{overflow-y:hidden!important}.overflow-y-visible{overflow-y:visible!important}.overflow-y-scroll{overflow-y:scroll!important}.d-inline{display:inline!important}.d-inline-block{display:inline-block!important}.d-block{display:block!important}.d-grid{display:grid!important}.d-inline-grid{display:inline-grid!important}.d-table{display:table!important}.d-table-row{display:table-row!important}.d-table-cell{display:table-cell!important}.d-flex{display:flex!important}.d-inline-flex{display:inline-flex!important}.d-none{display:none!important}.shadow{box-shadow:var(--bs-box-shadow)!important}.shadow-sm{box-shadow:var(--bs-box-shadow-sm)!important}.shadow-lg{box-shadow:var(--bs-box-shadow-lg)!important}.shadow-none{box-shadow:none!important}.focus-ring-primary{--bs-focus-ring-color:rgba(var(--bs-primary-rgb), var(--bs-focus-ring-opacity))}.focus-ring-secondary{--bs-focus-ring-color:rgba(var(--bs-secondary-rgb), var(--bs-focus-ring-opacity))}.focus-ring-success{--bs-focus-ring-color:rgba(var(--bs-success-rgb), var(--bs-focus-ring-opacity))}.focus-ring-info{--bs-focus-ring-color:rgba(var(--bs-info-rgb), var(--bs-focus-ring-opacity))}.focus-ring-warning{--bs-focus-ring-color:rgba(var(--bs-warning-rgb), var(--bs-focus-ring-opacity))}.focus-ring-danger{--bs-focus-ring-color:rgba(var(--bs-danger-rgb), var(--bs-focus-ring-opacity))}.focus-ring-light{--bs-focus-ring-color:rgba(var(--bs-light-rgb), var(--bs-focus-ring-opacity))}.focus-ring-dark{--bs-focus-ring-color:rgba(var(--bs-dark-rgb), var(--bs-focus-ring-opacity))}.position-static{position:static!important}.position-relative{position:relative!important}.position-absolute{position:absolute!important}.position-fixed{position:fixed!important}.position-sticky{position:-webkit-sticky!important;position:sticky!important}.top-0{top:0!important}.top-50{top:50%!important}.top-100{top:100%!important}.bottom-0{bottom:0!important}.bottom-50{bottom:50%!important}.bottom-100{bottom:100%!important}.start-0{left:0!important}.start-50{left:50%!important}.start-100{left:100%!important}.end-0{right:0!important}.end-50{right:50%!important}.end-100{right:100%!important}.translate-middle{transform:translate(-50%,-50%)!important}.translate-middle-x{transform:translateX(-50%)!important}.translate-middle-y{transform:translateY(-50%)!important}.border{border:var(--bs-border-width) var(--bs-border-style) var(--bs-border-color)!important}.border-0{border:0!important}.border-top{border-top:var(--bs-border-width) var(--bs-border-style) var(--bs-border-color)!important}.border-top-0{border-top:0!important}.border-end{border-right:var(--bs-border-width) var(--bs-border-style) var(--bs-border-color)!important}.border-end-0{border-right:0!important}.border-bottom{border-bottom:var(--bs-border-width) var(--bs-border-style) var(--bs-border-color)!important}.border-bottom-0{border-bottom:0!important}.border-start{border-left:var(--bs-border-width) var(--bs-border-style) var(--bs-border-color)!important}.border-start-0{border-left:0!important}.border-primary{--bs-border-opacity:1;border-color:rgba(var(--bs-primary-rgb),var(--bs-border-opacity))!important}.border-secondary{--bs-border-opacity:1;border-color:rgba(var(--bs-secondary-rgb),var(--bs-border-opacity))!important}.border-success{--bs-border-opacity:1;border-color:rgba(var(--bs-success-rgb),var(--bs-border-opacity))!important}.border-info{--bs-border-opacity:1;border-color:rgba(var(--bs-info-rgb),var(--bs-border-opacity))!important}.border-warning{--bs-border-opacity:1;border-color:rgba(var(--bs-warning-rgb),var(--bs-border-opacity))!important}.border-danger{--bs-border-opacity:1;border-color:rgba(var(--bs-danger-rgb),var(--bs-border-opacity))!important}.border-light{--bs-border-opacity:1;border-color:rgba(var(--bs-light-rgb),var(--bs-border-opacity))!important}.border-dark{--bs-border-opacity:1;border-color:rgba(var(--bs-dark-rgb),var(--bs-border-opacity))!important}.border-black{--bs-border-opacity:1;border-color:rgba(var(--bs-black-rgb),var(--bs-border-opacity))!important}.border-white{--bs-border-opacity:1;border-color:rgba(var(--bs-white-rgb),var(--bs-border-opacity))!important}.border-primary-subtle{border-color:var(--bs-primary-border-subtle)!important}.border-secondary-subtle{border-color:var(--bs-secondary-border-subtle)!important}.border-success-subtle{border-color:var(--bs-success-border-subtle)!important}.border-info-subtle{border-color:var(--bs-info-border-subtle)!important}.border-warning-subtle{border-color:var(--bs-warning-border-subtle)!important}.border-danger-subtle{border-color:var(--bs-danger-border-subtle)!important}.border-light-subtle{border-color:var(--bs-light-border-subtle)!important}.border-dark-subtle{border-color:var(--bs-dark-border-subtle)!important}.border-1{border-width:1px!important}.border-2{border-width:2px!important}.border-3{border-width:3px!important}.border-4{border-width:4px!important}.border-5{border-width:5px!important}.border-opacity-10{--bs-border-opacity:0.1}.border-opacity-25{--bs-border-opacity:0.25}.border-opacity-50{--bs-border-opacity:0.5}.border-opacity-75{--bs-border-opacity:0.75}.border-opacity-100{--bs-border-opacity:1}.w-25{width:25%!important}.w-50{width:50%!important}.w-75{width:75%!important}.w-100{width:100%!important}.w-auto{width:auto!important}.mw-100{max-width:100%!important}.vw-100{width:100vw!important}.min-vw-100{min-width:100vw!important}.h-25{height:25%!important}.h-50{height:50%!important}.h-75{height:75%!important}.h-100{height:100%!important}.h-auto{height:auto!important}.mh-100{max-height:100%!important}.vh-100{height:100vh!important}.min-vh-100{min-height:100vh!important}.flex-fill{flex:1 1 auto!important}.flex-row{flex-direction:row!important}.flex-column{flex-direction:column!important}.flex-row-reverse{flex-direction:row-reverse!important}.flex-column-reverse{flex-direction:column-reverse!important}.flex-grow-0{flex-grow:0!important}.flex-grow-1{flex-grow:1!important}.flex-shrink-0{flex-shrink:0!important}.flex-shrink-1{flex-shrink:1!important}.flex-wrap{flex-wrap:wrap!important}.flex-nowrap{flex-wrap:nowrap!important}.flex-wrap-reverse{flex-wrap:wrap-reverse!important}.justify-content-start{justify-content:flex-start!important}.justify-content-end{justify-content:flex-end!important}.justify-content-center{justify-content:center!important}.justify-content-between{justify-content:space-between!important}.justify-content-around{justify-content:space-around!important}.justify-content-evenly{justify-content:space-evenly!important}.align-items-start{align-items:flex-start!important}.align-items-end{align-items:flex-end!important}.align-items-center{align-items:center!important}.align-items-baseline{align-items:baseline!important}.align-items-stretch{align-items:stretch!important}.align-content-start{align-content:flex-start!important}.align-content-end{align-content:flex-end!important}.align-content-center{align-content:center!important}.align-content-between{align-content:space-between!important}.align-content-around{align-content:space-around!important}.align-content-stretch{align-content:stretch!important}.align-self-auto{align-self:auto!important}.align-self-start{align-self:flex-start!important}.align-self-end{align-self:flex-end!important}.align-self-center{align-self:center!important}.align-self-baseline{align-self:baseline!important}.align-self-stretch{align-self:stretch!important}.order-first{order:-1!important}.order-0{order:0!important}.order-1{order:1!important}.order-2{order:2!important}.order-3{order:3!important}.order-4{order:4!important}.order-5{order:5!important}.order-last{order:6!important}.m-0{margin:0!important}.m-1{margin:.25rem!important}.m-2{margin:.5rem!important}.m-3{margin:1rem!important}.m-4{margin:1.5rem!important}.m-5{margin:3rem!important}.m-auto{margin:auto!important}.mx-0{margin-right:0!important;margin-left:0!important}.mx-1{margin-right:.25rem!important;margin-left:.25rem!important}.mx-2{margin-right:.5rem!important;margin-left:.5rem!important}.mx-3{margin-right:1rem!important;margin-left:1rem!important}.mx-4{margin-right:1.5rem!important;margin-left:1.5rem!important}.mx-5{margin-right:3rem!important;margin-left:3rem!important}.mx-auto{margin-right:auto!important;margin-left:auto!important}.my-0{margin-top:0!important;margin-bottom:0!important}.my-1{margin-top:.25rem!important;margin-bottom:.25rem!important}.my-2{margin-top:.5rem!important;margin-bottom:.5rem!important}.my-3{margin-top:1rem!important;margin-bottom:1rem!important}.my-4{margin-top:1.5rem!important;margin-bottom:1.5rem!important}.my-5{margin-top:3rem!important;margin-bottom:3rem!important}.my-auto{margin-top:auto!important;margin-bottom:auto!important}.mt-0{margin-top:0!important}.mt-1{margin-top:.25rem!important}.mt-2{margin-top:.5rem!important}.mt-3{margin-top:1rem!important}.mt-4{margin-top:1.5rem!important}.mt-5{margin-top:3rem!important}.mt-auto{margin-top:auto!important}.me-0{margin-right:0!important}.me-1{margin-right:.25rem!important}.me-2{margin-right:.5rem!important}.me-3{margin-right:1rem!important}.me-4{margin-right:1.5rem!important}.me-5{margin-right:3rem!important}.me-auto{margin-right:auto!important}.mb-0{margin-bottom:0!important}.mb-1{margin-bottom:.25rem!important}.mb-2{margin-bottom:.5rem!important}.mb-3{margin-bottom:1rem!important}.mb-4{margin-bottom:1.5rem!important}.mb-5{margin-bottom:3rem!important}.mb-auto{margin-bottom:auto!important}.ms-0{margin-left:0!important}.ms-1{margin-left:.25rem!important}.ms-2{margin-left:.5rem!important}.ms-3{margin-left:1rem!important}.ms-4{margin-left:1.5rem!important}.ms-5{margin-left:3rem!important}.ms-auto{margin-left:auto!important}.p-0{padding:0!important}.p-1{padding:.25rem!important}.p-2{padding:.5rem!important}.p-3{padding:1rem!important}.p-4{padding:1.5rem!important}.p-5{padding:3rem!important}.px-0{padding-right:0!important;padding-left:0!important}.px-1{padding-right:.25rem!important;padding-left:.25rem!important}.px-2{padding-right:.5rem!important;padding-left:.5rem!important}.px-3{padding-right:1rem!important;padding-left:1rem!important}.px-4{padding-right:1.5rem!important;padding-left:1.5rem!important}.px-5{padding-right:3rem!important;padding-left:3rem!important}.py-0{padding-top:0!important;padding-bottom:0!important}.py-1{padding-top:.25rem!important;padding-bottom:.25rem!important}.py-2{padding-top:.5rem!important;padding-bottom:.5rem!important}.py-3{padding-top:1rem!important;padding-bottom:1rem!important}.py-4{padding-top:1.5rem!important;padding-bottom:1.5rem!important}.py-5{padding-top:3rem!important;padding-bottom:3rem!important}.pt-0{padding-top:0!important}.pt-1{padding-top:.25rem!important}.pt-2{padding-top:.5rem!important}.pt-3{padding-top:1rem!important}.pt-4{padding-top:1.5rem!important}.pt-5{padding-top:3rem!important}.pe-0{padding-right:0!important}.pe-1{padding-right:.25rem!important}.pe-2{padding-right:.5rem!important}.pe-3{padding-right:1rem!important}.pe-4{padding-right:1.5rem!important}.pe-5{padding-right:3rem!important}.pb-0{padding-bottom:0!important}.pb-1{padding-bottom:.25rem!important}.pb-2{padding-bottom:.5rem!important}.pb-3{padding-bottom:1rem!important}.pb-4{padding-bottom:1.5rem!important}.pb-5{padding-bottom:3rem!important}.ps-0{padding-left:0!important}.ps-1{padding-left:.25rem!important}.ps-2{padding-left:.5rem!important}.ps-3{padding-left:1rem!important}.ps-4{padding-left:1.5rem!important}.ps-5{padding-left:3rem!important}.gap-0{gap:0!important}.gap-1{gap:.25rem!important}.gap-2{gap:.5rem!important}.gap-3{gap:1rem!important}.gap-4{gap:1.5rem!important}.gap-5{gap:3rem!important}.row-gap-0{row-gap:0!important}.row-gap-1{row-gap:.25rem!important}.row-gap-2{row-gap:.5rem!important}.row-gap-3{row-gap:1rem!important}.row-gap-4{row-gap:1.5rem!important}.row-gap-5{row-gap:3rem!important}.column-gap-0{-moz-column-gap:0!important;column-gap:0!important}.column-gap-1{-moz-column-gap:0.25rem!important;column-gap:.25rem!important}.column-gap-2{-moz-column-gap:0.5rem!important;column-gap:.5rem!important}.column-gap-3{-moz-column-gap:1rem!important;column-gap:1rem!important}.column-gap-4{-moz-column-gap:1.5rem!important;column-gap:1.5rem!important}.column-gap-5{-moz-column-gap:3rem!important;column-gap:3rem!important}.font-monospace{font-family:var(--bs-font-monospace)!important}.fs-1{font-size:calc(1.375rem + 1.5vw)!important}.fs-2{font-size:calc(1.325rem + .9vw)!important}.fs-3{font-size:calc(1.3rem + .6vw)!important}.fs-4{font-size:calc(1.275rem + .3vw)!important}.fs-5{font-size:1.25rem!important}.fs-6{font-size:1rem!important}.fst-italic{font-style:italic!important}.fst-normal{font-style:normal!important}.fw-lighter{font-weight:lighter!important}.fw-light{font-weight:300!important}.fw-normal{font-weight:400!important}.fw-medium{font-weight:500!important}.fw-semibold{font-weight:600!important}.fw-bold{font-weight:700!important}.fw-bolder{font-weight:bolder!important}.lh-1{line-height:1!important}.lh-sm{line-height:1.25!important}.lh-base{line-height:1.5!important}.lh-lg{line-height:2!important}.text-start{text-align:left!important}.text-end{text-align:right!important}.text-center{text-align:center!important}.text-decoration-none{text-decoration:none!important}.text-decoration-underline{text-decoration:underline!important}.text-decoration-line-through{text-decoration:line-through!important}.text-lowercase{text-transform:lowercase!important}.text-uppercase{text-transform:uppercase!important}.text-capitalize{text-transform:capitalize!important}.text-wrap{white-space:normal!important}.text-nowrap{white-space:nowrap!important}.text-break{word-wrap:break-word!important;word-break:break-word!important}.text-primary{--bs-text-opacity:1;color:rgba(var(--bs-primary-rgb),var(--bs-text-opacity))!important}.text-secondary{--bs-text-opacity:1;color:rgba(var(--bs-secondary-rgb),var(--bs-text-opacity))!important}.text-success{--bs-text-opacity:1;color:rgba(var(--bs-success-rgb),var(--bs-text-opacity))!important}.text-info{--bs-text-opacity:1;color:rgba(var(--bs-info-rgb),var(--bs-text-opacity))!important}.text-warning{--bs-text-opacity:1;color:rgba(var(--bs-warning-rgb),var(--bs-text-opacity))!important}.text-danger{--bs-text-opacity:1;color:rgba(var(--bs-danger-rgb),var(--bs-text-opacity))!important}.text-light{--bs-text-opacity:1;color:rgba(var(--bs-light-rgb),var(--bs-text-opacity))!important}.text-dark{--bs-text-opacity:1;color:rgba(var(--bs-dark-rgb),var(--bs-text-opacity))!important}.text-black{--bs-text-opacity:1;color:rgba(var(--bs-black-rgb),var(--bs-text-opacity))!important}.text-white{--bs-text-opacity:1;color:rgba(var(--bs-white-rgb),var(--bs-text-opacity))!important}.text-body{--bs-text-opacity:1;color:rgba(var(--bs-body-color-rgb),var(--bs-text-opacity))!important}.text-muted{--bs-text-opacity:1;color:var(--bs-secondary-color)!important}.text-black-50{--bs-text-opacity:1;color:rgba(0,0,0,.5)!important}.text-white-50{--bs-text-opacity:1;color:rgba(255,255,255,.5)!important}.text-body-secondary{--bs-text-opacity:1;color:var(--bs-secondary-color)!important}.text-body-tertiary{--bs-text-opacity:1;color:var(--bs-tertiary-color)!important}.text-body-emphasis{--bs-text-opacity:1;color:var(--bs-emphasis-color)!important}.text-reset{--bs-text-opacity:1;color:inherit!important}.text-opacity-25{--bs-text-opacity:0.25}.text-opacity-50{--bs-text-opacity:0.5}.text-opacity-75{--bs-text-opacity:0.75}.text-opacity-100{--bs-text-opacity:1}.text-primary-emphasis{color:var(--bs-primary-text-emphasis)!important}.text-secondary-emphasis{color:var(--bs-secondary-text-emphasis)!important}.text-success-emphasis{color:var(--bs-success-text-emphasis)!important}.text-info-emphasis{color:var(--bs-info-text-emphasis)!important}.text-warning-emphasis{color:var(--bs-warning-text-emphasis)!important}.text-danger-emphasis{color:var(--bs-danger-text-emphasis)!important}.text-light-emphasis{color:var(--bs-light-text-emphasis)!important}.text-dark-emphasis{color:var(--bs-dark-text-emphasis)!important}.link-opacity-10{--bs-link-opacity:0.1}.link-opacity-10-hover:hover{--bs-link-opacity:0.1}.link-opacity-25{--bs-link-opacity:0.25}.link-opacity-25-hover:hover{--bs-link-opacity:0.25}.link-opacity-50{--bs-link-opacity:0.5}.link-opacity-50-hover:hover{--bs-link-opacity:0.5}.link-opacity-75{--bs-link-opacity:0.75}.link-opacity-75-hover:hover{--bs-link-opacity:0.75}.link-opacity-100{--bs-link-opacity:1}.link-opacity-100-hover:hover{--bs-link-opacity:1}.link-offset-1{text-underline-offset:0.125em!important}.link-offset-1-hover:hover{text-underline-offset:0.125em!important}.link-offset-2{text-underline-offset:0.25em!important}.link-offset-2-hover:hover{text-underline-offset:0.25em!important}.link-offset-3{text-underline-offset:0.375em!important}.link-offset-3-hover:hover{text-underline-offset:0.375em!important}.link-underline-primary{--bs-link-underline-opacity:1;-webkit-text-decoration-color:rgba(var(--bs-primary-rgb),var(--bs-link-underline-opacity))!important;text-decoration-color:rgba(var(--bs-primary-rgb),var(--bs-link-underline-opacity))!important}.link-underline-secondary{--bs-link-underline-opacity:1;-webkit-text-decoration-color:rgba(var(--bs-secondary-rgb),var(--bs-link-underline-opacity))!important;text-decoration-color:rgba(var(--bs-secondary-rgb),var(--bs-link-underline-opacity))!important}.link-underline-success{--bs-link-underline-opacity:1;-webkit-text-decoration-color:rgba(var(--bs-success-rgb),var(--bs-link-underline-opacity))!important;text-decoration-color:rgba(var(--bs-success-rgb),var(--bs-link-underline-opacity))!important}.link-underline-info{--bs-link-underline-opacity:1;-webkit-text-decoration-color:rgba(var(--bs-info-rgb),var(--bs-link-underline-opacity))!important;text-decoration-color:rgba(var(--bs-info-rgb),var(--bs-link-underline-opacity))!important}.link-underline-warning{--bs-link-underline-opacity:1;-webkit-text-decoration-color:rgba(var(--bs-warning-rgb),var(--bs-link-underline-opacity))!important;text-decoration-color:rgba(var(--bs-warning-rgb),var(--bs-link-underline-opacity))!important}.link-underline-danger{--bs-link-underline-opacity:1;-webkit-text-decoration-color:rgba(var(--bs-danger-rgb),var(--bs-link-underline-opacity))!important;text-decoration-color:rgba(var(--bs-danger-rgb),var(--bs-link-underline-opacity))!important}.link-underline-light{--bs-link-underline-opacity:1;-webkit-text-decoration-color:rgba(var(--bs-light-rgb),var(--bs-link-underline-opacity))!important;text-decoration-color:rgba(var(--bs-light-rgb),var(--bs-link-underline-opacity))!important}.link-underline-dark{--bs-link-underline-opacity:1;-webkit-text-decoration-color:rgba(var(--bs-dark-rgb),var(--bs-link-underline-opacity))!important;text-decoration-color:rgba(var(--bs-dark-rgb),var(--bs-link-underline-opacity))!important}.link-underline{--bs-link-underline-opacity:1;-webkit-text-decoration-color:rgba(var(--bs-link-color-rgb),var(--bs-link-underline-opacity,1))!important;text-decoration-color:rgba(var(--bs-link-color-rgb),var(--bs-link-underline-opacity,1))!important}.link-underline-opacity-0{--bs-link-underline-opacity:0}.link-underline-opacity-0-hover:hover{--bs-link-underline-opacity:0}.link-underline-opacity-10{--bs-link-underline-opacity:0.1}.link-underline-opacity-10-hover:hover{--bs-link-underline-opacity:0.1}.link-underline-opacity-25{--bs-link-underline-opacity:0.25}.link-underline-opacity-25-hover:hover{--bs-link-underline-opacity:0.25}.link-underline-opacity-50{--bs-link-underline-opacity:0.5}.link-underline-opacity-50-hover:hover{--bs-link-underline-opacity:0.5}.link-underline-opacity-75{--bs-link-underline-opacity:0.75}.link-underline-opacity-75-hover:hover{--bs-link-underline-opacity:0.75}.link-underline-opacity-100{--bs-link-underline-opacity:1}.link-underline-opacity-100-hover:hover{--bs-link-underline-opacity:1}.bg-primary{--bs-bg-opacity:1;background-color:rgba(var(--bs-primary-rgb),var(--bs-bg-opacity))!important}.bg-secondary{--bs-bg-opacity:1;background-color:rgba(var(--bs-secondary-rgb),var(--bs-bg-opacity))!important}.bg-success{--bs-bg-opacity:1;background-color:rgba(var(--bs-success-rgb),var(--bs-bg-opacity))!important}.bg-info{--bs-bg-opacity:1;background-color:rgba(var(--bs-info-rgb),var(--bs-bg-opacity))!important}.bg-warning{--bs-bg-opacity:1;background-color:rgba(var(--bs-warning-rgb),var(--bs-bg-opacity))!important}.bg-danger{--bs-bg-opacity:1;background-color:rgba(var(--bs-danger-rgb),var(--bs-bg-opacity))!important}.bg-light{--bs-bg-opacity:1;background-color:rgba(var(--bs-light-rgb),var(--bs-bg-opacity))!important}.bg-dark{--bs-bg-opacity:1;background-color:rgba(var(--bs-dark-rgb),var(--bs-bg-opacity))!important}.bg-black{--bs-bg-opacity:1;background-color:rgba(var(--bs-black-rgb),var(--bs-bg-opacity))!important}.bg-white{--bs-bg-opacity:1;background-color:rgba(var(--bs-white-rgb),var(--bs-bg-opacity))!important}.bg-body{--bs-bg-opacity:1;background-color:rgba(var(--bs-body-bg-rgb),var(--bs-bg-opacity))!important}.bg-transparent{--bs-bg-opacity:1;background-color:transparent!important}.bg-body-secondary{--bs-bg-opacity:1;background-color:rgba(var(--bs-secondary-bg-rgb),var(--bs-bg-opacity))!important}.bg-body-tertiary{--bs-bg-opacity:1;background-color:rgba(var(--bs-tertiary-bg-rgb),var(--bs-bg-opacity))!important}.bg-opacity-10{--bs-bg-opacity:0.1}.bg-opacity-25{--bs-bg-opacity:0.25}.bg-opacity-50{--bs-bg-opacity:0.5}.bg-opacity-75{--bs-bg-opacity:0.75}.bg-opacity-100{--bs-bg-opacity:1}.bg-primary-subtle{background-color:var(--bs-primary-bg-subtle)!important}.bg-secondary-subtle{background-color:var(--bs-secondary-bg-subtle)!important}.bg-success-subtle{background-color:var(--bs-success-bg-subtle)!important}.bg-info-subtle{background-color:var(--bs-info-bg-subtle)!important}.bg-warning-subtle{background-color:var(--bs-warning-bg-subtle)!important}.bg-danger-subtle{background-color:var(--bs-danger-bg-subtle)!important}.bg-light-subtle{background-color:var(--bs-light-bg-subtle)!important}.bg-dark-subtle{background-color:var(--bs-dark-bg-subtle)!important}.bg-gradient{background-image:var(--bs-gradient)!important}.user-select-all{-webkit-user-select:all!important;-moz-user-select:all!important;user-select:all!important}.user-select-auto{-webkit-user-select:auto!important;-moz-user-select:auto!important;user-select:auto!important}.user-select-none{-webkit-user-select:none!important;-moz-user-select:none!important;user-select:none!important}.pe-none{pointer-events:none!important}.pe-auto{pointer-events:auto!important}.rounded{border-radius:var(--bs-border-radius)!important}.rounded-0{border-radius:0!important}.rounded-1{border-radius:var(--bs-border-radius-sm)!important}.rounded-2{border-radius:var(--bs-border-radius)!important}.rounded-3{border-radius:var(--bs-border-radius-lg)!important}.rounded-4{border-radius:var(--bs-border-radius-xl)!important}.rounded-5{border-radius:var(--bs-border-radius-xxl)!important}.rounded-circle{border-radius:50%!important}.rounded-pill{border-radius:var(--bs-border-radius-pill)!important}.rounded-top{border-top-left-radius:var(--bs-border-radius)!important;border-top-right-radius:var(--bs-border-radius)!important}.rounded-top-0{border-top-left-radius:0!important;border-top-right-radius:0!important}.rounded-top-1{border-top-left-radius:var(--bs-border-radius-sm)!important;border-top-right-radius:var(--bs-border-radius-sm)!important}.rounded-top-2{border-top-left-radius:var(--bs-border-radius)!important;border-top-right-radius:var(--bs-border-radius)!important}.rounded-top-3{border-top-left-radius:var(--bs-border-radius-lg)!important;border-top-right-radius:var(--bs-border-radius-lg)!important}.rounded-top-4{border-top-left-radius:var(--bs-border-radius-xl)!important;border-top-right-radius:var(--bs-border-radius-xl)!important}.rounded-top-5{border-top-left-radius:var(--bs-border-radius-xxl)!important;border-top-right-radius:var(--bs-border-radius-xxl)!important}.rounded-top-circle{border-top-left-radius:50%!important;border-top-right-radius:50%!important}.rounded-top-pill{border-top-left-radius:var(--bs-border-radius-pill)!important;border-top-right-radius:var(--bs-border-radius-pill)!important}.rounded-end{border-top-right-radius:var(--bs-border-radius)!important;border-bottom-right-radius:var(--bs-border-radius)!important}.rounded-end-0{border-top-right-radius:0!important;border-bottom-right-radius:0!important}.rounded-end-1{border-top-right-radius:var(--bs-border-radius-sm)!important;border-bottom-right-radius:var(--bs-border-radius-sm)!important}.rounded-end-2{border-top-right-radius:var(--bs-border-radius)!important;border-bottom-right-radius:var(--bs-border-radius)!important}.rounded-end-3{border-top-right-radius:var(--bs-border-radius-lg)!important;border-bottom-right-radius:var(--bs-border-radius-lg)!important}.rounded-end-4{border-top-right-radius:var(--bs-border-radius-xl)!important;border-bottom-right-radius:var(--bs-border-radius-xl)!important}.rounded-end-5{border-top-right-radius:var(--bs-border-radius-xxl)!important;border-bottom-right-radius:var(--bs-border-radius-xxl)!important}.rounded-end-circle{border-top-right-radius:50%!important;border-bottom-right-radius:50%!important}.rounded-end-pill{border-top-right-radius:var(--bs-border-radius-pill)!important;border-bottom-right-radius:var(--bs-border-radius-pill)!important}.rounded-bottom{border-bottom-right-radius:var(--bs-border-radius)!important;border-bottom-left-radius:var(--bs-border-radius)!important}.rounded-bottom-0{border-bottom-right-radius:0!important;border-bottom-left-radius:0!important}.rounded-bottom-1{border-bottom-right-radius:var(--bs-border-radius-sm)!important;border-bottom-left-radius:var(--bs-border-radius-sm)!important}.rounded-bottom-2{border-bottom-right-radius:var(--bs-border-radius)!important;border-bottom-left-radius:var(--bs-border-radius)!important}.rounded-bottom-3{border-bottom-right-radius:var(--bs-border-radius-lg)!important;border-bottom-left-radius:var(--bs-border-radius-lg)!important}.rounded-bottom-4{border-bottom-right-radius:var(--bs-border-radius-xl)!important;border-bottom-left-radius:var(--bs-border-radius-xl)!important}.rounded-bottom-5{border-bottom-right-radius:var(--bs-border-radius-xxl)!important;border-bottom-left-radius:var(--bs-border-radius-xxl)!important}.rounded-bottom-circle{border-bottom-right-radius:50%!important;border-bottom-left-radius:50%!important}.rounded-bottom-pill{border-bottom-right-radius:var(--bs-border-radius-pill)!important;border-bottom-left-radius:var(--bs-border-radius-pill)!important}.rounded-start{border-bottom-left-radius:var(--bs-border-radius)!important;border-top-left-radius:var(--bs-border-radius)!important}.rounded-start-0{border-bottom-left-radius:0!important;border-top-left-radius:0!important}.rounded-start-1{border-bottom-left-radius:var(--bs-border-radius-sm)!important;border-top-left-radius:var(--bs-border-radius-sm)!important}.rounded-start-2{border-bottom-left-radius:var(--bs-border-radius)!important;border-top-left-radius:var(--bs-border-radius)!important}.rounded-start-3{border-bottom-left-radius:var(--bs-border-radius-lg)!important;border-top-left-radius:var(--bs-border-radius-lg)!important}.rounded-start-4{border-bottom-left-radius:var(--bs-border-radius-xl)!important;border-top-left-radius:var(--bs-border-radius-xl)!important}.rounded-start-5{border-bottom-left-radius:var(--bs-border-radius-xxl)!important;border-top-left-radius:var(--bs-border-radius-xxl)!important}.rounded-start-circle{border-bottom-left-radius:50%!important;border-top-left-radius:50%!important}.rounded-start-pill{border-bottom-left-radius:var(--bs-border-radius-pill)!important;border-top-left-radius:var(--bs-border-radius-pill)!important}.visible{visibility:visible!important}.invisible{visibility:hidden!important}.z-n1{z-index:-1!important}.z-0{z-index:0!important}.z-1{z-index:1!important}.z-2{z-index:2!important}.z-3{z-index:3!important}@media (min-width:576px){.float-sm-start{float:left!important}.float-sm-end{float:right!important}.float-sm-none{float:none!important}.object-fit-sm-contain{-o-object-fit:contain!important;object-fit:contain!important}.object-fit-sm-cover{-o-object-fit:cover!important;object-fit:cover!important}.object-fit-sm-fill{-o-object-fit:fill!important;object-fit:fill!important}.object-fit-sm-scale{-o-object-fit:scale-down!important;object-fit:scale-down!important}.object-fit-sm-none{-o-object-fit:none!important;object-fit:none!important}.d-sm-inline{display:inline!important}.d-sm-inline-block{display:inline-block!important}.d-sm-block{display:block!important}.d-sm-grid{display:grid!important}.d-sm-inline-grid{display:inline-grid!important}.d-sm-table{display:table!important}.d-sm-table-row{display:table-row!important}.d-sm-table-cell{display:table-cell!important}.d-sm-flex{display:flex!important}.d-sm-inline-flex{display:inline-flex!important}.d-sm-none{display:none!important}.flex-sm-fill{flex:1 1 auto!important}.flex-sm-row{flex-direction:row!important}.flex-sm-column{flex-direction:column!important}.flex-sm-row-reverse{flex-direction:row-reverse!important}.flex-sm-column-reverse{flex-direction:column-reverse!important}.flex-sm-grow-0{flex-grow:0!important}.flex-sm-grow-1{flex-grow:1!important}.flex-sm-shrink-0{flex-shrink:0!important}.flex-sm-shrink-1{flex-shrink:1!important}.flex-sm-wrap{flex-wrap:wrap!important}.flex-sm-nowrap{flex-wrap:nowrap!important}.flex-sm-wrap-reverse{flex-wrap:wrap-reverse!important}.justify-content-sm-start{justify-content:flex-start!important}.justify-content-sm-end{justify-content:flex-end!important}.justify-content-sm-center{justify-content:center!important}.justify-content-sm-between{justify-content:space-between!important}.justify-content-sm-around{justify-content:space-around!important}.justify-content-sm-evenly{justify-content:space-evenly!important}.align-items-sm-start{align-items:flex-start!important}.align-items-sm-end{align-items:flex-end!important}.align-items-sm-center{align-items:center!important}.align-items-sm-baseline{align-items:baseline!important}.align-items-sm-stretch{align-items:stretch!important}.align-content-sm-start{align-content:flex-start!important}.align-content-sm-end{align-content:flex-end!important}.align-content-sm-center{align-content:center!important}.align-content-sm-between{align-content:space-between!important}.align-content-sm-around{align-content:space-around!important}.align-content-sm-stretch{align-content:stretch!important}.align-self-sm-auto{align-self:auto!important}.align-self-sm-start{align-self:flex-start!important}.align-self-sm-end{align-self:flex-end!important}.align-self-sm-center{align-self:center!important}.align-self-sm-baseline{align-self:baseline!important}.align-self-sm-stretch{align-self:stretch!important}.order-sm-first{order:-1!important}.order-sm-0{order:0!important}.order-sm-1{order:1!important}.order-sm-2{order:2!important}.order-sm-3{order:3!important}.order-sm-4{order:4!important}.order-sm-5{order:5!important}.order-sm-last{order:6!important}.m-sm-0{margin:0!important}.m-sm-1{margin:.25rem!important}.m-sm-2{margin:.5rem!important}.m-sm-3{margin:1rem!important}.m-sm-4{margin:1.5rem!important}.m-sm-5{margin:3rem!important}.m-sm-auto{margin:auto!important}.mx-sm-0{margin-right:0!important;margin-left:0!important}.mx-sm-1{margin-right:.25rem!important;margin-left:.25rem!important}.mx-sm-2{margin-right:.5rem!important;margin-left:.5rem!important}.mx-sm-3{margin-right:1rem!important;margin-left:1rem!important}.mx-sm-4{margin-right:1.5rem!important;margin-left:1.5rem!important}.mx-sm-5{margin-right:3rem!important;margin-left:3rem!important}.mx-sm-auto{margin-right:auto!important;margin-left:auto!important}.my-sm-0{margin-top:0!important;margin-bottom:0!important}.my-sm-1{margin-top:.25rem!important;margin-bottom:.25rem!important}.my-sm-2{margin-top:.5rem!important;margin-bottom:.5rem!important}.my-sm-3{margin-top:1rem!important;margin-bottom:1rem!important}.my-sm-4{margin-top:1.5rem!important;margin-bottom:1.5rem!important}.my-sm-5{margin-top:3rem!important;margin-bottom:3rem!important}.my-sm-auto{margin-top:auto!important;margin-bottom:auto!important}.mt-sm-0{margin-top:0!important}.mt-sm-1{margin-top:.25rem!important}.mt-sm-2{margin-top:.5rem!important}.mt-sm-3{margin-top:1rem!important}.mt-sm-4{margin-top:1.5rem!important}.mt-sm-5{margin-top:3rem!important}.mt-sm-auto{margin-top:auto!important}.me-sm-0{margin-right:0!important}.me-sm-1{margin-right:.25rem!important}.me-sm-2{margin-right:.5rem!important}.me-sm-3{margin-right:1rem!important}.me-sm-4{margin-right:1.5rem!important}.me-sm-5{margin-right:3rem!important}.me-sm-auto{margin-right:auto!important}.mb-sm-0{margin-bottom:0!important}.mb-sm-1{margin-bottom:.25rem!important}.mb-sm-2{margin-bottom:.5rem!important}.mb-sm-3{margin-bottom:1rem!important}.mb-sm-4{margin-bottom:1.5rem!important}.mb-sm-5{margin-bottom:3rem!important}.mb-sm-auto{margin-bottom:auto!important}.ms-sm-0{margin-left:0!important}.ms-sm-1{margin-left:.25rem!important}.ms-sm-2{margin-left:.5rem!important}.ms-sm-3{margin-left:1rem!important}.ms-sm-4{margin-left:1.5rem!important}.ms-sm-5{margin-left:3rem!important}.ms-sm-auto{margin-left:auto!important}.p-sm-0{padding:0!important}.p-sm-1{padding:.25rem!important}.p-sm-2{padding:.5rem!important}.p-sm-3{padding:1rem!important}.p-sm-4{padding:1.5rem!important}.p-sm-5{padding:3rem!important}.px-sm-0{padding-right:0!important;padding-left:0!important}.px-sm-1{padding-right:.25rem!important;padding-left:.25rem!important}.px-sm-2{padding-right:.5rem!important;padding-left:.5rem!important}.px-sm-3{padding-right:1rem!important;padding-left:1rem!important}.px-sm-4{padding-right:1.5rem!important;padding-left:1.5rem!important}.px-sm-5{padding-right:3rem!important;padding-left:3rem!important}.py-sm-0{padding-top:0!important;padding-bottom:0!important}.py-sm-1{padding-top:.25rem!important;padding-bottom:.25rem!important}.py-sm-2{padding-top:.5rem!important;padding-bottom:.5rem!important}.py-sm-3{padding-top:1rem!important;padding-bottom:1rem!important}.py-sm-4{padding-top:1.5rem!important;padding-bottom:1.5rem!important}.py-sm-5{padding-top:3rem!important;padding-bottom:3rem!important}.pt-sm-0{padding-top:0!important}.pt-sm-1{padding-top:.25rem!important}.pt-sm-2{padding-top:.5rem!important}.pt-sm-3{padding-top:1rem!important}.pt-sm-4{padding-top:1.5rem!important}.pt-sm-5{padding-top:3rem!important}.pe-sm-0{padding-right:0!important}.pe-sm-1{padding-right:.25rem!important}.pe-sm-2{padding-right:.5rem!important}.pe-sm-3{padding-right:1rem!important}.pe-sm-4{padding-right:1.5rem!important}.pe-sm-5{padding-right:3rem!important}.pb-sm-0{padding-bottom:0!important}.pb-sm-1{padding-bottom:.25rem!important}.pb-sm-2{padding-bottom:.5rem!important}.pb-sm-3{padding-bottom:1rem!important}.pb-sm-4{padding-bottom:1.5rem!important}.pb-sm-5{padding-bottom:3rem!important}.ps-sm-0{padding-left:0!important}.ps-sm-1{padding-left:.25rem!important}.ps-sm-2{padding-left:.5rem!important}.ps-sm-3{padding-left:1rem!important}.ps-sm-4{padding-left:1.5rem!important}.ps-sm-5{padding-left:3rem!important}.gap-sm-0{gap:0!important}.gap-sm-1{gap:.25rem!important}.gap-sm-2{gap:.5rem!important}.gap-sm-3{gap:1rem!important}.gap-sm-4{gap:1.5rem!important}.gap-sm-5{gap:3rem!important}.row-gap-sm-0{row-gap:0!important}.row-gap-sm-1{row-gap:.25rem!important}.row-gap-sm-2{row-gap:.5rem!important}.row-gap-sm-3{row-gap:1rem!important}.row-gap-sm-4{row-gap:1.5rem!important}.row-gap-sm-5{row-gap:3rem!important}.column-gap-sm-0{-moz-column-gap:0!important;column-gap:0!important}.column-gap-sm-1{-moz-column-gap:0.25rem!important;column-gap:.25rem!important}.column-gap-sm-2{-moz-column-gap:0.5rem!important;column-gap:.5rem!important}.column-gap-sm-3{-moz-column-gap:1rem!important;column-gap:1rem!important}.column-gap-sm-4{-moz-column-gap:1.5rem!important;column-gap:1.5rem!important}.column-gap-sm-5{-moz-column-gap:3rem!important;column-gap:3rem!important}.text-sm-start{text-align:left!important}.text-sm-end{text-align:right!important}.text-sm-center{text-align:center!important}}@media (min-width:768px){.float-md-start{float:left!important}.float-md-end{float:right!important}.float-md-none{float:none!important}.object-fit-md-contain{-o-object-fit:contain!important;object-fit:contain!important}.object-fit-md-cover{-o-object-fit:cover!important;object-fit:cover!important}.object-fit-md-fill{-o-object-fit:fill!important;object-fit:fill!important}.object-fit-md-scale{-o-object-fit:scale-down!important;object-fit:scale-down!important}.object-fit-md-none{-o-object-fit:none!important;object-fit:none!important}.d-md-inline{display:inline!important}.d-md-inline-block{display:inline-block!important}.d-md-block{display:block!important}.d-md-grid{display:grid!important}.d-md-inline-grid{display:inline-grid!important}.d-md-table{display:table!important}.d-md-table-row{display:table-row!important}.d-md-table-cell{display:table-cell!important}.d-md-flex{display:flex!important}.d-md-inline-flex{display:inline-flex!important}.d-md-none{display:none!important}.flex-md-fill{flex:1 1 auto!important}.flex-md-row{flex-direction:row!important}.flex-md-column{flex-direction:column!important}.flex-md-row-reverse{flex-direction:row-reverse!important}.flex-md-column-reverse{flex-direction:column-reverse!important}.flex-md-grow-0{flex-grow:0!important}.flex-md-grow-1{flex-grow:1!important}.flex-md-shrink-0{flex-shrink:0!important}.flex-md-shrink-1{flex-shrink:1!important}.flex-md-wrap{flex-wrap:wrap!important}.flex-md-nowrap{flex-wrap:nowrap!important}.flex-md-wrap-reverse{flex-wrap:wrap-reverse!important}.justify-content-md-start{justify-content:flex-start!important}.justify-content-md-end{justify-content:flex-end!important}.justify-content-md-center{justify-content:center!important}.justify-content-md-between{justify-content:space-between!important}.justify-content-md-around{justify-content:space-around!important}.justify-content-md-evenly{justify-content:space-evenly!important}.align-items-md-start{align-items:flex-start!important}.align-items-md-end{align-items:flex-end!important}.align-items-md-center{align-items:center!important}.align-items-md-baseline{align-items:baseline!important}.align-items-md-stretch{align-items:stretch!important}.align-content-md-start{align-content:flex-start!important}.align-content-md-end{align-content:flex-end!important}.align-content-md-center{align-content:center!important}.align-content-md-between{align-content:space-between!important}.align-content-md-around{align-content:space-around!important}.align-content-md-stretch{align-content:stretch!important}.align-self-md-auto{align-self:auto!important}.align-self-md-start{align-self:flex-start!important}.align-self-md-end{align-self:flex-end!important}.align-self-md-center{align-self:center!important}.align-self-md-baseline{align-self:baseline!important}.align-self-md-stretch{align-self:stretch!important}.order-md-first{order:-1!important}.order-md-0{order:0!important}.order-md-1{order:1!important}.order-md-2{order:2!important}.order-md-3{order:3!important}.order-md-4{order:4!important}.order-md-5{order:5!important}.order-md-last{order:6!important}.m-md-0{margin:0!important}.m-md-1{margin:.25rem!important}.m-md-2{margin:.5rem!important}.m-md-3{margin:1rem!important}.m-md-4{margin:1.5rem!important}.m-md-5{margin:3rem!important}.m-md-auto{margin:auto!important}.mx-md-0{margin-right:0!important;margin-left:0!important}.mx-md-1{margin-right:.25rem!important;margin-left:.25rem!important}.mx-md-2{margin-right:.5rem!important;margin-left:.5rem!important}.mx-md-3{margin-right:1rem!important;margin-left:1rem!important}.mx-md-4{margin-right:1.5rem!important;margin-left:1.5rem!important}.mx-md-5{margin-right:3rem!important;margin-left:3rem!important}.mx-md-auto{margin-right:auto!important;margin-left:auto!important}.my-md-0{margin-top:0!important;margin-bottom:0!important}.my-md-1{margin-top:.25rem!important;margin-bottom:.25rem!important}.my-md-2{margin-top:.5rem!important;margin-bottom:.5rem!important}.my-md-3{margin-top:1rem!important;margin-bottom:1rem!important}.my-md-4{margin-top:1.5rem!important;margin-bottom:1.5rem!important}.my-md-5{margin-top:3rem!important;margin-bottom:3rem!important}.my-md-auto{margin-top:auto!important;margin-bottom:auto!important}.mt-md-0{margin-top:0!important}.mt-md-1{margin-top:.25rem!important}.mt-md-2{margin-top:.5rem!important}.mt-md-3{margin-top:1rem!important}.mt-md-4{margin-top:1.5rem!important}.mt-md-5{margin-top:3rem!important}.mt-md-auto{margin-top:auto!important}.me-md-0{margin-right:0!important}.me-md-1{margin-right:.25rem!important}.me-md-2{margin-right:.5rem!important}.me-md-3{margin-right:1rem!important}.me-md-4{margin-right:1.5rem!important}.me-md-5{margin-right:3rem!important}.me-md-auto{margin-right:auto!important}.mb-md-0{margin-bottom:0!important}.mb-md-1{margin-bottom:.25rem!important}.mb-md-2{margin-bottom:.5rem!important}.mb-md-3{margin-bottom:1rem!important}.mb-md-4{margin-bottom:1.5rem!important}.mb-md-5{margin-bottom:3rem!important}.mb-md-auto{margin-bottom:auto!important}.ms-md-0{margin-left:0!important}.ms-md-1{margin-left:.25rem!important}.ms-md-2{margin-left:.5rem!important}.ms-md-3{margin-left:1rem!important}.ms-md-4{margin-left:1.5rem!important}.ms-md-5{margin-left:3rem!important}.ms-md-auto{margin-left:auto!important}.p-md-0{padding:0!important}.p-md-1{padding:.25rem!important}.p-md-2{padding:.5rem!important}.p-md-3{padding:1rem!important}.p-md-4{padding:1.5rem!important}.p-md-5{padding:3rem!important}.px-md-0{padding-right:0!important;padding-left:0!important}.px-md-1{padding-right:.25rem!important;padding-left:.25rem!important}.px-md-2{padding-right:.5rem!important;padding-left:.5rem!important}.px-md-3{padding-right:1rem!important;padding-left:1rem!important}.px-md-4{padding-right:1.5rem!important;padding-left:1.5rem!important}.px-md-5{padding-right:3rem!important;padding-left:3rem!important}.py-md-0{padding-top:0!important;padding-bottom:0!important}.py-md-1{padding-top:.25rem!important;padding-bottom:.25rem!important}.py-md-2{padding-top:.5rem!important;padding-bottom:.5rem!important}.py-md-3{padding-top:1rem!important;padding-bottom:1rem!important}.py-md-4{padding-top:1.5rem!important;padding-bottom:1.5rem!important}.py-md-5{padding-top:3rem!important;padding-bottom:3rem!important}.pt-md-0{padding-top:0!important}.pt-md-1{padding-top:.25rem!important}.pt-md-2{padding-top:.5rem!important}.pt-md-3{padding-top:1rem!important}.pt-md-4{padding-top:1.5rem!important}.pt-md-5{padding-top:3rem!important}.pe-md-0{padding-right:0!important}.pe-md-1{padding-right:.25rem!important}.pe-md-2{padding-right:.5rem!important}.pe-md-3{padding-right:1rem!important}.pe-md-4{padding-right:1.5rem!important}.pe-md-5{padding-right:3rem!important}.pb-md-0{padding-bottom:0!important}.pb-md-1{padding-bottom:.25rem!important}.pb-md-2{padding-bottom:.5rem!important}.pb-md-3{padding-bottom:1rem!important}.pb-md-4{padding-bottom:1.5rem!important}.pb-md-5{padding-bottom:3rem!important}.ps-md-0{padding-left:0!important}.ps-md-1{padding-left:.25rem!important}.ps-md-2{padding-left:.5rem!important}.ps-md-3{padding-left:1rem!important}.ps-md-4{padding-left:1.5rem!important}.ps-md-5{padding-left:3rem!important}.gap-md-0{gap:0!important}.gap-md-1{gap:.25rem!important}.gap-md-2{gap:.5rem!important}.gap-md-3{gap:1rem!important}.gap-md-4{gap:1.5rem!important}.gap-md-5{gap:3rem!important}.row-gap-md-0{row-gap:0!important}.row-gap-md-1{row-gap:.25rem!important}.row-gap-md-2{row-gap:.5rem!important}.row-gap-md-3{row-gap:1rem!important}.row-gap-md-4{row-gap:1.5rem!important}.row-gap-md-5{row-gap:3rem!important}.column-gap-md-0{-moz-column-gap:0!important;column-gap:0!important}.column-gap-md-1{-moz-column-gap:0.25rem!important;column-gap:.25rem!important}.column-gap-md-2{-moz-column-gap:0.5rem!important;column-gap:.5rem!important}.column-gap-md-3{-moz-column-gap:1rem!important;column-gap:1rem!important}.column-gap-md-4{-moz-column-gap:1.5rem!important;column-gap:1.5rem!important}.column-gap-md-5{-moz-column-gap:3rem!important;column-gap:3rem!important}.text-md-start{text-align:left!important}.text-md-end{text-align:right!important}.text-md-center{text-align:center!important}}@media (min-width:992px){.float-lg-start{float:left!important}.float-lg-end{float:right!important}.float-lg-none{float:none!important}.object-fit-lg-contain{-o-object-fit:contain!important;object-fit:contain!important}.object-fit-lg-cover{-o-object-fit:cover!important;object-fit:cover!important}.object-fit-lg-fill{-o-object-fit:fill!important;object-fit:fill!important}.object-fit-lg-scale{-o-object-fit:scale-down!important;object-fit:scale-down!important}.object-fit-lg-none{-o-object-fit:none!important;object-fit:none!important}.d-lg-inline{display:inline!important}.d-lg-inline-block{display:inline-block!important}.d-lg-block{display:block!important}.d-lg-grid{display:grid!important}.d-lg-inline-grid{display:inline-grid!important}.d-lg-table{display:table!important}.d-lg-table-row{display:table-row!important}.d-lg-table-cell{display:table-cell!important}.d-lg-flex{display:flex!important}.d-lg-inline-flex{display:inline-flex!important}.d-lg-none{display:none!important}.flex-lg-fill{flex:1 1 auto!important}.flex-lg-row{flex-direction:row!important}.flex-lg-column{flex-direction:column!important}.flex-lg-row-reverse{flex-direction:row-reverse!important}.flex-lg-column-reverse{flex-direction:column-reverse!important}.flex-lg-grow-0{flex-grow:0!important}.flex-lg-grow-1{flex-grow:1!important}.flex-lg-shrink-0{flex-shrink:0!important}.flex-lg-shrink-1{flex-shrink:1!important}.flex-lg-wrap{flex-wrap:wrap!important}.flex-lg-nowrap{flex-wrap:nowrap!important}.flex-lg-wrap-reverse{flex-wrap:wrap-reverse!important}.justify-content-lg-start{justify-content:flex-start!important}.justify-content-lg-end{justify-content:flex-end!important}.justify-content-lg-center{justify-content:center!important}.justify-content-lg-between{justify-content:space-between!important}.justify-content-lg-around{justify-content:space-around!important}.justify-content-lg-evenly{justify-content:space-evenly!important}.align-items-lg-start{align-items:flex-start!important}.align-items-lg-end{align-items:flex-end!important}.align-items-lg-center{align-items:center!important}.align-items-lg-baseline{align-items:baseline!important}.align-items-lg-stretch{align-items:stretch!important}.align-content-lg-start{align-content:flex-start!important}.align-content-lg-end{align-content:flex-end!important}.align-content-lg-center{align-content:center!important}.align-content-lg-between{align-content:space-between!important}.align-content-lg-around{align-content:space-around!important}.align-content-lg-stretch{align-content:stretch!important}.align-self-lg-auto{align-self:auto!important}.align-self-lg-start{align-self:flex-start!important}.align-self-lg-end{align-self:flex-end!important}.align-self-lg-center{align-self:center!important}.align-self-lg-baseline{align-self:baseline!important}.align-self-lg-stretch{align-self:stretch!important}.order-lg-first{order:-1!important}.order-lg-0{order:0!important}.order-lg-1{order:1!important}.order-lg-2{order:2!important}.order-lg-3{order:3!important}.order-lg-4{order:4!important}.order-lg-5{order:5!important}.order-lg-last{order:6!important}.m-lg-0{margin:0!important}.m-lg-1{margin:.25rem!important}.m-lg-2{margin:.5rem!important}.m-lg-3{margin:1rem!important}.m-lg-4{margin:1.5rem!important}.m-lg-5{margin:3rem!important}.m-lg-auto{margin:auto!important}.mx-lg-0{margin-right:0!important;margin-left:0!important}.mx-lg-1{margin-right:.25rem!important;margin-left:.25rem!important}.mx-lg-2{margin-right:.5rem!important;margin-left:.5rem!important}.mx-lg-3{margin-right:1rem!important;margin-left:1rem!important}.mx-lg-4{margin-right:1.5rem!important;margin-left:1.5rem!important}.mx-lg-5{margin-right:3rem!important;margin-left:3rem!important}.mx-lg-auto{margin-right:auto!important;margin-left:auto!important}.my-lg-0{margin-top:0!important;margin-bottom:0!important}.my-lg-1{margin-top:.25rem!important;margin-bottom:.25rem!important}.my-lg-2{margin-top:.5rem!important;margin-bottom:.5rem!important}.my-lg-3{margin-top:1rem!important;margin-bottom:1rem!important}.my-lg-4{margin-top:1.5rem!important;margin-bottom:1.5rem!important}.my-lg-5{margin-top:3rem!important;margin-bottom:3rem!important}.my-lg-auto{margin-top:auto!important;margin-bottom:auto!important}.mt-lg-0{margin-top:0!important}.mt-lg-1{margin-top:.25rem!important}.mt-lg-2{margin-top:.5rem!important}.mt-lg-3{margin-top:1rem!important}.mt-lg-4{margin-top:1.5rem!important}.mt-lg-5{margin-top:3rem!important}.mt-lg-auto{margin-top:auto!important}.me-lg-0{margin-right:0!important}.me-lg-1{margin-right:.25rem!important}.me-lg-2{margin-right:.5rem!important}.me-lg-3{margin-right:1rem!important}.me-lg-4{margin-right:1.5rem!important}.me-lg-5{margin-right:3rem!important}.me-lg-auto{margin-right:auto!important}.mb-lg-0{margin-bottom:0!important}.mb-lg-1{margin-bottom:.25rem!important}.mb-lg-2{margin-bottom:.5rem!important}.mb-lg-3{margin-bottom:1rem!important}.mb-lg-4{margin-bottom:1.5rem!important}.mb-lg-5{margin-bottom:3rem!important}.mb-lg-auto{margin-bottom:auto!important}.ms-lg-0{margin-left:0!important}.ms-lg-1{margin-left:.25rem!important}.ms-lg-2{margin-left:.5rem!important}.ms-lg-3{margin-left:1rem!important}.ms-lg-4{margin-left:1.5rem!important}.ms-lg-5{margin-left:3rem!important}.ms-lg-auto{margin-left:auto!important}.p-lg-0{padding:0!important}.p-lg-1{padding:.25rem!important}.p-lg-2{padding:.5rem!important}.p-lg-3{padding:1rem!important}.p-lg-4{padding:1.5rem!important}.p-lg-5{padding:3rem!important}.px-lg-0{padding-right:0!important;padding-left:0!important}.px-lg-1{padding-right:.25rem!important;padding-left:.25rem!important}.px-lg-2{padding-right:.5rem!important;padding-left:.5rem!important}.px-lg-3{padding-right:1rem!important;padding-left:1rem!important}.px-lg-4{padding-right:1.5rem!important;padding-left:1.5rem!important}.px-lg-5{padding-right:3rem!important;padding-left:3rem!important}.py-lg-0{padding-top:0!important;padding-bottom:0!important}.py-lg-1{padding-top:.25rem!important;padding-bottom:.25rem!important}.py-lg-2{padding-top:.5rem!important;padding-bottom:.5rem!important}.py-lg-3{padding-top:1rem!important;padding-bottom:1rem!important}.py-lg-4{padding-top:1.5rem!important;padding-bottom:1.5rem!important}.py-lg-5{padding-top:3rem!important;padding-bottom:3rem!important}.pt-lg-0{padding-top:0!important}.pt-lg-1{padding-top:.25rem!important}.pt-lg-2{padding-top:.5rem!important}.pt-lg-3{padding-top:1rem!important}.pt-lg-4{padding-top:1.5rem!important}.pt-lg-5{padding-top:3rem!important}.pe-lg-0{padding-right:0!important}.pe-lg-1{padding-right:.25rem!important}.pe-lg-2{padding-right:.5rem!important}.pe-lg-3{padding-right:1rem!important}.pe-lg-4{padding-right:1.5rem!important}.pe-lg-5{padding-right:3rem!important}.pb-lg-0{padding-bottom:0!important}.pb-lg-1{padding-bottom:.25rem!important}.pb-lg-2{padding-bottom:.5rem!important}.pb-lg-3{padding-bottom:1rem!important}.pb-lg-4{padding-bottom:1.5rem!important}.pb-lg-5{padding-bottom:3rem!important}.ps-lg-0{padding-left:0!important}.ps-lg-1{padding-left:.25rem!important}.ps-lg-2{padding-left:.5rem!important}.ps-lg-3{padding-left:1rem!important}.ps-lg-4{padding-left:1.5rem!important}.ps-lg-5{padding-left:3rem!important}.gap-lg-0{gap:0!important}.gap-lg-1{gap:.25rem!important}.gap-lg-2{gap:.5rem!important}.gap-lg-3{gap:1rem!important}.gap-lg-4{gap:1.5rem!important}.gap-lg-5{gap:3rem!important}.row-gap-lg-0{row-gap:0!important}.row-gap-lg-1{row-gap:.25rem!important}.row-gap-lg-2{row-gap:.5rem!important}.row-gap-lg-3{row-gap:1rem!important}.row-gap-lg-4{row-gap:1.5rem!important}.row-gap-lg-5{row-gap:3rem!important}.column-gap-lg-0{-moz-column-gap:0!important;column-gap:0!important}.column-gap-lg-1{-moz-column-gap:0.25rem!important;column-gap:.25rem!important}.column-gap-lg-2{-moz-column-gap:0.5rem!important;column-gap:.5rem!important}.column-gap-lg-3{-moz-column-gap:1rem!important;column-gap:1rem!important}.column-gap-lg-4{-moz-column-gap:1.5rem!important;column-gap:1.5rem!important}.column-gap-lg-5{-moz-column-gap:3rem!important;column-gap:3rem!important}.text-lg-start{text-align:left!important}.text-lg-end{text-align:right!important}.text-lg-center{text-align:center!important}}@media (min-width:1200px){.float-xl-start{float:left!important}.float-xl-end{float:right!important}.float-xl-none{float:none!important}.object-fit-xl-contain{-o-object-fit:contain!important;object-fit:contain!important}.object-fit-xl-cover{-o-object-fit:cover!important;object-fit:cover!important}.object-fit-xl-fill{-o-object-fit:fill!important;object-fit:fill!important}.object-fit-xl-scale{-o-object-fit:scale-down!important;object-fit:scale-down!important}.object-fit-xl-none{-o-object-fit:none!important;object-fit:none!important}.d-xl-inline{display:inline!important}.d-xl-inline-block{display:inline-block!important}.d-xl-block{display:block!important}.d-xl-grid{display:grid!important}.d-xl-inline-grid{display:inline-grid!important}.d-xl-table{display:table!important}.d-xl-table-row{display:table-row!important}.d-xl-table-cell{display:table-cell!important}.d-xl-flex{display:flex!important}.d-xl-inline-flex{display:inline-flex!important}.d-xl-none{display:none!important}.flex-xl-fill{flex:1 1 auto!important}.flex-xl-row{flex-direction:row!important}.flex-xl-column{flex-direction:column!important}.flex-xl-row-reverse{flex-direction:row-reverse!important}.flex-xl-column-reverse{flex-direction:column-reverse!important}.flex-xl-grow-0{flex-grow:0!important}.flex-xl-grow-1{flex-grow:1!important}.flex-xl-shrink-0{flex-shrink:0!important}.flex-xl-shrink-1{flex-shrink:1!important}.flex-xl-wrap{flex-wrap:wrap!important}.flex-xl-nowrap{flex-wrap:nowrap!important}.flex-xl-wrap-reverse{flex-wrap:wrap-reverse!important}.justify-content-xl-start{justify-content:flex-start!important}.justify-content-xl-end{justify-content:flex-end!important}.justify-content-xl-center{justify-content:center!important}.justify-content-xl-between{justify-content:space-between!important}.justify-content-xl-around{justify-content:space-around!important}.justify-content-xl-evenly{justify-content:space-evenly!important}.align-items-xl-start{align-items:flex-start!important}.align-items-xl-end{align-items:flex-end!important}.align-items-xl-center{align-items:center!important}.align-items-xl-baseline{align-items:baseline!important}.align-items-xl-stretch{align-items:stretch!important}.align-content-xl-start{align-content:flex-start!important}.align-content-xl-end{align-content:flex-end!important}.align-content-xl-center{align-content:center!important}.align-content-xl-between{align-content:space-between!important}.align-content-xl-around{align-content:space-around!important}.align-content-xl-stretch{align-content:stretch!important}.align-self-xl-auto{align-self:auto!important}.align-self-xl-start{align-self:flex-start!important}.align-self-xl-end{align-self:flex-end!important}.align-self-xl-center{align-self:center!important}.align-self-xl-baseline{align-self:baseline!important}.align-self-xl-stretch{align-self:stretch!important}.order-xl-first{order:-1!important}.order-xl-0{order:0!important}.order-xl-1{order:1!important}.order-xl-2{order:2!important}.order-xl-3{order:3!important}.order-xl-4{order:4!important}.order-xl-5{order:5!important}.order-xl-last{order:6!important}.m-xl-0{margin:0!important}.m-xl-1{margin:.25rem!important}.m-xl-2{margin:.5rem!important}.m-xl-3{margin:1rem!important}.m-xl-4{margin:1.5rem!important}.m-xl-5{margin:3rem!important}.m-xl-auto{margin:auto!important}.mx-xl-0{margin-right:0!important;margin-left:0!important}.mx-xl-1{margin-right:.25rem!important;margin-left:.25rem!important}.mx-xl-2{margin-right:.5rem!important;margin-left:.5rem!important}.mx-xl-3{margin-right:1rem!important;margin-left:1rem!important}.mx-xl-4{margin-right:1.5rem!important;margin-left:1.5rem!important}.mx-xl-5{margin-right:3rem!important;margin-left:3rem!important}.mx-xl-auto{margin-right:auto!important;margin-left:auto!important}.my-xl-0{margin-top:0!important;margin-bottom:0!important}.my-xl-1{margin-top:.25rem!important;margin-bottom:.25rem!important}.my-xl-2{margin-top:.5rem!important;margin-bottom:.5rem!important}.my-xl-3{margin-top:1rem!important;margin-bottom:1rem!important}.my-xl-4{margin-top:1.5rem!important;margin-bottom:1.5rem!important}.my-xl-5{margin-top:3rem!important;margin-bottom:3rem!important}.my-xl-auto{margin-top:auto!important;margin-bottom:auto!important}.mt-xl-0{margin-top:0!important}.mt-xl-1{margin-top:.25rem!important}.mt-xl-2{margin-top:.5rem!important}.mt-xl-3{margin-top:1rem!important}.mt-xl-4{margin-top:1.5rem!important}.mt-xl-5{margin-top:3rem!important}.mt-xl-auto{margin-top:auto!important}.me-xl-0{margin-right:0!important}.me-xl-1{margin-right:.25rem!important}.me-xl-2{margin-right:.5rem!important}.me-xl-3{margin-right:1rem!important}.me-xl-4{margin-right:1.5rem!important}.me-xl-5{margin-right:3rem!important}.me-xl-auto{margin-right:auto!important}.mb-xl-0{margin-bottom:0!important}.mb-xl-1{margin-bottom:.25rem!important}.mb-xl-2{margin-bottom:.5rem!important}.mb-xl-3{margin-bottom:1rem!important}.mb-xl-4{margin-bottom:1.5rem!important}.mb-xl-5{margin-bottom:3rem!important}.mb-xl-auto{margin-bottom:auto!important}.ms-xl-0{margin-left:0!important}.ms-xl-1{margin-left:.25rem!important}.ms-xl-2{margin-left:.5rem!important}.ms-xl-3{margin-left:1rem!important}.ms-xl-4{margin-left:1.5rem!important}.ms-xl-5{margin-left:3rem!important}.ms-xl-auto{margin-left:auto!important}.p-xl-0{padding:0!important}.p-xl-1{padding:.25rem!important}.p-xl-2{padding:.5rem!important}.p-xl-3{padding:1rem!important}.p-xl-4{padding:1.5rem!important}.p-xl-5{padding:3rem!important}.px-xl-0{padding-right:0!important;padding-left:0!important}.px-xl-1{padding-right:.25rem!important;padding-left:.25rem!important}.px-xl-2{padding-right:.5rem!important;padding-left:.5rem!important}.px-xl-3{padding-right:1rem!important;padding-left:1rem!important}.px-xl-4{padding-right:1.5rem!important;padding-left:1.5rem!important}.px-xl-5{padding-right:3rem!important;padding-left:3rem!important}.py-xl-0{padding-top:0!important;padding-bottom:0!important}.py-xl-1{padding-top:.25rem!important;padding-bottom:.25rem!important}.py-xl-2{padding-top:.5rem!important;padding-bottom:.5rem!important}.py-xl-3{padding-top:1rem!important;padding-bottom:1rem!important}.py-xl-4{padding-top:1.5rem!important;padding-bottom:1.5rem!important}.py-xl-5{padding-top:3rem!important;padding-bottom:3rem!important}.pt-xl-0{padding-top:0!important}.pt-xl-1{padding-top:.25rem!important}.pt-xl-2{padding-top:.5rem!important}.pt-xl-3{padding-top:1rem!important}.pt-xl-4{padding-top:1.5rem!important}.pt-xl-5{padding-top:3rem!important}.pe-xl-0{padding-right:0!important}.pe-xl-1{padding-right:.25rem!important}.pe-xl-2{padding-right:.5rem!important}.pe-xl-3{padding-right:1rem!important}.pe-xl-4{padding-right:1.5rem!important}.pe-xl-5{padding-right:3rem!important}.pb-xl-0{padding-bottom:0!important}.pb-xl-1{padding-bottom:.25rem!important}.pb-xl-2{padding-bottom:.5rem!important}.pb-xl-3{padding-bottom:1rem!important}.pb-xl-4{padding-bottom:1.5rem!important}.pb-xl-5{padding-bottom:3rem!important}.ps-xl-0{padding-left:0!important}.ps-xl-1{padding-left:.25rem!important}.ps-xl-2{padding-left:.5rem!important}.ps-xl-3{padding-left:1rem!important}.ps-xl-4{padding-left:1.5rem!important}.ps-xl-5{padding-left:3rem!important}.gap-xl-0{gap:0!important}.gap-xl-1{gap:.25rem!important}.gap-xl-2{gap:.5rem!important}.gap-xl-3{gap:1rem!important}.gap-xl-4{gap:1.5rem!important}.gap-xl-5{gap:3rem!important}.row-gap-xl-0{row-gap:0!important}.row-gap-xl-1{row-gap:.25rem!important}.row-gap-xl-2{row-gap:.5rem!important}.row-gap-xl-3{row-gap:1rem!important}.row-gap-xl-4{row-gap:1.5rem!important}.row-gap-xl-5{row-gap:3rem!important}.column-gap-xl-0{-moz-column-gap:0!important;column-gap:0!important}.column-gap-xl-1{-moz-column-gap:0.25rem!important;column-gap:.25rem!important}.column-gap-xl-2{-moz-column-gap:0.5rem!important;column-gap:.5rem!important}.column-gap-xl-3{-moz-column-gap:1rem!important;column-gap:1rem!important}.column-gap-xl-4{-moz-column-gap:1.5rem!important;column-gap:1.5rem!important}.column-gap-xl-5{-moz-column-gap:3rem!important;column-gap:3rem!important}.text-xl-start{text-align:left!important}.text-xl-end{text-align:right!important}.text-xl-center{text-align:center!important}}@media (min-width:1400px){.float-xxl-start{float:left!important}.float-xxl-end{float:right!important}.float-xxl-none{float:none!important}.object-fit-xxl-contain{-o-object-fit:contain!important;object-fit:contain!important}.object-fit-xxl-cover{-o-object-fit:cover!important;object-fit:cover!important}.object-fit-xxl-fill{-o-object-fit:fill!important;object-fit:fill!important}.object-fit-xxl-scale{-o-object-fit:scale-down!important;object-fit:scale-down!important}.object-fit-xxl-none{-o-object-fit:none!important;object-fit:none!important}.d-xxl-inline{display:inline!important}.d-xxl-inline-block{display:inline-block!important}.d-xxl-block{display:block!important}.d-xxl-grid{display:grid!important}.d-xxl-inline-grid{display:inline-grid!important}.d-xxl-table{display:table!important}.d-xxl-table-row{display:table-row!important}.d-xxl-table-cell{display:table-cell!important}.d-xxl-flex{display:flex!important}.d-xxl-inline-flex{display:inline-flex!important}.d-xxl-none{display:none!important}.flex-xxl-fill{flex:1 1 auto!important}.flex-xxl-row{flex-direction:row!important}.flex-xxl-column{flex-direction:column!important}.flex-xxl-row-reverse{flex-direction:row-reverse!important}.flex-xxl-column-reverse{flex-direction:column-reverse!important}.flex-xxl-grow-0{flex-grow:0!important}.flex-xxl-grow-1{flex-grow:1!important}.flex-xxl-shrink-0{flex-shrink:0!important}.flex-xxl-shrink-1{flex-shrink:1!important}.flex-xxl-wrap{flex-wrap:wrap!important}.flex-xxl-nowrap{flex-wrap:nowrap!important}.flex-xxl-wrap-reverse{flex-wrap:wrap-reverse!important}.justify-content-xxl-start{justify-content:flex-start!important}.justify-content-xxl-end{justify-content:flex-end!important}.justify-content-xxl-center{justify-content:center!important}.justify-content-xxl-between{justify-content:space-between!important}.justify-content-xxl-around{justify-content:space-around!important}.justify-content-xxl-evenly{justify-content:space-evenly!important}.align-items-xxl-start{align-items:flex-start!important}.align-items-xxl-end{align-items:flex-end!important}.align-items-xxl-center{align-items:center!important}.align-items-xxl-baseline{align-items:baseline!important}.align-items-xxl-stretch{align-items:stretch!important}.align-content-xxl-start{align-content:flex-start!important}.align-content-xxl-end{align-content:flex-end!important}.align-content-xxl-center{align-content:center!important}.align-content-xxl-between{align-content:space-between!important}.align-content-xxl-around{align-content:space-around!important}.align-content-xxl-stretch{align-content:stretch!important}.align-self-xxl-auto{align-self:auto!important}.align-self-xxl-start{align-self:flex-start!important}.align-self-xxl-end{align-self:flex-end!important}.align-self-xxl-center{align-self:center!important}.align-self-xxl-baseline{align-self:baseline!important}.align-self-xxl-stretch{align-self:stretch!important}.order-xxl-first{order:-1!important}.order-xxl-0{order:0!important}.order-xxl-1{order:1!important}.order-xxl-2{order:2!important}.order-xxl-3{order:3!important}.order-xxl-4{order:4!important}.order-xxl-5{order:5!important}.order-xxl-last{order:6!important}.m-xxl-0{margin:0!important}.m-xxl-1{margin:.25rem!important}.m-xxl-2{margin:.5rem!important}.m-xxl-3{margin:1rem!important}.m-xxl-4{margin:1.5rem!important}.m-xxl-5{margin:3rem!important}.m-xxl-auto{margin:auto!important}.mx-xxl-0{margin-right:0!important;margin-left:0!important}.mx-xxl-1{margin-right:.25rem!important;margin-left:.25rem!important}.mx-xxl-2{margin-right:.5rem!important;margin-left:.5rem!important}.mx-xxl-3{margin-right:1rem!important;margin-left:1rem!important}.mx-xxl-4{margin-right:1.5rem!important;margin-left:1.5rem!important}.mx-xxl-5{margin-right:3rem!important;margin-left:3rem!important}.mx-xxl-auto{margin-right:auto!important;margin-left:auto!important}.my-xxl-0{margin-top:0!important;margin-bottom:0!important}.my-xxl-1{margin-top:.25rem!important;margin-bottom:.25rem!important}.my-xxl-2{margin-top:.5rem!important;margin-bottom:.5rem!important}.my-xxl-3{margin-top:1rem!important;margin-bottom:1rem!important}.my-xxl-4{margin-top:1.5rem!important;margin-bottom:1.5rem!important}.my-xxl-5{margin-top:3rem!important;margin-bottom:3rem!important}.my-xxl-auto{margin-top:auto!important;margin-bottom:auto!important}.mt-xxl-0{margin-top:0!important}.mt-xxl-1{margin-top:.25rem!important}.mt-xxl-2{margin-top:.5rem!important}.mt-xxl-3{margin-top:1rem!important}.mt-xxl-4{margin-top:1.5rem!important}.mt-xxl-5{margin-top:3rem!important}.mt-xxl-auto{margin-top:auto!important}.me-xxl-0{margin-right:0!important}.me-xxl-1{margin-right:.25rem!important}.me-xxl-2{margin-right:.5rem!important}.me-xxl-3{margin-right:1rem!important}.me-xxl-4{margin-right:1.5rem!important}.me-xxl-5{margin-right:3rem!important}.me-xxl-auto{margin-right:auto!important}.mb-xxl-0{margin-bottom:0!important}.mb-xxl-1{margin-bottom:.25rem!important}.mb-xxl-2{margin-bottom:.5rem!important}.mb-xxl-3{margin-bottom:1rem!important}.mb-xxl-4{margin-bottom:1.5rem!important}.mb-xxl-5{margin-bottom:3rem!important}.mb-xxl-auto{margin-bottom:auto!important}.ms-xxl-0{margin-left:0!important}.ms-xxl-1{margin-left:.25rem!important}.ms-xxl-2{margin-left:.5rem!important}.ms-xxl-3{margin-left:1rem!important}.ms-xxl-4{margin-left:1.5rem!important}.ms-xxl-5{margin-left:3rem!important}.ms-xxl-auto{margin-left:auto!important}.p-xxl-0{padding:0!important}.p-xxl-1{padding:.25rem!important}.p-xxl-2{padding:.5rem!important}.p-xxl-3{padding:1rem!important}.p-xxl-4{padding:1.5rem!important}.p-xxl-5{padding:3rem!important}.px-xxl-0{padding-right:0!important;padding-left:0!important}.px-xxl-1{padding-right:.25rem!important;padding-left:.25rem!important}.px-xxl-2{padding-right:.5rem!important;padding-left:.5rem!important}.px-xxl-3{padding-right:1rem!important;padding-left:1rem!important}.px-xxl-4{padding-right:1.5rem!important;padding-left:1.5rem!important}.px-xxl-5{padding-right:3rem!important;padding-left:3rem!important}.py-xxl-0{padding-top:0!important;padding-bottom:0!important}.py-xxl-1{padding-top:.25rem!important;padding-bottom:.25rem!important}.py-xxl-2{padding-top:.5rem!important;padding-bottom:.5rem!important}.py-xxl-3{padding-top:1rem!important;padding-bottom:1rem!important}.py-xxl-4{padding-top:1.5rem!important;padding-bottom:1.5rem!important}.py-xxl-5{padding-top:3rem!important;padding-bottom:3rem!important}.pt-xxl-0{padding-top:0!important}.pt-xxl-1{padding-top:.25rem!important}.pt-xxl-2{padding-top:.5rem!important}.pt-xxl-3{padding-top:1rem!important}.pt-xxl-4{padding-top:1.5rem!important}.pt-xxl-5{padding-top:3rem!important}.pe-xxl-0{padding-right:0!important}.pe-xxl-1{padding-right:.25rem!important}.pe-xxl-2{padding-right:.5rem!important}.pe-xxl-3{padding-right:1rem!important}.pe-xxl-4{padding-right:1.5rem!important}.pe-xxl-5{padding-right:3rem!important}.pb-xxl-0{padding-bottom:0!important}.pb-xxl-1{padding-bottom:.25rem!important}.pb-xxl-2{padding-bottom:.5rem!important}.pb-xxl-3{padding-bottom:1rem!important}.pb-xxl-4{padding-bottom:1.5rem!important}.pb-xxl-5{padding-bottom:3rem!important}.ps-xxl-0{padding-left:0!important}.ps-xxl-1{padding-left:.25rem!important}.ps-xxl-2{padding-left:.5rem!important}.ps-xxl-3{padding-left:1rem!important}.ps-xxl-4{padding-left:1.5rem!important}.ps-xxl-5{padding-left:3rem!important}.gap-xxl-0{gap:0!important}.gap-xxl-1{gap:.25rem!important}.gap-xxl-2{gap:.5rem!important}.gap-xxl-3{gap:1rem!important}.gap-xxl-4{gap:1.5rem!important}.gap-xxl-5{gap:3rem!important}.row-gap-xxl-0{row-gap:0!important}.row-gap-xxl-1{row-gap:.25rem!important}.row-gap-xxl-2{row-gap:.5rem!important}.row-gap-xxl-3{row-gap:1rem!important}.row-gap-xxl-4{row-gap:1.5rem!important}.row-gap-xxl-5{row-gap:3rem!important}.column-gap-xxl-0{-moz-column-gap:0!important;column-gap:0!important}.column-gap-xxl-1{-moz-column-gap:0.25rem!important;column-gap:.25rem!important}.column-gap-xxl-2{-moz-column-gap:0.5rem!important;column-gap:.5rem!important}.column-gap-xxl-3{-moz-column-gap:1rem!important;column-gap:1rem!important}.column-gap-xxl-4{-moz-column-gap:1.5rem!important;column-gap:1.5rem!important}.column-gap-xxl-5{-moz-column-gap:3rem!important;column-gap:3rem!important}.text-xxl-start{text-align:left!important}.text-xxl-end{text-align:right!important}.text-xxl-center{text-align:center!important}}@media (min-width:1200px){.fs-1{font-size:2.5rem!important}.fs-2{font-size:2rem!important}.fs-3{font-size:1.75rem!important}.fs-4{font-size:1.5rem!important}}@media print{.d-print-inline{display:inline!important}.d-print-inline-block{display:inline-block!important}.d-print-block{display:block!important}.d-print-grid{display:grid!important}.d-print-inline-grid{display:inline-grid!important}.d-print-table{display:table!important}.d-print-table-row{display:table-row!important}.d-print-table-cell{display:table-cell!important}.d-print-flex{display:flex!important}.d-print-inline-flex{display:inline-flex!important}.d-print-none{display:none!important}} -/*# sourceMappingURL=bootstrap.min.css.map */ \ No newline at end of file diff --git a/backend/coverage-report/_css/custom.css b/backend/coverage-report/_css/custom.css deleted file mode 100644 index e69de29b..00000000 diff --git a/backend/coverage-report/_css/nv.d3.min.css b/backend/coverage-report/_css/nv.d3.min.css deleted file mode 100644 index 7a6f7fe9..00000000 --- a/backend/coverage-report/_css/nv.d3.min.css +++ /dev/null @@ -1 +0,0 @@ -.nvd3 .nv-axis{pointer-events:none;opacity:1}.nvd3 .nv-axis path{fill:none;stroke:#000;stroke-opacity:.75;shape-rendering:crispEdges}.nvd3 .nv-axis path.domain{stroke-opacity:.75}.nvd3 .nv-axis.nv-x path.domain{stroke-opacity:0}.nvd3 .nv-axis line{fill:none;stroke:#e5e5e5;shape-rendering:crispEdges}.nvd3 .nv-axis .zero line,.nvd3 .nv-axis line.zero{stroke-opacity:.75}.nvd3 .nv-axis .nv-axisMaxMin text{font-weight:700}.nvd3 .x .nv-axis .nv-axisMaxMin text,.nvd3 .x2 .nv-axis .nv-axisMaxMin text,.nvd3 .x3 .nv-axis .nv-axisMaxMin text{text-anchor:middle}.nvd3 .nv-axis.nv-disabled{opacity:0}.nvd3 .nv-bars rect{fill-opacity:.75;transition:fill-opacity 250ms linear;-moz-transition:fill-opacity 250ms linear;-webkit-transition:fill-opacity 250ms linear}.nvd3 .nv-bars rect.hover{fill-opacity:1}.nvd3 .nv-bars .hover rect{fill:#add8e6}.nvd3 .nv-bars text{fill:rgba(0,0,0,0)}.nvd3 .nv-bars .hover text{fill:rgba(0,0,0,1)}.nvd3 .nv-multibar .nv-groups rect,.nvd3 .nv-multibarHorizontal .nv-groups rect,.nvd3 .nv-discretebar .nv-groups rect{stroke-opacity:0;transition:fill-opacity 250ms linear;-moz-transition:fill-opacity 250ms linear;-webkit-transition:fill-opacity 250ms linear}.nvd3 .nv-multibar .nv-groups rect:hover,.nvd3 .nv-multibarHorizontal .nv-groups rect:hover,.nvd3 .nv-candlestickBar .nv-ticks rect:hover,.nvd3 .nv-discretebar .nv-groups rect:hover{fill-opacity:1}.nvd3 .nv-discretebar .nv-groups text,.nvd3 .nv-multibarHorizontal .nv-groups text{font-weight:700;fill:rgba(0,0,0,1);stroke:rgba(0,0,0,0)}.nvd3 .nv-boxplot circle{fill-opacity:.5}.nvd3 .nv-boxplot circle:hover{fill-opacity:1}.nvd3 .nv-boxplot rect:hover{fill-opacity:1}.nvd3 line.nv-boxplot-median{stroke:#000}.nv-boxplot-tick:hover{stroke-width:2.5px}.nvd3.nv-bullet{font:10px sans-serif}.nvd3.nv-bullet .nv-measure{fill-opacity:.8}.nvd3.nv-bullet .nv-measure:hover{fill-opacity:1}.nvd3.nv-bullet .nv-marker{stroke:#000;stroke-width:2px}.nvd3.nv-bullet .nv-markerTriangle{stroke:#000;fill:#fff;stroke-width:1.5px}.nvd3.nv-bullet .nv-tick line{stroke:#666;stroke-width:.5px}.nvd3.nv-bullet .nv-range.nv-s0{fill:#eee}.nvd3.nv-bullet .nv-range.nv-s1{fill:#ddd}.nvd3.nv-bullet .nv-range.nv-s2{fill:#ccc}.nvd3.nv-bullet .nv-title{font-size:14px;font-weight:700}.nvd3.nv-bullet .nv-subtitle{fill:#999}.nvd3.nv-bullet .nv-range{fill:#bababa;fill-opacity:.4}.nvd3.nv-bullet .nv-range:hover{fill-opacity:.7}.nvd3.nv-candlestickBar .nv-ticks .nv-tick{stroke-width:1px}.nvd3.nv-candlestickBar .nv-ticks .nv-tick.hover{stroke-width:2px}.nvd3.nv-candlestickBar .nv-ticks .nv-tick.positive rect{stroke:#2ca02c;fill:#2ca02c}.nvd3.nv-candlestickBar .nv-ticks .nv-tick.negative rect{stroke:#d62728;fill:#d62728}.with-transitions .nv-candlestickBar .nv-ticks .nv-tick{transition:stroke-width 250ms linear,stroke-opacity 250ms linear;-moz-transition:stroke-width 250ms linear,stroke-opacity 250ms linear;-webkit-transition:stroke-width 250ms linear,stroke-opacity 250ms linear}.nvd3.nv-candlestickBar .nv-ticks line{stroke:#333}.nvd3 .nv-legend .nv-disabled rect{}.nvd3 .nv-check-box .nv-box{fill-opacity:0;stroke-width:2}.nvd3 .nv-check-box .nv-check{fill-opacity:0;stroke-width:4}.nvd3 .nv-series.nv-disabled .nv-check-box .nv-check{fill-opacity:0;stroke-opacity:0}.nvd3 .nv-controlsWrap .nv-legend .nv-check-box .nv-check{opacity:0}.nvd3.nv-linePlusBar .nv-bar rect{fill-opacity:.75}.nvd3.nv-linePlusBar .nv-bar rect:hover{fill-opacity:1}.nvd3 .nv-groups path.nv-line{fill:none}.nvd3 .nv-groups path.nv-area{stroke:none}.nvd3.nv-line .nvd3.nv-scatter .nv-groups .nv-point{fill-opacity:0;stroke-opacity:0}.nvd3.nv-scatter.nv-single-point .nv-groups .nv-point{fill-opacity:.5!important;stroke-opacity:.5!important}.with-transitions .nvd3 .nv-groups .nv-point{transition:stroke-width 250ms linear,stroke-opacity 250ms linear;-moz-transition:stroke-width 250ms linear,stroke-opacity 250ms linear;-webkit-transition:stroke-width 250ms linear,stroke-opacity 250ms linear}.nvd3.nv-scatter .nv-groups .nv-point.hover,.nvd3 .nv-groups .nv-point.hover{stroke-width:7px;fill-opacity:.95!important;stroke-opacity:.95!important}.nvd3 .nv-point-paths path{stroke:#aaa;stroke-opacity:0;fill:#eee;fill-opacity:0}.nvd3 .nv-indexLine{cursor:ew-resize}svg.nvd3-svg{-webkit-touch-callout:none;-webkit-user-select:none;-khtml-user-select:none;-ms-user-select:none;-moz-user-select:none;user-select:none;display:block;width:100%;height:100%}.nvtooltip.with-3d-shadow,.with-3d-shadow .nvtooltip{-moz-box-shadow:0 5px 10px rgba(0,0,0,.2);-webkit-box-shadow:0 5px 10px rgba(0,0,0,.2);box-shadow:0 5px 10px rgba(0,0,0,.2);-webkit-border-radius:5px;-moz-border-radius:5px;border-radius:5px}.nvd3 text{font:400 12px Arial}.nvd3 .title{font:700 14px Arial}.nvd3 .nv-background{fill:#fff;fill-opacity:0}.nvd3.nv-noData{font-size:18px;font-weight:700}.nv-brush .extent{fill-opacity:.125;shape-rendering:crispEdges}.nv-brush .resize path{fill:#eee;stroke:#666}.nvd3 .nv-legend .nv-series{cursor:pointer}.nvd3 .nv-legend .nv-disabled circle{fill-opacity:0}.nvd3 .nv-brush .extent{fill-opacity:0!important}.nvd3 .nv-brushBackground rect{stroke:#000;stroke-width:.4;fill:#fff;fill-opacity:.7}.nvd3.nv-ohlcBar .nv-ticks .nv-tick{stroke-width:1px}.nvd3.nv-ohlcBar .nv-ticks .nv-tick.hover{stroke-width:2px}.nvd3.nv-ohlcBar .nv-ticks .nv-tick.positive{stroke:#2ca02c}.nvd3.nv-ohlcBar .nv-ticks .nv-tick.negative{stroke:#d62728}.nvd3 .background path{fill:none;stroke:#EEE;stroke-opacity:.4;shape-rendering:crispEdges}.nvd3 .foreground path{fill:none;stroke-opacity:.7}.nvd3 .nv-parallelCoordinates-brush .extent{fill:#fff;fill-opacity:.6;stroke:gray;shape-rendering:crispEdges}.nvd3 .nv-parallelCoordinates .hover{fill-opacity:1;stroke-width:3px}.nvd3 .missingValuesline line{fill:none;stroke:#000;stroke-width:1;stroke-opacity:1;stroke-dasharray:5,5}.nvd3.nv-pie path{stroke-opacity:0;transition:fill-opacity 250ms linear,stroke-width 250ms linear,stroke-opacity 250ms linear;-moz-transition:fill-opacity 250ms linear,stroke-width 250ms linear,stroke-opacity 250ms linear;-webkit-transition:fill-opacity 250ms linear,stroke-width 250ms linear,stroke-opacity 250ms linear}.nvd3.nv-pie .nv-pie-title{font-size:24px;fill:rgba(19,196,249,.59)}.nvd3.nv-pie .nv-slice text{stroke:#000;stroke-width:0}.nvd3.nv-pie path{stroke:#fff;stroke-width:1px;stroke-opacity:1}.nvd3.nv-pie .hover path{fill-opacity:.7}.nvd3.nv-pie .nv-label{pointer-events:none}.nvd3.nv-pie .nv-label rect{fill-opacity:0;stroke-opacity:0}.nvd3 .nv-groups .nv-point.hover{stroke-width:20px;stroke-opacity:.5}.nvd3 .nv-scatter .nv-point.hover{fill-opacity:1}.nv-noninteractive{pointer-events:none}.nv-distx,.nv-disty{pointer-events:none}.nvd3.nv-sparkline path{fill:none}.nvd3.nv-sparklineplus g.nv-hoverValue{pointer-events:none}.nvd3.nv-sparklineplus .nv-hoverValue line{stroke:#333;stroke-width:1.5px}.nvd3.nv-sparklineplus,.nvd3.nv-sparklineplus g{pointer-events:all}.nvd3 .nv-hoverArea{fill-opacity:0;stroke-opacity:0}.nvd3.nv-sparklineplus .nv-xValue,.nvd3.nv-sparklineplus .nv-yValue{stroke-width:0;font-size:.9em;font-weight:400}.nvd3.nv-sparklineplus .nv-yValue{stroke:#f66}.nvd3.nv-sparklineplus .nv-maxValue{stroke:#2ca02c;fill:#2ca02c}.nvd3.nv-sparklineplus .nv-minValue{stroke:#d62728;fill:#d62728}.nvd3.nv-sparklineplus .nv-currentValue{font-weight:700;font-size:1.1em}.nvd3.nv-stackedarea path.nv-area{fill-opacity:.7;stroke-opacity:0;transition:fill-opacity 250ms linear,stroke-opacity 250ms linear;-moz-transition:fill-opacity 250ms linear,stroke-opacity 250ms linear;-webkit-transition:fill-opacity 250ms linear,stroke-opacity 250ms linear}.nvd3.nv-stackedarea path.nv-area.hover{fill-opacity:.9}.nvd3.nv-stackedarea .nv-groups .nv-point{stroke-opacity:0;fill-opacity:0}.nvtooltip{position:absolute;background-color:rgba(255,255,255,1);color:rgba(0,0,0,1);padding:1px;border:1px solid rgba(0,0,0,.2);z-index:10000;display:block;font-family:Arial;font-size:13px;text-align:left;pointer-events:none;white-space:nowrap;-webkit-touch-callout:none;-webkit-user-select:none;-khtml-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.nvtooltip{background:rgba(255,255,255,.8);border:1px solid rgba(0,0,0,.5);border-radius:4px}.nvtooltip.with-transitions,.with-transitions .nvtooltip{transition:opacity 50ms linear;-moz-transition:opacity 50ms linear;-webkit-transition:opacity 50ms linear;transition-delay:200ms;-moz-transition-delay:200ms;-webkit-transition-delay:200ms}.nvtooltip.x-nvtooltip,.nvtooltip.y-nvtooltip{padding:8px}.nvtooltip h3{margin:0;padding:4px 14px;line-height:18px;font-weight:400;background-color:rgba(247,247,247,.75);color:rgba(0,0,0,1);text-align:center;border-bottom:1px solid #ebebeb;-webkit-border-radius:5px 5px 0 0;-moz-border-radius:5px 5px 0 0;border-radius:5px 5px 0 0}.nvtooltip p{margin:0;padding:5px 14px;text-align:center}.nvtooltip span{display:inline-block;margin:2px 0}.nvtooltip table{margin:6px;border-spacing:0}.nvtooltip table td{padding:2px 9px 2px 0;vertical-align:middle}.nvtooltip table td.key{font-weight:400}.nvtooltip table td.value{text-align:right;font-weight:700}.nvtooltip table tr.highlight td{padding:1px 9px 1px 0;border-bottom-style:solid;border-bottom-width:1px;border-top-style:solid;border-top-width:1px}.nvtooltip table td.legend-color-guide div{width:8px;height:8px;vertical-align:middle}.nvtooltip table td.legend-color-guide div{width:12px;height:12px;border:1px solid #999}.nvtooltip .footer{padding:3px;text-align:center}.nvtooltip-pending-removal{pointer-events:none;display:none}.nvd3 .nv-interactiveGuideLine{pointer-events:none}.nvd3 line.nv-guideline{stroke:#ccc} \ No newline at end of file diff --git a/backend/coverage-report/_css/octicons.css b/backend/coverage-report/_css/octicons.css deleted file mode 100644 index 31d97867..00000000 --- a/backend/coverage-report/_css/octicons.css +++ /dev/null @@ -1,5 +0,0 @@ -.octicon { - display: inline-block; - vertical-align: text-top; - fill: currentColor; -} diff --git a/backend/coverage-report/_css/style.css b/backend/coverage-report/_css/style.css deleted file mode 100644 index b007558e..00000000 --- a/backend/coverage-report/_css/style.css +++ /dev/null @@ -1,201 +0,0 @@ -:root { - --phpunit-breadcrumbs: var(--bs-gray-200); - --phpunit-success-bar: #28a745; - --phpunit-success-high: #99cb84; - --phpunit-success-medium: #c3e3b5; - --phpunit-success-low: #dff0d8; - --phpunit-warning: #fcf8e3; - --phpunit-warning-bar: #ffc107; - --phpunit-danger: #f2dede; - --phpunit-danger-bar: #dc3545; -} - -body { - font-family: sans-serif; - font-size: 1em; - font-kerning: normal; - text-rendering: optimizeLegibility; - padding-top: 10px; -} - -nav .breadcrumb { - border-radius: var(--bs-border-radius); - background-color: var(--phpunit-breadcrumbs); - padding: .75rem 1rem; -} - -.popover { - max-width: none; -} - -.popover-body { - max-height: 90vh; - overflow-y: auto; -} - -.octicon { - margin-right:.25em; - vertical-align: baseline; - width: 0.75em; -} - -.table-bordered>thead>tr>td { - border-bottom-width: 1px; -} - -.table tbody>tr>td, .table thead>tr>td { - padding-top: 3px; - padding-bottom: 3px; -} - -.table-condensed tbody>tr>td { - padding-top: 0; - padding-bottom: 0; -} - -.table .progress { - margin-bottom: inherit; -} - -.table-borderless th, .table-borderless td { - border: 0 !important; -} - -.table tbody tr.covered-by-large-tests, .table tbody tr.covered-by-large-tests td, li.covered-by-large-tests, tr.success, tr.success td, td.success, li.success, span.success { - background-color: var(--phpunit-success-low); -} - -.table tbody tr.covered-by-medium-tests, .table tbody tr.covered-by-medium-tests td, li.covered-by-medium-tests { - background-color: var(--phpunit-success-medium); -} - -.table tbody tr.covered-by-small-tests, .table tbody tr.covered-by-small-tests td, li.covered-by-small-tests { - background-color: var(--phpunit-success-high); -} - -.table tbody tr.warning, .table tbody tr.warning td, .table tbody td.warning, li.warning, span.warning { - background-color: var(--phpunit-warning); -} - -.table tbody tr.danger, .table tbody tr.danger td, .table tbody td.danger, li.danger, span.danger { - background-color: var(--phpunit-danger); -} - -.table tbody td.info { - background-color: rgb(from var(--bs-info) r g b / 0.25); -} - -td.big { - vertical-align: middle; - width: 117px; -} - -td.small { -} - -td.codeLine { - font-family: "Source Code Pro", var(--bs-font-monospace); - white-space: pre-wrap; -} - -td span.comment { - color: var(--bs-secondary-color); -} - -td span.default { - color: var(--bs-body-color); -} - -td span.html { - color: var(--bs-secondary-color); -} - -td span.keyword { - color: var(--bs-body-color); - font-weight: bold; -} - -pre span.string { - color: var(--bs-body-color); -} - -span.success, span.warning, span.danger { - margin-right: 2px; - padding-left: 10px; - padding-right: 10px; - text-align: center; -} - -#toplink { - position: fixed; - left: 5px; - bottom: 5px; - outline: 0; -} - -svg text { - font-family: var(--bs-font-sans-serif); - font-size: 11px; - color: var(--bs-gray); - fill: var(--bs-gray); -} - -.scrollbox { - height:245px; - overflow-x:scroll; - overflow-y:scroll; -} - -table + .structure-heading { - border-top: 1px solid var(--bs-gray-200); - padding-top: 0.5em; -} - -table#code td:first-of-type { - padding-left: .75em; - padding-right: .75em; -} - -table#code td:first-of-type a { - text-decoration: none; -} - -.legend { - font-weight: bold; - margin-right: 2px; - padding-left: 10px; - padding-right: 10px; - text-align: center; -} - -.covered-by-small-tests { - background-color: var(--phpunit-success-high); -} - -.covered-by-medium-tests { - background-color: var(--phpunit-success-medium); -} - -.covered-by-large-tests { - background-color: var(--phpunit-success-low); -} - -.not-covered { - background-color: var(--phpunit-danger); -} - -.not-coverable { - background-color: var(--phpunit-warning); -} - -.progress-bar.bg-success { - background-color: var(--phpunit-success-bar) !important; -} - -.progress-bar.bg-warning { - background-color: var(--phpunit-warning-bar) !important; -} - -.progress-bar.bg-danger { - background-color: var(--phpunit-danger-bar) !important; -} \ No newline at end of file diff --git a/backend/coverage-report/_icons/file-code.svg b/backend/coverage-report/_icons/file-code.svg deleted file mode 100644 index 5b4b1995..00000000 --- a/backend/coverage-report/_icons/file-code.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/backend/coverage-report/_icons/file-directory.svg b/backend/coverage-report/_icons/file-directory.svg deleted file mode 100644 index 4bf1f1ca..00000000 --- a/backend/coverage-report/_icons/file-directory.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/backend/coverage-report/_js/bootstrap.bundle.min.js b/backend/coverage-report/_js/bootstrap.bundle.min.js deleted file mode 100644 index 8739c91c..00000000 --- a/backend/coverage-report/_js/bootstrap.bundle.min.js +++ /dev/null @@ -1,7 +0,0 @@ -/*! - * Bootstrap v5.3.6 (https://getbootstrap.com/) - * Copyright 2011-2025 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors) - * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) - */ -!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):(t="undefined"!=typeof globalThis?globalThis:t||self).bootstrap=e()}(this,(function(){"use strict";const t=new Map,e={set(e,i,n){t.has(e)||t.set(e,new Map);const s=t.get(e);s.has(i)||0===s.size?s.set(i,n):console.error(`Bootstrap doesn't allow more than one instance per element. Bound instance: ${Array.from(s.keys())[0]}.`)},get:(e,i)=>t.has(e)&&t.get(e).get(i)||null,remove(e,i){if(!t.has(e))return;const n=t.get(e);n.delete(i),0===n.size&&t.delete(e)}},i="transitionend",n=t=>(t&&window.CSS&&window.CSS.escape&&(t=t.replace(/#([^\s"#']+)/g,((t,e)=>`#${CSS.escape(e)}`))),t),s=t=>{t.dispatchEvent(new Event(i))},o=t=>!(!t||"object"!=typeof t)&&(void 0!==t.jquery&&(t=t[0]),void 0!==t.nodeType),r=t=>o(t)?t.jquery?t[0]:t:"string"==typeof t&&t.length>0?document.querySelector(n(t)):null,a=t=>{if(!o(t)||0===t.getClientRects().length)return!1;const e="visible"===getComputedStyle(t).getPropertyValue("visibility"),i=t.closest("details:not([open])");if(!i)return e;if(i!==t){const e=t.closest("summary");if(e&&e.parentNode!==i)return!1;if(null===e)return!1}return e},l=t=>!t||t.nodeType!==Node.ELEMENT_NODE||!!t.classList.contains("disabled")||(void 0!==t.disabled?t.disabled:t.hasAttribute("disabled")&&"false"!==t.getAttribute("disabled")),c=t=>{if(!document.documentElement.attachShadow)return null;if("function"==typeof t.getRootNode){const e=t.getRootNode();return e instanceof ShadowRoot?e:null}return t instanceof ShadowRoot?t:t.parentNode?c(t.parentNode):null},h=()=>{},d=t=>{t.offsetHeight},u=()=>window.jQuery&&!document.body.hasAttribute("data-bs-no-jquery")?window.jQuery:null,f=[],p=()=>"rtl"===document.documentElement.dir,m=t=>{var e;e=()=>{const e=u();if(e){const i=t.NAME,n=e.fn[i];e.fn[i]=t.jQueryInterface,e.fn[i].Constructor=t,e.fn[i].noConflict=()=>(e.fn[i]=n,t.jQueryInterface)}},"loading"===document.readyState?(f.length||document.addEventListener("DOMContentLoaded",(()=>{for(const t of f)t()})),f.push(e)):e()},g=(t,e=[],i=t)=>"function"==typeof t?t.call(...e):i,_=(t,e,n=!0)=>{if(!n)return void g(t);const o=(t=>{if(!t)return 0;let{transitionDuration:e,transitionDelay:i}=window.getComputedStyle(t);const n=Number.parseFloat(e),s=Number.parseFloat(i);return n||s?(e=e.split(",")[0],i=i.split(",")[0],1e3*(Number.parseFloat(e)+Number.parseFloat(i))):0})(e)+5;let r=!1;const a=({target:n})=>{n===e&&(r=!0,e.removeEventListener(i,a),g(t))};e.addEventListener(i,a),setTimeout((()=>{r||s(e)}),o)},b=(t,e,i,n)=>{const s=t.length;let o=t.indexOf(e);return-1===o?!i&&n?t[s-1]:t[0]:(o+=i?1:-1,n&&(o=(o+s)%s),t[Math.max(0,Math.min(o,s-1))])},v=/[^.]*(?=\..*)\.|.*/,y=/\..*/,w=/::\d+$/,A={};let E=1;const T={mouseenter:"mouseover",mouseleave:"mouseout"},C=new Set(["click","dblclick","mouseup","mousedown","contextmenu","mousewheel","DOMMouseScroll","mouseover","mouseout","mousemove","selectstart","selectend","keydown","keypress","keyup","orientationchange","touchstart","touchmove","touchend","touchcancel","pointerdown","pointermove","pointerup","pointerleave","pointercancel","gesturestart","gesturechange","gestureend","focus","blur","change","reset","select","submit","focusin","focusout","load","unload","beforeunload","resize","move","DOMContentLoaded","readystatechange","error","abort","scroll"]);function O(t,e){return e&&`${e}::${E++}`||t.uidEvent||E++}function x(t){const e=O(t);return t.uidEvent=e,A[e]=A[e]||{},A[e]}function k(t,e,i=null){return Object.values(t).find((t=>t.callable===e&&t.delegationSelector===i))}function L(t,e,i){const n="string"==typeof e,s=n?i:e||i;let o=I(t);return C.has(o)||(o=t),[n,s,o]}function S(t,e,i,n,s){if("string"!=typeof e||!t)return;let[o,r,a]=L(e,i,n);if(e in T){const t=t=>function(e){if(!e.relatedTarget||e.relatedTarget!==e.delegateTarget&&!e.delegateTarget.contains(e.relatedTarget))return t.call(this,e)};r=t(r)}const l=x(t),c=l[a]||(l[a]={}),h=k(c,r,o?i:null);if(h)return void(h.oneOff=h.oneOff&&s);const d=O(r,e.replace(v,"")),u=o?function(t,e,i){return function n(s){const o=t.querySelectorAll(e);for(let{target:r}=s;r&&r!==this;r=r.parentNode)for(const a of o)if(a===r)return P(s,{delegateTarget:r}),n.oneOff&&N.off(t,s.type,e,i),i.apply(r,[s])}}(t,i,r):function(t,e){return function i(n){return P(n,{delegateTarget:t}),i.oneOff&&N.off(t,n.type,e),e.apply(t,[n])}}(t,r);u.delegationSelector=o?i:null,u.callable=r,u.oneOff=s,u.uidEvent=d,c[d]=u,t.addEventListener(a,u,o)}function D(t,e,i,n,s){const o=k(e[i],n,s);o&&(t.removeEventListener(i,o,Boolean(s)),delete e[i][o.uidEvent])}function $(t,e,i,n){const s=e[i]||{};for(const[o,r]of Object.entries(s))o.includes(n)&&D(t,e,i,r.callable,r.delegationSelector)}function I(t){return t=t.replace(y,""),T[t]||t}const N={on(t,e,i,n){S(t,e,i,n,!1)},one(t,e,i,n){S(t,e,i,n,!0)},off(t,e,i,n){if("string"!=typeof e||!t)return;const[s,o,r]=L(e,i,n),a=r!==e,l=x(t),c=l[r]||{},h=e.startsWith(".");if(void 0===o){if(h)for(const i of Object.keys(l))$(t,l,i,e.slice(1));for(const[i,n]of Object.entries(c)){const s=i.replace(w,"");a&&!e.includes(s)||D(t,l,r,n.callable,n.delegationSelector)}}else{if(!Object.keys(c).length)return;D(t,l,r,o,s?i:null)}},trigger(t,e,i){if("string"!=typeof e||!t)return null;const n=u();let s=null,o=!0,r=!0,a=!1;e!==I(e)&&n&&(s=n.Event(e,i),n(t).trigger(s),o=!s.isPropagationStopped(),r=!s.isImmediatePropagationStopped(),a=s.isDefaultPrevented());const l=P(new Event(e,{bubbles:o,cancelable:!0}),i);return a&&l.preventDefault(),r&&t.dispatchEvent(l),l.defaultPrevented&&s&&s.preventDefault(),l}};function P(t,e={}){for(const[i,n]of Object.entries(e))try{t[i]=n}catch(e){Object.defineProperty(t,i,{configurable:!0,get:()=>n})}return t}function j(t){if("true"===t)return!0;if("false"===t)return!1;if(t===Number(t).toString())return Number(t);if(""===t||"null"===t)return null;if("string"!=typeof t)return t;try{return JSON.parse(decodeURIComponent(t))}catch(e){return t}}function M(t){return t.replace(/[A-Z]/g,(t=>`-${t.toLowerCase()}`))}const F={setDataAttribute(t,e,i){t.setAttribute(`data-bs-${M(e)}`,i)},removeDataAttribute(t,e){t.removeAttribute(`data-bs-${M(e)}`)},getDataAttributes(t){if(!t)return{};const e={},i=Object.keys(t.dataset).filter((t=>t.startsWith("bs")&&!t.startsWith("bsConfig")));for(const n of i){let i=n.replace(/^bs/,"");i=i.charAt(0).toLowerCase()+i.slice(1),e[i]=j(t.dataset[n])}return e},getDataAttribute:(t,e)=>j(t.getAttribute(`data-bs-${M(e)}`))};class H{static get Default(){return{}}static get DefaultType(){return{}}static get NAME(){throw new Error('You have to implement the static method "NAME", for each component!')}_getConfig(t){return t=this._mergeConfigObj(t),t=this._configAfterMerge(t),this._typeCheckConfig(t),t}_configAfterMerge(t){return t}_mergeConfigObj(t,e){const i=o(e)?F.getDataAttribute(e,"config"):{};return{...this.constructor.Default,..."object"==typeof i?i:{},...o(e)?F.getDataAttributes(e):{},..."object"==typeof t?t:{}}}_typeCheckConfig(t,e=this.constructor.DefaultType){for(const[n,s]of Object.entries(e)){const e=t[n],r=o(e)?"element":null==(i=e)?`${i}`:Object.prototype.toString.call(i).match(/\s([a-z]+)/i)[1].toLowerCase();if(!new RegExp(s).test(r))throw new TypeError(`${this.constructor.NAME.toUpperCase()}: Option "${n}" provided type "${r}" but expected type "${s}".`)}var i}}class W extends H{constructor(t,i){super(),(t=r(t))&&(this._element=t,this._config=this._getConfig(i),e.set(this._element,this.constructor.DATA_KEY,this))}dispose(){e.remove(this._element,this.constructor.DATA_KEY),N.off(this._element,this.constructor.EVENT_KEY);for(const t of Object.getOwnPropertyNames(this))this[t]=null}_queueCallback(t,e,i=!0){_(t,e,i)}_getConfig(t){return t=this._mergeConfigObj(t,this._element),t=this._configAfterMerge(t),this._typeCheckConfig(t),t}static getInstance(t){return e.get(r(t),this.DATA_KEY)}static getOrCreateInstance(t,e={}){return this.getInstance(t)||new this(t,"object"==typeof e?e:null)}static get VERSION(){return"5.3.6"}static get DATA_KEY(){return`bs.${this.NAME}`}static get EVENT_KEY(){return`.${this.DATA_KEY}`}static eventName(t){return`${t}${this.EVENT_KEY}`}}const B=t=>{let e=t.getAttribute("data-bs-target");if(!e||"#"===e){let i=t.getAttribute("href");if(!i||!i.includes("#")&&!i.startsWith("."))return null;i.includes("#")&&!i.startsWith("#")&&(i=`#${i.split("#")[1]}`),e=i&&"#"!==i?i.trim():null}return e?e.split(",").map((t=>n(t))).join(","):null},z={find:(t,e=document.documentElement)=>[].concat(...Element.prototype.querySelectorAll.call(e,t)),findOne:(t,e=document.documentElement)=>Element.prototype.querySelector.call(e,t),children:(t,e)=>[].concat(...t.children).filter((t=>t.matches(e))),parents(t,e){const i=[];let n=t.parentNode.closest(e);for(;n;)i.push(n),n=n.parentNode.closest(e);return i},prev(t,e){let i=t.previousElementSibling;for(;i;){if(i.matches(e))return[i];i=i.previousElementSibling}return[]},next(t,e){let i=t.nextElementSibling;for(;i;){if(i.matches(e))return[i];i=i.nextElementSibling}return[]},focusableChildren(t){const e=["a","button","input","textarea","select","details","[tabindex]",'[contenteditable="true"]'].map((t=>`${t}:not([tabindex^="-"])`)).join(",");return this.find(e,t).filter((t=>!l(t)&&a(t)))},getSelectorFromElement(t){const e=B(t);return e&&z.findOne(e)?e:null},getElementFromSelector(t){const e=B(t);return e?z.findOne(e):null},getMultipleElementsFromSelector(t){const e=B(t);return e?z.find(e):[]}},R=(t,e="hide")=>{const i=`click.dismiss${t.EVENT_KEY}`,n=t.NAME;N.on(document,i,`[data-bs-dismiss="${n}"]`,(function(i){if(["A","AREA"].includes(this.tagName)&&i.preventDefault(),l(this))return;const s=z.getElementFromSelector(this)||this.closest(`.${n}`);t.getOrCreateInstance(s)[e]()}))},q=".bs.alert",V=`close${q}`,K=`closed${q}`;class Q extends W{static get NAME(){return"alert"}close(){if(N.trigger(this._element,V).defaultPrevented)return;this._element.classList.remove("show");const t=this._element.classList.contains("fade");this._queueCallback((()=>this._destroyElement()),this._element,t)}_destroyElement(){this._element.remove(),N.trigger(this._element,K),this.dispose()}static jQueryInterface(t){return this.each((function(){const e=Q.getOrCreateInstance(this);if("string"==typeof t){if(void 0===e[t]||t.startsWith("_")||"constructor"===t)throw new TypeError(`No method named "${t}"`);e[t](this)}}))}}R(Q,"close"),m(Q);const X='[data-bs-toggle="button"]';class Y extends W{static get NAME(){return"button"}toggle(){this._element.setAttribute("aria-pressed",this._element.classList.toggle("active"))}static jQueryInterface(t){return this.each((function(){const e=Y.getOrCreateInstance(this);"toggle"===t&&e[t]()}))}}N.on(document,"click.bs.button.data-api",X,(t=>{t.preventDefault();const e=t.target.closest(X);Y.getOrCreateInstance(e).toggle()})),m(Y);const U=".bs.swipe",G=`touchstart${U}`,J=`touchmove${U}`,Z=`touchend${U}`,tt=`pointerdown${U}`,et=`pointerup${U}`,it={endCallback:null,leftCallback:null,rightCallback:null},nt={endCallback:"(function|null)",leftCallback:"(function|null)",rightCallback:"(function|null)"};class st extends H{constructor(t,e){super(),this._element=t,t&&st.isSupported()&&(this._config=this._getConfig(e),this._deltaX=0,this._supportPointerEvents=Boolean(window.PointerEvent),this._initEvents())}static get Default(){return it}static get DefaultType(){return nt}static get NAME(){return"swipe"}dispose(){N.off(this._element,U)}_start(t){this._supportPointerEvents?this._eventIsPointerPenTouch(t)&&(this._deltaX=t.clientX):this._deltaX=t.touches[0].clientX}_end(t){this._eventIsPointerPenTouch(t)&&(this._deltaX=t.clientX-this._deltaX),this._handleSwipe(),g(this._config.endCallback)}_move(t){this._deltaX=t.touches&&t.touches.length>1?0:t.touches[0].clientX-this._deltaX}_handleSwipe(){const t=Math.abs(this._deltaX);if(t<=40)return;const e=t/this._deltaX;this._deltaX=0,e&&g(e>0?this._config.rightCallback:this._config.leftCallback)}_initEvents(){this._supportPointerEvents?(N.on(this._element,tt,(t=>this._start(t))),N.on(this._element,et,(t=>this._end(t))),this._element.classList.add("pointer-event")):(N.on(this._element,G,(t=>this._start(t))),N.on(this._element,J,(t=>this._move(t))),N.on(this._element,Z,(t=>this._end(t))))}_eventIsPointerPenTouch(t){return this._supportPointerEvents&&("pen"===t.pointerType||"touch"===t.pointerType)}static isSupported(){return"ontouchstart"in document.documentElement||navigator.maxTouchPoints>0}}const ot=".bs.carousel",rt=".data-api",at="ArrowLeft",lt="ArrowRight",ct="next",ht="prev",dt="left",ut="right",ft=`slide${ot}`,pt=`slid${ot}`,mt=`keydown${ot}`,gt=`mouseenter${ot}`,_t=`mouseleave${ot}`,bt=`dragstart${ot}`,vt=`load${ot}${rt}`,yt=`click${ot}${rt}`,wt="carousel",At="active",Et=".active",Tt=".carousel-item",Ct=Et+Tt,Ot={[at]:ut,[lt]:dt},xt={interval:5e3,keyboard:!0,pause:"hover",ride:!1,touch:!0,wrap:!0},kt={interval:"(number|boolean)",keyboard:"boolean",pause:"(string|boolean)",ride:"(boolean|string)",touch:"boolean",wrap:"boolean"};class Lt extends W{constructor(t,e){super(t,e),this._interval=null,this._activeElement=null,this._isSliding=!1,this.touchTimeout=null,this._swipeHelper=null,this._indicatorsElement=z.findOne(".carousel-indicators",this._element),this._addEventListeners(),this._config.ride===wt&&this.cycle()}static get Default(){return xt}static get DefaultType(){return kt}static get NAME(){return"carousel"}next(){this._slide(ct)}nextWhenVisible(){!document.hidden&&a(this._element)&&this.next()}prev(){this._slide(ht)}pause(){this._isSliding&&s(this._element),this._clearInterval()}cycle(){this._clearInterval(),this._updateInterval(),this._interval=setInterval((()=>this.nextWhenVisible()),this._config.interval)}_maybeEnableCycle(){this._config.ride&&(this._isSliding?N.one(this._element,pt,(()=>this.cycle())):this.cycle())}to(t){const e=this._getItems();if(t>e.length-1||t<0)return;if(this._isSliding)return void N.one(this._element,pt,(()=>this.to(t)));const i=this._getItemIndex(this._getActive());if(i===t)return;const n=t>i?ct:ht;this._slide(n,e[t])}dispose(){this._swipeHelper&&this._swipeHelper.dispose(),super.dispose()}_configAfterMerge(t){return t.defaultInterval=t.interval,t}_addEventListeners(){this._config.keyboard&&N.on(this._element,mt,(t=>this._keydown(t))),"hover"===this._config.pause&&(N.on(this._element,gt,(()=>this.pause())),N.on(this._element,_t,(()=>this._maybeEnableCycle()))),this._config.touch&&st.isSupported()&&this._addTouchEventListeners()}_addTouchEventListeners(){for(const t of z.find(".carousel-item img",this._element))N.on(t,bt,(t=>t.preventDefault()));const t={leftCallback:()=>this._slide(this._directionToOrder(dt)),rightCallback:()=>this._slide(this._directionToOrder(ut)),endCallback:()=>{"hover"===this._config.pause&&(this.pause(),this.touchTimeout&&clearTimeout(this.touchTimeout),this.touchTimeout=setTimeout((()=>this._maybeEnableCycle()),500+this._config.interval))}};this._swipeHelper=new st(this._element,t)}_keydown(t){if(/input|textarea/i.test(t.target.tagName))return;const e=Ot[t.key];e&&(t.preventDefault(),this._slide(this._directionToOrder(e)))}_getItemIndex(t){return this._getItems().indexOf(t)}_setActiveIndicatorElement(t){if(!this._indicatorsElement)return;const e=z.findOne(Et,this._indicatorsElement);e.classList.remove(At),e.removeAttribute("aria-current");const i=z.findOne(`[data-bs-slide-to="${t}"]`,this._indicatorsElement);i&&(i.classList.add(At),i.setAttribute("aria-current","true"))}_updateInterval(){const t=this._activeElement||this._getActive();if(!t)return;const e=Number.parseInt(t.getAttribute("data-bs-interval"),10);this._config.interval=e||this._config.defaultInterval}_slide(t,e=null){if(this._isSliding)return;const i=this._getActive(),n=t===ct,s=e||b(this._getItems(),i,n,this._config.wrap);if(s===i)return;const o=this._getItemIndex(s),r=e=>N.trigger(this._element,e,{relatedTarget:s,direction:this._orderToDirection(t),from:this._getItemIndex(i),to:o});if(r(ft).defaultPrevented)return;if(!i||!s)return;const a=Boolean(this._interval);this.pause(),this._isSliding=!0,this._setActiveIndicatorElement(o),this._activeElement=s;const l=n?"carousel-item-start":"carousel-item-end",c=n?"carousel-item-next":"carousel-item-prev";s.classList.add(c),d(s),i.classList.add(l),s.classList.add(l),this._queueCallback((()=>{s.classList.remove(l,c),s.classList.add(At),i.classList.remove(At,c,l),this._isSliding=!1,r(pt)}),i,this._isAnimated()),a&&this.cycle()}_isAnimated(){return this._element.classList.contains("slide")}_getActive(){return z.findOne(Ct,this._element)}_getItems(){return z.find(Tt,this._element)}_clearInterval(){this._interval&&(clearInterval(this._interval),this._interval=null)}_directionToOrder(t){return p()?t===dt?ht:ct:t===dt?ct:ht}_orderToDirection(t){return p()?t===ht?dt:ut:t===ht?ut:dt}static jQueryInterface(t){return this.each((function(){const e=Lt.getOrCreateInstance(this,t);if("number"!=typeof t){if("string"==typeof t){if(void 0===e[t]||t.startsWith("_")||"constructor"===t)throw new TypeError(`No method named "${t}"`);e[t]()}}else e.to(t)}))}}N.on(document,yt,"[data-bs-slide], [data-bs-slide-to]",(function(t){const e=z.getElementFromSelector(this);if(!e||!e.classList.contains(wt))return;t.preventDefault();const i=Lt.getOrCreateInstance(e),n=this.getAttribute("data-bs-slide-to");return n?(i.to(n),void i._maybeEnableCycle()):"next"===F.getDataAttribute(this,"slide")?(i.next(),void i._maybeEnableCycle()):(i.prev(),void i._maybeEnableCycle())})),N.on(window,vt,(()=>{const t=z.find('[data-bs-ride="carousel"]');for(const e of t)Lt.getOrCreateInstance(e)})),m(Lt);const St=".bs.collapse",Dt=`show${St}`,$t=`shown${St}`,It=`hide${St}`,Nt=`hidden${St}`,Pt=`click${St}.data-api`,jt="show",Mt="collapse",Ft="collapsing",Ht=`:scope .${Mt} .${Mt}`,Wt='[data-bs-toggle="collapse"]',Bt={parent:null,toggle:!0},zt={parent:"(null|element)",toggle:"boolean"};class Rt extends W{constructor(t,e){super(t,e),this._isTransitioning=!1,this._triggerArray=[];const i=z.find(Wt);for(const t of i){const e=z.getSelectorFromElement(t),i=z.find(e).filter((t=>t===this._element));null!==e&&i.length&&this._triggerArray.push(t)}this._initializeChildren(),this._config.parent||this._addAriaAndCollapsedClass(this._triggerArray,this._isShown()),this._config.toggle&&this.toggle()}static get Default(){return Bt}static get DefaultType(){return zt}static get NAME(){return"collapse"}toggle(){this._isShown()?this.hide():this.show()}show(){if(this._isTransitioning||this._isShown())return;let t=[];if(this._config.parent&&(t=this._getFirstLevelChildren(".collapse.show, .collapse.collapsing").filter((t=>t!==this._element)).map((t=>Rt.getOrCreateInstance(t,{toggle:!1})))),t.length&&t[0]._isTransitioning)return;if(N.trigger(this._element,Dt).defaultPrevented)return;for(const e of t)e.hide();const e=this._getDimension();this._element.classList.remove(Mt),this._element.classList.add(Ft),this._element.style[e]=0,this._addAriaAndCollapsedClass(this._triggerArray,!0),this._isTransitioning=!0;const i=`scroll${e[0].toUpperCase()+e.slice(1)}`;this._queueCallback((()=>{this._isTransitioning=!1,this._element.classList.remove(Ft),this._element.classList.add(Mt,jt),this._element.style[e]="",N.trigger(this._element,$t)}),this._element,!0),this._element.style[e]=`${this._element[i]}px`}hide(){if(this._isTransitioning||!this._isShown())return;if(N.trigger(this._element,It).defaultPrevented)return;const t=this._getDimension();this._element.style[t]=`${this._element.getBoundingClientRect()[t]}px`,d(this._element),this._element.classList.add(Ft),this._element.classList.remove(Mt,jt);for(const t of this._triggerArray){const e=z.getElementFromSelector(t);e&&!this._isShown(e)&&this._addAriaAndCollapsedClass([t],!1)}this._isTransitioning=!0,this._element.style[t]="",this._queueCallback((()=>{this._isTransitioning=!1,this._element.classList.remove(Ft),this._element.classList.add(Mt),N.trigger(this._element,Nt)}),this._element,!0)}_isShown(t=this._element){return t.classList.contains(jt)}_configAfterMerge(t){return t.toggle=Boolean(t.toggle),t.parent=r(t.parent),t}_getDimension(){return this._element.classList.contains("collapse-horizontal")?"width":"height"}_initializeChildren(){if(!this._config.parent)return;const t=this._getFirstLevelChildren(Wt);for(const e of t){const t=z.getElementFromSelector(e);t&&this._addAriaAndCollapsedClass([e],this._isShown(t))}}_getFirstLevelChildren(t){const e=z.find(Ht,this._config.parent);return z.find(t,this._config.parent).filter((t=>!e.includes(t)))}_addAriaAndCollapsedClass(t,e){if(t.length)for(const i of t)i.classList.toggle("collapsed",!e),i.setAttribute("aria-expanded",e)}static jQueryInterface(t){const e={};return"string"==typeof t&&/show|hide/.test(t)&&(e.toggle=!1),this.each((function(){const i=Rt.getOrCreateInstance(this,e);if("string"==typeof t){if(void 0===i[t])throw new TypeError(`No method named "${t}"`);i[t]()}}))}}N.on(document,Pt,Wt,(function(t){("A"===t.target.tagName||t.delegateTarget&&"A"===t.delegateTarget.tagName)&&t.preventDefault();for(const t of z.getMultipleElementsFromSelector(this))Rt.getOrCreateInstance(t,{toggle:!1}).toggle()})),m(Rt);var qt="top",Vt="bottom",Kt="right",Qt="left",Xt="auto",Yt=[qt,Vt,Kt,Qt],Ut="start",Gt="end",Jt="clippingParents",Zt="viewport",te="popper",ee="reference",ie=Yt.reduce((function(t,e){return t.concat([e+"-"+Ut,e+"-"+Gt])}),[]),ne=[].concat(Yt,[Xt]).reduce((function(t,e){return t.concat([e,e+"-"+Ut,e+"-"+Gt])}),[]),se="beforeRead",oe="read",re="afterRead",ae="beforeMain",le="main",ce="afterMain",he="beforeWrite",de="write",ue="afterWrite",fe=[se,oe,re,ae,le,ce,he,de,ue];function pe(t){return t?(t.nodeName||"").toLowerCase():null}function me(t){if(null==t)return window;if("[object Window]"!==t.toString()){var e=t.ownerDocument;return e&&e.defaultView||window}return t}function ge(t){return t instanceof me(t).Element||t instanceof Element}function _e(t){return t instanceof me(t).HTMLElement||t instanceof HTMLElement}function be(t){return"undefined"!=typeof ShadowRoot&&(t instanceof me(t).ShadowRoot||t instanceof ShadowRoot)}const ve={name:"applyStyles",enabled:!0,phase:"write",fn:function(t){var e=t.state;Object.keys(e.elements).forEach((function(t){var i=e.styles[t]||{},n=e.attributes[t]||{},s=e.elements[t];_e(s)&&pe(s)&&(Object.assign(s.style,i),Object.keys(n).forEach((function(t){var e=n[t];!1===e?s.removeAttribute(t):s.setAttribute(t,!0===e?"":e)})))}))},effect:function(t){var e=t.state,i={popper:{position:e.options.strategy,left:"0",top:"0",margin:"0"},arrow:{position:"absolute"},reference:{}};return Object.assign(e.elements.popper.style,i.popper),e.styles=i,e.elements.arrow&&Object.assign(e.elements.arrow.style,i.arrow),function(){Object.keys(e.elements).forEach((function(t){var n=e.elements[t],s=e.attributes[t]||{},o=Object.keys(e.styles.hasOwnProperty(t)?e.styles[t]:i[t]).reduce((function(t,e){return t[e]="",t}),{});_e(n)&&pe(n)&&(Object.assign(n.style,o),Object.keys(s).forEach((function(t){n.removeAttribute(t)})))}))}},requires:["computeStyles"]};function ye(t){return t.split("-")[0]}var we=Math.max,Ae=Math.min,Ee=Math.round;function Te(){var t=navigator.userAgentData;return null!=t&&t.brands&&Array.isArray(t.brands)?t.brands.map((function(t){return t.brand+"/"+t.version})).join(" "):navigator.userAgent}function Ce(){return!/^((?!chrome|android).)*safari/i.test(Te())}function Oe(t,e,i){void 0===e&&(e=!1),void 0===i&&(i=!1);var n=t.getBoundingClientRect(),s=1,o=1;e&&_e(t)&&(s=t.offsetWidth>0&&Ee(n.width)/t.offsetWidth||1,o=t.offsetHeight>0&&Ee(n.height)/t.offsetHeight||1);var r=(ge(t)?me(t):window).visualViewport,a=!Ce()&&i,l=(n.left+(a&&r?r.offsetLeft:0))/s,c=(n.top+(a&&r?r.offsetTop:0))/o,h=n.width/s,d=n.height/o;return{width:h,height:d,top:c,right:l+h,bottom:c+d,left:l,x:l,y:c}}function xe(t){var e=Oe(t),i=t.offsetWidth,n=t.offsetHeight;return Math.abs(e.width-i)<=1&&(i=e.width),Math.abs(e.height-n)<=1&&(n=e.height),{x:t.offsetLeft,y:t.offsetTop,width:i,height:n}}function ke(t,e){var i=e.getRootNode&&e.getRootNode();if(t.contains(e))return!0;if(i&&be(i)){var n=e;do{if(n&&t.isSameNode(n))return!0;n=n.parentNode||n.host}while(n)}return!1}function Le(t){return me(t).getComputedStyle(t)}function Se(t){return["table","td","th"].indexOf(pe(t))>=0}function De(t){return((ge(t)?t.ownerDocument:t.document)||window.document).documentElement}function $e(t){return"html"===pe(t)?t:t.assignedSlot||t.parentNode||(be(t)?t.host:null)||De(t)}function Ie(t){return _e(t)&&"fixed"!==Le(t).position?t.offsetParent:null}function Ne(t){for(var e=me(t),i=Ie(t);i&&Se(i)&&"static"===Le(i).position;)i=Ie(i);return i&&("html"===pe(i)||"body"===pe(i)&&"static"===Le(i).position)?e:i||function(t){var e=/firefox/i.test(Te());if(/Trident/i.test(Te())&&_e(t)&&"fixed"===Le(t).position)return null;var i=$e(t);for(be(i)&&(i=i.host);_e(i)&&["html","body"].indexOf(pe(i))<0;){var n=Le(i);if("none"!==n.transform||"none"!==n.perspective||"paint"===n.contain||-1!==["transform","perspective"].indexOf(n.willChange)||e&&"filter"===n.willChange||e&&n.filter&&"none"!==n.filter)return i;i=i.parentNode}return null}(t)||e}function Pe(t){return["top","bottom"].indexOf(t)>=0?"x":"y"}function je(t,e,i){return we(t,Ae(e,i))}function Me(t){return Object.assign({},{top:0,right:0,bottom:0,left:0},t)}function Fe(t,e){return e.reduce((function(e,i){return e[i]=t,e}),{})}const He={name:"arrow",enabled:!0,phase:"main",fn:function(t){var e,i=t.state,n=t.name,s=t.options,o=i.elements.arrow,r=i.modifiersData.popperOffsets,a=ye(i.placement),l=Pe(a),c=[Qt,Kt].indexOf(a)>=0?"height":"width";if(o&&r){var h=function(t,e){return Me("number"!=typeof(t="function"==typeof t?t(Object.assign({},e.rects,{placement:e.placement})):t)?t:Fe(t,Yt))}(s.padding,i),d=xe(o),u="y"===l?qt:Qt,f="y"===l?Vt:Kt,p=i.rects.reference[c]+i.rects.reference[l]-r[l]-i.rects.popper[c],m=r[l]-i.rects.reference[l],g=Ne(o),_=g?"y"===l?g.clientHeight||0:g.clientWidth||0:0,b=p/2-m/2,v=h[u],y=_-d[c]-h[f],w=_/2-d[c]/2+b,A=je(v,w,y),E=l;i.modifiersData[n]=((e={})[E]=A,e.centerOffset=A-w,e)}},effect:function(t){var e=t.state,i=t.options.element,n=void 0===i?"[data-popper-arrow]":i;null!=n&&("string"!=typeof n||(n=e.elements.popper.querySelector(n)))&&ke(e.elements.popper,n)&&(e.elements.arrow=n)},requires:["popperOffsets"],requiresIfExists:["preventOverflow"]};function We(t){return t.split("-")[1]}var Be={top:"auto",right:"auto",bottom:"auto",left:"auto"};function ze(t){var e,i=t.popper,n=t.popperRect,s=t.placement,o=t.variation,r=t.offsets,a=t.position,l=t.gpuAcceleration,c=t.adaptive,h=t.roundOffsets,d=t.isFixed,u=r.x,f=void 0===u?0:u,p=r.y,m=void 0===p?0:p,g="function"==typeof h?h({x:f,y:m}):{x:f,y:m};f=g.x,m=g.y;var _=r.hasOwnProperty("x"),b=r.hasOwnProperty("y"),v=Qt,y=qt,w=window;if(c){var A=Ne(i),E="clientHeight",T="clientWidth";A===me(i)&&"static"!==Le(A=De(i)).position&&"absolute"===a&&(E="scrollHeight",T="scrollWidth"),(s===qt||(s===Qt||s===Kt)&&o===Gt)&&(y=Vt,m-=(d&&A===w&&w.visualViewport?w.visualViewport.height:A[E])-n.height,m*=l?1:-1),s!==Qt&&(s!==qt&&s!==Vt||o!==Gt)||(v=Kt,f-=(d&&A===w&&w.visualViewport?w.visualViewport.width:A[T])-n.width,f*=l?1:-1)}var C,O=Object.assign({position:a},c&&Be),x=!0===h?function(t,e){var i=t.x,n=t.y,s=e.devicePixelRatio||1;return{x:Ee(i*s)/s||0,y:Ee(n*s)/s||0}}({x:f,y:m},me(i)):{x:f,y:m};return f=x.x,m=x.y,l?Object.assign({},O,((C={})[y]=b?"0":"",C[v]=_?"0":"",C.transform=(w.devicePixelRatio||1)<=1?"translate("+f+"px, "+m+"px)":"translate3d("+f+"px, "+m+"px, 0)",C)):Object.assign({},O,((e={})[y]=b?m+"px":"",e[v]=_?f+"px":"",e.transform="",e))}const Re={name:"computeStyles",enabled:!0,phase:"beforeWrite",fn:function(t){var e=t.state,i=t.options,n=i.gpuAcceleration,s=void 0===n||n,o=i.adaptive,r=void 0===o||o,a=i.roundOffsets,l=void 0===a||a,c={placement:ye(e.placement),variation:We(e.placement),popper:e.elements.popper,popperRect:e.rects.popper,gpuAcceleration:s,isFixed:"fixed"===e.options.strategy};null!=e.modifiersData.popperOffsets&&(e.styles.popper=Object.assign({},e.styles.popper,ze(Object.assign({},c,{offsets:e.modifiersData.popperOffsets,position:e.options.strategy,adaptive:r,roundOffsets:l})))),null!=e.modifiersData.arrow&&(e.styles.arrow=Object.assign({},e.styles.arrow,ze(Object.assign({},c,{offsets:e.modifiersData.arrow,position:"absolute",adaptive:!1,roundOffsets:l})))),e.attributes.popper=Object.assign({},e.attributes.popper,{"data-popper-placement":e.placement})},data:{}};var qe={passive:!0};const Ve={name:"eventListeners",enabled:!0,phase:"write",fn:function(){},effect:function(t){var e=t.state,i=t.instance,n=t.options,s=n.scroll,o=void 0===s||s,r=n.resize,a=void 0===r||r,l=me(e.elements.popper),c=[].concat(e.scrollParents.reference,e.scrollParents.popper);return o&&c.forEach((function(t){t.addEventListener("scroll",i.update,qe)})),a&&l.addEventListener("resize",i.update,qe),function(){o&&c.forEach((function(t){t.removeEventListener("scroll",i.update,qe)})),a&&l.removeEventListener("resize",i.update,qe)}},data:{}};var Ke={left:"right",right:"left",bottom:"top",top:"bottom"};function Qe(t){return t.replace(/left|right|bottom|top/g,(function(t){return Ke[t]}))}var Xe={start:"end",end:"start"};function Ye(t){return t.replace(/start|end/g,(function(t){return Xe[t]}))}function Ue(t){var e=me(t);return{scrollLeft:e.pageXOffset,scrollTop:e.pageYOffset}}function Ge(t){return Oe(De(t)).left+Ue(t).scrollLeft}function Je(t){var e=Le(t),i=e.overflow,n=e.overflowX,s=e.overflowY;return/auto|scroll|overlay|hidden/.test(i+s+n)}function Ze(t){return["html","body","#document"].indexOf(pe(t))>=0?t.ownerDocument.body:_e(t)&&Je(t)?t:Ze($e(t))}function ti(t,e){var i;void 0===e&&(e=[]);var n=Ze(t),s=n===(null==(i=t.ownerDocument)?void 0:i.body),o=me(n),r=s?[o].concat(o.visualViewport||[],Je(n)?n:[]):n,a=e.concat(r);return s?a:a.concat(ti($e(r)))}function ei(t){return Object.assign({},t,{left:t.x,top:t.y,right:t.x+t.width,bottom:t.y+t.height})}function ii(t,e,i){return e===Zt?ei(function(t,e){var i=me(t),n=De(t),s=i.visualViewport,o=n.clientWidth,r=n.clientHeight,a=0,l=0;if(s){o=s.width,r=s.height;var c=Ce();(c||!c&&"fixed"===e)&&(a=s.offsetLeft,l=s.offsetTop)}return{width:o,height:r,x:a+Ge(t),y:l}}(t,i)):ge(e)?function(t,e){var i=Oe(t,!1,"fixed"===e);return i.top=i.top+t.clientTop,i.left=i.left+t.clientLeft,i.bottom=i.top+t.clientHeight,i.right=i.left+t.clientWidth,i.width=t.clientWidth,i.height=t.clientHeight,i.x=i.left,i.y=i.top,i}(e,i):ei(function(t){var e,i=De(t),n=Ue(t),s=null==(e=t.ownerDocument)?void 0:e.body,o=we(i.scrollWidth,i.clientWidth,s?s.scrollWidth:0,s?s.clientWidth:0),r=we(i.scrollHeight,i.clientHeight,s?s.scrollHeight:0,s?s.clientHeight:0),a=-n.scrollLeft+Ge(t),l=-n.scrollTop;return"rtl"===Le(s||i).direction&&(a+=we(i.clientWidth,s?s.clientWidth:0)-o),{width:o,height:r,x:a,y:l}}(De(t)))}function ni(t){var e,i=t.reference,n=t.element,s=t.placement,o=s?ye(s):null,r=s?We(s):null,a=i.x+i.width/2-n.width/2,l=i.y+i.height/2-n.height/2;switch(o){case qt:e={x:a,y:i.y-n.height};break;case Vt:e={x:a,y:i.y+i.height};break;case Kt:e={x:i.x+i.width,y:l};break;case Qt:e={x:i.x-n.width,y:l};break;default:e={x:i.x,y:i.y}}var c=o?Pe(o):null;if(null!=c){var h="y"===c?"height":"width";switch(r){case Ut:e[c]=e[c]-(i[h]/2-n[h]/2);break;case Gt:e[c]=e[c]+(i[h]/2-n[h]/2)}}return e}function si(t,e){void 0===e&&(e={});var i=e,n=i.placement,s=void 0===n?t.placement:n,o=i.strategy,r=void 0===o?t.strategy:o,a=i.boundary,l=void 0===a?Jt:a,c=i.rootBoundary,h=void 0===c?Zt:c,d=i.elementContext,u=void 0===d?te:d,f=i.altBoundary,p=void 0!==f&&f,m=i.padding,g=void 0===m?0:m,_=Me("number"!=typeof g?g:Fe(g,Yt)),b=u===te?ee:te,v=t.rects.popper,y=t.elements[p?b:u],w=function(t,e,i,n){var s="clippingParents"===e?function(t){var e=ti($e(t)),i=["absolute","fixed"].indexOf(Le(t).position)>=0&&_e(t)?Ne(t):t;return ge(i)?e.filter((function(t){return ge(t)&&ke(t,i)&&"body"!==pe(t)})):[]}(t):[].concat(e),o=[].concat(s,[i]),r=o[0],a=o.reduce((function(e,i){var s=ii(t,i,n);return e.top=we(s.top,e.top),e.right=Ae(s.right,e.right),e.bottom=Ae(s.bottom,e.bottom),e.left=we(s.left,e.left),e}),ii(t,r,n));return a.width=a.right-a.left,a.height=a.bottom-a.top,a.x=a.left,a.y=a.top,a}(ge(y)?y:y.contextElement||De(t.elements.popper),l,h,r),A=Oe(t.elements.reference),E=ni({reference:A,element:v,placement:s}),T=ei(Object.assign({},v,E)),C=u===te?T:A,O={top:w.top-C.top+_.top,bottom:C.bottom-w.bottom+_.bottom,left:w.left-C.left+_.left,right:C.right-w.right+_.right},x=t.modifiersData.offset;if(u===te&&x){var k=x[s];Object.keys(O).forEach((function(t){var e=[Kt,Vt].indexOf(t)>=0?1:-1,i=[qt,Vt].indexOf(t)>=0?"y":"x";O[t]+=k[i]*e}))}return O}function oi(t,e){void 0===e&&(e={});var i=e,n=i.placement,s=i.boundary,o=i.rootBoundary,r=i.padding,a=i.flipVariations,l=i.allowedAutoPlacements,c=void 0===l?ne:l,h=We(n),d=h?a?ie:ie.filter((function(t){return We(t)===h})):Yt,u=d.filter((function(t){return c.indexOf(t)>=0}));0===u.length&&(u=d);var f=u.reduce((function(e,i){return e[i]=si(t,{placement:i,boundary:s,rootBoundary:o,padding:r})[ye(i)],e}),{});return Object.keys(f).sort((function(t,e){return f[t]-f[e]}))}const ri={name:"flip",enabled:!0,phase:"main",fn:function(t){var e=t.state,i=t.options,n=t.name;if(!e.modifiersData[n]._skip){for(var s=i.mainAxis,o=void 0===s||s,r=i.altAxis,a=void 0===r||r,l=i.fallbackPlacements,c=i.padding,h=i.boundary,d=i.rootBoundary,u=i.altBoundary,f=i.flipVariations,p=void 0===f||f,m=i.allowedAutoPlacements,g=e.options.placement,_=ye(g),b=l||(_!==g&&p?function(t){if(ye(t)===Xt)return[];var e=Qe(t);return[Ye(t),e,Ye(e)]}(g):[Qe(g)]),v=[g].concat(b).reduce((function(t,i){return t.concat(ye(i)===Xt?oi(e,{placement:i,boundary:h,rootBoundary:d,padding:c,flipVariations:p,allowedAutoPlacements:m}):i)}),[]),y=e.rects.reference,w=e.rects.popper,A=new Map,E=!0,T=v[0],C=0;C=0,S=L?"width":"height",D=si(e,{placement:O,boundary:h,rootBoundary:d,altBoundary:u,padding:c}),$=L?k?Kt:Qt:k?Vt:qt;y[S]>w[S]&&($=Qe($));var I=Qe($),N=[];if(o&&N.push(D[x]<=0),a&&N.push(D[$]<=0,D[I]<=0),N.every((function(t){return t}))){T=O,E=!1;break}A.set(O,N)}if(E)for(var P=function(t){var e=v.find((function(e){var i=A.get(e);if(i)return i.slice(0,t).every((function(t){return t}))}));if(e)return T=e,"break"},j=p?3:1;j>0&&"break"!==P(j);j--);e.placement!==T&&(e.modifiersData[n]._skip=!0,e.placement=T,e.reset=!0)}},requiresIfExists:["offset"],data:{_skip:!1}};function ai(t,e,i){return void 0===i&&(i={x:0,y:0}),{top:t.top-e.height-i.y,right:t.right-e.width+i.x,bottom:t.bottom-e.height+i.y,left:t.left-e.width-i.x}}function li(t){return[qt,Kt,Vt,Qt].some((function(e){return t[e]>=0}))}const ci={name:"hide",enabled:!0,phase:"main",requiresIfExists:["preventOverflow"],fn:function(t){var e=t.state,i=t.name,n=e.rects.reference,s=e.rects.popper,o=e.modifiersData.preventOverflow,r=si(e,{elementContext:"reference"}),a=si(e,{altBoundary:!0}),l=ai(r,n),c=ai(a,s,o),h=li(l),d=li(c);e.modifiersData[i]={referenceClippingOffsets:l,popperEscapeOffsets:c,isReferenceHidden:h,hasPopperEscaped:d},e.attributes.popper=Object.assign({},e.attributes.popper,{"data-popper-reference-hidden":h,"data-popper-escaped":d})}},hi={name:"offset",enabled:!0,phase:"main",requires:["popperOffsets"],fn:function(t){var e=t.state,i=t.options,n=t.name,s=i.offset,o=void 0===s?[0,0]:s,r=ne.reduce((function(t,i){return t[i]=function(t,e,i){var n=ye(t),s=[Qt,qt].indexOf(n)>=0?-1:1,o="function"==typeof i?i(Object.assign({},e,{placement:t})):i,r=o[0],a=o[1];return r=r||0,a=(a||0)*s,[Qt,Kt].indexOf(n)>=0?{x:a,y:r}:{x:r,y:a}}(i,e.rects,o),t}),{}),a=r[e.placement],l=a.x,c=a.y;null!=e.modifiersData.popperOffsets&&(e.modifiersData.popperOffsets.x+=l,e.modifiersData.popperOffsets.y+=c),e.modifiersData[n]=r}},di={name:"popperOffsets",enabled:!0,phase:"read",fn:function(t){var e=t.state,i=t.name;e.modifiersData[i]=ni({reference:e.rects.reference,element:e.rects.popper,placement:e.placement})},data:{}},ui={name:"preventOverflow",enabled:!0,phase:"main",fn:function(t){var e=t.state,i=t.options,n=t.name,s=i.mainAxis,o=void 0===s||s,r=i.altAxis,a=void 0!==r&&r,l=i.boundary,c=i.rootBoundary,h=i.altBoundary,d=i.padding,u=i.tether,f=void 0===u||u,p=i.tetherOffset,m=void 0===p?0:p,g=si(e,{boundary:l,rootBoundary:c,padding:d,altBoundary:h}),_=ye(e.placement),b=We(e.placement),v=!b,y=Pe(_),w="x"===y?"y":"x",A=e.modifiersData.popperOffsets,E=e.rects.reference,T=e.rects.popper,C="function"==typeof m?m(Object.assign({},e.rects,{placement:e.placement})):m,O="number"==typeof C?{mainAxis:C,altAxis:C}:Object.assign({mainAxis:0,altAxis:0},C),x=e.modifiersData.offset?e.modifiersData.offset[e.placement]:null,k={x:0,y:0};if(A){if(o){var L,S="y"===y?qt:Qt,D="y"===y?Vt:Kt,$="y"===y?"height":"width",I=A[y],N=I+g[S],P=I-g[D],j=f?-T[$]/2:0,M=b===Ut?E[$]:T[$],F=b===Ut?-T[$]:-E[$],H=e.elements.arrow,W=f&&H?xe(H):{width:0,height:0},B=e.modifiersData["arrow#persistent"]?e.modifiersData["arrow#persistent"].padding:{top:0,right:0,bottom:0,left:0},z=B[S],R=B[D],q=je(0,E[$],W[$]),V=v?E[$]/2-j-q-z-O.mainAxis:M-q-z-O.mainAxis,K=v?-E[$]/2+j+q+R+O.mainAxis:F+q+R+O.mainAxis,Q=e.elements.arrow&&Ne(e.elements.arrow),X=Q?"y"===y?Q.clientTop||0:Q.clientLeft||0:0,Y=null!=(L=null==x?void 0:x[y])?L:0,U=I+K-Y,G=je(f?Ae(N,I+V-Y-X):N,I,f?we(P,U):P);A[y]=G,k[y]=G-I}if(a){var J,Z="x"===y?qt:Qt,tt="x"===y?Vt:Kt,et=A[w],it="y"===w?"height":"width",nt=et+g[Z],st=et-g[tt],ot=-1!==[qt,Qt].indexOf(_),rt=null!=(J=null==x?void 0:x[w])?J:0,at=ot?nt:et-E[it]-T[it]-rt+O.altAxis,lt=ot?et+E[it]+T[it]-rt-O.altAxis:st,ct=f&&ot?function(t,e,i){var n=je(t,e,i);return n>i?i:n}(at,et,lt):je(f?at:nt,et,f?lt:st);A[w]=ct,k[w]=ct-et}e.modifiersData[n]=k}},requiresIfExists:["offset"]};function fi(t,e,i){void 0===i&&(i=!1);var n,s,o=_e(e),r=_e(e)&&function(t){var e=t.getBoundingClientRect(),i=Ee(e.width)/t.offsetWidth||1,n=Ee(e.height)/t.offsetHeight||1;return 1!==i||1!==n}(e),a=De(e),l=Oe(t,r,i),c={scrollLeft:0,scrollTop:0},h={x:0,y:0};return(o||!o&&!i)&&(("body"!==pe(e)||Je(a))&&(c=(n=e)!==me(n)&&_e(n)?{scrollLeft:(s=n).scrollLeft,scrollTop:s.scrollTop}:Ue(n)),_e(e)?((h=Oe(e,!0)).x+=e.clientLeft,h.y+=e.clientTop):a&&(h.x=Ge(a))),{x:l.left+c.scrollLeft-h.x,y:l.top+c.scrollTop-h.y,width:l.width,height:l.height}}function pi(t){var e=new Map,i=new Set,n=[];function s(t){i.add(t.name),[].concat(t.requires||[],t.requiresIfExists||[]).forEach((function(t){if(!i.has(t)){var n=e.get(t);n&&s(n)}})),n.push(t)}return t.forEach((function(t){e.set(t.name,t)})),t.forEach((function(t){i.has(t.name)||s(t)})),n}var mi={placement:"bottom",modifiers:[],strategy:"absolute"};function gi(){for(var t=arguments.length,e=new Array(t),i=0;iNumber.parseInt(t,10))):"function"==typeof t?e=>t(e,this._element):t}_getPopperConfig(){const t={placement:this._getPlacement(),modifiers:[{name:"preventOverflow",options:{boundary:this._config.boundary}},{name:"offset",options:{offset:this._getOffset()}}]};return(this._inNavbar||"static"===this._config.display)&&(F.setDataAttribute(this._menu,"popper","static"),t.modifiers=[{name:"applyStyles",enabled:!1}]),{...t,...g(this._config.popperConfig,[void 0,t])}}_selectMenuItem({key:t,target:e}){const i=z.find(".dropdown-menu .dropdown-item:not(.disabled):not(:disabled)",this._menu).filter((t=>a(t)));i.length&&b(i,e,t===Oi,!i.includes(e)).focus()}static jQueryInterface(t){return this.each((function(){const e=Ki.getOrCreateInstance(this,t);if("string"==typeof t){if(void 0===e[t])throw new TypeError(`No method named "${t}"`);e[t]()}}))}static clearMenus(t){if(2===t.button||"keyup"===t.type&&"Tab"!==t.key)return;const e=z.find(ji);for(const i of e){const e=Ki.getInstance(i);if(!e||!1===e._config.autoClose)continue;const n=t.composedPath(),s=n.includes(e._menu);if(n.includes(e._element)||"inside"===e._config.autoClose&&!s||"outside"===e._config.autoClose&&s)continue;if(e._menu.contains(t.target)&&("keyup"===t.type&&"Tab"===t.key||/input|select|option|textarea|form/i.test(t.target.tagName)))continue;const o={relatedTarget:e._element};"click"===t.type&&(o.clickEvent=t),e._completeHide(o)}}static dataApiKeydownHandler(t){const e=/input|textarea/i.test(t.target.tagName),i="Escape"===t.key,n=[Ci,Oi].includes(t.key);if(!n&&!i)return;if(e&&!i)return;t.preventDefault();const s=this.matches(Pi)?this:z.prev(this,Pi)[0]||z.next(this,Pi)[0]||z.findOne(Pi,t.delegateTarget.parentNode),o=Ki.getOrCreateInstance(s);if(n)return t.stopPropagation(),o.show(),void o._selectMenuItem(t);o._isShown()&&(t.stopPropagation(),o.hide(),s.focus())}}N.on(document,$i,Pi,Ki.dataApiKeydownHandler),N.on(document,$i,Mi,Ki.dataApiKeydownHandler),N.on(document,Di,Ki.clearMenus),N.on(document,Ii,Ki.clearMenus),N.on(document,Di,Pi,(function(t){t.preventDefault(),Ki.getOrCreateInstance(this).toggle()})),m(Ki);const Qi="backdrop",Xi="show",Yi=`mousedown.bs.${Qi}`,Ui={className:"modal-backdrop",clickCallback:null,isAnimated:!1,isVisible:!0,rootElement:"body"},Gi={className:"string",clickCallback:"(function|null)",isAnimated:"boolean",isVisible:"boolean",rootElement:"(element|string)"};class Ji extends H{constructor(t){super(),this._config=this._getConfig(t),this._isAppended=!1,this._element=null}static get Default(){return Ui}static get DefaultType(){return Gi}static get NAME(){return Qi}show(t){if(!this._config.isVisible)return void g(t);this._append();const e=this._getElement();this._config.isAnimated&&d(e),e.classList.add(Xi),this._emulateAnimation((()=>{g(t)}))}hide(t){this._config.isVisible?(this._getElement().classList.remove(Xi),this._emulateAnimation((()=>{this.dispose(),g(t)}))):g(t)}dispose(){this._isAppended&&(N.off(this._element,Yi),this._element.remove(),this._isAppended=!1)}_getElement(){if(!this._element){const t=document.createElement("div");t.className=this._config.className,this._config.isAnimated&&t.classList.add("fade"),this._element=t}return this._element}_configAfterMerge(t){return t.rootElement=r(t.rootElement),t}_append(){if(this._isAppended)return;const t=this._getElement();this._config.rootElement.append(t),N.on(t,Yi,(()=>{g(this._config.clickCallback)})),this._isAppended=!0}_emulateAnimation(t){_(t,this._getElement(),this._config.isAnimated)}}const Zi=".bs.focustrap",tn=`focusin${Zi}`,en=`keydown.tab${Zi}`,nn="backward",sn={autofocus:!0,trapElement:null},on={autofocus:"boolean",trapElement:"element"};class rn extends H{constructor(t){super(),this._config=this._getConfig(t),this._isActive=!1,this._lastTabNavDirection=null}static get Default(){return sn}static get DefaultType(){return on}static get NAME(){return"focustrap"}activate(){this._isActive||(this._config.autofocus&&this._config.trapElement.focus(),N.off(document,Zi),N.on(document,tn,(t=>this._handleFocusin(t))),N.on(document,en,(t=>this._handleKeydown(t))),this._isActive=!0)}deactivate(){this._isActive&&(this._isActive=!1,N.off(document,Zi))}_handleFocusin(t){const{trapElement:e}=this._config;if(t.target===document||t.target===e||e.contains(t.target))return;const i=z.focusableChildren(e);0===i.length?e.focus():this._lastTabNavDirection===nn?i[i.length-1].focus():i[0].focus()}_handleKeydown(t){"Tab"===t.key&&(this._lastTabNavDirection=t.shiftKey?nn:"forward")}}const an=".fixed-top, .fixed-bottom, .is-fixed, .sticky-top",ln=".sticky-top",cn="padding-right",hn="margin-right";class dn{constructor(){this._element=document.body}getWidth(){const t=document.documentElement.clientWidth;return Math.abs(window.innerWidth-t)}hide(){const t=this.getWidth();this._disableOverFlow(),this._setElementAttributes(this._element,cn,(e=>e+t)),this._setElementAttributes(an,cn,(e=>e+t)),this._setElementAttributes(ln,hn,(e=>e-t))}reset(){this._resetElementAttributes(this._element,"overflow"),this._resetElementAttributes(this._element,cn),this._resetElementAttributes(an,cn),this._resetElementAttributes(ln,hn)}isOverflowing(){return this.getWidth()>0}_disableOverFlow(){this._saveInitialAttribute(this._element,"overflow"),this._element.style.overflow="hidden"}_setElementAttributes(t,e,i){const n=this.getWidth();this._applyManipulationCallback(t,(t=>{if(t!==this._element&&window.innerWidth>t.clientWidth+n)return;this._saveInitialAttribute(t,e);const s=window.getComputedStyle(t).getPropertyValue(e);t.style.setProperty(e,`${i(Number.parseFloat(s))}px`)}))}_saveInitialAttribute(t,e){const i=t.style.getPropertyValue(e);i&&F.setDataAttribute(t,e,i)}_resetElementAttributes(t,e){this._applyManipulationCallback(t,(t=>{const i=F.getDataAttribute(t,e);null!==i?(F.removeDataAttribute(t,e),t.style.setProperty(e,i)):t.style.removeProperty(e)}))}_applyManipulationCallback(t,e){if(o(t))e(t);else for(const i of z.find(t,this._element))e(i)}}const un=".bs.modal",fn=`hide${un}`,pn=`hidePrevented${un}`,mn=`hidden${un}`,gn=`show${un}`,_n=`shown${un}`,bn=`resize${un}`,vn=`click.dismiss${un}`,yn=`mousedown.dismiss${un}`,wn=`keydown.dismiss${un}`,An=`click${un}.data-api`,En="modal-open",Tn="show",Cn="modal-static",On={backdrop:!0,focus:!0,keyboard:!0},xn={backdrop:"(boolean|string)",focus:"boolean",keyboard:"boolean"};class kn extends W{constructor(t,e){super(t,e),this._dialog=z.findOne(".modal-dialog",this._element),this._backdrop=this._initializeBackDrop(),this._focustrap=this._initializeFocusTrap(),this._isShown=!1,this._isTransitioning=!1,this._scrollBar=new dn,this._addEventListeners()}static get Default(){return On}static get DefaultType(){return xn}static get NAME(){return"modal"}toggle(t){return this._isShown?this.hide():this.show(t)}show(t){this._isShown||this._isTransitioning||N.trigger(this._element,gn,{relatedTarget:t}).defaultPrevented||(this._isShown=!0,this._isTransitioning=!0,this._scrollBar.hide(),document.body.classList.add(En),this._adjustDialog(),this._backdrop.show((()=>this._showElement(t))))}hide(){this._isShown&&!this._isTransitioning&&(N.trigger(this._element,fn).defaultPrevented||(this._isShown=!1,this._isTransitioning=!0,this._focustrap.deactivate(),this._element.classList.remove(Tn),this._queueCallback((()=>this._hideModal()),this._element,this._isAnimated())))}dispose(){N.off(window,un),N.off(this._dialog,un),this._backdrop.dispose(),this._focustrap.deactivate(),super.dispose()}handleUpdate(){this._adjustDialog()}_initializeBackDrop(){return new Ji({isVisible:Boolean(this._config.backdrop),isAnimated:this._isAnimated()})}_initializeFocusTrap(){return new rn({trapElement:this._element})}_showElement(t){document.body.contains(this._element)||document.body.append(this._element),this._element.style.display="block",this._element.removeAttribute("aria-hidden"),this._element.setAttribute("aria-modal",!0),this._element.setAttribute("role","dialog"),this._element.scrollTop=0;const e=z.findOne(".modal-body",this._dialog);e&&(e.scrollTop=0),d(this._element),this._element.classList.add(Tn),this._queueCallback((()=>{this._config.focus&&this._focustrap.activate(),this._isTransitioning=!1,N.trigger(this._element,_n,{relatedTarget:t})}),this._dialog,this._isAnimated())}_addEventListeners(){N.on(this._element,wn,(t=>{"Escape"===t.key&&(this._config.keyboard?this.hide():this._triggerBackdropTransition())})),N.on(window,bn,(()=>{this._isShown&&!this._isTransitioning&&this._adjustDialog()})),N.on(this._element,yn,(t=>{N.one(this._element,vn,(e=>{this._element===t.target&&this._element===e.target&&("static"!==this._config.backdrop?this._config.backdrop&&this.hide():this._triggerBackdropTransition())}))}))}_hideModal(){this._element.style.display="none",this._element.setAttribute("aria-hidden",!0),this._element.removeAttribute("aria-modal"),this._element.removeAttribute("role"),this._isTransitioning=!1,this._backdrop.hide((()=>{document.body.classList.remove(En),this._resetAdjustments(),this._scrollBar.reset(),N.trigger(this._element,mn)}))}_isAnimated(){return this._element.classList.contains("fade")}_triggerBackdropTransition(){if(N.trigger(this._element,pn).defaultPrevented)return;const t=this._element.scrollHeight>document.documentElement.clientHeight,e=this._element.style.overflowY;"hidden"===e||this._element.classList.contains(Cn)||(t||(this._element.style.overflowY="hidden"),this._element.classList.add(Cn),this._queueCallback((()=>{this._element.classList.remove(Cn),this._queueCallback((()=>{this._element.style.overflowY=e}),this._dialog)}),this._dialog),this._element.focus())}_adjustDialog(){const t=this._element.scrollHeight>document.documentElement.clientHeight,e=this._scrollBar.getWidth(),i=e>0;if(i&&!t){const t=p()?"paddingLeft":"paddingRight";this._element.style[t]=`${e}px`}if(!i&&t){const t=p()?"paddingRight":"paddingLeft";this._element.style[t]=`${e}px`}}_resetAdjustments(){this._element.style.paddingLeft="",this._element.style.paddingRight=""}static jQueryInterface(t,e){return this.each((function(){const i=kn.getOrCreateInstance(this,t);if("string"==typeof t){if(void 0===i[t])throw new TypeError(`No method named "${t}"`);i[t](e)}}))}}N.on(document,An,'[data-bs-toggle="modal"]',(function(t){const e=z.getElementFromSelector(this);["A","AREA"].includes(this.tagName)&&t.preventDefault(),N.one(e,gn,(t=>{t.defaultPrevented||N.one(e,mn,(()=>{a(this)&&this.focus()}))}));const i=z.findOne(".modal.show");i&&kn.getInstance(i).hide(),kn.getOrCreateInstance(e).toggle(this)})),R(kn),m(kn);const Ln=".bs.offcanvas",Sn=".data-api",Dn=`load${Ln}${Sn}`,$n="show",In="showing",Nn="hiding",Pn=".offcanvas.show",jn=`show${Ln}`,Mn=`shown${Ln}`,Fn=`hide${Ln}`,Hn=`hidePrevented${Ln}`,Wn=`hidden${Ln}`,Bn=`resize${Ln}`,zn=`click${Ln}${Sn}`,Rn=`keydown.dismiss${Ln}`,qn={backdrop:!0,keyboard:!0,scroll:!1},Vn={backdrop:"(boolean|string)",keyboard:"boolean",scroll:"boolean"};class Kn extends W{constructor(t,e){super(t,e),this._isShown=!1,this._backdrop=this._initializeBackDrop(),this._focustrap=this._initializeFocusTrap(),this._addEventListeners()}static get Default(){return qn}static get DefaultType(){return Vn}static get NAME(){return"offcanvas"}toggle(t){return this._isShown?this.hide():this.show(t)}show(t){this._isShown||N.trigger(this._element,jn,{relatedTarget:t}).defaultPrevented||(this._isShown=!0,this._backdrop.show(),this._config.scroll||(new dn).hide(),this._element.setAttribute("aria-modal",!0),this._element.setAttribute("role","dialog"),this._element.classList.add(In),this._queueCallback((()=>{this._config.scroll&&!this._config.backdrop||this._focustrap.activate(),this._element.classList.add($n),this._element.classList.remove(In),N.trigger(this._element,Mn,{relatedTarget:t})}),this._element,!0))}hide(){this._isShown&&(N.trigger(this._element,Fn).defaultPrevented||(this._focustrap.deactivate(),this._element.blur(),this._isShown=!1,this._element.classList.add(Nn),this._backdrop.hide(),this._queueCallback((()=>{this._element.classList.remove($n,Nn),this._element.removeAttribute("aria-modal"),this._element.removeAttribute("role"),this._config.scroll||(new dn).reset(),N.trigger(this._element,Wn)}),this._element,!0)))}dispose(){this._backdrop.dispose(),this._focustrap.deactivate(),super.dispose()}_initializeBackDrop(){const t=Boolean(this._config.backdrop);return new Ji({className:"offcanvas-backdrop",isVisible:t,isAnimated:!0,rootElement:this._element.parentNode,clickCallback:t?()=>{"static"!==this._config.backdrop?this.hide():N.trigger(this._element,Hn)}:null})}_initializeFocusTrap(){return new rn({trapElement:this._element})}_addEventListeners(){N.on(this._element,Rn,(t=>{"Escape"===t.key&&(this._config.keyboard?this.hide():N.trigger(this._element,Hn))}))}static jQueryInterface(t){return this.each((function(){const e=Kn.getOrCreateInstance(this,t);if("string"==typeof t){if(void 0===e[t]||t.startsWith("_")||"constructor"===t)throw new TypeError(`No method named "${t}"`);e[t](this)}}))}}N.on(document,zn,'[data-bs-toggle="offcanvas"]',(function(t){const e=z.getElementFromSelector(this);if(["A","AREA"].includes(this.tagName)&&t.preventDefault(),l(this))return;N.one(e,Wn,(()=>{a(this)&&this.focus()}));const i=z.findOne(Pn);i&&i!==e&&Kn.getInstance(i).hide(),Kn.getOrCreateInstance(e).toggle(this)})),N.on(window,Dn,(()=>{for(const t of z.find(Pn))Kn.getOrCreateInstance(t).show()})),N.on(window,Bn,(()=>{for(const t of z.find("[aria-modal][class*=show][class*=offcanvas-]"))"fixed"!==getComputedStyle(t).position&&Kn.getOrCreateInstance(t).hide()})),R(Kn),m(Kn);const Qn={"*":["class","dir","id","lang","role",/^aria-[\w-]*$/i],a:["target","href","title","rel"],area:[],b:[],br:[],col:[],code:[],dd:[],div:[],dl:[],dt:[],em:[],hr:[],h1:[],h2:[],h3:[],h4:[],h5:[],h6:[],i:[],img:["src","srcset","alt","title","width","height"],li:[],ol:[],p:[],pre:[],s:[],small:[],span:[],sub:[],sup:[],strong:[],u:[],ul:[]},Xn=new Set(["background","cite","href","itemtype","longdesc","poster","src","xlink:href"]),Yn=/^(?!javascript:)(?:[a-z0-9+.-]+:|[^&:/?#]*(?:[/?#]|$))/i,Un=(t,e)=>{const i=t.nodeName.toLowerCase();return e.includes(i)?!Xn.has(i)||Boolean(Yn.test(t.nodeValue)):e.filter((t=>t instanceof RegExp)).some((t=>t.test(i)))},Gn={allowList:Qn,content:{},extraClass:"",html:!1,sanitize:!0,sanitizeFn:null,template:"
"},Jn={allowList:"object",content:"object",extraClass:"(string|function)",html:"boolean",sanitize:"boolean",sanitizeFn:"(null|function)",template:"string"},Zn={entry:"(string|element|function|null)",selector:"(string|element)"};class ts extends H{constructor(t){super(),this._config=this._getConfig(t)}static get Default(){return Gn}static get DefaultType(){return Jn}static get NAME(){return"TemplateFactory"}getContent(){return Object.values(this._config.content).map((t=>this._resolvePossibleFunction(t))).filter(Boolean)}hasContent(){return this.getContent().length>0}changeContent(t){return this._checkContent(t),this._config.content={...this._config.content,...t},this}toHtml(){const t=document.createElement("div");t.innerHTML=this._maybeSanitize(this._config.template);for(const[e,i]of Object.entries(this._config.content))this._setContent(t,i,e);const e=t.children[0],i=this._resolvePossibleFunction(this._config.extraClass);return i&&e.classList.add(...i.split(" ")),e}_typeCheckConfig(t){super._typeCheckConfig(t),this._checkContent(t.content)}_checkContent(t){for(const[e,i]of Object.entries(t))super._typeCheckConfig({selector:e,entry:i},Zn)}_setContent(t,e,i){const n=z.findOne(i,t);n&&((e=this._resolvePossibleFunction(e))?o(e)?this._putElementInTemplate(r(e),n):this._config.html?n.innerHTML=this._maybeSanitize(e):n.textContent=e:n.remove())}_maybeSanitize(t){return this._config.sanitize?function(t,e,i){if(!t.length)return t;if(i&&"function"==typeof i)return i(t);const n=(new window.DOMParser).parseFromString(t,"text/html"),s=[].concat(...n.body.querySelectorAll("*"));for(const t of s){const i=t.nodeName.toLowerCase();if(!Object.keys(e).includes(i)){t.remove();continue}const n=[].concat(...t.attributes),s=[].concat(e["*"]||[],e[i]||[]);for(const e of n)Un(e,s)||t.removeAttribute(e.nodeName)}return n.body.innerHTML}(t,this._config.allowList,this._config.sanitizeFn):t}_resolvePossibleFunction(t){return g(t,[void 0,this])}_putElementInTemplate(t,e){if(this._config.html)return e.innerHTML="",void e.append(t);e.textContent=t.textContent}}const es=new Set(["sanitize","allowList","sanitizeFn"]),is="fade",ns="show",ss=".tooltip-inner",os=".modal",rs="hide.bs.modal",as="hover",ls="focus",cs={AUTO:"auto",TOP:"top",RIGHT:p()?"left":"right",BOTTOM:"bottom",LEFT:p()?"right":"left"},hs={allowList:Qn,animation:!0,boundary:"clippingParents",container:!1,customClass:"",delay:0,fallbackPlacements:["top","right","bottom","left"],html:!1,offset:[0,6],placement:"top",popperConfig:null,sanitize:!0,sanitizeFn:null,selector:!1,template:'',title:"",trigger:"hover focus"},ds={allowList:"object",animation:"boolean",boundary:"(string|element)",container:"(string|element|boolean)",customClass:"(string|function)",delay:"(number|object)",fallbackPlacements:"array",html:"boolean",offset:"(array|string|function)",placement:"(string|function)",popperConfig:"(null|object|function)",sanitize:"boolean",sanitizeFn:"(null|function)",selector:"(string|boolean)",template:"string",title:"(string|element|function)",trigger:"string"};class us extends W{constructor(t,e){if(void 0===wi)throw new TypeError("Bootstrap's tooltips require Popper (https://popper.js.org/docs/v2/)");super(t,e),this._isEnabled=!0,this._timeout=0,this._isHovered=null,this._activeTrigger={},this._popper=null,this._templateFactory=null,this._newContent=null,this.tip=null,this._setListeners(),this._config.selector||this._fixTitle()}static get Default(){return hs}static get DefaultType(){return ds}static get NAME(){return"tooltip"}enable(){this._isEnabled=!0}disable(){this._isEnabled=!1}toggleEnabled(){this._isEnabled=!this._isEnabled}toggle(){this._isEnabled&&(this._isShown()?this._leave():this._enter())}dispose(){clearTimeout(this._timeout),N.off(this._element.closest(os),rs,this._hideModalHandler),this._element.getAttribute("data-bs-original-title")&&this._element.setAttribute("title",this._element.getAttribute("data-bs-original-title")),this._disposePopper(),super.dispose()}show(){if("none"===this._element.style.display)throw new Error("Please use show on visible elements");if(!this._isWithContent()||!this._isEnabled)return;const t=N.trigger(this._element,this.constructor.eventName("show")),e=(c(this._element)||this._element.ownerDocument.documentElement).contains(this._element);if(t.defaultPrevented||!e)return;this._disposePopper();const i=this._getTipElement();this._element.setAttribute("aria-describedby",i.getAttribute("id"));const{container:n}=this._config;if(this._element.ownerDocument.documentElement.contains(this.tip)||(n.append(i),N.trigger(this._element,this.constructor.eventName("inserted"))),this._popper=this._createPopper(i),i.classList.add(ns),"ontouchstart"in document.documentElement)for(const t of[].concat(...document.body.children))N.on(t,"mouseover",h);this._queueCallback((()=>{N.trigger(this._element,this.constructor.eventName("shown")),!1===this._isHovered&&this._leave(),this._isHovered=!1}),this.tip,this._isAnimated())}hide(){if(this._isShown()&&!N.trigger(this._element,this.constructor.eventName("hide")).defaultPrevented){if(this._getTipElement().classList.remove(ns),"ontouchstart"in document.documentElement)for(const t of[].concat(...document.body.children))N.off(t,"mouseover",h);this._activeTrigger.click=!1,this._activeTrigger[ls]=!1,this._activeTrigger[as]=!1,this._isHovered=null,this._queueCallback((()=>{this._isWithActiveTrigger()||(this._isHovered||this._disposePopper(),this._element.removeAttribute("aria-describedby"),N.trigger(this._element,this.constructor.eventName("hidden")))}),this.tip,this._isAnimated())}}update(){this._popper&&this._popper.update()}_isWithContent(){return Boolean(this._getTitle())}_getTipElement(){return this.tip||(this.tip=this._createTipElement(this._newContent||this._getContentForTemplate())),this.tip}_createTipElement(t){const e=this._getTemplateFactory(t).toHtml();if(!e)return null;e.classList.remove(is,ns),e.classList.add(`bs-${this.constructor.NAME}-auto`);const i=(t=>{do{t+=Math.floor(1e6*Math.random())}while(document.getElementById(t));return t})(this.constructor.NAME).toString();return e.setAttribute("id",i),this._isAnimated()&&e.classList.add(is),e}setContent(t){this._newContent=t,this._isShown()&&(this._disposePopper(),this.show())}_getTemplateFactory(t){return this._templateFactory?this._templateFactory.changeContent(t):this._templateFactory=new ts({...this._config,content:t,extraClass:this._resolvePossibleFunction(this._config.customClass)}),this._templateFactory}_getContentForTemplate(){return{[ss]:this._getTitle()}}_getTitle(){return this._resolvePossibleFunction(this._config.title)||this._element.getAttribute("data-bs-original-title")}_initializeOnDelegatedTarget(t){return this.constructor.getOrCreateInstance(t.delegateTarget,this._getDelegateConfig())}_isAnimated(){return this._config.animation||this.tip&&this.tip.classList.contains(is)}_isShown(){return this.tip&&this.tip.classList.contains(ns)}_createPopper(t){const e=g(this._config.placement,[this,t,this._element]),i=cs[e.toUpperCase()];return yi(this._element,t,this._getPopperConfig(i))}_getOffset(){const{offset:t}=this._config;return"string"==typeof t?t.split(",").map((t=>Number.parseInt(t,10))):"function"==typeof t?e=>t(e,this._element):t}_resolvePossibleFunction(t){return g(t,[this._element,this._element])}_getPopperConfig(t){const e={placement:t,modifiers:[{name:"flip",options:{fallbackPlacements:this._config.fallbackPlacements}},{name:"offset",options:{offset:this._getOffset()}},{name:"preventOverflow",options:{boundary:this._config.boundary}},{name:"arrow",options:{element:`.${this.constructor.NAME}-arrow`}},{name:"preSetPlacement",enabled:!0,phase:"beforeMain",fn:t=>{this._getTipElement().setAttribute("data-popper-placement",t.state.placement)}}]};return{...e,...g(this._config.popperConfig,[void 0,e])}}_setListeners(){const t=this._config.trigger.split(" ");for(const e of t)if("click"===e)N.on(this._element,this.constructor.eventName("click"),this._config.selector,(t=>{this._initializeOnDelegatedTarget(t).toggle()}));else if("manual"!==e){const t=e===as?this.constructor.eventName("mouseenter"):this.constructor.eventName("focusin"),i=e===as?this.constructor.eventName("mouseleave"):this.constructor.eventName("focusout");N.on(this._element,t,this._config.selector,(t=>{const e=this._initializeOnDelegatedTarget(t);e._activeTrigger["focusin"===t.type?ls:as]=!0,e._enter()})),N.on(this._element,i,this._config.selector,(t=>{const e=this._initializeOnDelegatedTarget(t);e._activeTrigger["focusout"===t.type?ls:as]=e._element.contains(t.relatedTarget),e._leave()}))}this._hideModalHandler=()=>{this._element&&this.hide()},N.on(this._element.closest(os),rs,this._hideModalHandler)}_fixTitle(){const t=this._element.getAttribute("title");t&&(this._element.getAttribute("aria-label")||this._element.textContent.trim()||this._element.setAttribute("aria-label",t),this._element.setAttribute("data-bs-original-title",t),this._element.removeAttribute("title"))}_enter(){this._isShown()||this._isHovered?this._isHovered=!0:(this._isHovered=!0,this._setTimeout((()=>{this._isHovered&&this.show()}),this._config.delay.show))}_leave(){this._isWithActiveTrigger()||(this._isHovered=!1,this._setTimeout((()=>{this._isHovered||this.hide()}),this._config.delay.hide))}_setTimeout(t,e){clearTimeout(this._timeout),this._timeout=setTimeout(t,e)}_isWithActiveTrigger(){return Object.values(this._activeTrigger).includes(!0)}_getConfig(t){const e=F.getDataAttributes(this._element);for(const t of Object.keys(e))es.has(t)&&delete e[t];return t={...e,..."object"==typeof t&&t?t:{}},t=this._mergeConfigObj(t),t=this._configAfterMerge(t),this._typeCheckConfig(t),t}_configAfterMerge(t){return t.container=!1===t.container?document.body:r(t.container),"number"==typeof t.delay&&(t.delay={show:t.delay,hide:t.delay}),"number"==typeof t.title&&(t.title=t.title.toString()),"number"==typeof t.content&&(t.content=t.content.toString()),t}_getDelegateConfig(){const t={};for(const[e,i]of Object.entries(this._config))this.constructor.Default[e]!==i&&(t[e]=i);return t.selector=!1,t.trigger="manual",t}_disposePopper(){this._popper&&(this._popper.destroy(),this._popper=null),this.tip&&(this.tip.remove(),this.tip=null)}static jQueryInterface(t){return this.each((function(){const e=us.getOrCreateInstance(this,t);if("string"==typeof t){if(void 0===e[t])throw new TypeError(`No method named "${t}"`);e[t]()}}))}}m(us);const fs=".popover-header",ps=".popover-body",ms={...us.Default,content:"",offset:[0,8],placement:"right",template:'',trigger:"click"},gs={...us.DefaultType,content:"(null|string|element|function)"};class _s extends us{static get Default(){return ms}static get DefaultType(){return gs}static get NAME(){return"popover"}_isWithContent(){return this._getTitle()||this._getContent()}_getContentForTemplate(){return{[fs]:this._getTitle(),[ps]:this._getContent()}}_getContent(){return this._resolvePossibleFunction(this._config.content)}static jQueryInterface(t){return this.each((function(){const e=_s.getOrCreateInstance(this,t);if("string"==typeof t){if(void 0===e[t])throw new TypeError(`No method named "${t}"`);e[t]()}}))}}m(_s);const bs=".bs.scrollspy",vs=`activate${bs}`,ys=`click${bs}`,ws=`load${bs}.data-api`,As="active",Es="[href]",Ts=".nav-link",Cs=`${Ts}, .nav-item > ${Ts}, .list-group-item`,Os={offset:null,rootMargin:"0px 0px -25%",smoothScroll:!1,target:null,threshold:[.1,.5,1]},xs={offset:"(number|null)",rootMargin:"string",smoothScroll:"boolean",target:"element",threshold:"array"};class ks extends W{constructor(t,e){super(t,e),this._targetLinks=new Map,this._observableSections=new Map,this._rootElement="visible"===getComputedStyle(this._element).overflowY?null:this._element,this._activeTarget=null,this._observer=null,this._previousScrollData={visibleEntryTop:0,parentScrollTop:0},this.refresh()}static get Default(){return Os}static get DefaultType(){return xs}static get NAME(){return"scrollspy"}refresh(){this._initializeTargetsAndObservables(),this._maybeEnableSmoothScroll(),this._observer?this._observer.disconnect():this._observer=this._getNewObserver();for(const t of this._observableSections.values())this._observer.observe(t)}dispose(){this._observer.disconnect(),super.dispose()}_configAfterMerge(t){return t.target=r(t.target)||document.body,t.rootMargin=t.offset?`${t.offset}px 0px -30%`:t.rootMargin,"string"==typeof t.threshold&&(t.threshold=t.threshold.split(",").map((t=>Number.parseFloat(t)))),t}_maybeEnableSmoothScroll(){this._config.smoothScroll&&(N.off(this._config.target,ys),N.on(this._config.target,ys,Es,(t=>{const e=this._observableSections.get(t.target.hash);if(e){t.preventDefault();const i=this._rootElement||window,n=e.offsetTop-this._element.offsetTop;if(i.scrollTo)return void i.scrollTo({top:n,behavior:"smooth"});i.scrollTop=n}})))}_getNewObserver(){const t={root:this._rootElement,threshold:this._config.threshold,rootMargin:this._config.rootMargin};return new IntersectionObserver((t=>this._observerCallback(t)),t)}_observerCallback(t){const e=t=>this._targetLinks.get(`#${t.target.id}`),i=t=>{this._previousScrollData.visibleEntryTop=t.target.offsetTop,this._process(e(t))},n=(this._rootElement||document.documentElement).scrollTop,s=n>=this._previousScrollData.parentScrollTop;this._previousScrollData.parentScrollTop=n;for(const o of t){if(!o.isIntersecting){this._activeTarget=null,this._clearActiveClass(e(o));continue}const t=o.target.offsetTop>=this._previousScrollData.visibleEntryTop;if(s&&t){if(i(o),!n)return}else s||t||i(o)}}_initializeTargetsAndObservables(){this._targetLinks=new Map,this._observableSections=new Map;const t=z.find(Es,this._config.target);for(const e of t){if(!e.hash||l(e))continue;const t=z.findOne(decodeURI(e.hash),this._element);a(t)&&(this._targetLinks.set(decodeURI(e.hash),e),this._observableSections.set(e.hash,t))}}_process(t){this._activeTarget!==t&&(this._clearActiveClass(this._config.target),this._activeTarget=t,t.classList.add(As),this._activateParents(t),N.trigger(this._element,vs,{relatedTarget:t}))}_activateParents(t){if(t.classList.contains("dropdown-item"))z.findOne(".dropdown-toggle",t.closest(".dropdown")).classList.add(As);else for(const e of z.parents(t,".nav, .list-group"))for(const t of z.prev(e,Cs))t.classList.add(As)}_clearActiveClass(t){t.classList.remove(As);const e=z.find(`${Es}.${As}`,t);for(const t of e)t.classList.remove(As)}static jQueryInterface(t){return this.each((function(){const e=ks.getOrCreateInstance(this,t);if("string"==typeof t){if(void 0===e[t]||t.startsWith("_")||"constructor"===t)throw new TypeError(`No method named "${t}"`);e[t]()}}))}}N.on(window,ws,(()=>{for(const t of z.find('[data-bs-spy="scroll"]'))ks.getOrCreateInstance(t)})),m(ks);const Ls=".bs.tab",Ss=`hide${Ls}`,Ds=`hidden${Ls}`,$s=`show${Ls}`,Is=`shown${Ls}`,Ns=`click${Ls}`,Ps=`keydown${Ls}`,js=`load${Ls}`,Ms="ArrowLeft",Fs="ArrowRight",Hs="ArrowUp",Ws="ArrowDown",Bs="Home",zs="End",Rs="active",qs="fade",Vs="show",Ks=".dropdown-toggle",Qs=`:not(${Ks})`,Xs='[data-bs-toggle="tab"], [data-bs-toggle="pill"], [data-bs-toggle="list"]',Ys=`.nav-link${Qs}, .list-group-item${Qs}, [role="tab"]${Qs}, ${Xs}`,Us=`.${Rs}[data-bs-toggle="tab"], .${Rs}[data-bs-toggle="pill"], .${Rs}[data-bs-toggle="list"]`;class Gs extends W{constructor(t){super(t),this._parent=this._element.closest('.list-group, .nav, [role="tablist"]'),this._parent&&(this._setInitialAttributes(this._parent,this._getChildren()),N.on(this._element,Ps,(t=>this._keydown(t))))}static get NAME(){return"tab"}show(){const t=this._element;if(this._elemIsActive(t))return;const e=this._getActiveElem(),i=e?N.trigger(e,Ss,{relatedTarget:t}):null;N.trigger(t,$s,{relatedTarget:e}).defaultPrevented||i&&i.defaultPrevented||(this._deactivate(e,t),this._activate(t,e))}_activate(t,e){t&&(t.classList.add(Rs),this._activate(z.getElementFromSelector(t)),this._queueCallback((()=>{"tab"===t.getAttribute("role")?(t.removeAttribute("tabindex"),t.setAttribute("aria-selected",!0),this._toggleDropDown(t,!0),N.trigger(t,Is,{relatedTarget:e})):t.classList.add(Vs)}),t,t.classList.contains(qs)))}_deactivate(t,e){t&&(t.classList.remove(Rs),t.blur(),this._deactivate(z.getElementFromSelector(t)),this._queueCallback((()=>{"tab"===t.getAttribute("role")?(t.setAttribute("aria-selected",!1),t.setAttribute("tabindex","-1"),this._toggleDropDown(t,!1),N.trigger(t,Ds,{relatedTarget:e})):t.classList.remove(Vs)}),t,t.classList.contains(qs)))}_keydown(t){if(![Ms,Fs,Hs,Ws,Bs,zs].includes(t.key))return;t.stopPropagation(),t.preventDefault();const e=this._getChildren().filter((t=>!l(t)));let i;if([Bs,zs].includes(t.key))i=e[t.key===Bs?0:e.length-1];else{const n=[Fs,Ws].includes(t.key);i=b(e,t.target,n,!0)}i&&(i.focus({preventScroll:!0}),Gs.getOrCreateInstance(i).show())}_getChildren(){return z.find(Ys,this._parent)}_getActiveElem(){return this._getChildren().find((t=>this._elemIsActive(t)))||null}_setInitialAttributes(t,e){this._setAttributeIfNotExists(t,"role","tablist");for(const t of e)this._setInitialAttributesOnChild(t)}_setInitialAttributesOnChild(t){t=this._getInnerElement(t);const e=this._elemIsActive(t),i=this._getOuterElement(t);t.setAttribute("aria-selected",e),i!==t&&this._setAttributeIfNotExists(i,"role","presentation"),e||t.setAttribute("tabindex","-1"),this._setAttributeIfNotExists(t,"role","tab"),this._setInitialAttributesOnTargetPanel(t)}_setInitialAttributesOnTargetPanel(t){const e=z.getElementFromSelector(t);e&&(this._setAttributeIfNotExists(e,"role","tabpanel"),t.id&&this._setAttributeIfNotExists(e,"aria-labelledby",`${t.id}`))}_toggleDropDown(t,e){const i=this._getOuterElement(t);if(!i.classList.contains("dropdown"))return;const n=(t,n)=>{const s=z.findOne(t,i);s&&s.classList.toggle(n,e)};n(Ks,Rs),n(".dropdown-menu",Vs),i.setAttribute("aria-expanded",e)}_setAttributeIfNotExists(t,e,i){t.hasAttribute(e)||t.setAttribute(e,i)}_elemIsActive(t){return t.classList.contains(Rs)}_getInnerElement(t){return t.matches(Ys)?t:z.findOne(Ys,t)}_getOuterElement(t){return t.closest(".nav-item, .list-group-item")||t}static jQueryInterface(t){return this.each((function(){const e=Gs.getOrCreateInstance(this);if("string"==typeof t){if(void 0===e[t]||t.startsWith("_")||"constructor"===t)throw new TypeError(`No method named "${t}"`);e[t]()}}))}}N.on(document,Ns,Xs,(function(t){["A","AREA"].includes(this.tagName)&&t.preventDefault(),l(this)||Gs.getOrCreateInstance(this).show()})),N.on(window,js,(()=>{for(const t of z.find(Us))Gs.getOrCreateInstance(t)})),m(Gs);const Js=".bs.toast",Zs=`mouseover${Js}`,to=`mouseout${Js}`,eo=`focusin${Js}`,io=`focusout${Js}`,no=`hide${Js}`,so=`hidden${Js}`,oo=`show${Js}`,ro=`shown${Js}`,ao="hide",lo="show",co="showing",ho={animation:"boolean",autohide:"boolean",delay:"number"},uo={animation:!0,autohide:!0,delay:5e3};class fo extends W{constructor(t,e){super(t,e),this._timeout=null,this._hasMouseInteraction=!1,this._hasKeyboardInteraction=!1,this._setListeners()}static get Default(){return uo}static get DefaultType(){return ho}static get NAME(){return"toast"}show(){N.trigger(this._element,oo).defaultPrevented||(this._clearTimeout(),this._config.animation&&this._element.classList.add("fade"),this._element.classList.remove(ao),d(this._element),this._element.classList.add(lo,co),this._queueCallback((()=>{this._element.classList.remove(co),N.trigger(this._element,ro),this._maybeScheduleHide()}),this._element,this._config.animation))}hide(){this.isShown()&&(N.trigger(this._element,no).defaultPrevented||(this._element.classList.add(co),this._queueCallback((()=>{this._element.classList.add(ao),this._element.classList.remove(co,lo),N.trigger(this._element,so)}),this._element,this._config.animation)))}dispose(){this._clearTimeout(),this.isShown()&&this._element.classList.remove(lo),super.dispose()}isShown(){return this._element.classList.contains(lo)}_maybeScheduleHide(){this._config.autohide&&(this._hasMouseInteraction||this._hasKeyboardInteraction||(this._timeout=setTimeout((()=>{this.hide()}),this._config.delay)))}_onInteraction(t,e){switch(t.type){case"mouseover":case"mouseout":this._hasMouseInteraction=e;break;case"focusin":case"focusout":this._hasKeyboardInteraction=e}if(e)return void this._clearTimeout();const i=t.relatedTarget;this._element===i||this._element.contains(i)||this._maybeScheduleHide()}_setListeners(){N.on(this._element,Zs,(t=>this._onInteraction(t,!0))),N.on(this._element,to,(t=>this._onInteraction(t,!1))),N.on(this._element,eo,(t=>this._onInteraction(t,!0))),N.on(this._element,io,(t=>this._onInteraction(t,!1)))}_clearTimeout(){clearTimeout(this._timeout),this._timeout=null}static jQueryInterface(t){return this.each((function(){const e=fo.getOrCreateInstance(this,t);if("string"==typeof t){if(void 0===e[t])throw new TypeError(`No method named "${t}"`);e[t](this)}}))}}return R(fo),m(fo),{Alert:Q,Button:Y,Carousel:Lt,Collapse:Rt,Dropdown:Ki,Modal:kn,Offcanvas:Kn,Popover:_s,ScrollSpy:ks,Tab:Gs,Toast:fo,Tooltip:us}})); -//# sourceMappingURL=bootstrap.bundle.min.js.map \ No newline at end of file diff --git a/backend/coverage-report/_js/d3.min.js b/backend/coverage-report/_js/d3.min.js deleted file mode 100644 index 16648730..00000000 --- a/backend/coverage-report/_js/d3.min.js +++ /dev/null @@ -1,5 +0,0 @@ -!function(){function n(n){return n&&(n.ownerDocument||n.document||n).documentElement}function t(n){return n&&(n.ownerDocument&&n.ownerDocument.defaultView||n.document&&n||n.defaultView)}function e(n,t){return t>n?-1:n>t?1:n>=t?0:NaN}function r(n){return null===n?NaN:+n}function i(n){return!isNaN(n)}function u(n){return{left:function(t,e,r,i){for(arguments.length<3&&(r=0),arguments.length<4&&(i=t.length);i>r;){var u=r+i>>>1;n(t[u],e)<0?r=u+1:i=u}return r},right:function(t,e,r,i){for(arguments.length<3&&(r=0),arguments.length<4&&(i=t.length);i>r;){var u=r+i>>>1;n(t[u],e)>0?i=u:r=u+1}return r}}}function o(n){return n.length}function a(n){for(var t=1;n*t%1;)t*=10;return t}function l(n,t){for(var e in t)Object.defineProperty(n.prototype,e,{value:t[e],enumerable:!1})}function c(){this._=Object.create(null)}function f(n){return(n+="")===bo||n[0]===_o?_o+n:n}function s(n){return(n+="")[0]===_o?n.slice(1):n}function h(n){return f(n)in this._}function p(n){return(n=f(n))in this._&&delete this._[n]}function g(){var n=[];for(var t in this._)n.push(s(t));return n}function v(){var n=0;for(var t in this._)++n;return n}function d(){for(var n in this._)return!1;return!0}function y(){this._=Object.create(null)}function m(n){return n}function M(n,t,e){return function(){var r=e.apply(t,arguments);return r===t?n:r}}function x(n,t){if(t in n)return t;t=t.charAt(0).toUpperCase()+t.slice(1);for(var e=0,r=wo.length;r>e;++e){var i=wo[e]+t;if(i in n)return i}}function b(){}function _(){}function w(n){function t(){for(var t,r=e,i=-1,u=r.length;++ie;e++)for(var i,u=n[e],o=0,a=u.length;a>o;o++)(i=u[o])&&t(i,o,e);return n}function Z(n){return ko(n,qo),n}function V(n){var t,e;return function(r,i,u){var o,a=n[u].update,l=a.length;for(u!=e&&(e=u,t=0),i>=t&&(t=i+1);!(o=a[t])&&++t0&&(n=n.slice(0,a));var c=To.get(n);return c&&(n=c,l=B),a?t?i:r:t?b:u}function $(n,t){return function(e){var r=ao.event;ao.event=e,t[0]=this.__data__;try{n.apply(this,t)}finally{ao.event=r}}}function B(n,t){var e=$(n,t);return function(n){var t=this,r=n.relatedTarget;r&&(r===t||8&r.compareDocumentPosition(t))||e.call(t,n)}}function W(e){var r=".dragsuppress-"+ ++Do,i="click"+r,u=ao.select(t(e)).on("touchmove"+r,S).on("dragstart"+r,S).on("selectstart"+r,S);if(null==Ro&&(Ro="onselectstart"in e?!1:x(e.style,"userSelect")),Ro){var o=n(e).style,a=o[Ro];o[Ro]="none"}return function(n){if(u.on(r,null),Ro&&(o[Ro]=a),n){var t=function(){u.on(i,null)};u.on(i,function(){S(),t()},!0),setTimeout(t,0)}}}function J(n,e){e.changedTouches&&(e=e.changedTouches[0]);var r=n.ownerSVGElement||n;if(r.createSVGPoint){var i=r.createSVGPoint();if(0>Po){var u=t(n);if(u.scrollX||u.scrollY){r=ao.select("body").append("svg").style({position:"absolute",top:0,left:0,margin:0,padding:0,border:"none"},"important");var o=r[0][0].getScreenCTM();Po=!(o.f||o.e),r.remove()}}return Po?(i.x=e.pageX,i.y=e.pageY):(i.x=e.clientX,i.y=e.clientY),i=i.matrixTransform(n.getScreenCTM().inverse()),[i.x,i.y]}var a=n.getBoundingClientRect();return[e.clientX-a.left-n.clientLeft,e.clientY-a.top-n.clientTop]}function G(){return ao.event.changedTouches[0].identifier}function K(n){return n>0?1:0>n?-1:0}function Q(n,t,e){return(t[0]-n[0])*(e[1]-n[1])-(t[1]-n[1])*(e[0]-n[0])}function nn(n){return n>1?0:-1>n?Fo:Math.acos(n)}function tn(n){return n>1?Io:-1>n?-Io:Math.asin(n)}function en(n){return((n=Math.exp(n))-1/n)/2}function rn(n){return((n=Math.exp(n))+1/n)/2}function un(n){return((n=Math.exp(2*n))-1)/(n+1)}function on(n){return(n=Math.sin(n/2))*n}function an(){}function ln(n,t,e){return this instanceof ln?(this.h=+n,this.s=+t,void(this.l=+e)):arguments.length<2?n instanceof ln?new ln(n.h,n.s,n.l):_n(""+n,wn,ln):new ln(n,t,e)}function cn(n,t,e){function r(n){return n>360?n-=360:0>n&&(n+=360),60>n?u+(o-u)*n/60:180>n?o:240>n?u+(o-u)*(240-n)/60:u}function i(n){return Math.round(255*r(n))}var u,o;return n=isNaN(n)?0:(n%=360)<0?n+360:n,t=isNaN(t)?0:0>t?0:t>1?1:t,e=0>e?0:e>1?1:e,o=.5>=e?e*(1+t):e+t-e*t,u=2*e-o,new mn(i(n+120),i(n),i(n-120))}function fn(n,t,e){return this instanceof fn?(this.h=+n,this.c=+t,void(this.l=+e)):arguments.length<2?n instanceof fn?new fn(n.h,n.c,n.l):n instanceof hn?gn(n.l,n.a,n.b):gn((n=Sn((n=ao.rgb(n)).r,n.g,n.b)).l,n.a,n.b):new fn(n,t,e)}function sn(n,t,e){return isNaN(n)&&(n=0),isNaN(t)&&(t=0),new hn(e,Math.cos(n*=Yo)*t,Math.sin(n)*t)}function hn(n,t,e){return this instanceof hn?(this.l=+n,this.a=+t,void(this.b=+e)):arguments.length<2?n instanceof hn?new hn(n.l,n.a,n.b):n instanceof fn?sn(n.h,n.c,n.l):Sn((n=mn(n)).r,n.g,n.b):new hn(n,t,e)}function pn(n,t,e){var r=(n+16)/116,i=r+t/500,u=r-e/200;return i=vn(i)*na,r=vn(r)*ta,u=vn(u)*ea,new mn(yn(3.2404542*i-1.5371385*r-.4985314*u),yn(-.969266*i+1.8760108*r+.041556*u),yn(.0556434*i-.2040259*r+1.0572252*u))}function gn(n,t,e){return n>0?new fn(Math.atan2(e,t)*Zo,Math.sqrt(t*t+e*e),n):new fn(NaN,NaN,n)}function vn(n){return n>.206893034?n*n*n:(n-4/29)/7.787037}function dn(n){return n>.008856?Math.pow(n,1/3):7.787037*n+4/29}function yn(n){return Math.round(255*(.00304>=n?12.92*n:1.055*Math.pow(n,1/2.4)-.055))}function mn(n,t,e){return this instanceof mn?(this.r=~~n,this.g=~~t,void(this.b=~~e)):arguments.length<2?n instanceof mn?new mn(n.r,n.g,n.b):_n(""+n,mn,cn):new mn(n,t,e)}function Mn(n){return new mn(n>>16,n>>8&255,255&n)}function xn(n){return Mn(n)+""}function bn(n){return 16>n?"0"+Math.max(0,n).toString(16):Math.min(255,n).toString(16)}function _n(n,t,e){var r,i,u,o=0,a=0,l=0;if(r=/([a-z]+)\((.*)\)/.exec(n=n.toLowerCase()))switch(i=r[2].split(","),r[1]){case"hsl":return e(parseFloat(i[0]),parseFloat(i[1])/100,parseFloat(i[2])/100);case"rgb":return t(Nn(i[0]),Nn(i[1]),Nn(i[2]))}return(u=ua.get(n))?t(u.r,u.g,u.b):(null==n||"#"!==n.charAt(0)||isNaN(u=parseInt(n.slice(1),16))||(4===n.length?(o=(3840&u)>>4,o=o>>4|o,a=240&u,a=a>>4|a,l=15&u,l=l<<4|l):7===n.length&&(o=(16711680&u)>>16,a=(65280&u)>>8,l=255&u)),t(o,a,l))}function wn(n,t,e){var r,i,u=Math.min(n/=255,t/=255,e/=255),o=Math.max(n,t,e),a=o-u,l=(o+u)/2;return a?(i=.5>l?a/(o+u):a/(2-o-u),r=n==o?(t-e)/a+(e>t?6:0):t==o?(e-n)/a+2:(n-t)/a+4,r*=60):(r=NaN,i=l>0&&1>l?0:r),new ln(r,i,l)}function Sn(n,t,e){n=kn(n),t=kn(t),e=kn(e);var r=dn((.4124564*n+.3575761*t+.1804375*e)/na),i=dn((.2126729*n+.7151522*t+.072175*e)/ta),u=dn((.0193339*n+.119192*t+.9503041*e)/ea);return hn(116*i-16,500*(r-i),200*(i-u))}function kn(n){return(n/=255)<=.04045?n/12.92:Math.pow((n+.055)/1.055,2.4)}function Nn(n){var t=parseFloat(n);return"%"===n.charAt(n.length-1)?Math.round(2.55*t):t}function En(n){return"function"==typeof n?n:function(){return n}}function An(n){return function(t,e,r){return 2===arguments.length&&"function"==typeof e&&(r=e,e=null),Cn(t,e,n,r)}}function Cn(n,t,e,r){function i(){var n,t=l.status;if(!t&&Ln(l)||t>=200&&300>t||304===t){try{n=e.call(u,l)}catch(r){return void o.error.call(u,r)}o.load.call(u,n)}else o.error.call(u,l)}var u={},o=ao.dispatch("beforesend","progress","load","error"),a={},l=new XMLHttpRequest,c=null;return!this.XDomainRequest||"withCredentials"in l||!/^(http(s)?:)?\/\//.test(n)||(l=new XDomainRequest),"onload"in l?l.onload=l.onerror=i:l.onreadystatechange=function(){l.readyState>3&&i()},l.onprogress=function(n){var t=ao.event;ao.event=n;try{o.progress.call(u,l)}finally{ao.event=t}},u.header=function(n,t){return n=(n+"").toLowerCase(),arguments.length<2?a[n]:(null==t?delete a[n]:a[n]=t+"",u)},u.mimeType=function(n){return arguments.length?(t=null==n?null:n+"",u):t},u.responseType=function(n){return arguments.length?(c=n,u):c},u.response=function(n){return e=n,u},["get","post"].forEach(function(n){u[n]=function(){return u.send.apply(u,[n].concat(co(arguments)))}}),u.send=function(e,r,i){if(2===arguments.length&&"function"==typeof r&&(i=r,r=null),l.open(e,n,!0),null==t||"accept"in a||(a.accept=t+",*/*"),l.setRequestHeader)for(var f in a)l.setRequestHeader(f,a[f]);return null!=t&&l.overrideMimeType&&l.overrideMimeType(t),null!=c&&(l.responseType=c),null!=i&&u.on("error",i).on("load",function(n){i(null,n)}),o.beforesend.call(u,l),l.send(null==r?null:r),u},u.abort=function(){return l.abort(),u},ao.rebind(u,o,"on"),null==r?u:u.get(zn(r))}function zn(n){return 1===n.length?function(t,e){n(null==t?e:null)}:n}function Ln(n){var t=n.responseType;return t&&"text"!==t?n.response:n.responseText}function qn(n,t,e){var r=arguments.length;2>r&&(t=0),3>r&&(e=Date.now());var i=e+t,u={c:n,t:i,n:null};return aa?aa.n=u:oa=u,aa=u,la||(ca=clearTimeout(ca),la=1,fa(Tn)),u}function Tn(){var n=Rn(),t=Dn()-n;t>24?(isFinite(t)&&(clearTimeout(ca),ca=setTimeout(Tn,t)),la=0):(la=1,fa(Tn))}function Rn(){for(var n=Date.now(),t=oa;t;)n>=t.t&&t.c(n-t.t)&&(t.c=null),t=t.n;return n}function Dn(){for(var n,t=oa,e=1/0;t;)t.c?(t.t8?function(n){return n/e}:function(n){return n*e},symbol:n}}function jn(n){var t=n.decimal,e=n.thousands,r=n.grouping,i=n.currency,u=r&&e?function(n,t){for(var i=n.length,u=[],o=0,a=r[0],l=0;i>0&&a>0&&(l+a+1>t&&(a=Math.max(1,t-l)),u.push(n.substring(i-=a,i+a)),!((l+=a+1)>t));)a=r[o=(o+1)%r.length];return u.reverse().join(e)}:m;return function(n){var e=ha.exec(n),r=e[1]||" ",o=e[2]||">",a=e[3]||"-",l=e[4]||"",c=e[5],f=+e[6],s=e[7],h=e[8],p=e[9],g=1,v="",d="",y=!1,m=!0;switch(h&&(h=+h.substring(1)),(c||"0"===r&&"="===o)&&(c=r="0",o="="),p){case"n":s=!0,p="g";break;case"%":g=100,d="%",p="f";break;case"p":g=100,d="%",p="r";break;case"b":case"o":case"x":case"X":"#"===l&&(v="0"+p.toLowerCase());case"c":m=!1;case"d":y=!0,h=0;break;case"s":g=-1,p="r"}"$"===l&&(v=i[0],d=i[1]),"r"!=p||h||(p="g"),null!=h&&("g"==p?h=Math.max(1,Math.min(21,h)):"e"!=p&&"f"!=p||(h=Math.max(0,Math.min(20,h)))),p=pa.get(p)||Fn;var M=c&&s;return function(n){var e=d;if(y&&n%1)return"";var i=0>n||0===n&&0>1/n?(n=-n,"-"):"-"===a?"":a;if(0>g){var l=ao.formatPrefix(n,h);n=l.scale(n),e=l.symbol+d}else n*=g;n=p(n,h);var x,b,_=n.lastIndexOf(".");if(0>_){var w=m?n.lastIndexOf("e"):-1;0>w?(x=n,b=""):(x=n.substring(0,w),b=n.substring(w))}else x=n.substring(0,_),b=t+n.substring(_+1);!c&&s&&(x=u(x,1/0));var S=v.length+x.length+b.length+(M?0:i.length),k=f>S?new Array(S=f-S+1).join(r):"";return M&&(x=u(k+x,k.length?f-b.length:1/0)),i+=v,n=x+b,("<"===o?i+n+k:">"===o?k+i+n:"^"===o?k.substring(0,S>>=1)+i+n+k.substring(S):i+(M?n:k+n))+e}}}function Fn(n){return n+""}function Hn(){this._=new Date(arguments.length>1?Date.UTC.apply(this,arguments):arguments[0])}function On(n,t,e){function r(t){var e=n(t),r=u(e,1);return r-t>t-e?e:r}function i(e){return t(e=n(new va(e-1)),1),e}function u(n,e){return t(n=new va(+n),e),n}function o(n,r,u){var o=i(n),a=[];if(u>1)for(;r>o;)e(o)%u||a.push(new Date(+o)),t(o,1);else for(;r>o;)a.push(new Date(+o)),t(o,1);return a}function a(n,t,e){try{va=Hn;var r=new Hn;return r._=n,o(r,t,e)}finally{va=Date}}n.floor=n,n.round=r,n.ceil=i,n.offset=u,n.range=o;var l=n.utc=In(n);return l.floor=l,l.round=In(r),l.ceil=In(i),l.offset=In(u),l.range=a,n}function In(n){return function(t,e){try{va=Hn;var r=new Hn;return r._=t,n(r,e)._}finally{va=Date}}}function Yn(n){function t(n){function t(t){for(var e,i,u,o=[],a=-1,l=0;++aa;){if(r>=c)return-1;if(i=t.charCodeAt(a++),37===i){if(o=t.charAt(a++),u=C[o in ya?t.charAt(a++):o],!u||(r=u(n,e,r))<0)return-1}else if(i!=e.charCodeAt(r++))return-1}return r}function r(n,t,e){_.lastIndex=0;var r=_.exec(t.slice(e));return r?(n.w=w.get(r[0].toLowerCase()),e+r[0].length):-1}function i(n,t,e){x.lastIndex=0;var r=x.exec(t.slice(e));return r?(n.w=b.get(r[0].toLowerCase()),e+r[0].length):-1}function u(n,t,e){N.lastIndex=0;var r=N.exec(t.slice(e));return r?(n.m=E.get(r[0].toLowerCase()),e+r[0].length):-1}function o(n,t,e){S.lastIndex=0;var r=S.exec(t.slice(e));return r?(n.m=k.get(r[0].toLowerCase()),e+r[0].length):-1}function a(n,t,r){return e(n,A.c.toString(),t,r)}function l(n,t,r){return e(n,A.x.toString(),t,r)}function c(n,t,r){return e(n,A.X.toString(),t,r)}function f(n,t,e){var r=M.get(t.slice(e,e+=2).toLowerCase());return null==r?-1:(n.p=r,e)}var s=n.dateTime,h=n.date,p=n.time,g=n.periods,v=n.days,d=n.shortDays,y=n.months,m=n.shortMonths;t.utc=function(n){function e(n){try{va=Hn;var t=new va;return t._=n,r(t)}finally{va=Date}}var r=t(n);return e.parse=function(n){try{va=Hn;var t=r.parse(n);return t&&t._}finally{va=Date}},e.toString=r.toString,e},t.multi=t.utc.multi=ct;var M=ao.map(),x=Vn(v),b=Xn(v),_=Vn(d),w=Xn(d),S=Vn(y),k=Xn(y),N=Vn(m),E=Xn(m);g.forEach(function(n,t){M.set(n.toLowerCase(),t)});var A={a:function(n){return d[n.getDay()]},A:function(n){return v[n.getDay()]},b:function(n){return m[n.getMonth()]},B:function(n){return y[n.getMonth()]},c:t(s),d:function(n,t){return Zn(n.getDate(),t,2)},e:function(n,t){return Zn(n.getDate(),t,2)},H:function(n,t){return Zn(n.getHours(),t,2)},I:function(n,t){return Zn(n.getHours()%12||12,t,2)},j:function(n,t){return Zn(1+ga.dayOfYear(n),t,3)},L:function(n,t){return Zn(n.getMilliseconds(),t,3)},m:function(n,t){return Zn(n.getMonth()+1,t,2)},M:function(n,t){return Zn(n.getMinutes(),t,2)},p:function(n){return g[+(n.getHours()>=12)]},S:function(n,t){return Zn(n.getSeconds(),t,2)},U:function(n,t){return Zn(ga.sundayOfYear(n),t,2)},w:function(n){return n.getDay()},W:function(n,t){return Zn(ga.mondayOfYear(n),t,2)},x:t(h),X:t(p),y:function(n,t){return Zn(n.getFullYear()%100,t,2)},Y:function(n,t){return Zn(n.getFullYear()%1e4,t,4)},Z:at,"%":function(){return"%"}},C={a:r,A:i,b:u,B:o,c:a,d:tt,e:tt,H:rt,I:rt,j:et,L:ot,m:nt,M:it,p:f,S:ut,U:Bn,w:$n,W:Wn,x:l,X:c,y:Gn,Y:Jn,Z:Kn,"%":lt};return t}function Zn(n,t,e){var r=0>n?"-":"",i=(r?-n:n)+"",u=i.length;return r+(e>u?new Array(e-u+1).join(t)+i:i)}function Vn(n){return new RegExp("^(?:"+n.map(ao.requote).join("|")+")","i")}function Xn(n){for(var t=new c,e=-1,r=n.length;++e68?1900:2e3)}function nt(n,t,e){ma.lastIndex=0;var r=ma.exec(t.slice(e,e+2));return r?(n.m=r[0]-1,e+r[0].length):-1}function tt(n,t,e){ma.lastIndex=0;var r=ma.exec(t.slice(e,e+2));return r?(n.d=+r[0],e+r[0].length):-1}function et(n,t,e){ma.lastIndex=0;var r=ma.exec(t.slice(e,e+3));return r?(n.j=+r[0],e+r[0].length):-1}function rt(n,t,e){ma.lastIndex=0;var r=ma.exec(t.slice(e,e+2));return r?(n.H=+r[0],e+r[0].length):-1}function it(n,t,e){ma.lastIndex=0;var r=ma.exec(t.slice(e,e+2));return r?(n.M=+r[0],e+r[0].length):-1}function ut(n,t,e){ma.lastIndex=0;var r=ma.exec(t.slice(e,e+2));return r?(n.S=+r[0],e+r[0].length):-1}function ot(n,t,e){ma.lastIndex=0;var r=ma.exec(t.slice(e,e+3));return r?(n.L=+r[0],e+r[0].length):-1}function at(n){var t=n.getTimezoneOffset(),e=t>0?"-":"+",r=xo(t)/60|0,i=xo(t)%60;return e+Zn(r,"0",2)+Zn(i,"0",2)}function lt(n,t,e){Ma.lastIndex=0;var r=Ma.exec(t.slice(e,e+1));return r?e+r[0].length:-1}function ct(n){for(var t=n.length,e=-1;++e=0?1:-1,a=o*e,l=Math.cos(t),c=Math.sin(t),f=u*c,s=i*l+f*Math.cos(a),h=f*o*Math.sin(a);ka.add(Math.atan2(h,s)),r=n,i=l,u=c}var t,e,r,i,u;Na.point=function(o,a){Na.point=n,r=(t=o)*Yo,i=Math.cos(a=(e=a)*Yo/2+Fo/4),u=Math.sin(a)},Na.lineEnd=function(){n(t,e)}}function dt(n){var t=n[0],e=n[1],r=Math.cos(e);return[r*Math.cos(t),r*Math.sin(t),Math.sin(e)]}function yt(n,t){return n[0]*t[0]+n[1]*t[1]+n[2]*t[2]}function mt(n,t){return[n[1]*t[2]-n[2]*t[1],n[2]*t[0]-n[0]*t[2],n[0]*t[1]-n[1]*t[0]]}function Mt(n,t){n[0]+=t[0],n[1]+=t[1],n[2]+=t[2]}function xt(n,t){return[n[0]*t,n[1]*t,n[2]*t]}function bt(n){var t=Math.sqrt(n[0]*n[0]+n[1]*n[1]+n[2]*n[2]);n[0]/=t,n[1]/=t,n[2]/=t}function _t(n){return[Math.atan2(n[1],n[0]),tn(n[2])]}function wt(n,t){return xo(n[0]-t[0])a;++a)i.point((e=n[a])[0],e[1]);return void i.lineEnd()}var l=new Tt(e,n,null,!0),c=new Tt(e,null,l,!1);l.o=c,u.push(l),o.push(c),l=new Tt(r,n,null,!1),c=new Tt(r,null,l,!0),l.o=c,u.push(l),o.push(c)}}),o.sort(t),qt(u),qt(o),u.length){for(var a=0,l=e,c=o.length;c>a;++a)o[a].e=l=!l;for(var f,s,h=u[0];;){for(var p=h,g=!0;p.v;)if((p=p.n)===h)return;f=p.z,i.lineStart();do{if(p.v=p.o.v=!0,p.e){if(g)for(var a=0,c=f.length;c>a;++a)i.point((s=f[a])[0],s[1]);else r(p.x,p.n.x,1,i);p=p.n}else{if(g){f=p.p.z;for(var a=f.length-1;a>=0;--a)i.point((s=f[a])[0],s[1])}else r(p.x,p.p.x,-1,i);p=p.p}p=p.o,f=p.z,g=!g}while(!p.v);i.lineEnd()}}}function qt(n){if(t=n.length){for(var t,e,r=0,i=n[0];++r0){for(b||(u.polygonStart(),b=!0),u.lineStart();++o1&&2&t&&e.push(e.pop().concat(e.shift())),p.push(e.filter(Dt))}var p,g,v,d=t(u),y=i.invert(r[0],r[1]),m={point:o,lineStart:l,lineEnd:c,polygonStart:function(){m.point=f,m.lineStart=s,m.lineEnd=h,p=[],g=[]},polygonEnd:function(){m.point=o,m.lineStart=l,m.lineEnd=c,p=ao.merge(p);var n=Ot(y,g);p.length?(b||(u.polygonStart(),b=!0),Lt(p,Ut,n,e,u)):n&&(b||(u.polygonStart(),b=!0),u.lineStart(),e(null,null,1,u),u.lineEnd()),b&&(u.polygonEnd(),b=!1),p=g=null},sphere:function(){u.polygonStart(),u.lineStart(),e(null,null,1,u),u.lineEnd(),u.polygonEnd()}},M=Pt(),x=t(M),b=!1;return m}}function Dt(n){return n.length>1}function Pt(){var n,t=[];return{lineStart:function(){t.push(n=[])},point:function(t,e){n.push([t,e])},lineEnd:b,buffer:function(){var e=t;return t=[],n=null,e},rejoin:function(){t.length>1&&t.push(t.pop().concat(t.shift()))}}}function Ut(n,t){return((n=n.x)[0]<0?n[1]-Io-Uo:Io-n[1])-((t=t.x)[0]<0?t[1]-Io-Uo:Io-t[1])}function jt(n){var t,e=NaN,r=NaN,i=NaN;return{lineStart:function(){n.lineStart(),t=1},point:function(u,o){var a=u>0?Fo:-Fo,l=xo(u-e);xo(l-Fo)0?Io:-Io),n.point(i,r),n.lineEnd(),n.lineStart(),n.point(a,r),n.point(u,r),t=0):i!==a&&l>=Fo&&(xo(e-i)Uo?Math.atan((Math.sin(t)*(u=Math.cos(r))*Math.sin(e)-Math.sin(r)*(i=Math.cos(t))*Math.sin(n))/(i*u*o)):(t+r)/2}function Ht(n,t,e,r){var i;if(null==n)i=e*Io,r.point(-Fo,i),r.point(0,i),r.point(Fo,i),r.point(Fo,0),r.point(Fo,-i),r.point(0,-i),r.point(-Fo,-i),r.point(-Fo,0),r.point(-Fo,i);else if(xo(n[0]-t[0])>Uo){var u=n[0]a;++a){var c=t[a],f=c.length;if(f)for(var s=c[0],h=s[0],p=s[1]/2+Fo/4,g=Math.sin(p),v=Math.cos(p),d=1;;){d===f&&(d=0),n=c[d];var y=n[0],m=n[1]/2+Fo/4,M=Math.sin(m),x=Math.cos(m),b=y-h,_=b>=0?1:-1,w=_*b,S=w>Fo,k=g*M;if(ka.add(Math.atan2(k*_*Math.sin(w),v*x+k*Math.cos(w))),u+=S?b+_*Ho:b,S^h>=e^y>=e){var N=mt(dt(s),dt(n));bt(N);var E=mt(i,N);bt(E);var A=(S^b>=0?-1:1)*tn(E[2]);(r>A||r===A&&(N[0]||N[1]))&&(o+=S^b>=0?1:-1)}if(!d++)break;h=y,g=M,v=x,s=n}}return(-Uo>u||Uo>u&&-Uo>ka)^1&o}function It(n){function t(n,t){return Math.cos(n)*Math.cos(t)>u}function e(n){var e,u,l,c,f;return{lineStart:function(){c=l=!1,f=1},point:function(s,h){var p,g=[s,h],v=t(s,h),d=o?v?0:i(s,h):v?i(s+(0>s?Fo:-Fo),h):0;if(!e&&(c=l=v)&&n.lineStart(),v!==l&&(p=r(e,g),(wt(e,p)||wt(g,p))&&(g[0]+=Uo,g[1]+=Uo,v=t(g[0],g[1]))),v!==l)f=0,v?(n.lineStart(),p=r(g,e),n.point(p[0],p[1])):(p=r(e,g),n.point(p[0],p[1]),n.lineEnd()),e=p;else if(a&&e&&o^v){var y;d&u||!(y=r(g,e,!0))||(f=0,o?(n.lineStart(),n.point(y[0][0],y[0][1]),n.point(y[1][0],y[1][1]),n.lineEnd()):(n.point(y[1][0],y[1][1]),n.lineEnd(),n.lineStart(),n.point(y[0][0],y[0][1])))}!v||e&&wt(e,g)||n.point(g[0],g[1]),e=g,l=v,u=d},lineEnd:function(){l&&n.lineEnd(),e=null},clean:function(){return f|(c&&l)<<1}}}function r(n,t,e){var r=dt(n),i=dt(t),o=[1,0,0],a=mt(r,i),l=yt(a,a),c=a[0],f=l-c*c;if(!f)return!e&&n;var s=u*l/f,h=-u*c/f,p=mt(o,a),g=xt(o,s),v=xt(a,h);Mt(g,v);var d=p,y=yt(g,d),m=yt(d,d),M=y*y-m*(yt(g,g)-1);if(!(0>M)){var x=Math.sqrt(M),b=xt(d,(-y-x)/m);if(Mt(b,g),b=_t(b),!e)return b;var _,w=n[0],S=t[0],k=n[1],N=t[1];w>S&&(_=w,w=S,S=_);var E=S-w,A=xo(E-Fo)E;if(!A&&k>N&&(_=k,k=N,N=_),C?A?k+N>0^b[1]<(xo(b[0]-w)Fo^(w<=b[0]&&b[0]<=S)){var z=xt(d,(-y+x)/m);return Mt(z,g),[b,_t(z)]}}}function i(t,e){var r=o?n:Fo-n,i=0;return-r>t?i|=1:t>r&&(i|=2),-r>e?i|=4:e>r&&(i|=8),i}var u=Math.cos(n),o=u>0,a=xo(u)>Uo,l=ve(n,6*Yo);return Rt(t,e,l,o?[0,-n]:[-Fo,n-Fo])}function Yt(n,t,e,r){return function(i){var u,o=i.a,a=i.b,l=o.x,c=o.y,f=a.x,s=a.y,h=0,p=1,g=f-l,v=s-c;if(u=n-l,g||!(u>0)){if(u/=g,0>g){if(h>u)return;p>u&&(p=u)}else if(g>0){if(u>p)return;u>h&&(h=u)}if(u=e-l,g||!(0>u)){if(u/=g,0>g){if(u>p)return;u>h&&(h=u)}else if(g>0){if(h>u)return;p>u&&(p=u)}if(u=t-c,v||!(u>0)){if(u/=v,0>v){if(h>u)return;p>u&&(p=u)}else if(v>0){if(u>p)return;u>h&&(h=u)}if(u=r-c,v||!(0>u)){if(u/=v,0>v){if(u>p)return;u>h&&(h=u)}else if(v>0){if(h>u)return;p>u&&(p=u)}return h>0&&(i.a={x:l+h*g,y:c+h*v}),1>p&&(i.b={x:l+p*g,y:c+p*v}),i}}}}}}function Zt(n,t,e,r){function i(r,i){return xo(r[0]-n)0?0:3:xo(r[0]-e)0?2:1:xo(r[1]-t)0?1:0:i>0?3:2}function u(n,t){return o(n.x,t.x)}function o(n,t){var e=i(n,1),r=i(t,1);return e!==r?e-r:0===e?t[1]-n[1]:1===e?n[0]-t[0]:2===e?n[1]-t[1]:t[0]-n[0]}return function(a){function l(n){for(var t=0,e=d.length,r=n[1],i=0;e>i;++i)for(var u,o=1,a=d[i],l=a.length,c=a[0];l>o;++o)u=a[o],c[1]<=r?u[1]>r&&Q(c,u,n)>0&&++t:u[1]<=r&&Q(c,u,n)<0&&--t,c=u;return 0!==t}function c(u,a,l,c){var f=0,s=0;if(null==u||(f=i(u,l))!==(s=i(a,l))||o(u,a)<0^l>0){do c.point(0===f||3===f?n:e,f>1?r:t);while((f=(f+l+4)%4)!==s)}else c.point(a[0],a[1])}function f(i,u){return i>=n&&e>=i&&u>=t&&r>=u}function s(n,t){f(n,t)&&a.point(n,t)}function h(){C.point=g,d&&d.push(y=[]),S=!0,w=!1,b=_=NaN}function p(){v&&(g(m,M),x&&w&&E.rejoin(),v.push(E.buffer())),C.point=s,w&&a.lineEnd()}function g(n,t){n=Math.max(-Ha,Math.min(Ha,n)),t=Math.max(-Ha,Math.min(Ha,t));var e=f(n,t);if(d&&y.push([n,t]),S)m=n,M=t,x=e,S=!1,e&&(a.lineStart(),a.point(n,t));else if(e&&w)a.point(n,t);else{var r={a:{x:b,y:_},b:{x:n,y:t}};A(r)?(w||(a.lineStart(),a.point(r.a.x,r.a.y)),a.point(r.b.x,r.b.y),e||a.lineEnd(),k=!1):e&&(a.lineStart(),a.point(n,t),k=!1)}b=n,_=t,w=e}var v,d,y,m,M,x,b,_,w,S,k,N=a,E=Pt(),A=Yt(n,t,e,r),C={point:s,lineStart:h,lineEnd:p,polygonStart:function(){a=E,v=[],d=[],k=!0},polygonEnd:function(){a=N,v=ao.merge(v);var t=l([n,r]),e=k&&t,i=v.length;(e||i)&&(a.polygonStart(),e&&(a.lineStart(),c(null,null,1,a),a.lineEnd()),i&&Lt(v,u,t,c,a),a.polygonEnd()),v=d=y=null}};return C}}function Vt(n){var t=0,e=Fo/3,r=ae(n),i=r(t,e);return i.parallels=function(n){return arguments.length?r(t=n[0]*Fo/180,e=n[1]*Fo/180):[t/Fo*180,e/Fo*180]},i}function Xt(n,t){function e(n,t){var e=Math.sqrt(u-2*i*Math.sin(t))/i;return[e*Math.sin(n*=i),o-e*Math.cos(n)]}var r=Math.sin(n),i=(r+Math.sin(t))/2,u=1+r*(2*i-r),o=Math.sqrt(u)/i;return e.invert=function(n,t){var e=o-t;return[Math.atan2(n,e)/i,tn((u-(n*n+e*e)*i*i)/(2*i))]},e}function $t(){function n(n,t){Ia+=i*n-r*t,r=n,i=t}var t,e,r,i;$a.point=function(u,o){$a.point=n,t=r=u,e=i=o},$a.lineEnd=function(){n(t,e)}}function Bt(n,t){Ya>n&&(Ya=n),n>Va&&(Va=n),Za>t&&(Za=t),t>Xa&&(Xa=t)}function Wt(){function n(n,t){o.push("M",n,",",t,u)}function t(n,t){o.push("M",n,",",t),a.point=e}function e(n,t){o.push("L",n,",",t)}function r(){a.point=n}function i(){o.push("Z")}var u=Jt(4.5),o=[],a={point:n,lineStart:function(){a.point=t},lineEnd:r,polygonStart:function(){a.lineEnd=i},polygonEnd:function(){a.lineEnd=r,a.point=n},pointRadius:function(n){return u=Jt(n),a},result:function(){if(o.length){var n=o.join("");return o=[],n}}};return a}function Jt(n){return"m0,"+n+"a"+n+","+n+" 0 1,1 0,"+-2*n+"a"+n+","+n+" 0 1,1 0,"+2*n+"z"}function Gt(n,t){Ca+=n,za+=t,++La}function Kt(){function n(n,r){var i=n-t,u=r-e,o=Math.sqrt(i*i+u*u);qa+=o*(t+n)/2,Ta+=o*(e+r)/2,Ra+=o,Gt(t=n,e=r)}var t,e;Wa.point=function(r,i){Wa.point=n,Gt(t=r,e=i)}}function Qt(){Wa.point=Gt}function ne(){function n(n,t){var e=n-r,u=t-i,o=Math.sqrt(e*e+u*u);qa+=o*(r+n)/2,Ta+=o*(i+t)/2,Ra+=o,o=i*n-r*t,Da+=o*(r+n),Pa+=o*(i+t),Ua+=3*o,Gt(r=n,i=t)}var t,e,r,i;Wa.point=function(u,o){Wa.point=n,Gt(t=r=u,e=i=o)},Wa.lineEnd=function(){n(t,e)}}function te(n){function t(t,e){n.moveTo(t+o,e),n.arc(t,e,o,0,Ho)}function e(t,e){n.moveTo(t,e),a.point=r}function r(t,e){n.lineTo(t,e)}function i(){a.point=t}function u(){n.closePath()}var o=4.5,a={point:t,lineStart:function(){a.point=e},lineEnd:i,polygonStart:function(){a.lineEnd=u},polygonEnd:function(){a.lineEnd=i,a.point=t},pointRadius:function(n){return o=n,a},result:b};return a}function ee(n){function t(n){return(a?r:e)(n)}function e(t){return ue(t,function(e,r){e=n(e,r),t.point(e[0],e[1])})}function r(t){function e(e,r){e=n(e,r),t.point(e[0],e[1])}function r(){M=NaN,S.point=u,t.lineStart()}function u(e,r){var u=dt([e,r]),o=n(e,r);i(M,x,m,b,_,w,M=o[0],x=o[1],m=e,b=u[0],_=u[1],w=u[2],a,t),t.point(M,x)}function o(){S.point=e,t.lineEnd()}function l(){ -r(),S.point=c,S.lineEnd=f}function c(n,t){u(s=n,h=t),p=M,g=x,v=b,d=_,y=w,S.point=u}function f(){i(M,x,m,b,_,w,p,g,s,v,d,y,a,t),S.lineEnd=o,o()}var s,h,p,g,v,d,y,m,M,x,b,_,w,S={point:e,lineStart:r,lineEnd:o,polygonStart:function(){t.polygonStart(),S.lineStart=l},polygonEnd:function(){t.polygonEnd(),S.lineStart=r}};return S}function i(t,e,r,a,l,c,f,s,h,p,g,v,d,y){var m=f-t,M=s-e,x=m*m+M*M;if(x>4*u&&d--){var b=a+p,_=l+g,w=c+v,S=Math.sqrt(b*b+_*_+w*w),k=Math.asin(w/=S),N=xo(xo(w)-1)u||xo((m*z+M*L)/x-.5)>.3||o>a*p+l*g+c*v)&&(i(t,e,r,a,l,c,A,C,N,b/=S,_/=S,w,d,y),y.point(A,C),i(A,C,N,b,_,w,f,s,h,p,g,v,d,y))}}var u=.5,o=Math.cos(30*Yo),a=16;return t.precision=function(n){return arguments.length?(a=(u=n*n)>0&&16,t):Math.sqrt(u)},t}function re(n){var t=ee(function(t,e){return n([t*Zo,e*Zo])});return function(n){return le(t(n))}}function ie(n){this.stream=n}function ue(n,t){return{point:t,sphere:function(){n.sphere()},lineStart:function(){n.lineStart()},lineEnd:function(){n.lineEnd()},polygonStart:function(){n.polygonStart()},polygonEnd:function(){n.polygonEnd()}}}function oe(n){return ae(function(){return n})()}function ae(n){function t(n){return n=a(n[0]*Yo,n[1]*Yo),[n[0]*h+l,c-n[1]*h]}function e(n){return n=a.invert((n[0]-l)/h,(c-n[1])/h),n&&[n[0]*Zo,n[1]*Zo]}function r(){a=Ct(o=se(y,M,x),u);var n=u(v,d);return l=p-n[0]*h,c=g+n[1]*h,i()}function i(){return f&&(f.valid=!1,f=null),t}var u,o,a,l,c,f,s=ee(function(n,t){return n=u(n,t),[n[0]*h+l,c-n[1]*h]}),h=150,p=480,g=250,v=0,d=0,y=0,M=0,x=0,b=Fa,_=m,w=null,S=null;return t.stream=function(n){return f&&(f.valid=!1),f=le(b(o,s(_(n)))),f.valid=!0,f},t.clipAngle=function(n){return arguments.length?(b=null==n?(w=n,Fa):It((w=+n)*Yo),i()):w},t.clipExtent=function(n){return arguments.length?(S=n,_=n?Zt(n[0][0],n[0][1],n[1][0],n[1][1]):m,i()):S},t.scale=function(n){return arguments.length?(h=+n,r()):h},t.translate=function(n){return arguments.length?(p=+n[0],g=+n[1],r()):[p,g]},t.center=function(n){return arguments.length?(v=n[0]%360*Yo,d=n[1]%360*Yo,r()):[v*Zo,d*Zo]},t.rotate=function(n){return arguments.length?(y=n[0]%360*Yo,M=n[1]%360*Yo,x=n.length>2?n[2]%360*Yo:0,r()):[y*Zo,M*Zo,x*Zo]},ao.rebind(t,s,"precision"),function(){return u=n.apply(this,arguments),t.invert=u.invert&&e,r()}}function le(n){return ue(n,function(t,e){n.point(t*Yo,e*Yo)})}function ce(n,t){return[n,t]}function fe(n,t){return[n>Fo?n-Ho:-Fo>n?n+Ho:n,t]}function se(n,t,e){return n?t||e?Ct(pe(n),ge(t,e)):pe(n):t||e?ge(t,e):fe}function he(n){return function(t,e){return t+=n,[t>Fo?t-Ho:-Fo>t?t+Ho:t,e]}}function pe(n){var t=he(n);return t.invert=he(-n),t}function ge(n,t){function e(n,t){var e=Math.cos(t),a=Math.cos(n)*e,l=Math.sin(n)*e,c=Math.sin(t),f=c*r+a*i;return[Math.atan2(l*u-f*o,a*r-c*i),tn(f*u+l*o)]}var r=Math.cos(n),i=Math.sin(n),u=Math.cos(t),o=Math.sin(t);return e.invert=function(n,t){var e=Math.cos(t),a=Math.cos(n)*e,l=Math.sin(n)*e,c=Math.sin(t),f=c*u-l*o;return[Math.atan2(l*u+c*o,a*r+f*i),tn(f*r-a*i)]},e}function ve(n,t){var e=Math.cos(n),r=Math.sin(n);return function(i,u,o,a){var l=o*t;null!=i?(i=de(e,i),u=de(e,u),(o>0?u>i:i>u)&&(i+=o*Ho)):(i=n+o*Ho,u=n-.5*l);for(var c,f=i;o>0?f>u:u>f;f-=l)a.point((c=_t([e,-r*Math.cos(f),-r*Math.sin(f)]))[0],c[1])}}function de(n,t){var e=dt(t);e[0]-=n,bt(e);var r=nn(-e[1]);return((-e[2]<0?-r:r)+2*Math.PI-Uo)%(2*Math.PI)}function ye(n,t,e){var r=ao.range(n,t-Uo,e).concat(t);return function(n){return r.map(function(t){return[n,t]})}}function me(n,t,e){var r=ao.range(n,t-Uo,e).concat(t);return function(n){return r.map(function(t){return[t,n]})}}function Me(n){return n.source}function xe(n){return n.target}function be(n,t,e,r){var i=Math.cos(t),u=Math.sin(t),o=Math.cos(r),a=Math.sin(r),l=i*Math.cos(n),c=i*Math.sin(n),f=o*Math.cos(e),s=o*Math.sin(e),h=2*Math.asin(Math.sqrt(on(r-t)+i*o*on(e-n))),p=1/Math.sin(h),g=h?function(n){var t=Math.sin(n*=h)*p,e=Math.sin(h-n)*p,r=e*l+t*f,i=e*c+t*s,o=e*u+t*a;return[Math.atan2(i,r)*Zo,Math.atan2(o,Math.sqrt(r*r+i*i))*Zo]}:function(){return[n*Zo,t*Zo]};return g.distance=h,g}function _e(){function n(n,i){var u=Math.sin(i*=Yo),o=Math.cos(i),a=xo((n*=Yo)-t),l=Math.cos(a);Ja+=Math.atan2(Math.sqrt((a=o*Math.sin(a))*a+(a=r*u-e*o*l)*a),e*u+r*o*l),t=n,e=u,r=o}var t,e,r;Ga.point=function(i,u){t=i*Yo,e=Math.sin(u*=Yo),r=Math.cos(u),Ga.point=n},Ga.lineEnd=function(){Ga.point=Ga.lineEnd=b}}function we(n,t){function e(t,e){var r=Math.cos(t),i=Math.cos(e),u=n(r*i);return[u*i*Math.sin(t),u*Math.sin(e)]}return e.invert=function(n,e){var r=Math.sqrt(n*n+e*e),i=t(r),u=Math.sin(i),o=Math.cos(i);return[Math.atan2(n*u,r*o),Math.asin(r&&e*u/r)]},e}function Se(n,t){function e(n,t){o>0?-Io+Uo>t&&(t=-Io+Uo):t>Io-Uo&&(t=Io-Uo);var e=o/Math.pow(i(t),u);return[e*Math.sin(u*n),o-e*Math.cos(u*n)]}var r=Math.cos(n),i=function(n){return Math.tan(Fo/4+n/2)},u=n===t?Math.sin(n):Math.log(r/Math.cos(t))/Math.log(i(t)/i(n)),o=r*Math.pow(i(n),u)/u;return u?(e.invert=function(n,t){var e=o-t,r=K(u)*Math.sqrt(n*n+e*e);return[Math.atan2(n,e)/u,2*Math.atan(Math.pow(o/r,1/u))-Io]},e):Ne}function ke(n,t){function e(n,t){var e=u-t;return[e*Math.sin(i*n),u-e*Math.cos(i*n)]}var r=Math.cos(n),i=n===t?Math.sin(n):(r-Math.cos(t))/(t-n),u=r/i+n;return xo(i)i;i++){for(;r>1&&Q(n[e[r-2]],n[e[r-1]],n[i])<=0;)--r;e[r++]=i}return e.slice(0,r)}function qe(n,t){return n[0]-t[0]||n[1]-t[1]}function Te(n,t,e){return(e[0]-t[0])*(n[1]-t[1])<(e[1]-t[1])*(n[0]-t[0])}function Re(n,t,e,r){var i=n[0],u=e[0],o=t[0]-i,a=r[0]-u,l=n[1],c=e[1],f=t[1]-l,s=r[1]-c,h=(a*(l-c)-s*(i-u))/(s*o-a*f);return[i+h*o,l+h*f]}function De(n){var t=n[0],e=n[n.length-1];return!(t[0]-e[0]||t[1]-e[1])}function Pe(){rr(this),this.edge=this.site=this.circle=null}function Ue(n){var t=cl.pop()||new Pe;return t.site=n,t}function je(n){Be(n),ol.remove(n),cl.push(n),rr(n)}function Fe(n){var t=n.circle,e=t.x,r=t.cy,i={x:e,y:r},u=n.P,o=n.N,a=[n];je(n);for(var l=u;l.circle&&xo(e-l.circle.x)f;++f)c=a[f],l=a[f-1],nr(c.edge,l.site,c.site,i);l=a[0],c=a[s-1],c.edge=Ke(l.site,c.site,null,i),$e(l),$e(c)}function He(n){for(var t,e,r,i,u=n.x,o=n.y,a=ol._;a;)if(r=Oe(a,o)-u,r>Uo)a=a.L;else{if(i=u-Ie(a,o),!(i>Uo)){r>-Uo?(t=a.P,e=a):i>-Uo?(t=a,e=a.N):t=e=a;break}if(!a.R){t=a;break}a=a.R}var l=Ue(n);if(ol.insert(t,l),t||e){if(t===e)return Be(t),e=Ue(t.site),ol.insert(l,e),l.edge=e.edge=Ke(t.site,l.site),$e(t),void $e(e);if(!e)return void(l.edge=Ke(t.site,l.site));Be(t),Be(e);var c=t.site,f=c.x,s=c.y,h=n.x-f,p=n.y-s,g=e.site,v=g.x-f,d=g.y-s,y=2*(h*d-p*v),m=h*h+p*p,M=v*v+d*d,x={x:(d*m-p*M)/y+f,y:(h*M-v*m)/y+s};nr(e.edge,c,g,x),l.edge=Ke(c,n,null,x),e.edge=Ke(n,g,null,x),$e(t),$e(e)}}function Oe(n,t){var e=n.site,r=e.x,i=e.y,u=i-t;if(!u)return r;var o=n.P;if(!o)return-(1/0);e=o.site;var a=e.x,l=e.y,c=l-t;if(!c)return a;var f=a-r,s=1/u-1/c,h=f/c;return s?(-h+Math.sqrt(h*h-2*s*(f*f/(-2*c)-l+c/2+i-u/2)))/s+r:(r+a)/2}function Ie(n,t){var e=n.N;if(e)return Oe(e,t);var r=n.site;return r.y===t?r.x:1/0}function Ye(n){this.site=n,this.edges=[]}function Ze(n){for(var t,e,r,i,u,o,a,l,c,f,s=n[0][0],h=n[1][0],p=n[0][1],g=n[1][1],v=ul,d=v.length;d--;)if(u=v[d],u&&u.prepare())for(a=u.edges,l=a.length,o=0;l>o;)f=a[o].end(),r=f.x,i=f.y,c=a[++o%l].start(),t=c.x,e=c.y,(xo(r-t)>Uo||xo(i-e)>Uo)&&(a.splice(o,0,new tr(Qe(u.site,f,xo(r-s)Uo?{x:s,y:xo(t-s)Uo?{x:xo(e-g)Uo?{x:h,y:xo(t-h)Uo?{x:xo(e-p)=-jo)){var p=l*l+c*c,g=f*f+s*s,v=(s*p-c*g)/h,d=(l*g-f*p)/h,s=d+a,y=fl.pop()||new Xe;y.arc=n,y.site=i,y.x=v+o,y.y=s+Math.sqrt(v*v+d*d),y.cy=s,n.circle=y;for(var m=null,M=ll._;M;)if(y.yd||d>=a)return;if(h>g){if(u){if(u.y>=c)return}else u={x:d,y:l};e={x:d,y:c}}else{if(u){if(u.yr||r>1)if(h>g){if(u){if(u.y>=c)return}else u={x:(l-i)/r,y:l};e={x:(c-i)/r,y:c}}else{if(u){if(u.yp){if(u){if(u.x>=a)return}else u={x:o,y:r*o+i};e={x:a,y:r*a+i}}else{if(u){if(u.xu||s>o||r>h||i>p)){if(g=n.point){var g,v=t-n.x,d=e-n.y,y=v*v+d*d;if(l>y){var m=Math.sqrt(l=y);r=t-m,i=e-m,u=t+m,o=e+m,a=g}}for(var M=n.nodes,x=.5*(f+h),b=.5*(s+p),_=t>=x,w=e>=b,S=w<<1|_,k=S+4;k>S;++S)if(n=M[3&S])switch(3&S){case 0:c(n,f,s,x,b);break;case 1:c(n,x,s,h,b);break;case 2:c(n,f,b,x,p);break;case 3:c(n,x,b,h,p)}}}(n,r,i,u,o),a}function vr(n,t){n=ao.rgb(n),t=ao.rgb(t);var e=n.r,r=n.g,i=n.b,u=t.r-e,o=t.g-r,a=t.b-i;return function(n){return"#"+bn(Math.round(e+u*n))+bn(Math.round(r+o*n))+bn(Math.round(i+a*n))}}function dr(n,t){var e,r={},i={};for(e in n)e in t?r[e]=Mr(n[e],t[e]):i[e]=n[e];for(e in t)e in n||(i[e]=t[e]);return function(n){for(e in r)i[e]=r[e](n);return i}}function yr(n,t){return n=+n,t=+t,function(e){return n*(1-e)+t*e}}function mr(n,t){var e,r,i,u=hl.lastIndex=pl.lastIndex=0,o=-1,a=[],l=[];for(n+="",t+="";(e=hl.exec(n))&&(r=pl.exec(t));)(i=r.index)>u&&(i=t.slice(u,i),a[o]?a[o]+=i:a[++o]=i),(e=e[0])===(r=r[0])?a[o]?a[o]+=r:a[++o]=r:(a[++o]=null,l.push({i:o,x:yr(e,r)})),u=pl.lastIndex;return ur;++r)a[(e=l[r]).i]=e.x(n);return a.join("")})}function Mr(n,t){for(var e,r=ao.interpolators.length;--r>=0&&!(e=ao.interpolators[r](n,t)););return e}function xr(n,t){var e,r=[],i=[],u=n.length,o=t.length,a=Math.min(n.length,t.length);for(e=0;a>e;++e)r.push(Mr(n[e],t[e]));for(;u>e;++e)i[e]=n[e];for(;o>e;++e)i[e]=t[e];return function(n){for(e=0;a>e;++e)i[e]=r[e](n);return i}}function br(n){return function(t){return 0>=t?0:t>=1?1:n(t)}}function _r(n){return function(t){return 1-n(1-t)}}function wr(n){return function(t){return.5*(.5>t?n(2*t):2-n(2-2*t))}}function Sr(n){return n*n}function kr(n){return n*n*n}function Nr(n){if(0>=n)return 0;if(n>=1)return 1;var t=n*n,e=t*n;return 4*(.5>n?e:3*(n-t)+e-.75)}function Er(n){return function(t){return Math.pow(t,n)}}function Ar(n){return 1-Math.cos(n*Io)}function Cr(n){return Math.pow(2,10*(n-1))}function zr(n){return 1-Math.sqrt(1-n*n)}function Lr(n,t){var e;return arguments.length<2&&(t=.45),arguments.length?e=t/Ho*Math.asin(1/n):(n=1,e=t/4),function(r){return 1+n*Math.pow(2,-10*r)*Math.sin((r-e)*Ho/t)}}function qr(n){return n||(n=1.70158),function(t){return t*t*((n+1)*t-n)}}function Tr(n){return 1/2.75>n?7.5625*n*n:2/2.75>n?7.5625*(n-=1.5/2.75)*n+.75:2.5/2.75>n?7.5625*(n-=2.25/2.75)*n+.9375:7.5625*(n-=2.625/2.75)*n+.984375}function Rr(n,t){n=ao.hcl(n),t=ao.hcl(t);var e=n.h,r=n.c,i=n.l,u=t.h-e,o=t.c-r,a=t.l-i;return isNaN(o)&&(o=0,r=isNaN(r)?t.c:r),isNaN(u)?(u=0,e=isNaN(e)?t.h:e):u>180?u-=360:-180>u&&(u+=360),function(n){return sn(e+u*n,r+o*n,i+a*n)+""}}function Dr(n,t){n=ao.hsl(n),t=ao.hsl(t);var e=n.h,r=n.s,i=n.l,u=t.h-e,o=t.s-r,a=t.l-i;return isNaN(o)&&(o=0,r=isNaN(r)?t.s:r),isNaN(u)?(u=0,e=isNaN(e)?t.h:e):u>180?u-=360:-180>u&&(u+=360),function(n){return cn(e+u*n,r+o*n,i+a*n)+""}}function Pr(n,t){n=ao.lab(n),t=ao.lab(t);var e=n.l,r=n.a,i=n.b,u=t.l-e,o=t.a-r,a=t.b-i;return function(n){return pn(e+u*n,r+o*n,i+a*n)+""}}function Ur(n,t){return t-=n,function(e){return Math.round(n+t*e)}}function jr(n){var t=[n.a,n.b],e=[n.c,n.d],r=Hr(t),i=Fr(t,e),u=Hr(Or(e,t,-i))||0;t[0]*e[1]180?t+=360:t-n>180&&(n+=360),r.push({i:e.push(Ir(e)+"rotate(",null,")")-2,x:yr(n,t)})):t&&e.push(Ir(e)+"rotate("+t+")")}function Vr(n,t,e,r){n!==t?r.push({i:e.push(Ir(e)+"skewX(",null,")")-2,x:yr(n,t)}):t&&e.push(Ir(e)+"skewX("+t+")")}function Xr(n,t,e,r){if(n[0]!==t[0]||n[1]!==t[1]){var i=e.push(Ir(e)+"scale(",null,",",null,")");r.push({i:i-4,x:yr(n[0],t[0])},{i:i-2,x:yr(n[1],t[1])})}else 1===t[0]&&1===t[1]||e.push(Ir(e)+"scale("+t+")")}function $r(n,t){var e=[],r=[];return n=ao.transform(n),t=ao.transform(t),Yr(n.translate,t.translate,e,r),Zr(n.rotate,t.rotate,e,r),Vr(n.skew,t.skew,e,r),Xr(n.scale,t.scale,e,r),n=t=null,function(n){for(var t,i=-1,u=r.length;++i=0;)e.push(i[r])}function oi(n,t){for(var e=[n],r=[];null!=(n=e.pop());)if(r.push(n),(u=n.children)&&(i=u.length))for(var i,u,o=-1;++oe;++e)(t=n[e][1])>i&&(r=e,i=t);return r}function yi(n){return n.reduce(mi,0)}function mi(n,t){return n+t[1]}function Mi(n,t){return xi(n,Math.ceil(Math.log(t.length)/Math.LN2+1))}function xi(n,t){for(var e=-1,r=+n[0],i=(n[1]-r)/t,u=[];++e<=t;)u[e]=i*e+r;return u}function bi(n){return[ao.min(n),ao.max(n)]}function _i(n,t){return n.value-t.value}function wi(n,t){var e=n._pack_next;n._pack_next=t,t._pack_prev=n,t._pack_next=e,e._pack_prev=t}function Si(n,t){n._pack_next=t,t._pack_prev=n}function ki(n,t){var e=t.x-n.x,r=t.y-n.y,i=n.r+t.r;return.999*i*i>e*e+r*r}function Ni(n){function t(n){f=Math.min(n.x-n.r,f),s=Math.max(n.x+n.r,s),h=Math.min(n.y-n.r,h),p=Math.max(n.y+n.r,p)}if((e=n.children)&&(c=e.length)){var e,r,i,u,o,a,l,c,f=1/0,s=-(1/0),h=1/0,p=-(1/0);if(e.forEach(Ei),r=e[0],r.x=-r.r,r.y=0,t(r),c>1&&(i=e[1],i.x=i.r,i.y=0,t(i),c>2))for(u=e[2],zi(r,i,u),t(u),wi(r,u),r._pack_prev=u,wi(u,i),i=r._pack_next,o=3;c>o;o++){zi(r,i,u=e[o]);var g=0,v=1,d=1;for(a=i._pack_next;a!==i;a=a._pack_next,v++)if(ki(a,u)){g=1;break}if(1==g)for(l=r._pack_prev;l!==a._pack_prev&&!ki(l,u);l=l._pack_prev,d++);g?(d>v||v==d&&i.ro;o++)u=e[o],u.x-=y,u.y-=m,M=Math.max(M,u.r+Math.sqrt(u.x*u.x+u.y*u.y));n.r=M,e.forEach(Ai)}}function Ei(n){n._pack_next=n._pack_prev=n}function Ai(n){delete n._pack_next,delete n._pack_prev}function Ci(n,t,e,r){var i=n.children;if(n.x=t+=r*n.x,n.y=e+=r*n.y,n.r*=r,i)for(var u=-1,o=i.length;++u=0;)t=i[u],t.z+=e,t.m+=e,e+=t.s+(r+=t.c)}function Pi(n,t,e){return n.a.parent===t.parent?n.a:e}function Ui(n){return 1+ao.max(n,function(n){return n.y})}function ji(n){return n.reduce(function(n,t){return n+t.x},0)/n.length}function Fi(n){var t=n.children;return t&&t.length?Fi(t[0]):n}function Hi(n){var t,e=n.children;return e&&(t=e.length)?Hi(e[t-1]):n}function Oi(n){return{x:n.x,y:n.y,dx:n.dx,dy:n.dy}}function Ii(n,t){var e=n.x+t[3],r=n.y+t[0],i=n.dx-t[1]-t[3],u=n.dy-t[0]-t[2];return 0>i&&(e+=i/2,i=0),0>u&&(r+=u/2,u=0),{x:e,y:r,dx:i,dy:u}}function Yi(n){var t=n[0],e=n[n.length-1];return e>t?[t,e]:[e,t]}function Zi(n){return n.rangeExtent?n.rangeExtent():Yi(n.range())}function Vi(n,t,e,r){var i=e(n[0],n[1]),u=r(t[0],t[1]);return function(n){return u(i(n))}}function Xi(n,t){var e,r=0,i=n.length-1,u=n[r],o=n[i];return u>o&&(e=r,r=i,i=e,e=u,u=o,o=e),n[r]=t.floor(u),n[i]=t.ceil(o),n}function $i(n){return n?{floor:function(t){return Math.floor(t/n)*n},ceil:function(t){return Math.ceil(t/n)*n}}:Sl}function Bi(n,t,e,r){var i=[],u=[],o=0,a=Math.min(n.length,t.length)-1;for(n[a]2?Bi:Vi,l=r?Wr:Br;return o=i(n,t,l,e),a=i(t,n,l,Mr),u}function u(n){return o(n)}var o,a;return u.invert=function(n){return a(n)},u.domain=function(t){return arguments.length?(n=t.map(Number),i()):n},u.range=function(n){return arguments.length?(t=n,i()):t},u.rangeRound=function(n){return u.range(n).interpolate(Ur)},u.clamp=function(n){return arguments.length?(r=n,i()):r},u.interpolate=function(n){return arguments.length?(e=n,i()):e},u.ticks=function(t){return Qi(n,t)},u.tickFormat=function(t,e){return nu(n,t,e)},u.nice=function(t){return Gi(n,t),i()},u.copy=function(){return Wi(n,t,e,r)},i()}function Ji(n,t){return ao.rebind(n,t,"range","rangeRound","interpolate","clamp")}function Gi(n,t){return Xi(n,$i(Ki(n,t)[2])),Xi(n,$i(Ki(n,t)[2])),n}function Ki(n,t){null==t&&(t=10);var e=Yi(n),r=e[1]-e[0],i=Math.pow(10,Math.floor(Math.log(r/t)/Math.LN10)),u=t/r*i;return.15>=u?i*=10:.35>=u?i*=5:.75>=u&&(i*=2),e[0]=Math.ceil(e[0]/i)*i,e[1]=Math.floor(e[1]/i)*i+.5*i,e[2]=i,e}function Qi(n,t){return ao.range.apply(ao,Ki(n,t))}function nu(n,t,e){var r=Ki(n,t);if(e){var i=ha.exec(e);if(i.shift(),"s"===i[8]){var u=ao.formatPrefix(Math.max(xo(r[0]),xo(r[1])));return i[7]||(i[7]="."+tu(u.scale(r[2]))),i[8]="f",e=ao.format(i.join("")),function(n){return e(u.scale(n))+u.symbol}}i[7]||(i[7]="."+eu(i[8],r)),e=i.join("")}else e=",."+tu(r[2])+"f";return ao.format(e)}function tu(n){return-Math.floor(Math.log(n)/Math.LN10+.01)}function eu(n,t){var e=tu(t[2]);return n in kl?Math.abs(e-tu(Math.max(xo(t[0]),xo(t[1]))))+ +("e"!==n):e-2*("%"===n)}function ru(n,t,e,r){function i(n){return(e?Math.log(0>n?0:n):-Math.log(n>0?0:-n))/Math.log(t)}function u(n){return e?Math.pow(t,n):-Math.pow(t,-n)}function o(t){return n(i(t))}return o.invert=function(t){return u(n.invert(t))},o.domain=function(t){return arguments.length?(e=t[0]>=0,n.domain((r=t.map(Number)).map(i)),o):r},o.base=function(e){return arguments.length?(t=+e,n.domain(r.map(i)),o):t},o.nice=function(){var t=Xi(r.map(i),e?Math:El);return n.domain(t),r=t.map(u),o},o.ticks=function(){var n=Yi(r),o=[],a=n[0],l=n[1],c=Math.floor(i(a)),f=Math.ceil(i(l)),s=t%1?2:t;if(isFinite(f-c)){if(e){for(;f>c;c++)for(var h=1;s>h;h++)o.push(u(c)*h);o.push(u(c))}else for(o.push(u(c));c++0;h--)o.push(u(c)*h);for(c=0;o[c]l;f--);o=o.slice(c,f)}return o},o.tickFormat=function(n,e){if(!arguments.length)return Nl;arguments.length<2?e=Nl:"function"!=typeof e&&(e=ao.format(e));var r=Math.max(1,t*n/o.ticks().length);return function(n){var o=n/u(Math.round(i(n)));return t-.5>o*t&&(o*=t),r>=o?e(n):""}},o.copy=function(){return ru(n.copy(),t,e,r)},Ji(o,n)}function iu(n,t,e){function r(t){return n(i(t))}var i=uu(t),u=uu(1/t);return r.invert=function(t){return u(n.invert(t))},r.domain=function(t){return arguments.length?(n.domain((e=t.map(Number)).map(i)),r):e},r.ticks=function(n){return Qi(e,n)},r.tickFormat=function(n,t){return nu(e,n,t)},r.nice=function(n){return r.domain(Gi(e,n))},r.exponent=function(o){return arguments.length?(i=uu(t=o),u=uu(1/t),n.domain(e.map(i)),r):t},r.copy=function(){return iu(n.copy(),t,e)},Ji(r,n)}function uu(n){return function(t){return 0>t?-Math.pow(-t,n):Math.pow(t,n)}}function ou(n,t){function e(e){return u[((i.get(e)||("range"===t.t?i.set(e,n.push(e)):NaN))-1)%u.length]}function r(t,e){return ao.range(n.length).map(function(n){return t+e*n})}var i,u,o;return e.domain=function(r){if(!arguments.length)return n;n=[],i=new c;for(var u,o=-1,a=r.length;++oe?[NaN,NaN]:[e>0?a[e-1]:n[0],et?NaN:t/u+n,[t,t+1/u]},r.copy=function(){return lu(n,t,e)},i()}function cu(n,t){function e(e){return e>=e?t[ao.bisect(n,e)]:void 0}return e.domain=function(t){return arguments.length?(n=t,e):n},e.range=function(n){return arguments.length?(t=n,e):t},e.invertExtent=function(e){return e=t.indexOf(e),[n[e-1],n[e]]},e.copy=function(){return cu(n,t)},e}function fu(n){function t(n){return+n}return t.invert=t,t.domain=t.range=function(e){return arguments.length?(n=e.map(t),t):n},t.ticks=function(t){return Qi(n,t)},t.tickFormat=function(t,e){return nu(n,t,e)},t.copy=function(){return fu(n)},t}function su(){return 0}function hu(n){return n.innerRadius}function pu(n){return n.outerRadius}function gu(n){return n.startAngle}function vu(n){return n.endAngle}function du(n){return n&&n.padAngle}function yu(n,t,e,r){return(n-e)*t-(t-r)*n>0?0:1}function mu(n,t,e,r,i){var u=n[0]-t[0],o=n[1]-t[1],a=(i?r:-r)/Math.sqrt(u*u+o*o),l=a*o,c=-a*u,f=n[0]+l,s=n[1]+c,h=t[0]+l,p=t[1]+c,g=(f+h)/2,v=(s+p)/2,d=h-f,y=p-s,m=d*d+y*y,M=e-r,x=f*p-h*s,b=(0>y?-1:1)*Math.sqrt(Math.max(0,M*M*m-x*x)),_=(x*y-d*b)/m,w=(-x*d-y*b)/m,S=(x*y+d*b)/m,k=(-x*d+y*b)/m,N=_-g,E=w-v,A=S-g,C=k-v;return N*N+E*E>A*A+C*C&&(_=S,w=k),[[_-l,w-c],[_*e/M,w*e/M]]}function Mu(n){function t(t){function o(){c.push("M",u(n(f),a))}for(var l,c=[],f=[],s=-1,h=t.length,p=En(e),g=En(r);++s1?n.join("L"):n+"Z"}function bu(n){return n.join("L")+"Z"}function _u(n){for(var t=0,e=n.length,r=n[0],i=[r[0],",",r[1]];++t1&&i.push("H",r[0]),i.join("")}function wu(n){for(var t=0,e=n.length,r=n[0],i=[r[0],",",r[1]];++t1){a=t[1],u=n[l],l++,r+="C"+(i[0]+o[0])+","+(i[1]+o[1])+","+(u[0]-a[0])+","+(u[1]-a[1])+","+u[0]+","+u[1];for(var c=2;c9&&(i=3*t/Math.sqrt(i),o[a]=i*e,o[a+1]=i*r));for(a=-1;++a<=l;)i=(n[Math.min(l,a+1)][0]-n[Math.max(0,a-1)][0])/(6*(1+o[a]*o[a])),u.push([i||0,o[a]*i||0]);return u}function Fu(n){return n.length<3?xu(n):n[0]+Au(n,ju(n))}function Hu(n){for(var t,e,r,i=-1,u=n.length;++i=t?o(n-t):void(f.c=o)}function o(e){var i=g.active,u=g[i];u&&(u.timer.c=null,u.timer.t=NaN,--g.count,delete g[i],u.event&&u.event.interrupt.call(n,n.__data__,u.index));for(var o in g)if(r>+o){var c=g[o];c.timer.c=null,c.timer.t=NaN,--g.count,delete g[o]}f.c=a,qn(function(){return f.c&&a(e||1)&&(f.c=null,f.t=NaN),1},0,l),g.active=r,v.event&&v.event.start.call(n,n.__data__,t),p=[],v.tween.forEach(function(e,r){(r=r.call(n,n.__data__,t))&&p.push(r)}),h=v.ease,s=v.duration}function a(i){for(var u=i/s,o=h(u),a=p.length;a>0;)p[--a].call(n,o);return u>=1?(v.event&&v.event.end.call(n,n.__data__,t),--g.count?delete g[r]:delete n[e],1):void 0}var l,f,s,h,p,g=n[e]||(n[e]={active:0,count:0}),v=g[r];v||(l=i.time,f=qn(u,0,l),v=g[r]={tween:new c,time:l,timer:f,delay:i.delay,duration:i.duration,ease:i.ease,index:t},i=null,++g.count)}function no(n,t,e){n.attr("transform",function(n){var r=t(n);return"translate("+(isFinite(r)?r:e(n))+",0)"})}function to(n,t,e){n.attr("transform",function(n){var r=t(n);return"translate(0,"+(isFinite(r)?r:e(n))+")"})}function eo(n){return n.toISOString()}function ro(n,t,e){function r(t){return n(t)}function i(n,e){var r=n[1]-n[0],i=r/e,u=ao.bisect(Kl,i);return u==Kl.length?[t.year,Ki(n.map(function(n){return n/31536e6}),e)[2]]:u?t[i/Kl[u-1]1?{floor:function(t){for(;e(t=n.floor(t));)t=io(t-1);return t},ceil:function(t){for(;e(t=n.ceil(t));)t=io(+t+1);return t}}:n))},r.ticks=function(n,t){var e=Yi(r.domain()),u=null==n?i(e,10):"number"==typeof n?i(e,n):!n.range&&[{range:n},t];return u&&(n=u[0],t=u[1]),n.range(e[0],io(+e[1]+1),1>t?1:t)},r.tickFormat=function(){return e},r.copy=function(){return ro(n.copy(),t,e)},Ji(r,n)}function io(n){return new Date(n)}function uo(n){return JSON.parse(n.responseText)}function oo(n){var t=fo.createRange();return t.selectNode(fo.body),t.createContextualFragment(n.responseText)}var ao={version:"3.5.17"},lo=[].slice,co=function(n){return lo.call(n)},fo=this.document;if(fo)try{co(fo.documentElement.childNodes)[0].nodeType}catch(so){co=function(n){for(var t=n.length,e=new Array(t);t--;)e[t]=n[t];return e}}if(Date.now||(Date.now=function(){return+new Date}),fo)try{fo.createElement("DIV").style.setProperty("opacity",0,"")}catch(ho){var po=this.Element.prototype,go=po.setAttribute,vo=po.setAttributeNS,yo=this.CSSStyleDeclaration.prototype,mo=yo.setProperty;po.setAttribute=function(n,t){go.call(this,n,t+"")},po.setAttributeNS=function(n,t,e){vo.call(this,n,t,e+"")},yo.setProperty=function(n,t,e){mo.call(this,n,t+"",e)}}ao.ascending=e,ao.descending=function(n,t){return n>t?-1:t>n?1:t>=n?0:NaN},ao.min=function(n,t){var e,r,i=-1,u=n.length;if(1===arguments.length){for(;++i=r){e=r;break}for(;++ir&&(e=r)}else{for(;++i=r){e=r;break}for(;++ir&&(e=r)}return e},ao.max=function(n,t){var e,r,i=-1,u=n.length;if(1===arguments.length){for(;++i=r){e=r;break}for(;++ie&&(e=r)}else{for(;++i=r){e=r;break}for(;++ie&&(e=r)}return e},ao.extent=function(n,t){var e,r,i,u=-1,o=n.length;if(1===arguments.length){for(;++u=r){e=i=r;break}for(;++ur&&(e=r),r>i&&(i=r))}else{for(;++u=r){e=i=r;break}for(;++ur&&(e=r),r>i&&(i=r))}return[e,i]},ao.sum=function(n,t){var e,r=0,u=n.length,o=-1;if(1===arguments.length)for(;++o1?l/(f-1):void 0},ao.deviation=function(){var n=ao.variance.apply(this,arguments);return n?Math.sqrt(n):n};var Mo=u(e);ao.bisectLeft=Mo.left,ao.bisect=ao.bisectRight=Mo.right,ao.bisector=function(n){return u(1===n.length?function(t,r){return e(n(t),r)}:n)},ao.shuffle=function(n,t,e){(u=arguments.length)<3&&(e=n.length,2>u&&(t=0));for(var r,i,u=e-t;u;)i=Math.random()*u--|0,r=n[u+t],n[u+t]=n[i+t],n[i+t]=r;return n},ao.permute=function(n,t){for(var e=t.length,r=new Array(e);e--;)r[e]=n[t[e]];return r},ao.pairs=function(n){for(var t,e=0,r=n.length-1,i=n[0],u=new Array(0>r?0:r);r>e;)u[e]=[t=i,i=n[++e]];return u},ao.transpose=function(n){if(!(i=n.length))return[];for(var t=-1,e=ao.min(n,o),r=new Array(e);++t=0;)for(r=n[i],t=r.length;--t>=0;)e[--o]=r[t];return e};var xo=Math.abs;ao.range=function(n,t,e){if(arguments.length<3&&(e=1,arguments.length<2&&(t=n,n=0)),(t-n)/e===1/0)throw new Error("infinite range");var r,i=[],u=a(xo(e)),o=-1;if(n*=u,t*=u,e*=u,0>e)for(;(r=n+e*++o)>t;)i.push(r/u);else for(;(r=n+e*++o)=u.length)return r?r.call(i,o):e?o.sort(e):o;for(var l,f,s,h,p=-1,g=o.length,v=u[a++],d=new c;++p=u.length)return n;var r=[],i=o[e++];return n.forEach(function(n,i){r.push({key:n,values:t(i,e)})}),i?r.sort(function(n,t){return i(n.key,t.key)}):r}var e,r,i={},u=[],o=[];return i.map=function(t,e){return n(e,t,0)},i.entries=function(e){return t(n(ao.map,e,0),0)},i.key=function(n){return u.push(n),i},i.sortKeys=function(n){return o[u.length-1]=n,i},i.sortValues=function(n){return e=n,i},i.rollup=function(n){return r=n,i},i},ao.set=function(n){var t=new y;if(n)for(var e=0,r=n.length;r>e;++e)t.add(n[e]);return t},l(y,{has:h,add:function(n){return this._[f(n+="")]=!0,n},remove:p,values:g,size:v,empty:d,forEach:function(n){for(var t in this._)n.call(this,s(t))}}),ao.behavior={},ao.rebind=function(n,t){for(var e,r=1,i=arguments.length;++r=0&&(r=n.slice(e+1),n=n.slice(0,e)),n)return arguments.length<2?this[n].on(r):this[n].on(r,t);if(2===arguments.length){if(null==t)for(n in this)this.hasOwnProperty(n)&&this[n].on(r,null);return this}},ao.event=null,ao.requote=function(n){return n.replace(So,"\\$&")};var So=/[\\\^\$\*\+\?\|\[\]\(\)\.\{\}]/g,ko={}.__proto__?function(n,t){n.__proto__=t}:function(n,t){for(var e in t)n[e]=t[e]},No=function(n,t){return t.querySelector(n)},Eo=function(n,t){return t.querySelectorAll(n)},Ao=function(n,t){var e=n.matches||n[x(n,"matchesSelector")];return(Ao=function(n,t){return e.call(n,t)})(n,t)};"function"==typeof Sizzle&&(No=function(n,t){return Sizzle(n,t)[0]||null},Eo=Sizzle,Ao=Sizzle.matchesSelector),ao.selection=function(){return ao.select(fo.documentElement)};var Co=ao.selection.prototype=[];Co.select=function(n){var t,e,r,i,u=[];n=A(n);for(var o=-1,a=this.length;++o=0&&"xmlns"!==(e=n.slice(0,t))&&(n=n.slice(t+1)),Lo.hasOwnProperty(e)?{space:Lo[e],local:n}:n}},Co.attr=function(n,t){if(arguments.length<2){if("string"==typeof n){var e=this.node();return n=ao.ns.qualify(n),n.local?e.getAttributeNS(n.space,n.local):e.getAttribute(n)}for(t in n)this.each(z(t,n[t]));return this}return this.each(z(n,t))},Co.classed=function(n,t){if(arguments.length<2){if("string"==typeof n){var e=this.node(),r=(n=T(n)).length,i=-1;if(t=e.classList){for(;++ii){if("string"!=typeof n){2>i&&(e="");for(r in n)this.each(P(r,n[r],e));return this}if(2>i){var u=this.node();return t(u).getComputedStyle(u,null).getPropertyValue(n)}r=""}return this.each(P(n,e,r))},Co.property=function(n,t){if(arguments.length<2){if("string"==typeof n)return this.node()[n];for(t in n)this.each(U(t,n[t]));return this}return this.each(U(n,t))},Co.text=function(n){return arguments.length?this.each("function"==typeof n?function(){var t=n.apply(this,arguments);this.textContent=null==t?"":t}:null==n?function(){this.textContent=""}:function(){this.textContent=n}):this.node().textContent},Co.html=function(n){return arguments.length?this.each("function"==typeof n?function(){var t=n.apply(this,arguments);this.innerHTML=null==t?"":t}:null==n?function(){this.innerHTML=""}:function(){this.innerHTML=n}):this.node().innerHTML},Co.append=function(n){return n=j(n),this.select(function(){return this.appendChild(n.apply(this,arguments))})},Co.insert=function(n,t){return n=j(n),t=A(t),this.select(function(){return this.insertBefore(n.apply(this,arguments),t.apply(this,arguments)||null)})},Co.remove=function(){return this.each(F)},Co.data=function(n,t){function e(n,e){var r,i,u,o=n.length,s=e.length,h=Math.min(o,s),p=new Array(s),g=new Array(s),v=new Array(o);if(t){var d,y=new c,m=new Array(o);for(r=-1;++rr;++r)g[r]=H(e[r]);for(;o>r;++r)v[r]=n[r]}g.update=p,g.parentNode=p.parentNode=v.parentNode=n.parentNode,a.push(g),l.push(p),f.push(v)}var r,i,u=-1,o=this.length;if(!arguments.length){for(n=new Array(o=(r=this[0]).length);++uu;u++){i.push(t=[]),t.parentNode=(e=this[u]).parentNode;for(var a=0,l=e.length;l>a;a++)(r=e[a])&&n.call(r,r.__data__,a,u)&&t.push(r)}return E(i)},Co.order=function(){for(var n=-1,t=this.length;++n=0;)(e=r[i])&&(u&&u!==e.nextSibling&&u.parentNode.insertBefore(e,u),u=e);return this},Co.sort=function(n){n=I.apply(this,arguments);for(var t=-1,e=this.length;++tn;n++)for(var e=this[n],r=0,i=e.length;i>r;r++){var u=e[r];if(u)return u}return null},Co.size=function(){var n=0;return Y(this,function(){++n}),n};var qo=[];ao.selection.enter=Z,ao.selection.enter.prototype=qo,qo.append=Co.append,qo.empty=Co.empty,qo.node=Co.node,qo.call=Co.call,qo.size=Co.size,qo.select=function(n){for(var t,e,r,i,u,o=[],a=-1,l=this.length;++ar){if("string"!=typeof n){2>r&&(t=!1);for(e in n)this.each(X(e,n[e],t));return this}if(2>r)return(r=this.node()["__on"+n])&&r._;e=!1}return this.each(X(n,t,e))};var To=ao.map({mouseenter:"mouseover",mouseleave:"mouseout"});fo&&To.forEach(function(n){"on"+n in fo&&To.remove(n)});var Ro,Do=0;ao.mouse=function(n){return J(n,k())};var Po=this.navigator&&/WebKit/.test(this.navigator.userAgent)?-1:0;ao.touch=function(n,t,e){if(arguments.length<3&&(e=t,t=k().changedTouches),t)for(var r,i=0,u=t.length;u>i;++i)if((r=t[i]).identifier===e)return J(n,r)},ao.behavior.drag=function(){function n(){this.on("mousedown.drag",u).on("touchstart.drag",o)}function e(n,t,e,u,o){return function(){function a(){var n,e,r=t(h,v);r&&(n=r[0]-M[0],e=r[1]-M[1],g|=n|e,M=r,p({type:"drag",x:r[0]+c[0],y:r[1]+c[1],dx:n,dy:e}))}function l(){t(h,v)&&(y.on(u+d,null).on(o+d,null),m(g),p({type:"dragend"}))}var c,f=this,s=ao.event.target.correspondingElement||ao.event.target,h=f.parentNode,p=r.of(f,arguments),g=0,v=n(),d=".drag"+(null==v?"":"-"+v),y=ao.select(e(s)).on(u+d,a).on(o+d,l),m=W(s),M=t(h,v);i?(c=i.apply(f,arguments),c=[c.x-M[0],c.y-M[1]]):c=[0,0],p({type:"dragstart"})}}var r=N(n,"drag","dragstart","dragend"),i=null,u=e(b,ao.mouse,t,"mousemove","mouseup"),o=e(G,ao.touch,m,"touchmove","touchend");return n.origin=function(t){return arguments.length?(i=t,n):i},ao.rebind(n,r,"on")},ao.touches=function(n,t){return arguments.length<2&&(t=k().touches),t?co(t).map(function(t){var e=J(n,t);return e.identifier=t.identifier,e}):[]};var Uo=1e-6,jo=Uo*Uo,Fo=Math.PI,Ho=2*Fo,Oo=Ho-Uo,Io=Fo/2,Yo=Fo/180,Zo=180/Fo,Vo=Math.SQRT2,Xo=2,$o=4;ao.interpolateZoom=function(n,t){var e,r,i=n[0],u=n[1],o=n[2],a=t[0],l=t[1],c=t[2],f=a-i,s=l-u,h=f*f+s*s;if(jo>h)r=Math.log(c/o)/Vo,e=function(n){return[i+n*f,u+n*s,o*Math.exp(Vo*n*r)]};else{var p=Math.sqrt(h),g=(c*c-o*o+$o*h)/(2*o*Xo*p),v=(c*c-o*o-$o*h)/(2*c*Xo*p),d=Math.log(Math.sqrt(g*g+1)-g),y=Math.log(Math.sqrt(v*v+1)-v);r=(y-d)/Vo,e=function(n){var t=n*r,e=rn(d),a=o/(Xo*p)*(e*un(Vo*t+d)-en(d));return[i+a*f,u+a*s,o*e/rn(Vo*t+d)]}}return e.duration=1e3*r,e},ao.behavior.zoom=function(){function n(n){n.on(L,s).on(Wo+".zoom",p).on("dblclick.zoom",g).on(R,h)}function e(n){return[(n[0]-k.x)/k.k,(n[1]-k.y)/k.k]}function r(n){return[n[0]*k.k+k.x,n[1]*k.k+k.y]}function i(n){k.k=Math.max(A[0],Math.min(A[1],n))}function u(n,t){t=r(t),k.x+=n[0]-t[0],k.y+=n[1]-t[1]}function o(t,e,r,o){t.__chart__={x:k.x,y:k.y,k:k.k},i(Math.pow(2,o)),u(d=e,r),t=ao.select(t),C>0&&(t=t.transition().duration(C)),t.call(n.event)}function a(){b&&b.domain(x.range().map(function(n){return(n-k.x)/k.k}).map(x.invert)),w&&w.domain(_.range().map(function(n){return(n-k.y)/k.k}).map(_.invert))}function l(n){z++||n({type:"zoomstart"})}function c(n){a(),n({type:"zoom",scale:k.k,translate:[k.x,k.y]})}function f(n){--z||(n({type:"zoomend"}),d=null)}function s(){function n(){a=1,u(ao.mouse(i),h),c(o)}function r(){s.on(q,null).on(T,null),p(a),f(o)}var i=this,o=D.of(i,arguments),a=0,s=ao.select(t(i)).on(q,n).on(T,r),h=e(ao.mouse(i)),p=W(i);Il.call(i),l(o)}function h(){function n(){var n=ao.touches(g);return p=k.k,n.forEach(function(n){n.identifier in d&&(d[n.identifier]=e(n))}),n}function t(){var t=ao.event.target;ao.select(t).on(x,r).on(b,a),_.push(t);for(var e=ao.event.changedTouches,i=0,u=e.length;u>i;++i)d[e[i].identifier]=null;var l=n(),c=Date.now();if(1===l.length){if(500>c-M){var f=l[0];o(g,f,d[f.identifier],Math.floor(Math.log(k.k)/Math.LN2)+1),S()}M=c}else if(l.length>1){var f=l[0],s=l[1],h=f[0]-s[0],p=f[1]-s[1];y=h*h+p*p}}function r(){var n,t,e,r,o=ao.touches(g);Il.call(g);for(var a=0,l=o.length;l>a;++a,r=null)if(e=o[a],r=d[e.identifier]){if(t)break;n=e,t=r}if(r){var f=(f=e[0]-n[0])*f+(f=e[1]-n[1])*f,s=y&&Math.sqrt(f/y);n=[(n[0]+e[0])/2,(n[1]+e[1])/2],t=[(t[0]+r[0])/2,(t[1]+r[1])/2],i(s*p)}M=null,u(n,t),c(v)}function a(){if(ao.event.touches.length){for(var t=ao.event.changedTouches,e=0,r=t.length;r>e;++e)delete d[t[e].identifier];for(var i in d)return void n()}ao.selectAll(_).on(m,null),w.on(L,s).on(R,h),N(),f(v)}var p,g=this,v=D.of(g,arguments),d={},y=0,m=".zoom-"+ao.event.changedTouches[0].identifier,x="touchmove"+m,b="touchend"+m,_=[],w=ao.select(g),N=W(g);t(),l(v),w.on(L,null).on(R,t)}function p(){var n=D.of(this,arguments);m?clearTimeout(m):(Il.call(this),v=e(d=y||ao.mouse(this)),l(n)),m=setTimeout(function(){m=null,f(n)},50),S(),i(Math.pow(2,.002*Bo())*k.k),u(d,v),c(n)}function g(){var n=ao.mouse(this),t=Math.log(k.k)/Math.LN2;o(this,n,e(n),ao.event.shiftKey?Math.ceil(t)-1:Math.floor(t)+1)}var v,d,y,m,M,x,b,_,w,k={x:0,y:0,k:1},E=[960,500],A=Jo,C=250,z=0,L="mousedown.zoom",q="mousemove.zoom",T="mouseup.zoom",R="touchstart.zoom",D=N(n,"zoomstart","zoom","zoomend");return Wo||(Wo="onwheel"in fo?(Bo=function(){return-ao.event.deltaY*(ao.event.deltaMode?120:1)},"wheel"):"onmousewheel"in fo?(Bo=function(){return ao.event.wheelDelta},"mousewheel"):(Bo=function(){return-ao.event.detail},"MozMousePixelScroll")),n.event=function(n){n.each(function(){var n=D.of(this,arguments),t=k;Hl?ao.select(this).transition().each("start.zoom",function(){k=this.__chart__||{x:0,y:0,k:1},l(n)}).tween("zoom:zoom",function(){var e=E[0],r=E[1],i=d?d[0]:e/2,u=d?d[1]:r/2,o=ao.interpolateZoom([(i-k.x)/k.k,(u-k.y)/k.k,e/k.k],[(i-t.x)/t.k,(u-t.y)/t.k,e/t.k]);return function(t){var r=o(t),a=e/r[2];this.__chart__=k={x:i-r[0]*a,y:u-r[1]*a,k:a},c(n)}}).each("interrupt.zoom",function(){f(n)}).each("end.zoom",function(){f(n)}):(this.__chart__=k,l(n),c(n),f(n))})},n.translate=function(t){return arguments.length?(k={x:+t[0],y:+t[1],k:k.k},a(),n):[k.x,k.y]},n.scale=function(t){return arguments.length?(k={x:k.x,y:k.y,k:null},i(+t),a(),n):k.k},n.scaleExtent=function(t){return arguments.length?(A=null==t?Jo:[+t[0],+t[1]],n):A},n.center=function(t){return arguments.length?(y=t&&[+t[0],+t[1]],n):y},n.size=function(t){return arguments.length?(E=t&&[+t[0],+t[1]],n):E},n.duration=function(t){return arguments.length?(C=+t,n):C},n.x=function(t){return arguments.length?(b=t,x=t.copy(),k={x:0,y:0,k:1},n):b},n.y=function(t){return arguments.length?(w=t,_=t.copy(),k={x:0,y:0,k:1},n):w},ao.rebind(n,D,"on")};var Bo,Wo,Jo=[0,1/0];ao.color=an,an.prototype.toString=function(){return this.rgb()+""},ao.hsl=ln;var Go=ln.prototype=new an;Go.brighter=function(n){return n=Math.pow(.7,arguments.length?n:1),new ln(this.h,this.s,this.l/n)},Go.darker=function(n){return n=Math.pow(.7,arguments.length?n:1),new ln(this.h,this.s,n*this.l)},Go.rgb=function(){return cn(this.h,this.s,this.l)},ao.hcl=fn;var Ko=fn.prototype=new an;Ko.brighter=function(n){return new fn(this.h,this.c,Math.min(100,this.l+Qo*(arguments.length?n:1)))},Ko.darker=function(n){return new fn(this.h,this.c,Math.max(0,this.l-Qo*(arguments.length?n:1)))},Ko.rgb=function(){return sn(this.h,this.c,this.l).rgb()},ao.lab=hn;var Qo=18,na=.95047,ta=1,ea=1.08883,ra=hn.prototype=new an;ra.brighter=function(n){return new hn(Math.min(100,this.l+Qo*(arguments.length?n:1)),this.a,this.b)},ra.darker=function(n){return new hn(Math.max(0,this.l-Qo*(arguments.length?n:1)),this.a,this.b)},ra.rgb=function(){return pn(this.l,this.a,this.b)},ao.rgb=mn;var ia=mn.prototype=new an;ia.brighter=function(n){n=Math.pow(.7,arguments.length?n:1);var t=this.r,e=this.g,r=this.b,i=30;return t||e||r?(t&&i>t&&(t=i),e&&i>e&&(e=i),r&&i>r&&(r=i),new mn(Math.min(255,t/n),Math.min(255,e/n),Math.min(255,r/n))):new mn(i,i,i)},ia.darker=function(n){return n=Math.pow(.7,arguments.length?n:1),new mn(n*this.r,n*this.g,n*this.b)},ia.hsl=function(){return wn(this.r,this.g,this.b)},ia.toString=function(){return"#"+bn(this.r)+bn(this.g)+bn(this.b)};var ua=ao.map({aliceblue:15792383,antiquewhite:16444375,aqua:65535,aquamarine:8388564,azure:15794175,beige:16119260,bisque:16770244,black:0,blanchedalmond:16772045,blue:255,blueviolet:9055202,brown:10824234,burlywood:14596231,cadetblue:6266528,chartreuse:8388352,chocolate:13789470,coral:16744272,cornflowerblue:6591981,cornsilk:16775388,crimson:14423100,cyan:65535,darkblue:139,darkcyan:35723,darkgoldenrod:12092939,darkgray:11119017,darkgreen:25600,darkgrey:11119017,darkkhaki:12433259,darkmagenta:9109643,darkolivegreen:5597999,darkorange:16747520,darkorchid:10040012,darkred:9109504,darksalmon:15308410,darkseagreen:9419919,darkslateblue:4734347,darkslategray:3100495,darkslategrey:3100495,darkturquoise:52945,darkviolet:9699539,deeppink:16716947,deepskyblue:49151,dimgray:6908265,dimgrey:6908265,dodgerblue:2003199,firebrick:11674146,floralwhite:16775920,forestgreen:2263842,fuchsia:16711935,gainsboro:14474460,ghostwhite:16316671,gold:16766720,goldenrod:14329120,gray:8421504,green:32768,greenyellow:11403055,grey:8421504,honeydew:15794160,hotpink:16738740,indianred:13458524,indigo:4915330,ivory:16777200,khaki:15787660,lavender:15132410,lavenderblush:16773365,lawngreen:8190976,lemonchiffon:16775885,lightblue:11393254,lightcoral:15761536,lightcyan:14745599,lightgoldenrodyellow:16448210,lightgray:13882323,lightgreen:9498256,lightgrey:13882323,lightpink:16758465,lightsalmon:16752762,lightseagreen:2142890,lightskyblue:8900346,lightslategray:7833753,lightslategrey:7833753,lightsteelblue:11584734,lightyellow:16777184,lime:65280,limegreen:3329330,linen:16445670,magenta:16711935,maroon:8388608,mediumaquamarine:6737322,mediumblue:205,mediumorchid:12211667,mediumpurple:9662683,mediumseagreen:3978097,mediumslateblue:8087790,mediumspringgreen:64154,mediumturquoise:4772300,mediumvioletred:13047173,midnightblue:1644912,mintcream:16121850,mistyrose:16770273,moccasin:16770229,navajowhite:16768685,navy:128,oldlace:16643558,olive:8421376,olivedrab:7048739,orange:16753920,orangered:16729344,orchid:14315734,palegoldenrod:15657130,palegreen:10025880,paleturquoise:11529966,palevioletred:14381203,papayawhip:16773077,peachpuff:16767673,peru:13468991,pink:16761035,plum:14524637,powderblue:11591910,purple:8388736,rebeccapurple:6697881,red:16711680,rosybrown:12357519,royalblue:4286945,saddlebrown:9127187,salmon:16416882,sandybrown:16032864,seagreen:3050327,seashell:16774638,sienna:10506797,silver:12632256,skyblue:8900331,slateblue:6970061,slategray:7372944,slategrey:7372944,snow:16775930,springgreen:65407,steelblue:4620980,tan:13808780,teal:32896,thistle:14204888,tomato:16737095,turquoise:4251856,violet:15631086,wheat:16113331,white:16777215,whitesmoke:16119285,yellow:16776960,yellowgreen:10145074});ua.forEach(function(n,t){ua.set(n,Mn(t))}),ao.functor=En,ao.xhr=An(m),ao.dsv=function(n,t){function e(n,e,u){arguments.length<3&&(u=e,e=null);var o=Cn(n,t,null==e?r:i(e),u);return o.row=function(n){return arguments.length?o.response(null==(e=n)?r:i(n)):e},o}function r(n){return e.parse(n.responseText)}function i(n){return function(t){return e.parse(t.responseText,n)}}function u(t){return t.map(o).join(n)}function o(n){return a.test(n)?'"'+n.replace(/\"/g,'""')+'"':n}var a=new RegExp('["'+n+"\n]"),l=n.charCodeAt(0);return e.parse=function(n,t){var r;return e.parseRows(n,function(n,e){if(r)return r(n,e-1);var i=new Function("d","return {"+n.map(function(n,t){return JSON.stringify(n)+": d["+t+"]"}).join(",")+"}");r=t?function(n,e){return t(i(n),e)}:i})},e.parseRows=function(n,t){function e(){if(f>=c)return o;if(i)return i=!1,u;var t=f;if(34===n.charCodeAt(t)){for(var e=t;e++f;){var r=n.charCodeAt(f++),a=1;if(10===r)i=!0;else if(13===r)i=!0,10===n.charCodeAt(f)&&(++f,++a);else if(r!==l)continue;return n.slice(t,f-a)}return n.slice(t)}for(var r,i,u={},o={},a=[],c=n.length,f=0,s=0;(r=e())!==o;){for(var h=[];r!==u&&r!==o;)h.push(r),r=e();t&&null==(h=t(h,s++))||a.push(h)}return a},e.format=function(t){if(Array.isArray(t[0]))return e.formatRows(t);var r=new y,i=[];return t.forEach(function(n){for(var t in n)r.has(t)||i.push(r.add(t))}),[i.map(o).join(n)].concat(t.map(function(t){return i.map(function(n){return o(t[n])}).join(n)})).join("\n")},e.formatRows=function(n){return n.map(u).join("\n")},e},ao.csv=ao.dsv(",","text/csv"),ao.tsv=ao.dsv(" ","text/tab-separated-values");var oa,aa,la,ca,fa=this[x(this,"requestAnimationFrame")]||function(n){setTimeout(n,17)};ao.timer=function(){qn.apply(this,arguments)},ao.timer.flush=function(){Rn(),Dn()},ao.round=function(n,t){return t?Math.round(n*(t=Math.pow(10,t)))/t:Math.round(n)};var sa=["y","z","a","f","p","n","\xb5","m","","k","M","G","T","P","E","Z","Y"].map(Un);ao.formatPrefix=function(n,t){var e=0;return(n=+n)&&(0>n&&(n*=-1),t&&(n=ao.round(n,Pn(n,t))),e=1+Math.floor(1e-12+Math.log(n)/Math.LN10),e=Math.max(-24,Math.min(24,3*Math.floor((e-1)/3)))),sa[8+e/3]};var ha=/(?:([^{])?([<>=^]))?([+\- ])?([$#])?(0)?(\d+)?(,)?(\.-?\d+)?([a-z%])?/i,pa=ao.map({b:function(n){return n.toString(2)},c:function(n){return String.fromCharCode(n)},o:function(n){return n.toString(8)},x:function(n){return n.toString(16)},X:function(n){return n.toString(16).toUpperCase()},g:function(n,t){return n.toPrecision(t)},e:function(n,t){return n.toExponential(t)},f:function(n,t){return n.toFixed(t)},r:function(n,t){return(n=ao.round(n,Pn(n,t))).toFixed(Math.max(0,Math.min(20,Pn(n*(1+1e-15),t))))}}),ga=ao.time={},va=Date;Hn.prototype={getDate:function(){return this._.getUTCDate()},getDay:function(){return this._.getUTCDay()},getFullYear:function(){return this._.getUTCFullYear()},getHours:function(){return this._.getUTCHours()},getMilliseconds:function(){return this._.getUTCMilliseconds()},getMinutes:function(){return this._.getUTCMinutes()},getMonth:function(){return this._.getUTCMonth()},getSeconds:function(){return this._.getUTCSeconds()},getTime:function(){return this._.getTime()},getTimezoneOffset:function(){return 0},valueOf:function(){return this._.valueOf()},setDate:function(){da.setUTCDate.apply(this._,arguments)},setDay:function(){da.setUTCDay.apply(this._,arguments)},setFullYear:function(){da.setUTCFullYear.apply(this._,arguments)},setHours:function(){da.setUTCHours.apply(this._,arguments)},setMilliseconds:function(){da.setUTCMilliseconds.apply(this._,arguments)},setMinutes:function(){da.setUTCMinutes.apply(this._,arguments)},setMonth:function(){da.setUTCMonth.apply(this._,arguments)},setSeconds:function(){da.setUTCSeconds.apply(this._,arguments)},setTime:function(){da.setTime.apply(this._,arguments)}};var da=Date.prototype;ga.year=On(function(n){return n=ga.day(n),n.setMonth(0,1),n},function(n,t){n.setFullYear(n.getFullYear()+t)},function(n){return n.getFullYear()}),ga.years=ga.year.range,ga.years.utc=ga.year.utc.range,ga.day=On(function(n){var t=new va(2e3,0);return t.setFullYear(n.getFullYear(),n.getMonth(),n.getDate()),t},function(n,t){n.setDate(n.getDate()+t)},function(n){return n.getDate()-1}),ga.days=ga.day.range,ga.days.utc=ga.day.utc.range,ga.dayOfYear=function(n){var t=ga.year(n);return Math.floor((n-t-6e4*(n.getTimezoneOffset()-t.getTimezoneOffset()))/864e5)},["sunday","monday","tuesday","wednesday","thursday","friday","saturday"].forEach(function(n,t){t=7-t;var e=ga[n]=On(function(n){return(n=ga.day(n)).setDate(n.getDate()-(n.getDay()+t)%7),n},function(n,t){n.setDate(n.getDate()+7*Math.floor(t))},function(n){var e=ga.year(n).getDay();return Math.floor((ga.dayOfYear(n)+(e+t)%7)/7)-(e!==t)});ga[n+"s"]=e.range,ga[n+"s"].utc=e.utc.range,ga[n+"OfYear"]=function(n){var e=ga.year(n).getDay();return Math.floor((ga.dayOfYear(n)+(e+t)%7)/7)}}),ga.week=ga.sunday,ga.weeks=ga.sunday.range,ga.weeks.utc=ga.sunday.utc.range,ga.weekOfYear=ga.sundayOfYear;var ya={"-":"",_:" ",0:"0"},ma=/^\s*\d+/,Ma=/^%/;ao.locale=function(n){return{numberFormat:jn(n),timeFormat:Yn(n)}};var xa=ao.locale({decimal:".",thousands:",",grouping:[3],currency:["$",""],dateTime:"%a %b %e %X %Y",date:"%m/%d/%Y",time:"%H:%M:%S",periods:["AM","PM"],days:["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"], -shortDays:["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],months:["January","February","March","April","May","June","July","August","September","October","November","December"],shortMonths:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"]});ao.format=xa.numberFormat,ao.geo={},ft.prototype={s:0,t:0,add:function(n){st(n,this.t,ba),st(ba.s,this.s,this),this.s?this.t+=ba.t:this.s=ba.t},reset:function(){this.s=this.t=0},valueOf:function(){return this.s}};var ba=new ft;ao.geo.stream=function(n,t){n&&_a.hasOwnProperty(n.type)?_a[n.type](n,t):ht(n,t)};var _a={Feature:function(n,t){ht(n.geometry,t)},FeatureCollection:function(n,t){for(var e=n.features,r=-1,i=e.length;++rn?4*Fo+n:n,Na.lineStart=Na.lineEnd=Na.point=b}};ao.geo.bounds=function(){function n(n,t){M.push(x=[f=n,h=n]),s>t&&(s=t),t>p&&(p=t)}function t(t,e){var r=dt([t*Yo,e*Yo]);if(y){var i=mt(y,r),u=[i[1],-i[0],0],o=mt(u,i);bt(o),o=_t(o);var l=t-g,c=l>0?1:-1,v=o[0]*Zo*c,d=xo(l)>180;if(d^(v>c*g&&c*t>v)){var m=o[1]*Zo;m>p&&(p=m)}else if(v=(v+360)%360-180,d^(v>c*g&&c*t>v)){var m=-o[1]*Zo;s>m&&(s=m)}else s>e&&(s=e),e>p&&(p=e);d?g>t?a(f,t)>a(f,h)&&(h=t):a(t,h)>a(f,h)&&(f=t):h>=f?(f>t&&(f=t),t>h&&(h=t)):t>g?a(f,t)>a(f,h)&&(h=t):a(t,h)>a(f,h)&&(f=t)}else n(t,e);y=r,g=t}function e(){b.point=t}function r(){x[0]=f,x[1]=h,b.point=n,y=null}function i(n,e){if(y){var r=n-g;m+=xo(r)>180?r+(r>0?360:-360):r}else v=n,d=e;Na.point(n,e),t(n,e)}function u(){Na.lineStart()}function o(){i(v,d),Na.lineEnd(),xo(m)>Uo&&(f=-(h=180)),x[0]=f,x[1]=h,y=null}function a(n,t){return(t-=n)<0?t+360:t}function l(n,t){return n[0]-t[0]}function c(n,t){return t[0]<=t[1]?t[0]<=n&&n<=t[1]:nka?(f=-(h=180),s=-(p=90)):m>Uo?p=90:-Uo>m&&(s=-90),x[0]=f,x[1]=h}};return function(n){p=h=-(f=s=1/0),M=[],ao.geo.stream(n,b);var t=M.length;if(t){M.sort(l);for(var e,r=1,i=M[0],u=[i];t>r;++r)e=M[r],c(e[0],i)||c(e[1],i)?(a(i[0],e[1])>a(i[0],i[1])&&(i[1]=e[1]),a(e[0],i[1])>a(i[0],i[1])&&(i[0]=e[0])):u.push(i=e);for(var o,e,g=-(1/0),t=u.length-1,r=0,i=u[t];t>=r;i=e,++r)e=u[r],(o=a(i[1],e[0]))>g&&(g=o,f=e[0],h=i[1])}return M=x=null,f===1/0||s===1/0?[[NaN,NaN],[NaN,NaN]]:[[f,s],[h,p]]}}(),ao.geo.centroid=function(n){Ea=Aa=Ca=za=La=qa=Ta=Ra=Da=Pa=Ua=0,ao.geo.stream(n,ja);var t=Da,e=Pa,r=Ua,i=t*t+e*e+r*r;return jo>i&&(t=qa,e=Ta,r=Ra,Uo>Aa&&(t=Ca,e=za,r=La),i=t*t+e*e+r*r,jo>i)?[NaN,NaN]:[Math.atan2(e,t)*Zo,tn(r/Math.sqrt(i))*Zo]};var Ea,Aa,Ca,za,La,qa,Ta,Ra,Da,Pa,Ua,ja={sphere:b,point:St,lineStart:Nt,lineEnd:Et,polygonStart:function(){ja.lineStart=At},polygonEnd:function(){ja.lineStart=Nt}},Fa=Rt(zt,jt,Ht,[-Fo,-Fo/2]),Ha=1e9;ao.geo.clipExtent=function(){var n,t,e,r,i,u,o={stream:function(n){return i&&(i.valid=!1),i=u(n),i.valid=!0,i},extent:function(a){return arguments.length?(u=Zt(n=+a[0][0],t=+a[0][1],e=+a[1][0],r=+a[1][1]),i&&(i.valid=!1,i=null),o):[[n,t],[e,r]]}};return o.extent([[0,0],[960,500]])},(ao.geo.conicEqualArea=function(){return Vt(Xt)}).raw=Xt,ao.geo.albers=function(){return ao.geo.conicEqualArea().rotate([96,0]).center([-.6,38.7]).parallels([29.5,45.5]).scale(1070)},ao.geo.albersUsa=function(){function n(n){var u=n[0],o=n[1];return t=null,e(u,o),t||(r(u,o),t)||i(u,o),t}var t,e,r,i,u=ao.geo.albers(),o=ao.geo.conicEqualArea().rotate([154,0]).center([-2,58.5]).parallels([55,65]),a=ao.geo.conicEqualArea().rotate([157,0]).center([-3,19.9]).parallels([8,18]),l={point:function(n,e){t=[n,e]}};return n.invert=function(n){var t=u.scale(),e=u.translate(),r=(n[0]-e[0])/t,i=(n[1]-e[1])/t;return(i>=.12&&.234>i&&r>=-.425&&-.214>r?o:i>=.166&&.234>i&&r>=-.214&&-.115>r?a:u).invert(n)},n.stream=function(n){var t=u.stream(n),e=o.stream(n),r=a.stream(n);return{point:function(n,i){t.point(n,i),e.point(n,i),r.point(n,i)},sphere:function(){t.sphere(),e.sphere(),r.sphere()},lineStart:function(){t.lineStart(),e.lineStart(),r.lineStart()},lineEnd:function(){t.lineEnd(),e.lineEnd(),r.lineEnd()},polygonStart:function(){t.polygonStart(),e.polygonStart(),r.polygonStart()},polygonEnd:function(){t.polygonEnd(),e.polygonEnd(),r.polygonEnd()}}},n.precision=function(t){return arguments.length?(u.precision(t),o.precision(t),a.precision(t),n):u.precision()},n.scale=function(t){return arguments.length?(u.scale(t),o.scale(.35*t),a.scale(t),n.translate(u.translate())):u.scale()},n.translate=function(t){if(!arguments.length)return u.translate();var c=u.scale(),f=+t[0],s=+t[1];return e=u.translate(t).clipExtent([[f-.455*c,s-.238*c],[f+.455*c,s+.238*c]]).stream(l).point,r=o.translate([f-.307*c,s+.201*c]).clipExtent([[f-.425*c+Uo,s+.12*c+Uo],[f-.214*c-Uo,s+.234*c-Uo]]).stream(l).point,i=a.translate([f-.205*c,s+.212*c]).clipExtent([[f-.214*c+Uo,s+.166*c+Uo],[f-.115*c-Uo,s+.234*c-Uo]]).stream(l).point,n},n.scale(1070)};var Oa,Ia,Ya,Za,Va,Xa,$a={point:b,lineStart:b,lineEnd:b,polygonStart:function(){Ia=0,$a.lineStart=$t},polygonEnd:function(){$a.lineStart=$a.lineEnd=$a.point=b,Oa+=xo(Ia/2)}},Ba={point:Bt,lineStart:b,lineEnd:b,polygonStart:b,polygonEnd:b},Wa={point:Gt,lineStart:Kt,lineEnd:Qt,polygonStart:function(){Wa.lineStart=ne},polygonEnd:function(){Wa.point=Gt,Wa.lineStart=Kt,Wa.lineEnd=Qt}};ao.geo.path=function(){function n(n){return n&&("function"==typeof a&&u.pointRadius(+a.apply(this,arguments)),o&&o.valid||(o=i(u)),ao.geo.stream(n,o)),u.result()}function t(){return o=null,n}var e,r,i,u,o,a=4.5;return n.area=function(n){return Oa=0,ao.geo.stream(n,i($a)),Oa},n.centroid=function(n){return Ca=za=La=qa=Ta=Ra=Da=Pa=Ua=0,ao.geo.stream(n,i(Wa)),Ua?[Da/Ua,Pa/Ua]:Ra?[qa/Ra,Ta/Ra]:La?[Ca/La,za/La]:[NaN,NaN]},n.bounds=function(n){return Va=Xa=-(Ya=Za=1/0),ao.geo.stream(n,i(Ba)),[[Ya,Za],[Va,Xa]]},n.projection=function(n){return arguments.length?(i=(e=n)?n.stream||re(n):m,t()):e},n.context=function(n){return arguments.length?(u=null==(r=n)?new Wt:new te(n),"function"!=typeof a&&u.pointRadius(a),t()):r},n.pointRadius=function(t){return arguments.length?(a="function"==typeof t?t:(u.pointRadius(+t),+t),n):a},n.projection(ao.geo.albersUsa()).context(null)},ao.geo.transform=function(n){return{stream:function(t){var e=new ie(t);for(var r in n)e[r]=n[r];return e}}},ie.prototype={point:function(n,t){this.stream.point(n,t)},sphere:function(){this.stream.sphere()},lineStart:function(){this.stream.lineStart()},lineEnd:function(){this.stream.lineEnd()},polygonStart:function(){this.stream.polygonStart()},polygonEnd:function(){this.stream.polygonEnd()}},ao.geo.projection=oe,ao.geo.projectionMutator=ae,(ao.geo.equirectangular=function(){return oe(ce)}).raw=ce.invert=ce,ao.geo.rotation=function(n){function t(t){return t=n(t[0]*Yo,t[1]*Yo),t[0]*=Zo,t[1]*=Zo,t}return n=se(n[0]%360*Yo,n[1]*Yo,n.length>2?n[2]*Yo:0),t.invert=function(t){return t=n.invert(t[0]*Yo,t[1]*Yo),t[0]*=Zo,t[1]*=Zo,t},t},fe.invert=ce,ao.geo.circle=function(){function n(){var n="function"==typeof r?r.apply(this,arguments):r,t=se(-n[0]*Yo,-n[1]*Yo,0).invert,i=[];return e(null,null,1,{point:function(n,e){i.push(n=t(n,e)),n[0]*=Zo,n[1]*=Zo}}),{type:"Polygon",coordinates:[i]}}var t,e,r=[0,0],i=6;return n.origin=function(t){return arguments.length?(r=t,n):r},n.angle=function(r){return arguments.length?(e=ve((t=+r)*Yo,i*Yo),n):t},n.precision=function(r){return arguments.length?(e=ve(t*Yo,(i=+r)*Yo),n):i},n.angle(90)},ao.geo.distance=function(n,t){var e,r=(t[0]-n[0])*Yo,i=n[1]*Yo,u=t[1]*Yo,o=Math.sin(r),a=Math.cos(r),l=Math.sin(i),c=Math.cos(i),f=Math.sin(u),s=Math.cos(u);return Math.atan2(Math.sqrt((e=s*o)*e+(e=c*f-l*s*a)*e),l*f+c*s*a)},ao.geo.graticule=function(){function n(){return{type:"MultiLineString",coordinates:t()}}function t(){return ao.range(Math.ceil(u/d)*d,i,d).map(h).concat(ao.range(Math.ceil(c/y)*y,l,y).map(p)).concat(ao.range(Math.ceil(r/g)*g,e,g).filter(function(n){return xo(n%d)>Uo}).map(f)).concat(ao.range(Math.ceil(a/v)*v,o,v).filter(function(n){return xo(n%y)>Uo}).map(s))}var e,r,i,u,o,a,l,c,f,s,h,p,g=10,v=g,d=90,y=360,m=2.5;return n.lines=function(){return t().map(function(n){return{type:"LineString",coordinates:n}})},n.outline=function(){return{type:"Polygon",coordinates:[h(u).concat(p(l).slice(1),h(i).reverse().slice(1),p(c).reverse().slice(1))]}},n.extent=function(t){return arguments.length?n.majorExtent(t).minorExtent(t):n.minorExtent()},n.majorExtent=function(t){return arguments.length?(u=+t[0][0],i=+t[1][0],c=+t[0][1],l=+t[1][1],u>i&&(t=u,u=i,i=t),c>l&&(t=c,c=l,l=t),n.precision(m)):[[u,c],[i,l]]},n.minorExtent=function(t){return arguments.length?(r=+t[0][0],e=+t[1][0],a=+t[0][1],o=+t[1][1],r>e&&(t=r,r=e,e=t),a>o&&(t=a,a=o,o=t),n.precision(m)):[[r,a],[e,o]]},n.step=function(t){return arguments.length?n.majorStep(t).minorStep(t):n.minorStep()},n.majorStep=function(t){return arguments.length?(d=+t[0],y=+t[1],n):[d,y]},n.minorStep=function(t){return arguments.length?(g=+t[0],v=+t[1],n):[g,v]},n.precision=function(t){return arguments.length?(m=+t,f=ye(a,o,90),s=me(r,e,m),h=ye(c,l,90),p=me(u,i,m),n):m},n.majorExtent([[-180,-90+Uo],[180,90-Uo]]).minorExtent([[-180,-80-Uo],[180,80+Uo]])},ao.geo.greatArc=function(){function n(){return{type:"LineString",coordinates:[t||r.apply(this,arguments),e||i.apply(this,arguments)]}}var t,e,r=Me,i=xe;return n.distance=function(){return ao.geo.distance(t||r.apply(this,arguments),e||i.apply(this,arguments))},n.source=function(e){return arguments.length?(r=e,t="function"==typeof e?null:e,n):r},n.target=function(t){return arguments.length?(i=t,e="function"==typeof t?null:t,n):i},n.precision=function(){return arguments.length?n:0},n},ao.geo.interpolate=function(n,t){return be(n[0]*Yo,n[1]*Yo,t[0]*Yo,t[1]*Yo)},ao.geo.length=function(n){return Ja=0,ao.geo.stream(n,Ga),Ja};var Ja,Ga={sphere:b,point:b,lineStart:_e,lineEnd:b,polygonStart:b,polygonEnd:b},Ka=we(function(n){return Math.sqrt(2/(1+n))},function(n){return 2*Math.asin(n/2)});(ao.geo.azimuthalEqualArea=function(){return oe(Ka)}).raw=Ka;var Qa=we(function(n){var t=Math.acos(n);return t&&t/Math.sin(t)},m);(ao.geo.azimuthalEquidistant=function(){return oe(Qa)}).raw=Qa,(ao.geo.conicConformal=function(){return Vt(Se)}).raw=Se,(ao.geo.conicEquidistant=function(){return Vt(ke)}).raw=ke;var nl=we(function(n){return 1/n},Math.atan);(ao.geo.gnomonic=function(){return oe(nl)}).raw=nl,Ne.invert=function(n,t){return[n,2*Math.atan(Math.exp(t))-Io]},(ao.geo.mercator=function(){return Ee(Ne)}).raw=Ne;var tl=we(function(){return 1},Math.asin);(ao.geo.orthographic=function(){return oe(tl)}).raw=tl;var el=we(function(n){return 1/(1+n)},function(n){return 2*Math.atan(n)});(ao.geo.stereographic=function(){return oe(el)}).raw=el,Ae.invert=function(n,t){return[-t,2*Math.atan(Math.exp(n))-Io]},(ao.geo.transverseMercator=function(){var n=Ee(Ae),t=n.center,e=n.rotate;return n.center=function(n){return n?t([-n[1],n[0]]):(n=t(),[n[1],-n[0]])},n.rotate=function(n){return n?e([n[0],n[1],n.length>2?n[2]+90:90]):(n=e(),[n[0],n[1],n[2]-90])},e([0,0,90])}).raw=Ae,ao.geom={},ao.geom.hull=function(n){function t(n){if(n.length<3)return[];var t,i=En(e),u=En(r),o=n.length,a=[],l=[];for(t=0;o>t;t++)a.push([+i.call(this,n[t],t),+u.call(this,n[t],t),t]);for(a.sort(qe),t=0;o>t;t++)l.push([a[t][0],-a[t][1]]);var c=Le(a),f=Le(l),s=f[0]===c[0],h=f[f.length-1]===c[c.length-1],p=[];for(t=c.length-1;t>=0;--t)p.push(n[a[c[t]][2]]);for(t=+s;t=r&&c.x<=u&&c.y>=i&&c.y<=o?[[r,o],[u,o],[u,i],[r,i]]:[];f.point=n[a]}),t}function e(n){return n.map(function(n,t){return{x:Math.round(u(n,t)/Uo)*Uo,y:Math.round(o(n,t)/Uo)*Uo,i:t}})}var r=Ce,i=ze,u=r,o=i,a=sl;return n?t(n):(t.links=function(n){return ar(e(n)).edges.filter(function(n){return n.l&&n.r}).map(function(t){return{source:n[t.l.i],target:n[t.r.i]}})},t.triangles=function(n){var t=[];return ar(e(n)).cells.forEach(function(e,r){for(var i,u,o=e.site,a=e.edges.sort(Ve),l=-1,c=a.length,f=a[c-1].edge,s=f.l===o?f.r:f.l;++l=c,h=r>=f,p=h<<1|s;n.leaf=!1,n=n.nodes[p]||(n.nodes[p]=hr()),s?i=c:a=c,h?o=f:l=f,u(n,t,e,r,i,o,a,l)}var f,s,h,p,g,v,d,y,m,M=En(a),x=En(l);if(null!=t)v=t,d=e,y=r,m=i;else if(y=m=-(v=d=1/0),s=[],h=[],g=n.length,o)for(p=0;g>p;++p)f=n[p],f.xy&&(y=f.x),f.y>m&&(m=f.y),s.push(f.x),h.push(f.y);else for(p=0;g>p;++p){var b=+M(f=n[p],p),_=+x(f,p);v>b&&(v=b),d>_&&(d=_),b>y&&(y=b),_>m&&(m=_),s.push(b),h.push(_)}var w=y-v,S=m-d;w>S?m=d+w:y=v+S;var k=hr();if(k.add=function(n){u(k,n,+M(n,++p),+x(n,p),v,d,y,m)},k.visit=function(n){pr(n,k,v,d,y,m)},k.find=function(n){return gr(k,n[0],n[1],v,d,y,m)},p=-1,null==t){for(;++p=0?n.slice(0,t):n,r=t>=0?n.slice(t+1):"in";return e=vl.get(e)||gl,r=dl.get(r)||m,br(r(e.apply(null,lo.call(arguments,1))))},ao.interpolateHcl=Rr,ao.interpolateHsl=Dr,ao.interpolateLab=Pr,ao.interpolateRound=Ur,ao.transform=function(n){var t=fo.createElementNS(ao.ns.prefix.svg,"g");return(ao.transform=function(n){if(null!=n){t.setAttribute("transform",n);var e=t.transform.baseVal.consolidate()}return new jr(e?e.matrix:yl)})(n)},jr.prototype.toString=function(){return"translate("+this.translate+")rotate("+this.rotate+")skewX("+this.skew+")scale("+this.scale+")"};var yl={a:1,b:0,c:0,d:1,e:0,f:0};ao.interpolateTransform=$r,ao.layout={},ao.layout.bundle=function(){return function(n){for(var t=[],e=-1,r=n.length;++ea*a/y){if(v>l){var c=t.charge/l;n.px-=u*c,n.py-=o*c}return!0}if(t.point&&l&&v>l){var c=t.pointCharge/l;n.px-=u*c,n.py-=o*c}}return!t.charge}}function t(n){n.px=ao.event.x,n.py=ao.event.y,l.resume()}var e,r,i,u,o,a,l={},c=ao.dispatch("start","tick","end"),f=[1,1],s=.9,h=ml,p=Ml,g=-30,v=xl,d=.1,y=.64,M=[],x=[];return l.tick=function(){if((i*=.99)<.005)return e=null,c.end({type:"end",alpha:i=0}),!0;var t,r,l,h,p,v,y,m,b,_=M.length,w=x.length;for(r=0;w>r;++r)l=x[r],h=l.source,p=l.target,m=p.x-h.x,b=p.y-h.y,(v=m*m+b*b)&&(v=i*o[r]*((v=Math.sqrt(v))-u[r])/v,m*=v,b*=v,p.x-=m*(y=h.weight+p.weight?h.weight/(h.weight+p.weight):.5),p.y-=b*y,h.x+=m*(y=1-y),h.y+=b*y);if((y=i*d)&&(m=f[0]/2,b=f[1]/2,r=-1,y))for(;++r<_;)l=M[r],l.x+=(m-l.x)*y,l.y+=(b-l.y)*y;if(g)for(ri(t=ao.geom.quadtree(M),i,a),r=-1;++r<_;)(l=M[r]).fixed||t.visit(n(l));for(r=-1;++r<_;)l=M[r],l.fixed?(l.x=l.px,l.y=l.py):(l.x-=(l.px-(l.px=l.x))*s,l.y-=(l.py-(l.py=l.y))*s);c.tick({type:"tick",alpha:i})},l.nodes=function(n){return arguments.length?(M=n,l):M},l.links=function(n){return arguments.length?(x=n,l):x},l.size=function(n){return arguments.length?(f=n,l):f},l.linkDistance=function(n){return arguments.length?(h="function"==typeof n?n:+n,l):h},l.distance=l.linkDistance,l.linkStrength=function(n){return arguments.length?(p="function"==typeof n?n:+n,l):p},l.friction=function(n){return arguments.length?(s=+n,l):s},l.charge=function(n){return arguments.length?(g="function"==typeof n?n:+n,l):g},l.chargeDistance=function(n){return arguments.length?(v=n*n,l):Math.sqrt(v)},l.gravity=function(n){return arguments.length?(d=+n,l):d},l.theta=function(n){return arguments.length?(y=n*n,l):Math.sqrt(y)},l.alpha=function(n){return arguments.length?(n=+n,i?n>0?i=n:(e.c=null,e.t=NaN,e=null,c.end({type:"end",alpha:i=0})):n>0&&(c.start({type:"start",alpha:i=n}),e=qn(l.tick)),l):i},l.start=function(){function n(n,r){if(!e){for(e=new Array(i),l=0;i>l;++l)e[l]=[];for(l=0;c>l;++l){var u=x[l];e[u.source.index].push(u.target),e[u.target.index].push(u.source)}}for(var o,a=e[t],l=-1,f=a.length;++lt;++t)(r=M[t]).index=t,r.weight=0;for(t=0;c>t;++t)r=x[t],"number"==typeof r.source&&(r.source=M[r.source]),"number"==typeof r.target&&(r.target=M[r.target]),++r.source.weight,++r.target.weight;for(t=0;i>t;++t)r=M[t],isNaN(r.x)&&(r.x=n("x",s)),isNaN(r.y)&&(r.y=n("y",v)),isNaN(r.px)&&(r.px=r.x),isNaN(r.py)&&(r.py=r.y);if(u=[],"function"==typeof h)for(t=0;c>t;++t)u[t]=+h.call(this,x[t],t);else for(t=0;c>t;++t)u[t]=h;if(o=[],"function"==typeof p)for(t=0;c>t;++t)o[t]=+p.call(this,x[t],t);else for(t=0;c>t;++t)o[t]=p;if(a=[],"function"==typeof g)for(t=0;i>t;++t)a[t]=+g.call(this,M[t],t);else for(t=0;i>t;++t)a[t]=g;return l.resume()},l.resume=function(){return l.alpha(.1)},l.stop=function(){return l.alpha(0)},l.drag=function(){return r||(r=ao.behavior.drag().origin(m).on("dragstart.force",Qr).on("drag.force",t).on("dragend.force",ni)),arguments.length?void this.on("mouseover.force",ti).on("mouseout.force",ei).call(r):r},ao.rebind(l,c,"on")};var ml=20,Ml=1,xl=1/0;ao.layout.hierarchy=function(){function n(i){var u,o=[i],a=[];for(i.depth=0;null!=(u=o.pop());)if(a.push(u),(c=e.call(n,u,u.depth))&&(l=c.length)){for(var l,c,f;--l>=0;)o.push(f=c[l]),f.parent=u,f.depth=u.depth+1;r&&(u.value=0),u.children=c}else r&&(u.value=+r.call(n,u,u.depth)||0),delete u.children;return oi(i,function(n){var e,i;t&&(e=n.children)&&e.sort(t),r&&(i=n.parent)&&(i.value+=n.value)}),a}var t=ci,e=ai,r=li;return n.sort=function(e){return arguments.length?(t=e,n):t},n.children=function(t){return arguments.length?(e=t,n):e},n.value=function(t){return arguments.length?(r=t,n):r},n.revalue=function(t){return r&&(ui(t,function(n){n.children&&(n.value=0)}),oi(t,function(t){var e;t.children||(t.value=+r.call(n,t,t.depth)||0),(e=t.parent)&&(e.value+=t.value)})),t},n},ao.layout.partition=function(){function n(t,e,r,i){var u=t.children;if(t.x=e,t.y=t.depth*i,t.dx=r,t.dy=i,u&&(o=u.length)){var o,a,l,c=-1;for(r=t.value?r/t.value:0;++cs?-1:1),g=ao.sum(c),v=g?(s-l*p)/g:0,d=ao.range(l),y=[];return null!=e&&d.sort(e===bl?function(n,t){return c[t]-c[n]}:function(n,t){return e(o[n],o[t])}),d.forEach(function(n){y[n]={data:o[n],value:a=c[n],startAngle:f,endAngle:f+=a*v+p,padAngle:h}}),y}var t=Number,e=bl,r=0,i=Ho,u=0;return n.value=function(e){return arguments.length?(t=e,n):t},n.sort=function(t){return arguments.length?(e=t,n):e},n.startAngle=function(t){return arguments.length?(r=t,n):r},n.endAngle=function(t){return arguments.length?(i=t,n):i},n.padAngle=function(t){return arguments.length?(u=t,n):u},n};var bl={};ao.layout.stack=function(){function n(a,l){if(!(h=a.length))return a;var c=a.map(function(e,r){return t.call(n,e,r)}),f=c.map(function(t){return t.map(function(t,e){return[u.call(n,t,e),o.call(n,t,e)]})}),s=e.call(n,f,l);c=ao.permute(c,s),f=ao.permute(f,s);var h,p,g,v,d=r.call(n,f,l),y=c[0].length;for(g=0;y>g;++g)for(i.call(n,c[0][g],v=d[g],f[0][g][1]),p=1;h>p;++p)i.call(n,c[p][g],v+=f[p-1][g][1],f[p][g][1]);return a}var t=m,e=gi,r=vi,i=pi,u=si,o=hi;return n.values=function(e){return arguments.length?(t=e,n):t},n.order=function(t){return arguments.length?(e="function"==typeof t?t:_l.get(t)||gi,n):e},n.offset=function(t){return arguments.length?(r="function"==typeof t?t:wl.get(t)||vi,n):r},n.x=function(t){return arguments.length?(u=t,n):u},n.y=function(t){return arguments.length?(o=t,n):o},n.out=function(t){return arguments.length?(i=t,n):i},n};var _l=ao.map({"inside-out":function(n){var t,e,r=n.length,i=n.map(di),u=n.map(yi),o=ao.range(r).sort(function(n,t){return i[n]-i[t]}),a=0,l=0,c=[],f=[];for(t=0;r>t;++t)e=o[t],l>a?(a+=u[e],c.push(e)):(l+=u[e],f.push(e));return f.reverse().concat(c)},reverse:function(n){return ao.range(n.length).reverse()},"default":gi}),wl=ao.map({silhouette:function(n){var t,e,r,i=n.length,u=n[0].length,o=[],a=0,l=[];for(e=0;u>e;++e){for(t=0,r=0;i>t;t++)r+=n[t][e][1];r>a&&(a=r),o.push(r)}for(e=0;u>e;++e)l[e]=(a-o[e])/2;return l},wiggle:function(n){var t,e,r,i,u,o,a,l,c,f=n.length,s=n[0],h=s.length,p=[];for(p[0]=l=c=0,e=1;h>e;++e){for(t=0,i=0;f>t;++t)i+=n[t][e][1];for(t=0,u=0,a=s[e][0]-s[e-1][0];f>t;++t){for(r=0,o=(n[t][e][1]-n[t][e-1][1])/(2*a);t>r;++r)o+=(n[r][e][1]-n[r][e-1][1])/a;u+=o*n[t][e][1]}p[e]=l-=i?u/i*a:0,c>l&&(c=l)}for(e=0;h>e;++e)p[e]-=c;return p},expand:function(n){var t,e,r,i=n.length,u=n[0].length,o=1/i,a=[];for(e=0;u>e;++e){for(t=0,r=0;i>t;t++)r+=n[t][e][1];if(r)for(t=0;i>t;t++)n[t][e][1]/=r;else for(t=0;i>t;t++)n[t][e][1]=o}for(e=0;u>e;++e)a[e]=0;return a},zero:vi});ao.layout.histogram=function(){function n(n,u){for(var o,a,l=[],c=n.map(e,this),f=r.call(this,c,u),s=i.call(this,f,c,u),u=-1,h=c.length,p=s.length-1,g=t?1:1/h;++u0)for(u=-1;++u=f[0]&&a<=f[1]&&(o=l[ao.bisect(s,a,1,p)-1],o.y+=g,o.push(n[u]));return l}var t=!0,e=Number,r=bi,i=Mi;return n.value=function(t){return arguments.length?(e=t,n):e},n.range=function(t){return arguments.length?(r=En(t),n):r},n.bins=function(t){return arguments.length?(i="number"==typeof t?function(n){return xi(n,t)}:En(t),n):i},n.frequency=function(e){return arguments.length?(t=!!e,n):t},n},ao.layout.pack=function(){function n(n,u){var o=e.call(this,n,u),a=o[0],l=i[0],c=i[1],f=null==t?Math.sqrt:"function"==typeof t?t:function(){return t};if(a.x=a.y=0,oi(a,function(n){n.r=+f(n.value)}),oi(a,Ni),r){var s=r*(t?1:Math.max(2*a.r/l,2*a.r/c))/2;oi(a,function(n){n.r+=s}),oi(a,Ni),oi(a,function(n){n.r-=s})}return Ci(a,l/2,c/2,t?1:1/Math.max(2*a.r/l,2*a.r/c)),o}var t,e=ao.layout.hierarchy().sort(_i),r=0,i=[1,1];return n.size=function(t){return arguments.length?(i=t,n):i},n.radius=function(e){return arguments.length?(t=null==e||"function"==typeof e?e:+e,n):t},n.padding=function(t){return arguments.length?(r=+t,n):r},ii(n,e)},ao.layout.tree=function(){function n(n,i){var f=o.call(this,n,i),s=f[0],h=t(s);if(oi(h,e),h.parent.m=-h.z,ui(h,r),c)ui(s,u);else{var p=s,g=s,v=s;ui(s,function(n){n.xg.x&&(g=n),n.depth>v.depth&&(v=n)});var d=a(p,g)/2-p.x,y=l[0]/(g.x+a(g,p)/2+d),m=l[1]/(v.depth||1);ui(s,function(n){n.x=(n.x+d)*y,n.y=n.depth*m})}return f}function t(n){for(var t,e={A:null,children:[n]},r=[e];null!=(t=r.pop());)for(var i,u=t.children,o=0,a=u.length;a>o;++o)r.push((u[o]=i={_:u[o],parent:t,children:(i=u[o].children)&&i.slice()||[],A:null,a:null,z:0,m:0,c:0,s:0,t:null,i:o}).a=i);return e.children[0]}function e(n){var t=n.children,e=n.parent.children,r=n.i?e[n.i-1]:null;if(t.length){Di(n);var u=(t[0].z+t[t.length-1].z)/2;r?(n.z=r.z+a(n._,r._),n.m=n.z-u):n.z=u}else r&&(n.z=r.z+a(n._,r._));n.parent.A=i(n,r,n.parent.A||e[0])}function r(n){n._.x=n.z+n.parent.m,n.m+=n.parent.m}function i(n,t,e){if(t){for(var r,i=n,u=n,o=t,l=i.parent.children[0],c=i.m,f=u.m,s=o.m,h=l.m;o=Ti(o),i=qi(i),o&&i;)l=qi(l),u=Ti(u),u.a=n,r=o.z+s-i.z-c+a(o._,i._),r>0&&(Ri(Pi(o,n,e),n,r),c+=r,f+=r),s+=o.m,c+=i.m,h+=l.m,f+=u.m;o&&!Ti(u)&&(u.t=o,u.m+=s-f),i&&!qi(l)&&(l.t=i,l.m+=c-h,e=n)}return e}function u(n){n.x*=l[0],n.y=n.depth*l[1]}var o=ao.layout.hierarchy().sort(null).value(null),a=Li,l=[1,1],c=null;return n.separation=function(t){return arguments.length?(a=t,n):a},n.size=function(t){return arguments.length?(c=null==(l=t)?u:null,n):c?null:l},n.nodeSize=function(t){return arguments.length?(c=null==(l=t)?null:u,n):c?l:null},ii(n,o)},ao.layout.cluster=function(){function n(n,u){var o,a=t.call(this,n,u),l=a[0],c=0;oi(l,function(n){var t=n.children;t&&t.length?(n.x=ji(t),n.y=Ui(t)):(n.x=o?c+=e(n,o):0,n.y=0,o=n)});var f=Fi(l),s=Hi(l),h=f.x-e(f,s)/2,p=s.x+e(s,f)/2;return oi(l,i?function(n){n.x=(n.x-l.x)*r[0],n.y=(l.y-n.y)*r[1]}:function(n){n.x=(n.x-h)/(p-h)*r[0],n.y=(1-(l.y?n.y/l.y:1))*r[1]}),a}var t=ao.layout.hierarchy().sort(null).value(null),e=Li,r=[1,1],i=!1;return n.separation=function(t){return arguments.length?(e=t,n):e},n.size=function(t){return arguments.length?(i=null==(r=t),n):i?null:r},n.nodeSize=function(t){return arguments.length?(i=null!=(r=t),n):i?r:null},ii(n,t)},ao.layout.treemap=function(){function n(n,t){for(var e,r,i=-1,u=n.length;++it?0:t),e.area=isNaN(r)||0>=r?0:r}function t(e){var u=e.children;if(u&&u.length){var o,a,l,c=s(e),f=[],h=u.slice(),g=1/0,v="slice"===p?c.dx:"dice"===p?c.dy:"slice-dice"===p?1&e.depth?c.dy:c.dx:Math.min(c.dx,c.dy);for(n(h,c.dx*c.dy/e.value),f.area=0;(l=h.length)>0;)f.push(o=h[l-1]),f.area+=o.area,"squarify"!==p||(a=r(f,v))<=g?(h.pop(),g=a):(f.area-=f.pop().area,i(f,v,c,!1),v=Math.min(c.dx,c.dy),f.length=f.area=0,g=1/0);f.length&&(i(f,v,c,!0),f.length=f.area=0),u.forEach(t)}}function e(t){var r=t.children;if(r&&r.length){var u,o=s(t),a=r.slice(),l=[];for(n(a,o.dx*o.dy/t.value),l.area=0;u=a.pop();)l.push(u),l.area+=u.area,null!=u.z&&(i(l,u.z?o.dx:o.dy,o,!a.length),l.length=l.area=0);r.forEach(e)}}function r(n,t){for(var e,r=n.area,i=0,u=1/0,o=-1,a=n.length;++oe&&(u=e),e>i&&(i=e));return r*=r,t*=t,r?Math.max(t*i*g/r,r/(t*u*g)):1/0}function i(n,t,e,r){var i,u=-1,o=n.length,a=e.x,c=e.y,f=t?l(n.area/t):0; -if(t==e.dx){for((r||f>e.dy)&&(f=e.dy);++ue.dx)&&(f=e.dx);++ue&&(t=1),1>e&&(n=0),function(){var e,r,i;do e=2*Math.random()-1,r=2*Math.random()-1,i=e*e+r*r;while(!i||i>1);return n+t*e*Math.sqrt(-2*Math.log(i)/i)}},logNormal:function(){var n=ao.random.normal.apply(ao,arguments);return function(){return Math.exp(n())}},bates:function(n){var t=ao.random.irwinHall(n);return function(){return t()/n}},irwinHall:function(n){return function(){for(var t=0,e=0;n>e;e++)t+=Math.random();return t}}},ao.scale={};var Sl={floor:m,ceil:m};ao.scale.linear=function(){return Wi([0,1],[0,1],Mr,!1)};var kl={s:1,g:1,p:1,r:1,e:1};ao.scale.log=function(){return ru(ao.scale.linear().domain([0,1]),10,!0,[1,10])};var Nl=ao.format(".0e"),El={floor:function(n){return-Math.ceil(-n)},ceil:function(n){return-Math.floor(-n)}};ao.scale.pow=function(){return iu(ao.scale.linear(),1,[0,1])},ao.scale.sqrt=function(){return ao.scale.pow().exponent(.5)},ao.scale.ordinal=function(){return ou([],{t:"range",a:[[]]})},ao.scale.category10=function(){return ao.scale.ordinal().range(Al)},ao.scale.category20=function(){return ao.scale.ordinal().range(Cl)},ao.scale.category20b=function(){return ao.scale.ordinal().range(zl)},ao.scale.category20c=function(){return ao.scale.ordinal().range(Ll)};var Al=[2062260,16744206,2924588,14034728,9725885,9197131,14907330,8355711,12369186,1556175].map(xn),Cl=[2062260,11454440,16744206,16759672,2924588,10018698,14034728,16750742,9725885,12955861,9197131,12885140,14907330,16234194,8355711,13092807,12369186,14408589,1556175,10410725].map(xn),zl=[3750777,5395619,7040719,10264286,6519097,9216594,11915115,13556636,9202993,12426809,15186514,15190932,8666169,11356490,14049643,15177372,8077683,10834324,13528509,14589654].map(xn),Ll=[3244733,7057110,10406625,13032431,15095053,16616764,16625259,16634018,3253076,7652470,10607003,13101504,7695281,10394312,12369372,14342891,6513507,9868950,12434877,14277081].map(xn);ao.scale.quantile=function(){return au([],[])},ao.scale.quantize=function(){return lu(0,1,[0,1])},ao.scale.threshold=function(){return cu([.5],[0,1])},ao.scale.identity=function(){return fu([0,1])},ao.svg={},ao.svg.arc=function(){function n(){var n=Math.max(0,+e.apply(this,arguments)),c=Math.max(0,+r.apply(this,arguments)),f=o.apply(this,arguments)-Io,s=a.apply(this,arguments)-Io,h=Math.abs(s-f),p=f>s?0:1;if(n>c&&(g=c,c=n,n=g),h>=Oo)return t(c,p)+(n?t(n,1-p):"")+"Z";var g,v,d,y,m,M,x,b,_,w,S,k,N=0,E=0,A=[];if((y=(+l.apply(this,arguments)||0)/2)&&(d=u===ql?Math.sqrt(n*n+c*c):+u.apply(this,arguments),p||(E*=-1),c&&(E=tn(d/c*Math.sin(y))),n&&(N=tn(d/n*Math.sin(y)))),c){m=c*Math.cos(f+E),M=c*Math.sin(f+E),x=c*Math.cos(s-E),b=c*Math.sin(s-E);var C=Math.abs(s-f-2*E)<=Fo?0:1;if(E&&yu(m,M,x,b)===p^C){var z=(f+s)/2;m=c*Math.cos(z),M=c*Math.sin(z),x=b=null}}else m=M=0;if(n){_=n*Math.cos(s-N),w=n*Math.sin(s-N),S=n*Math.cos(f+N),k=n*Math.sin(f+N);var L=Math.abs(f-s+2*N)<=Fo?0:1;if(N&&yu(_,w,S,k)===1-p^L){var q=(f+s)/2;_=n*Math.cos(q),w=n*Math.sin(q),S=k=null}}else _=w=0;if(h>Uo&&(g=Math.min(Math.abs(c-n)/2,+i.apply(this,arguments)))>.001){v=c>n^p?0:1;var T=g,R=g;if(Fo>h){var D=null==S?[_,w]:null==x?[m,M]:Re([m,M],[S,k],[x,b],[_,w]),P=m-D[0],U=M-D[1],j=x-D[0],F=b-D[1],H=1/Math.sin(Math.acos((P*j+U*F)/(Math.sqrt(P*P+U*U)*Math.sqrt(j*j+F*F)))/2),O=Math.sqrt(D[0]*D[0]+D[1]*D[1]);R=Math.min(g,(n-O)/(H-1)),T=Math.min(g,(c-O)/(H+1))}if(null!=x){var I=mu(null==S?[_,w]:[S,k],[m,M],c,T,p),Y=mu([x,b],[_,w],c,T,p);g===T?A.push("M",I[0],"A",T,",",T," 0 0,",v," ",I[1],"A",c,",",c," 0 ",1-p^yu(I[1][0],I[1][1],Y[1][0],Y[1][1]),",",p," ",Y[1],"A",T,",",T," 0 0,",v," ",Y[0]):A.push("M",I[0],"A",T,",",T," 0 1,",v," ",Y[0])}else A.push("M",m,",",M);if(null!=S){var Z=mu([m,M],[S,k],n,-R,p),V=mu([_,w],null==x?[m,M]:[x,b],n,-R,p);g===R?A.push("L",V[0],"A",R,",",R," 0 0,",v," ",V[1],"A",n,",",n," 0 ",p^yu(V[1][0],V[1][1],Z[1][0],Z[1][1]),",",1-p," ",Z[1],"A",R,",",R," 0 0,",v," ",Z[0]):A.push("L",V[0],"A",R,",",R," 0 0,",v," ",Z[0])}else A.push("L",_,",",w)}else A.push("M",m,",",M),null!=x&&A.push("A",c,",",c," 0 ",C,",",p," ",x,",",b),A.push("L",_,",",w),null!=S&&A.push("A",n,",",n," 0 ",L,",",1-p," ",S,",",k);return A.push("Z"),A.join("")}function t(n,t){return"M0,"+n+"A"+n+","+n+" 0 1,"+t+" 0,"+-n+"A"+n+","+n+" 0 1,"+t+" 0,"+n}var e=hu,r=pu,i=su,u=ql,o=gu,a=vu,l=du;return n.innerRadius=function(t){return arguments.length?(e=En(t),n):e},n.outerRadius=function(t){return arguments.length?(r=En(t),n):r},n.cornerRadius=function(t){return arguments.length?(i=En(t),n):i},n.padRadius=function(t){return arguments.length?(u=t==ql?ql:En(t),n):u},n.startAngle=function(t){return arguments.length?(o=En(t),n):o},n.endAngle=function(t){return arguments.length?(a=En(t),n):a},n.padAngle=function(t){return arguments.length?(l=En(t),n):l},n.centroid=function(){var n=(+e.apply(this,arguments)+ +r.apply(this,arguments))/2,t=(+o.apply(this,arguments)+ +a.apply(this,arguments))/2-Io;return[Math.cos(t)*n,Math.sin(t)*n]},n};var ql="auto";ao.svg.line=function(){return Mu(m)};var Tl=ao.map({linear:xu,"linear-closed":bu,step:_u,"step-before":wu,"step-after":Su,basis:zu,"basis-open":Lu,"basis-closed":qu,bundle:Tu,cardinal:Eu,"cardinal-open":ku,"cardinal-closed":Nu,monotone:Fu});Tl.forEach(function(n,t){t.key=n,t.closed=/-closed$/.test(n)});var Rl=[0,2/3,1/3,0],Dl=[0,1/3,2/3,0],Pl=[0,1/6,2/3,1/6];ao.svg.line.radial=function(){var n=Mu(Hu);return n.radius=n.x,delete n.x,n.angle=n.y,delete n.y,n},wu.reverse=Su,Su.reverse=wu,ao.svg.area=function(){return Ou(m)},ao.svg.area.radial=function(){var n=Ou(Hu);return n.radius=n.x,delete n.x,n.innerRadius=n.x0,delete n.x0,n.outerRadius=n.x1,delete n.x1,n.angle=n.y,delete n.y,n.startAngle=n.y0,delete n.y0,n.endAngle=n.y1,delete n.y1,n},ao.svg.chord=function(){function n(n,a){var l=t(this,u,n,a),c=t(this,o,n,a);return"M"+l.p0+r(l.r,l.p1,l.a1-l.a0)+(e(l,c)?i(l.r,l.p1,l.r,l.p0):i(l.r,l.p1,c.r,c.p0)+r(c.r,c.p1,c.a1-c.a0)+i(c.r,c.p1,l.r,l.p0))+"Z"}function t(n,t,e,r){var i=t.call(n,e,r),u=a.call(n,i,r),o=l.call(n,i,r)-Io,f=c.call(n,i,r)-Io;return{r:u,a0:o,a1:f,p0:[u*Math.cos(o),u*Math.sin(o)],p1:[u*Math.cos(f),u*Math.sin(f)]}}function e(n,t){return n.a0==t.a0&&n.a1==t.a1}function r(n,t,e){return"A"+n+","+n+" 0 "+ +(e>Fo)+",1 "+t}function i(n,t,e,r){return"Q 0,0 "+r}var u=Me,o=xe,a=Iu,l=gu,c=vu;return n.radius=function(t){return arguments.length?(a=En(t),n):a},n.source=function(t){return arguments.length?(u=En(t),n):u},n.target=function(t){return arguments.length?(o=En(t),n):o},n.startAngle=function(t){return arguments.length?(l=En(t),n):l},n.endAngle=function(t){return arguments.length?(c=En(t),n):c},n},ao.svg.diagonal=function(){function n(n,i){var u=t.call(this,n,i),o=e.call(this,n,i),a=(u.y+o.y)/2,l=[u,{x:u.x,y:a},{x:o.x,y:a},o];return l=l.map(r),"M"+l[0]+"C"+l[1]+" "+l[2]+" "+l[3]}var t=Me,e=xe,r=Yu;return n.source=function(e){return arguments.length?(t=En(e),n):t},n.target=function(t){return arguments.length?(e=En(t),n):e},n.projection=function(t){return arguments.length?(r=t,n):r},n},ao.svg.diagonal.radial=function(){var n=ao.svg.diagonal(),t=Yu,e=n.projection;return n.projection=function(n){return arguments.length?e(Zu(t=n)):t},n},ao.svg.symbol=function(){function n(n,r){return(Ul.get(t.call(this,n,r))||$u)(e.call(this,n,r))}var t=Xu,e=Vu;return n.type=function(e){return arguments.length?(t=En(e),n):t},n.size=function(t){return arguments.length?(e=En(t),n):e},n};var Ul=ao.map({circle:$u,cross:function(n){var t=Math.sqrt(n/5)/2;return"M"+-3*t+","+-t+"H"+-t+"V"+-3*t+"H"+t+"V"+-t+"H"+3*t+"V"+t+"H"+t+"V"+3*t+"H"+-t+"V"+t+"H"+-3*t+"Z"},diamond:function(n){var t=Math.sqrt(n/(2*Fl)),e=t*Fl;return"M0,"+-t+"L"+e+",0 0,"+t+" "+-e+",0Z"},square:function(n){var t=Math.sqrt(n)/2;return"M"+-t+","+-t+"L"+t+","+-t+" "+t+","+t+" "+-t+","+t+"Z"},"triangle-down":function(n){var t=Math.sqrt(n/jl),e=t*jl/2;return"M0,"+e+"L"+t+","+-e+" "+-t+","+-e+"Z"},"triangle-up":function(n){var t=Math.sqrt(n/jl),e=t*jl/2;return"M0,"+-e+"L"+t+","+e+" "+-t+","+e+"Z"}});ao.svg.symbolTypes=Ul.keys();var jl=Math.sqrt(3),Fl=Math.tan(30*Yo);Co.transition=function(n){for(var t,e,r=Hl||++Zl,i=Ku(n),u=[],o=Ol||{time:Date.now(),ease:Nr,delay:0,duration:250},a=-1,l=this.length;++au;u++){i.push(t=[]);for(var e=this[u],a=0,l=e.length;l>a;a++)(r=e[a])&&n.call(r,r.__data__,a,u)&&t.push(r)}return Wu(i,this.namespace,this.id)},Yl.tween=function(n,t){var e=this.id,r=this.namespace;return arguments.length<2?this.node()[r][e].tween.get(n):Y(this,null==t?function(t){t[r][e].tween.remove(n)}:function(i){i[r][e].tween.set(n,t)})},Yl.attr=function(n,t){function e(){this.removeAttribute(a)}function r(){this.removeAttributeNS(a.space,a.local)}function i(n){return null==n?e:(n+="",function(){var t,e=this.getAttribute(a);return e!==n&&(t=o(e,n),function(n){this.setAttribute(a,t(n))})})}function u(n){return null==n?r:(n+="",function(){var t,e=this.getAttributeNS(a.space,a.local);return e!==n&&(t=o(e,n),function(n){this.setAttributeNS(a.space,a.local,t(n))})})}if(arguments.length<2){for(t in n)this.attr(t,n[t]);return this}var o="transform"==n?$r:Mr,a=ao.ns.qualify(n);return Ju(this,"attr."+n,t,a.local?u:i)},Yl.attrTween=function(n,t){function e(n,e){var r=t.call(this,n,e,this.getAttribute(i));return r&&function(n){this.setAttribute(i,r(n))}}function r(n,e){var r=t.call(this,n,e,this.getAttributeNS(i.space,i.local));return r&&function(n){this.setAttributeNS(i.space,i.local,r(n))}}var i=ao.ns.qualify(n);return this.tween("attr."+n,i.local?r:e)},Yl.style=function(n,e,r){function i(){this.style.removeProperty(n)}function u(e){return null==e?i:(e+="",function(){var i,u=t(this).getComputedStyle(this,null).getPropertyValue(n);return u!==e&&(i=Mr(u,e),function(t){this.style.setProperty(n,i(t),r)})})}var o=arguments.length;if(3>o){if("string"!=typeof n){2>o&&(e="");for(r in n)this.style(r,n[r],e);return this}r=""}return Ju(this,"style."+n,e,u)},Yl.styleTween=function(n,e,r){function i(i,u){var o=e.call(this,i,u,t(this).getComputedStyle(this,null).getPropertyValue(n));return o&&function(t){this.style.setProperty(n,o(t),r)}}return arguments.length<3&&(r=""),this.tween("style."+n,i)},Yl.text=function(n){return Ju(this,"text",n,Gu)},Yl.remove=function(){var n=this.namespace;return this.each("end.transition",function(){var t;this[n].count<2&&(t=this.parentNode)&&t.removeChild(this)})},Yl.ease=function(n){var t=this.id,e=this.namespace;return arguments.length<1?this.node()[e][t].ease:("function"!=typeof n&&(n=ao.ease.apply(ao,arguments)),Y(this,function(r){r[e][t].ease=n}))},Yl.delay=function(n){var t=this.id,e=this.namespace;return arguments.length<1?this.node()[e][t].delay:Y(this,"function"==typeof n?function(r,i,u){r[e][t].delay=+n.call(r,r.__data__,i,u)}:(n=+n,function(r){r[e][t].delay=n}))},Yl.duration=function(n){var t=this.id,e=this.namespace;return arguments.length<1?this.node()[e][t].duration:Y(this,"function"==typeof n?function(r,i,u){r[e][t].duration=Math.max(1,n.call(r,r.__data__,i,u))}:(n=Math.max(1,n),function(r){r[e][t].duration=n}))},Yl.each=function(n,t){var e=this.id,r=this.namespace;if(arguments.length<2){var i=Ol,u=Hl;try{Hl=e,Y(this,function(t,i,u){Ol=t[r][e],n.call(t,t.__data__,i,u)})}finally{Ol=i,Hl=u}}else Y(this,function(i){var u=i[r][e];(u.event||(u.event=ao.dispatch("start","end","interrupt"))).on(n,t)});return this},Yl.transition=function(){for(var n,t,e,r,i=this.id,u=++Zl,o=this.namespace,a=[],l=0,c=this.length;c>l;l++){a.push(n=[]);for(var t=this[l],f=0,s=t.length;s>f;f++)(e=t[f])&&(r=e[o][i],Qu(e,f,o,u,{time:r.time,ease:r.ease,delay:r.delay+r.duration,duration:r.duration})),n.push(e)}return Wu(a,o,u)},ao.svg.axis=function(){function n(n){n.each(function(){var n,c=ao.select(this),f=this.__chart__||e,s=this.__chart__=e.copy(),h=null==l?s.ticks?s.ticks.apply(s,a):s.domain():l,p=null==t?s.tickFormat?s.tickFormat.apply(s,a):m:t,g=c.selectAll(".tick").data(h,s),v=g.enter().insert("g",".domain").attr("class","tick").style("opacity",Uo),d=ao.transition(g.exit()).style("opacity",Uo).remove(),y=ao.transition(g.order()).style("opacity",1),M=Math.max(i,0)+o,x=Zi(s),b=c.selectAll(".domain").data([0]),_=(b.enter().append("path").attr("class","domain"),ao.transition(b));v.append("line"),v.append("text");var w,S,k,N,E=v.select("line"),A=y.select("line"),C=g.select("text").text(p),z=v.select("text"),L=y.select("text"),q="top"===r||"left"===r?-1:1;if("bottom"===r||"top"===r?(n=no,w="x",k="y",S="x2",N="y2",C.attr("dy",0>q?"0em":".71em").style("text-anchor","middle"),_.attr("d","M"+x[0]+","+q*u+"V0H"+x[1]+"V"+q*u)):(n=to,w="y",k="x",S="y2",N="x2",C.attr("dy",".32em").style("text-anchor",0>q?"end":"start"),_.attr("d","M"+q*u+","+x[0]+"H0V"+x[1]+"H"+q*u)),E.attr(N,q*i),z.attr(k,q*M),A.attr(S,0).attr(N,q*i),L.attr(w,0).attr(k,q*M),s.rangeBand){var T=s,R=T.rangeBand()/2;f=s=function(n){return T(n)+R}}else f.rangeBand?f=s:d.call(n,s,f);v.call(n,f,s),y.call(n,s,s)})}var t,e=ao.scale.linear(),r=Vl,i=6,u=6,o=3,a=[10],l=null;return n.scale=function(t){return arguments.length?(e=t,n):e},n.orient=function(t){return arguments.length?(r=t in Xl?t+"":Vl,n):r},n.ticks=function(){return arguments.length?(a=co(arguments),n):a},n.tickValues=function(t){return arguments.length?(l=t,n):l},n.tickFormat=function(e){return arguments.length?(t=e,n):t},n.tickSize=function(t){var e=arguments.length;return e?(i=+t,u=+arguments[e-1],n):i},n.innerTickSize=function(t){return arguments.length?(i=+t,n):i},n.outerTickSize=function(t){return arguments.length?(u=+t,n):u},n.tickPadding=function(t){return arguments.length?(o=+t,n):o},n.tickSubdivide=function(){return arguments.length&&n},n};var Vl="bottom",Xl={top:1,right:1,bottom:1,left:1};ao.svg.brush=function(){function n(t){t.each(function(){var t=ao.select(this).style("pointer-events","all").style("-webkit-tap-highlight-color","rgba(0,0,0,0)").on("mousedown.brush",u).on("touchstart.brush",u),o=t.selectAll(".background").data([0]);o.enter().append("rect").attr("class","background").style("visibility","hidden").style("cursor","crosshair"),t.selectAll(".extent").data([0]).enter().append("rect").attr("class","extent").style("cursor","move");var a=t.selectAll(".resize").data(v,m);a.exit().remove(),a.enter().append("g").attr("class",function(n){return"resize "+n}).style("cursor",function(n){return $l[n]}).append("rect").attr("x",function(n){return/[ew]$/.test(n)?-3:null}).attr("y",function(n){return/^[ns]/.test(n)?-3:null}).attr("width",6).attr("height",6).style("visibility","hidden"),a.style("display",n.empty()?"none":null);var l,s=ao.transition(t),h=ao.transition(o);c&&(l=Zi(c),h.attr("x",l[0]).attr("width",l[1]-l[0]),r(s)),f&&(l=Zi(f),h.attr("y",l[0]).attr("height",l[1]-l[0]),i(s)),e(s)})}function e(n){n.selectAll(".resize").attr("transform",function(n){return"translate("+s[+/e$/.test(n)]+","+h[+/^s/.test(n)]+")"})}function r(n){n.select(".extent").attr("x",s[0]),n.selectAll(".extent,.n>rect,.s>rect").attr("width",s[1]-s[0])}function i(n){n.select(".extent").attr("y",h[0]),n.selectAll(".extent,.e>rect,.w>rect").attr("height",h[1]-h[0])}function u(){function u(){32==ao.event.keyCode&&(C||(M=null,L[0]-=s[1],L[1]-=h[1],C=2),S())}function v(){32==ao.event.keyCode&&2==C&&(L[0]+=s[1],L[1]+=h[1],C=0,S())}function d(){var n=ao.mouse(b),t=!1;x&&(n[0]+=x[0],n[1]+=x[1]),C||(ao.event.altKey?(M||(M=[(s[0]+s[1])/2,(h[0]+h[1])/2]),L[0]=s[+(n[0]f?(i=r,r=f):i=f),v[0]!=r||v[1]!=i?(e?a=null:o=null,v[0]=r,v[1]=i,!0):void 0}function m(){d(),k.style("pointer-events","all").selectAll(".resize").style("display",n.empty()?"none":null),ao.select("body").style("cursor",null),q.on("mousemove.brush",null).on("mouseup.brush",null).on("touchmove.brush",null).on("touchend.brush",null).on("keydown.brush",null).on("keyup.brush",null),z(),w({type:"brushend"})}var M,x,b=this,_=ao.select(ao.event.target),w=l.of(b,arguments),k=ao.select(b),N=_.datum(),E=!/^(n|s)$/.test(N)&&c,A=!/^(e|w)$/.test(N)&&f,C=_.classed("extent"),z=W(b),L=ao.mouse(b),q=ao.select(t(b)).on("keydown.brush",u).on("keyup.brush",v);if(ao.event.changedTouches?q.on("touchmove.brush",d).on("touchend.brush",m):q.on("mousemove.brush",d).on("mouseup.brush",m),k.interrupt().selectAll("*").interrupt(),C)L[0]=s[0]-L[0],L[1]=h[0]-L[1];else if(N){var T=+/w$/.test(N),R=+/^n/.test(N);x=[s[1-T]-L[0],h[1-R]-L[1]],L[0]=s[T],L[1]=h[R]}else ao.event.altKey&&(M=L.slice());k.style("pointer-events","none").selectAll(".resize").style("display",null),ao.select("body").style("cursor",_.style("cursor")),w({type:"brushstart"}),d()}var o,a,l=N(n,"brushstart","brush","brushend"),c=null,f=null,s=[0,0],h=[0,0],p=!0,g=!0,v=Bl[0];return n.event=function(n){n.each(function(){var n=l.of(this,arguments),t={x:s,y:h,i:o,j:a},e=this.__chart__||t;this.__chart__=t,Hl?ao.select(this).transition().each("start.brush",function(){o=e.i,a=e.j,s=e.x,h=e.y,n({type:"brushstart"})}).tween("brush:brush",function(){var e=xr(s,t.x),r=xr(h,t.y);return o=a=null,function(i){s=t.x=e(i),h=t.y=r(i),n({type:"brush",mode:"resize"})}}).each("end.brush",function(){o=t.i,a=t.j,n({type:"brush",mode:"resize"}),n({type:"brushend"})}):(n({type:"brushstart"}),n({type:"brush",mode:"resize"}),n({type:"brushend"}))})},n.x=function(t){return arguments.length?(c=t,v=Bl[!c<<1|!f],n):c},n.y=function(t){return arguments.length?(f=t,v=Bl[!c<<1|!f],n):f},n.clamp=function(t){return arguments.length?(c&&f?(p=!!t[0],g=!!t[1]):c?p=!!t:f&&(g=!!t),n):c&&f?[p,g]:c?p:f?g:null},n.extent=function(t){var e,r,i,u,l;return arguments.length?(c&&(e=t[0],r=t[1],f&&(e=e[0],r=r[0]),o=[e,r],c.invert&&(e=c(e),r=c(r)),e>r&&(l=e,e=r,r=l),e==s[0]&&r==s[1]||(s=[e,r])),f&&(i=t[0],u=t[1],c&&(i=i[1],u=u[1]),a=[i,u],f.invert&&(i=f(i),u=f(u)),i>u&&(l=i,i=u,u=l),i==h[0]&&u==h[1]||(h=[i,u])),n):(c&&(o?(e=o[0],r=o[1]):(e=s[0],r=s[1],c.invert&&(e=c.invert(e),r=c.invert(r)),e>r&&(l=e,e=r,r=l))),f&&(a?(i=a[0],u=a[1]):(i=h[0],u=h[1],f.invert&&(i=f.invert(i),u=f.invert(u)),i>u&&(l=i,i=u,u=l))),c&&f?[[e,i],[r,u]]:c?[e,r]:f&&[i,u])},n.clear=function(){return n.empty()||(s=[0,0],h=[0,0],o=a=null),n},n.empty=function(){return!!c&&s[0]==s[1]||!!f&&h[0]==h[1]},ao.rebind(n,l,"on")};var $l={n:"ns-resize",e:"ew-resize",s:"ns-resize",w:"ew-resize",nw:"nwse-resize",ne:"nesw-resize",se:"nwse-resize",sw:"nesw-resize"},Bl=[["n","e","s","w","nw","ne","se","sw"],["e","w"],["n","s"],[]],Wl=ga.format=xa.timeFormat,Jl=Wl.utc,Gl=Jl("%Y-%m-%dT%H:%M:%S.%LZ");Wl.iso=Date.prototype.toISOString&&+new Date("2000-01-01T00:00:00.000Z")?eo:Gl,eo.parse=function(n){var t=new Date(n);return isNaN(t)?null:t},eo.toString=Gl.toString,ga.second=On(function(n){return new va(1e3*Math.floor(n/1e3))},function(n,t){n.setTime(n.getTime()+1e3*Math.floor(t))},function(n){return n.getSeconds()}),ga.seconds=ga.second.range,ga.seconds.utc=ga.second.utc.range,ga.minute=On(function(n){return new va(6e4*Math.floor(n/6e4))},function(n,t){n.setTime(n.getTime()+6e4*Math.floor(t))},function(n){return n.getMinutes()}),ga.minutes=ga.minute.range,ga.minutes.utc=ga.minute.utc.range,ga.hour=On(function(n){var t=n.getTimezoneOffset()/60;return new va(36e5*(Math.floor(n/36e5-t)+t))},function(n,t){n.setTime(n.getTime()+36e5*Math.floor(t))},function(n){return n.getHours()}),ga.hours=ga.hour.range,ga.hours.utc=ga.hour.utc.range,ga.month=On(function(n){return n=ga.day(n),n.setDate(1),n},function(n,t){n.setMonth(n.getMonth()+t)},function(n){return n.getMonth()}),ga.months=ga.month.range,ga.months.utc=ga.month.utc.range;var Kl=[1e3,5e3,15e3,3e4,6e4,3e5,9e5,18e5,36e5,108e5,216e5,432e5,864e5,1728e5,6048e5,2592e6,7776e6,31536e6],Ql=[[ga.second,1],[ga.second,5],[ga.second,15],[ga.second,30],[ga.minute,1],[ga.minute,5],[ga.minute,15],[ga.minute,30],[ga.hour,1],[ga.hour,3],[ga.hour,6],[ga.hour,12],[ga.day,1],[ga.day,2],[ga.week,1],[ga.month,1],[ga.month,3],[ga.year,1]],nc=Wl.multi([[".%L",function(n){return n.getMilliseconds()}],[":%S",function(n){return n.getSeconds()}],["%I:%M",function(n){return n.getMinutes()}],["%I %p",function(n){return n.getHours()}],["%a %d",function(n){return n.getDay()&&1!=n.getDate()}],["%b %d",function(n){return 1!=n.getDate()}],["%B",function(n){return n.getMonth()}],["%Y",zt]]),tc={range:function(n,t,e){return ao.range(Math.ceil(n/e)*e,+t,e).map(io)},floor:m,ceil:m};Ql.year=ga.year,ga.scale=function(){return ro(ao.scale.linear(),Ql,nc)};var ec=Ql.map(function(n){return[n[0].utc,n[1]]}),rc=Jl.multi([[".%L",function(n){return n.getUTCMilliseconds()}],[":%S",function(n){return n.getUTCSeconds()}],["%I:%M",function(n){return n.getUTCMinutes()}],["%I %p",function(n){return n.getUTCHours()}],["%a %d",function(n){return n.getUTCDay()&&1!=n.getUTCDate()}],["%b %d",function(n){return 1!=n.getUTCDate()}],["%B",function(n){return n.getUTCMonth()}],["%Y",zt]]);ec.year=ga.year.utc,ga.scale.utc=function(){return ro(ao.scale.linear(),ec,rc)},ao.text=An(function(n){return n.responseText}),ao.json=function(n,t){return Cn(n,"application/json",uo,t)},ao.html=function(n,t){return Cn(n,"text/html",oo,t)},ao.xml=An(function(n){return n.responseXML}),"function"==typeof define&&define.amd?(this.d3=ao,define(ao)):"object"==typeof module&&module.exports?module.exports=ao:this.d3=ao}(); \ No newline at end of file diff --git a/backend/coverage-report/_js/file.js b/backend/coverage-report/_js/file.js deleted file mode 100644 index 124a8a18..00000000 --- a/backend/coverage-report/_js/file.js +++ /dev/null @@ -1,53 +0,0 @@ -$(function () { - var $window = $(window) - , $top_link = $('#toplink') - , $body = $('body, html') - , offset = $('#code').offset().top; - - $top_link.hide().click(function (event) { - event.preventDefault(); - $body.animate({scrollTop: 0}, 800); - }); - - $window.scroll(function () { - if ($window.scrollTop() > offset) { - $top_link.fadeIn(); - } else { - $top_link.fadeOut(); - } - }); - - var $popovers = $('.popin > :first-child'); - $('.popin').on({ - 'click.popover': function (event) { - event.stopPropagation(); - - var $container = $(this).children().first(); - - //Close all other popovers: - $popovers.each(function () { - var $current = $(this); - if (!$current.is($container)) { - $current.popover('hide'); - } - }); - - // Toggle this popover: - $container.popover('toggle'); - }, - }); - - //Hide all popovers on outside click: - $(document).click(function (event) { - if ($(event.target).closest($('.popover')).length === 0) { - $popovers.popover('hide'); - } - }); - - //Hide all popovers on escape: - $(document).keyup(function (event) { - if (event.key === 'Escape') { - $popovers.popover('hide'); - } - }); -}); diff --git a/backend/coverage-report/_js/jquery.min.js b/backend/coverage-report/_js/jquery.min.js deleted file mode 100644 index 798cc8bf..00000000 --- a/backend/coverage-report/_js/jquery.min.js +++ /dev/null @@ -1,2 +0,0 @@ -/*! jQuery v3.7.1 | (c) OpenJS Foundation and other contributors | jquery.org/license */ -!function(e,t){"use strict";"object"==typeof module&&"object"==typeof module.exports?module.exports=e.document?t(e,!0):function(e){if(!e.document)throw new Error("jQuery requires a window with a document");return t(e)}:t(e)}("undefined"!=typeof window?window:this,function(ie,e){"use strict";var oe=[],r=Object.getPrototypeOf,ae=oe.slice,g=oe.flat?function(e){return oe.flat.call(e)}:function(e){return oe.concat.apply([],e)},s=oe.push,se=oe.indexOf,n={},i=n.toString,ue=n.hasOwnProperty,o=ue.toString,a=o.call(Object),le={},v=function(e){return"function"==typeof e&&"number"!=typeof e.nodeType&&"function"!=typeof e.item},y=function(e){return null!=e&&e===e.window},C=ie.document,u={type:!0,src:!0,nonce:!0,noModule:!0};function m(e,t,n){var r,i,o=(n=n||C).createElement("script");if(o.text=e,t)for(r in u)(i=t[r]||t.getAttribute&&t.getAttribute(r))&&o.setAttribute(r,i);n.head.appendChild(o).parentNode.removeChild(o)}function x(e){return null==e?e+"":"object"==typeof e||"function"==typeof e?n[i.call(e)]||"object":typeof e}var t="3.7.1",l=/HTML$/i,ce=function(e,t){return new ce.fn.init(e,t)};function c(e){var t=!!e&&"length"in e&&e.length,n=x(e);return!v(e)&&!y(e)&&("array"===n||0===t||"number"==typeof t&&0+~]|"+ge+")"+ge+"*"),x=new RegExp(ge+"|>"),j=new RegExp(g),A=new RegExp("^"+t+"$"),D={ID:new RegExp("^#("+t+")"),CLASS:new RegExp("^\\.("+t+")"),TAG:new RegExp("^("+t+"|[*])"),ATTR:new RegExp("^"+p),PSEUDO:new RegExp("^"+g),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+ge+"*(even|odd|(([+-]|)(\\d*)n|)"+ge+"*(?:([+-]|)"+ge+"*(\\d+)|))"+ge+"*\\)|)","i"),bool:new RegExp("^(?:"+f+")$","i"),needsContext:new RegExp("^"+ge+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+ge+"*((?:-\\d)?\\d*)"+ge+"*\\)|)(?=[^-]|$)","i")},N=/^(?:input|select|textarea|button)$/i,q=/^h\d$/i,L=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,H=/[+~]/,O=new RegExp("\\\\[\\da-fA-F]{1,6}"+ge+"?|\\\\([^\\r\\n\\f])","g"),P=function(e,t){var n="0x"+e.slice(1)-65536;return t||(n<0?String.fromCharCode(n+65536):String.fromCharCode(n>>10|55296,1023&n|56320))},M=function(){V()},R=J(function(e){return!0===e.disabled&&fe(e,"fieldset")},{dir:"parentNode",next:"legend"});try{k.apply(oe=ae.call(ye.childNodes),ye.childNodes),oe[ye.childNodes.length].nodeType}catch(e){k={apply:function(e,t){me.apply(e,ae.call(t))},call:function(e){me.apply(e,ae.call(arguments,1))}}}function I(t,e,n,r){var i,o,a,s,u,l,c,f=e&&e.ownerDocument,p=e?e.nodeType:9;if(n=n||[],"string"!=typeof t||!t||1!==p&&9!==p&&11!==p)return n;if(!r&&(V(e),e=e||T,C)){if(11!==p&&(u=L.exec(t)))if(i=u[1]){if(9===p){if(!(a=e.getElementById(i)))return n;if(a.id===i)return k.call(n,a),n}else if(f&&(a=f.getElementById(i))&&I.contains(e,a)&&a.id===i)return k.call(n,a),n}else{if(u[2])return k.apply(n,e.getElementsByTagName(t)),n;if((i=u[3])&&e.getElementsByClassName)return k.apply(n,e.getElementsByClassName(i)),n}if(!(h[t+" "]||d&&d.test(t))){if(c=t,f=e,1===p&&(x.test(t)||m.test(t))){(f=H.test(t)&&U(e.parentNode)||e)==e&&le.scope||((s=e.getAttribute("id"))?s=ce.escapeSelector(s):e.setAttribute("id",s=S)),o=(l=Y(t)).length;while(o--)l[o]=(s?"#"+s:":scope")+" "+Q(l[o]);c=l.join(",")}try{return k.apply(n,f.querySelectorAll(c)),n}catch(e){h(t,!0)}finally{s===S&&e.removeAttribute("id")}}}return re(t.replace(ve,"$1"),e,n,r)}function W(){var r=[];return function e(t,n){return r.push(t+" ")>b.cacheLength&&delete e[r.shift()],e[t+" "]=n}}function F(e){return e[S]=!0,e}function $(e){var t=T.createElement("fieldset");try{return!!e(t)}catch(e){return!1}finally{t.parentNode&&t.parentNode.removeChild(t),t=null}}function B(t){return function(e){return fe(e,"input")&&e.type===t}}function _(t){return function(e){return(fe(e,"input")||fe(e,"button"))&&e.type===t}}function z(t){return function(e){return"form"in e?e.parentNode&&!1===e.disabled?"label"in e?"label"in e.parentNode?e.parentNode.disabled===t:e.disabled===t:e.isDisabled===t||e.isDisabled!==!t&&R(e)===t:e.disabled===t:"label"in e&&e.disabled===t}}function X(a){return F(function(o){return o=+o,F(function(e,t){var n,r=a([],e.length,o),i=r.length;while(i--)e[n=r[i]]&&(e[n]=!(t[n]=e[n]))})})}function U(e){return e&&"undefined"!=typeof e.getElementsByTagName&&e}function V(e){var t,n=e?e.ownerDocument||e:ye;return n!=T&&9===n.nodeType&&n.documentElement&&(r=(T=n).documentElement,C=!ce.isXMLDoc(T),i=r.matches||r.webkitMatchesSelector||r.msMatchesSelector,r.msMatchesSelector&&ye!=T&&(t=T.defaultView)&&t.top!==t&&t.addEventListener("unload",M),le.getById=$(function(e){return r.appendChild(e).id=ce.expando,!T.getElementsByName||!T.getElementsByName(ce.expando).length}),le.disconnectedMatch=$(function(e){return i.call(e,"*")}),le.scope=$(function(){return T.querySelectorAll(":scope")}),le.cssHas=$(function(){try{return T.querySelector(":has(*,:jqfake)"),!1}catch(e){return!0}}),le.getById?(b.filter.ID=function(e){var t=e.replace(O,P);return function(e){return e.getAttribute("id")===t}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&C){var n=t.getElementById(e);return n?[n]:[]}}):(b.filter.ID=function(e){var n=e.replace(O,P);return function(e){var t="undefined"!=typeof e.getAttributeNode&&e.getAttributeNode("id");return t&&t.value===n}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&C){var n,r,i,o=t.getElementById(e);if(o){if((n=o.getAttributeNode("id"))&&n.value===e)return[o];i=t.getElementsByName(e),r=0;while(o=i[r++])if((n=o.getAttributeNode("id"))&&n.value===e)return[o]}return[]}}),b.find.TAG=function(e,t){return"undefined"!=typeof t.getElementsByTagName?t.getElementsByTagName(e):t.querySelectorAll(e)},b.find.CLASS=function(e,t){if("undefined"!=typeof t.getElementsByClassName&&C)return t.getElementsByClassName(e)},d=[],$(function(e){var t;r.appendChild(e).innerHTML="",e.querySelectorAll("[selected]").length||d.push("\\["+ge+"*(?:value|"+f+")"),e.querySelectorAll("[id~="+S+"-]").length||d.push("~="),e.querySelectorAll("a#"+S+"+*").length||d.push(".#.+[+~]"),e.querySelectorAll(":checked").length||d.push(":checked"),(t=T.createElement("input")).setAttribute("type","hidden"),e.appendChild(t).setAttribute("name","D"),r.appendChild(e).disabled=!0,2!==e.querySelectorAll(":disabled").length&&d.push(":enabled",":disabled"),(t=T.createElement("input")).setAttribute("name",""),e.appendChild(t),e.querySelectorAll("[name='']").length||d.push("\\["+ge+"*name"+ge+"*="+ge+"*(?:''|\"\")")}),le.cssHas||d.push(":has"),d=d.length&&new RegExp(d.join("|")),l=function(e,t){if(e===t)return a=!0,0;var n=!e.compareDocumentPosition-!t.compareDocumentPosition;return n||(1&(n=(e.ownerDocument||e)==(t.ownerDocument||t)?e.compareDocumentPosition(t):1)||!le.sortDetached&&t.compareDocumentPosition(e)===n?e===T||e.ownerDocument==ye&&I.contains(ye,e)?-1:t===T||t.ownerDocument==ye&&I.contains(ye,t)?1:o?se.call(o,e)-se.call(o,t):0:4&n?-1:1)}),T}for(e in I.matches=function(e,t){return I(e,null,null,t)},I.matchesSelector=function(e,t){if(V(e),C&&!h[t+" "]&&(!d||!d.test(t)))try{var n=i.call(e,t);if(n||le.disconnectedMatch||e.document&&11!==e.document.nodeType)return n}catch(e){h(t,!0)}return 0":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(O,P),e[3]=(e[3]||e[4]||e[5]||"").replace(O,P),"~="===e[2]&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),"nth"===e[1].slice(0,3)?(e[3]||I.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*("even"===e[3]||"odd"===e[3])),e[5]=+(e[7]+e[8]||"odd"===e[3])):e[3]&&I.error(e[0]),e},PSEUDO:function(e){var t,n=!e[6]&&e[2];return D.CHILD.test(e[0])?null:(e[3]?e[2]=e[4]||e[5]||"":n&&j.test(n)&&(t=Y(n,!0))&&(t=n.indexOf(")",n.length-t)-n.length)&&(e[0]=e[0].slice(0,t),e[2]=n.slice(0,t)),e.slice(0,3))}},filter:{TAG:function(e){var t=e.replace(O,P).toLowerCase();return"*"===e?function(){return!0}:function(e){return fe(e,t)}},CLASS:function(e){var t=s[e+" "];return t||(t=new RegExp("(^|"+ge+")"+e+"("+ge+"|$)"))&&s(e,function(e){return t.test("string"==typeof e.className&&e.className||"undefined"!=typeof e.getAttribute&&e.getAttribute("class")||"")})},ATTR:function(n,r,i){return function(e){var t=I.attr(e,n);return null==t?"!="===r:!r||(t+="","="===r?t===i:"!="===r?t!==i:"^="===r?i&&0===t.indexOf(i):"*="===r?i&&-1:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i;function T(e,n,r){return v(n)?ce.grep(e,function(e,t){return!!n.call(e,t,e)!==r}):n.nodeType?ce.grep(e,function(e){return e===n!==r}):"string"!=typeof n?ce.grep(e,function(e){return-1)[^>]*|#([\w-]+))$/;(ce.fn.init=function(e,t,n){var r,i;if(!e)return this;if(n=n||k,"string"==typeof e){if(!(r="<"===e[0]&&">"===e[e.length-1]&&3<=e.length?[null,e,null]:S.exec(e))||!r[1]&&t)return!t||t.jquery?(t||n).find(e):this.constructor(t).find(e);if(r[1]){if(t=t instanceof ce?t[0]:t,ce.merge(this,ce.parseHTML(r[1],t&&t.nodeType?t.ownerDocument||t:C,!0)),w.test(r[1])&&ce.isPlainObject(t))for(r in t)v(this[r])?this[r](t[r]):this.attr(r,t[r]);return this}return(i=C.getElementById(r[2]))&&(this[0]=i,this.length=1),this}return e.nodeType?(this[0]=e,this.length=1,this):v(e)?void 0!==n.ready?n.ready(e):e(ce):ce.makeArray(e,this)}).prototype=ce.fn,k=ce(C);var E=/^(?:parents|prev(?:Until|All))/,j={children:!0,contents:!0,next:!0,prev:!0};function A(e,t){while((e=e[t])&&1!==e.nodeType);return e}ce.fn.extend({has:function(e){var t=ce(e,this),n=t.length;return this.filter(function(){for(var e=0;e\x20\t\r\n\f]*)/i,Ce=/^$|^module$|\/(?:java|ecma)script/i;xe=C.createDocumentFragment().appendChild(C.createElement("div")),(be=C.createElement("input")).setAttribute("type","radio"),be.setAttribute("checked","checked"),be.setAttribute("name","t"),xe.appendChild(be),le.checkClone=xe.cloneNode(!0).cloneNode(!0).lastChild.checked,xe.innerHTML="",le.noCloneChecked=!!xe.cloneNode(!0).lastChild.defaultValue,xe.innerHTML="",le.option=!!xe.lastChild;var ke={thead:[1,"","
"],col:[2,"","
"],tr:[2,"","
"],td:[3,"","
"],_default:[0,"",""]};function Se(e,t){var n;return n="undefined"!=typeof e.getElementsByTagName?e.getElementsByTagName(t||"*"):"undefined"!=typeof e.querySelectorAll?e.querySelectorAll(t||"*"):[],void 0===t||t&&fe(e,t)?ce.merge([e],n):n}function Ee(e,t){for(var n=0,r=e.length;n",""]);var je=/<|&#?\w+;/;function Ae(e,t,n,r,i){for(var o,a,s,u,l,c,f=t.createDocumentFragment(),p=[],d=0,h=e.length;d\s*$/g;function Re(e,t){return fe(e,"table")&&fe(11!==t.nodeType?t:t.firstChild,"tr")&&ce(e).children("tbody")[0]||e}function Ie(e){return e.type=(null!==e.getAttribute("type"))+"/"+e.type,e}function We(e){return"true/"===(e.type||"").slice(0,5)?e.type=e.type.slice(5):e.removeAttribute("type"),e}function Fe(e,t){var n,r,i,o,a,s;if(1===t.nodeType){if(_.hasData(e)&&(s=_.get(e).events))for(i in _.remove(t,"handle events"),s)for(n=0,r=s[i].length;n").attr(n.scriptAttrs||{}).prop({charset:n.scriptCharset,src:n.url}).on("load error",i=function(e){r.remove(),i=null,e&&t("error"===e.type?404:200,e.type)}),C.head.appendChild(r[0])},abort:function(){i&&i()}}});var Jt,Kt=[],Zt=/(=)\?(?=&|$)|\?\?/;ce.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var e=Kt.pop()||ce.expando+"_"+jt.guid++;return this[e]=!0,e}}),ce.ajaxPrefilter("json jsonp",function(e,t,n){var r,i,o,a=!1!==e.jsonp&&(Zt.test(e.url)?"url":"string"==typeof e.data&&0===(e.contentType||"").indexOf("application/x-www-form-urlencoded")&&Zt.test(e.data)&&"data");if(a||"jsonp"===e.dataTypes[0])return r=e.jsonpCallback=v(e.jsonpCallback)?e.jsonpCallback():e.jsonpCallback,a?e[a]=e[a].replace(Zt,"$1"+r):!1!==e.jsonp&&(e.url+=(At.test(e.url)?"&":"?")+e.jsonp+"="+r),e.converters["script json"]=function(){return o||ce.error(r+" was not called"),o[0]},e.dataTypes[0]="json",i=ie[r],ie[r]=function(){o=arguments},n.always(function(){void 0===i?ce(ie).removeProp(r):ie[r]=i,e[r]&&(e.jsonpCallback=t.jsonpCallback,Kt.push(r)),o&&v(i)&&i(o[0]),o=i=void 0}),"script"}),le.createHTMLDocument=((Jt=C.implementation.createHTMLDocument("").body).innerHTML="
",2===Jt.childNodes.length),ce.parseHTML=function(e,t,n){return"string"!=typeof e?[]:("boolean"==typeof t&&(n=t,t=!1),t||(le.createHTMLDocument?((r=(t=C.implementation.createHTMLDocument("")).createElement("base")).href=C.location.href,t.head.appendChild(r)):t=C),o=!n&&[],(i=w.exec(e))?[t.createElement(i[1])]:(i=Ae([e],t,o),o&&o.length&&ce(o).remove(),ce.merge([],i.childNodes)));var r,i,o},ce.fn.load=function(e,t,n){var r,i,o,a=this,s=e.indexOf(" ");return-1").append(ce.parseHTML(e)).find(r):e)}).always(n&&function(e,t){a.each(function(){n.apply(this,o||[e.responseText,t,e])})}),this},ce.expr.pseudos.animated=function(t){return ce.grep(ce.timers,function(e){return t===e.elem}).length},ce.offset={setOffset:function(e,t,n){var r,i,o,a,s,u,l=ce.css(e,"position"),c=ce(e),f={};"static"===l&&(e.style.position="relative"),s=c.offset(),o=ce.css(e,"top"),u=ce.css(e,"left"),("absolute"===l||"fixed"===l)&&-1<(o+u).indexOf("auto")?(a=(r=c.position()).top,i=r.left):(a=parseFloat(o)||0,i=parseFloat(u)||0),v(t)&&(t=t.call(e,n,ce.extend({},s))),null!=t.top&&(f.top=t.top-s.top+a),null!=t.left&&(f.left=t.left-s.left+i),"using"in t?t.using.call(e,f):c.css(f)}},ce.fn.extend({offset:function(t){if(arguments.length)return void 0===t?this:this.each(function(e){ce.offset.setOffset(this,t,e)});var e,n,r=this[0];return r?r.getClientRects().length?(e=r.getBoundingClientRect(),n=r.ownerDocument.defaultView,{top:e.top+n.pageYOffset,left:e.left+n.pageXOffset}):{top:0,left:0}:void 0},position:function(){if(this[0]){var e,t,n,r=this[0],i={top:0,left:0};if("fixed"===ce.css(r,"position"))t=r.getBoundingClientRect();else{t=this.offset(),n=r.ownerDocument,e=r.offsetParent||n.documentElement;while(e&&(e===n.body||e===n.documentElement)&&"static"===ce.css(e,"position"))e=e.parentNode;e&&e!==r&&1===e.nodeType&&((i=ce(e).offset()).top+=ce.css(e,"borderTopWidth",!0),i.left+=ce.css(e,"borderLeftWidth",!0))}return{top:t.top-i.top-ce.css(r,"marginTop",!0),left:t.left-i.left-ce.css(r,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var e=this.offsetParent;while(e&&"static"===ce.css(e,"position"))e=e.offsetParent;return e||J})}}),ce.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(t,i){var o="pageYOffset"===i;ce.fn[t]=function(e){return M(this,function(e,t,n){var r;if(y(e)?r=e:9===e.nodeType&&(r=e.defaultView),void 0===n)return r?r[i]:e[t];r?r.scrollTo(o?r.pageXOffset:n,o?n:r.pageYOffset):e[t]=n},t,e,arguments.length)}}),ce.each(["top","left"],function(e,n){ce.cssHooks[n]=Ye(le.pixelPosition,function(e,t){if(t)return t=Ge(e,n),_e.test(t)?ce(e).position()[n]+"px":t})}),ce.each({Height:"height",Width:"width"},function(a,s){ce.each({padding:"inner"+a,content:s,"":"outer"+a},function(r,o){ce.fn[o]=function(e,t){var n=arguments.length&&(r||"boolean"!=typeof e),i=r||(!0===e||!0===t?"margin":"border");return M(this,function(e,t,n){var r;return y(e)?0===o.indexOf("outer")?e["inner"+a]:e.document.documentElement["client"+a]:9===e.nodeType?(r=e.documentElement,Math.max(e.body["scroll"+a],r["scroll"+a],e.body["offset"+a],r["offset"+a],r["client"+a])):void 0===n?ce.css(e,t,i):ce.style(e,t,n,i)},s,n?e:void 0,n)}})}),ce.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(e,t){ce.fn[t]=function(e){return this.on(t,e)}}),ce.fn.extend({bind:function(e,t,n){return this.on(e,null,t,n)},unbind:function(e,t){return this.off(e,null,t)},delegate:function(e,t,n,r){return this.on(t,e,n,r)},undelegate:function(e,t,n){return 1===arguments.length?this.off(e,"**"):this.off(t,e||"**",n)},hover:function(e,t){return this.on("mouseenter",e).on("mouseleave",t||e)}}),ce.each("blur focus focusin focusout resize scroll click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup contextmenu".split(" "),function(e,n){ce.fn[n]=function(e,t){return 0f&&(e=a.render.queue[f]);f++)d=e.generate(),typeof e.callback==typeof Function&&e.callback(d);a.render.queue.splice(0,f),a.render.queue.length?setTimeout(c):(a.dispatch.render_end(),a.render.active=!1)};setTimeout(c)},a.render.active=!1,a.render.queue=[],a.addGraph=function(b){typeof arguments[0]==typeof Function&&(b={generate:arguments[0],callback:arguments[1]}),a.render.queue.push(b),a.render.active||a.render()},"undefined"!=typeof module&&"undefined"!=typeof exports&&(module.exports=a),"undefined"!=typeof window&&(window.nv=a),a.dom.write=function(a){return void 0!==window.fastdom?fastdom.write(a):a()},a.dom.read=function(a){return void 0!==window.fastdom?fastdom.read(a):a()},a.interactiveGuideline=function(){"use strict";function b(l){l.each(function(l){function m(){var a=d3.mouse(this),d=a[0],e=a[1],i=!0,j=!1;if(k&&(d=d3.event.offsetX,e=d3.event.offsetY,"svg"!==d3.event.target.tagName&&(i=!1),d3.event.target.className.baseVal.match("nv-legend")&&(j=!0)),i&&(d-=f.left,e-=f.top),0>d||0>e||d>o||e>p||d3.event.relatedTarget&&void 0===d3.event.relatedTarget.ownerSVGElement||j){if(k&&d3.event.relatedTarget&&void 0===d3.event.relatedTarget.ownerSVGElement&&(void 0===d3.event.relatedTarget.className||d3.event.relatedTarget.className.match(c.nvPointerEventsClass)))return;return h.elementMouseout({mouseX:d,mouseY:e}),b.renderGuideLine(null),void c.hidden(!0)}c.hidden(!1);var l=g.invert(d);h.elementMousemove({mouseX:d,mouseY:e,pointXValue:l}),"dblclick"===d3.event.type&&h.elementDblclick({mouseX:d,mouseY:e,pointXValue:l}),"click"===d3.event.type&&h.elementClick({mouseX:d,mouseY:e,pointXValue:l})}var n=d3.select(this),o=d||960,p=e||400,q=n.selectAll("g.nv-wrap.nv-interactiveLineLayer").data([l]),r=q.enter().append("g").attr("class"," nv-wrap nv-interactiveLineLayer");r.append("g").attr("class","nv-interactiveGuideLine"),j&&(j.on("touchmove",m).on("mousemove",m,!0).on("mouseout",m,!0).on("dblclick",m).on("click",m),b.guideLine=null,b.renderGuideLine=function(c){i&&(b.guideLine&&b.guideLine.attr("x1")===c||a.dom.write(function(){var b=q.select(".nv-interactiveGuideLine").selectAll("line").data(null!=c?[a.utils.NaNtoZero(c)]:[],String);b.enter().append("line").attr("class","nv-guideline").attr("x1",function(a){return a}).attr("x2",function(a){return a}).attr("y1",p).attr("y2",0),b.exit().remove()}))})})}var c=a.models.tooltip();c.duration(0).hideDelay(0)._isInteractiveLayer(!0).hidden(!1);var d=null,e=null,f={left:0,top:0},g=d3.scale.linear(),h=d3.dispatch("elementMousemove","elementMouseout","elementClick","elementDblclick"),i=!0,j=null,k="ActiveXObject"in window;return b.dispatch=h,b.tooltip=c,b.margin=function(a){return arguments.length?(f.top="undefined"!=typeof a.top?a.top:f.top,f.left="undefined"!=typeof a.left?a.left:f.left,b):f},b.width=function(a){return arguments.length?(d=a,b):d},b.height=function(a){return arguments.length?(e=a,b):e},b.xScale=function(a){return arguments.length?(g=a,b):g},b.showGuideLine=function(a){return arguments.length?(i=a,b):i},b.svgContainer=function(a){return arguments.length?(j=a,b):j},b},a.interactiveBisect=function(a,b,c){"use strict";if(!(a instanceof Array))return null;var d;d="function"!=typeof c?function(a){return a.x}:c;var e=function(a,b){return d(a)-b},f=d3.bisector(e).left,g=d3.max([0,f(a,b)-1]),h=d(a[g]);if("undefined"==typeof h&&(h=g),h===b)return g;var i=d3.min([g+1,a.length-1]),j=d(a[i]);return"undefined"==typeof j&&(j=i),Math.abs(j-b)>=Math.abs(h-b)?g:i},a.nearestValueIndex=function(a,b,c){"use strict";var d=1/0,e=null;return a.forEach(function(a,f){var g=Math.abs(b-a);null!=a&&d>=g&&c>g&&(d=g,e=f)}),e},function(){"use strict";a.models.tooltip=function(){function b(){if(k){var a=d3.select(k);"svg"!==a.node().tagName&&(a=a.select("svg"));var b=a.node()?a.attr("viewBox"):null;if(b){b=b.split(" ");var c=parseInt(a.style("width"),10)/b[2];p.left=p.left*c,p.top=p.top*c}}}function c(){if(!n){var a;a=k?k:document.body,n=d3.select(a).append("div").attr("class","nvtooltip "+(j?j:"xy-tooltip")).attr("id",v),n.style("top",0).style("left",0),n.style("opacity",0),n.selectAll("div, table, td, tr").classed(w,!0),n.classed(w,!0),o=n.node()}}function d(){if(r&&B(e)){b();var f=p.left,g=null!==i?i:p.top;return a.dom.write(function(){c();var b=A(e);b&&(o.innerHTML=b),k&&u?a.dom.read(function(){var a=k.getElementsByTagName("svg")[0],b={left:0,top:0};if(a){var c=a.getBoundingClientRect(),d=k.getBoundingClientRect(),e=c.top;if(0>e){var i=k.getBoundingClientRect();e=Math.abs(e)>i.height?0:e}b.top=Math.abs(e-d.top),b.left=Math.abs(c.left-d.left)}f+=k.offsetLeft+b.left-2*k.scrollLeft,g+=k.offsetTop+b.top-2*k.scrollTop,h&&h>0&&(g=Math.floor(g/h)*h),C([f,g])}):C([f,g])}),d}}var e=null,f="w",g=25,h=0,i=null,j=null,k=null,l=!0,m=400,n=null,o=null,p={left:null,top:null},q={left:0,top:0},r=!0,s=100,t=!0,u=!1,v="nvtooltip-"+Math.floor(1e5*Math.random()),w="nv-pointer-events-none",x=function(a){return a},y=function(a){return a},z=function(a){return a},A=function(a){if(null===a)return"";var b=d3.select(document.createElement("table"));if(t){var c=b.selectAll("thead").data([a]).enter().append("thead");c.append("tr").append("td").attr("colspan",3).append("strong").classed("x-value",!0).html(y(a.value))}var d=b.selectAll("tbody").data([a]).enter().append("tbody"),e=d.selectAll("tr").data(function(a){return a.series}).enter().append("tr").classed("highlight",function(a){return a.highlight});e.append("td").classed("legend-color-guide",!0).append("div").style("background-color",function(a){return a.color}),e.append("td").classed("key",!0).html(function(a,b){return z(a.key,b)}),e.append("td").classed("value",!0).html(function(a,b){return x(a.value,b)}),e.selectAll("td").each(function(a){if(a.highlight){var b=d3.scale.linear().domain([0,1]).range(["#fff",a.color]),c=.6;d3.select(this).style("border-bottom-color",b(c)).style("border-top-color",b(c))}});var f=b.node().outerHTML;return void 0!==a.footer&&(f+=""),f},B=function(a){if(a&&a.series){if(a.series instanceof Array)return!!a.series.length;if(a.series instanceof Object)return a.series=[a.series],!0}return!1},C=function(b){o&&a.dom.read(function(){var c,d,e=parseInt(o.offsetHeight,10),h=parseInt(o.offsetWidth,10),i=a.utils.windowSize().width,j=a.utils.windowSize().height,k=window.pageYOffset,p=window.pageXOffset;j=window.innerWidth>=document.body.scrollWidth?j:j-16,i=window.innerHeight>=document.body.scrollHeight?i:i-16;var r,t,u=function(a){var b=d;do isNaN(a.offsetTop)||(b+=a.offsetTop),a=a.offsetParent;while(a);return b},v=function(a){var b=c;do isNaN(a.offsetLeft)||(b+=a.offsetLeft),a=a.offsetParent;while(a);return b};switch(f){case"e":c=b[0]-h-g,d=b[1]-e/2,r=v(o),t=u(o),p>r&&(c=b[0]+g>p?b[0]+g:p-r+c),k>t&&(d=k-t+d),t+e>k+j&&(d=k+j-t+d-e);break;case"w":c=b[0]+g,d=b[1]-e/2,r=v(o),t=u(o),r+h>i&&(c=b[0]-h-g),k>t&&(d=k+5),t+e>k+j&&(d=k+j-t+d-e);break;case"n":c=b[0]-h/2-5,d=b[1]+g,r=v(o),t=u(o),p>r&&(c=p+5),r+h>i&&(c=c-h/2+5),t+e>k+j&&(d=k+j-t+d-e);break;case"s":c=b[0]-h/2,d=b[1]-e-g,r=v(o),t=u(o),p>r&&(c=p+5),r+h>i&&(c=c-h/2+5),k>t&&(d=k);break;case"none":c=b[0],d=b[1]-g,r=v(o),t=u(o)}c-=q.left,d-=q.top;var w=o.getBoundingClientRect(),k=window.pageYOffset||document.documentElement.scrollTop,p=window.pageXOffset||document.documentElement.scrollLeft,x="translate("+(w.left+p)+"px, "+(w.top+k)+"px)",y="translate("+c+"px, "+d+"px)",z=d3.interpolateString(x,y),A=n.style("opacity")<.1;l?n.transition().delay(m).duration(0).style("opacity",0):n.interrupt().transition().duration(A?0:s).styleTween("transform",function(){return z},"important").style("-webkit-transform",y).style("opacity",1)})};return d.nvPointerEventsClass=w,d.options=a.utils.optionsFunc.bind(d),d._options=Object.create({},{duration:{get:function(){return s},set:function(a){s=a}},gravity:{get:function(){return f},set:function(a){f=a}},distance:{get:function(){return g},set:function(a){g=a}},snapDistance:{get:function(){return h},set:function(a){h=a}},classes:{get:function(){return j},set:function(a){j=a}},chartContainer:{get:function(){return k},set:function(a){k=a}},fixedTop:{get:function(){return i},set:function(a){i=a}},enabled:{get:function(){return r},set:function(a){r=a}},hideDelay:{get:function(){return m},set:function(a){m=a}},contentGenerator:{get:function(){return A},set:function(a){A=a}},valueFormatter:{get:function(){return x},set:function(a){x=a}},headerFormatter:{get:function(){return y},set:function(a){y=a}},keyFormatter:{get:function(){return z},set:function(a){z=a}},headerEnabled:{get:function(){return t},set:function(a){t=a}},_isInteractiveLayer:{get:function(){return u},set:function(a){u=!!a}},position:{get:function(){return p},set:function(a){p.left=void 0!==a.left?a.left:p.left,p.top=void 0!==a.top?a.top:p.top}},offset:{get:function(){return q},set:function(a){q.left=void 0!==a.left?a.left:q.left,q.top=void 0!==a.top?a.top:q.top}},hidden:{get:function(){return l},set:function(a){l!=a&&(l=!!a,d())}},data:{get:function(){return e},set:function(a){a.point&&(a.value=a.point.x,a.series=a.series||{},a.series.value=a.point.y,a.series.color=a.point.color||a.series.color),e=a}},tooltipElem:{get:function(){return o},set:function(){}},id:{get:function(){return v},set:function(){}}}),a.utils.initOptions(d),d}}(),a.utils.windowSize=function(){var a={width:640,height:480};return window.innerWidth&&window.innerHeight?(a.width=window.innerWidth,a.height=window.innerHeight,a):"CSS1Compat"==document.compatMode&&document.documentElement&&document.documentElement.offsetWidth?(a.width=document.documentElement.offsetWidth,a.height=document.documentElement.offsetHeight,a):document.body&&document.body.offsetWidth?(a.width=document.body.offsetWidth,a.height=document.body.offsetHeight,a):a},a.utils.windowResize=function(b){return window.addEventListener?window.addEventListener("resize",b):a.log("ERROR: Failed to bind to window.resize with: ",b),{callback:b,clear:function(){window.removeEventListener("resize",b)}}},a.utils.getColor=function(b){if(void 0===b)return a.utils.defaultColor();if(Array.isArray(b)){var c=d3.scale.ordinal().range(b);return function(a,b){var d=void 0===b?a:b;return a.color||c(d)}}return b},a.utils.defaultColor=function(){return a.utils.getColor(d3.scale.category20().range())},a.utils.customTheme=function(a,b,c){b=b||function(a){return a.key},c=c||d3.scale.category20().range();var d=c.length;return function(e){var f=b(e);return"function"==typeof a[f]?a[f]():void 0!==a[f]?a[f]:(d||(d=c.length),d-=1,c[d])}},a.utils.pjax=function(b,c){var d=function(d){d3.html(d,function(d){var e=d3.select(c).node();e.parentNode.replaceChild(d3.select(d).select(c).node(),e),a.utils.pjax(b,c)})};d3.selectAll(b).on("click",function(){history.pushState(this.href,this.textContent,this.href),d(this.href),d3.event.preventDefault()}),d3.select(window).on("popstate",function(){d3.event.state&&d(d3.event.state)})},a.utils.calcApproxTextWidth=function(a){if("function"==typeof a.style&&"function"==typeof a.text){var b=parseInt(a.style("font-size").replace("px",""),10),c=a.text().length;return c*b*.5}return 0},a.utils.NaNtoZero=function(a){return"number"!=typeof a||isNaN(a)||null===a||1/0===a||a===-1/0?0:a},d3.selection.prototype.watchTransition=function(a){var b=[this].concat([].slice.call(arguments,1));return a.transition.apply(a,b)},a.utils.renderWatch=function(b,c){if(!(this instanceof a.utils.renderWatch))return new a.utils.renderWatch(b,c);var d=void 0!==c?c:250,e=[],f=this;this.models=function(a){return a=[].slice.call(arguments,0),a.forEach(function(a){a.__rendered=!1,function(a){a.dispatch.on("renderEnd",function(){a.__rendered=!0,f.renderEnd("model")})}(a),e.indexOf(a)<0&&e.push(a)}),this},this.reset=function(a){void 0!==a&&(d=a),e=[]},this.transition=function(a,b,c){if(b=arguments.length>1?[].slice.call(arguments,1):[],c=b.length>1?b.pop():void 0!==d?d:250,a.__rendered=!1,e.indexOf(a)<0&&e.push(a),0===c)return a.__rendered=!0,a.delay=function(){return this},a.duration=function(){return this},a;a.__rendered=0===a.length?!0:a.every(function(a){return!a.length})?!0:!1;var g=0;return a.transition().duration(c).each(function(){++g}).each("end",function(){0===--g&&(a.__rendered=!0,f.renderEnd.apply(this,b))})},this.renderEnd=function(){e.every(function(a){return a.__rendered})&&(e.forEach(function(a){a.__rendered=!1}),b.renderEnd.apply(this,arguments))}},a.utils.deepExtend=function(b){var c=arguments.length>1?[].slice.call(arguments,1):[];c.forEach(function(c){for(var d in c){var e=b[d]instanceof Array,f="object"==typeof b[d],g="object"==typeof c[d];f&&!e&&g?a.utils.deepExtend(b[d],c[d]):b[d]=c[d]}})},a.utils.state=function(){if(!(this instanceof a.utils.state))return new a.utils.state;var b={},c=function(){},d=function(){return{}},e=null,f=null;this.dispatch=d3.dispatch("change","set"),this.dispatch.on("set",function(a){c(a,!0)}),this.getter=function(a){return d=a,this},this.setter=function(a,b){return b||(b=function(){}),c=function(c,d){a(c),d&&b()},this},this.init=function(b){e=e||{},a.utils.deepExtend(e,b)};var g=function(){var a=d();if(JSON.stringify(a)===JSON.stringify(b))return!1;for(var c in a)void 0===b[c]&&(b[c]={}),b[c]=a[c],f=!0;return!0};this.update=function(){e&&(c(e,!1),e=null),g.call(this)&&this.dispatch.change(b)}},a.utils.optionsFunc=function(a){return a&&d3.map(a).forEach(function(a,b){"function"==typeof this[a]&&this[a](b)}.bind(this)),this},a.utils.calcTicksX=function(b,c){var d=1,e=0;for(e;ed?f:d}return a.log("Requested number of ticks: ",b),a.log("Calculated max values to be: ",d),b=b>d?b=d-1:b,b=1>b?1:b,b=Math.floor(b),a.log("Calculating tick count as: ",b),b},a.utils.calcTicksY=function(b,c){return a.utils.calcTicksX(b,c)},a.utils.initOption=function(a,b){a._calls&&a._calls[b]?a[b]=a._calls[b]:(a[b]=function(c){return arguments.length?(a._overrides[b]=!0,a._options[b]=c,a):a._options[b]},a["_"+b]=function(c){return arguments.length?(a._overrides[b]||(a._options[b]=c),a):a._options[b]})},a.utils.initOptions=function(b){b._overrides=b._overrides||{};var c=Object.getOwnPropertyNames(b._options||{}),d=Object.getOwnPropertyNames(b._calls||{});c=c.concat(d);for(var e in c)a.utils.initOption(b,c[e])},a.utils.inheritOptionsD3=function(a,b,c){a._d3options=c.concat(a._d3options||[]),c.unshift(b),c.unshift(a),d3.rebind.apply(this,c)},a.utils.arrayUnique=function(a){return a.sort().filter(function(b,c){return!c||b!=a[c-1]})},a.utils.symbolMap=d3.map(),a.utils.symbol=function(){function b(b,e){var f=c.call(this,b,e),g=d.call(this,b,e);return-1!==d3.svg.symbolTypes.indexOf(f)?d3.svg.symbol().type(f).size(g)():a.utils.symbolMap.get(f)(g)}var c,d=64;return b.type=function(a){return arguments.length?(c=d3.functor(a),b):c},b.size=function(a){return arguments.length?(d=d3.functor(a),b):d},b},a.utils.inheritOptions=function(b,c){var d=Object.getOwnPropertyNames(c._options||{}),e=Object.getOwnPropertyNames(c._calls||{}),f=c._inherited||[],g=c._d3options||[],h=d.concat(e).concat(f).concat(g);h.unshift(c),h.unshift(b),d3.rebind.apply(this,h),b._inherited=a.utils.arrayUnique(d.concat(e).concat(f).concat(d).concat(b._inherited||[])),b._d3options=a.utils.arrayUnique(g.concat(b._d3options||[]))},a.utils.initSVG=function(a){a.classed({"nvd3-svg":!0})},a.utils.sanitizeHeight=function(a,b){return a||parseInt(b.style("height"),10)||400},a.utils.sanitizeWidth=function(a,b){return a||parseInt(b.style("width"),10)||960},a.utils.availableHeight=function(b,c,d){return a.utils.sanitizeHeight(b,c)-d.top-d.bottom},a.utils.availableWidth=function(b,c,d){return a.utils.sanitizeWidth(b,c)-d.left-d.right},a.utils.noData=function(b,c){var d=b.options(),e=d.margin(),f=d.noData(),g=null==f?["No Data Available."]:[f],h=a.utils.availableHeight(d.height(),c,e),i=a.utils.availableWidth(d.width(),c,e),j=e.left+i/2,k=e.top+h/2;c.selectAll("g").remove();var l=c.selectAll(".nv-noData").data(g);l.enter().append("text").attr("class","nvd3 nv-noData").attr("dy","-.7em").style("text-anchor","middle"),l.attr("x",j).attr("y",k).text(function(a){return a})},a.models.axis=function(){"use strict";function b(g){return s.reset(),g.each(function(b){var g=d3.select(this);a.utils.initSVG(g);var p=g.selectAll("g.nv-wrap.nv-axis").data([b]),q=p.enter().append("g").attr("class","nvd3 nv-wrap nv-axis"),t=(q.append("g"),p.select("g"));null!==n?c.ticks(n):("top"==c.orient()||"bottom"==c.orient())&&c.ticks(Math.abs(d.range()[1]-d.range()[0])/100),t.watchTransition(s,"axis").call(c),r=r||c.scale();var u=c.tickFormat();null==u&&(u=r.tickFormat());var v=t.selectAll("text.nv-axislabel").data([h||null]);v.exit().remove();var w,x,y;switch(c.orient()){case"top":v.enter().append("text").attr("class","nv-axislabel"),y=d.range().length<2?0:2===d.range().length?d.range()[1]:d.range()[d.range().length-1]+(d.range()[1]-d.range()[0]),v.attr("text-anchor","middle").attr("y",0).attr("x",y/2),i&&(x=p.selectAll("g.nv-axisMaxMin").data(d.domain()),x.enter().append("g").attr("class",function(a,b){return["nv-axisMaxMin","nv-axisMaxMin-x",0==b?"nv-axisMin-x":"nv-axisMax-x"].join(" ")}).append("text"),x.exit().remove(),x.attr("transform",function(b){return"translate("+a.utils.NaNtoZero(d(b))+",0)"}).select("text").attr("dy","-0.5em").attr("y",-c.tickPadding()).attr("text-anchor","middle").text(function(a){var b=u(a);return(""+b).match("NaN")?"":b}),x.watchTransition(s,"min-max top").attr("transform",function(b,c){return"translate("+a.utils.NaNtoZero(d.range()[c])+",0)"}));break;case"bottom":w=o+36;var z=30,A=0,B=t.selectAll("g").select("text"),C="";if(j%360){B.each(function(){var a=this.getBoundingClientRect(),b=a.width;A=a.height,b>z&&(z=b)}),C="rotate("+j+" 0,"+(A/2+c.tickPadding())+")";var D=Math.abs(Math.sin(j*Math.PI/180));w=(D?D*z:z)+30,B.attr("transform",C).style("text-anchor",j%360>0?"start":"end")}v.enter().append("text").attr("class","nv-axislabel"),y=d.range().length<2?0:2===d.range().length?d.range()[1]:d.range()[d.range().length-1]+(d.range()[1]-d.range()[0]),v.attr("text-anchor","middle").attr("y",w).attr("x",y/2),i&&(x=p.selectAll("g.nv-axisMaxMin").data([d.domain()[0],d.domain()[d.domain().length-1]]),x.enter().append("g").attr("class",function(a,b){return["nv-axisMaxMin","nv-axisMaxMin-x",0==b?"nv-axisMin-x":"nv-axisMax-x"].join(" ")}).append("text"),x.exit().remove(),x.attr("transform",function(b){return"translate("+a.utils.NaNtoZero(d(b)+(m?d.rangeBand()/2:0))+",0)"}).select("text").attr("dy",".71em").attr("y",c.tickPadding()).attr("transform",C).style("text-anchor",j?j%360>0?"start":"end":"middle").text(function(a){var b=u(a);return(""+b).match("NaN")?"":b}),x.watchTransition(s,"min-max bottom").attr("transform",function(b){return"translate("+a.utils.NaNtoZero(d(b)+(m?d.rangeBand()/2:0))+",0)"})),l&&B.attr("transform",function(a,b){return"translate(0,"+(b%2==0?"0":"12")+")"});break;case"right":v.enter().append("text").attr("class","nv-axislabel"),v.style("text-anchor",k?"middle":"begin").attr("transform",k?"rotate(90)":"").attr("y",k?-Math.max(e.right,f)+12:-10).attr("x",k?d3.max(d.range())/2:c.tickPadding()),i&&(x=p.selectAll("g.nv-axisMaxMin").data(d.domain()),x.enter().append("g").attr("class",function(a,b){return["nv-axisMaxMin","nv-axisMaxMin-y",0==b?"nv-axisMin-y":"nv-axisMax-y"].join(" ")}).append("text").style("opacity",0),x.exit().remove(),x.attr("transform",function(b){return"translate(0,"+a.utils.NaNtoZero(d(b))+")"}).select("text").attr("dy",".32em").attr("y",0).attr("x",c.tickPadding()).style("text-anchor","start").text(function(a){var b=u(a);return(""+b).match("NaN")?"":b}),x.watchTransition(s,"min-max right").attr("transform",function(b,c){return"translate(0,"+a.utils.NaNtoZero(d.range()[c])+")"}).select("text").style("opacity",1));break;case"left":v.enter().append("text").attr("class","nv-axislabel"),v.style("text-anchor",k?"middle":"end").attr("transform",k?"rotate(-90)":"").attr("y",k?-Math.max(e.left,f)+25-(o||0):-10).attr("x",k?-d3.max(d.range())/2:-c.tickPadding()),i&&(x=p.selectAll("g.nv-axisMaxMin").data(d.domain()),x.enter().append("g").attr("class",function(a,b){return["nv-axisMaxMin","nv-axisMaxMin-y",0==b?"nv-axisMin-y":"nv-axisMax-y"].join(" ")}).append("text").style("opacity",0),x.exit().remove(),x.attr("transform",function(b){return"translate(0,"+a.utils.NaNtoZero(r(b))+")"}).select("text").attr("dy",".32em").attr("y",0).attr("x",-c.tickPadding()).attr("text-anchor","end").text(function(a){var b=u(a);return(""+b).match("NaN")?"":b}),x.watchTransition(s,"min-max right").attr("transform",function(b,c){return"translate(0,"+a.utils.NaNtoZero(d.range()[c])+")"}).select("text").style("opacity",1))}if(v.text(function(a){return a}),!i||"left"!==c.orient()&&"right"!==c.orient()||(t.selectAll("g").each(function(a){d3.select(this).select("text").attr("opacity",1),(d(a)d.range()[0]-10)&&((a>1e-10||-1e-10>a)&&d3.select(this).attr("opacity",0),d3.select(this).select("text").attr("opacity",0))}),d.domain()[0]==d.domain()[1]&&0==d.domain()[0]&&p.selectAll("g.nv-axisMaxMin").style("opacity",function(a,b){return b?0:1})),i&&("top"===c.orient()||"bottom"===c.orient())){var E=[];p.selectAll("g.nv-axisMaxMin").each(function(a,b){try{E.push(b?d(a)-this.getBoundingClientRect().width-4:d(a)+this.getBoundingClientRect().width+4)}catch(c){E.push(b?d(a)-4:d(a)+4)}}),t.selectAll("g").each(function(a){(d(a)E[1])&&(a>1e-10||-1e-10>a?d3.select(this).remove():d3.select(this).select("text").remove())})}t.selectAll(".tick").filter(function(a){return!parseFloat(Math.round(1e5*a)/1e6)&&void 0!==a}).classed("zero",!0),r=d.copy()}),s.renderEnd("axis immediate"),b}var c=d3.svg.axis(),d=d3.scale.linear(),e={top:0,right:0,bottom:0,left:0},f=75,g=60,h=null,i=!0,j=0,k=!0,l=!1,m=!1,n=null,o=0,p=250,q=d3.dispatch("renderEnd");c.scale(d).orient("bottom").tickFormat(function(a){return a});var r,s=a.utils.renderWatch(q,p);return b.axis=c,b.dispatch=q,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{axisLabelDistance:{get:function(){return o},set:function(a){o=a}},staggerLabels:{get:function(){return l},set:function(a){l=a}},rotateLabels:{get:function(){return j},set:function(a){j=a}},rotateYLabel:{get:function(){return k},set:function(a){k=a}},showMaxMin:{get:function(){return i},set:function(a){i=a}},axisLabel:{get:function(){return h},set:function(a){h=a}},height:{get:function(){return g},set:function(a){g=a}},ticks:{get:function(){return n},set:function(a){n=a}},width:{get:function(){return f},set:function(a){f=a}},margin:{get:function(){return e},set:function(a){e.top=void 0!==a.top?a.top:e.top,e.right=void 0!==a.right?a.right:e.right,e.bottom=void 0!==a.bottom?a.bottom:e.bottom,e.left=void 0!==a.left?a.left:e.left}},duration:{get:function(){return p},set:function(a){p=a,s.reset(p)}},scale:{get:function(){return d},set:function(e){d=e,c.scale(d),m="function"==typeof d.rangeBands,a.utils.inheritOptionsD3(b,d,["domain","range","rangeBand","rangeBands"])}}}),a.utils.initOptions(b),a.utils.inheritOptionsD3(b,c,["orient","tickValues","tickSubdivide","tickSize","tickPadding","tickFormat"]),a.utils.inheritOptionsD3(b,d,["domain","range","rangeBand","rangeBands"]),b},a.models.boxPlot=function(){"use strict";function b(l){return v.reset(),l.each(function(b){var l=j-i.left-i.right,p=k-i.top-i.bottom;r=d3.select(this),a.utils.initSVG(r),m.domain(c||b.map(function(a,b){return o(a,b)})).rangeBands(e||[0,l],.1);var w=[];if(!d){var x=d3.min(b.map(function(a){var b=[];return b.push(a.values.Q1),a.values.hasOwnProperty("whisker_low")&&null!==a.values.whisker_low&&b.push(a.values.whisker_low),a.values.hasOwnProperty("outliers")&&null!==a.values.outliers&&(b=b.concat(a.values.outliers)),d3.min(b)})),y=d3.max(b.map(function(a){var b=[];return b.push(a.values.Q3),a.values.hasOwnProperty("whisker_high")&&null!==a.values.whisker_high&&b.push(a.values.whisker_high),a.values.hasOwnProperty("outliers")&&null!==a.values.outliers&&(b=b.concat(a.values.outliers)),d3.max(b)}));w=[x,y]}n.domain(d||w),n.range(f||[p,0]),g=g||m,h=h||n.copy().range([n(0),n(0)]);{var z=r.selectAll("g.nv-wrap").data([b]);z.enter().append("g").attr("class","nvd3 nv-wrap")}z.attr("transform","translate("+i.left+","+i.top+")");var A=z.selectAll(".nv-boxplot").data(function(a){return a}),B=A.enter().append("g").style("stroke-opacity",1e-6).style("fill-opacity",1e-6);A.attr("class","nv-boxplot").attr("transform",function(a,b){return"translate("+(m(o(a,b))+.05*m.rangeBand())+", 0)"}).classed("hover",function(a){return a.hover}),A.watchTransition(v,"nv-boxplot: boxplots").style("stroke-opacity",1).style("fill-opacity",.75).delay(function(a,c){return c*t/b.length}).attr("transform",function(a,b){return"translate("+(m(o(a,b))+.05*m.rangeBand())+", 0)"}),A.exit().remove(),B.each(function(a,b){var c=d3.select(this);["low","high"].forEach(function(d){a.values.hasOwnProperty("whisker_"+d)&&null!==a.values["whisker_"+d]&&(c.append("line").style("stroke",a.color?a.color:q(a,b)).attr("class","nv-boxplot-whisker nv-boxplot-"+d),c.append("line").style("stroke",a.color?a.color:q(a,b)).attr("class","nv-boxplot-tick nv-boxplot-"+d))})});var C=A.selectAll(".nv-boxplot-outlier").data(function(a){return a.values.hasOwnProperty("outliers")&&null!==a.values.outliers?a.values.outliers:[]});C.enter().append("circle").style("fill",function(a,b,c){return q(a,c)}).style("stroke",function(a,b,c){return q(a,c)}).on("mouseover",function(a,b,c){d3.select(this).classed("hover",!0),s.elementMouseover({series:{key:a,color:q(a,c)},e:d3.event})}).on("mouseout",function(a,b,c){d3.select(this).classed("hover",!1),s.elementMouseout({series:{key:a,color:q(a,c)},e:d3.event})}).on("mousemove",function(){s.elementMousemove({e:d3.event})}),C.attr("class","nv-boxplot-outlier"),C.watchTransition(v,"nv-boxplot: nv-boxplot-outlier").attr("cx",.45*m.rangeBand()).attr("cy",function(a){return n(a)}).attr("r","3"),C.exit().remove();var D=function(){return null===u?.9*m.rangeBand():Math.min(75,.9*m.rangeBand())},E=function(){return.45*m.rangeBand()-D()/2},F=function(){return.45*m.rangeBand()+D()/2};["low","high"].forEach(function(a){var b="low"===a?"Q1":"Q3";A.select("line.nv-boxplot-whisker.nv-boxplot-"+a).watchTransition(v,"nv-boxplot: boxplots").attr("x1",.45*m.rangeBand()).attr("y1",function(b){return n(b.values["whisker_"+a])}).attr("x2",.45*m.rangeBand()).attr("y2",function(a){return n(a.values[b])}),A.select("line.nv-boxplot-tick.nv-boxplot-"+a).watchTransition(v,"nv-boxplot: boxplots").attr("x1",E).attr("y1",function(b){return n(b.values["whisker_"+a])}).attr("x2",F).attr("y2",function(b){return n(b.values["whisker_"+a])})}),["low","high"].forEach(function(a){B.selectAll(".nv-boxplot-"+a).on("mouseover",function(b,c,d){d3.select(this).classed("hover",!0),s.elementMouseover({series:{key:b.values["whisker_"+a],color:q(b,d)},e:d3.event})}).on("mouseout",function(b,c,d){d3.select(this).classed("hover",!1),s.elementMouseout({series:{key:b.values["whisker_"+a],color:q(b,d)},e:d3.event})}).on("mousemove",function(){s.elementMousemove({e:d3.event})})}),B.append("rect").attr("class","nv-boxplot-box").on("mouseover",function(a,b){d3.select(this).classed("hover",!0),s.elementMouseover({key:a.label,value:a.label,series:[{key:"Q3",value:a.values.Q3,color:a.color||q(a,b)},{key:"Q2",value:a.values.Q2,color:a.color||q(a,b)},{key:"Q1",value:a.values.Q1,color:a.color||q(a,b)}],data:a,index:b,e:d3.event})}).on("mouseout",function(a,b){d3.select(this).classed("hover",!1),s.elementMouseout({key:a.label,value:a.label,series:[{key:"Q3",value:a.values.Q3,color:a.color||q(a,b)},{key:"Q2",value:a.values.Q2,color:a.color||q(a,b)},{key:"Q1",value:a.values.Q1,color:a.color||q(a,b)}],data:a,index:b,e:d3.event})}).on("mousemove",function(){s.elementMousemove({e:d3.event})}),A.select("rect.nv-boxplot-box").watchTransition(v,"nv-boxplot: boxes").attr("y",function(a){return n(a.values.Q3)}).attr("width",D).attr("x",E).attr("height",function(a){return Math.abs(n(a.values.Q3)-n(a.values.Q1))||1}).style("fill",function(a,b){return a.color||q(a,b)}).style("stroke",function(a,b){return a.color||q(a,b)}),B.append("line").attr("class","nv-boxplot-median"),A.select("line.nv-boxplot-median").watchTransition(v,"nv-boxplot: boxplots line").attr("x1",E).attr("y1",function(a){return n(a.values.Q2)}).attr("x2",F).attr("y2",function(a){return n(a.values.Q2)}),g=m.copy(),h=n.copy()}),v.renderEnd("nv-boxplot immediate"),b}var c,d,e,f,g,h,i={top:0,right:0,bottom:0,left:0},j=960,k=500,l=Math.floor(1e4*Math.random()),m=d3.scale.ordinal(),n=d3.scale.linear(),o=function(a){return a.x},p=function(a){return a.y},q=a.utils.defaultColor(),r=null,s=d3.dispatch("elementMouseover","elementMouseout","elementMousemove","renderEnd"),t=250,u=null,v=a.utils.renderWatch(s,t);return b.dispatch=s,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return j},set:function(a){j=a}},height:{get:function(){return k},set:function(a){k=a}},maxBoxWidth:{get:function(){return u},set:function(a){u=a}},x:{get:function(){return o},set:function(a){o=a}},y:{get:function(){return p},set:function(a){p=a}},xScale:{get:function(){return m},set:function(a){m=a}},yScale:{get:function(){return n},set:function(a){n=a}},xDomain:{get:function(){return c},set:function(a){c=a}},yDomain:{get:function(){return d},set:function(a){d=a}},xRange:{get:function(){return e},set:function(a){e=a}},yRange:{get:function(){return f},set:function(a){f=a}},id:{get:function(){return l},set:function(a){l=a}},margin:{get:function(){return i},set:function(a){i.top=void 0!==a.top?a.top:i.top,i.right=void 0!==a.right?a.right:i.right,i.bottom=void 0!==a.bottom?a.bottom:i.bottom,i.left=void 0!==a.left?a.left:i.left}},color:{get:function(){return q},set:function(b){q=a.utils.getColor(b)}},duration:{get:function(){return t},set:function(a){t=a,v.reset(t)}}}),a.utils.initOptions(b),b},a.models.boxPlotChart=function(){"use strict";function b(k){return t.reset(),t.models(e),l&&t.models(f),m&&t.models(g),k.each(function(k){var p=d3.select(this);a.utils.initSVG(p);var t=(i||parseInt(p.style("width"))||960)-h.left-h.right,u=(j||parseInt(p.style("height"))||400)-h.top-h.bottom;if(b.update=function(){r.beforeUpdate(),p.transition().duration(s).call(b)},b.container=this,!(k&&k.length&&k.filter(function(a){return a.values.hasOwnProperty("Q1")&&a.values.hasOwnProperty("Q2")&&a.values.hasOwnProperty("Q3")}).length)){var v=p.selectAll(".nv-noData").data([q]);return v.enter().append("text").attr("class","nvd3 nv-noData").attr("dy","-.7em").style("text-anchor","middle"),v.attr("x",h.left+t/2).attr("y",h.top+u/2).text(function(a){return a}),b}p.selectAll(".nv-noData").remove(),c=e.xScale(),d=e.yScale().clamp(!0);var w=p.selectAll("g.nv-wrap.nv-boxPlotWithAxes").data([k]),x=w.enter().append("g").attr("class","nvd3 nv-wrap nv-boxPlotWithAxes").append("g"),y=x.append("defs"),z=w.select("g"); -x.append("g").attr("class","nv-x nv-axis"),x.append("g").attr("class","nv-y nv-axis").append("g").attr("class","nv-zeroLine").append("line"),x.append("g").attr("class","nv-barsWrap"),z.attr("transform","translate("+h.left+","+h.top+")"),n&&z.select(".nv-y.nv-axis").attr("transform","translate("+t+",0)"),e.width(t).height(u);var A=z.select(".nv-barsWrap").datum(k.filter(function(a){return!a.disabled}));if(A.transition().call(e),y.append("clipPath").attr("id","nv-x-label-clip-"+e.id()).append("rect"),z.select("#nv-x-label-clip-"+e.id()+" rect").attr("width",c.rangeBand()*(o?2:1)).attr("height",16).attr("x",-c.rangeBand()/(o?1:2)),l){f.scale(c).ticks(a.utils.calcTicksX(t/100,k)).tickSize(-u,0),z.select(".nv-x.nv-axis").attr("transform","translate(0,"+d.range()[0]+")"),z.select(".nv-x.nv-axis").call(f);var B=z.select(".nv-x.nv-axis").selectAll("g");o&&B.selectAll("text").attr("transform",function(a,b,c){return"translate(0,"+(c%2==0?"5":"17")+")"})}m&&(g.scale(d).ticks(Math.floor(u/36)).tickSize(-t,0),z.select(".nv-y.nv-axis").call(g)),z.select(".nv-zeroLine line").attr("x1",0).attr("x2",t).attr("y1",d(0)).attr("y2",d(0))}),t.renderEnd("nv-boxplot chart immediate"),b}var c,d,e=a.models.boxPlot(),f=a.models.axis(),g=a.models.axis(),h={top:15,right:10,bottom:50,left:60},i=null,j=null,k=a.utils.getColor(),l=!0,m=!0,n=!1,o=!1,p=a.models.tooltip(),q="No Data Available.",r=d3.dispatch("tooltipShow","tooltipHide","beforeUpdate","renderEnd"),s=250;f.orient("bottom").showMaxMin(!1).tickFormat(function(a){return a}),g.orient(n?"right":"left").tickFormat(d3.format(",.1f")),p.duration(0);var t=a.utils.renderWatch(r,s);return e.dispatch.on("elementMouseover.tooltip",function(a){p.data(a).hidden(!1)}),e.dispatch.on("elementMouseout.tooltip",function(a){p.data(a).hidden(!0)}),e.dispatch.on("elementMousemove.tooltip",function(){p.position({top:d3.event.pageY,left:d3.event.pageX})()}),b.dispatch=r,b.boxplot=e,b.xAxis=f,b.yAxis=g,b.tooltip=p,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return i},set:function(a){i=a}},height:{get:function(){return j},set:function(a){j=a}},staggerLabels:{get:function(){return o},set:function(a){o=a}},showXAxis:{get:function(){return l},set:function(a){l=a}},showYAxis:{get:function(){return m},set:function(a){m=a}},tooltips:{get:function(){return tooltips},set:function(a){tooltips=a}},tooltipContent:{get:function(){return p},set:function(a){p=a}},noData:{get:function(){return q},set:function(a){q=a}},margin:{get:function(){return h},set:function(a){h.top=void 0!==a.top?a.top:h.top,h.right=void 0!==a.right?a.right:h.right,h.bottom=void 0!==a.bottom?a.bottom:h.bottom,h.left=void 0!==a.left?a.left:h.left}},duration:{get:function(){return s},set:function(a){s=a,t.reset(s),e.duration(s),f.duration(s),g.duration(s)}},color:{get:function(){return k},set:function(b){k=a.utils.getColor(b),e.color(k)}},rightAlignYAxis:{get:function(){return n},set:function(a){n=a,g.orient(a?"right":"left")}}}),a.utils.inheritOptions(b,e),a.utils.initOptions(b),b},a.models.bullet=function(){"use strict";function b(d){return d.each(function(b,d){var p=m-c.left-c.right,s=n-c.top-c.bottom;o=d3.select(this),a.utils.initSVG(o);{var t=f.call(this,b,d).slice().sort(d3.descending),u=g.call(this,b,d).slice().sort(d3.descending),v=h.call(this,b,d).slice().sort(d3.descending),w=i.call(this,b,d).slice(),x=j.call(this,b,d).slice(),y=k.call(this,b,d).slice(),z=d3.scale.linear().domain(d3.extent(d3.merge([l,t]))).range(e?[p,0]:[0,p]);this.__chart__||d3.scale.linear().domain([0,1/0]).range(z.range())}this.__chart__=z;var A=d3.min(t),B=d3.max(t),C=t[1],D=o.selectAll("g.nv-wrap.nv-bullet").data([b]),E=D.enter().append("g").attr("class","nvd3 nv-wrap nv-bullet"),F=E.append("g"),G=D.select("g");F.append("rect").attr("class","nv-range nv-rangeMax"),F.append("rect").attr("class","nv-range nv-rangeAvg"),F.append("rect").attr("class","nv-range nv-rangeMin"),F.append("rect").attr("class","nv-measure"),D.attr("transform","translate("+c.left+","+c.top+")");var H=function(a){return Math.abs(z(a)-z(0))},I=function(a){return z(0>a?a:0)};G.select("rect.nv-rangeMax").attr("height",s).attr("width",H(B>0?B:A)).attr("x",I(B>0?B:A)).datum(B>0?B:A),G.select("rect.nv-rangeAvg").attr("height",s).attr("width",H(C)).attr("x",I(C)).datum(C),G.select("rect.nv-rangeMin").attr("height",s).attr("width",H(B)).attr("x",I(B)).attr("width",H(B>0?A:B)).attr("x",I(B>0?A:B)).datum(B>0?A:B),G.select("rect.nv-measure").style("fill",q).attr("height",s/3).attr("y",s/3).attr("width",0>v?z(0)-z(v[0]):z(v[0])-z(0)).attr("x",I(v)).on("mouseover",function(){r.elementMouseover({value:v[0],label:y[0]||"Current",color:d3.select(this).style("fill")})}).on("mousemove",function(){r.elementMousemove({value:v[0],label:y[0]||"Current",color:d3.select(this).style("fill")})}).on("mouseout",function(){r.elementMouseout({value:v[0],label:y[0]||"Current",color:d3.select(this).style("fill")})});var J=s/6,K=u.map(function(a,b){return{value:a,label:x[b]}});F.selectAll("path.nv-markerTriangle").data(K).enter().append("path").attr("class","nv-markerTriangle").attr("transform",function(a){return"translate("+z(a.value)+","+s/2+")"}).attr("d","M0,"+J+"L"+J+","+-J+" "+-J+","+-J+"Z").on("mouseover",function(a){r.elementMouseover({value:a.value,label:a.label||"Previous",color:d3.select(this).style("fill"),pos:[z(a.value),s/2]})}).on("mousemove",function(a){r.elementMousemove({value:a.value,label:a.label||"Previous",color:d3.select(this).style("fill")})}).on("mouseout",function(a){r.elementMouseout({value:a.value,label:a.label||"Previous",color:d3.select(this).style("fill")})}),D.selectAll(".nv-range").on("mouseover",function(a,b){var c=w[b]||(b?1==b?"Mean":"Minimum":"Maximum");r.elementMouseover({value:a,label:c,color:d3.select(this).style("fill")})}).on("mousemove",function(){r.elementMousemove({value:v[0],label:y[0]||"Previous",color:d3.select(this).style("fill")})}).on("mouseout",function(a,b){var c=w[b]||(b?1==b?"Mean":"Minimum":"Maximum");r.elementMouseout({value:a,label:c,color:d3.select(this).style("fill")})})}),b}var c={top:0,right:0,bottom:0,left:0},d="left",e=!1,f=function(a){return a.ranges},g=function(a){return a.markers?a.markers:[0]},h=function(a){return a.measures},i=function(a){return a.rangeLabels?a.rangeLabels:[]},j=function(a){return a.markerLabels?a.markerLabels:[]},k=function(a){return a.measureLabels?a.measureLabels:[]},l=[0],m=380,n=30,o=null,p=null,q=a.utils.getColor(["#1f77b4"]),r=d3.dispatch("elementMouseover","elementMouseout","elementMousemove");return b.dispatch=r,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{ranges:{get:function(){return f},set:function(a){f=a}},markers:{get:function(){return g},set:function(a){g=a}},measures:{get:function(){return h},set:function(a){h=a}},forceX:{get:function(){return l},set:function(a){l=a}},width:{get:function(){return m},set:function(a){m=a}},height:{get:function(){return n},set:function(a){n=a}},tickFormat:{get:function(){return p},set:function(a){p=a}},margin:{get:function(){return c},set:function(a){c.top=void 0!==a.top?a.top:c.top,c.right=void 0!==a.right?a.right:c.right,c.bottom=void 0!==a.bottom?a.bottom:c.bottom,c.left=void 0!==a.left?a.left:c.left}},orient:{get:function(){return d},set:function(a){d=a,e="right"==d||"bottom"==d}},color:{get:function(){return q},set:function(b){q=a.utils.getColor(b)}}}),a.utils.initOptions(b),b},a.models.bulletChart=function(){"use strict";function b(d){return d.each(function(e,o){var p=d3.select(this);a.utils.initSVG(p);var q=a.utils.availableWidth(k,p,g),r=l-g.top-g.bottom;if(b.update=function(){b(d)},b.container=this,!e||!h.call(this,e,o))return a.utils.noData(b,p),b;p.selectAll(".nv-noData").remove();var s=h.call(this,e,o).slice().sort(d3.descending),t=i.call(this,e,o).slice().sort(d3.descending),u=j.call(this,e,o).slice().sort(d3.descending),v=p.selectAll("g.nv-wrap.nv-bulletChart").data([e]),w=v.enter().append("g").attr("class","nvd3 nv-wrap nv-bulletChart"),x=w.append("g"),y=v.select("g");x.append("g").attr("class","nv-bulletWrap"),x.append("g").attr("class","nv-titles"),v.attr("transform","translate("+g.left+","+g.top+")");var z=d3.scale.linear().domain([0,Math.max(s[0],t[0],u[0])]).range(f?[q,0]:[0,q]),A=this.__chart__||d3.scale.linear().domain([0,1/0]).range(z.range());this.__chart__=z;var B=x.select(".nv-titles").append("g").attr("text-anchor","end").attr("transform","translate(-6,"+(l-g.top-g.bottom)/2+")");B.append("text").attr("class","nv-title").text(function(a){return a.title}),B.append("text").attr("class","nv-subtitle").attr("dy","1em").text(function(a){return a.subtitle}),c.width(q).height(r);var C=y.select(".nv-bulletWrap");d3.transition(C).call(c);var D=m||z.tickFormat(q/100),E=y.selectAll("g.nv-tick").data(z.ticks(n?n:q/50),function(a){return this.textContent||D(a)}),F=E.enter().append("g").attr("class","nv-tick").attr("transform",function(a){return"translate("+A(a)+",0)"}).style("opacity",1e-6);F.append("line").attr("y1",r).attr("y2",7*r/6),F.append("text").attr("text-anchor","middle").attr("dy","1em").attr("y",7*r/6).text(D);var G=d3.transition(E).attr("transform",function(a){return"translate("+z(a)+",0)"}).style("opacity",1);G.select("line").attr("y1",r).attr("y2",7*r/6),G.select("text").attr("y",7*r/6),d3.transition(E.exit()).attr("transform",function(a){return"translate("+z(a)+",0)"}).style("opacity",1e-6).remove()}),d3.timer.flush(),b}var c=a.models.bullet(),d=a.models.tooltip(),e="left",f=!1,g={top:5,right:40,bottom:20,left:120},h=function(a){return a.ranges},i=function(a){return a.markers?a.markers:[0]},j=function(a){return a.measures},k=null,l=55,m=null,n=null,o=null,p=d3.dispatch("tooltipShow","tooltipHide");return d.duration(0).headerEnabled(!1),c.dispatch.on("elementMouseover.tooltip",function(a){a.series={key:a.label,value:a.value,color:a.color},d.data(a).hidden(!1)}),c.dispatch.on("elementMouseout.tooltip",function(){d.hidden(!0)}),c.dispatch.on("elementMousemove.tooltip",function(){d.position({top:d3.event.pageY,left:d3.event.pageX})()}),b.bullet=c,b.dispatch=p,b.tooltip=d,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{ranges:{get:function(){return h},set:function(a){h=a}},markers:{get:function(){return i},set:function(a){i=a}},measures:{get:function(){return j},set:function(a){j=a}},width:{get:function(){return k},set:function(a){k=a}},height:{get:function(){return l},set:function(a){l=a}},tickFormat:{get:function(){return m},set:function(a){m=a}},ticks:{get:function(){return n},set:function(a){n=a}},noData:{get:function(){return o},set:function(a){o=a}},tooltips:{get:function(){return d.enabled()},set:function(b){a.deprecated("tooltips","use chart.tooltip.enabled() instead"),d.enabled(!!b)}},tooltipContent:{get:function(){return d.contentGenerator()},set:function(b){a.deprecated("tooltipContent","use chart.tooltip.contentGenerator() instead"),d.contentGenerator(b)}},margin:{get:function(){return g},set:function(a){g.top=void 0!==a.top?a.top:g.top,g.right=void 0!==a.right?a.right:g.right,g.bottom=void 0!==a.bottom?a.bottom:g.bottom,g.left=void 0!==a.left?a.left:g.left}},orient:{get:function(){return e},set:function(a){e=a,f="right"==e||"bottom"==e}}}),a.utils.inheritOptions(b,c),a.utils.initOptions(b),b},a.models.candlestickBar=function(){"use strict";function b(x){return x.each(function(b){c=d3.select(this);var x=a.utils.availableWidth(i,c,h),y=a.utils.availableHeight(j,c,h);a.utils.initSVG(c);var A=x/b[0].values.length*.45;l.domain(d||d3.extent(b[0].values.map(n).concat(t))),l.range(v?f||[.5*x/b[0].values.length,x*(b[0].values.length-.5)/b[0].values.length]:f||[5+A/2,x-A/2-5]),m.domain(e||[d3.min(b[0].values.map(s).concat(u)),d3.max(b[0].values.map(r).concat(u))]).range(g||[y,0]),l.domain()[0]===l.domain()[1]&&l.domain(l.domain()[0]?[l.domain()[0]-.01*l.domain()[0],l.domain()[1]+.01*l.domain()[1]]:[-1,1]),m.domain()[0]===m.domain()[1]&&m.domain(m.domain()[0]?[m.domain()[0]+.01*m.domain()[0],m.domain()[1]-.01*m.domain()[1]]:[-1,1]);var B=d3.select(this).selectAll("g.nv-wrap.nv-candlestickBar").data([b[0].values]),C=B.enter().append("g").attr("class","nvd3 nv-wrap nv-candlestickBar"),D=C.append("defs"),E=C.append("g"),F=B.select("g");E.append("g").attr("class","nv-ticks"),B.attr("transform","translate("+h.left+","+h.top+")"),c.on("click",function(a,b){z.chartClick({data:a,index:b,pos:d3.event,id:k})}),D.append("clipPath").attr("id","nv-chart-clip-path-"+k).append("rect"),B.select("#nv-chart-clip-path-"+k+" rect").attr("width",x).attr("height",y),F.attr("clip-path",w?"url(#nv-chart-clip-path-"+k+")":"");var G=B.select(".nv-ticks").selectAll(".nv-tick").data(function(a){return a});G.exit().remove();{var H=G.enter().append("g").attr("class",function(a,b,c){return(p(a,b)>q(a,b)?"nv-tick negative":"nv-tick positive")+" nv-tick-"+c+"-"+b});H.append("line").attr("class","nv-candlestick-lines").attr("transform",function(a,b){return"translate("+l(n(a,b))+",0)"}).attr("x1",0).attr("y1",function(a,b){return m(r(a,b))}).attr("x2",0).attr("y2",function(a,b){return m(s(a,b))}),H.append("rect").attr("class","nv-candlestick-rects nv-bars").attr("transform",function(a,b){return"translate("+(l(n(a,b))-A/2)+","+(m(o(a,b))-(p(a,b)>q(a,b)?m(q(a,b))-m(p(a,b)):0))+")"}).attr("x",0).attr("y",0).attr("width",A).attr("height",function(a,b){var c=p(a,b),d=q(a,b);return c>d?m(d)-m(c):m(c)-m(d)})}c.selectAll(".nv-candlestick-lines").transition().attr("transform",function(a,b){return"translate("+l(n(a,b))+",0)"}).attr("x1",0).attr("y1",function(a,b){return m(r(a,b))}).attr("x2",0).attr("y2",function(a,b){return m(s(a,b))}),c.selectAll(".nv-candlestick-rects").transition().attr("transform",function(a,b){return"translate("+(l(n(a,b))-A/2)+","+(m(o(a,b))-(p(a,b)>q(a,b)?m(q(a,b))-m(p(a,b)):0))+")"}).attr("x",0).attr("y",0).attr("width",A).attr("height",function(a,b){var c=p(a,b),d=q(a,b);return c>d?m(d)-m(c):m(c)-m(d)})}),b}var c,d,e,f,g,h={top:0,right:0,bottom:0,left:0},i=null,j=null,k=Math.floor(1e4*Math.random()),l=d3.scale.linear(),m=d3.scale.linear(),n=function(a){return a.x},o=function(a){return a.y},p=function(a){return a.open},q=function(a){return a.close},r=function(a){return a.high},s=function(a){return a.low},t=[],u=[],v=!1,w=!0,x=a.utils.defaultColor(),y=!1,z=d3.dispatch("tooltipShow","tooltipHide","stateChange","changeState","renderEnd","chartClick","elementClick","elementDblClick","elementMouseover","elementMouseout","elementMousemove");return b.highlightPoint=function(a,d){b.clearHighlights(),c.select(".nv-candlestickBar .nv-tick-0-"+a).classed("hover",d)},b.clearHighlights=function(){c.select(".nv-candlestickBar .nv-tick.hover").classed("hover",!1)},b.dispatch=z,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return i},set:function(a){i=a}},height:{get:function(){return j},set:function(a){j=a}},xScale:{get:function(){return l},set:function(a){l=a}},yScale:{get:function(){return m},set:function(a){m=a}},xDomain:{get:function(){return d},set:function(a){d=a}},yDomain:{get:function(){return e},set:function(a){e=a}},xRange:{get:function(){return f},set:function(a){f=a}},yRange:{get:function(){return g},set:function(a){g=a}},forceX:{get:function(){return t},set:function(a){t=a}},forceY:{get:function(){return u},set:function(a){u=a}},padData:{get:function(){return v},set:function(a){v=a}},clipEdge:{get:function(){return w},set:function(a){w=a}},id:{get:function(){return k},set:function(a){k=a}},interactive:{get:function(){return y},set:function(a){y=a}},x:{get:function(){return n},set:function(a){n=a}},y:{get:function(){return o},set:function(a){o=a}},open:{get:function(){return p()},set:function(a){p=a}},close:{get:function(){return q()},set:function(a){q=a}},high:{get:function(){return r},set:function(a){r=a}},low:{get:function(){return s},set:function(a){s=a}},margin:{get:function(){return h},set:function(a){h.top=void 0!=a.top?a.top:h.top,h.right=void 0!=a.right?a.right:h.right,h.bottom=void 0!=a.bottom?a.bottom:h.bottom,h.left=void 0!=a.left?a.left:h.left}},color:{get:function(){return x},set:function(b){x=a.utils.getColor(b)}}}),a.utils.initOptions(b),b},a.models.cumulativeLineChart=function(){"use strict";function b(l){return H.reset(),H.models(f),r&&H.models(g),s&&H.models(h),l.each(function(l){function A(){d3.select(b.container).style("cursor","ew-resize")}function E(){G.x=d3.event.x,G.i=Math.round(F.invert(G.x)),K()}function H(){d3.select(b.container).style("cursor","auto"),y.index=G.i,C.stateChange(y)}function K(){bb.data([G]);var a=b.duration();b.duration(0),b.update(),b.duration(a)}var L=d3.select(this);a.utils.initSVG(L),L.classed("nv-chart-"+x,!0);var M=this,N=a.utils.availableWidth(o,L,m),O=a.utils.availableHeight(p,L,m);if(b.update=function(){0===D?L.call(b):L.transition().duration(D).call(b)},b.container=this,y.setter(J(l),b.update).getter(I(l)).update(),y.disabled=l.map(function(a){return!!a.disabled}),!z){var P;z={};for(P in y)z[P]=y[P]instanceof Array?y[P].slice(0):y[P]}var Q=d3.behavior.drag().on("dragstart",A).on("drag",E).on("dragend",H);if(!(l&&l.length&&l.filter(function(a){return a.values.length}).length))return a.utils.noData(b,L),b;if(L.selectAll(".nv-noData").remove(),d=f.xScale(),e=f.yScale(),w)f.yDomain(null);else{var R=l.filter(function(a){return!a.disabled}).map(function(a){var b=d3.extent(a.values,f.y());return b[0]<-.95&&(b[0]=-.95),[(b[0]-b[1])/(1+b[1]),(b[1]-b[0])/(1+b[0])]}),S=[d3.min(R,function(a){return a[0]}),d3.max(R,function(a){return a[1]})];f.yDomain(S)}F.domain([0,l[0].values.length-1]).range([0,N]).clamp(!0);var l=c(G.i,l),T=v?"none":"all",U=L.selectAll("g.nv-wrap.nv-cumulativeLine").data([l]),V=U.enter().append("g").attr("class","nvd3 nv-wrap nv-cumulativeLine").append("g"),W=U.select("g");if(V.append("g").attr("class","nv-interactive"),V.append("g").attr("class","nv-x nv-axis").style("pointer-events","none"),V.append("g").attr("class","nv-y nv-axis"),V.append("g").attr("class","nv-background"),V.append("g").attr("class","nv-linesWrap").style("pointer-events",T),V.append("g").attr("class","nv-avgLinesWrap").style("pointer-events","none"),V.append("g").attr("class","nv-legendWrap"),V.append("g").attr("class","nv-controlsWrap"),q&&(i.width(N),W.select(".nv-legendWrap").datum(l).call(i),m.top!=i.height()&&(m.top=i.height(),O=a.utils.availableHeight(p,L,m)),W.select(".nv-legendWrap").attr("transform","translate(0,"+-m.top+")")),u){var X=[{key:"Re-scale y-axis",disabled:!w}];j.width(140).color(["#444","#444","#444"]).rightAlign(!1).margin({top:5,right:0,bottom:5,left:20}),W.select(".nv-controlsWrap").datum(X).attr("transform","translate(0,"+-m.top+")").call(j)}U.attr("transform","translate("+m.left+","+m.top+")"),t&&W.select(".nv-y.nv-axis").attr("transform","translate("+N+",0)");var Y=l.filter(function(a){return a.tempDisabled});U.select(".tempDisabled").remove(),Y.length&&U.append("text").attr("class","tempDisabled").attr("x",N/2).attr("y","-.71em").style("text-anchor","end").text(Y.map(function(a){return a.key}).join(", ")+" values cannot be calculated for this time period."),v&&(k.width(N).height(O).margin({left:m.left,top:m.top}).svgContainer(L).xScale(d),U.select(".nv-interactive").call(k)),V.select(".nv-background").append("rect"),W.select(".nv-background rect").attr("width",N).attr("height",O),f.y(function(a){return a.display.y}).width(N).height(O).color(l.map(function(a,b){return a.color||n(a,b)}).filter(function(a,b){return!l[b].disabled&&!l[b].tempDisabled}));var Z=W.select(".nv-linesWrap").datum(l.filter(function(a){return!a.disabled&&!a.tempDisabled}));Z.call(f),l.forEach(function(a,b){a.seriesIndex=b});var $=l.filter(function(a){return!a.disabled&&!!B(a)}),_=W.select(".nv-avgLinesWrap").selectAll("line").data($,function(a){return a.key}),ab=function(a){var b=e(B(a));return 0>b?0:b>O?O:b};_.enter().append("line").style("stroke-width",2).style("stroke-dasharray","10,10").style("stroke",function(a){return f.color()(a,a.seriesIndex)}).attr("x1",0).attr("x2",N).attr("y1",ab).attr("y2",ab),_.style("stroke-opacity",function(a){var b=e(B(a));return 0>b||b>O?0:1}).attr("x1",0).attr("x2",N).attr("y1",ab).attr("y2",ab),_.exit().remove();var bb=Z.selectAll(".nv-indexLine").data([G]);bb.enter().append("rect").attr("class","nv-indexLine").attr("width",3).attr("x",-2).attr("fill","red").attr("fill-opacity",.5).style("pointer-events","all").call(Q),bb.attr("transform",function(a){return"translate("+F(a.i)+",0)"}).attr("height",O),r&&(g.scale(d)._ticks(a.utils.calcTicksX(N/70,l)).tickSize(-O,0),W.select(".nv-x.nv-axis").attr("transform","translate(0,"+e.range()[0]+")"),W.select(".nv-x.nv-axis").call(g)),s&&(h.scale(e)._ticks(a.utils.calcTicksY(O/36,l)).tickSize(-N,0),W.select(".nv-y.nv-axis").call(h)),W.select(".nv-background rect").on("click",function(){G.x=d3.mouse(this)[0],G.i=Math.round(F.invert(G.x)),y.index=G.i,C.stateChange(y),K()}),f.dispatch.on("elementClick",function(a){G.i=a.pointIndex,G.x=F(G.i),y.index=G.i,C.stateChange(y),K()}),j.dispatch.on("legendClick",function(a){a.disabled=!a.disabled,w=!a.disabled,y.rescaleY=w,C.stateChange(y),b.update()}),i.dispatch.on("stateChange",function(a){for(var c in a)y[c]=a[c];C.stateChange(y),b.update()}),k.dispatch.on("elementMousemove",function(c){f.clearHighlights();var d,e,i,j=[];if(l.filter(function(a,b){return a.seriesIndex=b,!a.disabled}).forEach(function(g,h){e=a.interactiveBisect(g.values,c.pointXValue,b.x()),f.highlightPoint(h,e,!0);var k=g.values[e];"undefined"!=typeof k&&("undefined"==typeof d&&(d=k),"undefined"==typeof i&&(i=b.xScale()(b.x()(k,e))),j.push({key:g.key,value:b.y()(k,e),color:n(g,g.seriesIndex)}))}),j.length>2){var o=b.yScale().invert(c.mouseY),p=Math.abs(b.yScale().domain()[0]-b.yScale().domain()[1]),q=.03*p,r=a.nearestValueIndex(j.map(function(a){return a.value}),o,q);null!==r&&(j[r].highlight=!0)}var s=g.tickFormat()(b.x()(d,e),e);k.tooltip.position({left:i+m.left,top:c.mouseY+m.top}).chartContainer(M.parentNode).valueFormatter(function(a){return h.tickFormat()(a)}).data({value:s,series:j})(),k.renderGuideLine(i)}),k.dispatch.on("elementMouseout",function(){f.clearHighlights()}),C.on("changeState",function(a){"undefined"!=typeof a.disabled&&(l.forEach(function(b,c){b.disabled=a.disabled[c]}),y.disabled=a.disabled),"undefined"!=typeof a.index&&(G.i=a.index,G.x=F(G.i),y.index=a.index,bb.data([G])),"undefined"!=typeof a.rescaleY&&(w=a.rescaleY),b.update()})}),H.renderEnd("cumulativeLineChart immediate"),b}function c(a,b){return K||(K=f.y()),b.map(function(b){if(!b.values)return b;var c=b.values[a];if(null==c)return b;var d=K(c,a);return-.95>d&&!E?(b.tempDisabled=!0,b):(b.tempDisabled=!1,b.values=b.values.map(function(a,b){return a.display={y:(K(a,b)-d)/(1+d)},a}),b)})}var d,e,f=a.models.line(),g=a.models.axis(),h=a.models.axis(),i=a.models.legend(),j=a.models.legend(),k=a.interactiveGuideline(),l=a.models.tooltip(),m={top:30,right:30,bottom:50,left:60},n=a.utils.defaultColor(),o=null,p=null,q=!0,r=!0,s=!0,t=!1,u=!0,v=!1,w=!0,x=f.id(),y=a.utils.state(),z=null,A=null,B=function(a){return a.average},C=d3.dispatch("stateChange","changeState","renderEnd"),D=250,E=!1;y.index=0,y.rescaleY=w,g.orient("bottom").tickPadding(7),h.orient(t?"right":"left"),l.valueFormatter(function(a,b){return h.tickFormat()(a,b)}).headerFormatter(function(a,b){return g.tickFormat()(a,b)}),j.updateState(!1);var F=d3.scale.linear(),G={i:0,x:0},H=a.utils.renderWatch(C,D),I=function(a){return function(){return{active:a.map(function(a){return!a.disabled}),index:G.i,rescaleY:w}}},J=function(a){return function(b){void 0!==b.index&&(G.i=b.index),void 0!==b.rescaleY&&(w=b.rescaleY),void 0!==b.active&&a.forEach(function(a,c){a.disabled=!b.active[c]})}};f.dispatch.on("elementMouseover.tooltip",function(a){var c={x:b.x()(a.point),y:b.y()(a.point),color:a.point.color};a.point=c,l.data(a).position(a.pos).hidden(!1)}),f.dispatch.on("elementMouseout.tooltip",function(){l.hidden(!0)});var K=null;return b.dispatch=C,b.lines=f,b.legend=i,b.controls=j,b.xAxis=g,b.yAxis=h,b.interactiveLayer=k,b.state=y,b.tooltip=l,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return o},set:function(a){o=a}},height:{get:function(){return p},set:function(a){p=a}},rescaleY:{get:function(){return w},set:function(a){w=a}},showControls:{get:function(){return u},set:function(a){u=a}},showLegend:{get:function(){return q},set:function(a){q=a}},average:{get:function(){return B},set:function(a){B=a}},defaultState:{get:function(){return z},set:function(a){z=a}},noData:{get:function(){return A},set:function(a){A=a}},showXAxis:{get:function(){return r},set:function(a){r=a}},showYAxis:{get:function(){return s},set:function(a){s=a}},noErrorCheck:{get:function(){return E},set:function(a){E=a}},tooltips:{get:function(){return l.enabled()},set:function(b){a.deprecated("tooltips","use chart.tooltip.enabled() instead"),l.enabled(!!b)}},tooltipContent:{get:function(){return l.contentGenerator()},set:function(b){a.deprecated("tooltipContent","use chart.tooltip.contentGenerator() instead"),l.contentGenerator(b)}},margin:{get:function(){return m},set:function(a){m.top=void 0!==a.top?a.top:m.top,m.right=void 0!==a.right?a.right:m.right,m.bottom=void 0!==a.bottom?a.bottom:m.bottom,m.left=void 0!==a.left?a.left:m.left}},color:{get:function(){return n},set:function(b){n=a.utils.getColor(b),i.color(n)}},useInteractiveGuideline:{get:function(){return v},set:function(a){v=a,a===!0&&(b.interactive(!1),b.useVoronoi(!1))}},rightAlignYAxis:{get:function(){return t},set:function(a){t=a,h.orient(a?"right":"left")}},duration:{get:function(){return D},set:function(a){D=a,f.duration(D),g.duration(D),h.duration(D),H.reset(D)}}}),a.utils.inheritOptions(b,f),a.utils.initOptions(b),b},a.models.discreteBar=function(){"use strict";function b(m){return y.reset(),m.each(function(b){var m=k-j.left-j.right,x=l-j.top-j.bottom;c=d3.select(this),a.utils.initSVG(c),b.forEach(function(a,b){a.values.forEach(function(a){a.series=b})});var z=d&&e?[]:b.map(function(a){return a.values.map(function(a,b){return{x:p(a,b),y:q(a,b),y0:a.y0}})});n.domain(d||d3.merge(z).map(function(a){return a.x})).rangeBands(f||[0,m],.1),o.domain(e||d3.extent(d3.merge(z).map(function(a){return a.y}).concat(r))),o.range(t?g||[x-(o.domain()[0]<0?12:0),o.domain()[1]>0?12:0]:g||[x,0]),h=h||n,i=i||o.copy().range([o(0),o(0)]);{var A=c.selectAll("g.nv-wrap.nv-discretebar").data([b]),B=A.enter().append("g").attr("class","nvd3 nv-wrap nv-discretebar"),C=B.append("g");A.select("g")}C.append("g").attr("class","nv-groups"),A.attr("transform","translate("+j.left+","+j.top+")");var D=A.select(".nv-groups").selectAll(".nv-group").data(function(a){return a},function(a){return a.key});D.enter().append("g").style("stroke-opacity",1e-6).style("fill-opacity",1e-6),D.exit().watchTransition(y,"discreteBar: exit groups").style("stroke-opacity",1e-6).style("fill-opacity",1e-6).remove(),D.attr("class",function(a,b){return"nv-group nv-series-"+b}).classed("hover",function(a){return a.hover}),D.watchTransition(y,"discreteBar: groups").style("stroke-opacity",1).style("fill-opacity",.75);var E=D.selectAll("g.nv-bar").data(function(a){return a.values});E.exit().remove();var F=E.enter().append("g").attr("transform",function(a,b){return"translate("+(n(p(a,b))+.05*n.rangeBand())+", "+o(0)+")"}).on("mouseover",function(a,b){d3.select(this).classed("hover",!0),v.elementMouseover({data:a,index:b,color:d3.select(this).style("fill")})}).on("mouseout",function(a,b){d3.select(this).classed("hover",!1),v.elementMouseout({data:a,index:b,color:d3.select(this).style("fill")})}).on("mousemove",function(a,b){v.elementMousemove({data:a,index:b,color:d3.select(this).style("fill")})}).on("click",function(a,b){v.elementClick({data:a,index:b,color:d3.select(this).style("fill")}),d3.event.stopPropagation()}).on("dblclick",function(a,b){v.elementDblClick({data:a,index:b,color:d3.select(this).style("fill")}),d3.event.stopPropagation()});F.append("rect").attr("height",0).attr("width",.9*n.rangeBand()/b.length),t?(F.append("text").attr("text-anchor","middle"),E.select("text").text(function(a,b){return u(q(a,b))}).watchTransition(y,"discreteBar: bars text").attr("x",.9*n.rangeBand()/2).attr("y",function(a,b){return q(a,b)<0?o(q(a,b))-o(0)+12:-4})):E.selectAll("text").remove(),E.attr("class",function(a,b){return q(a,b)<0?"nv-bar negative":"nv-bar positive"}).style("fill",function(a,b){return a.color||s(a,b)}).style("stroke",function(a,b){return a.color||s(a,b)}).select("rect").attr("class",w).watchTransition(y,"discreteBar: bars rect").attr("width",.9*n.rangeBand()/b.length),E.watchTransition(y,"discreteBar: bars").attr("transform",function(a,b){var c=n(p(a,b))+.05*n.rangeBand(),d=q(a,b)<0?o(0):o(0)-o(q(a,b))<1?o(0)-1:o(q(a,b));return"translate("+c+", "+d+")"}).select("rect").attr("height",function(a,b){return Math.max(Math.abs(o(q(a,b))-o(e&&e[0]||0))||1)}),h=n.copy(),i=o.copy()}),y.renderEnd("discreteBar immediate"),b}var c,d,e,f,g,h,i,j={top:0,right:0,bottom:0,left:0},k=960,l=500,m=Math.floor(1e4*Math.random()),n=d3.scale.ordinal(),o=d3.scale.linear(),p=function(a){return a.x},q=function(a){return a.y},r=[0],s=a.utils.defaultColor(),t=!1,u=d3.format(",.2f"),v=d3.dispatch("chartClick","elementClick","elementDblClick","elementMouseover","elementMouseout","elementMousemove","renderEnd"),w="discreteBar",x=250,y=a.utils.renderWatch(v,x);return b.dispatch=v,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return k},set:function(a){k=a}},height:{get:function(){return l},set:function(a){l=a}},forceY:{get:function(){return r},set:function(a){r=a}},showValues:{get:function(){return t},set:function(a){t=a}},x:{get:function(){return p},set:function(a){p=a}},y:{get:function(){return q},set:function(a){q=a}},xScale:{get:function(){return n},set:function(a){n=a}},yScale:{get:function(){return o},set:function(a){o=a}},xDomain:{get:function(){return d},set:function(a){d=a}},yDomain:{get:function(){return e},set:function(a){e=a}},xRange:{get:function(){return f},set:function(a){f=a}},yRange:{get:function(){return g},set:function(a){g=a}},valueFormat:{get:function(){return u},set:function(a){u=a}},id:{get:function(){return m},set:function(a){m=a}},rectClass:{get:function(){return w},set:function(a){w=a}},margin:{get:function(){return j},set:function(a){j.top=void 0!==a.top?a.top:j.top,j.right=void 0!==a.right?a.right:j.right,j.bottom=void 0!==a.bottom?a.bottom:j.bottom,j.left=void 0!==a.left?a.left:j.left}},color:{get:function(){return s},set:function(b){s=a.utils.getColor(b)}},duration:{get:function(){return x},set:function(a){x=a,y.reset(x)}}}),a.utils.initOptions(b),b},a.models.discreteBarChart=function(){"use strict";function b(h){return t.reset(),t.models(e),m&&t.models(f),n&&t.models(g),h.each(function(h){var l=d3.select(this);a.utils.initSVG(l);var q=a.utils.availableWidth(j,l,i),t=a.utils.availableHeight(k,l,i);if(b.update=function(){r.beforeUpdate(),l.transition().duration(s).call(b)},b.container=this,!(h&&h.length&&h.filter(function(a){return a.values.length}).length))return a.utils.noData(b,l),b;l.selectAll(".nv-noData").remove(),c=e.xScale(),d=e.yScale().clamp(!0);var u=l.selectAll("g.nv-wrap.nv-discreteBarWithAxes").data([h]),v=u.enter().append("g").attr("class","nvd3 nv-wrap nv-discreteBarWithAxes").append("g"),w=v.append("defs"),x=u.select("g");v.append("g").attr("class","nv-x nv-axis"),v.append("g").attr("class","nv-y nv-axis").append("g").attr("class","nv-zeroLine").append("line"),v.append("g").attr("class","nv-barsWrap"),x.attr("transform","translate("+i.left+","+i.top+")"),o&&x.select(".nv-y.nv-axis").attr("transform","translate("+q+",0)"),e.width(q).height(t);var y=x.select(".nv-barsWrap").datum(h.filter(function(a){return!a.disabled}));if(y.transition().call(e),w.append("clipPath").attr("id","nv-x-label-clip-"+e.id()).append("rect"),x.select("#nv-x-label-clip-"+e.id()+" rect").attr("width",c.rangeBand()*(p?2:1)).attr("height",16).attr("x",-c.rangeBand()/(p?1:2)),m){f.scale(c)._ticks(a.utils.calcTicksX(q/100,h)).tickSize(-t,0),x.select(".nv-x.nv-axis").attr("transform","translate(0,"+(d.range()[0]+(e.showValues()&&d.domain()[0]<0?16:0))+")"),x.select(".nv-x.nv-axis").call(f); -var z=x.select(".nv-x.nv-axis").selectAll("g");p&&z.selectAll("text").attr("transform",function(a,b,c){return"translate(0,"+(c%2==0?"5":"17")+")"})}n&&(g.scale(d)._ticks(a.utils.calcTicksY(t/36,h)).tickSize(-q,0),x.select(".nv-y.nv-axis").call(g)),x.select(".nv-zeroLine line").attr("x1",0).attr("x2",q).attr("y1",d(0)).attr("y2",d(0))}),t.renderEnd("discreteBar chart immediate"),b}var c,d,e=a.models.discreteBar(),f=a.models.axis(),g=a.models.axis(),h=a.models.tooltip(),i={top:15,right:10,bottom:50,left:60},j=null,k=null,l=a.utils.getColor(),m=!0,n=!0,o=!1,p=!1,q=null,r=d3.dispatch("beforeUpdate","renderEnd"),s=250;f.orient("bottom").showMaxMin(!1).tickFormat(function(a){return a}),g.orient(o?"right":"left").tickFormat(d3.format(",.1f")),h.duration(0).headerEnabled(!1).valueFormatter(function(a,b){return g.tickFormat()(a,b)}).keyFormatter(function(a,b){return f.tickFormat()(a,b)});var t=a.utils.renderWatch(r,s);return e.dispatch.on("elementMouseover.tooltip",function(a){a.series={key:b.x()(a.data),value:b.y()(a.data),color:a.color},h.data(a).hidden(!1)}),e.dispatch.on("elementMouseout.tooltip",function(){h.hidden(!0)}),e.dispatch.on("elementMousemove.tooltip",function(){h.position({top:d3.event.pageY,left:d3.event.pageX})()}),b.dispatch=r,b.discretebar=e,b.xAxis=f,b.yAxis=g,b.tooltip=h,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return j},set:function(a){j=a}},height:{get:function(){return k},set:function(a){k=a}},staggerLabels:{get:function(){return p},set:function(a){p=a}},showXAxis:{get:function(){return m},set:function(a){m=a}},showYAxis:{get:function(){return n},set:function(a){n=a}},noData:{get:function(){return q},set:function(a){q=a}},tooltips:{get:function(){return h.enabled()},set:function(b){a.deprecated("tooltips","use chart.tooltip.enabled() instead"),h.enabled(!!b)}},tooltipContent:{get:function(){return h.contentGenerator()},set:function(b){a.deprecated("tooltipContent","use chart.tooltip.contentGenerator() instead"),h.contentGenerator(b)}},margin:{get:function(){return i},set:function(a){i.top=void 0!==a.top?a.top:i.top,i.right=void 0!==a.right?a.right:i.right,i.bottom=void 0!==a.bottom?a.bottom:i.bottom,i.left=void 0!==a.left?a.left:i.left}},duration:{get:function(){return s},set:function(a){s=a,t.reset(s),e.duration(s),f.duration(s),g.duration(s)}},color:{get:function(){return l},set:function(b){l=a.utils.getColor(b),e.color(l)}},rightAlignYAxis:{get:function(){return o},set:function(a){o=a,g.orient(a?"right":"left")}}}),a.utils.inheritOptions(b,e),a.utils.initOptions(b),b},a.models.distribution=function(){"use strict";function b(k){return m.reset(),k.each(function(b){var k=(e-("x"===g?d.left+d.right:d.top+d.bottom),"x"==g?"y":"x"),l=d3.select(this);a.utils.initSVG(l),c=c||j;var n=l.selectAll("g.nv-distribution").data([b]),o=n.enter().append("g").attr("class","nvd3 nv-distribution"),p=(o.append("g"),n.select("g"));n.attr("transform","translate("+d.left+","+d.top+")");var q=p.selectAll("g.nv-dist").data(function(a){return a},function(a){return a.key});q.enter().append("g"),q.attr("class",function(a,b){return"nv-dist nv-series-"+b}).style("stroke",function(a,b){return i(a,b)});var r=q.selectAll("line.nv-dist"+g).data(function(a){return a.values});r.enter().append("line").attr(g+"1",function(a,b){return c(h(a,b))}).attr(g+"2",function(a,b){return c(h(a,b))}),m.transition(q.exit().selectAll("line.nv-dist"+g),"dist exit").attr(g+"1",function(a,b){return j(h(a,b))}).attr(g+"2",function(a,b){return j(h(a,b))}).style("stroke-opacity",0).remove(),r.attr("class",function(a,b){return"nv-dist"+g+" nv-dist"+g+"-"+b}).attr(k+"1",0).attr(k+"2",f),m.transition(r,"dist").attr(g+"1",function(a,b){return j(h(a,b))}).attr(g+"2",function(a,b){return j(h(a,b))}),c=j.copy()}),m.renderEnd("distribution immediate"),b}var c,d={top:0,right:0,bottom:0,left:0},e=400,f=8,g="x",h=function(a){return a[g]},i=a.utils.defaultColor(),j=d3.scale.linear(),k=250,l=d3.dispatch("renderEnd"),m=a.utils.renderWatch(l,k);return b.options=a.utils.optionsFunc.bind(b),b.dispatch=l,b.margin=function(a){return arguments.length?(d.top="undefined"!=typeof a.top?a.top:d.top,d.right="undefined"!=typeof a.right?a.right:d.right,d.bottom="undefined"!=typeof a.bottom?a.bottom:d.bottom,d.left="undefined"!=typeof a.left?a.left:d.left,b):d},b.width=function(a){return arguments.length?(e=a,b):e},b.axis=function(a){return arguments.length?(g=a,b):g},b.size=function(a){return arguments.length?(f=a,b):f},b.getData=function(a){return arguments.length?(h=d3.functor(a),b):h},b.scale=function(a){return arguments.length?(j=a,b):j},b.color=function(c){return arguments.length?(i=a.utils.getColor(c),b):i},b.duration=function(a){return arguments.length?(k=a,m.reset(k),b):k},b},a.models.furiousLegend=function(){"use strict";function b(p){function q(a,b){return"furious"!=o?"#000":m?a.disengaged?g(a,b):"#fff":m?void 0:a.disabled?g(a,b):"#fff"}function r(a,b){return m&&"furious"==o?a.disengaged?"#fff":g(a,b):a.disabled?"#fff":g(a,b)}return p.each(function(b){var p=d-c.left-c.right,s=d3.select(this);a.utils.initSVG(s);var t=s.selectAll("g.nv-legend").data([b]),u=(t.enter().append("g").attr("class","nvd3 nv-legend").append("g"),t.select("g"));t.attr("transform","translate("+c.left+","+c.top+")");var v,w=u.selectAll(".nv-series").data(function(a){return"furious"!=o?a:a.filter(function(a){return m?!0:!a.disengaged})}),x=w.enter().append("g").attr("class","nv-series");if("classic"==o)x.append("circle").style("stroke-width",2).attr("class","nv-legend-symbol").attr("r",5),v=w.select("circle");else if("furious"==o){x.append("rect").style("stroke-width",2).attr("class","nv-legend-symbol").attr("rx",3).attr("ry",3),v=w.select("rect"),x.append("g").attr("class","nv-check-box").property("innerHTML",'').attr("transform","translate(-10,-8)scale(0.5)");var y=w.select(".nv-check-box");y.each(function(a,b){d3.select(this).selectAll("path").attr("stroke",q(a,b))})}x.append("text").attr("text-anchor","start").attr("class","nv-legend-text").attr("dy",".32em").attr("dx","8");var z=w.select("text.nv-legend-text");w.on("mouseover",function(a,b){n.legendMouseover(a,b)}).on("mouseout",function(a,b){n.legendMouseout(a,b)}).on("click",function(a,b){n.legendClick(a,b);var c=w.data();if(k){if("classic"==o)l?(c.forEach(function(a){a.disabled=!0}),a.disabled=!1):(a.disabled=!a.disabled,c.every(function(a){return a.disabled})&&c.forEach(function(a){a.disabled=!1}));else if("furious"==o)if(m)a.disengaged=!a.disengaged,a.userDisabled=void 0==a.userDisabled?!!a.disabled:a.userDisabled,a.disabled=a.disengaged||a.userDisabled;else if(!m){a.disabled=!a.disabled,a.userDisabled=a.disabled;var d=c.filter(function(a){return!a.disengaged});d.every(function(a){return a.userDisabled})&&c.forEach(function(a){a.disabled=a.userDisabled=!1})}n.stateChange({disabled:c.map(function(a){return!!a.disabled}),disengaged:c.map(function(a){return!!a.disengaged})})}}).on("dblclick",function(a,b){if(("furious"!=o||!m)&&(n.legendDblclick(a,b),k)){var c=w.data();c.forEach(function(a){a.disabled=!0,"furious"==o&&(a.userDisabled=a.disabled)}),a.disabled=!1,"furious"==o&&(a.userDisabled=a.disabled),n.stateChange({disabled:c.map(function(a){return!!a.disabled})})}}),w.classed("nv-disabled",function(a){return a.userDisabled}),w.exit().remove(),z.attr("fill",q).text(f);var A;switch(o){case"furious":A=23;break;case"classic":A=20}if(h){var B=[];w.each(function(){var b,c=d3.select(this).select("text");try{if(b=c.node().getComputedTextLength(),0>=b)throw Error()}catch(d){b=a.utils.calcApproxTextWidth(c)}B.push(b+i)});for(var C=0,D=0,E=[];p>D&&Cp&&C>1;){E=[],C--;for(var F=0;F(E[F%C]||0)&&(E[F%C]=B[F]);D=E.reduce(function(a,b){return a+b})}for(var G=[],H=0,I=0;C>H;H++)G[H]=I,I+=E[H];w.attr("transform",function(a,b){return"translate("+G[b%C]+","+(5+Math.floor(b/C)*A)+")"}),j?u.attr("transform","translate("+(d-c.right-D)+","+c.top+")"):u.attr("transform","translate(0,"+c.top+")"),e=c.top+c.bottom+Math.ceil(B.length/C)*A}else{var J,K=5,L=5,M=0;w.attr("transform",function(){var a=d3.select(this).select("text").node().getComputedTextLength()+i;return J=L,dM&&(M=L),"translate("+J+","+K+")"}),u.attr("transform","translate("+(d-c.right-M)+","+c.top+")"),e=c.top+c.bottom+K+15}"furious"==o&&v.attr("width",function(a,b){return z[0][b].getComputedTextLength()+27}).attr("height",18).attr("y",-9).attr("x",-15),v.style("fill",r).style("stroke",function(a,b){return a.color||g(a,b)})}),b}var c={top:5,right:0,bottom:5,left:0},d=400,e=20,f=function(a){return a.key},g=a.utils.getColor(),h=!0,i=28,j=!0,k=!0,l=!1,m=!1,n=d3.dispatch("legendClick","legendDblclick","legendMouseover","legendMouseout","stateChange"),o="classic";return b.dispatch=n,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return d},set:function(a){d=a}},height:{get:function(){return e},set:function(a){e=a}},key:{get:function(){return f},set:function(a){f=a}},align:{get:function(){return h},set:function(a){h=a}},rightAlign:{get:function(){return j},set:function(a){j=a}},padding:{get:function(){return i},set:function(a){i=a}},updateState:{get:function(){return k},set:function(a){k=a}},radioButtonMode:{get:function(){return l},set:function(a){l=a}},expanded:{get:function(){return m},set:function(a){m=a}},vers:{get:function(){return o},set:function(a){o=a}},margin:{get:function(){return c},set:function(a){c.top=void 0!==a.top?a.top:c.top,c.right=void 0!==a.right?a.right:c.right,c.bottom=void 0!==a.bottom?a.bottom:c.bottom,c.left=void 0!==a.left?a.left:c.left}},color:{get:function(){return g},set:function(b){g=a.utils.getColor(b)}}}),a.utils.initOptions(b),b},a.models.historicalBar=function(){"use strict";function b(x){return x.each(function(b){w.reset(),k=d3.select(this);var x=a.utils.availableWidth(h,k,g),y=a.utils.availableHeight(i,k,g);a.utils.initSVG(k),l.domain(c||d3.extent(b[0].values.map(n).concat(p))),l.range(r?e||[.5*x/b[0].values.length,x*(b[0].values.length-.5)/b[0].values.length]:e||[0,x]),m.domain(d||d3.extent(b[0].values.map(o).concat(q))).range(f||[y,0]),l.domain()[0]===l.domain()[1]&&l.domain(l.domain()[0]?[l.domain()[0]-.01*l.domain()[0],l.domain()[1]+.01*l.domain()[1]]:[-1,1]),m.domain()[0]===m.domain()[1]&&m.domain(m.domain()[0]?[m.domain()[0]+.01*m.domain()[0],m.domain()[1]-.01*m.domain()[1]]:[-1,1]);var z=k.selectAll("g.nv-wrap.nv-historicalBar-"+j).data([b[0].values]),A=z.enter().append("g").attr("class","nvd3 nv-wrap nv-historicalBar-"+j),B=A.append("defs"),C=A.append("g"),D=z.select("g");C.append("g").attr("class","nv-bars"),z.attr("transform","translate("+g.left+","+g.top+")"),k.on("click",function(a,b){u.chartClick({data:a,index:b,pos:d3.event,id:j})}),B.append("clipPath").attr("id","nv-chart-clip-path-"+j).append("rect"),z.select("#nv-chart-clip-path-"+j+" rect").attr("width",x).attr("height",y),D.attr("clip-path",s?"url(#nv-chart-clip-path-"+j+")":"");var E=z.select(".nv-bars").selectAll(".nv-bar").data(function(a){return a},function(a,b){return n(a,b)});E.exit().remove(),E.enter().append("rect").attr("x",0).attr("y",function(b,c){return a.utils.NaNtoZero(m(Math.max(0,o(b,c))))}).attr("height",function(b,c){return a.utils.NaNtoZero(Math.abs(m(o(b,c))-m(0)))}).attr("transform",function(a,c){return"translate("+(l(n(a,c))-x/b[0].values.length*.45)+",0)"}).on("mouseover",function(a,b){v&&(d3.select(this).classed("hover",!0),u.elementMouseover({data:a,index:b,color:d3.select(this).style("fill")}))}).on("mouseout",function(a,b){v&&(d3.select(this).classed("hover",!1),u.elementMouseout({data:a,index:b,color:d3.select(this).style("fill")}))}).on("mousemove",function(a,b){v&&u.elementMousemove({data:a,index:b,color:d3.select(this).style("fill")})}).on("click",function(a,b){v&&(u.elementClick({data:a,index:b,color:d3.select(this).style("fill")}),d3.event.stopPropagation())}).on("dblclick",function(a,b){v&&(u.elementDblClick({data:a,index:b,color:d3.select(this).style("fill")}),d3.event.stopPropagation())}),E.attr("fill",function(a,b){return t(a,b)}).attr("class",function(a,b,c){return(o(a,b)<0?"nv-bar negative":"nv-bar positive")+" nv-bar-"+c+"-"+b}).watchTransition(w,"bars").attr("transform",function(a,c){return"translate("+(l(n(a,c))-x/b[0].values.length*.45)+",0)"}).attr("width",x/b[0].values.length*.9),E.watchTransition(w,"bars").attr("y",function(b,c){var d=o(b,c)<0?m(0):m(0)-m(o(b,c))<1?m(0)-1:m(o(b,c));return a.utils.NaNtoZero(d)}).attr("height",function(b,c){return a.utils.NaNtoZero(Math.max(Math.abs(m(o(b,c))-m(0)),1))})}),w.renderEnd("historicalBar immediate"),b}var c,d,e,f,g={top:0,right:0,bottom:0,left:0},h=null,i=null,j=Math.floor(1e4*Math.random()),k=null,l=d3.scale.linear(),m=d3.scale.linear(),n=function(a){return a.x},o=function(a){return a.y},p=[],q=[0],r=!1,s=!0,t=a.utils.defaultColor(),u=d3.dispatch("chartClick","elementClick","elementDblClick","elementMouseover","elementMouseout","elementMousemove","renderEnd"),v=!0,w=a.utils.renderWatch(u,0);return b.highlightPoint=function(a,b){k.select(".nv-bars .nv-bar-0-"+a).classed("hover",b)},b.clearHighlights=function(){k.select(".nv-bars .nv-bar.hover").classed("hover",!1)},b.dispatch=u,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return h},set:function(a){h=a}},height:{get:function(){return i},set:function(a){i=a}},forceX:{get:function(){return p},set:function(a){p=a}},forceY:{get:function(){return q},set:function(a){q=a}},padData:{get:function(){return r},set:function(a){r=a}},x:{get:function(){return n},set:function(a){n=a}},y:{get:function(){return o},set:function(a){o=a}},xScale:{get:function(){return l},set:function(a){l=a}},yScale:{get:function(){return m},set:function(a){m=a}},xDomain:{get:function(){return c},set:function(a){c=a}},yDomain:{get:function(){return d},set:function(a){d=a}},xRange:{get:function(){return e},set:function(a){e=a}},yRange:{get:function(){return f},set:function(a){f=a}},clipEdge:{get:function(){return s},set:function(a){s=a}},id:{get:function(){return j},set:function(a){j=a}},interactive:{get:function(){return v},set:function(a){v=a}},margin:{get:function(){return g},set:function(a){g.top=void 0!==a.top?a.top:g.top,g.right=void 0!==a.right?a.right:g.right,g.bottom=void 0!==a.bottom?a.bottom:g.bottom,g.left=void 0!==a.left?a.left:g.left}},color:{get:function(){return t},set:function(b){t=a.utils.getColor(b)}}}),a.utils.initOptions(b),b},a.models.historicalBarChart=function(b){"use strict";function c(b){return b.each(function(k){z.reset(),z.models(f),q&&z.models(g),r&&z.models(h);var w=d3.select(this),A=this;a.utils.initSVG(w);var B=a.utils.availableWidth(n,w,l),C=a.utils.availableHeight(o,w,l);if(c.update=function(){w.transition().duration(y).call(c)},c.container=this,u.disabled=k.map(function(a){return!!a.disabled}),!v){var D;v={};for(D in u)v[D]=u[D]instanceof Array?u[D].slice(0):u[D]}if(!(k&&k.length&&k.filter(function(a){return a.values.length}).length))return a.utils.noData(c,w),c;w.selectAll(".nv-noData").remove(),d=f.xScale(),e=f.yScale();var E=w.selectAll("g.nv-wrap.nv-historicalBarChart").data([k]),F=E.enter().append("g").attr("class","nvd3 nv-wrap nv-historicalBarChart").append("g"),G=E.select("g");F.append("g").attr("class","nv-x nv-axis"),F.append("g").attr("class","nv-y nv-axis"),F.append("g").attr("class","nv-barsWrap"),F.append("g").attr("class","nv-legendWrap"),F.append("g").attr("class","nv-interactive"),p&&(i.width(B),G.select(".nv-legendWrap").datum(k).call(i),l.top!=i.height()&&(l.top=i.height(),C=a.utils.availableHeight(o,w,l)),E.select(".nv-legendWrap").attr("transform","translate(0,"+-l.top+")")),E.attr("transform","translate("+l.left+","+l.top+")"),s&&G.select(".nv-y.nv-axis").attr("transform","translate("+B+",0)"),t&&(j.width(B).height(C).margin({left:l.left,top:l.top}).svgContainer(w).xScale(d),E.select(".nv-interactive").call(j)),f.width(B).height(C).color(k.map(function(a,b){return a.color||m(a,b)}).filter(function(a,b){return!k[b].disabled}));var H=G.select(".nv-barsWrap").datum(k.filter(function(a){return!a.disabled}));H.transition().call(f),q&&(g.scale(d)._ticks(a.utils.calcTicksX(B/100,k)).tickSize(-C,0),G.select(".nv-x.nv-axis").attr("transform","translate(0,"+e.range()[0]+")"),G.select(".nv-x.nv-axis").transition().call(g)),r&&(h.scale(e)._ticks(a.utils.calcTicksY(C/36,k)).tickSize(-B,0),G.select(".nv-y.nv-axis").transition().call(h)),j.dispatch.on("elementMousemove",function(b){f.clearHighlights();var d,e,i,n=[];k.filter(function(a,b){return a.seriesIndex=b,!a.disabled}).forEach(function(g){e=a.interactiveBisect(g.values,b.pointXValue,c.x()),f.highlightPoint(e,!0);var h=g.values[e];void 0!==h&&(void 0===d&&(d=h),void 0===i&&(i=c.xScale()(c.x()(h,e))),n.push({key:g.key,value:c.y()(h,e),color:m(g,g.seriesIndex),data:g.values[e]}))});var o=g.tickFormat()(c.x()(d,e));j.tooltip.position({left:i+l.left,top:b.mouseY+l.top}).chartContainer(A.parentNode).valueFormatter(function(a){return h.tickFormat()(a)}).data({value:o,index:e,series:n})(),j.renderGuideLine(i)}),j.dispatch.on("elementMouseout",function(){x.tooltipHide(),f.clearHighlights()}),i.dispatch.on("legendClick",function(a){a.disabled=!a.disabled,k.filter(function(a){return!a.disabled}).length||k.map(function(a){return a.disabled=!1,E.selectAll(".nv-series").classed("disabled",!1),a}),u.disabled=k.map(function(a){return!!a.disabled}),x.stateChange(u),b.transition().call(c)}),i.dispatch.on("legendDblclick",function(a){k.forEach(function(a){a.disabled=!0}),a.disabled=!1,u.disabled=k.map(function(a){return!!a.disabled}),x.stateChange(u),c.update()}),x.on("changeState",function(a){"undefined"!=typeof a.disabled&&(k.forEach(function(b,c){b.disabled=a.disabled[c]}),u.disabled=a.disabled),c.update()})}),z.renderEnd("historicalBarChart immediate"),c}var d,e,f=b||a.models.historicalBar(),g=a.models.axis(),h=a.models.axis(),i=a.models.legend(),j=a.interactiveGuideline(),k=a.models.tooltip(),l={top:30,right:90,bottom:50,left:90},m=a.utils.defaultColor(),n=null,o=null,p=!1,q=!0,r=!0,s=!1,t=!1,u={},v=null,w=null,x=d3.dispatch("tooltipHide","stateChange","changeState","renderEnd"),y=250;g.orient("bottom").tickPadding(7),h.orient(s?"right":"left"),k.duration(0).headerEnabled(!1).valueFormatter(function(a,b){return h.tickFormat()(a,b)}).headerFormatter(function(a,b){return g.tickFormat()(a,b)});var z=a.utils.renderWatch(x,0);return f.dispatch.on("elementMouseover.tooltip",function(a){a.series={key:c.x()(a.data),value:c.y()(a.data),color:a.color},k.data(a).hidden(!1)}),f.dispatch.on("elementMouseout.tooltip",function(){k.hidden(!0)}),f.dispatch.on("elementMousemove.tooltip",function(){k.position({top:d3.event.pageY,left:d3.event.pageX})()}),c.dispatch=x,c.bars=f,c.legend=i,c.xAxis=g,c.yAxis=h,c.interactiveLayer=j,c.tooltip=k,c.options=a.utils.optionsFunc.bind(c),c._options=Object.create({},{width:{get:function(){return n},set:function(a){n=a}},height:{get:function(){return o},set:function(a){o=a}},showLegend:{get:function(){return p},set:function(a){p=a}},showXAxis:{get:function(){return q},set:function(a){q=a}},showYAxis:{get:function(){return r},set:function(a){r=a}},defaultState:{get:function(){return v},set:function(a){v=a}},noData:{get:function(){return w},set:function(a){w=a}},tooltips:{get:function(){return k.enabled()},set:function(b){a.deprecated("tooltips","use chart.tooltip.enabled() instead"),k.enabled(!!b)}},tooltipContent:{get:function(){return k.contentGenerator()},set:function(b){a.deprecated("tooltipContent","use chart.tooltip.contentGenerator() instead"),k.contentGenerator(b)}},margin:{get:function(){return l},set:function(a){l.top=void 0!==a.top?a.top:l.top,l.right=void 0!==a.right?a.right:l.right,l.bottom=void 0!==a.bottom?a.bottom:l.bottom,l.left=void 0!==a.left?a.left:l.left}},color:{get:function(){return m},set:function(b){m=a.utils.getColor(b),i.color(m),f.color(m)}},duration:{get:function(){return y},set:function(a){y=a,z.reset(y),h.duration(y),g.duration(y)}},rightAlignYAxis:{get:function(){return s},set:function(a){s=a,h.orient(a?"right":"left")}},useInteractiveGuideline:{get:function(){return t},set:function(a){t=a,a===!0&&c.interactive(!1)}}}),a.utils.inheritOptions(c,f),a.utils.initOptions(c),c},a.models.ohlcBarChart=function(){var b=a.models.historicalBarChart(a.models.ohlcBar());return b.useInteractiveGuideline(!0),b.interactiveLayer.tooltip.contentGenerator(function(a){var c=a.series[0].data,d=c.open'+a.value+"
open:"+b.yAxis.tickFormat()(c.open)+"
close:"+b.yAxis.tickFormat()(c.close)+"
high"+b.yAxis.tickFormat()(c.high)+"
low:"+b.yAxis.tickFormat()(c.low)+"
"}),b},a.models.candlestickBarChart=function(){var b=a.models.historicalBarChart(a.models.candlestickBar());return b.useInteractiveGuideline(!0),b.interactiveLayer.tooltip.contentGenerator(function(a){var c=a.series[0].data,d=c.open'+a.value+"
open:"+b.yAxis.tickFormat()(c.open)+"
close:"+b.yAxis.tickFormat()(c.close)+"
high"+b.yAxis.tickFormat()(c.high)+"
low:"+b.yAxis.tickFormat()(c.low)+"
"}),b},a.models.legend=function(){"use strict";function b(p){function q(a,b){return"furious"!=o?"#000":m?a.disengaged?"#000":"#fff":m?void 0:(a.color||(a.color=g(a,b)),a.disabled?a.color:"#fff")}function r(a,b){return m&&"furious"==o&&a.disengaged?"#eee":a.color||g(a,b)}function s(a){return m&&"furious"==o?1:a.disabled?0:1}return p.each(function(b){var g=d-c.left-c.right,p=d3.select(this);a.utils.initSVG(p);var t=p.selectAll("g.nv-legend").data([b]),u=t.enter().append("g").attr("class","nvd3 nv-legend").append("g"),v=t.select("g");t.attr("transform","translate("+c.left+","+c.top+")");var w,x,y=v.selectAll(".nv-series").data(function(a){return"furious"!=o?a:a.filter(function(a){return m?!0:!a.disengaged})}),z=y.enter().append("g").attr("class","nv-series");switch(o){case"furious":x=23;break;case"classic":x=20}if("classic"==o)z.append("circle").style("stroke-width",2).attr("class","nv-legend-symbol").attr("r",5),w=y.select("circle");else if("furious"==o){z.append("rect").style("stroke-width",2).attr("class","nv-legend-symbol").attr("rx",3).attr("ry",3),w=y.select(".nv-legend-symbol"),z.append("g").attr("class","nv-check-box").property("innerHTML",'').attr("transform","translate(-10,-8)scale(0.5)");var A=y.select(".nv-check-box");A.each(function(a,b){d3.select(this).selectAll("path").attr("stroke",q(a,b))})}z.append("text").attr("text-anchor","start").attr("class","nv-legend-text").attr("dy",".32em").attr("dx","8");var B=y.select("text.nv-legend-text");y.on("mouseover",function(a,b){n.legendMouseover(a,b)}).on("mouseout",function(a,b){n.legendMouseout(a,b)}).on("click",function(a,b){n.legendClick(a,b);var c=y.data();if(k){if("classic"==o)l?(c.forEach(function(a){a.disabled=!0}),a.disabled=!1):(a.disabled=!a.disabled,c.every(function(a){return a.disabled})&&c.forEach(function(a){a.disabled=!1}));else if("furious"==o)if(m)a.disengaged=!a.disengaged,a.userDisabled=void 0==a.userDisabled?!!a.disabled:a.userDisabled,a.disabled=a.disengaged||a.userDisabled;else if(!m){a.disabled=!a.disabled,a.userDisabled=a.disabled;var d=c.filter(function(a){return!a.disengaged});d.every(function(a){return a.userDisabled})&&c.forEach(function(a){a.disabled=a.userDisabled=!1})}n.stateChange({disabled:c.map(function(a){return!!a.disabled}),disengaged:c.map(function(a){return!!a.disengaged})})}}).on("dblclick",function(a,b){if(("furious"!=o||!m)&&(n.legendDblclick(a,b),k)){var c=y.data();c.forEach(function(a){a.disabled=!0,"furious"==o&&(a.userDisabled=a.disabled)}),a.disabled=!1,"furious"==o&&(a.userDisabled=a.disabled),n.stateChange({disabled:c.map(function(a){return!!a.disabled})})}}),y.classed("nv-disabled",function(a){return a.userDisabled}),y.exit().remove(),B.attr("fill",q).text(f);var C=0;if(h){var D=[];y.each(function(){var b,c=d3.select(this).select("text");try{if(b=c.node().getComputedTextLength(),0>=b)throw Error()}catch(d){b=a.utils.calcApproxTextWidth(c)}D.push(b+i)});var E=0,F=[];for(C=0;g>C&&Eg&&E>1;){F=[],E--;for(var G=0;G(F[G%E]||0)&&(F[G%E]=D[G]);C=F.reduce(function(a,b){return a+b})}for(var H=[],I=0,J=0;E>I;I++)H[I]=J,J+=F[I];y.attr("transform",function(a,b){return"translate("+H[b%E]+","+(5+Math.floor(b/E)*x)+")"}),j?v.attr("transform","translate("+(d-c.right-C)+","+c.top+")"):v.attr("transform","translate(0,"+c.top+")"),e=c.top+c.bottom+Math.ceil(D.length/E)*x}else{var K,L=5,M=5,N=0;y.attr("transform",function(){var a=d3.select(this).select("text").node().getComputedTextLength()+i;return K=M,dN&&(N=M),K+N>C&&(C=K+N),"translate("+K+","+L+")"}),v.attr("transform","translate("+(d-c.right-N)+","+c.top+")"),e=c.top+c.bottom+L+15}if("furious"==o){w.attr("width",function(a,b){return B[0][b].getComputedTextLength()+27}).attr("height",18).attr("y",-9).attr("x",-15),u.insert("rect",":first-child").attr("class","nv-legend-bg").attr("fill","#eee").attr("opacity",0);var O=v.select(".nv-legend-bg");O.transition().duration(300).attr("x",-x).attr("width",C+x-12).attr("height",e+10).attr("y",-c.top-10).attr("opacity",m?1:0)}w.style("fill",r).style("fill-opacity",s).style("stroke",r)}),b}var c={top:5,right:0,bottom:5,left:0},d=400,e=20,f=function(a){return a.key},g=a.utils.getColor(),h=!0,i=32,j=!0,k=!0,l=!1,m=!1,n=d3.dispatch("legendClick","legendDblclick","legendMouseover","legendMouseout","stateChange"),o="classic";return b.dispatch=n,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return d},set:function(a){d=a}},height:{get:function(){return e},set:function(a){e=a}},key:{get:function(){return f},set:function(a){f=a}},align:{get:function(){return h},set:function(a){h=a}},rightAlign:{get:function(){return j},set:function(a){j=a}},padding:{get:function(){return i},set:function(a){i=a}},updateState:{get:function(){return k},set:function(a){k=a}},radioButtonMode:{get:function(){return l},set:function(a){l=a}},expanded:{get:function(){return m},set:function(a){m=a}},vers:{get:function(){return o},set:function(a){o=a}},margin:{get:function(){return c},set:function(a){c.top=void 0!==a.top?a.top:c.top,c.right=void 0!==a.right?a.right:c.right,c.bottom=void 0!==a.bottom?a.bottom:c.bottom,c.left=void 0!==a.left?a.left:c.left}},color:{get:function(){return g},set:function(b){g=a.utils.getColor(b)}}}),a.utils.initOptions(b),b},a.models.line=function(){"use strict";function b(r){return v.reset(),v.models(e),r.each(function(b){i=d3.select(this);var r=a.utils.availableWidth(g,i,f),s=a.utils.availableHeight(h,i,f);a.utils.initSVG(i),c=e.xScale(),d=e.yScale(),t=t||c,u=u||d;var w=i.selectAll("g.nv-wrap.nv-line").data([b]),x=w.enter().append("g").attr("class","nvd3 nv-wrap nv-line"),y=x.append("defs"),z=x.append("g"),A=w.select("g");z.append("g").attr("class","nv-groups"),z.append("g").attr("class","nv-scatterWrap"),w.attr("transform","translate("+f.left+","+f.top+")"),e.width(r).height(s);var B=w.select(".nv-scatterWrap");B.call(e),y.append("clipPath").attr("id","nv-edge-clip-"+e.id()).append("rect"),w.select("#nv-edge-clip-"+e.id()+" rect").attr("width",r).attr("height",s>0?s:0),A.attr("clip-path",p?"url(#nv-edge-clip-"+e.id()+")":""),B.attr("clip-path",p?"url(#nv-edge-clip-"+e.id()+")":"");var C=w.select(".nv-groups").selectAll(".nv-group").data(function(a){return a},function(a){return a.key});C.enter().append("g").style("stroke-opacity",1e-6).style("stroke-width",function(a){return a.strokeWidth||j}).style("fill-opacity",1e-6),C.exit().remove(),C.attr("class",function(a,b){return(a.classed||"")+" nv-group nv-series-"+b}).classed("hover",function(a){return a.hover}).style("fill",function(a,b){return k(a,b)}).style("stroke",function(a,b){return k(a,b)}),C.watchTransition(v,"line: groups").style("stroke-opacity",1).style("fill-opacity",function(a){return a.fillOpacity||.5});var D=C.selectAll("path.nv-area").data(function(a){return o(a)?[a]:[]});D.enter().append("path").attr("class","nv-area").attr("d",function(b){return d3.svg.area().interpolate(q).defined(n).x(function(b,c){return a.utils.NaNtoZero(t(l(b,c)))}).y0(function(b,c){return a.utils.NaNtoZero(u(m(b,c)))}).y1(function(){return u(d.domain()[0]<=0?d.domain()[1]>=0?0:d.domain()[1]:d.domain()[0])}).apply(this,[b.values])}),C.exit().selectAll("path.nv-area").remove(),D.watchTransition(v,"line: areaPaths").attr("d",function(b){return d3.svg.area().interpolate(q).defined(n).x(function(b,d){return a.utils.NaNtoZero(c(l(b,d)))}).y0(function(b,c){return a.utils.NaNtoZero(d(m(b,c)))}).y1(function(){return d(d.domain()[0]<=0?d.domain()[1]>=0?0:d.domain()[1]:d.domain()[0])}).apply(this,[b.values])});var E=C.selectAll("path.nv-line").data(function(a){return[a.values]});E.enter().append("path").attr("class","nv-line").attr("d",d3.svg.line().interpolate(q).defined(n).x(function(b,c){return a.utils.NaNtoZero(t(l(b,c)))}).y(function(b,c){return a.utils.NaNtoZero(u(m(b,c)))})),E.watchTransition(v,"line: linePaths").attr("d",d3.svg.line().interpolate(q).defined(n).x(function(b,d){return a.utils.NaNtoZero(c(l(b,d)))}).y(function(b,c){return a.utils.NaNtoZero(d(m(b,c)))})),t=c.copy(),u=d.copy()}),v.renderEnd("line immediate"),b}var c,d,e=a.models.scatter(),f={top:0,right:0,bottom:0,left:0},g=960,h=500,i=null,j=1.5,k=a.utils.defaultColor(),l=function(a){return a.x},m=function(a){return a.y},n=function(a,b){return!isNaN(m(a,b))&&null!==m(a,b)},o=function(a){return a.area},p=!1,q="linear",r=250,s=d3.dispatch("elementClick","elementMouseover","elementMouseout","renderEnd");e.pointSize(16).pointDomain([16,256]);var t,u,v=a.utils.renderWatch(s,r);return b.dispatch=s,b.scatter=e,e.dispatch.on("elementClick",function(){s.elementClick.apply(this,arguments)}),e.dispatch.on("elementMouseover",function(){s.elementMouseover.apply(this,arguments)}),e.dispatch.on("elementMouseout",function(){s.elementMouseout.apply(this,arguments)}),b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return g},set:function(a){g=a}},height:{get:function(){return h},set:function(a){h=a}},defined:{get:function(){return n},set:function(a){n=a}},interpolate:{get:function(){return q},set:function(a){q=a}},clipEdge:{get:function(){return p},set:function(a){p=a}},margin:{get:function(){return f},set:function(a){f.top=void 0!==a.top?a.top:f.top,f.right=void 0!==a.right?a.right:f.right,f.bottom=void 0!==a.bottom?a.bottom:f.bottom,f.left=void 0!==a.left?a.left:f.left}},duration:{get:function(){return r},set:function(a){r=a,v.reset(r),e.duration(r)}},isArea:{get:function(){return o},set:function(a){o=d3.functor(a)}},x:{get:function(){return l},set:function(a){l=a,e.x(a)}},y:{get:function(){return m},set:function(a){m=a,e.y(a)}},color:{get:function(){return k},set:function(b){k=a.utils.getColor(b),e.color(k)}}}),a.utils.inheritOptions(b,e),a.utils.initOptions(b),b},a.models.lineChart=function(){"use strict";function b(j){return y.reset(),y.models(e),p&&y.models(f),q&&y.models(g),j.each(function(j){var v=d3.select(this),y=this;a.utils.initSVG(v);var B=a.utils.availableWidth(m,v,k),C=a.utils.availableHeight(n,v,k);if(b.update=function(){0===x?v.call(b):v.transition().duration(x).call(b)},b.container=this,t.setter(A(j),b.update).getter(z(j)).update(),t.disabled=j.map(function(a){return!!a.disabled}),!u){var D;u={};for(D in t)u[D]=t[D]instanceof Array?t[D].slice(0):t[D] -}if(!(j&&j.length&&j.filter(function(a){return a.values.length}).length))return a.utils.noData(b,v),b;v.selectAll(".nv-noData").remove(),c=e.xScale(),d=e.yScale();var E=v.selectAll("g.nv-wrap.nv-lineChart").data([j]),F=E.enter().append("g").attr("class","nvd3 nv-wrap nv-lineChart").append("g"),G=E.select("g");F.append("rect").style("opacity",0),F.append("g").attr("class","nv-x nv-axis"),F.append("g").attr("class","nv-y nv-axis"),F.append("g").attr("class","nv-linesWrap"),F.append("g").attr("class","nv-legendWrap"),F.append("g").attr("class","nv-interactive"),G.select("rect").attr("width",B).attr("height",C>0?C:0),o&&(h.width(B),G.select(".nv-legendWrap").datum(j).call(h),k.top!=h.height()&&(k.top=h.height(),C=a.utils.availableHeight(n,v,k)),E.select(".nv-legendWrap").attr("transform","translate(0,"+-k.top+")")),E.attr("transform","translate("+k.left+","+k.top+")"),r&&G.select(".nv-y.nv-axis").attr("transform","translate("+B+",0)"),s&&(i.width(B).height(C).margin({left:k.left,top:k.top}).svgContainer(v).xScale(c),E.select(".nv-interactive").call(i)),e.width(B).height(C).color(j.map(function(a,b){return a.color||l(a,b)}).filter(function(a,b){return!j[b].disabled}));var H=G.select(".nv-linesWrap").datum(j.filter(function(a){return!a.disabled}));H.call(e),p&&(f.scale(c)._ticks(a.utils.calcTicksX(B/100,j)).tickSize(-C,0),G.select(".nv-x.nv-axis").attr("transform","translate(0,"+d.range()[0]+")"),G.select(".nv-x.nv-axis").call(f)),q&&(g.scale(d)._ticks(a.utils.calcTicksY(C/36,j)).tickSize(-B,0),G.select(".nv-y.nv-axis").call(g)),h.dispatch.on("stateChange",function(a){for(var c in a)t[c]=a[c];w.stateChange(t),b.update()}),i.dispatch.on("elementMousemove",function(c){e.clearHighlights();var d,h,m,n=[];if(j.filter(function(a,b){return a.seriesIndex=b,!a.disabled}).forEach(function(f,g){h=a.interactiveBisect(f.values,c.pointXValue,b.x());var i=f.values[h],j=b.y()(i,h);null!=j&&e.highlightPoint(g,h,!0),void 0!==i&&(void 0===d&&(d=i),void 0===m&&(m=b.xScale()(b.x()(i,h))),n.push({key:f.key,value:j,color:l(f,f.seriesIndex)}))}),n.length>2){var o=b.yScale().invert(c.mouseY),p=Math.abs(b.yScale().domain()[0]-b.yScale().domain()[1]),q=.03*p,r=a.nearestValueIndex(n.map(function(a){return a.value}),o,q);null!==r&&(n[r].highlight=!0)}var s=f.tickFormat()(b.x()(d,h));i.tooltip.position({left:c.mouseX+k.left,top:c.mouseY+k.top}).chartContainer(y.parentNode).valueFormatter(function(a){return null==a?"N/A":g.tickFormat()(a)}).data({value:s,index:h,series:n})(),i.renderGuideLine(m)}),i.dispatch.on("elementClick",function(c){var d,f=[];j.filter(function(a,b){return a.seriesIndex=b,!a.disabled}).forEach(function(e){var g=a.interactiveBisect(e.values,c.pointXValue,b.x()),h=e.values[g];if("undefined"!=typeof h){"undefined"==typeof d&&(d=b.xScale()(b.x()(h,g)));var i=b.yScale()(b.y()(h,g));f.push({point:h,pointIndex:g,pos:[d,i],seriesIndex:e.seriesIndex,series:e})}}),e.dispatch.elementClick(f)}),i.dispatch.on("elementMouseout",function(){e.clearHighlights()}),w.on("changeState",function(a){"undefined"!=typeof a.disabled&&j.length===a.disabled.length&&(j.forEach(function(b,c){b.disabled=a.disabled[c]}),t.disabled=a.disabled),b.update()})}),y.renderEnd("lineChart immediate"),b}var c,d,e=a.models.line(),f=a.models.axis(),g=a.models.axis(),h=a.models.legend(),i=a.interactiveGuideline(),j=a.models.tooltip(),k={top:30,right:20,bottom:50,left:60},l=a.utils.defaultColor(),m=null,n=null,o=!0,p=!0,q=!0,r=!1,s=!1,t=a.utils.state(),u=null,v=null,w=d3.dispatch("tooltipShow","tooltipHide","stateChange","changeState","renderEnd"),x=250;f.orient("bottom").tickPadding(7),g.orient(r?"right":"left"),j.valueFormatter(function(a,b){return g.tickFormat()(a,b)}).headerFormatter(function(a,b){return f.tickFormat()(a,b)});var y=a.utils.renderWatch(w,x),z=function(a){return function(){return{active:a.map(function(a){return!a.disabled})}}},A=function(a){return function(b){void 0!==b.active&&a.forEach(function(a,c){a.disabled=!b.active[c]})}};return e.dispatch.on("elementMouseover.tooltip",function(a){j.data(a).position(a.pos).hidden(!1)}),e.dispatch.on("elementMouseout.tooltip",function(){j.hidden(!0)}),b.dispatch=w,b.lines=e,b.legend=h,b.xAxis=f,b.yAxis=g,b.interactiveLayer=i,b.tooltip=j,b.dispatch=w,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return m},set:function(a){m=a}},height:{get:function(){return n},set:function(a){n=a}},showLegend:{get:function(){return o},set:function(a){o=a}},showXAxis:{get:function(){return p},set:function(a){p=a}},showYAxis:{get:function(){return q},set:function(a){q=a}},defaultState:{get:function(){return u},set:function(a){u=a}},noData:{get:function(){return v},set:function(a){v=a}},tooltips:{get:function(){return j.enabled()},set:function(b){a.deprecated("tooltips","use chart.tooltip.enabled() instead"),j.enabled(!!b)}},tooltipContent:{get:function(){return j.contentGenerator()},set:function(b){a.deprecated("tooltipContent","use chart.tooltip.contentGenerator() instead"),j.contentGenerator(b)}},margin:{get:function(){return k},set:function(a){k.top=void 0!==a.top?a.top:k.top,k.right=void 0!==a.right?a.right:k.right,k.bottom=void 0!==a.bottom?a.bottom:k.bottom,k.left=void 0!==a.left?a.left:k.left}},duration:{get:function(){return x},set:function(a){x=a,y.reset(x),e.duration(x),f.duration(x),g.duration(x)}},color:{get:function(){return l},set:function(b){l=a.utils.getColor(b),h.color(l),e.color(l)}},rightAlignYAxis:{get:function(){return r},set:function(a){r=a,g.orient(r?"right":"left")}},useInteractiveGuideline:{get:function(){return s},set:function(a){s=a,s&&(e.interactive(!1),e.useVoronoi(!1))}}}),a.utils.inheritOptions(b,e),a.utils.initOptions(b),b},a.models.linePlusBarChart=function(){"use strict";function b(v){return v.each(function(v){function J(a){var b=+("e"==a),c=b?1:-1,d=X/3;return"M"+.5*c+","+d+"A6,6 0 0 "+b+" "+6.5*c+","+(d+6)+"V"+(2*d-6)+"A6,6 0 0 "+b+" "+.5*c+","+2*d+"ZM"+2.5*c+","+(d+8)+"V"+(2*d-8)+"M"+4.5*c+","+(d+8)+"V"+(2*d-8)}function S(){u.empty()||u.extent(I),kb.data([u.empty()?e.domain():I]).each(function(a){var b=e(a[0])-e.range()[0],c=e.range()[1]-e(a[1]);d3.select(this).select(".left").attr("width",0>b?0:b),d3.select(this).select(".right").attr("x",e(a[1])).attr("width",0>c?0:c)})}function T(){I=u.empty()?null:u.extent(),c=u.empty()?e.domain():u.extent(),K.brush({extent:c,brush:u}),S(),l.width(V).height(W).color(v.map(function(a,b){return a.color||C(a,b)}).filter(function(a,b){return!v[b].disabled&&v[b].bar})),j.width(V).height(W).color(v.map(function(a,b){return a.color||C(a,b)}).filter(function(a,b){return!v[b].disabled&&!v[b].bar}));var b=db.select(".nv-focus .nv-barsWrap").datum(Z.length?Z.map(function(a){return{key:a.key,values:a.values.filter(function(a,b){return l.x()(a,b)>=c[0]&&l.x()(a,b)<=c[1]})}}):[{values:[]}]),h=db.select(".nv-focus .nv-linesWrap").datum($[0].disabled?[{values:[]}]:$.map(function(a){return{area:a.area,fillOpacity:a.fillOpacity,key:a.key,values:a.values.filter(function(a,b){return j.x()(a,b)>=c[0]&&j.x()(a,b)<=c[1]})}}));d=Z.length?l.xScale():j.xScale(),n.scale(d)._ticks(a.utils.calcTicksX(V/100,v)).tickSize(-W,0),n.domain([Math.ceil(c[0]),Math.floor(c[1])]),db.select(".nv-x.nv-axis").transition().duration(L).call(n),b.transition().duration(L).call(l),h.transition().duration(L).call(j),db.select(".nv-focus .nv-x.nv-axis").attr("transform","translate(0,"+f.range()[0]+")"),p.scale(f)._ticks(a.utils.calcTicksY(W/36,v)).tickSize(-V,0),q.scale(g)._ticks(a.utils.calcTicksY(W/36,v)).tickSize(Z.length?0:-V,0),db.select(".nv-focus .nv-y1.nv-axis").style("opacity",Z.length?1:0),db.select(".nv-focus .nv-y2.nv-axis").style("opacity",$.length&&!$[0].disabled?1:0).attr("transform","translate("+d.range()[1]+",0)"),db.select(".nv-focus .nv-y1.nv-axis").transition().duration(L).call(p),db.select(".nv-focus .nv-y2.nv-axis").transition().duration(L).call(q)}var U=d3.select(this);a.utils.initSVG(U);var V=a.utils.availableWidth(y,U,w),W=a.utils.availableHeight(z,U,w)-(E?H:0),X=H-x.top-x.bottom;if(b.update=function(){U.transition().duration(L).call(b)},b.container=this,M.setter(R(v),b.update).getter(Q(v)).update(),M.disabled=v.map(function(a){return!!a.disabled}),!N){var Y;N={};for(Y in M)N[Y]=M[Y]instanceof Array?M[Y].slice(0):M[Y]}if(!(v&&v.length&&v.filter(function(a){return a.values.length}).length))return a.utils.noData(b,U),b;U.selectAll(".nv-noData").remove();var Z=v.filter(function(a){return!a.disabled&&a.bar}),$=v.filter(function(a){return!a.bar});d=l.xScale(),e=o.scale(),f=l.yScale(),g=j.yScale(),h=m.yScale(),i=k.yScale();var _=v.filter(function(a){return!a.disabled&&a.bar}).map(function(a){return a.values.map(function(a,b){return{x:A(a,b),y:B(a,b)}})}),ab=v.filter(function(a){return!a.disabled&&!a.bar}).map(function(a){return a.values.map(function(a,b){return{x:A(a,b),y:B(a,b)}})});d.range([0,V]),e.domain(d3.extent(d3.merge(_.concat(ab)),function(a){return a.x})).range([0,V]);var bb=U.selectAll("g.nv-wrap.nv-linePlusBar").data([v]),cb=bb.enter().append("g").attr("class","nvd3 nv-wrap nv-linePlusBar").append("g"),db=bb.select("g");cb.append("g").attr("class","nv-legendWrap");var eb=cb.append("g").attr("class","nv-focus");eb.append("g").attr("class","nv-x nv-axis"),eb.append("g").attr("class","nv-y1 nv-axis"),eb.append("g").attr("class","nv-y2 nv-axis"),eb.append("g").attr("class","nv-barsWrap"),eb.append("g").attr("class","nv-linesWrap");var fb=cb.append("g").attr("class","nv-context");if(fb.append("g").attr("class","nv-x nv-axis"),fb.append("g").attr("class","nv-y1 nv-axis"),fb.append("g").attr("class","nv-y2 nv-axis"),fb.append("g").attr("class","nv-barsWrap"),fb.append("g").attr("class","nv-linesWrap"),fb.append("g").attr("class","nv-brushBackground"),fb.append("g").attr("class","nv-x nv-brush"),D){var gb=t.align()?V/2:V,hb=t.align()?gb:0;t.width(gb),db.select(".nv-legendWrap").datum(v.map(function(a){return a.originalKey=void 0===a.originalKey?a.key:a.originalKey,a.key=a.originalKey+(a.bar?O:P),a})).call(t),w.top!=t.height()&&(w.top=t.height(),W=a.utils.availableHeight(z,U,w)-H),db.select(".nv-legendWrap").attr("transform","translate("+hb+","+-w.top+")")}bb.attr("transform","translate("+w.left+","+w.top+")"),db.select(".nv-context").style("display",E?"initial":"none"),m.width(V).height(X).color(v.map(function(a,b){return a.color||C(a,b)}).filter(function(a,b){return!v[b].disabled&&v[b].bar})),k.width(V).height(X).color(v.map(function(a,b){return a.color||C(a,b)}).filter(function(a,b){return!v[b].disabled&&!v[b].bar}));var ib=db.select(".nv-context .nv-barsWrap").datum(Z.length?Z:[{values:[]}]),jb=db.select(".nv-context .nv-linesWrap").datum($[0].disabled?[{values:[]}]:$);db.select(".nv-context").attr("transform","translate(0,"+(W+w.bottom+x.top)+")"),ib.transition().call(m),jb.transition().call(k),G&&(o._ticks(a.utils.calcTicksX(V/100,v)).tickSize(-X,0),db.select(".nv-context .nv-x.nv-axis").attr("transform","translate(0,"+h.range()[0]+")"),db.select(".nv-context .nv-x.nv-axis").transition().call(o)),F&&(r.scale(h)._ticks(X/36).tickSize(-V,0),s.scale(i)._ticks(X/36).tickSize(Z.length?0:-V,0),db.select(".nv-context .nv-y3.nv-axis").style("opacity",Z.length?1:0).attr("transform","translate(0,"+e.range()[0]+")"),db.select(".nv-context .nv-y2.nv-axis").style("opacity",$.length?1:0).attr("transform","translate("+e.range()[1]+",0)"),db.select(".nv-context .nv-y1.nv-axis").transition().call(r),db.select(".nv-context .nv-y2.nv-axis").transition().call(s)),u.x(e).on("brush",T),I&&u.extent(I);var kb=db.select(".nv-brushBackground").selectAll("g").data([I||u.extent()]),lb=kb.enter().append("g");lb.append("rect").attr("class","left").attr("x",0).attr("y",0).attr("height",X),lb.append("rect").attr("class","right").attr("x",0).attr("y",0).attr("height",X);var mb=db.select(".nv-x.nv-brush").call(u);mb.selectAll("rect").attr("height",X),mb.selectAll(".resize").append("path").attr("d",J),t.dispatch.on("stateChange",function(a){for(var c in a)M[c]=a[c];K.stateChange(M),b.update()}),K.on("changeState",function(a){"undefined"!=typeof a.disabled&&(v.forEach(function(b,c){b.disabled=a.disabled[c]}),M.disabled=a.disabled),b.update()}),T()}),b}var c,d,e,f,g,h,i,j=a.models.line(),k=a.models.line(),l=a.models.historicalBar(),m=a.models.historicalBar(),n=a.models.axis(),o=a.models.axis(),p=a.models.axis(),q=a.models.axis(),r=a.models.axis(),s=a.models.axis(),t=a.models.legend(),u=d3.svg.brush(),v=a.models.tooltip(),w={top:30,right:30,bottom:30,left:60},x={top:0,right:30,bottom:20,left:60},y=null,z=null,A=function(a){return a.x},B=function(a){return a.y},C=a.utils.defaultColor(),D=!0,E=!0,F=!1,G=!0,H=50,I=null,J=null,K=d3.dispatch("brush","stateChange","changeState"),L=0,M=a.utils.state(),N=null,O=" (left axis)",P=" (right axis)";j.clipEdge(!0),k.interactive(!1),n.orient("bottom").tickPadding(5),p.orient("left"),q.orient("right"),o.orient("bottom").tickPadding(5),r.orient("left"),s.orient("right"),v.headerEnabled(!0).headerFormatter(function(a,b){return n.tickFormat()(a,b)});var Q=function(a){return function(){return{active:a.map(function(a){return!a.disabled})}}},R=function(a){return function(b){void 0!==b.active&&a.forEach(function(a,c){a.disabled=!b.active[c]})}};return j.dispatch.on("elementMouseover.tooltip",function(a){v.duration(100).valueFormatter(function(a,b){return q.tickFormat()(a,b)}).data(a).position(a.pos).hidden(!1)}),j.dispatch.on("elementMouseout.tooltip",function(){v.hidden(!0)}),l.dispatch.on("elementMouseover.tooltip",function(a){a.value=b.x()(a.data),a.series={value:b.y()(a.data),color:a.color},v.duration(0).valueFormatter(function(a,b){return p.tickFormat()(a,b)}).data(a).hidden(!1)}),l.dispatch.on("elementMouseout.tooltip",function(){v.hidden(!0)}),l.dispatch.on("elementMousemove.tooltip",function(){v.position({top:d3.event.pageY,left:d3.event.pageX})()}),b.dispatch=K,b.legend=t,b.lines=j,b.lines2=k,b.bars=l,b.bars2=m,b.xAxis=n,b.x2Axis=o,b.y1Axis=p,b.y2Axis=q,b.y3Axis=r,b.y4Axis=s,b.tooltip=v,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return y},set:function(a){y=a}},height:{get:function(){return z},set:function(a){z=a}},showLegend:{get:function(){return D},set:function(a){D=a}},brushExtent:{get:function(){return I},set:function(a){I=a}},noData:{get:function(){return J},set:function(a){J=a}},focusEnable:{get:function(){return E},set:function(a){E=a}},focusHeight:{get:function(){return H},set:function(a){H=a}},focusShowAxisX:{get:function(){return G},set:function(a){G=a}},focusShowAxisY:{get:function(){return F},set:function(a){F=a}},legendLeftAxisHint:{get:function(){return O},set:function(a){O=a}},legendRightAxisHint:{get:function(){return P},set:function(a){P=a}},tooltips:{get:function(){return v.enabled()},set:function(b){a.deprecated("tooltips","use chart.tooltip.enabled() instead"),v.enabled(!!b)}},tooltipContent:{get:function(){return v.contentGenerator()},set:function(b){a.deprecated("tooltipContent","use chart.tooltip.contentGenerator() instead"),v.contentGenerator(b)}},margin:{get:function(){return w},set:function(a){w.top=void 0!==a.top?a.top:w.top,w.right=void 0!==a.right?a.right:w.right,w.bottom=void 0!==a.bottom?a.bottom:w.bottom,w.left=void 0!==a.left?a.left:w.left}},duration:{get:function(){return L},set:function(a){L=a}},color:{get:function(){return C},set:function(b){C=a.utils.getColor(b),t.color(C)}},x:{get:function(){return A},set:function(a){A=a,j.x(a),k.x(a),l.x(a),m.x(a)}},y:{get:function(){return B},set:function(a){B=a,j.y(a),k.y(a),l.y(a),m.y(a)}}}),a.utils.inheritOptions(b,j),a.utils.initOptions(b),b},a.models.lineWithFocusChart=function(){"use strict";function b(o){return o.each(function(o){function z(a){var b=+("e"==a),c=b?1:-1,d=M/3;return"M"+.5*c+","+d+"A6,6 0 0 "+b+" "+6.5*c+","+(d+6)+"V"+(2*d-6)+"A6,6 0 0 "+b+" "+.5*c+","+2*d+"ZM"+2.5*c+","+(d+8)+"V"+(2*d-8)+"M"+4.5*c+","+(d+8)+"V"+(2*d-8)}function G(){n.empty()||n.extent(y),U.data([n.empty()?e.domain():y]).each(function(a){var b=e(a[0])-c.range()[0],d=K-e(a[1]);d3.select(this).select(".left").attr("width",0>b?0:b),d3.select(this).select(".right").attr("x",e(a[1])).attr("width",0>d?0:d)})}function H(){y=n.empty()?null:n.extent();var a=n.empty()?e.domain():n.extent();if(!(Math.abs(a[0]-a[1])<=1)){A.brush({extent:a,brush:n}),G();var b=Q.select(".nv-focus .nv-linesWrap").datum(o.filter(function(a){return!a.disabled}).map(function(b){return{key:b.key,area:b.area,values:b.values.filter(function(b,c){return g.x()(b,c)>=a[0]&&g.x()(b,c)<=a[1]})}}));b.transition().duration(B).call(g),Q.select(".nv-focus .nv-x.nv-axis").transition().duration(B).call(i),Q.select(".nv-focus .nv-y.nv-axis").transition().duration(B).call(j)}}var I=d3.select(this),J=this;a.utils.initSVG(I);var K=a.utils.availableWidth(t,I,q),L=a.utils.availableHeight(u,I,q)-v,M=v-r.top-r.bottom;if(b.update=function(){I.transition().duration(B).call(b)},b.container=this,C.setter(F(o),b.update).getter(E(o)).update(),C.disabled=o.map(function(a){return!!a.disabled}),!D){var N;D={};for(N in C)D[N]=C[N]instanceof Array?C[N].slice(0):C[N]}if(!(o&&o.length&&o.filter(function(a){return a.values.length}).length))return a.utils.noData(b,I),b;I.selectAll(".nv-noData").remove(),c=g.xScale(),d=g.yScale(),e=h.xScale(),f=h.yScale();var O=I.selectAll("g.nv-wrap.nv-lineWithFocusChart").data([o]),P=O.enter().append("g").attr("class","nvd3 nv-wrap nv-lineWithFocusChart").append("g"),Q=O.select("g");P.append("g").attr("class","nv-legendWrap");var R=P.append("g").attr("class","nv-focus");R.append("g").attr("class","nv-x nv-axis"),R.append("g").attr("class","nv-y nv-axis"),R.append("g").attr("class","nv-linesWrap"),R.append("g").attr("class","nv-interactive");var S=P.append("g").attr("class","nv-context");S.append("g").attr("class","nv-x nv-axis"),S.append("g").attr("class","nv-y nv-axis"),S.append("g").attr("class","nv-linesWrap"),S.append("g").attr("class","nv-brushBackground"),S.append("g").attr("class","nv-x nv-brush"),x&&(m.width(K),Q.select(".nv-legendWrap").datum(o).call(m),q.top!=m.height()&&(q.top=m.height(),L=a.utils.availableHeight(u,I,q)-v),Q.select(".nv-legendWrap").attr("transform","translate(0,"+-q.top+")")),O.attr("transform","translate("+q.left+","+q.top+")"),w&&(p.width(K).height(L).margin({left:q.left,top:q.top}).svgContainer(I).xScale(c),O.select(".nv-interactive").call(p)),g.width(K).height(L).color(o.map(function(a,b){return a.color||s(a,b)}).filter(function(a,b){return!o[b].disabled})),h.defined(g.defined()).width(K).height(M).color(o.map(function(a,b){return a.color||s(a,b)}).filter(function(a,b){return!o[b].disabled})),Q.select(".nv-context").attr("transform","translate(0,"+(L+q.bottom+r.top)+")");var T=Q.select(".nv-context .nv-linesWrap").datum(o.filter(function(a){return!a.disabled}));d3.transition(T).call(h),i.scale(c)._ticks(a.utils.calcTicksX(K/100,o)).tickSize(-L,0),j.scale(d)._ticks(a.utils.calcTicksY(L/36,o)).tickSize(-K,0),Q.select(".nv-focus .nv-x.nv-axis").attr("transform","translate(0,"+L+")"),n.x(e).on("brush",function(){H()}),y&&n.extent(y);var U=Q.select(".nv-brushBackground").selectAll("g").data([y||n.extent()]),V=U.enter().append("g");V.append("rect").attr("class","left").attr("x",0).attr("y",0).attr("height",M),V.append("rect").attr("class","right").attr("x",0).attr("y",0).attr("height",M);var W=Q.select(".nv-x.nv-brush").call(n);W.selectAll("rect").attr("height",M),W.selectAll(".resize").append("path").attr("d",z),H(),k.scale(e)._ticks(a.utils.calcTicksX(K/100,o)).tickSize(-M,0),Q.select(".nv-context .nv-x.nv-axis").attr("transform","translate(0,"+f.range()[0]+")"),d3.transition(Q.select(".nv-context .nv-x.nv-axis")).call(k),l.scale(f)._ticks(a.utils.calcTicksY(M/36,o)).tickSize(-K,0),d3.transition(Q.select(".nv-context .nv-y.nv-axis")).call(l),Q.select(".nv-context .nv-x.nv-axis").attr("transform","translate(0,"+f.range()[0]+")"),m.dispatch.on("stateChange",function(a){for(var c in a)C[c]=a[c];A.stateChange(C),b.update()}),p.dispatch.on("elementMousemove",function(c){g.clearHighlights();var d,f,h,k=[];if(o.filter(function(a,b){return a.seriesIndex=b,!a.disabled}).forEach(function(i,j){var l=n.empty()?e.domain():n.extent(),m=i.values.filter(function(a,b){return g.x()(a,b)>=l[0]&&g.x()(a,b)<=l[1]});f=a.interactiveBisect(m,c.pointXValue,g.x());var o=m[f],p=b.y()(o,f);null!=p&&g.highlightPoint(j,f,!0),void 0!==o&&(void 0===d&&(d=o),void 0===h&&(h=b.xScale()(b.x()(o,f))),k.push({key:i.key,value:b.y()(o,f),color:s(i,i.seriesIndex)}))}),k.length>2){var l=b.yScale().invert(c.mouseY),m=Math.abs(b.yScale().domain()[0]-b.yScale().domain()[1]),r=.03*m,t=a.nearestValueIndex(k.map(function(a){return a.value}),l,r);null!==t&&(k[t].highlight=!0)}var u=i.tickFormat()(b.x()(d,f));p.tooltip.position({left:c.mouseX+q.left,top:c.mouseY+q.top}).chartContainer(J.parentNode).valueFormatter(function(a){return null==a?"N/A":j.tickFormat()(a)}).data({value:u,index:f,series:k})(),p.renderGuideLine(h)}),p.dispatch.on("elementMouseout",function(){g.clearHighlights()}),A.on("changeState",function(a){"undefined"!=typeof a.disabled&&o.forEach(function(b,c){b.disabled=a.disabled[c]}),b.update()})}),b}var c,d,e,f,g=a.models.line(),h=a.models.line(),i=a.models.axis(),j=a.models.axis(),k=a.models.axis(),l=a.models.axis(),m=a.models.legend(),n=d3.svg.brush(),o=a.models.tooltip(),p=a.interactiveGuideline(),q={top:30,right:30,bottom:30,left:60},r={top:0,right:30,bottom:20,left:60},s=a.utils.defaultColor(),t=null,u=null,v=50,w=!1,x=!0,y=null,z=null,A=d3.dispatch("brush","stateChange","changeState"),B=250,C=a.utils.state(),D=null;g.clipEdge(!0).duration(0),h.interactive(!1),i.orient("bottom").tickPadding(5),j.orient("left"),k.orient("bottom").tickPadding(5),l.orient("left"),o.valueFormatter(function(a,b){return j.tickFormat()(a,b)}).headerFormatter(function(a,b){return i.tickFormat()(a,b)});var E=function(a){return function(){return{active:a.map(function(a){return!a.disabled})}}},F=function(a){return function(b){void 0!==b.active&&a.forEach(function(a,c){a.disabled=!b.active[c]})}};return g.dispatch.on("elementMouseover.tooltip",function(a){o.data(a).position(a.pos).hidden(!1)}),g.dispatch.on("elementMouseout.tooltip",function(){o.hidden(!0)}),b.dispatch=A,b.legend=m,b.lines=g,b.lines2=h,b.xAxis=i,b.yAxis=j,b.x2Axis=k,b.y2Axis=l,b.interactiveLayer=p,b.tooltip=o,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return t},set:function(a){t=a}},height:{get:function(){return u},set:function(a){u=a}},focusHeight:{get:function(){return v},set:function(a){v=a}},showLegend:{get:function(){return x},set:function(a){x=a}},brushExtent:{get:function(){return y},set:function(a){y=a}},defaultState:{get:function(){return D},set:function(a){D=a}},noData:{get:function(){return z},set:function(a){z=a}},tooltips:{get:function(){return o.enabled()},set:function(b){a.deprecated("tooltips","use chart.tooltip.enabled() instead"),o.enabled(!!b)}},tooltipContent:{get:function(){return o.contentGenerator()},set:function(b){a.deprecated("tooltipContent","use chart.tooltip.contentGenerator() instead"),o.contentGenerator(b)}},margin:{get:function(){return q},set:function(a){q.top=void 0!==a.top?a.top:q.top,q.right=void 0!==a.right?a.right:q.right,q.bottom=void 0!==a.bottom?a.bottom:q.bottom,q.left=void 0!==a.left?a.left:q.left}},color:{get:function(){return s},set:function(b){s=a.utils.getColor(b),m.color(s)}},interpolate:{get:function(){return g.interpolate()},set:function(a){g.interpolate(a),h.interpolate(a)}},xTickFormat:{get:function(){return i.tickFormat()},set:function(a){i.tickFormat(a),k.tickFormat(a)}},yTickFormat:{get:function(){return j.tickFormat()},set:function(a){j.tickFormat(a),l.tickFormat(a)}},duration:{get:function(){return B},set:function(a){B=a,j.duration(B),l.duration(B),i.duration(B),k.duration(B)}},x:{get:function(){return g.x()},set:function(a){g.x(a),h.x(a)}},y:{get:function(){return g.y()},set:function(a){g.y(a),h.y(a)}},useInteractiveGuideline:{get:function(){return w},set:function(a){w=a,w&&(g.interactive(!1),g.useVoronoi(!1))}}}),a.utils.inheritOptions(b,g),a.utils.initOptions(b),b},a.models.multiBar=function(){"use strict";function b(E){return C.reset(),E.each(function(b){var E=k-j.left-j.right,F=l-j.top-j.bottom;p=d3.select(this),a.utils.initSVG(p);var G=0;if(x&&b.length&&(x=[{values:b[0].values.map(function(a){return{x:a.x,y:0,series:a.series,size:.01}})}]),u){var H=d3.layout.stack().offset(v).values(function(a){return a.values}).y(r)(!b.length&&x?x:b);H.forEach(function(a,c){a.nonStackable?(b[c].nonStackableSeries=G++,H[c]=b[c]):c>0&&H[c-1].nonStackable&&H[c].values.map(function(a,b){a.y0-=H[c-1].values[b].y,a.y1=a.y0+a.y})}),b=H}b.forEach(function(a,b){a.values.forEach(function(c){c.series=b,c.key=a.key})}),u&&b[0].values.map(function(a,c){var d=0,e=0;b.map(function(a,f){if(!b[f].nonStackable){var g=a.values[c];g.size=Math.abs(g.y),g.y<0?(g.y1=e,e-=g.size):(g.y1=g.size+d,d+=g.size)}})});var I=d&&e?[]:b.map(function(a,b){return a.values.map(function(a,c){return{x:q(a,c),y:r(a,c),y0:a.y0,y1:a.y1,idx:b}})});m.domain(d||d3.merge(I).map(function(a){return a.x})).rangeBands(f||[0,E],A),n.domain(e||d3.extent(d3.merge(I).map(function(a){var c=a.y;return u&&!b[a.idx].nonStackable&&(c=a.y>0?a.y1:a.y1+a.y),c}).concat(s))).range(g||[F,0]),m.domain()[0]===m.domain()[1]&&m.domain(m.domain()[0]?[m.domain()[0]-.01*m.domain()[0],m.domain()[1]+.01*m.domain()[1]]:[-1,1]),n.domain()[0]===n.domain()[1]&&n.domain(n.domain()[0]?[n.domain()[0]+.01*n.domain()[0],n.domain()[1]-.01*n.domain()[1]]:[-1,1]),h=h||m,i=i||n;var J=p.selectAll("g.nv-wrap.nv-multibar").data([b]),K=J.enter().append("g").attr("class","nvd3 nv-wrap nv-multibar"),L=K.append("defs"),M=K.append("g"),N=J.select("g");M.append("g").attr("class","nv-groups"),J.attr("transform","translate("+j.left+","+j.top+")"),L.append("clipPath").attr("id","nv-edge-clip-"+o).append("rect"),J.select("#nv-edge-clip-"+o+" rect").attr("width",E).attr("height",F),N.attr("clip-path",t?"url(#nv-edge-clip-"+o+")":"");var O=J.select(".nv-groups").selectAll(".nv-group").data(function(a){return a},function(a,b){return b});O.enter().append("g").style("stroke-opacity",1e-6).style("fill-opacity",1e-6);var P=C.transition(O.exit().selectAll("rect.nv-bar"),"multibarExit",Math.min(100,z)).attr("y",function(a){var c=i(0)||0;return u&&b[a.series]&&!b[a.series].nonStackable&&(c=i(a.y0)),c}).attr("height",0).remove();P.delay&&P.delay(function(a,b){var c=b*(z/(D+1))-b;return c}),O.attr("class",function(a,b){return"nv-group nv-series-"+b}).classed("hover",function(a){return a.hover}).style("fill",function(a,b){return w(a,b)}).style("stroke",function(a,b){return w(a,b)}),O.style("stroke-opacity",1).style("fill-opacity",.75);var Q=O.selectAll("rect.nv-bar").data(function(a){return x&&!b.length?x.values:a.values});Q.exit().remove();Q.enter().append("rect").attr("class",function(a,b){return r(a,b)<0?"nv-bar negative":"nv-bar positive"}).attr("x",function(a,c,d){return u&&!b[d].nonStackable?0:d*m.rangeBand()/b.length}).attr("y",function(a,c,d){return i(u&&!b[d].nonStackable?a.y0:0)||0}).attr("height",0).attr("width",function(a,c,d){return m.rangeBand()/(u&&!b[d].nonStackable?1:b.length)}).attr("transform",function(a,b){return"translate("+m(q(a,b))+",0)"});Q.style("fill",function(a,b,c){return w(a,c,b)}).style("stroke",function(a,b,c){return w(a,c,b)}).on("mouseover",function(a,b){d3.select(this).classed("hover",!0),B.elementMouseover({data:a,index:b,color:d3.select(this).style("fill")})}).on("mouseout",function(a,b){d3.select(this).classed("hover",!1),B.elementMouseout({data:a,index:b,color:d3.select(this).style("fill")})}).on("mousemove",function(a,b){B.elementMousemove({data:a,index:b,color:d3.select(this).style("fill")})}).on("click",function(a,b){B.elementClick({data:a,index:b,color:d3.select(this).style("fill")}),d3.event.stopPropagation()}).on("dblclick",function(a,b){B.elementDblClick({data:a,index:b,color:d3.select(this).style("fill")}),d3.event.stopPropagation()}),Q.attr("class",function(a,b){return r(a,b)<0?"nv-bar negative":"nv-bar positive"}).attr("transform",function(a,b){return"translate("+m(q(a,b))+",0)"}),y&&(c||(c=b.map(function(){return!0})),Q.style("fill",function(a,b,d){return d3.rgb(y(a,b)).darker(c.map(function(a,b){return b}).filter(function(a,b){return!c[b]})[d]).toString()}).style("stroke",function(a,b,d){return d3.rgb(y(a,b)).darker(c.map(function(a,b){return b}).filter(function(a,b){return!c[b]})[d]).toString()}));var R=Q.watchTransition(C,"multibar",Math.min(250,z)).delay(function(a,c){return c*z/b[0].values.length});u?R.attr("y",function(a,c,d){var e=0;return e=b[d].nonStackable?r(a,c)<0?n(0):n(0)-n(r(a,c))<-1?n(0)-1:n(r(a,c))||0:n(a.y1)}).attr("height",function(a,c,d){return b[d].nonStackable?Math.max(Math.abs(n(r(a,c))-n(0)),1)||0:Math.max(Math.abs(n(a.y+a.y0)-n(a.y0)),1)}).attr("x",function(a,c,d){var e=0;return b[d].nonStackable&&(e=a.series*m.rangeBand()/b.length,b.length!==G&&(e=b[d].nonStackableSeries*m.rangeBand()/(2*G))),e}).attr("width",function(a,c,d){if(b[d].nonStackable){var e=m.rangeBand()/G;return b.length!==G&&(e=m.rangeBand()/(2*G)),e}return m.rangeBand()}):R.attr("x",function(a){return a.series*m.rangeBand()/b.length}).attr("width",m.rangeBand()/b.length).attr("y",function(a,b){return r(a,b)<0?n(0):n(0)-n(r(a,b))<1?n(0)-1:n(r(a,b))||0}).attr("height",function(a,b){return Math.max(Math.abs(n(r(a,b))-n(0)),1)||0}),h=m.copy(),i=n.copy(),b[0]&&b[0].values&&(D=b[0].values.length)}),C.renderEnd("multibar immediate"),b}var c,d,e,f,g,h,i,j={top:0,right:0,bottom:0,left:0},k=960,l=500,m=d3.scale.ordinal(),n=d3.scale.linear(),o=Math.floor(1e4*Math.random()),p=null,q=function(a){return a.x},r=function(a){return a.y},s=[0],t=!0,u=!1,v="zero",w=a.utils.defaultColor(),x=!1,y=null,z=500,A=.1,B=d3.dispatch("chartClick","elementClick","elementDblClick","elementMouseover","elementMouseout","elementMousemove","renderEnd"),C=a.utils.renderWatch(B,z),D=0;return b.dispatch=B,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return k},set:function(a){k=a}},height:{get:function(){return l},set:function(a){l=a}},x:{get:function(){return q},set:function(a){q=a}},y:{get:function(){return r},set:function(a){r=a}},xScale:{get:function(){return m},set:function(a){m=a}},yScale:{get:function(){return n},set:function(a){n=a}},xDomain:{get:function(){return d},set:function(a){d=a}},yDomain:{get:function(){return e},set:function(a){e=a}},xRange:{get:function(){return f},set:function(a){f=a}},yRange:{get:function(){return g},set:function(a){g=a}},forceY:{get:function(){return s},set:function(a){s=a}},stacked:{get:function(){return u},set:function(a){u=a}},stackOffset:{get:function(){return v},set:function(a){v=a}},clipEdge:{get:function(){return t},set:function(a){t=a}},disabled:{get:function(){return c},set:function(a){c=a}},id:{get:function(){return o},set:function(a){o=a}},hideable:{get:function(){return x},set:function(a){x=a}},groupSpacing:{get:function(){return A},set:function(a){A=a}},margin:{get:function(){return j},set:function(a){j.top=void 0!==a.top?a.top:j.top,j.right=void 0!==a.right?a.right:j.right,j.bottom=void 0!==a.bottom?a.bottom:j.bottom,j.left=void 0!==a.left?a.left:j.left}},duration:{get:function(){return z},set:function(a){z=a,C.reset(z)}},color:{get:function(){return w},set:function(b){w=a.utils.getColor(b)}},barColor:{get:function(){return y},set:function(b){y=b?a.utils.getColor(b):null}}}),a.utils.initOptions(b),b},a.models.multiBarChart=function(){"use strict";function b(j){return D.reset(),D.models(e),r&&D.models(f),s&&D.models(g),j.each(function(j){var z=d3.select(this);a.utils.initSVG(z);var D=a.utils.availableWidth(l,z,k),H=a.utils.availableHeight(m,z,k);if(b.update=function(){0===C?z.call(b):z.transition().duration(C).call(b)},b.container=this,x.setter(G(j),b.update).getter(F(j)).update(),x.disabled=j.map(function(a){return!!a.disabled}),!y){var I;y={};for(I in x)y[I]=x[I]instanceof Array?x[I].slice(0):x[I]}if(!(j&&j.length&&j.filter(function(a){return a.values.length}).length))return a.utils.noData(b,z),b;z.selectAll(".nv-noData").remove(),c=e.xScale(),d=e.yScale(); -var J=z.selectAll("g.nv-wrap.nv-multiBarWithLegend").data([j]),K=J.enter().append("g").attr("class","nvd3 nv-wrap nv-multiBarWithLegend").append("g"),L=J.select("g");if(K.append("g").attr("class","nv-x nv-axis"),K.append("g").attr("class","nv-y nv-axis"),K.append("g").attr("class","nv-barsWrap"),K.append("g").attr("class","nv-legendWrap"),K.append("g").attr("class","nv-controlsWrap"),q&&(h.width(D-B()),L.select(".nv-legendWrap").datum(j).call(h),k.top!=h.height()&&(k.top=h.height(),H=a.utils.availableHeight(m,z,k)),L.select(".nv-legendWrap").attr("transform","translate("+B()+","+-k.top+")")),o){var M=[{key:p.grouped||"Grouped",disabled:e.stacked()},{key:p.stacked||"Stacked",disabled:!e.stacked()}];i.width(B()).color(["#444","#444","#444"]),L.select(".nv-controlsWrap").datum(M).attr("transform","translate(0,"+-k.top+")").call(i)}J.attr("transform","translate("+k.left+","+k.top+")"),t&&L.select(".nv-y.nv-axis").attr("transform","translate("+D+",0)"),e.disabled(j.map(function(a){return a.disabled})).width(D).height(H).color(j.map(function(a,b){return a.color||n(a,b)}).filter(function(a,b){return!j[b].disabled}));var N=L.select(".nv-barsWrap").datum(j.filter(function(a){return!a.disabled}));if(N.call(e),r){f.scale(c)._ticks(a.utils.calcTicksX(D/100,j)).tickSize(-H,0),L.select(".nv-x.nv-axis").attr("transform","translate(0,"+d.range()[0]+")"),L.select(".nv-x.nv-axis").call(f);var O=L.select(".nv-x.nv-axis > g").selectAll("g");if(O.selectAll("line, text").style("opacity",1),v){var P=function(a,b){return"translate("+a+","+b+")"},Q=5,R=17;O.selectAll("text").attr("transform",function(a,b,c){return P(0,c%2==0?Q:R)});var S=d3.selectAll(".nv-x.nv-axis .nv-wrap g g text")[0].length;L.selectAll(".nv-x.nv-axis .nv-axisMaxMin text").attr("transform",function(a,b){return P(0,0===b||S%2!==0?R:Q)})}u&&O.filter(function(a,b){return b%Math.ceil(j[0].values.length/(D/100))!==0}).selectAll("text, line").style("opacity",0),w&&O.selectAll(".tick text").attr("transform","rotate("+w+" 0,0)").style("text-anchor",w>0?"start":"end"),L.select(".nv-x.nv-axis").selectAll("g.nv-axisMaxMin text").style("opacity",1)}s&&(g.scale(d)._ticks(a.utils.calcTicksY(H/36,j)).tickSize(-D,0),L.select(".nv-y.nv-axis").call(g)),h.dispatch.on("stateChange",function(a){for(var c in a)x[c]=a[c];A.stateChange(x),b.update()}),i.dispatch.on("legendClick",function(a){if(a.disabled){switch(M=M.map(function(a){return a.disabled=!0,a}),a.disabled=!1,a.key){case"Grouped":case p.grouped:e.stacked(!1);break;case"Stacked":case p.stacked:e.stacked(!0)}x.stacked=e.stacked(),A.stateChange(x),b.update()}}),A.on("changeState",function(a){"undefined"!=typeof a.disabled&&(j.forEach(function(b,c){b.disabled=a.disabled[c]}),x.disabled=a.disabled),"undefined"!=typeof a.stacked&&(e.stacked(a.stacked),x.stacked=a.stacked,E=a.stacked),b.update()})}),D.renderEnd("multibarchart immediate"),b}var c,d,e=a.models.multiBar(),f=a.models.axis(),g=a.models.axis(),h=a.models.legend(),i=a.models.legend(),j=a.models.tooltip(),k={top:30,right:20,bottom:50,left:60},l=null,m=null,n=a.utils.defaultColor(),o=!0,p={},q=!0,r=!0,s=!0,t=!1,u=!0,v=!1,w=0,x=a.utils.state(),y=null,z=null,A=d3.dispatch("stateChange","changeState","renderEnd"),B=function(){return o?180:0},C=250;x.stacked=!1,e.stacked(!1),f.orient("bottom").tickPadding(7).showMaxMin(!1).tickFormat(function(a){return a}),g.orient(t?"right":"left").tickFormat(d3.format(",.1f")),j.duration(0).valueFormatter(function(a,b){return g.tickFormat()(a,b)}).headerFormatter(function(a,b){return f.tickFormat()(a,b)}),i.updateState(!1);var D=a.utils.renderWatch(A),E=!1,F=function(a){return function(){return{active:a.map(function(a){return!a.disabled}),stacked:E}}},G=function(a){return function(b){void 0!==b.stacked&&(E=b.stacked),void 0!==b.active&&a.forEach(function(a,c){a.disabled=!b.active[c]})}};return e.dispatch.on("elementMouseover.tooltip",function(a){a.value=b.x()(a.data),a.series={key:a.data.key,value:b.y()(a.data),color:a.color},j.data(a).hidden(!1)}),e.dispatch.on("elementMouseout.tooltip",function(){j.hidden(!0)}),e.dispatch.on("elementMousemove.tooltip",function(){j.position({top:d3.event.pageY,left:d3.event.pageX})()}),b.dispatch=A,b.multibar=e,b.legend=h,b.controls=i,b.xAxis=f,b.yAxis=g,b.state=x,b.tooltip=j,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return l},set:function(a){l=a}},height:{get:function(){return m},set:function(a){m=a}},showLegend:{get:function(){return q},set:function(a){q=a}},showControls:{get:function(){return o},set:function(a){o=a}},controlLabels:{get:function(){return p},set:function(a){p=a}},showXAxis:{get:function(){return r},set:function(a){r=a}},showYAxis:{get:function(){return s},set:function(a){s=a}},defaultState:{get:function(){return y},set:function(a){y=a}},noData:{get:function(){return z},set:function(a){z=a}},reduceXTicks:{get:function(){return u},set:function(a){u=a}},rotateLabels:{get:function(){return w},set:function(a){w=a}},staggerLabels:{get:function(){return v},set:function(a){v=a}},tooltips:{get:function(){return j.enabled()},set:function(b){a.deprecated("tooltips","use chart.tooltip.enabled() instead"),j.enabled(!!b)}},tooltipContent:{get:function(){return j.contentGenerator()},set:function(b){a.deprecated("tooltipContent","use chart.tooltip.contentGenerator() instead"),j.contentGenerator(b)}},margin:{get:function(){return k},set:function(a){k.top=void 0!==a.top?a.top:k.top,k.right=void 0!==a.right?a.right:k.right,k.bottom=void 0!==a.bottom?a.bottom:k.bottom,k.left=void 0!==a.left?a.left:k.left}},duration:{get:function(){return C},set:function(a){C=a,e.duration(C),f.duration(C),g.duration(C),D.reset(C)}},color:{get:function(){return n},set:function(b){n=a.utils.getColor(b),h.color(n)}},rightAlignYAxis:{get:function(){return t},set:function(a){t=a,g.orient(t?"right":"left")}},barColor:{get:function(){return e.barColor},set:function(a){e.barColor(a),h.color(function(a,b){return d3.rgb("#ccc").darker(1.5*b).toString()})}}}),a.utils.inheritOptions(b,e),a.utils.initOptions(b),b},a.models.multiBarHorizontal=function(){"use strict";function b(m){return E.reset(),m.each(function(b){var m=k-j.left-j.right,C=l-j.top-j.bottom;n=d3.select(this),a.utils.initSVG(n),w&&(b=d3.layout.stack().offset("zero").values(function(a){return a.values}).y(r)(b)),b.forEach(function(a,b){a.values.forEach(function(c){c.series=b,c.key=a.key})}),w&&b[0].values.map(function(a,c){var d=0,e=0;b.map(function(a){var b=a.values[c];b.size=Math.abs(b.y),b.y<0?(b.y1=e-b.size,e-=b.size):(b.y1=d,d+=b.size)})});var F=d&&e?[]:b.map(function(a){return a.values.map(function(a,b){return{x:q(a,b),y:r(a,b),y0:a.y0,y1:a.y1}})});o.domain(d||d3.merge(F).map(function(a){return a.x})).rangeBands(f||[0,C],A),p.domain(e||d3.extent(d3.merge(F).map(function(a){return w?a.y>0?a.y1+a.y:a.y1:a.y}).concat(t))),p.range(x&&!w?g||[p.domain()[0]<0?z:0,m-(p.domain()[1]>0?z:0)]:g||[0,m]),h=h||o,i=i||d3.scale.linear().domain(p.domain()).range([p(0),p(0)]);{var G=d3.select(this).selectAll("g.nv-wrap.nv-multibarHorizontal").data([b]),H=G.enter().append("g").attr("class","nvd3 nv-wrap nv-multibarHorizontal"),I=(H.append("defs"),H.append("g"));G.select("g")}I.append("g").attr("class","nv-groups"),G.attr("transform","translate("+j.left+","+j.top+")");var J=G.select(".nv-groups").selectAll(".nv-group").data(function(a){return a},function(a,b){return b});J.enter().append("g").style("stroke-opacity",1e-6).style("fill-opacity",1e-6),J.exit().watchTransition(E,"multibarhorizontal: exit groups").style("stroke-opacity",1e-6).style("fill-opacity",1e-6).remove(),J.attr("class",function(a,b){return"nv-group nv-series-"+b}).classed("hover",function(a){return a.hover}).style("fill",function(a,b){return u(a,b)}).style("stroke",function(a,b){return u(a,b)}),J.watchTransition(E,"multibarhorizontal: groups").style("stroke-opacity",1).style("fill-opacity",.75);var K=J.selectAll("g.nv-bar").data(function(a){return a.values});K.exit().remove();var L=K.enter().append("g").attr("transform",function(a,c,d){return"translate("+i(w?a.y0:0)+","+(w?0:d*o.rangeBand()/b.length+o(q(a,c)))+")"});L.append("rect").attr("width",0).attr("height",o.rangeBand()/(w?1:b.length)),K.on("mouseover",function(a,b){d3.select(this).classed("hover",!0),D.elementMouseover({data:a,index:b,color:d3.select(this).style("fill")})}).on("mouseout",function(a,b){d3.select(this).classed("hover",!1),D.elementMouseout({data:a,index:b,color:d3.select(this).style("fill")})}).on("mouseout",function(a,b){D.elementMouseout({data:a,index:b,color:d3.select(this).style("fill")})}).on("mousemove",function(a,b){D.elementMousemove({data:a,index:b,color:d3.select(this).style("fill")})}).on("click",function(a,b){D.elementClick({data:a,index:b,color:d3.select(this).style("fill")}),d3.event.stopPropagation()}).on("dblclick",function(a,b){D.elementDblClick({data:a,index:b,color:d3.select(this).style("fill")}),d3.event.stopPropagation()}),s(b[0],0)&&(L.append("polyline"),K.select("polyline").attr("fill","none").attr("points",function(a,c){var d=s(a,c),e=.8*o.rangeBand()/(2*(w?1:b.length));d=d.length?d:[-Math.abs(d),Math.abs(d)],d=d.map(function(a){return p(a)-p(0)});var f=[[d[0],-e],[d[0],e],[d[0],0],[d[1],0],[d[1],-e],[d[1],e]];return f.map(function(a){return a.join(",")}).join(" ")}).attr("transform",function(a,c){var d=o.rangeBand()/(2*(w?1:b.length));return"translate("+(r(a,c)<0?0:p(r(a,c))-p(0))+", "+d+")"})),L.append("text"),x&&!w?(K.select("text").attr("text-anchor",function(a,b){return r(a,b)<0?"end":"start"}).attr("y",o.rangeBand()/(2*b.length)).attr("dy",".32em").text(function(a,b){var c=B(r(a,b)),d=s(a,b);return void 0===d?c:d.length?c+"+"+B(Math.abs(d[1]))+"-"+B(Math.abs(d[0])):c+"±"+B(Math.abs(d))}),K.watchTransition(E,"multibarhorizontal: bars").select("text").attr("x",function(a,b){return r(a,b)<0?-4:p(r(a,b))-p(0)+4})):K.selectAll("text").text(""),y&&!w?(L.append("text").classed("nv-bar-label",!0),K.select("text.nv-bar-label").attr("text-anchor",function(a,b){return r(a,b)<0?"start":"end"}).attr("y",o.rangeBand()/(2*b.length)).attr("dy",".32em").text(function(a,b){return q(a,b)}),K.watchTransition(E,"multibarhorizontal: bars").select("text.nv-bar-label").attr("x",function(a,b){return r(a,b)<0?p(0)-p(r(a,b))+4:-4})):K.selectAll("text.nv-bar-label").text(""),K.attr("class",function(a,b){return r(a,b)<0?"nv-bar negative":"nv-bar positive"}),v&&(c||(c=b.map(function(){return!0})),K.style("fill",function(a,b,d){return d3.rgb(v(a,b)).darker(c.map(function(a,b){return b}).filter(function(a,b){return!c[b]})[d]).toString()}).style("stroke",function(a,b,d){return d3.rgb(v(a,b)).darker(c.map(function(a,b){return b}).filter(function(a,b){return!c[b]})[d]).toString()})),w?K.watchTransition(E,"multibarhorizontal: bars").attr("transform",function(a,b){return"translate("+p(a.y1)+","+o(q(a,b))+")"}).select("rect").attr("width",function(a,b){return Math.abs(p(r(a,b)+a.y0)-p(a.y0))}).attr("height",o.rangeBand()):K.watchTransition(E,"multibarhorizontal: bars").attr("transform",function(a,c){return"translate("+p(r(a,c)<0?r(a,c):0)+","+(a.series*o.rangeBand()/b.length+o(q(a,c)))+")"}).select("rect").attr("height",o.rangeBand()/b.length).attr("width",function(a,b){return Math.max(Math.abs(p(r(a,b))-p(0)),1)}),h=o.copy(),i=p.copy()}),E.renderEnd("multibarHorizontal immediate"),b}var c,d,e,f,g,h,i,j={top:0,right:0,bottom:0,left:0},k=960,l=500,m=Math.floor(1e4*Math.random()),n=null,o=d3.scale.ordinal(),p=d3.scale.linear(),q=function(a){return a.x},r=function(a){return a.y},s=function(a){return a.yErr},t=[0],u=a.utils.defaultColor(),v=null,w=!1,x=!1,y=!1,z=60,A=.1,B=d3.format(",.2f"),C=250,D=d3.dispatch("chartClick","elementClick","elementDblClick","elementMouseover","elementMouseout","elementMousemove","renderEnd"),E=a.utils.renderWatch(D,C);return b.dispatch=D,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return k},set:function(a){k=a}},height:{get:function(){return l},set:function(a){l=a}},x:{get:function(){return q},set:function(a){q=a}},y:{get:function(){return r},set:function(a){r=a}},yErr:{get:function(){return s},set:function(a){s=a}},xScale:{get:function(){return o},set:function(a){o=a}},yScale:{get:function(){return p},set:function(a){p=a}},xDomain:{get:function(){return d},set:function(a){d=a}},yDomain:{get:function(){return e},set:function(a){e=a}},xRange:{get:function(){return f},set:function(a){f=a}},yRange:{get:function(){return g},set:function(a){g=a}},forceY:{get:function(){return t},set:function(a){t=a}},stacked:{get:function(){return w},set:function(a){w=a}},showValues:{get:function(){return x},set:function(a){x=a}},disabled:{get:function(){return c},set:function(a){c=a}},id:{get:function(){return m},set:function(a){m=a}},valueFormat:{get:function(){return B},set:function(a){B=a}},valuePadding:{get:function(){return z},set:function(a){z=a}},groupSpacing:{get:function(){return A},set:function(a){A=a}},margin:{get:function(){return j},set:function(a){j.top=void 0!==a.top?a.top:j.top,j.right=void 0!==a.right?a.right:j.right,j.bottom=void 0!==a.bottom?a.bottom:j.bottom,j.left=void 0!==a.left?a.left:j.left}},duration:{get:function(){return C},set:function(a){C=a,E.reset(C)}},color:{get:function(){return u},set:function(b){u=a.utils.getColor(b)}},barColor:{get:function(){return v},set:function(b){v=b?a.utils.getColor(b):null}}}),a.utils.initOptions(b),b},a.models.multiBarHorizontalChart=function(){"use strict";function b(j){return C.reset(),C.models(e),r&&C.models(f),s&&C.models(g),j.each(function(j){var w=d3.select(this);a.utils.initSVG(w);var C=a.utils.availableWidth(l,w,k),D=a.utils.availableHeight(m,w,k);if(b.update=function(){w.transition().duration(z).call(b)},b.container=this,t=e.stacked(),u.setter(B(j),b.update).getter(A(j)).update(),u.disabled=j.map(function(a){return!!a.disabled}),!v){var E;v={};for(E in u)v[E]=u[E]instanceof Array?u[E].slice(0):u[E]}if(!(j&&j.length&&j.filter(function(a){return a.values.length}).length))return a.utils.noData(b,w),b;w.selectAll(".nv-noData").remove(),c=e.xScale(),d=e.yScale();var F=w.selectAll("g.nv-wrap.nv-multiBarHorizontalChart").data([j]),G=F.enter().append("g").attr("class","nvd3 nv-wrap nv-multiBarHorizontalChart").append("g"),H=F.select("g");if(G.append("g").attr("class","nv-x nv-axis"),G.append("g").attr("class","nv-y nv-axis").append("g").attr("class","nv-zeroLine").append("line"),G.append("g").attr("class","nv-barsWrap"),G.append("g").attr("class","nv-legendWrap"),G.append("g").attr("class","nv-controlsWrap"),q&&(h.width(C-y()),H.select(".nv-legendWrap").datum(j).call(h),k.top!=h.height()&&(k.top=h.height(),D=a.utils.availableHeight(m,w,k)),H.select(".nv-legendWrap").attr("transform","translate("+y()+","+-k.top+")")),o){var I=[{key:p.grouped||"Grouped",disabled:e.stacked()},{key:p.stacked||"Stacked",disabled:!e.stacked()}];i.width(y()).color(["#444","#444","#444"]),H.select(".nv-controlsWrap").datum(I).attr("transform","translate(0,"+-k.top+")").call(i)}F.attr("transform","translate("+k.left+","+k.top+")"),e.disabled(j.map(function(a){return a.disabled})).width(C).height(D).color(j.map(function(a,b){return a.color||n(a,b)}).filter(function(a,b){return!j[b].disabled}));var J=H.select(".nv-barsWrap").datum(j.filter(function(a){return!a.disabled}));if(J.transition().call(e),r){f.scale(c)._ticks(a.utils.calcTicksY(D/24,j)).tickSize(-C,0),H.select(".nv-x.nv-axis").call(f);var K=H.select(".nv-x.nv-axis").selectAll("g");K.selectAll("line, text")}s&&(g.scale(d)._ticks(a.utils.calcTicksX(C/100,j)).tickSize(-D,0),H.select(".nv-y.nv-axis").attr("transform","translate(0,"+D+")"),H.select(".nv-y.nv-axis").call(g)),H.select(".nv-zeroLine line").attr("x1",d(0)).attr("x2",d(0)).attr("y1",0).attr("y2",-D),h.dispatch.on("stateChange",function(a){for(var c in a)u[c]=a[c];x.stateChange(u),b.update()}),i.dispatch.on("legendClick",function(a){if(a.disabled){switch(I=I.map(function(a){return a.disabled=!0,a}),a.disabled=!1,a.key){case"Grouped":e.stacked(!1);break;case"Stacked":e.stacked(!0)}u.stacked=e.stacked(),x.stateChange(u),t=e.stacked(),b.update()}}),x.on("changeState",function(a){"undefined"!=typeof a.disabled&&(j.forEach(function(b,c){b.disabled=a.disabled[c]}),u.disabled=a.disabled),"undefined"!=typeof a.stacked&&(e.stacked(a.stacked),u.stacked=a.stacked,t=a.stacked),b.update()})}),C.renderEnd("multibar horizontal chart immediate"),b}var c,d,e=a.models.multiBarHorizontal(),f=a.models.axis(),g=a.models.axis(),h=a.models.legend().height(30),i=a.models.legend().height(30),j=a.models.tooltip(),k={top:30,right:20,bottom:50,left:60},l=null,m=null,n=a.utils.defaultColor(),o=!0,p={},q=!0,r=!0,s=!0,t=!1,u=a.utils.state(),v=null,w=null,x=d3.dispatch("stateChange","changeState","renderEnd"),y=function(){return o?180:0},z=250;u.stacked=!1,e.stacked(t),f.orient("left").tickPadding(5).showMaxMin(!1).tickFormat(function(a){return a}),g.orient("bottom").tickFormat(d3.format(",.1f")),j.duration(0).valueFormatter(function(a,b){return g.tickFormat()(a,b)}).headerFormatter(function(a,b){return f.tickFormat()(a,b)}),i.updateState(!1);var A=function(a){return function(){return{active:a.map(function(a){return!a.disabled}),stacked:t}}},B=function(a){return function(b){void 0!==b.stacked&&(t=b.stacked),void 0!==b.active&&a.forEach(function(a,c){a.disabled=!b.active[c]})}},C=a.utils.renderWatch(x,z);return e.dispatch.on("elementMouseover.tooltip",function(a){a.value=b.x()(a.data),a.series={key:a.data.key,value:b.y()(a.data),color:a.color},j.data(a).hidden(!1)}),e.dispatch.on("elementMouseout.tooltip",function(){j.hidden(!0)}),e.dispatch.on("elementMousemove.tooltip",function(){j.position({top:d3.event.pageY,left:d3.event.pageX})()}),b.dispatch=x,b.multibar=e,b.legend=h,b.controls=i,b.xAxis=f,b.yAxis=g,b.state=u,b.tooltip=j,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return l},set:function(a){l=a}},height:{get:function(){return m},set:function(a){m=a}},showLegend:{get:function(){return q},set:function(a){q=a}},showControls:{get:function(){return o},set:function(a){o=a}},controlLabels:{get:function(){return p},set:function(a){p=a}},showXAxis:{get:function(){return r},set:function(a){r=a}},showYAxis:{get:function(){return s},set:function(a){s=a}},defaultState:{get:function(){return v},set:function(a){v=a}},noData:{get:function(){return w},set:function(a){w=a}},tooltips:{get:function(){return j.enabled()},set:function(b){a.deprecated("tooltips","use chart.tooltip.enabled() instead"),j.enabled(!!b)}},tooltipContent:{get:function(){return j.contentGenerator()},set:function(b){a.deprecated("tooltipContent","use chart.tooltip.contentGenerator() instead"),j.contentGenerator(b)}},margin:{get:function(){return k},set:function(a){k.top=void 0!==a.top?a.top:k.top,k.right=void 0!==a.right?a.right:k.right,k.bottom=void 0!==a.bottom?a.bottom:k.bottom,k.left=void 0!==a.left?a.left:k.left}},duration:{get:function(){return z},set:function(a){z=a,C.reset(z),e.duration(z),f.duration(z),g.duration(z)}},color:{get:function(){return n},set:function(b){n=a.utils.getColor(b),h.color(n)}},barColor:{get:function(){return e.barColor},set:function(a){e.barColor(a),h.color(function(a,b){return d3.rgb("#ccc").darker(1.5*b).toString()})}}}),a.utils.inheritOptions(b,e),a.utils.initOptions(b),b},a.models.multiChart=function(){"use strict";function b(j){return j.each(function(j){function k(a){var b=2===j[a.seriesIndex].yAxis?z:y;a.value=a.point.x,a.series={value:a.point.y,color:a.point.color},B.duration(100).valueFormatter(function(a,c){return b.tickFormat()(a,c)}).data(a).position(a.pos).hidden(!1)}function l(a){var b=2===j[a.seriesIndex].yAxis?z:y;a.point.x=v.x()(a.point),a.point.y=v.y()(a.point),B.duration(100).valueFormatter(function(a,c){return b.tickFormat()(a,c)}).data(a).position(a.pos).hidden(!1)}function n(a){var b=2===j[a.data.series].yAxis?z:y;a.value=t.x()(a.data),a.series={value:t.y()(a.data),color:a.color},B.duration(0).valueFormatter(function(a,c){return b.tickFormat()(a,c)}).data(a).hidden(!1)}var C=d3.select(this);a.utils.initSVG(C),b.update=function(){C.transition().call(b)},b.container=this;var D=a.utils.availableWidth(g,C,e),E=a.utils.availableHeight(h,C,e),F=j.filter(function(a){return"line"==a.type&&1==a.yAxis}),G=j.filter(function(a){return"line"==a.type&&2==a.yAxis}),H=j.filter(function(a){return"bar"==a.type&&1==a.yAxis}),I=j.filter(function(a){return"bar"==a.type&&2==a.yAxis}),J=j.filter(function(a){return"area"==a.type&&1==a.yAxis}),K=j.filter(function(a){return"area"==a.type&&2==a.yAxis});if(!(j&&j.length&&j.filter(function(a){return a.values.length}).length))return a.utils.noData(b,C),b;C.selectAll(".nv-noData").remove();var L=j.filter(function(a){return!a.disabled&&1==a.yAxis}).map(function(a){return a.values.map(function(a){return{x:a.x,y:a.y}})}),M=j.filter(function(a){return!a.disabled&&2==a.yAxis}).map(function(a){return a.values.map(function(a){return{x:a.x,y:a.y}})});o.domain(d3.extent(d3.merge(L.concat(M)),function(a){return a.x})).range([0,D]);var N=C.selectAll("g.wrap.multiChart").data([j]),O=N.enter().append("g").attr("class","wrap nvd3 multiChart").append("g");O.append("g").attr("class","nv-x nv-axis"),O.append("g").attr("class","nv-y1 nv-axis"),O.append("g").attr("class","nv-y2 nv-axis"),O.append("g").attr("class","lines1Wrap"),O.append("g").attr("class","lines2Wrap"),O.append("g").attr("class","bars1Wrap"),O.append("g").attr("class","bars2Wrap"),O.append("g").attr("class","stack1Wrap"),O.append("g").attr("class","stack2Wrap"),O.append("g").attr("class","legendWrap");var P=N.select("g"),Q=j.map(function(a,b){return j[b].color||f(a,b)});if(i){var R=A.align()?D/2:D,S=A.align()?R:0;A.width(R),A.color(Q),P.select(".legendWrap").datum(j.map(function(a){return a.originalKey=void 0===a.originalKey?a.key:a.originalKey,a.key=a.originalKey+(1==a.yAxis?"":" (right axis)"),a})).call(A),e.top!=A.height()&&(e.top=A.height(),E=a.utils.availableHeight(h,C,e)),P.select(".legendWrap").attr("transform","translate("+S+","+-e.top+")")}r.width(D).height(E).interpolate(m).color(Q.filter(function(a,b){return!j[b].disabled&&1==j[b].yAxis&&"line"==j[b].type})),s.width(D).height(E).interpolate(m).color(Q.filter(function(a,b){return!j[b].disabled&&2==j[b].yAxis&&"line"==j[b].type})),t.width(D).height(E).color(Q.filter(function(a,b){return!j[b].disabled&&1==j[b].yAxis&&"bar"==j[b].type})),u.width(D).height(E).color(Q.filter(function(a,b){return!j[b].disabled&&2==j[b].yAxis&&"bar"==j[b].type})),v.width(D).height(E).color(Q.filter(function(a,b){return!j[b].disabled&&1==j[b].yAxis&&"area"==j[b].type})),w.width(D).height(E).color(Q.filter(function(a,b){return!j[b].disabled&&2==j[b].yAxis&&"area"==j[b].type})),P.attr("transform","translate("+e.left+","+e.top+")");var T=P.select(".lines1Wrap").datum(F.filter(function(a){return!a.disabled})),U=P.select(".bars1Wrap").datum(H.filter(function(a){return!a.disabled})),V=P.select(".stack1Wrap").datum(J.filter(function(a){return!a.disabled})),W=P.select(".lines2Wrap").datum(G.filter(function(a){return!a.disabled})),X=P.select(".bars2Wrap").datum(I.filter(function(a){return!a.disabled})),Y=P.select(".stack2Wrap").datum(K.filter(function(a){return!a.disabled})),Z=J.length?J.map(function(a){return a.values}).reduce(function(a,b){return a.map(function(a,c){return{x:a.x,y:a.y+b[c].y}})}).concat([{x:0,y:0}]):[],$=K.length?K.map(function(a){return a.values}).reduce(function(a,b){return a.map(function(a,c){return{x:a.x,y:a.y+b[c].y}})}).concat([{x:0,y:0}]):[];p.domain(c||d3.extent(d3.merge(L).concat(Z),function(a){return a.y})).range([0,E]),q.domain(d||d3.extent(d3.merge(M).concat($),function(a){return a.y})).range([0,E]),r.yDomain(p.domain()),t.yDomain(p.domain()),v.yDomain(p.domain()),s.yDomain(q.domain()),u.yDomain(q.domain()),w.yDomain(q.domain()),J.length&&d3.transition(V).call(v),K.length&&d3.transition(Y).call(w),H.length&&d3.transition(U).call(t),I.length&&d3.transition(X).call(u),F.length&&d3.transition(T).call(r),G.length&&d3.transition(W).call(s),x._ticks(a.utils.calcTicksX(D/100,j)).tickSize(-E,0),P.select(".nv-x.nv-axis").attr("transform","translate(0,"+E+")"),d3.transition(P.select(".nv-x.nv-axis")).call(x),y._ticks(a.utils.calcTicksY(E/36,j)).tickSize(-D,0),d3.transition(P.select(".nv-y1.nv-axis")).call(y),z._ticks(a.utils.calcTicksY(E/36,j)).tickSize(-D,0),d3.transition(P.select(".nv-y2.nv-axis")).call(z),P.select(".nv-y1.nv-axis").classed("nv-disabled",L.length?!1:!0).attr("transform","translate("+o.range()[0]+",0)"),P.select(".nv-y2.nv-axis").classed("nv-disabled",M.length?!1:!0).attr("transform","translate("+o.range()[1]+",0)"),A.dispatch.on("stateChange",function(){b.update()}),r.dispatch.on("elementMouseover.tooltip",k),s.dispatch.on("elementMouseover.tooltip",k),r.dispatch.on("elementMouseout.tooltip",function(){B.hidden(!0)}),s.dispatch.on("elementMouseout.tooltip",function(){B.hidden(!0)}),v.dispatch.on("elementMouseover.tooltip",l),w.dispatch.on("elementMouseover.tooltip",l),v.dispatch.on("elementMouseout.tooltip",function(){B.hidden(!0)}),w.dispatch.on("elementMouseout.tooltip",function(){B.hidden(!0)}),t.dispatch.on("elementMouseover.tooltip",n),u.dispatch.on("elementMouseover.tooltip",n),t.dispatch.on("elementMouseout.tooltip",function(){B.hidden(!0)}),u.dispatch.on("elementMouseout.tooltip",function(){B.hidden(!0)}),t.dispatch.on("elementMousemove.tooltip",function(){B.position({top:d3.event.pageY,left:d3.event.pageX})()}),u.dispatch.on("elementMousemove.tooltip",function(){B.position({top:d3.event.pageY,left:d3.event.pageX})()})}),b}var c,d,e={top:30,right:20,bottom:50,left:60},f=a.utils.defaultColor(),g=null,h=null,i=!0,j=null,k=function(a){return a.x},l=function(a){return a.y},m="monotone",n=!0,o=d3.scale.linear(),p=d3.scale.linear(),q=d3.scale.linear(),r=a.models.line().yScale(p),s=a.models.line().yScale(q),t=a.models.multiBar().stacked(!1).yScale(p),u=a.models.multiBar().stacked(!1).yScale(q),v=a.models.stackedArea().yScale(p),w=a.models.stackedArea().yScale(q),x=a.models.axis().scale(o).orient("bottom").tickPadding(5),y=a.models.axis().scale(p).orient("left"),z=a.models.axis().scale(q).orient("right"),A=a.models.legend().height(30),B=a.models.tooltip(),C=d3.dispatch();return b.dispatch=C,b.lines1=r,b.lines2=s,b.bars1=t,b.bars2=u,b.stack1=v,b.stack2=w,b.xAxis=x,b.yAxis1=y,b.yAxis2=z,b.tooltip=B,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return g},set:function(a){g=a}},height:{get:function(){return h},set:function(a){h=a}},showLegend:{get:function(){return i},set:function(a){i=a}},yDomain1:{get:function(){return c},set:function(a){c=a}},yDomain2:{get:function(){return d},set:function(a){d=a}},noData:{get:function(){return j},set:function(a){j=a}},interpolate:{get:function(){return m},set:function(a){m=a}},tooltips:{get:function(){return B.enabled()},set:function(b){a.deprecated("tooltips","use chart.tooltip.enabled() instead"),B.enabled(!!b)}},tooltipContent:{get:function(){return B.contentGenerator()},set:function(b){a.deprecated("tooltipContent","use chart.tooltip.contentGenerator() instead"),B.contentGenerator(b)}},margin:{get:function(){return e},set:function(a){e.top=void 0!==a.top?a.top:e.top,e.right=void 0!==a.right?a.right:e.right,e.bottom=void 0!==a.bottom?a.bottom:e.bottom,e.left=void 0!==a.left?a.left:e.left}},color:{get:function(){return f},set:function(b){f=a.utils.getColor(b)}},x:{get:function(){return k},set:function(a){k=a,r.x(a),s.x(a),t.x(a),u.x(a),v.x(a),w.x(a)}},y:{get:function(){return l},set:function(a){l=a,r.y(a),s.y(a),v.y(a),w.y(a),t.y(a),u.y(a)}},useVoronoi:{get:function(){return n},set:function(a){n=a,r.useVoronoi(a),s.useVoronoi(a),v.useVoronoi(a),w.useVoronoi(a)}}}),a.utils.initOptions(b),b},a.models.ohlcBar=function(){"use strict";function b(y){return y.each(function(b){k=d3.select(this);var y=a.utils.availableWidth(h,k,g),A=a.utils.availableHeight(i,k,g);a.utils.initSVG(k);var B=y/b[0].values.length*.9;l.domain(c||d3.extent(b[0].values.map(n).concat(t))),l.range(v?e||[.5*y/b[0].values.length,y*(b[0].values.length-.5)/b[0].values.length]:e||[5+B/2,y-B/2-5]),m.domain(d||[d3.min(b[0].values.map(s).concat(u)),d3.max(b[0].values.map(r).concat(u))]).range(f||[A,0]),l.domain()[0]===l.domain()[1]&&l.domain(l.domain()[0]?[l.domain()[0]-.01*l.domain()[0],l.domain()[1]+.01*l.domain()[1]]:[-1,1]),m.domain()[0]===m.domain()[1]&&m.domain(m.domain()[0]?[m.domain()[0]+.01*m.domain()[0],m.domain()[1]-.01*m.domain()[1]]:[-1,1]);var C=d3.select(this).selectAll("g.nv-wrap.nv-ohlcBar").data([b[0].values]),D=C.enter().append("g").attr("class","nvd3 nv-wrap nv-ohlcBar"),E=D.append("defs"),F=D.append("g"),G=C.select("g");F.append("g").attr("class","nv-ticks"),C.attr("transform","translate("+g.left+","+g.top+")"),k.on("click",function(a,b){z.chartClick({data:a,index:b,pos:d3.event,id:j})}),E.append("clipPath").attr("id","nv-chart-clip-path-"+j).append("rect"),C.select("#nv-chart-clip-path-"+j+" rect").attr("width",y).attr("height",A),G.attr("clip-path",w?"url(#nv-chart-clip-path-"+j+")":"");var H=C.select(".nv-ticks").selectAll(".nv-tick").data(function(a){return a});H.exit().remove(),H.enter().append("path").attr("class",function(a,b,c){return(p(a,b)>q(a,b)?"nv-tick negative":"nv-tick positive")+" nv-tick-"+c+"-"+b}).attr("d",function(a,b){return"m0,0l0,"+(m(p(a,b))-m(r(a,b)))+"l"+-B/2+",0l"+B/2+",0l0,"+(m(s(a,b))-m(p(a,b)))+"l0,"+(m(q(a,b))-m(s(a,b)))+"l"+B/2+",0l"+-B/2+",0z"}).attr("transform",function(a,b){return"translate("+l(n(a,b))+","+m(r(a,b))+")"}).attr("fill",function(){return x[0]}).attr("stroke",function(){return x[0]}).attr("x",0).attr("y",function(a,b){return m(Math.max(0,o(a,b)))}).attr("height",function(a,b){return Math.abs(m(o(a,b))-m(0))}),H.attr("class",function(a,b,c){return(p(a,b)>q(a,b)?"nv-tick negative":"nv-tick positive")+" nv-tick-"+c+"-"+b}),d3.transition(H).attr("transform",function(a,b){return"translate("+l(n(a,b))+","+m(r(a,b))+")"}).attr("d",function(a,c){var d=y/b[0].values.length*.9;return"m0,0l0,"+(m(p(a,c))-m(r(a,c)))+"l"+-d/2+",0l"+d/2+",0l0,"+(m(s(a,c))-m(p(a,c)))+"l0,"+(m(q(a,c))-m(s(a,c)))+"l"+d/2+",0l"+-d/2+",0z"})}),b}var c,d,e,f,g={top:0,right:0,bottom:0,left:0},h=null,i=null,j=Math.floor(1e4*Math.random()),k=null,l=d3.scale.linear(),m=d3.scale.linear(),n=function(a){return a.x},o=function(a){return a.y},p=function(a){return a.open},q=function(a){return a.close},r=function(a){return a.high},s=function(a){return a.low},t=[],u=[],v=!1,w=!0,x=a.utils.defaultColor(),y=!1,z=d3.dispatch("tooltipShow","tooltipHide","stateChange","changeState","renderEnd","chartClick","elementClick","elementDblClick","elementMouseover","elementMouseout","elementMousemove");return b.highlightPoint=function(a,c){b.clearHighlights(),k.select(".nv-ohlcBar .nv-tick-0-"+a).classed("hover",c)},b.clearHighlights=function(){k.select(".nv-ohlcBar .nv-tick.hover").classed("hover",!1)},b.dispatch=z,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return h},set:function(a){h=a}},height:{get:function(){return i},set:function(a){i=a}},xScale:{get:function(){return l},set:function(a){l=a}},yScale:{get:function(){return m},set:function(a){m=a}},xDomain:{get:function(){return c},set:function(a){c=a}},yDomain:{get:function(){return d},set:function(a){d=a}},xRange:{get:function(){return e},set:function(a){e=a}},yRange:{get:function(){return f},set:function(a){f=a}},forceX:{get:function(){return t},set:function(a){t=a}},forceY:{get:function(){return u},set:function(a){u=a}},padData:{get:function(){return v},set:function(a){v=a}},clipEdge:{get:function(){return w},set:function(a){w=a}},id:{get:function(){return j},set:function(a){j=a}},interactive:{get:function(){return y},set:function(a){y=a}},x:{get:function(){return n},set:function(a){n=a}},y:{get:function(){return o},set:function(a){o=a}},open:{get:function(){return p()},set:function(a){p=a}},close:{get:function(){return q()},set:function(a){q=a}},high:{get:function(){return r},set:function(a){r=a}},low:{get:function(){return s},set:function(a){s=a}},margin:{get:function(){return g},set:function(a){g.top=void 0!=a.top?a.top:g.top,g.right=void 0!=a.right?a.right:g.right,g.bottom=void 0!=a.bottom?a.bottom:g.bottom,g.left=void 0!=a.left?a.left:g.left -}},color:{get:function(){return x},set:function(b){x=a.utils.getColor(b)}}}),a.utils.initOptions(b),b},a.models.parallelCoordinates=function(){"use strict";function b(p){return p.each(function(b){function p(a){return F(h.map(function(b){if(isNaN(a[b])||isNaN(parseFloat(a[b]))){var c=g[b].domain(),d=g[b].range(),e=c[0]-(c[1]-c[0])/9;if(J.indexOf(b)<0){var h=d3.scale.linear().domain([e,c[1]]).range([x-12,d[1]]);g[b].brush.y(h),J.push(b)}return[f(b),g[b](e)]}return J.length>0?(D.style("display","inline"),E.style("display","inline")):(D.style("display","none"),E.style("display","none")),[f(b),g[b](a[b])]}))}function q(){var a=h.filter(function(a){return!g[a].brush.empty()}),b=a.map(function(a){return g[a].brush.extent()});k=[],a.forEach(function(a,c){k[c]={dimension:a,extent:b[c]}}),l=[],M.style("display",function(c){var d=a.every(function(a,d){return isNaN(c[a])&&b[d][0]==g[a].brush.y().domain()[0]?!0:b[d][0]<=c[a]&&c[a]<=b[d][1]});return d&&l.push(c),d?null:"none"}),o.brush({filters:k,active:l})}function r(a){m[a]=this.parentNode.__origin__=f(a),L.attr("visibility","hidden")}function s(a){m[a]=Math.min(w,Math.max(0,this.parentNode.__origin__+=d3.event.x)),M.attr("d",p),h.sort(function(a,b){return u(a)-u(b)}),f.domain(h),N.attr("transform",function(a){return"translate("+u(a)+")"})}function t(a){delete this.parentNode.__origin__,delete m[a],d3.select(this.parentNode).attr("transform","translate("+f(a)+")"),M.attr("d",p),L.attr("d",p).attr("visibility",null)}function u(a){var b=m[a];return null==b?f(a):b}var v=d3.select(this),w=a.utils.availableWidth(d,v,c),x=a.utils.availableHeight(e,v,c);a.utils.initSVG(v),l=b,f.rangePoints([0,w],1).domain(h);var y={};h.forEach(function(a){var c=d3.extent(b,function(b){return+b[a]});return y[a]=!1,void 0===c[0]&&(y[a]=!0,c[0]=0,c[1]=0),c[0]===c[1]&&(c[0]=c[0]-1,c[1]=c[1]+1),g[a]=d3.scale.linear().domain(c).range([.9*(x-12),0]),g[a].brush=d3.svg.brush().y(g[a]).on("brush",q),"name"!=a});var z=v.selectAll("g.nv-wrap.nv-parallelCoordinates").data([b]),A=z.enter().append("g").attr("class","nvd3 nv-wrap nv-parallelCoordinates"),B=A.append("g"),C=z.select("g");B.append("g").attr("class","nv-parallelCoordinates background"),B.append("g").attr("class","nv-parallelCoordinates foreground"),B.append("g").attr("class","nv-parallelCoordinates missingValuesline"),z.attr("transform","translate("+c.left+","+c.top+")");var D,E,F=d3.svg.line().interpolate("cardinal").tension(n),G=d3.svg.axis().orient("left"),H=d3.behavior.drag().on("dragstart",r).on("drag",s).on("dragend",t),I=f.range()[1]-f.range()[0],J=[],K=[0+I/2,x-12,w-I/2,x-12];D=z.select(".missingValuesline").selectAll("line").data([K]),D.enter().append("line"),D.exit().remove(),D.attr("x1",function(a){return a[0]}).attr("y1",function(a){return a[1]}).attr("x2",function(a){return a[2]}).attr("y2",function(a){return a[3]}),E=z.select(".missingValuesline").selectAll("text").data(["undefined values"]),E.append("text").data(["undefined values"]),E.enter().append("text"),E.exit().remove(),E.attr("y",x).attr("x",w-92-I/2).text(function(a){return a});var L=z.select(".background").selectAll("path").data(b);L.enter().append("path"),L.exit().remove(),L.attr("d",p);var M=z.select(".foreground").selectAll("path").data(b);M.enter().append("path"),M.exit().remove(),M.attr("d",p).attr("stroke",j),M.on("mouseover",function(a,b){d3.select(this).classed("hover",!0),o.elementMouseover({label:a.name,data:a.data,index:b,pos:[d3.mouse(this.parentNode)[0],d3.mouse(this.parentNode)[1]]})}),M.on("mouseout",function(a,b){d3.select(this).classed("hover",!1),o.elementMouseout({label:a.name,data:a.data,index:b})});var N=C.selectAll(".dimension").data(h),O=N.enter().append("g").attr("class","nv-parallelCoordinates dimension");O.append("g").attr("class","nv-parallelCoordinates nv-axis"),O.append("g").attr("class","nv-parallelCoordinates-brush"),O.append("text").attr("class","nv-parallelCoordinates nv-label"),N.attr("transform",function(a){return"translate("+f(a)+",0)"}),N.exit().remove(),N.select(".nv-label").style("cursor","move").attr("dy","-1em").attr("text-anchor","middle").text(String).on("mouseover",function(a){o.elementMouseover({dim:a,pos:[d3.mouse(this.parentNode.parentNode)[0],d3.mouse(this.parentNode.parentNode)[1]]})}).on("mouseout",function(a){o.elementMouseout({dim:a})}).call(H),N.select(".nv-axis").each(function(a,b){d3.select(this).call(G.scale(g[a]).tickFormat(d3.format(i[b])))}),N.select(".nv-parallelCoordinates-brush").each(function(a){d3.select(this).call(g[a].brush)}).selectAll("rect").attr("x",-8).attr("width",16)}),b}var c={top:30,right:0,bottom:10,left:0},d=null,e=null,f=d3.scale.ordinal(),g={},h=[],i=[],j=a.utils.defaultColor(),k=[],l=[],m=[],n=1,o=d3.dispatch("brush","elementMouseover","elementMouseout");return b.dispatch=o,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return d},set:function(a){d=a}},height:{get:function(){return e},set:function(a){e=a}},dimensionNames:{get:function(){return h},set:function(a){h=a}},dimensionFormats:{get:function(){return i},set:function(a){i=a}},lineTension:{get:function(){return n},set:function(a){n=a}},dimensions:{get:function(){return h},set:function(b){a.deprecated("dimensions","use dimensionNames instead"),h=b}},margin:{get:function(){return c},set:function(a){c.top=void 0!==a.top?a.top:c.top,c.right=void 0!==a.right?a.right:c.right,c.bottom=void 0!==a.bottom?a.bottom:c.bottom,c.left=void 0!==a.left?a.left:c.left}},color:{get:function(){return j},set:function(b){j=a.utils.getColor(b)}}}),a.utils.initOptions(b),b},a.models.pie=function(){"use strict";function b(E){return D.reset(),E.each(function(b){function E(a,b){a.endAngle=isNaN(a.endAngle)?0:a.endAngle,a.startAngle=isNaN(a.startAngle)?0:a.startAngle,p||(a.innerRadius=0);var c=d3.interpolate(this._current,a);return this._current=c(0),function(a){return B[b](c(a))}}var F=d-c.left-c.right,G=e-c.top-c.bottom,H=Math.min(F,G)/2,I=[],J=[];if(i=d3.select(this),0===z.length)for(var K=H-H/5,L=y*H,M=0;Mc)return"";if("function"==typeof n)d=n(a,b,{key:f(a.data),value:g(a.data),percent:k(c)});else switch(n){case"key":d=f(a.data);break;case"value":d=k(g(a.data));break;case"percent":d=d3.format("%")(c)}return d})}}),D.renderEnd("pie immediate"),b}var c={top:0,right:0,bottom:0,left:0},d=500,e=500,f=function(a){return a.x},g=function(a){return a.y},h=Math.floor(1e4*Math.random()),i=null,j=a.utils.defaultColor(),k=d3.format(",.2f"),l=!0,m=!1,n="key",o=.02,p=!1,q=!1,r=!0,s=0,t=!1,u=!1,v=!1,w=!1,x=0,y=.5,z=[],A=d3.dispatch("chartClick","elementClick","elementDblClick","elementMouseover","elementMouseout","elementMousemove","renderEnd"),B=[],C=[],D=a.utils.renderWatch(A);return b.dispatch=A,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{arcsRadius:{get:function(){return z},set:function(a){z=a}},width:{get:function(){return d},set:function(a){d=a}},height:{get:function(){return e},set:function(a){e=a}},showLabels:{get:function(){return l},set:function(a){l=a}},title:{get:function(){return q},set:function(a){q=a}},titleOffset:{get:function(){return s},set:function(a){s=a}},labelThreshold:{get:function(){return o},set:function(a){o=a}},valueFormat:{get:function(){return k},set:function(a){k=a}},x:{get:function(){return f},set:function(a){f=a}},id:{get:function(){return h},set:function(a){h=a}},endAngle:{get:function(){return w},set:function(a){w=a}},startAngle:{get:function(){return u},set:function(a){u=a}},padAngle:{get:function(){return v},set:function(a){v=a}},cornerRadius:{get:function(){return x},set:function(a){x=a}},donutRatio:{get:function(){return y},set:function(a){y=a}},labelsOutside:{get:function(){return m},set:function(a){m=a}},labelSunbeamLayout:{get:function(){return t},set:function(a){t=a}},donut:{get:function(){return p},set:function(a){p=a}},growOnHover:{get:function(){return r},set:function(a){r=a}},pieLabelsOutside:{get:function(){return m},set:function(b){m=b,a.deprecated("pieLabelsOutside","use labelsOutside instead")}},donutLabelsOutside:{get:function(){return m},set:function(b){m=b,a.deprecated("donutLabelsOutside","use labelsOutside instead")}},labelFormat:{get:function(){return k},set:function(b){k=b,a.deprecated("labelFormat","use valueFormat instead")}},margin:{get:function(){return c},set:function(a){c.top="undefined"!=typeof a.top?a.top:c.top,c.right="undefined"!=typeof a.right?a.right:c.right,c.bottom="undefined"!=typeof a.bottom?a.bottom:c.bottom,c.left="undefined"!=typeof a.left?a.left:c.left}},y:{get:function(){return g},set:function(a){g=d3.functor(a)}},color:{get:function(){return j},set:function(b){j=a.utils.getColor(b)}},labelType:{get:function(){return n},set:function(a){n=a||"key"}}}),a.utils.initOptions(b),b},a.models.pieChart=function(){"use strict";function b(e){return q.reset(),q.models(c),e.each(function(e){var k=d3.select(this);a.utils.initSVG(k);var n=a.utils.availableWidth(g,k,f),o=a.utils.availableHeight(h,k,f);if(b.update=function(){k.transition().call(b)},b.container=this,l.setter(s(e),b.update).getter(r(e)).update(),l.disabled=e.map(function(a){return!!a.disabled}),!m){var q;m={};for(q in l)m[q]=l[q]instanceof Array?l[q].slice(0):l[q]}if(!e||!e.length)return a.utils.noData(b,k),b;k.selectAll(".nv-noData").remove();var t=k.selectAll("g.nv-wrap.nv-pieChart").data([e]),u=t.enter().append("g").attr("class","nvd3 nv-wrap nv-pieChart").append("g"),v=t.select("g");if(u.append("g").attr("class","nv-pieWrap"),u.append("g").attr("class","nv-legendWrap"),i)if("top"===j)d.width(n).key(c.x()),t.select(".nv-legendWrap").datum(e).call(d),f.top!=d.height()&&(f.top=d.height(),o=a.utils.availableHeight(h,k,f)),t.select(".nv-legendWrap").attr("transform","translate(0,"+-f.top+")");else if("right"===j){var w=a.models.legend().width();w>n/2&&(w=n/2),d.height(o).key(c.x()),d.width(w),n-=d.width(),t.select(".nv-legendWrap").datum(e).call(d).attr("transform","translate("+n+",0)")}t.attr("transform","translate("+f.left+","+f.top+")"),c.width(n).height(o);var x=v.select(".nv-pieWrap").datum([e]);d3.transition(x).call(c),d.dispatch.on("stateChange",function(a){for(var c in a)l[c]=a[c];p.stateChange(l),b.update()}),p.on("changeState",function(a){"undefined"!=typeof a.disabled&&(e.forEach(function(b,c){b.disabled=a.disabled[c]}),l.disabled=a.disabled),b.update()})}),q.renderEnd("pieChart immediate"),b}var c=a.models.pie(),d=a.models.legend(),e=a.models.tooltip(),f={top:30,right:20,bottom:20,left:20},g=null,h=null,i=!0,j="top",k=a.utils.defaultColor(),l=a.utils.state(),m=null,n=null,o=250,p=d3.dispatch("tooltipShow","tooltipHide","stateChange","changeState","renderEnd");e.headerEnabled(!1).duration(0).valueFormatter(function(a,b){return c.valueFormat()(a,b)});var q=a.utils.renderWatch(p),r=function(a){return function(){return{active:a.map(function(a){return!a.disabled})}}},s=function(a){return function(b){void 0!==b.active&&a.forEach(function(a,c){a.disabled=!b.active[c]})}};return c.dispatch.on("elementMouseover.tooltip",function(a){a.series={key:b.x()(a.data),value:b.y()(a.data),color:a.color},e.data(a).hidden(!1)}),c.dispatch.on("elementMouseout.tooltip",function(){e.hidden(!0)}),c.dispatch.on("elementMousemove.tooltip",function(){e.position({top:d3.event.pageY,left:d3.event.pageX})()}),b.legend=d,b.dispatch=p,b.pie=c,b.tooltip=e,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{noData:{get:function(){return n},set:function(a){n=a}},showLegend:{get:function(){return i},set:function(a){i=a}},legendPosition:{get:function(){return j},set:function(a){j=a}},defaultState:{get:function(){return m},set:function(a){m=a}},tooltips:{get:function(){return e.enabled()},set:function(b){a.deprecated("tooltips","use chart.tooltip.enabled() instead"),e.enabled(!!b)}},tooltipContent:{get:function(){return e.contentGenerator()},set:function(b){a.deprecated("tooltipContent","use chart.tooltip.contentGenerator() instead"),e.contentGenerator(b)}},color:{get:function(){return k},set:function(a){k=a,d.color(k),c.color(k)}},duration:{get:function(){return o},set:function(a){o=a,q.reset(o)}},margin:{get:function(){return f},set:function(a){f.top=void 0!==a.top?a.top:f.top,f.right=void 0!==a.right?a.right:f.right,f.bottom=void 0!==a.bottom?a.bottom:f.bottom,f.left=void 0!==a.left?a.left:f.left}}}),a.utils.inheritOptions(b,c),a.utils.initOptions(b),b},a.models.scatter=function(){"use strict";function b(N){return P.reset(),N.each(function(b){function N(){if(O=!1,!w)return!1;if(M===!0){var a=d3.merge(b.map(function(a,b){return a.values.map(function(a,c){var d=p(a,c),e=q(a,c);return[m(d)+1e-4*Math.random(),n(e)+1e-4*Math.random(),b,c,a]}).filter(function(a,b){return x(a[4],b)})}));if(0==a.length)return!1;a.length<3&&(a.push([m.range()[0]-20,n.range()[0]-20,null,null]),a.push([m.range()[1]+20,n.range()[1]+20,null,null]),a.push([m.range()[0]-20,n.range()[0]+20,null,null]),a.push([m.range()[1]+20,n.range()[1]-20,null,null]));var c=d3.geom.polygon([[-10,-10],[-10,i+10],[h+10,i+10],[h+10,-10]]),d=d3.geom.voronoi(a).map(function(b,d){return{data:c.clip(b),series:a[d][2],point:a[d][3]}});U.select(".nv-point-paths").selectAll("path").remove();var e=U.select(".nv-point-paths").selectAll("path").data(d),f=e.enter().append("svg:path").attr("d",function(a){return a&&a.data&&0!==a.data.length?"M"+a.data.join(",")+"Z":"M 0 0"}).attr("id",function(a,b){return"nv-path-"+b}).attr("clip-path",function(a,b){return"url(#nv-clip-"+b+")"});C&&f.style("fill",d3.rgb(230,230,230)).style("fill-opacity",.4).style("stroke-opacity",1).style("stroke",d3.rgb(200,200,200)),B&&(U.select(".nv-point-clips").selectAll("clipPath").remove(),U.select(".nv-point-clips").selectAll("clipPath").data(a).enter().append("svg:clipPath").attr("id",function(a,b){return"nv-clip-"+b}).append("svg:circle").attr("cx",function(a){return a[0]}).attr("cy",function(a){return a[1]}).attr("r",D));var k=function(a,c){if(O)return 0;var d=b[a.series];if(void 0!==d){var e=d.values[a.point];e.color=j(d,a.series),e.x=p(e),e.y=q(e);var f=l.node().getBoundingClientRect(),h=window.pageYOffset||document.documentElement.scrollTop,i=window.pageXOffset||document.documentElement.scrollLeft,k={left:m(p(e,a.point))+f.left+i+g.left+10,top:n(q(e,a.point))+f.top+h+g.top+10};c({point:e,series:d,pos:k,seriesIndex:a.series,pointIndex:a.point})}};e.on("click",function(a){k(a,L.elementClick)}).on("dblclick",function(a){k(a,L.elementDblClick)}).on("mouseover",function(a){k(a,L.elementMouseover)}).on("mouseout",function(a){k(a,L.elementMouseout)})}else U.select(".nv-groups").selectAll(".nv-group").selectAll(".nv-point").on("click",function(a,c){if(O||!b[a.series])return 0;var d=b[a.series],e=d.values[c];L.elementClick({point:e,series:d,pos:[m(p(e,c))+g.left,n(q(e,c))+g.top],seriesIndex:a.series,pointIndex:c})}).on("dblclick",function(a,c){if(O||!b[a.series])return 0;var d=b[a.series],e=d.values[c];L.elementDblClick({point:e,series:d,pos:[m(p(e,c))+g.left,n(q(e,c))+g.top],seriesIndex:a.series,pointIndex:c})}).on("mouseover",function(a,c){if(O||!b[a.series])return 0;var d=b[a.series],e=d.values[c];L.elementMouseover({point:e,series:d,pos:[m(p(e,c))+g.left,n(q(e,c))+g.top],seriesIndex:a.series,pointIndex:c,color:j(a,c)})}).on("mouseout",function(a,c){if(O||!b[a.series])return 0;var d=b[a.series],e=d.values[c];L.elementMouseout({point:e,series:d,seriesIndex:a.series,pointIndex:c,color:j(a,c)})})}l=d3.select(this);var R=a.utils.availableWidth(h,l,g),S=a.utils.availableHeight(i,l,g);a.utils.initSVG(l),b.forEach(function(a,b){a.values.forEach(function(a){a.series=b})});var T=E&&F&&I?[]:d3.merge(b.map(function(a){return a.values.map(function(a,b){return{x:p(a,b),y:q(a,b),size:r(a,b)}})}));m.domain(E||d3.extent(T.map(function(a){return a.x}).concat(t))),m.range(y&&b[0]?G||[(R*z+R)/(2*b[0].values.length),R-R*(1+z)/(2*b[0].values.length)]:G||[0,R]),n.domain(F||d3.extent(T.map(function(a){return a.y}).concat(u))).range(H||[S,0]),o.domain(I||d3.extent(T.map(function(a){return a.size}).concat(v))).range(J||Q),K=m.domain()[0]===m.domain()[1]||n.domain()[0]===n.domain()[1],m.domain()[0]===m.domain()[1]&&m.domain(m.domain()[0]?[m.domain()[0]-.01*m.domain()[0],m.domain()[1]+.01*m.domain()[1]]:[-1,1]),n.domain()[0]===n.domain()[1]&&n.domain(n.domain()[0]?[n.domain()[0]-.01*n.domain()[0],n.domain()[1]+.01*n.domain()[1]]:[-1,1]),isNaN(m.domain()[0])&&m.domain([-1,1]),isNaN(n.domain()[0])&&n.domain([-1,1]),c=c||m,d=d||n,e=e||o;var U=l.selectAll("g.nv-wrap.nv-scatter").data([b]),V=U.enter().append("g").attr("class","nvd3 nv-wrap nv-scatter nv-chart-"+k),W=V.append("defs"),X=V.append("g"),Y=U.select("g");U.classed("nv-single-point",K),X.append("g").attr("class","nv-groups"),X.append("g").attr("class","nv-point-paths"),V.append("g").attr("class","nv-point-clips"),U.attr("transform","translate("+g.left+","+g.top+")"),W.append("clipPath").attr("id","nv-edge-clip-"+k).append("rect"),U.select("#nv-edge-clip-"+k+" rect").attr("width",R).attr("height",S>0?S:0),Y.attr("clip-path",A?"url(#nv-edge-clip-"+k+")":""),O=!0;var Z=U.select(".nv-groups").selectAll(".nv-group").data(function(a){return a},function(a){return a.key});Z.enter().append("g").style("stroke-opacity",1e-6).style("fill-opacity",1e-6),Z.exit().remove(),Z.attr("class",function(a,b){return"nv-group nv-series-"+b}).classed("hover",function(a){return a.hover}),Z.watchTransition(P,"scatter: groups").style("fill",function(a,b){return j(a,b)}).style("stroke",function(a,b){return j(a,b)}).style("stroke-opacity",1).style("fill-opacity",.5);var $=Z.selectAll("path.nv-point").data(function(a){return a.values.map(function(a,b){return[a,b]}).filter(function(a,b){return x(a[0],b)})});$.enter().append("path").style("fill",function(a){return a.color}).style("stroke",function(a){return a.color}).attr("transform",function(a){return"translate("+c(p(a[0],a[1]))+","+d(q(a[0],a[1]))+")"}).attr("d",a.utils.symbol().type(function(a){return s(a[0])}).size(function(a){return o(r(a[0],a[1]))})),$.exit().remove(),Z.exit().selectAll("path.nv-point").watchTransition(P,"scatter exit").attr("transform",function(a){return"translate("+m(p(a[0],a[1]))+","+n(q(a[0],a[1]))+")"}).remove(),$.each(function(a){d3.select(this).classed("nv-point",!0).classed("nv-point-"+a[1],!0).classed("nv-noninteractive",!w).classed("hover",!1)}),$.watchTransition(P,"scatter points").attr("transform",function(a){return"translate("+m(p(a[0],a[1]))+","+n(q(a[0],a[1]))+")"}).attr("d",a.utils.symbol().type(function(a){return s(a[0])}).size(function(a){return o(r(a[0],a[1]))})),clearTimeout(f),f=setTimeout(N,300),c=m.copy(),d=n.copy(),e=o.copy()}),P.renderEnd("scatter immediate"),b}var c,d,e,f,g={top:0,right:0,bottom:0,left:0},h=null,i=null,j=a.utils.defaultColor(),k=Math.floor(1e5*Math.random()),l=null,m=d3.scale.linear(),n=d3.scale.linear(),o=d3.scale.linear(),p=function(a){return a.x},q=function(a){return a.y},r=function(a){return a.size||1},s=function(a){return a.shape||"circle"},t=[],u=[],v=[],w=!0,x=function(a){return!a.notActive},y=!1,z=.1,A=!1,B=!0,C=!1,D=function(){return 25},E=null,F=null,G=null,H=null,I=null,J=null,K=!1,L=d3.dispatch("elementClick","elementDblClick","elementMouseover","elementMouseout","renderEnd"),M=!0,N=250,O=!1,P=a.utils.renderWatch(L,N),Q=[16,256];return b.dispatch=L,b.options=a.utils.optionsFunc.bind(b),b._calls=new function(){this.clearHighlights=function(){return a.dom.write(function(){l.selectAll(".nv-point.hover").classed("hover",!1)}),null},this.highlightPoint=function(b,c,d){a.dom.write(function(){l.select(" .nv-series-"+b+" .nv-point-"+c).classed("hover",d)})}},L.on("elementMouseover.point",function(a){w&&b._calls.highlightPoint(a.seriesIndex,a.pointIndex,!0)}),L.on("elementMouseout.point",function(a){w&&b._calls.highlightPoint(a.seriesIndex,a.pointIndex,!1)}),b._options=Object.create({},{width:{get:function(){return h},set:function(a){h=a}},height:{get:function(){return i},set:function(a){i=a}},xScale:{get:function(){return m},set:function(a){m=a}},yScale:{get:function(){return n},set:function(a){n=a}},pointScale:{get:function(){return o},set:function(a){o=a}},xDomain:{get:function(){return E},set:function(a){E=a}},yDomain:{get:function(){return F},set:function(a){F=a}},pointDomain:{get:function(){return I},set:function(a){I=a}},xRange:{get:function(){return G},set:function(a){G=a}},yRange:{get:function(){return H},set:function(a){H=a}},pointRange:{get:function(){return J},set:function(a){J=a}},forceX:{get:function(){return t},set:function(a){t=a}},forceY:{get:function(){return u},set:function(a){u=a}},forcePoint:{get:function(){return v},set:function(a){v=a}},interactive:{get:function(){return w},set:function(a){w=a}},pointActive:{get:function(){return x},set:function(a){x=a}},padDataOuter:{get:function(){return z},set:function(a){z=a}},padData:{get:function(){return y},set:function(a){y=a}},clipEdge:{get:function(){return A},set:function(a){A=a}},clipVoronoi:{get:function(){return B},set:function(a){B=a}},clipRadius:{get:function(){return D},set:function(a){D=a}},showVoronoi:{get:function(){return C},set:function(a){C=a}},id:{get:function(){return k},set:function(a){k=a}},x:{get:function(){return p},set:function(a){p=d3.functor(a)}},y:{get:function(){return q},set:function(a){q=d3.functor(a)}},pointSize:{get:function(){return r},set:function(a){r=d3.functor(a)}},pointShape:{get:function(){return s},set:function(a){s=d3.functor(a)}},margin:{get:function(){return g},set:function(a){g.top=void 0!==a.top?a.top:g.top,g.right=void 0!==a.right?a.right:g.right,g.bottom=void 0!==a.bottom?a.bottom:g.bottom,g.left=void 0!==a.left?a.left:g.left}},duration:{get:function(){return N},set:function(a){N=a,P.reset(N)}},color:{get:function(){return j},set:function(b){j=a.utils.getColor(b)}},useVoronoi:{get:function(){return M},set:function(a){M=a,M===!1&&(B=!1)}}}),a.utils.initOptions(b),b},a.models.scatterChart=function(){"use strict";function b(z){return D.reset(),D.models(c),t&&D.models(d),u&&D.models(e),q&&D.models(g),r&&D.models(h),z.each(function(z){m=d3.select(this),a.utils.initSVG(m);var G=a.utils.availableWidth(k,m,j),H=a.utils.availableHeight(l,m,j);if(b.update=function(){0===A?m.call(b):m.transition().duration(A).call(b)},b.container=this,w.setter(F(z),b.update).getter(E(z)).update(),w.disabled=z.map(function(a){return!!a.disabled}),!x){var I;x={};for(I in w)x[I]=w[I]instanceof Array?w[I].slice(0):w[I]}if(!(z&&z.length&&z.filter(function(a){return a.values.length}).length))return a.utils.noData(b,m),D.renderEnd("scatter immediate"),b;m.selectAll(".nv-noData").remove(),o=c.xScale(),p=c.yScale();var J=m.selectAll("g.nv-wrap.nv-scatterChart").data([z]),K=J.enter().append("g").attr("class","nvd3 nv-wrap nv-scatterChart nv-chart-"+c.id()),L=K.append("g"),M=J.select("g");if(L.append("rect").attr("class","nvd3 nv-background").style("pointer-events","none"),L.append("g").attr("class","nv-x nv-axis"),L.append("g").attr("class","nv-y nv-axis"),L.append("g").attr("class","nv-scatterWrap"),L.append("g").attr("class","nv-regressionLinesWrap"),L.append("g").attr("class","nv-distWrap"),L.append("g").attr("class","nv-legendWrap"),v&&M.select(".nv-y.nv-axis").attr("transform","translate("+G+",0)"),s){var N=G;f.width(N),J.select(".nv-legendWrap").datum(z).call(f),j.top!=f.height()&&(j.top=f.height(),H=a.utils.availableHeight(l,m,j)),J.select(".nv-legendWrap").attr("transform","translate(0,"+-j.top+")")}J.attr("transform","translate("+j.left+","+j.top+")"),c.width(G).height(H).color(z.map(function(a,b){return a.color=a.color||n(a,b),a.color}).filter(function(a,b){return!z[b].disabled})),J.select(".nv-scatterWrap").datum(z.filter(function(a){return!a.disabled})).call(c),J.select(".nv-regressionLinesWrap").attr("clip-path","url(#nv-edge-clip-"+c.id()+")");var O=J.select(".nv-regressionLinesWrap").selectAll(".nv-regLines").data(function(a){return a});O.enter().append("g").attr("class","nv-regLines");var P=O.selectAll(".nv-regLine").data(function(a){return[a]});P.enter().append("line").attr("class","nv-regLine").style("stroke-opacity",0),P.filter(function(a){return a.intercept&&a.slope}).watchTransition(D,"scatterPlusLineChart: regline").attr("x1",o.range()[0]).attr("x2",o.range()[1]).attr("y1",function(a){return p(o.domain()[0]*a.slope+a.intercept)}).attr("y2",function(a){return p(o.domain()[1]*a.slope+a.intercept)}).style("stroke",function(a,b,c){return n(a,c)}).style("stroke-opacity",function(a){return a.disabled||"undefined"==typeof a.slope||"undefined"==typeof a.intercept?0:1}),t&&(d.scale(o)._ticks(a.utils.calcTicksX(G/100,z)).tickSize(-H,0),M.select(".nv-x.nv-axis").attr("transform","translate(0,"+p.range()[0]+")").call(d)),u&&(e.scale(p)._ticks(a.utils.calcTicksY(H/36,z)).tickSize(-G,0),M.select(".nv-y.nv-axis").call(e)),q&&(g.getData(c.x()).scale(o).width(G).color(z.map(function(a,b){return a.color||n(a,b)}).filter(function(a,b){return!z[b].disabled})),L.select(".nv-distWrap").append("g").attr("class","nv-distributionX"),M.select(".nv-distributionX").attr("transform","translate(0,"+p.range()[0]+")").datum(z.filter(function(a){return!a.disabled})).call(g)),r&&(h.getData(c.y()).scale(p).width(H).color(z.map(function(a,b){return a.color||n(a,b)}).filter(function(a,b){return!z[b].disabled})),L.select(".nv-distWrap").append("g").attr("class","nv-distributionY"),M.select(".nv-distributionY").attr("transform","translate("+(v?G:-h.size())+",0)").datum(z.filter(function(a){return!a.disabled})).call(h)),f.dispatch.on("stateChange",function(a){for(var c in a)w[c]=a[c];y.stateChange(w),b.update()}),y.on("changeState",function(a){"undefined"!=typeof a.disabled&&(z.forEach(function(b,c){b.disabled=a.disabled[c]}),w.disabled=a.disabled),b.update()}),c.dispatch.on("elementMouseout.tooltip",function(a){i.hidden(!0),m.select(".nv-chart-"+c.id()+" .nv-series-"+a.seriesIndex+" .nv-distx-"+a.pointIndex).attr("y1",0),m.select(".nv-chart-"+c.id()+" .nv-series-"+a.seriesIndex+" .nv-disty-"+a.pointIndex).attr("x2",h.size())}),c.dispatch.on("elementMouseover.tooltip",function(a){m.select(".nv-series-"+a.seriesIndex+" .nv-distx-"+a.pointIndex).attr("y1",a.pos.top-H-j.top),m.select(".nv-series-"+a.seriesIndex+" .nv-disty-"+a.pointIndex).attr("x2",a.pos.left+g.size()-j.left),i.position(a.pos).data(a).hidden(!1)}),B=o.copy(),C=p.copy()}),D.renderEnd("scatter with line immediate"),b}var c=a.models.scatter(),d=a.models.axis(),e=a.models.axis(),f=a.models.legend(),g=a.models.distribution(),h=a.models.distribution(),i=a.models.tooltip(),j={top:30,right:20,bottom:50,left:75},k=null,l=null,m=null,n=a.utils.defaultColor(),o=c.xScale(),p=c.yScale(),q=!1,r=!1,s=!0,t=!0,u=!0,v=!1,w=a.utils.state(),x=null,y=d3.dispatch("stateChange","changeState","renderEnd"),z=null,A=250;c.xScale(o).yScale(p),d.orient("bottom").tickPadding(10),e.orient(v?"right":"left").tickPadding(10),g.axis("x"),h.axis("y"),i.headerFormatter(function(a,b){return d.tickFormat()(a,b)}).valueFormatter(function(a,b){return e.tickFormat()(a,b)});var B,C,D=a.utils.renderWatch(y,A),E=function(a){return function(){return{active:a.map(function(a){return!a.disabled})}}},F=function(a){return function(b){void 0!==b.active&&a.forEach(function(a,c){a.disabled=!b.active[c]})}};return b.dispatch=y,b.scatter=c,b.legend=f,b.xAxis=d,b.yAxis=e,b.distX=g,b.distY=h,b.tooltip=i,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return k},set:function(a){k=a}},height:{get:function(){return l},set:function(a){l=a}},container:{get:function(){return m},set:function(a){m=a}},showDistX:{get:function(){return q},set:function(a){q=a}},showDistY:{get:function(){return r},set:function(a){r=a}},showLegend:{get:function(){return s},set:function(a){s=a}},showXAxis:{get:function(){return t},set:function(a){t=a}},showYAxis:{get:function(){return u},set:function(a){u=a}},defaultState:{get:function(){return x},set:function(a){x=a}},noData:{get:function(){return z},set:function(a){z=a}},duration:{get:function(){return A},set:function(a){A=a}},tooltips:{get:function(){return i.enabled()},set:function(b){a.deprecated("tooltips","use chart.tooltip.enabled() instead"),i.enabled(!!b) -}},tooltipContent:{get:function(){return i.contentGenerator()},set:function(b){a.deprecated("tooltipContent","use chart.tooltip.contentGenerator() instead"),i.contentGenerator(b)}},tooltipXContent:{get:function(){return i.contentGenerator()},set:function(){a.deprecated("tooltipContent","This option is removed, put values into main tooltip.")}},tooltipYContent:{get:function(){return i.contentGenerator()},set:function(){a.deprecated("tooltipContent","This option is removed, put values into main tooltip.")}},margin:{get:function(){return j},set:function(a){j.top=void 0!==a.top?a.top:j.top,j.right=void 0!==a.right?a.right:j.right,j.bottom=void 0!==a.bottom?a.bottom:j.bottom,j.left=void 0!==a.left?a.left:j.left}},rightAlignYAxis:{get:function(){return v},set:function(a){v=a,e.orient(a?"right":"left")}},color:{get:function(){return n},set:function(b){n=a.utils.getColor(b),f.color(n),g.color(n),h.color(n)}}}),a.utils.inheritOptions(b,c),a.utils.initOptions(b),b},a.models.sparkline=function(){"use strict";function b(k){return k.each(function(b){var k=h-g.left-g.right,q=i-g.top-g.bottom;j=d3.select(this),a.utils.initSVG(j),l.domain(c||d3.extent(b,n)).range(e||[0,k]),m.domain(d||d3.extent(b,o)).range(f||[q,0]);{var r=j.selectAll("g.nv-wrap.nv-sparkline").data([b]),s=r.enter().append("g").attr("class","nvd3 nv-wrap nv-sparkline");s.append("g"),r.select("g")}r.attr("transform","translate("+g.left+","+g.top+")");var t=r.selectAll("path").data(function(a){return[a]});t.enter().append("path"),t.exit().remove(),t.style("stroke",function(a,b){return a.color||p(a,b)}).attr("d",d3.svg.line().x(function(a,b){return l(n(a,b))}).y(function(a,b){return m(o(a,b))}));var u=r.selectAll("circle.nv-point").data(function(a){function b(b){if(-1!=b){var c=a[b];return c.pointIndex=b,c}return null}var c=a.map(function(a,b){return o(a,b)}),d=b(c.lastIndexOf(m.domain()[1])),e=b(c.indexOf(m.domain()[0])),f=b(c.length-1);return[e,d,f].filter(function(a){return null!=a})});u.enter().append("circle"),u.exit().remove(),u.attr("cx",function(a){return l(n(a,a.pointIndex))}).attr("cy",function(a){return m(o(a,a.pointIndex))}).attr("r",2).attr("class",function(a){return n(a,a.pointIndex)==l.domain()[1]?"nv-point nv-currentValue":o(a,a.pointIndex)==m.domain()[0]?"nv-point nv-minValue":"nv-point nv-maxValue"})}),b}var c,d,e,f,g={top:2,right:0,bottom:2,left:0},h=400,i=32,j=null,k=!0,l=d3.scale.linear(),m=d3.scale.linear(),n=function(a){return a.x},o=function(a){return a.y},p=a.utils.getColor(["#000"]);return b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return h},set:function(a){h=a}},height:{get:function(){return i},set:function(a){i=a}},xDomain:{get:function(){return c},set:function(a){c=a}},yDomain:{get:function(){return d},set:function(a){d=a}},xRange:{get:function(){return e},set:function(a){e=a}},yRange:{get:function(){return f},set:function(a){f=a}},xScale:{get:function(){return l},set:function(a){l=a}},yScale:{get:function(){return m},set:function(a){m=a}},animate:{get:function(){return k},set:function(a){k=a}},x:{get:function(){return n},set:function(a){n=d3.functor(a)}},y:{get:function(){return o},set:function(a){o=d3.functor(a)}},margin:{get:function(){return g},set:function(a){g.top=void 0!==a.top?a.top:g.top,g.right=void 0!==a.right?a.right:g.right,g.bottom=void 0!==a.bottom?a.bottom:g.bottom,g.left=void 0!==a.left?a.left:g.left}},color:{get:function(){return p},set:function(b){p=a.utils.getColor(b)}}}),a.utils.initOptions(b),b},a.models.sparklinePlus=function(){"use strict";function b(p){return p.each(function(p){function q(){if(!j){var a=z.selectAll(".nv-hoverValue").data(i),b=a.enter().append("g").attr("class","nv-hoverValue").style("stroke-opacity",0).style("fill-opacity",0);a.exit().transition().duration(250).style("stroke-opacity",0).style("fill-opacity",0).remove(),a.attr("transform",function(a){return"translate("+c(e.x()(p[a],a))+",0)"}).transition().duration(250).style("stroke-opacity",1).style("fill-opacity",1),i.length&&(b.append("line").attr("x1",0).attr("y1",-f.top).attr("x2",0).attr("y2",u),b.append("text").attr("class","nv-xValue").attr("x",-6).attr("y",-f.top).attr("text-anchor","end").attr("dy",".9em"),z.select(".nv-hoverValue .nv-xValue").text(k(e.x()(p[i[0]],i[0]))),b.append("text").attr("class","nv-yValue").attr("x",6).attr("y",-f.top).attr("text-anchor","start").attr("dy",".9em"),z.select(".nv-hoverValue .nv-yValue").text(l(e.y()(p[i[0]],i[0]))))}}function r(){function a(a,b){for(var c=Math.abs(e.x()(a[0],0)-b),d=0,f=0;fc;++c){for(b=0,d=0;bb;b++)a[b][c][1]/=d;else for(b=0;e>b;b++)a[b][c][1]=0}for(c=0;f>c;++c)g[c]=0;return g}}),u.renderEnd("stackedArea immediate"),b}var c,d,e={top:0,right:0,bottom:0,left:0},f=960,g=500,h=a.utils.defaultColor(),i=Math.floor(1e5*Math.random()),j=null,k=function(a){return a.x},l=function(a){return a.y},m="stack",n="zero",o="default",p="linear",q=!1,r=a.models.scatter(),s=250,t=d3.dispatch("areaClick","areaMouseover","areaMouseout","renderEnd","elementClick","elementMouseover","elementMouseout");r.pointSize(2.2).pointDomain([2.2,2.2]);var u=a.utils.renderWatch(t,s);return b.dispatch=t,b.scatter=r,r.dispatch.on("elementClick",function(){t.elementClick.apply(this,arguments)}),r.dispatch.on("elementMouseover",function(){t.elementMouseover.apply(this,arguments)}),r.dispatch.on("elementMouseout",function(){t.elementMouseout.apply(this,arguments)}),b.interpolate=function(a){return arguments.length?(p=a,b):p},b.duration=function(a){return arguments.length?(s=a,u.reset(s),r.duration(s),b):s},b.dispatch=t,b.scatter=r,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return f},set:function(a){f=a}},height:{get:function(){return g},set:function(a){g=a}},clipEdge:{get:function(){return q},set:function(a){q=a}},offset:{get:function(){return n},set:function(a){n=a}},order:{get:function(){return o},set:function(a){o=a}},interpolate:{get:function(){return p},set:function(a){p=a}},x:{get:function(){return k},set:function(a){k=d3.functor(a)}},y:{get:function(){return l},set:function(a){l=d3.functor(a)}},margin:{get:function(){return e},set:function(a){e.top=void 0!==a.top?a.top:e.top,e.right=void 0!==a.right?a.right:e.right,e.bottom=void 0!==a.bottom?a.bottom:e.bottom,e.left=void 0!==a.left?a.left:e.left}},color:{get:function(){return h},set:function(b){h=a.utils.getColor(b)}},style:{get:function(){return m},set:function(a){switch(m=a){case"stack":b.offset("zero"),b.order("default");break;case"stream":b.offset("wiggle"),b.order("inside-out");break;case"stream-center":b.offset("silhouette"),b.order("inside-out");break;case"expand":b.offset("expand"),b.order("default");break;case"stack_percent":b.offset(b.d3_stackedOffset_stackPercent),b.order("default")}}},duration:{get:function(){return s},set:function(a){s=a,u.reset(s),r.duration(s)}}}),a.utils.inheritOptions(b,r),a.utils.initOptions(b),b},a.models.stackedAreaChart=function(){"use strict";function b(k){return F.reset(),F.models(e),r&&F.models(f),s&&F.models(g),k.each(function(k){var x=d3.select(this),F=this;a.utils.initSVG(x);var K=a.utils.availableWidth(m,x,l),L=a.utils.availableHeight(n,x,l);if(b.update=function(){x.transition().duration(C).call(b)},b.container=this,v.setter(I(k),b.update).getter(H(k)).update(),v.disabled=k.map(function(a){return!!a.disabled}),!w){var M;w={};for(M in v)w[M]=v[M]instanceof Array?v[M].slice(0):v[M]}if(!(k&&k.length&&k.filter(function(a){return a.values.length}).length))return a.utils.noData(b,x),b;x.selectAll(".nv-noData").remove(),c=e.xScale(),d=e.yScale();var N=x.selectAll("g.nv-wrap.nv-stackedAreaChart").data([k]),O=N.enter().append("g").attr("class","nvd3 nv-wrap nv-stackedAreaChart").append("g"),P=N.select("g");if(O.append("rect").style("opacity",0),O.append("g").attr("class","nv-x nv-axis"),O.append("g").attr("class","nv-y nv-axis"),O.append("g").attr("class","nv-stackedWrap"),O.append("g").attr("class","nv-legendWrap"),O.append("g").attr("class","nv-controlsWrap"),O.append("g").attr("class","nv-interactive"),P.select("rect").attr("width",K).attr("height",L),q){var Q=p?K-z:K;h.width(Q),P.select(".nv-legendWrap").datum(k).call(h),l.top!=h.height()&&(l.top=h.height(),L=a.utils.availableHeight(n,x,l)),P.select(".nv-legendWrap").attr("transform","translate("+(K-Q)+","+-l.top+")")}if(p){var R=[{key:B.stacked||"Stacked",metaKey:"Stacked",disabled:"stack"!=e.style(),style:"stack"},{key:B.stream||"Stream",metaKey:"Stream",disabled:"stream"!=e.style(),style:"stream"},{key:B.expanded||"Expanded",metaKey:"Expanded",disabled:"expand"!=e.style(),style:"expand"},{key:B.stack_percent||"Stack %",metaKey:"Stack_Percent",disabled:"stack_percent"!=e.style(),style:"stack_percent"}];z=A.length/3*260,R=R.filter(function(a){return-1!==A.indexOf(a.metaKey)}),i.width(z).color(["#444","#444","#444"]),P.select(".nv-controlsWrap").datum(R).call(i),l.top!=Math.max(i.height(),h.height())&&(l.top=Math.max(i.height(),h.height()),L=a.utils.availableHeight(n,x,l)),P.select(".nv-controlsWrap").attr("transform","translate(0,"+-l.top+")")}N.attr("transform","translate("+l.left+","+l.top+")"),t&&P.select(".nv-y.nv-axis").attr("transform","translate("+K+",0)"),u&&(j.width(K).height(L).margin({left:l.left,top:l.top}).svgContainer(x).xScale(c),N.select(".nv-interactive").call(j)),e.width(K).height(L);var S=P.select(".nv-stackedWrap").datum(k);if(S.transition().call(e),r&&(f.scale(c)._ticks(a.utils.calcTicksX(K/100,k)).tickSize(-L,0),P.select(".nv-x.nv-axis").attr("transform","translate(0,"+L+")"),P.select(".nv-x.nv-axis").transition().duration(0).call(f)),s){var T;if(T="wiggle"===e.offset()?0:a.utils.calcTicksY(L/36,k),g.scale(d)._ticks(T).tickSize(-K,0),"expand"===e.style()||"stack_percent"===e.style()){var U=g.tickFormat();D&&U===J||(D=U),g.tickFormat(J)}else D&&(g.tickFormat(D),D=null);P.select(".nv-y.nv-axis").transition().duration(0).call(g)}e.dispatch.on("areaClick.toggle",function(a){k.forEach(1===k.filter(function(a){return!a.disabled}).length?function(a){a.disabled=!1}:function(b,c){b.disabled=c!=a.seriesIndex}),v.disabled=k.map(function(a){return!!a.disabled}),y.stateChange(v),b.update()}),h.dispatch.on("stateChange",function(a){for(var c in a)v[c]=a[c];y.stateChange(v),b.update()}),i.dispatch.on("legendClick",function(a){a.disabled&&(R=R.map(function(a){return a.disabled=!0,a}),a.disabled=!1,e.style(a.style),v.style=e.style(),y.stateChange(v),b.update())}),j.dispatch.on("elementMousemove",function(c){e.clearHighlights();var d,g,h,i=[];if(k.filter(function(a,b){return a.seriesIndex=b,!a.disabled}).forEach(function(f,j){g=a.interactiveBisect(f.values,c.pointXValue,b.x());var k=f.values[g],l=b.y()(k,g);if(null!=l&&e.highlightPoint(j,g,!0),"undefined"!=typeof k){"undefined"==typeof d&&(d=k),"undefined"==typeof h&&(h=b.xScale()(b.x()(k,g)));var m="expand"==e.style()?k.display.y:b.y()(k,g);i.push({key:f.key,value:m,color:o(f,f.seriesIndex),stackedValue:k.display})}}),i.reverse(),i.length>2){var m=b.yScale().invert(c.mouseY),n=null;i.forEach(function(a,b){m=Math.abs(m);var c=Math.abs(a.stackedValue.y0),d=Math.abs(a.stackedValue.y);return m>=c&&d+c>=m?void(n=b):void 0}),null!=n&&(i[n].highlight=!0)}var p=f.tickFormat()(b.x()(d,g)),q=j.tooltip.valueFormatter();"expand"===e.style()||"stack_percent"===e.style()?(E||(E=q),q=d3.format(".1%")):E&&(q=E,E=null),j.tooltip.position({left:h+l.left,top:c.mouseY+l.top}).chartContainer(F.parentNode).valueFormatter(q).data({value:p,series:i})(),j.renderGuideLine(h)}),j.dispatch.on("elementMouseout",function(){e.clearHighlights()}),y.on("changeState",function(a){"undefined"!=typeof a.disabled&&k.length===a.disabled.length&&(k.forEach(function(b,c){b.disabled=a.disabled[c]}),v.disabled=a.disabled),"undefined"!=typeof a.style&&(e.style(a.style),G=a.style),b.update()})}),F.renderEnd("stacked Area chart immediate"),b}var c,d,e=a.models.stackedArea(),f=a.models.axis(),g=a.models.axis(),h=a.models.legend(),i=a.models.legend(),j=a.interactiveGuideline(),k=a.models.tooltip(),l={top:30,right:25,bottom:50,left:60},m=null,n=null,o=a.utils.defaultColor(),p=!0,q=!0,r=!0,s=!0,t=!1,u=!1,v=a.utils.state(),w=null,x=null,y=d3.dispatch("stateChange","changeState","renderEnd"),z=250,A=["Stacked","Stream","Expanded"],B={},C=250;v.style=e.style(),f.orient("bottom").tickPadding(7),g.orient(t?"right":"left"),k.headerFormatter(function(a,b){return f.tickFormat()(a,b)}).valueFormatter(function(a,b){return g.tickFormat()(a,b)}),j.tooltip.headerFormatter(function(a,b){return f.tickFormat()(a,b)}).valueFormatter(function(a,b){return g.tickFormat()(a,b)});var D=null,E=null;i.updateState(!1);var F=a.utils.renderWatch(y),G=e.style(),H=function(a){return function(){return{active:a.map(function(a){return!a.disabled}),style:e.style()}}},I=function(a){return function(b){void 0!==b.style&&(G=b.style),void 0!==b.active&&a.forEach(function(a,c){a.disabled=!b.active[c]})}},J=d3.format("%");return e.dispatch.on("elementMouseover.tooltip",function(a){a.point.x=e.x()(a.point),a.point.y=e.y()(a.point),k.data(a).position(a.pos).hidden(!1)}),e.dispatch.on("elementMouseout.tooltip",function(){k.hidden(!0)}),b.dispatch=y,b.stacked=e,b.legend=h,b.controls=i,b.xAxis=f,b.yAxis=g,b.interactiveLayer=j,b.tooltip=k,b.dispatch=y,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return m},set:function(a){m=a}},height:{get:function(){return n},set:function(a){n=a}},showLegend:{get:function(){return q},set:function(a){q=a}},showXAxis:{get:function(){return r},set:function(a){r=a}},showYAxis:{get:function(){return s},set:function(a){s=a}},defaultState:{get:function(){return w},set:function(a){w=a}},noData:{get:function(){return x},set:function(a){x=a}},showControls:{get:function(){return p},set:function(a){p=a}},controlLabels:{get:function(){return B},set:function(a){B=a}},controlOptions:{get:function(){return A},set:function(a){A=a}},tooltips:{get:function(){return k.enabled()},set:function(b){a.deprecated("tooltips","use chart.tooltip.enabled() instead"),k.enabled(!!b)}},tooltipContent:{get:function(){return k.contentGenerator()},set:function(b){a.deprecated("tooltipContent","use chart.tooltip.contentGenerator() instead"),k.contentGenerator(b)}},margin:{get:function(){return l},set:function(a){l.top=void 0!==a.top?a.top:l.top,l.right=void 0!==a.right?a.right:l.right,l.bottom=void 0!==a.bottom?a.bottom:l.bottom,l.left=void 0!==a.left?a.left:l.left}},duration:{get:function(){return C},set:function(a){C=a,F.reset(C),e.duration(C),f.duration(C),g.duration(C)}},color:{get:function(){return o},set:function(b){o=a.utils.getColor(b),h.color(o),e.color(o)}},rightAlignYAxis:{get:function(){return t},set:function(a){t=a,g.orient(t?"right":"left")}},useInteractiveGuideline:{get:function(){return u},set:function(a){u=!!a,b.interactive(!a),b.useVoronoi(!a),e.scatter.interactive(!a)}}}),a.utils.inheritOptions(b,e),a.utils.initOptions(b),b},a.models.sunburst=function(){"use strict";function b(u){return t.reset(),u.each(function(b){function t(a){a.x0=a.x,a.dx0=a.dx}function u(a){var b=d3.interpolate(p.domain(),[a.x,a.x+a.dx]),c=d3.interpolate(q.domain(),[a.y,1]),d=d3.interpolate(q.range(),[a.y?20:0,y]);return function(a,e){return e?function(){return s(a)}:function(e){return p.domain(b(e)),q.domain(c(e)).range(d(e)),s(a)}}}l=d3.select(this);var v,w=a.utils.availableWidth(g,l,f),x=a.utils.availableHeight(h,l,f),y=Math.min(w,x)/2;a.utils.initSVG(l);var z=l.selectAll(".nv-wrap.nv-sunburst").data(b),A=z.enter().append("g").attr("class","nvd3 nv-wrap nv-sunburst nv-chart-"+k),B=A.selectAll("nv-sunburst");z.attr("transform","translate("+w/2+","+x/2+")"),l.on("click",function(a,b){o.chartClick({data:a,index:b,pos:d3.event,id:k})}),q.range([0,y]),c=c||b,e=b[0],r.value(j[i]||j.count),v=B.data(r.nodes).enter().append("path").attr("d",s).style("fill",function(a){return m((a.children?a:a.parent).name)}).style("stroke","#FFF").on("click",function(a){d!==c&&c!==a&&(d=c),c=a,v.transition().duration(n).attrTween("d",u(a))}).each(t).on("dblclick",function(a){d.parent==a&&v.transition().duration(n).attrTween("d",u(e))}).each(t).on("mouseover",function(a){d3.select(this).classed("hover",!0).style("opacity",.8),o.elementMouseover({data:a,color:d3.select(this).style("fill")})}).on("mouseout",function(a){d3.select(this).classed("hover",!1).style("opacity",1),o.elementMouseout({data:a})}).on("mousemove",function(a){o.elementMousemove({data:a})})}),t.renderEnd("sunburst immediate"),b}var c,d,e,f={top:0,right:0,bottom:0,left:0},g=null,h=null,i="count",j={count:function(){return 1},size:function(a){return a.size}},k=Math.floor(1e4*Math.random()),l=null,m=a.utils.defaultColor(),n=500,o=d3.dispatch("chartClick","elementClick","elementDblClick","elementMousemove","elementMouseover","elementMouseout","renderEnd"),p=d3.scale.linear().range([0,2*Math.PI]),q=d3.scale.sqrt(),r=d3.layout.partition().sort(null).value(function(){return 1}),s=d3.svg.arc().startAngle(function(a){return Math.max(0,Math.min(2*Math.PI,p(a.x)))}).endAngle(function(a){return Math.max(0,Math.min(2*Math.PI,p(a.x+a.dx)))}).innerRadius(function(a){return Math.max(0,q(a.y))}).outerRadius(function(a){return Math.max(0,q(a.y+a.dy))}),t=a.utils.renderWatch(o);return b.dispatch=o,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return g},set:function(a){g=a}},height:{get:function(){return h},set:function(a){h=a}},mode:{get:function(){return i},set:function(a){i=a}},id:{get:function(){return k},set:function(a){k=a}},duration:{get:function(){return n},set:function(a){n=a}},margin:{get:function(){return f},set:function(a){f.top=void 0!=a.top?a.top:f.top,f.right=void 0!=a.right?a.right:f.right,f.bottom=void 0!=a.bottom?a.bottom:f.bottom,f.left=void 0!=a.left?a.left:f.left}},color:{get:function(){return m},set:function(b){m=a.utils.getColor(b)}}}),a.utils.initOptions(b),b},a.models.sunburstChart=function(){"use strict";function b(d){return m.reset(),m.models(c),d.each(function(d){var h=d3.select(this);a.utils.initSVG(h);var i=a.utils.availableWidth(f,h,e),j=a.utils.availableHeight(g,h,e);if(b.update=function(){0===k?h.call(b):h.transition().duration(k).call(b)},b.container=this,!d||!d.length)return a.utils.noData(b,h),b;h.selectAll(".nv-noData").remove();var l=h.selectAll("g.nv-wrap.nv-sunburstChart").data(d),m=l.enter().append("g").attr("class","nvd3 nv-wrap nv-sunburstChart").append("g"),n=l.select("g");m.append("g").attr("class","nv-sunburstWrap"),l.attr("transform","translate("+e.left+","+e.top+")"),c.width(i).height(j);var o=n.select(".nv-sunburstWrap").datum(d);d3.transition(o).call(c)}),m.renderEnd("sunburstChart immediate"),b}var c=a.models.sunburst(),d=a.models.tooltip(),e={top:30,right:20,bottom:20,left:20},f=null,g=null,h=a.utils.defaultColor(),i=(Math.round(1e5*Math.random()),null),j=null,k=250,l=d3.dispatch("tooltipShow","tooltipHide","stateChange","changeState","renderEnd"),m=a.utils.renderWatch(l);return d.headerEnabled(!1).duration(0).valueFormatter(function(a){return a}),c.dispatch.on("elementMouseover.tooltip",function(a){a.series={key:a.data.name,value:a.data.size,color:a.color},d.data(a).hidden(!1)}),c.dispatch.on("elementMouseout.tooltip",function(){d.hidden(!0)}),c.dispatch.on("elementMousemove.tooltip",function(){d.position({top:d3.event.pageY,left:d3.event.pageX})()}),b.dispatch=l,b.sunburst=c,b.tooltip=d,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{noData:{get:function(){return j},set:function(a){j=a}},defaultState:{get:function(){return i},set:function(a){i=a}},color:{get:function(){return h},set:function(a){h=a,c.color(h)}},duration:{get:function(){return k},set:function(a){k=a,m.reset(k),c.duration(k)}},margin:{get:function(){return e},set:function(a){e.top=void 0!==a.top?a.top:e.top,e.right=void 0!==a.right?a.right:e.right,e.bottom=void 0!==a.bottom?a.bottom:e.bottom,e.left=void 0!==a.left?a.left:e.left}}}),a.utils.inheritOptions(b,c),a.utils.initOptions(b),b},a.version="1.8.1"}(); \ No newline at end of file diff --git a/backend/coverage-report/dashboard.html b/backend/coverage-report/dashboard.html deleted file mode 100644 index 9c3e94a7..00000000 --- a/backend/coverage-report/dashboard.html +++ /dev/null @@ -1,670 +0,0 @@ - - - - - Dashboard for /var/www/html/backend/app - - - - - - - -
-
-
-
- -
-
-
-
-
-
-
-

Classes

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
-
-
-

Insufficient Coverage

-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
ClassCoverage
App\Console\Commands\SyncChannelPostsCommand0%
App\Exceptions\PlatformAuthException0%
App\Exceptions\PublishException0%
App\Exceptions\RoutingMismatchException0%
App\Http\Controllers\Api\V1\AuthController0%
App\Http\Controllers\Api\V1\LogsController0%
App\Http\Controllers\Api\V1\PlatformAccountsController0%
App\Http\Controllers\Api\V1\PlatformChannelsController0%
App\Http\Controllers\Api\V1\RoutingController0%
App\Http\Controllers\ArticlesController0%
App\Http\Controllers\FeedsController0%
App\Http\Controllers\LogsController0%
App\Http\Controllers\OnboardingController0%
App\Http\Controllers\PlatformAccountsController0%
App\Http\Controllers\PlatformChannelsController0%
App\Http\Controllers\RoutingController0%
App\Http\Controllers\SettingsController0%
App\Http\Middleware\HandleAppearance0%
App\Http\Middleware\HandleInertiaRequests0%
App\Http\Resources\ArticlePublicationResource0%
App\Http\Resources\PlatformAccountResource0%
App\Http\Resources\PlatformChannelResource0%
App\Http\Resources\PlatformInstanceResource0%
App\Http\Resources\RouteResource0%
App\Listeners\LogExceptionToDatabase0%
App\Models\Keyword0%
App\Models\PlatformAccount0%
App\Models\PlatformChannel0%
App\Models\PlatformChannelPost0%
App\Models\PlatformInstance0%
App\Modules\Lemmy\LemmyRequest0%
App\Modules\Lemmy\Services\LemmyApiService0%
App\Modules\Lemmy\Services\LemmyPublisher0%
App\Services\Auth\LemmyAuthService0%
App\Services\OnboardingRedirectService0%
App\Services\Parsers\BelgaArticlePageParser0%
App\Services\Parsers\BelgaHomepageParser0%
App\Services\Parsers\VrtArticlePageParser0%
App\Services\Parsers\VrtHomepageParser0%
App\Services\Publishing\ArticlePublishingService0%
App\Services\RoutingValidationService0%
App\Services\SystemStatusService0%
App\Jobs\SyncChannelPostsJob2%
App\Models\Feed8%
App\Jobs\PublishToLemmyJob16%
App\Services\Http\HttpFetcher22%
App\Services\Parsers\BelgaHomepageParserAdapter25%
App\Services\Parsers\VrtHomepageParserAdapter25%
App\Services\Parsers\BelgaArticleParser33%
App\Services\Parsers\VrtArticleParser33%
App\Services\Factories\ArticleParserFactory36%
App\Services\Article\ArticleFetcher45%
App\Services\Article\ValidationService48%
App\Models\Route50%
App\Listeners\ValidateArticleListener53%
App\Services\Log\LogSaver58%
App\Models\Language60%
App\Jobs\ArticleDiscoveryJob71%
App\Console\Commands\FetchNewArticlesCommand75%
App\Providers\HorizonServiceProvider75%
App\Http\Controllers\Api\V1\FeedsController76%
App\Listeners\PublishApprovedArticle80%
App\Providers\AppServiceProvider82%
App\Http\Controllers\Api\V1\DashboardController84%
App\Http\Controllers\Api\V1\SettingsController85%
App\Http\Controllers\Api\V1\BaseController87%
App\Services\Factories\HomepageParserFactory87%
App\Http\Controllers\Api\V1\ArticlesController87%
-
-
-
-

Project Risks

-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
ClassCRAP
App\Http\Controllers\OnboardingController506
App\Modules\Lemmy\Services\LemmyApiService462
App\Http\Controllers\Api\V1\RoutingController306
App\Services\Parsers\BelgaArticlePageParser306
App\Http\Controllers\RoutingController240
App\Http\Controllers\Api\V1\PlatformAccountsController210
App\Services\Parsers\VrtArticlePageParser210
App\Http\Controllers\Api\V1\PlatformChannelsController182
App\Jobs\SyncChannelPostsJob170
App\Models\Feed143
App\Http\Controllers\Api\V1\AuthController132
App\Http\Controllers\PlatformAccountsController110
App\Http\Controllers\PlatformChannelsController110
App\Models\PlatformAccount110
App\Http\Controllers\FeedsController90
App\Services\SystemStatusService72
App\Services\Http\HttpFetcher46
App\Modules\Lemmy\LemmyRequest42
App\Services\Auth\LemmyAuthService42
App\Services\Article\ArticleFetcher30
App\Exceptions\PublishException30
App\Services\Publishing\ArticlePublishingService30
App\Services\RoutingValidationService30
App\Http\Controllers\Api\V1\FeedsController15
App\Services\Factories\ArticleParserFactory15
App\Console\Commands\SyncChannelPostsCommand12
App\Http\Controllers\Api\V1\LogsController12
App\Http\Controllers\SettingsController12
App\Listeners\ValidateArticleListener11
App\Services\Article\ValidationService8
App\Services\Log\LogSaver8
App\Jobs\PublishToLemmyJob8
App\Http\Controllers\Api\V1\SettingsController7
App\Providers\AppServiceProvider6
App\Http\Controllers\Api\V1\BaseController6
App\Services\OnboardingRedirectService6
App\Services\Factories\HomepageParserFactory5
App\Http\Controllers\Api\V1\ArticlesController5
App\Listeners\PublishApprovedArticle4
App\Jobs\ArticleDiscoveryJob3
App\Console\Commands\FetchNewArticlesCommand3
App\Http\Controllers\Api\V1\DashboardController3
-
-
-
-
-
-

Methods

-
-
-
-
-

Coverage Distribution

-
- -
-
-
-

Complexity

-
- -
-
-
-
-
-

Insufficient Coverage

-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
MethodCoverage
handle0%
syncLemmy0%
__construct0%
getPlatform0%
__construct0%
getArticle0%
getPlatform0%
__construct0%
login0%
register0%
logout0%
me0%
sendNotFound0%
sendUnauthorized0%
index0%
index0%
store0%
show0%
update0%
destroy0%
setActive0%
index0%
store0%
show0%
update0%
destroy0%
toggle0%
index0%
store0%
show0%
update0%
destroy0%
toggle0%
__invoke0%
approve0%
reject0%
index0%
create0%
store0%
show0%
edit0%
update0%
destroy0%
toggle0%
__invoke0%
index0%
platform0%
feed0%
channel0%
complete0%
needsOnboarding0%
hasPlatformAccount0%
hasFeed0%
hasChannel0%
index0%
create0%
store0%
edit0%
update0%
destroy0%
setActive0%
index0%
create0%
store0%
show0%
edit0%
update0%
destroy0%
toggle0%
index0%
create0%
store0%
edit0%
update0%
destroy0%
toggle0%
parseJsonFilters0%
index0%
update0%
handle0%
version0%
share0%
toArray0%
toArray0%
toArray0%
toArray0%
toArray0%
handle0%
dispatchForAllActiveChannels0%
handle0%
syncLemmyChannelPosts0%
getAuthToken0%
handle0%
getTypeDisplayAttribute0%
getStatusAttribute0%
channels0%
activeChannels0%
feed0%
platformChannel0%
platformChannels0%
feeds0%
password0%
apiToken0%
getActive0%
setAsActive0%
channels0%
activeChannels0%
platformInstance0%
platformAccounts0%
activePlatformAccounts0%
getFullNameAttribute0%
feeds0%
activeFeeds0%
language0%
casts0%
urlExists0%
storePost0%
channels0%
languages0%
findByUrl0%
keywords0%
__construct0%
get0%
post0%
withToken0%
__construct0%
login0%
getCommunityId0%
syncChannelPosts0%
createPost0%
getLanguages0%
__construct0%
publishToChannel0%
mapExceptionToLogLevel0%
saveArticle0%
validateByKeywords0%
getToken0%
getSupportedSources0%
registerParser0%
fetchMultipleUrls0%
debug0%
handleRedirect0%
extractTitle0%
extractDescription0%
extractFullArticle0%
extractThumbnail0%
extractData0%
extractData0%
getSourceName0%
extractArticleUrls0%
extractArticleUrls0%
getHomepageUrl0%
getSourceName0%
extractTitle0%
extractDescription0%
extractFullArticle0%
extractThumbnail0%
extractData0%
extractData0%
getSourceName0%
extractArticleUrls0%
extractArticleUrls0%
getHomepageUrl0%
getSourceName0%
publishToRoutedChannels0%
publishToChannel0%
validateLanguageCompatibility0%
getSystemStatus0%
canProcessArticles0%
getArticlesFromWebsiteFeed38%
getArticlesFromFeed44%
handle53%
log53%
update63%
store66%
handle66%
gate66%
validate66%
approve71%
reject71%
destroy71%
index71%
handle75%
toggle77%
handle80%
getParser80%
getParser80%
stats83%
fetchArticleData88%
-
-
- -
- -
- - - - - - diff --git a/backend/coverage-report/index.html b/backend/coverage-report/index.html deleted file mode 100644 index 83f8ae56..00000000 --- a/backend/coverage-report/index.html +++ /dev/null @@ -1,424 +0,0 @@ - - - - - Code Coverage for /var/www/html/backend/app - - - - - - - -
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
-
- 26.08% covered (danger) -
-
-
26.08%
434 / 1664
-
- 26.54% covered (danger) -
-
-
26.54%
69 / 260
-
- 20.00% covered (danger) -
-
-
20.00%
17 / 85
Console
-
- 37.50% covered (danger) -
-
-
37.50%
6 / 16
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
Contracts
n/a
0 / 0
n/a
0 / 0
n/a
0 / 0
Enums
n/a
0 / 0
n/a
0 / 0
n/a
0 / 0
Events
-
- 100.00% covered (success) -
-
-
100.00%
5 / 5
-
- 100.00% covered (success) -
-
-
100.00%
5 / 5
-
- 100.00% covered (success) -
-
-
100.00%
5 / 5
Exceptions
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 19
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 6
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
Http
-
- 20.07% covered (danger) -
-
-
20.07%
164 / 817
-
- 12.87% covered (danger) -
-
-
12.87%
13 / 101
-
- 13.79% covered (danger) -
-
-
13.79%
4 / 29
Jobs
-
- 40.74% covered (danger) -
-
-
40.74%
33 / 81
-
- 50.00% covered (danger) -
-
-
50.00%
6 / 12
-
- 25.00% covered (danger) -
-
-
25.00%
1 / 4
Listeners
-
- 55.81% covered (warning) -
-
-
55.81%
24 / 43
-
- 40.00% covered (danger) -
-
-
40.00%
2 / 5
-
- 25.00% covered (danger) -
-
-
25.00%
1 / 4
Models
-
- 40.13% covered (danger) -
-
-
40.13%
61 / 152
-
- 48.15% covered (danger) -
-
-
48.15%
26 / 54
-
- 33.33% covered (danger) -
-
-
33.33%
4 / 12
Modules
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 120
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 12
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 3
Providers
-
- 81.82% covered (warning) -
-
-
81.82%
27 / 33
-
- 40.00% covered (danger) -
-
-
40.00%
2 / 5
-
- 0.00% covered (danger) -
-
-
0.00%
0 / 2
Services
-
- 28.84% covered (danger) -
-
-
28.84%
107 / 371
-
- 25.00% covered (danger) -
-
-
25.00%
14 / 56
-
- 5.00% covered (danger) -
-
-
5.00%
1 / 20
LogLevelEnum.php
-
- 100.00% covered (success) -
-
-
100.00%
7 / 7
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
-
- 100.00% covered (success) -
-
-
100.00%
1 / 1
-
- -
- -