[
  {
    "path": ".aspire/settings.json",
    "content": "{\n  \"appHostPath\": \"../src/Clean.Architecture.AspireHost/Clean.Architecture.AspireHost.csproj\"\n}"
  },
  {
    "path": ".editorconfig",
    "content": "###############################\n# Core EditorConfig Options   #\n###############################\nroot = true\n# All files\n[*]\nindent_style = space\n\n# XML project files\n[*.{csproj,vbproj,vcxproj,vcxproj.filters,proj,projitems,shproj}]\nindent_size = 2\n\n# XML config files\n[*.{props,targets,ruleset,config,nuspec,resx,vsixmanifest,vsct}]\nindent_size = 2\n\n# Code files\n[*.{cs,csx,vb,vbx}]\nindent_size = 2\ninsert_final_newline = true\ncharset = utf-8-bom\n###############################\n# .NET Coding Conventions     #\n###############################\n[*.{cs,vb}]\n# Organize usings\ndotnet_sort_system_directives_first = true\n# this. preferences\ndotnet_style_qualification_for_field = false:silent\ndotnet_style_qualification_for_property = false:silent\ndotnet_style_qualification_for_method = false:silent\ndotnet_style_qualification_for_event = false:silent\n# Language keywords vs BCL types preferences\ndotnet_style_predefined_type_for_locals_parameters_members = true:silent\ndotnet_style_predefined_type_for_member_access = true:silent\n# Parentheses preferences\ndotnet_style_parentheses_in_arithmetic_binary_operators = always_for_clarity:silent\ndotnet_style_parentheses_in_relational_binary_operators = always_for_clarity:silent\ndotnet_style_parentheses_in_other_binary_operators = always_for_clarity:silent\ndotnet_style_parentheses_in_other_operators = never_if_unnecessary:silent\n# Modifier preferences\ndotnet_style_require_accessibility_modifiers = for_non_interface_members:silent\ndotnet_style_readonly_field = true:suggestion\n# Expression-level preferences\ndotnet_style_object_initializer = true:suggestion\ndotnet_style_collection_initializer = true:suggestion\ndotnet_style_explicit_tuple_names = true:suggestion\ndotnet_style_null_propagation = true:suggestion\ndotnet_style_coalesce_expression = true:suggestion\ndotnet_style_prefer_is_null_check_over_reference_equality_method = true:silent\ndotnet_style_prefer_inferred_tuple_names = true:suggestion\ndotnet_style_prefer_inferred_anonymous_type_member_names = true:suggestion\ndotnet_style_prefer_auto_properties = true:silent\ndotnet_style_prefer_conditional_expression_over_assignment = true:silent\ndotnet_style_prefer_conditional_expression_over_return = true:silent\n###############################\n# Naming Conventions          #\n###############################\n# Style Definitions\ndotnet_naming_style.pascal_case_style.capitalization             = pascal_case\n# Use PascalCase for constant fields  \ndotnet_naming_rule.constant_fields_should_be_pascal_case.severity = suggestion\ndotnet_naming_rule.constant_fields_should_be_pascal_case.symbols  = constant_fields\ndotnet_naming_rule.constant_fields_should_be_pascal_case.style = pascal_case_style\ndotnet_naming_symbols.constant_fields.applicable_kinds            = field\ndotnet_naming_symbols.constant_fields.applicable_accessibilities  = *\ndotnet_naming_symbols.constant_fields.required_modifiers          = const\ntab_width= 2\ndotnet_naming_rule.private_members_with_underscore.symbols  = private_fields\ndotnet_naming_rule.private_members_with_underscore.style = prefix_underscore\ndotnet_naming_rule.private_members_with_underscore.severity = suggestion\ndotnet_naming_symbols.private_fields.applicable_kinds           = field\ndotnet_naming_symbols.private_fields.applicable_accessibilities = private\ndotnet_naming_style.prefix_underscore.capitalization = camel_case\ndotnet_naming_style.prefix_underscore.required_prefix = _\ndotnet_style_operator_placement_when_wrapping = beginning_of_line\nend_of_line = crlf\n###############################\n# C# Coding Conventions       #\n###############################\n[*.cs]\n# var preferences\ncsharp_style_var_for_built_in_types = true:silent\ncsharp_style_var_when_type_is_apparent = true:silent\ncsharp_style_var_elsewhere = true:silent\n# Expression-bodied members\ncsharp_style_expression_bodied_methods = false:silent\ncsharp_style_expression_bodied_constructors = false:silent\ncsharp_style_expression_bodied_operators = false:silent\ncsharp_style_expression_bodied_properties = true:silent\ncsharp_style_expression_bodied_indexers = true:silent\ncsharp_style_expression_bodied_accessors = true:silent\n# Pattern matching preferences\ncsharp_style_pattern_matching_over_is_with_cast_check = true:suggestion\ncsharp_style_pattern_matching_over_as_with_null_check = true:suggestion\n# Null-checking preferences\ncsharp_style_throw_expression = true:suggestion\ncsharp_style_conditional_delegate_call = true:suggestion\n# Modifier preferences\ncsharp_preferred_modifier_order = public,private,protected,internal,static,extern,new,virtual,abstract,sealed,override,readonly,unsafe,volatile,async:suggestion\n# Expression-level preferences\ncsharp_prefer_braces = true:silent\ncsharp_style_deconstructed_variable_declaration = true:suggestion\ncsharp_prefer_simple_default_expression = true:suggestion\ncsharp_style_pattern_local_over_anonymous_function = true:suggestion\ncsharp_style_inlined_variable_declaration = true:suggestion\n# Namespaces\ncsharp_style_namespace_declarations = file_scoped:warning\n###############################\n# C# Formatting Rules         #\n###############################\n# New line preferences\ncsharp_new_line_before_open_brace = all\ncsharp_new_line_before_else = true\ncsharp_new_line_before_catch = true\ncsharp_new_line_before_finally = true\ncsharp_new_line_before_members_in_object_initializers = true\ncsharp_new_line_before_members_in_anonymous_types = true\ncsharp_new_line_between_query_expression_clauses = true\n# Indentation preferences\ncsharp_indent_case_contents = true\ncsharp_indent_switch_labels = true\ncsharp_indent_labels = flush_left\n# Space preferences\ncsharp_space_after_cast = false\ncsharp_space_after_keywords_in_control_flow_statements = true\ncsharp_space_between_method_call_parameter_list_parentheses = false\ncsharp_space_between_method_declaration_parameter_list_parentheses = false\ncsharp_space_between_parentheses = false\ncsharp_space_before_colon_in_inheritance_clause = true\ncsharp_space_after_colon_in_inheritance_clause = true\ncsharp_space_around_binary_operators = before_and_after\ncsharp_space_between_method_declaration_empty_parameter_list_parentheses = false\ncsharp_space_between_method_call_name_and_opening_parenthesis = false\ncsharp_space_between_method_call_empty_parameter_list_parentheses = false\n# Wrapping preferences\ncsharp_preserve_single_line_statements = true\ncsharp_preserve_single_line_blocks = true\ncsharp_using_directive_placement = outside_namespace:suggestion\ncsharp_prefer_simple_using_statement = true:suggestion\ncsharp_style_prefer_method_group_conversion = true:silent\ncsharp_style_prefer_top_level_statements = true:silent\ncsharp_style_prefer_primary_constructors = true:suggestion\ncsharp_style_expression_bodied_lambdas = true:silent\ncsharp_style_expression_bodied_local_functions = false:silent\n###############################\n# VB Coding Conventions       #\n###############################\n[*.vb]\n# Modifier preferences\nvisual_basic_preferred_modifier_order = Partial,Default,Private,Protected,Public,Friend,NotOverridable,Overridable,MustOverride,Overloads,Overrides,MustInherit,NotInheritable,Static,Shared,Shadows,ReadOnly,WriteOnly,Dim,Const,WithEvents,Widening,Narrowing,Custom,Async:suggestion"
  },
  {
    "path": ".github/CONTRIBUTING.md",
    "content": "# Contributing to CleanArchitecture\n\n**First:** if you're unsure or afraid of _anything_, just ask or submit the\nissue or pull request anyways. You won't be yelled at for giving your best\neffort. The worst that can happen is that you'll be politely asked to change\nsomething. We appreciate any sort of contributions, and don't want a wall of\nrules to get in the way of that.\n\nHowever, for those individuals who want a bit more guidance on the best way to\ncontribute to the project, read on. This document will cover what we're looking\nfor. By addressing all the points we're looking for, it raises the chances we\ncan quickly merge or address your contributions.\n\n## Issues\n\n### Reporting an Issue\n\n* Make sure you test against the latest released version. It is possible we\n  already fixed the bug you're experiencing.\n  \n* If you can, check and see if there is an existing open issue that is already \n  reporting the problem. Feel free to upvote this issue or comment on it to \n  describe your specific scenario (assuming it's the same underlying issue).\n\n* Provide a reproducible test case. If a contributor can't reproduce an issue,\n  then it dramatically lowers the chances it'll get fixed. And in some cases,\n  the issue will eventually be closed.\n\n* Respond promptly to any questions made by the maintainers about your issue. Stale\n  issues will be closed (eventually).\n\n## Pull Requests\n\n* Pull requests are welcome but are most likely to be accepted when they address\n  an existing issue. A common workflow is to create an issue describing the problem\n  your PR would solve, and then volunteer to submit a PR addressing the issue as an \n  initial comment on the issue.\n  \n* As much as possible, pull requests should follow the existing coding conventions\n  used by the project. This is generally true for any project. The only exception to \n  this would be a pull request whose purpose is to adjust the coding conventions used\n  by the project.\n  \n* When possible, issues will be marked with a `help wanted` tag if community contributions\n  are particularly welcome for them. This will often be the case for relatively simple\n  fixes that would make good initial contributions.\n  \n* If your PR addresses an issue, please include \"Fixes #NNN\" in the summary for the PR\n  so that the issue is linked to the PR (and vice versa) and if/when the PR is merged,\n  the issue is automatically closed.\n  \nThank you for reading this and for considering contributing to this project!\n  \n"
  },
  {
    "path": ".github/FUNDING.yml",
    "content": "# These are supported funding model platforms\n\ngithub: [ardalis]\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/bug_report.md",
    "content": "---\nname: Bug report\nabout: Create a report to help us improve\n---\n<!-- ⚠️⚠️ Do Not Delete This! bug_report_template ⚠️⚠️ -->\n<!-- 🔎 Search existing issues to avoid creating duplicates. -->\n\n- .NET SDK Version:\n\nSteps to Reproduce:\n\n1.\n2.\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/config.yml",
    "content": "blank_issues_enabled: false\ncontact_links:\n  - name: Question\n    url: https://stackoverflow.com/questions/tagged/ardalis-cleanarchitecture\n    about: Please ask and answer questions on Stack Overflow.\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/feature_request.md",
    "content": "---\nname: Feature request\nabout: Suggest an idea for this project\n\n---\n\n<!-- ⚠️⚠️ Do Not Delete This! feature_request_template ⚠️⚠️ -->\n<!-- Please search existing issues to avoid creating duplicates. -->\n\n<!-- Describe the feature you'd like. -->\n"
  },
  {
    "path": ".github/copilot-instructions.md",
    "content": "# GitHub Copilot Instructions for Clean Architecture Template\n\n## Project Overview\nThis is a **Clean Architecture template** for .NET 9 that demonstrates Domain-Driven Design (DDD) patterns. It's a starter template, not a reference application - delete sample code once you understand the patterns.\n\n## Architecture & Project Structure\n\n### C# Conventions\n- Use standard Microsoft naming conventions\n- Use `PascalCase` for types and methods, `camelCase` for parameters and private fields\n- Use `I` prefix for interfaces (e.g., `IRepository`)\n- Use `Async` suffix for async methods (e.g., `GetByIdAsync`)\n- Prefix private fields with `_` (e.g., `_repository`)\n- Always use {} for blocks except single-line exits (e.g. `return`, `throw`)\n- Always keep single line blocks on one line (e.g., `if (x) return y;`)\n- Prefer primary constructors for required dependencies\n- Never use primary constructor parameters directly - always assign to private fields for clarity and testability\n\n### Core Dependencies Flow\n- **Core** ← UseCases ← Infrastructure \n- **Core** ← UseCases ← Web\n- Never allow Core to depend on outer layers\n\n### Key Projects\n- **Core**: Domain entities, aggregates, value objects, specifications, interfaces\n- **UseCases**: Commands/queries (CQRS), Mediator handlers, application logic  \n- **Infrastructure**: EF Core, external services, email, file access\n- **Web**: FastEndpoints API, REPR pattern, validation\n\n## Development Patterns\n\n### API Endpoints (FastEndpoints + REPR)\n- One endpoint per file: `Create.cs`, `Update.cs`, `Delete.cs`, `GetById.cs`\n- Separate request/response/validator files: `Create.CreateRequest.cs`, `Create.CreateValidator.cs`\n- Use `Endpoint<TRequest, TResponse>` base class\n- Example: `src/Clean.Architecture.Web/Contributors/Create.cs`\n\n### Domain Model (Core)\n- Entities use encapsulation - minimize public setters\n- Group related entities into Aggregates\n- Use Value Objects (e.g., `ContributorName.From()`)\n- Domain Events for cross-aggregate communication\n- Repository interfaces defined in Core, implemented in Infrastructure\n\n### Use Cases (CQRS)\n- Commands for mutations, Queries for reads\n- Queries can bypass repository pattern for performance\n- Use Mediator (source generator) for command/query handling\n- Chain of responsibility for cross-cutting concerns (logging, validation)\n\n### Validation Strategy\n- **API Level**: FluentValidation on request DTOs (FastEndpoints integration)\n- **Use Case Level**: Validate commands/queries (defensive coding)\n- **Domain Level**: Business invariants throw exceptions, assume pre-validated input\n\n## Essential Commands\n\n### Build & Test\n```bash\ndotnet build Clean.Architecture.slnx\ndotnet test Clean.Architecture.slnx\n```\n\n### Entity Framework Migrations\n```bash\n# From Web project directory\ndotnet ef migrations add MigrationName -c AppDbContext -p ../Clean.Architecture.Infrastructure/Clean.Architecture.Infrastructure.csproj -s Clean.Architecture.Web.csproj -o Data/Migrations\n\ndotnet ef database update -c AppDbContext -p ../Clean.Architecture.Infrastructure/Clean.Architecture.Infrastructure.csproj -s Clean.Architecture.Web.csproj\n```\n\n### Template Installation & Usage\n```bash\ndotnet new install Ardalis.CleanArchitecture.Template\ndotnet new clean-arch -o Your.ProjectName\n```\n\n## Key Dependencies & Patterns\n\n### Primary Libraries\n- **FastEndpoints**: API endpoints (replaced Controllers/Minimal APIs)\n- **Mediator**: Command/query handling in UseCases\n- **EF Core**: Data access (SQLite default, easily changed to SQL Server)\n- **Ardalis.Specification**: Repository query specifications\n- **Ardalis.Result**: Error handling pattern\n- **Serilog**: Structured logging\n\n### Central Package Management\n- All package versions in `Directory.Packages.props`\n- Use `<PackageReference Include=\"...\" />` without Version attribute\n\n### Test Organization\n- **UnitTests**: Core business logic, use cases\n- **IntegrationTests**: Database, infrastructure components  \n- **FunctionalTests**: API endpoints (subcutaneous testing)\n- Use `Microsoft.AspNetCore.Mvc.Testing` for API tests\n\n## File Organization Conventions\n\n### Web Project Structure\n```\nContributors/\n  Create.cs                    # Endpoint\n  Create.CreateRequest.cs      # Request DTO\n  Create.CreateResponse.cs     # Response DTO  \n  Create.CreateValidator.cs    # FluentValidation\n  Update.cs, Delete.cs, etc.\n```\n\n### Sample vs Template\n- `/sample` folder: Complete working example (NimblePros.SampleToDo)\n- `/src` folder: Clean template ready for your project\n- Study sample for patterns, use src for new projects\n\n## Common Gotchas\n\n- Don't include hyphens in project names (template limitation)\n- Replace `Ardalis.SharedKernel` with your own shared kernel\n- Database path in `appsettings.json` for SQLite\n- Use absolute paths in EF migration commands\n- FastEndpoints uses different validation approach than Controller-based APIs\n\n## VS Code Tasks\nUse the predefined tasks: `build`, `publish`, `watch` instead of manual `dotnet` commands when possible.\n"
  },
  {
    "path": ".github/dependabot.yml",
    "content": "version: 2\nupdates:\n- package-ecosystem: nuget\n  directory: \"/\"\n  schedule:\n    interval: daily\n  open-pull-requests-limit: 10\n"
  },
  {
    "path": ".github/workflows/build-ramdisk.yml",
    "content": "name: Build and Test with Ramdisk\n\non:\n  push:\n    branches:\n      - main\n  pull_request:\n\njobs:\n  build-and-test:\n    runs-on: ubuntu-latest\n\n    steps:\n      # Step 1: Checkout the repository\n      - name: Checkout Code\n        uses: actions/checkout@v3\n\n      # Step 2: Set up .NET environment\n      - name: Setup .NET\n        uses: actions/setup-dotnet@v5\n        with:\n          dotnet-version: 10.0.x\n\n      # Step 3: Prepare a directory in /dev/shm\n      - name: Set up Ramdisk Directory\n        run: |\n          mkdir -p /dev/shm/ramdisk/project\n\n      # Step 4: Copy source code to the ramdisk\n      - name: Copy Code to Ramdisk\n        run: |\n          cp -r $GITHUB_WORKSPACE/* /dev/shm/ramdisk/project\n\n      # Step 5: Debug Directory Contents\n      - name: Debug Directory\n        run: |\n          ls -R /dev/shm/ramdisk/project\n\n      # Step 6: Build and Test from the ramdisk\n      - name: Build and Test\n        run: |\n          cd /dev/shm/ramdisk/project\n          dotnet build Clean.Architecture.slnx --configuration Debug\n          dotnet test Clean.Architecture.slnx --\n"
  },
  {
    "path": ".github/workflows/codeql-analysis.yml",
    "content": "name: CodeQL Analysis\n\non:\n  push:\n    branches: [ main ]\n  pull_request:\n  schedule:\n    - cron: '0 8 * * *'\n\njobs:\n  analyze:\n    name: CodeQL Analysis\n    runs-on: ubuntu-latest\n    steps:\n      - name: Checkout repository\n        id: checkout_repo\n        uses: actions/checkout@v4\n\n      - name: Initialize CodeQL\n        id: init_codeql\n        uses: github/codeql-action/init@v3\n        with:\n          queries: security-and-quality\n\n      - name: Autobuild\n        uses: github/codeql-action/autobuild@v3\n\n      - name: Perform CodeQL Analysis\n        id: analyze_codeql\n        uses: github/codeql-action/analyze@v3\n\n# Built with ❤ by [Pipeline Foundation](https://pipeline.foundation)\n"
  },
  {
    "path": ".github/workflows/dotnetcore.yml",
    "content": "name: .NET Core\n\non:\n  push:\n    branches: [ main ]\n  pull_request:\n    branches: [ main ]\n\njobs:\n  build:\n\n    runs-on: ubuntu-latest\n\n    steps:\n    - uses: actions/checkout@v2\n    - name: Setup .NET Core\n      uses: actions/setup-dotnet@v5\n      with:\n        dotnet-version: '10.0.x'\n    - name: Build Full Template\n      run: dotnet build ./Clean.Architecture.slnx -c Release\n    - name: Test Full Template\n      run: dotnet test ./Clean.Architecture.slnx -c Release --no-build --verbosity normal\n    - name: Build MinimalClean Template\n      run: dotnet build ./MinimalClean/MinimalClean.Architecture.slnx -c Release\n"
  },
  {
    "path": ".github/workflows/publish-templates.yml",
    "content": "name: Publish Templates to NuGet\n\non:\n  workflow_dispatch:\n    inputs:\n      publish-full:\n        description: 'Publish Full Clean Architecture Template'\n        required: true\n        type: boolean\n        default: false\n      publish-minimal:\n        description: 'Publish Minimal Clean Architecture Template'\n        required: true\n        type: boolean\n        default: false\n  push:\n    tags:\n      - 'v*'\n  release:\n    types: [published]\n\nenv:\n  DOTNET_VERSION: '10.0.x'\n  PACK_OUTPUT: artifacts/packages\n\njobs:\n  build-and-test:\n    runs-on: ubuntu-latest\n    \n    steps:\n      - name: Checkout\n        uses: actions/checkout@v4\n\n      - name: Setup .NET\n        uses: actions/setup-dotnet@v4\n        with:\n          dotnet-version: ${{ env.DOTNET_VERSION }}\n\n      - name: Build Full Template Solution\n        run: dotnet build ./Clean.Architecture.slnx -c Release\n\n      - name: Test Full Template\n        run: dotnet test ./Clean.Architecture.slnx -c Release --no-build --verbosity normal\n\n      - name: Build MinimalClean Template Solution\n        run: dotnet build ./MinimalClean/MinimalClean.Architecture.slnx -c Release\n\n      - name: Test Template Installations\n        shell: pwsh\n        run: |\n          # Test Full Template\n          # Write-Host \"Testing Full Clean Architecture Template...\"\n          # dotnet new install .\n          # dotnet new clean-arch -o TestFullTemplate\n          # dotnet build TestFullTemplate/TestFullTemplate.slnx\n          # dotnet new uninstall Ardalis.CleanArchitecture.Template\n          # Remove-Item -Recurse -Force TestFullTemplate\n          \n          # Test Minimal Template\n          # Write-Host \"Testing Minimal Clean Architecture Template...\"\n          # dotnet new install ./MinimalClean\n          # dotnet new min-clean -o TestMinimalTemplate\n          # dotnet build TestMinimalTemplate/TestMinimalTemplate.slnx\n          # dotnet new uninstall Ardalis.MinimalClean.Template\n          # Remove-Item -Recurse -Force TestMinimalTemplate\n\n  package:\n    needs: build-and-test\n    runs-on: ubuntu-latest\n    \n    steps:\n      - name: Checkout\n        uses: actions/checkout@v4\n\n      - name: Setup NuGet\n        uses: nuget/setup-nuget@v2\n        with:\n          nuget-version: 'latest'\n\n      - name: Install Mono\n        run: sudo apt-get update && sudo apt-get install -y mono-complete          \n\n      - name: Create output directory\n        run: mkdir -p ${{ env.PACK_OUTPUT }}\n\n      - name: Pack Full Template\n        if: ${{ github.event_name == 'release' || github.event.inputs.publish-full == 'true' }}\n        run: nuget pack CleanArchitecture.nuspec -OutputDirectory ${{ env.PACK_OUTPUT }} -NoDefaultExcludes\n\n      - name: Pack Minimal Template\n        if: ${{ github.event_name == 'release' || github.event.inputs.publish-minimal == 'true' }}\n        run: nuget pack MinimalClean.nuspec -OutputDirectory ${{ env.PACK_OUTPUT }} -NoDefaultExcludes\n\n      - name: Upload packages as artifacts\n        uses: actions/upload-artifact@v4\n        with:\n          name: nuget-packages\n          path: ${{ env.PACK_OUTPUT }}/*.nupkg\n\n  publish:\n    needs: package\n    runs-on: ubuntu-latest\n    #if: ${{ github.event_name == 'release' && github.event.action == 'published' }}\n    permissions:\n      contents: read\n      id-token: write\n    \n    steps:\n      - name: Download packages\n        uses: actions/download-artifact@v4\n        with:\n          name: nuget-packages\n          path: ${{ env.PACK_OUTPUT }}\n\n      - name: Setup .NET\n        uses: actions/setup-dotnet@v4\n        with:\n          dotnet-version: ${{ env.DOTNET_VERSION }}\n\n      - name: NuGet login (OIDC)\n        uses: NuGet/login@v1\n        id: login\n        with:\n          user: ${{ secrets.NUGET_USER }}\n\n      - name: Push packages to NuGet\n        shell: pwsh\n        run: |\n          Get-ChildItem \"${{ env.PACK_OUTPUT }}\" -Filter *.nupkg | ForEach-Object {\n            Write-Host \"Publishing $($_.Name)...\"\n            dotnet nuget push $_.FullName `\n              --api-key \"${{ steps.login.outputs.NUGET_API_KEY }}\" `\n              --source https://api.nuget.org/v3/index.json `\n              --skip-duplicate\n          }\n"
  },
  {
    "path": ".github/workflows/publish.yml",
    "content": "name: Publish to Nuget\n\non:\n  workflow_dispatch:\n  push:\n    tags:\n      - 'v*'\n  release:\n    types: [published]\n\nenv:\n  SOLUTION_FILE: Clean.Architecture.slnx\n  NUSPEC_FILE: CleanArchitecture.nuspec\n  PACK_OUTPUT: artifacts/package/release\n\njobs:\n  build:\n    permissions:\n      contents: read\n      id-token: write\n    runs-on: ubuntu-latest\n\n    steps:\n      - name: Checkout\n        uses: actions/checkout@v4\n\n      - name: Setup dotnet\n        uses: actions/setup-dotnet@v4\n        with:\n          dotnet-version: 10.0.x\n\n      - name: Build\n        run: dotnet build \"${{ env.SOLUTION_FILE }}\" --configuration Release\n\n      - name: Test\n        run: dotnet test \"${{ env.SOLUTION_FILE }}\" --configuration Release --no-build --no-restore\n\n      - uses: nuget/setup-nuget@v2\n        name: Setup NuGet\n        with:\n          nuget-version: 'latest'\n\n      - name: Install Mono\n        run: sudo apt-get update && sudo apt-get install -y mono-complete\n\n      - name: Pack (nuspec)\n        run: nuget pack \"${{ env.NUSPEC_FILE }}\" -OutputDirectory \"${{ env.PACK_OUTPUT }}\" -NoDefaultExcludes\n\n      - name: NuGet login (OIDC -> temp API key)\n        uses: NuGet/login@v1\n        id: login\n        with:\n          user: ${{ secrets.NUGET_USER }}\n\n      - name: Push to NuGet\n        #if: ${{ github.event_name == 'release' && github.event.action == 'published' && github.event.release.tag_name != '' }}\n        shell: pwsh\n        run: |\n          Get-ChildItem \"${{ env.PACK_OUTPUT }}\" -Filter *.nupkg | ForEach-Object {\n            dotnet nuget push $_.FullName `\n              --api-key \"${{ steps.login.outputs.NUGET_API_KEY }}\" `\n              --source https://api.nuget.org/v3/index.json\n          }\n"
  },
  {
    "path": ".gitignore",
    "content": "## Ignore Visual Studio temporary files, build results, and\n## files generated by popular Visual Studio add-ons.\n\n# User-specific files\n*.suo\n*.user\n*.userosscache\n*.sln.docstates\n\n# User-specific files (MonoDevelop/Xamarin Studio)\n*.userprefs\n\n# Build results\n[Dd]ebug/\n[Dd]ebugPublic/\n[Rr]elease/\n[Rr]eleases/\nx64/\nx86/\nbld/\n[Bb]in/\n[Oo]bj/\n[Ll]og/\n\n# Visual Studio 2015 cache/options directory\n.vs/\n# Uncomment if you have tasks that create the project's static files in wwwroot\n#wwwroot/\n\n# MSTest test Results\n[Tt]est[Rr]esult*/\n[Bb]uild[Ll]og.*\n\n# NUNIT\n*.VisualState.xml\nTestResult.xml\n\n# Build Results of an ATL Project\n[Dd]ebugPS/\n[Rr]eleasePS/\ndlldata.c\n\n# DNX\nproject.lock.json\nartifacts/\n\n*_i.c\n*_p.c\n*_i.h\n*.ilk\n*.meta\n*.obj\n*.pch\n*.pdb\n*.pgc\n*.pgd\n*.rsp\n*.sbr\n*.tlb\n*.tli\n*.tlh\n*.tmp\n*.tmp_proj\n*.log\n*.vspscc\n*.vssscc\n.builds\n*.pidb\n*.svclog\n*.scc\n\n# Chutzpah Test files\n_Chutzpah*\n\n# Visual C++ cache files\nipch/\n*.aps\n*.ncb\n*.opendb\n*.opensdf\n*.sdf\n*.cachefile\n*.VC.db\n*.VC.VC.opendb\n\n# Visual Studio profiler\n*.psess\n*.vsp\n*.vspx\n*.sap\n\n# TFS 2012 Local Workspace\n$tf/\n\n# Guidance Automation Toolkit\n*.gpState\n\n# ReSharper is a .NET coding add-in\n_ReSharper*/\n*.[Rr]e[Ss]harper\n*.DotSettings.user\n\n# JustCode is a .NET coding add-in\n.JustCode\n\n# TeamCity is a build add-in\n_TeamCity*\n\n# DotCover is a Code Coverage Tool\n*.dotCover\n\n# Visual Studio code coverage results\n*.coverage\n*.coveragexml\n\n# NCrunch\n_NCrunch_*\n.*crunch*.local.xml\nnCrunchTemp_*\n\n# MightyMoose\n*.mm.*\nAutoTest.Net/\n\n# Web workbench (sass)\n.sass-cache/\n\n# Installshield output folder\n[Ee]xpress/\n\n# DocProject is a documentation generator add-in\nDocProject/buildhelp/\nDocProject/Help/*.HxT\nDocProject/Help/*.HxC\nDocProject/Help/*.hhc\nDocProject/Help/*.hhk\nDocProject/Help/*.hhp\nDocProject/Help/Html2\nDocProject/Help/html\n\n# Click-Once directory\npublish/\n\n# Publish Web Output\n*.[Pp]ublish.xml\n*.azurePubxml\n# TODO: Comment the next line if you want to checkin your web deploy settings\n# but database connection strings (with potential passwords) will be unencrypted\n*.pubxml\n*.publishproj\n\n# Microsoft Azure Web App publish settings. Comment the next line if you want to\n# checkin your Azure Web App publish settings, but sensitive information contained\n# in these scripts will be unencrypted\nPublishScripts/\n\n# NuGet Packages\n*.nupkg\n# The packages folder can be ignored because of Package Restore\n**/packages/*\n# except build/, which is used as an MSBuild target.\n!**/packages/build/\n# Uncomment if necessary however generally it will be regenerated when needed\n#!**/packages/repositories.config\n# NuGet v3's project.json files produces more ignoreable files\n*.nuget.props\n*.nuget.targets\n\n# Microsoft Azure Build Output\ncsx/\n*.build.csdef\n\n# Microsoft Azure Emulator\necf/\nrcf/\n\n# Windows Store app package directories and files\nAppPackages/\nBundleArtifacts/\nPackage.StoreAssociation.xml\n_pkginfo.txt\n\n# Visual Studio cache files\n# files ending in .cache can be ignored\n*.[Cc]ache\n# but keep track of directories ending in .cache\n!*.[Cc]ache/\n\n# Others\nClientBin/\n~$*\n*~\n*.dbmdl\n*.dbproj.schemaview\n*.pfx\n*.publishsettings\nnode_modules/\norleans.codegen.cs\n\n# Since there are multiple workflows, uncomment next line to ignore bower_components\n# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)\n#bower_components/\n\n# RIA/Silverlight projects\nGenerated_Code/\n\n# Backup & report files from converting an old project file\n# to a newer Visual Studio version. Backup files are not needed,\n# because we have git ;-)\n_UpgradeReport_Files/\nBackup*/\nUpgradeLog*.XML\nUpgradeLog*.htm\n\n# SQL Server files\n*.mdf\n*.ldf\n\n# Business Intelligence projects\n*.rdl.data\n*.bim.layout\n*.bim_*.settings\n\n# Microsoft Fakes\nFakesAssemblies/\n\n# GhostDoc plugin setting file\n*.GhostDoc.xml\n\n# Node.js Tools for Visual Studio\n.ntvs_analysis.dat\n\n# Visual Studio 6 build log\n*.plg\n\n# Visual Studio 6 workspace options file\n*.opt\n\n# Visual Studio LightSwitch build output\n**/*.HTMLClient/GeneratedArtifacts\n**/*.DesktopClient/GeneratedArtifacts\n**/*.DesktopClient/ModelManifest.xml\n**/*.Server/GeneratedArtifacts\n**/*.Server/ModelManifest.xml\n_Pvt_Extensions\n\n# Paket dependency manager\n.paket/paket.exe\npaket-files/\n\n# FAKE - F# Make\n.fake/\n\n# JetBrains Rider\n.idea/\n*.sln.iml\n*.sqlite\n*.sqlite-shm\n*.sqlite-wal\n\n# Nuget files\nDeploymentSettings.props\nPackages.props\n\n#Local Log Files\nlog*.txt\n/sample/src/NimblePros.SampleToDo.Web/appsettings.Development.json\n"
  },
  {
    "path": ".runsettings",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<RunSettings>\n  <RunConfiguration>\n    <!-- Enable parallel test execution at the assembly level -->\n    <MaxCpuCount>0</MaxCpuCount>\n    <!-- 0 means use all available processors -->\n    <DisableParallelization>false</DisableParallelization>\n  </RunConfiguration>\n  \n  <xUnit>\n    <!-- Configure xUnit-specific settings -->\n    <ParallelizeAssembly>true</ParallelizeAssembly>\n    <ParallelizeTestCollections>true</ParallelizeTestCollections>\n    <MaxParallelThreads>0</MaxParallelThreads>\n    <!-- 0 means use default algorithm (processors * 2) -->\n  </xUnit>\n</RunSettings>\n"
  },
  {
    "path": ".template.config/template.json",
    "content": "{\n  \"$schema\": \"http://json.schemastore.org/template\",\n  \"author\": \"ardalis (Steve Smith)\",\n  \"classifications\": [\n    \"Web\",\n    \"ASP.NET\",\n    \"Clean Architecture\"\n  ],\n  \"tags\": {\n    \"language\": \"C#\",\n    \"type\": \"project\"\n  },\n  \"identity\": \"Ardalis.CleanArchitecture.Template\",\n  \"name\": \"ASP.NET Clean Architecture Solution\",\n  \"shortName\": \"clean-arch\",\n  \"sourceName\": \"Clean.Architecture\",\n  \"templateFileExtensions\": [ \".cs\", \".csproj\", \".slnx\" ],\n  \"preferNameDirectory\": true,\n  \"sources\": [\n    {\n      \"include\": [\n        \"**/*\"\n      ],\n      \"exclude\": [ \n        \".vs/**\",\n        \".vscode/**\",\n        \".git/**\",\n        \".github/**\",\n        \".idea/**\",\n        \".template.config/**\",\n        \"docs/**\",\n        \"sample/**\"\n      ],\n      \"modifiers\": [\n        {\n          \"condition\": \"true\",\n          \"copyOnly\": [ \"*.dll\", \"*.png\", \"*.ico\", \"*.jpg\", \"*.jpeg\", \"*.ps1\" ]\n        },\n        {\n          \"rename\": {\n            \"README.template.md\": \"README.md\"\n          }\n        }\n      ]\n    }\n  ]\n}\n"
  },
  {
    "path": ".vscode/launch.json",
    "content": "{\n    \"version\": \"0.2.0\",\n    \"configurations\": [\n        {\n            // Use IntelliSense to find out which attributes exist for C# debugging\n            // Use hover for the description of the existing attributes\n            // For further information visit https://github.com/dotnet/vscode-csharp/blob/main/debugger-launchjson.md.\n            \"name\": \".NET Core Launch (web)\",\n            \"type\": \"coreclr\",\n            \"request\": \"launch\",\n            \"preLaunchTask\": \"build\",\n            // If you have changed target frameworks, make sure to update the program path.\n            \"program\": \"${workspaceFolder}/src/Clean.Architecture.Web/bin/Debug/net8.0/Clean.Architecture.Web.dll\",\n            \"args\": [],\n            \"cwd\": \"${workspaceFolder}/src/Clean.Architecture.Web\",\n            \"stopAtEntry\": false,\n            // Enable launching a web browser when ASP.NET Core starts. For more information: https://aka.ms/VSCode-CS-LaunchJson-WebBrowser\n            \"serverReadyAction\": {\n                \"action\": \"openExternally\",\n                \"pattern\": \"\\\\bNow listening on:\\\\s+(https?://\\\\S+)\"\n            },\n            \"env\": {\n                \"ASPNETCORE_ENVIRONMENT\": \"Development\"\n            },\n            \"sourceFileMap\": {\n                \"/Views\": \"${workspaceFolder}/Views\"\n            }\n        },\n        {\n            \"name\": \".NET Core Attach\",\n            \"type\": \"coreclr\",\n            \"request\": \"attach\"\n        }\n    ]\n}"
  },
  {
    "path": ".vscode/settings.json",
    "content": "{\n    \"workbench.colorCustomizations\": {\n        \"activityBar.activeBackground\": \"#6b9a8e\",\n        \"activityBar.background\": \"#6b9a8e\",\n        \"activityBar.foreground\": \"#15202b\",\n        \"activityBar.inactiveForeground\": \"#15202b99\",\n        \"activityBarBadge.background\": \"#684e72\",\n        \"activityBarBadge.foreground\": \"#e7e7e7\",\n        \"commandCenter.border\": \"#e7e7e799\",\n        \"sash.hoverBorder\": \"#6b9a8e\",\n        \"statusBar.background\": \"#557d73\",\n        \"statusBar.foreground\": \"#e7e7e7\",\n        \"statusBarItem.hoverBackground\": \"#6b9a8e\",\n        \"statusBarItem.remoteBackground\": \"#557d73\",\n        \"statusBarItem.remoteForeground\": \"#e7e7e7\",\n        \"titleBar.activeBackground\": \"#557d73\",\n        \"titleBar.activeForeground\": \"#e7e7e7\",\n        \"titleBar.inactiveBackground\": \"#557d7399\",\n        \"titleBar.inactiveForeground\": \"#e7e7e799\"\n    },\n    \"peacock.color\": \"#557d73\"\n}"
  },
  {
    "path": ".vscode/tasks.json",
    "content": "{\n    \"version\": \"2.0.0\",\n    \"tasks\": [\n        {\n            \"label\": \"build\",\n            \"command\": \"dotnet\",\n            \"type\": \"process\",\n            \"args\": [\n                \"build\",\n                \"${workspaceFolder}/Clean.Architecture.slnx\",\n                \"/property:GenerateFullPaths=true\",\n                \"/consoleloggerparameters:NoSummary;ForceNoAlign\"\n            ],\n            \"problemMatcher\": \"$msCompile\"\n        },\n        {\n            \"label\": \"publish\",\n            \"command\": \"dotnet\",\n            \"type\": \"process\",\n            \"args\": [\n                \"publish\",\n                \"${workspaceFolder}/Clean.Architecture.slnx\",\n                \"/property:GenerateFullPaths=true\",\n                \"/consoleloggerparameters:NoSummary;ForceNoAlign\"\n            ],\n            \"problemMatcher\": \"$msCompile\"\n        },\n        {\n            \"label\": \"watch\",\n            \"command\": \"dotnet\",\n            \"type\": \"process\",\n            \"args\": [\n                \"watch\",\n                \"run\",\n                \"--project\",\n                \"${workspaceFolder}/Clean.Architecture.slnx\"\n            ],\n            \"problemMatcher\": \"$msCompile\"\n        }\n    ]\n}"
  },
  {
    "path": "CODE_OF_CONDUCT.md",
    "content": "# Code of Conduct\n\nThis project has adopted the code of conduct defined by the Contributor Covenant\nto clarify expected behavior in our community.\nFor more information, see the [.NET Foundation Code of Conduct](https://dotnetfoundation.org/code-of-conduct).\n"
  },
  {
    "path": "CONTRIBUTING.md",
    "content": "# Contributing to Ardalis.CleanArchitecture\n\nWe love your input! We want to make contributing to this project as easy and transparent as possible, whether it's:\n\n- Reporting a bug\n- Discussing the current state of the code\n- Submitting a fix\n- Proposing new features\n\n## We Develop with GitHub\n\nObviously...\n\n## We Use Pull Requests\n\nMostly. But pretty much exclusively for non-maintainers. You'll need to fork the repo in order to submit a pull request. Here are the basic steps:\n\n1. Fork the repo and create your branch from `main`.\n2. If you've added code that should be tested, add tests.\n3. If you've changed APIs, update the documentation.\n4. Ensure the test suite passes.\n5. Make sure your code lints.\n6. Issue that pull request!\n\n- [Pull Request Check List](https://ardalis.com/github-pull-request-checklist/)\n- [Resync your fork with this upstream repo](https://ardalis.com/syncing-a-fork-of-a-github-repository-with-upstream/)\n\n## Ask before adding a pull request\n\nYou can just add a pull request out of the blue if you want, but it's much better etiquette (and more likely to be accepted) if you open a new issue or comment in an existing issue stating you'd like to make a pull request.\n\n## Getting Started\n\nLook for [issues marked with 'help wanted'](https://github.com/ardalis/CleanArchitecture/issues?q=is%3Aissue+is%3Aopen+label%3A%22help+wanted%22) to find good places to start contributing.\n\n## Any contributions you make will be under the MIT Software License\n\nIn short, when you submit code changes, your submissions are understood to be under the same [MIT License](http://choosealicense.com/licenses/mit/) that covers this project.\n\n## Report bugs using Github's [issues](https://github.com/ardalis/CleanArchitecture/issues)\n\nWe use GitHub issues to track public bugs. Report a bug by [opening a new issue](https://github.com/ardalis/CleanArchitecture/issues/new/choose); it's that easy!\n\n## Sponsor us\n\nIf you don't have the time or expertise to contribute code, you can still support us by [sponsoring](https://github.com/sponsors/ardalis).\n"
  },
  {
    "path": "Clean.Architecture.slnx",
    "content": "<Solution>\n  <Configurations>\n    <Platform Name=\"Any CPU\" />\n    <Platform Name=\"x64\" />\n    <Platform Name=\"x86\" />\n  </Configurations>\n  <Folder Name=\"/Solution Items/\">\n    <File Path=\".editorconfig\" />\n    <File Path=\".template.config/template.json\" />\n    <File Path=\"CleanArchitecture.nuspec\" />\n    <File Path=\"Directory.Build.props\" />\n    <File Path=\"Directory.Packages.props\" />\n  </Folder>\n  <Folder Name=\"/src/\">\n    <Project Path=\"src/Clean.Architecture.Core/Clean.Architecture.Core.csproj\" />\n    <Project Path=\"src/Clean.Architecture.Infrastructure/Clean.Architecture.Infrastructure.csproj\" />\n    <Project Path=\"src/Clean.Architecture.UseCases/Clean.Architecture.UseCases.csproj\" />\n    <Project Path=\"src/Clean.Architecture.Web/Clean.Architecture.Web.csproj\" />\n  </Folder>\n  <Folder Name=\"/src/_aspire/\">\n    <Project Path=\"src/Clean.Architecture.AspireHost/Clean.Architecture.AspireHost.csproj\" />\n    <Project Path=\"src/Clean.Architecture.ServiceDefaults/Clean.Architecture.ServiceDefaults.csproj\" />\n  </Folder>\n  <Folder Name=\"/tests/\">\n    <Project Path=\"tests/Clean.Architecture.FunctionalTests/Clean.Architecture.FunctionalTests.csproj\">\n      <BuildDependency Project=\"src/Clean.Architecture.Web/Clean.Architecture.Web.csproj\" />\n    </Project>\n    <Project Path=\"tests/Clean.Architecture.IntegrationTests/Clean.Architecture.IntegrationTests.csproj\">\n      <BuildDependency Project=\"src/Clean.Architecture.Infrastructure/Clean.Architecture.Infrastructure.csproj\" />\n    </Project>\n    <Project Path=\"tests/Clean.Architecture.UnitTests/Clean.Architecture.UnitTests.csproj\" />\n  </Folder>\n</Solution>\n"
  },
  {
    "path": "CleanArchitecture.nuspec",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<package xmlns=\"http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd\">\n  <metadata>\n    <id>Ardalis.CleanArchitecture.Template</id>\n    <title>ASP.NET Core Clean Architecture Solution</title>\n    <version>11.0.1</version>\n    <authors>Steve Smith</authors>\n    <description>\n      The Clean Architecture Solution Template popularized by Steve @ardalis Smith. Provides a great starting point for modern and/or DDD solutions built with .NET 10.\n      Features zero tight coupling to database or data access technology.\n    </description>\n    <language>en-US</language>\n    <license type=\"expression\">MIT</license>\n    <projectUrl>https://github.com/ardalis/CleanArchitecture</projectUrl>\n    <releaseNotes>\n      * Update dependencies.\n    </releaseNotes>\n    <packageTypes>\n      <packageType name=\"Template\" />\n    </packageTypes>\n    <tags>Web ASP.NET \"Clean Architecture\" ddd domain-driven-design clean-architecture clean architecture ardalis SOLID</tags>\n    <icon>./content/icon.png</icon>\n    <readme>README.md</readme>\n  </metadata>\n  <files>\n    <file src=\".\\**\" target=\"content\" exclude=\"**\\bin\\**;**\\obj\\**;**\\.git\\**;**\\.github\\**;**\\*.user;**\\.vs\\**;**\\.vscode\\**;**\\.gitignore;**\\sample\\**\" />\n    <file src=\"README.md\" />\n  </files>\n</package>\n"
  },
  {
    "path": "Directory.Build.props",
    "content": "<Project>\n  <PropertyGroup>\n    <ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>\n    <CentralPackageTransitivePinningEnabled>true</CentralPackageTransitivePinningEnabled>\n    <TreatWarningsAsErrors>true</TreatWarningsAsErrors>\n    <TargetFramework>net10.0</TargetFramework>\n    <Nullable>enable</Nullable>\n    <ImplicitUsings>enable</ImplicitUsings>\n    <LangVersion>latest</LangVersion>\n  </PropertyGroup>\n  <PropertyGroup>\n    <NoWarn>1591</NoWarn> <!-- Remove this to turn on warnings for missing XML Comments -->\n  </PropertyGroup>\n</Project>"
  },
  {
    "path": "Directory.Packages.props",
    "content": "<Project>\n  <ItemGroup>\n    <PackageVersion Include=\"Ardalis.GuardClauses\" Version=\"5.0.0\" />\n    <PackageVersion Include=\"Ardalis.HttpClientTestExtensions\" Version=\"4.2.0\" />\n    <PackageVersion Include=\"Ardalis.ListStartupServices\" Version=\"1.1.4\" />\n    <PackageVersion Include=\"Ardalis.Result\" Version=\"10.1.0\" />\n    <PackageVersion Include=\"Ardalis.Result.AspNetCore\" Version=\"10.1.0\" />\n    <PackageVersion Include=\"Ardalis.SharedKernel\" Version=\"5.0.0\" />\n    <PackageVersion Include=\"Ardalis.SmartEnum\" Version=\"8.2.0\" />\n    <PackageVersion Include=\"Ardalis.Specification\" Version=\"9.3.1\" />\n    <PackageVersion Include=\"Ardalis.Specification.EntityFrameworkCore\" Version=\"9.3.1\" />\n    <PackageVersion Include=\"Azure.Identity\" Version=\"1.17.0\" />\n    <PackageVersion Include=\"coverlet.collector\" Version=\"6.0.4\" />\n    <PackageVersion Include=\"FastEndpoints\" Version=\"7.1.1\" />\n    <PackageVersion Include=\"FastEndpoints.ApiExplorer\" Version=\"2.2.0\" />\n    <PackageVersion Include=\"FastEndpoints.Swagger\" Version=\"7.1.1\" />\n    <PackageVersion Include=\"MailKit\" Version=\"4.15.1\" />\n    <PackageVersion Include=\"Mediator.Abstractions\" Version=\"3.0.1\" />\n    <PackageVersion Include=\"Mediator.SourceGenerator\" Version=\"3.0.1\" />\n    <PackageVersion Include=\"Microsoft.AspNetCore.Mvc.Testing\" Version=\"10.0.0\" />\n    <PackageVersion Include=\"Microsoft.EntityFrameworkCore.InMemory\" Version=\"10.0.0\" />\n    <PackageVersion Include=\"Microsoft.EntityFrameworkCore.Relational\" Version=\"10.0.0\" />\n    <PackageVersion Include=\"Microsoft.EntityFrameworkCore.Design\" Version=\"10.0.0\" />\n    <PackageVersion Include=\"Microsoft.EntityFrameworkCore.Sqlite\" Version=\"10.0.0\" />\n    <PackageVersion Include=\"Microsoft.EntityFrameworkCore.SqlServer\" Version=\"10.0.0\" />\n    <PackageVersion Include=\"Microsoft.Extensions.Configuration\" Version=\"10.0.0\" />\n    <PackageVersion Include=\"Microsoft.Extensions.Logging\" Version=\"10.0.0\" />\n    <PackageVersion Include=\"Microsoft.Extensions.Logging.Abstractions\" Version=\"10.0.0\" />\n    <PackageVersion Include=\"Microsoft.Extensions.Options.ConfigurationExtensions\" Version=\"10.0.0\" />\n    <PackageVersion Include=\"Microsoft.NET.Test.Sdk\" Version=\"18.0.1\" />\n    <PackageVersion Include=\"NimblePros.Metronome\" Version=\"0.4.1\" />\n    <PackageVersion Include=\"NSubstitute\" Version=\"5.3.0\" />\n    <PackageVersion Include=\"ReportGenerator\" Version=\"5.5.0\" />\n    <PackageVersion Include=\"Scalar.AspNetCore\" Version=\"2.10.3\" />\n    <PackageVersion Include=\"Serilog.AspNetCore\" Version=\"9.0.0\" />\n    <PackageVersion Include=\"Serilog.Sinks.OpenTelemetry\" Version=\"4.2.0\" />\n    <PackageVersion Include=\"Shouldly\" Version=\"4.3.0\" />\n    <PackageVersion Include=\"SQLite\" Version=\"3.13.0\" />\n    <PackageVersion Include=\"Swashbuckle.AspNetCore\" Version=\"6.5.0\" />\n    <PackageVersion Include=\"Swashbuckle.AspNetCore.Annotations\" Version=\"6.5.0\" />\n    <PackageVersion Include=\"Testcontainers\" Version=\"4.3.0\" />\n    <PackageVersion Include=\"Testcontainers.MsSql\" Version=\"4.3.0\" />\n    <PackageVersion Include=\"xunit\" Version=\"2.9.3\" />\n    <PackageVersion Include=\"xunit.runner.visualstudio\" Version=\"3.1.5\" />\n    <PackageVersion Include=\"Aspire.Hosting.AppHost\" Version=\"13.0.0\" />\n    <PackageVersion Include=\"Aspire.Hosting.SqlServer\" Version=\"13.0.0\" />\n    <PackageVersion Include=\"Microsoft.Extensions.Http.Resilience\" Version=\"10.0.0\" />\n    <PackageVersion Include=\"Microsoft.Extensions.ServiceDiscovery\" Version=\"10.0.0\" />\n    <PackageVersion Include=\"OpenTelemetry.Exporter.OpenTelemetryProtocol\" Version=\"1.14.0\" />\n    <PackageVersion Include=\"OpenTelemetry.Extensions.Hosting\" Version=\"1.14.0\" />\n    <PackageVersion Include=\"OpenTelemetry.Instrumentation.AspNetCore\" Version=\"1.13.0\" />\n    <PackageVersion Include=\"OpenTelemetry.Instrumentation.Http\" Version=\"1.13.0\" />\n    <PackageVersion Include=\"OpenTelemetry.Instrumentation.Runtime\" Version=\"1.13.0\" />\n    <PackageVersion Include=\"Aspire.Hosting.Testing\" Version=\"9.5.1\" />\n    <PackageVersion Include=\"Vogen\" Version=\"8.0.2\" />\n  </ItemGroup>\n</Project>\n"
  },
  {
    "path": "LICENSE",
    "content": "MIT License\n\nCopyright (c) 2016 Steve Smith\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
  },
  {
    "path": "MinimalClean/.editorconfig",
    "content": "###############################\n# Core EditorConfig Options   #\n###############################\nroot = true\n# All files\n[*]\nindent_style = space\n\n# XML project files\n[*.{csproj,vbproj,vcxproj,vcxproj.filters,proj,projitems,shproj}]\nindent_size = 2\n\n# XML config files\n[*.{props,targets,ruleset,config,nuspec,resx,vsixmanifest,vsct}]\nindent_size = 2\n\n# Code files\n[*.{cs,csx,vb,vbx}]\nindent_size = 2\ninsert_final_newline = true\ncharset = utf-8-bom\n###############################\n# .NET Coding Conventions     #\n###############################\n[*.{cs,vb}]\n# Organize usings\ndotnet_sort_system_directives_first = true\n# this. preferences\ndotnet_style_qualification_for_field = false:silent\ndotnet_style_qualification_for_property = false:silent\ndotnet_style_qualification_for_method = false:silent\ndotnet_style_qualification_for_event = false:silent\n# Language keywords vs BCL types preferences\ndotnet_style_predefined_type_for_locals_parameters_members = true:silent\ndotnet_style_predefined_type_for_member_access = true:silent\n# Parentheses preferences\ndotnet_style_parentheses_in_arithmetic_binary_operators = always_for_clarity:silent\ndotnet_style_parentheses_in_relational_binary_operators = always_for_clarity:silent\ndotnet_style_parentheses_in_other_binary_operators = always_for_clarity:silent\ndotnet_style_parentheses_in_other_operators = never_if_unnecessary:silent\n# Modifier preferences\ndotnet_style_require_accessibility_modifiers = for_non_interface_members:silent\ndotnet_style_readonly_field = true:suggestion\n# Expression-level preferences\ndotnet_style_object_initializer = true:suggestion\ndotnet_style_collection_initializer = true:suggestion\ndotnet_style_explicit_tuple_names = true:suggestion\ndotnet_style_null_propagation = true:suggestion\ndotnet_style_coalesce_expression = true:suggestion\ndotnet_style_prefer_is_null_check_over_reference_equality_method = true:silent\ndotnet_style_prefer_inferred_tuple_names = true:suggestion\ndotnet_style_prefer_inferred_anonymous_type_member_names = true:suggestion\ndotnet_style_prefer_auto_properties = true:silent\ndotnet_style_prefer_conditional_expression_over_assignment = true:silent\ndotnet_style_prefer_conditional_expression_over_return = true:silent\n###############################\n# Naming Conventions          #\n###############################\n# Style Definitions\ndotnet_naming_style.pascal_case_style.capitalization             = pascal_case\n# Use PascalCase for constant fields  \ndotnet_naming_rule.constant_fields_should_be_pascal_case.severity = suggestion\ndotnet_naming_rule.constant_fields_should_be_pascal_case.symbols  = constant_fields\ndotnet_naming_rule.constant_fields_should_be_pascal_case.style = pascal_case_style\ndotnet_naming_symbols.constant_fields.applicable_kinds            = field\ndotnet_naming_symbols.constant_fields.applicable_accessibilities  = *\ndotnet_naming_symbols.constant_fields.required_modifiers          = const\ntab_width= 2\ndotnet_naming_rule.private_members_with_underscore.symbols  = private_fields\ndotnet_naming_rule.private_members_with_underscore.style = prefix_underscore\ndotnet_naming_rule.private_members_with_underscore.severity = suggestion\ndotnet_naming_symbols.private_fields.applicable_kinds           = field\ndotnet_naming_symbols.private_fields.applicable_accessibilities = private\ndotnet_naming_style.prefix_underscore.capitalization = camel_case\ndotnet_naming_style.prefix_underscore.required_prefix = _\ndotnet_style_operator_placement_when_wrapping = beginning_of_line\nend_of_line = crlf\n###############################\n# C# Coding Conventions       #\n###############################\n[*.cs]\n# var preferences\ncsharp_style_var_for_built_in_types = true:silent\ncsharp_style_var_when_type_is_apparent = true:silent\ncsharp_style_var_elsewhere = true:silent\n# Expression-bodied members\ncsharp_style_expression_bodied_methods = false:silent\ncsharp_style_expression_bodied_constructors = false:silent\ncsharp_style_expression_bodied_operators = false:silent\ncsharp_style_expression_bodied_properties = true:silent\ncsharp_style_expression_bodied_indexers = true:silent\ncsharp_style_expression_bodied_accessors = true:silent\n# Pattern matching preferences\ncsharp_style_pattern_matching_over_is_with_cast_check = true:suggestion\ncsharp_style_pattern_matching_over_as_with_null_check = true:suggestion\n# Null-checking preferences\ncsharp_style_throw_expression = true:suggestion\ncsharp_style_conditional_delegate_call = true:suggestion\n# Modifier preferences\ncsharp_preferred_modifier_order = public,private,protected,internal,static,extern,new,virtual,abstract,sealed,override,readonly,unsafe,volatile,async:suggestion\n# Expression-level preferences\ncsharp_prefer_braces = true:silent\ncsharp_style_deconstructed_variable_declaration = true:suggestion\ncsharp_prefer_simple_default_expression = true:suggestion\ncsharp_style_pattern_local_over_anonymous_function = true:suggestion\ncsharp_style_inlined_variable_declaration = true:suggestion\n# Namespaces\ncsharp_style_namespace_declarations = file_scoped:warning\n###############################\n# C# Formatting Rules         #\n###############################\n# New line preferences\ncsharp_new_line_before_open_brace = all\ncsharp_new_line_before_else = true\ncsharp_new_line_before_catch = true\ncsharp_new_line_before_finally = true\ncsharp_new_line_before_members_in_object_initializers = true\ncsharp_new_line_before_members_in_anonymous_types = true\ncsharp_new_line_between_query_expression_clauses = true\n# Indentation preferences\ncsharp_indent_case_contents = true\ncsharp_indent_switch_labels = true\ncsharp_indent_labels = flush_left\n# Space preferences\ncsharp_space_after_cast = false\ncsharp_space_after_keywords_in_control_flow_statements = true\ncsharp_space_between_method_call_parameter_list_parentheses = false\ncsharp_space_between_method_declaration_parameter_list_parentheses = false\ncsharp_space_between_parentheses = false\ncsharp_space_before_colon_in_inheritance_clause = true\ncsharp_space_after_colon_in_inheritance_clause = true\ncsharp_space_around_binary_operators = before_and_after\ncsharp_space_between_method_declaration_empty_parameter_list_parentheses = false\ncsharp_space_between_method_call_name_and_opening_parenthesis = false\ncsharp_space_between_method_call_empty_parameter_list_parentheses = false\n# Wrapping preferences\ncsharp_preserve_single_line_statements = true\ncsharp_preserve_single_line_blocks = true\ncsharp_using_directive_placement = outside_namespace:suggestion\ncsharp_prefer_simple_using_statement = true:suggestion\ncsharp_style_prefer_method_group_conversion = true:silent\ncsharp_style_prefer_top_level_statements = true:silent\ncsharp_style_prefer_primary_constructors = true:suggestion\ncsharp_style_expression_bodied_lambdas = true:silent\ncsharp_style_expression_bodied_local_functions = false:silent\n###############################\n# VB Coding Conventions       #\n###############################\n[*.vb]\n# Modifier preferences\nvisual_basic_preferred_modifier_order = Partial,Default,Private,Protected,Public,Friend,NotOverridable,Overridable,MustOverride,Overloads,Overrides,MustInherit,NotInheritable,Static,Shared,Shadows,ReadOnly,WriteOnly,Dim,Const,WithEvents,Widening,Narrowing,Custom,Async:suggestion"
  },
  {
    "path": "MinimalClean/.gitignore",
    "content": "## Ignore Visual Studio temporary files, build results, and\n## files generated by popular Visual Studio add-ons.\n\n# User-specific files\n*.suo\n*.user\n*.userosscache\n*.sln.docstates\n\n# Build results\n[Dd]ebug/\n[Dd]ebugPublic/\n[Rr]elease/\n[Rr]eleases/\nx64/\nx86/\nbuild/\nbld/\n[Bb]in/\n[Oo]bj/\n\n# Visual Studio 2015/2017/2019/2022 cache/options directory\n.vs/\n.vscode/\n\n# MSTest test Results\n[Tt]est[Rr]esult*/\n[Bb]uild[Ll]og.*\n\n# NUnit\n*.VisualState.xml\nTestResult.xml\nnunit-*.xml\n\n# Build Results of an ATL Project\n[Dd]ebugPS/\n[Rr]eleasePS/\ndlldata.c\n\n# .NET Core\nproject.lock.json\nproject.fragment.lock.json\nartifacts/\n\n# ASP.NET Scaffolding\nScaffoldingReadMe.txt\n\n# Database files\n*.db\n*.db-shm\n*.db-wal\n*.sqlite\n*.sqlite3\n\n# Entity Framework Core migrations (keep migrations folder, ignore db files)\n**/Migrations/*.db\n\n# User-specific files (MonoDevelop/Xamarin Studio)\n*.userprefs\n\n# Windows image file caches\nThumbs.db\nehthumbs.db\n\n# Folder config file\nDesktop.ini\n\n# Recycle Bin used on file shares\n$RECYCLE.BIN/\n\n# Mac desktop service store files\n.DS_Store\n\n# JetBrains Rider\n.idea/\n*.sln.iml\n\n# CodeRush\n.cr/\n\n# Python Tools for Visual Studio (PTVS)\n__pycache__/\n*.pyc\n\n# Cake - Uncomment if you are using it\n# tools/**\n# !tools/packages.config\n\n# NCrunch\n_NCrunch_*\n.*crunch*.local.xml\nnCrunchTemp_*\n\n# MightyMoose\n*.mm.*\nAutoTest.Net/\n\n# Web workbench (sass)\n.sass-cache/\n\n# Installshield output folder\n[Ee]xpress/\n\n# DocProject is a documentation generator add-in\nDocProject/buildhelp/\nDocProject/Help/*.HxT\nDocProject/Help/*.HxC\nDocProject/Help/*.hhc\nDocProject/Help/*.hhk\nDocProject/Help/*.hhp\nDocProject/Help/Html2\nDocProject/Help/html\n\n# Click-Once directory\npublish/\n\n# Publish Web Output\n*.[Pp]ublish.xml\n*.azurePubxml\n\n# NuGet Packages\n*.nupkg\n# The packages folder can be ignored because of Package Restore\n**/packages/*\n# except build/, which is used as an MSBuild target.\n!**/packages/build/\n# Uncomment if necessary however generally it will be regenerated when needed\n#!**/packages/repositories.config\n# NuGet v3's project.json files produces more ignoreable files\n*.nuget.props\n*.nuget.targets\n\n# Microsoft Azure Build Output\ncsx/\n*.build.csdef\n\n# Microsoft Azure Emulator\necf/\nrcf/\n\n# Windows Store app package directories and files\nAppPackages/\nBundleArtifacts/\nPackage.StoreAssociation.xml\n_pkginfo.txt\n\n# Visual Studio cache files\n# files ending in .cache can be ignored\n*.[Cc]ache\n# but keep track of directories ending in .cache\n!*.[Cc]ache/\n\n# Others\nClientBin/\n~$*\n*~\n*.dbmdl\n*.dbproj.schemaview\n*.jfm\n*.pfx\n*.publishsettings\norleans.codegen.cs\n\n# RIA/Silverlight projects\nGenerated_Code/\n\n# Backup & report files from converting an old project file\n# to a newer Visual Studio version. Backup files are not needed,\n# because we have git ;-)\n_UpgradeReport_Files/\nBackup*/\nUpgradeLog*.XML\nUpgradeLog*.htm\n\n# SQL Server files\n*.mdf\n*.ldf\n*.ndf\n\n# Business Intelligence projects\n*.rdl.data\n*.bim.layout\n*.bim_*.settings\n\n# Microsoft Fakes\nFakesAssemblies/\n\n# GhostDoc plugin setting file\n*.GhostDoc.xml\n\n# Node.js Tools for Visual Studio\n.ntvs_analysis.dat\nnode_modules/\n\n# Typescript v1 declaration files\ntypings/\n\n# Visual Studio 6 build log\n*.plg\n\n# Visual Studio 6 workspace options file\n*.opt\n\n# Visual Studio 6 auto-generated workspace file (contains which files were open etc.)\n*.vbw\n\n# Visual Studio LightSwitch build output\n**/*.HTMLClient/GeneratedArtifacts\n**/*.DesktopClient/GeneratedArtifacts\n**/*.DesktopClient/ModelManifest.xml\n**/*.Server/GeneratedArtifacts\n**/*.Server/ModelManifest.xml\n_Pvt_Extensions\n\n# Paket dependency manager\n.paket/paket.exe\npaket-files/\n\n# FAKE - F# Make\n.fake/\n\n# JetBrains Rider\n.idea/\n*.sln.iml\n\n# CodeRush\n.cr/\n\n# Python Tools for Visual Studio (PTVS)\n__pycache__/\n*.pyc\n\n# Cake - Uncomment if you are using it\n# tools/\n\n# Telerik's JustMock configuration file\n*.jmconfig\n\n# BizTalk build output\n*.btp.cs\n*.btm.cs\n*.odx.cs\n*.xsd.cs\n"
  },
  {
    "path": "MinimalClean/.runsettings",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<RunSettings>\n  <RunConfiguration>\n    <!-- Enable parallel test execution at the assembly level -->\n    <MaxCpuCount>0</MaxCpuCount>\n    <!-- 0 means use all available processors -->\n    <DisableParallelization>false</DisableParallelization>\n  </RunConfiguration>\n  \n  <xUnit>\n    <!-- Configure xUnit-specific settings -->\n    <ParallelizeAssembly>true</ParallelizeAssembly>\n    <ParallelizeTestCollections>true</ParallelizeTestCollections>\n    <MaxParallelThreads>0</MaxParallelThreads>\n    <!-- 0 means use default algorithm (processors * 2) -->\n  </xUnit>\n</RunSettings>\n"
  },
  {
    "path": "MinimalClean/.template.config/template.json",
    "content": "{\n  \"$schema\": \"http://json.schemastore.org/template\",\n  \"author\": \"ardalis (Steve Smith)\",\n  \"classifications\": [\n    \"Web\",\n    \"ASP.NET\",\n    \"Clean Architecture\",\n    \"Minimal\"\n  ],\n  \"tags\": {\n    \"language\": \"C#\",\n    \"type\": \"project\"\n  },\n  \"identity\": \"Ardalis.MinimalClean.Template\",\n  \"name\": \"ASP.NET Minimal Clean Architecture Solution\",\n  \"shortName\": \"min-clean\",\n  \"sourceName\": \"MinimalClean.Architecture\",\n  \"templateFileExtensions\": [ \".cs\", \".csproj\", \".slnx\" ],\n  \"preferNameDirectory\": true,\n  \"sources\": [\n    {\n      \"include\": [\n        \"**/*\"\n      ],\n      \"exclude\": [ \n        \".vs/**\",\n        \".vscode/**\",\n        \".git/**\",\n        \".github/**\",\n        \".idea/**\",\n        \".template.config/**\",\n        \"**/bin/**\",\n        \"**/obj/**\",\n        \"**/.vs/**\"\n      ],\n      \"modifiers\": [\n        {\n          \"condition\": \"true\",\n          \"copyOnly\": [ \"*.dll\", \"*.png\", \"*.ico\", \"*.jpg\", \"*.jpeg\", \"*.ps1\" ]\n        },\n        {\n          \"rename\": {\n            \"README.template.md\": \"README.md\"\n          }\n        }\n      ]\n    }\n  ]\n}\n"
  },
  {
    "path": "MinimalClean/Directory.Build.props",
    "content": "<Project>\n  <PropertyGroup>\n    <ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>\n    <TreatWarningsAsErrors>true</TreatWarningsAsErrors>\n    <TargetFramework>net10.0</TargetFramework>\n    <Nullable>enable</Nullable>\n    <ImplicitUsings>enable</ImplicitUsings>\n    <LangVersion>latest</LangVersion>\n  </PropertyGroup>\n  <PropertyGroup>\n    <NoWarn>1591</NoWarn> <!-- Remove this to turn on warnings for missing XML Comments -->\n  </PropertyGroup>\n</Project>"
  },
  {
    "path": "MinimalClean/Directory.Packages.props",
    "content": "<Project>\n  <ItemGroup>\n    <PackageVersion Include=\"Ardalis.GuardClauses\" Version=\"5.0.0\" />\n    <PackageVersion Include=\"Ardalis.HttpClientTestExtensions\" Version=\"4.2.0\" />\n    <PackageVersion Include=\"Ardalis.ListStartupServices\" Version=\"1.1.4\" />\n    <PackageVersion Include=\"Ardalis.Result\" Version=\"10.1.0\" />\n    <PackageVersion Include=\"Ardalis.Result.AspNetCore\" Version=\"10.1.0\" />\n    <PackageVersion Include=\"Ardalis.SharedKernel\" Version=\"5.0.0\" />\n    <PackageVersion Include=\"Ardalis.SmartEnum\" Version=\"8.2.0\" />\n    <PackageVersion Include=\"Ardalis.Specification\" Version=\"9.3.1\" />\n    <PackageVersion Include=\"Ardalis.Specification.EntityFrameworkCore\" Version=\"9.3.1\" />\n    <PackageVersion Include=\"Azure.Identity\" Version=\"1.17.0\" />\n    <PackageVersion Include=\"coverlet.collector\" Version=\"6.0.4\" />\n    <PackageVersion Include=\"FastEndpoints\" Version=\"7.1.1\" />\n    <PackageVersion Include=\"FastEndpoints.ApiExplorer\" Version=\"2.2.0\" />\n    <PackageVersion Include=\"FastEndpoints.Swagger\" Version=\"7.1.1\" />\n    <PackageVersion Include=\"MailKit\" Version=\"4.14.1\" />\n    <PackageVersion Include=\"Mediator.Abstractions\" Version=\"3.0.1\" />\n    <PackageVersion Include=\"Mediator.SourceGenerator\" Version=\"3.0.1\" />\n    <PackageVersion Include=\"Microsoft.AspNetCore.Mvc.Testing\" Version=\"10.0.0\" />\n    <PackageVersion Include=\"Microsoft.EntityFrameworkCore.InMemory\" Version=\"10.0.0\" />\n    <PackageVersion Include=\"Microsoft.EntityFrameworkCore.Relational\" Version=\"10.0.0\" />\n    <PackageVersion Include=\"Microsoft.EntityFrameworkCore.Design\" Version=\"10.0.0\" />\n    <PackageVersion Include=\"Microsoft.EntityFrameworkCore.Sqlite\" Version=\"10.0.0\" />\n    <PackageVersion Include=\"Microsoft.EntityFrameworkCore.SqlServer\" Version=\"10.0.0\" />\n    <PackageVersion Include=\"Microsoft.Extensions.Configuration\" Version=\"10.0.0\" />\n    <PackageVersion Include=\"Microsoft.Extensions.Logging\" Version=\"10.0.0\" />\n    <PackageVersion Include=\"Microsoft.Extensions.Logging.Abstractions\" Version=\"10.0.0\" />\n    <PackageVersion Include=\"Microsoft.Extensions.Options.ConfigurationExtensions\" Version=\"10.0.0\" />\n    <PackageVersion Include=\"Microsoft.NET.Test.Sdk\" Version=\"18.0.1\" />\n    <PackageVersion Include=\"MimeKit\" Version=\"4.15.1\" />\n    <PackageVersion Include=\"NimblePros.Metronome\" Version=\"0.4.1\" />\n    <PackageVersion Include=\"NsDepCop\" Version=\"2.6.0\" />\n    <PackageVersion Include=\"NSubstitute\" Version=\"5.3.0\" />\n    <PackageVersion Include=\"ReportGenerator\" Version=\"5.5.0\" />\n    <PackageVersion Include=\"Scalar.AspNetCore\" Version=\"2.10.3\" />\n    <PackageVersion Include=\"Serilog.AspNetCore\" Version=\"9.0.0\" />\n    <PackageVersion Include=\"Serilog.Sinks.OpenTelemetry\" Version=\"4.2.0\" />\n    <PackageVersion Include=\"Shouldly\" Version=\"4.3.0\" />\n    <PackageVersion Include=\"SQLite\" Version=\"3.13.0\" />\n    <PackageVersion Include=\"Swashbuckle.AspNetCore\" Version=\"6.5.0\" />\n    <PackageVersion Include=\"Swashbuckle.AspNetCore.Annotations\" Version=\"6.5.0\" />\n    <PackageVersion Include=\"Testcontainers\" Version=\"4.3.0\" />\n    <PackageVersion Include=\"Testcontainers.MsSql\" Version=\"4.3.0\" />\n    <PackageVersion Include=\"xunit\" Version=\"2.9.3\" />\n    <PackageVersion Include=\"xunit.runner.visualstudio\" Version=\"3.1.5\" />\n    <PackageVersion Include=\"Aspire.Hosting.AppHost\" Version=\"13.0.0\" />\n    <PackageVersion Include=\"Aspire.Hosting.SqlServer\" Version=\"13.0.0\" />\n    <PackageVersion Include=\"Microsoft.Extensions.Http.Resilience\" Version=\"10.0.0\" />\n    <PackageVersion Include=\"Microsoft.Extensions.ServiceDiscovery\" Version=\"10.0.0\" />\n    <PackageVersion Include=\"OpenTelemetry.Exporter.OpenTelemetryProtocol\" Version=\"1.14.0\" />\n    <PackageVersion Include=\"OpenTelemetry.Extensions.Hosting\" Version=\"1.14.0\" />\n    <PackageVersion Include=\"OpenTelemetry.Instrumentation.AspNetCore\" Version=\"1.13.0\" />\n    <PackageVersion Include=\"OpenTelemetry.Instrumentation.Http\" Version=\"1.13.0\" />\n    <PackageVersion Include=\"OpenTelemetry.Instrumentation.Runtime\" Version=\"1.13.0\" />\n    <PackageVersion Include=\"Aspire.Hosting.Testing\" Version=\"9.5.1\" />\n    <PackageVersion Include=\"Vogen\" Version=\"8.0.2\" />\n  </ItemGroup>\n</Project>"
  },
  {
    "path": "MinimalClean/MinimalClean.Architecture.slnx",
    "content": "<Solution>\n  <Configurations>\n    <Platform Name=\"Any CPU\" />\n    <Platform Name=\"x64\" />\n    <Platform Name=\"x86\" />\n  </Configurations>\n  <Folder Name=\"/Solution Items/\">\n    <File Path=\"../MinimalClean.nuspec\" />\n    <File Path=\".editorconfig\" />\n    <File Path=\"Directory.Build.props\" />\n    <File Path=\"Directory.Packages.props\" />\n  </Folder>\n  <Folder Name=\"/src/\">\n    <Project Path=\"src/MinimalClean.Architecture.Web/MinimalClean.Architecture.Web.csproj\" />\n  </Folder>\n  <Folder Name=\"/src/_aspire/\">\n    <Project Path=\"src/MinimalClean.Architecture.AspireHost/MinimalClean.Architecture.AspireHost.csproj\" />\n    <Project Path=\"src/MinimalClean.Architecture.ServiceDefaults/MinimalClean.Architecture.ServiceDefaults.csproj\" />\n  </Folder>\n</Solution>\n"
  },
  {
    "path": "MinimalClean/README.template.md",
    "content": "# MinimalClean.Architecture\n\nWelcome to your new project generated with the **Minimal Clean Architecture** template!\n\nThis is a streamlined, single-project Vertical Slice Architecture (VSA) that follows Clean Architecture principles without the overhead of multiple projects. Perfect for smaller applications, MVPs, or teams that want architectural guidance without complex project boundaries.\n\n## Getting Started\n\n### Build and Run\n\n```powershell\n# Build the solution\ndotnet build\n\n# Run the application\ndotnet run --project src/MinimalClean.Architecture.Web\n\n# Or run with Aspire (if using)\ndotnet run --project src/MinimalClean.Architecture.AspireHost\n```\n\n### Database Setup\n\nThis template uses **SQL Server in a container** managed by Aspire. When you run the Aspire AppHost, it automatically starts a SQL Server container and creates the database.\n\n#### Option 1: Run with Aspire (Recommended)\n\n```powershell\ndotnet run --project src/MinimalClean.Architecture.AspireHost\n```\n\nThe SQL Server container and database are automatically provisioned and migrations are applied on startup.\n\n#### Option 2: Run Web project directly (SQL Server LocalDB)\n\nIf running the Web project without Aspire, update `appsettings.json` to use LocalDB:\n\n```powershell\ndotnet ef database update -c AppDbContext -p src/MinimalClean.Architecture.Web -s src/MinimalClean.Architecture.Web\ndotnet run --project src/MinimalClean.Architecture.Web\n```\n\n## Project Structure\n\nThis template uses a **single Web project** organized by **vertical slices** (features):\n\n```text\nsrc/MinimalClean.Architecture.Web/\n├── Domain/                    # Domain entities and aggregates\n│   ├── CartAggregate/\n│   ├── OrderAggregate/\n│   └── ProductAggregate/\n├── Infrastructure/            # Data access and external services\n│   ├── Data/\n│   │   ├── AppDbContext.cs\n│   │   ├── Config/           # EF Core configurations\n│   │   └── Migrations/\n│   └── Email/                # Email services\n├── Endpoints/                 # API endpoints (FastEndpoints)\n│   ├── Cart/\n│   ├── Order/\n│   └── Product/\n└── Program.cs                # Application startup\n```\n\n### Key Design Decisions\n\n```text\nSingle project vertical slice architecture\n```\n\n- **Single Project**: All code in one Web project - simpler dependencies, faster builds\n- **Vertical Slices**: Organized by feature (Cart, Order, Product) not layer\n- **Domain-Driven Design**: Entities use proper encapsulation and business logic\n- **FastEndpoints**: REPR pattern for clean, testable API endpoints\n- **Entity Framework Core**: Simple data access with SQLite (easily switched to SQL Server)\n- **Mediator Pattern**: Optional - use for cross-cutting concerns or remove for simplicity\n\n## What's Different from Full Clean Architecture?\n\nThis minimal template simplifies the full Clean Architecture template:\n\n| Full Template | Minimal Template |\n|--------------|------------------|\n| 4+ projects (Core, UseCases, Infrastructure, Web) | 1 Web project |\n| Repository pattern with Specifications | Repository pattern with Specifications if needed |\n| Extensive use of interfaces and abstractions | Pragmatic abstractions where needed |\n| Separate Use Cases project with Mediator | Optional Mediator; logic can be in endpoints |\n| Complex domain patterns (Aggregates, Value Objects, Domain Events) | Pragmatic DDD patterns (Aggregates, Value Objects) |\n\n## When to Use This Template\n\n**Use Minimal Clean Architecture when:**\n\n- ✓ Building MVPs or smaller applications\n- ✓ You want architectural guidance without project ceremony\n- ✓ Team prefers simplicity and fast iteration\n- ✓ Vertical slice architecture appeals to you\n- ✓ You may grow into full Clean Architecture later\n\n**Use Full Clean Architecture when:**\n\n- × Building large, complex enterprise applications\n- × Multiple teams working on different layers\n- × Need strict separation of concerns and dependencies\n- × Domain complexity requires extensive DDD patterns\n- × Long-term maintenance and evolution expected\n\n## Technology Stack\n\n- **.NET 10**: Latest LTS framework\n- **FastEndpoints**: REPR pattern for API endpoints\n- **Entity Framework Core**: Data access with migrations\n- **SQL Server**: Containerized database via Aspire (easily switched to PostgreSQL, SQLite, etc.)\n- **Aspire**: Cloud-ready orchestration and observability\n- **Serilog**: Structured logging\n- **FluentValidation**: Request validation\n\n## Common Tasks\n\n### Adding a New Feature (Vertical Slice)\n\n1. **Create Domain Entity**: Add to `Domain/YourFeatureAggregate/`\n2. **Add EF Configuration**: Create config in `Infrastructure/Data/Config/`\n3. **Create Migration**: `dotnet ef migrations add AddYourFeature`\n4. **Create Endpoints**: Add FastEndpoints in `Endpoints/YourFeature/`\n\n### Switching to SQL Server\n\nUpdate `appsettings.json`:\n\n```json\n{\n  \"ConnectionStrings\": {\n    \"DefaultConnection\": \"Server=(localdb)\\\\mssqllocaldb;Database=YourDb;Trusted_Connection=true;\"\n  }\n}\n```\n\n### Running Tests\n\n```powershell\ndotnet test\n```\n\n## Migration Path to Full Clean Architecture\n\nAs your application grows, you can migrate to the full Clean Architecture template:\n\n1. **Extract Core**: Move Domain entities to separate Core project\n2. **Extract UseCases**: Move business logic to UseCases project with Mediator\n3. **Extract Infrastructure**: Move data access to Infrastructure project\n4. **Update Dependencies**: Set up proper dependency flow (Core ← UseCases ← Infrastructure)\n\nLearn more: [Clean Architecture Template](https://github.com/ardalis/CleanArchitecture)\n\n## Resources\n\n- [Clean Architecture Template Repository](https://github.com/ardalis/CleanArchitecture)\n- [Vertical Slice Architecture](https://jimmybogard.com/vertical-slice-architecture/)\n- [FastEndpoints Documentation](https://fast-endpoints.com/)\n- [Ardalis on YouTube](https://www.youtube.com/@Ardalis)\n\n## Need Help?\n\n- Report issues: [GitHub Issues](https://github.com/ardalis/CleanArchitecture/issues)\n- Ask questions: [Discussions](https://github.com/ardalis/CleanArchitecture/discussions)\n- Follow updates: [@ardalis](https://twitter.com/ardalis)\n\n---\n\n**Happy Coding!** 🚀\n"
  },
  {
    "path": "MinimalClean/global.json",
    "content": "{\n  \"sdk\": {\n    \"version\": \"10.0.100\",\n    \"rollForward\": \"latestMajor\",\n    \"allowPrerelease\": true\n  }\n}\n"
  },
  {
    "path": "MinimalClean/src/MinimalClean.Architecture.AspireHost/AppHost.cs",
    "content": "﻿using System.Net.Sockets;\n\nvar builder = DistributedApplication.CreateBuilder(args);\n\n// Add SQL Server container\nvar sqlServer = builder.AddSqlServer(\"sqlserver\")\n  .WithLifetime(ContainerLifetime.Persistent);\n\n// Add the database\nvar appDb = sqlServer.AddDatabase(\"AppDb\");\n\n// Papercut SMTP container for email testing\nvar papercut = builder.AddContainer(\"papercut\", \"jijiechen/papercut\", \"latest\")\n  .WithEndpoint(\"smtp\", e =>\n  {\n    e.TargetPort = 25;   // container port\n    e.Port = 25;         // host port\n    e.Protocol = ProtocolType.Tcp;\n    e.UriScheme = \"smtp\";\n  })\n  .WithEndpoint(\"ui\", e =>\n  {\n    e.TargetPort = 37408;\n    e.Port = 37408;\n    e.UriScheme = \"http\";\n  });\n\n// register the API project and link the DB\nbuilder.AddProject<Projects.MinimalClean_Architecture_Web>(\"web\")\n      .WithEnvironment(\"ASPNETCORE_ENVIRONMENT\", builder.Environment.EnvironmentName)\n      .WithReference(appDb)\n      .WaitFor(papercut)\n      .WaitFor(appDb)\n      .WithUrl(\"https://localhost:57379\"); // Match launchSettings\n\nbuilder.Build().Run();\n"
  },
  {
    "path": "MinimalClean/src/MinimalClean.Architecture.AspireHost/MinimalClean.Architecture.AspireHost.csproj",
    "content": "﻿<Project Sdk=\"Microsoft.NET.Sdk\">\n\n  <Sdk Name=\"Aspire.AppHost.Sdk\" Version=\"13.0.0\" />\n\n  <PropertyGroup>\n    <OutputType>Exe</OutputType>\n    <UserSecretsId>47f99468-f41d-48b8-ae3f-69682954d973</UserSecretsId>\n  </PropertyGroup>\n\n  <ItemGroup>\n    <PackageReference Include=\"Aspire.Hosting.AppHost\" />\n    <PackageReference Include=\"Aspire.Hosting.SqlServer\" />\n    <PackageReference Include=\"Microsoft.Extensions.Http.Resilience\" />\n    <PackageReference Include=\"Microsoft.Extensions.ServiceDiscovery\" />\n    <PackageReference Include=\"OpenTelemetry.Exporter.OpenTelemetryProtocol\" />\n    <PackageReference Include=\"OpenTelemetry.Extensions.Hosting\" />\n    <PackageReference Include=\"OpenTelemetry.Instrumentation.AspNetCore\" />\n    <PackageReference Include=\"OpenTelemetry.Instrumentation.Http\" />\n    <PackageReference Include=\"OpenTelemetry.Instrumentation.Runtime\" />\n  </ItemGroup>\n  \n  <ItemGroup>\n    <!-- The IsAspireProjectResource attribute tells .NET Aspire to treat this \n        reference as a standard project reference and not attempt to generate\n        a metadata file -->\n    <ProjectReference Include=\"..\\MinimalClean.Architecture.ServiceDefaults\\MinimalClean.Architecture.ServiceDefaults.csproj\" IsAspireProjectResource=\"false\" />\n    <ProjectReference Include=\"..\\MinimalClean.Architecture.Web\\MinimalClean.Architecture.Web.csproj\" />\n  </ItemGroup>\n\n</Project>\n"
  },
  {
    "path": "MinimalClean/src/MinimalClean.Architecture.AspireHost/Properties/launchSettings.json",
    "content": "{\n  \"$schema\": \"https://json.schemastore.org/launchsettings.json\",\n  \"profiles\": {\n    \"https\": {\n      \"commandName\": \"Project\",\n      \"dotnetRunMessages\": true,\n      \"launchBrowser\": true,\n      \"applicationUrl\": \"https://localhost:17143;http://localhost:15258\",\n      \"environmentVariables\": {\n        \"ASPNETCORE_ENVIRONMENT\": \"Development\",\n        \"DOTNET_ENVIRONMENT\": \"Development\",\n        \"DOTNET_DASHBOARD_OTLP_ENDPOINT_URL\": \"https://localhost:21007\",\n        \"DOTNET_RESOURCE_SERVICE_ENDPOINT_URL\": \"https://localhost:22245\"\n      }\n    },\n    \"http\": {\n      \"commandName\": \"Project\",\n      \"dotnetRunMessages\": true,\n      \"launchBrowser\": true,\n      \"applicationUrl\": \"http://localhost:15258\",\n      \"environmentVariables\": {\n        \"ASPNETCORE_ENVIRONMENT\": \"Development\",\n        \"DOTNET_ENVIRONMENT\": \"Development\",\n        \"DOTNET_DASHBOARD_OTLP_ENDPOINT_URL\": \"http://localhost:19187\",\n        \"DOTNET_RESOURCE_SERVICE_ENDPOINT_URL\": \"http://localhost:20134\"\n      }\n    }\n  }\n}\n"
  },
  {
    "path": "MinimalClean/src/MinimalClean.Architecture.AspireHost/appsettings.Development.json",
    "content": "{\n  \"Logging\": {\n    \"LogLevel\": {\n      \"Default\": \"Information\",\n      \"Microsoft.AspNetCore\": \"Warning\"\n    }\n  }\n}\n"
  },
  {
    "path": "MinimalClean/src/MinimalClean.Architecture.AspireHost/appsettings.json",
    "content": "{\n  \"Logging\": {\n    \"LogLevel\": {\n      \"Default\": \"Information\",\n      \"Microsoft.AspNetCore\": \"Warning\",\n      \"Aspire.Hosting.Dcp\": \"Warning\"\n    }\n  }\n}\n"
  },
  {
    "path": "MinimalClean/src/MinimalClean.Architecture.ServiceDefaults/Extensions.cs",
    "content": "using Microsoft.AspNetCore.Builder;\nusing Microsoft.AspNetCore.Diagnostics.HealthChecks;\nusing Microsoft.Extensions.DependencyInjection;\nusing Microsoft.Extensions.Diagnostics.HealthChecks;\nusing Microsoft.Extensions.Logging;\nusing Microsoft.Extensions.ServiceDiscovery;\nusing OpenTelemetry;\nusing OpenTelemetry.Metrics;\nusing OpenTelemetry.Trace;\n\nnamespace Microsoft.Extensions.Hosting;\n\n// Adds common .NET Aspire services: service discovery, resilience, health checks, and OpenTelemetry.\n// This project should be referenced by each service project in your solution.\n// To learn more about using this project, see https://aka.ms/dotnet/aspire/service-defaults\npublic static class Extensions\n{\n  private const string HealthEndpointPath = \"/health\";\n  private const string AlivenessEndpointPath = \"/alive\";\n\n  public static TBuilder AddServiceDefaults<TBuilder>(this TBuilder builder) where TBuilder : IHostApplicationBuilder\n  {\n    builder.ConfigureOpenTelemetry();\n\n    builder.AddDefaultHealthChecks();\n\n    builder.Services.AddServiceDiscovery();\n\n    builder.Services.ConfigureHttpClientDefaults(http =>\n    {\n      // Turn on resilience by default\n      http.AddStandardResilienceHandler();\n\n      // Turn on service discovery by default\n      http.AddServiceDiscovery();\n    });\n\n    // Uncomment the following to restrict the allowed schemes for service discovery.\n    // builder.Services.Configure<ServiceDiscoveryOptions>(options =>\n    // {\n    //     options.AllowedSchemes = [\"https\"];\n    // });\n\n    return builder;\n  }\n\n  public static TBuilder ConfigureOpenTelemetry<TBuilder>(this TBuilder builder) where TBuilder : IHostApplicationBuilder\n  {\n    builder.Logging.AddOpenTelemetry(logging =>\n    {\n      logging.IncludeFormattedMessage = true;\n      logging.IncludeScopes = true;\n    });\n\n    builder.Services.AddOpenTelemetry()\n        .WithMetrics(metrics =>\n        {\n          metrics.AddAspNetCoreInstrumentation()\n                  .AddHttpClientInstrumentation()\n                  .AddRuntimeInstrumentation();\n        })\n        .WithTracing(tracing =>\n        {\n          tracing.AddSource(builder.Environment.ApplicationName)\n                  .AddAspNetCoreInstrumentation(tracing =>\n                      // Exclude health check requests from tracing\n                      tracing.Filter = context =>\n                          !context.Request.Path.StartsWithSegments(HealthEndpointPath)\n                          && !context.Request.Path.StartsWithSegments(AlivenessEndpointPath)\n                  )\n                  // Uncomment the following line to enable gRPC instrumentation (requires the OpenTelemetry.Instrumentation.GrpcNetClient package)\n                  //.AddGrpcClientInstrumentation()\n                  .AddHttpClientInstrumentation();\n        });\n\n    builder.AddOpenTelemetryExporters();\n\n    return builder;\n  }\n\n  private static TBuilder AddOpenTelemetryExporters<TBuilder>(this TBuilder builder) where TBuilder : IHostApplicationBuilder\n  {\n    var useOtlpExporter = !string.IsNullOrWhiteSpace(builder.Configuration[\"OTEL_EXPORTER_OTLP_ENDPOINT\"]);\n\n    if (useOtlpExporter)\n    {\n      builder.Services.AddOpenTelemetry().UseOtlpExporter();\n    }\n\n    // Uncomment the following lines to enable the Azure Monitor exporter (requires the Azure.Monitor.OpenTelemetry.AspNetCore package)\n    //if (!string.IsNullOrEmpty(builder.Configuration[\"APPLICATIONINSIGHTS_CONNECTION_STRING\"]))\n    //{\n    //    builder.Services.AddOpenTelemetry()\n    //       .UseAzureMonitor();\n    //}\n\n    return builder;\n  }\n\n  public static TBuilder AddDefaultHealthChecks<TBuilder>(this TBuilder builder) where TBuilder : IHostApplicationBuilder\n  {\n    builder.Services.AddHealthChecks()\n        // Add a default liveness check to ensure app is responsive\n        .AddCheck(\"self\", () => HealthCheckResult.Healthy(), [\"live\"]);\n\n    return builder;\n  }\n\n  public static WebApplication MapDefaultEndpoints(this WebApplication app)\n  {\n    // Adding health checks endpoints to applications in non-development environments has security implications.\n    // See https://aka.ms/dotnet/aspire/healthchecks for details before enabling these endpoints in non-development environments.\n    if (app.Environment.IsDevelopment())\n    {\n      // All health checks must pass for app to be considered ready to accept traffic after starting\n      app.MapHealthChecks(HealthEndpointPath);\n\n      // Only health checks tagged with the \"live\" tag must pass for app to be considered alive\n      app.MapHealthChecks(AlivenessEndpointPath, new HealthCheckOptions\n      {\n        Predicate = r => r.Tags.Contains(\"live\")\n      });\n    }\n\n    return app;\n  }\n}\n"
  },
  {
    "path": "MinimalClean/src/MinimalClean.Architecture.ServiceDefaults/MinimalClean.Architecture.ServiceDefaults.csproj",
    "content": "<Project Sdk=\"Microsoft.NET.Sdk\">\n\n  <PropertyGroup>\n    <IsAspireSharedProject>true</IsAspireSharedProject>\n  </PropertyGroup>\n\n  <ItemGroup>\n    <FrameworkReference Include=\"Microsoft.AspNetCore.App\" />\n\n    <PackageReference Include=\"Microsoft.Extensions.Http.Resilience\" />\n    <PackageReference Include=\"Microsoft.Extensions.ServiceDiscovery\" />\n    <PackageReference Include=\"OpenTelemetry.Exporter.OpenTelemetryProtocol\" />\n    <PackageReference Include=\"OpenTelemetry.Extensions.Hosting\" />\n    <PackageReference Include=\"OpenTelemetry.Instrumentation.AspNetCore\" />\n    <PackageReference Include=\"OpenTelemetry.Instrumentation.Http\" />\n    <PackageReference Include=\"OpenTelemetry.Instrumentation.Runtime\" />\n  </ItemGroup>\n\n</Project>\n"
  },
  {
    "path": "MinimalClean/src/MinimalClean.Architecture.Web/AssemblyInfo.cs",
    "content": "using Vogen;\n[assembly: VogenDefaults(\n        staticAbstractsGeneration: StaticAbstractsGeneration.MostCommon |\n        StaticAbstractsGeneration.InstanceMethodsAndProperties)]\nnamespace MinimalClean.Architecture.Web;\n\npublic class AssemblyInfo { }\n"
  },
  {
    "path": "MinimalClean/src/MinimalClean.Architecture.Web/CartFeatures/AddToCart/AddToCartEndpoint.cs",
    "content": "using FluentValidation;\nusing Microsoft.AspNetCore.Http.HttpResults;\nusing MinimalClean.Architecture.Web.Domain.CartAggregate;\n\nnamespace MinimalClean.Architecture.Web.CartFeatures.AddToCart;\n\npublic sealed class AddToCartRequest\n{\n  public const string Route = \"/cart\";\n\n  public Guid? CartId { get; init; }\n  public int ProductId { get; init; }\n  public int Quantity { get; init; }\n}\n\n\npublic class AddToCartEndpoint(IMediator mediator)\n  : FastEndpoints.Endpoint<AddToCartRequest,\n             Results<Ok<CartResponse>,\n                     NotFound,\n                     ValidationProblem,\n                     ProblemHttpResult>,\n             AddToCartMapper>\n{\n  public override void Configure()\n  {\n    Post(AddToCartRequest.Route);\n    AllowAnonymous();\n\n    Summary(s =>\n    {\n      s.Summary = \"Add item to cart\";\n      s.Description = \"Adds a product to an existing cart or creates a new cart if CartId is not provided. Returns the updated cart with all items.\";\n      s.ExampleRequest = new AddToCartRequest \n      { \n        CartId = null, // null creates new cart\n        ProductId = 1, \n        Quantity = 2 \n      };\n      s.ResponseExamples[200] = new CartResponse(\n        Guid.Empty,\n        new List<CartItemResponse>\n        {\n          new(1, 2, 999.99m, 1999.98m)\n        },\n        1999.98m);\n\n      // Document possible responses\n      s.Responses[200] = \"Item added to cart successfully\";\n      s.Responses[404] = \"Product or Cart not found\";\n      s.Responses[400] = \"Invalid request data\";\n    });\n\n    // Add tags for API grouping\n    Tags(\"Cart\");\n\n    // Add additional metadata\n    Description(builder => builder\n      .Accepts<AddToCartRequest>(\"application/json\")\n      .Produces<CartResponse>(200, \"application/json\")\n      .ProducesProblem(404)\n      .ProducesProblem(400));\n  }\n\n  public override async Task<Results<Ok<CartResponse>, NotFound, ValidationProblem, ProblemHttpResult>>\n    ExecuteAsync(AddToCartRequest request, CancellationToken ct)\n  {\n    var cartId = request.CartId.HasValue ? CartId.From(request.CartId.Value) : (CartId?)null;\n    var command = new AddToCartCommand(cartId, request.ProductId, request.Quantity);\n    var result = await mediator.Send(command, ct);\n\n    if (result.Status == ResultStatus.NotFound)\n    {\n      return TypedResults.NotFound();\n    }\n\n    if (!result.IsSuccess)\n    {\n      return TypedResults.Problem(result.Errors.FirstOrDefault() ?? \"An error occurred\");\n    }\n\n    var response = Map.FromEntity(result.Value);\n    return TypedResults.Ok(response);\n  }\n}\n\npublic sealed class AddToCartValidator : FastEndpoints.Validator<AddToCartRequest>\n{\n  public AddToCartValidator()\n  {\n    RuleFor(x => x.ProductId)\n      .GreaterThan(0)\n      .WithMessage(\"Product ID must be greater than 0\");\n\n    RuleFor(x => x.Quantity)\n      .GreaterThan(0)\n      .WithMessage(\"Quantity must be greater than 0\");\n  }\n}\n\n\npublic sealed class AddToCartMapper\n  : FastEndpoints.Mapper<AddToCartRequest, CartResponse, CartDto>\n{\n  public override CartResponse FromEntity(CartDto e)\n  {\n    var items = e.Items.Select(i => new CartItemResponse(\n      i.ProductId,\n      i.Quantity,\n      i.UnitPrice,\n      i.TotalPrice\n    )).ToList();\n\n    return new CartResponse(e.Id.Value, items, e.Total);\n  }\n}\n\n"
  },
  {
    "path": "MinimalClean/src/MinimalClean.Architecture.Web/CartFeatures/AddToCart/AddToCartHandler.cs",
    "content": "using MinimalClean.Architecture.Web.Domain.CartAggregate;\nusing MinimalClean.Architecture.Web.Domain.CartAggregate.Specifications;\nusing MinimalClean.Architecture.Web.Domain.ProductAggregate;\nusing MinimalClean.Architecture.Web.Domain.ProductAggregate.Specifications;\n\nnamespace MinimalClean.Architecture.Web.CartFeatures.AddToCart;\n\npublic record AddToCartCommand(CartId? CartId, int ProductId, int Quantity) : ICommand<Result<CartDto>>;\n\npublic class AddToCartHandler(\n  IRepository<Cart> cartRepository,\n  IReadRepository<Product> productRepository)\n  : ICommandHandler<AddToCartCommand, Result<CartDto>>\n{\n  public async ValueTask<Result<CartDto>> Handle(AddToCartCommand request, CancellationToken cancellationToken)\n  {\n    // Validate product exists\n    var productSpec = new ProductByIdSpec(ProductId.From(request.ProductId));\n    var product = await productRepository.FirstOrDefaultAsync(productSpec, cancellationToken);\n    if (product == null)\n    {\n      return Result.NotFound(\"Product not found\");\n    }\n\n    // Get or create cart\n    Cart cart;\n    if (request.CartId.HasValue)\n    {\n      var cartSpec = new CartByIdSpec(request.CartId.Value);\n      var existingCart = await cartRepository.FirstOrDefaultAsync(cartSpec, cancellationToken);\n      if (existingCart == null)\n      {\n        return Result.NotFound(\"Cart not found\");\n      }\n      cart = existingCart;\n    }\n    else\n    {\n      // Create new cart - AddAsync saves by default\n      cart = new Cart();\n      cart = await cartRepository.AddAsync(cart, cancellationToken);\n    }\n\n    // Add item to cart\n    cart.AddItem(request.ProductId, request.Quantity, product.UnitPrice);\n\n    // Update the cart with the new items\n    await cartRepository.UpdateAsync(cart, cancellationToken);\n\n    // Map to DTO\n    var items = cart.Items.Select(i => new CartItemDto(\n      i.ProductId,\n      i.Quantity,\n      i.UnitPrice,\n      i.Quantity * i.UnitPrice\n    )).ToList();\n\n    var total = items.Sum(i => i.TotalPrice);\n\n    return new CartDto(cart.Id, items, total);\n  }\n}\n"
  },
  {
    "path": "MinimalClean/src/MinimalClean.Architecture.Web/CartFeatures/CartDto.cs",
    "content": "using MinimalClean.Architecture.Web.Domain.CartAggregate;\n\nnamespace MinimalClean.Architecture.Web.CartFeatures;\n\npublic record CartDto(CartId Id, IReadOnlyList<CartItemDto> Items, decimal Total);\n\npublic record CartItemDto(int ProductId, int Quantity, decimal UnitPrice, decimal TotalPrice);\n"
  },
  {
    "path": "MinimalClean/src/MinimalClean.Architecture.Web/CartFeatures/CartResponse.cs",
    "content": "namespace MinimalClean.Architecture.Web.CartFeatures;\n\npublic record CartResponse(Guid CartId, IReadOnlyList<CartItemResponse> Items, decimal Total);\n\npublic record CartItemResponse(int ProductId, int Quantity, decimal UnitPrice, decimal TotalPrice);\n"
  },
  {
    "path": "MinimalClean/src/MinimalClean.Architecture.Web/CartFeatures/Checkout/CheckoutEndpoint.cs",
    "content": "﻿using FastEndpoints;\nusing FluentValidation;\nusing Microsoft.AspNetCore.Http.HttpResults;\nusing MinimalClean.Architecture.Web.Domain.CartAggregate;\n\nnamespace MinimalClean.Architecture.Web.CartFeatures.Checkout;\n\npublic sealed class CheckoutRequest\n{\n  public const string Route = \"/cart/{CartId}/checkout\";\n\n  public Guid CartId { get; init; }\n  public string Email { get; init; } = string.Empty;\n}\n\npublic record CheckoutResponse(Guid OrderId);\n\npublic class CheckoutEndpoint(IMediator mediator)\n  : Endpoint<CheckoutRequest,\n             Results<Ok<CheckoutResponse>,\n                     NotFound,\n                     ValidationProblem,\n                     ProblemHttpResult>,\n             CheckoutMapper>\n{\n  public override void Configure()\n  {\n    Post(CheckoutRequest.Route);\n    AllowAnonymous();\n\n    Summary(s =>\n    {\n      s.Summary = \"Checkout cart\";\n      s.Description = \"Processes checkout for a cart, creating an order and marking the cart as completed. Requires a guest email address.\";\n      s.ExampleRequest = new CheckoutRequest \n      { \n        CartId = Guid.Parse(\"12345678-1234-1234-1234-123456789012\"),\n        Email = \"guest@example.com\"\n      };\n      s.ResponseExamples[200] = new CheckoutResponse(\n        Guid.Parse(\"87654321-4321-4321-4321-210987654321\"));\n\n      // Document possible responses\n      s.Responses[200] = \"Checkout completed successfully\";\n      s.Responses[404] = \"Cart not found\";\n      s.Responses[400] = \"Invalid request data or empty cart\";\n    });\n\n    // Add tags for API grouping\n    Tags(\"Cart\");\n\n    // Add additional metadata\n    Description(builder => builder\n      .Accepts<CheckoutRequest>(\"application/json\")\n      .Produces<CheckoutResponse>(200, \"application/json\")\n      .ProducesProblem(404)\n      .ProducesProblem(400));\n  }\n\n  public override async Task<Results<Ok<CheckoutResponse>, NotFound, ValidationProblem, ProblemHttpResult>>\n    ExecuteAsync(CheckoutRequest request, CancellationToken ct)\n  {\n    var cartId = CartId.From(request.CartId);\n    var command = new CheckoutCommand(cartId, request.Email);\n    var result = await mediator.Send(command, ct);\n\n    if (result.Status == ResultStatus.NotFound)\n    {\n      return TypedResults.NotFound();\n    }\n\n    if (result.Status == ResultStatus.Invalid)\n    {\n      return TypedResults.ValidationProblem(result.ValidationErrors.ToDictionary(e => e.Identifier, e => new[] { e.ErrorMessage }));\n    }\n\n    if (!result.IsSuccess)\n    {\n      return TypedResults.Problem(result.Errors.FirstOrDefault() ?? \"An error occurred during checkout\");\n    }\n\n    var response = Map.FromEntity(result.Value);\n    return TypedResults.Ok(response);\n  }\n}\n\npublic sealed class CheckoutValidator : Validator<CheckoutRequest>\n{\n  public CheckoutValidator()\n  {\n    RuleFor(x => x.CartId)\n      .NotEqual(Guid.Empty)\n      .WithMessage(\"Cart ID is required\");\n\n    RuleFor(x => x.Email)\n      .NotEmpty()\n      .WithMessage(\"Email is required\")\n      .EmailAddress()\n      .WithMessage(\"Email must be a valid email address\");\n  }\n}\n\npublic sealed class CheckoutMapper\n  : Mapper<CheckoutRequest, CheckoutResponse, CheckoutResult>\n{\n    public override CheckoutResponse FromEntity(CheckoutResult e) => new CheckoutResponse(e.OrderId.Value);\n}\n\n"
  },
  {
    "path": "MinimalClean/src/MinimalClean.Architecture.Web/CartFeatures/Checkout/CheckoutHandler.cs",
    "content": "using MinimalClean.Architecture.Web.Domain.CartAggregate;\nusing MinimalClean.Architecture.Web.Domain.CartAggregate.Specifications;\nusing MinimalClean.Architecture.Web.Domain.GuestUserAggregate;\nusing MinimalClean.Architecture.Web.Domain.GuestUserAggregate.Specifications;\nusing MinimalClean.Architecture.Web.Domain.OrderAggregate;\nusing MinimalClean.Architecture.Web.Domain.ProductAggregate;\n\nnamespace MinimalClean.Architecture.Web.CartFeatures.Checkout;\n\npublic record CheckoutCommand(CartId CartId, string Email) : ICommand<Result<CheckoutResult>>;\n\npublic record CheckoutResult(OrderId OrderId);\n\npublic class CheckoutHandler(\n  IRepository<Domain.CartAggregate.Cart> cartRepository,\n  IRepository<GuestUser> guestUserRepository,\n  IRepository<Order> orderRepository)\n  : ICommandHandler<CheckoutCommand, Result<CheckoutResult>>\n{\n  public async ValueTask<Result<CheckoutResult>> Handle(CheckoutCommand request, CancellationToken cancellationToken)\n  {\n    // Find the cart with its items\n    var cartSpec = new CartByIdSpec(request.CartId);\n    var cart = await cartRepository.FirstOrDefaultAsync(cartSpec, cancellationToken);\n\n    if (cart == null) return Result.NotFound(\"Cart not found\");\n    if (!cart.Items.Any()) return Result.Invalid(new ValidationError(\"Cart is empty\"));\n\n    // Get or create guest user\n    var guestUserSpec = new GuestUserByEmailSpec(request.Email);\n    var guestUser = await guestUserRepository.FirstOrDefaultAsync(guestUserSpec, cancellationToken);\n\n    if (guestUser == null)\n    {\n      var guestUserId = GuestUserId.From(Guid.NewGuid());\n      guestUser = new GuestUser(guestUserId, request.Email);\n      guestUser = await guestUserRepository.AddAsync(guestUser, cancellationToken);\n    }\n\n    // Create new order\n    var orderId = OrderId.From(Guid.NewGuid());\n    var order = new Order(orderId, guestUser.Id.Value);\n\n    // Add items from cart to order\n    foreach (var cartItem in cart.Items)\n    {\n      order.AddItem(\n        ProductId.From(cartItem.ProductId),\n        Quantity.From(cartItem.Quantity),\n        Price.From(cartItem.UnitPrice));\n    }\n\n    await orderRepository.AddAsync(order, cancellationToken);\n\n    cart.MarkAsDeleted();\n    await cartRepository.UpdateAsync(cart, cancellationToken);\n\n    return new CheckoutResult(order.Id);\n  }\n}\n"
  },
  {
    "path": "MinimalClean/src/MinimalClean.Architecture.Web/CartFeatures/GetById/GetByIdEndpoint.cs",
    "content": "using MinimalClean.Architecture.Web.Domain.CartAggregate;\nusing MinimalClean.Architecture.Web.Extensions;\nusing Microsoft.AspNetCore.Http.HttpResults;\nusing FastEndpoints;\n\nnamespace MinimalClean.Architecture.Web.CartFeatures.GetById;\n\npublic sealed class GetCartRequest\n{\n  public const string Route = \"/cart/{CartId}\";\n\n  public Guid CartId { get; init; }\n}\n\npublic class GetByIdEndpoint(IMediator mediator)\n  : Endpoint<GetCartRequest,\n             Results<Ok<CartResponse>,\n                     NotFound,\n                     ProblemHttpResult>,\n             GetCartMapper>\n{\n  public override void Configure()\n  {\n    Get(GetCartRequest.Route);\n    AllowAnonymous();\n\n    Summary(s =>\n    {\n      s.Summary = \"Get cart by ID\";\n      s.Description = \"Retrieves a cart and all its items by cart ID.\";\n      s.ExampleRequest = new GetCartRequest \n      { \n        CartId = Guid.Parse(\"12345678-1234-1234-1234-123456789012\")\n      };\n      s.ResponseExamples[200] = new CartResponse(\n        Guid.Parse(\"12345678-1234-1234-1234-123456789012\"),\n        new List<CartItemResponse>\n        {\n          new(1, 2, 999.99m, 1999.98m)\n        },\n        1999.98m);\n\n      // Document possible responses\n      s.Responses[200] = \"Cart retrieved successfully\";\n      s.Responses[404] = \"Cart not found\";\n    });\n\n    // Add tags for API grouping\n    Tags(\"Cart\");\n\n    // Add additional metadata\n    Description(builder => builder\n      .Produces<CartResponse>(200, \"application/json\")\n      .ProducesProblem(404));\n  }\n\n  public override async Task<Results<Ok<CartResponse>, NotFound, ProblemHttpResult>>\n    ExecuteAsync(GetCartRequest request, CancellationToken ct)\n  {\n    var cartId = CartId.From(request.CartId);\n    var query = new GetCartQuery(cartId);\n    var result = await mediator.Send(query, ct);\n\n    return result.ToGetByIdResult(Map.FromEntity);\n  }\n}\n\npublic sealed class GetCartMapper\n  : Mapper<GetCartRequest, CartResponse, CartDto>\n{\n  public override CartResponse FromEntity(CartDto e)\n  {\n    var items = e.Items.Select(i => new CartItemResponse(\n      i.ProductId,\n      i.Quantity,\n      i.UnitPrice,\n      i.TotalPrice\n    )).ToList();\n\n    return new CartResponse(e.Id.Value, items, e.Total);\n  }\n}\n"
  },
  {
    "path": "MinimalClean/src/MinimalClean.Architecture.Web/CartFeatures/GetById/GetCartHandler.cs",
    "content": "using MinimalClean.Architecture.Web.Domain.CartAggregate;\nusing MinimalClean.Architecture.Web.Domain.CartAggregate.Specifications;\n\nnamespace MinimalClean.Architecture.Web.CartFeatures.GetById;\n\npublic record GetCartQuery(CartId CartId) : IQuery<Result<CartDto>>;\npublic class GetCartHandler(IReadRepository<Domain.CartAggregate.Cart> repository)\n  : IQueryHandler<GetCartQuery, Result<CartDto>>\n{\n  public async ValueTask<Result<CartDto>> Handle(GetCartQuery request, CancellationToken cancellationToken)\n  {\n    var spec = new CartByIdSpec(request.CartId);\n    var cart = await repository.FirstOrDefaultAsync(spec, cancellationToken);\n\n    if (cart == null)\n    {\n      return Result.NotFound(\"Cart not found\");\n    }\n\n    // Map to DTO\n    var items = cart.Items.Select(i => new CartItemDto(\n      i.ProductId,\n      i.Quantity,\n      i.UnitPrice,\n      i.Quantity * i.UnitPrice\n    )).ToList();\n\n    var total = items.Sum(i => i.TotalPrice);\n\n    return new CartDto(cart.Id, items, total);\n  }\n}\n"
  },
  {
    "path": "MinimalClean/src/MinimalClean.Architecture.Web/Configurations/DatabaseOptions.cs",
    "content": "namespace MinimalClean.Architecture.Web.Configurations;\n\n/// <summary>\n/// Configuration options for database management\n/// </summary>\npublic class DatabaseOptions\n{\n  /// <summary>\n  /// If true, drops and recreates the database on startup in Development environment.\n  /// WARNING: This will delete all existing data!\n  /// </summary>\n  public bool RecreateOnStartup { get; set; } = false;\n}\n"
  },
  {
    "path": "MinimalClean/src/MinimalClean.Architecture.Web/Configurations/LoggerConfigs.cs",
    "content": "﻿using Serilog;\n\nnamespace MinimalClean.Architecture.Web.Configurations;\n\npublic static class LoggerConfigs\n{\n  public static WebApplicationBuilder AddLoggerConfigs(this WebApplicationBuilder builder)\n  {\n    // Add Serilog as an additional logging provider alongside OpenTelemetry\n    // This allows both Serilog (for console/file) and OpenTelemetry (for Aspire) to work together\n    builder.Logging.AddSerilog(new LoggerConfiguration()\n      .ReadFrom.Configuration(builder.Configuration)\n      .Enrich.FromLogContext()\n      .Enrich.WithProperty(\"Application\", builder.Environment.ApplicationName)\n      .WriteTo.Console()\n      .CreateLogger());\n\n    return builder;\n  }\n}\n"
  },
  {
    "path": "MinimalClean/src/MinimalClean.Architecture.Web/Configurations/LoggingBehavior.cs",
    "content": "﻿using System.Diagnostics;\n\nnamespace Nimble.Modulith.Web;\n\npublic class LoggingBehavior<TRequest, TResponse>(ILogger<LoggingBehavior<TRequest, TResponse>> logger) : IPipelineBehavior<TRequest, TResponse>\n    where TRequest : notnull, IMessage\n{\n  private readonly ILogger<LoggingBehavior<TRequest, TResponse>> _logger = logger;\n\n    public async ValueTask<TResponse> Handle(\n      TRequest request,\n      MessageHandlerDelegate<TRequest, TResponse> next,\n      CancellationToken cancellationToken)\n  {\n    if (_logger.IsEnabled(LogLevel.Information))\n    {\n      // Use structured logging with the whole object instead of reflection\n      _logger.LogInformation(\"Handling {RequestName}: {@Request}\", \n        typeof(TRequest).Name, request);\n    }\n\n    var sw = Stopwatch.StartNew();\n    var response = await next(request, cancellationToken);\n\n    _logger.LogInformation(\n      \"Handled {RequestName} with {Response} in {Ms} ms\",\n      typeof(TRequest).Name,\n      response,\n      sw.ElapsedMilliseconds);\n\n    sw.Stop();\n    return response;\n  }\n}\n"
  },
  {
    "path": "MinimalClean/src/MinimalClean.Architecture.Web/Configurations/MediatorConfig.cs",
    "content": "namespace MinimalClean.Architecture.Web.Configurations;\n\npublic static class MediatorConfig\n{\n  // Should be called from ServiceConfigs.cs, not Program.cs\n  public static IServiceCollection AddMediatorSourceGen(this IServiceCollection services,\n    ILogger logger)\n  {\n    logger.LogInformation(\"Registering Mediator SourceGen and Behaviors\");\n    services.AddMediator(options =>\n    {\n      // Lifetime: Singleton is fastest per docs; Scoped/Transient also supported.\n      options.ServiceLifetime = ServiceLifetime.Scoped;\n\n      // Supply any TYPE from each assembly you want scanned (the generator finds the assembly from the type)\n      options.Assemblies =\n      [\n        typeof(MediatorConfig)                  // Web\n      ];\n\n      // Register AOT pipeline behaviors here (order matters)\n      options.PipelineBehaviors =\n      [\n        typeof(Nimble.Modulith.Web.LoggingBehavior<,>)\n      ];\n\n      // If you have stream behaviors:\n      // options.StreamPipelineBehaviors = [ typeof(YourStreamBehavior<,>) ];\n    });\n\n    return services;\n  }\n}\n"
  },
  {
    "path": "MinimalClean/src/MinimalClean.Architecture.Web/Configurations/MiddlewareConfig.cs",
    "content": "using Ardalis.ListStartupServices;\nusing FastEndpoints;\nusing FastEndpoints.Swagger;\nusing Microsoft.EntityFrameworkCore;\nusing Microsoft.Extensions.Options;\nusing MinimalClean.Architecture.Web.Infrastructure.Data;\nusing Scalar.AspNetCore;\n\nnamespace MinimalClean.Architecture.Web.Configurations;\n\npublic static class MiddlewareConfig\n{\n  public static async Task<IApplicationBuilder> UseAppMiddlewareAndSeedDatabase(this WebApplication app)\n  {\n    if (app.Environment.IsDevelopment())\n    {\n      app.UseDeveloperExceptionPage();\n      app.UseShowAllServicesMiddleware(); // see https://github.com/ardalis/AspNetCoreStartupServices\n    }\n    else\n    {   \n      app.UseDefaultExceptionHandler(); // from FastEndpoints\n      app.UseHsts();\n    }\n\n    app.UseFastEndpoints();\n\n    if (app.Environment.IsDevelopment())\n    {\n      app.UseSwaggerGen(options =>\n      {\n        options.Path = \"/openapi/{documentName}.json\";\n      });\n      app.MapScalarApiReference();\n    }\n\n    app.UseHttpsRedirection(); // Note this will drop Authorization headers\n\n    await SeedDatabase(app);\n\n    return app;\n  }\n\n  static async Task SeedDatabase(WebApplication app)\n  {\n    using var scope = app.Services.CreateScope();\n    var services = scope.ServiceProvider;\n    var logger = services.GetRequiredService<ILogger<Program>>();\n\n    try\n    {\n      var context = services.GetRequiredService<AppDbContext>();\n      var dbOptions = services.GetService<IOptions<DatabaseOptions>>()?.Value;\n      \n      // Drop and recreate database in development if configured\n      if (app.Environment.IsDevelopment() && dbOptions?.RecreateOnStartup == true)\n      {\n        logger.LogWarning(\"DROPPING database for fresh start (DatabaseOptions:RecreateOnStartup = true)...\");\n        await context.Database.EnsureDeletedAsync();\n        logger.LogInformation(\"Database dropped.\");\n      }\n\n      // Apply all pending migrations\n      logger.LogInformation(\"Applying database migrations...\");\n      await context.Database.MigrateAsync();\n      logger.LogInformation(\"Database migrations applied successfully.\");\n\n      // Seed data\n      await SeedData.InitializeAsync(context, logger);\n    }\n    catch (Exception ex)\n    {\n      logger.LogError(ex, \"An error occurred seeding the DB. {exceptionMessage}\", ex.Message);\n    }\n  }\n}\n"
  },
  {
    "path": "MinimalClean/src/MinimalClean.Architecture.Web/Configurations/OptionConfigs.cs",
    "content": "using Ardalis.ListStartupServices;\nusing MinimalClean.Architecture.Web.Infrastructure.Email;\n\nnamespace MinimalClean.Architecture.Web.Configurations;\n\npublic static class OptionConfigs\n{\n  public static IServiceCollection AddOptionConfigs(this IServiceCollection services,\n                                                    IConfiguration configuration,\n                                                    Microsoft.Extensions.Logging.ILogger logger,\n                                                    WebApplicationBuilder builder)\n  {\n    services.Configure<MailserverConfiguration>(configuration.GetSection(\"Mailserver\"))\n    .Configure<DatabaseOptions>(configuration.GetSection(\"DatabaseOptions\"))\n    // Configure Web Behavior\n    .Configure<CookiePolicyOptions>(options =>\n    {\n      options.CheckConsentNeeded = context => true;\n      options.MinimumSameSitePolicy = SameSiteMode.None;\n    });\n\n    if (builder.Environment.IsDevelopment())\n    {\n      // add list services for diagnostic purposes - see https://github.com/ardalis/AspNetCoreStartupServices\n      services.Configure<ServiceConfig>(config =>\n      {\n        config.Services = new List<ServiceDescriptor>(builder.Services);\n\n        // optional - default path to view services is /listallservices - recommended to choose your own path\n        config.Path = \"/listservices\";\n      });\n    }\n\n    logger.LogInformation(\"{Project} were configured\", \"Options\");\n\n    return services;\n  }\n}\n"
  },
  {
    "path": "MinimalClean/src/MinimalClean.Architecture.Web/Configurations/ServiceConfigs.cs",
    "content": "using MinimalClean.Architecture.Web.Domain.Interfaces;\nusing MinimalClean.Architecture.Web.Infrastructure;\nusing MinimalClean.Architecture.Web.Infrastructure.Email;\n\nnamespace MinimalClean.Architecture.Web.Configurations;\n\npublic static class ServiceConfigs\n{\n  public static IServiceCollection AddServiceConfigs(this IServiceCollection services, Microsoft.Extensions.Logging.ILogger logger, WebApplicationBuilder builder)\n  {\n    services.AddInfrastructureServices(builder.Configuration, logger)\n            .AddMediatorSourceGen(logger);\n\n    if (builder.Environment.IsDevelopment())\n    {\n      // Use a local test email server\n      // See: https://ardalis.com/configuring-a-local-test-email-server/\n      services.AddScoped<IEmailSender, MimeKitEmailSender>();\n\n      // Otherwise use this:\n      //builder.Services.AddScoped<IEmailSender, FakeEmailSender>();\n\n    }\n    else\n    {\n      services.AddScoped<IEmailSender, MimeKitEmailSender>();\n    }\n\n    logger.LogInformation(\"{Project} services registered\", \"Mediator and Email Sender\");\n\n    return services;\n  }\n\n\n}\n"
  },
  {
    "path": "MinimalClean/src/MinimalClean.Architecture.Web/Constants.cs",
    "content": "namespace MinimalClean.Architecture.Web;\n\npublic class Constants\n{\n  public const int DEFAULT_PAGE_SIZE = 10;\n  public const int MAX_PAGE_SIZE = 100;\n}\n"
  },
  {
    "path": "MinimalClean/src/MinimalClean.Architecture.Web/Domain/CartAggregate/Cart.cs",
    "content": "﻿namespace MinimalClean.Architecture.Web.Domain.CartAggregate;\n\npublic class Cart : EntityBase<Cart, CartId>, IAggregateRoot\n{\n  private readonly List<CartItem> _items = new();\n\n  public DateTime CreatedOn { get; private set; } = DateTime.UtcNow;\n  public bool Deleted { get; private set; } = false;\n  public IReadOnlyList<CartItem> Items => _items.AsReadOnly();\n\n  public void AddItem(int productId, int quantity, decimal unitPrice)\n  {\n    var item = new CartItem(productId, quantity, unitPrice);\n    _items.Add(item);\n  }\n\n    public void MarkAsDeleted() => Deleted = true;\n}\n"
  },
  {
    "path": "MinimalClean/src/MinimalClean.Architecture.Web/Domain/CartAggregate/CartId.cs",
    "content": "using Vogen;\n\nnamespace MinimalClean.Architecture.Web.Domain.CartAggregate;\n\n[ValueObject<Guid>]\npublic readonly partial struct CartId\n{\n  private static Validation Validate(Guid value)\n      => value != Guid.Empty ? Validation.Ok : Validation.Invalid(\"CartId must set to non-default value.\");\n}\n[ValueObject<int>]\npublic readonly partial struct TestId { }\n"
  },
  {
    "path": "MinimalClean/src/MinimalClean.Architecture.Web/Domain/CartAggregate/CartItem.cs",
    "content": "namespace MinimalClean.Architecture.Web.Domain.CartAggregate;\n\npublic class CartItem : EntityBase<CartItem, CartItemId>\n{\n  // Private constructor for EF Core\n  private CartItem() { }\n  \n  public CartItem(int productId, int quantity, decimal unitPrice)\n  {\n    ProductId = productId;\n    Quantity = quantity;\n    UnitPrice = unitPrice;\n  }\n\n  public int ProductId { get; private set; }\n  public int Quantity { get; private set; }\n  public decimal UnitPrice { get; private set; }\n}\n"
  },
  {
    "path": "MinimalClean/src/MinimalClean.Architecture.Web/Domain/CartAggregate/CartItemId.cs",
    "content": "using Vogen;\n\nnamespace MinimalClean.Architecture.Web.Domain.CartAggregate;\n\n[ValueObject<Guid>]\npublic readonly partial struct CartItemId\n{\n  private static Validation Validate(Guid value)\n      => value != Guid.Empty ? Validation.Ok : Validation.Invalid(\"CartItemId must set to non-default value.\");\n}\n"
  },
  {
    "path": "MinimalClean/src/MinimalClean.Architecture.Web/Domain/CartAggregate/Specifications/CartByIdSpec.cs",
    "content": "namespace MinimalClean.Architecture.Web.Domain.CartAggregate.Specifications;\n\npublic class CartByIdSpec : Specification<Cart>\n{\n  public CartByIdSpec(CartId cartId) =>\n    Query\n        .Include(c => c.Items)\n        .Where(cart => cart.Id == cartId && !cart.Deleted);\n}\n"
  },
  {
    "path": "MinimalClean/src/MinimalClean.Architecture.Web/Domain/GuestUserAggregate/GuestUser.cs",
    "content": "namespace MinimalClean.Architecture.Web.Domain.GuestUserAggregate;\n\npublic class GuestUser : EntityBase<GuestUser, GuestUserId>, IAggregateRoot\n{\n  public GuestUser(GuestUserId id, string email)\n  {\n    Id = id;\n    Email = email;\n  }\n\n  public string Email { get; private set; }\n\n  public GuestUser UpdateEmail(string newEmail)\n  {\n    Email = newEmail;\n    return this;\n  }\n}\n"
  },
  {
    "path": "MinimalClean/src/MinimalClean.Architecture.Web/Domain/GuestUserAggregate/GuestUserId.cs",
    "content": "using Vogen;\n\nnamespace MinimalClean.Architecture.Web.Domain.GuestUserAggregate;\n\n[ValueObject<Guid>]\npublic readonly partial struct GuestUserId\n{\n  private static Validation Validate(Guid value)\n      => value != Guid.Empty ? Validation.Ok : Validation.Invalid(\"GuestUserId cannot be empty.\");\n}\n"
  },
  {
    "path": "MinimalClean/src/MinimalClean.Architecture.Web/Domain/GuestUserAggregate/Specifications/GuestUserByEmailSpec.cs",
    "content": "namespace MinimalClean.Architecture.Web.Domain.GuestUserAggregate.Specifications;\n\npublic class GuestUserByEmailSpec : Specification<GuestUser>\n{\n  public GuestUserByEmailSpec(string email) =>\n    Query.Where(g => g.Email == email);\n}"
  },
  {
    "path": "MinimalClean/src/MinimalClean.Architecture.Web/Domain/GuestUserAggregate/Specifications/GuestUserByIdSpec.cs",
    "content": "namespace MinimalClean.Architecture.Web.Domain.GuestUserAggregate.Specifications;\n\npublic class GuestUserByIdSpec : Specification<GuestUser>\n{\n  public GuestUserByIdSpec(GuestUserId guestUserId) =>\n    Query.Where(g => g.Id == guestUserId);\n}"
  },
  {
    "path": "MinimalClean/src/MinimalClean.Architecture.Web/Domain/Interfaces/IEmailSender.cs",
    "content": "namespace MinimalClean.Architecture.Web.Domain.Interfaces;\n\npublic interface IEmailSender\n{\n  Task SendEmailAsync(string to, string from, string subject, string body);\n}\n"
  },
  {
    "path": "MinimalClean/src/MinimalClean.Architecture.Web/Domain/OrderAggregate/Order.cs",
    "content": "using MinimalClean.Architecture.Web.Domain.ProductAggregate;\nusing MinimalClean.Architecture.Web.Infrastructure.Data;\n\nnamespace MinimalClean.Architecture.Web.Domain.OrderAggregate;\n\npublic class Order : EntityBase<Order, OrderId>, IAggregateRoot\n{\n  private readonly List<OrderItem> _items = new();\n\n  public Order(OrderId id, Guid guestUserId)\n  {\n    Id = id;\n    GuestUserId = guestUserId;\n\n  }\n\n  public DateTimeOffset CreatedOn { get; private set; } = DateTimeOffset.UtcNow;\n  public Guid GuestUserId { get; private set; }\n  public DateTimeOffset? DatePaid { get; private set; }\n  public string PaymentReference { get; private set; } = string.Empty;\n  public IReadOnlyList<OrderItem> Items => _items.AsReadOnly();\n\n  public decimal Total => _items.Sum(i => i.UnitPrice.Value * i.Quantity.Value);\n\n  public void AddItem(ProductId productId, Quantity quantity, Price unitPrice)\n  {\n    var item = new OrderItem(Id, productId, quantity, unitPrice);\n\n    if(Items.Any(i => i.ProductId == productId))\n    {\n      var existingItem = Items.First(i => i.ProductId == productId);\n      existingItem.IncreaseQuantity(quantity);\n      return;\n    }\n    _items.Add(item);\n  }\n\n  public void ConfirmPayment(DateTimeOffset datePaid, string paymentReference)\n  {\n    DatePaid = datePaid;\n    PaymentReference = paymentReference;\n  }\n}\n"
  },
  {
    "path": "MinimalClean/src/MinimalClean.Architecture.Web/Domain/OrderAggregate/OrderId.cs",
    "content": "using Vogen;\n\nnamespace MinimalClean.Architecture.Web.Domain.OrderAggregate;\n\n[ValueObject<Guid>]\npublic readonly partial struct OrderId\n{\n  private static Validation Validate(Guid value)\n      => value != Guid.Empty ? Validation.Ok : Validation.Invalid(\"OrderId cannot be empty.\");\n}\n"
  },
  {
    "path": "MinimalClean/src/MinimalClean.Architecture.Web/Domain/OrderAggregate/OrderItem.cs",
    "content": "﻿\nusing MinimalClean.Architecture.Web.Domain.ProductAggregate;\n\nnamespace MinimalClean.Architecture.Web.Domain.OrderAggregate;\n\npublic class OrderItem(OrderId orderId, ProductId productId, Quantity quantity, Price unitPrice)\n  : EntityBase<OrderItem, OrderItemId>\n{\n  public OrderId OrderId { get; private set; } = orderId;\n  public ProductId ProductId { get; private set; } = productId;\n  public Quantity Quantity { get; private set; } = quantity;\n  public Price UnitPrice { get; private set; } = unitPrice;\n\n  internal void IncreaseQuantity(Quantity quantity) => Quantity += quantity;\n}\n"
  },
  {
    "path": "MinimalClean/src/MinimalClean.Architecture.Web/Domain/OrderAggregate/OrderItemId.cs",
    "content": "using Vogen;\n\nnamespace MinimalClean.Architecture.Web.Domain.OrderAggregate;\n\n[ValueObject<Guid>]\npublic readonly partial struct OrderItemId\n{\n  private static Validation Validate(Guid value)\n      => value != Guid.Empty ? Validation.Ok : Validation.Invalid(\"OrderItemId cannot be empty.\");\n}\n"
  },
  {
    "path": "MinimalClean/src/MinimalClean.Architecture.Web/Domain/OrderAggregate/Price.cs",
    "content": "using Vogen;\n\nnamespace MinimalClean.Architecture.Web.Domain.OrderAggregate;\n\n[ValueObject<decimal>]\npublic readonly partial struct Price\n{\n  private static Validation Validate(decimal value)\n      => value > 0 ? Validation.Ok : Validation.Invalid(\"Price must be greater than zero.\");\n}\n"
  },
  {
    "path": "MinimalClean/src/MinimalClean.Architecture.Web/Domain/OrderAggregate/Quantity.cs",
    "content": "﻿using Vogen;\n\nnamespace MinimalClean.Architecture.Web.Domain.OrderAggregate;\n\n[ValueObject<int>]\npublic readonly partial struct Quantity\n{\n  private static Validation Validate(int value)\n      => value > 0 ? Validation.Ok : Validation.Invalid(\"Quantity must be greater than zero.\");\n\n  public static Quantity operator +(Quantity left, Quantity right) => From(left.Value + right.Value);\n}\n"
  },
  {
    "path": "MinimalClean/src/MinimalClean.Architecture.Web/Domain/ProductAggregate/Product.cs",
    "content": "﻿using Ardalis.GuardClauses;\n\nnamespace MinimalClean.Architecture.Web.Domain.ProductAggregate;\n\npublic class Product : EntityBase<Product, ProductId>, IAggregateRoot\n{\n  // Private constructor for EF Core\n  private Product() { }\n\n  public Product(ProductId id, string name, decimal unitPrice)\n  {\n    Guard.Against.InvalidInput(id, nameof(id), (id) => id == ProductId.New,\n      \"Use Product.Create() to create new products instead of passing ProductId.New to the constructor.\");\n    Id = id;\n    Name = name;\n    UnitPrice = unitPrice;\n  }\n\n  // Factory method for creating new products (before persistence)\n  public static Product Create(string name, decimal unitPrice) => new Product(ProductId.New, name, unitPrice);\n\n  public string Name { get; private set; } = string.Empty;\n  public decimal UnitPrice { get; private set; }\n\n  public Product UpdateName(string newName)\n  {\n    Name = newName;\n    return this;\n  }\n\n  public Product UpdatePrice(decimal newPrice)\n  {\n    UnitPrice = newPrice;\n    return this;\n  }\n}\n"
  },
  {
    "path": "MinimalClean/src/MinimalClean.Architecture.Web/Domain/ProductAggregate/ProductId.cs",
    "content": "using Vogen;\n\nnamespace MinimalClean.Architecture.Web.Domain.ProductAggregate;\n\n[ValueObject<int>]\npublic readonly partial struct ProductId\n{\n  /// <summary>\n  /// Represents a new Product that has not yet been persisted to the database.\n  /// EF Core will assign the actual identity value on SaveChanges.\n  /// </summary>\n  public static ProductId New => From(0);\n\n  private static Validation Validate(int value)\n      => value >= 0 ? Validation.Ok : Validation.Invalid(\"ProductId must be non-negative.\");\n}\n"
  },
  {
    "path": "MinimalClean/src/MinimalClean.Architecture.Web/Domain/ProductAggregate/Specifications/ProductByIdSpec.cs",
    "content": "namespace MinimalClean.Architecture.Web.Domain.ProductAggregate.Specifications;\n\npublic class ProductByIdSpec : Specification<Product>\n{\n  public ProductByIdSpec(ProductId productId) =>\n    Query\n        .Where(product => product.Id == productId);\n}\n"
  },
  {
    "path": "MinimalClean/src/MinimalClean.Architecture.Web/Extensions/ResultExtensions.cs",
    "content": "﻿using Microsoft.AspNetCore.Http.HttpResults;\n\nnamespace MinimalClean.Architecture.Web.Extensions;\n\npublic static class ResultExtensions\n{\n  /// <summary>\n  /// Maps Result to TypedResults for endpoints that return Created, ValidationProblem, or ProblemHttpResult\n  /// </summary>\n  public static Results<Created<TResponse>, ValidationProblem, ProblemHttpResult> ToCreatedResult<TValue, TResponse>(\n    this Result<TValue> result,\n    Func<TValue, string> locationBuilder,\n    Func<TValue, TResponse> mapResponse)\n  {\n    return result.Status switch\n    {\n      ResultStatus.Ok => TypedResults.Created(locationBuilder(result.Value), mapResponse(result.Value)),\n      ResultStatus.Invalid => TypedResults.ValidationProblem(\n        result.ValidationErrors\n          .GroupBy(e => e.Identifier ?? string.Empty)\n          .ToDictionary(\n            g => g.Key,\n            g => g.Select(e => e.ErrorMessage).ToArray()\n          )\n      ),\n      _ => TypedResults.Problem(\n        title: \"Create failed\",\n        detail: string.Join(\"; \", result.Errors),\n        statusCode: StatusCodes.Status400BadRequest)\n    };\n  }\n\n  /// <summary>\n  /// Maps Result to TypedResults for GetById endpoints that return Ok, NotFound, or ProblemHttpResult\n  /// </summary>\n  public static Results<Ok<TResponse>, NotFound, ProblemHttpResult> ToGetByIdResult<TValue, TResponse>(\n    this Result<TValue> result,\n    Func<TValue, TResponse> mapResponse) => ToOkOrNotFoundResult(result, mapResponse, \"Get\");\n\n  /// <summary>\n  /// Maps Result to TypedResults for Update endpoints that return Ok, NotFound, or ProblemHttpResult\n  /// </summary>\n  public static Results<Ok<TResponse>, NotFound, ProblemHttpResult> ToUpdateResult<TValue, TResponse>(\n  this Result<TValue> result,\n  Func<TValue, TResponse> mapResponse) => ToOkOrNotFoundResult(result, mapResponse, \"Update\");\n\n  /// <summary>\n  /// Maps Result to TypedResults for Delete endpoints that return NoContent, NotFound, or ProblemHttpResult\n  /// </summary>\n  public static Results<NoContent, NotFound, ProblemHttpResult> ToDeleteResult(\n  this Result result) => result.Status switch\n  {\n    ResultStatus.Ok => TypedResults.NoContent(),\n    ResultStatus.NotFound => TypedResults.NotFound(),\n    _ => TypedResults.Problem(\n        title: \"Delete failed\",\n        detail: string.Join(\"; \", result.Errors),\n        statusCode: StatusCodes.Status400BadRequest)\n  };\n\n  /// <summary>\n  /// Private helper method for Ok/NotFound result patterns\n  /// </summary>\n  private static Results<Ok<TResponse>, NotFound, ProblemHttpResult> ToOkOrNotFoundResult<TValue, TResponse>(\n  Result<TValue> result,\n  Func<TValue, TResponse> mapResponse,\n  string operationName) => result.Status switch\n  {\n    ResultStatus.Ok => TypedResults.Ok(mapResponse(result.Value)),\n    ResultStatus.NotFound => TypedResults.NotFound(),\n    _ => TypedResults.Problem(\n        title: $\"{operationName} failed\",\n        detail: string.Join(\"; \", result.Errors),\n        statusCode: StatusCodes.Status400BadRequest)\n  };\n\n  /// <summary>\n  /// Maps Result to TypedResults for endpoints that return Ok only (like List endpoints)\n  /// </summary>\n  public static Ok<TResponse> ToOkOnlyResult<TValue, TResponse>(\n  this Result<TValue> result,\n  Func<TValue, TResponse> mapResponse) => TypedResults.Ok(mapResponse(result.Value));\n}\n"
  },
  {
    "path": "MinimalClean/src/MinimalClean.Architecture.Web/GlobalUsings.cs",
    "content": "global using Mediator;\nglobal using Ardalis.Result;\nglobal using Ardalis.Specification;\nglobal using Ardalis.SharedKernel;\n"
  },
  {
    "path": "MinimalClean/src/MinimalClean.Architecture.Web/Infrastructure/Data/AppDbContext.cs",
    "content": "using System.Reflection;\nusing Microsoft.EntityFrameworkCore;\nusing MinimalClean.Architecture.Web.Domain.CartAggregate;\nusing MinimalClean.Architecture.Web.Domain.GuestUserAggregate;\nusing MinimalClean.Architecture.Web.Domain.OrderAggregate;\nusing MinimalClean.Architecture.Web.Domain.ProductAggregate;\n\nnamespace MinimalClean.Architecture.Web.Infrastructure.Data;\npublic class AppDbContext(DbContextOptions<AppDbContext> options) : \n  DbContext(options)\n{\n  public DbSet<Product> Products => Set<Product>();\n  public DbSet<Cart> Carts => Set<Cart>();\n  public DbSet<CartItem> CartItems => Set<CartItem>();\n  public DbSet<GuestUser> GuestUsers => Set<GuestUser>();\n  public DbSet<Order> Orders => Set<Order>();\n  public DbSet<OrderItem> OrderItems => Set<OrderItem>();\n\n  protected override void OnModelCreating(ModelBuilder modelBuilder)\n  {\n    base.OnModelCreating(modelBuilder);\n    modelBuilder.ApplyConfigurationsFromAssembly(Assembly.GetExecutingAssembly());\n  }\n\n  public override int SaveChanges() =>\n        SaveChangesAsync().GetAwaiter().GetResult();\n}\n"
  },
  {
    "path": "MinimalClean/src/MinimalClean.Architecture.Web/Infrastructure/Data/AppDbContextExtensions.cs",
    "content": "using Microsoft.EntityFrameworkCore;\n\nnamespace MinimalClean.Architecture.Web.Infrastructure.Data;\n\npublic static class AppDbContextExtensions\n{\n  public static void AddApplicationDbContext(this IServiceCollection services, string connectionString) =>\n    services.AddDbContext<AppDbContext>(options =>\n         options.UseSqlServer(connectionString));\n\n}\n"
  },
  {
    "path": "MinimalClean/src/MinimalClean.Architecture.Web/Infrastructure/Data/AppDbContextFactory.cs",
    "content": "using Microsoft.EntityFrameworkCore;\nusing Microsoft.EntityFrameworkCore.Design;\n\nnamespace MinimalClean.Architecture.Web.Infrastructure.Data;\n\n/// <summary>\n/// Design-time factory for creating DbContext instances for EF Core tools.\n/// This is ONLY used when CREATING migrations (e.g., 'dotnet ef migrations add').\n/// It is NOT used at runtime - Aspire handles the runtime connection.\n/// \n/// Migrations are automatically APPLIED at runtime via MigrateAsync() in MiddlewareConfig.cs.\n/// \n/// To create migrations with SQL Server, set an environment variable:\n/// PowerShell: $env:ConnectionStrings__AppDb = \"Server=localhost,1433;Database=AppDb;User ID=sa;Password=YourPassword;TrustServerCertificate=true\"\n/// Bash: export ConnectionStrings__AppDb=\"Server=localhost,1433;Database=AppDb;User ID=sa;Password=YourPassword;TrustServerCertificate=true\"\n/// \n/// Always uses SQL Server for migrations.\n/// </summary>\npublic class AppDbContextFactory : IDesignTimeDbContextFactory<AppDbContext>\n{\n  public AppDbContext CreateDbContext(string[] args)\n  {\n    var optionsBuilder = new DbContextOptionsBuilder<AppDbContext>();\n\n    // Try to get connection string from environment variable (ASP.NET Core format)\n    var connectionString = Environment.GetEnvironmentVariable(\"ConnectionStrings__AppDb\")\n                          ?? \"Server=localhost,1433;Database=AppDb_Design;User ID=sa;Password=Your$tr0ngP@ss!;TrustServerCertificate=true\"; // Default SQL Server connection for design-time\n\n    optionsBuilder.UseSqlServer(connectionString);\n\n    return new AppDbContext(optionsBuilder.Options);\n  }\n}\n"
  },
  {
    "path": "MinimalClean/src/MinimalClean.Architecture.Web/Infrastructure/Data/Config/CartConfiguration.cs",
    "content": "using Microsoft.EntityFrameworkCore;\nusing Microsoft.EntityFrameworkCore.Metadata.Builders;\nusing MinimalClean.Architecture.Web.Domain.CartAggregate;\n\nnamespace MinimalClean.Architecture.Web.Infrastructure.Data.Config;\n\npublic class CartConfiguration : IEntityTypeConfiguration<Cart>\n{\n  public void Configure(EntityTypeBuilder<Cart> builder)\n  {\n    builder.Property(entity => entity.Id)\n      .HasValueGenerator<VogenGuidIdValueGenerator<AppDbContext, Cart, CartId>>()\n      .HasVogenConversion()\n      .IsRequired();\n\n    builder.Property(entity => entity.CreatedOn)\n      .IsRequired();\n\n    builder.Property(entity => entity.Deleted)\n      .IsRequired();\n\n    // CartItems relationship\n    builder.HasMany(c => c.Items);\n  }\n}\n"
  },
  {
    "path": "MinimalClean/src/MinimalClean.Architecture.Web/Infrastructure/Data/Config/CartItemConfiguration.cs",
    "content": "using Microsoft.EntityFrameworkCore;\nusing Microsoft.EntityFrameworkCore.Metadata.Builders;\nusing MinimalClean.Architecture.Web.Domain.CartAggregate;\n\nnamespace MinimalClean.Architecture.Web.Infrastructure.Data.Config;\n\npublic class CartItemConfiguration : IEntityTypeConfiguration<CartItem>\n{\n  public void Configure(EntityTypeBuilder<CartItem> builder)\n  {\n    builder.ToTable(\"CartItems\");\n\n    builder.Property(entity => entity.Id)\n      .HasValueGenerator<VogenGuidIdValueGenerator<AppDbContext, CartItem, CartItemId>>()\n      .HasVogenConversion()\n      .IsRequired();\n        \n    builder.Property(ci => ci.ProductId)\n      .IsRequired();\n    \n    builder.Property(ci => ci.Quantity)\n      .IsRequired();\n    \n    builder.Property(ci => ci.UnitPrice)\n      .HasPrecision(18, 2)\n      .IsRequired();\n  }\n}\n"
  },
  {
    "path": "MinimalClean/src/MinimalClean.Architecture.Web/Infrastructure/Data/Config/DataSchemaConstants.cs",
    "content": "namespace MinimalClean.Architecture.Web.Infrastructure.Data.Config;\n\npublic static class DataSchemaConstants\n{\n  public const int DEFAULT_NAME_LENGTH = 100;\n}\n"
  },
  {
    "path": "MinimalClean/src/MinimalClean.Architecture.Web/Infrastructure/Data/Config/GuestUserConfiguration.cs",
    "content": "using Microsoft.EntityFrameworkCore;\nusing Microsoft.EntityFrameworkCore.Metadata.Builders;\nusing MinimalClean.Architecture.Web.Domain.GuestUserAggregate;\n\nnamespace MinimalClean.Architecture.Web.Infrastructure.Data.Config;\n\npublic class GuestUserConfiguration : IEntityTypeConfiguration<GuestUser>\n{\n  public void Configure(EntityTypeBuilder<GuestUser> builder)\n  {\n    builder.Property(entity => entity.Id)\n      .HasValueGenerator<VogenGuidIdValueGenerator<AppDbContext, GuestUser, GuestUserId>>()\n      .HasVogenConversion()\n      .IsRequired();\n\n    builder.Property(entity => entity.Email)\n      .HasMaxLength(DataSchemaConstants.DEFAULT_NAME_LENGTH)\n      .IsRequired();\n  }\n}\n"
  },
  {
    "path": "MinimalClean/src/MinimalClean.Architecture.Web/Infrastructure/Data/Config/OrderConfiguration.cs",
    "content": "using Microsoft.EntityFrameworkCore;\nusing Microsoft.EntityFrameworkCore.Metadata.Builders;\nusing MinimalClean.Architecture.Web.Domain.OrderAggregate;\n\nnamespace MinimalClean.Architecture.Web.Infrastructure.Data.Config;\n\npublic class OrderConfiguration : IEntityTypeConfiguration<Order>\n{\n  public void Configure(EntityTypeBuilder<Order> builder)\n  {\n    builder.Property(entity => entity.Id)\n      .HasValueGenerator<VogenGuidIdValueGenerator<AppDbContext, Order, OrderId>>()\n      .HasVogenConversion()\n      .IsRequired();\n\n    builder.Property(entity => entity.CreatedOn)\n      .IsRequired();\n\n    builder.Property(entity => entity.GuestUserId)\n      .IsRequired();\n\n    builder.Property(entity => entity.DatePaid)\n      .IsRequired(false);\n\n    builder.Property(entity => entity.PaymentReference)\n      .HasMaxLength(DataSchemaConstants.DEFAULT_NAME_LENGTH)\n      .IsRequired(false);\n\n    // OrderItems relationship\n    builder.HasMany(o => o.Items);\n  }\n}\n"
  },
  {
    "path": "MinimalClean/src/MinimalClean.Architecture.Web/Infrastructure/Data/Config/OrderItemConfiguration.cs",
    "content": "using Microsoft.EntityFrameworkCore;\nusing Microsoft.EntityFrameworkCore.Metadata.Builders;\nusing MinimalClean.Architecture.Web.Domain.OrderAggregate;\nusing MinimalClean.Architecture.Web.Domain.ProductAggregate;\n\nnamespace MinimalClean.Architecture.Web.Infrastructure.Data.Config;\n\npublic class OrderItemConfiguration : IEntityTypeConfiguration<OrderItem>\n{\n  public void Configure(EntityTypeBuilder<OrderItem> builder)\n  {\n    ArgumentNullException.ThrowIfNull(builder);\n    builder.ToTable(\"OrderItems\");\n\n    builder.Property(entity => entity.Id)\n      .HasValueGenerator<VogenGuidIdValueGenerator<AppDbContext, OrderItem, OrderItemId>>()\n      .HasVogenConversion()\n      .IsRequired();\n        \n    builder.Property(oi => oi.OrderId)\n      .HasVogenConversion()\n      .IsRequired();\n    \n    builder.Property(oi => oi.ProductId)\n      .HasVogenConversion()\n      .IsRequired();\n    \n    builder.Property(oi => oi.Quantity)\n      .HasVogenConversion()\n      .IsRequired();\n    \n    builder.Property(oi => oi.UnitPrice)\n      .HasVogenConversion()\n      .HasPrecision(18, 2)\n      .IsRequired();\n  }\n}\n"
  },
  {
    "path": "MinimalClean/src/MinimalClean.Architecture.Web/Infrastructure/Data/Config/ProductConfiguration.cs",
    "content": "using Microsoft.EntityFrameworkCore;\nusing Microsoft.EntityFrameworkCore.Metadata.Builders;\nusing MinimalClean.Architecture.Web.Domain.ProductAggregate;\n\nnamespace MinimalClean.Architecture.Web.Infrastructure.Data.Config;\n\npublic class ProductConfiguration : IEntityTypeConfiguration<Product>\n{\n  public void Configure(EntityTypeBuilder<Product> builder)\n  {\n    builder.Property(entity => entity.Id)\n      .HasValueGenerator<VogenIntIdValueGenerator<AppDbContext, Product, ProductId>>()\n      .HasVogenConversion()\n      .IsRequired();\n\n    builder.Property(entity => entity.Name)\n      .HasMaxLength(100)\n      .IsRequired();\n\n    builder.Property(entity => entity.UnitPrice)\n      .HasPrecision(18, 2)\n      .IsRequired();\n\n    builder.HasData(\n      new Product(\n        ProductId.From(1),\n        \"Coffee Mug\",\n        9.99m),\n      new Product(\n        ProductId.From(2),\n        \"T-Shirt\",\n        19.99m),\n      new Product(\n        ProductId.From(3),\n        \"Sticker Pack\",\n        3.99m)\n    );\n  }\n}\n"
  },
  {
    "path": "MinimalClean/src/MinimalClean.Architecture.Web/Infrastructure/Data/Config/VogenEfCoreConverters.cs",
    "content": "using MinimalClean.Architecture.Web.Domain.CartAggregate;\nusing MinimalClean.Architecture.Web.Domain.GuestUserAggregate;\nusing MinimalClean.Architecture.Web.Domain.OrderAggregate;\nusing MinimalClean.Architecture.Web.Domain.ProductAggregate;\nusing Vogen;\n\nnamespace MinimalClean.Architecture.Web.Infrastructure.Data.Config;\n\n[EfCoreConverter<ProductId>]\n[EfCoreConverter<CartId>]\n[EfCoreConverter<CartItemId>]\n[EfCoreConverter<GuestUserId>]\n[EfCoreConverter<OrderId>]\n[EfCoreConverter<OrderItemId>]\n[EfCoreConverter<Quantity>]\n[EfCoreConverter<Price>]\ninternal partial class VogenEfCoreConverters;\n"
  },
  {
    "path": "MinimalClean/src/MinimalClean.Architecture.Web/Infrastructure/Data/Config/VogenGuidIdValueGenerator.cs",
    "content": "using Microsoft.EntityFrameworkCore;\nusing Microsoft.EntityFrameworkCore.ChangeTracking;\nusing Microsoft.EntityFrameworkCore.ValueGeneration;\n\nnamespace MinimalClean.Architecture.Web.Infrastructure.Data.Config;\n\ninternal class VogenGuidIdValueGenerator<TContext, TEntityBase, TId> : ValueGenerator<TId>\n    where TContext : DbContext\n    where TEntityBase : EntityBase<TEntityBase, TId>\n    where TId : struct\n{\n  public override TId Next(EntityEntry entry)\n  {\n    // Use reflection to call the static From method on the value object\n    var fromMethod = typeof(TId).GetMethod(\"From\", new[] { typeof(Guid) });\n    if (fromMethod == null)\n    {\n      throw new InvalidOperationException($\"Type {typeof(TId).Name} does not have a From(Guid) method\");\n    }\n\n    return (TId)fromMethod.Invoke(null, new object[] { Guid.NewGuid() })!;\n  }\n\n  public override bool GeneratesTemporaryValues => false;\n}\n"
  },
  {
    "path": "MinimalClean/src/MinimalClean.Architecture.Web/Infrastructure/Data/Config/VogenIntIdValueGenerator.cs",
    "content": "using System.Reflection;\nusing Microsoft.EntityFrameworkCore;\nusing Microsoft.EntityFrameworkCore.ChangeTracking;\nusing Microsoft.EntityFrameworkCore.ValueGeneration;\nusing Vogen;\n\nnamespace MinimalClean.Architecture.Web.Infrastructure.Data.Config;\n\ninternal class VogenIntIdValueGenerator<TContext, TEntityBase, TId> : ValueGenerator<TId>\n    where TContext : DbContext\n    where TEntityBase : EntityBase<TEntityBase, TId>\n    where TId : IVogen<TId, int>\n{\n  private readonly PropertyInfo _matchPropertyGetter;\n\n  public VogenIntIdValueGenerator()\n  {\n    var matchingProperties =\n        typeof(TContext).GetProperties()\n        .Where(p => p.GetGetMethod()!.IsPublic && p.PropertyType == typeof(DbSet<TEntityBase>))\n        .ToList();\n\n    if (matchingProperties.Count == 0)\n    {\n      throw new InvalidOperationException($\"No properties found in the EFCore context for a DBSet of {nameof(TEntityBase)}\");\n    }\n\n    if (matchingProperties.Count > 1)\n    {\n      throw new InvalidOperationException($\"Multiple properties found in the EFCore context for a DBSet of {nameof(TEntityBase)}\");\n    }\n\n    _matchPropertyGetter = matchingProperties[0];\n  }\n\n  public override TId Next(EntityEntry entry)\n  {\n    TContext ctx = (TContext)entry.Context;\n\n    DbSet<TEntityBase> entities = (DbSet<TEntityBase>)_matchPropertyGetter.GetValue(ctx)!;\n\n    var next = Math.Max(\n        MaxFrom(entities.Local),\n        MaxFrom(entities)) + 1;\n\n    return TId.From(next);\n  }\n\n  private static int MaxFrom(IEnumerable<TEntityBase> es)\n  {\n    if (!es.Any()) return 0;\n    return es.Max(e => e.Id.Value);\n  }\n\n  public override bool GeneratesTemporaryValues => false;\n}\n"
  },
  {
    "path": "MinimalClean/src/MinimalClean.Architecture.Web/Infrastructure/Data/EfRepository.cs",
    "content": "using Ardalis.Specification.EntityFrameworkCore;\n\nnamespace MinimalClean.Architecture.Web.Infrastructure.Data;\n\n// inherit from Ardalis.Specification type\npublic class EfRepository<T>(AppDbContext dbContext) :\n  RepositoryBase<T>(dbContext), IReadRepository<T>, IRepository<T> where T : class, IAggregateRoot\n{\n}\n"
  },
  {
    "path": "MinimalClean/src/MinimalClean.Architecture.Web/Infrastructure/Data/EventDispatcherInterceptor.cs",
    "content": "using Microsoft.EntityFrameworkCore.Diagnostics;\n\nnamespace MinimalClean.Architecture.Web.Infrastructure.Data;\n\n// Intercepts SaveChanges to dispatch domain events after changes are successfully saved\npublic class EventDispatchInterceptor(IDomainEventDispatcher domainEventDispatcher) : SaveChangesInterceptor\n{\n  private readonly IDomainEventDispatcher _domainEventDispatcher = domainEventDispatcher;\n\n  // Called after SaveChangesAsync has completed successfully\n  public override async ValueTask<int> SavedChangesAsync(SaveChangesCompletedEventData eventData, int result,\n    CancellationToken cancellationToken = new CancellationToken())\n  {\n    var context = eventData.Context;\n    if (context is not AppDbContext appDbContext)\n    {\n      return await base.SavedChangesAsync(eventData, result, cancellationToken).ConfigureAwait(false);\n    }\n\n    // Retrieve all tracked entities that have domain events\n    var entitiesWithEvents = appDbContext.ChangeTracker.Entries<HasDomainEventsBase>()\n      .Select(e => e.Entity)\n      .Where(e => e.DomainEvents.Any())\n      .ToArray();\n\n    // Dispatch and clear domain events\n    await _domainEventDispatcher.DispatchAndClearEvents(entitiesWithEvents);\n\n    return await base.SavedChangesAsync(eventData, result, cancellationToken);\n\n  }\n}\n\n"
  },
  {
    "path": "MinimalClean/src/MinimalClean.Architecture.Web/Infrastructure/Data/Migrations/20251020223304_Initial.Designer.cs",
    "content": "// <auto-generated />\nusing System;\nusing Microsoft.EntityFrameworkCore;\nusing Microsoft.EntityFrameworkCore.Infrastructure;\nusing Microsoft.EntityFrameworkCore.Metadata;\nusing Microsoft.EntityFrameworkCore.Migrations;\nusing Microsoft.EntityFrameworkCore.Storage.ValueConversion;\nusing MinimalClean.Architecture.Web.Infrastructure.Data;\n\n#nullable disable\n\nnamespace MinimalClean.Architecture.Web.Infrastructure.Data.Migrations\n{\n    [DbContext(typeof(AppDbContext))]\n    [Migration(\"20251020223304_Initial\")]\n    partial class Initial\n    {\n        /// <inheritdoc />\n        protected override void BuildTargetModel(ModelBuilder modelBuilder)\n        {\n#pragma warning disable 612, 618\n            modelBuilder\n                .HasAnnotation(\"ProductVersion\", \"9.0.10\")\n                .HasAnnotation(\"Relational:MaxIdentifierLength\", 128);\n\n            SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder);\n\n            modelBuilder.Entity(\"MinimalClean.Architecture.Web.Domain.CartAggregate.Cart\", b =>\n                {\n                    b.Property<Guid>(\"Id\")\n                        .HasColumnType(\"uniqueidentifier\");\n\n                    b.Property<DateTime>(\"CreatedOn\")\n                        .HasColumnType(\"datetime2\");\n\n                    b.Property<bool>(\"Deleted\")\n                        .HasColumnType(\"bit\");\n\n                    b.HasKey(\"Id\");\n\n                    b.ToTable(\"Carts\");\n                });\n\n            modelBuilder.Entity(\"MinimalClean.Architecture.Web.Domain.CartAggregate.CartItem\", b =>\n                {\n                    b.Property<Guid>(\"Id\")\n                        .HasColumnType(\"uniqueidentifier\");\n\n                    b.Property<Guid?>(\"CartId\")\n                        .HasColumnType(\"uniqueidentifier\");\n\n                    b.Property<int>(\"ProductId\")\n                        .HasColumnType(\"int\");\n\n                    b.Property<int>(\"Quantity\")\n                        .HasColumnType(\"int\");\n\n                    b.Property<decimal>(\"UnitPrice\")\n                        .HasPrecision(18, 2)\n                        .HasColumnType(\"decimal(18,2)\");\n\n                    b.HasKey(\"Id\");\n\n                    b.HasIndex(\"CartId\");\n\n                    b.ToTable(\"CartItems\", (string)null);\n                });\n\n            modelBuilder.Entity(\"MinimalClean.Architecture.Web.Domain.ProductAggregate.Product\", b =>\n                {\n                    b.Property<int>(\"Id\")\n                        .HasColumnType(\"int\");\n\n                    b.Property<string>(\"Name\")\n                        .IsRequired()\n                        .HasMaxLength(100)\n                        .HasColumnType(\"nvarchar(100)\");\n\n                    b.Property<decimal>(\"UnitPrice\")\n                        .HasPrecision(18, 2)\n                        .HasColumnType(\"decimal(18,2)\");\n\n                    b.HasKey(\"Id\");\n\n                    b.ToTable(\"Products\");\n\n                    b.HasData(\n                        new\n                        {\n                            Id = 1,\n                            Name = \"Laptop\",\n                            UnitPrice = 999.99m\n                        },\n                        new\n                        {\n                            Id = 2,\n                            Name = \"Smartphone\",\n                            UnitPrice = 499.99m\n                        },\n                        new\n                        {\n                            Id = 3,\n                            Name = \"Tablet\",\n                            UnitPrice = 299.99m\n                        });\n                });\n\n            modelBuilder.Entity(\"MinimalClean.Architecture.Web.Domain.CartAggregate.CartItem\", b =>\n                {\n                    b.HasOne(\"MinimalClean.Architecture.Web.Domain.CartAggregate.Cart\", null)\n                        .WithMany(\"Items\")\n                        .HasForeignKey(\"CartId\");\n                });\n\n            modelBuilder.Entity(\"MinimalClean.Architecture.Web.Domain.CartAggregate.Cart\", b =>\n                {\n                    b.Navigation(\"Items\");\n                });\n#pragma warning restore 612, 618\n        }\n    }\n}\n"
  },
  {
    "path": "MinimalClean/src/MinimalClean.Architecture.Web/Infrastructure/Data/Migrations/20251020223304_Initial.cs",
    "content": "using System;\nusing Microsoft.EntityFrameworkCore.Migrations;\n\n#nullable disable\n\n#pragma warning disable CA1814 // Prefer jagged arrays over multidimensional\n\nnamespace MinimalClean.Architecture.Web.Infrastructure.Data.Migrations\n{\n    /// <inheritdoc />\n    public partial class Initial : Migration\n    {\n        /// <inheritdoc />\n        protected override void Up(MigrationBuilder migrationBuilder)\n        {\n            migrationBuilder.CreateTable(\n                name: \"Carts\",\n                columns: table => new\n                {\n                    Id = table.Column<Guid>(type: \"uniqueidentifier\", nullable: false),\n                    CreatedOn = table.Column<DateTime>(type: \"datetime2\", nullable: false),\n                    Deleted = table.Column<bool>(type: \"bit\", nullable: false)\n                },\n                constraints: table =>\n                {\n                    table.PrimaryKey(\"PK_Carts\", x => x.Id);\n                });\n\n            migrationBuilder.CreateTable(\n                name: \"Products\",\n                columns: table => new\n                {\n                    Id = table.Column<int>(type: \"int\", nullable: false),\n                    Name = table.Column<string>(type: \"nvarchar(100)\", maxLength: 100, nullable: false),\n                    UnitPrice = table.Column<decimal>(type: \"decimal(18,2)\", precision: 18, scale: 2, nullable: false)\n                },\n                constraints: table =>\n                {\n                    table.PrimaryKey(\"PK_Products\", x => x.Id);\n                });\n\n            migrationBuilder.CreateTable(\n                name: \"CartItems\",\n                columns: table => new\n                {\n                    Id = table.Column<Guid>(type: \"uniqueidentifier\", nullable: false),\n                    ProductId = table.Column<int>(type: \"int\", nullable: false),\n                    Quantity = table.Column<int>(type: \"int\", nullable: false),\n                    UnitPrice = table.Column<decimal>(type: \"decimal(18,2)\", precision: 18, scale: 2, nullable: false),\n                    CartId = table.Column<Guid>(type: \"uniqueidentifier\", nullable: true)\n                },\n                constraints: table =>\n                {\n                    table.PrimaryKey(\"PK_CartItems\", x => x.Id);\n                    table.ForeignKey(\n                        name: \"FK_CartItems_Carts_CartId\",\n                        column: x => x.CartId,\n                        principalTable: \"Carts\",\n                        principalColumn: \"Id\");\n                });\n\n            migrationBuilder.InsertData(\n                table: \"Products\",\n                columns: new[] { \"Id\", \"Name\", \"UnitPrice\" },\n                values: new object[,]\n                {\n                    { 1, \"Laptop\", 999.99m },\n                    { 2, \"Smartphone\", 499.99m },\n                    { 3, \"Tablet\", 299.99m }\n                });\n\n            migrationBuilder.CreateIndex(\n                name: \"IX_CartItems_CartId\",\n                table: \"CartItems\",\n                column: \"CartId\");\n        }\n\n        /// <inheritdoc />\n        protected override void Down(MigrationBuilder migrationBuilder)\n        {\n            migrationBuilder.DropTable(\n                name: \"CartItems\");\n\n            migrationBuilder.DropTable(\n                name: \"Products\");\n\n            migrationBuilder.DropTable(\n                name: \"Carts\");\n        }\n    }\n}\n"
  },
  {
    "path": "MinimalClean/src/MinimalClean.Architecture.Web/Infrastructure/Data/Migrations/20251024232246_AddGuestUsersAndOrdersSqlServer.Designer.cs",
    "content": "// <auto-generated />\nusing System;\nusing Microsoft.EntityFrameworkCore;\nusing Microsoft.EntityFrameworkCore.Infrastructure;\nusing Microsoft.EntityFrameworkCore.Metadata;\nusing Microsoft.EntityFrameworkCore.Migrations;\nusing Microsoft.EntityFrameworkCore.Storage.ValueConversion;\nusing MinimalClean.Architecture.Web.Infrastructure.Data;\n\n#nullable disable\n\nnamespace MinimalClean.Architecture.Web.Infrastructure.Data.Migrations\n{\n    [DbContext(typeof(AppDbContext))]\n    [Migration(\"20251024232246_AddGuestUsersAndOrdersSqlServer\")]\n    partial class AddGuestUsersAndOrdersSqlServer\n    {\n        /// <inheritdoc />\n        protected override void BuildTargetModel(ModelBuilder modelBuilder)\n        {\n#pragma warning disable 612, 618\n            modelBuilder\n                .HasAnnotation(\"ProductVersion\", \"9.0.10\")\n                .HasAnnotation(\"Relational:MaxIdentifierLength\", 128);\n\n            SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder);\n\n            modelBuilder.Entity(\"MinimalClean.Architecture.Web.Domain.CartAggregate.Cart\", b =>\n                {\n                    b.Property<Guid>(\"Id\")\n                        .HasColumnType(\"uniqueidentifier\");\n\n                    b.Property<DateTime>(\"CreatedOn\")\n                        .HasColumnType(\"datetime2\");\n\n                    b.Property<bool>(\"Deleted\")\n                        .HasColumnType(\"bit\");\n\n                    b.HasKey(\"Id\");\n\n                    b.ToTable(\"Carts\");\n                });\n\n            modelBuilder.Entity(\"MinimalClean.Architecture.Web.Domain.CartAggregate.CartItem\", b =>\n                {\n                    b.Property<Guid>(\"Id\")\n                        .HasColumnType(\"uniqueidentifier\");\n\n                    b.Property<Guid?>(\"CartId\")\n                        .HasColumnType(\"uniqueidentifier\");\n\n                    b.Property<int>(\"ProductId\")\n                        .HasColumnType(\"int\");\n\n                    b.Property<int>(\"Quantity\")\n                        .HasColumnType(\"int\");\n\n                    b.Property<decimal>(\"UnitPrice\")\n                        .HasPrecision(18, 2)\n                        .HasColumnType(\"decimal(18,2)\");\n\n                    b.HasKey(\"Id\");\n\n                    b.HasIndex(\"CartId\");\n\n                    b.ToTable(\"CartItems\", (string)null);\n                });\n\n            modelBuilder.Entity(\"MinimalClean.Architecture.Web.Domain.GuestUserAggregate.GuestUser\", b =>\n                {\n                    b.Property<Guid>(\"Id\")\n                        .HasColumnType(\"uniqueidentifier\");\n\n                    b.Property<string>(\"Email\")\n                        .IsRequired()\n                        .HasMaxLength(100)\n                        .HasColumnType(\"nvarchar(100)\");\n\n                    b.HasKey(\"Id\");\n\n                    b.ToTable(\"GuestUsers\");\n                });\n\n            modelBuilder.Entity(\"MinimalClean.Architecture.Web.Domain.OrderAggregate.Order\", b =>\n                {\n                    b.Property<Guid>(\"Id\")\n                        .HasColumnType(\"uniqueidentifier\");\n\n                    b.Property<DateTimeOffset>(\"CreatedOn\")\n                        .HasColumnType(\"datetimeoffset\");\n\n                    b.Property<DateTimeOffset?>(\"DatePaid\")\n                        .HasColumnType(\"datetimeoffset\");\n\n                    b.Property<Guid>(\"GuestUserId\")\n                        .HasColumnType(\"uniqueidentifier\");\n\n                    b.Property<string>(\"PaymentReference\")\n                        .HasMaxLength(100)\n                        .HasColumnType(\"nvarchar(100)\");\n\n                    b.HasKey(\"Id\");\n\n                    b.ToTable(\"Orders\");\n                });\n\n            modelBuilder.Entity(\"MinimalClean.Architecture.Web.Domain.OrderAggregate.OrderItem\", b =>\n                {\n                    b.Property<Guid>(\"Id\")\n                        .HasColumnType(\"uniqueidentifier\");\n\n                    b.Property<Guid>(\"OrderId\")\n                        .HasColumnType(\"uniqueidentifier\");\n\n                    b.Property<int>(\"ProductId\")\n                        .HasColumnType(\"int\");\n\n                    b.Property<int>(\"Quantity\")\n                        .HasColumnType(\"int\");\n\n                    b.Property<decimal>(\"UnitPrice\")\n                        .HasPrecision(18, 2)\n                        .HasColumnType(\"decimal(18,2)\");\n\n                    b.HasKey(\"Id\");\n\n                    b.HasIndex(\"OrderId\");\n\n                    b.ToTable(\"OrderItems\", (string)null);\n                });\n\n            modelBuilder.Entity(\"MinimalClean.Architecture.Web.Domain.ProductAggregate.Product\", b =>\n                {\n                    b.Property<int>(\"Id\")\n                        .HasColumnType(\"int\");\n\n                    b.Property<string>(\"Name\")\n                        .IsRequired()\n                        .HasMaxLength(100)\n                        .HasColumnType(\"nvarchar(100)\");\n\n                    b.Property<decimal>(\"UnitPrice\")\n                        .HasPrecision(18, 2)\n                        .HasColumnType(\"decimal(18,2)\");\n\n                    b.HasKey(\"Id\");\n\n                    b.ToTable(\"Products\");\n\n                    b.HasData(\n                        new\n                        {\n                            Id = 1,\n                            Name = \"Coffee Mug\",\n                            UnitPrice = 9.99m\n                        },\n                        new\n                        {\n                            Id = 2,\n                            Name = \"T-Shirt\",\n                            UnitPrice = 19.99m\n                        },\n                        new\n                        {\n                            Id = 3,\n                            Name = \"Sticker Pack\",\n                            UnitPrice = 3.99m\n                        });\n                });\n\n            modelBuilder.Entity(\"MinimalClean.Architecture.Web.Domain.CartAggregate.CartItem\", b =>\n                {\n                    b.HasOne(\"MinimalClean.Architecture.Web.Domain.CartAggregate.Cart\", null)\n                        .WithMany(\"Items\")\n                        .HasForeignKey(\"CartId\");\n                });\n\n            modelBuilder.Entity(\"MinimalClean.Architecture.Web.Domain.OrderAggregate.OrderItem\", b =>\n                {\n                    b.HasOne(\"MinimalClean.Architecture.Web.Domain.OrderAggregate.Order\", null)\n                        .WithMany(\"Items\")\n                        .HasForeignKey(\"OrderId\")\n                        .OnDelete(DeleteBehavior.Cascade)\n                        .IsRequired();\n                });\n\n            modelBuilder.Entity(\"MinimalClean.Architecture.Web.Domain.CartAggregate.Cart\", b =>\n                {\n                    b.Navigation(\"Items\");\n                });\n\n            modelBuilder.Entity(\"MinimalClean.Architecture.Web.Domain.OrderAggregate.Order\", b =>\n                {\n                    b.Navigation(\"Items\");\n                });\n#pragma warning restore 612, 618\n        }\n    }\n}\n"
  },
  {
    "path": "MinimalClean/src/MinimalClean.Architecture.Web/Infrastructure/Data/Migrations/20251024232246_AddGuestUsersAndOrdersSqlServer.cs",
    "content": "using System;\nusing Microsoft.EntityFrameworkCore.Migrations;\n\n#nullable disable\n\nnamespace MinimalClean.Architecture.Web.Infrastructure.Data.Migrations\n{\n    /// <inheritdoc />\n    public partial class AddGuestUsersAndOrdersSqlServer : Migration\n    {\n        /// <inheritdoc />\n        protected override void Up(MigrationBuilder migrationBuilder)\n        {\n            migrationBuilder.CreateTable(\n                name: \"GuestUsers\",\n                columns: table => new\n                {\n                    Id = table.Column<Guid>(type: \"uniqueidentifier\", nullable: false),\n                    Email = table.Column<string>(type: \"nvarchar(100)\", maxLength: 100, nullable: false)\n                },\n                constraints: table =>\n                {\n                    table.PrimaryKey(\"PK_GuestUsers\", x => x.Id);\n                });\n\n            migrationBuilder.CreateTable(\n                name: \"Orders\",\n                columns: table => new\n                {\n                    Id = table.Column<Guid>(type: \"uniqueidentifier\", nullable: false),\n                    CreatedOn = table.Column<DateTimeOffset>(type: \"datetimeoffset\", nullable: false),\n                    GuestUserId = table.Column<Guid>(type: \"uniqueidentifier\", nullable: false),\n                    DatePaid = table.Column<DateTimeOffset>(type: \"datetimeoffset\", nullable: true),\n                    PaymentReference = table.Column<string>(type: \"nvarchar(100)\", maxLength: 100, nullable: true)\n                },\n                constraints: table =>\n                {\n                    table.PrimaryKey(\"PK_Orders\", x => x.Id);\n                });\n\n            migrationBuilder.CreateTable(\n                name: \"OrderItems\",\n                columns: table => new\n                {\n                    Id = table.Column<Guid>(type: \"uniqueidentifier\", nullable: false),\n                    OrderId = table.Column<Guid>(type: \"uniqueidentifier\", nullable: false),\n                    ProductId = table.Column<int>(type: \"int\", nullable: false),\n                    Quantity = table.Column<int>(type: \"int\", nullable: false),\n                    UnitPrice = table.Column<decimal>(type: \"decimal(18,2)\", precision: 18, scale: 2, nullable: false)\n                },\n                constraints: table =>\n                {\n                    table.PrimaryKey(\"PK_OrderItems\", x => x.Id);\n                    table.ForeignKey(\n                        name: \"FK_OrderItems_Orders_OrderId\",\n                        column: x => x.OrderId,\n                        principalTable: \"Orders\",\n                        principalColumn: \"Id\",\n                        onDelete: ReferentialAction.Cascade);\n                });\n\n            migrationBuilder.UpdateData(\n                table: \"Products\",\n                keyColumn: \"Id\",\n                keyValue: 1,\n                columns: new[] { \"Name\", \"UnitPrice\" },\n                values: new object[] { \"Coffee Mug\", 9.99m });\n\n            migrationBuilder.UpdateData(\n                table: \"Products\",\n                keyColumn: \"Id\",\n                keyValue: 2,\n                columns: new[] { \"Name\", \"UnitPrice\" },\n                values: new object[] { \"T-Shirt\", 19.99m });\n\n            migrationBuilder.UpdateData(\n                table: \"Products\",\n                keyColumn: \"Id\",\n                keyValue: 3,\n                columns: new[] { \"Name\", \"UnitPrice\" },\n                values: new object[] { \"Sticker Pack\", 3.99m });\n\n            migrationBuilder.CreateIndex(\n                name: \"IX_OrderItems_OrderId\",\n                table: \"OrderItems\",\n                column: \"OrderId\");\n        }\n\n        /// <inheritdoc />\n        protected override void Down(MigrationBuilder migrationBuilder)\n        {\n            migrationBuilder.DropTable(\n                name: \"GuestUsers\");\n\n            migrationBuilder.DropTable(\n                name: \"OrderItems\");\n\n            migrationBuilder.DropTable(\n                name: \"Orders\");\n\n            migrationBuilder.UpdateData(\n                table: \"Products\",\n                keyColumn: \"Id\",\n                keyValue: 1,\n                columns: new[] { \"Name\", \"UnitPrice\" },\n                values: new object[] { \"Laptop\", 999.99m });\n\n            migrationBuilder.UpdateData(\n                table: \"Products\",\n                keyColumn: \"Id\",\n                keyValue: 2,\n                columns: new[] { \"Name\", \"UnitPrice\" },\n                values: new object[] { \"Smartphone\", 499.99m });\n\n            migrationBuilder.UpdateData(\n                table: \"Products\",\n                keyColumn: \"Id\",\n                keyValue: 3,\n                columns: new[] { \"Name\", \"UnitPrice\" },\n                values: new object[] { \"Tablet\", 299.99m });\n        }\n    }\n}\n"
  },
  {
    "path": "MinimalClean/src/MinimalClean.Architecture.Web/Infrastructure/Data/Migrations/AppDbContextModelSnapshot.cs",
    "content": "// <auto-generated />\nusing System;\nusing Microsoft.EntityFrameworkCore;\nusing Microsoft.EntityFrameworkCore.Infrastructure;\nusing Microsoft.EntityFrameworkCore.Metadata;\nusing Microsoft.EntityFrameworkCore.Storage.ValueConversion;\nusing MinimalClean.Architecture.Web.Infrastructure.Data;\n\n#nullable disable\n\nnamespace MinimalClean.Architecture.Web.Infrastructure.Data.Migrations\n{\n    [DbContext(typeof(AppDbContext))]\n    partial class AppDbContextModelSnapshot : ModelSnapshot\n    {\n        protected override void BuildModel(ModelBuilder modelBuilder)\n        {\n#pragma warning disable 612, 618\n            modelBuilder\n                .HasAnnotation(\"ProductVersion\", \"9.0.10\")\n                .HasAnnotation(\"Relational:MaxIdentifierLength\", 128);\n\n            SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder);\n\n            modelBuilder.Entity(\"MinimalClean.Architecture.Web.Domain.CartAggregate.Cart\", b =>\n                {\n                    b.Property<Guid>(\"Id\")\n                        .HasColumnType(\"uniqueidentifier\");\n\n                    b.Property<DateTime>(\"CreatedOn\")\n                        .HasColumnType(\"datetime2\");\n\n                    b.Property<bool>(\"Deleted\")\n                        .HasColumnType(\"bit\");\n\n                    b.HasKey(\"Id\");\n\n                    b.ToTable(\"Carts\");\n                });\n\n            modelBuilder.Entity(\"MinimalClean.Architecture.Web.Domain.CartAggregate.CartItem\", b =>\n                {\n                    b.Property<Guid>(\"Id\")\n                        .HasColumnType(\"uniqueidentifier\");\n\n                    b.Property<Guid?>(\"CartId\")\n                        .HasColumnType(\"uniqueidentifier\");\n\n                    b.Property<int>(\"ProductId\")\n                        .HasColumnType(\"int\");\n\n                    b.Property<int>(\"Quantity\")\n                        .HasColumnType(\"int\");\n\n                    b.Property<decimal>(\"UnitPrice\")\n                        .HasPrecision(18, 2)\n                        .HasColumnType(\"decimal(18,2)\");\n\n                    b.HasKey(\"Id\");\n\n                    b.HasIndex(\"CartId\");\n\n                    b.ToTable(\"CartItems\", (string)null);\n                });\n\n            modelBuilder.Entity(\"MinimalClean.Architecture.Web.Domain.GuestUserAggregate.GuestUser\", b =>\n                {\n                    b.Property<Guid>(\"Id\")\n                        .HasColumnType(\"uniqueidentifier\");\n\n                    b.Property<string>(\"Email\")\n                        .IsRequired()\n                        .HasMaxLength(100)\n                        .HasColumnType(\"nvarchar(100)\");\n\n                    b.HasKey(\"Id\");\n\n                    b.ToTable(\"GuestUsers\");\n                });\n\n            modelBuilder.Entity(\"MinimalClean.Architecture.Web.Domain.OrderAggregate.Order\", b =>\n                {\n                    b.Property<Guid>(\"Id\")\n                        .HasColumnType(\"uniqueidentifier\");\n\n                    b.Property<DateTimeOffset>(\"CreatedOn\")\n                        .HasColumnType(\"datetimeoffset\");\n\n                    b.Property<DateTimeOffset?>(\"DatePaid\")\n                        .HasColumnType(\"datetimeoffset\");\n\n                    b.Property<Guid>(\"GuestUserId\")\n                        .HasColumnType(\"uniqueidentifier\");\n\n                    b.Property<string>(\"PaymentReference\")\n                        .HasMaxLength(100)\n                        .HasColumnType(\"nvarchar(100)\");\n\n                    b.HasKey(\"Id\");\n\n                    b.ToTable(\"Orders\");\n                });\n\n            modelBuilder.Entity(\"MinimalClean.Architecture.Web.Domain.OrderAggregate.OrderItem\", b =>\n                {\n                    b.Property<Guid>(\"Id\")\n                        .HasColumnType(\"uniqueidentifier\");\n\n                    b.Property<Guid>(\"OrderId\")\n                        .HasColumnType(\"uniqueidentifier\");\n\n                    b.Property<int>(\"ProductId\")\n                        .HasColumnType(\"int\");\n\n                    b.Property<int>(\"Quantity\")\n                        .HasColumnType(\"int\");\n\n                    b.Property<decimal>(\"UnitPrice\")\n                        .HasPrecision(18, 2)\n                        .HasColumnType(\"decimal(18,2)\");\n\n                    b.HasKey(\"Id\");\n\n                    b.HasIndex(\"OrderId\");\n\n                    b.ToTable(\"OrderItems\", (string)null);\n                });\n\n            modelBuilder.Entity(\"MinimalClean.Architecture.Web.Domain.ProductAggregate.Product\", b =>\n                {\n                    b.Property<int>(\"Id\")\n                        .HasColumnType(\"int\");\n\n                    b.Property<string>(\"Name\")\n                        .IsRequired()\n                        .HasMaxLength(100)\n                        .HasColumnType(\"nvarchar(100)\");\n\n                    b.Property<decimal>(\"UnitPrice\")\n                        .HasPrecision(18, 2)\n                        .HasColumnType(\"decimal(18,2)\");\n\n                    b.HasKey(\"Id\");\n\n                    b.ToTable(\"Products\");\n\n                    b.HasData(\n                        new\n                        {\n                            Id = 1,\n                            Name = \"Coffee Mug\",\n                            UnitPrice = 9.99m\n                        },\n                        new\n                        {\n                            Id = 2,\n                            Name = \"T-Shirt\",\n                            UnitPrice = 19.99m\n                        },\n                        new\n                        {\n                            Id = 3,\n                            Name = \"Sticker Pack\",\n                            UnitPrice = 3.99m\n                        });\n                });\n\n            modelBuilder.Entity(\"MinimalClean.Architecture.Web.Domain.CartAggregate.CartItem\", b =>\n                {\n                    b.HasOne(\"MinimalClean.Architecture.Web.Domain.CartAggregate.Cart\", null)\n                        .WithMany(\"Items\")\n                        .HasForeignKey(\"CartId\");\n                });\n\n            modelBuilder.Entity(\"MinimalClean.Architecture.Web.Domain.OrderAggregate.OrderItem\", b =>\n                {\n                    b.HasOne(\"MinimalClean.Architecture.Web.Domain.OrderAggregate.Order\", null)\n                        .WithMany(\"Items\")\n                        .HasForeignKey(\"OrderId\")\n                        .OnDelete(DeleteBehavior.Cascade)\n                        .IsRequired();\n                });\n\n            modelBuilder.Entity(\"MinimalClean.Architecture.Web.Domain.CartAggregate.Cart\", b =>\n                {\n                    b.Navigation(\"Items\");\n                });\n\n            modelBuilder.Entity(\"MinimalClean.Architecture.Web.Domain.OrderAggregate.Order\", b =>\n                {\n                    b.Navigation(\"Items\");\n                });\n#pragma warning restore 612, 618\n        }\n    }\n}\n"
  },
  {
    "path": "MinimalClean/src/MinimalClean.Architecture.Web/Infrastructure/Data/Queries/ListProductsQueryService.cs",
    "content": "﻿using Microsoft.EntityFrameworkCore;\nusing MinimalClean.Architecture.Web.ProductFeatures;\nusing MinimalClean.Architecture.Web.ProductFeatures.List;\n\nnamespace MinimalClean.Architecture.Web.Infrastructure.Data.Queries;\n\npublic class ListProductsQueryService(AppDbContext db) : IListProductsQueryService\n{\n  private readonly AppDbContext _db = db;\n\n    public async Task<PagedResult<ProductDto>> ListAsync(int page, int perPage)\n  {\n    var items = await _db.Products\n      .OrderBy(p => p.Id)\n      .Skip((page - 1) * perPage)\n      .Take(perPage)\n      .Select(p => new ProductDto(p.Id, p.Name, p.UnitPrice))\n      .AsNoTracking()\n      .ToListAsync();\n\n    int totalCount = await _db.Products.CountAsync();\n    int totalPages = (int)Math.Ceiling(totalCount / (double)perPage);\n    var result = new PagedResult<ProductDto>(items, page, perPage, totalCount, totalPages);\n\n    return result;\n  }\n}\n"
  },
  {
    "path": "MinimalClean/src/MinimalClean.Architecture.Web/Infrastructure/Data/SeedData.cs",
    "content": "using Microsoft.EntityFrameworkCore;\nusing MinimalClean.Architecture.Web.Domain.ProductAggregate;\nusing Microsoft.Extensions.Logging;\n\nnamespace MinimalClean.Architecture.Web.Infrastructure.Data;\n\npublic static class SeedData\n{\n  public const int NUMBER_OF_PRODUCTS = 10;\n\n  public static async Task InitializeAsync(AppDbContext dbContext, ILogger logger)\n  {\n    if (await dbContext.Products.AnyAsync())\n    {\n      logger.LogInformation(\"DB has data - seeding not required.\");\n      return; // DB has been seeded\n    }\n    await PopulateTestDataAsync(dbContext, logger);\n  }\n\n  public static async Task PopulateTestDataAsync(AppDbContext dbContext, ILogger logger)\n  {\n    logger.LogInformation(\"Seeding database with sample data.\");\n\n    // add more products to support demonstrating paging\n    for (int i = 1; i <= NUMBER_OF_PRODUCTS; i++)\n    {\n      dbContext.Products.Add(new Product(ProductId.From(i), $\"Product {i}\", 10m + i));\n    }\n    await dbContext.SaveChangesAsync();\n  }\n}\n"
  },
  {
    "path": "MinimalClean/src/MinimalClean.Architecture.Web/Infrastructure/Email/FakeEmailSender.cs",
    "content": "using MinimalClean.Architecture.Web.Domain.Interfaces;\n\nnamespace MinimalClean.Architecture.Web.Infrastructure.Email;\n\npublic class FakeEmailSender(ILogger<FakeEmailSender> logger) : IEmailSender\n{\n  private readonly ILogger<FakeEmailSender> _logger = logger;\n  public Task SendEmailAsync(string to, string from, string subject, string body)\n  {\n    _logger.LogInformation(\"Not actually sending an email to {to} from {from} with subject {subject}\", to, from, subject);\n    return Task.CompletedTask;\n  }\n}\n"
  },
  {
    "path": "MinimalClean/src/MinimalClean.Architecture.Web/Infrastructure/Email/MailserverConfiguration.cs",
    "content": "namespace MinimalClean.Architecture.Web.Infrastructure.Email;\n\npublic class MailserverConfiguration()\n{\n  public string Hostname { get; set; } = \"localhost\";\n  public int Port { get; set; } = 25;\n}\n"
  },
  {
    "path": "MinimalClean/src/MinimalClean.Architecture.Web/Infrastructure/Email/MimeKitEmailSender.cs",
    "content": "using Microsoft.Extensions.Options;\nusing MimeKit;\nusing MinimalClean.Architecture.Web.Domain.Interfaces;\n\nnamespace MinimalClean.Architecture.Web.Infrastructure.Email;\n\npublic class MimeKitEmailSender(ILogger<MimeKitEmailSender> logger,\n  IOptions<MailserverConfiguration> mailserverOptions) : IEmailSender\n{\n  private readonly ILogger<MimeKitEmailSender> _logger = logger;\n  private readonly MailserverConfiguration _mailserverConfiguration = mailserverOptions.Value!;\n\n  public async Task SendEmailAsync(string to, string from, string subject, string body)\n  {\n    _logger.LogWarning(\"Sending email to {to} from {from} with subject {subject} using {type}.\", to, from, subject, this.ToString());\n\n    using var client = new MailKit.Net.Smtp.SmtpClient(); \n    await client.ConnectAsync(_mailserverConfiguration.Hostname, \n      _mailserverConfiguration.Port, false);\n    var message = new MimeMessage();\n    message.From.Add(new MailboxAddress(from, from));\n    message.To.Add(new MailboxAddress(to, to));\n    message.Subject = subject;\n    message.Body = new TextPart(\"plain\") { Text = body };\n\n    await client.SendAsync(message);\n\n    await client.DisconnectAsync(true, \n      new CancellationToken(canceled: true));\n  }\n}\n"
  },
  {
    "path": "MinimalClean/src/MinimalClean.Architecture.Web/Infrastructure/InfrastructureServiceExtensions.cs",
    "content": "using Ardalis.GuardClauses;\nusing MinimalClean.Architecture.Web.Infrastructure.Data;\nusing MinimalClean.Architecture.Web.Infrastructure.Data.Queries;\nusing MinimalClean.Architecture.Web.ProductFeatures.List;\nusing Microsoft.EntityFrameworkCore;\n\nnamespace MinimalClean.Architecture.Web.Infrastructure;\npublic static class InfrastructureServiceExtensions\n{\n  public static IServiceCollection AddInfrastructureServices(\n    this IServiceCollection services,\n    ConfigurationManager config,\n    ILogger logger)\n  {\n    // Always use SQL Server from Aspire\n    string? connectionString = config.GetConnectionString(\"AppDb\");\n    Guard.Against.Null(connectionString, \"AppDb connection string is required. Make sure the application is running with Aspire.\");\n\n    services.AddScoped<EventDispatchInterceptor>();\n    services.AddScoped<IDomainEventDispatcher, MediatorDomainEventDispatcher>();\n\n    services.AddDbContext<AppDbContext>((provider, options) =>\n    {\n      var eventDispatchInterceptor = provider.GetRequiredService<EventDispatchInterceptor>();\n      \n      options.UseSqlServer(connectionString);\n      options.AddInterceptors(eventDispatchInterceptor);\n    });\n\n    services.AddScoped(typeof(IRepository<>), typeof(EfRepository<>))\n           .AddScoped(typeof(IReadRepository<>), typeof(EfRepository<>))\n           .AddScoped<IListProductsQueryService, ListProductsQueryService>();\n\n    logger.LogInformation(\"{Project} services registered\", \"Infrastructure\");\n\n    return services;\n  }\n}\n"
  },
  {
    "path": "MinimalClean/src/MinimalClean.Architecture.Web/MinimalClean.Architecture.Web.csproj",
    "content": "﻿<Project Sdk=\"Microsoft.NET.Sdk.Web\">\n  <Sdk Name=\"Microsoft.Build.CentralPackageVersions\" Version=\"2.1.3\" />\n\n  <PropertyGroup>\n    <PreserveCompilationContext>true</PreserveCompilationContext>\n    <OutputType>Exe</OutputType>\n    <WebProjectMode>true</WebProjectMode>\n    <GenerateDocumentationFile>True</GenerateDocumentationFile>\n    <RootNamespace>MinimalClean.Architecture.Web</RootNamespace>\n    <WarningsAsErrors>NSDEPCOP01</WarningsAsErrors>\n  </PropertyGroup>\n\n  <ItemGroup>\n    <PackageReference Include=\"Ardalis.GuardClauses\" />\n    <PackageReference Include=\"Ardalis.Result\" />\n    <PackageReference Include=\"Ardalis.ListStartupServices\" />\n    <PackageReference Include=\"Ardalis.Result.AspNetCore\" />\n    <PackageReference Include=\"Ardalis.SharedKernel\" />\n    <PackageReference Include=\"Ardalis.SmartEnum\" />\n    <PackageReference Include=\"Ardalis.Specification\" />\n    <PackageReference Include=\"Ardalis.Specification.EntityFrameworkCore\" />\n    <PackageReference Include=\"Azure.Identity\" />\n\n    <PackageReference Include=\"FastEndpoints\" />\n    <PackageReference Include=\"FastEndpoints.Swagger\" />\n    <PackageReference Include=\"Mediator.Abstractions\" />\n    <PackageReference Include=\"Mediator.SourceGenerator\">\n      <PrivateAssets>all</PrivateAssets>\n      <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>\n    </PackageReference>\n    \n    <PackageReference Include=\"MailKit\" />\n    <PackageReference Include=\"MimeKit\" />\n    <PackageReference Include=\"NimblePros.Metronome\" />\n    <PackageReference Include=\"Scalar.AspNetCore\" />\n    <PackageReference Include=\"Serilog.AspNetCore\" />\n    <PackageReference Include=\"Serilog.Sinks.OpenTelemetry\" />\n\n    <PackageReference Include=\"Vogen\">\n      <IncludeAssets>compile; runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>\n    </PackageReference>\n\n    <PackageReference Include=\"Microsoft.EntityFrameworkCore.Relational\" />\n    <PackageReference Include=\"Microsoft.EntityFrameworkCore.SqlServer\" />\n    <PackageReference Include=\"Microsoft.EntityFrameworkCore.Design\" PrivateAssets=\"all\">\n      <IncludeAssets>runtime; build; native; analyzers; buildtransitive</IncludeAssets>\n    </PackageReference>\n\n    <PackageReference Include=\"NsDepCop\">\n      <PrivateAssets>all</PrivateAssets>\n      <IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>\n    </PackageReference>\n  </ItemGroup>\n\n  <ItemGroup>\n    <ProjectReference Include=\"..\\MinimalClean.Architecture.ServiceDefaults\\MinimalClean.Architecture.ServiceDefaults.csproj\" />\n  </ItemGroup>\n\n</Project>\n"
  },
  {
    "path": "MinimalClean/src/MinimalClean.Architecture.Web/PagedResult.cs",
    "content": "namespace MinimalClean.Architecture.Web;\n\npublic record PagedResult<T>(\n  IReadOnlyList<T> Items,\n  int Page,\n  int PerPage,\n  int TotalCount,\n  int TotalPages);\n"
  },
  {
    "path": "MinimalClean/src/MinimalClean.Architecture.Web/ProductFeatures/Create/CreateEndpoint.cs",
    "content": "using FastEndpoints;\nusing FluentValidation;\nusing Microsoft.AspNetCore.Http.HttpResults;\nusing MinimalClean.Architecture.Web.Domain.ProductAggregate;\nusing MinimalClean.Architecture.Web.ProductFeatures;\n\nnamespace MinimalClean.Architecture.Web.ProductFeatures.Create;\n\npublic sealed class CreateProductRequest\n{ \n  public string Name { get; init; } = string.Empty;\n  public decimal UnitPrice { get; init; }\n}\n\npublic class CreateEndpoint(IRepository<Product> repository) : \n  Endpoint<CreateProductRequest, \n           Results<Created<ProductRecord>, ValidationProblem, ProblemHttpResult>>\n{\n  private readonly IRepository<Product> _repository = repository;\n\n  public override void Configure()\n  {\n    Post(\"/Products\");\n    AllowAnonymous();\n\n    Summary(s =>\n    {\n      s.Summary = \"Create a new product\";\n      s.Description = \"Creates a new product with the specified name and unit price.\";\n      s.ExampleRequest = new CreateProductRequest { Name = \"Sample Product\", UnitPrice = 19.99m };\n      s.ResponseExamples[201] = new ProductRecord(1, \"Sample Product\", 19.99m);\n\n      s.Responses[201] = \"Product created successfully\";\n      s.Responses[400] = \"Invalid request data\";\n    });\n\n    Tags(\"Products\");\n\n    Description(builder => builder\n      .Accepts<CreateProductRequest>()\n      .Produces<ProductRecord>(201, \"application/json\")\n      .ProducesProblem(400));\n  }\n\n  public override async Task<Results<Created<ProductRecord>, ValidationProblem, ProblemHttpResult>> \n    ExecuteAsync(CreateProductRequest request, CancellationToken cancellationToken)\n  {\n    var product = Product.Create(request.Name, request.UnitPrice);\n\n    await _repository.AddAsync(product, cancellationToken);\n    await _repository.SaveChangesAsync(cancellationToken);\n\n    var response = new ProductRecord(product.Id.Value, product.Name, product.UnitPrice);\n    return TypedResults.Created($\"/Products/{product.Id.Value}\", response);\n  }\n}\n\npublic sealed class CreateProductValidator : Validator<CreateProductRequest>\n{\n  public CreateProductValidator()\n  {\n    RuleFor(x => x.Name)\n      .NotEmpty()\n      .WithMessage(\"Product name is required\")\n      .MaximumLength(200)\n      .WithMessage(\"Product name must not exceed 200 characters\");\n\n    RuleFor(x => x.UnitPrice)\n      .GreaterThan(0)\n      .WithMessage(\"Unit price must be greater than zero\");\n  }\n}\n"
  },
  {
    "path": "MinimalClean/src/MinimalClean.Architecture.Web/ProductFeatures/GetById/GetByIdEndpoint.cs",
    "content": "﻿using FastEndpoints;\nusing FluentValidation;\nusing Microsoft.AspNetCore.Http.HttpResults;\nusing MinimalClean.Architecture.Web.Domain.ProductAggregate;\nusing MinimalClean.Architecture.Web.Extensions;\n\nnamespace MinimalClean.Architecture.Web.ProductFeatures.GetById;\n\npublic sealed class GetProductByIdRequest\n{\n  public const string Route = \"/Products/{ProductId}\";\n  public int ProductId { get; init; }\n}\n\npublic class GetByIdEndpoint(IMediator mediator)\n  : Endpoint<GetProductByIdRequest,\n             Results<Ok<ProductRecord>,\n                     NotFound,\n                     ProblemHttpResult>,\n             GetProductByIdMapper>\n{\n  public override void Configure()\n  {\n    Get(GetProductByIdRequest.Route);\n    AllowAnonymous();\n\n    Summary(s =>\n    {\n      s.Summary = \"Get a product by ID\";\n      s.Description = \"Retrieves a specific product by its unique identifier. Returns detailed product information including ID, name, and unit price.\";\n      s.ExampleRequest = new GetProductByIdRequest { ProductId = 1 };\n      s.ResponseExamples[200] = new ProductRecord(1, \"Laptop\", 999.99m);\n\n      // Document possible responses\n      s.Responses[200] = \"Product found and returned successfully\";\n      s.Responses[404] = \"Product with specified ID not found\";\n    });\n\n    // Add tags for API grouping\n    Tags(\"Products\");\n\n    // Add additional metadata\n    Description(builder => builder\n      .Accepts<GetProductByIdRequest>()\n      .Produces<ProductRecord>(200, \"application/json\")\n      .ProducesProblem(404));\n  }\n\n  public override async Task<Results<Ok<ProductRecord>, NotFound, ProblemHttpResult>>\n    ExecuteAsync(GetProductByIdRequest request, CancellationToken ct)\n  {\n    var result = await mediator.Send(new GetProductQuery(ProductId.From(request.ProductId)), ct);\n\n    return result.ToGetByIdResult(Map.FromEntity);\n  }\n}\n\npublic sealed class GetProductByIdValidator : Validator<GetProductByIdRequest>\n{\n  public GetProductByIdValidator()\n  {\n    RuleFor(x => x.ProductId)\n      .GreaterThan(0)\n      .WithMessage(\"Product ID must be greater than 0\");\n  }\n}\n\n\npublic sealed class GetProductByIdMapper\n  : Mapper<GetProductByIdRequest, ProductRecord, ProductDto>\n{\n  public override ProductRecord FromEntity(ProductDto e)\n    => new(e.Id.Value, e.Name, e.UnitPrice);\n}\n"
  },
  {
    "path": "MinimalClean/src/MinimalClean.Architecture.Web/ProductFeatures/GetById/GetProductHandler.cs",
    "content": "using MinimalClean.Architecture.Web.Domain.ProductAggregate;\nusing MinimalClean.Architecture.Web.Domain.ProductAggregate.Specifications;\n\nnamespace MinimalClean.Architecture.Web.ProductFeatures.GetById;\n\npublic record GetProductQuery(ProductId ProductId) : IQuery<Result<ProductDto>>;\n\npublic class GetProductHandler(IReadRepository<Product> _repository)\n  : IQueryHandler<GetProductQuery, Result<ProductDto>>\n{\n  public async ValueTask<Result<ProductDto>> Handle(GetProductQuery request, CancellationToken cancellationToken)\n  {\n    var spec = new ProductByIdSpec(request.ProductId);\n    var entity = await _repository.FirstOrDefaultAsync(spec, cancellationToken);\n    if (entity == null) return Result.NotFound();\n\n    return new ProductDto(entity.Id, entity.Name, entity.UnitPrice);\n  }\n}\n"
  },
  {
    "path": "MinimalClean/src/MinimalClean.Architecture.Web/ProductFeatures/List/IListProductsQueryService.cs",
    "content": "namespace MinimalClean.Architecture.Web.ProductFeatures.List;\n\n/// <summary>\n/// Represents a service that will actually fetch the necessary data\n/// Typically implemented in Infrastructure\n/// </summary>\npublic interface IListProductsQueryService\n{\n  Task<PagedResult<ProductDto>> ListAsync(int page, int perPage);\n}\n"
  },
  {
    "path": "MinimalClean/src/MinimalClean.Architecture.Web/ProductFeatures/List/ListEndpoint.cs",
    "content": "using FastEndpoints;\nusing FluentValidation;\nusing MinimalClean.Architecture.Web.ProductFeatures;\n\nnamespace MinimalClean.Architecture.Web.ProductFeatures.List;\n\npublic sealed class ListProductsRequest\n{\n  [BindFrom(\"page\")]\n  public int Page { get; init; } = 1;\n\n  [BindFrom(\"per_page\")]\n  public int PerPage { get; init; } = Constants.DEFAULT_PAGE_SIZE;\n}\n\npublic record ProductListResponse : PagedResult<ProductRecord>\n{\n  public ProductListResponse(IReadOnlyList<ProductRecord> Items, int Page, int PerPage, int TotalCount, int TotalPages)\n    : base(Items, Page, PerPage, TotalCount, TotalPages)\n  {\n  }\n}\n\n\npublic class ListEndpoint(IMediator mediator) : Endpoint<ListProductsRequest, ProductListResponse, ListProductsMapper>\n{\n  private readonly IMediator _mediator = mediator;\n\n  public override void Configure()\n  {\n    Get(\"/Products\");\n    AllowAnonymous();\n\n    Summary(s =>\n    {\n      s.Summary = \"List products with pagination\";\n      s.Description = \"Retrieves a paginated list of all products. Supports GitHub-style pagination with 1-based page indexing and configurable page size.\";\n      s.ExampleRequest = new ListProductsRequest { Page = 1, PerPage = 10 };\n      s.ResponseExamples[200] = new ProductListResponse(\n        new List<ProductRecord>\n        {\n          new(1, \"Sample Product 1\", 9.99m),\n          new(2, \"Sample Product 2\", 19.99m)\n        },\n        1, 10, 2, 1);\n\n      s.Params[\"page\"] = \"1-based page index (default 1)\";\n      s.Params[\"per_page\"] = $\"Page size 1–{Constants.MAX_PAGE_SIZE} (default {Constants.DEFAULT_PAGE_SIZE})\";\n\n      s.Responses[200] = \"Paginated list of products returned successfully\";\n      s.Responses[400] = \"Invalid pagination parameters\";\n    });\n\n    Tags(\"Products\");\n\n    Description(builder => builder\n      .Accepts<ListProductsRequest>()\n      .Produces<ProductListResponse>(200, \"application/json\")\n      .ProducesProblem(400));\n  }\n\n  public override async Task HandleAsync(ListProductsRequest request, CancellationToken cancellationToken)\n  {\n    var result = await _mediator.Send(new ListProductsQuery(request.Page, request.PerPage));\n    if (!result.IsSuccess)\n    {\n      await Send.ErrorsAsync(statusCode: 400, cancellationToken);\n      return;\n    }\n\n    var pagedResult = result.Value;\n    AddLinkHeader(pagedResult.Page, pagedResult.PerPage, pagedResult.TotalPages);\n\n    var response = Map.FromEntity(pagedResult);\n    await Send.OkAsync(response, cancellationToken);\n  }\n\n  private void AddLinkHeader(int page, int perPage, int totalPages)\n  {\n    var baseUrl = $\"{HttpContext.Request.Scheme}://{HttpContext.Request.Host}{HttpContext.Request.Path}\";\n    string Link(string rel, int p) => $\"<{baseUrl}?page={p}&per_page={perPage}>; rel=\\\"{rel}\\\"\";\n\n    var parts = new List<string>();\n    if (page > 1)\n    {\n      parts.Add(Link(\"first\", 1));\n      parts.Add(Link(\"prev\", page - 1));\n    }\n    if (page < totalPages)\n    {\n      parts.Add(Link(\"next\", page + 1));\n      parts.Add(Link(\"last\", totalPages));\n    }\n\n    if (parts.Count > 0)\n      HttpContext.Response.Headers[\"Link\"] = string.Join(\", \", parts);\n  }\n}\n\npublic sealed class ListProductsValidator : Validator<ListProductsRequest>\n{\n  public ListProductsValidator()\n  {\n    RuleFor(x => x.Page)\n      .GreaterThanOrEqualTo(1)\n      .WithMessage(\"page must be >= 1\");\n\n    RuleFor(x => x.PerPage)\n      .InclusiveBetween(1, Constants.MAX_PAGE_SIZE)\n      .WithMessage($\"per_page must be between 1 and {Constants.MAX_PAGE_SIZE}\");\n  }\n}\n\npublic sealed class ListProductsMapper\n  : Mapper<ListProductsRequest, ProductListResponse, PagedResult<ProductDto>>\n{\n  public override ProductListResponse FromEntity(PagedResult<ProductDto> e)\n  {\n    var items = e.Items\n      .Select(p => new ProductRecord(p.Id.Value, p.Name, p.UnitPrice))\n      .ToList();\n\n    return new ProductListResponse(items, e.Page, e.PerPage, e.TotalCount, e.TotalPages);\n  }\n}\n"
  },
  {
    "path": "MinimalClean/src/MinimalClean.Architecture.Web/ProductFeatures/List/ListProductsHandler.cs",
    "content": "﻿namespace MinimalClean.Architecture.Web.ProductFeatures.List;\n\npublic record ListProductsQuery(int? Page = 1,\n  int? PerPage = Constants.DEFAULT_PAGE_SIZE)\n  : IQuery<Result<PagedResult<ProductDto>>>;\n\npublic class ListProductsHandler(IListProductsQueryService query) : IQueryHandler<ListProductsQuery, Result<PagedResult<ProductDto>>>\n{\n  private readonly IListProductsQueryService _query = query;\n\n  public async ValueTask<Result<PagedResult<ProductDto>>> Handle(ListProductsQuery request,\n                                                               CancellationToken cancellationToken)\n  {\n\n    var result = await _query.ListAsync(request.Page ?? 1, request.PerPage ?? Constants.DEFAULT_PAGE_SIZE);\n\n    return Result.Success(result);\n  }\n}\n"
  },
  {
    "path": "MinimalClean/src/MinimalClean.Architecture.Web/ProductFeatures/ProductDto.cs",
    "content": "using MinimalClean.Architecture.Web.Domain.ProductAggregate;\n\nnamespace MinimalClean.Architecture.Web.ProductFeatures;\npublic record ProductDto(ProductId Id, string Name, decimal UnitPrice);\n"
  },
  {
    "path": "MinimalClean/src/MinimalClean.Architecture.Web/ProductFeatures/ProductRecord.cs",
    "content": "namespace MinimalClean.Architecture.Web.ProductFeatures;\n\npublic record ProductRecord(int Id, string Name, decimal UnitPrice);\n"
  },
  {
    "path": "MinimalClean/src/MinimalClean.Architecture.Web/Program.cs",
    "content": "﻿using FastEndpoints;\nusing FastEndpoints.Swagger;\nusing MinimalClean.Architecture.Web.Configurations;\nusing Serilog;\n\nvar builder = WebApplication.CreateBuilder(args);\n\nbuilder.AddServiceDefaults()    // This sets up OpenTelemetry logging\n       .AddLoggerConfigs();     // This adds Serilog for console formatting\n\nusing var loggerFactory = LoggerFactory.Create(config => config.AddConsole());\nvar startupLogger = loggerFactory.CreateLogger<Program>();\n\nstartupLogger.LogInformation(\"Starting web host\");\n\nbuilder.Services.AddOptionConfigs(builder.Configuration, startupLogger, builder);\nbuilder.Services.AddServiceConfigs(startupLogger, builder);\n\nbuilder.Services.AddFastEndpoints()\n                .SwaggerDocument(o =>\n                {\n                  o.ShortSchemaNames = true;\n                });\n\nvar app = builder.Build();\n\nawait app.UseAppMiddlewareAndSeedDatabase();\n\napp.MapDefaultEndpoints(); // Aspire health checks and metrics\n\napp.Run();\n\n// Make the implicit Program.cs class public, so integration tests can reference the correct assembly for host building\npublic partial class Program { }\n"
  },
  {
    "path": "MinimalClean/src/MinimalClean.Architecture.Web/Properties/launchSettings.json",
    "content": "{\n  \"profiles\": {\n    \"https\": {\n      \"commandName\": \"Project\",\n      \"dotnetRunMessages\": true,\n      \"launchUrl\": \"scalar\",\n      \"environmentVariables\": {\n        \"ASPNETCORE_ENVIRONMENT\": \"Development\"\n      },\n      \"applicationUrl\": \"https://localhost:57379/\"\n    }\n  }\n}"
  },
  {
    "path": "MinimalClean/src/MinimalClean.Architecture.Web/api.http",
    "content": "@MinimalClean_HostAddress = https://localhost:57379\n\n@MinimalClean_CartId = 68fe4cfd-84bb-4b8a-bb4e-528c26325c72\n\n### List Products\nGET {{MinimalClean_HostAddress}}/products\nAccept: application/json\n\n### Get Product By ID\nGET {{MinimalClean_HostAddress}}/products/1\nAccept: application/json\n\n### Create Product\nPOST {{MinimalClean_HostAddress}}/products\nContent-Type: application/json\n\n{\n  \"name\": \"New Product\",\n  \"unitPrice\": 29.99\n}\n\n### Add to Cart (Anonymous User - creates cart)\nPOST {{MinimalClean_HostAddress}}/cart\nContent-Type: application/json\n\n{\n  \"productId\": 1,\n  \"quantity\": 2\n}\n\n### Add to Cart (Anonymous User - existing cart)\nPOST {{MinimalClean_HostAddress}}/cart\nContent-Type: application/json\n\n{\n  \"cartId\": \"{{MinimalClean_CartId}}\",\n  \"productId\": 2,\n  \"quantity\": 3\n}\n\n### View Cart\nGET {{MinimalClean_HostAddress}}/cart/{{MinimalClean_CartId}}\nAccept: application/json\n\n### Checkout\nPOST {{MinimalClean_HostAddress}}/cart/{{MinimalClean_CartId}}/checkout\nContent-Type: application/json\n\n{\n  \"email\": \"guest@example.com\"\n}\n### Note: Get order ID from response for future use\n\n\n\n\n"
  },
  {
    "path": "MinimalClean/src/MinimalClean.Architecture.Web/appsettings.Development.json",
    "content": "{\n  \"DatabaseOptions\": {\n    \"RecreateOnStartup\": true\n  },\n  \"Logging\": {\n    \"LogLevel\": {\n      \"Default\": \"Information\",\n      \"Microsoft.AspNetCore\": \"Warning\",\n      \"Microsoft.EntityFrameworkCore\": \"Information\"\n    }\n  }\n}\n"
  },
  {
    "path": "MinimalClean/src/MinimalClean.Architecture.Web/appsettings.json",
    "content": "﻿{\n  \"ConnectionStrings\": {\n    \"AppDb\": \"Server=(localdb)\\\\mssqllocaldb;Database=MinimalCleanArchitecture;Trusted_Connection=True;MultipleActiveResultSets=true\"\n  },\n  \"Serilog\": {\n    \"MinimumLevel\": {\n      \"Default\": \"Information\",\n      \"Override\": {\n        \"Microsoft\": \"Warning\",\n        \"Microsoft.Hosting.Lifetime\": \"Information\",\n        \"Microsoft.AspNetCore\": \"Warning\",\n        \"System\": \"Warning\"\n      }\n    },\n    \"Enrich\": [\"FromLogContext\", \"WithMachineName\", \"WithThreadId\"],\n    \"WriteTo\": [\n      {\n        \"Name\": \"Console\",\n        \"Args\": {\n          \"outputTemplate\": \"[{Timestamp:HH:mm:ss} {Level:u3}] {Message:lj} {Properties:j}{NewLine}{Exception}\"\n        }\n      }\n    ]\n  },\n  \"Mailserver\": {\n    \"Server\": \"localhost\",\n    \"Port\": 25\n  }\n}\n"
  },
  {
    "path": "MinimalClean/src/MinimalClean.Architecture.Web/config.nsdepcop",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<NsDepCopConfig>\n    <Allowed From=\"*\" To=\"*\" />\n\n    <Disallowed From=\"MinimalClean.Architecture.Web.Domain.*\"\n\t\t\t\tTo=\"MinimalClean.Architecture.Web.Infrastructure.*\" />\n    \n    <Disallowed From=\"MinimalClean.Architecture.Web.CartFeatures.*\"\n\t\t\t\tTo=\"MinimalClean.Architecture.Web.Infrastructure.*\" />\n    \n    <Disallowed From=\"MinimalClean.Architecture.Web.ProductFeatures.*\"\n\t\t\t\tTo=\"MinimalClean.Architecture.Web.Infrastructure.*\" />\n    \n    <Disallowed From=\"MinimalClean.Architecture.Web.Domain.OrderAggregate.*\"\n\t\t\t\tTo=\"MinimalClean.Architecture.Web.Domain.CartAggregate.*\" />\n\n    <AnalyzerConfig>\n        <IssueKind Name=\"IllegalDependency\" Severity=\"Error\" />\n    </AnalyzerConfig>\n</NsDepCopConfig>\n"
  },
  {
    "path": "MinimalClean/src/MinimalClean.Architecture.Web/wwwroot/.gitkeep",
    "content": ""
  },
  {
    "path": "MinimalClean.nuspec",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<package xmlns=\"http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd\">\n  <metadata>\n    <id>Ardalis.MinimalClean.Template</id>\n    <title>ASP.NET Minimal Clean Architecture Solution</title>\n    <version>1.0.1</version>\n    <authors>Steve Smith</authors>\n    <description>\n      A simplified Clean Architecture template using vertical slice architecture in a single project. \n      Perfect for MVPs, smaller applications, or teams wanting architectural guidance without multi-project complexity.\n      Features Domain-Driven Design patterns, FastEndpoints, Entity Framework Core, and optional Aspire support.\n      Built with .NET 10 and C#.\n    </description>\n    <language>en-US</language>\n    <license type=\"expression\">MIT</license>\n    <projectUrl>https://github.com/ardalis/CleanArchitecture</projectUrl>\n    <releaseNotes>\n      * Initial release of Minimal Clean Architecture template\n      * Single-project vertical slice architecture\n      * Built with .NET 10 and C#.\n      * FastEndpoints for REPR pattern\n      * Pragmatic DDD with simplified patterns\n      * Aspire support\n      * 1.0.1 fixes a minor bug\n    </releaseNotes>\n    <packageTypes>\n      <packageType name=\"Template\" />\n    </packageTypes>\n    <tags>Web ASP.NET \"Clean Architecture\" \"Vertical Slice\" minimal ddd domain-driven-design clean-architecture ardalis FastEndpoints</tags>\n    <icon>./content/icon.png</icon>\n    <readme>README.md</readme>\n  </metadata>\n  <files>\n    <file src=\"MinimalClean\\**\" target=\"content\" exclude=\"**\\bin\\**;**\\obj\\**;**\\.git\\**;**\\.vs\\**;**\\.vscode\\**;**\\*.user\" />\n    <file src=\"README.md\" />\n    <file src=\"icon.png\" target=\"content\" />\n  </files>\n</package>\n"
  },
  {
    "path": "PARALLEL_TEST_EXECUTION.md",
    "content": "# Parallel Test Execution Configuration\n\nThis workspace is configured to run all three test projects in parallel in Visual Studio Test Explorer.\n\n## Configuration Files\n\n### `.runsettings` (Solution Root)\n- Enables parallel test execution at the assembly level\n- `MaxCpuCount=0` uses all available processors to run test assemblies in parallel\n- `DisableParallelization=false` ensures parallelization is enabled\n\n### `xunit.runner.json` (In Each Test Project)\nEach test project contains an `xunit.runner.json` file with:\n- `parallelizeAssembly: true` - Allows tests from this assembly to run in parallel with other assemblies\n- `parallelizeTestCollections: true` - Runs test collections within the assembly in parallel\n- `maxParallelThreads: 0` - Uses xUnit's default algorithm (processors  2)\n\n## How to Use in Visual Studio\n\n### Option 1: Configure via Test Explorer Settings\n1. Open **Test Explorer** (Test ? Test Explorer)\n2. Click the settings icon (??) in the toolbar\n3. Select **Configure Run Settings** ? **Select Solution Wide runsettings File**\n4. Browse to and select the `.runsettings` file at the solution root\n\n### Option 2: Configure via Visual Studio Settings\n1. Go to **Tools** ? **Options**\n2. Navigate to **Test** ? **General**\n3. Under **Run Settings File**, browse and select the `.runsettings` file\n\n### Option 3: Automatic Detection\nVisual Studio will automatically detect and use `.runsettings` in the solution root in most cases.\n\n## Verification\n\nAfter configuration, when you run all tests:\n- The three test projects (UnitTests, IntegrationTests, FunctionalTests) will run in parallel\n- Within each project, test collections will also run in parallel\n- You should see multiple tests running simultaneously in Test Explorer\n\n## Performance Considerations\n\n**Recommended for:**\n- Fast unit tests (UnitTests project)\n- Independent integration tests that don't share state\n\n**Use with caution for:**\n- Tests using shared resources (databases, files, ports)\n- Tests with Testcontainers - these may need collection fixtures to control parallelization\n\nIf you encounter issues with FunctionalTests (which use Testcontainers), you may need to:\n1. Disable parallelization for that specific project by setting `parallelizeAssembly: false` in its `xunit.runner.json`\n2. Use xUnit Collection Fixtures to control which tests can run in parallel\n3. Configure Testcontainers to use unique ports/databases per test class\n\n## Disabling Parallel Execution\n\nTo disable parallel execution for a specific test project, update its `xunit.runner.json`:\n```json\n{\n  \"shadowCopy\": false,\n  \"parallelizeAssembly\": false,\n  \"parallelizeTestCollections\": false\n}\n```\n\n## Command Line Usage\n\nTo use the .runsettings file when running tests from the command line:\n```bash\ndotnet test --settings .runsettings\n```\n\n## Related Documentation\n- [xUnit Parallel Test Execution](https://xunit.net/docs/running-tests-in-parallel)\n- [Visual Studio Run Settings](https://learn.microsoft.com/en-us/visualstudio/test/configure-unit-tests-by-using-a-dot-runsettings-file)\n"
  },
  {
    "path": "README.md",
    "content": "[![.NET Core](https://github.com/ardalis/CleanArchitecture/workflows/.NET%20Core/badge.svg)](https://github.com/ardalis/CleanArchitecture/actions)\n[![publish Ardalis.CleanArchitecture Template to nuget](https://github.com/ardalis/CleanArchitecture/actions/workflows/publish.yml/badge.svg)](https://github.com/ardalis/CleanArchitecture/actions/workflows/publish.yml)\n[![Ardalis.CleanArchitecture.Template on NuGet](https://img.shields.io/nuget/v/Ardalis.CleanArchitecture.Template?label=Ardalis.CleanArchitecture.Template)](https://www.nuget.org/packages/Ardalis.CleanArchitecture.Template/)\n\n<a href=\"https://twitter.com/intent/follow?screen_name=ardalis\">\n    <img src=\"https://img.shields.io/twitter/follow/ardalis.svg?label=Follow%20@ardalis\" alt=\"Follow @ardalis\" />\n</a> &nbsp; <a href=\"https://twitter.com/intent/follow?screen_name=nimblepros\">\n    <img src=\"https://img.shields.io/twitter/follow/nimblepros.svg?label=Follow%20@nimblepros\" alt=\"Follow @nimblepros\" />\n</a>\n\n<p>\n\n![Alt](https://repobeats.axiom.co/api/embed/be5094dd306ba53b8f4fc0b43c9de5d8ca23a608.svg \"Repobeats analytics image\")\n\n</p>\n\n# Clean Architecture\n\nA starting point for Clean Architecture with ASP.NET Core. [Clean Architecture](https://8thlight.com/blog/uncle-bob/2012/08/13/the-clean-architecture.html) is just the latest in a series of names for the same loosely-coupled, dependency-inverted architecture. You will also find it named [hexagonal](https://alistair.cockburn.us/hexagonal-architecture), [ports-and-adapters](http://www.dossier-andreas.net/software_architecture/ports_and_adapters.html), or [onion architecture](http://jeffreypalermo.com/blog/the-onion-architecture-part-1/).\n\nLearn more about Clean Architecture and this template in [NimblePros' Introducing Clean Architecture course](https://academy.nimblepros.com/p/learn-clean-architecture). Use code ARDALIS to save 20%.\n\nThis architecture is used in the [DDD Fundamentals course](https://www.pluralsight.com/courses/fundamentals-domain-driven-design) by [Steve Smith](https://ardalis.com) and [Julie Lerman](https://thedatafarm.com/).\n\n:school: Contact Steve's company, [NimblePros](https://nimblepros.com/), for Clean Architecture or DDD training and/or implementation assistance for your team.\n\n## Take the Course!\n\n[Learn about how to implement Clean Architecture](https://academy.nimblepros.com/p/intro-to-clean-architecture) from [NimblePros](https://nimblepros.com) trainers [Sarah \"sadukie\" Dutkiewicz](https://blog.nimblepros.com/author/sadukie/) and [Steve \"ardalis\" Smith](https://blog.nimblepros.com/author/ardalis/).\n\n## Table Of Contents\n\n- [Clean Architecture](#clean-architecture)\n  - [Take the Course!](#take-the-course)\n  - [Table Of Contents](#table-of-contents)\n  - [Give a Star! :star:](#give-a-star-star)\n  - [Sponsors](#sponsors)\n  - [Troubleshooting Chrome Errors](#troubleshooting-chrome-errors)\n  - [Versions](#versions)\n  - [Learn More](#learn-more)\n- [Getting Started](#getting-started)\n  - [Template Installation](#template-installation)\n  - [Using the dotnet CLI template](#using-the-dotnet-cli-template)\n    - [Full Clean Architecture (`clean-arch`)](#full-clean-architecture-clean-arch)\n    - [Minimal Clean Architecture (`min-clean`)](#minimal-clean-architecture-min-clean)\n  - [Template Comparison](#template-comparison)\n    - [Which Template Should I Use?](#which-template-should-i-use)\n  - [What about Controllers and Razor Pages?](#what-about-controllers-and-razor-pages)\n    - [Add Ardalis.ApiEndpoints](#add-ardalisapiendpoints)\n    - [Add Controllers](#add-controllers)\n    - [Add Razor Pages](#add-razor-pages)\n  - [Using the GitHub Repository](#using-the-github-repository)\n  - [Running Migrations](#running-migrations)\n- [Goals](#goals)\n  - [History and Shameless Plug Section](#history-and-shameless-plug-section)\n- [Design Decisions and Dependencies](#design-decisions-and-dependencies)\n  - [Where To Validate](#where-to-validate)\n  - [The Core Project](#the-core-project)\n  - [The Use Cases Project](#the-use-cases-project)\n  - [The Infrastructure Project](#the-infrastructure-project)\n  - [The Web Project](#the-web-project)\n  - [The SharedKernel Package](#the-sharedkernel-package)\n  - [The Test Projects](#the-test-projects)\n- [Patterns Used](#patterns-used)\n  - [Domain Events](#domain-events)\n  - [Related Projects](#related-projects)\n  - [Presentations and Videos on Clean Architecture](#presentations-and-videos-on-clean-architecture)\n\n## Give a Star! :star:\n\nIf you like or are using this project to learn or start your solution, please give it a star. Thanks!\n\nOr if you're feeling really generous, we now support GitHub sponsorships - see the button above.\n\n## Sponsors\n\nI'm please to announce that [Amazon AWS's FOSS fund](https://github.com/aws/dotnet-foss) has chosen to award a 12-month sponsorship to this project. Thank you, and thanks to all of my other past and current sponsors!\n\n## Troubleshooting Chrome Errors\n\nBy default the site uses HTTPS and expects you to have a self-signed developer certificate for localhost use. If you get an error with Chrome [see this answer](https://stackoverflow.com/a/31900210/13729) for mitigation instructions.\n\n## Versions\n\nThe main branch is now using **.NET 9**. This corresponds with NuGet package version 10.x. Previous versions are available - see our [Releases](https://github.com/ardalis/CleanArchitecture/releases).\n\n## Learn More\n\n- [Live Stream Recordings Working on Clean Architecture](https://www.youtube.com/c/Ardalis/search?query=clean%20architecture)\n- [DotNetRocks Podcast Discussion with Steve \"ardalis\" Smith](https://player.fm/series/net-rocks/clean-architecture-with-steve-smith)\n- [Fritz and Friends Streaming Discussion with Steve \"ardalis\" Smith](https://www.youtube.com/watch?v=k8cZUW4MS3I)\n\n# Getting Started\n\nTo use this template, there are **two template options**:\n\n1. **Full Clean Architecture** (`clean-arch`) - Complete multi-project solution with Core, UseCases, Infrastructure, and Web\n2. **Minimal Clean Architecture** (`min-clean`) - Simplified single-project vertical slice architecture\n\nChoose based on your project's complexity and team preferences. See [Template Comparison](#template-comparison) below.\n\n## Template Installation\n\nInstall the templates from NuGet:\n\n```powershell\n# Full Clean Architecture template\ndotnet new install Ardalis.CleanArchitecture.Template\n\n# Minimal Clean Architecture template  \ndotnet new install Ardalis.MinimalClean.Template\n```\n\n## Using the dotnet CLI template\n\n### Full Clean Architecture (`clean-arch`)\n\nFirst, install the template from [NuGet (https://www.nuget.org/packages/Ardalis.CleanArchitecture.Template/)](https://www.nuget.org/packages/Ardalis.CleanArchitecture.Template/):\n\n```powershell\ndotnet new install Ardalis.CleanArchitecture.Template\n```\n\nYou can see available options by running the command with the `-?` option:\n\n```powershell\ndotnet new clean-arch -?\nASP.NET Clean Architecture Solution (C#)\nAuthor: Steve Smith @ardalis, Erik Dahl\n\nUsage:\n  dotnet new clean-arch [options] [template options]\n\nOptions:\n  -n, --name <name>       The name for the output being created. If no name is specified, the name of the output\n                          directory is used.\n  -o, --output <output>   Location to place the generated output.\n  --dry-run               Displays a summary of what would happen if the given command line were run if it would result\n                          in a template creation.\n  --force                 Forces content to be generated even if it would change existing files.\n  --no-update-check       Disables checking for the template package updates when instantiating a template.\n  --project <project>     The project that should be used for context evaluation.\n  -lang, --language <C#>  Specifies the template language to instantiate.\n  --type <project>        Specifies the template type to instantiate.\n\nTemplate options:\n  -as, --aspire  Include .NET Aspire.\n                 Type: bool\n                 Default: false\n```\n\nYou should see the template in the list of templates from `dotnet new list` after this installs successfully. Look for \"ASP.NET Clean Architecture Solution\" with Short Name of \"clean-arch\".\n\nNavigate to the parent directory in which you'd like the solution's folder to be created.\n\nRun this command to create the solution structure in a subfolder name `Your.ProjectName`:\n\n```powershell\ndotnet new clean-arch -o Your.ProjectName\n```\n\nThe `Your.ProjectName` directory and solution file will be created, and inside that will be all of your new solution contents, properly namespaced and ready to run/test!\n\nExample:\n![powershell screenshot showing steps](https://user-images.githubusercontent.com/782127/101661723-9fd28e80-3a16-11eb-8be4-f9195d825ad6.png)\n\nThanks [@dahlsailrunner](https://github.com/dahlsailrunner) for your help getting this working!\n\n**Known Issues**:\n\n- Don't include hyphens in the name. See [#201](https://github.com/ardalis/CleanArchitecture/issues/201).\n- Don't use 'Ardalis' as your namespace (conflicts with dependencies).\n\n### Minimal Clean Architecture (`min-clean`)\n\nFor a simpler, single-project vertical slice architecture, use the Minimal Clean Architecture template:\n\n```powershell\ndotnet new install Ardalis.MinimalClean.Template\ndotnet new min-clean -o Your.ProjectName\n```\n\nThis template provides:\n\n- **Single Web project** with all code organized by vertical slices (features)\n- **Simplified architecture** - no separate Core, UseCases, or Infrastructure projects\n- **Domain-Driven Design patterns** - entities, aggregates, but pragmatic\n- **FastEndpoints** for clean API endpoints\n- **Entity Framework Core** with migrations\n- **Aspire** support for cloud-ready development (optional)\n\nPerfect for MVPs, smaller applications, or teams that want architectural guidance without multi-project complexity.\n\n## Template Comparison\n\n| Feature | Full Clean Architecture | Minimal Clean Architecture |\n|---------|------------------------|----------------------------|\n| **Command** | `clean-arch` | `min-clean` |\n| **Projects** | 4+ (Core, UseCases, Infrastructure, Web) | 1 (Web only) |\n| **Organization** | By layer (horizontal) | By feature (vertical slices) |\n| **DDD Patterns** | Extensive (Aggregates, Value Objects, Domain Events, Specifications) | Pragmatic (simplified domain model) |\n| **Repository Pattern** | Yes, with Specifications | Optional (direct DbContext or simple repos) |\n| **Mediator/CQRS** | Yes (separate UseCases project) | Optional (can be in endpoints) |\n| **Complexity** | Higher - more abstractions | Lower - simpler structure |\n| **Best For** | Large enterprise apps, long-term maintenance | MVPs, smaller apps, rapid iteration |\n| **Team Size** | Multiple teams, strict boundaries | Small teams, collaborative |\n| **Learning Curve** | Steeper - more patterns to learn | Gentler - focused essentials |\n| **Migration Path** | Can simplify to minimal | Can grow into full template |\n\n### Which Template Should I Use?\n\n**Choose Full Clean Architecture if:**\n\n- Building large, complex enterprise applications\n- Multiple teams working on different layers\n- Long-term maintenance and evolution expected\n- Need strict separation of concerns and testability\n- Domain complexity requires extensive DDD patterns\n\n**Choose Minimal Clean Architecture if:**\n\n- Building MVPs or smaller applications\n- Want architectural guidance without project overhead\n- Prefer vertical slice architecture\n- Team values simplicity and fast iteration\n- May grow into full Clean Architecture later\n\n**Not sure?** Start with Minimal Clean and migrate to Full Clean Architecture if your application grows in complexity.\n\n## What about Controllers and Razor Pages?\n\nAs of version 9, this solution template only includes support for API Endpoints using the FastEndpoints library. If you want to use my ApiEndpoints library, Razor Pages, and/or Controllers you can use the last template that included them, [version 7.1](https://www.nuget.org/packages/Ardalis.CleanArchitecture.Template/7.1.0). Alternately, they're easily added to this template after installation.\n\n### Add Ardalis.ApiEndpoints\n\nTo use [Ardalis.ApiEndpoints](https://www.nuget.org/packages/Ardalis.ApiEndpoints) instead of (or in addition to) [FastEndpoints](https://fast-endpoints.com/), just add the reference and use the base classes from the documentation.\n\n```powershell\ndotnet add package Ardalis.ApiEndpoints\n```\n\n### Add Controllers\n\nYou'll need to add support for controllers to the Program.cs file. You need:\n\n```csharp\nbuilder.Services.AddControllers(); // ControllersWithView if you need Views\n\n// and\n\napp.MapControllers();\n```\n\nOnce these are in place, you should be able to create a Controllers folder and (optionally) a Views folder and everything should work as expected. Personally I find Razor Pages to be much better than Controllers and Views so if you haven't fully investigated Razor Pages you might want to do so right about now before you choose Views.\n\n### Add Razor Pages\n\nYou'll need to add support for Razor Pages to the Program.cs file. You need:\n\n```csharp\nbuilder.Services.AddRazorPages();\n\n// and\n\napp.MapRazorPages();\n```\n\nThen you just add a Pages folder in the root of the project and go from there.\n\n## Using the GitHub Repository\n\nTo get started based on this repository, you need to get a copy locally. You have three options: fork, clone, or download. Most of the time, you probably just want to download.\n\nYou should **download the repository**, unblock the zip file, and extract it to a new folder if you just want to play with the project or you wish to use it as the starting point for an application.\n\nYou should **fork this repository** only if you plan on submitting a pull request. Or if you'd like to keep a copy of a snapshot of the repository in your own GitHub account.\n\nYou should **clone this repository** if you're one of the contributors and you have commit access to it. Otherwise you probably want one of the other options.\n\n## Running Migrations\n\nYou shouldn't need to do this to use this template, but if you want migrations set up properly in the Infrastructure project, you need to specify that project name when you run the migrations command.\n\nIn Visual Studio, open the Package Manager Console, and run `Add-Migration InitialMigrationName -StartupProject Your.ProjectName.Web -Context AppDbContext -Project Your.ProjectName.Infrastructure`.\n\nIn a terminal with the CLI, the command is similar. Run this from the Web project directory:\n\n```powershell\ndotnet ef migrations add MIGRATIONNAME -c AppDbContext -p ../Your.ProjectName.Infrastructure/Your.ProjectName.Infrastructure.csproj -s Your.ProjectName.Web.csproj -o Data/Migrations\n```\n\nTo use SqlServer, change `options.UseSqlite(connectionString));` to `options.UseSqlServer(connectionString));` in the `Your.ProjectName.Infrastructure.StartupSetup` file. Also remember to replace the `SqliteConnection` with `DefaultConnection` in the `Your.ProjectName.Web.Program` file, which points to your Database Server.\n\nTo update the database use this command from the Web project folder (replace `Clean.Architecture` with your project's name):\n\n```powershell\ndotnet ef database update -c AppDbContext -p ../Clean.Architecture.Infrastructure/Clean.Architecture.Infrastructure.csproj -s Clean.Architecture.Web.csproj\n```\n\n# Goals\n\nThe goal of this repository is to provide a basic solution structure that can be used to build Domain-Driven Design (DDD)-based or simply well-factored, SOLID applications using .NET Core. Learn more about these topics here:\n\n- [SOLID Principles for C# Developers](https://www.pluralsight.com/courses/csharp-solid-principles)\n- [Domain-Driven Design Fundamentals](https://www.pluralsight.com/courses/fundamentals-domain-driven-design)\n- [Refactoring to SOLID C# Code](https://www.pluralsight.com/courses/refactoring-solid-c-sharp-code)\n\nIf you're used to building applications as single-project or as a set of projects that follow the traditional UI -> Business Layer -> Data Access Layer \"N-Tier\" architecture, I recommend you check out these two courses (ideally before DDD Fundamentals):\n\n- [Creating N-Tier Applications in C#, Part 1](https://www.pluralsight.com/courses/n-tier-apps-part1)\n- [Creating N-Tier Applications in C#, Part 2](https://www.pluralsight.com/courses/n-tier-csharp-part2)\n\nSteve Smith also maintains Microsoft's reference application, eShopOnWeb, and its associated free eBook. Check them out here:\n\n- [eShopOnWeb on GitHub](https://github.com/nimblepros/eShopOnWeb) (now supported by [NimblePros](https://nimblepros.com))\n- [Architecting Modern Web Applications with ASP.NET Core and Microsoft Azure](https://aka.ms/webappebook) (eBook)\n\nNote that the goal of this project and repository is **not** to provide a sample or reference application. It's meant to just be a template, but with enough pieces in place to show you where things belong as you set up your actual solution. Instead of useless \"Class1.cs\" there are a few real classes in place. Delete them as soon as you understand why they're there and where you should put your own, similar files. There *is* a sample application in the `/sample` folder, if you're looking for that.\n\n## History and Shameless Plug Section\n\nI've used this starter kit to teach the basics of ASP.NET Core using Domain-Driven Design concepts and patterns for some time now (starting when ASP.NET Core was still in pre-release). Typically I teach a one- or two-day hands-on workshop ahead of events like DevIntersection, or private on-site workshops for companies looking to bring their teams up to speed with the latest development technologies and techniques. Feel free to [contact me](https://nimblepros.com/) if you'd like information about upcoming workshops.\n\n# Design Decisions and Dependencies\n\nThe goal of this solution template is to provide a fairly bare-bones starter kit for new projects. It does not include every possible framework, tool, or feature that a particular enterprise application might benefit from. Its choices of technology for things like data access are rooted in what is the most common, accessible technology for most business software developers using Microsoft's technology stack. It doesn't (currently) include extensive support for things like logging, monitoring, or analytics, though these can all be added easily. Below is a list of the technology dependencies it includes, and why they were chosen. Most of these can easily be swapped out for your technology of choice, since the nature of this architecture is to support modularity and encapsulation.\n\n## Where To Validate\n\nValidation of user input is a requirement of all software applications. The question is, where does it make sense to implement it in a concise and elegant manner? This solution template includes 4 separate projects, each of which might be responsible for performing validation as well as enforcing business invariants (which, given validation should already have occurred, are usually modeled as exceptions).\n\n- [When to Validate and When to Throw Exceptions](https://www.youtube.com/watch?v=dpPcnAT7n7M)\n\nThe domain model itself should generally rely on object-oriented design to ensure it is always in a consistent state. It leverages encapsulation and limits public state mutation access to achieve this, and it assumes that any arguments passed to it have already been validated, so null or other improper values yield exceptions, not validation results, in most cases.\n\nThe use cases / application project includes the set of all commands and queries the system supports. It's frequently responsible for validating its own command and query objects. This is most easily done using a [chain of responsibility pattern](https://deviq.com/design-patterns/chain-of-responsibility-pattern) via Mediator behaviors or some other pipeline.\n\nThe Web project includes all API endpoints, which include their own request and response types, following the [REPR pattern](https://deviq.com/design-patterns/repr-design-pattern). The FastEndpoints library includes built-in support for validation using FluentValidation on the request types. This is a natural place to perform input validation as well.\n\nHaving validation occur both within the API endpoints and then again at the use case level may be considered redundant. There are tradeoffs to adding essentially the same validation in two places, one for API requests and another for messages sent to Use Case handlers. Following defensive coding, it often makes sense to add validation in both places, as the overhead is minimal and the peace of mind of mind and greater application robustness is often worth it.\n\n## The Core Project\n\nThe Core project is the center of the Clean Architecture design, and all other project dependencies should point toward it. As such, it has very few external dependencies. The Core project should include the Domain Model including things like:\n\n- Entities\n- Aggregates\n- Value Objects\n- Domain Events\n- Domain Event Handlers\n- Domain Services\n- Specifications\n- Interfaces\n- DTOs (sometimes)\n\nYou can learn more about these patterns and how to apply them here:\n\n- [DDD Fundamentals](https://www.pluralsight.com/courses/fundamentals-domain-driven-design)\n- [DDD Concepts](https://deviq.com/domain-driven-design/ddd-overview)\n\n## The Use Cases Project\n\nAn optional project, I've included it because many folks were demanding it and it's easier to remove than to add later. This is also often referred to as the *Application* or *Application Services* layer. The Use Cases project is organized following CQRS into Commands and Queries (I considered having folders for `Commands` and `Queries` but felt it added little - the folders per actual *command* or *query* is sufficient without extra nesting). Commands mutate the domain model and thus should always use Repository abstractions for their data access (Repositories are how one fetches and persists domain model types). Queries are readonly, and thus **do not need to use the repository pattern**, but instead can use whatever query service or approach is most convenient.\n\nSince the Use Cases project is set up to depend on Core and does not depend on Infrastructure, there will still need to be abstractions defined for its data access. And it *can* use things like specifications, which can sometimes help encapsulate query logic as well as result type mapping. But it doesn't *have* to use repository/specification - it can just issue a SQL query or call a stored procedure if that's the most efficient way to get the data.\n\nAlthough this is an optional project to include (without it, your API endpoints would just work directly with the domain model or query services), it does provide a nice UI-ignorant place to add automated tests, and lends itself toward applying policies for cross-cutting concerns using a Chain of Responsibility pattern around the message handlers (for things like validation, caching, auth, logging, timing, etc.). The template includes an example of this for logging, which is located in the [SharedKernel NuGet package](https://github.com/ardalis/Ardalis.SharedKernel/blob/main/src/Ardalis.SharedKernel/LoggingBehavior.cs).\n\n## The Infrastructure Project\n\nMost of your application's dependencies on external resources should be implemented in classes defined in the Infrastructure project. These classes should implement interfaces defined in Core. If you have a very large project with many dependencies, it may make sense to have multiple Infrastructure projects (e.g. Infrastructure.Data), but for most projects one Infrastructure project with folders works fine. The template includes data access and domain event implementations, but you would also add things like email providers, file access, web api clients, etc. to this project so they're not adding coupling to your Core or UI projects.\n\n## The Web Project\n\nThe entry point of the application is the ASP.NET Core web project (or possibly the AspireHost project, which in turn loads the Web project). This is actually a console application, with a `public static void Main` method in `Program.cs`. It leverages FastEndpoints and the REPR pattern to organize its API endpoints.\n\n## The SharedKernel Package\n\nA [Shared Kernel](https://deviq.com/domain-driven-design/shared-kernel) is used to share common elements between bounded contexts. It's a DDD term but many organizations leverage \"common\" projects or packages for things that are useful to share between several applications.\n\nI recommend creating a separate SharedKernel project and solution if you will require sharing code between multiple [bounded contexts](https://ardalis.com/encapsulation-boundaries-large-and-small/) (see [DDD Fundamentals](https://www.pluralsight.com/courses/domain-driven-design-fundamentals)). I further recommend this be published as a NuGet package (most likely privately within your organization) and referenced as a NuGet dependency by those projects that require it.\n\nPreviously a project for SharedKernel was included in this project. However, for the above reasons I've made it a separate package, [Ardalis.SharedKernel](https://github.com/ardalis/Ardalis.SharedKernel), which **you should replace with your own when you use this template**.\n\nIf you want to see another [example of a SharedKernel package, the one I use in my updated Pluralsight DDD course is on NuGet here](https://www.nuget.org/packages/PluralsightDdd.SharedKernel/).\n\n## The Test Projects\n\nTest projects could be organized based on the kind of test (unit, functional, integration, performance, etc.) or by the project they are testing (Core, Infrastructure, Web), or both. For this simple starter kit, the test projects are organized based on the kind of test, with unit, functional and integration test projects existing in this solution. Functional tests are a special kind of [integration test](https://learn.microsoft.com/en-us/aspnet/core/test/integration-tests?view=aspnetcore-8.0) that perform [subcutaneous testing](https://martinfowler.com/bliki/SubcutaneousTest.html) of the APIs of the Web project, without actually hosting a real website or going over the network. I've created a bunch of [test helpers](https://github.com/ardalis/HttpClientTestExtensions) to make these kinds of tests shorter and easier to maintain.\n\n# Patterns Used\n\nThis solution template has code built in to support a few common patterns, especially Domain-Driven Design patterns. Here is a brief overview of how a few of them work.\n\n## Domain Events\n\nDomain events are a great pattern for decoupling a trigger for an operation from its implementation. This is especially useful from within domain entities since the handlers of the events can have dependencies while the entities themselves typically do not. In the sample, you can see this in action with the `ToDoItem.MarkComplete()` method. The following sequence diagram demonstrates how the event and its handler are used when an item is marked complete through a web API endpoint.\n\n![Domain Event Sequence Diagram](https://user-images.githubusercontent.com/782127/75702680-216ce300-5c73-11ea-9187-ec656192ad3b.png)\n\n## Related Projects\n\n- [ApiEndpoints](https://github.com/ardalis/apiendpoints)\n- [GuardClauses](https://github.com/ardalis/guardclauses)\n- [HttpClientTestExtensions](https://github.com/ardalis/HttpClientTestExtensions)\n- [Result](https://github.com/ardalis/result)\n- [SharedKernel](https://github.com/ardalis/Ardalis.SharedKernel)\n- [SmartEnum](https://github.com/ardalis/SmartEnum)\n- [Specification](https://github.com/ardalis/specification)\n- [FastEndpoints](https://fast-endpoints.com/)\n\n## Presentations and Videos on Clean Architecture\n\n- [What's New in Clean Architecture Template 9.1](https://www.youtube.com/watch?v=EJIgjL41em4)\n- [The REPR Pattern and Clean Architecture](https://www.youtube.com/watch?v=-AJcEJPwagQ)\n- [Clean Architecture with ASP.NET Core 8](https://www.youtube.com/watch?v=yF9SwL0p0Y0)\n- [Getting Started with Clean Architecture and .NET 8 (webinar)](https://www.youtube.com/watch?v=IsmyqNrfQQw)\n\n"
  },
  {
    "path": "README.template.md",
    "content": "# ${name}\n\nWelcome to your new project generated with the Clean Architecture template!\n\n## Getting Started\n\n- Build the solution:\n  ```sh\n  dotnet build\n  ```\n- Run the application:\n  ```sh\n  dotnet run --project src/Your.ProjectName.Web\n  ```\n- Update the database (if using EF Core):\n  ```sh\n  dotnet ef database update -c AppDbContext -p src/Your.ProjectName.Infrastructure/Your.ProjectName.Infrastructure.csproj -s src/Your.ProjectName.Web/Your.ProjectName.Web.csproj\n  ```\n\n## Solution Structure\n\n- **Core**: Domain entities, value objects, interfaces\n- **UseCases**: Application logic, CQRS handlers\n- **Infrastructure**: Data access, external services\n- **Web**: API endpoints (FastEndpoints)\n\nFor more details, see the documentation or visit the [Clean Architecture Template repository](https://github.com/ardalis/CleanArchitecture).\n"
  },
  {
    "path": "TESTCONTAINERS_IMPLEMENTATION.md",
    "content": "# Testcontainers Implementation for Functional Tests\n\n## Summary\n\nSuccessfully migrated functional tests from in-memory database to **Testcontainers** with SQL Server 2022. This provides a more realistic testing environment that matches production database behavior.\n\n## Changes Made\n\n### 1. Package References\n\n**Added to `Directory.Packages.props`:**\n```xml\n<PackageVersion Include=\"Testcontainers\" Version=\"4.3.0\" />\n<PackageVersion Include=\"Testcontainers.MsSql\" Version=\"4.3.0\" />\n```\n\n**Updated `tests\\Clean.Architecture.FunctionalTests\\Clean.Architecture.FunctionalTests.csproj`:**\n- Removed: `Microsoft.EntityFrameworkCore.InMemory`\n- Added: `Testcontainers` and `Testcontainers.MsSql`\n\n### 2. CustomWebApplicationFactory\n\n**File:** `tests\\Clean.Architecture.FunctionalTests\\CustomWebApplicationFactory.cs`\n\nKey changes:\n- Implements `IAsyncLifetime` for proper async initialization/cleanup\n- Creates a SQL Server container using `MsSqlBuilder`\n- Uses SQL Server 2022 image: `mcr.microsoft.com/mssql/server:2022-latest`\n- Applies EF Core migrations instead of `EnsureCreated()`\n- Each test run gets a fresh containerized SQL Server instance\n\n```csharp\nprivate readonly MsSqlContainer _dbContainer = new MsSqlBuilder()\n  .WithImage(\"mcr.microsoft.com/mssql/server:2022-latest\")\n  .WithPassword(\"Your_password123!\")\n  .Build();\n```\n\n### 3. Test Configuration\n\nTests now:\n- Use real SQL Server running in Docker containers\n- Apply actual EF Core migrations (matches production)\n- Run against isolated database instances (parallel test safety)\n- Clean up containers automatically after tests complete\n\n## Benefits\n\n? **Realistic Testing**: Tests run against actual SQL Server, not in-memory provider  \n? **Migration Testing**: Validates that migrations work correctly  \n? **Production Parity**: Database behavior matches production environment  \n? **Isolation**: Each test class gets its own containerized database  \n? **Automatic Cleanup**: Containers are disposed after tests complete\n\n## Requirements\n\n- **Docker Desktop** must be running on the development machine\n- Tests take slightly longer (~10-13 seconds vs instant with in-memory)\n- First run downloads SQL Server 2022 Docker image (~1.5 GB)\n\n## Test Results\n\nAll 18 tests passing:\n- ? Unit Tests: 15 tests\n- ? Functional Tests: 3 tests\n- ? Total Duration: ~12 seconds\n\n## Usage\n\nRun tests normally:\n```bash\ndotnet test\n```\n\nOr specifically for functional tests:\n```bash\ndotnet test tests\\Clean.Architecture.FunctionalTests\\Clean.Architecture.FunctionalTests.csproj\n```\n\n## Notes\n\n- Tests use the \"Testing\" environment configuration\n- SQL Server password: `Your_password123!` (only for test containers)\n- Container lifecycle managed by xUnit's `IAsyncLifetime`\n- Containers are automatically cleaned up even if tests fail\n"
  },
  {
    "path": "docs/architecture-decisions/README.md",
    "content": "# Architecture Decision Records (ADR)\n\n## What is an Architecture Decision Record (ADR)?\nAn Architecture Decision Record (ADR) documents significant architecture decisions made throughout a project, capturing the context, rationale, and consequences of each decision. This promotes transparency and provides a historical reference for future design considerations.\n\n## Purpose of ADRs\n- **Knowledge Management**: Consolidates architectural knowledge and decisions.\n- **Collaboration**: Enhances team communication by documenting discussions and outcomes.\n- **Clarity**: Provides clear reasoning behind design choices, making it easier for new team members to understand past decisions.\n\n## Best Practices for Writing ADRs\n1. **Be Specific**: Each ADR should address a single architectural decision. Avoid conflating multiple decisions into one record.\n2. **Document Context**: Clearly explain the project’s context and relevant considerations that influenced the decision. Include team dynamics and priorities.\n3. **Rationale and Consequences**: Describe the reasons for the decision, including pros and cons, and outline the implications of the decision for the project and \n\nfuture architecture.\n4. **Immutable Records**: Once an ADR is created, avoid altering it. Instead, create a new ADR to reflect any changes or updates.\n5. **Timestamp Entries**: Include timestamps to track when each decision was made, especially for aspects that may evolve over time (e.g., costs, schedules).\n6. **Use Templates**: Utilize established templates for consistency and completeness in documenting ADRs.\n\n## Versioning ADRs\n- **Track Changes**: Each time an ADR is updated or a new version is created, increment the version number (e.g., `v1.0`, `v1.1`, etc.) to reflect changes clearly.\n- **Document Changes**: Include a \"Changelog\" section in the ADR to summarize what has changed in each version. This can include updates to the rationale, context, or decision consequences.\n- **Maintain Clarity**: Ensure the latest version is easily accessible while keeping older versions for reference. You might consider using a version control system (e.g., Git) to manage this effectively.\n\n## How to Start Using ADRs\n1. **Identify Decisions**: Collaborate with your team to identify significant architecture decisions that need documentation.\n2. **Select a Tool**: Choose a tool for documenting ADRs (e.g., markdown files in a Git repository, Google Docs, project management tools).\n3. **Create ADRs**: For each decision, create an ADR file in the `adr` directory, following naming conventions (e.g., `choose-database.md`).\n\n## File Name Conventions\n- Use a present tense imperative verb phrase.\n- Separate words with lowercase letters and dashes.\n- Use `.md` extension for markdown formatting.\n\n## Templates\nRefer to the following templates for structuring your ADRs:\n- [Decision record template by Michael Nygard](https://thinkrelevance.com/blog/2011/11/15/documenting-architecture-decisions)\n- [Decision record template by Jeff Tyree and Art Akerman](https://github.com/adr/adr)\n- [MADR project templates](https://adr.github.io/madr/)\n\n## Teamwork Advice for ADRs\n- Foster a culture of collaborative decision-making and ensure ADRs are seen as valuable tools rather than bureaucratic requirements.\n- Consider using the term \"decisions\" instead of \"ADRs\" to encourage engagement.\n- Maintain living documents by updating existing ADRs with new information rather than rewriting them.\n\n## For More Information\n- [Architectural Decision Wikipedia](https://en.wikipedia.org/wiki/Architectural_decision)\n- [Markdown Architectural Decision Records](https://adr.github.io/)\n- [Tools for working with ADRs](https://github.com/adr/adr)\n\nBy following these guidelines, your team can effectively leverage ADRs to enhance architectural decision-making and project transparency while keeping a clear version history of all architectural decisions.\n"
  },
  {
    "path": "docs/architecture-decisions/adr-001-dotnet-di-adoption.md",
    "content": "# ADR 001: Replace Autofac with .NET Core Dependency Injection\n\n## Status\nAccepted\n\n## Context\nInitially, this repository employed Autofac for dependency injection. At the time of adoption, Autofac was preferred due to its robust feature set, including:\n- Support for advanced scenarios such as decorators and modules, which could be placed close to their corresponding implementations.\n- A well-established history of stability and maturity, having been used in various projects before .NET Core's built-in DI was fully featured.\n\nAs the .NET ecosystem evolved, the built-in DI container began to meet the needs of our project without introducing the added complexity associated with Autofac. The .NET DI framework has matured significantly, offering sufficient functionality for typical use cases, including:\n- Improved support for configuration through extension methods.\n- A simpler learning curve for new contributors familiar with .NET conventions.\n\n## Decision\nBased on community feedback and a review of our project's requirements, we have decided to remove Autofac from this template and transition to using .NET's built-in dependency injection infrastructure. This decision aligns with the goal of simplifying the codebase and reducing external dependencies.\n\n## Consequences\n- **Simplified Codebase**: Removing Autofac results in a cleaner, more maintainable codebase that adheres to .NET standards.\n- **Reduced Complexity**: The transition eliminates the need for additional files and configurations specific to Autofac, making the project easier to understand for new contributors.\n- **Standardization**: Adopting .NET's built-in DI promotes consistency with other .NET projects, making it easier for developers familiar with the framework to contribute effectively.\n\n## References\n- [Issue #649: Why is this repo using Autofac instead of .NET's own DI infrastructure?](https://github.com/ardalis/CleanArchitecture/issues/649) - Discussion that led to this decision.\n- [Getting Started with Architecture Decision Records](https://ardalis.com/getting-started-with-architecture-decision-records/) - Resource on ADR best practices.\n"
  },
  {
    "path": "docs/minimal-clean-architecture.md",
    "content": "# Minimal Clean Architecture\n\n## Overview\n\nThe **Minimal Clean Architecture** template provides a simplified, pragmatic approach to Clean Architecture for ASP.NET Core applications. It maintains the core principles of Clean Architecture—separation of concerns, dependency inversion, and testability—while reducing complexity through a single-project Vertical Slice Architecture (VSA).\n\n## Philosophy\n\n### Core Principles\n\n1. **Simplicity First**: Minimize unnecessary abstractions and project boundaries\n2. **Vertical Slices**: Organize by feature rather than technical layer\n3. **Pragmatic DDD**: Use domain patterns where they add value, not everywhere\n4. **Progressive Enhancement**: Start simple, add complexity only when needed\n\n### Clean Architecture Principles Maintained\n\n- ✅ **Dependency Inversion**: Domain doesn't depend on infrastructure\n- ✅ **Testability**: Business logic can be tested in isolation\n- ✅ **Separation of Concerns**: Clear boundaries between domain, infrastructure, and presentation\n- ✅ **Framework Independence**: Domain logic isn't coupled to ASP.NET Core\n\n### Simplifications from Full Template\n\n- **Single Project**: All code in one Web project instead of 4+ projects\n- **Simplified DDD**: Essential patterns only (entities, aggregates) without extensive value objects, specifications\n- **Optional CQRS**: Mediator is optional; logic can live in endpoints\n- **Direct Data Access**: Can use DbContext directly or simple repositories instead of complex repository pattern\n- **Vertical Organization**: Group by feature (Cart, Order, Product) instead of by layer\n\n## Architecture\n\n### Project Structure\n\n```text\nMinimalClean.Architecture.Web/\n├── Domain/                         # Domain Layer\n│   ├── CartAggregate/\n│   │   ├── Cart.cs                 # Aggregate root\n│   │   ├── CartItem.cs            # Entity\n│   │   └── Events/                # Domain events (optional)\n│   ├── OrderAggregate/\n│   └── ProductAggregate/\n├── Infrastructure/                 # Infrastructure Layer\n│   ├── Data/\n│   │   ├── AppDbContext.cs        # EF Core DbContext\n│   │   ├── Config/                # EF configurations\n│   │   │   ├── CartConfiguration.cs\n│   │   │   └── OrderConfiguration.cs\n│   │   └── Migrations/            # EF migrations\n│   ├── Email/                     # External services\n│   └── Services/                  # Infrastructure services\n├── Endpoints/                      # Presentation Layer\n│   ├── Cart/\n│   │   ├── Create.cs              # Create cart endpoint\n│   │   ├── AddItem.cs             # Add item to cart\n│   │   └── List.cs                # List carts\n│   ├── Order/\n│   └── Product/\n└── Program.cs                     # Application startup\n```\n\n### Vertical Slice Organization\n\nEach feature (Cart, Order, Product) contains:\n\n- **Domain**: Entities and business logic\n- **Infrastructure**: Data configurations for that feature\n- **Endpoints**: API endpoints for that feature\n\nThis keeps related code together, making it easier to understand and modify features independently.\n\n### Dependency Flow\n\n```text\nEndpoints ──→ Domain\n    ↓\nInfrastructure ──→ Domain\n```\n\n- Endpoints can use Domain and Infrastructure\n- Infrastructure depends on Domain (for entity configurations)\n- Domain has no dependencies on other layers\n\n## Design Decisions\n\n### ADR-001: Single Project Architecture\n\n**Status**: Accepted\n\n**Context**: Need to balance architectural guidance with simplicity for smaller applications.\n\n**Decision**: Use a single Web project with clear folder structure instead of multiple projects.\n\n**Consequences**:\n- ✅ Simpler to navigate and understand\n- ✅ Faster builds (no project-to-project references)\n- ✅ Easier to refactor (no project boundary concerns)\n- ✅ Lower initial complexity\n- ⚠️ Developers must respect folder boundaries (not enforced by compiler)\n- ⚠️ Harder to enforce strict layer separation\n\n**Migration Path**: Can be extracted into multiple projects later if needed.\n\n### ADR-002: Vertical Slice Organization\n\n**Status**: Accepted\n\n**Context**: Need to organize code in a way that's easy to understand and modify.\n\n**Decision**: Organize by feature (vertical slices) rather than by layer (horizontal).\n\n**Consequences**:\n- ✅ Related code is colocated (easier to find)\n- ✅ Features can be modified independently\n- ✅ Natural fit for microservices extraction\n- ✅ Aligns with business capabilities\n- ⚠️ May have some code duplication across features\n- ⚠️ Shared concerns need careful consideration\n\n### ADR-003: Pragmatic DDD\n\n**Status**: Accepted\n\n**Context**: Full DDD patterns can be overkill for simpler domains.\n\n**Decision**: Use essential DDD patterns (entities, aggregates) but keep it simple.\n\n**Patterns Included**:\n- ✅ Entities with encapsulation\n- ✅ Aggregate roots\n- ✅ Domain events (optional)\n\n**Patterns Simplified/Optional**:\n- ⚠️ Value Objects (use when valuable, not everywhere)\n- ⚠️ Specifications (use LINQ, add if needed)\n- ⚠️ Domain Services (add only when needed)\n\n**Consequences**:\n- ✅ Easier to learn and apply\n- ✅ Less boilerplate code\n- ✅ Faster development\n- ⚠️ May need to add patterns as domain complexity grows\n\n### ADR-004: Optional Mediator/CQRS\n\n**Status**: Accepted\n\n**Context**: CQRS with Mediator adds valuable patterns but also complexity.\n\n**Decision**: Make Mediator optional; allow business logic in endpoints for simple cases. Trade-off is no ability to use custom pipeline for cross-cutting concerns.\n\n**Usage Guidelines**:\n- Simple CRUD: Can put logic directly in endpoints\n- Complex workflows: Use Mediator commands/queries\n- Cross-cutting concerns: Use Mediator pipeline behaviors\n\n**Consequences**:\n- ✅ Lower initial complexity\n- ✅ Developers choose appropriate level of abstraction\n- ⚠️ Inconsistent patterns across codebase possible\n- ⚠️ Need clear team guidelines on when to use Mediator\n\n### ADR-005: FastEndpoints for APIs\n\n**Status**: Accepted\n\n**Context**: Need clean, testable API endpoints.\n\n**Decision**: Use FastEndpoints with REPR pattern.\n\n**Consequences**:\n- ✅ One file per endpoint (easy to find)\n- ✅ Built-in validation support\n- ✅ Clear request/response types\n- ✅ Testable without HTTP layer\n- ⚠️ Different from standard ASP.NET Core patterns\n- ⚠️ Learning curve for team\n\n## When to Use This Template\n\n### Ideal Scenarios\n\n1. **MVPs and Prototypes**\n   - Need to validate ideas quickly\n   - Want architectural guidance without overhead\n   - May grow into larger application\n\n2. **Small to Medium Applications**\n   - 5-50 endpoints\n   - 5-20 domain entities\n   - 1-5 developers\n   - Simple to moderate domain complexity\n\n3. **Learning Clean Architecture**\n   - Want to understand principles without complexity\n   - Stepping stone to full Clean Architecture\n   - Teaching tool for teams\n\n4. **Vertical Slice Architecture Preference**\n   - Team prefers feature-based organization\n   - Planning to extract microservices later\n   - Value cohesion over layer separation\n\n### Not Recommended For\n\n1. **Large Enterprise Applications**\n   - Complex domain requiring extensive DDD patterns\n   - Multiple teams needing strict boundaries\n   - Long-term evolution expected\n   - → Use Full Clean Architecture instead\n\n2. **Microservices from Start**\n   - If you know you'll split into services\n   - → Consider separate services with minimal template each\n\n3. **Regulatory/Compliance Heavy**\n   - Strict audit requirements\n   - Need enforced layer boundaries\n   - → Use Full Clean Architecture instead\n\n## Migration Paths\n\n### From Minimal to Full Clean Architecture\n\nAs your application grows, you can migrate to the full template:\n\n#### Step 1: Extract Core Project\n\n```powershell\n# Create new Core project\ndotnet new classlib -n YourProject.Core\n\n# Move domain entities\nmv Domain/* ../YourProject.Core/\n\n# Update namespaces\n# Update project references\n```\n\n#### Step 2: Extract Infrastructure Project\n\n```powershell\n# Create Infrastructure project\ndotnet new classlib -n YourProject.Infrastructure\n\n# Move infrastructure code\nmv Infrastructure/* ../YourProject.Infrastructure/\n\n# Add reference to Core\ndotnet add YourProject.Infrastructure reference YourProject.Core\n```\n\n#### Step 3: Extract UseCases (Optional)\n\n```powershell\n# Create UseCases project\ndotnet new classlib -n YourProject.UseCases\n\n# Move business logic from endpoints to use cases\n# Add Mediator (if not already using)\n# Create command/query handlers\n# Leverage Mediator Behaviors for cross-cutting concerns\n```\n\n#### Step 4: Clean Up Web Project\n\n- Update project references\n- Keep only endpoints and startup code\n- Reference UseCases or Infrastructure as needed\n\n### From Full Clean Architecture to Minimal\n\nIf you find the full template too complex:\n\n#### Step 1: Merge Projects\n\n```powershell\n# Copy all code into Web project\n# Organize by vertical slices\n```\n\n#### Step 2: Simplify Patterns\n\n- Replace Specifications with LINQ\n- Simplify Value Objects to primitives where beneficial\n- Remove unnecessary abstractions\n\n#### Step 3: Organize Vertically\n\n- Group by feature instead of layer\n- Colocate related code\n\n## Best Practices\n\n### Domain Layer\n\n```csharp\n// Good: Encapsulated entity\npublic class Cart\n{\n    private readonly List<CartItem> _items = new();\n    public IReadOnlyCollection<CartItem> Items => _items.AsReadOnly();\n    \n    public void AddItem(Product product, int quantity)\n    {\n        // Business logic here\n        var existingItem = _items.FirstOrDefault(i => i.ProductId == product.Id);\n        if (existingItem != null)\n        {\n            existingItem.IncreaseQuantity(quantity);\n        }\n        else\n        {\n            _items.Add(new CartItem(product, quantity));\n        }\n    }\n}\n\n// Avoid: Anemic domain model\npublic class Cart\n{\n    public List<CartItem> Items { get; set; } = new();\n}\n```\n\n### Endpoint Layer\n\n```csharp\n// Good: Clear, focused endpoint\npublic class CreateCart : EndpointWithoutRequest<CartResponse>\n{\n    private readonly AppDbContext _db;\n    \n    public CreateCart(AppDbContext db) => _db = db;\n    \n    public override void Configure()\n    {\n        Post(\"/carts\");\n        AllowAnonymous();\n    }\n    \n    public override async Task HandleAsync(CancellationToken ct)\n    {\n        var cart = new Cart(guestUserId: Guid.NewGuid());\n        _db.Carts.Add(cart);\n        await _db.SaveChangesAsync(ct);\n        \n        await Send.Async(new CartResponse(cart.Id, cart.Items.Count), cancellation: ct);\n    }\n}\n```\n\n### Infrastructure Layer\n\n```csharp\n// Good: Focused EF configuration\npublic class CartConfiguration : IEntityTypeConfiguration<Cart>\n{\n    public void Configure(EntityTypeBuilder<Cart> builder)\n    {\n        builder.HasKey(c => c.Id);\n        builder.HasMany(c => c.Items)\n               .WithOne()\n               .HasForeignKey(\"CartId\");\n    }\n}\n```\n\n## Testing Strategy\n\n### Unit Tests\n\nFocus on domain logic:\n\n```csharp\npublic class CartTests\n{\n    [Fact]\n    public void AddItem_NewProduct_AddsToCart()\n    {\n        // Arrange\n        var cart = new Cart(guestUserId: Guid.NewGuid());\n        var product = new Product(\"Test\", 10m);\n        \n        // Act\n        cart.AddItem(product, 2);\n        \n        // Assert\n        Assert.Single(cart.Items);\n        Assert.Equal(2, cart.Items.First().Quantity);\n    }\n}\n```\n\n### Functional Tests\n\nTest endpoints end-to-end:\n\n```csharp\npublic class CartEndpointsTests : IClassFixture<WebApplicationFactory<Program>>\n{\n    [Fact]\n    public async Task CreateCart_ReturnsNewCart()\n    {\n        // Arrange\n        var client = _factory.CreateClient();\n        \n        // Act\n        var response = await client.PostAsync(\"/carts\", null);\n        \n        // Assert\n        response.EnsureSuccessStatusCode();\n        var cart = await response.Content.ReadFromJsonAsync<CartResponse>();\n        Assert.NotNull(cart);\n    }\n}\n```\n\n## Resources\n\n- [Main Clean Architecture Template](https://github.com/ardalis/CleanArchitecture)\n- [Vertical Slice Architecture](https://jimmybogard.com/vertical-slice-architecture/)\n- [FastEndpoints Documentation](https://fast-endpoints.com/)\n- [Domain-Driven Design Fundamentals](https://www.pluralsight.com/courses/fundamentals-domain-driven-design)\n- [Clean Architecture Course](https://academy.nimblepros.com/p/intro-to-clean-architecture)\n\n## Contributing\n\nContributions are welcome! Please see the main [Contributing Guide](../CONTRIBUTING.md).\n\n## License\n\nMIT - see [LICENSE](../LICENSE)\n"
  },
  {
    "path": "global.json",
    "content": "{\n  \"sdk\": {\n    \"version\": \"10.0.100\",\n    \"rollForward\": \"latestMajor\",\n    \"allowPrerelease\": true\n  }\n}"
  },
  {
    "path": "nuget.config",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<configuration>\n    <packageRestore>\n        <add key=\"enabled\" value=\"True\" />\n        <add key=\"automatic\" value=\"True\" />\n    </packageRestore>\n\n    <packageSources>\n        <clear />\n        <add key=\"nuget.org\" value=\"https://api.nuget.org/v3/index.json\" />\n        <add key=\"LocalNuget\" value=\"c:\\LocalNuget\" />\n\n    </packageSources>\n\n    <packageSourceMapping>\n        <packageSource key=\"nuget.org\">\n            <package pattern=\"*\" />\n        </packageSource>\n    </packageSourceMapping>\n\n    <bindingRedirects>\n        <add key=\"skip\" value=\"False\" />\n    </bindingRedirects>\n\n    <packageManagement>\n        <add key=\"format\" value=\"0\" />\n        <add key=\"disabled\" value=\"False\" />\n    </packageManagement>\n\n    <disabledPackageSources>\n        <clear />\n      </disabledPackageSources>\n    \n      <fallbackPackageFolders>\n        <clear />\n      </fallbackPackageFolders>\n</configuration>\n"
  },
  {
    "path": "sample/.editorconfig",
    "content": "###############################\n# Core EditorConfig Options   #\n###############################\nroot = true\n# All files\n[*]\nindent_style = space\n\n# XML project files\n[*.{csproj,vbproj,vcxproj,vcxproj.filters,proj,projitems,shproj}]\nindent_size = 2\n\n# XML config files\n[*.{props,targets,ruleset,config,nuspec,resx,vsixmanifest,vsct}]\nindent_size = 2\n\n# Code files\n[*.{cs,csx,vb,vbx}]\nindent_size =2\ninsert_final_newline = true\ncharset = utf-8-bom\n###############################\n# .NET Coding Conventions     #\n###############################\n[*.{cs,vb}]\n# Organize usings\ndotnet_sort_system_directives_first = true\n# this. preferences\ndotnet_style_qualification_for_field = false:silent\ndotnet_style_qualification_for_property = false:silent\ndotnet_style_qualification_for_method = false:silent\ndotnet_style_qualification_for_event = false:silent\n# Language keywords vs BCL types preferences\ndotnet_style_predefined_type_for_locals_parameters_members = true:silent\ndotnet_style_predefined_type_for_member_access = true:silent\n# Parentheses preferences\ndotnet_style_parentheses_in_arithmetic_binary_operators = always_for_clarity:silent\ndotnet_style_parentheses_in_relational_binary_operators = always_for_clarity:silent\ndotnet_style_parentheses_in_other_binary_operators = always_for_clarity:silent\ndotnet_style_parentheses_in_other_operators = never_if_unnecessary:silent\n# Modifier preferences\ndotnet_style_require_accessibility_modifiers = for_non_interface_members:silent\ndotnet_style_readonly_field = true:suggestion\n# Expression-level preferences\ndotnet_style_object_initializer = true:suggestion\ndotnet_style_collection_initializer = true:suggestion\ndotnet_style_explicit_tuple_names = true:suggestion\ndotnet_style_null_propagation = true:suggestion\ndotnet_style_coalesce_expression = true:suggestion\ndotnet_style_prefer_is_null_check_over_reference_equality_method = true:silent\ndotnet_style_prefer_inferred_tuple_names = true:suggestion\ndotnet_style_prefer_inferred_anonymous_type_member_names = true:suggestion\ndotnet_style_prefer_auto_properties = true:silent\ndotnet_style_prefer_conditional_expression_over_assignment = true:silent\ndotnet_style_prefer_conditional_expression_over_return = true:silent\n###############################\n# Naming Conventions          #\n###############################\n# Style Definitions\ndotnet_naming_style.pascal_case_style.capitalization             = pascal_case\n# Use PascalCase for constant fields  \ndotnet_naming_rule.constant_fields_should_be_pascal_case.severity = suggestion\ndotnet_naming_rule.constant_fields_should_be_pascal_case.symbols  = constant_fields\ndotnet_naming_rule.constant_fields_should_be_pascal_case.style    = pascal_case_style\ndotnet_naming_symbols.constant_fields.applicable_kinds            = field\ndotnet_naming_symbols.constant_fields.applicable_accessibilities  = *\ndotnet_naming_symbols.constant_fields.required_modifiers          = const\ntab_width=2\ndotnet_naming_rule.private_members_with_underscore.symbols  = private_fields\ndotnet_naming_rule.private_members_with_underscore.style    = prefix_underscore\ndotnet_naming_rule.private_members_with_underscore.severity = suggestion\ndotnet_naming_symbols.private_fields.applicable_kinds           = field\ndotnet_naming_symbols.private_fields.applicable_accessibilities = private\ndotnet_naming_style.prefix_underscore.capitalization = camel_case\ndotnet_naming_style.prefix_underscore.required_prefix = _\n###############################\n# C# Coding Conventions       #\n###############################\n[*.cs]\n# var preferences\ncsharp_style_var_for_built_in_types = true:silent\ncsharp_style_var_when_type_is_apparent = true:silent\ncsharp_style_var_elsewhere = true:silent\n# Expression-bodied members\ncsharp_style_expression_bodied_methods = false:silent\ncsharp_style_expression_bodied_constructors = false:silent\ncsharp_style_expression_bodied_operators = false:silent\ncsharp_style_expression_bodied_properties = true:silent\ncsharp_style_expression_bodied_indexers = true:silent\ncsharp_style_expression_bodied_accessors = true:silent\n# Pattern matching preferences\ncsharp_style_pattern_matching_over_is_with_cast_check = true:suggestion\ncsharp_style_pattern_matching_over_as_with_null_check = true:suggestion\n# Null-checking preferences\ncsharp_style_throw_expression = true:suggestion\ncsharp_style_conditional_delegate_call = true:suggestion\n# Modifier preferences\ncsharp_preferred_modifier_order = public,private,protected,internal,static,extern,new,virtual,abstract,sealed,override,readonly,unsafe,volatile,async:suggestion\n# Expression-level preferences\ncsharp_prefer_braces = true:silent\ncsharp_style_deconstructed_variable_declaration = true:suggestion\ncsharp_prefer_simple_default_expression = true:suggestion\ncsharp_style_pattern_local_over_anonymous_function = true:suggestion\ncsharp_style_inlined_variable_declaration = true:suggestion\n# Namespaces\ncsharp_style_namespace_declarations = file_scoped:warning\n###############################\n# C# Formatting Rules         #\n###############################\n# New line preferences\ncsharp_new_line_before_open_brace = all\ncsharp_new_line_before_else = true\ncsharp_new_line_before_catch = true\ncsharp_new_line_before_finally = true\ncsharp_new_line_before_members_in_object_initializers = true\ncsharp_new_line_before_members_in_anonymous_types = true\ncsharp_new_line_between_query_expression_clauses = true\n# Indentation preferences\ncsharp_indent_case_contents = true\ncsharp_indent_switch_labels = true\ncsharp_indent_labels = flush_left\n# Space preferences\ncsharp_space_after_cast = false\ncsharp_space_after_keywords_in_control_flow_statements = true\ncsharp_space_between_method_call_parameter_list_parentheses = false\ncsharp_space_between_method_declaration_parameter_list_parentheses = false\ncsharp_space_between_parentheses = false\ncsharp_space_before_colon_in_inheritance_clause = true\ncsharp_space_after_colon_in_inheritance_clause = true\ncsharp_space_around_binary_operators = before_and_after\ncsharp_space_between_method_declaration_empty_parameter_list_parentheses = false\ncsharp_space_between_method_call_name_and_opening_parenthesis = false\ncsharp_space_between_method_call_empty_parameter_list_parentheses = false\n# Wrapping preferences\ncsharp_preserve_single_line_statements = true\ncsharp_preserve_single_line_blocks = true\n###############################\n# VB Coding Conventions       #\n###############################\n[*.vb]\n# Modifier preferences\nvisual_basic_preferred_modifier_order = Partial,Default,Private,Protected,Public,Friend,NotOverridable,Overridable,MustOverride,Overloads,Overrides,MustInherit,NotInheritable,Static,Shared,Shadows,ReadOnly,WriteOnly,Dim,Const,WithEvents,Widening,Narrowing,Custom,Async:suggestion"
  },
  {
    "path": "sample/.github/copilot-instructions.md",
    "content": "﻿# Solution Development Practices & Conventions\n\nThis document provides guidance for contributing to this solution, which is based on the Clean Architecture template for .NET 9. Follow these practices to ensure consistency, maintainability, and adherence to architectural principles.\n\n---\n\n## Table of Contents\n\n- [Architecture Overview](#architecture-overview)\n- [Project Structure](#project-structure)\n- [Development Patterns](#development-patterns)\n- [Use Case Guidelines](#use-case-guidelines)\n- [API Endpoint Conventions](#api-endpoint-conventions)\n- [Validation Strategy](#validation-strategy)\n- [Testing](#testing)\n- [File & Naming Conventions](#file--naming-conventions)\n- [Common Gotchas](#common-gotchas)\n- [Essential Commands](#essential-commands)\n\n---\n\n## Architecture Overview\n\n- Follows Clean Architecture and Domain-Driven Design (DDD) principles.\n- **Core** project contains domain models, value objects, and repository interfaces.\n- **UseCases** project contains application logic, commands, queries, and handlers.\n- **Infrastructure** project implements data access and external services.\n- **Web** project exposes API endpoints using FastEndpoints.\n\n**Dependency Flow:**  \n`Core` ← `UseCases` ← `Infrastructure`  \n`Core` ← `UseCases` ← `Web`  \n_Core must never depend on outer layers._\n\n---\n\n## Project Structure\n\n- **Core**: Domain entities, aggregates, value objects, domain events, repository interfaces.\n- **UseCases**: CQRS handlers (commands/queries), Mediator, application logic.\n- **Infrastructure**: EF Core, external services, repository implementations.\n- **Web**: FastEndpoints API, request/response/validator classes, REPR pattern.\n\n---\n\n## Development Patterns\n\n- **CQRS**: Use commands for mutations and queries for reads.\n- **Mediator**: All use case handlers implement Mediator interfaces.\n- **Repository Pattern**: Use repository interfaces from Core, implemented in Infrastructure.\n- **Value Objects**: Use for domain concepts (e.g., `ProjectName`, `ContributorId`).\n- **Domain Events**: Use for cross-aggregate communication.\n\n---\n\n## Use Case Guidelines\n\n- **Inputs/Outputs**: Use Value Objects (`ProjectName`, `ContributorId`) for use case command/query parameters and return types. Use value objects internally within the domain. Translate from primitives in the endpoints.\n- **Validation**: Validate at API and use case boundaries; enforce business invariants in the domain.\n- **Error Handling**: Use `Ardalis.Result<T>` for use case results and error propagation.\n- **Defensive Coding**: Validate commands/queries in handlers; assume pre-validated input in domain. Use `Ardalis.GuardClauses` to defend against invalid states in the domain.\n\n---\n\n## API Endpoint Conventions\n\n- One endpoint per file (e.g., `Create.cs`, `Update.cs`).\n- Separate files for request, response, and validator (e.g., `Create.CreateRequest.cs`, `Create.CreateResponse.cs`, `Create.CreateValidator.cs`).\n- Endpoints inherit from `Endpoint<TRequest, TResponse>`.\n- Use REPR (Request/Endpoint/Processor/Response) pattern.\n\n---\n\n## Validation Strategy\n\n- **API Level**: Use FluentValidation for request DTOs.\n- **Use Case Level**: Validate commands/queries in handlers or behaviors.\n- **Domain Level**: Throw exceptions for business rule violations using guard clauses (e.g., `Ardalis.GuardClauses`).)\n\n---\n\n## Testing\n\n- **UnitTests**: Test domain logic and use cases.\n- **IntegrationTests**: Test infrastructure and database interactions.\n- **FunctionalTests**: Test API endpoints using subcutaneous testing.\n\n---\n\n## File & Naming Conventions\n\n- Use PascalCase for files, classes, and methods.\n- Organize files by feature (e.g., `Contributors/Create.cs`, `Projects/Create.cs`).\n- Place request, response, and validator files alongside their endpoint.\n- Do not use hyphens in project or file names.\n- Test classes are named for the class and method being tested. Examples: `ProjectAddItem` or `CreateContributorHandlerHandle`.\n- Test methods are named such that the class name and method name form a sentence describing the test. (e.g. `ReturnsItemGivenValidInputs()` or `ThrowsExceptionGivenNegativeInput()`)\n\n---\n\n## Common Gotchas\n\n- Do not allow Core to reference UseCases, Infrastructure, or Web.\n- Use absolute paths for EF Core migration commands.\n"
  },
  {
    "path": "sample/.runsettings",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<RunSettings>\n  <RunConfiguration>\n    <MaxCpuCount>0</MaxCpuCount> <!-- 0 = use all available cores -->\n  </RunConfiguration>\n</RunSettings>\n"
  },
  {
    "path": "sample/Directory.Build.props",
    "content": "<Project>\n  <PropertyGroup>\n    <ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>\n    <TreatWarningsAsErrors>true</TreatWarningsAsErrors>\n    <TargetFramework>net10.0</TargetFramework>\n    <Nullable>enable</Nullable>\n    <ImplicitUsings>enable</ImplicitUsings>\n  </PropertyGroup>\n  <PropertyGroup>\n    <NoWarn>1591</NoWarn> <!-- Remove this to turn on warnings for missing XML Comments -->\n  </PropertyGroup>\n</Project>"
  },
  {
    "path": "sample/Directory.Packages.props",
    "content": "<Project>\n  <ItemGroup>\n    <PackageVersion Include=\"Ardalis.GuardClauses\" Version=\"5.0.0\" />\n    <PackageVersion Include=\"Ardalis.HttpClientTestExtensions\" Version=\"4.2.0\" />\n    <PackageVersion Include=\"Ardalis.ListStartupServices\" Version=\"1.1.4\" />\n    <PackageVersion Include=\"Ardalis.Result\" Version=\"10.1.0\" />\n    <PackageVersion Include=\"Ardalis.Result.AspNetCore\" Version=\"10.1.0\" />\n    <PackageVersion Include=\"Ardalis.SmartEnum\" Version=\"8.2.0\" />\n    <PackageVersion Include=\"Ardalis.Specification\" Version=\"9.3.1\" />\n    <PackageVersion Include=\"Ardalis.Specification.EntityFrameworkCore\" Version=\"9.3.1\" />\n    <PackageVersion Include=\"AspNetCore.Localizer.Json\" Version=\"1.0.2\" />\n    <PackageVersion Include=\"Azure.Identity\" Version=\"1.13.1\" />\n    <PackageVersion Include=\"coverlet.collector\" Version=\"6.0.4\" />\n    <PackageVersion Include=\"FastEndpoints\" Version=\"7.0.1\" />\n    <PackageVersion Include=\"FastEndpoints.ApiExplorer\" Version=\"2.3.0\" />\n    <PackageVersion Include=\"FastEndpoints.Swagger\" Version=\"7.0.1\" />\n    <PackageVersion Include=\"FastEndpoints.Swagger.Swashbuckle\" Version=\"2.3.0\" />\n    <PackageVersion Include=\"FluentValidation\" Version=\"12.0.0\" />\n    <PackageVersion Include=\"FluentValidation.DependencyInjectionExtensions\" Version=\"12.0.0\" />\n    <PackageVersion Include=\"MailKit\" Version=\"4.14.0\" />\n    <PackageVersion Include=\"Mediator.Abstractions\" Version=\"3.0.1\" />\n    <PackageVersion Include=\"Mediator.SourceGenerator\" Version=\"3.0.1\" />\n    <PackageVersion Include=\"Microsoft.AspNetCore.Mvc.NewtonsoftJson\" Version=\"9.0.9\" />\n    <PackageVersion Include=\"Microsoft.AspNetCore.Mvc.Testing\" Version=\"9.0.9\" />\n    <PackageVersion Include=\"Microsoft.EntityFrameworkCore.InMemory\" Version=\"9.0.9\" />\n    <PackageVersion Include=\"Microsoft.EntityFrameworkCore.Relational\" Version=\"9.0.9\" />\n    <PackageVersion Include=\"Microsoft.EntityFrameworkCore.Design\" Version=\"9.0.8\" />\n    <PackageVersion Include=\"Microsoft.EntityFrameworkCore.Tools\" Version=\"9.0.9\" />\n    <PackageVersion Include=\"Microsoft.EntityFrameworkCore.Sqlite\" Version=\"9.0.9\" />\n    <PackageVersion Include=\"Microsoft.EntityFrameworkCore.SqlServer\" Version=\"9.0.9\" />\n    <PackageVersion Include=\"Microsoft.Extensions.Configuration\" Version=\"9.0.0\" />\n    <PackageVersion Include=\"Microsoft.Extensions.Localization\" Version=\"9.0.9\" />\n    <PackageVersion Include=\"Microsoft.Extensions.Logging\" Version=\"9.0.0\" />\n    <PackageVersion Include=\"Microsoft.Extensions.Logging.Abstractions\" Version=\"9.0.9\" />\n    <PackageVersion Include=\"Microsoft.Extensions.Options.ConfigurationExtensions\" Version=\"9.0.0\" />\n    <PackageVersion Include=\"Microsoft.NET.Test.Sdk\" Version=\"18.0.0\" />\n    <PackageVersion Include=\"Newtonsoft.Json\" Version=\"13.0.4\" />\n    <PackageVersion Include=\"NimblePros.Metronome\" Version=\"0.4.1\" />\n    <PackageVersion Include=\"NimblePros.SharedKernel\" Version=\"3.1.0\" />\n    <PackageVersion Include=\"NSubstitute\" Version=\"5.3.0\" />\n    <PackageVersion Include=\"ReportGenerator\" Version=\"5.4.16\" />\n    <PackageVersion Include=\"Serilog.AspNetCore\" Version=\"9.0.0\" />\n    <PackageVersion Include=\"Serilog.Sinks.ApplicationInsights\" Version=\"4.0.0\" />\n    <PackageVersion Include=\"Serilog.Sinks.OpenTelemetry\" Version=\"4.2.0\" />\n    <PackageVersion Include=\"Shouldly\" Version=\"4.3.0\" />\n    <PackageVersion Include=\"SQLite\" Version=\"3.13.0\" />\n    <PackageVersion Include=\"Swashbuckle.AspNetCore\" Version=\"6.5.0\" />\n    <PackageVersion Include=\"Swashbuckle.AspNetCore.Annotations\" Version=\"6.5.0\" />\n    <PackageVersion Include=\"Testcontainers\" Version=\"4.7.0\" />\n    <PackageVersion Include=\"Vogen\" Version=\"8.0.2\" />\n    <PackageVersion Include=\"xunit\" Version=\"2.9.3\" />\n    <PackageVersion Include=\"xunit.runner.visualstudio\" Version=\"3.1.5\" />\n    <PackageVersion Include=\"Aspire.Hosting.AppHost\" Version=\"9.5.1\" />\n    <PackageVersion Include=\"Microsoft.Extensions.Http.Resilience\" Version=\"9.9.0\" />\n    <PackageVersion Include=\"Microsoft.Extensions.ServiceDiscovery\" Version=\"9.5.0\" />\n    <PackageVersion Include=\"OpenTelemetry.Exporter.OpenTelemetryProtocol\" Version=\"1.13.0\" />\n    <PackageVersion Include=\"OpenTelemetry.Extensions.Hosting\" Version=\"1.13.0\" />\n    <PackageVersion Include=\"OpenTelemetry.Instrumentation.AspNetCore\" Version=\"1.12.0\" />\n    <PackageVersion Include=\"OpenTelemetry.Instrumentation.Http\" Version=\"1.12.0\" />\n    <PackageVersion Include=\"OpenTelemetry.Instrumentation.Runtime\" Version=\"1.12.0\" />\n    <PackageVersion Include=\"Aspire.Hosting.Testing\" Version=\"9.0.0\" />\n  </ItemGroup>\n</Project>"
  },
  {
    "path": "sample/NimblePros.SampleToDo.slnx",
    "content": "<Solution>\n  <Configurations>\n    <Platform Name=\"Any CPU\" />\n    <Platform Name=\"x64\" />\n    <Platform Name=\"x86\" />\n  </Configurations>\n  <Folder Name=\"/Solution Items/\">\n    <File Path=\".editorconfig\" />\n    <File Path=\"CleanArchitecture.nuspec\" />\n    <File Path=\"Directory.Build.props\" />\n    <File Path=\"Directory.Packages.props\" />\n  </Folder>\n  <Folder Name=\"/src/\">\n    <Project Path=\"src/NimblePros.SampleToDo.AspireHost/NimblePros.SampleToDo.AspireHost.csproj\" />\n    <Project Path=\"src/NimblePros.SampleToDo.Core/NimblePros.SampleToDo.Core.csproj\" />\n    <Project Path=\"src/NimblePros.SampleToDo.Infrastructure/NimblePros.SampleToDo.Infrastructure.csproj\" />\n    <Project Path=\"src/NimblePros.SampleToDo.ServiceDefaults/NimblePros.SampleToDo.ServiceDefaults.csproj\" />\n    <Project Path=\"src/NimblePros.SampleToDo.UseCases/NimblePros.SampleToDo.UseCases.csproj\" />\n    <Project Path=\"src/NimblePros.SampleToDo.Web/NimblePros.SampleToDo.Web.csproj\" />\n  </Folder>\n  <Folder Name=\"/tests/\">\n    <Project Path=\"tests/NimblePros.SampleToDo.FunctionalTests/NimblePros.SampleToDo.FunctionalTests.csproj\">\n      <BuildDependency Project=\"src/NimblePros.SampleToDo.Web/NimblePros.SampleToDo.Web.csproj\" />\n    </Project>\n    <Project Path=\"tests/NimblePros.SampleToDo.IntegrationTests/NimblePros.SampleToDo.IntegrationTests.csproj\">\n      <BuildDependency Project=\"src/NimblePros.SampleToDo.Infrastructure/NimblePros.SampleToDo.Infrastructure.csproj\" />\n    </Project>\n    <Project Path=\"tests/NimblePros.SampleToDo.UnitTests/NimblePros.SampleToDo.UnitTests.csproj\" />\n  </Folder>\n</Solution>\n"
  },
  {
    "path": "sample/src/NimblePros.SampleToDo.AspireHost/NimblePros.SampleToDo.AspireHost.csproj",
    "content": "<Project Sdk=\"Microsoft.NET.Sdk\">\n\n  <Sdk Name=\"Aspire.AppHost.Sdk\" Version=\"9.5.1\" />\n\n  <PropertyGroup>\n    <OutputType>Exe</OutputType>\n    <IsAspireHost>true</IsAspireHost>\n    <UserSecretsId>c540eeb6-e06b-4456-a539-be58dd8b88c7</UserSecretsId>\n  </PropertyGroup>\n\n  <ItemGroup>\n    <PackageReference Include=\"Aspire.Hosting.AppHost\" />\n  </ItemGroup>\n\n  <ItemGroup>\n    <ProjectReference Include=\"..\\NimblePros.SampleToDo.Web\\NimblePros.SampleToDo.Web.csproj\" />\n  </ItemGroup>\n  <ItemGroup>\n    <!-- The IsAspireProjectResource attribute tells .NET Aspire to treat this \n        reference as a standard project reference and not attempt to generate\n        a metadata file -->\n    <ProjectReference Include=\"..\\NimblePros.SampleToDo.ServiceDefaults\\NimblePros.SampleToDo.ServiceDefaults.csproj\"\n                      IsAspireProjectResource=\"false\" />\n  </ItemGroup>\n\n</Project>\n"
  },
  {
    "path": "sample/src/NimblePros.SampleToDo.AspireHost/Program.cs",
    "content": "﻿using System.Net.Sockets;\n\nvar builder = DistributedApplication.CreateBuilder(args);\n\n// Papercut container\nvar papercut = builder.AddContainer(\"papercut\", \"jijiechen/papercut\", \"latest\")\n  .WithEndpoint(\"smtp\", e =>\n  {\n    e.TargetPort = 25;   // container port\n    e.Port = 25;         // host port (optional—omit to auto-assign)\n    e.Protocol = ProtocolType.Tcp;\n    e.UriScheme = \"smtp\"; // makes the resolved value look like smtp://host:port\n  })\n  .WithEndpoint(\"ui\", e =>\n  {\n    e.TargetPort = 37408;\n    e.Port = 37408;      // optional – Aspire can allocate\n    e.UriScheme = \"http\";\n  });\n\n// Your web project\nvar web = builder.AddProject<Projects.NimblePros_SampleToDo_Web>(\"web\")\n    .WithHttpHealthCheck(\"/health\")\n    // Pass the endpoints to the app via env vars (EndpointReference resolves to a URL at run time)\n    .WithEnvironment(\"Papercut__Smtp__Url\", papercut.GetEndpoint(\"smtp\"))\n    .WithEnvironment(\"Papercut__Ui__Url\", papercut.GetEndpoint(\"ui\"));\n\n// (optionally) if your app wants separate host/port values, you can parse the URL at startup,\n// or expose two env vars and parse them from the URL inside the app.\n\nbuilder.Build().Run();\n"
  },
  {
    "path": "sample/src/NimblePros.SampleToDo.AspireHost/Properties/launchSettings.json",
    "content": "{\n  \"$schema\": \"https://json.schemastore.org/launchsettings.json\",\n  \"profiles\": {\n    \"https\": {\n      \"commandName\": \"Project\",\n      \"dotnetRunMessages\": true,\n      \"launchBrowser\": true,\n      \"applicationUrl\": \"https://localhost:17143;http://localhost:15258\",\n      \"environmentVariables\": {\n        \"ASPNETCORE_ENVIRONMENT\": \"Development\",\n        \"DOTNET_ENVIRONMENT\": \"Development\",\n        \"DOTNET_DASHBOARD_OTLP_ENDPOINT_URL\": \"https://localhost:21007\",\n        \"DOTNET_RESOURCE_SERVICE_ENDPOINT_URL\": \"https://localhost:22245\"\n      }\n    },\n    \"http\": {\n      \"commandName\": \"Project\",\n      \"dotnetRunMessages\": true,\n      \"launchBrowser\": true,\n      \"applicationUrl\": \"http://localhost:15258\",\n      \"environmentVariables\": {\n        \"ASPNETCORE_ENVIRONMENT\": \"Development\",\n        \"DOTNET_ENVIRONMENT\": \"Development\",\n        \"DOTNET_DASHBOARD_OTLP_ENDPOINT_URL\": \"http://localhost:19187\",\n        \"DOTNET_RESOURCE_SERVICE_ENDPOINT_URL\": \"http://localhost:20134\"\n      }\n    }\n  }\n}\n"
  },
  {
    "path": "sample/src/NimblePros.SampleToDo.AspireHost/appsettings.Development.json",
    "content": "{\n  \"Logging\": {\n    \"LogLevel\": {\n      \"Default\": \"Information\",\n      \"Microsoft.AspNetCore\": \"Warning\"\n    }\n  }\n}\n"
  },
  {
    "path": "sample/src/NimblePros.SampleToDo.AspireHost/appsettings.json",
    "content": "{\n  \"Logging\": {\n    \"LogLevel\": {\n      \"Default\": \"Information\",\n      \"Microsoft.AspNetCore\": \"Warning\",\n      \"Aspire.Hosting.Dcp\": \"Warning\"\n    }\n  }\n}\n"
  },
  {
    "path": "sample/src/NimblePros.SampleToDo.Core/ContributorAggregate/Contributor.cs",
    "content": "﻿using NimblePros.SampleToDo.Core.ContributorAggregate.Events;\n\nnamespace NimblePros.SampleToDo.Core.ContributorAggregate;\n\npublic sealed class Contributor : EntityBase<Contributor, ContributorId>, IAggregateRoot\n{\n  public ContributorName Name { get; private set; }\n\n  public Contributor(ContributorName name)\n  {\n      Name = name;\n  }\n\n  public Contributor UpdateName(ContributorName newName)\n  {\n    if (Name.Equals(newName)) return this;\n    Name = newName;\n    this.RegisterDomainEvent(new ContributorNameUpdatedEvent(this));\n    return this;\n  }\n}\n\n"
  },
  {
    "path": "sample/src/NimblePros.SampleToDo.Core/ContributorAggregate/ContributorId.cs",
    "content": "﻿using Vogen;\n\nnamespace NimblePros.SampleToDo.Core.ContributorAggregate;\n\n[ValueObject<int>]\npublic partial struct ContributorId\n{\n    private static Validation Validate(int value)\n        => value > 0 ? Validation.Ok : Validation.Invalid(\"ContributorId must be positive.\");\n}\n\n"
  },
  {
    "path": "sample/src/NimblePros.SampleToDo.Core/ContributorAggregate/ContributorName.cs",
    "content": "﻿using Vogen;\n\nnamespace NimblePros.SampleToDo.Core.ContributorAggregate;\n\n[ValueObject<string>(conversions: Conversions.SystemTextJson)]\npublic partial struct ContributorName\n{\n  public const int MaxLength = 100;\n  private static Validation Validate(in string name) =>\n    string.IsNullOrEmpty(name)\n      ? Validation.Invalid(\"Name cannot be empty\")\n      : name.Length > MaxLength\n        ? Validation.Invalid($\"Name cannot be longer than {MaxLength} characters\")\n        : Validation.Ok;\n}\n"
  },
  {
    "path": "sample/src/NimblePros.SampleToDo.Core/ContributorAggregate/Events/ContributorDeletedEvent.cs",
    "content": "﻿namespace NimblePros.SampleToDo.Core.ContributorAggregate.Events;\n\n/// <summary>\n/// A domain event that is dispatched whenever a contributor is deleted.\n/// The DeleteContributorService is used to dispatch this event.\n/// </summary>\npublic sealed class ContributorDeletedEvent(ContributorId contributorId) : DomainEventBase\n{\n  public ContributorId ContributorId { get; private set; } = contributorId;\n}\n"
  },
  {
    "path": "sample/src/NimblePros.SampleToDo.Core/ContributorAggregate/Events/ContributorNameUpdatedEvent.cs",
    "content": "﻿namespace NimblePros.SampleToDo.Core.ContributorAggregate.Events;\n\npublic sealed class ContributorNameUpdatedEvent(Contributor contributor) : DomainEventBase\n{\n  public Contributor Contributor { get; private set; } = contributor;\n}\n"
  },
  {
    "path": "sample/src/NimblePros.SampleToDo.Core/ContributorAggregate/Handlers/ContributorDeletedHandler.cs",
    "content": "﻿using Microsoft.Extensions.Logging;\nusing NimblePros.SampleToDo.Core.ContributorAggregate.Events;\nusing NimblePros.SampleToDo.Core.ProjectAggregate;\nusing NimblePros.SampleToDo.Core.ProjectAggregate.Specifications;\n\nnamespace NimblePros.SampleToDo.Core.ContributorAggregate.Handlers;\n\npublic class ContributorDeletedHandler : INotificationHandler<ContributorDeletedEvent>\n{\n  private readonly IRepository<Project> _repository;\n  private readonly ILogger<ContributorDeletedHandler> _logger;\n\n  public ContributorDeletedHandler(IRepository<Project> repository,\n    ILogger<ContributorDeletedHandler> logger)\n  {\n    _repository = repository;\n    _logger = logger;\n  }\n\n  public async ValueTask Handle(ContributorDeletedEvent domainEvent, CancellationToken cancellationToken)\n  {\n    _logger.LogInformation(\"Removing deleted contributor {contributorId} from all projects...\", domainEvent.ContributorId);\n    // Perform eventual consistency removal of contributors from projects when one is deleted\n    var projectSpec = new ProjectsWithItemsByContributorIdSpec(domainEvent.ContributorId);\n    var projects = await _repository.ListAsync(projectSpec, cancellationToken);\n    foreach (var project in projects)\n    {\n      project.Items\n        .Where(item => item.ContributorId == domainEvent.ContributorId)\n        .ToList()\n        .ForEach(item => item.RemoveContributor());\n      await _repository.UpdateAsync(project, cancellationToken);\n    }\n  }\n}\n"
  },
  {
    "path": "sample/src/NimblePros.SampleToDo.Core/ContributorAggregate/Handlers/ContributorNameUpdatedEventLoggingHandler.cs",
    "content": "﻿using Microsoft.Extensions.Logging;\nusing NimblePros.SampleToDo.Core.ContributorAggregate.Events;\n\nnamespace NimblePros.SampleToDo.Core.ContributorAggregate.Handlers;\n\npublic class ContributorNameUpdatedEventLoggingHandler(ILogger<ContributorNameUpdatedEventLoggingHandler> logger) :\n  INotificationHandler<ContributorNameUpdatedEvent>\n{\n  private readonly ILogger<ContributorNameUpdatedEventLoggingHandler> _logger = logger;\n\n  public ValueTask Handle(ContributorNameUpdatedEvent notification, CancellationToken cancellationToken)\n  {\n    var contributorId = notification.Contributor.Id;\n    string newName = notification.Contributor.Name.Value;\n    _logger.LogInformation(\"Contributor {contributorId}'s name was updated to {newName}\", contributorId, newName);\n    return ValueTask.CompletedTask;\n  }\n}\n"
  },
  {
    "path": "sample/src/NimblePros.SampleToDo.Core/ContributorAggregate/Specifications/ContributorByIdSpec.cs",
    "content": "﻿namespace NimblePros.SampleToDo.Core.ContributorAggregate.Specifications;\n\npublic class ContributorByIdSpec : Specification<Contributor>, ISingleResultSpecification<Contributor>\n{\n  public ContributorByIdSpec(ContributorId contributorId)\n  {\n    Query\n        .Where(contributor => contributor.Id == contributorId);\n  }\n}\n"
  },
  {
    "path": "sample/src/NimblePros.SampleToDo.Core/CoreServiceExtensions.cs",
    "content": "﻿using Microsoft.Extensions.DependencyInjection;\nusing Microsoft.Extensions.Logging;\nusing NimblePros.SampleToDo.Core.Interfaces;\nusing NimblePros.SampleToDo.Core.Services;\n\nnamespace NimblePros.SampleToDo.Core;\n\npublic static class CoreServiceExtensions\n{\n  public static IServiceCollection AddCoreServices(this IServiceCollection services, ILogger logger)\n  {\n    services.AddScoped<IToDoItemSearchService, ToDoItemSearchService>();\n    services.AddScoped<IDeleteContributorService, DeleteContributorService>();\n    \n    logger.LogInformation(\"{Project} services registered\", \"Core\");\n\n    return services;\n  }\n}\n"
  },
  {
    "path": "sample/src/NimblePros.SampleToDo.Core/GlobalUsings.cs",
    "content": "﻿global using Ardalis.GuardClauses;\nglobal using Ardalis.Result;\nglobal using Ardalis.SmartEnum;\nglobal using Ardalis.Specification;\nglobal using Mediator;\nglobal using NimblePros.SharedKernel;\n"
  },
  {
    "path": "sample/src/NimblePros.SampleToDo.Core/Interfaces/IDeleteContributorService.cs",
    "content": "﻿using NimblePros.SampleToDo.Core.ContributorAggregate;\n\nnamespace NimblePros.SampleToDo.Core.Interfaces;\n\npublic interface IDeleteContributorService\n{\n  // This service and method exist to provide a place in which to fire domain events\n  // when deleting this aggregate root entity\n  public Task<Result> DeleteContributor(ContributorId contributorId);\n}\n"
  },
  {
    "path": "sample/src/NimblePros.SampleToDo.Core/Interfaces/IEmailSender.cs",
    "content": "﻿namespace NimblePros.SampleToDo.Core.Interfaces;\n\npublic interface IEmailSender\n{\n  Task SendEmailAsync(string to, string from, string subject, string body);\n}\n"
  },
  {
    "path": "sample/src/NimblePros.SampleToDo.Core/Interfaces/IToDoItemSearchService.cs",
    "content": "﻿using NimblePros.SampleToDo.Core.ProjectAggregate;\n\nnamespace NimblePros.SampleToDo.Core.Interfaces;\n\npublic interface IToDoItemSearchService\n{\n  Task<Result<ToDoItem>> GetNextIncompleteItemAsync(ProjectId projectId);\n  Task<Result<List<ToDoItem>>> GetAllIncompleteItemsAsync(ProjectId projectId, string searchString);\n}\n"
  },
  {
    "path": "sample/src/NimblePros.SampleToDo.Core/Localization.cs",
    "content": "﻿using Microsoft.Extensions.Localization;\n\n/// <summary>\n/// Exposes the current <see cref=\"IStringLocalizer\"/> to static code\n/// (Vogen Validate, domain events, etc.) without pulling the whole\n/// DI container into Core.\n/// </summary>\npublic static class Localization\n{\n  /// <summary>\n  /// Set by <c>Program.cs</c> during app startup.\n  /// </summary>\n  public static ILocalizationContext? Current { get; set; }\n\n  public sealed class LocalizationContext : ILocalizationContext\n  {\n    public IStringLocalizer Localizer { get; }\n\n    public LocalizationContext(IStringLocalizer localizer) =>\n        Localizer = localizer;\n  }\n}\n\npublic interface ILocalizationContext\n{\n  IStringLocalizer Localizer { get; }\n}\n"
  },
  {
    "path": "sample/src/NimblePros.SampleToDo.Core/NimblePros.SampleToDo.Core.csproj",
    "content": "﻿<Project Sdk=\"Microsoft.NET.Sdk\">\n  <ItemGroup>\n    <PackageReference Include=\"Ardalis.GuardClauses\" />\n    <PackageReference Include=\"Ardalis.Result\" />\n    <PackageReference Include=\"Ardalis.SmartEnum\" />\n    <PackageReference Include=\"Ardalis.Specification\" />\n    <PackageReference Include=\"Mediator.Abstractions\" />\n    <PackageReference Include=\"Microsoft.Extensions.Localization\" />\n    <PackageReference Include=\"Microsoft.Extensions.Logging.Abstractions\" />\n    <PackageReference Include=\"NimblePros.SharedKernel\" />\n    <PackageReference Include=\"Vogen\" />\n  </ItemGroup>\n\n</Project>\n"
  },
  {
    "path": "sample/src/NimblePros.SampleToDo.Core/ProjectAggregate/Events/ContributorAddedToItemEvent.cs",
    "content": "﻿using NimblePros.SampleToDo.Core.ContributorAggregate;\n\nnamespace NimblePros.SampleToDo.Core.ProjectAggregate.Events;\n\npublic sealed class ContributorAddedToItemEvent(ToDoItem item, ContributorId contributorId) : DomainEventBase\n{\n  public ContributorId ContributorId { get; set; } = contributorId;\n  public ToDoItem Item { get; set; } = item;\n\n}\n"
  },
  {
    "path": "sample/src/NimblePros.SampleToDo.Core/ProjectAggregate/Events/NewItemAddedEvent.cs",
    "content": "﻿namespace NimblePros.SampleToDo.Core.ProjectAggregate.Events;\n\npublic sealed class NewItemAddedEvent(Project project, ToDoItem newItem) : DomainEventBase\n{\n  public Project Project { get; private set; } = project;\n  public ToDoItem NewItem { get; private set; } = newItem;\n}\n"
  },
  {
    "path": "sample/src/NimblePros.SampleToDo.Core/ProjectAggregate/Events/ToDoItemCompletedEvent.cs",
    "content": "﻿namespace NimblePros.SampleToDo.Core.ProjectAggregate.Events;\n\npublic sealed class ToDoItemCompletedEvent(ToDoItem completedItem) : DomainEventBase\n{\n  public ToDoItem CompletedItem { get; private set; } = completedItem;\n}\n"
  },
  {
    "path": "sample/src/NimblePros.SampleToDo.Core/ProjectAggregate/Handlers/ContributorAddedToItemLoggingHandler.cs",
    "content": "﻿using Microsoft.Extensions.Logging;\nusing NimblePros.SampleToDo.Core.ProjectAggregate.Events;\n\nnamespace NimblePros.SampleToDo.Core.ProjectAggregate.Handlers;\n\npublic class ContributorAddedToItemLoggingHandler(ILogger<ContributorAddedToItemLoggingHandler> logger)\n  : INotificationHandler<ContributorAddedToItemEvent>\n{\n  private readonly ILogger<ContributorAddedToItemLoggingHandler> _logger = logger;\n\n  public ValueTask Handle(ContributorAddedToItemEvent notification, CancellationToken cancellationToken)\n  {\n    _logger.LogInformation(\"Contributor {ContributorId} assigned to ToDo item {Item}\", notification.ContributorId,  notification.Item);\n    return default;\n  }\n}\n"
  },
  {
    "path": "sample/src/NimblePros.SampleToDo.Core/ProjectAggregate/Handlers/ItemCompletedEmailNotificationHandler.cs",
    "content": "﻿using NimblePros.SampleToDo.Core.Interfaces;\nusing NimblePros.SampleToDo.Core.ProjectAggregate.Events;\n\nnamespace NimblePros.SampleToDo.Core.ProjectAggregate.Handlers;\n\npublic class ItemCompletedEmailNotificationHandler : Mediator.INotificationHandler<ToDoItemCompletedEvent>\n{\n  private readonly IEmailSender _emailSender;\n\n  // In a REAL app you might want to use the Outbox pattern and a command/queue here...\n  public ItemCompletedEmailNotificationHandler(IEmailSender emailSender)\n  {\n    _emailSender = emailSender;\n  }\n\n  // configure a test email server to demo this works\n  // https://ardalis.com/configuring-a-local-test-email-server\n  public async ValueTask Handle(ToDoItemCompletedEvent domainEvent, \n    CancellationToken cancellationToken)\n  {\n    Guard.Against.Null(domainEvent, nameof(domainEvent));\n\n    await _emailSender.SendEmailAsync(\"test@test.com\", \"test@test.com\",\n      $\"{domainEvent.CompletedItem.Title} was completed.\",\n      domainEvent.CompletedItem.ToString());\n  }\n}\n"
  },
  {
    "path": "sample/src/NimblePros.SampleToDo.Core/ProjectAggregate/Handlers/NewItemAddedLoggingHandler.cs",
    "content": "﻿using Microsoft.Extensions.Logging;\nusing NimblePros.SampleToDo.Core.ProjectAggregate.Events;\n\nnamespace NimblePros.SampleToDo.Core.ProjectAggregate.Handlers;\n\npublic class NewItemAddedLoggingHandler(ILogger<NewItemAddedLoggingHandler> logger)\n  : INotificationHandler<NewItemAddedEvent>\n{\n  private readonly ILogger<NewItemAddedLoggingHandler> _logger = logger;\n\n  public ValueTask Handle(NewItemAddedEvent notification, CancellationToken cancellationToken)\n  {\n    _logger.LogInformation(\"New Item {Item} added to Project {Project}\", notification.NewItem,  notification.Project);\n    return default;\n  }\n}\n"
  },
  {
    "path": "sample/src/NimblePros.SampleToDo.Core/ProjectAggregate/Priority.cs",
    "content": "﻿namespace NimblePros.SampleToDo.Core.ProjectAggregate;\n\npublic class Priority : SmartEnum<Priority>\n{\n  public static readonly Priority Backlog = new(nameof(Backlog), 0);\n  public static readonly Priority Critical = new(nameof(Critical), 1);\n\n  protected Priority(string name, int value) : base(name, value) { }\n}\n"
  },
  {
    "path": "sample/src/NimblePros.SampleToDo.Core/ProjectAggregate/Project.cs",
    "content": "﻿using NimblePros.SampleToDo.Core.ContributorAggregate.Events;\nusing NimblePros.SampleToDo.Core.ProjectAggregate.Events;\n\nnamespace NimblePros.SampleToDo.Core.ProjectAggregate;\n\npublic class Project : EntityBase<Project, ProjectId>, IAggregateRoot\n{\n  public ProjectName Name { get; private set; }\n\n  private readonly List<ToDoItem> _items = [];\n  public IEnumerable<ToDoItem> Items => _items.AsReadOnly();\n  public ProjectStatus Status => _items.All(i => i.IsDone) ? ProjectStatus.Complete : ProjectStatus.InProgress;\n\n  public Project(ProjectName name)\n  {\n    Name = name;\n  }\n\n  public Project AddItem(ToDoItem newItem)\n  {\n    Guard.Against.Null(newItem);\n    _items.Add(newItem);\n\n    var newItemAddedEvent = new NewItemAddedEvent(this, newItem);\n    base.RegisterDomainEvent(newItemAddedEvent);\n    return this;\n  }\n\n  public Project UpdateName(ProjectName newName)\n  {\n    if (Name.Equals(newName)) return this;\n    Name = newName;\n    return this;\n  }\n}\n"
  },
  {
    "path": "sample/src/NimblePros.SampleToDo.Core/ProjectAggregate/ProjectErrorMessages.cs",
    "content": "﻿// Core/ProjectAggregate/ProjectMessages.cs\nnamespace NimblePros.SampleToDo.Core.ProjectAggregate;\n\n/// <summary>\n/// Strongly-typed, localisable message accessors for the Project aggregate.\n/// The implementation is deliberately **static** so it can be called from Vogen’s\n/// static <c>Validate</c> method.\n/// </summary>\npublic static class ProjectErrorMessages\n{\n  // -----------------------------------------------------------------\n  // 1. Public entry points – these are what you call from the domain\n  // -----------------------------------------------------------------\n  public static string CoreProjectNameEmpty => Get(nameof(CoreProjectNameEmpty));\n  public static string CoreProjectNameTooLong(int maxLength) => Get(nameof(CoreProjectNameTooLong), maxLength);\n  public static string CoreToDoItemDescriptionEmpty => Get(nameof(CoreToDoItemDescriptionEmpty));\n  public static string CoreToDoItemDescriptionTooLong(int maxLength) => Get(nameof(CoreToDoItemDescriptionTooLong), maxLength);\n  public static string CoreToDoItemTitleEmpty => Get(nameof(CoreToDoItemTitleEmpty));\n  public static string CoreToDoItemTitleTooLong(int maxLength) => Get(nameof(CoreToDoItemTitleTooLong), maxLength);\n\n  // -----------------------------------------------------------------\n  // 2. Private helper that forwards to the current localizer\n  // -----------------------------------------------------------------\n  private static string Get(string key, params object[] args)\n  {\n    // The static holder is set once in Program.cs (Web project)\n    var localizer = Localization.Current?.Localizer;\n\n    if (localizer is not null)\n    {\n      // Uses the standard {0}, {1}… placeholders defined in JSON/RESX\n      var localized = localizer[key, args];\n      return localized.ResourceNotFound ? Fallback(key, args) : localized;\n    }\n\n    // No DI container available (e.g. unit-tests) → fallback to English\n    return Fallback(key, args);\n  }\n\n  // -----------------------------------------------------------------\n  // 3. Hard-coded English fallback (never throws, always returns a string)\n  // -----------------------------------------------------------------\n  private static string Fallback(string key, object[] args) => key switch\n  {\n    nameof(CoreProjectNameEmpty) => \"Name cannot be empty\",\n    nameof(CoreProjectNameTooLong) => FormattableString.Invariant($\"Name cannot be longer than {args[0]} characters\"),\n    nameof(CoreToDoItemDescriptionEmpty) => \"Description cannot be empty\",\n    nameof(CoreToDoItemDescriptionTooLong) => FormattableString.Invariant($\"Description cannot be longer than {args[0]} characters\"),\n    nameof(CoreToDoItemTitleEmpty) => \"Title cannot be empty\",\n    nameof(CoreToDoItemTitleTooLong) => FormattableString.Invariant($\"Title cannot be longer than {args[0]} characters\"),\n    _ => $\"[{key}]\"\n  };\n}\n"
  },
  {
    "path": "sample/src/NimblePros.SampleToDo.Core/ProjectAggregate/ProjectId.cs",
    "content": "﻿using Vogen;\nnamespace NimblePros.SampleToDo.Core.ProjectAggregate;\n\n[ValueObject<int>]\npublic partial struct ProjectId;\n"
  },
  {
    "path": "sample/src/NimblePros.SampleToDo.Core/ProjectAggregate/ProjectName.cs",
    "content": "﻿using Vogen;\n\n[assembly: VogenDefaults(\n        staticAbstractsGeneration: StaticAbstractsGeneration.MostCommon | StaticAbstractsGeneration.InstanceMethodsAndProperties)]\n\n\nnamespace NimblePros.SampleToDo.Core.ProjectAggregate;\n\n// NOTE: Structs do not require conversion to work with EF Core\n[ValueObject<string>(conversions: Conversions.SystemTextJson)]\npublic partial struct ProjectName\n{\n  public const int MaxLength = 100;\n  private static Validation Validate(in string name) =>\n    string.IsNullOrEmpty(name)\n      ? Validation.Invalid(ProjectErrorMessages.CoreProjectNameEmpty)\n      : name.Length > MaxLength\n        ? Validation.Invalid(ProjectErrorMessages.CoreProjectNameTooLong(MaxLength))\n        : Validation.Ok;\n}\n"
  },
  {
    "path": "sample/src/NimblePros.SampleToDo.Core/ProjectAggregate/ProjectStatus.cs",
    "content": "﻿namespace NimblePros.SampleToDo.Core.ProjectAggregate;\n\npublic enum ProjectStatus\n{\n  InProgress, // NOTE: Better to use a SmartEnum if you want spaces in your strings e.g. \"In Progress\"\n  Complete\n}\n"
  },
  {
    "path": "sample/src/NimblePros.SampleToDo.Core/ProjectAggregate/Specifications/IncompleteItemsSearchSpec.cs",
    "content": "﻿namespace NimblePros.SampleToDo.Core.ProjectAggregate.Specifications;\n\npublic class IncompleteItemsSearchSpec : Specification<ToDoItem>\n{\n  public IncompleteItemsSearchSpec(string searchString)\n  {\n    Query\n        .Where(item => !item.IsDone &&\n        (item.Title.Value.Contains(searchString) ||\n        item.Description.Value.Contains(searchString)));\n  }\n}\n"
  },
  {
    "path": "sample/src/NimblePros.SampleToDo.Core/ProjectAggregate/Specifications/IncompleteItemsSpec.cs",
    "content": "﻿namespace NimblePros.SampleToDo.Core.ProjectAggregate.Specifications;\n\npublic class IncompleteItemsSpec : Specification<ToDoItem>\n{\n  public IncompleteItemsSpec()\n  {\n    Query.Where(item => !item.IsDone);\n  }\n}\n"
  },
  {
    "path": "sample/src/NimblePros.SampleToDo.Core/ProjectAggregate/Specifications/ProjectByIdWithItemsSpec.cs",
    "content": "﻿namespace NimblePros.SampleToDo.Core.ProjectAggregate.Specifications;\n\npublic class ProjectByIdWithItemsSpec : Specification<Project>\n{\n  public ProjectByIdWithItemsSpec(ProjectId projectId)\n  {\n    Query\n        .Where(project => project.Id == projectId)\n        .Include(project => project.Items);\n  }\n}\n"
  },
  {
    "path": "sample/src/NimblePros.SampleToDo.Core/ProjectAggregate/Specifications/ProjectsWithItemsByContributorId.cs",
    "content": "﻿using NimblePros.SampleToDo.Core.ContributorAggregate;\n\nnamespace NimblePros.SampleToDo.Core.ProjectAggregate.Specifications;\n\npublic class ProjectsWithItemsByContributorIdSpec : Specification<Project>\n{\n  public ProjectsWithItemsByContributorIdSpec(ContributorId contributorId)\n  {\n    Query\n        .Where(project => project.Items.Any(item => item.ContributorId == contributorId))\n        .Include(project => project.Items);\n  }\n}\n"
  },
  {
    "path": "sample/src/NimblePros.SampleToDo.Core/ProjectAggregate/ToDoItem.cs",
    "content": "﻿using System.Xml.Linq;\nusing NimblePros.SampleToDo.Core.ContributorAggregate;\nusing NimblePros.SampleToDo.Core.ProjectAggregate.Events;\n\nnamespace NimblePros.SampleToDo.Core.ProjectAggregate;\n\npublic class ToDoItem : EntityBase<ToDoItem, ToDoItemId>\n{\n  public ToDoItem() : this(Priority.Backlog)\n  {\n  }\n  public ToDoItem(ToDoItemTitle title, ToDoItemDescription description) : this(Priority.Backlog)\n  {\n    Title = title;\n    Description = description;\n  }\n\n  public ToDoItem(Priority priority)\n  {\n    Priority = priority;\n  }\n\n  public ToDoItemTitle Title { get; private set; }\n  public ToDoItemDescription Description { get; private set; }\n  public ContributorId? ContributorId { get; private set; } // tasks don't have anyone assigned when first created\n  public bool IsDone { get; private set; }\n\n  public Priority Priority { get; private set; }\n\n  public ToDoItem MarkComplete()\n  {\n    if (!IsDone)\n    {\n      IsDone = true;\n\n      RegisterDomainEvent(new ToDoItemCompletedEvent(this));\n    }\n    return this;\n  }\n\n  public ToDoItem AddContributor(ContributorId contributorId)\n  {\n    Guard.Against.Null(contributorId);\n    ContributorId = contributorId;\n\n    var contributorAddedToItem = new ContributorAddedToItemEvent(this, contributorId);\n    base.RegisterDomainEvent(contributorAddedToItem);\n    return this;\n  }\n\n  public ToDoItem RemoveContributor()\n  {\n    ContributorId = null;\n    return this;\n  }\n\n  public ToDoItem UpdateTitle(ToDoItemTitle newTitle)\n  {\n    if (Title.Equals(newTitle)) return this;\n    Title = newTitle;\n    return this;\n  }\n\n  public ToDoItem UpdateDescription(ToDoItemDescription newDescription)\n  {\n    if (Description.Equals(newDescription)) return this;\n    Description = newDescription;\n    return this;\n  }\n\n  public override string ToString()\n  {\n    string status = IsDone ? \"Done!\" : \"Not done.\";\n    return $\"{Id}: Status: {status} - {Title.Value} - Priority: {Priority}\";\n  }\n}\n"
  },
  {
    "path": "sample/src/NimblePros.SampleToDo.Core/ProjectAggregate/ToDoItemDescription.cs",
    "content": "﻿using Vogen;\n\nnamespace NimblePros.SampleToDo.Core.ProjectAggregate;\n\n[ValueObject<string>(conversions: Conversions.SystemTextJson)]\npublic partial struct ToDoItemDescription\n{\n  public const int MaxLength = 200;\n  private static Validation Validate(in string description) =>\n    string.IsNullOrEmpty(description)\n      ? Validation.Invalid(ProjectErrorMessages.CoreToDoItemDescriptionEmpty)\n      : description.Length > MaxLength\n        ? Validation.Invalid(ProjectErrorMessages.CoreToDoItemDescriptionTooLong(MaxLength))\n        : Validation.Ok;\n}\n"
  },
  {
    "path": "sample/src/NimblePros.SampleToDo.Core/ProjectAggregate/ToDoItemId.cs",
    "content": "﻿using Vogen;\nnamespace NimblePros.SampleToDo.Core.ProjectAggregate;\n\n[ValueObject<int>]\npublic partial struct ToDoItemId;\n"
  },
  {
    "path": "sample/src/NimblePros.SampleToDo.Core/ProjectAggregate/ToDoItemTitle.cs",
    "content": "﻿using Vogen;\n\nnamespace NimblePros.SampleToDo.Core.ProjectAggregate;\n\n[ValueObject<string>(conversions: Conversions.SystemTextJson)]\npublic partial struct ToDoItemTitle\n{\n  public const int MaxLength = 100;\n  private static Validation Validate(in string title) =>\n    string.IsNullOrEmpty(title)\n      ? Validation.Invalid(ProjectErrorMessages.CoreToDoItemTitleEmpty)\n      : title.Length > MaxLength\n        ? Validation.Invalid(ProjectErrorMessages.CoreToDoItemTitleTooLong(MaxLength))\n        : Validation.Ok;\n}\n"
  },
  {
    "path": "sample/src/NimblePros.SampleToDo.Core/Services/DeleteContributorService.cs",
    "content": "﻿using Microsoft.Extensions.Logging;\nusing NimblePros.SampleToDo.Core.ContributorAggregate;\nusing NimblePros.SampleToDo.Core.ContributorAggregate.Events;\nusing NimblePros.SampleToDo.Core.Interfaces;\n\nnamespace NimblePros.SampleToDo.Core.Services;\n\npublic class DeleteContributorService : IDeleteContributorService\n{\n  private readonly IRepository<Contributor> _repository;\n  private readonly IMediator _mediator;\n  private readonly ILogger<DeleteContributorService> _logger;\n\n  public DeleteContributorService(IRepository<Contributor> repository,\n    IMediator mediator,\n    ILogger<DeleteContributorService> logger)\n  {\n    _repository = repository;\n    _mediator = mediator;\n    _logger = logger;\n  }\n\n  public async Task<Result> DeleteContributor(ContributorId contributorId)\n  {\n    _logger.LogInformation(\"Deleting Contributor {contributorId}\", contributorId);\n    var aggregateToDelete = await _repository.GetByIdAsync(contributorId);\n    if (aggregateToDelete == null) return Result.NotFound();\n\n    await _repository.DeleteAsync(aggregateToDelete);\n    var domainEvent = new ContributorDeletedEvent(contributorId);\n    await _mediator.Publish(domainEvent);\n    return Result.Success();\n  }\n}\n"
  },
  {
    "path": "sample/src/NimblePros.SampleToDo.Core/Services/ToDoItemSearchService.cs",
    "content": "﻿using NimblePros.SampleToDo.Core.Interfaces;\nusing NimblePros.SampleToDo.Core.ProjectAggregate;\nusing NimblePros.SampleToDo.Core.ProjectAggregate.Specifications;\n\nnamespace NimblePros.SampleToDo.Core.Services;\n\npublic class ToDoItemSearchService : IToDoItemSearchService\n{\n  private readonly IRepository<Project> _repository;\n\n  public ToDoItemSearchService(IRepository<Project> repository)\n  {\n    _repository = repository;\n  }\n\n  public async Task<Result<List<ToDoItem>>> GetAllIncompleteItemsAsync(ProjectId projectId, string searchString)\n  {\n    if (string.IsNullOrEmpty(searchString))\n    {\n      var errors = new List<ValidationError>\n      {\n        new() { Identifier = nameof(searchString), ErrorMessage = $\"{nameof(searchString)} is required.\" }\n      };\n\n      return Result<List<ToDoItem>>.Invalid(errors);\n    }\n\n    var projectSpec = new ProjectByIdWithItemsSpec(projectId);\n    var project = await _repository.FirstOrDefaultAsync(projectSpec);\n\n    // TODO: Optionally use Ardalis.GuardClauses Guard.Against.NotFound and catch\n    if (project == null)\n    {\n      return Result<List<ToDoItem>>.NotFound();\n    }\n\n    var incompleteSpec = new IncompleteItemsSearchSpec(searchString);\n    try\n    {\n      var items = incompleteSpec.Evaluate(project.Items).ToList();\n\n      return new Result<List<ToDoItem>>(items);\n    }\n    catch (Exception ex)\n    {\n      // TODO: Log details here\n      return Result<List<ToDoItem>>.Error( ex.Message );\n    }\n  }\n\n  public async Task<Result<ToDoItem>> GetNextIncompleteItemAsync(ProjectId projectId)\n  {\n    var projectSpec = new ProjectByIdWithItemsSpec(projectId);\n    var project = await _repository.FirstOrDefaultAsync(projectSpec);\n    if (project == null)\n    {\n      return Result<ToDoItem>.NotFound();\n    }\n\n    var incompleteSpec = new IncompleteItemsSpec();\n    var items = incompleteSpec.Evaluate(project.Items).ToList();\n    if (!items.Any())\n    {\n      return Result<ToDoItem>.NotFound();\n    }\n\n    return new Result<ToDoItem>(items.First());\n  }\n}\n"
  },
  {
    "path": "sample/src/NimblePros.SampleToDo.Infrastructure/Data/AppDbContext.cs",
    "content": "﻿using NimblePros.SampleToDo.Core.ContributorAggregate;\nusing NimblePros.SampleToDo.Core.ProjectAggregate;\n\nnamespace NimblePros.SampleToDo.Infrastructure.Data;\n\npublic class AppDbContext : DbContext\n{\n\n  public AppDbContext(DbContextOptions<AppDbContext> options)\n      : base(options) {}\n\n  public DbSet<ToDoItem> ToDoItems => Set<ToDoItem>();\n  public DbSet<Project> Projects => Set<Project>();\n  public DbSet<Contributor> Contributors => Set<Contributor>();\n\n  protected override void OnModelCreating(ModelBuilder modelBuilder)\n  {\n    base.OnModelCreating(modelBuilder);\n    modelBuilder.ApplyConfigurationsFromAssembly(Assembly.GetExecutingAssembly());\n  }\n\n  protected override void ConfigureConventions(ModelConfigurationBuilder configurationBuilder)\n  {\n    base.ConfigureConventions(configurationBuilder);\n\n    //configurationBuilder.RegisterAllInVogenEfCoreConverters();\n  }\n\n  public override int SaveChanges()\n  {\n    return SaveChangesAsync().GetAwaiter().GetResult();\n  }\n}\n"
  },
  {
    "path": "sample/src/NimblePros.SampleToDo.Infrastructure/Data/Config/ContributorConfiguration.cs",
    "content": "﻿using NimblePros.SampleToDo.Core.ContributorAggregate;\n\nnamespace NimblePros.SampleToDo.Infrastructure.Data.Config;\n\npublic class ContributorConfiguration : IEntityTypeConfiguration<Contributor>\n{\n  public void Configure(EntityTypeBuilder<Contributor> builder)\n  {\n    builder.Property(entity => entity.Id)\n      .HasValueGenerator<VogenIdValueGenerator<AppDbContext, Contributor, ContributorId>>()\n      .HasVogenConversion()\n      .IsRequired();\n\n    builder.Property(entity => entity.Name)\n      .HasVogenConversion()\n      .HasMaxLength(ContributorName.MaxLength)\n      .IsRequired();\n  }\n}\n"
  },
  {
    "path": "sample/src/NimblePros.SampleToDo.Infrastructure/Data/Config/DataSchemaConstants.cs",
    "content": "﻿namespace NimblePros.SampleToDo.Infrastructure.Data.Config;\n\npublic static class DataSchemaConstants\n{\n  public const int DEFAULT_NAME_LENGTH = 100;\n}\n"
  },
  {
    "path": "sample/src/NimblePros.SampleToDo.Infrastructure/Data/Config/ProjectConfiguration.cs",
    "content": "﻿using NimblePros.SampleToDo.Core.ProjectAggregate;\n\nnamespace NimblePros.SampleToDo.Infrastructure.Data.Config;\n\npublic class ProjectConfiguration : IEntityTypeConfiguration<Project>\n{\n  public void Configure(EntityTypeBuilder<Project> builder)\n  {\n    builder.Property(p => p.Id)\n      .HasValueGenerator<VogenIdValueGenerator<AppDbContext, Project, ProjectId>>()\n      .HasVogenConversion()\n      .IsRequired();\n    builder.Property(p => p.Name)\n      .HasVogenConversion()\n      .HasMaxLength(ProjectName.MaxLength)\n      .IsRequired();\n  }\n}\n\n\n"
  },
  {
    "path": "sample/src/NimblePros.SampleToDo.Infrastructure/Data/Config/ToDoItemConfiguration.cs",
    "content": "﻿using NimblePros.SampleToDo.Core.ContributorAggregate;\nusing NimblePros.SampleToDo.Core.ProjectAggregate;\n\nnamespace NimblePros.SampleToDo.Infrastructure.Data.Config;\n\npublic class ToDoItemConfiguration : IEntityTypeConfiguration<ToDoItem>\n{\n  public void Configure(EntityTypeBuilder<ToDoItem> builder)\n  {\n    builder.Property(p => p.Id)\n      .HasValueGenerator<VogenIdValueGenerator<AppDbContext, ToDoItem, ToDoItemId>>()\n      .HasVogenConversion()\n      .IsRequired();\n\n    builder.Property(p => p.Title)\n      .HasVogenConversion()\n      .HasMaxLength(ToDoItemTitle.MaxLength)\n      .IsRequired();\n\n    builder.Property(p => p.Description)\n      .HasVogenConversion()\n      .HasMaxLength(ToDoItemDescription.MaxLength)\n      .IsRequired();\n\n    builder.Property(t => t.ContributorId)\n      .HasConversion(\n          v => v.HasValue ? v.Value.Value : (int?)null, // to db\n          v => v.HasValue ? ContributorId.From(v.Value) : (ContributorId?)null // from db\n      )\n      .IsRequired(false);\n    builder.Property(t => t.Priority)\n      .HasConversion(\n          p => p.Value,\n          p => Priority.FromValue(p));\n  }\n}\n"
  },
  {
    "path": "sample/src/NimblePros.SampleToDo.Infrastructure/Data/Config/VogenEfCoreConverters.cs",
    "content": "﻿using NimblePros.SampleToDo.Core.ContributorAggregate;\nusing NimblePros.SampleToDo.Core.ProjectAggregate;\nusing Vogen;\n\nnamespace NimblePros.SampleToDo.Infrastructure.Data.Config;\n\n[EfCoreConverter<ContributorId>]\n[EfCoreConverter<ToDoItemId>]\n[EfCoreConverter<ContributorName>]\n[EfCoreConverter<ProjectName>]\n[EfCoreConverter<ProjectId>]\n[EfCoreConverter<ToDoItemTitle>]\n[EfCoreConverter<ToDoItemDescription>]\ninternal partial class VogenEfCoreConverters;\n"
  },
  {
    "path": "sample/src/NimblePros.SampleToDo.Infrastructure/Data/Config/VogenIdValueGenerator.cs",
    "content": "﻿using Microsoft.EntityFrameworkCore.ChangeTracking;\nusing Microsoft.EntityFrameworkCore.ValueGeneration;\nusing NimblePros.SharedKernel;\n\nnamespace NimblePros.SampleToDo.Infrastructure.Data.Config;\n\ninternal class VogenIdValueGenerator<TContext, TEntityBase, TId> : ValueGenerator<TId>\n    where TContext : DbContext\n    where TEntityBase : EntityBase<TEntityBase, TId>\n    where TId : IVogen<TId, int>\n{\n  private readonly PropertyInfo _matchPropertyGetter;\n\n  public VogenIdValueGenerator()\n  {\n    var matchingProperties =\n        typeof(TContext).GetProperties().Where(p => p!.GetGetMethod()!.IsPublic && p.PropertyType == typeof(DbSet<TEntityBase>)).ToList();\n\n    if (matchingProperties.Count == 0)\n    {\n      throw new InvalidOperationException($\"No properties found in the EFCore context for a DBSet of {nameof(TEntityBase)}\");\n    }\n\n    if (matchingProperties.Count > 1)\n    {\n      throw new InvalidOperationException($\"Multiple properties found in the EFCore context for a DBSet of {nameof(TEntityBase)}\");\n    }\n\n    _matchPropertyGetter = matchingProperties[0];\n  }\n\n  public override TId Next(EntityEntry entry)\n  {\n    TContext ctx = (TContext)entry.Context;\n\n    DbSet<TEntityBase> entities = (DbSet<TEntityBase>)_matchPropertyGetter!.GetValue(ctx)!;\n\n    var next = Math.Max(\n        MaxFrom(entities.Local),\n        MaxFrom(entities)) + 1;\n\n    return TId.From(next);\n\n    static int MaxFrom(IEnumerable<TEntityBase> es) =>\n        es.Any() ? es.Max(e => e.Id.Value) : 0;\n  }\n\n\n  public override bool GeneratesTemporaryValues => false;\n}\n"
  },
  {
    "path": "sample/src/NimblePros.SampleToDo.Infrastructure/Data/EfRepository.cs",
    "content": "﻿using NimblePros.SharedKernel;\n\nnamespace NimblePros.SampleToDo.Infrastructure.Data;\n\n// inherit from Ardalis.Specification type\npublic class EfRepository<T> : RepositoryBase<T>, IReadRepository<T>, IRepository<T> \n  where T : class, IAggregateRoot\n{\n  public EfRepository(AppDbContext dbContext) : base(dbContext)\n  {\n  }\n}\n"
  },
  {
    "path": "sample/src/NimblePros.SampleToDo.Infrastructure/Data/EventDispatchInterceptor.cs",
    "content": "﻿using Microsoft.EntityFrameworkCore.Diagnostics;\nusing NimblePros.SharedKernel;\n\nnamespace NimblePros.SampleToDo.Infrastructure.Data;\n\n// Intercepts SaveChanges to dispatch domain events after changes are successfully saved\npublic class EventDispatchInterceptor(IDomainEventDispatcher domainEventDispatcher) : SaveChangesInterceptor\n{\n  private readonly IDomainEventDispatcher _domainEventDispatcher = domainEventDispatcher;\n\n  // Called after SaveChangesAsync has completed successfully\n  public override async ValueTask<int> SavedChangesAsync(SaveChangesCompletedEventData eventData, int result,\n    CancellationToken cancellationToken = new CancellationToken())\n  {\n    var context = eventData.Context;\n    if (context is not AppDbContext appDbContext)\n    {\n      return await base.SavedChangesAsync(eventData, result, cancellationToken).ConfigureAwait(false);\n    }\n\n    // Retrieve all tracked entities that have domain events\n    var entitiesWithEvents = appDbContext.ChangeTracker.Entries<IHasDomainEvents>()\n      .Select(e => e.Entity)\n      .Where(e => e.DomainEvents.Any())\n      .ToArray();\n\n    // Dispatch and clear domain events\n    await _domainEventDispatcher.DispatchAndClearEvents(entitiesWithEvents);\n\n    return await base.SavedChangesAsync(eventData, result, cancellationToken);\n\n  }\n}\n"
  },
  {
    "path": "sample/src/NimblePros.SampleToDo.Infrastructure/Data/Queries/FakeListContributorsQueryService.cs",
    "content": "﻿using NimblePros.SampleToDo.Core.ContributorAggregate;\nusing NimblePros.SampleToDo.UseCases;\nusing NimblePros.SampleToDo.UseCases.Contributors;\nusing NimblePros.SampleToDo.UseCases.Contributors.Queries.List;\n\nnamespace NimblePros.SampleToDo.Infrastructure.Data.Queries;\n\npublic class FakeListContributorsQueryService : IListContributorsQueryService\n{\n  public Task<PagedResult<ContributorDto>> ListAsync(int page, int perPage)\n  {\n    var items = new List<ContributorDto>();\n    for (int i = 1; i <= 25; i++)\n    { \n      items.Add(new ContributorDto(ContributorId.From(i), ContributorName.From($\"Fake {i}\")));\n    };\n\n    int totalPages = (int)Math.Ceiling(items.Count / (double)perPage);\n    var result = new PagedResult<ContributorDto>(items, page, perPage, items.Count, totalPages);\n    return Task.FromResult(result);\n  }\n}\n"
  },
  {
    "path": "sample/src/NimblePros.SampleToDo.Infrastructure/Data/Queries/FakeListIncompleteItemsQueryService.cs",
    "content": "﻿using NimblePros.SampleToDo.Core.ProjectAggregate;\nusing NimblePros.SampleToDo.UseCases.Projects;\nusing NimblePros.SampleToDo.UseCases.Projects.ListIncompleteItems;\n\nnamespace NimblePros.SampleToDo.Infrastructure.Data.Queries;\n\npublic class FakeListIncompleteItemsQueryService : IListIncompleteItemsQueryService\n{\n  public async Task<IEnumerable<ToDoItemDto>> ListAsync(int projectId)\n  {\n    var testItem = new ToDoItemDto(Id: ToDoItemId.From(1000), Title: \"test\", Description: \"test description\", IsComplete: false, null);\n    return await Task.FromResult(new List<ToDoItemDto>() { testItem});\n  }\n}\n"
  },
  {
    "path": "sample/src/NimblePros.SampleToDo.Infrastructure/Data/Queries/FakeListProjectsShallowQueryService.cs",
    "content": "﻿using NimblePros.SampleToDo.UseCases.Projects;\nusing NimblePros.SampleToDo.UseCases.Projects.ListShallow;\n\nnamespace NimblePros.SampleToDo.Infrastructure.Data.Queries;\n\npublic class FakeListProjectsShallowQueryService : IListProjectsShallowQueryService\n{\n  public async Task<IEnumerable<ProjectDto>> ListAsync()\n  {\n    var testProject = new ProjectDto(1000, \"Test Project\", \"InProgress\");\n    return await Task.FromResult(new List<ProjectDto> { testProject });\n  }\n}\n"
  },
  {
    "path": "sample/src/NimblePros.SampleToDo.Infrastructure/Data/Queries/ListContributorsQueryService.cs",
    "content": "﻿using NimblePros.SampleToDo.UseCases;\nusing NimblePros.SampleToDo.UseCases.Contributors;\nusing NimblePros.SampleToDo.UseCases.Contributors.Queries.List;\n\nnamespace NimblePros.SampleToDo.Infrastructure.Data.Queries;\n\npublic class ListContributorsQueryService : IListContributorsQueryService\n{\n  // You can use EF, Dapper, SqlClient, etc. for queries\n  private readonly AppDbContext _db;\n\n  public ListContributorsQueryService(AppDbContext db)\n  {\n    _db = db;\n  }\n\n  public async Task<PagedResult<ContributorDto>> ListAsync(int page, int perPage)\n  {\n    var items = await _db.Contributors.FromSqlRaw(\"SELECT Id, Name FROM Contributors\") // don't fetch other big columns\n      .OrderBy(c => c.Id)\n      .Skip((page - 1) * perPage)\n      .Take(perPage)\n      .Select(c => new ContributorDto(c.Id, c.Name))\n      .ToListAsync();\n\n    int totalCount = await _db.Contributors.CountAsync();\n    int totalPages = (int)Math.Ceiling(totalCount / (double)perPage);\n    var result = new PagedResult<ContributorDto>(items, page, perPage, totalCount, totalPages);\n\n    return result;\n  }\n}\n"
  },
  {
    "path": "sample/src/NimblePros.SampleToDo.Infrastructure/Data/Queries/ListIncompleteItemsQueryService.cs",
    "content": "﻿using NimblePros.SampleToDo.UseCases.Projects;\nusing NimblePros.SampleToDo.UseCases.Projects.ListIncompleteItems;\n\nnamespace NimblePros.SampleToDo.Infrastructure.Data.Queries;\n\npublic class ListIncompleteItemsQueryService : IListIncompleteItemsQueryService\n{\n  private readonly AppDbContext _db;\n\n  public ListIncompleteItemsQueryService(AppDbContext db)\n  {\n    _db = db;\n  }\n\n  public async Task<IEnumerable<ToDoItemDto>> ListAsync(int projectId)\n  {\n    var projectParameter = new SqlParameter(\"@projectId\", System.Data.SqlDbType.Int);\n    var result = await _db.ToDoItems.FromSqlRaw(\"SELECT Id, Title, Description, IsDone, ContributorId FROM ToDoItems WHERE ProjectId = @ProjectId\",\n      projectParameter) // don't fetch other big columns\n      .Select(x => new ToDoItemDto(x.Id, x.Title.Value, x.Description.Value, x.IsDone, x.ContributorId))\n      .ToListAsync();\n\n    return result;\n  }\n}\n"
  },
  {
    "path": "sample/src/NimblePros.SampleToDo.Infrastructure/Data/Queries/ListProjectsShallowQueryService.cs",
    "content": "﻿using NimblePros.SampleToDo.UseCases.Projects;\nusing NimblePros.SampleToDo.UseCases.Projects.ListShallow;\n\nnamespace NimblePros.SampleToDo.Infrastructure.Data.Queries;\n\npublic class ListProjectsShallowQueryService(AppDbContext db) : \n  IListProjectsShallowQueryService\n{\n  private readonly AppDbContext _db = db;\n\n  public async Task<IEnumerable<ProjectDto>> ListAsync()\n  {\n    var result = await _db.Projects.FromSqlRaw(\"SELECT Id, Name FROM Projects\") // don't fetch other big columns\n      .Select(x => new ProjectDto(x.Id.Value, x.Name.Value, x.Status.ToString()))\n      .ToListAsync();\n\n    return result;\n  }\n}\n"
  },
  {
    "path": "sample/src/NimblePros.SampleToDo.Infrastructure/Email/FakeEmailSender.cs",
    "content": "﻿using NimblePros.SampleToDo.Core.Interfaces;\n\nnamespace NimblePros.SampleToDo.Infrastructure.Email;\n\npublic class FakeEmailSender : IEmailSender\n{\n  private readonly ILogger<FakeEmailSender> _logger;\n\n  public FakeEmailSender(ILogger<FakeEmailSender> logger)\n  {\n    _logger = logger;\n  }\n  public Task SendEmailAsync(string to, string from, string subject, string body)\n  {\n    _logger.LogInformation(\"Not actually sending an email to {to} from {from} with subject {subject}\", to, from, subject);\n    return Task.CompletedTask;\n  }\n}\n"
  },
  {
    "path": "sample/src/NimblePros.SampleToDo.Infrastructure/Email/MailserverConfiguration.cs",
    "content": "﻿namespace NimblePros.SampleToDo.Infrastructure.Email;\n\npublic class MailserverConfiguration()\n{\n  public const string SectionName = \"Mailserver\";\n\n  public string Hostname { get; set; } = \"localhost\";\n  public int Port { get; set; } = 25;\n}\n"
  },
  {
    "path": "sample/src/NimblePros.SampleToDo.Infrastructure/Email/MimeKitEmailSender.cs",
    "content": "﻿using Microsoft.Extensions.Options;\nusing MimeKit;\nusing NimblePros.SampleToDo.Core.Interfaces;\n\nnamespace NimblePros.SampleToDo.Infrastructure.Email;\n\npublic class MimeKitEmailSender(ILogger<MimeKitEmailSender> logger,\n  IOptions<MailserverConfiguration> mailserverOptions) : IEmailSender\n{\n  private readonly ILogger<MimeKitEmailSender> _logger = logger;\n  private readonly MailserverConfiguration _mailserverConfiguration = mailserverOptions.Value!;\n\n  public async Task SendEmailAsync(string to, string from, string subject, string body)\n  {\n    _logger.LogWarning(\"Sending email to {to} from {from} with subject {subject} using {type}.\", to, from, subject, ToString());\n\n    try\n    {\n\n    using var client = new MailKit.Net.Smtp.SmtpClient();\n    await client.ConnectAsync(_mailserverConfiguration.Hostname,\n      _mailserverConfiguration.Port, false);\n    var message = new MimeMessage();\n    message.From.Add(new MailboxAddress(from, from));\n    message.To.Add(new MailboxAddress(to, to));\n    message.Subject = subject;\n    message.Body = new TextPart(\"plain\") { Text = body };\n\n    await client.SendAsync(message);\n\n    await client.DisconnectAsync(true,\n      new CancellationToken(canceled: true));\n    }\n    catch (Exception ex)\n    {\n      _logger.LogWarning(\"Run Papercut docker image: \");\n      _logger.LogWarning(\"docker run --name=papercut -p 25:25 -p 37408:37408 jijiechen/papercut:latest\");\n      _logger.LogError(ex, \"Error sending email\");\n      throw;\n    }\n  }\n}\n"
  },
  {
    "path": "sample/src/NimblePros.SampleToDo.Infrastructure/Email/SmtpEmailSender.cs",
    "content": "﻿using NimblePros.SampleToDo.Core.Interfaces;\n\nnamespace NimblePros.SampleToDo.Infrastructure.Email;\n\n[Obsolete(\"Use MimeKitEmailSender instead\")]\npublic class SmtpEmailSender : IEmailSender\n{\n  private readonly ILogger<SmtpEmailSender> _logger;\n\n  public SmtpEmailSender(ILogger<SmtpEmailSender> logger)\n  {\n    _logger = logger;\n  }\n\n  public async Task SendEmailAsync(string to, string from, string subject, string body)\n  {\n    var emailClient = new SmtpClient(\"localhost\");\n    var message = new MailMessage\n    {\n      From = new MailAddress(from),\n      Subject = subject,\n      Body = body\n    };\n    message.To.Add(new MailAddress(to));\n    await emailClient.SendMailAsync(message);\n    _logger.LogWarning(\"Sending email to {to} from {from} with subject {subject}.\", to, from, subject);\n  }\n}\n"
  },
  {
    "path": "sample/src/NimblePros.SampleToDo.Infrastructure/GlobalUsings.cs",
    "content": "﻿global using System.Net.Mail;\nglobal using System.Reflection;\nglobal using Ardalis.Specification.EntityFrameworkCore;\nglobal using Microsoft.Data.SqlClient;\nglobal using Microsoft.EntityFrameworkCore;\nglobal using Microsoft.EntityFrameworkCore.Metadata.Builders;\nglobal using Microsoft.Extensions.DependencyInjection;\nglobal using Microsoft.Extensions.Logging;\n"
  },
  {
    "path": "sample/src/NimblePros.SampleToDo.Infrastructure/InfrastructureServiceExtensions.cs",
    "content": "﻿using Microsoft.Extensions.Configuration;\nusing NimblePros.Metronome;\nusing NimblePros.SampleToDo.Core.Interfaces;\nusing NimblePros.SampleToDo.Infrastructure.Data;\nusing NimblePros.SampleToDo.Infrastructure.Data.Queries;\nusing NimblePros.SampleToDo.Infrastructure.Email;\nusing NimblePros.SampleToDo.UseCases.Contributors.Queries.List;\nusing NimblePros.SampleToDo.UseCases.Projects.ListIncompleteItems;\nusing NimblePros.SampleToDo.UseCases.Projects.ListShallow;\nusing NimblePros.SharedKernel;\n\nnamespace NimblePros.SampleToDo.Infrastructure;\n\npublic static class InfrastructureServiceExtensions\n{\n  public static IServiceCollection AddInfrastructureServices(\n    this IServiceCollection services,\n    IConfiguration configuration,\n    ILogger logger,\n    string environmentName)\n  {\n    if (environmentName == \"Development\")\n    {\n      RegisterDevelopmentOnlyDependencies(services, configuration);\n    }\n    else if (environmentName == \"Testing\")\n    {\n      RegisterTestingOnlyDependencies(services);\n    }\n    else\n    {\n      RegisterProductionOnlyDependencies(services, configuration);\n    }\n    \n    RegisterEFRepositories(services);\n    \n    logger.LogInformation(\"{Project} services registered\", \"Infrastructure\");\n    \n    return services;\n  }\n  private static void AddDbContextWithSqlite(IServiceCollection services, IConfiguration configuration)\n  {\n    services.AddScoped<EventDispatchInterceptor>();\n    services.AddScoped<IDomainEventDispatcher, MediatorDomainEventDispatcher>();\n    var connectionString = configuration.GetConnectionString(\"SqliteConnection\");\n    services.AddDbContext<AppDbContext>((provider, options) =>\n    {\n      \n      options.UseSqlite(connectionString)\n             .AddMetronomeDbTracking(provider)\n             .AddInterceptors(provider.GetRequiredService<EventDispatchInterceptor>());\n    });\n             \n  }\n\n\n  private static void RegisterDevelopmentOnlyDependencies(IServiceCollection services, IConfiguration configuration)\n  {\n    AddDbContextWithSqlite(services, configuration);\n    services.AddScoped<IEmailSender, MimeKitEmailSender>(); // to demo with a localhost test email server like Papercut\n    services.AddScoped<IListContributorsQueryService, ListContributorsQueryService>();\n    services.AddScoped<IListIncompleteItemsQueryService, ListIncompleteItemsQueryService>();\n    services.AddScoped<IListProjectsShallowQueryService, ListProjectsShallowQueryService>();\n  }\n\n  private static void RegisterTestingOnlyDependencies(IServiceCollection services)\n  {\n    // do not configure a DbContext here for testing - it's configured in CustomWebApplicationFactory\n\n    services.AddScoped<IEmailSender, FakeEmailSender>();\n    services.AddScoped<IListContributorsQueryService, FakeListContributorsQueryService>();\n    services.AddScoped<IListIncompleteItemsQueryService, FakeListIncompleteItemsQueryService>();\n    services.AddScoped<IListProjectsShallowQueryService, FakeListProjectsShallowQueryService>();\n  }\n\n  private static void RegisterProductionOnlyDependencies(IServiceCollection services, IConfiguration configuration)\n  {\n    AddDbContextWithSqlite(services, configuration);\n\n    services.AddScoped<IEmailSender, MimeKitEmailSender>();\n    services.AddScoped<IListContributorsQueryService, ListContributorsQueryService>();\n    services.AddScoped<IListIncompleteItemsQueryService, ListIncompleteItemsQueryService>();\n    services.AddScoped<IListProjectsShallowQueryService, ListProjectsShallowQueryService>();\n  }\n\n  private static void RegisterEFRepositories(IServiceCollection services)\n  {\n    services.AddScoped(typeof(IRepository<>), typeof(EfRepository<>));\n    services.AddScoped(typeof(IReadRepository<>), typeof(EfRepository<>));\n  }\n}\n"
  },
  {
    "path": "sample/src/NimblePros.SampleToDo.Infrastructure/NimblePros.SampleToDo.Infrastructure.csproj",
    "content": "﻿<Project Sdk=\"Microsoft.NET.Sdk\">\n  <Sdk Name=\"Microsoft.Build.CentralPackageVersions\" Version=\"2.1.3\" />  \n  <ItemGroup>\n    <PackageReference Include=\"Ardalis.Specification.EntityFrameworkCore\" />\n    <PackageReference Include=\"MailKit\" />\n    <PackageReference Include=\"Microsoft.EntityFrameworkCore.Relational\" />\n    <PackageReference Include=\"Microsoft.EntityFrameworkCore.Tools\" PrivateAssets=\"all\" />\n    <PackageReference Include=\"Microsoft.EntityFrameworkCore.Sqlite\" />\n    <PackageReference Include=\"Microsoft.EntityFrameworkCore.SqlServer\" />\n    <PackageReference Include=\"NimblePros.Metronome\" />\n    <PackageReference Include=\"SQLite\" />\n    <PackageReference Include=\"Vogen\" />\n  </ItemGroup>\n  \n  <ItemGroup>\n    <ProjectReference Include=\"..\\NimblePros.SampleToDo.Core\\NimblePros.SampleToDo.Core.csproj\" />\n    <ProjectReference Include=\"..\\NimblePros.SampleToDo.UseCases\\NimblePros.SampleToDo.UseCases.csproj\" />\n  </ItemGroup>\n</Project>\n"
  },
  {
    "path": "sample/src/NimblePros.SampleToDo.ServiceDefaults/Extensions.cs",
    "content": "﻿using Microsoft.AspNetCore.Builder;\nusing Microsoft.AspNetCore.Diagnostics.HealthChecks;\nusing Microsoft.Extensions.DependencyInjection;\nusing Microsoft.Extensions.Diagnostics.HealthChecks;\nusing Microsoft.Extensions.Logging;\nusing Microsoft.Extensions.ServiceDiscovery;\nusing OpenTelemetry;\nusing OpenTelemetry.Metrics;\nusing OpenTelemetry.Trace;\n\nnamespace Microsoft.Extensions.Hosting;\n\n// Adds common Aspire services: service discovery, resilience, health checks, and OpenTelemetry.\n// This project should be referenced by each service project in your solution.\n// To learn more about using this project, see https://aka.ms/dotnet/aspire/service-defaults\npublic static class Extensions\n{\n  private const string HealthEndpointPath = \"/health\";\n  private const string AlivenessEndpointPath = \"/alive\";\n\n  public static TBuilder AddServiceDefaults<TBuilder>(this TBuilder builder) where TBuilder : IHostApplicationBuilder\n  {\n    builder.ConfigureOpenTelemetry();\n\n    builder.AddDefaultHealthChecks();\n\n    builder.Services.AddServiceDiscovery();\n\n    builder.Services.ConfigureHttpClientDefaults(http =>\n    {\n      // Turn on resilience by default\n      http.AddStandardResilienceHandler();\n\n      // Turn on service discovery by default\n      http.AddServiceDiscovery();\n    });\n\n    // Uncomment the following to restrict the allowed schemes for service discovery.\n    // builder.Services.Configure<ServiceDiscoveryOptions>(options =>\n    // {\n    //     options.AllowedSchemes = [\"https\"];\n    // });\n\n    return builder;\n  }\n\n  public static TBuilder ConfigureOpenTelemetry<TBuilder>(this TBuilder builder) where TBuilder : IHostApplicationBuilder\n  {\n    builder.Logging.AddOpenTelemetry(logging =>\n    {\n      logging.IncludeFormattedMessage = true;\n      logging.IncludeScopes = true;\n    });\n\n    builder.Services.AddOpenTelemetry()\n        .WithMetrics(metrics =>\n        {\n          metrics.AddAspNetCoreInstrumentation()\n                  .AddHttpClientInstrumentation()\n                  .AddRuntimeInstrumentation();\n        })\n        .WithTracing(tracing =>\n        {\n          tracing.AddSource(builder.Environment.ApplicationName)\n                  .AddAspNetCoreInstrumentation(tracing =>\n                      // Exclude health check requests from tracing\n                      tracing.Filter = context =>\n                          !context.Request.Path.StartsWithSegments(HealthEndpointPath)\n                          && !context.Request.Path.StartsWithSegments(AlivenessEndpointPath)\n                  )\n                  // Uncomment the following line to enable gRPC instrumentation (requires the OpenTelemetry.Instrumentation.GrpcNetClient package)\n                  //.AddGrpcClientInstrumentation()\n                  .AddHttpClientInstrumentation();\n        });\n\n    builder.AddOpenTelemetryExporters();\n\n    return builder;\n  }\n\n  private static TBuilder AddOpenTelemetryExporters<TBuilder>(this TBuilder builder) where TBuilder : IHostApplicationBuilder\n  {\n    var useOtlpExporter = !string.IsNullOrWhiteSpace(builder.Configuration[\"OTEL_EXPORTER_OTLP_ENDPOINT\"]);\n\n    if (useOtlpExporter)\n    {\n      builder.Services.AddOpenTelemetry().UseOtlpExporter();\n    }\n\n    // Uncomment the following lines to enable the Azure Monitor exporter (requires the Azure.Monitor.OpenTelemetry.AspNetCore package)\n    //if (!string.IsNullOrEmpty(builder.Configuration[\"APPLICATIONINSIGHTS_CONNECTION_STRING\"]))\n    //{\n    //    builder.Services.AddOpenTelemetry()\n    //       .UseAzureMonitor();\n    //}\n\n    return builder;\n  }\n\n  public static TBuilder AddDefaultHealthChecks<TBuilder>(this TBuilder builder) where TBuilder : IHostApplicationBuilder\n  {\n    builder.Services.AddHealthChecks()\n        // Add a default liveness check to ensure app is responsive\n        .AddCheck(\"self\", () => HealthCheckResult.Healthy(), [\"live\"]);\n\n    return builder;\n  }\n\n  public static WebApplication MapDefaultEndpoints(this WebApplication app)\n  {\n    // Adding health checks endpoints to applications in non-development environments has security implications.\n    // See https://aka.ms/dotnet/aspire/healthchecks for details before enabling these endpoints in non-development environments.\n    if (app.Environment.IsDevelopment())\n    {\n      // All health checks must pass for app to be considered ready to accept traffic after starting\n      app.MapHealthChecks(HealthEndpointPath);\n\n      // Only health checks tagged with the \"live\" tag must pass for app to be considered alive\n      app.MapHealthChecks(AlivenessEndpointPath, new HealthCheckOptions\n      {\n        Predicate = r => r.Tags.Contains(\"live\")\n      });\n    }\n\n    return app;\n  }\n}\n"
  },
  {
    "path": "sample/src/NimblePros.SampleToDo.ServiceDefaults/NimblePros.SampleToDo.ServiceDefaults.csproj",
    "content": "<Project Sdk=\"Microsoft.NET.Sdk\">\n\n  <PropertyGroup>\n    <IsAspireSharedProject>true</IsAspireSharedProject>\n  </PropertyGroup>\n\n  <ItemGroup>\n    <FrameworkReference Include=\"Microsoft.AspNetCore.App\" />\n\n    <PackageReference Include=\"Microsoft.Extensions.Http.Resilience\" />\n    <PackageReference Include=\"Microsoft.Extensions.ServiceDiscovery\" />\n    <PackageReference Include=\"OpenTelemetry.Exporter.OpenTelemetryProtocol\" />\n    <PackageReference Include=\"OpenTelemetry.Extensions.Hosting\" />\n    <PackageReference Include=\"OpenTelemetry.Instrumentation.AspNetCore\" />\n    <PackageReference Include=\"OpenTelemetry.Instrumentation.Http\" />\n    <PackageReference Include=\"OpenTelemetry.Instrumentation.Runtime\" />\n  </ItemGroup>\n\n</Project>\n"
  },
  {
    "path": "sample/src/NimblePros.SampleToDo.UseCases/Constants.cs",
    "content": "﻿namespace NimblePros.SampleToDo.UseCases;\n\npublic class Constants\n{\n  public const int DEFAULT_PAGE_SIZE = 10;\n  public const int MAX_PAGE_SIZE = 100;\n}\n"
  },
  {
    "path": "sample/src/NimblePros.SampleToDo.UseCases/Contributors/Commands/Create/CreateContributorCommand.cs",
    "content": "﻿using NimblePros.SampleToDo.Core.ContributorAggregate;\n\nnamespace NimblePros.SampleToDo.UseCases.Contributors.Commands.Create;\n\n/// <summary>\n/// Create a new Contributor.\n/// </summary>\n/// <param name=\"Name\"></param>\npublic record CreateContributorCommand(ContributorName Name) : Mediator.ICommand<Result<int>>;\n"
  },
  {
    "path": "sample/src/NimblePros.SampleToDo.UseCases/Contributors/Commands/Create/CreateContributorHandler.cs",
    "content": "﻿using NimblePros.SampleToDo.Core.ContributorAggregate;\n\nnamespace NimblePros.SampleToDo.UseCases.Contributors.Commands.Create;\n\npublic class CreateContributorHandler(IRepository<Contributor> repository)\n  : ICommandHandler<CreateContributorCommand, Result<int>>\n{\n  private readonly IRepository<Contributor> _repository = repository;\n\n  public async ValueTask<Result<int>> Handle(CreateContributorCommand command, CancellationToken cancellationToken)\n  {\n    var newContributor = new Contributor(command.Name);\n    var createdItem = await _repository.AddAsync(newContributor, cancellationToken);\n\n    return createdItem.Id.Value;\n  }\n}\n"
  },
  {
    "path": "sample/src/NimblePros.SampleToDo.UseCases/Contributors/Commands/Delete/DeleteContributorCommand.cs",
    "content": "﻿using NimblePros.SampleToDo.Core.ContributorAggregate;\n\nnamespace NimblePros.SampleToDo.UseCases.Contributors.Commands.Delete;\n\npublic record DeleteContributorCommand(ContributorId ContributorId) : ICommand<Result>;\n"
  },
  {
    "path": "sample/src/NimblePros.SampleToDo.UseCases/Contributors/Commands/Delete/DeleteContributorHandler.cs",
    "content": "﻿using NimblePros.SampleToDo.Core.Interfaces;\n\nnamespace NimblePros.SampleToDo.UseCases.Contributors.Commands.Delete;\n\npublic class DeleteContributorHandler : ICommandHandler<DeleteContributorCommand, Result>\n{\n  private readonly IDeleteContributorService _deleteContributorService;\n\n  public DeleteContributorHandler(IDeleteContributorService deleteContributorService)\n  {\n    _deleteContributorService = deleteContributorService;\n  }\n\n  public async ValueTask<Result> Handle(DeleteContributorCommand request, CancellationToken cancellationToken)\n  {\n    // This Approach: Keep Domain Events in the Domain Model / Core project; this becomes a pass-through\n    return await _deleteContributorService.DeleteContributor(request.ContributorId);\n\n    // Another Approach: Do the real work here including dispatching domain events - change the event from internal to public\n    // Ardalis prefers using the service so that \"domain event\" behavior remains in the domain model / core project\n    // var aggregateToDelete = await _repository.GetByIdAsync(request.ContributorId);\n    // if (aggregateToDelete == null) return Result.NotFound();\n\n    // await _repository.DeleteAsync(aggregateToDelete);\n    // var domainEvent = new ContributorDeletedEvent(request.ContributorId);\n    // await _mediator.Publish(domainEvent);\n    // return Result.Success();\n  }\n}\n"
  },
  {
    "path": "sample/src/NimblePros.SampleToDo.UseCases/Contributors/Commands/Update/UpdateContributorCommand.cs",
    "content": "﻿using NimblePros.SampleToDo.Core.ContributorAggregate;\n\nnamespace NimblePros.SampleToDo.UseCases.Contributors.Commands.Update;\n\npublic record UpdateContributorCommand(ContributorId ContributorId, ContributorName NewName) : ICommand<Result<ContributorDto>>;\n"
  },
  {
    "path": "sample/src/NimblePros.SampleToDo.UseCases/Contributors/Commands/Update/UpdateContributorHandler.cs",
    "content": "﻿using NimblePros.SampleToDo.Core.ContributorAggregate;\nusing NimblePros.SampleToDo.Core.ContributorAggregate.Specifications;\n\nnamespace NimblePros.SampleToDo.UseCases.Contributors.Commands.Update;\n\npublic class UpdateContributorHandler : ICommandHandler<UpdateContributorCommand, Result<ContributorDto>>\n{\n  private readonly IRepository<Contributor> _repository;\n\n  public UpdateContributorHandler(IRepository<Contributor> repository)\n  {\n    _repository = repository;\n  }\n\n  public async ValueTask<Result<ContributorDto>> Handle(UpdateContributorCommand request, CancellationToken cancellationToken)\n  {\n    var spec = new ContributorByIdSpec(request.ContributorId);\n    var existingContributor = await _repository.SingleOrDefaultAsync(spec, cancellationToken);\n    if (existingContributor == null)\n    {\n      return Result.NotFound();\n    }\n\n    existingContributor.UpdateName(request.NewName!);\n\n    await _repository.UpdateAsync(existingContributor, cancellationToken);\n\n    return Result.Success(new ContributorDto(existingContributor.Id, existingContributor.Name));\n  }\n}\n"
  },
  {
    "path": "sample/src/NimblePros.SampleToDo.UseCases/Contributors/ContributorDTO.cs",
    "content": "﻿using NimblePros.SampleToDo.Core.ContributorAggregate;\n\nnamespace NimblePros.SampleToDo.UseCases.Contributors;\npublic record ContributorDto(ContributorId Id, ContributorName Name);\n"
  },
  {
    "path": "sample/src/NimblePros.SampleToDo.UseCases/Contributors/Queries/Get/GetContributorHandler.cs",
    "content": "﻿using NimblePros.SampleToDo.Core.ContributorAggregate;\nusing NimblePros.SampleToDo.Core.ContributorAggregate.Specifications;\n\nnamespace NimblePros.SampleToDo.UseCases.Contributors.Queries.Get;\n\n/// <summary>\n/// Queries don't necessarily need to use repository methods, but they can if it's convenient\n/// </summary>\npublic class GetContributorHandler(IReadRepository<Contributor> repository)\n  : IQueryHandler<GetContributorQuery, Result<ContributorDto>>\n{\n  private readonly IReadRepository<Contributor> _repository = repository;\n\n  public async ValueTask<Result<ContributorDto>> Handle(GetContributorQuery request, CancellationToken cancellationToken)\n  {\n    var spec = new ContributorByIdSpec(request.ContributorId);\n    var entity = await _repository.FirstOrDefaultAsync(spec, cancellationToken);\n    if (entity == null) return Result.NotFound();\n\n    return new ContributorDto(entity.Id, entity.Name);\n  }\n}\n"
  },
  {
    "path": "sample/src/NimblePros.SampleToDo.UseCases/Contributors/Queries/Get/GetContributorQuery.cs",
    "content": "﻿using NimblePros.SampleToDo.Core.ContributorAggregate;\n\nnamespace NimblePros.SampleToDo.UseCases.Contributors.Queries.Get;\n\npublic record GetContributorQuery(ContributorId ContributorId) : IQuery<Result<ContributorDto>>, ICacheable\n{\n  public string? CacheProfile => null;\n\n  public string GetCacheKey()\n  {\n    return $\"{nameof(GetContributorQuery)}-{ContributorId.Value}\";\n  }\n}\n"
  },
  {
    "path": "sample/src/NimblePros.SampleToDo.UseCases/Contributors/Queries/List/IListContributorsQueryService.cs",
    "content": "﻿namespace NimblePros.SampleToDo.UseCases.Contributors.Queries.List;\n\n/// <summary>\n/// Represents a service that will actually fetch the necessary data\n/// Typically implemented in Infrastructure\n/// </summary>\npublic interface IListContributorsQueryService\n{\n  Task<PagedResult<ContributorDto>> ListAsync(int page, int perPage);\n}\n"
  },
  {
    "path": "sample/src/NimblePros.SampleToDo.UseCases/Contributors/Queries/List/ListContributorsHandler.cs",
    "content": "﻿namespace NimblePros.SampleToDo.UseCases.Contributors.Queries.List;\n\npublic class ListContributorsHandler : IQueryHandler<ListContributorsQuery, Result<PagedResult<ContributorDto>>>\n{\n  private readonly IListContributorsQueryService _query;\n\n  public ListContributorsHandler(IListContributorsQueryService query)\n  {\n    _query = query;\n  }\n\n  public async ValueTask<Result<PagedResult<ContributorDto>>> Handle(ListContributorsQuery request,\n                                                                     CancellationToken cancellationToken)\n  {\n\n    var result = await _query.ListAsync(request.Page ?? 1, request.PerPage ?? Constants.DEFAULT_PAGE_SIZE);\n\n    return Result.Success(result);\n  }\n}\n"
  },
  {
    "path": "sample/src/NimblePros.SampleToDo.UseCases/Contributors/Queries/List/ListContributorsQuery.cs",
    "content": "﻿namespace NimblePros.SampleToDo.UseCases.Contributors.Queries.List;\n\npublic record ListContributorsQuery(int? Page = 1, int? PerPage = Constants.DEFAULT_PAGE_SIZE)\n  : IQuery<Result<PagedResult<ContributorDto>>>, ICacheable\n{\n  public string? CacheProfile => \"Long\";\n\n  public string GetCacheKey()\n  {\n    return $\"{nameof(ListContributorsQuery)}-{Page}-{PerPage}\";\n  }\n}\n"
  },
  {
    "path": "sample/src/NimblePros.SampleToDo.UseCases/GlobalUsings.cs",
    "content": "﻿global using Ardalis.Result;\nglobal using Mediator;\nglobal using NimblePros.SharedKernel;\n"
  },
  {
    "path": "sample/src/NimblePros.SampleToDo.UseCases/ICacheable.cs",
    "content": "﻿namespace NimblePros.SampleToDo.UseCases;\npublic interface ICacheable\n{\n  string GetCacheKey();\n  string? CacheProfile { get; } // TODO: Use SmartEnum for this with CacheProfile.None\n}\n"
  },
  {
    "path": "sample/src/NimblePros.SampleToDo.UseCases/NimblePros.SampleToDo.UseCases.csproj",
    "content": "﻿<Project Sdk=\"Microsoft.NET.Sdk\">\n  <ItemGroup>\n    <Compile Remove=\"Projects\\AddContributorToItem\\**\" />\n    <EmbeddedResource Remove=\"Projects\\AddContributorToItem\\**\" />\n    <None Remove=\"Projects\\AddContributorToItem\\**\" />\n  </ItemGroup>\n\n  <ItemGroup>\n    <PackageReference Include=\"Ardalis.Result\" />\n    <PackageReference Include=\"Microsoft.EntityFrameworkCore.Relational\" />\n    <PackageReference Include=\"NimblePros.SharedKernel\" />\n  </ItemGroup>\n\n  <ItemGroup>\n    <ProjectReference Include=\"..\\NimblePros.SampleToDo.Core\\NimblePros.SampleToDo.Core.csproj\" />\n  </ItemGroup>\n\n</Project>\n"
  },
  {
    "path": "sample/src/NimblePros.SampleToDo.UseCases/PagedResult.cs",
    "content": "﻿namespace NimblePros.SampleToDo.UseCases;\n\npublic record PagedResult<T>(\n  IReadOnlyList<T> Items,\n  int Page,\n  int PerPage,\n  int TotalCount,\n  int TotalPages);\n"
  },
  {
    "path": "sample/src/NimblePros.SampleToDo.UseCases/Projects/AddToDoItem/AddToDoItemCommand.cs",
    "content": "﻿using NimblePros.SampleToDo.Core.ContributorAggregate;\nusing NimblePros.SampleToDo.Core.ProjectAggregate;\n\nnamespace NimblePros.SampleToDo.UseCases.Projects.AddToDoItem;\n\n/// <summary>\n/// Creates a new ToDoItem and adds it to a Project\n/// </summary>\n/// <param name=\"ProjectId\"></param>\n/// <param name=\"ContributorId\"></param>\n/// <param name=\"Title\"></param>\n/// <param name=\"Description\"></param>\npublic record AddToDoItemCommand(ProjectId ProjectId,\n                                 ContributorId? ContributorId,\n                                 ToDoItemTitle Title,\n                                 ToDoItemDescription Description) : ICommand<Result<ToDoItemId>>;\n"
  },
  {
    "path": "sample/src/NimblePros.SampleToDo.UseCases/Projects/AddToDoItem/AddToDoItemHandler.cs",
    "content": "﻿using NimblePros.SampleToDo.Core.ProjectAggregate;\nusing NimblePros.SampleToDo.Core.ProjectAggregate.Specifications;\n\nnamespace NimblePros.SampleToDo.UseCases.Projects.AddToDoItem;\n\npublic class AddToDoItemHandler : ICommandHandler<AddToDoItemCommand, Result<ToDoItemId>>\n{\n  private readonly IRepository<Project> _repository;\n\n  public AddToDoItemHandler(IRepository<Project> repository)\n  {\n    _repository = repository;\n  }\n\n  public async ValueTask<Result<ToDoItemId>> Handle(AddToDoItemCommand request,\n    CancellationToken cancellationToken)\n  {\n    var spec = new ProjectByIdWithItemsSpec(request.ProjectId);\n    var entity = await _repository.FirstOrDefaultAsync(spec, cancellationToken);\n    if (entity == null)\n    {\n      return Result.NotFound();\n    }\n\n    var newItem = new ToDoItem(title: request.Title!, description: request.Description!);\n\n    if (request.ContributorId.HasValue)\n    {\n      newItem.AddContributor(request.ContributorId.Value);\n    }\n    entity.AddItem(newItem);\n    await _repository.UpdateAsync(entity);\n\n    return Result.Success(newItem.Id);\n  }\n}\n"
  },
  {
    "path": "sample/src/NimblePros.SampleToDo.UseCases/Projects/Create/CreateProjectCommand.cs",
    "content": "﻿using NimblePros.SampleToDo.Core.ProjectAggregate;\n\nnamespace NimblePros.SampleToDo.UseCases.Projects.Create;\n\n/// <summary>\n/// Create a new Project.\n/// </summary>\n/// <param name=\"Name\"></param>\npublic record CreateProjectCommand(ProjectName Name) : ICommand<Result<ProjectId>>;\n"
  },
  {
    "path": "sample/src/NimblePros.SampleToDo.UseCases/Projects/Create/CreateProjectHandler.cs",
    "content": "﻿using NimblePros.SampleToDo.Core.ProjectAggregate;\n\nnamespace NimblePros.SampleToDo.UseCases.Projects.Create;\n\npublic class CreateProjectHandler(IRepository<Project> repository) : ICommandHandler<CreateProjectCommand, Result<ProjectId>>\n{\n  private readonly IRepository<Project> _repository = repository;\n\n  public async ValueTask<Result<ProjectId>> Handle(CreateProjectCommand request,\n    CancellationToken cancellationToken)\n  {\n    var newProject = new Project(request.Name);\n    // NOTE: This implementation issues 3 queries due to Vogen implementation\n    var createdItem = await _repository.AddAsync(newProject, cancellationToken);\n\n    return createdItem.Id;\n  }\n}\n"
  },
  {
    "path": "sample/src/NimblePros.SampleToDo.UseCases/Projects/Delete/DeleteProjectCommand.cs",
    "content": "﻿using NimblePros.SampleToDo.Core.ProjectAggregate;\n\nnamespace NimblePros.SampleToDo.UseCases.Projects.Delete;\n\npublic record DeleteProjectCommand(ProjectId ProjectId) : ICommand<Result>;\n"
  },
  {
    "path": "sample/src/NimblePros.SampleToDo.UseCases/Projects/Delete/DeleteProjectHandler.cs",
    "content": "﻿using NimblePros.SampleToDo.Core.ProjectAggregate;\n\nnamespace NimblePros.SampleToDo.UseCases.Projects.Delete;\n\npublic class DeleteProjectHandler : ICommandHandler<DeleteProjectCommand, Result>\n{\n  private readonly IRepository<Project> _repository;\n\n  public DeleteProjectHandler(IRepository<Project> repository)\n  {\n    _repository = repository;\n  }\n\n  public async ValueTask<Result> Handle(DeleteProjectCommand request, CancellationToken cancellationToken)\n  {\n    var aggregateToDelete = await _repository.GetByIdAsync(request.ProjectId, cancellationToken);\n    if (aggregateToDelete == null)\n    {\n      return Result.NotFound();\n    }\n\n    await _repository.DeleteAsync(aggregateToDelete, cancellationToken);\n\n    return Result.Success();\n  }\n}\n"
  },
  {
    "path": "sample/src/NimblePros.SampleToDo.UseCases/Projects/GetWithAllItems/GetProjectWithAllItemsHandler.cs",
    "content": "﻿using NimblePros.SampleToDo.Core.ProjectAggregate;\nusing NimblePros.SampleToDo.Core.ProjectAggregate.Specifications;\n\nnamespace NimblePros.SampleToDo.UseCases.Projects.GetWithAllItems;\n\n/// <summary>\n/// Queries don't necessarily need to use repository methods, but they can if it's convenient\n/// </summary>\npublic class GetProjectWithAllItemsHandler : IQueryHandler<GetProjectWithAllItemsQuery, Result<ProjectWithAllItemsDto>>\n{\n  private readonly IReadRepository<Project> _repository;\n\n  public GetProjectWithAllItemsHandler(IReadRepository<Project> repository)\n  {\n    _repository = repository;\n  }\n\n  public async ValueTask<Result<ProjectWithAllItemsDto>> Handle(GetProjectWithAllItemsQuery request, CancellationToken cancellationToken)\n  {\n    var spec = new ProjectByIdWithItemsSpec(request.ProjectId);\n    var project = await _repository.FirstOrDefaultAsync(spec, cancellationToken);\n    if (project == null) return Result.NotFound();\n\n    var items = project.Items\n              .Select(i => new ToDoItemDto(i.Id, i.Title.Value, i.Description.Value, i.IsDone, i.ContributorId)).ToList();\n    return new ProjectWithAllItemsDto(project.Id, project.Name, items, project.Status.ToString())\n      ;\n  }\n}\n"
  },
  {
    "path": "sample/src/NimblePros.SampleToDo.UseCases/Projects/GetWithAllItems/GetProjectWithAllItemsQuery.cs",
    "content": "﻿using NimblePros.SampleToDo.Core.ProjectAggregate;\n\nnamespace NimblePros.SampleToDo.UseCases.Projects.GetWithAllItems;\n\npublic record GetProjectWithAllItemsQuery(ProjectId ProjectId) : \n  IQuery<Result<ProjectWithAllItemsDto>>, ICacheable\n{\n  public string? CacheProfile => \"Short\";\n\n  public string GetCacheKey()\n  {\n    return $\"{nameof(GetProjectWithAllItemsQuery)}-{ProjectId}\";\n  }\n}\n"
  },
  {
    "path": "sample/src/NimblePros.SampleToDo.UseCases/Projects/ListIncompleteItems/IListIncompleteItemsQueryService.cs",
    "content": "﻿namespace NimblePros.SampleToDo.UseCases.Projects.ListIncompleteItems;\n\n/// <summary>\n/// Represents a service that will actually fetch the necessary data\n/// Typically implemented in Infrastructure\n/// </summary>\npublic interface IListIncompleteItemsQueryService\n{\n  Task<IEnumerable<ToDoItemDto>> ListAsync(int projectId);\n}\n"
  },
  {
    "path": "sample/src/NimblePros.SampleToDo.UseCases/Projects/ListIncompleteItems/ListIncompleteItemsByProjectHandler.cs",
    "content": "﻿namespace NimblePros.SampleToDo.UseCases.Projects.ListIncompleteItems;\n\npublic class ListIncompleteItemsByProjectHandler : IQueryHandler<ListIncompleteItemsByProjectQuery, Result<IEnumerable<ToDoItemDto>>>\n{\n  private readonly IListIncompleteItemsQueryService _query;\n\n  public ListIncompleteItemsByProjectHandler(IListIncompleteItemsQueryService query)\n  {\n    _query = query;\n  }\n\n  public async ValueTask<Result<IEnumerable<ToDoItemDto>>> Handle(ListIncompleteItemsByProjectQuery request,\n    CancellationToken cancellationToken)\n  {\n    var result = await _query.ListAsync(request.ProjectId);\n\n    return Result.Success(result);\n  }\n}\n"
  },
  {
    "path": "sample/src/NimblePros.SampleToDo.UseCases/Projects/ListIncompleteItems/ListIncompleteItemsByProjectQuery.cs",
    "content": "﻿namespace NimblePros.SampleToDo.UseCases.Projects.ListIncompleteItems;\n\npublic record ListIncompleteItemsByProjectQuery(int ProjectId) : \n  IQuery<Result<IEnumerable<ToDoItemDto>>>, ICacheable\n{\n  public string? CacheProfile => null;\n\n  public string GetCacheKey()\n  {\n    return $\"{nameof(ListIncompleteItemsByProjectQuery)}-{ProjectId}\";\n  }\n}\n"
  },
  {
    "path": "sample/src/NimblePros.SampleToDo.UseCases/Projects/ListShallow/IListProjectsShallowQueryService.cs",
    "content": "﻿namespace NimblePros.SampleToDo.UseCases.Projects.ListShallow;\n\n/// <summary>\n/// Represents a service that will actually fetch the necessary data\n/// Typically implemented in Infrastructure\n/// </summary>\npublic interface IListProjectsShallowQueryService\n{\n  Task<IEnumerable<ProjectDto>> ListAsync();\n}\n"
  },
  {
    "path": "sample/src/NimblePros.SampleToDo.UseCases/Projects/ListShallow/ListProjectsShallowHandler.cs",
    "content": "﻿namespace NimblePros.SampleToDo.UseCases.Projects.ListShallow;\n\npublic class ListProjectsShallowHandler(IListProjectsShallowQueryService query)\n  : IQueryHandler<ListProjectsShallowQuery, Result<IEnumerable<ProjectDto>>>\n{\n  private readonly IListProjectsShallowQueryService _query = query;\n\n  public async ValueTask<Result<IEnumerable<ProjectDto>>> Handle(ListProjectsShallowQuery request, CancellationToken cancellationToken)\n  {\n    var result = await _query.ListAsync();\n\n    return Result.Success(result);\n  }\n}\n"
  },
  {
    "path": "sample/src/NimblePros.SampleToDo.UseCases/Projects/ListShallow/ListProjectsShallowQuery.cs",
    "content": "﻿namespace NimblePros.SampleToDo.UseCases.Projects.ListShallow;\n\npublic record ListProjectsShallowQuery(int? Skip, int? Take) :\n  IQuery<Result<IEnumerable<ProjectDto>>>, ICacheable\n{\n  public string? CacheProfile => null;\n\n  public string GetCacheKey()\n  {\n    return $\"{nameof(ListProjectsShallowQuery)}-{Skip}-{Take}\";\n  }\n}\n"
  },
  {
    "path": "sample/src/NimblePros.SampleToDo.UseCases/Projects/MarkToDoItemComplete/MarkToDoItemCompleteCommand.cs",
    "content": "﻿using NimblePros.SampleToDo.Core.ProjectAggregate;\n\nnamespace NimblePros.SampleToDo.UseCases.Projects.MarkToDoItemComplete;\n\n/// <summary>\n/// Create a new Project.\n/// </summary>\n/// <param name=\"Name\"></param>\npublic record MarkToDoItemCompleteCommand(ProjectId ProjectId, int ToDoItemId) : ICommand<Result>;\n"
  },
  {
    "path": "sample/src/NimblePros.SampleToDo.UseCases/Projects/MarkToDoItemComplete/MarkToDoItemCompleteHandler.cs",
    "content": "﻿using NimblePros.SampleToDo.Core.ProjectAggregate;\nusing NimblePros.SampleToDo.Core.ProjectAggregate.Specifications;\n\nnamespace NimblePros.SampleToDo.UseCases.Projects.MarkToDoItemComplete;\n\npublic class MarkToDoItemCompleteHandler : ICommandHandler<MarkToDoItemCompleteCommand, Result>\n{\n  private readonly IRepository<Project> _repository;\n\n  public MarkToDoItemCompleteHandler(IRepository<Project> repository)\n  {\n    _repository = repository;\n  }\n\n  public async ValueTask<Result> Handle(MarkToDoItemCompleteCommand request,\n    CancellationToken cancellationToken)\n  {\n    var spec = new ProjectByIdWithItemsSpec(request.ProjectId);\n    var entity = await _repository.FirstOrDefaultAsync(spec, cancellationToken);\n    if (entity == null) return Result.NotFound(\"Project not found.\");\n\n    var item = entity.Items.FirstOrDefault(i => i.Id == request.ToDoItemId);\n    if (item == null) return Result.NotFound(\"Item not found.\");\n\n    item.MarkComplete();\n    await _repository.UpdateAsync(entity);\n\n    return Result.Success();\n  }\n}\n"
  },
  {
    "path": "sample/src/NimblePros.SampleToDo.UseCases/Projects/ProjectDTO.cs",
    "content": "﻿namespace NimblePros.SampleToDo.UseCases.Projects;\n\npublic record ProjectDto(int Id, string Name, string Status);\n"
  },
  {
    "path": "sample/src/NimblePros.SampleToDo.UseCases/Projects/ProjectWithAllItemsDTO.cs",
    "content": "﻿using NimblePros.SampleToDo.Core.ProjectAggregate;\n\nnamespace NimblePros.SampleToDo.UseCases.Projects;\npublic record ProjectWithAllItemsDto(ProjectId Id, ProjectName Name, List<ToDoItemDto> Items, string Status);\n"
  },
  {
    "path": "sample/src/NimblePros.SampleToDo.UseCases/Projects/ToDoItemDTO.cs",
    "content": "﻿using NimblePros.SampleToDo.Core.ContributorAggregate;\nusing NimblePros.SampleToDo.Core.ProjectAggregate;\n\nnamespace NimblePros.SampleToDo.UseCases.Projects;\n\npublic record ToDoItemDto(ToDoItemId Id, string Title, string Description, bool IsComplete, ContributorId? ContributorId);\n"
  },
  {
    "path": "sample/src/NimblePros.SampleToDo.UseCases/Projects/Update/UpdateProjectCommand.cs",
    "content": "﻿using NimblePros.SampleToDo.Core.ProjectAggregate;\n\nnamespace NimblePros.SampleToDo.UseCases.Projects.Update;\n\npublic record UpdateProjectCommand(ProjectId ProjectId, ProjectName NewName) : ICommand<Result<ProjectDto>>;\n"
  },
  {
    "path": "sample/src/NimblePros.SampleToDo.UseCases/Projects/Update/UpdateProjectHandler.cs",
    "content": "﻿using NimblePros.SampleToDo.Core.ProjectAggregate;\n\nnamespace NimblePros.SampleToDo.UseCases.Projects.Update;\n\npublic class UpdateProjectHandler : ICommandHandler<UpdateProjectCommand, Result<ProjectDto>>\n{\n  private readonly IRepository<Project> _repository;\n\n  public UpdateProjectHandler(IRepository<Project> repository)\n  {\n    _repository = repository;\n  }\n\n  public async ValueTask<Result<ProjectDto>> Handle(UpdateProjectCommand request, CancellationToken cancellationToken)\n  {\n    var existingEntity = await _repository.GetByIdAsync(request.ProjectId, cancellationToken);\n    if (existingEntity == null)\n    {\n      return Result.NotFound();\n    }\n\n    existingEntity.UpdateName(request.NewName!);\n\n    await _repository.UpdateAsync(existingEntity, cancellationToken);\n\n    return Result.Success(new ProjectDto(existingEntity.Id.Value, existingEntity.Name.Value, existingEntity.Status.ToString()));\n  }\n}\n"
  },
  {
    "path": "sample/src/NimblePros.SampleToDo.UseCases/README.md",
    "content": "﻿## Use Cases Project\n\nIn Clean Architecture, the Use Cases (or Application Services) project is a relatively thin layer that wraps the domain model.\n\nUse Cases are typically organized by feature. These may be simple CRUD operations or much more complex activities.\n\nUse Cases should not depend directly on infrastructure concerns, making them simple to unit test in most cases.\n\nUse Cases are often grouped into Commands and Queries, following CQRS.\n\nHaving Use Cases as a separate project can reduce the amount of logic in UI and Infrastructure projects.\n\nFor simpler projects, the Use Cases project can be omitted, and its behavior moved into the UI project, either as using separate services or Mediator handlers, or by simply putting the logic into the API endpoints.\n"
  },
  {
    "path": "sample/src/NimblePros.SampleToDo.Web/CachingBehavior.cs",
    "content": "﻿using Ardalis.GuardClauses;\nusing Microsoft.Extensions.Caching.Memory;\nusing Microsoft.Extensions.Options;\nusing NimblePros.SampleToDo.UseCases;\nusing NimblePros.SampleToDo.Web.Configurations;\n\nnamespace NimblePros.SampleToDo.Web;\n\npublic class CachingBehavior<TRequest, TResponse>(IMemoryCache cache,\n                                                  ILogger<CachingBehavior<TRequest, TResponse>> logger,\n                                                  IOptions<CachingOptions> cachingOptions) :\n    IPipelineBehavior<TRequest, TResponse?>\n    where TRequest : notnull, IMessage\n{\n  private readonly IMemoryCache _cache = cache;\n  private readonly ILogger<CachingBehavior<TRequest, TResponse>> _logger = logger;\n  private readonly CachingOptions _cachingOptions = cachingOptions.Value;\n\n  public async ValueTask<TResponse?> Handle(\n      TRequest request,\n      Mediator.MessageHandlerDelegate<TRequest, TResponse?> next,\n      CancellationToken cancellationToken)\n  {\n    Guard.Against.Null(request, nameof(request));\n\n    if (request is not ICacheable cacheable) return await next(request, cancellationToken);\n\n    int cacheDurationSeconds = _cachingOptions.DefaultDurationSeconds;\n    if (cacheable.CacheProfile != null)\n    {\n      var profile = _cachingOptions.Profiles.FirstOrDefault(p => p.Name.Equals(cacheable.CacheProfile, StringComparison.OrdinalIgnoreCase));\n      if (profile != null)\n      {\n        _logger.LogInformation(\"Using cache profile {ProfileName} with duration {DurationSeconds} seconds.\", profile.Name, profile.CacheDurationSeconds);\n        cacheDurationSeconds = profile?.CacheDurationSeconds ?? _cachingOptions.DefaultDurationSeconds;\n      }\n    }\n    var cacheOptions =\n        new MemoryCacheEntryOptions()\n            .SetAbsoluteExpiration(TimeSpan.FromSeconds(cacheDurationSeconds));\n\n\n  var cacheKey = cacheable.GetCacheKey();\n    _logger.LogDebug(\"Checking cache for {CacheKey}\", cacheKey);\n    return await _cache.GetOrCreateAsync(cacheKey, async entry =>\n    {\n      _logger.LogInformation($\"Cache miss. Getting data from database. ({cacheKey})\");\n      entry.SetOptions(cacheOptions);\n      return await next(request, cancellationToken);\n    });\n  }\n}\n"
  },
  {
    "path": "sample/src/NimblePros.SampleToDo.Web/Configurations/CachingOptions.cs",
    "content": "﻿namespace NimblePros.SampleToDo.Web.Configurations;\n\npublic class CachingOptions\n{\n  public const string SectionName = \"Caching\";\n  public int DefaultDurationSeconds { get; set; } = 10;\n  public List<CachingProfile> Profiles { get; set; } = [];\n}\n"
  },
  {
    "path": "sample/src/NimblePros.SampleToDo.Web/Configurations/CachingProfile.cs",
    "content": "﻿namespace NimblePros.SampleToDo.Web.Configurations;\n\npublic class CachingProfile\n{\n  public string Name { get; set; } = string.Empty;\n  public int CacheDurationSeconds { get; set; }\n}\n"
  },
  {
    "path": "sample/src/NimblePros.SampleToDo.Web/Configurations/GlobalExceptionHandler.cs",
    "content": "﻿using Microsoft.AspNetCore.Diagnostics;\n\nnamespace NimblePros.SampleToDo.Web.Configurations;\n\npublic class GlobalExceptionHandler(\n  IHostEnvironment env, \n  ILogger<GlobalExceptionHandler> logger) : IExceptionHandler\n{\n  public async ValueTask<bool> TryHandleAsync(HttpContext httpContext, Exception exception, CancellationToken cancellationToken)\n  {\n    logger.LogError(exception, \"Unhandled exception occurred\");\n\n    var problemDetails = new\n    {\n      type = \"https://tools.ietf.org/html/rfc7231#section-6.6.1\",\n      title = \"Internal Server Error\",\n      status = StatusCodes.Status500InternalServerError,\n      detail = env.IsDevelopment() ? exception.Message : \"An internal server error occurred\",\n      instance = httpContext.Request.Path\n    };\n\n    httpContext.Response.StatusCode = StatusCodes.Status500InternalServerError;\n    httpContext.Response.ContentType = \"application/json\";\n    \n    await httpContext.Response.WriteAsJsonAsync(problemDetails, cancellationToken);\n    return true;\n  }\n}\n"
  },
  {
    "path": "sample/src/NimblePros.SampleToDo.Web/Configurations/LoggerConfig.cs",
    "content": "﻿namespace NimblePros.SampleToDo.Web.Configurations;\n\npublic static class LoggerConfig\n{\n  public static WebApplicationBuilder AddLoggerConfigs(this WebApplicationBuilder builder)\n  {\n    builder.Host.UseSerilog((_, config) => config.ReadFrom.Configuration(builder.Configuration));\n\n    return builder;\n  }\n}\n"
  },
  {
    "path": "sample/src/NimblePros.SampleToDo.Web/Configurations/MediatorConfig.cs",
    "content": "﻿using NimblePros.SampleToDo.Core.ContributorAggregate;\nusing NimblePros.SampleToDo.Infrastructure;\nusing NimblePros.SampleToDo.UseCases.Contributors.Commands.Create;\n\nnamespace NimblePros.SampleToDo.Web.Configurations;\n\npublic static class MediatorConfig\n{\n  // Should be called from ServiceConfigs.cs, not Program.cs\n  public static IServiceCollection AddMediatorSourceGen(this IServiceCollection services, \n    Microsoft.Extensions.Logging.ILogger logger)\n  {\n    logger.LogInformation(\"Registering Mediator SourceGen and Behaviors\");\n    services.AddMediator(options =>\n    {\n      // Lifetime: Singleton is fastest per docs; Scoped/Transient also supported.\n      options.ServiceLifetime = ServiceLifetime.Scoped;\n\n      // Supply any TYPE from each assembly you want scanned (the generator finds the assembly from the type)\n      options.Assemblies =\n      [\n        typeof(Contributor),                       // Core\n        typeof(CreateContributorCommand),         // UseCases\n        typeof(InfrastructureServiceExtensions), // Infrastructure\n        typeof(MediatorConfig)                  // Web\n      ];\n\n      // Register pipeline behaviors here (order matters)\n      options.PipelineBehaviors =\n      [\n        typeof(LoggingBehavior<,>),\n        typeof(CachingBehavior<,>)\n      ];\n\n      // If you have stream behaviors:\n      // options.StreamPipelineBehaviors = [ typeof(YourStreamBehavior<,>) ];\n    });\n\n    // Alternative: register behaviors via DI yourself (useful if not doing AOT):\n    // services.AddScoped(typeof(IPipelineBehavior<,>), typeof(LoggingBehavior<,>));\n    // services.AddScoped(typeof(IPipelineBehavior<,>), typeof(CachingBehavior<,>));\n\n    return services;\n  }\n}\n"
  },
  {
    "path": "sample/src/NimblePros.SampleToDo.Web/Configurations/MiddlewareConfig.cs",
    "content": "﻿using NimblePros.Metronome;\nusing NimblePros.SampleToDo.Infrastructure.Data;\n\nnamespace NimblePros.SampleToDo.Web.Configurations;\n\npublic static class MiddlewareConfig\n{\n  public static async Task<IApplicationBuilder> UseAppMiddleware(this WebApplication app)\n  {\n    // Use global exception handler in both dev and prod\n    app.UseExceptionHandler();\n\n    if (app.Environment.IsDevelopment())\n    {\n      app.UseShowAllServicesMiddleware(); // see https://github.com/ardalis/AspNetCoreStartupServices\n      app.UseMetronomeLoggingMiddleware();\n    }\n    else\n    {\n      app.UseHsts();\n    }\n\n    app.UseFastEndpoints()\n        .UseSwaggerGen(); // Includes AddFileServer and static files middleware\n\n    app.UseHttpsRedirection();\n\n    await SeedDatabase(app);\n\n    app.MapDefaultEndpoints(); // aspire health checks\n\n    return app;\n  }\n\n  static async Task SeedDatabase(WebApplication app)\n  {\n    using var scope = app.Services.CreateScope();\n    var services = scope.ServiceProvider;\n\n    try\n    {\n      var context = services.GetRequiredService<AppDbContext>();\n      //          context.Database.Migrate();\n      context.Database.EnsureCreated();\n      await SeedData.InitializeAsync(context);\n    }\n    catch (Exception ex)\n    {\n      var logger = services.GetRequiredService<ILogger<Program>>();\n      logger.LogError(ex, \"An error occurred seeding the DB. {exceptionMessage}\", ex.Message);\n    }\n  }\n}\n"
  },
  {
    "path": "sample/src/NimblePros.SampleToDo.Web/Configurations/OptionConfigs.cs",
    "content": "﻿using NimblePros.SampleToDo.Infrastructure.Email;\n\nnamespace NimblePros.SampleToDo.Web.Configurations;\n\npublic static class OptionConfig\n{\n  public static IServiceCollection AddOptionConfigs(this IServiceCollection services,\n                                                    IConfiguration configuration,\n                                                    Microsoft.Extensions.Logging.ILogger logger,\n                                                    WebApplicationBuilder builder)\n  {\n    services.Configure<MailserverConfiguration>(configuration.GetSection(MailserverConfiguration.SectionName));\n    services.Configure<CachingOptions>(builder.Configuration.GetSection(CachingOptions.SectionName));\n\n    services.Configure<CookiePolicyOptions>(options =>\n    {\n      options.CheckConsentNeeded = context => true;\n      options.MinimumSameSitePolicy = SameSiteMode.None;\n    });\n\n    // Register global exception handler\n    services.AddExceptionHandler<GlobalExceptionHandler>();\n    services.AddProblemDetails();\n\n    if (builder.Environment.IsDevelopment())\n    {\n      // add list services for diagnostic purposes - see https://github.com/ardalis/AspNetCoreStartupServices\n      services.Configure((Ardalis.ListStartupServices.ServiceConfig config) =>\n      {\n        config.Services = new List<ServiceDescriptor>(builder.Services);\n\n        // optional - default path to view services is /listallservices - recommended to choose your own path\n        config.Path = \"/listservices\";\n      });\n    }\n\n    logger.LogInformation(\"{Project} were configured\", \"Configuration and Options\");\n\n    return services;\n  }\n}\n"
  },
  {
    "path": "sample/src/NimblePros.SampleToDo.Web/Configurations/ServiceConfigs.cs",
    "content": "﻿using NimblePros.Metronome;\nusing NimblePros.SampleToDo.Core;\nusing NimblePros.SampleToDo.Infrastructure;\n\nnamespace NimblePros.SampleToDo.Web.Configurations;\n\npublic static class ServiceConfig\n{\n  public static IServiceCollection AddServiceConfigs(this IServiceCollection services,\n                                                     Microsoft.Extensions.Logging.ILogger logger,\n                                                     WebApplicationBuilder builder)\n  {\n    services.AddCoreServices(logger)\n            .AddInfrastructureServices(builder.Configuration, logger, builder.Environment.EnvironmentName)\n            .AddMediatorSourceGen(logger);\n\n    // add a default http client\n    services.AddHttpClient(\"Default\")\n      .AddMetronomeHandler();\n\n    return services;\n  }\n}\n"
  },
  {
    "path": "sample/src/NimblePros.SampleToDo.Web/Contributors/ContributorRecord.cs",
    "content": "﻿namespace NimblePros.SampleToDo.Web.Contributors;\n\npublic record ContributorRecord(int Id, string Name);\n"
  },
  {
    "path": "sample/src/NimblePros.SampleToDo.Web/Contributors/Create.cs",
    "content": "﻿using System.ComponentModel.DataAnnotations;\nusing FluentValidation;\nusing NimblePros.SampleToDo.Core.ContributorAggregate;\nusing NimblePros.SampleToDo.UseCases.Contributors.Commands.Create;\nusing NimblePros.SampleToDo.Web.Extensions;\n\nnamespace NimblePros.SampleToDo.Web.Contributors;\n\n// This shows an example of having all related types in one file for simplicity.\n// Fast-Endpoints generally uses one file per class for larger projects, which\n// is the recommended approach. More files, but fewer merge conflicts and easier to \n// see what changed in a given commit or PR.\n\npublic class Create(IMediator mediator)\n  : Endpoint<CreateContributorRequest, \n          Results<Created<CreateContributorResponse>,\n                          ValidationProblem,\n                          ProblemHttpResult>>\n{\n  private readonly IMediator _mediator = mediator;\n\n  public override void Configure()\n  {\n    Post(CreateContributorRequest.Route);\n    AllowAnonymous();\n    Summary(s =>\n    {\n      s.Summary = \"Create a new contributor\";\n      s.Description = \"Creates a new contributor with the provided name. The contributor name must be between 2 and 100 characters long.\";\n      s.ExampleRequest = new CreateContributorRequest { Name = \"John Doe\" };\n      s.ResponseExamples[201] = new CreateContributorResponse(1, \"John Doe\");\n      \n      // Document possible responses\n      s.Responses[201] = \"Contributor created successfully\";\n      s.Responses[400] = \"Invalid input data - validation errors\";\n      s.Responses[500] = \"Internal server error\";\n    });\n    \n    // Add tags for API grouping\n    Tags(\"Contributors\");\n    \n    // Add additional metadata\n    Description(builder => builder\n      .Accepts<CreateContributorRequest>(\"application/json\")\n      .Produces<CreateContributorResponse>(201, \"application/json\")\n      .ProducesProblem(400)\n      .ProducesProblem(500));\n  }\n\n  public override async Task<Results<Created<CreateContributorResponse>, ValidationProblem, ProblemHttpResult>>\n    ExecuteAsync(CreateContributorRequest request, CancellationToken cancellationToken)\n  {\n    var result = await _mediator.Send(new CreateContributorCommand(ContributorName.From(request.Name!)));\n\n    return result.ToCreatedResult(\n      id => $\"/Contributors/{id}\", \n      id => new CreateContributorResponse(id, request.Name!));\n  }\n}\n\npublic class CreateContributorRequest\n{\n  public const string Route = \"/Contributors\";\n\n  [Required]\n  public string Name { get; set; } = String.Empty;\n}\n\npublic class CreateContributorValidator : Validator<CreateContributorRequest>\n{\n  public CreateContributorValidator()\n  {\n    RuleFor(x => x.Name)\n      .NotEmpty()\n      .WithMessage(\"Name is required.\")\n      .MinimumLength(2)\n      .MaximumLength(ContributorName.MaxLength);\n  }\n}\n\npublic class CreateContributorResponse(int id, string name)\n{\n  public int Id { get; set; } = id;\n  public string Name { get; set; } = name;\n}"
  },
  {
    "path": "sample/src/NimblePros.SampleToDo.Web/Contributors/Delete.DeleteContributorRequest.cs",
    "content": "﻿namespace NimblePros.SampleToDo.Web.Contributors;\n\npublic record DeleteContributorRequest\n{\n  public const string Route = \"/Contributors/{ContributorId:int}\";\n  public static string BuildRoute(int contributorId) => Route.Replace(\"{ContributorId:int}\", contributorId.ToString());\n\n  public int ContributorId { get; set; }\n}\n"
  },
  {
    "path": "sample/src/NimblePros.SampleToDo.Web/Contributors/Delete.DeleteContributorValidator.cs",
    "content": "﻿using FastEndpoints;\nusing FluentValidation;\n\nnamespace NimblePros.SampleToDo.Web.Contributors;\n\n/// <summary>\n/// See: https://fast-endpoints.com/docs/validation\n/// </summary>\npublic class DeleteContributorValidator : Validator<DeleteContributorRequest>\n{\n  public DeleteContributorValidator()\n  {\n    RuleFor(x => x.ContributorId)\n      .GreaterThan(0);\n  }\n}\n"
  },
  {
    "path": "sample/src/NimblePros.SampleToDo.Web/Contributors/Delete.cs",
    "content": "﻿using NimblePros.SampleToDo.Core.ContributorAggregate;\nusing NimblePros.SampleToDo.UseCases.Contributors.Commands.Delete;\nusing NimblePros.SampleToDo.Web.Extensions;\n\nnamespace NimblePros.SampleToDo.Web.Contributors;\n\npublic class Delete\n  : Endpoint<DeleteContributorRequest,\n             Results<NoContent,\n                     NotFound,\n                     ProblemHttpResult>>\n{\n  private readonly IMediator _mediator;\n  public Delete(IMediator mediator) => _mediator = mediator;\n\n  public override void Configure()\n  {\n    Delete(DeleteContributorRequest.Route);\n    AllowAnonymous();\n    Summary(s =>\n    {\n      s.Summary = \"Delete a contributor\";\n      s.Description = \"Deletes an existing contributor by ID. This action cannot be undone.\";\n      s.ExampleRequest = new DeleteContributorRequest { ContributorId = 1 };\n      \n      // Document possible responses\n      s.Responses[204] = \"Contributor deleted successfully\";\n      s.Responses[404] = \"Contributor not found\";\n      s.Responses[400] = \"Invalid request or deletion failed\";\n    });\n    \n    // Add tags for API grouping\n    Tags(\"Contributors\");\n    \n    // Add additional metadata\n    Description(builder => builder\n      .Accepts<DeleteContributorRequest>()\n      .Produces(204)\n      .ProducesProblem(404)\n      .ProducesProblem(400));\n  }\n\n  public override async Task<Results<NoContent, NotFound, ProblemHttpResult>>\n    ExecuteAsync(DeleteContributorRequest req, CancellationToken ct)\n  {\n    var cmd = new DeleteContributorCommand(ContributorId.From(req.ContributorId));\n    var result = await _mediator.Send(cmd, ct);\n\n    return result.ToDeleteResult();\n  }\n}\n"
  },
  {
    "path": "sample/src/NimblePros.SampleToDo.Web/Contributors/GetById.GetContributorByIdMapper.cs",
    "content": "﻿using NimblePros.SampleToDo.UseCases.Contributors;\n\nnamespace NimblePros.SampleToDo.Web.Contributors;\n\npublic sealed class GetContributorByIdMapper\n  : Mapper<GetContributorByIdRequest, ContributorRecord, ContributorDto>\n{\n  public override ContributorRecord FromEntity(ContributorDto e)\n    => new(e.Id.Value, e.Name.Value);\n}\n"
  },
  {
    "path": "sample/src/NimblePros.SampleToDo.Web/Contributors/GetById.GetContributorByIdRequest.cs",
    "content": "﻿namespace NimblePros.SampleToDo.Web.Contributors;\n\npublic class GetContributorByIdRequest\n{\n  public const string Route = \"/Contributors/{ContributorId:int}\";\n  public static string BuildRoute(int contributorId) => Route.Replace(\"{ContributorId:int}\", contributorId.ToString());\n\n  public int ContributorId { get; set; }\n}\n"
  },
  {
    "path": "sample/src/NimblePros.SampleToDo.Web/Contributors/GetById.GetContributorValidator.cs",
    "content": "﻿using FastEndpoints;\nusing FluentValidation;\n\nnamespace NimblePros.SampleToDo.Web.Contributors;\n\n/// <summary>\n/// See: https://fast-endpoints.com/docs/validation\n/// </summary>\npublic class GetContributorValidator : Validator<GetContributorByIdRequest>\n{\n  public GetContributorValidator()\n  {\n    RuleFor(x => x.ContributorId)\n      .GreaterThan(0);\n  }\n}\n"
  },
  {
    "path": "sample/src/NimblePros.SampleToDo.Web/Contributors/GetById.cs",
    "content": "﻿using NimblePros.SampleToDo.Core.ContributorAggregate;\nusing NimblePros.SampleToDo.UseCases.Contributors.Queries.Get;\nusing NimblePros.SampleToDo.Web.Extensions;\n\nnamespace NimblePros.SampleToDo.Web.Contributors;\n\npublic class GetById(IMediator mediator)\n  : Endpoint<GetContributorByIdRequest,\n             Results<Ok<ContributorRecord>,\n                     NotFound,\n                     ProblemHttpResult>,\n             GetContributorByIdMapper>\n{\n  public override void Configure()\n  {\n    Get(GetContributorByIdRequest.Route);\n    AllowAnonymous();\n\n    // Optional: document statuses for Swagger\n    Summary(s =>\n    {\n      s.Summary = \"Get a contributor by ID\";\n      s.Description = \"Retrieves a specific contributor by their unique identifier. Returns detailed contributor information including ID and name.\";\n      s.ExampleRequest = new GetContributorByIdRequest { ContributorId = 1 };\n      s.ResponseExamples[200] = new ContributorRecord(1, \"John Doe\");\n      \n      // Document possible responses\n      s.Responses[200] = \"Contributor found and returned successfully\";\n      s.Responses[404] = \"Contributor with specified ID not found\";\n    });\n    \n    // Add tags for API grouping\n    Tags(\"Contributors\");\n    \n    // Add additional metadata\n    Description(builder => builder\n      .Accepts<GetContributorByIdRequest>()\n      .Produces<ContributorRecord>(200, \"application/json\")\n      .ProducesProblem(404));\n  }\n\n  public override async Task<Results<Ok<ContributorRecord>, NotFound, ProblemHttpResult>>\n    ExecuteAsync(GetContributorByIdRequest request, CancellationToken ct)\n  {\n    var result = await mediator.Send(new GetContributorQuery(ContributorId.From(request.ContributorId)), ct);\n\n    return result.ToGetByIdResult(Map.FromEntity);\n  }\n}\n"
  },
  {
    "path": "sample/src/NimblePros.SampleToDo.Web/Contributors/List.ContributorListResponse.cs",
    "content": "﻿\nnamespace NimblePros.SampleToDo.Web.Contributors;\n\npublic record ContributorListResponse : UseCases.PagedResult<ContributorRecord>\n{\n  public ContributorListResponse(IReadOnlyList<ContributorRecord> Items, int Page, int PerPage, int TotalCount, int TotalPages)\n    : base(Items, Page, PerPage, TotalCount, TotalPages)\n  {\n  }\n}\n"
  },
  {
    "path": "sample/src/NimblePros.SampleToDo.Web/Contributors/List.cs",
    "content": "﻿using FluentValidation;\nusing NimblePros.SampleToDo.UseCases.Contributors;\nusing NimblePros.SampleToDo.UseCases.Contributors.Queries.List;\n\nnamespace NimblePros.SampleToDo.Web.Contributors;\n\npublic class List(IMediator mediator) : Endpoint<ListContributorsRequest, ContributorListResponse, ListContributorsMapper>\n{\n  private readonly IMediator _mediator = mediator;\n\n  public override void Configure()\n  {\n    Get(\"/Contributors\");\n    AllowAnonymous();\n\n    Summary(s =>\n    {\n      s.Summary = \"List contributors with pagination\";\n      s.Description = \"Retrieves a paginated list of all contributors. Supports GitHub-style pagination with 1-based page indexing and configurable page size.\";\n      s.ExampleRequest = new ListContributorsRequest { Page = 1, PerPage = 10 };\n      s.ResponseExamples[200] = new ContributorListResponse(\n        new List<ContributorRecord> \n        { \n          new(1, \"John Doe\"), \n          new(2, \"Jane Smith\") \n        },\n        1, 10, 2, 1);\n      \n      // Document pagination parameters\n      s.Params[\"page\"] = \"1-based page index (default 1)\";\n      s.Params[\"per_page\"] = $\"Page size 1–{UseCases.Constants.MAX_PAGE_SIZE} (default {UseCases.Constants.DEFAULT_PAGE_SIZE})\";\n      \n      // Document possible responses\n      s.Responses[200] = \"Paginated list of contributors returned successfully\";\n      s.Responses[400] = \"Invalid pagination parameters\";\n    });\n    \n    // Add tags for API grouping\n    Tags(\"Contributors\");\n    \n    // Add additional metadata\n    Description(builder => builder\n      .Accepts<ListContributorsRequest>()\n      .Produces<ContributorListResponse>(200, \"application/json\")\n      .ProducesProblem(400));\n  }\n\n  public override async Task HandleAsync(ListContributorsRequest request, CancellationToken cancellationToken)\n  {\n    var result = await _mediator.Send(new ListContributorsQuery(request.Page, request.PerPage));\n    if (!result.IsSuccess)\n    {\n      await Send.ErrorsAsync(statusCode: 400, cancellationToken);\n      return;\n    }\n\n    var pagedResult = result.Value;\n    AddLinkHeader(pagedResult.Page, pagedResult.PerPage, pagedResult.TotalPages);\n\n    var response = Map.FromEntity(pagedResult);\n    await Send.OkAsync(response, cancellationToken);\n  }\n\n  private void AddLinkHeader(int page, int perPage, int totalPages)\n  {\n    var baseUrl = $\"{HttpContext.Request.Scheme}://{HttpContext.Request.Host}{HttpContext.Request.Path}\";\n    string Link(string rel, int p) => $\"<{baseUrl}?page={p}&per_page={perPage}>; rel=\\\"{rel}\\\"\";\n\n    var parts = new List<string>();\n    if (page > 1)\n    {\n      parts.Add(Link(\"first\", 1));\n      parts.Add(Link(\"prev\", page - 1));\n    }\n    if (page < totalPages)\n    {\n      parts.Add(Link(\"next\", page + 1));\n      parts.Add(Link(\"last\", totalPages));\n    }\n\n    if (parts.Count > 0)\n      HttpContext.Response.Headers[\"Link\"] = string.Join(\", \", parts);\n  }\n}\n\npublic sealed class ListContributorsRequest\n{\n  // Bind to ?page=\n  [BindFrom(\"page\")]\n  public int Page { get; init; } = 1;\n\n  // Bind to ?per_page=\n  [BindFrom(\"per_page\")]\n  public int PerPage { get; init; } = UseCases.Constants.DEFAULT_PAGE_SIZE;\n}\n\npublic sealed class ListContributorsValidator : Validator<ListContributorsRequest>\n{\n  public ListContributorsValidator()\n  {\n    RuleFor(x => x.Page)\n      .GreaterThanOrEqualTo(1)\n      .WithMessage(\"page must be >= 1\");\n\n    RuleFor(x => x.PerPage)\n      .InclusiveBetween(1, UseCases.Constants.MAX_PAGE_SIZE)\n      .WithMessage($\"per_page must be between 1 and {UseCases.Constants.MAX_PAGE_SIZE}\");\n  }\n}\n\npublic sealed class ListContributorsMapper\n  : Mapper<ListContributorsRequest, ContributorListResponse, UseCases.PagedResult<ContributorDto>>\n{\n  public override ContributorListResponse FromEntity(UseCases.PagedResult<ContributorDto> e)\n  {\n    var items = e.Items\n      .Select(c => new ContributorRecord(c.Id.Value, c.Name.Value))\n      .ToList();\n\n    return new ContributorListResponse(items, e.Page, e.PerPage, e.TotalCount, e.TotalPages);\n  }\n}\n\n\n\n\n"
  },
  {
    "path": "sample/src/NimblePros.SampleToDo.Web/Contributors/Update.UpdateContributorRequest.cs",
    "content": "﻿using System.ComponentModel.DataAnnotations;\n\nnamespace NimblePros.SampleToDo.Web.Contributors;\n\npublic class UpdateContributorRequest\n{\n  public const string Route = \"/Contributors/{ContributorId:int}\";\n  public static string BuildRoute(int contributorId) => Route.Replace(\"{ContributorId:int}\", contributorId.ToString());\n\n  public int ContributorId { get; set; }\n\n  [Required]\n  public int Id { get; set; }\n  [Required]\n  public string? Name { get; set; }\n}\n"
  },
  {
    "path": "sample/src/NimblePros.SampleToDo.Web/Contributors/Update.UpdateContributorResponse.cs",
    "content": "﻿namespace NimblePros.SampleToDo.Web.Contributors;\n\npublic class UpdateContributorResponse\n{\n  public UpdateContributorResponse(ContributorRecord contributor)\n  {\n    Contributor = contributor;\n  }\n  public ContributorRecord Contributor { get; set; }\n}\n"
  },
  {
    "path": "sample/src/NimblePros.SampleToDo.Web/Contributors/Update.UpdateContributorValidator.cs",
    "content": "﻿using FluentValidation;\nusing NimblePros.SampleToDo.Infrastructure.Data.Config;\n\nnamespace NimblePros.SampleToDo.Web.Contributors;\n\n/// <summary>\n/// See: https://fast-endpoints.com/docs/validation\n/// </summary>\npublic class UpdateContributorValidator : Validator<UpdateContributorRequest>\n{\n  public UpdateContributorValidator()\n  {\n    RuleFor(x => x.Name)\n      .NotEmpty()\n      .WithMessage(\"Name is required.\")\n      .MinimumLength(2)\n      .MaximumLength(DataSchemaConstants.DEFAULT_NAME_LENGTH);\n    RuleFor(x => x.ContributorId)\n      .Must((args, contributorId) => args.Id == contributorId)\n      .WithMessage(\"Route and body Ids must match; cannot update Id of an existing resource.\");\n  }\n}\n"
  },
  {
    "path": "sample/src/NimblePros.SampleToDo.Web/Contributors/Update.cs",
    "content": "﻿using NimblePros.SampleToDo.Core.ContributorAggregate;\nusing NimblePros.SampleToDo.UseCases.Contributors;\nusing NimblePros.SampleToDo.UseCases.Contributors.Commands.Update;\nusing NimblePros.SampleToDo.Web.Extensions;\n\nnamespace NimblePros.SampleToDo.Web.Contributors;\n\npublic class Update(IMediator mediator)\n  : Endpoint<\n        UpdateContributorRequest,\n        Results<Ok<UpdateContributorResponse>, NotFound, ProblemHttpResult>,\n        UpdateContributorMapper>\n{\n  private readonly IMediator _mediator = mediator;\n\n  public override void Configure()\n  {\n    Put(UpdateContributorRequest.Route);\n    AllowAnonymous();\n\n    // Optional but nice: enumerate for Swagger\n    Summary(s =>\n    {\n      s.Summary = \"Update a contributor\";\n      s.Description = \"Updates an existing contributor's information. The contributor name must be between 2 and 100 characters long.\";\n      s.ExampleRequest = new UpdateContributorRequest { Id = 1, Name = \"Updated Name\" };\n      s.ResponseExamples[200] = new UpdateContributorResponse(new ContributorRecord(1, \"Updated Name\"));\n      \n      // Document possible responses\n      s.Responses[200] = \"Contributor updated successfully\";\n      s.Responses[404] = \"Contributor with specified ID not found\";\n      s.Responses[400] = \"Invalid input data or business rule violation\";\n    });\n    \n    // Add tags for API grouping\n    Tags(\"Contributors\");\n    \n    // Add additional metadata\n    Description(builder => builder\n      .Accepts<UpdateContributorRequest>(\"application/json\")\n      .Produces<UpdateContributorResponse>(200, \"application/json\")\n      .ProducesProblem(404)\n      .ProducesProblem(400));\n  }\n\n  public override async Task<Results<Ok<UpdateContributorResponse>, NotFound, ProblemHttpResult>>\n    ExecuteAsync(UpdateContributorRequest request, CancellationToken ct)\n  {\n    var cmd = new UpdateContributorCommand(\n      ContributorId.From(request.Id),\n      ContributorName.From(request.Name!));\n\n    var result = await _mediator.Send(cmd, ct);\n\n    return result.ToUpdateResult(Map.FromEntity);\n  }\n}\n\npublic sealed class UpdateContributorMapper\n  : Mapper<UpdateContributorRequest, UpdateContributorResponse, ContributorDto>\n{\n  public override UpdateContributorResponse FromEntity(ContributorDto e)\n    => new(new ContributorRecord(e.Id.Value, e.Name.Value));\n}\n"
  },
  {
    "path": "sample/src/NimblePros.SampleToDo.Web/Extensions/ResultExtensions.cs",
    "content": "using Ardalis.Result;\n\nnamespace NimblePros.SampleToDo.Web.Extensions;\n\npublic static class ResultExtensions\n{\n  /// <summary>\n  /// Maps Result to TypedResults for endpoints that return Created, ValidationProblem, or ProblemHttpResult\n  /// </summary>\n  public static Results<Created<TResponse>, ValidationProblem, ProblemHttpResult> ToCreatedResult<TValue, TResponse>(\n    this Result<TValue> result, \n    Func<TValue, string> locationBuilder,\n    Func<TValue, TResponse> mapResponse)\n  {\n    return result.Status switch\n    {\n      ResultStatus.Ok => TypedResults.Created(locationBuilder(result.Value), mapResponse(result.Value)),\n      ResultStatus.Invalid => TypedResults.ValidationProblem(\n        result.ValidationErrors\n          .GroupBy(e => e.Identifier ?? string.Empty)\n          .ToDictionary(\n            g => g.Key,\n            g => g.Select(e => e.ErrorMessage).ToArray()\n          )\n      ),\n      _ => TypedResults.Problem(\n        title: \"Create failed\",\n        detail: string.Join(\"; \", result.Errors),\n        statusCode: StatusCodes.Status400BadRequest)\n    };\n  }\n\n  /// <summary>\n  /// Maps Result to TypedResults for GetById endpoints that return Ok, NotFound, or ProblemHttpResult\n  /// </summary>\n  public static Results<Ok<TResponse>, NotFound, ProblemHttpResult> ToGetByIdResult<TValue, TResponse>(\n    this Result<TValue> result,\n    Func<TValue, TResponse> mapResponse)\n  {\n    return ToOkOrNotFoundResult(result, mapResponse, \"Get\");\n  }\n\n  /// <summary>\n  /// Maps Result to TypedResults for Update endpoints that return Ok, NotFound, or ProblemHttpResult\n  /// </summary>\n  public static Results<Ok<TResponse>, NotFound, ProblemHttpResult> ToUpdateResult<TValue, TResponse>(\n    this Result<TValue> result,\n    Func<TValue, TResponse> mapResponse)\n  {\n    return ToOkOrNotFoundResult(result, mapResponse, \"Update\");\n  }\n\n  /// <summary>\n  /// Maps Result to TypedResults for Delete endpoints that return NoContent, NotFound, or ProblemHttpResult\n  /// </summary>\n  public static Results<NoContent, NotFound, ProblemHttpResult> ToDeleteResult(\n    this Result result)\n  {\n    return result.Status switch\n    {\n      ResultStatus.Ok => TypedResults.NoContent(),\n      ResultStatus.NotFound => TypedResults.NotFound(),\n      _ => TypedResults.Problem(\n        title: \"Delete failed\",\n        detail: string.Join(\"; \", result.Errors),\n        statusCode: StatusCodes.Status400BadRequest)\n    };\n  }\n\n  /// <summary>\n  /// Private helper method for Ok/NotFound result patterns\n  /// </summary>\n  private static Results<Ok<TResponse>, NotFound, ProblemHttpResult> ToOkOrNotFoundResult<TValue, TResponse>(\n    Result<TValue> result,\n    Func<TValue, TResponse> mapResponse,\n    string operationName)\n  {\n    return result.Status switch\n    {\n      ResultStatus.Ok => TypedResults.Ok(mapResponse(result.Value)),\n      ResultStatus.NotFound => TypedResults.NotFound(),\n      _ => TypedResults.Problem(\n        title: $\"{operationName} failed\",\n        detail: string.Join(\"; \", result.Errors),\n        statusCode: StatusCodes.Status400BadRequest)\n    };\n  }\n\n  /// <summary>\n  /// Maps Result to TypedResults for endpoints that return Ok only (like List endpoints)\n  /// </summary>\n  public static Ok<TResponse> ToOkOnlyResult<TValue, TResponse>(\n    this Result<TValue> result,\n    Func<TValue, TResponse> mapResponse)\n  {\n    return TypedResults.Ok(mapResponse(result.Value));\n  }\n}"
  },
  {
    "path": "sample/src/NimblePros.SampleToDo.Web/GlobalUsings.cs",
    "content": "﻿global using Ardalis.ListStartupServices;\nglobal using Ardalis.Result;\nglobal using FastEndpoints;\nglobal using FastEndpoints.Swagger;\nglobal using Mediator;\nglobal using Microsoft.AspNetCore.Http; // Ok, NotFound, NoContent, ProblemDetails\nglobal using Microsoft.AspNetCore.Http.HttpResults;\nglobal using Microsoft.EntityFrameworkCore;\nglobal using NimblePros.SharedKernel;\nglobal using Serilog;\nglobal using Serilog.Extensions.Logging;\n"
  },
  {
    "path": "sample/src/NimblePros.SampleToDo.Web/LoggingBehavior.cs",
    "content": "﻿using System.Diagnostics;\nusing System.Reflection;\nusing Ardalis.GuardClauses;\n\nnamespace NimblePros.SampleToDo.Web;\n\npublic class LoggingBehavior<TRequest, TResponse> : IPipelineBehavior<TRequest, TResponse>\n    where TRequest : notnull, IMessage\n{\n  private readonly ILogger<LoggingBehavior<TRequest, TResponse>> _logger;\n\n  public LoggingBehavior(ILogger<LoggingBehavior<TRequest, TResponse>> logger)\n  {\n    _logger = logger;\n  }\n\n  public async ValueTask<TResponse> Handle(\n      TRequest request,\n      MessageHandlerDelegate<TRequest, TResponse> next,\n      CancellationToken cancellationToken)\n  {\n    Guard.Against.Null(request);\n    if (_logger.IsEnabled(LogLevel.Information))\n    {\n      _logger.LogInformation(\"Handling {RequestName}\", typeof(TRequest).Name);\n\n      Type myType = request.GetType();\n      IList<PropertyInfo> props = new List<PropertyInfo>(myType.GetProperties());\n      foreach (PropertyInfo prop in props)\n      {\n        object? propValue = prop?.GetValue(request, null);\n        _logger.LogInformation(\"Property {Property} : {@Value}\", prop?.Name, propValue);\n      }\n    }\n\n    var sw = Stopwatch.StartNew();\n\n    var response = await next(request, cancellationToken);\n\n    _logger.LogInformation(\"Handled {RequestName} with {Response} in {ms} ms\", typeof(TRequest).Name, response, sw.ElapsedMilliseconds);\n    sw.Stop();\n    return response;\n  }\n}\n"
  },
  {
    "path": "sample/src/NimblePros.SampleToDo.Web/NimblePros.SampleToDo.Web.csproj",
    "content": "﻿<Project Sdk=\"Microsoft.NET.Sdk.Web\">\n  <Sdk Name=\"Microsoft.Build.CentralPackageVersions\" Version=\"2.1.3\" />\n\n  <PropertyGroup>\n    <OutputType>Exe</OutputType>\n    <WebProjectMode>true</WebProjectMode>\n    <GenerateDocumentationFile>True</GenerateDocumentationFile>\n    <!--<DocumentationFile>bin\\swagger-docs.xml</DocumentationFile>-->\n  </PropertyGroup>\n  <ItemGroup>\n    <PackageReference Include=\"Ardalis.ListStartupServices\" />\n    <PackageReference Include=\"Ardalis.Result\" />\n    <PackageReference Include=\"Ardalis.Result.AspNetCore\" />\n    <PackageReference Include=\"AspNetCore.Localizer.Json\" />\n    <PackageReference Include=\"FastEndpoints\" />\n    <PackageReference Include=\"FastEndpoints.ApiExplorer\" />\n    <PackageReference Include=\"FastEndpoints.Swagger\" />\n    <PackageReference Include=\"FastEndpoints.Swagger.Swashbuckle\" />\n    <PackageReference Include=\"FluentValidation\" />\n    <PackageReference Include=\"FluentValidation.DependencyInjectionExtensions\" />\n    <PackageReference Include=\"Mediator.SourceGenerator\" PrivateAssets=\"all\" />\n    <PackageReference Include=\"Microsoft.AspNetCore.Mvc.NewtonsoftJson\" />\n    <PackageReference Include=\"Microsoft.EntityFrameworkCore.Design\" />\n    <PackageReference Include=\"Microsoft.EntityFrameworkCore.Tools\" PrivateAssets=\"all\" />\n    <PackageReference Include=\"NimblePros.Metronome\" />\n    <PackageReference Include=\"NimblePros.SharedKernel\" />\n    <PackageReference Include=\"Serilog.Sinks.ApplicationInsights\" />\n    <PackageReference Include=\"Serilog.AspNetCore\" />\n    <PackageReference Include=\"Serilog.Sinks.OpenTelemetry\" />\n    <!--<PackageReference Include=\"Swashbuckle.AspNetCore\" />\n    <PackageReference Include=\"Swashbuckle.AspNetCore.Annotations\" />-->\n  </ItemGroup>\n\n  <ItemGroup>\n    <ProjectReference Include=\"..\\NimblePros.SampleToDo.Infrastructure\\NimblePros.SampleToDo.Infrastructure.csproj\" />\n    <ProjectReference Include=\"..\\NimblePros.SampleToDo.ServiceDefaults\\NimblePros.SampleToDo.ServiceDefaults.csproj\" />\n    <ProjectReference Include=\"..\\NimblePros.SampleToDo.UseCases\\NimblePros.SampleToDo.UseCases.csproj\" />\n  </ItemGroup>\n\n</Project>\n"
  },
  {
    "path": "sample/src/NimblePros.SampleToDo.Web/Program.cs",
    "content": "﻿using System.Text;\nusing AspNetCore.Localizer.Json.Extensions;\nusing FluentValidation;\nusing Microsoft.Extensions.Localization;\nusing NimblePros.Metronome;\nusing NimblePros.SampleToDo.Core.ProjectAggregate;\nusing NimblePros.SampleToDo.Infrastructure.Data;\nusing NimblePros.SampleToDo.Web.Configurations;\nusing NimblePros.SampleToDo.Web.Projects;\n\npublic partial class Program\n{\n  private static async Task Main(string[] args)\n  {\n    var builder = WebApplication.CreateBuilder(args);\n    builder.WebHost.ConfigureKestrel(o =>\n    {\n      o.AddServerHeader = false; // <- removes \"Server: Kestrel\"\n    });\n    builder.AddServiceDefaults();\n\n\n    var logger = Log.Logger = new LoggerConfiguration()\n      .Enrich.FromLogContext()\n      .WriteTo.Console()\n      .CreateLogger();\n\n    logger.Information(\"Starting web host\");\n\n    builder.AddLoggerConfigs();\n\n    var appLogger = new SerilogLoggerFactory(logger)\n        .CreateLogger<Program>();\n\n    builder.Services.AddOptionConfigs(builder.Configuration, appLogger, builder);\n\n    builder.Services.AddServiceConfigs(appLogger, builder);\n\n    builder.Services.AddFastEndpoints()\n                    .SwaggerDocument(o =>\n                    {\n                      o.ShortSchemaNames = true;\n                    });\n    builder.Services.AddValidatorsFromAssemblyContaining<UpdateProjectRequestValidator>();\n\n    if (!builder.Environment.EnvironmentName.Equals(\"Testing\"))\n    {\n      var connectionString = builder.Configuration.GetConnectionString(\"SqliteConnection\");\n      builder.Services.AddDbContext<AppDbContext>(options =>\n                options.UseSqlite(connectionString));\n    }\n\n    builder.Services.AddMemoryCache();\n\n    // add list services for diagnostic purposes - see https://github.com/ardalis/AspNetCoreStartupServices\n    builder.Services.Configure((Ardalis.ListStartupServices.ServiceConfig config) =>\n    {\n      config.Services = new List<ServiceDescriptor>(builder.Services);\n\n      // optional - default path to view services is /listallservices - recommended to choose your own path\n      config.Path = \"/listservices\";\n    });\n\n    // track db and external service calls\n    builder.Services.AddMetronome();\n\n    // Add localization with the JSON path\n    builder.Services.AddLocalization(options => options.ResourcesPath = \"i18n\");\n\n    // ----- Add JSON-specific localization\n    builder.Services.AddJsonLocalization(options =>\n    {\n      options.ResourcesPath = \"i18n\";  // Path to the JSON files (e.g., i18n/en/Project.json)\n      options.CacheDuration = TimeSpan.FromHours(1);  // Optional: Cache for performance\n      options.FileEncoding = Encoding.UTF8; //Optional: Specify file encoding\n    });\n\n    // ----- Register the typed localizer for the Project aggregate -----\n    builder.Services.AddSingleton<IStringLocalizer>(sp =>\n    {\n      var factory = sp.GetRequiredService<IStringLocalizerFactory>();\n      // Creates a localizer for 'ProjectAggregate' – loads from i18n/{culture}/Project.json\n      return factory.Create(typeof(ProjectErrorMessages));\n    });\n\n    var app = builder.Build();\n\n    // ----- Set the static holder for Core access -----\n    var localizer = app.Services.GetRequiredService<IStringLocalizer>();\n    Localization.Current = new Localization.LocalizationContext(localizer);\n\n    // ----- Add request localization middleware (before app.Run()) -----\n    var supportedCultures = new[] { \"en\", \"fr\", \"fa\" };  // Add your cultures\n    var localizationOptions = new RequestLocalizationOptions()\n        .SetDefaultCulture(supportedCultures[0])\n        .AddSupportedCultures(supportedCultures)\n        .AddSupportedUICultures(supportedCultures);\n    app.UseRequestLocalization(localizationOptions);\n\n    // Verify validators are registered properly in development\n    if (app.Environment.IsDevelopment())\n    {\n      using var scope = app.Services.CreateScope();\n      var validatorsCount = scope.ServiceProvider.GetServices<IValidator<UpdateProjectRequest>>().Count();\n      appLogger.LogInformation(\"Validators found: {validatorsCount}\", validatorsCount);\n    }\n    \n    // see Configurations/MiddlewareConfig.cs  \n    await app.UseAppMiddleware();\n\n    app.Run();\n  }\n}\n\n// Make the implicit Program.cs class public, so integration tests can reference the correct assembly for host building\npublic partial class Program\n{\n}\n"
  },
  {
    "path": "sample/src/NimblePros.SampleToDo.Web/Projects/Create.CreateProjectRequest.cs",
    "content": "﻿using System.ComponentModel.DataAnnotations;\n\nnamespace NimblePros.SampleToDo.Web.Projects;\n\npublic class CreateProjectRequest\n{\n  public const string Route = \"/Projects\";\n\n  [Required]\n  public string Name { get; set; } = String.Empty;\n}\n"
  },
  {
    "path": "sample/src/NimblePros.SampleToDo.Web/Projects/Create.CreateProjectResponse.cs",
    "content": "﻿namespace NimblePros.SampleToDo.Web.Projects;\n\npublic record CreateProjectResponse(int Id, string Name);\n"
  },
  {
    "path": "sample/src/NimblePros.SampleToDo.Web/Projects/Create.CreateProjectValidator.cs",
    "content": "﻿using FastEndpoints;\nusing FluentValidation;\nusing NimblePros.SampleToDo.Core.ProjectAggregate;\n\nnamespace NimblePros.SampleToDo.Web.Projects;\n\npublic class CreateProjectValidator : Validator<CreateProjectRequest>\n{\n  public CreateProjectValidator()\n  {\n    RuleFor(x => x.Name)\n      .NotEmpty()\n      .WithMessage(\"Name is required.\")\n      .MinimumLength(2)\n      .MaximumLength(ProjectName.MaxLength);\n  }\n}\n"
  },
  {
    "path": "sample/src/NimblePros.SampleToDo.Web/Projects/Create.cs",
    "content": "﻿using NimblePros.SampleToDo.Core.ProjectAggregate;\nusing NimblePros.SampleToDo.UseCases.Projects.Create;\nusing NimblePros.SampleToDo.Web.Extensions;\n\nnamespace NimblePros.SampleToDo.Web.Projects;\n\npublic class Create(IMediator mediator) \n  : Endpoint<CreateProjectRequest, Results<Created<CreateProjectResponse>, ValidationProblem, ProblemHttpResult>>\n{\n  private readonly IMediator _mediator = mediator;\n\n  public override void Configure()\n  {\n    Post(CreateProjectRequest.Route);\n    AllowAnonymous();\n    Summary(s =>\n    {\n      s.Summary = \"Create a new project\";\n      s.Description = \"Creates a new project with the provided name. The project name must be between 2 and 100 characters long.\";\n      s.ExampleRequest = new CreateProjectRequest { Name = \"My New Project\" };\n      s.ResponseExamples[201] = new CreateProjectResponse(1, \"My New Project\");\n      \n      // Document possible responses\n      s.Responses[201] = \"Project created successfully\";\n      s.Responses[400] = \"Invalid input data - validation errors\";\n      s.Responses[500] = \"Internal server error\";\n    });\n    \n    // Add tags for API grouping\n    Tags(\"Projects\");\n    \n    // Add additional metadata\n    Description(builder => builder\n      .Accepts<CreateProjectRequest>(\"application/json\")\n      .Produces<CreateProjectResponse>(201, \"application/json\")\n      .ProducesProblem(400)\n      .ProducesProblem(500));\n  }\n\n  public override async Task<Results<Created<CreateProjectResponse>, ValidationProblem, ProblemHttpResult>>\n    ExecuteAsync(CreateProjectRequest request, CancellationToken cancellationToken)\n  {\n    var result = await _mediator.Send(new CreateProjectCommand(ProjectName.From(request.Name!)));\n\n    return result.ToCreatedResult(\n      id => $\"/Projects/{id}\", \n      id => new CreateProjectResponse(id.Value, request.Name!));\n  }\n}\n"
  },
  {
    "path": "sample/src/NimblePros.SampleToDo.Web/Projects/CreateToDoItem.CreateToDoItemRequest.cs",
    "content": "﻿using System.ComponentModel.DataAnnotations;\nusing Microsoft.AspNetCore.Mvc;\n\nnamespace NimblePros.SampleToDo.Web.Projects;\n\npublic class CreateToDoItemRequest\n{\n  public const string Route = \"/Projects/{ProjectId:int}/ToDoItems\";\n  public static string BuildRoute(int projectId) => Route.Replace(\"{ProjectId:int}\", projectId.ToString());\n\n  [Required]\n  [FromRoute]\n  public int ProjectId { get; set; } = 0;\n\n  [Required]\n  public string Title { get; set; } = string.Empty;\n  [Required]\n  public string Description { get; set; } = string.Empty;\n\n  public int? ContributorId { get; set; }\n}\n"
  },
  {
    "path": "sample/src/NimblePros.SampleToDo.Web/Projects/CreateToDoItem.CreateToDoItemValidator.cs",
    "content": "﻿using FluentValidation;\nusing NimblePros.SampleToDo.Infrastructure.Data.Config;\n\nnamespace NimblePros.SampleToDo.Web.Projects;\n\n/// <summary>\n/// See: https://fast-endpoints.com/docs/validation\n/// </summary>\npublic class CreateToDoItemValidator : Validator<CreateToDoItemRequest>\n{\n  public CreateToDoItemValidator()\n  {\n    RuleFor(x => x.ProjectId)\n      .GreaterThan(0);\n    RuleFor(x => x.Title)\n      .NotEmpty()\n      .MinimumLength(2)\n      .MaximumLength(DataSchemaConstants.DEFAULT_NAME_LENGTH);\n    RuleFor(x => x.Description)\n      .MaximumLength(200) // TODO: Move to constant\n      .NotEmpty();\n  }\n}\n"
  },
  {
    "path": "sample/src/NimblePros.SampleToDo.Web/Projects/CreateToDoItem.cs",
    "content": "﻿using NimblePros.SampleToDo.Core.ContributorAggregate;\nusing NimblePros.SampleToDo.Core.ProjectAggregate;\nusing NimblePros.SampleToDo.UseCases.Projects.AddToDoItem;\nusing NimblePros.SampleToDo.Web.Projects;\n\nnamespace NimblePros.SampleToDo.Web.ProjectEndpoints;\n\npublic class Create : Endpoint<CreateToDoItemRequest, Results<Created, NotFound, ProblemHttpResult>>\n{\n  private readonly IMediator _mediator;\n\n  public Create(IMediator mediator)\n  {\n    _mediator = mediator;\n  }\n\n  public override void Configure()\n  {\n    Post(CreateToDoItemRequest.Route);\n    AllowAnonymous();\n    Summary(s =>\n    {\n      s.Summary = \"Add a new todo item to a project\";\n      s.Description = \"Creates a new todo item within an existing project. The project must exist and the contributor (if specified) must be valid.\";\n      s.ExampleRequest = new CreateToDoItemRequest\n      {\n        ContributorId = 1,\n        ProjectId = 1,\n        Title = \"Implement user authentication\",\n        Description = \"Add JWT-based authentication to the API\"\n      };\n\n      // Document possible responses\n      s.Responses[201] = \"Todo item created successfully\";\n      s.Responses[404] = \"Project or contributor not found\";\n      s.Responses[400] = \"Invalid input data\";\n      s.Responses[500] = \"Internal server error\";\n    });\n\n    // Add tags for API grouping\n    Tags(\"Projects\");\n\n    // Add additional metadata\n    Description(builder => builder\n      .Accepts<CreateToDoItemRequest>(\"application/json\")\n      .Produces(201)\n      .ProducesProblem(404)\n      .ProducesProblem(400)\n      .ProducesProblem(500));\n  }\n\n  public override async Task<Results<Created, NotFound, ProblemHttpResult>>\n    ExecuteAsync(CreateToDoItemRequest request, CancellationToken cancellationToken)\n  {\n    ContributorId? contributorId = request.ContributorId.HasValue\n                                    ? ContributorId.From(request.ContributorId.Value)\n                                    : null;\n    var command = new AddToDoItemCommand(ProjectId.From(request.ProjectId), contributorId,\n      ToDoItemTitle.From(request.Title), ToDoItemDescription.From(request.Description));\n    var result = await _mediator.Send(command);\n\n    return result.Status switch\n    {\n      ResultStatus.Ok => TypedResults.Created($\"/Projects/{request.ProjectId}\"),\n      ResultStatus.NotFound => TypedResults.NotFound(),\n      _ => TypedResults.Problem(\n        title: \"Create todo item failed\",\n        detail: string.Join(\"; \", result.Errors),\n        statusCode: StatusCodes.Status400BadRequest)\n    };\n  }\n}\n"
  },
  {
    "path": "sample/src/NimblePros.SampleToDo.Web/Projects/Delete.DeleteProjectRequest.cs",
    "content": "﻿namespace NimblePros.SampleToDo.Web.Projects;\n\npublic class DeleteProjectRequest\n{\n  public const string Route = \"/Projects/{ProjectId:int}\";\n  public static string BuildRoute(int projectId) => Route.Replace(\"{ProjectId:int}\", projectId.ToString());\n\n  public int ProjectId { get; set; }\n}\n"
  },
  {
    "path": "sample/src/NimblePros.SampleToDo.Web/Projects/Delete.DeleteProjectValidator.cs",
    "content": "using FastEndpoints;\nusing FluentValidation;\n\nnamespace NimblePros.SampleToDo.Web.Projects;\n\n/// <summary>\n/// See: https://fast-endpoints.com/docs/validation\n/// </summary>\npublic class DeleteProjectValidator : Validator<DeleteProjectRequest>\n{\n  public DeleteProjectValidator()\n  {\n    RuleFor(x => x.ProjectId)\n      .GreaterThan(0);\n  }\n}"
  },
  {
    "path": "sample/src/NimblePros.SampleToDo.Web/Projects/Delete.cs",
    "content": "﻿using NimblePros.SampleToDo.Core.ProjectAggregate;\nusing NimblePros.SampleToDo.UseCases.Projects.Delete;\nusing NimblePros.SampleToDo.Web.Extensions;\n\nnamespace NimblePros.SampleToDo.Web.Projects;\n\npublic class Delete\n  : Endpoint<DeleteProjectRequest,\n             Results<NoContent,\n                     NotFound,\n                     ProblemHttpResult>>\n{\n  private readonly IMediator _mediator;\n  public Delete(IMediator mediator) => _mediator = mediator;\n\n  public override void Configure()\n  {\n    Delete(DeleteProjectRequest.Route);\n    AllowAnonymous();\n    Summary(s =>\n    {\n      s.Summary = \"Delete a project\";\n      s.Description = \"Deletes an existing project by ID. This will also delete all associated todo items. This action cannot be undone.\";\n      s.ExampleRequest = new DeleteProjectRequest { ProjectId = 1 };\n      \n      // Document possible responses\n      s.Responses[204] = \"Project deleted successfully\";\n      s.Responses[404] = \"Project not found\";\n      s.Responses[400] = \"Invalid request or deletion failed\";\n    });\n    \n    // Add tags for API grouping\n    Tags(\"Projects\");\n    \n    // Add additional metadata\n    Description(builder => builder\n      .Accepts<DeleteProjectRequest>()\n      .Produces(204)\n      .ProducesProblem(404)\n      .ProducesProblem(400));\n  }\n\n  public override async Task<Results<NoContent, NotFound, ProblemHttpResult>>\n    ExecuteAsync(DeleteProjectRequest req, CancellationToken ct)\n  {\n    var cmd = new DeleteProjectCommand(ProjectId.From(req.ProjectId));\n    var result = await _mediator.Send(cmd, ct);\n\n    return result.ToDeleteResult();\n  }\n}\n"
  },
  {
    "path": "sample/src/NimblePros.SampleToDo.Web/Projects/GetById.GetProjectByIdRequest.cs",
    "content": "﻿\nnamespace NimblePros.SampleToDo.Web.Endpoints.Projects;\n\npublic class GetProjectByIdRequest\n{\n  public const string Route = \"/Projects/{ProjectId:int}\";\n  public static string BuildRoute(int projectId) => Route.Replace(\"{ProjectId:int}\", projectId.ToString());\n\n  public int ProjectId { get; set; }\n}\n"
  },
  {
    "path": "sample/src/NimblePros.SampleToDo.Web/Projects/GetById.GetProjectByIdResponse.cs",
    "content": "﻿namespace NimblePros.SampleToDo.Web.Projects;\n\npublic record GetProjectByIdResponse(int Id, string Name, List<ToDoItemRecord> Items);\n"
  },
  {
    "path": "sample/src/NimblePros.SampleToDo.Web/Projects/GetById.GetProjectByIdValidator.cs",
    "content": "using FastEndpoints;\nusing FluentValidation;\nusing NimblePros.SampleToDo.Web.Endpoints.Projects;\n\nnamespace NimblePros.SampleToDo.Web.Projects;\n\n/// <summary>\n/// See: https://fast-endpoints.com/docs/validation\n/// </summary>\npublic class GetProjectByIdValidator : Validator<GetProjectByIdRequest>\n{\n  public GetProjectByIdValidator()\n  {\n    RuleFor(x => x.ProjectId)\n      .GreaterThan(0);\n  }\n}"
  },
  {
    "path": "sample/src/NimblePros.SampleToDo.Web/Projects/GetById.cs",
    "content": "﻿using NimblePros.SampleToDo.Core.ProjectAggregate;\nusing NimblePros.SampleToDo.UseCases.Projects.GetWithAllItems;\nusing NimblePros.SampleToDo.Web.Endpoints.Projects;\nusing NimblePros.SampleToDo.Web.Extensions;\n\nnamespace NimblePros.SampleToDo.Web.Projects;\n\npublic class GetById(IMediator mediator)\n  : Endpoint<GetProjectByIdRequest,\n             Results<Ok<GetProjectByIdResponse>,\n                     NotFound,\n                     ProblemHttpResult>>\n{\n  public override void Configure()\n  {\n    Get(GetProjectByIdRequest.Route);\n    AllowAnonymous();\n    \n    Summary(s =>\n    {\n      s.Summary = \"Get a project by ID\";\n      s.Description = \"Retrieves a specific project by its unique identifier. Returns detailed project information including all associated todo items.\";\n      s.ExampleRequest = new GetProjectByIdRequest { ProjectId = 1 };\n      s.ResponseExamples[200] = new GetProjectByIdResponse(\n        1, \n        \"Sample Project\", \n        new List<ToDoItemRecord> \n        { \n          new(1, \"Sample Task\", \"Sample task description\", false, 1) \n        });\n      \n      // Document possible responses\n      s.Responses[200] = \"Project found and returned successfully\";\n      s.Responses[404] = \"Project with specified ID not found\";\n      s.Responses[400] = \"Invalid project ID provided\";\n    });\n    \n    // Add tags for API grouping\n    Tags(\"Projects\");\n    \n    // Add additional metadata\n    Description(builder => builder\n      .Accepts<GetProjectByIdRequest>()\n      .Produces<GetProjectByIdResponse>(200, \"application/json\")\n      .ProducesProblem(404)\n      .ProducesProblem(400));\n  }\n\n  public override async Task<Results<Ok<GetProjectByIdResponse>, NotFound, ProblemHttpResult>>\n    ExecuteAsync(GetProjectByIdRequest request, CancellationToken ct)\n  {\n    var command = new GetProjectWithAllItemsQuery(ProjectId.From(request.ProjectId));\n    var result = await mediator.Send(command, ct);\n\n    return result.ToGetByIdResult(project => new GetProjectByIdResponse(\n      project.Id.Value,\n      project.Name.Value,\n      project.Items\n        .Select(item => new ToDoItemRecord(\n          item.Id.Value,\n          item.Title,\n          item.Description,\n          item.IsComplete,\n          item.ContributorId?.Value))\n        .ToList()));\n  }\n}\n"
  },
  {
    "path": "sample/src/NimblePros.SampleToDo.Web/Projects/List.ProjectListResponse.cs",
    "content": "﻿namespace NimblePros.SampleToDo.Web.Projects;\n\npublic record ProjectListResponse : UseCases.PagedResult<ProjectRecord>\n{\n  public ProjectListResponse(IReadOnlyList<ProjectRecord> Items, int Page, int PerPage, int TotalCount, int TotalPages)\n    : base(Items, Page, PerPage, TotalCount, TotalPages)\n  {\n  }\n}\n"
  },
  {
    "path": "sample/src/NimblePros.SampleToDo.Web/Projects/List.cs",
    "content": "﻿using FluentValidation;\nusing NimblePros.SampleToDo.Core.ProjectAggregate;\nusing NimblePros.SampleToDo.UseCases.Projects;\nusing NimblePros.SampleToDo.UseCases.Projects.ListShallow;\n\nnamespace NimblePros.SampleToDo.Web.Projects;\n\npublic class List(IMediator mediator) : Endpoint<ListProjectsRequest, ProjectListResponse, ListProjectsMapper>\n{\n  private readonly IMediator _mediator = mediator;\n\n  public override void Configure()\n  {\n    Get($\"/{nameof(Project)}s\");\n    AllowAnonymous();\n\n    Summary(s =>\n    {\n      s.Summary = \"List projects with pagination\";\n      s.Description = \"Retrieves a paginated list of all projects without their todo items. Supports GitHub-style pagination with 1-based page indexing and configurable page size.\";\n      s.ExampleRequest = new ListProjectsRequest { Page = 1, PerPage = 10 };\n      s.ResponseExamples[200] = new ProjectListResponse(\n        new List<ProjectRecord> \n        { \n          new(1, \"Sample Project\"), \n          new(2, \"Another Project\") \n        },\n        1, 10, 2, 1);\n      \n      // Document pagination parameters\n      s.Params[\"page\"] = \"1-based page index (default 1)\";\n      s.Params[\"per_page\"] = $\"Page size 1–{UseCases.Constants.MAX_PAGE_SIZE} (default {UseCases.Constants.DEFAULT_PAGE_SIZE})\";\n      \n      // Document possible responses\n      s.Responses[200] = \"Paginated list of projects returned successfully\";\n      s.Responses[400] = \"Invalid pagination parameters\";\n    });\n    \n    // Add tags for API grouping\n    Tags(\"Projects\");\n    \n    // Add additional metadata\n    Description(builder => builder\n      .Accepts<ListProjectsRequest>()\n      .Produces<ProjectListResponse>(200, \"application/json\")\n      .ProducesProblem(400));\n  }\n\n  public override async Task HandleAsync(ListProjectsRequest request, CancellationToken cancellationToken)\n  {\n    var result = await _mediator.Send(new ListProjectsShallowQuery(null, null));\n\n    if (!result.IsSuccess)\n    {\n      await Send.ErrorsAsync(statusCode: 400, cancellationToken);\n      return;\n    }\n\n    // For now, simulate pagination behavior until ListProjectsShallowQuery supports it\n    var allProjects = result.Value.ToList();\n    var skip = (request.Page - 1) * request.PerPage;\n    var pagedProjects = allProjects.Skip(skip).Take(request.PerPage).ToList();\n    var totalCount = allProjects.Count;\n    var totalPages = (int)Math.Ceiling((double)totalCount / request.PerPage);\n\n    AddLinkHeader(request.Page, request.PerPage, totalPages);\n\n    var pagedResult = new UseCases.PagedResult<ProjectDto>(\n      pagedProjects, \n      request.Page, \n      request.PerPage, \n      totalCount, \n      totalPages);\n\n    var response = Map.FromEntity(pagedResult);\n    await Send.OkAsync(response, cancellationToken);\n  }\n\n  private void AddLinkHeader(int page, int perPage, int totalPages)\n  {\n    var baseUrl = $\"{HttpContext.Request.Scheme}://{HttpContext.Request.Host}{HttpContext.Request.Path}\";\n    string Link(string rel, int p) => $\"<{baseUrl}?page={p}&per_page={perPage}>; rel=\\\"{rel}\\\"\";\n\n    var parts = new List<string>();\n    if (page > 1)\n    {\n      parts.Add(Link(\"first\", 1));\n      parts.Add(Link(\"prev\", page - 1));\n    }\n    if (page < totalPages)\n    {\n      parts.Add(Link(\"next\", page + 1));\n      parts.Add(Link(\"last\", totalPages));\n    }\n\n    if (parts.Count > 0)\n      HttpContext.Response.Headers[\"Link\"] = string.Join(\", \", parts);\n  }\n}\n\npublic sealed class ListProjectsRequest\n{\n  // Bind to ?page=\n  [BindFrom(\"page\")]\n  public int Page { get; init; } = 1;\n\n  // Bind to ?per_page=\n  [BindFrom(\"per_page\")]\n  public int PerPage { get; init; } = UseCases.Constants.DEFAULT_PAGE_SIZE;\n}\n\npublic sealed class ListProjectsValidator : Validator<ListProjectsRequest>\n{\n  public ListProjectsValidator()\n  {\n    RuleFor(x => x.Page)\n      .GreaterThanOrEqualTo(1)\n      .WithMessage(\"page must be >= 1\");\n\n    RuleFor(x => x.PerPage)\n      .InclusiveBetween(1, UseCases.Constants.MAX_PAGE_SIZE)\n      .WithMessage($\"per_page must be between 1 and {UseCases.Constants.MAX_PAGE_SIZE}\");\n  }\n}\n\npublic sealed class ListProjectsMapper\n  : Mapper<ListProjectsRequest, ProjectListResponse, UseCases.PagedResult<ProjectDto>>\n{\n  public override ProjectListResponse FromEntity(UseCases.PagedResult<ProjectDto> e)\n  {\n    var items = e.Items\n      .Select(p => new ProjectRecord(p.Id, p.Name))\n      .ToList();\n\n    return new ProjectListResponse(items, e.Page, e.PerPage, e.TotalCount, e.TotalPages);\n  }\n}\n"
  },
  {
    "path": "sample/src/NimblePros.SampleToDo.Web/Projects/ListIncompleteItems.ListIncompleteItemsRequest.cs",
    "content": "﻿using Microsoft.AspNetCore.Mvc;\n\nnamespace NimblePros.SampleToDo.Web.Endpoints.ProjectEndpoints;\n\npublic class ListIncompleteItemsRequest\n{\n  public const string Route = \"/Projects/{ProjectId}/IncompleteItems\";\n  public static string BuildRoute(int projectId) => Route.Replace(\"{ProjectId:int}\", projectId.ToString());\n\n\n  [FromRoute]\n  public int ProjectId { get; set; }\n  //[FromQuery]\n  //public string? SearchString { get; set; }\n}\n"
  },
  {
    "path": "sample/src/NimblePros.SampleToDo.Web/Projects/ListIncompleteItems.ListIncompleteItemsResponse.cs",
    "content": "﻿namespace NimblePros.SampleToDo.Web.Projects;\n\npublic class ListIncompleteItemsResponse\n{\n  public ListIncompleteItemsResponse(int projectId, List<ToDoItemRecord> incompleteItems)\n  {\n    ProjectId = projectId;\n    IncompleteItems = incompleteItems;\n  }\n  public int ProjectId { get; set; }\n  public List<ToDoItemRecord> IncompleteItems { get; set; }\n}\n"
  },
  {
    "path": "sample/src/NimblePros.SampleToDo.Web/Projects/ListIncompleteItems.cs",
    "content": "﻿using NimblePros.SampleToDo.UseCases.Projects.ListIncompleteItems;\nusing NimblePros.SampleToDo.Web.Endpoints.ProjectEndpoints;\n\nnamespace NimblePros.SampleToDo.Web.Projects;\n\n/// <summary>\n/// Lists all incomplete items in a project.\n/// </summary>\n/// <remarks>\n/// Lists all incomplete items in a project.\n/// Returns FAKE data in DEV. Run in production to use real database-driven data.\n/// </remarks>\npublic class ListIncompleteItems(IMediator mediator) : Endpoint<ListIncompleteItemsRequest, ListIncompleteItemsResponse>\n{\n  private readonly IMediator _mediator = mediator;\n\n  public override void Configure()\n  {\n    Get(ListIncompleteItemsRequest.Route);\n    AllowAnonymous();\n  }\n\n  public override async Task HandleAsync(ListIncompleteItemsRequest request, CancellationToken cancellationToken)\n  {\n    Response = new ListIncompleteItemsResponse(request.ProjectId, new List<ToDoItemRecord>());\n\n    var result = await _mediator.Send(new ListIncompleteItemsByProjectQuery(request.ProjectId));\n\n    if (result.Status == ResultStatus.NotFound)\n    {\n      await Send.NotFoundAsync(cancellationToken);\n      return;\n    }\n\n    Response.IncompleteItems = result.Value.Select(item =>\n                    new ToDoItemRecord(item.Id.Value, item.Title, item.Description, item.IsComplete, item.ContributorId?.Value))\n                    .ToList();\n\n  }\n}\n"
  },
  {
    "path": "sample/src/NimblePros.SampleToDo.Web/Projects/MarkItemComplete.MarkItemCompleteRequest.cs",
    "content": "﻿using System.ComponentModel.DataAnnotations;\nusing Microsoft.AspNetCore.Mvc;\n\nnamespace NimblePros.SampleToDo.Web.ProjectEndpoints;\n\npublic class MarkItemCompleteRequest\n{\n  public const string Route = \"/Projects/{ProjectId:int}/ToDoItems/{ToDoItemId:int}\";\n  public static string BuildRoute(int projectId, int toDoItemId) => Route.Replace(\"{ProjectId:int}\", projectId.ToString())\n                                                                         .Replace(\"{ToDoItemId:int}\", toDoItemId.ToString());\n\n  [Required]\n  [FromRoute]\n  public int ProjectId { get; set; } = 0;\n  [Required]\n  [FromRoute]\n  public int ToDoItemId { get; set; } = 0;\n\n}\n"
  },
  {
    "path": "sample/src/NimblePros.SampleToDo.Web/Projects/MarkItemComplete.cs",
    "content": "﻿using NimblePros.SampleToDo.Core.ProjectAggregate;\nusing NimblePros.SampleToDo.UseCases.Projects.MarkToDoItemComplete;\n\nnamespace NimblePros.SampleToDo.Web.ProjectEndpoints;\n\n/// <summary>\n/// Mark an item as complete\n/// </summary>\npublic class MarkItemComplete(IMediator mediator) : Endpoint<MarkItemCompleteRequest>\n{\n  private readonly IMediator _mediator = mediator;\n\n  public override void Configure()\n  {\n    Post(MarkItemCompleteRequest.Route);\n    AllowAnonymous();\n    Summary(s =>\n    {\n      s.ExampleRequest = new MarkItemCompleteRequest\n      {\n        ProjectId = 1,\n        ToDoItemId = 1\n      };\n    });\n  }\n\n  public override async Task HandleAsync(\n    MarkItemCompleteRequest request,\n    CancellationToken cancellationToken)\n  {\n    var command = new MarkToDoItemCompleteCommand(ProjectId.From(request.ProjectId), request.ToDoItemId);\n    var result = await _mediator.Send(command);\n\n    if (result.Status == Ardalis.Result.ResultStatus.NotFound)\n    {\n      await Send.NotFoundAsync(cancellationToken);\n      return;\n    }\n\n    if (result.IsSuccess)\n    {\n      await Send.NoContentAsync(cancellationToken);\n    };\n    // TODO: Handle other issues as needed\n  }\n\n}\n"
  },
  {
    "path": "sample/src/NimblePros.SampleToDo.Web/Projects/ProjectRecord.cs",
    "content": "﻿namespace NimblePros.SampleToDo.Web.Projects;\n\npublic record ProjectRecord(int Id, string Name);\n"
  },
  {
    "path": "sample/src/NimblePros.SampleToDo.Web/Projects/ToDoItemRecord.cs",
    "content": "﻿namespace NimblePros.SampleToDo.Web.Projects;\npublic record ToDoItemRecord(int Id, string Title, string Description, bool IsDone, int? ContributorId);\n"
  },
  {
    "path": "sample/src/NimblePros.SampleToDo.Web/Projects/Update.UpdateProjectRequest.cs",
    "content": "﻿using System.ComponentModel.DataAnnotations;\n\nnamespace NimblePros.SampleToDo.Web.Projects;\n\npublic class UpdateProjectRequest\n{\n  public const string Route = \"/Projects/{ProjectId:int}\";\n  public static string BuildRoute(int projectId) => Route.Replace(\"{ProjectId:int}\", projectId.ToString());\n\n  public int ProjectId { get; set; }\n\n  [Required]\n  public int Id { get; set; }\n  [Required]\n  public string? Name { get; set; }\n}\n"
  },
  {
    "path": "sample/src/NimblePros.SampleToDo.Web/Projects/Update.UpdateProjectRequestValidator.cs",
    "content": "﻿using FluentValidation;\nusing NimblePros.SampleToDo.Infrastructure.Data.Config;\n\nnamespace NimblePros.SampleToDo.Web.Projects;\n\n/// <summary>\n/// See: https://fast-endpoints.com/docs/validation\n/// </summary>\npublic class UpdateProjectRequestValidator : Validator<UpdateProjectRequest>\n{\n  public UpdateProjectRequestValidator()\n  {\n    RuleFor(x => x.Name)\n      .NotEmpty()\n      .WithMessage(\"Name is required.\")\n      .MinimumLength(2)\n      .MaximumLength(DataSchemaConstants.DEFAULT_NAME_LENGTH);\n    RuleFor(x => x.ProjectId)\n      .Must((args, projectId) => args.Id == projectId)\n      .WithMessage(\"Route and body Ids must match; cannot update Id of an existing resource.\");\n  }\n}\n"
  },
  {
    "path": "sample/src/NimblePros.SampleToDo.Web/Projects/Update.UpdateProjectResponse.cs",
    "content": "﻿namespace NimblePros.SampleToDo.Web.Projects;\n\npublic class UpdateProjectResponse\n{\n  public UpdateProjectResponse(ProjectRecord project)\n  {\n    Project = project;\n  }\n  public ProjectRecord Project { get; set; }\n}\n"
  },
  {
    "path": "sample/src/NimblePros.SampleToDo.Web/Projects/Update.cs",
    "content": "﻿using NimblePros.SampleToDo.Core.ProjectAggregate;\nusing NimblePros.SampleToDo.UseCases.Projects;\nusing NimblePros.SampleToDo.UseCases.Projects.Update;\nusing NimblePros.SampleToDo.Web.Extensions;\n\nnamespace NimblePros.SampleToDo.Web.Projects;\n\npublic class Update(IMediator mediator)\n  : Endpoint<\n        UpdateProjectRequest,\n        Results<Ok<UpdateProjectResponse>, NotFound, ProblemHttpResult>,\n        UpdateProjectMapper>\n{\n  private readonly IMediator _mediator = mediator;\n\n  public override void Configure()\n  {\n    Put(UpdateProjectRequest.Route);\n    AllowAnonymous();\n\n    // Optional but nice: enumerate for Swagger\n    Summary(s =>\n    {\n      s.Summary = \"Update a project\";\n      s.Description = \"Updates an existing project's information. The project name must be between 2 and 100 characters long.\";\n      s.ExampleRequest = new UpdateProjectRequest { Id = 1, Name = \"Updated Project Name\" };\n      s.ResponseExamples[200] = new UpdateProjectResponse(new ProjectRecord(1, \"Updated Project Name\"));\n      \n      // Document possible responses\n      s.Responses[200] = \"Project updated successfully\";\n      s.Responses[404] = \"Project with specified ID not found\";\n      s.Responses[400] = \"Invalid input data or business rule violation\";\n    });\n    \n    // Add tags for API grouping\n    Tags(\"Projects\");\n    \n    // Add additional metadata\n    Description(builder => builder\n      .Accepts<UpdateProjectRequest>(\"application/json\")\n      .Produces<UpdateProjectResponse>(200, \"application/json\")\n      .ProducesProblem(404)\n      .ProducesProblem(400));\n  }\n\n  public override async Task<Results<Ok<UpdateProjectResponse>, NotFound, ProblemHttpResult>>\n    ExecuteAsync(UpdateProjectRequest request, CancellationToken ct)\n  {\n    var cmd = new UpdateProjectCommand(\n      ProjectId.From(request.Id),\n      ProjectName.From(request.Name!));\n\n    var result = await _mediator.Send(cmd, ct);\n\n    return result.ToUpdateResult(Map.FromEntity);\n  }\n}\n\npublic sealed class UpdateProjectMapper\n  : Mapper<UpdateProjectRequest, UpdateProjectResponse, ProjectDto>\n{\n  public override UpdateProjectResponse FromEntity(ProjectDto e)\n    => new(new ProjectRecord(e.Id, e.Name));\n}\n"
  },
  {
    "path": "sample/src/NimblePros.SampleToDo.Web/Properties/launchSettings.json",
    "content": "{\n  \"iisSettings\": {\n    \"windowsAuthentication\": false,\n    \"anonymousAuthentication\": true,\n    \"iisExpress\": {\n      \"applicationUrl\": \"http://localhost:57677/\",\n      \"sslPort\": 0\n    }\n  },\n  \"profiles\": {\n    \"https\": {\n      \"commandName\": \"Project\",\n      \"dotnetRunMessages\": true,\n      \"launchUrl\": \"swagger\",\n      \"environmentVariables\": {\n        \"ASPNETCORE_ENVIRONMENT\": \"Development\"\n      },\n      \"applicationUrl\": \"https://localhost:57678/\"\n    },\n    \"IIS Express\": {\n      \"commandName\": \"IISExpress\",\n      \"environmentVariables\": {\n        \"ASPNETCORE_ENVIRONMENT\": \"Development\"\n      }\n    }\n  }\n}"
  },
  {
    "path": "sample/src/NimblePros.SampleToDo.Web/SeedData.cs",
    "content": "﻿using NimblePros.SampleToDo.Core.ContributorAggregate;\nusing NimblePros.SampleToDo.Core.ProjectAggregate;\nusing NimblePros.SampleToDo.Infrastructure.Data;\n\nnamespace NimblePros.SampleToDo.Web;\n\npublic static class SeedData\n{\n  public static readonly Contributor Contributor1 = new(ContributorName.From(\"Ardalis\"));\n  public static readonly Contributor Contributor2 = new(ContributorName.From(\"Snowfrog\"));\n  public static readonly Project TestProject1 = new Project(ProjectName.From(\"Test Project\"));\n\n  public static readonly ToDoItem ToDoItem1 =\n    new ToDoItem(title: ToDoItemTitle.From(\"Get Sample Working\"),\n      description: ToDoItemDescription.From(\"Try to get the sample to build.\"));\n\n  public static readonly ToDoItem ToDoItem2 =\n  new ToDoItem(title: ToDoItemTitle.From(\"Review Solution\"),\n    description: ToDoItemDescription.From(\"Review the different projects in the solution and how they relate to one another.\"));\n\n\n  public static readonly ToDoItem ToDoItem3 =\nnew ToDoItem(title: ToDoItemTitle.From(\"Run and Review Tests\"),\n  description: ToDoItemDescription.From(\"Make sure all the tests run and review what they are doing.\"));\n\n  public static async Task InitializeAsync(AppDbContext dbContext)\n  {\n    if (await dbContext.ToDoItems.AnyAsync())\n    {\n      return;   // DB has been seeded\n    }\n\n    await PopulateTestDataAsync(dbContext);\n  }\n\n  public static async Task PopulateTestDataAsync(AppDbContext dbContext)\n  {\n    foreach (var item in dbContext.Projects)\n    {\n      dbContext.Remove(item);\n    }\n    foreach (var item in dbContext.ToDoItems)\n    {\n      dbContext.Remove(item);\n    }\n    foreach (var item in dbContext.Contributors)\n    {\n      dbContext.Remove(item);\n    }\n    await dbContext.SaveChangesAsync();\n\n    dbContext.Contributors.Add(Contributor1);\n    dbContext.Contributors.Add(Contributor2);\n\n    await dbContext.SaveChangesAsync();\n\n    ToDoItem1.AddContributor(Contributor1.Id);\n    ToDoItem2.AddContributor(Contributor2.Id);\n    ToDoItem3.AddContributor(Contributor1.Id);\n\n    TestProject1.AddItem(ToDoItem1);\n    TestProject1.AddItem(ToDoItem2);\n    TestProject1.AddItem(ToDoItem3);\n    dbContext.Projects.Add(TestProject1);\n\n    await dbContext.SaveChangesAsync();\n\n    // add a bunch more contributors to support demonstrating paging\n    for (int i = 1; i <= 25; i++)\n    {\n      dbContext.Contributors.Add(new Contributor(ContributorName.From($\"Contributor {i}\")));\n    }\n    await dbContext.SaveChangesAsync();\n  }\n}\n"
  },
  {
    "path": "sample/src/NimblePros.SampleToDo.Web/api.http",
    "content": "# For more info on HTTP files go to https://aka.ms/vs/httpfile\n@host=https://localhost\n@port=57678\n\n// List all contributors\nGET {{host}}:{{port}}/Contributors\n\n###\n\n// Get a specific contributor\n@id_to_get=1\nGET {{host}}:{{port}}/Contributors/{{id_to_get}}\n\n###\n\n// Add a new contributor\nPOST {{host}}:{{port}}/Contributors\nContent-Type: application/json\n\n{\n  \"name\": \"John Doe 123\",\n  \"email\": \"test@t2est.com\",\n  \"phoneNumber\": \"1224567890\"\n}\n\n###\n\n// Update a contributor\n@id_to_update=1\nPUT {{host}}:{{port}}/Contributors/{{id_to_update}}\nContent-Type: application/json\n\n{\n  \"id\": {{id_to_update}},\n  \"name\": \"ardalis\"\n}\n\n###\n\n// Delete a contributor\n@id_to_delete=5\nDELETE {{host}}:{{port}}/Contributors/{{id_to_delete}}\n\n\n###\n\n// List all Projects\nGET {{host}}:{{port}}/Projects\n\n###\n\n// Get a specific project\n@projectId_to_get=1\nGET {{host}}:{{port}}/Projects/{{projectId_to_get}}\n\n###\n\n// Delete a specific project\n@projectId_to_delete=20\nDELETE {{host}}:{{port}}/Projects/{{projectId_to_delete}}\n\n###\n\n// Create a new project\nPOST {{host}}:{{port}}/Projects\nContent-Type: application/json\n\n{\n  \"name\": \"New Project\"\n}\n\n###\n\n// Update project - specify id in body\nPUT {{host}}:{{port}}/Projects/\nContent-Type: application/json\n\n{\n  \"id\": 2,\n  \"name\": \"new name\"\n}\n\n###\n\n// Mark an item as complete\n@project_id=1\n@item_id=2\nPOST {{host}}:{{port}}/Projects/{{project_id}}/ToDoItems/{{item_id}}\nContent-Type: application/json\n\n{\n}\n\n###\n"
  },
  {
    "path": "sample/src/NimblePros.SampleToDo.Web/appsettings.json",
    "content": "﻿{\n  \"ConnectionStrings\": {\n    \"DefaultConnection\": \"Server=(localdb)\\\\v11.0;Database=cleanarchitecture;Trusted_Connection=True;MultipleActiveResultSets=true\",\n    \"SqliteConnection\": \"Data Source=database.sqlite\"\n  },\n  \"Serilog\": {\n    \"MinimumLevel\": {\n      \"Default\": \"Information\",\n      \"Override\": {\n        \"NimblePros.SampleToDo\": \"Debug\",\n        \"Microsoft\" : \"Warning\"\n      }\n    },\n    \"WriteTo\": [\n      {\n        \"Name\": \"Console\"\n      },\n      {\n        \"Name\": \"File\",\n        \"Args\": {\n          \"path\": \"log.txt\",\n          \"rollingInterval\": \"Day\"\n        }\n      },\n      {\n        \"Name\": \"OpenTelemetry\"\n      }\n      //Uncomment this section if you'd like to push your logs to Azure Application Insights\n      //Full list of Serilog Sinks can be found here: https://github.com/serilog/serilog/wiki/Provided-Sinks\n      //{\n      //  \"Name\": \"ApplicationInsights\",\n      //  \"Args\": {\n      //    \"instrumentationKey\": \"\", //Fill in with your ApplicationInsights InstrumentationKey\n      //    \"telemetryConverter\": \"Serilog.Sinks.ApplicationInsights.Sinks.ApplicationInsights.TelemetryConverters.TraceTelemetryConverter, Serilog.Sinks.ApplicationInsights\"\n      //  }\n      //}\n    ]\n  },\n  \"Caching\": {\n    \"DefaultDurationSeconds\": 10,\n    \"Profiles\": {\n      \"Short\": 5,\n      \"Medium\": 60,\n      \"Long\": 300\n    }\n  }\n}\n"
  },
  {
    "path": "sample/src/NimblePros.SampleToDo.Web/i18n/en/Project.json",
    "content": "{\n  \"CoreProjectNameEmpty\": \"Name cannot be empty\",\n  \"CoreProjectNameTooLong\": \"Name cannot be longer than {0} characters\",\n  \"CoreToDoItemDescriptionEmpty\": \"Description cannot be empty\",\n  \"CoreToDoItemDescriptionTooLong\": \"Description cannot be longer than {0} characters\",\n  \"CoreToDoItemTitleEmpty\": \"Title cannot be empty\",\n  \"CoreToDoItemTitleTooLong\": \"Title cannot be longer than {0} characters\"\n}"
  },
  {
    "path": "sample/src/NimblePros.SampleToDo.Web/i18n/fa/Project.json",
    "content": "﻿{\n  \"CoreProjectNameEmpty\": \"نام نمی‌تواند خالی باشد\",\n  \"CoreProjectNameTooLong\": \"نام نمی‌تواند بیش از {0} کاراکتر باشد\",\n  \"CoreToDoItemDescriptionEmpty\": \"توضیحات نمی‌تواند خالی باشد\",\n  \"CoreToDoItemDescriptionTooLong\": \"توضیحات نمی‌تواند بیش از {0} کاراکتر باشد\",\n  \"CoreToDoItemTitleEmpty\": \"عنوان نمی‌تواند خالی باشد\",\n  \"CoreToDoItemTitleTooLong\": \"عنوان نمی‌تواند بیش از {0} کاراکتر باشد\"\n}\n"
  },
  {
    "path": "sample/src/NimblePros.SampleToDo.Web/i18n/fr/Project.json",
    "content": "{\n  \"CoreProjectNameEmpty\": \"Le nom ne peut pas être vide\",\n  \"CoreProjectNameTooLong\": \"Le nom ne peut pas dépasser {0} caractères\",\n  \"CoreToDoItemDescriptionEmpty\": \"La description ne peut pas être vide\",\n  \"CoreToDoItemDescriptionTooLong\": \"La description ne peut pas dépasser {0} caractères\",\n  \"CoreToDoItemTitleEmpty\": \"Le titre ne peut pas être vide\",\n  \"CoreToDoItemTitleTooLong\": \"Le titre ne peut pas dépasser {0} caractères\"\n}\n"
  },
  {
    "path": "sample/src/NimblePros.SampleToDo.Web/wwwroot/css/site.css",
    "content": "html {\n  font-size: 14px;\n}\n\n@media (min-width: 768px) {\n  html {\n    font-size: 16px;\n  }\n}\n\nhtml {\n  position: relative;\n  min-height: 100%;\n}\n\nbody {\n  margin-bottom: 60px;\n}"
  },
  {
    "path": "sample/src/NimblePros.SampleToDo.Web/wwwroot/js/site.js",
    "content": "﻿// Please see documentation at https://docs.microsoft.com/aspnet/core/client-side/bundling-and-minification\n// for details on configuring this project to bundle and minify static web assets.\n\n// Write your JavaScript code.\n"
  },
  {
    "path": "sample/src/NimblePros.SampleToDo.Web/wwwroot/lib/bootstrap/LICENSE",
    "content": "The MIT License (MIT)\n\nCopyright (c) 2011-2021 Twitter, Inc.\nCopyright (c) 2011-2021 The Bootstrap Authors\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n"
  },
  {
    "path": "sample/src/NimblePros.SampleToDo.Web/wwwroot/lib/bootstrap/dist/css/bootstrap-grid.css",
    "content": "/*!\n * Bootstrap Grid v5.1.0 (https://getbootstrap.com/)\n * Copyright 2011-2021 The Bootstrap Authors\n * Copyright 2011-2021 Twitter, Inc.\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n */\n.container,\n.container-fluid,\n.container-xxl,\n.container-xl,\n.container-lg,\n.container-md,\n.container-sm {\n  width: 100%;\n  padding-right: var(--bs-gutter-x, 0.75rem);\n  padding-left: var(--bs-gutter-x, 0.75rem);\n  margin-right: auto;\n  margin-left: auto;\n}\n\n@media (min-width: 576px) {\n  .container-sm, .container {\n    max-width: 540px;\n  }\n}\n@media (min-width: 768px) {\n  .container-md, .container-sm, .container {\n    max-width: 720px;\n  }\n}\n@media (min-width: 992px) {\n  .container-lg, .container-md, .container-sm, .container {\n    max-width: 960px;\n  }\n}\n@media (min-width: 1200px) {\n  .container-xl, .container-lg, .container-md, .container-sm, .container {\n    max-width: 1140px;\n  }\n}\n@media (min-width: 1400px) {\n  .container-xxl, .container-xl, .container-lg, .container-md, .container-sm, .container {\n    max-width: 1320px;\n  }\n}\n.row {\n  --bs-gutter-x: 1.5rem;\n  --bs-gutter-y: 0;\n  display: flex;\n  flex-wrap: wrap;\n  margin-top: calc(var(--bs-gutter-y) * -1);\n  margin-right: calc(var(--bs-gutter-x) * -.5);\n  margin-left: calc(var(--bs-gutter-x) * -.5);\n}\n.row > * {\n  box-sizing: border-box;\n  flex-shrink: 0;\n  width: 100%;\n  max-width: 100%;\n  padding-right: calc(var(--bs-gutter-x) * .5);\n  padding-left: calc(var(--bs-gutter-x) * .5);\n  margin-top: var(--bs-gutter-y);\n}\n\n.col {\n  flex: 1 0 0%;\n}\n\n.row-cols-auto > * {\n  flex: 0 0 auto;\n  width: auto;\n}\n\n.row-cols-1 > * {\n  flex: 0 0 auto;\n  width: 100%;\n}\n\n.row-cols-2 > * {\n  flex: 0 0 auto;\n  width: 50%;\n}\n\n.row-cols-3 > * {\n  flex: 0 0 auto;\n  width: 33.3333333333%;\n}\n\n.row-cols-4 > * {\n  flex: 0 0 auto;\n  width: 25%;\n}\n\n.row-cols-5 > * {\n  flex: 0 0 auto;\n  width: 20%;\n}\n\n.row-cols-6 > * {\n  flex: 0 0 auto;\n  width: 16.6666666667%;\n}\n\n.col-auto {\n  flex: 0 0 auto;\n  width: auto;\n}\n\n.col-1 {\n  flex: 0 0 auto;\n  width: 8.33333333%;\n}\n\n.col-2 {\n  flex: 0 0 auto;\n  width: 16.66666667%;\n}\n\n.col-3 {\n  flex: 0 0 auto;\n  width: 25%;\n}\n\n.col-4 {\n  flex: 0 0 auto;\n  width: 33.33333333%;\n}\n\n.col-5 {\n  flex: 0 0 auto;\n  width: 41.66666667%;\n}\n\n.col-6 {\n  flex: 0 0 auto;\n  width: 50%;\n}\n\n.col-7 {\n  flex: 0 0 auto;\n  width: 58.33333333%;\n}\n\n.col-8 {\n  flex: 0 0 auto;\n  width: 66.66666667%;\n}\n\n.col-9 {\n  flex: 0 0 auto;\n  width: 75%;\n}\n\n.col-10 {\n  flex: 0 0 auto;\n  width: 83.33333333%;\n}\n\n.col-11 {\n  flex: 0 0 auto;\n  width: 91.66666667%;\n}\n\n.col-12 {\n  flex: 0 0 auto;\n  width: 100%;\n}\n\n.offset-1 {\n  margin-left: 8.33333333%;\n}\n\n.offset-2 {\n  margin-left: 16.66666667%;\n}\n\n.offset-3 {\n  margin-left: 25%;\n}\n\n.offset-4 {\n  margin-left: 33.33333333%;\n}\n\n.offset-5 {\n  margin-left: 41.66666667%;\n}\n\n.offset-6 {\n  margin-left: 50%;\n}\n\n.offset-7 {\n  margin-left: 58.33333333%;\n}\n\n.offset-8 {\n  margin-left: 66.66666667%;\n}\n\n.offset-9 {\n  margin-left: 75%;\n}\n\n.offset-10 {\n  margin-left: 83.33333333%;\n}\n\n.offset-11 {\n  margin-left: 91.66666667%;\n}\n\n.g-0,\n.gx-0 {\n  --bs-gutter-x: 0;\n}\n\n.g-0,\n.gy-0 {\n  --bs-gutter-y: 0;\n}\n\n.g-1,\n.gx-1 {\n  --bs-gutter-x: 0.25rem;\n}\n\n.g-1,\n.gy-1 {\n  --bs-gutter-y: 0.25rem;\n}\n\n.g-2,\n.gx-2 {\n  --bs-gutter-x: 0.5rem;\n}\n\n.g-2,\n.gy-2 {\n  --bs-gutter-y: 0.5rem;\n}\n\n.g-3,\n.gx-3 {\n  --bs-gutter-x: 1rem;\n}\n\n.g-3,\n.gy-3 {\n  --bs-gutter-y: 1rem;\n}\n\n.g-4,\n.gx-4 {\n  --bs-gutter-x: 1.5rem;\n}\n\n.g-4,\n.gy-4 {\n  --bs-gutter-y: 1.5rem;\n}\n\n.g-5,\n.gx-5 {\n  --bs-gutter-x: 3rem;\n}\n\n.g-5,\n.gy-5 {\n  --bs-gutter-y: 3rem;\n}\n\n@media (min-width: 576px) {\n  .col-sm {\n    flex: 1 0 0%;\n  }\n\n  .row-cols-sm-auto > * {\n    flex: 0 0 auto;\n    width: auto;\n  }\n\n  .row-cols-sm-1 > * {\n    flex: 0 0 auto;\n    width: 100%;\n  }\n\n  .row-cols-sm-2 > * {\n    flex: 0 0 auto;\n    width: 50%;\n  }\n\n  .row-cols-sm-3 > * {\n    flex: 0 0 auto;\n    width: 33.3333333333%;\n  }\n\n  .row-cols-sm-4 > * {\n    flex: 0 0 auto;\n    width: 25%;\n  }\n\n  .row-cols-sm-5 > * {\n    flex: 0 0 auto;\n    width: 20%;\n  }\n\n  .row-cols-sm-6 > * {\n    flex: 0 0 auto;\n    width: 16.6666666667%;\n  }\n\n  .col-sm-auto {\n    flex: 0 0 auto;\n    width: auto;\n  }\n\n  .col-sm-1 {\n    flex: 0 0 auto;\n    width: 8.33333333%;\n  }\n\n  .col-sm-2 {\n    flex: 0 0 auto;\n    width: 16.66666667%;\n  }\n\n  .col-sm-3 {\n    flex: 0 0 auto;\n    width: 25%;\n  }\n\n  .col-sm-4 {\n    flex: 0 0 auto;\n    width: 33.33333333%;\n  }\n\n  .col-sm-5 {\n    flex: 0 0 auto;\n    width: 41.66666667%;\n  }\n\n  .col-sm-6 {\n    flex: 0 0 auto;\n    width: 50%;\n  }\n\n  .col-sm-7 {\n    flex: 0 0 auto;\n    width: 58.33333333%;\n  }\n\n  .col-sm-8 {\n    flex: 0 0 auto;\n    width: 66.66666667%;\n  }\n\n  .col-sm-9 {\n    flex: 0 0 auto;\n    width: 75%;\n  }\n\n  .col-sm-10 {\n    flex: 0 0 auto;\n    width: 83.33333333%;\n  }\n\n  .col-sm-11 {\n    flex: 0 0 auto;\n    width: 91.66666667%;\n  }\n\n  .col-sm-12 {\n    flex: 0 0 auto;\n    width: 100%;\n  }\n\n  .offset-sm-0 {\n    margin-left: 0;\n  }\n\n  .offset-sm-1 {\n    margin-left: 8.33333333%;\n  }\n\n  .offset-sm-2 {\n    margin-left: 16.66666667%;\n  }\n\n  .offset-sm-3 {\n    margin-left: 25%;\n  }\n\n  .offset-sm-4 {\n    margin-left: 33.33333333%;\n  }\n\n  .offset-sm-5 {\n    margin-left: 41.66666667%;\n  }\n\n  .offset-sm-6 {\n    margin-left: 50%;\n  }\n\n  .offset-sm-7 {\n    margin-left: 58.33333333%;\n  }\n\n  .offset-sm-8 {\n    margin-left: 66.66666667%;\n  }\n\n  .offset-sm-9 {\n    margin-left: 75%;\n  }\n\n  .offset-sm-10 {\n    margin-left: 83.33333333%;\n  }\n\n  .offset-sm-11 {\n    margin-left: 91.66666667%;\n  }\n\n  .g-sm-0,\n.gx-sm-0 {\n    --bs-gutter-x: 0;\n  }\n\n  .g-sm-0,\n.gy-sm-0 {\n    --bs-gutter-y: 0;\n  }\n\n  .g-sm-1,\n.gx-sm-1 {\n    --bs-gutter-x: 0.25rem;\n  }\n\n  .g-sm-1,\n.gy-sm-1 {\n    --bs-gutter-y: 0.25rem;\n  }\n\n  .g-sm-2,\n.gx-sm-2 {\n    --bs-gutter-x: 0.5rem;\n  }\n\n  .g-sm-2,\n.gy-sm-2 {\n    --bs-gutter-y: 0.5rem;\n  }\n\n  .g-sm-3,\n.gx-sm-3 {\n    --bs-gutter-x: 1rem;\n  }\n\n  .g-sm-3,\n.gy-sm-3 {\n    --bs-gutter-y: 1rem;\n  }\n\n  .g-sm-4,\n.gx-sm-4 {\n    --bs-gutter-x: 1.5rem;\n  }\n\n  .g-sm-4,\n.gy-sm-4 {\n    --bs-gutter-y: 1.5rem;\n  }\n\n  .g-sm-5,\n.gx-sm-5 {\n    --bs-gutter-x: 3rem;\n  }\n\n  .g-sm-5,\n.gy-sm-5 {\n    --bs-gutter-y: 3rem;\n  }\n}\n@media (min-width: 768px) {\n  .col-md {\n    flex: 1 0 0%;\n  }\n\n  .row-cols-md-auto > * {\n    flex: 0 0 auto;\n    width: auto;\n  }\n\n  .row-cols-md-1 > * {\n    flex: 0 0 auto;\n    width: 100%;\n  }\n\n  .row-cols-md-2 > * {\n    flex: 0 0 auto;\n    width: 50%;\n  }\n\n  .row-cols-md-3 > * {\n    flex: 0 0 auto;\n    width: 33.3333333333%;\n  }\n\n  .row-cols-md-4 > * {\n    flex: 0 0 auto;\n    width: 25%;\n  }\n\n  .row-cols-md-5 > * {\n    flex: 0 0 auto;\n    width: 20%;\n  }\n\n  .row-cols-md-6 > * {\n    flex: 0 0 auto;\n    width: 16.6666666667%;\n  }\n\n  .col-md-auto {\n    flex: 0 0 auto;\n    width: auto;\n  }\n\n  .col-md-1 {\n    flex: 0 0 auto;\n    width: 8.33333333%;\n  }\n\n  .col-md-2 {\n    flex: 0 0 auto;\n    width: 16.66666667%;\n  }\n\n  .col-md-3 {\n    flex: 0 0 auto;\n    width: 25%;\n  }\n\n  .col-md-4 {\n    flex: 0 0 auto;\n    width: 33.33333333%;\n  }\n\n  .col-md-5 {\n    flex: 0 0 auto;\n    width: 41.66666667%;\n  }\n\n  .col-md-6 {\n    flex: 0 0 auto;\n    width: 50%;\n  }\n\n  .col-md-7 {\n    flex: 0 0 auto;\n    width: 58.33333333%;\n  }\n\n  .col-md-8 {\n    flex: 0 0 auto;\n    width: 66.66666667%;\n  }\n\n  .col-md-9 {\n    flex: 0 0 auto;\n    width: 75%;\n  }\n\n  .col-md-10 {\n    flex: 0 0 auto;\n    width: 83.33333333%;\n  }\n\n  .col-md-11 {\n    flex: 0 0 auto;\n    width: 91.66666667%;\n  }\n\n  .col-md-12 {\n    flex: 0 0 auto;\n    width: 100%;\n  }\n\n  .offset-md-0 {\n    margin-left: 0;\n  }\n\n  .offset-md-1 {\n    margin-left: 8.33333333%;\n  }\n\n  .offset-md-2 {\n    margin-left: 16.66666667%;\n  }\n\n  .offset-md-3 {\n    margin-left: 25%;\n  }\n\n  .offset-md-4 {\n    margin-left: 33.33333333%;\n  }\n\n  .offset-md-5 {\n    margin-left: 41.66666667%;\n  }\n\n  .offset-md-6 {\n    margin-left: 50%;\n  }\n\n  .offset-md-7 {\n    margin-left: 58.33333333%;\n  }\n\n  .offset-md-8 {\n    margin-left: 66.66666667%;\n  }\n\n  .offset-md-9 {\n    margin-left: 75%;\n  }\n\n  .offset-md-10 {\n    margin-left: 83.33333333%;\n  }\n\n  .offset-md-11 {\n    margin-left: 91.66666667%;\n  }\n\n  .g-md-0,\n.gx-md-0 {\n    --bs-gutter-x: 0;\n  }\n\n  .g-md-0,\n.gy-md-0 {\n    --bs-gutter-y: 0;\n  }\n\n  .g-md-1,\n.gx-md-1 {\n    --bs-gutter-x: 0.25rem;\n  }\n\n  .g-md-1,\n.gy-md-1 {\n    --bs-gutter-y: 0.25rem;\n  }\n\n  .g-md-2,\n.gx-md-2 {\n    --bs-gutter-x: 0.5rem;\n  }\n\n  .g-md-2,\n.gy-md-2 {\n    --bs-gutter-y: 0.5rem;\n  }\n\n  .g-md-3,\n.gx-md-3 {\n    --bs-gutter-x: 1rem;\n  }\n\n  .g-md-3,\n.gy-md-3 {\n    --bs-gutter-y: 1rem;\n  }\n\n  .g-md-4,\n.gx-md-4 {\n    --bs-gutter-x: 1.5rem;\n  }\n\n  .g-md-4,\n.gy-md-4 {\n    --bs-gutter-y: 1.5rem;\n  }\n\n  .g-md-5,\n.gx-md-5 {\n    --bs-gutter-x: 3rem;\n  }\n\n  .g-md-5,\n.gy-md-5 {\n    --bs-gutter-y: 3rem;\n  }\n}\n@media (min-width: 992px) {\n  .col-lg {\n    flex: 1 0 0%;\n  }\n\n  .row-cols-lg-auto > * {\n    flex: 0 0 auto;\n    width: auto;\n  }\n\n  .row-cols-lg-1 > * {\n    flex: 0 0 auto;\n    width: 100%;\n  }\n\n  .row-cols-lg-2 > * {\n    flex: 0 0 auto;\n    width: 50%;\n  }\n\n  .row-cols-lg-3 > * {\n    flex: 0 0 auto;\n    width: 33.3333333333%;\n  }\n\n  .row-cols-lg-4 > * {\n    flex: 0 0 auto;\n    width: 25%;\n  }\n\n  .row-cols-lg-5 > * {\n    flex: 0 0 auto;\n    width: 20%;\n  }\n\n  .row-cols-lg-6 > * {\n    flex: 0 0 auto;\n    width: 16.6666666667%;\n  }\n\n  .col-lg-auto {\n    flex: 0 0 auto;\n    width: auto;\n  }\n\n  .col-lg-1 {\n    flex: 0 0 auto;\n    width: 8.33333333%;\n  }\n\n  .col-lg-2 {\n    flex: 0 0 auto;\n    width: 16.66666667%;\n  }\n\n  .col-lg-3 {\n    flex: 0 0 auto;\n    width: 25%;\n  }\n\n  .col-lg-4 {\n    flex: 0 0 auto;\n    width: 33.33333333%;\n  }\n\n  .col-lg-5 {\n    flex: 0 0 auto;\n    width: 41.66666667%;\n  }\n\n  .col-lg-6 {\n    flex: 0 0 auto;\n    width: 50%;\n  }\n\n  .col-lg-7 {\n    flex: 0 0 auto;\n    width: 58.33333333%;\n  }\n\n  .col-lg-8 {\n    flex: 0 0 auto;\n    width: 66.66666667%;\n  }\n\n  .col-lg-9 {\n    flex: 0 0 auto;\n    width: 75%;\n  }\n\n  .col-lg-10 {\n    flex: 0 0 auto;\n    width: 83.33333333%;\n  }\n\n  .col-lg-11 {\n    flex: 0 0 auto;\n    width: 91.66666667%;\n  }\n\n  .col-lg-12 {\n    flex: 0 0 auto;\n    width: 100%;\n  }\n\n  .offset-lg-0 {\n    margin-left: 0;\n  }\n\n  .offset-lg-1 {\n    margin-left: 8.33333333%;\n  }\n\n  .offset-lg-2 {\n    margin-left: 16.66666667%;\n  }\n\n  .offset-lg-3 {\n    margin-left: 25%;\n  }\n\n  .offset-lg-4 {\n    margin-left: 33.33333333%;\n  }\n\n  .offset-lg-5 {\n    margin-left: 41.66666667%;\n  }\n\n  .offset-lg-6 {\n    margin-left: 50%;\n  }\n\n  .offset-lg-7 {\n    margin-left: 58.33333333%;\n  }\n\n  .offset-lg-8 {\n    margin-left: 66.66666667%;\n  }\n\n  .offset-lg-9 {\n    margin-left: 75%;\n  }\n\n  .offset-lg-10 {\n    margin-left: 83.33333333%;\n  }\n\n  .offset-lg-11 {\n    margin-left: 91.66666667%;\n  }\n\n  .g-lg-0,\n.gx-lg-0 {\n    --bs-gutter-x: 0;\n  }\n\n  .g-lg-0,\n.gy-lg-0 {\n    --bs-gutter-y: 0;\n  }\n\n  .g-lg-1,\n.gx-lg-1 {\n    --bs-gutter-x: 0.25rem;\n  }\n\n  .g-lg-1,\n.gy-lg-1 {\n    --bs-gutter-y: 0.25rem;\n  }\n\n  .g-lg-2,\n.gx-lg-2 {\n    --bs-gutter-x: 0.5rem;\n  }\n\n  .g-lg-2,\n.gy-lg-2 {\n    --bs-gutter-y: 0.5rem;\n  }\n\n  .g-lg-3,\n.gx-lg-3 {\n    --bs-gutter-x: 1rem;\n  }\n\n  .g-lg-3,\n.gy-lg-3 {\n    --bs-gutter-y: 1rem;\n  }\n\n  .g-lg-4,\n.gx-lg-4 {\n    --bs-gutter-x: 1.5rem;\n  }\n\n  .g-lg-4,\n.gy-lg-4 {\n    --bs-gutter-y: 1.5rem;\n  }\n\n  .g-lg-5,\n.gx-lg-5 {\n    --bs-gutter-x: 3rem;\n  }\n\n  .g-lg-5,\n.gy-lg-5 {\n    --bs-gutter-y: 3rem;\n  }\n}\n@media (min-width: 1200px) {\n  .col-xl {\n    flex: 1 0 0%;\n  }\n\n  .row-cols-xl-auto > * {\n    flex: 0 0 auto;\n    width: auto;\n  }\n\n  .row-cols-xl-1 > * {\n    flex: 0 0 auto;\n    width: 100%;\n  }\n\n  .row-cols-xl-2 > * {\n    flex: 0 0 auto;\n    width: 50%;\n  }\n\n  .row-cols-xl-3 > * {\n    flex: 0 0 auto;\n    width: 33.3333333333%;\n  }\n\n  .row-cols-xl-4 > * {\n    flex: 0 0 auto;\n    width: 25%;\n  }\n\n  .row-cols-xl-5 > * {\n    flex: 0 0 auto;\n    width: 20%;\n  }\n\n  .row-cols-xl-6 > * {\n    flex: 0 0 auto;\n    width: 16.6666666667%;\n  }\n\n  .col-xl-auto {\n    flex: 0 0 auto;\n    width: auto;\n  }\n\n  .col-xl-1 {\n    flex: 0 0 auto;\n    width: 8.33333333%;\n  }\n\n  .col-xl-2 {\n    flex: 0 0 auto;\n    width: 16.66666667%;\n  }\n\n  .col-xl-3 {\n    flex: 0 0 auto;\n    width: 25%;\n  }\n\n  .col-xl-4 {\n    flex: 0 0 auto;\n    width: 33.33333333%;\n  }\n\n  .col-xl-5 {\n    flex: 0 0 auto;\n    width: 41.66666667%;\n  }\n\n  .col-xl-6 {\n    flex: 0 0 auto;\n    width: 50%;\n  }\n\n  .col-xl-7 {\n    flex: 0 0 auto;\n    width: 58.33333333%;\n  }\n\n  .col-xl-8 {\n    flex: 0 0 auto;\n    width: 66.66666667%;\n  }\n\n  .col-xl-9 {\n    flex: 0 0 auto;\n    width: 75%;\n  }\n\n  .col-xl-10 {\n    flex: 0 0 auto;\n    width: 83.33333333%;\n  }\n\n  .col-xl-11 {\n    flex: 0 0 auto;\n    width: 91.66666667%;\n  }\n\n  .col-xl-12 {\n    flex: 0 0 auto;\n    width: 100%;\n  }\n\n  .offset-xl-0 {\n    margin-left: 0;\n  }\n\n  .offset-xl-1 {\n    margin-left: 8.33333333%;\n  }\n\n  .offset-xl-2 {\n    margin-left: 16.66666667%;\n  }\n\n  .offset-xl-3 {\n    margin-left: 25%;\n  }\n\n  .offset-xl-4 {\n    margin-left: 33.33333333%;\n  }\n\n  .offset-xl-5 {\n    margin-left: 41.66666667%;\n  }\n\n  .offset-xl-6 {\n    margin-left: 50%;\n  }\n\n  .offset-xl-7 {\n    margin-left: 58.33333333%;\n  }\n\n  .offset-xl-8 {\n    margin-left: 66.66666667%;\n  }\n\n  .offset-xl-9 {\n    margin-left: 75%;\n  }\n\n  .offset-xl-10 {\n    margin-left: 83.33333333%;\n  }\n\n  .offset-xl-11 {\n    margin-left: 91.66666667%;\n  }\n\n  .g-xl-0,\n.gx-xl-0 {\n    --bs-gutter-x: 0;\n  }\n\n  .g-xl-0,\n.gy-xl-0 {\n    --bs-gutter-y: 0;\n  }\n\n  .g-xl-1,\n.gx-xl-1 {\n    --bs-gutter-x: 0.25rem;\n  }\n\n  .g-xl-1,\n.gy-xl-1 {\n    --bs-gutter-y: 0.25rem;\n  }\n\n  .g-xl-2,\n.gx-xl-2 {\n    --bs-gutter-x: 0.5rem;\n  }\n\n  .g-xl-2,\n.gy-xl-2 {\n    --bs-gutter-y: 0.5rem;\n  }\n\n  .g-xl-3,\n.gx-xl-3 {\n    --bs-gutter-x: 1rem;\n  }\n\n  .g-xl-3,\n.gy-xl-3 {\n    --bs-gutter-y: 1rem;\n  }\n\n  .g-xl-4,\n.gx-xl-4 {\n    --bs-gutter-x: 1.5rem;\n  }\n\n  .g-xl-4,\n.gy-xl-4 {\n    --bs-gutter-y: 1.5rem;\n  }\n\n  .g-xl-5,\n.gx-xl-5 {\n    --bs-gutter-x: 3rem;\n  }\n\n  .g-xl-5,\n.gy-xl-5 {\n    --bs-gutter-y: 3rem;\n  }\n}\n@media (min-width: 1400px) {\n  .col-xxl {\n    flex: 1 0 0%;\n  }\n\n  .row-cols-xxl-auto > * {\n    flex: 0 0 auto;\n    width: auto;\n  }\n\n  .row-cols-xxl-1 > * {\n    flex: 0 0 auto;\n    width: 100%;\n  }\n\n  .row-cols-xxl-2 > * {\n    flex: 0 0 auto;\n    width: 50%;\n  }\n\n  .row-cols-xxl-3 > * {\n    flex: 0 0 auto;\n    width: 33.3333333333%;\n  }\n\n  .row-cols-xxl-4 > * {\n    flex: 0 0 auto;\n    width: 25%;\n  }\n\n  .row-cols-xxl-5 > * {\n    flex: 0 0 auto;\n    width: 20%;\n  }\n\n  .row-cols-xxl-6 > * {\n    flex: 0 0 auto;\n    width: 16.6666666667%;\n  }\n\n  .col-xxl-auto {\n    flex: 0 0 auto;\n    width: auto;\n  }\n\n  .col-xxl-1 {\n    flex: 0 0 auto;\n    width: 8.33333333%;\n  }\n\n  .col-xxl-2 {\n    flex: 0 0 auto;\n    width: 16.66666667%;\n  }\n\n  .col-xxl-3 {\n    flex: 0 0 auto;\n    width: 25%;\n  }\n\n  .col-xxl-4 {\n    flex: 0 0 auto;\n    width: 33.33333333%;\n  }\n\n  .col-xxl-5 {\n    flex: 0 0 auto;\n    width: 41.66666667%;\n  }\n\n  .col-xxl-6 {\n    flex: 0 0 auto;\n    width: 50%;\n  }\n\n  .col-xxl-7 {\n    flex: 0 0 auto;\n    width: 58.33333333%;\n  }\n\n  .col-xxl-8 {\n    flex: 0 0 auto;\n    width: 66.66666667%;\n  }\n\n  .col-xxl-9 {\n    flex: 0 0 auto;\n    width: 75%;\n  }\n\n  .col-xxl-10 {\n    flex: 0 0 auto;\n    width: 83.33333333%;\n  }\n\n  .col-xxl-11 {\n    flex: 0 0 auto;\n    width: 91.66666667%;\n  }\n\n  .col-xxl-12 {\n    flex: 0 0 auto;\n    width: 100%;\n  }\n\n  .offset-xxl-0 {\n    margin-left: 0;\n  }\n\n  .offset-xxl-1 {\n    margin-left: 8.33333333%;\n  }\n\n  .offset-xxl-2 {\n    margin-left: 16.66666667%;\n  }\n\n  .offset-xxl-3 {\n    margin-left: 25%;\n  }\n\n  .offset-xxl-4 {\n    margin-left: 33.33333333%;\n  }\n\n  .offset-xxl-5 {\n    margin-left: 41.66666667%;\n  }\n\n  .offset-xxl-6 {\n    margin-left: 50%;\n  }\n\n  .offset-xxl-7 {\n    margin-left: 58.33333333%;\n  }\n\n  .offset-xxl-8 {\n    margin-left: 66.66666667%;\n  }\n\n  .offset-xxl-9 {\n    margin-left: 75%;\n  }\n\n  .offset-xxl-10 {\n    margin-left: 83.33333333%;\n  }\n\n  .offset-xxl-11 {\n    margin-left: 91.66666667%;\n  }\n\n  .g-xxl-0,\n.gx-xxl-0 {\n    --bs-gutter-x: 0;\n  }\n\n  .g-xxl-0,\n.gy-xxl-0 {\n    --bs-gutter-y: 0;\n  }\n\n  .g-xxl-1,\n.gx-xxl-1 {\n    --bs-gutter-x: 0.25rem;\n  }\n\n  .g-xxl-1,\n.gy-xxl-1 {\n    --bs-gutter-y: 0.25rem;\n  }\n\n  .g-xxl-2,\n.gx-xxl-2 {\n    --bs-gutter-x: 0.5rem;\n  }\n\n  .g-xxl-2,\n.gy-xxl-2 {\n    --bs-gutter-y: 0.5rem;\n  }\n\n  .g-xxl-3,\n.gx-xxl-3 {\n    --bs-gutter-x: 1rem;\n  }\n\n  .g-xxl-3,\n.gy-xxl-3 {\n    --bs-gutter-y: 1rem;\n  }\n\n  .g-xxl-4,\n.gx-xxl-4 {\n    --bs-gutter-x: 1.5rem;\n  }\n\n  .g-xxl-4,\n.gy-xxl-4 {\n    --bs-gutter-y: 1.5rem;\n  }\n\n  .g-xxl-5,\n.gx-xxl-5 {\n    --bs-gutter-x: 3rem;\n  }\n\n  .g-xxl-5,\n.gy-xxl-5 {\n    --bs-gutter-y: 3rem;\n  }\n}\n.d-inline {\n  display: inline !important;\n}\n\n.d-inline-block {\n  display: inline-block !important;\n}\n\n.d-block {\n  display: block !important;\n}\n\n.d-grid {\n  display: grid !important;\n}\n\n.d-table {\n  display: table !important;\n}\n\n.d-table-row {\n  display: table-row !important;\n}\n\n.d-table-cell {\n  display: table-cell !important;\n}\n\n.d-flex {\n  display: flex !important;\n}\n\n.d-inline-flex {\n  display: inline-flex !important;\n}\n\n.d-none {\n  display: none !important;\n}\n\n.flex-fill {\n  flex: 1 1 auto !important;\n}\n\n.flex-row {\n  flex-direction: row !important;\n}\n\n.flex-column {\n  flex-direction: column !important;\n}\n\n.flex-row-reverse {\n  flex-direction: row-reverse !important;\n}\n\n.flex-column-reverse {\n  flex-direction: column-reverse !important;\n}\n\n.flex-grow-0 {\n  flex-grow: 0 !important;\n}\n\n.flex-grow-1 {\n  flex-grow: 1 !important;\n}\n\n.flex-shrink-0 {\n  flex-shrink: 0 !important;\n}\n\n.flex-shrink-1 {\n  flex-shrink: 1 !important;\n}\n\n.flex-wrap {\n  flex-wrap: wrap !important;\n}\n\n.flex-nowrap {\n  flex-wrap: nowrap !important;\n}\n\n.flex-wrap-reverse {\n  flex-wrap: wrap-reverse !important;\n}\n\n.justify-content-start {\n  justify-content: flex-start !important;\n}\n\n.justify-content-end {\n  justify-content: flex-end !important;\n}\n\n.justify-content-center {\n  justify-content: center !important;\n}\n\n.justify-content-between {\n  justify-content: space-between !important;\n}\n\n.justify-content-around {\n  justify-content: space-around !important;\n}\n\n.justify-content-evenly {\n  justify-content: space-evenly !important;\n}\n\n.align-items-start {\n  align-items: flex-start !important;\n}\n\n.align-items-end {\n  align-items: flex-end !important;\n}\n\n.align-items-center {\n  align-items: center !important;\n}\n\n.align-items-baseline {\n  align-items: baseline !important;\n}\n\n.align-items-stretch {\n  align-items: stretch !important;\n}\n\n.align-content-start {\n  align-content: flex-start !important;\n}\n\n.align-content-end {\n  align-content: flex-end !important;\n}\n\n.align-content-center {\n  align-content: center !important;\n}\n\n.align-content-between {\n  align-content: space-between !important;\n}\n\n.align-content-around {\n  align-content: space-around !important;\n}\n\n.align-content-stretch {\n  align-content: stretch !important;\n}\n\n.align-self-auto {\n  align-self: auto !important;\n}\n\n.align-self-start {\n  align-self: flex-start !important;\n}\n\n.align-self-end {\n  align-self: flex-end !important;\n}\n\n.align-self-center {\n  align-self: center !important;\n}\n\n.align-self-baseline {\n  align-self: baseline !important;\n}\n\n.align-self-stretch {\n  align-self: stretch !important;\n}\n\n.order-first {\n  order: -1 !important;\n}\n\n.order-0 {\n  order: 0 !important;\n}\n\n.order-1 {\n  order: 1 !important;\n}\n\n.order-2 {\n  order: 2 !important;\n}\n\n.order-3 {\n  order: 3 !important;\n}\n\n.order-4 {\n  order: 4 !important;\n}\n\n.order-5 {\n  order: 5 !important;\n}\n\n.order-last {\n  order: 6 !important;\n}\n\n.m-0 {\n  margin: 0 !important;\n}\n\n.m-1 {\n  margin: 0.25rem !important;\n}\n\n.m-2 {\n  margin: 0.5rem !important;\n}\n\n.m-3 {\n  margin: 1rem !important;\n}\n\n.m-4 {\n  margin: 1.5rem !important;\n}\n\n.m-5 {\n  margin: 3rem !important;\n}\n\n.m-auto {\n  margin: auto !important;\n}\n\n.mx-0 {\n  margin-right: 0 !important;\n  margin-left: 0 !important;\n}\n\n.mx-1 {\n  margin-right: 0.25rem !important;\n  margin-left: 0.25rem !important;\n}\n\n.mx-2 {\n  margin-right: 0.5rem !important;\n  margin-left: 0.5rem !important;\n}\n\n.mx-3 {\n  margin-right: 1rem !important;\n  margin-left: 1rem !important;\n}\n\n.mx-4 {\n  margin-right: 1.5rem !important;\n  margin-left: 1.5rem !important;\n}\n\n.mx-5 {\n  margin-right: 3rem !important;\n  margin-left: 3rem !important;\n}\n\n.mx-auto {\n  margin-right: auto !important;\n  margin-left: auto !important;\n}\n\n.my-0 {\n  margin-top: 0 !important;\n  margin-bottom: 0 !important;\n}\n\n.my-1 {\n  margin-top: 0.25rem !important;\n  margin-bottom: 0.25rem !important;\n}\n\n.my-2 {\n  margin-top: 0.5rem !important;\n  margin-bottom: 0.5rem !important;\n}\n\n.my-3 {\n  margin-top: 1rem !important;\n  margin-bottom: 1rem !important;\n}\n\n.my-4 {\n  margin-top: 1.5rem !important;\n  margin-bottom: 1.5rem !important;\n}\n\n.my-5 {\n  margin-top: 3rem !important;\n  margin-bottom: 3rem !important;\n}\n\n.my-auto {\n  margin-top: auto !important;\n  margin-bottom: auto !important;\n}\n\n.mt-0 {\n  margin-top: 0 !important;\n}\n\n.mt-1 {\n  margin-top: 0.25rem !important;\n}\n\n.mt-2 {\n  margin-top: 0.5rem !important;\n}\n\n.mt-3 {\n  margin-top: 1rem !important;\n}\n\n.mt-4 {\n  margin-top: 1.5rem !important;\n}\n\n.mt-5 {\n  margin-top: 3rem !important;\n}\n\n.mt-auto {\n  margin-top: auto !important;\n}\n\n.me-0 {\n  margin-right: 0 !important;\n}\n\n.me-1 {\n  margin-right: 0.25rem !important;\n}\n\n.me-2 {\n  margin-right: 0.5rem !important;\n}\n\n.me-3 {\n  margin-right: 1rem !important;\n}\n\n.me-4 {\n  margin-right: 1.5rem !important;\n}\n\n.me-5 {\n  margin-right: 3rem !important;\n}\n\n.me-auto {\n  margin-right: auto !important;\n}\n\n.mb-0 {\n  margin-bottom: 0 !important;\n}\n\n.mb-1 {\n  margin-bottom: 0.25rem !important;\n}\n\n.mb-2 {\n  margin-bottom: 0.5rem !important;\n}\n\n.mb-3 {\n  margin-bottom: 1rem !important;\n}\n\n.mb-4 {\n  margin-bottom: 1.5rem !important;\n}\n\n.mb-5 {\n  margin-bottom: 3rem !important;\n}\n\n.mb-auto {\n  margin-bottom: auto !important;\n}\n\n.ms-0 {\n  margin-left: 0 !important;\n}\n\n.ms-1 {\n  margin-left: 0.25rem !important;\n}\n\n.ms-2 {\n  margin-left: 0.5rem !important;\n}\n\n.ms-3 {\n  margin-left: 1rem !important;\n}\n\n.ms-4 {\n  margin-left: 1.5rem !important;\n}\n\n.ms-5 {\n  margin-left: 3rem !important;\n}\n\n.ms-auto {\n  margin-left: auto !important;\n}\n\n.p-0 {\n  padding: 0 !important;\n}\n\n.p-1 {\n  padding: 0.25rem !important;\n}\n\n.p-2 {\n  padding: 0.5rem !important;\n}\n\n.p-3 {\n  padding: 1rem !important;\n}\n\n.p-4 {\n  padding: 1.5rem !important;\n}\n\n.p-5 {\n  padding: 3rem !important;\n}\n\n.px-0 {\n  padding-right: 0 !important;\n  padding-left: 0 !important;\n}\n\n.px-1 {\n  padding-right: 0.25rem !important;\n  padding-left: 0.25rem !important;\n}\n\n.px-2 {\n  padding-right: 0.5rem !important;\n  padding-left: 0.5rem !important;\n}\n\n.px-3 {\n  padding-right: 1rem !important;\n  padding-left: 1rem !important;\n}\n\n.px-4 {\n  padding-right: 1.5rem !important;\n  padding-left: 1.5rem !important;\n}\n\n.px-5 {\n  padding-right: 3rem !important;\n  padding-left: 3rem !important;\n}\n\n.py-0 {\n  padding-top: 0 !important;\n  padding-bottom: 0 !important;\n}\n\n.py-1 {\n  padding-top: 0.25rem !important;\n  padding-bottom: 0.25rem !important;\n}\n\n.py-2 {\n  padding-top: 0.5rem !important;\n  padding-bottom: 0.5rem !important;\n}\n\n.py-3 {\n  padding-top: 1rem !important;\n  padding-bottom: 1rem !important;\n}\n\n.py-4 {\n  padding-top: 1.5rem !important;\n  padding-bottom: 1.5rem !important;\n}\n\n.py-5 {\n  padding-top: 3rem !important;\n  padding-bottom: 3rem !important;\n}\n\n.pt-0 {\n  padding-top: 0 !important;\n}\n\n.pt-1 {\n  padding-top: 0.25rem !important;\n}\n\n.pt-2 {\n  padding-top: 0.5rem !important;\n}\n\n.pt-3 {\n  padding-top: 1rem !important;\n}\n\n.pt-4 {\n  padding-top: 1.5rem !important;\n}\n\n.pt-5 {\n  padding-top: 3rem !important;\n}\n\n.pe-0 {\n  padding-right: 0 !important;\n}\n\n.pe-1 {\n  padding-right: 0.25rem !important;\n}\n\n.pe-2 {\n  padding-right: 0.5rem !important;\n}\n\n.pe-3 {\n  padding-right: 1rem !important;\n}\n\n.pe-4 {\n  padding-right: 1.5rem !important;\n}\n\n.pe-5 {\n  padding-right: 3rem !important;\n}\n\n.pb-0 {\n  padding-bottom: 0 !important;\n}\n\n.pb-1 {\n  padding-bottom: 0.25rem !important;\n}\n\n.pb-2 {\n  padding-bottom: 0.5rem !important;\n}\n\n.pb-3 {\n  padding-bottom: 1rem !important;\n}\n\n.pb-4 {\n  padding-bottom: 1.5rem !important;\n}\n\n.pb-5 {\n  padding-bottom: 3rem !important;\n}\n\n.ps-0 {\n  padding-left: 0 !important;\n}\n\n.ps-1 {\n  padding-left: 0.25rem !important;\n}\n\n.ps-2 {\n  padding-left: 0.5rem !important;\n}\n\n.ps-3 {\n  padding-left: 1rem !important;\n}\n\n.ps-4 {\n  padding-left: 1.5rem !important;\n}\n\n.ps-5 {\n  padding-left: 3rem !important;\n}\n\n@media (min-width: 576px) {\n  .d-sm-inline {\n    display: inline !important;\n  }\n\n  .d-sm-inline-block {\n    display: inline-block !important;\n  }\n\n  .d-sm-block {\n    display: block !important;\n  }\n\n  .d-sm-grid {\n    display: grid !important;\n  }\n\n  .d-sm-table {\n    display: table !important;\n  }\n\n  .d-sm-table-row {\n    display: table-row !important;\n  }\n\n  .d-sm-table-cell {\n    display: table-cell !important;\n  }\n\n  .d-sm-flex {\n    display: flex !important;\n  }\n\n  .d-sm-inline-flex {\n    display: inline-flex !important;\n  }\n\n  .d-sm-none {\n    display: none !important;\n  }\n\n  .flex-sm-fill {\n    flex: 1 1 auto !important;\n  }\n\n  .flex-sm-row {\n    flex-direction: row !important;\n  }\n\n  .flex-sm-column {\n    flex-direction: column !important;\n  }\n\n  .flex-sm-row-reverse {\n    flex-direction: row-reverse !important;\n  }\n\n  .flex-sm-column-reverse {\n    flex-direction: column-reverse !important;\n  }\n\n  .flex-sm-grow-0 {\n    flex-grow: 0 !important;\n  }\n\n  .flex-sm-grow-1 {\n    flex-grow: 1 !important;\n  }\n\n  .flex-sm-shrink-0 {\n    flex-shrink: 0 !important;\n  }\n\n  .flex-sm-shrink-1 {\n    flex-shrink: 1 !important;\n  }\n\n  .flex-sm-wrap {\n    flex-wrap: wrap !important;\n  }\n\n  .flex-sm-nowrap {\n    flex-wrap: nowrap !important;\n  }\n\n  .flex-sm-wrap-reverse {\n    flex-wrap: wrap-reverse !important;\n  }\n\n  .justify-content-sm-start {\n    justify-content: flex-start !important;\n  }\n\n  .justify-content-sm-end {\n    justify-content: flex-end !important;\n  }\n\n  .justify-content-sm-center {\n    justify-content: center !important;\n  }\n\n  .justify-content-sm-between {\n    justify-content: space-between !important;\n  }\n\n  .justify-content-sm-around {\n    justify-content: space-around !important;\n  }\n\n  .justify-content-sm-evenly {\n    justify-content: space-evenly !important;\n  }\n\n  .align-items-sm-start {\n    align-items: flex-start !important;\n  }\n\n  .align-items-sm-end {\n    align-items: flex-end !important;\n  }\n\n  .align-items-sm-center {\n    align-items: center !important;\n  }\n\n  .align-items-sm-baseline {\n    align-items: baseline !important;\n  }\n\n  .align-items-sm-stretch {\n    align-items: stretch !important;\n  }\n\n  .align-content-sm-start {\n    align-content: flex-start !important;\n  }\n\n  .align-content-sm-end {\n    align-content: flex-end !important;\n  }\n\n  .align-content-sm-center {\n    align-content: center !important;\n  }\n\n  .align-content-sm-between {\n    align-content: space-between !important;\n  }\n\n  .align-content-sm-around {\n    align-content: space-around !important;\n  }\n\n  .align-content-sm-stretch {\n    align-content: stretch !important;\n  }\n\n  .align-self-sm-auto {\n    align-self: auto !important;\n  }\n\n  .align-self-sm-start {\n    align-self: flex-start !important;\n  }\n\n  .align-self-sm-end {\n    align-self: flex-end !important;\n  }\n\n  .align-self-sm-center {\n    align-self: center !important;\n  }\n\n  .align-self-sm-baseline {\n    align-self: baseline !important;\n  }\n\n  .align-self-sm-stretch {\n    align-self: stretch !important;\n  }\n\n  .order-sm-first {\n    order: -1 !important;\n  }\n\n  .order-sm-0 {\n    order: 0 !important;\n  }\n\n  .order-sm-1 {\n    order: 1 !important;\n  }\n\n  .order-sm-2 {\n    order: 2 !important;\n  }\n\n  .order-sm-3 {\n    order: 3 !important;\n  }\n\n  .order-sm-4 {\n    order: 4 !important;\n  }\n\n  .order-sm-5 {\n    order: 5 !important;\n  }\n\n  .order-sm-last {\n    order: 6 !important;\n  }\n\n  .m-sm-0 {\n    margin: 0 !important;\n  }\n\n  .m-sm-1 {\n    margin: 0.25rem !important;\n  }\n\n  .m-sm-2 {\n    margin: 0.5rem !important;\n  }\n\n  .m-sm-3 {\n    margin: 1rem !important;\n  }\n\n  .m-sm-4 {\n    margin: 1.5rem !important;\n  }\n\n  .m-sm-5 {\n    margin: 3rem !important;\n  }\n\n  .m-sm-auto {\n    margin: auto !important;\n  }\n\n  .mx-sm-0 {\n    margin-right: 0 !important;\n    margin-left: 0 !important;\n  }\n\n  .mx-sm-1 {\n    margin-right: 0.25rem !important;\n    margin-left: 0.25rem !important;\n  }\n\n  .mx-sm-2 {\n    margin-right: 0.5rem !important;\n    margin-left: 0.5rem !important;\n  }\n\n  .mx-sm-3 {\n    margin-right: 1rem !important;\n    margin-left: 1rem !important;\n  }\n\n  .mx-sm-4 {\n    margin-right: 1.5rem !important;\n    margin-left: 1.5rem !important;\n  }\n\n  .mx-sm-5 {\n    margin-right: 3rem !important;\n    margin-left: 3rem !important;\n  }\n\n  .mx-sm-auto {\n    margin-right: auto !important;\n    margin-left: auto !important;\n  }\n\n  .my-sm-0 {\n    margin-top: 0 !important;\n    margin-bottom: 0 !important;\n  }\n\n  .my-sm-1 {\n    margin-top: 0.25rem !important;\n    margin-bottom: 0.25rem !important;\n  }\n\n  .my-sm-2 {\n    margin-top: 0.5rem !important;\n    margin-bottom: 0.5rem !important;\n  }\n\n  .my-sm-3 {\n    margin-top: 1rem !important;\n    margin-bottom: 1rem !important;\n  }\n\n  .my-sm-4 {\n    margin-top: 1.5rem !important;\n    margin-bottom: 1.5rem !important;\n  }\n\n  .my-sm-5 {\n    margin-top: 3rem !important;\n    margin-bottom: 3rem !important;\n  }\n\n  .my-sm-auto {\n    margin-top: auto !important;\n    margin-bottom: auto !important;\n  }\n\n  .mt-sm-0 {\n    margin-top: 0 !important;\n  }\n\n  .mt-sm-1 {\n    margin-top: 0.25rem !important;\n  }\n\n  .mt-sm-2 {\n    margin-top: 0.5rem !important;\n  }\n\n  .mt-sm-3 {\n    margin-top: 1rem !important;\n  }\n\n  .mt-sm-4 {\n    margin-top: 1.5rem !important;\n  }\n\n  .mt-sm-5 {\n    margin-top: 3rem !important;\n  }\n\n  .mt-sm-auto {\n    margin-top: auto !important;\n  }\n\n  .me-sm-0 {\n    margin-right: 0 !important;\n  }\n\n  .me-sm-1 {\n    margin-right: 0.25rem !important;\n  }\n\n  .me-sm-2 {\n    margin-right: 0.5rem !important;\n  }\n\n  .me-sm-3 {\n    margin-right: 1rem !important;\n  }\n\n  .me-sm-4 {\n    margin-right: 1.5rem !important;\n  }\n\n  .me-sm-5 {\n    margin-right: 3rem !important;\n  }\n\n  .me-sm-auto {\n    margin-right: auto !important;\n  }\n\n  .mb-sm-0 {\n    margin-bottom: 0 !important;\n  }\n\n  .mb-sm-1 {\n    margin-bottom: 0.25rem !important;\n  }\n\n  .mb-sm-2 {\n    margin-bottom: 0.5rem !important;\n  }\n\n  .mb-sm-3 {\n    margin-bottom: 1rem !important;\n  }\n\n  .mb-sm-4 {\n    margin-bottom: 1.5rem !important;\n  }\n\n  .mb-sm-5 {\n    margin-bottom: 3rem !important;\n  }\n\n  .mb-sm-auto {\n    margin-bottom: auto !important;\n  }\n\n  .ms-sm-0 {\n    margin-left: 0 !important;\n  }\n\n  .ms-sm-1 {\n    margin-left: 0.25rem !important;\n  }\n\n  .ms-sm-2 {\n    margin-left: 0.5rem !important;\n  }\n\n  .ms-sm-3 {\n    margin-left: 1rem !important;\n  }\n\n  .ms-sm-4 {\n    margin-left: 1.5rem !important;\n  }\n\n  .ms-sm-5 {\n    margin-left: 3rem !important;\n  }\n\n  .ms-sm-auto {\n    margin-left: auto !important;\n  }\n\n  .p-sm-0 {\n    padding: 0 !important;\n  }\n\n  .p-sm-1 {\n    padding: 0.25rem !important;\n  }\n\n  .p-sm-2 {\n    padding: 0.5rem !important;\n  }\n\n  .p-sm-3 {\n    padding: 1rem !important;\n  }\n\n  .p-sm-4 {\n    padding: 1.5rem !important;\n  }\n\n  .p-sm-5 {\n    padding: 3rem !important;\n  }\n\n  .px-sm-0 {\n    padding-right: 0 !important;\n    padding-left: 0 !important;\n  }\n\n  .px-sm-1 {\n    padding-right: 0.25rem !important;\n    padding-left: 0.25rem !important;\n  }\n\n  .px-sm-2 {\n    padding-right: 0.5rem !important;\n    padding-left: 0.5rem !important;\n  }\n\n  .px-sm-3 {\n    padding-right: 1rem !important;\n    padding-left: 1rem !important;\n  }\n\n  .px-sm-4 {\n    padding-right: 1.5rem !important;\n    padding-left: 1.5rem !important;\n  }\n\n  .px-sm-5 {\n    padding-right: 3rem !important;\n    padding-left: 3rem !important;\n  }\n\n  .py-sm-0 {\n    padding-top: 0 !important;\n    padding-bottom: 0 !important;\n  }\n\n  .py-sm-1 {\n    padding-top: 0.25rem !important;\n    padding-bottom: 0.25rem !important;\n  }\n\n  .py-sm-2 {\n    padding-top: 0.5rem !important;\n    padding-bottom: 0.5rem !important;\n  }\n\n  .py-sm-3 {\n    padding-top: 1rem !important;\n    padding-bottom: 1rem !important;\n  }\n\n  .py-sm-4 {\n    padding-top: 1.5rem !important;\n    padding-bottom: 1.5rem !important;\n  }\n\n  .py-sm-5 {\n    padding-top: 3rem !important;\n    padding-bottom: 3rem !important;\n  }\n\n  .pt-sm-0 {\n    padding-top: 0 !important;\n  }\n\n  .pt-sm-1 {\n    padding-top: 0.25rem !important;\n  }\n\n  .pt-sm-2 {\n    padding-top: 0.5rem !important;\n  }\n\n  .pt-sm-3 {\n    padding-top: 1rem !important;\n  }\n\n  .pt-sm-4 {\n    padding-top: 1.5rem !important;\n  }\n\n  .pt-sm-5 {\n    padding-top: 3rem !important;\n  }\n\n  .pe-sm-0 {\n    padding-right: 0 !important;\n  }\n\n  .pe-sm-1 {\n    padding-right: 0.25rem !important;\n  }\n\n  .pe-sm-2 {\n    padding-right: 0.5rem !important;\n  }\n\n  .pe-sm-3 {\n    padding-right: 1rem !important;\n  }\n\n  .pe-sm-4 {\n    padding-right: 1.5rem !important;\n  }\n\n  .pe-sm-5 {\n    padding-right: 3rem !important;\n  }\n\n  .pb-sm-0 {\n    padding-bottom: 0 !important;\n  }\n\n  .pb-sm-1 {\n    padding-bottom: 0.25rem !important;\n  }\n\n  .pb-sm-2 {\n    padding-bottom: 0.5rem !important;\n  }\n\n  .pb-sm-3 {\n    padding-bottom: 1rem !important;\n  }\n\n  .pb-sm-4 {\n    padding-bottom: 1.5rem !important;\n  }\n\n  .pb-sm-5 {\n    padding-bottom: 3rem !important;\n  }\n\n  .ps-sm-0 {\n    padding-left: 0 !important;\n  }\n\n  .ps-sm-1 {\n    padding-left: 0.25rem !important;\n  }\n\n  .ps-sm-2 {\n    padding-left: 0.5rem !important;\n  }\n\n  .ps-sm-3 {\n    padding-left: 1rem !important;\n  }\n\n  .ps-sm-4 {\n    padding-left: 1.5rem !important;\n  }\n\n  .ps-sm-5 {\n    padding-left: 3rem !important;\n  }\n}\n@media (min-width: 768px) {\n  .d-md-inline {\n    display: inline !important;\n  }\n\n  .d-md-inline-block {\n    display: inline-block !important;\n  }\n\n  .d-md-block {\n    display: block !important;\n  }\n\n  .d-md-grid {\n    display: grid !important;\n  }\n\n  .d-md-table {\n    display: table !important;\n  }\n\n  .d-md-table-row {\n    display: table-row !important;\n  }\n\n  .d-md-table-cell {\n    display: table-cell !important;\n  }\n\n  .d-md-flex {\n    display: flex !important;\n  }\n\n  .d-md-inline-flex {\n    display: inline-flex !important;\n  }\n\n  .d-md-none {\n    display: none !important;\n  }\n\n  .flex-md-fill {\n    flex: 1 1 auto !important;\n  }\n\n  .flex-md-row {\n    flex-direction: row !important;\n  }\n\n  .flex-md-column {\n    flex-direction: column !important;\n  }\n\n  .flex-md-row-reverse {\n    flex-direction: row-reverse !important;\n  }\n\n  .flex-md-column-reverse {\n    flex-direction: column-reverse !important;\n  }\n\n  .flex-md-grow-0 {\n    flex-grow: 0 !important;\n  }\n\n  .flex-md-grow-1 {\n    flex-grow: 1 !important;\n  }\n\n  .flex-md-shrink-0 {\n    flex-shrink: 0 !important;\n  }\n\n  .flex-md-shrink-1 {\n    flex-shrink: 1 !important;\n  }\n\n  .flex-md-wrap {\n    flex-wrap: wrap !important;\n  }\n\n  .flex-md-nowrap {\n    flex-wrap: nowrap !important;\n  }\n\n  .flex-md-wrap-reverse {\n    flex-wrap: wrap-reverse !important;\n  }\n\n  .justify-content-md-start {\n    justify-content: flex-start !important;\n  }\n\n  .justify-content-md-end {\n    justify-content: flex-end !important;\n  }\n\n  .justify-content-md-center {\n    justify-content: center !important;\n  }\n\n  .justify-content-md-between {\n    justify-content: space-between !important;\n  }\n\n  .justify-content-md-around {\n    justify-content: space-around !important;\n  }\n\n  .justify-content-md-evenly {\n    justify-content: space-evenly !important;\n  }\n\n  .align-items-md-start {\n    align-items: flex-start !important;\n  }\n\n  .align-items-md-end {\n    align-items: flex-end !important;\n  }\n\n  .align-items-md-center {\n    align-items: center !important;\n  }\n\n  .align-items-md-baseline {\n    align-items: baseline !important;\n  }\n\n  .align-items-md-stretch {\n    align-items: stretch !important;\n  }\n\n  .align-content-md-start {\n    align-content: flex-start !important;\n  }\n\n  .align-content-md-end {\n    align-content: flex-end !important;\n  }\n\n  .align-content-md-center {\n    align-content: center !important;\n  }\n\n  .align-content-md-between {\n    align-content: space-between !important;\n  }\n\n  .align-content-md-around {\n    align-content: space-around !important;\n  }\n\n  .align-content-md-stretch {\n    align-content: stretch !important;\n  }\n\n  .align-self-md-auto {\n    align-self: auto !important;\n  }\n\n  .align-self-md-start {\n    align-self: flex-start !important;\n  }\n\n  .align-self-md-end {\n    align-self: flex-end !important;\n  }\n\n  .align-self-md-center {\n    align-self: center !important;\n  }\n\n  .align-self-md-baseline {\n    align-self: baseline !important;\n  }\n\n  .align-self-md-stretch {\n    align-self: stretch !important;\n  }\n\n  .order-md-first {\n    order: -1 !important;\n  }\n\n  .order-md-0 {\n    order: 0 !important;\n  }\n\n  .order-md-1 {\n    order: 1 !important;\n  }\n\n  .order-md-2 {\n    order: 2 !important;\n  }\n\n  .order-md-3 {\n    order: 3 !important;\n  }\n\n  .order-md-4 {\n    order: 4 !important;\n  }\n\n  .order-md-5 {\n    order: 5 !important;\n  }\n\n  .order-md-last {\n    order: 6 !important;\n  }\n\n  .m-md-0 {\n    margin: 0 !important;\n  }\n\n  .m-md-1 {\n    margin: 0.25rem !important;\n  }\n\n  .m-md-2 {\n    margin: 0.5rem !important;\n  }\n\n  .m-md-3 {\n    margin: 1rem !important;\n  }\n\n  .m-md-4 {\n    margin: 1.5rem !important;\n  }\n\n  .m-md-5 {\n    margin: 3rem !important;\n  }\n\n  .m-md-auto {\n    margin: auto !important;\n  }\n\n  .mx-md-0 {\n    margin-right: 0 !important;\n    margin-left: 0 !important;\n  }\n\n  .mx-md-1 {\n    margin-right: 0.25rem !important;\n    margin-left: 0.25rem !important;\n  }\n\n  .mx-md-2 {\n    margin-right: 0.5rem !important;\n    margin-left: 0.5rem !important;\n  }\n\n  .mx-md-3 {\n    margin-right: 1rem !important;\n    margin-left: 1rem !important;\n  }\n\n  .mx-md-4 {\n    margin-right: 1.5rem !important;\n    margin-left: 1.5rem !important;\n  }\n\n  .mx-md-5 {\n    margin-right: 3rem !important;\n    margin-left: 3rem !important;\n  }\n\n  .mx-md-auto {\n    margin-right: auto !important;\n    margin-left: auto !important;\n  }\n\n  .my-md-0 {\n    margin-top: 0 !important;\n    margin-bottom: 0 !important;\n  }\n\n  .my-md-1 {\n    margin-top: 0.25rem !important;\n    margin-bottom: 0.25rem !important;\n  }\n\n  .my-md-2 {\n    margin-top: 0.5rem !important;\n    margin-bottom: 0.5rem !important;\n  }\n\n  .my-md-3 {\n    margin-top: 1rem !important;\n    margin-bottom: 1rem !important;\n  }\n\n  .my-md-4 {\n    margin-top: 1.5rem !important;\n    margin-bottom: 1.5rem !important;\n  }\n\n  .my-md-5 {\n    margin-top: 3rem !important;\n    margin-bottom: 3rem !important;\n  }\n\n  .my-md-auto {\n    margin-top: auto !important;\n    margin-bottom: auto !important;\n  }\n\n  .mt-md-0 {\n    margin-top: 0 !important;\n  }\n\n  .mt-md-1 {\n    margin-top: 0.25rem !important;\n  }\n\n  .mt-md-2 {\n    margin-top: 0.5rem !important;\n  }\n\n  .mt-md-3 {\n    margin-top: 1rem !important;\n  }\n\n  .mt-md-4 {\n    margin-top: 1.5rem !important;\n  }\n\n  .mt-md-5 {\n    margin-top: 3rem !important;\n  }\n\n  .mt-md-auto {\n    margin-top: auto !important;\n  }\n\n  .me-md-0 {\n    margin-right: 0 !important;\n  }\n\n  .me-md-1 {\n    margin-right: 0.25rem !important;\n  }\n\n  .me-md-2 {\n    margin-right: 0.5rem !important;\n  }\n\n  .me-md-3 {\n    margin-right: 1rem !important;\n  }\n\n  .me-md-4 {\n    margin-right: 1.5rem !important;\n  }\n\n  .me-md-5 {\n    margin-right: 3rem !important;\n  }\n\n  .me-md-auto {\n    margin-right: auto !important;\n  }\n\n  .mb-md-0 {\n    margin-bottom: 0 !important;\n  }\n\n  .mb-md-1 {\n    margin-bottom: 0.25rem !important;\n  }\n\n  .mb-md-2 {\n    margin-bottom: 0.5rem !important;\n  }\n\n  .mb-md-3 {\n    margin-bottom: 1rem !important;\n  }\n\n  .mb-md-4 {\n    margin-bottom: 1.5rem !important;\n  }\n\n  .mb-md-5 {\n    margin-bottom: 3rem !important;\n  }\n\n  .mb-md-auto {\n    margin-bottom: auto !important;\n  }\n\n  .ms-md-0 {\n    margin-left: 0 !important;\n  }\n\n  .ms-md-1 {\n    margin-left: 0.25rem !important;\n  }\n\n  .ms-md-2 {\n    margin-left: 0.5rem !important;\n  }\n\n  .ms-md-3 {\n    margin-left: 1rem !important;\n  }\n\n  .ms-md-4 {\n    margin-left: 1.5rem !important;\n  }\n\n  .ms-md-5 {\n    margin-left: 3rem !important;\n  }\n\n  .ms-md-auto {\n    margin-left: auto !important;\n  }\n\n  .p-md-0 {\n    padding: 0 !important;\n  }\n\n  .p-md-1 {\n    padding: 0.25rem !important;\n  }\n\n  .p-md-2 {\n    padding: 0.5rem !important;\n  }\n\n  .p-md-3 {\n    padding: 1rem !important;\n  }\n\n  .p-md-4 {\n    padding: 1.5rem !important;\n  }\n\n  .p-md-5 {\n    padding: 3rem !important;\n  }\n\n  .px-md-0 {\n    padding-right: 0 !important;\n    padding-left: 0 !important;\n  }\n\n  .px-md-1 {\n    padding-right: 0.25rem !important;\n    padding-left: 0.25rem !important;\n  }\n\n  .px-md-2 {\n    padding-right: 0.5rem !important;\n    padding-left: 0.5rem !important;\n  }\n\n  .px-md-3 {\n    padding-right: 1rem !important;\n    padding-left: 1rem !important;\n  }\n\n  .px-md-4 {\n    padding-right: 1.5rem !important;\n    padding-left: 1.5rem !important;\n  }\n\n  .px-md-5 {\n    padding-right: 3rem !important;\n    padding-left: 3rem !important;\n  }\n\n  .py-md-0 {\n    padding-top: 0 !important;\n    padding-bottom: 0 !important;\n  }\n\n  .py-md-1 {\n    padding-top: 0.25rem !important;\n    padding-bottom: 0.25rem !important;\n  }\n\n  .py-md-2 {\n    padding-top: 0.5rem !important;\n    padding-bottom: 0.5rem !important;\n  }\n\n  .py-md-3 {\n    padding-top: 1rem !important;\n    padding-bottom: 1rem !important;\n  }\n\n  .py-md-4 {\n    padding-top: 1.5rem !important;\n    padding-bottom: 1.5rem !important;\n  }\n\n  .py-md-5 {\n    padding-top: 3rem !important;\n    padding-bottom: 3rem !important;\n  }\n\n  .pt-md-0 {\n    padding-top: 0 !important;\n  }\n\n  .pt-md-1 {\n    padding-top: 0.25rem !important;\n  }\n\n  .pt-md-2 {\n    padding-top: 0.5rem !important;\n  }\n\n  .pt-md-3 {\n    padding-top: 1rem !important;\n  }\n\n  .pt-md-4 {\n    padding-top: 1.5rem !important;\n  }\n\n  .pt-md-5 {\n    padding-top: 3rem !important;\n  }\n\n  .pe-md-0 {\n    padding-right: 0 !important;\n  }\n\n  .pe-md-1 {\n    padding-right: 0.25rem !important;\n  }\n\n  .pe-md-2 {\n    padding-right: 0.5rem !important;\n  }\n\n  .pe-md-3 {\n    padding-right: 1rem !important;\n  }\n\n  .pe-md-4 {\n    padding-right: 1.5rem !important;\n  }\n\n  .pe-md-5 {\n    padding-right: 3rem !important;\n  }\n\n  .pb-md-0 {\n    padding-bottom: 0 !important;\n  }\n\n  .pb-md-1 {\n    padding-bottom: 0.25rem !important;\n  }\n\n  .pb-md-2 {\n    padding-bottom: 0.5rem !important;\n  }\n\n  .pb-md-3 {\n    padding-bottom: 1rem !important;\n  }\n\n  .pb-md-4 {\n    padding-bottom: 1.5rem !important;\n  }\n\n  .pb-md-5 {\n    padding-bottom: 3rem !important;\n  }\n\n  .ps-md-0 {\n    padding-left: 0 !important;\n  }\n\n  .ps-md-1 {\n    padding-left: 0.25rem !important;\n  }\n\n  .ps-md-2 {\n    padding-left: 0.5rem !important;\n  }\n\n  .ps-md-3 {\n    padding-left: 1rem !important;\n  }\n\n  .ps-md-4 {\n    padding-left: 1.5rem !important;\n  }\n\n  .ps-md-5 {\n    padding-left: 3rem !important;\n  }\n}\n@media (min-width: 992px) {\n  .d-lg-inline {\n    display: inline !important;\n  }\n\n  .d-lg-inline-block {\n    display: inline-block !important;\n  }\n\n  .d-lg-block {\n    display: block !important;\n  }\n\n  .d-lg-grid {\n    display: grid !important;\n  }\n\n  .d-lg-table {\n    display: table !important;\n  }\n\n  .d-lg-table-row {\n    display: table-row !important;\n  }\n\n  .d-lg-table-cell {\n    display: table-cell !important;\n  }\n\n  .d-lg-flex {\n    display: flex !important;\n  }\n\n  .d-lg-inline-flex {\n    display: inline-flex !important;\n  }\n\n  .d-lg-none {\n    display: none !important;\n  }\n\n  .flex-lg-fill {\n    flex: 1 1 auto !important;\n  }\n\n  .flex-lg-row {\n    flex-direction: row !important;\n  }\n\n  .flex-lg-column {\n    flex-direction: column !important;\n  }\n\n  .flex-lg-row-reverse {\n    flex-direction: row-reverse !important;\n  }\n\n  .flex-lg-column-reverse {\n    flex-direction: column-reverse !important;\n  }\n\n  .flex-lg-grow-0 {\n    flex-grow: 0 !important;\n  }\n\n  .flex-lg-grow-1 {\n    flex-grow: 1 !important;\n  }\n\n  .flex-lg-shrink-0 {\n    flex-shrink: 0 !important;\n  }\n\n  .flex-lg-shrink-1 {\n    flex-shrink: 1 !important;\n  }\n\n  .flex-lg-wrap {\n    flex-wrap: wrap !important;\n  }\n\n  .flex-lg-nowrap {\n    flex-wrap: nowrap !important;\n  }\n\n  .flex-lg-wrap-reverse {\n    flex-wrap: wrap-reverse !important;\n  }\n\n  .justify-content-lg-start {\n    justify-content: flex-start !important;\n  }\n\n  .justify-content-lg-end {\n    justify-content: flex-end !important;\n  }\n\n  .justify-content-lg-center {\n    justify-content: center !important;\n  }\n\n  .justify-content-lg-between {\n    justify-content: space-between !important;\n  }\n\n  .justify-content-lg-around {\n    justify-content: space-around !important;\n  }\n\n  .justify-content-lg-evenly {\n    justify-content: space-evenly !important;\n  }\n\n  .align-items-lg-start {\n    align-items: flex-start !important;\n  }\n\n  .align-items-lg-end {\n    align-items: flex-end !important;\n  }\n\n  .align-items-lg-center {\n    align-items: center !important;\n  }\n\n  .align-items-lg-baseline {\n    align-items: baseline !important;\n  }\n\n  .align-items-lg-stretch {\n    align-items: stretch !important;\n  }\n\n  .align-content-lg-start {\n    align-content: flex-start !important;\n  }\n\n  .align-content-lg-end {\n    align-content: flex-end !important;\n  }\n\n  .align-content-lg-center {\n    align-content: center !important;\n  }\n\n  .align-content-lg-between {\n    align-content: space-between !important;\n  }\n\n  .align-content-lg-around {\n    align-content: space-around !important;\n  }\n\n  .align-content-lg-stretch {\n    align-content: stretch !important;\n  }\n\n  .align-self-lg-auto {\n    align-self: auto !important;\n  }\n\n  .align-self-lg-start {\n    align-self: flex-start !important;\n  }\n\n  .align-self-lg-end {\n    align-self: flex-end !important;\n  }\n\n  .align-self-lg-center {\n    align-self: center !important;\n  }\n\n  .align-self-lg-baseline {\n    align-self: baseline !important;\n  }\n\n  .align-self-lg-stretch {\n    align-self: stretch !important;\n  }\n\n  .order-lg-first {\n    order: -1 !important;\n  }\n\n  .order-lg-0 {\n    order: 0 !important;\n  }\n\n  .order-lg-1 {\n    order: 1 !important;\n  }\n\n  .order-lg-2 {\n    order: 2 !important;\n  }\n\n  .order-lg-3 {\n    order: 3 !important;\n  }\n\n  .order-lg-4 {\n    order: 4 !important;\n  }\n\n  .order-lg-5 {\n    order: 5 !important;\n  }\n\n  .order-lg-last {\n    order: 6 !important;\n  }\n\n  .m-lg-0 {\n    margin: 0 !important;\n  }\n\n  .m-lg-1 {\n    margin: 0.25rem !important;\n  }\n\n  .m-lg-2 {\n    margin: 0.5rem !important;\n  }\n\n  .m-lg-3 {\n    margin: 1rem !important;\n  }\n\n  .m-lg-4 {\n    margin: 1.5rem !important;\n  }\n\n  .m-lg-5 {\n    margin: 3rem !important;\n  }\n\n  .m-lg-auto {\n    margin: auto !important;\n  }\n\n  .mx-lg-0 {\n    margin-right: 0 !important;\n    margin-left: 0 !important;\n  }\n\n  .mx-lg-1 {\n    margin-right: 0.25rem !important;\n    margin-left: 0.25rem !important;\n  }\n\n  .mx-lg-2 {\n    margin-right: 0.5rem !important;\n    margin-left: 0.5rem !important;\n  }\n\n  .mx-lg-3 {\n    margin-right: 1rem !important;\n    margin-left: 1rem !important;\n  }\n\n  .mx-lg-4 {\n    margin-right: 1.5rem !important;\n    margin-left: 1.5rem !important;\n  }\n\n  .mx-lg-5 {\n    margin-right: 3rem !important;\n    margin-left: 3rem !important;\n  }\n\n  .mx-lg-auto {\n    margin-right: auto !important;\n    margin-left: auto !important;\n  }\n\n  .my-lg-0 {\n    margin-top: 0 !important;\n    margin-bottom: 0 !important;\n  }\n\n  .my-lg-1 {\n    margin-top: 0.25rem !important;\n    margin-bottom: 0.25rem !important;\n  }\n\n  .my-lg-2 {\n    margin-top: 0.5rem !important;\n    margin-bottom: 0.5rem !important;\n  }\n\n  .my-lg-3 {\n    margin-top: 1rem !important;\n    margin-bottom: 1rem !important;\n  }\n\n  .my-lg-4 {\n    margin-top: 1.5rem !important;\n    margin-bottom: 1.5rem !important;\n  }\n\n  .my-lg-5 {\n    margin-top: 3rem !important;\n    margin-bottom: 3rem !important;\n  }\n\n  .my-lg-auto {\n    margin-top: auto !important;\n    margin-bottom: auto !important;\n  }\n\n  .mt-lg-0 {\n    margin-top: 0 !important;\n  }\n\n  .mt-lg-1 {\n    margin-top: 0.25rem !important;\n  }\n\n  .mt-lg-2 {\n    margin-top: 0.5rem !important;\n  }\n\n  .mt-lg-3 {\n    margin-top: 1rem !important;\n  }\n\n  .mt-lg-4 {\n    margin-top: 1.5rem !important;\n  }\n\n  .mt-lg-5 {\n    margin-top: 3rem !important;\n  }\n\n  .mt-lg-auto {\n    margin-top: auto !important;\n  }\n\n  .me-lg-0 {\n    margin-right: 0 !important;\n  }\n\n  .me-lg-1 {\n    margin-right: 0.25rem !important;\n  }\n\n  .me-lg-2 {\n    margin-right: 0.5rem !important;\n  }\n\n  .me-lg-3 {\n    margin-right: 1rem !important;\n  }\n\n  .me-lg-4 {\n    margin-right: 1.5rem !important;\n  }\n\n  .me-lg-5 {\n    margin-right: 3rem !important;\n  }\n\n  .me-lg-auto {\n    margin-right: auto !important;\n  }\n\n  .mb-lg-0 {\n    margin-bottom: 0 !important;\n  }\n\n  .mb-lg-1 {\n    margin-bottom: 0.25rem !important;\n  }\n\n  .mb-lg-2 {\n    margin-bottom: 0.5rem !important;\n  }\n\n  .mb-lg-3 {\n    margin-bottom: 1rem !important;\n  }\n\n  .mb-lg-4 {\n    margin-bottom: 1.5rem !important;\n  }\n\n  .mb-lg-5 {\n    margin-bottom: 3rem !important;\n  }\n\n  .mb-lg-auto {\n    margin-bottom: auto !important;\n  }\n\n  .ms-lg-0 {\n    margin-left: 0 !important;\n  }\n\n  .ms-lg-1 {\n    margin-left: 0.25rem !important;\n  }\n\n  .ms-lg-2 {\n    margin-left: 0.5rem !important;\n  }\n\n  .ms-lg-3 {\n    margin-left: 1rem !important;\n  }\n\n  .ms-lg-4 {\n    margin-left: 1.5rem !important;\n  }\n\n  .ms-lg-5 {\n    margin-left: 3rem !important;\n  }\n\n  .ms-lg-auto {\n    margin-left: auto !important;\n  }\n\n  .p-lg-0 {\n    padding: 0 !important;\n  }\n\n  .p-lg-1 {\n    padding: 0.25rem !important;\n  }\n\n  .p-lg-2 {\n    padding: 0.5rem !important;\n  }\n\n  .p-lg-3 {\n    padding: 1rem !important;\n  }\n\n  .p-lg-4 {\n    padding: 1.5rem !important;\n  }\n\n  .p-lg-5 {\n    padding: 3rem !important;\n  }\n\n  .px-lg-0 {\n    padding-right: 0 !important;\n    padding-left: 0 !important;\n  }\n\n  .px-lg-1 {\n    padding-right: 0.25rem !important;\n    padding-left: 0.25rem !important;\n  }\n\n  .px-lg-2 {\n    padding-right: 0.5rem !important;\n    padding-left: 0.5rem !important;\n  }\n\n  .px-lg-3 {\n    padding-right: 1rem !important;\n    padding-left: 1rem !important;\n  }\n\n  .px-lg-4 {\n    padding-right: 1.5rem !important;\n    padding-left: 1.5rem !important;\n  }\n\n  .px-lg-5 {\n    padding-right: 3rem !important;\n    padding-left: 3rem !important;\n  }\n\n  .py-lg-0 {\n    padding-top: 0 !important;\n    padding-bottom: 0 !important;\n  }\n\n  .py-lg-1 {\n    padding-top: 0.25rem !important;\n    padding-bottom: 0.25rem !important;\n  }\n\n  .py-lg-2 {\n    padding-top: 0.5rem !important;\n    padding-bottom: 0.5rem !important;\n  }\n\n  .py-lg-3 {\n    padding-top: 1rem !important;\n    padding-bottom: 1rem !important;\n  }\n\n  .py-lg-4 {\n    padding-top: 1.5rem !important;\n    padding-bottom: 1.5rem !important;\n  }\n\n  .py-lg-5 {\n    padding-top: 3rem !important;\n    padding-bottom: 3rem !important;\n  }\n\n  .pt-lg-0 {\n    padding-top: 0 !important;\n  }\n\n  .pt-lg-1 {\n    padding-top: 0.25rem !important;\n  }\n\n  .pt-lg-2 {\n    padding-top: 0.5rem !important;\n  }\n\n  .pt-lg-3 {\n    padding-top: 1rem !important;\n  }\n\n  .pt-lg-4 {\n    padding-top: 1.5rem !important;\n  }\n\n  .pt-lg-5 {\n    padding-top: 3rem !important;\n  }\n\n  .pe-lg-0 {\n    padding-right: 0 !important;\n  }\n\n  .pe-lg-1 {\n    padding-right: 0.25rem !important;\n  }\n\n  .pe-lg-2 {\n    padding-right: 0.5rem !important;\n  }\n\n  .pe-lg-3 {\n    padding-right: 1rem !important;\n  }\n\n  .pe-lg-4 {\n    padding-right: 1.5rem !important;\n  }\n\n  .pe-lg-5 {\n    padding-right: 3rem !important;\n  }\n\n  .pb-lg-0 {\n    padding-bottom: 0 !important;\n  }\n\n  .pb-lg-1 {\n    padding-bottom: 0.25rem !important;\n  }\n\n  .pb-lg-2 {\n    padding-bottom: 0.5rem !important;\n  }\n\n  .pb-lg-3 {\n    padding-bottom: 1rem !important;\n  }\n\n  .pb-lg-4 {\n    padding-bottom: 1.5rem !important;\n  }\n\n  .pb-lg-5 {\n    padding-bottom: 3rem !important;\n  }\n\n  .ps-lg-0 {\n    padding-left: 0 !important;\n  }\n\n  .ps-lg-1 {\n    padding-left: 0.25rem !important;\n  }\n\n  .ps-lg-2 {\n    padding-left: 0.5rem !important;\n  }\n\n  .ps-lg-3 {\n    padding-left: 1rem !important;\n  }\n\n  .ps-lg-4 {\n    padding-left: 1.5rem !important;\n  }\n\n  .ps-lg-5 {\n    padding-left: 3rem !important;\n  }\n}\n@media (min-width: 1200px) {\n  .d-xl-inline {\n    display: inline !important;\n  }\n\n  .d-xl-inline-block {\n    display: inline-block !important;\n  }\n\n  .d-xl-block {\n    display: block !important;\n  }\n\n  .d-xl-grid {\n    display: grid !important;\n  }\n\n  .d-xl-table {\n    display: table !important;\n  }\n\n  .d-xl-table-row {\n    display: table-row !important;\n  }\n\n  .d-xl-table-cell {\n    display: table-cell !important;\n  }\n\n  .d-xl-flex {\n    display: flex !important;\n  }\n\n  .d-xl-inline-flex {\n    display: inline-flex !important;\n  }\n\n  .d-xl-none {\n    display: none !important;\n  }\n\n  .flex-xl-fill {\n    flex: 1 1 auto !important;\n  }\n\n  .flex-xl-row {\n    flex-direction: row !important;\n  }\n\n  .flex-xl-column {\n    flex-direction: column !important;\n  }\n\n  .flex-xl-row-reverse {\n    flex-direction: row-reverse !important;\n  }\n\n  .flex-xl-column-reverse {\n    flex-direction: column-reverse !important;\n  }\n\n  .flex-xl-grow-0 {\n    flex-grow: 0 !important;\n  }\n\n  .flex-xl-grow-1 {\n    flex-grow: 1 !important;\n  }\n\n  .flex-xl-shrink-0 {\n    flex-shrink: 0 !important;\n  }\n\n  .flex-xl-shrink-1 {\n    flex-shrink: 1 !important;\n  }\n\n  .flex-xl-wrap {\n    flex-wrap: wrap !important;\n  }\n\n  .flex-xl-nowrap {\n    flex-wrap: nowrap !important;\n  }\n\n  .flex-xl-wrap-reverse {\n    flex-wrap: wrap-reverse !important;\n  }\n\n  .justify-content-xl-start {\n    justify-content: flex-start !important;\n  }\n\n  .justify-content-xl-end {\n    justify-content: flex-end !important;\n  }\n\n  .justify-content-xl-center {\n    justify-content: center !important;\n  }\n\n  .justify-content-xl-between {\n    justify-content: space-between !important;\n  }\n\n  .justify-content-xl-around {\n    justify-content: space-around !important;\n  }\n\n  .justify-content-xl-evenly {\n    justify-content: space-evenly !important;\n  }\n\n  .align-items-xl-start {\n    align-items: flex-start !important;\n  }\n\n  .align-items-xl-end {\n    align-items: flex-end !important;\n  }\n\n  .align-items-xl-center {\n    align-items: center !important;\n  }\n\n  .align-items-xl-baseline {\n    align-items: baseline !important;\n  }\n\n  .align-items-xl-stretch {\n    align-items: stretch !important;\n  }\n\n  .align-content-xl-start {\n    align-content: flex-start !important;\n  }\n\n  .align-content-xl-end {\n    align-content: flex-end !important;\n  }\n\n  .align-content-xl-center {\n    align-content: center !important;\n  }\n\n  .align-content-xl-between {\n    align-content: space-between !important;\n  }\n\n  .align-content-xl-around {\n    align-content: space-around !important;\n  }\n\n  .align-content-xl-stretch {\n    align-content: stretch !important;\n  }\n\n  .align-self-xl-auto {\n    align-self: auto !important;\n  }\n\n  .align-self-xl-start {\n    align-self: flex-start !important;\n  }\n\n  .align-self-xl-end {\n    align-self: flex-end !important;\n  }\n\n  .align-self-xl-center {\n    align-self: center !important;\n  }\n\n  .align-self-xl-baseline {\n    align-self: baseline !important;\n  }\n\n  .align-self-xl-stretch {\n    align-self: stretch !important;\n  }\n\n  .order-xl-first {\n    order: -1 !important;\n  }\n\n  .order-xl-0 {\n    order: 0 !important;\n  }\n\n  .order-xl-1 {\n    order: 1 !important;\n  }\n\n  .order-xl-2 {\n    order: 2 !important;\n  }\n\n  .order-xl-3 {\n    order: 3 !important;\n  }\n\n  .order-xl-4 {\n    order: 4 !important;\n  }\n\n  .order-xl-5 {\n    order: 5 !important;\n  }\n\n  .order-xl-last {\n    order: 6 !important;\n  }\n\n  .m-xl-0 {\n    margin: 0 !important;\n  }\n\n  .m-xl-1 {\n    margin: 0.25rem !important;\n  }\n\n  .m-xl-2 {\n    margin: 0.5rem !important;\n  }\n\n  .m-xl-3 {\n    margin: 1rem !important;\n  }\n\n  .m-xl-4 {\n    margin: 1.5rem !important;\n  }\n\n  .m-xl-5 {\n    margin: 3rem !important;\n  }\n\n  .m-xl-auto {\n    margin: auto !important;\n  }\n\n  .mx-xl-0 {\n    margin-right: 0 !important;\n    margin-left: 0 !important;\n  }\n\n  .mx-xl-1 {\n    margin-right: 0.25rem !important;\n    margin-left: 0.25rem !important;\n  }\n\n  .mx-xl-2 {\n    margin-right: 0.5rem !important;\n    margin-left: 0.5rem !important;\n  }\n\n  .mx-xl-3 {\n    margin-right: 1rem !important;\n    margin-left: 1rem !important;\n  }\n\n  .mx-xl-4 {\n    margin-right: 1.5rem !important;\n    margin-left: 1.5rem !important;\n  }\n\n  .mx-xl-5 {\n    margin-right: 3rem !important;\n    margin-left: 3rem !important;\n  }\n\n  .mx-xl-auto {\n    margin-right: auto !important;\n    margin-left: auto !important;\n  }\n\n  .my-xl-0 {\n    margin-top: 0 !important;\n    margin-bottom: 0 !important;\n  }\n\n  .my-xl-1 {\n    margin-top: 0.25rem !important;\n    margin-bottom: 0.25rem !important;\n  }\n\n  .my-xl-2 {\n    margin-top: 0.5rem !important;\n    margin-bottom: 0.5rem !important;\n  }\n\n  .my-xl-3 {\n    margin-top: 1rem !important;\n    margin-bottom: 1rem !important;\n  }\n\n  .my-xl-4 {\n    margin-top: 1.5rem !important;\n    margin-bottom: 1.5rem !important;\n  }\n\n  .my-xl-5 {\n    margin-top: 3rem !important;\n    margin-bottom: 3rem !important;\n  }\n\n  .my-xl-auto {\n    margin-top: auto !important;\n    margin-bottom: auto !important;\n  }\n\n  .mt-xl-0 {\n    margin-top: 0 !important;\n  }\n\n  .mt-xl-1 {\n    margin-top: 0.25rem !important;\n  }\n\n  .mt-xl-2 {\n    margin-top: 0.5rem !important;\n  }\n\n  .mt-xl-3 {\n    margin-top: 1rem !important;\n  }\n\n  .mt-xl-4 {\n    margin-top: 1.5rem !important;\n  }\n\n  .mt-xl-5 {\n    margin-top: 3rem !important;\n  }\n\n  .mt-xl-auto {\n    margin-top: auto !important;\n  }\n\n  .me-xl-0 {\n    margin-right: 0 !important;\n  }\n\n  .me-xl-1 {\n    margin-right: 0.25rem !important;\n  }\n\n  .me-xl-2 {\n    margin-right: 0.5rem !important;\n  }\n\n  .me-xl-3 {\n    margin-right: 1rem !important;\n  }\n\n  .me-xl-4 {\n    margin-right: 1.5rem !important;\n  }\n\n  .me-xl-5 {\n    margin-right: 3rem !important;\n  }\n\n  .me-xl-auto {\n    margin-right: auto !important;\n  }\n\n  .mb-xl-0 {\n    margin-bottom: 0 !important;\n  }\n\n  .mb-xl-1 {\n    margin-bottom: 0.25rem !important;\n  }\n\n  .mb-xl-2 {\n    margin-bottom: 0.5rem !important;\n  }\n\n  .mb-xl-3 {\n    margin-bottom: 1rem !important;\n  }\n\n  .mb-xl-4 {\n    margin-bottom: 1.5rem !important;\n  }\n\n  .mb-xl-5 {\n    margin-bottom: 3rem !important;\n  }\n\n  .mb-xl-auto {\n    margin-bottom: auto !important;\n  }\n\n  .ms-xl-0 {\n    margin-left: 0 !important;\n  }\n\n  .ms-xl-1 {\n    margin-left: 0.25rem !important;\n  }\n\n  .ms-xl-2 {\n    margin-left: 0.5rem !important;\n  }\n\n  .ms-xl-3 {\n    margin-left: 1rem !important;\n  }\n\n  .ms-xl-4 {\n    margin-left: 1.5rem !important;\n  }\n\n  .ms-xl-5 {\n    margin-left: 3rem !important;\n  }\n\n  .ms-xl-auto {\n    margin-left: auto !important;\n  }\n\n  .p-xl-0 {\n    padding: 0 !important;\n  }\n\n  .p-xl-1 {\n    padding: 0.25rem !important;\n  }\n\n  .p-xl-2 {\n    padding: 0.5rem !important;\n  }\n\n  .p-xl-3 {\n    padding: 1rem !important;\n  }\n\n  .p-xl-4 {\n    padding: 1.5rem !important;\n  }\n\n  .p-xl-5 {\n    padding: 3rem !important;\n  }\n\n  .px-xl-0 {\n    padding-right: 0 !important;\n    padding-left: 0 !important;\n  }\n\n  .px-xl-1 {\n    padding-right: 0.25rem !important;\n    padding-left: 0.25rem !important;\n  }\n\n  .px-xl-2 {\n    padding-right: 0.5rem !important;\n    padding-left: 0.5rem !important;\n  }\n\n  .px-xl-3 {\n    padding-right: 1rem !important;\n    padding-left: 1rem !important;\n  }\n\n  .px-xl-4 {\n    padding-right: 1.5rem !important;\n    padding-left: 1.5rem !important;\n  }\n\n  .px-xl-5 {\n    padding-right: 3rem !important;\n    padding-left: 3rem !important;\n  }\n\n  .py-xl-0 {\n    padding-top: 0 !important;\n    padding-bottom: 0 !important;\n  }\n\n  .py-xl-1 {\n    padding-top: 0.25rem !important;\n    padding-bottom: 0.25rem !important;\n  }\n\n  .py-xl-2 {\n    padding-top: 0.5rem !important;\n    padding-bottom: 0.5rem !important;\n  }\n\n  .py-xl-3 {\n    padding-top: 1rem !important;\n    padding-bottom: 1rem !important;\n  }\n\n  .py-xl-4 {\n    padding-top: 1.5rem !important;\n    padding-bottom: 1.5rem !important;\n  }\n\n  .py-xl-5 {\n    padding-top: 3rem !important;\n    padding-bottom: 3rem !important;\n  }\n\n  .pt-xl-0 {\n    padding-top: 0 !important;\n  }\n\n  .pt-xl-1 {\n    padding-top: 0.25rem !important;\n  }\n\n  .pt-xl-2 {\n    padding-top: 0.5rem !important;\n  }\n\n  .pt-xl-3 {\n    padding-top: 1rem !important;\n  }\n\n  .pt-xl-4 {\n    padding-top: 1.5rem !important;\n  }\n\n  .pt-xl-5 {\n    padding-top: 3rem !important;\n  }\n\n  .pe-xl-0 {\n    padding-right: 0 !important;\n  }\n\n  .pe-xl-1 {\n    padding-right: 0.25rem !important;\n  }\n\n  .pe-xl-2 {\n    padding-right: 0.5rem !important;\n  }\n\n  .pe-xl-3 {\n    padding-right: 1rem !important;\n  }\n\n  .pe-xl-4 {\n    padding-right: 1.5rem !important;\n  }\n\n  .pe-xl-5 {\n    padding-right: 3rem !important;\n  }\n\n  .pb-xl-0 {\n    padding-bottom: 0 !important;\n  }\n\n  .pb-xl-1 {\n    padding-bottom: 0.25rem !important;\n  }\n\n  .pb-xl-2 {\n    padding-bottom: 0.5rem !important;\n  }\n\n  .pb-xl-3 {\n    padding-bottom: 1rem !important;\n  }\n\n  .pb-xl-4 {\n    padding-bottom: 1.5rem !important;\n  }\n\n  .pb-xl-5 {\n    padding-bottom: 3rem !important;\n  }\n\n  .ps-xl-0 {\n    padding-left: 0 !important;\n  }\n\n  .ps-xl-1 {\n    padding-left: 0.25rem !important;\n  }\n\n  .ps-xl-2 {\n    padding-left: 0.5rem !important;\n  }\n\n  .ps-xl-3 {\n    padding-left: 1rem !important;\n  }\n\n  .ps-xl-4 {\n    padding-left: 1.5rem !important;\n  }\n\n  .ps-xl-5 {\n    padding-left: 3rem !important;\n  }\n}\n@media (min-width: 1400px) {\n  .d-xxl-inline {\n    display: inline !important;\n  }\n\n  .d-xxl-inline-block {\n    display: inline-block !important;\n  }\n\n  .d-xxl-block {\n    display: block !important;\n  }\n\n  .d-xxl-grid {\n    display: grid !important;\n  }\n\n  .d-xxl-table {\n    display: table !important;\n  }\n\n  .d-xxl-table-row {\n    display: table-row !important;\n  }\n\n  .d-xxl-table-cell {\n    display: table-cell !important;\n  }\n\n  .d-xxl-flex {\n    display: flex !important;\n  }\n\n  .d-xxl-inline-flex {\n    display: inline-flex !important;\n  }\n\n  .d-xxl-none {\n    display: none !important;\n  }\n\n  .flex-xxl-fill {\n    flex: 1 1 auto !important;\n  }\n\n  .flex-xxl-row {\n    flex-direction: row !important;\n  }\n\n  .flex-xxl-column {\n    flex-direction: column !important;\n  }\n\n  .flex-xxl-row-reverse {\n    flex-direction: row-reverse !important;\n  }\n\n  .flex-xxl-column-reverse {\n    flex-direction: column-reverse !important;\n  }\n\n  .flex-xxl-grow-0 {\n    flex-grow: 0 !important;\n  }\n\n  .flex-xxl-grow-1 {\n    flex-grow: 1 !important;\n  }\n\n  .flex-xxl-shrink-0 {\n    flex-shrink: 0 !important;\n  }\n\n  .flex-xxl-shrink-1 {\n    flex-shrink: 1 !important;\n  }\n\n  .flex-xxl-wrap {\n    flex-wrap: wrap !important;\n  }\n\n  .flex-xxl-nowrap {\n    flex-wrap: nowrap !important;\n  }\n\n  .flex-xxl-wrap-reverse {\n    flex-wrap: wrap-reverse !important;\n  }\n\n  .justify-content-xxl-start {\n    justify-content: flex-start !important;\n  }\n\n  .justify-content-xxl-end {\n    justify-content: flex-end !important;\n  }\n\n  .justify-content-xxl-center {\n    justify-content: center !important;\n  }\n\n  .justify-content-xxl-between {\n    justify-content: space-between !important;\n  }\n\n  .justify-content-xxl-around {\n    justify-content: space-around !important;\n  }\n\n  .justify-content-xxl-evenly {\n    justify-content: space-evenly !important;\n  }\n\n  .align-items-xxl-start {\n    align-items: flex-start !important;\n  }\n\n  .align-items-xxl-end {\n    align-items: flex-end !important;\n  }\n\n  .align-items-xxl-center {\n    align-items: center !important;\n  }\n\n  .align-items-xxl-baseline {\n    align-items: baseline !important;\n  }\n\n  .align-items-xxl-stretch {\n    align-items: stretch !important;\n  }\n\n  .align-content-xxl-start {\n    align-content: flex-start !important;\n  }\n\n  .align-content-xxl-end {\n    align-content: flex-end !important;\n  }\n\n  .align-content-xxl-center {\n    align-content: center !important;\n  }\n\n  .align-content-xxl-between {\n    align-content: space-between !important;\n  }\n\n  .align-content-xxl-around {\n    align-content: space-around !important;\n  }\n\n  .align-content-xxl-stretch {\n    align-content: stretch !important;\n  }\n\n  .align-self-xxl-auto {\n    align-self: auto !important;\n  }\n\n  .align-self-xxl-start {\n    align-self: flex-start !important;\n  }\n\n  .align-self-xxl-end {\n    align-self: flex-end !important;\n  }\n\n  .align-self-xxl-center {\n    align-self: center !important;\n  }\n\n  .align-self-xxl-baseline {\n    align-self: baseline !important;\n  }\n\n  .align-self-xxl-stretch {\n    align-self: stretch !important;\n  }\n\n  .order-xxl-first {\n    order: -1 !important;\n  }\n\n  .order-xxl-0 {\n    order: 0 !important;\n  }\n\n  .order-xxl-1 {\n    order: 1 !important;\n  }\n\n  .order-xxl-2 {\n    order: 2 !important;\n  }\n\n  .order-xxl-3 {\n    order: 3 !important;\n  }\n\n  .order-xxl-4 {\n    order: 4 !important;\n  }\n\n  .order-xxl-5 {\n    order: 5 !important;\n  }\n\n  .order-xxl-last {\n    order: 6 !important;\n  }\n\n  .m-xxl-0 {\n    margin: 0 !important;\n  }\n\n  .m-xxl-1 {\n    margin: 0.25rem !important;\n  }\n\n  .m-xxl-2 {\n    margin: 0.5rem !important;\n  }\n\n  .m-xxl-3 {\n    margin: 1rem !important;\n  }\n\n  .m-xxl-4 {\n    margin: 1.5rem !important;\n  }\n\n  .m-xxl-5 {\n    margin: 3rem !important;\n  }\n\n  .m-xxl-auto {\n    margin: auto !important;\n  }\n\n  .mx-xxl-0 {\n    margin-right: 0 !important;\n    margin-left: 0 !important;\n  }\n\n  .mx-xxl-1 {\n    margin-right: 0.25rem !important;\n    margin-left: 0.25rem !important;\n  }\n\n  .mx-xxl-2 {\n    margin-right: 0.5rem !important;\n    margin-left: 0.5rem !important;\n  }\n\n  .mx-xxl-3 {\n    margin-right: 1rem !important;\n    margin-left: 1rem !important;\n  }\n\n  .mx-xxl-4 {\n    margin-right: 1.5rem !important;\n    margin-left: 1.5rem !important;\n  }\n\n  .mx-xxl-5 {\n    margin-right: 3rem !important;\n    margin-left: 3rem !important;\n  }\n\n  .mx-xxl-auto {\n    margin-right: auto !important;\n    margin-left: auto !important;\n  }\n\n  .my-xxl-0 {\n    margin-top: 0 !important;\n    margin-bottom: 0 !important;\n  }\n\n  .my-xxl-1 {\n    margin-top: 0.25rem !important;\n    margin-bottom: 0.25rem !important;\n  }\n\n  .my-xxl-2 {\n    margin-top: 0.5rem !important;\n    margin-bottom: 0.5rem !important;\n  }\n\n  .my-xxl-3 {\n    margin-top: 1rem !important;\n    margin-bottom: 1rem !important;\n  }\n\n  .my-xxl-4 {\n    margin-top: 1.5rem !important;\n    margin-bottom: 1.5rem !important;\n  }\n\n  .my-xxl-5 {\n    margin-top: 3rem !important;\n    margin-bottom: 3rem !important;\n  }\n\n  .my-xxl-auto {\n    margin-top: auto !important;\n    margin-bottom: auto !important;\n  }\n\n  .mt-xxl-0 {\n    margin-top: 0 !important;\n  }\n\n  .mt-xxl-1 {\n    margin-top: 0.25rem !important;\n  }\n\n  .mt-xxl-2 {\n    margin-top: 0.5rem !important;\n  }\n\n  .mt-xxl-3 {\n    margin-top: 1rem !important;\n  }\n\n  .mt-xxl-4 {\n    margin-top: 1.5rem !important;\n  }\n\n  .mt-xxl-5 {\n    margin-top: 3rem !important;\n  }\n\n  .mt-xxl-auto {\n    margin-top: auto !important;\n  }\n\n  .me-xxl-0 {\n    margin-right: 0 !important;\n  }\n\n  .me-xxl-1 {\n    margin-right: 0.25rem !important;\n  }\n\n  .me-xxl-2 {\n    margin-right: 0.5rem !important;\n  }\n\n  .me-xxl-3 {\n    margin-right: 1rem !important;\n  }\n\n  .me-xxl-4 {\n    margin-right: 1.5rem !important;\n  }\n\n  .me-xxl-5 {\n    margin-right: 3rem !important;\n  }\n\n  .me-xxl-auto {\n    margin-right: auto !important;\n  }\n\n  .mb-xxl-0 {\n    margin-bottom: 0 !important;\n  }\n\n  .mb-xxl-1 {\n    margin-bottom: 0.25rem !important;\n  }\n\n  .mb-xxl-2 {\n    margin-bottom: 0.5rem !important;\n  }\n\n  .mb-xxl-3 {\n    margin-bottom: 1rem !important;\n  }\n\n  .mb-xxl-4 {\n    margin-bottom: 1.5rem !important;\n  }\n\n  .mb-xxl-5 {\n    margin-bottom: 3rem !important;\n  }\n\n  .mb-xxl-auto {\n    margin-bottom: auto !important;\n  }\n\n  .ms-xxl-0 {\n    margin-left: 0 !important;\n  }\n\n  .ms-xxl-1 {\n    margin-left: 0.25rem !important;\n  }\n\n  .ms-xxl-2 {\n    margin-left: 0.5rem !important;\n  }\n\n  .ms-xxl-3 {\n    margin-left: 1rem !important;\n  }\n\n  .ms-xxl-4 {\n    margin-left: 1.5rem !important;\n  }\n\n  .ms-xxl-5 {\n    margin-left: 3rem !important;\n  }\n\n  .ms-xxl-auto {\n    margin-left: auto !important;\n  }\n\n  .p-xxl-0 {\n    padding: 0 !important;\n  }\n\n  .p-xxl-1 {\n    padding: 0.25rem !important;\n  }\n\n  .p-xxl-2 {\n    padding: 0.5rem !important;\n  }\n\n  .p-xxl-3 {\n    padding: 1rem !important;\n  }\n\n  .p-xxl-4 {\n    padding: 1.5rem !important;\n  }\n\n  .p-xxl-5 {\n    padding: 3rem !important;\n  }\n\n  .px-xxl-0 {\n    padding-right: 0 !important;\n    padding-left: 0 !important;\n  }\n\n  .px-xxl-1 {\n    padding-right: 0.25rem !important;\n    padding-left: 0.25rem !important;\n  }\n\n  .px-xxl-2 {\n    padding-right: 0.5rem !important;\n    padding-left: 0.5rem !important;\n  }\n\n  .px-xxl-3 {\n    padding-right: 1rem !important;\n    padding-left: 1rem !important;\n  }\n\n  .px-xxl-4 {\n    padding-right: 1.5rem !important;\n    padding-left: 1.5rem !important;\n  }\n\n  .px-xxl-5 {\n    padding-right: 3rem !important;\n    padding-left: 3rem !important;\n  }\n\n  .py-xxl-0 {\n    padding-top: 0 !important;\n    padding-bottom: 0 !important;\n  }\n\n  .py-xxl-1 {\n    padding-top: 0.25rem !important;\n    padding-bottom: 0.25rem !important;\n  }\n\n  .py-xxl-2 {\n    padding-top: 0.5rem !important;\n    padding-bottom: 0.5rem !important;\n  }\n\n  .py-xxl-3 {\n    padding-top: 1rem !important;\n    padding-bottom: 1rem !important;\n  }\n\n  .py-xxl-4 {\n    padding-top: 1.5rem !important;\n    padding-bottom: 1.5rem !important;\n  }\n\n  .py-xxl-5 {\n    padding-top: 3rem !important;\n    padding-bottom: 3rem !important;\n  }\n\n  .pt-xxl-0 {\n    padding-top: 0 !important;\n  }\n\n  .pt-xxl-1 {\n    padding-top: 0.25rem !important;\n  }\n\n  .pt-xxl-2 {\n    padding-top: 0.5rem !important;\n  }\n\n  .pt-xxl-3 {\n    padding-top: 1rem !important;\n  }\n\n  .pt-xxl-4 {\n    padding-top: 1.5rem !important;\n  }\n\n  .pt-xxl-5 {\n    padding-top: 3rem !important;\n  }\n\n  .pe-xxl-0 {\n    padding-right: 0 !important;\n  }\n\n  .pe-xxl-1 {\n    padding-right: 0.25rem !important;\n  }\n\n  .pe-xxl-2 {\n    padding-right: 0.5rem !important;\n  }\n\n  .pe-xxl-3 {\n    padding-right: 1rem !important;\n  }\n\n  .pe-xxl-4 {\n    padding-right: 1.5rem !important;\n  }\n\n  .pe-xxl-5 {\n    padding-right: 3rem !important;\n  }\n\n  .pb-xxl-0 {\n    padding-bottom: 0 !important;\n  }\n\n  .pb-xxl-1 {\n    padding-bottom: 0.25rem !important;\n  }\n\n  .pb-xxl-2 {\n    padding-bottom: 0.5rem !important;\n  }\n\n  .pb-xxl-3 {\n    padding-bottom: 1rem !important;\n  }\n\n  .pb-xxl-4 {\n    padding-bottom: 1.5rem !important;\n  }\n\n  .pb-xxl-5 {\n    padding-bottom: 3rem !important;\n  }\n\n  .ps-xxl-0 {\n    padding-left: 0 !important;\n  }\n\n  .ps-xxl-1 {\n    padding-left: 0.25rem !important;\n  }\n\n  .ps-xxl-2 {\n    padding-left: 0.5rem !important;\n  }\n\n  .ps-xxl-3 {\n    padding-left: 1rem !important;\n  }\n\n  .ps-xxl-4 {\n    padding-left: 1.5rem !important;\n  }\n\n  .ps-xxl-5 {\n    padding-left: 3rem !important;\n  }\n}\n@media print {\n  .d-print-inline {\n    display: inline !important;\n  }\n\n  .d-print-inline-block {\n    display: inline-block !important;\n  }\n\n  .d-print-block {\n    display: block !important;\n  }\n\n  .d-print-grid {\n    display: grid !important;\n  }\n\n  .d-print-table {\n    display: table !important;\n  }\n\n  .d-print-table-row {\n    display: table-row !important;\n  }\n\n  .d-print-table-cell {\n    display: table-cell !important;\n  }\n\n  .d-print-flex {\n    display: flex !important;\n  }\n\n  .d-print-inline-flex {\n    display: inline-flex !important;\n  }\n\n  .d-print-none {\n    display: none !important;\n  }\n}\n\n/*# sourceMappingURL=bootstrap-grid.css.map */"
  },
  {
    "path": "sample/src/NimblePros.SampleToDo.Web/wwwroot/lib/bootstrap/dist/css/bootstrap-grid.rtl.css",
    "content": "/*!\n * Bootstrap Grid v5.1.0 (https://getbootstrap.com/)\n * Copyright 2011-2021 The Bootstrap Authors\n * Copyright 2011-2021 Twitter, Inc.\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n */\n.container,\n.container-fluid,\n.container-xxl,\n.container-xl,\n.container-lg,\n.container-md,\n.container-sm {\n  width: 100%;\n  padding-left: var(--bs-gutter-x, 0.75rem);\n  padding-right: var(--bs-gutter-x, 0.75rem);\n  margin-left: auto;\n  margin-right: auto;\n}\n\n@media (min-width: 576px) {\n  .container-sm, .container {\n    max-width: 540px;\n  }\n}\n@media (min-width: 768px) {\n  .container-md, .container-sm, .container {\n    max-width: 720px;\n  }\n}\n@media (min-width: 992px) {\n  .container-lg, .container-md, .container-sm, .container {\n    max-width: 960px;\n  }\n}\n@media (min-width: 1200px) {\n  .container-xl, .container-lg, .container-md, .container-sm, .container {\n    max-width: 1140px;\n  }\n}\n@media (min-width: 1400px) {\n  .container-xxl, .container-xl, .container-lg, .container-md, .container-sm, .container {\n    max-width: 1320px;\n  }\n}\n.row {\n  --bs-gutter-x: 1.5rem;\n  --bs-gutter-y: 0;\n  display: flex;\n  flex-wrap: wrap;\n  margin-top: calc(var(--bs-gutter-y) * -1);\n  margin-left: calc(var(--bs-gutter-x) * -.5);\n  margin-right: calc(var(--bs-gutter-x) * -.5);\n}\n.row > * {\n  box-sizing: border-box;\n  flex-shrink: 0;\n  width: 100%;\n  max-width: 100%;\n  padding-left: calc(var(--bs-gutter-x) * .5);\n  padding-right: calc(var(--bs-gutter-x) * .5);\n  margin-top: var(--bs-gutter-y);\n}\n\n.col {\n  flex: 1 0 0%;\n}\n\n.row-cols-auto > * {\n  flex: 0 0 auto;\n  width: auto;\n}\n\n.row-cols-1 > * {\n  flex: 0 0 auto;\n  width: 100%;\n}\n\n.row-cols-2 > * {\n  flex: 0 0 auto;\n  width: 50%;\n}\n\n.row-cols-3 > * {\n  flex: 0 0 auto;\n  width: 33.3333333333%;\n}\n\n.row-cols-4 > * {\n  flex: 0 0 auto;\n  width: 25%;\n}\n\n.row-cols-5 > * {\n  flex: 0 0 auto;\n  width: 20%;\n}\n\n.row-cols-6 > * {\n  flex: 0 0 auto;\n  width: 16.6666666667%;\n}\n\n.col-auto {\n  flex: 0 0 auto;\n  width: auto;\n}\n\n.col-1 {\n  flex: 0 0 auto;\n  width: 8.33333333%;\n}\n\n.col-2 {\n  flex: 0 0 auto;\n  width: 16.66666667%;\n}\n\n.col-3 {\n  flex: 0 0 auto;\n  width: 25%;\n}\n\n.col-4 {\n  flex: 0 0 auto;\n  width: 33.33333333%;\n}\n\n.col-5 {\n  flex: 0 0 auto;\n  width: 41.66666667%;\n}\n\n.col-6 {\n  flex: 0 0 auto;\n  width: 50%;\n}\n\n.col-7 {\n  flex: 0 0 auto;\n  width: 58.33333333%;\n}\n\n.col-8 {\n  flex: 0 0 auto;\n  width: 66.66666667%;\n}\n\n.col-9 {\n  flex: 0 0 auto;\n  width: 75%;\n}\n\n.col-10 {\n  flex: 0 0 auto;\n  width: 83.33333333%;\n}\n\n.col-11 {\n  flex: 0 0 auto;\n  width: 91.66666667%;\n}\n\n.col-12 {\n  flex: 0 0 auto;\n  width: 100%;\n}\n\n.offset-1 {\n  margin-right: 8.33333333%;\n}\n\n.offset-2 {\n  margin-right: 16.66666667%;\n}\n\n.offset-3 {\n  margin-right: 25%;\n}\n\n.offset-4 {\n  margin-right: 33.33333333%;\n}\n\n.offset-5 {\n  margin-right: 41.66666667%;\n}\n\n.offset-6 {\n  margin-right: 50%;\n}\n\n.offset-7 {\n  margin-right: 58.33333333%;\n}\n\n.offset-8 {\n  margin-right: 66.66666667%;\n}\n\n.offset-9 {\n  margin-right: 75%;\n}\n\n.offset-10 {\n  margin-right: 83.33333333%;\n}\n\n.offset-11 {\n  margin-right: 91.66666667%;\n}\n\n.g-0,\n.gx-0 {\n  --bs-gutter-x: 0;\n}\n\n.g-0,\n.gy-0 {\n  --bs-gutter-y: 0;\n}\n\n.g-1,\n.gx-1 {\n  --bs-gutter-x: 0.25rem;\n}\n\n.g-1,\n.gy-1 {\n  --bs-gutter-y: 0.25rem;\n}\n\n.g-2,\n.gx-2 {\n  --bs-gutter-x: 0.5rem;\n}\n\n.g-2,\n.gy-2 {\n  --bs-gutter-y: 0.5rem;\n}\n\n.g-3,\n.gx-3 {\n  --bs-gutter-x: 1rem;\n}\n\n.g-3,\n.gy-3 {\n  --bs-gutter-y: 1rem;\n}\n\n.g-4,\n.gx-4 {\n  --bs-gutter-x: 1.5rem;\n}\n\n.g-4,\n.gy-4 {\n  --bs-gutter-y: 1.5rem;\n}\n\n.g-5,\n.gx-5 {\n  --bs-gutter-x: 3rem;\n}\n\n.g-5,\n.gy-5 {\n  --bs-gutter-y: 3rem;\n}\n\n@media (min-width: 576px) {\n  .col-sm {\n    flex: 1 0 0%;\n  }\n\n  .row-cols-sm-auto > * {\n    flex: 0 0 auto;\n    width: auto;\n  }\n\n  .row-cols-sm-1 > * {\n    flex: 0 0 auto;\n    width: 100%;\n  }\n\n  .row-cols-sm-2 > * {\n    flex: 0 0 auto;\n    width: 50%;\n  }\n\n  .row-cols-sm-3 > * {\n    flex: 0 0 auto;\n    width: 33.3333333333%;\n  }\n\n  .row-cols-sm-4 > * {\n    flex: 0 0 auto;\n    width: 25%;\n  }\n\n  .row-cols-sm-5 > * {\n    flex: 0 0 auto;\n    width: 20%;\n  }\n\n  .row-cols-sm-6 > * {\n    flex: 0 0 auto;\n    width: 16.6666666667%;\n  }\n\n  .col-sm-auto {\n    flex: 0 0 auto;\n    width: auto;\n  }\n\n  .col-sm-1 {\n    flex: 0 0 auto;\n    width: 8.33333333%;\n  }\n\n  .col-sm-2 {\n    flex: 0 0 auto;\n    width: 16.66666667%;\n  }\n\n  .col-sm-3 {\n    flex: 0 0 auto;\n    width: 25%;\n  }\n\n  .col-sm-4 {\n    flex: 0 0 auto;\n    width: 33.33333333%;\n  }\n\n  .col-sm-5 {\n    flex: 0 0 auto;\n    width: 41.66666667%;\n  }\n\n  .col-sm-6 {\n    flex: 0 0 auto;\n    width: 50%;\n  }\n\n  .col-sm-7 {\n    flex: 0 0 auto;\n    width: 58.33333333%;\n  }\n\n  .col-sm-8 {\n    flex: 0 0 auto;\n    width: 66.66666667%;\n  }\n\n  .col-sm-9 {\n    flex: 0 0 auto;\n    width: 75%;\n  }\n\n  .col-sm-10 {\n    flex: 0 0 auto;\n    width: 83.33333333%;\n  }\n\n  .col-sm-11 {\n    flex: 0 0 auto;\n    width: 91.66666667%;\n  }\n\n  .col-sm-12 {\n    flex: 0 0 auto;\n    width: 100%;\n  }\n\n  .offset-sm-0 {\n    margin-right: 0;\n  }\n\n  .offset-sm-1 {\n    margin-right: 8.33333333%;\n  }\n\n  .offset-sm-2 {\n    margin-right: 16.66666667%;\n  }\n\n  .offset-sm-3 {\n    margin-right: 25%;\n  }\n\n  .offset-sm-4 {\n    margin-right: 33.33333333%;\n  }\n\n  .offset-sm-5 {\n    margin-right: 41.66666667%;\n  }\n\n  .offset-sm-6 {\n    margin-right: 50%;\n  }\n\n  .offset-sm-7 {\n    margin-right: 58.33333333%;\n  }\n\n  .offset-sm-8 {\n    margin-right: 66.66666667%;\n  }\n\n  .offset-sm-9 {\n    margin-right: 75%;\n  }\n\n  .offset-sm-10 {\n    margin-right: 83.33333333%;\n  }\n\n  .offset-sm-11 {\n    margin-right: 91.66666667%;\n  }\n\n  .g-sm-0,\n.gx-sm-0 {\n    --bs-gutter-x: 0;\n  }\n\n  .g-sm-0,\n.gy-sm-0 {\n    --bs-gutter-y: 0;\n  }\n\n  .g-sm-1,\n.gx-sm-1 {\n    --bs-gutter-x: 0.25rem;\n  }\n\n  .g-sm-1,\n.gy-sm-1 {\n    --bs-gutter-y: 0.25rem;\n  }\n\n  .g-sm-2,\n.gx-sm-2 {\n    --bs-gutter-x: 0.5rem;\n  }\n\n  .g-sm-2,\n.gy-sm-2 {\n    --bs-gutter-y: 0.5rem;\n  }\n\n  .g-sm-3,\n.gx-sm-3 {\n    --bs-gutter-x: 1rem;\n  }\n\n  .g-sm-3,\n.gy-sm-3 {\n    --bs-gutter-y: 1rem;\n  }\n\n  .g-sm-4,\n.gx-sm-4 {\n    --bs-gutter-x: 1.5rem;\n  }\n\n  .g-sm-4,\n.gy-sm-4 {\n    --bs-gutter-y: 1.5rem;\n  }\n\n  .g-sm-5,\n.gx-sm-5 {\n    --bs-gutter-x: 3rem;\n  }\n\n  .g-sm-5,\n.gy-sm-5 {\n    --bs-gutter-y: 3rem;\n  }\n}\n@media (min-width: 768px) {\n  .col-md {\n    flex: 1 0 0%;\n  }\n\n  .row-cols-md-auto > * {\n    flex: 0 0 auto;\n    width: auto;\n  }\n\n  .row-cols-md-1 > * {\n    flex: 0 0 auto;\n    width: 100%;\n  }\n\n  .row-cols-md-2 > * {\n    flex: 0 0 auto;\n    width: 50%;\n  }\n\n  .row-cols-md-3 > * {\n    flex: 0 0 auto;\n    width: 33.3333333333%;\n  }\n\n  .row-cols-md-4 > * {\n    flex: 0 0 auto;\n    width: 25%;\n  }\n\n  .row-cols-md-5 > * {\n    flex: 0 0 auto;\n    width: 20%;\n  }\n\n  .row-cols-md-6 > * {\n    flex: 0 0 auto;\n    width: 16.6666666667%;\n  }\n\n  .col-md-auto {\n    flex: 0 0 auto;\n    width: auto;\n  }\n\n  .col-md-1 {\n    flex: 0 0 auto;\n    width: 8.33333333%;\n  }\n\n  .col-md-2 {\n    flex: 0 0 auto;\n    width: 16.66666667%;\n  }\n\n  .col-md-3 {\n    flex: 0 0 auto;\n    width: 25%;\n  }\n\n  .col-md-4 {\n    flex: 0 0 auto;\n    width: 33.33333333%;\n  }\n\n  .col-md-5 {\n    flex: 0 0 auto;\n    width: 41.66666667%;\n  }\n\n  .col-md-6 {\n    flex: 0 0 auto;\n    width: 50%;\n  }\n\n  .col-md-7 {\n    flex: 0 0 auto;\n    width: 58.33333333%;\n  }\n\n  .col-md-8 {\n    flex: 0 0 auto;\n    width: 66.66666667%;\n  }\n\n  .col-md-9 {\n    flex: 0 0 auto;\n    width: 75%;\n  }\n\n  .col-md-10 {\n    flex: 0 0 auto;\n    width: 83.33333333%;\n  }\n\n  .col-md-11 {\n    flex: 0 0 auto;\n    width: 91.66666667%;\n  }\n\n  .col-md-12 {\n    flex: 0 0 auto;\n    width: 100%;\n  }\n\n  .offset-md-0 {\n    margin-right: 0;\n  }\n\n  .offset-md-1 {\n    margin-right: 8.33333333%;\n  }\n\n  .offset-md-2 {\n    margin-right: 16.66666667%;\n  }\n\n  .offset-md-3 {\n    margin-right: 25%;\n  }\n\n  .offset-md-4 {\n    margin-right: 33.33333333%;\n  }\n\n  .offset-md-5 {\n    margin-right: 41.66666667%;\n  }\n\n  .offset-md-6 {\n    margin-right: 50%;\n  }\n\n  .offset-md-7 {\n    margin-right: 58.33333333%;\n  }\n\n  .offset-md-8 {\n    margin-right: 66.66666667%;\n  }\n\n  .offset-md-9 {\n    margin-right: 75%;\n  }\n\n  .offset-md-10 {\n    margin-right: 83.33333333%;\n  }\n\n  .offset-md-11 {\n    margin-right: 91.66666667%;\n  }\n\n  .g-md-0,\n.gx-md-0 {\n    --bs-gutter-x: 0;\n  }\n\n  .g-md-0,\n.gy-md-0 {\n    --bs-gutter-y: 0;\n  }\n\n  .g-md-1,\n.gx-md-1 {\n    --bs-gutter-x: 0.25rem;\n  }\n\n  .g-md-1,\n.gy-md-1 {\n    --bs-gutter-y: 0.25rem;\n  }\n\n  .g-md-2,\n.gx-md-2 {\n    --bs-gutter-x: 0.5rem;\n  }\n\n  .g-md-2,\n.gy-md-2 {\n    --bs-gutter-y: 0.5rem;\n  }\n\n  .g-md-3,\n.gx-md-3 {\n    --bs-gutter-x: 1rem;\n  }\n\n  .g-md-3,\n.gy-md-3 {\n    --bs-gutter-y: 1rem;\n  }\n\n  .g-md-4,\n.gx-md-4 {\n    --bs-gutter-x: 1.5rem;\n  }\n\n  .g-md-4,\n.gy-md-4 {\n    --bs-gutter-y: 1.5rem;\n  }\n\n  .g-md-5,\n.gx-md-5 {\n    --bs-gutter-x: 3rem;\n  }\n\n  .g-md-5,\n.gy-md-5 {\n    --bs-gutter-y: 3rem;\n  }\n}\n@media (min-width: 992px) {\n  .col-lg {\n    flex: 1 0 0%;\n  }\n\n  .row-cols-lg-auto > * {\n    flex: 0 0 auto;\n    width: auto;\n  }\n\n  .row-cols-lg-1 > * {\n    flex: 0 0 auto;\n    width: 100%;\n  }\n\n  .row-cols-lg-2 > * {\n    flex: 0 0 auto;\n    width: 50%;\n  }\n\n  .row-cols-lg-3 > * {\n    flex: 0 0 auto;\n    width: 33.3333333333%;\n  }\n\n  .row-cols-lg-4 > * {\n    flex: 0 0 auto;\n    width: 25%;\n  }\n\n  .row-cols-lg-5 > * {\n    flex: 0 0 auto;\n    width: 20%;\n  }\n\n  .row-cols-lg-6 > * {\n    flex: 0 0 auto;\n    width: 16.6666666667%;\n  }\n\n  .col-lg-auto {\n    flex: 0 0 auto;\n    width: auto;\n  }\n\n  .col-lg-1 {\n    flex: 0 0 auto;\n    width: 8.33333333%;\n  }\n\n  .col-lg-2 {\n    flex: 0 0 auto;\n    width: 16.66666667%;\n  }\n\n  .col-lg-3 {\n    flex: 0 0 auto;\n    width: 25%;\n  }\n\n  .col-lg-4 {\n    flex: 0 0 auto;\n    width: 33.33333333%;\n  }\n\n  .col-lg-5 {\n    flex: 0 0 auto;\n    width: 41.66666667%;\n  }\n\n  .col-lg-6 {\n    flex: 0 0 auto;\n    width: 50%;\n  }\n\n  .col-lg-7 {\n    flex: 0 0 auto;\n    width: 58.33333333%;\n  }\n\n  .col-lg-8 {\n    flex: 0 0 auto;\n    width: 66.66666667%;\n  }\n\n  .col-lg-9 {\n    flex: 0 0 auto;\n    width: 75%;\n  }\n\n  .col-lg-10 {\n    flex: 0 0 auto;\n    width: 83.33333333%;\n  }\n\n  .col-lg-11 {\n    flex: 0 0 auto;\n    width: 91.66666667%;\n  }\n\n  .col-lg-12 {\n    flex: 0 0 auto;\n    width: 100%;\n  }\n\n  .offset-lg-0 {\n    margin-right: 0;\n  }\n\n  .offset-lg-1 {\n    margin-right: 8.33333333%;\n  }\n\n  .offset-lg-2 {\n    margin-right: 16.66666667%;\n  }\n\n  .offset-lg-3 {\n    margin-right: 25%;\n  }\n\n  .offset-lg-4 {\n    margin-right: 33.33333333%;\n  }\n\n  .offset-lg-5 {\n    margin-right: 41.66666667%;\n  }\n\n  .offset-lg-6 {\n    margin-right: 50%;\n  }\n\n  .offset-lg-7 {\n    margin-right: 58.33333333%;\n  }\n\n  .offset-lg-8 {\n    margin-right: 66.66666667%;\n  }\n\n  .offset-lg-9 {\n    margin-right: 75%;\n  }\n\n  .offset-lg-10 {\n    margin-right: 83.33333333%;\n  }\n\n  .offset-lg-11 {\n    margin-right: 91.66666667%;\n  }\n\n  .g-lg-0,\n.gx-lg-0 {\n    --bs-gutter-x: 0;\n  }\n\n  .g-lg-0,\n.gy-lg-0 {\n    --bs-gutter-y: 0;\n  }\n\n  .g-lg-1,\n.gx-lg-1 {\n    --bs-gutter-x: 0.25rem;\n  }\n\n  .g-lg-1,\n.gy-lg-1 {\n    --bs-gutter-y: 0.25rem;\n  }\n\n  .g-lg-2,\n.gx-lg-2 {\n    --bs-gutter-x: 0.5rem;\n  }\n\n  .g-lg-2,\n.gy-lg-2 {\n    --bs-gutter-y: 0.5rem;\n  }\n\n  .g-lg-3,\n.gx-lg-3 {\n    --bs-gutter-x: 1rem;\n  }\n\n  .g-lg-3,\n.gy-lg-3 {\n    --bs-gutter-y: 1rem;\n  }\n\n  .g-lg-4,\n.gx-lg-4 {\n    --bs-gutter-x: 1.5rem;\n  }\n\n  .g-lg-4,\n.gy-lg-4 {\n    --bs-gutter-y: 1.5rem;\n  }\n\n  .g-lg-5,\n.gx-lg-5 {\n    --bs-gutter-x: 3rem;\n  }\n\n  .g-lg-5,\n.gy-lg-5 {\n    --bs-gutter-y: 3rem;\n  }\n}\n@media (min-width: 1200px) {\n  .col-xl {\n    flex: 1 0 0%;\n  }\n\n  .row-cols-xl-auto > * {\n    flex: 0 0 auto;\n    width: auto;\n  }\n\n  .row-cols-xl-1 > * {\n    flex: 0 0 auto;\n    width: 100%;\n  }\n\n  .row-cols-xl-2 > * {\n    flex: 0 0 auto;\n    width: 50%;\n  }\n\n  .row-cols-xl-3 > * {\n    flex: 0 0 auto;\n    width: 33.3333333333%;\n  }\n\n  .row-cols-xl-4 > * {\n    flex: 0 0 auto;\n    width: 25%;\n  }\n\n  .row-cols-xl-5 > * {\n    flex: 0 0 auto;\n    width: 20%;\n  }\n\n  .row-cols-xl-6 > * {\n    flex: 0 0 auto;\n    width: 16.6666666667%;\n  }\n\n  .col-xl-auto {\n    flex: 0 0 auto;\n    width: auto;\n  }\n\n  .col-xl-1 {\n    flex: 0 0 auto;\n    width: 8.33333333%;\n  }\n\n  .col-xl-2 {\n    flex: 0 0 auto;\n    width: 16.66666667%;\n  }\n\n  .col-xl-3 {\n    flex: 0 0 auto;\n    width: 25%;\n  }\n\n  .col-xl-4 {\n    flex: 0 0 auto;\n    width: 33.33333333%;\n  }\n\n  .col-xl-5 {\n    flex: 0 0 auto;\n    width: 41.66666667%;\n  }\n\n  .col-xl-6 {\n    flex: 0 0 auto;\n    width: 50%;\n  }\n\n  .col-xl-7 {\n    flex: 0 0 auto;\n    width: 58.33333333%;\n  }\n\n  .col-xl-8 {\n    flex: 0 0 auto;\n    width: 66.66666667%;\n  }\n\n  .col-xl-9 {\n    flex: 0 0 auto;\n    width: 75%;\n  }\n\n  .col-xl-10 {\n    flex: 0 0 auto;\n    width: 83.33333333%;\n  }\n\n  .col-xl-11 {\n    flex: 0 0 auto;\n    width: 91.66666667%;\n  }\n\n  .col-xl-12 {\n    flex: 0 0 auto;\n    width: 100%;\n  }\n\n  .offset-xl-0 {\n    margin-right: 0;\n  }\n\n  .offset-xl-1 {\n    margin-right: 8.33333333%;\n  }\n\n  .offset-xl-2 {\n    margin-right: 16.66666667%;\n  }\n\n  .offset-xl-3 {\n    margin-right: 25%;\n  }\n\n  .offset-xl-4 {\n    margin-right: 33.33333333%;\n  }\n\n  .offset-xl-5 {\n    margin-right: 41.66666667%;\n  }\n\n  .offset-xl-6 {\n    margin-right: 50%;\n  }\n\n  .offset-xl-7 {\n    margin-right: 58.33333333%;\n  }\n\n  .offset-xl-8 {\n    margin-right: 66.66666667%;\n  }\n\n  .offset-xl-9 {\n    margin-right: 75%;\n  }\n\n  .offset-xl-10 {\n    margin-right: 83.33333333%;\n  }\n\n  .offset-xl-11 {\n    margin-right: 91.66666667%;\n  }\n\n  .g-xl-0,\n.gx-xl-0 {\n    --bs-gutter-x: 0;\n  }\n\n  .g-xl-0,\n.gy-xl-0 {\n    --bs-gutter-y: 0;\n  }\n\n  .g-xl-1,\n.gx-xl-1 {\n    --bs-gutter-x: 0.25rem;\n  }\n\n  .g-xl-1,\n.gy-xl-1 {\n    --bs-gutter-y: 0.25rem;\n  }\n\n  .g-xl-2,\n.gx-xl-2 {\n    --bs-gutter-x: 0.5rem;\n  }\n\n  .g-xl-2,\n.gy-xl-2 {\n    --bs-gutter-y: 0.5rem;\n  }\n\n  .g-xl-3,\n.gx-xl-3 {\n    --bs-gutter-x: 1rem;\n  }\n\n  .g-xl-3,\n.gy-xl-3 {\n    --bs-gutter-y: 1rem;\n  }\n\n  .g-xl-4,\n.gx-xl-4 {\n    --bs-gutter-x: 1.5rem;\n  }\n\n  .g-xl-4,\n.gy-xl-4 {\n    --bs-gutter-y: 1.5rem;\n  }\n\n  .g-xl-5,\n.gx-xl-5 {\n    --bs-gutter-x: 3rem;\n  }\n\n  .g-xl-5,\n.gy-xl-5 {\n    --bs-gutter-y: 3rem;\n  }\n}\n@media (min-width: 1400px) {\n  .col-xxl {\n    flex: 1 0 0%;\n  }\n\n  .row-cols-xxl-auto > * {\n    flex: 0 0 auto;\n    width: auto;\n  }\n\n  .row-cols-xxl-1 > * {\n    flex: 0 0 auto;\n    width: 100%;\n  }\n\n  .row-cols-xxl-2 > * {\n    flex: 0 0 auto;\n    width: 50%;\n  }\n\n  .row-cols-xxl-3 > * {\n    flex: 0 0 auto;\n    width: 33.3333333333%;\n  }\n\n  .row-cols-xxl-4 > * {\n    flex: 0 0 auto;\n    width: 25%;\n  }\n\n  .row-cols-xxl-5 > * {\n    flex: 0 0 auto;\n    width: 20%;\n  }\n\n  .row-cols-xxl-6 > * {\n    flex: 0 0 auto;\n    width: 16.6666666667%;\n  }\n\n  .col-xxl-auto {\n    flex: 0 0 auto;\n    width: auto;\n  }\n\n  .col-xxl-1 {\n    flex: 0 0 auto;\n    width: 8.33333333%;\n  }\n\n  .col-xxl-2 {\n    flex: 0 0 auto;\n    width: 16.66666667%;\n  }\n\n  .col-xxl-3 {\n    flex: 0 0 auto;\n    width: 25%;\n  }\n\n  .col-xxl-4 {\n    flex: 0 0 auto;\n    width: 33.33333333%;\n  }\n\n  .col-xxl-5 {\n    flex: 0 0 auto;\n    width: 41.66666667%;\n  }\n\n  .col-xxl-6 {\n    flex: 0 0 auto;\n    width: 50%;\n  }\n\n  .col-xxl-7 {\n    flex: 0 0 auto;\n    width: 58.33333333%;\n  }\n\n  .col-xxl-8 {\n    flex: 0 0 auto;\n    width: 66.66666667%;\n  }\n\n  .col-xxl-9 {\n    flex: 0 0 auto;\n    width: 75%;\n  }\n\n  .col-xxl-10 {\n    flex: 0 0 auto;\n    width: 83.33333333%;\n  }\n\n  .col-xxl-11 {\n    flex: 0 0 auto;\n    width: 91.66666667%;\n  }\n\n  .col-xxl-12 {\n    flex: 0 0 auto;\n    width: 100%;\n  }\n\n  .offset-xxl-0 {\n    margin-right: 0;\n  }\n\n  .offset-xxl-1 {\n    margin-right: 8.33333333%;\n  }\n\n  .offset-xxl-2 {\n    margin-right: 16.66666667%;\n  }\n\n  .offset-xxl-3 {\n    margin-right: 25%;\n  }\n\n  .offset-xxl-4 {\n    margin-right: 33.33333333%;\n  }\n\n  .offset-xxl-5 {\n    margin-right: 41.66666667%;\n  }\n\n  .offset-xxl-6 {\n    margin-right: 50%;\n  }\n\n  .offset-xxl-7 {\n    margin-right: 58.33333333%;\n  }\n\n  .offset-xxl-8 {\n    margin-right: 66.66666667%;\n  }\n\n  .offset-xxl-9 {\n    margin-right: 75%;\n  }\n\n  .offset-xxl-10 {\n    margin-right: 83.33333333%;\n  }\n\n  .offset-xxl-11 {\n    margin-right: 91.66666667%;\n  }\n\n  .g-xxl-0,\n.gx-xxl-0 {\n    --bs-gutter-x: 0;\n  }\n\n  .g-xxl-0,\n.gy-xxl-0 {\n    --bs-gutter-y: 0;\n  }\n\n  .g-xxl-1,\n.gx-xxl-1 {\n    --bs-gutter-x: 0.25rem;\n  }\n\n  .g-xxl-1,\n.gy-xxl-1 {\n    --bs-gutter-y: 0.25rem;\n  }\n\n  .g-xxl-2,\n.gx-xxl-2 {\n    --bs-gutter-x: 0.5rem;\n  }\n\n  .g-xxl-2,\n.gy-xxl-2 {\n    --bs-gutter-y: 0.5rem;\n  }\n\n  .g-xxl-3,\n.gx-xxl-3 {\n    --bs-gutter-x: 1rem;\n  }\n\n  .g-xxl-3,\n.gy-xxl-3 {\n    --bs-gutter-y: 1rem;\n  }\n\n  .g-xxl-4,\n.gx-xxl-4 {\n    --bs-gutter-x: 1.5rem;\n  }\n\n  .g-xxl-4,\n.gy-xxl-4 {\n    --bs-gutter-y: 1.5rem;\n  }\n\n  .g-xxl-5,\n.gx-xxl-5 {\n    --bs-gutter-x: 3rem;\n  }\n\n  .g-xxl-5,\n.gy-xxl-5 {\n    --bs-gutter-y: 3rem;\n  }\n}\n.d-inline {\n  display: inline !important;\n}\n\n.d-inline-block {\n  display: inline-block !important;\n}\n\n.d-block {\n  display: block !important;\n}\n\n.d-grid {\n  display: grid !important;\n}\n\n.d-table {\n  display: table !important;\n}\n\n.d-table-row {\n  display: table-row !important;\n}\n\n.d-table-cell {\n  display: table-cell !important;\n}\n\n.d-flex {\n  display: flex !important;\n}\n\n.d-inline-flex {\n  display: inline-flex !important;\n}\n\n.d-none {\n  display: none !important;\n}\n\n.flex-fill {\n  flex: 1 1 auto !important;\n}\n\n.flex-row {\n  flex-direction: row !important;\n}\n\n.flex-column {\n  flex-direction: column !important;\n}\n\n.flex-row-reverse {\n  flex-direction: row-reverse !important;\n}\n\n.flex-column-reverse {\n  flex-direction: column-reverse !important;\n}\n\n.flex-grow-0 {\n  flex-grow: 0 !important;\n}\n\n.flex-grow-1 {\n  flex-grow: 1 !important;\n}\n\n.flex-shrink-0 {\n  flex-shrink: 0 !important;\n}\n\n.flex-shrink-1 {\n  flex-shrink: 1 !important;\n}\n\n.flex-wrap {\n  flex-wrap: wrap !important;\n}\n\n.flex-nowrap {\n  flex-wrap: nowrap !important;\n}\n\n.flex-wrap-reverse {\n  flex-wrap: wrap-reverse !important;\n}\n\n.justify-content-start {\n  justify-content: flex-start !important;\n}\n\n.justify-content-end {\n  justify-content: flex-end !important;\n}\n\n.justify-content-center {\n  justify-content: center !important;\n}\n\n.justify-content-between {\n  justify-content: space-between !important;\n}\n\n.justify-content-around {\n  justify-content: space-around !important;\n}\n\n.justify-content-evenly {\n  justify-content: space-evenly !important;\n}\n\n.align-items-start {\n  align-items: flex-start !important;\n}\n\n.align-items-end {\n  align-items: flex-end !important;\n}\n\n.align-items-center {\n  align-items: center !important;\n}\n\n.align-items-baseline {\n  align-items: baseline !important;\n}\n\n.align-items-stretch {\n  align-items: stretch !important;\n}\n\n.align-content-start {\n  align-content: flex-start !important;\n}\n\n.align-content-end {\n  align-content: flex-end !important;\n}\n\n.align-content-center {\n  align-content: center !important;\n}\n\n.align-content-between {\n  align-content: space-between !important;\n}\n\n.align-content-around {\n  align-content: space-around !important;\n}\n\n.align-content-stretch {\n  align-content: stretch !important;\n}\n\n.align-self-auto {\n  align-self: auto !important;\n}\n\n.align-self-start {\n  align-self: flex-start !important;\n}\n\n.align-self-end {\n  align-self: flex-end !important;\n}\n\n.align-self-center {\n  align-self: center !important;\n}\n\n.align-self-baseline {\n  align-self: baseline !important;\n}\n\n.align-self-stretch {\n  align-self: stretch !important;\n}\n\n.order-first {\n  order: -1 !important;\n}\n\n.order-0 {\n  order: 0 !important;\n}\n\n.order-1 {\n  order: 1 !important;\n}\n\n.order-2 {\n  order: 2 !important;\n}\n\n.order-3 {\n  order: 3 !important;\n}\n\n.order-4 {\n  order: 4 !important;\n}\n\n.order-5 {\n  order: 5 !important;\n}\n\n.order-last {\n  order: 6 !important;\n}\n\n.m-0 {\n  margin: 0 !important;\n}\n\n.m-1 {\n  margin: 0.25rem !important;\n}\n\n.m-2 {\n  margin: 0.5rem !important;\n}\n\n.m-3 {\n  margin: 1rem !important;\n}\n\n.m-4 {\n  margin: 1.5rem !important;\n}\n\n.m-5 {\n  margin: 3rem !important;\n}\n\n.m-auto {\n  margin: auto !important;\n}\n\n.mx-0 {\n  margin-left: 0 !important;\n  margin-right: 0 !important;\n}\n\n.mx-1 {\n  margin-left: 0.25rem !important;\n  margin-right: 0.25rem !important;\n}\n\n.mx-2 {\n  margin-left: 0.5rem !important;\n  margin-right: 0.5rem !important;\n}\n\n.mx-3 {\n  margin-left: 1rem !important;\n  margin-right: 1rem !important;\n}\n\n.mx-4 {\n  margin-left: 1.5rem !important;\n  margin-right: 1.5rem !important;\n}\n\n.mx-5 {\n  margin-left: 3rem !important;\n  margin-right: 3rem !important;\n}\n\n.mx-auto {\n  margin-left: auto !important;\n  margin-right: auto !important;\n}\n\n.my-0 {\n  margin-top: 0 !important;\n  margin-bottom: 0 !important;\n}\n\n.my-1 {\n  margin-top: 0.25rem !important;\n  margin-bottom: 0.25rem !important;\n}\n\n.my-2 {\n  margin-top: 0.5rem !important;\n  margin-bottom: 0.5rem !important;\n}\n\n.my-3 {\n  margin-top: 1rem !important;\n  margin-bottom: 1rem !important;\n}\n\n.my-4 {\n  margin-top: 1.5rem !important;\n  margin-bottom: 1.5rem !important;\n}\n\n.my-5 {\n  margin-top: 3rem !important;\n  margin-bottom: 3rem !important;\n}\n\n.my-auto {\n  margin-top: auto !important;\n  margin-bottom: auto !important;\n}\n\n.mt-0 {\n  margin-top: 0 !important;\n}\n\n.mt-1 {\n  margin-top: 0.25rem !important;\n}\n\n.mt-2 {\n  margin-top: 0.5rem !important;\n}\n\n.mt-3 {\n  margin-top: 1rem !important;\n}\n\n.mt-4 {\n  margin-top: 1.5rem !important;\n}\n\n.mt-5 {\n  margin-top: 3rem !important;\n}\n\n.mt-auto {\n  margin-top: auto !important;\n}\n\n.me-0 {\n  margin-left: 0 !important;\n}\n\n.me-1 {\n  margin-left: 0.25rem !important;\n}\n\n.me-2 {\n  margin-left: 0.5rem !important;\n}\n\n.me-3 {\n  margin-left: 1rem !important;\n}\n\n.me-4 {\n  margin-left: 1.5rem !important;\n}\n\n.me-5 {\n  margin-left: 3rem !important;\n}\n\n.me-auto {\n  margin-left: auto !important;\n}\n\n.mb-0 {\n  margin-bottom: 0 !important;\n}\n\n.mb-1 {\n  margin-bottom: 0.25rem !important;\n}\n\n.mb-2 {\n  margin-bottom: 0.5rem !important;\n}\n\n.mb-3 {\n  margin-bottom: 1rem !important;\n}\n\n.mb-4 {\n  margin-bottom: 1.5rem !important;\n}\n\n.mb-5 {\n  margin-bottom: 3rem !important;\n}\n\n.mb-auto {\n  margin-bottom: auto !important;\n}\n\n.ms-0 {\n  margin-right: 0 !important;\n}\n\n.ms-1 {\n  margin-right: 0.25rem !important;\n}\n\n.ms-2 {\n  margin-right: 0.5rem !important;\n}\n\n.ms-3 {\n  margin-right: 1rem !important;\n}\n\n.ms-4 {\n  margin-right: 1.5rem !important;\n}\n\n.ms-5 {\n  margin-right: 3rem !important;\n}\n\n.ms-auto {\n  margin-right: auto !important;\n}\n\n.p-0 {\n  padding: 0 !important;\n}\n\n.p-1 {\n  padding: 0.25rem !important;\n}\n\n.p-2 {\n  padding: 0.5rem !important;\n}\n\n.p-3 {\n  padding: 1rem !important;\n}\n\n.p-4 {\n  padding: 1.5rem !important;\n}\n\n.p-5 {\n  padding: 3rem !important;\n}\n\n.px-0 {\n  padding-left: 0 !important;\n  padding-right: 0 !important;\n}\n\n.px-1 {\n  padding-left: 0.25rem !important;\n  padding-right: 0.25rem !important;\n}\n\n.px-2 {\n  padding-left: 0.5rem !important;\n  padding-right: 0.5rem !important;\n}\n\n.px-3 {\n  padding-left: 1rem !important;\n  padding-right: 1rem !important;\n}\n\n.px-4 {\n  padding-left: 1.5rem !important;\n  padding-right: 1.5rem !important;\n}\n\n.px-5 {\n  padding-left: 3rem !important;\n  padding-right: 3rem !important;\n}\n\n.py-0 {\n  padding-top: 0 !important;\n  padding-bottom: 0 !important;\n}\n\n.py-1 {\n  padding-top: 0.25rem !important;\n  padding-bottom: 0.25rem !important;\n}\n\n.py-2 {\n  padding-top: 0.5rem !important;\n  padding-bottom: 0.5rem !important;\n}\n\n.py-3 {\n  padding-top: 1rem !important;\n  padding-bottom: 1rem !important;\n}\n\n.py-4 {\n  padding-top: 1.5rem !important;\n  padding-bottom: 1.5rem !important;\n}\n\n.py-5 {\n  padding-top: 3rem !important;\n  padding-bottom: 3rem !important;\n}\n\n.pt-0 {\n  padding-top: 0 !important;\n}\n\n.pt-1 {\n  padding-top: 0.25rem !important;\n}\n\n.pt-2 {\n  padding-top: 0.5rem !important;\n}\n\n.pt-3 {\n  padding-top: 1rem !important;\n}\n\n.pt-4 {\n  padding-top: 1.5rem !important;\n}\n\n.pt-5 {\n  padding-top: 3rem !important;\n}\n\n.pe-0 {\n  padding-left: 0 !important;\n}\n\n.pe-1 {\n  padding-left: 0.25rem !important;\n}\n\n.pe-2 {\n  padding-left: 0.5rem !important;\n}\n\n.pe-3 {\n  padding-left: 1rem !important;\n}\n\n.pe-4 {\n  padding-left: 1.5rem !important;\n}\n\n.pe-5 {\n  padding-left: 3rem !important;\n}\n\n.pb-0 {\n  padding-bottom: 0 !important;\n}\n\n.pb-1 {\n  padding-bottom: 0.25rem !important;\n}\n\n.pb-2 {\n  padding-bottom: 0.5rem !important;\n}\n\n.pb-3 {\n  padding-bottom: 1rem !important;\n}\n\n.pb-4 {\n  padding-bottom: 1.5rem !important;\n}\n\n.pb-5 {\n  padding-bottom: 3rem !important;\n}\n\n.ps-0 {\n  padding-right: 0 !important;\n}\n\n.ps-1 {\n  padding-right: 0.25rem !important;\n}\n\n.ps-2 {\n  padding-right: 0.5rem !important;\n}\n\n.ps-3 {\n  padding-right: 1rem !important;\n}\n\n.ps-4 {\n  padding-right: 1.5rem !important;\n}\n\n.ps-5 {\n  padding-right: 3rem !important;\n}\n\n@media (min-width: 576px) {\n  .d-sm-inline {\n    display: inline !important;\n  }\n\n  .d-sm-inline-block {\n    display: inline-block !important;\n  }\n\n  .d-sm-block {\n    display: block !important;\n  }\n\n  .d-sm-grid {\n    display: grid !important;\n  }\n\n  .d-sm-table {\n    display: table !important;\n  }\n\n  .d-sm-table-row {\n    display: table-row !important;\n  }\n\n  .d-sm-table-cell {\n    display: table-cell !important;\n  }\n\n  .d-sm-flex {\n    display: flex !important;\n  }\n\n  .d-sm-inline-flex {\n    display: inline-flex !important;\n  }\n\n  .d-sm-none {\n    display: none !important;\n  }\n\n  .flex-sm-fill {\n    flex: 1 1 auto !important;\n  }\n\n  .flex-sm-row {\n    flex-direction: row !important;\n  }\n\n  .flex-sm-column {\n    flex-direction: column !important;\n  }\n\n  .flex-sm-row-reverse {\n    flex-direction: row-reverse !important;\n  }\n\n  .flex-sm-column-reverse {\n    flex-direction: column-reverse !important;\n  }\n\n  .flex-sm-grow-0 {\n    flex-grow: 0 !important;\n  }\n\n  .flex-sm-grow-1 {\n    flex-grow: 1 !important;\n  }\n\n  .flex-sm-shrink-0 {\n    flex-shrink: 0 !important;\n  }\n\n  .flex-sm-shrink-1 {\n    flex-shrink: 1 !important;\n  }\n\n  .flex-sm-wrap {\n    flex-wrap: wrap !important;\n  }\n\n  .flex-sm-nowrap {\n    flex-wrap: nowrap !important;\n  }\n\n  .flex-sm-wrap-reverse {\n    flex-wrap: wrap-reverse !important;\n  }\n\n  .justify-content-sm-start {\n    justify-content: flex-start !important;\n  }\n\n  .justify-content-sm-end {\n    justify-content: flex-end !important;\n  }\n\n  .justify-content-sm-center {\n    justify-content: center !important;\n  }\n\n  .justify-content-sm-between {\n    justify-content: space-between !important;\n  }\n\n  .justify-content-sm-around {\n    justify-content: space-around !important;\n  }\n\n  .justify-content-sm-evenly {\n    justify-content: space-evenly !important;\n  }\n\n  .align-items-sm-start {\n    align-items: flex-start !important;\n  }\n\n  .align-items-sm-end {\n    align-items: flex-end !important;\n  }\n\n  .align-items-sm-center {\n    align-items: center !important;\n  }\n\n  .align-items-sm-baseline {\n    align-items: baseline !important;\n  }\n\n  .align-items-sm-stretch {\n    align-items: stretch !important;\n  }\n\n  .align-content-sm-start {\n    align-content: flex-start !important;\n  }\n\n  .align-content-sm-end {\n    align-content: flex-end !important;\n  }\n\n  .align-content-sm-center {\n    align-content: center !important;\n  }\n\n  .align-content-sm-between {\n    align-content: space-between !important;\n  }\n\n  .align-content-sm-around {\n    align-content: space-around !important;\n  }\n\n  .align-content-sm-stretch {\n    align-content: stretch !important;\n  }\n\n  .align-self-sm-auto {\n    align-self: auto !important;\n  }\n\n  .align-self-sm-start {\n    align-self: flex-start !important;\n  }\n\n  .align-self-sm-end {\n    align-self: flex-end !important;\n  }\n\n  .align-self-sm-center {\n    align-self: center !important;\n  }\n\n  .align-self-sm-baseline {\n    align-self: baseline !important;\n  }\n\n  .align-self-sm-stretch {\n    align-self: stretch !important;\n  }\n\n  .order-sm-first {\n    order: -1 !important;\n  }\n\n  .order-sm-0 {\n    order: 0 !important;\n  }\n\n  .order-sm-1 {\n    order: 1 !important;\n  }\n\n  .order-sm-2 {\n    order: 2 !important;\n  }\n\n  .order-sm-3 {\n    order: 3 !important;\n  }\n\n  .order-sm-4 {\n    order: 4 !important;\n  }\n\n  .order-sm-5 {\n    order: 5 !important;\n  }\n\n  .order-sm-last {\n    order: 6 !important;\n  }\n\n  .m-sm-0 {\n    margin: 0 !important;\n  }\n\n  .m-sm-1 {\n    margin: 0.25rem !important;\n  }\n\n  .m-sm-2 {\n    margin: 0.5rem !important;\n  }\n\n  .m-sm-3 {\n    margin: 1rem !important;\n  }\n\n  .m-sm-4 {\n    margin: 1.5rem !important;\n  }\n\n  .m-sm-5 {\n    margin: 3rem !important;\n  }\n\n  .m-sm-auto {\n    margin: auto !important;\n  }\n\n  .mx-sm-0 {\n    margin-left: 0 !important;\n    margin-right: 0 !important;\n  }\n\n  .mx-sm-1 {\n    margin-left: 0.25rem !important;\n    margin-right: 0.25rem !important;\n  }\n\n  .mx-sm-2 {\n    margin-left: 0.5rem !important;\n    margin-right: 0.5rem !important;\n  }\n\n  .mx-sm-3 {\n    margin-left: 1rem !important;\n    margin-right: 1rem !important;\n  }\n\n  .mx-sm-4 {\n    margin-left: 1.5rem !important;\n    margin-right: 1.5rem !important;\n  }\n\n  .mx-sm-5 {\n    margin-left: 3rem !important;\n    margin-right: 3rem !important;\n  }\n\n  .mx-sm-auto {\n    margin-left: auto !important;\n    margin-right: auto !important;\n  }\n\n  .my-sm-0 {\n    margin-top: 0 !important;\n    margin-bottom: 0 !important;\n  }\n\n  .my-sm-1 {\n    margin-top: 0.25rem !important;\n    margin-bottom: 0.25rem !important;\n  }\n\n  .my-sm-2 {\n    margin-top: 0.5rem !important;\n    margin-bottom: 0.5rem !important;\n  }\n\n  .my-sm-3 {\n    margin-top: 1rem !important;\n    margin-bottom: 1rem !important;\n  }\n\n  .my-sm-4 {\n    margin-top: 1.5rem !important;\n    margin-bottom: 1.5rem !important;\n  }\n\n  .my-sm-5 {\n    margin-top: 3rem !important;\n    margin-bottom: 3rem !important;\n  }\n\n  .my-sm-auto {\n    margin-top: auto !important;\n    margin-bottom: auto !important;\n  }\n\n  .mt-sm-0 {\n    margin-top: 0 !important;\n  }\n\n  .mt-sm-1 {\n    margin-top: 0.25rem !important;\n  }\n\n  .mt-sm-2 {\n    margin-top: 0.5rem !important;\n  }\n\n  .mt-sm-3 {\n    margin-top: 1rem !important;\n  }\n\n  .mt-sm-4 {\n    margin-top: 1.5rem !important;\n  }\n\n  .mt-sm-5 {\n    margin-top: 3rem !important;\n  }\n\n  .mt-sm-auto {\n    margin-top: auto !important;\n  }\n\n  .me-sm-0 {\n    margin-left: 0 !important;\n  }\n\n  .me-sm-1 {\n    margin-left: 0.25rem !important;\n  }\n\n  .me-sm-2 {\n    margin-left: 0.5rem !important;\n  }\n\n  .me-sm-3 {\n    margin-left: 1rem !important;\n  }\n\n  .me-sm-4 {\n    margin-left: 1.5rem !important;\n  }\n\n  .me-sm-5 {\n    margin-left: 3rem !important;\n  }\n\n  .me-sm-auto {\n    margin-left: auto !important;\n  }\n\n  .mb-sm-0 {\n    margin-bottom: 0 !important;\n  }\n\n  .mb-sm-1 {\n    margin-bottom: 0.25rem !important;\n  }\n\n  .mb-sm-2 {\n    margin-bottom: 0.5rem !important;\n  }\n\n  .mb-sm-3 {\n    margin-bottom: 1rem !important;\n  }\n\n  .mb-sm-4 {\n    margin-bottom: 1.5rem !important;\n  }\n\n  .mb-sm-5 {\n    margin-bottom: 3rem !important;\n  }\n\n  .mb-sm-auto {\n    margin-bottom: auto !important;\n  }\n\n  .ms-sm-0 {\n    margin-right: 0 !important;\n  }\n\n  .ms-sm-1 {\n    margin-right: 0.25rem !important;\n  }\n\n  .ms-sm-2 {\n    margin-right: 0.5rem !important;\n  }\n\n  .ms-sm-3 {\n    margin-right: 1rem !important;\n  }\n\n  .ms-sm-4 {\n    margin-right: 1.5rem !important;\n  }\n\n  .ms-sm-5 {\n    margin-right: 3rem !important;\n  }\n\n  .ms-sm-auto {\n    margin-right: auto !important;\n  }\n\n  .p-sm-0 {\n    padding: 0 !important;\n  }\n\n  .p-sm-1 {\n    padding: 0.25rem !important;\n  }\n\n  .p-sm-2 {\n    padding: 0.5rem !important;\n  }\n\n  .p-sm-3 {\n    padding: 1rem !important;\n  }\n\n  .p-sm-4 {\n    padding: 1.5rem !important;\n  }\n\n  .p-sm-5 {\n    padding: 3rem !important;\n  }\n\n  .px-sm-0 {\n    padding-left: 0 !important;\n    padding-right: 0 !important;\n  }\n\n  .px-sm-1 {\n    padding-left: 0.25rem !important;\n    padding-right: 0.25rem !important;\n  }\n\n  .px-sm-2 {\n    padding-left: 0.5rem !important;\n    padding-right: 0.5rem !important;\n  }\n\n  .px-sm-3 {\n    padding-left: 1rem !important;\n    padding-right: 1rem !important;\n  }\n\n  .px-sm-4 {\n    padding-left: 1.5rem !important;\n    padding-right: 1.5rem !important;\n  }\n\n  .px-sm-5 {\n    padding-left: 3rem !important;\n    padding-right: 3rem !important;\n  }\n\n  .py-sm-0 {\n    padding-top: 0 !important;\n    padding-bottom: 0 !important;\n  }\n\n  .py-sm-1 {\n    padding-top: 0.25rem !important;\n    padding-bottom: 0.25rem !important;\n  }\n\n  .py-sm-2 {\n    padding-top: 0.5rem !important;\n    padding-bottom: 0.5rem !important;\n  }\n\n  .py-sm-3 {\n    padding-top: 1rem !important;\n    padding-bottom: 1rem !important;\n  }\n\n  .py-sm-4 {\n    padding-top: 1.5rem !important;\n    padding-bottom: 1.5rem !important;\n  }\n\n  .py-sm-5 {\n    padding-top: 3rem !important;\n    padding-bottom: 3rem !important;\n  }\n\n  .pt-sm-0 {\n    padding-top: 0 !important;\n  }\n\n  .pt-sm-1 {\n    padding-top: 0.25rem !important;\n  }\n\n  .pt-sm-2 {\n    padding-top: 0.5rem !important;\n  }\n\n  .pt-sm-3 {\n    padding-top: 1rem !important;\n  }\n\n  .pt-sm-4 {\n    padding-top: 1.5rem !important;\n  }\n\n  .pt-sm-5 {\n    padding-top: 3rem !important;\n  }\n\n  .pe-sm-0 {\n    padding-left: 0 !important;\n  }\n\n  .pe-sm-1 {\n    padding-left: 0.25rem !important;\n  }\n\n  .pe-sm-2 {\n    padding-left: 0.5rem !important;\n  }\n\n  .pe-sm-3 {\n    padding-left: 1rem !important;\n  }\n\n  .pe-sm-4 {\n    padding-left: 1.5rem !important;\n  }\n\n  .pe-sm-5 {\n    padding-left: 3rem !important;\n  }\n\n  .pb-sm-0 {\n    padding-bottom: 0 !important;\n  }\n\n  .pb-sm-1 {\n    padding-bottom: 0.25rem !important;\n  }\n\n  .pb-sm-2 {\n    padding-bottom: 0.5rem !important;\n  }\n\n  .pb-sm-3 {\n    padding-bottom: 1rem !important;\n  }\n\n  .pb-sm-4 {\n    padding-bottom: 1.5rem !important;\n  }\n\n  .pb-sm-5 {\n    padding-bottom: 3rem !important;\n  }\n\n  .ps-sm-0 {\n    padding-right: 0 !important;\n  }\n\n  .ps-sm-1 {\n    padding-right: 0.25rem !important;\n  }\n\n  .ps-sm-2 {\n    padding-right: 0.5rem !important;\n  }\n\n  .ps-sm-3 {\n    padding-right: 1rem !important;\n  }\n\n  .ps-sm-4 {\n    padding-right: 1.5rem !important;\n  }\n\n  .ps-sm-5 {\n    padding-right: 3rem !important;\n  }\n}\n@media (min-width: 768px) {\n  .d-md-inline {\n    display: inline !important;\n  }\n\n  .d-md-inline-block {\n    display: inline-block !important;\n  }\n\n  .d-md-block {\n    display: block !important;\n  }\n\n  .d-md-grid {\n    display: grid !important;\n  }\n\n  .d-md-table {\n    display: table !important;\n  }\n\n  .d-md-table-row {\n    display: table-row !important;\n  }\n\n  .d-md-table-cell {\n    display: table-cell !important;\n  }\n\n  .d-md-flex {\n    display: flex !important;\n  }\n\n  .d-md-inline-flex {\n    display: inline-flex !important;\n  }\n\n  .d-md-none {\n    display: none !important;\n  }\n\n  .flex-md-fill {\n    flex: 1 1 auto !important;\n  }\n\n  .flex-md-row {\n    flex-direction: row !important;\n  }\n\n  .flex-md-column {\n    flex-direction: column !important;\n  }\n\n  .flex-md-row-reverse {\n    flex-direction: row-reverse !important;\n  }\n\n  .flex-md-column-reverse {\n    flex-direction: column-reverse !important;\n  }\n\n  .flex-md-grow-0 {\n    flex-grow: 0 !important;\n  }\n\n  .flex-md-grow-1 {\n    flex-grow: 1 !important;\n  }\n\n  .flex-md-shrink-0 {\n    flex-shrink: 0 !important;\n  }\n\n  .flex-md-shrink-1 {\n    flex-shrink: 1 !important;\n  }\n\n  .flex-md-wrap {\n    flex-wrap: wrap !important;\n  }\n\n  .flex-md-nowrap {\n    flex-wrap: nowrap !important;\n  }\n\n  .flex-md-wrap-reverse {\n    flex-wrap: wrap-reverse !important;\n  }\n\n  .justify-content-md-start {\n    justify-content: flex-start !important;\n  }\n\n  .justify-content-md-end {\n    justify-content: flex-end !important;\n  }\n\n  .justify-content-md-center {\n    justify-content: center !important;\n  }\n\n  .justify-content-md-between {\n    justify-content: space-between !important;\n  }\n\n  .justify-content-md-around {\n    justify-content: space-around !important;\n  }\n\n  .justify-content-md-evenly {\n    justify-content: space-evenly !important;\n  }\n\n  .align-items-md-start {\n    align-items: flex-start !important;\n  }\n\n  .align-items-md-end {\n    align-items: flex-end !important;\n  }\n\n  .align-items-md-center {\n    align-items: center !important;\n  }\n\n  .align-items-md-baseline {\n    align-items: baseline !important;\n  }\n\n  .align-items-md-stretch {\n    align-items: stretch !important;\n  }\n\n  .align-content-md-start {\n    align-content: flex-start !important;\n  }\n\n  .align-content-md-end {\n    align-content: flex-end !important;\n  }\n\n  .align-content-md-center {\n    align-content: center !important;\n  }\n\n  .align-content-md-between {\n    align-content: space-between !important;\n  }\n\n  .align-content-md-around {\n    align-content: space-around !important;\n  }\n\n  .align-content-md-stretch {\n    align-content: stretch !important;\n  }\n\n  .align-self-md-auto {\n    align-self: auto !important;\n  }\n\n  .align-self-md-start {\n    align-self: flex-start !important;\n  }\n\n  .align-self-md-end {\n    align-self: flex-end !important;\n  }\n\n  .align-self-md-center {\n    align-self: center !important;\n  }\n\n  .align-self-md-baseline {\n    align-self: baseline !important;\n  }\n\n  .align-self-md-stretch {\n    align-self: stretch !important;\n  }\n\n  .order-md-first {\n    order: -1 !important;\n  }\n\n  .order-md-0 {\n    order: 0 !important;\n  }\n\n  .order-md-1 {\n    order: 1 !important;\n  }\n\n  .order-md-2 {\n    order: 2 !important;\n  }\n\n  .order-md-3 {\n    order: 3 !important;\n  }\n\n  .order-md-4 {\n    order: 4 !important;\n  }\n\n  .order-md-5 {\n    order: 5 !important;\n  }\n\n  .order-md-last {\n    order: 6 !important;\n  }\n\n  .m-md-0 {\n    margin: 0 !important;\n  }\n\n  .m-md-1 {\n    margin: 0.25rem !important;\n  }\n\n  .m-md-2 {\n    margin: 0.5rem !important;\n  }\n\n  .m-md-3 {\n    margin: 1rem !important;\n  }\n\n  .m-md-4 {\n    margin: 1.5rem !important;\n  }\n\n  .m-md-5 {\n    margin: 3rem !important;\n  }\n\n  .m-md-auto {\n    margin: auto !important;\n  }\n\n  .mx-md-0 {\n    margin-left: 0 !important;\n    margin-right: 0 !important;\n  }\n\n  .mx-md-1 {\n    margin-left: 0.25rem !important;\n    margin-right: 0.25rem !important;\n  }\n\n  .mx-md-2 {\n    margin-left: 0.5rem !important;\n    margin-right: 0.5rem !important;\n  }\n\n  .mx-md-3 {\n    margin-left: 1rem !important;\n    margin-right: 1rem !important;\n  }\n\n  .mx-md-4 {\n    margin-left: 1.5rem !important;\n    margin-right: 1.5rem !important;\n  }\n\n  .mx-md-5 {\n    margin-left: 3rem !important;\n    margin-right: 3rem !important;\n  }\n\n  .mx-md-auto {\n    margin-left: auto !important;\n    margin-right: auto !important;\n  }\n\n  .my-md-0 {\n    margin-top: 0 !important;\n    margin-bottom: 0 !important;\n  }\n\n  .my-md-1 {\n    margin-top: 0.25rem !important;\n    margin-bottom: 0.25rem !important;\n  }\n\n  .my-md-2 {\n    margin-top: 0.5rem !important;\n    margin-bottom: 0.5rem !important;\n  }\n\n  .my-md-3 {\n    margin-top: 1rem !important;\n    margin-bottom: 1rem !important;\n  }\n\n  .my-md-4 {\n    margin-top: 1.5rem !important;\n    margin-bottom: 1.5rem !important;\n  }\n\n  .my-md-5 {\n    margin-top: 3rem !important;\n    margin-bottom: 3rem !important;\n  }\n\n  .my-md-auto {\n    margin-top: auto !important;\n    margin-bottom: auto !important;\n  }\n\n  .mt-md-0 {\n    margin-top: 0 !important;\n  }\n\n  .mt-md-1 {\n    margin-top: 0.25rem !important;\n  }\n\n  .mt-md-2 {\n    margin-top: 0.5rem !important;\n  }\n\n  .mt-md-3 {\n    margin-top: 1rem !important;\n  }\n\n  .mt-md-4 {\n    margin-top: 1.5rem !important;\n  }\n\n  .mt-md-5 {\n    margin-top: 3rem !important;\n  }\n\n  .mt-md-auto {\n    margin-top: auto !important;\n  }\n\n  .me-md-0 {\n    margin-left: 0 !important;\n  }\n\n  .me-md-1 {\n    margin-left: 0.25rem !important;\n  }\n\n  .me-md-2 {\n    margin-left: 0.5rem !important;\n  }\n\n  .me-md-3 {\n    margin-left: 1rem !important;\n  }\n\n  .me-md-4 {\n    margin-left: 1.5rem !important;\n  }\n\n  .me-md-5 {\n    margin-left: 3rem !important;\n  }\n\n  .me-md-auto {\n    margin-left: auto !important;\n  }\n\n  .mb-md-0 {\n    margin-bottom: 0 !important;\n  }\n\n  .mb-md-1 {\n    margin-bottom: 0.25rem !important;\n  }\n\n  .mb-md-2 {\n    margin-bottom: 0.5rem !important;\n  }\n\n  .mb-md-3 {\n    margin-bottom: 1rem !important;\n  }\n\n  .mb-md-4 {\n    margin-bottom: 1.5rem !important;\n  }\n\n  .mb-md-5 {\n    margin-bottom: 3rem !important;\n  }\n\n  .mb-md-auto {\n    margin-bottom: auto !important;\n  }\n\n  .ms-md-0 {\n    margin-right: 0 !important;\n  }\n\n  .ms-md-1 {\n    margin-right: 0.25rem !important;\n  }\n\n  .ms-md-2 {\n    margin-right: 0.5rem !important;\n  }\n\n  .ms-md-3 {\n    margin-right: 1rem !important;\n  }\n\n  .ms-md-4 {\n    margin-right: 1.5rem !important;\n  }\n\n  .ms-md-5 {\n    margin-right: 3rem !important;\n  }\n\n  .ms-md-auto {\n    margin-right: auto !important;\n  }\n\n  .p-md-0 {\n    padding: 0 !important;\n  }\n\n  .p-md-1 {\n    padding: 0.25rem !important;\n  }\n\n  .p-md-2 {\n    padding: 0.5rem !important;\n  }\n\n  .p-md-3 {\n    padding: 1rem !important;\n  }\n\n  .p-md-4 {\n    padding: 1.5rem !important;\n  }\n\n  .p-md-5 {\n    padding: 3rem !important;\n  }\n\n  .px-md-0 {\n    padding-left: 0 !important;\n    padding-right: 0 !important;\n  }\n\n  .px-md-1 {\n    padding-left: 0.25rem !important;\n    padding-right: 0.25rem !important;\n  }\n\n  .px-md-2 {\n    padding-left: 0.5rem !important;\n    padding-right: 0.5rem !important;\n  }\n\n  .px-md-3 {\n    padding-left: 1rem !important;\n    padding-right: 1rem !important;\n  }\n\n  .px-md-4 {\n    padding-left: 1.5rem !important;\n    padding-right: 1.5rem !important;\n  }\n\n  .px-md-5 {\n    padding-left: 3rem !important;\n    padding-right: 3rem !important;\n  }\n\n  .py-md-0 {\n    padding-top: 0 !important;\n    padding-bottom: 0 !important;\n  }\n\n  .py-md-1 {\n    padding-top: 0.25rem !important;\n    padding-bottom: 0.25rem !important;\n  }\n\n  .py-md-2 {\n    padding-top: 0.5rem !important;\n    padding-bottom: 0.5rem !important;\n  }\n\n  .py-md-3 {\n    padding-top: 1rem !important;\n    padding-bottom: 1rem !important;\n  }\n\n  .py-md-4 {\n    padding-top: 1.5rem !important;\n    padding-bottom: 1.5rem !important;\n  }\n\n  .py-md-5 {\n    padding-top: 3rem !important;\n    padding-bottom: 3rem !important;\n  }\n\n  .pt-md-0 {\n    padding-top: 0 !important;\n  }\n\n  .pt-md-1 {\n    padding-top: 0.25rem !important;\n  }\n\n  .pt-md-2 {\n    padding-top: 0.5rem !important;\n  }\n\n  .pt-md-3 {\n    padding-top: 1rem !important;\n  }\n\n  .pt-md-4 {\n    padding-top: 1.5rem !important;\n  }\n\n  .pt-md-5 {\n    padding-top: 3rem !important;\n  }\n\n  .pe-md-0 {\n    padding-left: 0 !important;\n  }\n\n  .pe-md-1 {\n    padding-left: 0.25rem !important;\n  }\n\n  .pe-md-2 {\n    padding-left: 0.5rem !important;\n  }\n\n  .pe-md-3 {\n    padding-left: 1rem !important;\n  }\n\n  .pe-md-4 {\n    padding-left: 1.5rem !important;\n  }\n\n  .pe-md-5 {\n    padding-left: 3rem !important;\n  }\n\n  .pb-md-0 {\n    padding-bottom: 0 !important;\n  }\n\n  .pb-md-1 {\n    padding-bottom: 0.25rem !important;\n  }\n\n  .pb-md-2 {\n    padding-bottom: 0.5rem !important;\n  }\n\n  .pb-md-3 {\n    padding-bottom: 1rem !important;\n  }\n\n  .pb-md-4 {\n    padding-bottom: 1.5rem !important;\n  }\n\n  .pb-md-5 {\n    padding-bottom: 3rem !important;\n  }\n\n  .ps-md-0 {\n    padding-right: 0 !important;\n  }\n\n  .ps-md-1 {\n    padding-right: 0.25rem !important;\n  }\n\n  .ps-md-2 {\n    padding-right: 0.5rem !important;\n  }\n\n  .ps-md-3 {\n    padding-right: 1rem !important;\n  }\n\n  .ps-md-4 {\n    padding-right: 1.5rem !important;\n  }\n\n  .ps-md-5 {\n    padding-right: 3rem !important;\n  }\n}\n@media (min-width: 992px) {\n  .d-lg-inline {\n    display: inline !important;\n  }\n\n  .d-lg-inline-block {\n    display: inline-block !important;\n  }\n\n  .d-lg-block {\n    display: block !important;\n  }\n\n  .d-lg-grid {\n    display: grid !important;\n  }\n\n  .d-lg-table {\n    display: table !important;\n  }\n\n  .d-lg-table-row {\n    display: table-row !important;\n  }\n\n  .d-lg-table-cell {\n    display: table-cell !important;\n  }\n\n  .d-lg-flex {\n    display: flex !important;\n  }\n\n  .d-lg-inline-flex {\n    display: inline-flex !important;\n  }\n\n  .d-lg-none {\n    display: none !important;\n  }\n\n  .flex-lg-fill {\n    flex: 1 1 auto !important;\n  }\n\n  .flex-lg-row {\n    flex-direction: row !important;\n  }\n\n  .flex-lg-column {\n    flex-direction: column !important;\n  }\n\n  .flex-lg-row-reverse {\n    flex-direction: row-reverse !important;\n  }\n\n  .flex-lg-column-reverse {\n    flex-direction: column-reverse !important;\n  }\n\n  .flex-lg-grow-0 {\n    flex-grow: 0 !important;\n  }\n\n  .flex-lg-grow-1 {\n    flex-grow: 1 !important;\n  }\n\n  .flex-lg-shrink-0 {\n    flex-shrink: 0 !important;\n  }\n\n  .flex-lg-shrink-1 {\n    flex-shrink: 1 !important;\n  }\n\n  .flex-lg-wrap {\n    flex-wrap: wrap !important;\n  }\n\n  .flex-lg-nowrap {\n    flex-wrap: nowrap !important;\n  }\n\n  .flex-lg-wrap-reverse {\n    flex-wrap: wrap-reverse !important;\n  }\n\n  .justify-content-lg-start {\n    justify-content: flex-start !important;\n  }\n\n  .justify-content-lg-end {\n    justify-content: flex-end !important;\n  }\n\n  .justify-content-lg-center {\n    justify-content: center !important;\n  }\n\n  .justify-content-lg-between {\n    justify-content: space-between !important;\n  }\n\n  .justify-content-lg-around {\n    justify-content: space-around !important;\n  }\n\n  .justify-content-lg-evenly {\n    justify-content: space-evenly !important;\n  }\n\n  .align-items-lg-start {\n    align-items: flex-start !important;\n  }\n\n  .align-items-lg-end {\n    align-items: flex-end !important;\n  }\n\n  .align-items-lg-center {\n    align-items: center !important;\n  }\n\n  .align-items-lg-baseline {\n    align-items: baseline !important;\n  }\n\n  .align-items-lg-stretch {\n    align-items: stretch !important;\n  }\n\n  .align-content-lg-start {\n    align-content: flex-start !important;\n  }\n\n  .align-content-lg-end {\n    align-content: flex-end !important;\n  }\n\n  .align-content-lg-center {\n    align-content: center !important;\n  }\n\n  .align-content-lg-between {\n    align-content: space-between !important;\n  }\n\n  .align-content-lg-around {\n    align-content: space-around !important;\n  }\n\n  .align-content-lg-stretch {\n    align-content: stretch !important;\n  }\n\n  .align-self-lg-auto {\n    align-self: auto !important;\n  }\n\n  .align-self-lg-start {\n    align-self: flex-start !important;\n  }\n\n  .align-self-lg-end {\n    align-self: flex-end !important;\n  }\n\n  .align-self-lg-center {\n    align-self: center !important;\n  }\n\n  .align-self-lg-baseline {\n    align-self: baseline !important;\n  }\n\n  .align-self-lg-stretch {\n    align-self: stretch !important;\n  }\n\n  .order-lg-first {\n    order: -1 !important;\n  }\n\n  .order-lg-0 {\n    order: 0 !important;\n  }\n\n  .order-lg-1 {\n    order: 1 !important;\n  }\n\n  .order-lg-2 {\n    order: 2 !important;\n  }\n\n  .order-lg-3 {\n    order: 3 !important;\n  }\n\n  .order-lg-4 {\n    order: 4 !important;\n  }\n\n  .order-lg-5 {\n    order: 5 !important;\n  }\n\n  .order-lg-last {\n    order: 6 !important;\n  }\n\n  .m-lg-0 {\n    margin: 0 !important;\n  }\n\n  .m-lg-1 {\n    margin: 0.25rem !important;\n  }\n\n  .m-lg-2 {\n    margin: 0.5rem !important;\n  }\n\n  .m-lg-3 {\n    margin: 1rem !important;\n  }\n\n  .m-lg-4 {\n    margin: 1.5rem !important;\n  }\n\n  .m-lg-5 {\n    margin: 3rem !important;\n  }\n\n  .m-lg-auto {\n    margin: auto !important;\n  }\n\n  .mx-lg-0 {\n    margin-left: 0 !important;\n    margin-right: 0 !important;\n  }\n\n  .mx-lg-1 {\n    margin-left: 0.25rem !important;\n    margin-right: 0.25rem !important;\n  }\n\n  .mx-lg-2 {\n    margin-left: 0.5rem !important;\n    margin-right: 0.5rem !important;\n  }\n\n  .mx-lg-3 {\n    margin-left: 1rem !important;\n    margin-right: 1rem !important;\n  }\n\n  .mx-lg-4 {\n    margin-left: 1.5rem !important;\n    margin-right: 1.5rem !important;\n  }\n\n  .mx-lg-5 {\n    margin-left: 3rem !important;\n    margin-right: 3rem !important;\n  }\n\n  .mx-lg-auto {\n    margin-left: auto !important;\n    margin-right: auto !important;\n  }\n\n  .my-lg-0 {\n    margin-top: 0 !important;\n    margin-bottom: 0 !important;\n  }\n\n  .my-lg-1 {\n    margin-top: 0.25rem !important;\n    margin-bottom: 0.25rem !important;\n  }\n\n  .my-lg-2 {\n    margin-top: 0.5rem !important;\n    margin-bottom: 0.5rem !important;\n  }\n\n  .my-lg-3 {\n    margin-top: 1rem !important;\n    margin-bottom: 1rem !important;\n  }\n\n  .my-lg-4 {\n    margin-top: 1.5rem !important;\n    margin-bottom: 1.5rem !important;\n  }\n\n  .my-lg-5 {\n    margin-top: 3rem !important;\n    margin-bottom: 3rem !important;\n  }\n\n  .my-lg-auto {\n    margin-top: auto !important;\n    margin-bottom: auto !important;\n  }\n\n  .mt-lg-0 {\n    margin-top: 0 !important;\n  }\n\n  .mt-lg-1 {\n    margin-top: 0.25rem !important;\n  }\n\n  .mt-lg-2 {\n    margin-top: 0.5rem !important;\n  }\n\n  .mt-lg-3 {\n    margin-top: 1rem !important;\n  }\n\n  .mt-lg-4 {\n    margin-top: 1.5rem !important;\n  }\n\n  .mt-lg-5 {\n    margin-top: 3rem !important;\n  }\n\n  .mt-lg-auto {\n    margin-top: auto !important;\n  }\n\n  .me-lg-0 {\n    margin-left: 0 !important;\n  }\n\n  .me-lg-1 {\n    margin-left: 0.25rem !important;\n  }\n\n  .me-lg-2 {\n    margin-left: 0.5rem !important;\n  }\n\n  .me-lg-3 {\n    margin-left: 1rem !important;\n  }\n\n  .me-lg-4 {\n    margin-left: 1.5rem !important;\n  }\n\n  .me-lg-5 {\n    margin-left: 3rem !important;\n  }\n\n  .me-lg-auto {\n    margin-left: auto !important;\n  }\n\n  .mb-lg-0 {\n    margin-bottom: 0 !important;\n  }\n\n  .mb-lg-1 {\n    margin-bottom: 0.25rem !important;\n  }\n\n  .mb-lg-2 {\n    margin-bottom: 0.5rem !important;\n  }\n\n  .mb-lg-3 {\n    margin-bottom: 1rem !important;\n  }\n\n  .mb-lg-4 {\n    margin-bottom: 1.5rem !important;\n  }\n\n  .mb-lg-5 {\n    margin-bottom: 3rem !important;\n  }\n\n  .mb-lg-auto {\n    margin-bottom: auto !important;\n  }\n\n  .ms-lg-0 {\n    margin-right: 0 !important;\n  }\n\n  .ms-lg-1 {\n    margin-right: 0.25rem !important;\n  }\n\n  .ms-lg-2 {\n    margin-right: 0.5rem !important;\n  }\n\n  .ms-lg-3 {\n    margin-right: 1rem !important;\n  }\n\n  .ms-lg-4 {\n    margin-right: 1.5rem !important;\n  }\n\n  .ms-lg-5 {\n    margin-right: 3rem !important;\n  }\n\n  .ms-lg-auto {\n    margin-right: auto !important;\n  }\n\n  .p-lg-0 {\n    padding: 0 !important;\n  }\n\n  .p-lg-1 {\n    padding: 0.25rem !important;\n  }\n\n  .p-lg-2 {\n    padding: 0.5rem !important;\n  }\n\n  .p-lg-3 {\n    padding: 1rem !important;\n  }\n\n  .p-lg-4 {\n    padding: 1.5rem !important;\n  }\n\n  .p-lg-5 {\n    padding: 3rem !important;\n  }\n\n  .px-lg-0 {\n    padding-left: 0 !important;\n    padding-right: 0 !important;\n  }\n\n  .px-lg-1 {\n    padding-left: 0.25rem !important;\n    padding-right: 0.25rem !important;\n  }\n\n  .px-lg-2 {\n    padding-left: 0.5rem !important;\n    padding-right: 0.5rem !important;\n  }\n\n  .px-lg-3 {\n    padding-left: 1rem !important;\n    padding-right: 1rem !important;\n  }\n\n  .px-lg-4 {\n    padding-left: 1.5rem !important;\n    padding-right: 1.5rem !important;\n  }\n\n  .px-lg-5 {\n    padding-left: 3rem !important;\n    padding-right: 3rem !important;\n  }\n\n  .py-lg-0 {\n    padding-top: 0 !important;\n    padding-bottom: 0 !important;\n  }\n\n  .py-lg-1 {\n    padding-top: 0.25rem !important;\n    padding-bottom: 0.25rem !important;\n  }\n\n  .py-lg-2 {\n    padding-top: 0.5rem !important;\n    padding-bottom: 0.5rem !important;\n  }\n\n  .py-lg-3 {\n    padding-top: 1rem !important;\n    padding-bottom: 1rem !important;\n  }\n\n  .py-lg-4 {\n    padding-top: 1.5rem !important;\n    padding-bottom: 1.5rem !important;\n  }\n\n  .py-lg-5 {\n    padding-top: 3rem !important;\n    padding-bottom: 3rem !important;\n  }\n\n  .pt-lg-0 {\n    padding-top: 0 !important;\n  }\n\n  .pt-lg-1 {\n    padding-top: 0.25rem !important;\n  }\n\n  .pt-lg-2 {\n    padding-top: 0.5rem !important;\n  }\n\n  .pt-lg-3 {\n    padding-top: 1rem !important;\n  }\n\n  .pt-lg-4 {\n    padding-top: 1.5rem !important;\n  }\n\n  .pt-lg-5 {\n    padding-top: 3rem !important;\n  }\n\n  .pe-lg-0 {\n    padding-left: 0 !important;\n  }\n\n  .pe-lg-1 {\n    padding-left: 0.25rem !important;\n  }\n\n  .pe-lg-2 {\n    padding-left: 0.5rem !important;\n  }\n\n  .pe-lg-3 {\n    padding-left: 1rem !important;\n  }\n\n  .pe-lg-4 {\n    padding-left: 1.5rem !important;\n  }\n\n  .pe-lg-5 {\n    padding-left: 3rem !important;\n  }\n\n  .pb-lg-0 {\n    padding-bottom: 0 !important;\n  }\n\n  .pb-lg-1 {\n    padding-bottom: 0.25rem !important;\n  }\n\n  .pb-lg-2 {\n    padding-bottom: 0.5rem !important;\n  }\n\n  .pb-lg-3 {\n    padding-bottom: 1rem !important;\n  }\n\n  .pb-lg-4 {\n    padding-bottom: 1.5rem !important;\n  }\n\n  .pb-lg-5 {\n    padding-bottom: 3rem !important;\n  }\n\n  .ps-lg-0 {\n    padding-right: 0 !important;\n  }\n\n  .ps-lg-1 {\n    padding-right: 0.25rem !important;\n  }\n\n  .ps-lg-2 {\n    padding-right: 0.5rem !important;\n  }\n\n  .ps-lg-3 {\n    padding-right: 1rem !important;\n  }\n\n  .ps-lg-4 {\n    padding-right: 1.5rem !important;\n  }\n\n  .ps-lg-5 {\n    padding-right: 3rem !important;\n  }\n}\n@media (min-width: 1200px) {\n  .d-xl-inline {\n    display: inline !important;\n  }\n\n  .d-xl-inline-block {\n    display: inline-block !important;\n  }\n\n  .d-xl-block {\n    display: block !important;\n  }\n\n  .d-xl-grid {\n    display: grid !important;\n  }\n\n  .d-xl-table {\n    display: table !important;\n  }\n\n  .d-xl-table-row {\n    display: table-row !important;\n  }\n\n  .d-xl-table-cell {\n    display: table-cell !important;\n  }\n\n  .d-xl-flex {\n    display: flex !important;\n  }\n\n  .d-xl-inline-flex {\n    display: inline-flex !important;\n  }\n\n  .d-xl-none {\n    display: none !important;\n  }\n\n  .flex-xl-fill {\n    flex: 1 1 auto !important;\n  }\n\n  .flex-xl-row {\n    flex-direction: row !important;\n  }\n\n  .flex-xl-column {\n    flex-direction: column !important;\n  }\n\n  .flex-xl-row-reverse {\n    flex-direction: row-reverse !important;\n  }\n\n  .flex-xl-column-reverse {\n    flex-direction: column-reverse !important;\n  }\n\n  .flex-xl-grow-0 {\n    flex-grow: 0 !important;\n  }\n\n  .flex-xl-grow-1 {\n    flex-grow: 1 !important;\n  }\n\n  .flex-xl-shrink-0 {\n    flex-shrink: 0 !important;\n  }\n\n  .flex-xl-shrink-1 {\n    flex-shrink: 1 !important;\n  }\n\n  .flex-xl-wrap {\n    flex-wrap: wrap !important;\n  }\n\n  .flex-xl-nowrap {\n    flex-wrap: nowrap !important;\n  }\n\n  .flex-xl-wrap-reverse {\n    flex-wrap: wrap-reverse !important;\n  }\n\n  .justify-content-xl-start {\n    justify-content: flex-start !important;\n  }\n\n  .justify-content-xl-end {\n    justify-content: flex-end !important;\n  }\n\n  .justify-content-xl-center {\n    justify-content: center !important;\n  }\n\n  .justify-content-xl-between {\n    justify-content: space-between !important;\n  }\n\n  .justify-content-xl-around {\n    justify-content: space-around !important;\n  }\n\n  .justify-content-xl-evenly {\n    justify-content: space-evenly !important;\n  }\n\n  .align-items-xl-start {\n    align-items: flex-start !important;\n  }\n\n  .align-items-xl-end {\n    align-items: flex-end !important;\n  }\n\n  .align-items-xl-center {\n    align-items: center !important;\n  }\n\n  .align-items-xl-baseline {\n    align-items: baseline !important;\n  }\n\n  .align-items-xl-stretch {\n    align-items: stretch !important;\n  }\n\n  .align-content-xl-start {\n    align-content: flex-start !important;\n  }\n\n  .align-content-xl-end {\n    align-content: flex-end !important;\n  }\n\n  .align-content-xl-center {\n    align-content: center !important;\n  }\n\n  .align-content-xl-between {\n    align-content: space-between !important;\n  }\n\n  .align-content-xl-around {\n    align-content: space-around !important;\n  }\n\n  .align-content-xl-stretch {\n    align-content: stretch !important;\n  }\n\n  .align-self-xl-auto {\n    align-self: auto !important;\n  }\n\n  .align-self-xl-start {\n    align-self: flex-start !important;\n  }\n\n  .align-self-xl-end {\n    align-self: flex-end !important;\n  }\n\n  .align-self-xl-center {\n    align-self: center !important;\n  }\n\n  .align-self-xl-baseline {\n    align-self: baseline !important;\n  }\n\n  .align-self-xl-stretch {\n    align-self: stretch !important;\n  }\n\n  .order-xl-first {\n    order: -1 !important;\n  }\n\n  .order-xl-0 {\n    order: 0 !important;\n  }\n\n  .order-xl-1 {\n    order: 1 !important;\n  }\n\n  .order-xl-2 {\n    order: 2 !important;\n  }\n\n  .order-xl-3 {\n    order: 3 !important;\n  }\n\n  .order-xl-4 {\n    order: 4 !important;\n  }\n\n  .order-xl-5 {\n    order: 5 !important;\n  }\n\n  .order-xl-last {\n    order: 6 !important;\n  }\n\n  .m-xl-0 {\n    margin: 0 !important;\n  }\n\n  .m-xl-1 {\n    margin: 0.25rem !important;\n  }\n\n  .m-xl-2 {\n    margin: 0.5rem !important;\n  }\n\n  .m-xl-3 {\n    margin: 1rem !important;\n  }\n\n  .m-xl-4 {\n    margin: 1.5rem !important;\n  }\n\n  .m-xl-5 {\n    margin: 3rem !important;\n  }\n\n  .m-xl-auto {\n    margin: auto !important;\n  }\n\n  .mx-xl-0 {\n    margin-left: 0 !important;\n    margin-right: 0 !important;\n  }\n\n  .mx-xl-1 {\n    margin-left: 0.25rem !important;\n    margin-right: 0.25rem !important;\n  }\n\n  .mx-xl-2 {\n    margin-left: 0.5rem !important;\n    margin-right: 0.5rem !important;\n  }\n\n  .mx-xl-3 {\n    margin-left: 1rem !important;\n    margin-right: 1rem !important;\n  }\n\n  .mx-xl-4 {\n    margin-left: 1.5rem !important;\n    margin-right: 1.5rem !important;\n  }\n\n  .mx-xl-5 {\n    margin-left: 3rem !important;\n    margin-right: 3rem !important;\n  }\n\n  .mx-xl-auto {\n    margin-left: auto !important;\n    margin-right: auto !important;\n  }\n\n  .my-xl-0 {\n    margin-top: 0 !important;\n    margin-bottom: 0 !important;\n  }\n\n  .my-xl-1 {\n    margin-top: 0.25rem !important;\n    margin-bottom: 0.25rem !important;\n  }\n\n  .my-xl-2 {\n    margin-top: 0.5rem !important;\n    margin-bottom: 0.5rem !important;\n  }\n\n  .my-xl-3 {\n    margin-top: 1rem !important;\n    margin-bottom: 1rem !important;\n  }\n\n  .my-xl-4 {\n    margin-top: 1.5rem !important;\n    margin-bottom: 1.5rem !important;\n  }\n\n  .my-xl-5 {\n    margin-top: 3rem !important;\n    margin-bottom: 3rem !important;\n  }\n\n  .my-xl-auto {\n    margin-top: auto !important;\n    margin-bottom: auto !important;\n  }\n\n  .mt-xl-0 {\n    margin-top: 0 !important;\n  }\n\n  .mt-xl-1 {\n    margin-top: 0.25rem !important;\n  }\n\n  .mt-xl-2 {\n    margin-top: 0.5rem !important;\n  }\n\n  .mt-xl-3 {\n    margin-top: 1rem !important;\n  }\n\n  .mt-xl-4 {\n    margin-top: 1.5rem !important;\n  }\n\n  .mt-xl-5 {\n    margin-top: 3rem !important;\n  }\n\n  .mt-xl-auto {\n    margin-top: auto !important;\n  }\n\n  .me-xl-0 {\n    margin-left: 0 !important;\n  }\n\n  .me-xl-1 {\n    margin-left: 0.25rem !important;\n  }\n\n  .me-xl-2 {\n    margin-left: 0.5rem !important;\n  }\n\n  .me-xl-3 {\n    margin-left: 1rem !important;\n  }\n\n  .me-xl-4 {\n    margin-left: 1.5rem !important;\n  }\n\n  .me-xl-5 {\n    margin-left: 3rem !important;\n  }\n\n  .me-xl-auto {\n    margin-left: auto !important;\n  }\n\n  .mb-xl-0 {\n    margin-bottom: 0 !important;\n  }\n\n  .mb-xl-1 {\n    margin-bottom: 0.25rem !important;\n  }\n\n  .mb-xl-2 {\n    margin-bottom: 0.5rem !important;\n  }\n\n  .mb-xl-3 {\n    margin-bottom: 1rem !important;\n  }\n\n  .mb-xl-4 {\n    margin-bottom: 1.5rem !important;\n  }\n\n  .mb-xl-5 {\n    margin-bottom: 3rem !important;\n  }\n\n  .mb-xl-auto {\n    margin-bottom: auto !important;\n  }\n\n  .ms-xl-0 {\n    margin-right: 0 !important;\n  }\n\n  .ms-xl-1 {\n    margin-right: 0.25rem !important;\n  }\n\n  .ms-xl-2 {\n    margin-right: 0.5rem !important;\n  }\n\n  .ms-xl-3 {\n    margin-right: 1rem !important;\n  }\n\n  .ms-xl-4 {\n    margin-right: 1.5rem !important;\n  }\n\n  .ms-xl-5 {\n    margin-right: 3rem !important;\n  }\n\n  .ms-xl-auto {\n    margin-right: auto !important;\n  }\n\n  .p-xl-0 {\n    padding: 0 !important;\n  }\n\n  .p-xl-1 {\n    padding: 0.25rem !important;\n  }\n\n  .p-xl-2 {\n    padding: 0.5rem !important;\n  }\n\n  .p-xl-3 {\n    padding: 1rem !important;\n  }\n\n  .p-xl-4 {\n    padding: 1.5rem !important;\n  }\n\n  .p-xl-5 {\n    padding: 3rem !important;\n  }\n\n  .px-xl-0 {\n    padding-left: 0 !important;\n    padding-right: 0 !important;\n  }\n\n  .px-xl-1 {\n    padding-left: 0.25rem !important;\n    padding-right: 0.25rem !important;\n  }\n\n  .px-xl-2 {\n    padding-left: 0.5rem !important;\n    padding-right: 0.5rem !important;\n  }\n\n  .px-xl-3 {\n    padding-left: 1rem !important;\n    padding-right: 1rem !important;\n  }\n\n  .px-xl-4 {\n    padding-left: 1.5rem !important;\n    padding-right: 1.5rem !important;\n  }\n\n  .px-xl-5 {\n    padding-left: 3rem !important;\n    padding-right: 3rem !important;\n  }\n\n  .py-xl-0 {\n    padding-top: 0 !important;\n    padding-bottom: 0 !important;\n  }\n\n  .py-xl-1 {\n    padding-top: 0.25rem !important;\n    padding-bottom: 0.25rem !important;\n  }\n\n  .py-xl-2 {\n    padding-top: 0.5rem !important;\n    padding-bottom: 0.5rem !important;\n  }\n\n  .py-xl-3 {\n    padding-top: 1rem !important;\n    padding-bottom: 1rem !important;\n  }\n\n  .py-xl-4 {\n    padding-top: 1.5rem !important;\n    padding-bottom: 1.5rem !important;\n  }\n\n  .py-xl-5 {\n    padding-top: 3rem !important;\n    padding-bottom: 3rem !important;\n  }\n\n  .pt-xl-0 {\n    padding-top: 0 !important;\n  }\n\n  .pt-xl-1 {\n    padding-top: 0.25rem !important;\n  }\n\n  .pt-xl-2 {\n    padding-top: 0.5rem !important;\n  }\n\n  .pt-xl-3 {\n    padding-top: 1rem !important;\n  }\n\n  .pt-xl-4 {\n    padding-top: 1.5rem !important;\n  }\n\n  .pt-xl-5 {\n    padding-top: 3rem !important;\n  }\n\n  .pe-xl-0 {\n    padding-left: 0 !important;\n  }\n\n  .pe-xl-1 {\n    padding-left: 0.25rem !important;\n  }\n\n  .pe-xl-2 {\n    padding-left: 0.5rem !important;\n  }\n\n  .pe-xl-3 {\n    padding-left: 1rem !important;\n  }\n\n  .pe-xl-4 {\n    padding-left: 1.5rem !important;\n  }\n\n  .pe-xl-5 {\n    padding-left: 3rem !important;\n  }\n\n  .pb-xl-0 {\n    padding-bottom: 0 !important;\n  }\n\n  .pb-xl-1 {\n    padding-bottom: 0.25rem !important;\n  }\n\n  .pb-xl-2 {\n    padding-bottom: 0.5rem !important;\n  }\n\n  .pb-xl-3 {\n    padding-bottom: 1rem !important;\n  }\n\n  .pb-xl-4 {\n    padding-bottom: 1.5rem !important;\n  }\n\n  .pb-xl-5 {\n    padding-bottom: 3rem !important;\n  }\n\n  .ps-xl-0 {\n    padding-right: 0 !important;\n  }\n\n  .ps-xl-1 {\n    padding-right: 0.25rem !important;\n  }\n\n  .ps-xl-2 {\n    padding-right: 0.5rem !important;\n  }\n\n  .ps-xl-3 {\n    padding-right: 1rem !important;\n  }\n\n  .ps-xl-4 {\n    padding-right: 1.5rem !important;\n  }\n\n  .ps-xl-5 {\n    padding-right: 3rem !important;\n  }\n}\n@media (min-width: 1400px) {\n  .d-xxl-inline {\n    display: inline !important;\n  }\n\n  .d-xxl-inline-block {\n    display: inline-block !important;\n  }\n\n  .d-xxl-block {\n    display: block !important;\n  }\n\n  .d-xxl-grid {\n    display: grid !important;\n  }\n\n  .d-xxl-table {\n    display: table !important;\n  }\n\n  .d-xxl-table-row {\n    display: table-row !important;\n  }\n\n  .d-xxl-table-cell {\n    display: table-cell !important;\n  }\n\n  .d-xxl-flex {\n    display: flex !important;\n  }\n\n  .d-xxl-inline-flex {\n    display: inline-flex !important;\n  }\n\n  .d-xxl-none {\n    display: none !important;\n  }\n\n  .flex-xxl-fill {\n    flex: 1 1 auto !important;\n  }\n\n  .flex-xxl-row {\n    flex-direction: row !important;\n  }\n\n  .flex-xxl-column {\n    flex-direction: column !important;\n  }\n\n  .flex-xxl-row-reverse {\n    flex-direction: row-reverse !important;\n  }\n\n  .flex-xxl-column-reverse {\n    flex-direction: column-reverse !important;\n  }\n\n  .flex-xxl-grow-0 {\n    flex-grow: 0 !important;\n  }\n\n  .flex-xxl-grow-1 {\n    flex-grow: 1 !important;\n  }\n\n  .flex-xxl-shrink-0 {\n    flex-shrink: 0 !important;\n  }\n\n  .flex-xxl-shrink-1 {\n    flex-shrink: 1 !important;\n  }\n\n  .flex-xxl-wrap {\n    flex-wrap: wrap !important;\n  }\n\n  .flex-xxl-nowrap {\n    flex-wrap: nowrap !important;\n  }\n\n  .flex-xxl-wrap-reverse {\n    flex-wrap: wrap-reverse !important;\n  }\n\n  .justify-content-xxl-start {\n    justify-content: flex-start !important;\n  }\n\n  .justify-content-xxl-end {\n    justify-content: flex-end !important;\n  }\n\n  .justify-content-xxl-center {\n    justify-content: center !important;\n  }\n\n  .justify-content-xxl-between {\n    justify-content: space-between !important;\n  }\n\n  .justify-content-xxl-around {\n    justify-content: space-around !important;\n  }\n\n  .justify-content-xxl-evenly {\n    justify-content: space-evenly !important;\n  }\n\n  .align-items-xxl-start {\n    align-items: flex-start !important;\n  }\n\n  .align-items-xxl-end {\n    align-items: flex-end !important;\n  }\n\n  .align-items-xxl-center {\n    align-items: center !important;\n  }\n\n  .align-items-xxl-baseline {\n    align-items: baseline !important;\n  }\n\n  .align-items-xxl-stretch {\n    align-items: stretch !important;\n  }\n\n  .align-content-xxl-start {\n    align-content: flex-start !important;\n  }\n\n  .align-content-xxl-end {\n    align-content: flex-end !important;\n  }\n\n  .align-content-xxl-center {\n    align-content: center !important;\n  }\n\n  .align-content-xxl-between {\n    align-content: space-between !important;\n  }\n\n  .align-content-xxl-around {\n    align-content: space-around !important;\n  }\n\n  .align-content-xxl-stretch {\n    align-content: stretch !important;\n  }\n\n  .align-self-xxl-auto {\n    align-self: auto !important;\n  }\n\n  .align-self-xxl-start {\n    align-self: flex-start !important;\n  }\n\n  .align-self-xxl-end {\n    align-self: flex-end !important;\n  }\n\n  .align-self-xxl-center {\n    align-self: center !important;\n  }\n\n  .align-self-xxl-baseline {\n    align-self: baseline !important;\n  }\n\n  .align-self-xxl-stretch {\n    align-self: stretch !important;\n  }\n\n  .order-xxl-first {\n    order: -1 !important;\n  }\n\n  .order-xxl-0 {\n    order: 0 !important;\n  }\n\n  .order-xxl-1 {\n    order: 1 !important;\n  }\n\n  .order-xxl-2 {\n    order: 2 !important;\n  }\n\n  .order-xxl-3 {\n    order: 3 !important;\n  }\n\n  .order-xxl-4 {\n    order: 4 !important;\n  }\n\n  .order-xxl-5 {\n    order: 5 !important;\n  }\n\n  .order-xxl-last {\n    order: 6 !important;\n  }\n\n  .m-xxl-0 {\n    margin: 0 !important;\n  }\n\n  .m-xxl-1 {\n    margin: 0.25rem !important;\n  }\n\n  .m-xxl-2 {\n    margin: 0.5rem !important;\n  }\n\n  .m-xxl-3 {\n    margin: 1rem !important;\n  }\n\n  .m-xxl-4 {\n    margin: 1.5rem !important;\n  }\n\n  .m-xxl-5 {\n    margin: 3rem !important;\n  }\n\n  .m-xxl-auto {\n    margin: auto !important;\n  }\n\n  .mx-xxl-0 {\n    margin-left: 0 !important;\n    margin-right: 0 !important;\n  }\n\n  .mx-xxl-1 {\n    margin-left: 0.25rem !important;\n    margin-right: 0.25rem !important;\n  }\n\n  .mx-xxl-2 {\n    margin-left: 0.5rem !important;\n    margin-right: 0.5rem !important;\n  }\n\n  .mx-xxl-3 {\n    margin-left: 1rem !important;\n    margin-right: 1rem !important;\n  }\n\n  .mx-xxl-4 {\n    margin-left: 1.5rem !important;\n    margin-right: 1.5rem !important;\n  }\n\n  .mx-xxl-5 {\n    margin-left: 3rem !important;\n    margin-right: 3rem !important;\n  }\n\n  .mx-xxl-auto {\n    margin-left: auto !important;\n    margin-right: auto !important;\n  }\n\n  .my-xxl-0 {\n    margin-top: 0 !important;\n    margin-bottom: 0 !important;\n  }\n\n  .my-xxl-1 {\n    margin-top: 0.25rem !important;\n    margin-bottom: 0.25rem !important;\n  }\n\n  .my-xxl-2 {\n    margin-top: 0.5rem !important;\n    margin-bottom: 0.5rem !important;\n  }\n\n  .my-xxl-3 {\n    margin-top: 1rem !important;\n    margin-bottom: 1rem !important;\n  }\n\n  .my-xxl-4 {\n    margin-top: 1.5rem !important;\n    margin-bottom: 1.5rem !important;\n  }\n\n  .my-xxl-5 {\n    margin-top: 3rem !important;\n    margin-bottom: 3rem !important;\n  }\n\n  .my-xxl-auto {\n    margin-top: auto !important;\n    margin-bottom: auto !important;\n  }\n\n  .mt-xxl-0 {\n    margin-top: 0 !important;\n  }\n\n  .mt-xxl-1 {\n    margin-top: 0.25rem !important;\n  }\n\n  .mt-xxl-2 {\n    margin-top: 0.5rem !important;\n  }\n\n  .mt-xxl-3 {\n    margin-top: 1rem !important;\n  }\n\n  .mt-xxl-4 {\n    margin-top: 1.5rem !important;\n  }\n\n  .mt-xxl-5 {\n    margin-top: 3rem !important;\n  }\n\n  .mt-xxl-auto {\n    margin-top: auto !important;\n  }\n\n  .me-xxl-0 {\n    margin-left: 0 !important;\n  }\n\n  .me-xxl-1 {\n    margin-left: 0.25rem !important;\n  }\n\n  .me-xxl-2 {\n    margin-left: 0.5rem !important;\n  }\n\n  .me-xxl-3 {\n    margin-left: 1rem !important;\n  }\n\n  .me-xxl-4 {\n    margin-left: 1.5rem !important;\n  }\n\n  .me-xxl-5 {\n    margin-left: 3rem !important;\n  }\n\n  .me-xxl-auto {\n    margin-left: auto !important;\n  }\n\n  .mb-xxl-0 {\n    margin-bottom: 0 !important;\n  }\n\n  .mb-xxl-1 {\n    margin-bottom: 0.25rem !important;\n  }\n\n  .mb-xxl-2 {\n    margin-bottom: 0.5rem !important;\n  }\n\n  .mb-xxl-3 {\n    margin-bottom: 1rem !important;\n  }\n\n  .mb-xxl-4 {\n    margin-bottom: 1.5rem !important;\n  }\n\n  .mb-xxl-5 {\n    margin-bottom: 3rem !important;\n  }\n\n  .mb-xxl-auto {\n    margin-bottom: auto !important;\n  }\n\n  .ms-xxl-0 {\n    margin-right: 0 !important;\n  }\n\n  .ms-xxl-1 {\n    margin-right: 0.25rem !important;\n  }\n\n  .ms-xxl-2 {\n    margin-right: 0.5rem !important;\n  }\n\n  .ms-xxl-3 {\n    margin-right: 1rem !important;\n  }\n\n  .ms-xxl-4 {\n    margin-right: 1.5rem !important;\n  }\n\n  .ms-xxl-5 {\n    margin-right: 3rem !important;\n  }\n\n  .ms-xxl-auto {\n    margin-right: auto !important;\n  }\n\n  .p-xxl-0 {\n    padding: 0 !important;\n  }\n\n  .p-xxl-1 {\n    padding: 0.25rem !important;\n  }\n\n  .p-xxl-2 {\n    padding: 0.5rem !important;\n  }\n\n  .p-xxl-3 {\n    padding: 1rem !important;\n  }\n\n  .p-xxl-4 {\n    padding: 1.5rem !important;\n  }\n\n  .p-xxl-5 {\n    padding: 3rem !important;\n  }\n\n  .px-xxl-0 {\n    padding-left: 0 !important;\n    padding-right: 0 !important;\n  }\n\n  .px-xxl-1 {\n    padding-left: 0.25rem !important;\n    padding-right: 0.25rem !important;\n  }\n\n  .px-xxl-2 {\n    padding-left: 0.5rem !important;\n    padding-right: 0.5rem !important;\n  }\n\n  .px-xxl-3 {\n    padding-left: 1rem !important;\n    padding-right: 1rem !important;\n  }\n\n  .px-xxl-4 {\n    padding-left: 1.5rem !important;\n    padding-right: 1.5rem !important;\n  }\n\n  .px-xxl-5 {\n    padding-left: 3rem !important;\n    padding-right: 3rem !important;\n  }\n\n  .py-xxl-0 {\n    padding-top: 0 !important;\n    padding-bottom: 0 !important;\n  }\n\n  .py-xxl-1 {\n    padding-top: 0.25rem !important;\n    padding-bottom: 0.25rem !important;\n  }\n\n  .py-xxl-2 {\n    padding-top: 0.5rem !important;\n    padding-bottom: 0.5rem !important;\n  }\n\n  .py-xxl-3 {\n    padding-top: 1rem !important;\n    padding-bottom: 1rem !important;\n  }\n\n  .py-xxl-4 {\n    padding-top: 1.5rem !important;\n    padding-bottom: 1.5rem !important;\n  }\n\n  .py-xxl-5 {\n    padding-top: 3rem !important;\n    padding-bottom: 3rem !important;\n  }\n\n  .pt-xxl-0 {\n    padding-top: 0 !important;\n  }\n\n  .pt-xxl-1 {\n    padding-top: 0.25rem !important;\n  }\n\n  .pt-xxl-2 {\n    padding-top: 0.5rem !important;\n  }\n\n  .pt-xxl-3 {\n    padding-top: 1rem !important;\n  }\n\n  .pt-xxl-4 {\n    padding-top: 1.5rem !important;\n  }\n\n  .pt-xxl-5 {\n    padding-top: 3rem !important;\n  }\n\n  .pe-xxl-0 {\n    padding-left: 0 !important;\n  }\n\n  .pe-xxl-1 {\n    padding-left: 0.25rem !important;\n  }\n\n  .pe-xxl-2 {\n    padding-left: 0.5rem !important;\n  }\n\n  .pe-xxl-3 {\n    padding-left: 1rem !important;\n  }\n\n  .pe-xxl-4 {\n    padding-left: 1.5rem !important;\n  }\n\n  .pe-xxl-5 {\n    padding-left: 3rem !important;\n  }\n\n  .pb-xxl-0 {\n    padding-bottom: 0 !important;\n  }\n\n  .pb-xxl-1 {\n    padding-bottom: 0.25rem !important;\n  }\n\n  .pb-xxl-2 {\n    padding-bottom: 0.5rem !important;\n  }\n\n  .pb-xxl-3 {\n    padding-bottom: 1rem !important;\n  }\n\n  .pb-xxl-4 {\n    padding-bottom: 1.5rem !important;\n  }\n\n  .pb-xxl-5 {\n    padding-bottom: 3rem !important;\n  }\n\n  .ps-xxl-0 {\n    padding-right: 0 !important;\n  }\n\n  .ps-xxl-1 {\n    padding-right: 0.25rem !important;\n  }\n\n  .ps-xxl-2 {\n    padding-right: 0.5rem !important;\n  }\n\n  .ps-xxl-3 {\n    padding-right: 1rem !important;\n  }\n\n  .ps-xxl-4 {\n    padding-right: 1.5rem !important;\n  }\n\n  .ps-xxl-5 {\n    padding-right: 3rem !important;\n  }\n}\n@media print {\n  .d-print-inline {\n    display: inline !important;\n  }\n\n  .d-print-inline-block {\n    display: inline-block !important;\n  }\n\n  .d-print-block {\n    display: block !important;\n  }\n\n  .d-print-grid {\n    display: grid !important;\n  }\n\n  .d-print-table {\n    display: table !important;\n  }\n\n  .d-print-table-row {\n    display: table-row !important;\n  }\n\n  .d-print-table-cell {\n    display: table-cell !important;\n  }\n\n  .d-print-flex {\n    display: flex !important;\n  }\n\n  .d-print-inline-flex {\n    display: inline-flex !important;\n  }\n\n  .d-print-none {\n    display: none !important;\n  }\n}\n/*# sourceMappingURL=bootstrap-grid.rtl.css.map */"
  },
  {
    "path": "sample/src/NimblePros.SampleToDo.Web/wwwroot/lib/bootstrap/dist/css/bootstrap-reboot.css",
    "content": "/*!\n * Bootstrap Reboot v5.1.0 (https://getbootstrap.com/)\n * Copyright 2011-2021 The Bootstrap Authors\n * Copyright 2011-2021 Twitter, Inc.\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * Forked from Normalize.css, licensed MIT (https://github.com/necolas/normalize.css/blob/master/LICENSE.md)\n */\n*,\n*::before,\n*::after {\n  box-sizing: border-box;\n}\n\n@media (prefers-reduced-motion: no-preference) {\n  :root {\n    scroll-behavior: smooth;\n  }\n}\n\nbody {\n  margin: 0;\n  font-family: var(--bs-body-font-family);\n  font-size: var(--bs-body-font-size);\n  font-weight: var(--bs-body-font-weight);\n  line-height: var(--bs-body-line-height);\n  color: var(--bs-body-color);\n  text-align: var(--bs-body-text-align);\n  background-color: var(--bs-body-bg);\n  -webkit-text-size-adjust: 100%;\n  -webkit-tap-highlight-color: rgba(0, 0, 0, 0);\n}\n\nhr {\n  margin: 1rem 0;\n  color: inherit;\n  background-color: currentColor;\n  border: 0;\n  opacity: 0.25;\n}\n\nhr:not([size]) {\n  height: 1px;\n}\n\nh6, h5, h4, h3, h2, h1 {\n  margin-top: 0;\n  margin-bottom: 0.5rem;\n  font-weight: 500;\n  line-height: 1.2;\n}\n\nh1 {\n  font-size: calc(1.375rem + 1.5vw);\n}\n@media (min-width: 1200px) {\n  h1 {\n    font-size: 2.5rem;\n  }\n}\n\nh2 {\n  font-size: calc(1.325rem + 0.9vw);\n}\n@media (min-width: 1200px) {\n  h2 {\n    font-size: 2rem;\n  }\n}\n\nh3 {\n  font-size: calc(1.3rem + 0.6vw);\n}\n@media (min-width: 1200px) {\n  h3 {\n    font-size: 1.75rem;\n  }\n}\n\nh4 {\n  font-size: calc(1.275rem + 0.3vw);\n}\n@media (min-width: 1200px) {\n  h4 {\n    font-size: 1.5rem;\n  }\n}\n\nh5 {\n  font-size: 1.25rem;\n}\n\nh6 {\n  font-size: 1rem;\n}\n\np {\n  margin-top: 0;\n  margin-bottom: 1rem;\n}\n\nabbr[title],\nabbr[data-bs-original-title] {\n  -webkit-text-decoration: underline dotted;\n  text-decoration: underline dotted;\n  cursor: help;\n  -webkit-text-decoration-skip-ink: none;\n  text-decoration-skip-ink: none;\n}\n\naddress {\n  margin-bottom: 1rem;\n  font-style: normal;\n  line-height: inherit;\n}\n\nol,\nul {\n  padding-left: 2rem;\n}\n\nol,\nul,\ndl {\n  margin-top: 0;\n  margin-bottom: 1rem;\n}\n\nol ol,\nul ul,\nol ul,\nul ol {\n  margin-bottom: 0;\n}\n\ndt {\n  font-weight: 700;\n}\n\ndd {\n  margin-bottom: 0.5rem;\n  margin-left: 0;\n}\n\nblockquote {\n  margin: 0 0 1rem;\n}\n\nb,\nstrong {\n  font-weight: bolder;\n}\n\nsmall {\n  font-size: 0.875em;\n}\n\nmark {\n  padding: 0.2em;\n  background-color: #fcf8e3;\n}\n\nsub,\nsup {\n  position: relative;\n  font-size: 0.75em;\n  line-height: 0;\n  vertical-align: baseline;\n}\n\nsub {\n  bottom: -0.25em;\n}\n\nsup {\n  top: -0.5em;\n}\n\na {\n  color: #0d6efd;\n  text-decoration: underline;\n}\na:hover {\n  color: #0a58ca;\n}\n\na:not([href]):not([class]), a:not([href]):not([class]):hover {\n  color: inherit;\n  text-decoration: none;\n}\n\npre,\ncode,\nkbd,\nsamp {\n  font-family: SFMono-Regular, Menlo, Monaco, Consolas, \"Liberation Mono\", \"Courier New\", monospace;\n  font-size: 1em;\n  direction: ltr /* rtl:ignore */;\n  unicode-bidi: bidi-override;\n}\n\npre {\n  display: block;\n  margin-top: 0;\n  margin-bottom: 1rem;\n  overflow: auto;\n  font-size: 0.875em;\n}\npre code {\n  font-size: inherit;\n  color: inherit;\n  word-break: normal;\n}\n\ncode {\n  font-size: 0.875em;\n  color: #d63384;\n  word-wrap: break-word;\n}\na > code {\n  color: inherit;\n}\n\nkbd {\n  padding: 0.2rem 0.4rem;\n  font-size: 0.875em;\n  color: #fff;\n  background-color: #212529;\n  border-radius: 0.2rem;\n}\nkbd kbd {\n  padding: 0;\n  font-size: 1em;\n  font-weight: 700;\n}\n\nfigure {\n  margin: 0 0 1rem;\n}\n\nimg,\nsvg {\n  vertical-align: middle;\n}\n\ntable {\n  caption-side: bottom;\n  border-collapse: collapse;\n}\n\ncaption {\n  padding-top: 0.5rem;\n  padding-bottom: 0.5rem;\n  color: #6c757d;\n  text-align: left;\n}\n\nth {\n  text-align: inherit;\n  text-align: -webkit-match-parent;\n}\n\nthead,\ntbody,\ntfoot,\ntr,\ntd,\nth {\n  border-color: inherit;\n  border-style: solid;\n  border-width: 0;\n}\n\nlabel {\n  display: inline-block;\n}\n\nbutton {\n  border-radius: 0;\n}\n\nbutton:focus:not(:focus-visible) {\n  outline: 0;\n}\n\ninput,\nbutton,\nselect,\noptgroup,\ntextarea {\n  margin: 0;\n  font-family: inherit;\n  font-size: inherit;\n  line-height: inherit;\n}\n\nbutton,\nselect {\n  text-transform: none;\n}\n\n[role=button] {\n  cursor: pointer;\n}\n\nselect {\n  word-wrap: normal;\n}\nselect:disabled {\n  opacity: 1;\n}\n\n[list]::-webkit-calendar-picker-indicator {\n  display: none;\n}\n\nbutton,\n[type=button],\n[type=reset],\n[type=submit] {\n  -webkit-appearance: button;\n}\nbutton:not(:disabled),\n[type=button]:not(:disabled),\n[type=reset]:not(:disabled),\n[type=submit]:not(:disabled) {\n  cursor: pointer;\n}\n\n::-moz-focus-inner {\n  padding: 0;\n  border-style: none;\n}\n\ntextarea {\n  resize: vertical;\n}\n\nfieldset {\n  min-width: 0;\n  padding: 0;\n  margin: 0;\n  border: 0;\n}\n\nlegend {\n  float: left;\n  width: 100%;\n  padding: 0;\n  margin-bottom: 0.5rem;\n  font-size: calc(1.275rem + 0.3vw);\n  line-height: inherit;\n}\n@media (min-width: 1200px) {\n  legend {\n    font-size: 1.5rem;\n  }\n}\nlegend + * {\n  clear: left;\n}\n\n::-webkit-datetime-edit-fields-wrapper,\n::-webkit-datetime-edit-text,\n::-webkit-datetime-edit-minute,\n::-webkit-datetime-edit-hour-field,\n::-webkit-datetime-edit-day-field,\n::-webkit-datetime-edit-month-field,\n::-webkit-datetime-edit-year-field {\n  padding: 0;\n}\n\n::-webkit-inner-spin-button {\n  height: auto;\n}\n\n[type=search] {\n  outline-offset: -2px;\n  -webkit-appearance: textfield;\n}\n\n/* rtl:raw:\n[type=\"tel\"],\n[type=\"url\"],\n[type=\"email\"],\n[type=\"number\"] {\n  direction: ltr;\n}\n*/\n::-webkit-search-decoration {\n  -webkit-appearance: none;\n}\n\n::-webkit-color-swatch-wrapper {\n  padding: 0;\n}\n\n::file-selector-button {\n  font: inherit;\n}\n\n::-webkit-file-upload-button {\n  font: inherit;\n  -webkit-appearance: button;\n}\n\noutput {\n  display: inline-block;\n}\n\niframe {\n  border: 0;\n}\n\nsummary {\n  display: list-item;\n  cursor: pointer;\n}\n\nprogress {\n  vertical-align: baseline;\n}\n\n[hidden] {\n  display: none !important;\n}\n\n/*# sourceMappingURL=bootstrap-reboot.css.map */"
  },
  {
    "path": "sample/src/NimblePros.SampleToDo.Web/wwwroot/lib/bootstrap/dist/css/bootstrap-reboot.rtl.css",
    "content": "/*!\n * Bootstrap Reboot v5.1.0 (https://getbootstrap.com/)\n * Copyright 2011-2021 The Bootstrap Authors\n * Copyright 2011-2021 Twitter, Inc.\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * Forked from Normalize.css, licensed MIT (https://github.com/necolas/normalize.css/blob/master/LICENSE.md)\n */\n*,\n*::before,\n*::after {\n  box-sizing: border-box;\n}\n\n@media (prefers-reduced-motion: no-preference) {\n  :root {\n    scroll-behavior: smooth;\n  }\n}\n\nbody {\n  margin: 0;\n  font-family: var(--bs-body-font-family);\n  font-size: var(--bs-body-font-size);\n  font-weight: var(--bs-body-font-weight);\n  line-height: var(--bs-body-line-height);\n  color: var(--bs-body-color);\n  text-align: var(--bs-body-text-align);\n  background-color: var(--bs-body-bg);\n  -webkit-text-size-adjust: 100%;\n  -webkit-tap-highlight-color: rgba(0, 0, 0, 0);\n}\n\nhr {\n  margin: 1rem 0;\n  color: inherit;\n  background-color: currentColor;\n  border: 0;\n  opacity: 0.25;\n}\n\nhr:not([size]) {\n  height: 1px;\n}\n\nh6, h5, h4, h3, h2, h1 {\n  margin-top: 0;\n  margin-bottom: 0.5rem;\n  font-weight: 500;\n  line-height: 1.2;\n}\n\nh1 {\n  font-size: calc(1.375rem + 1.5vw);\n}\n@media (min-width: 1200px) {\n  h1 {\n    font-size: 2.5rem;\n  }\n}\n\nh2 {\n  font-size: calc(1.325rem + 0.9vw);\n}\n@media (min-width: 1200px) {\n  h2 {\n    font-size: 2rem;\n  }\n}\n\nh3 {\n  font-size: calc(1.3rem + 0.6vw);\n}\n@media (min-width: 1200px) {\n  h3 {\n    font-size: 1.75rem;\n  }\n}\n\nh4 {\n  font-size: calc(1.275rem + 0.3vw);\n}\n@media (min-width: 1200px) {\n  h4 {\n    font-size: 1.5rem;\n  }\n}\n\nh5 {\n  font-size: 1.25rem;\n}\n\nh6 {\n  font-size: 1rem;\n}\n\np {\n  margin-top: 0;\n  margin-bottom: 1rem;\n}\n\nabbr[title],\nabbr[data-bs-original-title] {\n  -webkit-text-decoration: underline dotted;\n  text-decoration: underline dotted;\n  cursor: help;\n  -webkit-text-decoration-skip-ink: none;\n  text-decoration-skip-ink: none;\n}\n\naddress {\n  margin-bottom: 1rem;\n  font-style: normal;\n  line-height: inherit;\n}\n\nol,\nul {\n  padding-right: 2rem;\n}\n\nol,\nul,\ndl {\n  margin-top: 0;\n  margin-bottom: 1rem;\n}\n\nol ol,\nul ul,\nol ul,\nul ol {\n  margin-bottom: 0;\n}\n\ndt {\n  font-weight: 700;\n}\n\ndd {\n  margin-bottom: 0.5rem;\n  margin-right: 0;\n}\n\nblockquote {\n  margin: 0 0 1rem;\n}\n\nb,\nstrong {\n  font-weight: bolder;\n}\n\nsmall {\n  font-size: 0.875em;\n}\n\nmark {\n  padding: 0.2em;\n  background-color: #fcf8e3;\n}\n\nsub,\nsup {\n  position: relative;\n  font-size: 0.75em;\n  line-height: 0;\n  vertical-align: baseline;\n}\n\nsub {\n  bottom: -0.25em;\n}\n\nsup {\n  top: -0.5em;\n}\n\na {\n  color: #0d6efd;\n  text-decoration: underline;\n}\na:hover {\n  color: #0a58ca;\n}\n\na:not([href]):not([class]), a:not([href]):not([class]):hover {\n  color: inherit;\n  text-decoration: none;\n}\n\npre,\ncode,\nkbd,\nsamp {\n  font-family: SFMono-Regular, Menlo, Monaco, Consolas, \"Liberation Mono\", \"Courier New\", monospace;\n  font-size: 1em;\n  direction: ltr ;\n  unicode-bidi: bidi-override;\n}\n\npre {\n  display: block;\n  margin-top: 0;\n  margin-bottom: 1rem;\n  overflow: auto;\n  font-size: 0.875em;\n}\npre code {\n  font-size: inherit;\n  color: inherit;\n  word-break: normal;\n}\n\ncode {\n  font-size: 0.875em;\n  color: #d63384;\n  word-wrap: break-word;\n}\na > code {\n  color: inherit;\n}\n\nkbd {\n  padding: 0.2rem 0.4rem;\n  font-size: 0.875em;\n  color: #fff;\n  background-color: #212529;\n  border-radius: 0.2rem;\n}\nkbd kbd {\n  padding: 0;\n  font-size: 1em;\n  font-weight: 700;\n}\n\nfigure {\n  margin: 0 0 1rem;\n}\n\nimg,\nsvg {\n  vertical-align: middle;\n}\n\ntable {\n  caption-side: bottom;\n  border-collapse: collapse;\n}\n\ncaption {\n  padding-top: 0.5rem;\n  padding-bottom: 0.5rem;\n  color: #6c757d;\n  text-align: right;\n}\n\nth {\n  text-align: inherit;\n  text-align: -webkit-match-parent;\n}\n\nthead,\ntbody,\ntfoot,\ntr,\ntd,\nth {\n  border-color: inherit;\n  border-style: solid;\n  border-width: 0;\n}\n\nlabel {\n  display: inline-block;\n}\n\nbutton {\n  border-radius: 0;\n}\n\nbutton:focus:not(:focus-visible) {\n  outline: 0;\n}\n\ninput,\nbutton,\nselect,\noptgroup,\ntextarea {\n  margin: 0;\n  font-family: inherit;\n  font-size: inherit;\n  line-height: inherit;\n}\n\nbutton,\nselect {\n  text-transform: none;\n}\n\n[role=button] {\n  cursor: pointer;\n}\n\nselect {\n  word-wrap: normal;\n}\nselect:disabled {\n  opacity: 1;\n}\n\n[list]::-webkit-calendar-picker-indicator {\n  display: none;\n}\n\nbutton,\n[type=button],\n[type=reset],\n[type=submit] {\n  -webkit-appearance: button;\n}\nbutton:not(:disabled),\n[type=button]:not(:disabled),\n[type=reset]:not(:disabled),\n[type=submit]:not(:disabled) {\n  cursor: pointer;\n}\n\n::-moz-focus-inner {\n  padding: 0;\n  border-style: none;\n}\n\ntextarea {\n  resize: vertical;\n}\n\nfieldset {\n  min-width: 0;\n  padding: 0;\n  margin: 0;\n  border: 0;\n}\n\nlegend {\n  float: right;\n  width: 100%;\n  padding: 0;\n  margin-bottom: 0.5rem;\n  font-size: calc(1.275rem + 0.3vw);\n  line-height: inherit;\n}\n@media (min-width: 1200px) {\n  legend {\n    font-size: 1.5rem;\n  }\n}\nlegend + * {\n  clear: right;\n}\n\n::-webkit-datetime-edit-fields-wrapper,\n::-webkit-datetime-edit-text,\n::-webkit-datetime-edit-minute,\n::-webkit-datetime-edit-hour-field,\n::-webkit-datetime-edit-day-field,\n::-webkit-datetime-edit-month-field,\n::-webkit-datetime-edit-year-field {\n  padding: 0;\n}\n\n::-webkit-inner-spin-button {\n  height: auto;\n}\n\n[type=search] {\n  outline-offset: -2px;\n  -webkit-appearance: textfield;\n}\n\n[type=\"tel\"],\n[type=\"url\"],\n[type=\"email\"],\n[type=\"number\"] {\n  direction: ltr;\n}\n::-webkit-search-decoration {\n  -webkit-appearance: none;\n}\n\n::-webkit-color-swatch-wrapper {\n  padding: 0;\n}\n\n::file-selector-button {\n  font: inherit;\n}\n\n::-webkit-file-upload-button {\n  font: inherit;\n  -webkit-appearance: button;\n}\n\noutput {\n  display: inline-block;\n}\n\niframe {\n  border: 0;\n}\n\nsummary {\n  display: list-item;\n  cursor: pointer;\n}\n\nprogress {\n  vertical-align: baseline;\n}\n\n[hidden] {\n  display: none !important;\n}\n/*# sourceMappingURL=bootstrap-reboot.rtl.css.map */"
  },
  {
    "path": "sample/src/NimblePros.SampleToDo.Web/wwwroot/lib/bootstrap/dist/css/bootstrap-utilities.css",
    "content": "/*!\n * Bootstrap Utilities v5.1.0 (https://getbootstrap.com/)\n * Copyright 2011-2021 The Bootstrap Authors\n * Copyright 2011-2021 Twitter, Inc.\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n */\n.clearfix::after {\n  display: block;\n  clear: both;\n  content: \"\";\n}\n\n.link-primary {\n  color: #0d6efd;\n}\n.link-primary:hover, .link-primary:focus {\n  color: #0a58ca;\n}\n\n.link-secondary {\n  color: #6c757d;\n}\n.link-secondary:hover, .link-secondary:focus {\n  color: #565e64;\n}\n\n.link-success {\n  color: #198754;\n}\n.link-success:hover, .link-success:focus {\n  color: #146c43;\n}\n\n.link-info {\n  color: #0dcaf0;\n}\n.link-info:hover, .link-info:focus {\n  color: #3dd5f3;\n}\n\n.link-warning {\n  color: #ffc107;\n}\n.link-warning:hover, .link-warning:focus {\n  color: #ffcd39;\n}\n\n.link-danger {\n  color: #dc3545;\n}\n.link-danger:hover, .link-danger:focus {\n  color: #b02a37;\n}\n\n.link-light {\n  color: #f8f9fa;\n}\n.link-light:hover, .link-light:focus {\n  color: #f9fafb;\n}\n\n.link-dark {\n  color: #212529;\n}\n.link-dark:hover, .link-dark:focus {\n  color: #1a1e21;\n}\n\n.ratio {\n  position: relative;\n  width: 100%;\n}\n.ratio::before {\n  display: block;\n  padding-top: var(--bs-aspect-ratio);\n  content: \"\";\n}\n.ratio > * {\n  position: absolute;\n  top: 0;\n  left: 0;\n  width: 100%;\n  height: 100%;\n}\n\n.ratio-1x1 {\n  --bs-aspect-ratio: 100%;\n}\n\n.ratio-4x3 {\n  --bs-aspect-ratio: calc(3 / 4 * 100%);\n}\n\n.ratio-16x9 {\n  --bs-aspect-ratio: calc(9 / 16 * 100%);\n}\n\n.ratio-21x9 {\n  --bs-aspect-ratio: calc(9 / 21 * 100%);\n}\n\n.fixed-top {\n  position: fixed;\n  top: 0;\n  right: 0;\n  left: 0;\n  z-index: 1030;\n}\n\n.fixed-bottom {\n  position: fixed;\n  right: 0;\n  bottom: 0;\n  left: 0;\n  z-index: 1030;\n}\n\n.sticky-top {\n  position: -webkit-sticky;\n  position: sticky;\n  top: 0;\n  z-index: 1020;\n}\n\n@media (min-width: 576px) {\n  .sticky-sm-top {\n    position: -webkit-sticky;\n    position: sticky;\n    top: 0;\n    z-index: 1020;\n  }\n}\n@media (min-width: 768px) {\n  .sticky-md-top {\n    position: -webkit-sticky;\n    position: sticky;\n    top: 0;\n    z-index: 1020;\n  }\n}\n@media (min-width: 992px) {\n  .sticky-lg-top {\n    position: -webkit-sticky;\n    position: sticky;\n    top: 0;\n    z-index: 1020;\n  }\n}\n@media (min-width: 1200px) {\n  .sticky-xl-top {\n    position: -webkit-sticky;\n    position: sticky;\n    top: 0;\n    z-index: 1020;\n  }\n}\n@media (min-width: 1400px) {\n  .sticky-xxl-top {\n    position: -webkit-sticky;\n    position: sticky;\n    top: 0;\n    z-index: 1020;\n  }\n}\n.hstack {\n  display: flex;\n  flex-direction: row;\n  align-items: center;\n  align-self: stretch;\n}\n\n.vstack {\n  display: flex;\n  flex: 1 1 auto;\n  flex-direction: column;\n  align-self: stretch;\n}\n\n.visually-hidden,\n.visually-hidden-focusable:not(:focus):not(:focus-within) {\n  position: absolute !important;\n  width: 1px !important;\n  height: 1px !important;\n  padding: 0 !important;\n  margin: -1px !important;\n  overflow: hidden !important;\n  clip: rect(0, 0, 0, 0) !important;\n  white-space: nowrap !important;\n  border: 0 !important;\n}\n\n.stretched-link::after {\n  position: absolute;\n  top: 0;\n  right: 0;\n  bottom: 0;\n  left: 0;\n  z-index: 1;\n  content: \"\";\n}\n\n.text-truncate {\n  overflow: hidden;\n  text-overflow: ellipsis;\n  white-space: nowrap;\n}\n\n.vr {\n  display: inline-block;\n  align-self: stretch;\n  width: 1px;\n  min-height: 1em;\n  background-color: currentColor;\n  opacity: 0.25;\n}\n\n.align-baseline {\n  vertical-align: baseline !important;\n}\n\n.align-top {\n  vertical-align: top !important;\n}\n\n.align-middle {\n  vertical-align: middle !important;\n}\n\n.align-bottom {\n  vertical-align: bottom !important;\n}\n\n.align-text-bottom {\n  vertical-align: text-bottom !important;\n}\n\n.align-text-top {\n  vertical-align: text-top !important;\n}\n\n.float-start {\n  float: left !important;\n}\n\n.float-end {\n  float: right !important;\n}\n\n.float-none {\n  float: none !important;\n}\n\n.opacity-0 {\n  opacity: 0 !important;\n}\n\n.opacity-25 {\n  opacity: 0.25 !important;\n}\n\n.opacity-50 {\n  opacity: 0.5 !important;\n}\n\n.opacity-75 {\n  opacity: 0.75 !important;\n}\n\n.opacity-100 {\n  opacity: 1 !important;\n}\n\n.overflow-auto {\n  overflow: auto !important;\n}\n\n.overflow-hidden {\n  overflow: hidden !important;\n}\n\n.overflow-visible {\n  overflow: visible !important;\n}\n\n.overflow-scroll {\n  overflow: scroll !important;\n}\n\n.d-inline {\n  display: inline !important;\n}\n\n.d-inline-block {\n  display: inline-block !important;\n}\n\n.d-block {\n  display: block !important;\n}\n\n.d-grid {\n  display: grid !important;\n}\n\n.d-table {\n  display: table !important;\n}\n\n.d-table-row {\n  display: table-row !important;\n}\n\n.d-table-cell {\n  display: table-cell !important;\n}\n\n.d-flex {\n  display: flex !important;\n}\n\n.d-inline-flex {\n  display: inline-flex !important;\n}\n\n.d-none {\n  display: none !important;\n}\n\n.shadow {\n  box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.15) !important;\n}\n\n.shadow-sm {\n  box-shadow: 0 0.125rem 0.25rem rgba(0, 0, 0, 0.075) !important;\n}\n\n.shadow-lg {\n  box-shadow: 0 1rem 3rem rgba(0, 0, 0, 0.175) !important;\n}\n\n.shadow-none {\n  box-shadow: none !important;\n}\n\n.position-static {\n  position: static !important;\n}\n\n.position-relative {\n  position: relative !important;\n}\n\n.position-absolute {\n  position: absolute !important;\n}\n\n.position-fixed {\n  position: fixed !important;\n}\n\n.position-sticky {\n  position: -webkit-sticky !important;\n  position: sticky !important;\n}\n\n.top-0 {\n  top: 0 !important;\n}\n\n.top-50 {\n  top: 50% !important;\n}\n\n.top-100 {\n  top: 100% !important;\n}\n\n.bottom-0 {\n  bottom: 0 !important;\n}\n\n.bottom-50 {\n  bottom: 50% !important;\n}\n\n.bottom-100 {\n  bottom: 100% !important;\n}\n\n.start-0 {\n  left: 0 !important;\n}\n\n.start-50 {\n  left: 50% !important;\n}\n\n.start-100 {\n  left: 100% !important;\n}\n\n.end-0 {\n  right: 0 !important;\n}\n\n.end-50 {\n  right: 50% !important;\n}\n\n.end-100 {\n  right: 100% !important;\n}\n\n.translate-middle {\n  transform: translate(-50%, -50%) !important;\n}\n\n.translate-middle-x {\n  transform: translateX(-50%) !important;\n}\n\n.translate-middle-y {\n  transform: translateY(-50%) !important;\n}\n\n.border {\n  border: 1px solid #dee2e6 !important;\n}\n\n.border-0 {\n  border: 0 !important;\n}\n\n.border-top {\n  border-top: 1px solid #dee2e6 !important;\n}\n\n.border-top-0 {\n  border-top: 0 !important;\n}\n\n.border-end {\n  border-right: 1px solid #dee2e6 !important;\n}\n\n.border-end-0 {\n  border-right: 0 !important;\n}\n\n.border-bottom {\n  border-bottom: 1px solid #dee2e6 !important;\n}\n\n.border-bottom-0 {\n  border-bottom: 0 !important;\n}\n\n.border-start {\n  border-left: 1px solid #dee2e6 !important;\n}\n\n.border-start-0 {\n  border-left: 0 !important;\n}\n\n.border-primary {\n  border-color: #0d6efd !important;\n}\n\n.border-secondary {\n  border-color: #6c757d !important;\n}\n\n.border-success {\n  border-color: #198754 !important;\n}\n\n.border-info {\n  border-color: #0dcaf0 !important;\n}\n\n.border-warning {\n  border-color: #ffc107 !important;\n}\n\n.border-danger {\n  border-color: #dc3545 !important;\n}\n\n.border-light {\n  border-color: #f8f9fa !important;\n}\n\n.border-dark {\n  border-color: #212529 !important;\n}\n\n.border-white {\n  border-color: #fff !important;\n}\n\n.border-1 {\n  border-width: 1px !important;\n}\n\n.border-2 {\n  border-width: 2px !important;\n}\n\n.border-3 {\n  border-width: 3px !important;\n}\n\n.border-4 {\n  border-width: 4px !important;\n}\n\n.border-5 {\n  border-width: 5px !important;\n}\n\n.w-25 {\n  width: 25% !important;\n}\n\n.w-50 {\n  width: 50% !important;\n}\n\n.w-75 {\n  width: 75% !important;\n}\n\n.w-100 {\n  width: 100% !important;\n}\n\n.w-auto {\n  width: auto !important;\n}\n\n.mw-100 {\n  max-width: 100% !important;\n}\n\n.vw-100 {\n  width: 100vw !important;\n}\n\n.min-vw-100 {\n  min-width: 100vw !important;\n}\n\n.h-25 {\n  height: 25% !important;\n}\n\n.h-50 {\n  height: 50% !important;\n}\n\n.h-75 {\n  height: 75% !important;\n}\n\n.h-100 {\n  height: 100% !important;\n}\n\n.h-auto {\n  height: auto !important;\n}\n\n.mh-100 {\n  max-height: 100% !important;\n}\n\n.vh-100 {\n  height: 100vh !important;\n}\n\n.min-vh-100 {\n  min-height: 100vh !important;\n}\n\n.flex-fill {\n  flex: 1 1 auto !important;\n}\n\n.flex-row {\n  flex-direction: row !important;\n}\n\n.flex-column {\n  flex-direction: column !important;\n}\n\n.flex-row-reverse {\n  flex-direction: row-reverse !important;\n}\n\n.flex-column-reverse {\n  flex-direction: column-reverse !important;\n}\n\n.flex-grow-0 {\n  flex-grow: 0 !important;\n}\n\n.flex-grow-1 {\n  flex-grow: 1 !important;\n}\n\n.flex-shrink-0 {\n  flex-shrink: 0 !important;\n}\n\n.flex-shrink-1 {\n  flex-shrink: 1 !important;\n}\n\n.flex-wrap {\n  flex-wrap: wrap !important;\n}\n\n.flex-nowrap {\n  flex-wrap: nowrap !important;\n}\n\n.flex-wrap-reverse {\n  flex-wrap: wrap-reverse !important;\n}\n\n.gap-0 {\n  gap: 0 !important;\n}\n\n.gap-1 {\n  gap: 0.25rem !important;\n}\n\n.gap-2 {\n  gap: 0.5rem !important;\n}\n\n.gap-3 {\n  gap: 1rem !important;\n}\n\n.gap-4 {\n  gap: 1.5rem !important;\n}\n\n.gap-5 {\n  gap: 3rem !important;\n}\n\n.justify-content-start {\n  justify-content: flex-start !important;\n}\n\n.justify-content-end {\n  justify-content: flex-end !important;\n}\n\n.justify-content-center {\n  justify-content: center !important;\n}\n\n.justify-content-between {\n  justify-content: space-between !important;\n}\n\n.justify-content-around {\n  justify-content: space-around !important;\n}\n\n.justify-content-evenly {\n  justify-content: space-evenly !important;\n}\n\n.align-items-start {\n  align-items: flex-start !important;\n}\n\n.align-items-end {\n  align-items: flex-end !important;\n}\n\n.align-items-center {\n  align-items: center !important;\n}\n\n.align-items-baseline {\n  align-items: baseline !important;\n}\n\n.align-items-stretch {\n  align-items: stretch !important;\n}\n\n.align-content-start {\n  align-content: flex-start !important;\n}\n\n.align-content-end {\n  align-content: flex-end !important;\n}\n\n.align-content-center {\n  align-content: center !important;\n}\n\n.align-content-between {\n  align-content: space-between !important;\n}\n\n.align-content-around {\n  align-content: space-around !important;\n}\n\n.align-content-stretch {\n  align-content: stretch !important;\n}\n\n.align-self-auto {\n  align-self: auto !important;\n}\n\n.align-self-start {\n  align-self: flex-start !important;\n}\n\n.align-self-end {\n  align-self: flex-end !important;\n}\n\n.align-self-center {\n  align-self: center !important;\n}\n\n.align-self-baseline {\n  align-self: baseline !important;\n}\n\n.align-self-stretch {\n  align-self: stretch !important;\n}\n\n.order-first {\n  order: -1 !important;\n}\n\n.order-0 {\n  order: 0 !important;\n}\n\n.order-1 {\n  order: 1 !important;\n}\n\n.order-2 {\n  order: 2 !important;\n}\n\n.order-3 {\n  order: 3 !important;\n}\n\n.order-4 {\n  order: 4 !important;\n}\n\n.order-5 {\n  order: 5 !important;\n}\n\n.order-last {\n  order: 6 !important;\n}\n\n.m-0 {\n  margin: 0 !important;\n}\n\n.m-1 {\n  margin: 0.25rem !important;\n}\n\n.m-2 {\n  margin: 0.5rem !important;\n}\n\n.m-3 {\n  margin: 1rem !important;\n}\n\n.m-4 {\n  margin: 1.5rem !important;\n}\n\n.m-5 {\n  margin: 3rem !important;\n}\n\n.m-auto {\n  margin: auto !important;\n}\n\n.mx-0 {\n  margin-right: 0 !important;\n  margin-left: 0 !important;\n}\n\n.mx-1 {\n  margin-right: 0.25rem !important;\n  margin-left: 0.25rem !important;\n}\n\n.mx-2 {\n  margin-right: 0.5rem !important;\n  margin-left: 0.5rem !important;\n}\n\n.mx-3 {\n  margin-right: 1rem !important;\n  margin-left: 1rem !important;\n}\n\n.mx-4 {\n  margin-right: 1.5rem !important;\n  margin-left: 1.5rem !important;\n}\n\n.mx-5 {\n  margin-right: 3rem !important;\n  margin-left: 3rem !important;\n}\n\n.mx-auto {\n  margin-right: auto !important;\n  margin-left: auto !important;\n}\n\n.my-0 {\n  margin-top: 0 !important;\n  margin-bottom: 0 !important;\n}\n\n.my-1 {\n  margin-top: 0.25rem !important;\n  margin-bottom: 0.25rem !important;\n}\n\n.my-2 {\n  margin-top: 0.5rem !important;\n  margin-bottom: 0.5rem !important;\n}\n\n.my-3 {\n  margin-top: 1rem !important;\n  margin-bottom: 1rem !important;\n}\n\n.my-4 {\n  margin-top: 1.5rem !important;\n  margin-bottom: 1.5rem !important;\n}\n\n.my-5 {\n  margin-top: 3rem !important;\n  margin-bottom: 3rem !important;\n}\n\n.my-auto {\n  margin-top: auto !important;\n  margin-bottom: auto !important;\n}\n\n.mt-0 {\n  margin-top: 0 !important;\n}\n\n.mt-1 {\n  margin-top: 0.25rem !important;\n}\n\n.mt-2 {\n  margin-top: 0.5rem !important;\n}\n\n.mt-3 {\n  margin-top: 1rem !important;\n}\n\n.mt-4 {\n  margin-top: 1.5rem !important;\n}\n\n.mt-5 {\n  margin-top: 3rem !important;\n}\n\n.mt-auto {\n  margin-top: auto !important;\n}\n\n.me-0 {\n  margin-right: 0 !important;\n}\n\n.me-1 {\n  margin-right: 0.25rem !important;\n}\n\n.me-2 {\n  margin-right: 0.5rem !important;\n}\n\n.me-3 {\n  margin-right: 1rem !important;\n}\n\n.me-4 {\n  margin-right: 1.5rem !important;\n}\n\n.me-5 {\n  margin-right: 3rem !important;\n}\n\n.me-auto {\n  margin-right: auto !important;\n}\n\n.mb-0 {\n  margin-bottom: 0 !important;\n}\n\n.mb-1 {\n  margin-bottom: 0.25rem !important;\n}\n\n.mb-2 {\n  margin-bottom: 0.5rem !important;\n}\n\n.mb-3 {\n  margin-bottom: 1rem !important;\n}\n\n.mb-4 {\n  margin-bottom: 1.5rem !important;\n}\n\n.mb-5 {\n  margin-bottom: 3rem !important;\n}\n\n.mb-auto {\n  margin-bottom: auto !important;\n}\n\n.ms-0 {\n  margin-left: 0 !important;\n}\n\n.ms-1 {\n  margin-left: 0.25rem !important;\n}\n\n.ms-2 {\n  margin-left: 0.5rem !important;\n}\n\n.ms-3 {\n  margin-left: 1rem !important;\n}\n\n.ms-4 {\n  margin-left: 1.5rem !important;\n}\n\n.ms-5 {\n  margin-left: 3rem !important;\n}\n\n.ms-auto {\n  margin-left: auto !important;\n}\n\n.p-0 {\n  padding: 0 !important;\n}\n\n.p-1 {\n  padding: 0.25rem !important;\n}\n\n.p-2 {\n  padding: 0.5rem !important;\n}\n\n.p-3 {\n  padding: 1rem !important;\n}\n\n.p-4 {\n  padding: 1.5rem !important;\n}\n\n.p-5 {\n  padding: 3rem !important;\n}\n\n.px-0 {\n  padding-right: 0 !important;\n  padding-left: 0 !important;\n}\n\n.px-1 {\n  padding-right: 0.25rem !important;\n  padding-left: 0.25rem !important;\n}\n\n.px-2 {\n  padding-right: 0.5rem !important;\n  padding-left: 0.5rem !important;\n}\n\n.px-3 {\n  padding-right: 1rem !important;\n  padding-left: 1rem !important;\n}\n\n.px-4 {\n  padding-right: 1.5rem !important;\n  padding-left: 1.5rem !important;\n}\n\n.px-5 {\n  padding-right: 3rem !important;\n  padding-left: 3rem !important;\n}\n\n.py-0 {\n  padding-top: 0 !important;\n  padding-bottom: 0 !important;\n}\n\n.py-1 {\n  padding-top: 0.25rem !important;\n  padding-bottom: 0.25rem !important;\n}\n\n.py-2 {\n  padding-top: 0.5rem !important;\n  padding-bottom: 0.5rem !important;\n}\n\n.py-3 {\n  padding-top: 1rem !important;\n  padding-bottom: 1rem !important;\n}\n\n.py-4 {\n  padding-top: 1.5rem !important;\n  padding-bottom: 1.5rem !important;\n}\n\n.py-5 {\n  padding-top: 3rem !important;\n  padding-bottom: 3rem !important;\n}\n\n.pt-0 {\n  padding-top: 0 !important;\n}\n\n.pt-1 {\n  padding-top: 0.25rem !important;\n}\n\n.pt-2 {\n  padding-top: 0.5rem !important;\n}\n\n.pt-3 {\n  padding-top: 1rem !important;\n}\n\n.pt-4 {\n  padding-top: 1.5rem !important;\n}\n\n.pt-5 {\n  padding-top: 3rem !important;\n}\n\n.pe-0 {\n  padding-right: 0 !important;\n}\n\n.pe-1 {\n  padding-right: 0.25rem !important;\n}\n\n.pe-2 {\n  padding-right: 0.5rem !important;\n}\n\n.pe-3 {\n  padding-right: 1rem !important;\n}\n\n.pe-4 {\n  padding-right: 1.5rem !important;\n}\n\n.pe-5 {\n  padding-right: 3rem !important;\n}\n\n.pb-0 {\n  padding-bottom: 0 !important;\n}\n\n.pb-1 {\n  padding-bottom: 0.25rem !important;\n}\n\n.pb-2 {\n  padding-bottom: 0.5rem !important;\n}\n\n.pb-3 {\n  padding-bottom: 1rem !important;\n}\n\n.pb-4 {\n  padding-bottom: 1.5rem !important;\n}\n\n.pb-5 {\n  padding-bottom: 3rem !important;\n}\n\n.ps-0 {\n  padding-left: 0 !important;\n}\n\n.ps-1 {\n  padding-left: 0.25rem !important;\n}\n\n.ps-2 {\n  padding-left: 0.5rem !important;\n}\n\n.ps-3 {\n  padding-left: 1rem !important;\n}\n\n.ps-4 {\n  padding-left: 1.5rem !important;\n}\n\n.ps-5 {\n  padding-left: 3rem !important;\n}\n\n.font-monospace {\n  font-family: var(--bs-font-monospace) !important;\n}\n\n.fs-1 {\n  font-size: calc(1.375rem + 1.5vw) !important;\n}\n\n.fs-2 {\n  font-size: calc(1.325rem + 0.9vw) !important;\n}\n\n.fs-3 {\n  font-size: calc(1.3rem + 0.6vw) !important;\n}\n\n.fs-4 {\n  font-size: calc(1.275rem + 0.3vw) !important;\n}\n\n.fs-5 {\n  font-size: 1.25rem !important;\n}\n\n.fs-6 {\n  font-size: 1rem !important;\n}\n\n.fst-italic {\n  font-style: italic !important;\n}\n\n.fst-normal {\n  font-style: normal !important;\n}\n\n.fw-light {\n  font-weight: 300 !important;\n}\n\n.fw-lighter {\n  font-weight: lighter !important;\n}\n\n.fw-normal {\n  font-weight: 400 !important;\n}\n\n.fw-bold {\n  font-weight: 700 !important;\n}\n\n.fw-bolder {\n  font-weight: bolder !important;\n}\n\n.lh-1 {\n  line-height: 1 !important;\n}\n\n.lh-sm {\n  line-height: 1.25 !important;\n}\n\n.lh-base {\n  line-height: 1.5 !important;\n}\n\n.lh-lg {\n  line-height: 2 !important;\n}\n\n.text-start {\n  text-align: left !important;\n}\n\n.text-end {\n  text-align: right !important;\n}\n\n.text-center {\n  text-align: center !important;\n}\n\n.text-decoration-none {\n  text-decoration: none !important;\n}\n\n.text-decoration-underline {\n  text-decoration: underline !important;\n}\n\n.text-decoration-line-through {\n  text-decoration: line-through !important;\n}\n\n.text-lowercase {\n  text-transform: lowercase !important;\n}\n\n.text-uppercase {\n  text-transform: uppercase !important;\n}\n\n.text-capitalize {\n  text-transform: capitalize !important;\n}\n\n.text-wrap {\n  white-space: normal !important;\n}\n\n.text-nowrap {\n  white-space: nowrap !important;\n}\n\n/* rtl:begin:remove */\n.text-break {\n  word-wrap: break-word !important;\n  word-break: break-word !important;\n}\n\n/* rtl:end:remove */\n.text-primary {\n  --bs-text-opacity: 1;\n  color: rgba(var(--bs-primary-rgb), var(--bs-text-opacity)) !important;\n}\n\n.text-secondary {\n  --bs-text-opacity: 1;\n  color: rgba(var(--bs-secondary-rgb), var(--bs-text-opacity)) !important;\n}\n\n.text-success {\n  --bs-text-opacity: 1;\n  color: rgba(var(--bs-success-rgb), var(--bs-text-opacity)) !important;\n}\n\n.text-info {\n  --bs-text-opacity: 1;\n  color: rgba(var(--bs-info-rgb), var(--bs-text-opacity)) !important;\n}\n\n.text-warning {\n  --bs-text-opacity: 1;\n  color: rgba(var(--bs-warning-rgb), var(--bs-text-opacity)) !important;\n}\n\n.text-danger {\n  --bs-text-opacity: 1;\n  color: rgba(var(--bs-danger-rgb), var(--bs-text-opacity)) !important;\n}\n\n.text-light {\n  --bs-text-opacity: 1;\n  color: rgba(var(--bs-light-rgb), var(--bs-text-opacity)) !important;\n}\n\n.text-dark {\n  --bs-text-opacity: 1;\n  color: rgba(var(--bs-dark-rgb), var(--bs-text-opacity)) !important;\n}\n\n.text-black {\n  --bs-text-opacity: 1;\n  color: rgba(var(--bs-black-rgb), var(--bs-text-opacity)) !important;\n}\n\n.text-white {\n  --bs-text-opacity: 1;\n  color: rgba(var(--bs-white-rgb), var(--bs-text-opacity)) !important;\n}\n\n.text-body {\n  --bs-text-opacity: 1;\n  color: rgba(var(--bs-body-rgb), var(--bs-text-opacity)) !important;\n}\n\n.text-muted {\n  --bs-text-opacity: 1;\n  color: #6c757d !important;\n}\n\n.text-black-50 {\n  --bs-text-opacity: 1;\n  color: rgba(0, 0, 0, 0.5) !important;\n}\n\n.text-white-50 {\n  --bs-text-opacity: 1;\n  color: rgba(255, 255, 255, 0.5) !important;\n}\n\n.text-reset {\n  --bs-text-opacity: 1;\n  color: inherit !important;\n}\n\n.text-opacity-25 {\n  --bs-text-opacity: 0.25;\n}\n\n.text-opacity-50 {\n  --bs-text-opacity: 0.5;\n}\n\n.text-opacity-75 {\n  --bs-text-opacity: 0.75;\n}\n\n.text-opacity-100 {\n  --bs-text-opacity: 1;\n}\n\n.bg-primary {\n  --bs-bg-opacity: 1;\n  background-color: rgba(var(--bs-primary-rgb), var(--bs-bg-opacity)) !important;\n}\n\n.bg-secondary {\n  --bs-bg-opacity: 1;\n  background-color: rgba(var(--bs-secondary-rgb), var(--bs-bg-opacity)) !important;\n}\n\n.bg-success {\n  --bs-bg-opacity: 1;\n  background-color: rgba(var(--bs-success-rgb), var(--bs-bg-opacity)) !important;\n}\n\n.bg-info {\n  --bs-bg-opacity: 1;\n  background-color: rgba(var(--bs-info-rgb), var(--bs-bg-opacity)) !important;\n}\n\n.bg-warning {\n  --bs-bg-opacity: 1;\n  background-color: rgba(var(--bs-warning-rgb), var(--bs-bg-opacity)) !important;\n}\n\n.bg-danger {\n  --bs-bg-opacity: 1;\n  background-color: rgba(var(--bs-danger-rgb), var(--bs-bg-opacity)) !important;\n}\n\n.bg-light {\n  --bs-bg-opacity: 1;\n  background-color: rgba(var(--bs-light-rgb), var(--bs-bg-opacity)) !important;\n}\n\n.bg-dark {\n  --bs-bg-opacity: 1;\n  background-color: rgba(var(--bs-dark-rgb), var(--bs-bg-opacity)) !important;\n}\n\n.bg-black {\n  --bs-bg-opacity: 1;\n  background-color: rgba(var(--bs-black-rgb), var(--bs-bg-opacity)) !important;\n}\n\n.bg-white {\n  --bs-bg-opacity: 1;\n  background-color: rgba(var(--bs-white-rgb), var(--bs-bg-opacity)) !important;\n}\n\n.bg-body {\n  --bs-bg-opacity: 1;\n  background-color: rgba(var(--bs-body-rgb), var(--bs-bg-opacity)) !important;\n}\n\n.bg-transparent {\n  --bs-bg-opacity: 1;\n  background-color: transparent !important;\n}\n\n.bg-opacity-10 {\n  --bs-bg-opacity: 0.1;\n}\n\n.bg-opacity-25 {\n  --bs-bg-opacity: 0.25;\n}\n\n.bg-opacity-50 {\n  --bs-bg-opacity: 0.5;\n}\n\n.bg-opacity-75 {\n  --bs-bg-opacity: 0.75;\n}\n\n.bg-opacity-100 {\n  --bs-bg-opacity: 1;\n}\n\n.bg-gradient {\n  background-image: var(--bs-gradient) !important;\n}\n\n.user-select-all {\n  -webkit-user-select: all !important;\n  -moz-user-select: all !important;\n  user-select: all !important;\n}\n\n.user-select-auto {\n  -webkit-user-select: auto !important;\n  -moz-user-select: auto !important;\n  user-select: auto !important;\n}\n\n.user-select-none {\n  -webkit-user-select: none !important;\n  -moz-user-select: none !important;\n  user-select: none !important;\n}\n\n.pe-none {\n  pointer-events: none !important;\n}\n\n.pe-auto {\n  pointer-events: auto !important;\n}\n\n.rounded {\n  border-radius: 0.25rem !important;\n}\n\n.rounded-0 {\n  border-radius: 0 !important;\n}\n\n.rounded-1 {\n  border-radius: 0.2rem !important;\n}\n\n.rounded-2 {\n  border-radius: 0.25rem !important;\n}\n\n.rounded-3 {\n  border-radius: 0.3rem !important;\n}\n\n.rounded-circle {\n  border-radius: 50% !important;\n}\n\n.rounded-pill {\n  border-radius: 50rem !important;\n}\n\n.rounded-top {\n  border-top-left-radius: 0.25rem !important;\n  border-top-right-radius: 0.25rem !important;\n}\n\n.rounded-end {\n  border-top-right-radius: 0.25rem !important;\n  border-bottom-right-radius: 0.25rem !important;\n}\n\n.rounded-bottom {\n  border-bottom-right-radius: 0.25rem !important;\n  border-bottom-left-radius: 0.25rem !important;\n}\n\n.rounded-start {\n  border-bottom-left-radius: 0.25rem !important;\n  border-top-left-radius: 0.25rem !important;\n}\n\n.visible {\n  visibility: visible !important;\n}\n\n.invisible {\n  visibility: hidden !important;\n}\n\n@media (min-width: 576px) {\n  .float-sm-start {\n    float: left !important;\n  }\n\n  .float-sm-end {\n    float: right !important;\n  }\n\n  .float-sm-none {\n    float: none !important;\n  }\n\n  .d-sm-inline {\n    display: inline !important;\n  }\n\n  .d-sm-inline-block {\n    display: inline-block !important;\n  }\n\n  .d-sm-block {\n    display: block !important;\n  }\n\n  .d-sm-grid {\n    display: grid !important;\n  }\n\n  .d-sm-table {\n    display: table !important;\n  }\n\n  .d-sm-table-row {\n    display: table-row !important;\n  }\n\n  .d-sm-table-cell {\n    display: table-cell !important;\n  }\n\n  .d-sm-flex {\n    display: flex !important;\n  }\n\n  .d-sm-inline-flex {\n    display: inline-flex !important;\n  }\n\n  .d-sm-none {\n    display: none !important;\n  }\n\n  .flex-sm-fill {\n    flex: 1 1 auto !important;\n  }\n\n  .flex-sm-row {\n    flex-direction: row !important;\n  }\n\n  .flex-sm-column {\n    flex-direction: column !important;\n  }\n\n  .flex-sm-row-reverse {\n    flex-direction: row-reverse !important;\n  }\n\n  .flex-sm-column-reverse {\n    flex-direction: column-reverse !important;\n  }\n\n  .flex-sm-grow-0 {\n    flex-grow: 0 !important;\n  }\n\n  .flex-sm-grow-1 {\n    flex-grow: 1 !important;\n  }\n\n  .flex-sm-shrink-0 {\n    flex-shrink: 0 !important;\n  }\n\n  .flex-sm-shrink-1 {\n    flex-shrink: 1 !important;\n  }\n\n  .flex-sm-wrap {\n    flex-wrap: wrap !important;\n  }\n\n  .flex-sm-nowrap {\n    flex-wrap: nowrap !important;\n  }\n\n  .flex-sm-wrap-reverse {\n    flex-wrap: wrap-reverse !important;\n  }\n\n  .gap-sm-0 {\n    gap: 0 !important;\n  }\n\n  .gap-sm-1 {\n    gap: 0.25rem !important;\n  }\n\n  .gap-sm-2 {\n    gap: 0.5rem !important;\n  }\n\n  .gap-sm-3 {\n    gap: 1rem !important;\n  }\n\n  .gap-sm-4 {\n    gap: 1.5rem !important;\n  }\n\n  .gap-sm-5 {\n    gap: 3rem !important;\n  }\n\n  .justify-content-sm-start {\n    justify-content: flex-start !important;\n  }\n\n  .justify-content-sm-end {\n    justify-content: flex-end !important;\n  }\n\n  .justify-content-sm-center {\n    justify-content: center !important;\n  }\n\n  .justify-content-sm-between {\n    justify-content: space-between !important;\n  }\n\n  .justify-content-sm-around {\n    justify-content: space-around !important;\n  }\n\n  .justify-content-sm-evenly {\n    justify-content: space-evenly !important;\n  }\n\n  .align-items-sm-start {\n    align-items: flex-start !important;\n  }\n\n  .align-items-sm-end {\n    align-items: flex-end !important;\n  }\n\n  .align-items-sm-center {\n    align-items: center !important;\n  }\n\n  .align-items-sm-baseline {\n    align-items: baseline !important;\n  }\n\n  .align-items-sm-stretch {\n    align-items: stretch !important;\n  }\n\n  .align-content-sm-start {\n    align-content: flex-start !important;\n  }\n\n  .align-content-sm-end {\n    align-content: flex-end !important;\n  }\n\n  .align-content-sm-center {\n    align-content: center !important;\n  }\n\n  .align-content-sm-between {\n    align-content: space-between !important;\n  }\n\n  .align-content-sm-around {\n    align-content: space-around !important;\n  }\n\n  .align-content-sm-stretch {\n    align-content: stretch !important;\n  }\n\n  .align-self-sm-auto {\n    align-self: auto !important;\n  }\n\n  .align-self-sm-start {\n    align-self: flex-start !important;\n  }\n\n  .align-self-sm-end {\n    align-self: flex-end !important;\n  }\n\n  .align-self-sm-center {\n    align-self: center !important;\n  }\n\n  .align-self-sm-baseline {\n    align-self: baseline !important;\n  }\n\n  .align-self-sm-stretch {\n    align-self: stretch !important;\n  }\n\n  .order-sm-first {\n    order: -1 !important;\n  }\n\n  .order-sm-0 {\n    order: 0 !important;\n  }\n\n  .order-sm-1 {\n    order: 1 !important;\n  }\n\n  .order-sm-2 {\n    order: 2 !important;\n  }\n\n  .order-sm-3 {\n    order: 3 !important;\n  }\n\n  .order-sm-4 {\n    order: 4 !important;\n  }\n\n  .order-sm-5 {\n    order: 5 !important;\n  }\n\n  .order-sm-last {\n    order: 6 !important;\n  }\n\n  .m-sm-0 {\n    margin: 0 !important;\n  }\n\n  .m-sm-1 {\n    margin: 0.25rem !important;\n  }\n\n  .m-sm-2 {\n    margin: 0.5rem !important;\n  }\n\n  .m-sm-3 {\n    margin: 1rem !important;\n  }\n\n  .m-sm-4 {\n    margin: 1.5rem !important;\n  }\n\n  .m-sm-5 {\n    margin: 3rem !important;\n  }\n\n  .m-sm-auto {\n    margin: auto !important;\n  }\n\n  .mx-sm-0 {\n    margin-right: 0 !important;\n    margin-left: 0 !important;\n  }\n\n  .mx-sm-1 {\n    margin-right: 0.25rem !important;\n    margin-left: 0.25rem !important;\n  }\n\n  .mx-sm-2 {\n    margin-right: 0.5rem !important;\n    margin-left: 0.5rem !important;\n  }\n\n  .mx-sm-3 {\n    margin-right: 1rem !important;\n    margin-left: 1rem !important;\n  }\n\n  .mx-sm-4 {\n    margin-right: 1.5rem !important;\n    margin-left: 1.5rem !important;\n  }\n\n  .mx-sm-5 {\n    margin-right: 3rem !important;\n    margin-left: 3rem !important;\n  }\n\n  .mx-sm-auto {\n    margin-right: auto !important;\n    margin-left: auto !important;\n  }\n\n  .my-sm-0 {\n    margin-top: 0 !important;\n    margin-bottom: 0 !important;\n  }\n\n  .my-sm-1 {\n    margin-top: 0.25rem !important;\n    margin-bottom: 0.25rem !important;\n  }\n\n  .my-sm-2 {\n    margin-top: 0.5rem !important;\n    margin-bottom: 0.5rem !important;\n  }\n\n  .my-sm-3 {\n    margin-top: 1rem !important;\n    margin-bottom: 1rem !important;\n  }\n\n  .my-sm-4 {\n    margin-top: 1.5rem !important;\n    margin-bottom: 1.5rem !important;\n  }\n\n  .my-sm-5 {\n    margin-top: 3rem !important;\n    margin-bottom: 3rem !important;\n  }\n\n  .my-sm-auto {\n    margin-top: auto !important;\n    margin-bottom: auto !important;\n  }\n\n  .mt-sm-0 {\n    margin-top: 0 !important;\n  }\n\n  .mt-sm-1 {\n    margin-top: 0.25rem !important;\n  }\n\n  .mt-sm-2 {\n    margin-top: 0.5rem !important;\n  }\n\n  .mt-sm-3 {\n    margin-top: 1rem !important;\n  }\n\n  .mt-sm-4 {\n    margin-top: 1.5rem !important;\n  }\n\n  .mt-sm-5 {\n    margin-top: 3rem !important;\n  }\n\n  .mt-sm-auto {\n    margin-top: auto !important;\n  }\n\n  .me-sm-0 {\n    margin-right: 0 !important;\n  }\n\n  .me-sm-1 {\n    margin-right: 0.25rem !important;\n  }\n\n  .me-sm-2 {\n    margin-right: 0.5rem !important;\n  }\n\n  .me-sm-3 {\n    margin-right: 1rem !important;\n  }\n\n  .me-sm-4 {\n    margin-right: 1.5rem !important;\n  }\n\n  .me-sm-5 {\n    margin-right: 3rem !important;\n  }\n\n  .me-sm-auto {\n    margin-right: auto !important;\n  }\n\n  .mb-sm-0 {\n    margin-bottom: 0 !important;\n  }\n\n  .mb-sm-1 {\n    margin-bottom: 0.25rem !important;\n  }\n\n  .mb-sm-2 {\n    margin-bottom: 0.5rem !important;\n  }\n\n  .mb-sm-3 {\n    margin-bottom: 1rem !important;\n  }\n\n  .mb-sm-4 {\n    margin-bottom: 1.5rem !important;\n  }\n\n  .mb-sm-5 {\n    margin-bottom: 3rem !important;\n  }\n\n  .mb-sm-auto {\n    margin-bottom: auto !important;\n  }\n\n  .ms-sm-0 {\n    margin-left: 0 !important;\n  }\n\n  .ms-sm-1 {\n    margin-left: 0.25rem !important;\n  }\n\n  .ms-sm-2 {\n    margin-left: 0.5rem !important;\n  }\n\n  .ms-sm-3 {\n    margin-left: 1rem !important;\n  }\n\n  .ms-sm-4 {\n    margin-left: 1.5rem !important;\n  }\n\n  .ms-sm-5 {\n    margin-left: 3rem !important;\n  }\n\n  .ms-sm-auto {\n    margin-left: auto !important;\n  }\n\n  .p-sm-0 {\n    padding: 0 !important;\n  }\n\n  .p-sm-1 {\n    padding: 0.25rem !important;\n  }\n\n  .p-sm-2 {\n    padding: 0.5rem !important;\n  }\n\n  .p-sm-3 {\n    padding: 1rem !important;\n  }\n\n  .p-sm-4 {\n    padding: 1.5rem !important;\n  }\n\n  .p-sm-5 {\n    padding: 3rem !important;\n  }\n\n  .px-sm-0 {\n    padding-right: 0 !important;\n    padding-left: 0 !important;\n  }\n\n  .px-sm-1 {\n    padding-right: 0.25rem !important;\n    padding-left: 0.25rem !important;\n  }\n\n  .px-sm-2 {\n    padding-right: 0.5rem !important;\n    padding-left: 0.5rem !important;\n  }\n\n  .px-sm-3 {\n    padding-right: 1rem !important;\n    padding-left: 1rem !important;\n  }\n\n  .px-sm-4 {\n    padding-right: 1.5rem !important;\n    padding-left: 1.5rem !important;\n  }\n\n  .px-sm-5 {\n    padding-right: 3rem !important;\n    padding-left: 3rem !important;\n  }\n\n  .py-sm-0 {\n    padding-top: 0 !important;\n    padding-bottom: 0 !important;\n  }\n\n  .py-sm-1 {\n    padding-top: 0.25rem !important;\n    padding-bottom: 0.25rem !important;\n  }\n\n  .py-sm-2 {\n    padding-top: 0.5rem !important;\n    padding-bottom: 0.5rem !important;\n  }\n\n  .py-sm-3 {\n    padding-top: 1rem !important;\n    padding-bottom: 1rem !important;\n  }\n\n  .py-sm-4 {\n    padding-top: 1.5rem !important;\n    padding-bottom: 1.5rem !important;\n  }\n\n  .py-sm-5 {\n    padding-top: 3rem !important;\n    padding-bottom: 3rem !important;\n  }\n\n  .pt-sm-0 {\n    padding-top: 0 !important;\n  }\n\n  .pt-sm-1 {\n    padding-top: 0.25rem !important;\n  }\n\n  .pt-sm-2 {\n    padding-top: 0.5rem !important;\n  }\n\n  .pt-sm-3 {\n    padding-top: 1rem !important;\n  }\n\n  .pt-sm-4 {\n    padding-top: 1.5rem !important;\n  }\n\n  .pt-sm-5 {\n    padding-top: 3rem !important;\n  }\n\n  .pe-sm-0 {\n    padding-right: 0 !important;\n  }\n\n  .pe-sm-1 {\n    padding-right: 0.25rem !important;\n  }\n\n  .pe-sm-2 {\n    padding-right: 0.5rem !important;\n  }\n\n  .pe-sm-3 {\n    padding-right: 1rem !important;\n  }\n\n  .pe-sm-4 {\n    padding-right: 1.5rem !important;\n  }\n\n  .pe-sm-5 {\n    padding-right: 3rem !important;\n  }\n\n  .pb-sm-0 {\n    padding-bottom: 0 !important;\n  }\n\n  .pb-sm-1 {\n    padding-bottom: 0.25rem !important;\n  }\n\n  .pb-sm-2 {\n    padding-bottom: 0.5rem !important;\n  }\n\n  .pb-sm-3 {\n    padding-bottom: 1rem !important;\n  }\n\n  .pb-sm-4 {\n    padding-bottom: 1.5rem !important;\n  }\n\n  .pb-sm-5 {\n    padding-bottom: 3rem !important;\n  }\n\n  .ps-sm-0 {\n    padding-left: 0 !important;\n  }\n\n  .ps-sm-1 {\n    padding-left: 0.25rem !important;\n  }\n\n  .ps-sm-2 {\n    padding-left: 0.5rem !important;\n  }\n\n  .ps-sm-3 {\n    padding-left: 1rem !important;\n  }\n\n  .ps-sm-4 {\n    padding-left: 1.5rem !important;\n  }\n\n  .ps-sm-5 {\n    padding-left: 3rem !important;\n  }\n\n  .text-sm-start {\n    text-align: left !important;\n  }\n\n  .text-sm-end {\n    text-align: right !important;\n  }\n\n  .text-sm-center {\n    text-align: center !important;\n  }\n}\n@media (min-width: 768px) {\n  .float-md-start {\n    float: left !important;\n  }\n\n  .float-md-end {\n    float: right !important;\n  }\n\n  .float-md-none {\n    float: none !important;\n  }\n\n  .d-md-inline {\n    display: inline !important;\n  }\n\n  .d-md-inline-block {\n    display: inline-block !important;\n  }\n\n  .d-md-block {\n    display: block !important;\n  }\n\n  .d-md-grid {\n    display: grid !important;\n  }\n\n  .d-md-table {\n    display: table !important;\n  }\n\n  .d-md-table-row {\n    display: table-row !important;\n  }\n\n  .d-md-table-cell {\n    display: table-cell !important;\n  }\n\n  .d-md-flex {\n    display: flex !important;\n  }\n\n  .d-md-inline-flex {\n    display: inline-flex !important;\n  }\n\n  .d-md-none {\n    display: none !important;\n  }\n\n  .flex-md-fill {\n    flex: 1 1 auto !important;\n  }\n\n  .flex-md-row {\n    flex-direction: row !important;\n  }\n\n  .flex-md-column {\n    flex-direction: column !important;\n  }\n\n  .flex-md-row-reverse {\n    flex-direction: row-reverse !important;\n  }\n\n  .flex-md-column-reverse {\n    flex-direction: column-reverse !important;\n  }\n\n  .flex-md-grow-0 {\n    flex-grow: 0 !important;\n  }\n\n  .flex-md-grow-1 {\n    flex-grow: 1 !important;\n  }\n\n  .flex-md-shrink-0 {\n    flex-shrink: 0 !important;\n  }\n\n  .flex-md-shrink-1 {\n    flex-shrink: 1 !important;\n  }\n\n  .flex-md-wrap {\n    flex-wrap: wrap !important;\n  }\n\n  .flex-md-nowrap {\n    flex-wrap: nowrap !important;\n  }\n\n  .flex-md-wrap-reverse {\n    flex-wrap: wrap-reverse !important;\n  }\n\n  .gap-md-0 {\n    gap: 0 !important;\n  }\n\n  .gap-md-1 {\n    gap: 0.25rem !important;\n  }\n\n  .gap-md-2 {\n    gap: 0.5rem !important;\n  }\n\n  .gap-md-3 {\n    gap: 1rem !important;\n  }\n\n  .gap-md-4 {\n    gap: 1.5rem !important;\n  }\n\n  .gap-md-5 {\n    gap: 3rem !important;\n  }\n\n  .justify-content-md-start {\n    justify-content: flex-start !important;\n  }\n\n  .justify-content-md-end {\n    justify-content: flex-end !important;\n  }\n\n  .justify-content-md-center {\n    justify-content: center !important;\n  }\n\n  .justify-content-md-between {\n    justify-content: space-between !important;\n  }\n\n  .justify-content-md-around {\n    justify-content: space-around !important;\n  }\n\n  .justify-content-md-evenly {\n    justify-content: space-evenly !important;\n  }\n\n  .align-items-md-start {\n    align-items: flex-start !important;\n  }\n\n  .align-items-md-end {\n    align-items: flex-end !important;\n  }\n\n  .align-items-md-center {\n    align-items: center !important;\n  }\n\n  .align-items-md-baseline {\n    align-items: baseline !important;\n  }\n\n  .align-items-md-stretch {\n    align-items: stretch !important;\n  }\n\n  .align-content-md-start {\n    align-content: flex-start !important;\n  }\n\n  .align-content-md-end {\n    align-content: flex-end !important;\n  }\n\n  .align-content-md-center {\n    align-content: center !important;\n  }\n\n  .align-content-md-between {\n    align-content: space-between !important;\n  }\n\n  .align-content-md-around {\n    align-content: space-around !important;\n  }\n\n  .align-content-md-stretch {\n    align-content: stretch !important;\n  }\n\n  .align-self-md-auto {\n    align-self: auto !important;\n  }\n\n  .align-self-md-start {\n    align-self: flex-start !important;\n  }\n\n  .align-self-md-end {\n    align-self: flex-end !important;\n  }\n\n  .align-self-md-center {\n    align-self: center !important;\n  }\n\n  .align-self-md-baseline {\n    align-self: baseline !important;\n  }\n\n  .align-self-md-stretch {\n    align-self: stretch !important;\n  }\n\n  .order-md-first {\n    order: -1 !important;\n  }\n\n  .order-md-0 {\n    order: 0 !important;\n  }\n\n  .order-md-1 {\n    order: 1 !important;\n  }\n\n  .order-md-2 {\n    order: 2 !important;\n  }\n\n  .order-md-3 {\n    order: 3 !important;\n  }\n\n  .order-md-4 {\n    order: 4 !important;\n  }\n\n  .order-md-5 {\n    order: 5 !important;\n  }\n\n  .order-md-last {\n    order: 6 !important;\n  }\n\n  .m-md-0 {\n    margin: 0 !important;\n  }\n\n  .m-md-1 {\n    margin: 0.25rem !important;\n  }\n\n  .m-md-2 {\n    margin: 0.5rem !important;\n  }\n\n  .m-md-3 {\n    margin: 1rem !important;\n  }\n\n  .m-md-4 {\n    margin: 1.5rem !important;\n  }\n\n  .m-md-5 {\n    margin: 3rem !important;\n  }\n\n  .m-md-auto {\n    margin: auto !important;\n  }\n\n  .mx-md-0 {\n    margin-right: 0 !important;\n    margin-left: 0 !important;\n  }\n\n  .mx-md-1 {\n    margin-right: 0.25rem !important;\n    margin-left: 0.25rem !important;\n  }\n\n  .mx-md-2 {\n    margin-right: 0.5rem !important;\n    margin-left: 0.5rem !important;\n  }\n\n  .mx-md-3 {\n    margin-right: 1rem !important;\n    margin-left: 1rem !important;\n  }\n\n  .mx-md-4 {\n    margin-right: 1.5rem !important;\n    margin-left: 1.5rem !important;\n  }\n\n  .mx-md-5 {\n    margin-right: 3rem !important;\n    margin-left: 3rem !important;\n  }\n\n  .mx-md-auto {\n    margin-right: auto !important;\n    margin-left: auto !important;\n  }\n\n  .my-md-0 {\n    margin-top: 0 !important;\n    margin-bottom: 0 !important;\n  }\n\n  .my-md-1 {\n    margin-top: 0.25rem !important;\n    margin-bottom: 0.25rem !important;\n  }\n\n  .my-md-2 {\n    margin-top: 0.5rem !important;\n    margin-bottom: 0.5rem !important;\n  }\n\n  .my-md-3 {\n    margin-top: 1rem !important;\n    margin-bottom: 1rem !important;\n  }\n\n  .my-md-4 {\n    margin-top: 1.5rem !important;\n    margin-bottom: 1.5rem !important;\n  }\n\n  .my-md-5 {\n    margin-top: 3rem !important;\n    margin-bottom: 3rem !important;\n  }\n\n  .my-md-auto {\n    margin-top: auto !important;\n    margin-bottom: auto !important;\n  }\n\n  .mt-md-0 {\n    margin-top: 0 !important;\n  }\n\n  .mt-md-1 {\n    margin-top: 0.25rem !important;\n  }\n\n  .mt-md-2 {\n    margin-top: 0.5rem !important;\n  }\n\n  .mt-md-3 {\n    margin-top: 1rem !important;\n  }\n\n  .mt-md-4 {\n    margin-top: 1.5rem !important;\n  }\n\n  .mt-md-5 {\n    margin-top: 3rem !important;\n  }\n\n  .mt-md-auto {\n    margin-top: auto !important;\n  }\n\n  .me-md-0 {\n    margin-right: 0 !important;\n  }\n\n  .me-md-1 {\n    margin-right: 0.25rem !important;\n  }\n\n  .me-md-2 {\n    margin-right: 0.5rem !important;\n  }\n\n  .me-md-3 {\n    margin-right: 1rem !important;\n  }\n\n  .me-md-4 {\n    margin-right: 1.5rem !important;\n  }\n\n  .me-md-5 {\n    margin-right: 3rem !important;\n  }\n\n  .me-md-auto {\n    margin-right: auto !important;\n  }\n\n  .mb-md-0 {\n    margin-bottom: 0 !important;\n  }\n\n  .mb-md-1 {\n    margin-bottom: 0.25rem !important;\n  }\n\n  .mb-md-2 {\n    margin-bottom: 0.5rem !important;\n  }\n\n  .mb-md-3 {\n    margin-bottom: 1rem !important;\n  }\n\n  .mb-md-4 {\n    margin-bottom: 1.5rem !important;\n  }\n\n  .mb-md-5 {\n    margin-bottom: 3rem !important;\n  }\n\n  .mb-md-auto {\n    margin-bottom: auto !important;\n  }\n\n  .ms-md-0 {\n    margin-left: 0 !important;\n  }\n\n  .ms-md-1 {\n    margin-left: 0.25rem !important;\n  }\n\n  .ms-md-2 {\n    margin-left: 0.5rem !important;\n  }\n\n  .ms-md-3 {\n    margin-left: 1rem !important;\n  }\n\n  .ms-md-4 {\n    margin-left: 1.5rem !important;\n  }\n\n  .ms-md-5 {\n    margin-left: 3rem !important;\n  }\n\n  .ms-md-auto {\n    margin-left: auto !important;\n  }\n\n  .p-md-0 {\n    padding: 0 !important;\n  }\n\n  .p-md-1 {\n    padding: 0.25rem !important;\n  }\n\n  .p-md-2 {\n    padding: 0.5rem !important;\n  }\n\n  .p-md-3 {\n    padding: 1rem !important;\n  }\n\n  .p-md-4 {\n    padding: 1.5rem !important;\n  }\n\n  .p-md-5 {\n    padding: 3rem !important;\n  }\n\n  .px-md-0 {\n    padding-right: 0 !important;\n    padding-left: 0 !important;\n  }\n\n  .px-md-1 {\n    padding-right: 0.25rem !important;\n    padding-left: 0.25rem !important;\n  }\n\n  .px-md-2 {\n    padding-right: 0.5rem !important;\n    padding-left: 0.5rem !important;\n  }\n\n  .px-md-3 {\n    padding-right: 1rem !important;\n    padding-left: 1rem !important;\n  }\n\n  .px-md-4 {\n    padding-right: 1.5rem !important;\n    padding-left: 1.5rem !important;\n  }\n\n  .px-md-5 {\n    padding-right: 3rem !important;\n    padding-left: 3rem !important;\n  }\n\n  .py-md-0 {\n    padding-top: 0 !important;\n    padding-bottom: 0 !important;\n  }\n\n  .py-md-1 {\n    padding-top: 0.25rem !important;\n    padding-bottom: 0.25rem !important;\n  }\n\n  .py-md-2 {\n    padding-top: 0.5rem !important;\n    padding-bottom: 0.5rem !important;\n  }\n\n  .py-md-3 {\n    padding-top: 1rem !important;\n    padding-bottom: 1rem !important;\n  }\n\n  .py-md-4 {\n    padding-top: 1.5rem !important;\n    padding-bottom: 1.5rem !important;\n  }\n\n  .py-md-5 {\n    padding-top: 3rem !important;\n    padding-bottom: 3rem !important;\n  }\n\n  .pt-md-0 {\n    padding-top: 0 !important;\n  }\n\n  .pt-md-1 {\n    padding-top: 0.25rem !important;\n  }\n\n  .pt-md-2 {\n    padding-top: 0.5rem !important;\n  }\n\n  .pt-md-3 {\n    padding-top: 1rem !important;\n  }\n\n  .pt-md-4 {\n    padding-top: 1.5rem !important;\n  }\n\n  .pt-md-5 {\n    padding-top: 3rem !important;\n  }\n\n  .pe-md-0 {\n    padding-right: 0 !important;\n  }\n\n  .pe-md-1 {\n    padding-right: 0.25rem !important;\n  }\n\n  .pe-md-2 {\n    padding-right: 0.5rem !important;\n  }\n\n  .pe-md-3 {\n    padding-right: 1rem !important;\n  }\n\n  .pe-md-4 {\n    padding-right: 1.5rem !important;\n  }\n\n  .pe-md-5 {\n    padding-right: 3rem !important;\n  }\n\n  .pb-md-0 {\n    padding-bottom: 0 !important;\n  }\n\n  .pb-md-1 {\n    padding-bottom: 0.25rem !important;\n  }\n\n  .pb-md-2 {\n    padding-bottom: 0.5rem !important;\n  }\n\n  .pb-md-3 {\n    padding-bottom: 1rem !important;\n  }\n\n  .pb-md-4 {\n    padding-bottom: 1.5rem !important;\n  }\n\n  .pb-md-5 {\n    padding-bottom: 3rem !important;\n  }\n\n  .ps-md-0 {\n    padding-left: 0 !important;\n  }\n\n  .ps-md-1 {\n    padding-left: 0.25rem !important;\n  }\n\n  .ps-md-2 {\n    padding-left: 0.5rem !important;\n  }\n\n  .ps-md-3 {\n    padding-left: 1rem !important;\n  }\n\n  .ps-md-4 {\n    padding-left: 1.5rem !important;\n  }\n\n  .ps-md-5 {\n    padding-left: 3rem !important;\n  }\n\n  .text-md-start {\n    text-align: left !important;\n  }\n\n  .text-md-end {\n    text-align: right !important;\n  }\n\n  .text-md-center {\n    text-align: center !important;\n  }\n}\n@media (min-width: 992px) {\n  .float-lg-start {\n    float: left !important;\n  }\n\n  .float-lg-end {\n    float: right !important;\n  }\n\n  .float-lg-none {\n    float: none !important;\n  }\n\n  .d-lg-inline {\n    display: inline !important;\n  }\n\n  .d-lg-inline-block {\n    display: inline-block !important;\n  }\n\n  .d-lg-block {\n    display: block !important;\n  }\n\n  .d-lg-grid {\n    display: grid !important;\n  }\n\n  .d-lg-table {\n    display: table !important;\n  }\n\n  .d-lg-table-row {\n    display: table-row !important;\n  }\n\n  .d-lg-table-cell {\n    display: table-cell !important;\n  }\n\n  .d-lg-flex {\n    display: flex !important;\n  }\n\n  .d-lg-inline-flex {\n    display: inline-flex !important;\n  }\n\n  .d-lg-none {\n    display: none !important;\n  }\n\n  .flex-lg-fill {\n    flex: 1 1 auto !important;\n  }\n\n  .flex-lg-row {\n    flex-direction: row !important;\n  }\n\n  .flex-lg-column {\n    flex-direction: column !important;\n  }\n\n  .flex-lg-row-reverse {\n    flex-direction: row-reverse !important;\n  }\n\n  .flex-lg-column-reverse {\n    flex-direction: column-reverse !important;\n  }\n\n  .flex-lg-grow-0 {\n    flex-grow: 0 !important;\n  }\n\n  .flex-lg-grow-1 {\n    flex-grow: 1 !important;\n  }\n\n  .flex-lg-shrink-0 {\n    flex-shrink: 0 !important;\n  }\n\n  .flex-lg-shrink-1 {\n    flex-shrink: 1 !important;\n  }\n\n  .flex-lg-wrap {\n    flex-wrap: wrap !important;\n  }\n\n  .flex-lg-nowrap {\n    flex-wrap: nowrap !important;\n  }\n\n  .flex-lg-wrap-reverse {\n    flex-wrap: wrap-reverse !important;\n  }\n\n  .gap-lg-0 {\n    gap: 0 !important;\n  }\n\n  .gap-lg-1 {\n    gap: 0.25rem !important;\n  }\n\n  .gap-lg-2 {\n    gap: 0.5rem !important;\n  }\n\n  .gap-lg-3 {\n    gap: 1rem !important;\n  }\n\n  .gap-lg-4 {\n    gap: 1.5rem !important;\n  }\n\n  .gap-lg-5 {\n    gap: 3rem !important;\n  }\n\n  .justify-content-lg-start {\n    justify-content: flex-start !important;\n  }\n\n  .justify-content-lg-end {\n    justify-content: flex-end !important;\n  }\n\n  .justify-content-lg-center {\n    justify-content: center !important;\n  }\n\n  .justify-content-lg-between {\n    justify-content: space-between !important;\n  }\n\n  .justify-content-lg-around {\n    justify-content: space-around !important;\n  }\n\n  .justify-content-lg-evenly {\n    justify-content: space-evenly !important;\n  }\n\n  .align-items-lg-start {\n    align-items: flex-start !important;\n  }\n\n  .align-items-lg-end {\n    align-items: flex-end !important;\n  }\n\n  .align-items-lg-center {\n    align-items: center !important;\n  }\n\n  .align-items-lg-baseline {\n    align-items: baseline !important;\n  }\n\n  .align-items-lg-stretch {\n    align-items: stretch !important;\n  }\n\n  .align-content-lg-start {\n    align-content: flex-start !important;\n  }\n\n  .align-content-lg-end {\n    align-content: flex-end !important;\n  }\n\n  .align-content-lg-center {\n    align-content: center !important;\n  }\n\n  .align-content-lg-between {\n    align-content: space-between !important;\n  }\n\n  .align-content-lg-around {\n    align-content: space-around !important;\n  }\n\n  .align-content-lg-stretch {\n    align-content: stretch !important;\n  }\n\n  .align-self-lg-auto {\n    align-self: auto !important;\n  }\n\n  .align-self-lg-start {\n    align-self: flex-start !important;\n  }\n\n  .align-self-lg-end {\n    align-self: flex-end !important;\n  }\n\n  .align-self-lg-center {\n    align-self: center !important;\n  }\n\n  .align-self-lg-baseline {\n    align-self: baseline !important;\n  }\n\n  .align-self-lg-stretch {\n    align-self: stretch !important;\n  }\n\n  .order-lg-first {\n    order: -1 !important;\n  }\n\n  .order-lg-0 {\n    order: 0 !important;\n  }\n\n  .order-lg-1 {\n    order: 1 !important;\n  }\n\n  .order-lg-2 {\n    order: 2 !important;\n  }\n\n  .order-lg-3 {\n    order: 3 !important;\n  }\n\n  .order-lg-4 {\n    order: 4 !important;\n  }\n\n  .order-lg-5 {\n    order: 5 !important;\n  }\n\n  .order-lg-last {\n    order: 6 !important;\n  }\n\n  .m-lg-0 {\n    margin: 0 !important;\n  }\n\n  .m-lg-1 {\n    margin: 0.25rem !important;\n  }\n\n  .m-lg-2 {\n    margin: 0.5rem !important;\n  }\n\n  .m-lg-3 {\n    margin: 1rem !important;\n  }\n\n  .m-lg-4 {\n    margin: 1.5rem !important;\n  }\n\n  .m-lg-5 {\n    margin: 3rem !important;\n  }\n\n  .m-lg-auto {\n    margin: auto !important;\n  }\n\n  .mx-lg-0 {\n    margin-right: 0 !important;\n    margin-left: 0 !important;\n  }\n\n  .mx-lg-1 {\n    margin-right: 0.25rem !important;\n    margin-left: 0.25rem !important;\n  }\n\n  .mx-lg-2 {\n    margin-right: 0.5rem !important;\n    margin-left: 0.5rem !important;\n  }\n\n  .mx-lg-3 {\n    margin-right: 1rem !important;\n    margin-left: 1rem !important;\n  }\n\n  .mx-lg-4 {\n    margin-right: 1.5rem !important;\n    margin-left: 1.5rem !important;\n  }\n\n  .mx-lg-5 {\n    margin-right: 3rem !important;\n    margin-left: 3rem !important;\n  }\n\n  .mx-lg-auto {\n    margin-right: auto !important;\n    margin-left: auto !important;\n  }\n\n  .my-lg-0 {\n    margin-top: 0 !important;\n    margin-bottom: 0 !important;\n  }\n\n  .my-lg-1 {\n    margin-top: 0.25rem !important;\n    margin-bottom: 0.25rem !important;\n  }\n\n  .my-lg-2 {\n    margin-top: 0.5rem !important;\n    margin-bottom: 0.5rem !important;\n  }\n\n  .my-lg-3 {\n    margin-top: 1rem !important;\n    margin-bottom: 1rem !important;\n  }\n\n  .my-lg-4 {\n    margin-top: 1.5rem !important;\n    margin-bottom: 1.5rem !important;\n  }\n\n  .my-lg-5 {\n    margin-top: 3rem !important;\n    margin-bottom: 3rem !important;\n  }\n\n  .my-lg-auto {\n    margin-top: auto !important;\n    margin-bottom: auto !important;\n  }\n\n  .mt-lg-0 {\n    margin-top: 0 !important;\n  }\n\n  .mt-lg-1 {\n    margin-top: 0.25rem !important;\n  }\n\n  .mt-lg-2 {\n    margin-top: 0.5rem !important;\n  }\n\n  .mt-lg-3 {\n    margin-top: 1rem !important;\n  }\n\n  .mt-lg-4 {\n    margin-top: 1.5rem !important;\n  }\n\n  .mt-lg-5 {\n    margin-top: 3rem !important;\n  }\n\n  .mt-lg-auto {\n    margin-top: auto !important;\n  }\n\n  .me-lg-0 {\n    margin-right: 0 !important;\n  }\n\n  .me-lg-1 {\n    margin-right: 0.25rem !important;\n  }\n\n  .me-lg-2 {\n    margin-right: 0.5rem !important;\n  }\n\n  .me-lg-3 {\n    margin-right: 1rem !important;\n  }\n\n  .me-lg-4 {\n    margin-right: 1.5rem !important;\n  }\n\n  .me-lg-5 {\n    margin-right: 3rem !important;\n  }\n\n  .me-lg-auto {\n    margin-right: auto !important;\n  }\n\n  .mb-lg-0 {\n    margin-bottom: 0 !important;\n  }\n\n  .mb-lg-1 {\n    margin-bottom: 0.25rem !important;\n  }\n\n  .mb-lg-2 {\n    margin-bottom: 0.5rem !important;\n  }\n\n  .mb-lg-3 {\n    margin-bottom: 1rem !important;\n  }\n\n  .mb-lg-4 {\n    margin-bottom: 1.5rem !important;\n  }\n\n  .mb-lg-5 {\n    margin-bottom: 3rem !important;\n  }\n\n  .mb-lg-auto {\n    margin-bottom: auto !important;\n  }\n\n  .ms-lg-0 {\n    margin-left: 0 !important;\n  }\n\n  .ms-lg-1 {\n    margin-left: 0.25rem !important;\n  }\n\n  .ms-lg-2 {\n    margin-left: 0.5rem !important;\n  }\n\n  .ms-lg-3 {\n    margin-left: 1rem !important;\n  }\n\n  .ms-lg-4 {\n    margin-left: 1.5rem !important;\n  }\n\n  .ms-lg-5 {\n    margin-left: 3rem !important;\n  }\n\n  .ms-lg-auto {\n    margin-left: auto !important;\n  }\n\n  .p-lg-0 {\n    padding: 0 !important;\n  }\n\n  .p-lg-1 {\n    padding: 0.25rem !important;\n  }\n\n  .p-lg-2 {\n    padding: 0.5rem !important;\n  }\n\n  .p-lg-3 {\n    padding: 1rem !important;\n  }\n\n  .p-lg-4 {\n    padding: 1.5rem !important;\n  }\n\n  .p-lg-5 {\n    padding: 3rem !important;\n  }\n\n  .px-lg-0 {\n    padding-right: 0 !important;\n    padding-left: 0 !important;\n  }\n\n  .px-lg-1 {\n    padding-right: 0.25rem !important;\n    padding-left: 0.25rem !important;\n  }\n\n  .px-lg-2 {\n    padding-right: 0.5rem !important;\n    padding-left: 0.5rem !important;\n  }\n\n  .px-lg-3 {\n    padding-right: 1rem !important;\n    padding-left: 1rem !important;\n  }\n\n  .px-lg-4 {\n    padding-right: 1.5rem !important;\n    padding-left: 1.5rem !important;\n  }\n\n  .px-lg-5 {\n    padding-right: 3rem !important;\n    padding-left: 3rem !important;\n  }\n\n  .py-lg-0 {\n    padding-top: 0 !important;\n    padding-bottom: 0 !important;\n  }\n\n  .py-lg-1 {\n    padding-top: 0.25rem !important;\n    padding-bottom: 0.25rem !important;\n  }\n\n  .py-lg-2 {\n    padding-top: 0.5rem !important;\n    padding-bottom: 0.5rem !important;\n  }\n\n  .py-lg-3 {\n    padding-top: 1rem !important;\n    padding-bottom: 1rem !important;\n  }\n\n  .py-lg-4 {\n    padding-top: 1.5rem !important;\n    padding-bottom: 1.5rem !important;\n  }\n\n  .py-lg-5 {\n    padding-top: 3rem !important;\n    padding-bottom: 3rem !important;\n  }\n\n  .pt-lg-0 {\n    padding-top: 0 !important;\n  }\n\n  .pt-lg-1 {\n    padding-top: 0.25rem !important;\n  }\n\n  .pt-lg-2 {\n    padding-top: 0.5rem !important;\n  }\n\n  .pt-lg-3 {\n    padding-top: 1rem !important;\n  }\n\n  .pt-lg-4 {\n    padding-top: 1.5rem !important;\n  }\n\n  .pt-lg-5 {\n    padding-top: 3rem !important;\n  }\n\n  .pe-lg-0 {\n    padding-right: 0 !important;\n  }\n\n  .pe-lg-1 {\n    padding-right: 0.25rem !important;\n  }\n\n  .pe-lg-2 {\n    padding-right: 0.5rem !important;\n  }\n\n  .pe-lg-3 {\n    padding-right: 1rem !important;\n  }\n\n  .pe-lg-4 {\n    padding-right: 1.5rem !important;\n  }\n\n  .pe-lg-5 {\n    padding-right: 3rem !important;\n  }\n\n  .pb-lg-0 {\n    padding-bottom: 0 !important;\n  }\n\n  .pb-lg-1 {\n    padding-bottom: 0.25rem !important;\n  }\n\n  .pb-lg-2 {\n    padding-bottom: 0.5rem !important;\n  }\n\n  .pb-lg-3 {\n    padding-bottom: 1rem !important;\n  }\n\n  .pb-lg-4 {\n    padding-bottom: 1.5rem !important;\n  }\n\n  .pb-lg-5 {\n    padding-bottom: 3rem !important;\n  }\n\n  .ps-lg-0 {\n    padding-left: 0 !important;\n  }\n\n  .ps-lg-1 {\n    padding-left: 0.25rem !important;\n  }\n\n  .ps-lg-2 {\n    padding-left: 0.5rem !important;\n  }\n\n  .ps-lg-3 {\n    padding-left: 1rem !important;\n  }\n\n  .ps-lg-4 {\n    padding-left: 1.5rem !important;\n  }\n\n  .ps-lg-5 {\n    padding-left: 3rem !important;\n  }\n\n  .text-lg-start {\n    text-align: left !important;\n  }\n\n  .text-lg-end {\n    text-align: right !important;\n  }\n\n  .text-lg-center {\n    text-align: center !important;\n  }\n}\n@media (min-width: 1200px) {\n  .float-xl-start {\n    float: left !important;\n  }\n\n  .float-xl-end {\n    float: right !important;\n  }\n\n  .float-xl-none {\n    float: none !important;\n  }\n\n  .d-xl-inline {\n    display: inline !important;\n  }\n\n  .d-xl-inline-block {\n    display: inline-block !important;\n  }\n\n  .d-xl-block {\n    display: block !important;\n  }\n\n  .d-xl-grid {\n    display: grid !important;\n  }\n\n  .d-xl-table {\n    display: table !important;\n  }\n\n  .d-xl-table-row {\n    display: table-row !important;\n  }\n\n  .d-xl-table-cell {\n    display: table-cell !important;\n  }\n\n  .d-xl-flex {\n    display: flex !important;\n  }\n\n  .d-xl-inline-flex {\n    display: inline-flex !important;\n  }\n\n  .d-xl-none {\n    display: none !important;\n  }\n\n  .flex-xl-fill {\n    flex: 1 1 auto !important;\n  }\n\n  .flex-xl-row {\n    flex-direction: row !important;\n  }\n\n  .flex-xl-column {\n    flex-direction: column !important;\n  }\n\n  .flex-xl-row-reverse {\n    flex-direction: row-reverse !important;\n  }\n\n  .flex-xl-column-reverse {\n    flex-direction: column-reverse !important;\n  }\n\n  .flex-xl-grow-0 {\n    flex-grow: 0 !important;\n  }\n\n  .flex-xl-grow-1 {\n    flex-grow: 1 !important;\n  }\n\n  .flex-xl-shrink-0 {\n    flex-shrink: 0 !important;\n  }\n\n  .flex-xl-shrink-1 {\n    flex-shrink: 1 !important;\n  }\n\n  .flex-xl-wrap {\n    flex-wrap: wrap !important;\n  }\n\n  .flex-xl-nowrap {\n    flex-wrap: nowrap !important;\n  }\n\n  .flex-xl-wrap-reverse {\n    flex-wrap: wrap-reverse !important;\n  }\n\n  .gap-xl-0 {\n    gap: 0 !important;\n  }\n\n  .gap-xl-1 {\n    gap: 0.25rem !important;\n  }\n\n  .gap-xl-2 {\n    gap: 0.5rem !important;\n  }\n\n  .gap-xl-3 {\n    gap: 1rem !important;\n  }\n\n  .gap-xl-4 {\n    gap: 1.5rem !important;\n  }\n\n  .gap-xl-5 {\n    gap: 3rem !important;\n  }\n\n  .justify-content-xl-start {\n    justify-content: flex-start !important;\n  }\n\n  .justify-content-xl-end {\n    justify-content: flex-end !important;\n  }\n\n  .justify-content-xl-center {\n    justify-content: center !important;\n  }\n\n  .justify-content-xl-between {\n    justify-content: space-between !important;\n  }\n\n  .justify-content-xl-around {\n    justify-content: space-around !important;\n  }\n\n  .justify-content-xl-evenly {\n    justify-content: space-evenly !important;\n  }\n\n  .align-items-xl-start {\n    align-items: flex-start !important;\n  }\n\n  .align-items-xl-end {\n    align-items: flex-end !important;\n  }\n\n  .align-items-xl-center {\n    align-items: center !important;\n  }\n\n  .align-items-xl-baseline {\n    align-items: baseline !important;\n  }\n\n  .align-items-xl-stretch {\n    align-items: stretch !important;\n  }\n\n  .align-content-xl-start {\n    align-content: flex-start !important;\n  }\n\n  .align-content-xl-end {\n    align-content: flex-end !important;\n  }\n\n  .align-content-xl-center {\n    align-content: center !important;\n  }\n\n  .align-content-xl-between {\n    align-content: space-between !important;\n  }\n\n  .align-content-xl-around {\n    align-content: space-around !important;\n  }\n\n  .align-content-xl-stretch {\n    align-content: stretch !important;\n  }\n\n  .align-self-xl-auto {\n    align-self: auto !important;\n  }\n\n  .align-self-xl-start {\n    align-self: flex-start !important;\n  }\n\n  .align-self-xl-end {\n    align-self: flex-end !important;\n  }\n\n  .align-self-xl-center {\n    align-self: center !important;\n  }\n\n  .align-self-xl-baseline {\n    align-self: baseline !important;\n  }\n\n  .align-self-xl-stretch {\n    align-self: stretch !important;\n  }\n\n  .order-xl-first {\n    order: -1 !important;\n  }\n\n  .order-xl-0 {\n    order: 0 !important;\n  }\n\n  .order-xl-1 {\n    order: 1 !important;\n  }\n\n  .order-xl-2 {\n    order: 2 !important;\n  }\n\n  .order-xl-3 {\n    order: 3 !important;\n  }\n\n  .order-xl-4 {\n    order: 4 !important;\n  }\n\n  .order-xl-5 {\n    order: 5 !important;\n  }\n\n  .order-xl-last {\n    order: 6 !important;\n  }\n\n  .m-xl-0 {\n    margin: 0 !important;\n  }\n\n  .m-xl-1 {\n    margin: 0.25rem !important;\n  }\n\n  .m-xl-2 {\n    margin: 0.5rem !important;\n  }\n\n  .m-xl-3 {\n    margin: 1rem !important;\n  }\n\n  .m-xl-4 {\n    margin: 1.5rem !important;\n  }\n\n  .m-xl-5 {\n    margin: 3rem !important;\n  }\n\n  .m-xl-auto {\n    margin: auto !important;\n  }\n\n  .mx-xl-0 {\n    margin-right: 0 !important;\n    margin-left: 0 !important;\n  }\n\n  .mx-xl-1 {\n    margin-right: 0.25rem !important;\n    margin-left: 0.25rem !important;\n  }\n\n  .mx-xl-2 {\n    margin-right: 0.5rem !important;\n    margin-left: 0.5rem !important;\n  }\n\n  .mx-xl-3 {\n    margin-right: 1rem !important;\n    margin-left: 1rem !important;\n  }\n\n  .mx-xl-4 {\n    margin-right: 1.5rem !important;\n    margin-left: 1.5rem !important;\n  }\n\n  .mx-xl-5 {\n    margin-right: 3rem !important;\n    margin-left: 3rem !important;\n  }\n\n  .mx-xl-auto {\n    margin-right: auto !important;\n    margin-left: auto !important;\n  }\n\n  .my-xl-0 {\n    margin-top: 0 !important;\n    margin-bottom: 0 !important;\n  }\n\n  .my-xl-1 {\n    margin-top: 0.25rem !important;\n    margin-bottom: 0.25rem !important;\n  }\n\n  .my-xl-2 {\n    margin-top: 0.5rem !important;\n    margin-bottom: 0.5rem !important;\n  }\n\n  .my-xl-3 {\n    margin-top: 1rem !important;\n    margin-bottom: 1rem !important;\n  }\n\n  .my-xl-4 {\n    margin-top: 1.5rem !important;\n    margin-bottom: 1.5rem !important;\n  }\n\n  .my-xl-5 {\n    margin-top: 3rem !important;\n    margin-bottom: 3rem !important;\n  }\n\n  .my-xl-auto {\n    margin-top: auto !important;\n    margin-bottom: auto !important;\n  }\n\n  .mt-xl-0 {\n    margin-top: 0 !important;\n  }\n\n  .mt-xl-1 {\n    margin-top: 0.25rem !important;\n  }\n\n  .mt-xl-2 {\n    margin-top: 0.5rem !important;\n  }\n\n  .mt-xl-3 {\n    margin-top: 1rem !important;\n  }\n\n  .mt-xl-4 {\n    margin-top: 1.5rem !important;\n  }\n\n  .mt-xl-5 {\n    margin-top: 3rem !important;\n  }\n\n  .mt-xl-auto {\n    margin-top: auto !important;\n  }\n\n  .me-xl-0 {\n    margin-right: 0 !important;\n  }\n\n  .me-xl-1 {\n    margin-right: 0.25rem !important;\n  }\n\n  .me-xl-2 {\n    margin-right: 0.5rem !important;\n  }\n\n  .me-xl-3 {\n    margin-right: 1rem !important;\n  }\n\n  .me-xl-4 {\n    margin-right: 1.5rem !important;\n  }\n\n  .me-xl-5 {\n    margin-right: 3rem !important;\n  }\n\n  .me-xl-auto {\n    margin-right: auto !important;\n  }\n\n  .mb-xl-0 {\n    margin-bottom: 0 !important;\n  }\n\n  .mb-xl-1 {\n    margin-bottom: 0.25rem !important;\n  }\n\n  .mb-xl-2 {\n    margin-bottom: 0.5rem !important;\n  }\n\n  .mb-xl-3 {\n    margin-bottom: 1rem !important;\n  }\n\n  .mb-xl-4 {\n    margin-bottom: 1.5rem !important;\n  }\n\n  .mb-xl-5 {\n    margin-bottom: 3rem !important;\n  }\n\n  .mb-xl-auto {\n    margin-bottom: auto !important;\n  }\n\n  .ms-xl-0 {\n    margin-left: 0 !important;\n  }\n\n  .ms-xl-1 {\n    margin-left: 0.25rem !important;\n  }\n\n  .ms-xl-2 {\n    margin-left: 0.5rem !important;\n  }\n\n  .ms-xl-3 {\n    margin-left: 1rem !important;\n  }\n\n  .ms-xl-4 {\n    margin-left: 1.5rem !important;\n  }\n\n  .ms-xl-5 {\n    margin-left: 3rem !important;\n  }\n\n  .ms-xl-auto {\n    margin-left: auto !important;\n  }\n\n  .p-xl-0 {\n    padding: 0 !important;\n  }\n\n  .p-xl-1 {\n    padding: 0.25rem !important;\n  }\n\n  .p-xl-2 {\n    padding: 0.5rem !important;\n  }\n\n  .p-xl-3 {\n    padding: 1rem !important;\n  }\n\n  .p-xl-4 {\n    padding: 1.5rem !important;\n  }\n\n  .p-xl-5 {\n    padding: 3rem !important;\n  }\n\n  .px-xl-0 {\n    padding-right: 0 !important;\n    padding-left: 0 !important;\n  }\n\n  .px-xl-1 {\n    padding-right: 0.25rem !important;\n    padding-left: 0.25rem !important;\n  }\n\n  .px-xl-2 {\n    padding-right: 0.5rem !important;\n    padding-left: 0.5rem !important;\n  }\n\n  .px-xl-3 {\n    padding-right: 1rem !important;\n    padding-left: 1rem !important;\n  }\n\n  .px-xl-4 {\n    padding-right: 1.5rem !important;\n    padding-left: 1.5rem !important;\n  }\n\n  .px-xl-5 {\n    padding-right: 3rem !important;\n    padding-left: 3rem !important;\n  }\n\n  .py-xl-0 {\n    padding-top: 0 !important;\n    padding-bottom: 0 !important;\n  }\n\n  .py-xl-1 {\n    padding-top: 0.25rem !important;\n    padding-bottom: 0.25rem !important;\n  }\n\n  .py-xl-2 {\n    padding-top: 0.5rem !important;\n    padding-bottom: 0.5rem !important;\n  }\n\n  .py-xl-3 {\n    padding-top: 1rem !important;\n    padding-bottom: 1rem !important;\n  }\n\n  .py-xl-4 {\n    padding-top: 1.5rem !important;\n    padding-bottom: 1.5rem !important;\n  }\n\n  .py-xl-5 {\n    padding-top: 3rem !important;\n    padding-bottom: 3rem !important;\n  }\n\n  .pt-xl-0 {\n    padding-top: 0 !important;\n  }\n\n  .pt-xl-1 {\n    padding-top: 0.25rem !important;\n  }\n\n  .pt-xl-2 {\n    padding-top: 0.5rem !important;\n  }\n\n  .pt-xl-3 {\n    padding-top: 1rem !important;\n  }\n\n  .pt-xl-4 {\n    padding-top: 1.5rem !important;\n  }\n\n  .pt-xl-5 {\n    padding-top: 3rem !important;\n  }\n\n  .pe-xl-0 {\n    padding-right: 0 !important;\n  }\n\n  .pe-xl-1 {\n    padding-right: 0.25rem !important;\n  }\n\n  .pe-xl-2 {\n    padding-right: 0.5rem !important;\n  }\n\n  .pe-xl-3 {\n    padding-right: 1rem !important;\n  }\n\n  .pe-xl-4 {\n    padding-right: 1.5rem !important;\n  }\n\n  .pe-xl-5 {\n    padding-right: 3rem !important;\n  }\n\n  .pb-xl-0 {\n    padding-bottom: 0 !important;\n  }\n\n  .pb-xl-1 {\n    padding-bottom: 0.25rem !important;\n  }\n\n  .pb-xl-2 {\n    padding-bottom: 0.5rem !important;\n  }\n\n  .pb-xl-3 {\n    padding-bottom: 1rem !important;\n  }\n\n  .pb-xl-4 {\n    padding-bottom: 1.5rem !important;\n  }\n\n  .pb-xl-5 {\n    padding-bottom: 3rem !important;\n  }\n\n  .ps-xl-0 {\n    padding-left: 0 !important;\n  }\n\n  .ps-xl-1 {\n    padding-left: 0.25rem !important;\n  }\n\n  .ps-xl-2 {\n    padding-left: 0.5rem !important;\n  }\n\n  .ps-xl-3 {\n    padding-left: 1rem !important;\n  }\n\n  .ps-xl-4 {\n    padding-left: 1.5rem !important;\n  }\n\n  .ps-xl-5 {\n    padding-left: 3rem !important;\n  }\n\n  .text-xl-start {\n    text-align: left !important;\n  }\n\n  .text-xl-end {\n    text-align: right !important;\n  }\n\n  .text-xl-center {\n    text-align: center !important;\n  }\n}\n@media (min-width: 1400px) {\n  .float-xxl-start {\n    float: left !important;\n  }\n\n  .float-xxl-end {\n    float: right !important;\n  }\n\n  .float-xxl-none {\n    float: none !important;\n  }\n\n  .d-xxl-inline {\n    display: inline !important;\n  }\n\n  .d-xxl-inline-block {\n    display: inline-block !important;\n  }\n\n  .d-xxl-block {\n    display: block !important;\n  }\n\n  .d-xxl-grid {\n    display: grid !important;\n  }\n\n  .d-xxl-table {\n    display: table !important;\n  }\n\n  .d-xxl-table-row {\n    display: table-row !important;\n  }\n\n  .d-xxl-table-cell {\n    display: table-cell !important;\n  }\n\n  .d-xxl-flex {\n    display: flex !important;\n  }\n\n  .d-xxl-inline-flex {\n    display: inline-flex !important;\n  }\n\n  .d-xxl-none {\n    display: none !important;\n  }\n\n  .flex-xxl-fill {\n    flex: 1 1 auto !important;\n  }\n\n  .flex-xxl-row {\n    flex-direction: row !important;\n  }\n\n  .flex-xxl-column {\n    flex-direction: column !important;\n  }\n\n  .flex-xxl-row-reverse {\n    flex-direction: row-reverse !important;\n  }\n\n  .flex-xxl-column-reverse {\n    flex-direction: column-reverse !important;\n  }\n\n  .flex-xxl-grow-0 {\n    flex-grow: 0 !important;\n  }\n\n  .flex-xxl-grow-1 {\n    flex-grow: 1 !important;\n  }\n\n  .flex-xxl-shrink-0 {\n    flex-shrink: 0 !important;\n  }\n\n  .flex-xxl-shrink-1 {\n    flex-shrink: 1 !important;\n  }\n\n  .flex-xxl-wrap {\n    flex-wrap: wrap !important;\n  }\n\n  .flex-xxl-nowrap {\n    flex-wrap: nowrap !important;\n  }\n\n  .flex-xxl-wrap-reverse {\n    flex-wrap: wrap-reverse !important;\n  }\n\n  .gap-xxl-0 {\n    gap: 0 !important;\n  }\n\n  .gap-xxl-1 {\n    gap: 0.25rem !important;\n  }\n\n  .gap-xxl-2 {\n    gap: 0.5rem !important;\n  }\n\n  .gap-xxl-3 {\n    gap: 1rem !important;\n  }\n\n  .gap-xxl-4 {\n    gap: 1.5rem !important;\n  }\n\n  .gap-xxl-5 {\n    gap: 3rem !important;\n  }\n\n  .justify-content-xxl-start {\n    justify-content: flex-start !important;\n  }\n\n  .justify-content-xxl-end {\n    justify-content: flex-end !important;\n  }\n\n  .justify-content-xxl-center {\n    justify-content: center !important;\n  }\n\n  .justify-content-xxl-between {\n    justify-content: space-between !important;\n  }\n\n  .justify-content-xxl-around {\n    justify-content: space-around !important;\n  }\n\n  .justify-content-xxl-evenly {\n    justify-content: space-evenly !important;\n  }\n\n  .align-items-xxl-start {\n    align-items: flex-start !important;\n  }\n\n  .align-items-xxl-end {\n    align-items: flex-end !important;\n  }\n\n  .align-items-xxl-center {\n    align-items: center !important;\n  }\n\n  .align-items-xxl-baseline {\n    align-items: baseline !important;\n  }\n\n  .align-items-xxl-stretch {\n    align-items: stretch !important;\n  }\n\n  .align-content-xxl-start {\n    align-content: flex-start !important;\n  }\n\n  .align-content-xxl-end {\n    align-content: flex-end !important;\n  }\n\n  .align-content-xxl-center {\n    align-content: center !important;\n  }\n\n  .align-content-xxl-between {\n    align-content: space-between !important;\n  }\n\n  .align-content-xxl-around {\n    align-content: space-around !important;\n  }\n\n  .align-content-xxl-stretch {\n    align-content: stretch !important;\n  }\n\n  .align-self-xxl-auto {\n    align-self: auto !important;\n  }\n\n  .align-self-xxl-start {\n    align-self: flex-start !important;\n  }\n\n  .align-self-xxl-end {\n    align-self: flex-end !important;\n  }\n\n  .align-self-xxl-center {\n    align-self: center !important;\n  }\n\n  .align-self-xxl-baseline {\n    align-self: baseline !important;\n  }\n\n  .align-self-xxl-stretch {\n    align-self: stretch !important;\n  }\n\n  .order-xxl-first {\n    order: -1 !important;\n  }\n\n  .order-xxl-0 {\n    order: 0 !important;\n  }\n\n  .order-xxl-1 {\n    order: 1 !important;\n  }\n\n  .order-xxl-2 {\n    order: 2 !important;\n  }\n\n  .order-xxl-3 {\n    order: 3 !important;\n  }\n\n  .order-xxl-4 {\n    order: 4 !important;\n  }\n\n  .order-xxl-5 {\n    order: 5 !important;\n  }\n\n  .order-xxl-last {\n    order: 6 !important;\n  }\n\n  .m-xxl-0 {\n    margin: 0 !important;\n  }\n\n  .m-xxl-1 {\n    margin: 0.25rem !important;\n  }\n\n  .m-xxl-2 {\n    margin: 0.5rem !important;\n  }\n\n  .m-xxl-3 {\n    margin: 1rem !important;\n  }\n\n  .m-xxl-4 {\n    margin: 1.5rem !important;\n  }\n\n  .m-xxl-5 {\n    margin: 3rem !important;\n  }\n\n  .m-xxl-auto {\n    margin: auto !important;\n  }\n\n  .mx-xxl-0 {\n    margin-right: 0 !important;\n    margin-left: 0 !important;\n  }\n\n  .mx-xxl-1 {\n    margin-right: 0.25rem !important;\n    margin-left: 0.25rem !important;\n  }\n\n  .mx-xxl-2 {\n    margin-right: 0.5rem !important;\n    margin-left: 0.5rem !important;\n  }\n\n  .mx-xxl-3 {\n    margin-right: 1rem !important;\n    margin-left: 1rem !important;\n  }\n\n  .mx-xxl-4 {\n    margin-right: 1.5rem !important;\n    margin-left: 1.5rem !important;\n  }\n\n  .mx-xxl-5 {\n    margin-right: 3rem !important;\n    margin-left: 3rem !important;\n  }\n\n  .mx-xxl-auto {\n    margin-right: auto !important;\n    margin-left: auto !important;\n  }\n\n  .my-xxl-0 {\n    margin-top: 0 !important;\n    margin-bottom: 0 !important;\n  }\n\n  .my-xxl-1 {\n    margin-top: 0.25rem !important;\n    margin-bottom: 0.25rem !important;\n  }\n\n  .my-xxl-2 {\n    margin-top: 0.5rem !important;\n    margin-bottom: 0.5rem !important;\n  }\n\n  .my-xxl-3 {\n    margin-top: 1rem !important;\n    margin-bottom: 1rem !important;\n  }\n\n  .my-xxl-4 {\n    margin-top: 1.5rem !important;\n    margin-bottom: 1.5rem !important;\n  }\n\n  .my-xxl-5 {\n    margin-top: 3rem !important;\n    margin-bottom: 3rem !important;\n  }\n\n  .my-xxl-auto {\n    margin-top: auto !important;\n    margin-bottom: auto !important;\n  }\n\n  .mt-xxl-0 {\n    margin-top: 0 !important;\n  }\n\n  .mt-xxl-1 {\n    margin-top: 0.25rem !important;\n  }\n\n  .mt-xxl-2 {\n    margin-top: 0.5rem !important;\n  }\n\n  .mt-xxl-3 {\n    margin-top: 1rem !important;\n  }\n\n  .mt-xxl-4 {\n    margin-top: 1.5rem !important;\n  }\n\n  .mt-xxl-5 {\n    margin-top: 3rem !important;\n  }\n\n  .mt-xxl-auto {\n    margin-top: auto !important;\n  }\n\n  .me-xxl-0 {\n    margin-right: 0 !important;\n  }\n\n  .me-xxl-1 {\n    margin-right: 0.25rem !important;\n  }\n\n  .me-xxl-2 {\n    margin-right: 0.5rem !important;\n  }\n\n  .me-xxl-3 {\n    margin-right: 1rem !important;\n  }\n\n  .me-xxl-4 {\n    margin-right: 1.5rem !important;\n  }\n\n  .me-xxl-5 {\n    margin-right: 3rem !important;\n  }\n\n  .me-xxl-auto {\n    margin-right: auto !important;\n  }\n\n  .mb-xxl-0 {\n    margin-bottom: 0 !important;\n  }\n\n  .mb-xxl-1 {\n    margin-bottom: 0.25rem !important;\n  }\n\n  .mb-xxl-2 {\n    margin-bottom: 0.5rem !important;\n  }\n\n  .mb-xxl-3 {\n    margin-bottom: 1rem !important;\n  }\n\n  .mb-xxl-4 {\n    margin-bottom: 1.5rem !important;\n  }\n\n  .mb-xxl-5 {\n    margin-bottom: 3rem !important;\n  }\n\n  .mb-xxl-auto {\n    margin-bottom: auto !important;\n  }\n\n  .ms-xxl-0 {\n    margin-left: 0 !important;\n  }\n\n  .ms-xxl-1 {\n    margin-left: 0.25rem !important;\n  }\n\n  .ms-xxl-2 {\n    margin-left: 0.5rem !important;\n  }\n\n  .ms-xxl-3 {\n    margin-left: 1rem !important;\n  }\n\n  .ms-xxl-4 {\n    margin-left: 1.5rem !important;\n  }\n\n  .ms-xxl-5 {\n    margin-left: 3rem !important;\n  }\n\n  .ms-xxl-auto {\n    margin-left: auto !important;\n  }\n\n  .p-xxl-0 {\n    padding: 0 !important;\n  }\n\n  .p-xxl-1 {\n    padding: 0.25rem !important;\n  }\n\n  .p-xxl-2 {\n    padding: 0.5rem !important;\n  }\n\n  .p-xxl-3 {\n    padding: 1rem !important;\n  }\n\n  .p-xxl-4 {\n    padding: 1.5rem !important;\n  }\n\n  .p-xxl-5 {\n    padding: 3rem !important;\n  }\n\n  .px-xxl-0 {\n    padding-right: 0 !important;\n    padding-left: 0 !important;\n  }\n\n  .px-xxl-1 {\n    padding-right: 0.25rem !important;\n    padding-left: 0.25rem !important;\n  }\n\n  .px-xxl-2 {\n    padding-right: 0.5rem !important;\n    padding-left: 0.5rem !important;\n  }\n\n  .px-xxl-3 {\n    padding-right: 1rem !important;\n    padding-left: 1rem !important;\n  }\n\n  .px-xxl-4 {\n    padding-right: 1.5rem !important;\n    padding-left: 1.5rem !important;\n  }\n\n  .px-xxl-5 {\n    padding-right: 3rem !important;\n    padding-left: 3rem !important;\n  }\n\n  .py-xxl-0 {\n    padding-top: 0 !important;\n    padding-bottom: 0 !important;\n  }\n\n  .py-xxl-1 {\n    padding-top: 0.25rem !important;\n    padding-bottom: 0.25rem !important;\n  }\n\n  .py-xxl-2 {\n    padding-top: 0.5rem !important;\n    padding-bottom: 0.5rem !important;\n  }\n\n  .py-xxl-3 {\n    padding-top: 1rem !important;\n    padding-bottom: 1rem !important;\n  }\n\n  .py-xxl-4 {\n    padding-top: 1.5rem !important;\n    padding-bottom: 1.5rem !important;\n  }\n\n  .py-xxl-5 {\n    padding-top: 3rem !important;\n    padding-bottom: 3rem !important;\n  }\n\n  .pt-xxl-0 {\n    padding-top: 0 !important;\n  }\n\n  .pt-xxl-1 {\n    padding-top: 0.25rem !important;\n  }\n\n  .pt-xxl-2 {\n    padding-top: 0.5rem !important;\n  }\n\n  .pt-xxl-3 {\n    padding-top: 1rem !important;\n  }\n\n  .pt-xxl-4 {\n    padding-top: 1.5rem !important;\n  }\n\n  .pt-xxl-5 {\n    padding-top: 3rem !important;\n  }\n\n  .pe-xxl-0 {\n    padding-right: 0 !important;\n  }\n\n  .pe-xxl-1 {\n    padding-right: 0.25rem !important;\n  }\n\n  .pe-xxl-2 {\n    padding-right: 0.5rem !important;\n  }\n\n  .pe-xxl-3 {\n    padding-right: 1rem !important;\n  }\n\n  .pe-xxl-4 {\n    padding-right: 1.5rem !important;\n  }\n\n  .pe-xxl-5 {\n    padding-right: 3rem !important;\n  }\n\n  .pb-xxl-0 {\n    padding-bottom: 0 !important;\n  }\n\n  .pb-xxl-1 {\n    padding-bottom: 0.25rem !important;\n  }\n\n  .pb-xxl-2 {\n    padding-bottom: 0.5rem !important;\n  }\n\n  .pb-xxl-3 {\n    padding-bottom: 1rem !important;\n  }\n\n  .pb-xxl-4 {\n    padding-bottom: 1.5rem !important;\n  }\n\n  .pb-xxl-5 {\n    padding-bottom: 3rem !important;\n  }\n\n  .ps-xxl-0 {\n    padding-left: 0 !important;\n  }\n\n  .ps-xxl-1 {\n    padding-left: 0.25rem !important;\n  }\n\n  .ps-xxl-2 {\n    padding-left: 0.5rem !important;\n  }\n\n  .ps-xxl-3 {\n    padding-left: 1rem !important;\n  }\n\n  .ps-xxl-4 {\n    padding-left: 1.5rem !important;\n  }\n\n  .ps-xxl-5 {\n    padding-left: 3rem !important;\n  }\n\n  .text-xxl-start {\n    text-align: left !important;\n  }\n\n  .text-xxl-end {\n    text-align: right !important;\n  }\n\n  .text-xxl-center {\n    text-align: center !important;\n  }\n}\n@media (min-width: 1200px) {\n  .fs-1 {\n    font-size: 2.5rem !important;\n  }\n\n  .fs-2 {\n    font-size: 2rem !important;\n  }\n\n  .fs-3 {\n    font-size: 1.75rem !important;\n  }\n\n  .fs-4 {\n    font-size: 1.5rem !important;\n  }\n}\n@media print {\n  .d-print-inline {\n    display: inline !important;\n  }\n\n  .d-print-inline-block {\n    display: inline-block !important;\n  }\n\n  .d-print-block {\n    display: block !important;\n  }\n\n  .d-print-grid {\n    display: grid !important;\n  }\n\n  .d-print-table {\n    display: table !important;\n  }\n\n  .d-print-table-row {\n    display: table-row !important;\n  }\n\n  .d-print-table-cell {\n    display: table-cell !important;\n  }\n\n  .d-print-flex {\n    display: flex !important;\n  }\n\n  .d-print-inline-flex {\n    display: inline-flex !important;\n  }\n\n  .d-print-none {\n    display: none !important;\n  }\n}\n\n/*# sourceMappingURL=bootstrap-utilities.css.map */"
  },
  {
    "path": "sample/src/NimblePros.SampleToDo.Web/wwwroot/lib/bootstrap/dist/css/bootstrap-utilities.rtl.css",
    "content": "/*!\n * Bootstrap Utilities v5.1.0 (https://getbootstrap.com/)\n * Copyright 2011-2021 The Bootstrap Authors\n * Copyright 2011-2021 Twitter, Inc.\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n */\n.clearfix::after {\n  display: block;\n  clear: both;\n  content: \"\";\n}\n\n.link-primary {\n  color: #0d6efd;\n}\n.link-primary:hover, .link-primary:focus {\n  color: #0a58ca;\n}\n\n.link-secondary {\n  color: #6c757d;\n}\n.link-secondary:hover, .link-secondary:focus {\n  color: #565e64;\n}\n\n.link-success {\n  color: #198754;\n}\n.link-success:hover, .link-success:focus {\n  color: #146c43;\n}\n\n.link-info {\n  color: #0dcaf0;\n}\n.link-info:hover, .link-info:focus {\n  color: #3dd5f3;\n}\n\n.link-warning {\n  color: #ffc107;\n}\n.link-warning:hover, .link-warning:focus {\n  color: #ffcd39;\n}\n\n.link-danger {\n  color: #dc3545;\n}\n.link-danger:hover, .link-danger:focus {\n  color: #b02a37;\n}\n\n.link-light {\n  color: #f8f9fa;\n}\n.link-light:hover, .link-light:focus {\n  color: #f9fafb;\n}\n\n.link-dark {\n  color: #212529;\n}\n.link-dark:hover, .link-dark:focus {\n  color: #1a1e21;\n}\n\n.ratio {\n  position: relative;\n  width: 100%;\n}\n.ratio::before {\n  display: block;\n  padding-top: var(--bs-aspect-ratio);\n  content: \"\";\n}\n.ratio > * {\n  position: absolute;\n  top: 0;\n  right: 0;\n  width: 100%;\n  height: 100%;\n}\n\n.ratio-1x1 {\n  --bs-aspect-ratio: 100%;\n}\n\n.ratio-4x3 {\n  --bs-aspect-ratio: calc(3 / 4 * 100%);\n}\n\n.ratio-16x9 {\n  --bs-aspect-ratio: calc(9 / 16 * 100%);\n}\n\n.ratio-21x9 {\n  --bs-aspect-ratio: calc(9 / 21 * 100%);\n}\n\n.fixed-top {\n  position: fixed;\n  top: 0;\n  left: 0;\n  right: 0;\n  z-index: 1030;\n}\n\n.fixed-bottom {\n  position: fixed;\n  left: 0;\n  bottom: 0;\n  right: 0;\n  z-index: 1030;\n}\n\n.sticky-top {\n  position: -webkit-sticky;\n  position: sticky;\n  top: 0;\n  z-index: 1020;\n}\n\n@media (min-width: 576px) {\n  .sticky-sm-top {\n    position: -webkit-sticky;\n    position: sticky;\n    top: 0;\n    z-index: 1020;\n  }\n}\n@media (min-width: 768px) {\n  .sticky-md-top {\n    position: -webkit-sticky;\n    position: sticky;\n    top: 0;\n    z-index: 1020;\n  }\n}\n@media (min-width: 992px) {\n  .sticky-lg-top {\n    position: -webkit-sticky;\n    position: sticky;\n    top: 0;\n    z-index: 1020;\n  }\n}\n@media (min-width: 1200px) {\n  .sticky-xl-top {\n    position: -webkit-sticky;\n    position: sticky;\n    top: 0;\n    z-index: 1020;\n  }\n}\n@media (min-width: 1400px) {\n  .sticky-xxl-top {\n    position: -webkit-sticky;\n    position: sticky;\n    top: 0;\n    z-index: 1020;\n  }\n}\n.hstack {\n  display: flex;\n  flex-direction: row;\n  align-items: center;\n  align-self: stretch;\n}\n\n.vstack {\n  display: flex;\n  flex: 1 1 auto;\n  flex-direction: column;\n  align-self: stretch;\n}\n\n.visually-hidden,\n.visually-hidden-focusable:not(:focus):not(:focus-within) {\n  position: absolute !important;\n  width: 1px !important;\n  height: 1px !important;\n  padding: 0 !important;\n  margin: -1px !important;\n  overflow: hidden !important;\n  clip: rect(0, 0, 0, 0) !important;\n  white-space: nowrap !important;\n  border: 0 !important;\n}\n\n.stretched-link::after {\n  position: absolute;\n  top: 0;\n  left: 0;\n  bottom: 0;\n  right: 0;\n  z-index: 1;\n  content: \"\";\n}\n\n.text-truncate {\n  overflow: hidden;\n  text-overflow: ellipsis;\n  white-space: nowrap;\n}\n\n.vr {\n  display: inline-block;\n  align-self: stretch;\n  width: 1px;\n  min-height: 1em;\n  background-color: currentColor;\n  opacity: 0.25;\n}\n\n.align-baseline {\n  vertical-align: baseline !important;\n}\n\n.align-top {\n  vertical-align: top !important;\n}\n\n.align-middle {\n  vertical-align: middle !important;\n}\n\n.align-bottom {\n  vertical-align: bottom !important;\n}\n\n.align-text-bottom {\n  vertical-align: text-bottom !important;\n}\n\n.align-text-top {\n  vertical-align: text-top !important;\n}\n\n.float-start {\n  float: right !important;\n}\n\n.float-end {\n  float: left !important;\n}\n\n.float-none {\n  float: none !important;\n}\n\n.opacity-0 {\n  opacity: 0 !important;\n}\n\n.opacity-25 {\n  opacity: 0.25 !important;\n}\n\n.opacity-50 {\n  opacity: 0.5 !important;\n}\n\n.opacity-75 {\n  opacity: 0.75 !important;\n}\n\n.opacity-100 {\n  opacity: 1 !important;\n}\n\n.overflow-auto {\n  overflow: auto !important;\n}\n\n.overflow-hidden {\n  overflow: hidden !important;\n}\n\n.overflow-visible {\n  overflow: visible !important;\n}\n\n.overflow-scroll {\n  overflow: scroll !important;\n}\n\n.d-inline {\n  display: inline !important;\n}\n\n.d-inline-block {\n  display: inline-block !important;\n}\n\n.d-block {\n  display: block !important;\n}\n\n.d-grid {\n  display: grid !important;\n}\n\n.d-table {\n  display: table !important;\n}\n\n.d-table-row {\n  display: table-row !important;\n}\n\n.d-table-cell {\n  display: table-cell !important;\n}\n\n.d-flex {\n  display: flex !important;\n}\n\n.d-inline-flex {\n  display: inline-flex !important;\n}\n\n.d-none {\n  display: none !important;\n}\n\n.shadow {\n  box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.15) !important;\n}\n\n.shadow-sm {\n  box-shadow: 0 0.125rem 0.25rem rgba(0, 0, 0, 0.075) !important;\n}\n\n.shadow-lg {\n  box-shadow: 0 1rem 3rem rgba(0, 0, 0, 0.175) !important;\n}\n\n.shadow-none {\n  box-shadow: none !important;\n}\n\n.position-static {\n  position: static !important;\n}\n\n.position-relative {\n  position: relative !important;\n}\n\n.position-absolute {\n  position: absolute !important;\n}\n\n.position-fixed {\n  position: fixed !important;\n}\n\n.position-sticky {\n  position: -webkit-sticky !important;\n  position: sticky !important;\n}\n\n.top-0 {\n  top: 0 !important;\n}\n\n.top-50 {\n  top: 50% !important;\n}\n\n.top-100 {\n  top: 100% !important;\n}\n\n.bottom-0 {\n  bottom: 0 !important;\n}\n\n.bottom-50 {\n  bottom: 50% !important;\n}\n\n.bottom-100 {\n  bottom: 100% !important;\n}\n\n.start-0 {\n  right: 0 !important;\n}\n\n.start-50 {\n  right: 50% !important;\n}\n\n.start-100 {\n  right: 100% !important;\n}\n\n.end-0 {\n  left: 0 !important;\n}\n\n.end-50 {\n  left: 50% !important;\n}\n\n.end-100 {\n  left: 100% !important;\n}\n\n.translate-middle {\n  transform: translate(50%, -50%) !important;\n}\n\n.translate-middle-x {\n  transform: translateX(50%) !important;\n}\n\n.translate-middle-y {\n  transform: translateY(-50%) !important;\n}\n\n.border {\n  border: 1px solid #dee2e6 !important;\n}\n\n.border-0 {\n  border: 0 !important;\n}\n\n.border-top {\n  border-top: 1px solid #dee2e6 !important;\n}\n\n.border-top-0 {\n  border-top: 0 !important;\n}\n\n.border-end {\n  border-left: 1px solid #dee2e6 !important;\n}\n\n.border-end-0 {\n  border-left: 0 !important;\n}\n\n.border-bottom {\n  border-bottom: 1px solid #dee2e6 !important;\n}\n\n.border-bottom-0 {\n  border-bottom: 0 !important;\n}\n\n.border-start {\n  border-right: 1px solid #dee2e6 !important;\n}\n\n.border-start-0 {\n  border-right: 0 !important;\n}\n\n.border-primary {\n  border-color: #0d6efd !important;\n}\n\n.border-secondary {\n  border-color: #6c757d !important;\n}\n\n.border-success {\n  border-color: #198754 !important;\n}\n\n.border-info {\n  border-color: #0dcaf0 !important;\n}\n\n.border-warning {\n  border-color: #ffc107 !important;\n}\n\n.border-danger {\n  border-color: #dc3545 !important;\n}\n\n.border-light {\n  border-color: #f8f9fa !important;\n}\n\n.border-dark {\n  border-color: #212529 !important;\n}\n\n.border-white {\n  border-color: #fff !important;\n}\n\n.border-1 {\n  border-width: 1px !important;\n}\n\n.border-2 {\n  border-width: 2px !important;\n}\n\n.border-3 {\n  border-width: 3px !important;\n}\n\n.border-4 {\n  border-width: 4px !important;\n}\n\n.border-5 {\n  border-width: 5px !important;\n}\n\n.w-25 {\n  width: 25% !important;\n}\n\n.w-50 {\n  width: 50% !important;\n}\n\n.w-75 {\n  width: 75% !important;\n}\n\n.w-100 {\n  width: 100% !important;\n}\n\n.w-auto {\n  width: auto !important;\n}\n\n.mw-100 {\n  max-width: 100% !important;\n}\n\n.vw-100 {\n  width: 100vw !important;\n}\n\n.min-vw-100 {\n  min-width: 100vw !important;\n}\n\n.h-25 {\n  height: 25% !important;\n}\n\n.h-50 {\n  height: 50% !important;\n}\n\n.h-75 {\n  height: 75% !important;\n}\n\n.h-100 {\n  height: 100% !important;\n}\n\n.h-auto {\n  height: auto !important;\n}\n\n.mh-100 {\n  max-height: 100% !important;\n}\n\n.vh-100 {\n  height: 100vh !important;\n}\n\n.min-vh-100 {\n  min-height: 100vh !important;\n}\n\n.flex-fill {\n  flex: 1 1 auto !important;\n}\n\n.flex-row {\n  flex-direction: row !important;\n}\n\n.flex-column {\n  flex-direction: column !important;\n}\n\n.flex-row-reverse {\n  flex-direction: row-reverse !important;\n}\n\n.flex-column-reverse {\n  flex-direction: column-reverse !important;\n}\n\n.flex-grow-0 {\n  flex-grow: 0 !important;\n}\n\n.flex-grow-1 {\n  flex-grow: 1 !important;\n}\n\n.flex-shrink-0 {\n  flex-shrink: 0 !important;\n}\n\n.flex-shrink-1 {\n  flex-shrink: 1 !important;\n}\n\n.flex-wrap {\n  flex-wrap: wrap !important;\n}\n\n.flex-nowrap {\n  flex-wrap: nowrap !important;\n}\n\n.flex-wrap-reverse {\n  flex-wrap: wrap-reverse !important;\n}\n\n.gap-0 {\n  gap: 0 !important;\n}\n\n.gap-1 {\n  gap: 0.25rem !important;\n}\n\n.gap-2 {\n  gap: 0.5rem !important;\n}\n\n.gap-3 {\n  gap: 1rem !important;\n}\n\n.gap-4 {\n  gap: 1.5rem !important;\n}\n\n.gap-5 {\n  gap: 3rem !important;\n}\n\n.justify-content-start {\n  justify-content: flex-start !important;\n}\n\n.justify-content-end {\n  justify-content: flex-end !important;\n}\n\n.justify-content-center {\n  justify-content: center !important;\n}\n\n.justify-content-between {\n  justify-content: space-between !important;\n}\n\n.justify-content-around {\n  justify-content: space-around !important;\n}\n\n.justify-content-evenly {\n  justify-content: space-evenly !important;\n}\n\n.align-items-start {\n  align-items: flex-start !important;\n}\n\n.align-items-end {\n  align-items: flex-end !important;\n}\n\n.align-items-center {\n  align-items: center !important;\n}\n\n.align-items-baseline {\n  align-items: baseline !important;\n}\n\n.align-items-stretch {\n  align-items: stretch !important;\n}\n\n.align-content-start {\n  align-content: flex-start !important;\n}\n\n.align-content-end {\n  align-content: flex-end !important;\n}\n\n.align-content-center {\n  align-content: center !important;\n}\n\n.align-content-between {\n  align-content: space-between !important;\n}\n\n.align-content-around {\n  align-content: space-around !important;\n}\n\n.align-content-stretch {\n  align-content: stretch !important;\n}\n\n.align-self-auto {\n  align-self: auto !important;\n}\n\n.align-self-start {\n  align-self: flex-start !important;\n}\n\n.align-self-end {\n  align-self: flex-end !important;\n}\n\n.align-self-center {\n  align-self: center !important;\n}\n\n.align-self-baseline {\n  align-self: baseline !important;\n}\n\n.align-self-stretch {\n  align-self: stretch !important;\n}\n\n.order-first {\n  order: -1 !important;\n}\n\n.order-0 {\n  order: 0 !important;\n}\n\n.order-1 {\n  order: 1 !important;\n}\n\n.order-2 {\n  order: 2 !important;\n}\n\n.order-3 {\n  order: 3 !important;\n}\n\n.order-4 {\n  order: 4 !important;\n}\n\n.order-5 {\n  order: 5 !important;\n}\n\n.order-last {\n  order: 6 !important;\n}\n\n.m-0 {\n  margin: 0 !important;\n}\n\n.m-1 {\n  margin: 0.25rem !important;\n}\n\n.m-2 {\n  margin: 0.5rem !important;\n}\n\n.m-3 {\n  margin: 1rem !important;\n}\n\n.m-4 {\n  margin: 1.5rem !important;\n}\n\n.m-5 {\n  margin: 3rem !important;\n}\n\n.m-auto {\n  margin: auto !important;\n}\n\n.mx-0 {\n  margin-left: 0 !important;\n  margin-right: 0 !important;\n}\n\n.mx-1 {\n  margin-left: 0.25rem !important;\n  margin-right: 0.25rem !important;\n}\n\n.mx-2 {\n  margin-left: 0.5rem !important;\n  margin-right: 0.5rem !important;\n}\n\n.mx-3 {\n  margin-left: 1rem !important;\n  margin-right: 1rem !important;\n}\n\n.mx-4 {\n  margin-left: 1.5rem !important;\n  margin-right: 1.5rem !important;\n}\n\n.mx-5 {\n  margin-left: 3rem !important;\n  margin-right: 3rem !important;\n}\n\n.mx-auto {\n  margin-left: auto !important;\n  margin-right: auto !important;\n}\n\n.my-0 {\n  margin-top: 0 !important;\n  margin-bottom: 0 !important;\n}\n\n.my-1 {\n  margin-top: 0.25rem !important;\n  margin-bottom: 0.25rem !important;\n}\n\n.my-2 {\n  margin-top: 0.5rem !important;\n  margin-bottom: 0.5rem !important;\n}\n\n.my-3 {\n  margin-top: 1rem !important;\n  margin-bottom: 1rem !important;\n}\n\n.my-4 {\n  margin-top: 1.5rem !important;\n  margin-bottom: 1.5rem !important;\n}\n\n.my-5 {\n  margin-top: 3rem !important;\n  margin-bottom: 3rem !important;\n}\n\n.my-auto {\n  margin-top: auto !important;\n  margin-bottom: auto !important;\n}\n\n.mt-0 {\n  margin-top: 0 !important;\n}\n\n.mt-1 {\n  margin-top: 0.25rem !important;\n}\n\n.mt-2 {\n  margin-top: 0.5rem !important;\n}\n\n.mt-3 {\n  margin-top: 1rem !important;\n}\n\n.mt-4 {\n  margin-top: 1.5rem !important;\n}\n\n.mt-5 {\n  margin-top: 3rem !important;\n}\n\n.mt-auto {\n  margin-top: auto !important;\n}\n\n.me-0 {\n  margin-left: 0 !important;\n}\n\n.me-1 {\n  margin-left: 0.25rem !important;\n}\n\n.me-2 {\n  margin-left: 0.5rem !important;\n}\n\n.me-3 {\n  margin-left: 1rem !important;\n}\n\n.me-4 {\n  margin-left: 1.5rem !important;\n}\n\n.me-5 {\n  margin-left: 3rem !important;\n}\n\n.me-auto {\n  margin-left: auto !important;\n}\n\n.mb-0 {\n  margin-bottom: 0 !important;\n}\n\n.mb-1 {\n  margin-bottom: 0.25rem !important;\n}\n\n.mb-2 {\n  margin-bottom: 0.5rem !important;\n}\n\n.mb-3 {\n  margin-bottom: 1rem !important;\n}\n\n.mb-4 {\n  margin-bottom: 1.5rem !important;\n}\n\n.mb-5 {\n  margin-bottom: 3rem !important;\n}\n\n.mb-auto {\n  margin-bottom: auto !important;\n}\n\n.ms-0 {\n  margin-right: 0 !important;\n}\n\n.ms-1 {\n  margin-right: 0.25rem !important;\n}\n\n.ms-2 {\n  margin-right: 0.5rem !important;\n}\n\n.ms-3 {\n  margin-right: 1rem !important;\n}\n\n.ms-4 {\n  margin-right: 1.5rem !important;\n}\n\n.ms-5 {\n  margin-right: 3rem !important;\n}\n\n.ms-auto {\n  margin-right: auto !important;\n}\n\n.p-0 {\n  padding: 0 !important;\n}\n\n.p-1 {\n  padding: 0.25rem !important;\n}\n\n.p-2 {\n  padding: 0.5rem !important;\n}\n\n.p-3 {\n  padding: 1rem !important;\n}\n\n.p-4 {\n  padding: 1.5rem !important;\n}\n\n.p-5 {\n  padding: 3rem !important;\n}\n\n.px-0 {\n  padding-left: 0 !important;\n  padding-right: 0 !important;\n}\n\n.px-1 {\n  padding-left: 0.25rem !important;\n  padding-right: 0.25rem !important;\n}\n\n.px-2 {\n  padding-left: 0.5rem !important;\n  padding-right: 0.5rem !important;\n}\n\n.px-3 {\n  padding-left: 1rem !important;\n  padding-right: 1rem !important;\n}\n\n.px-4 {\n  padding-left: 1.5rem !important;\n  padding-right: 1.5rem !important;\n}\n\n.px-5 {\n  padding-left: 3rem !important;\n  padding-right: 3rem !important;\n}\n\n.py-0 {\n  padding-top: 0 !important;\n  padding-bottom: 0 !important;\n}\n\n.py-1 {\n  padding-top: 0.25rem !important;\n  padding-bottom: 0.25rem !important;\n}\n\n.py-2 {\n  padding-top: 0.5rem !important;\n  padding-bottom: 0.5rem !important;\n}\n\n.py-3 {\n  padding-top: 1rem !important;\n  padding-bottom: 1rem !important;\n}\n\n.py-4 {\n  padding-top: 1.5rem !important;\n  padding-bottom: 1.5rem !important;\n}\n\n.py-5 {\n  padding-top: 3rem !important;\n  padding-bottom: 3rem !important;\n}\n\n.pt-0 {\n  padding-top: 0 !important;\n}\n\n.pt-1 {\n  padding-top: 0.25rem !important;\n}\n\n.pt-2 {\n  padding-top: 0.5rem !important;\n}\n\n.pt-3 {\n  padding-top: 1rem !important;\n}\n\n.pt-4 {\n  padding-top: 1.5rem !important;\n}\n\n.pt-5 {\n  padding-top: 3rem !important;\n}\n\n.pe-0 {\n  padding-left: 0 !important;\n}\n\n.pe-1 {\n  padding-left: 0.25rem !important;\n}\n\n.pe-2 {\n  padding-left: 0.5rem !important;\n}\n\n.pe-3 {\n  padding-left: 1rem !important;\n}\n\n.pe-4 {\n  padding-left: 1.5rem !important;\n}\n\n.pe-5 {\n  padding-left: 3rem !important;\n}\n\n.pb-0 {\n  padding-bottom: 0 !important;\n}\n\n.pb-1 {\n  padding-bottom: 0.25rem !important;\n}\n\n.pb-2 {\n  padding-bottom: 0.5rem !important;\n}\n\n.pb-3 {\n  padding-bottom: 1rem !important;\n}\n\n.pb-4 {\n  padding-bottom: 1.5rem !important;\n}\n\n.pb-5 {\n  padding-bottom: 3rem !important;\n}\n\n.ps-0 {\n  padding-right: 0 !important;\n}\n\n.ps-1 {\n  padding-right: 0.25rem !important;\n}\n\n.ps-2 {\n  padding-right: 0.5rem !important;\n}\n\n.ps-3 {\n  padding-right: 1rem !important;\n}\n\n.ps-4 {\n  padding-right: 1.5rem !important;\n}\n\n.ps-5 {\n  padding-right: 3rem !important;\n}\n\n.font-monospace {\n  font-family: var(--bs-font-monospace) !important;\n}\n\n.fs-1 {\n  font-size: calc(1.375rem + 1.5vw) !important;\n}\n\n.fs-2 {\n  font-size: calc(1.325rem + 0.9vw) !important;\n}\n\n.fs-3 {\n  font-size: calc(1.3rem + 0.6vw) !important;\n}\n\n.fs-4 {\n  font-size: calc(1.275rem + 0.3vw) !important;\n}\n\n.fs-5 {\n  font-size: 1.25rem !important;\n}\n\n.fs-6 {\n  font-size: 1rem !important;\n}\n\n.fst-italic {\n  font-style: italic !important;\n}\n\n.fst-normal {\n  font-style: normal !important;\n}\n\n.fw-light {\n  font-weight: 300 !important;\n}\n\n.fw-lighter {\n  font-weight: lighter !important;\n}\n\n.fw-normal {\n  font-weight: 400 !important;\n}\n\n.fw-bold {\n  font-weight: 700 !important;\n}\n\n.fw-bolder {\n  font-weight: bolder !important;\n}\n\n.lh-1 {\n  line-height: 1 !important;\n}\n\n.lh-sm {\n  line-height: 1.25 !important;\n}\n\n.lh-base {\n  line-height: 1.5 !important;\n}\n\n.lh-lg {\n  line-height: 2 !important;\n}\n\n.text-start {\n  text-align: right !important;\n}\n\n.text-end {\n  text-align: left !important;\n}\n\n.text-center {\n  text-align: center !important;\n}\n\n.text-decoration-none {\n  text-decoration: none !important;\n}\n\n.text-decoration-underline {\n  text-decoration: underline !important;\n}\n\n.text-decoration-line-through {\n  text-decoration: line-through !important;\n}\n\n.text-lowercase {\n  text-transform: lowercase !important;\n}\n\n.text-uppercase {\n  text-transform: uppercase !important;\n}\n\n.text-capitalize {\n  text-transform: capitalize !important;\n}\n\n.text-wrap {\n  white-space: normal !important;\n}\n\n.text-nowrap {\n  white-space: nowrap !important;\n}\n.text-primary {\n  --bs-text-opacity: 1;\n  color: rgba(var(--bs-primary-rgb), var(--bs-text-opacity)) !important;\n}\n\n.text-secondary {\n  --bs-text-opacity: 1;\n  color: rgba(var(--bs-secondary-rgb), var(--bs-text-opacity)) !important;\n}\n\n.text-success {\n  --bs-text-opacity: 1;\n  color: rgba(var(--bs-success-rgb), var(--bs-text-opacity)) !important;\n}\n\n.text-info {\n  --bs-text-opacity: 1;\n  color: rgba(var(--bs-info-rgb), var(--bs-text-opacity)) !important;\n}\n\n.text-warning {\n  --bs-text-opacity: 1;\n  color: rgba(var(--bs-warning-rgb), var(--bs-text-opacity)) !important;\n}\n\n.text-danger {\n  --bs-text-opacity: 1;\n  color: rgba(var(--bs-danger-rgb), var(--bs-text-opacity)) !important;\n}\n\n.text-light {\n  --bs-text-opacity: 1;\n  color: rgba(var(--bs-light-rgb), var(--bs-text-opacity)) !important;\n}\n\n.text-dark {\n  --bs-text-opacity: 1;\n  color: rgba(var(--bs-dark-rgb), var(--bs-text-opacity)) !important;\n}\n\n.text-black {\n  --bs-text-opacity: 1;\n  color: rgba(var(--bs-black-rgb), var(--bs-text-opacity)) !important;\n}\n\n.text-white {\n  --bs-text-opacity: 1;\n  color: rgba(var(--bs-white-rgb), var(--bs-text-opacity)) !important;\n}\n\n.text-body {\n  --bs-text-opacity: 1;\n  color: rgba(var(--bs-body-rgb), var(--bs-text-opacity)) !important;\n}\n\n.text-muted {\n  --bs-text-opacity: 1;\n  color: #6c757d !important;\n}\n\n.text-black-50 {\n  --bs-text-opacity: 1;\n  color: rgba(0, 0, 0, 0.5) !important;\n}\n\n.text-white-50 {\n  --bs-text-opacity: 1;\n  color: rgba(255, 255, 255, 0.5) !important;\n}\n\n.text-reset {\n  --bs-text-opacity: 1;\n  color: inherit !important;\n}\n\n.text-opacity-25 {\n  --bs-text-opacity: 0.25;\n}\n\n.text-opacity-50 {\n  --bs-text-opacity: 0.5;\n}\n\n.text-opacity-75 {\n  --bs-text-opacity: 0.75;\n}\n\n.text-opacity-100 {\n  --bs-text-opacity: 1;\n}\n\n.bg-primary {\n  --bs-bg-opacity: 1;\n  background-color: rgba(var(--bs-primary-rgb), var(--bs-bg-opacity)) !important;\n}\n\n.bg-secondary {\n  --bs-bg-opacity: 1;\n  background-color: rgba(var(--bs-secondary-rgb), var(--bs-bg-opacity)) !important;\n}\n\n.bg-success {\n  --bs-bg-opacity: 1;\n  background-color: rgba(var(--bs-success-rgb), var(--bs-bg-opacity)) !important;\n}\n\n.bg-info {\n  --bs-bg-opacity: 1;\n  background-color: rgba(var(--bs-info-rgb), var(--bs-bg-opacity)) !important;\n}\n\n.bg-warning {\n  --bs-bg-opacity: 1;\n  background-color: rgba(var(--bs-warning-rgb), var(--bs-bg-opacity)) !important;\n}\n\n.bg-danger {\n  --bs-bg-opacity: 1;\n  background-color: rgba(var(--bs-danger-rgb), var(--bs-bg-opacity)) !important;\n}\n\n.bg-light {\n  --bs-bg-opacity: 1;\n  background-color: rgba(var(--bs-light-rgb), var(--bs-bg-opacity)) !important;\n}\n\n.bg-dark {\n  --bs-bg-opacity: 1;\n  background-color: rgba(var(--bs-dark-rgb), var(--bs-bg-opacity)) !important;\n}\n\n.bg-black {\n  --bs-bg-opacity: 1;\n  background-color: rgba(var(--bs-black-rgb), var(--bs-bg-opacity)) !important;\n}\n\n.bg-white {\n  --bs-bg-opacity: 1;\n  background-color: rgba(var(--bs-white-rgb), var(--bs-bg-opacity)) !important;\n}\n\n.bg-body {\n  --bs-bg-opacity: 1;\n  background-color: rgba(var(--bs-body-rgb), var(--bs-bg-opacity)) !important;\n}\n\n.bg-transparent {\n  --bs-bg-opacity: 1;\n  background-color: transparent !important;\n}\n\n.bg-opacity-10 {\n  --bs-bg-opacity: 0.1;\n}\n\n.bg-opacity-25 {\n  --bs-bg-opacity: 0.25;\n}\n\n.bg-opacity-50 {\n  --bs-bg-opacity: 0.5;\n}\n\n.bg-opacity-75 {\n  --bs-bg-opacity: 0.75;\n}\n\n.bg-opacity-100 {\n  --bs-bg-opacity: 1;\n}\n\n.bg-gradient {\n  background-image: var(--bs-gradient) !important;\n}\n\n.user-select-all {\n  -webkit-user-select: all !important;\n  -moz-user-select: all !important;\n  user-select: all !important;\n}\n\n.user-select-auto {\n  -webkit-user-select: auto !important;\n  -moz-user-select: auto !important;\n  user-select: auto !important;\n}\n\n.user-select-none {\n  -webkit-user-select: none !important;\n  -moz-user-select: none !important;\n  user-select: none !important;\n}\n\n.pe-none {\n  pointer-events: none !important;\n}\n\n.pe-auto {\n  pointer-events: auto !important;\n}\n\n.rounded {\n  border-radius: 0.25rem !important;\n}\n\n.rounded-0 {\n  border-radius: 0 !important;\n}\n\n.rounded-1 {\n  border-radius: 0.2rem !important;\n}\n\n.rounded-2 {\n  border-radius: 0.25rem !important;\n}\n\n.rounded-3 {\n  border-radius: 0.3rem !important;\n}\n\n.rounded-circle {\n  border-radius: 50% !important;\n}\n\n.rounded-pill {\n  border-radius: 50rem !important;\n}\n\n.rounded-top {\n  border-top-right-radius: 0.25rem !important;\n  border-top-left-radius: 0.25rem !important;\n}\n\n.rounded-end {\n  border-top-left-radius: 0.25rem !important;\n  border-bottom-left-radius: 0.25rem !important;\n}\n\n.rounded-bottom {\n  border-bottom-left-radius: 0.25rem !important;\n  border-bottom-right-radius: 0.25rem !important;\n}\n\n.rounded-start {\n  border-bottom-right-radius: 0.25rem !important;\n  border-top-right-radius: 0.25rem !important;\n}\n\n.visible {\n  visibility: visible !important;\n}\n\n.invisible {\n  visibility: hidden !important;\n}\n\n@media (min-width: 576px) {\n  .float-sm-start {\n    float: right !important;\n  }\n\n  .float-sm-end {\n    float: left !important;\n  }\n\n  .float-sm-none {\n    float: none !important;\n  }\n\n  .d-sm-inline {\n    display: inline !important;\n  }\n\n  .d-sm-inline-block {\n    display: inline-block !important;\n  }\n\n  .d-sm-block {\n    display: block !important;\n  }\n\n  .d-sm-grid {\n    display: grid !important;\n  }\n\n  .d-sm-table {\n    display: table !important;\n  }\n\n  .d-sm-table-row {\n    display: table-row !important;\n  }\n\n  .d-sm-table-cell {\n    display: table-cell !important;\n  }\n\n  .d-sm-flex {\n    display: flex !important;\n  }\n\n  .d-sm-inline-flex {\n    display: inline-flex !important;\n  }\n\n  .d-sm-none {\n    display: none !important;\n  }\n\n  .flex-sm-fill {\n    flex: 1 1 auto !important;\n  }\n\n  .flex-sm-row {\n    flex-direction: row !important;\n  }\n\n  .flex-sm-column {\n    flex-direction: column !important;\n  }\n\n  .flex-sm-row-reverse {\n    flex-direction: row-reverse !important;\n  }\n\n  .flex-sm-column-reverse {\n    flex-direction: column-reverse !important;\n  }\n\n  .flex-sm-grow-0 {\n    flex-grow: 0 !important;\n  }\n\n  .flex-sm-grow-1 {\n    flex-grow: 1 !important;\n  }\n\n  .flex-sm-shrink-0 {\n    flex-shrink: 0 !important;\n  }\n\n  .flex-sm-shrink-1 {\n    flex-shrink: 1 !important;\n  }\n\n  .flex-sm-wrap {\n    flex-wrap: wrap !important;\n  }\n\n  .flex-sm-nowrap {\n    flex-wrap: nowrap !important;\n  }\n\n  .flex-sm-wrap-reverse {\n    flex-wrap: wrap-reverse !important;\n  }\n\n  .gap-sm-0 {\n    gap: 0 !important;\n  }\n\n  .gap-sm-1 {\n    gap: 0.25rem !important;\n  }\n\n  .gap-sm-2 {\n    gap: 0.5rem !important;\n  }\n\n  .gap-sm-3 {\n    gap: 1rem !important;\n  }\n\n  .gap-sm-4 {\n    gap: 1.5rem !important;\n  }\n\n  .gap-sm-5 {\n    gap: 3rem !important;\n  }\n\n  .justify-content-sm-start {\n    justify-content: flex-start !important;\n  }\n\n  .justify-content-sm-end {\n    justify-content: flex-end !important;\n  }\n\n  .justify-content-sm-center {\n    justify-content: center !important;\n  }\n\n  .justify-content-sm-between {\n    justify-content: space-between !important;\n  }\n\n  .justify-content-sm-around {\n    justify-content: space-around !important;\n  }\n\n  .justify-content-sm-evenly {\n    justify-content: space-evenly !important;\n  }\n\n  .align-items-sm-start {\n    align-items: flex-start !important;\n  }\n\n  .align-items-sm-end {\n    align-items: flex-end !important;\n  }\n\n  .align-items-sm-center {\n    align-items: center !important;\n  }\n\n  .align-items-sm-baseline {\n    align-items: baseline !important;\n  }\n\n  .align-items-sm-stretch {\n    align-items: stretch !important;\n  }\n\n  .align-content-sm-start {\n    align-content: flex-start !important;\n  }\n\n  .align-content-sm-end {\n    align-content: flex-end !important;\n  }\n\n  .align-content-sm-center {\n    align-content: center !important;\n  }\n\n  .align-content-sm-between {\n    align-content: space-between !important;\n  }\n\n  .align-content-sm-around {\n    align-content: space-around !important;\n  }\n\n  .align-content-sm-stretch {\n    align-content: stretch !important;\n  }\n\n  .align-self-sm-auto {\n    align-self: auto !important;\n  }\n\n  .align-self-sm-start {\n    align-self: flex-start !important;\n  }\n\n  .align-self-sm-end {\n    align-self: flex-end !important;\n  }\n\n  .align-self-sm-center {\n    align-self: center !important;\n  }\n\n  .align-self-sm-baseline {\n    align-self: baseline !important;\n  }\n\n  .align-self-sm-stretch {\n    align-self: stretch !important;\n  }\n\n  .order-sm-first {\n    order: -1 !important;\n  }\n\n  .order-sm-0 {\n    order: 0 !important;\n  }\n\n  .order-sm-1 {\n    order: 1 !important;\n  }\n\n  .order-sm-2 {\n    order: 2 !important;\n  }\n\n  .order-sm-3 {\n    order: 3 !important;\n  }\n\n  .order-sm-4 {\n    order: 4 !important;\n  }\n\n  .order-sm-5 {\n    order: 5 !important;\n  }\n\n  .order-sm-last {\n    order: 6 !important;\n  }\n\n  .m-sm-0 {\n    margin: 0 !important;\n  }\n\n  .m-sm-1 {\n    margin: 0.25rem !important;\n  }\n\n  .m-sm-2 {\n    margin: 0.5rem !important;\n  }\n\n  .m-sm-3 {\n    margin: 1rem !important;\n  }\n\n  .m-sm-4 {\n    margin: 1.5rem !important;\n  }\n\n  .m-sm-5 {\n    margin: 3rem !important;\n  }\n\n  .m-sm-auto {\n    margin: auto !important;\n  }\n\n  .mx-sm-0 {\n    margin-left: 0 !important;\n    margin-right: 0 !important;\n  }\n\n  .mx-sm-1 {\n    margin-left: 0.25rem !important;\n    margin-right: 0.25rem !important;\n  }\n\n  .mx-sm-2 {\n    margin-left: 0.5rem !important;\n    margin-right: 0.5rem !important;\n  }\n\n  .mx-sm-3 {\n    margin-left: 1rem !important;\n    margin-right: 1rem !important;\n  }\n\n  .mx-sm-4 {\n    margin-left: 1.5rem !important;\n    margin-right: 1.5rem !important;\n  }\n\n  .mx-sm-5 {\n    margin-left: 3rem !important;\n    margin-right: 3rem !important;\n  }\n\n  .mx-sm-auto {\n    margin-left: auto !important;\n    margin-right: auto !important;\n  }\n\n  .my-sm-0 {\n    margin-top: 0 !important;\n    margin-bottom: 0 !important;\n  }\n\n  .my-sm-1 {\n    margin-top: 0.25rem !important;\n    margin-bottom: 0.25rem !important;\n  }\n\n  .my-sm-2 {\n    margin-top: 0.5rem !important;\n    margin-bottom: 0.5rem !important;\n  }\n\n  .my-sm-3 {\n    margin-top: 1rem !important;\n    margin-bottom: 1rem !important;\n  }\n\n  .my-sm-4 {\n    margin-top: 1.5rem !important;\n    margin-bottom: 1.5rem !important;\n  }\n\n  .my-sm-5 {\n    margin-top: 3rem !important;\n    margin-bottom: 3rem !important;\n  }\n\n  .my-sm-auto {\n    margin-top: auto !important;\n    margin-bottom: auto !important;\n  }\n\n  .mt-sm-0 {\n    margin-top: 0 !important;\n  }\n\n  .mt-sm-1 {\n    margin-top: 0.25rem !important;\n  }\n\n  .mt-sm-2 {\n    margin-top: 0.5rem !important;\n  }\n\n  .mt-sm-3 {\n    margin-top: 1rem !important;\n  }\n\n  .mt-sm-4 {\n    margin-top: 1.5rem !important;\n  }\n\n  .mt-sm-5 {\n    margin-top: 3rem !important;\n  }\n\n  .mt-sm-auto {\n    margin-top: auto !important;\n  }\n\n  .me-sm-0 {\n    margin-left: 0 !important;\n  }\n\n  .me-sm-1 {\n    margin-left: 0.25rem !important;\n  }\n\n  .me-sm-2 {\n    margin-left: 0.5rem !important;\n  }\n\n  .me-sm-3 {\n    margin-left: 1rem !important;\n  }\n\n  .me-sm-4 {\n    margin-left: 1.5rem !important;\n  }\n\n  .me-sm-5 {\n    margin-left: 3rem !important;\n  }\n\n  .me-sm-auto {\n    margin-left: auto !important;\n  }\n\n  .mb-sm-0 {\n    margin-bottom: 0 !important;\n  }\n\n  .mb-sm-1 {\n    margin-bottom: 0.25rem !important;\n  }\n\n  .mb-sm-2 {\n    margin-bottom: 0.5rem !important;\n  }\n\n  .mb-sm-3 {\n    margin-bottom: 1rem !important;\n  }\n\n  .mb-sm-4 {\n    margin-bottom: 1.5rem !important;\n  }\n\n  .mb-sm-5 {\n    margin-bottom: 3rem !important;\n  }\n\n  .mb-sm-auto {\n    margin-bottom: auto !important;\n  }\n\n  .ms-sm-0 {\n    margin-right: 0 !important;\n  }\n\n  .ms-sm-1 {\n    margin-right: 0.25rem !important;\n  }\n\n  .ms-sm-2 {\n    margin-right: 0.5rem !important;\n  }\n\n  .ms-sm-3 {\n    margin-right: 1rem !important;\n  }\n\n  .ms-sm-4 {\n    margin-right: 1.5rem !important;\n  }\n\n  .ms-sm-5 {\n    margin-right: 3rem !important;\n  }\n\n  .ms-sm-auto {\n    margin-right: auto !important;\n  }\n\n  .p-sm-0 {\n    padding: 0 !important;\n  }\n\n  .p-sm-1 {\n    padding: 0.25rem !important;\n  }\n\n  .p-sm-2 {\n    padding: 0.5rem !important;\n  }\n\n  .p-sm-3 {\n    padding: 1rem !important;\n  }\n\n  .p-sm-4 {\n    padding: 1.5rem !important;\n  }\n\n  .p-sm-5 {\n    padding: 3rem !important;\n  }\n\n  .px-sm-0 {\n    padding-left: 0 !important;\n    padding-right: 0 !important;\n  }\n\n  .px-sm-1 {\n    padding-left: 0.25rem !important;\n    padding-right: 0.25rem !important;\n  }\n\n  .px-sm-2 {\n    padding-left: 0.5rem !important;\n    padding-right: 0.5rem !important;\n  }\n\n  .px-sm-3 {\n    padding-left: 1rem !important;\n    padding-right: 1rem !important;\n  }\n\n  .px-sm-4 {\n    padding-left: 1.5rem !important;\n    padding-right: 1.5rem !important;\n  }\n\n  .px-sm-5 {\n    padding-left: 3rem !important;\n    padding-right: 3rem !important;\n  }\n\n  .py-sm-0 {\n    padding-top: 0 !important;\n    padding-bottom: 0 !important;\n  }\n\n  .py-sm-1 {\n    padding-top: 0.25rem !important;\n    padding-bottom: 0.25rem !important;\n  }\n\n  .py-sm-2 {\n    padding-top: 0.5rem !important;\n    padding-bottom: 0.5rem !important;\n  }\n\n  .py-sm-3 {\n    padding-top: 1rem !important;\n    padding-bottom: 1rem !important;\n  }\n\n  .py-sm-4 {\n    padding-top: 1.5rem !important;\n    padding-bottom: 1.5rem !important;\n  }\n\n  .py-sm-5 {\n    padding-top: 3rem !important;\n    padding-bottom: 3rem !important;\n  }\n\n  .pt-sm-0 {\n    padding-top: 0 !important;\n  }\n\n  .pt-sm-1 {\n    padding-top: 0.25rem !important;\n  }\n\n  .pt-sm-2 {\n    padding-top: 0.5rem !important;\n  }\n\n  .pt-sm-3 {\n    padding-top: 1rem !important;\n  }\n\n  .pt-sm-4 {\n    padding-top: 1.5rem !important;\n  }\n\n  .pt-sm-5 {\n    padding-top: 3rem !important;\n  }\n\n  .pe-sm-0 {\n    padding-left: 0 !important;\n  }\n\n  .pe-sm-1 {\n    padding-left: 0.25rem !important;\n  }\n\n  .pe-sm-2 {\n    padding-left: 0.5rem !important;\n  }\n\n  .pe-sm-3 {\n    padding-left: 1rem !important;\n  }\n\n  .pe-sm-4 {\n    padding-left: 1.5rem !important;\n  }\n\n  .pe-sm-5 {\n    padding-left: 3rem !important;\n  }\n\n  .pb-sm-0 {\n    padding-bottom: 0 !important;\n  }\n\n  .pb-sm-1 {\n    padding-bottom: 0.25rem !important;\n  }\n\n  .pb-sm-2 {\n    padding-bottom: 0.5rem !important;\n  }\n\n  .pb-sm-3 {\n    padding-bottom: 1rem !important;\n  }\n\n  .pb-sm-4 {\n    padding-bottom: 1.5rem !important;\n  }\n\n  .pb-sm-5 {\n    padding-bottom: 3rem !important;\n  }\n\n  .ps-sm-0 {\n    padding-right: 0 !important;\n  }\n\n  .ps-sm-1 {\n    padding-right: 0.25rem !important;\n  }\n\n  .ps-sm-2 {\n    padding-right: 0.5rem !important;\n  }\n\n  .ps-sm-3 {\n    padding-right: 1rem !important;\n  }\n\n  .ps-sm-4 {\n    padding-right: 1.5rem !important;\n  }\n\n  .ps-sm-5 {\n    padding-right: 3rem !important;\n  }\n\n  .text-sm-start {\n    text-align: right !important;\n  }\n\n  .text-sm-end {\n    text-align: left !important;\n  }\n\n  .text-sm-center {\n    text-align: center !important;\n  }\n}\n@media (min-width: 768px) {\n  .float-md-start {\n    float: right !important;\n  }\n\n  .float-md-end {\n    float: left !important;\n  }\n\n  .float-md-none {\n    float: none !important;\n  }\n\n  .d-md-inline {\n    display: inline !important;\n  }\n\n  .d-md-inline-block {\n    display: inline-block !important;\n  }\n\n  .d-md-block {\n    display: block !important;\n  }\n\n  .d-md-grid {\n    display: grid !important;\n  }\n\n  .d-md-table {\n    display: table !important;\n  }\n\n  .d-md-table-row {\n    display: table-row !important;\n  }\n\n  .d-md-table-cell {\n    display: table-cell !important;\n  }\n\n  .d-md-flex {\n    display: flex !important;\n  }\n\n  .d-md-inline-flex {\n    display: inline-flex !important;\n  }\n\n  .d-md-none {\n    display: none !important;\n  }\n\n  .flex-md-fill {\n    flex: 1 1 auto !important;\n  }\n\n  .flex-md-row {\n    flex-direction: row !important;\n  }\n\n  .flex-md-column {\n    flex-direction: column !important;\n  }\n\n  .flex-md-row-reverse {\n    flex-direction: row-reverse !important;\n  }\n\n  .flex-md-column-reverse {\n    flex-direction: column-reverse !important;\n  }\n\n  .flex-md-grow-0 {\n    flex-grow: 0 !important;\n  }\n\n  .flex-md-grow-1 {\n    flex-grow: 1 !important;\n  }\n\n  .flex-md-shrink-0 {\n    flex-shrink: 0 !important;\n  }\n\n  .flex-md-shrink-1 {\n    flex-shrink: 1 !important;\n  }\n\n  .flex-md-wrap {\n    flex-wrap: wrap !important;\n  }\n\n  .flex-md-nowrap {\n    flex-wrap: nowrap !important;\n  }\n\n  .flex-md-wrap-reverse {\n    flex-wrap: wrap-reverse !important;\n  }\n\n  .gap-md-0 {\n    gap: 0 !important;\n  }\n\n  .gap-md-1 {\n    gap: 0.25rem !important;\n  }\n\n  .gap-md-2 {\n    gap: 0.5rem !important;\n  }\n\n  .gap-md-3 {\n    gap: 1rem !important;\n  }\n\n  .gap-md-4 {\n    gap: 1.5rem !important;\n  }\n\n  .gap-md-5 {\n    gap: 3rem !important;\n  }\n\n  .justify-content-md-start {\n    justify-content: flex-start !important;\n  }\n\n  .justify-content-md-end {\n    justify-content: flex-end !important;\n  }\n\n  .justify-content-md-center {\n    justify-content: center !important;\n  }\n\n  .justify-content-md-between {\n    justify-content: space-between !important;\n  }\n\n  .justify-content-md-around {\n    justify-content: space-around !important;\n  }\n\n  .justify-content-md-evenly {\n    justify-content: space-evenly !important;\n  }\n\n  .align-items-md-start {\n    align-items: flex-start !important;\n  }\n\n  .align-items-md-end {\n    align-items: flex-end !important;\n  }\n\n  .align-items-md-center {\n    align-items: center !important;\n  }\n\n  .align-items-md-baseline {\n    align-items: baseline !important;\n  }\n\n  .align-items-md-stretch {\n    align-items: stretch !important;\n  }\n\n  .align-content-md-start {\n    align-content: flex-start !important;\n  }\n\n  .align-content-md-end {\n    align-content: flex-end !important;\n  }\n\n  .align-content-md-center {\n    align-content: center !important;\n  }\n\n  .align-content-md-between {\n    align-content: space-between !important;\n  }\n\n  .align-content-md-around {\n    align-content: space-around !important;\n  }\n\n  .align-content-md-stretch {\n    align-content: stretch !important;\n  }\n\n  .align-self-md-auto {\n    align-self: auto !important;\n  }\n\n  .align-self-md-start {\n    align-self: flex-start !important;\n  }\n\n  .align-self-md-end {\n    align-self: flex-end !important;\n  }\n\n  .align-self-md-center {\n    align-self: center !important;\n  }\n\n  .align-self-md-baseline {\n    align-self: baseline !important;\n  }\n\n  .align-self-md-stretch {\n    align-self: stretch !important;\n  }\n\n  .order-md-first {\n    order: -1 !important;\n  }\n\n  .order-md-0 {\n    order: 0 !important;\n  }\n\n  .order-md-1 {\n    order: 1 !important;\n  }\n\n  .order-md-2 {\n    order: 2 !important;\n  }\n\n  .order-md-3 {\n    order: 3 !important;\n  }\n\n  .order-md-4 {\n    order: 4 !important;\n  }\n\n  .order-md-5 {\n    order: 5 !important;\n  }\n\n  .order-md-last {\n    order: 6 !important;\n  }\n\n  .m-md-0 {\n    margin: 0 !important;\n  }\n\n  .m-md-1 {\n    margin: 0.25rem !important;\n  }\n\n  .m-md-2 {\n    margin: 0.5rem !important;\n  }\n\n  .m-md-3 {\n    margin: 1rem !important;\n  }\n\n  .m-md-4 {\n    margin: 1.5rem !important;\n  }\n\n  .m-md-5 {\n    margin: 3rem !important;\n  }\n\n  .m-md-auto {\n    margin: auto !important;\n  }\n\n  .mx-md-0 {\n    margin-left: 0 !important;\n    margin-right: 0 !important;\n  }\n\n  .mx-md-1 {\n    margin-left: 0.25rem !important;\n    margin-right: 0.25rem !important;\n  }\n\n  .mx-md-2 {\n    margin-left: 0.5rem !important;\n    margin-right: 0.5rem !important;\n  }\n\n  .mx-md-3 {\n    margin-left: 1rem !important;\n    margin-right: 1rem !important;\n  }\n\n  .mx-md-4 {\n    margin-left: 1.5rem !important;\n    margin-right: 1.5rem !important;\n  }\n\n  .mx-md-5 {\n    margin-left: 3rem !important;\n    margin-right: 3rem !important;\n  }\n\n  .mx-md-auto {\n    margin-left: auto !important;\n    margin-right: auto !important;\n  }\n\n  .my-md-0 {\n    margin-top: 0 !important;\n    margin-bottom: 0 !important;\n  }\n\n  .my-md-1 {\n    margin-top: 0.25rem !important;\n    margin-bottom: 0.25rem !important;\n  }\n\n  .my-md-2 {\n    margin-top: 0.5rem !important;\n    margin-bottom: 0.5rem !important;\n  }\n\n  .my-md-3 {\n    margin-top: 1rem !important;\n    margin-bottom: 1rem !important;\n  }\n\n  .my-md-4 {\n    margin-top: 1.5rem !important;\n    margin-bottom: 1.5rem !important;\n  }\n\n  .my-md-5 {\n    margin-top: 3rem !important;\n    margin-bottom: 3rem !important;\n  }\n\n  .my-md-auto {\n    margin-top: auto !important;\n    margin-bottom: auto !important;\n  }\n\n  .mt-md-0 {\n    margin-top: 0 !important;\n  }\n\n  .mt-md-1 {\n    margin-top: 0.25rem !important;\n  }\n\n  .mt-md-2 {\n    margin-top: 0.5rem !important;\n  }\n\n  .mt-md-3 {\n    margin-top: 1rem !important;\n  }\n\n  .mt-md-4 {\n    margin-top: 1.5rem !important;\n  }\n\n  .mt-md-5 {\n    margin-top: 3rem !important;\n  }\n\n  .mt-md-auto {\n    margin-top: auto !important;\n  }\n\n  .me-md-0 {\n    margin-left: 0 !important;\n  }\n\n  .me-md-1 {\n    margin-left: 0.25rem !important;\n  }\n\n  .me-md-2 {\n    margin-left: 0.5rem !important;\n  }\n\n  .me-md-3 {\n    margin-left: 1rem !important;\n  }\n\n  .me-md-4 {\n    margin-left: 1.5rem !important;\n  }\n\n  .me-md-5 {\n    margin-left: 3rem !important;\n  }\n\n  .me-md-auto {\n    margin-left: auto !important;\n  }\n\n  .mb-md-0 {\n    margin-bottom: 0 !important;\n  }\n\n  .mb-md-1 {\n    margin-bottom: 0.25rem !important;\n  }\n\n  .mb-md-2 {\n    margin-bottom: 0.5rem !important;\n  }\n\n  .mb-md-3 {\n    margin-bottom: 1rem !important;\n  }\n\n  .mb-md-4 {\n    margin-bottom: 1.5rem !important;\n  }\n\n  .mb-md-5 {\n    margin-bottom: 3rem !important;\n  }\n\n  .mb-md-auto {\n    margin-bottom: auto !important;\n  }\n\n  .ms-md-0 {\n    margin-right: 0 !important;\n  }\n\n  .ms-md-1 {\n    margin-right: 0.25rem !important;\n  }\n\n  .ms-md-2 {\n    margin-right: 0.5rem !important;\n  }\n\n  .ms-md-3 {\n    margin-right: 1rem !important;\n  }\n\n  .ms-md-4 {\n    margin-right: 1.5rem !important;\n  }\n\n  .ms-md-5 {\n    margin-right: 3rem !important;\n  }\n\n  .ms-md-auto {\n    margin-right: auto !important;\n  }\n\n  .p-md-0 {\n    padding: 0 !important;\n  }\n\n  .p-md-1 {\n    padding: 0.25rem !important;\n  }\n\n  .p-md-2 {\n    padding: 0.5rem !important;\n  }\n\n  .p-md-3 {\n    padding: 1rem !important;\n  }\n\n  .p-md-4 {\n    padding: 1.5rem !important;\n  }\n\n  .p-md-5 {\n    padding: 3rem !important;\n  }\n\n  .px-md-0 {\n    padding-left: 0 !important;\n    padding-right: 0 !important;\n  }\n\n  .px-md-1 {\n    padding-left: 0.25rem !important;\n    padding-right: 0.25rem !important;\n  }\n\n  .px-md-2 {\n    padding-left: 0.5rem !important;\n    padding-right: 0.5rem !important;\n  }\n\n  .px-md-3 {\n    padding-left: 1rem !important;\n    padding-right: 1rem !important;\n  }\n\n  .px-md-4 {\n    padding-left: 1.5rem !important;\n    padding-right: 1.5rem !important;\n  }\n\n  .px-md-5 {\n    padding-left: 3rem !important;\n    padding-right: 3rem !important;\n  }\n\n  .py-md-0 {\n    padding-top: 0 !important;\n    padding-bottom: 0 !important;\n  }\n\n  .py-md-1 {\n    padding-top: 0.25rem !important;\n    padding-bottom: 0.25rem !important;\n  }\n\n  .py-md-2 {\n    padding-top: 0.5rem !important;\n    padding-bottom: 0.5rem !important;\n  }\n\n  .py-md-3 {\n    padding-top: 1rem !important;\n    padding-bottom: 1rem !important;\n  }\n\n  .py-md-4 {\n    padding-top: 1.5rem !important;\n    padding-bottom: 1.5rem !important;\n  }\n\n  .py-md-5 {\n    padding-top: 3rem !important;\n    padding-bottom: 3rem !important;\n  }\n\n  .pt-md-0 {\n    padding-top: 0 !important;\n  }\n\n  .pt-md-1 {\n    padding-top: 0.25rem !important;\n  }\n\n  .pt-md-2 {\n    padding-top: 0.5rem !important;\n  }\n\n  .pt-md-3 {\n    padding-top: 1rem !important;\n  }\n\n  .pt-md-4 {\n    padding-top: 1.5rem !important;\n  }\n\n  .pt-md-5 {\n    padding-top: 3rem !important;\n  }\n\n  .pe-md-0 {\n    padding-left: 0 !important;\n  }\n\n  .pe-md-1 {\n    padding-left: 0.25rem !important;\n  }\n\n  .pe-md-2 {\n    padding-left: 0.5rem !important;\n  }\n\n  .pe-md-3 {\n    padding-left: 1rem !important;\n  }\n\n  .pe-md-4 {\n    padding-left: 1.5rem !important;\n  }\n\n  .pe-md-5 {\n    padding-left: 3rem !important;\n  }\n\n  .pb-md-0 {\n    padding-bottom: 0 !important;\n  }\n\n  .pb-md-1 {\n    padding-bottom: 0.25rem !important;\n  }\n\n  .pb-md-2 {\n    padding-bottom: 0.5rem !important;\n  }\n\n  .pb-md-3 {\n    padding-bottom: 1rem !important;\n  }\n\n  .pb-md-4 {\n    padding-bottom: 1.5rem !important;\n  }\n\n  .pb-md-5 {\n    padding-bottom: 3rem !important;\n  }\n\n  .ps-md-0 {\n    padding-right: 0 !important;\n  }\n\n  .ps-md-1 {\n    padding-right: 0.25rem !important;\n  }\n\n  .ps-md-2 {\n    padding-right: 0.5rem !important;\n  }\n\n  .ps-md-3 {\n    padding-right: 1rem !important;\n  }\n\n  .ps-md-4 {\n    padding-right: 1.5rem !important;\n  }\n\n  .ps-md-5 {\n    padding-right: 3rem !important;\n  }\n\n  .text-md-start {\n    text-align: right !important;\n  }\n\n  .text-md-end {\n    text-align: left !important;\n  }\n\n  .text-md-center {\n    text-align: center !important;\n  }\n}\n@media (min-width: 992px) {\n  .float-lg-start {\n    float: right !important;\n  }\n\n  .float-lg-end {\n    float: left !important;\n  }\n\n  .float-lg-none {\n    float: none !important;\n  }\n\n  .d-lg-inline {\n    display: inline !important;\n  }\n\n  .d-lg-inline-block {\n    display: inline-block !important;\n  }\n\n  .d-lg-block {\n    display: block !important;\n  }\n\n  .d-lg-grid {\n    display: grid !important;\n  }\n\n  .d-lg-table {\n    display: table !important;\n  }\n\n  .d-lg-table-row {\n    display: table-row !important;\n  }\n\n  .d-lg-table-cell {\n    display: table-cell !important;\n  }\n\n  .d-lg-flex {\n    display: flex !important;\n  }\n\n  .d-lg-inline-flex {\n    display: inline-flex !important;\n  }\n\n  .d-lg-none {\n    display: none !important;\n  }\n\n  .flex-lg-fill {\n    flex: 1 1 auto !important;\n  }\n\n  .flex-lg-row {\n    flex-direction: row !important;\n  }\n\n  .flex-lg-column {\n    flex-direction: column !important;\n  }\n\n  .flex-lg-row-reverse {\n    flex-direction: row-reverse !important;\n  }\n\n  .flex-lg-column-reverse {\n    flex-direction: column-reverse !important;\n  }\n\n  .flex-lg-grow-0 {\n    flex-grow: 0 !important;\n  }\n\n  .flex-lg-grow-1 {\n    flex-grow: 1 !important;\n  }\n\n  .flex-lg-shrink-0 {\n    flex-shrink: 0 !important;\n  }\n\n  .flex-lg-shrink-1 {\n    flex-shrink: 1 !important;\n  }\n\n  .flex-lg-wrap {\n    flex-wrap: wrap !important;\n  }\n\n  .flex-lg-nowrap {\n    flex-wrap: nowrap !important;\n  }\n\n  .flex-lg-wrap-reverse {\n    flex-wrap: wrap-reverse !important;\n  }\n\n  .gap-lg-0 {\n    gap: 0 !important;\n  }\n\n  .gap-lg-1 {\n    gap: 0.25rem !important;\n  }\n\n  .gap-lg-2 {\n    gap: 0.5rem !important;\n  }\n\n  .gap-lg-3 {\n    gap: 1rem !important;\n  }\n\n  .gap-lg-4 {\n    gap: 1.5rem !important;\n  }\n\n  .gap-lg-5 {\n    gap: 3rem !important;\n  }\n\n  .justify-content-lg-start {\n    justify-content: flex-start !important;\n  }\n\n  .justify-content-lg-end {\n    justify-content: flex-end !important;\n  }\n\n  .justify-content-lg-center {\n    justify-content: center !important;\n  }\n\n  .justify-content-lg-between {\n    justify-content: space-between !important;\n  }\n\n  .justify-content-lg-around {\n    justify-content: space-around !important;\n  }\n\n  .justify-content-lg-evenly {\n    justify-content: space-evenly !important;\n  }\n\n  .align-items-lg-start {\n    align-items: flex-start !important;\n  }\n\n  .align-items-lg-end {\n    align-items: flex-end !important;\n  }\n\n  .align-items-lg-center {\n    align-items: center !important;\n  }\n\n  .align-items-lg-baseline {\n    align-items: baseline !important;\n  }\n\n  .align-items-lg-stretch {\n    align-items: stretch !important;\n  }\n\n  .align-content-lg-start {\n    align-content: flex-start !important;\n  }\n\n  .align-content-lg-end {\n    align-content: flex-end !important;\n  }\n\n  .align-content-lg-center {\n    align-content: center !important;\n  }\n\n  .align-content-lg-between {\n    align-content: space-between !important;\n  }\n\n  .align-content-lg-around {\n    align-content: space-around !important;\n  }\n\n  .align-content-lg-stretch {\n    align-content: stretch !important;\n  }\n\n  .align-self-lg-auto {\n    align-self: auto !important;\n  }\n\n  .align-self-lg-start {\n    align-self: flex-start !important;\n  }\n\n  .align-self-lg-end {\n    align-self: flex-end !important;\n  }\n\n  .align-self-lg-center {\n    align-self: center !important;\n  }\n\n  .align-self-lg-baseline {\n    align-self: baseline !important;\n  }\n\n  .align-self-lg-stretch {\n    align-self: stretch !important;\n  }\n\n  .order-lg-first {\n    order: -1 !important;\n  }\n\n  .order-lg-0 {\n    order: 0 !important;\n  }\n\n  .order-lg-1 {\n    order: 1 !important;\n  }\n\n  .order-lg-2 {\n    order: 2 !important;\n  }\n\n  .order-lg-3 {\n    order: 3 !important;\n  }\n\n  .order-lg-4 {\n    order: 4 !important;\n  }\n\n  .order-lg-5 {\n    order: 5 !important;\n  }\n\n  .order-lg-last {\n    order: 6 !important;\n  }\n\n  .m-lg-0 {\n    margin: 0 !important;\n  }\n\n  .m-lg-1 {\n    margin: 0.25rem !important;\n  }\n\n  .m-lg-2 {\n    margin: 0.5rem !important;\n  }\n\n  .m-lg-3 {\n    margin: 1rem !important;\n  }\n\n  .m-lg-4 {\n    margin: 1.5rem !important;\n  }\n\n  .m-lg-5 {\n    margin: 3rem !important;\n  }\n\n  .m-lg-auto {\n    margin: auto !important;\n  }\n\n  .mx-lg-0 {\n    margin-left: 0 !important;\n    margin-right: 0 !important;\n  }\n\n  .mx-lg-1 {\n    margin-left: 0.25rem !important;\n    margin-right: 0.25rem !important;\n  }\n\n  .mx-lg-2 {\n    margin-left: 0.5rem !important;\n    margin-right: 0.5rem !important;\n  }\n\n  .mx-lg-3 {\n    margin-left: 1rem !important;\n    margin-right: 1rem !important;\n  }\n\n  .mx-lg-4 {\n    margin-left: 1.5rem !important;\n    margin-right: 1.5rem !important;\n  }\n\n  .mx-lg-5 {\n    margin-left: 3rem !important;\n    margin-right: 3rem !important;\n  }\n\n  .mx-lg-auto {\n    margin-left: auto !important;\n    margin-right: auto !important;\n  }\n\n  .my-lg-0 {\n    margin-top: 0 !important;\n    margin-bottom: 0 !important;\n  }\n\n  .my-lg-1 {\n    margin-top: 0.25rem !important;\n    margin-bottom: 0.25rem !important;\n  }\n\n  .my-lg-2 {\n    margin-top: 0.5rem !important;\n    margin-bottom: 0.5rem !important;\n  }\n\n  .my-lg-3 {\n    margin-top: 1rem !important;\n    margin-bottom: 1rem !important;\n  }\n\n  .my-lg-4 {\n    margin-top: 1.5rem !important;\n    margin-bottom: 1.5rem !important;\n  }\n\n  .my-lg-5 {\n    margin-top: 3rem !important;\n    margin-bottom: 3rem !important;\n  }\n\n  .my-lg-auto {\n    margin-top: auto !important;\n    margin-bottom: auto !important;\n  }\n\n  .mt-lg-0 {\n    margin-top: 0 !important;\n  }\n\n  .mt-lg-1 {\n    margin-top: 0.25rem !important;\n  }\n\n  .mt-lg-2 {\n    margin-top: 0.5rem !important;\n  }\n\n  .mt-lg-3 {\n    margin-top: 1rem !important;\n  }\n\n  .mt-lg-4 {\n    margin-top: 1.5rem !important;\n  }\n\n  .mt-lg-5 {\n    margin-top: 3rem !important;\n  }\n\n  .mt-lg-auto {\n    margin-top: auto !important;\n  }\n\n  .me-lg-0 {\n    margin-left: 0 !important;\n  }\n\n  .me-lg-1 {\n    margin-left: 0.25rem !important;\n  }\n\n  .me-lg-2 {\n    margin-left: 0.5rem !important;\n  }\n\n  .me-lg-3 {\n    margin-left: 1rem !important;\n  }\n\n  .me-lg-4 {\n    margin-left: 1.5rem !important;\n  }\n\n  .me-lg-5 {\n    margin-left: 3rem !important;\n  }\n\n  .me-lg-auto {\n    margin-left: auto !important;\n  }\n\n  .mb-lg-0 {\n    margin-bottom: 0 !important;\n  }\n\n  .mb-lg-1 {\n    margin-bottom: 0.25rem !important;\n  }\n\n  .mb-lg-2 {\n    margin-bottom: 0.5rem !important;\n  }\n\n  .mb-lg-3 {\n    margin-bottom: 1rem !important;\n  }\n\n  .mb-lg-4 {\n    margin-bottom: 1.5rem !important;\n  }\n\n  .mb-lg-5 {\n    margin-bottom: 3rem !important;\n  }\n\n  .mb-lg-auto {\n    margin-bottom: auto !important;\n  }\n\n  .ms-lg-0 {\n    margin-right: 0 !important;\n  }\n\n  .ms-lg-1 {\n    margin-right: 0.25rem !important;\n  }\n\n  .ms-lg-2 {\n    margin-right: 0.5rem !important;\n  }\n\n  .ms-lg-3 {\n    margin-right: 1rem !important;\n  }\n\n  .ms-lg-4 {\n    margin-right: 1.5rem !important;\n  }\n\n  .ms-lg-5 {\n    margin-right: 3rem !important;\n  }\n\n  .ms-lg-auto {\n    margin-right: auto !important;\n  }\n\n  .p-lg-0 {\n    padding: 0 !important;\n  }\n\n  .p-lg-1 {\n    padding: 0.25rem !important;\n  }\n\n  .p-lg-2 {\n    padding: 0.5rem !important;\n  }\n\n  .p-lg-3 {\n    padding: 1rem !important;\n  }\n\n  .p-lg-4 {\n    padding: 1.5rem !important;\n  }\n\n  .p-lg-5 {\n    padding: 3rem !important;\n  }\n\n  .px-lg-0 {\n    padding-left: 0 !important;\n    padding-right: 0 !important;\n  }\n\n  .px-lg-1 {\n    padding-left: 0.25rem !important;\n    padding-right: 0.25rem !important;\n  }\n\n  .px-lg-2 {\n    padding-left: 0.5rem !important;\n    padding-right: 0.5rem !important;\n  }\n\n  .px-lg-3 {\n    padding-left: 1rem !important;\n    padding-right: 1rem !important;\n  }\n\n  .px-lg-4 {\n    padding-left: 1.5rem !important;\n    padding-right: 1.5rem !important;\n  }\n\n  .px-lg-5 {\n    padding-left: 3rem !important;\n    padding-right: 3rem !important;\n  }\n\n  .py-lg-0 {\n    padding-top: 0 !important;\n    padding-bottom: 0 !important;\n  }\n\n  .py-lg-1 {\n    padding-top: 0.25rem !important;\n    padding-bottom: 0.25rem !important;\n  }\n\n  .py-lg-2 {\n    padding-top: 0.5rem !important;\n    padding-bottom: 0.5rem !important;\n  }\n\n  .py-lg-3 {\n    padding-top: 1rem !important;\n    padding-bottom: 1rem !important;\n  }\n\n  .py-lg-4 {\n    padding-top: 1.5rem !important;\n    padding-bottom: 1.5rem !important;\n  }\n\n  .py-lg-5 {\n    padding-top: 3rem !important;\n    padding-bottom: 3rem !important;\n  }\n\n  .pt-lg-0 {\n    padding-top: 0 !important;\n  }\n\n  .pt-lg-1 {\n    padding-top: 0.25rem !important;\n  }\n\n  .pt-lg-2 {\n    padding-top: 0.5rem !important;\n  }\n\n  .pt-lg-3 {\n    padding-top: 1rem !important;\n  }\n\n  .pt-lg-4 {\n    padding-top: 1.5rem !important;\n  }\n\n  .pt-lg-5 {\n    padding-top: 3rem !important;\n  }\n\n  .pe-lg-0 {\n    padding-left: 0 !important;\n  }\n\n  .pe-lg-1 {\n    padding-left: 0.25rem !important;\n  }\n\n  .pe-lg-2 {\n    padding-left: 0.5rem !important;\n  }\n\n  .pe-lg-3 {\n    padding-left: 1rem !important;\n  }\n\n  .pe-lg-4 {\n    padding-left: 1.5rem !important;\n  }\n\n  .pe-lg-5 {\n    padding-left: 3rem !important;\n  }\n\n  .pb-lg-0 {\n    padding-bottom: 0 !important;\n  }\n\n  .pb-lg-1 {\n    padding-bottom: 0.25rem !important;\n  }\n\n  .pb-lg-2 {\n    padding-bottom: 0.5rem !important;\n  }\n\n  .pb-lg-3 {\n    padding-bottom: 1rem !important;\n  }\n\n  .pb-lg-4 {\n    padding-bottom: 1.5rem !important;\n  }\n\n  .pb-lg-5 {\n    padding-bottom: 3rem !important;\n  }\n\n  .ps-lg-0 {\n    padding-right: 0 !important;\n  }\n\n  .ps-lg-1 {\n    padding-right: 0.25rem !important;\n  }\n\n  .ps-lg-2 {\n    padding-right: 0.5rem !important;\n  }\n\n  .ps-lg-3 {\n    padding-right: 1rem !important;\n  }\n\n  .ps-lg-4 {\n    padding-right: 1.5rem !important;\n  }\n\n  .ps-lg-5 {\n    padding-right: 3rem !important;\n  }\n\n  .text-lg-start {\n    text-align: right !important;\n  }\n\n  .text-lg-end {\n    text-align: left !important;\n  }\n\n  .text-lg-center {\n    text-align: center !important;\n  }\n}\n@media (min-width: 1200px) {\n  .float-xl-start {\n    float: right !important;\n  }\n\n  .float-xl-end {\n    float: left !important;\n  }\n\n  .float-xl-none {\n    float: none !important;\n  }\n\n  .d-xl-inline {\n    display: inline !important;\n  }\n\n  .d-xl-inline-block {\n    display: inline-block !important;\n  }\n\n  .d-xl-block {\n    display: block !important;\n  }\n\n  .d-xl-grid {\n    display: grid !important;\n  }\n\n  .d-xl-table {\n    display: table !important;\n  }\n\n  .d-xl-table-row {\n    display: table-row !important;\n  }\n\n  .d-xl-table-cell {\n    display: table-cell !important;\n  }\n\n  .d-xl-flex {\n    display: flex !important;\n  }\n\n  .d-xl-inline-flex {\n    display: inline-flex !important;\n  }\n\n  .d-xl-none {\n    display: none !important;\n  }\n\n  .flex-xl-fill {\n    flex: 1 1 auto !important;\n  }\n\n  .flex-xl-row {\n    flex-direction: row !important;\n  }\n\n  .flex-xl-column {\n    flex-direction: column !important;\n  }\n\n  .flex-xl-row-reverse {\n    flex-direction: row-reverse !important;\n  }\n\n  .flex-xl-column-reverse {\n    flex-direction: column-reverse !important;\n  }\n\n  .flex-xl-grow-0 {\n    flex-grow: 0 !important;\n  }\n\n  .flex-xl-grow-1 {\n    flex-grow: 1 !important;\n  }\n\n  .flex-xl-shrink-0 {\n    flex-shrink: 0 !important;\n  }\n\n  .flex-xl-shrink-1 {\n    flex-shrink: 1 !important;\n  }\n\n  .flex-xl-wrap {\n    flex-wrap: wrap !important;\n  }\n\n  .flex-xl-nowrap {\n    flex-wrap: nowrap !important;\n  }\n\n  .flex-xl-wrap-reverse {\n    flex-wrap: wrap-reverse !important;\n  }\n\n  .gap-xl-0 {\n    gap: 0 !important;\n  }\n\n  .gap-xl-1 {\n    gap: 0.25rem !important;\n  }\n\n  .gap-xl-2 {\n    gap: 0.5rem !important;\n  }\n\n  .gap-xl-3 {\n    gap: 1rem !important;\n  }\n\n  .gap-xl-4 {\n    gap: 1.5rem !important;\n  }\n\n  .gap-xl-5 {\n    gap: 3rem !important;\n  }\n\n  .justify-content-xl-start {\n    justify-content: flex-start !important;\n  }\n\n  .justify-content-xl-end {\n    justify-content: flex-end !important;\n  }\n\n  .justify-content-xl-center {\n    justify-content: center !important;\n  }\n\n  .justify-content-xl-between {\n    justify-content: space-between !important;\n  }\n\n  .justify-content-xl-around {\n    justify-content: space-around !important;\n  }\n\n  .justify-content-xl-evenly {\n    justify-content: space-evenly !important;\n  }\n\n  .align-items-xl-start {\n    align-items: flex-start !important;\n  }\n\n  .align-items-xl-end {\n    align-items: flex-end !important;\n  }\n\n  .align-items-xl-center {\n    align-items: center !important;\n  }\n\n  .align-items-xl-baseline {\n    align-items: baseline !important;\n  }\n\n  .align-items-xl-stretch {\n    align-items: stretch !important;\n  }\n\n  .align-content-xl-start {\n    align-content: flex-start !important;\n  }\n\n  .align-content-xl-end {\n    align-content: flex-end !important;\n  }\n\n  .align-content-xl-center {\n    align-content: center !important;\n  }\n\n  .align-content-xl-between {\n    align-content: space-between !important;\n  }\n\n  .align-content-xl-around {\n    align-content: space-around !important;\n  }\n\n  .align-content-xl-stretch {\n    align-content: stretch !important;\n  }\n\n  .align-self-xl-auto {\n    align-self: auto !important;\n  }\n\n  .align-self-xl-start {\n    align-self: flex-start !important;\n  }\n\n  .align-self-xl-end {\n    align-self: flex-end !important;\n  }\n\n  .align-self-xl-center {\n    align-self: center !important;\n  }\n\n  .align-self-xl-baseline {\n    align-self: baseline !important;\n  }\n\n  .align-self-xl-stretch {\n    align-self: stretch !important;\n  }\n\n  .order-xl-first {\n    order: -1 !important;\n  }\n\n  .order-xl-0 {\n    order: 0 !important;\n  }\n\n  .order-xl-1 {\n    order: 1 !important;\n  }\n\n  .order-xl-2 {\n    order: 2 !important;\n  }\n\n  .order-xl-3 {\n    order: 3 !important;\n  }\n\n  .order-xl-4 {\n    order: 4 !important;\n  }\n\n  .order-xl-5 {\n    order: 5 !important;\n  }\n\n  .order-xl-last {\n    order: 6 !important;\n  }\n\n  .m-xl-0 {\n    margin: 0 !important;\n  }\n\n  .m-xl-1 {\n    margin: 0.25rem !important;\n  }\n\n  .m-xl-2 {\n    margin: 0.5rem !important;\n  }\n\n  .m-xl-3 {\n    margin: 1rem !important;\n  }\n\n  .m-xl-4 {\n    margin: 1.5rem !important;\n  }\n\n  .m-xl-5 {\n    margin: 3rem !important;\n  }\n\n  .m-xl-auto {\n    margin: auto !important;\n  }\n\n  .mx-xl-0 {\n    margin-left: 0 !important;\n    margin-right: 0 !important;\n  }\n\n  .mx-xl-1 {\n    margin-left: 0.25rem !important;\n    margin-right: 0.25rem !important;\n  }\n\n  .mx-xl-2 {\n    margin-left: 0.5rem !important;\n    margin-right: 0.5rem !important;\n  }\n\n  .mx-xl-3 {\n    margin-left: 1rem !important;\n    margin-right: 1rem !important;\n  }\n\n  .mx-xl-4 {\n    margin-left: 1.5rem !important;\n    margin-right: 1.5rem !important;\n  }\n\n  .mx-xl-5 {\n    margin-left: 3rem !important;\n    margin-right: 3rem !important;\n  }\n\n  .mx-xl-auto {\n    margin-left: auto !important;\n    margin-right: auto !important;\n  }\n\n  .my-xl-0 {\n    margin-top: 0 !important;\n    margin-bottom: 0 !important;\n  }\n\n  .my-xl-1 {\n    margin-top: 0.25rem !important;\n    margin-bottom: 0.25rem !important;\n  }\n\n  .my-xl-2 {\n    margin-top: 0.5rem !important;\n    margin-bottom: 0.5rem !important;\n  }\n\n  .my-xl-3 {\n    margin-top: 1rem !important;\n    margin-bottom: 1rem !important;\n  }\n\n  .my-xl-4 {\n    margin-top: 1.5rem !important;\n    margin-bottom: 1.5rem !important;\n  }\n\n  .my-xl-5 {\n    margin-top: 3rem !important;\n    margin-bottom: 3rem !important;\n  }\n\n  .my-xl-auto {\n    margin-top: auto !important;\n    margin-bottom: auto !important;\n  }\n\n  .mt-xl-0 {\n    margin-top: 0 !important;\n  }\n\n  .mt-xl-1 {\n    margin-top: 0.25rem !important;\n  }\n\n  .mt-xl-2 {\n    margin-top: 0.5rem !important;\n  }\n\n  .mt-xl-3 {\n    margin-top: 1rem !important;\n  }\n\n  .mt-xl-4 {\n    margin-top: 1.5rem !important;\n  }\n\n  .mt-xl-5 {\n    margin-top: 3rem !important;\n  }\n\n  .mt-xl-auto {\n    margin-top: auto !important;\n  }\n\n  .me-xl-0 {\n    margin-left: 0 !important;\n  }\n\n  .me-xl-1 {\n    margin-left: 0.25rem !important;\n  }\n\n  .me-xl-2 {\n    margin-left: 0.5rem !important;\n  }\n\n  .me-xl-3 {\n    margin-left: 1rem !important;\n  }\n\n  .me-xl-4 {\n    margin-left: 1.5rem !important;\n  }\n\n  .me-xl-5 {\n    margin-left: 3rem !important;\n  }\n\n  .me-xl-auto {\n    margin-left: auto !important;\n  }\n\n  .mb-xl-0 {\n    margin-bottom: 0 !important;\n  }\n\n  .mb-xl-1 {\n    margin-bottom: 0.25rem !important;\n  }\n\n  .mb-xl-2 {\n    margin-bottom: 0.5rem !important;\n  }\n\n  .mb-xl-3 {\n    margin-bottom: 1rem !important;\n  }\n\n  .mb-xl-4 {\n    margin-bottom: 1.5rem !important;\n  }\n\n  .mb-xl-5 {\n    margin-bottom: 3rem !important;\n  }\n\n  .mb-xl-auto {\n    margin-bottom: auto !important;\n  }\n\n  .ms-xl-0 {\n    margin-right: 0 !important;\n  }\n\n  .ms-xl-1 {\n    margin-right: 0.25rem !important;\n  }\n\n  .ms-xl-2 {\n    margin-right: 0.5rem !important;\n  }\n\n  .ms-xl-3 {\n    margin-right: 1rem !important;\n  }\n\n  .ms-xl-4 {\n    margin-right: 1.5rem !important;\n  }\n\n  .ms-xl-5 {\n    margin-right: 3rem !important;\n  }\n\n  .ms-xl-auto {\n    margin-right: auto !important;\n  }\n\n  .p-xl-0 {\n    padding: 0 !important;\n  }\n\n  .p-xl-1 {\n    padding: 0.25rem !important;\n  }\n\n  .p-xl-2 {\n    padding: 0.5rem !important;\n  }\n\n  .p-xl-3 {\n    padding: 1rem !important;\n  }\n\n  .p-xl-4 {\n    padding: 1.5rem !important;\n  }\n\n  .p-xl-5 {\n    padding: 3rem !important;\n  }\n\n  .px-xl-0 {\n    padding-left: 0 !important;\n    padding-right: 0 !important;\n  }\n\n  .px-xl-1 {\n    padding-left: 0.25rem !important;\n    padding-right: 0.25rem !important;\n  }\n\n  .px-xl-2 {\n    padding-left: 0.5rem !important;\n    padding-right: 0.5rem !important;\n  }\n\n  .px-xl-3 {\n    padding-left: 1rem !important;\n    padding-right: 1rem !important;\n  }\n\n  .px-xl-4 {\n    padding-left: 1.5rem !important;\n    padding-right: 1.5rem !important;\n  }\n\n  .px-xl-5 {\n    padding-left: 3rem !important;\n    padding-right: 3rem !important;\n  }\n\n  .py-xl-0 {\n    padding-top: 0 !important;\n    padding-bottom: 0 !important;\n  }\n\n  .py-xl-1 {\n    padding-top: 0.25rem !important;\n    padding-bottom: 0.25rem !important;\n  }\n\n  .py-xl-2 {\n    padding-top: 0.5rem !important;\n    padding-bottom: 0.5rem !important;\n  }\n\n  .py-xl-3 {\n    padding-top: 1rem !important;\n    padding-bottom: 1rem !important;\n  }\n\n  .py-xl-4 {\n    padding-top: 1.5rem !important;\n    padding-bottom: 1.5rem !important;\n  }\n\n  .py-xl-5 {\n    padding-top: 3rem !important;\n    padding-bottom: 3rem !important;\n  }\n\n  .pt-xl-0 {\n    padding-top: 0 !important;\n  }\n\n  .pt-xl-1 {\n    padding-top: 0.25rem !important;\n  }\n\n  .pt-xl-2 {\n    padding-top: 0.5rem !important;\n  }\n\n  .pt-xl-3 {\n    padding-top: 1rem !important;\n  }\n\n  .pt-xl-4 {\n    padding-top: 1.5rem !important;\n  }\n\n  .pt-xl-5 {\n    padding-top: 3rem !important;\n  }\n\n  .pe-xl-0 {\n    padding-left: 0 !important;\n  }\n\n  .pe-xl-1 {\n    padding-left: 0.25rem !important;\n  }\n\n  .pe-xl-2 {\n    padding-left: 0.5rem !important;\n  }\n\n  .pe-xl-3 {\n    padding-left: 1rem !important;\n  }\n\n  .pe-xl-4 {\n    padding-left: 1.5rem !important;\n  }\n\n  .pe-xl-5 {\n    padding-left: 3rem !important;\n  }\n\n  .pb-xl-0 {\n    padding-bottom: 0 !important;\n  }\n\n  .pb-xl-1 {\n    padding-bottom: 0.25rem !important;\n  }\n\n  .pb-xl-2 {\n    padding-bottom: 0.5rem !important;\n  }\n\n  .pb-xl-3 {\n    padding-bottom: 1rem !important;\n  }\n\n  .pb-xl-4 {\n    padding-bottom: 1.5rem !important;\n  }\n\n  .pb-xl-5 {\n    padding-bottom: 3rem !important;\n  }\n\n  .ps-xl-0 {\n    padding-right: 0 !important;\n  }\n\n  .ps-xl-1 {\n    padding-right: 0.25rem !important;\n  }\n\n  .ps-xl-2 {\n    padding-right: 0.5rem !important;\n  }\n\n  .ps-xl-3 {\n    padding-right: 1rem !important;\n  }\n\n  .ps-xl-4 {\n    padding-right: 1.5rem !important;\n  }\n\n  .ps-xl-5 {\n    padding-right: 3rem !important;\n  }\n\n  .text-xl-start {\n    text-align: right !important;\n  }\n\n  .text-xl-end {\n    text-align: left !important;\n  }\n\n  .text-xl-center {\n    text-align: center !important;\n  }\n}\n@media (min-width: 1400px) {\n  .float-xxl-start {\n    float: right !important;\n  }\n\n  .float-xxl-end {\n    float: left !important;\n  }\n\n  .float-xxl-none {\n    float: none !important;\n  }\n\n  .d-xxl-inline {\n    display: inline !important;\n  }\n\n  .d-xxl-inline-block {\n    display: inline-block !important;\n  }\n\n  .d-xxl-block {\n    display: block !important;\n  }\n\n  .d-xxl-grid {\n    display: grid !important;\n  }\n\n  .d-xxl-table {\n    display: table !important;\n  }\n\n  .d-xxl-table-row {\n    display: table-row !important;\n  }\n\n  .d-xxl-table-cell {\n    display: table-cell !important;\n  }\n\n  .d-xxl-flex {\n    display: flex !important;\n  }\n\n  .d-xxl-inline-flex {\n    display: inline-flex !important;\n  }\n\n  .d-xxl-none {\n    display: none !important;\n  }\n\n  .flex-xxl-fill {\n    flex: 1 1 auto !important;\n  }\n\n  .flex-xxl-row {\n    flex-direction: row !important;\n  }\n\n  .flex-xxl-column {\n    flex-direction: column !important;\n  }\n\n  .flex-xxl-row-reverse {\n    flex-direction: row-reverse !important;\n  }\n\n  .flex-xxl-column-reverse {\n    flex-direction: column-reverse !important;\n  }\n\n  .flex-xxl-grow-0 {\n    flex-grow: 0 !important;\n  }\n\n  .flex-xxl-grow-1 {\n    flex-grow: 1 !important;\n  }\n\n  .flex-xxl-shrink-0 {\n    flex-shrink: 0 !important;\n  }\n\n  .flex-xxl-shrink-1 {\n    flex-shrink: 1 !important;\n  }\n\n  .flex-xxl-wrap {\n    flex-wrap: wrap !important;\n  }\n\n  .flex-xxl-nowrap {\n    flex-wrap: nowrap !important;\n  }\n\n  .flex-xxl-wrap-reverse {\n    flex-wrap: wrap-reverse !important;\n  }\n\n  .gap-xxl-0 {\n    gap: 0 !important;\n  }\n\n  .gap-xxl-1 {\n    gap: 0.25rem !important;\n  }\n\n  .gap-xxl-2 {\n    gap: 0.5rem !important;\n  }\n\n  .gap-xxl-3 {\n    gap: 1rem !important;\n  }\n\n  .gap-xxl-4 {\n    gap: 1.5rem !important;\n  }\n\n  .gap-xxl-5 {\n    gap: 3rem !important;\n  }\n\n  .justify-content-xxl-start {\n    justify-content: flex-start !important;\n  }\n\n  .justify-content-xxl-end {\n    justify-content: flex-end !important;\n  }\n\n  .justify-content-xxl-center {\n    justify-content: center !important;\n  }\n\n  .justify-content-xxl-between {\n    justify-content: space-between !important;\n  }\n\n  .justify-content-xxl-around {\n    justify-content: space-around !important;\n  }\n\n  .justify-content-xxl-evenly {\n    justify-content: space-evenly !important;\n  }\n\n  .align-items-xxl-start {\n    align-items: flex-start !important;\n  }\n\n  .align-items-xxl-end {\n    align-items: flex-end !important;\n  }\n\n  .align-items-xxl-center {\n    align-items: center !important;\n  }\n\n  .align-items-xxl-baseline {\n    align-items: baseline !important;\n  }\n\n  .align-items-xxl-stretch {\n    align-items: stretch !important;\n  }\n\n  .align-content-xxl-start {\n    align-content: flex-start !important;\n  }\n\n  .align-content-xxl-end {\n    align-content: flex-end !important;\n  }\n\n  .align-content-xxl-center {\n    align-content: center !important;\n  }\n\n  .align-content-xxl-between {\n    align-content: space-between !important;\n  }\n\n  .align-content-xxl-around {\n    align-content: space-around !important;\n  }\n\n  .align-content-xxl-stretch {\n    align-content: stretch !important;\n  }\n\n  .align-self-xxl-auto {\n    align-self: auto !important;\n  }\n\n  .align-self-xxl-start {\n    align-self: flex-start !important;\n  }\n\n  .align-self-xxl-end {\n    align-self: flex-end !important;\n  }\n\n  .align-self-xxl-center {\n    align-self: center !important;\n  }\n\n  .align-self-xxl-baseline {\n    align-self: baseline !important;\n  }\n\n  .align-self-xxl-stretch {\n    align-self: stretch !important;\n  }\n\n  .order-xxl-first {\n    order: -1 !important;\n  }\n\n  .order-xxl-0 {\n    order: 0 !important;\n  }\n\n  .order-xxl-1 {\n    order: 1 !important;\n  }\n\n  .order-xxl-2 {\n    order: 2 !important;\n  }\n\n  .order-xxl-3 {\n    order: 3 !important;\n  }\n\n  .order-xxl-4 {\n    order: 4 !important;\n  }\n\n  .order-xxl-5 {\n    order: 5 !important;\n  }\n\n  .order-xxl-last {\n    order: 6 !important;\n  }\n\n  .m-xxl-0 {\n    margin: 0 !important;\n  }\n\n  .m-xxl-1 {\n    margin: 0.25rem !important;\n  }\n\n  .m-xxl-2 {\n    margin: 0.5rem !important;\n  }\n\n  .m-xxl-3 {\n    margin: 1rem !important;\n  }\n\n  .m-xxl-4 {\n    margin: 1.5rem !important;\n  }\n\n  .m-xxl-5 {\n    margin: 3rem !important;\n  }\n\n  .m-xxl-auto {\n    margin: auto !important;\n  }\n\n  .mx-xxl-0 {\n    margin-left: 0 !important;\n    margin-right: 0 !important;\n  }\n\n  .mx-xxl-1 {\n    margin-left: 0.25rem !important;\n    margin-right: 0.25rem !important;\n  }\n\n  .mx-xxl-2 {\n    margin-left: 0.5rem !important;\n    margin-right: 0.5rem !important;\n  }\n\n  .mx-xxl-3 {\n    margin-left: 1rem !important;\n    margin-right: 1rem !important;\n  }\n\n  .mx-xxl-4 {\n    margin-left: 1.5rem !important;\n    margin-right: 1.5rem !important;\n  }\n\n  .mx-xxl-5 {\n    margin-left: 3rem !important;\n    margin-right: 3rem !important;\n  }\n\n  .mx-xxl-auto {\n    margin-left: auto !important;\n    margin-right: auto !important;\n  }\n\n  .my-xxl-0 {\n    margin-top: 0 !important;\n    margin-bottom: 0 !important;\n  }\n\n  .my-xxl-1 {\n    margin-top: 0.25rem !important;\n    margin-bottom: 0.25rem !important;\n  }\n\n  .my-xxl-2 {\n    margin-top: 0.5rem !important;\n    margin-bottom: 0.5rem !important;\n  }\n\n  .my-xxl-3 {\n    margin-top: 1rem !important;\n    margin-bottom: 1rem !important;\n  }\n\n  .my-xxl-4 {\n    margin-top: 1.5rem !important;\n    margin-bottom: 1.5rem !important;\n  }\n\n  .my-xxl-5 {\n    margin-top: 3rem !important;\n    margin-bottom: 3rem !important;\n  }\n\n  .my-xxl-auto {\n    margin-top: auto !important;\n    margin-bottom: auto !important;\n  }\n\n  .mt-xxl-0 {\n    margin-top: 0 !important;\n  }\n\n  .mt-xxl-1 {\n    margin-top: 0.25rem !important;\n  }\n\n  .mt-xxl-2 {\n    margin-top: 0.5rem !important;\n  }\n\n  .mt-xxl-3 {\n    margin-top: 1rem !important;\n  }\n\n  .mt-xxl-4 {\n    margin-top: 1.5rem !important;\n  }\n\n  .mt-xxl-5 {\n    margin-top: 3rem !important;\n  }\n\n  .mt-xxl-auto {\n    margin-top: auto !important;\n  }\n\n  .me-xxl-0 {\n    margin-left: 0 !important;\n  }\n\n  .me-xxl-1 {\n    margin-left: 0.25rem !important;\n  }\n\n  .me-xxl-2 {\n    margin-left: 0.5rem !important;\n  }\n\n  .me-xxl-3 {\n    margin-left: 1rem !important;\n  }\n\n  .me-xxl-4 {\n    margin-left: 1.5rem !important;\n  }\n\n  .me-xxl-5 {\n    margin-left: 3rem !important;\n  }\n\n  .me-xxl-auto {\n    margin-left: auto !important;\n  }\n\n  .mb-xxl-0 {\n    margin-bottom: 0 !important;\n  }\n\n  .mb-xxl-1 {\n    margin-bottom: 0.25rem !important;\n  }\n\n  .mb-xxl-2 {\n    margin-bottom: 0.5rem !important;\n  }\n\n  .mb-xxl-3 {\n    margin-bottom: 1rem !important;\n  }\n\n  .mb-xxl-4 {\n    margin-bottom: 1.5rem !important;\n  }\n\n  .mb-xxl-5 {\n    margin-bottom: 3rem !important;\n  }\n\n  .mb-xxl-auto {\n    margin-bottom: auto !important;\n  }\n\n  .ms-xxl-0 {\n    margin-right: 0 !important;\n  }\n\n  .ms-xxl-1 {\n    margin-right: 0.25rem !important;\n  }\n\n  .ms-xxl-2 {\n    margin-right: 0.5rem !important;\n  }\n\n  .ms-xxl-3 {\n    margin-right: 1rem !important;\n  }\n\n  .ms-xxl-4 {\n    margin-right: 1.5rem !important;\n  }\n\n  .ms-xxl-5 {\n    margin-right: 3rem !important;\n  }\n\n  .ms-xxl-auto {\n    margin-right: auto !important;\n  }\n\n  .p-xxl-0 {\n    padding: 0 !important;\n  }\n\n  .p-xxl-1 {\n    padding: 0.25rem !important;\n  }\n\n  .p-xxl-2 {\n    padding: 0.5rem !important;\n  }\n\n  .p-xxl-3 {\n    padding: 1rem !important;\n  }\n\n  .p-xxl-4 {\n    padding: 1.5rem !important;\n  }\n\n  .p-xxl-5 {\n    padding: 3rem !important;\n  }\n\n  .px-xxl-0 {\n    padding-left: 0 !important;\n    padding-right: 0 !important;\n  }\n\n  .px-xxl-1 {\n    padding-left: 0.25rem !important;\n    padding-right: 0.25rem !important;\n  }\n\n  .px-xxl-2 {\n    padding-left: 0.5rem !important;\n    padding-right: 0.5rem !important;\n  }\n\n  .px-xxl-3 {\n    padding-left: 1rem !important;\n    padding-right: 1rem !important;\n  }\n\n  .px-xxl-4 {\n    padding-left: 1.5rem !important;\n    padding-right: 1.5rem !important;\n  }\n\n  .px-xxl-5 {\n    padding-left: 3rem !important;\n    padding-right: 3rem !important;\n  }\n\n  .py-xxl-0 {\n    padding-top: 0 !important;\n    padding-bottom: 0 !important;\n  }\n\n  .py-xxl-1 {\n    padding-top: 0.25rem !important;\n    padding-bottom: 0.25rem !important;\n  }\n\n  .py-xxl-2 {\n    padding-top: 0.5rem !important;\n    padding-bottom: 0.5rem !important;\n  }\n\n  .py-xxl-3 {\n    padding-top: 1rem !important;\n    padding-bottom: 1rem !important;\n  }\n\n  .py-xxl-4 {\n    padding-top: 1.5rem !important;\n    padding-bottom: 1.5rem !important;\n  }\n\n  .py-xxl-5 {\n    padding-top: 3rem !important;\n    padding-bottom: 3rem !important;\n  }\n\n  .pt-xxl-0 {\n    padding-top: 0 !important;\n  }\n\n  .pt-xxl-1 {\n    padding-top: 0.25rem !important;\n  }\n\n  .pt-xxl-2 {\n    padding-top: 0.5rem !important;\n  }\n\n  .pt-xxl-3 {\n    padding-top: 1rem !important;\n  }\n\n  .pt-xxl-4 {\n    padding-top: 1.5rem !important;\n  }\n\n  .pt-xxl-5 {\n    padding-top: 3rem !important;\n  }\n\n  .pe-xxl-0 {\n    padding-left: 0 !important;\n  }\n\n  .pe-xxl-1 {\n    padding-left: 0.25rem !important;\n  }\n\n  .pe-xxl-2 {\n    padding-left: 0.5rem !important;\n  }\n\n  .pe-xxl-3 {\n    padding-left: 1rem !important;\n  }\n\n  .pe-xxl-4 {\n    padding-left: 1.5rem !important;\n  }\n\n  .pe-xxl-5 {\n    padding-left: 3rem !important;\n  }\n\n  .pb-xxl-0 {\n    padding-bottom: 0 !important;\n  }\n\n  .pb-xxl-1 {\n    padding-bottom: 0.25rem !important;\n  }\n\n  .pb-xxl-2 {\n    padding-bottom: 0.5rem !important;\n  }\n\n  .pb-xxl-3 {\n    padding-bottom: 1rem !important;\n  }\n\n  .pb-xxl-4 {\n    padding-bottom: 1.5rem !important;\n  }\n\n  .pb-xxl-5 {\n    padding-bottom: 3rem !important;\n  }\n\n  .ps-xxl-0 {\n    padding-right: 0 !important;\n  }\n\n  .ps-xxl-1 {\n    padding-right: 0.25rem !important;\n  }\n\n  .ps-xxl-2 {\n    padding-right: 0.5rem !important;\n  }\n\n  .ps-xxl-3 {\n    padding-right: 1rem !important;\n  }\n\n  .ps-xxl-4 {\n    padding-right: 1.5rem !important;\n  }\n\n  .ps-xxl-5 {\n    padding-right: 3rem !important;\n  }\n\n  .text-xxl-start {\n    text-align: right !important;\n  }\n\n  .text-xxl-end {\n    text-align: left !important;\n  }\n\n  .text-xxl-center {\n    text-align: center !important;\n  }\n}\n@media (min-width: 1200px) {\n  .fs-1 {\n    font-size: 2.5rem !important;\n  }\n\n  .fs-2 {\n    font-size: 2rem !important;\n  }\n\n  .fs-3 {\n    font-size: 1.75rem !important;\n  }\n\n  .fs-4 {\n    font-size: 1.5rem !important;\n  }\n}\n@media print {\n  .d-print-inline {\n    display: inline !important;\n  }\n\n  .d-print-inline-block {\n    display: inline-block !important;\n  }\n\n  .d-print-block {\n    display: block !important;\n  }\n\n  .d-print-grid {\n    display: grid !important;\n  }\n\n  .d-print-table {\n    display: table !important;\n  }\n\n  .d-print-table-row {\n    display: table-row !important;\n  }\n\n  .d-print-table-cell {\n    display: table-cell !important;\n  }\n\n  .d-print-flex {\n    display: flex !important;\n  }\n\n  .d-print-inline-flex {\n    display: inline-flex !important;\n  }\n\n  .d-print-none {\n    display: none !important;\n  }\n}\n/*# sourceMappingURL=bootstrap-utilities.rtl.css.map */"
  },
  {
    "path": "sample/src/NimblePros.SampleToDo.Web/wwwroot/lib/bootstrap/dist/css/bootstrap.css",
    "content": "@charset \"UTF-8\";\n/*!\n * Bootstrap v5.1.0 (https://getbootstrap.com/)\n * Copyright 2011-2021 The Bootstrap Authors\n * Copyright 2011-2021 Twitter, Inc.\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n */\n:root {\n  --bs-blue: #0d6efd;\n  --bs-indigo: #6610f2;\n  --bs-purple: #6f42c1;\n  --bs-pink: #d63384;\n  --bs-red: #dc3545;\n  --bs-orange: #fd7e14;\n  --bs-yellow: #ffc107;\n  --bs-green: #198754;\n  --bs-teal: #20c997;\n  --bs-cyan: #0dcaf0;\n  --bs-white: #fff;\n  --bs-gray: #6c757d;\n  --bs-gray-dark: #343a40;\n  --bs-gray-100: #f8f9fa;\n  --bs-gray-200: #e9ecef;\n  --bs-gray-300: #dee2e6;\n  --bs-gray-400: #ced4da;\n  --bs-gray-500: #adb5bd;\n  --bs-gray-600: #6c757d;\n  --bs-gray-700: #495057;\n  --bs-gray-800: #343a40;\n  --bs-gray-900: #212529;\n  --bs-primary: #0d6efd;\n  --bs-secondary: #6c757d;\n  --bs-success: #198754;\n  --bs-info: #0dcaf0;\n  --bs-warning: #ffc107;\n  --bs-danger: #dc3545;\n  --bs-light: #f8f9fa;\n  --bs-dark: #212529;\n  --bs-primary-rgb: 13, 110, 253;\n  --bs-secondary-rgb: 108, 117, 125;\n  --bs-success-rgb: 25, 135, 84;\n  --bs-info-rgb: 13, 202, 240;\n  --bs-warning-rgb: 255, 193, 7;\n  --bs-danger-rgb: 220, 53, 69;\n  --bs-light-rgb: 248, 249, 250;\n  --bs-dark-rgb: 33, 37, 41;\n  --bs-white-rgb: 255, 255, 255;\n  --bs-black-rgb: 0, 0, 0;\n  --bs-body-rgb: 33, 37, 41;\n  --bs-font-sans-serif: system-ui, -apple-system, \"Segoe UI\", Roboto, \"Helvetica Neue\", Arial, \"Noto Sans\", \"Liberation Sans\", sans-serif, \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\", \"Noto Color Emoji\";\n  --bs-font-monospace: SFMono-Regular, Menlo, Monaco, Consolas, \"Liberation Mono\", \"Courier New\", monospace;\n  --bs-gradient: linear-gradient(180deg, rgba(255, 255, 255, 0.15), rgba(255, 255, 255, 0));\n  --bs-body-font-family: var(--bs-font-sans-serif);\n  --bs-body-font-size: 1rem;\n  --bs-body-font-weight: 400;\n  --bs-body-line-height: 1.5;\n  --bs-body-color: #212529;\n  --bs-body-bg: #fff;\n}\n\n*,\n*::before,\n*::after {\n  box-sizing: border-box;\n}\n\n@media (prefers-reduced-motion: no-preference) {\n  :root {\n    scroll-behavior: smooth;\n  }\n}\n\nbody {\n  margin: 0;\n  font-family: var(--bs-body-font-family);\n  font-size: var(--bs-body-font-size);\n  font-weight: var(--bs-body-font-weight);\n  line-height: var(--bs-body-line-height);\n  color: var(--bs-body-color);\n  text-align: var(--bs-body-text-align);\n  background-color: var(--bs-body-bg);\n  -webkit-text-size-adjust: 100%;\n  -webkit-tap-highlight-color: rgba(0, 0, 0, 0);\n}\n\nhr {\n  margin: 1rem 0;\n  color: inherit;\n  background-color: currentColor;\n  border: 0;\n  opacity: 0.25;\n}\n\nhr:not([size]) {\n  height: 1px;\n}\n\nh6, .h6, h5, .h5, h4, .h4, h3, .h3, h2, .h2, h1, .h1 {\n  margin-top: 0;\n  margin-bottom: 0.5rem;\n  font-weight: 500;\n  line-height: 1.2;\n}\n\nh1, .h1 {\n  font-size: calc(1.375rem + 1.5vw);\n}\n@media (min-width: 1200px) {\n  h1, .h1 {\n    font-size: 2.5rem;\n  }\n}\n\nh2, .h2 {\n  font-size: calc(1.325rem + 0.9vw);\n}\n@media (min-width: 1200px) {\n  h2, .h2 {\n    font-size: 2rem;\n  }\n}\n\nh3, .h3 {\n  font-size: calc(1.3rem + 0.6vw);\n}\n@media (min-width: 1200px) {\n  h3, .h3 {\n    font-size: 1.75rem;\n  }\n}\n\nh4, .h4 {\n  font-size: calc(1.275rem + 0.3vw);\n}\n@media (min-width: 1200px) {\n  h4, .h4 {\n    font-size: 1.5rem;\n  }\n}\n\nh5, .h5 {\n  font-size: 1.25rem;\n}\n\nh6, .h6 {\n  font-size: 1rem;\n}\n\np {\n  margin-top: 0;\n  margin-bottom: 1rem;\n}\n\nabbr[title],\nabbr[data-bs-original-title] {\n  -webkit-text-decoration: underline dotted;\n  text-decoration: underline dotted;\n  cursor: help;\n  -webkit-text-decoration-skip-ink: none;\n  text-decoration-skip-ink: none;\n}\n\naddress {\n  margin-bottom: 1rem;\n  font-style: normal;\n  line-height: inherit;\n}\n\nol,\nul {\n  padding-left: 2rem;\n}\n\nol,\nul,\ndl {\n  margin-top: 0;\n  margin-bottom: 1rem;\n}\n\nol ol,\nul ul,\nol ul,\nul ol {\n  margin-bottom: 0;\n}\n\ndt {\n  font-weight: 700;\n}\n\ndd {\n  margin-bottom: 0.5rem;\n  margin-left: 0;\n}\n\nblockquote {\n  margin: 0 0 1rem;\n}\n\nb,\nstrong {\n  font-weight: bolder;\n}\n\nsmall, .small {\n  font-size: 0.875em;\n}\n\nmark, .mark {\n  padding: 0.2em;\n  background-color: #fcf8e3;\n}\n\nsub,\nsup {\n  position: relative;\n  font-size: 0.75em;\n  line-height: 0;\n  vertical-align: baseline;\n}\n\nsub {\n  bottom: -0.25em;\n}\n\nsup {\n  top: -0.5em;\n}\n\na {\n  color: #0d6efd;\n  text-decoration: underline;\n}\na:hover {\n  color: #0a58ca;\n}\n\na:not([href]):not([class]), a:not([href]):not([class]):hover {\n  color: inherit;\n  text-decoration: none;\n}\n\npre,\ncode,\nkbd,\nsamp {\n  font-family: var(--bs-font-monospace);\n  font-size: 1em;\n  direction: ltr /* rtl:ignore */;\n  unicode-bidi: bidi-override;\n}\n\npre {\n  display: block;\n  margin-top: 0;\n  margin-bottom: 1rem;\n  overflow: auto;\n  font-size: 0.875em;\n}\npre code {\n  font-size: inherit;\n  color: inherit;\n  word-break: normal;\n}\n\ncode {\n  font-size: 0.875em;\n  color: #d63384;\n  word-wrap: break-word;\n}\na > code {\n  color: inherit;\n}\n\nkbd {\n  padding: 0.2rem 0.4rem;\n  font-size: 0.875em;\n  color: #fff;\n  background-color: #212529;\n  border-radius: 0.2rem;\n}\nkbd kbd {\n  padding: 0;\n  font-size: 1em;\n  font-weight: 700;\n}\n\nfigure {\n  margin: 0 0 1rem;\n}\n\nimg,\nsvg {\n  vertical-align: middle;\n}\n\ntable {\n  caption-side: bottom;\n  border-collapse: collapse;\n}\n\ncaption {\n  padding-top: 0.5rem;\n  padding-bottom: 0.5rem;\n  color: #6c757d;\n  text-align: left;\n}\n\nth {\n  text-align: inherit;\n  text-align: -webkit-match-parent;\n}\n\nthead,\ntbody,\ntfoot,\ntr,\ntd,\nth {\n  border-color: inherit;\n  border-style: solid;\n  border-width: 0;\n}\n\nlabel {\n  display: inline-block;\n}\n\nbutton {\n  border-radius: 0;\n}\n\nbutton:focus:not(:focus-visible) {\n  outline: 0;\n}\n\ninput,\nbutton,\nselect,\noptgroup,\ntextarea {\n  margin: 0;\n  font-family: inherit;\n  font-size: inherit;\n  line-height: inherit;\n}\n\nbutton,\nselect {\n  text-transform: none;\n}\n\n[role=button] {\n  cursor: pointer;\n}\n\nselect {\n  word-wrap: normal;\n}\nselect:disabled {\n  opacity: 1;\n}\n\n[list]::-webkit-calendar-picker-indicator {\n  display: none;\n}\n\nbutton,\n[type=button],\n[type=reset],\n[type=submit] {\n  -webkit-appearance: button;\n}\nbutton:not(:disabled),\n[type=button]:not(:disabled),\n[type=reset]:not(:disabled),\n[type=submit]:not(:disabled) {\n  cursor: pointer;\n}\n\n::-moz-focus-inner {\n  padding: 0;\n  border-style: none;\n}\n\ntextarea {\n  resize: vertical;\n}\n\nfieldset {\n  min-width: 0;\n  padding: 0;\n  margin: 0;\n  border: 0;\n}\n\nlegend {\n  float: left;\n  width: 100%;\n  padding: 0;\n  margin-bottom: 0.5rem;\n  font-size: calc(1.275rem + 0.3vw);\n  line-height: inherit;\n}\n@media (min-width: 1200px) {\n  legend {\n    font-size: 1.5rem;\n  }\n}\nlegend + * {\n  clear: left;\n}\n\n::-webkit-datetime-edit-fields-wrapper,\n::-webkit-datetime-edit-text,\n::-webkit-datetime-edit-minute,\n::-webkit-datetime-edit-hour-field,\n::-webkit-datetime-edit-day-field,\n::-webkit-datetime-edit-month-field,\n::-webkit-datetime-edit-year-field {\n  padding: 0;\n}\n\n::-webkit-inner-spin-button {\n  height: auto;\n}\n\n[type=search] {\n  outline-offset: -2px;\n  -webkit-appearance: textfield;\n}\n\n/* rtl:raw:\n[type=\"tel\"],\n[type=\"url\"],\n[type=\"email\"],\n[type=\"number\"] {\n  direction: ltr;\n}\n*/\n::-webkit-search-decoration {\n  -webkit-appearance: none;\n}\n\n::-webkit-color-swatch-wrapper {\n  padding: 0;\n}\n\n::file-selector-button {\n  font: inherit;\n}\n\n::-webkit-file-upload-button {\n  font: inherit;\n  -webkit-appearance: button;\n}\n\noutput {\n  display: inline-block;\n}\n\niframe {\n  border: 0;\n}\n\nsummary {\n  display: list-item;\n  cursor: pointer;\n}\n\nprogress {\n  vertical-align: baseline;\n}\n\n[hidden] {\n  display: none !important;\n}\n\n.lead {\n  font-size: 1.25rem;\n  font-weight: 300;\n}\n\n.display-1 {\n  font-size: calc(1.625rem + 4.5vw);\n  font-weight: 300;\n  line-height: 1.2;\n}\n@media (min-width: 1200px) {\n  .display-1 {\n    font-size: 5rem;\n  }\n}\n\n.display-2 {\n  font-size: calc(1.575rem + 3.9vw);\n  font-weight: 300;\n  line-height: 1.2;\n}\n@media (min-width: 1200px) {\n  .display-2 {\n    font-size: 4.5rem;\n  }\n}\n\n.display-3 {\n  font-size: calc(1.525rem + 3.3vw);\n  font-weight: 300;\n  line-height: 1.2;\n}\n@media (min-width: 1200px) {\n  .display-3 {\n    font-size: 4rem;\n  }\n}\n\n.display-4 {\n  font-size: calc(1.475rem + 2.7vw);\n  font-weight: 300;\n  line-height: 1.2;\n}\n@media (min-width: 1200px) {\n  .display-4 {\n    font-size: 3.5rem;\n  }\n}\n\n.display-5 {\n  font-size: calc(1.425rem + 2.1vw);\n  font-weight: 300;\n  line-height: 1.2;\n}\n@media (min-width: 1200px) {\n  .display-5 {\n    font-size: 3rem;\n  }\n}\n\n.display-6 {\n  font-size: calc(1.375rem + 1.5vw);\n  font-weight: 300;\n  line-height: 1.2;\n}\n@media (min-width: 1200px) {\n  .display-6 {\n    font-size: 2.5rem;\n  }\n}\n\n.list-unstyled {\n  padding-left: 0;\n  list-style: none;\n}\n\n.list-inline {\n  padding-left: 0;\n  list-style: none;\n}\n\n.list-inline-item {\n  display: inline-block;\n}\n.list-inline-item:not(:last-child) {\n  margin-right: 0.5rem;\n}\n\n.initialism {\n  font-size: 0.875em;\n  text-transform: uppercase;\n}\n\n.blockquote {\n  margin-bottom: 1rem;\n  font-size: 1.25rem;\n}\n.blockquote > :last-child {\n  margin-bottom: 0;\n}\n\n.blockquote-footer {\n  margin-top: -1rem;\n  margin-bottom: 1rem;\n  font-size: 0.875em;\n  color: #6c757d;\n}\n.blockquote-footer::before {\n  content: \"— \";\n}\n\n.img-fluid {\n  max-width: 100%;\n  height: auto;\n}\n\n.img-thumbnail {\n  padding: 0.25rem;\n  background-color: #fff;\n  border: 1px solid #dee2e6;\n  border-radius: 0.25rem;\n  max-width: 100%;\n  height: auto;\n}\n\n.figure {\n  display: inline-block;\n}\n\n.figure-img {\n  margin-bottom: 0.5rem;\n  line-height: 1;\n}\n\n.figure-caption {\n  font-size: 0.875em;\n  color: #6c757d;\n}\n\n.container,\n.container-fluid,\n.container-xxl,\n.container-xl,\n.container-lg,\n.container-md,\n.container-sm {\n  width: 100%;\n  padding-right: var(--bs-gutter-x, 0.75rem);\n  padding-left: var(--bs-gutter-x, 0.75rem);\n  margin-right: auto;\n  margin-left: auto;\n}\n\n@media (min-width: 576px) {\n  .container-sm, .container {\n    max-width: 540px;\n  }\n}\n@media (min-width: 768px) {\n  .container-md, .container-sm, .container {\n    max-width: 720px;\n  }\n}\n@media (min-width: 992px) {\n  .container-lg, .container-md, .container-sm, .container {\n    max-width: 960px;\n  }\n}\n@media (min-width: 1200px) {\n  .container-xl, .container-lg, .container-md, .container-sm, .container {\n    max-width: 1140px;\n  }\n}\n@media (min-width: 1400px) {\n  .container-xxl, .container-xl, .container-lg, .container-md, .container-sm, .container {\n    max-width: 1320px;\n  }\n}\n.row {\n  --bs-gutter-x: 1.5rem;\n  --bs-gutter-y: 0;\n  display: flex;\n  flex-wrap: wrap;\n  margin-top: calc(var(--bs-gutter-y) * -1);\n  margin-right: calc(var(--bs-gutter-x) * -.5);\n  margin-left: calc(var(--bs-gutter-x) * -.5);\n}\n.row > * {\n  flex-shrink: 0;\n  width: 100%;\n  max-width: 100%;\n  padding-right: calc(var(--bs-gutter-x) * .5);\n  padding-left: calc(var(--bs-gutter-x) * .5);\n  margin-top: var(--bs-gutter-y);\n}\n\n.col {\n  flex: 1 0 0%;\n}\n\n.row-cols-auto > * {\n  flex: 0 0 auto;\n  width: auto;\n}\n\n.row-cols-1 > * {\n  flex: 0 0 auto;\n  width: 100%;\n}\n\n.row-cols-2 > * {\n  flex: 0 0 auto;\n  width: 50%;\n}\n\n.row-cols-3 > * {\n  flex: 0 0 auto;\n  width: 33.3333333333%;\n}\n\n.row-cols-4 > * {\n  flex: 0 0 auto;\n  width: 25%;\n}\n\n.row-cols-5 > * {\n  flex: 0 0 auto;\n  width: 20%;\n}\n\n.row-cols-6 > * {\n  flex: 0 0 auto;\n  width: 16.6666666667%;\n}\n\n.col-auto {\n  flex: 0 0 auto;\n  width: auto;\n}\n\n.col-1 {\n  flex: 0 0 auto;\n  width: 8.33333333%;\n}\n\n.col-2 {\n  flex: 0 0 auto;\n  width: 16.66666667%;\n}\n\n.col-3 {\n  flex: 0 0 auto;\n  width: 25%;\n}\n\n.col-4 {\n  flex: 0 0 auto;\n  width: 33.33333333%;\n}\n\n.col-5 {\n  flex: 0 0 auto;\n  width: 41.66666667%;\n}\n\n.col-6 {\n  flex: 0 0 auto;\n  width: 50%;\n}\n\n.col-7 {\n  flex: 0 0 auto;\n  width: 58.33333333%;\n}\n\n.col-8 {\n  flex: 0 0 auto;\n  width: 66.66666667%;\n}\n\n.col-9 {\n  flex: 0 0 auto;\n  width: 75%;\n}\n\n.col-10 {\n  flex: 0 0 auto;\n  width: 83.33333333%;\n}\n\n.col-11 {\n  flex: 0 0 auto;\n  width: 91.66666667%;\n}\n\n.col-12 {\n  flex: 0 0 auto;\n  width: 100%;\n}\n\n.offset-1 {\n  margin-left: 8.33333333%;\n}\n\n.offset-2 {\n  margin-left: 16.66666667%;\n}\n\n.offset-3 {\n  margin-left: 25%;\n}\n\n.offset-4 {\n  margin-left: 33.33333333%;\n}\n\n.offset-5 {\n  margin-left: 41.66666667%;\n}\n\n.offset-6 {\n  margin-left: 50%;\n}\n\n.offset-7 {\n  margin-left: 58.33333333%;\n}\n\n.offset-8 {\n  margin-left: 66.66666667%;\n}\n\n.offset-9 {\n  margin-left: 75%;\n}\n\n.offset-10 {\n  margin-left: 83.33333333%;\n}\n\n.offset-11 {\n  margin-left: 91.66666667%;\n}\n\n.g-0,\n.gx-0 {\n  --bs-gutter-x: 0;\n}\n\n.g-0,\n.gy-0 {\n  --bs-gutter-y: 0;\n}\n\n.g-1,\n.gx-1 {\n  --bs-gutter-x: 0.25rem;\n}\n\n.g-1,\n.gy-1 {\n  --bs-gutter-y: 0.25rem;\n}\n\n.g-2,\n.gx-2 {\n  --bs-gutter-x: 0.5rem;\n}\n\n.g-2,\n.gy-2 {\n  --bs-gutter-y: 0.5rem;\n}\n\n.g-3,\n.gx-3 {\n  --bs-gutter-x: 1rem;\n}\n\n.g-3,\n.gy-3 {\n  --bs-gutter-y: 1rem;\n}\n\n.g-4,\n.gx-4 {\n  --bs-gutter-x: 1.5rem;\n}\n\n.g-4,\n.gy-4 {\n  --bs-gutter-y: 1.5rem;\n}\n\n.g-5,\n.gx-5 {\n  --bs-gutter-x: 3rem;\n}\n\n.g-5,\n.gy-5 {\n  --bs-gutter-y: 3rem;\n}\n\n@media (min-width: 576px) {\n  .col-sm {\n    flex: 1 0 0%;\n  }\n\n  .row-cols-sm-auto > * {\n    flex: 0 0 auto;\n    width: auto;\n  }\n\n  .row-cols-sm-1 > * {\n    flex: 0 0 auto;\n    width: 100%;\n  }\n\n  .row-cols-sm-2 > * {\n    flex: 0 0 auto;\n    width: 50%;\n  }\n\n  .row-cols-sm-3 > * {\n    flex: 0 0 auto;\n    width: 33.3333333333%;\n  }\n\n  .row-cols-sm-4 > * {\n    flex: 0 0 auto;\n    width: 25%;\n  }\n\n  .row-cols-sm-5 > * {\n    flex: 0 0 auto;\n    width: 20%;\n  }\n\n  .row-cols-sm-6 > * {\n    flex: 0 0 auto;\n    width: 16.6666666667%;\n  }\n\n  .col-sm-auto {\n    flex: 0 0 auto;\n    width: auto;\n  }\n\n  .col-sm-1 {\n    flex: 0 0 auto;\n    width: 8.33333333%;\n  }\n\n  .col-sm-2 {\n    flex: 0 0 auto;\n    width: 16.66666667%;\n  }\n\n  .col-sm-3 {\n    flex: 0 0 auto;\n    width: 25%;\n  }\n\n  .col-sm-4 {\n    flex: 0 0 auto;\n    width: 33.33333333%;\n  }\n\n  .col-sm-5 {\n    flex: 0 0 auto;\n    width: 41.66666667%;\n  }\n\n  .col-sm-6 {\n    flex: 0 0 auto;\n    width: 50%;\n  }\n\n  .col-sm-7 {\n    flex: 0 0 auto;\n    width: 58.33333333%;\n  }\n\n  .col-sm-8 {\n    flex: 0 0 auto;\n    width: 66.66666667%;\n  }\n\n  .col-sm-9 {\n    flex: 0 0 auto;\n    width: 75%;\n  }\n\n  .col-sm-10 {\n    flex: 0 0 auto;\n    width: 83.33333333%;\n  }\n\n  .col-sm-11 {\n    flex: 0 0 auto;\n    width: 91.66666667%;\n  }\n\n  .col-sm-12 {\n    flex: 0 0 auto;\n    width: 100%;\n  }\n\n  .offset-sm-0 {\n    margin-left: 0;\n  }\n\n  .offset-sm-1 {\n    margin-left: 8.33333333%;\n  }\n\n  .offset-sm-2 {\n    margin-left: 16.66666667%;\n  }\n\n  .offset-sm-3 {\n    margin-left: 25%;\n  }\n\n  .offset-sm-4 {\n    margin-left: 33.33333333%;\n  }\n\n  .offset-sm-5 {\n    margin-left: 41.66666667%;\n  }\n\n  .offset-sm-6 {\n    margin-left: 50%;\n  }\n\n  .offset-sm-7 {\n    margin-left: 58.33333333%;\n  }\n\n  .offset-sm-8 {\n    margin-left: 66.66666667%;\n  }\n\n  .offset-sm-9 {\n    margin-left: 75%;\n  }\n\n  .offset-sm-10 {\n    margin-left: 83.33333333%;\n  }\n\n  .offset-sm-11 {\n    margin-left: 91.66666667%;\n  }\n\n  .g-sm-0,\n.gx-sm-0 {\n    --bs-gutter-x: 0;\n  }\n\n  .g-sm-0,\n.gy-sm-0 {\n    --bs-gutter-y: 0;\n  }\n\n  .g-sm-1,\n.gx-sm-1 {\n    --bs-gutter-x: 0.25rem;\n  }\n\n  .g-sm-1,\n.gy-sm-1 {\n    --bs-gutter-y: 0.25rem;\n  }\n\n  .g-sm-2,\n.gx-sm-2 {\n    --bs-gutter-x: 0.5rem;\n  }\n\n  .g-sm-2,\n.gy-sm-2 {\n    --bs-gutter-y: 0.5rem;\n  }\n\n  .g-sm-3,\n.gx-sm-3 {\n    --bs-gutter-x: 1rem;\n  }\n\n  .g-sm-3,\n.gy-sm-3 {\n    --bs-gutter-y: 1rem;\n  }\n\n  .g-sm-4,\n.gx-sm-4 {\n    --bs-gutter-x: 1.5rem;\n  }\n\n  .g-sm-4,\n.gy-sm-4 {\n    --bs-gutter-y: 1.5rem;\n  }\n\n  .g-sm-5,\n.gx-sm-5 {\n    --bs-gutter-x: 3rem;\n  }\n\n  .g-sm-5,\n.gy-sm-5 {\n    --bs-gutter-y: 3rem;\n  }\n}\n@media (min-width: 768px) {\n  .col-md {\n    flex: 1 0 0%;\n  }\n\n  .row-cols-md-auto > * {\n    flex: 0 0 auto;\n    width: auto;\n  }\n\n  .row-cols-md-1 > * {\n    flex: 0 0 auto;\n    width: 100%;\n  }\n\n  .row-cols-md-2 > * {\n    flex: 0 0 auto;\n    width: 50%;\n  }\n\n  .row-cols-md-3 > * {\n    flex: 0 0 auto;\n    width: 33.3333333333%;\n  }\n\n  .row-cols-md-4 > * {\n    flex: 0 0 auto;\n    width: 25%;\n  }\n\n  .row-cols-md-5 > * {\n    flex: 0 0 auto;\n    width: 20%;\n  }\n\n  .row-cols-md-6 > * {\n    flex: 0 0 auto;\n    width: 16.6666666667%;\n  }\n\n  .col-md-auto {\n    flex: 0 0 auto;\n    width: auto;\n  }\n\n  .col-md-1 {\n    flex: 0 0 auto;\n    width: 8.33333333%;\n  }\n\n  .col-md-2 {\n    flex: 0 0 auto;\n    width: 16.66666667%;\n  }\n\n  .col-md-3 {\n    flex: 0 0 auto;\n    width: 25%;\n  }\n\n  .col-md-4 {\n    flex: 0 0 auto;\n    width: 33.33333333%;\n  }\n\n  .col-md-5 {\n    flex: 0 0 auto;\n    width: 41.66666667%;\n  }\n\n  .col-md-6 {\n    flex: 0 0 auto;\n    width: 50%;\n  }\n\n  .col-md-7 {\n    flex: 0 0 auto;\n    width: 58.33333333%;\n  }\n\n  .col-md-8 {\n    flex: 0 0 auto;\n    width: 66.66666667%;\n  }\n\n  .col-md-9 {\n    flex: 0 0 auto;\n    width: 75%;\n  }\n\n  .col-md-10 {\n    flex: 0 0 auto;\n    width: 83.33333333%;\n  }\n\n  .col-md-11 {\n    flex: 0 0 auto;\n    width: 91.66666667%;\n  }\n\n  .col-md-12 {\n    flex: 0 0 auto;\n    width: 100%;\n  }\n\n  .offset-md-0 {\n    margin-left: 0;\n  }\n\n  .offset-md-1 {\n    margin-left: 8.33333333%;\n  }\n\n  .offset-md-2 {\n    margin-left: 16.66666667%;\n  }\n\n  .offset-md-3 {\n    margin-left: 25%;\n  }\n\n  .offset-md-4 {\n    margin-left: 33.33333333%;\n  }\n\n  .offset-md-5 {\n    margin-left: 41.66666667%;\n  }\n\n  .offset-md-6 {\n    margin-left: 50%;\n  }\n\n  .offset-md-7 {\n    margin-left: 58.33333333%;\n  }\n\n  .offset-md-8 {\n    margin-left: 66.66666667%;\n  }\n\n  .offset-md-9 {\n    margin-left: 75%;\n  }\n\n  .offset-md-10 {\n    margin-left: 83.33333333%;\n  }\n\n  .offset-md-11 {\n    margin-left: 91.66666667%;\n  }\n\n  .g-md-0,\n.gx-md-0 {\n    --bs-gutter-x: 0;\n  }\n\n  .g-md-0,\n.gy-md-0 {\n    --bs-gutter-y: 0;\n  }\n\n  .g-md-1,\n.gx-md-1 {\n    --bs-gutter-x: 0.25rem;\n  }\n\n  .g-md-1,\n.gy-md-1 {\n    --bs-gutter-y: 0.25rem;\n  }\n\n  .g-md-2,\n.gx-md-2 {\n    --bs-gutter-x: 0.5rem;\n  }\n\n  .g-md-2,\n.gy-md-2 {\n    --bs-gutter-y: 0.5rem;\n  }\n\n  .g-md-3,\n.gx-md-3 {\n    --bs-gutter-x: 1rem;\n  }\n\n  .g-md-3,\n.gy-md-3 {\n    --bs-gutter-y: 1rem;\n  }\n\n  .g-md-4,\n.gx-md-4 {\n    --bs-gutter-x: 1.5rem;\n  }\n\n  .g-md-4,\n.gy-md-4 {\n    --bs-gutter-y: 1.5rem;\n  }\n\n  .g-md-5,\n.gx-md-5 {\n    --bs-gutter-x: 3rem;\n  }\n\n  .g-md-5,\n.gy-md-5 {\n    --bs-gutter-y: 3rem;\n  }\n}\n@media (min-width: 992px) {\n  .col-lg {\n    flex: 1 0 0%;\n  }\n\n  .row-cols-lg-auto > * {\n    flex: 0 0 auto;\n    width: auto;\n  }\n\n  .row-cols-lg-1 > * {\n    flex: 0 0 auto;\n    width: 100%;\n  }\n\n  .row-cols-lg-2 > * {\n    flex: 0 0 auto;\n    width: 50%;\n  }\n\n  .row-cols-lg-3 > * {\n    flex: 0 0 auto;\n    width: 33.3333333333%;\n  }\n\n  .row-cols-lg-4 > * {\n    flex: 0 0 auto;\n    width: 25%;\n  }\n\n  .row-cols-lg-5 > * {\n    flex: 0 0 auto;\n    width: 20%;\n  }\n\n  .row-cols-lg-6 > * {\n    flex: 0 0 auto;\n    width: 16.6666666667%;\n  }\n\n  .col-lg-auto {\n    flex: 0 0 auto;\n    width: auto;\n  }\n\n  .col-lg-1 {\n    flex: 0 0 auto;\n    width: 8.33333333%;\n  }\n\n  .col-lg-2 {\n    flex: 0 0 auto;\n    width: 16.66666667%;\n  }\n\n  .col-lg-3 {\n    flex: 0 0 auto;\n    width: 25%;\n  }\n\n  .col-lg-4 {\n    flex: 0 0 auto;\n    width: 33.33333333%;\n  }\n\n  .col-lg-5 {\n    flex: 0 0 auto;\n    width: 41.66666667%;\n  }\n\n  .col-lg-6 {\n    flex: 0 0 auto;\n    width: 50%;\n  }\n\n  .col-lg-7 {\n    flex: 0 0 auto;\n    width: 58.33333333%;\n  }\n\n  .col-lg-8 {\n    flex: 0 0 auto;\n    width: 66.66666667%;\n  }\n\n  .col-lg-9 {\n    flex: 0 0 auto;\n    width: 75%;\n  }\n\n  .col-lg-10 {\n    flex: 0 0 auto;\n    width: 83.33333333%;\n  }\n\n  .col-lg-11 {\n    flex: 0 0 auto;\n    width: 91.66666667%;\n  }\n\n  .col-lg-12 {\n    flex: 0 0 auto;\n    width: 100%;\n  }\n\n  .offset-lg-0 {\n    margin-left: 0;\n  }\n\n  .offset-lg-1 {\n    margin-left: 8.33333333%;\n  }\n\n  .offset-lg-2 {\n    margin-left: 16.66666667%;\n  }\n\n  .offset-lg-3 {\n    margin-left: 25%;\n  }\n\n  .offset-lg-4 {\n    margin-left: 33.33333333%;\n  }\n\n  .offset-lg-5 {\n    margin-left: 41.66666667%;\n  }\n\n  .offset-lg-6 {\n    margin-left: 50%;\n  }\n\n  .offset-lg-7 {\n    margin-left: 58.33333333%;\n  }\n\n  .offset-lg-8 {\n    margin-left: 66.66666667%;\n  }\n\n  .offset-lg-9 {\n    margin-left: 75%;\n  }\n\n  .offset-lg-10 {\n    margin-left: 83.33333333%;\n  }\n\n  .offset-lg-11 {\n    margin-left: 91.66666667%;\n  }\n\n  .g-lg-0,\n.gx-lg-0 {\n    --bs-gutter-x: 0;\n  }\n\n  .g-lg-0,\n.gy-lg-0 {\n    --bs-gutter-y: 0;\n  }\n\n  .g-lg-1,\n.gx-lg-1 {\n    --bs-gutter-x: 0.25rem;\n  }\n\n  .g-lg-1,\n.gy-lg-1 {\n    --bs-gutter-y: 0.25rem;\n  }\n\n  .g-lg-2,\n.gx-lg-2 {\n    --bs-gutter-x: 0.5rem;\n  }\n\n  .g-lg-2,\n.gy-lg-2 {\n    --bs-gutter-y: 0.5rem;\n  }\n\n  .g-lg-3,\n.gx-lg-3 {\n    --bs-gutter-x: 1rem;\n  }\n\n  .g-lg-3,\n.gy-lg-3 {\n    --bs-gutter-y: 1rem;\n  }\n\n  .g-lg-4,\n.gx-lg-4 {\n    --bs-gutter-x: 1.5rem;\n  }\n\n  .g-lg-4,\n.gy-lg-4 {\n    --bs-gutter-y: 1.5rem;\n  }\n\n  .g-lg-5,\n.gx-lg-5 {\n    --bs-gutter-x: 3rem;\n  }\n\n  .g-lg-5,\n.gy-lg-5 {\n    --bs-gutter-y: 3rem;\n  }\n}\n@media (min-width: 1200px) {\n  .col-xl {\n    flex: 1 0 0%;\n  }\n\n  .row-cols-xl-auto > * {\n    flex: 0 0 auto;\n    width: auto;\n  }\n\n  .row-cols-xl-1 > * {\n    flex: 0 0 auto;\n    width: 100%;\n  }\n\n  .row-cols-xl-2 > * {\n    flex: 0 0 auto;\n    width: 50%;\n  }\n\n  .row-cols-xl-3 > * {\n    flex: 0 0 auto;\n    width: 33.3333333333%;\n  }\n\n  .row-cols-xl-4 > * {\n    flex: 0 0 auto;\n    width: 25%;\n  }\n\n  .row-cols-xl-5 > * {\n    flex: 0 0 auto;\n    width: 20%;\n  }\n\n  .row-cols-xl-6 > * {\n    flex: 0 0 auto;\n    width: 16.6666666667%;\n  }\n\n  .col-xl-auto {\n    flex: 0 0 auto;\n    width: auto;\n  }\n\n  .col-xl-1 {\n    flex: 0 0 auto;\n    width: 8.33333333%;\n  }\n\n  .col-xl-2 {\n    flex: 0 0 auto;\n    width: 16.66666667%;\n  }\n\n  .col-xl-3 {\n    flex: 0 0 auto;\n    width: 25%;\n  }\n\n  .col-xl-4 {\n    flex: 0 0 auto;\n    width: 33.33333333%;\n  }\n\n  .col-xl-5 {\n    flex: 0 0 auto;\n    width: 41.66666667%;\n  }\n\n  .col-xl-6 {\n    flex: 0 0 auto;\n    width: 50%;\n  }\n\n  .col-xl-7 {\n    flex: 0 0 auto;\n    width: 58.33333333%;\n  }\n\n  .col-xl-8 {\n    flex: 0 0 auto;\n    width: 66.66666667%;\n  }\n\n  .col-xl-9 {\n    flex: 0 0 auto;\n    width: 75%;\n  }\n\n  .col-xl-10 {\n    flex: 0 0 auto;\n    width: 83.33333333%;\n  }\n\n  .col-xl-11 {\n    flex: 0 0 auto;\n    width: 91.66666667%;\n  }\n\n  .col-xl-12 {\n    flex: 0 0 auto;\n    width: 100%;\n  }\n\n  .offset-xl-0 {\n    margin-left: 0;\n  }\n\n  .offset-xl-1 {\n    margin-left: 8.33333333%;\n  }\n\n  .offset-xl-2 {\n    margin-left: 16.66666667%;\n  }\n\n  .offset-xl-3 {\n    margin-left: 25%;\n  }\n\n  .offset-xl-4 {\n    margin-left: 33.33333333%;\n  }\n\n  .offset-xl-5 {\n    margin-left: 41.66666667%;\n  }\n\n  .offset-xl-6 {\n    margin-left: 50%;\n  }\n\n  .offset-xl-7 {\n    margin-left: 58.33333333%;\n  }\n\n  .offset-xl-8 {\n    margin-left: 66.66666667%;\n  }\n\n  .offset-xl-9 {\n    margin-left: 75%;\n  }\n\n  .offset-xl-10 {\n    margin-left: 83.33333333%;\n  }\n\n  .offset-xl-11 {\n    margin-left: 91.66666667%;\n  }\n\n  .g-xl-0,\n.gx-xl-0 {\n    --bs-gutter-x: 0;\n  }\n\n  .g-xl-0,\n.gy-xl-0 {\n    --bs-gutter-y: 0;\n  }\n\n  .g-xl-1,\n.gx-xl-1 {\n    --bs-gutter-x: 0.25rem;\n  }\n\n  .g-xl-1,\n.gy-xl-1 {\n    --bs-gutter-y: 0.25rem;\n  }\n\n  .g-xl-2,\n.gx-xl-2 {\n    --bs-gutter-x: 0.5rem;\n  }\n\n  .g-xl-2,\n.gy-xl-2 {\n    --bs-gutter-y: 0.5rem;\n  }\n\n  .g-xl-3,\n.gx-xl-3 {\n    --bs-gutter-x: 1rem;\n  }\n\n  .g-xl-3,\n.gy-xl-3 {\n    --bs-gutter-y: 1rem;\n  }\n\n  .g-xl-4,\n.gx-xl-4 {\n    --bs-gutter-x: 1.5rem;\n  }\n\n  .g-xl-4,\n.gy-xl-4 {\n    --bs-gutter-y: 1.5rem;\n  }\n\n  .g-xl-5,\n.gx-xl-5 {\n    --bs-gutter-x: 3rem;\n  }\n\n  .g-xl-5,\n.gy-xl-5 {\n    --bs-gutter-y: 3rem;\n  }\n}\n@media (min-width: 1400px) {\n  .col-xxl {\n    flex: 1 0 0%;\n  }\n\n  .row-cols-xxl-auto > * {\n    flex: 0 0 auto;\n    width: auto;\n  }\n\n  .row-cols-xxl-1 > * {\n    flex: 0 0 auto;\n    width: 100%;\n  }\n\n  .row-cols-xxl-2 > * {\n    flex: 0 0 auto;\n    width: 50%;\n  }\n\n  .row-cols-xxl-3 > * {\n    flex: 0 0 auto;\n    width: 33.3333333333%;\n  }\n\n  .row-cols-xxl-4 > * {\n    flex: 0 0 auto;\n    width: 25%;\n  }\n\n  .row-cols-xxl-5 > * {\n    flex: 0 0 auto;\n    width: 20%;\n  }\n\n  .row-cols-xxl-6 > * {\n    flex: 0 0 auto;\n    width: 16.6666666667%;\n  }\n\n  .col-xxl-auto {\n    flex: 0 0 auto;\n    width: auto;\n  }\n\n  .col-xxl-1 {\n    flex: 0 0 auto;\n    width: 8.33333333%;\n  }\n\n  .col-xxl-2 {\n    flex: 0 0 auto;\n    width: 16.66666667%;\n  }\n\n  .col-xxl-3 {\n    flex: 0 0 auto;\n    width: 25%;\n  }\n\n  .col-xxl-4 {\n    flex: 0 0 auto;\n    width: 33.33333333%;\n  }\n\n  .col-xxl-5 {\n    flex: 0 0 auto;\n    width: 41.66666667%;\n  }\n\n  .col-xxl-6 {\n    flex: 0 0 auto;\n    width: 50%;\n  }\n\n  .col-xxl-7 {\n    flex: 0 0 auto;\n    width: 58.33333333%;\n  }\n\n  .col-xxl-8 {\n    flex: 0 0 auto;\n    width: 66.66666667%;\n  }\n\n  .col-xxl-9 {\n    flex: 0 0 auto;\n    width: 75%;\n  }\n\n  .col-xxl-10 {\n    flex: 0 0 auto;\n    width: 83.33333333%;\n  }\n\n  .col-xxl-11 {\n    flex: 0 0 auto;\n    width: 91.66666667%;\n  }\n\n  .col-xxl-12 {\n    flex: 0 0 auto;\n    width: 100%;\n  }\n\n  .offset-xxl-0 {\n    margin-left: 0;\n  }\n\n  .offset-xxl-1 {\n    margin-left: 8.33333333%;\n  }\n\n  .offset-xxl-2 {\n    margin-left: 16.66666667%;\n  }\n\n  .offset-xxl-3 {\n    margin-left: 25%;\n  }\n\n  .offset-xxl-4 {\n    margin-left: 33.33333333%;\n  }\n\n  .offset-xxl-5 {\n    margin-left: 41.66666667%;\n  }\n\n  .offset-xxl-6 {\n    margin-left: 50%;\n  }\n\n  .offset-xxl-7 {\n    margin-left: 58.33333333%;\n  }\n\n  .offset-xxl-8 {\n    margin-left: 66.66666667%;\n  }\n\n  .offset-xxl-9 {\n    margin-left: 75%;\n  }\n\n  .offset-xxl-10 {\n    margin-left: 83.33333333%;\n  }\n\n  .offset-xxl-11 {\n    margin-left: 91.66666667%;\n  }\n\n  .g-xxl-0,\n.gx-xxl-0 {\n    --bs-gutter-x: 0;\n  }\n\n  .g-xxl-0,\n.gy-xxl-0 {\n    --bs-gutter-y: 0;\n  }\n\n  .g-xxl-1,\n.gx-xxl-1 {\n    --bs-gutter-x: 0.25rem;\n  }\n\n  .g-xxl-1,\n.gy-xxl-1 {\n    --bs-gutter-y: 0.25rem;\n  }\n\n  .g-xxl-2,\n.gx-xxl-2 {\n    --bs-gutter-x: 0.5rem;\n  }\n\n  .g-xxl-2,\n.gy-xxl-2 {\n    --bs-gutter-y: 0.5rem;\n  }\n\n  .g-xxl-3,\n.gx-xxl-3 {\n    --bs-gutter-x: 1rem;\n  }\n\n  .g-xxl-3,\n.gy-xxl-3 {\n    --bs-gutter-y: 1rem;\n  }\n\n  .g-xxl-4,\n.gx-xxl-4 {\n    --bs-gutter-x: 1.5rem;\n  }\n\n  .g-xxl-4,\n.gy-xxl-4 {\n    --bs-gutter-y: 1.5rem;\n  }\n\n  .g-xxl-5,\n.gx-xxl-5 {\n    --bs-gutter-x: 3rem;\n  }\n\n  .g-xxl-5,\n.gy-xxl-5 {\n    --bs-gutter-y: 3rem;\n  }\n}\n.table {\n  --bs-table-bg: transparent;\n  --bs-table-accent-bg: transparent;\n  --bs-table-striped-color: #212529;\n  --bs-table-striped-bg: rgba(0, 0, 0, 0.05);\n  --bs-table-active-color: #212529;\n  --bs-table-active-bg: rgba(0, 0, 0, 0.1);\n  --bs-table-hover-color: #212529;\n  --bs-table-hover-bg: rgba(0, 0, 0, 0.075);\n  width: 100%;\n  margin-bottom: 1rem;\n  color: #212529;\n  vertical-align: top;\n  border-color: #dee2e6;\n}\n.table > :not(caption) > * > * {\n  padding: 0.5rem 0.5rem;\n  background-color: var(--bs-table-bg);\n  border-bottom-width: 1px;\n  box-shadow: inset 0 0 0 9999px var(--bs-table-accent-bg);\n}\n.table > tbody {\n  vertical-align: inherit;\n}\n.table > thead {\n  vertical-align: bottom;\n}\n.table > :not(:last-child) > :last-child > * {\n  border-bottom-color: currentColor;\n}\n\n.caption-top {\n  caption-side: top;\n}\n\n.table-sm > :not(caption) > * > * {\n  padding: 0.25rem 0.25rem;\n}\n\n.table-bordered > :not(caption) > * {\n  border-width: 1px 0;\n}\n.table-bordered > :not(caption) > * > * {\n  border-width: 0 1px;\n}\n\n.table-borderless > :not(caption) > * > * {\n  border-bottom-width: 0;\n}\n\n.table-striped > tbody > tr:nth-of-type(odd) {\n  --bs-table-accent-bg: var(--bs-table-striped-bg);\n  color: var(--bs-table-striped-color);\n}\n\n.table-active {\n  --bs-table-accent-bg: var(--bs-table-active-bg);\n  color: var(--bs-table-active-color);\n}\n\n.table-hover > tbody > tr:hover {\n  --bs-table-accent-bg: var(--bs-table-hover-bg);\n  color: var(--bs-table-hover-color);\n}\n\n.table-primary {\n  --bs-table-bg: #cfe2ff;\n  --bs-table-striped-bg: #c5d7f2;\n  --bs-table-striped-color: #000;\n  --bs-table-active-bg: #bacbe6;\n  --bs-table-active-color: #000;\n  --bs-table-hover-bg: #bfd1ec;\n  --bs-table-hover-color: #000;\n  color: #000;\n  border-color: #bacbe6;\n}\n\n.table-secondary {\n  --bs-table-bg: #e2e3e5;\n  --bs-table-striped-bg: #d7d8da;\n  --bs-table-striped-color: #000;\n  --bs-table-active-bg: #cbccce;\n  --bs-table-active-color: #000;\n  --bs-table-hover-bg: #d1d2d4;\n  --bs-table-hover-color: #000;\n  color: #000;\n  border-color: #cbccce;\n}\n\n.table-success {\n  --bs-table-bg: #d1e7dd;\n  --bs-table-striped-bg: #c7dbd2;\n  --bs-table-striped-color: #000;\n  --bs-table-active-bg: #bcd0c7;\n  --bs-table-active-color: #000;\n  --bs-table-hover-bg: #c1d6cc;\n  --bs-table-hover-color: #000;\n  color: #000;\n  border-color: #bcd0c7;\n}\n\n.table-info {\n  --bs-table-bg: #cff4fc;\n  --bs-table-striped-bg: #c5e8ef;\n  --bs-table-striped-color: #000;\n  --bs-table-active-bg: #badce3;\n  --bs-table-active-color: #000;\n  --bs-table-hover-bg: #bfe2e9;\n  --bs-table-hover-color: #000;\n  color: #000;\n  border-color: #badce3;\n}\n\n.table-warning {\n  --bs-table-bg: #fff3cd;\n  --bs-table-striped-bg: #f2e7c3;\n  --bs-table-striped-color: #000;\n  --bs-table-active-bg: #e6dbb9;\n  --bs-table-active-color: #000;\n  --bs-table-hover-bg: #ece1be;\n  --bs-table-hover-color: #000;\n  color: #000;\n  border-color: #e6dbb9;\n}\n\n.table-danger {\n  --bs-table-bg: #f8d7da;\n  --bs-table-striped-bg: #eccccf;\n  --bs-table-striped-color: #000;\n  --bs-table-active-bg: #dfc2c4;\n  --bs-table-active-color: #000;\n  --bs-table-hover-bg: #e5c7ca;\n  --bs-table-hover-color: #000;\n  color: #000;\n  border-color: #dfc2c4;\n}\n\n.table-light {\n  --bs-table-bg: #f8f9fa;\n  --bs-table-striped-bg: #ecedee;\n  --bs-table-striped-color: #000;\n  --bs-table-active-bg: #dfe0e1;\n  --bs-table-active-color: #000;\n  --bs-table-hover-bg: #e5e6e7;\n  --bs-table-hover-color: #000;\n  color: #000;\n  border-color: #dfe0e1;\n}\n\n.table-dark {\n  --bs-table-bg: #212529;\n  --bs-table-striped-bg: #2c3034;\n  --bs-table-striped-color: #fff;\n  --bs-table-active-bg: #373b3e;\n  --bs-table-active-color: #fff;\n  --bs-table-hover-bg: #323539;\n  --bs-table-hover-color: #fff;\n  color: #fff;\n  border-color: #373b3e;\n}\n\n.table-responsive {\n  overflow-x: auto;\n  -webkit-overflow-scrolling: touch;\n}\n\n@media (max-width: 575.98px) {\n  .table-responsive-sm {\n    overflow-x: auto;\n    -webkit-overflow-scrolling: touch;\n  }\n}\n@media (max-width: 767.98px) {\n  .table-responsive-md {\n    overflow-x: auto;\n    -webkit-overflow-scrolling: touch;\n  }\n}\n@media (max-width: 991.98px) {\n  .table-responsive-lg {\n    overflow-x: auto;\n    -webkit-overflow-scrolling: touch;\n  }\n}\n@media (max-width: 1199.98px) {\n  .table-responsive-xl {\n    overflow-x: auto;\n    -webkit-overflow-scrolling: touch;\n  }\n}\n@media (max-width: 1399.98px) {\n  .table-responsive-xxl {\n    overflow-x: auto;\n    -webkit-overflow-scrolling: touch;\n  }\n}\n.form-label {\n  margin-bottom: 0.5rem;\n}\n\n.col-form-label {\n  padding-top: calc(0.375rem + 1px);\n  padding-bottom: calc(0.375rem + 1px);\n  margin-bottom: 0;\n  font-size: inherit;\n  line-height: 1.5;\n}\n\n.col-form-label-lg {\n  padding-top: calc(0.5rem + 1px);\n  padding-bottom: calc(0.5rem + 1px);\n  font-size: 1.25rem;\n}\n\n.col-form-label-sm {\n  padding-top: calc(0.25rem + 1px);\n  padding-bottom: calc(0.25rem + 1px);\n  font-size: 0.875rem;\n}\n\n.form-text {\n  margin-top: 0.25rem;\n  font-size: 0.875em;\n  color: #6c757d;\n}\n\n.form-control {\n  display: block;\n  width: 100%;\n  padding: 0.375rem 0.75rem;\n  font-size: 1rem;\n  font-weight: 400;\n  line-height: 1.5;\n  color: #212529;\n  background-color: #fff;\n  background-clip: padding-box;\n  border: 1px solid #ced4da;\n  -webkit-appearance: none;\n  -moz-appearance: none;\n  appearance: none;\n  border-radius: 0.25rem;\n  transition: border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;\n}\n@media (prefers-reduced-motion: reduce) {\n  .form-control {\n    transition: none;\n  }\n}\n.form-control[type=file] {\n  overflow: hidden;\n}\n.form-control[type=file]:not(:disabled):not([readonly]) {\n  cursor: pointer;\n}\n.form-control:focus {\n  color: #212529;\n  background-color: #fff;\n  border-color: #86b7fe;\n  outline: 0;\n  box-shadow: 0 0 0 0.25rem rgba(13, 110, 253, 0.25);\n}\n.form-control::-webkit-date-and-time-value {\n  height: 1.5em;\n}\n.form-control::-moz-placeholder {\n  color: #6c757d;\n  opacity: 1;\n}\n.form-control::placeholder {\n  color: #6c757d;\n  opacity: 1;\n}\n.form-control:disabled, .form-control[readonly] {\n  background-color: #e9ecef;\n  opacity: 1;\n}\n.form-control::file-selector-button {\n  padding: 0.375rem 0.75rem;\n  margin: -0.375rem -0.75rem;\n  -webkit-margin-end: 0.75rem;\n  margin-inline-end: 0.75rem;\n  color: #212529;\n  background-color: #e9ecef;\n  pointer-events: none;\n  border-color: inherit;\n  border-style: solid;\n  border-width: 0;\n  border-inline-end-width: 1px;\n  border-radius: 0;\n  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;\n}\n@media (prefers-reduced-motion: reduce) {\n  .form-control::file-selector-button {\n    transition: none;\n  }\n}\n.form-control:hover:not(:disabled):not([readonly])::file-selector-button {\n  background-color: #dde0e3;\n}\n.form-control::-webkit-file-upload-button {\n  padding: 0.375rem 0.75rem;\n  margin: -0.375rem -0.75rem;\n  -webkit-margin-end: 0.75rem;\n  margin-inline-end: 0.75rem;\n  color: #212529;\n  background-color: #e9ecef;\n  pointer-events: none;\n  border-color: inherit;\n  border-style: solid;\n  border-width: 0;\n  border-inline-end-width: 1px;\n  border-radius: 0;\n  -webkit-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;\n  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;\n}\n@media (prefers-reduced-motion: reduce) {\n  .form-control::-webkit-file-upload-button {\n    -webkit-transition: none;\n    transition: none;\n  }\n}\n.form-control:hover:not(:disabled):not([readonly])::-webkit-file-upload-button {\n  background-color: #dde0e3;\n}\n\n.form-control-plaintext {\n  display: block;\n  width: 100%;\n  padding: 0.375rem 0;\n  margin-bottom: 0;\n  line-height: 1.5;\n  color: #212529;\n  background-color: transparent;\n  border: solid transparent;\n  border-width: 1px 0;\n}\n.form-control-plaintext.form-control-sm, .form-control-plaintext.form-control-lg {\n  padding-right: 0;\n  padding-left: 0;\n}\n\n.form-control-sm {\n  min-height: calc(1.5em + 0.5rem + 2px);\n  padding: 0.25rem 0.5rem;\n  font-size: 0.875rem;\n  border-radius: 0.2rem;\n}\n.form-control-sm::file-selector-button {\n  padding: 0.25rem 0.5rem;\n  margin: -0.25rem -0.5rem;\n  -webkit-margin-end: 0.5rem;\n  margin-inline-end: 0.5rem;\n}\n.form-control-sm::-webkit-file-upload-button {\n  padding: 0.25rem 0.5rem;\n  margin: -0.25rem -0.5rem;\n  -webkit-margin-end: 0.5rem;\n  margin-inline-end: 0.5rem;\n}\n\n.form-control-lg {\n  min-height: calc(1.5em + 1rem + 2px);\n  padding: 0.5rem 1rem;\n  font-size: 1.25rem;\n  border-radius: 0.3rem;\n}\n.form-control-lg::file-selector-button {\n  padding: 0.5rem 1rem;\n  margin: -0.5rem -1rem;\n  -webkit-margin-end: 1rem;\n  margin-inline-end: 1rem;\n}\n.form-control-lg::-webkit-file-upload-button {\n  padding: 0.5rem 1rem;\n  margin: -0.5rem -1rem;\n  -webkit-margin-end: 1rem;\n  margin-inline-end: 1rem;\n}\n\ntextarea.form-control {\n  min-height: calc(1.5em + 0.75rem + 2px);\n}\ntextarea.form-control-sm {\n  min-height: calc(1.5em + 0.5rem + 2px);\n}\ntextarea.form-control-lg {\n  min-height: calc(1.5em + 1rem + 2px);\n}\n\n.form-control-color {\n  width: 3rem;\n  height: auto;\n  padding: 0.375rem;\n}\n.form-control-color:not(:disabled):not([readonly]) {\n  cursor: pointer;\n}\n.form-control-color::-moz-color-swatch {\n  height: 1.5em;\n  border-radius: 0.25rem;\n}\n.form-control-color::-webkit-color-swatch {\n  height: 1.5em;\n  border-radius: 0.25rem;\n}\n\n.form-select {\n  display: block;\n  width: 100%;\n  padding: 0.375rem 2.25rem 0.375rem 0.75rem;\n  -moz-padding-start: calc(0.75rem - 3px);\n  font-size: 1rem;\n  font-weight: 400;\n  line-height: 1.5;\n  color: #212529;\n  background-color: #fff;\n  background-image: 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 5l6 6 6-6'/%3e%3c/svg%3e\");\n  background-repeat: no-repeat;\n  background-position: right 0.75rem center;\n  background-size: 16px 12px;\n  border: 1px solid #ced4da;\n  border-radius: 0.25rem;\n  transition: border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;\n  -webkit-appearance: none;\n  -moz-appearance: none;\n  appearance: none;\n}\n@media (prefers-reduced-motion: reduce) {\n  .form-select {\n    transition: none;\n  }\n}\n.form-select:focus {\n  border-color: #86b7fe;\n  outline: 0;\n  box-shadow: 0 0 0 0.25rem rgba(13, 110, 253, 0.25);\n}\n.form-select[multiple], .form-select[size]:not([size=\"1\"]) {\n  padding-right: 0.75rem;\n  background-image: none;\n}\n.form-select:disabled {\n  background-color: #e9ecef;\n}\n.form-select:-moz-focusring {\n  color: transparent;\n  text-shadow: 0 0 0 #212529;\n}\n\n.form-select-sm {\n  padding-top: 0.25rem;\n  padding-bottom: 0.25rem;\n  padding-left: 0.5rem;\n  font-size: 0.875rem;\n}\n\n.form-select-lg {\n  padding-top: 0.5rem;\n  padding-bottom: 0.5rem;\n  padding-left: 1rem;\n  font-size: 1.25rem;\n}\n\n.form-check {\n  display: block;\n  min-height: 1.5rem;\n  padding-left: 1.5em;\n  margin-bottom: 0.125rem;\n}\n.form-check .form-check-input {\n  float: left;\n  margin-left: -1.5em;\n}\n\n.form-check-input {\n  width: 1em;\n  height: 1em;\n  margin-top: 0.25em;\n  vertical-align: top;\n  background-color: #fff;\n  background-repeat: no-repeat;\n  background-position: center;\n  background-size: contain;\n  border: 1px solid rgba(0, 0, 0, 0.25);\n  -webkit-appearance: none;\n  -moz-appearance: none;\n  appearance: none;\n  -webkit-print-color-adjust: exact;\n  color-adjust: exact;\n}\n.form-check-input[type=checkbox] {\n  border-radius: 0.25em;\n}\n.form-check-input[type=radio] {\n  border-radius: 50%;\n}\n.form-check-input:active {\n  filter: brightness(90%);\n}\n.form-check-input:focus {\n  border-color: #86b7fe;\n  outline: 0;\n  box-shadow: 0 0 0 0.25rem rgba(13, 110, 253, 0.25);\n}\n.form-check-input:checked {\n  background-color: #0d6efd;\n  border-color: #0d6efd;\n}\n.form-check-input:checked[type=checkbox] {\n  background-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 10l3 3l6-6'/%3e%3c/svg%3e\");\n}\n.form-check-input:checked[type=radio] {\n  background-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\");\n}\n.form-check-input[type=checkbox]:indeterminate {\n  background-color: #0d6efd;\n  border-color: #0d6efd;\n  background-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\");\n}\n.form-check-input:disabled {\n  pointer-events: none;\n  filter: none;\n  opacity: 0.5;\n}\n.form-check-input[disabled] ~ .form-check-label, .form-check-input:disabled ~ .form-check-label {\n  opacity: 0.5;\n}\n\n.form-switch {\n  padding-left: 2.5em;\n}\n.form-switch .form-check-input {\n  width: 2em;\n  margin-left: -2.5em;\n  background-image: 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\");\n  background-position: left center;\n  border-radius: 2em;\n  transition: background-position 0.15s ease-in-out;\n}\n@media (prefers-reduced-motion: reduce) {\n  .form-switch .form-check-input {\n    transition: none;\n  }\n}\n.form-switch .form-check-input:focus {\n  background-image: 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\");\n}\n.form-switch .form-check-input:checked {\n  background-position: right center;\n  background-image: 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\");\n}\n\n.form-check-inline {\n  display: inline-block;\n  margin-right: 1rem;\n}\n\n.btn-check {\n  position: absolute;\n  clip: rect(0, 0, 0, 0);\n  pointer-events: none;\n}\n.btn-check[disabled] + .btn, .btn-check:disabled + .btn {\n  pointer-events: none;\n  filter: none;\n  opacity: 0.65;\n}\n\n.form-range {\n  width: 100%;\n  height: 1.5rem;\n  padding: 0;\n  background-color: transparent;\n  -webkit-appearance: none;\n  -moz-appearance: none;\n  appearance: none;\n}\n.form-range:focus {\n  outline: 0;\n}\n.form-range:focus::-webkit-slider-thumb {\n  box-shadow: 0 0 0 1px #fff, 0 0 0 0.25rem rgba(13, 110, 253, 0.25);\n}\n.form-range:focus::-moz-range-thumb {\n  box-shadow: 0 0 0 1px #fff, 0 0 0 0.25rem rgba(13, 110, 253, 0.25);\n}\n.form-range::-moz-focus-outer {\n  border: 0;\n}\n.form-range::-webkit-slider-thumb {\n  width: 1rem;\n  height: 1rem;\n  margin-top: -0.25rem;\n  background-color: #0d6efd;\n  border: 0;\n  border-radius: 1rem;\n  -webkit-transition: background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;\n  transition: background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;\n  -webkit-appearance: none;\n  appearance: none;\n}\n@media (prefers-reduced-motion: reduce) {\n  .form-range::-webkit-slider-thumb {\n    -webkit-transition: none;\n    transition: none;\n  }\n}\n.form-range::-webkit-slider-thumb:active {\n  background-color: #b6d4fe;\n}\n.form-range::-webkit-slider-runnable-track {\n  width: 100%;\n  height: 0.5rem;\n  color: transparent;\n  cursor: pointer;\n  background-color: #dee2e6;\n  border-color: transparent;\n  border-radius: 1rem;\n}\n.form-range::-moz-range-thumb {\n  width: 1rem;\n  height: 1rem;\n  background-color: #0d6efd;\n  border: 0;\n  border-radius: 1rem;\n  -moz-transition: background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;\n  transition: background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;\n  -moz-appearance: none;\n  appearance: none;\n}\n@media (prefers-reduced-motion: reduce) {\n  .form-range::-moz-range-thumb {\n    -moz-transition: none;\n    transition: none;\n  }\n}\n.form-range::-moz-range-thumb:active {\n  background-color: #b6d4fe;\n}\n.form-range::-moz-range-track {\n  width: 100%;\n  height: 0.5rem;\n  color: transparent;\n  cursor: pointer;\n  background-color: #dee2e6;\n  border-color: transparent;\n  border-radius: 1rem;\n}\n.form-range:disabled {\n  pointer-events: none;\n}\n.form-range:disabled::-webkit-slider-thumb {\n  background-color: #adb5bd;\n}\n.form-range:disabled::-moz-range-thumb {\n  background-color: #adb5bd;\n}\n\n.form-floating {\n  position: relative;\n}\n.form-floating > .form-control,\n.form-floating > .form-select {\n  height: calc(3.5rem + 2px);\n  line-height: 1.25;\n}\n.form-floating > label {\n  position: absolute;\n  top: 0;\n  left: 0;\n  height: 100%;\n  padding: 1rem 0.75rem;\n  pointer-events: none;\n  border: 1px solid transparent;\n  transform-origin: 0 0;\n  transition: opacity 0.1s ease-in-out, transform 0.1s ease-in-out;\n}\n@media (prefers-reduced-motion: reduce) {\n  .form-floating > label {\n    transition: none;\n  }\n}\n.form-floating > .form-control {\n  padding: 1rem 0.75rem;\n}\n.form-floating > .form-control::-moz-placeholder {\n  color: transparent;\n}\n.form-floating > .form-control::placeholder {\n  color: transparent;\n}\n.form-floating > .form-control:not(:-moz-placeholder-shown) {\n  padding-top: 1.625rem;\n  padding-bottom: 0.625rem;\n}\n.form-floating > .form-control:focus, .form-floating > .form-control:not(:placeholder-shown) {\n  padding-top: 1.625rem;\n  padding-bottom: 0.625rem;\n}\n.form-floating > .form-control:-webkit-autofill {\n  padding-top: 1.625rem;\n  padding-bottom: 0.625rem;\n}\n.form-floating > .form-select {\n  padding-top: 1.625rem;\n  padding-bottom: 0.625rem;\n}\n.form-floating > .form-control:not(:-moz-placeholder-shown) ~ label {\n  opacity: 0.65;\n  transform: scale(0.85) translateY(-0.5rem) translateX(0.15rem);\n}\n.form-floating > .form-control:focus ~ label,\n.form-floating > .form-control:not(:placeholder-shown) ~ label,\n.form-floating > .form-select ~ label {\n  opacity: 0.65;\n  transform: scale(0.85) translateY(-0.5rem) translateX(0.15rem);\n}\n.form-floating > .form-control:-webkit-autofill ~ label {\n  opacity: 0.65;\n  transform: scale(0.85) translateY(-0.5rem) translateX(0.15rem);\n}\n\n.input-group {\n  position: relative;\n  display: flex;\n  flex-wrap: wrap;\n  align-items: stretch;\n  width: 100%;\n}\n.input-group > .form-control,\n.input-group > .form-select {\n  position: relative;\n  flex: 1 1 auto;\n  width: 1%;\n  min-width: 0;\n}\n.input-group > .form-control:focus,\n.input-group > .form-select:focus {\n  z-index: 3;\n}\n.input-group .btn {\n  position: relative;\n  z-index: 2;\n}\n.input-group .btn:focus {\n  z-index: 3;\n}\n\n.input-group-text {\n  display: flex;\n  align-items: center;\n  padding: 0.375rem 0.75rem;\n  font-size: 1rem;\n  font-weight: 400;\n  line-height: 1.5;\n  color: #212529;\n  text-align: center;\n  white-space: nowrap;\n  background-color: #e9ecef;\n  border: 1px solid #ced4da;\n  border-radius: 0.25rem;\n}\n\n.input-group-lg > .form-control,\n.input-group-lg > .form-select,\n.input-group-lg > .input-group-text,\n.input-group-lg > .btn {\n  padding: 0.5rem 1rem;\n  font-size: 1.25rem;\n  border-radius: 0.3rem;\n}\n\n.input-group-sm > .form-control,\n.input-group-sm > .form-select,\n.input-group-sm > .input-group-text,\n.input-group-sm > .btn {\n  padding: 0.25rem 0.5rem;\n  font-size: 0.875rem;\n  border-radius: 0.2rem;\n}\n\n.input-group-lg > .form-select,\n.input-group-sm > .form-select {\n  padding-right: 3rem;\n}\n\n.input-group:not(.has-validation) > :not(:last-child):not(.dropdown-toggle):not(.dropdown-menu),\n.input-group:not(.has-validation) > .dropdown-toggle:nth-last-child(n+3) {\n  border-top-right-radius: 0;\n  border-bottom-right-radius: 0;\n}\n.input-group.has-validation > :nth-last-child(n+3):not(.dropdown-toggle):not(.dropdown-menu),\n.input-group.has-validation > .dropdown-toggle:nth-last-child(n+4) {\n  border-top-right-radius: 0;\n  border-bottom-right-radius: 0;\n}\n.input-group > :not(:first-child):not(.dropdown-menu):not(.valid-tooltip):not(.valid-feedback):not(.invalid-tooltip):not(.invalid-feedback) {\n  margin-left: -1px;\n  border-top-left-radius: 0;\n  border-bottom-left-radius: 0;\n}\n\n.valid-feedback {\n  display: none;\n  width: 100%;\n  margin-top: 0.25rem;\n  font-size: 0.875em;\n  color: #198754;\n}\n\n.valid-tooltip {\n  position: absolute;\n  top: 100%;\n  z-index: 5;\n  display: none;\n  max-width: 100%;\n  padding: 0.25rem 0.5rem;\n  margin-top: 0.1rem;\n  font-size: 0.875rem;\n  color: #fff;\n  background-color: rgba(25, 135, 84, 0.9);\n  border-radius: 0.25rem;\n}\n\n.was-validated :valid ~ .valid-feedback,\n.was-validated :valid ~ .valid-tooltip,\n.is-valid ~ .valid-feedback,\n.is-valid ~ .valid-tooltip {\n  display: block;\n}\n\n.was-validated .form-control:valid, .form-control.is-valid {\n  border-color: #198754;\n  padding-right: calc(1.5em + 0.75rem);\n  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.73L.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.1z'/%3e%3c/svg%3e\");\n  background-repeat: no-repeat;\n  background-position: right calc(0.375em + 0.1875rem) center;\n  background-size: calc(0.75em + 0.375rem) calc(0.75em + 0.375rem);\n}\n.was-validated .form-control:valid:focus, .form-control.is-valid:focus {\n  border-color: #198754;\n  box-shadow: 0 0 0 0.25rem rgba(25, 135, 84, 0.25);\n}\n\n.was-validated textarea.form-control:valid, textarea.form-control.is-valid {\n  padding-right: calc(1.5em + 0.75rem);\n  background-position: top calc(0.375em + 0.1875rem) right calc(0.375em + 0.1875rem);\n}\n\n.was-validated .form-select:valid, .form-select.is-valid {\n  border-color: #198754;\n}\n.was-validated .form-select:valid:not([multiple]):not([size]), .was-validated .form-select:valid:not([multiple])[size=\"1\"], .form-select.is-valid:not([multiple]):not([size]), .form-select.is-valid:not([multiple])[size=\"1\"] {\n  padding-right: 4.125rem;\n  background-image: 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 5l6 6 6-6'/%3e%3c/svg%3e\"), 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.73L.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.1z'/%3e%3c/svg%3e\");\n  background-position: right 0.75rem center, center right 2.25rem;\n  background-size: 16px 12px, calc(0.75em + 0.375rem) calc(0.75em + 0.375rem);\n}\n.was-validated .form-select:valid:focus, .form-select.is-valid:focus {\n  border-color: #198754;\n  box-shadow: 0 0 0 0.25rem rgba(25, 135, 84, 0.25);\n}\n\n.was-validated .form-check-input:valid, .form-check-input.is-valid {\n  border-color: #198754;\n}\n.was-validated .form-check-input:valid:checked, .form-check-input.is-valid:checked {\n  background-color: #198754;\n}\n.was-validated .form-check-input:valid:focus, .form-check-input.is-valid:focus {\n  box-shadow: 0 0 0 0.25rem rgba(25, 135, 84, 0.25);\n}\n.was-validated .form-check-input:valid ~ .form-check-label, .form-check-input.is-valid ~ .form-check-label {\n  color: #198754;\n}\n\n.form-check-inline .form-check-input ~ .valid-feedback {\n  margin-left: 0.5em;\n}\n\n.was-validated .input-group .form-control:valid, .input-group .form-control.is-valid,\n.was-validated .input-group .form-select:valid,\n.input-group .form-select.is-valid {\n  z-index: 1;\n}\n.was-validated .input-group .form-control:valid:focus, .input-group .form-control.is-valid:focus,\n.was-validated .input-group .form-select:valid:focus,\n.input-group .form-select.is-valid:focus {\n  z-index: 3;\n}\n\n.invalid-feedback {\n  display: none;\n  width: 100%;\n  margin-top: 0.25rem;\n  font-size: 0.875em;\n  color: #dc3545;\n}\n\n.invalid-tooltip {\n  position: absolute;\n  top: 100%;\n  z-index: 5;\n  display: none;\n  max-width: 100%;\n  padding: 0.25rem 0.5rem;\n  margin-top: 0.1rem;\n  font-size: 0.875rem;\n  color: #fff;\n  background-color: rgba(220, 53, 69, 0.9);\n  border-radius: 0.25rem;\n}\n\n.was-validated :invalid ~ .invalid-feedback,\n.was-validated :invalid ~ .invalid-tooltip,\n.is-invalid ~ .invalid-feedback,\n.is-invalid ~ .invalid-tooltip {\n  display: block;\n}\n\n.was-validated .form-control:invalid, .form-control.is-invalid {\n  border-color: #dc3545;\n  padding-right: calc(1.5em + 0.75rem);\n  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\");\n  background-repeat: no-repeat;\n  background-position: right calc(0.375em + 0.1875rem) center;\n  background-size: calc(0.75em + 0.375rem) calc(0.75em + 0.375rem);\n}\n.was-validated .form-control:invalid:focus, .form-control.is-invalid:focus {\n  border-color: #dc3545;\n  box-shadow: 0 0 0 0.25rem rgba(220, 53, 69, 0.25);\n}\n\n.was-validated textarea.form-control:invalid, textarea.form-control.is-invalid {\n  padding-right: calc(1.5em + 0.75rem);\n  background-position: top calc(0.375em + 0.1875rem) right calc(0.375em + 0.1875rem);\n}\n\n.was-validated .form-select:invalid, .form-select.is-invalid {\n  border-color: #dc3545;\n}\n.was-validated .form-select:invalid:not([multiple]):not([size]), .was-validated .form-select:invalid:not([multiple])[size=\"1\"], .form-select.is-invalid:not([multiple]):not([size]), .form-select.is-invalid:not([multiple])[size=\"1\"] {\n  padding-right: 4.125rem;\n  background-image: 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 5l6 6 6-6'/%3e%3c/svg%3e\"), 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\");\n  background-position: right 0.75rem center, center right 2.25rem;\n  background-size: 16px 12px, calc(0.75em + 0.375rem) calc(0.75em + 0.375rem);\n}\n.was-validated .form-select:invalid:focus, .form-select.is-invalid:focus {\n  border-color: #dc3545;\n  box-shadow: 0 0 0 0.25rem rgba(220, 53, 69, 0.25);\n}\n\n.was-validated .form-check-input:invalid, .form-check-input.is-invalid {\n  border-color: #dc3545;\n}\n.was-validated .form-check-input:invalid:checked, .form-check-input.is-invalid:checked {\n  background-color: #dc3545;\n}\n.was-validated .form-check-input:invalid:focus, .form-check-input.is-invalid:focus {\n  box-shadow: 0 0 0 0.25rem rgba(220, 53, 69, 0.25);\n}\n.was-validated .form-check-input:invalid ~ .form-check-label, .form-check-input.is-invalid ~ .form-check-label {\n  color: #dc3545;\n}\n\n.form-check-inline .form-check-input ~ .invalid-feedback {\n  margin-left: 0.5em;\n}\n\n.was-validated .input-group .form-control:invalid, .input-group .form-control.is-invalid,\n.was-validated .input-group .form-select:invalid,\n.input-group .form-select.is-invalid {\n  z-index: 2;\n}\n.was-validated .input-group .form-control:invalid:focus, .input-group .form-control.is-invalid:focus,\n.was-validated .input-group .form-select:invalid:focus,\n.input-group .form-select.is-invalid:focus {\n  z-index: 3;\n}\n\n.btn {\n  display: inline-block;\n  font-weight: 400;\n  line-height: 1.5;\n  color: #212529;\n  text-align: center;\n  text-decoration: none;\n  vertical-align: middle;\n  cursor: pointer;\n  -webkit-user-select: none;\n  -moz-user-select: none;\n  user-select: none;\n  background-color: transparent;\n  border: 1px solid transparent;\n  padding: 0.375rem 0.75rem;\n  font-size: 1rem;\n  border-radius: 0.25rem;\n  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;\n}\n@media (prefers-reduced-motion: reduce) {\n  .btn {\n    transition: none;\n  }\n}\n.btn:hover {\n  color: #212529;\n}\n.btn-check:focus + .btn, .btn:focus {\n  outline: 0;\n  box-shadow: 0 0 0 0.25rem rgba(13, 110, 253, 0.25);\n}\n.btn:disabled, .btn.disabled, fieldset:disabled .btn {\n  pointer-events: none;\n  opacity: 0.65;\n}\n\n.btn-primary {\n  color: #fff;\n  background-color: #0d6efd;\n  border-color: #0d6efd;\n}\n.btn-primary:hover {\n  color: #fff;\n  background-color: #0b5ed7;\n  border-color: #0a58ca;\n}\n.btn-check:focus + .btn-primary, .btn-primary:focus {\n  color: #fff;\n  background-color: #0b5ed7;\n  border-color: #0a58ca;\n  box-shadow: 0 0 0 0.25rem rgba(49, 132, 253, 0.5);\n}\n.btn-check:checked + .btn-primary, .btn-check:active + .btn-primary, .btn-primary:active, .btn-primary.active, .show > .btn-primary.dropdown-toggle {\n  color: #fff;\n  background-color: #0a58ca;\n  border-color: #0a53be;\n}\n.btn-check:checked + .btn-primary:focus, .btn-check:active + .btn-primary:focus, .btn-primary:active:focus, .btn-primary.active:focus, .show > .btn-primary.dropdown-toggle:focus {\n  box-shadow: 0 0 0 0.25rem rgba(49, 132, 253, 0.5);\n}\n.btn-primary:disabled, .btn-primary.disabled {\n  color: #fff;\n  background-color: #0d6efd;\n  border-color: #0d6efd;\n}\n\n.btn-secondary {\n  color: #fff;\n  background-color: #6c757d;\n  border-color: #6c757d;\n}\n.btn-secondary:hover {\n  color: #fff;\n  background-color: #5c636a;\n  border-color: #565e64;\n}\n.btn-check:focus + .btn-secondary, .btn-secondary:focus {\n  color: #fff;\n  background-color: #5c636a;\n  border-color: #565e64;\n  box-shadow: 0 0 0 0.25rem rgba(130, 138, 145, 0.5);\n}\n.btn-check:checked + .btn-secondary, .btn-check:active + .btn-secondary, .btn-secondary:active, .btn-secondary.active, .show > .btn-secondary.dropdown-toggle {\n  color: #fff;\n  background-color: #565e64;\n  border-color: #51585e;\n}\n.btn-check:checked + .btn-secondary:focus, .btn-check:active + .btn-secondary:focus, .btn-secondary:active:focus, .btn-secondary.active:focus, .show > .btn-secondary.dropdown-toggle:focus {\n  box-shadow: 0 0 0 0.25rem rgba(130, 138, 145, 0.5);\n}\n.btn-secondary:disabled, .btn-secondary.disabled {\n  color: #fff;\n  background-color: #6c757d;\n  border-color: #6c757d;\n}\n\n.btn-success {\n  color: #fff;\n  background-color: #198754;\n  border-color: #198754;\n}\n.btn-success:hover {\n  color: #fff;\n  background-color: #157347;\n  border-color: #146c43;\n}\n.btn-check:focus + .btn-success, .btn-success:focus {\n  color: #fff;\n  background-color: #157347;\n  border-color: #146c43;\n  box-shadow: 0 0 0 0.25rem rgba(60, 153, 110, 0.5);\n}\n.btn-check:checked + .btn-success, .btn-check:active + .btn-success, .btn-success:active, .btn-success.active, .show > .btn-success.dropdown-toggle {\n  color: #fff;\n  background-color: #146c43;\n  border-color: #13653f;\n}\n.btn-check:checked + .btn-success:focus, .btn-check:active + .btn-success:focus, .btn-success:active:focus, .btn-success.active:focus, .show > .btn-success.dropdown-toggle:focus {\n  box-shadow: 0 0 0 0.25rem rgba(60, 153, 110, 0.5);\n}\n.btn-success:disabled, .btn-success.disabled {\n  color: #fff;\n  background-color: #198754;\n  border-color: #198754;\n}\n\n.btn-info {\n  color: #000;\n  background-color: #0dcaf0;\n  border-color: #0dcaf0;\n}\n.btn-info:hover {\n  color: #000;\n  background-color: #31d2f2;\n  border-color: #25cff2;\n}\n.btn-check:focus + .btn-info, .btn-info:focus {\n  color: #000;\n  background-color: #31d2f2;\n  border-color: #25cff2;\n  box-shadow: 0 0 0 0.25rem rgba(11, 172, 204, 0.5);\n}\n.btn-check:checked + .btn-info, .btn-check:active + .btn-info, .btn-info:active, .btn-info.active, .show > .btn-info.dropdown-toggle {\n  color: #000;\n  background-color: #3dd5f3;\n  border-color: #25cff2;\n}\n.btn-check:checked + .btn-info:focus, .btn-check:active + .btn-info:focus, .btn-info:active:focus, .btn-info.active:focus, .show > .btn-info.dropdown-toggle:focus {\n  box-shadow: 0 0 0 0.25rem rgba(11, 172, 204, 0.5);\n}\n.btn-info:disabled, .btn-info.disabled {\n  color: #000;\n  background-color: #0dcaf0;\n  border-color: #0dcaf0;\n}\n\n.btn-warning {\n  color: #000;\n  background-color: #ffc107;\n  border-color: #ffc107;\n}\n.btn-warning:hover {\n  color: #000;\n  background-color: #ffca2c;\n  border-color: #ffc720;\n}\n.btn-check:focus + .btn-warning, .btn-warning:focus {\n  color: #000;\n  background-color: #ffca2c;\n  border-color: #ffc720;\n  box-shadow: 0 0 0 0.25rem rgba(217, 164, 6, 0.5);\n}\n.btn-check:checked + .btn-warning, .btn-check:active + .btn-warning, .btn-warning:active, .btn-warning.active, .show > .btn-warning.dropdown-toggle {\n  color: #000;\n  background-color: #ffcd39;\n  border-color: #ffc720;\n}\n.btn-check:checked + .btn-warning:focus, .btn-check:active + .btn-warning:focus, .btn-warning:active:focus, .btn-warning.active:focus, .show > .btn-warning.dropdown-toggle:focus {\n  box-shadow: 0 0 0 0.25rem rgba(217, 164, 6, 0.5);\n}\n.btn-warning:disabled, .btn-warning.disabled {\n  color: #000;\n  background-color: #ffc107;\n  border-color: #ffc107;\n}\n\n.btn-danger {\n  color: #fff;\n  background-color: #dc3545;\n  border-color: #dc3545;\n}\n.btn-danger:hover {\n  color: #fff;\n  background-color: #bb2d3b;\n  border-color: #b02a37;\n}\n.btn-check:focus + .btn-danger, .btn-danger:focus {\n  color: #fff;\n  background-color: #bb2d3b;\n  border-color: #b02a37;\n  box-shadow: 0 0 0 0.25rem rgba(225, 83, 97, 0.5);\n}\n.btn-check:checked + .btn-danger, .btn-check:active + .btn-danger, .btn-danger:active, .btn-danger.active, .show > .btn-danger.dropdown-toggle {\n  color: #fff;\n  background-color: #b02a37;\n  border-color: #a52834;\n}\n.btn-check:checked + .btn-danger:focus, .btn-check:active + .btn-danger:focus, .btn-danger:active:focus, .btn-danger.active:focus, .show > .btn-danger.dropdown-toggle:focus {\n  box-shadow: 0 0 0 0.25rem rgba(225, 83, 97, 0.5);\n}\n.btn-danger:disabled, .btn-danger.disabled {\n  color: #fff;\n  background-color: #dc3545;\n  border-color: #dc3545;\n}\n\n.btn-light {\n  color: #000;\n  background-color: #f8f9fa;\n  border-color: #f8f9fa;\n}\n.btn-light:hover {\n  color: #000;\n  background-color: #f9fafb;\n  border-color: #f9fafb;\n}\n.btn-check:focus + .btn-light, .btn-light:focus {\n  color: #000;\n  background-color: #f9fafb;\n  border-color: #f9fafb;\n  box-shadow: 0 0 0 0.25rem rgba(211, 212, 213, 0.5);\n}\n.btn-check:checked + .btn-light, .btn-check:active + .btn-light, .btn-light:active, .btn-light.active, .show > .btn-light.dropdown-toggle {\n  color: #000;\n  background-color: #f9fafb;\n  border-color: #f9fafb;\n}\n.btn-check:checked + .btn-light:focus, .btn-check:active + .btn-light:focus, .btn-light:active:focus, .btn-light.active:focus, .show > .btn-light.dropdown-toggle:focus {\n  box-shadow: 0 0 0 0.25rem rgba(211, 212, 213, 0.5);\n}\n.btn-light:disabled, .btn-light.disabled {\n  color: #000;\n  background-color: #f8f9fa;\n  border-color: #f8f9fa;\n}\n\n.btn-dark {\n  color: #fff;\n  background-color: #212529;\n  border-color: #212529;\n}\n.btn-dark:hover {\n  color: #fff;\n  background-color: #1c1f23;\n  border-color: #1a1e21;\n}\n.btn-check:focus + .btn-dark, .btn-dark:focus {\n  color: #fff;\n  background-color: #1c1f23;\n  border-color: #1a1e21;\n  box-shadow: 0 0 0 0.25rem rgba(66, 70, 73, 0.5);\n}\n.btn-check:checked + .btn-dark, .btn-check:active + .btn-dark, .btn-dark:active, .btn-dark.active, .show > .btn-dark.dropdown-toggle {\n  color: #fff;\n  background-color: #1a1e21;\n  border-color: #191c1f;\n}\n.btn-check:checked + .btn-dark:focus, .btn-check:active + .btn-dark:focus, .btn-dark:active:focus, .btn-dark.active:focus, .show > .btn-dark.dropdown-toggle:focus {\n  box-shadow: 0 0 0 0.25rem rgba(66, 70, 73, 0.5);\n}\n.btn-dark:disabled, .btn-dark.disabled {\n  color: #fff;\n  background-color: #212529;\n  border-color: #212529;\n}\n\n.btn-outline-primary {\n  color: #0d6efd;\n  border-color: #0d6efd;\n}\n.btn-outline-primary:hover {\n  color: #fff;\n  background-color: #0d6efd;\n  border-color: #0d6efd;\n}\n.btn-check:focus + .btn-outline-primary, .btn-outline-primary:focus {\n  box-shadow: 0 0 0 0.25rem rgba(13, 110, 253, 0.5);\n}\n.btn-check:checked + .btn-outline-primary, .btn-check:active + .btn-outline-primary, .btn-outline-primary:active, .btn-outline-primary.active, .btn-outline-primary.dropdown-toggle.show {\n  color: #fff;\n  background-color: #0d6efd;\n  border-color: #0d6efd;\n}\n.btn-check:checked + .btn-outline-primary:focus, .btn-check:active + .btn-outline-primary:focus, .btn-outline-primary:active:focus, .btn-outline-primary.active:focus, .btn-outline-primary.dropdown-toggle.show:focus {\n  box-shadow: 0 0 0 0.25rem rgba(13, 110, 253, 0.5);\n}\n.btn-outline-primary:disabled, .btn-outline-primary.disabled {\n  color: #0d6efd;\n  background-color: transparent;\n}\n\n.btn-outline-secondary {\n  color: #6c757d;\n  border-color: #6c757d;\n}\n.btn-outline-secondary:hover {\n  color: #fff;\n  background-color: #6c757d;\n  border-color: #6c757d;\n}\n.btn-check:focus + .btn-outline-secondary, .btn-outline-secondary:focus {\n  box-shadow: 0 0 0 0.25rem rgba(108, 117, 125, 0.5);\n}\n.btn-check:checked + .btn-outline-secondary, .btn-check:active + .btn-outline-secondary, .btn-outline-secondary:active, .btn-outline-secondary.active, .btn-outline-secondary.dropdown-toggle.show {\n  color: #fff;\n  background-color: #6c757d;\n  border-color: #6c757d;\n}\n.btn-check:checked + .btn-outline-secondary:focus, .btn-check:active + .btn-outline-secondary:focus, .btn-outline-secondary:active:focus, .btn-outline-secondary.active:focus, .btn-outline-secondary.dropdown-toggle.show:focus {\n  box-shadow: 0 0 0 0.25rem rgba(108, 117, 125, 0.5);\n}\n.btn-outline-secondary:disabled, .btn-outline-secondary.disabled {\n  color: #6c757d;\n  background-color: transparent;\n}\n\n.btn-outline-success {\n  color: #198754;\n  border-color: #198754;\n}\n.btn-outline-success:hover {\n  color: #fff;\n  background-color: #198754;\n  border-color: #198754;\n}\n.btn-check:focus + .btn-outline-success, .btn-outline-success:focus {\n  box-shadow: 0 0 0 0.25rem rgba(25, 135, 84, 0.5);\n}\n.btn-check:checked + .btn-outline-success, .btn-check:active + .btn-outline-success, .btn-outline-success:active, .btn-outline-success.active, .btn-outline-success.dropdown-toggle.show {\n  color: #fff;\n  background-color: #198754;\n  border-color: #198754;\n}\n.btn-check:checked + .btn-outline-success:focus, .btn-check:active + .btn-outline-success:focus, .btn-outline-success:active:focus, .btn-outline-success.active:focus, .btn-outline-success.dropdown-toggle.show:focus {\n  box-shadow: 0 0 0 0.25rem rgba(25, 135, 84, 0.5);\n}\n.btn-outline-success:disabled, .btn-outline-success.disabled {\n  color: #198754;\n  background-color: transparent;\n}\n\n.btn-outline-info {\n  color: #0dcaf0;\n  border-color: #0dcaf0;\n}\n.btn-outline-info:hover {\n  color: #000;\n  background-color: #0dcaf0;\n  border-color: #0dcaf0;\n}\n.btn-check:focus + .btn-outline-info, .btn-outline-info:focus {\n  box-shadow: 0 0 0 0.25rem rgba(13, 202, 240, 0.5);\n}\n.btn-check:checked + .btn-outline-info, .btn-check:active + .btn-outline-info, .btn-outline-info:active, .btn-outline-info.active, .btn-outline-info.dropdown-toggle.show {\n  color: #000;\n  background-color: #0dcaf0;\n  border-color: #0dcaf0;\n}\n.btn-check:checked + .btn-outline-info:focus, .btn-check:active + .btn-outline-info:focus, .btn-outline-info:active:focus, .btn-outline-info.active:focus, .btn-outline-info.dropdown-toggle.show:focus {\n  box-shadow: 0 0 0 0.25rem rgba(13, 202, 240, 0.5);\n}\n.btn-outline-info:disabled, .btn-outline-info.disabled {\n  color: #0dcaf0;\n  background-color: transparent;\n}\n\n.btn-outline-warning {\n  color: #ffc107;\n  border-color: #ffc107;\n}\n.btn-outline-warning:hover {\n  color: #000;\n  background-color: #ffc107;\n  border-color: #ffc107;\n}\n.btn-check:focus + .btn-outline-warning, .btn-outline-warning:focus {\n  box-shadow: 0 0 0 0.25rem rgba(255, 193, 7, 0.5);\n}\n.btn-check:checked + .btn-outline-warning, .btn-check:active + .btn-outline-warning, .btn-outline-warning:active, .btn-outline-warning.active, .btn-outline-warning.dropdown-toggle.show {\n  color: #000;\n  background-color: #ffc107;\n  border-color: #ffc107;\n}\n.btn-check:checked + .btn-outline-warning:focus, .btn-check:active + .btn-outline-warning:focus, .btn-outline-warning:active:focus, .btn-outline-warning.active:focus, .btn-outline-warning.dropdown-toggle.show:focus {\n  box-shadow: 0 0 0 0.25rem rgba(255, 193, 7, 0.5);\n}\n.btn-outline-warning:disabled, .btn-outline-warning.disabled {\n  color: #ffc107;\n  background-color: transparent;\n}\n\n.btn-outline-danger {\n  color: #dc3545;\n  border-color: #dc3545;\n}\n.btn-outline-danger:hover {\n  color: #fff;\n  background-color: #dc3545;\n  border-color: #dc3545;\n}\n.btn-check:focus + .btn-outline-danger, .btn-outline-danger:focus {\n  box-shadow: 0 0 0 0.25rem rgba(220, 53, 69, 0.5);\n}\n.btn-check:checked + .btn-outline-danger, .btn-check:active + .btn-outline-danger, .btn-outline-danger:active, .btn-outline-danger.active, .btn-outline-danger.dropdown-toggle.show {\n  color: #fff;\n  background-color: #dc3545;\n  border-color: #dc3545;\n}\n.btn-check:checked + .btn-outline-danger:focus, .btn-check:active + .btn-outline-danger:focus, .btn-outline-danger:active:focus, .btn-outline-danger.active:focus, .btn-outline-danger.dropdown-toggle.show:focus {\n  box-shadow: 0 0 0 0.25rem rgba(220, 53, 69, 0.5);\n}\n.btn-outline-danger:disabled, .btn-outline-danger.disabled {\n  color: #dc3545;\n  background-color: transparent;\n}\n\n.btn-outline-light {\n  color: #f8f9fa;\n  border-color: #f8f9fa;\n}\n.btn-outline-light:hover {\n  color: #000;\n  background-color: #f8f9fa;\n  border-color: #f8f9fa;\n}\n.btn-check:focus + .btn-outline-light, .btn-outline-light:focus {\n  box-shadow: 0 0 0 0.25rem rgba(248, 249, 250, 0.5);\n}\n.btn-check:checked + .btn-outline-light, .btn-check:active + .btn-outline-light, .btn-outline-light:active, .btn-outline-light.active, .btn-outline-light.dropdown-toggle.show {\n  color: #000;\n  background-color: #f8f9fa;\n  border-color: #f8f9fa;\n}\n.btn-check:checked + .btn-outline-light:focus, .btn-check:active + .btn-outline-light:focus, .btn-outline-light:active:focus, .btn-outline-light.active:focus, .btn-outline-light.dropdown-toggle.show:focus {\n  box-shadow: 0 0 0 0.25rem rgba(248, 249, 250, 0.5);\n}\n.btn-outline-light:disabled, .btn-outline-light.disabled {\n  color: #f8f9fa;\n  background-color: transparent;\n}\n\n.btn-outline-dark {\n  color: #212529;\n  border-color: #212529;\n}\n.btn-outline-dark:hover {\n  color: #fff;\n  background-color: #212529;\n  border-color: #212529;\n}\n.btn-check:focus + .btn-outline-dark, .btn-outline-dark:focus {\n  box-shadow: 0 0 0 0.25rem rgba(33, 37, 41, 0.5);\n}\n.btn-check:checked + .btn-outline-dark, .btn-check:active + .btn-outline-dark, .btn-outline-dark:active, .btn-outline-dark.active, .btn-outline-dark.dropdown-toggle.show {\n  color: #fff;\n  background-color: #212529;\n  border-color: #212529;\n}\n.btn-check:checked + .btn-outline-dark:focus, .btn-check:active + .btn-outline-dark:focus, .btn-outline-dark:active:focus, .btn-outline-dark.active:focus, .btn-outline-dark.dropdown-toggle.show:focus {\n  box-shadow: 0 0 0 0.25rem rgba(33, 37, 41, 0.5);\n}\n.btn-outline-dark:disabled, .btn-outline-dark.disabled {\n  color: #212529;\n  background-color: transparent;\n}\n\n.btn-link {\n  font-weight: 400;\n  color: #0d6efd;\n  text-decoration: underline;\n}\n.btn-link:hover {\n  color: #0a58ca;\n}\n.btn-link:disabled, .btn-link.disabled {\n  color: #6c757d;\n}\n\n.btn-lg, .btn-group-lg > .btn {\n  padding: 0.5rem 1rem;\n  font-size: 1.25rem;\n  border-radius: 0.3rem;\n}\n\n.btn-sm, .btn-group-sm > .btn {\n  padding: 0.25rem 0.5rem;\n  font-size: 0.875rem;\n  border-radius: 0.2rem;\n}\n\n.fade {\n  transition: opacity 0.15s linear;\n}\n@media (prefers-reduced-motion: reduce) {\n  .fade {\n    transition: none;\n  }\n}\n.fade:not(.show) {\n  opacity: 0;\n}\n\n.collapse:not(.show) {\n  display: none;\n}\n\n.collapsing {\n  height: 0;\n  overflow: hidden;\n  transition: height 0.35s ease;\n}\n@media (prefers-reduced-motion: reduce) {\n  .collapsing {\n    transition: none;\n  }\n}\n.collapsing.collapse-horizontal {\n  width: 0;\n  height: auto;\n  transition: width 0.35s ease;\n}\n@media (prefers-reduced-motion: reduce) {\n  .collapsing.collapse-horizontal {\n    transition: none;\n  }\n}\n\n.dropup,\n.dropend,\n.dropdown,\n.dropstart {\n  position: relative;\n}\n\n.dropdown-toggle {\n  white-space: nowrap;\n}\n.dropdown-toggle::after {\n  display: inline-block;\n  margin-left: 0.255em;\n  vertical-align: 0.255em;\n  content: \"\";\n  border-top: 0.3em solid;\n  border-right: 0.3em solid transparent;\n  border-bottom: 0;\n  border-left: 0.3em solid transparent;\n}\n.dropdown-toggle:empty::after {\n  margin-left: 0;\n}\n\n.dropdown-menu {\n  position: absolute;\n  z-index: 1000;\n  display: none;\n  min-width: 10rem;\n  padding: 0.5rem 0;\n  margin: 0;\n  font-size: 1rem;\n  color: #212529;\n  text-align: left;\n  list-style: none;\n  background-color: #fff;\n  background-clip: padding-box;\n  border: 1px solid rgba(0, 0, 0, 0.15);\n  border-radius: 0.25rem;\n}\n.dropdown-menu[data-bs-popper] {\n  top: 100%;\n  left: 0;\n  margin-top: 0.125rem;\n}\n\n.dropdown-menu-start {\n  --bs-position: start;\n}\n.dropdown-menu-start[data-bs-popper] {\n  right: auto;\n  left: 0;\n}\n\n.dropdown-menu-end {\n  --bs-position: end;\n}\n.dropdown-menu-end[data-bs-popper] {\n  right: 0;\n  left: auto;\n}\n\n@media (min-width: 576px) {\n  .dropdown-menu-sm-start {\n    --bs-position: start;\n  }\n  .dropdown-menu-sm-start[data-bs-popper] {\n    right: auto;\n    left: 0;\n  }\n\n  .dropdown-menu-sm-end {\n    --bs-position: end;\n  }\n  .dropdown-menu-sm-end[data-bs-popper] {\n    right: 0;\n    left: auto;\n  }\n}\n@media (min-width: 768px) {\n  .dropdown-menu-md-start {\n    --bs-position: start;\n  }\n  .dropdown-menu-md-start[data-bs-popper] {\n    right: auto;\n    left: 0;\n  }\n\n  .dropdown-menu-md-end {\n    --bs-position: end;\n  }\n  .dropdown-menu-md-end[data-bs-popper] {\n    right: 0;\n    left: auto;\n  }\n}\n@media (min-width: 992px) {\n  .dropdown-menu-lg-start {\n    --bs-position: start;\n  }\n  .dropdown-menu-lg-start[data-bs-popper] {\n    right: auto;\n    left: 0;\n  }\n\n  .dropdown-menu-lg-end {\n    --bs-position: end;\n  }\n  .dropdown-menu-lg-end[data-bs-popper] {\n    right: 0;\n    left: auto;\n  }\n}\n@media (min-width: 1200px) {\n  .dropdown-menu-xl-start {\n    --bs-position: start;\n  }\n  .dropdown-menu-xl-start[data-bs-popper] {\n    right: auto;\n    left: 0;\n  }\n\n  .dropdown-menu-xl-end {\n    --bs-position: end;\n  }\n  .dropdown-menu-xl-end[data-bs-popper] {\n    right: 0;\n    left: auto;\n  }\n}\n@media (min-width: 1400px) {\n  .dropdown-menu-xxl-start {\n    --bs-position: start;\n  }\n  .dropdown-menu-xxl-start[data-bs-popper] {\n    right: auto;\n    left: 0;\n  }\n\n  .dropdown-menu-xxl-end {\n    --bs-position: end;\n  }\n  .dropdown-menu-xxl-end[data-bs-popper] {\n    right: 0;\n    left: auto;\n  }\n}\n.dropup .dropdown-menu[data-bs-popper] {\n  top: auto;\n  bottom: 100%;\n  margin-top: 0;\n  margin-bottom: 0.125rem;\n}\n.dropup .dropdown-toggle::after {\n  display: inline-block;\n  margin-left: 0.255em;\n  vertical-align: 0.255em;\n  content: \"\";\n  border-top: 0;\n  border-right: 0.3em solid transparent;\n  border-bottom: 0.3em solid;\n  border-left: 0.3em solid transparent;\n}\n.dropup .dropdown-toggle:empty::after {\n  margin-left: 0;\n}\n\n.dropend .dropdown-menu[data-bs-popper] {\n  top: 0;\n  right: auto;\n  left: 100%;\n  margin-top: 0;\n  margin-left: 0.125rem;\n}\n.dropend .dropdown-toggle::after {\n  display: inline-block;\n  margin-left: 0.255em;\n  vertical-align: 0.255em;\n  content: \"\";\n  border-top: 0.3em solid transparent;\n  border-right: 0;\n  border-bottom: 0.3em solid transparent;\n  border-left: 0.3em solid;\n}\n.dropend .dropdown-toggle:empty::after {\n  margin-left: 0;\n}\n.dropend .dropdown-toggle::after {\n  vertical-align: 0;\n}\n\n.dropstart .dropdown-menu[data-bs-popper] {\n  top: 0;\n  right: 100%;\n  left: auto;\n  margin-top: 0;\n  margin-right: 0.125rem;\n}\n.dropstart .dropdown-toggle::after {\n  display: inline-block;\n  margin-left: 0.255em;\n  vertical-align: 0.255em;\n  content: \"\";\n}\n.dropstart .dropdown-toggle::after {\n  display: none;\n}\n.dropstart .dropdown-toggle::before {\n  display: inline-block;\n  margin-right: 0.255em;\n  vertical-align: 0.255em;\n  content: \"\";\n  border-top: 0.3em solid transparent;\n  border-right: 0.3em solid;\n  border-bottom: 0.3em solid transparent;\n}\n.dropstart .dropdown-toggle:empty::after {\n  margin-left: 0;\n}\n.dropstart .dropdown-toggle::before {\n  vertical-align: 0;\n}\n\n.dropdown-divider {\n  height: 0;\n  margin: 0.5rem 0;\n  overflow: hidden;\n  border-top: 1px solid rgba(0, 0, 0, 0.15);\n}\n\n.dropdown-item {\n  display: block;\n  width: 100%;\n  padding: 0.25rem 1rem;\n  clear: both;\n  font-weight: 400;\n  color: #212529;\n  text-align: inherit;\n  text-decoration: none;\n  white-space: nowrap;\n  background-color: transparent;\n  border: 0;\n}\n.dropdown-item:hover, .dropdown-item:focus {\n  color: #1e2125;\n  background-color: #e9ecef;\n}\n.dropdown-item.active, .dropdown-item:active {\n  color: #fff;\n  text-decoration: none;\n  background-color: #0d6efd;\n}\n.dropdown-item.disabled, .dropdown-item:disabled {\n  color: #adb5bd;\n  pointer-events: none;\n  background-color: transparent;\n}\n\n.dropdown-menu.show {\n  display: block;\n}\n\n.dropdown-header {\n  display: block;\n  padding: 0.5rem 1rem;\n  margin-bottom: 0;\n  font-size: 0.875rem;\n  color: #6c757d;\n  white-space: nowrap;\n}\n\n.dropdown-item-text {\n  display: block;\n  padding: 0.25rem 1rem;\n  color: #212529;\n}\n\n.dropdown-menu-dark {\n  color: #dee2e6;\n  background-color: #343a40;\n  border-color: rgba(0, 0, 0, 0.15);\n}\n.dropdown-menu-dark .dropdown-item {\n  color: #dee2e6;\n}\n.dropdown-menu-dark .dropdown-item:hover, .dropdown-menu-dark .dropdown-item:focus {\n  color: #fff;\n  background-color: rgba(255, 255, 255, 0.15);\n}\n.dropdown-menu-dark .dropdown-item.active, .dropdown-menu-dark .dropdown-item:active {\n  color: #fff;\n  background-color: #0d6efd;\n}\n.dropdown-menu-dark .dropdown-item.disabled, .dropdown-menu-dark .dropdown-item:disabled {\n  color: #adb5bd;\n}\n.dropdown-menu-dark .dropdown-divider {\n  border-color: rgba(0, 0, 0, 0.15);\n}\n.dropdown-menu-dark .dropdown-item-text {\n  color: #dee2e6;\n}\n.dropdown-menu-dark .dropdown-header {\n  color: #adb5bd;\n}\n\n.btn-group,\n.btn-group-vertical {\n  position: relative;\n  display: inline-flex;\n  vertical-align: middle;\n}\n.btn-group > .btn,\n.btn-group-vertical > .btn {\n  position: relative;\n  flex: 1 1 auto;\n}\n.btn-group > .btn-check:checked + .btn,\n.btn-group > .btn-check:focus + .btn,\n.btn-group > .btn:hover,\n.btn-group > .btn:focus,\n.btn-group > .btn:active,\n.btn-group > .btn.active,\n.btn-group-vertical > .btn-check:checked + .btn,\n.btn-group-vertical > .btn-check:focus + .btn,\n.btn-group-vertical > .btn:hover,\n.btn-group-vertical > .btn:focus,\n.btn-group-vertical > .btn:active,\n.btn-group-vertical > .btn.active {\n  z-index: 1;\n}\n\n.btn-toolbar {\n  display: flex;\n  flex-wrap: wrap;\n  justify-content: flex-start;\n}\n.btn-toolbar .input-group {\n  width: auto;\n}\n\n.btn-group > .btn:not(:first-child),\n.btn-group > .btn-group:not(:first-child) {\n  margin-left: -1px;\n}\n.btn-group > .btn:not(:last-child):not(.dropdown-toggle),\n.btn-group > .btn-group:not(:last-child) > .btn {\n  border-top-right-radius: 0;\n  border-bottom-right-radius: 0;\n}\n.btn-group > .btn:nth-child(n+3),\n.btn-group > :not(.btn-check) + .btn,\n.btn-group > .btn-group:not(:first-child) > .btn {\n  border-top-left-radius: 0;\n  border-bottom-left-radius: 0;\n}\n\n.dropdown-toggle-split {\n  padding-right: 0.5625rem;\n  padding-left: 0.5625rem;\n}\n.dropdown-toggle-split::after, .dropup .dropdown-toggle-split::after, .dropend .dropdown-toggle-split::after {\n  margin-left: 0;\n}\n.dropstart .dropdown-toggle-split::before {\n  margin-right: 0;\n}\n\n.btn-sm + .dropdown-toggle-split, .btn-group-sm > .btn + .dropdown-toggle-split {\n  padding-right: 0.375rem;\n  padding-left: 0.375rem;\n}\n\n.btn-lg + .dropdown-toggle-split, .btn-group-lg > .btn + .dropdown-toggle-split {\n  padding-right: 0.75rem;\n  padding-left: 0.75rem;\n}\n\n.btn-group-vertical {\n  flex-direction: column;\n  align-items: flex-start;\n  justify-content: center;\n}\n.btn-group-vertical > .btn,\n.btn-group-vertical > .btn-group {\n  width: 100%;\n}\n.btn-group-vertical > .btn:not(:first-child),\n.btn-group-vertical > .btn-group:not(:first-child) {\n  margin-top: -1px;\n}\n.btn-group-vertical > .btn:not(:last-child):not(.dropdown-toggle),\n.btn-group-vertical > .btn-group:not(:last-child) > .btn {\n  border-bottom-right-radius: 0;\n  border-bottom-left-radius: 0;\n}\n.btn-group-vertical > .btn ~ .btn,\n.btn-group-vertical > .btn-group:not(:first-child) > .btn {\n  border-top-left-radius: 0;\n  border-top-right-radius: 0;\n}\n\n.nav {\n  display: flex;\n  flex-wrap: wrap;\n  padding-left: 0;\n  margin-bottom: 0;\n  list-style: none;\n}\n\n.nav-link {\n  display: block;\n  padding: 0.5rem 1rem;\n  color: #0d6efd;\n  text-decoration: none;\n  transition: color 0.15s ease-in-out, background-color 0.15s ease-in-out, border-color 0.15s ease-in-out;\n}\n@media (prefers-reduced-motion: reduce) {\n  .nav-link {\n    transition: none;\n  }\n}\n.nav-link:hover, .nav-link:focus {\n  color: #0a58ca;\n}\n.nav-link.disabled {\n  color: #6c757d;\n  pointer-events: none;\n  cursor: default;\n}\n\n.nav-tabs {\n  border-bottom: 1px solid #dee2e6;\n}\n.nav-tabs .nav-link {\n  margin-bottom: -1px;\n  background: none;\n  border: 1px solid transparent;\n  border-top-left-radius: 0.25rem;\n  border-top-right-radius: 0.25rem;\n}\n.nav-tabs .nav-link:hover, .nav-tabs .nav-link:focus {\n  border-color: #e9ecef #e9ecef #dee2e6;\n  isolation: isolate;\n}\n.nav-tabs .nav-link.disabled {\n  color: #6c757d;\n  background-color: transparent;\n  border-color: transparent;\n}\n.nav-tabs .nav-link.active,\n.nav-tabs .nav-item.show .nav-link {\n  color: #495057;\n  background-color: #fff;\n  border-color: #dee2e6 #dee2e6 #fff;\n}\n.nav-tabs .dropdown-menu {\n  margin-top: -1px;\n  border-top-left-radius: 0;\n  border-top-right-radius: 0;\n}\n\n.nav-pills .nav-link {\n  background: none;\n  border: 0;\n  border-radius: 0.25rem;\n}\n.nav-pills .nav-link.active,\n.nav-pills .show > .nav-link {\n  color: #fff;\n  background-color: #0d6efd;\n}\n\n.nav-fill > .nav-link,\n.nav-fill .nav-item {\n  flex: 1 1 auto;\n  text-align: center;\n}\n\n.nav-justified > .nav-link,\n.nav-justified .nav-item {\n  flex-basis: 0;\n  flex-grow: 1;\n  text-align: center;\n}\n\n.nav-fill .nav-item .nav-link,\n.nav-justified .nav-item .nav-link {\n  width: 100%;\n}\n\n.tab-content > .tab-pane {\n  display: none;\n}\n.tab-content > .active {\n  display: block;\n}\n\n.navbar {\n  position: relative;\n  display: flex;\n  flex-wrap: wrap;\n  align-items: center;\n  justify-content: space-between;\n  padding-top: 0.5rem;\n  padding-bottom: 0.5rem;\n}\n.navbar > .container,\n.navbar > .container-fluid,\n.navbar > .container-sm,\n.navbar > .container-md,\n.navbar > .container-lg,\n.navbar > .container-xl,\n.navbar > .container-xxl {\n  display: flex;\n  flex-wrap: inherit;\n  align-items: center;\n  justify-content: space-between;\n}\n.navbar-brand {\n  padding-top: 0.3125rem;\n  padding-bottom: 0.3125rem;\n  margin-right: 1rem;\n  font-size: 1.25rem;\n  text-decoration: none;\n  white-space: nowrap;\n}\n.navbar-nav {\n  display: flex;\n  flex-direction: column;\n  padding-left: 0;\n  margin-bottom: 0;\n  list-style: none;\n}\n.navbar-nav .nav-link {\n  padding-right: 0;\n  padding-left: 0;\n}\n.navbar-nav .dropdown-menu {\n  position: static;\n}\n\n.navbar-text {\n  padding-top: 0.5rem;\n  padding-bottom: 0.5rem;\n}\n\n.navbar-collapse {\n  flex-basis: 100%;\n  flex-grow: 1;\n  align-items: center;\n}\n\n.navbar-toggler {\n  padding: 0.25rem 0.75rem;\n  font-size: 1.25rem;\n  line-height: 1;\n  background-color: transparent;\n  border: 1px solid transparent;\n  border-radius: 0.25rem;\n  transition: box-shadow 0.15s ease-in-out;\n}\n@media (prefers-reduced-motion: reduce) {\n  .navbar-toggler {\n    transition: none;\n  }\n}\n.navbar-toggler:hover {\n  text-decoration: none;\n}\n.navbar-toggler:focus {\n  text-decoration: none;\n  outline: 0;\n  box-shadow: 0 0 0 0.25rem;\n}\n\n.navbar-toggler-icon {\n  display: inline-block;\n  width: 1.5em;\n  height: 1.5em;\n  vertical-align: middle;\n  background-repeat: no-repeat;\n  background-position: center;\n  background-size: 100%;\n}\n\n.navbar-nav-scroll {\n  max-height: var(--bs-scroll-height, 75vh);\n  overflow-y: auto;\n}\n\n@media (min-width: 576px) {\n  .navbar-expand-sm {\n    flex-wrap: nowrap;\n    justify-content: flex-start;\n  }\n  .navbar-expand-sm .navbar-nav {\n    flex-direction: row;\n  }\n  .navbar-expand-sm .navbar-nav .dropdown-menu {\n    position: absolute;\n  }\n  .navbar-expand-sm .navbar-nav .nav-link {\n    padding-right: 0.5rem;\n    padding-left: 0.5rem;\n  }\n  .navbar-expand-sm .navbar-nav-scroll {\n    overflow: visible;\n  }\n  .navbar-expand-sm .navbar-collapse {\n    display: flex !important;\n    flex-basis: auto;\n  }\n  .navbar-expand-sm .navbar-toggler {\n    display: none;\n  }\n  .navbar-expand-sm .offcanvas-header {\n    display: none;\n  }\n  .navbar-expand-sm .offcanvas {\n    position: inherit;\n    bottom: 0;\n    z-index: 1000;\n    flex-grow: 1;\n    visibility: visible !important;\n    background-color: transparent;\n    border-right: 0;\n    border-left: 0;\n    transition: none;\n    transform: none;\n  }\n  .navbar-expand-sm .offcanvas-top,\n.navbar-expand-sm .offcanvas-bottom {\n    height: auto;\n    border-top: 0;\n    border-bottom: 0;\n  }\n  .navbar-expand-sm .offcanvas-body {\n    display: flex;\n    flex-grow: 0;\n    padding: 0;\n    overflow-y: visible;\n  }\n}\n@media (min-width: 768px) {\n  .navbar-expand-md {\n    flex-wrap: nowrap;\n    justify-content: flex-start;\n  }\n  .navbar-expand-md .navbar-nav {\n    flex-direction: row;\n  }\n  .navbar-expand-md .navbar-nav .dropdown-menu {\n    position: absolute;\n  }\n  .navbar-expand-md .navbar-nav .nav-link {\n    padding-right: 0.5rem;\n    padding-left: 0.5rem;\n  }\n  .navbar-expand-md .navbar-nav-scroll {\n    overflow: visible;\n  }\n  .navbar-expand-md .navbar-collapse {\n    display: flex !important;\n    flex-basis: auto;\n  }\n  .navbar-expand-md .navbar-toggler {\n    display: none;\n  }\n  .navbar-expand-md .offcanvas-header {\n    display: none;\n  }\n  .navbar-expand-md .offcanvas {\n    position: inherit;\n    bottom: 0;\n    z-index: 1000;\n    flex-grow: 1;\n    visibility: visible !important;\n    background-color: transparent;\n    border-right: 0;\n    border-left: 0;\n    transition: none;\n    transform: none;\n  }\n  .navbar-expand-md .offcanvas-top,\n.navbar-expand-md .offcanvas-bottom {\n    height: auto;\n    border-top: 0;\n    border-bottom: 0;\n  }\n  .navbar-expand-md .offcanvas-body {\n    display: flex;\n    flex-grow: 0;\n    padding: 0;\n    overflow-y: visible;\n  }\n}\n@media (min-width: 992px) {\n  .navbar-expand-lg {\n    flex-wrap: nowrap;\n    justify-content: flex-start;\n  }\n  .navbar-expand-lg .navbar-nav {\n    flex-direction: row;\n  }\n  .navbar-expand-lg .navbar-nav .dropdown-menu {\n    position: absolute;\n  }\n  .navbar-expand-lg .navbar-nav .nav-link {\n    padding-right: 0.5rem;\n    padding-left: 0.5rem;\n  }\n  .navbar-expand-lg .navbar-nav-scroll {\n    overflow: visible;\n  }\n  .navbar-expand-lg .navbar-collapse {\n    display: flex !important;\n    flex-basis: auto;\n  }\n  .navbar-expand-lg .navbar-toggler {\n    display: none;\n  }\n  .navbar-expand-lg .offcanvas-header {\n    display: none;\n  }\n  .navbar-expand-lg .offcanvas {\n    position: inherit;\n    bottom: 0;\n    z-index: 1000;\n    flex-grow: 1;\n    visibility: visible !important;\n    background-color: transparent;\n    border-right: 0;\n    border-left: 0;\n    transition: none;\n    transform: none;\n  }\n  .navbar-expand-lg .offcanvas-top,\n.navbar-expand-lg .offcanvas-bottom {\n    height: auto;\n    border-top: 0;\n    border-bottom: 0;\n  }\n  .navbar-expand-lg .offcanvas-body {\n    display: flex;\n    flex-grow: 0;\n    padding: 0;\n    overflow-y: visible;\n  }\n}\n@media (min-width: 1200px) {\n  .navbar-expand-xl {\n    flex-wrap: nowrap;\n    justify-content: flex-start;\n  }\n  .navbar-expand-xl .navbar-nav {\n    flex-direction: row;\n  }\n  .navbar-expand-xl .navbar-nav .dropdown-menu {\n    position: absolute;\n  }\n  .navbar-expand-xl .navbar-nav .nav-link {\n    padding-right: 0.5rem;\n    padding-left: 0.5rem;\n  }\n  .navbar-expand-xl .navbar-nav-scroll {\n    overflow: visible;\n  }\n  .navbar-expand-xl .navbar-collapse {\n    display: flex !important;\n    flex-basis: auto;\n  }\n  .navbar-expand-xl .navbar-toggler {\n    display: none;\n  }\n  .navbar-expand-xl .offcanvas-header {\n    display: none;\n  }\n  .navbar-expand-xl .offcanvas {\n    position: inherit;\n    bottom: 0;\n    z-index: 1000;\n    flex-grow: 1;\n    visibility: visible !important;\n    background-color: transparent;\n    border-right: 0;\n    border-left: 0;\n    transition: none;\n    transform: none;\n  }\n  .navbar-expand-xl .offcanvas-top,\n.navbar-expand-xl .offcanvas-bottom {\n    height: auto;\n    border-top: 0;\n    border-bottom: 0;\n  }\n  .navbar-expand-xl .offcanvas-body {\n    display: flex;\n    flex-grow: 0;\n    padding: 0;\n    overflow-y: visible;\n  }\n}\n@media (min-width: 1400px) {\n  .navbar-expand-xxl {\n    flex-wrap: nowrap;\n    justify-content: flex-start;\n  }\n  .navbar-expand-xxl .navbar-nav {\n    flex-direction: row;\n  }\n  .navbar-expand-xxl .navbar-nav .dropdown-menu {\n    position: absolute;\n  }\n  .navbar-expand-xxl .navbar-nav .nav-link {\n    padding-right: 0.5rem;\n    padding-left: 0.5rem;\n  }\n  .navbar-expand-xxl .navbar-nav-scroll {\n    overflow: visible;\n  }\n  .navbar-expand-xxl .navbar-collapse {\n    display: flex !important;\n    flex-basis: auto;\n  }\n  .navbar-expand-xxl .navbar-toggler {\n    display: none;\n  }\n  .navbar-expand-xxl .offcanvas-header {\n    display: none;\n  }\n  .navbar-expand-xxl .offcanvas {\n    position: inherit;\n    bottom: 0;\n    z-index: 1000;\n    flex-grow: 1;\n    visibility: visible !important;\n    background-color: transparent;\n    border-right: 0;\n    border-left: 0;\n    transition: none;\n    transform: none;\n  }\n  .navbar-expand-xxl .offcanvas-top,\n.navbar-expand-xxl .offcanvas-bottom {\n    height: auto;\n    border-top: 0;\n    border-bottom: 0;\n  }\n  .navbar-expand-xxl .offcanvas-body {\n    display: flex;\n    flex-grow: 0;\n    padding: 0;\n    overflow-y: visible;\n  }\n}\n.navbar-expand {\n  flex-wrap: nowrap;\n  justify-content: flex-start;\n}\n.navbar-expand .navbar-nav {\n  flex-direction: row;\n}\n.navbar-expand .navbar-nav .dropdown-menu {\n  position: absolute;\n}\n.navbar-expand .navbar-nav .nav-link {\n  padding-right: 0.5rem;\n  padding-left: 0.5rem;\n}\n.navbar-expand .navbar-nav-scroll {\n  overflow: visible;\n}\n.navbar-expand .navbar-collapse {\n  display: flex !important;\n  flex-basis: auto;\n}\n.navbar-expand .navbar-toggler {\n  display: none;\n}\n.navbar-expand .offcanvas-header {\n  display: none;\n}\n.navbar-expand .offcanvas {\n  position: inherit;\n  bottom: 0;\n  z-index: 1000;\n  flex-grow: 1;\n  visibility: visible !important;\n  background-color: transparent;\n  border-right: 0;\n  border-left: 0;\n  transition: none;\n  transform: none;\n}\n.navbar-expand .offcanvas-top,\n.navbar-expand .offcanvas-bottom {\n  height: auto;\n  border-top: 0;\n  border-bottom: 0;\n}\n.navbar-expand .offcanvas-body {\n  display: flex;\n  flex-grow: 0;\n  padding: 0;\n  overflow-y: visible;\n}\n\n.navbar-light .navbar-brand {\n  color: rgba(0, 0, 0, 0.9);\n}\n.navbar-light .navbar-brand:hover, .navbar-light .navbar-brand:focus {\n  color: rgba(0, 0, 0, 0.9);\n}\n.navbar-light .navbar-nav .nav-link {\n  color: rgba(0, 0, 0, 0.55);\n}\n.navbar-light .navbar-nav .nav-link:hover, .navbar-light .navbar-nav .nav-link:focus {\n  color: rgba(0, 0, 0, 0.7);\n}\n.navbar-light .navbar-nav .nav-link.disabled {\n  color: rgba(0, 0, 0, 0.3);\n}\n.navbar-light .navbar-nav .show > .nav-link,\n.navbar-light .navbar-nav .nav-link.active {\n  color: rgba(0, 0, 0, 0.9);\n}\n.navbar-light .navbar-toggler {\n  color: rgba(0, 0, 0, 0.55);\n  border-color: rgba(0, 0, 0, 0.1);\n}\n.navbar-light .navbar-toggler-icon {\n  background-image: url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 30 30'%3e%3cpath stroke='rgba%280, 0, 0, 0.55%29' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e\");\n}\n.navbar-light .navbar-text {\n  color: rgba(0, 0, 0, 0.55);\n}\n.navbar-light .navbar-text a,\n.navbar-light .navbar-text a:hover,\n.navbar-light .navbar-text a:focus {\n  color: rgba(0, 0, 0, 0.9);\n}\n\n.navbar-dark .navbar-brand {\n  color: #fff;\n}\n.navbar-dark .navbar-brand:hover, .navbar-dark .navbar-brand:focus {\n  color: #fff;\n}\n.navbar-dark .navbar-nav .nav-link {\n  color: rgba(255, 255, 255, 0.55);\n}\n.navbar-dark .navbar-nav .nav-link:hover, .navbar-dark .navbar-nav .nav-link:focus {\n  color: rgba(255, 255, 255, 0.75);\n}\n.navbar-dark .navbar-nav .nav-link.disabled {\n  color: rgba(255, 255, 255, 0.25);\n}\n.navbar-dark .navbar-nav .show > .nav-link,\n.navbar-dark .navbar-nav .nav-link.active {\n  color: #fff;\n}\n.navbar-dark .navbar-toggler {\n  color: rgba(255, 255, 255, 0.55);\n  border-color: rgba(255, 255, 255, 0.1);\n}\n.navbar-dark .navbar-toggler-icon {\n  background-image: 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\");\n}\n.navbar-dark .navbar-text {\n  color: rgba(255, 255, 255, 0.55);\n}\n.navbar-dark .navbar-text a,\n.navbar-dark .navbar-text a:hover,\n.navbar-dark .navbar-text a:focus {\n  color: #fff;\n}\n\n.card {\n  position: relative;\n  display: flex;\n  flex-direction: column;\n  min-width: 0;\n  word-wrap: break-word;\n  background-color: #fff;\n  background-clip: border-box;\n  border: 1px solid rgba(0, 0, 0, 0.125);\n  border-radius: 0.25rem;\n}\n.card > hr {\n  margin-right: 0;\n  margin-left: 0;\n}\n.card > .list-group {\n  border-top: inherit;\n  border-bottom: inherit;\n}\n.card > .list-group:first-child {\n  border-top-width: 0;\n  border-top-left-radius: calc(0.25rem - 1px);\n  border-top-right-radius: calc(0.25rem - 1px);\n}\n.card > .list-group:last-child {\n  border-bottom-width: 0;\n  border-bottom-right-radius: calc(0.25rem - 1px);\n  border-bottom-left-radius: calc(0.25rem - 1px);\n}\n.card > .card-header + .list-group,\n.card > .list-group + .card-footer {\n  border-top: 0;\n}\n\n.card-body {\n  flex: 1 1 auto;\n  padding: 1rem 1rem;\n}\n\n.card-title {\n  margin-bottom: 0.5rem;\n}\n\n.card-subtitle {\n  margin-top: -0.25rem;\n  margin-bottom: 0;\n}\n\n.card-text:last-child {\n  margin-bottom: 0;\n}\n\n.card-link + .card-link {\n  margin-left: 1rem;\n}\n\n.card-header {\n  padding: 0.5rem 1rem;\n  margin-bottom: 0;\n  background-color: rgba(0, 0, 0, 0.03);\n  border-bottom: 1px solid rgba(0, 0, 0, 0.125);\n}\n.card-header:first-child {\n  border-radius: calc(0.25rem - 1px) calc(0.25rem - 1px) 0 0;\n}\n\n.card-footer {\n  padding: 0.5rem 1rem;\n  background-color: rgba(0, 0, 0, 0.03);\n  border-top: 1px solid rgba(0, 0, 0, 0.125);\n}\n.card-footer:last-child {\n  border-radius: 0 0 calc(0.25rem - 1px) calc(0.25rem - 1px);\n}\n\n.card-header-tabs {\n  margin-right: -0.5rem;\n  margin-bottom: -0.5rem;\n  margin-left: -0.5rem;\n  border-bottom: 0;\n}\n\n.card-header-pills {\n  margin-right: -0.5rem;\n  margin-left: -0.5rem;\n}\n\n.card-img-overlay {\n  position: absolute;\n  top: 0;\n  right: 0;\n  bottom: 0;\n  left: 0;\n  padding: 1rem;\n  border-radius: calc(0.25rem - 1px);\n}\n\n.card-img,\n.card-img-top,\n.card-img-bottom {\n  width: 100%;\n}\n\n.card-img,\n.card-img-top {\n  border-top-left-radius: calc(0.25rem - 1px);\n  border-top-right-radius: calc(0.25rem - 1px);\n}\n\n.card-img,\n.card-img-bottom {\n  border-bottom-right-radius: calc(0.25rem - 1px);\n  border-bottom-left-radius: calc(0.25rem - 1px);\n}\n\n.card-group > .card {\n  margin-bottom: 0.75rem;\n}\n@media (min-width: 576px) {\n  .card-group {\n    display: flex;\n    flex-flow: row wrap;\n  }\n  .card-group > .card {\n    flex: 1 0 0%;\n    margin-bottom: 0;\n  }\n  .card-group > .card + .card {\n    margin-left: 0;\n    border-left: 0;\n  }\n  .card-group > .card:not(:last-child) {\n    border-top-right-radius: 0;\n    border-bottom-right-radius: 0;\n  }\n  .card-group > .card:not(:last-child) .card-img-top,\n.card-group > .card:not(:last-child) .card-header {\n    border-top-right-radius: 0;\n  }\n  .card-group > .card:not(:last-child) .card-img-bottom,\n.card-group > .card:not(:last-child) .card-footer {\n    border-bottom-right-radius: 0;\n  }\n  .card-group > .card:not(:first-child) {\n    border-top-left-radius: 0;\n    border-bottom-left-radius: 0;\n  }\n  .card-group > .card:not(:first-child) .card-img-top,\n.card-group > .card:not(:first-child) .card-header {\n    border-top-left-radius: 0;\n  }\n  .card-group > .card:not(:first-child) .card-img-bottom,\n.card-group > .card:not(:first-child) .card-footer {\n    border-bottom-left-radius: 0;\n  }\n}\n\n.accordion-button {\n  position: relative;\n  display: flex;\n  align-items: center;\n  width: 100%;\n  padding: 1rem 1.25rem;\n  font-size: 1rem;\n  color: #212529;\n  text-align: left;\n  background-color: #fff;\n  border: 0;\n  border-radius: 0;\n  overflow-anchor: none;\n  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;\n}\n@media (prefers-reduced-motion: reduce) {\n  .accordion-button {\n    transition: none;\n  }\n}\n.accordion-button:not(.collapsed) {\n  color: #0c63e4;\n  background-color: #e7f1ff;\n  box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.125);\n}\n.accordion-button:not(.collapsed)::after {\n  background-image: url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%230c63e4'%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-.708z'/%3e%3c/svg%3e\");\n  transform: rotate(-180deg);\n}\n.accordion-button::after {\n  flex-shrink: 0;\n  width: 1.25rem;\n  height: 1.25rem;\n  margin-left: auto;\n  content: \"\";\n  background-image: url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23212529'%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-.708z'/%3e%3c/svg%3e\");\n  background-repeat: no-repeat;\n  background-size: 1.25rem;\n  transition: transform 0.2s ease-in-out;\n}\n@media (prefers-reduced-motion: reduce) {\n  .accordion-button::after {\n    transition: none;\n  }\n}\n.accordion-button:hover {\n  z-index: 2;\n}\n.accordion-button:focus {\n  z-index: 3;\n  border-color: #86b7fe;\n  outline: 0;\n  box-shadow: 0 0 0 0.25rem rgba(13, 110, 253, 0.25);\n}\n\n.accordion-header {\n  margin-bottom: 0;\n}\n\n.accordion-item {\n  background-color: #fff;\n  border: 1px solid rgba(0, 0, 0, 0.125);\n}\n.accordion-item:first-of-type {\n  border-top-left-radius: 0.25rem;\n  border-top-right-radius: 0.25rem;\n}\n.accordion-item:first-of-type .accordion-button {\n  border-top-left-radius: calc(0.25rem - 1px);\n  border-top-right-radius: calc(0.25rem - 1px);\n}\n.accordion-item:not(:first-of-type) {\n  border-top: 0;\n}\n.accordion-item:last-of-type {\n  border-bottom-right-radius: 0.25rem;\n  border-bottom-left-radius: 0.25rem;\n}\n.accordion-item:last-of-type .accordion-button.collapsed {\n  border-bottom-right-radius: calc(0.25rem - 1px);\n  border-bottom-left-radius: calc(0.25rem - 1px);\n}\n.accordion-item:last-of-type .accordion-collapse {\n  border-bottom-right-radius: 0.25rem;\n  border-bottom-left-radius: 0.25rem;\n}\n\n.accordion-body {\n  padding: 1rem 1.25rem;\n}\n\n.accordion-flush .accordion-collapse {\n  border-width: 0;\n}\n.accordion-flush .accordion-item {\n  border-right: 0;\n  border-left: 0;\n  border-radius: 0;\n}\n.accordion-flush .accordion-item:first-child {\n  border-top: 0;\n}\n.accordion-flush .accordion-item:last-child {\n  border-bottom: 0;\n}\n.accordion-flush .accordion-item .accordion-button {\n  border-radius: 0;\n}\n\n.breadcrumb {\n  display: flex;\n  flex-wrap: wrap;\n  padding: 0 0;\n  margin-bottom: 1rem;\n  list-style: none;\n}\n\n.breadcrumb-item + .breadcrumb-item {\n  padding-left: 0.5rem;\n}\n.breadcrumb-item + .breadcrumb-item::before {\n  float: left;\n  padding-right: 0.5rem;\n  color: #6c757d;\n  content: var(--bs-breadcrumb-divider, \"/\") /* rtl: var(--bs-breadcrumb-divider, \"/\") */;\n}\n.breadcrumb-item.active {\n  color: #6c757d;\n}\n\n.pagination {\n  display: flex;\n  padding-left: 0;\n  list-style: none;\n}\n\n.page-link {\n  position: relative;\n  display: block;\n  color: #0d6efd;\n  text-decoration: none;\n  background-color: #fff;\n  border: 1px solid #dee2e6;\n  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;\n}\n@media (prefers-reduced-motion: reduce) {\n  .page-link {\n    transition: none;\n  }\n}\n.page-link:hover {\n  z-index: 2;\n  color: #0a58ca;\n  background-color: #e9ecef;\n  border-color: #dee2e6;\n}\n.page-link:focus {\n  z-index: 3;\n  color: #0a58ca;\n  background-color: #e9ecef;\n  outline: 0;\n  box-shadow: 0 0 0 0.25rem rgba(13, 110, 253, 0.25);\n}\n\n.page-item:not(:first-child) .page-link {\n  margin-left: -1px;\n}\n.page-item.active .page-link {\n  z-index: 3;\n  color: #fff;\n  background-color: #0d6efd;\n  border-color: #0d6efd;\n}\n.page-item.disabled .page-link {\n  color: #6c757d;\n  pointer-events: none;\n  background-color: #fff;\n  border-color: #dee2e6;\n}\n\n.page-link {\n  padding: 0.375rem 0.75rem;\n}\n\n.page-item:first-child .page-link {\n  border-top-left-radius: 0.25rem;\n  border-bottom-left-radius: 0.25rem;\n}\n.page-item:last-child .page-link {\n  border-top-right-radius: 0.25rem;\n  border-bottom-right-radius: 0.25rem;\n}\n\n.pagination-lg .page-link {\n  padding: 0.75rem 1.5rem;\n  font-size: 1.25rem;\n}\n.pagination-lg .page-item:first-child .page-link {\n  border-top-left-radius: 0.3rem;\n  border-bottom-left-radius: 0.3rem;\n}\n.pagination-lg .page-item:last-child .page-link {\n  border-top-right-radius: 0.3rem;\n  border-bottom-right-radius: 0.3rem;\n}\n\n.pagination-sm .page-link {\n  padding: 0.25rem 0.5rem;\n  font-size: 0.875rem;\n}\n.pagination-sm .page-item:first-child .page-link {\n  border-top-left-radius: 0.2rem;\n  border-bottom-left-radius: 0.2rem;\n}\n.pagination-sm .page-item:last-child .page-link {\n  border-top-right-radius: 0.2rem;\n  border-bottom-right-radius: 0.2rem;\n}\n\n.badge {\n  display: inline-block;\n  padding: 0.35em 0.65em;\n  font-size: 0.75em;\n  font-weight: 700;\n  line-height: 1;\n  color: #fff;\n  text-align: center;\n  white-space: nowrap;\n  vertical-align: baseline;\n  border-radius: 0.25rem;\n}\n.badge:empty {\n  display: none;\n}\n\n.btn .badge {\n  position: relative;\n  top: -1px;\n}\n\n.alert {\n  position: relative;\n  padding: 1rem 1rem;\n  margin-bottom: 1rem;\n  border: 1px solid transparent;\n  border-radius: 0.25rem;\n}\n\n.alert-heading {\n  color: inherit;\n}\n\n.alert-link {\n  font-weight: 700;\n}\n\n.alert-dismissible {\n  padding-right: 3rem;\n}\n.alert-dismissible .btn-close {\n  position: absolute;\n  top: 0;\n  right: 0;\n  z-index: 2;\n  padding: 1.25rem 1rem;\n}\n\n.alert-primary {\n  color: #084298;\n  background-color: #cfe2ff;\n  border-color: #b6d4fe;\n}\n.alert-primary .alert-link {\n  color: #06357a;\n}\n\n.alert-secondary {\n  color: #41464b;\n  background-color: #e2e3e5;\n  border-color: #d3d6d8;\n}\n.alert-secondary .alert-link {\n  color: #34383c;\n}\n\n.alert-success {\n  color: #0f5132;\n  background-color: #d1e7dd;\n  border-color: #badbcc;\n}\n.alert-success .alert-link {\n  color: #0c4128;\n}\n\n.alert-info {\n  color: #055160;\n  background-color: #cff4fc;\n  border-color: #b6effb;\n}\n.alert-info .alert-link {\n  color: #04414d;\n}\n\n.alert-warning {\n  color: #664d03;\n  background-color: #fff3cd;\n  border-color: #ffecb5;\n}\n.alert-warning .alert-link {\n  color: #523e02;\n}\n\n.alert-danger {\n  color: #842029;\n  background-color: #f8d7da;\n  border-color: #f5c2c7;\n}\n.alert-danger .alert-link {\n  color: #6a1a21;\n}\n\n.alert-light {\n  color: #636464;\n  background-color: #fefefe;\n  border-color: #fdfdfe;\n}\n.alert-light .alert-link {\n  color: #4f5050;\n}\n\n.alert-dark {\n  color: #141619;\n  background-color: #d3d3d4;\n  border-color: #bcbebf;\n}\n.alert-dark .alert-link {\n  color: #101214;\n}\n\n@-webkit-keyframes progress-bar-stripes {\n  0% {\n    background-position-x: 1rem;\n  }\n}\n\n@keyframes progress-bar-stripes {\n  0% {\n    background-position-x: 1rem;\n  }\n}\n.progress {\n  display: flex;\n  height: 1rem;\n  overflow: hidden;\n  font-size: 0.75rem;\n  background-color: #e9ecef;\n  border-radius: 0.25rem;\n}\n\n.progress-bar {\n  display: flex;\n  flex-direction: column;\n  justify-content: center;\n  overflow: hidden;\n  color: #fff;\n  text-align: center;\n  white-space: nowrap;\n  background-color: #0d6efd;\n  transition: width 0.6s ease;\n}\n@media (prefers-reduced-motion: reduce) {\n  .progress-bar {\n    transition: none;\n  }\n}\n\n.progress-bar-striped {\n  background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n  background-size: 1rem 1rem;\n}\n\n.progress-bar-animated {\n  -webkit-animation: 1s linear infinite progress-bar-stripes;\n  animation: 1s linear infinite progress-bar-stripes;\n}\n@media (prefers-reduced-motion: reduce) {\n  .progress-bar-animated {\n    -webkit-animation: none;\n    animation: none;\n  }\n}\n\n.list-group {\n  display: flex;\n  flex-direction: column;\n  padding-left: 0;\n  margin-bottom: 0;\n  border-radius: 0.25rem;\n}\n\n.list-group-numbered {\n  list-style-type: none;\n  counter-reset: section;\n}\n.list-group-numbered > li::before {\n  content: counters(section, \".\") \". \";\n  counter-increment: section;\n}\n\n.list-group-item-action {\n  width: 100%;\n  color: #495057;\n  text-align: inherit;\n}\n.list-group-item-action:hover, .list-group-item-action:focus {\n  z-index: 1;\n  color: #495057;\n  text-decoration: none;\n  background-color: #f8f9fa;\n}\n.list-group-item-action:active {\n  color: #212529;\n  background-color: #e9ecef;\n}\n\n.list-group-item {\n  position: relative;\n  display: block;\n  padding: 0.5rem 1rem;\n  color: #212529;\n  text-decoration: none;\n  background-color: #fff;\n  border: 1px solid rgba(0, 0, 0, 0.125);\n}\n.list-group-item:first-child {\n  border-top-left-radius: inherit;\n  border-top-right-radius: inherit;\n}\n.list-group-item:last-child {\n  border-bottom-right-radius: inherit;\n  border-bottom-left-radius: inherit;\n}\n.list-group-item.disabled, .list-group-item:disabled {\n  color: #6c757d;\n  pointer-events: none;\n  background-color: #fff;\n}\n.list-group-item.active {\n  z-index: 2;\n  color: #fff;\n  background-color: #0d6efd;\n  border-color: #0d6efd;\n}\n.list-group-item + .list-group-item {\n  border-top-width: 0;\n}\n.list-group-item + .list-group-item.active {\n  margin-top: -1px;\n  border-top-width: 1px;\n}\n\n.list-group-horizontal {\n  flex-direction: row;\n}\n.list-group-horizontal > .list-group-item:first-child {\n  border-bottom-left-radius: 0.25rem;\n  border-top-right-radius: 0;\n}\n.list-group-horizontal > .list-group-item:last-child {\n  border-top-right-radius: 0.25rem;\n  border-bottom-left-radius: 0;\n}\n.list-group-horizontal > .list-group-item.active {\n  margin-top: 0;\n}\n.list-group-horizontal > .list-group-item + .list-group-item {\n  border-top-width: 1px;\n  border-left-width: 0;\n}\n.list-group-horizontal > .list-group-item + .list-group-item.active {\n  margin-left: -1px;\n  border-left-width: 1px;\n}\n\n@media (min-width: 576px) {\n  .list-group-horizontal-sm {\n    flex-direction: row;\n  }\n  .list-group-horizontal-sm > .list-group-item:first-child {\n    border-bottom-left-radius: 0.25rem;\n    border-top-right-radius: 0;\n  }\n  .list-group-horizontal-sm > .list-group-item:last-child {\n    border-top-right-radius: 0.25rem;\n    border-bottom-left-radius: 0;\n  }\n  .list-group-horizontal-sm > .list-group-item.active {\n    margin-top: 0;\n  }\n  .list-group-horizontal-sm > .list-group-item + .list-group-item {\n    border-top-width: 1px;\n    border-left-width: 0;\n  }\n  .list-group-horizontal-sm > .list-group-item + .list-group-item.active {\n    margin-left: -1px;\n    border-left-width: 1px;\n  }\n}\n@media (min-width: 768px) {\n  .list-group-horizontal-md {\n    flex-direction: row;\n  }\n  .list-group-horizontal-md > .list-group-item:first-child {\n    border-bottom-left-radius: 0.25rem;\n    border-top-right-radius: 0;\n  }\n  .list-group-horizontal-md > .list-group-item:last-child {\n    border-top-right-radius: 0.25rem;\n    border-bottom-left-radius: 0;\n  }\n  .list-group-horizontal-md > .list-group-item.active {\n    margin-top: 0;\n  }\n  .list-group-horizontal-md > .list-group-item + .list-group-item {\n    border-top-width: 1px;\n    border-left-width: 0;\n  }\n  .list-group-horizontal-md > .list-group-item + .list-group-item.active {\n    margin-left: -1px;\n    border-left-width: 1px;\n  }\n}\n@media (min-width: 992px) {\n  .list-group-horizontal-lg {\n    flex-direction: row;\n  }\n  .list-group-horizontal-lg > .list-group-item:first-child {\n    border-bottom-left-radius: 0.25rem;\n    border-top-right-radius: 0;\n  }\n  .list-group-horizontal-lg > .list-group-item:last-child {\n    border-top-right-radius: 0.25rem;\n    border-bottom-left-radius: 0;\n  }\n  .list-group-horizontal-lg > .list-group-item.active {\n    margin-top: 0;\n  }\n  .list-group-horizontal-lg > .list-group-item + .list-group-item {\n    border-top-width: 1px;\n    border-left-width: 0;\n  }\n  .list-group-horizontal-lg > .list-group-item + .list-group-item.active {\n    margin-left: -1px;\n    border-left-width: 1px;\n  }\n}\n@media (min-width: 1200px) {\n  .list-group-horizontal-xl {\n    flex-direction: row;\n  }\n  .list-group-horizontal-xl > .list-group-item:first-child {\n    border-bottom-left-radius: 0.25rem;\n    border-top-right-radius: 0;\n  }\n  .list-group-horizontal-xl > .list-group-item:last-child {\n    border-top-right-radius: 0.25rem;\n    border-bottom-left-radius: 0;\n  }\n  .list-group-horizontal-xl > .list-group-item.active {\n    margin-top: 0;\n  }\n  .list-group-horizontal-xl > .list-group-item + .list-group-item {\n    border-top-width: 1px;\n    border-left-width: 0;\n  }\n  .list-group-horizontal-xl > .list-group-item + .list-group-item.active {\n    margin-left: -1px;\n    border-left-width: 1px;\n  }\n}\n@media (min-width: 1400px) {\n  .list-group-horizontal-xxl {\n    flex-direction: row;\n  }\n  .list-group-horizontal-xxl > .list-group-item:first-child {\n    border-bottom-left-radius: 0.25rem;\n    border-top-right-radius: 0;\n  }\n  .list-group-horizontal-xxl > .list-group-item:last-child {\n    border-top-right-radius: 0.25rem;\n    border-bottom-left-radius: 0;\n  }\n  .list-group-horizontal-xxl > .list-group-item.active {\n    margin-top: 0;\n  }\n  .list-group-horizontal-xxl > .list-group-item + .list-group-item {\n    border-top-width: 1px;\n    border-left-width: 0;\n  }\n  .list-group-horizontal-xxl > .list-group-item + .list-group-item.active {\n    margin-left: -1px;\n    border-left-width: 1px;\n  }\n}\n.list-group-flush {\n  border-radius: 0;\n}\n.list-group-flush > .list-group-item {\n  border-width: 0 0 1px;\n}\n.list-group-flush > .list-group-item:last-child {\n  border-bottom-width: 0;\n}\n\n.list-group-item-primary {\n  color: #084298;\n  background-color: #cfe2ff;\n}\n.list-group-item-primary.list-group-item-action:hover, .list-group-item-primary.list-group-item-action:focus {\n  color: #084298;\n  background-color: #bacbe6;\n}\n.list-group-item-primary.list-group-item-action.active {\n  color: #fff;\n  background-color: #084298;\n  border-color: #084298;\n}\n\n.list-group-item-secondary {\n  color: #41464b;\n  background-color: #e2e3e5;\n}\n.list-group-item-secondary.list-group-item-action:hover, .list-group-item-secondary.list-group-item-action:focus {\n  color: #41464b;\n  background-color: #cbccce;\n}\n.list-group-item-secondary.list-group-item-action.active {\n  color: #fff;\n  background-color: #41464b;\n  border-color: #41464b;\n}\n\n.list-group-item-success {\n  color: #0f5132;\n  background-color: #d1e7dd;\n}\n.list-group-item-success.list-group-item-action:hover, .list-group-item-success.list-group-item-action:focus {\n  color: #0f5132;\n  background-color: #bcd0c7;\n}\n.list-group-item-success.list-group-item-action.active {\n  color: #fff;\n  background-color: #0f5132;\n  border-color: #0f5132;\n}\n\n.list-group-item-info {\n  color: #055160;\n  background-color: #cff4fc;\n}\n.list-group-item-info.list-group-item-action:hover, .list-group-item-info.list-group-item-action:focus {\n  color: #055160;\n  background-color: #badce3;\n}\n.list-group-item-info.list-group-item-action.active {\n  color: #fff;\n  background-color: #055160;\n  border-color: #055160;\n}\n\n.list-group-item-warning {\n  color: #664d03;\n  background-color: #fff3cd;\n}\n.list-group-item-warning.list-group-item-action:hover, .list-group-item-warning.list-group-item-action:focus {\n  color: #664d03;\n  background-color: #e6dbb9;\n}\n.list-group-item-warning.list-group-item-action.active {\n  color: #fff;\n  background-color: #664d03;\n  border-color: #664d03;\n}\n\n.list-group-item-danger {\n  color: #842029;\n  background-color: #f8d7da;\n}\n.list-group-item-danger.list-group-item-action:hover, .list-group-item-danger.list-group-item-action:focus {\n  color: #842029;\n  background-color: #dfc2c4;\n}\n.list-group-item-danger.list-group-item-action.active {\n  color: #fff;\n  background-color: #842029;\n  border-color: #842029;\n}\n\n.list-group-item-light {\n  color: #636464;\n  background-color: #fefefe;\n}\n.list-group-item-light.list-group-item-action:hover, .list-group-item-light.list-group-item-action:focus {\n  color: #636464;\n  background-color: #e5e5e5;\n}\n.list-group-item-light.list-group-item-action.active {\n  color: #fff;\n  background-color: #636464;\n  border-color: #636464;\n}\n\n.list-group-item-dark {\n  color: #141619;\n  background-color: #d3d3d4;\n}\n.list-group-item-dark.list-group-item-action:hover, .list-group-item-dark.list-group-item-action:focus {\n  color: #141619;\n  background-color: #bebebf;\n}\n.list-group-item-dark.list-group-item-action.active {\n  color: #fff;\n  background-color: #141619;\n  border-color: #141619;\n}\n\n.btn-close {\n  box-sizing: content-box;\n  width: 1em;\n  height: 1em;\n  padding: 0.25em 0.25em;\n  color: #000;\n  background: transparent 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 011.414 0L8 6.586 14.293.293a1 1 0 111.414 1.414L9.414 8l6.293 6.293a1 1 0 01-1.414 1.414L8 9.414l-6.293 6.293a1 1 0 01-1.414-1.414L6.586 8 .293 1.707a1 1 0 010-1.414z'/%3e%3c/svg%3e\") center/1em auto no-repeat;\n  border: 0;\n  border-radius: 0.25rem;\n  opacity: 0.5;\n}\n.btn-close:hover {\n  color: #000;\n  text-decoration: none;\n  opacity: 0.75;\n}\n.btn-close:focus {\n  outline: 0;\n  box-shadow: 0 0 0 0.25rem rgba(13, 110, 253, 0.25);\n  opacity: 1;\n}\n.btn-close:disabled, .btn-close.disabled {\n  pointer-events: none;\n  -webkit-user-select: none;\n  -moz-user-select: none;\n  user-select: none;\n  opacity: 0.25;\n}\n\n.btn-close-white {\n  filter: invert(1) grayscale(100%) brightness(200%);\n}\n\n.toast {\n  width: 350px;\n  max-width: 100%;\n  font-size: 0.875rem;\n  pointer-events: auto;\n  background-color: rgba(255, 255, 255, 0.85);\n  background-clip: padding-box;\n  border: 1px solid rgba(0, 0, 0, 0.1);\n  box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.15);\n  border-radius: 0.25rem;\n}\n.toast.showing {\n  opacity: 0;\n}\n.toast:not(.show) {\n  display: none;\n}\n\n.toast-container {\n  width: -webkit-max-content;\n  width: -moz-max-content;\n  width: max-content;\n  max-width: 100%;\n  pointer-events: none;\n}\n.toast-container > :not(:last-child) {\n  margin-bottom: 0.75rem;\n}\n\n.toast-header {\n  display: flex;\n  align-items: center;\n  padding: 0.5rem 0.75rem;\n  color: #6c757d;\n  background-color: rgba(255, 255, 255, 0.85);\n  background-clip: padding-box;\n  border-bottom: 1px solid rgba(0, 0, 0, 0.05);\n  border-top-left-radius: calc(0.25rem - 1px);\n  border-top-right-radius: calc(0.25rem - 1px);\n}\n.toast-header .btn-close {\n  margin-right: -0.375rem;\n  margin-left: 0.75rem;\n}\n\n.toast-body {\n  padding: 0.75rem;\n  word-wrap: break-word;\n}\n\n.modal {\n  position: fixed;\n  top: 0;\n  left: 0;\n  z-index: 1055;\n  display: none;\n  width: 100%;\n  height: 100%;\n  overflow-x: hidden;\n  overflow-y: auto;\n  outline: 0;\n}\n\n.modal-dialog {\n  position: relative;\n  width: auto;\n  margin: 0.5rem;\n  pointer-events: none;\n}\n.modal.fade .modal-dialog {\n  transition: transform 0.3s ease-out;\n  transform: translate(0, -50px);\n}\n@media (prefers-reduced-motion: reduce) {\n  .modal.fade .modal-dialog {\n    transition: none;\n  }\n}\n.modal.show .modal-dialog {\n  transform: none;\n}\n.modal.modal-static .modal-dialog {\n  transform: scale(1.02);\n}\n\n.modal-dialog-scrollable {\n  height: calc(100% - 1rem);\n}\n.modal-dialog-scrollable .modal-content {\n  max-height: 100%;\n  overflow: hidden;\n}\n.modal-dialog-scrollable .modal-body {\n  overflow-y: auto;\n}\n\n.modal-dialog-centered {\n  display: flex;\n  align-items: center;\n  min-height: calc(100% - 1rem);\n}\n\n.modal-content {\n  position: relative;\n  display: flex;\n  flex-direction: column;\n  width: 100%;\n  pointer-events: auto;\n  background-color: #fff;\n  background-clip: padding-box;\n  border: 1px solid rgba(0, 0, 0, 0.2);\n  border-radius: 0.3rem;\n  outline: 0;\n}\n\n.modal-backdrop {\n  position: fixed;\n  top: 0;\n  left: 0;\n  z-index: 1050;\n  width: 100vw;\n  height: 100vh;\n  background-color: #000;\n}\n.modal-backdrop.fade {\n  opacity: 0;\n}\n.modal-backdrop.show {\n  opacity: 0.5;\n}\n\n.modal-header {\n  display: flex;\n  flex-shrink: 0;\n  align-items: center;\n  justify-content: space-between;\n  padding: 1rem 1rem;\n  border-bottom: 1px solid #dee2e6;\n  border-top-left-radius: calc(0.3rem - 1px);\n  border-top-right-radius: calc(0.3rem - 1px);\n}\n.modal-header .btn-close {\n  padding: 0.5rem 0.5rem;\n  margin: -0.5rem -0.5rem -0.5rem auto;\n}\n\n.modal-title {\n  margin-bottom: 0;\n  line-height: 1.5;\n}\n\n.modal-body {\n  position: relative;\n  flex: 1 1 auto;\n  padding: 1rem;\n}\n\n.modal-footer {\n  display: flex;\n  flex-wrap: wrap;\n  flex-shrink: 0;\n  align-items: center;\n  justify-content: flex-end;\n  padding: 0.75rem;\n  border-top: 1px solid #dee2e6;\n  border-bottom-right-radius: calc(0.3rem - 1px);\n  border-bottom-left-radius: calc(0.3rem - 1px);\n}\n.modal-footer > * {\n  margin: 0.25rem;\n}\n\n@media (min-width: 576px) {\n  .modal-dialog {\n    max-width: 500px;\n    margin: 1.75rem auto;\n  }\n\n  .modal-dialog-scrollable {\n    height: calc(100% - 3.5rem);\n  }\n\n  .modal-dialog-centered {\n    min-height: calc(100% - 3.5rem);\n  }\n\n  .modal-sm {\n    max-width: 300px;\n  }\n}\n@media (min-width: 992px) {\n  .modal-lg,\n.modal-xl {\n    max-width: 800px;\n  }\n}\n@media (min-width: 1200px) {\n  .modal-xl {\n    max-width: 1140px;\n  }\n}\n.modal-fullscreen {\n  width: 100vw;\n  max-width: none;\n  height: 100%;\n  margin: 0;\n}\n.modal-fullscreen .modal-content {\n  height: 100%;\n  border: 0;\n  border-radius: 0;\n}\n.modal-fullscreen .modal-header {\n  border-radius: 0;\n}\n.modal-fullscreen .modal-body {\n  overflow-y: auto;\n}\n.modal-fullscreen .modal-footer {\n  border-radius: 0;\n}\n\n@media (max-width: 575.98px) {\n  .modal-fullscreen-sm-down {\n    width: 100vw;\n    max-width: none;\n    height: 100%;\n    margin: 0;\n  }\n  .modal-fullscreen-sm-down .modal-content {\n    height: 100%;\n    border: 0;\n    border-radius: 0;\n  }\n  .modal-fullscreen-sm-down .modal-header {\n    border-radius: 0;\n  }\n  .modal-fullscreen-sm-down .modal-body {\n    overflow-y: auto;\n  }\n  .modal-fullscreen-sm-down .modal-footer {\n    border-radius: 0;\n  }\n}\n@media (max-width: 767.98px) {\n  .modal-fullscreen-md-down {\n    width: 100vw;\n    max-width: none;\n    height: 100%;\n    margin: 0;\n  }\n  .modal-fullscreen-md-down .modal-content {\n    height: 100%;\n    border: 0;\n    border-radius: 0;\n  }\n  .modal-fullscreen-md-down .modal-header {\n    border-radius: 0;\n  }\n  .modal-fullscreen-md-down .modal-body {\n    overflow-y: auto;\n  }\n  .modal-fullscreen-md-down .modal-footer {\n    border-radius: 0;\n  }\n}\n@media (max-width: 991.98px) {\n  .modal-fullscreen-lg-down {\n    width: 100vw;\n    max-width: none;\n    height: 100%;\n    margin: 0;\n  }\n  .modal-fullscreen-lg-down .modal-content {\n    height: 100%;\n    border: 0;\n    border-radius: 0;\n  }\n  .modal-fullscreen-lg-down .modal-header {\n    border-radius: 0;\n  }\n  .modal-fullscreen-lg-down .modal-body {\n    overflow-y: auto;\n  }\n  .modal-fullscreen-lg-down .modal-footer {\n    border-radius: 0;\n  }\n}\n@media (max-width: 1199.98px) {\n  .modal-fullscreen-xl-down {\n    width: 100vw;\n    max-width: none;\n    height: 100%;\n    margin: 0;\n  }\n  .modal-fullscreen-xl-down .modal-content {\n    height: 100%;\n    border: 0;\n    border-radius: 0;\n  }\n  .modal-fullscreen-xl-down .modal-header {\n    border-radius: 0;\n  }\n  .modal-fullscreen-xl-down .modal-body {\n    overflow-y: auto;\n  }\n  .modal-fullscreen-xl-down .modal-footer {\n    border-radius: 0;\n  }\n}\n@media (max-width: 1399.98px) {\n  .modal-fullscreen-xxl-down {\n    width: 100vw;\n    max-width: none;\n    height: 100%;\n    margin: 0;\n  }\n  .modal-fullscreen-xxl-down .modal-content {\n    height: 100%;\n    border: 0;\n    border-radius: 0;\n  }\n  .modal-fullscreen-xxl-down .modal-header {\n    border-radius: 0;\n  }\n  .modal-fullscreen-xxl-down .modal-body {\n    overflow-y: auto;\n  }\n  .modal-fullscreen-xxl-down .modal-footer {\n    border-radius: 0;\n  }\n}\n.tooltip {\n  position: absolute;\n  z-index: 1080;\n  display: block;\n  margin: 0;\n  font-family: var(--bs-font-sans-serif);\n  font-style: normal;\n  font-weight: 400;\n  line-height: 1.5;\n  text-align: left;\n  text-align: start;\n  text-decoration: none;\n  text-shadow: none;\n  text-transform: none;\n  letter-spacing: normal;\n  word-break: normal;\n  word-spacing: normal;\n  white-space: normal;\n  line-break: auto;\n  font-size: 0.875rem;\n  word-wrap: break-word;\n  opacity: 0;\n}\n.tooltip.show {\n  opacity: 0.9;\n}\n.tooltip .tooltip-arrow {\n  position: absolute;\n  display: block;\n  width: 0.8rem;\n  height: 0.4rem;\n}\n.tooltip .tooltip-arrow::before {\n  position: absolute;\n  content: \"\";\n  border-color: transparent;\n  border-style: solid;\n}\n\n.bs-tooltip-top, .bs-tooltip-auto[data-popper-placement^=top] {\n  padding: 0.4rem 0;\n}\n.bs-tooltip-top .tooltip-arrow, .bs-tooltip-auto[data-popper-placement^=top] .tooltip-arrow {\n  bottom: 0;\n}\n.bs-tooltip-top .tooltip-arrow::before, .bs-tooltip-auto[data-popper-placement^=top] .tooltip-arrow::before {\n  top: -1px;\n  border-width: 0.4rem 0.4rem 0;\n  border-top-color: #000;\n}\n\n.bs-tooltip-end, .bs-tooltip-auto[data-popper-placement^=right] {\n  padding: 0 0.4rem;\n}\n.bs-tooltip-end .tooltip-arrow, .bs-tooltip-auto[data-popper-placement^=right] .tooltip-arrow {\n  left: 0;\n  width: 0.4rem;\n  height: 0.8rem;\n}\n.bs-tooltip-end .tooltip-arrow::before, .bs-tooltip-auto[data-popper-placement^=right] .tooltip-arrow::before {\n  right: -1px;\n  border-width: 0.4rem 0.4rem 0.4rem 0;\n  border-right-color: #000;\n}\n\n.bs-tooltip-bottom, .bs-tooltip-auto[data-popper-placement^=bottom] {\n  padding: 0.4rem 0;\n}\n.bs-tooltip-bottom .tooltip-arrow, .bs-tooltip-auto[data-popper-placement^=bottom] .tooltip-arrow {\n  top: 0;\n}\n.bs-tooltip-bottom .tooltip-arrow::before, .bs-tooltip-auto[data-popper-placement^=bottom] .tooltip-arrow::before {\n  bottom: -1px;\n  border-width: 0 0.4rem 0.4rem;\n  border-bottom-color: #000;\n}\n\n.bs-tooltip-start, .bs-tooltip-auto[data-popper-placement^=left] {\n  padding: 0 0.4rem;\n}\n.bs-tooltip-start .tooltip-arrow, .bs-tooltip-auto[data-popper-placement^=left] .tooltip-arrow {\n  right: 0;\n  width: 0.4rem;\n  height: 0.8rem;\n}\n.bs-tooltip-start .tooltip-arrow::before, .bs-tooltip-auto[data-popper-placement^=left] .tooltip-arrow::before {\n  left: -1px;\n  border-width: 0.4rem 0 0.4rem 0.4rem;\n  border-left-color: #000;\n}\n\n.tooltip-inner {\n  max-width: 200px;\n  padding: 0.25rem 0.5rem;\n  color: #fff;\n  text-align: center;\n  background-color: #000;\n  border-radius: 0.25rem;\n}\n\n.popover {\n  position: absolute;\n  top: 0;\n  left: 0 /* rtl:ignore */;\n  z-index: 1070;\n  display: block;\n  max-width: 276px;\n  font-family: var(--bs-font-sans-serif);\n  font-style: normal;\n  font-weight: 400;\n  line-height: 1.5;\n  text-align: left;\n  text-align: start;\n  text-decoration: none;\n  text-shadow: none;\n  text-transform: none;\n  letter-spacing: normal;\n  word-break: normal;\n  word-spacing: normal;\n  white-space: normal;\n  line-break: auto;\n  font-size: 0.875rem;\n  word-wrap: break-word;\n  background-color: #fff;\n  background-clip: padding-box;\n  border: 1px solid rgba(0, 0, 0, 0.2);\n  border-radius: 0.3rem;\n}\n.popover .popover-arrow {\n  position: absolute;\n  display: block;\n  width: 1rem;\n  height: 0.5rem;\n}\n.popover .popover-arrow::before, .popover .popover-arrow::after {\n  position: absolute;\n  display: block;\n  content: \"\";\n  border-color: transparent;\n  border-style: solid;\n}\n\n.bs-popover-top > .popover-arrow, .bs-popover-auto[data-popper-placement^=top] > .popover-arrow {\n  bottom: calc(-0.5rem - 1px);\n}\n.bs-popover-top > .popover-arrow::before, .bs-popover-auto[data-popper-placement^=top] > .popover-arrow::before {\n  bottom: 0;\n  border-width: 0.5rem 0.5rem 0;\n  border-top-color: rgba(0, 0, 0, 0.25);\n}\n.bs-popover-top > .popover-arrow::after, .bs-popover-auto[data-popper-placement^=top] > .popover-arrow::after {\n  bottom: 1px;\n  border-width: 0.5rem 0.5rem 0;\n  border-top-color: #fff;\n}\n\n.bs-popover-end > .popover-arrow, .bs-popover-auto[data-popper-placement^=right] > .popover-arrow {\n  left: calc(-0.5rem - 1px);\n  width: 0.5rem;\n  height: 1rem;\n}\n.bs-popover-end > .popover-arrow::before, .bs-popover-auto[data-popper-placement^=right] > .popover-arrow::before {\n  left: 0;\n  border-width: 0.5rem 0.5rem 0.5rem 0;\n  border-right-color: rgba(0, 0, 0, 0.25);\n}\n.bs-popover-end > .popover-arrow::after, .bs-popover-auto[data-popper-placement^=right] > .popover-arrow::after {\n  left: 1px;\n  border-width: 0.5rem 0.5rem 0.5rem 0;\n  border-right-color: #fff;\n}\n\n.bs-popover-bottom > .popover-arrow, .bs-popover-auto[data-popper-placement^=bottom] > .popover-arrow {\n  top: calc(-0.5rem - 1px);\n}\n.bs-popover-bottom > .popover-arrow::before, .bs-popover-auto[data-popper-placement^=bottom] > .popover-arrow::before {\n  top: 0;\n  border-width: 0 0.5rem 0.5rem 0.5rem;\n  border-bottom-color: rgba(0, 0, 0, 0.25);\n}\n.bs-popover-bottom > .popover-arrow::after, .bs-popover-auto[data-popper-placement^=bottom] > .popover-arrow::after {\n  top: 1px;\n  border-width: 0 0.5rem 0.5rem 0.5rem;\n  border-bottom-color: #fff;\n}\n.bs-popover-bottom .popover-header::before, .bs-popover-auto[data-popper-placement^=bottom] .popover-header::before {\n  position: absolute;\n  top: 0;\n  left: 50%;\n  display: block;\n  width: 1rem;\n  margin-left: -0.5rem;\n  content: \"\";\n  border-bottom: 1px solid #f0f0f0;\n}\n\n.bs-popover-start > .popover-arrow, .bs-popover-auto[data-popper-placement^=left] > .popover-arrow {\n  right: calc(-0.5rem - 1px);\n  width: 0.5rem;\n  height: 1rem;\n}\n.bs-popover-start > .popover-arrow::before, .bs-popover-auto[data-popper-placement^=left] > .popover-arrow::before {\n  right: 0;\n  border-width: 0.5rem 0 0.5rem 0.5rem;\n  border-left-color: rgba(0, 0, 0, 0.25);\n}\n.bs-popover-start > .popover-arrow::after, .bs-popover-auto[data-popper-placement^=left] > .popover-arrow::after {\n  right: 1px;\n  border-width: 0.5rem 0 0.5rem 0.5rem;\n  border-left-color: #fff;\n}\n\n.popover-header {\n  padding: 0.5rem 1rem;\n  margin-bottom: 0;\n  font-size: 1rem;\n  background-color: #f0f0f0;\n  border-bottom: 1px solid rgba(0, 0, 0, 0.2);\n  border-top-left-radius: calc(0.3rem - 1px);\n  border-top-right-radius: calc(0.3rem - 1px);\n}\n.popover-header:empty {\n  display: none;\n}\n\n.popover-body {\n  padding: 1rem 1rem;\n  color: #212529;\n}\n\n.carousel {\n  position: relative;\n}\n\n.carousel.pointer-event {\n  touch-action: pan-y;\n}\n\n.carousel-inner {\n  position: relative;\n  width: 100%;\n  overflow: hidden;\n}\n.carousel-inner::after {\n  display: block;\n  clear: both;\n  content: \"\";\n}\n\n.carousel-item {\n  position: relative;\n  display: none;\n  float: left;\n  width: 100%;\n  margin-right: -100%;\n  -webkit-backface-visibility: hidden;\n  backface-visibility: hidden;\n  transition: transform 0.6s ease-in-out;\n}\n@media (prefers-reduced-motion: reduce) {\n  .carousel-item {\n    transition: none;\n  }\n}\n\n.carousel-item.active,\n.carousel-item-next,\n.carousel-item-prev {\n  display: block;\n}\n\n/* rtl:begin:ignore */\n.carousel-item-next:not(.carousel-item-start),\n.active.carousel-item-end {\n  transform: translateX(100%);\n}\n\n.carousel-item-prev:not(.carousel-item-end),\n.active.carousel-item-start {\n  transform: translateX(-100%);\n}\n\n/* rtl:end:ignore */\n.carousel-fade .carousel-item {\n  opacity: 0;\n  transition-property: opacity;\n  transform: none;\n}\n.carousel-fade .carousel-item.active,\n.carousel-fade .carousel-item-next.carousel-item-start,\n.carousel-fade .carousel-item-prev.carousel-item-end {\n  z-index: 1;\n  opacity: 1;\n}\n.carousel-fade .active.carousel-item-start,\n.carousel-fade .active.carousel-item-end {\n  z-index: 0;\n  opacity: 0;\n  transition: opacity 0s 0.6s;\n}\n@media (prefers-reduced-motion: reduce) {\n  .carousel-fade .active.carousel-item-start,\n.carousel-fade .active.carousel-item-end {\n    transition: none;\n  }\n}\n\n.carousel-control-prev,\n.carousel-control-next {\n  position: absolute;\n  top: 0;\n  bottom: 0;\n  z-index: 1;\n  display: flex;\n  align-items: center;\n  justify-content: center;\n  width: 15%;\n  padding: 0;\n  color: #fff;\n  text-align: center;\n  background: none;\n  border: 0;\n  opacity: 0.5;\n  transition: opacity 0.15s ease;\n}\n@media (prefers-reduced-motion: reduce) {\n  .carousel-control-prev,\n.carousel-control-next {\n    transition: none;\n  }\n}\n.carousel-control-prev:hover, .carousel-control-prev:focus,\n.carousel-control-next:hover,\n.carousel-control-next:focus {\n  color: #fff;\n  text-decoration: none;\n  outline: 0;\n  opacity: 0.9;\n}\n\n.carousel-control-prev {\n  left: 0;\n}\n\n.carousel-control-next {\n  right: 0;\n}\n\n.carousel-control-prev-icon,\n.carousel-control-next-icon {\n  display: inline-block;\n  width: 2rem;\n  height: 2rem;\n  background-repeat: no-repeat;\n  background-position: 50%;\n  background-size: 100% 100%;\n}\n\n/* rtl:options: {\n  \"autoRename\": true,\n  \"stringMap\":[ {\n    \"name\"    : \"prev-next\",\n    \"search\"  : \"prev\",\n    \"replace\" : \"next\"\n  } ]\n} */\n.carousel-control-prev-icon {\n  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 0z'/%3e%3c/svg%3e\");\n}\n\n.carousel-control-next-icon {\n  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-.708z'/%3e%3c/svg%3e\");\n}\n\n.carousel-indicators {\n  position: absolute;\n  right: 0;\n  bottom: 0;\n  left: 0;\n  z-index: 2;\n  display: flex;\n  justify-content: center;\n  padding: 0;\n  margin-right: 15%;\n  margin-bottom: 1rem;\n  margin-left: 15%;\n  list-style: none;\n}\n.carousel-indicators [data-bs-target] {\n  box-sizing: content-box;\n  flex: 0 1 auto;\n  width: 30px;\n  height: 3px;\n  padding: 0;\n  margin-right: 3px;\n  margin-left: 3px;\n  text-indent: -999px;\n  cursor: pointer;\n  background-color: #fff;\n  background-clip: padding-box;\n  border: 0;\n  border-top: 10px solid transparent;\n  border-bottom: 10px solid transparent;\n  opacity: 0.5;\n  transition: opacity 0.6s ease;\n}\n@media (prefers-reduced-motion: reduce) {\n  .carousel-indicators [data-bs-target] {\n    transition: none;\n  }\n}\n.carousel-indicators .active {\n  opacity: 1;\n}\n\n.carousel-caption {\n  position: absolute;\n  right: 15%;\n  bottom: 1.25rem;\n  left: 15%;\n  padding-top: 1.25rem;\n  padding-bottom: 1.25rem;\n  color: #fff;\n  text-align: center;\n}\n\n.carousel-dark .carousel-control-prev-icon,\n.carousel-dark .carousel-control-next-icon {\n  filter: invert(1) grayscale(100);\n}\n.carousel-dark .carousel-indicators [data-bs-target] {\n  background-color: #000;\n}\n.carousel-dark .carousel-caption {\n  color: #000;\n}\n\n@-webkit-keyframes spinner-border {\n  to {\n    transform: rotate(360deg) /* rtl:ignore */;\n  }\n}\n\n@keyframes spinner-border {\n  to {\n    transform: rotate(360deg) /* rtl:ignore */;\n  }\n}\n.spinner-border {\n  display: inline-block;\n  width: 2rem;\n  height: 2rem;\n  vertical-align: -0.125em;\n  border: 0.25em solid currentColor;\n  border-right-color: transparent;\n  border-radius: 50%;\n  -webkit-animation: 0.75s linear infinite spinner-border;\n  animation: 0.75s linear infinite spinner-border;\n}\n\n.spinner-border-sm {\n  width: 1rem;\n  height: 1rem;\n  border-width: 0.2em;\n}\n\n@-webkit-keyframes spinner-grow {\n  0% {\n    transform: scale(0);\n  }\n  50% {\n    opacity: 1;\n    transform: none;\n  }\n}\n\n@keyframes spinner-grow {\n  0% {\n    transform: scale(0);\n  }\n  50% {\n    opacity: 1;\n    transform: none;\n  }\n}\n.spinner-grow {\n  display: inline-block;\n  width: 2rem;\n  height: 2rem;\n  vertical-align: -0.125em;\n  background-color: currentColor;\n  border-radius: 50%;\n  opacity: 0;\n  -webkit-animation: 0.75s linear infinite spinner-grow;\n  animation: 0.75s linear infinite spinner-grow;\n}\n\n.spinner-grow-sm {\n  width: 1rem;\n  height: 1rem;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .spinner-border,\n.spinner-grow {\n    -webkit-animation-duration: 1.5s;\n    animation-duration: 1.5s;\n  }\n}\n.offcanvas {\n  position: fixed;\n  bottom: 0;\n  z-index: 1045;\n  display: flex;\n  flex-direction: column;\n  max-width: 100%;\n  visibility: hidden;\n  background-color: #fff;\n  background-clip: padding-box;\n  outline: 0;\n  transition: transform 0.3s ease-in-out;\n}\n@media (prefers-reduced-motion: reduce) {\n  .offcanvas {\n    transition: none;\n  }\n}\n\n.offcanvas-backdrop {\n  position: fixed;\n  top: 0;\n  left: 0;\n  z-index: 1040;\n  width: 100vw;\n  height: 100vh;\n  background-color: #000;\n}\n.offcanvas-backdrop.fade {\n  opacity: 0;\n}\n.offcanvas-backdrop.show {\n  opacity: 0.5;\n}\n\n.offcanvas-header {\n  display: flex;\n  align-items: center;\n  justify-content: space-between;\n  padding: 1rem 1rem;\n}\n.offcanvas-header .btn-close {\n  padding: 0.5rem 0.5rem;\n  margin-top: -0.5rem;\n  margin-right: -0.5rem;\n  margin-bottom: -0.5rem;\n}\n\n.offcanvas-title {\n  margin-bottom: 0;\n  line-height: 1.5;\n}\n\n.offcanvas-body {\n  flex-grow: 1;\n  padding: 1rem 1rem;\n  overflow-y: auto;\n}\n\n.offcanvas-start {\n  top: 0;\n  left: 0;\n  width: 400px;\n  border-right: 1px solid rgba(0, 0, 0, 0.2);\n  transform: translateX(-100%);\n}\n\n.offcanvas-end {\n  top: 0;\n  right: 0;\n  width: 400px;\n  border-left: 1px solid rgba(0, 0, 0, 0.2);\n  transform: translateX(100%);\n}\n\n.offcanvas-top {\n  top: 0;\n  right: 0;\n  left: 0;\n  height: 30vh;\n  max-height: 100%;\n  border-bottom: 1px solid rgba(0, 0, 0, 0.2);\n  transform: translateY(-100%);\n}\n\n.offcanvas-bottom {\n  right: 0;\n  left: 0;\n  height: 30vh;\n  max-height: 100%;\n  border-top: 1px solid rgba(0, 0, 0, 0.2);\n  transform: translateY(100%);\n}\n\n.offcanvas.show {\n  transform: none;\n}\n\n.placeholder {\n  display: inline-block;\n  min-height: 1em;\n  vertical-align: middle;\n  cursor: wait;\n  background-color: currentColor;\n  opacity: 0.5;\n}\n.placeholder.btn::before {\n  display: inline-block;\n  content: \"\";\n}\n\n.placeholder-xs {\n  min-height: 0.6em;\n}\n\n.placeholder-sm {\n  min-height: 0.8em;\n}\n\n.placeholder-lg {\n  min-height: 1.2em;\n}\n\n.placeholder-glow .placeholder {\n  -webkit-animation: placeholder-glow 2s ease-in-out infinite;\n  animation: placeholder-glow 2s ease-in-out infinite;\n}\n\n@-webkit-keyframes placeholder-glow {\n  50% {\n    opacity: 0.2;\n  }\n}\n\n@keyframes placeholder-glow {\n  50% {\n    opacity: 0.2;\n  }\n}\n.placeholder-wave {\n  -webkit-mask-image: linear-gradient(130deg, #000 55%, rgba(0, 0, 0, 0.8) 75%, #000 95%);\n  mask-image: linear-gradient(130deg, #000 55%, rgba(0, 0, 0, 0.8) 75%, #000 95%);\n  -webkit-mask-size: 200% 100%;\n  mask-size: 200% 100%;\n  -webkit-animation: placeholder-wave 2s linear infinite;\n  animation: placeholder-wave 2s linear infinite;\n}\n\n@-webkit-keyframes placeholder-wave {\n  100% {\n    -webkit-mask-position: -200% 0%;\n    mask-position: -200% 0%;\n  }\n}\n\n@keyframes placeholder-wave {\n  100% {\n    -webkit-mask-position: -200% 0%;\n    mask-position: -200% 0%;\n  }\n}\n.clearfix::after {\n  display: block;\n  clear: both;\n  content: \"\";\n}\n\n.link-primary {\n  color: #0d6efd;\n}\n.link-primary:hover, .link-primary:focus {\n  color: #0a58ca;\n}\n\n.link-secondary {\n  color: #6c757d;\n}\n.link-secondary:hover, .link-secondary:focus {\n  color: #565e64;\n}\n\n.link-success {\n  color: #198754;\n}\n.link-success:hover, .link-success:focus {\n  color: #146c43;\n}\n\n.link-info {\n  color: #0dcaf0;\n}\n.link-info:hover, .link-info:focus {\n  color: #3dd5f3;\n}\n\n.link-warning {\n  color: #ffc107;\n}\n.link-warning:hover, .link-warning:focus {\n  color: #ffcd39;\n}\n\n.link-danger {\n  color: #dc3545;\n}\n.link-danger:hover, .link-danger:focus {\n  color: #b02a37;\n}\n\n.link-light {\n  color: #f8f9fa;\n}\n.link-light:hover, .link-light:focus {\n  color: #f9fafb;\n}\n\n.link-dark {\n  color: #212529;\n}\n.link-dark:hover, .link-dark:focus {\n  color: #1a1e21;\n}\n\n.ratio {\n  position: relative;\n  width: 100%;\n}\n.ratio::before {\n  display: block;\n  padding-top: var(--bs-aspect-ratio);\n  content: \"\";\n}\n.ratio > * {\n  position: absolute;\n  top: 0;\n  left: 0;\n  width: 100%;\n  height: 100%;\n}\n\n.ratio-1x1 {\n  --bs-aspect-ratio: 100%;\n}\n\n.ratio-4x3 {\n  --bs-aspect-ratio: calc(3 / 4 * 100%);\n}\n\n.ratio-16x9 {\n  --bs-aspect-ratio: calc(9 / 16 * 100%);\n}\n\n.ratio-21x9 {\n  --bs-aspect-ratio: calc(9 / 21 * 100%);\n}\n\n.fixed-top {\n  position: fixed;\n  top: 0;\n  right: 0;\n  left: 0;\n  z-index: 1030;\n}\n\n.fixed-bottom {\n  position: fixed;\n  right: 0;\n  bottom: 0;\n  left: 0;\n  z-index: 1030;\n}\n\n.sticky-top {\n  position: -webkit-sticky;\n  position: sticky;\n  top: 0;\n  z-index: 1020;\n}\n\n@media (min-width: 576px) {\n  .sticky-sm-top {\n    position: -webkit-sticky;\n    position: sticky;\n    top: 0;\n    z-index: 1020;\n  }\n}\n@media (min-width: 768px) {\n  .sticky-md-top {\n    position: -webkit-sticky;\n    position: sticky;\n    top: 0;\n    z-index: 1020;\n  }\n}\n@media (min-width: 992px) {\n  .sticky-lg-top {\n    position: -webkit-sticky;\n    position: sticky;\n    top: 0;\n    z-index: 1020;\n  }\n}\n@media (min-width: 1200px) {\n  .sticky-xl-top {\n    position: -webkit-sticky;\n    position: sticky;\n    top: 0;\n    z-index: 1020;\n  }\n}\n@media (min-width: 1400px) {\n  .sticky-xxl-top {\n    position: -webkit-sticky;\n    position: sticky;\n    top: 0;\n    z-index: 1020;\n  }\n}\n.hstack {\n  display: flex;\n  flex-direction: row;\n  align-items: center;\n  align-self: stretch;\n}\n\n.vstack {\n  display: flex;\n  flex: 1 1 auto;\n  flex-direction: column;\n  align-self: stretch;\n}\n\n.visually-hidden,\n.visually-hidden-focusable:not(:focus):not(:focus-within) {\n  position: absolute !important;\n  width: 1px !important;\n  height: 1px !important;\n  padding: 0 !important;\n  margin: -1px !important;\n  overflow: hidden !important;\n  clip: rect(0, 0, 0, 0) !important;\n  white-space: nowrap !important;\n  border: 0 !important;\n}\n\n.stretched-link::after {\n  position: absolute;\n  top: 0;\n  right: 0;\n  bottom: 0;\n  left: 0;\n  z-index: 1;\n  content: \"\";\n}\n\n.text-truncate {\n  overflow: hidden;\n  text-overflow: ellipsis;\n  white-space: nowrap;\n}\n\n.vr {\n  display: inline-block;\n  align-self: stretch;\n  width: 1px;\n  min-height: 1em;\n  background-color: currentColor;\n  opacity: 0.25;\n}\n\n.align-baseline {\n  vertical-align: baseline !important;\n}\n\n.align-top {\n  vertical-align: top !important;\n}\n\n.align-middle {\n  vertical-align: middle !important;\n}\n\n.align-bottom {\n  vertical-align: bottom !important;\n}\n\n.align-text-bottom {\n  vertical-align: text-bottom !important;\n}\n\n.align-text-top {\n  vertical-align: text-top !important;\n}\n\n.float-start {\n  float: left !important;\n}\n\n.float-end {\n  float: right !important;\n}\n\n.float-none {\n  float: none !important;\n}\n\n.opacity-0 {\n  opacity: 0 !important;\n}\n\n.opacity-25 {\n  opacity: 0.25 !important;\n}\n\n.opacity-50 {\n  opacity: 0.5 !important;\n}\n\n.opacity-75 {\n  opacity: 0.75 !important;\n}\n\n.opacity-100 {\n  opacity: 1 !important;\n}\n\n.overflow-auto {\n  overflow: auto !important;\n}\n\n.overflow-hidden {\n  overflow: hidden !important;\n}\n\n.overflow-visible {\n  overflow: visible !important;\n}\n\n.overflow-scroll {\n  overflow: scroll !important;\n}\n\n.d-inline {\n  display: inline !important;\n}\n\n.d-inline-block {\n  display: inline-block !important;\n}\n\n.d-block {\n  display: block !important;\n}\n\n.d-grid {\n  display: grid !important;\n}\n\n.d-table {\n  display: table !important;\n}\n\n.d-table-row {\n  display: table-row !important;\n}\n\n.d-table-cell {\n  display: table-cell !important;\n}\n\n.d-flex {\n  display: flex !important;\n}\n\n.d-inline-flex {\n  display: inline-flex !important;\n}\n\n.d-none {\n  display: none !important;\n}\n\n.shadow {\n  box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.15) !important;\n}\n\n.shadow-sm {\n  box-shadow: 0 0.125rem 0.25rem rgba(0, 0, 0, 0.075) !important;\n}\n\n.shadow-lg {\n  box-shadow: 0 1rem 3rem rgba(0, 0, 0, 0.175) !important;\n}\n\n.shadow-none {\n  box-shadow: none !important;\n}\n\n.position-static {\n  position: static !important;\n}\n\n.position-relative {\n  position: relative !important;\n}\n\n.position-absolute {\n  position: absolute !important;\n}\n\n.position-fixed {\n  position: fixed !important;\n}\n\n.position-sticky {\n  position: -webkit-sticky !important;\n  position: sticky !important;\n}\n\n.top-0 {\n  top: 0 !important;\n}\n\n.top-50 {\n  top: 50% !important;\n}\n\n.top-100 {\n  top: 100% !important;\n}\n\n.bottom-0 {\n  bottom: 0 !important;\n}\n\n.bottom-50 {\n  bottom: 50% !important;\n}\n\n.bottom-100 {\n  bottom: 100% !important;\n}\n\n.start-0 {\n  left: 0 !important;\n}\n\n.start-50 {\n  left: 50% !important;\n}\n\n.start-100 {\n  left: 100% !important;\n}\n\n.end-0 {\n  right: 0 !important;\n}\n\n.end-50 {\n  right: 50% !important;\n}\n\n.end-100 {\n  right: 100% !important;\n}\n\n.translate-middle {\n  transform: translate(-50%, -50%) !important;\n}\n\n.translate-middle-x {\n  transform: translateX(-50%) !important;\n}\n\n.translate-middle-y {\n  transform: translateY(-50%) !important;\n}\n\n.border {\n  border: 1px solid #dee2e6 !important;\n}\n\n.border-0 {\n  border: 0 !important;\n}\n\n.border-top {\n  border-top: 1px solid #dee2e6 !important;\n}\n\n.border-top-0 {\n  border-top: 0 !important;\n}\n\n.border-end {\n  border-right: 1px solid #dee2e6 !important;\n}\n\n.border-end-0 {\n  border-right: 0 !important;\n}\n\n.border-bottom {\n  border-bottom: 1px solid #dee2e6 !important;\n}\n\n.border-bottom-0 {\n  border-bottom: 0 !important;\n}\n\n.border-start {\n  border-left: 1px solid #dee2e6 !important;\n}\n\n.border-start-0 {\n  border-left: 0 !important;\n}\n\n.border-primary {\n  border-color: #0d6efd !important;\n}\n\n.border-secondary {\n  border-color: #6c757d !important;\n}\n\n.border-success {\n  border-color: #198754 !important;\n}\n\n.border-info {\n  border-color: #0dcaf0 !important;\n}\n\n.border-warning {\n  border-color: #ffc107 !important;\n}\n\n.border-danger {\n  border-color: #dc3545 !important;\n}\n\n.border-light {\n  border-color: #f8f9fa !important;\n}\n\n.border-dark {\n  border-color: #212529 !important;\n}\n\n.border-white {\n  border-color: #fff !important;\n}\n\n.border-1 {\n  border-width: 1px !important;\n}\n\n.border-2 {\n  border-width: 2px !important;\n}\n\n.border-3 {\n  border-width: 3px !important;\n}\n\n.border-4 {\n  border-width: 4px !important;\n}\n\n.border-5 {\n  border-width: 5px !important;\n}\n\n.w-25 {\n  width: 25% !important;\n}\n\n.w-50 {\n  width: 50% !important;\n}\n\n.w-75 {\n  width: 75% !important;\n}\n\n.w-100 {\n  width: 100% !important;\n}\n\n.w-auto {\n  width: auto !important;\n}\n\n.mw-100 {\n  max-width: 100% !important;\n}\n\n.vw-100 {\n  width: 100vw !important;\n}\n\n.min-vw-100 {\n  min-width: 100vw !important;\n}\n\n.h-25 {\n  height: 25% !important;\n}\n\n.h-50 {\n  height: 50% !important;\n}\n\n.h-75 {\n  height: 75% !important;\n}\n\n.h-100 {\n  height: 100% !important;\n}\n\n.h-auto {\n  height: auto !important;\n}\n\n.mh-100 {\n  max-height: 100% !important;\n}\n\n.vh-100 {\n  height: 100vh !important;\n}\n\n.min-vh-100 {\n  min-height: 100vh !important;\n}\n\n.flex-fill {\n  flex: 1 1 auto !important;\n}\n\n.flex-row {\n  flex-direction: row !important;\n}\n\n.flex-column {\n  flex-direction: column !important;\n}\n\n.flex-row-reverse {\n  flex-direction: row-reverse !important;\n}\n\n.flex-column-reverse {\n  flex-direction: column-reverse !important;\n}\n\n.flex-grow-0 {\n  flex-grow: 0 !important;\n}\n\n.flex-grow-1 {\n  flex-grow: 1 !important;\n}\n\n.flex-shrink-0 {\n  flex-shrink: 0 !important;\n}\n\n.flex-shrink-1 {\n  flex-shrink: 1 !important;\n}\n\n.flex-wrap {\n  flex-wrap: wrap !important;\n}\n\n.flex-nowrap {\n  flex-wrap: nowrap !important;\n}\n\n.flex-wrap-reverse {\n  flex-wrap: wrap-reverse !important;\n}\n\n.gap-0 {\n  gap: 0 !important;\n}\n\n.gap-1 {\n  gap: 0.25rem !important;\n}\n\n.gap-2 {\n  gap: 0.5rem !important;\n}\n\n.gap-3 {\n  gap: 1rem !important;\n}\n\n.gap-4 {\n  gap: 1.5rem !important;\n}\n\n.gap-5 {\n  gap: 3rem !important;\n}\n\n.justify-content-start {\n  justify-content: flex-start !important;\n}\n\n.justify-content-end {\n  justify-content: flex-end !important;\n}\n\n.justify-content-center {\n  justify-content: center !important;\n}\n\n.justify-content-between {\n  justify-content: space-between !important;\n}\n\n.justify-content-around {\n  justify-content: space-around !important;\n}\n\n.justify-content-evenly {\n  justify-content: space-evenly !important;\n}\n\n.align-items-start {\n  align-items: flex-start !important;\n}\n\n.align-items-end {\n  align-items: flex-end !important;\n}\n\n.align-items-center {\n  align-items: center !important;\n}\n\n.align-items-baseline {\n  align-items: baseline !important;\n}\n\n.align-items-stretch {\n  align-items: stretch !important;\n}\n\n.align-content-start {\n  align-content: flex-start !important;\n}\n\n.align-content-end {\n  align-content: flex-end !important;\n}\n\n.align-content-center {\n  align-content: center !important;\n}\n\n.align-content-between {\n  align-content: space-between !important;\n}\n\n.align-content-around {\n  align-content: space-around !important;\n}\n\n.align-content-stretch {\n  align-content: stretch !important;\n}\n\n.align-self-auto {\n  align-self: auto !important;\n}\n\n.align-self-start {\n  align-self: flex-start !important;\n}\n\n.align-self-end {\n  align-self: flex-end !important;\n}\n\n.align-self-center {\n  align-self: center !important;\n}\n\n.align-self-baseline {\n  align-self: baseline !important;\n}\n\n.align-self-stretch {\n  align-self: stretch !important;\n}\n\n.order-first {\n  order: -1 !important;\n}\n\n.order-0 {\n  order: 0 !important;\n}\n\n.order-1 {\n  order: 1 !important;\n}\n\n.order-2 {\n  order: 2 !important;\n}\n\n.order-3 {\n  order: 3 !important;\n}\n\n.order-4 {\n  order: 4 !important;\n}\n\n.order-5 {\n  order: 5 !important;\n}\n\n.order-last {\n  order: 6 !important;\n}\n\n.m-0 {\n  margin: 0 !important;\n}\n\n.m-1 {\n  margin: 0.25rem !important;\n}\n\n.m-2 {\n  margin: 0.5rem !important;\n}\n\n.m-3 {\n  margin: 1rem !important;\n}\n\n.m-4 {\n  margin: 1.5rem !important;\n}\n\n.m-5 {\n  margin: 3rem !important;\n}\n\n.m-auto {\n  margin: auto !important;\n}\n\n.mx-0 {\n  margin-right: 0 !important;\n  margin-left: 0 !important;\n}\n\n.mx-1 {\n  margin-right: 0.25rem !important;\n  margin-left: 0.25rem !important;\n}\n\n.mx-2 {\n  margin-right: 0.5rem !important;\n  margin-left: 0.5rem !important;\n}\n\n.mx-3 {\n  margin-right: 1rem !important;\n  margin-left: 1rem !important;\n}\n\n.mx-4 {\n  margin-right: 1.5rem !important;\n  margin-left: 1.5rem !important;\n}\n\n.mx-5 {\n  margin-right: 3rem !important;\n  margin-left: 3rem !important;\n}\n\n.mx-auto {\n  margin-right: auto !important;\n  margin-left: auto !important;\n}\n\n.my-0 {\n  margin-top: 0 !important;\n  margin-bottom: 0 !important;\n}\n\n.my-1 {\n  margin-top: 0.25rem !important;\n  margin-bottom: 0.25rem !important;\n}\n\n.my-2 {\n  margin-top: 0.5rem !important;\n  margin-bottom: 0.5rem !important;\n}\n\n.my-3 {\n  margin-top: 1rem !important;\n  margin-bottom: 1rem !important;\n}\n\n.my-4 {\n  margin-top: 1.5rem !important;\n  margin-bottom: 1.5rem !important;\n}\n\n.my-5 {\n  margin-top: 3rem !important;\n  margin-bottom: 3rem !important;\n}\n\n.my-auto {\n  margin-top: auto !important;\n  margin-bottom: auto !important;\n}\n\n.mt-0 {\n  margin-top: 0 !important;\n}\n\n.mt-1 {\n  margin-top: 0.25rem !important;\n}\n\n.mt-2 {\n  margin-top: 0.5rem !important;\n}\n\n.mt-3 {\n  margin-top: 1rem !important;\n}\n\n.mt-4 {\n  margin-top: 1.5rem !important;\n}\n\n.mt-5 {\n  margin-top: 3rem !important;\n}\n\n.mt-auto {\n  margin-top: auto !important;\n}\n\n.me-0 {\n  margin-right: 0 !important;\n}\n\n.me-1 {\n  margin-right: 0.25rem !important;\n}\n\n.me-2 {\n  margin-right: 0.5rem !important;\n}\n\n.me-3 {\n  margin-right: 1rem !important;\n}\n\n.me-4 {\n  margin-right: 1.5rem !important;\n}\n\n.me-5 {\n  margin-right: 3rem !important;\n}\n\n.me-auto {\n  margin-right: auto !important;\n}\n\n.mb-0 {\n  margin-bottom: 0 !important;\n}\n\n.mb-1 {\n  margin-bottom: 0.25rem !important;\n}\n\n.mb-2 {\n  margin-bottom: 0.5rem !important;\n}\n\n.mb-3 {\n  margin-bottom: 1rem !important;\n}\n\n.mb-4 {\n  margin-bottom: 1.5rem !important;\n}\n\n.mb-5 {\n  margin-bottom: 3rem !important;\n}\n\n.mb-auto {\n  margin-bottom: auto !important;\n}\n\n.ms-0 {\n  margin-left: 0 !important;\n}\n\n.ms-1 {\n  margin-left: 0.25rem !important;\n}\n\n.ms-2 {\n  margin-left: 0.5rem !important;\n}\n\n.ms-3 {\n  margin-left: 1rem !important;\n}\n\n.ms-4 {\n  margin-left: 1.5rem !important;\n}\n\n.ms-5 {\n  margin-left: 3rem !important;\n}\n\n.ms-auto {\n  margin-left: auto !important;\n}\n\n.p-0 {\n  padding: 0 !important;\n}\n\n.p-1 {\n  padding: 0.25rem !important;\n}\n\n.p-2 {\n  padding: 0.5rem !important;\n}\n\n.p-3 {\n  padding: 1rem !important;\n}\n\n.p-4 {\n  padding: 1.5rem !important;\n}\n\n.p-5 {\n  padding: 3rem !important;\n}\n\n.px-0 {\n  padding-right: 0 !important;\n  padding-left: 0 !important;\n}\n\n.px-1 {\n  padding-right: 0.25rem !important;\n  padding-left: 0.25rem !important;\n}\n\n.px-2 {\n  padding-right: 0.5rem !important;\n  padding-left: 0.5rem !important;\n}\n\n.px-3 {\n  padding-right: 1rem !important;\n  padding-left: 1rem !important;\n}\n\n.px-4 {\n  padding-right: 1.5rem !important;\n  padding-left: 1.5rem !important;\n}\n\n.px-5 {\n  padding-right: 3rem !important;\n  padding-left: 3rem !important;\n}\n\n.py-0 {\n  padding-top: 0 !important;\n  padding-bottom: 0 !important;\n}\n\n.py-1 {\n  padding-top: 0.25rem !important;\n  padding-bottom: 0.25rem !important;\n}\n\n.py-2 {\n  padding-top: 0.5rem !important;\n  padding-bottom: 0.5rem !important;\n}\n\n.py-3 {\n  padding-top: 1rem !important;\n  padding-bottom: 1rem !important;\n}\n\n.py-4 {\n  padding-top: 1.5rem !important;\n  padding-bottom: 1.5rem !important;\n}\n\n.py-5 {\n  padding-top: 3rem !important;\n  padding-bottom: 3rem !important;\n}\n\n.pt-0 {\n  padding-top: 0 !important;\n}\n\n.pt-1 {\n  padding-top: 0.25rem !important;\n}\n\n.pt-2 {\n  padding-top: 0.5rem !important;\n}\n\n.pt-3 {\n  padding-top: 1rem !important;\n}\n\n.pt-4 {\n  padding-top: 1.5rem !important;\n}\n\n.pt-5 {\n  padding-top: 3rem !important;\n}\n\n.pe-0 {\n  padding-right: 0 !important;\n}\n\n.pe-1 {\n  padding-right: 0.25rem !important;\n}\n\n.pe-2 {\n  padding-right: 0.5rem !important;\n}\n\n.pe-3 {\n  padding-right: 1rem !important;\n}\n\n.pe-4 {\n  padding-right: 1.5rem !important;\n}\n\n.pe-5 {\n  padding-right: 3rem !important;\n}\n\n.pb-0 {\n  padding-bottom: 0 !important;\n}\n\n.pb-1 {\n  padding-bottom: 0.25rem !important;\n}\n\n.pb-2 {\n  padding-bottom: 0.5rem !important;\n}\n\n.pb-3 {\n  padding-bottom: 1rem !important;\n}\n\n.pb-4 {\n  padding-bottom: 1.5rem !important;\n}\n\n.pb-5 {\n  padding-bottom: 3rem !important;\n}\n\n.ps-0 {\n  padding-left: 0 !important;\n}\n\n.ps-1 {\n  padding-left: 0.25rem !important;\n}\n\n.ps-2 {\n  padding-left: 0.5rem !important;\n}\n\n.ps-3 {\n  padding-left: 1rem !important;\n}\n\n.ps-4 {\n  padding-left: 1.5rem !important;\n}\n\n.ps-5 {\n  padding-left: 3rem !important;\n}\n\n.font-monospace {\n  font-family: var(--bs-font-monospace) !important;\n}\n\n.fs-1 {\n  font-size: calc(1.375rem + 1.5vw) !important;\n}\n\n.fs-2 {\n  font-size: calc(1.325rem + 0.9vw) !important;\n}\n\n.fs-3 {\n  font-size: calc(1.3rem + 0.6vw) !important;\n}\n\n.fs-4 {\n  font-size: calc(1.275rem + 0.3vw) !important;\n}\n\n.fs-5 {\n  font-size: 1.25rem !important;\n}\n\n.fs-6 {\n  font-size: 1rem !important;\n}\n\n.fst-italic {\n  font-style: italic !important;\n}\n\n.fst-normal {\n  font-style: normal !important;\n}\n\n.fw-light {\n  font-weight: 300 !important;\n}\n\n.fw-lighter {\n  font-weight: lighter !important;\n}\n\n.fw-normal {\n  font-weight: 400 !important;\n}\n\n.fw-bold {\n  font-weight: 700 !important;\n}\n\n.fw-bolder {\n  font-weight: bolder !important;\n}\n\n.lh-1 {\n  line-height: 1 !important;\n}\n\n.lh-sm {\n  line-height: 1.25 !important;\n}\n\n.lh-base {\n  line-height: 1.5 !important;\n}\n\n.lh-lg {\n  line-height: 2 !important;\n}\n\n.text-start {\n  text-align: left !important;\n}\n\n.text-end {\n  text-align: right !important;\n}\n\n.text-center {\n  text-align: center !important;\n}\n\n.text-decoration-none {\n  text-decoration: none !important;\n}\n\n.text-decoration-underline {\n  text-decoration: underline !important;\n}\n\n.text-decoration-line-through {\n  text-decoration: line-through !important;\n}\n\n.text-lowercase {\n  text-transform: lowercase !important;\n}\n\n.text-uppercase {\n  text-transform: uppercase !important;\n}\n\n.text-capitalize {\n  text-transform: capitalize !important;\n}\n\n.text-wrap {\n  white-space: normal !important;\n}\n\n.text-nowrap {\n  white-space: nowrap !important;\n}\n\n/* rtl:begin:remove */\n.text-break {\n  word-wrap: break-word !important;\n  word-break: break-word !important;\n}\n\n/* rtl:end:remove */\n.text-primary {\n  --bs-text-opacity: 1;\n  color: rgba(var(--bs-primary-rgb), var(--bs-text-opacity)) !important;\n}\n\n.text-secondary {\n  --bs-text-opacity: 1;\n  color: rgba(var(--bs-secondary-rgb), var(--bs-text-opacity)) !important;\n}\n\n.text-success {\n  --bs-text-opacity: 1;\n  color: rgba(var(--bs-success-rgb), var(--bs-text-opacity)) !important;\n}\n\n.text-info {\n  --bs-text-opacity: 1;\n  color: rgba(var(--bs-info-rgb), var(--bs-text-opacity)) !important;\n}\n\n.text-warning {\n  --bs-text-opacity: 1;\n  color: rgba(var(--bs-warning-rgb), var(--bs-text-opacity)) !important;\n}\n\n.text-danger {\n  --bs-text-opacity: 1;\n  color: rgba(var(--bs-danger-rgb), var(--bs-text-opacity)) !important;\n}\n\n.text-light {\n  --bs-text-opacity: 1;\n  color: rgba(var(--bs-light-rgb), var(--bs-text-opacity)) !important;\n}\n\n.text-dark {\n  --bs-text-opacity: 1;\n  color: rgba(var(--bs-dark-rgb), var(--bs-text-opacity)) !important;\n}\n\n.text-black {\n  --bs-text-opacity: 1;\n  color: rgba(var(--bs-black-rgb), var(--bs-text-opacity)) !important;\n}\n\n.text-white {\n  --bs-text-opacity: 1;\n  color: rgba(var(--bs-white-rgb), var(--bs-text-opacity)) !important;\n}\n\n.text-body {\n  --bs-text-opacity: 1;\n  color: rgba(var(--bs-body-rgb), var(--bs-text-opacity)) !important;\n}\n\n.text-muted {\n  --bs-text-opacity: 1;\n  color: #6c757d !important;\n}\n\n.text-black-50 {\n  --bs-text-opacity: 1;\n  color: rgba(0, 0, 0, 0.5) !important;\n}\n\n.text-white-50 {\n  --bs-text-opacity: 1;\n  color: rgba(255, 255, 255, 0.5) !important;\n}\n\n.text-reset {\n  --bs-text-opacity: 1;\n  color: inherit !important;\n}\n\n.text-opacity-25 {\n  --bs-text-opacity: 0.25;\n}\n\n.text-opacity-50 {\n  --bs-text-opacity: 0.5;\n}\n\n.text-opacity-75 {\n  --bs-text-opacity: 0.75;\n}\n\n.text-opacity-100 {\n  --bs-text-opacity: 1;\n}\n\n.bg-primary {\n  --bs-bg-opacity: 1;\n  background-color: rgba(var(--bs-primary-rgb), var(--bs-bg-opacity)) !important;\n}\n\n.bg-secondary {\n  --bs-bg-opacity: 1;\n  background-color: rgba(var(--bs-secondary-rgb), var(--bs-bg-opacity)) !important;\n}\n\n.bg-success {\n  --bs-bg-opacity: 1;\n  background-color: rgba(var(--bs-success-rgb), var(--bs-bg-opacity)) !important;\n}\n\n.bg-info {\n  --bs-bg-opacity: 1;\n  background-color: rgba(var(--bs-info-rgb), var(--bs-bg-opacity)) !important;\n}\n\n.bg-warning {\n  --bs-bg-opacity: 1;\n  background-color: rgba(var(--bs-warning-rgb), var(--bs-bg-opacity)) !important;\n}\n\n.bg-danger {\n  --bs-bg-opacity: 1;\n  background-color: rgba(var(--bs-danger-rgb), var(--bs-bg-opacity)) !important;\n}\n\n.bg-light {\n  --bs-bg-opacity: 1;\n  background-color: rgba(var(--bs-light-rgb), var(--bs-bg-opacity)) !important;\n}\n\n.bg-dark {\n  --bs-bg-opacity: 1;\n  background-color: rgba(var(--bs-dark-rgb), var(--bs-bg-opacity)) !important;\n}\n\n.bg-black {\n  --bs-bg-opacity: 1;\n  background-color: rgba(var(--bs-black-rgb), var(--bs-bg-opacity)) !important;\n}\n\n.bg-white {\n  --bs-bg-opacity: 1;\n  background-color: rgba(var(--bs-white-rgb), var(--bs-bg-opacity)) !important;\n}\n\n.bg-body {\n  --bs-bg-opacity: 1;\n  background-color: rgba(var(--bs-body-rgb), var(--bs-bg-opacity)) !important;\n}\n\n.bg-transparent {\n  --bs-bg-opacity: 1;\n  background-color: transparent !important;\n}\n\n.bg-opacity-10 {\n  --bs-bg-opacity: 0.1;\n}\n\n.bg-opacity-25 {\n  --bs-bg-opacity: 0.25;\n}\n\n.bg-opacity-50 {\n  --bs-bg-opacity: 0.5;\n}\n\n.bg-opacity-75 {\n  --bs-bg-opacity: 0.75;\n}\n\n.bg-opacity-100 {\n  --bs-bg-opacity: 1;\n}\n\n.bg-gradient {\n  background-image: var(--bs-gradient) !important;\n}\n\n.user-select-all {\n  -webkit-user-select: all !important;\n  -moz-user-select: all !important;\n  user-select: all !important;\n}\n\n.user-select-auto {\n  -webkit-user-select: auto !important;\n  -moz-user-select: auto !important;\n  user-select: auto !important;\n}\n\n.user-select-none {\n  -webkit-user-select: none !important;\n  -moz-user-select: none !important;\n  user-select: none !important;\n}\n\n.pe-none {\n  pointer-events: none !important;\n}\n\n.pe-auto {\n  pointer-events: auto !important;\n}\n\n.rounded {\n  border-radius: 0.25rem !important;\n}\n\n.rounded-0 {\n  border-radius: 0 !important;\n}\n\n.rounded-1 {\n  border-radius: 0.2rem !important;\n}\n\n.rounded-2 {\n  border-radius: 0.25rem !important;\n}\n\n.rounded-3 {\n  border-radius: 0.3rem !important;\n}\n\n.rounded-circle {\n  border-radius: 50% !important;\n}\n\n.rounded-pill {\n  border-radius: 50rem !important;\n}\n\n.rounded-top {\n  border-top-left-radius: 0.25rem !important;\n  border-top-right-radius: 0.25rem !important;\n}\n\n.rounded-end {\n  border-top-right-radius: 0.25rem !important;\n  border-bottom-right-radius: 0.25rem !important;\n}\n\n.rounded-bottom {\n  border-bottom-right-radius: 0.25rem !important;\n  border-bottom-left-radius: 0.25rem !important;\n}\n\n.rounded-start {\n  border-bottom-left-radius: 0.25rem !important;\n  border-top-left-radius: 0.25rem !important;\n}\n\n.visible {\n  visibility: visible !important;\n}\n\n.invisible {\n  visibility: hidden !important;\n}\n\n@media (min-width: 576px) {\n  .float-sm-start {\n    float: left !important;\n  }\n\n  .float-sm-end {\n    float: right !important;\n  }\n\n  .float-sm-none {\n    float: none !important;\n  }\n\n  .d-sm-inline {\n    display: inline !important;\n  }\n\n  .d-sm-inline-block {\n    display: inline-block !important;\n  }\n\n  .d-sm-block {\n    display: block !important;\n  }\n\n  .d-sm-grid {\n    display: grid !important;\n  }\n\n  .d-sm-table {\n    display: table !important;\n  }\n\n  .d-sm-table-row {\n    display: table-row !important;\n  }\n\n  .d-sm-table-cell {\n    display: table-cell !important;\n  }\n\n  .d-sm-flex {\n    display: flex !important;\n  }\n\n  .d-sm-inline-flex {\n    display: inline-flex !important;\n  }\n\n  .d-sm-none {\n    display: none !important;\n  }\n\n  .flex-sm-fill {\n    flex: 1 1 auto !important;\n  }\n\n  .flex-sm-row {\n    flex-direction: row !important;\n  }\n\n  .flex-sm-column {\n    flex-direction: column !important;\n  }\n\n  .flex-sm-row-reverse {\n    flex-direction: row-reverse !important;\n  }\n\n  .flex-sm-column-reverse {\n    flex-direction: column-reverse !important;\n  }\n\n  .flex-sm-grow-0 {\n    flex-grow: 0 !important;\n  }\n\n  .flex-sm-grow-1 {\n    flex-grow: 1 !important;\n  }\n\n  .flex-sm-shrink-0 {\n    flex-shrink: 0 !important;\n  }\n\n  .flex-sm-shrink-1 {\n    flex-shrink: 1 !important;\n  }\n\n  .flex-sm-wrap {\n    flex-wrap: wrap !important;\n  }\n\n  .flex-sm-nowrap {\n    flex-wrap: nowrap !important;\n  }\n\n  .flex-sm-wrap-reverse {\n    flex-wrap: wrap-reverse !important;\n  }\n\n  .gap-sm-0 {\n    gap: 0 !important;\n  }\n\n  .gap-sm-1 {\n    gap: 0.25rem !important;\n  }\n\n  .gap-sm-2 {\n    gap: 0.5rem !important;\n  }\n\n  .gap-sm-3 {\n    gap: 1rem !important;\n  }\n\n  .gap-sm-4 {\n    gap: 1.5rem !important;\n  }\n\n  .gap-sm-5 {\n    gap: 3rem !important;\n  }\n\n  .justify-content-sm-start {\n    justify-content: flex-start !important;\n  }\n\n  .justify-content-sm-end {\n    justify-content: flex-end !important;\n  }\n\n  .justify-content-sm-center {\n    justify-content: center !important;\n  }\n\n  .justify-content-sm-between {\n    justify-content: space-between !important;\n  }\n\n  .justify-content-sm-around {\n    justify-content: space-around !important;\n  }\n\n  .justify-content-sm-evenly {\n    justify-content: space-evenly !important;\n  }\n\n  .align-items-sm-start {\n    align-items: flex-start !important;\n  }\n\n  .align-items-sm-end {\n    align-items: flex-end !important;\n  }\n\n  .align-items-sm-center {\n    align-items: center !important;\n  }\n\n  .align-items-sm-baseline {\n    align-items: baseline !important;\n  }\n\n  .align-items-sm-stretch {\n    align-items: stretch !important;\n  }\n\n  .align-content-sm-start {\n    align-content: flex-start !important;\n  }\n\n  .align-content-sm-end {\n    align-content: flex-end !important;\n  }\n\n  .align-content-sm-center {\n    align-content: center !important;\n  }\n\n  .align-content-sm-between {\n    align-content: space-between !important;\n  }\n\n  .align-content-sm-around {\n    align-content: space-around !important;\n  }\n\n  .align-content-sm-stretch {\n    align-content: stretch !important;\n  }\n\n  .align-self-sm-auto {\n    align-self: auto !important;\n  }\n\n  .align-self-sm-start {\n    align-self: flex-start !important;\n  }\n\n  .align-self-sm-end {\n    align-self: flex-end !important;\n  }\n\n  .align-self-sm-center {\n    align-self: center !important;\n  }\n\n  .align-self-sm-baseline {\n    align-self: baseline !important;\n  }\n\n  .align-self-sm-stretch {\n    align-self: stretch !important;\n  }\n\n  .order-sm-first {\n    order: -1 !important;\n  }\n\n  .order-sm-0 {\n    order: 0 !important;\n  }\n\n  .order-sm-1 {\n    order: 1 !important;\n  }\n\n  .order-sm-2 {\n    order: 2 !important;\n  }\n\n  .order-sm-3 {\n    order: 3 !important;\n  }\n\n  .order-sm-4 {\n    order: 4 !important;\n  }\n\n  .order-sm-5 {\n    order: 5 !important;\n  }\n\n  .order-sm-last {\n    order: 6 !important;\n  }\n\n  .m-sm-0 {\n    margin: 0 !important;\n  }\n\n  .m-sm-1 {\n    margin: 0.25rem !important;\n  }\n\n  .m-sm-2 {\n    margin: 0.5rem !important;\n  }\n\n  .m-sm-3 {\n    margin: 1rem !important;\n  }\n\n  .m-sm-4 {\n    margin: 1.5rem !important;\n  }\n\n  .m-sm-5 {\n    margin: 3rem !important;\n  }\n\n  .m-sm-auto {\n    margin: auto !important;\n  }\n\n  .mx-sm-0 {\n    margin-right: 0 !important;\n    margin-left: 0 !important;\n  }\n\n  .mx-sm-1 {\n    margin-right: 0.25rem !important;\n    margin-left: 0.25rem !important;\n  }\n\n  .mx-sm-2 {\n    margin-right: 0.5rem !important;\n    margin-left: 0.5rem !important;\n  }\n\n  .mx-sm-3 {\n    margin-right: 1rem !important;\n    margin-left: 1rem !important;\n  }\n\n  .mx-sm-4 {\n    margin-right: 1.5rem !important;\n    margin-left: 1.5rem !important;\n  }\n\n  .mx-sm-5 {\n    margin-right: 3rem !important;\n    margin-left: 3rem !important;\n  }\n\n  .mx-sm-auto {\n    margin-right: auto !important;\n    margin-left: auto !important;\n  }\n\n  .my-sm-0 {\n    margin-top: 0 !important;\n    margin-bottom: 0 !important;\n  }\n\n  .my-sm-1 {\n    margin-top: 0.25rem !important;\n    margin-bottom: 0.25rem !important;\n  }\n\n  .my-sm-2 {\n    margin-top: 0.5rem !important;\n    margin-bottom: 0.5rem !important;\n  }\n\n  .my-sm-3 {\n    margin-top: 1rem !important;\n    margin-bottom: 1rem !important;\n  }\n\n  .my-sm-4 {\n    margin-top: 1.5rem !important;\n    margin-bottom: 1.5rem !important;\n  }\n\n  .my-sm-5 {\n    margin-top: 3rem !important;\n    margin-bottom: 3rem !important;\n  }\n\n  .my-sm-auto {\n    margin-top: auto !important;\n    margin-bottom: auto !important;\n  }\n\n  .mt-sm-0 {\n    margin-top: 0 !important;\n  }\n\n  .mt-sm-1 {\n    margin-top: 0.25rem !important;\n  }\n\n  .mt-sm-2 {\n    margin-top: 0.5rem !important;\n  }\n\n  .mt-sm-3 {\n    margin-top: 1rem !important;\n  }\n\n  .mt-sm-4 {\n    margin-top: 1.5rem !important;\n  }\n\n  .mt-sm-5 {\n    margin-top: 3rem !important;\n  }\n\n  .mt-sm-auto {\n    margin-top: auto !important;\n  }\n\n  .me-sm-0 {\n    margin-right: 0 !important;\n  }\n\n  .me-sm-1 {\n    margin-right: 0.25rem !important;\n  }\n\n  .me-sm-2 {\n    margin-right: 0.5rem !important;\n  }\n\n  .me-sm-3 {\n    margin-right: 1rem !important;\n  }\n\n  .me-sm-4 {\n    margin-right: 1.5rem !important;\n  }\n\n  .me-sm-5 {\n    margin-right: 3rem !important;\n  }\n\n  .me-sm-auto {\n    margin-right: auto !important;\n  }\n\n  .mb-sm-0 {\n    margin-bottom: 0 !important;\n  }\n\n  .mb-sm-1 {\n    margin-bottom: 0.25rem !important;\n  }\n\n  .mb-sm-2 {\n    margin-bottom: 0.5rem !important;\n  }\n\n  .mb-sm-3 {\n    margin-bottom: 1rem !important;\n  }\n\n  .mb-sm-4 {\n    margin-bottom: 1.5rem !important;\n  }\n\n  .mb-sm-5 {\n    margin-bottom: 3rem !important;\n  }\n\n  .mb-sm-auto {\n    margin-bottom: auto !important;\n  }\n\n  .ms-sm-0 {\n    margin-left: 0 !important;\n  }\n\n  .ms-sm-1 {\n    margin-left: 0.25rem !important;\n  }\n\n  .ms-sm-2 {\n    margin-left: 0.5rem !important;\n  }\n\n  .ms-sm-3 {\n    margin-left: 1rem !important;\n  }\n\n  .ms-sm-4 {\n    margin-left: 1.5rem !important;\n  }\n\n  .ms-sm-5 {\n    margin-left: 3rem !important;\n  }\n\n  .ms-sm-auto {\n    margin-left: auto !important;\n  }\n\n  .p-sm-0 {\n    padding: 0 !important;\n  }\n\n  .p-sm-1 {\n    padding: 0.25rem !important;\n  }\n\n  .p-sm-2 {\n    padding: 0.5rem !important;\n  }\n\n  .p-sm-3 {\n    padding: 1rem !important;\n  }\n\n  .p-sm-4 {\n    padding: 1.5rem !important;\n  }\n\n  .p-sm-5 {\n    padding: 3rem !important;\n  }\n\n  .px-sm-0 {\n    padding-right: 0 !important;\n    padding-left: 0 !important;\n  }\n\n  .px-sm-1 {\n    padding-right: 0.25rem !important;\n    padding-left: 0.25rem !important;\n  }\n\n  .px-sm-2 {\n    padding-right: 0.5rem !important;\n    padding-left: 0.5rem !important;\n  }\n\n  .px-sm-3 {\n    padding-right: 1rem !important;\n    padding-left: 1rem !important;\n  }\n\n  .px-sm-4 {\n    padding-right: 1.5rem !important;\n    padding-left: 1.5rem !important;\n  }\n\n  .px-sm-5 {\n    padding-right: 3rem !important;\n    padding-left: 3rem !important;\n  }\n\n  .py-sm-0 {\n    padding-top: 0 !important;\n    padding-bottom: 0 !important;\n  }\n\n  .py-sm-1 {\n    padding-top: 0.25rem !important;\n    padding-bottom: 0.25rem !important;\n  }\n\n  .py-sm-2 {\n    padding-top: 0.5rem !important;\n    padding-bottom: 0.5rem !important;\n  }\n\n  .py-sm-3 {\n    padding-top: 1rem !important;\n    padding-bottom: 1rem !important;\n  }\n\n  .py-sm-4 {\n    padding-top: 1.5rem !important;\n    padding-bottom: 1.5rem !important;\n  }\n\n  .py-sm-5 {\n    padding-top: 3rem !important;\n    padding-bottom: 3rem !important;\n  }\n\n  .pt-sm-0 {\n    padding-top: 0 !important;\n  }\n\n  .pt-sm-1 {\n    padding-top: 0.25rem !important;\n  }\n\n  .pt-sm-2 {\n    padding-top: 0.5rem !important;\n  }\n\n  .pt-sm-3 {\n    padding-top: 1rem !important;\n  }\n\n  .pt-sm-4 {\n    padding-top: 1.5rem !important;\n  }\n\n  .pt-sm-5 {\n    padding-top: 3rem !important;\n  }\n\n  .pe-sm-0 {\n    padding-right: 0 !important;\n  }\n\n  .pe-sm-1 {\n    padding-right: 0.25rem !important;\n  }\n\n  .pe-sm-2 {\n    padding-right: 0.5rem !important;\n  }\n\n  .pe-sm-3 {\n    padding-right: 1rem !important;\n  }\n\n  .pe-sm-4 {\n    padding-right: 1.5rem !important;\n  }\n\n  .pe-sm-5 {\n    padding-right: 3rem !important;\n  }\n\n  .pb-sm-0 {\n    padding-bottom: 0 !important;\n  }\n\n  .pb-sm-1 {\n    padding-bottom: 0.25rem !important;\n  }\n\n  .pb-sm-2 {\n    padding-bottom: 0.5rem !important;\n  }\n\n  .pb-sm-3 {\n    padding-bottom: 1rem !important;\n  }\n\n  .pb-sm-4 {\n    padding-bottom: 1.5rem !important;\n  }\n\n  .pb-sm-5 {\n    padding-bottom: 3rem !important;\n  }\n\n  .ps-sm-0 {\n    padding-left: 0 !important;\n  }\n\n  .ps-sm-1 {\n    padding-left: 0.25rem !important;\n  }\n\n  .ps-sm-2 {\n    padding-left: 0.5rem !important;\n  }\n\n  .ps-sm-3 {\n    padding-left: 1rem !important;\n  }\n\n  .ps-sm-4 {\n    padding-left: 1.5rem !important;\n  }\n\n  .ps-sm-5 {\n    padding-left: 3rem !important;\n  }\n\n  .text-sm-start {\n    text-align: left !important;\n  }\n\n  .text-sm-end {\n    text-align: right !important;\n  }\n\n  .text-sm-center {\n    text-align: center !important;\n  }\n}\n@media (min-width: 768px) {\n  .float-md-start {\n    float: left !important;\n  }\n\n  .float-md-end {\n    float: right !important;\n  }\n\n  .float-md-none {\n    float: none !important;\n  }\n\n  .d-md-inline {\n    display: inline !important;\n  }\n\n  .d-md-inline-block {\n    display: inline-block !important;\n  }\n\n  .d-md-block {\n    display: block !important;\n  }\n\n  .d-md-grid {\n    display: grid !important;\n  }\n\n  .d-md-table {\n    display: table !important;\n  }\n\n  .d-md-table-row {\n    display: table-row !important;\n  }\n\n  .d-md-table-cell {\n    display: table-cell !important;\n  }\n\n  .d-md-flex {\n    display: flex !important;\n  }\n\n  .d-md-inline-flex {\n    display: inline-flex !important;\n  }\n\n  .d-md-none {\n    display: none !important;\n  }\n\n  .flex-md-fill {\n    flex: 1 1 auto !important;\n  }\n\n  .flex-md-row {\n    flex-direction: row !important;\n  }\n\n  .flex-md-column {\n    flex-direction: column !important;\n  }\n\n  .flex-md-row-reverse {\n    flex-direction: row-reverse !important;\n  }\n\n  .flex-md-column-reverse {\n    flex-direction: column-reverse !important;\n  }\n\n  .flex-md-grow-0 {\n    flex-grow: 0 !important;\n  }\n\n  .flex-md-grow-1 {\n    flex-grow: 1 !important;\n  }\n\n  .flex-md-shrink-0 {\n    flex-shrink: 0 !important;\n  }\n\n  .flex-md-shrink-1 {\n    flex-shrink: 1 !important;\n  }\n\n  .flex-md-wrap {\n    flex-wrap: wrap !important;\n  }\n\n  .flex-md-nowrap {\n    flex-wrap: nowrap !important;\n  }\n\n  .flex-md-wrap-reverse {\n    flex-wrap: wrap-reverse !important;\n  }\n\n  .gap-md-0 {\n    gap: 0 !important;\n  }\n\n  .gap-md-1 {\n    gap: 0.25rem !important;\n  }\n\n  .gap-md-2 {\n    gap: 0.5rem !important;\n  }\n\n  .gap-md-3 {\n    gap: 1rem !important;\n  }\n\n  .gap-md-4 {\n    gap: 1.5rem !important;\n  }\n\n  .gap-md-5 {\n    gap: 3rem !important;\n  }\n\n  .justify-content-md-start {\n    justify-content: flex-start !important;\n  }\n\n  .justify-content-md-end {\n    justify-content: flex-end !important;\n  }\n\n  .justify-content-md-center {\n    justify-content: center !important;\n  }\n\n  .justify-content-md-between {\n    justify-content: space-between !important;\n  }\n\n  .justify-content-md-around {\n    justify-content: space-around !important;\n  }\n\n  .justify-content-md-evenly {\n    justify-content: space-evenly !important;\n  }\n\n  .align-items-md-start {\n    align-items: flex-start !important;\n  }\n\n  .align-items-md-end {\n    align-items: flex-end !important;\n  }\n\n  .align-items-md-center {\n    align-items: center !important;\n  }\n\n  .align-items-md-baseline {\n    align-items: baseline !important;\n  }\n\n  .align-items-md-stretch {\n    align-items: stretch !important;\n  }\n\n  .align-content-md-start {\n    align-content: flex-start !important;\n  }\n\n  .align-content-md-end {\n    align-content: flex-end !important;\n  }\n\n  .align-content-md-center {\n    align-content: center !important;\n  }\n\n  .align-content-md-between {\n    align-content: space-between !important;\n  }\n\n  .align-content-md-around {\n    align-content: space-around !important;\n  }\n\n  .align-content-md-stretch {\n    align-content: stretch !important;\n  }\n\n  .align-self-md-auto {\n    align-self: auto !important;\n  }\n\n  .align-self-md-start {\n    align-self: flex-start !important;\n  }\n\n  .align-self-md-end {\n    align-self: flex-end !important;\n  }\n\n  .align-self-md-center {\n    align-self: center !important;\n  }\n\n  .align-self-md-baseline {\n    align-self: baseline !important;\n  }\n\n  .align-self-md-stretch {\n    align-self: stretch !important;\n  }\n\n  .order-md-first {\n    order: -1 !important;\n  }\n\n  .order-md-0 {\n    order: 0 !important;\n  }\n\n  .order-md-1 {\n    order: 1 !important;\n  }\n\n  .order-md-2 {\n    order: 2 !important;\n  }\n\n  .order-md-3 {\n    order: 3 !important;\n  }\n\n  .order-md-4 {\n    order: 4 !important;\n  }\n\n  .order-md-5 {\n    order: 5 !important;\n  }\n\n  .order-md-last {\n    order: 6 !important;\n  }\n\n  .m-md-0 {\n    margin: 0 !important;\n  }\n\n  .m-md-1 {\n    margin: 0.25rem !important;\n  }\n\n  .m-md-2 {\n    margin: 0.5rem !important;\n  }\n\n  .m-md-3 {\n    margin: 1rem !important;\n  }\n\n  .m-md-4 {\n    margin: 1.5rem !important;\n  }\n\n  .m-md-5 {\n    margin: 3rem !important;\n  }\n\n  .m-md-auto {\n    margin: auto !important;\n  }\n\n  .mx-md-0 {\n    margin-right: 0 !important;\n    margin-left: 0 !important;\n  }\n\n  .mx-md-1 {\n    margin-right: 0.25rem !important;\n    margin-left: 0.25rem !important;\n  }\n\n  .mx-md-2 {\n    margin-right: 0.5rem !important;\n    margin-left: 0.5rem !important;\n  }\n\n  .mx-md-3 {\n    margin-right: 1rem !important;\n    margin-left: 1rem !important;\n  }\n\n  .mx-md-4 {\n    margin-right: 1.5rem !important;\n    margin-left: 1.5rem !important;\n  }\n\n  .mx-md-5 {\n    margin-right: 3rem !important;\n    margin-left: 3rem !important;\n  }\n\n  .mx-md-auto {\n    margin-right: auto !important;\n    margin-left: auto !important;\n  }\n\n  .my-md-0 {\n    margin-top: 0 !important;\n    margin-bottom: 0 !important;\n  }\n\n  .my-md-1 {\n    margin-top: 0.25rem !important;\n    margin-bottom: 0.25rem !important;\n  }\n\n  .my-md-2 {\n    margin-top: 0.5rem !important;\n    margin-bottom: 0.5rem !important;\n  }\n\n  .my-md-3 {\n    margin-top: 1rem !important;\n    margin-bottom: 1rem !important;\n  }\n\n  .my-md-4 {\n    margin-top: 1.5rem !important;\n    margin-bottom: 1.5rem !important;\n  }\n\n  .my-md-5 {\n    margin-top: 3rem !important;\n    margin-bottom: 3rem !important;\n  }\n\n  .my-md-auto {\n    margin-top: auto !important;\n    margin-bottom: auto !important;\n  }\n\n  .mt-md-0 {\n    margin-top: 0 !important;\n  }\n\n  .mt-md-1 {\n    margin-top: 0.25rem !important;\n  }\n\n  .mt-md-2 {\n    margin-top: 0.5rem !important;\n  }\n\n  .mt-md-3 {\n    margin-top: 1rem !important;\n  }\n\n  .mt-md-4 {\n    margin-top: 1.5rem !important;\n  }\n\n  .mt-md-5 {\n    margin-top: 3rem !important;\n  }\n\n  .mt-md-auto {\n    margin-top: auto !important;\n  }\n\n  .me-md-0 {\n    margin-right: 0 !important;\n  }\n\n  .me-md-1 {\n    margin-right: 0.25rem !important;\n  }\n\n  .me-md-2 {\n    margin-right: 0.5rem !important;\n  }\n\n  .me-md-3 {\n    margin-right: 1rem !important;\n  }\n\n  .me-md-4 {\n    margin-right: 1.5rem !important;\n  }\n\n  .me-md-5 {\n    margin-right: 3rem !important;\n  }\n\n  .me-md-auto {\n    margin-right: auto !important;\n  }\n\n  .mb-md-0 {\n    margin-bottom: 0 !important;\n  }\n\n  .mb-md-1 {\n    margin-bottom: 0.25rem !important;\n  }\n\n  .mb-md-2 {\n    margin-bottom: 0.5rem !important;\n  }\n\n  .mb-md-3 {\n    margin-bottom: 1rem !important;\n  }\n\n  .mb-md-4 {\n    margin-bottom: 1.5rem !important;\n  }\n\n  .mb-md-5 {\n    margin-bottom: 3rem !important;\n  }\n\n  .mb-md-auto {\n    margin-bottom: auto !important;\n  }\n\n  .ms-md-0 {\n    margin-left: 0 !important;\n  }\n\n  .ms-md-1 {\n    margin-left: 0.25rem !important;\n  }\n\n  .ms-md-2 {\n    margin-left: 0.5rem !important;\n  }\n\n  .ms-md-3 {\n    margin-left: 1rem !important;\n  }\n\n  .ms-md-4 {\n    margin-left: 1.5rem !important;\n  }\n\n  .ms-md-5 {\n    margin-left: 3rem !important;\n  }\n\n  .ms-md-auto {\n    margin-left: auto !important;\n  }\n\n  .p-md-0 {\n    padding: 0 !important;\n  }\n\n  .p-md-1 {\n    padding: 0.25rem !important;\n  }\n\n  .p-md-2 {\n    padding: 0.5rem !important;\n  }\n\n  .p-md-3 {\n    padding: 1rem !important;\n  }\n\n  .p-md-4 {\n    padding: 1.5rem !important;\n  }\n\n  .p-md-5 {\n    padding: 3rem !important;\n  }\n\n  .px-md-0 {\n    padding-right: 0 !important;\n    padding-left: 0 !important;\n  }\n\n  .px-md-1 {\n    padding-right: 0.25rem !important;\n    padding-left: 0.25rem !important;\n  }\n\n  .px-md-2 {\n    padding-right: 0.5rem !important;\n    padding-left: 0.5rem !important;\n  }\n\n  .px-md-3 {\n    padding-right: 1rem !important;\n    padding-left: 1rem !important;\n  }\n\n  .px-md-4 {\n    padding-right: 1.5rem !important;\n    padding-left: 1.5rem !important;\n  }\n\n  .px-md-5 {\n    padding-right: 3rem !important;\n    padding-left: 3rem !important;\n  }\n\n  .py-md-0 {\n    padding-top: 0 !important;\n    padding-bottom: 0 !important;\n  }\n\n  .py-md-1 {\n    padding-top: 0.25rem !important;\n    padding-bottom: 0.25rem !important;\n  }\n\n  .py-md-2 {\n    padding-top: 0.5rem !important;\n    padding-bottom: 0.5rem !important;\n  }\n\n  .py-md-3 {\n    padding-top: 1rem !important;\n    padding-bottom: 1rem !important;\n  }\n\n  .py-md-4 {\n    padding-top: 1.5rem !important;\n    padding-bottom: 1.5rem !important;\n  }\n\n  .py-md-5 {\n    padding-top: 3rem !important;\n    padding-bottom: 3rem !important;\n  }\n\n  .pt-md-0 {\n    padding-top: 0 !important;\n  }\n\n  .pt-md-1 {\n    padding-top: 0.25rem !important;\n  }\n\n  .pt-md-2 {\n    padding-top: 0.5rem !important;\n  }\n\n  .pt-md-3 {\n    padding-top: 1rem !important;\n  }\n\n  .pt-md-4 {\n    padding-top: 1.5rem !important;\n  }\n\n  .pt-md-5 {\n    padding-top: 3rem !important;\n  }\n\n  .pe-md-0 {\n    padding-right: 0 !important;\n  }\n\n  .pe-md-1 {\n    padding-right: 0.25rem !important;\n  }\n\n  .pe-md-2 {\n    padding-right: 0.5rem !important;\n  }\n\n  .pe-md-3 {\n    padding-right: 1rem !important;\n  }\n\n  .pe-md-4 {\n    padding-right: 1.5rem !important;\n  }\n\n  .pe-md-5 {\n    padding-right: 3rem !important;\n  }\n\n  .pb-md-0 {\n    padding-bottom: 0 !important;\n  }\n\n  .pb-md-1 {\n    padding-bottom: 0.25rem !important;\n  }\n\n  .pb-md-2 {\n    padding-bottom: 0.5rem !important;\n  }\n\n  .pb-md-3 {\n    padding-bottom: 1rem !important;\n  }\n\n  .pb-md-4 {\n    padding-bottom: 1.5rem !important;\n  }\n\n  .pb-md-5 {\n    padding-bottom: 3rem !important;\n  }\n\n  .ps-md-0 {\n    padding-left: 0 !important;\n  }\n\n  .ps-md-1 {\n    padding-left: 0.25rem !important;\n  }\n\n  .ps-md-2 {\n    padding-left: 0.5rem !important;\n  }\n\n  .ps-md-3 {\n    padding-left: 1rem !important;\n  }\n\n  .ps-md-4 {\n    padding-left: 1.5rem !important;\n  }\n\n  .ps-md-5 {\n    padding-left: 3rem !important;\n  }\n\n  .text-md-start {\n    text-align: left !important;\n  }\n\n  .text-md-end {\n    text-align: right !important;\n  }\n\n  .text-md-center {\n    text-align: center !important;\n  }\n}\n@media (min-width: 992px) {\n  .float-lg-start {\n    float: left !important;\n  }\n\n  .float-lg-end {\n    float: right !important;\n  }\n\n  .float-lg-none {\n    float: none !important;\n  }\n\n  .d-lg-inline {\n    display: inline !important;\n  }\n\n  .d-lg-inline-block {\n    display: inline-block !important;\n  }\n\n  .d-lg-block {\n    display: block !important;\n  }\n\n  .d-lg-grid {\n    display: grid !important;\n  }\n\n  .d-lg-table {\n    display: table !important;\n  }\n\n  .d-lg-table-row {\n    display: table-row !important;\n  }\n\n  .d-lg-table-cell {\n    display: table-cell !important;\n  }\n\n  .d-lg-flex {\n    display: flex !important;\n  }\n\n  .d-lg-inline-flex {\n    display: inline-flex !important;\n  }\n\n  .d-lg-none {\n    display: none !important;\n  }\n\n  .flex-lg-fill {\n    flex: 1 1 auto !important;\n  }\n\n  .flex-lg-row {\n    flex-direction: row !important;\n  }\n\n  .flex-lg-column {\n    flex-direction: column !important;\n  }\n\n  .flex-lg-row-reverse {\n    flex-direction: row-reverse !important;\n  }\n\n  .flex-lg-column-reverse {\n    flex-direction: column-reverse !important;\n  }\n\n  .flex-lg-grow-0 {\n    flex-grow: 0 !important;\n  }\n\n  .flex-lg-grow-1 {\n    flex-grow: 1 !important;\n  }\n\n  .flex-lg-shrink-0 {\n    flex-shrink: 0 !important;\n  }\n\n  .flex-lg-shrink-1 {\n    flex-shrink: 1 !important;\n  }\n\n  .flex-lg-wrap {\n    flex-wrap: wrap !important;\n  }\n\n  .flex-lg-nowrap {\n    flex-wrap: nowrap !important;\n  }\n\n  .flex-lg-wrap-reverse {\n    flex-wrap: wrap-reverse !important;\n  }\n\n  .gap-lg-0 {\n    gap: 0 !important;\n  }\n\n  .gap-lg-1 {\n    gap: 0.25rem !important;\n  }\n\n  .gap-lg-2 {\n    gap: 0.5rem !important;\n  }\n\n  .gap-lg-3 {\n    gap: 1rem !important;\n  }\n\n  .gap-lg-4 {\n    gap: 1.5rem !important;\n  }\n\n  .gap-lg-5 {\n    gap: 3rem !important;\n  }\n\n  .justify-content-lg-start {\n    justify-content: flex-start !important;\n  }\n\n  .justify-content-lg-end {\n    justify-content: flex-end !important;\n  }\n\n  .justify-content-lg-center {\n    justify-content: center !important;\n  }\n\n  .justify-content-lg-between {\n    justify-content: space-between !important;\n  }\n\n  .justify-content-lg-around {\n    justify-content: space-around !important;\n  }\n\n  .justify-content-lg-evenly {\n    justify-content: space-evenly !important;\n  }\n\n  .align-items-lg-start {\n    align-items: flex-start !important;\n  }\n\n  .align-items-lg-end {\n    align-items: flex-end !important;\n  }\n\n  .align-items-lg-center {\n    align-items: center !important;\n  }\n\n  .align-items-lg-baseline {\n    align-items: baseline !important;\n  }\n\n  .align-items-lg-stretch {\n    align-items: stretch !important;\n  }\n\n  .align-content-lg-start {\n    align-content: flex-start !important;\n  }\n\n  .align-content-lg-end {\n    align-content: flex-end !important;\n  }\n\n  .align-content-lg-center {\n    align-content: center !important;\n  }\n\n  .align-content-lg-between {\n    align-content: space-between !important;\n  }\n\n  .align-content-lg-around {\n    align-content: space-around !important;\n  }\n\n  .align-content-lg-stretch {\n    align-content: stretch !important;\n  }\n\n  .align-self-lg-auto {\n    align-self: auto !important;\n  }\n\n  .align-self-lg-start {\n    align-self: flex-start !important;\n  }\n\n  .align-self-lg-end {\n    align-self: flex-end !important;\n  }\n\n  .align-self-lg-center {\n    align-self: center !important;\n  }\n\n  .align-self-lg-baseline {\n    align-self: baseline !important;\n  }\n\n  .align-self-lg-stretch {\n    align-self: stretch !important;\n  }\n\n  .order-lg-first {\n    order: -1 !important;\n  }\n\n  .order-lg-0 {\n    order: 0 !important;\n  }\n\n  .order-lg-1 {\n    order: 1 !important;\n  }\n\n  .order-lg-2 {\n    order: 2 !important;\n  }\n\n  .order-lg-3 {\n    order: 3 !important;\n  }\n\n  .order-lg-4 {\n    order: 4 !important;\n  }\n\n  .order-lg-5 {\n    order: 5 !important;\n  }\n\n  .order-lg-last {\n    order: 6 !important;\n  }\n\n  .m-lg-0 {\n    margin: 0 !important;\n  }\n\n  .m-lg-1 {\n    margin: 0.25rem !important;\n  }\n\n  .m-lg-2 {\n    margin: 0.5rem !important;\n  }\n\n  .m-lg-3 {\n    margin: 1rem !important;\n  }\n\n  .m-lg-4 {\n    margin: 1.5rem !important;\n  }\n\n  .m-lg-5 {\n    margin: 3rem !important;\n  }\n\n  .m-lg-auto {\n    margin: auto !important;\n  }\n\n  .mx-lg-0 {\n    margin-right: 0 !important;\n    margin-left: 0 !important;\n  }\n\n  .mx-lg-1 {\n    margin-right: 0.25rem !important;\n    margin-left: 0.25rem !important;\n  }\n\n  .mx-lg-2 {\n    margin-right: 0.5rem !important;\n    margin-left: 0.5rem !important;\n  }\n\n  .mx-lg-3 {\n    margin-right: 1rem !important;\n    margin-left: 1rem !important;\n  }\n\n  .mx-lg-4 {\n    margin-right: 1.5rem !important;\n    margin-left: 1.5rem !important;\n  }\n\n  .mx-lg-5 {\n    margin-right: 3rem !important;\n    margin-left: 3rem !important;\n  }\n\n  .mx-lg-auto {\n    margin-right: auto !important;\n    margin-left: auto !important;\n  }\n\n  .my-lg-0 {\n    margin-top: 0 !important;\n    margin-bottom: 0 !important;\n  }\n\n  .my-lg-1 {\n    margin-top: 0.25rem !important;\n    margin-bottom: 0.25rem !important;\n  }\n\n  .my-lg-2 {\n    margin-top: 0.5rem !important;\n    margin-bottom: 0.5rem !important;\n  }\n\n  .my-lg-3 {\n    margin-top: 1rem !important;\n    margin-bottom: 1rem !important;\n  }\n\n  .my-lg-4 {\n    margin-top: 1.5rem !important;\n    margin-bottom: 1.5rem !important;\n  }\n\n  .my-lg-5 {\n    margin-top: 3rem !important;\n    margin-bottom: 3rem !important;\n  }\n\n  .my-lg-auto {\n    margin-top: auto !important;\n    margin-bottom: auto !important;\n  }\n\n  .mt-lg-0 {\n    margin-top: 0 !important;\n  }\n\n  .mt-lg-1 {\n    margin-top: 0.25rem !important;\n  }\n\n  .mt-lg-2 {\n    margin-top: 0.5rem !important;\n  }\n\n  .mt-lg-3 {\n    margin-top: 1rem !important;\n  }\n\n  .mt-lg-4 {\n    margin-top: 1.5rem !important;\n  }\n\n  .mt-lg-5 {\n    margin-top: 3rem !important;\n  }\n\n  .mt-lg-auto {\n    margin-top: auto !important;\n  }\n\n  .me-lg-0 {\n    margin-right: 0 !important;\n  }\n\n  .me-lg-1 {\n    margin-right: 0.25rem !important;\n  }\n\n  .me-lg-2 {\n    margin-right: 0.5rem !important;\n  }\n\n  .me-lg-3 {\n    margin-right: 1rem !important;\n  }\n\n  .me-lg-4 {\n    margin-right: 1.5rem !important;\n  }\n\n  .me-lg-5 {\n    margin-right: 3rem !important;\n  }\n\n  .me-lg-auto {\n    margin-right: auto !important;\n  }\n\n  .mb-lg-0 {\n    margin-bottom: 0 !important;\n  }\n\n  .mb-lg-1 {\n    margin-bottom: 0.25rem !important;\n  }\n\n  .mb-lg-2 {\n    margin-bottom: 0.5rem !important;\n  }\n\n  .mb-lg-3 {\n    margin-bottom: 1rem !important;\n  }\n\n  .mb-lg-4 {\n    margin-bottom: 1.5rem !important;\n  }\n\n  .mb-lg-5 {\n    margin-bottom: 3rem !important;\n  }\n\n  .mb-lg-auto {\n    margin-bottom: auto !important;\n  }\n\n  .ms-lg-0 {\n    margin-left: 0 !important;\n  }\n\n  .ms-lg-1 {\n    margin-left: 0.25rem !important;\n  }\n\n  .ms-lg-2 {\n    margin-left: 0.5rem !important;\n  }\n\n  .ms-lg-3 {\n    margin-left: 1rem !important;\n  }\n\n  .ms-lg-4 {\n    margin-left: 1.5rem !important;\n  }\n\n  .ms-lg-5 {\n    margin-left: 3rem !important;\n  }\n\n  .ms-lg-auto {\n    margin-left: auto !important;\n  }\n\n  .p-lg-0 {\n    padding: 0 !important;\n  }\n\n  .p-lg-1 {\n    padding: 0.25rem !important;\n  }\n\n  .p-lg-2 {\n    padding: 0.5rem !important;\n  }\n\n  .p-lg-3 {\n    padding: 1rem !important;\n  }\n\n  .p-lg-4 {\n    padding: 1.5rem !important;\n  }\n\n  .p-lg-5 {\n    padding: 3rem !important;\n  }\n\n  .px-lg-0 {\n    padding-right: 0 !important;\n    padding-left: 0 !important;\n  }\n\n  .px-lg-1 {\n    padding-right: 0.25rem !important;\n    padding-left: 0.25rem !important;\n  }\n\n  .px-lg-2 {\n    padding-right: 0.5rem !important;\n    padding-left: 0.5rem !important;\n  }\n\n  .px-lg-3 {\n    padding-right: 1rem !important;\n    padding-left: 1rem !important;\n  }\n\n  .px-lg-4 {\n    padding-right: 1.5rem !important;\n    padding-left: 1.5rem !important;\n  }\n\n  .px-lg-5 {\n    padding-right: 3rem !important;\n    padding-left: 3rem !important;\n  }\n\n  .py-lg-0 {\n    padding-top: 0 !important;\n    padding-bottom: 0 !important;\n  }\n\n  .py-lg-1 {\n    padding-top: 0.25rem !important;\n    padding-bottom: 0.25rem !important;\n  }\n\n  .py-lg-2 {\n    padding-top: 0.5rem !important;\n    padding-bottom: 0.5rem !important;\n  }\n\n  .py-lg-3 {\n    padding-top: 1rem !important;\n    padding-bottom: 1rem !important;\n  }\n\n  .py-lg-4 {\n    padding-top: 1.5rem !important;\n    padding-bottom: 1.5rem !important;\n  }\n\n  .py-lg-5 {\n    padding-top: 3rem !important;\n    padding-bottom: 3rem !important;\n  }\n\n  .pt-lg-0 {\n    padding-top: 0 !important;\n  }\n\n  .pt-lg-1 {\n    padding-top: 0.25rem !important;\n  }\n\n  .pt-lg-2 {\n    padding-top: 0.5rem !important;\n  }\n\n  .pt-lg-3 {\n    padding-top: 1rem !important;\n  }\n\n  .pt-lg-4 {\n    padding-top: 1.5rem !important;\n  }\n\n  .pt-lg-5 {\n    padding-top: 3rem !important;\n  }\n\n  .pe-lg-0 {\n    padding-right: 0 !important;\n  }\n\n  .pe-lg-1 {\n    padding-right: 0.25rem !important;\n  }\n\n  .pe-lg-2 {\n    padding-right: 0.5rem !important;\n  }\n\n  .pe-lg-3 {\n    padding-right: 1rem !important;\n  }\n\n  .pe-lg-4 {\n    padding-right: 1.5rem !important;\n  }\n\n  .pe-lg-5 {\n    padding-right: 3rem !important;\n  }\n\n  .pb-lg-0 {\n    padding-bottom: 0 !important;\n  }\n\n  .pb-lg-1 {\n    padding-bottom: 0.25rem !important;\n  }\n\n  .pb-lg-2 {\n    padding-bottom: 0.5rem !important;\n  }\n\n  .pb-lg-3 {\n    padding-bottom: 1rem !important;\n  }\n\n  .pb-lg-4 {\n    padding-bottom: 1.5rem !important;\n  }\n\n  .pb-lg-5 {\n    padding-bottom: 3rem !important;\n  }\n\n  .ps-lg-0 {\n    padding-left: 0 !important;\n  }\n\n  .ps-lg-1 {\n    padding-left: 0.25rem !important;\n  }\n\n  .ps-lg-2 {\n    padding-left: 0.5rem !important;\n  }\n\n  .ps-lg-3 {\n    padding-left: 1rem !important;\n  }\n\n  .ps-lg-4 {\n    padding-left: 1.5rem !important;\n  }\n\n  .ps-lg-5 {\n    padding-left: 3rem !important;\n  }\n\n  .text-lg-start {\n    text-align: left !important;\n  }\n\n  .text-lg-end {\n    text-align: right !important;\n  }\n\n  .text-lg-center {\n    text-align: center !important;\n  }\n}\n@media (min-width: 1200px) {\n  .float-xl-start {\n    float: left !important;\n  }\n\n  .float-xl-end {\n    float: right !important;\n  }\n\n  .float-xl-none {\n    float: none !important;\n  }\n\n  .d-xl-inline {\n    display: inline !important;\n  }\n\n  .d-xl-inline-block {\n    display: inline-block !important;\n  }\n\n  .d-xl-block {\n    display: block !important;\n  }\n\n  .d-xl-grid {\n    display: grid !important;\n  }\n\n  .d-xl-table {\n    display: table !important;\n  }\n\n  .d-xl-table-row {\n    display: table-row !important;\n  }\n\n  .d-xl-table-cell {\n    display: table-cell !important;\n  }\n\n  .d-xl-flex {\n    display: flex !important;\n  }\n\n  .d-xl-inline-flex {\n    display: inline-flex !important;\n  }\n\n  .d-xl-none {\n    display: none !important;\n  }\n\n  .flex-xl-fill {\n    flex: 1 1 auto !important;\n  }\n\n  .flex-xl-row {\n    flex-direction: row !important;\n  }\n\n  .flex-xl-column {\n    flex-direction: column !important;\n  }\n\n  .flex-xl-row-reverse {\n    flex-direction: row-reverse !important;\n  }\n\n  .flex-xl-column-reverse {\n    flex-direction: column-reverse !important;\n  }\n\n  .flex-xl-grow-0 {\n    flex-grow: 0 !important;\n  }\n\n  .flex-xl-grow-1 {\n    flex-grow: 1 !important;\n  }\n\n  .flex-xl-shrink-0 {\n    flex-shrink: 0 !important;\n  }\n\n  .flex-xl-shrink-1 {\n    flex-shrink: 1 !important;\n  }\n\n  .flex-xl-wrap {\n    flex-wrap: wrap !important;\n  }\n\n  .flex-xl-nowrap {\n    flex-wrap: nowrap !important;\n  }\n\n  .flex-xl-wrap-reverse {\n    flex-wrap: wrap-reverse !important;\n  }\n\n  .gap-xl-0 {\n    gap: 0 !important;\n  }\n\n  .gap-xl-1 {\n    gap: 0.25rem !important;\n  }\n\n  .gap-xl-2 {\n    gap: 0.5rem !important;\n  }\n\n  .gap-xl-3 {\n    gap: 1rem !important;\n  }\n\n  .gap-xl-4 {\n    gap: 1.5rem !important;\n  }\n\n  .gap-xl-5 {\n    gap: 3rem !important;\n  }\n\n  .justify-content-xl-start {\n    justify-content: flex-start !important;\n  }\n\n  .justify-content-xl-end {\n    justify-content: flex-end !important;\n  }\n\n  .justify-content-xl-center {\n    justify-content: center !important;\n  }\n\n  .justify-content-xl-between {\n    justify-content: space-between !important;\n  }\n\n  .justify-content-xl-around {\n    justify-content: space-around !important;\n  }\n\n  .justify-content-xl-evenly {\n    justify-content: space-evenly !important;\n  }\n\n  .align-items-xl-start {\n    align-items: flex-start !important;\n  }\n\n  .align-items-xl-end {\n    align-items: flex-end !important;\n  }\n\n  .align-items-xl-center {\n    align-items: center !important;\n  }\n\n  .align-items-xl-baseline {\n    align-items: baseline !important;\n  }\n\n  .align-items-xl-stretch {\n    align-items: stretch !important;\n  }\n\n  .align-content-xl-start {\n    align-content: flex-start !important;\n  }\n\n  .align-content-xl-end {\n    align-content: flex-end !important;\n  }\n\n  .align-content-xl-center {\n    align-content: center !important;\n  }\n\n  .align-content-xl-between {\n    align-content: space-between !important;\n  }\n\n  .align-content-xl-around {\n    align-content: space-around !important;\n  }\n\n  .align-content-xl-stretch {\n    align-content: stretch !important;\n  }\n\n  .align-self-xl-auto {\n    align-self: auto !important;\n  }\n\n  .align-self-xl-start {\n    align-self: flex-start !important;\n  }\n\n  .align-self-xl-end {\n    align-self: flex-end !important;\n  }\n\n  .align-self-xl-center {\n    align-self: center !important;\n  }\n\n  .align-self-xl-baseline {\n    align-self: baseline !important;\n  }\n\n  .align-self-xl-stretch {\n    align-self: stretch !important;\n  }\n\n  .order-xl-first {\n    order: -1 !important;\n  }\n\n  .order-xl-0 {\n    order: 0 !important;\n  }\n\n  .order-xl-1 {\n    order: 1 !important;\n  }\n\n  .order-xl-2 {\n    order: 2 !important;\n  }\n\n  .order-xl-3 {\n    order: 3 !important;\n  }\n\n  .order-xl-4 {\n    order: 4 !important;\n  }\n\n  .order-xl-5 {\n    order: 5 !important;\n  }\n\n  .order-xl-last {\n    order: 6 !important;\n  }\n\n  .m-xl-0 {\n    margin: 0 !important;\n  }\n\n  .m-xl-1 {\n    margin: 0.25rem !important;\n  }\n\n  .m-xl-2 {\n    margin: 0.5rem !important;\n  }\n\n  .m-xl-3 {\n    margin: 1rem !important;\n  }\n\n  .m-xl-4 {\n    margin: 1.5rem !important;\n  }\n\n  .m-xl-5 {\n    margin: 3rem !important;\n  }\n\n  .m-xl-auto {\n    margin: auto !important;\n  }\n\n  .mx-xl-0 {\n    margin-right: 0 !important;\n    margin-left: 0 !important;\n  }\n\n  .mx-xl-1 {\n    margin-right: 0.25rem !important;\n    margin-left: 0.25rem !important;\n  }\n\n  .mx-xl-2 {\n    margin-right: 0.5rem !important;\n    margin-left: 0.5rem !important;\n  }\n\n  .mx-xl-3 {\n    margin-right: 1rem !important;\n    margin-left: 1rem !important;\n  }\n\n  .mx-xl-4 {\n    margin-right: 1.5rem !important;\n    margin-left: 1.5rem !important;\n  }\n\n  .mx-xl-5 {\n    margin-right: 3rem !important;\n    margin-left: 3rem !important;\n  }\n\n  .mx-xl-auto {\n    margin-right: auto !important;\n    margin-left: auto !important;\n  }\n\n  .my-xl-0 {\n    margin-top: 0 !important;\n    margin-bottom: 0 !important;\n  }\n\n  .my-xl-1 {\n    margin-top: 0.25rem !important;\n    margin-bottom: 0.25rem !important;\n  }\n\n  .my-xl-2 {\n    margin-top: 0.5rem !important;\n    margin-bottom: 0.5rem !important;\n  }\n\n  .my-xl-3 {\n    margin-top: 1rem !important;\n    margin-bottom: 1rem !important;\n  }\n\n  .my-xl-4 {\n    margin-top: 1.5rem !important;\n    margin-bottom: 1.5rem !important;\n  }\n\n  .my-xl-5 {\n    margin-top: 3rem !important;\n    margin-bottom: 3rem !important;\n  }\n\n  .my-xl-auto {\n    margin-top: auto !important;\n    margin-bottom: auto !important;\n  }\n\n  .mt-xl-0 {\n    margin-top: 0 !important;\n  }\n\n  .mt-xl-1 {\n    margin-top: 0.25rem !important;\n  }\n\n  .mt-xl-2 {\n    margin-top: 0.5rem !important;\n  }\n\n  .mt-xl-3 {\n    margin-top: 1rem !important;\n  }\n\n  .mt-xl-4 {\n    margin-top: 1.5rem !important;\n  }\n\n  .mt-xl-5 {\n    margin-top: 3rem !important;\n  }\n\n  .mt-xl-auto {\n    margin-top: auto !important;\n  }\n\n  .me-xl-0 {\n    margin-right: 0 !important;\n  }\n\n  .me-xl-1 {\n    margin-right: 0.25rem !important;\n  }\n\n  .me-xl-2 {\n    margin-right: 0.5rem !important;\n  }\n\n  .me-xl-3 {\n    margin-right: 1rem !important;\n  }\n\n  .me-xl-4 {\n    margin-right: 1.5rem !important;\n  }\n\n  .me-xl-5 {\n    margin-right: 3rem !important;\n  }\n\n  .me-xl-auto {\n    margin-right: auto !important;\n  }\n\n  .mb-xl-0 {\n    margin-bottom: 0 !important;\n  }\n\n  .mb-xl-1 {\n    margin-bottom: 0.25rem !important;\n  }\n\n  .mb-xl-2 {\n    margin-bottom: 0.5rem !important;\n  }\n\n  .mb-xl-3 {\n    margin-bottom: 1rem !important;\n  }\n\n  .mb-xl-4 {\n    margin-bottom: 1.5rem !important;\n  }\n\n  .mb-xl-5 {\n    margin-bottom: 3rem !important;\n  }\n\n  .mb-xl-auto {\n    margin-bottom: auto !important;\n  }\n\n  .ms-xl-0 {\n    margin-left: 0 !important;\n  }\n\n  .ms-xl-1 {\n    margin-left: 0.25rem !important;\n  }\n\n  .ms-xl-2 {\n    margin-left: 0.5rem !important;\n  }\n\n  .ms-xl-3 {\n    margin-left: 1rem !important;\n  }\n\n  .ms-xl-4 {\n    margin-left: 1.5rem !important;\n  }\n\n  .ms-xl-5 {\n    margin-left: 3rem !important;\n  }\n\n  .ms-xl-auto {\n    margin-left: auto !important;\n  }\n\n  .p-xl-0 {\n    padding: 0 !important;\n  }\n\n  .p-xl-1 {\n    padding: 0.25rem !important;\n  }\n\n  .p-xl-2 {\n    padding: 0.5rem !important;\n  }\n\n  .p-xl-3 {\n    padding: 1rem !important;\n  }\n\n  .p-xl-4 {\n    padding: 1.5rem !important;\n  }\n\n  .p-xl-5 {\n    padding: 3rem !important;\n  }\n\n  .px-xl-0 {\n    padding-right: 0 !important;\n    padding-left: 0 !important;\n  }\n\n  .px-xl-1 {\n    padding-right: 0.25rem !important;\n    padding-left: 0.25rem !important;\n  }\n\n  .px-xl-2 {\n    padding-right: 0.5rem !important;\n    padding-left: 0.5rem !important;\n  }\n\n  .px-xl-3 {\n    padding-right: 1rem !important;\n    padding-left: 1rem !important;\n  }\n\n  .px-xl-4 {\n    padding-right: 1.5rem !important;\n    padding-left: 1.5rem !important;\n  }\n\n  .px-xl-5 {\n    padding-right: 3rem !important;\n    padding-left: 3rem !important;\n  }\n\n  .py-xl-0 {\n    padding-top: 0 !important;\n    padding-bottom: 0 !important;\n  }\n\n  .py-xl-1 {\n    padding-top: 0.25rem !important;\n    padding-bottom: 0.25rem !important;\n  }\n\n  .py-xl-2 {\n    padding-top: 0.5rem !important;\n    padding-bottom: 0.5rem !important;\n  }\n\n  .py-xl-3 {\n    padding-top: 1rem !important;\n    padding-bottom: 1rem !important;\n  }\n\n  .py-xl-4 {\n    padding-top: 1.5rem !important;\n    padding-bottom: 1.5rem !important;\n  }\n\n  .py-xl-5 {\n    padding-top: 3rem !important;\n    padding-bottom: 3rem !important;\n  }\n\n  .pt-xl-0 {\n    padding-top: 0 !important;\n  }\n\n  .pt-xl-1 {\n    padding-top: 0.25rem !important;\n  }\n\n  .pt-xl-2 {\n    padding-top: 0.5rem !important;\n  }\n\n  .pt-xl-3 {\n    padding-top: 1rem !important;\n  }\n\n  .pt-xl-4 {\n    padding-top: 1.5rem !important;\n  }\n\n  .pt-xl-5 {\n    padding-top: 3rem !important;\n  }\n\n  .pe-xl-0 {\n    padding-right: 0 !important;\n  }\n\n  .pe-xl-1 {\n    padding-right: 0.25rem !important;\n  }\n\n  .pe-xl-2 {\n    padding-right: 0.5rem !important;\n  }\n\n  .pe-xl-3 {\n    padding-right: 1rem !important;\n  }\n\n  .pe-xl-4 {\n    padding-right: 1.5rem !important;\n  }\n\n  .pe-xl-5 {\n    padding-right: 3rem !important;\n  }\n\n  .pb-xl-0 {\n    padding-bottom: 0 !important;\n  }\n\n  .pb-xl-1 {\n    padding-bottom: 0.25rem !important;\n  }\n\n  .pb-xl-2 {\n    padding-bottom: 0.5rem !important;\n  }\n\n  .pb-xl-3 {\n    padding-bottom: 1rem !important;\n  }\n\n  .pb-xl-4 {\n    padding-bottom: 1.5rem !important;\n  }\n\n  .pb-xl-5 {\n    padding-bottom: 3rem !important;\n  }\n\n  .ps-xl-0 {\n    padding-left: 0 !important;\n  }\n\n  .ps-xl-1 {\n    padding-left: 0.25rem !important;\n  }\n\n  .ps-xl-2 {\n    padding-left: 0.5rem !important;\n  }\n\n  .ps-xl-3 {\n    padding-left: 1rem !important;\n  }\n\n  .ps-xl-4 {\n    padding-left: 1.5rem !important;\n  }\n\n  .ps-xl-5 {\n    padding-left: 3rem !important;\n  }\n\n  .text-xl-start {\n    text-align: left !important;\n  }\n\n  .text-xl-end {\n    text-align: right !important;\n  }\n\n  .text-xl-center {\n    text-align: center !important;\n  }\n}\n@media (min-width: 1400px) {\n  .float-xxl-start {\n    float: left !important;\n  }\n\n  .float-xxl-end {\n    float: right !important;\n  }\n\n  .float-xxl-none {\n    float: none !important;\n  }\n\n  .d-xxl-inline {\n    display: inline !important;\n  }\n\n  .d-xxl-inline-block {\n    display: inline-block !important;\n  }\n\n  .d-xxl-block {\n    display: block !important;\n  }\n\n  .d-xxl-grid {\n    display: grid !important;\n  }\n\n  .d-xxl-table {\n    display: table !important;\n  }\n\n  .d-xxl-table-row {\n    display: table-row !important;\n  }\n\n  .d-xxl-table-cell {\n    display: table-cell !important;\n  }\n\n  .d-xxl-flex {\n    display: flex !important;\n  }\n\n  .d-xxl-inline-flex {\n    display: inline-flex !important;\n  }\n\n  .d-xxl-none {\n    display: none !important;\n  }\n\n  .flex-xxl-fill {\n    flex: 1 1 auto !important;\n  }\n\n  .flex-xxl-row {\n    flex-direction: row !important;\n  }\n\n  .flex-xxl-column {\n    flex-direction: column !important;\n  }\n\n  .flex-xxl-row-reverse {\n    flex-direction: row-reverse !important;\n  }\n\n  .flex-xxl-column-reverse {\n    flex-direction: column-reverse !important;\n  }\n\n  .flex-xxl-grow-0 {\n    flex-grow: 0 !important;\n  }\n\n  .flex-xxl-grow-1 {\n    flex-grow: 1 !important;\n  }\n\n  .flex-xxl-shrink-0 {\n    flex-shrink: 0 !important;\n  }\n\n  .flex-xxl-shrink-1 {\n    flex-shrink: 1 !important;\n  }\n\n  .flex-xxl-wrap {\n    flex-wrap: wrap !important;\n  }\n\n  .flex-xxl-nowrap {\n    flex-wrap: nowrap !important;\n  }\n\n  .flex-xxl-wrap-reverse {\n    flex-wrap: wrap-reverse !important;\n  }\n\n  .gap-xxl-0 {\n    gap: 0 !important;\n  }\n\n  .gap-xxl-1 {\n    gap: 0.25rem !important;\n  }\n\n  .gap-xxl-2 {\n    gap: 0.5rem !important;\n  }\n\n  .gap-xxl-3 {\n    gap: 1rem !important;\n  }\n\n  .gap-xxl-4 {\n    gap: 1.5rem !important;\n  }\n\n  .gap-xxl-5 {\n    gap: 3rem !important;\n  }\n\n  .justify-content-xxl-start {\n    justify-content: flex-start !important;\n  }\n\n  .justify-content-xxl-end {\n    justify-content: flex-end !important;\n  }\n\n  .justify-content-xxl-center {\n    justify-content: center !important;\n  }\n\n  .justify-content-xxl-between {\n    justify-content: space-between !important;\n  }\n\n  .justify-content-xxl-around {\n    justify-content: space-around !important;\n  }\n\n  .justify-content-xxl-evenly {\n    justify-content: space-evenly !important;\n  }\n\n  .align-items-xxl-start {\n    align-items: flex-start !important;\n  }\n\n  .align-items-xxl-end {\n    align-items: flex-end !important;\n  }\n\n  .align-items-xxl-center {\n    align-items: center !important;\n  }\n\n  .align-items-xxl-baseline {\n    align-items: baseline !important;\n  }\n\n  .align-items-xxl-stretch {\n    align-items: stretch !important;\n  }\n\n  .align-content-xxl-start {\n    align-content: flex-start !important;\n  }\n\n  .align-content-xxl-end {\n    align-content: flex-end !important;\n  }\n\n  .align-content-xxl-center {\n    align-content: center !important;\n  }\n\n  .align-content-xxl-between {\n    align-content: space-between !important;\n  }\n\n  .align-content-xxl-around {\n    align-content: space-around !important;\n  }\n\n  .align-content-xxl-stretch {\n    align-content: stretch !important;\n  }\n\n  .align-self-xxl-auto {\n    align-self: auto !important;\n  }\n\n  .align-self-xxl-start {\n    align-self: flex-start !important;\n  }\n\n  .align-self-xxl-end {\n    align-self: flex-end !important;\n  }\n\n  .align-self-xxl-center {\n    align-self: center !important;\n  }\n\n  .align-self-xxl-baseline {\n    align-self: baseline !important;\n  }\n\n  .align-self-xxl-stretch {\n    align-self: stretch !important;\n  }\n\n  .order-xxl-first {\n    order: -1 !important;\n  }\n\n  .order-xxl-0 {\n    order: 0 !important;\n  }\n\n  .order-xxl-1 {\n    order: 1 !important;\n  }\n\n  .order-xxl-2 {\n    order: 2 !important;\n  }\n\n  .order-xxl-3 {\n    order: 3 !important;\n  }\n\n  .order-xxl-4 {\n    order: 4 !important;\n  }\n\n  .order-xxl-5 {\n    order: 5 !important;\n  }\n\n  .order-xxl-last {\n    order: 6 !important;\n  }\n\n  .m-xxl-0 {\n    margin: 0 !important;\n  }\n\n  .m-xxl-1 {\n    margin: 0.25rem !important;\n  }\n\n  .m-xxl-2 {\n    margin: 0.5rem !important;\n  }\n\n  .m-xxl-3 {\n    margin: 1rem !important;\n  }\n\n  .m-xxl-4 {\n    margin: 1.5rem !important;\n  }\n\n  .m-xxl-5 {\n    margin: 3rem !important;\n  }\n\n  .m-xxl-auto {\n    margin: auto !important;\n  }\n\n  .mx-xxl-0 {\n    margin-right: 0 !important;\n    margin-left: 0 !important;\n  }\n\n  .mx-xxl-1 {\n    margin-right: 0.25rem !important;\n    margin-left: 0.25rem !important;\n  }\n\n  .mx-xxl-2 {\n    margin-right: 0.5rem !important;\n    margin-left: 0.5rem !important;\n  }\n\n  .mx-xxl-3 {\n    margin-right: 1rem !important;\n    margin-left: 1rem !important;\n  }\n\n  .mx-xxl-4 {\n    margin-right: 1.5rem !important;\n    margin-left: 1.5rem !important;\n  }\n\n  .mx-xxl-5 {\n    margin-right: 3rem !important;\n    margin-left: 3rem !important;\n  }\n\n  .mx-xxl-auto {\n    margin-right: auto !important;\n    margin-left: auto !important;\n  }\n\n  .my-xxl-0 {\n    margin-top: 0 !important;\n    margin-bottom: 0 !important;\n  }\n\n  .my-xxl-1 {\n    margin-top: 0.25rem !important;\n    margin-bottom: 0.25rem !important;\n  }\n\n  .my-xxl-2 {\n    margin-top: 0.5rem !important;\n    margin-bottom: 0.5rem !important;\n  }\n\n  .my-xxl-3 {\n    margin-top: 1rem !important;\n    margin-bottom: 1rem !important;\n  }\n\n  .my-xxl-4 {\n    margin-top: 1.5rem !important;\n    margin-bottom: 1.5rem !important;\n  }\n\n  .my-xxl-5 {\n    margin-top: 3rem !important;\n    margin-bottom: 3rem !important;\n  }\n\n  .my-xxl-auto {\n    margin-top: auto !important;\n    margin-bottom: auto !important;\n  }\n\n  .mt-xxl-0 {\n    margin-top: 0 !important;\n  }\n\n  .mt-xxl-1 {\n    margin-top: 0.25rem !important;\n  }\n\n  .mt-xxl-2 {\n    margin-top: 0.5rem !important;\n  }\n\n  .mt-xxl-3 {\n    margin-top: 1rem !important;\n  }\n\n  .mt-xxl-4 {\n    margin-top: 1.5rem !important;\n  }\n\n  .mt-xxl-5 {\n    margin-top: 3rem !important;\n  }\n\n  .mt-xxl-auto {\n    margin-top: auto !important;\n  }\n\n  .me-xxl-0 {\n    margin-right: 0 !important;\n  }\n\n  .me-xxl-1 {\n    margin-right: 0.25rem !important;\n  }\n\n  .me-xxl-2 {\n    margin-right: 0.5rem !important;\n  }\n\n  .me-xxl-3 {\n    margin-right: 1rem !important;\n  }\n\n  .me-xxl-4 {\n    margin-right: 1.5rem !important;\n  }\n\n  .me-xxl-5 {\n    margin-right: 3rem !important;\n  }\n\n  .me-xxl-auto {\n    margin-right: auto !important;\n  }\n\n  .mb-xxl-0 {\n    margin-bottom: 0 !important;\n  }\n\n  .mb-xxl-1 {\n    margin-bottom: 0.25rem !important;\n  }\n\n  .mb-xxl-2 {\n    margin-bottom: 0.5rem !important;\n  }\n\n  .mb-xxl-3 {\n    margin-bottom: 1rem !important;\n  }\n\n  .mb-xxl-4 {\n    margin-bottom: 1.5rem !important;\n  }\n\n  .mb-xxl-5 {\n    margin-bottom: 3rem !important;\n  }\n\n  .mb-xxl-auto {\n    margin-bottom: auto !important;\n  }\n\n  .ms-xxl-0 {\n    margin-left: 0 !important;\n  }\n\n  .ms-xxl-1 {\n    margin-left: 0.25rem !important;\n  }\n\n  .ms-xxl-2 {\n    margin-left: 0.5rem !important;\n  }\n\n  .ms-xxl-3 {\n    margin-left: 1rem !important;\n  }\n\n  .ms-xxl-4 {\n    margin-left: 1.5rem !important;\n  }\n\n  .ms-xxl-5 {\n    margin-left: 3rem !important;\n  }\n\n  .ms-xxl-auto {\n    margin-left: auto !important;\n  }\n\n  .p-xxl-0 {\n    padding: 0 !important;\n  }\n\n  .p-xxl-1 {\n    padding: 0.25rem !important;\n  }\n\n  .p-xxl-2 {\n    padding: 0.5rem !important;\n  }\n\n  .p-xxl-3 {\n    padding: 1rem !important;\n  }\n\n  .p-xxl-4 {\n    padding: 1.5rem !important;\n  }\n\n  .p-xxl-5 {\n    padding: 3rem !important;\n  }\n\n  .px-xxl-0 {\n    padding-right: 0 !important;\n    padding-left: 0 !important;\n  }\n\n  .px-xxl-1 {\n    padding-right: 0.25rem !important;\n    padding-left: 0.25rem !important;\n  }\n\n  .px-xxl-2 {\n    padding-right: 0.5rem !important;\n    padding-left: 0.5rem !important;\n  }\n\n  .px-xxl-3 {\n    padding-right: 1rem !important;\n    padding-left: 1rem !important;\n  }\n\n  .px-xxl-4 {\n    padding-right: 1.5rem !important;\n    padding-left: 1.5rem !important;\n  }\n\n  .px-xxl-5 {\n    padding-right: 3rem !important;\n    padding-left: 3rem !important;\n  }\n\n  .py-xxl-0 {\n    padding-top: 0 !important;\n    padding-bottom: 0 !important;\n  }\n\n  .py-xxl-1 {\n    padding-top: 0.25rem !important;\n    padding-bottom: 0.25rem !important;\n  }\n\n  .py-xxl-2 {\n    padding-top: 0.5rem !important;\n    padding-bottom: 0.5rem !important;\n  }\n\n  .py-xxl-3 {\n    padding-top: 1rem !important;\n    padding-bottom: 1rem !important;\n  }\n\n  .py-xxl-4 {\n    padding-top: 1.5rem !important;\n    padding-bottom: 1.5rem !important;\n  }\n\n  .py-xxl-5 {\n    padding-top: 3rem !important;\n    padding-bottom: 3rem !important;\n  }\n\n  .pt-xxl-0 {\n    padding-top: 0 !important;\n  }\n\n  .pt-xxl-1 {\n    padding-top: 0.25rem !important;\n  }\n\n  .pt-xxl-2 {\n    padding-top: 0.5rem !important;\n  }\n\n  .pt-xxl-3 {\n    padding-top: 1rem !important;\n  }\n\n  .pt-xxl-4 {\n    padding-top: 1.5rem !important;\n  }\n\n  .pt-xxl-5 {\n    padding-top: 3rem !important;\n  }\n\n  .pe-xxl-0 {\n    padding-right: 0 !important;\n  }\n\n  .pe-xxl-1 {\n    padding-right: 0.25rem !important;\n  }\n\n  .pe-xxl-2 {\n    padding-right: 0.5rem !important;\n  }\n\n  .pe-xxl-3 {\n    padding-right: 1rem !important;\n  }\n\n  .pe-xxl-4 {\n    padding-right: 1.5rem !important;\n  }\n\n  .pe-xxl-5 {\n    padding-right: 3rem !important;\n  }\n\n  .pb-xxl-0 {\n    padding-bottom: 0 !important;\n  }\n\n  .pb-xxl-1 {\n    padding-bottom: 0.25rem !important;\n  }\n\n  .pb-xxl-2 {\n    padding-bottom: 0.5rem !important;\n  }\n\n  .pb-xxl-3 {\n    padding-bottom: 1rem !important;\n  }\n\n  .pb-xxl-4 {\n    padding-bottom: 1.5rem !important;\n  }\n\n  .pb-xxl-5 {\n    padding-bottom: 3rem !important;\n  }\n\n  .ps-xxl-0 {\n    padding-left: 0 !important;\n  }\n\n  .ps-xxl-1 {\n    padding-left: 0.25rem !important;\n  }\n\n  .ps-xxl-2 {\n    padding-left: 0.5rem !important;\n  }\n\n  .ps-xxl-3 {\n    padding-left: 1rem !important;\n  }\n\n  .ps-xxl-4 {\n    padding-left: 1.5rem !important;\n  }\n\n  .ps-xxl-5 {\n    padding-left: 3rem !important;\n  }\n\n  .text-xxl-start {\n    text-align: left !important;\n  }\n\n  .text-xxl-end {\n    text-align: right !important;\n  }\n\n  .text-xxl-center {\n    text-align: center !important;\n  }\n}\n@media (min-width: 1200px) {\n  .fs-1 {\n    font-size: 2.5rem !important;\n  }\n\n  .fs-2 {\n    font-size: 2rem !important;\n  }\n\n  .fs-3 {\n    font-size: 1.75rem !important;\n  }\n\n  .fs-4 {\n    font-size: 1.5rem !important;\n  }\n}\n@media print {\n  .d-print-inline {\n    display: inline !important;\n  }\n\n  .d-print-inline-block {\n    display: inline-block !important;\n  }\n\n  .d-print-block {\n    display: block !important;\n  }\n\n  .d-print-grid {\n    display: grid !important;\n  }\n\n  .d-print-table {\n    display: table !important;\n  }\n\n  .d-print-table-row {\n    display: table-row !important;\n  }\n\n  .d-print-table-cell {\n    display: table-cell !important;\n  }\n\n  .d-print-flex {\n    display: flex !important;\n  }\n\n  .d-print-inline-flex {\n    display: inline-flex !important;\n  }\n\n  .d-print-none {\n    display: none !important;\n  }\n}\n\n/*# sourceMappingURL=bootstrap.css.map */"
  },
  {
    "path": "sample/src/NimblePros.SampleToDo.Web/wwwroot/lib/bootstrap/dist/css/bootstrap.rtl.css",
    "content": "@charset \"UTF-8\";\n/*!\n * Bootstrap v5.1.0 (https://getbootstrap.com/)\n * Copyright 2011-2021 The Bootstrap Authors\n * Copyright 2011-2021 Twitter, Inc.\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n */\n:root {\n  --bs-blue: #0d6efd;\n  --bs-indigo: #6610f2;\n  --bs-purple: #6f42c1;\n  --bs-pink: #d63384;\n  --bs-red: #dc3545;\n  --bs-orange: #fd7e14;\n  --bs-yellow: #ffc107;\n  --bs-green: #198754;\n  --bs-teal: #20c997;\n  --bs-cyan: #0dcaf0;\n  --bs-white: #fff;\n  --bs-gray: #6c757d;\n  --bs-gray-dark: #343a40;\n  --bs-gray-100: #f8f9fa;\n  --bs-gray-200: #e9ecef;\n  --bs-gray-300: #dee2e6;\n  --bs-gray-400: #ced4da;\n  --bs-gray-500: #adb5bd;\n  --bs-gray-600: #6c757d;\n  --bs-gray-700: #495057;\n  --bs-gray-800: #343a40;\n  --bs-gray-900: #212529;\n  --bs-primary: #0d6efd;\n  --bs-secondary: #6c757d;\n  --bs-success: #198754;\n  --bs-info: #0dcaf0;\n  --bs-warning: #ffc107;\n  --bs-danger: #dc3545;\n  --bs-light: #f8f9fa;\n  --bs-dark: #212529;\n  --bs-primary-rgb: 13, 110, 253;\n  --bs-secondary-rgb: 108, 117, 125;\n  --bs-success-rgb: 25, 135, 84;\n  --bs-info-rgb: 13, 202, 240;\n  --bs-warning-rgb: 255, 193, 7;\n  --bs-danger-rgb: 220, 53, 69;\n  --bs-light-rgb: 248, 249, 250;\n  --bs-dark-rgb: 33, 37, 41;\n  --bs-white-rgb: 255, 255, 255;\n  --bs-black-rgb: 0, 0, 0;\n  --bs-body-rgb: 33, 37, 41;\n  --bs-font-sans-serif: system-ui, -apple-system, \"Segoe UI\", Roboto, \"Helvetica Neue\", Arial, \"Noto Sans\", \"Liberation Sans\", sans-serif, \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\", \"Noto Color Emoji\";\n  --bs-font-monospace: SFMono-Regular, Menlo, Monaco, Consolas, \"Liberation Mono\", \"Courier New\", monospace;\n  --bs-gradient: linear-gradient(180deg, rgba(255, 255, 255, 0.15), rgba(255, 255, 255, 0));\n  --bs-body-font-family: var(--bs-font-sans-serif);\n  --bs-body-font-size: 1rem;\n  --bs-body-font-weight: 400;\n  --bs-body-line-height: 1.5;\n  --bs-body-color: #212529;\n  --bs-body-bg: #fff;\n}\n\n*,\n*::before,\n*::after {\n  box-sizing: border-box;\n}\n\n@media (prefers-reduced-motion: no-preference) {\n  :root {\n    scroll-behavior: smooth;\n  }\n}\n\nbody {\n  margin: 0;\n  font-family: var(--bs-body-font-family);\n  font-size: var(--bs-body-font-size);\n  font-weight: var(--bs-body-font-weight);\n  line-height: var(--bs-body-line-height);\n  color: var(--bs-body-color);\n  text-align: var(--bs-body-text-align);\n  background-color: var(--bs-body-bg);\n  -webkit-text-size-adjust: 100%;\n  -webkit-tap-highlight-color: rgba(0, 0, 0, 0);\n}\n\nhr {\n  margin: 1rem 0;\n  color: inherit;\n  background-color: currentColor;\n  border: 0;\n  opacity: 0.25;\n}\n\nhr:not([size]) {\n  height: 1px;\n}\n\nh6, .h6, h5, .h5, h4, .h4, h3, .h3, h2, .h2, h1, .h1 {\n  margin-top: 0;\n  margin-bottom: 0.5rem;\n  font-weight: 500;\n  line-height: 1.2;\n}\n\nh1, .h1 {\n  font-size: calc(1.375rem + 1.5vw);\n}\n@media (min-width: 1200px) {\n  h1, .h1 {\n    font-size: 2.5rem;\n  }\n}\n\nh2, .h2 {\n  font-size: calc(1.325rem + 0.9vw);\n}\n@media (min-width: 1200px) {\n  h2, .h2 {\n    font-size: 2rem;\n  }\n}\n\nh3, .h3 {\n  font-size: calc(1.3rem + 0.6vw);\n}\n@media (min-width: 1200px) {\n  h3, .h3 {\n    font-size: 1.75rem;\n  }\n}\n\nh4, .h4 {\n  font-size: calc(1.275rem + 0.3vw);\n}\n@media (min-width: 1200px) {\n  h4, .h4 {\n    font-size: 1.5rem;\n  }\n}\n\nh5, .h5 {\n  font-size: 1.25rem;\n}\n\nh6, .h6 {\n  font-size: 1rem;\n}\n\np {\n  margin-top: 0;\n  margin-bottom: 1rem;\n}\n\nabbr[title],\nabbr[data-bs-original-title] {\n  -webkit-text-decoration: underline dotted;\n  text-decoration: underline dotted;\n  cursor: help;\n  -webkit-text-decoration-skip-ink: none;\n  text-decoration-skip-ink: none;\n}\n\naddress {\n  margin-bottom: 1rem;\n  font-style: normal;\n  line-height: inherit;\n}\n\nol,\nul {\n  padding-right: 2rem;\n}\n\nol,\nul,\ndl {\n  margin-top: 0;\n  margin-bottom: 1rem;\n}\n\nol ol,\nul ul,\nol ul,\nul ol {\n  margin-bottom: 0;\n}\n\ndt {\n  font-weight: 700;\n}\n\ndd {\n  margin-bottom: 0.5rem;\n  margin-right: 0;\n}\n\nblockquote {\n  margin: 0 0 1rem;\n}\n\nb,\nstrong {\n  font-weight: bolder;\n}\n\nsmall, .small {\n  font-size: 0.875em;\n}\n\nmark, .mark {\n  padding: 0.2em;\n  background-color: #fcf8e3;\n}\n\nsub,\nsup {\n  position: relative;\n  font-size: 0.75em;\n  line-height: 0;\n  vertical-align: baseline;\n}\n\nsub {\n  bottom: -0.25em;\n}\n\nsup {\n  top: -0.5em;\n}\n\na {\n  color: #0d6efd;\n  text-decoration: underline;\n}\na:hover {\n  color: #0a58ca;\n}\n\na:not([href]):not([class]), a:not([href]):not([class]):hover {\n  color: inherit;\n  text-decoration: none;\n}\n\npre,\ncode,\nkbd,\nsamp {\n  font-family: var(--bs-font-monospace);\n  font-size: 1em;\n  direction: ltr ;\n  unicode-bidi: bidi-override;\n}\n\npre {\n  display: block;\n  margin-top: 0;\n  margin-bottom: 1rem;\n  overflow: auto;\n  font-size: 0.875em;\n}\npre code {\n  font-size: inherit;\n  color: inherit;\n  word-break: normal;\n}\n\ncode {\n  font-size: 0.875em;\n  color: #d63384;\n  word-wrap: break-word;\n}\na > code {\n  color: inherit;\n}\n\nkbd {\n  padding: 0.2rem 0.4rem;\n  font-size: 0.875em;\n  color: #fff;\n  background-color: #212529;\n  border-radius: 0.2rem;\n}\nkbd kbd {\n  padding: 0;\n  font-size: 1em;\n  font-weight: 700;\n}\n\nfigure {\n  margin: 0 0 1rem;\n}\n\nimg,\nsvg {\n  vertical-align: middle;\n}\n\ntable {\n  caption-side: bottom;\n  border-collapse: collapse;\n}\n\ncaption {\n  padding-top: 0.5rem;\n  padding-bottom: 0.5rem;\n  color: #6c757d;\n  text-align: right;\n}\n\nth {\n  text-align: inherit;\n  text-align: -webkit-match-parent;\n}\n\nthead,\ntbody,\ntfoot,\ntr,\ntd,\nth {\n  border-color: inherit;\n  border-style: solid;\n  border-width: 0;\n}\n\nlabel {\n  display: inline-block;\n}\n\nbutton {\n  border-radius: 0;\n}\n\nbutton:focus:not(:focus-visible) {\n  outline: 0;\n}\n\ninput,\nbutton,\nselect,\noptgroup,\ntextarea {\n  margin: 0;\n  font-family: inherit;\n  font-size: inherit;\n  line-height: inherit;\n}\n\nbutton,\nselect {\n  text-transform: none;\n}\n\n[role=button] {\n  cursor: pointer;\n}\n\nselect {\n  word-wrap: normal;\n}\nselect:disabled {\n  opacity: 1;\n}\n\n[list]::-webkit-calendar-picker-indicator {\n  display: none;\n}\n\nbutton,\n[type=button],\n[type=reset],\n[type=submit] {\n  -webkit-appearance: button;\n}\nbutton:not(:disabled),\n[type=button]:not(:disabled),\n[type=reset]:not(:disabled),\n[type=submit]:not(:disabled) {\n  cursor: pointer;\n}\n\n::-moz-focus-inner {\n  padding: 0;\n  border-style: none;\n}\n\ntextarea {\n  resize: vertical;\n}\n\nfieldset {\n  min-width: 0;\n  padding: 0;\n  margin: 0;\n  border: 0;\n}\n\nlegend {\n  float: right;\n  width: 100%;\n  padding: 0;\n  margin-bottom: 0.5rem;\n  font-size: calc(1.275rem + 0.3vw);\n  line-height: inherit;\n}\n@media (min-width: 1200px) {\n  legend {\n    font-size: 1.5rem;\n  }\n}\nlegend + * {\n  clear: right;\n}\n\n::-webkit-datetime-edit-fields-wrapper,\n::-webkit-datetime-edit-text,\n::-webkit-datetime-edit-minute,\n::-webkit-datetime-edit-hour-field,\n::-webkit-datetime-edit-day-field,\n::-webkit-datetime-edit-month-field,\n::-webkit-datetime-edit-year-field {\n  padding: 0;\n}\n\n::-webkit-inner-spin-button {\n  height: auto;\n}\n\n[type=search] {\n  outline-offset: -2px;\n  -webkit-appearance: textfield;\n}\n\n[type=\"tel\"],\n[type=\"url\"],\n[type=\"email\"],\n[type=\"number\"] {\n  direction: ltr;\n}\n::-webkit-search-decoration {\n  -webkit-appearance: none;\n}\n\n::-webkit-color-swatch-wrapper {\n  padding: 0;\n}\n\n::file-selector-button {\n  font: inherit;\n}\n\n::-webkit-file-upload-button {\n  font: inherit;\n  -webkit-appearance: button;\n}\n\noutput {\n  display: inline-block;\n}\n\niframe {\n  border: 0;\n}\n\nsummary {\n  display: list-item;\n  cursor: pointer;\n}\n\nprogress {\n  vertical-align: baseline;\n}\n\n[hidden] {\n  display: none !important;\n}\n\n.lead {\n  font-size: 1.25rem;\n  font-weight: 300;\n}\n\n.display-1 {\n  font-size: calc(1.625rem + 4.5vw);\n  font-weight: 300;\n  line-height: 1.2;\n}\n@media (min-width: 1200px) {\n  .display-1 {\n    font-size: 5rem;\n  }\n}\n\n.display-2 {\n  font-size: calc(1.575rem + 3.9vw);\n  font-weight: 300;\n  line-height: 1.2;\n}\n@media (min-width: 1200px) {\n  .display-2 {\n    font-size: 4.5rem;\n  }\n}\n\n.display-3 {\n  font-size: calc(1.525rem + 3.3vw);\n  font-weight: 300;\n  line-height: 1.2;\n}\n@media (min-width: 1200px) {\n  .display-3 {\n    font-size: 4rem;\n  }\n}\n\n.display-4 {\n  font-size: calc(1.475rem + 2.7vw);\n  font-weight: 300;\n  line-height: 1.2;\n}\n@media (min-width: 1200px) {\n  .display-4 {\n    font-size: 3.5rem;\n  }\n}\n\n.display-5 {\n  font-size: calc(1.425rem + 2.1vw);\n  font-weight: 300;\n  line-height: 1.2;\n}\n@media (min-width: 1200px) {\n  .display-5 {\n    font-size: 3rem;\n  }\n}\n\n.display-6 {\n  font-size: calc(1.375rem + 1.5vw);\n  font-weight: 300;\n  line-height: 1.2;\n}\n@media (min-width: 1200px) {\n  .display-6 {\n    font-size: 2.5rem;\n  }\n}\n\n.list-unstyled {\n  padding-right: 0;\n  list-style: none;\n}\n\n.list-inline {\n  padding-right: 0;\n  list-style: none;\n}\n\n.list-inline-item {\n  display: inline-block;\n}\n.list-inline-item:not(:last-child) {\n  margin-left: 0.5rem;\n}\n\n.initialism {\n  font-size: 0.875em;\n  text-transform: uppercase;\n}\n\n.blockquote {\n  margin-bottom: 1rem;\n  font-size: 1.25rem;\n}\n.blockquote > :last-child {\n  margin-bottom: 0;\n}\n\n.blockquote-footer {\n  margin-top: -1rem;\n  margin-bottom: 1rem;\n  font-size: 0.875em;\n  color: #6c757d;\n}\n.blockquote-footer::before {\n  content: \"— \";\n}\n\n.img-fluid {\n  max-width: 100%;\n  height: auto;\n}\n\n.img-thumbnail {\n  padding: 0.25rem;\n  background-color: #fff;\n  border: 1px solid #dee2e6;\n  border-radius: 0.25rem;\n  max-width: 100%;\n  height: auto;\n}\n\n.figure {\n  display: inline-block;\n}\n\n.figure-img {\n  margin-bottom: 0.5rem;\n  line-height: 1;\n}\n\n.figure-caption {\n  font-size: 0.875em;\n  color: #6c757d;\n}\n\n.container,\n.container-fluid,\n.container-xxl,\n.container-xl,\n.container-lg,\n.container-md,\n.container-sm {\n  width: 100%;\n  padding-left: var(--bs-gutter-x, 0.75rem);\n  padding-right: var(--bs-gutter-x, 0.75rem);\n  margin-left: auto;\n  margin-right: auto;\n}\n\n@media (min-width: 576px) {\n  .container-sm, .container {\n    max-width: 540px;\n  }\n}\n@media (min-width: 768px) {\n  .container-md, .container-sm, .container {\n    max-width: 720px;\n  }\n}\n@media (min-width: 992px) {\n  .container-lg, .container-md, .container-sm, .container {\n    max-width: 960px;\n  }\n}\n@media (min-width: 1200px) {\n  .container-xl, .container-lg, .container-md, .container-sm, .container {\n    max-width: 1140px;\n  }\n}\n@media (min-width: 1400px) {\n  .container-xxl, .container-xl, .container-lg, .container-md, .container-sm, .container {\n    max-width: 1320px;\n  }\n}\n.row {\n  --bs-gutter-x: 1.5rem;\n  --bs-gutter-y: 0;\n  display: flex;\n  flex-wrap: wrap;\n  margin-top: calc(var(--bs-gutter-y) * -1);\n  margin-left: calc(var(--bs-gutter-x) * -.5);\n  margin-right: calc(var(--bs-gutter-x) * -.5);\n}\n.row > * {\n  flex-shrink: 0;\n  width: 100%;\n  max-width: 100%;\n  padding-left: calc(var(--bs-gutter-x) * .5);\n  padding-right: calc(var(--bs-gutter-x) * .5);\n  margin-top: var(--bs-gutter-y);\n}\n\n.col {\n  flex: 1 0 0%;\n}\n\n.row-cols-auto > * {\n  flex: 0 0 auto;\n  width: auto;\n}\n\n.row-cols-1 > * {\n  flex: 0 0 auto;\n  width: 100%;\n}\n\n.row-cols-2 > * {\n  flex: 0 0 auto;\n  width: 50%;\n}\n\n.row-cols-3 > * {\n  flex: 0 0 auto;\n  width: 33.3333333333%;\n}\n\n.row-cols-4 > * {\n  flex: 0 0 auto;\n  width: 25%;\n}\n\n.row-cols-5 > * {\n  flex: 0 0 auto;\n  width: 20%;\n}\n\n.row-cols-6 > * {\n  flex: 0 0 auto;\n  width: 16.6666666667%;\n}\n\n.col-auto {\n  flex: 0 0 auto;\n  width: auto;\n}\n\n.col-1 {\n  flex: 0 0 auto;\n  width: 8.33333333%;\n}\n\n.col-2 {\n  flex: 0 0 auto;\n  width: 16.66666667%;\n}\n\n.col-3 {\n  flex: 0 0 auto;\n  width: 25%;\n}\n\n.col-4 {\n  flex: 0 0 auto;\n  width: 33.33333333%;\n}\n\n.col-5 {\n  flex: 0 0 auto;\n  width: 41.66666667%;\n}\n\n.col-6 {\n  flex: 0 0 auto;\n  width: 50%;\n}\n\n.col-7 {\n  flex: 0 0 auto;\n  width: 58.33333333%;\n}\n\n.col-8 {\n  flex: 0 0 auto;\n  width: 66.66666667%;\n}\n\n.col-9 {\n  flex: 0 0 auto;\n  width: 75%;\n}\n\n.col-10 {\n  flex: 0 0 auto;\n  width: 83.33333333%;\n}\n\n.col-11 {\n  flex: 0 0 auto;\n  width: 91.66666667%;\n}\n\n.col-12 {\n  flex: 0 0 auto;\n  width: 100%;\n}\n\n.offset-1 {\n  margin-right: 8.33333333%;\n}\n\n.offset-2 {\n  margin-right: 16.66666667%;\n}\n\n.offset-3 {\n  margin-right: 25%;\n}\n\n.offset-4 {\n  margin-right: 33.33333333%;\n}\n\n.offset-5 {\n  margin-right: 41.66666667%;\n}\n\n.offset-6 {\n  margin-right: 50%;\n}\n\n.offset-7 {\n  margin-right: 58.33333333%;\n}\n\n.offset-8 {\n  margin-right: 66.66666667%;\n}\n\n.offset-9 {\n  margin-right: 75%;\n}\n\n.offset-10 {\n  margin-right: 83.33333333%;\n}\n\n.offset-11 {\n  margin-right: 91.66666667%;\n}\n\n.g-0,\n.gx-0 {\n  --bs-gutter-x: 0;\n}\n\n.g-0,\n.gy-0 {\n  --bs-gutter-y: 0;\n}\n\n.g-1,\n.gx-1 {\n  --bs-gutter-x: 0.25rem;\n}\n\n.g-1,\n.gy-1 {\n  --bs-gutter-y: 0.25rem;\n}\n\n.g-2,\n.gx-2 {\n  --bs-gutter-x: 0.5rem;\n}\n\n.g-2,\n.gy-2 {\n  --bs-gutter-y: 0.5rem;\n}\n\n.g-3,\n.gx-3 {\n  --bs-gutter-x: 1rem;\n}\n\n.g-3,\n.gy-3 {\n  --bs-gutter-y: 1rem;\n}\n\n.g-4,\n.gx-4 {\n  --bs-gutter-x: 1.5rem;\n}\n\n.g-4,\n.gy-4 {\n  --bs-gutter-y: 1.5rem;\n}\n\n.g-5,\n.gx-5 {\n  --bs-gutter-x: 3rem;\n}\n\n.g-5,\n.gy-5 {\n  --bs-gutter-y: 3rem;\n}\n\n@media (min-width: 576px) {\n  .col-sm {\n    flex: 1 0 0%;\n  }\n\n  .row-cols-sm-auto > * {\n    flex: 0 0 auto;\n    width: auto;\n  }\n\n  .row-cols-sm-1 > * {\n    flex: 0 0 auto;\n    width: 100%;\n  }\n\n  .row-cols-sm-2 > * {\n    flex: 0 0 auto;\n    width: 50%;\n  }\n\n  .row-cols-sm-3 > * {\n    flex: 0 0 auto;\n    width: 33.3333333333%;\n  }\n\n  .row-cols-sm-4 > * {\n    flex: 0 0 auto;\n    width: 25%;\n  }\n\n  .row-cols-sm-5 > * {\n    flex: 0 0 auto;\n    width: 20%;\n  }\n\n  .row-cols-sm-6 > * {\n    flex: 0 0 auto;\n    width: 16.6666666667%;\n  }\n\n  .col-sm-auto {\n    flex: 0 0 auto;\n    width: auto;\n  }\n\n  .col-sm-1 {\n    flex: 0 0 auto;\n    width: 8.33333333%;\n  }\n\n  .col-sm-2 {\n    flex: 0 0 auto;\n    width: 16.66666667%;\n  }\n\n  .col-sm-3 {\n    flex: 0 0 auto;\n    width: 25%;\n  }\n\n  .col-sm-4 {\n    flex: 0 0 auto;\n    width: 33.33333333%;\n  }\n\n  .col-sm-5 {\n    flex: 0 0 auto;\n    width: 41.66666667%;\n  }\n\n  .col-sm-6 {\n    flex: 0 0 auto;\n    width: 50%;\n  }\n\n  .col-sm-7 {\n    flex: 0 0 auto;\n    width: 58.33333333%;\n  }\n\n  .col-sm-8 {\n    flex: 0 0 auto;\n    width: 66.66666667%;\n  }\n\n  .col-sm-9 {\n    flex: 0 0 auto;\n    width: 75%;\n  }\n\n  .col-sm-10 {\n    flex: 0 0 auto;\n    width: 83.33333333%;\n  }\n\n  .col-sm-11 {\n    flex: 0 0 auto;\n    width: 91.66666667%;\n  }\n\n  .col-sm-12 {\n    flex: 0 0 auto;\n    width: 100%;\n  }\n\n  .offset-sm-0 {\n    margin-right: 0;\n  }\n\n  .offset-sm-1 {\n    margin-right: 8.33333333%;\n  }\n\n  .offset-sm-2 {\n    margin-right: 16.66666667%;\n  }\n\n  .offset-sm-3 {\n    margin-right: 25%;\n  }\n\n  .offset-sm-4 {\n    margin-right: 33.33333333%;\n  }\n\n  .offset-sm-5 {\n    margin-right: 41.66666667%;\n  }\n\n  .offset-sm-6 {\n    margin-right: 50%;\n  }\n\n  .offset-sm-7 {\n    margin-right: 58.33333333%;\n  }\n\n  .offset-sm-8 {\n    margin-right: 66.66666667%;\n  }\n\n  .offset-sm-9 {\n    margin-right: 75%;\n  }\n\n  .offset-sm-10 {\n    margin-right: 83.33333333%;\n  }\n\n  .offset-sm-11 {\n    margin-right: 91.66666667%;\n  }\n\n  .g-sm-0,\n.gx-sm-0 {\n    --bs-gutter-x: 0;\n  }\n\n  .g-sm-0,\n.gy-sm-0 {\n    --bs-gutter-y: 0;\n  }\n\n  .g-sm-1,\n.gx-sm-1 {\n    --bs-gutter-x: 0.25rem;\n  }\n\n  .g-sm-1,\n.gy-sm-1 {\n    --bs-gutter-y: 0.25rem;\n  }\n\n  .g-sm-2,\n.gx-sm-2 {\n    --bs-gutter-x: 0.5rem;\n  }\n\n  .g-sm-2,\n.gy-sm-2 {\n    --bs-gutter-y: 0.5rem;\n  }\n\n  .g-sm-3,\n.gx-sm-3 {\n    --bs-gutter-x: 1rem;\n  }\n\n  .g-sm-3,\n.gy-sm-3 {\n    --bs-gutter-y: 1rem;\n  }\n\n  .g-sm-4,\n.gx-sm-4 {\n    --bs-gutter-x: 1.5rem;\n  }\n\n  .g-sm-4,\n.gy-sm-4 {\n    --bs-gutter-y: 1.5rem;\n  }\n\n  .g-sm-5,\n.gx-sm-5 {\n    --bs-gutter-x: 3rem;\n  }\n\n  .g-sm-5,\n.gy-sm-5 {\n    --bs-gutter-y: 3rem;\n  }\n}\n@media (min-width: 768px) {\n  .col-md {\n    flex: 1 0 0%;\n  }\n\n  .row-cols-md-auto > * {\n    flex: 0 0 auto;\n    width: auto;\n  }\n\n  .row-cols-md-1 > * {\n    flex: 0 0 auto;\n    width: 100%;\n  }\n\n  .row-cols-md-2 > * {\n    flex: 0 0 auto;\n    width: 50%;\n  }\n\n  .row-cols-md-3 > * {\n    flex: 0 0 auto;\n    width: 33.3333333333%;\n  }\n\n  .row-cols-md-4 > * {\n    flex: 0 0 auto;\n    width: 25%;\n  }\n\n  .row-cols-md-5 > * {\n    flex: 0 0 auto;\n    width: 20%;\n  }\n\n  .row-cols-md-6 > * {\n    flex: 0 0 auto;\n    width: 16.6666666667%;\n  }\n\n  .col-md-auto {\n    flex: 0 0 auto;\n    width: auto;\n  }\n\n  .col-md-1 {\n    flex: 0 0 auto;\n    width: 8.33333333%;\n  }\n\n  .col-md-2 {\n    flex: 0 0 auto;\n    width: 16.66666667%;\n  }\n\n  .col-md-3 {\n    flex: 0 0 auto;\n    width: 25%;\n  }\n\n  .col-md-4 {\n    flex: 0 0 auto;\n    width: 33.33333333%;\n  }\n\n  .col-md-5 {\n    flex: 0 0 auto;\n    width: 41.66666667%;\n  }\n\n  .col-md-6 {\n    flex: 0 0 auto;\n    width: 50%;\n  }\n\n  .col-md-7 {\n    flex: 0 0 auto;\n    width: 58.33333333%;\n  }\n\n  .col-md-8 {\n    flex: 0 0 auto;\n    width: 66.66666667%;\n  }\n\n  .col-md-9 {\n    flex: 0 0 auto;\n    width: 75%;\n  }\n\n  .col-md-10 {\n    flex: 0 0 auto;\n    width: 83.33333333%;\n  }\n\n  .col-md-11 {\n    flex: 0 0 auto;\n    width: 91.66666667%;\n  }\n\n  .col-md-12 {\n    flex: 0 0 auto;\n    width: 100%;\n  }\n\n  .offset-md-0 {\n    margin-right: 0;\n  }\n\n  .offset-md-1 {\n    margin-right: 8.33333333%;\n  }\n\n  .offset-md-2 {\n    margin-right: 16.66666667%;\n  }\n\n  .offset-md-3 {\n    margin-right: 25%;\n  }\n\n  .offset-md-4 {\n    margin-right: 33.33333333%;\n  }\n\n  .offset-md-5 {\n    margin-right: 41.66666667%;\n  }\n\n  .offset-md-6 {\n    margin-right: 50%;\n  }\n\n  .offset-md-7 {\n    margin-right: 58.33333333%;\n  }\n\n  .offset-md-8 {\n    margin-right: 66.66666667%;\n  }\n\n  .offset-md-9 {\n    margin-right: 75%;\n  }\n\n  .offset-md-10 {\n    margin-right: 83.33333333%;\n  }\n\n  .offset-md-11 {\n    margin-right: 91.66666667%;\n  }\n\n  .g-md-0,\n.gx-md-0 {\n    --bs-gutter-x: 0;\n  }\n\n  .g-md-0,\n.gy-md-0 {\n    --bs-gutter-y: 0;\n  }\n\n  .g-md-1,\n.gx-md-1 {\n    --bs-gutter-x: 0.25rem;\n  }\n\n  .g-md-1,\n.gy-md-1 {\n    --bs-gutter-y: 0.25rem;\n  }\n\n  .g-md-2,\n.gx-md-2 {\n    --bs-gutter-x: 0.5rem;\n  }\n\n  .g-md-2,\n.gy-md-2 {\n    --bs-gutter-y: 0.5rem;\n  }\n\n  .g-md-3,\n.gx-md-3 {\n    --bs-gutter-x: 1rem;\n  }\n\n  .g-md-3,\n.gy-md-3 {\n    --bs-gutter-y: 1rem;\n  }\n\n  .g-md-4,\n.gx-md-4 {\n    --bs-gutter-x: 1.5rem;\n  }\n\n  .g-md-4,\n.gy-md-4 {\n    --bs-gutter-y: 1.5rem;\n  }\n\n  .g-md-5,\n.gx-md-5 {\n    --bs-gutter-x: 3rem;\n  }\n\n  .g-md-5,\n.gy-md-5 {\n    --bs-gutter-y: 3rem;\n  }\n}\n@media (min-width: 992px) {\n  .col-lg {\n    flex: 1 0 0%;\n  }\n\n  .row-cols-lg-auto > * {\n    flex: 0 0 auto;\n    width: auto;\n  }\n\n  .row-cols-lg-1 > * {\n    flex: 0 0 auto;\n    width: 100%;\n  }\n\n  .row-cols-lg-2 > * {\n    flex: 0 0 auto;\n    width: 50%;\n  }\n\n  .row-cols-lg-3 > * {\n    flex: 0 0 auto;\n    width: 33.3333333333%;\n  }\n\n  .row-cols-lg-4 > * {\n    flex: 0 0 auto;\n    width: 25%;\n  }\n\n  .row-cols-lg-5 > * {\n    flex: 0 0 auto;\n    width: 20%;\n  }\n\n  .row-cols-lg-6 > * {\n    flex: 0 0 auto;\n    width: 16.6666666667%;\n  }\n\n  .col-lg-auto {\n    flex: 0 0 auto;\n    width: auto;\n  }\n\n  .col-lg-1 {\n    flex: 0 0 auto;\n    width: 8.33333333%;\n  }\n\n  .col-lg-2 {\n    flex: 0 0 auto;\n    width: 16.66666667%;\n  }\n\n  .col-lg-3 {\n    flex: 0 0 auto;\n    width: 25%;\n  }\n\n  .col-lg-4 {\n    flex: 0 0 auto;\n    width: 33.33333333%;\n  }\n\n  .col-lg-5 {\n    flex: 0 0 auto;\n    width: 41.66666667%;\n  }\n\n  .col-lg-6 {\n    flex: 0 0 auto;\n    width: 50%;\n  }\n\n  .col-lg-7 {\n    flex: 0 0 auto;\n    width: 58.33333333%;\n  }\n\n  .col-lg-8 {\n    flex: 0 0 auto;\n    width: 66.66666667%;\n  }\n\n  .col-lg-9 {\n    flex: 0 0 auto;\n    width: 75%;\n  }\n\n  .col-lg-10 {\n    flex: 0 0 auto;\n    width: 83.33333333%;\n  }\n\n  .col-lg-11 {\n    flex: 0 0 auto;\n    width: 91.66666667%;\n  }\n\n  .col-lg-12 {\n    flex: 0 0 auto;\n    width: 100%;\n  }\n\n  .offset-lg-0 {\n    margin-right: 0;\n  }\n\n  .offset-lg-1 {\n    margin-right: 8.33333333%;\n  }\n\n  .offset-lg-2 {\n    margin-right: 16.66666667%;\n  }\n\n  .offset-lg-3 {\n    margin-right: 25%;\n  }\n\n  .offset-lg-4 {\n    margin-right: 33.33333333%;\n  }\n\n  .offset-lg-5 {\n    margin-right: 41.66666667%;\n  }\n\n  .offset-lg-6 {\n    margin-right: 50%;\n  }\n\n  .offset-lg-7 {\n    margin-right: 58.33333333%;\n  }\n\n  .offset-lg-8 {\n    margin-right: 66.66666667%;\n  }\n\n  .offset-lg-9 {\n    margin-right: 75%;\n  }\n\n  .offset-lg-10 {\n    margin-right: 83.33333333%;\n  }\n\n  .offset-lg-11 {\n    margin-right: 91.66666667%;\n  }\n\n  .g-lg-0,\n.gx-lg-0 {\n    --bs-gutter-x: 0;\n  }\n\n  .g-lg-0,\n.gy-lg-0 {\n    --bs-gutter-y: 0;\n  }\n\n  .g-lg-1,\n.gx-lg-1 {\n    --bs-gutter-x: 0.25rem;\n  }\n\n  .g-lg-1,\n.gy-lg-1 {\n    --bs-gutter-y: 0.25rem;\n  }\n\n  .g-lg-2,\n.gx-lg-2 {\n    --bs-gutter-x: 0.5rem;\n  }\n\n  .g-lg-2,\n.gy-lg-2 {\n    --bs-gutter-y: 0.5rem;\n  }\n\n  .g-lg-3,\n.gx-lg-3 {\n    --bs-gutter-x: 1rem;\n  }\n\n  .g-lg-3,\n.gy-lg-3 {\n    --bs-gutter-y: 1rem;\n  }\n\n  .g-lg-4,\n.gx-lg-4 {\n    --bs-gutter-x: 1.5rem;\n  }\n\n  .g-lg-4,\n.gy-lg-4 {\n    --bs-gutter-y: 1.5rem;\n  }\n\n  .g-lg-5,\n.gx-lg-5 {\n    --bs-gutter-x: 3rem;\n  }\n\n  .g-lg-5,\n.gy-lg-5 {\n    --bs-gutter-y: 3rem;\n  }\n}\n@media (min-width: 1200px) {\n  .col-xl {\n    flex: 1 0 0%;\n  }\n\n  .row-cols-xl-auto > * {\n    flex: 0 0 auto;\n    width: auto;\n  }\n\n  .row-cols-xl-1 > * {\n    flex: 0 0 auto;\n    width: 100%;\n  }\n\n  .row-cols-xl-2 > * {\n    flex: 0 0 auto;\n    width: 50%;\n  }\n\n  .row-cols-xl-3 > * {\n    flex: 0 0 auto;\n    width: 33.3333333333%;\n  }\n\n  .row-cols-xl-4 > * {\n    flex: 0 0 auto;\n    width: 25%;\n  }\n\n  .row-cols-xl-5 > * {\n    flex: 0 0 auto;\n    width: 20%;\n  }\n\n  .row-cols-xl-6 > * {\n    flex: 0 0 auto;\n    width: 16.6666666667%;\n  }\n\n  .col-xl-auto {\n    flex: 0 0 auto;\n    width: auto;\n  }\n\n  .col-xl-1 {\n    flex: 0 0 auto;\n    width: 8.33333333%;\n  }\n\n  .col-xl-2 {\n    flex: 0 0 auto;\n    width: 16.66666667%;\n  }\n\n  .col-xl-3 {\n    flex: 0 0 auto;\n    width: 25%;\n  }\n\n  .col-xl-4 {\n    flex: 0 0 auto;\n    width: 33.33333333%;\n  }\n\n  .col-xl-5 {\n    flex: 0 0 auto;\n    width: 41.66666667%;\n  }\n\n  .col-xl-6 {\n    flex: 0 0 auto;\n    width: 50%;\n  }\n\n  .col-xl-7 {\n    flex: 0 0 auto;\n    width: 58.33333333%;\n  }\n\n  .col-xl-8 {\n    flex: 0 0 auto;\n    width: 66.66666667%;\n  }\n\n  .col-xl-9 {\n    flex: 0 0 auto;\n    width: 75%;\n  }\n\n  .col-xl-10 {\n    flex: 0 0 auto;\n    width: 83.33333333%;\n  }\n\n  .col-xl-11 {\n    flex: 0 0 auto;\n    width: 91.66666667%;\n  }\n\n  .col-xl-12 {\n    flex: 0 0 auto;\n    width: 100%;\n  }\n\n  .offset-xl-0 {\n    margin-right: 0;\n  }\n\n  .offset-xl-1 {\n    margin-right: 8.33333333%;\n  }\n\n  .offset-xl-2 {\n    margin-right: 16.66666667%;\n  }\n\n  .offset-xl-3 {\n    margin-right: 25%;\n  }\n\n  .offset-xl-4 {\n    margin-right: 33.33333333%;\n  }\n\n  .offset-xl-5 {\n    margin-right: 41.66666667%;\n  }\n\n  .offset-xl-6 {\n    margin-right: 50%;\n  }\n\n  .offset-xl-7 {\n    margin-right: 58.33333333%;\n  }\n\n  .offset-xl-8 {\n    margin-right: 66.66666667%;\n  }\n\n  .offset-xl-9 {\n    margin-right: 75%;\n  }\n\n  .offset-xl-10 {\n    margin-right: 83.33333333%;\n  }\n\n  .offset-xl-11 {\n    margin-right: 91.66666667%;\n  }\n\n  .g-xl-0,\n.gx-xl-0 {\n    --bs-gutter-x: 0;\n  }\n\n  .g-xl-0,\n.gy-xl-0 {\n    --bs-gutter-y: 0;\n  }\n\n  .g-xl-1,\n.gx-xl-1 {\n    --bs-gutter-x: 0.25rem;\n  }\n\n  .g-xl-1,\n.gy-xl-1 {\n    --bs-gutter-y: 0.25rem;\n  }\n\n  .g-xl-2,\n.gx-xl-2 {\n    --bs-gutter-x: 0.5rem;\n  }\n\n  .g-xl-2,\n.gy-xl-2 {\n    --bs-gutter-y: 0.5rem;\n  }\n\n  .g-xl-3,\n.gx-xl-3 {\n    --bs-gutter-x: 1rem;\n  }\n\n  .g-xl-3,\n.gy-xl-3 {\n    --bs-gutter-y: 1rem;\n  }\n\n  .g-xl-4,\n.gx-xl-4 {\n    --bs-gutter-x: 1.5rem;\n  }\n\n  .g-xl-4,\n.gy-xl-4 {\n    --bs-gutter-y: 1.5rem;\n  }\n\n  .g-xl-5,\n.gx-xl-5 {\n    --bs-gutter-x: 3rem;\n  }\n\n  .g-xl-5,\n.gy-xl-5 {\n    --bs-gutter-y: 3rem;\n  }\n}\n@media (min-width: 1400px) {\n  .col-xxl {\n    flex: 1 0 0%;\n  }\n\n  .row-cols-xxl-auto > * {\n    flex: 0 0 auto;\n    width: auto;\n  }\n\n  .row-cols-xxl-1 > * {\n    flex: 0 0 auto;\n    width: 100%;\n  }\n\n  .row-cols-xxl-2 > * {\n    flex: 0 0 auto;\n    width: 50%;\n  }\n\n  .row-cols-xxl-3 > * {\n    flex: 0 0 auto;\n    width: 33.3333333333%;\n  }\n\n  .row-cols-xxl-4 > * {\n    flex: 0 0 auto;\n    width: 25%;\n  }\n\n  .row-cols-xxl-5 > * {\n    flex: 0 0 auto;\n    width: 20%;\n  }\n\n  .row-cols-xxl-6 > * {\n    flex: 0 0 auto;\n    width: 16.6666666667%;\n  }\n\n  .col-xxl-auto {\n    flex: 0 0 auto;\n    width: auto;\n  }\n\n  .col-xxl-1 {\n    flex: 0 0 auto;\n    width: 8.33333333%;\n  }\n\n  .col-xxl-2 {\n    flex: 0 0 auto;\n    width: 16.66666667%;\n  }\n\n  .col-xxl-3 {\n    flex: 0 0 auto;\n    width: 25%;\n  }\n\n  .col-xxl-4 {\n    flex: 0 0 auto;\n    width: 33.33333333%;\n  }\n\n  .col-xxl-5 {\n    flex: 0 0 auto;\n    width: 41.66666667%;\n  }\n\n  .col-xxl-6 {\n    flex: 0 0 auto;\n    width: 50%;\n  }\n\n  .col-xxl-7 {\n    flex: 0 0 auto;\n    width: 58.33333333%;\n  }\n\n  .col-xxl-8 {\n    flex: 0 0 auto;\n    width: 66.66666667%;\n  }\n\n  .col-xxl-9 {\n    flex: 0 0 auto;\n    width: 75%;\n  }\n\n  .col-xxl-10 {\n    flex: 0 0 auto;\n    width: 83.33333333%;\n  }\n\n  .col-xxl-11 {\n    flex: 0 0 auto;\n    width: 91.66666667%;\n  }\n\n  .col-xxl-12 {\n    flex: 0 0 auto;\n    width: 100%;\n  }\n\n  .offset-xxl-0 {\n    margin-right: 0;\n  }\n\n  .offset-xxl-1 {\n    margin-right: 8.33333333%;\n  }\n\n  .offset-xxl-2 {\n    margin-right: 16.66666667%;\n  }\n\n  .offset-xxl-3 {\n    margin-right: 25%;\n  }\n\n  .offset-xxl-4 {\n    margin-right: 33.33333333%;\n  }\n\n  .offset-xxl-5 {\n    margin-right: 41.66666667%;\n  }\n\n  .offset-xxl-6 {\n    margin-right: 50%;\n  }\n\n  .offset-xxl-7 {\n    margin-right: 58.33333333%;\n  }\n\n  .offset-xxl-8 {\n    margin-right: 66.66666667%;\n  }\n\n  .offset-xxl-9 {\n    margin-right: 75%;\n  }\n\n  .offset-xxl-10 {\n    margin-right: 83.33333333%;\n  }\n\n  .offset-xxl-11 {\n    margin-right: 91.66666667%;\n  }\n\n  .g-xxl-0,\n.gx-xxl-0 {\n    --bs-gutter-x: 0;\n  }\n\n  .g-xxl-0,\n.gy-xxl-0 {\n    --bs-gutter-y: 0;\n  }\n\n  .g-xxl-1,\n.gx-xxl-1 {\n    --bs-gutter-x: 0.25rem;\n  }\n\n  .g-xxl-1,\n.gy-xxl-1 {\n    --bs-gutter-y: 0.25rem;\n  }\n\n  .g-xxl-2,\n.gx-xxl-2 {\n    --bs-gutter-x: 0.5rem;\n  }\n\n  .g-xxl-2,\n.gy-xxl-2 {\n    --bs-gutter-y: 0.5rem;\n  }\n\n  .g-xxl-3,\n.gx-xxl-3 {\n    --bs-gutter-x: 1rem;\n  }\n\n  .g-xxl-3,\n.gy-xxl-3 {\n    --bs-gutter-y: 1rem;\n  }\n\n  .g-xxl-4,\n.gx-xxl-4 {\n    --bs-gutter-x: 1.5rem;\n  }\n\n  .g-xxl-4,\n.gy-xxl-4 {\n    --bs-gutter-y: 1.5rem;\n  }\n\n  .g-xxl-5,\n.gx-xxl-5 {\n    --bs-gutter-x: 3rem;\n  }\n\n  .g-xxl-5,\n.gy-xxl-5 {\n    --bs-gutter-y: 3rem;\n  }\n}\n.table {\n  --bs-table-bg: transparent;\n  --bs-table-accent-bg: transparent;\n  --bs-table-striped-color: #212529;\n  --bs-table-striped-bg: rgba(0, 0, 0, 0.05);\n  --bs-table-active-color: #212529;\n  --bs-table-active-bg: rgba(0, 0, 0, 0.1);\n  --bs-table-hover-color: #212529;\n  --bs-table-hover-bg: rgba(0, 0, 0, 0.075);\n  width: 100%;\n  margin-bottom: 1rem;\n  color: #212529;\n  vertical-align: top;\n  border-color: #dee2e6;\n}\n.table > :not(caption) > * > * {\n  padding: 0.5rem 0.5rem;\n  background-color: var(--bs-table-bg);\n  border-bottom-width: 1px;\n  box-shadow: inset 0 0 0 9999px var(--bs-table-accent-bg);\n}\n.table > tbody {\n  vertical-align: inherit;\n}\n.table > thead {\n  vertical-align: bottom;\n}\n.table > :not(:last-child) > :last-child > * {\n  border-bottom-color: currentColor;\n}\n\n.caption-top {\n  caption-side: top;\n}\n\n.table-sm > :not(caption) > * > * {\n  padding: 0.25rem 0.25rem;\n}\n\n.table-bordered > :not(caption) > * {\n  border-width: 1px 0;\n}\n.table-bordered > :not(caption) > * > * {\n  border-width: 0 1px;\n}\n\n.table-borderless > :not(caption) > * > * {\n  border-bottom-width: 0;\n}\n\n.table-striped > tbody > tr:nth-of-type(odd) {\n  --bs-table-accent-bg: var(--bs-table-striped-bg);\n  color: var(--bs-table-striped-color);\n}\n\n.table-active {\n  --bs-table-accent-bg: var(--bs-table-active-bg);\n  color: var(--bs-table-active-color);\n}\n\n.table-hover > tbody > tr:hover {\n  --bs-table-accent-bg: var(--bs-table-hover-bg);\n  color: var(--bs-table-hover-color);\n}\n\n.table-primary {\n  --bs-table-bg: #cfe2ff;\n  --bs-table-striped-bg: #c5d7f2;\n  --bs-table-striped-color: #000;\n  --bs-table-active-bg: #bacbe6;\n  --bs-table-active-color: #000;\n  --bs-table-hover-bg: #bfd1ec;\n  --bs-table-hover-color: #000;\n  color: #000;\n  border-color: #bacbe6;\n}\n\n.table-secondary {\n  --bs-table-bg: #e2e3e5;\n  --bs-table-striped-bg: #d7d8da;\n  --bs-table-striped-color: #000;\n  --bs-table-active-bg: #cbccce;\n  --bs-table-active-color: #000;\n  --bs-table-hover-bg: #d1d2d4;\n  --bs-table-hover-color: #000;\n  color: #000;\n  border-color: #cbccce;\n}\n\n.table-success {\n  --bs-table-bg: #d1e7dd;\n  --bs-table-striped-bg: #c7dbd2;\n  --bs-table-striped-color: #000;\n  --bs-table-active-bg: #bcd0c7;\n  --bs-table-active-color: #000;\n  --bs-table-hover-bg: #c1d6cc;\n  --bs-table-hover-color: #000;\n  color: #000;\n  border-color: #bcd0c7;\n}\n\n.table-info {\n  --bs-table-bg: #cff4fc;\n  --bs-table-striped-bg: #c5e8ef;\n  --bs-table-striped-color: #000;\n  --bs-table-active-bg: #badce3;\n  --bs-table-active-color: #000;\n  --bs-table-hover-bg: #bfe2e9;\n  --bs-table-hover-color: #000;\n  color: #000;\n  border-color: #badce3;\n}\n\n.table-warning {\n  --bs-table-bg: #fff3cd;\n  --bs-table-striped-bg: #f2e7c3;\n  --bs-table-striped-color: #000;\n  --bs-table-active-bg: #e6dbb9;\n  --bs-table-active-color: #000;\n  --bs-table-hover-bg: #ece1be;\n  --bs-table-hover-color: #000;\n  color: #000;\n  border-color: #e6dbb9;\n}\n\n.table-danger {\n  --bs-table-bg: #f8d7da;\n  --bs-table-striped-bg: #eccccf;\n  --bs-table-striped-color: #000;\n  --bs-table-active-bg: #dfc2c4;\n  --bs-table-active-color: #000;\n  --bs-table-hover-bg: #e5c7ca;\n  --bs-table-hover-color: #000;\n  color: #000;\n  border-color: #dfc2c4;\n}\n\n.table-light {\n  --bs-table-bg: #f8f9fa;\n  --bs-table-striped-bg: #ecedee;\n  --bs-table-striped-color: #000;\n  --bs-table-active-bg: #dfe0e1;\n  --bs-table-active-color: #000;\n  --bs-table-hover-bg: #e5e6e7;\n  --bs-table-hover-color: #000;\n  color: #000;\n  border-color: #dfe0e1;\n}\n\n.table-dark {\n  --bs-table-bg: #212529;\n  --bs-table-striped-bg: #2c3034;\n  --bs-table-striped-color: #fff;\n  --bs-table-active-bg: #373b3e;\n  --bs-table-active-color: #fff;\n  --bs-table-hover-bg: #323539;\n  --bs-table-hover-color: #fff;\n  color: #fff;\n  border-color: #373b3e;\n}\n\n.table-responsive {\n  overflow-x: auto;\n  -webkit-overflow-scrolling: touch;\n}\n\n@media (max-width: 575.98px) {\n  .table-responsive-sm {\n    overflow-x: auto;\n    -webkit-overflow-scrolling: touch;\n  }\n}\n@media (max-width: 767.98px) {\n  .table-responsive-md {\n    overflow-x: auto;\n    -webkit-overflow-scrolling: touch;\n  }\n}\n@media (max-width: 991.98px) {\n  .table-responsive-lg {\n    overflow-x: auto;\n    -webkit-overflow-scrolling: touch;\n  }\n}\n@media (max-width: 1199.98px) {\n  .table-responsive-xl {\n    overflow-x: auto;\n    -webkit-overflow-scrolling: touch;\n  }\n}\n@media (max-width: 1399.98px) {\n  .table-responsive-xxl {\n    overflow-x: auto;\n    -webkit-overflow-scrolling: touch;\n  }\n}\n.form-label {\n  margin-bottom: 0.5rem;\n}\n\n.col-form-label {\n  padding-top: calc(0.375rem + 1px);\n  padding-bottom: calc(0.375rem + 1px);\n  margin-bottom: 0;\n  font-size: inherit;\n  line-height: 1.5;\n}\n\n.col-form-label-lg {\n  padding-top: calc(0.5rem + 1px);\n  padding-bottom: calc(0.5rem + 1px);\n  font-size: 1.25rem;\n}\n\n.col-form-label-sm {\n  padding-top: calc(0.25rem + 1px);\n  padding-bottom: calc(0.25rem + 1px);\n  font-size: 0.875rem;\n}\n\n.form-text {\n  margin-top: 0.25rem;\n  font-size: 0.875em;\n  color: #6c757d;\n}\n\n.form-control {\n  display: block;\n  width: 100%;\n  padding: 0.375rem 0.75rem;\n  font-size: 1rem;\n  font-weight: 400;\n  line-height: 1.5;\n  color: #212529;\n  background-color: #fff;\n  background-clip: padding-box;\n  border: 1px solid #ced4da;\n  -webkit-appearance: none;\n  -moz-appearance: none;\n  appearance: none;\n  border-radius: 0.25rem;\n  transition: border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;\n}\n@media (prefers-reduced-motion: reduce) {\n  .form-control {\n    transition: none;\n  }\n}\n.form-control[type=file] {\n  overflow: hidden;\n}\n.form-control[type=file]:not(:disabled):not([readonly]) {\n  cursor: pointer;\n}\n.form-control:focus {\n  color: #212529;\n  background-color: #fff;\n  border-color: #86b7fe;\n  outline: 0;\n  box-shadow: 0 0 0 0.25rem rgba(13, 110, 253, 0.25);\n}\n.form-control::-webkit-date-and-time-value {\n  height: 1.5em;\n}\n.form-control::-moz-placeholder {\n  color: #6c757d;\n  opacity: 1;\n}\n.form-control::placeholder {\n  color: #6c757d;\n  opacity: 1;\n}\n.form-control:disabled, .form-control[readonly] {\n  background-color: #e9ecef;\n  opacity: 1;\n}\n.form-control::file-selector-button {\n  padding: 0.375rem 0.75rem;\n  margin: -0.375rem -0.75rem;\n  -webkit-margin-end: 0.75rem;\n  margin-inline-end: 0.75rem;\n  color: #212529;\n  background-color: #e9ecef;\n  pointer-events: none;\n  border-color: inherit;\n  border-style: solid;\n  border-width: 0;\n  border-inline-end-width: 1px;\n  border-radius: 0;\n  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;\n}\n@media (prefers-reduced-motion: reduce) {\n  .form-control::file-selector-button {\n    transition: none;\n  }\n}\n.form-control:hover:not(:disabled):not([readonly])::file-selector-button {\n  background-color: #dde0e3;\n}\n.form-control::-webkit-file-upload-button {\n  padding: 0.375rem 0.75rem;\n  margin: -0.375rem -0.75rem;\n  -webkit-margin-end: 0.75rem;\n  margin-inline-end: 0.75rem;\n  color: #212529;\n  background-color: #e9ecef;\n  pointer-events: none;\n  border-color: inherit;\n  border-style: solid;\n  border-width: 0;\n  border-inline-end-width: 1px;\n  border-radius: 0;\n  -webkit-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;\n  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;\n}\n@media (prefers-reduced-motion: reduce) {\n  .form-control::-webkit-file-upload-button {\n    -webkit-transition: none;\n    transition: none;\n  }\n}\n.form-control:hover:not(:disabled):not([readonly])::-webkit-file-upload-button {\n  background-color: #dde0e3;\n}\n\n.form-control-plaintext {\n  display: block;\n  width: 100%;\n  padding: 0.375rem 0;\n  margin-bottom: 0;\n  line-height: 1.5;\n  color: #212529;\n  background-color: transparent;\n  border: solid transparent;\n  border-width: 1px 0;\n}\n.form-control-plaintext.form-control-sm, .form-control-plaintext.form-control-lg {\n  padding-left: 0;\n  padding-right: 0;\n}\n\n.form-control-sm {\n  min-height: calc(1.5em + 0.5rem + 2px);\n  padding: 0.25rem 0.5rem;\n  font-size: 0.875rem;\n  border-radius: 0.2rem;\n}\n.form-control-sm::file-selector-button {\n  padding: 0.25rem 0.5rem;\n  margin: -0.25rem -0.5rem;\n  -webkit-margin-end: 0.5rem;\n  margin-inline-end: 0.5rem;\n}\n.form-control-sm::-webkit-file-upload-button {\n  padding: 0.25rem 0.5rem;\n  margin: -0.25rem -0.5rem;\n  -webkit-margin-end: 0.5rem;\n  margin-inline-end: 0.5rem;\n}\n\n.form-control-lg {\n  min-height: calc(1.5em + 1rem + 2px);\n  padding: 0.5rem 1rem;\n  font-size: 1.25rem;\n  border-radius: 0.3rem;\n}\n.form-control-lg::file-selector-button {\n  padding: 0.5rem 1rem;\n  margin: -0.5rem -1rem;\n  -webkit-margin-end: 1rem;\n  margin-inline-end: 1rem;\n}\n.form-control-lg::-webkit-file-upload-button {\n  padding: 0.5rem 1rem;\n  margin: -0.5rem -1rem;\n  -webkit-margin-end: 1rem;\n  margin-inline-end: 1rem;\n}\n\ntextarea.form-control {\n  min-height: calc(1.5em + 0.75rem + 2px);\n}\ntextarea.form-control-sm {\n  min-height: calc(1.5em + 0.5rem + 2px);\n}\ntextarea.form-control-lg {\n  min-height: calc(1.5em + 1rem + 2px);\n}\n\n.form-control-color {\n  width: 3rem;\n  height: auto;\n  padding: 0.375rem;\n}\n.form-control-color:not(:disabled):not([readonly]) {\n  cursor: pointer;\n}\n.form-control-color::-moz-color-swatch {\n  height: 1.5em;\n  border-radius: 0.25rem;\n}\n.form-control-color::-webkit-color-swatch {\n  height: 1.5em;\n  border-radius: 0.25rem;\n}\n\n.form-select {\n  display: block;\n  width: 100%;\n  padding: 0.375rem 0.75rem 0.375rem 2.25rem;\n  -moz-padding-start: calc(0.75rem - 3px);\n  font-size: 1rem;\n  font-weight: 400;\n  line-height: 1.5;\n  color: #212529;\n  background-color: #fff;\n  background-image: 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 5l6 6 6-6'/%3e%3c/svg%3e\");\n  background-repeat: no-repeat;\n  background-position: left 0.75rem center;\n  background-size: 16px 12px;\n  border: 1px solid #ced4da;\n  border-radius: 0.25rem;\n  transition: border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;\n  -webkit-appearance: none;\n  -moz-appearance: none;\n  appearance: none;\n}\n@media (prefers-reduced-motion: reduce) {\n  .form-select {\n    transition: none;\n  }\n}\n.form-select:focus {\n  border-color: #86b7fe;\n  outline: 0;\n  box-shadow: 0 0 0 0.25rem rgba(13, 110, 253, 0.25);\n}\n.form-select[multiple], .form-select[size]:not([size=\"1\"]) {\n  padding-left: 0.75rem;\n  background-image: none;\n}\n.form-select:disabled {\n  background-color: #e9ecef;\n}\n.form-select:-moz-focusring {\n  color: transparent;\n  text-shadow: 0 0 0 #212529;\n}\n\n.form-select-sm {\n  padding-top: 0.25rem;\n  padding-bottom: 0.25rem;\n  padding-right: 0.5rem;\n  font-size: 0.875rem;\n}\n\n.form-select-lg {\n  padding-top: 0.5rem;\n  padding-bottom: 0.5rem;\n  padding-right: 1rem;\n  font-size: 1.25rem;\n}\n\n.form-check {\n  display: block;\n  min-height: 1.5rem;\n  padding-right: 1.5em;\n  margin-bottom: 0.125rem;\n}\n.form-check .form-check-input {\n  float: right;\n  margin-right: -1.5em;\n}\n\n.form-check-input {\n  width: 1em;\n  height: 1em;\n  margin-top: 0.25em;\n  vertical-align: top;\n  background-color: #fff;\n  background-repeat: no-repeat;\n  background-position: center;\n  background-size: contain;\n  border: 1px solid rgba(0, 0, 0, 0.25);\n  -webkit-appearance: none;\n  -moz-appearance: none;\n  appearance: none;\n  -webkit-print-color-adjust: exact;\n  color-adjust: exact;\n}\n.form-check-input[type=checkbox] {\n  border-radius: 0.25em;\n}\n.form-check-input[type=radio] {\n  border-radius: 50%;\n}\n.form-check-input:active {\n  filter: brightness(90%);\n}\n.form-check-input:focus {\n  border-color: #86b7fe;\n  outline: 0;\n  box-shadow: 0 0 0 0.25rem rgba(13, 110, 253, 0.25);\n}\n.form-check-input:checked {\n  background-color: #0d6efd;\n  border-color: #0d6efd;\n}\n.form-check-input:checked[type=checkbox] {\n  background-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 10l3 3l6-6'/%3e%3c/svg%3e\");\n}\n.form-check-input:checked[type=radio] {\n  background-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\");\n}\n.form-check-input[type=checkbox]:indeterminate {\n  background-color: #0d6efd;\n  border-color: #0d6efd;\n  background-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\");\n}\n.form-check-input:disabled {\n  pointer-events: none;\n  filter: none;\n  opacity: 0.5;\n}\n.form-check-input[disabled] ~ .form-check-label, .form-check-input:disabled ~ .form-check-label {\n  opacity: 0.5;\n}\n\n.form-switch {\n  padding-right: 2.5em;\n}\n.form-switch .form-check-input {\n  width: 2em;\n  margin-right: -2.5em;\n  background-image: 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\");\n  background-position: right center;\n  border-radius: 2em;\n  transition: background-position 0.15s ease-in-out;\n}\n@media (prefers-reduced-motion: reduce) {\n  .form-switch .form-check-input {\n    transition: none;\n  }\n}\n.form-switch .form-check-input:focus {\n  background-image: 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\");\n}\n.form-switch .form-check-input:checked {\n  background-position: left center;\n  background-image: 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\");\n}\n\n.form-check-inline {\n  display: inline-block;\n  margin-left: 1rem;\n}\n\n.btn-check {\n  position: absolute;\n  clip: rect(0, 0, 0, 0);\n  pointer-events: none;\n}\n.btn-check[disabled] + .btn, .btn-check:disabled + .btn {\n  pointer-events: none;\n  filter: none;\n  opacity: 0.65;\n}\n\n.form-range {\n  width: 100%;\n  height: 1.5rem;\n  padding: 0;\n  background-color: transparent;\n  -webkit-appearance: none;\n  -moz-appearance: none;\n  appearance: none;\n}\n.form-range:focus {\n  outline: 0;\n}\n.form-range:focus::-webkit-slider-thumb {\n  box-shadow: 0 0 0 1px #fff, 0 0 0 0.25rem rgba(13, 110, 253, 0.25);\n}\n.form-range:focus::-moz-range-thumb {\n  box-shadow: 0 0 0 1px #fff, 0 0 0 0.25rem rgba(13, 110, 253, 0.25);\n}\n.form-range::-moz-focus-outer {\n  border: 0;\n}\n.form-range::-webkit-slider-thumb {\n  width: 1rem;\n  height: 1rem;\n  margin-top: -0.25rem;\n  background-color: #0d6efd;\n  border: 0;\n  border-radius: 1rem;\n  -webkit-transition: background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;\n  transition: background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;\n  -webkit-appearance: none;\n  appearance: none;\n}\n@media (prefers-reduced-motion: reduce) {\n  .form-range::-webkit-slider-thumb {\n    -webkit-transition: none;\n    transition: none;\n  }\n}\n.form-range::-webkit-slider-thumb:active {\n  background-color: #b6d4fe;\n}\n.form-range::-webkit-slider-runnable-track {\n  width: 100%;\n  height: 0.5rem;\n  color: transparent;\n  cursor: pointer;\n  background-color: #dee2e6;\n  border-color: transparent;\n  border-radius: 1rem;\n}\n.form-range::-moz-range-thumb {\n  width: 1rem;\n  height: 1rem;\n  background-color: #0d6efd;\n  border: 0;\n  border-radius: 1rem;\n  -moz-transition: background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;\n  transition: background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;\n  -moz-appearance: none;\n  appearance: none;\n}\n@media (prefers-reduced-motion: reduce) {\n  .form-range::-moz-range-thumb {\n    -moz-transition: none;\n    transition: none;\n  }\n}\n.form-range::-moz-range-thumb:active {\n  background-color: #b6d4fe;\n}\n.form-range::-moz-range-track {\n  width: 100%;\n  height: 0.5rem;\n  color: transparent;\n  cursor: pointer;\n  background-color: #dee2e6;\n  border-color: transparent;\n  border-radius: 1rem;\n}\n.form-range:disabled {\n  pointer-events: none;\n}\n.form-range:disabled::-webkit-slider-thumb {\n  background-color: #adb5bd;\n}\n.form-range:disabled::-moz-range-thumb {\n  background-color: #adb5bd;\n}\n\n.form-floating {\n  position: relative;\n}\n.form-floating > .form-control,\n.form-floating > .form-select {\n  height: calc(3.5rem + 2px);\n  line-height: 1.25;\n}\n.form-floating > label {\n  position: absolute;\n  top: 0;\n  right: 0;\n  height: 100%;\n  padding: 1rem 0.75rem;\n  pointer-events: none;\n  border: 1px solid transparent;\n  transform-origin: 100% 0;\n  transition: opacity 0.1s ease-in-out, transform 0.1s ease-in-out;\n}\n@media (prefers-reduced-motion: reduce) {\n  .form-floating > label {\n    transition: none;\n  }\n}\n.form-floating > .form-control {\n  padding: 1rem 0.75rem;\n}\n.form-floating > .form-control::-moz-placeholder {\n  color: transparent;\n}\n.form-floating > .form-control::placeholder {\n  color: transparent;\n}\n.form-floating > .form-control:not(:-moz-placeholder-shown) {\n  padding-top: 1.625rem;\n  padding-bottom: 0.625rem;\n}\n.form-floating > .form-control:focus, .form-floating > .form-control:not(:placeholder-shown) {\n  padding-top: 1.625rem;\n  padding-bottom: 0.625rem;\n}\n.form-floating > .form-control:-webkit-autofill {\n  padding-top: 1.625rem;\n  padding-bottom: 0.625rem;\n}\n.form-floating > .form-select {\n  padding-top: 1.625rem;\n  padding-bottom: 0.625rem;\n}\n.form-floating > .form-control:not(:-moz-placeholder-shown) ~ label {\n  opacity: 0.65;\n  transform: scale(0.85) translateY(-0.5rem) translateX(-0.15rem);\n}\n.form-floating > .form-control:focus ~ label,\n.form-floating > .form-control:not(:placeholder-shown) ~ label,\n.form-floating > .form-select ~ label {\n  opacity: 0.65;\n  transform: scale(0.85) translateY(-0.5rem) translateX(-0.15rem);\n}\n.form-floating > .form-control:-webkit-autofill ~ label {\n  opacity: 0.65;\n  transform: scale(0.85) translateY(-0.5rem) translateX(-0.15rem);\n}\n\n.input-group {\n  position: relative;\n  display: flex;\n  flex-wrap: wrap;\n  align-items: stretch;\n  width: 100%;\n}\n.input-group > .form-control,\n.input-group > .form-select {\n  position: relative;\n  flex: 1 1 auto;\n  width: 1%;\n  min-width: 0;\n}\n.input-group > .form-control:focus,\n.input-group > .form-select:focus {\n  z-index: 3;\n}\n.input-group .btn {\n  position: relative;\n  z-index: 2;\n}\n.input-group .btn:focus {\n  z-index: 3;\n}\n\n.input-group-text {\n  display: flex;\n  align-items: center;\n  padding: 0.375rem 0.75rem;\n  font-size: 1rem;\n  font-weight: 400;\n  line-height: 1.5;\n  color: #212529;\n  text-align: center;\n  white-space: nowrap;\n  background-color: #e9ecef;\n  border: 1px solid #ced4da;\n  border-radius: 0.25rem;\n}\n\n.input-group-lg > .form-control,\n.input-group-lg > .form-select,\n.input-group-lg > .input-group-text,\n.input-group-lg > .btn {\n  padding: 0.5rem 1rem;\n  font-size: 1.25rem;\n  border-radius: 0.3rem;\n}\n\n.input-group-sm > .form-control,\n.input-group-sm > .form-select,\n.input-group-sm > .input-group-text,\n.input-group-sm > .btn {\n  padding: 0.25rem 0.5rem;\n  font-size: 0.875rem;\n  border-radius: 0.2rem;\n}\n\n.input-group-lg > .form-select,\n.input-group-sm > .form-select {\n  padding-left: 3rem;\n}\n\n.input-group:not(.has-validation) > :not(:last-child):not(.dropdown-toggle):not(.dropdown-menu),\n.input-group:not(.has-validation) > .dropdown-toggle:nth-last-child(n+3) {\n  border-top-left-radius: 0;\n  border-bottom-left-radius: 0;\n}\n.input-group.has-validation > :nth-last-child(n+3):not(.dropdown-toggle):not(.dropdown-menu),\n.input-group.has-validation > .dropdown-toggle:nth-last-child(n+4) {\n  border-top-left-radius: 0;\n  border-bottom-left-radius: 0;\n}\n.input-group > :not(:first-child):not(.dropdown-menu):not(.valid-tooltip):not(.valid-feedback):not(.invalid-tooltip):not(.invalid-feedback) {\n  margin-right: -1px;\n  border-top-right-radius: 0;\n  border-bottom-right-radius: 0;\n}\n\n.valid-feedback {\n  display: none;\n  width: 100%;\n  margin-top: 0.25rem;\n  font-size: 0.875em;\n  color: #198754;\n}\n\n.valid-tooltip {\n  position: absolute;\n  top: 100%;\n  z-index: 5;\n  display: none;\n  max-width: 100%;\n  padding: 0.25rem 0.5rem;\n  margin-top: 0.1rem;\n  font-size: 0.875rem;\n  color: #fff;\n  background-color: rgba(25, 135, 84, 0.9);\n  border-radius: 0.25rem;\n}\n\n.was-validated :valid ~ .valid-feedback,\n.was-validated :valid ~ .valid-tooltip,\n.is-valid ~ .valid-feedback,\n.is-valid ~ .valid-tooltip {\n  display: block;\n}\n\n.was-validated .form-control:valid, .form-control.is-valid {\n  border-color: #198754;\n  padding-left: calc(1.5em + 0.75rem);\n  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.73L.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.1z'/%3e%3c/svg%3e\");\n  background-repeat: no-repeat;\n  background-position: left calc(0.375em + 0.1875rem) center;\n  background-size: calc(0.75em + 0.375rem) calc(0.75em + 0.375rem);\n}\n.was-validated .form-control:valid:focus, .form-control.is-valid:focus {\n  border-color: #198754;\n  box-shadow: 0 0 0 0.25rem rgba(25, 135, 84, 0.25);\n}\n\n.was-validated textarea.form-control:valid, textarea.form-control.is-valid {\n  padding-left: calc(1.5em + 0.75rem);\n  background-position: top calc(0.375em + 0.1875rem) left calc(0.375em + 0.1875rem);\n}\n\n.was-validated .form-select:valid, .form-select.is-valid {\n  border-color: #198754;\n}\n.was-validated .form-select:valid:not([multiple]):not([size]), .was-validated .form-select:valid:not([multiple])[size=\"1\"], .form-select.is-valid:not([multiple]):not([size]), .form-select.is-valid:not([multiple])[size=\"1\"] {\n  padding-left: 4.125rem;\n  background-image: 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 5l6 6 6-6'/%3e%3c/svg%3e\"), 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.73L.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.1z'/%3e%3c/svg%3e\");\n  background-position: left 0.75rem center, center left 2.25rem;\n  background-size: 16px 12px, calc(0.75em + 0.375rem) calc(0.75em + 0.375rem);\n}\n.was-validated .form-select:valid:focus, .form-select.is-valid:focus {\n  border-color: #198754;\n  box-shadow: 0 0 0 0.25rem rgba(25, 135, 84, 0.25);\n}\n\n.was-validated .form-check-input:valid, .form-check-input.is-valid {\n  border-color: #198754;\n}\n.was-validated .form-check-input:valid:checked, .form-check-input.is-valid:checked {\n  background-color: #198754;\n}\n.was-validated .form-check-input:valid:focus, .form-check-input.is-valid:focus {\n  box-shadow: 0 0 0 0.25rem rgba(25, 135, 84, 0.25);\n}\n.was-validated .form-check-input:valid ~ .form-check-label, .form-check-input.is-valid ~ .form-check-label {\n  color: #198754;\n}\n\n.form-check-inline .form-check-input ~ .valid-feedback {\n  margin-right: 0.5em;\n}\n\n.was-validated .input-group .form-control:valid, .input-group .form-control.is-valid,\n.was-validated .input-group .form-select:valid,\n.input-group .form-select.is-valid {\n  z-index: 1;\n}\n.was-validated .input-group .form-control:valid:focus, .input-group .form-control.is-valid:focus,\n.was-validated .input-group .form-select:valid:focus,\n.input-group .form-select.is-valid:focus {\n  z-index: 3;\n}\n\n.invalid-feedback {\n  display: none;\n  width: 100%;\n  margin-top: 0.25rem;\n  font-size: 0.875em;\n  color: #dc3545;\n}\n\n.invalid-tooltip {\n  position: absolute;\n  top: 100%;\n  z-index: 5;\n  display: none;\n  max-width: 100%;\n  padding: 0.25rem 0.5rem;\n  margin-top: 0.1rem;\n  font-size: 0.875rem;\n  color: #fff;\n  background-color: rgba(220, 53, 69, 0.9);\n  border-radius: 0.25rem;\n}\n\n.was-validated :invalid ~ .invalid-feedback,\n.was-validated :invalid ~ .invalid-tooltip,\n.is-invalid ~ .invalid-feedback,\n.is-invalid ~ .invalid-tooltip {\n  display: block;\n}\n\n.was-validated .form-control:invalid, .form-control.is-invalid {\n  border-color: #dc3545;\n  padding-left: calc(1.5em + 0.75rem);\n  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\");\n  background-repeat: no-repeat;\n  background-position: left calc(0.375em + 0.1875rem) center;\n  background-size: calc(0.75em + 0.375rem) calc(0.75em + 0.375rem);\n}\n.was-validated .form-control:invalid:focus, .form-control.is-invalid:focus {\n  border-color: #dc3545;\n  box-shadow: 0 0 0 0.25rem rgba(220, 53, 69, 0.25);\n}\n\n.was-validated textarea.form-control:invalid, textarea.form-control.is-invalid {\n  padding-left: calc(1.5em + 0.75rem);\n  background-position: top calc(0.375em + 0.1875rem) left calc(0.375em + 0.1875rem);\n}\n\n.was-validated .form-select:invalid, .form-select.is-invalid {\n  border-color: #dc3545;\n}\n.was-validated .form-select:invalid:not([multiple]):not([size]), .was-validated .form-select:invalid:not([multiple])[size=\"1\"], .form-select.is-invalid:not([multiple]):not([size]), .form-select.is-invalid:not([multiple])[size=\"1\"] {\n  padding-left: 4.125rem;\n  background-image: 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 5l6 6 6-6'/%3e%3c/svg%3e\"), 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\");\n  background-position: left 0.75rem center, center left 2.25rem;\n  background-size: 16px 12px, calc(0.75em + 0.375rem) calc(0.75em + 0.375rem);\n}\n.was-validated .form-select:invalid:focus, .form-select.is-invalid:focus {\n  border-color: #dc3545;\n  box-shadow: 0 0 0 0.25rem rgba(220, 53, 69, 0.25);\n}\n\n.was-validated .form-check-input:invalid, .form-check-input.is-invalid {\n  border-color: #dc3545;\n}\n.was-validated .form-check-input:invalid:checked, .form-check-input.is-invalid:checked {\n  background-color: #dc3545;\n}\n.was-validated .form-check-input:invalid:focus, .form-check-input.is-invalid:focus {\n  box-shadow: 0 0 0 0.25rem rgba(220, 53, 69, 0.25);\n}\n.was-validated .form-check-input:invalid ~ .form-check-label, .form-check-input.is-invalid ~ .form-check-label {\n  color: #dc3545;\n}\n\n.form-check-inline .form-check-input ~ .invalid-feedback {\n  margin-right: 0.5em;\n}\n\n.was-validated .input-group .form-control:invalid, .input-group .form-control.is-invalid,\n.was-validated .input-group .form-select:invalid,\n.input-group .form-select.is-invalid {\n  z-index: 2;\n}\n.was-validated .input-group .form-control:invalid:focus, .input-group .form-control.is-invalid:focus,\n.was-validated .input-group .form-select:invalid:focus,\n.input-group .form-select.is-invalid:focus {\n  z-index: 3;\n}\n\n.btn {\n  display: inline-block;\n  font-weight: 400;\n  line-height: 1.5;\n  color: #212529;\n  text-align: center;\n  text-decoration: none;\n  vertical-align: middle;\n  cursor: pointer;\n  -webkit-user-select: none;\n  -moz-user-select: none;\n  user-select: none;\n  background-color: transparent;\n  border: 1px solid transparent;\n  padding: 0.375rem 0.75rem;\n  font-size: 1rem;\n  border-radius: 0.25rem;\n  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;\n}\n@media (prefers-reduced-motion: reduce) {\n  .btn {\n    transition: none;\n  }\n}\n.btn:hover {\n  color: #212529;\n}\n.btn-check:focus + .btn, .btn:focus {\n  outline: 0;\n  box-shadow: 0 0 0 0.25rem rgba(13, 110, 253, 0.25);\n}\n.btn:disabled, .btn.disabled, fieldset:disabled .btn {\n  pointer-events: none;\n  opacity: 0.65;\n}\n\n.btn-primary {\n  color: #fff;\n  background-color: #0d6efd;\n  border-color: #0d6efd;\n}\n.btn-primary:hover {\n  color: #fff;\n  background-color: #0b5ed7;\n  border-color: #0a58ca;\n}\n.btn-check:focus + .btn-primary, .btn-primary:focus {\n  color: #fff;\n  background-color: #0b5ed7;\n  border-color: #0a58ca;\n  box-shadow: 0 0 0 0.25rem rgba(49, 132, 253, 0.5);\n}\n.btn-check:checked + .btn-primary, .btn-check:active + .btn-primary, .btn-primary:active, .btn-primary.active, .show > .btn-primary.dropdown-toggle {\n  color: #fff;\n  background-color: #0a58ca;\n  border-color: #0a53be;\n}\n.btn-check:checked + .btn-primary:focus, .btn-check:active + .btn-primary:focus, .btn-primary:active:focus, .btn-primary.active:focus, .show > .btn-primary.dropdown-toggle:focus {\n  box-shadow: 0 0 0 0.25rem rgba(49, 132, 253, 0.5);\n}\n.btn-primary:disabled, .btn-primary.disabled {\n  color: #fff;\n  background-color: #0d6efd;\n  border-color: #0d6efd;\n}\n\n.btn-secondary {\n  color: #fff;\n  background-color: #6c757d;\n  border-color: #6c757d;\n}\n.btn-secondary:hover {\n  color: #fff;\n  background-color: #5c636a;\n  border-color: #565e64;\n}\n.btn-check:focus + .btn-secondary, .btn-secondary:focus {\n  color: #fff;\n  background-color: #5c636a;\n  border-color: #565e64;\n  box-shadow: 0 0 0 0.25rem rgba(130, 138, 145, 0.5);\n}\n.btn-check:checked + .btn-secondary, .btn-check:active + .btn-secondary, .btn-secondary:active, .btn-secondary.active, .show > .btn-secondary.dropdown-toggle {\n  color: #fff;\n  background-color: #565e64;\n  border-color: #51585e;\n}\n.btn-check:checked + .btn-secondary:focus, .btn-check:active + .btn-secondary:focus, .btn-secondary:active:focus, .btn-secondary.active:focus, .show > .btn-secondary.dropdown-toggle:focus {\n  box-shadow: 0 0 0 0.25rem rgba(130, 138, 145, 0.5);\n}\n.btn-secondary:disabled, .btn-secondary.disabled {\n  color: #fff;\n  background-color: #6c757d;\n  border-color: #6c757d;\n}\n\n.btn-success {\n  color: #fff;\n  background-color: #198754;\n  border-color: #198754;\n}\n.btn-success:hover {\n  color: #fff;\n  background-color: #157347;\n  border-color: #146c43;\n}\n.btn-check:focus + .btn-success, .btn-success:focus {\n  color: #fff;\n  background-color: #157347;\n  border-color: #146c43;\n  box-shadow: 0 0 0 0.25rem rgba(60, 153, 110, 0.5);\n}\n.btn-check:checked + .btn-success, .btn-check:active + .btn-success, .btn-success:active, .btn-success.active, .show > .btn-success.dropdown-toggle {\n  color: #fff;\n  background-color: #146c43;\n  border-color: #13653f;\n}\n.btn-check:checked + .btn-success:focus, .btn-check:active + .btn-success:focus, .btn-success:active:focus, .btn-success.active:focus, .show > .btn-success.dropdown-toggle:focus {\n  box-shadow: 0 0 0 0.25rem rgba(60, 153, 110, 0.5);\n}\n.btn-success:disabled, .btn-success.disabled {\n  color: #fff;\n  background-color: #198754;\n  border-color: #198754;\n}\n\n.btn-info {\n  color: #000;\n  background-color: #0dcaf0;\n  border-color: #0dcaf0;\n}\n.btn-info:hover {\n  color: #000;\n  background-color: #31d2f2;\n  border-color: #25cff2;\n}\n.btn-check:focus + .btn-info, .btn-info:focus {\n  color: #000;\n  background-color: #31d2f2;\n  border-color: #25cff2;\n  box-shadow: 0 0 0 0.25rem rgba(11, 172, 204, 0.5);\n}\n.btn-check:checked + .btn-info, .btn-check:active + .btn-info, .btn-info:active, .btn-info.active, .show > .btn-info.dropdown-toggle {\n  color: #000;\n  background-color: #3dd5f3;\n  border-color: #25cff2;\n}\n.btn-check:checked + .btn-info:focus, .btn-check:active + .btn-info:focus, .btn-info:active:focus, .btn-info.active:focus, .show > .btn-info.dropdown-toggle:focus {\n  box-shadow: 0 0 0 0.25rem rgba(11, 172, 204, 0.5);\n}\n.btn-info:disabled, .btn-info.disabled {\n  color: #000;\n  background-color: #0dcaf0;\n  border-color: #0dcaf0;\n}\n\n.btn-warning {\n  color: #000;\n  background-color: #ffc107;\n  border-color: #ffc107;\n}\n.btn-warning:hover {\n  color: #000;\n  background-color: #ffca2c;\n  border-color: #ffc720;\n}\n.btn-check:focus + .btn-warning, .btn-warning:focus {\n  color: #000;\n  background-color: #ffca2c;\n  border-color: #ffc720;\n  box-shadow: 0 0 0 0.25rem rgba(217, 164, 6, 0.5);\n}\n.btn-check:checked + .btn-warning, .btn-check:active + .btn-warning, .btn-warning:active, .btn-warning.active, .show > .btn-warning.dropdown-toggle {\n  color: #000;\n  background-color: #ffcd39;\n  border-color: #ffc720;\n}\n.btn-check:checked + .btn-warning:focus, .btn-check:active + .btn-warning:focus, .btn-warning:active:focus, .btn-warning.active:focus, .show > .btn-warning.dropdown-toggle:focus {\n  box-shadow: 0 0 0 0.25rem rgba(217, 164, 6, 0.5);\n}\n.btn-warning:disabled, .btn-warning.disabled {\n  color: #000;\n  background-color: #ffc107;\n  border-color: #ffc107;\n}\n\n.btn-danger {\n  color: #fff;\n  background-color: #dc3545;\n  border-color: #dc3545;\n}\n.btn-danger:hover {\n  color: #fff;\n  background-color: #bb2d3b;\n  border-color: #b02a37;\n}\n.btn-check:focus + .btn-danger, .btn-danger:focus {\n  color: #fff;\n  background-color: #bb2d3b;\n  border-color: #b02a37;\n  box-shadow: 0 0 0 0.25rem rgba(225, 83, 97, 0.5);\n}\n.btn-check:checked + .btn-danger, .btn-check:active + .btn-danger, .btn-danger:active, .btn-danger.active, .show > .btn-danger.dropdown-toggle {\n  color: #fff;\n  background-color: #b02a37;\n  border-color: #a52834;\n}\n.btn-check:checked + .btn-danger:focus, .btn-check:active + .btn-danger:focus, .btn-danger:active:focus, .btn-danger.active:focus, .show > .btn-danger.dropdown-toggle:focus {\n  box-shadow: 0 0 0 0.25rem rgba(225, 83, 97, 0.5);\n}\n.btn-danger:disabled, .btn-danger.disabled {\n  color: #fff;\n  background-color: #dc3545;\n  border-color: #dc3545;\n}\n\n.btn-light {\n  color: #000;\n  background-color: #f8f9fa;\n  border-color: #f8f9fa;\n}\n.btn-light:hover {\n  color: #000;\n  background-color: #f9fafb;\n  border-color: #f9fafb;\n}\n.btn-check:focus + .btn-light, .btn-light:focus {\n  color: #000;\n  background-color: #f9fafb;\n  border-color: #f9fafb;\n  box-shadow: 0 0 0 0.25rem rgba(211, 212, 213, 0.5);\n}\n.btn-check:checked + .btn-light, .btn-check:active + .btn-light, .btn-light:active, .btn-light.active, .show > .btn-light.dropdown-toggle {\n  color: #000;\n  background-color: #f9fafb;\n  border-color: #f9fafb;\n}\n.btn-check:checked + .btn-light:focus, .btn-check:active + .btn-light:focus, .btn-light:active:focus, .btn-light.active:focus, .show > .btn-light.dropdown-toggle:focus {\n  box-shadow: 0 0 0 0.25rem rgba(211, 212, 213, 0.5);\n}\n.btn-light:disabled, .btn-light.disabled {\n  color: #000;\n  background-color: #f8f9fa;\n  border-color: #f8f9fa;\n}\n\n.btn-dark {\n  color: #fff;\n  background-color: #212529;\n  border-color: #212529;\n}\n.btn-dark:hover {\n  color: #fff;\n  background-color: #1c1f23;\n  border-color: #1a1e21;\n}\n.btn-check:focus + .btn-dark, .btn-dark:focus {\n  color: #fff;\n  background-color: #1c1f23;\n  border-color: #1a1e21;\n  box-shadow: 0 0 0 0.25rem rgba(66, 70, 73, 0.5);\n}\n.btn-check:checked + .btn-dark, .btn-check:active + .btn-dark, .btn-dark:active, .btn-dark.active, .show > .btn-dark.dropdown-toggle {\n  color: #fff;\n  background-color: #1a1e21;\n  border-color: #191c1f;\n}\n.btn-check:checked + .btn-dark:focus, .btn-check:active + .btn-dark:focus, .btn-dark:active:focus, .btn-dark.active:focus, .show > .btn-dark.dropdown-toggle:focus {\n  box-shadow: 0 0 0 0.25rem rgba(66, 70, 73, 0.5);\n}\n.btn-dark:disabled, .btn-dark.disabled {\n  color: #fff;\n  background-color: #212529;\n  border-color: #212529;\n}\n\n.btn-outline-primary {\n  color: #0d6efd;\n  border-color: #0d6efd;\n}\n.btn-outline-primary:hover {\n  color: #fff;\n  background-color: #0d6efd;\n  border-color: #0d6efd;\n}\n.btn-check:focus + .btn-outline-primary, .btn-outline-primary:focus {\n  box-shadow: 0 0 0 0.25rem rgba(13, 110, 253, 0.5);\n}\n.btn-check:checked + .btn-outline-primary, .btn-check:active + .btn-outline-primary, .btn-outline-primary:active, .btn-outline-primary.active, .btn-outline-primary.dropdown-toggle.show {\n  color: #fff;\n  background-color: #0d6efd;\n  border-color: #0d6efd;\n}\n.btn-check:checked + .btn-outline-primary:focus, .btn-check:active + .btn-outline-primary:focus, .btn-outline-primary:active:focus, .btn-outline-primary.active:focus, .btn-outline-primary.dropdown-toggle.show:focus {\n  box-shadow: 0 0 0 0.25rem rgba(13, 110, 253, 0.5);\n}\n.btn-outline-primary:disabled, .btn-outline-primary.disabled {\n  color: #0d6efd;\n  background-color: transparent;\n}\n\n.btn-outline-secondary {\n  color: #6c757d;\n  border-color: #6c757d;\n}\n.btn-outline-secondary:hover {\n  color: #fff;\n  background-color: #6c757d;\n  border-color: #6c757d;\n}\n.btn-check:focus + .btn-outline-secondary, .btn-outline-secondary:focus {\n  box-shadow: 0 0 0 0.25rem rgba(108, 117, 125, 0.5);\n}\n.btn-check:checked + .btn-outline-secondary, .btn-check:active + .btn-outline-secondary, .btn-outline-secondary:active, .btn-outline-secondary.active, .btn-outline-secondary.dropdown-toggle.show {\n  color: #fff;\n  background-color: #6c757d;\n  border-color: #6c757d;\n}\n.btn-check:checked + .btn-outline-secondary:focus, .btn-check:active + .btn-outline-secondary:focus, .btn-outline-secondary:active:focus, .btn-outline-secondary.active:focus, .btn-outline-secondary.dropdown-toggle.show:focus {\n  box-shadow: 0 0 0 0.25rem rgba(108, 117, 125, 0.5);\n}\n.btn-outline-secondary:disabled, .btn-outline-secondary.disabled {\n  color: #6c757d;\n  background-color: transparent;\n}\n\n.btn-outline-success {\n  color: #198754;\n  border-color: #198754;\n}\n.btn-outline-success:hover {\n  color: #fff;\n  background-color: #198754;\n  border-color: #198754;\n}\n.btn-check:focus + .btn-outline-success, .btn-outline-success:focus {\n  box-shadow: 0 0 0 0.25rem rgba(25, 135, 84, 0.5);\n}\n.btn-check:checked + .btn-outline-success, .btn-check:active + .btn-outline-success, .btn-outline-success:active, .btn-outline-success.active, .btn-outline-success.dropdown-toggle.show {\n  color: #fff;\n  background-color: #198754;\n  border-color: #198754;\n}\n.btn-check:checked + .btn-outline-success:focus, .btn-check:active + .btn-outline-success:focus, .btn-outline-success:active:focus, .btn-outline-success.active:focus, .btn-outline-success.dropdown-toggle.show:focus {\n  box-shadow: 0 0 0 0.25rem rgba(25, 135, 84, 0.5);\n}\n.btn-outline-success:disabled, .btn-outline-success.disabled {\n  color: #198754;\n  background-color: transparent;\n}\n\n.btn-outline-info {\n  color: #0dcaf0;\n  border-color: #0dcaf0;\n}\n.btn-outline-info:hover {\n  color: #000;\n  background-color: #0dcaf0;\n  border-color: #0dcaf0;\n}\n.btn-check:focus + .btn-outline-info, .btn-outline-info:focus {\n  box-shadow: 0 0 0 0.25rem rgba(13, 202, 240, 0.5);\n}\n.btn-check:checked + .btn-outline-info, .btn-check:active + .btn-outline-info, .btn-outline-info:active, .btn-outline-info.active, .btn-outline-info.dropdown-toggle.show {\n  color: #000;\n  background-color: #0dcaf0;\n  border-color: #0dcaf0;\n}\n.btn-check:checked + .btn-outline-info:focus, .btn-check:active + .btn-outline-info:focus, .btn-outline-info:active:focus, .btn-outline-info.active:focus, .btn-outline-info.dropdown-toggle.show:focus {\n  box-shadow: 0 0 0 0.25rem rgba(13, 202, 240, 0.5);\n}\n.btn-outline-info:disabled, .btn-outline-info.disabled {\n  color: #0dcaf0;\n  background-color: transparent;\n}\n\n.btn-outline-warning {\n  color: #ffc107;\n  border-color: #ffc107;\n}\n.btn-outline-warning:hover {\n  color: #000;\n  background-color: #ffc107;\n  border-color: #ffc107;\n}\n.btn-check:focus + .btn-outline-warning, .btn-outline-warning:focus {\n  box-shadow: 0 0 0 0.25rem rgba(255, 193, 7, 0.5);\n}\n.btn-check:checked + .btn-outline-warning, .btn-check:active + .btn-outline-warning, .btn-outline-warning:active, .btn-outline-warning.active, .btn-outline-warning.dropdown-toggle.show {\n  color: #000;\n  background-color: #ffc107;\n  border-color: #ffc107;\n}\n.btn-check:checked + .btn-outline-warning:focus, .btn-check:active + .btn-outline-warning:focus, .btn-outline-warning:active:focus, .btn-outline-warning.active:focus, .btn-outline-warning.dropdown-toggle.show:focus {\n  box-shadow: 0 0 0 0.25rem rgba(255, 193, 7, 0.5);\n}\n.btn-outline-warning:disabled, .btn-outline-warning.disabled {\n  color: #ffc107;\n  background-color: transparent;\n}\n\n.btn-outline-danger {\n  color: #dc3545;\n  border-color: #dc3545;\n}\n.btn-outline-danger:hover {\n  color: #fff;\n  background-color: #dc3545;\n  border-color: #dc3545;\n}\n.btn-check:focus + .btn-outline-danger, .btn-outline-danger:focus {\n  box-shadow: 0 0 0 0.25rem rgba(220, 53, 69, 0.5);\n}\n.btn-check:checked + .btn-outline-danger, .btn-check:active + .btn-outline-danger, .btn-outline-danger:active, .btn-outline-danger.active, .btn-outline-danger.dropdown-toggle.show {\n  color: #fff;\n  background-color: #dc3545;\n  border-color: #dc3545;\n}\n.btn-check:checked + .btn-outline-danger:focus, .btn-check:active + .btn-outline-danger:focus, .btn-outline-danger:active:focus, .btn-outline-danger.active:focus, .btn-outline-danger.dropdown-toggle.show:focus {\n  box-shadow: 0 0 0 0.25rem rgba(220, 53, 69, 0.5);\n}\n.btn-outline-danger:disabled, .btn-outline-danger.disabled {\n  color: #dc3545;\n  background-color: transparent;\n}\n\n.btn-outline-light {\n  color: #f8f9fa;\n  border-color: #f8f9fa;\n}\n.btn-outline-light:hover {\n  color: #000;\n  background-color: #f8f9fa;\n  border-color: #f8f9fa;\n}\n.btn-check:focus + .btn-outline-light, .btn-outline-light:focus {\n  box-shadow: 0 0 0 0.25rem rgba(248, 249, 250, 0.5);\n}\n.btn-check:checked + .btn-outline-light, .btn-check:active + .btn-outline-light, .btn-outline-light:active, .btn-outline-light.active, .btn-outline-light.dropdown-toggle.show {\n  color: #000;\n  background-color: #f8f9fa;\n  border-color: #f8f9fa;\n}\n.btn-check:checked + .btn-outline-light:focus, .btn-check:active + .btn-outline-light:focus, .btn-outline-light:active:focus, .btn-outline-light.active:focus, .btn-outline-light.dropdown-toggle.show:focus {\n  box-shadow: 0 0 0 0.25rem rgba(248, 249, 250, 0.5);\n}\n.btn-outline-light:disabled, .btn-outline-light.disabled {\n  color: #f8f9fa;\n  background-color: transparent;\n}\n\n.btn-outline-dark {\n  color: #212529;\n  border-color: #212529;\n}\n.btn-outline-dark:hover {\n  color: #fff;\n  background-color: #212529;\n  border-color: #212529;\n}\n.btn-check:focus + .btn-outline-dark, .btn-outline-dark:focus {\n  box-shadow: 0 0 0 0.25rem rgba(33, 37, 41, 0.5);\n}\n.btn-check:checked + .btn-outline-dark, .btn-check:active + .btn-outline-dark, .btn-outline-dark:active, .btn-outline-dark.active, .btn-outline-dark.dropdown-toggle.show {\n  color: #fff;\n  background-color: #212529;\n  border-color: #212529;\n}\n.btn-check:checked + .btn-outline-dark:focus, .btn-check:active + .btn-outline-dark:focus, .btn-outline-dark:active:focus, .btn-outline-dark.active:focus, .btn-outline-dark.dropdown-toggle.show:focus {\n  box-shadow: 0 0 0 0.25rem rgba(33, 37, 41, 0.5);\n}\n.btn-outline-dark:disabled, .btn-outline-dark.disabled {\n  color: #212529;\n  background-color: transparent;\n}\n\n.btn-link {\n  font-weight: 400;\n  color: #0d6efd;\n  text-decoration: underline;\n}\n.btn-link:hover {\n  color: #0a58ca;\n}\n.btn-link:disabled, .btn-link.disabled {\n  color: #6c757d;\n}\n\n.btn-lg, .btn-group-lg > .btn {\n  padding: 0.5rem 1rem;\n  font-size: 1.25rem;\n  border-radius: 0.3rem;\n}\n\n.btn-sm, .btn-group-sm > .btn {\n  padding: 0.25rem 0.5rem;\n  font-size: 0.875rem;\n  border-radius: 0.2rem;\n}\n\n.fade {\n  transition: opacity 0.15s linear;\n}\n@media (prefers-reduced-motion: reduce) {\n  .fade {\n    transition: none;\n  }\n}\n.fade:not(.show) {\n  opacity: 0;\n}\n\n.collapse:not(.show) {\n  display: none;\n}\n\n.collapsing {\n  height: 0;\n  overflow: hidden;\n  transition: height 0.35s ease;\n}\n@media (prefers-reduced-motion: reduce) {\n  .collapsing {\n    transition: none;\n  }\n}\n.collapsing.collapse-horizontal {\n  width: 0;\n  height: auto;\n  transition: width 0.35s ease;\n}\n@media (prefers-reduced-motion: reduce) {\n  .collapsing.collapse-horizontal {\n    transition: none;\n  }\n}\n\n.dropup,\n.dropend,\n.dropdown,\n.dropstart {\n  position: relative;\n}\n\n.dropdown-toggle {\n  white-space: nowrap;\n}\n.dropdown-toggle::after {\n  display: inline-block;\n  margin-right: 0.255em;\n  vertical-align: 0.255em;\n  content: \"\";\n  border-top: 0.3em solid;\n  border-left: 0.3em solid transparent;\n  border-bottom: 0;\n  border-right: 0.3em solid transparent;\n}\n.dropdown-toggle:empty::after {\n  margin-right: 0;\n}\n\n.dropdown-menu {\n  position: absolute;\n  z-index: 1000;\n  display: none;\n  min-width: 10rem;\n  padding: 0.5rem 0;\n  margin: 0;\n  font-size: 1rem;\n  color: #212529;\n  text-align: right;\n  list-style: none;\n  background-color: #fff;\n  background-clip: padding-box;\n  border: 1px solid rgba(0, 0, 0, 0.15);\n  border-radius: 0.25rem;\n}\n.dropdown-menu[data-bs-popper] {\n  top: 100%;\n  right: 0;\n  margin-top: 0.125rem;\n}\n\n.dropdown-menu-start {\n  --bs-position: start;\n}\n.dropdown-menu-start[data-bs-popper] {\n  left: auto;\n  right: 0;\n}\n\n.dropdown-menu-end {\n  --bs-position: end;\n}\n.dropdown-menu-end[data-bs-popper] {\n  left: 0;\n  right: auto;\n}\n\n@media (min-width: 576px) {\n  .dropdown-menu-sm-start {\n    --bs-position: start;\n  }\n  .dropdown-menu-sm-start[data-bs-popper] {\n    left: auto;\n    right: 0;\n  }\n\n  .dropdown-menu-sm-end {\n    --bs-position: end;\n  }\n  .dropdown-menu-sm-end[data-bs-popper] {\n    left: 0;\n    right: auto;\n  }\n}\n@media (min-width: 768px) {\n  .dropdown-menu-md-start {\n    --bs-position: start;\n  }\n  .dropdown-menu-md-start[data-bs-popper] {\n    left: auto;\n    right: 0;\n  }\n\n  .dropdown-menu-md-end {\n    --bs-position: end;\n  }\n  .dropdown-menu-md-end[data-bs-popper] {\n    left: 0;\n    right: auto;\n  }\n}\n@media (min-width: 992px) {\n  .dropdown-menu-lg-start {\n    --bs-position: start;\n  }\n  .dropdown-menu-lg-start[data-bs-popper] {\n    left: auto;\n    right: 0;\n  }\n\n  .dropdown-menu-lg-end {\n    --bs-position: end;\n  }\n  .dropdown-menu-lg-end[data-bs-popper] {\n    left: 0;\n    right: auto;\n  }\n}\n@media (min-width: 1200px) {\n  .dropdown-menu-xl-start {\n    --bs-position: start;\n  }\n  .dropdown-menu-xl-start[data-bs-popper] {\n    left: auto;\n    right: 0;\n  }\n\n  .dropdown-menu-xl-end {\n    --bs-position: end;\n  }\n  .dropdown-menu-xl-end[data-bs-popper] {\n    left: 0;\n    right: auto;\n  }\n}\n@media (min-width: 1400px) {\n  .dropdown-menu-xxl-start {\n    --bs-position: start;\n  }\n  .dropdown-menu-xxl-start[data-bs-popper] {\n    left: auto;\n    right: 0;\n  }\n\n  .dropdown-menu-xxl-end {\n    --bs-position: end;\n  }\n  .dropdown-menu-xxl-end[data-bs-popper] {\n    left: 0;\n    right: auto;\n  }\n}\n.dropup .dropdown-menu[data-bs-popper] {\n  top: auto;\n  bottom: 100%;\n  margin-top: 0;\n  margin-bottom: 0.125rem;\n}\n.dropup .dropdown-toggle::after {\n  display: inline-block;\n  margin-right: 0.255em;\n  vertical-align: 0.255em;\n  content: \"\";\n  border-top: 0;\n  border-left: 0.3em solid transparent;\n  border-bottom: 0.3em solid;\n  border-right: 0.3em solid transparent;\n}\n.dropup .dropdown-toggle:empty::after {\n  margin-right: 0;\n}\n\n.dropend .dropdown-menu[data-bs-popper] {\n  top: 0;\n  left: auto;\n  right: 100%;\n  margin-top: 0;\n  margin-right: 0.125rem;\n}\n.dropend .dropdown-toggle::after {\n  display: inline-block;\n  margin-right: 0.255em;\n  vertical-align: 0.255em;\n  content: \"\";\n  border-top: 0.3em solid transparent;\n  border-left: 0;\n  border-bottom: 0.3em solid transparent;\n  border-right: 0.3em solid;\n}\n.dropend .dropdown-toggle:empty::after {\n  margin-right: 0;\n}\n.dropend .dropdown-toggle::after {\n  vertical-align: 0;\n}\n\n.dropstart .dropdown-menu[data-bs-popper] {\n  top: 0;\n  left: 100%;\n  right: auto;\n  margin-top: 0;\n  margin-left: 0.125rem;\n}\n.dropstart .dropdown-toggle::after {\n  display: inline-block;\n  margin-right: 0.255em;\n  vertical-align: 0.255em;\n  content: \"\";\n}\n.dropstart .dropdown-toggle::after {\n  display: none;\n}\n.dropstart .dropdown-toggle::before {\n  display: inline-block;\n  margin-left: 0.255em;\n  vertical-align: 0.255em;\n  content: \"\";\n  border-top: 0.3em solid transparent;\n  border-left: 0.3em solid;\n  border-bottom: 0.3em solid transparent;\n}\n.dropstart .dropdown-toggle:empty::after {\n  margin-right: 0;\n}\n.dropstart .dropdown-toggle::before {\n  vertical-align: 0;\n}\n\n.dropdown-divider {\n  height: 0;\n  margin: 0.5rem 0;\n  overflow: hidden;\n  border-top: 1px solid rgba(0, 0, 0, 0.15);\n}\n\n.dropdown-item {\n  display: block;\n  width: 100%;\n  padding: 0.25rem 1rem;\n  clear: both;\n  font-weight: 400;\n  color: #212529;\n  text-align: inherit;\n  text-decoration: none;\n  white-space: nowrap;\n  background-color: transparent;\n  border: 0;\n}\n.dropdown-item:hover, .dropdown-item:focus {\n  color: #1e2125;\n  background-color: #e9ecef;\n}\n.dropdown-item.active, .dropdown-item:active {\n  color: #fff;\n  text-decoration: none;\n  background-color: #0d6efd;\n}\n.dropdown-item.disabled, .dropdown-item:disabled {\n  color: #adb5bd;\n  pointer-events: none;\n  background-color: transparent;\n}\n\n.dropdown-menu.show {\n  display: block;\n}\n\n.dropdown-header {\n  display: block;\n  padding: 0.5rem 1rem;\n  margin-bottom: 0;\n  font-size: 0.875rem;\n  color: #6c757d;\n  white-space: nowrap;\n}\n\n.dropdown-item-text {\n  display: block;\n  padding: 0.25rem 1rem;\n  color: #212529;\n}\n\n.dropdown-menu-dark {\n  color: #dee2e6;\n  background-color: #343a40;\n  border-color: rgba(0, 0, 0, 0.15);\n}\n.dropdown-menu-dark .dropdown-item {\n  color: #dee2e6;\n}\n.dropdown-menu-dark .dropdown-item:hover, .dropdown-menu-dark .dropdown-item:focus {\n  color: #fff;\n  background-color: rgba(255, 255, 255, 0.15);\n}\n.dropdown-menu-dark .dropdown-item.active, .dropdown-menu-dark .dropdown-item:active {\n  color: #fff;\n  background-color: #0d6efd;\n}\n.dropdown-menu-dark .dropdown-item.disabled, .dropdown-menu-dark .dropdown-item:disabled {\n  color: #adb5bd;\n}\n.dropdown-menu-dark .dropdown-divider {\n  border-color: rgba(0, 0, 0, 0.15);\n}\n.dropdown-menu-dark .dropdown-item-text {\n  color: #dee2e6;\n}\n.dropdown-menu-dark .dropdown-header {\n  color: #adb5bd;\n}\n\n.btn-group,\n.btn-group-vertical {\n  position: relative;\n  display: inline-flex;\n  vertical-align: middle;\n}\n.btn-group > .btn,\n.btn-group-vertical > .btn {\n  position: relative;\n  flex: 1 1 auto;\n}\n.btn-group > .btn-check:checked + .btn,\n.btn-group > .btn-check:focus + .btn,\n.btn-group > .btn:hover,\n.btn-group > .btn:focus,\n.btn-group > .btn:active,\n.btn-group > .btn.active,\n.btn-group-vertical > .btn-check:checked + .btn,\n.btn-group-vertical > .btn-check:focus + .btn,\n.btn-group-vertical > .btn:hover,\n.btn-group-vertical > .btn:focus,\n.btn-group-vertical > .btn:active,\n.btn-group-vertical > .btn.active {\n  z-index: 1;\n}\n\n.btn-toolbar {\n  display: flex;\n  flex-wrap: wrap;\n  justify-content: flex-start;\n}\n.btn-toolbar .input-group {\n  width: auto;\n}\n\n.btn-group > .btn:not(:first-child),\n.btn-group > .btn-group:not(:first-child) {\n  margin-right: -1px;\n}\n.btn-group > .btn:not(:last-child):not(.dropdown-toggle),\n.btn-group > .btn-group:not(:last-child) > .btn {\n  border-top-left-radius: 0;\n  border-bottom-left-radius: 0;\n}\n.btn-group > .btn:nth-child(n+3),\n.btn-group > :not(.btn-check) + .btn,\n.btn-group > .btn-group:not(:first-child) > .btn {\n  border-top-right-radius: 0;\n  border-bottom-right-radius: 0;\n}\n\n.dropdown-toggle-split {\n  padding-left: 0.5625rem;\n  padding-right: 0.5625rem;\n}\n.dropdown-toggle-split::after, .dropup .dropdown-toggle-split::after, .dropend .dropdown-toggle-split::after {\n  margin-right: 0;\n}\n.dropstart .dropdown-toggle-split::before {\n  margin-left: 0;\n}\n\n.btn-sm + .dropdown-toggle-split, .btn-group-sm > .btn + .dropdown-toggle-split {\n  padding-left: 0.375rem;\n  padding-right: 0.375rem;\n}\n\n.btn-lg + .dropdown-toggle-split, .btn-group-lg > .btn + .dropdown-toggle-split {\n  padding-left: 0.75rem;\n  padding-right: 0.75rem;\n}\n\n.btn-group-vertical {\n  flex-direction: column;\n  align-items: flex-start;\n  justify-content: center;\n}\n.btn-group-vertical > .btn,\n.btn-group-vertical > .btn-group {\n  width: 100%;\n}\n.btn-group-vertical > .btn:not(:first-child),\n.btn-group-vertical > .btn-group:not(:first-child) {\n  margin-top: -1px;\n}\n.btn-group-vertical > .btn:not(:last-child):not(.dropdown-toggle),\n.btn-group-vertical > .btn-group:not(:last-child) > .btn {\n  border-bottom-left-radius: 0;\n  border-bottom-right-radius: 0;\n}\n.btn-group-vertical > .btn ~ .btn,\n.btn-group-vertical > .btn-group:not(:first-child) > .btn {\n  border-top-right-radius: 0;\n  border-top-left-radius: 0;\n}\n\n.nav {\n  display: flex;\n  flex-wrap: wrap;\n  padding-right: 0;\n  margin-bottom: 0;\n  list-style: none;\n}\n\n.nav-link {\n  display: block;\n  padding: 0.5rem 1rem;\n  color: #0d6efd;\n  text-decoration: none;\n  transition: color 0.15s ease-in-out, background-color 0.15s ease-in-out, border-color 0.15s ease-in-out;\n}\n@media (prefers-reduced-motion: reduce) {\n  .nav-link {\n    transition: none;\n  }\n}\n.nav-link:hover, .nav-link:focus {\n  color: #0a58ca;\n}\n.nav-link.disabled {\n  color: #6c757d;\n  pointer-events: none;\n  cursor: default;\n}\n\n.nav-tabs {\n  border-bottom: 1px solid #dee2e6;\n}\n.nav-tabs .nav-link {\n  margin-bottom: -1px;\n  background: none;\n  border: 1px solid transparent;\n  border-top-right-radius: 0.25rem;\n  border-top-left-radius: 0.25rem;\n}\n.nav-tabs .nav-link:hover, .nav-tabs .nav-link:focus {\n  border-color: #e9ecef #e9ecef #dee2e6;\n  isolation: isolate;\n}\n.nav-tabs .nav-link.disabled {\n  color: #6c757d;\n  background-color: transparent;\n  border-color: transparent;\n}\n.nav-tabs .nav-link.active,\n.nav-tabs .nav-item.show .nav-link {\n  color: #495057;\n  background-color: #fff;\n  border-color: #dee2e6 #dee2e6 #fff;\n}\n.nav-tabs .dropdown-menu {\n  margin-top: -1px;\n  border-top-right-radius: 0;\n  border-top-left-radius: 0;\n}\n\n.nav-pills .nav-link {\n  background: none;\n  border: 0;\n  border-radius: 0.25rem;\n}\n.nav-pills .nav-link.active,\n.nav-pills .show > .nav-link {\n  color: #fff;\n  background-color: #0d6efd;\n}\n\n.nav-fill > .nav-link,\n.nav-fill .nav-item {\n  flex: 1 1 auto;\n  text-align: center;\n}\n\n.nav-justified > .nav-link,\n.nav-justified .nav-item {\n  flex-basis: 0;\n  flex-grow: 1;\n  text-align: center;\n}\n\n.nav-fill .nav-item .nav-link,\n.nav-justified .nav-item .nav-link {\n  width: 100%;\n}\n\n.tab-content > .tab-pane {\n  display: none;\n}\n.tab-content > .active {\n  display: block;\n}\n\n.navbar {\n  position: relative;\n  display: flex;\n  flex-wrap: wrap;\n  align-items: center;\n  justify-content: space-between;\n  padding-top: 0.5rem;\n  padding-bottom: 0.5rem;\n}\n.navbar > .container,\n.navbar > .container-fluid,\n.navbar > .container-sm,\n.navbar > .container-md,\n.navbar > .container-lg,\n.navbar > .container-xl,\n.navbar > .container-xxl {\n  display: flex;\n  flex-wrap: inherit;\n  align-items: center;\n  justify-content: space-between;\n}\n.navbar-brand {\n  padding-top: 0.3125rem;\n  padding-bottom: 0.3125rem;\n  margin-left: 1rem;\n  font-size: 1.25rem;\n  text-decoration: none;\n  white-space: nowrap;\n}\n.navbar-nav {\n  display: flex;\n  flex-direction: column;\n  padding-right: 0;\n  margin-bottom: 0;\n  list-style: none;\n}\n.navbar-nav .nav-link {\n  padding-left: 0;\n  padding-right: 0;\n}\n.navbar-nav .dropdown-menu {\n  position: static;\n}\n\n.navbar-text {\n  padding-top: 0.5rem;\n  padding-bottom: 0.5rem;\n}\n\n.navbar-collapse {\n  flex-basis: 100%;\n  flex-grow: 1;\n  align-items: center;\n}\n\n.navbar-toggler {\n  padding: 0.25rem 0.75rem;\n  font-size: 1.25rem;\n  line-height: 1;\n  background-color: transparent;\n  border: 1px solid transparent;\n  border-radius: 0.25rem;\n  transition: box-shadow 0.15s ease-in-out;\n}\n@media (prefers-reduced-motion: reduce) {\n  .navbar-toggler {\n    transition: none;\n  }\n}\n.navbar-toggler:hover {\n  text-decoration: none;\n}\n.navbar-toggler:focus {\n  text-decoration: none;\n  outline: 0;\n  box-shadow: 0 0 0 0.25rem;\n}\n\n.navbar-toggler-icon {\n  display: inline-block;\n  width: 1.5em;\n  height: 1.5em;\n  vertical-align: middle;\n  background-repeat: no-repeat;\n  background-position: center;\n  background-size: 100%;\n}\n\n.navbar-nav-scroll {\n  max-height: var(--bs-scroll-height, 75vh);\n  overflow-y: auto;\n}\n\n@media (min-width: 576px) {\n  .navbar-expand-sm {\n    flex-wrap: nowrap;\n    justify-content: flex-start;\n  }\n  .navbar-expand-sm .navbar-nav {\n    flex-direction: row;\n  }\n  .navbar-expand-sm .navbar-nav .dropdown-menu {\n    position: absolute;\n  }\n  .navbar-expand-sm .navbar-nav .nav-link {\n    padding-left: 0.5rem;\n    padding-right: 0.5rem;\n  }\n  .navbar-expand-sm .navbar-nav-scroll {\n    overflow: visible;\n  }\n  .navbar-expand-sm .navbar-collapse {\n    display: flex !important;\n    flex-basis: auto;\n  }\n  .navbar-expand-sm .navbar-toggler {\n    display: none;\n  }\n  .navbar-expand-sm .offcanvas-header {\n    display: none;\n  }\n  .navbar-expand-sm .offcanvas {\n    position: inherit;\n    bottom: 0;\n    z-index: 1000;\n    flex-grow: 1;\n    visibility: visible !important;\n    background-color: transparent;\n    border-left: 0;\n    border-right: 0;\n    transition: none;\n    transform: none;\n  }\n  .navbar-expand-sm .offcanvas-top,\n.navbar-expand-sm .offcanvas-bottom {\n    height: auto;\n    border-top: 0;\n    border-bottom: 0;\n  }\n  .navbar-expand-sm .offcanvas-body {\n    display: flex;\n    flex-grow: 0;\n    padding: 0;\n    overflow-y: visible;\n  }\n}\n@media (min-width: 768px) {\n  .navbar-expand-md {\n    flex-wrap: nowrap;\n    justify-content: flex-start;\n  }\n  .navbar-expand-md .navbar-nav {\n    flex-direction: row;\n  }\n  .navbar-expand-md .navbar-nav .dropdown-menu {\n    position: absolute;\n  }\n  .navbar-expand-md .navbar-nav .nav-link {\n    padding-left: 0.5rem;\n    padding-right: 0.5rem;\n  }\n  .navbar-expand-md .navbar-nav-scroll {\n    overflow: visible;\n  }\n  .navbar-expand-md .navbar-collapse {\n    display: flex !important;\n    flex-basis: auto;\n  }\n  .navbar-expand-md .navbar-toggler {\n    display: none;\n  }\n  .navbar-expand-md .offcanvas-header {\n    display: none;\n  }\n  .navbar-expand-md .offcanvas {\n    position: inherit;\n    bottom: 0;\n    z-index: 1000;\n    flex-grow: 1;\n    visibility: visible !important;\n    background-color: transparent;\n    border-left: 0;\n    border-right: 0;\n    transition: none;\n    transform: none;\n  }\n  .navbar-expand-md .offcanvas-top,\n.navbar-expand-md .offcanvas-bottom {\n    height: auto;\n    border-top: 0;\n    border-bottom: 0;\n  }\n  .navbar-expand-md .offcanvas-body {\n    display: flex;\n    flex-grow: 0;\n    padding: 0;\n    overflow-y: visible;\n  }\n}\n@media (min-width: 992px) {\n  .navbar-expand-lg {\n    flex-wrap: nowrap;\n    justify-content: flex-start;\n  }\n  .navbar-expand-lg .navbar-nav {\n    flex-direction: row;\n  }\n  .navbar-expand-lg .navbar-nav .dropdown-menu {\n    position: absolute;\n  }\n  .navbar-expand-lg .navbar-nav .nav-link {\n    padding-left: 0.5rem;\n    padding-right: 0.5rem;\n  }\n  .navbar-expand-lg .navbar-nav-scroll {\n    overflow: visible;\n  }\n  .navbar-expand-lg .navbar-collapse {\n    display: flex !important;\n    flex-basis: auto;\n  }\n  .navbar-expand-lg .navbar-toggler {\n    display: none;\n  }\n  .navbar-expand-lg .offcanvas-header {\n    display: none;\n  }\n  .navbar-expand-lg .offcanvas {\n    position: inherit;\n    bottom: 0;\n    z-index: 1000;\n    flex-grow: 1;\n    visibility: visible !important;\n    background-color: transparent;\n    border-left: 0;\n    border-right: 0;\n    transition: none;\n    transform: none;\n  }\n  .navbar-expand-lg .offcanvas-top,\n.navbar-expand-lg .offcanvas-bottom {\n    height: auto;\n    border-top: 0;\n    border-bottom: 0;\n  }\n  .navbar-expand-lg .offcanvas-body {\n    display: flex;\n    flex-grow: 0;\n    padding: 0;\n    overflow-y: visible;\n  }\n}\n@media (min-width: 1200px) {\n  .navbar-expand-xl {\n    flex-wrap: nowrap;\n    justify-content: flex-start;\n  }\n  .navbar-expand-xl .navbar-nav {\n    flex-direction: row;\n  }\n  .navbar-expand-xl .navbar-nav .dropdown-menu {\n    position: absolute;\n  }\n  .navbar-expand-xl .navbar-nav .nav-link {\n    padding-left: 0.5rem;\n    padding-right: 0.5rem;\n  }\n  .navbar-expand-xl .navbar-nav-scroll {\n    overflow: visible;\n  }\n  .navbar-expand-xl .navbar-collapse {\n    display: flex !important;\n    flex-basis: auto;\n  }\n  .navbar-expand-xl .navbar-toggler {\n    display: none;\n  }\n  .navbar-expand-xl .offcanvas-header {\n    display: none;\n  }\n  .navbar-expand-xl .offcanvas {\n    position: inherit;\n    bottom: 0;\n    z-index: 1000;\n    flex-grow: 1;\n    visibility: visible !important;\n    background-color: transparent;\n    border-left: 0;\n    border-right: 0;\n    transition: none;\n    transform: none;\n  }\n  .navbar-expand-xl .offcanvas-top,\n.navbar-expand-xl .offcanvas-bottom {\n    height: auto;\n    border-top: 0;\n    border-bottom: 0;\n  }\n  .navbar-expand-xl .offcanvas-body {\n    display: flex;\n    flex-grow: 0;\n    padding: 0;\n    overflow-y: visible;\n  }\n}\n@media (min-width: 1400px) {\n  .navbar-expand-xxl {\n    flex-wrap: nowrap;\n    justify-content: flex-start;\n  }\n  .navbar-expand-xxl .navbar-nav {\n    flex-direction: row;\n  }\n  .navbar-expand-xxl .navbar-nav .dropdown-menu {\n    position: absolute;\n  }\n  .navbar-expand-xxl .navbar-nav .nav-link {\n    padding-left: 0.5rem;\n    padding-right: 0.5rem;\n  }\n  .navbar-expand-xxl .navbar-nav-scroll {\n    overflow: visible;\n  }\n  .navbar-expand-xxl .navbar-collapse {\n    display: flex !important;\n    flex-basis: auto;\n  }\n  .navbar-expand-xxl .navbar-toggler {\n    display: none;\n  }\n  .navbar-expand-xxl .offcanvas-header {\n    display: none;\n  }\n  .navbar-expand-xxl .offcanvas {\n    position: inherit;\n    bottom: 0;\n    z-index: 1000;\n    flex-grow: 1;\n    visibility: visible !important;\n    background-color: transparent;\n    border-left: 0;\n    border-right: 0;\n    transition: none;\n    transform: none;\n  }\n  .navbar-expand-xxl .offcanvas-top,\n.navbar-expand-xxl .offcanvas-bottom {\n    height: auto;\n    border-top: 0;\n    border-bottom: 0;\n  }\n  .navbar-expand-xxl .offcanvas-body {\n    display: flex;\n    flex-grow: 0;\n    padding: 0;\n    overflow-y: visible;\n  }\n}\n.navbar-expand {\n  flex-wrap: nowrap;\n  justify-content: flex-start;\n}\n.navbar-expand .navbar-nav {\n  flex-direction: row;\n}\n.navbar-expand .navbar-nav .dropdown-menu {\n  position: absolute;\n}\n.navbar-expand .navbar-nav .nav-link {\n  padding-left: 0.5rem;\n  padding-right: 0.5rem;\n}\n.navbar-expand .navbar-nav-scroll {\n  overflow: visible;\n}\n.navbar-expand .navbar-collapse {\n  display: flex !important;\n  flex-basis: auto;\n}\n.navbar-expand .navbar-toggler {\n  display: none;\n}\n.navbar-expand .offcanvas-header {\n  display: none;\n}\n.navbar-expand .offcanvas {\n  position: inherit;\n  bottom: 0;\n  z-index: 1000;\n  flex-grow: 1;\n  visibility: visible !important;\n  background-color: transparent;\n  border-left: 0;\n  border-right: 0;\n  transition: none;\n  transform: none;\n}\n.navbar-expand .offcanvas-top,\n.navbar-expand .offcanvas-bottom {\n  height: auto;\n  border-top: 0;\n  border-bottom: 0;\n}\n.navbar-expand .offcanvas-body {\n  display: flex;\n  flex-grow: 0;\n  padding: 0;\n  overflow-y: visible;\n}\n\n.navbar-light .navbar-brand {\n  color: rgba(0, 0, 0, 0.9);\n}\n.navbar-light .navbar-brand:hover, .navbar-light .navbar-brand:focus {\n  color: rgba(0, 0, 0, 0.9);\n}\n.navbar-light .navbar-nav .nav-link {\n  color: rgba(0, 0, 0, 0.55);\n}\n.navbar-light .navbar-nav .nav-link:hover, .navbar-light .navbar-nav .nav-link:focus {\n  color: rgba(0, 0, 0, 0.7);\n}\n.navbar-light .navbar-nav .nav-link.disabled {\n  color: rgba(0, 0, 0, 0.3);\n}\n.navbar-light .navbar-nav .show > .nav-link,\n.navbar-light .navbar-nav .nav-link.active {\n  color: rgba(0, 0, 0, 0.9);\n}\n.navbar-light .navbar-toggler {\n  color: rgba(0, 0, 0, 0.55);\n  border-color: rgba(0, 0, 0, 0.1);\n}\n.navbar-light .navbar-toggler-icon {\n  background-image: url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 30 30'%3e%3cpath stroke='rgba%280, 0, 0, 0.55%29' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e\");\n}\n.navbar-light .navbar-text {\n  color: rgba(0, 0, 0, 0.55);\n}\n.navbar-light .navbar-text a,\n.navbar-light .navbar-text a:hover,\n.navbar-light .navbar-text a:focus {\n  color: rgba(0, 0, 0, 0.9);\n}\n\n.navbar-dark .navbar-brand {\n  color: #fff;\n}\n.navbar-dark .navbar-brand:hover, .navbar-dark .navbar-brand:focus {\n  color: #fff;\n}\n.navbar-dark .navbar-nav .nav-link {\n  color: rgba(255, 255, 255, 0.55);\n}\n.navbar-dark .navbar-nav .nav-link:hover, .navbar-dark .navbar-nav .nav-link:focus {\n  color: rgba(255, 255, 255, 0.75);\n}\n.navbar-dark .navbar-nav .nav-link.disabled {\n  color: rgba(255, 255, 255, 0.25);\n}\n.navbar-dark .navbar-nav .show > .nav-link,\n.navbar-dark .navbar-nav .nav-link.active {\n  color: #fff;\n}\n.navbar-dark .navbar-toggler {\n  color: rgba(255, 255, 255, 0.55);\n  border-color: rgba(255, 255, 255, 0.1);\n}\n.navbar-dark .navbar-toggler-icon {\n  background-image: 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\");\n}\n.navbar-dark .navbar-text {\n  color: rgba(255, 255, 255, 0.55);\n}\n.navbar-dark .navbar-text a,\n.navbar-dark .navbar-text a:hover,\n.navbar-dark .navbar-text a:focus {\n  color: #fff;\n}\n\n.card {\n  position: relative;\n  display: flex;\n  flex-direction: column;\n  min-width: 0;\n  word-wrap: break-word;\n  background-color: #fff;\n  background-clip: border-box;\n  border: 1px solid rgba(0, 0, 0, 0.125);\n  border-radius: 0.25rem;\n}\n.card > hr {\n  margin-left: 0;\n  margin-right: 0;\n}\n.card > .list-group {\n  border-top: inherit;\n  border-bottom: inherit;\n}\n.card > .list-group:first-child {\n  border-top-width: 0;\n  border-top-right-radius: calc(0.25rem - 1px);\n  border-top-left-radius: calc(0.25rem - 1px);\n}\n.card > .list-group:last-child {\n  border-bottom-width: 0;\n  border-bottom-left-radius: calc(0.25rem - 1px);\n  border-bottom-right-radius: calc(0.25rem - 1px);\n}\n.card > .card-header + .list-group,\n.card > .list-group + .card-footer {\n  border-top: 0;\n}\n\n.card-body {\n  flex: 1 1 auto;\n  padding: 1rem 1rem;\n}\n\n.card-title {\n  margin-bottom: 0.5rem;\n}\n\n.card-subtitle {\n  margin-top: -0.25rem;\n  margin-bottom: 0;\n}\n\n.card-text:last-child {\n  margin-bottom: 0;\n}\n\n.card-link + .card-link {\n  margin-right: 1rem;\n}\n\n.card-header {\n  padding: 0.5rem 1rem;\n  margin-bottom: 0;\n  background-color: rgba(0, 0, 0, 0.03);\n  border-bottom: 1px solid rgba(0, 0, 0, 0.125);\n}\n.card-header:first-child {\n  border-radius: calc(0.25rem - 1px) calc(0.25rem - 1px) 0 0;\n}\n\n.card-footer {\n  padding: 0.5rem 1rem;\n  background-color: rgba(0, 0, 0, 0.03);\n  border-top: 1px solid rgba(0, 0, 0, 0.125);\n}\n.card-footer:last-child {\n  border-radius: 0 0 calc(0.25rem - 1px) calc(0.25rem - 1px);\n}\n\n.card-header-tabs {\n  margin-left: -0.5rem;\n  margin-bottom: -0.5rem;\n  margin-right: -0.5rem;\n  border-bottom: 0;\n}\n\n.card-header-pills {\n  margin-left: -0.5rem;\n  margin-right: -0.5rem;\n}\n\n.card-img-overlay {\n  position: absolute;\n  top: 0;\n  left: 0;\n  bottom: 0;\n  right: 0;\n  padding: 1rem;\n  border-radius: calc(0.25rem - 1px);\n}\n\n.card-img,\n.card-img-top,\n.card-img-bottom {\n  width: 100%;\n}\n\n.card-img,\n.card-img-top {\n  border-top-right-radius: calc(0.25rem - 1px);\n  border-top-left-radius: calc(0.25rem - 1px);\n}\n\n.card-img,\n.card-img-bottom {\n  border-bottom-left-radius: calc(0.25rem - 1px);\n  border-bottom-right-radius: calc(0.25rem - 1px);\n}\n\n.card-group > .card {\n  margin-bottom: 0.75rem;\n}\n@media (min-width: 576px) {\n  .card-group {\n    display: flex;\n    flex-flow: row wrap;\n  }\n  .card-group > .card {\n    flex: 1 0 0%;\n    margin-bottom: 0;\n  }\n  .card-group > .card + .card {\n    margin-right: 0;\n    border-right: 0;\n  }\n  .card-group > .card:not(:last-child) {\n    border-top-left-radius: 0;\n    border-bottom-left-radius: 0;\n  }\n  .card-group > .card:not(:last-child) .card-img-top,\n.card-group > .card:not(:last-child) .card-header {\n    border-top-left-radius: 0;\n  }\n  .card-group > .card:not(:last-child) .card-img-bottom,\n.card-group > .card:not(:last-child) .card-footer {\n    border-bottom-left-radius: 0;\n  }\n  .card-group > .card:not(:first-child) {\n    border-top-right-radius: 0;\n    border-bottom-right-radius: 0;\n  }\n  .card-group > .card:not(:first-child) .card-img-top,\n.card-group > .card:not(:first-child) .card-header {\n    border-top-right-radius: 0;\n  }\n  .card-group > .card:not(:first-child) .card-img-bottom,\n.card-group > .card:not(:first-child) .card-footer {\n    border-bottom-right-radius: 0;\n  }\n}\n\n.accordion-button {\n  position: relative;\n  display: flex;\n  align-items: center;\n  width: 100%;\n  padding: 1rem 1.25rem;\n  font-size: 1rem;\n  color: #212529;\n  text-align: right;\n  background-color: #fff;\n  border: 0;\n  border-radius: 0;\n  overflow-anchor: none;\n  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;\n}\n@media (prefers-reduced-motion: reduce) {\n  .accordion-button {\n    transition: none;\n  }\n}\n.accordion-button:not(.collapsed) {\n  color: #0c63e4;\n  background-color: #e7f1ff;\n  box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.125);\n}\n.accordion-button:not(.collapsed)::after {\n  background-image: url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%230c63e4'%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-.708z'/%3e%3c/svg%3e\");\n  transform: rotate(180deg);\n}\n.accordion-button::after {\n  flex-shrink: 0;\n  width: 1.25rem;\n  height: 1.25rem;\n  margin-right: auto;\n  content: \"\";\n  background-image: url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23212529'%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-.708z'/%3e%3c/svg%3e\");\n  background-repeat: no-repeat;\n  background-size: 1.25rem;\n  transition: transform 0.2s ease-in-out;\n}\n@media (prefers-reduced-motion: reduce) {\n  .accordion-button::after {\n    transition: none;\n  }\n}\n.accordion-button:hover {\n  z-index: 2;\n}\n.accordion-button:focus {\n  z-index: 3;\n  border-color: #86b7fe;\n  outline: 0;\n  box-shadow: 0 0 0 0.25rem rgba(13, 110, 253, 0.25);\n}\n\n.accordion-header {\n  margin-bottom: 0;\n}\n\n.accordion-item {\n  background-color: #fff;\n  border: 1px solid rgba(0, 0, 0, 0.125);\n}\n.accordion-item:first-of-type {\n  border-top-right-radius: 0.25rem;\n  border-top-left-radius: 0.25rem;\n}\n.accordion-item:first-of-type .accordion-button {\n  border-top-right-radius: calc(0.25rem - 1px);\n  border-top-left-radius: calc(0.25rem - 1px);\n}\n.accordion-item:not(:first-of-type) {\n  border-top: 0;\n}\n.accordion-item:last-of-type {\n  border-bottom-left-radius: 0.25rem;\n  border-bottom-right-radius: 0.25rem;\n}\n.accordion-item:last-of-type .accordion-button.collapsed {\n  border-bottom-left-radius: calc(0.25rem - 1px);\n  border-bottom-right-radius: calc(0.25rem - 1px);\n}\n.accordion-item:last-of-type .accordion-collapse {\n  border-bottom-left-radius: 0.25rem;\n  border-bottom-right-radius: 0.25rem;\n}\n\n.accordion-body {\n  padding: 1rem 1.25rem;\n}\n\n.accordion-flush .accordion-collapse {\n  border-width: 0;\n}\n.accordion-flush .accordion-item {\n  border-left: 0;\n  border-right: 0;\n  border-radius: 0;\n}\n.accordion-flush .accordion-item:first-child {\n  border-top: 0;\n}\n.accordion-flush .accordion-item:last-child {\n  border-bottom: 0;\n}\n.accordion-flush .accordion-item .accordion-button {\n  border-radius: 0;\n}\n\n.breadcrumb {\n  display: flex;\n  flex-wrap: wrap;\n  padding: 0 0;\n  margin-bottom: 1rem;\n  list-style: none;\n}\n\n.breadcrumb-item + .breadcrumb-item {\n  padding-right: 0.5rem;\n}\n.breadcrumb-item + .breadcrumb-item::before {\n  float: right;\n  padding-left: 0.5rem;\n  color: #6c757d;\n  content:  var(--bs-breadcrumb-divider, \"/\") ;\n}\n.breadcrumb-item.active {\n  color: #6c757d;\n}\n\n.pagination {\n  display: flex;\n  padding-right: 0;\n  list-style: none;\n}\n\n.page-link {\n  position: relative;\n  display: block;\n  color: #0d6efd;\n  text-decoration: none;\n  background-color: #fff;\n  border: 1px solid #dee2e6;\n  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;\n}\n@media (prefers-reduced-motion: reduce) {\n  .page-link {\n    transition: none;\n  }\n}\n.page-link:hover {\n  z-index: 2;\n  color: #0a58ca;\n  background-color: #e9ecef;\n  border-color: #dee2e6;\n}\n.page-link:focus {\n  z-index: 3;\n  color: #0a58ca;\n  background-color: #e9ecef;\n  outline: 0;\n  box-shadow: 0 0 0 0.25rem rgba(13, 110, 253, 0.25);\n}\n\n.page-item:not(:first-child) .page-link {\n  margin-right: -1px;\n}\n.page-item.active .page-link {\n  z-index: 3;\n  color: #fff;\n  background-color: #0d6efd;\n  border-color: #0d6efd;\n}\n.page-item.disabled .page-link {\n  color: #6c757d;\n  pointer-events: none;\n  background-color: #fff;\n  border-color: #dee2e6;\n}\n\n.page-link {\n  padding: 0.375rem 0.75rem;\n}\n\n.page-item:first-child .page-link {\n  border-top-right-radius: 0.25rem;\n  border-bottom-right-radius: 0.25rem;\n}\n.page-item:last-child .page-link {\n  border-top-left-radius: 0.25rem;\n  border-bottom-left-radius: 0.25rem;\n}\n\n.pagination-lg .page-link {\n  padding: 0.75rem 1.5rem;\n  font-size: 1.25rem;\n}\n.pagination-lg .page-item:first-child .page-link {\n  border-top-right-radius: 0.3rem;\n  border-bottom-right-radius: 0.3rem;\n}\n.pagination-lg .page-item:last-child .page-link {\n  border-top-left-radius: 0.3rem;\n  border-bottom-left-radius: 0.3rem;\n}\n\n.pagination-sm .page-link {\n  padding: 0.25rem 0.5rem;\n  font-size: 0.875rem;\n}\n.pagination-sm .page-item:first-child .page-link {\n  border-top-right-radius: 0.2rem;\n  border-bottom-right-radius: 0.2rem;\n}\n.pagination-sm .page-item:last-child .page-link {\n  border-top-left-radius: 0.2rem;\n  border-bottom-left-radius: 0.2rem;\n}\n\n.badge {\n  display: inline-block;\n  padding: 0.35em 0.65em;\n  font-size: 0.75em;\n  font-weight: 700;\n  line-height: 1;\n  color: #fff;\n  text-align: center;\n  white-space: nowrap;\n  vertical-align: baseline;\n  border-radius: 0.25rem;\n}\n.badge:empty {\n  display: none;\n}\n\n.btn .badge {\n  position: relative;\n  top: -1px;\n}\n\n.alert {\n  position: relative;\n  padding: 1rem 1rem;\n  margin-bottom: 1rem;\n  border: 1px solid transparent;\n  border-radius: 0.25rem;\n}\n\n.alert-heading {\n  color: inherit;\n}\n\n.alert-link {\n  font-weight: 700;\n}\n\n.alert-dismissible {\n  padding-left: 3rem;\n}\n.alert-dismissible .btn-close {\n  position: absolute;\n  top: 0;\n  left: 0;\n  z-index: 2;\n  padding: 1.25rem 1rem;\n}\n\n.alert-primary {\n  color: #084298;\n  background-color: #cfe2ff;\n  border-color: #b6d4fe;\n}\n.alert-primary .alert-link {\n  color: #06357a;\n}\n\n.alert-secondary {\n  color: #41464b;\n  background-color: #e2e3e5;\n  border-color: #d3d6d8;\n}\n.alert-secondary .alert-link {\n  color: #34383c;\n}\n\n.alert-success {\n  color: #0f5132;\n  background-color: #d1e7dd;\n  border-color: #badbcc;\n}\n.alert-success .alert-link {\n  color: #0c4128;\n}\n\n.alert-info {\n  color: #055160;\n  background-color: #cff4fc;\n  border-color: #b6effb;\n}\n.alert-info .alert-link {\n  color: #04414d;\n}\n\n.alert-warning {\n  color: #664d03;\n  background-color: #fff3cd;\n  border-color: #ffecb5;\n}\n.alert-warning .alert-link {\n  color: #523e02;\n}\n\n.alert-danger {\n  color: #842029;\n  background-color: #f8d7da;\n  border-color: #f5c2c7;\n}\n.alert-danger .alert-link {\n  color: #6a1a21;\n}\n\n.alert-light {\n  color: #636464;\n  background-color: #fefefe;\n  border-color: #fdfdfe;\n}\n.alert-light .alert-link {\n  color: #4f5050;\n}\n\n.alert-dark {\n  color: #141619;\n  background-color: #d3d3d4;\n  border-color: #bcbebf;\n}\n.alert-dark .alert-link {\n  color: #101214;\n}\n\n@-webkit-keyframes progress-bar-stripes {\n  0% {\n    background-position-x: 1rem;\n  }\n}\n\n@keyframes progress-bar-stripes {\n  0% {\n    background-position-x: 1rem;\n  }\n}\n.progress {\n  display: flex;\n  height: 1rem;\n  overflow: hidden;\n  font-size: 0.75rem;\n  background-color: #e9ecef;\n  border-radius: 0.25rem;\n}\n\n.progress-bar {\n  display: flex;\n  flex-direction: column;\n  justify-content: center;\n  overflow: hidden;\n  color: #fff;\n  text-align: center;\n  white-space: nowrap;\n  background-color: #0d6efd;\n  transition: width 0.6s ease;\n}\n@media (prefers-reduced-motion: reduce) {\n  .progress-bar {\n    transition: none;\n  }\n}\n\n.progress-bar-striped {\n  background-image: linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n  background-size: 1rem 1rem;\n}\n\n.progress-bar-animated {\n  -webkit-animation: 1s linear infinite progress-bar-stripes;\n  animation: 1s linear infinite progress-bar-stripes;\n}\n@media (prefers-reduced-motion: reduce) {\n  .progress-bar-animated {\n    -webkit-animation: none;\n    animation: none;\n  }\n}\n\n.list-group {\n  display: flex;\n  flex-direction: column;\n  padding-right: 0;\n  margin-bottom: 0;\n  border-radius: 0.25rem;\n}\n\n.list-group-numbered {\n  list-style-type: none;\n  counter-reset: section;\n}\n.list-group-numbered > li::before {\n  content: counters(section, \".\") \". \";\n  counter-increment: section;\n}\n\n.list-group-item-action {\n  width: 100%;\n  color: #495057;\n  text-align: inherit;\n}\n.list-group-item-action:hover, .list-group-item-action:focus {\n  z-index: 1;\n  color: #495057;\n  text-decoration: none;\n  background-color: #f8f9fa;\n}\n.list-group-item-action:active {\n  color: #212529;\n  background-color: #e9ecef;\n}\n\n.list-group-item {\n  position: relative;\n  display: block;\n  padding: 0.5rem 1rem;\n  color: #212529;\n  text-decoration: none;\n  background-color: #fff;\n  border: 1px solid rgba(0, 0, 0, 0.125);\n}\n.list-group-item:first-child {\n  border-top-right-radius: inherit;\n  border-top-left-radius: inherit;\n}\n.list-group-item:last-child {\n  border-bottom-left-radius: inherit;\n  border-bottom-right-radius: inherit;\n}\n.list-group-item.disabled, .list-group-item:disabled {\n  color: #6c757d;\n  pointer-events: none;\n  background-color: #fff;\n}\n.list-group-item.active {\n  z-index: 2;\n  color: #fff;\n  background-color: #0d6efd;\n  border-color: #0d6efd;\n}\n.list-group-item + .list-group-item {\n  border-top-width: 0;\n}\n.list-group-item + .list-group-item.active {\n  margin-top: -1px;\n  border-top-width: 1px;\n}\n\n.list-group-horizontal {\n  flex-direction: row;\n}\n.list-group-horizontal > .list-group-item:first-child {\n  border-bottom-right-radius: 0.25rem;\n  border-top-left-radius: 0;\n}\n.list-group-horizontal > .list-group-item:last-child {\n  border-top-left-radius: 0.25rem;\n  border-bottom-right-radius: 0;\n}\n.list-group-horizontal > .list-group-item.active {\n  margin-top: 0;\n}\n.list-group-horizontal > .list-group-item + .list-group-item {\n  border-top-width: 1px;\n  border-right-width: 0;\n}\n.list-group-horizontal > .list-group-item + .list-group-item.active {\n  margin-right: -1px;\n  border-right-width: 1px;\n}\n\n@media (min-width: 576px) {\n  .list-group-horizontal-sm {\n    flex-direction: row;\n  }\n  .list-group-horizontal-sm > .list-group-item:first-child {\n    border-bottom-right-radius: 0.25rem;\n    border-top-left-radius: 0;\n  }\n  .list-group-horizontal-sm > .list-group-item:last-child {\n    border-top-left-radius: 0.25rem;\n    border-bottom-right-radius: 0;\n  }\n  .list-group-horizontal-sm > .list-group-item.active {\n    margin-top: 0;\n  }\n  .list-group-horizontal-sm > .list-group-item + .list-group-item {\n    border-top-width: 1px;\n    border-right-width: 0;\n  }\n  .list-group-horizontal-sm > .list-group-item + .list-group-item.active {\n    margin-right: -1px;\n    border-right-width: 1px;\n  }\n}\n@media (min-width: 768px) {\n  .list-group-horizontal-md {\n    flex-direction: row;\n  }\n  .list-group-horizontal-md > .list-group-item:first-child {\n    border-bottom-right-radius: 0.25rem;\n    border-top-left-radius: 0;\n  }\n  .list-group-horizontal-md > .list-group-item:last-child {\n    border-top-left-radius: 0.25rem;\n    border-bottom-right-radius: 0;\n  }\n  .list-group-horizontal-md > .list-group-item.active {\n    margin-top: 0;\n  }\n  .list-group-horizontal-md > .list-group-item + .list-group-item {\n    border-top-width: 1px;\n    border-right-width: 0;\n  }\n  .list-group-horizontal-md > .list-group-item + .list-group-item.active {\n    margin-right: -1px;\n    border-right-width: 1px;\n  }\n}\n@media (min-width: 992px) {\n  .list-group-horizontal-lg {\n    flex-direction: row;\n  }\n  .list-group-horizontal-lg > .list-group-item:first-child {\n    border-bottom-right-radius: 0.25rem;\n    border-top-left-radius: 0;\n  }\n  .list-group-horizontal-lg > .list-group-item:last-child {\n    border-top-left-radius: 0.25rem;\n    border-bottom-right-radius: 0;\n  }\n  .list-group-horizontal-lg > .list-group-item.active {\n    margin-top: 0;\n  }\n  .list-group-horizontal-lg > .list-group-item + .list-group-item {\n    border-top-width: 1px;\n    border-right-width: 0;\n  }\n  .list-group-horizontal-lg > .list-group-item + .list-group-item.active {\n    margin-right: -1px;\n    border-right-width: 1px;\n  }\n}\n@media (min-width: 1200px) {\n  .list-group-horizontal-xl {\n    flex-direction: row;\n  }\n  .list-group-horizontal-xl > .list-group-item:first-child {\n    border-bottom-right-radius: 0.25rem;\n    border-top-left-radius: 0;\n  }\n  .list-group-horizontal-xl > .list-group-item:last-child {\n    border-top-left-radius: 0.25rem;\n    border-bottom-right-radius: 0;\n  }\n  .list-group-horizontal-xl > .list-group-item.active {\n    margin-top: 0;\n  }\n  .list-group-horizontal-xl > .list-group-item + .list-group-item {\n    border-top-width: 1px;\n    border-right-width: 0;\n  }\n  .list-group-horizontal-xl > .list-group-item + .list-group-item.active {\n    margin-right: -1px;\n    border-right-width: 1px;\n  }\n}\n@media (min-width: 1400px) {\n  .list-group-horizontal-xxl {\n    flex-direction: row;\n  }\n  .list-group-horizontal-xxl > .list-group-item:first-child {\n    border-bottom-right-radius: 0.25rem;\n    border-top-left-radius: 0;\n  }\n  .list-group-horizontal-xxl > .list-group-item:last-child {\n    border-top-left-radius: 0.25rem;\n    border-bottom-right-radius: 0;\n  }\n  .list-group-horizontal-xxl > .list-group-item.active {\n    margin-top: 0;\n  }\n  .list-group-horizontal-xxl > .list-group-item + .list-group-item {\n    border-top-width: 1px;\n    border-right-width: 0;\n  }\n  .list-group-horizontal-xxl > .list-group-item + .list-group-item.active {\n    margin-right: -1px;\n    border-right-width: 1px;\n  }\n}\n.list-group-flush {\n  border-radius: 0;\n}\n.list-group-flush > .list-group-item {\n  border-width: 0 0 1px;\n}\n.list-group-flush > .list-group-item:last-child {\n  border-bottom-width: 0;\n}\n\n.list-group-item-primary {\n  color: #084298;\n  background-color: #cfe2ff;\n}\n.list-group-item-primary.list-group-item-action:hover, .list-group-item-primary.list-group-item-action:focus {\n  color: #084298;\n  background-color: #bacbe6;\n}\n.list-group-item-primary.list-group-item-action.active {\n  color: #fff;\n  background-color: #084298;\n  border-color: #084298;\n}\n\n.list-group-item-secondary {\n  color: #41464b;\n  background-color: #e2e3e5;\n}\n.list-group-item-secondary.list-group-item-action:hover, .list-group-item-secondary.list-group-item-action:focus {\n  color: #41464b;\n  background-color: #cbccce;\n}\n.list-group-item-secondary.list-group-item-action.active {\n  color: #fff;\n  background-color: #41464b;\n  border-color: #41464b;\n}\n\n.list-group-item-success {\n  color: #0f5132;\n  background-color: #d1e7dd;\n}\n.list-group-item-success.list-group-item-action:hover, .list-group-item-success.list-group-item-action:focus {\n  color: #0f5132;\n  background-color: #bcd0c7;\n}\n.list-group-item-success.list-group-item-action.active {\n  color: #fff;\n  background-color: #0f5132;\n  border-color: #0f5132;\n}\n\n.list-group-item-info {\n  color: #055160;\n  background-color: #cff4fc;\n}\n.list-group-item-info.list-group-item-action:hover, .list-group-item-info.list-group-item-action:focus {\n  color: #055160;\n  background-color: #badce3;\n}\n.list-group-item-info.list-group-item-action.active {\n  color: #fff;\n  background-color: #055160;\n  border-color: #055160;\n}\n\n.list-group-item-warning {\n  color: #664d03;\n  background-color: #fff3cd;\n}\n.list-group-item-warning.list-group-item-action:hover, .list-group-item-warning.list-group-item-action:focus {\n  color: #664d03;\n  background-color: #e6dbb9;\n}\n.list-group-item-warning.list-group-item-action.active {\n  color: #fff;\n  background-color: #664d03;\n  border-color: #664d03;\n}\n\n.list-group-item-danger {\n  color: #842029;\n  background-color: #f8d7da;\n}\n.list-group-item-danger.list-group-item-action:hover, .list-group-item-danger.list-group-item-action:focus {\n  color: #842029;\n  background-color: #dfc2c4;\n}\n.list-group-item-danger.list-group-item-action.active {\n  color: #fff;\n  background-color: #842029;\n  border-color: #842029;\n}\n\n.list-group-item-light {\n  color: #636464;\n  background-color: #fefefe;\n}\n.list-group-item-light.list-group-item-action:hover, .list-group-item-light.list-group-item-action:focus {\n  color: #636464;\n  background-color: #e5e5e5;\n}\n.list-group-item-light.list-group-item-action.active {\n  color: #fff;\n  background-color: #636464;\n  border-color: #636464;\n}\n\n.list-group-item-dark {\n  color: #141619;\n  background-color: #d3d3d4;\n}\n.list-group-item-dark.list-group-item-action:hover, .list-group-item-dark.list-group-item-action:focus {\n  color: #141619;\n  background-color: #bebebf;\n}\n.list-group-item-dark.list-group-item-action.active {\n  color: #fff;\n  background-color: #141619;\n  border-color: #141619;\n}\n\n.btn-close {\n  box-sizing: content-box;\n  width: 1em;\n  height: 1em;\n  padding: 0.25em 0.25em;\n  color: #000;\n  background: transparent 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 011.414 0L8 6.586 14.293.293a1 1 0 111.414 1.414L9.414 8l6.293 6.293a1 1 0 01-1.414 1.414L8 9.414l-6.293 6.293a1 1 0 01-1.414-1.414L6.586 8 .293 1.707a1 1 0 010-1.414z'/%3e%3c/svg%3e\") center/1em auto no-repeat;\n  border: 0;\n  border-radius: 0.25rem;\n  opacity: 0.5;\n}\n.btn-close:hover {\n  color: #000;\n  text-decoration: none;\n  opacity: 0.75;\n}\n.btn-close:focus {\n  outline: 0;\n  box-shadow: 0 0 0 0.25rem rgba(13, 110, 253, 0.25);\n  opacity: 1;\n}\n.btn-close:disabled, .btn-close.disabled {\n  pointer-events: none;\n  -webkit-user-select: none;\n  -moz-user-select: none;\n  user-select: none;\n  opacity: 0.25;\n}\n\n.btn-close-white {\n  filter: invert(1) grayscale(100%) brightness(200%);\n}\n\n.toast {\n  width: 350px;\n  max-width: 100%;\n  font-size: 0.875rem;\n  pointer-events: auto;\n  background-color: rgba(255, 255, 255, 0.85);\n  background-clip: padding-box;\n  border: 1px solid rgba(0, 0, 0, 0.1);\n  box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.15);\n  border-radius: 0.25rem;\n}\n.toast.showing {\n  opacity: 0;\n}\n.toast:not(.show) {\n  display: none;\n}\n\n.toast-container {\n  width: -webkit-max-content;\n  width: -moz-max-content;\n  width: max-content;\n  max-width: 100%;\n  pointer-events: none;\n}\n.toast-container > :not(:last-child) {\n  margin-bottom: 0.75rem;\n}\n\n.toast-header {\n  display: flex;\n  align-items: center;\n  padding: 0.5rem 0.75rem;\n  color: #6c757d;\n  background-color: rgba(255, 255, 255, 0.85);\n  background-clip: padding-box;\n  border-bottom: 1px solid rgba(0, 0, 0, 0.05);\n  border-top-right-radius: calc(0.25rem - 1px);\n  border-top-left-radius: calc(0.25rem - 1px);\n}\n.toast-header .btn-close {\n  margin-left: -0.375rem;\n  margin-right: 0.75rem;\n}\n\n.toast-body {\n  padding: 0.75rem;\n  word-wrap: break-word;\n}\n\n.modal {\n  position: fixed;\n  top: 0;\n  right: 0;\n  z-index: 1055;\n  display: none;\n  width: 100%;\n  height: 100%;\n  overflow-x: hidden;\n  overflow-y: auto;\n  outline: 0;\n}\n\n.modal-dialog {\n  position: relative;\n  width: auto;\n  margin: 0.5rem;\n  pointer-events: none;\n}\n.modal.fade .modal-dialog {\n  transition: transform 0.3s ease-out;\n  transform: translate(0, -50px);\n}\n@media (prefers-reduced-motion: reduce) {\n  .modal.fade .modal-dialog {\n    transition: none;\n  }\n}\n.modal.show .modal-dialog {\n  transform: none;\n}\n.modal.modal-static .modal-dialog {\n  transform: scale(1.02);\n}\n\n.modal-dialog-scrollable {\n  height: calc(100% - 1rem);\n}\n.modal-dialog-scrollable .modal-content {\n  max-height: 100%;\n  overflow: hidden;\n}\n.modal-dialog-scrollable .modal-body {\n  overflow-y: auto;\n}\n\n.modal-dialog-centered {\n  display: flex;\n  align-items: center;\n  min-height: calc(100% - 1rem);\n}\n\n.modal-content {\n  position: relative;\n  display: flex;\n  flex-direction: column;\n  width: 100%;\n  pointer-events: auto;\n  background-color: #fff;\n  background-clip: padding-box;\n  border: 1px solid rgba(0, 0, 0, 0.2);\n  border-radius: 0.3rem;\n  outline: 0;\n}\n\n.modal-backdrop {\n  position: fixed;\n  top: 0;\n  right: 0;\n  z-index: 1050;\n  width: 100vw;\n  height: 100vh;\n  background-color: #000;\n}\n.modal-backdrop.fade {\n  opacity: 0;\n}\n.modal-backdrop.show {\n  opacity: 0.5;\n}\n\n.modal-header {\n  display: flex;\n  flex-shrink: 0;\n  align-items: center;\n  justify-content: space-between;\n  padding: 1rem 1rem;\n  border-bottom: 1px solid #dee2e6;\n  border-top-right-radius: calc(0.3rem - 1px);\n  border-top-left-radius: calc(0.3rem - 1px);\n}\n.modal-header .btn-close {\n  padding: 0.5rem 0.5rem;\n  margin: -0.5rem auto -0.5rem -0.5rem;\n}\n\n.modal-title {\n  margin-bottom: 0;\n  line-height: 1.5;\n}\n\n.modal-body {\n  position: relative;\n  flex: 1 1 auto;\n  padding: 1rem;\n}\n\n.modal-footer {\n  display: flex;\n  flex-wrap: wrap;\n  flex-shrink: 0;\n  align-items: center;\n  justify-content: flex-end;\n  padding: 0.75rem;\n  border-top: 1px solid #dee2e6;\n  border-bottom-left-radius: calc(0.3rem - 1px);\n  border-bottom-right-radius: calc(0.3rem - 1px);\n}\n.modal-footer > * {\n  margin: 0.25rem;\n}\n\n@media (min-width: 576px) {\n  .modal-dialog {\n    max-width: 500px;\n    margin: 1.75rem auto;\n  }\n\n  .modal-dialog-scrollable {\n    height: calc(100% - 3.5rem);\n  }\n\n  .modal-dialog-centered {\n    min-height: calc(100% - 3.5rem);\n  }\n\n  .modal-sm {\n    max-width: 300px;\n  }\n}\n@media (min-width: 992px) {\n  .modal-lg,\n.modal-xl {\n    max-width: 800px;\n  }\n}\n@media (min-width: 1200px) {\n  .modal-xl {\n    max-width: 1140px;\n  }\n}\n.modal-fullscreen {\n  width: 100vw;\n  max-width: none;\n  height: 100%;\n  margin: 0;\n}\n.modal-fullscreen .modal-content {\n  height: 100%;\n  border: 0;\n  border-radius: 0;\n}\n.modal-fullscreen .modal-header {\n  border-radius: 0;\n}\n.modal-fullscreen .modal-body {\n  overflow-y: auto;\n}\n.modal-fullscreen .modal-footer {\n  border-radius: 0;\n}\n\n@media (max-width: 575.98px) {\n  .modal-fullscreen-sm-down {\n    width: 100vw;\n    max-width: none;\n    height: 100%;\n    margin: 0;\n  }\n  .modal-fullscreen-sm-down .modal-content {\n    height: 100%;\n    border: 0;\n    border-radius: 0;\n  }\n  .modal-fullscreen-sm-down .modal-header {\n    border-radius: 0;\n  }\n  .modal-fullscreen-sm-down .modal-body {\n    overflow-y: auto;\n  }\n  .modal-fullscreen-sm-down .modal-footer {\n    border-radius: 0;\n  }\n}\n@media (max-width: 767.98px) {\n  .modal-fullscreen-md-down {\n    width: 100vw;\n    max-width: none;\n    height: 100%;\n    margin: 0;\n  }\n  .modal-fullscreen-md-down .modal-content {\n    height: 100%;\n    border: 0;\n    border-radius: 0;\n  }\n  .modal-fullscreen-md-down .modal-header {\n    border-radius: 0;\n  }\n  .modal-fullscreen-md-down .modal-body {\n    overflow-y: auto;\n  }\n  .modal-fullscreen-md-down .modal-footer {\n    border-radius: 0;\n  }\n}\n@media (max-width: 991.98px) {\n  .modal-fullscreen-lg-down {\n    width: 100vw;\n    max-width: none;\n    height: 100%;\n    margin: 0;\n  }\n  .modal-fullscreen-lg-down .modal-content {\n    height: 100%;\n    border: 0;\n    border-radius: 0;\n  }\n  .modal-fullscreen-lg-down .modal-header {\n    border-radius: 0;\n  }\n  .modal-fullscreen-lg-down .modal-body {\n    overflow-y: auto;\n  }\n  .modal-fullscreen-lg-down .modal-footer {\n    border-radius: 0;\n  }\n}\n@media (max-width: 1199.98px) {\n  .modal-fullscreen-xl-down {\n    width: 100vw;\n    max-width: none;\n    height: 100%;\n    margin: 0;\n  }\n  .modal-fullscreen-xl-down .modal-content {\n    height: 100%;\n    border: 0;\n    border-radius: 0;\n  }\n  .modal-fullscreen-xl-down .modal-header {\n    border-radius: 0;\n  }\n  .modal-fullscreen-xl-down .modal-body {\n    overflow-y: auto;\n  }\n  .modal-fullscreen-xl-down .modal-footer {\n    border-radius: 0;\n  }\n}\n@media (max-width: 1399.98px) {\n  .modal-fullscreen-xxl-down {\n    width: 100vw;\n    max-width: none;\n    height: 100%;\n    margin: 0;\n  }\n  .modal-fullscreen-xxl-down .modal-content {\n    height: 100%;\n    border: 0;\n    border-radius: 0;\n  }\n  .modal-fullscreen-xxl-down .modal-header {\n    border-radius: 0;\n  }\n  .modal-fullscreen-xxl-down .modal-body {\n    overflow-y: auto;\n  }\n  .modal-fullscreen-xxl-down .modal-footer {\n    border-radius: 0;\n  }\n}\n.tooltip {\n  position: absolute;\n  z-index: 1080;\n  display: block;\n  margin: 0;\n  font-family: var(--bs-font-sans-serif);\n  font-style: normal;\n  font-weight: 400;\n  line-height: 1.5;\n  text-align: right;\n  text-align: start;\n  text-decoration: none;\n  text-shadow: none;\n  text-transform: none;\n  letter-spacing: normal;\n  word-break: normal;\n  word-spacing: normal;\n  white-space: normal;\n  line-break: auto;\n  font-size: 0.875rem;\n  word-wrap: break-word;\n  opacity: 0;\n}\n.tooltip.show {\n  opacity: 0.9;\n}\n.tooltip .tooltip-arrow {\n  position: absolute;\n  display: block;\n  width: 0.8rem;\n  height: 0.4rem;\n}\n.tooltip .tooltip-arrow::before {\n  position: absolute;\n  content: \"\";\n  border-color: transparent;\n  border-style: solid;\n}\n\n.bs-tooltip-top, .bs-tooltip-auto[data-popper-placement^=top] {\n  padding: 0.4rem 0;\n}\n.bs-tooltip-top .tooltip-arrow, .bs-tooltip-auto[data-popper-placement^=top] .tooltip-arrow {\n  bottom: 0;\n}\n.bs-tooltip-top .tooltip-arrow::before, .bs-tooltip-auto[data-popper-placement^=top] .tooltip-arrow::before {\n  top: -1px;\n  border-width: 0.4rem 0.4rem 0;\n  border-top-color: #000;\n}\n\n.bs-tooltip-end, .bs-tooltip-auto[data-popper-placement^=right] {\n  padding: 0 0.4rem;\n}\n.bs-tooltip-end .tooltip-arrow, .bs-tooltip-auto[data-popper-placement^=right] .tooltip-arrow {\n  right: 0;\n  width: 0.4rem;\n  height: 0.8rem;\n}\n.bs-tooltip-end .tooltip-arrow::before, .bs-tooltip-auto[data-popper-placement^=right] .tooltip-arrow::before {\n  left: -1px;\n  border-width: 0.4rem 0 0.4rem 0.4rem;\n  border-left-color: #000;\n}\n\n.bs-tooltip-bottom, .bs-tooltip-auto[data-popper-placement^=bottom] {\n  padding: 0.4rem 0;\n}\n.bs-tooltip-bottom .tooltip-arrow, .bs-tooltip-auto[data-popper-placement^=bottom] .tooltip-arrow {\n  top: 0;\n}\n.bs-tooltip-bottom .tooltip-arrow::before, .bs-tooltip-auto[data-popper-placement^=bottom] .tooltip-arrow::before {\n  bottom: -1px;\n  border-width: 0 0.4rem 0.4rem;\n  border-bottom-color: #000;\n}\n\n.bs-tooltip-start, .bs-tooltip-auto[data-popper-placement^=left] {\n  padding: 0 0.4rem;\n}\n.bs-tooltip-start .tooltip-arrow, .bs-tooltip-auto[data-popper-placement^=left] .tooltip-arrow {\n  left: 0;\n  width: 0.4rem;\n  height: 0.8rem;\n}\n.bs-tooltip-start .tooltip-arrow::before, .bs-tooltip-auto[data-popper-placement^=left] .tooltip-arrow::before {\n  right: -1px;\n  border-width: 0.4rem 0.4rem 0.4rem 0;\n  border-right-color: #000;\n}\n\n.tooltip-inner {\n  max-width: 200px;\n  padding: 0.25rem 0.5rem;\n  color: #fff;\n  text-align: center;\n  background-color: #000;\n  border-radius: 0.25rem;\n}\n\n.popover {\n  position: absolute;\n  top: 0;\n  left: 0 ;\n  z-index: 1070;\n  display: block;\n  max-width: 276px;\n  font-family: var(--bs-font-sans-serif);\n  font-style: normal;\n  font-weight: 400;\n  line-height: 1.5;\n  text-align: right;\n  text-align: start;\n  text-decoration: none;\n  text-shadow: none;\n  text-transform: none;\n  letter-spacing: normal;\n  word-break: normal;\n  word-spacing: normal;\n  white-space: normal;\n  line-break: auto;\n  font-size: 0.875rem;\n  word-wrap: break-word;\n  background-color: #fff;\n  background-clip: padding-box;\n  border: 1px solid rgba(0, 0, 0, 0.2);\n  border-radius: 0.3rem;\n}\n.popover .popover-arrow {\n  position: absolute;\n  display: block;\n  width: 1rem;\n  height: 0.5rem;\n}\n.popover .popover-arrow::before, .popover .popover-arrow::after {\n  position: absolute;\n  display: block;\n  content: \"\";\n  border-color: transparent;\n  border-style: solid;\n}\n\n.bs-popover-top > .popover-arrow, .bs-popover-auto[data-popper-placement^=top] > .popover-arrow {\n  bottom: calc(-0.5rem - 1px);\n}\n.bs-popover-top > .popover-arrow::before, .bs-popover-auto[data-popper-placement^=top] > .popover-arrow::before {\n  bottom: 0;\n  border-width: 0.5rem 0.5rem 0;\n  border-top-color: rgba(0, 0, 0, 0.25);\n}\n.bs-popover-top > .popover-arrow::after, .bs-popover-auto[data-popper-placement^=top] > .popover-arrow::after {\n  bottom: 1px;\n  border-width: 0.5rem 0.5rem 0;\n  border-top-color: #fff;\n}\n\n.bs-popover-end > .popover-arrow, .bs-popover-auto[data-popper-placement^=right] > .popover-arrow {\n  right: calc(-0.5rem - 1px);\n  width: 0.5rem;\n  height: 1rem;\n}\n.bs-popover-end > .popover-arrow::before, .bs-popover-auto[data-popper-placement^=right] > .popover-arrow::before {\n  right: 0;\n  border-width: 0.5rem 0 0.5rem 0.5rem;\n  border-left-color: rgba(0, 0, 0, 0.25);\n}\n.bs-popover-end > .popover-arrow::after, .bs-popover-auto[data-popper-placement^=right] > .popover-arrow::after {\n  right: 1px;\n  border-width: 0.5rem 0 0.5rem 0.5rem;\n  border-left-color: #fff;\n}\n\n.bs-popover-bottom > .popover-arrow, .bs-popover-auto[data-popper-placement^=bottom] > .popover-arrow {\n  top: calc(-0.5rem - 1px);\n}\n.bs-popover-bottom > .popover-arrow::before, .bs-popover-auto[data-popper-placement^=bottom] > .popover-arrow::before {\n  top: 0;\n  border-width: 0 0.5rem 0.5rem 0.5rem;\n  border-bottom-color: rgba(0, 0, 0, 0.25);\n}\n.bs-popover-bottom > .popover-arrow::after, .bs-popover-auto[data-popper-placement^=bottom] > .popover-arrow::after {\n  top: 1px;\n  border-width: 0 0.5rem 0.5rem 0.5rem;\n  border-bottom-color: #fff;\n}\n.bs-popover-bottom .popover-header::before, .bs-popover-auto[data-popper-placement^=bottom] .popover-header::before {\n  position: absolute;\n  top: 0;\n  right: 50%;\n  display: block;\n  width: 1rem;\n  margin-right: -0.5rem;\n  content: \"\";\n  border-bottom: 1px solid #f0f0f0;\n}\n\n.bs-popover-start > .popover-arrow, .bs-popover-auto[data-popper-placement^=left] > .popover-arrow {\n  left: calc(-0.5rem - 1px);\n  width: 0.5rem;\n  height: 1rem;\n}\n.bs-popover-start > .popover-arrow::before, .bs-popover-auto[data-popper-placement^=left] > .popover-arrow::before {\n  left: 0;\n  border-width: 0.5rem 0.5rem 0.5rem 0;\n  border-right-color: rgba(0, 0, 0, 0.25);\n}\n.bs-popover-start > .popover-arrow::after, .bs-popover-auto[data-popper-placement^=left] > .popover-arrow::after {\n  left: 1px;\n  border-width: 0.5rem 0.5rem 0.5rem 0;\n  border-right-color: #fff;\n}\n\n.popover-header {\n  padding: 0.5rem 1rem;\n  margin-bottom: 0;\n  font-size: 1rem;\n  background-color: #f0f0f0;\n  border-bottom: 1px solid rgba(0, 0, 0, 0.2);\n  border-top-right-radius: calc(0.3rem - 1px);\n  border-top-left-radius: calc(0.3rem - 1px);\n}\n.popover-header:empty {\n  display: none;\n}\n\n.popover-body {\n  padding: 1rem 1rem;\n  color: #212529;\n}\n\n.carousel {\n  position: relative;\n}\n\n.carousel.pointer-event {\n  touch-action: pan-y;\n}\n\n.carousel-inner {\n  position: relative;\n  width: 100%;\n  overflow: hidden;\n}\n.carousel-inner::after {\n  display: block;\n  clear: both;\n  content: \"\";\n}\n\n.carousel-item {\n  position: relative;\n  display: none;\n  float: right;\n  width: 100%;\n  margin-left: -100%;\n  -webkit-backface-visibility: hidden;\n  backface-visibility: hidden;\n  transition: transform 0.6s ease-in-out;\n}\n@media (prefers-reduced-motion: reduce) {\n  .carousel-item {\n    transition: none;\n  }\n}\n\n.carousel-item.active,\n.carousel-item-next,\n.carousel-item-prev {\n  display: block;\n}\n.carousel-item-next:not(.carousel-item-start),\n.active.carousel-item-end {\n  transform: translateX(100%);\n}\n\n.carousel-item-prev:not(.carousel-item-end),\n.active.carousel-item-start {\n  transform: translateX(-100%);\n}\n.carousel-fade .carousel-item {\n  opacity: 0;\n  transition-property: opacity;\n  transform: none;\n}\n.carousel-fade .carousel-item.active,\n.carousel-fade .carousel-item-next.carousel-item-start,\n.carousel-fade .carousel-item-prev.carousel-item-end {\n  z-index: 1;\n  opacity: 1;\n}\n.carousel-fade .active.carousel-item-start,\n.carousel-fade .active.carousel-item-end {\n  z-index: 0;\n  opacity: 0;\n  transition: opacity 0s 0.6s;\n}\n@media (prefers-reduced-motion: reduce) {\n  .carousel-fade .active.carousel-item-start,\n.carousel-fade .active.carousel-item-end {\n    transition: none;\n  }\n}\n\n.carousel-control-prev,\n.carousel-control-next {\n  position: absolute;\n  top: 0;\n  bottom: 0;\n  z-index: 1;\n  display: flex;\n  align-items: center;\n  justify-content: center;\n  width: 15%;\n  padding: 0;\n  color: #fff;\n  text-align: center;\n  background: none;\n  border: 0;\n  opacity: 0.5;\n  transition: opacity 0.15s ease;\n}\n@media (prefers-reduced-motion: reduce) {\n  .carousel-control-prev,\n.carousel-control-next {\n    transition: none;\n  }\n}\n.carousel-control-prev:hover, .carousel-control-prev:focus,\n.carousel-control-next:hover,\n.carousel-control-next:focus {\n  color: #fff;\n  text-decoration: none;\n  outline: 0;\n  opacity: 0.9;\n}\n\n.carousel-control-prev {\n  right: 0;\n}\n\n.carousel-control-next {\n  left: 0;\n}\n\n.carousel-control-prev-icon,\n.carousel-control-next-icon {\n  display: inline-block;\n  width: 2rem;\n  height: 2rem;\n  background-repeat: no-repeat;\n  background-position: 50%;\n  background-size: 100% 100%;\n}\n.carousel-control-next-icon {\n  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 0z'/%3e%3c/svg%3e\");\n}\n\n.carousel-control-prev-icon {\n  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-.708z'/%3e%3c/svg%3e\");\n}\n\n.carousel-indicators {\n  position: absolute;\n  left: 0;\n  bottom: 0;\n  right: 0;\n  z-index: 2;\n  display: flex;\n  justify-content: center;\n  padding: 0;\n  margin-left: 15%;\n  margin-bottom: 1rem;\n  margin-right: 15%;\n  list-style: none;\n}\n.carousel-indicators [data-bs-target] {\n  box-sizing: content-box;\n  flex: 0 1 auto;\n  width: 30px;\n  height: 3px;\n  padding: 0;\n  margin-left: 3px;\n  margin-right: 3px;\n  text-indent: -999px;\n  cursor: pointer;\n  background-color: #fff;\n  background-clip: padding-box;\n  border: 0;\n  border-top: 10px solid transparent;\n  border-bottom: 10px solid transparent;\n  opacity: 0.5;\n  transition: opacity 0.6s ease;\n}\n@media (prefers-reduced-motion: reduce) {\n  .carousel-indicators [data-bs-target] {\n    transition: none;\n  }\n}\n.carousel-indicators .active {\n  opacity: 1;\n}\n\n.carousel-caption {\n  position: absolute;\n  left: 15%;\n  bottom: 1.25rem;\n  right: 15%;\n  padding-top: 1.25rem;\n  padding-bottom: 1.25rem;\n  color: #fff;\n  text-align: center;\n}\n\n.carousel-dark .carousel-control-next-icon,\n.carousel-dark .carousel-control-prev-icon {\n  filter: invert(1) grayscale(100);\n}\n.carousel-dark .carousel-indicators [data-bs-target] {\n  background-color: #000;\n}\n.carousel-dark .carousel-caption {\n  color: #000;\n}\n\n@-webkit-keyframes spinner-border {\n  to {\n    transform: rotate(360deg) ;\n  }\n}\n\n@keyframes spinner-border {\n  to {\n    transform: rotate(360deg) ;\n  }\n}\n.spinner-border {\n  display: inline-block;\n  width: 2rem;\n  height: 2rem;\n  vertical-align: -0.125em;\n  border: 0.25em solid currentColor;\n  border-left-color: transparent;\n  border-radius: 50%;\n  -webkit-animation: 0.75s linear infinite spinner-border;\n  animation: 0.75s linear infinite spinner-border;\n}\n\n.spinner-border-sm {\n  width: 1rem;\n  height: 1rem;\n  border-width: 0.2em;\n}\n\n@-webkit-keyframes spinner-grow {\n  0% {\n    transform: scale(0);\n  }\n  50% {\n    opacity: 1;\n    transform: none;\n  }\n}\n\n@keyframes spinner-grow {\n  0% {\n    transform: scale(0);\n  }\n  50% {\n    opacity: 1;\n    transform: none;\n  }\n}\n.spinner-grow {\n  display: inline-block;\n  width: 2rem;\n  height: 2rem;\n  vertical-align: -0.125em;\n  background-color: currentColor;\n  border-radius: 50%;\n  opacity: 0;\n  -webkit-animation: 0.75s linear infinite spinner-grow;\n  animation: 0.75s linear infinite spinner-grow;\n}\n\n.spinner-grow-sm {\n  width: 1rem;\n  height: 1rem;\n}\n\n@media (prefers-reduced-motion: reduce) {\n  .spinner-border,\n.spinner-grow {\n    -webkit-animation-duration: 1.5s;\n    animation-duration: 1.5s;\n  }\n}\n.offcanvas {\n  position: fixed;\n  bottom: 0;\n  z-index: 1045;\n  display: flex;\n  flex-direction: column;\n  max-width: 100%;\n  visibility: hidden;\n  background-color: #fff;\n  background-clip: padding-box;\n  outline: 0;\n  transition: transform 0.3s ease-in-out;\n}\n@media (prefers-reduced-motion: reduce) {\n  .offcanvas {\n    transition: none;\n  }\n}\n\n.offcanvas-backdrop {\n  position: fixed;\n  top: 0;\n  right: 0;\n  z-index: 1040;\n  width: 100vw;\n  height: 100vh;\n  background-color: #000;\n}\n.offcanvas-backdrop.fade {\n  opacity: 0;\n}\n.offcanvas-backdrop.show {\n  opacity: 0.5;\n}\n\n.offcanvas-header {\n  display: flex;\n  align-items: center;\n  justify-content: space-between;\n  padding: 1rem 1rem;\n}\n.offcanvas-header .btn-close {\n  padding: 0.5rem 0.5rem;\n  margin-top: -0.5rem;\n  margin-left: -0.5rem;\n  margin-bottom: -0.5rem;\n}\n\n.offcanvas-title {\n  margin-bottom: 0;\n  line-height: 1.5;\n}\n\n.offcanvas-body {\n  flex-grow: 1;\n  padding: 1rem 1rem;\n  overflow-y: auto;\n}\n\n.offcanvas-start {\n  top: 0;\n  right: 0;\n  width: 400px;\n  border-left: 1px solid rgba(0, 0, 0, 0.2);\n  transform: translateX(100%);\n}\n\n.offcanvas-end {\n  top: 0;\n  left: 0;\n  width: 400px;\n  border-right: 1px solid rgba(0, 0, 0, 0.2);\n  transform: translateX(-100%);\n}\n\n.offcanvas-top {\n  top: 0;\n  left: 0;\n  right: 0;\n  height: 30vh;\n  max-height: 100%;\n  border-bottom: 1px solid rgba(0, 0, 0, 0.2);\n  transform: translateY(-100%);\n}\n\n.offcanvas-bottom {\n  left: 0;\n  right: 0;\n  height: 30vh;\n  max-height: 100%;\n  border-top: 1px solid rgba(0, 0, 0, 0.2);\n  transform: translateY(100%);\n}\n\n.offcanvas.show {\n  transform: none;\n}\n\n.placeholder {\n  display: inline-block;\n  min-height: 1em;\n  vertical-align: middle;\n  cursor: wait;\n  background-color: currentColor;\n  opacity: 0.5;\n}\n.placeholder.btn::before {\n  display: inline-block;\n  content: \"\";\n}\n\n.placeholder-xs {\n  min-height: 0.6em;\n}\n\n.placeholder-sm {\n  min-height: 0.8em;\n}\n\n.placeholder-lg {\n  min-height: 1.2em;\n}\n\n.placeholder-glow .placeholder {\n  -webkit-animation: placeholder-glow 2s ease-in-out infinite;\n  animation: placeholder-glow 2s ease-in-out infinite;\n}\n\n@-webkit-keyframes placeholder-glow {\n  50% {\n    opacity: 0.2;\n  }\n}\n\n@keyframes placeholder-glow {\n  50% {\n    opacity: 0.2;\n  }\n}\n.placeholder-wave {\n  -webkit-mask-image: linear-gradient(130deg, #000 55%, rgba(0, 0, 0, 0.8) 75%, #000 95%);\n  mask-image: linear-gradient(130deg, #000 55%, rgba(0, 0, 0, 0.8) 75%, #000 95%);\n  -webkit-mask-size: 200% 100%;\n  mask-size: 200% 100%;\n  -webkit-animation: placeholder-wave 2s linear infinite;\n  animation: placeholder-wave 2s linear infinite;\n}\n\n@-webkit-keyframes placeholder-wave {\n  100% {\n    -webkit-mask-position: -200% 0%;\n    mask-position: -200% 0%;\n  }\n}\n\n@keyframes placeholder-wave {\n  100% {\n    -webkit-mask-position: -200% 0%;\n    mask-position: -200% 0%;\n  }\n}\n.clearfix::after {\n  display: block;\n  clear: both;\n  content: \"\";\n}\n\n.link-primary {\n  color: #0d6efd;\n}\n.link-primary:hover, .link-primary:focus {\n  color: #0a58ca;\n}\n\n.link-secondary {\n  color: #6c757d;\n}\n.link-secondary:hover, .link-secondary:focus {\n  color: #565e64;\n}\n\n.link-success {\n  color: #198754;\n}\n.link-success:hover, .link-success:focus {\n  color: #146c43;\n}\n\n.link-info {\n  color: #0dcaf0;\n}\n.link-info:hover, .link-info:focus {\n  color: #3dd5f3;\n}\n\n.link-warning {\n  color: #ffc107;\n}\n.link-warning:hover, .link-warning:focus {\n  color: #ffcd39;\n}\n\n.link-danger {\n  color: #dc3545;\n}\n.link-danger:hover, .link-danger:focus {\n  color: #b02a37;\n}\n\n.link-light {\n  color: #f8f9fa;\n}\n.link-light:hover, .link-light:focus {\n  color: #f9fafb;\n}\n\n.link-dark {\n  color: #212529;\n}\n.link-dark:hover, .link-dark:focus {\n  color: #1a1e21;\n}\n\n.ratio {\n  position: relative;\n  width: 100%;\n}\n.ratio::before {\n  display: block;\n  padding-top: var(--bs-aspect-ratio);\n  content: \"\";\n}\n.ratio > * {\n  position: absolute;\n  top: 0;\n  right: 0;\n  width: 100%;\n  height: 100%;\n}\n\n.ratio-1x1 {\n  --bs-aspect-ratio: 100%;\n}\n\n.ratio-4x3 {\n  --bs-aspect-ratio: calc(3 / 4 * 100%);\n}\n\n.ratio-16x9 {\n  --bs-aspect-ratio: calc(9 / 16 * 100%);\n}\n\n.ratio-21x9 {\n  --bs-aspect-ratio: calc(9 / 21 * 100%);\n}\n\n.fixed-top {\n  position: fixed;\n  top: 0;\n  left: 0;\n  right: 0;\n  z-index: 1030;\n}\n\n.fixed-bottom {\n  position: fixed;\n  left: 0;\n  bottom: 0;\n  right: 0;\n  z-index: 1030;\n}\n\n.sticky-top {\n  position: -webkit-sticky;\n  position: sticky;\n  top: 0;\n  z-index: 1020;\n}\n\n@media (min-width: 576px) {\n  .sticky-sm-top {\n    position: -webkit-sticky;\n    position: sticky;\n    top: 0;\n    z-index: 1020;\n  }\n}\n@media (min-width: 768px) {\n  .sticky-md-top {\n    position: -webkit-sticky;\n    position: sticky;\n    top: 0;\n    z-index: 1020;\n  }\n}\n@media (min-width: 992px) {\n  .sticky-lg-top {\n    position: -webkit-sticky;\n    position: sticky;\n    top: 0;\n    z-index: 1020;\n  }\n}\n@media (min-width: 1200px) {\n  .sticky-xl-top {\n    position: -webkit-sticky;\n    position: sticky;\n    top: 0;\n    z-index: 1020;\n  }\n}\n@media (min-width: 1400px) {\n  .sticky-xxl-top {\n    position: -webkit-sticky;\n    position: sticky;\n    top: 0;\n    z-index: 1020;\n  }\n}\n.hstack {\n  display: flex;\n  flex-direction: row;\n  align-items: center;\n  align-self: stretch;\n}\n\n.vstack {\n  display: flex;\n  flex: 1 1 auto;\n  flex-direction: column;\n  align-self: stretch;\n}\n\n.visually-hidden,\n.visually-hidden-focusable:not(:focus):not(:focus-within) {\n  position: absolute !important;\n  width: 1px !important;\n  height: 1px !important;\n  padding: 0 !important;\n  margin: -1px !important;\n  overflow: hidden !important;\n  clip: rect(0, 0, 0, 0) !important;\n  white-space: nowrap !important;\n  border: 0 !important;\n}\n\n.stretched-link::after {\n  position: absolute;\n  top: 0;\n  left: 0;\n  bottom: 0;\n  right: 0;\n  z-index: 1;\n  content: \"\";\n}\n\n.text-truncate {\n  overflow: hidden;\n  text-overflow: ellipsis;\n  white-space: nowrap;\n}\n\n.vr {\n  display: inline-block;\n  align-self: stretch;\n  width: 1px;\n  min-height: 1em;\n  background-color: currentColor;\n  opacity: 0.25;\n}\n\n.align-baseline {\n  vertical-align: baseline !important;\n}\n\n.align-top {\n  vertical-align: top !important;\n}\n\n.align-middle {\n  vertical-align: middle !important;\n}\n\n.align-bottom {\n  vertical-align: bottom !important;\n}\n\n.align-text-bottom {\n  vertical-align: text-bottom !important;\n}\n\n.align-text-top {\n  vertical-align: text-top !important;\n}\n\n.float-start {\n  float: right !important;\n}\n\n.float-end {\n  float: left !important;\n}\n\n.float-none {\n  float: none !important;\n}\n\n.opacity-0 {\n  opacity: 0 !important;\n}\n\n.opacity-25 {\n  opacity: 0.25 !important;\n}\n\n.opacity-50 {\n  opacity: 0.5 !important;\n}\n\n.opacity-75 {\n  opacity: 0.75 !important;\n}\n\n.opacity-100 {\n  opacity: 1 !important;\n}\n\n.overflow-auto {\n  overflow: auto !important;\n}\n\n.overflow-hidden {\n  overflow: hidden !important;\n}\n\n.overflow-visible {\n  overflow: visible !important;\n}\n\n.overflow-scroll {\n  overflow: scroll !important;\n}\n\n.d-inline {\n  display: inline !important;\n}\n\n.d-inline-block {\n  display: inline-block !important;\n}\n\n.d-block {\n  display: block !important;\n}\n\n.d-grid {\n  display: grid !important;\n}\n\n.d-table {\n  display: table !important;\n}\n\n.d-table-row {\n  display: table-row !important;\n}\n\n.d-table-cell {\n  display: table-cell !important;\n}\n\n.d-flex {\n  display: flex !important;\n}\n\n.d-inline-flex {\n  display: inline-flex !important;\n}\n\n.d-none {\n  display: none !important;\n}\n\n.shadow {\n  box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.15) !important;\n}\n\n.shadow-sm {\n  box-shadow: 0 0.125rem 0.25rem rgba(0, 0, 0, 0.075) !important;\n}\n\n.shadow-lg {\n  box-shadow: 0 1rem 3rem rgba(0, 0, 0, 0.175) !important;\n}\n\n.shadow-none {\n  box-shadow: none !important;\n}\n\n.position-static {\n  position: static !important;\n}\n\n.position-relative {\n  position: relative !important;\n}\n\n.position-absolute {\n  position: absolute !important;\n}\n\n.position-fixed {\n  position: fixed !important;\n}\n\n.position-sticky {\n  position: -webkit-sticky !important;\n  position: sticky !important;\n}\n\n.top-0 {\n  top: 0 !important;\n}\n\n.top-50 {\n  top: 50% !important;\n}\n\n.top-100 {\n  top: 100% !important;\n}\n\n.bottom-0 {\n  bottom: 0 !important;\n}\n\n.bottom-50 {\n  bottom: 50% !important;\n}\n\n.bottom-100 {\n  bottom: 100% !important;\n}\n\n.start-0 {\n  right: 0 !important;\n}\n\n.start-50 {\n  right: 50% !important;\n}\n\n.start-100 {\n  right: 100% !important;\n}\n\n.end-0 {\n  left: 0 !important;\n}\n\n.end-50 {\n  left: 50% !important;\n}\n\n.end-100 {\n  left: 100% !important;\n}\n\n.translate-middle {\n  transform: translate(50%, -50%) !important;\n}\n\n.translate-middle-x {\n  transform: translateX(50%) !important;\n}\n\n.translate-middle-y {\n  transform: translateY(-50%) !important;\n}\n\n.border {\n  border: 1px solid #dee2e6 !important;\n}\n\n.border-0 {\n  border: 0 !important;\n}\n\n.border-top {\n  border-top: 1px solid #dee2e6 !important;\n}\n\n.border-top-0 {\n  border-top: 0 !important;\n}\n\n.border-end {\n  border-left: 1px solid #dee2e6 !important;\n}\n\n.border-end-0 {\n  border-left: 0 !important;\n}\n\n.border-bottom {\n  border-bottom: 1px solid #dee2e6 !important;\n}\n\n.border-bottom-0 {\n  border-bottom: 0 !important;\n}\n\n.border-start {\n  border-right: 1px solid #dee2e6 !important;\n}\n\n.border-start-0 {\n  border-right: 0 !important;\n}\n\n.border-primary {\n  border-color: #0d6efd !important;\n}\n\n.border-secondary {\n  border-color: #6c757d !important;\n}\n\n.border-success {\n  border-color: #198754 !important;\n}\n\n.border-info {\n  border-color: #0dcaf0 !important;\n}\n\n.border-warning {\n  border-color: #ffc107 !important;\n}\n\n.border-danger {\n  border-color: #dc3545 !important;\n}\n\n.border-light {\n  border-color: #f8f9fa !important;\n}\n\n.border-dark {\n  border-color: #212529 !important;\n}\n\n.border-white {\n  border-color: #fff !important;\n}\n\n.border-1 {\n  border-width: 1px !important;\n}\n\n.border-2 {\n  border-width: 2px !important;\n}\n\n.border-3 {\n  border-width: 3px !important;\n}\n\n.border-4 {\n  border-width: 4px !important;\n}\n\n.border-5 {\n  border-width: 5px !important;\n}\n\n.w-25 {\n  width: 25% !important;\n}\n\n.w-50 {\n  width: 50% !important;\n}\n\n.w-75 {\n  width: 75% !important;\n}\n\n.w-100 {\n  width: 100% !important;\n}\n\n.w-auto {\n  width: auto !important;\n}\n\n.mw-100 {\n  max-width: 100% !important;\n}\n\n.vw-100 {\n  width: 100vw !important;\n}\n\n.min-vw-100 {\n  min-width: 100vw !important;\n}\n\n.h-25 {\n  height: 25% !important;\n}\n\n.h-50 {\n  height: 50% !important;\n}\n\n.h-75 {\n  height: 75% !important;\n}\n\n.h-100 {\n  height: 100% !important;\n}\n\n.h-auto {\n  height: auto !important;\n}\n\n.mh-100 {\n  max-height: 100% !important;\n}\n\n.vh-100 {\n  height: 100vh !important;\n}\n\n.min-vh-100 {\n  min-height: 100vh !important;\n}\n\n.flex-fill {\n  flex: 1 1 auto !important;\n}\n\n.flex-row {\n  flex-direction: row !important;\n}\n\n.flex-column {\n  flex-direction: column !important;\n}\n\n.flex-row-reverse {\n  flex-direction: row-reverse !important;\n}\n\n.flex-column-reverse {\n  flex-direction: column-reverse !important;\n}\n\n.flex-grow-0 {\n  flex-grow: 0 !important;\n}\n\n.flex-grow-1 {\n  flex-grow: 1 !important;\n}\n\n.flex-shrink-0 {\n  flex-shrink: 0 !important;\n}\n\n.flex-shrink-1 {\n  flex-shrink: 1 !important;\n}\n\n.flex-wrap {\n  flex-wrap: wrap !important;\n}\n\n.flex-nowrap {\n  flex-wrap: nowrap !important;\n}\n\n.flex-wrap-reverse {\n  flex-wrap: wrap-reverse !important;\n}\n\n.gap-0 {\n  gap: 0 !important;\n}\n\n.gap-1 {\n  gap: 0.25rem !important;\n}\n\n.gap-2 {\n  gap: 0.5rem !important;\n}\n\n.gap-3 {\n  gap: 1rem !important;\n}\n\n.gap-4 {\n  gap: 1.5rem !important;\n}\n\n.gap-5 {\n  gap: 3rem !important;\n}\n\n.justify-content-start {\n  justify-content: flex-start !important;\n}\n\n.justify-content-end {\n  justify-content: flex-end !important;\n}\n\n.justify-content-center {\n  justify-content: center !important;\n}\n\n.justify-content-between {\n  justify-content: space-between !important;\n}\n\n.justify-content-around {\n  justify-content: space-around !important;\n}\n\n.justify-content-evenly {\n  justify-content: space-evenly !important;\n}\n\n.align-items-start {\n  align-items: flex-start !important;\n}\n\n.align-items-end {\n  align-items: flex-end !important;\n}\n\n.align-items-center {\n  align-items: center !important;\n}\n\n.align-items-baseline {\n  align-items: baseline !important;\n}\n\n.align-items-stretch {\n  align-items: stretch !important;\n}\n\n.align-content-start {\n  align-content: flex-start !important;\n}\n\n.align-content-end {\n  align-content: flex-end !important;\n}\n\n.align-content-center {\n  align-content: center !important;\n}\n\n.align-content-between {\n  align-content: space-between !important;\n}\n\n.align-content-around {\n  align-content: space-around !important;\n}\n\n.align-content-stretch {\n  align-content: stretch !important;\n}\n\n.align-self-auto {\n  align-self: auto !important;\n}\n\n.align-self-start {\n  align-self: flex-start !important;\n}\n\n.align-self-end {\n  align-self: flex-end !important;\n}\n\n.align-self-center {\n  align-self: center !important;\n}\n\n.align-self-baseline {\n  align-self: baseline !important;\n}\n\n.align-self-stretch {\n  align-self: stretch !important;\n}\n\n.order-first {\n  order: -1 !important;\n}\n\n.order-0 {\n  order: 0 !important;\n}\n\n.order-1 {\n  order: 1 !important;\n}\n\n.order-2 {\n  order: 2 !important;\n}\n\n.order-3 {\n  order: 3 !important;\n}\n\n.order-4 {\n  order: 4 !important;\n}\n\n.order-5 {\n  order: 5 !important;\n}\n\n.order-last {\n  order: 6 !important;\n}\n\n.m-0 {\n  margin: 0 !important;\n}\n\n.m-1 {\n  margin: 0.25rem !important;\n}\n\n.m-2 {\n  margin: 0.5rem !important;\n}\n\n.m-3 {\n  margin: 1rem !important;\n}\n\n.m-4 {\n  margin: 1.5rem !important;\n}\n\n.m-5 {\n  margin: 3rem !important;\n}\n\n.m-auto {\n  margin: auto !important;\n}\n\n.mx-0 {\n  margin-left: 0 !important;\n  margin-right: 0 !important;\n}\n\n.mx-1 {\n  margin-left: 0.25rem !important;\n  margin-right: 0.25rem !important;\n}\n\n.mx-2 {\n  margin-left: 0.5rem !important;\n  margin-right: 0.5rem !important;\n}\n\n.mx-3 {\n  margin-left: 1rem !important;\n  margin-right: 1rem !important;\n}\n\n.mx-4 {\n  margin-left: 1.5rem !important;\n  margin-right: 1.5rem !important;\n}\n\n.mx-5 {\n  margin-left: 3rem !important;\n  margin-right: 3rem !important;\n}\n\n.mx-auto {\n  margin-left: auto !important;\n  margin-right: auto !important;\n}\n\n.my-0 {\n  margin-top: 0 !important;\n  margin-bottom: 0 !important;\n}\n\n.my-1 {\n  margin-top: 0.25rem !important;\n  margin-bottom: 0.25rem !important;\n}\n\n.my-2 {\n  margin-top: 0.5rem !important;\n  margin-bottom: 0.5rem !important;\n}\n\n.my-3 {\n  margin-top: 1rem !important;\n  margin-bottom: 1rem !important;\n}\n\n.my-4 {\n  margin-top: 1.5rem !important;\n  margin-bottom: 1.5rem !important;\n}\n\n.my-5 {\n  margin-top: 3rem !important;\n  margin-bottom: 3rem !important;\n}\n\n.my-auto {\n  margin-top: auto !important;\n  margin-bottom: auto !important;\n}\n\n.mt-0 {\n  margin-top: 0 !important;\n}\n\n.mt-1 {\n  margin-top: 0.25rem !important;\n}\n\n.mt-2 {\n  margin-top: 0.5rem !important;\n}\n\n.mt-3 {\n  margin-top: 1rem !important;\n}\n\n.mt-4 {\n  margin-top: 1.5rem !important;\n}\n\n.mt-5 {\n  margin-top: 3rem !important;\n}\n\n.mt-auto {\n  margin-top: auto !important;\n}\n\n.me-0 {\n  margin-left: 0 !important;\n}\n\n.me-1 {\n  margin-left: 0.25rem !important;\n}\n\n.me-2 {\n  margin-left: 0.5rem !important;\n}\n\n.me-3 {\n  margin-left: 1rem !important;\n}\n\n.me-4 {\n  margin-left: 1.5rem !important;\n}\n\n.me-5 {\n  margin-left: 3rem !important;\n}\n\n.me-auto {\n  margin-left: auto !important;\n}\n\n.mb-0 {\n  margin-bottom: 0 !important;\n}\n\n.mb-1 {\n  margin-bottom: 0.25rem !important;\n}\n\n.mb-2 {\n  margin-bottom: 0.5rem !important;\n}\n\n.mb-3 {\n  margin-bottom: 1rem !important;\n}\n\n.mb-4 {\n  margin-bottom: 1.5rem !important;\n}\n\n.mb-5 {\n  margin-bottom: 3rem !important;\n}\n\n.mb-auto {\n  margin-bottom: auto !important;\n}\n\n.ms-0 {\n  margin-right: 0 !important;\n}\n\n.ms-1 {\n  margin-right: 0.25rem !important;\n}\n\n.ms-2 {\n  margin-right: 0.5rem !important;\n}\n\n.ms-3 {\n  margin-right: 1rem !important;\n}\n\n.ms-4 {\n  margin-right: 1.5rem !important;\n}\n\n.ms-5 {\n  margin-right: 3rem !important;\n}\n\n.ms-auto {\n  margin-right: auto !important;\n}\n\n.p-0 {\n  padding: 0 !important;\n}\n\n.p-1 {\n  padding: 0.25rem !important;\n}\n\n.p-2 {\n  padding: 0.5rem !important;\n}\n\n.p-3 {\n  padding: 1rem !important;\n}\n\n.p-4 {\n  padding: 1.5rem !important;\n}\n\n.p-5 {\n  padding: 3rem !important;\n}\n\n.px-0 {\n  padding-left: 0 !important;\n  padding-right: 0 !important;\n}\n\n.px-1 {\n  padding-left: 0.25rem !important;\n  padding-right: 0.25rem !important;\n}\n\n.px-2 {\n  padding-left: 0.5rem !important;\n  padding-right: 0.5rem !important;\n}\n\n.px-3 {\n  padding-left: 1rem !important;\n  padding-right: 1rem !important;\n}\n\n.px-4 {\n  padding-left: 1.5rem !important;\n  padding-right: 1.5rem !important;\n}\n\n.px-5 {\n  padding-left: 3rem !important;\n  padding-right: 3rem !important;\n}\n\n.py-0 {\n  padding-top: 0 !important;\n  padding-bottom: 0 !important;\n}\n\n.py-1 {\n  padding-top: 0.25rem !important;\n  padding-bottom: 0.25rem !important;\n}\n\n.py-2 {\n  padding-top: 0.5rem !important;\n  padding-bottom: 0.5rem !important;\n}\n\n.py-3 {\n  padding-top: 1rem !important;\n  padding-bottom: 1rem !important;\n}\n\n.py-4 {\n  padding-top: 1.5rem !important;\n  padding-bottom: 1.5rem !important;\n}\n\n.py-5 {\n  padding-top: 3rem !important;\n  padding-bottom: 3rem !important;\n}\n\n.pt-0 {\n  padding-top: 0 !important;\n}\n\n.pt-1 {\n  padding-top: 0.25rem !important;\n}\n\n.pt-2 {\n  padding-top: 0.5rem !important;\n}\n\n.pt-3 {\n  padding-top: 1rem !important;\n}\n\n.pt-4 {\n  padding-top: 1.5rem !important;\n}\n\n.pt-5 {\n  padding-top: 3rem !important;\n}\n\n.pe-0 {\n  padding-left: 0 !important;\n}\n\n.pe-1 {\n  padding-left: 0.25rem !important;\n}\n\n.pe-2 {\n  padding-left: 0.5rem !important;\n}\n\n.pe-3 {\n  padding-left: 1rem !important;\n}\n\n.pe-4 {\n  padding-left: 1.5rem !important;\n}\n\n.pe-5 {\n  padding-left: 3rem !important;\n}\n\n.pb-0 {\n  padding-bottom: 0 !important;\n}\n\n.pb-1 {\n  padding-bottom: 0.25rem !important;\n}\n\n.pb-2 {\n  padding-bottom: 0.5rem !important;\n}\n\n.pb-3 {\n  padding-bottom: 1rem !important;\n}\n\n.pb-4 {\n  padding-bottom: 1.5rem !important;\n}\n\n.pb-5 {\n  padding-bottom: 3rem !important;\n}\n\n.ps-0 {\n  padding-right: 0 !important;\n}\n\n.ps-1 {\n  padding-right: 0.25rem !important;\n}\n\n.ps-2 {\n  padding-right: 0.5rem !important;\n}\n\n.ps-3 {\n  padding-right: 1rem !important;\n}\n\n.ps-4 {\n  padding-right: 1.5rem !important;\n}\n\n.ps-5 {\n  padding-right: 3rem !important;\n}\n\n.font-monospace {\n  font-family: var(--bs-font-monospace) !important;\n}\n\n.fs-1 {\n  font-size: calc(1.375rem + 1.5vw) !important;\n}\n\n.fs-2 {\n  font-size: calc(1.325rem + 0.9vw) !important;\n}\n\n.fs-3 {\n  font-size: calc(1.3rem + 0.6vw) !important;\n}\n\n.fs-4 {\n  font-size: calc(1.275rem + 0.3vw) !important;\n}\n\n.fs-5 {\n  font-size: 1.25rem !important;\n}\n\n.fs-6 {\n  font-size: 1rem !important;\n}\n\n.fst-italic {\n  font-style: italic !important;\n}\n\n.fst-normal {\n  font-style: normal !important;\n}\n\n.fw-light {\n  font-weight: 300 !important;\n}\n\n.fw-lighter {\n  font-weight: lighter !important;\n}\n\n.fw-normal {\n  font-weight: 400 !important;\n}\n\n.fw-bold {\n  font-weight: 700 !important;\n}\n\n.fw-bolder {\n  font-weight: bolder !important;\n}\n\n.lh-1 {\n  line-height: 1 !important;\n}\n\n.lh-sm {\n  line-height: 1.25 !important;\n}\n\n.lh-base {\n  line-height: 1.5 !important;\n}\n\n.lh-lg {\n  line-height: 2 !important;\n}\n\n.text-start {\n  text-align: right !important;\n}\n\n.text-end {\n  text-align: left !important;\n}\n\n.text-center {\n  text-align: center !important;\n}\n\n.text-decoration-none {\n  text-decoration: none !important;\n}\n\n.text-decoration-underline {\n  text-decoration: underline !important;\n}\n\n.text-decoration-line-through {\n  text-decoration: line-through !important;\n}\n\n.text-lowercase {\n  text-transform: lowercase !important;\n}\n\n.text-uppercase {\n  text-transform: uppercase !important;\n}\n\n.text-capitalize {\n  text-transform: capitalize !important;\n}\n\n.text-wrap {\n  white-space: normal !important;\n}\n\n.text-nowrap {\n  white-space: nowrap !important;\n}\n.text-primary {\n  --bs-text-opacity: 1;\n  color: rgba(var(--bs-primary-rgb), var(--bs-text-opacity)) !important;\n}\n\n.text-secondary {\n  --bs-text-opacity: 1;\n  color: rgba(var(--bs-secondary-rgb), var(--bs-text-opacity)) !important;\n}\n\n.text-success {\n  --bs-text-opacity: 1;\n  color: rgba(var(--bs-success-rgb), var(--bs-text-opacity)) !important;\n}\n\n.text-info {\n  --bs-text-opacity: 1;\n  color: rgba(var(--bs-info-rgb), var(--bs-text-opacity)) !important;\n}\n\n.text-warning {\n  --bs-text-opacity: 1;\n  color: rgba(var(--bs-warning-rgb), var(--bs-text-opacity)) !important;\n}\n\n.text-danger {\n  --bs-text-opacity: 1;\n  color: rgba(var(--bs-danger-rgb), var(--bs-text-opacity)) !important;\n}\n\n.text-light {\n  --bs-text-opacity: 1;\n  color: rgba(var(--bs-light-rgb), var(--bs-text-opacity)) !important;\n}\n\n.text-dark {\n  --bs-text-opacity: 1;\n  color: rgba(var(--bs-dark-rgb), var(--bs-text-opacity)) !important;\n}\n\n.text-black {\n  --bs-text-opacity: 1;\n  color: rgba(var(--bs-black-rgb), var(--bs-text-opacity)) !important;\n}\n\n.text-white {\n  --bs-text-opacity: 1;\n  color: rgba(var(--bs-white-rgb), var(--bs-text-opacity)) !important;\n}\n\n.text-body {\n  --bs-text-opacity: 1;\n  color: rgba(var(--bs-body-rgb), var(--bs-text-opacity)) !important;\n}\n\n.text-muted {\n  --bs-text-opacity: 1;\n  color: #6c757d !important;\n}\n\n.text-black-50 {\n  --bs-text-opacity: 1;\n  color: rgba(0, 0, 0, 0.5) !important;\n}\n\n.text-white-50 {\n  --bs-text-opacity: 1;\n  color: rgba(255, 255, 255, 0.5) !important;\n}\n\n.text-reset {\n  --bs-text-opacity: 1;\n  color: inherit !important;\n}\n\n.text-opacity-25 {\n  --bs-text-opacity: 0.25;\n}\n\n.text-opacity-50 {\n  --bs-text-opacity: 0.5;\n}\n\n.text-opacity-75 {\n  --bs-text-opacity: 0.75;\n}\n\n.text-opacity-100 {\n  --bs-text-opacity: 1;\n}\n\n.bg-primary {\n  --bs-bg-opacity: 1;\n  background-color: rgba(var(--bs-primary-rgb), var(--bs-bg-opacity)) !important;\n}\n\n.bg-secondary {\n  --bs-bg-opacity: 1;\n  background-color: rgba(var(--bs-secondary-rgb), var(--bs-bg-opacity)) !important;\n}\n\n.bg-success {\n  --bs-bg-opacity: 1;\n  background-color: rgba(var(--bs-success-rgb), var(--bs-bg-opacity)) !important;\n}\n\n.bg-info {\n  --bs-bg-opacity: 1;\n  background-color: rgba(var(--bs-info-rgb), var(--bs-bg-opacity)) !important;\n}\n\n.bg-warning {\n  --bs-bg-opacity: 1;\n  background-color: rgba(var(--bs-warning-rgb), var(--bs-bg-opacity)) !important;\n}\n\n.bg-danger {\n  --bs-bg-opacity: 1;\n  background-color: rgba(var(--bs-danger-rgb), var(--bs-bg-opacity)) !important;\n}\n\n.bg-light {\n  --bs-bg-opacity: 1;\n  background-color: rgba(var(--bs-light-rgb), var(--bs-bg-opacity)) !important;\n}\n\n.bg-dark {\n  --bs-bg-opacity: 1;\n  background-color: rgba(var(--bs-dark-rgb), var(--bs-bg-opacity)) !important;\n}\n\n.bg-black {\n  --bs-bg-opacity: 1;\n  background-color: rgba(var(--bs-black-rgb), var(--bs-bg-opacity)) !important;\n}\n\n.bg-white {\n  --bs-bg-opacity: 1;\n  background-color: rgba(var(--bs-white-rgb), var(--bs-bg-opacity)) !important;\n}\n\n.bg-body {\n  --bs-bg-opacity: 1;\n  background-color: rgba(var(--bs-body-rgb), var(--bs-bg-opacity)) !important;\n}\n\n.bg-transparent {\n  --bs-bg-opacity: 1;\n  background-color: transparent !important;\n}\n\n.bg-opacity-10 {\n  --bs-bg-opacity: 0.1;\n}\n\n.bg-opacity-25 {\n  --bs-bg-opacity: 0.25;\n}\n\n.bg-opacity-50 {\n  --bs-bg-opacity: 0.5;\n}\n\n.bg-opacity-75 {\n  --bs-bg-opacity: 0.75;\n}\n\n.bg-opacity-100 {\n  --bs-bg-opacity: 1;\n}\n\n.bg-gradient {\n  background-image: var(--bs-gradient) !important;\n}\n\n.user-select-all {\n  -webkit-user-select: all !important;\n  -moz-user-select: all !important;\n  user-select: all !important;\n}\n\n.user-select-auto {\n  -webkit-user-select: auto !important;\n  -moz-user-select: auto !important;\n  user-select: auto !important;\n}\n\n.user-select-none {\n  -webkit-user-select: none !important;\n  -moz-user-select: none !important;\n  user-select: none !important;\n}\n\n.pe-none {\n  pointer-events: none !important;\n}\n\n.pe-auto {\n  pointer-events: auto !important;\n}\n\n.rounded {\n  border-radius: 0.25rem !important;\n}\n\n.rounded-0 {\n  border-radius: 0 !important;\n}\n\n.rounded-1 {\n  border-radius: 0.2rem !important;\n}\n\n.rounded-2 {\n  border-radius: 0.25rem !important;\n}\n\n.rounded-3 {\n  border-radius: 0.3rem !important;\n}\n\n.rounded-circle {\n  border-radius: 50% !important;\n}\n\n.rounded-pill {\n  border-radius: 50rem !important;\n}\n\n.rounded-top {\n  border-top-right-radius: 0.25rem !important;\n  border-top-left-radius: 0.25rem !important;\n}\n\n.rounded-end {\n  border-top-left-radius: 0.25rem !important;\n  border-bottom-left-radius: 0.25rem !important;\n}\n\n.rounded-bottom {\n  border-bottom-left-radius: 0.25rem !important;\n  border-bottom-right-radius: 0.25rem !important;\n}\n\n.rounded-start {\n  border-bottom-right-radius: 0.25rem !important;\n  border-top-right-radius: 0.25rem !important;\n}\n\n.visible {\n  visibility: visible !important;\n}\n\n.invisible {\n  visibility: hidden !important;\n}\n\n@media (min-width: 576px) {\n  .float-sm-start {\n    float: right !important;\n  }\n\n  .float-sm-end {\n    float: left !important;\n  }\n\n  .float-sm-none {\n    float: none !important;\n  }\n\n  .d-sm-inline {\n    display: inline !important;\n  }\n\n  .d-sm-inline-block {\n    display: inline-block !important;\n  }\n\n  .d-sm-block {\n    display: block !important;\n  }\n\n  .d-sm-grid {\n    display: grid !important;\n  }\n\n  .d-sm-table {\n    display: table !important;\n  }\n\n  .d-sm-table-row {\n    display: table-row !important;\n  }\n\n  .d-sm-table-cell {\n    display: table-cell !important;\n  }\n\n  .d-sm-flex {\n    display: flex !important;\n  }\n\n  .d-sm-inline-flex {\n    display: inline-flex !important;\n  }\n\n  .d-sm-none {\n    display: none !important;\n  }\n\n  .flex-sm-fill {\n    flex: 1 1 auto !important;\n  }\n\n  .flex-sm-row {\n    flex-direction: row !important;\n  }\n\n  .flex-sm-column {\n    flex-direction: column !important;\n  }\n\n  .flex-sm-row-reverse {\n    flex-direction: row-reverse !important;\n  }\n\n  .flex-sm-column-reverse {\n    flex-direction: column-reverse !important;\n  }\n\n  .flex-sm-grow-0 {\n    flex-grow: 0 !important;\n  }\n\n  .flex-sm-grow-1 {\n    flex-grow: 1 !important;\n  }\n\n  .flex-sm-shrink-0 {\n    flex-shrink: 0 !important;\n  }\n\n  .flex-sm-shrink-1 {\n    flex-shrink: 1 !important;\n  }\n\n  .flex-sm-wrap {\n    flex-wrap: wrap !important;\n  }\n\n  .flex-sm-nowrap {\n    flex-wrap: nowrap !important;\n  }\n\n  .flex-sm-wrap-reverse {\n    flex-wrap: wrap-reverse !important;\n  }\n\n  .gap-sm-0 {\n    gap: 0 !important;\n  }\n\n  .gap-sm-1 {\n    gap: 0.25rem !important;\n  }\n\n  .gap-sm-2 {\n    gap: 0.5rem !important;\n  }\n\n  .gap-sm-3 {\n    gap: 1rem !important;\n  }\n\n  .gap-sm-4 {\n    gap: 1.5rem !important;\n  }\n\n  .gap-sm-5 {\n    gap: 3rem !important;\n  }\n\n  .justify-content-sm-start {\n    justify-content: flex-start !important;\n  }\n\n  .justify-content-sm-end {\n    justify-content: flex-end !important;\n  }\n\n  .justify-content-sm-center {\n    justify-content: center !important;\n  }\n\n  .justify-content-sm-between {\n    justify-content: space-between !important;\n  }\n\n  .justify-content-sm-around {\n    justify-content: space-around !important;\n  }\n\n  .justify-content-sm-evenly {\n    justify-content: space-evenly !important;\n  }\n\n  .align-items-sm-start {\n    align-items: flex-start !important;\n  }\n\n  .align-items-sm-end {\n    align-items: flex-end !important;\n  }\n\n  .align-items-sm-center {\n    align-items: center !important;\n  }\n\n  .align-items-sm-baseline {\n    align-items: baseline !important;\n  }\n\n  .align-items-sm-stretch {\n    align-items: stretch !important;\n  }\n\n  .align-content-sm-start {\n    align-content: flex-start !important;\n  }\n\n  .align-content-sm-end {\n    align-content: flex-end !important;\n  }\n\n  .align-content-sm-center {\n    align-content: center !important;\n  }\n\n  .align-content-sm-between {\n    align-content: space-between !important;\n  }\n\n  .align-content-sm-around {\n    align-content: space-around !important;\n  }\n\n  .align-content-sm-stretch {\n    align-content: stretch !important;\n  }\n\n  .align-self-sm-auto {\n    align-self: auto !important;\n  }\n\n  .align-self-sm-start {\n    align-self: flex-start !important;\n  }\n\n  .align-self-sm-end {\n    align-self: flex-end !important;\n  }\n\n  .align-self-sm-center {\n    align-self: center !important;\n  }\n\n  .align-self-sm-baseline {\n    align-self: baseline !important;\n  }\n\n  .align-self-sm-stretch {\n    align-self: stretch !important;\n  }\n\n  .order-sm-first {\n    order: -1 !important;\n  }\n\n  .order-sm-0 {\n    order: 0 !important;\n  }\n\n  .order-sm-1 {\n    order: 1 !important;\n  }\n\n  .order-sm-2 {\n    order: 2 !important;\n  }\n\n  .order-sm-3 {\n    order: 3 !important;\n  }\n\n  .order-sm-4 {\n    order: 4 !important;\n  }\n\n  .order-sm-5 {\n    order: 5 !important;\n  }\n\n  .order-sm-last {\n    order: 6 !important;\n  }\n\n  .m-sm-0 {\n    margin: 0 !important;\n  }\n\n  .m-sm-1 {\n    margin: 0.25rem !important;\n  }\n\n  .m-sm-2 {\n    margin: 0.5rem !important;\n  }\n\n  .m-sm-3 {\n    margin: 1rem !important;\n  }\n\n  .m-sm-4 {\n    margin: 1.5rem !important;\n  }\n\n  .m-sm-5 {\n    margin: 3rem !important;\n  }\n\n  .m-sm-auto {\n    margin: auto !important;\n  }\n\n  .mx-sm-0 {\n    margin-left: 0 !important;\n    margin-right: 0 !important;\n  }\n\n  .mx-sm-1 {\n    margin-left: 0.25rem !important;\n    margin-right: 0.25rem !important;\n  }\n\n  .mx-sm-2 {\n    margin-left: 0.5rem !important;\n    margin-right: 0.5rem !important;\n  }\n\n  .mx-sm-3 {\n    margin-left: 1rem !important;\n    margin-right: 1rem !important;\n  }\n\n  .mx-sm-4 {\n    margin-left: 1.5rem !important;\n    margin-right: 1.5rem !important;\n  }\n\n  .mx-sm-5 {\n    margin-left: 3rem !important;\n    margin-right: 3rem !important;\n  }\n\n  .mx-sm-auto {\n    margin-left: auto !important;\n    margin-right: auto !important;\n  }\n\n  .my-sm-0 {\n    margin-top: 0 !important;\n    margin-bottom: 0 !important;\n  }\n\n  .my-sm-1 {\n    margin-top: 0.25rem !important;\n    margin-bottom: 0.25rem !important;\n  }\n\n  .my-sm-2 {\n    margin-top: 0.5rem !important;\n    margin-bottom: 0.5rem !important;\n  }\n\n  .my-sm-3 {\n    margin-top: 1rem !important;\n    margin-bottom: 1rem !important;\n  }\n\n  .my-sm-4 {\n    margin-top: 1.5rem !important;\n    margin-bottom: 1.5rem !important;\n  }\n\n  .my-sm-5 {\n    margin-top: 3rem !important;\n    margin-bottom: 3rem !important;\n  }\n\n  .my-sm-auto {\n    margin-top: auto !important;\n    margin-bottom: auto !important;\n  }\n\n  .mt-sm-0 {\n    margin-top: 0 !important;\n  }\n\n  .mt-sm-1 {\n    margin-top: 0.25rem !important;\n  }\n\n  .mt-sm-2 {\n    margin-top: 0.5rem !important;\n  }\n\n  .mt-sm-3 {\n    margin-top: 1rem !important;\n  }\n\n  .mt-sm-4 {\n    margin-top: 1.5rem !important;\n  }\n\n  .mt-sm-5 {\n    margin-top: 3rem !important;\n  }\n\n  .mt-sm-auto {\n    margin-top: auto !important;\n  }\n\n  .me-sm-0 {\n    margin-left: 0 !important;\n  }\n\n  .me-sm-1 {\n    margin-left: 0.25rem !important;\n  }\n\n  .me-sm-2 {\n    margin-left: 0.5rem !important;\n  }\n\n  .me-sm-3 {\n    margin-left: 1rem !important;\n  }\n\n  .me-sm-4 {\n    margin-left: 1.5rem !important;\n  }\n\n  .me-sm-5 {\n    margin-left: 3rem !important;\n  }\n\n  .me-sm-auto {\n    margin-left: auto !important;\n  }\n\n  .mb-sm-0 {\n    margin-bottom: 0 !important;\n  }\n\n  .mb-sm-1 {\n    margin-bottom: 0.25rem !important;\n  }\n\n  .mb-sm-2 {\n    margin-bottom: 0.5rem !important;\n  }\n\n  .mb-sm-3 {\n    margin-bottom: 1rem !important;\n  }\n\n  .mb-sm-4 {\n    margin-bottom: 1.5rem !important;\n  }\n\n  .mb-sm-5 {\n    margin-bottom: 3rem !important;\n  }\n\n  .mb-sm-auto {\n    margin-bottom: auto !important;\n  }\n\n  .ms-sm-0 {\n    margin-right: 0 !important;\n  }\n\n  .ms-sm-1 {\n    margin-right: 0.25rem !important;\n  }\n\n  .ms-sm-2 {\n    margin-right: 0.5rem !important;\n  }\n\n  .ms-sm-3 {\n    margin-right: 1rem !important;\n  }\n\n  .ms-sm-4 {\n    margin-right: 1.5rem !important;\n  }\n\n  .ms-sm-5 {\n    margin-right: 3rem !important;\n  }\n\n  .ms-sm-auto {\n    margin-right: auto !important;\n  }\n\n  .p-sm-0 {\n    padding: 0 !important;\n  }\n\n  .p-sm-1 {\n    padding: 0.25rem !important;\n  }\n\n  .p-sm-2 {\n    padding: 0.5rem !important;\n  }\n\n  .p-sm-3 {\n    padding: 1rem !important;\n  }\n\n  .p-sm-4 {\n    padding: 1.5rem !important;\n  }\n\n  .p-sm-5 {\n    padding: 3rem !important;\n  }\n\n  .px-sm-0 {\n    padding-left: 0 !important;\n    padding-right: 0 !important;\n  }\n\n  .px-sm-1 {\n    padding-left: 0.25rem !important;\n    padding-right: 0.25rem !important;\n  }\n\n  .px-sm-2 {\n    padding-left: 0.5rem !important;\n    padding-right: 0.5rem !important;\n  }\n\n  .px-sm-3 {\n    padding-left: 1rem !important;\n    padding-right: 1rem !important;\n  }\n\n  .px-sm-4 {\n    padding-left: 1.5rem !important;\n    padding-right: 1.5rem !important;\n  }\n\n  .px-sm-5 {\n    padding-left: 3rem !important;\n    padding-right: 3rem !important;\n  }\n\n  .py-sm-0 {\n    padding-top: 0 !important;\n    padding-bottom: 0 !important;\n  }\n\n  .py-sm-1 {\n    padding-top: 0.25rem !important;\n    padding-bottom: 0.25rem !important;\n  }\n\n  .py-sm-2 {\n    padding-top: 0.5rem !important;\n    padding-bottom: 0.5rem !important;\n  }\n\n  .py-sm-3 {\n    padding-top: 1rem !important;\n    padding-bottom: 1rem !important;\n  }\n\n  .py-sm-4 {\n    padding-top: 1.5rem !important;\n    padding-bottom: 1.5rem !important;\n  }\n\n  .py-sm-5 {\n    padding-top: 3rem !important;\n    padding-bottom: 3rem !important;\n  }\n\n  .pt-sm-0 {\n    padding-top: 0 !important;\n  }\n\n  .pt-sm-1 {\n    padding-top: 0.25rem !important;\n  }\n\n  .pt-sm-2 {\n    padding-top: 0.5rem !important;\n  }\n\n  .pt-sm-3 {\n    padding-top: 1rem !important;\n  }\n\n  .pt-sm-4 {\n    padding-top: 1.5rem !important;\n  }\n\n  .pt-sm-5 {\n    padding-top: 3rem !important;\n  }\n\n  .pe-sm-0 {\n    padding-left: 0 !important;\n  }\n\n  .pe-sm-1 {\n    padding-left: 0.25rem !important;\n  }\n\n  .pe-sm-2 {\n    padding-left: 0.5rem !important;\n  }\n\n  .pe-sm-3 {\n    padding-left: 1rem !important;\n  }\n\n  .pe-sm-4 {\n    padding-left: 1.5rem !important;\n  }\n\n  .pe-sm-5 {\n    padding-left: 3rem !important;\n  }\n\n  .pb-sm-0 {\n    padding-bottom: 0 !important;\n  }\n\n  .pb-sm-1 {\n    padding-bottom: 0.25rem !important;\n  }\n\n  .pb-sm-2 {\n    padding-bottom: 0.5rem !important;\n  }\n\n  .pb-sm-3 {\n    padding-bottom: 1rem !important;\n  }\n\n  .pb-sm-4 {\n    padding-bottom: 1.5rem !important;\n  }\n\n  .pb-sm-5 {\n    padding-bottom: 3rem !important;\n  }\n\n  .ps-sm-0 {\n    padding-right: 0 !important;\n  }\n\n  .ps-sm-1 {\n    padding-right: 0.25rem !important;\n  }\n\n  .ps-sm-2 {\n    padding-right: 0.5rem !important;\n  }\n\n  .ps-sm-3 {\n    padding-right: 1rem !important;\n  }\n\n  .ps-sm-4 {\n    padding-right: 1.5rem !important;\n  }\n\n  .ps-sm-5 {\n    padding-right: 3rem !important;\n  }\n\n  .text-sm-start {\n    text-align: right !important;\n  }\n\n  .text-sm-end {\n    text-align: left !important;\n  }\n\n  .text-sm-center {\n    text-align: center !important;\n  }\n}\n@media (min-width: 768px) {\n  .float-md-start {\n    float: right !important;\n  }\n\n  .float-md-end {\n    float: left !important;\n  }\n\n  .float-md-none {\n    float: none !important;\n  }\n\n  .d-md-inline {\n    display: inline !important;\n  }\n\n  .d-md-inline-block {\n    display: inline-block !important;\n  }\n\n  .d-md-block {\n    display: block !important;\n  }\n\n  .d-md-grid {\n    display: grid !important;\n  }\n\n  .d-md-table {\n    display: table !important;\n  }\n\n  .d-md-table-row {\n    display: table-row !important;\n  }\n\n  .d-md-table-cell {\n    display: table-cell !important;\n  }\n\n  .d-md-flex {\n    display: flex !important;\n  }\n\n  .d-md-inline-flex {\n    display: inline-flex !important;\n  }\n\n  .d-md-none {\n    display: none !important;\n  }\n\n  .flex-md-fill {\n    flex: 1 1 auto !important;\n  }\n\n  .flex-md-row {\n    flex-direction: row !important;\n  }\n\n  .flex-md-column {\n    flex-direction: column !important;\n  }\n\n  .flex-md-row-reverse {\n    flex-direction: row-reverse !important;\n  }\n\n  .flex-md-column-reverse {\n    flex-direction: column-reverse !important;\n  }\n\n  .flex-md-grow-0 {\n    flex-grow: 0 !important;\n  }\n\n  .flex-md-grow-1 {\n    flex-grow: 1 !important;\n  }\n\n  .flex-md-shrink-0 {\n    flex-shrink: 0 !important;\n  }\n\n  .flex-md-shrink-1 {\n    flex-shrink: 1 !important;\n  }\n\n  .flex-md-wrap {\n    flex-wrap: wrap !important;\n  }\n\n  .flex-md-nowrap {\n    flex-wrap: nowrap !important;\n  }\n\n  .flex-md-wrap-reverse {\n    flex-wrap: wrap-reverse !important;\n  }\n\n  .gap-md-0 {\n    gap: 0 !important;\n  }\n\n  .gap-md-1 {\n    gap: 0.25rem !important;\n  }\n\n  .gap-md-2 {\n    gap: 0.5rem !important;\n  }\n\n  .gap-md-3 {\n    gap: 1rem !important;\n  }\n\n  .gap-md-4 {\n    gap: 1.5rem !important;\n  }\n\n  .gap-md-5 {\n    gap: 3rem !important;\n  }\n\n  .justify-content-md-start {\n    justify-content: flex-start !important;\n  }\n\n  .justify-content-md-end {\n    justify-content: flex-end !important;\n  }\n\n  .justify-content-md-center {\n    justify-content: center !important;\n  }\n\n  .justify-content-md-between {\n    justify-content: space-between !important;\n  }\n\n  .justify-content-md-around {\n    justify-content: space-around !important;\n  }\n\n  .justify-content-md-evenly {\n    justify-content: space-evenly !important;\n  }\n\n  .align-items-md-start {\n    align-items: flex-start !important;\n  }\n\n  .align-items-md-end {\n    align-items: flex-end !important;\n  }\n\n  .align-items-md-center {\n    align-items: center !important;\n  }\n\n  .align-items-md-baseline {\n    align-items: baseline !important;\n  }\n\n  .align-items-md-stretch {\n    align-items: stretch !important;\n  }\n\n  .align-content-md-start {\n    align-content: flex-start !important;\n  }\n\n  .align-content-md-end {\n    align-content: flex-end !important;\n  }\n\n  .align-content-md-center {\n    align-content: center !important;\n  }\n\n  .align-content-md-between {\n    align-content: space-between !important;\n  }\n\n  .align-content-md-around {\n    align-content: space-around !important;\n  }\n\n  .align-content-md-stretch {\n    align-content: stretch !important;\n  }\n\n  .align-self-md-auto {\n    align-self: auto !important;\n  }\n\n  .align-self-md-start {\n    align-self: flex-start !important;\n  }\n\n  .align-self-md-end {\n    align-self: flex-end !important;\n  }\n\n  .align-self-md-center {\n    align-self: center !important;\n  }\n\n  .align-self-md-baseline {\n    align-self: baseline !important;\n  }\n\n  .align-self-md-stretch {\n    align-self: stretch !important;\n  }\n\n  .order-md-first {\n    order: -1 !important;\n  }\n\n  .order-md-0 {\n    order: 0 !important;\n  }\n\n  .order-md-1 {\n    order: 1 !important;\n  }\n\n  .order-md-2 {\n    order: 2 !important;\n  }\n\n  .order-md-3 {\n    order: 3 !important;\n  }\n\n  .order-md-4 {\n    order: 4 !important;\n  }\n\n  .order-md-5 {\n    order: 5 !important;\n  }\n\n  .order-md-last {\n    order: 6 !important;\n  }\n\n  .m-md-0 {\n    margin: 0 !important;\n  }\n\n  .m-md-1 {\n    margin: 0.25rem !important;\n  }\n\n  .m-md-2 {\n    margin: 0.5rem !important;\n  }\n\n  .m-md-3 {\n    margin: 1rem !important;\n  }\n\n  .m-md-4 {\n    margin: 1.5rem !important;\n  }\n\n  .m-md-5 {\n    margin: 3rem !important;\n  }\n\n  .m-md-auto {\n    margin: auto !important;\n  }\n\n  .mx-md-0 {\n    margin-left: 0 !important;\n    margin-right: 0 !important;\n  }\n\n  .mx-md-1 {\n    margin-left: 0.25rem !important;\n    margin-right: 0.25rem !important;\n  }\n\n  .mx-md-2 {\n    margin-left: 0.5rem !important;\n    margin-right: 0.5rem !important;\n  }\n\n  .mx-md-3 {\n    margin-left: 1rem !important;\n    margin-right: 1rem !important;\n  }\n\n  .mx-md-4 {\n    margin-left: 1.5rem !important;\n    margin-right: 1.5rem !important;\n  }\n\n  .mx-md-5 {\n    margin-left: 3rem !important;\n    margin-right: 3rem !important;\n  }\n\n  .mx-md-auto {\n    margin-left: auto !important;\n    margin-right: auto !important;\n  }\n\n  .my-md-0 {\n    margin-top: 0 !important;\n    margin-bottom: 0 !important;\n  }\n\n  .my-md-1 {\n    margin-top: 0.25rem !important;\n    margin-bottom: 0.25rem !important;\n  }\n\n  .my-md-2 {\n    margin-top: 0.5rem !important;\n    margin-bottom: 0.5rem !important;\n  }\n\n  .my-md-3 {\n    margin-top: 1rem !important;\n    margin-bottom: 1rem !important;\n  }\n\n  .my-md-4 {\n    margin-top: 1.5rem !important;\n    margin-bottom: 1.5rem !important;\n  }\n\n  .my-md-5 {\n    margin-top: 3rem !important;\n    margin-bottom: 3rem !important;\n  }\n\n  .my-md-auto {\n    margin-top: auto !important;\n    margin-bottom: auto !important;\n  }\n\n  .mt-md-0 {\n    margin-top: 0 !important;\n  }\n\n  .mt-md-1 {\n    margin-top: 0.25rem !important;\n  }\n\n  .mt-md-2 {\n    margin-top: 0.5rem !important;\n  }\n\n  .mt-md-3 {\n    margin-top: 1rem !important;\n  }\n\n  .mt-md-4 {\n    margin-top: 1.5rem !important;\n  }\n\n  .mt-md-5 {\n    margin-top: 3rem !important;\n  }\n\n  .mt-md-auto {\n    margin-top: auto !important;\n  }\n\n  .me-md-0 {\n    margin-left: 0 !important;\n  }\n\n  .me-md-1 {\n    margin-left: 0.25rem !important;\n  }\n\n  .me-md-2 {\n    margin-left: 0.5rem !important;\n  }\n\n  .me-md-3 {\n    margin-left: 1rem !important;\n  }\n\n  .me-md-4 {\n    margin-left: 1.5rem !important;\n  }\n\n  .me-md-5 {\n    margin-left: 3rem !important;\n  }\n\n  .me-md-auto {\n    margin-left: auto !important;\n  }\n\n  .mb-md-0 {\n    margin-bottom: 0 !important;\n  }\n\n  .mb-md-1 {\n    margin-bottom: 0.25rem !important;\n  }\n\n  .mb-md-2 {\n    margin-bottom: 0.5rem !important;\n  }\n\n  .mb-md-3 {\n    margin-bottom: 1rem !important;\n  }\n\n  .mb-md-4 {\n    margin-bottom: 1.5rem !important;\n  }\n\n  .mb-md-5 {\n    margin-bottom: 3rem !important;\n  }\n\n  .mb-md-auto {\n    margin-bottom: auto !important;\n  }\n\n  .ms-md-0 {\n    margin-right: 0 !important;\n  }\n\n  .ms-md-1 {\n    margin-right: 0.25rem !important;\n  }\n\n  .ms-md-2 {\n    margin-right: 0.5rem !important;\n  }\n\n  .ms-md-3 {\n    margin-right: 1rem !important;\n  }\n\n  .ms-md-4 {\n    margin-right: 1.5rem !important;\n  }\n\n  .ms-md-5 {\n    margin-right: 3rem !important;\n  }\n\n  .ms-md-auto {\n    margin-right: auto !important;\n  }\n\n  .p-md-0 {\n    padding: 0 !important;\n  }\n\n  .p-md-1 {\n    padding: 0.25rem !important;\n  }\n\n  .p-md-2 {\n    padding: 0.5rem !important;\n  }\n\n  .p-md-3 {\n    padding: 1rem !important;\n  }\n\n  .p-md-4 {\n    padding: 1.5rem !important;\n  }\n\n  .p-md-5 {\n    padding: 3rem !important;\n  }\n\n  .px-md-0 {\n    padding-left: 0 !important;\n    padding-right: 0 !important;\n  }\n\n  .px-md-1 {\n    padding-left: 0.25rem !important;\n    padding-right: 0.25rem !important;\n  }\n\n  .px-md-2 {\n    padding-left: 0.5rem !important;\n    padding-right: 0.5rem !important;\n  }\n\n  .px-md-3 {\n    padding-left: 1rem !important;\n    padding-right: 1rem !important;\n  }\n\n  .px-md-4 {\n    padding-left: 1.5rem !important;\n    padding-right: 1.5rem !important;\n  }\n\n  .px-md-5 {\n    padding-left: 3rem !important;\n    padding-right: 3rem !important;\n  }\n\n  .py-md-0 {\n    padding-top: 0 !important;\n    padding-bottom: 0 !important;\n  }\n\n  .py-md-1 {\n    padding-top: 0.25rem !important;\n    padding-bottom: 0.25rem !important;\n  }\n\n  .py-md-2 {\n    padding-top: 0.5rem !important;\n    padding-bottom: 0.5rem !important;\n  }\n\n  .py-md-3 {\n    padding-top: 1rem !important;\n    padding-bottom: 1rem !important;\n  }\n\n  .py-md-4 {\n    padding-top: 1.5rem !important;\n    padding-bottom: 1.5rem !important;\n  }\n\n  .py-md-5 {\n    padding-top: 3rem !important;\n    padding-bottom: 3rem !important;\n  }\n\n  .pt-md-0 {\n    padding-top: 0 !important;\n  }\n\n  .pt-md-1 {\n    padding-top: 0.25rem !important;\n  }\n\n  .pt-md-2 {\n    padding-top: 0.5rem !important;\n  }\n\n  .pt-md-3 {\n    padding-top: 1rem !important;\n  }\n\n  .pt-md-4 {\n    padding-top: 1.5rem !important;\n  }\n\n  .pt-md-5 {\n    padding-top: 3rem !important;\n  }\n\n  .pe-md-0 {\n    padding-left: 0 !important;\n  }\n\n  .pe-md-1 {\n    padding-left: 0.25rem !important;\n  }\n\n  .pe-md-2 {\n    padding-left: 0.5rem !important;\n  }\n\n  .pe-md-3 {\n    padding-left: 1rem !important;\n  }\n\n  .pe-md-4 {\n    padding-left: 1.5rem !important;\n  }\n\n  .pe-md-5 {\n    padding-left: 3rem !important;\n  }\n\n  .pb-md-0 {\n    padding-bottom: 0 !important;\n  }\n\n  .pb-md-1 {\n    padding-bottom: 0.25rem !important;\n  }\n\n  .pb-md-2 {\n    padding-bottom: 0.5rem !important;\n  }\n\n  .pb-md-3 {\n    padding-bottom: 1rem !important;\n  }\n\n  .pb-md-4 {\n    padding-bottom: 1.5rem !important;\n  }\n\n  .pb-md-5 {\n    padding-bottom: 3rem !important;\n  }\n\n  .ps-md-0 {\n    padding-right: 0 !important;\n  }\n\n  .ps-md-1 {\n    padding-right: 0.25rem !important;\n  }\n\n  .ps-md-2 {\n    padding-right: 0.5rem !important;\n  }\n\n  .ps-md-3 {\n    padding-right: 1rem !important;\n  }\n\n  .ps-md-4 {\n    padding-right: 1.5rem !important;\n  }\n\n  .ps-md-5 {\n    padding-right: 3rem !important;\n  }\n\n  .text-md-start {\n    text-align: right !important;\n  }\n\n  .text-md-end {\n    text-align: left !important;\n  }\n\n  .text-md-center {\n    text-align: center !important;\n  }\n}\n@media (min-width: 992px) {\n  .float-lg-start {\n    float: right !important;\n  }\n\n  .float-lg-end {\n    float: left !important;\n  }\n\n  .float-lg-none {\n    float: none !important;\n  }\n\n  .d-lg-inline {\n    display: inline !important;\n  }\n\n  .d-lg-inline-block {\n    display: inline-block !important;\n  }\n\n  .d-lg-block {\n    display: block !important;\n  }\n\n  .d-lg-grid {\n    display: grid !important;\n  }\n\n  .d-lg-table {\n    display: table !important;\n  }\n\n  .d-lg-table-row {\n    display: table-row !important;\n  }\n\n  .d-lg-table-cell {\n    display: table-cell !important;\n  }\n\n  .d-lg-flex {\n    display: flex !important;\n  }\n\n  .d-lg-inline-flex {\n    display: inline-flex !important;\n  }\n\n  .d-lg-none {\n    display: none !important;\n  }\n\n  .flex-lg-fill {\n    flex: 1 1 auto !important;\n  }\n\n  .flex-lg-row {\n    flex-direction: row !important;\n  }\n\n  .flex-lg-column {\n    flex-direction: column !important;\n  }\n\n  .flex-lg-row-reverse {\n    flex-direction: row-reverse !important;\n  }\n\n  .flex-lg-column-reverse {\n    flex-direction: column-reverse !important;\n  }\n\n  .flex-lg-grow-0 {\n    flex-grow: 0 !important;\n  }\n\n  .flex-lg-grow-1 {\n    flex-grow: 1 !important;\n  }\n\n  .flex-lg-shrink-0 {\n    flex-shrink: 0 !important;\n  }\n\n  .flex-lg-shrink-1 {\n    flex-shrink: 1 !important;\n  }\n\n  .flex-lg-wrap {\n    flex-wrap: wrap !important;\n  }\n\n  .flex-lg-nowrap {\n    flex-wrap: nowrap !important;\n  }\n\n  .flex-lg-wrap-reverse {\n    flex-wrap: wrap-reverse !important;\n  }\n\n  .gap-lg-0 {\n    gap: 0 !important;\n  }\n\n  .gap-lg-1 {\n    gap: 0.25rem !important;\n  }\n\n  .gap-lg-2 {\n    gap: 0.5rem !important;\n  }\n\n  .gap-lg-3 {\n    gap: 1rem !important;\n  }\n\n  .gap-lg-4 {\n    gap: 1.5rem !important;\n  }\n\n  .gap-lg-5 {\n    gap: 3rem !important;\n  }\n\n  .justify-content-lg-start {\n    justify-content: flex-start !important;\n  }\n\n  .justify-content-lg-end {\n    justify-content: flex-end !important;\n  }\n\n  .justify-content-lg-center {\n    justify-content: center !important;\n  }\n\n  .justify-content-lg-between {\n    justify-content: space-between !important;\n  }\n\n  .justify-content-lg-around {\n    justify-content: space-around !important;\n  }\n\n  .justify-content-lg-evenly {\n    justify-content: space-evenly !important;\n  }\n\n  .align-items-lg-start {\n    align-items: flex-start !important;\n  }\n\n  .align-items-lg-end {\n    align-items: flex-end !important;\n  }\n\n  .align-items-lg-center {\n    align-items: center !important;\n  }\n\n  .align-items-lg-baseline {\n    align-items: baseline !important;\n  }\n\n  .align-items-lg-stretch {\n    align-items: stretch !important;\n  }\n\n  .align-content-lg-start {\n    align-content: flex-start !important;\n  }\n\n  .align-content-lg-end {\n    align-content: flex-end !important;\n  }\n\n  .align-content-lg-center {\n    align-content: center !important;\n  }\n\n  .align-content-lg-between {\n    align-content: space-between !important;\n  }\n\n  .align-content-lg-around {\n    align-content: space-around !important;\n  }\n\n  .align-content-lg-stretch {\n    align-content: stretch !important;\n  }\n\n  .align-self-lg-auto {\n    align-self: auto !important;\n  }\n\n  .align-self-lg-start {\n    align-self: flex-start !important;\n  }\n\n  .align-self-lg-end {\n    align-self: flex-end !important;\n  }\n\n  .align-self-lg-center {\n    align-self: center !important;\n  }\n\n  .align-self-lg-baseline {\n    align-self: baseline !important;\n  }\n\n  .align-self-lg-stretch {\n    align-self: stretch !important;\n  }\n\n  .order-lg-first {\n    order: -1 !important;\n  }\n\n  .order-lg-0 {\n    order: 0 !important;\n  }\n\n  .order-lg-1 {\n    order: 1 !important;\n  }\n\n  .order-lg-2 {\n    order: 2 !important;\n  }\n\n  .order-lg-3 {\n    order: 3 !important;\n  }\n\n  .order-lg-4 {\n    order: 4 !important;\n  }\n\n  .order-lg-5 {\n    order: 5 !important;\n  }\n\n  .order-lg-last {\n    order: 6 !important;\n  }\n\n  .m-lg-0 {\n    margin: 0 !important;\n  }\n\n  .m-lg-1 {\n    margin: 0.25rem !important;\n  }\n\n  .m-lg-2 {\n    margin: 0.5rem !important;\n  }\n\n  .m-lg-3 {\n    margin: 1rem !important;\n  }\n\n  .m-lg-4 {\n    margin: 1.5rem !important;\n  }\n\n  .m-lg-5 {\n    margin: 3rem !important;\n  }\n\n  .m-lg-auto {\n    margin: auto !important;\n  }\n\n  .mx-lg-0 {\n    margin-left: 0 !important;\n    margin-right: 0 !important;\n  }\n\n  .mx-lg-1 {\n    margin-left: 0.25rem !important;\n    margin-right: 0.25rem !important;\n  }\n\n  .mx-lg-2 {\n    margin-left: 0.5rem !important;\n    margin-right: 0.5rem !important;\n  }\n\n  .mx-lg-3 {\n    margin-left: 1rem !important;\n    margin-right: 1rem !important;\n  }\n\n  .mx-lg-4 {\n    margin-left: 1.5rem !important;\n    margin-right: 1.5rem !important;\n  }\n\n  .mx-lg-5 {\n    margin-left: 3rem !important;\n    margin-right: 3rem !important;\n  }\n\n  .mx-lg-auto {\n    margin-left: auto !important;\n    margin-right: auto !important;\n  }\n\n  .my-lg-0 {\n    margin-top: 0 !important;\n    margin-bottom: 0 !important;\n  }\n\n  .my-lg-1 {\n    margin-top: 0.25rem !important;\n    margin-bottom: 0.25rem !important;\n  }\n\n  .my-lg-2 {\n    margin-top: 0.5rem !important;\n    margin-bottom: 0.5rem !important;\n  }\n\n  .my-lg-3 {\n    margin-top: 1rem !important;\n    margin-bottom: 1rem !important;\n  }\n\n  .my-lg-4 {\n    margin-top: 1.5rem !important;\n    margin-bottom: 1.5rem !important;\n  }\n\n  .my-lg-5 {\n    margin-top: 3rem !important;\n    margin-bottom: 3rem !important;\n  }\n\n  .my-lg-auto {\n    margin-top: auto !important;\n    margin-bottom: auto !important;\n  }\n\n  .mt-lg-0 {\n    margin-top: 0 !important;\n  }\n\n  .mt-lg-1 {\n    margin-top: 0.25rem !important;\n  }\n\n  .mt-lg-2 {\n    margin-top: 0.5rem !important;\n  }\n\n  .mt-lg-3 {\n    margin-top: 1rem !important;\n  }\n\n  .mt-lg-4 {\n    margin-top: 1.5rem !important;\n  }\n\n  .mt-lg-5 {\n    margin-top: 3rem !important;\n  }\n\n  .mt-lg-auto {\n    margin-top: auto !important;\n  }\n\n  .me-lg-0 {\n    margin-left: 0 !important;\n  }\n\n  .me-lg-1 {\n    margin-left: 0.25rem !important;\n  }\n\n  .me-lg-2 {\n    margin-left: 0.5rem !important;\n  }\n\n  .me-lg-3 {\n    margin-left: 1rem !important;\n  }\n\n  .me-lg-4 {\n    margin-left: 1.5rem !important;\n  }\n\n  .me-lg-5 {\n    margin-left: 3rem !important;\n  }\n\n  .me-lg-auto {\n    margin-left: auto !important;\n  }\n\n  .mb-lg-0 {\n    margin-bottom: 0 !important;\n  }\n\n  .mb-lg-1 {\n    margin-bottom: 0.25rem !important;\n  }\n\n  .mb-lg-2 {\n    margin-bottom: 0.5rem !important;\n  }\n\n  .mb-lg-3 {\n    margin-bottom: 1rem !important;\n  }\n\n  .mb-lg-4 {\n    margin-bottom: 1.5rem !important;\n  }\n\n  .mb-lg-5 {\n    margin-bottom: 3rem !important;\n  }\n\n  .mb-lg-auto {\n    margin-bottom: auto !important;\n  }\n\n  .ms-lg-0 {\n    margin-right: 0 !important;\n  }\n\n  .ms-lg-1 {\n    margin-right: 0.25rem !important;\n  }\n\n  .ms-lg-2 {\n    margin-right: 0.5rem !important;\n  }\n\n  .ms-lg-3 {\n    margin-right: 1rem !important;\n  }\n\n  .ms-lg-4 {\n    margin-right: 1.5rem !important;\n  }\n\n  .ms-lg-5 {\n    margin-right: 3rem !important;\n  }\n\n  .ms-lg-auto {\n    margin-right: auto !important;\n  }\n\n  .p-lg-0 {\n    padding: 0 !important;\n  }\n\n  .p-lg-1 {\n    padding: 0.25rem !important;\n  }\n\n  .p-lg-2 {\n    padding: 0.5rem !important;\n  }\n\n  .p-lg-3 {\n    padding: 1rem !important;\n  }\n\n  .p-lg-4 {\n    padding: 1.5rem !important;\n  }\n\n  .p-lg-5 {\n    padding: 3rem !important;\n  }\n\n  .px-lg-0 {\n    padding-left: 0 !important;\n    padding-right: 0 !important;\n  }\n\n  .px-lg-1 {\n    padding-left: 0.25rem !important;\n    padding-right: 0.25rem !important;\n  }\n\n  .px-lg-2 {\n    padding-left: 0.5rem !important;\n    padding-right: 0.5rem !important;\n  }\n\n  .px-lg-3 {\n    padding-left: 1rem !important;\n    padding-right: 1rem !important;\n  }\n\n  .px-lg-4 {\n    padding-left: 1.5rem !important;\n    padding-right: 1.5rem !important;\n  }\n\n  .px-lg-5 {\n    padding-left: 3rem !important;\n    padding-right: 3rem !important;\n  }\n\n  .py-lg-0 {\n    padding-top: 0 !important;\n    padding-bottom: 0 !important;\n  }\n\n  .py-lg-1 {\n    padding-top: 0.25rem !important;\n    padding-bottom: 0.25rem !important;\n  }\n\n  .py-lg-2 {\n    padding-top: 0.5rem !important;\n    padding-bottom: 0.5rem !important;\n  }\n\n  .py-lg-3 {\n    padding-top: 1rem !important;\n    padding-bottom: 1rem !important;\n  }\n\n  .py-lg-4 {\n    padding-top: 1.5rem !important;\n    padding-bottom: 1.5rem !important;\n  }\n\n  .py-lg-5 {\n    padding-top: 3rem !important;\n    padding-bottom: 3rem !important;\n  }\n\n  .pt-lg-0 {\n    padding-top: 0 !important;\n  }\n\n  .pt-lg-1 {\n    padding-top: 0.25rem !important;\n  }\n\n  .pt-lg-2 {\n    padding-top: 0.5rem !important;\n  }\n\n  .pt-lg-3 {\n    padding-top: 1rem !important;\n  }\n\n  .pt-lg-4 {\n    padding-top: 1.5rem !important;\n  }\n\n  .pt-lg-5 {\n    padding-top: 3rem !important;\n  }\n\n  .pe-lg-0 {\n    padding-left: 0 !important;\n  }\n\n  .pe-lg-1 {\n    padding-left: 0.25rem !important;\n  }\n\n  .pe-lg-2 {\n    padding-left: 0.5rem !important;\n  }\n\n  .pe-lg-3 {\n    padding-left: 1rem !important;\n  }\n\n  .pe-lg-4 {\n    padding-left: 1.5rem !important;\n  }\n\n  .pe-lg-5 {\n    padding-left: 3rem !important;\n  }\n\n  .pb-lg-0 {\n    padding-bottom: 0 !important;\n  }\n\n  .pb-lg-1 {\n    padding-bottom: 0.25rem !important;\n  }\n\n  .pb-lg-2 {\n    padding-bottom: 0.5rem !important;\n  }\n\n  .pb-lg-3 {\n    padding-bottom: 1rem !important;\n  }\n\n  .pb-lg-4 {\n    padding-bottom: 1.5rem !important;\n  }\n\n  .pb-lg-5 {\n    padding-bottom: 3rem !important;\n  }\n\n  .ps-lg-0 {\n    padding-right: 0 !important;\n  }\n\n  .ps-lg-1 {\n    padding-right: 0.25rem !important;\n  }\n\n  .ps-lg-2 {\n    padding-right: 0.5rem !important;\n  }\n\n  .ps-lg-3 {\n    padding-right: 1rem !important;\n  }\n\n  .ps-lg-4 {\n    padding-right: 1.5rem !important;\n  }\n\n  .ps-lg-5 {\n    padding-right: 3rem !important;\n  }\n\n  .text-lg-start {\n    text-align: right !important;\n  }\n\n  .text-lg-end {\n    text-align: left !important;\n  }\n\n  .text-lg-center {\n    text-align: center !important;\n  }\n}\n@media (min-width: 1200px) {\n  .float-xl-start {\n    float: right !important;\n  }\n\n  .float-xl-end {\n    float: left !important;\n  }\n\n  .float-xl-none {\n    float: none !important;\n  }\n\n  .d-xl-inline {\n    display: inline !important;\n  }\n\n  .d-xl-inline-block {\n    display: inline-block !important;\n  }\n\n  .d-xl-block {\n    display: block !important;\n  }\n\n  .d-xl-grid {\n    display: grid !important;\n  }\n\n  .d-xl-table {\n    display: table !important;\n  }\n\n  .d-xl-table-row {\n    display: table-row !important;\n  }\n\n  .d-xl-table-cell {\n    display: table-cell !important;\n  }\n\n  .d-xl-flex {\n    display: flex !important;\n  }\n\n  .d-xl-inline-flex {\n    display: inline-flex !important;\n  }\n\n  .d-xl-none {\n    display: none !important;\n  }\n\n  .flex-xl-fill {\n    flex: 1 1 auto !important;\n  }\n\n  .flex-xl-row {\n    flex-direction: row !important;\n  }\n\n  .flex-xl-column {\n    flex-direction: column !important;\n  }\n\n  .flex-xl-row-reverse {\n    flex-direction: row-reverse !important;\n  }\n\n  .flex-xl-column-reverse {\n    flex-direction: column-reverse !important;\n  }\n\n  .flex-xl-grow-0 {\n    flex-grow: 0 !important;\n  }\n\n  .flex-xl-grow-1 {\n    flex-grow: 1 !important;\n  }\n\n  .flex-xl-shrink-0 {\n    flex-shrink: 0 !important;\n  }\n\n  .flex-xl-shrink-1 {\n    flex-shrink: 1 !important;\n  }\n\n  .flex-xl-wrap {\n    flex-wrap: wrap !important;\n  }\n\n  .flex-xl-nowrap {\n    flex-wrap: nowrap !important;\n  }\n\n  .flex-xl-wrap-reverse {\n    flex-wrap: wrap-reverse !important;\n  }\n\n  .gap-xl-0 {\n    gap: 0 !important;\n  }\n\n  .gap-xl-1 {\n    gap: 0.25rem !important;\n  }\n\n  .gap-xl-2 {\n    gap: 0.5rem !important;\n  }\n\n  .gap-xl-3 {\n    gap: 1rem !important;\n  }\n\n  .gap-xl-4 {\n    gap: 1.5rem !important;\n  }\n\n  .gap-xl-5 {\n    gap: 3rem !important;\n  }\n\n  .justify-content-xl-start {\n    justify-content: flex-start !important;\n  }\n\n  .justify-content-xl-end {\n    justify-content: flex-end !important;\n  }\n\n  .justify-content-xl-center {\n    justify-content: center !important;\n  }\n\n  .justify-content-xl-between {\n    justify-content: space-between !important;\n  }\n\n  .justify-content-xl-around {\n    justify-content: space-around !important;\n  }\n\n  .justify-content-xl-evenly {\n    justify-content: space-evenly !important;\n  }\n\n  .align-items-xl-start {\n    align-items: flex-start !important;\n  }\n\n  .align-items-xl-end {\n    align-items: flex-end !important;\n  }\n\n  .align-items-xl-center {\n    align-items: center !important;\n  }\n\n  .align-items-xl-baseline {\n    align-items: baseline !important;\n  }\n\n  .align-items-xl-stretch {\n    align-items: stretch !important;\n  }\n\n  .align-content-xl-start {\n    align-content: flex-start !important;\n  }\n\n  .align-content-xl-end {\n    align-content: flex-end !important;\n  }\n\n  .align-content-xl-center {\n    align-content: center !important;\n  }\n\n  .align-content-xl-between {\n    align-content: space-between !important;\n  }\n\n  .align-content-xl-around {\n    align-content: space-around !important;\n  }\n\n  .align-content-xl-stretch {\n    align-content: stretch !important;\n  }\n\n  .align-self-xl-auto {\n    align-self: auto !important;\n  }\n\n  .align-self-xl-start {\n    align-self: flex-start !important;\n  }\n\n  .align-self-xl-end {\n    align-self: flex-end !important;\n  }\n\n  .align-self-xl-center {\n    align-self: center !important;\n  }\n\n  .align-self-xl-baseline {\n    align-self: baseline !important;\n  }\n\n  .align-self-xl-stretch {\n    align-self: stretch !important;\n  }\n\n  .order-xl-first {\n    order: -1 !important;\n  }\n\n  .order-xl-0 {\n    order: 0 !important;\n  }\n\n  .order-xl-1 {\n    order: 1 !important;\n  }\n\n  .order-xl-2 {\n    order: 2 !important;\n  }\n\n  .order-xl-3 {\n    order: 3 !important;\n  }\n\n  .order-xl-4 {\n    order: 4 !important;\n  }\n\n  .order-xl-5 {\n    order: 5 !important;\n  }\n\n  .order-xl-last {\n    order: 6 !important;\n  }\n\n  .m-xl-0 {\n    margin: 0 !important;\n  }\n\n  .m-xl-1 {\n    margin: 0.25rem !important;\n  }\n\n  .m-xl-2 {\n    margin: 0.5rem !important;\n  }\n\n  .m-xl-3 {\n    margin: 1rem !important;\n  }\n\n  .m-xl-4 {\n    margin: 1.5rem !important;\n  }\n\n  .m-xl-5 {\n    margin: 3rem !important;\n  }\n\n  .m-xl-auto {\n    margin: auto !important;\n  }\n\n  .mx-xl-0 {\n    margin-left: 0 !important;\n    margin-right: 0 !important;\n  }\n\n  .mx-xl-1 {\n    margin-left: 0.25rem !important;\n    margin-right: 0.25rem !important;\n  }\n\n  .mx-xl-2 {\n    margin-left: 0.5rem !important;\n    margin-right: 0.5rem !important;\n  }\n\n  .mx-xl-3 {\n    margin-left: 1rem !important;\n    margin-right: 1rem !important;\n  }\n\n  .mx-xl-4 {\n    margin-left: 1.5rem !important;\n    margin-right: 1.5rem !important;\n  }\n\n  .mx-xl-5 {\n    margin-left: 3rem !important;\n    margin-right: 3rem !important;\n  }\n\n  .mx-xl-auto {\n    margin-left: auto !important;\n    margin-right: auto !important;\n  }\n\n  .my-xl-0 {\n    margin-top: 0 !important;\n    margin-bottom: 0 !important;\n  }\n\n  .my-xl-1 {\n    margin-top: 0.25rem !important;\n    margin-bottom: 0.25rem !important;\n  }\n\n  .my-xl-2 {\n    margin-top: 0.5rem !important;\n    margin-bottom: 0.5rem !important;\n  }\n\n  .my-xl-3 {\n    margin-top: 1rem !important;\n    margin-bottom: 1rem !important;\n  }\n\n  .my-xl-4 {\n    margin-top: 1.5rem !important;\n    margin-bottom: 1.5rem !important;\n  }\n\n  .my-xl-5 {\n    margin-top: 3rem !important;\n    margin-bottom: 3rem !important;\n  }\n\n  .my-xl-auto {\n    margin-top: auto !important;\n    margin-bottom: auto !important;\n  }\n\n  .mt-xl-0 {\n    margin-top: 0 !important;\n  }\n\n  .mt-xl-1 {\n    margin-top: 0.25rem !important;\n  }\n\n  .mt-xl-2 {\n    margin-top: 0.5rem !important;\n  }\n\n  .mt-xl-3 {\n    margin-top: 1rem !important;\n  }\n\n  .mt-xl-4 {\n    margin-top: 1.5rem !important;\n  }\n\n  .mt-xl-5 {\n    margin-top: 3rem !important;\n  }\n\n  .mt-xl-auto {\n    margin-top: auto !important;\n  }\n\n  .me-xl-0 {\n    margin-left: 0 !important;\n  }\n\n  .me-xl-1 {\n    margin-left: 0.25rem !important;\n  }\n\n  .me-xl-2 {\n    margin-left: 0.5rem !important;\n  }\n\n  .me-xl-3 {\n    margin-left: 1rem !important;\n  }\n\n  .me-xl-4 {\n    margin-left: 1.5rem !important;\n  }\n\n  .me-xl-5 {\n    margin-left: 3rem !important;\n  }\n\n  .me-xl-auto {\n    margin-left: auto !important;\n  }\n\n  .mb-xl-0 {\n    margin-bottom: 0 !important;\n  }\n\n  .mb-xl-1 {\n    margin-bottom: 0.25rem !important;\n  }\n\n  .mb-xl-2 {\n    margin-bottom: 0.5rem !important;\n  }\n\n  .mb-xl-3 {\n    margin-bottom: 1rem !important;\n  }\n\n  .mb-xl-4 {\n    margin-bottom: 1.5rem !important;\n  }\n\n  .mb-xl-5 {\n    margin-bottom: 3rem !important;\n  }\n\n  .mb-xl-auto {\n    margin-bottom: auto !important;\n  }\n\n  .ms-xl-0 {\n    margin-right: 0 !important;\n  }\n\n  .ms-xl-1 {\n    margin-right: 0.25rem !important;\n  }\n\n  .ms-xl-2 {\n    margin-right: 0.5rem !important;\n  }\n\n  .ms-xl-3 {\n    margin-right: 1rem !important;\n  }\n\n  .ms-xl-4 {\n    margin-right: 1.5rem !important;\n  }\n\n  .ms-xl-5 {\n    margin-right: 3rem !important;\n  }\n\n  .ms-xl-auto {\n    margin-right: auto !important;\n  }\n\n  .p-xl-0 {\n    padding: 0 !important;\n  }\n\n  .p-xl-1 {\n    padding: 0.25rem !important;\n  }\n\n  .p-xl-2 {\n    padding: 0.5rem !important;\n  }\n\n  .p-xl-3 {\n    padding: 1rem !important;\n  }\n\n  .p-xl-4 {\n    padding: 1.5rem !important;\n  }\n\n  .p-xl-5 {\n    padding: 3rem !important;\n  }\n\n  .px-xl-0 {\n    padding-left: 0 !important;\n    padding-right: 0 !important;\n  }\n\n  .px-xl-1 {\n    padding-left: 0.25rem !important;\n    padding-right: 0.25rem !important;\n  }\n\n  .px-xl-2 {\n    padding-left: 0.5rem !important;\n    padding-right: 0.5rem !important;\n  }\n\n  .px-xl-3 {\n    padding-left: 1rem !important;\n    padding-right: 1rem !important;\n  }\n\n  .px-xl-4 {\n    padding-left: 1.5rem !important;\n    padding-right: 1.5rem !important;\n  }\n\n  .px-xl-5 {\n    padding-left: 3rem !important;\n    padding-right: 3rem !important;\n  }\n\n  .py-xl-0 {\n    padding-top: 0 !important;\n    padding-bottom: 0 !important;\n  }\n\n  .py-xl-1 {\n    padding-top: 0.25rem !important;\n    padding-bottom: 0.25rem !important;\n  }\n\n  .py-xl-2 {\n    padding-top: 0.5rem !important;\n    padding-bottom: 0.5rem !important;\n  }\n\n  .py-xl-3 {\n    padding-top: 1rem !important;\n    padding-bottom: 1rem !important;\n  }\n\n  .py-xl-4 {\n    padding-top: 1.5rem !important;\n    padding-bottom: 1.5rem !important;\n  }\n\n  .py-xl-5 {\n    padding-top: 3rem !important;\n    padding-bottom: 3rem !important;\n  }\n\n  .pt-xl-0 {\n    padding-top: 0 !important;\n  }\n\n  .pt-xl-1 {\n    padding-top: 0.25rem !important;\n  }\n\n  .pt-xl-2 {\n    padding-top: 0.5rem !important;\n  }\n\n  .pt-xl-3 {\n    padding-top: 1rem !important;\n  }\n\n  .pt-xl-4 {\n    padding-top: 1.5rem !important;\n  }\n\n  .pt-xl-5 {\n    padding-top: 3rem !important;\n  }\n\n  .pe-xl-0 {\n    padding-left: 0 !important;\n  }\n\n  .pe-xl-1 {\n    padding-left: 0.25rem !important;\n  }\n\n  .pe-xl-2 {\n    padding-left: 0.5rem !important;\n  }\n\n  .pe-xl-3 {\n    padding-left: 1rem !important;\n  }\n\n  .pe-xl-4 {\n    padding-left: 1.5rem !important;\n  }\n\n  .pe-xl-5 {\n    padding-left: 3rem !important;\n  }\n\n  .pb-xl-0 {\n    padding-bottom: 0 !important;\n  }\n\n  .pb-xl-1 {\n    padding-bottom: 0.25rem !important;\n  }\n\n  .pb-xl-2 {\n    padding-bottom: 0.5rem !important;\n  }\n\n  .pb-xl-3 {\n    padding-bottom: 1rem !important;\n  }\n\n  .pb-xl-4 {\n    padding-bottom: 1.5rem !important;\n  }\n\n  .pb-xl-5 {\n    padding-bottom: 3rem !important;\n  }\n\n  .ps-xl-0 {\n    padding-right: 0 !important;\n  }\n\n  .ps-xl-1 {\n    padding-right: 0.25rem !important;\n  }\n\n  .ps-xl-2 {\n    padding-right: 0.5rem !important;\n  }\n\n  .ps-xl-3 {\n    padding-right: 1rem !important;\n  }\n\n  .ps-xl-4 {\n    padding-right: 1.5rem !important;\n  }\n\n  .ps-xl-5 {\n    padding-right: 3rem !important;\n  }\n\n  .text-xl-start {\n    text-align: right !important;\n  }\n\n  .text-xl-end {\n    text-align: left !important;\n  }\n\n  .text-xl-center {\n    text-align: center !important;\n  }\n}\n@media (min-width: 1400px) {\n  .float-xxl-start {\n    float: right !important;\n  }\n\n  .float-xxl-end {\n    float: left !important;\n  }\n\n  .float-xxl-none {\n    float: none !important;\n  }\n\n  .d-xxl-inline {\n    display: inline !important;\n  }\n\n  .d-xxl-inline-block {\n    display: inline-block !important;\n  }\n\n  .d-xxl-block {\n    display: block !important;\n  }\n\n  .d-xxl-grid {\n    display: grid !important;\n  }\n\n  .d-xxl-table {\n    display: table !important;\n  }\n\n  .d-xxl-table-row {\n    display: table-row !important;\n  }\n\n  .d-xxl-table-cell {\n    display: table-cell !important;\n  }\n\n  .d-xxl-flex {\n    display: flex !important;\n  }\n\n  .d-xxl-inline-flex {\n    display: inline-flex !important;\n  }\n\n  .d-xxl-none {\n    display: none !important;\n  }\n\n  .flex-xxl-fill {\n    flex: 1 1 auto !important;\n  }\n\n  .flex-xxl-row {\n    flex-direction: row !important;\n  }\n\n  .flex-xxl-column {\n    flex-direction: column !important;\n  }\n\n  .flex-xxl-row-reverse {\n    flex-direction: row-reverse !important;\n  }\n\n  .flex-xxl-column-reverse {\n    flex-direction: column-reverse !important;\n  }\n\n  .flex-xxl-grow-0 {\n    flex-grow: 0 !important;\n  }\n\n  .flex-xxl-grow-1 {\n    flex-grow: 1 !important;\n  }\n\n  .flex-xxl-shrink-0 {\n    flex-shrink: 0 !important;\n  }\n\n  .flex-xxl-shrink-1 {\n    flex-shrink: 1 !important;\n  }\n\n  .flex-xxl-wrap {\n    flex-wrap: wrap !important;\n  }\n\n  .flex-xxl-nowrap {\n    flex-wrap: nowrap !important;\n  }\n\n  .flex-xxl-wrap-reverse {\n    flex-wrap: wrap-reverse !important;\n  }\n\n  .gap-xxl-0 {\n    gap: 0 !important;\n  }\n\n  .gap-xxl-1 {\n    gap: 0.25rem !important;\n  }\n\n  .gap-xxl-2 {\n    gap: 0.5rem !important;\n  }\n\n  .gap-xxl-3 {\n    gap: 1rem !important;\n  }\n\n  .gap-xxl-4 {\n    gap: 1.5rem !important;\n  }\n\n  .gap-xxl-5 {\n    gap: 3rem !important;\n  }\n\n  .justify-content-xxl-start {\n    justify-content: flex-start !important;\n  }\n\n  .justify-content-xxl-end {\n    justify-content: flex-end !important;\n  }\n\n  .justify-content-xxl-center {\n    justify-content: center !important;\n  }\n\n  .justify-content-xxl-between {\n    justify-content: space-between !important;\n  }\n\n  .justify-content-xxl-around {\n    justify-content: space-around !important;\n  }\n\n  .justify-content-xxl-evenly {\n    justify-content: space-evenly !important;\n  }\n\n  .align-items-xxl-start {\n    align-items: flex-start !important;\n  }\n\n  .align-items-xxl-end {\n    align-items: flex-end !important;\n  }\n\n  .align-items-xxl-center {\n    align-items: center !important;\n  }\n\n  .align-items-xxl-baseline {\n    align-items: baseline !important;\n  }\n\n  .align-items-xxl-stretch {\n    align-items: stretch !important;\n  }\n\n  .align-content-xxl-start {\n    align-content: flex-start !important;\n  }\n\n  .align-content-xxl-end {\n    align-content: flex-end !important;\n  }\n\n  .align-content-xxl-center {\n    align-content: center !important;\n  }\n\n  .align-content-xxl-between {\n    align-content: space-between !important;\n  }\n\n  .align-content-xxl-around {\n    align-content: space-around !important;\n  }\n\n  .align-content-xxl-stretch {\n    align-content: stretch !important;\n  }\n\n  .align-self-xxl-auto {\n    align-self: auto !important;\n  }\n\n  .align-self-xxl-start {\n    align-self: flex-start !important;\n  }\n\n  .align-self-xxl-end {\n    align-self: flex-end !important;\n  }\n\n  .align-self-xxl-center {\n    align-self: center !important;\n  }\n\n  .align-self-xxl-baseline {\n    align-self: baseline !important;\n  }\n\n  .align-self-xxl-stretch {\n    align-self: stretch !important;\n  }\n\n  .order-xxl-first {\n    order: -1 !important;\n  }\n\n  .order-xxl-0 {\n    order: 0 !important;\n  }\n\n  .order-xxl-1 {\n    order: 1 !important;\n  }\n\n  .order-xxl-2 {\n    order: 2 !important;\n  }\n\n  .order-xxl-3 {\n    order: 3 !important;\n  }\n\n  .order-xxl-4 {\n    order: 4 !important;\n  }\n\n  .order-xxl-5 {\n    order: 5 !important;\n  }\n\n  .order-xxl-last {\n    order: 6 !important;\n  }\n\n  .m-xxl-0 {\n    margin: 0 !important;\n  }\n\n  .m-xxl-1 {\n    margin: 0.25rem !important;\n  }\n\n  .m-xxl-2 {\n    margin: 0.5rem !important;\n  }\n\n  .m-xxl-3 {\n    margin: 1rem !important;\n  }\n\n  .m-xxl-4 {\n    margin: 1.5rem !important;\n  }\n\n  .m-xxl-5 {\n    margin: 3rem !important;\n  }\n\n  .m-xxl-auto {\n    margin: auto !important;\n  }\n\n  .mx-xxl-0 {\n    margin-left: 0 !important;\n    margin-right: 0 !important;\n  }\n\n  .mx-xxl-1 {\n    margin-left: 0.25rem !important;\n    margin-right: 0.25rem !important;\n  }\n\n  .mx-xxl-2 {\n    margin-left: 0.5rem !important;\n    margin-right: 0.5rem !important;\n  }\n\n  .mx-xxl-3 {\n    margin-left: 1rem !important;\n    margin-right: 1rem !important;\n  }\n\n  .mx-xxl-4 {\n    margin-left: 1.5rem !important;\n    margin-right: 1.5rem !important;\n  }\n\n  .mx-xxl-5 {\n    margin-left: 3rem !important;\n    margin-right: 3rem !important;\n  }\n\n  .mx-xxl-auto {\n    margin-left: auto !important;\n    margin-right: auto !important;\n  }\n\n  .my-xxl-0 {\n    margin-top: 0 !important;\n    margin-bottom: 0 !important;\n  }\n\n  .my-xxl-1 {\n    margin-top: 0.25rem !important;\n    margin-bottom: 0.25rem !important;\n  }\n\n  .my-xxl-2 {\n    margin-top: 0.5rem !important;\n    margin-bottom: 0.5rem !important;\n  }\n\n  .my-xxl-3 {\n    margin-top: 1rem !important;\n    margin-bottom: 1rem !important;\n  }\n\n  .my-xxl-4 {\n    margin-top: 1.5rem !important;\n    margin-bottom: 1.5rem !important;\n  }\n\n  .my-xxl-5 {\n    margin-top: 3rem !important;\n    margin-bottom: 3rem !important;\n  }\n\n  .my-xxl-auto {\n    margin-top: auto !important;\n    margin-bottom: auto !important;\n  }\n\n  .mt-xxl-0 {\n    margin-top: 0 !important;\n  }\n\n  .mt-xxl-1 {\n    margin-top: 0.25rem !important;\n  }\n\n  .mt-xxl-2 {\n    margin-top: 0.5rem !important;\n  }\n\n  .mt-xxl-3 {\n    margin-top: 1rem !important;\n  }\n\n  .mt-xxl-4 {\n    margin-top: 1.5rem !important;\n  }\n\n  .mt-xxl-5 {\n    margin-top: 3rem !important;\n  }\n\n  .mt-xxl-auto {\n    margin-top: auto !important;\n  }\n\n  .me-xxl-0 {\n    margin-left: 0 !important;\n  }\n\n  .me-xxl-1 {\n    margin-left: 0.25rem !important;\n  }\n\n  .me-xxl-2 {\n    margin-left: 0.5rem !important;\n  }\n\n  .me-xxl-3 {\n    margin-left: 1rem !important;\n  }\n\n  .me-xxl-4 {\n    margin-left: 1.5rem !important;\n  }\n\n  .me-xxl-5 {\n    margin-left: 3rem !important;\n  }\n\n  .me-xxl-auto {\n    margin-left: auto !important;\n  }\n\n  .mb-xxl-0 {\n    margin-bottom: 0 !important;\n  }\n\n  .mb-xxl-1 {\n    margin-bottom: 0.25rem !important;\n  }\n\n  .mb-xxl-2 {\n    margin-bottom: 0.5rem !important;\n  }\n\n  .mb-xxl-3 {\n    margin-bottom: 1rem !important;\n  }\n\n  .mb-xxl-4 {\n    margin-bottom: 1.5rem !important;\n  }\n\n  .mb-xxl-5 {\n    margin-bottom: 3rem !important;\n  }\n\n  .mb-xxl-auto {\n    margin-bottom: auto !important;\n  }\n\n  .ms-xxl-0 {\n    margin-right: 0 !important;\n  }\n\n  .ms-xxl-1 {\n    margin-right: 0.25rem !important;\n  }\n\n  .ms-xxl-2 {\n    margin-right: 0.5rem !important;\n  }\n\n  .ms-xxl-3 {\n    margin-right: 1rem !important;\n  }\n\n  .ms-xxl-4 {\n    margin-right: 1.5rem !important;\n  }\n\n  .ms-xxl-5 {\n    margin-right: 3rem !important;\n  }\n\n  .ms-xxl-auto {\n    margin-right: auto !important;\n  }\n\n  .p-xxl-0 {\n    padding: 0 !important;\n  }\n\n  .p-xxl-1 {\n    padding: 0.25rem !important;\n  }\n\n  .p-xxl-2 {\n    padding: 0.5rem !important;\n  }\n\n  .p-xxl-3 {\n    padding: 1rem !important;\n  }\n\n  .p-xxl-4 {\n    padding: 1.5rem !important;\n  }\n\n  .p-xxl-5 {\n    padding: 3rem !important;\n  }\n\n  .px-xxl-0 {\n    padding-left: 0 !important;\n    padding-right: 0 !important;\n  }\n\n  .px-xxl-1 {\n    padding-left: 0.25rem !important;\n    padding-right: 0.25rem !important;\n  }\n\n  .px-xxl-2 {\n    padding-left: 0.5rem !important;\n    padding-right: 0.5rem !important;\n  }\n\n  .px-xxl-3 {\n    padding-left: 1rem !important;\n    padding-right: 1rem !important;\n  }\n\n  .px-xxl-4 {\n    padding-left: 1.5rem !important;\n    padding-right: 1.5rem !important;\n  }\n\n  .px-xxl-5 {\n    padding-left: 3rem !important;\n    padding-right: 3rem !important;\n  }\n\n  .py-xxl-0 {\n    padding-top: 0 !important;\n    padding-bottom: 0 !important;\n  }\n\n  .py-xxl-1 {\n    padding-top: 0.25rem !important;\n    padding-bottom: 0.25rem !important;\n  }\n\n  .py-xxl-2 {\n    padding-top: 0.5rem !important;\n    padding-bottom: 0.5rem !important;\n  }\n\n  .py-xxl-3 {\n    padding-top: 1rem !important;\n    padding-bottom: 1rem !important;\n  }\n\n  .py-xxl-4 {\n    padding-top: 1.5rem !important;\n    padding-bottom: 1.5rem !important;\n  }\n\n  .py-xxl-5 {\n    padding-top: 3rem !important;\n    padding-bottom: 3rem !important;\n  }\n\n  .pt-xxl-0 {\n    padding-top: 0 !important;\n  }\n\n  .pt-xxl-1 {\n    padding-top: 0.25rem !important;\n  }\n\n  .pt-xxl-2 {\n    padding-top: 0.5rem !important;\n  }\n\n  .pt-xxl-3 {\n    padding-top: 1rem !important;\n  }\n\n  .pt-xxl-4 {\n    padding-top: 1.5rem !important;\n  }\n\n  .pt-xxl-5 {\n    padding-top: 3rem !important;\n  }\n\n  .pe-xxl-0 {\n    padding-left: 0 !important;\n  }\n\n  .pe-xxl-1 {\n    padding-left: 0.25rem !important;\n  }\n\n  .pe-xxl-2 {\n    padding-left: 0.5rem !important;\n  }\n\n  .pe-xxl-3 {\n    padding-left: 1rem !important;\n  }\n\n  .pe-xxl-4 {\n    padding-left: 1.5rem !important;\n  }\n\n  .pe-xxl-5 {\n    padding-left: 3rem !important;\n  }\n\n  .pb-xxl-0 {\n    padding-bottom: 0 !important;\n  }\n\n  .pb-xxl-1 {\n    padding-bottom: 0.25rem !important;\n  }\n\n  .pb-xxl-2 {\n    padding-bottom: 0.5rem !important;\n  }\n\n  .pb-xxl-3 {\n    padding-bottom: 1rem !important;\n  }\n\n  .pb-xxl-4 {\n    padding-bottom: 1.5rem !important;\n  }\n\n  .pb-xxl-5 {\n    padding-bottom: 3rem !important;\n  }\n\n  .ps-xxl-0 {\n    padding-right: 0 !important;\n  }\n\n  .ps-xxl-1 {\n    padding-right: 0.25rem !important;\n  }\n\n  .ps-xxl-2 {\n    padding-right: 0.5rem !important;\n  }\n\n  .ps-xxl-3 {\n    padding-right: 1rem !important;\n  }\n\n  .ps-xxl-4 {\n    padding-right: 1.5rem !important;\n  }\n\n  .ps-xxl-5 {\n    padding-right: 3rem !important;\n  }\n\n  .text-xxl-start {\n    text-align: right !important;\n  }\n\n  .text-xxl-end {\n    text-align: left !important;\n  }\n\n  .text-xxl-center {\n    text-align: center !important;\n  }\n}\n@media (min-width: 1200px) {\n  .fs-1 {\n    font-size: 2.5rem !important;\n  }\n\n  .fs-2 {\n    font-size: 2rem !important;\n  }\n\n  .fs-3 {\n    font-size: 1.75rem !important;\n  }\n\n  .fs-4 {\n    font-size: 1.5rem !important;\n  }\n}\n@media print {\n  .d-print-inline {\n    display: inline !important;\n  }\n\n  .d-print-inline-block {\n    display: inline-block !important;\n  }\n\n  .d-print-block {\n    display: block !important;\n  }\n\n  .d-print-grid {\n    display: grid !important;\n  }\n\n  .d-print-table {\n    display: table !important;\n  }\n\n  .d-print-table-row {\n    display: table-row !important;\n  }\n\n  .d-print-table-cell {\n    display: table-cell !important;\n  }\n\n  .d-print-flex {\n    display: flex !important;\n  }\n\n  .d-print-inline-flex {\n    display: inline-flex !important;\n  }\n\n  .d-print-none {\n    display: none !important;\n  }\n}\n/*# sourceMappingURL=bootstrap.rtl.css.map */"
  },
  {
    "path": "sample/src/NimblePros.SampleToDo.Web/wwwroot/lib/bootstrap/dist/js/bootstrap.bundle.js",
    "content": "/*!\n  * Bootstrap v5.1.0 (https://getbootstrap.com/)\n  * Copyright 2011-2021 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors)\n  * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n  */\n(function (global, factory) {\n  typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :\n  typeof define === 'function' && define.amd ? define(factory) :\n  (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.bootstrap = factory());\n}(this, (function () { 'use strict';\n\n  /**\n   * --------------------------------------------------------------------------\n   * Bootstrap (v5.1.0): util/index.js\n   * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n   * --------------------------------------------------------------------------\n   */\n  const MAX_UID = 1000000;\n  const MILLISECONDS_MULTIPLIER = 1000;\n  const TRANSITION_END = 'transitionend'; // Shoutout AngusCroll (https://goo.gl/pxwQGp)\n\n  const toType = obj => {\n    if (obj === null || obj === undefined) {\n      return `${obj}`;\n    }\n\n    return {}.toString.call(obj).match(/\\s([a-z]+)/i)[1].toLowerCase();\n  };\n  /**\n   * --------------------------------------------------------------------------\n   * Public Util Api\n   * --------------------------------------------------------------------------\n   */\n\n\n  const getUID = prefix => {\n    do {\n      prefix += Math.floor(Math.random() * MAX_UID);\n    } while (document.getElementById(prefix));\n\n    return prefix;\n  };\n\n  const getSelector = element => {\n    let selector = element.getAttribute('data-bs-target');\n\n    if (!selector || selector === '#') {\n      let hrefAttr = element.getAttribute('href'); // The only valid content that could double as a selector are IDs or classes,\n      // so everything starting with `#` or `.`. If a \"real\" URL is used as the selector,\n      // `document.querySelector` will rightfully complain it is invalid.\n      // See https://github.com/twbs/bootstrap/issues/32273\n\n      if (!hrefAttr || !hrefAttr.includes('#') && !hrefAttr.startsWith('.')) {\n        return null;\n      } // Just in case some CMS puts out a full URL with the anchor appended\n\n\n      if (hrefAttr.includes('#') && !hrefAttr.startsWith('#')) {\n        hrefAttr = `#${hrefAttr.split('#')[1]}`;\n      }\n\n      selector = hrefAttr && hrefAttr !== '#' ? hrefAttr.trim() : null;\n    }\n\n    return selector;\n  };\n\n  const getSelectorFromElement = element => {\n    const selector = getSelector(element);\n\n    if (selector) {\n      return document.querySelector(selector) ? selector : null;\n    }\n\n    return null;\n  };\n\n  const getElementFromSelector = element => {\n    const selector = getSelector(element);\n    return selector ? document.querySelector(selector) : null;\n  };\n\n  const getTransitionDurationFromElement = element => {\n    if (!element) {\n      return 0;\n    } // Get transition-duration of the element\n\n\n    let {\n      transitionDuration,\n      transitionDelay\n    } = window.getComputedStyle(element);\n    const floatTransitionDuration = Number.parseFloat(transitionDuration);\n    const floatTransitionDelay = Number.parseFloat(transitionDelay); // Return 0 if element or transition duration is not found\n\n    if (!floatTransitionDuration && !floatTransitionDelay) {\n      return 0;\n    } // If multiple durations are defined, take the first\n\n\n    transitionDuration = transitionDuration.split(',')[0];\n    transitionDelay = transitionDelay.split(',')[0];\n    return (Number.parseFloat(transitionDuration) + Number.parseFloat(transitionDelay)) * MILLISECONDS_MULTIPLIER;\n  };\n\n  const triggerTransitionEnd = element => {\n    element.dispatchEvent(new Event(TRANSITION_END));\n  };\n\n  const isElement$1 = obj => {\n    if (!obj || typeof obj !== 'object') {\n      return false;\n    }\n\n    if (typeof obj.jquery !== 'undefined') {\n      obj = obj[0];\n    }\n\n    return typeof obj.nodeType !== 'undefined';\n  };\n\n  const getElement = obj => {\n    if (isElement$1(obj)) {\n      // it's a jQuery object or a node element\n      return obj.jquery ? obj[0] : obj;\n    }\n\n    if (typeof obj === 'string' && obj.length > 0) {\n      return document.querySelector(obj);\n    }\n\n    return null;\n  };\n\n  const typeCheckConfig = (componentName, config, configTypes) => {\n    Object.keys(configTypes).forEach(property => {\n      const expectedTypes = configTypes[property];\n      const value = config[property];\n      const valueType = value && isElement$1(value) ? 'element' : toType(value);\n\n      if (!new RegExp(expectedTypes).test(valueType)) {\n        throw new TypeError(`${componentName.toUpperCase()}: Option \"${property}\" provided type \"${valueType}\" but expected type \"${expectedTypes}\".`);\n      }\n    });\n  };\n\n  const isVisible = element => {\n    if (!isElement$1(element) || element.getClientRects().length === 0) {\n      return false;\n    }\n\n    return getComputedStyle(element).getPropertyValue('visibility') === 'visible';\n  };\n\n  const isDisabled = element => {\n    if (!element || element.nodeType !== Node.ELEMENT_NODE) {\n      return true;\n    }\n\n    if (element.classList.contains('disabled')) {\n      return true;\n    }\n\n    if (typeof element.disabled !== 'undefined') {\n      return element.disabled;\n    }\n\n    return element.hasAttribute('disabled') && element.getAttribute('disabled') !== 'false';\n  };\n\n  const findShadowRoot = element => {\n    if (!document.documentElement.attachShadow) {\n      return null;\n    } // Can find the shadow root otherwise it'll return the document\n\n\n    if (typeof element.getRootNode === 'function') {\n      const root = element.getRootNode();\n      return root instanceof ShadowRoot ? root : null;\n    }\n\n    if (element instanceof ShadowRoot) {\n      return element;\n    } // when we don't find a shadow root\n\n\n    if (!element.parentNode) {\n      return null;\n    }\n\n    return findShadowRoot(element.parentNode);\n  };\n\n  const noop = () => {};\n  /**\n   * Trick to restart an element's animation\n   *\n   * @param {HTMLElement} element\n   * @return void\n   *\n   * @see https://www.charistheo.io/blog/2021/02/restart-a-css-animation-with-javascript/#restarting-a-css-animation\n   */\n\n\n  const reflow = element => {\n    // eslint-disable-next-line no-unused-expressions\n    element.offsetHeight;\n  };\n\n  const getjQuery = () => {\n    const {\n      jQuery\n    } = window;\n\n    if (jQuery && !document.body.hasAttribute('data-bs-no-jquery')) {\n      return jQuery;\n    }\n\n    return null;\n  };\n\n  const DOMContentLoadedCallbacks = [];\n\n  const onDOMContentLoaded = callback => {\n    if (document.readyState === 'loading') {\n      // add listener on the first call when the document is in loading state\n      if (!DOMContentLoadedCallbacks.length) {\n        document.addEventListener('DOMContentLoaded', () => {\n          DOMContentLoadedCallbacks.forEach(callback => callback());\n        });\n      }\n\n      DOMContentLoadedCallbacks.push(callback);\n    } else {\n      callback();\n    }\n  };\n\n  const isRTL = () => document.documentElement.dir === 'rtl';\n\n  const defineJQueryPlugin = plugin => {\n    onDOMContentLoaded(() => {\n      const $ = getjQuery();\n      /* istanbul ignore if */\n\n      if ($) {\n        const name = plugin.NAME;\n        const JQUERY_NO_CONFLICT = $.fn[name];\n        $.fn[name] = plugin.jQueryInterface;\n        $.fn[name].Constructor = plugin;\n\n        $.fn[name].noConflict = () => {\n          $.fn[name] = JQUERY_NO_CONFLICT;\n          return plugin.jQueryInterface;\n        };\n      }\n    });\n  };\n\n  const execute = callback => {\n    if (typeof callback === 'function') {\n      callback();\n    }\n  };\n\n  const executeAfterTransition = (callback, transitionElement, waitForTransition = true) => {\n    if (!waitForTransition) {\n      execute(callback);\n      return;\n    }\n\n    const durationPadding = 5;\n    const emulatedDuration = getTransitionDurationFromElement(transitionElement) + durationPadding;\n    let called = false;\n\n    const handler = ({\n      target\n    }) => {\n      if (target !== transitionElement) {\n        return;\n      }\n\n      called = true;\n      transitionElement.removeEventListener(TRANSITION_END, handler);\n      execute(callback);\n    };\n\n    transitionElement.addEventListener(TRANSITION_END, handler);\n    setTimeout(() => {\n      if (!called) {\n        triggerTransitionEnd(transitionElement);\n      }\n    }, emulatedDuration);\n  };\n  /**\n   * Return the previous/next element of a list.\n   *\n   * @param {array} list    The list of elements\n   * @param activeElement   The active element\n   * @param shouldGetNext   Choose to get next or previous element\n   * @param isCycleAllowed\n   * @return {Element|elem} The proper element\n   */\n\n\n  const getNextActiveElement = (list, activeElement, shouldGetNext, isCycleAllowed) => {\n    let index = list.indexOf(activeElement); // if the element does not exist in the list return an element depending on the direction and if cycle is allowed\n\n    if (index === -1) {\n      return list[!shouldGetNext && isCycleAllowed ? list.length - 1 : 0];\n    }\n\n    const listLength = list.length;\n    index += shouldGetNext ? 1 : -1;\n\n    if (isCycleAllowed) {\n      index = (index + listLength) % listLength;\n    }\n\n    return list[Math.max(0, Math.min(index, listLength - 1))];\n  };\n\n  /**\n   * --------------------------------------------------------------------------\n   * Bootstrap (v5.1.0): dom/event-handler.js\n   * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n   * --------------------------------------------------------------------------\n   */\n  /**\n   * ------------------------------------------------------------------------\n   * Constants\n   * ------------------------------------------------------------------------\n   */\n\n  const namespaceRegex = /[^.]*(?=\\..*)\\.|.*/;\n  const stripNameRegex = /\\..*/;\n  const stripUidRegex = /::\\d+$/;\n  const eventRegistry = {}; // Events storage\n\n  let uidEvent = 1;\n  const customEvents = {\n    mouseenter: 'mouseover',\n    mouseleave: 'mouseout'\n  };\n  const customEventsRegex = /^(mouseenter|mouseleave)/i;\n  const nativeEvents = 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']);\n  /**\n   * ------------------------------------------------------------------------\n   * Private methods\n   * ------------------------------------------------------------------------\n   */\n\n  function getUidEvent(element, uid) {\n    return uid && `${uid}::${uidEvent++}` || element.uidEvent || uidEvent++;\n  }\n\n  function getEvent(element) {\n    const uid = getUidEvent(element);\n    element.uidEvent = uid;\n    eventRegistry[uid] = eventRegistry[uid] || {};\n    return eventRegistry[uid];\n  }\n\n  function bootstrapHandler(element, fn) {\n    return function handler(event) {\n      event.delegateTarget = element;\n\n      if (handler.oneOff) {\n        EventHandler.off(element, event.type, fn);\n      }\n\n      return fn.apply(element, [event]);\n    };\n  }\n\n  function bootstrapDelegationHandler(element, selector, fn) {\n    return function handler(event) {\n      const domElements = element.querySelectorAll(selector);\n\n      for (let {\n        target\n      } = event; target && target !== this; target = target.parentNode) {\n        for (let i = domElements.length; i--;) {\n          if (domElements[i] === target) {\n            event.delegateTarget = target;\n\n            if (handler.oneOff) {\n              // eslint-disable-next-line unicorn/consistent-destructuring\n              EventHandler.off(element, event.type, selector, fn);\n            }\n\n            return fn.apply(target, [event]);\n          }\n        }\n      } // To please ESLint\n\n\n      return null;\n    };\n  }\n\n  function findHandler(events, handler, delegationSelector = null) {\n    const uidEventList = Object.keys(events);\n\n    for (let i = 0, len = uidEventList.length; i < len; i++) {\n      const event = events[uidEventList[i]];\n\n      if (event.originalHandler === handler && event.delegationSelector === delegationSelector) {\n        return event;\n      }\n    }\n\n    return null;\n  }\n\n  function normalizeParams(originalTypeEvent, handler, delegationFn) {\n    const delegation = typeof handler === 'string';\n    const originalHandler = delegation ? delegationFn : handler;\n    let typeEvent = getTypeEvent(originalTypeEvent);\n    const isNative = nativeEvents.has(typeEvent);\n\n    if (!isNative) {\n      typeEvent = originalTypeEvent;\n    }\n\n    return [delegation, originalHandler, typeEvent];\n  }\n\n  function addHandler(element, originalTypeEvent, handler, delegationFn, oneOff) {\n    if (typeof originalTypeEvent !== 'string' || !element) {\n      return;\n    }\n\n    if (!handler) {\n      handler = delegationFn;\n      delegationFn = null;\n    } // in case of mouseenter or mouseleave wrap the handler within a function that checks for its DOM position\n    // this prevents the handler from being dispatched the same way as mouseover or mouseout does\n\n\n    if (customEventsRegex.test(originalTypeEvent)) {\n      const wrapFn = fn => {\n        return function (event) {\n          if (!event.relatedTarget || event.relatedTarget !== event.delegateTarget && !event.delegateTarget.contains(event.relatedTarget)) {\n            return fn.call(this, event);\n          }\n        };\n      };\n\n      if (delegationFn) {\n        delegationFn = wrapFn(delegationFn);\n      } else {\n        handler = wrapFn(handler);\n      }\n    }\n\n    const [delegation, originalHandler, typeEvent] = normalizeParams(originalTypeEvent, handler, delegationFn);\n    const events = getEvent(element);\n    const handlers = events[typeEvent] || (events[typeEvent] = {});\n    const previousFn = findHandler(handlers, originalHandler, delegation ? handler : null);\n\n    if (previousFn) {\n      previousFn.oneOff = previousFn.oneOff && oneOff;\n      return;\n    }\n\n    const uid = getUidEvent(originalHandler, originalTypeEvent.replace(namespaceRegex, ''));\n    const fn = delegation ? bootstrapDelegationHandler(element, handler, delegationFn) : bootstrapHandler(element, handler);\n    fn.delegationSelector = delegation ? handler : null;\n    fn.originalHandler = originalHandler;\n    fn.oneOff = oneOff;\n    fn.uidEvent = uid;\n    handlers[uid] = fn;\n    element.addEventListener(typeEvent, fn, delegation);\n  }\n\n  function removeHandler(element, events, typeEvent, handler, delegationSelector) {\n    const fn = findHandler(events[typeEvent], handler, delegationSelector);\n\n    if (!fn) {\n      return;\n    }\n\n    element.removeEventListener(typeEvent, fn, Boolean(delegationSelector));\n    delete events[typeEvent][fn.uidEvent];\n  }\n\n  function removeNamespacedHandlers(element, events, typeEvent, namespace) {\n    const storeElementEvent = events[typeEvent] || {};\n    Object.keys(storeElementEvent).forEach(handlerKey => {\n      if (handlerKey.includes(namespace)) {\n        const event = storeElementEvent[handlerKey];\n        removeHandler(element, events, typeEvent, event.originalHandler, event.delegationSelector);\n      }\n    });\n  }\n\n  function getTypeEvent(event) {\n    // allow to get the native events from namespaced events ('click.bs.button' --> 'click')\n    event = event.replace(stripNameRegex, '');\n    return customEvents[event] || event;\n  }\n\n  const EventHandler = {\n    on(element, event, handler, delegationFn) {\n      addHandler(element, event, handler, delegationFn, false);\n    },\n\n    one(element, event, handler, delegationFn) {\n      addHandler(element, event, handler, delegationFn, true);\n    },\n\n    off(element, originalTypeEvent, handler, delegationFn) {\n      if (typeof originalTypeEvent !== 'string' || !element) {\n        return;\n      }\n\n      const [delegation, originalHandler, typeEvent] = normalizeParams(originalTypeEvent, handler, delegationFn);\n      const inNamespace = typeEvent !== originalTypeEvent;\n      const events = getEvent(element);\n      const isNamespace = originalTypeEvent.startsWith('.');\n\n      if (typeof originalHandler !== 'undefined') {\n        // Simplest case: handler is passed, remove that listener ONLY.\n        if (!events || !events[typeEvent]) {\n          return;\n        }\n\n        removeHandler(element, events, typeEvent, originalHandler, delegation ? handler : null);\n        return;\n      }\n\n      if (isNamespace) {\n        Object.keys(events).forEach(elementEvent => {\n          removeNamespacedHandlers(element, events, elementEvent, originalTypeEvent.slice(1));\n        });\n      }\n\n      const storeElementEvent = events[typeEvent] || {};\n      Object.keys(storeElementEvent).forEach(keyHandlers => {\n        const handlerKey = keyHandlers.replace(stripUidRegex, '');\n\n        if (!inNamespace || originalTypeEvent.includes(handlerKey)) {\n          const event = storeElementEvent[keyHandlers];\n          removeHandler(element, events, typeEvent, event.originalHandler, event.delegationSelector);\n        }\n      });\n    },\n\n    trigger(element, event, args) {\n      if (typeof event !== 'string' || !element) {\n        return null;\n      }\n\n      const $ = getjQuery();\n      const typeEvent = getTypeEvent(event);\n      const inNamespace = event !== typeEvent;\n      const isNative = nativeEvents.has(typeEvent);\n      let jQueryEvent;\n      let bubbles = true;\n      let nativeDispatch = true;\n      let defaultPrevented = false;\n      let evt = null;\n\n      if (inNamespace && $) {\n        jQueryEvent = $.Event(event, args);\n        $(element).trigger(jQueryEvent);\n        bubbles = !jQueryEvent.isPropagationStopped();\n        nativeDispatch = !jQueryEvent.isImmediatePropagationStopped();\n        defaultPrevented = jQueryEvent.isDefaultPrevented();\n      }\n\n      if (isNative) {\n        evt = document.createEvent('HTMLEvents');\n        evt.initEvent(typeEvent, bubbles, true);\n      } else {\n        evt = new CustomEvent(event, {\n          bubbles,\n          cancelable: true\n        });\n      } // merge custom information in our event\n\n\n      if (typeof args !== 'undefined') {\n        Object.keys(args).forEach(key => {\n          Object.defineProperty(evt, key, {\n            get() {\n              return args[key];\n            }\n\n          });\n        });\n      }\n\n      if (defaultPrevented) {\n        evt.preventDefault();\n      }\n\n      if (nativeDispatch) {\n        element.dispatchEvent(evt);\n      }\n\n      if (evt.defaultPrevented && typeof jQueryEvent !== 'undefined') {\n        jQueryEvent.preventDefault();\n      }\n\n      return evt;\n    }\n\n  };\n\n  /**\n   * --------------------------------------------------------------------------\n   * Bootstrap (v5.1.0): dom/data.js\n   * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n   * --------------------------------------------------------------------------\n   */\n\n  /**\n   * ------------------------------------------------------------------------\n   * Constants\n   * ------------------------------------------------------------------------\n   */\n  const elementMap = new Map();\n  var Data = {\n    set(element, key, instance) {\n      if (!elementMap.has(element)) {\n        elementMap.set(element, new Map());\n      }\n\n      const instanceMap = elementMap.get(element); // make it clear we only want one instance per element\n      // can be removed later when multiple key/instances are fine to be used\n\n      if (!instanceMap.has(key) && instanceMap.size !== 0) {\n        // eslint-disable-next-line no-console\n        console.error(`Bootstrap doesn't allow more than one instance per element. Bound instance: ${Array.from(instanceMap.keys())[0]}.`);\n        return;\n      }\n\n      instanceMap.set(key, instance);\n    },\n\n    get(element, key) {\n      if (elementMap.has(element)) {\n        return elementMap.get(element).get(key) || null;\n      }\n\n      return null;\n    },\n\n    remove(element, key) {\n      if (!elementMap.has(element)) {\n        return;\n      }\n\n      const instanceMap = elementMap.get(element);\n      instanceMap.delete(key); // free up element references if there are no instances left for an element\n\n      if (instanceMap.size === 0) {\n        elementMap.delete(element);\n      }\n    }\n\n  };\n\n  /**\n   * --------------------------------------------------------------------------\n   * Bootstrap (v5.1.0): base-component.js\n   * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n   * --------------------------------------------------------------------------\n   */\n  /**\n   * ------------------------------------------------------------------------\n   * Constants\n   * ------------------------------------------------------------------------\n   */\n\n  const VERSION = '5.1.0';\n\n  class BaseComponent {\n    constructor(element) {\n      element = getElement(element);\n\n      if (!element) {\n        return;\n      }\n\n      this._element = element;\n      Data.set(this._element, this.constructor.DATA_KEY, this);\n    }\n\n    dispose() {\n      Data.remove(this._element, this.constructor.DATA_KEY);\n      EventHandler.off(this._element, this.constructor.EVENT_KEY);\n      Object.getOwnPropertyNames(this).forEach(propertyName => {\n        this[propertyName] = null;\n      });\n    }\n\n    _queueCallback(callback, element, isAnimated = true) {\n      executeAfterTransition(callback, element, isAnimated);\n    }\n    /** Static */\n\n\n    static getInstance(element) {\n      return Data.get(getElement(element), this.DATA_KEY);\n    }\n\n    static getOrCreateInstance(element, config = {}) {\n      return this.getInstance(element) || new this(element, typeof config === 'object' ? config : null);\n    }\n\n    static get VERSION() {\n      return VERSION;\n    }\n\n    static get NAME() {\n      throw new Error('You have to implement the static method \"NAME\", for each component!');\n    }\n\n    static get DATA_KEY() {\n      return `bs.${this.NAME}`;\n    }\n\n    static get EVENT_KEY() {\n      return `.${this.DATA_KEY}`;\n    }\n\n  }\n\n  /**\n   * --------------------------------------------------------------------------\n   * Bootstrap (v5.1.0): util/component-functions.js\n   * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n   * --------------------------------------------------------------------------\n   */\n\n  const enableDismissTrigger = (component, method = 'hide') => {\n    const clickEvent = `click.dismiss${component.EVENT_KEY}`;\n    const name = component.NAME;\n    EventHandler.on(document, clickEvent, `[data-bs-dismiss=\"${name}\"]`, function (event) {\n      if (['A', 'AREA'].includes(this.tagName)) {\n        event.preventDefault();\n      }\n\n      if (isDisabled(this)) {\n        return;\n      }\n\n      const target = getElementFromSelector(this) || this.closest(`.${name}`);\n      const instance = component.getOrCreateInstance(target); // Method argument is left, for Alert and only, as it doesn't implement the 'hide' method\n\n      instance[method]();\n    });\n  };\n\n  /**\n   * --------------------------------------------------------------------------\n   * Bootstrap (v5.1.0): alert.js\n   * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n   * --------------------------------------------------------------------------\n   */\n  /**\n   * ------------------------------------------------------------------------\n   * Constants\n   * ------------------------------------------------------------------------\n   */\n\n  const NAME$d = 'alert';\n  const DATA_KEY$c = 'bs.alert';\n  const EVENT_KEY$c = `.${DATA_KEY$c}`;\n  const EVENT_CLOSE = `close${EVENT_KEY$c}`;\n  const EVENT_CLOSED = `closed${EVENT_KEY$c}`;\n  const CLASS_NAME_FADE$5 = 'fade';\n  const CLASS_NAME_SHOW$8 = 'show';\n  /**\n   * ------------------------------------------------------------------------\n   * Class Definition\n   * ------------------------------------------------------------------------\n   */\n\n  class Alert extends BaseComponent {\n    // Getters\n    static get NAME() {\n      return NAME$d;\n    } // Public\n\n\n    close() {\n      const closeEvent = EventHandler.trigger(this._element, EVENT_CLOSE);\n\n      if (closeEvent.defaultPrevented) {\n        return;\n      }\n\n      this._element.classList.remove(CLASS_NAME_SHOW$8);\n\n      const isAnimated = this._element.classList.contains(CLASS_NAME_FADE$5);\n\n      this._queueCallback(() => this._destroyElement(), this._element, isAnimated);\n    } // Private\n\n\n    _destroyElement() {\n      this._element.remove();\n\n      EventHandler.trigger(this._element, EVENT_CLOSED);\n      this.dispose();\n    } // Static\n\n\n    static jQueryInterface(config) {\n      return this.each(function () {\n        const data = Alert.getOrCreateInstance(this);\n\n        if (typeof config !== 'string') {\n          return;\n        }\n\n        if (data[config] === undefined || config.startsWith('_') || config === 'constructor') {\n          throw new TypeError(`No method named \"${config}\"`);\n        }\n\n        data[config](this);\n      });\n    }\n\n  }\n  /**\n   * ------------------------------------------------------------------------\n   * Data Api implementation\n   * ------------------------------------------------------------------------\n   */\n\n\n  enableDismissTrigger(Alert, 'close');\n  /**\n   * ------------------------------------------------------------------------\n   * jQuery\n   * ------------------------------------------------------------------------\n   * add .Alert to jQuery only if jQuery is present\n   */\n\n  defineJQueryPlugin(Alert);\n\n  /**\n   * --------------------------------------------------------------------------\n   * Bootstrap (v5.1.0): button.js\n   * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n   * --------------------------------------------------------------------------\n   */\n  /**\n   * ------------------------------------------------------------------------\n   * Constants\n   * ------------------------------------------------------------------------\n   */\n\n  const NAME$c = 'button';\n  const DATA_KEY$b = 'bs.button';\n  const EVENT_KEY$b = `.${DATA_KEY$b}`;\n  const DATA_API_KEY$7 = '.data-api';\n  const CLASS_NAME_ACTIVE$3 = 'active';\n  const SELECTOR_DATA_TOGGLE$5 = '[data-bs-toggle=\"button\"]';\n  const EVENT_CLICK_DATA_API$6 = `click${EVENT_KEY$b}${DATA_API_KEY$7}`;\n  /**\n   * ------------------------------------------------------------------------\n   * Class Definition\n   * ------------------------------------------------------------------------\n   */\n\n  class Button extends BaseComponent {\n    // Getters\n    static get NAME() {\n      return NAME$c;\n    } // Public\n\n\n    toggle() {\n      // Toggle class and sync the `aria-pressed` attribute with the return value of the `.toggle()` method\n      this._element.setAttribute('aria-pressed', this._element.classList.toggle(CLASS_NAME_ACTIVE$3));\n    } // Static\n\n\n    static jQueryInterface(config) {\n      return this.each(function () {\n        const data = Button.getOrCreateInstance(this);\n\n        if (config === 'toggle') {\n          data[config]();\n        }\n      });\n    }\n\n  }\n  /**\n   * ------------------------------------------------------------------------\n   * Data Api implementation\n   * ------------------------------------------------------------------------\n   */\n\n\n  EventHandler.on(document, EVENT_CLICK_DATA_API$6, SELECTOR_DATA_TOGGLE$5, event => {\n    event.preventDefault();\n    const button = event.target.closest(SELECTOR_DATA_TOGGLE$5);\n    const data = Button.getOrCreateInstance(button);\n    data.toggle();\n  });\n  /**\n   * ------------------------------------------------------------------------\n   * jQuery\n   * ------------------------------------------------------------------------\n   * add .Button to jQuery only if jQuery is present\n   */\n\n  defineJQueryPlugin(Button);\n\n  /**\n   * --------------------------------------------------------------------------\n   * Bootstrap (v5.1.0): dom/manipulator.js\n   * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n   * --------------------------------------------------------------------------\n   */\n  function normalizeData(val) {\n    if (val === 'true') {\n      return true;\n    }\n\n    if (val === 'false') {\n      return false;\n    }\n\n    if (val === Number(val).toString()) {\n      return Number(val);\n    }\n\n    if (val === '' || val === 'null') {\n      return null;\n    }\n\n    return val;\n  }\n\n  function normalizeDataKey(key) {\n    return key.replace(/[A-Z]/g, chr => `-${chr.toLowerCase()}`);\n  }\n\n  const Manipulator = {\n    setDataAttribute(element, key, value) {\n      element.setAttribute(`data-bs-${normalizeDataKey(key)}`, value);\n    },\n\n    removeDataAttribute(element, key) {\n      element.removeAttribute(`data-bs-${normalizeDataKey(key)}`);\n    },\n\n    getDataAttributes(element) {\n      if (!element) {\n        return {};\n      }\n\n      const attributes = {};\n      Object.keys(element.dataset).filter(key => key.startsWith('bs')).forEach(key => {\n        let pureKey = key.replace(/^bs/, '');\n        pureKey = pureKey.charAt(0).toLowerCase() + pureKey.slice(1, pureKey.length);\n        attributes[pureKey] = normalizeData(element.dataset[key]);\n      });\n      return attributes;\n    },\n\n    getDataAttribute(element, key) {\n      return normalizeData(element.getAttribute(`data-bs-${normalizeDataKey(key)}`));\n    },\n\n    offset(element) {\n      const rect = element.getBoundingClientRect();\n      return {\n        top: rect.top + window.pageYOffset,\n        left: rect.left + window.pageXOffset\n      };\n    },\n\n    position(element) {\n      return {\n        top: element.offsetTop,\n        left: element.offsetLeft\n      };\n    }\n\n  };\n\n  /**\n   * --------------------------------------------------------------------------\n   * Bootstrap (v5.1.0): dom/selector-engine.js\n   * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n   * --------------------------------------------------------------------------\n   */\n  const NODE_TEXT = 3;\n  const SelectorEngine = {\n    find(selector, element = document.documentElement) {\n      return [].concat(...Element.prototype.querySelectorAll.call(element, selector));\n    },\n\n    findOne(selector, element = document.documentElement) {\n      return Element.prototype.querySelector.call(element, selector);\n    },\n\n    children(element, selector) {\n      return [].concat(...element.children).filter(child => child.matches(selector));\n    },\n\n    parents(element, selector) {\n      const parents = [];\n      let ancestor = element.parentNode;\n\n      while (ancestor && ancestor.nodeType === Node.ELEMENT_NODE && ancestor.nodeType !== NODE_TEXT) {\n        if (ancestor.matches(selector)) {\n          parents.push(ancestor);\n        }\n\n        ancestor = ancestor.parentNode;\n      }\n\n      return parents;\n    },\n\n    prev(element, selector) {\n      let previous = element.previousElementSibling;\n\n      while (previous) {\n        if (previous.matches(selector)) {\n          return [previous];\n        }\n\n        previous = previous.previousElementSibling;\n      }\n\n      return [];\n    },\n\n    next(element, selector) {\n      let next = element.nextElementSibling;\n\n      while (next) {\n        if (next.matches(selector)) {\n          return [next];\n        }\n\n        next = next.nextElementSibling;\n      }\n\n      return [];\n    },\n\n    focusableChildren(element) {\n      const focusables = ['a', 'button', 'input', 'textarea', 'select', 'details', '[tabindex]', '[contenteditable=\"true\"]'].map(selector => `${selector}:not([tabindex^=\"-\"])`).join(', ');\n      return this.find(focusables, element).filter(el => !isDisabled(el) && isVisible(el));\n    }\n\n  };\n\n  /**\n   * --------------------------------------------------------------------------\n   * Bootstrap (v5.1.0): carousel.js\n   * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n   * --------------------------------------------------------------------------\n   */\n  /**\n   * ------------------------------------------------------------------------\n   * Constants\n   * ------------------------------------------------------------------------\n   */\n\n  const NAME$b = 'carousel';\n  const DATA_KEY$a = 'bs.carousel';\n  const EVENT_KEY$a = `.${DATA_KEY$a}`;\n  const DATA_API_KEY$6 = '.data-api';\n  const ARROW_LEFT_KEY = 'ArrowLeft';\n  const ARROW_RIGHT_KEY = 'ArrowRight';\n  const TOUCHEVENT_COMPAT_WAIT = 500; // Time for mouse compat events to fire after touch\n\n  const SWIPE_THRESHOLD = 40;\n  const Default$a = {\n    interval: 5000,\n    keyboard: true,\n    slide: false,\n    pause: 'hover',\n    wrap: true,\n    touch: true\n  };\n  const DefaultType$a = {\n    interval: '(number|boolean)',\n    keyboard: 'boolean',\n    slide: '(boolean|string)',\n    pause: '(string|boolean)',\n    wrap: 'boolean',\n    touch: 'boolean'\n  };\n  const ORDER_NEXT = 'next';\n  const ORDER_PREV = 'prev';\n  const DIRECTION_LEFT = 'left';\n  const DIRECTION_RIGHT = 'right';\n  const KEY_TO_DIRECTION = {\n    [ARROW_LEFT_KEY]: DIRECTION_RIGHT,\n    [ARROW_RIGHT_KEY]: DIRECTION_LEFT\n  };\n  const EVENT_SLIDE = `slide${EVENT_KEY$a}`;\n  const EVENT_SLID = `slid${EVENT_KEY$a}`;\n  const EVENT_KEYDOWN = `keydown${EVENT_KEY$a}`;\n  const EVENT_MOUSEENTER = `mouseenter${EVENT_KEY$a}`;\n  const EVENT_MOUSELEAVE = `mouseleave${EVENT_KEY$a}`;\n  const EVENT_TOUCHSTART = `touchstart${EVENT_KEY$a}`;\n  const EVENT_TOUCHMOVE = `touchmove${EVENT_KEY$a}`;\n  const EVENT_TOUCHEND = `touchend${EVENT_KEY$a}`;\n  const EVENT_POINTERDOWN = `pointerdown${EVENT_KEY$a}`;\n  const EVENT_POINTERUP = `pointerup${EVENT_KEY$a}`;\n  const EVENT_DRAG_START = `dragstart${EVENT_KEY$a}`;\n  const EVENT_LOAD_DATA_API$2 = `load${EVENT_KEY$a}${DATA_API_KEY$6}`;\n  const EVENT_CLICK_DATA_API$5 = `click${EVENT_KEY$a}${DATA_API_KEY$6}`;\n  const CLASS_NAME_CAROUSEL = 'carousel';\n  const CLASS_NAME_ACTIVE$2 = 'active';\n  const CLASS_NAME_SLIDE = 'slide';\n  const CLASS_NAME_END = 'carousel-item-end';\n  const CLASS_NAME_START = 'carousel-item-start';\n  const CLASS_NAME_NEXT = 'carousel-item-next';\n  const CLASS_NAME_PREV = 'carousel-item-prev';\n  const CLASS_NAME_POINTER_EVENT = 'pointer-event';\n  const SELECTOR_ACTIVE$1 = '.active';\n  const SELECTOR_ACTIVE_ITEM = '.active.carousel-item';\n  const SELECTOR_ITEM = '.carousel-item';\n  const SELECTOR_ITEM_IMG = '.carousel-item img';\n  const SELECTOR_NEXT_PREV = '.carousel-item-next, .carousel-item-prev';\n  const SELECTOR_INDICATORS = '.carousel-indicators';\n  const SELECTOR_INDICATOR = '[data-bs-target]';\n  const SELECTOR_DATA_SLIDE = '[data-bs-slide], [data-bs-slide-to]';\n  const SELECTOR_DATA_RIDE = '[data-bs-ride=\"carousel\"]';\n  const POINTER_TYPE_TOUCH = 'touch';\n  const POINTER_TYPE_PEN = 'pen';\n  /**\n   * ------------------------------------------------------------------------\n   * Class Definition\n   * ------------------------------------------------------------------------\n   */\n\n  class Carousel extends BaseComponent {\n    constructor(element, config) {\n      super(element);\n      this._items = null;\n      this._interval = null;\n      this._activeElement = null;\n      this._isPaused = false;\n      this._isSliding = false;\n      this.touchTimeout = null;\n      this.touchStartX = 0;\n      this.touchDeltaX = 0;\n      this._config = this._getConfig(config);\n      this._indicatorsElement = SelectorEngine.findOne(SELECTOR_INDICATORS, this._element);\n      this._touchSupported = 'ontouchstart' in document.documentElement || navigator.maxTouchPoints > 0;\n      this._pointerEvent = Boolean(window.PointerEvent);\n\n      this._addEventListeners();\n    } // Getters\n\n\n    static get Default() {\n      return Default$a;\n    }\n\n    static get NAME() {\n      return NAME$b;\n    } // Public\n\n\n    next() {\n      this._slide(ORDER_NEXT);\n    }\n\n    nextWhenVisible() {\n      // Don't call next when the page isn't visible\n      // or the carousel or its parent isn't visible\n      if (!document.hidden && isVisible(this._element)) {\n        this.next();\n      }\n    }\n\n    prev() {\n      this._slide(ORDER_PREV);\n    }\n\n    pause(event) {\n      if (!event) {\n        this._isPaused = true;\n      }\n\n      if (SelectorEngine.findOne(SELECTOR_NEXT_PREV, this._element)) {\n        triggerTransitionEnd(this._element);\n        this.cycle(true);\n      }\n\n      clearInterval(this._interval);\n      this._interval = null;\n    }\n\n    cycle(event) {\n      if (!event) {\n        this._isPaused = false;\n      }\n\n      if (this._interval) {\n        clearInterval(this._interval);\n        this._interval = null;\n      }\n\n      if (this._config && this._config.interval && !this._isPaused) {\n        this._updateInterval();\n\n        this._interval = setInterval((document.visibilityState ? this.nextWhenVisible : this.next).bind(this), this._config.interval);\n      }\n    }\n\n    to(index) {\n      this._activeElement = SelectorEngine.findOne(SELECTOR_ACTIVE_ITEM, this._element);\n\n      const activeIndex = this._getItemIndex(this._activeElement);\n\n      if (index > this._items.length - 1 || index < 0) {\n        return;\n      }\n\n      if (this._isSliding) {\n        EventHandler.one(this._element, EVENT_SLID, () => this.to(index));\n        return;\n      }\n\n      if (activeIndex === index) {\n        this.pause();\n        this.cycle();\n        return;\n      }\n\n      const order = index > activeIndex ? ORDER_NEXT : ORDER_PREV;\n\n      this._slide(order, this._items[index]);\n    } // Private\n\n\n    _getConfig(config) {\n      config = { ...Default$a,\n        ...Manipulator.getDataAttributes(this._element),\n        ...(typeof config === 'object' ? config : {})\n      };\n      typeCheckConfig(NAME$b, config, DefaultType$a);\n      return config;\n    }\n\n    _handleSwipe() {\n      const absDeltax = Math.abs(this.touchDeltaX);\n\n      if (absDeltax <= SWIPE_THRESHOLD) {\n        return;\n      }\n\n      const direction = absDeltax / this.touchDeltaX;\n      this.touchDeltaX = 0;\n\n      if (!direction) {\n        return;\n      }\n\n      this._slide(direction > 0 ? DIRECTION_RIGHT : DIRECTION_LEFT);\n    }\n\n    _addEventListeners() {\n      if (this._config.keyboard) {\n        EventHandler.on(this._element, EVENT_KEYDOWN, event => this._keydown(event));\n      }\n\n      if (this._config.pause === 'hover') {\n        EventHandler.on(this._element, EVENT_MOUSEENTER, event => this.pause(event));\n        EventHandler.on(this._element, EVENT_MOUSELEAVE, event => this.cycle(event));\n      }\n\n      if (this._config.touch && this._touchSupported) {\n        this._addTouchEventListeners();\n      }\n    }\n\n    _addTouchEventListeners() {\n      const start = event => {\n        if (this._pointerEvent && (event.pointerType === POINTER_TYPE_PEN || event.pointerType === POINTER_TYPE_TOUCH)) {\n          this.touchStartX = event.clientX;\n        } else if (!this._pointerEvent) {\n          this.touchStartX = event.touches[0].clientX;\n        }\n      };\n\n      const move = event => {\n        // ensure swiping with one touch and not pinching\n        this.touchDeltaX = event.touches && event.touches.length > 1 ? 0 : event.touches[0].clientX - this.touchStartX;\n      };\n\n      const end = event => {\n        if (this._pointerEvent && (event.pointerType === POINTER_TYPE_PEN || event.pointerType === POINTER_TYPE_TOUCH)) {\n          this.touchDeltaX = event.clientX - this.touchStartX;\n        }\n\n        this._handleSwipe();\n\n        if (this._config.pause === 'hover') {\n          // If it's a touch-enabled device, mouseenter/leave are fired as\n          // part of the mouse compatibility events on first tap - the carousel\n          // would stop cycling until user tapped out of it;\n          // here, we listen for touchend, explicitly pause the carousel\n          // (as if it's the second time we tap on it, mouseenter compat event\n          // is NOT fired) and after a timeout (to allow for mouse compatibility\n          // events to fire) we explicitly restart cycling\n          this.pause();\n\n          if (this.touchTimeout) {\n            clearTimeout(this.touchTimeout);\n          }\n\n          this.touchTimeout = setTimeout(event => this.cycle(event), TOUCHEVENT_COMPAT_WAIT + this._config.interval);\n        }\n      };\n\n      SelectorEngine.find(SELECTOR_ITEM_IMG, this._element).forEach(itemImg => {\n        EventHandler.on(itemImg, EVENT_DRAG_START, e => e.preventDefault());\n      });\n\n      if (this._pointerEvent) {\n        EventHandler.on(this._element, EVENT_POINTERDOWN, event => start(event));\n        EventHandler.on(this._element, EVENT_POINTERUP, event => end(event));\n\n        this._element.classList.add(CLASS_NAME_POINTER_EVENT);\n      } else {\n        EventHandler.on(this._element, EVENT_TOUCHSTART, event => start(event));\n        EventHandler.on(this._element, EVENT_TOUCHMOVE, event => move(event));\n        EventHandler.on(this._element, EVENT_TOUCHEND, event => end(event));\n      }\n    }\n\n    _keydown(event) {\n      if (/input|textarea/i.test(event.target.tagName)) {\n        return;\n      }\n\n      const direction = KEY_TO_DIRECTION[event.key];\n\n      if (direction) {\n        event.preventDefault();\n\n        this._slide(direction);\n      }\n    }\n\n    _getItemIndex(element) {\n      this._items = element && element.parentNode ? SelectorEngine.find(SELECTOR_ITEM, element.parentNode) : [];\n      return this._items.indexOf(element);\n    }\n\n    _getItemByOrder(order, activeElement) {\n      const isNext = order === ORDER_NEXT;\n      return getNextActiveElement(this._items, activeElement, isNext, this._config.wrap);\n    }\n\n    _triggerSlideEvent(relatedTarget, eventDirectionName) {\n      const targetIndex = this._getItemIndex(relatedTarget);\n\n      const fromIndex = this._getItemIndex(SelectorEngine.findOne(SELECTOR_ACTIVE_ITEM, this._element));\n\n      return EventHandler.trigger(this._element, EVENT_SLIDE, {\n        relatedTarget,\n        direction: eventDirectionName,\n        from: fromIndex,\n        to: targetIndex\n      });\n    }\n\n    _setActiveIndicatorElement(element) {\n      if (this._indicatorsElement) {\n        const activeIndicator = SelectorEngine.findOne(SELECTOR_ACTIVE$1, this._indicatorsElement);\n        activeIndicator.classList.remove(CLASS_NAME_ACTIVE$2);\n        activeIndicator.removeAttribute('aria-current');\n        const indicators = SelectorEngine.find(SELECTOR_INDICATOR, this._indicatorsElement);\n\n        for (let i = 0; i < indicators.length; i++) {\n          if (Number.parseInt(indicators[i].getAttribute('data-bs-slide-to'), 10) === this._getItemIndex(element)) {\n            indicators[i].classList.add(CLASS_NAME_ACTIVE$2);\n            indicators[i].setAttribute('aria-current', 'true');\n            break;\n          }\n        }\n      }\n    }\n\n    _updateInterval() {\n      const element = this._activeElement || SelectorEngine.findOne(SELECTOR_ACTIVE_ITEM, this._element);\n\n      if (!element) {\n        return;\n      }\n\n      const elementInterval = Number.parseInt(element.getAttribute('data-bs-interval'), 10);\n\n      if (elementInterval) {\n        this._config.defaultInterval = this._config.defaultInterval || this._config.interval;\n        this._config.interval = elementInterval;\n      } else {\n        this._config.interval = this._config.defaultInterval || this._config.interval;\n      }\n    }\n\n    _slide(directionOrOrder, element) {\n      const order = this._directionToOrder(directionOrOrder);\n\n      const activeElement = SelectorEngine.findOne(SELECTOR_ACTIVE_ITEM, this._element);\n\n      const activeElementIndex = this._getItemIndex(activeElement);\n\n      const nextElement = element || this._getItemByOrder(order, activeElement);\n\n      const nextElementIndex = this._getItemIndex(nextElement);\n\n      const isCycling = Boolean(this._interval);\n      const isNext = order === ORDER_NEXT;\n      const directionalClassName = isNext ? CLASS_NAME_START : CLASS_NAME_END;\n      const orderClassName = isNext ? CLASS_NAME_NEXT : CLASS_NAME_PREV;\n\n      const eventDirectionName = this._orderToDirection(order);\n\n      if (nextElement && nextElement.classList.contains(CLASS_NAME_ACTIVE$2)) {\n        this._isSliding = false;\n        return;\n      }\n\n      if (this._isSliding) {\n        return;\n      }\n\n      const slideEvent = this._triggerSlideEvent(nextElement, eventDirectionName);\n\n      if (slideEvent.defaultPrevented) {\n        return;\n      }\n\n      if (!activeElement || !nextElement) {\n        // Some weirdness is happening, so we bail\n        return;\n      }\n\n      this._isSliding = true;\n\n      if (isCycling) {\n        this.pause();\n      }\n\n      this._setActiveIndicatorElement(nextElement);\n\n      this._activeElement = nextElement;\n\n      const triggerSlidEvent = () => {\n        EventHandler.trigger(this._element, EVENT_SLID, {\n          relatedTarget: nextElement,\n          direction: eventDirectionName,\n          from: activeElementIndex,\n          to: nextElementIndex\n        });\n      };\n\n      if (this._element.classList.contains(CLASS_NAME_SLIDE)) {\n        nextElement.classList.add(orderClassName);\n        reflow(nextElement);\n        activeElement.classList.add(directionalClassName);\n        nextElement.classList.add(directionalClassName);\n\n        const completeCallBack = () => {\n          nextElement.classList.remove(directionalClassName, orderClassName);\n          nextElement.classList.add(CLASS_NAME_ACTIVE$2);\n          activeElement.classList.remove(CLASS_NAME_ACTIVE$2, orderClassName, directionalClassName);\n          this._isSliding = false;\n          setTimeout(triggerSlidEvent, 0);\n        };\n\n        this._queueCallback(completeCallBack, activeElement, true);\n      } else {\n        activeElement.classList.remove(CLASS_NAME_ACTIVE$2);\n        nextElement.classList.add(CLASS_NAME_ACTIVE$2);\n        this._isSliding = false;\n        triggerSlidEvent();\n      }\n\n      if (isCycling) {\n        this.cycle();\n      }\n    }\n\n    _directionToOrder(direction) {\n      if (![DIRECTION_RIGHT, DIRECTION_LEFT].includes(direction)) {\n        return direction;\n      }\n\n      if (isRTL()) {\n        return direction === DIRECTION_LEFT ? ORDER_PREV : ORDER_NEXT;\n      }\n\n      return direction === DIRECTION_LEFT ? ORDER_NEXT : ORDER_PREV;\n    }\n\n    _orderToDirection(order) {\n      if (![ORDER_NEXT, ORDER_PREV].includes(order)) {\n        return order;\n      }\n\n      if (isRTL()) {\n        return order === ORDER_PREV ? DIRECTION_LEFT : DIRECTION_RIGHT;\n      }\n\n      return order === ORDER_PREV ? DIRECTION_RIGHT : DIRECTION_LEFT;\n    } // Static\n\n\n    static carouselInterface(element, config) {\n      const data = Carousel.getOrCreateInstance(element, config);\n      let {\n        _config\n      } = data;\n\n      if (typeof config === 'object') {\n        _config = { ..._config,\n          ...config\n        };\n      }\n\n      const action = typeof config === 'string' ? config : _config.slide;\n\n      if (typeof config === 'number') {\n        data.to(config);\n      } else if (typeof action === 'string') {\n        if (typeof data[action] === 'undefined') {\n          throw new TypeError(`No method named \"${action}\"`);\n        }\n\n        data[action]();\n      } else if (_config.interval && _config.ride) {\n        data.pause();\n        data.cycle();\n      }\n    }\n\n    static jQueryInterface(config) {\n      return this.each(function () {\n        Carousel.carouselInterface(this, config);\n      });\n    }\n\n    static dataApiClickHandler(event) {\n      const target = getElementFromSelector(this);\n\n      if (!target || !target.classList.contains(CLASS_NAME_CAROUSEL)) {\n        return;\n      }\n\n      const config = { ...Manipulator.getDataAttributes(target),\n        ...Manipulator.getDataAttributes(this)\n      };\n      const slideIndex = this.getAttribute('data-bs-slide-to');\n\n      if (slideIndex) {\n        config.interval = false;\n      }\n\n      Carousel.carouselInterface(target, config);\n\n      if (slideIndex) {\n        Carousel.getInstance(target).to(slideIndex);\n      }\n\n      event.preventDefault();\n    }\n\n  }\n  /**\n   * ------------------------------------------------------------------------\n   * Data Api implementation\n   * ------------------------------------------------------------------------\n   */\n\n\n  EventHandler.on(document, EVENT_CLICK_DATA_API$5, SELECTOR_DATA_SLIDE, Carousel.dataApiClickHandler);\n  EventHandler.on(window, EVENT_LOAD_DATA_API$2, () => {\n    const carousels = SelectorEngine.find(SELECTOR_DATA_RIDE);\n\n    for (let i = 0, len = carousels.length; i < len; i++) {\n      Carousel.carouselInterface(carousels[i], Carousel.getInstance(carousels[i]));\n    }\n  });\n  /**\n   * ------------------------------------------------------------------------\n   * jQuery\n   * ------------------------------------------------------------------------\n   * add .Carousel to jQuery only if jQuery is present\n   */\n\n  defineJQueryPlugin(Carousel);\n\n  /**\n   * --------------------------------------------------------------------------\n   * Bootstrap (v5.1.0): collapse.js\n   * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n   * --------------------------------------------------------------------------\n   */\n  /**\n   * ------------------------------------------------------------------------\n   * Constants\n   * ------------------------------------------------------------------------\n   */\n\n  const NAME$a = 'collapse';\n  const DATA_KEY$9 = 'bs.collapse';\n  const EVENT_KEY$9 = `.${DATA_KEY$9}`;\n  const DATA_API_KEY$5 = '.data-api';\n  const Default$9 = {\n    toggle: true,\n    parent: null\n  };\n  const DefaultType$9 = {\n    toggle: 'boolean',\n    parent: '(null|element)'\n  };\n  const EVENT_SHOW$5 = `show${EVENT_KEY$9}`;\n  const EVENT_SHOWN$5 = `shown${EVENT_KEY$9}`;\n  const EVENT_HIDE$5 = `hide${EVENT_KEY$9}`;\n  const EVENT_HIDDEN$5 = `hidden${EVENT_KEY$9}`;\n  const EVENT_CLICK_DATA_API$4 = `click${EVENT_KEY$9}${DATA_API_KEY$5}`;\n  const CLASS_NAME_SHOW$7 = 'show';\n  const CLASS_NAME_COLLAPSE = 'collapse';\n  const CLASS_NAME_COLLAPSING = 'collapsing';\n  const CLASS_NAME_COLLAPSED = 'collapsed';\n  const CLASS_NAME_HORIZONTAL = 'collapse-horizontal';\n  const WIDTH = 'width';\n  const HEIGHT = 'height';\n  const SELECTOR_ACTIVES = '.show, .collapsing';\n  const SELECTOR_DATA_TOGGLE$4 = '[data-bs-toggle=\"collapse\"]';\n  /**\n   * ------------------------------------------------------------------------\n   * Class Definition\n   * ------------------------------------------------------------------------\n   */\n\n  class Collapse extends BaseComponent {\n    constructor(element, config) {\n      super(element);\n      this._isTransitioning = false;\n      this._config = this._getConfig(config);\n      this._triggerArray = [];\n      const toggleList = SelectorEngine.find(SELECTOR_DATA_TOGGLE$4);\n\n      for (let i = 0, len = toggleList.length; i < len; i++) {\n        const elem = toggleList[i];\n        const selector = getSelectorFromElement(elem);\n        const filterElement = SelectorEngine.find(selector).filter(foundElem => foundElem === this._element);\n\n        if (selector !== null && filterElement.length) {\n          this._selector = selector;\n\n          this._triggerArray.push(elem);\n        }\n      }\n\n      this._initializeChildren();\n\n      if (!this._config.parent) {\n        this._addAriaAndCollapsedClass(this._triggerArray, this._isShown());\n      }\n\n      if (this._config.toggle) {\n        this.toggle();\n      }\n    } // Getters\n\n\n    static get Default() {\n      return Default$9;\n    }\n\n    static get NAME() {\n      return NAME$a;\n    } // Public\n\n\n    toggle() {\n      if (this._isShown()) {\n        this.hide();\n      } else {\n        this.show();\n      }\n    }\n\n    show() {\n      if (this._isTransitioning || this._isShown()) {\n        return;\n      }\n\n      let actives = [];\n      let activesData;\n\n      if (this._config.parent) {\n        const children = SelectorEngine.find(`.${CLASS_NAME_COLLAPSE} .${CLASS_NAME_COLLAPSE}`, this._config.parent);\n        actives = SelectorEngine.find(SELECTOR_ACTIVES, this._config.parent).filter(elem => !children.includes(elem)); // remove children if greater depth\n      }\n\n      const container = SelectorEngine.findOne(this._selector);\n\n      if (actives.length) {\n        const tempActiveData = actives.find(elem => container !== elem);\n        activesData = tempActiveData ? Collapse.getInstance(tempActiveData) : null;\n\n        if (activesData && activesData._isTransitioning) {\n          return;\n        }\n      }\n\n      const startEvent = EventHandler.trigger(this._element, EVENT_SHOW$5);\n\n      if (startEvent.defaultPrevented) {\n        return;\n      }\n\n      actives.forEach(elemActive => {\n        if (container !== elemActive) {\n          Collapse.getOrCreateInstance(elemActive, {\n            toggle: false\n          }).hide();\n        }\n\n        if (!activesData) {\n          Data.set(elemActive, DATA_KEY$9, null);\n        }\n      });\n\n      const dimension = this._getDimension();\n\n      this._element.classList.remove(CLASS_NAME_COLLAPSE);\n\n      this._element.classList.add(CLASS_NAME_COLLAPSING);\n\n      this._element.style[dimension] = 0;\n\n      this._addAriaAndCollapsedClass(this._triggerArray, true);\n\n      this._isTransitioning = true;\n\n      const complete = () => {\n        this._isTransitioning = false;\n\n        this._element.classList.remove(CLASS_NAME_COLLAPSING);\n\n        this._element.classList.add(CLASS_NAME_COLLAPSE, CLASS_NAME_SHOW$7);\n\n        this._element.style[dimension] = '';\n        EventHandler.trigger(this._element, EVENT_SHOWN$5);\n      };\n\n      const capitalizedDimension = dimension[0].toUpperCase() + dimension.slice(1);\n      const scrollSize = `scroll${capitalizedDimension}`;\n\n      this._queueCallback(complete, this._element, true);\n\n      this._element.style[dimension] = `${this._element[scrollSize]}px`;\n    }\n\n    hide() {\n      if (this._isTransitioning || !this._isShown()) {\n        return;\n      }\n\n      const startEvent = EventHandler.trigger(this._element, EVENT_HIDE$5);\n\n      if (startEvent.defaultPrevented) {\n        return;\n      }\n\n      const dimension = this._getDimension();\n\n      this._element.style[dimension] = `${this._element.getBoundingClientRect()[dimension]}px`;\n      reflow(this._element);\n\n      this._element.classList.add(CLASS_NAME_COLLAPSING);\n\n      this._element.classList.remove(CLASS_NAME_COLLAPSE, CLASS_NAME_SHOW$7);\n\n      const triggerArrayLength = this._triggerArray.length;\n\n      for (let i = 0; i < triggerArrayLength; i++) {\n        const trigger = this._triggerArray[i];\n        const elem = getElementFromSelector(trigger);\n\n        if (elem && !this._isShown(elem)) {\n          this._addAriaAndCollapsedClass([trigger], false);\n        }\n      }\n\n      this._isTransitioning = true;\n\n      const complete = () => {\n        this._isTransitioning = false;\n\n        this._element.classList.remove(CLASS_NAME_COLLAPSING);\n\n        this._element.classList.add(CLASS_NAME_COLLAPSE);\n\n        EventHandler.trigger(this._element, EVENT_HIDDEN$5);\n      };\n\n      this._element.style[dimension] = '';\n\n      this._queueCallback(complete, this._element, true);\n    }\n\n    _isShown(element = this._element) {\n      return element.classList.contains(CLASS_NAME_SHOW$7);\n    } // Private\n\n\n    _getConfig(config) {\n      config = { ...Default$9,\n        ...Manipulator.getDataAttributes(this._element),\n        ...config\n      };\n      config.toggle = Boolean(config.toggle); // Coerce string values\n\n      config.parent = getElement(config.parent);\n      typeCheckConfig(NAME$a, config, DefaultType$9);\n      return config;\n    }\n\n    _getDimension() {\n      return this._element.classList.contains(CLASS_NAME_HORIZONTAL) ? WIDTH : HEIGHT;\n    }\n\n    _initializeChildren() {\n      if (!this._config.parent) {\n        return;\n      }\n\n      const children = SelectorEngine.find(`.${CLASS_NAME_COLLAPSE} .${CLASS_NAME_COLLAPSE}`, this._config.parent);\n      SelectorEngine.find(SELECTOR_DATA_TOGGLE$4, this._config.parent).filter(elem => !children.includes(elem)).forEach(element => {\n        const selected = getElementFromSelector(element);\n\n        if (selected) {\n          this._addAriaAndCollapsedClass([element], this._isShown(selected));\n        }\n      });\n    }\n\n    _addAriaAndCollapsedClass(triggerArray, isOpen) {\n      if (!triggerArray.length) {\n        return;\n      }\n\n      triggerArray.forEach(elem => {\n        if (isOpen) {\n          elem.classList.remove(CLASS_NAME_COLLAPSED);\n        } else {\n          elem.classList.add(CLASS_NAME_COLLAPSED);\n        }\n\n        elem.setAttribute('aria-expanded', isOpen);\n      });\n    } // Static\n\n\n    static jQueryInterface(config) {\n      return this.each(function () {\n        const _config = {};\n\n        if (typeof config === 'string' && /show|hide/.test(config)) {\n          _config.toggle = false;\n        }\n\n        const data = Collapse.getOrCreateInstance(this, _config);\n\n        if (typeof config === 'string') {\n          if (typeof data[config] === 'undefined') {\n            throw new TypeError(`No method named \"${config}\"`);\n          }\n\n          data[config]();\n        }\n      });\n    }\n\n  }\n  /**\n   * ------------------------------------------------------------------------\n   * Data Api implementation\n   * ------------------------------------------------------------------------\n   */\n\n\n  EventHandler.on(document, EVENT_CLICK_DATA_API$4, SELECTOR_DATA_TOGGLE$4, function (event) {\n    // preventDefault only for <a> elements (which change the URL) not inside the collapsible element\n    if (event.target.tagName === 'A' || event.delegateTarget && event.delegateTarget.tagName === 'A') {\n      event.preventDefault();\n    }\n\n    const selector = getSelectorFromElement(this);\n    const selectorElements = SelectorEngine.find(selector);\n    selectorElements.forEach(element => {\n      Collapse.getOrCreateInstance(element, {\n        toggle: false\n      }).toggle();\n    });\n  });\n  /**\n   * ------------------------------------------------------------------------\n   * jQuery\n   * ------------------------------------------------------------------------\n   * add .Collapse to jQuery only if jQuery is present\n   */\n\n  defineJQueryPlugin(Collapse);\n\n  var top = 'top';\n  var bottom = 'bottom';\n  var right = 'right';\n  var left = 'left';\n  var auto = 'auto';\n  var basePlacements = [top, bottom, right, left];\n  var start = 'start';\n  var end = 'end';\n  var clippingParents = 'clippingParents';\n  var viewport = 'viewport';\n  var popper = 'popper';\n  var reference = 'reference';\n  var variationPlacements = /*#__PURE__*/basePlacements.reduce(function (acc, placement) {\n    return acc.concat([placement + \"-\" + start, placement + \"-\" + end]);\n  }, []);\n  var placements = /*#__PURE__*/[].concat(basePlacements, [auto]).reduce(function (acc, placement) {\n    return acc.concat([placement, placement + \"-\" + start, placement + \"-\" + end]);\n  }, []); // modifiers that need to read the DOM\n\n  var beforeRead = 'beforeRead';\n  var read = 'read';\n  var afterRead = 'afterRead'; // pure-logic modifiers\n\n  var beforeMain = 'beforeMain';\n  var main = 'main';\n  var afterMain = 'afterMain'; // modifier with the purpose to write to the DOM (or write into a framework state)\n\n  var beforeWrite = 'beforeWrite';\n  var write = 'write';\n  var afterWrite = 'afterWrite';\n  var modifierPhases = [beforeRead, read, afterRead, beforeMain, main, afterMain, beforeWrite, write, afterWrite];\n\n  function getNodeName(element) {\n    return element ? (element.nodeName || '').toLowerCase() : null;\n  }\n\n  function getWindow(node) {\n    if (node == null) {\n      return window;\n    }\n\n    if (node.toString() !== '[object Window]') {\n      var ownerDocument = node.ownerDocument;\n      return ownerDocument ? ownerDocument.defaultView || window : window;\n    }\n\n    return node;\n  }\n\n  function isElement(node) {\n    var OwnElement = getWindow(node).Element;\n    return node instanceof OwnElement || node instanceof Element;\n  }\n\n  function isHTMLElement(node) {\n    var OwnElement = getWindow(node).HTMLElement;\n    return node instanceof OwnElement || node instanceof HTMLElement;\n  }\n\n  function isShadowRoot(node) {\n    // IE 11 has no ShadowRoot\n    if (typeof ShadowRoot === 'undefined') {\n      return false;\n    }\n\n    var OwnElement = getWindow(node).ShadowRoot;\n    return node instanceof OwnElement || node instanceof ShadowRoot;\n  }\n\n  // and applies them to the HTMLElements such as popper and arrow\n\n  function applyStyles(_ref) {\n    var state = _ref.state;\n    Object.keys(state.elements).forEach(function (name) {\n      var style = state.styles[name] || {};\n      var attributes = state.attributes[name] || {};\n      var element = state.elements[name]; // arrow is optional + virtual elements\n\n      if (!isHTMLElement(element) || !getNodeName(element)) {\n        return;\n      } // Flow doesn't support to extend this property, but it's the most\n      // effective way to apply styles to an HTMLElement\n      // $FlowFixMe[cannot-write]\n\n\n      Object.assign(element.style, style);\n      Object.keys(attributes).forEach(function (name) {\n        var value = attributes[name];\n\n        if (value === false) {\n          element.removeAttribute(name);\n        } else {\n          element.setAttribute(name, value === true ? '' : value);\n        }\n      });\n    });\n  }\n\n  function effect$2(_ref2) {\n    var state = _ref2.state;\n    var initialStyles = {\n      popper: {\n        position: state.options.strategy,\n        left: '0',\n        top: '0',\n        margin: '0'\n      },\n      arrow: {\n        position: 'absolute'\n      },\n      reference: {}\n    };\n    Object.assign(state.elements.popper.style, initialStyles.popper);\n    state.styles = initialStyles;\n\n    if (state.elements.arrow) {\n      Object.assign(state.elements.arrow.style, initialStyles.arrow);\n    }\n\n    return function () {\n      Object.keys(state.elements).forEach(function (name) {\n        var element = state.elements[name];\n        var attributes = state.attributes[name] || {};\n        var styleProperties = Object.keys(state.styles.hasOwnProperty(name) ? state.styles[name] : initialStyles[name]); // Set all values to an empty string to unset them\n\n        var style = styleProperties.reduce(function (style, property) {\n          style[property] = '';\n          return style;\n        }, {}); // arrow is optional + virtual elements\n\n        if (!isHTMLElement(element) || !getNodeName(element)) {\n          return;\n        }\n\n        Object.assign(element.style, style);\n        Object.keys(attributes).forEach(function (attribute) {\n          element.removeAttribute(attribute);\n        });\n      });\n    };\n  } // eslint-disable-next-line import/no-unused-modules\n\n\n  var applyStyles$1 = {\n    name: 'applyStyles',\n    enabled: true,\n    phase: 'write',\n    fn: applyStyles,\n    effect: effect$2,\n    requires: ['computeStyles']\n  };\n\n  function getBasePlacement(placement) {\n    return placement.split('-')[0];\n  }\n\n  var round$1 = Math.round;\n  function getBoundingClientRect(element, includeScale) {\n    if (includeScale === void 0) {\n      includeScale = false;\n    }\n\n    var rect = element.getBoundingClientRect();\n    var scaleX = 1;\n    var scaleY = 1;\n\n    if (isHTMLElement(element) && includeScale) {\n      // Fallback to 1 in case both values are `0`\n      scaleX = rect.width / element.offsetWidth || 1;\n      scaleY = rect.height / element.offsetHeight || 1;\n    }\n\n    return {\n      width: round$1(rect.width / scaleX),\n      height: round$1(rect.height / scaleY),\n      top: round$1(rect.top / scaleY),\n      right: round$1(rect.right / scaleX),\n      bottom: round$1(rect.bottom / scaleY),\n      left: round$1(rect.left / scaleX),\n      x: round$1(rect.left / scaleX),\n      y: round$1(rect.top / scaleY)\n    };\n  }\n\n  // means it doesn't take into account transforms.\n\n  function getLayoutRect(element) {\n    var clientRect = getBoundingClientRect(element); // Use the clientRect sizes if it's not been transformed.\n    // Fixes https://github.com/popperjs/popper-core/issues/1223\n\n    var width = element.offsetWidth;\n    var height = element.offsetHeight;\n\n    if (Math.abs(clientRect.width - width) <= 1) {\n      width = clientRect.width;\n    }\n\n    if (Math.abs(clientRect.height - height) <= 1) {\n      height = clientRect.height;\n    }\n\n    return {\n      x: element.offsetLeft,\n      y: element.offsetTop,\n      width: width,\n      height: height\n    };\n  }\n\n  function contains(parent, child) {\n    var rootNode = child.getRootNode && child.getRootNode(); // First, attempt with faster native method\n\n    if (parent.contains(child)) {\n      return true;\n    } // then fallback to custom implementation with Shadow DOM support\n    else if (rootNode && isShadowRoot(rootNode)) {\n        var next = child;\n\n        do {\n          if (next && parent.isSameNode(next)) {\n            return true;\n          } // $FlowFixMe[prop-missing]: need a better way to handle this...\n\n\n          next = next.parentNode || next.host;\n        } while (next);\n      } // Give up, the result is false\n\n\n    return false;\n  }\n\n  function getComputedStyle$1(element) {\n    return getWindow(element).getComputedStyle(element);\n  }\n\n  function isTableElement(element) {\n    return ['table', 'td', 'th'].indexOf(getNodeName(element)) >= 0;\n  }\n\n  function getDocumentElement(element) {\n    // $FlowFixMe[incompatible-return]: assume body is always available\n    return ((isElement(element) ? element.ownerDocument : // $FlowFixMe[prop-missing]\n    element.document) || window.document).documentElement;\n  }\n\n  function getParentNode(element) {\n    if (getNodeName(element) === 'html') {\n      return element;\n    }\n\n    return (// this is a quicker (but less type safe) way to save quite some bytes from the bundle\n      // $FlowFixMe[incompatible-return]\n      // $FlowFixMe[prop-missing]\n      element.assignedSlot || // step into the shadow DOM of the parent of a slotted node\n      element.parentNode || ( // DOM Element detected\n      isShadowRoot(element) ? element.host : null) || // ShadowRoot detected\n      // $FlowFixMe[incompatible-call]: HTMLElement is a Node\n      getDocumentElement(element) // fallback\n\n    );\n  }\n\n  function getTrueOffsetParent(element) {\n    if (!isHTMLElement(element) || // https://github.com/popperjs/popper-core/issues/837\n    getComputedStyle$1(element).position === 'fixed') {\n      return null;\n    }\n\n    return element.offsetParent;\n  } // `.offsetParent` reports `null` for fixed elements, while absolute elements\n  // return the containing block\n\n\n  function getContainingBlock(element) {\n    var isFirefox = navigator.userAgent.toLowerCase().indexOf('firefox') !== -1;\n    var isIE = navigator.userAgent.indexOf('Trident') !== -1;\n\n    if (isIE && isHTMLElement(element)) {\n      // In IE 9, 10 and 11 fixed elements containing block is always established by the viewport\n      var elementCss = getComputedStyle$1(element);\n\n      if (elementCss.position === 'fixed') {\n        return null;\n      }\n    }\n\n    var currentNode = getParentNode(element);\n\n    while (isHTMLElement(currentNode) && ['html', 'body'].indexOf(getNodeName(currentNode)) < 0) {\n      var css = getComputedStyle$1(currentNode); // This is non-exhaustive but covers the most common CSS properties that\n      // create a containing block.\n      // https://developer.mozilla.org/en-US/docs/Web/CSS/Containing_block#identifying_the_containing_block\n\n      if (css.transform !== 'none' || css.perspective !== 'none' || css.contain === 'paint' || ['transform', 'perspective'].indexOf(css.willChange) !== -1 || isFirefox && css.willChange === 'filter' || isFirefox && css.filter && css.filter !== 'none') {\n        return currentNode;\n      } else {\n        currentNode = currentNode.parentNode;\n      }\n    }\n\n    return null;\n  } // Gets the closest ancestor positioned element. Handles some edge cases,\n  // such as table ancestors and cross browser bugs.\n\n\n  function getOffsetParent(element) {\n    var window = getWindow(element);\n    var offsetParent = getTrueOffsetParent(element);\n\n    while (offsetParent && isTableElement(offsetParent) && getComputedStyle$1(offsetParent).position === 'static') {\n      offsetParent = getTrueOffsetParent(offsetParent);\n    }\n\n    if (offsetParent && (getNodeName(offsetParent) === 'html' || getNodeName(offsetParent) === 'body' && getComputedStyle$1(offsetParent).position === 'static')) {\n      return window;\n    }\n\n    return offsetParent || getContainingBlock(element) || window;\n  }\n\n  function getMainAxisFromPlacement(placement) {\n    return ['top', 'bottom'].indexOf(placement) >= 0 ? 'x' : 'y';\n  }\n\n  var max = Math.max;\n  var min = Math.min;\n  var round = Math.round;\n\n  function within(min$1, value, max$1) {\n    return max(min$1, min(value, max$1));\n  }\n\n  function getFreshSideObject() {\n    return {\n      top: 0,\n      right: 0,\n      bottom: 0,\n      left: 0\n    };\n  }\n\n  function mergePaddingObject(paddingObject) {\n    return Object.assign({}, getFreshSideObject(), paddingObject);\n  }\n\n  function expandToHashMap(value, keys) {\n    return keys.reduce(function (hashMap, key) {\n      hashMap[key] = value;\n      return hashMap;\n    }, {});\n  }\n\n  var toPaddingObject = function toPaddingObject(padding, state) {\n    padding = typeof padding === 'function' ? padding(Object.assign({}, state.rects, {\n      placement: state.placement\n    })) : padding;\n    return mergePaddingObject(typeof padding !== 'number' ? padding : expandToHashMap(padding, basePlacements));\n  };\n\n  function arrow(_ref) {\n    var _state$modifiersData$;\n\n    var state = _ref.state,\n        name = _ref.name,\n        options = _ref.options;\n    var arrowElement = state.elements.arrow;\n    var popperOffsets = state.modifiersData.popperOffsets;\n    var basePlacement = getBasePlacement(state.placement);\n    var axis = getMainAxisFromPlacement(basePlacement);\n    var isVertical = [left, right].indexOf(basePlacement) >= 0;\n    var len = isVertical ? 'height' : 'width';\n\n    if (!arrowElement || !popperOffsets) {\n      return;\n    }\n\n    var paddingObject = toPaddingObject(options.padding, state);\n    var arrowRect = getLayoutRect(arrowElement);\n    var minProp = axis === 'y' ? top : left;\n    var maxProp = axis === 'y' ? bottom : right;\n    var endDiff = state.rects.reference[len] + state.rects.reference[axis] - popperOffsets[axis] - state.rects.popper[len];\n    var startDiff = popperOffsets[axis] - state.rects.reference[axis];\n    var arrowOffsetParent = getOffsetParent(arrowElement);\n    var clientSize = arrowOffsetParent ? axis === 'y' ? arrowOffsetParent.clientHeight || 0 : arrowOffsetParent.clientWidth || 0 : 0;\n    var centerToReference = endDiff / 2 - startDiff / 2; // Make sure the arrow doesn't overflow the popper if the center point is\n    // outside of the popper bounds\n\n    var min = paddingObject[minProp];\n    var max = clientSize - arrowRect[len] - paddingObject[maxProp];\n    var center = clientSize / 2 - arrowRect[len] / 2 + centerToReference;\n    var offset = within(min, center, max); // Prevents breaking syntax highlighting...\n\n    var axisProp = axis;\n    state.modifiersData[name] = (_state$modifiersData$ = {}, _state$modifiersData$[axisProp] = offset, _state$modifiersData$.centerOffset = offset - center, _state$modifiersData$);\n  }\n\n  function effect$1(_ref2) {\n    var state = _ref2.state,\n        options = _ref2.options;\n    var _options$element = options.element,\n        arrowElement = _options$element === void 0 ? '[data-popper-arrow]' : _options$element;\n\n    if (arrowElement == null) {\n      return;\n    } // CSS selector\n\n\n    if (typeof arrowElement === 'string') {\n      arrowElement = state.elements.popper.querySelector(arrowElement);\n\n      if (!arrowElement) {\n        return;\n      }\n    }\n\n    if (!contains(state.elements.popper, arrowElement)) {\n\n      return;\n    }\n\n    state.elements.arrow = arrowElement;\n  } // eslint-disable-next-line import/no-unused-modules\n\n\n  var arrow$1 = {\n    name: 'arrow',\n    enabled: true,\n    phase: 'main',\n    fn: arrow,\n    effect: effect$1,\n    requires: ['popperOffsets'],\n    requiresIfExists: ['preventOverflow']\n  };\n\n  var unsetSides = {\n    top: 'auto',\n    right: 'auto',\n    bottom: 'auto',\n    left: 'auto'\n  }; // Round the offsets to the nearest suitable subpixel based on the DPR.\n  // Zooming can change the DPR, but it seems to report a value that will\n  // cleanly divide the values into the appropriate subpixels.\n\n  function roundOffsetsByDPR(_ref) {\n    var x = _ref.x,\n        y = _ref.y;\n    var win = window;\n    var dpr = win.devicePixelRatio || 1;\n    return {\n      x: round(round(x * dpr) / dpr) || 0,\n      y: round(round(y * dpr) / dpr) || 0\n    };\n  }\n\n  function mapToStyles(_ref2) {\n    var _Object$assign2;\n\n    var popper = _ref2.popper,\n        popperRect = _ref2.popperRect,\n        placement = _ref2.placement,\n        offsets = _ref2.offsets,\n        position = _ref2.position,\n        gpuAcceleration = _ref2.gpuAcceleration,\n        adaptive = _ref2.adaptive,\n        roundOffsets = _ref2.roundOffsets;\n\n    var _ref3 = roundOffsets === true ? roundOffsetsByDPR(offsets) : typeof roundOffsets === 'function' ? roundOffsets(offsets) : offsets,\n        _ref3$x = _ref3.x,\n        x = _ref3$x === void 0 ? 0 : _ref3$x,\n        _ref3$y = _ref3.y,\n        y = _ref3$y === void 0 ? 0 : _ref3$y;\n\n    var hasX = offsets.hasOwnProperty('x');\n    var hasY = offsets.hasOwnProperty('y');\n    var sideX = left;\n    var sideY = top;\n    var win = window;\n\n    if (adaptive) {\n      var offsetParent = getOffsetParent(popper);\n      var heightProp = 'clientHeight';\n      var widthProp = 'clientWidth';\n\n      if (offsetParent === getWindow(popper)) {\n        offsetParent = getDocumentElement(popper);\n\n        if (getComputedStyle$1(offsetParent).position !== 'static') {\n          heightProp = 'scrollHeight';\n          widthProp = 'scrollWidth';\n        }\n      } // $FlowFixMe[incompatible-cast]: force type refinement, we compare offsetParent with window above, but Flow doesn't detect it\n\n\n      offsetParent = offsetParent;\n\n      if (placement === top) {\n        sideY = bottom; // $FlowFixMe[prop-missing]\n\n        y -= offsetParent[heightProp] - popperRect.height;\n        y *= gpuAcceleration ? 1 : -1;\n      }\n\n      if (placement === left) {\n        sideX = right; // $FlowFixMe[prop-missing]\n\n        x -= offsetParent[widthProp] - popperRect.width;\n        x *= gpuAcceleration ? 1 : -1;\n      }\n    }\n\n    var commonStyles = Object.assign({\n      position: position\n    }, adaptive && unsetSides);\n\n    if (gpuAcceleration) {\n      var _Object$assign;\n\n      return Object.assign({}, commonStyles, (_Object$assign = {}, _Object$assign[sideY] = hasY ? '0' : '', _Object$assign[sideX] = hasX ? '0' : '', _Object$assign.transform = (win.devicePixelRatio || 1) < 2 ? \"translate(\" + x + \"px, \" + y + \"px)\" : \"translate3d(\" + x + \"px, \" + y + \"px, 0)\", _Object$assign));\n    }\n\n    return Object.assign({}, commonStyles, (_Object$assign2 = {}, _Object$assign2[sideY] = hasY ? y + \"px\" : '', _Object$assign2[sideX] = hasX ? x + \"px\" : '', _Object$assign2.transform = '', _Object$assign2));\n  }\n\n  function computeStyles(_ref4) {\n    var state = _ref4.state,\n        options = _ref4.options;\n    var _options$gpuAccelerat = options.gpuAcceleration,\n        gpuAcceleration = _options$gpuAccelerat === void 0 ? true : _options$gpuAccelerat,\n        _options$adaptive = options.adaptive,\n        adaptive = _options$adaptive === void 0 ? true : _options$adaptive,\n        _options$roundOffsets = options.roundOffsets,\n        roundOffsets = _options$roundOffsets === void 0 ? true : _options$roundOffsets;\n\n    var commonStyles = {\n      placement: getBasePlacement(state.placement),\n      popper: state.elements.popper,\n      popperRect: state.rects.popper,\n      gpuAcceleration: gpuAcceleration\n    };\n\n    if (state.modifiersData.popperOffsets != null) {\n      state.styles.popper = Object.assign({}, state.styles.popper, mapToStyles(Object.assign({}, commonStyles, {\n        offsets: state.modifiersData.popperOffsets,\n        position: state.options.strategy,\n        adaptive: adaptive,\n        roundOffsets: roundOffsets\n      })));\n    }\n\n    if (state.modifiersData.arrow != null) {\n      state.styles.arrow = Object.assign({}, state.styles.arrow, mapToStyles(Object.assign({}, commonStyles, {\n        offsets: state.modifiersData.arrow,\n        position: 'absolute',\n        adaptive: false,\n        roundOffsets: roundOffsets\n      })));\n    }\n\n    state.attributes.popper = Object.assign({}, state.attributes.popper, {\n      'data-popper-placement': state.placement\n    });\n  } // eslint-disable-next-line import/no-unused-modules\n\n\n  var computeStyles$1 = {\n    name: 'computeStyles',\n    enabled: true,\n    phase: 'beforeWrite',\n    fn: computeStyles,\n    data: {}\n  };\n\n  var passive = {\n    passive: true\n  };\n\n  function effect(_ref) {\n    var state = _ref.state,\n        instance = _ref.instance,\n        options = _ref.options;\n    var _options$scroll = options.scroll,\n        scroll = _options$scroll === void 0 ? true : _options$scroll,\n        _options$resize = options.resize,\n        resize = _options$resize === void 0 ? true : _options$resize;\n    var window = getWindow(state.elements.popper);\n    var scrollParents = [].concat(state.scrollParents.reference, state.scrollParents.popper);\n\n    if (scroll) {\n      scrollParents.forEach(function (scrollParent) {\n        scrollParent.addEventListener('scroll', instance.update, passive);\n      });\n    }\n\n    if (resize) {\n      window.addEventListener('resize', instance.update, passive);\n    }\n\n    return function () {\n      if (scroll) {\n        scrollParents.forEach(function (scrollParent) {\n          scrollParent.removeEventListener('scroll', instance.update, passive);\n        });\n      }\n\n      if (resize) {\n        window.removeEventListener('resize', instance.update, passive);\n      }\n    };\n  } // eslint-disable-next-line import/no-unused-modules\n\n\n  var eventListeners = {\n    name: 'eventListeners',\n    enabled: true,\n    phase: 'write',\n    fn: function fn() {},\n    effect: effect,\n    data: {}\n  };\n\n  var hash$1 = {\n    left: 'right',\n    right: 'left',\n    bottom: 'top',\n    top: 'bottom'\n  };\n  function getOppositePlacement(placement) {\n    return placement.replace(/left|right|bottom|top/g, function (matched) {\n      return hash$1[matched];\n    });\n  }\n\n  var hash = {\n    start: 'end',\n    end: 'start'\n  };\n  function getOppositeVariationPlacement(placement) {\n    return placement.replace(/start|end/g, function (matched) {\n      return hash[matched];\n    });\n  }\n\n  function getWindowScroll(node) {\n    var win = getWindow(node);\n    var scrollLeft = win.pageXOffset;\n    var scrollTop = win.pageYOffset;\n    return {\n      scrollLeft: scrollLeft,\n      scrollTop: scrollTop\n    };\n  }\n\n  function getWindowScrollBarX(element) {\n    // If <html> has a CSS width greater than the viewport, then this will be\n    // incorrect for RTL.\n    // Popper 1 is broken in this case and never had a bug report so let's assume\n    // it's not an issue. I don't think anyone ever specifies width on <html>\n    // anyway.\n    // Browsers where the left scrollbar doesn't cause an issue report `0` for\n    // this (e.g. Edge 2019, IE11, Safari)\n    return getBoundingClientRect(getDocumentElement(element)).left + getWindowScroll(element).scrollLeft;\n  }\n\n  function getViewportRect(element) {\n    var win = getWindow(element);\n    var html = getDocumentElement(element);\n    var visualViewport = win.visualViewport;\n    var width = html.clientWidth;\n    var height = html.clientHeight;\n    var x = 0;\n    var y = 0; // NB: This isn't supported on iOS <= 12. If the keyboard is open, the popper\n    // can be obscured underneath it.\n    // Also, `html.clientHeight` adds the bottom bar height in Safari iOS, even\n    // if it isn't open, so if this isn't available, the popper will be detected\n    // to overflow the bottom of the screen too early.\n\n    if (visualViewport) {\n      width = visualViewport.width;\n      height = visualViewport.height; // Uses Layout Viewport (like Chrome; Safari does not currently)\n      // In Chrome, it returns a value very close to 0 (+/-) but contains rounding\n      // errors due to floating point numbers, so we need to check precision.\n      // Safari returns a number <= 0, usually < -1 when pinch-zoomed\n      // Feature detection fails in mobile emulation mode in Chrome.\n      // Math.abs(win.innerWidth / visualViewport.scale - visualViewport.width) <\n      // 0.001\n      // Fallback here: \"Not Safari\" userAgent\n\n      if (!/^((?!chrome|android).)*safari/i.test(navigator.userAgent)) {\n        x = visualViewport.offsetLeft;\n        y = visualViewport.offsetTop;\n      }\n    }\n\n    return {\n      width: width,\n      height: height,\n      x: x + getWindowScrollBarX(element),\n      y: y\n    };\n  }\n\n  // of the `<html>` and `<body>` rect bounds if horizontally scrollable\n\n  function getDocumentRect(element) {\n    var _element$ownerDocumen;\n\n    var html = getDocumentElement(element);\n    var winScroll = getWindowScroll(element);\n    var body = (_element$ownerDocumen = element.ownerDocument) == null ? void 0 : _element$ownerDocumen.body;\n    var width = max(html.scrollWidth, html.clientWidth, body ? body.scrollWidth : 0, body ? body.clientWidth : 0);\n    var height = max(html.scrollHeight, html.clientHeight, body ? body.scrollHeight : 0, body ? body.clientHeight : 0);\n    var x = -winScroll.scrollLeft + getWindowScrollBarX(element);\n    var y = -winScroll.scrollTop;\n\n    if (getComputedStyle$1(body || html).direction === 'rtl') {\n      x += max(html.clientWidth, body ? body.clientWidth : 0) - width;\n    }\n\n    return {\n      width: width,\n      height: height,\n      x: x,\n      y: y\n    };\n  }\n\n  function isScrollParent(element) {\n    // Firefox wants us to check `-x` and `-y` variations as well\n    var _getComputedStyle = getComputedStyle$1(element),\n        overflow = _getComputedStyle.overflow,\n        overflowX = _getComputedStyle.overflowX,\n        overflowY = _getComputedStyle.overflowY;\n\n    return /auto|scroll|overlay|hidden/.test(overflow + overflowY + overflowX);\n  }\n\n  function getScrollParent(node) {\n    if (['html', 'body', '#document'].indexOf(getNodeName(node)) >= 0) {\n      // $FlowFixMe[incompatible-return]: assume body is always available\n      return node.ownerDocument.body;\n    }\n\n    if (isHTMLElement(node) && isScrollParent(node)) {\n      return node;\n    }\n\n    return getScrollParent(getParentNode(node));\n  }\n\n  /*\n  given a DOM element, return the list of all scroll parents, up the list of ancesors\n  until we get to the top window object. This list is what we attach scroll listeners\n  to, because if any of these parent elements scroll, we'll need to re-calculate the\n  reference element's position.\n  */\n\n  function listScrollParents(element, list) {\n    var _element$ownerDocumen;\n\n    if (list === void 0) {\n      list = [];\n    }\n\n    var scrollParent = getScrollParent(element);\n    var isBody = scrollParent === ((_element$ownerDocumen = element.ownerDocument) == null ? void 0 : _element$ownerDocumen.body);\n    var win = getWindow(scrollParent);\n    var target = isBody ? [win].concat(win.visualViewport || [], isScrollParent(scrollParent) ? scrollParent : []) : scrollParent;\n    var updatedList = list.concat(target);\n    return isBody ? updatedList : // $FlowFixMe[incompatible-call]: isBody tells us target will be an HTMLElement here\n    updatedList.concat(listScrollParents(getParentNode(target)));\n  }\n\n  function rectToClientRect(rect) {\n    return Object.assign({}, rect, {\n      left: rect.x,\n      top: rect.y,\n      right: rect.x + rect.width,\n      bottom: rect.y + rect.height\n    });\n  }\n\n  function getInnerBoundingClientRect(element) {\n    var rect = getBoundingClientRect(element);\n    rect.top = rect.top + element.clientTop;\n    rect.left = rect.left + element.clientLeft;\n    rect.bottom = rect.top + element.clientHeight;\n    rect.right = rect.left + element.clientWidth;\n    rect.width = element.clientWidth;\n    rect.height = element.clientHeight;\n    rect.x = rect.left;\n    rect.y = rect.top;\n    return rect;\n  }\n\n  function getClientRectFromMixedType(element, clippingParent) {\n    return clippingParent === viewport ? rectToClientRect(getViewportRect(element)) : isHTMLElement(clippingParent) ? getInnerBoundingClientRect(clippingParent) : rectToClientRect(getDocumentRect(getDocumentElement(element)));\n  } // A \"clipping parent\" is an overflowable container with the characteristic of\n  // clipping (or hiding) overflowing elements with a position different from\n  // `initial`\n\n\n  function getClippingParents(element) {\n    var clippingParents = listScrollParents(getParentNode(element));\n    var canEscapeClipping = ['absolute', 'fixed'].indexOf(getComputedStyle$1(element).position) >= 0;\n    var clipperElement = canEscapeClipping && isHTMLElement(element) ? getOffsetParent(element) : element;\n\n    if (!isElement(clipperElement)) {\n      return [];\n    } // $FlowFixMe[incompatible-return]: https://github.com/facebook/flow/issues/1414\n\n\n    return clippingParents.filter(function (clippingParent) {\n      return isElement(clippingParent) && contains(clippingParent, clipperElement) && getNodeName(clippingParent) !== 'body';\n    });\n  } // Gets the maximum area that the element is visible in due to any number of\n  // clipping parents\n\n\n  function getClippingRect(element, boundary, rootBoundary) {\n    var mainClippingParents = boundary === 'clippingParents' ? getClippingParents(element) : [].concat(boundary);\n    var clippingParents = [].concat(mainClippingParents, [rootBoundary]);\n    var firstClippingParent = clippingParents[0];\n    var clippingRect = clippingParents.reduce(function (accRect, clippingParent) {\n      var rect = getClientRectFromMixedType(element, clippingParent);\n      accRect.top = max(rect.top, accRect.top);\n      accRect.right = min(rect.right, accRect.right);\n      accRect.bottom = min(rect.bottom, accRect.bottom);\n      accRect.left = max(rect.left, accRect.left);\n      return accRect;\n    }, getClientRectFromMixedType(element, firstClippingParent));\n    clippingRect.width = clippingRect.right - clippingRect.left;\n    clippingRect.height = clippingRect.bottom - clippingRect.top;\n    clippingRect.x = clippingRect.left;\n    clippingRect.y = clippingRect.top;\n    return clippingRect;\n  }\n\n  function getVariation(placement) {\n    return placement.split('-')[1];\n  }\n\n  function computeOffsets(_ref) {\n    var reference = _ref.reference,\n        element = _ref.element,\n        placement = _ref.placement;\n    var basePlacement = placement ? getBasePlacement(placement) : null;\n    var variation = placement ? getVariation(placement) : null;\n    var commonX = reference.x + reference.width / 2 - element.width / 2;\n    var commonY = reference.y + reference.height / 2 - element.height / 2;\n    var offsets;\n\n    switch (basePlacement) {\n      case top:\n        offsets = {\n          x: commonX,\n          y: reference.y - element.height\n        };\n        break;\n\n      case bottom:\n        offsets = {\n          x: commonX,\n          y: reference.y + reference.height\n        };\n        break;\n\n      case right:\n        offsets = {\n          x: reference.x + reference.width,\n          y: commonY\n        };\n        break;\n\n      case left:\n        offsets = {\n          x: reference.x - element.width,\n          y: commonY\n        };\n        break;\n\n      default:\n        offsets = {\n          x: reference.x,\n          y: reference.y\n        };\n    }\n\n    var mainAxis = basePlacement ? getMainAxisFromPlacement(basePlacement) : null;\n\n    if (mainAxis != null) {\n      var len = mainAxis === 'y' ? 'height' : 'width';\n\n      switch (variation) {\n        case start:\n          offsets[mainAxis] = offsets[mainAxis] - (reference[len] / 2 - element[len] / 2);\n          break;\n\n        case end:\n          offsets[mainAxis] = offsets[mainAxis] + (reference[len] / 2 - element[len] / 2);\n          break;\n      }\n    }\n\n    return offsets;\n  }\n\n  function detectOverflow(state, options) {\n    if (options === void 0) {\n      options = {};\n    }\n\n    var _options = options,\n        _options$placement = _options.placement,\n        placement = _options$placement === void 0 ? state.placement : _options$placement,\n        _options$boundary = _options.boundary,\n        boundary = _options$boundary === void 0 ? clippingParents : _options$boundary,\n        _options$rootBoundary = _options.rootBoundary,\n        rootBoundary = _options$rootBoundary === void 0 ? viewport : _options$rootBoundary,\n        _options$elementConte = _options.elementContext,\n        elementContext = _options$elementConte === void 0 ? popper : _options$elementConte,\n        _options$altBoundary = _options.altBoundary,\n        altBoundary = _options$altBoundary === void 0 ? false : _options$altBoundary,\n        _options$padding = _options.padding,\n        padding = _options$padding === void 0 ? 0 : _options$padding;\n    var paddingObject = mergePaddingObject(typeof padding !== 'number' ? padding : expandToHashMap(padding, basePlacements));\n    var altContext = elementContext === popper ? reference : popper;\n    var referenceElement = state.elements.reference;\n    var popperRect = state.rects.popper;\n    var element = state.elements[altBoundary ? altContext : elementContext];\n    var clippingClientRect = getClippingRect(isElement(element) ? element : element.contextElement || getDocumentElement(state.elements.popper), boundary, rootBoundary);\n    var referenceClientRect = getBoundingClientRect(referenceElement);\n    var popperOffsets = computeOffsets({\n      reference: referenceClientRect,\n      element: popperRect,\n      strategy: 'absolute',\n      placement: placement\n    });\n    var popperClientRect = rectToClientRect(Object.assign({}, popperRect, popperOffsets));\n    var elementClientRect = elementContext === popper ? popperClientRect : referenceClientRect; // positive = overflowing the clipping rect\n    // 0 or negative = within the clipping rect\n\n    var overflowOffsets = {\n      top: clippingClientRect.top - elementClientRect.top + paddingObject.top,\n      bottom: elementClientRect.bottom - clippingClientRect.bottom + paddingObject.bottom,\n      left: clippingClientRect.left - elementClientRect.left + paddingObject.left,\n      right: elementClientRect.right - clippingClientRect.right + paddingObject.right\n    };\n    var offsetData = state.modifiersData.offset; // Offsets can be applied only to the popper element\n\n    if (elementContext === popper && offsetData) {\n      var offset = offsetData[placement];\n      Object.keys(overflowOffsets).forEach(function (key) {\n        var multiply = [right, bottom].indexOf(key) >= 0 ? 1 : -1;\n        var axis = [top, bottom].indexOf(key) >= 0 ? 'y' : 'x';\n        overflowOffsets[key] += offset[axis] * multiply;\n      });\n    }\n\n    return overflowOffsets;\n  }\n\n  function computeAutoPlacement(state, options) {\n    if (options === void 0) {\n      options = {};\n    }\n\n    var _options = options,\n        placement = _options.placement,\n        boundary = _options.boundary,\n        rootBoundary = _options.rootBoundary,\n        padding = _options.padding,\n        flipVariations = _options.flipVariations,\n        _options$allowedAutoP = _options.allowedAutoPlacements,\n        allowedAutoPlacements = _options$allowedAutoP === void 0 ? placements : _options$allowedAutoP;\n    var variation = getVariation(placement);\n    var placements$1 = variation ? flipVariations ? variationPlacements : variationPlacements.filter(function (placement) {\n      return getVariation(placement) === variation;\n    }) : basePlacements;\n    var allowedPlacements = placements$1.filter(function (placement) {\n      return allowedAutoPlacements.indexOf(placement) >= 0;\n    });\n\n    if (allowedPlacements.length === 0) {\n      allowedPlacements = placements$1;\n    } // $FlowFixMe[incompatible-type]: Flow seems to have problems with two array unions...\n\n\n    var overflows = allowedPlacements.reduce(function (acc, placement) {\n      acc[placement] = detectOverflow(state, {\n        placement: placement,\n        boundary: boundary,\n        rootBoundary: rootBoundary,\n        padding: padding\n      })[getBasePlacement(placement)];\n      return acc;\n    }, {});\n    return Object.keys(overflows).sort(function (a, b) {\n      return overflows[a] - overflows[b];\n    });\n  }\n\n  function getExpandedFallbackPlacements(placement) {\n    if (getBasePlacement(placement) === auto) {\n      return [];\n    }\n\n    var oppositePlacement = getOppositePlacement(placement);\n    return [getOppositeVariationPlacement(placement), oppositePlacement, getOppositeVariationPlacement(oppositePlacement)];\n  }\n\n  function flip(_ref) {\n    var state = _ref.state,\n        options = _ref.options,\n        name = _ref.name;\n\n    if (state.modifiersData[name]._skip) {\n      return;\n    }\n\n    var _options$mainAxis = options.mainAxis,\n        checkMainAxis = _options$mainAxis === void 0 ? true : _options$mainAxis,\n        _options$altAxis = options.altAxis,\n        checkAltAxis = _options$altAxis === void 0 ? true : _options$altAxis,\n        specifiedFallbackPlacements = options.fallbackPlacements,\n        padding = options.padding,\n        boundary = options.boundary,\n        rootBoundary = options.rootBoundary,\n        altBoundary = options.altBoundary,\n        _options$flipVariatio = options.flipVariations,\n        flipVariations = _options$flipVariatio === void 0 ? true : _options$flipVariatio,\n        allowedAutoPlacements = options.allowedAutoPlacements;\n    var preferredPlacement = state.options.placement;\n    var basePlacement = getBasePlacement(preferredPlacement);\n    var isBasePlacement = basePlacement === preferredPlacement;\n    var fallbackPlacements = specifiedFallbackPlacements || (isBasePlacement || !flipVariations ? [getOppositePlacement(preferredPlacement)] : getExpandedFallbackPlacements(preferredPlacement));\n    var placements = [preferredPlacement].concat(fallbackPlacements).reduce(function (acc, placement) {\n      return acc.concat(getBasePlacement(placement) === auto ? computeAutoPlacement(state, {\n        placement: placement,\n        boundary: boundary,\n        rootBoundary: rootBoundary,\n        padding: padding,\n        flipVariations: flipVariations,\n        allowedAutoPlacements: allowedAutoPlacements\n      }) : placement);\n    }, []);\n    var referenceRect = state.rects.reference;\n    var popperRect = state.rects.popper;\n    var checksMap = new Map();\n    var makeFallbackChecks = true;\n    var firstFittingPlacement = placements[0];\n\n    for (var i = 0; i < placements.length; i++) {\n      var placement = placements[i];\n\n      var _basePlacement = getBasePlacement(placement);\n\n      var isStartVariation = getVariation(placement) === start;\n      var isVertical = [top, bottom].indexOf(_basePlacement) >= 0;\n      var len = isVertical ? 'width' : 'height';\n      var overflow = detectOverflow(state, {\n        placement: placement,\n        boundary: boundary,\n        rootBoundary: rootBoundary,\n        altBoundary: altBoundary,\n        padding: padding\n      });\n      var mainVariationSide = isVertical ? isStartVariation ? right : left : isStartVariation ? bottom : top;\n\n      if (referenceRect[len] > popperRect[len]) {\n        mainVariationSide = getOppositePlacement(mainVariationSide);\n      }\n\n      var altVariationSide = getOppositePlacement(mainVariationSide);\n      var checks = [];\n\n      if (checkMainAxis) {\n        checks.push(overflow[_basePlacement] <= 0);\n      }\n\n      if (checkAltAxis) {\n        checks.push(overflow[mainVariationSide] <= 0, overflow[altVariationSide] <= 0);\n      }\n\n      if (checks.every(function (check) {\n        return check;\n      })) {\n        firstFittingPlacement = placement;\n        makeFallbackChecks = false;\n        break;\n      }\n\n      checksMap.set(placement, checks);\n    }\n\n    if (makeFallbackChecks) {\n      // `2` may be desired in some cases – research later\n      var numberOfChecks = flipVariations ? 3 : 1;\n\n      var _loop = function _loop(_i) {\n        var fittingPlacement = placements.find(function (placement) {\n          var checks = checksMap.get(placement);\n\n          if (checks) {\n            return checks.slice(0, _i).every(function (check) {\n              return check;\n            });\n          }\n        });\n\n        if (fittingPlacement) {\n          firstFittingPlacement = fittingPlacement;\n          return \"break\";\n        }\n      };\n\n      for (var _i = numberOfChecks; _i > 0; _i--) {\n        var _ret = _loop(_i);\n\n        if (_ret === \"break\") break;\n      }\n    }\n\n    if (state.placement !== firstFittingPlacement) {\n      state.modifiersData[name]._skip = true;\n      state.placement = firstFittingPlacement;\n      state.reset = true;\n    }\n  } // eslint-disable-next-line import/no-unused-modules\n\n\n  var flip$1 = {\n    name: 'flip',\n    enabled: true,\n    phase: 'main',\n    fn: flip,\n    requiresIfExists: ['offset'],\n    data: {\n      _skip: false\n    }\n  };\n\n  function getSideOffsets(overflow, rect, preventedOffsets) {\n    if (preventedOffsets === void 0) {\n      preventedOffsets = {\n        x: 0,\n        y: 0\n      };\n    }\n\n    return {\n      top: overflow.top - rect.height - preventedOffsets.y,\n      right: overflow.right - rect.width + preventedOffsets.x,\n      bottom: overflow.bottom - rect.height + preventedOffsets.y,\n      left: overflow.left - rect.width - preventedOffsets.x\n    };\n  }\n\n  function isAnySideFullyClipped(overflow) {\n    return [top, right, bottom, left].some(function (side) {\n      return overflow[side] >= 0;\n    });\n  }\n\n  function hide(_ref) {\n    var state = _ref.state,\n        name = _ref.name;\n    var referenceRect = state.rects.reference;\n    var popperRect = state.rects.popper;\n    var preventedOffsets = state.modifiersData.preventOverflow;\n    var referenceOverflow = detectOverflow(state, {\n      elementContext: 'reference'\n    });\n    var popperAltOverflow = detectOverflow(state, {\n      altBoundary: true\n    });\n    var referenceClippingOffsets = getSideOffsets(referenceOverflow, referenceRect);\n    var popperEscapeOffsets = getSideOffsets(popperAltOverflow, popperRect, preventedOffsets);\n    var isReferenceHidden = isAnySideFullyClipped(referenceClippingOffsets);\n    var hasPopperEscaped = isAnySideFullyClipped(popperEscapeOffsets);\n    state.modifiersData[name] = {\n      referenceClippingOffsets: referenceClippingOffsets,\n      popperEscapeOffsets: popperEscapeOffsets,\n      isReferenceHidden: isReferenceHidden,\n      hasPopperEscaped: hasPopperEscaped\n    };\n    state.attributes.popper = Object.assign({}, state.attributes.popper, {\n      'data-popper-reference-hidden': isReferenceHidden,\n      'data-popper-escaped': hasPopperEscaped\n    });\n  } // eslint-disable-next-line import/no-unused-modules\n\n\n  var hide$1 = {\n    name: 'hide',\n    enabled: true,\n    phase: 'main',\n    requiresIfExists: ['preventOverflow'],\n    fn: hide\n  };\n\n  function distanceAndSkiddingToXY(placement, rects, offset) {\n    var basePlacement = getBasePlacement(placement);\n    var invertDistance = [left, top].indexOf(basePlacement) >= 0 ? -1 : 1;\n\n    var _ref = typeof offset === 'function' ? offset(Object.assign({}, rects, {\n      placement: placement\n    })) : offset,\n        skidding = _ref[0],\n        distance = _ref[1];\n\n    skidding = skidding || 0;\n    distance = (distance || 0) * invertDistance;\n    return [left, right].indexOf(basePlacement) >= 0 ? {\n      x: distance,\n      y: skidding\n    } : {\n      x: skidding,\n      y: distance\n    };\n  }\n\n  function offset(_ref2) {\n    var state = _ref2.state,\n        options = _ref2.options,\n        name = _ref2.name;\n    var _options$offset = options.offset,\n        offset = _options$offset === void 0 ? [0, 0] : _options$offset;\n    var data = placements.reduce(function (acc, placement) {\n      acc[placement] = distanceAndSkiddingToXY(placement, state.rects, offset);\n      return acc;\n    }, {});\n    var _data$state$placement = data[state.placement],\n        x = _data$state$placement.x,\n        y = _data$state$placement.y;\n\n    if (state.modifiersData.popperOffsets != null) {\n      state.modifiersData.popperOffsets.x += x;\n      state.modifiersData.popperOffsets.y += y;\n    }\n\n    state.modifiersData[name] = data;\n  } // eslint-disable-next-line import/no-unused-modules\n\n\n  var offset$1 = {\n    name: 'offset',\n    enabled: true,\n    phase: 'main',\n    requires: ['popperOffsets'],\n    fn: offset\n  };\n\n  function popperOffsets(_ref) {\n    var state = _ref.state,\n        name = _ref.name;\n    // Offsets are the actual position the popper needs to have to be\n    // properly positioned near its reference element\n    // This is the most basic placement, and will be adjusted by\n    // the modifiers in the next step\n    state.modifiersData[name] = computeOffsets({\n      reference: state.rects.reference,\n      element: state.rects.popper,\n      strategy: 'absolute',\n      placement: state.placement\n    });\n  } // eslint-disable-next-line import/no-unused-modules\n\n\n  var popperOffsets$1 = {\n    name: 'popperOffsets',\n    enabled: true,\n    phase: 'read',\n    fn: popperOffsets,\n    data: {}\n  };\n\n  function getAltAxis(axis) {\n    return axis === 'x' ? 'y' : 'x';\n  }\n\n  function preventOverflow(_ref) {\n    var state = _ref.state,\n        options = _ref.options,\n        name = _ref.name;\n    var _options$mainAxis = options.mainAxis,\n        checkMainAxis = _options$mainAxis === void 0 ? true : _options$mainAxis,\n        _options$altAxis = options.altAxis,\n        checkAltAxis = _options$altAxis === void 0 ? false : _options$altAxis,\n        boundary = options.boundary,\n        rootBoundary = options.rootBoundary,\n        altBoundary = options.altBoundary,\n        padding = options.padding,\n        _options$tether = options.tether,\n        tether = _options$tether === void 0 ? true : _options$tether,\n        _options$tetherOffset = options.tetherOffset,\n        tetherOffset = _options$tetherOffset === void 0 ? 0 : _options$tetherOffset;\n    var overflow = detectOverflow(state, {\n      boundary: boundary,\n      rootBoundary: rootBoundary,\n      padding: padding,\n      altBoundary: altBoundary\n    });\n    var basePlacement = getBasePlacement(state.placement);\n    var variation = getVariation(state.placement);\n    var isBasePlacement = !variation;\n    var mainAxis = getMainAxisFromPlacement(basePlacement);\n    var altAxis = getAltAxis(mainAxis);\n    var popperOffsets = state.modifiersData.popperOffsets;\n    var referenceRect = state.rects.reference;\n    var popperRect = state.rects.popper;\n    var tetherOffsetValue = typeof tetherOffset === 'function' ? tetherOffset(Object.assign({}, state.rects, {\n      placement: state.placement\n    })) : tetherOffset;\n    var data = {\n      x: 0,\n      y: 0\n    };\n\n    if (!popperOffsets) {\n      return;\n    }\n\n    if (checkMainAxis || checkAltAxis) {\n      var mainSide = mainAxis === 'y' ? top : left;\n      var altSide = mainAxis === 'y' ? bottom : right;\n      var len = mainAxis === 'y' ? 'height' : 'width';\n      var offset = popperOffsets[mainAxis];\n      var min$1 = popperOffsets[mainAxis] + overflow[mainSide];\n      var max$1 = popperOffsets[mainAxis] - overflow[altSide];\n      var additive = tether ? -popperRect[len] / 2 : 0;\n      var minLen = variation === start ? referenceRect[len] : popperRect[len];\n      var maxLen = variation === start ? -popperRect[len] : -referenceRect[len]; // We need to include the arrow in the calculation so the arrow doesn't go\n      // outside the reference bounds\n\n      var arrowElement = state.elements.arrow;\n      var arrowRect = tether && arrowElement ? getLayoutRect(arrowElement) : {\n        width: 0,\n        height: 0\n      };\n      var arrowPaddingObject = state.modifiersData['arrow#persistent'] ? state.modifiersData['arrow#persistent'].padding : getFreshSideObject();\n      var arrowPaddingMin = arrowPaddingObject[mainSide];\n      var arrowPaddingMax = arrowPaddingObject[altSide]; // If the reference length is smaller than the arrow length, we don't want\n      // to include its full size in the calculation. If the reference is small\n      // and near the edge of a boundary, the popper can overflow even if the\n      // reference is not overflowing as well (e.g. virtual elements with no\n      // width or height)\n\n      var arrowLen = within(0, referenceRect[len], arrowRect[len]);\n      var minOffset = isBasePlacement ? referenceRect[len] / 2 - additive - arrowLen - arrowPaddingMin - tetherOffsetValue : minLen - arrowLen - arrowPaddingMin - tetherOffsetValue;\n      var maxOffset = isBasePlacement ? -referenceRect[len] / 2 + additive + arrowLen + arrowPaddingMax + tetherOffsetValue : maxLen + arrowLen + arrowPaddingMax + tetherOffsetValue;\n      var arrowOffsetParent = state.elements.arrow && getOffsetParent(state.elements.arrow);\n      var clientOffset = arrowOffsetParent ? mainAxis === 'y' ? arrowOffsetParent.clientTop || 0 : arrowOffsetParent.clientLeft || 0 : 0;\n      var offsetModifierValue = state.modifiersData.offset ? state.modifiersData.offset[state.placement][mainAxis] : 0;\n      var tetherMin = popperOffsets[mainAxis] + minOffset - offsetModifierValue - clientOffset;\n      var tetherMax = popperOffsets[mainAxis] + maxOffset - offsetModifierValue;\n\n      if (checkMainAxis) {\n        var preventedOffset = within(tether ? min(min$1, tetherMin) : min$1, offset, tether ? max(max$1, tetherMax) : max$1);\n        popperOffsets[mainAxis] = preventedOffset;\n        data[mainAxis] = preventedOffset - offset;\n      }\n\n      if (checkAltAxis) {\n        var _mainSide = mainAxis === 'x' ? top : left;\n\n        var _altSide = mainAxis === 'x' ? bottom : right;\n\n        var _offset = popperOffsets[altAxis];\n\n        var _min = _offset + overflow[_mainSide];\n\n        var _max = _offset - overflow[_altSide];\n\n        var _preventedOffset = within(tether ? min(_min, tetherMin) : _min, _offset, tether ? max(_max, tetherMax) : _max);\n\n        popperOffsets[altAxis] = _preventedOffset;\n        data[altAxis] = _preventedOffset - _offset;\n      }\n    }\n\n    state.modifiersData[name] = data;\n  } // eslint-disable-next-line import/no-unused-modules\n\n\n  var preventOverflow$1 = {\n    name: 'preventOverflow',\n    enabled: true,\n    phase: 'main',\n    fn: preventOverflow,\n    requiresIfExists: ['offset']\n  };\n\n  function getHTMLElementScroll(element) {\n    return {\n      scrollLeft: element.scrollLeft,\n      scrollTop: element.scrollTop\n    };\n  }\n\n  function getNodeScroll(node) {\n    if (node === getWindow(node) || !isHTMLElement(node)) {\n      return getWindowScroll(node);\n    } else {\n      return getHTMLElementScroll(node);\n    }\n  }\n\n  function isElementScaled(element) {\n    var rect = element.getBoundingClientRect();\n    var scaleX = rect.width / element.offsetWidth || 1;\n    var scaleY = rect.height / element.offsetHeight || 1;\n    return scaleX !== 1 || scaleY !== 1;\n  } // Returns the composite rect of an element relative to its offsetParent.\n  // Composite means it takes into account transforms as well as layout.\n\n\n  function getCompositeRect(elementOrVirtualElement, offsetParent, isFixed) {\n    if (isFixed === void 0) {\n      isFixed = false;\n    }\n\n    var isOffsetParentAnElement = isHTMLElement(offsetParent);\n    var offsetParentIsScaled = isHTMLElement(offsetParent) && isElementScaled(offsetParent);\n    var documentElement = getDocumentElement(offsetParent);\n    var rect = getBoundingClientRect(elementOrVirtualElement, offsetParentIsScaled);\n    var scroll = {\n      scrollLeft: 0,\n      scrollTop: 0\n    };\n    var offsets = {\n      x: 0,\n      y: 0\n    };\n\n    if (isOffsetParentAnElement || !isOffsetParentAnElement && !isFixed) {\n      if (getNodeName(offsetParent) !== 'body' || // https://github.com/popperjs/popper-core/issues/1078\n      isScrollParent(documentElement)) {\n        scroll = getNodeScroll(offsetParent);\n      }\n\n      if (isHTMLElement(offsetParent)) {\n        offsets = getBoundingClientRect(offsetParent, true);\n        offsets.x += offsetParent.clientLeft;\n        offsets.y += offsetParent.clientTop;\n      } else if (documentElement) {\n        offsets.x = getWindowScrollBarX(documentElement);\n      }\n    }\n\n    return {\n      x: rect.left + scroll.scrollLeft - offsets.x,\n      y: rect.top + scroll.scrollTop - offsets.y,\n      width: rect.width,\n      height: rect.height\n    };\n  }\n\n  function order(modifiers) {\n    var map = new Map();\n    var visited = new Set();\n    var result = [];\n    modifiers.forEach(function (modifier) {\n      map.set(modifier.name, modifier);\n    }); // On visiting object, check for its dependencies and visit them recursively\n\n    function sort(modifier) {\n      visited.add(modifier.name);\n      var requires = [].concat(modifier.requires || [], modifier.requiresIfExists || []);\n      requires.forEach(function (dep) {\n        if (!visited.has(dep)) {\n          var depModifier = map.get(dep);\n\n          if (depModifier) {\n            sort(depModifier);\n          }\n        }\n      });\n      result.push(modifier);\n    }\n\n    modifiers.forEach(function (modifier) {\n      if (!visited.has(modifier.name)) {\n        // check for visited object\n        sort(modifier);\n      }\n    });\n    return result;\n  }\n\n  function orderModifiers(modifiers) {\n    // order based on dependencies\n    var orderedModifiers = order(modifiers); // order based on phase\n\n    return modifierPhases.reduce(function (acc, phase) {\n      return acc.concat(orderedModifiers.filter(function (modifier) {\n        return modifier.phase === phase;\n      }));\n    }, []);\n  }\n\n  function debounce(fn) {\n    var pending;\n    return function () {\n      if (!pending) {\n        pending = new Promise(function (resolve) {\n          Promise.resolve().then(function () {\n            pending = undefined;\n            resolve(fn());\n          });\n        });\n      }\n\n      return pending;\n    };\n  }\n\n  function mergeByName(modifiers) {\n    var merged = modifiers.reduce(function (merged, current) {\n      var existing = merged[current.name];\n      merged[current.name] = existing ? Object.assign({}, existing, current, {\n        options: Object.assign({}, existing.options, current.options),\n        data: Object.assign({}, existing.data, current.data)\n      }) : current;\n      return merged;\n    }, {}); // IE11 does not support Object.values\n\n    return Object.keys(merged).map(function (key) {\n      return merged[key];\n    });\n  }\n\n  var DEFAULT_OPTIONS = {\n    placement: 'bottom',\n    modifiers: [],\n    strategy: 'absolute'\n  };\n\n  function areValidElements() {\n    for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {\n      args[_key] = arguments[_key];\n    }\n\n    return !args.some(function (element) {\n      return !(element && typeof element.getBoundingClientRect === 'function');\n    });\n  }\n\n  function popperGenerator(generatorOptions) {\n    if (generatorOptions === void 0) {\n      generatorOptions = {};\n    }\n\n    var _generatorOptions = generatorOptions,\n        _generatorOptions$def = _generatorOptions.defaultModifiers,\n        defaultModifiers = _generatorOptions$def === void 0 ? [] : _generatorOptions$def,\n        _generatorOptions$def2 = _generatorOptions.defaultOptions,\n        defaultOptions = _generatorOptions$def2 === void 0 ? DEFAULT_OPTIONS : _generatorOptions$def2;\n    return function createPopper(reference, popper, options) {\n      if (options === void 0) {\n        options = defaultOptions;\n      }\n\n      var state = {\n        placement: 'bottom',\n        orderedModifiers: [],\n        options: Object.assign({}, DEFAULT_OPTIONS, defaultOptions),\n        modifiersData: {},\n        elements: {\n          reference: reference,\n          popper: popper\n        },\n        attributes: {},\n        styles: {}\n      };\n      var effectCleanupFns = [];\n      var isDestroyed = false;\n      var instance = {\n        state: state,\n        setOptions: function setOptions(options) {\n          cleanupModifierEffects();\n          state.options = Object.assign({}, defaultOptions, state.options, options);\n          state.scrollParents = {\n            reference: isElement(reference) ? listScrollParents(reference) : reference.contextElement ? listScrollParents(reference.contextElement) : [],\n            popper: listScrollParents(popper)\n          }; // Orders the modifiers based on their dependencies and `phase`\n          // properties\n\n          var orderedModifiers = orderModifiers(mergeByName([].concat(defaultModifiers, state.options.modifiers))); // Strip out disabled modifiers\n\n          state.orderedModifiers = orderedModifiers.filter(function (m) {\n            return m.enabled;\n          }); // Validate the provided modifiers so that the consumer will get warned\n\n          runModifierEffects();\n          return instance.update();\n        },\n        // Sync update – it will always be executed, even if not necessary. This\n        // is useful for low frequency updates where sync behavior simplifies the\n        // logic.\n        // For high frequency updates (e.g. `resize` and `scroll` events), always\n        // prefer the async Popper#update method\n        forceUpdate: function forceUpdate() {\n          if (isDestroyed) {\n            return;\n          }\n\n          var _state$elements = state.elements,\n              reference = _state$elements.reference,\n              popper = _state$elements.popper; // Don't proceed if `reference` or `popper` are not valid elements\n          // anymore\n\n          if (!areValidElements(reference, popper)) {\n\n            return;\n          } // Store the reference and popper rects to be read by modifiers\n\n\n          state.rects = {\n            reference: getCompositeRect(reference, getOffsetParent(popper), state.options.strategy === 'fixed'),\n            popper: getLayoutRect(popper)\n          }; // Modifiers have the ability to reset the current update cycle. The\n          // most common use case for this is the `flip` modifier changing the\n          // placement, which then needs to re-run all the modifiers, because the\n          // logic was previously ran for the previous placement and is therefore\n          // stale/incorrect\n\n          state.reset = false;\n          state.placement = state.options.placement; // On each update cycle, the `modifiersData` property for each modifier\n          // is filled with the initial data specified by the modifier. This means\n          // it doesn't persist and is fresh on each update.\n          // To ensure persistent data, use `${name}#persistent`\n\n          state.orderedModifiers.forEach(function (modifier) {\n            return state.modifiersData[modifier.name] = Object.assign({}, modifier.data);\n          });\n\n          for (var index = 0; index < state.orderedModifiers.length; index++) {\n\n            if (state.reset === true) {\n              state.reset = false;\n              index = -1;\n              continue;\n            }\n\n            var _state$orderedModifie = state.orderedModifiers[index],\n                fn = _state$orderedModifie.fn,\n                _state$orderedModifie2 = _state$orderedModifie.options,\n                _options = _state$orderedModifie2 === void 0 ? {} : _state$orderedModifie2,\n                name = _state$orderedModifie.name;\n\n            if (typeof fn === 'function') {\n              state = fn({\n                state: state,\n                options: _options,\n                name: name,\n                instance: instance\n              }) || state;\n            }\n          }\n        },\n        // Async and optimistically optimized update – it will not be executed if\n        // not necessary (debounced to run at most once-per-tick)\n        update: debounce(function () {\n          return new Promise(function (resolve) {\n            instance.forceUpdate();\n            resolve(state);\n          });\n        }),\n        destroy: function destroy() {\n          cleanupModifierEffects();\n          isDestroyed = true;\n        }\n      };\n\n      if (!areValidElements(reference, popper)) {\n\n        return instance;\n      }\n\n      instance.setOptions(options).then(function (state) {\n        if (!isDestroyed && options.onFirstUpdate) {\n          options.onFirstUpdate(state);\n        }\n      }); // Modifiers have the ability to execute arbitrary code before the first\n      // update cycle runs. They will be executed in the same order as the update\n      // cycle. This is useful when a modifier adds some persistent data that\n      // other modifiers need to use, but the modifier is run after the dependent\n      // one.\n\n      function runModifierEffects() {\n        state.orderedModifiers.forEach(function (_ref3) {\n          var name = _ref3.name,\n              _ref3$options = _ref3.options,\n              options = _ref3$options === void 0 ? {} : _ref3$options,\n              effect = _ref3.effect;\n\n          if (typeof effect === 'function') {\n            var cleanupFn = effect({\n              state: state,\n              name: name,\n              instance: instance,\n              options: options\n            });\n\n            var noopFn = function noopFn() {};\n\n            effectCleanupFns.push(cleanupFn || noopFn);\n          }\n        });\n      }\n\n      function cleanupModifierEffects() {\n        effectCleanupFns.forEach(function (fn) {\n          return fn();\n        });\n        effectCleanupFns = [];\n      }\n\n      return instance;\n    };\n  }\n  var createPopper$2 = /*#__PURE__*/popperGenerator(); // eslint-disable-next-line import/no-unused-modules\n\n  var defaultModifiers$1 = [eventListeners, popperOffsets$1, computeStyles$1, applyStyles$1];\n  var createPopper$1 = /*#__PURE__*/popperGenerator({\n    defaultModifiers: defaultModifiers$1\n  }); // eslint-disable-next-line import/no-unused-modules\n\n  var defaultModifiers = [eventListeners, popperOffsets$1, computeStyles$1, applyStyles$1, offset$1, flip$1, preventOverflow$1, arrow$1, hide$1];\n  var createPopper = /*#__PURE__*/popperGenerator({\n    defaultModifiers: defaultModifiers\n  }); // eslint-disable-next-line import/no-unused-modules\n\n  var Popper = /*#__PURE__*/Object.freeze({\n    __proto__: null,\n    popperGenerator: popperGenerator,\n    detectOverflow: detectOverflow,\n    createPopperBase: createPopper$2,\n    createPopper: createPopper,\n    createPopperLite: createPopper$1,\n    top: top,\n    bottom: bottom,\n    right: right,\n    left: left,\n    auto: auto,\n    basePlacements: basePlacements,\n    start: start,\n    end: end,\n    clippingParents: clippingParents,\n    viewport: viewport,\n    popper: popper,\n    reference: reference,\n    variationPlacements: variationPlacements,\n    placements: placements,\n    beforeRead: beforeRead,\n    read: read,\n    afterRead: afterRead,\n    beforeMain: beforeMain,\n    main: main,\n    afterMain: afterMain,\n    beforeWrite: beforeWrite,\n    write: write,\n    afterWrite: afterWrite,\n    modifierPhases: modifierPhases,\n    applyStyles: applyStyles$1,\n    arrow: arrow$1,\n    computeStyles: computeStyles$1,\n    eventListeners: eventListeners,\n    flip: flip$1,\n    hide: hide$1,\n    offset: offset$1,\n    popperOffsets: popperOffsets$1,\n    preventOverflow: preventOverflow$1\n  });\n\n  /**\n   * --------------------------------------------------------------------------\n   * Bootstrap (v5.1.0): dropdown.js\n   * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n   * --------------------------------------------------------------------------\n   */\n  /**\n   * ------------------------------------------------------------------------\n   * Constants\n   * ------------------------------------------------------------------------\n   */\n\n  const NAME$9 = 'dropdown';\n  const DATA_KEY$8 = 'bs.dropdown';\n  const EVENT_KEY$8 = `.${DATA_KEY$8}`;\n  const DATA_API_KEY$4 = '.data-api';\n  const ESCAPE_KEY$2 = 'Escape';\n  const SPACE_KEY = 'Space';\n  const TAB_KEY$1 = 'Tab';\n  const ARROW_UP_KEY = 'ArrowUp';\n  const ARROW_DOWN_KEY = 'ArrowDown';\n  const RIGHT_MOUSE_BUTTON = 2; // MouseEvent.button value for the secondary button, usually the right button\n\n  const REGEXP_KEYDOWN = new RegExp(`${ARROW_UP_KEY}|${ARROW_DOWN_KEY}|${ESCAPE_KEY$2}`);\n  const EVENT_HIDE$4 = `hide${EVENT_KEY$8}`;\n  const EVENT_HIDDEN$4 = `hidden${EVENT_KEY$8}`;\n  const EVENT_SHOW$4 = `show${EVENT_KEY$8}`;\n  const EVENT_SHOWN$4 = `shown${EVENT_KEY$8}`;\n  const EVENT_CLICK_DATA_API$3 = `click${EVENT_KEY$8}${DATA_API_KEY$4}`;\n  const EVENT_KEYDOWN_DATA_API = `keydown${EVENT_KEY$8}${DATA_API_KEY$4}`;\n  const EVENT_KEYUP_DATA_API = `keyup${EVENT_KEY$8}${DATA_API_KEY$4}`;\n  const CLASS_NAME_SHOW$6 = 'show';\n  const CLASS_NAME_DROPUP = 'dropup';\n  const CLASS_NAME_DROPEND = 'dropend';\n  const CLASS_NAME_DROPSTART = 'dropstart';\n  const CLASS_NAME_NAVBAR = 'navbar';\n  const SELECTOR_DATA_TOGGLE$3 = '[data-bs-toggle=\"dropdown\"]';\n  const SELECTOR_MENU = '.dropdown-menu';\n  const SELECTOR_NAVBAR_NAV = '.navbar-nav';\n  const SELECTOR_VISIBLE_ITEMS = '.dropdown-menu .dropdown-item:not(.disabled):not(:disabled)';\n  const PLACEMENT_TOP = isRTL() ? 'top-end' : 'top-start';\n  const PLACEMENT_TOPEND = isRTL() ? 'top-start' : 'top-end';\n  const PLACEMENT_BOTTOM = isRTL() ? 'bottom-end' : 'bottom-start';\n  const PLACEMENT_BOTTOMEND = isRTL() ? 'bottom-start' : 'bottom-end';\n  const PLACEMENT_RIGHT = isRTL() ? 'left-start' : 'right-start';\n  const PLACEMENT_LEFT = isRTL() ? 'right-start' : 'left-start';\n  const Default$8 = {\n    offset: [0, 2],\n    boundary: 'clippingParents',\n    reference: 'toggle',\n    display: 'dynamic',\n    popperConfig: null,\n    autoClose: true\n  };\n  const DefaultType$8 = {\n    offset: '(array|string|function)',\n    boundary: '(string|element)',\n    reference: '(string|element|object)',\n    display: 'string',\n    popperConfig: '(null|object|function)',\n    autoClose: '(boolean|string)'\n  };\n  /**\n   * ------------------------------------------------------------------------\n   * Class Definition\n   * ------------------------------------------------------------------------\n   */\n\n  class Dropdown extends BaseComponent {\n    constructor(element, config) {\n      super(element);\n      this._popper = null;\n      this._config = this._getConfig(config);\n      this._menu = this._getMenuElement();\n      this._inNavbar = this._detectNavbar();\n    } // Getters\n\n\n    static get Default() {\n      return Default$8;\n    }\n\n    static get DefaultType() {\n      return DefaultType$8;\n    }\n\n    static get NAME() {\n      return NAME$9;\n    } // Public\n\n\n    toggle() {\n      return this._isShown() ? this.hide() : this.show();\n    }\n\n    show() {\n      if (isDisabled(this._element) || this._isShown(this._menu)) {\n        return;\n      }\n\n      const relatedTarget = {\n        relatedTarget: this._element\n      };\n      const showEvent = EventHandler.trigger(this._element, EVENT_SHOW$4, relatedTarget);\n\n      if (showEvent.defaultPrevented) {\n        return;\n      }\n\n      const parent = Dropdown.getParentFromElement(this._element); // Totally disable Popper for Dropdowns in Navbar\n\n      if (this._inNavbar) {\n        Manipulator.setDataAttribute(this._menu, 'popper', 'none');\n      } else {\n        this._createPopper(parent);\n      } // If this is a touch-enabled device we add extra\n      // empty mouseover listeners to the body's immediate children;\n      // only needed because of broken event delegation on iOS\n      // https://www.quirksmode.org/blog/archives/2014/02/mouse_event_bub.html\n\n\n      if ('ontouchstart' in document.documentElement && !parent.closest(SELECTOR_NAVBAR_NAV)) {\n        [].concat(...document.body.children).forEach(elem => EventHandler.on(elem, 'mouseover', noop));\n      }\n\n      this._element.focus();\n\n      this._element.setAttribute('aria-expanded', true);\n\n      this._menu.classList.add(CLASS_NAME_SHOW$6);\n\n      this._element.classList.add(CLASS_NAME_SHOW$6);\n\n      EventHandler.trigger(this._element, EVENT_SHOWN$4, relatedTarget);\n    }\n\n    hide() {\n      if (isDisabled(this._element) || !this._isShown(this._menu)) {\n        return;\n      }\n\n      const relatedTarget = {\n        relatedTarget: this._element\n      };\n\n      this._completeHide(relatedTarget);\n    }\n\n    dispose() {\n      if (this._popper) {\n        this._popper.destroy();\n      }\n\n      super.dispose();\n    }\n\n    update() {\n      this._inNavbar = this._detectNavbar();\n\n      if (this._popper) {\n        this._popper.update();\n      }\n    } // Private\n\n\n    _completeHide(relatedTarget) {\n      const hideEvent = EventHandler.trigger(this._element, EVENT_HIDE$4, relatedTarget);\n\n      if (hideEvent.defaultPrevented) {\n        return;\n      } // If this is a touch-enabled device we remove the extra\n      // empty mouseover listeners we added for iOS support\n\n\n      if ('ontouchstart' in document.documentElement) {\n        [].concat(...document.body.children).forEach(elem => EventHandler.off(elem, 'mouseover', noop));\n      }\n\n      if (this._popper) {\n        this._popper.destroy();\n      }\n\n      this._menu.classList.remove(CLASS_NAME_SHOW$6);\n\n      this._element.classList.remove(CLASS_NAME_SHOW$6);\n\n      this._element.setAttribute('aria-expanded', 'false');\n\n      Manipulator.removeDataAttribute(this._menu, 'popper');\n      EventHandler.trigger(this._element, EVENT_HIDDEN$4, relatedTarget);\n    }\n\n    _getConfig(config) {\n      config = { ...this.constructor.Default,\n        ...Manipulator.getDataAttributes(this._element),\n        ...config\n      };\n      typeCheckConfig(NAME$9, config, this.constructor.DefaultType);\n\n      if (typeof config.reference === 'object' && !isElement$1(config.reference) && typeof config.reference.getBoundingClientRect !== 'function') {\n        // Popper virtual elements require a getBoundingClientRect method\n        throw new TypeError(`${NAME$9.toUpperCase()}: Option \"reference\" provided type \"object\" without a required \"getBoundingClientRect\" method.`);\n      }\n\n      return config;\n    }\n\n    _createPopper(parent) {\n      if (typeof Popper === 'undefined') {\n        throw new TypeError('Bootstrap\\'s dropdowns require Popper (https://popper.js.org)');\n      }\n\n      let referenceElement = this._element;\n\n      if (this._config.reference === 'parent') {\n        referenceElement = parent;\n      } else if (isElement$1(this._config.reference)) {\n        referenceElement = getElement(this._config.reference);\n      } else if (typeof this._config.reference === 'object') {\n        referenceElement = this._config.reference;\n      }\n\n      const popperConfig = this._getPopperConfig();\n\n      const isDisplayStatic = popperConfig.modifiers.find(modifier => modifier.name === 'applyStyles' && modifier.enabled === false);\n      this._popper = createPopper(referenceElement, this._menu, popperConfig);\n\n      if (isDisplayStatic) {\n        Manipulator.setDataAttribute(this._menu, 'popper', 'static');\n      }\n    }\n\n    _isShown(element = this._element) {\n      return element.classList.contains(CLASS_NAME_SHOW$6);\n    }\n\n    _getMenuElement() {\n      return SelectorEngine.next(this._element, SELECTOR_MENU)[0];\n    }\n\n    _getPlacement() {\n      const parentDropdown = this._element.parentNode;\n\n      if (parentDropdown.classList.contains(CLASS_NAME_DROPEND)) {\n        return PLACEMENT_RIGHT;\n      }\n\n      if (parentDropdown.classList.contains(CLASS_NAME_DROPSTART)) {\n        return PLACEMENT_LEFT;\n      } // We need to trim the value because custom properties can also include spaces\n\n\n      const isEnd = getComputedStyle(this._menu).getPropertyValue('--bs-position').trim() === 'end';\n\n      if (parentDropdown.classList.contains(CLASS_NAME_DROPUP)) {\n        return isEnd ? PLACEMENT_TOPEND : PLACEMENT_TOP;\n      }\n\n      return isEnd ? PLACEMENT_BOTTOMEND : PLACEMENT_BOTTOM;\n    }\n\n    _detectNavbar() {\n      return this._element.closest(`.${CLASS_NAME_NAVBAR}`) !== null;\n    }\n\n    _getOffset() {\n      const {\n        offset\n      } = this._config;\n\n      if (typeof offset === 'string') {\n        return offset.split(',').map(val => Number.parseInt(val, 10));\n      }\n\n      if (typeof offset === 'function') {\n        return popperData => offset(popperData, this._element);\n      }\n\n      return offset;\n    }\n\n    _getPopperConfig() {\n      const defaultBsPopperConfig = {\n        placement: this._getPlacement(),\n        modifiers: [{\n          name: 'preventOverflow',\n          options: {\n            boundary: this._config.boundary\n          }\n        }, {\n          name: 'offset',\n          options: {\n            offset: this._getOffset()\n          }\n        }]\n      }; // Disable Popper if we have a static display\n\n      if (this._config.display === 'static') {\n        defaultBsPopperConfig.modifiers = [{\n          name: 'applyStyles',\n          enabled: false\n        }];\n      }\n\n      return { ...defaultBsPopperConfig,\n        ...(typeof this._config.popperConfig === 'function' ? this._config.popperConfig(defaultBsPopperConfig) : this._config.popperConfig)\n      };\n    }\n\n    _selectMenuItem({\n      key,\n      target\n    }) {\n      const items = SelectorEngine.find(SELECTOR_VISIBLE_ITEMS, this._menu).filter(isVisible);\n\n      if (!items.length) {\n        return;\n      } // if target isn't included in items (e.g. when expanding the dropdown)\n      // allow cycling to get the last item in case key equals ARROW_UP_KEY\n\n\n      getNextActiveElement(items, target, key === ARROW_DOWN_KEY, !items.includes(target)).focus();\n    } // Static\n\n\n    static jQueryInterface(config) {\n      return this.each(function () {\n        const data = Dropdown.getOrCreateInstance(this, config);\n\n        if (typeof config !== 'string') {\n          return;\n        }\n\n        if (typeof data[config] === 'undefined') {\n          throw new TypeError(`No method named \"${config}\"`);\n        }\n\n        data[config]();\n      });\n    }\n\n    static clearMenus(event) {\n      if (event && (event.button === RIGHT_MOUSE_BUTTON || event.type === 'keyup' && event.key !== TAB_KEY$1)) {\n        return;\n      }\n\n      const toggles = SelectorEngine.find(SELECTOR_DATA_TOGGLE$3);\n\n      for (let i = 0, len = toggles.length; i < len; i++) {\n        const context = Dropdown.getInstance(toggles[i]);\n\n        if (!context || context._config.autoClose === false) {\n          continue;\n        }\n\n        if (!context._isShown()) {\n          continue;\n        }\n\n        const relatedTarget = {\n          relatedTarget: context._element\n        };\n\n        if (event) {\n          const composedPath = event.composedPath();\n          const isMenuTarget = composedPath.includes(context._menu);\n\n          if (composedPath.includes(context._element) || context._config.autoClose === 'inside' && !isMenuTarget || context._config.autoClose === 'outside' && isMenuTarget) {\n            continue;\n          } // Tab navigation through the dropdown menu or events from contained inputs shouldn't close the menu\n\n\n          if (context._menu.contains(event.target) && (event.type === 'keyup' && event.key === TAB_KEY$1 || /input|select|option|textarea|form/i.test(event.target.tagName))) {\n            continue;\n          }\n\n          if (event.type === 'click') {\n            relatedTarget.clickEvent = event;\n          }\n        }\n\n        context._completeHide(relatedTarget);\n      }\n    }\n\n    static getParentFromElement(element) {\n      return getElementFromSelector(element) || element.parentNode;\n    }\n\n    static dataApiKeydownHandler(event) {\n      // If not input/textarea:\n      //  - And not a key in REGEXP_KEYDOWN => not a dropdown command\n      // If input/textarea:\n      //  - If space key => not a dropdown command\n      //  - If key is other than escape\n      //    - If key is not up or down => not a dropdown command\n      //    - If trigger inside the menu => not a dropdown command\n      if (/input|textarea/i.test(event.target.tagName) ? event.key === SPACE_KEY || event.key !== ESCAPE_KEY$2 && (event.key !== ARROW_DOWN_KEY && event.key !== ARROW_UP_KEY || event.target.closest(SELECTOR_MENU)) : !REGEXP_KEYDOWN.test(event.key)) {\n        return;\n      }\n\n      const isActive = this.classList.contains(CLASS_NAME_SHOW$6);\n\n      if (!isActive && event.key === ESCAPE_KEY$2) {\n        return;\n      }\n\n      event.preventDefault();\n      event.stopPropagation();\n\n      if (isDisabled(this)) {\n        return;\n      }\n\n      const getToggleButton = this.matches(SELECTOR_DATA_TOGGLE$3) ? this : SelectorEngine.prev(this, SELECTOR_DATA_TOGGLE$3)[0];\n      const instance = Dropdown.getOrCreateInstance(getToggleButton);\n\n      if (event.key === ESCAPE_KEY$2) {\n        instance.hide();\n        return;\n      }\n\n      if (event.key === ARROW_UP_KEY || event.key === ARROW_DOWN_KEY) {\n        if (!isActive) {\n          instance.show();\n        }\n\n        instance._selectMenuItem(event);\n\n        return;\n      }\n\n      if (!isActive || event.key === SPACE_KEY) {\n        Dropdown.clearMenus();\n      }\n    }\n\n  }\n  /**\n   * ------------------------------------------------------------------------\n   * Data Api implementation\n   * ------------------------------------------------------------------------\n   */\n\n\n  EventHandler.on(document, EVENT_KEYDOWN_DATA_API, SELECTOR_DATA_TOGGLE$3, Dropdown.dataApiKeydownHandler);\n  EventHandler.on(document, EVENT_KEYDOWN_DATA_API, SELECTOR_MENU, Dropdown.dataApiKeydownHandler);\n  EventHandler.on(document, EVENT_CLICK_DATA_API$3, Dropdown.clearMenus);\n  EventHandler.on(document, EVENT_KEYUP_DATA_API, Dropdown.clearMenus);\n  EventHandler.on(document, EVENT_CLICK_DATA_API$3, SELECTOR_DATA_TOGGLE$3, function (event) {\n    event.preventDefault();\n    Dropdown.getOrCreateInstance(this).toggle();\n  });\n  /**\n   * ------------------------------------------------------------------------\n   * jQuery\n   * ------------------------------------------------------------------------\n   * add .Dropdown to jQuery only if jQuery is present\n   */\n\n  defineJQueryPlugin(Dropdown);\n\n  /**\n   * --------------------------------------------------------------------------\n   * Bootstrap (v5.1.0): util/scrollBar.js\n   * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n   * --------------------------------------------------------------------------\n   */\n  const SELECTOR_FIXED_CONTENT = '.fixed-top, .fixed-bottom, .is-fixed, .sticky-top';\n  const SELECTOR_STICKY_CONTENT = '.sticky-top';\n\n  class ScrollBarHelper {\n    constructor() {\n      this._element = document.body;\n    }\n\n    getWidth() {\n      // https://developer.mozilla.org/en-US/docs/Web/API/Window/innerWidth#usage_notes\n      const documentWidth = document.documentElement.clientWidth;\n      return Math.abs(window.innerWidth - documentWidth);\n    }\n\n    hide() {\n      const width = this.getWidth();\n\n      this._disableOverFlow(); // give padding to element to balance the hidden scrollbar width\n\n\n      this._setElementAttributes(this._element, 'paddingRight', calculatedValue => calculatedValue + width); // trick: We adjust positive paddingRight and negative marginRight to sticky-top elements to keep showing fullwidth\n\n\n      this._setElementAttributes(SELECTOR_FIXED_CONTENT, 'paddingRight', calculatedValue => calculatedValue + width);\n\n      this._setElementAttributes(SELECTOR_STICKY_CONTENT, 'marginRight', calculatedValue => calculatedValue - width);\n    }\n\n    _disableOverFlow() {\n      this._saveInitialAttribute(this._element, 'overflow');\n\n      this._element.style.overflow = 'hidden';\n    }\n\n    _setElementAttributes(selector, styleProp, callback) {\n      const scrollbarWidth = this.getWidth();\n\n      const manipulationCallBack = element => {\n        if (element !== this._element && window.innerWidth > element.clientWidth + scrollbarWidth) {\n          return;\n        }\n\n        this._saveInitialAttribute(element, styleProp);\n\n        const calculatedValue = window.getComputedStyle(element)[styleProp];\n        element.style[styleProp] = `${callback(Number.parseFloat(calculatedValue))}px`;\n      };\n\n      this._applyManipulationCallback(selector, manipulationCallBack);\n    }\n\n    reset() {\n      this._resetElementAttributes(this._element, 'overflow');\n\n      this._resetElementAttributes(this._element, 'paddingRight');\n\n      this._resetElementAttributes(SELECTOR_FIXED_CONTENT, 'paddingRight');\n\n      this._resetElementAttributes(SELECTOR_STICKY_CONTENT, 'marginRight');\n    }\n\n    _saveInitialAttribute(element, styleProp) {\n      const actualValue = element.style[styleProp];\n\n      if (actualValue) {\n        Manipulator.setDataAttribute(element, styleProp, actualValue);\n      }\n    }\n\n    _resetElementAttributes(selector, styleProp) {\n      const manipulationCallBack = element => {\n        const value = Manipulator.getDataAttribute(element, styleProp);\n\n        if (typeof value === 'undefined') {\n          element.style.removeProperty(styleProp);\n        } else {\n          Manipulator.removeDataAttribute(element, styleProp);\n          element.style[styleProp] = value;\n        }\n      };\n\n      this._applyManipulationCallback(selector, manipulationCallBack);\n    }\n\n    _applyManipulationCallback(selector, callBack) {\n      if (isElement$1(selector)) {\n        callBack(selector);\n      } else {\n        SelectorEngine.find(selector, this._element).forEach(callBack);\n      }\n    }\n\n    isOverflowing() {\n      return this.getWidth() > 0;\n    }\n\n  }\n\n  /**\n   * --------------------------------------------------------------------------\n   * Bootstrap (v5.1.0): util/backdrop.js\n   * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n   * --------------------------------------------------------------------------\n   */\n  const Default$7 = {\n    className: 'modal-backdrop',\n    isVisible: true,\n    // if false, we use the backdrop helper without adding any element to the dom\n    isAnimated: false,\n    rootElement: 'body',\n    // give the choice to place backdrop under different elements\n    clickCallback: null\n  };\n  const DefaultType$7 = {\n    className: 'string',\n    isVisible: 'boolean',\n    isAnimated: 'boolean',\n    rootElement: '(element|string)',\n    clickCallback: '(function|null)'\n  };\n  const NAME$8 = 'backdrop';\n  const CLASS_NAME_FADE$4 = 'fade';\n  const CLASS_NAME_SHOW$5 = 'show';\n  const EVENT_MOUSEDOWN = `mousedown.bs.${NAME$8}`;\n\n  class Backdrop {\n    constructor(config) {\n      this._config = this._getConfig(config);\n      this._isAppended = false;\n      this._element = null;\n    }\n\n    show(callback) {\n      if (!this._config.isVisible) {\n        execute(callback);\n        return;\n      }\n\n      this._append();\n\n      if (this._config.isAnimated) {\n        reflow(this._getElement());\n      }\n\n      this._getElement().classList.add(CLASS_NAME_SHOW$5);\n\n      this._emulateAnimation(() => {\n        execute(callback);\n      });\n    }\n\n    hide(callback) {\n      if (!this._config.isVisible) {\n        execute(callback);\n        return;\n      }\n\n      this._getElement().classList.remove(CLASS_NAME_SHOW$5);\n\n      this._emulateAnimation(() => {\n        this.dispose();\n        execute(callback);\n      });\n    } // Private\n\n\n    _getElement() {\n      if (!this._element) {\n        const backdrop = document.createElement('div');\n        backdrop.className = this._config.className;\n\n        if (this._config.isAnimated) {\n          backdrop.classList.add(CLASS_NAME_FADE$4);\n        }\n\n        this._element = backdrop;\n      }\n\n      return this._element;\n    }\n\n    _getConfig(config) {\n      config = { ...Default$7,\n        ...(typeof config === 'object' ? config : {})\n      }; // use getElement() with the default \"body\" to get a fresh Element on each instantiation\n\n      config.rootElement = getElement(config.rootElement);\n      typeCheckConfig(NAME$8, config, DefaultType$7);\n      return config;\n    }\n\n    _append() {\n      if (this._isAppended) {\n        return;\n      }\n\n      this._config.rootElement.append(this._getElement());\n\n      EventHandler.on(this._getElement(), EVENT_MOUSEDOWN, () => {\n        execute(this._config.clickCallback);\n      });\n      this._isAppended = true;\n    }\n\n    dispose() {\n      if (!this._isAppended) {\n        return;\n      }\n\n      EventHandler.off(this._element, EVENT_MOUSEDOWN);\n\n      this._element.remove();\n\n      this._isAppended = false;\n    }\n\n    _emulateAnimation(callback) {\n      executeAfterTransition(callback, this._getElement(), this._config.isAnimated);\n    }\n\n  }\n\n  /**\n   * --------------------------------------------------------------------------\n   * Bootstrap (v5.1.0): util/focustrap.js\n   * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n   * --------------------------------------------------------------------------\n   */\n  const Default$6 = {\n    trapElement: null,\n    // The element to trap focus inside of\n    autofocus: true\n  };\n  const DefaultType$6 = {\n    trapElement: 'element',\n    autofocus: 'boolean'\n  };\n  const NAME$7 = 'focustrap';\n  const DATA_KEY$7 = 'bs.focustrap';\n  const EVENT_KEY$7 = `.${DATA_KEY$7}`;\n  const EVENT_FOCUSIN$1 = `focusin${EVENT_KEY$7}`;\n  const EVENT_KEYDOWN_TAB = `keydown.tab${EVENT_KEY$7}`;\n  const TAB_KEY = 'Tab';\n  const TAB_NAV_FORWARD = 'forward';\n  const TAB_NAV_BACKWARD = 'backward';\n\n  class FocusTrap {\n    constructor(config) {\n      this._config = this._getConfig(config);\n      this._isActive = false;\n      this._lastTabNavDirection = null;\n    }\n\n    activate() {\n      const {\n        trapElement,\n        autofocus\n      } = this._config;\n\n      if (this._isActive) {\n        return;\n      }\n\n      if (autofocus) {\n        trapElement.focus();\n      }\n\n      EventHandler.off(document, EVENT_KEY$7); // guard against infinite focus loop\n\n      EventHandler.on(document, EVENT_FOCUSIN$1, event => this._handleFocusin(event));\n      EventHandler.on(document, EVENT_KEYDOWN_TAB, event => this._handleKeydown(event));\n      this._isActive = true;\n    }\n\n    deactivate() {\n      if (!this._isActive) {\n        return;\n      }\n\n      this._isActive = false;\n      EventHandler.off(document, EVENT_KEY$7);\n    } // Private\n\n\n    _handleFocusin(event) {\n      const {\n        target\n      } = event;\n      const {\n        trapElement\n      } = this._config;\n\n      if (target === document || target === trapElement || trapElement.contains(target)) {\n        return;\n      }\n\n      const elements = SelectorEngine.focusableChildren(trapElement);\n\n      if (elements.length === 0) {\n        trapElement.focus();\n      } else if (this._lastTabNavDirection === TAB_NAV_BACKWARD) {\n        elements[elements.length - 1].focus();\n      } else {\n        elements[0].focus();\n      }\n    }\n\n    _handleKeydown(event) {\n      if (event.key !== TAB_KEY) {\n        return;\n      }\n\n      this._lastTabNavDirection = event.shiftKey ? TAB_NAV_BACKWARD : TAB_NAV_FORWARD;\n    }\n\n    _getConfig(config) {\n      config = { ...Default$6,\n        ...(typeof config === 'object' ? config : {})\n      };\n      typeCheckConfig(NAME$7, config, DefaultType$6);\n      return config;\n    }\n\n  }\n\n  /**\n   * --------------------------------------------------------------------------\n   * Bootstrap (v5.1.0): modal.js\n   * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n   * --------------------------------------------------------------------------\n   */\n  /**\n   * ------------------------------------------------------------------------\n   * Constants\n   * ------------------------------------------------------------------------\n   */\n\n  const NAME$6 = 'modal';\n  const DATA_KEY$6 = 'bs.modal';\n  const EVENT_KEY$6 = `.${DATA_KEY$6}`;\n  const DATA_API_KEY$3 = '.data-api';\n  const ESCAPE_KEY$1 = 'Escape';\n  const Default$5 = {\n    backdrop: true,\n    keyboard: true,\n    focus: true\n  };\n  const DefaultType$5 = {\n    backdrop: '(boolean|string)',\n    keyboard: 'boolean',\n    focus: 'boolean'\n  };\n  const EVENT_HIDE$3 = `hide${EVENT_KEY$6}`;\n  const EVENT_HIDE_PREVENTED = `hidePrevented${EVENT_KEY$6}`;\n  const EVENT_HIDDEN$3 = `hidden${EVENT_KEY$6}`;\n  const EVENT_SHOW$3 = `show${EVENT_KEY$6}`;\n  const EVENT_SHOWN$3 = `shown${EVENT_KEY$6}`;\n  const EVENT_RESIZE = `resize${EVENT_KEY$6}`;\n  const EVENT_CLICK_DISMISS = `click.dismiss${EVENT_KEY$6}`;\n  const EVENT_KEYDOWN_DISMISS$1 = `keydown.dismiss${EVENT_KEY$6}`;\n  const EVENT_MOUSEUP_DISMISS = `mouseup.dismiss${EVENT_KEY$6}`;\n  const EVENT_MOUSEDOWN_DISMISS = `mousedown.dismiss${EVENT_KEY$6}`;\n  const EVENT_CLICK_DATA_API$2 = `click${EVENT_KEY$6}${DATA_API_KEY$3}`;\n  const CLASS_NAME_OPEN = 'modal-open';\n  const CLASS_NAME_FADE$3 = 'fade';\n  const CLASS_NAME_SHOW$4 = 'show';\n  const CLASS_NAME_STATIC = 'modal-static';\n  const SELECTOR_DIALOG = '.modal-dialog';\n  const SELECTOR_MODAL_BODY = '.modal-body';\n  const SELECTOR_DATA_TOGGLE$2 = '[data-bs-toggle=\"modal\"]';\n  /**\n   * ------------------------------------------------------------------------\n   * Class Definition\n   * ------------------------------------------------------------------------\n   */\n\n  class Modal extends BaseComponent {\n    constructor(element, config) {\n      super(element);\n      this._config = this._getConfig(config);\n      this._dialog = SelectorEngine.findOne(SELECTOR_DIALOG, this._element);\n      this._backdrop = this._initializeBackDrop();\n      this._focustrap = this._initializeFocusTrap();\n      this._isShown = false;\n      this._ignoreBackdropClick = false;\n      this._isTransitioning = false;\n      this._scrollBar = new ScrollBarHelper();\n    } // Getters\n\n\n    static get Default() {\n      return Default$5;\n    }\n\n    static get NAME() {\n      return NAME$6;\n    } // Public\n\n\n    toggle(relatedTarget) {\n      return this._isShown ? this.hide() : this.show(relatedTarget);\n    }\n\n    show(relatedTarget) {\n      if (this._isShown || this._isTransitioning) {\n        return;\n      }\n\n      const showEvent = EventHandler.trigger(this._element, EVENT_SHOW$3, {\n        relatedTarget\n      });\n\n      if (showEvent.defaultPrevented) {\n        return;\n      }\n\n      this._isShown = true;\n\n      if (this._isAnimated()) {\n        this._isTransitioning = true;\n      }\n\n      this._scrollBar.hide();\n\n      document.body.classList.add(CLASS_NAME_OPEN);\n\n      this._adjustDialog();\n\n      this._setEscapeEvent();\n\n      this._setResizeEvent();\n\n      EventHandler.on(this._dialog, EVENT_MOUSEDOWN_DISMISS, () => {\n        EventHandler.one(this._element, EVENT_MOUSEUP_DISMISS, event => {\n          if (event.target === this._element) {\n            this._ignoreBackdropClick = true;\n          }\n        });\n      });\n\n      this._showBackdrop(() => this._showElement(relatedTarget));\n    }\n\n    hide() {\n      if (!this._isShown || this._isTransitioning) {\n        return;\n      }\n\n      const hideEvent = EventHandler.trigger(this._element, EVENT_HIDE$3);\n\n      if (hideEvent.defaultPrevented) {\n        return;\n      }\n\n      this._isShown = false;\n\n      const isAnimated = this._isAnimated();\n\n      if (isAnimated) {\n        this._isTransitioning = true;\n      }\n\n      this._setEscapeEvent();\n\n      this._setResizeEvent();\n\n      this._focustrap.deactivate();\n\n      this._element.classList.remove(CLASS_NAME_SHOW$4);\n\n      EventHandler.off(this._element, EVENT_CLICK_DISMISS);\n      EventHandler.off(this._dialog, EVENT_MOUSEDOWN_DISMISS);\n\n      this._queueCallback(() => this._hideModal(), this._element, isAnimated);\n    }\n\n    dispose() {\n      [window, this._dialog].forEach(htmlElement => EventHandler.off(htmlElement, EVENT_KEY$6));\n\n      this._backdrop.dispose();\n\n      this._focustrap.deactivate();\n\n      super.dispose();\n    }\n\n    handleUpdate() {\n      this._adjustDialog();\n    } // Private\n\n\n    _initializeBackDrop() {\n      return new Backdrop({\n        isVisible: Boolean(this._config.backdrop),\n        // 'static' option will be translated to true, and booleans will keep their value\n        isAnimated: this._isAnimated()\n      });\n    }\n\n    _initializeFocusTrap() {\n      return new FocusTrap({\n        trapElement: this._element\n      });\n    }\n\n    _getConfig(config) {\n      config = { ...Default$5,\n        ...Manipulator.getDataAttributes(this._element),\n        ...(typeof config === 'object' ? config : {})\n      };\n      typeCheckConfig(NAME$6, config, DefaultType$5);\n      return config;\n    }\n\n    _showElement(relatedTarget) {\n      const isAnimated = this._isAnimated();\n\n      const modalBody = SelectorEngine.findOne(SELECTOR_MODAL_BODY, this._dialog);\n\n      if (!this._element.parentNode || this._element.parentNode.nodeType !== Node.ELEMENT_NODE) {\n        // Don't move modal's DOM position\n        document.body.append(this._element);\n      }\n\n      this._element.style.display = 'block';\n\n      this._element.removeAttribute('aria-hidden');\n\n      this._element.setAttribute('aria-modal', true);\n\n      this._element.setAttribute('role', 'dialog');\n\n      this._element.scrollTop = 0;\n\n      if (modalBody) {\n        modalBody.scrollTop = 0;\n      }\n\n      if (isAnimated) {\n        reflow(this._element);\n      }\n\n      this._element.classList.add(CLASS_NAME_SHOW$4);\n\n      const transitionComplete = () => {\n        if (this._config.focus) {\n          this._focustrap.activate();\n        }\n\n        this._isTransitioning = false;\n        EventHandler.trigger(this._element, EVENT_SHOWN$3, {\n          relatedTarget\n        });\n      };\n\n      this._queueCallback(transitionComplete, this._dialog, isAnimated);\n    }\n\n    _setEscapeEvent() {\n      if (this._isShown) {\n        EventHandler.on(this._element, EVENT_KEYDOWN_DISMISS$1, event => {\n          if (this._config.keyboard && event.key === ESCAPE_KEY$1) {\n            event.preventDefault();\n            this.hide();\n          } else if (!this._config.keyboard && event.key === ESCAPE_KEY$1) {\n            this._triggerBackdropTransition();\n          }\n        });\n      } else {\n        EventHandler.off(this._element, EVENT_KEYDOWN_DISMISS$1);\n      }\n    }\n\n    _setResizeEvent() {\n      if (this._isShown) {\n        EventHandler.on(window, EVENT_RESIZE, () => this._adjustDialog());\n      } else {\n        EventHandler.off(window, EVENT_RESIZE);\n      }\n    }\n\n    _hideModal() {\n      this._element.style.display = 'none';\n\n      this._element.setAttribute('aria-hidden', true);\n\n      this._element.removeAttribute('aria-modal');\n\n      this._element.removeAttribute('role');\n\n      this._isTransitioning = false;\n\n      this._backdrop.hide(() => {\n        document.body.classList.remove(CLASS_NAME_OPEN);\n\n        this._resetAdjustments();\n\n        this._scrollBar.reset();\n\n        EventHandler.trigger(this._element, EVENT_HIDDEN$3);\n      });\n    }\n\n    _showBackdrop(callback) {\n      EventHandler.on(this._element, EVENT_CLICK_DISMISS, event => {\n        if (this._ignoreBackdropClick) {\n          this._ignoreBackdropClick = false;\n          return;\n        }\n\n        if (event.target !== event.currentTarget) {\n          return;\n        }\n\n        if (this._config.backdrop === true) {\n          this.hide();\n        } else if (this._config.backdrop === 'static') {\n          this._triggerBackdropTransition();\n        }\n      });\n\n      this._backdrop.show(callback);\n    }\n\n    _isAnimated() {\n      return this._element.classList.contains(CLASS_NAME_FADE$3);\n    }\n\n    _triggerBackdropTransition() {\n      const hideEvent = EventHandler.trigger(this._element, EVENT_HIDE_PREVENTED);\n\n      if (hideEvent.defaultPrevented) {\n        return;\n      }\n\n      const {\n        classList,\n        scrollHeight,\n        style\n      } = this._element;\n      const isModalOverflowing = scrollHeight > document.documentElement.clientHeight; // return if the following background transition hasn't yet completed\n\n      if (!isModalOverflowing && style.overflowY === 'hidden' || classList.contains(CLASS_NAME_STATIC)) {\n        return;\n      }\n\n      if (!isModalOverflowing) {\n        style.overflowY = 'hidden';\n      }\n\n      classList.add(CLASS_NAME_STATIC);\n\n      this._queueCallback(() => {\n        classList.remove(CLASS_NAME_STATIC);\n\n        if (!isModalOverflowing) {\n          this._queueCallback(() => {\n            style.overflowY = '';\n          }, this._dialog);\n        }\n      }, this._dialog);\n\n      this._element.focus();\n    } // ----------------------------------------------------------------------\n    // the following methods are used to handle overflowing modals\n    // ----------------------------------------------------------------------\n\n\n    _adjustDialog() {\n      const isModalOverflowing = this._element.scrollHeight > document.documentElement.clientHeight;\n\n      const scrollbarWidth = this._scrollBar.getWidth();\n\n      const isBodyOverflowing = scrollbarWidth > 0;\n\n      if (!isBodyOverflowing && isModalOverflowing && !isRTL() || isBodyOverflowing && !isModalOverflowing && isRTL()) {\n        this._element.style.paddingLeft = `${scrollbarWidth}px`;\n      }\n\n      if (isBodyOverflowing && !isModalOverflowing && !isRTL() || !isBodyOverflowing && isModalOverflowing && isRTL()) {\n        this._element.style.paddingRight = `${scrollbarWidth}px`;\n      }\n    }\n\n    _resetAdjustments() {\n      this._element.style.paddingLeft = '';\n      this._element.style.paddingRight = '';\n    } // Static\n\n\n    static jQueryInterface(config, relatedTarget) {\n      return this.each(function () {\n        const data = Modal.getOrCreateInstance(this, config);\n\n        if (typeof config !== 'string') {\n          return;\n        }\n\n        if (typeof data[config] === 'undefined') {\n          throw new TypeError(`No method named \"${config}\"`);\n        }\n\n        data[config](relatedTarget);\n      });\n    }\n\n  }\n  /**\n   * ------------------------------------------------------------------------\n   * Data Api implementation\n   * ------------------------------------------------------------------------\n   */\n\n\n  EventHandler.on(document, EVENT_CLICK_DATA_API$2, SELECTOR_DATA_TOGGLE$2, function (event) {\n    const target = getElementFromSelector(this);\n\n    if (['A', 'AREA'].includes(this.tagName)) {\n      event.preventDefault();\n    }\n\n    EventHandler.one(target, EVENT_SHOW$3, showEvent => {\n      if (showEvent.defaultPrevented) {\n        // only register focus restorer if modal will actually get shown\n        return;\n      }\n\n      EventHandler.one(target, EVENT_HIDDEN$3, () => {\n        if (isVisible(this)) {\n          this.focus();\n        }\n      });\n    });\n    const data = Modal.getOrCreateInstance(target);\n    data.toggle(this);\n  });\n  enableDismissTrigger(Modal);\n  /**\n   * ------------------------------------------------------------------------\n   * jQuery\n   * ------------------------------------------------------------------------\n   * add .Modal to jQuery only if jQuery is present\n   */\n\n  defineJQueryPlugin(Modal);\n\n  /**\n   * --------------------------------------------------------------------------\n   * Bootstrap (v5.1.0): offcanvas.js\n   * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n   * --------------------------------------------------------------------------\n   */\n  /**\n   * ------------------------------------------------------------------------\n   * Constants\n   * ------------------------------------------------------------------------\n   */\n\n  const NAME$5 = 'offcanvas';\n  const DATA_KEY$5 = 'bs.offcanvas';\n  const EVENT_KEY$5 = `.${DATA_KEY$5}`;\n  const DATA_API_KEY$2 = '.data-api';\n  const EVENT_LOAD_DATA_API$1 = `load${EVENT_KEY$5}${DATA_API_KEY$2}`;\n  const ESCAPE_KEY = 'Escape';\n  const Default$4 = {\n    backdrop: true,\n    keyboard: true,\n    scroll: false\n  };\n  const DefaultType$4 = {\n    backdrop: 'boolean',\n    keyboard: 'boolean',\n    scroll: 'boolean'\n  };\n  const CLASS_NAME_SHOW$3 = 'show';\n  const CLASS_NAME_BACKDROP = 'offcanvas-backdrop';\n  const OPEN_SELECTOR = '.offcanvas.show';\n  const EVENT_SHOW$2 = `show${EVENT_KEY$5}`;\n  const EVENT_SHOWN$2 = `shown${EVENT_KEY$5}`;\n  const EVENT_HIDE$2 = `hide${EVENT_KEY$5}`;\n  const EVENT_HIDDEN$2 = `hidden${EVENT_KEY$5}`;\n  const EVENT_CLICK_DATA_API$1 = `click${EVENT_KEY$5}${DATA_API_KEY$2}`;\n  const EVENT_KEYDOWN_DISMISS = `keydown.dismiss${EVENT_KEY$5}`;\n  const SELECTOR_DATA_TOGGLE$1 = '[data-bs-toggle=\"offcanvas\"]';\n  /**\n   * ------------------------------------------------------------------------\n   * Class Definition\n   * ------------------------------------------------------------------------\n   */\n\n  class Offcanvas extends BaseComponent {\n    constructor(element, config) {\n      super(element);\n      this._config = this._getConfig(config);\n      this._isShown = false;\n      this._backdrop = this._initializeBackDrop();\n      this._focustrap = this._initializeFocusTrap();\n\n      this._addEventListeners();\n    } // Getters\n\n\n    static get NAME() {\n      return NAME$5;\n    }\n\n    static get Default() {\n      return Default$4;\n    } // Public\n\n\n    toggle(relatedTarget) {\n      return this._isShown ? this.hide() : this.show(relatedTarget);\n    }\n\n    show(relatedTarget) {\n      if (this._isShown) {\n        return;\n      }\n\n      const showEvent = EventHandler.trigger(this._element, EVENT_SHOW$2, {\n        relatedTarget\n      });\n\n      if (showEvent.defaultPrevented) {\n        return;\n      }\n\n      this._isShown = true;\n      this._element.style.visibility = 'visible';\n\n      this._backdrop.show();\n\n      if (!this._config.scroll) {\n        new ScrollBarHelper().hide();\n      }\n\n      this._element.removeAttribute('aria-hidden');\n\n      this._element.setAttribute('aria-modal', true);\n\n      this._element.setAttribute('role', 'dialog');\n\n      this._element.classList.add(CLASS_NAME_SHOW$3);\n\n      const completeCallBack = () => {\n        if (!this._config.scroll) {\n          this._focustrap.activate();\n        }\n\n        EventHandler.trigger(this._element, EVENT_SHOWN$2, {\n          relatedTarget\n        });\n      };\n\n      this._queueCallback(completeCallBack, this._element, true);\n    }\n\n    hide() {\n      if (!this._isShown) {\n        return;\n      }\n\n      const hideEvent = EventHandler.trigger(this._element, EVENT_HIDE$2);\n\n      if (hideEvent.defaultPrevented) {\n        return;\n      }\n\n      this._focustrap.deactivate();\n\n      this._element.blur();\n\n      this._isShown = false;\n\n      this._element.classList.remove(CLASS_NAME_SHOW$3);\n\n      this._backdrop.hide();\n\n      const completeCallback = () => {\n        this._element.setAttribute('aria-hidden', true);\n\n        this._element.removeAttribute('aria-modal');\n\n        this._element.removeAttribute('role');\n\n        this._element.style.visibility = 'hidden';\n\n        if (!this._config.scroll) {\n          new ScrollBarHelper().reset();\n        }\n\n        EventHandler.trigger(this._element, EVENT_HIDDEN$2);\n      };\n\n      this._queueCallback(completeCallback, this._element, true);\n    }\n\n    dispose() {\n      this._backdrop.dispose();\n\n      this._focustrap.deactivate();\n\n      super.dispose();\n    } // Private\n\n\n    _getConfig(config) {\n      config = { ...Default$4,\n        ...Manipulator.getDataAttributes(this._element),\n        ...(typeof config === 'object' ? config : {})\n      };\n      typeCheckConfig(NAME$5, config, DefaultType$4);\n      return config;\n    }\n\n    _initializeBackDrop() {\n      return new Backdrop({\n        className: CLASS_NAME_BACKDROP,\n        isVisible: this._config.backdrop,\n        isAnimated: true,\n        rootElement: this._element.parentNode,\n        clickCallback: () => this.hide()\n      });\n    }\n\n    _initializeFocusTrap() {\n      return new FocusTrap({\n        trapElement: this._element\n      });\n    }\n\n    _addEventListeners() {\n      EventHandler.on(this._element, EVENT_KEYDOWN_DISMISS, event => {\n        if (this._config.keyboard && event.key === ESCAPE_KEY) {\n          this.hide();\n        }\n      });\n    } // Static\n\n\n    static jQueryInterface(config) {\n      return this.each(function () {\n        const data = Offcanvas.getOrCreateInstance(this, config);\n\n        if (typeof config !== 'string') {\n          return;\n        }\n\n        if (data[config] === undefined || config.startsWith('_') || config === 'constructor') {\n          throw new TypeError(`No method named \"${config}\"`);\n        }\n\n        data[config](this);\n      });\n    }\n\n  }\n  /**\n   * ------------------------------------------------------------------------\n   * Data Api implementation\n   * ------------------------------------------------------------------------\n   */\n\n\n  EventHandler.on(document, EVENT_CLICK_DATA_API$1, SELECTOR_DATA_TOGGLE$1, function (event) {\n    const target = getElementFromSelector(this);\n\n    if (['A', 'AREA'].includes(this.tagName)) {\n      event.preventDefault();\n    }\n\n    if (isDisabled(this)) {\n      return;\n    }\n\n    EventHandler.one(target, EVENT_HIDDEN$2, () => {\n      // focus on trigger when it is closed\n      if (isVisible(this)) {\n        this.focus();\n      }\n    }); // avoid conflict when clicking a toggler of an offcanvas, while another is open\n\n    const allReadyOpen = SelectorEngine.findOne(OPEN_SELECTOR);\n\n    if (allReadyOpen && allReadyOpen !== target) {\n      Offcanvas.getInstance(allReadyOpen).hide();\n    }\n\n    const data = Offcanvas.getOrCreateInstance(target);\n    data.toggle(this);\n  });\n  EventHandler.on(window, EVENT_LOAD_DATA_API$1, () => SelectorEngine.find(OPEN_SELECTOR).forEach(el => Offcanvas.getOrCreateInstance(el).show()));\n  enableDismissTrigger(Offcanvas);\n  /**\n   * ------------------------------------------------------------------------\n   * jQuery\n   * ------------------------------------------------------------------------\n   */\n\n  defineJQueryPlugin(Offcanvas);\n\n  /**\n   * --------------------------------------------------------------------------\n   * Bootstrap (v5.1.0): util/sanitizer.js\n   * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n   * --------------------------------------------------------------------------\n   */\n  const uriAttrs = new Set(['background', 'cite', 'href', 'itemtype', 'longdesc', 'poster', 'src', 'xlink:href']);\n  const ARIA_ATTRIBUTE_PATTERN = /^aria-[\\w-]*$/i;\n  /**\n   * A pattern that recognizes a commonly useful subset of URLs that are safe.\n   *\n   * Shoutout to Angular 7 https://github.com/angular/angular/blob/7.2.4/packages/core/src/sanitization/url_sanitizer.ts\n   */\n\n  const SAFE_URL_PATTERN = /^(?:(?:https?|mailto|ftp|tel|file):|[^#&/:?]*(?:[#/?]|$))/i;\n  /**\n   * A pattern that matches safe data URLs. Only matches image, video and audio types.\n   *\n   * Shoutout to Angular 7 https://github.com/angular/angular/blob/7.2.4/packages/core/src/sanitization/url_sanitizer.ts\n   */\n\n  const DATA_URL_PATTERN = /^data:(?:image\\/(?:bmp|gif|jpeg|jpg|png|tiff|webp)|video\\/(?:mpeg|mp4|ogg|webm)|audio\\/(?:mp3|oga|ogg|opus));base64,[\\d+/a-z]+=*$/i;\n\n  const allowedAttribute = (attr, allowedAttributeList) => {\n    const attrName = attr.nodeName.toLowerCase();\n\n    if (allowedAttributeList.includes(attrName)) {\n      if (uriAttrs.has(attrName)) {\n        return Boolean(SAFE_URL_PATTERN.test(attr.nodeValue) || DATA_URL_PATTERN.test(attr.nodeValue));\n      }\n\n      return true;\n    }\n\n    const regExp = allowedAttributeList.filter(attrRegex => attrRegex instanceof RegExp); // Check if a regular expression validates the attribute.\n\n    for (let i = 0, len = regExp.length; i < len; i++) {\n      if (regExp[i].test(attrName)) {\n        return true;\n      }\n    }\n\n    return false;\n  };\n\n  const DefaultAllowlist = {\n    // Global attributes allowed on any supplied element below.\n    '*': ['class', 'dir', 'id', 'lang', 'role', ARIA_ATTRIBUTE_PATTERN],\n    a: ['target', 'href', 'title', 'rel'],\n    area: [],\n    b: [],\n    br: [],\n    col: [],\n    code: [],\n    div: [],\n    em: [],\n    hr: [],\n    h1: [],\n    h2: [],\n    h3: [],\n    h4: [],\n    h5: [],\n    h6: [],\n    i: [],\n    img: ['src', 'srcset', 'alt', 'title', 'width', 'height'],\n    li: [],\n    ol: [],\n    p: [],\n    pre: [],\n    s: [],\n    small: [],\n    span: [],\n    sub: [],\n    sup: [],\n    strong: [],\n    u: [],\n    ul: []\n  };\n  function sanitizeHtml(unsafeHtml, allowList, sanitizeFn) {\n    if (!unsafeHtml.length) {\n      return unsafeHtml;\n    }\n\n    if (sanitizeFn && typeof sanitizeFn === 'function') {\n      return sanitizeFn(unsafeHtml);\n    }\n\n    const domParser = new window.DOMParser();\n    const createdDocument = domParser.parseFromString(unsafeHtml, 'text/html');\n    const allowlistKeys = Object.keys(allowList);\n    const elements = [].concat(...createdDocument.body.querySelectorAll('*'));\n\n    for (let i = 0, len = elements.length; i < len; i++) {\n      const el = elements[i];\n      const elName = el.nodeName.toLowerCase();\n\n      if (!allowlistKeys.includes(elName)) {\n        el.remove();\n        continue;\n      }\n\n      const attributeList = [].concat(...el.attributes);\n      const allowedAttributes = [].concat(allowList['*'] || [], allowList[elName] || []);\n      attributeList.forEach(attr => {\n        if (!allowedAttribute(attr, allowedAttributes)) {\n          el.removeAttribute(attr.nodeName);\n        }\n      });\n    }\n\n    return createdDocument.body.innerHTML;\n  }\n\n  /**\n   * --------------------------------------------------------------------------\n   * Bootstrap (v5.1.0): tooltip.js\n   * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n   * --------------------------------------------------------------------------\n   */\n  /**\n   * ------------------------------------------------------------------------\n   * Constants\n   * ------------------------------------------------------------------------\n   */\n\n  const NAME$4 = 'tooltip';\n  const DATA_KEY$4 = 'bs.tooltip';\n  const EVENT_KEY$4 = `.${DATA_KEY$4}`;\n  const CLASS_PREFIX$1 = 'bs-tooltip';\n  const DISALLOWED_ATTRIBUTES = new Set(['sanitize', 'allowList', 'sanitizeFn']);\n  const DefaultType$3 = {\n    animation: 'boolean',\n    template: 'string',\n    title: '(string|element|function)',\n    trigger: 'string',\n    delay: '(number|object)',\n    html: 'boolean',\n    selector: '(string|boolean)',\n    placement: '(string|function)',\n    offset: '(array|string|function)',\n    container: '(string|element|boolean)',\n    fallbackPlacements: 'array',\n    boundary: '(string|element)',\n    customClass: '(string|function)',\n    sanitize: 'boolean',\n    sanitizeFn: '(null|function)',\n    allowList: 'object',\n    popperConfig: '(null|object|function)'\n  };\n  const AttachmentMap = {\n    AUTO: 'auto',\n    TOP: 'top',\n    RIGHT: isRTL() ? 'left' : 'right',\n    BOTTOM: 'bottom',\n    LEFT: isRTL() ? 'right' : 'left'\n  };\n  const Default$3 = {\n    animation: true,\n    template: '<div class=\"tooltip\" role=\"tooltip\">' + '<div class=\"tooltip-arrow\"></div>' + '<div class=\"tooltip-inner\"></div>' + '</div>',\n    trigger: 'hover focus',\n    title: '',\n    delay: 0,\n    html: false,\n    selector: false,\n    placement: 'top',\n    offset: [0, 0],\n    container: false,\n    fallbackPlacements: ['top', 'right', 'bottom', 'left'],\n    boundary: 'clippingParents',\n    customClass: '',\n    sanitize: true,\n    sanitizeFn: null,\n    allowList: DefaultAllowlist,\n    popperConfig: null\n  };\n  const Event$2 = {\n    HIDE: `hide${EVENT_KEY$4}`,\n    HIDDEN: `hidden${EVENT_KEY$4}`,\n    SHOW: `show${EVENT_KEY$4}`,\n    SHOWN: `shown${EVENT_KEY$4}`,\n    INSERTED: `inserted${EVENT_KEY$4}`,\n    CLICK: `click${EVENT_KEY$4}`,\n    FOCUSIN: `focusin${EVENT_KEY$4}`,\n    FOCUSOUT: `focusout${EVENT_KEY$4}`,\n    MOUSEENTER: `mouseenter${EVENT_KEY$4}`,\n    MOUSELEAVE: `mouseleave${EVENT_KEY$4}`\n  };\n  const CLASS_NAME_FADE$2 = 'fade';\n  const CLASS_NAME_MODAL = 'modal';\n  const CLASS_NAME_SHOW$2 = 'show';\n  const HOVER_STATE_SHOW = 'show';\n  const HOVER_STATE_OUT = 'out';\n  const SELECTOR_TOOLTIP_INNER = '.tooltip-inner';\n  const SELECTOR_MODAL = `.${CLASS_NAME_MODAL}`;\n  const EVENT_MODAL_HIDE = 'hide.bs.modal';\n  const TRIGGER_HOVER = 'hover';\n  const TRIGGER_FOCUS = 'focus';\n  const TRIGGER_CLICK = 'click';\n  const TRIGGER_MANUAL = 'manual';\n  /**\n   * ------------------------------------------------------------------------\n   * Class Definition\n   * ------------------------------------------------------------------------\n   */\n\n  class Tooltip extends BaseComponent {\n    constructor(element, config) {\n      if (typeof Popper === 'undefined') {\n        throw new TypeError('Bootstrap\\'s tooltips require Popper (https://popper.js.org)');\n      }\n\n      super(element); // private\n\n      this._isEnabled = true;\n      this._timeout = 0;\n      this._hoverState = '';\n      this._activeTrigger = {};\n      this._popper = null; // Protected\n\n      this._config = this._getConfig(config);\n      this.tip = null;\n\n      this._setListeners();\n    } // Getters\n\n\n    static get Default() {\n      return Default$3;\n    }\n\n    static get NAME() {\n      return NAME$4;\n    }\n\n    static get Event() {\n      return Event$2;\n    }\n\n    static get DefaultType() {\n      return DefaultType$3;\n    } // Public\n\n\n    enable() {\n      this._isEnabled = true;\n    }\n\n    disable() {\n      this._isEnabled = false;\n    }\n\n    toggleEnabled() {\n      this._isEnabled = !this._isEnabled;\n    }\n\n    toggle(event) {\n      if (!this._isEnabled) {\n        return;\n      }\n\n      if (event) {\n        const context = this._initializeOnDelegatedTarget(event);\n\n        context._activeTrigger.click = !context._activeTrigger.click;\n\n        if (context._isWithActiveTrigger()) {\n          context._enter(null, context);\n        } else {\n          context._leave(null, context);\n        }\n      } else {\n        if (this.getTipElement().classList.contains(CLASS_NAME_SHOW$2)) {\n          this._leave(null, this);\n\n          return;\n        }\n\n        this._enter(null, this);\n      }\n    }\n\n    dispose() {\n      clearTimeout(this._timeout);\n      EventHandler.off(this._element.closest(SELECTOR_MODAL), EVENT_MODAL_HIDE, this._hideModalHandler);\n\n      if (this.tip) {\n        this.tip.remove();\n      }\n\n      if (this._popper) {\n        this._popper.destroy();\n      }\n\n      super.dispose();\n    }\n\n    show() {\n      if (this._element.style.display === 'none') {\n        throw new Error('Please use show on visible elements');\n      }\n\n      if (!(this.isWithContent() && this._isEnabled)) {\n        return;\n      }\n\n      const showEvent = EventHandler.trigger(this._element, this.constructor.Event.SHOW);\n      const shadowRoot = findShadowRoot(this._element);\n      const isInTheDom = shadowRoot === null ? this._element.ownerDocument.documentElement.contains(this._element) : shadowRoot.contains(this._element);\n\n      if (showEvent.defaultPrevented || !isInTheDom) {\n        return;\n      }\n\n      const tip = this.getTipElement();\n      const tipId = getUID(this.constructor.NAME);\n      tip.setAttribute('id', tipId);\n\n      this._element.setAttribute('aria-describedby', tipId);\n\n      if (this._config.animation) {\n        tip.classList.add(CLASS_NAME_FADE$2);\n      }\n\n      const placement = typeof this._config.placement === 'function' ? this._config.placement.call(this, tip, this._element) : this._config.placement;\n\n      const attachment = this._getAttachment(placement);\n\n      this._addAttachmentClass(attachment);\n\n      const {\n        container\n      } = this._config;\n      Data.set(tip, this.constructor.DATA_KEY, this);\n\n      if (!this._element.ownerDocument.documentElement.contains(this.tip)) {\n        container.append(tip);\n        EventHandler.trigger(this._element, this.constructor.Event.INSERTED);\n      }\n\n      if (this._popper) {\n        this._popper.update();\n      } else {\n        this._popper = createPopper(this._element, tip, this._getPopperConfig(attachment));\n      }\n\n      tip.classList.add(CLASS_NAME_SHOW$2);\n\n      const customClass = this._resolvePossibleFunction(this._config.customClass);\n\n      if (customClass) {\n        tip.classList.add(...customClass.split(' '));\n      } // If this is a touch-enabled device we add extra\n      // empty mouseover listeners to the body's immediate children;\n      // only needed because of broken event delegation on iOS\n      // https://www.quirksmode.org/blog/archives/2014/02/mouse_event_bub.html\n\n\n      if ('ontouchstart' in document.documentElement) {\n        [].concat(...document.body.children).forEach(element => {\n          EventHandler.on(element, 'mouseover', noop);\n        });\n      }\n\n      const complete = () => {\n        const prevHoverState = this._hoverState;\n        this._hoverState = null;\n        EventHandler.trigger(this._element, this.constructor.Event.SHOWN);\n\n        if (prevHoverState === HOVER_STATE_OUT) {\n          this._leave(null, this);\n        }\n      };\n\n      const isAnimated = this.tip.classList.contains(CLASS_NAME_FADE$2);\n\n      this._queueCallback(complete, this.tip, isAnimated);\n    }\n\n    hide() {\n      if (!this._popper) {\n        return;\n      }\n\n      const tip = this.getTipElement();\n\n      const complete = () => {\n        if (this._isWithActiveTrigger()) {\n          return;\n        }\n\n        if (this._hoverState !== HOVER_STATE_SHOW) {\n          tip.remove();\n        }\n\n        this._cleanTipClass();\n\n        this._element.removeAttribute('aria-describedby');\n\n        EventHandler.trigger(this._element, this.constructor.Event.HIDDEN);\n\n        if (this._popper) {\n          this._popper.destroy();\n\n          this._popper = null;\n        }\n      };\n\n      const hideEvent = EventHandler.trigger(this._element, this.constructor.Event.HIDE);\n\n      if (hideEvent.defaultPrevented) {\n        return;\n      }\n\n      tip.classList.remove(CLASS_NAME_SHOW$2); // If this is a touch-enabled device we remove the extra\n      // empty mouseover listeners we added for iOS support\n\n      if ('ontouchstart' in document.documentElement) {\n        [].concat(...document.body.children).forEach(element => EventHandler.off(element, 'mouseover', noop));\n      }\n\n      this._activeTrigger[TRIGGER_CLICK] = false;\n      this._activeTrigger[TRIGGER_FOCUS] = false;\n      this._activeTrigger[TRIGGER_HOVER] = false;\n      const isAnimated = this.tip.classList.contains(CLASS_NAME_FADE$2);\n\n      this._queueCallback(complete, this.tip, isAnimated);\n\n      this._hoverState = '';\n    }\n\n    update() {\n      if (this._popper !== null) {\n        this._popper.update();\n      }\n    } // Protected\n\n\n    isWithContent() {\n      return Boolean(this.getTitle());\n    }\n\n    getTipElement() {\n      if (this.tip) {\n        return this.tip;\n      }\n\n      const element = document.createElement('div');\n      element.innerHTML = this._config.template;\n      const tip = element.children[0];\n      this.setContent(tip);\n      tip.classList.remove(CLASS_NAME_FADE$2, CLASS_NAME_SHOW$2);\n      this.tip = tip;\n      return this.tip;\n    }\n\n    setContent(tip) {\n      this._sanitizeAndSetContent(tip, this.getTitle(), SELECTOR_TOOLTIP_INNER);\n    }\n\n    _sanitizeAndSetContent(template, content, selector) {\n      const templateElement = SelectorEngine.findOne(selector, template);\n\n      if (!content && templateElement) {\n        templateElement.remove();\n        return;\n      } // we use append for html objects to maintain js events\n\n\n      this.setElementContent(templateElement, content);\n    }\n\n    setElementContent(element, content) {\n      if (element === null) {\n        return;\n      }\n\n      if (isElement$1(content)) {\n        content = getElement(content); // content is a DOM node or a jQuery\n\n        if (this._config.html) {\n          if (content.parentNode !== element) {\n            element.innerHTML = '';\n            element.append(content);\n          }\n        } else {\n          element.textContent = content.textContent;\n        }\n\n        return;\n      }\n\n      if (this._config.html) {\n        if (this._config.sanitize) {\n          content = sanitizeHtml(content, this._config.allowList, this._config.sanitizeFn);\n        }\n\n        element.innerHTML = content;\n      } else {\n        element.textContent = content;\n      }\n    }\n\n    getTitle() {\n      const title = this._element.getAttribute('data-bs-original-title') || this._config.title;\n\n      return this._resolvePossibleFunction(title);\n    }\n\n    updateAttachment(attachment) {\n      if (attachment === 'right') {\n        return 'end';\n      }\n\n      if (attachment === 'left') {\n        return 'start';\n      }\n\n      return attachment;\n    } // Private\n\n\n    _initializeOnDelegatedTarget(event, context) {\n      return context || this.constructor.getOrCreateInstance(event.delegateTarget, this._getDelegateConfig());\n    }\n\n    _getOffset() {\n      const {\n        offset\n      } = this._config;\n\n      if (typeof offset === 'string') {\n        return offset.split(',').map(val => Number.parseInt(val, 10));\n      }\n\n      if (typeof offset === 'function') {\n        return popperData => offset(popperData, this._element);\n      }\n\n      return offset;\n    }\n\n    _resolvePossibleFunction(content) {\n      return typeof content === 'function' ? content.call(this._element) : content;\n    }\n\n    _getPopperConfig(attachment) {\n      const defaultBsPopperConfig = {\n        placement: attachment,\n        modifiers: [{\n          name: 'flip',\n          options: {\n            fallbackPlacements: this._config.fallbackPlacements\n          }\n        }, {\n          name: 'offset',\n          options: {\n            offset: this._getOffset()\n          }\n        }, {\n          name: 'preventOverflow',\n          options: {\n            boundary: this._config.boundary\n          }\n        }, {\n          name: 'arrow',\n          options: {\n            element: `.${this.constructor.NAME}-arrow`\n          }\n        }, {\n          name: 'onChange',\n          enabled: true,\n          phase: 'afterWrite',\n          fn: data => this._handlePopperPlacementChange(data)\n        }],\n        onFirstUpdate: data => {\n          if (data.options.placement !== data.placement) {\n            this._handlePopperPlacementChange(data);\n          }\n        }\n      };\n      return { ...defaultBsPopperConfig,\n        ...(typeof this._config.popperConfig === 'function' ? this._config.popperConfig(defaultBsPopperConfig) : this._config.popperConfig)\n      };\n    }\n\n    _addAttachmentClass(attachment) {\n      this.getTipElement().classList.add(`${this._getBasicClassPrefix()}-${this.updateAttachment(attachment)}`);\n    }\n\n    _getAttachment(placement) {\n      return AttachmentMap[placement.toUpperCase()];\n    }\n\n    _setListeners() {\n      const triggers = this._config.trigger.split(' ');\n\n      triggers.forEach(trigger => {\n        if (trigger === 'click') {\n          EventHandler.on(this._element, this.constructor.Event.CLICK, this._config.selector, event => this.toggle(event));\n        } else if (trigger !== TRIGGER_MANUAL) {\n          const eventIn = trigger === TRIGGER_HOVER ? this.constructor.Event.MOUSEENTER : this.constructor.Event.FOCUSIN;\n          const eventOut = trigger === TRIGGER_HOVER ? this.constructor.Event.MOUSELEAVE : this.constructor.Event.FOCUSOUT;\n          EventHandler.on(this._element, eventIn, this._config.selector, event => this._enter(event));\n          EventHandler.on(this._element, eventOut, this._config.selector, event => this._leave(event));\n        }\n      });\n\n      this._hideModalHandler = () => {\n        if (this._element) {\n          this.hide();\n        }\n      };\n\n      EventHandler.on(this._element.closest(SELECTOR_MODAL), EVENT_MODAL_HIDE, this._hideModalHandler);\n\n      if (this._config.selector) {\n        this._config = { ...this._config,\n          trigger: 'manual',\n          selector: ''\n        };\n      } else {\n        this._fixTitle();\n      }\n    }\n\n    _fixTitle() {\n      const title = this._element.getAttribute('title');\n\n      const originalTitleType = typeof this._element.getAttribute('data-bs-original-title');\n\n      if (title || originalTitleType !== 'string') {\n        this._element.setAttribute('data-bs-original-title', title || '');\n\n        if (title && !this._element.getAttribute('aria-label') && !this._element.textContent) {\n          this._element.setAttribute('aria-label', title);\n        }\n\n        this._element.setAttribute('title', '');\n      }\n    }\n\n    _enter(event, context) {\n      context = this._initializeOnDelegatedTarget(event, context);\n\n      if (event) {\n        context._activeTrigger[event.type === 'focusin' ? TRIGGER_FOCUS : TRIGGER_HOVER] = true;\n      }\n\n      if (context.getTipElement().classList.contains(CLASS_NAME_SHOW$2) || context._hoverState === HOVER_STATE_SHOW) {\n        context._hoverState = HOVER_STATE_SHOW;\n        return;\n      }\n\n      clearTimeout(context._timeout);\n      context._hoverState = HOVER_STATE_SHOW;\n\n      if (!context._config.delay || !context._config.delay.show) {\n        context.show();\n        return;\n      }\n\n      context._timeout = setTimeout(() => {\n        if (context._hoverState === HOVER_STATE_SHOW) {\n          context.show();\n        }\n      }, context._config.delay.show);\n    }\n\n    _leave(event, context) {\n      context = this._initializeOnDelegatedTarget(event, context);\n\n      if (event) {\n        context._activeTrigger[event.type === 'focusout' ? TRIGGER_FOCUS : TRIGGER_HOVER] = context._element.contains(event.relatedTarget);\n      }\n\n      if (context._isWithActiveTrigger()) {\n        return;\n      }\n\n      clearTimeout(context._timeout);\n      context._hoverState = HOVER_STATE_OUT;\n\n      if (!context._config.delay || !context._config.delay.hide) {\n        context.hide();\n        return;\n      }\n\n      context._timeout = setTimeout(() => {\n        if (context._hoverState === HOVER_STATE_OUT) {\n          context.hide();\n        }\n      }, context._config.delay.hide);\n    }\n\n    _isWithActiveTrigger() {\n      for (const trigger in this._activeTrigger) {\n        if (this._activeTrigger[trigger]) {\n          return true;\n        }\n      }\n\n      return false;\n    }\n\n    _getConfig(config) {\n      const dataAttributes = Manipulator.getDataAttributes(this._element);\n      Object.keys(dataAttributes).forEach(dataAttr => {\n        if (DISALLOWED_ATTRIBUTES.has(dataAttr)) {\n          delete dataAttributes[dataAttr];\n        }\n      });\n      config = { ...this.constructor.Default,\n        ...dataAttributes,\n        ...(typeof config === 'object' && config ? config : {})\n      };\n      config.container = config.container === false ? document.body : getElement(config.container);\n\n      if (typeof config.delay === 'number') {\n        config.delay = {\n          show: config.delay,\n          hide: config.delay\n        };\n      }\n\n      if (typeof config.title === 'number') {\n        config.title = config.title.toString();\n      }\n\n      if (typeof config.content === 'number') {\n        config.content = config.content.toString();\n      }\n\n      typeCheckConfig(NAME$4, config, this.constructor.DefaultType);\n\n      if (config.sanitize) {\n        config.template = sanitizeHtml(config.template, config.allowList, config.sanitizeFn);\n      }\n\n      return config;\n    }\n\n    _getDelegateConfig() {\n      const config = {};\n\n      for (const key in this._config) {\n        if (this.constructor.Default[key] !== this._config[key]) {\n          config[key] = this._config[key];\n        }\n      } // In the future can be replaced with:\n      // const keysWithDifferentValues = Object.entries(this._config).filter(entry => this.constructor.Default[entry[0]] !== this._config[entry[0]])\n      // `Object.fromEntries(keysWithDifferentValues)`\n\n\n      return config;\n    }\n\n    _cleanTipClass() {\n      const tip = this.getTipElement();\n      const basicClassPrefixRegex = new RegExp(`(^|\\\\s)${this._getBasicClassPrefix()}\\\\S+`, 'g');\n      const tabClass = tip.getAttribute('class').match(basicClassPrefixRegex);\n\n      if (tabClass !== null && tabClass.length > 0) {\n        tabClass.map(token => token.trim()).forEach(tClass => tip.classList.remove(tClass));\n      }\n    }\n\n    _getBasicClassPrefix() {\n      return CLASS_PREFIX$1;\n    }\n\n    _handlePopperPlacementChange(popperData) {\n      const {\n        state\n      } = popperData;\n\n      if (!state) {\n        return;\n      }\n\n      this.tip = state.elements.popper;\n\n      this._cleanTipClass();\n\n      this._addAttachmentClass(this._getAttachment(state.placement));\n    } // Static\n\n\n    static jQueryInterface(config) {\n      return this.each(function () {\n        const data = Tooltip.getOrCreateInstance(this, config);\n\n        if (typeof config === 'string') {\n          if (typeof data[config] === 'undefined') {\n            throw new TypeError(`No method named \"${config}\"`);\n          }\n\n          data[config]();\n        }\n      });\n    }\n\n  }\n  /**\n   * ------------------------------------------------------------------------\n   * jQuery\n   * ------------------------------------------------------------------------\n   * add .Tooltip to jQuery only if jQuery is present\n   */\n\n\n  defineJQueryPlugin(Tooltip);\n\n  /**\n   * --------------------------------------------------------------------------\n   * Bootstrap (v5.1.0): popover.js\n   * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n   * --------------------------------------------------------------------------\n   */\n  /**\n   * ------------------------------------------------------------------------\n   * Constants\n   * ------------------------------------------------------------------------\n   */\n\n  const NAME$3 = 'popover';\n  const DATA_KEY$3 = 'bs.popover';\n  const EVENT_KEY$3 = `.${DATA_KEY$3}`;\n  const CLASS_PREFIX = 'bs-popover';\n  const Default$2 = { ...Tooltip.Default,\n    placement: 'right',\n    offset: [0, 8],\n    trigger: 'click',\n    content: '',\n    template: '<div class=\"popover\" role=\"tooltip\">' + '<div class=\"popover-arrow\"></div>' + '<h3 class=\"popover-header\"></h3>' + '<div class=\"popover-body\"></div>' + '</div>'\n  };\n  const DefaultType$2 = { ...Tooltip.DefaultType,\n    content: '(string|element|function)'\n  };\n  const Event$1 = {\n    HIDE: `hide${EVENT_KEY$3}`,\n    HIDDEN: `hidden${EVENT_KEY$3}`,\n    SHOW: `show${EVENT_KEY$3}`,\n    SHOWN: `shown${EVENT_KEY$3}`,\n    INSERTED: `inserted${EVENT_KEY$3}`,\n    CLICK: `click${EVENT_KEY$3}`,\n    FOCUSIN: `focusin${EVENT_KEY$3}`,\n    FOCUSOUT: `focusout${EVENT_KEY$3}`,\n    MOUSEENTER: `mouseenter${EVENT_KEY$3}`,\n    MOUSELEAVE: `mouseleave${EVENT_KEY$3}`\n  };\n  const SELECTOR_TITLE = '.popover-header';\n  const SELECTOR_CONTENT = '.popover-body';\n  /**\n   * ------------------------------------------------------------------------\n   * Class Definition\n   * ------------------------------------------------------------------------\n   */\n\n  class Popover extends Tooltip {\n    // Getters\n    static get Default() {\n      return Default$2;\n    }\n\n    static get NAME() {\n      return NAME$3;\n    }\n\n    static get Event() {\n      return Event$1;\n    }\n\n    static get DefaultType() {\n      return DefaultType$2;\n    } // Overrides\n\n\n    isWithContent() {\n      return this.getTitle() || this._getContent();\n    }\n\n    setContent(tip) {\n      this._sanitizeAndSetContent(tip, this.getTitle(), SELECTOR_TITLE);\n\n      this._sanitizeAndSetContent(tip, this._getContent(), SELECTOR_CONTENT);\n    } // Private\n\n\n    _getContent() {\n      return this._resolvePossibleFunction(this._config.content);\n    }\n\n    _getBasicClassPrefix() {\n      return CLASS_PREFIX;\n    } // Static\n\n\n    static jQueryInterface(config) {\n      return this.each(function () {\n        const data = Popover.getOrCreateInstance(this, config);\n\n        if (typeof config === 'string') {\n          if (typeof data[config] === 'undefined') {\n            throw new TypeError(`No method named \"${config}\"`);\n          }\n\n          data[config]();\n        }\n      });\n    }\n\n  }\n  /**\n   * ------------------------------------------------------------------------\n   * jQuery\n   * ------------------------------------------------------------------------\n   * add .Popover to jQuery only if jQuery is present\n   */\n\n\n  defineJQueryPlugin(Popover);\n\n  /**\n   * --------------------------------------------------------------------------\n   * Bootstrap (v5.1.0): scrollspy.js\n   * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n   * --------------------------------------------------------------------------\n   */\n  /**\n   * ------------------------------------------------------------------------\n   * Constants\n   * ------------------------------------------------------------------------\n   */\n\n  const NAME$2 = 'scrollspy';\n  const DATA_KEY$2 = 'bs.scrollspy';\n  const EVENT_KEY$2 = `.${DATA_KEY$2}`;\n  const DATA_API_KEY$1 = '.data-api';\n  const Default$1 = {\n    offset: 10,\n    method: 'auto',\n    target: ''\n  };\n  const DefaultType$1 = {\n    offset: 'number',\n    method: 'string',\n    target: '(string|element)'\n  };\n  const EVENT_ACTIVATE = `activate${EVENT_KEY$2}`;\n  const EVENT_SCROLL = `scroll${EVENT_KEY$2}`;\n  const EVENT_LOAD_DATA_API = `load${EVENT_KEY$2}${DATA_API_KEY$1}`;\n  const CLASS_NAME_DROPDOWN_ITEM = 'dropdown-item';\n  const CLASS_NAME_ACTIVE$1 = 'active';\n  const SELECTOR_DATA_SPY = '[data-bs-spy=\"scroll\"]';\n  const SELECTOR_NAV_LIST_GROUP$1 = '.nav, .list-group';\n  const SELECTOR_NAV_LINKS = '.nav-link';\n  const SELECTOR_NAV_ITEMS = '.nav-item';\n  const SELECTOR_LIST_ITEMS = '.list-group-item';\n  const SELECTOR_LINK_ITEMS = `${SELECTOR_NAV_LINKS}, ${SELECTOR_LIST_ITEMS}, .${CLASS_NAME_DROPDOWN_ITEM}`;\n  const SELECTOR_DROPDOWN$1 = '.dropdown';\n  const SELECTOR_DROPDOWN_TOGGLE$1 = '.dropdown-toggle';\n  const METHOD_OFFSET = 'offset';\n  const METHOD_POSITION = 'position';\n  /**\n   * ------------------------------------------------------------------------\n   * Class Definition\n   * ------------------------------------------------------------------------\n   */\n\n  class ScrollSpy extends BaseComponent {\n    constructor(element, config) {\n      super(element);\n      this._scrollElement = this._element.tagName === 'BODY' ? window : this._element;\n      this._config = this._getConfig(config);\n      this._offsets = [];\n      this._targets = [];\n      this._activeTarget = null;\n      this._scrollHeight = 0;\n      EventHandler.on(this._scrollElement, EVENT_SCROLL, () => this._process());\n      this.refresh();\n\n      this._process();\n    } // Getters\n\n\n    static get Default() {\n      return Default$1;\n    }\n\n    static get NAME() {\n      return NAME$2;\n    } // Public\n\n\n    refresh() {\n      const autoMethod = this._scrollElement === this._scrollElement.window ? METHOD_OFFSET : METHOD_POSITION;\n      const offsetMethod = this._config.method === 'auto' ? autoMethod : this._config.method;\n      const offsetBase = offsetMethod === METHOD_POSITION ? this._getScrollTop() : 0;\n      this._offsets = [];\n      this._targets = [];\n      this._scrollHeight = this._getScrollHeight();\n      const targets = SelectorEngine.find(SELECTOR_LINK_ITEMS, this._config.target);\n      targets.map(element => {\n        const targetSelector = getSelectorFromElement(element);\n        const target = targetSelector ? SelectorEngine.findOne(targetSelector) : null;\n\n        if (target) {\n          const targetBCR = target.getBoundingClientRect();\n\n          if (targetBCR.width || targetBCR.height) {\n            return [Manipulator[offsetMethod](target).top + offsetBase, targetSelector];\n          }\n        }\n\n        return null;\n      }).filter(item => item).sort((a, b) => a[0] - b[0]).forEach(item => {\n        this._offsets.push(item[0]);\n\n        this._targets.push(item[1]);\n      });\n    }\n\n    dispose() {\n      EventHandler.off(this._scrollElement, EVENT_KEY$2);\n      super.dispose();\n    } // Private\n\n\n    _getConfig(config) {\n      config = { ...Default$1,\n        ...Manipulator.getDataAttributes(this._element),\n        ...(typeof config === 'object' && config ? config : {})\n      };\n      config.target = getElement(config.target) || document.documentElement;\n      typeCheckConfig(NAME$2, config, DefaultType$1);\n      return config;\n    }\n\n    _getScrollTop() {\n      return this._scrollElement === window ? this._scrollElement.pageYOffset : this._scrollElement.scrollTop;\n    }\n\n    _getScrollHeight() {\n      return this._scrollElement.scrollHeight || Math.max(document.body.scrollHeight, document.documentElement.scrollHeight);\n    }\n\n    _getOffsetHeight() {\n      return this._scrollElement === window ? window.innerHeight : this._scrollElement.getBoundingClientRect().height;\n    }\n\n    _process() {\n      const scrollTop = this._getScrollTop() + this._config.offset;\n\n      const scrollHeight = this._getScrollHeight();\n\n      const maxScroll = this._config.offset + scrollHeight - this._getOffsetHeight();\n\n      if (this._scrollHeight !== scrollHeight) {\n        this.refresh();\n      }\n\n      if (scrollTop >= maxScroll) {\n        const target = this._targets[this._targets.length - 1];\n\n        if (this._activeTarget !== target) {\n          this._activate(target);\n        }\n\n        return;\n      }\n\n      if (this._activeTarget && scrollTop < this._offsets[0] && this._offsets[0] > 0) {\n        this._activeTarget = null;\n\n        this._clear();\n\n        return;\n      }\n\n      for (let i = this._offsets.length; i--;) {\n        const isActiveTarget = this._activeTarget !== this._targets[i] && scrollTop >= this._offsets[i] && (typeof this._offsets[i + 1] === 'undefined' || scrollTop < this._offsets[i + 1]);\n\n        if (isActiveTarget) {\n          this._activate(this._targets[i]);\n        }\n      }\n    }\n\n    _activate(target) {\n      this._activeTarget = target;\n\n      this._clear();\n\n      const queries = SELECTOR_LINK_ITEMS.split(',').map(selector => `${selector}[data-bs-target=\"${target}\"],${selector}[href=\"${target}\"]`);\n      const link = SelectorEngine.findOne(queries.join(','), this._config.target);\n      link.classList.add(CLASS_NAME_ACTIVE$1);\n\n      if (link.classList.contains(CLASS_NAME_DROPDOWN_ITEM)) {\n        SelectorEngine.findOne(SELECTOR_DROPDOWN_TOGGLE$1, link.closest(SELECTOR_DROPDOWN$1)).classList.add(CLASS_NAME_ACTIVE$1);\n      } else {\n        SelectorEngine.parents(link, SELECTOR_NAV_LIST_GROUP$1).forEach(listGroup => {\n          // Set triggered links parents as active\n          // With both <ul> and <nav> markup a parent is the previous sibling of any nav ancestor\n          SelectorEngine.prev(listGroup, `${SELECTOR_NAV_LINKS}, ${SELECTOR_LIST_ITEMS}`).forEach(item => item.classList.add(CLASS_NAME_ACTIVE$1)); // Handle special case when .nav-link is inside .nav-item\n\n          SelectorEngine.prev(listGroup, SELECTOR_NAV_ITEMS).forEach(navItem => {\n            SelectorEngine.children(navItem, SELECTOR_NAV_LINKS).forEach(item => item.classList.add(CLASS_NAME_ACTIVE$1));\n          });\n        });\n      }\n\n      EventHandler.trigger(this._scrollElement, EVENT_ACTIVATE, {\n        relatedTarget: target\n      });\n    }\n\n    _clear() {\n      SelectorEngine.find(SELECTOR_LINK_ITEMS, this._config.target).filter(node => node.classList.contains(CLASS_NAME_ACTIVE$1)).forEach(node => node.classList.remove(CLASS_NAME_ACTIVE$1));\n    } // Static\n\n\n    static jQueryInterface(config) {\n      return this.each(function () {\n        const data = ScrollSpy.getOrCreateInstance(this, config);\n\n        if (typeof config !== 'string') {\n          return;\n        }\n\n        if (typeof data[config] === 'undefined') {\n          throw new TypeError(`No method named \"${config}\"`);\n        }\n\n        data[config]();\n      });\n    }\n\n  }\n  /**\n   * ------------------------------------------------------------------------\n   * Data Api implementation\n   * ------------------------------------------------------------------------\n   */\n\n\n  EventHandler.on(window, EVENT_LOAD_DATA_API, () => {\n    SelectorEngine.find(SELECTOR_DATA_SPY).forEach(spy => new ScrollSpy(spy));\n  });\n  /**\n   * ------------------------------------------------------------------------\n   * jQuery\n   * ------------------------------------------------------------------------\n   * add .ScrollSpy to jQuery only if jQuery is present\n   */\n\n  defineJQueryPlugin(ScrollSpy);\n\n  /**\n   * --------------------------------------------------------------------------\n   * Bootstrap (v5.1.0): tab.js\n   * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n   * --------------------------------------------------------------------------\n   */\n  /**\n   * ------------------------------------------------------------------------\n   * Constants\n   * ------------------------------------------------------------------------\n   */\n\n  const NAME$1 = 'tab';\n  const DATA_KEY$1 = 'bs.tab';\n  const EVENT_KEY$1 = `.${DATA_KEY$1}`;\n  const DATA_API_KEY = '.data-api';\n  const EVENT_HIDE$1 = `hide${EVENT_KEY$1}`;\n  const EVENT_HIDDEN$1 = `hidden${EVENT_KEY$1}`;\n  const EVENT_SHOW$1 = `show${EVENT_KEY$1}`;\n  const EVENT_SHOWN$1 = `shown${EVENT_KEY$1}`;\n  const EVENT_CLICK_DATA_API = `click${EVENT_KEY$1}${DATA_API_KEY}`;\n  const CLASS_NAME_DROPDOWN_MENU = 'dropdown-menu';\n  const CLASS_NAME_ACTIVE = 'active';\n  const CLASS_NAME_FADE$1 = 'fade';\n  const CLASS_NAME_SHOW$1 = 'show';\n  const SELECTOR_DROPDOWN = '.dropdown';\n  const SELECTOR_NAV_LIST_GROUP = '.nav, .list-group';\n  const SELECTOR_ACTIVE = '.active';\n  const SELECTOR_ACTIVE_UL = ':scope > li > .active';\n  const SELECTOR_DATA_TOGGLE = '[data-bs-toggle=\"tab\"], [data-bs-toggle=\"pill\"], [data-bs-toggle=\"list\"]';\n  const SELECTOR_DROPDOWN_TOGGLE = '.dropdown-toggle';\n  const SELECTOR_DROPDOWN_ACTIVE_CHILD = ':scope > .dropdown-menu .active';\n  /**\n   * ------------------------------------------------------------------------\n   * Class Definition\n   * ------------------------------------------------------------------------\n   */\n\n  class Tab extends BaseComponent {\n    // Getters\n    static get NAME() {\n      return NAME$1;\n    } // Public\n\n\n    show() {\n      if (this._element.parentNode && this._element.parentNode.nodeType === Node.ELEMENT_NODE && this._element.classList.contains(CLASS_NAME_ACTIVE)) {\n        return;\n      }\n\n      let previous;\n      const target = getElementFromSelector(this._element);\n\n      const listElement = this._element.closest(SELECTOR_NAV_LIST_GROUP);\n\n      if (listElement) {\n        const itemSelector = listElement.nodeName === 'UL' || listElement.nodeName === 'OL' ? SELECTOR_ACTIVE_UL : SELECTOR_ACTIVE;\n        previous = SelectorEngine.find(itemSelector, listElement);\n        previous = previous[previous.length - 1];\n      }\n\n      const hideEvent = previous ? EventHandler.trigger(previous, EVENT_HIDE$1, {\n        relatedTarget: this._element\n      }) : null;\n      const showEvent = EventHandler.trigger(this._element, EVENT_SHOW$1, {\n        relatedTarget: previous\n      });\n\n      if (showEvent.defaultPrevented || hideEvent !== null && hideEvent.defaultPrevented) {\n        return;\n      }\n\n      this._activate(this._element, listElement);\n\n      const complete = () => {\n        EventHandler.trigger(previous, EVENT_HIDDEN$1, {\n          relatedTarget: this._element\n        });\n        EventHandler.trigger(this._element, EVENT_SHOWN$1, {\n          relatedTarget: previous\n        });\n      };\n\n      if (target) {\n        this._activate(target, target.parentNode, complete);\n      } else {\n        complete();\n      }\n    } // Private\n\n\n    _activate(element, container, callback) {\n      const activeElements = container && (container.nodeName === 'UL' || container.nodeName === 'OL') ? SelectorEngine.find(SELECTOR_ACTIVE_UL, container) : SelectorEngine.children(container, SELECTOR_ACTIVE);\n      const active = activeElements[0];\n      const isTransitioning = callback && active && active.classList.contains(CLASS_NAME_FADE$1);\n\n      const complete = () => this._transitionComplete(element, active, callback);\n\n      if (active && isTransitioning) {\n        active.classList.remove(CLASS_NAME_SHOW$1);\n\n        this._queueCallback(complete, element, true);\n      } else {\n        complete();\n      }\n    }\n\n    _transitionComplete(element, active, callback) {\n      if (active) {\n        active.classList.remove(CLASS_NAME_ACTIVE);\n        const dropdownChild = SelectorEngine.findOne(SELECTOR_DROPDOWN_ACTIVE_CHILD, active.parentNode);\n\n        if (dropdownChild) {\n          dropdownChild.classList.remove(CLASS_NAME_ACTIVE);\n        }\n\n        if (active.getAttribute('role') === 'tab') {\n          active.setAttribute('aria-selected', false);\n        }\n      }\n\n      element.classList.add(CLASS_NAME_ACTIVE);\n\n      if (element.getAttribute('role') === 'tab') {\n        element.setAttribute('aria-selected', true);\n      }\n\n      reflow(element);\n\n      if (element.classList.contains(CLASS_NAME_FADE$1)) {\n        element.classList.add(CLASS_NAME_SHOW$1);\n      }\n\n      let parent = element.parentNode;\n\n      if (parent && parent.nodeName === 'LI') {\n        parent = parent.parentNode;\n      }\n\n      if (parent && parent.classList.contains(CLASS_NAME_DROPDOWN_MENU)) {\n        const dropdownElement = element.closest(SELECTOR_DROPDOWN);\n\n        if (dropdownElement) {\n          SelectorEngine.find(SELECTOR_DROPDOWN_TOGGLE, dropdownElement).forEach(dropdown => dropdown.classList.add(CLASS_NAME_ACTIVE));\n        }\n\n        element.setAttribute('aria-expanded', true);\n      }\n\n      if (callback) {\n        callback();\n      }\n    } // Static\n\n\n    static jQueryInterface(config) {\n      return this.each(function () {\n        const data = Tab.getOrCreateInstance(this);\n\n        if (typeof config === 'string') {\n          if (typeof data[config] === 'undefined') {\n            throw new TypeError(`No method named \"${config}\"`);\n          }\n\n          data[config]();\n        }\n      });\n    }\n\n  }\n  /**\n   * ------------------------------------------------------------------------\n   * Data Api implementation\n   * ------------------------------------------------------------------------\n   */\n\n\n  EventHandler.on(document, EVENT_CLICK_DATA_API, SELECTOR_DATA_TOGGLE, function (event) {\n    if (['A', 'AREA'].includes(this.tagName)) {\n      event.preventDefault();\n    }\n\n    if (isDisabled(this)) {\n      return;\n    }\n\n    const data = Tab.getOrCreateInstance(this);\n    data.show();\n  });\n  /**\n   * ------------------------------------------------------------------------\n   * jQuery\n   * ------------------------------------------------------------------------\n   * add .Tab to jQuery only if jQuery is present\n   */\n\n  defineJQueryPlugin(Tab);\n\n  /**\n   * --------------------------------------------------------------------------\n   * Bootstrap (v5.1.0): toast.js\n   * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n   * --------------------------------------------------------------------------\n   */\n  /**\n   * ------------------------------------------------------------------------\n   * Constants\n   * ------------------------------------------------------------------------\n   */\n\n  const NAME = 'toast';\n  const DATA_KEY = 'bs.toast';\n  const EVENT_KEY = `.${DATA_KEY}`;\n  const EVENT_MOUSEOVER = `mouseover${EVENT_KEY}`;\n  const EVENT_MOUSEOUT = `mouseout${EVENT_KEY}`;\n  const EVENT_FOCUSIN = `focusin${EVENT_KEY}`;\n  const EVENT_FOCUSOUT = `focusout${EVENT_KEY}`;\n  const EVENT_HIDE = `hide${EVENT_KEY}`;\n  const EVENT_HIDDEN = `hidden${EVENT_KEY}`;\n  const EVENT_SHOW = `show${EVENT_KEY}`;\n  const EVENT_SHOWN = `shown${EVENT_KEY}`;\n  const CLASS_NAME_FADE = 'fade';\n  const CLASS_NAME_HIDE = 'hide'; // @deprecated - kept here only for backwards compatibility\n\n  const CLASS_NAME_SHOW = 'show';\n  const CLASS_NAME_SHOWING = 'showing';\n  const DefaultType = {\n    animation: 'boolean',\n    autohide: 'boolean',\n    delay: 'number'\n  };\n  const Default = {\n    animation: true,\n    autohide: true,\n    delay: 5000\n  };\n  /**\n   * ------------------------------------------------------------------------\n   * Class Definition\n   * ------------------------------------------------------------------------\n   */\n\n  class Toast extends BaseComponent {\n    constructor(element, config) {\n      super(element);\n      this._config = this._getConfig(config);\n      this._timeout = null;\n      this._hasMouseInteraction = false;\n      this._hasKeyboardInteraction = false;\n\n      this._setListeners();\n    } // Getters\n\n\n    static get DefaultType() {\n      return DefaultType;\n    }\n\n    static get Default() {\n      return Default;\n    }\n\n    static get NAME() {\n      return NAME;\n    } // Public\n\n\n    show() {\n      const showEvent = EventHandler.trigger(this._element, EVENT_SHOW);\n\n      if (showEvent.defaultPrevented) {\n        return;\n      }\n\n      this._clearTimeout();\n\n      if (this._config.animation) {\n        this._element.classList.add(CLASS_NAME_FADE);\n      }\n\n      const complete = () => {\n        this._element.classList.remove(CLASS_NAME_SHOWING);\n\n        EventHandler.trigger(this._element, EVENT_SHOWN);\n\n        this._maybeScheduleHide();\n      };\n\n      this._element.classList.remove(CLASS_NAME_HIDE); // @deprecated\n\n\n      reflow(this._element);\n\n      this._element.classList.add(CLASS_NAME_SHOW);\n\n      this._element.classList.add(CLASS_NAME_SHOWING);\n\n      this._queueCallback(complete, this._element, this._config.animation);\n    }\n\n    hide() {\n      if (!this._element.classList.contains(CLASS_NAME_SHOW)) {\n        return;\n      }\n\n      const hideEvent = EventHandler.trigger(this._element, EVENT_HIDE);\n\n      if (hideEvent.defaultPrevented) {\n        return;\n      }\n\n      const complete = () => {\n        this._element.classList.add(CLASS_NAME_HIDE); // @deprecated\n\n\n        this._element.classList.remove(CLASS_NAME_SHOWING);\n\n        this._element.classList.remove(CLASS_NAME_SHOW);\n\n        EventHandler.trigger(this._element, EVENT_HIDDEN);\n      };\n\n      this._element.classList.add(CLASS_NAME_SHOWING);\n\n      this._queueCallback(complete, this._element, this._config.animation);\n    }\n\n    dispose() {\n      this._clearTimeout();\n\n      if (this._element.classList.contains(CLASS_NAME_SHOW)) {\n        this._element.classList.remove(CLASS_NAME_SHOW);\n      }\n\n      super.dispose();\n    } // Private\n\n\n    _getConfig(config) {\n      config = { ...Default,\n        ...Manipulator.getDataAttributes(this._element),\n        ...(typeof config === 'object' && config ? config : {})\n      };\n      typeCheckConfig(NAME, config, this.constructor.DefaultType);\n      return config;\n    }\n\n    _maybeScheduleHide() {\n      if (!this._config.autohide) {\n        return;\n      }\n\n      if (this._hasMouseInteraction || this._hasKeyboardInteraction) {\n        return;\n      }\n\n      this._timeout = setTimeout(() => {\n        this.hide();\n      }, this._config.delay);\n    }\n\n    _onInteraction(event, isInteracting) {\n      switch (event.type) {\n        case 'mouseover':\n        case 'mouseout':\n          this._hasMouseInteraction = isInteracting;\n          break;\n\n        case 'focusin':\n        case 'focusout':\n          this._hasKeyboardInteraction = isInteracting;\n          break;\n      }\n\n      if (isInteracting) {\n        this._clearTimeout();\n\n        return;\n      }\n\n      const nextElement = event.relatedTarget;\n\n      if (this._element === nextElement || this._element.contains(nextElement)) {\n        return;\n      }\n\n      this._maybeScheduleHide();\n    }\n\n    _setListeners() {\n      EventHandler.on(this._element, EVENT_MOUSEOVER, event => this._onInteraction(event, true));\n      EventHandler.on(this._element, EVENT_MOUSEOUT, event => this._onInteraction(event, false));\n      EventHandler.on(this._element, EVENT_FOCUSIN, event => this._onInteraction(event, true));\n      EventHandler.on(this._element, EVENT_FOCUSOUT, event => this._onInteraction(event, false));\n    }\n\n    _clearTimeout() {\n      clearTimeout(this._timeout);\n      this._timeout = null;\n    } // Static\n\n\n    static jQueryInterface(config) {\n      return this.each(function () {\n        const data = Toast.getOrCreateInstance(this, config);\n\n        if (typeof config === 'string') {\n          if (typeof data[config] === 'undefined') {\n            throw new TypeError(`No method named \"${config}\"`);\n          }\n\n          data[config](this);\n        }\n      });\n    }\n\n  }\n\n  enableDismissTrigger(Toast);\n  /**\n   * ------------------------------------------------------------------------\n   * jQuery\n   * ------------------------------------------------------------------------\n   * add .Toast to jQuery only if jQuery is present\n   */\n\n  defineJQueryPlugin(Toast);\n\n  /**\n   * --------------------------------------------------------------------------\n   * Bootstrap (v5.1.0): index.umd.js\n   * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n   * --------------------------------------------------------------------------\n   */\n  var index_umd = {\n    Alert,\n    Button,\n    Carousel,\n    Collapse,\n    Dropdown,\n    Modal,\n    Offcanvas,\n    Popover,\n    ScrollSpy,\n    Tab,\n    Toast,\n    Tooltip\n  };\n\n  return index_umd;\n\n})));\n//# sourceMappingURL=bootstrap.bundle.js.map\n"
  },
  {
    "path": "sample/src/NimblePros.SampleToDo.Web/wwwroot/lib/bootstrap/dist/js/bootstrap.esm.js",
    "content": "/*!\n  * Bootstrap v5.1.0 (https://getbootstrap.com/)\n  * Copyright 2011-2021 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors)\n  * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n  */\nimport * as Popper from '@popperjs/core';\n\n/**\n * --------------------------------------------------------------------------\n * Bootstrap (v5.1.0): util/index.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\nconst MAX_UID = 1000000;\nconst MILLISECONDS_MULTIPLIER = 1000;\nconst TRANSITION_END = 'transitionend'; // Shoutout AngusCroll (https://goo.gl/pxwQGp)\n\nconst toType = obj => {\n  if (obj === null || obj === undefined) {\n    return `${obj}`;\n  }\n\n  return {}.toString.call(obj).match(/\\s([a-z]+)/i)[1].toLowerCase();\n};\n/**\n * --------------------------------------------------------------------------\n * Public Util Api\n * --------------------------------------------------------------------------\n */\n\n\nconst getUID = prefix => {\n  do {\n    prefix += Math.floor(Math.random() * MAX_UID);\n  } while (document.getElementById(prefix));\n\n  return prefix;\n};\n\nconst getSelector = element => {\n  let selector = element.getAttribute('data-bs-target');\n\n  if (!selector || selector === '#') {\n    let hrefAttr = element.getAttribute('href'); // The only valid content that could double as a selector are IDs or classes,\n    // so everything starting with `#` or `.`. If a \"real\" URL is used as the selector,\n    // `document.querySelector` will rightfully complain it is invalid.\n    // See https://github.com/twbs/bootstrap/issues/32273\n\n    if (!hrefAttr || !hrefAttr.includes('#') && !hrefAttr.startsWith('.')) {\n      return null;\n    } // Just in case some CMS puts out a full URL with the anchor appended\n\n\n    if (hrefAttr.includes('#') && !hrefAttr.startsWith('#')) {\n      hrefAttr = `#${hrefAttr.split('#')[1]}`;\n    }\n\n    selector = hrefAttr && hrefAttr !== '#' ? hrefAttr.trim() : null;\n  }\n\n  return selector;\n};\n\nconst getSelectorFromElement = element => {\n  const selector = getSelector(element);\n\n  if (selector) {\n    return document.querySelector(selector) ? selector : null;\n  }\n\n  return null;\n};\n\nconst getElementFromSelector = element => {\n  const selector = getSelector(element);\n  return selector ? document.querySelector(selector) : null;\n};\n\nconst getTransitionDurationFromElement = element => {\n  if (!element) {\n    return 0;\n  } // Get transition-duration of the element\n\n\n  let {\n    transitionDuration,\n    transitionDelay\n  } = window.getComputedStyle(element);\n  const floatTransitionDuration = Number.parseFloat(transitionDuration);\n  const floatTransitionDelay = Number.parseFloat(transitionDelay); // Return 0 if element or transition duration is not found\n\n  if (!floatTransitionDuration && !floatTransitionDelay) {\n    return 0;\n  } // If multiple durations are defined, take the first\n\n\n  transitionDuration = transitionDuration.split(',')[0];\n  transitionDelay = transitionDelay.split(',')[0];\n  return (Number.parseFloat(transitionDuration) + Number.parseFloat(transitionDelay)) * MILLISECONDS_MULTIPLIER;\n};\n\nconst triggerTransitionEnd = element => {\n  element.dispatchEvent(new Event(TRANSITION_END));\n};\n\nconst isElement = obj => {\n  if (!obj || typeof obj !== 'object') {\n    return false;\n  }\n\n  if (typeof obj.jquery !== 'undefined') {\n    obj = obj[0];\n  }\n\n  return typeof obj.nodeType !== 'undefined';\n};\n\nconst getElement = obj => {\n  if (isElement(obj)) {\n    // it's a jQuery object or a node element\n    return obj.jquery ? obj[0] : obj;\n  }\n\n  if (typeof obj === 'string' && obj.length > 0) {\n    return document.querySelector(obj);\n  }\n\n  return null;\n};\n\nconst typeCheckConfig = (componentName, config, configTypes) => {\n  Object.keys(configTypes).forEach(property => {\n    const expectedTypes = configTypes[property];\n    const value = config[property];\n    const valueType = value && isElement(value) ? 'element' : toType(value);\n\n    if (!new RegExp(expectedTypes).test(valueType)) {\n      throw new TypeError(`${componentName.toUpperCase()}: Option \"${property}\" provided type \"${valueType}\" but expected type \"${expectedTypes}\".`);\n    }\n  });\n};\n\nconst isVisible = element => {\n  if (!isElement(element) || element.getClientRects().length === 0) {\n    return false;\n  }\n\n  return getComputedStyle(element).getPropertyValue('visibility') === 'visible';\n};\n\nconst isDisabled = element => {\n  if (!element || element.nodeType !== Node.ELEMENT_NODE) {\n    return true;\n  }\n\n  if (element.classList.contains('disabled')) {\n    return true;\n  }\n\n  if (typeof element.disabled !== 'undefined') {\n    return element.disabled;\n  }\n\n  return element.hasAttribute('disabled') && element.getAttribute('disabled') !== 'false';\n};\n\nconst findShadowRoot = element => {\n  if (!document.documentElement.attachShadow) {\n    return null;\n  } // Can find the shadow root otherwise it'll return the document\n\n\n  if (typeof element.getRootNode === 'function') {\n    const root = element.getRootNode();\n    return root instanceof ShadowRoot ? root : null;\n  }\n\n  if (element instanceof ShadowRoot) {\n    return element;\n  } // when we don't find a shadow root\n\n\n  if (!element.parentNode) {\n    return null;\n  }\n\n  return findShadowRoot(element.parentNode);\n};\n\nconst noop = () => {};\n/**\n * Trick to restart an element's animation\n *\n * @param {HTMLElement} element\n * @return void\n *\n * @see https://www.charistheo.io/blog/2021/02/restart-a-css-animation-with-javascript/#restarting-a-css-animation\n */\n\n\nconst reflow = element => {\n  // eslint-disable-next-line no-unused-expressions\n  element.offsetHeight;\n};\n\nconst getjQuery = () => {\n  const {\n    jQuery\n  } = window;\n\n  if (jQuery && !document.body.hasAttribute('data-bs-no-jquery')) {\n    return jQuery;\n  }\n\n  return null;\n};\n\nconst DOMContentLoadedCallbacks = [];\n\nconst onDOMContentLoaded = callback => {\n  if (document.readyState === 'loading') {\n    // add listener on the first call when the document is in loading state\n    if (!DOMContentLoadedCallbacks.length) {\n      document.addEventListener('DOMContentLoaded', () => {\n        DOMContentLoadedCallbacks.forEach(callback => callback());\n      });\n    }\n\n    DOMContentLoadedCallbacks.push(callback);\n  } else {\n    callback();\n  }\n};\n\nconst isRTL = () => document.documentElement.dir === 'rtl';\n\nconst defineJQueryPlugin = plugin => {\n  onDOMContentLoaded(() => {\n    const $ = getjQuery();\n    /* istanbul ignore if */\n\n    if ($) {\n      const name = plugin.NAME;\n      const JQUERY_NO_CONFLICT = $.fn[name];\n      $.fn[name] = plugin.jQueryInterface;\n      $.fn[name].Constructor = plugin;\n\n      $.fn[name].noConflict = () => {\n        $.fn[name] = JQUERY_NO_CONFLICT;\n        return plugin.jQueryInterface;\n      };\n    }\n  });\n};\n\nconst execute = callback => {\n  if (typeof callback === 'function') {\n    callback();\n  }\n};\n\nconst executeAfterTransition = (callback, transitionElement, waitForTransition = true) => {\n  if (!waitForTransition) {\n    execute(callback);\n    return;\n  }\n\n  const durationPadding = 5;\n  const emulatedDuration = getTransitionDurationFromElement(transitionElement) + durationPadding;\n  let called = false;\n\n  const handler = ({\n    target\n  }) => {\n    if (target !== transitionElement) {\n      return;\n    }\n\n    called = true;\n    transitionElement.removeEventListener(TRANSITION_END, handler);\n    execute(callback);\n  };\n\n  transitionElement.addEventListener(TRANSITION_END, handler);\n  setTimeout(() => {\n    if (!called) {\n      triggerTransitionEnd(transitionElement);\n    }\n  }, emulatedDuration);\n};\n/**\n * Return the previous/next element of a list.\n *\n * @param {array} list    The list of elements\n * @param activeElement   The active element\n * @param shouldGetNext   Choose to get next or previous element\n * @param isCycleAllowed\n * @return {Element|elem} The proper element\n */\n\n\nconst getNextActiveElement = (list, activeElement, shouldGetNext, isCycleAllowed) => {\n  let index = list.indexOf(activeElement); // if the element does not exist in the list return an element depending on the direction and if cycle is allowed\n\n  if (index === -1) {\n    return list[!shouldGetNext && isCycleAllowed ? list.length - 1 : 0];\n  }\n\n  const listLength = list.length;\n  index += shouldGetNext ? 1 : -1;\n\n  if (isCycleAllowed) {\n    index = (index + listLength) % listLength;\n  }\n\n  return list[Math.max(0, Math.min(index, listLength - 1))];\n};\n\n/**\n * --------------------------------------------------------------------------\n * Bootstrap (v5.1.0): dom/event-handler.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n/**\n * ------------------------------------------------------------------------\n * Constants\n * ------------------------------------------------------------------------\n */\n\nconst namespaceRegex = /[^.]*(?=\\..*)\\.|.*/;\nconst stripNameRegex = /\\..*/;\nconst stripUidRegex = /::\\d+$/;\nconst eventRegistry = {}; // Events storage\n\nlet uidEvent = 1;\nconst customEvents = {\n  mouseenter: 'mouseover',\n  mouseleave: 'mouseout'\n};\nconst customEventsRegex = /^(mouseenter|mouseleave)/i;\nconst nativeEvents = 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']);\n/**\n * ------------------------------------------------------------------------\n * Private methods\n * ------------------------------------------------------------------------\n */\n\nfunction getUidEvent(element, uid) {\n  return uid && `${uid}::${uidEvent++}` || element.uidEvent || uidEvent++;\n}\n\nfunction getEvent(element) {\n  const uid = getUidEvent(element);\n  element.uidEvent = uid;\n  eventRegistry[uid] = eventRegistry[uid] || {};\n  return eventRegistry[uid];\n}\n\nfunction bootstrapHandler(element, fn) {\n  return function handler(event) {\n    event.delegateTarget = element;\n\n    if (handler.oneOff) {\n      EventHandler.off(element, event.type, fn);\n    }\n\n    return fn.apply(element, [event]);\n  };\n}\n\nfunction bootstrapDelegationHandler(element, selector, fn) {\n  return function handler(event) {\n    const domElements = element.querySelectorAll(selector);\n\n    for (let {\n      target\n    } = event; target && target !== this; target = target.parentNode) {\n      for (let i = domElements.length; i--;) {\n        if (domElements[i] === target) {\n          event.delegateTarget = target;\n\n          if (handler.oneOff) {\n            // eslint-disable-next-line unicorn/consistent-destructuring\n            EventHandler.off(element, event.type, selector, fn);\n          }\n\n          return fn.apply(target, [event]);\n        }\n      }\n    } // To please ESLint\n\n\n    return null;\n  };\n}\n\nfunction findHandler(events, handler, delegationSelector = null) {\n  const uidEventList = Object.keys(events);\n\n  for (let i = 0, len = uidEventList.length; i < len; i++) {\n    const event = events[uidEventList[i]];\n\n    if (event.originalHandler === handler && event.delegationSelector === delegationSelector) {\n      return event;\n    }\n  }\n\n  return null;\n}\n\nfunction normalizeParams(originalTypeEvent, handler, delegationFn) {\n  const delegation = typeof handler === 'string';\n  const originalHandler = delegation ? delegationFn : handler;\n  let typeEvent = getTypeEvent(originalTypeEvent);\n  const isNative = nativeEvents.has(typeEvent);\n\n  if (!isNative) {\n    typeEvent = originalTypeEvent;\n  }\n\n  return [delegation, originalHandler, typeEvent];\n}\n\nfunction addHandler(element, originalTypeEvent, handler, delegationFn, oneOff) {\n  if (typeof originalTypeEvent !== 'string' || !element) {\n    return;\n  }\n\n  if (!handler) {\n    handler = delegationFn;\n    delegationFn = null;\n  } // in case of mouseenter or mouseleave wrap the handler within a function that checks for its DOM position\n  // this prevents the handler from being dispatched the same way as mouseover or mouseout does\n\n\n  if (customEventsRegex.test(originalTypeEvent)) {\n    const wrapFn = fn => {\n      return function (event) {\n        if (!event.relatedTarget || event.relatedTarget !== event.delegateTarget && !event.delegateTarget.contains(event.relatedTarget)) {\n          return fn.call(this, event);\n        }\n      };\n    };\n\n    if (delegationFn) {\n      delegationFn = wrapFn(delegationFn);\n    } else {\n      handler = wrapFn(handler);\n    }\n  }\n\n  const [delegation, originalHandler, typeEvent] = normalizeParams(originalTypeEvent, handler, delegationFn);\n  const events = getEvent(element);\n  const handlers = events[typeEvent] || (events[typeEvent] = {});\n  const previousFn = findHandler(handlers, originalHandler, delegation ? handler : null);\n\n  if (previousFn) {\n    previousFn.oneOff = previousFn.oneOff && oneOff;\n    return;\n  }\n\n  const uid = getUidEvent(originalHandler, originalTypeEvent.replace(namespaceRegex, ''));\n  const fn = delegation ? bootstrapDelegationHandler(element, handler, delegationFn) : bootstrapHandler(element, handler);\n  fn.delegationSelector = delegation ? handler : null;\n  fn.originalHandler = originalHandler;\n  fn.oneOff = oneOff;\n  fn.uidEvent = uid;\n  handlers[uid] = fn;\n  element.addEventListener(typeEvent, fn, delegation);\n}\n\nfunction removeHandler(element, events, typeEvent, handler, delegationSelector) {\n  const fn = findHandler(events[typeEvent], handler, delegationSelector);\n\n  if (!fn) {\n    return;\n  }\n\n  element.removeEventListener(typeEvent, fn, Boolean(delegationSelector));\n  delete events[typeEvent][fn.uidEvent];\n}\n\nfunction removeNamespacedHandlers(element, events, typeEvent, namespace) {\n  const storeElementEvent = events[typeEvent] || {};\n  Object.keys(storeElementEvent).forEach(handlerKey => {\n    if (handlerKey.includes(namespace)) {\n      const event = storeElementEvent[handlerKey];\n      removeHandler(element, events, typeEvent, event.originalHandler, event.delegationSelector);\n    }\n  });\n}\n\nfunction getTypeEvent(event) {\n  // allow to get the native events from namespaced events ('click.bs.button' --> 'click')\n  event = event.replace(stripNameRegex, '');\n  return customEvents[event] || event;\n}\n\nconst EventHandler = {\n  on(element, event, handler, delegationFn) {\n    addHandler(element, event, handler, delegationFn, false);\n  },\n\n  one(element, event, handler, delegationFn) {\n    addHandler(element, event, handler, delegationFn, true);\n  },\n\n  off(element, originalTypeEvent, handler, delegationFn) {\n    if (typeof originalTypeEvent !== 'string' || !element) {\n      return;\n    }\n\n    const [delegation, originalHandler, typeEvent] = normalizeParams(originalTypeEvent, handler, delegationFn);\n    const inNamespace = typeEvent !== originalTypeEvent;\n    const events = getEvent(element);\n    const isNamespace = originalTypeEvent.startsWith('.');\n\n    if (typeof originalHandler !== 'undefined') {\n      // Simplest case: handler is passed, remove that listener ONLY.\n      if (!events || !events[typeEvent]) {\n        return;\n      }\n\n      removeHandler(element, events, typeEvent, originalHandler, delegation ? handler : null);\n      return;\n    }\n\n    if (isNamespace) {\n      Object.keys(events).forEach(elementEvent => {\n        removeNamespacedHandlers(element, events, elementEvent, originalTypeEvent.slice(1));\n      });\n    }\n\n    const storeElementEvent = events[typeEvent] || {};\n    Object.keys(storeElementEvent).forEach(keyHandlers => {\n      const handlerKey = keyHandlers.replace(stripUidRegex, '');\n\n      if (!inNamespace || originalTypeEvent.includes(handlerKey)) {\n        const event = storeElementEvent[keyHandlers];\n        removeHandler(element, events, typeEvent, event.originalHandler, event.delegationSelector);\n      }\n    });\n  },\n\n  trigger(element, event, args) {\n    if (typeof event !== 'string' || !element) {\n      return null;\n    }\n\n    const $ = getjQuery();\n    const typeEvent = getTypeEvent(event);\n    const inNamespace = event !== typeEvent;\n    const isNative = nativeEvents.has(typeEvent);\n    let jQueryEvent;\n    let bubbles = true;\n    let nativeDispatch = true;\n    let defaultPrevented = false;\n    let evt = null;\n\n    if (inNamespace && $) {\n      jQueryEvent = $.Event(event, args);\n      $(element).trigger(jQueryEvent);\n      bubbles = !jQueryEvent.isPropagationStopped();\n      nativeDispatch = !jQueryEvent.isImmediatePropagationStopped();\n      defaultPrevented = jQueryEvent.isDefaultPrevented();\n    }\n\n    if (isNative) {\n      evt = document.createEvent('HTMLEvents');\n      evt.initEvent(typeEvent, bubbles, true);\n    } else {\n      evt = new CustomEvent(event, {\n        bubbles,\n        cancelable: true\n      });\n    } // merge custom information in our event\n\n\n    if (typeof args !== 'undefined') {\n      Object.keys(args).forEach(key => {\n        Object.defineProperty(evt, key, {\n          get() {\n            return args[key];\n          }\n\n        });\n      });\n    }\n\n    if (defaultPrevented) {\n      evt.preventDefault();\n    }\n\n    if (nativeDispatch) {\n      element.dispatchEvent(evt);\n    }\n\n    if (evt.defaultPrevented && typeof jQueryEvent !== 'undefined') {\n      jQueryEvent.preventDefault();\n    }\n\n    return evt;\n  }\n\n};\n\n/**\n * --------------------------------------------------------------------------\n * Bootstrap (v5.1.0): dom/data.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\n/**\n * ------------------------------------------------------------------------\n * Constants\n * ------------------------------------------------------------------------\n */\nconst elementMap = new Map();\nvar Data = {\n  set(element, key, instance) {\n    if (!elementMap.has(element)) {\n      elementMap.set(element, new Map());\n    }\n\n    const instanceMap = elementMap.get(element); // make it clear we only want one instance per element\n    // can be removed later when multiple key/instances are fine to be used\n\n    if (!instanceMap.has(key) && instanceMap.size !== 0) {\n      // eslint-disable-next-line no-console\n      console.error(`Bootstrap doesn't allow more than one instance per element. Bound instance: ${Array.from(instanceMap.keys())[0]}.`);\n      return;\n    }\n\n    instanceMap.set(key, instance);\n  },\n\n  get(element, key) {\n    if (elementMap.has(element)) {\n      return elementMap.get(element).get(key) || null;\n    }\n\n    return null;\n  },\n\n  remove(element, key) {\n    if (!elementMap.has(element)) {\n      return;\n    }\n\n    const instanceMap = elementMap.get(element);\n    instanceMap.delete(key); // free up element references if there are no instances left for an element\n\n    if (instanceMap.size === 0) {\n      elementMap.delete(element);\n    }\n  }\n\n};\n\n/**\n * --------------------------------------------------------------------------\n * Bootstrap (v5.1.0): base-component.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n/**\n * ------------------------------------------------------------------------\n * Constants\n * ------------------------------------------------------------------------\n */\n\nconst VERSION = '5.1.0';\n\nclass BaseComponent {\n  constructor(element) {\n    element = getElement(element);\n\n    if (!element) {\n      return;\n    }\n\n    this._element = element;\n    Data.set(this._element, this.constructor.DATA_KEY, this);\n  }\n\n  dispose() {\n    Data.remove(this._element, this.constructor.DATA_KEY);\n    EventHandler.off(this._element, this.constructor.EVENT_KEY);\n    Object.getOwnPropertyNames(this).forEach(propertyName => {\n      this[propertyName] = null;\n    });\n  }\n\n  _queueCallback(callback, element, isAnimated = true) {\n    executeAfterTransition(callback, element, isAnimated);\n  }\n  /** Static */\n\n\n  static getInstance(element) {\n    return Data.get(getElement(element), this.DATA_KEY);\n  }\n\n  static getOrCreateInstance(element, config = {}) {\n    return this.getInstance(element) || new this(element, typeof config === 'object' ? config : null);\n  }\n\n  static get VERSION() {\n    return VERSION;\n  }\n\n  static get NAME() {\n    throw new Error('You have to implement the static method \"NAME\", for each component!');\n  }\n\n  static get DATA_KEY() {\n    return `bs.${this.NAME}`;\n  }\n\n  static get EVENT_KEY() {\n    return `.${this.DATA_KEY}`;\n  }\n\n}\n\n/**\n * --------------------------------------------------------------------------\n * Bootstrap (v5.1.0): util/component-functions.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nconst enableDismissTrigger = (component, method = 'hide') => {\n  const clickEvent = `click.dismiss${component.EVENT_KEY}`;\n  const name = component.NAME;\n  EventHandler.on(document, clickEvent, `[data-bs-dismiss=\"${name}\"]`, function (event) {\n    if (['A', 'AREA'].includes(this.tagName)) {\n      event.preventDefault();\n    }\n\n    if (isDisabled(this)) {\n      return;\n    }\n\n    const target = getElementFromSelector(this) || this.closest(`.${name}`);\n    const instance = component.getOrCreateInstance(target); // Method argument is left, for Alert and only, as it doesn't implement the 'hide' method\n\n    instance[method]();\n  });\n};\n\n/**\n * --------------------------------------------------------------------------\n * Bootstrap (v5.1.0): alert.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n/**\n * ------------------------------------------------------------------------\n * Constants\n * ------------------------------------------------------------------------\n */\n\nconst NAME$d = 'alert';\nconst DATA_KEY$c = 'bs.alert';\nconst EVENT_KEY$c = `.${DATA_KEY$c}`;\nconst EVENT_CLOSE = `close${EVENT_KEY$c}`;\nconst EVENT_CLOSED = `closed${EVENT_KEY$c}`;\nconst CLASS_NAME_FADE$5 = 'fade';\nconst CLASS_NAME_SHOW$8 = 'show';\n/**\n * ------------------------------------------------------------------------\n * Class Definition\n * ------------------------------------------------------------------------\n */\n\nclass Alert extends BaseComponent {\n  // Getters\n  static get NAME() {\n    return NAME$d;\n  } // Public\n\n\n  close() {\n    const closeEvent = EventHandler.trigger(this._element, EVENT_CLOSE);\n\n    if (closeEvent.defaultPrevented) {\n      return;\n    }\n\n    this._element.classList.remove(CLASS_NAME_SHOW$8);\n\n    const isAnimated = this._element.classList.contains(CLASS_NAME_FADE$5);\n\n    this._queueCallback(() => this._destroyElement(), this._element, isAnimated);\n  } // Private\n\n\n  _destroyElement() {\n    this._element.remove();\n\n    EventHandler.trigger(this._element, EVENT_CLOSED);\n    this.dispose();\n  } // Static\n\n\n  static jQueryInterface(config) {\n    return this.each(function () {\n      const data = Alert.getOrCreateInstance(this);\n\n      if (typeof config !== 'string') {\n        return;\n      }\n\n      if (data[config] === undefined || config.startsWith('_') || config === 'constructor') {\n        throw new TypeError(`No method named \"${config}\"`);\n      }\n\n      data[config](this);\n    });\n  }\n\n}\n/**\n * ------------------------------------------------------------------------\n * Data Api implementation\n * ------------------------------------------------------------------------\n */\n\n\nenableDismissTrigger(Alert, 'close');\n/**\n * ------------------------------------------------------------------------\n * jQuery\n * ------------------------------------------------------------------------\n * add .Alert to jQuery only if jQuery is present\n */\n\ndefineJQueryPlugin(Alert);\n\n/**\n * --------------------------------------------------------------------------\n * Bootstrap (v5.1.0): button.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n/**\n * ------------------------------------------------------------------------\n * Constants\n * ------------------------------------------------------------------------\n */\n\nconst NAME$c = 'button';\nconst DATA_KEY$b = 'bs.button';\nconst EVENT_KEY$b = `.${DATA_KEY$b}`;\nconst DATA_API_KEY$7 = '.data-api';\nconst CLASS_NAME_ACTIVE$3 = 'active';\nconst SELECTOR_DATA_TOGGLE$5 = '[data-bs-toggle=\"button\"]';\nconst EVENT_CLICK_DATA_API$6 = `click${EVENT_KEY$b}${DATA_API_KEY$7}`;\n/**\n * ------------------------------------------------------------------------\n * Class Definition\n * ------------------------------------------------------------------------\n */\n\nclass Button extends BaseComponent {\n  // Getters\n  static get NAME() {\n    return NAME$c;\n  } // Public\n\n\n  toggle() {\n    // Toggle class and sync the `aria-pressed` attribute with the return value of the `.toggle()` method\n    this._element.setAttribute('aria-pressed', this._element.classList.toggle(CLASS_NAME_ACTIVE$3));\n  } // Static\n\n\n  static jQueryInterface(config) {\n    return this.each(function () {\n      const data = Button.getOrCreateInstance(this);\n\n      if (config === 'toggle') {\n        data[config]();\n      }\n    });\n  }\n\n}\n/**\n * ------------------------------------------------------------------------\n * Data Api implementation\n * ------------------------------------------------------------------------\n */\n\n\nEventHandler.on(document, EVENT_CLICK_DATA_API$6, SELECTOR_DATA_TOGGLE$5, event => {\n  event.preventDefault();\n  const button = event.target.closest(SELECTOR_DATA_TOGGLE$5);\n  const data = Button.getOrCreateInstance(button);\n  data.toggle();\n});\n/**\n * ------------------------------------------------------------------------\n * jQuery\n * ------------------------------------------------------------------------\n * add .Button to jQuery only if jQuery is present\n */\n\ndefineJQueryPlugin(Button);\n\n/**\n * --------------------------------------------------------------------------\n * Bootstrap (v5.1.0): dom/manipulator.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\nfunction normalizeData(val) {\n  if (val === 'true') {\n    return true;\n  }\n\n  if (val === 'false') {\n    return false;\n  }\n\n  if (val === Number(val).toString()) {\n    return Number(val);\n  }\n\n  if (val === '' || val === 'null') {\n    return null;\n  }\n\n  return val;\n}\n\nfunction normalizeDataKey(key) {\n  return key.replace(/[A-Z]/g, chr => `-${chr.toLowerCase()}`);\n}\n\nconst Manipulator = {\n  setDataAttribute(element, key, value) {\n    element.setAttribute(`data-bs-${normalizeDataKey(key)}`, value);\n  },\n\n  removeDataAttribute(element, key) {\n    element.removeAttribute(`data-bs-${normalizeDataKey(key)}`);\n  },\n\n  getDataAttributes(element) {\n    if (!element) {\n      return {};\n    }\n\n    const attributes = {};\n    Object.keys(element.dataset).filter(key => key.startsWith('bs')).forEach(key => {\n      let pureKey = key.replace(/^bs/, '');\n      pureKey = pureKey.charAt(0).toLowerCase() + pureKey.slice(1, pureKey.length);\n      attributes[pureKey] = normalizeData(element.dataset[key]);\n    });\n    return attributes;\n  },\n\n  getDataAttribute(element, key) {\n    return normalizeData(element.getAttribute(`data-bs-${normalizeDataKey(key)}`));\n  },\n\n  offset(element) {\n    const rect = element.getBoundingClientRect();\n    return {\n      top: rect.top + window.pageYOffset,\n      left: rect.left + window.pageXOffset\n    };\n  },\n\n  position(element) {\n    return {\n      top: element.offsetTop,\n      left: element.offsetLeft\n    };\n  }\n\n};\n\n/**\n * --------------------------------------------------------------------------\n * Bootstrap (v5.1.0): dom/selector-engine.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\nconst NODE_TEXT = 3;\nconst SelectorEngine = {\n  find(selector, element = document.documentElement) {\n    return [].concat(...Element.prototype.querySelectorAll.call(element, selector));\n  },\n\n  findOne(selector, element = document.documentElement) {\n    return Element.prototype.querySelector.call(element, selector);\n  },\n\n  children(element, selector) {\n    return [].concat(...element.children).filter(child => child.matches(selector));\n  },\n\n  parents(element, selector) {\n    const parents = [];\n    let ancestor = element.parentNode;\n\n    while (ancestor && ancestor.nodeType === Node.ELEMENT_NODE && ancestor.nodeType !== NODE_TEXT) {\n      if (ancestor.matches(selector)) {\n        parents.push(ancestor);\n      }\n\n      ancestor = ancestor.parentNode;\n    }\n\n    return parents;\n  },\n\n  prev(element, selector) {\n    let previous = element.previousElementSibling;\n\n    while (previous) {\n      if (previous.matches(selector)) {\n        return [previous];\n      }\n\n      previous = previous.previousElementSibling;\n    }\n\n    return [];\n  },\n\n  next(element, selector) {\n    let next = element.nextElementSibling;\n\n    while (next) {\n      if (next.matches(selector)) {\n        return [next];\n      }\n\n      next = next.nextElementSibling;\n    }\n\n    return [];\n  },\n\n  focusableChildren(element) {\n    const focusables = ['a', 'button', 'input', 'textarea', 'select', 'details', '[tabindex]', '[contenteditable=\"true\"]'].map(selector => `${selector}:not([tabindex^=\"-\"])`).join(', ');\n    return this.find(focusables, element).filter(el => !isDisabled(el) && isVisible(el));\n  }\n\n};\n\n/**\n * --------------------------------------------------------------------------\n * Bootstrap (v5.1.0): carousel.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n/**\n * ------------------------------------------------------------------------\n * Constants\n * ------------------------------------------------------------------------\n */\n\nconst NAME$b = 'carousel';\nconst DATA_KEY$a = 'bs.carousel';\nconst EVENT_KEY$a = `.${DATA_KEY$a}`;\nconst DATA_API_KEY$6 = '.data-api';\nconst ARROW_LEFT_KEY = 'ArrowLeft';\nconst ARROW_RIGHT_KEY = 'ArrowRight';\nconst TOUCHEVENT_COMPAT_WAIT = 500; // Time for mouse compat events to fire after touch\n\nconst SWIPE_THRESHOLD = 40;\nconst Default$a = {\n  interval: 5000,\n  keyboard: true,\n  slide: false,\n  pause: 'hover',\n  wrap: true,\n  touch: true\n};\nconst DefaultType$a = {\n  interval: '(number|boolean)',\n  keyboard: 'boolean',\n  slide: '(boolean|string)',\n  pause: '(string|boolean)',\n  wrap: 'boolean',\n  touch: 'boolean'\n};\nconst ORDER_NEXT = 'next';\nconst ORDER_PREV = 'prev';\nconst DIRECTION_LEFT = 'left';\nconst DIRECTION_RIGHT = 'right';\nconst KEY_TO_DIRECTION = {\n  [ARROW_LEFT_KEY]: DIRECTION_RIGHT,\n  [ARROW_RIGHT_KEY]: DIRECTION_LEFT\n};\nconst EVENT_SLIDE = `slide${EVENT_KEY$a}`;\nconst EVENT_SLID = `slid${EVENT_KEY$a}`;\nconst EVENT_KEYDOWN = `keydown${EVENT_KEY$a}`;\nconst EVENT_MOUSEENTER = `mouseenter${EVENT_KEY$a}`;\nconst EVENT_MOUSELEAVE = `mouseleave${EVENT_KEY$a}`;\nconst EVENT_TOUCHSTART = `touchstart${EVENT_KEY$a}`;\nconst EVENT_TOUCHMOVE = `touchmove${EVENT_KEY$a}`;\nconst EVENT_TOUCHEND = `touchend${EVENT_KEY$a}`;\nconst EVENT_POINTERDOWN = `pointerdown${EVENT_KEY$a}`;\nconst EVENT_POINTERUP = `pointerup${EVENT_KEY$a}`;\nconst EVENT_DRAG_START = `dragstart${EVENT_KEY$a}`;\nconst EVENT_LOAD_DATA_API$2 = `load${EVENT_KEY$a}${DATA_API_KEY$6}`;\nconst EVENT_CLICK_DATA_API$5 = `click${EVENT_KEY$a}${DATA_API_KEY$6}`;\nconst CLASS_NAME_CAROUSEL = 'carousel';\nconst CLASS_NAME_ACTIVE$2 = 'active';\nconst CLASS_NAME_SLIDE = 'slide';\nconst CLASS_NAME_END = 'carousel-item-end';\nconst CLASS_NAME_START = 'carousel-item-start';\nconst CLASS_NAME_NEXT = 'carousel-item-next';\nconst CLASS_NAME_PREV = 'carousel-item-prev';\nconst CLASS_NAME_POINTER_EVENT = 'pointer-event';\nconst SELECTOR_ACTIVE$1 = '.active';\nconst SELECTOR_ACTIVE_ITEM = '.active.carousel-item';\nconst SELECTOR_ITEM = '.carousel-item';\nconst SELECTOR_ITEM_IMG = '.carousel-item img';\nconst SELECTOR_NEXT_PREV = '.carousel-item-next, .carousel-item-prev';\nconst SELECTOR_INDICATORS = '.carousel-indicators';\nconst SELECTOR_INDICATOR = '[data-bs-target]';\nconst SELECTOR_DATA_SLIDE = '[data-bs-slide], [data-bs-slide-to]';\nconst SELECTOR_DATA_RIDE = '[data-bs-ride=\"carousel\"]';\nconst POINTER_TYPE_TOUCH = 'touch';\nconst POINTER_TYPE_PEN = 'pen';\n/**\n * ------------------------------------------------------------------------\n * Class Definition\n * ------------------------------------------------------------------------\n */\n\nclass Carousel extends BaseComponent {\n  constructor(element, config) {\n    super(element);\n    this._items = null;\n    this._interval = null;\n    this._activeElement = null;\n    this._isPaused = false;\n    this._isSliding = false;\n    this.touchTimeout = null;\n    this.touchStartX = 0;\n    this.touchDeltaX = 0;\n    this._config = this._getConfig(config);\n    this._indicatorsElement = SelectorEngine.findOne(SELECTOR_INDICATORS, this._element);\n    this._touchSupported = 'ontouchstart' in document.documentElement || navigator.maxTouchPoints > 0;\n    this._pointerEvent = Boolean(window.PointerEvent);\n\n    this._addEventListeners();\n  } // Getters\n\n\n  static get Default() {\n    return Default$a;\n  }\n\n  static get NAME() {\n    return NAME$b;\n  } // Public\n\n\n  next() {\n    this._slide(ORDER_NEXT);\n  }\n\n  nextWhenVisible() {\n    // Don't call next when the page isn't visible\n    // or the carousel or its parent isn't visible\n    if (!document.hidden && isVisible(this._element)) {\n      this.next();\n    }\n  }\n\n  prev() {\n    this._slide(ORDER_PREV);\n  }\n\n  pause(event) {\n    if (!event) {\n      this._isPaused = true;\n    }\n\n    if (SelectorEngine.findOne(SELECTOR_NEXT_PREV, this._element)) {\n      triggerTransitionEnd(this._element);\n      this.cycle(true);\n    }\n\n    clearInterval(this._interval);\n    this._interval = null;\n  }\n\n  cycle(event) {\n    if (!event) {\n      this._isPaused = false;\n    }\n\n    if (this._interval) {\n      clearInterval(this._interval);\n      this._interval = null;\n    }\n\n    if (this._config && this._config.interval && !this._isPaused) {\n      this._updateInterval();\n\n      this._interval = setInterval((document.visibilityState ? this.nextWhenVisible : this.next).bind(this), this._config.interval);\n    }\n  }\n\n  to(index) {\n    this._activeElement = SelectorEngine.findOne(SELECTOR_ACTIVE_ITEM, this._element);\n\n    const activeIndex = this._getItemIndex(this._activeElement);\n\n    if (index > this._items.length - 1 || index < 0) {\n      return;\n    }\n\n    if (this._isSliding) {\n      EventHandler.one(this._element, EVENT_SLID, () => this.to(index));\n      return;\n    }\n\n    if (activeIndex === index) {\n      this.pause();\n      this.cycle();\n      return;\n    }\n\n    const order = index > activeIndex ? ORDER_NEXT : ORDER_PREV;\n\n    this._slide(order, this._items[index]);\n  } // Private\n\n\n  _getConfig(config) {\n    config = { ...Default$a,\n      ...Manipulator.getDataAttributes(this._element),\n      ...(typeof config === 'object' ? config : {})\n    };\n    typeCheckConfig(NAME$b, config, DefaultType$a);\n    return config;\n  }\n\n  _handleSwipe() {\n    const absDeltax = Math.abs(this.touchDeltaX);\n\n    if (absDeltax <= SWIPE_THRESHOLD) {\n      return;\n    }\n\n    const direction = absDeltax / this.touchDeltaX;\n    this.touchDeltaX = 0;\n\n    if (!direction) {\n      return;\n    }\n\n    this._slide(direction > 0 ? DIRECTION_RIGHT : DIRECTION_LEFT);\n  }\n\n  _addEventListeners() {\n    if (this._config.keyboard) {\n      EventHandler.on(this._element, EVENT_KEYDOWN, event => this._keydown(event));\n    }\n\n    if (this._config.pause === 'hover') {\n      EventHandler.on(this._element, EVENT_MOUSEENTER, event => this.pause(event));\n      EventHandler.on(this._element, EVENT_MOUSELEAVE, event => this.cycle(event));\n    }\n\n    if (this._config.touch && this._touchSupported) {\n      this._addTouchEventListeners();\n    }\n  }\n\n  _addTouchEventListeners() {\n    const start = event => {\n      if (this._pointerEvent && (event.pointerType === POINTER_TYPE_PEN || event.pointerType === POINTER_TYPE_TOUCH)) {\n        this.touchStartX = event.clientX;\n      } else if (!this._pointerEvent) {\n        this.touchStartX = event.touches[0].clientX;\n      }\n    };\n\n    const move = event => {\n      // ensure swiping with one touch and not pinching\n      this.touchDeltaX = event.touches && event.touches.length > 1 ? 0 : event.touches[0].clientX - this.touchStartX;\n    };\n\n    const end = event => {\n      if (this._pointerEvent && (event.pointerType === POINTER_TYPE_PEN || event.pointerType === POINTER_TYPE_TOUCH)) {\n        this.touchDeltaX = event.clientX - this.touchStartX;\n      }\n\n      this._handleSwipe();\n\n      if (this._config.pause === 'hover') {\n        // If it's a touch-enabled device, mouseenter/leave are fired as\n        // part of the mouse compatibility events on first tap - the carousel\n        // would stop cycling until user tapped out of it;\n        // here, we listen for touchend, explicitly pause the carousel\n        // (as if it's the second time we tap on it, mouseenter compat event\n        // is NOT fired) and after a timeout (to allow for mouse compatibility\n        // events to fire) we explicitly restart cycling\n        this.pause();\n\n        if (this.touchTimeout) {\n          clearTimeout(this.touchTimeout);\n        }\n\n        this.touchTimeout = setTimeout(event => this.cycle(event), TOUCHEVENT_COMPAT_WAIT + this._config.interval);\n      }\n    };\n\n    SelectorEngine.find(SELECTOR_ITEM_IMG, this._element).forEach(itemImg => {\n      EventHandler.on(itemImg, EVENT_DRAG_START, e => e.preventDefault());\n    });\n\n    if (this._pointerEvent) {\n      EventHandler.on(this._element, EVENT_POINTERDOWN, event => start(event));\n      EventHandler.on(this._element, EVENT_POINTERUP, event => end(event));\n\n      this._element.classList.add(CLASS_NAME_POINTER_EVENT);\n    } else {\n      EventHandler.on(this._element, EVENT_TOUCHSTART, event => start(event));\n      EventHandler.on(this._element, EVENT_TOUCHMOVE, event => move(event));\n      EventHandler.on(this._element, EVENT_TOUCHEND, event => end(event));\n    }\n  }\n\n  _keydown(event) {\n    if (/input|textarea/i.test(event.target.tagName)) {\n      return;\n    }\n\n    const direction = KEY_TO_DIRECTION[event.key];\n\n    if (direction) {\n      event.preventDefault();\n\n      this._slide(direction);\n    }\n  }\n\n  _getItemIndex(element) {\n    this._items = element && element.parentNode ? SelectorEngine.find(SELECTOR_ITEM, element.parentNode) : [];\n    return this._items.indexOf(element);\n  }\n\n  _getItemByOrder(order, activeElement) {\n    const isNext = order === ORDER_NEXT;\n    return getNextActiveElement(this._items, activeElement, isNext, this._config.wrap);\n  }\n\n  _triggerSlideEvent(relatedTarget, eventDirectionName) {\n    const targetIndex = this._getItemIndex(relatedTarget);\n\n    const fromIndex = this._getItemIndex(SelectorEngine.findOne(SELECTOR_ACTIVE_ITEM, this._element));\n\n    return EventHandler.trigger(this._element, EVENT_SLIDE, {\n      relatedTarget,\n      direction: eventDirectionName,\n      from: fromIndex,\n      to: targetIndex\n    });\n  }\n\n  _setActiveIndicatorElement(element) {\n    if (this._indicatorsElement) {\n      const activeIndicator = SelectorEngine.findOne(SELECTOR_ACTIVE$1, this._indicatorsElement);\n      activeIndicator.classList.remove(CLASS_NAME_ACTIVE$2);\n      activeIndicator.removeAttribute('aria-current');\n      const indicators = SelectorEngine.find(SELECTOR_INDICATOR, this._indicatorsElement);\n\n      for (let i = 0; i < indicators.length; i++) {\n        if (Number.parseInt(indicators[i].getAttribute('data-bs-slide-to'), 10) === this._getItemIndex(element)) {\n          indicators[i].classList.add(CLASS_NAME_ACTIVE$2);\n          indicators[i].setAttribute('aria-current', 'true');\n          break;\n        }\n      }\n    }\n  }\n\n  _updateInterval() {\n    const element = this._activeElement || SelectorEngine.findOne(SELECTOR_ACTIVE_ITEM, this._element);\n\n    if (!element) {\n      return;\n    }\n\n    const elementInterval = Number.parseInt(element.getAttribute('data-bs-interval'), 10);\n\n    if (elementInterval) {\n      this._config.defaultInterval = this._config.defaultInterval || this._config.interval;\n      this._config.interval = elementInterval;\n    } else {\n      this._config.interval = this._config.defaultInterval || this._config.interval;\n    }\n  }\n\n  _slide(directionOrOrder, element) {\n    const order = this._directionToOrder(directionOrOrder);\n\n    const activeElement = SelectorEngine.findOne(SELECTOR_ACTIVE_ITEM, this._element);\n\n    const activeElementIndex = this._getItemIndex(activeElement);\n\n    const nextElement = element || this._getItemByOrder(order, activeElement);\n\n    const nextElementIndex = this._getItemIndex(nextElement);\n\n    const isCycling = Boolean(this._interval);\n    const isNext = order === ORDER_NEXT;\n    const directionalClassName = isNext ? CLASS_NAME_START : CLASS_NAME_END;\n    const orderClassName = isNext ? CLASS_NAME_NEXT : CLASS_NAME_PREV;\n\n    const eventDirectionName = this._orderToDirection(order);\n\n    if (nextElement && nextElement.classList.contains(CLASS_NAME_ACTIVE$2)) {\n      this._isSliding = false;\n      return;\n    }\n\n    if (this._isSliding) {\n      return;\n    }\n\n    const slideEvent = this._triggerSlideEvent(nextElement, eventDirectionName);\n\n    if (slideEvent.defaultPrevented) {\n      return;\n    }\n\n    if (!activeElement || !nextElement) {\n      // Some weirdness is happening, so we bail\n      return;\n    }\n\n    this._isSliding = true;\n\n    if (isCycling) {\n      this.pause();\n    }\n\n    this._setActiveIndicatorElement(nextElement);\n\n    this._activeElement = nextElement;\n\n    const triggerSlidEvent = () => {\n      EventHandler.trigger(this._element, EVENT_SLID, {\n        relatedTarget: nextElement,\n        direction: eventDirectionName,\n        from: activeElementIndex,\n        to: nextElementIndex\n      });\n    };\n\n    if (this._element.classList.contains(CLASS_NAME_SLIDE)) {\n      nextElement.classList.add(orderClassName);\n      reflow(nextElement);\n      activeElement.classList.add(directionalClassName);\n      nextElement.classList.add(directionalClassName);\n\n      const completeCallBack = () => {\n        nextElement.classList.remove(directionalClassName, orderClassName);\n        nextElement.classList.add(CLASS_NAME_ACTIVE$2);\n        activeElement.classList.remove(CLASS_NAME_ACTIVE$2, orderClassName, directionalClassName);\n        this._isSliding = false;\n        setTimeout(triggerSlidEvent, 0);\n      };\n\n      this._queueCallback(completeCallBack, activeElement, true);\n    } else {\n      activeElement.classList.remove(CLASS_NAME_ACTIVE$2);\n      nextElement.classList.add(CLASS_NAME_ACTIVE$2);\n      this._isSliding = false;\n      triggerSlidEvent();\n    }\n\n    if (isCycling) {\n      this.cycle();\n    }\n  }\n\n  _directionToOrder(direction) {\n    if (![DIRECTION_RIGHT, DIRECTION_LEFT].includes(direction)) {\n      return direction;\n    }\n\n    if (isRTL()) {\n      return direction === DIRECTION_LEFT ? ORDER_PREV : ORDER_NEXT;\n    }\n\n    return direction === DIRECTION_LEFT ? ORDER_NEXT : ORDER_PREV;\n  }\n\n  _orderToDirection(order) {\n    if (![ORDER_NEXT, ORDER_PREV].includes(order)) {\n      return order;\n    }\n\n    if (isRTL()) {\n      return order === ORDER_PREV ? DIRECTION_LEFT : DIRECTION_RIGHT;\n    }\n\n    return order === ORDER_PREV ? DIRECTION_RIGHT : DIRECTION_LEFT;\n  } // Static\n\n\n  static carouselInterface(element, config) {\n    const data = Carousel.getOrCreateInstance(element, config);\n    let {\n      _config\n    } = data;\n\n    if (typeof config === 'object') {\n      _config = { ..._config,\n        ...config\n      };\n    }\n\n    const action = typeof config === 'string' ? config : _config.slide;\n\n    if (typeof config === 'number') {\n      data.to(config);\n    } else if (typeof action === 'string') {\n      if (typeof data[action] === 'undefined') {\n        throw new TypeError(`No method named \"${action}\"`);\n      }\n\n      data[action]();\n    } else if (_config.interval && _config.ride) {\n      data.pause();\n      data.cycle();\n    }\n  }\n\n  static jQueryInterface(config) {\n    return this.each(function () {\n      Carousel.carouselInterface(this, config);\n    });\n  }\n\n  static dataApiClickHandler(event) {\n    const target = getElementFromSelector(this);\n\n    if (!target || !target.classList.contains(CLASS_NAME_CAROUSEL)) {\n      return;\n    }\n\n    const config = { ...Manipulator.getDataAttributes(target),\n      ...Manipulator.getDataAttributes(this)\n    };\n    const slideIndex = this.getAttribute('data-bs-slide-to');\n\n    if (slideIndex) {\n      config.interval = false;\n    }\n\n    Carousel.carouselInterface(target, config);\n\n    if (slideIndex) {\n      Carousel.getInstance(target).to(slideIndex);\n    }\n\n    event.preventDefault();\n  }\n\n}\n/**\n * ------------------------------------------------------------------------\n * Data Api implementation\n * ------------------------------------------------------------------------\n */\n\n\nEventHandler.on(document, EVENT_CLICK_DATA_API$5, SELECTOR_DATA_SLIDE, Carousel.dataApiClickHandler);\nEventHandler.on(window, EVENT_LOAD_DATA_API$2, () => {\n  const carousels = SelectorEngine.find(SELECTOR_DATA_RIDE);\n\n  for (let i = 0, len = carousels.length; i < len; i++) {\n    Carousel.carouselInterface(carousels[i], Carousel.getInstance(carousels[i]));\n  }\n});\n/**\n * ------------------------------------------------------------------------\n * jQuery\n * ------------------------------------------------------------------------\n * add .Carousel to jQuery only if jQuery is present\n */\n\ndefineJQueryPlugin(Carousel);\n\n/**\n * --------------------------------------------------------------------------\n * Bootstrap (v5.1.0): collapse.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n/**\n * ------------------------------------------------------------------------\n * Constants\n * ------------------------------------------------------------------------\n */\n\nconst NAME$a = 'collapse';\nconst DATA_KEY$9 = 'bs.collapse';\nconst EVENT_KEY$9 = `.${DATA_KEY$9}`;\nconst DATA_API_KEY$5 = '.data-api';\nconst Default$9 = {\n  toggle: true,\n  parent: null\n};\nconst DefaultType$9 = {\n  toggle: 'boolean',\n  parent: '(null|element)'\n};\nconst EVENT_SHOW$5 = `show${EVENT_KEY$9}`;\nconst EVENT_SHOWN$5 = `shown${EVENT_KEY$9}`;\nconst EVENT_HIDE$5 = `hide${EVENT_KEY$9}`;\nconst EVENT_HIDDEN$5 = `hidden${EVENT_KEY$9}`;\nconst EVENT_CLICK_DATA_API$4 = `click${EVENT_KEY$9}${DATA_API_KEY$5}`;\nconst CLASS_NAME_SHOW$7 = 'show';\nconst CLASS_NAME_COLLAPSE = 'collapse';\nconst CLASS_NAME_COLLAPSING = 'collapsing';\nconst CLASS_NAME_COLLAPSED = 'collapsed';\nconst CLASS_NAME_HORIZONTAL = 'collapse-horizontal';\nconst WIDTH = 'width';\nconst HEIGHT = 'height';\nconst SELECTOR_ACTIVES = '.show, .collapsing';\nconst SELECTOR_DATA_TOGGLE$4 = '[data-bs-toggle=\"collapse\"]';\n/**\n * ------------------------------------------------------------------------\n * Class Definition\n * ------------------------------------------------------------------------\n */\n\nclass Collapse extends BaseComponent {\n  constructor(element, config) {\n    super(element);\n    this._isTransitioning = false;\n    this._config = this._getConfig(config);\n    this._triggerArray = [];\n    const toggleList = SelectorEngine.find(SELECTOR_DATA_TOGGLE$4);\n\n    for (let i = 0, len = toggleList.length; i < len; i++) {\n      const elem = toggleList[i];\n      const selector = getSelectorFromElement(elem);\n      const filterElement = SelectorEngine.find(selector).filter(foundElem => foundElem === this._element);\n\n      if (selector !== null && filterElement.length) {\n        this._selector = selector;\n\n        this._triggerArray.push(elem);\n      }\n    }\n\n    this._initializeChildren();\n\n    if (!this._config.parent) {\n      this._addAriaAndCollapsedClass(this._triggerArray, this._isShown());\n    }\n\n    if (this._config.toggle) {\n      this.toggle();\n    }\n  } // Getters\n\n\n  static get Default() {\n    return Default$9;\n  }\n\n  static get NAME() {\n    return NAME$a;\n  } // Public\n\n\n  toggle() {\n    if (this._isShown()) {\n      this.hide();\n    } else {\n      this.show();\n    }\n  }\n\n  show() {\n    if (this._isTransitioning || this._isShown()) {\n      return;\n    }\n\n    let actives = [];\n    let activesData;\n\n    if (this._config.parent) {\n      const children = SelectorEngine.find(`.${CLASS_NAME_COLLAPSE} .${CLASS_NAME_COLLAPSE}`, this._config.parent);\n      actives = SelectorEngine.find(SELECTOR_ACTIVES, this._config.parent).filter(elem => !children.includes(elem)); // remove children if greater depth\n    }\n\n    const container = SelectorEngine.findOne(this._selector);\n\n    if (actives.length) {\n      const tempActiveData = actives.find(elem => container !== elem);\n      activesData = tempActiveData ? Collapse.getInstance(tempActiveData) : null;\n\n      if (activesData && activesData._isTransitioning) {\n        return;\n      }\n    }\n\n    const startEvent = EventHandler.trigger(this._element, EVENT_SHOW$5);\n\n    if (startEvent.defaultPrevented) {\n      return;\n    }\n\n    actives.forEach(elemActive => {\n      if (container !== elemActive) {\n        Collapse.getOrCreateInstance(elemActive, {\n          toggle: false\n        }).hide();\n      }\n\n      if (!activesData) {\n        Data.set(elemActive, DATA_KEY$9, null);\n      }\n    });\n\n    const dimension = this._getDimension();\n\n    this._element.classList.remove(CLASS_NAME_COLLAPSE);\n\n    this._element.classList.add(CLASS_NAME_COLLAPSING);\n\n    this._element.style[dimension] = 0;\n\n    this._addAriaAndCollapsedClass(this._triggerArray, true);\n\n    this._isTransitioning = true;\n\n    const complete = () => {\n      this._isTransitioning = false;\n\n      this._element.classList.remove(CLASS_NAME_COLLAPSING);\n\n      this._element.classList.add(CLASS_NAME_COLLAPSE, CLASS_NAME_SHOW$7);\n\n      this._element.style[dimension] = '';\n      EventHandler.trigger(this._element, EVENT_SHOWN$5);\n    };\n\n    const capitalizedDimension = dimension[0].toUpperCase() + dimension.slice(1);\n    const scrollSize = `scroll${capitalizedDimension}`;\n\n    this._queueCallback(complete, this._element, true);\n\n    this._element.style[dimension] = `${this._element[scrollSize]}px`;\n  }\n\n  hide() {\n    if (this._isTransitioning || !this._isShown()) {\n      return;\n    }\n\n    const startEvent = EventHandler.trigger(this._element, EVENT_HIDE$5);\n\n    if (startEvent.defaultPrevented) {\n      return;\n    }\n\n    const dimension = this._getDimension();\n\n    this._element.style[dimension] = `${this._element.getBoundingClientRect()[dimension]}px`;\n    reflow(this._element);\n\n    this._element.classList.add(CLASS_NAME_COLLAPSING);\n\n    this._element.classList.remove(CLASS_NAME_COLLAPSE, CLASS_NAME_SHOW$7);\n\n    const triggerArrayLength = this._triggerArray.length;\n\n    for (let i = 0; i < triggerArrayLength; i++) {\n      const trigger = this._triggerArray[i];\n      const elem = getElementFromSelector(trigger);\n\n      if (elem && !this._isShown(elem)) {\n        this._addAriaAndCollapsedClass([trigger], false);\n      }\n    }\n\n    this._isTransitioning = true;\n\n    const complete = () => {\n      this._isTransitioning = false;\n\n      this._element.classList.remove(CLASS_NAME_COLLAPSING);\n\n      this._element.classList.add(CLASS_NAME_COLLAPSE);\n\n      EventHandler.trigger(this._element, EVENT_HIDDEN$5);\n    };\n\n    this._element.style[dimension] = '';\n\n    this._queueCallback(complete, this._element, true);\n  }\n\n  _isShown(element = this._element) {\n    return element.classList.contains(CLASS_NAME_SHOW$7);\n  } // Private\n\n\n  _getConfig(config) {\n    config = { ...Default$9,\n      ...Manipulator.getDataAttributes(this._element),\n      ...config\n    };\n    config.toggle = Boolean(config.toggle); // Coerce string values\n\n    config.parent = getElement(config.parent);\n    typeCheckConfig(NAME$a, config, DefaultType$9);\n    return config;\n  }\n\n  _getDimension() {\n    return this._element.classList.contains(CLASS_NAME_HORIZONTAL) ? WIDTH : HEIGHT;\n  }\n\n  _initializeChildren() {\n    if (!this._config.parent) {\n      return;\n    }\n\n    const children = SelectorEngine.find(`.${CLASS_NAME_COLLAPSE} .${CLASS_NAME_COLLAPSE}`, this._config.parent);\n    SelectorEngine.find(SELECTOR_DATA_TOGGLE$4, this._config.parent).filter(elem => !children.includes(elem)).forEach(element => {\n      const selected = getElementFromSelector(element);\n\n      if (selected) {\n        this._addAriaAndCollapsedClass([element], this._isShown(selected));\n      }\n    });\n  }\n\n  _addAriaAndCollapsedClass(triggerArray, isOpen) {\n    if (!triggerArray.length) {\n      return;\n    }\n\n    triggerArray.forEach(elem => {\n      if (isOpen) {\n        elem.classList.remove(CLASS_NAME_COLLAPSED);\n      } else {\n        elem.classList.add(CLASS_NAME_COLLAPSED);\n      }\n\n      elem.setAttribute('aria-expanded', isOpen);\n    });\n  } // Static\n\n\n  static jQueryInterface(config) {\n    return this.each(function () {\n      const _config = {};\n\n      if (typeof config === 'string' && /show|hide/.test(config)) {\n        _config.toggle = false;\n      }\n\n      const data = Collapse.getOrCreateInstance(this, _config);\n\n      if (typeof config === 'string') {\n        if (typeof data[config] === 'undefined') {\n          throw new TypeError(`No method named \"${config}\"`);\n        }\n\n        data[config]();\n      }\n    });\n  }\n\n}\n/**\n * ------------------------------------------------------------------------\n * Data Api implementation\n * ------------------------------------------------------------------------\n */\n\n\nEventHandler.on(document, EVENT_CLICK_DATA_API$4, SELECTOR_DATA_TOGGLE$4, function (event) {\n  // preventDefault only for <a> elements (which change the URL) not inside the collapsible element\n  if (event.target.tagName === 'A' || event.delegateTarget && event.delegateTarget.tagName === 'A') {\n    event.preventDefault();\n  }\n\n  const selector = getSelectorFromElement(this);\n  const selectorElements = SelectorEngine.find(selector);\n  selectorElements.forEach(element => {\n    Collapse.getOrCreateInstance(element, {\n      toggle: false\n    }).toggle();\n  });\n});\n/**\n * ------------------------------------------------------------------------\n * jQuery\n * ------------------------------------------------------------------------\n * add .Collapse to jQuery only if jQuery is present\n */\n\ndefineJQueryPlugin(Collapse);\n\n/**\n * --------------------------------------------------------------------------\n * Bootstrap (v5.1.0): dropdown.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n/**\n * ------------------------------------------------------------------------\n * Constants\n * ------------------------------------------------------------------------\n */\n\nconst NAME$9 = 'dropdown';\nconst DATA_KEY$8 = 'bs.dropdown';\nconst EVENT_KEY$8 = `.${DATA_KEY$8}`;\nconst DATA_API_KEY$4 = '.data-api';\nconst ESCAPE_KEY$2 = 'Escape';\nconst SPACE_KEY = 'Space';\nconst TAB_KEY$1 = 'Tab';\nconst ARROW_UP_KEY = 'ArrowUp';\nconst ARROW_DOWN_KEY = 'ArrowDown';\nconst RIGHT_MOUSE_BUTTON = 2; // MouseEvent.button value for the secondary button, usually the right button\n\nconst REGEXP_KEYDOWN = new RegExp(`${ARROW_UP_KEY}|${ARROW_DOWN_KEY}|${ESCAPE_KEY$2}`);\nconst EVENT_HIDE$4 = `hide${EVENT_KEY$8}`;\nconst EVENT_HIDDEN$4 = `hidden${EVENT_KEY$8}`;\nconst EVENT_SHOW$4 = `show${EVENT_KEY$8}`;\nconst EVENT_SHOWN$4 = `shown${EVENT_KEY$8}`;\nconst EVENT_CLICK_DATA_API$3 = `click${EVENT_KEY$8}${DATA_API_KEY$4}`;\nconst EVENT_KEYDOWN_DATA_API = `keydown${EVENT_KEY$8}${DATA_API_KEY$4}`;\nconst EVENT_KEYUP_DATA_API = `keyup${EVENT_KEY$8}${DATA_API_KEY$4}`;\nconst CLASS_NAME_SHOW$6 = 'show';\nconst CLASS_NAME_DROPUP = 'dropup';\nconst CLASS_NAME_DROPEND = 'dropend';\nconst CLASS_NAME_DROPSTART = 'dropstart';\nconst CLASS_NAME_NAVBAR = 'navbar';\nconst SELECTOR_DATA_TOGGLE$3 = '[data-bs-toggle=\"dropdown\"]';\nconst SELECTOR_MENU = '.dropdown-menu';\nconst SELECTOR_NAVBAR_NAV = '.navbar-nav';\nconst SELECTOR_VISIBLE_ITEMS = '.dropdown-menu .dropdown-item:not(.disabled):not(:disabled)';\nconst PLACEMENT_TOP = isRTL() ? 'top-end' : 'top-start';\nconst PLACEMENT_TOPEND = isRTL() ? 'top-start' : 'top-end';\nconst PLACEMENT_BOTTOM = isRTL() ? 'bottom-end' : 'bottom-start';\nconst PLACEMENT_BOTTOMEND = isRTL() ? 'bottom-start' : 'bottom-end';\nconst PLACEMENT_RIGHT = isRTL() ? 'left-start' : 'right-start';\nconst PLACEMENT_LEFT = isRTL() ? 'right-start' : 'left-start';\nconst Default$8 = {\n  offset: [0, 2],\n  boundary: 'clippingParents',\n  reference: 'toggle',\n  display: 'dynamic',\n  popperConfig: null,\n  autoClose: true\n};\nconst DefaultType$8 = {\n  offset: '(array|string|function)',\n  boundary: '(string|element)',\n  reference: '(string|element|object)',\n  display: 'string',\n  popperConfig: '(null|object|function)',\n  autoClose: '(boolean|string)'\n};\n/**\n * ------------------------------------------------------------------------\n * Class Definition\n * ------------------------------------------------------------------------\n */\n\nclass Dropdown extends BaseComponent {\n  constructor(element, config) {\n    super(element);\n    this._popper = null;\n    this._config = this._getConfig(config);\n    this._menu = this._getMenuElement();\n    this._inNavbar = this._detectNavbar();\n  } // Getters\n\n\n  static get Default() {\n    return Default$8;\n  }\n\n  static get DefaultType() {\n    return DefaultType$8;\n  }\n\n  static get NAME() {\n    return NAME$9;\n  } // Public\n\n\n  toggle() {\n    return this._isShown() ? this.hide() : this.show();\n  }\n\n  show() {\n    if (isDisabled(this._element) || this._isShown(this._menu)) {\n      return;\n    }\n\n    const relatedTarget = {\n      relatedTarget: this._element\n    };\n    const showEvent = EventHandler.trigger(this._element, EVENT_SHOW$4, relatedTarget);\n\n    if (showEvent.defaultPrevented) {\n      return;\n    }\n\n    const parent = Dropdown.getParentFromElement(this._element); // Totally disable Popper for Dropdowns in Navbar\n\n    if (this._inNavbar) {\n      Manipulator.setDataAttribute(this._menu, 'popper', 'none');\n    } else {\n      this._createPopper(parent);\n    } // If this is a touch-enabled device we add extra\n    // empty mouseover listeners to the body's immediate children;\n    // only needed because of broken event delegation on iOS\n    // https://www.quirksmode.org/blog/archives/2014/02/mouse_event_bub.html\n\n\n    if ('ontouchstart' in document.documentElement && !parent.closest(SELECTOR_NAVBAR_NAV)) {\n      [].concat(...document.body.children).forEach(elem => EventHandler.on(elem, 'mouseover', noop));\n    }\n\n    this._element.focus();\n\n    this._element.setAttribute('aria-expanded', true);\n\n    this._menu.classList.add(CLASS_NAME_SHOW$6);\n\n    this._element.classList.add(CLASS_NAME_SHOW$6);\n\n    EventHandler.trigger(this._element, EVENT_SHOWN$4, relatedTarget);\n  }\n\n  hide() {\n    if (isDisabled(this._element) || !this._isShown(this._menu)) {\n      return;\n    }\n\n    const relatedTarget = {\n      relatedTarget: this._element\n    };\n\n    this._completeHide(relatedTarget);\n  }\n\n  dispose() {\n    if (this._popper) {\n      this._popper.destroy();\n    }\n\n    super.dispose();\n  }\n\n  update() {\n    this._inNavbar = this._detectNavbar();\n\n    if (this._popper) {\n      this._popper.update();\n    }\n  } // Private\n\n\n  _completeHide(relatedTarget) {\n    const hideEvent = EventHandler.trigger(this._element, EVENT_HIDE$4, relatedTarget);\n\n    if (hideEvent.defaultPrevented) {\n      return;\n    } // If this is a touch-enabled device we remove the extra\n    // empty mouseover listeners we added for iOS support\n\n\n    if ('ontouchstart' in document.documentElement) {\n      [].concat(...document.body.children).forEach(elem => EventHandler.off(elem, 'mouseover', noop));\n    }\n\n    if (this._popper) {\n      this._popper.destroy();\n    }\n\n    this._menu.classList.remove(CLASS_NAME_SHOW$6);\n\n    this._element.classList.remove(CLASS_NAME_SHOW$6);\n\n    this._element.setAttribute('aria-expanded', 'false');\n\n    Manipulator.removeDataAttribute(this._menu, 'popper');\n    EventHandler.trigger(this._element, EVENT_HIDDEN$4, relatedTarget);\n  }\n\n  _getConfig(config) {\n    config = { ...this.constructor.Default,\n      ...Manipulator.getDataAttributes(this._element),\n      ...config\n    };\n    typeCheckConfig(NAME$9, config, this.constructor.DefaultType);\n\n    if (typeof config.reference === 'object' && !isElement(config.reference) && typeof config.reference.getBoundingClientRect !== 'function') {\n      // Popper virtual elements require a getBoundingClientRect method\n      throw new TypeError(`${NAME$9.toUpperCase()}: Option \"reference\" provided type \"object\" without a required \"getBoundingClientRect\" method.`);\n    }\n\n    return config;\n  }\n\n  _createPopper(parent) {\n    if (typeof Popper === 'undefined') {\n      throw new TypeError('Bootstrap\\'s dropdowns require Popper (https://popper.js.org)');\n    }\n\n    let referenceElement = this._element;\n\n    if (this._config.reference === 'parent') {\n      referenceElement = parent;\n    } else if (isElement(this._config.reference)) {\n      referenceElement = getElement(this._config.reference);\n    } else if (typeof this._config.reference === 'object') {\n      referenceElement = this._config.reference;\n    }\n\n    const popperConfig = this._getPopperConfig();\n\n    const isDisplayStatic = popperConfig.modifiers.find(modifier => modifier.name === 'applyStyles' && modifier.enabled === false);\n    this._popper = Popper.createPopper(referenceElement, this._menu, popperConfig);\n\n    if (isDisplayStatic) {\n      Manipulator.setDataAttribute(this._menu, 'popper', 'static');\n    }\n  }\n\n  _isShown(element = this._element) {\n    return element.classList.contains(CLASS_NAME_SHOW$6);\n  }\n\n  _getMenuElement() {\n    return SelectorEngine.next(this._element, SELECTOR_MENU)[0];\n  }\n\n  _getPlacement() {\n    const parentDropdown = this._element.parentNode;\n\n    if (parentDropdown.classList.contains(CLASS_NAME_DROPEND)) {\n      return PLACEMENT_RIGHT;\n    }\n\n    if (parentDropdown.classList.contains(CLASS_NAME_DROPSTART)) {\n      return PLACEMENT_LEFT;\n    } // We need to trim the value because custom properties can also include spaces\n\n\n    const isEnd = getComputedStyle(this._menu).getPropertyValue('--bs-position').trim() === 'end';\n\n    if (parentDropdown.classList.contains(CLASS_NAME_DROPUP)) {\n      return isEnd ? PLACEMENT_TOPEND : PLACEMENT_TOP;\n    }\n\n    return isEnd ? PLACEMENT_BOTTOMEND : PLACEMENT_BOTTOM;\n  }\n\n  _detectNavbar() {\n    return this._element.closest(`.${CLASS_NAME_NAVBAR}`) !== null;\n  }\n\n  _getOffset() {\n    const {\n      offset\n    } = this._config;\n\n    if (typeof offset === 'string') {\n      return offset.split(',').map(val => Number.parseInt(val, 10));\n    }\n\n    if (typeof offset === 'function') {\n      return popperData => offset(popperData, this._element);\n    }\n\n    return offset;\n  }\n\n  _getPopperConfig() {\n    const defaultBsPopperConfig = {\n      placement: this._getPlacement(),\n      modifiers: [{\n        name: 'preventOverflow',\n        options: {\n          boundary: this._config.boundary\n        }\n      }, {\n        name: 'offset',\n        options: {\n          offset: this._getOffset()\n        }\n      }]\n    }; // Disable Popper if we have a static display\n\n    if (this._config.display === 'static') {\n      defaultBsPopperConfig.modifiers = [{\n        name: 'applyStyles',\n        enabled: false\n      }];\n    }\n\n    return { ...defaultBsPopperConfig,\n      ...(typeof this._config.popperConfig === 'function' ? this._config.popperConfig(defaultBsPopperConfig) : this._config.popperConfig)\n    };\n  }\n\n  _selectMenuItem({\n    key,\n    target\n  }) {\n    const items = SelectorEngine.find(SELECTOR_VISIBLE_ITEMS, this._menu).filter(isVisible);\n\n    if (!items.length) {\n      return;\n    } // if target isn't included in items (e.g. when expanding the dropdown)\n    // allow cycling to get the last item in case key equals ARROW_UP_KEY\n\n\n    getNextActiveElement(items, target, key === ARROW_DOWN_KEY, !items.includes(target)).focus();\n  } // Static\n\n\n  static jQueryInterface(config) {\n    return this.each(function () {\n      const data = Dropdown.getOrCreateInstance(this, config);\n\n      if (typeof config !== 'string') {\n        return;\n      }\n\n      if (typeof data[config] === 'undefined') {\n        throw new TypeError(`No method named \"${config}\"`);\n      }\n\n      data[config]();\n    });\n  }\n\n  static clearMenus(event) {\n    if (event && (event.button === RIGHT_MOUSE_BUTTON || event.type === 'keyup' && event.key !== TAB_KEY$1)) {\n      return;\n    }\n\n    const toggles = SelectorEngine.find(SELECTOR_DATA_TOGGLE$3);\n\n    for (let i = 0, len = toggles.length; i < len; i++) {\n      const context = Dropdown.getInstance(toggles[i]);\n\n      if (!context || context._config.autoClose === false) {\n        continue;\n      }\n\n      if (!context._isShown()) {\n        continue;\n      }\n\n      const relatedTarget = {\n        relatedTarget: context._element\n      };\n\n      if (event) {\n        const composedPath = event.composedPath();\n        const isMenuTarget = composedPath.includes(context._menu);\n\n        if (composedPath.includes(context._element) || context._config.autoClose === 'inside' && !isMenuTarget || context._config.autoClose === 'outside' && isMenuTarget) {\n          continue;\n        } // Tab navigation through the dropdown menu or events from contained inputs shouldn't close the menu\n\n\n        if (context._menu.contains(event.target) && (event.type === 'keyup' && event.key === TAB_KEY$1 || /input|select|option|textarea|form/i.test(event.target.tagName))) {\n          continue;\n        }\n\n        if (event.type === 'click') {\n          relatedTarget.clickEvent = event;\n        }\n      }\n\n      context._completeHide(relatedTarget);\n    }\n  }\n\n  static getParentFromElement(element) {\n    return getElementFromSelector(element) || element.parentNode;\n  }\n\n  static dataApiKeydownHandler(event) {\n    // If not input/textarea:\n    //  - And not a key in REGEXP_KEYDOWN => not a dropdown command\n    // If input/textarea:\n    //  - If space key => not a dropdown command\n    //  - If key is other than escape\n    //    - If key is not up or down => not a dropdown command\n    //    - If trigger inside the menu => not a dropdown command\n    if (/input|textarea/i.test(event.target.tagName) ? event.key === SPACE_KEY || event.key !== ESCAPE_KEY$2 && (event.key !== ARROW_DOWN_KEY && event.key !== ARROW_UP_KEY || event.target.closest(SELECTOR_MENU)) : !REGEXP_KEYDOWN.test(event.key)) {\n      return;\n    }\n\n    const isActive = this.classList.contains(CLASS_NAME_SHOW$6);\n\n    if (!isActive && event.key === ESCAPE_KEY$2) {\n      return;\n    }\n\n    event.preventDefault();\n    event.stopPropagation();\n\n    if (isDisabled(this)) {\n      return;\n    }\n\n    const getToggleButton = this.matches(SELECTOR_DATA_TOGGLE$3) ? this : SelectorEngine.prev(this, SELECTOR_DATA_TOGGLE$3)[0];\n    const instance = Dropdown.getOrCreateInstance(getToggleButton);\n\n    if (event.key === ESCAPE_KEY$2) {\n      instance.hide();\n      return;\n    }\n\n    if (event.key === ARROW_UP_KEY || event.key === ARROW_DOWN_KEY) {\n      if (!isActive) {\n        instance.show();\n      }\n\n      instance._selectMenuItem(event);\n\n      return;\n    }\n\n    if (!isActive || event.key === SPACE_KEY) {\n      Dropdown.clearMenus();\n    }\n  }\n\n}\n/**\n * ------------------------------------------------------------------------\n * Data Api implementation\n * ------------------------------------------------------------------------\n */\n\n\nEventHandler.on(document, EVENT_KEYDOWN_DATA_API, SELECTOR_DATA_TOGGLE$3, Dropdown.dataApiKeydownHandler);\nEventHandler.on(document, EVENT_KEYDOWN_DATA_API, SELECTOR_MENU, Dropdown.dataApiKeydownHandler);\nEventHandler.on(document, EVENT_CLICK_DATA_API$3, Dropdown.clearMenus);\nEventHandler.on(document, EVENT_KEYUP_DATA_API, Dropdown.clearMenus);\nEventHandler.on(document, EVENT_CLICK_DATA_API$3, SELECTOR_DATA_TOGGLE$3, function (event) {\n  event.preventDefault();\n  Dropdown.getOrCreateInstance(this).toggle();\n});\n/**\n * ------------------------------------------------------------------------\n * jQuery\n * ------------------------------------------------------------------------\n * add .Dropdown to jQuery only if jQuery is present\n */\n\ndefineJQueryPlugin(Dropdown);\n\n/**\n * --------------------------------------------------------------------------\n * Bootstrap (v5.1.0): util/scrollBar.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\nconst SELECTOR_FIXED_CONTENT = '.fixed-top, .fixed-bottom, .is-fixed, .sticky-top';\nconst SELECTOR_STICKY_CONTENT = '.sticky-top';\n\nclass ScrollBarHelper {\n  constructor() {\n    this._element = document.body;\n  }\n\n  getWidth() {\n    // https://developer.mozilla.org/en-US/docs/Web/API/Window/innerWidth#usage_notes\n    const documentWidth = document.documentElement.clientWidth;\n    return Math.abs(window.innerWidth - documentWidth);\n  }\n\n  hide() {\n    const width = this.getWidth();\n\n    this._disableOverFlow(); // give padding to element to balance the hidden scrollbar width\n\n\n    this._setElementAttributes(this._element, 'paddingRight', calculatedValue => calculatedValue + width); // trick: We adjust positive paddingRight and negative marginRight to sticky-top elements to keep showing fullwidth\n\n\n    this._setElementAttributes(SELECTOR_FIXED_CONTENT, 'paddingRight', calculatedValue => calculatedValue + width);\n\n    this._setElementAttributes(SELECTOR_STICKY_CONTENT, 'marginRight', calculatedValue => calculatedValue - width);\n  }\n\n  _disableOverFlow() {\n    this._saveInitialAttribute(this._element, 'overflow');\n\n    this._element.style.overflow = 'hidden';\n  }\n\n  _setElementAttributes(selector, styleProp, callback) {\n    const scrollbarWidth = this.getWidth();\n\n    const manipulationCallBack = element => {\n      if (element !== this._element && window.innerWidth > element.clientWidth + scrollbarWidth) {\n        return;\n      }\n\n      this._saveInitialAttribute(element, styleProp);\n\n      const calculatedValue = window.getComputedStyle(element)[styleProp];\n      element.style[styleProp] = `${callback(Number.parseFloat(calculatedValue))}px`;\n    };\n\n    this._applyManipulationCallback(selector, manipulationCallBack);\n  }\n\n  reset() {\n    this._resetElementAttributes(this._element, 'overflow');\n\n    this._resetElementAttributes(this._element, 'paddingRight');\n\n    this._resetElementAttributes(SELECTOR_FIXED_CONTENT, 'paddingRight');\n\n    this._resetElementAttributes(SELECTOR_STICKY_CONTENT, 'marginRight');\n  }\n\n  _saveInitialAttribute(element, styleProp) {\n    const actualValue = element.style[styleProp];\n\n    if (actualValue) {\n      Manipulator.setDataAttribute(element, styleProp, actualValue);\n    }\n  }\n\n  _resetElementAttributes(selector, styleProp) {\n    const manipulationCallBack = element => {\n      const value = Manipulator.getDataAttribute(element, styleProp);\n\n      if (typeof value === 'undefined') {\n        element.style.removeProperty(styleProp);\n      } else {\n        Manipulator.removeDataAttribute(element, styleProp);\n        element.style[styleProp] = value;\n      }\n    };\n\n    this._applyManipulationCallback(selector, manipulationCallBack);\n  }\n\n  _applyManipulationCallback(selector, callBack) {\n    if (isElement(selector)) {\n      callBack(selector);\n    } else {\n      SelectorEngine.find(selector, this._element).forEach(callBack);\n    }\n  }\n\n  isOverflowing() {\n    return this.getWidth() > 0;\n  }\n\n}\n\n/**\n * --------------------------------------------------------------------------\n * Bootstrap (v5.1.0): util/backdrop.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n * --------------------------------------------------------------------------\n */\nconst Default$7 = {\n  className: 'modal-backdrop',\n  isVisible: true,\n  // if false, we use the backdrop helper without adding any element to the dom\n  isAnimated: false,\n  rootElement: 'body',\n  // give the choice to place backdrop under different elements\n  clickCallback: null\n};\nconst DefaultType$7 = {\n  className: 'string',\n  isVisible: 'boolean',\n  isAnimated: 'boolean',\n  rootElement: '(element|string)',\n  clickCallback: '(function|null)'\n};\nconst NAME$8 = 'backdrop';\nconst CLASS_NAME_FADE$4 = 'fade';\nconst CLASS_NAME_SHOW$5 = 'show';\nconst EVENT_MOUSEDOWN = `mousedown.bs.${NAME$8}`;\n\nclass Backdrop {\n  constructor(config) {\n    this._config = this._getConfig(config);\n    this._isAppended = false;\n    this._element = null;\n  }\n\n  show(callback) {\n    if (!this._config.isVisible) {\n      execute(callback);\n      return;\n    }\n\n    this._append();\n\n    if (this._config.isAnimated) {\n      reflow(this._getElement());\n    }\n\n    this._getElement().classList.add(CLASS_NAME_SHOW$5);\n\n    this._emulateAnimation(() => {\n      execute(callback);\n    });\n  }\n\n  hide(callback) {\n    if (!this._config.isVisible) {\n      execute(callback);\n      return;\n    }\n\n    this._getElement().classList.remove(CLASS_NAME_SHOW$5);\n\n    this._emulateAnimation(() => {\n      this.dispose();\n      execute(callback);\n    });\n  } // Private\n\n\n  _getElement() {\n    if (!this._element) {\n      const backdrop = document.createElement('div');\n      backdrop.className = this._config.className;\n\n      if (this._config.isAnimated) {\n        backdrop.classList.add(CLASS_NAME_FADE$4);\n      }\n\n      this._element = backdrop;\n    }\n\n    return this._element;\n  }\n\n  _getConfig(config) {\n    config = { ...Default$7,\n      ...(typeof config === 'object' ? config : {})\n    }; // use getElement() with the default \"body\" to get a fresh Element on each instantiation\n\n    config.rootElement = getElement(config.rootElement);\n    typeCheckConfig(NAME$8, config, DefaultType$7);\n    return config;\n  }\n\n  _append() {\n    if (this._isAppended) {\n      return;\n    }\n\n    this._config.rootElement.append(this._getElement());\n\n    EventHandler.on(this._getElement(), EVENT_MOUSEDOWN, () => {\n      execute(this._config.clickCallback);\n    });\n    this._isAppended = true;\n  }\n\n  dispose() {\n    if (!this._isAppended) {\n      return;\n    }\n\n    EventHandler.off(this._element, EVENT_MOUSEDOWN);\n\n    this._element.remove();\n\n    this._isAppended = false;\n  }\n\n  _emulateAnimation(callback) {\n    executeAfterTransition(callback, this._getElement(), this._config.isAnimated);\n  }\n\n}\n\n/**\n * --------------------------------------------------------------------------\n * Bootstrap (v5.1.0): util/focustrap.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n * --------------------------------------------------------------------------\n */\nconst Default$6 = {\n  trapElement: null,\n  // The element to trap focus inside of\n  autofocus: true\n};\nconst DefaultType$6 = {\n  trapElement: 'element',\n  autofocus: 'boolean'\n};\nconst NAME$7 = 'focustrap';\nconst DATA_KEY$7 = 'bs.focustrap';\nconst EVENT_KEY$7 = `.${DATA_KEY$7}`;\nconst EVENT_FOCUSIN$1 = `focusin${EVENT_KEY$7}`;\nconst EVENT_KEYDOWN_TAB = `keydown.tab${EVENT_KEY$7}`;\nconst TAB_KEY = 'Tab';\nconst TAB_NAV_FORWARD = 'forward';\nconst TAB_NAV_BACKWARD = 'backward';\n\nclass FocusTrap {\n  constructor(config) {\n    this._config = this._getConfig(config);\n    this._isActive = false;\n    this._lastTabNavDirection = null;\n  }\n\n  activate() {\n    const {\n      trapElement,\n      autofocus\n    } = this._config;\n\n    if (this._isActive) {\n      return;\n    }\n\n    if (autofocus) {\n      trapElement.focus();\n    }\n\n    EventHandler.off(document, EVENT_KEY$7); // guard against infinite focus loop\n\n    EventHandler.on(document, EVENT_FOCUSIN$1, event => this._handleFocusin(event));\n    EventHandler.on(document, EVENT_KEYDOWN_TAB, event => this._handleKeydown(event));\n    this._isActive = true;\n  }\n\n  deactivate() {\n    if (!this._isActive) {\n      return;\n    }\n\n    this._isActive = false;\n    EventHandler.off(document, EVENT_KEY$7);\n  } // Private\n\n\n  _handleFocusin(event) {\n    const {\n      target\n    } = event;\n    const {\n      trapElement\n    } = this._config;\n\n    if (target === document || target === trapElement || trapElement.contains(target)) {\n      return;\n    }\n\n    const elements = SelectorEngine.focusableChildren(trapElement);\n\n    if (elements.length === 0) {\n      trapElement.focus();\n    } else if (this._lastTabNavDirection === TAB_NAV_BACKWARD) {\n      elements[elements.length - 1].focus();\n    } else {\n      elements[0].focus();\n    }\n  }\n\n  _handleKeydown(event) {\n    if (event.key !== TAB_KEY) {\n      return;\n    }\n\n    this._lastTabNavDirection = event.shiftKey ? TAB_NAV_BACKWARD : TAB_NAV_FORWARD;\n  }\n\n  _getConfig(config) {\n    config = { ...Default$6,\n      ...(typeof config === 'object' ? config : {})\n    };\n    typeCheckConfig(NAME$7, config, DefaultType$6);\n    return config;\n  }\n\n}\n\n/**\n * --------------------------------------------------------------------------\n * Bootstrap (v5.1.0): modal.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n/**\n * ------------------------------------------------------------------------\n * Constants\n * ------------------------------------------------------------------------\n */\n\nconst NAME$6 = 'modal';\nconst DATA_KEY$6 = 'bs.modal';\nconst EVENT_KEY$6 = `.${DATA_KEY$6}`;\nconst DATA_API_KEY$3 = '.data-api';\nconst ESCAPE_KEY$1 = 'Escape';\nconst Default$5 = {\n  backdrop: true,\n  keyboard: true,\n  focus: true\n};\nconst DefaultType$5 = {\n  backdrop: '(boolean|string)',\n  keyboard: 'boolean',\n  focus: 'boolean'\n};\nconst EVENT_HIDE$3 = `hide${EVENT_KEY$6}`;\nconst EVENT_HIDE_PREVENTED = `hidePrevented${EVENT_KEY$6}`;\nconst EVENT_HIDDEN$3 = `hidden${EVENT_KEY$6}`;\nconst EVENT_SHOW$3 = `show${EVENT_KEY$6}`;\nconst EVENT_SHOWN$3 = `shown${EVENT_KEY$6}`;\nconst EVENT_RESIZE = `resize${EVENT_KEY$6}`;\nconst EVENT_CLICK_DISMISS = `click.dismiss${EVENT_KEY$6}`;\nconst EVENT_KEYDOWN_DISMISS$1 = `keydown.dismiss${EVENT_KEY$6}`;\nconst EVENT_MOUSEUP_DISMISS = `mouseup.dismiss${EVENT_KEY$6}`;\nconst EVENT_MOUSEDOWN_DISMISS = `mousedown.dismiss${EVENT_KEY$6}`;\nconst EVENT_CLICK_DATA_API$2 = `click${EVENT_KEY$6}${DATA_API_KEY$3}`;\nconst CLASS_NAME_OPEN = 'modal-open';\nconst CLASS_NAME_FADE$3 = 'fade';\nconst CLASS_NAME_SHOW$4 = 'show';\nconst CLASS_NAME_STATIC = 'modal-static';\nconst SELECTOR_DIALOG = '.modal-dialog';\nconst SELECTOR_MODAL_BODY = '.modal-body';\nconst SELECTOR_DATA_TOGGLE$2 = '[data-bs-toggle=\"modal\"]';\n/**\n * ------------------------------------------------------------------------\n * Class Definition\n * ------------------------------------------------------------------------\n */\n\nclass Modal extends BaseComponent {\n  constructor(element, config) {\n    super(element);\n    this._config = this._getConfig(config);\n    this._dialog = SelectorEngine.findOne(SELECTOR_DIALOG, this._element);\n    this._backdrop = this._initializeBackDrop();\n    this._focustrap = this._initializeFocusTrap();\n    this._isShown = false;\n    this._ignoreBackdropClick = false;\n    this._isTransitioning = false;\n    this._scrollBar = new ScrollBarHelper();\n  } // Getters\n\n\n  static get Default() {\n    return Default$5;\n  }\n\n  static get NAME() {\n    return NAME$6;\n  } // Public\n\n\n  toggle(relatedTarget) {\n    return this._isShown ? this.hide() : this.show(relatedTarget);\n  }\n\n  show(relatedTarget) {\n    if (this._isShown || this._isTransitioning) {\n      return;\n    }\n\n    const showEvent = EventHandler.trigger(this._element, EVENT_SHOW$3, {\n      relatedTarget\n    });\n\n    if (showEvent.defaultPrevented) {\n      return;\n    }\n\n    this._isShown = true;\n\n    if (this._isAnimated()) {\n      this._isTransitioning = true;\n    }\n\n    this._scrollBar.hide();\n\n    document.body.classList.add(CLASS_NAME_OPEN);\n\n    this._adjustDialog();\n\n    this._setEscapeEvent();\n\n    this._setResizeEvent();\n\n    EventHandler.on(this._dialog, EVENT_MOUSEDOWN_DISMISS, () => {\n      EventHandler.one(this._element, EVENT_MOUSEUP_DISMISS, event => {\n        if (event.target === this._element) {\n          this._ignoreBackdropClick = true;\n        }\n      });\n    });\n\n    this._showBackdrop(() => this._showElement(relatedTarget));\n  }\n\n  hide() {\n    if (!this._isShown || this._isTransitioning) {\n      return;\n    }\n\n    const hideEvent = EventHandler.trigger(this._element, EVENT_HIDE$3);\n\n    if (hideEvent.defaultPrevented) {\n      return;\n    }\n\n    this._isShown = false;\n\n    const isAnimated = this._isAnimated();\n\n    if (isAnimated) {\n      this._isTransitioning = true;\n    }\n\n    this._setEscapeEvent();\n\n    this._setResizeEvent();\n\n    this._focustrap.deactivate();\n\n    this._element.classList.remove(CLASS_NAME_SHOW$4);\n\n    EventHandler.off(this._element, EVENT_CLICK_DISMISS);\n    EventHandler.off(this._dialog, EVENT_MOUSEDOWN_DISMISS);\n\n    this._queueCallback(() => this._hideModal(), this._element, isAnimated);\n  }\n\n  dispose() {\n    [window, this._dialog].forEach(htmlElement => EventHandler.off(htmlElement, EVENT_KEY$6));\n\n    this._backdrop.dispose();\n\n    this._focustrap.deactivate();\n\n    super.dispose();\n  }\n\n  handleUpdate() {\n    this._adjustDialog();\n  } // Private\n\n\n  _initializeBackDrop() {\n    return new Backdrop({\n      isVisible: Boolean(this._config.backdrop),\n      // 'static' option will be translated to true, and booleans will keep their value\n      isAnimated: this._isAnimated()\n    });\n  }\n\n  _initializeFocusTrap() {\n    return new FocusTrap({\n      trapElement: this._element\n    });\n  }\n\n  _getConfig(config) {\n    config = { ...Default$5,\n      ...Manipulator.getDataAttributes(this._element),\n      ...(typeof config === 'object' ? config : {})\n    };\n    typeCheckConfig(NAME$6, config, DefaultType$5);\n    return config;\n  }\n\n  _showElement(relatedTarget) {\n    const isAnimated = this._isAnimated();\n\n    const modalBody = SelectorEngine.findOne(SELECTOR_MODAL_BODY, this._dialog);\n\n    if (!this._element.parentNode || this._element.parentNode.nodeType !== Node.ELEMENT_NODE) {\n      // Don't move modal's DOM position\n      document.body.append(this._element);\n    }\n\n    this._element.style.display = 'block';\n\n    this._element.removeAttribute('aria-hidden');\n\n    this._element.setAttribute('aria-modal', true);\n\n    this._element.setAttribute('role', 'dialog');\n\n    this._element.scrollTop = 0;\n\n    if (modalBody) {\n      modalBody.scrollTop = 0;\n    }\n\n    if (isAnimated) {\n      reflow(this._element);\n    }\n\n    this._element.classList.add(CLASS_NAME_SHOW$4);\n\n    const transitionComplete = () => {\n      if (this._config.focus) {\n        this._focustrap.activate();\n      }\n\n      this._isTransitioning = false;\n      EventHandler.trigger(this._element, EVENT_SHOWN$3, {\n        relatedTarget\n      });\n    };\n\n    this._queueCallback(transitionComplete, this._dialog, isAnimated);\n  }\n\n  _setEscapeEvent() {\n    if (this._isShown) {\n      EventHandler.on(this._element, EVENT_KEYDOWN_DISMISS$1, event => {\n        if (this._config.keyboard && event.key === ESCAPE_KEY$1) {\n          event.preventDefault();\n          this.hide();\n        } else if (!this._config.keyboard && event.key === ESCAPE_KEY$1) {\n          this._triggerBackdropTransition();\n        }\n      });\n    } else {\n      EventHandler.off(this._element, EVENT_KEYDOWN_DISMISS$1);\n    }\n  }\n\n  _setResizeEvent() {\n    if (this._isShown) {\n      EventHandler.on(window, EVENT_RESIZE, () => this._adjustDialog());\n    } else {\n      EventHandler.off(window, EVENT_RESIZE);\n    }\n  }\n\n  _hideModal() {\n    this._element.style.display = 'none';\n\n    this._element.setAttribute('aria-hidden', true);\n\n    this._element.removeAttribute('aria-modal');\n\n    this._element.removeAttribute('role');\n\n    this._isTransitioning = false;\n\n    this._backdrop.hide(() => {\n      document.body.classList.remove(CLASS_NAME_OPEN);\n\n      this._resetAdjustments();\n\n      this._scrollBar.reset();\n\n      EventHandler.trigger(this._element, EVENT_HIDDEN$3);\n    });\n  }\n\n  _showBackdrop(callback) {\n    EventHandler.on(this._element, EVENT_CLICK_DISMISS, event => {\n      if (this._ignoreBackdropClick) {\n        this._ignoreBackdropClick = false;\n        return;\n      }\n\n      if (event.target !== event.currentTarget) {\n        return;\n      }\n\n      if (this._config.backdrop === true) {\n        this.hide();\n      } else if (this._config.backdrop === 'static') {\n        this._triggerBackdropTransition();\n      }\n    });\n\n    this._backdrop.show(callback);\n  }\n\n  _isAnimated() {\n    return this._element.classList.contains(CLASS_NAME_FADE$3);\n  }\n\n  _triggerBackdropTransition() {\n    const hideEvent = EventHandler.trigger(this._element, EVENT_HIDE_PREVENTED);\n\n    if (hideEvent.defaultPrevented) {\n      return;\n    }\n\n    const {\n      classList,\n      scrollHeight,\n      style\n    } = this._element;\n    const isModalOverflowing = scrollHeight > document.documentElement.clientHeight; // return if the following background transition hasn't yet completed\n\n    if (!isModalOverflowing && style.overflowY === 'hidden' || classList.contains(CLASS_NAME_STATIC)) {\n      return;\n    }\n\n    if (!isModalOverflowing) {\n      style.overflowY = 'hidden';\n    }\n\n    classList.add(CLASS_NAME_STATIC);\n\n    this._queueCallback(() => {\n      classList.remove(CLASS_NAME_STATIC);\n\n      if (!isModalOverflowing) {\n        this._queueCallback(() => {\n          style.overflowY = '';\n        }, this._dialog);\n      }\n    }, this._dialog);\n\n    this._element.focus();\n  } // ----------------------------------------------------------------------\n  // the following methods are used to handle overflowing modals\n  // ----------------------------------------------------------------------\n\n\n  _adjustDialog() {\n    const isModalOverflowing = this._element.scrollHeight > document.documentElement.clientHeight;\n\n    const scrollbarWidth = this._scrollBar.getWidth();\n\n    const isBodyOverflowing = scrollbarWidth > 0;\n\n    if (!isBodyOverflowing && isModalOverflowing && !isRTL() || isBodyOverflowing && !isModalOverflowing && isRTL()) {\n      this._element.style.paddingLeft = `${scrollbarWidth}px`;\n    }\n\n    if (isBodyOverflowing && !isModalOverflowing && !isRTL() || !isBodyOverflowing && isModalOverflowing && isRTL()) {\n      this._element.style.paddingRight = `${scrollbarWidth}px`;\n    }\n  }\n\n  _resetAdjustments() {\n    this._element.style.paddingLeft = '';\n    this._element.style.paddingRight = '';\n  } // Static\n\n\n  static jQueryInterface(config, relatedTarget) {\n    return this.each(function () {\n      const data = Modal.getOrCreateInstance(this, config);\n\n      if (typeof config !== 'string') {\n        return;\n      }\n\n      if (typeof data[config] === 'undefined') {\n        throw new TypeError(`No method named \"${config}\"`);\n      }\n\n      data[config](relatedTarget);\n    });\n  }\n\n}\n/**\n * ------------------------------------------------------------------------\n * Data Api implementation\n * ------------------------------------------------------------------------\n */\n\n\nEventHandler.on(document, EVENT_CLICK_DATA_API$2, SELECTOR_DATA_TOGGLE$2, function (event) {\n  const target = getElementFromSelector(this);\n\n  if (['A', 'AREA'].includes(this.tagName)) {\n    event.preventDefault();\n  }\n\n  EventHandler.one(target, EVENT_SHOW$3, showEvent => {\n    if (showEvent.defaultPrevented) {\n      // only register focus restorer if modal will actually get shown\n      return;\n    }\n\n    EventHandler.one(target, EVENT_HIDDEN$3, () => {\n      if (isVisible(this)) {\n        this.focus();\n      }\n    });\n  });\n  const data = Modal.getOrCreateInstance(target);\n  data.toggle(this);\n});\nenableDismissTrigger(Modal);\n/**\n * ------------------------------------------------------------------------\n * jQuery\n * ------------------------------------------------------------------------\n * add .Modal to jQuery only if jQuery is present\n */\n\ndefineJQueryPlugin(Modal);\n\n/**\n * --------------------------------------------------------------------------\n * Bootstrap (v5.1.0): offcanvas.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n * --------------------------------------------------------------------------\n */\n/**\n * ------------------------------------------------------------------------\n * Constants\n * ------------------------------------------------------------------------\n */\n\nconst NAME$5 = 'offcanvas';\nconst DATA_KEY$5 = 'bs.offcanvas';\nconst EVENT_KEY$5 = `.${DATA_KEY$5}`;\nconst DATA_API_KEY$2 = '.data-api';\nconst EVENT_LOAD_DATA_API$1 = `load${EVENT_KEY$5}${DATA_API_KEY$2}`;\nconst ESCAPE_KEY = 'Escape';\nconst Default$4 = {\n  backdrop: true,\n  keyboard: true,\n  scroll: false\n};\nconst DefaultType$4 = {\n  backdrop: 'boolean',\n  keyboard: 'boolean',\n  scroll: 'boolean'\n};\nconst CLASS_NAME_SHOW$3 = 'show';\nconst CLASS_NAME_BACKDROP = 'offcanvas-backdrop';\nconst OPEN_SELECTOR = '.offcanvas.show';\nconst EVENT_SHOW$2 = `show${EVENT_KEY$5}`;\nconst EVENT_SHOWN$2 = `shown${EVENT_KEY$5}`;\nconst EVENT_HIDE$2 = `hide${EVENT_KEY$5}`;\nconst EVENT_HIDDEN$2 = `hidden${EVENT_KEY$5}`;\nconst EVENT_CLICK_DATA_API$1 = `click${EVENT_KEY$5}${DATA_API_KEY$2}`;\nconst EVENT_KEYDOWN_DISMISS = `keydown.dismiss${EVENT_KEY$5}`;\nconst SELECTOR_DATA_TOGGLE$1 = '[data-bs-toggle=\"offcanvas\"]';\n/**\n * ------------------------------------------------------------------------\n * Class Definition\n * ------------------------------------------------------------------------\n */\n\nclass Offcanvas extends BaseComponent {\n  constructor(element, config) {\n    super(element);\n    this._config = this._getConfig(config);\n    this._isShown = false;\n    this._backdrop = this._initializeBackDrop();\n    this._focustrap = this._initializeFocusTrap();\n\n    this._addEventListeners();\n  } // Getters\n\n\n  static get NAME() {\n    return NAME$5;\n  }\n\n  static get Default() {\n    return Default$4;\n  } // Public\n\n\n  toggle(relatedTarget) {\n    return this._isShown ? this.hide() : this.show(relatedTarget);\n  }\n\n  show(relatedTarget) {\n    if (this._isShown) {\n      return;\n    }\n\n    const showEvent = EventHandler.trigger(this._element, EVENT_SHOW$2, {\n      relatedTarget\n    });\n\n    if (showEvent.defaultPrevented) {\n      return;\n    }\n\n    this._isShown = true;\n    this._element.style.visibility = 'visible';\n\n    this._backdrop.show();\n\n    if (!this._config.scroll) {\n      new ScrollBarHelper().hide();\n    }\n\n    this._element.removeAttribute('aria-hidden');\n\n    this._element.setAttribute('aria-modal', true);\n\n    this._element.setAttribute('role', 'dialog');\n\n    this._element.classList.add(CLASS_NAME_SHOW$3);\n\n    const completeCallBack = () => {\n      if (!this._config.scroll) {\n        this._focustrap.activate();\n      }\n\n      EventHandler.trigger(this._element, EVENT_SHOWN$2, {\n        relatedTarget\n      });\n    };\n\n    this._queueCallback(completeCallBack, this._element, true);\n  }\n\n  hide() {\n    if (!this._isShown) {\n      return;\n    }\n\n    const hideEvent = EventHandler.trigger(this._element, EVENT_HIDE$2);\n\n    if (hideEvent.defaultPrevented) {\n      return;\n    }\n\n    this._focustrap.deactivate();\n\n    this._element.blur();\n\n    this._isShown = false;\n\n    this._element.classList.remove(CLASS_NAME_SHOW$3);\n\n    this._backdrop.hide();\n\n    const completeCallback = () => {\n      this._element.setAttribute('aria-hidden', true);\n\n      this._element.removeAttribute('aria-modal');\n\n      this._element.removeAttribute('role');\n\n      this._element.style.visibility = 'hidden';\n\n      if (!this._config.scroll) {\n        new ScrollBarHelper().reset();\n      }\n\n      EventHandler.trigger(this._element, EVENT_HIDDEN$2);\n    };\n\n    this._queueCallback(completeCallback, this._element, true);\n  }\n\n  dispose() {\n    this._backdrop.dispose();\n\n    this._focustrap.deactivate();\n\n    super.dispose();\n  } // Private\n\n\n  _getConfig(config) {\n    config = { ...Default$4,\n      ...Manipulator.getDataAttributes(this._element),\n      ...(typeof config === 'object' ? config : {})\n    };\n    typeCheckConfig(NAME$5, config, DefaultType$4);\n    return config;\n  }\n\n  _initializeBackDrop() {\n    return new Backdrop({\n      className: CLASS_NAME_BACKDROP,\n      isVisible: this._config.backdrop,\n      isAnimated: true,\n      rootElement: this._element.parentNode,\n      clickCallback: () => this.hide()\n    });\n  }\n\n  _initializeFocusTrap() {\n    return new FocusTrap({\n      trapElement: this._element\n    });\n  }\n\n  _addEventListeners() {\n    EventHandler.on(this._element, EVENT_KEYDOWN_DISMISS, event => {\n      if (this._config.keyboard && event.key === ESCAPE_KEY) {\n        this.hide();\n      }\n    });\n  } // Static\n\n\n  static jQueryInterface(config) {\n    return this.each(function () {\n      const data = Offcanvas.getOrCreateInstance(this, config);\n\n      if (typeof config !== 'string') {\n        return;\n      }\n\n      if (data[config] === undefined || config.startsWith('_') || config === 'constructor') {\n        throw new TypeError(`No method named \"${config}\"`);\n      }\n\n      data[config](this);\n    });\n  }\n\n}\n/**\n * ------------------------------------------------------------------------\n * Data Api implementation\n * ------------------------------------------------------------------------\n */\n\n\nEventHandler.on(document, EVENT_CLICK_DATA_API$1, SELECTOR_DATA_TOGGLE$1, function (event) {\n  const target = getElementFromSelector(this);\n\n  if (['A', 'AREA'].includes(this.tagName)) {\n    event.preventDefault();\n  }\n\n  if (isDisabled(this)) {\n    return;\n  }\n\n  EventHandler.one(target, EVENT_HIDDEN$2, () => {\n    // focus on trigger when it is closed\n    if (isVisible(this)) {\n      this.focus();\n    }\n  }); // avoid conflict when clicking a toggler of an offcanvas, while another is open\n\n  const allReadyOpen = SelectorEngine.findOne(OPEN_SELECTOR);\n\n  if (allReadyOpen && allReadyOpen !== target) {\n    Offcanvas.getInstance(allReadyOpen).hide();\n  }\n\n  const data = Offcanvas.getOrCreateInstance(target);\n  data.toggle(this);\n});\nEventHandler.on(window, EVENT_LOAD_DATA_API$1, () => SelectorEngine.find(OPEN_SELECTOR).forEach(el => Offcanvas.getOrCreateInstance(el).show()));\nenableDismissTrigger(Offcanvas);\n/**\n * ------------------------------------------------------------------------\n * jQuery\n * ------------------------------------------------------------------------\n */\n\ndefineJQueryPlugin(Offcanvas);\n\n/**\n * --------------------------------------------------------------------------\n * Bootstrap (v5.1.0): util/sanitizer.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\nconst uriAttrs = new Set(['background', 'cite', 'href', 'itemtype', 'longdesc', 'poster', 'src', 'xlink:href']);\nconst ARIA_ATTRIBUTE_PATTERN = /^aria-[\\w-]*$/i;\n/**\n * A pattern that recognizes a commonly useful subset of URLs that are safe.\n *\n * Shoutout to Angular 7 https://github.com/angular/angular/blob/7.2.4/packages/core/src/sanitization/url_sanitizer.ts\n */\n\nconst SAFE_URL_PATTERN = /^(?:(?:https?|mailto|ftp|tel|file):|[^#&/:?]*(?:[#/?]|$))/i;\n/**\n * A pattern that matches safe data URLs. Only matches image, video and audio types.\n *\n * Shoutout to Angular 7 https://github.com/angular/angular/blob/7.2.4/packages/core/src/sanitization/url_sanitizer.ts\n */\n\nconst DATA_URL_PATTERN = /^data:(?:image\\/(?:bmp|gif|jpeg|jpg|png|tiff|webp)|video\\/(?:mpeg|mp4|ogg|webm)|audio\\/(?:mp3|oga|ogg|opus));base64,[\\d+/a-z]+=*$/i;\n\nconst allowedAttribute = (attr, allowedAttributeList) => {\n  const attrName = attr.nodeName.toLowerCase();\n\n  if (allowedAttributeList.includes(attrName)) {\n    if (uriAttrs.has(attrName)) {\n      return Boolean(SAFE_URL_PATTERN.test(attr.nodeValue) || DATA_URL_PATTERN.test(attr.nodeValue));\n    }\n\n    return true;\n  }\n\n  const regExp = allowedAttributeList.filter(attrRegex => attrRegex instanceof RegExp); // Check if a regular expression validates the attribute.\n\n  for (let i = 0, len = regExp.length; i < len; i++) {\n    if (regExp[i].test(attrName)) {\n      return true;\n    }\n  }\n\n  return false;\n};\n\nconst DefaultAllowlist = {\n  // Global attributes allowed on any supplied element below.\n  '*': ['class', 'dir', 'id', 'lang', 'role', ARIA_ATTRIBUTE_PATTERN],\n  a: ['target', 'href', 'title', 'rel'],\n  area: [],\n  b: [],\n  br: [],\n  col: [],\n  code: [],\n  div: [],\n  em: [],\n  hr: [],\n  h1: [],\n  h2: [],\n  h3: [],\n  h4: [],\n  h5: [],\n  h6: [],\n  i: [],\n  img: ['src', 'srcset', 'alt', 'title', 'width', 'height'],\n  li: [],\n  ol: [],\n  p: [],\n  pre: [],\n  s: [],\n  small: [],\n  span: [],\n  sub: [],\n  sup: [],\n  strong: [],\n  u: [],\n  ul: []\n};\nfunction sanitizeHtml(unsafeHtml, allowList, sanitizeFn) {\n  if (!unsafeHtml.length) {\n    return unsafeHtml;\n  }\n\n  if (sanitizeFn && typeof sanitizeFn === 'function') {\n    return sanitizeFn(unsafeHtml);\n  }\n\n  const domParser = new window.DOMParser();\n  const createdDocument = domParser.parseFromString(unsafeHtml, 'text/html');\n  const allowlistKeys = Object.keys(allowList);\n  const elements = [].concat(...createdDocument.body.querySelectorAll('*'));\n\n  for (let i = 0, len = elements.length; i < len; i++) {\n    const el = elements[i];\n    const elName = el.nodeName.toLowerCase();\n\n    if (!allowlistKeys.includes(elName)) {\n      el.remove();\n      continue;\n    }\n\n    const attributeList = [].concat(...el.attributes);\n    const allowedAttributes = [].concat(allowList['*'] || [], allowList[elName] || []);\n    attributeList.forEach(attr => {\n      if (!allowedAttribute(attr, allowedAttributes)) {\n        el.removeAttribute(attr.nodeName);\n      }\n    });\n  }\n\n  return createdDocument.body.innerHTML;\n}\n\n/**\n * --------------------------------------------------------------------------\n * Bootstrap (v5.1.0): tooltip.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n/**\n * ------------------------------------------------------------------------\n * Constants\n * ------------------------------------------------------------------------\n */\n\nconst NAME$4 = 'tooltip';\nconst DATA_KEY$4 = 'bs.tooltip';\nconst EVENT_KEY$4 = `.${DATA_KEY$4}`;\nconst CLASS_PREFIX$1 = 'bs-tooltip';\nconst DISALLOWED_ATTRIBUTES = new Set(['sanitize', 'allowList', 'sanitizeFn']);\nconst DefaultType$3 = {\n  animation: 'boolean',\n  template: 'string',\n  title: '(string|element|function)',\n  trigger: 'string',\n  delay: '(number|object)',\n  html: 'boolean',\n  selector: '(string|boolean)',\n  placement: '(string|function)',\n  offset: '(array|string|function)',\n  container: '(string|element|boolean)',\n  fallbackPlacements: 'array',\n  boundary: '(string|element)',\n  customClass: '(string|function)',\n  sanitize: 'boolean',\n  sanitizeFn: '(null|function)',\n  allowList: 'object',\n  popperConfig: '(null|object|function)'\n};\nconst AttachmentMap = {\n  AUTO: 'auto',\n  TOP: 'top',\n  RIGHT: isRTL() ? 'left' : 'right',\n  BOTTOM: 'bottom',\n  LEFT: isRTL() ? 'right' : 'left'\n};\nconst Default$3 = {\n  animation: true,\n  template: '<div class=\"tooltip\" role=\"tooltip\">' + '<div class=\"tooltip-arrow\"></div>' + '<div class=\"tooltip-inner\"></div>' + '</div>',\n  trigger: 'hover focus',\n  title: '',\n  delay: 0,\n  html: false,\n  selector: false,\n  placement: 'top',\n  offset: [0, 0],\n  container: false,\n  fallbackPlacements: ['top', 'right', 'bottom', 'left'],\n  boundary: 'clippingParents',\n  customClass: '',\n  sanitize: true,\n  sanitizeFn: null,\n  allowList: DefaultAllowlist,\n  popperConfig: null\n};\nconst Event$2 = {\n  HIDE: `hide${EVENT_KEY$4}`,\n  HIDDEN: `hidden${EVENT_KEY$4}`,\n  SHOW: `show${EVENT_KEY$4}`,\n  SHOWN: `shown${EVENT_KEY$4}`,\n  INSERTED: `inserted${EVENT_KEY$4}`,\n  CLICK: `click${EVENT_KEY$4}`,\n  FOCUSIN: `focusin${EVENT_KEY$4}`,\n  FOCUSOUT: `focusout${EVENT_KEY$4}`,\n  MOUSEENTER: `mouseenter${EVENT_KEY$4}`,\n  MOUSELEAVE: `mouseleave${EVENT_KEY$4}`\n};\nconst CLASS_NAME_FADE$2 = 'fade';\nconst CLASS_NAME_MODAL = 'modal';\nconst CLASS_NAME_SHOW$2 = 'show';\nconst HOVER_STATE_SHOW = 'show';\nconst HOVER_STATE_OUT = 'out';\nconst SELECTOR_TOOLTIP_INNER = '.tooltip-inner';\nconst SELECTOR_MODAL = `.${CLASS_NAME_MODAL}`;\nconst EVENT_MODAL_HIDE = 'hide.bs.modal';\nconst TRIGGER_HOVER = 'hover';\nconst TRIGGER_FOCUS = 'focus';\nconst TRIGGER_CLICK = 'click';\nconst TRIGGER_MANUAL = 'manual';\n/**\n * ------------------------------------------------------------------------\n * Class Definition\n * ------------------------------------------------------------------------\n */\n\nclass Tooltip extends BaseComponent {\n  constructor(element, config) {\n    if (typeof Popper === 'undefined') {\n      throw new TypeError('Bootstrap\\'s tooltips require Popper (https://popper.js.org)');\n    }\n\n    super(element); // private\n\n    this._isEnabled = true;\n    this._timeout = 0;\n    this._hoverState = '';\n    this._activeTrigger = {};\n    this._popper = null; // Protected\n\n    this._config = this._getConfig(config);\n    this.tip = null;\n\n    this._setListeners();\n  } // Getters\n\n\n  static get Default() {\n    return Default$3;\n  }\n\n  static get NAME() {\n    return NAME$4;\n  }\n\n  static get Event() {\n    return Event$2;\n  }\n\n  static get DefaultType() {\n    return DefaultType$3;\n  } // Public\n\n\n  enable() {\n    this._isEnabled = true;\n  }\n\n  disable() {\n    this._isEnabled = false;\n  }\n\n  toggleEnabled() {\n    this._isEnabled = !this._isEnabled;\n  }\n\n  toggle(event) {\n    if (!this._isEnabled) {\n      return;\n    }\n\n    if (event) {\n      const context = this._initializeOnDelegatedTarget(event);\n\n      context._activeTrigger.click = !context._activeTrigger.click;\n\n      if (context._isWithActiveTrigger()) {\n        context._enter(null, context);\n      } else {\n        context._leave(null, context);\n      }\n    } else {\n      if (this.getTipElement().classList.contains(CLASS_NAME_SHOW$2)) {\n        this._leave(null, this);\n\n        return;\n      }\n\n      this._enter(null, this);\n    }\n  }\n\n  dispose() {\n    clearTimeout(this._timeout);\n    EventHandler.off(this._element.closest(SELECTOR_MODAL), EVENT_MODAL_HIDE, this._hideModalHandler);\n\n    if (this.tip) {\n      this.tip.remove();\n    }\n\n    if (this._popper) {\n      this._popper.destroy();\n    }\n\n    super.dispose();\n  }\n\n  show() {\n    if (this._element.style.display === 'none') {\n      throw new Error('Please use show on visible elements');\n    }\n\n    if (!(this.isWithContent() && this._isEnabled)) {\n      return;\n    }\n\n    const showEvent = EventHandler.trigger(this._element, this.constructor.Event.SHOW);\n    const shadowRoot = findShadowRoot(this._element);\n    const isInTheDom = shadowRoot === null ? this._element.ownerDocument.documentElement.contains(this._element) : shadowRoot.contains(this._element);\n\n    if (showEvent.defaultPrevented || !isInTheDom) {\n      return;\n    }\n\n    const tip = this.getTipElement();\n    const tipId = getUID(this.constructor.NAME);\n    tip.setAttribute('id', tipId);\n\n    this._element.setAttribute('aria-describedby', tipId);\n\n    if (this._config.animation) {\n      tip.classList.add(CLASS_NAME_FADE$2);\n    }\n\n    const placement = typeof this._config.placement === 'function' ? this._config.placement.call(this, tip, this._element) : this._config.placement;\n\n    const attachment = this._getAttachment(placement);\n\n    this._addAttachmentClass(attachment);\n\n    const {\n      container\n    } = this._config;\n    Data.set(tip, this.constructor.DATA_KEY, this);\n\n    if (!this._element.ownerDocument.documentElement.contains(this.tip)) {\n      container.append(tip);\n      EventHandler.trigger(this._element, this.constructor.Event.INSERTED);\n    }\n\n    if (this._popper) {\n      this._popper.update();\n    } else {\n      this._popper = Popper.createPopper(this._element, tip, this._getPopperConfig(attachment));\n    }\n\n    tip.classList.add(CLASS_NAME_SHOW$2);\n\n    const customClass = this._resolvePossibleFunction(this._config.customClass);\n\n    if (customClass) {\n      tip.classList.add(...customClass.split(' '));\n    } // If this is a touch-enabled device we add extra\n    // empty mouseover listeners to the body's immediate children;\n    // only needed because of broken event delegation on iOS\n    // https://www.quirksmode.org/blog/archives/2014/02/mouse_event_bub.html\n\n\n    if ('ontouchstart' in document.documentElement) {\n      [].concat(...document.body.children).forEach(element => {\n        EventHandler.on(element, 'mouseover', noop);\n      });\n    }\n\n    const complete = () => {\n      const prevHoverState = this._hoverState;\n      this._hoverState = null;\n      EventHandler.trigger(this._element, this.constructor.Event.SHOWN);\n\n      if (prevHoverState === HOVER_STATE_OUT) {\n        this._leave(null, this);\n      }\n    };\n\n    const isAnimated = this.tip.classList.contains(CLASS_NAME_FADE$2);\n\n    this._queueCallback(complete, this.tip, isAnimated);\n  }\n\n  hide() {\n    if (!this._popper) {\n      return;\n    }\n\n    const tip = this.getTipElement();\n\n    const complete = () => {\n      if (this._isWithActiveTrigger()) {\n        return;\n      }\n\n      if (this._hoverState !== HOVER_STATE_SHOW) {\n        tip.remove();\n      }\n\n      this._cleanTipClass();\n\n      this._element.removeAttribute('aria-describedby');\n\n      EventHandler.trigger(this._element, this.constructor.Event.HIDDEN);\n\n      if (this._popper) {\n        this._popper.destroy();\n\n        this._popper = null;\n      }\n    };\n\n    const hideEvent = EventHandler.trigger(this._element, this.constructor.Event.HIDE);\n\n    if (hideEvent.defaultPrevented) {\n      return;\n    }\n\n    tip.classList.remove(CLASS_NAME_SHOW$2); // If this is a touch-enabled device we remove the extra\n    // empty mouseover listeners we added for iOS support\n\n    if ('ontouchstart' in document.documentElement) {\n      [].concat(...document.body.children).forEach(element => EventHandler.off(element, 'mouseover', noop));\n    }\n\n    this._activeTrigger[TRIGGER_CLICK] = false;\n    this._activeTrigger[TRIGGER_FOCUS] = false;\n    this._activeTrigger[TRIGGER_HOVER] = false;\n    const isAnimated = this.tip.classList.contains(CLASS_NAME_FADE$2);\n\n    this._queueCallback(complete, this.tip, isAnimated);\n\n    this._hoverState = '';\n  }\n\n  update() {\n    if (this._popper !== null) {\n      this._popper.update();\n    }\n  } // Protected\n\n\n  isWithContent() {\n    return Boolean(this.getTitle());\n  }\n\n  getTipElement() {\n    if (this.tip) {\n      return this.tip;\n    }\n\n    const element = document.createElement('div');\n    element.innerHTML = this._config.template;\n    const tip = element.children[0];\n    this.setContent(tip);\n    tip.classList.remove(CLASS_NAME_FADE$2, CLASS_NAME_SHOW$2);\n    this.tip = tip;\n    return this.tip;\n  }\n\n  setContent(tip) {\n    this._sanitizeAndSetContent(tip, this.getTitle(), SELECTOR_TOOLTIP_INNER);\n  }\n\n  _sanitizeAndSetContent(template, content, selector) {\n    const templateElement = SelectorEngine.findOne(selector, template);\n\n    if (!content && templateElement) {\n      templateElement.remove();\n      return;\n    } // we use append for html objects to maintain js events\n\n\n    this.setElementContent(templateElement, content);\n  }\n\n  setElementContent(element, content) {\n    if (element === null) {\n      return;\n    }\n\n    if (isElement(content)) {\n      content = getElement(content); // content is a DOM node or a jQuery\n\n      if (this._config.html) {\n        if (content.parentNode !== element) {\n          element.innerHTML = '';\n          element.append(content);\n        }\n      } else {\n        element.textContent = content.textContent;\n      }\n\n      return;\n    }\n\n    if (this._config.html) {\n      if (this._config.sanitize) {\n        content = sanitizeHtml(content, this._config.allowList, this._config.sanitizeFn);\n      }\n\n      element.innerHTML = content;\n    } else {\n      element.textContent = content;\n    }\n  }\n\n  getTitle() {\n    const title = this._element.getAttribute('data-bs-original-title') || this._config.title;\n\n    return this._resolvePossibleFunction(title);\n  }\n\n  updateAttachment(attachment) {\n    if (attachment === 'right') {\n      return 'end';\n    }\n\n    if (attachment === 'left') {\n      return 'start';\n    }\n\n    return attachment;\n  } // Private\n\n\n  _initializeOnDelegatedTarget(event, context) {\n    return context || this.constructor.getOrCreateInstance(event.delegateTarget, this._getDelegateConfig());\n  }\n\n  _getOffset() {\n    const {\n      offset\n    } = this._config;\n\n    if (typeof offset === 'string') {\n      return offset.split(',').map(val => Number.parseInt(val, 10));\n    }\n\n    if (typeof offset === 'function') {\n      return popperData => offset(popperData, this._element);\n    }\n\n    return offset;\n  }\n\n  _resolvePossibleFunction(content) {\n    return typeof content === 'function' ? content.call(this._element) : content;\n  }\n\n  _getPopperConfig(attachment) {\n    const defaultBsPopperConfig = {\n      placement: attachment,\n      modifiers: [{\n        name: 'flip',\n        options: {\n          fallbackPlacements: this._config.fallbackPlacements\n        }\n      }, {\n        name: 'offset',\n        options: {\n          offset: this._getOffset()\n        }\n      }, {\n        name: 'preventOverflow',\n        options: {\n          boundary: this._config.boundary\n        }\n      }, {\n        name: 'arrow',\n        options: {\n          element: `.${this.constructor.NAME}-arrow`\n        }\n      }, {\n        name: 'onChange',\n        enabled: true,\n        phase: 'afterWrite',\n        fn: data => this._handlePopperPlacementChange(data)\n      }],\n      onFirstUpdate: data => {\n        if (data.options.placement !== data.placement) {\n          this._handlePopperPlacementChange(data);\n        }\n      }\n    };\n    return { ...defaultBsPopperConfig,\n      ...(typeof this._config.popperConfig === 'function' ? this._config.popperConfig(defaultBsPopperConfig) : this._config.popperConfig)\n    };\n  }\n\n  _addAttachmentClass(attachment) {\n    this.getTipElement().classList.add(`${this._getBasicClassPrefix()}-${this.updateAttachment(attachment)}`);\n  }\n\n  _getAttachment(placement) {\n    return AttachmentMap[placement.toUpperCase()];\n  }\n\n  _setListeners() {\n    const triggers = this._config.trigger.split(' ');\n\n    triggers.forEach(trigger => {\n      if (trigger === 'click') {\n        EventHandler.on(this._element, this.constructor.Event.CLICK, this._config.selector, event => this.toggle(event));\n      } else if (trigger !== TRIGGER_MANUAL) {\n        const eventIn = trigger === TRIGGER_HOVER ? this.constructor.Event.MOUSEENTER : this.constructor.Event.FOCUSIN;\n        const eventOut = trigger === TRIGGER_HOVER ? this.constructor.Event.MOUSELEAVE : this.constructor.Event.FOCUSOUT;\n        EventHandler.on(this._element, eventIn, this._config.selector, event => this._enter(event));\n        EventHandler.on(this._element, eventOut, this._config.selector, event => this._leave(event));\n      }\n    });\n\n    this._hideModalHandler = () => {\n      if (this._element) {\n        this.hide();\n      }\n    };\n\n    EventHandler.on(this._element.closest(SELECTOR_MODAL), EVENT_MODAL_HIDE, this._hideModalHandler);\n\n    if (this._config.selector) {\n      this._config = { ...this._config,\n        trigger: 'manual',\n        selector: ''\n      };\n    } else {\n      this._fixTitle();\n    }\n  }\n\n  _fixTitle() {\n    const title = this._element.getAttribute('title');\n\n    const originalTitleType = typeof this._element.getAttribute('data-bs-original-title');\n\n    if (title || originalTitleType !== 'string') {\n      this._element.setAttribute('data-bs-original-title', title || '');\n\n      if (title && !this._element.getAttribute('aria-label') && !this._element.textContent) {\n        this._element.setAttribute('aria-label', title);\n      }\n\n      this._element.setAttribute('title', '');\n    }\n  }\n\n  _enter(event, context) {\n    context = this._initializeOnDelegatedTarget(event, context);\n\n    if (event) {\n      context._activeTrigger[event.type === 'focusin' ? TRIGGER_FOCUS : TRIGGER_HOVER] = true;\n    }\n\n    if (context.getTipElement().classList.contains(CLASS_NAME_SHOW$2) || context._hoverState === HOVER_STATE_SHOW) {\n      context._hoverState = HOVER_STATE_SHOW;\n      return;\n    }\n\n    clearTimeout(context._timeout);\n    context._hoverState = HOVER_STATE_SHOW;\n\n    if (!context._config.delay || !context._config.delay.show) {\n      context.show();\n      return;\n    }\n\n    context._timeout = setTimeout(() => {\n      if (context._hoverState === HOVER_STATE_SHOW) {\n        context.show();\n      }\n    }, context._config.delay.show);\n  }\n\n  _leave(event, context) {\n    context = this._initializeOnDelegatedTarget(event, context);\n\n    if (event) {\n      context._activeTrigger[event.type === 'focusout' ? TRIGGER_FOCUS : TRIGGER_HOVER] = context._element.contains(event.relatedTarget);\n    }\n\n    if (context._isWithActiveTrigger()) {\n      return;\n    }\n\n    clearTimeout(context._timeout);\n    context._hoverState = HOVER_STATE_OUT;\n\n    if (!context._config.delay || !context._config.delay.hide) {\n      context.hide();\n      return;\n    }\n\n    context._timeout = setTimeout(() => {\n      if (context._hoverState === HOVER_STATE_OUT) {\n        context.hide();\n      }\n    }, context._config.delay.hide);\n  }\n\n  _isWithActiveTrigger() {\n    for (const trigger in this._activeTrigger) {\n      if (this._activeTrigger[trigger]) {\n        return true;\n      }\n    }\n\n    return false;\n  }\n\n  _getConfig(config) {\n    const dataAttributes = Manipulator.getDataAttributes(this._element);\n    Object.keys(dataAttributes).forEach(dataAttr => {\n      if (DISALLOWED_ATTRIBUTES.has(dataAttr)) {\n        delete dataAttributes[dataAttr];\n      }\n    });\n    config = { ...this.constructor.Default,\n      ...dataAttributes,\n      ...(typeof config === 'object' && config ? config : {})\n    };\n    config.container = config.container === false ? document.body : getElement(config.container);\n\n    if (typeof config.delay === 'number') {\n      config.delay = {\n        show: config.delay,\n        hide: config.delay\n      };\n    }\n\n    if (typeof config.title === 'number') {\n      config.title = config.title.toString();\n    }\n\n    if (typeof config.content === 'number') {\n      config.content = config.content.toString();\n    }\n\n    typeCheckConfig(NAME$4, config, this.constructor.DefaultType);\n\n    if (config.sanitize) {\n      config.template = sanitizeHtml(config.template, config.allowList, config.sanitizeFn);\n    }\n\n    return config;\n  }\n\n  _getDelegateConfig() {\n    const config = {};\n\n    for (const key in this._config) {\n      if (this.constructor.Default[key] !== this._config[key]) {\n        config[key] = this._config[key];\n      }\n    } // In the future can be replaced with:\n    // const keysWithDifferentValues = Object.entries(this._config).filter(entry => this.constructor.Default[entry[0]] !== this._config[entry[0]])\n    // `Object.fromEntries(keysWithDifferentValues)`\n\n\n    return config;\n  }\n\n  _cleanTipClass() {\n    const tip = this.getTipElement();\n    const basicClassPrefixRegex = new RegExp(`(^|\\\\s)${this._getBasicClassPrefix()}\\\\S+`, 'g');\n    const tabClass = tip.getAttribute('class').match(basicClassPrefixRegex);\n\n    if (tabClass !== null && tabClass.length > 0) {\n      tabClass.map(token => token.trim()).forEach(tClass => tip.classList.remove(tClass));\n    }\n  }\n\n  _getBasicClassPrefix() {\n    return CLASS_PREFIX$1;\n  }\n\n  _handlePopperPlacementChange(popperData) {\n    const {\n      state\n    } = popperData;\n\n    if (!state) {\n      return;\n    }\n\n    this.tip = state.elements.popper;\n\n    this._cleanTipClass();\n\n    this._addAttachmentClass(this._getAttachment(state.placement));\n  } // Static\n\n\n  static jQueryInterface(config) {\n    return this.each(function () {\n      const data = Tooltip.getOrCreateInstance(this, config);\n\n      if (typeof config === 'string') {\n        if (typeof data[config] === 'undefined') {\n          throw new TypeError(`No method named \"${config}\"`);\n        }\n\n        data[config]();\n      }\n    });\n  }\n\n}\n/**\n * ------------------------------------------------------------------------\n * jQuery\n * ------------------------------------------------------------------------\n * add .Tooltip to jQuery only if jQuery is present\n */\n\n\ndefineJQueryPlugin(Tooltip);\n\n/**\n * --------------------------------------------------------------------------\n * Bootstrap (v5.1.0): popover.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n/**\n * ------------------------------------------------------------------------\n * Constants\n * ------------------------------------------------------------------------\n */\n\nconst NAME$3 = 'popover';\nconst DATA_KEY$3 = 'bs.popover';\nconst EVENT_KEY$3 = `.${DATA_KEY$3}`;\nconst CLASS_PREFIX = 'bs-popover';\nconst Default$2 = { ...Tooltip.Default,\n  placement: 'right',\n  offset: [0, 8],\n  trigger: 'click',\n  content: '',\n  template: '<div class=\"popover\" role=\"tooltip\">' + '<div class=\"popover-arrow\"></div>' + '<h3 class=\"popover-header\"></h3>' + '<div class=\"popover-body\"></div>' + '</div>'\n};\nconst DefaultType$2 = { ...Tooltip.DefaultType,\n  content: '(string|element|function)'\n};\nconst Event$1 = {\n  HIDE: `hide${EVENT_KEY$3}`,\n  HIDDEN: `hidden${EVENT_KEY$3}`,\n  SHOW: `show${EVENT_KEY$3}`,\n  SHOWN: `shown${EVENT_KEY$3}`,\n  INSERTED: `inserted${EVENT_KEY$3}`,\n  CLICK: `click${EVENT_KEY$3}`,\n  FOCUSIN: `focusin${EVENT_KEY$3}`,\n  FOCUSOUT: `focusout${EVENT_KEY$3}`,\n  MOUSEENTER: `mouseenter${EVENT_KEY$3}`,\n  MOUSELEAVE: `mouseleave${EVENT_KEY$3}`\n};\nconst SELECTOR_TITLE = '.popover-header';\nconst SELECTOR_CONTENT = '.popover-body';\n/**\n * ------------------------------------------------------------------------\n * Class Definition\n * ------------------------------------------------------------------------\n */\n\nclass Popover extends Tooltip {\n  // Getters\n  static get Default() {\n    return Default$2;\n  }\n\n  static get NAME() {\n    return NAME$3;\n  }\n\n  static get Event() {\n    return Event$1;\n  }\n\n  static get DefaultType() {\n    return DefaultType$2;\n  } // Overrides\n\n\n  isWithContent() {\n    return this.getTitle() || this._getContent();\n  }\n\n  setContent(tip) {\n    this._sanitizeAndSetContent(tip, this.getTitle(), SELECTOR_TITLE);\n\n    this._sanitizeAndSetContent(tip, this._getContent(), SELECTOR_CONTENT);\n  } // Private\n\n\n  _getContent() {\n    return this._resolvePossibleFunction(this._config.content);\n  }\n\n  _getBasicClassPrefix() {\n    return CLASS_PREFIX;\n  } // Static\n\n\n  static jQueryInterface(config) {\n    return this.each(function () {\n      const data = Popover.getOrCreateInstance(this, config);\n\n      if (typeof config === 'string') {\n        if (typeof data[config] === 'undefined') {\n          throw new TypeError(`No method named \"${config}\"`);\n        }\n\n        data[config]();\n      }\n    });\n  }\n\n}\n/**\n * ------------------------------------------------------------------------\n * jQuery\n * ------------------------------------------------------------------------\n * add .Popover to jQuery only if jQuery is present\n */\n\n\ndefineJQueryPlugin(Popover);\n\n/**\n * --------------------------------------------------------------------------\n * Bootstrap (v5.1.0): scrollspy.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n/**\n * ------------------------------------------------------------------------\n * Constants\n * ------------------------------------------------------------------------\n */\n\nconst NAME$2 = 'scrollspy';\nconst DATA_KEY$2 = 'bs.scrollspy';\nconst EVENT_KEY$2 = `.${DATA_KEY$2}`;\nconst DATA_API_KEY$1 = '.data-api';\nconst Default$1 = {\n  offset: 10,\n  method: 'auto',\n  target: ''\n};\nconst DefaultType$1 = {\n  offset: 'number',\n  method: 'string',\n  target: '(string|element)'\n};\nconst EVENT_ACTIVATE = `activate${EVENT_KEY$2}`;\nconst EVENT_SCROLL = `scroll${EVENT_KEY$2}`;\nconst EVENT_LOAD_DATA_API = `load${EVENT_KEY$2}${DATA_API_KEY$1}`;\nconst CLASS_NAME_DROPDOWN_ITEM = 'dropdown-item';\nconst CLASS_NAME_ACTIVE$1 = 'active';\nconst SELECTOR_DATA_SPY = '[data-bs-spy=\"scroll\"]';\nconst SELECTOR_NAV_LIST_GROUP$1 = '.nav, .list-group';\nconst SELECTOR_NAV_LINKS = '.nav-link';\nconst SELECTOR_NAV_ITEMS = '.nav-item';\nconst SELECTOR_LIST_ITEMS = '.list-group-item';\nconst SELECTOR_LINK_ITEMS = `${SELECTOR_NAV_LINKS}, ${SELECTOR_LIST_ITEMS}, .${CLASS_NAME_DROPDOWN_ITEM}`;\nconst SELECTOR_DROPDOWN$1 = '.dropdown';\nconst SELECTOR_DROPDOWN_TOGGLE$1 = '.dropdown-toggle';\nconst METHOD_OFFSET = 'offset';\nconst METHOD_POSITION = 'position';\n/**\n * ------------------------------------------------------------------------\n * Class Definition\n * ------------------------------------------------------------------------\n */\n\nclass ScrollSpy extends BaseComponent {\n  constructor(element, config) {\n    super(element);\n    this._scrollElement = this._element.tagName === 'BODY' ? window : this._element;\n    this._config = this._getConfig(config);\n    this._offsets = [];\n    this._targets = [];\n    this._activeTarget = null;\n    this._scrollHeight = 0;\n    EventHandler.on(this._scrollElement, EVENT_SCROLL, () => this._process());\n    this.refresh();\n\n    this._process();\n  } // Getters\n\n\n  static get Default() {\n    return Default$1;\n  }\n\n  static get NAME() {\n    return NAME$2;\n  } // Public\n\n\n  refresh() {\n    const autoMethod = this._scrollElement === this._scrollElement.window ? METHOD_OFFSET : METHOD_POSITION;\n    const offsetMethod = this._config.method === 'auto' ? autoMethod : this._config.method;\n    const offsetBase = offsetMethod === METHOD_POSITION ? this._getScrollTop() : 0;\n    this._offsets = [];\n    this._targets = [];\n    this._scrollHeight = this._getScrollHeight();\n    const targets = SelectorEngine.find(SELECTOR_LINK_ITEMS, this._config.target);\n    targets.map(element => {\n      const targetSelector = getSelectorFromElement(element);\n      const target = targetSelector ? SelectorEngine.findOne(targetSelector) : null;\n\n      if (target) {\n        const targetBCR = target.getBoundingClientRect();\n\n        if (targetBCR.width || targetBCR.height) {\n          return [Manipulator[offsetMethod](target).top + offsetBase, targetSelector];\n        }\n      }\n\n      return null;\n    }).filter(item => item).sort((a, b) => a[0] - b[0]).forEach(item => {\n      this._offsets.push(item[0]);\n\n      this._targets.push(item[1]);\n    });\n  }\n\n  dispose() {\n    EventHandler.off(this._scrollElement, EVENT_KEY$2);\n    super.dispose();\n  } // Private\n\n\n  _getConfig(config) {\n    config = { ...Default$1,\n      ...Manipulator.getDataAttributes(this._element),\n      ...(typeof config === 'object' && config ? config : {})\n    };\n    config.target = getElement(config.target) || document.documentElement;\n    typeCheckConfig(NAME$2, config, DefaultType$1);\n    return config;\n  }\n\n  _getScrollTop() {\n    return this._scrollElement === window ? this._scrollElement.pageYOffset : this._scrollElement.scrollTop;\n  }\n\n  _getScrollHeight() {\n    return this._scrollElement.scrollHeight || Math.max(document.body.scrollHeight, document.documentElement.scrollHeight);\n  }\n\n  _getOffsetHeight() {\n    return this._scrollElement === window ? window.innerHeight : this._scrollElement.getBoundingClientRect().height;\n  }\n\n  _process() {\n    const scrollTop = this._getScrollTop() + this._config.offset;\n\n    const scrollHeight = this._getScrollHeight();\n\n    const maxScroll = this._config.offset + scrollHeight - this._getOffsetHeight();\n\n    if (this._scrollHeight !== scrollHeight) {\n      this.refresh();\n    }\n\n    if (scrollTop >= maxScroll) {\n      const target = this._targets[this._targets.length - 1];\n\n      if (this._activeTarget !== target) {\n        this._activate(target);\n      }\n\n      return;\n    }\n\n    if (this._activeTarget && scrollTop < this._offsets[0] && this._offsets[0] > 0) {\n      this._activeTarget = null;\n\n      this._clear();\n\n      return;\n    }\n\n    for (let i = this._offsets.length; i--;) {\n      const isActiveTarget = this._activeTarget !== this._targets[i] && scrollTop >= this._offsets[i] && (typeof this._offsets[i + 1] === 'undefined' || scrollTop < this._offsets[i + 1]);\n\n      if (isActiveTarget) {\n        this._activate(this._targets[i]);\n      }\n    }\n  }\n\n  _activate(target) {\n    this._activeTarget = target;\n\n    this._clear();\n\n    const queries = SELECTOR_LINK_ITEMS.split(',').map(selector => `${selector}[data-bs-target=\"${target}\"],${selector}[href=\"${target}\"]`);\n    const link = SelectorEngine.findOne(queries.join(','), this._config.target);\n    link.classList.add(CLASS_NAME_ACTIVE$1);\n\n    if (link.classList.contains(CLASS_NAME_DROPDOWN_ITEM)) {\n      SelectorEngine.findOne(SELECTOR_DROPDOWN_TOGGLE$1, link.closest(SELECTOR_DROPDOWN$1)).classList.add(CLASS_NAME_ACTIVE$1);\n    } else {\n      SelectorEngine.parents(link, SELECTOR_NAV_LIST_GROUP$1).forEach(listGroup => {\n        // Set triggered links parents as active\n        // With both <ul> and <nav> markup a parent is the previous sibling of any nav ancestor\n        SelectorEngine.prev(listGroup, `${SELECTOR_NAV_LINKS}, ${SELECTOR_LIST_ITEMS}`).forEach(item => item.classList.add(CLASS_NAME_ACTIVE$1)); // Handle special case when .nav-link is inside .nav-item\n\n        SelectorEngine.prev(listGroup, SELECTOR_NAV_ITEMS).forEach(navItem => {\n          SelectorEngine.children(navItem, SELECTOR_NAV_LINKS).forEach(item => item.classList.add(CLASS_NAME_ACTIVE$1));\n        });\n      });\n    }\n\n    EventHandler.trigger(this._scrollElement, EVENT_ACTIVATE, {\n      relatedTarget: target\n    });\n  }\n\n  _clear() {\n    SelectorEngine.find(SELECTOR_LINK_ITEMS, this._config.target).filter(node => node.classList.contains(CLASS_NAME_ACTIVE$1)).forEach(node => node.classList.remove(CLASS_NAME_ACTIVE$1));\n  } // Static\n\n\n  static jQueryInterface(config) {\n    return this.each(function () {\n      const data = ScrollSpy.getOrCreateInstance(this, config);\n\n      if (typeof config !== 'string') {\n        return;\n      }\n\n      if (typeof data[config] === 'undefined') {\n        throw new TypeError(`No method named \"${config}\"`);\n      }\n\n      data[config]();\n    });\n  }\n\n}\n/**\n * ------------------------------------------------------------------------\n * Data Api implementation\n * ------------------------------------------------------------------------\n */\n\n\nEventHandler.on(window, EVENT_LOAD_DATA_API, () => {\n  SelectorEngine.find(SELECTOR_DATA_SPY).forEach(spy => new ScrollSpy(spy));\n});\n/**\n * ------------------------------------------------------------------------\n * jQuery\n * ------------------------------------------------------------------------\n * add .ScrollSpy to jQuery only if jQuery is present\n */\n\ndefineJQueryPlugin(ScrollSpy);\n\n/**\n * --------------------------------------------------------------------------\n * Bootstrap (v5.1.0): tab.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n/**\n * ------------------------------------------------------------------------\n * Constants\n * ------------------------------------------------------------------------\n */\n\nconst NAME$1 = 'tab';\nconst DATA_KEY$1 = 'bs.tab';\nconst EVENT_KEY$1 = `.${DATA_KEY$1}`;\nconst DATA_API_KEY = '.data-api';\nconst EVENT_HIDE$1 = `hide${EVENT_KEY$1}`;\nconst EVENT_HIDDEN$1 = `hidden${EVENT_KEY$1}`;\nconst EVENT_SHOW$1 = `show${EVENT_KEY$1}`;\nconst EVENT_SHOWN$1 = `shown${EVENT_KEY$1}`;\nconst EVENT_CLICK_DATA_API = `click${EVENT_KEY$1}${DATA_API_KEY}`;\nconst CLASS_NAME_DROPDOWN_MENU = 'dropdown-menu';\nconst CLASS_NAME_ACTIVE = 'active';\nconst CLASS_NAME_FADE$1 = 'fade';\nconst CLASS_NAME_SHOW$1 = 'show';\nconst SELECTOR_DROPDOWN = '.dropdown';\nconst SELECTOR_NAV_LIST_GROUP = '.nav, .list-group';\nconst SELECTOR_ACTIVE = '.active';\nconst SELECTOR_ACTIVE_UL = ':scope > li > .active';\nconst SELECTOR_DATA_TOGGLE = '[data-bs-toggle=\"tab\"], [data-bs-toggle=\"pill\"], [data-bs-toggle=\"list\"]';\nconst SELECTOR_DROPDOWN_TOGGLE = '.dropdown-toggle';\nconst SELECTOR_DROPDOWN_ACTIVE_CHILD = ':scope > .dropdown-menu .active';\n/**\n * ------------------------------------------------------------------------\n * Class Definition\n * ------------------------------------------------------------------------\n */\n\nclass Tab extends BaseComponent {\n  // Getters\n  static get NAME() {\n    return NAME$1;\n  } // Public\n\n\n  show() {\n    if (this._element.parentNode && this._element.parentNode.nodeType === Node.ELEMENT_NODE && this._element.classList.contains(CLASS_NAME_ACTIVE)) {\n      return;\n    }\n\n    let previous;\n    const target = getElementFromSelector(this._element);\n\n    const listElement = this._element.closest(SELECTOR_NAV_LIST_GROUP);\n\n    if (listElement) {\n      const itemSelector = listElement.nodeName === 'UL' || listElement.nodeName === 'OL' ? SELECTOR_ACTIVE_UL : SELECTOR_ACTIVE;\n      previous = SelectorEngine.find(itemSelector, listElement);\n      previous = previous[previous.length - 1];\n    }\n\n    const hideEvent = previous ? EventHandler.trigger(previous, EVENT_HIDE$1, {\n      relatedTarget: this._element\n    }) : null;\n    const showEvent = EventHandler.trigger(this._element, EVENT_SHOW$1, {\n      relatedTarget: previous\n    });\n\n    if (showEvent.defaultPrevented || hideEvent !== null && hideEvent.defaultPrevented) {\n      return;\n    }\n\n    this._activate(this._element, listElement);\n\n    const complete = () => {\n      EventHandler.trigger(previous, EVENT_HIDDEN$1, {\n        relatedTarget: this._element\n      });\n      EventHandler.trigger(this._element, EVENT_SHOWN$1, {\n        relatedTarget: previous\n      });\n    };\n\n    if (target) {\n      this._activate(target, target.parentNode, complete);\n    } else {\n      complete();\n    }\n  } // Private\n\n\n  _activate(element, container, callback) {\n    const activeElements = container && (container.nodeName === 'UL' || container.nodeName === 'OL') ? SelectorEngine.find(SELECTOR_ACTIVE_UL, container) : SelectorEngine.children(container, SELECTOR_ACTIVE);\n    const active = activeElements[0];\n    const isTransitioning = callback && active && active.classList.contains(CLASS_NAME_FADE$1);\n\n    const complete = () => this._transitionComplete(element, active, callback);\n\n    if (active && isTransitioning) {\n      active.classList.remove(CLASS_NAME_SHOW$1);\n\n      this._queueCallback(complete, element, true);\n    } else {\n      complete();\n    }\n  }\n\n  _transitionComplete(element, active, callback) {\n    if (active) {\n      active.classList.remove(CLASS_NAME_ACTIVE);\n      const dropdownChild = SelectorEngine.findOne(SELECTOR_DROPDOWN_ACTIVE_CHILD, active.parentNode);\n\n      if (dropdownChild) {\n        dropdownChild.classList.remove(CLASS_NAME_ACTIVE);\n      }\n\n      if (active.getAttribute('role') === 'tab') {\n        active.setAttribute('aria-selected', false);\n      }\n    }\n\n    element.classList.add(CLASS_NAME_ACTIVE);\n\n    if (element.getAttribute('role') === 'tab') {\n      element.setAttribute('aria-selected', true);\n    }\n\n    reflow(element);\n\n    if (element.classList.contains(CLASS_NAME_FADE$1)) {\n      element.classList.add(CLASS_NAME_SHOW$1);\n    }\n\n    let parent = element.parentNode;\n\n    if (parent && parent.nodeName === 'LI') {\n      parent = parent.parentNode;\n    }\n\n    if (parent && parent.classList.contains(CLASS_NAME_DROPDOWN_MENU)) {\n      const dropdownElement = element.closest(SELECTOR_DROPDOWN);\n\n      if (dropdownElement) {\n        SelectorEngine.find(SELECTOR_DROPDOWN_TOGGLE, dropdownElement).forEach(dropdown => dropdown.classList.add(CLASS_NAME_ACTIVE));\n      }\n\n      element.setAttribute('aria-expanded', true);\n    }\n\n    if (callback) {\n      callback();\n    }\n  } // Static\n\n\n  static jQueryInterface(config) {\n    return this.each(function () {\n      const data = Tab.getOrCreateInstance(this);\n\n      if (typeof config === 'string') {\n        if (typeof data[config] === 'undefined') {\n          throw new TypeError(`No method named \"${config}\"`);\n        }\n\n        data[config]();\n      }\n    });\n  }\n\n}\n/**\n * ------------------------------------------------------------------------\n * Data Api implementation\n * ------------------------------------------------------------------------\n */\n\n\nEventHandler.on(document, EVENT_CLICK_DATA_API, SELECTOR_DATA_TOGGLE, function (event) {\n  if (['A', 'AREA'].includes(this.tagName)) {\n    event.preventDefault();\n  }\n\n  if (isDisabled(this)) {\n    return;\n  }\n\n  const data = Tab.getOrCreateInstance(this);\n  data.show();\n});\n/**\n * ------------------------------------------------------------------------\n * jQuery\n * ------------------------------------------------------------------------\n * add .Tab to jQuery only if jQuery is present\n */\n\ndefineJQueryPlugin(Tab);\n\n/**\n * --------------------------------------------------------------------------\n * Bootstrap (v5.1.0): toast.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n/**\n * ------------------------------------------------------------------------\n * Constants\n * ------------------------------------------------------------------------\n */\n\nconst NAME = 'toast';\nconst DATA_KEY = 'bs.toast';\nconst EVENT_KEY = `.${DATA_KEY}`;\nconst EVENT_MOUSEOVER = `mouseover${EVENT_KEY}`;\nconst EVENT_MOUSEOUT = `mouseout${EVENT_KEY}`;\nconst EVENT_FOCUSIN = `focusin${EVENT_KEY}`;\nconst EVENT_FOCUSOUT = `focusout${EVENT_KEY}`;\nconst EVENT_HIDE = `hide${EVENT_KEY}`;\nconst EVENT_HIDDEN = `hidden${EVENT_KEY}`;\nconst EVENT_SHOW = `show${EVENT_KEY}`;\nconst EVENT_SHOWN = `shown${EVENT_KEY}`;\nconst CLASS_NAME_FADE = 'fade';\nconst CLASS_NAME_HIDE = 'hide'; // @deprecated - kept here only for backwards compatibility\n\nconst CLASS_NAME_SHOW = 'show';\nconst CLASS_NAME_SHOWING = 'showing';\nconst DefaultType = {\n  animation: 'boolean',\n  autohide: 'boolean',\n  delay: 'number'\n};\nconst Default = {\n  animation: true,\n  autohide: true,\n  delay: 5000\n};\n/**\n * ------------------------------------------------------------------------\n * Class Definition\n * ------------------------------------------------------------------------\n */\n\nclass Toast extends BaseComponent {\n  constructor(element, config) {\n    super(element);\n    this._config = this._getConfig(config);\n    this._timeout = null;\n    this._hasMouseInteraction = false;\n    this._hasKeyboardInteraction = false;\n\n    this._setListeners();\n  } // Getters\n\n\n  static get DefaultType() {\n    return DefaultType;\n  }\n\n  static get Default() {\n    return Default;\n  }\n\n  static get NAME() {\n    return NAME;\n  } // Public\n\n\n  show() {\n    const showEvent = EventHandler.trigger(this._element, EVENT_SHOW);\n\n    if (showEvent.defaultPrevented) {\n      return;\n    }\n\n    this._clearTimeout();\n\n    if (this._config.animation) {\n      this._element.classList.add(CLASS_NAME_FADE);\n    }\n\n    const complete = () => {\n      this._element.classList.remove(CLASS_NAME_SHOWING);\n\n      EventHandler.trigger(this._element, EVENT_SHOWN);\n\n      this._maybeScheduleHide();\n    };\n\n    this._element.classList.remove(CLASS_NAME_HIDE); // @deprecated\n\n\n    reflow(this._element);\n\n    this._element.classList.add(CLASS_NAME_SHOW);\n\n    this._element.classList.add(CLASS_NAME_SHOWING);\n\n    this._queueCallback(complete, this._element, this._config.animation);\n  }\n\n  hide() {\n    if (!this._element.classList.contains(CLASS_NAME_SHOW)) {\n      return;\n    }\n\n    const hideEvent = EventHandler.trigger(this._element, EVENT_HIDE);\n\n    if (hideEvent.defaultPrevented) {\n      return;\n    }\n\n    const complete = () => {\n      this._element.classList.add(CLASS_NAME_HIDE); // @deprecated\n\n\n      this._element.classList.remove(CLASS_NAME_SHOWING);\n\n      this._element.classList.remove(CLASS_NAME_SHOW);\n\n      EventHandler.trigger(this._element, EVENT_HIDDEN);\n    };\n\n    this._element.classList.add(CLASS_NAME_SHOWING);\n\n    this._queueCallback(complete, this._element, this._config.animation);\n  }\n\n  dispose() {\n    this._clearTimeout();\n\n    if (this._element.classList.contains(CLASS_NAME_SHOW)) {\n      this._element.classList.remove(CLASS_NAME_SHOW);\n    }\n\n    super.dispose();\n  } // Private\n\n\n  _getConfig(config) {\n    config = { ...Default,\n      ...Manipulator.getDataAttributes(this._element),\n      ...(typeof config === 'object' && config ? config : {})\n    };\n    typeCheckConfig(NAME, config, this.constructor.DefaultType);\n    return config;\n  }\n\n  _maybeScheduleHide() {\n    if (!this._config.autohide) {\n      return;\n    }\n\n    if (this._hasMouseInteraction || this._hasKeyboardInteraction) {\n      return;\n    }\n\n    this._timeout = setTimeout(() => {\n      this.hide();\n    }, this._config.delay);\n  }\n\n  _onInteraction(event, isInteracting) {\n    switch (event.type) {\n      case 'mouseover':\n      case 'mouseout':\n        this._hasMouseInteraction = isInteracting;\n        break;\n\n      case 'focusin':\n      case 'focusout':\n        this._hasKeyboardInteraction = isInteracting;\n        break;\n    }\n\n    if (isInteracting) {\n      this._clearTimeout();\n\n      return;\n    }\n\n    const nextElement = event.relatedTarget;\n\n    if (this._element === nextElement || this._element.contains(nextElement)) {\n      return;\n    }\n\n    this._maybeScheduleHide();\n  }\n\n  _setListeners() {\n    EventHandler.on(this._element, EVENT_MOUSEOVER, event => this._onInteraction(event, true));\n    EventHandler.on(this._element, EVENT_MOUSEOUT, event => this._onInteraction(event, false));\n    EventHandler.on(this._element, EVENT_FOCUSIN, event => this._onInteraction(event, true));\n    EventHandler.on(this._element, EVENT_FOCUSOUT, event => this._onInteraction(event, false));\n  }\n\n  _clearTimeout() {\n    clearTimeout(this._timeout);\n    this._timeout = null;\n  } // Static\n\n\n  static jQueryInterface(config) {\n    return this.each(function () {\n      const data = Toast.getOrCreateInstance(this, config);\n\n      if (typeof config === 'string') {\n        if (typeof data[config] === 'undefined') {\n          throw new TypeError(`No method named \"${config}\"`);\n        }\n\n        data[config](this);\n      }\n    });\n  }\n\n}\n\nenableDismissTrigger(Toast);\n/**\n * ------------------------------------------------------------------------\n * jQuery\n * ------------------------------------------------------------------------\n * add .Toast to jQuery only if jQuery is present\n */\n\ndefineJQueryPlugin(Toast);\n\nexport { Alert, Button, Carousel, Collapse, Dropdown, Modal, Offcanvas, Popover, ScrollSpy, Tab, Toast, Tooltip };\n//# sourceMappingURL=bootstrap.esm.js.map\n"
  },
  {
    "path": "sample/src/NimblePros.SampleToDo.Web/wwwroot/lib/bootstrap/dist/js/bootstrap.js",
    "content": "/*!\n  * Bootstrap v5.1.0 (https://getbootstrap.com/)\n  * Copyright 2011-2021 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors)\n  * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n  */\n(function (global, factory) {\n  typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('@popperjs/core')) :\n  typeof define === 'function' && define.amd ? define(['@popperjs/core'], factory) :\n  (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.bootstrap = factory(global.Popper));\n}(this, (function (Popper) { 'use strict';\n\n  function _interopNamespace(e) {\n    if (e && e.__esModule) return e;\n    var n = Object.create(null);\n    if (e) {\n      Object.keys(e).forEach(function (k) {\n        if (k !== 'default') {\n          var d = Object.getOwnPropertyDescriptor(e, k);\n          Object.defineProperty(n, k, d.get ? d : {\n            enumerable: true,\n            get: function () {\n              return e[k];\n            }\n          });\n        }\n      });\n    }\n    n['default'] = e;\n    return Object.freeze(n);\n  }\n\n  var Popper__namespace = /*#__PURE__*/_interopNamespace(Popper);\n\n  /**\n   * --------------------------------------------------------------------------\n   * Bootstrap (v5.1.0): util/index.js\n   * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n   * --------------------------------------------------------------------------\n   */\n  const MAX_UID = 1000000;\n  const MILLISECONDS_MULTIPLIER = 1000;\n  const TRANSITION_END = 'transitionend'; // Shoutout AngusCroll (https://goo.gl/pxwQGp)\n\n  const toType = obj => {\n    if (obj === null || obj === undefined) {\n      return `${obj}`;\n    }\n\n    return {}.toString.call(obj).match(/\\s([a-z]+)/i)[1].toLowerCase();\n  };\n  /**\n   * --------------------------------------------------------------------------\n   * Public Util Api\n   * --------------------------------------------------------------------------\n   */\n\n\n  const getUID = prefix => {\n    do {\n      prefix += Math.floor(Math.random() * MAX_UID);\n    } while (document.getElementById(prefix));\n\n    return prefix;\n  };\n\n  const getSelector = element => {\n    let selector = element.getAttribute('data-bs-target');\n\n    if (!selector || selector === '#') {\n      let hrefAttr = element.getAttribute('href'); // The only valid content that could double as a selector are IDs or classes,\n      // so everything starting with `#` or `.`. If a \"real\" URL is used as the selector,\n      // `document.querySelector` will rightfully complain it is invalid.\n      // See https://github.com/twbs/bootstrap/issues/32273\n\n      if (!hrefAttr || !hrefAttr.includes('#') && !hrefAttr.startsWith('.')) {\n        return null;\n      } // Just in case some CMS puts out a full URL with the anchor appended\n\n\n      if (hrefAttr.includes('#') && !hrefAttr.startsWith('#')) {\n        hrefAttr = `#${hrefAttr.split('#')[1]}`;\n      }\n\n      selector = hrefAttr && hrefAttr !== '#' ? hrefAttr.trim() : null;\n    }\n\n    return selector;\n  };\n\n  const getSelectorFromElement = element => {\n    const selector = getSelector(element);\n\n    if (selector) {\n      return document.querySelector(selector) ? selector : null;\n    }\n\n    return null;\n  };\n\n  const getElementFromSelector = element => {\n    const selector = getSelector(element);\n    return selector ? document.querySelector(selector) : null;\n  };\n\n  const getTransitionDurationFromElement = element => {\n    if (!element) {\n      return 0;\n    } // Get transition-duration of the element\n\n\n    let {\n      transitionDuration,\n      transitionDelay\n    } = window.getComputedStyle(element);\n    const floatTransitionDuration = Number.parseFloat(transitionDuration);\n    const floatTransitionDelay = Number.parseFloat(transitionDelay); // Return 0 if element or transition duration is not found\n\n    if (!floatTransitionDuration && !floatTransitionDelay) {\n      return 0;\n    } // If multiple durations are defined, take the first\n\n\n    transitionDuration = transitionDuration.split(',')[0];\n    transitionDelay = transitionDelay.split(',')[0];\n    return (Number.parseFloat(transitionDuration) + Number.parseFloat(transitionDelay)) * MILLISECONDS_MULTIPLIER;\n  };\n\n  const triggerTransitionEnd = element => {\n    element.dispatchEvent(new Event(TRANSITION_END));\n  };\n\n  const isElement = obj => {\n    if (!obj || typeof obj !== 'object') {\n      return false;\n    }\n\n    if (typeof obj.jquery !== 'undefined') {\n      obj = obj[0];\n    }\n\n    return typeof obj.nodeType !== 'undefined';\n  };\n\n  const getElement = obj => {\n    if (isElement(obj)) {\n      // it's a jQuery object or a node element\n      return obj.jquery ? obj[0] : obj;\n    }\n\n    if (typeof obj === 'string' && obj.length > 0) {\n      return document.querySelector(obj);\n    }\n\n    return null;\n  };\n\n  const typeCheckConfig = (componentName, config, configTypes) => {\n    Object.keys(configTypes).forEach(property => {\n      const expectedTypes = configTypes[property];\n      const value = config[property];\n      const valueType = value && isElement(value) ? 'element' : toType(value);\n\n      if (!new RegExp(expectedTypes).test(valueType)) {\n        throw new TypeError(`${componentName.toUpperCase()}: Option \"${property}\" provided type \"${valueType}\" but expected type \"${expectedTypes}\".`);\n      }\n    });\n  };\n\n  const isVisible = element => {\n    if (!isElement(element) || element.getClientRects().length === 0) {\n      return false;\n    }\n\n    return getComputedStyle(element).getPropertyValue('visibility') === 'visible';\n  };\n\n  const isDisabled = element => {\n    if (!element || element.nodeType !== Node.ELEMENT_NODE) {\n      return true;\n    }\n\n    if (element.classList.contains('disabled')) {\n      return true;\n    }\n\n    if (typeof element.disabled !== 'undefined') {\n      return element.disabled;\n    }\n\n    return element.hasAttribute('disabled') && element.getAttribute('disabled') !== 'false';\n  };\n\n  const findShadowRoot = element => {\n    if (!document.documentElement.attachShadow) {\n      return null;\n    } // Can find the shadow root otherwise it'll return the document\n\n\n    if (typeof element.getRootNode === 'function') {\n      const root = element.getRootNode();\n      return root instanceof ShadowRoot ? root : null;\n    }\n\n    if (element instanceof ShadowRoot) {\n      return element;\n    } // when we don't find a shadow root\n\n\n    if (!element.parentNode) {\n      return null;\n    }\n\n    return findShadowRoot(element.parentNode);\n  };\n\n  const noop = () => {};\n  /**\n   * Trick to restart an element's animation\n   *\n   * @param {HTMLElement} element\n   * @return void\n   *\n   * @see https://www.charistheo.io/blog/2021/02/restart-a-css-animation-with-javascript/#restarting-a-css-animation\n   */\n\n\n  const reflow = element => {\n    // eslint-disable-next-line no-unused-expressions\n    element.offsetHeight;\n  };\n\n  const getjQuery = () => {\n    const {\n      jQuery\n    } = window;\n\n    if (jQuery && !document.body.hasAttribute('data-bs-no-jquery')) {\n      return jQuery;\n    }\n\n    return null;\n  };\n\n  const DOMContentLoadedCallbacks = [];\n\n  const onDOMContentLoaded = callback => {\n    if (document.readyState === 'loading') {\n      // add listener on the first call when the document is in loading state\n      if (!DOMContentLoadedCallbacks.length) {\n        document.addEventListener('DOMContentLoaded', () => {\n          DOMContentLoadedCallbacks.forEach(callback => callback());\n        });\n      }\n\n      DOMContentLoadedCallbacks.push(callback);\n    } else {\n      callback();\n    }\n  };\n\n  const isRTL = () => document.documentElement.dir === 'rtl';\n\n  const defineJQueryPlugin = plugin => {\n    onDOMContentLoaded(() => {\n      const $ = getjQuery();\n      /* istanbul ignore if */\n\n      if ($) {\n        const name = plugin.NAME;\n        const JQUERY_NO_CONFLICT = $.fn[name];\n        $.fn[name] = plugin.jQueryInterface;\n        $.fn[name].Constructor = plugin;\n\n        $.fn[name].noConflict = () => {\n          $.fn[name] = JQUERY_NO_CONFLICT;\n          return plugin.jQueryInterface;\n        };\n      }\n    });\n  };\n\n  const execute = callback => {\n    if (typeof callback === 'function') {\n      callback();\n    }\n  };\n\n  const executeAfterTransition = (callback, transitionElement, waitForTransition = true) => {\n    if (!waitForTransition) {\n      execute(callback);\n      return;\n    }\n\n    const durationPadding = 5;\n    const emulatedDuration = getTransitionDurationFromElement(transitionElement) + durationPadding;\n    let called = false;\n\n    const handler = ({\n      target\n    }) => {\n      if (target !== transitionElement) {\n        return;\n      }\n\n      called = true;\n      transitionElement.removeEventListener(TRANSITION_END, handler);\n      execute(callback);\n    };\n\n    transitionElement.addEventListener(TRANSITION_END, handler);\n    setTimeout(() => {\n      if (!called) {\n        triggerTransitionEnd(transitionElement);\n      }\n    }, emulatedDuration);\n  };\n  /**\n   * Return the previous/next element of a list.\n   *\n   * @param {array} list    The list of elements\n   * @param activeElement   The active element\n   * @param shouldGetNext   Choose to get next or previous element\n   * @param isCycleAllowed\n   * @return {Element|elem} The proper element\n   */\n\n\n  const getNextActiveElement = (list, activeElement, shouldGetNext, isCycleAllowed) => {\n    let index = list.indexOf(activeElement); // if the element does not exist in the list return an element depending on the direction and if cycle is allowed\n\n    if (index === -1) {\n      return list[!shouldGetNext && isCycleAllowed ? list.length - 1 : 0];\n    }\n\n    const listLength = list.length;\n    index += shouldGetNext ? 1 : -1;\n\n    if (isCycleAllowed) {\n      index = (index + listLength) % listLength;\n    }\n\n    return list[Math.max(0, Math.min(index, listLength - 1))];\n  };\n\n  /**\n   * --------------------------------------------------------------------------\n   * Bootstrap (v5.1.0): dom/event-handler.js\n   * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n   * --------------------------------------------------------------------------\n   */\n  /**\n   * ------------------------------------------------------------------------\n   * Constants\n   * ------------------------------------------------------------------------\n   */\n\n  const namespaceRegex = /[^.]*(?=\\..*)\\.|.*/;\n  const stripNameRegex = /\\..*/;\n  const stripUidRegex = /::\\d+$/;\n  const eventRegistry = {}; // Events storage\n\n  let uidEvent = 1;\n  const customEvents = {\n    mouseenter: 'mouseover',\n    mouseleave: 'mouseout'\n  };\n  const customEventsRegex = /^(mouseenter|mouseleave)/i;\n  const nativeEvents = 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']);\n  /**\n   * ------------------------------------------------------------------------\n   * Private methods\n   * ------------------------------------------------------------------------\n   */\n\n  function getUidEvent(element, uid) {\n    return uid && `${uid}::${uidEvent++}` || element.uidEvent || uidEvent++;\n  }\n\n  function getEvent(element) {\n    const uid = getUidEvent(element);\n    element.uidEvent = uid;\n    eventRegistry[uid] = eventRegistry[uid] || {};\n    return eventRegistry[uid];\n  }\n\n  function bootstrapHandler(element, fn) {\n    return function handler(event) {\n      event.delegateTarget = element;\n\n      if (handler.oneOff) {\n        EventHandler.off(element, event.type, fn);\n      }\n\n      return fn.apply(element, [event]);\n    };\n  }\n\n  function bootstrapDelegationHandler(element, selector, fn) {\n    return function handler(event) {\n      const domElements = element.querySelectorAll(selector);\n\n      for (let {\n        target\n      } = event; target && target !== this; target = target.parentNode) {\n        for (let i = domElements.length; i--;) {\n          if (domElements[i] === target) {\n            event.delegateTarget = target;\n\n            if (handler.oneOff) {\n              // eslint-disable-next-line unicorn/consistent-destructuring\n              EventHandler.off(element, event.type, selector, fn);\n            }\n\n            return fn.apply(target, [event]);\n          }\n        }\n      } // To please ESLint\n\n\n      return null;\n    };\n  }\n\n  function findHandler(events, handler, delegationSelector = null) {\n    const uidEventList = Object.keys(events);\n\n    for (let i = 0, len = uidEventList.length; i < len; i++) {\n      const event = events[uidEventList[i]];\n\n      if (event.originalHandler === handler && event.delegationSelector === delegationSelector) {\n        return event;\n      }\n    }\n\n    return null;\n  }\n\n  function normalizeParams(originalTypeEvent, handler, delegationFn) {\n    const delegation = typeof handler === 'string';\n    const originalHandler = delegation ? delegationFn : handler;\n    let typeEvent = getTypeEvent(originalTypeEvent);\n    const isNative = nativeEvents.has(typeEvent);\n\n    if (!isNative) {\n      typeEvent = originalTypeEvent;\n    }\n\n    return [delegation, originalHandler, typeEvent];\n  }\n\n  function addHandler(element, originalTypeEvent, handler, delegationFn, oneOff) {\n    if (typeof originalTypeEvent !== 'string' || !element) {\n      return;\n    }\n\n    if (!handler) {\n      handler = delegationFn;\n      delegationFn = null;\n    } // in case of mouseenter or mouseleave wrap the handler within a function that checks for its DOM position\n    // this prevents the handler from being dispatched the same way as mouseover or mouseout does\n\n\n    if (customEventsRegex.test(originalTypeEvent)) {\n      const wrapFn = fn => {\n        return function (event) {\n          if (!event.relatedTarget || event.relatedTarget !== event.delegateTarget && !event.delegateTarget.contains(event.relatedTarget)) {\n            return fn.call(this, event);\n          }\n        };\n      };\n\n      if (delegationFn) {\n        delegationFn = wrapFn(delegationFn);\n      } else {\n        handler = wrapFn(handler);\n      }\n    }\n\n    const [delegation, originalHandler, typeEvent] = normalizeParams(originalTypeEvent, handler, delegationFn);\n    const events = getEvent(element);\n    const handlers = events[typeEvent] || (events[typeEvent] = {});\n    const previousFn = findHandler(handlers, originalHandler, delegation ? handler : null);\n\n    if (previousFn) {\n      previousFn.oneOff = previousFn.oneOff && oneOff;\n      return;\n    }\n\n    const uid = getUidEvent(originalHandler, originalTypeEvent.replace(namespaceRegex, ''));\n    const fn = delegation ? bootstrapDelegationHandler(element, handler, delegationFn) : bootstrapHandler(element, handler);\n    fn.delegationSelector = delegation ? handler : null;\n    fn.originalHandler = originalHandler;\n    fn.oneOff = oneOff;\n    fn.uidEvent = uid;\n    handlers[uid] = fn;\n    element.addEventListener(typeEvent, fn, delegation);\n  }\n\n  function removeHandler(element, events, typeEvent, handler, delegationSelector) {\n    const fn = findHandler(events[typeEvent], handler, delegationSelector);\n\n    if (!fn) {\n      return;\n    }\n\n    element.removeEventListener(typeEvent, fn, Boolean(delegationSelector));\n    delete events[typeEvent][fn.uidEvent];\n  }\n\n  function removeNamespacedHandlers(element, events, typeEvent, namespace) {\n    const storeElementEvent = events[typeEvent] || {};\n    Object.keys(storeElementEvent).forEach(handlerKey => {\n      if (handlerKey.includes(namespace)) {\n        const event = storeElementEvent[handlerKey];\n        removeHandler(element, events, typeEvent, event.originalHandler, event.delegationSelector);\n      }\n    });\n  }\n\n  function getTypeEvent(event) {\n    // allow to get the native events from namespaced events ('click.bs.button' --> 'click')\n    event = event.replace(stripNameRegex, '');\n    return customEvents[event] || event;\n  }\n\n  const EventHandler = {\n    on(element, event, handler, delegationFn) {\n      addHandler(element, event, handler, delegationFn, false);\n    },\n\n    one(element, event, handler, delegationFn) {\n      addHandler(element, event, handler, delegationFn, true);\n    },\n\n    off(element, originalTypeEvent, handler, delegationFn) {\n      if (typeof originalTypeEvent !== 'string' || !element) {\n        return;\n      }\n\n      const [delegation, originalHandler, typeEvent] = normalizeParams(originalTypeEvent, handler, delegationFn);\n      const inNamespace = typeEvent !== originalTypeEvent;\n      const events = getEvent(element);\n      const isNamespace = originalTypeEvent.startsWith('.');\n\n      if (typeof originalHandler !== 'undefined') {\n        // Simplest case: handler is passed, remove that listener ONLY.\n        if (!events || !events[typeEvent]) {\n          return;\n        }\n\n        removeHandler(element, events, typeEvent, originalHandler, delegation ? handler : null);\n        return;\n      }\n\n      if (isNamespace) {\n        Object.keys(events).forEach(elementEvent => {\n          removeNamespacedHandlers(element, events, elementEvent, originalTypeEvent.slice(1));\n        });\n      }\n\n      const storeElementEvent = events[typeEvent] || {};\n      Object.keys(storeElementEvent).forEach(keyHandlers => {\n        const handlerKey = keyHandlers.replace(stripUidRegex, '');\n\n        if (!inNamespace || originalTypeEvent.includes(handlerKey)) {\n          const event = storeElementEvent[keyHandlers];\n          removeHandler(element, events, typeEvent, event.originalHandler, event.delegationSelector);\n        }\n      });\n    },\n\n    trigger(element, event, args) {\n      if (typeof event !== 'string' || !element) {\n        return null;\n      }\n\n      const $ = getjQuery();\n      const typeEvent = getTypeEvent(event);\n      const inNamespace = event !== typeEvent;\n      const isNative = nativeEvents.has(typeEvent);\n      let jQueryEvent;\n      let bubbles = true;\n      let nativeDispatch = true;\n      let defaultPrevented = false;\n      let evt = null;\n\n      if (inNamespace && $) {\n        jQueryEvent = $.Event(event, args);\n        $(element).trigger(jQueryEvent);\n        bubbles = !jQueryEvent.isPropagationStopped();\n        nativeDispatch = !jQueryEvent.isImmediatePropagationStopped();\n        defaultPrevented = jQueryEvent.isDefaultPrevented();\n      }\n\n      if (isNative) {\n        evt = document.createEvent('HTMLEvents');\n        evt.initEvent(typeEvent, bubbles, true);\n      } else {\n        evt = new CustomEvent(event, {\n          bubbles,\n          cancelable: true\n        });\n      } // merge custom information in our event\n\n\n      if (typeof args !== 'undefined') {\n        Object.keys(args).forEach(key => {\n          Object.defineProperty(evt, key, {\n            get() {\n              return args[key];\n            }\n\n          });\n        });\n      }\n\n      if (defaultPrevented) {\n        evt.preventDefault();\n      }\n\n      if (nativeDispatch) {\n        element.dispatchEvent(evt);\n      }\n\n      if (evt.defaultPrevented && typeof jQueryEvent !== 'undefined') {\n        jQueryEvent.preventDefault();\n      }\n\n      return evt;\n    }\n\n  };\n\n  /**\n   * --------------------------------------------------------------------------\n   * Bootstrap (v5.1.0): dom/data.js\n   * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n   * --------------------------------------------------------------------------\n   */\n\n  /**\n   * ------------------------------------------------------------------------\n   * Constants\n   * ------------------------------------------------------------------------\n   */\n  const elementMap = new Map();\n  var Data = {\n    set(element, key, instance) {\n      if (!elementMap.has(element)) {\n        elementMap.set(element, new Map());\n      }\n\n      const instanceMap = elementMap.get(element); // make it clear we only want one instance per element\n      // can be removed later when multiple key/instances are fine to be used\n\n      if (!instanceMap.has(key) && instanceMap.size !== 0) {\n        // eslint-disable-next-line no-console\n        console.error(`Bootstrap doesn't allow more than one instance per element. Bound instance: ${Array.from(instanceMap.keys())[0]}.`);\n        return;\n      }\n\n      instanceMap.set(key, instance);\n    },\n\n    get(element, key) {\n      if (elementMap.has(element)) {\n        return elementMap.get(element).get(key) || null;\n      }\n\n      return null;\n    },\n\n    remove(element, key) {\n      if (!elementMap.has(element)) {\n        return;\n      }\n\n      const instanceMap = elementMap.get(element);\n      instanceMap.delete(key); // free up element references if there are no instances left for an element\n\n      if (instanceMap.size === 0) {\n        elementMap.delete(element);\n      }\n    }\n\n  };\n\n  /**\n   * --------------------------------------------------------------------------\n   * Bootstrap (v5.1.0): base-component.js\n   * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n   * --------------------------------------------------------------------------\n   */\n  /**\n   * ------------------------------------------------------------------------\n   * Constants\n   * ------------------------------------------------------------------------\n   */\n\n  const VERSION = '5.1.0';\n\n  class BaseComponent {\n    constructor(element) {\n      element = getElement(element);\n\n      if (!element) {\n        return;\n      }\n\n      this._element = element;\n      Data.set(this._element, this.constructor.DATA_KEY, this);\n    }\n\n    dispose() {\n      Data.remove(this._element, this.constructor.DATA_KEY);\n      EventHandler.off(this._element, this.constructor.EVENT_KEY);\n      Object.getOwnPropertyNames(this).forEach(propertyName => {\n        this[propertyName] = null;\n      });\n    }\n\n    _queueCallback(callback, element, isAnimated = true) {\n      executeAfterTransition(callback, element, isAnimated);\n    }\n    /** Static */\n\n\n    static getInstance(element) {\n      return Data.get(getElement(element), this.DATA_KEY);\n    }\n\n    static getOrCreateInstance(element, config = {}) {\n      return this.getInstance(element) || new this(element, typeof config === 'object' ? config : null);\n    }\n\n    static get VERSION() {\n      return VERSION;\n    }\n\n    static get NAME() {\n      throw new Error('You have to implement the static method \"NAME\", for each component!');\n    }\n\n    static get DATA_KEY() {\n      return `bs.${this.NAME}`;\n    }\n\n    static get EVENT_KEY() {\n      return `.${this.DATA_KEY}`;\n    }\n\n  }\n\n  /**\n   * --------------------------------------------------------------------------\n   * Bootstrap (v5.1.0): util/component-functions.js\n   * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n   * --------------------------------------------------------------------------\n   */\n\n  const enableDismissTrigger = (component, method = 'hide') => {\n    const clickEvent = `click.dismiss${component.EVENT_KEY}`;\n    const name = component.NAME;\n    EventHandler.on(document, clickEvent, `[data-bs-dismiss=\"${name}\"]`, function (event) {\n      if (['A', 'AREA'].includes(this.tagName)) {\n        event.preventDefault();\n      }\n\n      if (isDisabled(this)) {\n        return;\n      }\n\n      const target = getElementFromSelector(this) || this.closest(`.${name}`);\n      const instance = component.getOrCreateInstance(target); // Method argument is left, for Alert and only, as it doesn't implement the 'hide' method\n\n      instance[method]();\n    });\n  };\n\n  /**\n   * --------------------------------------------------------------------------\n   * Bootstrap (v5.1.0): alert.js\n   * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n   * --------------------------------------------------------------------------\n   */\n  /**\n   * ------------------------------------------------------------------------\n   * Constants\n   * ------------------------------------------------------------------------\n   */\n\n  const NAME$d = 'alert';\n  const DATA_KEY$c = 'bs.alert';\n  const EVENT_KEY$c = `.${DATA_KEY$c}`;\n  const EVENT_CLOSE = `close${EVENT_KEY$c}`;\n  const EVENT_CLOSED = `closed${EVENT_KEY$c}`;\n  const CLASS_NAME_FADE$5 = 'fade';\n  const CLASS_NAME_SHOW$8 = 'show';\n  /**\n   * ------------------------------------------------------------------------\n   * Class Definition\n   * ------------------------------------------------------------------------\n   */\n\n  class Alert extends BaseComponent {\n    // Getters\n    static get NAME() {\n      return NAME$d;\n    } // Public\n\n\n    close() {\n      const closeEvent = EventHandler.trigger(this._element, EVENT_CLOSE);\n\n      if (closeEvent.defaultPrevented) {\n        return;\n      }\n\n      this._element.classList.remove(CLASS_NAME_SHOW$8);\n\n      const isAnimated = this._element.classList.contains(CLASS_NAME_FADE$5);\n\n      this._queueCallback(() => this._destroyElement(), this._element, isAnimated);\n    } // Private\n\n\n    _destroyElement() {\n      this._element.remove();\n\n      EventHandler.trigger(this._element, EVENT_CLOSED);\n      this.dispose();\n    } // Static\n\n\n    static jQueryInterface(config) {\n      return this.each(function () {\n        const data = Alert.getOrCreateInstance(this);\n\n        if (typeof config !== 'string') {\n          return;\n        }\n\n        if (data[config] === undefined || config.startsWith('_') || config === 'constructor') {\n          throw new TypeError(`No method named \"${config}\"`);\n        }\n\n        data[config](this);\n      });\n    }\n\n  }\n  /**\n   * ------------------------------------------------------------------------\n   * Data Api implementation\n   * ------------------------------------------------------------------------\n   */\n\n\n  enableDismissTrigger(Alert, 'close');\n  /**\n   * ------------------------------------------------------------------------\n   * jQuery\n   * ------------------------------------------------------------------------\n   * add .Alert to jQuery only if jQuery is present\n   */\n\n  defineJQueryPlugin(Alert);\n\n  /**\n   * --------------------------------------------------------------------------\n   * Bootstrap (v5.1.0): button.js\n   * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n   * --------------------------------------------------------------------------\n   */\n  /**\n   * ------------------------------------------------------------------------\n   * Constants\n   * ------------------------------------------------------------------------\n   */\n\n  const NAME$c = 'button';\n  const DATA_KEY$b = 'bs.button';\n  const EVENT_KEY$b = `.${DATA_KEY$b}`;\n  const DATA_API_KEY$7 = '.data-api';\n  const CLASS_NAME_ACTIVE$3 = 'active';\n  const SELECTOR_DATA_TOGGLE$5 = '[data-bs-toggle=\"button\"]';\n  const EVENT_CLICK_DATA_API$6 = `click${EVENT_KEY$b}${DATA_API_KEY$7}`;\n  /**\n   * ------------------------------------------------------------------------\n   * Class Definition\n   * ------------------------------------------------------------------------\n   */\n\n  class Button extends BaseComponent {\n    // Getters\n    static get NAME() {\n      return NAME$c;\n    } // Public\n\n\n    toggle() {\n      // Toggle class and sync the `aria-pressed` attribute with the return value of the `.toggle()` method\n      this._element.setAttribute('aria-pressed', this._element.classList.toggle(CLASS_NAME_ACTIVE$3));\n    } // Static\n\n\n    static jQueryInterface(config) {\n      return this.each(function () {\n        const data = Button.getOrCreateInstance(this);\n\n        if (config === 'toggle') {\n          data[config]();\n        }\n      });\n    }\n\n  }\n  /**\n   * ------------------------------------------------------------------------\n   * Data Api implementation\n   * ------------------------------------------------------------------------\n   */\n\n\n  EventHandler.on(document, EVENT_CLICK_DATA_API$6, SELECTOR_DATA_TOGGLE$5, event => {\n    event.preventDefault();\n    const button = event.target.closest(SELECTOR_DATA_TOGGLE$5);\n    const data = Button.getOrCreateInstance(button);\n    data.toggle();\n  });\n  /**\n   * ------------------------------------------------------------------------\n   * jQuery\n   * ------------------------------------------------------------------------\n   * add .Button to jQuery only if jQuery is present\n   */\n\n  defineJQueryPlugin(Button);\n\n  /**\n   * --------------------------------------------------------------------------\n   * Bootstrap (v5.1.0): dom/manipulator.js\n   * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n   * --------------------------------------------------------------------------\n   */\n  function normalizeData(val) {\n    if (val === 'true') {\n      return true;\n    }\n\n    if (val === 'false') {\n      return false;\n    }\n\n    if (val === Number(val).toString()) {\n      return Number(val);\n    }\n\n    if (val === '' || val === 'null') {\n      return null;\n    }\n\n    return val;\n  }\n\n  function normalizeDataKey(key) {\n    return key.replace(/[A-Z]/g, chr => `-${chr.toLowerCase()}`);\n  }\n\n  const Manipulator = {\n    setDataAttribute(element, key, value) {\n      element.setAttribute(`data-bs-${normalizeDataKey(key)}`, value);\n    },\n\n    removeDataAttribute(element, key) {\n      element.removeAttribute(`data-bs-${normalizeDataKey(key)}`);\n    },\n\n    getDataAttributes(element) {\n      if (!element) {\n        return {};\n      }\n\n      const attributes = {};\n      Object.keys(element.dataset).filter(key => key.startsWith('bs')).forEach(key => {\n        let pureKey = key.replace(/^bs/, '');\n        pureKey = pureKey.charAt(0).toLowerCase() + pureKey.slice(1, pureKey.length);\n        attributes[pureKey] = normalizeData(element.dataset[key]);\n      });\n      return attributes;\n    },\n\n    getDataAttribute(element, key) {\n      return normalizeData(element.getAttribute(`data-bs-${normalizeDataKey(key)}`));\n    },\n\n    offset(element) {\n      const rect = element.getBoundingClientRect();\n      return {\n        top: rect.top + window.pageYOffset,\n        left: rect.left + window.pageXOffset\n      };\n    },\n\n    position(element) {\n      return {\n        top: element.offsetTop,\n        left: element.offsetLeft\n      };\n    }\n\n  };\n\n  /**\n   * --------------------------------------------------------------------------\n   * Bootstrap (v5.1.0): dom/selector-engine.js\n   * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n   * --------------------------------------------------------------------------\n   */\n  const NODE_TEXT = 3;\n  const SelectorEngine = {\n    find(selector, element = document.documentElement) {\n      return [].concat(...Element.prototype.querySelectorAll.call(element, selector));\n    },\n\n    findOne(selector, element = document.documentElement) {\n      return Element.prototype.querySelector.call(element, selector);\n    },\n\n    children(element, selector) {\n      return [].concat(...element.children).filter(child => child.matches(selector));\n    },\n\n    parents(element, selector) {\n      const parents = [];\n      let ancestor = element.parentNode;\n\n      while (ancestor && ancestor.nodeType === Node.ELEMENT_NODE && ancestor.nodeType !== NODE_TEXT) {\n        if (ancestor.matches(selector)) {\n          parents.push(ancestor);\n        }\n\n        ancestor = ancestor.parentNode;\n      }\n\n      return parents;\n    },\n\n    prev(element, selector) {\n      let previous = element.previousElementSibling;\n\n      while (previous) {\n        if (previous.matches(selector)) {\n          return [previous];\n        }\n\n        previous = previous.previousElementSibling;\n      }\n\n      return [];\n    },\n\n    next(element, selector) {\n      let next = element.nextElementSibling;\n\n      while (next) {\n        if (next.matches(selector)) {\n          return [next];\n        }\n\n        next = next.nextElementSibling;\n      }\n\n      return [];\n    },\n\n    focusableChildren(element) {\n      const focusables = ['a', 'button', 'input', 'textarea', 'select', 'details', '[tabindex]', '[contenteditable=\"true\"]'].map(selector => `${selector}:not([tabindex^=\"-\"])`).join(', ');\n      return this.find(focusables, element).filter(el => !isDisabled(el) && isVisible(el));\n    }\n\n  };\n\n  /**\n   * --------------------------------------------------------------------------\n   * Bootstrap (v5.1.0): carousel.js\n   * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n   * --------------------------------------------------------------------------\n   */\n  /**\n   * ------------------------------------------------------------------------\n   * Constants\n   * ------------------------------------------------------------------------\n   */\n\n  const NAME$b = 'carousel';\n  const DATA_KEY$a = 'bs.carousel';\n  const EVENT_KEY$a = `.${DATA_KEY$a}`;\n  const DATA_API_KEY$6 = '.data-api';\n  const ARROW_LEFT_KEY = 'ArrowLeft';\n  const ARROW_RIGHT_KEY = 'ArrowRight';\n  const TOUCHEVENT_COMPAT_WAIT = 500; // Time for mouse compat events to fire after touch\n\n  const SWIPE_THRESHOLD = 40;\n  const Default$a = {\n    interval: 5000,\n    keyboard: true,\n    slide: false,\n    pause: 'hover',\n    wrap: true,\n    touch: true\n  };\n  const DefaultType$a = {\n    interval: '(number|boolean)',\n    keyboard: 'boolean',\n    slide: '(boolean|string)',\n    pause: '(string|boolean)',\n    wrap: 'boolean',\n    touch: 'boolean'\n  };\n  const ORDER_NEXT = 'next';\n  const ORDER_PREV = 'prev';\n  const DIRECTION_LEFT = 'left';\n  const DIRECTION_RIGHT = 'right';\n  const KEY_TO_DIRECTION = {\n    [ARROW_LEFT_KEY]: DIRECTION_RIGHT,\n    [ARROW_RIGHT_KEY]: DIRECTION_LEFT\n  };\n  const EVENT_SLIDE = `slide${EVENT_KEY$a}`;\n  const EVENT_SLID = `slid${EVENT_KEY$a}`;\n  const EVENT_KEYDOWN = `keydown${EVENT_KEY$a}`;\n  const EVENT_MOUSEENTER = `mouseenter${EVENT_KEY$a}`;\n  const EVENT_MOUSELEAVE = `mouseleave${EVENT_KEY$a}`;\n  const EVENT_TOUCHSTART = `touchstart${EVENT_KEY$a}`;\n  const EVENT_TOUCHMOVE = `touchmove${EVENT_KEY$a}`;\n  const EVENT_TOUCHEND = `touchend${EVENT_KEY$a}`;\n  const EVENT_POINTERDOWN = `pointerdown${EVENT_KEY$a}`;\n  const EVENT_POINTERUP = `pointerup${EVENT_KEY$a}`;\n  const EVENT_DRAG_START = `dragstart${EVENT_KEY$a}`;\n  const EVENT_LOAD_DATA_API$2 = `load${EVENT_KEY$a}${DATA_API_KEY$6}`;\n  const EVENT_CLICK_DATA_API$5 = `click${EVENT_KEY$a}${DATA_API_KEY$6}`;\n  const CLASS_NAME_CAROUSEL = 'carousel';\n  const CLASS_NAME_ACTIVE$2 = 'active';\n  const CLASS_NAME_SLIDE = 'slide';\n  const CLASS_NAME_END = 'carousel-item-end';\n  const CLASS_NAME_START = 'carousel-item-start';\n  const CLASS_NAME_NEXT = 'carousel-item-next';\n  const CLASS_NAME_PREV = 'carousel-item-prev';\n  const CLASS_NAME_POINTER_EVENT = 'pointer-event';\n  const SELECTOR_ACTIVE$1 = '.active';\n  const SELECTOR_ACTIVE_ITEM = '.active.carousel-item';\n  const SELECTOR_ITEM = '.carousel-item';\n  const SELECTOR_ITEM_IMG = '.carousel-item img';\n  const SELECTOR_NEXT_PREV = '.carousel-item-next, .carousel-item-prev';\n  const SELECTOR_INDICATORS = '.carousel-indicators';\n  const SELECTOR_INDICATOR = '[data-bs-target]';\n  const SELECTOR_DATA_SLIDE = '[data-bs-slide], [data-bs-slide-to]';\n  const SELECTOR_DATA_RIDE = '[data-bs-ride=\"carousel\"]';\n  const POINTER_TYPE_TOUCH = 'touch';\n  const POINTER_TYPE_PEN = 'pen';\n  /**\n   * ------------------------------------------------------------------------\n   * Class Definition\n   * ------------------------------------------------------------------------\n   */\n\n  class Carousel extends BaseComponent {\n    constructor(element, config) {\n      super(element);\n      this._items = null;\n      this._interval = null;\n      this._activeElement = null;\n      this._isPaused = false;\n      this._isSliding = false;\n      this.touchTimeout = null;\n      this.touchStartX = 0;\n      this.touchDeltaX = 0;\n      this._config = this._getConfig(config);\n      this._indicatorsElement = SelectorEngine.findOne(SELECTOR_INDICATORS, this._element);\n      this._touchSupported = 'ontouchstart' in document.documentElement || navigator.maxTouchPoints > 0;\n      this._pointerEvent = Boolean(window.PointerEvent);\n\n      this._addEventListeners();\n    } // Getters\n\n\n    static get Default() {\n      return Default$a;\n    }\n\n    static get NAME() {\n      return NAME$b;\n    } // Public\n\n\n    next() {\n      this._slide(ORDER_NEXT);\n    }\n\n    nextWhenVisible() {\n      // Don't call next when the page isn't visible\n      // or the carousel or its parent isn't visible\n      if (!document.hidden && isVisible(this._element)) {\n        this.next();\n      }\n    }\n\n    prev() {\n      this._slide(ORDER_PREV);\n    }\n\n    pause(event) {\n      if (!event) {\n        this._isPaused = true;\n      }\n\n      if (SelectorEngine.findOne(SELECTOR_NEXT_PREV, this._element)) {\n        triggerTransitionEnd(this._element);\n        this.cycle(true);\n      }\n\n      clearInterval(this._interval);\n      this._interval = null;\n    }\n\n    cycle(event) {\n      if (!event) {\n        this._isPaused = false;\n      }\n\n      if (this._interval) {\n        clearInterval(this._interval);\n        this._interval = null;\n      }\n\n      if (this._config && this._config.interval && !this._isPaused) {\n        this._updateInterval();\n\n        this._interval = setInterval((document.visibilityState ? this.nextWhenVisible : this.next).bind(this), this._config.interval);\n      }\n    }\n\n    to(index) {\n      this._activeElement = SelectorEngine.findOne(SELECTOR_ACTIVE_ITEM, this._element);\n\n      const activeIndex = this._getItemIndex(this._activeElement);\n\n      if (index > this._items.length - 1 || index < 0) {\n        return;\n      }\n\n      if (this._isSliding) {\n        EventHandler.one(this._element, EVENT_SLID, () => this.to(index));\n        return;\n      }\n\n      if (activeIndex === index) {\n        this.pause();\n        this.cycle();\n        return;\n      }\n\n      const order = index > activeIndex ? ORDER_NEXT : ORDER_PREV;\n\n      this._slide(order, this._items[index]);\n    } // Private\n\n\n    _getConfig(config) {\n      config = { ...Default$a,\n        ...Manipulator.getDataAttributes(this._element),\n        ...(typeof config === 'object' ? config : {})\n      };\n      typeCheckConfig(NAME$b, config, DefaultType$a);\n      return config;\n    }\n\n    _handleSwipe() {\n      const absDeltax = Math.abs(this.touchDeltaX);\n\n      if (absDeltax <= SWIPE_THRESHOLD) {\n        return;\n      }\n\n      const direction = absDeltax / this.touchDeltaX;\n      this.touchDeltaX = 0;\n\n      if (!direction) {\n        return;\n      }\n\n      this._slide(direction > 0 ? DIRECTION_RIGHT : DIRECTION_LEFT);\n    }\n\n    _addEventListeners() {\n      if (this._config.keyboard) {\n        EventHandler.on(this._element, EVENT_KEYDOWN, event => this._keydown(event));\n      }\n\n      if (this._config.pause === 'hover') {\n        EventHandler.on(this._element, EVENT_MOUSEENTER, event => this.pause(event));\n        EventHandler.on(this._element, EVENT_MOUSELEAVE, event => this.cycle(event));\n      }\n\n      if (this._config.touch && this._touchSupported) {\n        this._addTouchEventListeners();\n      }\n    }\n\n    _addTouchEventListeners() {\n      const start = event => {\n        if (this._pointerEvent && (event.pointerType === POINTER_TYPE_PEN || event.pointerType === POINTER_TYPE_TOUCH)) {\n          this.touchStartX = event.clientX;\n        } else if (!this._pointerEvent) {\n          this.touchStartX = event.touches[0].clientX;\n        }\n      };\n\n      const move = event => {\n        // ensure swiping with one touch and not pinching\n        this.touchDeltaX = event.touches && event.touches.length > 1 ? 0 : event.touches[0].clientX - this.touchStartX;\n      };\n\n      const end = event => {\n        if (this._pointerEvent && (event.pointerType === POINTER_TYPE_PEN || event.pointerType === POINTER_TYPE_TOUCH)) {\n          this.touchDeltaX = event.clientX - this.touchStartX;\n        }\n\n        this._handleSwipe();\n\n        if (this._config.pause === 'hover') {\n          // If it's a touch-enabled device, mouseenter/leave are fired as\n          // part of the mouse compatibility events on first tap - the carousel\n          // would stop cycling until user tapped out of it;\n          // here, we listen for touchend, explicitly pause the carousel\n          // (as if it's the second time we tap on it, mouseenter compat event\n          // is NOT fired) and after a timeout (to allow for mouse compatibility\n          // events to fire) we explicitly restart cycling\n          this.pause();\n\n          if (this.touchTimeout) {\n            clearTimeout(this.touchTimeout);\n          }\n\n          this.touchTimeout = setTimeout(event => this.cycle(event), TOUCHEVENT_COMPAT_WAIT + this._config.interval);\n        }\n      };\n\n      SelectorEngine.find(SELECTOR_ITEM_IMG, this._element).forEach(itemImg => {\n        EventHandler.on(itemImg, EVENT_DRAG_START, e => e.preventDefault());\n      });\n\n      if (this._pointerEvent) {\n        EventHandler.on(this._element, EVENT_POINTERDOWN, event => start(event));\n        EventHandler.on(this._element, EVENT_POINTERUP, event => end(event));\n\n        this._element.classList.add(CLASS_NAME_POINTER_EVENT);\n      } else {\n        EventHandler.on(this._element, EVENT_TOUCHSTART, event => start(event));\n        EventHandler.on(this._element, EVENT_TOUCHMOVE, event => move(event));\n        EventHandler.on(this._element, EVENT_TOUCHEND, event => end(event));\n      }\n    }\n\n    _keydown(event) {\n      if (/input|textarea/i.test(event.target.tagName)) {\n        return;\n      }\n\n      const direction = KEY_TO_DIRECTION[event.key];\n\n      if (direction) {\n        event.preventDefault();\n\n        this._slide(direction);\n      }\n    }\n\n    _getItemIndex(element) {\n      this._items = element && element.parentNode ? SelectorEngine.find(SELECTOR_ITEM, element.parentNode) : [];\n      return this._items.indexOf(element);\n    }\n\n    _getItemByOrder(order, activeElement) {\n      const isNext = order === ORDER_NEXT;\n      return getNextActiveElement(this._items, activeElement, isNext, this._config.wrap);\n    }\n\n    _triggerSlideEvent(relatedTarget, eventDirectionName) {\n      const targetIndex = this._getItemIndex(relatedTarget);\n\n      const fromIndex = this._getItemIndex(SelectorEngine.findOne(SELECTOR_ACTIVE_ITEM, this._element));\n\n      return EventHandler.trigger(this._element, EVENT_SLIDE, {\n        relatedTarget,\n        direction: eventDirectionName,\n        from: fromIndex,\n        to: targetIndex\n      });\n    }\n\n    _setActiveIndicatorElement(element) {\n      if (this._indicatorsElement) {\n        const activeIndicator = SelectorEngine.findOne(SELECTOR_ACTIVE$1, this._indicatorsElement);\n        activeIndicator.classList.remove(CLASS_NAME_ACTIVE$2);\n        activeIndicator.removeAttribute('aria-current');\n        const indicators = SelectorEngine.find(SELECTOR_INDICATOR, this._indicatorsElement);\n\n        for (let i = 0; i < indicators.length; i++) {\n          if (Number.parseInt(indicators[i].getAttribute('data-bs-slide-to'), 10) === this._getItemIndex(element)) {\n            indicators[i].classList.add(CLASS_NAME_ACTIVE$2);\n            indicators[i].setAttribute('aria-current', 'true');\n            break;\n          }\n        }\n      }\n    }\n\n    _updateInterval() {\n      const element = this._activeElement || SelectorEngine.findOne(SELECTOR_ACTIVE_ITEM, this._element);\n\n      if (!element) {\n        return;\n      }\n\n      const elementInterval = Number.parseInt(element.getAttribute('data-bs-interval'), 10);\n\n      if (elementInterval) {\n        this._config.defaultInterval = this._config.defaultInterval || this._config.interval;\n        this._config.interval = elementInterval;\n      } else {\n        this._config.interval = this._config.defaultInterval || this._config.interval;\n      }\n    }\n\n    _slide(directionOrOrder, element) {\n      const order = this._directionToOrder(directionOrOrder);\n\n      const activeElement = SelectorEngine.findOne(SELECTOR_ACTIVE_ITEM, this._element);\n\n      const activeElementIndex = this._getItemIndex(activeElement);\n\n      const nextElement = element || this._getItemByOrder(order, activeElement);\n\n      const nextElementIndex = this._getItemIndex(nextElement);\n\n      const isCycling = Boolean(this._interval);\n      const isNext = order === ORDER_NEXT;\n      const directionalClassName = isNext ? CLASS_NAME_START : CLASS_NAME_END;\n      const orderClassName = isNext ? CLASS_NAME_NEXT : CLASS_NAME_PREV;\n\n      const eventDirectionName = this._orderToDirection(order);\n\n      if (nextElement && nextElement.classList.contains(CLASS_NAME_ACTIVE$2)) {\n        this._isSliding = false;\n        return;\n      }\n\n      if (this._isSliding) {\n        return;\n      }\n\n      const slideEvent = this._triggerSlideEvent(nextElement, eventDirectionName);\n\n      if (slideEvent.defaultPrevented) {\n        return;\n      }\n\n      if (!activeElement || !nextElement) {\n        // Some weirdness is happening, so we bail\n        return;\n      }\n\n      this._isSliding = true;\n\n      if (isCycling) {\n        this.pause();\n      }\n\n      this._setActiveIndicatorElement(nextElement);\n\n      this._activeElement = nextElement;\n\n      const triggerSlidEvent = () => {\n        EventHandler.trigger(this._element, EVENT_SLID, {\n          relatedTarget: nextElement,\n          direction: eventDirectionName,\n          from: activeElementIndex,\n          to: nextElementIndex\n        });\n      };\n\n      if (this._element.classList.contains(CLASS_NAME_SLIDE)) {\n        nextElement.classList.add(orderClassName);\n        reflow(nextElement);\n        activeElement.classList.add(directionalClassName);\n        nextElement.classList.add(directionalClassName);\n\n        const completeCallBack = () => {\n          nextElement.classList.remove(directionalClassName, orderClassName);\n          nextElement.classList.add(CLASS_NAME_ACTIVE$2);\n          activeElement.classList.remove(CLASS_NAME_ACTIVE$2, orderClassName, directionalClassName);\n          this._isSliding = false;\n          setTimeout(triggerSlidEvent, 0);\n        };\n\n        this._queueCallback(completeCallBack, activeElement, true);\n      } else {\n        activeElement.classList.remove(CLASS_NAME_ACTIVE$2);\n        nextElement.classList.add(CLASS_NAME_ACTIVE$2);\n        this._isSliding = false;\n        triggerSlidEvent();\n      }\n\n      if (isCycling) {\n        this.cycle();\n      }\n    }\n\n    _directionToOrder(direction) {\n      if (![DIRECTION_RIGHT, DIRECTION_LEFT].includes(direction)) {\n        return direction;\n      }\n\n      if (isRTL()) {\n        return direction === DIRECTION_LEFT ? ORDER_PREV : ORDER_NEXT;\n      }\n\n      return direction === DIRECTION_LEFT ? ORDER_NEXT : ORDER_PREV;\n    }\n\n    _orderToDirection(order) {\n      if (![ORDER_NEXT, ORDER_PREV].includes(order)) {\n        return order;\n      }\n\n      if (isRTL()) {\n        return order === ORDER_PREV ? DIRECTION_LEFT : DIRECTION_RIGHT;\n      }\n\n      return order === ORDER_PREV ? DIRECTION_RIGHT : DIRECTION_LEFT;\n    } // Static\n\n\n    static carouselInterface(element, config) {\n      const data = Carousel.getOrCreateInstance(element, config);\n      let {\n        _config\n      } = data;\n\n      if (typeof config === 'object') {\n        _config = { ..._config,\n          ...config\n        };\n      }\n\n      const action = typeof config === 'string' ? config : _config.slide;\n\n      if (typeof config === 'number') {\n        data.to(config);\n      } else if (typeof action === 'string') {\n        if (typeof data[action] === 'undefined') {\n          throw new TypeError(`No method named \"${action}\"`);\n        }\n\n        data[action]();\n      } else if (_config.interval && _config.ride) {\n        data.pause();\n        data.cycle();\n      }\n    }\n\n    static jQueryInterface(config) {\n      return this.each(function () {\n        Carousel.carouselInterface(this, config);\n      });\n    }\n\n    static dataApiClickHandler(event) {\n      const target = getElementFromSelector(this);\n\n      if (!target || !target.classList.contains(CLASS_NAME_CAROUSEL)) {\n        return;\n      }\n\n      const config = { ...Manipulator.getDataAttributes(target),\n        ...Manipulator.getDataAttributes(this)\n      };\n      const slideIndex = this.getAttribute('data-bs-slide-to');\n\n      if (slideIndex) {\n        config.interval = false;\n      }\n\n      Carousel.carouselInterface(target, config);\n\n      if (slideIndex) {\n        Carousel.getInstance(target).to(slideIndex);\n      }\n\n      event.preventDefault();\n    }\n\n  }\n  /**\n   * ------------------------------------------------------------------------\n   * Data Api implementation\n   * ------------------------------------------------------------------------\n   */\n\n\n  EventHandler.on(document, EVENT_CLICK_DATA_API$5, SELECTOR_DATA_SLIDE, Carousel.dataApiClickHandler);\n  EventHandler.on(window, EVENT_LOAD_DATA_API$2, () => {\n    const carousels = SelectorEngine.find(SELECTOR_DATA_RIDE);\n\n    for (let i = 0, len = carousels.length; i < len; i++) {\n      Carousel.carouselInterface(carousels[i], Carousel.getInstance(carousels[i]));\n    }\n  });\n  /**\n   * ------------------------------------------------------------------------\n   * jQuery\n   * ------------------------------------------------------------------------\n   * add .Carousel to jQuery only if jQuery is present\n   */\n\n  defineJQueryPlugin(Carousel);\n\n  /**\n   * --------------------------------------------------------------------------\n   * Bootstrap (v5.1.0): collapse.js\n   * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n   * --------------------------------------------------------------------------\n   */\n  /**\n   * ------------------------------------------------------------------------\n   * Constants\n   * ------------------------------------------------------------------------\n   */\n\n  const NAME$a = 'collapse';\n  const DATA_KEY$9 = 'bs.collapse';\n  const EVENT_KEY$9 = `.${DATA_KEY$9}`;\n  const DATA_API_KEY$5 = '.data-api';\n  const Default$9 = {\n    toggle: true,\n    parent: null\n  };\n  const DefaultType$9 = {\n    toggle: 'boolean',\n    parent: '(null|element)'\n  };\n  const EVENT_SHOW$5 = `show${EVENT_KEY$9}`;\n  const EVENT_SHOWN$5 = `shown${EVENT_KEY$9}`;\n  const EVENT_HIDE$5 = `hide${EVENT_KEY$9}`;\n  const EVENT_HIDDEN$5 = `hidden${EVENT_KEY$9}`;\n  const EVENT_CLICK_DATA_API$4 = `click${EVENT_KEY$9}${DATA_API_KEY$5}`;\n  const CLASS_NAME_SHOW$7 = 'show';\n  const CLASS_NAME_COLLAPSE = 'collapse';\n  const CLASS_NAME_COLLAPSING = 'collapsing';\n  const CLASS_NAME_COLLAPSED = 'collapsed';\n  const CLASS_NAME_HORIZONTAL = 'collapse-horizontal';\n  const WIDTH = 'width';\n  const HEIGHT = 'height';\n  const SELECTOR_ACTIVES = '.show, .collapsing';\n  const SELECTOR_DATA_TOGGLE$4 = '[data-bs-toggle=\"collapse\"]';\n  /**\n   * ------------------------------------------------------------------------\n   * Class Definition\n   * ------------------------------------------------------------------------\n   */\n\n  class Collapse extends BaseComponent {\n    constructor(element, config) {\n      super(element);\n      this._isTransitioning = false;\n      this._config = this._getConfig(config);\n      this._triggerArray = [];\n      const toggleList = SelectorEngine.find(SELECTOR_DATA_TOGGLE$4);\n\n      for (let i = 0, len = toggleList.length; i < len; i++) {\n        const elem = toggleList[i];\n        const selector = getSelectorFromElement(elem);\n        const filterElement = SelectorEngine.find(selector).filter(foundElem => foundElem === this._element);\n\n        if (selector !== null && filterElement.length) {\n          this._selector = selector;\n\n          this._triggerArray.push(elem);\n        }\n      }\n\n      this._initializeChildren();\n\n      if (!this._config.parent) {\n        this._addAriaAndCollapsedClass(this._triggerArray, this._isShown());\n      }\n\n      if (this._config.toggle) {\n        this.toggle();\n      }\n    } // Getters\n\n\n    static get Default() {\n      return Default$9;\n    }\n\n    static get NAME() {\n      return NAME$a;\n    } // Public\n\n\n    toggle() {\n      if (this._isShown()) {\n        this.hide();\n      } else {\n        this.show();\n      }\n    }\n\n    show() {\n      if (this._isTransitioning || this._isShown()) {\n        return;\n      }\n\n      let actives = [];\n      let activesData;\n\n      if (this._config.parent) {\n        const children = SelectorEngine.find(`.${CLASS_NAME_COLLAPSE} .${CLASS_NAME_COLLAPSE}`, this._config.parent);\n        actives = SelectorEngine.find(SELECTOR_ACTIVES, this._config.parent).filter(elem => !children.includes(elem)); // remove children if greater depth\n      }\n\n      const container = SelectorEngine.findOne(this._selector);\n\n      if (actives.length) {\n        const tempActiveData = actives.find(elem => container !== elem);\n        activesData = tempActiveData ? Collapse.getInstance(tempActiveData) : null;\n\n        if (activesData && activesData._isTransitioning) {\n          return;\n        }\n      }\n\n      const startEvent = EventHandler.trigger(this._element, EVENT_SHOW$5);\n\n      if (startEvent.defaultPrevented) {\n        return;\n      }\n\n      actives.forEach(elemActive => {\n        if (container !== elemActive) {\n          Collapse.getOrCreateInstance(elemActive, {\n            toggle: false\n          }).hide();\n        }\n\n        if (!activesData) {\n          Data.set(elemActive, DATA_KEY$9, null);\n        }\n      });\n\n      const dimension = this._getDimension();\n\n      this._element.classList.remove(CLASS_NAME_COLLAPSE);\n\n      this._element.classList.add(CLASS_NAME_COLLAPSING);\n\n      this._element.style[dimension] = 0;\n\n      this._addAriaAndCollapsedClass(this._triggerArray, true);\n\n      this._isTransitioning = true;\n\n      const complete = () => {\n        this._isTransitioning = false;\n\n        this._element.classList.remove(CLASS_NAME_COLLAPSING);\n\n        this._element.classList.add(CLASS_NAME_COLLAPSE, CLASS_NAME_SHOW$7);\n\n        this._element.style[dimension] = '';\n        EventHandler.trigger(this._element, EVENT_SHOWN$5);\n      };\n\n      const capitalizedDimension = dimension[0].toUpperCase() + dimension.slice(1);\n      const scrollSize = `scroll${capitalizedDimension}`;\n\n      this._queueCallback(complete, this._element, true);\n\n      this._element.style[dimension] = `${this._element[scrollSize]}px`;\n    }\n\n    hide() {\n      if (this._isTransitioning || !this._isShown()) {\n        return;\n      }\n\n      const startEvent = EventHandler.trigger(this._element, EVENT_HIDE$5);\n\n      if (startEvent.defaultPrevented) {\n        return;\n      }\n\n      const dimension = this._getDimension();\n\n      this._element.style[dimension] = `${this._element.getBoundingClientRect()[dimension]}px`;\n      reflow(this._element);\n\n      this._element.classList.add(CLASS_NAME_COLLAPSING);\n\n      this._element.classList.remove(CLASS_NAME_COLLAPSE, CLASS_NAME_SHOW$7);\n\n      const triggerArrayLength = this._triggerArray.length;\n\n      for (let i = 0; i < triggerArrayLength; i++) {\n        const trigger = this._triggerArray[i];\n        const elem = getElementFromSelector(trigger);\n\n        if (elem && !this._isShown(elem)) {\n          this._addAriaAndCollapsedClass([trigger], false);\n        }\n      }\n\n      this._isTransitioning = true;\n\n      const complete = () => {\n        this._isTransitioning = false;\n\n        this._element.classList.remove(CLASS_NAME_COLLAPSING);\n\n        this._element.classList.add(CLASS_NAME_COLLAPSE);\n\n        EventHandler.trigger(this._element, EVENT_HIDDEN$5);\n      };\n\n      this._element.style[dimension] = '';\n\n      this._queueCallback(complete, this._element, true);\n    }\n\n    _isShown(element = this._element) {\n      return element.classList.contains(CLASS_NAME_SHOW$7);\n    } // Private\n\n\n    _getConfig(config) {\n      config = { ...Default$9,\n        ...Manipulator.getDataAttributes(this._element),\n        ...config\n      };\n      config.toggle = Boolean(config.toggle); // Coerce string values\n\n      config.parent = getElement(config.parent);\n      typeCheckConfig(NAME$a, config, DefaultType$9);\n      return config;\n    }\n\n    _getDimension() {\n      return this._element.classList.contains(CLASS_NAME_HORIZONTAL) ? WIDTH : HEIGHT;\n    }\n\n    _initializeChildren() {\n      if (!this._config.parent) {\n        return;\n      }\n\n      const children = SelectorEngine.find(`.${CLASS_NAME_COLLAPSE} .${CLASS_NAME_COLLAPSE}`, this._config.parent);\n      SelectorEngine.find(SELECTOR_DATA_TOGGLE$4, this._config.parent).filter(elem => !children.includes(elem)).forEach(element => {\n        const selected = getElementFromSelector(element);\n\n        if (selected) {\n          this._addAriaAndCollapsedClass([element], this._isShown(selected));\n        }\n      });\n    }\n\n    _addAriaAndCollapsedClass(triggerArray, isOpen) {\n      if (!triggerArray.length) {\n        return;\n      }\n\n      triggerArray.forEach(elem => {\n        if (isOpen) {\n          elem.classList.remove(CLASS_NAME_COLLAPSED);\n        } else {\n          elem.classList.add(CLASS_NAME_COLLAPSED);\n        }\n\n        elem.setAttribute('aria-expanded', isOpen);\n      });\n    } // Static\n\n\n    static jQueryInterface(config) {\n      return this.each(function () {\n        const _config = {};\n\n        if (typeof config === 'string' && /show|hide/.test(config)) {\n          _config.toggle = false;\n        }\n\n        const data = Collapse.getOrCreateInstance(this, _config);\n\n        if (typeof config === 'string') {\n          if (typeof data[config] === 'undefined') {\n            throw new TypeError(`No method named \"${config}\"`);\n          }\n\n          data[config]();\n        }\n      });\n    }\n\n  }\n  /**\n   * ------------------------------------------------------------------------\n   * Data Api implementation\n   * ------------------------------------------------------------------------\n   */\n\n\n  EventHandler.on(document, EVENT_CLICK_DATA_API$4, SELECTOR_DATA_TOGGLE$4, function (event) {\n    // preventDefault only for <a> elements (which change the URL) not inside the collapsible element\n    if (event.target.tagName === 'A' || event.delegateTarget && event.delegateTarget.tagName === 'A') {\n      event.preventDefault();\n    }\n\n    const selector = getSelectorFromElement(this);\n    const selectorElements = SelectorEngine.find(selector);\n    selectorElements.forEach(element => {\n      Collapse.getOrCreateInstance(element, {\n        toggle: false\n      }).toggle();\n    });\n  });\n  /**\n   * ------------------------------------------------------------------------\n   * jQuery\n   * ------------------------------------------------------------------------\n   * add .Collapse to jQuery only if jQuery is present\n   */\n\n  defineJQueryPlugin(Collapse);\n\n  /**\n   * --------------------------------------------------------------------------\n   * Bootstrap (v5.1.0): dropdown.js\n   * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n   * --------------------------------------------------------------------------\n   */\n  /**\n   * ------------------------------------------------------------------------\n   * Constants\n   * ------------------------------------------------------------------------\n   */\n\n  const NAME$9 = 'dropdown';\n  const DATA_KEY$8 = 'bs.dropdown';\n  const EVENT_KEY$8 = `.${DATA_KEY$8}`;\n  const DATA_API_KEY$4 = '.data-api';\n  const ESCAPE_KEY$2 = 'Escape';\n  const SPACE_KEY = 'Space';\n  const TAB_KEY$1 = 'Tab';\n  const ARROW_UP_KEY = 'ArrowUp';\n  const ARROW_DOWN_KEY = 'ArrowDown';\n  const RIGHT_MOUSE_BUTTON = 2; // MouseEvent.button value for the secondary button, usually the right button\n\n  const REGEXP_KEYDOWN = new RegExp(`${ARROW_UP_KEY}|${ARROW_DOWN_KEY}|${ESCAPE_KEY$2}`);\n  const EVENT_HIDE$4 = `hide${EVENT_KEY$8}`;\n  const EVENT_HIDDEN$4 = `hidden${EVENT_KEY$8}`;\n  const EVENT_SHOW$4 = `show${EVENT_KEY$8}`;\n  const EVENT_SHOWN$4 = `shown${EVENT_KEY$8}`;\n  const EVENT_CLICK_DATA_API$3 = `click${EVENT_KEY$8}${DATA_API_KEY$4}`;\n  const EVENT_KEYDOWN_DATA_API = `keydown${EVENT_KEY$8}${DATA_API_KEY$4}`;\n  const EVENT_KEYUP_DATA_API = `keyup${EVENT_KEY$8}${DATA_API_KEY$4}`;\n  const CLASS_NAME_SHOW$6 = 'show';\n  const CLASS_NAME_DROPUP = 'dropup';\n  const CLASS_NAME_DROPEND = 'dropend';\n  const CLASS_NAME_DROPSTART = 'dropstart';\n  const CLASS_NAME_NAVBAR = 'navbar';\n  const SELECTOR_DATA_TOGGLE$3 = '[data-bs-toggle=\"dropdown\"]';\n  const SELECTOR_MENU = '.dropdown-menu';\n  const SELECTOR_NAVBAR_NAV = '.navbar-nav';\n  const SELECTOR_VISIBLE_ITEMS = '.dropdown-menu .dropdown-item:not(.disabled):not(:disabled)';\n  const PLACEMENT_TOP = isRTL() ? 'top-end' : 'top-start';\n  const PLACEMENT_TOPEND = isRTL() ? 'top-start' : 'top-end';\n  const PLACEMENT_BOTTOM = isRTL() ? 'bottom-end' : 'bottom-start';\n  const PLACEMENT_BOTTOMEND = isRTL() ? 'bottom-start' : 'bottom-end';\n  const PLACEMENT_RIGHT = isRTL() ? 'left-start' : 'right-start';\n  const PLACEMENT_LEFT = isRTL() ? 'right-start' : 'left-start';\n  const Default$8 = {\n    offset: [0, 2],\n    boundary: 'clippingParents',\n    reference: 'toggle',\n    display: 'dynamic',\n    popperConfig: null,\n    autoClose: true\n  };\n  const DefaultType$8 = {\n    offset: '(array|string|function)',\n    boundary: '(string|element)',\n    reference: '(string|element|object)',\n    display: 'string',\n    popperConfig: '(null|object|function)',\n    autoClose: '(boolean|string)'\n  };\n  /**\n   * ------------------------------------------------------------------------\n   * Class Definition\n   * ------------------------------------------------------------------------\n   */\n\n  class Dropdown extends BaseComponent {\n    constructor(element, config) {\n      super(element);\n      this._popper = null;\n      this._config = this._getConfig(config);\n      this._menu = this._getMenuElement();\n      this._inNavbar = this._detectNavbar();\n    } // Getters\n\n\n    static get Default() {\n      return Default$8;\n    }\n\n    static get DefaultType() {\n      return DefaultType$8;\n    }\n\n    static get NAME() {\n      return NAME$9;\n    } // Public\n\n\n    toggle() {\n      return this._isShown() ? this.hide() : this.show();\n    }\n\n    show() {\n      if (isDisabled(this._element) || this._isShown(this._menu)) {\n        return;\n      }\n\n      const relatedTarget = {\n        relatedTarget: this._element\n      };\n      const showEvent = EventHandler.trigger(this._element, EVENT_SHOW$4, relatedTarget);\n\n      if (showEvent.defaultPrevented) {\n        return;\n      }\n\n      const parent = Dropdown.getParentFromElement(this._element); // Totally disable Popper for Dropdowns in Navbar\n\n      if (this._inNavbar) {\n        Manipulator.setDataAttribute(this._menu, 'popper', 'none');\n      } else {\n        this._createPopper(parent);\n      } // If this is a touch-enabled device we add extra\n      // empty mouseover listeners to the body's immediate children;\n      // only needed because of broken event delegation on iOS\n      // https://www.quirksmode.org/blog/archives/2014/02/mouse_event_bub.html\n\n\n      if ('ontouchstart' in document.documentElement && !parent.closest(SELECTOR_NAVBAR_NAV)) {\n        [].concat(...document.body.children).forEach(elem => EventHandler.on(elem, 'mouseover', noop));\n      }\n\n      this._element.focus();\n\n      this._element.setAttribute('aria-expanded', true);\n\n      this._menu.classList.add(CLASS_NAME_SHOW$6);\n\n      this._element.classList.add(CLASS_NAME_SHOW$6);\n\n      EventHandler.trigger(this._element, EVENT_SHOWN$4, relatedTarget);\n    }\n\n    hide() {\n      if (isDisabled(this._element) || !this._isShown(this._menu)) {\n        return;\n      }\n\n      const relatedTarget = {\n        relatedTarget: this._element\n      };\n\n      this._completeHide(relatedTarget);\n    }\n\n    dispose() {\n      if (this._popper) {\n        this._popper.destroy();\n      }\n\n      super.dispose();\n    }\n\n    update() {\n      this._inNavbar = this._detectNavbar();\n\n      if (this._popper) {\n        this._popper.update();\n      }\n    } // Private\n\n\n    _completeHide(relatedTarget) {\n      const hideEvent = EventHandler.trigger(this._element, EVENT_HIDE$4, relatedTarget);\n\n      if (hideEvent.defaultPrevented) {\n        return;\n      } // If this is a touch-enabled device we remove the extra\n      // empty mouseover listeners we added for iOS support\n\n\n      if ('ontouchstart' in document.documentElement) {\n        [].concat(...document.body.children).forEach(elem => EventHandler.off(elem, 'mouseover', noop));\n      }\n\n      if (this._popper) {\n        this._popper.destroy();\n      }\n\n      this._menu.classList.remove(CLASS_NAME_SHOW$6);\n\n      this._element.classList.remove(CLASS_NAME_SHOW$6);\n\n      this._element.setAttribute('aria-expanded', 'false');\n\n      Manipulator.removeDataAttribute(this._menu, 'popper');\n      EventHandler.trigger(this._element, EVENT_HIDDEN$4, relatedTarget);\n    }\n\n    _getConfig(config) {\n      config = { ...this.constructor.Default,\n        ...Manipulator.getDataAttributes(this._element),\n        ...config\n      };\n      typeCheckConfig(NAME$9, config, this.constructor.DefaultType);\n\n      if (typeof config.reference === 'object' && !isElement(config.reference) && typeof config.reference.getBoundingClientRect !== 'function') {\n        // Popper virtual elements require a getBoundingClientRect method\n        throw new TypeError(`${NAME$9.toUpperCase()}: Option \"reference\" provided type \"object\" without a required \"getBoundingClientRect\" method.`);\n      }\n\n      return config;\n    }\n\n    _createPopper(parent) {\n      if (typeof Popper__namespace === 'undefined') {\n        throw new TypeError('Bootstrap\\'s dropdowns require Popper (https://popper.js.org)');\n      }\n\n      let referenceElement = this._element;\n\n      if (this._config.reference === 'parent') {\n        referenceElement = parent;\n      } else if (isElement(this._config.reference)) {\n        referenceElement = getElement(this._config.reference);\n      } else if (typeof this._config.reference === 'object') {\n        referenceElement = this._config.reference;\n      }\n\n      const popperConfig = this._getPopperConfig();\n\n      const isDisplayStatic = popperConfig.modifiers.find(modifier => modifier.name === 'applyStyles' && modifier.enabled === false);\n      this._popper = Popper__namespace.createPopper(referenceElement, this._menu, popperConfig);\n\n      if (isDisplayStatic) {\n        Manipulator.setDataAttribute(this._menu, 'popper', 'static');\n      }\n    }\n\n    _isShown(element = this._element) {\n      return element.classList.contains(CLASS_NAME_SHOW$6);\n    }\n\n    _getMenuElement() {\n      return SelectorEngine.next(this._element, SELECTOR_MENU)[0];\n    }\n\n    _getPlacement() {\n      const parentDropdown = this._element.parentNode;\n\n      if (parentDropdown.classList.contains(CLASS_NAME_DROPEND)) {\n        return PLACEMENT_RIGHT;\n      }\n\n      if (parentDropdown.classList.contains(CLASS_NAME_DROPSTART)) {\n        return PLACEMENT_LEFT;\n      } // We need to trim the value because custom properties can also include spaces\n\n\n      const isEnd = getComputedStyle(this._menu).getPropertyValue('--bs-position').trim() === 'end';\n\n      if (parentDropdown.classList.contains(CLASS_NAME_DROPUP)) {\n        return isEnd ? PLACEMENT_TOPEND : PLACEMENT_TOP;\n      }\n\n      return isEnd ? PLACEMENT_BOTTOMEND : PLACEMENT_BOTTOM;\n    }\n\n    _detectNavbar() {\n      return this._element.closest(`.${CLASS_NAME_NAVBAR}`) !== null;\n    }\n\n    _getOffset() {\n      const {\n        offset\n      } = this._config;\n\n      if (typeof offset === 'string') {\n        return offset.split(',').map(val => Number.parseInt(val, 10));\n      }\n\n      if (typeof offset === 'function') {\n        return popperData => offset(popperData, this._element);\n      }\n\n      return offset;\n    }\n\n    _getPopperConfig() {\n      const defaultBsPopperConfig = {\n        placement: this._getPlacement(),\n        modifiers: [{\n          name: 'preventOverflow',\n          options: {\n            boundary: this._config.boundary\n          }\n        }, {\n          name: 'offset',\n          options: {\n            offset: this._getOffset()\n          }\n        }]\n      }; // Disable Popper if we have a static display\n\n      if (this._config.display === 'static') {\n        defaultBsPopperConfig.modifiers = [{\n          name: 'applyStyles',\n          enabled: false\n        }];\n      }\n\n      return { ...defaultBsPopperConfig,\n        ...(typeof this._config.popperConfig === 'function' ? this._config.popperConfig(defaultBsPopperConfig) : this._config.popperConfig)\n      };\n    }\n\n    _selectMenuItem({\n      key,\n      target\n    }) {\n      const items = SelectorEngine.find(SELECTOR_VISIBLE_ITEMS, this._menu).filter(isVisible);\n\n      if (!items.length) {\n        return;\n      } // if target isn't included in items (e.g. when expanding the dropdown)\n      // allow cycling to get the last item in case key equals ARROW_UP_KEY\n\n\n      getNextActiveElement(items, target, key === ARROW_DOWN_KEY, !items.includes(target)).focus();\n    } // Static\n\n\n    static jQueryInterface(config) {\n      return this.each(function () {\n        const data = Dropdown.getOrCreateInstance(this, config);\n\n        if (typeof config !== 'string') {\n          return;\n        }\n\n        if (typeof data[config] === 'undefined') {\n          throw new TypeError(`No method named \"${config}\"`);\n        }\n\n        data[config]();\n      });\n    }\n\n    static clearMenus(event) {\n      if (event && (event.button === RIGHT_MOUSE_BUTTON || event.type === 'keyup' && event.key !== TAB_KEY$1)) {\n        return;\n      }\n\n      const toggles = SelectorEngine.find(SELECTOR_DATA_TOGGLE$3);\n\n      for (let i = 0, len = toggles.length; i < len; i++) {\n        const context = Dropdown.getInstance(toggles[i]);\n\n        if (!context || context._config.autoClose === false) {\n          continue;\n        }\n\n        if (!context._isShown()) {\n          continue;\n        }\n\n        const relatedTarget = {\n          relatedTarget: context._element\n        };\n\n        if (event) {\n          const composedPath = event.composedPath();\n          const isMenuTarget = composedPath.includes(context._menu);\n\n          if (composedPath.includes(context._element) || context._config.autoClose === 'inside' && !isMenuTarget || context._config.autoClose === 'outside' && isMenuTarget) {\n            continue;\n          } // Tab navigation through the dropdown menu or events from contained inputs shouldn't close the menu\n\n\n          if (context._menu.contains(event.target) && (event.type === 'keyup' && event.key === TAB_KEY$1 || /input|select|option|textarea|form/i.test(event.target.tagName))) {\n            continue;\n          }\n\n          if (event.type === 'click') {\n            relatedTarget.clickEvent = event;\n          }\n        }\n\n        context._completeHide(relatedTarget);\n      }\n    }\n\n    static getParentFromElement(element) {\n      return getElementFromSelector(element) || element.parentNode;\n    }\n\n    static dataApiKeydownHandler(event) {\n      // If not input/textarea:\n      //  - And not a key in REGEXP_KEYDOWN => not a dropdown command\n      // If input/textarea:\n      //  - If space key => not a dropdown command\n      //  - If key is other than escape\n      //    - If key is not up or down => not a dropdown command\n      //    - If trigger inside the menu => not a dropdown command\n      if (/input|textarea/i.test(event.target.tagName) ? event.key === SPACE_KEY || event.key !== ESCAPE_KEY$2 && (event.key !== ARROW_DOWN_KEY && event.key !== ARROW_UP_KEY || event.target.closest(SELECTOR_MENU)) : !REGEXP_KEYDOWN.test(event.key)) {\n        return;\n      }\n\n      const isActive = this.classList.contains(CLASS_NAME_SHOW$6);\n\n      if (!isActive && event.key === ESCAPE_KEY$2) {\n        return;\n      }\n\n      event.preventDefault();\n      event.stopPropagation();\n\n      if (isDisabled(this)) {\n        return;\n      }\n\n      const getToggleButton = this.matches(SELECTOR_DATA_TOGGLE$3) ? this : SelectorEngine.prev(this, SELECTOR_DATA_TOGGLE$3)[0];\n      const instance = Dropdown.getOrCreateInstance(getToggleButton);\n\n      if (event.key === ESCAPE_KEY$2) {\n        instance.hide();\n        return;\n      }\n\n      if (event.key === ARROW_UP_KEY || event.key === ARROW_DOWN_KEY) {\n        if (!isActive) {\n          instance.show();\n        }\n\n        instance._selectMenuItem(event);\n\n        return;\n      }\n\n      if (!isActive || event.key === SPACE_KEY) {\n        Dropdown.clearMenus();\n      }\n    }\n\n  }\n  /**\n   * ------------------------------------------------------------------------\n   * Data Api implementation\n   * ------------------------------------------------------------------------\n   */\n\n\n  EventHandler.on(document, EVENT_KEYDOWN_DATA_API, SELECTOR_DATA_TOGGLE$3, Dropdown.dataApiKeydownHandler);\n  EventHandler.on(document, EVENT_KEYDOWN_DATA_API, SELECTOR_MENU, Dropdown.dataApiKeydownHandler);\n  EventHandler.on(document, EVENT_CLICK_DATA_API$3, Dropdown.clearMenus);\n  EventHandler.on(document, EVENT_KEYUP_DATA_API, Dropdown.clearMenus);\n  EventHandler.on(document, EVENT_CLICK_DATA_API$3, SELECTOR_DATA_TOGGLE$3, function (event) {\n    event.preventDefault();\n    Dropdown.getOrCreateInstance(this).toggle();\n  });\n  /**\n   * ------------------------------------------------------------------------\n   * jQuery\n   * ------------------------------------------------------------------------\n   * add .Dropdown to jQuery only if jQuery is present\n   */\n\n  defineJQueryPlugin(Dropdown);\n\n  /**\n   * --------------------------------------------------------------------------\n   * Bootstrap (v5.1.0): util/scrollBar.js\n   * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n   * --------------------------------------------------------------------------\n   */\n  const SELECTOR_FIXED_CONTENT = '.fixed-top, .fixed-bottom, .is-fixed, .sticky-top';\n  const SELECTOR_STICKY_CONTENT = '.sticky-top';\n\n  class ScrollBarHelper {\n    constructor() {\n      this._element = document.body;\n    }\n\n    getWidth() {\n      // https://developer.mozilla.org/en-US/docs/Web/API/Window/innerWidth#usage_notes\n      const documentWidth = document.documentElement.clientWidth;\n      return Math.abs(window.innerWidth - documentWidth);\n    }\n\n    hide() {\n      const width = this.getWidth();\n\n      this._disableOverFlow(); // give padding to element to balance the hidden scrollbar width\n\n\n      this._setElementAttributes(this._element, 'paddingRight', calculatedValue => calculatedValue + width); // trick: We adjust positive paddingRight and negative marginRight to sticky-top elements to keep showing fullwidth\n\n\n      this._setElementAttributes(SELECTOR_FIXED_CONTENT, 'paddingRight', calculatedValue => calculatedValue + width);\n\n      this._setElementAttributes(SELECTOR_STICKY_CONTENT, 'marginRight', calculatedValue => calculatedValue - width);\n    }\n\n    _disableOverFlow() {\n      this._saveInitialAttribute(this._element, 'overflow');\n\n      this._element.style.overflow = 'hidden';\n    }\n\n    _setElementAttributes(selector, styleProp, callback) {\n      const scrollbarWidth = this.getWidth();\n\n      const manipulationCallBack = element => {\n        if (element !== this._element && window.innerWidth > element.clientWidth + scrollbarWidth) {\n          return;\n        }\n\n        this._saveInitialAttribute(element, styleProp);\n\n        const calculatedValue = window.getComputedStyle(element)[styleProp];\n        element.style[styleProp] = `${callback(Number.parseFloat(calculatedValue))}px`;\n      };\n\n      this._applyManipulationCallback(selector, manipulationCallBack);\n    }\n\n    reset() {\n      this._resetElementAttributes(this._element, 'overflow');\n\n      this._resetElementAttributes(this._element, 'paddingRight');\n\n      this._resetElementAttributes(SELECTOR_FIXED_CONTENT, 'paddingRight');\n\n      this._resetElementAttributes(SELECTOR_STICKY_CONTENT, 'marginRight');\n    }\n\n    _saveInitialAttribute(element, styleProp) {\n      const actualValue = element.style[styleProp];\n\n      if (actualValue) {\n        Manipulator.setDataAttribute(element, styleProp, actualValue);\n      }\n    }\n\n    _resetElementAttributes(selector, styleProp) {\n      const manipulationCallBack = element => {\n        const value = Manipulator.getDataAttribute(element, styleProp);\n\n        if (typeof value === 'undefined') {\n          element.style.removeProperty(styleProp);\n        } else {\n          Manipulator.removeDataAttribute(element, styleProp);\n          element.style[styleProp] = value;\n        }\n      };\n\n      this._applyManipulationCallback(selector, manipulationCallBack);\n    }\n\n    _applyManipulationCallback(selector, callBack) {\n      if (isElement(selector)) {\n        callBack(selector);\n      } else {\n        SelectorEngine.find(selector, this._element).forEach(callBack);\n      }\n    }\n\n    isOverflowing() {\n      return this.getWidth() > 0;\n    }\n\n  }\n\n  /**\n   * --------------------------------------------------------------------------\n   * Bootstrap (v5.1.0): util/backdrop.js\n   * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n   * --------------------------------------------------------------------------\n   */\n  const Default$7 = {\n    className: 'modal-backdrop',\n    isVisible: true,\n    // if false, we use the backdrop helper without adding any element to the dom\n    isAnimated: false,\n    rootElement: 'body',\n    // give the choice to place backdrop under different elements\n    clickCallback: null\n  };\n  const DefaultType$7 = {\n    className: 'string',\n    isVisible: 'boolean',\n    isAnimated: 'boolean',\n    rootElement: '(element|string)',\n    clickCallback: '(function|null)'\n  };\n  const NAME$8 = 'backdrop';\n  const CLASS_NAME_FADE$4 = 'fade';\n  const CLASS_NAME_SHOW$5 = 'show';\n  const EVENT_MOUSEDOWN = `mousedown.bs.${NAME$8}`;\n\n  class Backdrop {\n    constructor(config) {\n      this._config = this._getConfig(config);\n      this._isAppended = false;\n      this._element = null;\n    }\n\n    show(callback) {\n      if (!this._config.isVisible) {\n        execute(callback);\n        return;\n      }\n\n      this._append();\n\n      if (this._config.isAnimated) {\n        reflow(this._getElement());\n      }\n\n      this._getElement().classList.add(CLASS_NAME_SHOW$5);\n\n      this._emulateAnimation(() => {\n        execute(callback);\n      });\n    }\n\n    hide(callback) {\n      if (!this._config.isVisible) {\n        execute(callback);\n        return;\n      }\n\n      this._getElement().classList.remove(CLASS_NAME_SHOW$5);\n\n      this._emulateAnimation(() => {\n        this.dispose();\n        execute(callback);\n      });\n    } // Private\n\n\n    _getElement() {\n      if (!this._element) {\n        const backdrop = document.createElement('div');\n        backdrop.className = this._config.className;\n\n        if (this._config.isAnimated) {\n          backdrop.classList.add(CLASS_NAME_FADE$4);\n        }\n\n        this._element = backdrop;\n      }\n\n      return this._element;\n    }\n\n    _getConfig(config) {\n      config = { ...Default$7,\n        ...(typeof config === 'object' ? config : {})\n      }; // use getElement() with the default \"body\" to get a fresh Element on each instantiation\n\n      config.rootElement = getElement(config.rootElement);\n      typeCheckConfig(NAME$8, config, DefaultType$7);\n      return config;\n    }\n\n    _append() {\n      if (this._isAppended) {\n        return;\n      }\n\n      this._config.rootElement.append(this._getElement());\n\n      EventHandler.on(this._getElement(), EVENT_MOUSEDOWN, () => {\n        execute(this._config.clickCallback);\n      });\n      this._isAppended = true;\n    }\n\n    dispose() {\n      if (!this._isAppended) {\n        return;\n      }\n\n      EventHandler.off(this._element, EVENT_MOUSEDOWN);\n\n      this._element.remove();\n\n      this._isAppended = false;\n    }\n\n    _emulateAnimation(callback) {\n      executeAfterTransition(callback, this._getElement(), this._config.isAnimated);\n    }\n\n  }\n\n  /**\n   * --------------------------------------------------------------------------\n   * Bootstrap (v5.1.0): util/focustrap.js\n   * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n   * --------------------------------------------------------------------------\n   */\n  const Default$6 = {\n    trapElement: null,\n    // The element to trap focus inside of\n    autofocus: true\n  };\n  const DefaultType$6 = {\n    trapElement: 'element',\n    autofocus: 'boolean'\n  };\n  const NAME$7 = 'focustrap';\n  const DATA_KEY$7 = 'bs.focustrap';\n  const EVENT_KEY$7 = `.${DATA_KEY$7}`;\n  const EVENT_FOCUSIN$1 = `focusin${EVENT_KEY$7}`;\n  const EVENT_KEYDOWN_TAB = `keydown.tab${EVENT_KEY$7}`;\n  const TAB_KEY = 'Tab';\n  const TAB_NAV_FORWARD = 'forward';\n  const TAB_NAV_BACKWARD = 'backward';\n\n  class FocusTrap {\n    constructor(config) {\n      this._config = this._getConfig(config);\n      this._isActive = false;\n      this._lastTabNavDirection = null;\n    }\n\n    activate() {\n      const {\n        trapElement,\n        autofocus\n      } = this._config;\n\n      if (this._isActive) {\n        return;\n      }\n\n      if (autofocus) {\n        trapElement.focus();\n      }\n\n      EventHandler.off(document, EVENT_KEY$7); // guard against infinite focus loop\n\n      EventHandler.on(document, EVENT_FOCUSIN$1, event => this._handleFocusin(event));\n      EventHandler.on(document, EVENT_KEYDOWN_TAB, event => this._handleKeydown(event));\n      this._isActive = true;\n    }\n\n    deactivate() {\n      if (!this._isActive) {\n        return;\n      }\n\n      this._isActive = false;\n      EventHandler.off(document, EVENT_KEY$7);\n    } // Private\n\n\n    _handleFocusin(event) {\n      const {\n        target\n      } = event;\n      const {\n        trapElement\n      } = this._config;\n\n      if (target === document || target === trapElement || trapElement.contains(target)) {\n        return;\n      }\n\n      const elements = SelectorEngine.focusableChildren(trapElement);\n\n      if (elements.length === 0) {\n        trapElement.focus();\n      } else if (this._lastTabNavDirection === TAB_NAV_BACKWARD) {\n        elements[elements.length - 1].focus();\n      } else {\n        elements[0].focus();\n      }\n    }\n\n    _handleKeydown(event) {\n      if (event.key !== TAB_KEY) {\n        return;\n      }\n\n      this._lastTabNavDirection = event.shiftKey ? TAB_NAV_BACKWARD : TAB_NAV_FORWARD;\n    }\n\n    _getConfig(config) {\n      config = { ...Default$6,\n        ...(typeof config === 'object' ? config : {})\n      };\n      typeCheckConfig(NAME$7, config, DefaultType$6);\n      return config;\n    }\n\n  }\n\n  /**\n   * --------------------------------------------------------------------------\n   * Bootstrap (v5.1.0): modal.js\n   * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n   * --------------------------------------------------------------------------\n   */\n  /**\n   * ------------------------------------------------------------------------\n   * Constants\n   * ------------------------------------------------------------------------\n   */\n\n  const NAME$6 = 'modal';\n  const DATA_KEY$6 = 'bs.modal';\n  const EVENT_KEY$6 = `.${DATA_KEY$6}`;\n  const DATA_API_KEY$3 = '.data-api';\n  const ESCAPE_KEY$1 = 'Escape';\n  const Default$5 = {\n    backdrop: true,\n    keyboard: true,\n    focus: true\n  };\n  const DefaultType$5 = {\n    backdrop: '(boolean|string)',\n    keyboard: 'boolean',\n    focus: 'boolean'\n  };\n  const EVENT_HIDE$3 = `hide${EVENT_KEY$6}`;\n  const EVENT_HIDE_PREVENTED = `hidePrevented${EVENT_KEY$6}`;\n  const EVENT_HIDDEN$3 = `hidden${EVENT_KEY$6}`;\n  const EVENT_SHOW$3 = `show${EVENT_KEY$6}`;\n  const EVENT_SHOWN$3 = `shown${EVENT_KEY$6}`;\n  const EVENT_RESIZE = `resize${EVENT_KEY$6}`;\n  const EVENT_CLICK_DISMISS = `click.dismiss${EVENT_KEY$6}`;\n  const EVENT_KEYDOWN_DISMISS$1 = `keydown.dismiss${EVENT_KEY$6}`;\n  const EVENT_MOUSEUP_DISMISS = `mouseup.dismiss${EVENT_KEY$6}`;\n  const EVENT_MOUSEDOWN_DISMISS = `mousedown.dismiss${EVENT_KEY$6}`;\n  const EVENT_CLICK_DATA_API$2 = `click${EVENT_KEY$6}${DATA_API_KEY$3}`;\n  const CLASS_NAME_OPEN = 'modal-open';\n  const CLASS_NAME_FADE$3 = 'fade';\n  const CLASS_NAME_SHOW$4 = 'show';\n  const CLASS_NAME_STATIC = 'modal-static';\n  const SELECTOR_DIALOG = '.modal-dialog';\n  const SELECTOR_MODAL_BODY = '.modal-body';\n  const SELECTOR_DATA_TOGGLE$2 = '[data-bs-toggle=\"modal\"]';\n  /**\n   * ------------------------------------------------------------------------\n   * Class Definition\n   * ------------------------------------------------------------------------\n   */\n\n  class Modal extends BaseComponent {\n    constructor(element, config) {\n      super(element);\n      this._config = this._getConfig(config);\n      this._dialog = SelectorEngine.findOne(SELECTOR_DIALOG, this._element);\n      this._backdrop = this._initializeBackDrop();\n      this._focustrap = this._initializeFocusTrap();\n      this._isShown = false;\n      this._ignoreBackdropClick = false;\n      this._isTransitioning = false;\n      this._scrollBar = new ScrollBarHelper();\n    } // Getters\n\n\n    static get Default() {\n      return Default$5;\n    }\n\n    static get NAME() {\n      return NAME$6;\n    } // Public\n\n\n    toggle(relatedTarget) {\n      return this._isShown ? this.hide() : this.show(relatedTarget);\n    }\n\n    show(relatedTarget) {\n      if (this._isShown || this._isTransitioning) {\n        return;\n      }\n\n      const showEvent = EventHandler.trigger(this._element, EVENT_SHOW$3, {\n        relatedTarget\n      });\n\n      if (showEvent.defaultPrevented) {\n        return;\n      }\n\n      this._isShown = true;\n\n      if (this._isAnimated()) {\n        this._isTransitioning = true;\n      }\n\n      this._scrollBar.hide();\n\n      document.body.classList.add(CLASS_NAME_OPEN);\n\n      this._adjustDialog();\n\n      this._setEscapeEvent();\n\n      this._setResizeEvent();\n\n      EventHandler.on(this._dialog, EVENT_MOUSEDOWN_DISMISS, () => {\n        EventHandler.one(this._element, EVENT_MOUSEUP_DISMISS, event => {\n          if (event.target === this._element) {\n            this._ignoreBackdropClick = true;\n          }\n        });\n      });\n\n      this._showBackdrop(() => this._showElement(relatedTarget));\n    }\n\n    hide() {\n      if (!this._isShown || this._isTransitioning) {\n        return;\n      }\n\n      const hideEvent = EventHandler.trigger(this._element, EVENT_HIDE$3);\n\n      if (hideEvent.defaultPrevented) {\n        return;\n      }\n\n      this._isShown = false;\n\n      const isAnimated = this._isAnimated();\n\n      if (isAnimated) {\n        this._isTransitioning = true;\n      }\n\n      this._setEscapeEvent();\n\n      this._setResizeEvent();\n\n      this._focustrap.deactivate();\n\n      this._element.classList.remove(CLASS_NAME_SHOW$4);\n\n      EventHandler.off(this._element, EVENT_CLICK_DISMISS);\n      EventHandler.off(this._dialog, EVENT_MOUSEDOWN_DISMISS);\n\n      this._queueCallback(() => this._hideModal(), this._element, isAnimated);\n    }\n\n    dispose() {\n      [window, this._dialog].forEach(htmlElement => EventHandler.off(htmlElement, EVENT_KEY$6));\n\n      this._backdrop.dispose();\n\n      this._focustrap.deactivate();\n\n      super.dispose();\n    }\n\n    handleUpdate() {\n      this._adjustDialog();\n    } // Private\n\n\n    _initializeBackDrop() {\n      return new Backdrop({\n        isVisible: Boolean(this._config.backdrop),\n        // 'static' option will be translated to true, and booleans will keep their value\n        isAnimated: this._isAnimated()\n      });\n    }\n\n    _initializeFocusTrap() {\n      return new FocusTrap({\n        trapElement: this._element\n      });\n    }\n\n    _getConfig(config) {\n      config = { ...Default$5,\n        ...Manipulator.getDataAttributes(this._element),\n        ...(typeof config === 'object' ? config : {})\n      };\n      typeCheckConfig(NAME$6, config, DefaultType$5);\n      return config;\n    }\n\n    _showElement(relatedTarget) {\n      const isAnimated = this._isAnimated();\n\n      const modalBody = SelectorEngine.findOne(SELECTOR_MODAL_BODY, this._dialog);\n\n      if (!this._element.parentNode || this._element.parentNode.nodeType !== Node.ELEMENT_NODE) {\n        // Don't move modal's DOM position\n        document.body.append(this._element);\n      }\n\n      this._element.style.display = 'block';\n\n      this._element.removeAttribute('aria-hidden');\n\n      this._element.setAttribute('aria-modal', true);\n\n      this._element.setAttribute('role', 'dialog');\n\n      this._element.scrollTop = 0;\n\n      if (modalBody) {\n        modalBody.scrollTop = 0;\n      }\n\n      if (isAnimated) {\n        reflow(this._element);\n      }\n\n      this._element.classList.add(CLASS_NAME_SHOW$4);\n\n      const transitionComplete = () => {\n        if (this._config.focus) {\n          this._focustrap.activate();\n        }\n\n        this._isTransitioning = false;\n        EventHandler.trigger(this._element, EVENT_SHOWN$3, {\n          relatedTarget\n        });\n      };\n\n      this._queueCallback(transitionComplete, this._dialog, isAnimated);\n    }\n\n    _setEscapeEvent() {\n      if (this._isShown) {\n        EventHandler.on(this._element, EVENT_KEYDOWN_DISMISS$1, event => {\n          if (this._config.keyboard && event.key === ESCAPE_KEY$1) {\n            event.preventDefault();\n            this.hide();\n          } else if (!this._config.keyboard && event.key === ESCAPE_KEY$1) {\n            this._triggerBackdropTransition();\n          }\n        });\n      } else {\n        EventHandler.off(this._element, EVENT_KEYDOWN_DISMISS$1);\n      }\n    }\n\n    _setResizeEvent() {\n      if (this._isShown) {\n        EventHandler.on(window, EVENT_RESIZE, () => this._adjustDialog());\n      } else {\n        EventHandler.off(window, EVENT_RESIZE);\n      }\n    }\n\n    _hideModal() {\n      this._element.style.display = 'none';\n\n      this._element.setAttribute('aria-hidden', true);\n\n      this._element.removeAttribute('aria-modal');\n\n      this._element.removeAttribute('role');\n\n      this._isTransitioning = false;\n\n      this._backdrop.hide(() => {\n        document.body.classList.remove(CLASS_NAME_OPEN);\n\n        this._resetAdjustments();\n\n        this._scrollBar.reset();\n\n        EventHandler.trigger(this._element, EVENT_HIDDEN$3);\n      });\n    }\n\n    _showBackdrop(callback) {\n      EventHandler.on(this._element, EVENT_CLICK_DISMISS, event => {\n        if (this._ignoreBackdropClick) {\n          this._ignoreBackdropClick = false;\n          return;\n        }\n\n        if (event.target !== event.currentTarget) {\n          return;\n        }\n\n        if (this._config.backdrop === true) {\n          this.hide();\n        } else if (this._config.backdrop === 'static') {\n          this._triggerBackdropTransition();\n        }\n      });\n\n      this._backdrop.show(callback);\n    }\n\n    _isAnimated() {\n      return this._element.classList.contains(CLASS_NAME_FADE$3);\n    }\n\n    _triggerBackdropTransition() {\n      const hideEvent = EventHandler.trigger(this._element, EVENT_HIDE_PREVENTED);\n\n      if (hideEvent.defaultPrevented) {\n        return;\n      }\n\n      const {\n        classList,\n        scrollHeight,\n        style\n      } = this._element;\n      const isModalOverflowing = scrollHeight > document.documentElement.clientHeight; // return if the following background transition hasn't yet completed\n\n      if (!isModalOverflowing && style.overflowY === 'hidden' || classList.contains(CLASS_NAME_STATIC)) {\n        return;\n      }\n\n      if (!isModalOverflowing) {\n        style.overflowY = 'hidden';\n      }\n\n      classList.add(CLASS_NAME_STATIC);\n\n      this._queueCallback(() => {\n        classList.remove(CLASS_NAME_STATIC);\n\n        if (!isModalOverflowing) {\n          this._queueCallback(() => {\n            style.overflowY = '';\n          }, this._dialog);\n        }\n      }, this._dialog);\n\n      this._element.focus();\n    } // ----------------------------------------------------------------------\n    // the following methods are used to handle overflowing modals\n    // ----------------------------------------------------------------------\n\n\n    _adjustDialog() {\n      const isModalOverflowing = this._element.scrollHeight > document.documentElement.clientHeight;\n\n      const scrollbarWidth = this._scrollBar.getWidth();\n\n      const isBodyOverflowing = scrollbarWidth > 0;\n\n      if (!isBodyOverflowing && isModalOverflowing && !isRTL() || isBodyOverflowing && !isModalOverflowing && isRTL()) {\n        this._element.style.paddingLeft = `${scrollbarWidth}px`;\n      }\n\n      if (isBodyOverflowing && !isModalOverflowing && !isRTL() || !isBodyOverflowing && isModalOverflowing && isRTL()) {\n        this._element.style.paddingRight = `${scrollbarWidth}px`;\n      }\n    }\n\n    _resetAdjustments() {\n      this._element.style.paddingLeft = '';\n      this._element.style.paddingRight = '';\n    } // Static\n\n\n    static jQueryInterface(config, relatedTarget) {\n      return this.each(function () {\n        const data = Modal.getOrCreateInstance(this, config);\n\n        if (typeof config !== 'string') {\n          return;\n        }\n\n        if (typeof data[config] === 'undefined') {\n          throw new TypeError(`No method named \"${config}\"`);\n        }\n\n        data[config](relatedTarget);\n      });\n    }\n\n  }\n  /**\n   * ------------------------------------------------------------------------\n   * Data Api implementation\n   * ------------------------------------------------------------------------\n   */\n\n\n  EventHandler.on(document, EVENT_CLICK_DATA_API$2, SELECTOR_DATA_TOGGLE$2, function (event) {\n    const target = getElementFromSelector(this);\n\n    if (['A', 'AREA'].includes(this.tagName)) {\n      event.preventDefault();\n    }\n\n    EventHandler.one(target, EVENT_SHOW$3, showEvent => {\n      if (showEvent.defaultPrevented) {\n        // only register focus restorer if modal will actually get shown\n        return;\n      }\n\n      EventHandler.one(target, EVENT_HIDDEN$3, () => {\n        if (isVisible(this)) {\n          this.focus();\n        }\n      });\n    });\n    const data = Modal.getOrCreateInstance(target);\n    data.toggle(this);\n  });\n  enableDismissTrigger(Modal);\n  /**\n   * ------------------------------------------------------------------------\n   * jQuery\n   * ------------------------------------------------------------------------\n   * add .Modal to jQuery only if jQuery is present\n   */\n\n  defineJQueryPlugin(Modal);\n\n  /**\n   * --------------------------------------------------------------------------\n   * Bootstrap (v5.1.0): offcanvas.js\n   * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n   * --------------------------------------------------------------------------\n   */\n  /**\n   * ------------------------------------------------------------------------\n   * Constants\n   * ------------------------------------------------------------------------\n   */\n\n  const NAME$5 = 'offcanvas';\n  const DATA_KEY$5 = 'bs.offcanvas';\n  const EVENT_KEY$5 = `.${DATA_KEY$5}`;\n  const DATA_API_KEY$2 = '.data-api';\n  const EVENT_LOAD_DATA_API$1 = `load${EVENT_KEY$5}${DATA_API_KEY$2}`;\n  const ESCAPE_KEY = 'Escape';\n  const Default$4 = {\n    backdrop: true,\n    keyboard: true,\n    scroll: false\n  };\n  const DefaultType$4 = {\n    backdrop: 'boolean',\n    keyboard: 'boolean',\n    scroll: 'boolean'\n  };\n  const CLASS_NAME_SHOW$3 = 'show';\n  const CLASS_NAME_BACKDROP = 'offcanvas-backdrop';\n  const OPEN_SELECTOR = '.offcanvas.show';\n  const EVENT_SHOW$2 = `show${EVENT_KEY$5}`;\n  const EVENT_SHOWN$2 = `shown${EVENT_KEY$5}`;\n  const EVENT_HIDE$2 = `hide${EVENT_KEY$5}`;\n  const EVENT_HIDDEN$2 = `hidden${EVENT_KEY$5}`;\n  const EVENT_CLICK_DATA_API$1 = `click${EVENT_KEY$5}${DATA_API_KEY$2}`;\n  const EVENT_KEYDOWN_DISMISS = `keydown.dismiss${EVENT_KEY$5}`;\n  const SELECTOR_DATA_TOGGLE$1 = '[data-bs-toggle=\"offcanvas\"]';\n  /**\n   * ------------------------------------------------------------------------\n   * Class Definition\n   * ------------------------------------------------------------------------\n   */\n\n  class Offcanvas extends BaseComponent {\n    constructor(element, config) {\n      super(element);\n      this._config = this._getConfig(config);\n      this._isShown = false;\n      this._backdrop = this._initializeBackDrop();\n      this._focustrap = this._initializeFocusTrap();\n\n      this._addEventListeners();\n    } // Getters\n\n\n    static get NAME() {\n      return NAME$5;\n    }\n\n    static get Default() {\n      return Default$4;\n    } // Public\n\n\n    toggle(relatedTarget) {\n      return this._isShown ? this.hide() : this.show(relatedTarget);\n    }\n\n    show(relatedTarget) {\n      if (this._isShown) {\n        return;\n      }\n\n      const showEvent = EventHandler.trigger(this._element, EVENT_SHOW$2, {\n        relatedTarget\n      });\n\n      if (showEvent.defaultPrevented) {\n        return;\n      }\n\n      this._isShown = true;\n      this._element.style.visibility = 'visible';\n\n      this._backdrop.show();\n\n      if (!this._config.scroll) {\n        new ScrollBarHelper().hide();\n      }\n\n      this._element.removeAttribute('aria-hidden');\n\n      this._element.setAttribute('aria-modal', true);\n\n      this._element.setAttribute('role', 'dialog');\n\n      this._element.classList.add(CLASS_NAME_SHOW$3);\n\n      const completeCallBack = () => {\n        if (!this._config.scroll) {\n          this._focustrap.activate();\n        }\n\n        EventHandler.trigger(this._element, EVENT_SHOWN$2, {\n          relatedTarget\n        });\n      };\n\n      this._queueCallback(completeCallBack, this._element, true);\n    }\n\n    hide() {\n      if (!this._isShown) {\n        return;\n      }\n\n      const hideEvent = EventHandler.trigger(this._element, EVENT_HIDE$2);\n\n      if (hideEvent.defaultPrevented) {\n        return;\n      }\n\n      this._focustrap.deactivate();\n\n      this._element.blur();\n\n      this._isShown = false;\n\n      this._element.classList.remove(CLASS_NAME_SHOW$3);\n\n      this._backdrop.hide();\n\n      const completeCallback = () => {\n        this._element.setAttribute('aria-hidden', true);\n\n        this._element.removeAttribute('aria-modal');\n\n        this._element.removeAttribute('role');\n\n        this._element.style.visibility = 'hidden';\n\n        if (!this._config.scroll) {\n          new ScrollBarHelper().reset();\n        }\n\n        EventHandler.trigger(this._element, EVENT_HIDDEN$2);\n      };\n\n      this._queueCallback(completeCallback, this._element, true);\n    }\n\n    dispose() {\n      this._backdrop.dispose();\n\n      this._focustrap.deactivate();\n\n      super.dispose();\n    } // Private\n\n\n    _getConfig(config) {\n      config = { ...Default$4,\n        ...Manipulator.getDataAttributes(this._element),\n        ...(typeof config === 'object' ? config : {})\n      };\n      typeCheckConfig(NAME$5, config, DefaultType$4);\n      return config;\n    }\n\n    _initializeBackDrop() {\n      return new Backdrop({\n        className: CLASS_NAME_BACKDROP,\n        isVisible: this._config.backdrop,\n        isAnimated: true,\n        rootElement: this._element.parentNode,\n        clickCallback: () => this.hide()\n      });\n    }\n\n    _initializeFocusTrap() {\n      return new FocusTrap({\n        trapElement: this._element\n      });\n    }\n\n    _addEventListeners() {\n      EventHandler.on(this._element, EVENT_KEYDOWN_DISMISS, event => {\n        if (this._config.keyboard && event.key === ESCAPE_KEY) {\n          this.hide();\n        }\n      });\n    } // Static\n\n\n    static jQueryInterface(config) {\n      return this.each(function () {\n        const data = Offcanvas.getOrCreateInstance(this, config);\n\n        if (typeof config !== 'string') {\n          return;\n        }\n\n        if (data[config] === undefined || config.startsWith('_') || config === 'constructor') {\n          throw new TypeError(`No method named \"${config}\"`);\n        }\n\n        data[config](this);\n      });\n    }\n\n  }\n  /**\n   * ------------------------------------------------------------------------\n   * Data Api implementation\n   * ------------------------------------------------------------------------\n   */\n\n\n  EventHandler.on(document, EVENT_CLICK_DATA_API$1, SELECTOR_DATA_TOGGLE$1, function (event) {\n    const target = getElementFromSelector(this);\n\n    if (['A', 'AREA'].includes(this.tagName)) {\n      event.preventDefault();\n    }\n\n    if (isDisabled(this)) {\n      return;\n    }\n\n    EventHandler.one(target, EVENT_HIDDEN$2, () => {\n      // focus on trigger when it is closed\n      if (isVisible(this)) {\n        this.focus();\n      }\n    }); // avoid conflict when clicking a toggler of an offcanvas, while another is open\n\n    const allReadyOpen = SelectorEngine.findOne(OPEN_SELECTOR);\n\n    if (allReadyOpen && allReadyOpen !== target) {\n      Offcanvas.getInstance(allReadyOpen).hide();\n    }\n\n    const data = Offcanvas.getOrCreateInstance(target);\n    data.toggle(this);\n  });\n  EventHandler.on(window, EVENT_LOAD_DATA_API$1, () => SelectorEngine.find(OPEN_SELECTOR).forEach(el => Offcanvas.getOrCreateInstance(el).show()));\n  enableDismissTrigger(Offcanvas);\n  /**\n   * ------------------------------------------------------------------------\n   * jQuery\n   * ------------------------------------------------------------------------\n   */\n\n  defineJQueryPlugin(Offcanvas);\n\n  /**\n   * --------------------------------------------------------------------------\n   * Bootstrap (v5.1.0): util/sanitizer.js\n   * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n   * --------------------------------------------------------------------------\n   */\n  const uriAttrs = new Set(['background', 'cite', 'href', 'itemtype', 'longdesc', 'poster', 'src', 'xlink:href']);\n  const ARIA_ATTRIBUTE_PATTERN = /^aria-[\\w-]*$/i;\n  /**\n   * A pattern that recognizes a commonly useful subset of URLs that are safe.\n   *\n   * Shoutout to Angular 7 https://github.com/angular/angular/blob/7.2.4/packages/core/src/sanitization/url_sanitizer.ts\n   */\n\n  const SAFE_URL_PATTERN = /^(?:(?:https?|mailto|ftp|tel|file):|[^#&/:?]*(?:[#/?]|$))/i;\n  /**\n   * A pattern that matches safe data URLs. Only matches image, video and audio types.\n   *\n   * Shoutout to Angular 7 https://github.com/angular/angular/blob/7.2.4/packages/core/src/sanitization/url_sanitizer.ts\n   */\n\n  const DATA_URL_PATTERN = /^data:(?:image\\/(?:bmp|gif|jpeg|jpg|png|tiff|webp)|video\\/(?:mpeg|mp4|ogg|webm)|audio\\/(?:mp3|oga|ogg|opus));base64,[\\d+/a-z]+=*$/i;\n\n  const allowedAttribute = (attr, allowedAttributeList) => {\n    const attrName = attr.nodeName.toLowerCase();\n\n    if (allowedAttributeList.includes(attrName)) {\n      if (uriAttrs.has(attrName)) {\n        return Boolean(SAFE_URL_PATTERN.test(attr.nodeValue) || DATA_URL_PATTERN.test(attr.nodeValue));\n      }\n\n      return true;\n    }\n\n    const regExp = allowedAttributeList.filter(attrRegex => attrRegex instanceof RegExp); // Check if a regular expression validates the attribute.\n\n    for (let i = 0, len = regExp.length; i < len; i++) {\n      if (regExp[i].test(attrName)) {\n        return true;\n      }\n    }\n\n    return false;\n  };\n\n  const DefaultAllowlist = {\n    // Global attributes allowed on any supplied element below.\n    '*': ['class', 'dir', 'id', 'lang', 'role', ARIA_ATTRIBUTE_PATTERN],\n    a: ['target', 'href', 'title', 'rel'],\n    area: [],\n    b: [],\n    br: [],\n    col: [],\n    code: [],\n    div: [],\n    em: [],\n    hr: [],\n    h1: [],\n    h2: [],\n    h3: [],\n    h4: [],\n    h5: [],\n    h6: [],\n    i: [],\n    img: ['src', 'srcset', 'alt', 'title', 'width', 'height'],\n    li: [],\n    ol: [],\n    p: [],\n    pre: [],\n    s: [],\n    small: [],\n    span: [],\n    sub: [],\n    sup: [],\n    strong: [],\n    u: [],\n    ul: []\n  };\n  function sanitizeHtml(unsafeHtml, allowList, sanitizeFn) {\n    if (!unsafeHtml.length) {\n      return unsafeHtml;\n    }\n\n    if (sanitizeFn && typeof sanitizeFn === 'function') {\n      return sanitizeFn(unsafeHtml);\n    }\n\n    const domParser = new window.DOMParser();\n    const createdDocument = domParser.parseFromString(unsafeHtml, 'text/html');\n    const allowlistKeys = Object.keys(allowList);\n    const elements = [].concat(...createdDocument.body.querySelectorAll('*'));\n\n    for (let i = 0, len = elements.length; i < len; i++) {\n      const el = elements[i];\n      const elName = el.nodeName.toLowerCase();\n\n      if (!allowlistKeys.includes(elName)) {\n        el.remove();\n        continue;\n      }\n\n      const attributeList = [].concat(...el.attributes);\n      const allowedAttributes = [].concat(allowList['*'] || [], allowList[elName] || []);\n      attributeList.forEach(attr => {\n        if (!allowedAttribute(attr, allowedAttributes)) {\n          el.removeAttribute(attr.nodeName);\n        }\n      });\n    }\n\n    return createdDocument.body.innerHTML;\n  }\n\n  /**\n   * --------------------------------------------------------------------------\n   * Bootstrap (v5.1.0): tooltip.js\n   * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n   * --------------------------------------------------------------------------\n   */\n  /**\n   * ------------------------------------------------------------------------\n   * Constants\n   * ------------------------------------------------------------------------\n   */\n\n  const NAME$4 = 'tooltip';\n  const DATA_KEY$4 = 'bs.tooltip';\n  const EVENT_KEY$4 = `.${DATA_KEY$4}`;\n  const CLASS_PREFIX$1 = 'bs-tooltip';\n  const DISALLOWED_ATTRIBUTES = new Set(['sanitize', 'allowList', 'sanitizeFn']);\n  const DefaultType$3 = {\n    animation: 'boolean',\n    template: 'string',\n    title: '(string|element|function)',\n    trigger: 'string',\n    delay: '(number|object)',\n    html: 'boolean',\n    selector: '(string|boolean)',\n    placement: '(string|function)',\n    offset: '(array|string|function)',\n    container: '(string|element|boolean)',\n    fallbackPlacements: 'array',\n    boundary: '(string|element)',\n    customClass: '(string|function)',\n    sanitize: 'boolean',\n    sanitizeFn: '(null|function)',\n    allowList: 'object',\n    popperConfig: '(null|object|function)'\n  };\n  const AttachmentMap = {\n    AUTO: 'auto',\n    TOP: 'top',\n    RIGHT: isRTL() ? 'left' : 'right',\n    BOTTOM: 'bottom',\n    LEFT: isRTL() ? 'right' : 'left'\n  };\n  const Default$3 = {\n    animation: true,\n    template: '<div class=\"tooltip\" role=\"tooltip\">' + '<div class=\"tooltip-arrow\"></div>' + '<div class=\"tooltip-inner\"></div>' + '</div>',\n    trigger: 'hover focus',\n    title: '',\n    delay: 0,\n    html: false,\n    selector: false,\n    placement: 'top',\n    offset: [0, 0],\n    container: false,\n    fallbackPlacements: ['top', 'right', 'bottom', 'left'],\n    boundary: 'clippingParents',\n    customClass: '',\n    sanitize: true,\n    sanitizeFn: null,\n    allowList: DefaultAllowlist,\n    popperConfig: null\n  };\n  const Event$2 = {\n    HIDE: `hide${EVENT_KEY$4}`,\n    HIDDEN: `hidden${EVENT_KEY$4}`,\n    SHOW: `show${EVENT_KEY$4}`,\n    SHOWN: `shown${EVENT_KEY$4}`,\n    INSERTED: `inserted${EVENT_KEY$4}`,\n    CLICK: `click${EVENT_KEY$4}`,\n    FOCUSIN: `focusin${EVENT_KEY$4}`,\n    FOCUSOUT: `focusout${EVENT_KEY$4}`,\n    MOUSEENTER: `mouseenter${EVENT_KEY$4}`,\n    MOUSELEAVE: `mouseleave${EVENT_KEY$4}`\n  };\n  const CLASS_NAME_FADE$2 = 'fade';\n  const CLASS_NAME_MODAL = 'modal';\n  const CLASS_NAME_SHOW$2 = 'show';\n  const HOVER_STATE_SHOW = 'show';\n  const HOVER_STATE_OUT = 'out';\n  const SELECTOR_TOOLTIP_INNER = '.tooltip-inner';\n  const SELECTOR_MODAL = `.${CLASS_NAME_MODAL}`;\n  const EVENT_MODAL_HIDE = 'hide.bs.modal';\n  const TRIGGER_HOVER = 'hover';\n  const TRIGGER_FOCUS = 'focus';\n  const TRIGGER_CLICK = 'click';\n  const TRIGGER_MANUAL = 'manual';\n  /**\n   * ------------------------------------------------------------------------\n   * Class Definition\n   * ------------------------------------------------------------------------\n   */\n\n  class Tooltip extends BaseComponent {\n    constructor(element, config) {\n      if (typeof Popper__namespace === 'undefined') {\n        throw new TypeError('Bootstrap\\'s tooltips require Popper (https://popper.js.org)');\n      }\n\n      super(element); // private\n\n      this._isEnabled = true;\n      this._timeout = 0;\n      this._hoverState = '';\n      this._activeTrigger = {};\n      this._popper = null; // Protected\n\n      this._config = this._getConfig(config);\n      this.tip = null;\n\n      this._setListeners();\n    } // Getters\n\n\n    static get Default() {\n      return Default$3;\n    }\n\n    static get NAME() {\n      return NAME$4;\n    }\n\n    static get Event() {\n      return Event$2;\n    }\n\n    static get DefaultType() {\n      return DefaultType$3;\n    } // Public\n\n\n    enable() {\n      this._isEnabled = true;\n    }\n\n    disable() {\n      this._isEnabled = false;\n    }\n\n    toggleEnabled() {\n      this._isEnabled = !this._isEnabled;\n    }\n\n    toggle(event) {\n      if (!this._isEnabled) {\n        return;\n      }\n\n      if (event) {\n        const context = this._initializeOnDelegatedTarget(event);\n\n        context._activeTrigger.click = !context._activeTrigger.click;\n\n        if (context._isWithActiveTrigger()) {\n          context._enter(null, context);\n        } else {\n          context._leave(null, context);\n        }\n      } else {\n        if (this.getTipElement().classList.contains(CLASS_NAME_SHOW$2)) {\n          this._leave(null, this);\n\n          return;\n        }\n\n        this._enter(null, this);\n      }\n    }\n\n    dispose() {\n      clearTimeout(this._timeout);\n      EventHandler.off(this._element.closest(SELECTOR_MODAL), EVENT_MODAL_HIDE, this._hideModalHandler);\n\n      if (this.tip) {\n        this.tip.remove();\n      }\n\n      if (this._popper) {\n        this._popper.destroy();\n      }\n\n      super.dispose();\n    }\n\n    show() {\n      if (this._element.style.display === 'none') {\n        throw new Error('Please use show on visible elements');\n      }\n\n      if (!(this.isWithContent() && this._isEnabled)) {\n        return;\n      }\n\n      const showEvent = EventHandler.trigger(this._element, this.constructor.Event.SHOW);\n      const shadowRoot = findShadowRoot(this._element);\n      const isInTheDom = shadowRoot === null ? this._element.ownerDocument.documentElement.contains(this._element) : shadowRoot.contains(this._element);\n\n      if (showEvent.defaultPrevented || !isInTheDom) {\n        return;\n      }\n\n      const tip = this.getTipElement();\n      const tipId = getUID(this.constructor.NAME);\n      tip.setAttribute('id', tipId);\n\n      this._element.setAttribute('aria-describedby', tipId);\n\n      if (this._config.animation) {\n        tip.classList.add(CLASS_NAME_FADE$2);\n      }\n\n      const placement = typeof this._config.placement === 'function' ? this._config.placement.call(this, tip, this._element) : this._config.placement;\n\n      const attachment = this._getAttachment(placement);\n\n      this._addAttachmentClass(attachment);\n\n      const {\n        container\n      } = this._config;\n      Data.set(tip, this.constructor.DATA_KEY, this);\n\n      if (!this._element.ownerDocument.documentElement.contains(this.tip)) {\n        container.append(tip);\n        EventHandler.trigger(this._element, this.constructor.Event.INSERTED);\n      }\n\n      if (this._popper) {\n        this._popper.update();\n      } else {\n        this._popper = Popper__namespace.createPopper(this._element, tip, this._getPopperConfig(attachment));\n      }\n\n      tip.classList.add(CLASS_NAME_SHOW$2);\n\n      const customClass = this._resolvePossibleFunction(this._config.customClass);\n\n      if (customClass) {\n        tip.classList.add(...customClass.split(' '));\n      } // If this is a touch-enabled device we add extra\n      // empty mouseover listeners to the body's immediate children;\n      // only needed because of broken event delegation on iOS\n      // https://www.quirksmode.org/blog/archives/2014/02/mouse_event_bub.html\n\n\n      if ('ontouchstart' in document.documentElement) {\n        [].concat(...document.body.children).forEach(element => {\n          EventHandler.on(element, 'mouseover', noop);\n        });\n      }\n\n      const complete = () => {\n        const prevHoverState = this._hoverState;\n        this._hoverState = null;\n        EventHandler.trigger(this._element, this.constructor.Event.SHOWN);\n\n        if (prevHoverState === HOVER_STATE_OUT) {\n          this._leave(null, this);\n        }\n      };\n\n      const isAnimated = this.tip.classList.contains(CLASS_NAME_FADE$2);\n\n      this._queueCallback(complete, this.tip, isAnimated);\n    }\n\n    hide() {\n      if (!this._popper) {\n        return;\n      }\n\n      const tip = this.getTipElement();\n\n      const complete = () => {\n        if (this._isWithActiveTrigger()) {\n          return;\n        }\n\n        if (this._hoverState !== HOVER_STATE_SHOW) {\n          tip.remove();\n        }\n\n        this._cleanTipClass();\n\n        this._element.removeAttribute('aria-describedby');\n\n        EventHandler.trigger(this._element, this.constructor.Event.HIDDEN);\n\n        if (this._popper) {\n          this._popper.destroy();\n\n          this._popper = null;\n        }\n      };\n\n      const hideEvent = EventHandler.trigger(this._element, this.constructor.Event.HIDE);\n\n      if (hideEvent.defaultPrevented) {\n        return;\n      }\n\n      tip.classList.remove(CLASS_NAME_SHOW$2); // If this is a touch-enabled device we remove the extra\n      // empty mouseover listeners we added for iOS support\n\n      if ('ontouchstart' in document.documentElement) {\n        [].concat(...document.body.children).forEach(element => EventHandler.off(element, 'mouseover', noop));\n      }\n\n      this._activeTrigger[TRIGGER_CLICK] = false;\n      this._activeTrigger[TRIGGER_FOCUS] = false;\n      this._activeTrigger[TRIGGER_HOVER] = false;\n      const isAnimated = this.tip.classList.contains(CLASS_NAME_FADE$2);\n\n      this._queueCallback(complete, this.tip, isAnimated);\n\n      this._hoverState = '';\n    }\n\n    update() {\n      if (this._popper !== null) {\n        this._popper.update();\n      }\n    } // Protected\n\n\n    isWithContent() {\n      return Boolean(this.getTitle());\n    }\n\n    getTipElement() {\n      if (this.tip) {\n        return this.tip;\n      }\n\n      const element = document.createElement('div');\n      element.innerHTML = this._config.template;\n      const tip = element.children[0];\n      this.setContent(tip);\n      tip.classList.remove(CLASS_NAME_FADE$2, CLASS_NAME_SHOW$2);\n      this.tip = tip;\n      return this.tip;\n    }\n\n    setContent(tip) {\n      this._sanitizeAndSetContent(tip, this.getTitle(), SELECTOR_TOOLTIP_INNER);\n    }\n\n    _sanitizeAndSetContent(template, content, selector) {\n      const templateElement = SelectorEngine.findOne(selector, template);\n\n      if (!content && templateElement) {\n        templateElement.remove();\n        return;\n      } // we use append for html objects to maintain js events\n\n\n      this.setElementContent(templateElement, content);\n    }\n\n    setElementContent(element, content) {\n      if (element === null) {\n        return;\n      }\n\n      if (isElement(content)) {\n        content = getElement(content); // content is a DOM node or a jQuery\n\n        if (this._config.html) {\n          if (content.parentNode !== element) {\n            element.innerHTML = '';\n            element.append(content);\n          }\n        } else {\n          element.textContent = content.textContent;\n        }\n\n        return;\n      }\n\n      if (this._config.html) {\n        if (this._config.sanitize) {\n          content = sanitizeHtml(content, this._config.allowList, this._config.sanitizeFn);\n        }\n\n        element.innerHTML = content;\n      } else {\n        element.textContent = content;\n      }\n    }\n\n    getTitle() {\n      const title = this._element.getAttribute('data-bs-original-title') || this._config.title;\n\n      return this._resolvePossibleFunction(title);\n    }\n\n    updateAttachment(attachment) {\n      if (attachment === 'right') {\n        return 'end';\n      }\n\n      if (attachment === 'left') {\n        return 'start';\n      }\n\n      return attachment;\n    } // Private\n\n\n    _initializeOnDelegatedTarget(event, context) {\n      return context || this.constructor.getOrCreateInstance(event.delegateTarget, this._getDelegateConfig());\n    }\n\n    _getOffset() {\n      const {\n        offset\n      } = this._config;\n\n      if (typeof offset === 'string') {\n        return offset.split(',').map(val => Number.parseInt(val, 10));\n      }\n\n      if (typeof offset === 'function') {\n        return popperData => offset(popperData, this._element);\n      }\n\n      return offset;\n    }\n\n    _resolvePossibleFunction(content) {\n      return typeof content === 'function' ? content.call(this._element) : content;\n    }\n\n    _getPopperConfig(attachment) {\n      const defaultBsPopperConfig = {\n        placement: attachment,\n        modifiers: [{\n          name: 'flip',\n          options: {\n            fallbackPlacements: this._config.fallbackPlacements\n          }\n        }, {\n          name: 'offset',\n          options: {\n            offset: this._getOffset()\n          }\n        }, {\n          name: 'preventOverflow',\n          options: {\n            boundary: this._config.boundary\n          }\n        }, {\n          name: 'arrow',\n          options: {\n            element: `.${this.constructor.NAME}-arrow`\n          }\n        }, {\n          name: 'onChange',\n          enabled: true,\n          phase: 'afterWrite',\n          fn: data => this._handlePopperPlacementChange(data)\n        }],\n        onFirstUpdate: data => {\n          if (data.options.placement !== data.placement) {\n            this._handlePopperPlacementChange(data);\n          }\n        }\n      };\n      return { ...defaultBsPopperConfig,\n        ...(typeof this._config.popperConfig === 'function' ? this._config.popperConfig(defaultBsPopperConfig) : this._config.popperConfig)\n      };\n    }\n\n    _addAttachmentClass(attachment) {\n      this.getTipElement().classList.add(`${this._getBasicClassPrefix()}-${this.updateAttachment(attachment)}`);\n    }\n\n    _getAttachment(placement) {\n      return AttachmentMap[placement.toUpperCase()];\n    }\n\n    _setListeners() {\n      const triggers = this._config.trigger.split(' ');\n\n      triggers.forEach(trigger => {\n        if (trigger === 'click') {\n          EventHandler.on(this._element, this.constructor.Event.CLICK, this._config.selector, event => this.toggle(event));\n        } else if (trigger !== TRIGGER_MANUAL) {\n          const eventIn = trigger === TRIGGER_HOVER ? this.constructor.Event.MOUSEENTER : this.constructor.Event.FOCUSIN;\n          const eventOut = trigger === TRIGGER_HOVER ? this.constructor.Event.MOUSELEAVE : this.constructor.Event.FOCUSOUT;\n          EventHandler.on(this._element, eventIn, this._config.selector, event => this._enter(event));\n          EventHandler.on(this._element, eventOut, this._config.selector, event => this._leave(event));\n        }\n      });\n\n      this._hideModalHandler = () => {\n        if (this._element) {\n          this.hide();\n        }\n      };\n\n      EventHandler.on(this._element.closest(SELECTOR_MODAL), EVENT_MODAL_HIDE, this._hideModalHandler);\n\n      if (this._config.selector) {\n        this._config = { ...this._config,\n          trigger: 'manual',\n          selector: ''\n        };\n      } else {\n        this._fixTitle();\n      }\n    }\n\n    _fixTitle() {\n      const title = this._element.getAttribute('title');\n\n      const originalTitleType = typeof this._element.getAttribute('data-bs-original-title');\n\n      if (title || originalTitleType !== 'string') {\n        this._element.setAttribute('data-bs-original-title', title || '');\n\n        if (title && !this._element.getAttribute('aria-label') && !this._element.textContent) {\n          this._element.setAttribute('aria-label', title);\n        }\n\n        this._element.setAttribute('title', '');\n      }\n    }\n\n    _enter(event, context) {\n      context = this._initializeOnDelegatedTarget(event, context);\n\n      if (event) {\n        context._activeTrigger[event.type === 'focusin' ? TRIGGER_FOCUS : TRIGGER_HOVER] = true;\n      }\n\n      if (context.getTipElement().classList.contains(CLASS_NAME_SHOW$2) || context._hoverState === HOVER_STATE_SHOW) {\n        context._hoverState = HOVER_STATE_SHOW;\n        return;\n      }\n\n      clearTimeout(context._timeout);\n      context._hoverState = HOVER_STATE_SHOW;\n\n      if (!context._config.delay || !context._config.delay.show) {\n        context.show();\n        return;\n      }\n\n      context._timeout = setTimeout(() => {\n        if (context._hoverState === HOVER_STATE_SHOW) {\n          context.show();\n        }\n      }, context._config.delay.show);\n    }\n\n    _leave(event, context) {\n      context = this._initializeOnDelegatedTarget(event, context);\n\n      if (event) {\n        context._activeTrigger[event.type === 'focusout' ? TRIGGER_FOCUS : TRIGGER_HOVER] = context._element.contains(event.relatedTarget);\n      }\n\n      if (context._isWithActiveTrigger()) {\n        return;\n      }\n\n      clearTimeout(context._timeout);\n      context._hoverState = HOVER_STATE_OUT;\n\n      if (!context._config.delay || !context._config.delay.hide) {\n        context.hide();\n        return;\n      }\n\n      context._timeout = setTimeout(() => {\n        if (context._hoverState === HOVER_STATE_OUT) {\n          context.hide();\n        }\n      }, context._config.delay.hide);\n    }\n\n    _isWithActiveTrigger() {\n      for (const trigger in this._activeTrigger) {\n        if (this._activeTrigger[trigger]) {\n          return true;\n        }\n      }\n\n      return false;\n    }\n\n    _getConfig(config) {\n      const dataAttributes = Manipulator.getDataAttributes(this._element);\n      Object.keys(dataAttributes).forEach(dataAttr => {\n        if (DISALLOWED_ATTRIBUTES.has(dataAttr)) {\n          delete dataAttributes[dataAttr];\n        }\n      });\n      config = { ...this.constructor.Default,\n        ...dataAttributes,\n        ...(typeof config === 'object' && config ? config : {})\n      };\n      config.container = config.container === false ? document.body : getElement(config.container);\n\n      if (typeof config.delay === 'number') {\n        config.delay = {\n          show: config.delay,\n          hide: config.delay\n        };\n      }\n\n      if (typeof config.title === 'number') {\n        config.title = config.title.toString();\n      }\n\n      if (typeof config.content === 'number') {\n        config.content = config.content.toString();\n      }\n\n      typeCheckConfig(NAME$4, config, this.constructor.DefaultType);\n\n      if (config.sanitize) {\n        config.template = sanitizeHtml(config.template, config.allowList, config.sanitizeFn);\n      }\n\n      return config;\n    }\n\n    _getDelegateConfig() {\n      const config = {};\n\n      for (const key in this._config) {\n        if (this.constructor.Default[key] !== this._config[key]) {\n          config[key] = this._config[key];\n        }\n      } // In the future can be replaced with:\n      // const keysWithDifferentValues = Object.entries(this._config).filter(entry => this.constructor.Default[entry[0]] !== this._config[entry[0]])\n      // `Object.fromEntries(keysWithDifferentValues)`\n\n\n      return config;\n    }\n\n    _cleanTipClass() {\n      const tip = this.getTipElement();\n      const basicClassPrefixRegex = new RegExp(`(^|\\\\s)${this._getBasicClassPrefix()}\\\\S+`, 'g');\n      const tabClass = tip.getAttribute('class').match(basicClassPrefixRegex);\n\n      if (tabClass !== null && tabClass.length > 0) {\n        tabClass.map(token => token.trim()).forEach(tClass => tip.classList.remove(tClass));\n      }\n    }\n\n    _getBasicClassPrefix() {\n      return CLASS_PREFIX$1;\n    }\n\n    _handlePopperPlacementChange(popperData) {\n      const {\n        state\n      } = popperData;\n\n      if (!state) {\n        return;\n      }\n\n      this.tip = state.elements.popper;\n\n      this._cleanTipClass();\n\n      this._addAttachmentClass(this._getAttachment(state.placement));\n    } // Static\n\n\n    static jQueryInterface(config) {\n      return this.each(function () {\n        const data = Tooltip.getOrCreateInstance(this, config);\n\n        if (typeof config === 'string') {\n          if (typeof data[config] === 'undefined') {\n            throw new TypeError(`No method named \"${config}\"`);\n          }\n\n          data[config]();\n        }\n      });\n    }\n\n  }\n  /**\n   * ------------------------------------------------------------------------\n   * jQuery\n   * ------------------------------------------------------------------------\n   * add .Tooltip to jQuery only if jQuery is present\n   */\n\n\n  defineJQueryPlugin(Tooltip);\n\n  /**\n   * --------------------------------------------------------------------------\n   * Bootstrap (v5.1.0): popover.js\n   * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n   * --------------------------------------------------------------------------\n   */\n  /**\n   * ------------------------------------------------------------------------\n   * Constants\n   * ------------------------------------------------------------------------\n   */\n\n  const NAME$3 = 'popover';\n  const DATA_KEY$3 = 'bs.popover';\n  const EVENT_KEY$3 = `.${DATA_KEY$3}`;\n  const CLASS_PREFIX = 'bs-popover';\n  const Default$2 = { ...Tooltip.Default,\n    placement: 'right',\n    offset: [0, 8],\n    trigger: 'click',\n    content: '',\n    template: '<div class=\"popover\" role=\"tooltip\">' + '<div class=\"popover-arrow\"></div>' + '<h3 class=\"popover-header\"></h3>' + '<div class=\"popover-body\"></div>' + '</div>'\n  };\n  const DefaultType$2 = { ...Tooltip.DefaultType,\n    content: '(string|element|function)'\n  };\n  const Event$1 = {\n    HIDE: `hide${EVENT_KEY$3}`,\n    HIDDEN: `hidden${EVENT_KEY$3}`,\n    SHOW: `show${EVENT_KEY$3}`,\n    SHOWN: `shown${EVENT_KEY$3}`,\n    INSERTED: `inserted${EVENT_KEY$3}`,\n    CLICK: `click${EVENT_KEY$3}`,\n    FOCUSIN: `focusin${EVENT_KEY$3}`,\n    FOCUSOUT: `focusout${EVENT_KEY$3}`,\n    MOUSEENTER: `mouseenter${EVENT_KEY$3}`,\n    MOUSELEAVE: `mouseleave${EVENT_KEY$3}`\n  };\n  const SELECTOR_TITLE = '.popover-header';\n  const SELECTOR_CONTENT = '.popover-body';\n  /**\n   * ------------------------------------------------------------------------\n   * Class Definition\n   * ------------------------------------------------------------------------\n   */\n\n  class Popover extends Tooltip {\n    // Getters\n    static get Default() {\n      return Default$2;\n    }\n\n    static get NAME() {\n      return NAME$3;\n    }\n\n    static get Event() {\n      return Event$1;\n    }\n\n    static get DefaultType() {\n      return DefaultType$2;\n    } // Overrides\n\n\n    isWithContent() {\n      return this.getTitle() || this._getContent();\n    }\n\n    setContent(tip) {\n      this._sanitizeAndSetContent(tip, this.getTitle(), SELECTOR_TITLE);\n\n      this._sanitizeAndSetContent(tip, this._getContent(), SELECTOR_CONTENT);\n    } // Private\n\n\n    _getContent() {\n      return this._resolvePossibleFunction(this._config.content);\n    }\n\n    _getBasicClassPrefix() {\n      return CLASS_PREFIX;\n    } // Static\n\n\n    static jQueryInterface(config) {\n      return this.each(function () {\n        const data = Popover.getOrCreateInstance(this, config);\n\n        if (typeof config === 'string') {\n          if (typeof data[config] === 'undefined') {\n            throw new TypeError(`No method named \"${config}\"`);\n          }\n\n          data[config]();\n        }\n      });\n    }\n\n  }\n  /**\n   * ------------------------------------------------------------------------\n   * jQuery\n   * ------------------------------------------------------------------------\n   * add .Popover to jQuery only if jQuery is present\n   */\n\n\n  defineJQueryPlugin(Popover);\n\n  /**\n   * --------------------------------------------------------------------------\n   * Bootstrap (v5.1.0): scrollspy.js\n   * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n   * --------------------------------------------------------------------------\n   */\n  /**\n   * ------------------------------------------------------------------------\n   * Constants\n   * ------------------------------------------------------------------------\n   */\n\n  const NAME$2 = 'scrollspy';\n  const DATA_KEY$2 = 'bs.scrollspy';\n  const EVENT_KEY$2 = `.${DATA_KEY$2}`;\n  const DATA_API_KEY$1 = '.data-api';\n  const Default$1 = {\n    offset: 10,\n    method: 'auto',\n    target: ''\n  };\n  const DefaultType$1 = {\n    offset: 'number',\n    method: 'string',\n    target: '(string|element)'\n  };\n  const EVENT_ACTIVATE = `activate${EVENT_KEY$2}`;\n  const EVENT_SCROLL = `scroll${EVENT_KEY$2}`;\n  const EVENT_LOAD_DATA_API = `load${EVENT_KEY$2}${DATA_API_KEY$1}`;\n  const CLASS_NAME_DROPDOWN_ITEM = 'dropdown-item';\n  const CLASS_NAME_ACTIVE$1 = 'active';\n  const SELECTOR_DATA_SPY = '[data-bs-spy=\"scroll\"]';\n  const SELECTOR_NAV_LIST_GROUP$1 = '.nav, .list-group';\n  const SELECTOR_NAV_LINKS = '.nav-link';\n  const SELECTOR_NAV_ITEMS = '.nav-item';\n  const SELECTOR_LIST_ITEMS = '.list-group-item';\n  const SELECTOR_LINK_ITEMS = `${SELECTOR_NAV_LINKS}, ${SELECTOR_LIST_ITEMS}, .${CLASS_NAME_DROPDOWN_ITEM}`;\n  const SELECTOR_DROPDOWN$1 = '.dropdown';\n  const SELECTOR_DROPDOWN_TOGGLE$1 = '.dropdown-toggle';\n  const METHOD_OFFSET = 'offset';\n  const METHOD_POSITION = 'position';\n  /**\n   * ------------------------------------------------------------------------\n   * Class Definition\n   * ------------------------------------------------------------------------\n   */\n\n  class ScrollSpy extends BaseComponent {\n    constructor(element, config) {\n      super(element);\n      this._scrollElement = this._element.tagName === 'BODY' ? window : this._element;\n      this._config = this._getConfig(config);\n      this._offsets = [];\n      this._targets = [];\n      this._activeTarget = null;\n      this._scrollHeight = 0;\n      EventHandler.on(this._scrollElement, EVENT_SCROLL, () => this._process());\n      this.refresh();\n\n      this._process();\n    } // Getters\n\n\n    static get Default() {\n      return Default$1;\n    }\n\n    static get NAME() {\n      return NAME$2;\n    } // Public\n\n\n    refresh() {\n      const autoMethod = this._scrollElement === this._scrollElement.window ? METHOD_OFFSET : METHOD_POSITION;\n      const offsetMethod = this._config.method === 'auto' ? autoMethod : this._config.method;\n      const offsetBase = offsetMethod === METHOD_POSITION ? this._getScrollTop() : 0;\n      this._offsets = [];\n      this._targets = [];\n      this._scrollHeight = this._getScrollHeight();\n      const targets = SelectorEngine.find(SELECTOR_LINK_ITEMS, this._config.target);\n      targets.map(element => {\n        const targetSelector = getSelectorFromElement(element);\n        const target = targetSelector ? SelectorEngine.findOne(targetSelector) : null;\n\n        if (target) {\n          const targetBCR = target.getBoundingClientRect();\n\n          if (targetBCR.width || targetBCR.height) {\n            return [Manipulator[offsetMethod](target).top + offsetBase, targetSelector];\n          }\n        }\n\n        return null;\n      }).filter(item => item).sort((a, b) => a[0] - b[0]).forEach(item => {\n        this._offsets.push(item[0]);\n\n        this._targets.push(item[1]);\n      });\n    }\n\n    dispose() {\n      EventHandler.off(this._scrollElement, EVENT_KEY$2);\n      super.dispose();\n    } // Private\n\n\n    _getConfig(config) {\n      config = { ...Default$1,\n        ...Manipulator.getDataAttributes(this._element),\n        ...(typeof config === 'object' && config ? config : {})\n      };\n      config.target = getElement(config.target) || document.documentElement;\n      typeCheckConfig(NAME$2, config, DefaultType$1);\n      return config;\n    }\n\n    _getScrollTop() {\n      return this._scrollElement === window ? this._scrollElement.pageYOffset : this._scrollElement.scrollTop;\n    }\n\n    _getScrollHeight() {\n      return this._scrollElement.scrollHeight || Math.max(document.body.scrollHeight, document.documentElement.scrollHeight);\n    }\n\n    _getOffsetHeight() {\n      return this._scrollElement === window ? window.innerHeight : this._scrollElement.getBoundingClientRect().height;\n    }\n\n    _process() {\n      const scrollTop = this._getScrollTop() + this._config.offset;\n\n      const scrollHeight = this._getScrollHeight();\n\n      const maxScroll = this._config.offset + scrollHeight - this._getOffsetHeight();\n\n      if (this._scrollHeight !== scrollHeight) {\n        this.refresh();\n      }\n\n      if (scrollTop >= maxScroll) {\n        const target = this._targets[this._targets.length - 1];\n\n        if (this._activeTarget !== target) {\n          this._activate(target);\n        }\n\n        return;\n      }\n\n      if (this._activeTarget && scrollTop < this._offsets[0] && this._offsets[0] > 0) {\n        this._activeTarget = null;\n\n        this._clear();\n\n        return;\n      }\n\n      for (let i = this._offsets.length; i--;) {\n        const isActiveTarget = this._activeTarget !== this._targets[i] && scrollTop >= this._offsets[i] && (typeof this._offsets[i + 1] === 'undefined' || scrollTop < this._offsets[i + 1]);\n\n        if (isActiveTarget) {\n          this._activate(this._targets[i]);\n        }\n      }\n    }\n\n    _activate(target) {\n      this._activeTarget = target;\n\n      this._clear();\n\n      const queries = SELECTOR_LINK_ITEMS.split(',').map(selector => `${selector}[data-bs-target=\"${target}\"],${selector}[href=\"${target}\"]`);\n      const link = SelectorEngine.findOne(queries.join(','), this._config.target);\n      link.classList.add(CLASS_NAME_ACTIVE$1);\n\n      if (link.classList.contains(CLASS_NAME_DROPDOWN_ITEM)) {\n        SelectorEngine.findOne(SELECTOR_DROPDOWN_TOGGLE$1, link.closest(SELECTOR_DROPDOWN$1)).classList.add(CLASS_NAME_ACTIVE$1);\n      } else {\n        SelectorEngine.parents(link, SELECTOR_NAV_LIST_GROUP$1).forEach(listGroup => {\n          // Set triggered links parents as active\n          // With both <ul> and <nav> markup a parent is the previous sibling of any nav ancestor\n          SelectorEngine.prev(listGroup, `${SELECTOR_NAV_LINKS}, ${SELECTOR_LIST_ITEMS}`).forEach(item => item.classList.add(CLASS_NAME_ACTIVE$1)); // Handle special case when .nav-link is inside .nav-item\n\n          SelectorEngine.prev(listGroup, SELECTOR_NAV_ITEMS).forEach(navItem => {\n            SelectorEngine.children(navItem, SELECTOR_NAV_LINKS).forEach(item => item.classList.add(CLASS_NAME_ACTIVE$1));\n          });\n        });\n      }\n\n      EventHandler.trigger(this._scrollElement, EVENT_ACTIVATE, {\n        relatedTarget: target\n      });\n    }\n\n    _clear() {\n      SelectorEngine.find(SELECTOR_LINK_ITEMS, this._config.target).filter(node => node.classList.contains(CLASS_NAME_ACTIVE$1)).forEach(node => node.classList.remove(CLASS_NAME_ACTIVE$1));\n    } // Static\n\n\n    static jQueryInterface(config) {\n      return this.each(function () {\n        const data = ScrollSpy.getOrCreateInstance(this, config);\n\n        if (typeof config !== 'string') {\n          return;\n        }\n\n        if (typeof data[config] === 'undefined') {\n          throw new TypeError(`No method named \"${config}\"`);\n        }\n\n        data[config]();\n      });\n    }\n\n  }\n  /**\n   * ------------------------------------------------------------------------\n   * Data Api implementation\n   * ------------------------------------------------------------------------\n   */\n\n\n  EventHandler.on(window, EVENT_LOAD_DATA_API, () => {\n    SelectorEngine.find(SELECTOR_DATA_SPY).forEach(spy => new ScrollSpy(spy));\n  });\n  /**\n   * ------------------------------------------------------------------------\n   * jQuery\n   * ------------------------------------------------------------------------\n   * add .ScrollSpy to jQuery only if jQuery is present\n   */\n\n  defineJQueryPlugin(ScrollSpy);\n\n  /**\n   * --------------------------------------------------------------------------\n   * Bootstrap (v5.1.0): tab.js\n   * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n   * --------------------------------------------------------------------------\n   */\n  /**\n   * ------------------------------------------------------------------------\n   * Constants\n   * ------------------------------------------------------------------------\n   */\n\n  const NAME$1 = 'tab';\n  const DATA_KEY$1 = 'bs.tab';\n  const EVENT_KEY$1 = `.${DATA_KEY$1}`;\n  const DATA_API_KEY = '.data-api';\n  const EVENT_HIDE$1 = `hide${EVENT_KEY$1}`;\n  const EVENT_HIDDEN$1 = `hidden${EVENT_KEY$1}`;\n  const EVENT_SHOW$1 = `show${EVENT_KEY$1}`;\n  const EVENT_SHOWN$1 = `shown${EVENT_KEY$1}`;\n  const EVENT_CLICK_DATA_API = `click${EVENT_KEY$1}${DATA_API_KEY}`;\n  const CLASS_NAME_DROPDOWN_MENU = 'dropdown-menu';\n  const CLASS_NAME_ACTIVE = 'active';\n  const CLASS_NAME_FADE$1 = 'fade';\n  const CLASS_NAME_SHOW$1 = 'show';\n  const SELECTOR_DROPDOWN = '.dropdown';\n  const SELECTOR_NAV_LIST_GROUP = '.nav, .list-group';\n  const SELECTOR_ACTIVE = '.active';\n  const SELECTOR_ACTIVE_UL = ':scope > li > .active';\n  const SELECTOR_DATA_TOGGLE = '[data-bs-toggle=\"tab\"], [data-bs-toggle=\"pill\"], [data-bs-toggle=\"list\"]';\n  const SELECTOR_DROPDOWN_TOGGLE = '.dropdown-toggle';\n  const SELECTOR_DROPDOWN_ACTIVE_CHILD = ':scope > .dropdown-menu .active';\n  /**\n   * ------------------------------------------------------------------------\n   * Class Definition\n   * ------------------------------------------------------------------------\n   */\n\n  class Tab extends BaseComponent {\n    // Getters\n    static get NAME() {\n      return NAME$1;\n    } // Public\n\n\n    show() {\n      if (this._element.parentNode && this._element.parentNode.nodeType === Node.ELEMENT_NODE && this._element.classList.contains(CLASS_NAME_ACTIVE)) {\n        return;\n      }\n\n      let previous;\n      const target = getElementFromSelector(this._element);\n\n      const listElement = this._element.closest(SELECTOR_NAV_LIST_GROUP);\n\n      if (listElement) {\n        const itemSelector = listElement.nodeName === 'UL' || listElement.nodeName === 'OL' ? SELECTOR_ACTIVE_UL : SELECTOR_ACTIVE;\n        previous = SelectorEngine.find(itemSelector, listElement);\n        previous = previous[previous.length - 1];\n      }\n\n      const hideEvent = previous ? EventHandler.trigger(previous, EVENT_HIDE$1, {\n        relatedTarget: this._element\n      }) : null;\n      const showEvent = EventHandler.trigger(this._element, EVENT_SHOW$1, {\n        relatedTarget: previous\n      });\n\n      if (showEvent.defaultPrevented || hideEvent !== null && hideEvent.defaultPrevented) {\n        return;\n      }\n\n      this._activate(this._element, listElement);\n\n      const complete = () => {\n        EventHandler.trigger(previous, EVENT_HIDDEN$1, {\n          relatedTarget: this._element\n        });\n        EventHandler.trigger(this._element, EVENT_SHOWN$1, {\n          relatedTarget: previous\n        });\n      };\n\n      if (target) {\n        this._activate(target, target.parentNode, complete);\n      } else {\n        complete();\n      }\n    } // Private\n\n\n    _activate(element, container, callback) {\n      const activeElements = container && (container.nodeName === 'UL' || container.nodeName === 'OL') ? SelectorEngine.find(SELECTOR_ACTIVE_UL, container) : SelectorEngine.children(container, SELECTOR_ACTIVE);\n      const active = activeElements[0];\n      const isTransitioning = callback && active && active.classList.contains(CLASS_NAME_FADE$1);\n\n      const complete = () => this._transitionComplete(element, active, callback);\n\n      if (active && isTransitioning) {\n        active.classList.remove(CLASS_NAME_SHOW$1);\n\n        this._queueCallback(complete, element, true);\n      } else {\n        complete();\n      }\n    }\n\n    _transitionComplete(element, active, callback) {\n      if (active) {\n        active.classList.remove(CLASS_NAME_ACTIVE);\n        const dropdownChild = SelectorEngine.findOne(SELECTOR_DROPDOWN_ACTIVE_CHILD, active.parentNode);\n\n        if (dropdownChild) {\n          dropdownChild.classList.remove(CLASS_NAME_ACTIVE);\n        }\n\n        if (active.getAttribute('role') === 'tab') {\n          active.setAttribute('aria-selected', false);\n        }\n      }\n\n      element.classList.add(CLASS_NAME_ACTIVE);\n\n      if (element.getAttribute('role') === 'tab') {\n        element.setAttribute('aria-selected', true);\n      }\n\n      reflow(element);\n\n      if (element.classList.contains(CLASS_NAME_FADE$1)) {\n        element.classList.add(CLASS_NAME_SHOW$1);\n      }\n\n      let parent = element.parentNode;\n\n      if (parent && parent.nodeName === 'LI') {\n        parent = parent.parentNode;\n      }\n\n      if (parent && parent.classList.contains(CLASS_NAME_DROPDOWN_MENU)) {\n        const dropdownElement = element.closest(SELECTOR_DROPDOWN);\n\n        if (dropdownElement) {\n          SelectorEngine.find(SELECTOR_DROPDOWN_TOGGLE, dropdownElement).forEach(dropdown => dropdown.classList.add(CLASS_NAME_ACTIVE));\n        }\n\n        element.setAttribute('aria-expanded', true);\n      }\n\n      if (callback) {\n        callback();\n      }\n    } // Static\n\n\n    static jQueryInterface(config) {\n      return this.each(function () {\n        const data = Tab.getOrCreateInstance(this);\n\n        if (typeof config === 'string') {\n          if (typeof data[config] === 'undefined') {\n            throw new TypeError(`No method named \"${config}\"`);\n          }\n\n          data[config]();\n        }\n      });\n    }\n\n  }\n  /**\n   * ------------------------------------------------------------------------\n   * Data Api implementation\n   * ------------------------------------------------------------------------\n   */\n\n\n  EventHandler.on(document, EVENT_CLICK_DATA_API, SELECTOR_DATA_TOGGLE, function (event) {\n    if (['A', 'AREA'].includes(this.tagName)) {\n      event.preventDefault();\n    }\n\n    if (isDisabled(this)) {\n      return;\n    }\n\n    const data = Tab.getOrCreateInstance(this);\n    data.show();\n  });\n  /**\n   * ------------------------------------------------------------------------\n   * jQuery\n   * ------------------------------------------------------------------------\n   * add .Tab to jQuery only if jQuery is present\n   */\n\n  defineJQueryPlugin(Tab);\n\n  /**\n   * --------------------------------------------------------------------------\n   * Bootstrap (v5.1.0): toast.js\n   * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n   * --------------------------------------------------------------------------\n   */\n  /**\n   * ------------------------------------------------------------------------\n   * Constants\n   * ------------------------------------------------------------------------\n   */\n\n  const NAME = 'toast';\n  const DATA_KEY = 'bs.toast';\n  const EVENT_KEY = `.${DATA_KEY}`;\n  const EVENT_MOUSEOVER = `mouseover${EVENT_KEY}`;\n  const EVENT_MOUSEOUT = `mouseout${EVENT_KEY}`;\n  const EVENT_FOCUSIN = `focusin${EVENT_KEY}`;\n  const EVENT_FOCUSOUT = `focusout${EVENT_KEY}`;\n  const EVENT_HIDE = `hide${EVENT_KEY}`;\n  const EVENT_HIDDEN = `hidden${EVENT_KEY}`;\n  const EVENT_SHOW = `show${EVENT_KEY}`;\n  const EVENT_SHOWN = `shown${EVENT_KEY}`;\n  const CLASS_NAME_FADE = 'fade';\n  const CLASS_NAME_HIDE = 'hide'; // @deprecated - kept here only for backwards compatibility\n\n  const CLASS_NAME_SHOW = 'show';\n  const CLASS_NAME_SHOWING = 'showing';\n  const DefaultType = {\n    animation: 'boolean',\n    autohide: 'boolean',\n    delay: 'number'\n  };\n  const Default = {\n    animation: true,\n    autohide: true,\n    delay: 5000\n  };\n  /**\n   * ------------------------------------------------------------------------\n   * Class Definition\n   * ------------------------------------------------------------------------\n   */\n\n  class Toast extends BaseComponent {\n    constructor(element, config) {\n      super(element);\n      this._config = this._getConfig(config);\n      this._timeout = null;\n      this._hasMouseInteraction = false;\n      this._hasKeyboardInteraction = false;\n\n      this._setListeners();\n    } // Getters\n\n\n    static get DefaultType() {\n      return DefaultType;\n    }\n\n    static get Default() {\n      return Default;\n    }\n\n    static get NAME() {\n      return NAME;\n    } // Public\n\n\n    show() {\n      const showEvent = EventHandler.trigger(this._element, EVENT_SHOW);\n\n      if (showEvent.defaultPrevented) {\n        return;\n      }\n\n      this._clearTimeout();\n\n      if (this._config.animation) {\n        this._element.classList.add(CLASS_NAME_FADE);\n      }\n\n      const complete = () => {\n        this._element.classList.remove(CLASS_NAME_SHOWING);\n\n        EventHandler.trigger(this._element, EVENT_SHOWN);\n\n        this._maybeScheduleHide();\n      };\n\n      this._element.classList.remove(CLASS_NAME_HIDE); // @deprecated\n\n\n      reflow(this._element);\n\n      this._element.classList.add(CLASS_NAME_SHOW);\n\n      this._element.classList.add(CLASS_NAME_SHOWING);\n\n      this._queueCallback(complete, this._element, this._config.animation);\n    }\n\n    hide() {\n      if (!this._element.classList.contains(CLASS_NAME_SHOW)) {\n        return;\n      }\n\n      const hideEvent = EventHandler.trigger(this._element, EVENT_HIDE);\n\n      if (hideEvent.defaultPrevented) {\n        return;\n      }\n\n      const complete = () => {\n        this._element.classList.add(CLASS_NAME_HIDE); // @deprecated\n\n\n        this._element.classList.remove(CLASS_NAME_SHOWING);\n\n        this._element.classList.remove(CLASS_NAME_SHOW);\n\n        EventHandler.trigger(this._element, EVENT_HIDDEN);\n      };\n\n      this._element.classList.add(CLASS_NAME_SHOWING);\n\n      this._queueCallback(complete, this._element, this._config.animation);\n    }\n\n    dispose() {\n      this._clearTimeout();\n\n      if (this._element.classList.contains(CLASS_NAME_SHOW)) {\n        this._element.classList.remove(CLASS_NAME_SHOW);\n      }\n\n      super.dispose();\n    } // Private\n\n\n    _getConfig(config) {\n      config = { ...Default,\n        ...Manipulator.getDataAttributes(this._element),\n        ...(typeof config === 'object' && config ? config : {})\n      };\n      typeCheckConfig(NAME, config, this.constructor.DefaultType);\n      return config;\n    }\n\n    _maybeScheduleHide() {\n      if (!this._config.autohide) {\n        return;\n      }\n\n      if (this._hasMouseInteraction || this._hasKeyboardInteraction) {\n        return;\n      }\n\n      this._timeout = setTimeout(() => {\n        this.hide();\n      }, this._config.delay);\n    }\n\n    _onInteraction(event, isInteracting) {\n      switch (event.type) {\n        case 'mouseover':\n        case 'mouseout':\n          this._hasMouseInteraction = isInteracting;\n          break;\n\n        case 'focusin':\n        case 'focusout':\n          this._hasKeyboardInteraction = isInteracting;\n          break;\n      }\n\n      if (isInteracting) {\n        this._clearTimeout();\n\n        return;\n      }\n\n      const nextElement = event.relatedTarget;\n\n      if (this._element === nextElement || this._element.contains(nextElement)) {\n        return;\n      }\n\n      this._maybeScheduleHide();\n    }\n\n    _setListeners() {\n      EventHandler.on(this._element, EVENT_MOUSEOVER, event => this._onInteraction(event, true));\n      EventHandler.on(this._element, EVENT_MOUSEOUT, event => this._onInteraction(event, false));\n      EventHandler.on(this._element, EVENT_FOCUSIN, event => this._onInteraction(event, true));\n      EventHandler.on(this._element, EVENT_FOCUSOUT, event => this._onInteraction(event, false));\n    }\n\n    _clearTimeout() {\n      clearTimeout(this._timeout);\n      this._timeout = null;\n    } // Static\n\n\n    static jQueryInterface(config) {\n      return this.each(function () {\n        const data = Toast.getOrCreateInstance(this, config);\n\n        if (typeof config === 'string') {\n          if (typeof data[config] === 'undefined') {\n            throw new TypeError(`No method named \"${config}\"`);\n          }\n\n          data[config](this);\n        }\n      });\n    }\n\n  }\n\n  enableDismissTrigger(Toast);\n  /**\n   * ------------------------------------------------------------------------\n   * jQuery\n   * ------------------------------------------------------------------------\n   * add .Toast to jQuery only if jQuery is present\n   */\n\n  defineJQueryPlugin(Toast);\n\n  /**\n   * --------------------------------------------------------------------------\n   * Bootstrap (v5.1.0): index.umd.js\n   * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n   * --------------------------------------------------------------------------\n   */\n  var index_umd = {\n    Alert,\n    Button,\n    Carousel,\n    Collapse,\n    Dropdown,\n    Modal,\n    Offcanvas,\n    Popover,\n    ScrollSpy,\n    Tab,\n    Toast,\n    Tooltip\n  };\n\n  return index_umd;\n\n})));\n//# sourceMappingURL=bootstrap.js.map\n"
  },
  {
    "path": "sample/src/NimblePros.SampleToDo.Web/wwwroot/lib/jquery/LICENSE.txt",
    "content": "Copyright JS Foundation and other contributors, https://js.foundation/\n\nThis software consists of voluntary contributions made by many\nindividuals. For exact contribution history, see the revision history\navailable at https://github.com/jquery/jquery\n\nThe following license applies to all parts of this software except as\ndocumented below:\n\n====\n\nPermission is hereby granted, free of charge, to any person obtaining\na copy of this software and associated documentation files (the\n\"Software\"), to deal in the Software without restriction, including\nwithout limitation the rights to use, copy, modify, merge, publish,\ndistribute, sublicense, and/or sell copies of the Software, and to\npermit persons to whom the Software is furnished to do so, subject to\nthe following conditions:\n\nThe above copyright notice and this permission notice shall be\nincluded in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\nNONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE\nLIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\nOF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION\nWITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n\n====\n\nAll files located in the node_modules and external directories are\nexternally maintained libraries used by this software which have their\nown licenses; we recommend you read them, as their terms may differ from\nthe terms above.\n"
  },
  {
    "path": "sample/src/NimblePros.SampleToDo.Web/wwwroot/lib/jquery/dist/jquery.js",
    "content": "/*!\n * jQuery JavaScript Library v3.5.1\n * https://jquery.com/\n *\n * Includes Sizzle.js\n * https://sizzlejs.com/\n *\n * Copyright JS Foundation and other contributors\n * Released under the MIT license\n * https://jquery.org/license\n *\n * Date: 2020-05-04T22:49Z\n */\n( function( global, factory ) {\n\n\t\"use strict\";\n\n\tif ( typeof module === \"object\" && typeof module.exports === \"object\" ) {\n\n\t\t// For CommonJS and CommonJS-like environments where a proper `window`\n\t\t// is present, execute the factory and get jQuery.\n\t\t// For environments that do not have a `window` with a `document`\n\t\t// (such as Node.js), expose a factory as module.exports.\n\t\t// This accentuates the need for the creation of a real `window`.\n\t\t// e.g. var jQuery = require(\"jquery\")(window);\n\t\t// See ticket #14549 for more info.\n\t\tmodule.exports = global.document ?\n\t\t\tfactory( global, true ) :\n\t\t\tfunction( w ) {\n\t\t\t\tif ( !w.document ) {\n\t\t\t\t\tthrow new Error( \"jQuery requires a window with a document\" );\n\t\t\t\t}\n\t\t\t\treturn factory( w );\n\t\t\t};\n\t} else {\n\t\tfactory( global );\n\t}\n\n// Pass this if window is not defined yet\n} )( typeof window !== \"undefined\" ? window : this, function( window, noGlobal ) {\n\n// Edge <= 12 - 13+, Firefox <=18 - 45+, IE 10 - 11, Safari 5.1 - 9+, iOS 6 - 9.1\n// throw exceptions when non-strict code (e.g., ASP.NET 4.5) accesses strict mode\n// arguments.callee.caller (trac-13335). But as of jQuery 3.0 (2016), strict mode should be common\n// enough that all such attempts are guarded in a try block.\n\"use strict\";\n\nvar arr = [];\n\nvar getProto = Object.getPrototypeOf;\n\nvar slice = arr.slice;\n\nvar flat = arr.flat ? function( array ) {\n\treturn arr.flat.call( array );\n} : function( array ) {\n\treturn arr.concat.apply( [], array );\n};\n\n\nvar push = arr.push;\n\nvar indexOf = arr.indexOf;\n\nvar class2type = {};\n\nvar toString = class2type.toString;\n\nvar hasOwn = class2type.hasOwnProperty;\n\nvar fnToString = hasOwn.toString;\n\nvar ObjectFunctionString = fnToString.call( Object );\n\nvar support = {};\n\nvar isFunction = function isFunction( obj ) {\n\n      // Support: Chrome <=57, Firefox <=52\n      // In some browsers, typeof returns \"function\" for HTML <object> elements\n      // (i.e., `typeof document.createElement( \"object\" ) === \"function\"`).\n      // We don't want to classify *any* DOM node as a function.\n      return typeof obj === \"function\" && typeof obj.nodeType !== \"number\";\n  };\n\n\nvar isWindow = function isWindow( obj ) {\n\t\treturn obj != null && obj === obj.window;\n\t};\n\n\nvar document = window.document;\n\n\n\n\tvar preservedScriptAttributes = {\n\t\ttype: true,\n\t\tsrc: true,\n\t\tnonce: true,\n\t\tnoModule: true\n\t};\n\n\tfunction DOMEval( code, node, doc ) {\n\t\tdoc = doc || document;\n\n\t\tvar i, val,\n\t\t\tscript = doc.createElement( \"script\" );\n\n\t\tscript.text = code;\n\t\tif ( node ) {\n\t\t\tfor ( i in preservedScriptAttributes ) {\n\n\t\t\t\t// Support: Firefox 64+, Edge 18+\n\t\t\t\t// Some browsers don't support the \"nonce\" property on scripts.\n\t\t\t\t// On the other hand, just using `getAttribute` is not enough as\n\t\t\t\t// the `nonce` attribute is reset to an empty string whenever it\n\t\t\t\t// becomes browsing-context connected.\n\t\t\t\t// See https://github.com/whatwg/html/issues/2369\n\t\t\t\t// See https://html.spec.whatwg.org/#nonce-attributes\n\t\t\t\t// The `node.getAttribute` check was added for the sake of\n\t\t\t\t// `jQuery.globalEval` so that it can fake a nonce-containing node\n\t\t\t\t// via an object.\n\t\t\t\tval = node[ i ] || node.getAttribute && node.getAttribute( i );\n\t\t\t\tif ( val ) {\n\t\t\t\t\tscript.setAttribute( i, val );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tdoc.head.appendChild( script ).parentNode.removeChild( script );\n\t}\n\n\nfunction toType( obj ) {\n\tif ( obj == null ) {\n\t\treturn obj + \"\";\n\t}\n\n\t// Support: Android <=2.3 only (functionish RegExp)\n\treturn typeof obj === \"object\" || typeof obj === \"function\" ?\n\t\tclass2type[ toString.call( obj ) ] || \"object\" :\n\t\ttypeof obj;\n}\n/* global Symbol */\n// Defining this global in .eslintrc.json would create a danger of using the global\n// unguarded in another place, it seems safer to define global only for this module\n\n\n\nvar\n\tversion = \"3.5.1\",\n\n\t// Define a local copy of jQuery\n\tjQuery = function( selector, context ) {\n\n\t\t// The jQuery object is actually just the init constructor 'enhanced'\n\t\t// Need init if jQuery is called (just allow error to be thrown if not included)\n\t\treturn new jQuery.fn.init( selector, context );\n\t};\n\njQuery.fn = jQuery.prototype = {\n\n\t// The current version of jQuery being used\n\tjquery: version,\n\n\tconstructor: jQuery,\n\n\t// The default length of a jQuery object is 0\n\tlength: 0,\n\n\ttoArray: function() {\n\t\treturn slice.call( this );\n\t},\n\n\t// Get the Nth element in the matched element set OR\n\t// Get the whole matched element set as a clean array\n\tget: function( num ) {\n\n\t\t// Return all the elements in a clean array\n\t\tif ( num == null ) {\n\t\t\treturn slice.call( this );\n\t\t}\n\n\t\t// Return just the one element from the set\n\t\treturn num < 0 ? this[ num + this.length ] : this[ num ];\n\t},\n\n\t// Take an array of elements and push it onto the stack\n\t// (returning the new matched element set)\n\tpushStack: function( elems ) {\n\n\t\t// Build a new jQuery matched element set\n\t\tvar ret = jQuery.merge( this.constructor(), elems );\n\n\t\t// Add the old object onto the stack (as a reference)\n\t\tret.prevObject = this;\n\n\t\t// Return the newly-formed element set\n\t\treturn ret;\n\t},\n\n\t// Execute a callback for every element in the matched set.\n\teach: function( callback ) {\n\t\treturn jQuery.each( this, callback );\n\t},\n\n\tmap: function( callback ) {\n\t\treturn this.pushStack( jQuery.map( this, function( elem, i ) {\n\t\t\treturn callback.call( elem, i, elem );\n\t\t} ) );\n\t},\n\n\tslice: function() {\n\t\treturn this.pushStack( slice.apply( this, arguments ) );\n\t},\n\n\tfirst: function() {\n\t\treturn this.eq( 0 );\n\t},\n\n\tlast: function() {\n\t\treturn this.eq( -1 );\n\t},\n\n\teven: function() {\n\t\treturn this.pushStack( jQuery.grep( this, function( _elem, i ) {\n\t\t\treturn ( i + 1 ) % 2;\n\t\t} ) );\n\t},\n\n\todd: function() {\n\t\treturn this.pushStack( jQuery.grep( this, function( _elem, i ) {\n\t\t\treturn i % 2;\n\t\t} ) );\n\t},\n\n\teq: function( i ) {\n\t\tvar len = this.length,\n\t\t\tj = +i + ( i < 0 ? len : 0 );\n\t\treturn this.pushStack( j >= 0 && j < len ? [ this[ j ] ] : [] );\n\t},\n\n\tend: function() {\n\t\treturn this.prevObject || this.constructor();\n\t},\n\n\t// For internal use only.\n\t// Behaves like an Array's method, not like a jQuery method.\n\tpush: push,\n\tsort: arr.sort,\n\tsplice: arr.splice\n};\n\njQuery.extend = jQuery.fn.extend = function() {\n\tvar options, name, src, copy, copyIsArray, clone,\n\t\ttarget = arguments[ 0 ] || {},\n\t\ti = 1,\n\t\tlength = arguments.length,\n\t\tdeep = false;\n\n\t// Handle a deep copy situation\n\tif ( typeof target === \"boolean\" ) {\n\t\tdeep = target;\n\n\t\t// Skip the boolean and the target\n\t\ttarget = arguments[ i ] || {};\n\t\ti++;\n\t}\n\n\t// Handle case when target is a string or something (possible in deep copy)\n\tif ( typeof target !== \"object\" && !isFunction( target ) ) {\n\t\ttarget = {};\n\t}\n\n\t// Extend jQuery itself if only one argument is passed\n\tif ( i === length ) {\n\t\ttarget = this;\n\t\ti--;\n\t}\n\n\tfor ( ; i < length; i++ ) {\n\n\t\t// Only deal with non-null/undefined values\n\t\tif ( ( options = arguments[ i ] ) != null ) {\n\n\t\t\t// Extend the base object\n\t\t\tfor ( name in options ) {\n\t\t\t\tcopy = options[ name ];\n\n\t\t\t\t// Prevent Object.prototype pollution\n\t\t\t\t// Prevent never-ending loop\n\t\t\t\tif ( name === \"__proto__\" || target === copy ) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\t// Recurse if we're merging plain objects or arrays\n\t\t\t\tif ( deep && copy && ( jQuery.isPlainObject( copy ) ||\n\t\t\t\t\t( copyIsArray = Array.isArray( copy ) ) ) ) {\n\t\t\t\t\tsrc = target[ name ];\n\n\t\t\t\t\t// Ensure proper type for the source value\n\t\t\t\t\tif ( copyIsArray && !Array.isArray( src ) ) {\n\t\t\t\t\t\tclone = [];\n\t\t\t\t\t} else if ( !copyIsArray && !jQuery.isPlainObject( src ) ) {\n\t\t\t\t\t\tclone = {};\n\t\t\t\t\t} else {\n\t\t\t\t\t\tclone = src;\n\t\t\t\t\t}\n\t\t\t\t\tcopyIsArray = false;\n\n\t\t\t\t\t// Never move original objects, clone them\n\t\t\t\t\ttarget[ name ] = jQuery.extend( deep, clone, copy );\n\n\t\t\t\t// Don't bring in undefined values\n\t\t\t\t} else if ( copy !== undefined ) {\n\t\t\t\t\ttarget[ name ] = copy;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// Return the modified object\n\treturn target;\n};\n\njQuery.extend( {\n\n\t// Unique for each copy of jQuery on the page\n\texpando: \"jQuery\" + ( version + Math.random() ).replace( /\\D/g, \"\" ),\n\n\t// Assume jQuery is ready without the ready module\n\tisReady: true,\n\n\terror: function( msg ) {\n\t\tthrow new Error( msg );\n\t},\n\n\tnoop: function() {},\n\n\tisPlainObject: function( obj ) {\n\t\tvar proto, Ctor;\n\n\t\t// Detect obvious negatives\n\t\t// Use toString instead of jQuery.type to catch host objects\n\t\tif ( !obj || toString.call( obj ) !== \"[object Object]\" ) {\n\t\t\treturn false;\n\t\t}\n\n\t\tproto = getProto( obj );\n\n\t\t// Objects with no prototype (e.g., `Object.create( null )`) are plain\n\t\tif ( !proto ) {\n\t\t\treturn true;\n\t\t}\n\n\t\t// Objects with prototype are plain iff they were constructed by a global Object function\n\t\tCtor = hasOwn.call( proto, \"constructor\" ) && proto.constructor;\n\t\treturn typeof Ctor === \"function\" && fnToString.call( Ctor ) === ObjectFunctionString;\n\t},\n\n\tisEmptyObject: function( obj ) {\n\t\tvar name;\n\n\t\tfor ( name in obj ) {\n\t\t\treturn false;\n\t\t}\n\t\treturn true;\n\t},\n\n\t// Evaluates a script in a provided context; falls back to the global one\n\t// if not specified.\n\tglobalEval: function( code, options, doc ) {\n\t\tDOMEval( code, { nonce: options && options.nonce }, doc );\n\t},\n\n\teach: function( obj, callback ) {\n\t\tvar length, i = 0;\n\n\t\tif ( isArrayLike( obj ) ) {\n\t\t\tlength = obj.length;\n\t\t\tfor ( ; i < length; i++ ) {\n\t\t\t\tif ( callback.call( obj[ i ], i, obj[ i ] ) === false ) {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tfor ( i in obj ) {\n\t\t\t\tif ( callback.call( obj[ i ], i, obj[ i ] ) === false ) {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn obj;\n\t},\n\n\t// results is for internal usage only\n\tmakeArray: function( arr, results ) {\n\t\tvar ret = results || [];\n\n\t\tif ( arr != null ) {\n\t\t\tif ( isArrayLike( Object( arr ) ) ) {\n\t\t\t\tjQuery.merge( ret,\n\t\t\t\t\ttypeof arr === \"string\" ?\n\t\t\t\t\t[ arr ] : arr\n\t\t\t\t);\n\t\t\t} else {\n\t\t\t\tpush.call( ret, arr );\n\t\t\t}\n\t\t}\n\n\t\treturn ret;\n\t},\n\n\tinArray: function( elem, arr, i ) {\n\t\treturn arr == null ? -1 : indexOf.call( arr, elem, i );\n\t},\n\n\t// Support: Android <=4.0 only, PhantomJS 1 only\n\t// push.apply(_, arraylike) throws on ancient WebKit\n\tmerge: function( first, second ) {\n\t\tvar len = +second.length,\n\t\t\tj = 0,\n\t\t\ti = first.length;\n\n\t\tfor ( ; j < len; j++ ) {\n\t\t\tfirst[ i++ ] = second[ j ];\n\t\t}\n\n\t\tfirst.length = i;\n\n\t\treturn first;\n\t},\n\n\tgrep: function( elems, callback, invert ) {\n\t\tvar callbackInverse,\n\t\t\tmatches = [],\n\t\t\ti = 0,\n\t\t\tlength = elems.length,\n\t\t\tcallbackExpect = !invert;\n\n\t\t// Go through the array, only saving the items\n\t\t// that pass the validator function\n\t\tfor ( ; i < length; i++ ) {\n\t\t\tcallbackInverse = !callback( elems[ i ], i );\n\t\t\tif ( callbackInverse !== callbackExpect ) {\n\t\t\t\tmatches.push( elems[ i ] );\n\t\t\t}\n\t\t}\n\n\t\treturn matches;\n\t},\n\n\t// arg is for internal usage only\n\tmap: function( elems, callback, arg ) {\n\t\tvar length, value,\n\t\t\ti = 0,\n\t\t\tret = [];\n\n\t\t// Go through the array, translating each of the items to their new values\n\t\tif ( isArrayLike( elems ) ) {\n\t\t\tlength = elems.length;\n\t\t\tfor ( ; i < length; i++ ) {\n\t\t\t\tvalue = callback( elems[ i ], i, arg );\n\n\t\t\t\tif ( value != null ) {\n\t\t\t\t\tret.push( value );\n\t\t\t\t}\n\t\t\t}\n\n\t\t// Go through every key on the object,\n\t\t} else {\n\t\t\tfor ( i in elems ) {\n\t\t\t\tvalue = callback( elems[ i ], i, arg );\n\n\t\t\t\tif ( value != null ) {\n\t\t\t\t\tret.push( value );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Flatten any nested arrays\n\t\treturn flat( ret );\n\t},\n\n\t// A global GUID counter for objects\n\tguid: 1,\n\n\t// jQuery.support is not used in Core but other projects attach their\n\t// properties to it so it needs to exist.\n\tsupport: support\n} );\n\nif ( typeof Symbol === \"function\" ) {\n\tjQuery.fn[ Symbol.iterator ] = arr[ Symbol.iterator ];\n}\n\n// Populate the class2type map\njQuery.each( \"Boolean Number String Function Array Date RegExp Object Error Symbol\".split( \" \" ),\nfunction( _i, name ) {\n\tclass2type[ \"[object \" + name + \"]\" ] = name.toLowerCase();\n} );\n\nfunction isArrayLike( obj ) {\n\n\t// Support: real iOS 8.2 only (not reproducible in simulator)\n\t// `in` check used to prevent JIT error (gh-2145)\n\t// hasOwn isn't used here due to false negatives\n\t// regarding Nodelist length in IE\n\tvar length = !!obj && \"length\" in obj && obj.length,\n\t\ttype = toType( obj );\n\n\tif ( isFunction( obj ) || isWindow( obj ) ) {\n\t\treturn false;\n\t}\n\n\treturn type === \"array\" || length === 0 ||\n\t\ttypeof length === \"number\" && length > 0 && ( length - 1 ) in obj;\n}\nvar Sizzle =\n/*!\n * Sizzle CSS Selector Engine v2.3.5\n * https://sizzlejs.com/\n *\n * Copyright JS Foundation and other contributors\n * Released under the MIT license\n * https://js.foundation/\n *\n * Date: 2020-03-14\n */\n( function( window ) {\nvar i,\n\tsupport,\n\tExpr,\n\tgetText,\n\tisXML,\n\ttokenize,\n\tcompile,\n\tselect,\n\toutermostContext,\n\tsortInput,\n\thasDuplicate,\n\n\t// Local document vars\n\tsetDocument,\n\tdocument,\n\tdocElem,\n\tdocumentIsHTML,\n\trbuggyQSA,\n\trbuggyMatches,\n\tmatches,\n\tcontains,\n\n\t// Instance-specific data\n\texpando = \"sizzle\" + 1 * new Date(),\n\tpreferredDoc = window.document,\n\tdirruns = 0,\n\tdone = 0,\n\tclassCache = createCache(),\n\ttokenCache = createCache(),\n\tcompilerCache = createCache(),\n\tnonnativeSelectorCache = createCache(),\n\tsortOrder = function( a, b ) {\n\t\tif ( a === b ) {\n\t\t\thasDuplicate = true;\n\t\t}\n\t\treturn 0;\n\t},\n\n\t// Instance methods\n\thasOwn = ( {} ).hasOwnProperty,\n\tarr = [],\n\tpop = arr.pop,\n\tpushNative = arr.push,\n\tpush = arr.push,\n\tslice = arr.slice,\n\n\t// Use a stripped-down indexOf as it's faster than native\n\t// https://jsperf.com/thor-indexof-vs-for/5\n\tindexOf = function( list, elem ) {\n\t\tvar i = 0,\n\t\t\tlen = list.length;\n\t\tfor ( ; i < len; i++ ) {\n\t\t\tif ( list[ i ] === elem ) {\n\t\t\t\treturn i;\n\t\t\t}\n\t\t}\n\t\treturn -1;\n\t},\n\n\tbooleans = \"checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|\" +\n\t\t\"ismap|loop|multiple|open|readonly|required|scoped\",\n\n\t// Regular expressions\n\n\t// http://www.w3.org/TR/css3-selectors/#whitespace\n\twhitespace = \"[\\\\x20\\\\t\\\\r\\\\n\\\\f]\",\n\n\t// https://www.w3.org/TR/css-syntax-3/#ident-token-diagram\n\tidentifier = \"(?:\\\\\\\\[\\\\da-fA-F]{1,6}\" + whitespace +\n\t\t\"?|\\\\\\\\[^\\\\r\\\\n\\\\f]|[\\\\w-]|[^\\0-\\\\x7f])+\",\n\n\t// Attribute selectors: http://www.w3.org/TR/selectors/#attribute-selectors\n\tattributes = \"\\\\[\" + whitespace + \"*(\" + identifier + \")(?:\" + whitespace +\n\n\t\t// Operator (capture 2)\n\t\t\"*([*^$|!~]?=)\" + whitespace +\n\n\t\t// \"Attribute values must be CSS identifiers [capture 5]\n\t\t// or strings [capture 3 or capture 4]\"\n\t\t\"*(?:'((?:\\\\\\\\.|[^\\\\\\\\'])*)'|\\\"((?:\\\\\\\\.|[^\\\\\\\\\\\"])*)\\\"|(\" + identifier + \"))|)\" +\n\t\twhitespace + \"*\\\\]\",\n\n\tpseudos = \":(\" + identifier + \")(?:\\\\((\" +\n\n\t\t// To reduce the number of selectors needing tokenize in the preFilter, prefer arguments:\n\t\t// 1. quoted (capture 3; capture 4 or capture 5)\n\t\t\"('((?:\\\\\\\\.|[^\\\\\\\\'])*)'|\\\"((?:\\\\\\\\.|[^\\\\\\\\\\\"])*)\\\")|\" +\n\n\t\t// 2. simple (capture 6)\n\t\t\"((?:\\\\\\\\.|[^\\\\\\\\()[\\\\]]|\" + attributes + \")*)|\" +\n\n\t\t// 3. anything else (capture 2)\n\t\t\".*\" +\n\t\t\")\\\\)|)\",\n\n\t// Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter\n\trwhitespace = new RegExp( whitespace + \"+\", \"g\" ),\n\trtrim = new RegExp( \"^\" + whitespace + \"+|((?:^|[^\\\\\\\\])(?:\\\\\\\\.)*)\" +\n\t\twhitespace + \"+$\", \"g\" ),\n\n\trcomma = new RegExp( \"^\" + whitespace + \"*,\" + whitespace + \"*\" ),\n\trcombinators = new RegExp( \"^\" + whitespace + \"*([>+~]|\" + whitespace + \")\" + whitespace +\n\t\t\"*\" ),\n\trdescend = new RegExp( whitespace + \"|>\" ),\n\n\trpseudo = new RegExp( pseudos ),\n\tridentifier = new RegExp( \"^\" + identifier + \"$\" ),\n\n\tmatchExpr = {\n\t\t\"ID\": new RegExp( \"^#(\" + identifier + \")\" ),\n\t\t\"CLASS\": new RegExp( \"^\\\\.(\" + identifier + \")\" ),\n\t\t\"TAG\": new RegExp( \"^(\" + identifier + \"|[*])\" ),\n\t\t\"ATTR\": new RegExp( \"^\" + attributes ),\n\t\t\"PSEUDO\": new RegExp( \"^\" + pseudos ),\n\t\t\"CHILD\": new RegExp( \"^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\\\(\" +\n\t\t\twhitespace + \"*(even|odd|(([+-]|)(\\\\d*)n|)\" + whitespace + \"*(?:([+-]|)\" +\n\t\t\twhitespace + \"*(\\\\d+)|))\" + whitespace + \"*\\\\)|)\", \"i\" ),\n\t\t\"bool\": new RegExp( \"^(?:\" + booleans + \")$\", \"i\" ),\n\n\t\t// For use in libraries implementing .is()\n\t\t// We use this for POS matching in `select`\n\t\t\"needsContext\": new RegExp( \"^\" + whitespace +\n\t\t\t\"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\\\(\" + whitespace +\n\t\t\t\"*((?:-\\\\d)?\\\\d*)\" + whitespace + \"*\\\\)|)(?=[^-]|$)\", \"i\" )\n\t},\n\n\trhtml = /HTML$/i,\n\trinputs = /^(?:input|select|textarea|button)$/i,\n\trheader = /^h\\d$/i,\n\n\trnative = /^[^{]+\\{\\s*\\[native \\w/,\n\n\t// Easily-parseable/retrievable ID or TAG or CLASS selectors\n\trquickExpr = /^(?:#([\\w-]+)|(\\w+)|\\.([\\w-]+))$/,\n\n\trsibling = /[+~]/,\n\n\t// CSS escapes\n\t// http://www.w3.org/TR/CSS21/syndata.html#escaped-characters\n\trunescape = new RegExp( \"\\\\\\\\[\\\\da-fA-F]{1,6}\" + whitespace + \"?|\\\\\\\\([^\\\\r\\\\n\\\\f])\", \"g\" ),\n\tfunescape = function( escape, nonHex ) {\n\t\tvar high = \"0x\" + escape.slice( 1 ) - 0x10000;\n\n\t\treturn nonHex ?\n\n\t\t\t// Strip the backslash prefix from a non-hex escape sequence\n\t\t\tnonHex :\n\n\t\t\t// Replace a hexadecimal escape sequence with the encoded Unicode code point\n\t\t\t// Support: IE <=11+\n\t\t\t// For values outside the Basic Multilingual Plane (BMP), manually construct a\n\t\t\t// surrogate pair\n\t\t\thigh < 0 ?\n\t\t\t\tString.fromCharCode( high + 0x10000 ) :\n\t\t\t\tString.fromCharCode( high >> 10 | 0xD800, high & 0x3FF | 0xDC00 );\n\t},\n\n\t// CSS string/identifier serialization\n\t// https://drafts.csswg.org/cssom/#common-serializing-idioms\n\trcssescape = /([\\0-\\x1f\\x7f]|^-?\\d)|^-$|[^\\0-\\x1f\\x7f-\\uFFFF\\w-]/g,\n\tfcssescape = function( ch, asCodePoint ) {\n\t\tif ( asCodePoint ) {\n\n\t\t\t// U+0000 NULL becomes U+FFFD REPLACEMENT CHARACTER\n\t\t\tif ( ch === \"\\0\" ) {\n\t\t\t\treturn \"\\uFFFD\";\n\t\t\t}\n\n\t\t\t// Control characters and (dependent upon position) numbers get escaped as code points\n\t\t\treturn ch.slice( 0, -1 ) + \"\\\\\" +\n\t\t\t\tch.charCodeAt( ch.length - 1 ).toString( 16 ) + \" \";\n\t\t}\n\n\t\t// Other potentially-special ASCII characters get backslash-escaped\n\t\treturn \"\\\\\" + ch;\n\t},\n\n\t// Used for iframes\n\t// See setDocument()\n\t// Removing the function wrapper causes a \"Permission Denied\"\n\t// error in IE\n\tunloadHandler = function() {\n\t\tsetDocument();\n\t},\n\n\tinDisabledFieldset = addCombinator(\n\t\tfunction( elem ) {\n\t\t\treturn elem.disabled === true && elem.nodeName.toLowerCase() === \"fieldset\";\n\t\t},\n\t\t{ dir: \"parentNode\", next: \"legend\" }\n\t);\n\n// Optimize for push.apply( _, NodeList )\ntry {\n\tpush.apply(\n\t\t( arr = slice.call( preferredDoc.childNodes ) ),\n\t\tpreferredDoc.childNodes\n\t);\n\n\t// Support: Android<4.0\n\t// Detect silently failing push.apply\n\t// eslint-disable-next-line no-unused-expressions\n\tarr[ preferredDoc.childNodes.length ].nodeType;\n} catch ( e ) {\n\tpush = { apply: arr.length ?\n\n\t\t// Leverage slice if possible\n\t\tfunction( target, els ) {\n\t\t\tpushNative.apply( target, slice.call( els ) );\n\t\t} :\n\n\t\t// Support: IE<9\n\t\t// Otherwise append directly\n\t\tfunction( target, els ) {\n\t\t\tvar j = target.length,\n\t\t\t\ti = 0;\n\n\t\t\t// Can't trust NodeList.length\n\t\t\twhile ( ( target[ j++ ] = els[ i++ ] ) ) {}\n\t\t\ttarget.length = j - 1;\n\t\t}\n\t};\n}\n\nfunction Sizzle( selector, context, results, seed ) {\n\tvar m, i, elem, nid, match, groups, newSelector,\n\t\tnewContext = context && context.ownerDocument,\n\n\t\t// nodeType defaults to 9, since context defaults to document\n\t\tnodeType = context ? context.nodeType : 9;\n\n\tresults = results || [];\n\n\t// Return early from calls with invalid selector or context\n\tif ( typeof selector !== \"string\" || !selector ||\n\t\tnodeType !== 1 && nodeType !== 9 && nodeType !== 11 ) {\n\n\t\treturn results;\n\t}\n\n\t// Try to shortcut find operations (as opposed to filters) in HTML documents\n\tif ( !seed ) {\n\t\tsetDocument( context );\n\t\tcontext = context || document;\n\n\t\tif ( documentIsHTML ) {\n\n\t\t\t// If the selector is sufficiently simple, try using a \"get*By*\" DOM method\n\t\t\t// (excepting DocumentFragment context, where the methods don't exist)\n\t\t\tif ( nodeType !== 11 && ( match = rquickExpr.exec( selector ) ) ) {\n\n\t\t\t\t// ID selector\n\t\t\t\tif ( ( m = match[ 1 ] ) ) {\n\n\t\t\t\t\t// Document context\n\t\t\t\t\tif ( nodeType === 9 ) {\n\t\t\t\t\t\tif ( ( elem = context.getElementById( m ) ) ) {\n\n\t\t\t\t\t\t\t// Support: IE, Opera, Webkit\n\t\t\t\t\t\t\t// TODO: identify versions\n\t\t\t\t\t\t\t// getElementById can match elements by name instead of ID\n\t\t\t\t\t\t\tif ( elem.id === m ) {\n\t\t\t\t\t\t\t\tresults.push( elem );\n\t\t\t\t\t\t\t\treturn results;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\treturn results;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t// Element context\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\t// Support: IE, Opera, Webkit\n\t\t\t\t\t\t// TODO: identify versions\n\t\t\t\t\t\t// getElementById can match elements by name instead of ID\n\t\t\t\t\t\tif ( newContext && ( elem = newContext.getElementById( m ) ) &&\n\t\t\t\t\t\t\tcontains( context, elem ) &&\n\t\t\t\t\t\t\telem.id === m ) {\n\n\t\t\t\t\t\t\tresults.push( elem );\n\t\t\t\t\t\t\treturn results;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t// Type selector\n\t\t\t\t} else if ( match[ 2 ] ) {\n\t\t\t\t\tpush.apply( results, context.getElementsByTagName( selector ) );\n\t\t\t\t\treturn results;\n\n\t\t\t\t// Class selector\n\t\t\t\t} else if ( ( m = match[ 3 ] ) && support.getElementsByClassName &&\n\t\t\t\t\tcontext.getElementsByClassName ) {\n\n\t\t\t\t\tpush.apply( results, context.getElementsByClassName( m ) );\n\t\t\t\t\treturn results;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Take advantage of querySelectorAll\n\t\t\tif ( support.qsa &&\n\t\t\t\t!nonnativeSelectorCache[ selector + \" \" ] &&\n\t\t\t\t( !rbuggyQSA || !rbuggyQSA.test( selector ) ) &&\n\n\t\t\t\t// Support: IE 8 only\n\t\t\t\t// Exclude object elements\n\t\t\t\t( nodeType !== 1 || context.nodeName.toLowerCase() !== \"object\" ) ) {\n\n\t\t\t\tnewSelector = selector;\n\t\t\t\tnewContext = context;\n\n\t\t\t\t// qSA considers elements outside a scoping root when evaluating child or\n\t\t\t\t// descendant combinators, which is not what we want.\n\t\t\t\t// In such cases, we work around the behavior by prefixing every selector in the\n\t\t\t\t// list with an ID selector referencing the scope context.\n\t\t\t\t// The technique has to be used as well when a leading combinator is used\n\t\t\t\t// as such selectors are not recognized by querySelectorAll.\n\t\t\t\t// Thanks to Andrew Dupont for this technique.\n\t\t\t\tif ( nodeType === 1 &&\n\t\t\t\t\t( rdescend.test( selector ) || rcombinators.test( selector ) ) ) {\n\n\t\t\t\t\t// Expand context for sibling selectors\n\t\t\t\t\tnewContext = rsibling.test( selector ) && testContext( context.parentNode ) ||\n\t\t\t\t\t\tcontext;\n\n\t\t\t\t\t// We can use :scope instead of the ID hack if the browser\n\t\t\t\t\t// supports it & if we're not changing the context.\n\t\t\t\t\tif ( newContext !== context || !support.scope ) {\n\n\t\t\t\t\t\t// Capture the context ID, setting it first if necessary\n\t\t\t\t\t\tif ( ( nid = context.getAttribute( \"id\" ) ) ) {\n\t\t\t\t\t\t\tnid = nid.replace( rcssescape, fcssescape );\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tcontext.setAttribute( \"id\", ( nid = expando ) );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t// Prefix every selector in the list\n\t\t\t\t\tgroups = tokenize( selector );\n\t\t\t\t\ti = groups.length;\n\t\t\t\t\twhile ( i-- ) {\n\t\t\t\t\t\tgroups[ i ] = ( nid ? \"#\" + nid : \":scope\" ) + \" \" +\n\t\t\t\t\t\t\ttoSelector( groups[ i ] );\n\t\t\t\t\t}\n\t\t\t\t\tnewSelector = groups.join( \",\" );\n\t\t\t\t}\n\n\t\t\t\ttry {\n\t\t\t\t\tpush.apply( results,\n\t\t\t\t\t\tnewContext.querySelectorAll( newSelector )\n\t\t\t\t\t);\n\t\t\t\t\treturn results;\n\t\t\t\t} catch ( qsaError ) {\n\t\t\t\t\tnonnativeSelectorCache( selector, true );\n\t\t\t\t} finally {\n\t\t\t\t\tif ( nid === expando ) {\n\t\t\t\t\t\tcontext.removeAttribute( \"id\" );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// All others\n\treturn select( selector.replace( rtrim, \"$1\" ), context, results, seed );\n}\n\n/**\n * Create key-value caches of limited size\n * @returns {function(string, object)} Returns the Object data after storing it on itself with\n *\tproperty name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength)\n *\tdeleting the oldest entry\n */\nfunction createCache() {\n\tvar keys = [];\n\n\tfunction cache( key, value ) {\n\n\t\t// Use (key + \" \") to avoid collision with native prototype properties (see Issue #157)\n\t\tif ( keys.push( key + \" \" ) > Expr.cacheLength ) {\n\n\t\t\t// Only keep the most recent entries\n\t\t\tdelete cache[ keys.shift() ];\n\t\t}\n\t\treturn ( cache[ key + \" \" ] = value );\n\t}\n\treturn cache;\n}\n\n/**\n * Mark a function for special use by Sizzle\n * @param {Function} fn The function to mark\n */\nfunction markFunction( fn ) {\n\tfn[ expando ] = true;\n\treturn fn;\n}\n\n/**\n * Support testing using an element\n * @param {Function} fn Passed the created element and returns a boolean result\n */\nfunction assert( fn ) {\n\tvar el = document.createElement( \"fieldset\" );\n\n\ttry {\n\t\treturn !!fn( el );\n\t} catch ( e ) {\n\t\treturn false;\n\t} finally {\n\n\t\t// Remove from its parent by default\n\t\tif ( el.parentNode ) {\n\t\t\tel.parentNode.removeChild( el );\n\t\t}\n\n\t\t// release memory in IE\n\t\tel = null;\n\t}\n}\n\n/**\n * Adds the same handler for all of the specified attrs\n * @param {String} attrs Pipe-separated list of attributes\n * @param {Function} handler The method that will be applied\n */\nfunction addHandle( attrs, handler ) {\n\tvar arr = attrs.split( \"|\" ),\n\t\ti = arr.length;\n\n\twhile ( i-- ) {\n\t\tExpr.attrHandle[ arr[ i ] ] = handler;\n\t}\n}\n\n/**\n * Checks document order of two siblings\n * @param {Element} a\n * @param {Element} b\n * @returns {Number} Returns less than 0 if a precedes b, greater than 0 if a follows b\n */\nfunction siblingCheck( a, b ) {\n\tvar cur = b && a,\n\t\tdiff = cur && a.nodeType === 1 && b.nodeType === 1 &&\n\t\t\ta.sourceIndex - b.sourceIndex;\n\n\t// Use IE sourceIndex if available on both nodes\n\tif ( diff ) {\n\t\treturn diff;\n\t}\n\n\t// Check if b follows a\n\tif ( cur ) {\n\t\twhile ( ( cur = cur.nextSibling ) ) {\n\t\t\tif ( cur === b ) {\n\t\t\t\treturn -1;\n\t\t\t}\n\t\t}\n\t}\n\n\treturn a ? 1 : -1;\n}\n\n/**\n * Returns a function to use in pseudos for input types\n * @param {String} type\n */\nfunction createInputPseudo( type ) {\n\treturn function( elem ) {\n\t\tvar name = elem.nodeName.toLowerCase();\n\t\treturn name === \"input\" && elem.type === type;\n\t};\n}\n\n/**\n * Returns a function to use in pseudos for buttons\n * @param {String} type\n */\nfunction createButtonPseudo( type ) {\n\treturn function( elem ) {\n\t\tvar name = elem.nodeName.toLowerCase();\n\t\treturn ( name === \"input\" || name === \"button\" ) && elem.type === type;\n\t};\n}\n\n/**\n * Returns a function to use in pseudos for :enabled/:disabled\n * @param {Boolean} disabled true for :disabled; false for :enabled\n */\nfunction createDisabledPseudo( disabled ) {\n\n\t// Known :disabled false positives: fieldset[disabled] > legend:nth-of-type(n+2) :can-disable\n\treturn function( elem ) {\n\n\t\t// Only certain elements can match :enabled or :disabled\n\t\t// https://html.spec.whatwg.org/multipage/scripting.html#selector-enabled\n\t\t// https://html.spec.whatwg.org/multipage/scripting.html#selector-disabled\n\t\tif ( \"form\" in elem ) {\n\n\t\t\t// Check for inherited disabledness on relevant non-disabled elements:\n\t\t\t// * listed form-associated elements in a disabled fieldset\n\t\t\t//   https://html.spec.whatwg.org/multipage/forms.html#category-listed\n\t\t\t//   https://html.spec.whatwg.org/multipage/forms.html#concept-fe-disabled\n\t\t\t// * option elements in a disabled optgroup\n\t\t\t//   https://html.spec.whatwg.org/multipage/forms.html#concept-option-disabled\n\t\t\t// All such elements have a \"form\" property.\n\t\t\tif ( elem.parentNode && elem.disabled === false ) {\n\n\t\t\t\t// Option elements defer to a parent optgroup if present\n\t\t\t\tif ( \"label\" in elem ) {\n\t\t\t\t\tif ( \"label\" in elem.parentNode ) {\n\t\t\t\t\t\treturn elem.parentNode.disabled === disabled;\n\t\t\t\t\t} else {\n\t\t\t\t\t\treturn elem.disabled === disabled;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Support: IE 6 - 11\n\t\t\t\t// Use the isDisabled shortcut property to check for disabled fieldset ancestors\n\t\t\t\treturn elem.isDisabled === disabled ||\n\n\t\t\t\t\t// Where there is no isDisabled, check manually\n\t\t\t\t\t/* jshint -W018 */\n\t\t\t\t\telem.isDisabled !== !disabled &&\n\t\t\t\t\tinDisabledFieldset( elem ) === disabled;\n\t\t\t}\n\n\t\t\treturn elem.disabled === disabled;\n\n\t\t// Try to winnow out elements that can't be disabled before trusting the disabled property.\n\t\t// Some victims get caught in our net (label, legend, menu, track), but it shouldn't\n\t\t// even exist on them, let alone have a boolean value.\n\t\t} else if ( \"label\" in elem ) {\n\t\t\treturn elem.disabled === disabled;\n\t\t}\n\n\t\t// Remaining elements are neither :enabled nor :disabled\n\t\treturn false;\n\t};\n}\n\n/**\n * Returns a function to use in pseudos for positionals\n * @param {Function} fn\n */\nfunction createPositionalPseudo( fn ) {\n\treturn markFunction( function( argument ) {\n\t\targument = +argument;\n\t\treturn markFunction( function( seed, matches ) {\n\t\t\tvar j,\n\t\t\t\tmatchIndexes = fn( [], seed.length, argument ),\n\t\t\t\ti = matchIndexes.length;\n\n\t\t\t// Match elements found at the specified indexes\n\t\t\twhile ( i-- ) {\n\t\t\t\tif ( seed[ ( j = matchIndexes[ i ] ) ] ) {\n\t\t\t\t\tseed[ j ] = !( matches[ j ] = seed[ j ] );\n\t\t\t\t}\n\t\t\t}\n\t\t} );\n\t} );\n}\n\n/**\n * Checks a node for validity as a Sizzle context\n * @param {Element|Object=} context\n * @returns {Element|Object|Boolean} The input node if acceptable, otherwise a falsy value\n */\nfunction testContext( context ) {\n\treturn context && typeof context.getElementsByTagName !== \"undefined\" && context;\n}\n\n// Expose support vars for convenience\nsupport = Sizzle.support = {};\n\n/**\n * Detects XML nodes\n * @param {Element|Object} elem An element or a document\n * @returns {Boolean} True iff elem is a non-HTML XML node\n */\nisXML = Sizzle.isXML = function( elem ) {\n\tvar namespace = elem.namespaceURI,\n\t\tdocElem = ( elem.ownerDocument || elem ).documentElement;\n\n\t// Support: IE <=8\n\t// Assume HTML when documentElement doesn't yet exist, such as inside loading iframes\n\t// https://bugs.jquery.com/ticket/4833\n\treturn !rhtml.test( namespace || docElem && docElem.nodeName || \"HTML\" );\n};\n\n/**\n * Sets document-related variables once based on the current document\n * @param {Element|Object} [doc] An element or document object to use to set the document\n * @returns {Object} Returns the current document\n */\nsetDocument = Sizzle.setDocument = function( node ) {\n\tvar hasCompare, subWindow,\n\t\tdoc = node ? node.ownerDocument || node : preferredDoc;\n\n\t// Return early if doc is invalid or already selected\n\t// Support: IE 11+, Edge 17 - 18+\n\t// IE/Edge sometimes throw a \"Permission denied\" error when strict-comparing\n\t// two documents; shallow comparisons work.\n\t// eslint-disable-next-line eqeqeq\n\tif ( doc == document || doc.nodeType !== 9 || !doc.documentElement ) {\n\t\treturn document;\n\t}\n\n\t// Update global variables\n\tdocument = doc;\n\tdocElem = document.documentElement;\n\tdocumentIsHTML = !isXML( document );\n\n\t// Support: IE 9 - 11+, Edge 12 - 18+\n\t// Accessing iframe documents after unload throws \"permission denied\" errors (jQuery #13936)\n\t// Support: IE 11+, Edge 17 - 18+\n\t// IE/Edge sometimes throw a \"Permission denied\" error when strict-comparing\n\t// two documents; shallow comparisons work.\n\t// eslint-disable-next-line eqeqeq\n\tif ( preferredDoc != document &&\n\t\t( subWindow = document.defaultView ) && subWindow.top !== subWindow ) {\n\n\t\t// Support: IE 11, Edge\n\t\tif ( subWindow.addEventListener ) {\n\t\t\tsubWindow.addEventListener( \"unload\", unloadHandler, false );\n\n\t\t// Support: IE 9 - 10 only\n\t\t} else if ( subWindow.attachEvent ) {\n\t\t\tsubWindow.attachEvent( \"onunload\", unloadHandler );\n\t\t}\n\t}\n\n\t// Support: IE 8 - 11+, Edge 12 - 18+, Chrome <=16 - 25 only, Firefox <=3.6 - 31 only,\n\t// Safari 4 - 5 only, Opera <=11.6 - 12.x only\n\t// IE/Edge & older browsers don't support the :scope pseudo-class.\n\t// Support: Safari 6.0 only\n\t// Safari 6.0 supports :scope but it's an alias of :root there.\n\tsupport.scope = assert( function( el ) {\n\t\tdocElem.appendChild( el ).appendChild( document.createElement( \"div\" ) );\n\t\treturn typeof el.querySelectorAll !== \"undefined\" &&\n\t\t\t!el.querySelectorAll( \":scope fieldset div\" ).length;\n\t} );\n\n\t/* Attributes\n\t---------------------------------------------------------------------- */\n\n\t// Support: IE<8\n\t// Verify that getAttribute really returns attributes and not properties\n\t// (excepting IE8 booleans)\n\tsupport.attributes = assert( function( el ) {\n\t\tel.className = \"i\";\n\t\treturn !el.getAttribute( \"className\" );\n\t} );\n\n\t/* getElement(s)By*\n\t---------------------------------------------------------------------- */\n\n\t// Check if getElementsByTagName(\"*\") returns only elements\n\tsupport.getElementsByTagName = assert( function( el ) {\n\t\tel.appendChild( document.createComment( \"\" ) );\n\t\treturn !el.getElementsByTagName( \"*\" ).length;\n\t} );\n\n\t// Support: IE<9\n\tsupport.getElementsByClassName = rnative.test( document.getElementsByClassName );\n\n\t// Support: IE<10\n\t// Check if getElementById returns elements by name\n\t// The broken getElementById methods don't pick up programmatically-set names,\n\t// so use a roundabout getElementsByName test\n\tsupport.getById = assert( function( el ) {\n\t\tdocElem.appendChild( el ).id = expando;\n\t\treturn !document.getElementsByName || !document.getElementsByName( expando ).length;\n\t} );\n\n\t// ID filter and find\n\tif ( support.getById ) {\n\t\tExpr.filter[ \"ID\" ] = function( id ) {\n\t\t\tvar attrId = id.replace( runescape, funescape );\n\t\t\treturn function( elem ) {\n\t\t\t\treturn elem.getAttribute( \"id\" ) === attrId;\n\t\t\t};\n\t\t};\n\t\tExpr.find[ \"ID\" ] = function( id, context ) {\n\t\t\tif ( typeof context.getElementById !== \"undefined\" && documentIsHTML ) {\n\t\t\t\tvar elem = context.getElementById( id );\n\t\t\t\treturn elem ? [ elem ] : [];\n\t\t\t}\n\t\t};\n\t} else {\n\t\tExpr.filter[ \"ID\" ] =  function( id ) {\n\t\t\tvar attrId = id.replace( runescape, funescape );\n\t\t\treturn function( elem ) {\n\t\t\t\tvar node = typeof elem.getAttributeNode !== \"undefined\" &&\n\t\t\t\t\telem.getAttributeNode( \"id\" );\n\t\t\t\treturn node && node.value === attrId;\n\t\t\t};\n\t\t};\n\n\t\t// Support: IE 6 - 7 only\n\t\t// getElementById is not reliable as a find shortcut\n\t\tExpr.find[ \"ID\" ] = function( id, context ) {\n\t\t\tif ( typeof context.getElementById !== \"undefined\" && documentIsHTML ) {\n\t\t\t\tvar node, i, elems,\n\t\t\t\t\telem = context.getElementById( id );\n\n\t\t\t\tif ( elem ) {\n\n\t\t\t\t\t// Verify the id attribute\n\t\t\t\t\tnode = elem.getAttributeNode( \"id\" );\n\t\t\t\t\tif ( node && node.value === id ) {\n\t\t\t\t\t\treturn [ elem ];\n\t\t\t\t\t}\n\n\t\t\t\t\t// Fall back on getElementsByName\n\t\t\t\t\telems = context.getElementsByName( id );\n\t\t\t\t\ti = 0;\n\t\t\t\t\twhile ( ( elem = elems[ i++ ] ) ) {\n\t\t\t\t\t\tnode = elem.getAttributeNode( \"id\" );\n\t\t\t\t\t\tif ( node && node.value === id ) {\n\t\t\t\t\t\t\treturn [ elem ];\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\treturn [];\n\t\t\t}\n\t\t};\n\t}\n\n\t// Tag\n\tExpr.find[ \"TAG\" ] = support.getElementsByTagName ?\n\t\tfunction( tag, context ) {\n\t\t\tif ( typeof context.getElementsByTagName !== \"undefined\" ) {\n\t\t\t\treturn context.getElementsByTagName( tag );\n\n\t\t\t// DocumentFragment nodes don't have gEBTN\n\t\t\t} else if ( support.qsa ) {\n\t\t\t\treturn context.querySelectorAll( tag );\n\t\t\t}\n\t\t} :\n\n\t\tfunction( tag, context ) {\n\t\t\tvar elem,\n\t\t\t\ttmp = [],\n\t\t\t\ti = 0,\n\n\t\t\t\t// By happy coincidence, a (broken) gEBTN appears on DocumentFragment nodes too\n\t\t\t\tresults = context.getElementsByTagName( tag );\n\n\t\t\t// Filter out possible comments\n\t\t\tif ( tag === \"*\" ) {\n\t\t\t\twhile ( ( elem = results[ i++ ] ) ) {\n\t\t\t\t\tif ( elem.nodeType === 1 ) {\n\t\t\t\t\t\ttmp.push( elem );\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\treturn tmp;\n\t\t\t}\n\t\t\treturn results;\n\t\t};\n\n\t// Class\n\tExpr.find[ \"CLASS\" ] = support.getElementsByClassName && function( className, context ) {\n\t\tif ( typeof context.getElementsByClassName !== \"undefined\" && documentIsHTML ) {\n\t\t\treturn context.getElementsByClassName( className );\n\t\t}\n\t};\n\n\t/* QSA/matchesSelector\n\t---------------------------------------------------------------------- */\n\n\t// QSA and matchesSelector support\n\n\t// matchesSelector(:active) reports false when true (IE9/Opera 11.5)\n\trbuggyMatches = [];\n\n\t// qSa(:focus) reports false when true (Chrome 21)\n\t// We allow this because of a bug in IE8/9 that throws an error\n\t// whenever `document.activeElement` is accessed on an iframe\n\t// So, we allow :focus to pass through QSA all the time to avoid the IE error\n\t// See https://bugs.jquery.com/ticket/13378\n\trbuggyQSA = [];\n\n\tif ( ( support.qsa = rnative.test( document.querySelectorAll ) ) ) {\n\n\t\t// Build QSA regex\n\t\t// Regex strategy adopted from Diego Perini\n\t\tassert( function( el ) {\n\n\t\t\tvar input;\n\n\t\t\t// Select is set to empty string on purpose\n\t\t\t// This is to test IE's treatment of not explicitly\n\t\t\t// setting a boolean content attribute,\n\t\t\t// since its presence should be enough\n\t\t\t// https://bugs.jquery.com/ticket/12359\n\t\t\tdocElem.appendChild( el ).innerHTML = \"<a id='\" + expando + \"'></a>\" +\n\t\t\t\t\"<select id='\" + expando + \"-\\r\\\\' msallowcapture=''>\" +\n\t\t\t\t\"<option selected=''></option></select>\";\n\n\t\t\t// Support: IE8, Opera 11-12.16\n\t\t\t// Nothing should be selected when empty strings follow ^= or $= or *=\n\t\t\t// The test attribute must be unknown in Opera but \"safe\" for WinRT\n\t\t\t// https://msdn.microsoft.com/en-us/library/ie/hh465388.aspx#attribute_section\n\t\t\tif ( el.querySelectorAll( \"[msallowcapture^='']\" ).length ) {\n\t\t\t\trbuggyQSA.push( \"[*^$]=\" + whitespace + \"*(?:''|\\\"\\\")\" );\n\t\t\t}\n\n\t\t\t// Support: IE8\n\t\t\t// Boolean attributes and \"value\" are not treated correctly\n\t\t\tif ( !el.querySelectorAll( \"[selected]\" ).length ) {\n\t\t\t\trbuggyQSA.push( \"\\\\[\" + whitespace + \"*(?:value|\" + booleans + \")\" );\n\t\t\t}\n\n\t\t\t// Support: Chrome<29, Android<4.4, Safari<7.0+, iOS<7.0+, PhantomJS<1.9.8+\n\t\t\tif ( !el.querySelectorAll( \"[id~=\" + expando + \"-]\" ).length ) {\n\t\t\t\trbuggyQSA.push( \"~=\" );\n\t\t\t}\n\n\t\t\t// Support: IE 11+, Edge 15 - 18+\n\t\t\t// IE 11/Edge don't find elements on a `[name='']` query in some cases.\n\t\t\t// Adding a temporary attribute to the document before the selection works\n\t\t\t// around the issue.\n\t\t\t// Interestingly, IE 10 & older don't seem to have the issue.\n\t\t\tinput = document.createElement( \"input\" );\n\t\t\tinput.setAttribute( \"name\", \"\" );\n\t\t\tel.appendChild( input );\n\t\t\tif ( !el.querySelectorAll( \"[name='']\" ).length ) {\n\t\t\t\trbuggyQSA.push( \"\\\\[\" + whitespace + \"*name\" + whitespace + \"*=\" +\n\t\t\t\t\twhitespace + \"*(?:''|\\\"\\\")\" );\n\t\t\t}\n\n\t\t\t// Webkit/Opera - :checked should return selected option elements\n\t\t\t// http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked\n\t\t\t// IE8 throws error here and will not see later tests\n\t\t\tif ( !el.querySelectorAll( \":checked\" ).length ) {\n\t\t\t\trbuggyQSA.push( \":checked\" );\n\t\t\t}\n\n\t\t\t// Support: Safari 8+, iOS 8+\n\t\t\t// https://bugs.webkit.org/show_bug.cgi?id=136851\n\t\t\t// In-page `selector#id sibling-combinator selector` fails\n\t\t\tif ( !el.querySelectorAll( \"a#\" + expando + \"+*\" ).length ) {\n\t\t\t\trbuggyQSA.push( \".#.+[+~]\" );\n\t\t\t}\n\n\t\t\t// Support: Firefox <=3.6 - 5 only\n\t\t\t// Old Firefox doesn't throw on a badly-escaped identifier.\n\t\t\tel.querySelectorAll( \"\\\\\\f\" );\n\t\t\trbuggyQSA.push( \"[\\\\r\\\\n\\\\f]\" );\n\t\t} );\n\n\t\tassert( function( el ) {\n\t\t\tel.innerHTML = \"<a href='' disabled='disabled'></a>\" +\n\t\t\t\t\"<select disabled='disabled'><option/></select>\";\n\n\t\t\t// Support: Windows 8 Native Apps\n\t\t\t// The type and name attributes are restricted during .innerHTML assignment\n\t\t\tvar input = document.createElement( \"input\" );\n\t\t\tinput.setAttribute( \"type\", \"hidden\" );\n\t\t\tel.appendChild( input ).setAttribute( \"name\", \"D\" );\n\n\t\t\t// Support: IE8\n\t\t\t// Enforce case-sensitivity of name attribute\n\t\t\tif ( el.querySelectorAll( \"[name=d]\" ).length ) {\n\t\t\t\trbuggyQSA.push( \"name\" + whitespace + \"*[*^$|!~]?=\" );\n\t\t\t}\n\n\t\t\t// FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled)\n\t\t\t// IE8 throws error here and will not see later tests\n\t\t\tif ( el.querySelectorAll( \":enabled\" ).length !== 2 ) {\n\t\t\t\trbuggyQSA.push( \":enabled\", \":disabled\" );\n\t\t\t}\n\n\t\t\t// Support: IE9-11+\n\t\t\t// IE's :disabled selector does not pick up the children of disabled fieldsets\n\t\t\tdocElem.appendChild( el ).disabled = true;\n\t\t\tif ( el.querySelectorAll( \":disabled\" ).length !== 2 ) {\n\t\t\t\trbuggyQSA.push( \":enabled\", \":disabled\" );\n\t\t\t}\n\n\t\t\t// Support: Opera 10 - 11 only\n\t\t\t// Opera 10-11 does not throw on post-comma invalid pseudos\n\t\t\tel.querySelectorAll( \"*,:x\" );\n\t\t\trbuggyQSA.push( \",.*:\" );\n\t\t} );\n\t}\n\n\tif ( ( support.matchesSelector = rnative.test( ( matches = docElem.matches ||\n\t\tdocElem.webkitMatchesSelector ||\n\t\tdocElem.mozMatchesSelector ||\n\t\tdocElem.oMatchesSelector ||\n\t\tdocElem.msMatchesSelector ) ) ) ) {\n\n\t\tassert( function( el ) {\n\n\t\t\t// Check to see if it's possible to do matchesSelector\n\t\t\t// on a disconnected node (IE 9)\n\t\t\tsupport.disconnectedMatch = matches.call( el, \"*\" );\n\n\t\t\t// This should fail with an exception\n\t\t\t// Gecko does not error, returns false instead\n\t\t\tmatches.call( el, \"[s!='']:x\" );\n\t\t\trbuggyMatches.push( \"!=\", pseudos );\n\t\t} );\n\t}\n\n\trbuggyQSA = rbuggyQSA.length && new RegExp( rbuggyQSA.join( \"|\" ) );\n\trbuggyMatches = rbuggyMatches.length && new RegExp( rbuggyMatches.join( \"|\" ) );\n\n\t/* Contains\n\t---------------------------------------------------------------------- */\n\thasCompare = rnative.test( docElem.compareDocumentPosition );\n\n\t// Element contains another\n\t// Purposefully self-exclusive\n\t// As in, an element does not contain itself\n\tcontains = hasCompare || rnative.test( docElem.contains ) ?\n\t\tfunction( a, b ) {\n\t\t\tvar adown = a.nodeType === 9 ? a.documentElement : a,\n\t\t\t\tbup = b && b.parentNode;\n\t\t\treturn a === bup || !!( bup && bup.nodeType === 1 && (\n\t\t\t\tadown.contains ?\n\t\t\t\t\tadown.contains( bup ) :\n\t\t\t\t\ta.compareDocumentPosition && a.compareDocumentPosition( bup ) & 16\n\t\t\t) );\n\t\t} :\n\t\tfunction( a, b ) {\n\t\t\tif ( b ) {\n\t\t\t\twhile ( ( b = b.parentNode ) ) {\n\t\t\t\t\tif ( b === a ) {\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn false;\n\t\t};\n\n\t/* Sorting\n\t---------------------------------------------------------------------- */\n\n\t// Document order sorting\n\tsortOrder = hasCompare ?\n\tfunction( a, b ) {\n\n\t\t// Flag for duplicate removal\n\t\tif ( a === b ) {\n\t\t\thasDuplicate = true;\n\t\t\treturn 0;\n\t\t}\n\n\t\t// Sort on method existence if only one input has compareDocumentPosition\n\t\tvar compare = !a.compareDocumentPosition - !b.compareDocumentPosition;\n\t\tif ( compare ) {\n\t\t\treturn compare;\n\t\t}\n\n\t\t// Calculate position if both inputs belong to the same document\n\t\t// Support: IE 11+, Edge 17 - 18+\n\t\t// IE/Edge sometimes throw a \"Permission denied\" error when strict-comparing\n\t\t// two documents; shallow comparisons work.\n\t\t// eslint-disable-next-line eqeqeq\n\t\tcompare = ( a.ownerDocument || a ) == ( b.ownerDocument || b ) ?\n\t\t\ta.compareDocumentPosition( b ) :\n\n\t\t\t// Otherwise we know they are disconnected\n\t\t\t1;\n\n\t\t// Disconnected nodes\n\t\tif ( compare & 1 ||\n\t\t\t( !support.sortDetached && b.compareDocumentPosition( a ) === compare ) ) {\n\n\t\t\t// Choose the first element that is related to our preferred document\n\t\t\t// Support: IE 11+, Edge 17 - 18+\n\t\t\t// IE/Edge sometimes throw a \"Permission denied\" error when strict-comparing\n\t\t\t// two documents; shallow comparisons work.\n\t\t\t// eslint-disable-next-line eqeqeq\n\t\t\tif ( a == document || a.ownerDocument == preferredDoc &&\n\t\t\t\tcontains( preferredDoc, a ) ) {\n\t\t\t\treturn -1;\n\t\t\t}\n\n\t\t\t// Support: IE 11+, Edge 17 - 18+\n\t\t\t// IE/Edge sometimes throw a \"Permission denied\" error when strict-comparing\n\t\t\t// two documents; shallow comparisons work.\n\t\t\t// eslint-disable-next-line eqeqeq\n\t\t\tif ( b == document || b.ownerDocument == preferredDoc &&\n\t\t\t\tcontains( preferredDoc, b ) ) {\n\t\t\t\treturn 1;\n\t\t\t}\n\n\t\t\t// Maintain original order\n\t\t\treturn sortInput ?\n\t\t\t\t( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) :\n\t\t\t\t0;\n\t\t}\n\n\t\treturn compare & 4 ? -1 : 1;\n\t} :\n\tfunction( a, b ) {\n\n\t\t// Exit early if the nodes are identical\n\t\tif ( a === b ) {\n\t\t\thasDuplicate = true;\n\t\t\treturn 0;\n\t\t}\n\n\t\tvar cur,\n\t\t\ti = 0,\n\t\t\taup = a.parentNode,\n\t\t\tbup = b.parentNode,\n\t\t\tap = [ a ],\n\t\t\tbp = [ b ];\n\n\t\t// Parentless nodes are either documents or disconnected\n\t\tif ( !aup || !bup ) {\n\n\t\t\t// Support: IE 11+, Edge 17 - 18+\n\t\t\t// IE/Edge sometimes throw a \"Permission denied\" error when strict-comparing\n\t\t\t// two documents; shallow comparisons work.\n\t\t\t/* eslint-disable eqeqeq */\n\t\t\treturn a == document ? -1 :\n\t\t\t\tb == document ? 1 :\n\t\t\t\t/* eslint-enable eqeqeq */\n\t\t\t\taup ? -1 :\n\t\t\t\tbup ? 1 :\n\t\t\t\tsortInput ?\n\t\t\t\t( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) :\n\t\t\t\t0;\n\n\t\t// If the nodes are siblings, we can do a quick check\n\t\t} else if ( aup === bup ) {\n\t\t\treturn siblingCheck( a, b );\n\t\t}\n\n\t\t// Otherwise we need full lists of their ancestors for comparison\n\t\tcur = a;\n\t\twhile ( ( cur = cur.parentNode ) ) {\n\t\t\tap.unshift( cur );\n\t\t}\n\t\tcur = b;\n\t\twhile ( ( cur = cur.parentNode ) ) {\n\t\t\tbp.unshift( cur );\n\t\t}\n\n\t\t// Walk down the tree looking for a discrepancy\n\t\twhile ( ap[ i ] === bp[ i ] ) {\n\t\t\ti++;\n\t\t}\n\n\t\treturn i ?\n\n\t\t\t// Do a sibling check if the nodes have a common ancestor\n\t\t\tsiblingCheck( ap[ i ], bp[ i ] ) :\n\n\t\t\t// Otherwise nodes in our document sort first\n\t\t\t// Support: IE 11+, Edge 17 - 18+\n\t\t\t// IE/Edge sometimes throw a \"Permission denied\" error when strict-comparing\n\t\t\t// two documents; shallow comparisons work.\n\t\t\t/* eslint-disable eqeqeq */\n\t\t\tap[ i ] == preferredDoc ? -1 :\n\t\t\tbp[ i ] == preferredDoc ? 1 :\n\t\t\t/* eslint-enable eqeqeq */\n\t\t\t0;\n\t};\n\n\treturn document;\n};\n\nSizzle.matches = function( expr, elements ) {\n\treturn Sizzle( expr, null, null, elements );\n};\n\nSizzle.matchesSelector = function( elem, expr ) {\n\tsetDocument( elem );\n\n\tif ( support.matchesSelector && documentIsHTML &&\n\t\t!nonnativeSelectorCache[ expr + \" \" ] &&\n\t\t( !rbuggyMatches || !rbuggyMatches.test( expr ) ) &&\n\t\t( !rbuggyQSA     || !rbuggyQSA.test( expr ) ) ) {\n\n\t\ttry {\n\t\t\tvar ret = matches.call( elem, expr );\n\n\t\t\t// IE 9's matchesSelector returns false on disconnected nodes\n\t\t\tif ( ret || support.disconnectedMatch ||\n\n\t\t\t\t// As well, disconnected nodes are said to be in a document\n\t\t\t\t// fragment in IE 9\n\t\t\t\telem.document && elem.document.nodeType !== 11 ) {\n\t\t\t\treturn ret;\n\t\t\t}\n\t\t} catch ( e ) {\n\t\t\tnonnativeSelectorCache( expr, true );\n\t\t}\n\t}\n\n\treturn Sizzle( expr, document, null, [ elem ] ).length > 0;\n};\n\nSizzle.contains = function( context, elem ) {\n\n\t// Set document vars if needed\n\t// Support: IE 11+, Edge 17 - 18+\n\t// IE/Edge sometimes throw a \"Permission denied\" error when strict-comparing\n\t// two documents; shallow comparisons work.\n\t// eslint-disable-next-line eqeqeq\n\tif ( ( context.ownerDocument || context ) != document ) {\n\t\tsetDocument( context );\n\t}\n\treturn contains( context, elem );\n};\n\nSizzle.attr = function( elem, name ) {\n\n\t// Set document vars if needed\n\t// Support: IE 11+, Edge 17 - 18+\n\t// IE/Edge sometimes throw a \"Permission denied\" error when strict-comparing\n\t// two documents; shallow comparisons work.\n\t// eslint-disable-next-line eqeqeq\n\tif ( ( elem.ownerDocument || elem ) != document ) {\n\t\tsetDocument( elem );\n\t}\n\n\tvar fn = Expr.attrHandle[ name.toLowerCase() ],\n\n\t\t// Don't get fooled by Object.prototype properties (jQuery #13807)\n\t\tval = fn && hasOwn.call( Expr.attrHandle, name.toLowerCase() ) ?\n\t\t\tfn( elem, name, !documentIsHTML ) :\n\t\t\tundefined;\n\n\treturn val !== undefined ?\n\t\tval :\n\t\tsupport.attributes || !documentIsHTML ?\n\t\t\telem.getAttribute( name ) :\n\t\t\t( val = elem.getAttributeNode( name ) ) && val.specified ?\n\t\t\t\tval.value :\n\t\t\t\tnull;\n};\n\nSizzle.escape = function( sel ) {\n\treturn ( sel + \"\" ).replace( rcssescape, fcssescape );\n};\n\nSizzle.error = function( msg ) {\n\tthrow new Error( \"Syntax error, unrecognized expression: \" + msg );\n};\n\n/**\n * Document sorting and removing duplicates\n * @param {ArrayLike} results\n */\nSizzle.uniqueSort = function( results ) {\n\tvar elem,\n\t\tduplicates = [],\n\t\tj = 0,\n\t\ti = 0;\n\n\t// Unless we *know* we can detect duplicates, assume their presence\n\thasDuplicate = !support.detectDuplicates;\n\tsortInput = !support.sortStable && results.slice( 0 );\n\tresults.sort( sortOrder );\n\n\tif ( hasDuplicate ) {\n\t\twhile ( ( elem = results[ i++ ] ) ) {\n\t\t\tif ( elem === results[ i ] ) {\n\t\t\t\tj = duplicates.push( i );\n\t\t\t}\n\t\t}\n\t\twhile ( j-- ) {\n\t\t\tresults.splice( duplicates[ j ], 1 );\n\t\t}\n\t}\n\n\t// Clear input after sorting to release objects\n\t// See https://github.com/jquery/sizzle/pull/225\n\tsortInput = null;\n\n\treturn results;\n};\n\n/**\n * Utility function for retrieving the text value of an array of DOM nodes\n * @param {Array|Element} elem\n */\ngetText = Sizzle.getText = function( elem ) {\n\tvar node,\n\t\tret = \"\",\n\t\ti = 0,\n\t\tnodeType = elem.nodeType;\n\n\tif ( !nodeType ) {\n\n\t\t// If no nodeType, this is expected to be an array\n\t\twhile ( ( node = elem[ i++ ] ) ) {\n\n\t\t\t// Do not traverse comment nodes\n\t\t\tret += getText( node );\n\t\t}\n\t} else if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) {\n\n\t\t// Use textContent for elements\n\t\t// innerText usage removed for consistency of new lines (jQuery #11153)\n\t\tif ( typeof elem.textContent === \"string\" ) {\n\t\t\treturn elem.textContent;\n\t\t} else {\n\n\t\t\t// Traverse its children\n\t\t\tfor ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {\n\t\t\t\tret += getText( elem );\n\t\t\t}\n\t\t}\n\t} else if ( nodeType === 3 || nodeType === 4 ) {\n\t\treturn elem.nodeValue;\n\t}\n\n\t// Do not include comment or processing instruction nodes\n\n\treturn ret;\n};\n\nExpr = Sizzle.selectors = {\n\n\t// Can be adjusted by the user\n\tcacheLength: 50,\n\n\tcreatePseudo: markFunction,\n\n\tmatch: matchExpr,\n\n\tattrHandle: {},\n\n\tfind: {},\n\n\trelative: {\n\t\t\">\": { dir: \"parentNode\", first: true },\n\t\t\" \": { dir: \"parentNode\" },\n\t\t\"+\": { dir: \"previousSibling\", first: true },\n\t\t\"~\": { dir: \"previousSibling\" }\n\t},\n\n\tpreFilter: {\n\t\t\"ATTR\": function( match ) {\n\t\t\tmatch[ 1 ] = match[ 1 ].replace( runescape, funescape );\n\n\t\t\t// Move the given value to match[3] whether quoted or unquoted\n\t\t\tmatch[ 3 ] = ( match[ 3 ] || match[ 4 ] ||\n\t\t\t\tmatch[ 5 ] || \"\" ).replace( runescape, funescape );\n\n\t\t\tif ( match[ 2 ] === \"~=\" ) {\n\t\t\t\tmatch[ 3 ] = \" \" + match[ 3 ] + \" \";\n\t\t\t}\n\n\t\t\treturn match.slice( 0, 4 );\n\t\t},\n\n\t\t\"CHILD\": function( match ) {\n\n\t\t\t/* matches from matchExpr[\"CHILD\"]\n\t\t\t\t1 type (only|nth|...)\n\t\t\t\t2 what (child|of-type)\n\t\t\t\t3 argument (even|odd|\\d*|\\d*n([+-]\\d+)?|...)\n\t\t\t\t4 xn-component of xn+y argument ([+-]?\\d*n|)\n\t\t\t\t5 sign of xn-component\n\t\t\t\t6 x of xn-component\n\t\t\t\t7 sign of y-component\n\t\t\t\t8 y of y-component\n\t\t\t*/\n\t\t\tmatch[ 1 ] = match[ 1 ].toLowerCase();\n\n\t\t\tif ( match[ 1 ].slice( 0, 3 ) === \"nth\" ) {\n\n\t\t\t\t// nth-* requires argument\n\t\t\t\tif ( !match[ 3 ] ) {\n\t\t\t\t\tSizzle.error( match[ 0 ] );\n\t\t\t\t}\n\n\t\t\t\t// numeric x and y parameters for Expr.filter.CHILD\n\t\t\t\t// remember that false/true cast respectively to 0/1\n\t\t\t\tmatch[ 4 ] = +( match[ 4 ] ?\n\t\t\t\t\tmatch[ 5 ] + ( match[ 6 ] || 1 ) :\n\t\t\t\t\t2 * ( match[ 3 ] === \"even\" || match[ 3 ] === \"odd\" ) );\n\t\t\t\tmatch[ 5 ] = +( ( match[ 7 ] + match[ 8 ] ) || match[ 3 ] === \"odd\" );\n\n\t\t\t\t// other types prohibit arguments\n\t\t\t} else if ( match[ 3 ] ) {\n\t\t\t\tSizzle.error( match[ 0 ] );\n\t\t\t}\n\n\t\t\treturn match;\n\t\t},\n\n\t\t\"PSEUDO\": function( match ) {\n\t\t\tvar excess,\n\t\t\t\tunquoted = !match[ 6 ] && match[ 2 ];\n\n\t\t\tif ( matchExpr[ \"CHILD\" ].test( match[ 0 ] ) ) {\n\t\t\t\treturn null;\n\t\t\t}\n\n\t\t\t// Accept quoted arguments as-is\n\t\t\tif ( match[ 3 ] ) {\n\t\t\t\tmatch[ 2 ] = match[ 4 ] || match[ 5 ] || \"\";\n\n\t\t\t// Strip excess characters from unquoted arguments\n\t\t\t} else if ( unquoted && rpseudo.test( unquoted ) &&\n\n\t\t\t\t// Get excess from tokenize (recursively)\n\t\t\t\t( excess = tokenize( unquoted, true ) ) &&\n\n\t\t\t\t// advance to the next closing parenthesis\n\t\t\t\t( excess = unquoted.indexOf( \")\", unquoted.length - excess ) - unquoted.length ) ) {\n\n\t\t\t\t// excess is a negative index\n\t\t\t\tmatch[ 0 ] = match[ 0 ].slice( 0, excess );\n\t\t\t\tmatch[ 2 ] = unquoted.slice( 0, excess );\n\t\t\t}\n\n\t\t\t// Return only captures needed by the pseudo filter method (type and argument)\n\t\t\treturn match.slice( 0, 3 );\n\t\t}\n\t},\n\n\tfilter: {\n\n\t\t\"TAG\": function( nodeNameSelector ) {\n\t\t\tvar nodeName = nodeNameSelector.replace( runescape, funescape ).toLowerCase();\n\t\t\treturn nodeNameSelector === \"*\" ?\n\t\t\t\tfunction() {\n\t\t\t\t\treturn true;\n\t\t\t\t} :\n\t\t\t\tfunction( elem ) {\n\t\t\t\t\treturn elem.nodeName && elem.nodeName.toLowerCase() === nodeName;\n\t\t\t\t};\n\t\t},\n\n\t\t\"CLASS\": function( className ) {\n\t\t\tvar pattern = classCache[ className + \" \" ];\n\n\t\t\treturn pattern ||\n\t\t\t\t( pattern = new RegExp( \"(^|\" + whitespace +\n\t\t\t\t\t\")\" + className + \"(\" + whitespace + \"|$)\" ) ) && classCache(\n\t\t\t\t\t\tclassName, function( elem ) {\n\t\t\t\t\t\t\treturn pattern.test(\n\t\t\t\t\t\t\t\ttypeof elem.className === \"string\" && elem.className ||\n\t\t\t\t\t\t\t\ttypeof elem.getAttribute !== \"undefined\" &&\n\t\t\t\t\t\t\t\t\telem.getAttribute( \"class\" ) ||\n\t\t\t\t\t\t\t\t\"\"\n\t\t\t\t\t\t\t);\n\t\t\t\t} );\n\t\t},\n\n\t\t\"ATTR\": function( name, operator, check ) {\n\t\t\treturn function( elem ) {\n\t\t\t\tvar result = Sizzle.attr( elem, name );\n\n\t\t\t\tif ( result == null ) {\n\t\t\t\t\treturn operator === \"!=\";\n\t\t\t\t}\n\t\t\t\tif ( !operator ) {\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\n\t\t\t\tresult += \"\";\n\n\t\t\t\t/* eslint-disable max-len */\n\n\t\t\t\treturn operator === \"=\" ? result === check :\n\t\t\t\t\toperator === \"!=\" ? result !== check :\n\t\t\t\t\toperator === \"^=\" ? check && result.indexOf( check ) === 0 :\n\t\t\t\t\toperator === \"*=\" ? check && result.indexOf( check ) > -1 :\n\t\t\t\t\toperator === \"$=\" ? check && result.slice( -check.length ) === check :\n\t\t\t\t\toperator === \"~=\" ? ( \" \" + result.replace( rwhitespace, \" \" ) + \" \" ).indexOf( check ) > -1 :\n\t\t\t\t\toperator === \"|=\" ? result === check || result.slice( 0, check.length + 1 ) === check + \"-\" :\n\t\t\t\t\tfalse;\n\t\t\t\t/* eslint-enable max-len */\n\n\t\t\t};\n\t\t},\n\n\t\t\"CHILD\": function( type, what, _argument, first, last ) {\n\t\t\tvar simple = type.slice( 0, 3 ) !== \"nth\",\n\t\t\t\tforward = type.slice( -4 ) !== \"last\",\n\t\t\t\tofType = what === \"of-type\";\n\n\t\t\treturn first === 1 && last === 0 ?\n\n\t\t\t\t// Shortcut for :nth-*(n)\n\t\t\t\tfunction( elem ) {\n\t\t\t\t\treturn !!elem.parentNode;\n\t\t\t\t} :\n\n\t\t\t\tfunction( elem, _context, xml ) {\n\t\t\t\t\tvar cache, uniqueCache, outerCache, node, nodeIndex, start,\n\t\t\t\t\t\tdir = simple !== forward ? \"nextSibling\" : \"previousSibling\",\n\t\t\t\t\t\tparent = elem.parentNode,\n\t\t\t\t\t\tname = ofType && elem.nodeName.toLowerCase(),\n\t\t\t\t\t\tuseCache = !xml && !ofType,\n\t\t\t\t\t\tdiff = false;\n\n\t\t\t\t\tif ( parent ) {\n\n\t\t\t\t\t\t// :(first|last|only)-(child|of-type)\n\t\t\t\t\t\tif ( simple ) {\n\t\t\t\t\t\t\twhile ( dir ) {\n\t\t\t\t\t\t\t\tnode = elem;\n\t\t\t\t\t\t\t\twhile ( ( node = node[ dir ] ) ) {\n\t\t\t\t\t\t\t\t\tif ( ofType ?\n\t\t\t\t\t\t\t\t\t\tnode.nodeName.toLowerCase() === name :\n\t\t\t\t\t\t\t\t\t\tnode.nodeType === 1 ) {\n\n\t\t\t\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t// Reverse direction for :only-* (if we haven't yet done so)\n\t\t\t\t\t\t\t\tstart = dir = type === \"only\" && !start && \"nextSibling\";\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tstart = [ forward ? parent.firstChild : parent.lastChild ];\n\n\t\t\t\t\t\t// non-xml :nth-child(...) stores cache data on `parent`\n\t\t\t\t\t\tif ( forward && useCache ) {\n\n\t\t\t\t\t\t\t// Seek `elem` from a previously-cached index\n\n\t\t\t\t\t\t\t// ...in a gzip-friendly way\n\t\t\t\t\t\t\tnode = parent;\n\t\t\t\t\t\t\touterCache = node[ expando ] || ( node[ expando ] = {} );\n\n\t\t\t\t\t\t\t// Support: IE <9 only\n\t\t\t\t\t\t\t// Defend against cloned attroperties (jQuery gh-1709)\n\t\t\t\t\t\t\tuniqueCache = outerCache[ node.uniqueID ] ||\n\t\t\t\t\t\t\t\t( outerCache[ node.uniqueID ] = {} );\n\n\t\t\t\t\t\t\tcache = uniqueCache[ type ] || [];\n\t\t\t\t\t\t\tnodeIndex = cache[ 0 ] === dirruns && cache[ 1 ];\n\t\t\t\t\t\t\tdiff = nodeIndex && cache[ 2 ];\n\t\t\t\t\t\t\tnode = nodeIndex && parent.childNodes[ nodeIndex ];\n\n\t\t\t\t\t\t\twhile ( ( node = ++nodeIndex && node && node[ dir ] ||\n\n\t\t\t\t\t\t\t\t// Fallback to seeking `elem` from the start\n\t\t\t\t\t\t\t\t( diff = nodeIndex = 0 ) || start.pop() ) ) {\n\n\t\t\t\t\t\t\t\t// When found, cache indexes on `parent` and break\n\t\t\t\t\t\t\t\tif ( node.nodeType === 1 && ++diff && node === elem ) {\n\t\t\t\t\t\t\t\t\tuniqueCache[ type ] = [ dirruns, nodeIndex, diff ];\n\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t// Use previously-cached element index if available\n\t\t\t\t\t\t\tif ( useCache ) {\n\n\t\t\t\t\t\t\t\t// ...in a gzip-friendly way\n\t\t\t\t\t\t\t\tnode = elem;\n\t\t\t\t\t\t\t\touterCache = node[ expando ] || ( node[ expando ] = {} );\n\n\t\t\t\t\t\t\t\t// Support: IE <9 only\n\t\t\t\t\t\t\t\t// Defend against cloned attroperties (jQuery gh-1709)\n\t\t\t\t\t\t\t\tuniqueCache = outerCache[ node.uniqueID ] ||\n\t\t\t\t\t\t\t\t\t( outerCache[ node.uniqueID ] = {} );\n\n\t\t\t\t\t\t\t\tcache = uniqueCache[ type ] || [];\n\t\t\t\t\t\t\t\tnodeIndex = cache[ 0 ] === dirruns && cache[ 1 ];\n\t\t\t\t\t\t\t\tdiff = nodeIndex;\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t// xml :nth-child(...)\n\t\t\t\t\t\t\t// or :nth-last-child(...) or :nth(-last)?-of-type(...)\n\t\t\t\t\t\t\tif ( diff === false ) {\n\n\t\t\t\t\t\t\t\t// Use the same loop as above to seek `elem` from the start\n\t\t\t\t\t\t\t\twhile ( ( node = ++nodeIndex && node && node[ dir ] ||\n\t\t\t\t\t\t\t\t\t( diff = nodeIndex = 0 ) || start.pop() ) ) {\n\n\t\t\t\t\t\t\t\t\tif ( ( ofType ?\n\t\t\t\t\t\t\t\t\t\tnode.nodeName.toLowerCase() === name :\n\t\t\t\t\t\t\t\t\t\tnode.nodeType === 1 ) &&\n\t\t\t\t\t\t\t\t\t\t++diff ) {\n\n\t\t\t\t\t\t\t\t\t\t// Cache the index of each encountered element\n\t\t\t\t\t\t\t\t\t\tif ( useCache ) {\n\t\t\t\t\t\t\t\t\t\t\touterCache = node[ expando ] ||\n\t\t\t\t\t\t\t\t\t\t\t\t( node[ expando ] = {} );\n\n\t\t\t\t\t\t\t\t\t\t\t// Support: IE <9 only\n\t\t\t\t\t\t\t\t\t\t\t// Defend against cloned attroperties (jQuery gh-1709)\n\t\t\t\t\t\t\t\t\t\t\tuniqueCache = outerCache[ node.uniqueID ] ||\n\t\t\t\t\t\t\t\t\t\t\t\t( outerCache[ node.uniqueID ] = {} );\n\n\t\t\t\t\t\t\t\t\t\t\tuniqueCache[ type ] = [ dirruns, diff ];\n\t\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\t\tif ( node === elem ) {\n\t\t\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Incorporate the offset, then check against cycle size\n\t\t\t\t\t\tdiff -= last;\n\t\t\t\t\t\treturn diff === first || ( diff % first === 0 && diff / first >= 0 );\n\t\t\t\t\t}\n\t\t\t\t};\n\t\t},\n\n\t\t\"PSEUDO\": function( pseudo, argument ) {\n\n\t\t\t// pseudo-class names are case-insensitive\n\t\t\t// http://www.w3.org/TR/selectors/#pseudo-classes\n\t\t\t// Prioritize by case sensitivity in case custom pseudos are added with uppercase letters\n\t\t\t// Remember that setFilters inherits from pseudos\n\t\t\tvar args,\n\t\t\t\tfn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] ||\n\t\t\t\t\tSizzle.error( \"unsupported pseudo: \" + pseudo );\n\n\t\t\t// The user may use createPseudo to indicate that\n\t\t\t// arguments are needed to create the filter function\n\t\t\t// just as Sizzle does\n\t\t\tif ( fn[ expando ] ) {\n\t\t\t\treturn fn( argument );\n\t\t\t}\n\n\t\t\t// But maintain support for old signatures\n\t\t\tif ( fn.length > 1 ) {\n\t\t\t\targs = [ pseudo, pseudo, \"\", argument ];\n\t\t\t\treturn Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ?\n\t\t\t\t\tmarkFunction( function( seed, matches ) {\n\t\t\t\t\t\tvar idx,\n\t\t\t\t\t\t\tmatched = fn( seed, argument ),\n\t\t\t\t\t\t\ti = matched.length;\n\t\t\t\t\t\twhile ( i-- ) {\n\t\t\t\t\t\t\tidx = indexOf( seed, matched[ i ] );\n\t\t\t\t\t\t\tseed[ idx ] = !( matches[ idx ] = matched[ i ] );\n\t\t\t\t\t\t}\n\t\t\t\t\t} ) :\n\t\t\t\t\tfunction( elem ) {\n\t\t\t\t\t\treturn fn( elem, 0, args );\n\t\t\t\t\t};\n\t\t\t}\n\n\t\t\treturn fn;\n\t\t}\n\t},\n\n\tpseudos: {\n\n\t\t// Potentially complex pseudos\n\t\t\"not\": markFunction( function( selector ) {\n\n\t\t\t// Trim the selector passed to compile\n\t\t\t// to avoid treating leading and trailing\n\t\t\t// spaces as combinators\n\t\t\tvar input = [],\n\t\t\t\tresults = [],\n\t\t\t\tmatcher = compile( selector.replace( rtrim, \"$1\" ) );\n\n\t\t\treturn matcher[ expando ] ?\n\t\t\t\tmarkFunction( function( seed, matches, _context, xml ) {\n\t\t\t\t\tvar elem,\n\t\t\t\t\t\tunmatched = matcher( seed, null, xml, [] ),\n\t\t\t\t\t\ti = seed.length;\n\n\t\t\t\t\t// Match elements unmatched by `matcher`\n\t\t\t\t\twhile ( i-- ) {\n\t\t\t\t\t\tif ( ( elem = unmatched[ i ] ) ) {\n\t\t\t\t\t\t\tseed[ i ] = !( matches[ i ] = elem );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t} ) :\n\t\t\t\tfunction( elem, _context, xml ) {\n\t\t\t\t\tinput[ 0 ] = elem;\n\t\t\t\t\tmatcher( input, null, xml, results );\n\n\t\t\t\t\t// Don't keep the element (issue #299)\n\t\t\t\t\tinput[ 0 ] = null;\n\t\t\t\t\treturn !results.pop();\n\t\t\t\t};\n\t\t} ),\n\n\t\t\"has\": markFunction( function( selector ) {\n\t\t\treturn function( elem ) {\n\t\t\t\treturn Sizzle( selector, elem ).length > 0;\n\t\t\t};\n\t\t} ),\n\n\t\t\"contains\": markFunction( function( text ) {\n\t\t\ttext = text.replace( runescape, funescape );\n\t\t\treturn function( elem ) {\n\t\t\t\treturn ( elem.textContent || getText( elem ) ).indexOf( text ) > -1;\n\t\t\t};\n\t\t} ),\n\n\t\t// \"Whether an element is represented by a :lang() selector\n\t\t// is based solely on the element's language value\n\t\t// being equal to the identifier C,\n\t\t// or beginning with the identifier C immediately followed by \"-\".\n\t\t// The matching of C against the element's language value is performed case-insensitively.\n\t\t// The identifier C does not have to be a valid language name.\"\n\t\t// http://www.w3.org/TR/selectors/#lang-pseudo\n\t\t\"lang\": markFunction( function( lang ) {\n\n\t\t\t// lang value must be a valid identifier\n\t\t\tif ( !ridentifier.test( lang || \"\" ) ) {\n\t\t\t\tSizzle.error( \"unsupported lang: \" + lang );\n\t\t\t}\n\t\t\tlang = lang.replace( runescape, funescape ).toLowerCase();\n\t\t\treturn function( elem ) {\n\t\t\t\tvar elemLang;\n\t\t\t\tdo {\n\t\t\t\t\tif ( ( elemLang = documentIsHTML ?\n\t\t\t\t\t\telem.lang :\n\t\t\t\t\t\telem.getAttribute( \"xml:lang\" ) || elem.getAttribute( \"lang\" ) ) ) {\n\n\t\t\t\t\t\telemLang = elemLang.toLowerCase();\n\t\t\t\t\t\treturn elemLang === lang || elemLang.indexOf( lang + \"-\" ) === 0;\n\t\t\t\t\t}\n\t\t\t\t} while ( ( elem = elem.parentNode ) && elem.nodeType === 1 );\n\t\t\t\treturn false;\n\t\t\t};\n\t\t} ),\n\n\t\t// Miscellaneous\n\t\t\"target\": function( elem ) {\n\t\t\tvar hash = window.location && window.location.hash;\n\t\t\treturn hash && hash.slice( 1 ) === elem.id;\n\t\t},\n\n\t\t\"root\": function( elem ) {\n\t\t\treturn elem === docElem;\n\t\t},\n\n\t\t\"focus\": function( elem ) {\n\t\t\treturn elem === document.activeElement &&\n\t\t\t\t( !document.hasFocus || document.hasFocus() ) &&\n\t\t\t\t!!( elem.type || elem.href || ~elem.tabIndex );\n\t\t},\n\n\t\t// Boolean properties\n\t\t\"enabled\": createDisabledPseudo( false ),\n\t\t\"disabled\": createDisabledPseudo( true ),\n\n\t\t\"checked\": function( elem ) {\n\n\t\t\t// In CSS3, :checked should return both checked and selected elements\n\t\t\t// http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked\n\t\t\tvar nodeName = elem.nodeName.toLowerCase();\n\t\t\treturn ( nodeName === \"input\" && !!elem.checked ) ||\n\t\t\t\t( nodeName === \"option\" && !!elem.selected );\n\t\t},\n\n\t\t\"selected\": function( elem ) {\n\n\t\t\t// Accessing this property makes selected-by-default\n\t\t\t// options in Safari work properly\n\t\t\tif ( elem.parentNode ) {\n\t\t\t\t// eslint-disable-next-line no-unused-expressions\n\t\t\t\telem.parentNode.selectedIndex;\n\t\t\t}\n\n\t\t\treturn elem.selected === true;\n\t\t},\n\n\t\t// Contents\n\t\t\"empty\": function( elem ) {\n\n\t\t\t// http://www.w3.org/TR/selectors/#empty-pseudo\n\t\t\t// :empty is negated by element (1) or content nodes (text: 3; cdata: 4; entity ref: 5),\n\t\t\t//   but not by others (comment: 8; processing instruction: 7; etc.)\n\t\t\t// nodeType < 6 works because attributes (2) do not appear as children\n\t\t\tfor ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {\n\t\t\t\tif ( elem.nodeType < 6 ) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn true;\n\t\t},\n\n\t\t\"parent\": function( elem ) {\n\t\t\treturn !Expr.pseudos[ \"empty\" ]( elem );\n\t\t},\n\n\t\t// Element/input types\n\t\t\"header\": function( elem ) {\n\t\t\treturn rheader.test( elem.nodeName );\n\t\t},\n\n\t\t\"input\": function( elem ) {\n\t\t\treturn rinputs.test( elem.nodeName );\n\t\t},\n\n\t\t\"button\": function( elem ) {\n\t\t\tvar name = elem.nodeName.toLowerCase();\n\t\t\treturn name === \"input\" && elem.type === \"button\" || name === \"button\";\n\t\t},\n\n\t\t\"text\": function( elem ) {\n\t\t\tvar attr;\n\t\t\treturn elem.nodeName.toLowerCase() === \"input\" &&\n\t\t\t\telem.type === \"text\" &&\n\n\t\t\t\t// Support: IE<8\n\t\t\t\t// New HTML5 attribute values (e.g., \"search\") appear with elem.type === \"text\"\n\t\t\t\t( ( attr = elem.getAttribute( \"type\" ) ) == null ||\n\t\t\t\t\tattr.toLowerCase() === \"text\" );\n\t\t},\n\n\t\t// Position-in-collection\n\t\t\"first\": createPositionalPseudo( function() {\n\t\t\treturn [ 0 ];\n\t\t} ),\n\n\t\t\"last\": createPositionalPseudo( function( _matchIndexes, length ) {\n\t\t\treturn [ length - 1 ];\n\t\t} ),\n\n\t\t\"eq\": createPositionalPseudo( function( _matchIndexes, length, argument ) {\n\t\t\treturn [ argument < 0 ? argument + length : argument ];\n\t\t} ),\n\n\t\t\"even\": createPositionalPseudo( function( matchIndexes, length ) {\n\t\t\tvar i = 0;\n\t\t\tfor ( ; i < length; i += 2 ) {\n\t\t\t\tmatchIndexes.push( i );\n\t\t\t}\n\t\t\treturn matchIndexes;\n\t\t} ),\n\n\t\t\"odd\": createPositionalPseudo( function( matchIndexes, length ) {\n\t\t\tvar i = 1;\n\t\t\tfor ( ; i < length; i += 2 ) {\n\t\t\t\tmatchIndexes.push( i );\n\t\t\t}\n\t\t\treturn matchIndexes;\n\t\t} ),\n\n\t\t\"lt\": createPositionalPseudo( function( matchIndexes, length, argument ) {\n\t\t\tvar i = argument < 0 ?\n\t\t\t\targument + length :\n\t\t\t\targument > length ?\n\t\t\t\t\tlength :\n\t\t\t\t\targument;\n\t\t\tfor ( ; --i >= 0; ) {\n\t\t\t\tmatchIndexes.push( i );\n\t\t\t}\n\t\t\treturn matchIndexes;\n\t\t} ),\n\n\t\t\"gt\": createPositionalPseudo( function( matchIndexes, length, argument ) {\n\t\t\tvar i = argument < 0 ? argument + length : argument;\n\t\t\tfor ( ; ++i < length; ) {\n\t\t\t\tmatchIndexes.push( i );\n\t\t\t}\n\t\t\treturn matchIndexes;\n\t\t} )\n\t}\n};\n\nExpr.pseudos[ \"nth\" ] = Expr.pseudos[ \"eq\" ];\n\n// Add button/input type pseudos\nfor ( i in { radio: true, checkbox: true, file: true, password: true, image: true } ) {\n\tExpr.pseudos[ i ] = createInputPseudo( i );\n}\nfor ( i in { submit: true, reset: true } ) {\n\tExpr.pseudos[ i ] = createButtonPseudo( i );\n}\n\n// Easy API for creating new setFilters\nfunction setFilters() {}\nsetFilters.prototype = Expr.filters = Expr.pseudos;\nExpr.setFilters = new setFilters();\n\ntokenize = Sizzle.tokenize = function( selector, parseOnly ) {\n\tvar matched, match, tokens, type,\n\t\tsoFar, groups, preFilters,\n\t\tcached = tokenCache[ selector + \" \" ];\n\n\tif ( cached ) {\n\t\treturn parseOnly ? 0 : cached.slice( 0 );\n\t}\n\n\tsoFar = selector;\n\tgroups = [];\n\tpreFilters = Expr.preFilter;\n\n\twhile ( soFar ) {\n\n\t\t// Comma and first run\n\t\tif ( !matched || ( match = rcomma.exec( soFar ) ) ) {\n\t\t\tif ( match ) {\n\n\t\t\t\t// Don't consume trailing commas as valid\n\t\t\t\tsoFar = soFar.slice( match[ 0 ].length ) || soFar;\n\t\t\t}\n\t\t\tgroups.push( ( tokens = [] ) );\n\t\t}\n\n\t\tmatched = false;\n\n\t\t// Combinators\n\t\tif ( ( match = rcombinators.exec( soFar ) ) ) {\n\t\t\tmatched = match.shift();\n\t\t\ttokens.push( {\n\t\t\t\tvalue: matched,\n\n\t\t\t\t// Cast descendant combinators to space\n\t\t\t\ttype: match[ 0 ].replace( rtrim, \" \" )\n\t\t\t} );\n\t\t\tsoFar = soFar.slice( matched.length );\n\t\t}\n\n\t\t// Filters\n\t\tfor ( type in Expr.filter ) {\n\t\t\tif ( ( match = matchExpr[ type ].exec( soFar ) ) && ( !preFilters[ type ] ||\n\t\t\t\t( match = preFilters[ type ]( match ) ) ) ) {\n\t\t\t\tmatched = match.shift();\n\t\t\t\ttokens.push( {\n\t\t\t\t\tvalue: matched,\n\t\t\t\t\ttype: type,\n\t\t\t\t\tmatches: match\n\t\t\t\t} );\n\t\t\t\tsoFar = soFar.slice( matched.length );\n\t\t\t}\n\t\t}\n\n\t\tif ( !matched ) {\n\t\t\tbreak;\n\t\t}\n\t}\n\n\t// Return the length of the invalid excess\n\t// if we're just parsing\n\t// Otherwise, throw an error or return tokens\n\treturn parseOnly ?\n\t\tsoFar.length :\n\t\tsoFar ?\n\t\t\tSizzle.error( selector ) :\n\n\t\t\t// Cache the tokens\n\t\t\ttokenCache( selector, groups ).slice( 0 );\n};\n\nfunction toSelector( tokens ) {\n\tvar i = 0,\n\t\tlen = tokens.length,\n\t\tselector = \"\";\n\tfor ( ; i < len; i++ ) {\n\t\tselector += tokens[ i ].value;\n\t}\n\treturn selector;\n}\n\nfunction addCombinator( matcher, combinator, base ) {\n\tvar dir = combinator.dir,\n\t\tskip = combinator.next,\n\t\tkey = skip || dir,\n\t\tcheckNonElements = base && key === \"parentNode\",\n\t\tdoneName = done++;\n\n\treturn combinator.first ?\n\n\t\t// Check against closest ancestor/preceding element\n\t\tfunction( elem, context, xml ) {\n\t\t\twhile ( ( elem = elem[ dir ] ) ) {\n\t\t\t\tif ( elem.nodeType === 1 || checkNonElements ) {\n\t\t\t\t\treturn matcher( elem, context, xml );\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn false;\n\t\t} :\n\n\t\t// Check against all ancestor/preceding elements\n\t\tfunction( elem, context, xml ) {\n\t\t\tvar oldCache, uniqueCache, outerCache,\n\t\t\t\tnewCache = [ dirruns, doneName ];\n\n\t\t\t// We can't set arbitrary data on XML nodes, so they don't benefit from combinator caching\n\t\t\tif ( xml ) {\n\t\t\t\twhile ( ( elem = elem[ dir ] ) ) {\n\t\t\t\t\tif ( elem.nodeType === 1 || checkNonElements ) {\n\t\t\t\t\t\tif ( matcher( elem, context, xml ) ) {\n\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\twhile ( ( elem = elem[ dir ] ) ) {\n\t\t\t\t\tif ( elem.nodeType === 1 || checkNonElements ) {\n\t\t\t\t\t\touterCache = elem[ expando ] || ( elem[ expando ] = {} );\n\n\t\t\t\t\t\t// Support: IE <9 only\n\t\t\t\t\t\t// Defend against cloned attroperties (jQuery gh-1709)\n\t\t\t\t\t\tuniqueCache = outerCache[ elem.uniqueID ] ||\n\t\t\t\t\t\t\t( outerCache[ elem.uniqueID ] = {} );\n\n\t\t\t\t\t\tif ( skip && skip === elem.nodeName.toLowerCase() ) {\n\t\t\t\t\t\t\telem = elem[ dir ] || elem;\n\t\t\t\t\t\t} else if ( ( oldCache = uniqueCache[ key ] ) &&\n\t\t\t\t\t\t\toldCache[ 0 ] === dirruns && oldCache[ 1 ] === doneName ) {\n\n\t\t\t\t\t\t\t// Assign to newCache so results back-propagate to previous elements\n\t\t\t\t\t\t\treturn ( newCache[ 2 ] = oldCache[ 2 ] );\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t// Reuse newcache so results back-propagate to previous elements\n\t\t\t\t\t\t\tuniqueCache[ key ] = newCache;\n\n\t\t\t\t\t\t\t// A match means we're done; a fail means we have to keep checking\n\t\t\t\t\t\t\tif ( ( newCache[ 2 ] = matcher( elem, context, xml ) ) ) {\n\t\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn false;\n\t\t};\n}\n\nfunction elementMatcher( matchers ) {\n\treturn matchers.length > 1 ?\n\t\tfunction( elem, context, xml ) {\n\t\t\tvar i = matchers.length;\n\t\t\twhile ( i-- ) {\n\t\t\t\tif ( !matchers[ i ]( elem, context, xml ) ) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn true;\n\t\t} :\n\t\tmatchers[ 0 ];\n}\n\nfunction multipleContexts( selector, contexts, results ) {\n\tvar i = 0,\n\t\tlen = contexts.length;\n\tfor ( ; i < len; i++ ) {\n\t\tSizzle( selector, contexts[ i ], results );\n\t}\n\treturn results;\n}\n\nfunction condense( unmatched, map, filter, context, xml ) {\n\tvar elem,\n\t\tnewUnmatched = [],\n\t\ti = 0,\n\t\tlen = unmatched.length,\n\t\tmapped = map != null;\n\n\tfor ( ; i < len; i++ ) {\n\t\tif ( ( elem = unmatched[ i ] ) ) {\n\t\t\tif ( !filter || filter( elem, context, xml ) ) {\n\t\t\t\tnewUnmatched.push( elem );\n\t\t\t\tif ( mapped ) {\n\t\t\t\t\tmap.push( i );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn newUnmatched;\n}\n\nfunction setMatcher( preFilter, selector, matcher, postFilter, postFinder, postSelector ) {\n\tif ( postFilter && !postFilter[ expando ] ) {\n\t\tpostFilter = setMatcher( postFilter );\n\t}\n\tif ( postFinder && !postFinder[ expando ] ) {\n\t\tpostFinder = setMatcher( postFinder, postSelector );\n\t}\n\treturn markFunction( function( seed, results, context, xml ) {\n\t\tvar temp, i, elem,\n\t\t\tpreMap = [],\n\t\t\tpostMap = [],\n\t\t\tpreexisting = results.length,\n\n\t\t\t// Get initial elements from seed or context\n\t\t\telems = seed || multipleContexts(\n\t\t\t\tselector || \"*\",\n\t\t\t\tcontext.nodeType ? [ context ] : context,\n\t\t\t\t[]\n\t\t\t),\n\n\t\t\t// Prefilter to get matcher input, preserving a map for seed-results synchronization\n\t\t\tmatcherIn = preFilter && ( seed || !selector ) ?\n\t\t\t\tcondense( elems, preMap, preFilter, context, xml ) :\n\t\t\t\telems,\n\n\t\t\tmatcherOut = matcher ?\n\n\t\t\t\t// If we have a postFinder, or filtered seed, or non-seed postFilter or preexisting results,\n\t\t\t\tpostFinder || ( seed ? preFilter : preexisting || postFilter ) ?\n\n\t\t\t\t\t// ...intermediate processing is necessary\n\t\t\t\t\t[] :\n\n\t\t\t\t\t// ...otherwise use results directly\n\t\t\t\t\tresults :\n\t\t\t\tmatcherIn;\n\n\t\t// Find primary matches\n\t\tif ( matcher ) {\n\t\t\tmatcher( matcherIn, matcherOut, context, xml );\n\t\t}\n\n\t\t// Apply postFilter\n\t\tif ( postFilter ) {\n\t\t\ttemp = condense( matcherOut, postMap );\n\t\t\tpostFilter( temp, [], context, xml );\n\n\t\t\t// Un-match failing elements by moving them back to matcherIn\n\t\t\ti = temp.length;\n\t\t\twhile ( i-- ) {\n\t\t\t\tif ( ( elem = temp[ i ] ) ) {\n\t\t\t\t\tmatcherOut[ postMap[ i ] ] = !( matcherIn[ postMap[ i ] ] = elem );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif ( seed ) {\n\t\t\tif ( postFinder || preFilter ) {\n\t\t\t\tif ( postFinder ) {\n\n\t\t\t\t\t// Get the final matcherOut by condensing this intermediate into postFinder contexts\n\t\t\t\t\ttemp = [];\n\t\t\t\t\ti = matcherOut.length;\n\t\t\t\t\twhile ( i-- ) {\n\t\t\t\t\t\tif ( ( elem = matcherOut[ i ] ) ) {\n\n\t\t\t\t\t\t\t// Restore matcherIn since elem is not yet a final match\n\t\t\t\t\t\t\ttemp.push( ( matcherIn[ i ] = elem ) );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tpostFinder( null, ( matcherOut = [] ), temp, xml );\n\t\t\t\t}\n\n\t\t\t\t// Move matched elements from seed to results to keep them synchronized\n\t\t\t\ti = matcherOut.length;\n\t\t\t\twhile ( i-- ) {\n\t\t\t\t\tif ( ( elem = matcherOut[ i ] ) &&\n\t\t\t\t\t\t( temp = postFinder ? indexOf( seed, elem ) : preMap[ i ] ) > -1 ) {\n\n\t\t\t\t\t\tseed[ temp ] = !( results[ temp ] = elem );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t// Add elements to results, through postFinder if defined\n\t\t} else {\n\t\t\tmatcherOut = condense(\n\t\t\t\tmatcherOut === results ?\n\t\t\t\t\tmatcherOut.splice( preexisting, matcherOut.length ) :\n\t\t\t\t\tmatcherOut\n\t\t\t);\n\t\t\tif ( postFinder ) {\n\t\t\t\tpostFinder( null, results, matcherOut, xml );\n\t\t\t} else {\n\t\t\t\tpush.apply( results, matcherOut );\n\t\t\t}\n\t\t}\n\t} );\n}\n\nfunction matcherFromTokens( tokens ) {\n\tvar checkContext, matcher, j,\n\t\tlen = tokens.length,\n\t\tleadingRelative = Expr.relative[ tokens[ 0 ].type ],\n\t\timplicitRelative = leadingRelative || Expr.relative[ \" \" ],\n\t\ti = leadingRelative ? 1 : 0,\n\n\t\t// The foundational matcher ensures that elements are reachable from top-level context(s)\n\t\tmatchContext = addCombinator( function( elem ) {\n\t\t\treturn elem === checkContext;\n\t\t}, implicitRelative, true ),\n\t\tmatchAnyContext = addCombinator( function( elem ) {\n\t\t\treturn indexOf( checkContext, elem ) > -1;\n\t\t}, implicitRelative, true ),\n\t\tmatchers = [ function( elem, context, xml ) {\n\t\t\tvar ret = ( !leadingRelative && ( xml || context !== outermostContext ) ) || (\n\t\t\t\t( checkContext = context ).nodeType ?\n\t\t\t\t\tmatchContext( elem, context, xml ) :\n\t\t\t\t\tmatchAnyContext( elem, context, xml ) );\n\n\t\t\t// Avoid hanging onto element (issue #299)\n\t\t\tcheckContext = null;\n\t\t\treturn ret;\n\t\t} ];\n\n\tfor ( ; i < len; i++ ) {\n\t\tif ( ( matcher = Expr.relative[ tokens[ i ].type ] ) ) {\n\t\t\tmatchers = [ addCombinator( elementMatcher( matchers ), matcher ) ];\n\t\t} else {\n\t\t\tmatcher = Expr.filter[ tokens[ i ].type ].apply( null, tokens[ i ].matches );\n\n\t\t\t// Return special upon seeing a positional matcher\n\t\t\tif ( matcher[ expando ] ) {\n\n\t\t\t\t// Find the next relative operator (if any) for proper handling\n\t\t\t\tj = ++i;\n\t\t\t\tfor ( ; j < len; j++ ) {\n\t\t\t\t\tif ( Expr.relative[ tokens[ j ].type ] ) {\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn setMatcher(\n\t\t\t\t\ti > 1 && elementMatcher( matchers ),\n\t\t\t\t\ti > 1 && toSelector(\n\n\t\t\t\t\t// If the preceding token was a descendant combinator, insert an implicit any-element `*`\n\t\t\t\t\ttokens\n\t\t\t\t\t\t.slice( 0, i - 1 )\n\t\t\t\t\t\t.concat( { value: tokens[ i - 2 ].type === \" \" ? \"*\" : \"\" } )\n\t\t\t\t\t).replace( rtrim, \"$1\" ),\n\t\t\t\t\tmatcher,\n\t\t\t\t\ti < j && matcherFromTokens( tokens.slice( i, j ) ),\n\t\t\t\t\tj < len && matcherFromTokens( ( tokens = tokens.slice( j ) ) ),\n\t\t\t\t\tj < len && toSelector( tokens )\n\t\t\t\t);\n\t\t\t}\n\t\t\tmatchers.push( matcher );\n\t\t}\n\t}\n\n\treturn elementMatcher( matchers );\n}\n\nfunction matcherFromGroupMatchers( elementMatchers, setMatchers ) {\n\tvar bySet = setMatchers.length > 0,\n\t\tbyElement = elementMatchers.length > 0,\n\t\tsuperMatcher = function( seed, context, xml, results, outermost ) {\n\t\t\tvar elem, j, matcher,\n\t\t\t\tmatchedCount = 0,\n\t\t\t\ti = \"0\",\n\t\t\t\tunmatched = seed && [],\n\t\t\t\tsetMatched = [],\n\t\t\t\tcontextBackup = outermostContext,\n\n\t\t\t\t// We must always have either seed elements or outermost context\n\t\t\t\telems = seed || byElement && Expr.find[ \"TAG\" ]( \"*\", outermost ),\n\n\t\t\t\t// Use integer dirruns iff this is the outermost matcher\n\t\t\t\tdirrunsUnique = ( dirruns += contextBackup == null ? 1 : Math.random() || 0.1 ),\n\t\t\t\tlen = elems.length;\n\n\t\t\tif ( outermost ) {\n\n\t\t\t\t// Support: IE 11+, Edge 17 - 18+\n\t\t\t\t// IE/Edge sometimes throw a \"Permission denied\" error when strict-comparing\n\t\t\t\t// two documents; shallow comparisons work.\n\t\t\t\t// eslint-disable-next-line eqeqeq\n\t\t\t\toutermostContext = context == document || context || outermost;\n\t\t\t}\n\n\t\t\t// Add elements passing elementMatchers directly to results\n\t\t\t// Support: IE<9, Safari\n\t\t\t// Tolerate NodeList properties (IE: \"length\"; Safari: <number>) matching elements by id\n\t\t\tfor ( ; i !== len && ( elem = elems[ i ] ) != null; i++ ) {\n\t\t\t\tif ( byElement && elem ) {\n\t\t\t\t\tj = 0;\n\n\t\t\t\t\t// Support: IE 11+, Edge 17 - 18+\n\t\t\t\t\t// IE/Edge sometimes throw a \"Permission denied\" error when strict-comparing\n\t\t\t\t\t// two documents; shallow comparisons work.\n\t\t\t\t\t// eslint-disable-next-line eqeqeq\n\t\t\t\t\tif ( !context && elem.ownerDocument != document ) {\n\t\t\t\t\t\tsetDocument( elem );\n\t\t\t\t\t\txml = !documentIsHTML;\n\t\t\t\t\t}\n\t\t\t\t\twhile ( ( matcher = elementMatchers[ j++ ] ) ) {\n\t\t\t\t\t\tif ( matcher( elem, context || document, xml ) ) {\n\t\t\t\t\t\t\tresults.push( elem );\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tif ( outermost ) {\n\t\t\t\t\t\tdirruns = dirrunsUnique;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Track unmatched elements for set filters\n\t\t\t\tif ( bySet ) {\n\n\t\t\t\t\t// They will have gone through all possible matchers\n\t\t\t\t\tif ( ( elem = !matcher && elem ) ) {\n\t\t\t\t\t\tmatchedCount--;\n\t\t\t\t\t}\n\n\t\t\t\t\t// Lengthen the array for every element, matched or not\n\t\t\t\t\tif ( seed ) {\n\t\t\t\t\t\tunmatched.push( elem );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// `i` is now the count of elements visited above, and adding it to `matchedCount`\n\t\t\t// makes the latter nonnegative.\n\t\t\tmatchedCount += i;\n\n\t\t\t// Apply set filters to unmatched elements\n\t\t\t// NOTE: This can be skipped if there are no unmatched elements (i.e., `matchedCount`\n\t\t\t// equals `i`), unless we didn't visit _any_ elements in the above loop because we have\n\t\t\t// no element matchers and no seed.\n\t\t\t// Incrementing an initially-string \"0\" `i` allows `i` to remain a string only in that\n\t\t\t// case, which will result in a \"00\" `matchedCount` that differs from `i` but is also\n\t\t\t// numerically zero.\n\t\t\tif ( bySet && i !== matchedCount ) {\n\t\t\t\tj = 0;\n\t\t\t\twhile ( ( matcher = setMatchers[ j++ ] ) ) {\n\t\t\t\t\tmatcher( unmatched, setMatched, context, xml );\n\t\t\t\t}\n\n\t\t\t\tif ( seed ) {\n\n\t\t\t\t\t// Reintegrate element matches to eliminate the need for sorting\n\t\t\t\t\tif ( matchedCount > 0 ) {\n\t\t\t\t\t\twhile ( i-- ) {\n\t\t\t\t\t\t\tif ( !( unmatched[ i ] || setMatched[ i ] ) ) {\n\t\t\t\t\t\t\t\tsetMatched[ i ] = pop.call( results );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t// Discard index placeholder values to get only actual matches\n\t\t\t\t\tsetMatched = condense( setMatched );\n\t\t\t\t}\n\n\t\t\t\t// Add matches to results\n\t\t\t\tpush.apply( results, setMatched );\n\n\t\t\t\t// Seedless set matches succeeding multiple successful matchers stipulate sorting\n\t\t\t\tif ( outermost && !seed && setMatched.length > 0 &&\n\t\t\t\t\t( matchedCount + setMatchers.length ) > 1 ) {\n\n\t\t\t\t\tSizzle.uniqueSort( results );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Override manipulation of globals by nested matchers\n\t\t\tif ( outermost ) {\n\t\t\t\tdirruns = dirrunsUnique;\n\t\t\t\toutermostContext = contextBackup;\n\t\t\t}\n\n\t\t\treturn unmatched;\n\t\t};\n\n\treturn bySet ?\n\t\tmarkFunction( superMatcher ) :\n\t\tsuperMatcher;\n}\n\ncompile = Sizzle.compile = function( selector, match /* Internal Use Only */ ) {\n\tvar i,\n\t\tsetMatchers = [],\n\t\telementMatchers = [],\n\t\tcached = compilerCache[ selector + \" \" ];\n\n\tif ( !cached ) {\n\n\t\t// Generate a function of recursive functions that can be used to check each element\n\t\tif ( !match ) {\n\t\t\tmatch = tokenize( selector );\n\t\t}\n\t\ti = match.length;\n\t\twhile ( i-- ) {\n\t\t\tcached = matcherFromTokens( match[ i ] );\n\t\t\tif ( cached[ expando ] ) {\n\t\t\t\tsetMatchers.push( cached );\n\t\t\t} else {\n\t\t\t\telementMatchers.push( cached );\n\t\t\t}\n\t\t}\n\n\t\t// Cache the compiled function\n\t\tcached = compilerCache(\n\t\t\tselector,\n\t\t\tmatcherFromGroupMatchers( elementMatchers, setMatchers )\n\t\t);\n\n\t\t// Save selector and tokenization\n\t\tcached.selector = selector;\n\t}\n\treturn cached;\n};\n\n/**\n * A low-level selection function that works with Sizzle's compiled\n *  selector functions\n * @param {String|Function} selector A selector or a pre-compiled\n *  selector function built with Sizzle.compile\n * @param {Element} context\n * @param {Array} [results]\n * @param {Array} [seed] A set of elements to match against\n */\nselect = Sizzle.select = function( selector, context, results, seed ) {\n\tvar i, tokens, token, type, find,\n\t\tcompiled = typeof selector === \"function\" && selector,\n\t\tmatch = !seed && tokenize( ( selector = compiled.selector || selector ) );\n\n\tresults = results || [];\n\n\t// Try to minimize operations if there is only one selector in the list and no seed\n\t// (the latter of which guarantees us context)\n\tif ( match.length === 1 ) {\n\n\t\t// Reduce context if the leading compound selector is an ID\n\t\ttokens = match[ 0 ] = match[ 0 ].slice( 0 );\n\t\tif ( tokens.length > 2 && ( token = tokens[ 0 ] ).type === \"ID\" &&\n\t\t\tcontext.nodeType === 9 && documentIsHTML && Expr.relative[ tokens[ 1 ].type ] ) {\n\n\t\t\tcontext = ( Expr.find[ \"ID\" ]( token.matches[ 0 ]\n\t\t\t\t.replace( runescape, funescape ), context ) || [] )[ 0 ];\n\t\t\tif ( !context ) {\n\t\t\t\treturn results;\n\n\t\t\t// Precompiled matchers will still verify ancestry, so step up a level\n\t\t\t} else if ( compiled ) {\n\t\t\t\tcontext = context.parentNode;\n\t\t\t}\n\n\t\t\tselector = selector.slice( tokens.shift().value.length );\n\t\t}\n\n\t\t// Fetch a seed set for right-to-left matching\n\t\ti = matchExpr[ \"needsContext\" ].test( selector ) ? 0 : tokens.length;\n\t\twhile ( i-- ) {\n\t\t\ttoken = tokens[ i ];\n\n\t\t\t// Abort if we hit a combinator\n\t\t\tif ( Expr.relative[ ( type = token.type ) ] ) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tif ( ( find = Expr.find[ type ] ) ) {\n\n\t\t\t\t// Search, expanding context for leading sibling combinators\n\t\t\t\tif ( ( seed = find(\n\t\t\t\t\ttoken.matches[ 0 ].replace( runescape, funescape ),\n\t\t\t\t\trsibling.test( tokens[ 0 ].type ) && testContext( context.parentNode ) ||\n\t\t\t\t\t\tcontext\n\t\t\t\t) ) ) {\n\n\t\t\t\t\t// If seed is empty or no tokens remain, we can return early\n\t\t\t\t\ttokens.splice( i, 1 );\n\t\t\t\t\tselector = seed.length && toSelector( tokens );\n\t\t\t\t\tif ( !selector ) {\n\t\t\t\t\t\tpush.apply( results, seed );\n\t\t\t\t\t\treturn results;\n\t\t\t\t\t}\n\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// Compile and execute a filtering function if one is not provided\n\t// Provide `match` to avoid retokenization if we modified the selector above\n\t( compiled || compile( selector, match ) )(\n\t\tseed,\n\t\tcontext,\n\t\t!documentIsHTML,\n\t\tresults,\n\t\t!context || rsibling.test( selector ) && testContext( context.parentNode ) || context\n\t);\n\treturn results;\n};\n\n// One-time assignments\n\n// Sort stability\nsupport.sortStable = expando.split( \"\" ).sort( sortOrder ).join( \"\" ) === expando;\n\n// Support: Chrome 14-35+\n// Always assume duplicates if they aren't passed to the comparison function\nsupport.detectDuplicates = !!hasDuplicate;\n\n// Initialize against the default document\nsetDocument();\n\n// Support: Webkit<537.32 - Safari 6.0.3/Chrome 25 (fixed in Chrome 27)\n// Detached nodes confoundingly follow *each other*\nsupport.sortDetached = assert( function( el ) {\n\n\t// Should return 1, but returns 4 (following)\n\treturn el.compareDocumentPosition( document.createElement( \"fieldset\" ) ) & 1;\n} );\n\n// Support: IE<8\n// Prevent attribute/property \"interpolation\"\n// https://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx\nif ( !assert( function( el ) {\n\tel.innerHTML = \"<a href='#'></a>\";\n\treturn el.firstChild.getAttribute( \"href\" ) === \"#\";\n} ) ) {\n\taddHandle( \"type|href|height|width\", function( elem, name, isXML ) {\n\t\tif ( !isXML ) {\n\t\t\treturn elem.getAttribute( name, name.toLowerCase() === \"type\" ? 1 : 2 );\n\t\t}\n\t} );\n}\n\n// Support: IE<9\n// Use defaultValue in place of getAttribute(\"value\")\nif ( !support.attributes || !assert( function( el ) {\n\tel.innerHTML = \"<input/>\";\n\tel.firstChild.setAttribute( \"value\", \"\" );\n\treturn el.firstChild.getAttribute( \"value\" ) === \"\";\n} ) ) {\n\taddHandle( \"value\", function( elem, _name, isXML ) {\n\t\tif ( !isXML && elem.nodeName.toLowerCase() === \"input\" ) {\n\t\t\treturn elem.defaultValue;\n\t\t}\n\t} );\n}\n\n// Support: IE<9\n// Use getAttributeNode to fetch booleans when getAttribute lies\nif ( !assert( function( el ) {\n\treturn el.getAttribute( \"disabled\" ) == null;\n} ) ) {\n\taddHandle( booleans, function( elem, name, isXML ) {\n\t\tvar val;\n\t\tif ( !isXML ) {\n\t\t\treturn elem[ name ] === true ? name.toLowerCase() :\n\t\t\t\t( val = elem.getAttributeNode( name ) ) && val.specified ?\n\t\t\t\t\tval.value :\n\t\t\t\t\tnull;\n\t\t}\n\t} );\n}\n\nreturn Sizzle;\n\n} )( window );\n\n\n\njQuery.find = Sizzle;\njQuery.expr = Sizzle.selectors;\n\n// Deprecated\njQuery.expr[ \":\" ] = jQuery.expr.pseudos;\njQuery.uniqueSort = jQuery.unique = Sizzle.uniqueSort;\njQuery.text = Sizzle.getText;\njQuery.isXMLDoc = Sizzle.isXML;\njQuery.contains = Sizzle.contains;\njQuery.escapeSelector = Sizzle.escape;\n\n\n\n\nvar dir = function( elem, dir, until ) {\n\tvar matched = [],\n\t\ttruncate = until !== undefined;\n\n\twhile ( ( elem = elem[ dir ] ) && elem.nodeType !== 9 ) {\n\t\tif ( elem.nodeType === 1 ) {\n\t\t\tif ( truncate && jQuery( elem ).is( until ) ) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tmatched.push( elem );\n\t\t}\n\t}\n\treturn matched;\n};\n\n\nvar siblings = function( n, elem ) {\n\tvar matched = [];\n\n\tfor ( ; n; n = n.nextSibling ) {\n\t\tif ( n.nodeType === 1 && n !== elem ) {\n\t\t\tmatched.push( n );\n\t\t}\n\t}\n\n\treturn matched;\n};\n\n\nvar rneedsContext = jQuery.expr.match.needsContext;\n\n\n\nfunction nodeName( elem, name ) {\n\n  return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase();\n\n};\nvar rsingleTag = ( /^<([a-z][^\\/\\0>:\\x20\\t\\r\\n\\f]*)[\\x20\\t\\r\\n\\f]*\\/?>(?:<\\/\\1>|)$/i );\n\n\n\n// Implement the identical functionality for filter and not\nfunction winnow( elements, qualifier, not ) {\n\tif ( isFunction( qualifier ) ) {\n\t\treturn jQuery.grep( elements, function( elem, i ) {\n\t\t\treturn !!qualifier.call( elem, i, elem ) !== not;\n\t\t} );\n\t}\n\n\t// Single element\n\tif ( qualifier.nodeType ) {\n\t\treturn jQuery.grep( elements, function( elem ) {\n\t\t\treturn ( elem === qualifier ) !== not;\n\t\t} );\n\t}\n\n\t// Arraylike of elements (jQuery, arguments, Array)\n\tif ( typeof qualifier !== \"string\" ) {\n\t\treturn jQuery.grep( elements, function( elem ) {\n\t\t\treturn ( indexOf.call( qualifier, elem ) > -1 ) !== not;\n\t\t} );\n\t}\n\n\t// Filtered directly for both simple and complex selectors\n\treturn jQuery.filter( qualifier, elements, not );\n}\n\njQuery.filter = function( expr, elems, not ) {\n\tvar elem = elems[ 0 ];\n\n\tif ( not ) {\n\t\texpr = \":not(\" + expr + \")\";\n\t}\n\n\tif ( elems.length === 1 && elem.nodeType === 1 ) {\n\t\treturn jQuery.find.matchesSelector( elem, expr ) ? [ elem ] : [];\n\t}\n\n\treturn jQuery.find.matches( expr, jQuery.grep( elems, function( elem ) {\n\t\treturn elem.nodeType === 1;\n\t} ) );\n};\n\njQuery.fn.extend( {\n\tfind: function( selector ) {\n\t\tvar i, ret,\n\t\t\tlen = this.length,\n\t\t\tself = this;\n\n\t\tif ( typeof selector !== \"string\" ) {\n\t\t\treturn this.pushStack( jQuery( selector ).filter( function() {\n\t\t\t\tfor ( i = 0; i < len; i++ ) {\n\t\t\t\t\tif ( jQuery.contains( self[ i ], this ) ) {\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} ) );\n\t\t}\n\n\t\tret = this.pushStack( [] );\n\n\t\tfor ( i = 0; i < len; i++ ) {\n\t\t\tjQuery.find( selector, self[ i ], ret );\n\t\t}\n\n\t\treturn len > 1 ? jQuery.uniqueSort( ret ) : ret;\n\t},\n\tfilter: function( selector ) {\n\t\treturn this.pushStack( winnow( this, selector || [], false ) );\n\t},\n\tnot: function( selector ) {\n\t\treturn this.pushStack( winnow( this, selector || [], true ) );\n\t},\n\tis: function( selector ) {\n\t\treturn !!winnow(\n\t\t\tthis,\n\n\t\t\t// If this is a positional/relative selector, check membership in the returned set\n\t\t\t// so $(\"p:first\").is(\"p:last\") won't return true for a doc with two \"p\".\n\t\t\ttypeof selector === \"string\" && rneedsContext.test( selector ) ?\n\t\t\t\tjQuery( selector ) :\n\t\t\t\tselector || [],\n\t\t\tfalse\n\t\t).length;\n\t}\n} );\n\n\n// Initialize a jQuery object\n\n\n// A central reference to the root jQuery(document)\nvar rootjQuery,\n\n\t// A simple way to check for HTML strings\n\t// Prioritize #id over <tag> to avoid XSS via location.hash (#9521)\n\t// Strict HTML recognition (#11290: must start with <)\n\t// Shortcut simple #id case for speed\n\trquickExpr = /^(?:\\s*(<[\\w\\W]+>)[^>]*|#([\\w-]+))$/,\n\n\tinit = jQuery.fn.init = function( selector, context, root ) {\n\t\tvar match, elem;\n\n\t\t// HANDLE: $(\"\"), $(null), $(undefined), $(false)\n\t\tif ( !selector ) {\n\t\t\treturn this;\n\t\t}\n\n\t\t// Method init() accepts an alternate rootjQuery\n\t\t// so migrate can support jQuery.sub (gh-2101)\n\t\troot = root || rootjQuery;\n\n\t\t// Handle HTML strings\n\t\tif ( typeof selector === \"string\" ) {\n\t\t\tif ( selector[ 0 ] === \"<\" &&\n\t\t\t\tselector[ selector.length - 1 ] === \">\" &&\n\t\t\t\tselector.length >= 3 ) {\n\n\t\t\t\t// Assume that strings that start and end with <> are HTML and skip the regex check\n\t\t\t\tmatch = [ null, selector, null ];\n\n\t\t\t} else {\n\t\t\t\tmatch = rquickExpr.exec( selector );\n\t\t\t}\n\n\t\t\t// Match html or make sure no context is specified for #id\n\t\t\tif ( match && ( match[ 1 ] || !context ) ) {\n\n\t\t\t\t// HANDLE: $(html) -> $(array)\n\t\t\t\tif ( match[ 1 ] ) {\n\t\t\t\t\tcontext = context instanceof jQuery ? context[ 0 ] : context;\n\n\t\t\t\t\t// Option to run scripts is true for back-compat\n\t\t\t\t\t// Intentionally let the error be thrown if parseHTML is not present\n\t\t\t\t\tjQuery.merge( this, jQuery.parseHTML(\n\t\t\t\t\t\tmatch[ 1 ],\n\t\t\t\t\t\tcontext && context.nodeType ? context.ownerDocument || context : document,\n\t\t\t\t\t\ttrue\n\t\t\t\t\t) );\n\n\t\t\t\t\t// HANDLE: $(html, props)\n\t\t\t\t\tif ( rsingleTag.test( match[ 1 ] ) && jQuery.isPlainObject( context ) ) {\n\t\t\t\t\t\tfor ( match in context ) {\n\n\t\t\t\t\t\t\t// Properties of context are called as methods if possible\n\t\t\t\t\t\t\tif ( isFunction( this[ match ] ) ) {\n\t\t\t\t\t\t\t\tthis[ match ]( context[ match ] );\n\n\t\t\t\t\t\t\t// ...and otherwise set as attributes\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tthis.attr( match, context[ match ] );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\treturn this;\n\n\t\t\t\t// HANDLE: $(#id)\n\t\t\t\t} else {\n\t\t\t\t\telem = document.getElementById( match[ 2 ] );\n\n\t\t\t\t\tif ( elem ) {\n\n\t\t\t\t\t\t// Inject the element directly into the jQuery object\n\t\t\t\t\t\tthis[ 0 ] = elem;\n\t\t\t\t\t\tthis.length = 1;\n\t\t\t\t\t}\n\t\t\t\t\treturn this;\n\t\t\t\t}\n\n\t\t\t// HANDLE: $(expr, $(...))\n\t\t\t} else if ( !context || context.jquery ) {\n\t\t\t\treturn ( context || root ).find( selector );\n\n\t\t\t// HANDLE: $(expr, context)\n\t\t\t// (which is just equivalent to: $(context).find(expr)\n\t\t\t} else {\n\t\t\t\treturn this.constructor( context ).find( selector );\n\t\t\t}\n\n\t\t// HANDLE: $(DOMElement)\n\t\t} else if ( selector.nodeType ) {\n\t\t\tthis[ 0 ] = selector;\n\t\t\tthis.length = 1;\n\t\t\treturn this;\n\n\t\t// HANDLE: $(function)\n\t\t// Shortcut for document ready\n\t\t} else if ( isFunction( selector ) ) {\n\t\t\treturn root.ready !== undefined ?\n\t\t\t\troot.ready( selector ) :\n\n\t\t\t\t// Execute immediately if ready is not present\n\t\t\t\tselector( jQuery );\n\t\t}\n\n\t\treturn jQuery.makeArray( selector, this );\n\t};\n\n// Give the init function the jQuery prototype for later instantiation\ninit.prototype = jQuery.fn;\n\n// Initialize central reference\nrootjQuery = jQuery( document );\n\n\nvar rparentsprev = /^(?:parents|prev(?:Until|All))/,\n\n\t// Methods guaranteed to produce a unique set when starting from a unique set\n\tguaranteedUnique = {\n\t\tchildren: true,\n\t\tcontents: true,\n\t\tnext: true,\n\t\tprev: true\n\t};\n\njQuery.fn.extend( {\n\thas: function( target ) {\n\t\tvar targets = jQuery( target, this ),\n\t\t\tl = targets.length;\n\n\t\treturn this.filter( function() {\n\t\t\tvar i = 0;\n\t\t\tfor ( ; i < l; i++ ) {\n\t\t\t\tif ( jQuery.contains( this, targets[ i ] ) ) {\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t}\n\t\t} );\n\t},\n\n\tclosest: function( selectors, context ) {\n\t\tvar cur,\n\t\t\ti = 0,\n\t\t\tl = this.length,\n\t\t\tmatched = [],\n\t\t\ttargets = typeof selectors !== \"string\" && jQuery( selectors );\n\n\t\t// Positional selectors never match, since there's no _selection_ context\n\t\tif ( !rneedsContext.test( selectors ) ) {\n\t\t\tfor ( ; i < l; i++ ) {\n\t\t\t\tfor ( cur = this[ i ]; cur && cur !== context; cur = cur.parentNode ) {\n\n\t\t\t\t\t// Always skip document fragments\n\t\t\t\t\tif ( cur.nodeType < 11 && ( targets ?\n\t\t\t\t\t\ttargets.index( cur ) > -1 :\n\n\t\t\t\t\t\t// Don't pass non-elements to Sizzle\n\t\t\t\t\t\tcur.nodeType === 1 &&\n\t\t\t\t\t\t\tjQuery.find.matchesSelector( cur, selectors ) ) ) {\n\n\t\t\t\t\t\tmatched.push( cur );\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn this.pushStack( matched.length > 1 ? jQuery.uniqueSort( matched ) : matched );\n\t},\n\n\t// Determine the position of an element within the set\n\tindex: function( elem ) {\n\n\t\t// No argument, return index in parent\n\t\tif ( !elem ) {\n\t\t\treturn ( this[ 0 ] && this[ 0 ].parentNode ) ? this.first().prevAll().length : -1;\n\t\t}\n\n\t\t// Index in selector\n\t\tif ( typeof elem === \"string\" ) {\n\t\t\treturn indexOf.call( jQuery( elem ), this[ 0 ] );\n\t\t}\n\n\t\t// Locate the position of the desired element\n\t\treturn indexOf.call( this,\n\n\t\t\t// If it receives a jQuery object, the first element is used\n\t\t\telem.jquery ? elem[ 0 ] : elem\n\t\t);\n\t},\n\n\tadd: function( selector, context ) {\n\t\treturn this.pushStack(\n\t\t\tjQuery.uniqueSort(\n\t\t\t\tjQuery.merge( this.get(), jQuery( selector, context ) )\n\t\t\t)\n\t\t);\n\t},\n\n\taddBack: function( selector ) {\n\t\treturn this.add( selector == null ?\n\t\t\tthis.prevObject : this.prevObject.filter( selector )\n\t\t);\n\t}\n} );\n\nfunction sibling( cur, dir ) {\n\twhile ( ( cur = cur[ dir ] ) && cur.nodeType !== 1 ) {}\n\treturn cur;\n}\n\njQuery.each( {\n\tparent: function( elem ) {\n\t\tvar parent = elem.parentNode;\n\t\treturn parent && parent.nodeType !== 11 ? parent : null;\n\t},\n\tparents: function( elem ) {\n\t\treturn dir( elem, \"parentNode\" );\n\t},\n\tparentsUntil: function( elem, _i, until ) {\n\t\treturn dir( elem, \"parentNode\", until );\n\t},\n\tnext: function( elem ) {\n\t\treturn sibling( elem, \"nextSibling\" );\n\t},\n\tprev: function( elem ) {\n\t\treturn sibling( elem, \"previousSibling\" );\n\t},\n\tnextAll: function( elem ) {\n\t\treturn dir( elem, \"nextSibling\" );\n\t},\n\tprevAll: function( elem ) {\n\t\treturn dir( elem, \"previousSibling\" );\n\t},\n\tnextUntil: function( elem, _i, until ) {\n\t\treturn dir( elem, \"nextSibling\", until );\n\t},\n\tprevUntil: function( elem, _i, until ) {\n\t\treturn dir( elem, \"previousSibling\", until );\n\t},\n\tsiblings: function( elem ) {\n\t\treturn siblings( ( elem.parentNode || {} ).firstChild, elem );\n\t},\n\tchildren: function( elem ) {\n\t\treturn siblings( elem.firstChild );\n\t},\n\tcontents: function( elem ) {\n\t\tif ( elem.contentDocument != null &&\n\n\t\t\t// Support: IE 11+\n\t\t\t// <object> elements with no `data` attribute has an object\n\t\t\t// `contentDocument` with a `null` prototype.\n\t\t\tgetProto( elem.contentDocument ) ) {\n\n\t\t\treturn elem.contentDocument;\n\t\t}\n\n\t\t// Support: IE 9 - 11 only, iOS 7 only, Android Browser <=4.3 only\n\t\t// Treat the template element as a regular one in browsers that\n\t\t// don't support it.\n\t\tif ( nodeName( elem, \"template\" ) ) {\n\t\t\telem = elem.content || elem;\n\t\t}\n\n\t\treturn jQuery.merge( [], elem.childNodes );\n\t}\n}, function( name, fn ) {\n\tjQuery.fn[ name ] = function( until, selector ) {\n\t\tvar matched = jQuery.map( this, fn, until );\n\n\t\tif ( name.slice( -5 ) !== \"Until\" ) {\n\t\t\tselector = until;\n\t\t}\n\n\t\tif ( selector && typeof selector === \"string\" ) {\n\t\t\tmatched = jQuery.filter( selector, matched );\n\t\t}\n\n\t\tif ( this.length > 1 ) {\n\n\t\t\t// Remove duplicates\n\t\t\tif ( !guaranteedUnique[ name ] ) {\n\t\t\t\tjQuery.uniqueSort( matched );\n\t\t\t}\n\n\t\t\t// Reverse order for parents* and prev-derivatives\n\t\t\tif ( rparentsprev.test( name ) ) {\n\t\t\t\tmatched.reverse();\n\t\t\t}\n\t\t}\n\n\t\treturn this.pushStack( matched );\n\t};\n} );\nvar rnothtmlwhite = ( /[^\\x20\\t\\r\\n\\f]+/g );\n\n\n\n// Convert String-formatted options into Object-formatted ones\nfunction createOptions( options ) {\n\tvar object = {};\n\tjQuery.each( options.match( rnothtmlwhite ) || [], function( _, flag ) {\n\t\tobject[ flag ] = true;\n\t} );\n\treturn object;\n}\n\n/*\n * Create a callback list using the following parameters:\n *\n *\toptions: an optional list of space-separated options that will change how\n *\t\t\tthe callback list behaves or a more traditional option object\n *\n * By default a callback list will act like an event callback list and can be\n * \"fired\" multiple times.\n *\n * Possible options:\n *\n *\tonce:\t\t\twill ensure the callback list can only be fired once (like a Deferred)\n *\n *\tmemory:\t\t\twill keep track of previous values and will call any callback added\n *\t\t\t\t\tafter the list has been fired right away with the latest \"memorized\"\n *\t\t\t\t\tvalues (like a Deferred)\n *\n *\tunique:\t\t\twill ensure a callback can only be added once (no duplicate in the list)\n *\n *\tstopOnFalse:\tinterrupt callings when a callback returns false\n *\n */\njQuery.Callbacks = function( options ) {\n\n\t// Convert options from String-formatted to Object-formatted if needed\n\t// (we check in cache first)\n\toptions = typeof options === \"string\" ?\n\t\tcreateOptions( options ) :\n\t\tjQuery.extend( {}, options );\n\n\tvar // Flag to know if list is currently firing\n\t\tfiring,\n\n\t\t// Last fire value for non-forgettable lists\n\t\tmemory,\n\n\t\t// Flag to know if list was already fired\n\t\tfired,\n\n\t\t// Flag to prevent firing\n\t\tlocked,\n\n\t\t// Actual callback list\n\t\tlist = [],\n\n\t\t// Queue of execution data for repeatable lists\n\t\tqueue = [],\n\n\t\t// Index of currently firing callback (modified by add/remove as needed)\n\t\tfiringIndex = -1,\n\n\t\t// Fire callbacks\n\t\tfire = function() {\n\n\t\t\t// Enforce single-firing\n\t\t\tlocked = locked || options.once;\n\n\t\t\t// Execute callbacks for all pending executions,\n\t\t\t// respecting firingIndex overrides and runtime changes\n\t\t\tfired = firing = true;\n\t\t\tfor ( ; queue.length; firingIndex = -1 ) {\n\t\t\t\tmemory = queue.shift();\n\t\t\t\twhile ( ++firingIndex < list.length ) {\n\n\t\t\t\t\t// Run callback and check for early termination\n\t\t\t\t\tif ( list[ firingIndex ].apply( memory[ 0 ], memory[ 1 ] ) === false &&\n\t\t\t\t\t\toptions.stopOnFalse ) {\n\n\t\t\t\t\t\t// Jump to end and forget the data so .add doesn't re-fire\n\t\t\t\t\t\tfiringIndex = list.length;\n\t\t\t\t\t\tmemory = false;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Forget the data if we're done with it\n\t\t\tif ( !options.memory ) {\n\t\t\t\tmemory = false;\n\t\t\t}\n\n\t\t\tfiring = false;\n\n\t\t\t// Clean up if we're done firing for good\n\t\t\tif ( locked ) {\n\n\t\t\t\t// Keep an empty list if we have data for future add calls\n\t\t\t\tif ( memory ) {\n\t\t\t\t\tlist = [];\n\n\t\t\t\t// Otherwise, this object is spent\n\t\t\t\t} else {\n\t\t\t\t\tlist = \"\";\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\n\t\t// Actual Callbacks object\n\t\tself = {\n\n\t\t\t// Add a callback or a collection of callbacks to the list\n\t\t\tadd: function() {\n\t\t\t\tif ( list ) {\n\n\t\t\t\t\t// If we have memory from a past run, we should fire after adding\n\t\t\t\t\tif ( memory && !firing ) {\n\t\t\t\t\t\tfiringIndex = list.length - 1;\n\t\t\t\t\t\tqueue.push( memory );\n\t\t\t\t\t}\n\n\t\t\t\t\t( function add( args ) {\n\t\t\t\t\t\tjQuery.each( args, function( _, arg ) {\n\t\t\t\t\t\t\tif ( isFunction( arg ) ) {\n\t\t\t\t\t\t\t\tif ( !options.unique || !self.has( arg ) ) {\n\t\t\t\t\t\t\t\t\tlist.push( arg );\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t} else if ( arg && arg.length && toType( arg ) !== \"string\" ) {\n\n\t\t\t\t\t\t\t\t// Inspect recursively\n\t\t\t\t\t\t\t\tadd( arg );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} );\n\t\t\t\t\t} )( arguments );\n\n\t\t\t\t\tif ( memory && !firing ) {\n\t\t\t\t\t\tfire();\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn this;\n\t\t\t},\n\n\t\t\t// Remove a callback from the list\n\t\t\tremove: function() {\n\t\t\t\tjQuery.each( arguments, function( _, arg ) {\n\t\t\t\t\tvar index;\n\t\t\t\t\twhile ( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) {\n\t\t\t\t\t\tlist.splice( index, 1 );\n\n\t\t\t\t\t\t// Handle firing indexes\n\t\t\t\t\t\tif ( index <= firingIndex ) {\n\t\t\t\t\t\t\tfiringIndex--;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t} );\n\t\t\t\treturn this;\n\t\t\t},\n\n\t\t\t// Check if a given callback is in the list.\n\t\t\t// If no argument is given, return whether or not list has callbacks attached.\n\t\t\thas: function( fn ) {\n\t\t\t\treturn fn ?\n\t\t\t\t\tjQuery.inArray( fn, list ) > -1 :\n\t\t\t\t\tlist.length > 0;\n\t\t\t},\n\n\t\t\t// Remove all callbacks from the list\n\t\t\tempty: function() {\n\t\t\t\tif ( list ) {\n\t\t\t\t\tlist = [];\n\t\t\t\t}\n\t\t\t\treturn this;\n\t\t\t},\n\n\t\t\t// Disable .fire and .add\n\t\t\t// Abort any current/pending executions\n\t\t\t// Clear all callbacks and values\n\t\t\tdisable: function() {\n\t\t\t\tlocked = queue = [];\n\t\t\t\tlist = memory = \"\";\n\t\t\t\treturn this;\n\t\t\t},\n\t\t\tdisabled: function() {\n\t\t\t\treturn !list;\n\t\t\t},\n\n\t\t\t// Disable .fire\n\t\t\t// Also disable .add unless we have memory (since it would have no effect)\n\t\t\t// Abort any pending executions\n\t\t\tlock: function() {\n\t\t\t\tlocked = queue = [];\n\t\t\t\tif ( !memory && !firing ) {\n\t\t\t\t\tlist = memory = \"\";\n\t\t\t\t}\n\t\t\t\treturn this;\n\t\t\t},\n\t\t\tlocked: function() {\n\t\t\t\treturn !!locked;\n\t\t\t},\n\n\t\t\t// Call all callbacks with the given context and arguments\n\t\t\tfireWith: function( context, args ) {\n\t\t\t\tif ( !locked ) {\n\t\t\t\t\targs = args || [];\n\t\t\t\t\targs = [ context, args.slice ? args.slice() : args ];\n\t\t\t\t\tqueue.push( args );\n\t\t\t\t\tif ( !firing ) {\n\t\t\t\t\t\tfire();\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn this;\n\t\t\t},\n\n\t\t\t// Call all the callbacks with the given arguments\n\t\t\tfire: function() {\n\t\t\t\tself.fireWith( this, arguments );\n\t\t\t\treturn this;\n\t\t\t},\n\n\t\t\t// To know if the callbacks have already been called at least once\n\t\t\tfired: function() {\n\t\t\t\treturn !!fired;\n\t\t\t}\n\t\t};\n\n\treturn self;\n};\n\n\nfunction Identity( v ) {\n\treturn v;\n}\nfunction Thrower( ex ) {\n\tthrow ex;\n}\n\nfunction adoptValue( value, resolve, reject, noValue ) {\n\tvar method;\n\n\ttry {\n\n\t\t// Check for promise aspect first to privilege synchronous behavior\n\t\tif ( value && isFunction( ( method = value.promise ) ) ) {\n\t\t\tmethod.call( value ).done( resolve ).fail( reject );\n\n\t\t// Other thenables\n\t\t} else if ( value && isFunction( ( method = value.then ) ) ) {\n\t\t\tmethod.call( value, resolve, reject );\n\n\t\t// Other non-thenables\n\t\t} else {\n\n\t\t\t// Control `resolve` arguments by letting Array#slice cast boolean `noValue` to integer:\n\t\t\t// * false: [ value ].slice( 0 ) => resolve( value )\n\t\t\t// * true: [ value ].slice( 1 ) => resolve()\n\t\t\tresolve.apply( undefined, [ value ].slice( noValue ) );\n\t\t}\n\n\t// For Promises/A+, convert exceptions into rejections\n\t// Since jQuery.when doesn't unwrap thenables, we can skip the extra checks appearing in\n\t// Deferred#then to conditionally suppress rejection.\n\t} catch ( value ) {\n\n\t\t// Support: Android 4.0 only\n\t\t// Strict mode functions invoked without .call/.apply get global-object context\n\t\treject.apply( undefined, [ value ] );\n\t}\n}\n\njQuery.extend( {\n\n\tDeferred: function( func ) {\n\t\tvar tuples = [\n\n\t\t\t\t// action, add listener, callbacks,\n\t\t\t\t// ... .then handlers, argument index, [final state]\n\t\t\t\t[ \"notify\", \"progress\", jQuery.Callbacks( \"memory\" ),\n\t\t\t\t\tjQuery.Callbacks( \"memory\" ), 2 ],\n\t\t\t\t[ \"resolve\", \"done\", jQuery.Callbacks( \"once memory\" ),\n\t\t\t\t\tjQuery.Callbacks( \"once memory\" ), 0, \"resolved\" ],\n\t\t\t\t[ \"reject\", \"fail\", jQuery.Callbacks( \"once memory\" ),\n\t\t\t\t\tjQuery.Callbacks( \"once memory\" ), 1, \"rejected\" ]\n\t\t\t],\n\t\t\tstate = \"pending\",\n\t\t\tpromise = {\n\t\t\t\tstate: function() {\n\t\t\t\t\treturn state;\n\t\t\t\t},\n\t\t\t\talways: function() {\n\t\t\t\t\tdeferred.done( arguments ).fail( arguments );\n\t\t\t\t\treturn this;\n\t\t\t\t},\n\t\t\t\t\"catch\": function( fn ) {\n\t\t\t\t\treturn promise.then( null, fn );\n\t\t\t\t},\n\n\t\t\t\t// Keep pipe for back-compat\n\t\t\t\tpipe: function( /* fnDone, fnFail, fnProgress */ ) {\n\t\t\t\t\tvar fns = arguments;\n\n\t\t\t\t\treturn jQuery.Deferred( function( newDefer ) {\n\t\t\t\t\t\tjQuery.each( tuples, function( _i, tuple ) {\n\n\t\t\t\t\t\t\t// Map tuples (progress, done, fail) to arguments (done, fail, progress)\n\t\t\t\t\t\t\tvar fn = isFunction( fns[ tuple[ 4 ] ] ) && fns[ tuple[ 4 ] ];\n\n\t\t\t\t\t\t\t// deferred.progress(function() { bind to newDefer or newDefer.notify })\n\t\t\t\t\t\t\t// deferred.done(function() { bind to newDefer or newDefer.resolve })\n\t\t\t\t\t\t\t// deferred.fail(function() { bind to newDefer or newDefer.reject })\n\t\t\t\t\t\t\tdeferred[ tuple[ 1 ] ]( function() {\n\t\t\t\t\t\t\t\tvar returned = fn && fn.apply( this, arguments );\n\t\t\t\t\t\t\t\tif ( returned && isFunction( returned.promise ) ) {\n\t\t\t\t\t\t\t\t\treturned.promise()\n\t\t\t\t\t\t\t\t\t\t.progress( newDefer.notify )\n\t\t\t\t\t\t\t\t\t\t.done( newDefer.resolve )\n\t\t\t\t\t\t\t\t\t\t.fail( newDefer.reject );\n\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\tnewDefer[ tuple[ 0 ] + \"With\" ](\n\t\t\t\t\t\t\t\t\t\tthis,\n\t\t\t\t\t\t\t\t\t\tfn ? [ returned ] : arguments\n\t\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t} );\n\t\t\t\t\t\t} );\n\t\t\t\t\t\tfns = null;\n\t\t\t\t\t} ).promise();\n\t\t\t\t},\n\t\t\t\tthen: function( onFulfilled, onRejected, onProgress ) {\n\t\t\t\t\tvar maxDepth = 0;\n\t\t\t\t\tfunction resolve( depth, deferred, handler, special ) {\n\t\t\t\t\t\treturn function() {\n\t\t\t\t\t\t\tvar that = this,\n\t\t\t\t\t\t\t\targs = arguments,\n\t\t\t\t\t\t\t\tmightThrow = function() {\n\t\t\t\t\t\t\t\t\tvar returned, then;\n\n\t\t\t\t\t\t\t\t\t// Support: Promises/A+ section 2.3.3.3.3\n\t\t\t\t\t\t\t\t\t// https://promisesaplus.com/#point-59\n\t\t\t\t\t\t\t\t\t// Ignore double-resolution attempts\n\t\t\t\t\t\t\t\t\tif ( depth < maxDepth ) {\n\t\t\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\treturned = handler.apply( that, args );\n\n\t\t\t\t\t\t\t\t\t// Support: Promises/A+ section 2.3.1\n\t\t\t\t\t\t\t\t\t// https://promisesaplus.com/#point-48\n\t\t\t\t\t\t\t\t\tif ( returned === deferred.promise() ) {\n\t\t\t\t\t\t\t\t\t\tthrow new TypeError( \"Thenable self-resolution\" );\n\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\t// Support: Promises/A+ sections 2.3.3.1, 3.5\n\t\t\t\t\t\t\t\t\t// https://promisesaplus.com/#point-54\n\t\t\t\t\t\t\t\t\t// https://promisesaplus.com/#point-75\n\t\t\t\t\t\t\t\t\t// Retrieve `then` only once\n\t\t\t\t\t\t\t\t\tthen = returned &&\n\n\t\t\t\t\t\t\t\t\t\t// Support: Promises/A+ section 2.3.4\n\t\t\t\t\t\t\t\t\t\t// https://promisesaplus.com/#point-64\n\t\t\t\t\t\t\t\t\t\t// Only check objects and functions for thenability\n\t\t\t\t\t\t\t\t\t\t( typeof returned === \"object\" ||\n\t\t\t\t\t\t\t\t\t\t\ttypeof returned === \"function\" ) &&\n\t\t\t\t\t\t\t\t\t\treturned.then;\n\n\t\t\t\t\t\t\t\t\t// Handle a returned thenable\n\t\t\t\t\t\t\t\t\tif ( isFunction( then ) ) {\n\n\t\t\t\t\t\t\t\t\t\t// Special processors (notify) just wait for resolution\n\t\t\t\t\t\t\t\t\t\tif ( special ) {\n\t\t\t\t\t\t\t\t\t\t\tthen.call(\n\t\t\t\t\t\t\t\t\t\t\t\treturned,\n\t\t\t\t\t\t\t\t\t\t\t\tresolve( maxDepth, deferred, Identity, special ),\n\t\t\t\t\t\t\t\t\t\t\t\tresolve( maxDepth, deferred, Thrower, special )\n\t\t\t\t\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\t\t\t\t// Normal processors (resolve) also hook into progress\n\t\t\t\t\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t\t\t\t\t// ...and disregard older resolution values\n\t\t\t\t\t\t\t\t\t\t\tmaxDepth++;\n\n\t\t\t\t\t\t\t\t\t\t\tthen.call(\n\t\t\t\t\t\t\t\t\t\t\t\treturned,\n\t\t\t\t\t\t\t\t\t\t\t\tresolve( maxDepth, deferred, Identity, special ),\n\t\t\t\t\t\t\t\t\t\t\t\tresolve( maxDepth, deferred, Thrower, special ),\n\t\t\t\t\t\t\t\t\t\t\t\tresolve( maxDepth, deferred, Identity,\n\t\t\t\t\t\t\t\t\t\t\t\t\tdeferred.notifyWith )\n\t\t\t\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\t// Handle all other returned values\n\t\t\t\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t\t\t\t// Only substitute handlers pass on context\n\t\t\t\t\t\t\t\t\t\t// and multiple values (non-spec behavior)\n\t\t\t\t\t\t\t\t\t\tif ( handler !== Identity ) {\n\t\t\t\t\t\t\t\t\t\t\tthat = undefined;\n\t\t\t\t\t\t\t\t\t\t\targs = [ returned ];\n\t\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\t\t// Process the value(s)\n\t\t\t\t\t\t\t\t\t\t// Default process is resolve\n\t\t\t\t\t\t\t\t\t\t( special || deferred.resolveWith )( that, args );\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t},\n\n\t\t\t\t\t\t\t\t// Only normal processors (resolve) catch and reject exceptions\n\t\t\t\t\t\t\t\tprocess = special ?\n\t\t\t\t\t\t\t\t\tmightThrow :\n\t\t\t\t\t\t\t\t\tfunction() {\n\t\t\t\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\t\t\t\tmightThrow();\n\t\t\t\t\t\t\t\t\t\t} catch ( e ) {\n\n\t\t\t\t\t\t\t\t\t\t\tif ( jQuery.Deferred.exceptionHook ) {\n\t\t\t\t\t\t\t\t\t\t\t\tjQuery.Deferred.exceptionHook( e,\n\t\t\t\t\t\t\t\t\t\t\t\t\tprocess.stackTrace );\n\t\t\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\t\t\t// Support: Promises/A+ section 2.3.3.3.4.1\n\t\t\t\t\t\t\t\t\t\t\t// https://promisesaplus.com/#point-61\n\t\t\t\t\t\t\t\t\t\t\t// Ignore post-resolution exceptions\n\t\t\t\t\t\t\t\t\t\t\tif ( depth + 1 >= maxDepth ) {\n\n\t\t\t\t\t\t\t\t\t\t\t\t// Only substitute handlers pass on context\n\t\t\t\t\t\t\t\t\t\t\t\t// and multiple values (non-spec behavior)\n\t\t\t\t\t\t\t\t\t\t\t\tif ( handler !== Thrower ) {\n\t\t\t\t\t\t\t\t\t\t\t\t\tthat = undefined;\n\t\t\t\t\t\t\t\t\t\t\t\t\targs = [ e ];\n\t\t\t\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\t\t\t\tdeferred.rejectWith( that, args );\n\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t};\n\n\t\t\t\t\t\t\t// Support: Promises/A+ section 2.3.3.3.1\n\t\t\t\t\t\t\t// https://promisesaplus.com/#point-57\n\t\t\t\t\t\t\t// Re-resolve promises immediately to dodge false rejection from\n\t\t\t\t\t\t\t// subsequent errors\n\t\t\t\t\t\t\tif ( depth ) {\n\t\t\t\t\t\t\t\tprocess();\n\t\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t\t// Call an optional hook to record the stack, in case of exception\n\t\t\t\t\t\t\t\t// since it's otherwise lost when execution goes async\n\t\t\t\t\t\t\t\tif ( jQuery.Deferred.getStackHook ) {\n\t\t\t\t\t\t\t\t\tprocess.stackTrace = jQuery.Deferred.getStackHook();\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\twindow.setTimeout( process );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t};\n\t\t\t\t\t}\n\n\t\t\t\t\treturn jQuery.Deferred( function( newDefer ) {\n\n\t\t\t\t\t\t// progress_handlers.add( ... )\n\t\t\t\t\t\ttuples[ 0 ][ 3 ].add(\n\t\t\t\t\t\t\tresolve(\n\t\t\t\t\t\t\t\t0,\n\t\t\t\t\t\t\t\tnewDefer,\n\t\t\t\t\t\t\t\tisFunction( onProgress ) ?\n\t\t\t\t\t\t\t\t\tonProgress :\n\t\t\t\t\t\t\t\t\tIdentity,\n\t\t\t\t\t\t\t\tnewDefer.notifyWith\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t);\n\n\t\t\t\t\t\t// fulfilled_handlers.add( ... )\n\t\t\t\t\t\ttuples[ 1 ][ 3 ].add(\n\t\t\t\t\t\t\tresolve(\n\t\t\t\t\t\t\t\t0,\n\t\t\t\t\t\t\t\tnewDefer,\n\t\t\t\t\t\t\t\tisFunction( onFulfilled ) ?\n\t\t\t\t\t\t\t\t\tonFulfilled :\n\t\t\t\t\t\t\t\t\tIdentity\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t);\n\n\t\t\t\t\t\t// rejected_handlers.add( ... )\n\t\t\t\t\t\ttuples[ 2 ][ 3 ].add(\n\t\t\t\t\t\t\tresolve(\n\t\t\t\t\t\t\t\t0,\n\t\t\t\t\t\t\t\tnewDefer,\n\t\t\t\t\t\t\t\tisFunction( onRejected ) ?\n\t\t\t\t\t\t\t\t\tonRejected :\n\t\t\t\t\t\t\t\t\tThrower\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t);\n\t\t\t\t\t} ).promise();\n\t\t\t\t},\n\n\t\t\t\t// Get a promise for this deferred\n\t\t\t\t// If obj is provided, the promise aspect is added to the object\n\t\t\t\tpromise: function( obj ) {\n\t\t\t\t\treturn obj != null ? jQuery.extend( obj, promise ) : promise;\n\t\t\t\t}\n\t\t\t},\n\t\t\tdeferred = {};\n\n\t\t// Add list-specific methods\n\t\tjQuery.each( tuples, function( i, tuple ) {\n\t\t\tvar list = tuple[ 2 ],\n\t\t\t\tstateString = tuple[ 5 ];\n\n\t\t\t// promise.progress = list.add\n\t\t\t// promise.done = list.add\n\t\t\t// promise.fail = list.add\n\t\t\tpromise[ tuple[ 1 ] ] = list.add;\n\n\t\t\t// Handle state\n\t\t\tif ( stateString ) {\n\t\t\t\tlist.add(\n\t\t\t\t\tfunction() {\n\n\t\t\t\t\t\t// state = \"resolved\" (i.e., fulfilled)\n\t\t\t\t\t\t// state = \"rejected\"\n\t\t\t\t\t\tstate = stateString;\n\t\t\t\t\t},\n\n\t\t\t\t\t// rejected_callbacks.disable\n\t\t\t\t\t// fulfilled_callbacks.disable\n\t\t\t\t\ttuples[ 3 - i ][ 2 ].disable,\n\n\t\t\t\t\t// rejected_handlers.disable\n\t\t\t\t\t// fulfilled_handlers.disable\n\t\t\t\t\ttuples[ 3 - i ][ 3 ].disable,\n\n\t\t\t\t\t// progress_callbacks.lock\n\t\t\t\t\ttuples[ 0 ][ 2 ].lock,\n\n\t\t\t\t\t// progress_handlers.lock\n\t\t\t\t\ttuples[ 0 ][ 3 ].lock\n\t\t\t\t);\n\t\t\t}\n\n\t\t\t// progress_handlers.fire\n\t\t\t// fulfilled_handlers.fire\n\t\t\t// rejected_handlers.fire\n\t\t\tlist.add( tuple[ 3 ].fire );\n\n\t\t\t// deferred.notify = function() { deferred.notifyWith(...) }\n\t\t\t// deferred.resolve = function() { deferred.resolveWith(...) }\n\t\t\t// deferred.reject = function() { deferred.rejectWith(...) }\n\t\t\tdeferred[ tuple[ 0 ] ] = function() {\n\t\t\t\tdeferred[ tuple[ 0 ] + \"With\" ]( this === deferred ? undefined : this, arguments );\n\t\t\t\treturn this;\n\t\t\t};\n\n\t\t\t// deferred.notifyWith = list.fireWith\n\t\t\t// deferred.resolveWith = list.fireWith\n\t\t\t// deferred.rejectWith = list.fireWith\n\t\t\tdeferred[ tuple[ 0 ] + \"With\" ] = list.fireWith;\n\t\t} );\n\n\t\t// Make the deferred a promise\n\t\tpromise.promise( deferred );\n\n\t\t// Call given func if any\n\t\tif ( func ) {\n\t\t\tfunc.call( deferred, deferred );\n\t\t}\n\n\t\t// All done!\n\t\treturn deferred;\n\t},\n\n\t// Deferred helper\n\twhen: function( singleValue ) {\n\t\tvar\n\n\t\t\t// count of uncompleted subordinates\n\t\t\tremaining = arguments.length,\n\n\t\t\t// count of unprocessed arguments\n\t\t\ti = remaining,\n\n\t\t\t// subordinate fulfillment data\n\t\t\tresolveContexts = Array( i ),\n\t\t\tresolveValues = slice.call( arguments ),\n\n\t\t\t// the master Deferred\n\t\t\tmaster = jQuery.Deferred(),\n\n\t\t\t// subordinate callback factory\n\t\t\tupdateFunc = function( i ) {\n\t\t\t\treturn function( value ) {\n\t\t\t\t\tresolveContexts[ i ] = this;\n\t\t\t\t\tresolveValues[ i ] = arguments.length > 1 ? slice.call( arguments ) : value;\n\t\t\t\t\tif ( !( --remaining ) ) {\n\t\t\t\t\t\tmaster.resolveWith( resolveContexts, resolveValues );\n\t\t\t\t\t}\n\t\t\t\t};\n\t\t\t};\n\n\t\t// Single- and empty arguments are adopted like Promise.resolve\n\t\tif ( remaining <= 1 ) {\n\t\t\tadoptValue( singleValue, master.done( updateFunc( i ) ).resolve, master.reject,\n\t\t\t\t!remaining );\n\n\t\t\t// Use .then() to unwrap secondary thenables (cf. gh-3000)\n\t\t\tif ( master.state() === \"pending\" ||\n\t\t\t\tisFunction( resolveValues[ i ] && resolveValues[ i ].then ) ) {\n\n\t\t\t\treturn master.then();\n\t\t\t}\n\t\t}\n\n\t\t// Multiple arguments are aggregated like Promise.all array elements\n\t\twhile ( i-- ) {\n\t\t\tadoptValue( resolveValues[ i ], updateFunc( i ), master.reject );\n\t\t}\n\n\t\treturn master.promise();\n\t}\n} );\n\n\n// These usually indicate a programmer mistake during development,\n// warn about them ASAP rather than swallowing them by default.\nvar rerrorNames = /^(Eval|Internal|Range|Reference|Syntax|Type|URI)Error$/;\n\njQuery.Deferred.exceptionHook = function( error, stack ) {\n\n\t// Support: IE 8 - 9 only\n\t// Console exists when dev tools are open, which can happen at any time\n\tif ( window.console && window.console.warn && error && rerrorNames.test( error.name ) ) {\n\t\twindow.console.warn( \"jQuery.Deferred exception: \" + error.message, error.stack, stack );\n\t}\n};\n\n\n\n\njQuery.readyException = function( error ) {\n\twindow.setTimeout( function() {\n\t\tthrow error;\n\t} );\n};\n\n\n\n\n// The deferred used on DOM ready\nvar readyList = jQuery.Deferred();\n\njQuery.fn.ready = function( fn ) {\n\n\treadyList\n\t\t.then( fn )\n\n\t\t// Wrap jQuery.readyException in a function so that the lookup\n\t\t// happens at the time of error handling instead of callback\n\t\t// registration.\n\t\t.catch( function( error ) {\n\t\t\tjQuery.readyException( error );\n\t\t} );\n\n\treturn this;\n};\n\njQuery.extend( {\n\n\t// Is the DOM ready to be used? Set to true once it occurs.\n\tisReady: false,\n\n\t// A counter to track how many items to wait for before\n\t// the ready event fires. See #6781\n\treadyWait: 1,\n\n\t// Handle when the DOM is ready\n\tready: function( wait ) {\n\n\t\t// Abort if there are pending holds or we're already ready\n\t\tif ( wait === true ? --jQuery.readyWait : jQuery.isReady ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Remember that the DOM is ready\n\t\tjQuery.isReady = true;\n\n\t\t// If a normal DOM Ready event fired, decrement, and wait if need be\n\t\tif ( wait !== true && --jQuery.readyWait > 0 ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// If there are functions bound, to execute\n\t\treadyList.resolveWith( document, [ jQuery ] );\n\t}\n} );\n\njQuery.ready.then = readyList.then;\n\n// The ready event handler and self cleanup method\nfunction completed() {\n\tdocument.removeEventListener( \"DOMContentLoaded\", completed );\n\twindow.removeEventListener( \"load\", completed );\n\tjQuery.ready();\n}\n\n// Catch cases where $(document).ready() is called\n// after the browser event has already occurred.\n// Support: IE <=9 - 10 only\n// Older IE sometimes signals \"interactive\" too soon\nif ( document.readyState === \"complete\" ||\n\t( document.readyState !== \"loading\" && !document.documentElement.doScroll ) ) {\n\n\t// Handle it asynchronously to allow scripts the opportunity to delay ready\n\twindow.setTimeout( jQuery.ready );\n\n} else {\n\n\t// Use the handy event callback\n\tdocument.addEventListener( \"DOMContentLoaded\", completed );\n\n\t// A fallback to window.onload, that will always work\n\twindow.addEventListener( \"load\", completed );\n}\n\n\n\n\n// Multifunctional method to get and set values of a collection\n// The value/s can optionally be executed if it's a function\nvar access = function( elems, fn, key, value, chainable, emptyGet, raw ) {\n\tvar i = 0,\n\t\tlen = elems.length,\n\t\tbulk = key == null;\n\n\t// Sets many values\n\tif ( toType( key ) === \"object\" ) {\n\t\tchainable = true;\n\t\tfor ( i in key ) {\n\t\t\taccess( elems, fn, i, key[ i ], true, emptyGet, raw );\n\t\t}\n\n\t// Sets one value\n\t} else if ( value !== undefined ) {\n\t\tchainable = true;\n\n\t\tif ( !isFunction( value ) ) {\n\t\t\traw = true;\n\t\t}\n\n\t\tif ( bulk ) {\n\n\t\t\t// Bulk operations run against the entire set\n\t\t\tif ( raw ) {\n\t\t\t\tfn.call( elems, value );\n\t\t\t\tfn = null;\n\n\t\t\t// ...except when executing function values\n\t\t\t} else {\n\t\t\t\tbulk = fn;\n\t\t\t\tfn = function( elem, _key, value ) {\n\t\t\t\t\treturn bulk.call( jQuery( elem ), value );\n\t\t\t\t};\n\t\t\t}\n\t\t}\n\n\t\tif ( fn ) {\n\t\t\tfor ( ; i < len; i++ ) {\n\t\t\t\tfn(\n\t\t\t\t\telems[ i ], key, raw ?\n\t\t\t\t\tvalue :\n\t\t\t\t\tvalue.call( elems[ i ], i, fn( elems[ i ], key ) )\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t}\n\n\tif ( chainable ) {\n\t\treturn elems;\n\t}\n\n\t// Gets\n\tif ( bulk ) {\n\t\treturn fn.call( elems );\n\t}\n\n\treturn len ? fn( elems[ 0 ], key ) : emptyGet;\n};\n\n\n// Matches dashed string for camelizing\nvar rmsPrefix = /^-ms-/,\n\trdashAlpha = /-([a-z])/g;\n\n// Used by camelCase as callback to replace()\nfunction fcamelCase( _all, letter ) {\n\treturn letter.toUpperCase();\n}\n\n// Convert dashed to camelCase; used by the css and data modules\n// Support: IE <=9 - 11, Edge 12 - 15\n// Microsoft forgot to hump their vendor prefix (#9572)\nfunction camelCase( string ) {\n\treturn string.replace( rmsPrefix, \"ms-\" ).replace( rdashAlpha, fcamelCase );\n}\nvar acceptData = function( owner ) {\n\n\t// Accepts only:\n\t//  - Node\n\t//    - Node.ELEMENT_NODE\n\t//    - Node.DOCUMENT_NODE\n\t//  - Object\n\t//    - Any\n\treturn owner.nodeType === 1 || owner.nodeType === 9 || !( +owner.nodeType );\n};\n\n\n\n\nfunction Data() {\n\tthis.expando = jQuery.expando + Data.uid++;\n}\n\nData.uid = 1;\n\nData.prototype = {\n\n\tcache: function( owner ) {\n\n\t\t// Check if the owner object already has a cache\n\t\tvar value = owner[ this.expando ];\n\n\t\t// If not, create one\n\t\tif ( !value ) {\n\t\t\tvalue = {};\n\n\t\t\t// We can accept data for non-element nodes in modern browsers,\n\t\t\t// but we should not, see #8335.\n\t\t\t// Always return an empty object.\n\t\t\tif ( acceptData( owner ) ) {\n\n\t\t\t\t// If it is a node unlikely to be stringify-ed or looped over\n\t\t\t\t// use plain assignment\n\t\t\t\tif ( owner.nodeType ) {\n\t\t\t\t\towner[ this.expando ] = value;\n\n\t\t\t\t// Otherwise secure it in a non-enumerable property\n\t\t\t\t// configurable must be true to allow the property to be\n\t\t\t\t// deleted when data is removed\n\t\t\t\t} else {\n\t\t\t\t\tObject.defineProperty( owner, this.expando, {\n\t\t\t\t\t\tvalue: value,\n\t\t\t\t\t\tconfigurable: true\n\t\t\t\t\t} );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn value;\n\t},\n\tset: function( owner, data, value ) {\n\t\tvar prop,\n\t\t\tcache = this.cache( owner );\n\n\t\t// Handle: [ owner, key, value ] args\n\t\t// Always use camelCase key (gh-2257)\n\t\tif ( typeof data === \"string\" ) {\n\t\t\tcache[ camelCase( data ) ] = value;\n\n\t\t// Handle: [ owner, { properties } ] args\n\t\t} else {\n\n\t\t\t// Copy the properties one-by-one to the cache object\n\t\t\tfor ( prop in data ) {\n\t\t\t\tcache[ camelCase( prop ) ] = data[ prop ];\n\t\t\t}\n\t\t}\n\t\treturn cache;\n\t},\n\tget: function( owner, key ) {\n\t\treturn key === undefined ?\n\t\t\tthis.cache( owner ) :\n\n\t\t\t// Always use camelCase key (gh-2257)\n\t\t\towner[ this.expando ] && owner[ this.expando ][ camelCase( key ) ];\n\t},\n\taccess: function( owner, key, value ) {\n\n\t\t// In cases where either:\n\t\t//\n\t\t//   1. No key was specified\n\t\t//   2. A string key was specified, but no value provided\n\t\t//\n\t\t// Take the \"read\" path and allow the get method to determine\n\t\t// which value to return, respectively either:\n\t\t//\n\t\t//   1. The entire cache object\n\t\t//   2. The data stored at the key\n\t\t//\n\t\tif ( key === undefined ||\n\t\t\t\t( ( key && typeof key === \"string\" ) && value === undefined ) ) {\n\n\t\t\treturn this.get( owner, key );\n\t\t}\n\n\t\t// When the key is not a string, or both a key and value\n\t\t// are specified, set or extend (existing objects) with either:\n\t\t//\n\t\t//   1. An object of properties\n\t\t//   2. A key and value\n\t\t//\n\t\tthis.set( owner, key, value );\n\n\t\t// Since the \"set\" path can have two possible entry points\n\t\t// return the expected data based on which path was taken[*]\n\t\treturn value !== undefined ? value : key;\n\t},\n\tremove: function( owner, key ) {\n\t\tvar i,\n\t\t\tcache = owner[ this.expando ];\n\n\t\tif ( cache === undefined ) {\n\t\t\treturn;\n\t\t}\n\n\t\tif ( key !== undefined ) {\n\n\t\t\t// Support array or space separated string of keys\n\t\t\tif ( Array.isArray( key ) ) {\n\n\t\t\t\t// If key is an array of keys...\n\t\t\t\t// We always set camelCase keys, so remove that.\n\t\t\t\tkey = key.map( camelCase );\n\t\t\t} else {\n\t\t\t\tkey = camelCase( key );\n\n\t\t\t\t// If a key with the spaces exists, use it.\n\t\t\t\t// Otherwise, create an array by matching non-whitespace\n\t\t\t\tkey = key in cache ?\n\t\t\t\t\t[ key ] :\n\t\t\t\t\t( key.match( rnothtmlwhite ) || [] );\n\t\t\t}\n\n\t\t\ti = key.length;\n\n\t\t\twhile ( i-- ) {\n\t\t\t\tdelete cache[ key[ i ] ];\n\t\t\t}\n\t\t}\n\n\t\t// Remove the expando if there's no more data\n\t\tif ( key === undefined || jQuery.isEmptyObject( cache ) ) {\n\n\t\t\t// Support: Chrome <=35 - 45\n\t\t\t// Webkit & Blink performance suffers when deleting properties\n\t\t\t// from DOM nodes, so set to undefined instead\n\t\t\t// https://bugs.chromium.org/p/chromium/issues/detail?id=378607 (bug restricted)\n\t\t\tif ( owner.nodeType ) {\n\t\t\t\towner[ this.expando ] = undefined;\n\t\t\t} else {\n\t\t\t\tdelete owner[ this.expando ];\n\t\t\t}\n\t\t}\n\t},\n\thasData: function( owner ) {\n\t\tvar cache = owner[ this.expando ];\n\t\treturn cache !== undefined && !jQuery.isEmptyObject( cache );\n\t}\n};\nvar dataPriv = new Data();\n\nvar dataUser = new Data();\n\n\n\n//\tImplementation Summary\n//\n//\t1. Enforce API surface and semantic compatibility with 1.9.x branch\n//\t2. Improve the module's maintainability by reducing the storage\n//\t\tpaths to a single mechanism.\n//\t3. Use the same single mechanism to support \"private\" and \"user\" data.\n//\t4. _Never_ expose \"private\" data to user code (TODO: Drop _data, _removeData)\n//\t5. Avoid exposing implementation details on user objects (eg. expando properties)\n//\t6. Provide a clear path for implementation upgrade to WeakMap in 2014\n\nvar rbrace = /^(?:\\{[\\w\\W]*\\}|\\[[\\w\\W]*\\])$/,\n\trmultiDash = /[A-Z]/g;\n\nfunction getData( data ) {\n\tif ( data === \"true\" ) {\n\t\treturn true;\n\t}\n\n\tif ( data === \"false\" ) {\n\t\treturn false;\n\t}\n\n\tif ( data === \"null\" ) {\n\t\treturn null;\n\t}\n\n\t// Only convert to a number if it doesn't change the string\n\tif ( data === +data + \"\" ) {\n\t\treturn +data;\n\t}\n\n\tif ( rbrace.test( data ) ) {\n\t\treturn JSON.parse( data );\n\t}\n\n\treturn data;\n}\n\nfunction dataAttr( elem, key, data ) {\n\tvar name;\n\n\t// If nothing was found internally, try to fetch any\n\t// data from the HTML5 data-* attribute\n\tif ( data === undefined && elem.nodeType === 1 ) {\n\t\tname = \"data-\" + key.replace( rmultiDash, \"-$&\" ).toLowerCase();\n\t\tdata = elem.getAttribute( name );\n\n\t\tif ( typeof data === \"string\" ) {\n\t\t\ttry {\n\t\t\t\tdata = getData( data );\n\t\t\t} catch ( e ) {}\n\n\t\t\t// Make sure we set the data so it isn't changed later\n\t\t\tdataUser.set( elem, key, data );\n\t\t} else {\n\t\t\tdata = undefined;\n\t\t}\n\t}\n\treturn data;\n}\n\njQuery.extend( {\n\thasData: function( elem ) {\n\t\treturn dataUser.hasData( elem ) || dataPriv.hasData( elem );\n\t},\n\n\tdata: function( elem, name, data ) {\n\t\treturn dataUser.access( elem, name, data );\n\t},\n\n\tremoveData: function( elem, name ) {\n\t\tdataUser.remove( elem, name );\n\t},\n\n\t// TODO: Now that all calls to _data and _removeData have been replaced\n\t// with direct calls to dataPriv methods, these can be deprecated.\n\t_data: function( elem, name, data ) {\n\t\treturn dataPriv.access( elem, name, data );\n\t},\n\n\t_removeData: function( elem, name ) {\n\t\tdataPriv.remove( elem, name );\n\t}\n} );\n\njQuery.fn.extend( {\n\tdata: function( key, value ) {\n\t\tvar i, name, data,\n\t\t\telem = this[ 0 ],\n\t\t\tattrs = elem && elem.attributes;\n\n\t\t// Gets all values\n\t\tif ( key === undefined ) {\n\t\t\tif ( this.length ) {\n\t\t\t\tdata = dataUser.get( elem );\n\n\t\t\t\tif ( elem.nodeType === 1 && !dataPriv.get( elem, \"hasDataAttrs\" ) ) {\n\t\t\t\t\ti = attrs.length;\n\t\t\t\t\twhile ( i-- ) {\n\n\t\t\t\t\t\t// Support: IE 11 only\n\t\t\t\t\t\t// The attrs elements can be null (#14894)\n\t\t\t\t\t\tif ( attrs[ i ] ) {\n\t\t\t\t\t\t\tname = attrs[ i ].name;\n\t\t\t\t\t\t\tif ( name.indexOf( \"data-\" ) === 0 ) {\n\t\t\t\t\t\t\t\tname = camelCase( name.slice( 5 ) );\n\t\t\t\t\t\t\t\tdataAttr( elem, name, data[ name ] );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tdataPriv.set( elem, \"hasDataAttrs\", true );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn data;\n\t\t}\n\n\t\t// Sets multiple values\n\t\tif ( typeof key === \"object\" ) {\n\t\t\treturn this.each( function() {\n\t\t\t\tdataUser.set( this, key );\n\t\t\t} );\n\t\t}\n\n\t\treturn access( this, function( value ) {\n\t\t\tvar data;\n\n\t\t\t// The calling jQuery object (element matches) is not empty\n\t\t\t// (and therefore has an element appears at this[ 0 ]) and the\n\t\t\t// `value` parameter was not undefined. An empty jQuery object\n\t\t\t// will result in `undefined` for elem = this[ 0 ] which will\n\t\t\t// throw an exception if an attempt to read a data cache is made.\n\t\t\tif ( elem && value === undefined ) {\n\n\t\t\t\t// Attempt to get data from the cache\n\t\t\t\t// The key will always be camelCased in Data\n\t\t\t\tdata = dataUser.get( elem, key );\n\t\t\t\tif ( data !== undefined ) {\n\t\t\t\t\treturn data;\n\t\t\t\t}\n\n\t\t\t\t// Attempt to \"discover\" the data in\n\t\t\t\t// HTML5 custom data-* attrs\n\t\t\t\tdata = dataAttr( elem, key );\n\t\t\t\tif ( data !== undefined ) {\n\t\t\t\t\treturn data;\n\t\t\t\t}\n\n\t\t\t\t// We tried really hard, but the data doesn't exist.\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Set the data...\n\t\t\tthis.each( function() {\n\n\t\t\t\t// We always store the camelCased key\n\t\t\t\tdataUser.set( this, key, value );\n\t\t\t} );\n\t\t}, null, value, arguments.length > 1, null, true );\n\t},\n\n\tremoveData: function( key ) {\n\t\treturn this.each( function() {\n\t\t\tdataUser.remove( this, key );\n\t\t} );\n\t}\n} );\n\n\njQuery.extend( {\n\tqueue: function( elem, type, data ) {\n\t\tvar queue;\n\n\t\tif ( elem ) {\n\t\t\ttype = ( type || \"fx\" ) + \"queue\";\n\t\t\tqueue = dataPriv.get( elem, type );\n\n\t\t\t// Speed up dequeue by getting out quickly if this is just a lookup\n\t\t\tif ( data ) {\n\t\t\t\tif ( !queue || Array.isArray( data ) ) {\n\t\t\t\t\tqueue = dataPriv.access( elem, type, jQuery.makeArray( data ) );\n\t\t\t\t} else {\n\t\t\t\t\tqueue.push( data );\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn queue || [];\n\t\t}\n\t},\n\n\tdequeue: function( elem, type ) {\n\t\ttype = type || \"fx\";\n\n\t\tvar queue = jQuery.queue( elem, type ),\n\t\t\tstartLength = queue.length,\n\t\t\tfn = queue.shift(),\n\t\t\thooks = jQuery._queueHooks( elem, type ),\n\t\t\tnext = function() {\n\t\t\t\tjQuery.dequeue( elem, type );\n\t\t\t};\n\n\t\t// If the fx queue is dequeued, always remove the progress sentinel\n\t\tif ( fn === \"inprogress\" ) {\n\t\t\tfn = queue.shift();\n\t\t\tstartLength--;\n\t\t}\n\n\t\tif ( fn ) {\n\n\t\t\t// Add a progress sentinel to prevent the fx queue from being\n\t\t\t// automatically dequeued\n\t\t\tif ( type === \"fx\" ) {\n\t\t\t\tqueue.unshift( \"inprogress\" );\n\t\t\t}\n\n\t\t\t// Clear up the last queue stop function\n\t\t\tdelete hooks.stop;\n\t\t\tfn.call( elem, next, hooks );\n\t\t}\n\n\t\tif ( !startLength && hooks ) {\n\t\t\thooks.empty.fire();\n\t\t}\n\t},\n\n\t// Not public - generate a queueHooks object, or return the current one\n\t_queueHooks: function( elem, type ) {\n\t\tvar key = type + \"queueHooks\";\n\t\treturn dataPriv.get( elem, key ) || dataPriv.access( elem, key, {\n\t\t\tempty: jQuery.Callbacks( \"once memory\" ).add( function() {\n\t\t\t\tdataPriv.remove( elem, [ type + \"queue\", key ] );\n\t\t\t} )\n\t\t} );\n\t}\n} );\n\njQuery.fn.extend( {\n\tqueue: function( type, data ) {\n\t\tvar setter = 2;\n\n\t\tif ( typeof type !== \"string\" ) {\n\t\t\tdata = type;\n\t\t\ttype = \"fx\";\n\t\t\tsetter--;\n\t\t}\n\n\t\tif ( arguments.length < setter ) {\n\t\t\treturn jQuery.queue( this[ 0 ], type );\n\t\t}\n\n\t\treturn data === undefined ?\n\t\t\tthis :\n\t\t\tthis.each( function() {\n\t\t\t\tvar queue = jQuery.queue( this, type, data );\n\n\t\t\t\t// Ensure a hooks for this queue\n\t\t\t\tjQuery._queueHooks( this, type );\n\n\t\t\t\tif ( type === \"fx\" && queue[ 0 ] !== \"inprogress\" ) {\n\t\t\t\t\tjQuery.dequeue( this, type );\n\t\t\t\t}\n\t\t\t} );\n\t},\n\tdequeue: function( type ) {\n\t\treturn this.each( function() {\n\t\t\tjQuery.dequeue( this, type );\n\t\t} );\n\t},\n\tclearQueue: function( type ) {\n\t\treturn this.queue( type || \"fx\", [] );\n\t},\n\n\t// Get a promise resolved when queues of a certain type\n\t// are emptied (fx is the type by default)\n\tpromise: function( type, obj ) {\n\t\tvar tmp,\n\t\t\tcount = 1,\n\t\t\tdefer = jQuery.Deferred(),\n\t\t\telements = this,\n\t\t\ti = this.length,\n\t\t\tresolve = function() {\n\t\t\t\tif ( !( --count ) ) {\n\t\t\t\t\tdefer.resolveWith( elements, [ elements ] );\n\t\t\t\t}\n\t\t\t};\n\n\t\tif ( typeof type !== \"string\" ) {\n\t\t\tobj = type;\n\t\t\ttype = undefined;\n\t\t}\n\t\ttype = type || \"fx\";\n\n\t\twhile ( i-- ) {\n\t\t\ttmp = dataPriv.get( elements[ i ], type + \"queueHooks\" );\n\t\t\tif ( tmp && tmp.empty ) {\n\t\t\t\tcount++;\n\t\t\t\ttmp.empty.add( resolve );\n\t\t\t}\n\t\t}\n\t\tresolve();\n\t\treturn defer.promise( obj );\n\t}\n} );\nvar pnum = ( /[+-]?(?:\\d*\\.|)\\d+(?:[eE][+-]?\\d+|)/ ).source;\n\nvar rcssNum = new RegExp( \"^(?:([+-])=|)(\" + pnum + \")([a-z%]*)$\", \"i\" );\n\n\nvar cssExpand = [ \"Top\", \"Right\", \"Bottom\", \"Left\" ];\n\nvar documentElement = document.documentElement;\n\n\n\n\tvar isAttached = function( elem ) {\n\t\t\treturn jQuery.contains( elem.ownerDocument, elem );\n\t\t},\n\t\tcomposed = { composed: true };\n\n\t// Support: IE 9 - 11+, Edge 12 - 18+, iOS 10.0 - 10.2 only\n\t// Check attachment across shadow DOM boundaries when possible (gh-3504)\n\t// Support: iOS 10.0-10.2 only\n\t// Early iOS 10 versions support `attachShadow` but not `getRootNode`,\n\t// leading to errors. We need to check for `getRootNode`.\n\tif ( documentElement.getRootNode ) {\n\t\tisAttached = function( elem ) {\n\t\t\treturn jQuery.contains( elem.ownerDocument, elem ) ||\n\t\t\t\telem.getRootNode( composed ) === elem.ownerDocument;\n\t\t};\n\t}\nvar isHiddenWithinTree = function( elem, el ) {\n\n\t\t// isHiddenWithinTree might be called from jQuery#filter function;\n\t\t// in that case, element will be second argument\n\t\telem = el || elem;\n\n\t\t// Inline style trumps all\n\t\treturn elem.style.display === \"none\" ||\n\t\t\telem.style.display === \"\" &&\n\n\t\t\t// Otherwise, check computed style\n\t\t\t// Support: Firefox <=43 - 45\n\t\t\t// Disconnected elements can have computed display: none, so first confirm that elem is\n\t\t\t// in the document.\n\t\t\tisAttached( elem ) &&\n\n\t\t\tjQuery.css( elem, \"display\" ) === \"none\";\n\t};\n\n\n\nfunction adjustCSS( elem, prop, valueParts, tween ) {\n\tvar adjusted, scale,\n\t\tmaxIterations = 20,\n\t\tcurrentValue = tween ?\n\t\t\tfunction() {\n\t\t\t\treturn tween.cur();\n\t\t\t} :\n\t\t\tfunction() {\n\t\t\t\treturn jQuery.css( elem, prop, \"\" );\n\t\t\t},\n\t\tinitial = currentValue(),\n\t\tunit = valueParts && valueParts[ 3 ] || ( jQuery.cssNumber[ prop ] ? \"\" : \"px\" ),\n\n\t\t// Starting value computation is required for potential unit mismatches\n\t\tinitialInUnit = elem.nodeType &&\n\t\t\t( jQuery.cssNumber[ prop ] || unit !== \"px\" && +initial ) &&\n\t\t\trcssNum.exec( jQuery.css( elem, prop ) );\n\n\tif ( initialInUnit && initialInUnit[ 3 ] !== unit ) {\n\n\t\t// Support: Firefox <=54\n\t\t// Halve the iteration target value to prevent interference from CSS upper bounds (gh-2144)\n\t\tinitial = initial / 2;\n\n\t\t// Trust units reported by jQuery.css\n\t\tunit = unit || initialInUnit[ 3 ];\n\n\t\t// Iteratively approximate from a nonzero starting point\n\t\tinitialInUnit = +initial || 1;\n\n\t\twhile ( maxIterations-- ) {\n\n\t\t\t// Evaluate and update our best guess (doubling guesses that zero out).\n\t\t\t// Finish if the scale equals or crosses 1 (making the old*new product non-positive).\n\t\t\tjQuery.style( elem, prop, initialInUnit + unit );\n\t\t\tif ( ( 1 - scale ) * ( 1 - ( scale = currentValue() / initial || 0.5 ) ) <= 0 ) {\n\t\t\t\tmaxIterations = 0;\n\t\t\t}\n\t\t\tinitialInUnit = initialInUnit / scale;\n\n\t\t}\n\n\t\tinitialInUnit = initialInUnit * 2;\n\t\tjQuery.style( elem, prop, initialInUnit + unit );\n\n\t\t// Make sure we update the tween properties later on\n\t\tvalueParts = valueParts || [];\n\t}\n\n\tif ( valueParts ) {\n\t\tinitialInUnit = +initialInUnit || +initial || 0;\n\n\t\t// Apply relative offset (+=/-=) if specified\n\t\tadjusted = valueParts[ 1 ] ?\n\t\t\tinitialInUnit + ( valueParts[ 1 ] + 1 ) * valueParts[ 2 ] :\n\t\t\t+valueParts[ 2 ];\n\t\tif ( tween ) {\n\t\t\ttween.unit = unit;\n\t\t\ttween.start = initialInUnit;\n\t\t\ttween.end = adjusted;\n\t\t}\n\t}\n\treturn adjusted;\n}\n\n\nvar defaultDisplayMap = {};\n\nfunction getDefaultDisplay( elem ) {\n\tvar temp,\n\t\tdoc = elem.ownerDocument,\n\t\tnodeName = elem.nodeName,\n\t\tdisplay = defaultDisplayMap[ nodeName ];\n\n\tif ( display ) {\n\t\treturn display;\n\t}\n\n\ttemp = doc.body.appendChild( doc.createElement( nodeName ) );\n\tdisplay = jQuery.css( temp, \"display\" );\n\n\ttemp.parentNode.removeChild( temp );\n\n\tif ( display === \"none\" ) {\n\t\tdisplay = \"block\";\n\t}\n\tdefaultDisplayMap[ nodeName ] = display;\n\n\treturn display;\n}\n\nfunction showHide( elements, show ) {\n\tvar display, elem,\n\t\tvalues = [],\n\t\tindex = 0,\n\t\tlength = elements.length;\n\n\t// Determine new display value for elements that need to change\n\tfor ( ; index < length; index++ ) {\n\t\telem = elements[ index ];\n\t\tif ( !elem.style ) {\n\t\t\tcontinue;\n\t\t}\n\n\t\tdisplay = elem.style.display;\n\t\tif ( show ) {\n\n\t\t\t// Since we force visibility upon cascade-hidden elements, an immediate (and slow)\n\t\t\t// check is required in this first loop unless we have a nonempty display value (either\n\t\t\t// inline or about-to-be-restored)\n\t\t\tif ( display === \"none\" ) {\n\t\t\t\tvalues[ index ] = dataPriv.get( elem, \"display\" ) || null;\n\t\t\t\tif ( !values[ index ] ) {\n\t\t\t\t\telem.style.display = \"\";\n\t\t\t\t}\n\t\t\t}\n\t\t\tif ( elem.style.display === \"\" && isHiddenWithinTree( elem ) ) {\n\t\t\t\tvalues[ index ] = getDefaultDisplay( elem );\n\t\t\t}\n\t\t} else {\n\t\t\tif ( display !== \"none\" ) {\n\t\t\t\tvalues[ index ] = \"none\";\n\n\t\t\t\t// Remember what we're overwriting\n\t\t\t\tdataPriv.set( elem, \"display\", display );\n\t\t\t}\n\t\t}\n\t}\n\n\t// Set the display of the elements in a second loop to avoid constant reflow\n\tfor ( index = 0; index < length; index++ ) {\n\t\tif ( values[ index ] != null ) {\n\t\t\telements[ index ].style.display = values[ index ];\n\t\t}\n\t}\n\n\treturn elements;\n}\n\njQuery.fn.extend( {\n\tshow: function() {\n\t\treturn showHide( this, true );\n\t},\n\thide: function() {\n\t\treturn showHide( this );\n\t},\n\ttoggle: function( state ) {\n\t\tif ( typeof state === \"boolean\" ) {\n\t\t\treturn state ? this.show() : this.hide();\n\t\t}\n\n\t\treturn this.each( function() {\n\t\t\tif ( isHiddenWithinTree( this ) ) {\n\t\t\t\tjQuery( this ).show();\n\t\t\t} else {\n\t\t\t\tjQuery( this ).hide();\n\t\t\t}\n\t\t} );\n\t}\n} );\nvar rcheckableType = ( /^(?:checkbox|radio)$/i );\n\nvar rtagName = ( /<([a-z][^\\/\\0>\\x20\\t\\r\\n\\f]*)/i );\n\nvar rscriptType = ( /^$|^module$|\\/(?:java|ecma)script/i );\n\n\n\n( function() {\n\tvar fragment = document.createDocumentFragment(),\n\t\tdiv = fragment.appendChild( document.createElement( \"div\" ) ),\n\t\tinput = document.createElement( \"input\" );\n\n\t// Support: Android 4.0 - 4.3 only\n\t// Check state lost if the name is set (#11217)\n\t// Support: Windows Web Apps (WWA)\n\t// `name` and `type` must use .setAttribute for WWA (#14901)\n\tinput.setAttribute( \"type\", \"radio\" );\n\tinput.setAttribute( \"checked\", \"checked\" );\n\tinput.setAttribute( \"name\", \"t\" );\n\n\tdiv.appendChild( input );\n\n\t// Support: Android <=4.1 only\n\t// Older WebKit doesn't clone checked state correctly in fragments\n\tsupport.checkClone = div.cloneNode( true ).cloneNode( true ).lastChild.checked;\n\n\t// Support: IE <=11 only\n\t// Make sure textarea (and checkbox) defaultValue is properly cloned\n\tdiv.innerHTML = \"<textarea>x</textarea>\";\n\tsupport.noCloneChecked = !!div.cloneNode( true ).lastChild.defaultValue;\n\n\t// Support: IE <=9 only\n\t// IE <=9 replaces <option> tags with their contents when inserted outside of\n\t// the select element.\n\tdiv.innerHTML = \"<option></option>\";\n\tsupport.option = !!div.lastChild;\n} )();\n\n\n// We have to close these tags to support XHTML (#13200)\nvar wrapMap = {\n\n\t// XHTML parsers do not magically insert elements in the\n\t// same way that tag soup parsers do. So we cannot shorten\n\t// this by omitting <tbody> or other required elements.\n\tthead: [ 1, \"<table>\", \"</table>\" ],\n\tcol: [ 2, \"<table><colgroup>\", \"</colgroup></table>\" ],\n\ttr: [ 2, \"<table><tbody>\", \"</tbody></table>\" ],\n\ttd: [ 3, \"<table><tbody><tr>\", \"</tr></tbody></table>\" ],\n\n\t_default: [ 0, \"\", \"\" ]\n};\n\nwrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead;\nwrapMap.th = wrapMap.td;\n\n// Support: IE <=9 only\nif ( !support.option ) {\n\twrapMap.optgroup = wrapMap.option = [ 1, \"<select multiple='multiple'>\", \"</select>\" ];\n}\n\n\nfunction getAll( context, tag ) {\n\n\t// Support: IE <=9 - 11 only\n\t// Use typeof to avoid zero-argument method invocation on host objects (#15151)\n\tvar ret;\n\n\tif ( typeof context.getElementsByTagName !== \"undefined\" ) {\n\t\tret = context.getElementsByTagName( tag || \"*\" );\n\n\t} else if ( typeof context.querySelectorAll !== \"undefined\" ) {\n\t\tret = context.querySelectorAll( tag || \"*\" );\n\n\t} else {\n\t\tret = [];\n\t}\n\n\tif ( tag === undefined || tag && nodeName( context, tag ) ) {\n\t\treturn jQuery.merge( [ context ], ret );\n\t}\n\n\treturn ret;\n}\n\n\n// Mark scripts as having already been evaluated\nfunction setGlobalEval( elems, refElements ) {\n\tvar i = 0,\n\t\tl = elems.length;\n\n\tfor ( ; i < l; i++ ) {\n\t\tdataPriv.set(\n\t\t\telems[ i ],\n\t\t\t\"globalEval\",\n\t\t\t!refElements || dataPriv.get( refElements[ i ], \"globalEval\" )\n\t\t);\n\t}\n}\n\n\nvar rhtml = /<|&#?\\w+;/;\n\nfunction buildFragment( elems, context, scripts, selection, ignored ) {\n\tvar elem, tmp, tag, wrap, attached, j,\n\t\tfragment = context.createDocumentFragment(),\n\t\tnodes = [],\n\t\ti = 0,\n\t\tl = elems.length;\n\n\tfor ( ; i < l; i++ ) {\n\t\telem = elems[ i ];\n\n\t\tif ( elem || elem === 0 ) {\n\n\t\t\t// Add nodes directly\n\t\t\tif ( toType( elem ) === \"object\" ) {\n\n\t\t\t\t// Support: Android <=4.0 only, PhantomJS 1 only\n\t\t\t\t// push.apply(_, arraylike) throws on ancient WebKit\n\t\t\t\tjQuery.merge( nodes, elem.nodeType ? [ elem ] : elem );\n\n\t\t\t// Convert non-html into a text node\n\t\t\t} else if ( !rhtml.test( elem ) ) {\n\t\t\t\tnodes.push( context.createTextNode( elem ) );\n\n\t\t\t// Convert html into DOM nodes\n\t\t\t} else {\n\t\t\t\ttmp = tmp || fragment.appendChild( context.createElement( \"div\" ) );\n\n\t\t\t\t// Deserialize a standard representation\n\t\t\t\ttag = ( rtagName.exec( elem ) || [ \"\", \"\" ] )[ 1 ].toLowerCase();\n\t\t\t\twrap = wrapMap[ tag ] || wrapMap._default;\n\t\t\t\ttmp.innerHTML = wrap[ 1 ] + jQuery.htmlPrefilter( elem ) + wrap[ 2 ];\n\n\t\t\t\t// Descend through wrappers to the right content\n\t\t\t\tj = wrap[ 0 ];\n\t\t\t\twhile ( j-- ) {\n\t\t\t\t\ttmp = tmp.lastChild;\n\t\t\t\t}\n\n\t\t\t\t// Support: Android <=4.0 only, PhantomJS 1 only\n\t\t\t\t// push.apply(_, arraylike) throws on ancient WebKit\n\t\t\t\tjQuery.merge( nodes, tmp.childNodes );\n\n\t\t\t\t// Remember the top-level container\n\t\t\t\ttmp = fragment.firstChild;\n\n\t\t\t\t// Ensure the created nodes are orphaned (#12392)\n\t\t\t\ttmp.textContent = \"\";\n\t\t\t}\n\t\t}\n\t}\n\n\t// Remove wrapper from fragment\n\tfragment.textContent = \"\";\n\n\ti = 0;\n\twhile ( ( elem = nodes[ i++ ] ) ) {\n\n\t\t// Skip elements already in the context collection (trac-4087)\n\t\tif ( selection && jQuery.inArray( elem, selection ) > -1 ) {\n\t\t\tif ( ignored ) {\n\t\t\t\tignored.push( elem );\n\t\t\t}\n\t\t\tcontinue;\n\t\t}\n\n\t\tattached = isAttached( elem );\n\n\t\t// Append to fragment\n\t\ttmp = getAll( fragment.appendChild( elem ), \"script\" );\n\n\t\t// Preserve script evaluation history\n\t\tif ( attached ) {\n\t\t\tsetGlobalEval( tmp );\n\t\t}\n\n\t\t// Capture executables\n\t\tif ( scripts ) {\n\t\t\tj = 0;\n\t\t\twhile ( ( elem = tmp[ j++ ] ) ) {\n\t\t\t\tif ( rscriptType.test( elem.type || \"\" ) ) {\n\t\t\t\t\tscripts.push( elem );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn fragment;\n}\n\n\nvar\n\trkeyEvent = /^key/,\n\trmouseEvent = /^(?:mouse|pointer|contextmenu|drag|drop)|click/,\n\trtypenamespace = /^([^.]*)(?:\\.(.+)|)/;\n\nfunction returnTrue() {\n\treturn true;\n}\n\nfunction returnFalse() {\n\treturn false;\n}\n\n// Support: IE <=9 - 11+\n// focus() and blur() are asynchronous, except when they are no-op.\n// So expect focus to be synchronous when the element is already active,\n// and blur to be synchronous when the element is not already active.\n// (focus and blur are always synchronous in other supported browsers,\n// this just defines when we can count on it).\nfunction expectSync( elem, type ) {\n\treturn ( elem === safeActiveElement() ) === ( type === \"focus\" );\n}\n\n// Support: IE <=9 only\n// Accessing document.activeElement can throw unexpectedly\n// https://bugs.jquery.com/ticket/13393\nfunction safeActiveElement() {\n\ttry {\n\t\treturn document.activeElement;\n\t} catch ( err ) { }\n}\n\nfunction on( elem, types, selector, data, fn, one ) {\n\tvar origFn, type;\n\n\t// Types can be a map of types/handlers\n\tif ( typeof types === \"object\" ) {\n\n\t\t// ( types-Object, selector, data )\n\t\tif ( typeof selector !== \"string\" ) {\n\n\t\t\t// ( types-Object, data )\n\t\t\tdata = data || selector;\n\t\t\tselector = undefined;\n\t\t}\n\t\tfor ( type in types ) {\n\t\t\ton( elem, type, selector, data, types[ type ], one );\n\t\t}\n\t\treturn elem;\n\t}\n\n\tif ( data == null && fn == null ) {\n\n\t\t// ( types, fn )\n\t\tfn = selector;\n\t\tdata = selector = undefined;\n\t} else if ( fn == null ) {\n\t\tif ( typeof selector === \"string\" ) {\n\n\t\t\t// ( types, selector, fn )\n\t\t\tfn = data;\n\t\t\tdata = undefined;\n\t\t} else {\n\n\t\t\t// ( types, data, fn )\n\t\t\tfn = data;\n\t\t\tdata = selector;\n\t\t\tselector = undefined;\n\t\t}\n\t}\n\tif ( fn === false ) {\n\t\tfn = returnFalse;\n\t} else if ( !fn ) {\n\t\treturn elem;\n\t}\n\n\tif ( one === 1 ) {\n\t\torigFn = fn;\n\t\tfn = function( event ) {\n\n\t\t\t// Can use an empty set, since event contains the info\n\t\t\tjQuery().off( event );\n\t\t\treturn origFn.apply( this, arguments );\n\t\t};\n\n\t\t// Use same guid so caller can remove using origFn\n\t\tfn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ );\n\t}\n\treturn elem.each( function() {\n\t\tjQuery.event.add( this, types, fn, data, selector );\n\t} );\n}\n\n/*\n * Helper functions for managing events -- not part of the public interface.\n * Props to Dean Edwards' addEvent library for many of the ideas.\n */\njQuery.event = {\n\n\tglobal: {},\n\n\tadd: function( elem, types, handler, data, selector ) {\n\n\t\tvar handleObjIn, eventHandle, tmp,\n\t\t\tevents, t, handleObj,\n\t\t\tspecial, handlers, type, namespaces, origType,\n\t\t\telemData = dataPriv.get( elem );\n\n\t\t// Only attach events to objects that accept data\n\t\tif ( !acceptData( elem ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Caller can pass in an object of custom data in lieu of the handler\n\t\tif ( handler.handler ) {\n\t\t\thandleObjIn = handler;\n\t\t\thandler = handleObjIn.handler;\n\t\t\tselector = handleObjIn.selector;\n\t\t}\n\n\t\t// Ensure that invalid selectors throw exceptions at attach time\n\t\t// Evaluate against documentElement in case elem is a non-element node (e.g., document)\n\t\tif ( selector ) {\n\t\t\tjQuery.find.matchesSelector( documentElement, selector );\n\t\t}\n\n\t\t// Make sure that the handler has a unique ID, used to find/remove it later\n\t\tif ( !handler.guid ) {\n\t\t\thandler.guid = jQuery.guid++;\n\t\t}\n\n\t\t// Init the element's event structure and main handler, if this is the first\n\t\tif ( !( events = elemData.events ) ) {\n\t\t\tevents = elemData.events = Object.create( null );\n\t\t}\n\t\tif ( !( eventHandle = elemData.handle ) ) {\n\t\t\teventHandle = elemData.handle = function( e ) {\n\n\t\t\t\t// Discard the second event of a jQuery.event.trigger() and\n\t\t\t\t// when an event is called after a page has unloaded\n\t\t\t\treturn typeof jQuery !== \"undefined\" && jQuery.event.triggered !== e.type ?\n\t\t\t\t\tjQuery.event.dispatch.apply( elem, arguments ) : undefined;\n\t\t\t};\n\t\t}\n\n\t\t// Handle multiple events separated by a space\n\t\ttypes = ( types || \"\" ).match( rnothtmlwhite ) || [ \"\" ];\n\t\tt = types.length;\n\t\twhile ( t-- ) {\n\t\t\ttmp = rtypenamespace.exec( types[ t ] ) || [];\n\t\t\ttype = origType = tmp[ 1 ];\n\t\t\tnamespaces = ( tmp[ 2 ] || \"\" ).split( \".\" ).sort();\n\n\t\t\t// There *must* be a type, no attaching namespace-only handlers\n\t\t\tif ( !type ) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t// If event changes its type, use the special event handlers for the changed type\n\t\t\tspecial = jQuery.event.special[ type ] || {};\n\n\t\t\t// If selector defined, determine special event api type, otherwise given type\n\t\t\ttype = ( selector ? special.delegateType : special.bindType ) || type;\n\n\t\t\t// Update special based on newly reset type\n\t\t\tspecial = jQuery.event.special[ type ] || {};\n\n\t\t\t// handleObj is passed to all event handlers\n\t\t\thandleObj = jQuery.extend( {\n\t\t\t\ttype: type,\n\t\t\t\torigType: origType,\n\t\t\t\tdata: data,\n\t\t\t\thandler: handler,\n\t\t\t\tguid: handler.guid,\n\t\t\t\tselector: selector,\n\t\t\t\tneedsContext: selector && jQuery.expr.match.needsContext.test( selector ),\n\t\t\t\tnamespace: namespaces.join( \".\" )\n\t\t\t}, handleObjIn );\n\n\t\t\t// Init the event handler queue if we're the first\n\t\t\tif ( !( handlers = events[ type ] ) ) {\n\t\t\t\thandlers = events[ type ] = [];\n\t\t\t\thandlers.delegateCount = 0;\n\n\t\t\t\t// Only use addEventListener if the special events handler returns false\n\t\t\t\tif ( !special.setup ||\n\t\t\t\t\tspecial.setup.call( elem, data, namespaces, eventHandle ) === false ) {\n\n\t\t\t\t\tif ( elem.addEventListener ) {\n\t\t\t\t\t\telem.addEventListener( type, eventHandle );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif ( special.add ) {\n\t\t\t\tspecial.add.call( elem, handleObj );\n\n\t\t\t\tif ( !handleObj.handler.guid ) {\n\t\t\t\t\thandleObj.handler.guid = handler.guid;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Add to the element's handler list, delegates in front\n\t\t\tif ( selector ) {\n\t\t\t\thandlers.splice( handlers.delegateCount++, 0, handleObj );\n\t\t\t} else {\n\t\t\t\thandlers.push( handleObj );\n\t\t\t}\n\n\t\t\t// Keep track of which events have ever been used, for event optimization\n\t\t\tjQuery.event.global[ type ] = true;\n\t\t}\n\n\t},\n\n\t// Detach an event or set of events from an element\n\tremove: function( elem, types, handler, selector, mappedTypes ) {\n\n\t\tvar j, origCount, tmp,\n\t\t\tevents, t, handleObj,\n\t\t\tspecial, handlers, type, namespaces, origType,\n\t\t\telemData = dataPriv.hasData( elem ) && dataPriv.get( elem );\n\n\t\tif ( !elemData || !( events = elemData.events ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Once for each type.namespace in types; type may be omitted\n\t\ttypes = ( types || \"\" ).match( rnothtmlwhite ) || [ \"\" ];\n\t\tt = types.length;\n\t\twhile ( t-- ) {\n\t\t\ttmp = rtypenamespace.exec( types[ t ] ) || [];\n\t\t\ttype = origType = tmp[ 1 ];\n\t\t\tnamespaces = ( tmp[ 2 ] || \"\" ).split( \".\" ).sort();\n\n\t\t\t// Unbind all events (on this namespace, if provided) for the element\n\t\t\tif ( !type ) {\n\t\t\t\tfor ( type in events ) {\n\t\t\t\t\tjQuery.event.remove( elem, type + types[ t ], handler, selector, true );\n\t\t\t\t}\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tspecial = jQuery.event.special[ type ] || {};\n\t\t\ttype = ( selector ? special.delegateType : special.bindType ) || type;\n\t\t\thandlers = events[ type ] || [];\n\t\t\ttmp = tmp[ 2 ] &&\n\t\t\t\tnew RegExp( \"(^|\\\\.)\" + namespaces.join( \"\\\\.(?:.*\\\\.|)\" ) + \"(\\\\.|$)\" );\n\n\t\t\t// Remove matching events\n\t\t\torigCount = j = handlers.length;\n\t\t\twhile ( j-- ) {\n\t\t\t\thandleObj = handlers[ j ];\n\n\t\t\t\tif ( ( mappedTypes || origType === handleObj.origType ) &&\n\t\t\t\t\t( !handler || handler.guid === handleObj.guid ) &&\n\t\t\t\t\t( !tmp || tmp.test( handleObj.namespace ) ) &&\n\t\t\t\t\t( !selector || selector === handleObj.selector ||\n\t\t\t\t\t\tselector === \"**\" && handleObj.selector ) ) {\n\t\t\t\t\thandlers.splice( j, 1 );\n\n\t\t\t\t\tif ( handleObj.selector ) {\n\t\t\t\t\t\thandlers.delegateCount--;\n\t\t\t\t\t}\n\t\t\t\t\tif ( special.remove ) {\n\t\t\t\t\t\tspecial.remove.call( elem, handleObj );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Remove generic event handler if we removed something and no more handlers exist\n\t\t\t// (avoids potential for endless recursion during removal of special event handlers)\n\t\t\tif ( origCount && !handlers.length ) {\n\t\t\t\tif ( !special.teardown ||\n\t\t\t\t\tspecial.teardown.call( elem, namespaces, elemData.handle ) === false ) {\n\n\t\t\t\t\tjQuery.removeEvent( elem, type, elemData.handle );\n\t\t\t\t}\n\n\t\t\t\tdelete events[ type ];\n\t\t\t}\n\t\t}\n\n\t\t// Remove data and the expando if it's no longer used\n\t\tif ( jQuery.isEmptyObject( events ) ) {\n\t\t\tdataPriv.remove( elem, \"handle events\" );\n\t\t}\n\t},\n\n\tdispatch: function( nativeEvent ) {\n\n\t\tvar i, j, ret, matched, handleObj, handlerQueue,\n\t\t\targs = new Array( arguments.length ),\n\n\t\t\t// Make a writable jQuery.Event from the native event object\n\t\t\tevent = jQuery.event.fix( nativeEvent ),\n\n\t\t\thandlers = (\n\t\t\t\t\tdataPriv.get( this, \"events\" ) || Object.create( null )\n\t\t\t\t)[ event.type ] || [],\n\t\t\tspecial = jQuery.event.special[ event.type ] || {};\n\n\t\t// Use the fix-ed jQuery.Event rather than the (read-only) native event\n\t\targs[ 0 ] = event;\n\n\t\tfor ( i = 1; i < arguments.length; i++ ) {\n\t\t\targs[ i ] = arguments[ i ];\n\t\t}\n\n\t\tevent.delegateTarget = this;\n\n\t\t// Call the preDispatch hook for the mapped type, and let it bail if desired\n\t\tif ( special.preDispatch && special.preDispatch.call( this, event ) === false ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Determine handlers\n\t\thandlerQueue = jQuery.event.handlers.call( this, event, handlers );\n\n\t\t// Run delegates first; they may want to stop propagation beneath us\n\t\ti = 0;\n\t\twhile ( ( matched = handlerQueue[ i++ ] ) && !event.isPropagationStopped() ) {\n\t\t\tevent.currentTarget = matched.elem;\n\n\t\t\tj = 0;\n\t\t\twhile ( ( handleObj = matched.handlers[ j++ ] ) &&\n\t\t\t\t!event.isImmediatePropagationStopped() ) {\n\n\t\t\t\t// If the event is namespaced, then each handler is only invoked if it is\n\t\t\t\t// specially universal or its namespaces are a superset of the event's.\n\t\t\t\tif ( !event.rnamespace || handleObj.namespace === false ||\n\t\t\t\t\tevent.rnamespace.test( handleObj.namespace ) ) {\n\n\t\t\t\t\tevent.handleObj = handleObj;\n\t\t\t\t\tevent.data = handleObj.data;\n\n\t\t\t\t\tret = ( ( jQuery.event.special[ handleObj.origType ] || {} ).handle ||\n\t\t\t\t\t\thandleObj.handler ).apply( matched.elem, args );\n\n\t\t\t\t\tif ( ret !== undefined ) {\n\t\t\t\t\t\tif ( ( event.result = ret ) === false ) {\n\t\t\t\t\t\t\tevent.preventDefault();\n\t\t\t\t\t\t\tevent.stopPropagation();\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Call the postDispatch hook for the mapped type\n\t\tif ( special.postDispatch ) {\n\t\t\tspecial.postDispatch.call( this, event );\n\t\t}\n\n\t\treturn event.result;\n\t},\n\n\thandlers: function( event, handlers ) {\n\t\tvar i, handleObj, sel, matchedHandlers, matchedSelectors,\n\t\t\thandlerQueue = [],\n\t\t\tdelegateCount = handlers.delegateCount,\n\t\t\tcur = event.target;\n\n\t\t// Find delegate handlers\n\t\tif ( delegateCount &&\n\n\t\t\t// Support: IE <=9\n\t\t\t// Black-hole SVG <use> instance trees (trac-13180)\n\t\t\tcur.nodeType &&\n\n\t\t\t// Support: Firefox <=42\n\t\t\t// Suppress spec-violating clicks indicating a non-primary pointer button (trac-3861)\n\t\t\t// https://www.w3.org/TR/DOM-Level-3-Events/#event-type-click\n\t\t\t// Support: IE 11 only\n\t\t\t// ...but not arrow key \"clicks\" of radio inputs, which can have `button` -1 (gh-2343)\n\t\t\t!( event.type === \"click\" && event.button >= 1 ) ) {\n\n\t\t\tfor ( ; cur !== this; cur = cur.parentNode || this ) {\n\n\t\t\t\t// Don't check non-elements (#13208)\n\t\t\t\t// Don't process clicks on disabled elements (#6911, #8165, #11382, #11764)\n\t\t\t\tif ( cur.nodeType === 1 && !( event.type === \"click\" && cur.disabled === true ) ) {\n\t\t\t\t\tmatchedHandlers = [];\n\t\t\t\t\tmatchedSelectors = {};\n\t\t\t\t\tfor ( i = 0; i < delegateCount; i++ ) {\n\t\t\t\t\t\thandleObj = handlers[ i ];\n\n\t\t\t\t\t\t// Don't conflict with Object.prototype properties (#13203)\n\t\t\t\t\t\tsel = handleObj.selector + \" \";\n\n\t\t\t\t\t\tif ( matchedSelectors[ sel ] === undefined ) {\n\t\t\t\t\t\t\tmatchedSelectors[ sel ] = handleObj.needsContext ?\n\t\t\t\t\t\t\t\tjQuery( sel, this ).index( cur ) > -1 :\n\t\t\t\t\t\t\t\tjQuery.find( sel, this, null, [ cur ] ).length;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif ( matchedSelectors[ sel ] ) {\n\t\t\t\t\t\t\tmatchedHandlers.push( handleObj );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tif ( matchedHandlers.length ) {\n\t\t\t\t\t\thandlerQueue.push( { elem: cur, handlers: matchedHandlers } );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Add the remaining (directly-bound) handlers\n\t\tcur = this;\n\t\tif ( delegateCount < handlers.length ) {\n\t\t\thandlerQueue.push( { elem: cur, handlers: handlers.slice( delegateCount ) } );\n\t\t}\n\n\t\treturn handlerQueue;\n\t},\n\n\taddProp: function( name, hook ) {\n\t\tObject.defineProperty( jQuery.Event.prototype, name, {\n\t\t\tenumerable: true,\n\t\t\tconfigurable: true,\n\n\t\t\tget: isFunction( hook ) ?\n\t\t\t\tfunction() {\n\t\t\t\t\tif ( this.originalEvent ) {\n\t\t\t\t\t\t\treturn hook( this.originalEvent );\n\t\t\t\t\t}\n\t\t\t\t} :\n\t\t\t\tfunction() {\n\t\t\t\t\tif ( this.originalEvent ) {\n\t\t\t\t\t\t\treturn this.originalEvent[ name ];\n\t\t\t\t\t}\n\t\t\t\t},\n\n\t\t\tset: function( value ) {\n\t\t\t\tObject.defineProperty( this, name, {\n\t\t\t\t\tenumerable: true,\n\t\t\t\t\tconfigurable: true,\n\t\t\t\t\twritable: true,\n\t\t\t\t\tvalue: value\n\t\t\t\t} );\n\t\t\t}\n\t\t} );\n\t},\n\n\tfix: function( originalEvent ) {\n\t\treturn originalEvent[ jQuery.expando ] ?\n\t\t\toriginalEvent :\n\t\t\tnew jQuery.Event( originalEvent );\n\t},\n\n\tspecial: {\n\t\tload: {\n\n\t\t\t// Prevent triggered image.load events from bubbling to window.load\n\t\t\tnoBubble: true\n\t\t},\n\t\tclick: {\n\n\t\t\t// Utilize native event to ensure correct state for checkable inputs\n\t\t\tsetup: function( data ) {\n\n\t\t\t\t// For mutual compressibility with _default, replace `this` access with a local var.\n\t\t\t\t// `|| data` is dead code meant only to preserve the variable through minification.\n\t\t\t\tvar el = this || data;\n\n\t\t\t\t// Claim the first handler\n\t\t\t\tif ( rcheckableType.test( el.type ) &&\n\t\t\t\t\tel.click && nodeName( el, \"input\" ) ) {\n\n\t\t\t\t\t// dataPriv.set( el, \"click\", ... )\n\t\t\t\t\tleverageNative( el, \"click\", returnTrue );\n\t\t\t\t}\n\n\t\t\t\t// Return false to allow normal processing in the caller\n\t\t\t\treturn false;\n\t\t\t},\n\t\t\ttrigger: function( data ) {\n\n\t\t\t\t// For mutual compressibility with _default, replace `this` access with a local var.\n\t\t\t\t// `|| data` is dead code meant only to preserve the variable through minification.\n\t\t\t\tvar el = this || data;\n\n\t\t\t\t// Force setup before triggering a click\n\t\t\t\tif ( rcheckableType.test( el.type ) &&\n\t\t\t\t\tel.click && nodeName( el, \"input\" ) ) {\n\n\t\t\t\t\tleverageNative( el, \"click\" );\n\t\t\t\t}\n\n\t\t\t\t// Return non-false to allow normal event-path propagation\n\t\t\t\treturn true;\n\t\t\t},\n\n\t\t\t// For cross-browser consistency, suppress native .click() on links\n\t\t\t// Also prevent it if we're currently inside a leveraged native-event stack\n\t\t\t_default: function( event ) {\n\t\t\t\tvar target = event.target;\n\t\t\t\treturn rcheckableType.test( target.type ) &&\n\t\t\t\t\ttarget.click && nodeName( target, \"input\" ) &&\n\t\t\t\t\tdataPriv.get( target, \"click\" ) ||\n\t\t\t\t\tnodeName( target, \"a\" );\n\t\t\t}\n\t\t},\n\n\t\tbeforeunload: {\n\t\t\tpostDispatch: function( event ) {\n\n\t\t\t\t// Support: Firefox 20+\n\t\t\t\t// Firefox doesn't alert if the returnValue field is not set.\n\t\t\t\tif ( event.result !== undefined && event.originalEvent ) {\n\t\t\t\t\tevent.originalEvent.returnValue = event.result;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n};\n\n// Ensure the presence of an event listener that handles manually-triggered\n// synthetic events by interrupting progress until reinvoked in response to\n// *native* events that it fires directly, ensuring that state changes have\n// already occurred before other listeners are invoked.\nfunction leverageNative( el, type, expectSync ) {\n\n\t// Missing expectSync indicates a trigger call, which must force setup through jQuery.event.add\n\tif ( !expectSync ) {\n\t\tif ( dataPriv.get( el, type ) === undefined ) {\n\t\t\tjQuery.event.add( el, type, returnTrue );\n\t\t}\n\t\treturn;\n\t}\n\n\t// Register the controller as a special universal handler for all event namespaces\n\tdataPriv.set( el, type, false );\n\tjQuery.event.add( el, type, {\n\t\tnamespace: false,\n\t\thandler: function( event ) {\n\t\t\tvar notAsync, result,\n\t\t\t\tsaved = dataPriv.get( this, type );\n\n\t\t\tif ( ( event.isTrigger & 1 ) && this[ type ] ) {\n\n\t\t\t\t// Interrupt processing of the outer synthetic .trigger()ed event\n\t\t\t\t// Saved data should be false in such cases, but might be a leftover capture object\n\t\t\t\t// from an async native handler (gh-4350)\n\t\t\t\tif ( !saved.length ) {\n\n\t\t\t\t\t// Store arguments for use when handling the inner native event\n\t\t\t\t\t// There will always be at least one argument (an event object), so this array\n\t\t\t\t\t// will not be confused with a leftover capture object.\n\t\t\t\t\tsaved = slice.call( arguments );\n\t\t\t\t\tdataPriv.set( this, type, saved );\n\n\t\t\t\t\t// Trigger the native event and capture its result\n\t\t\t\t\t// Support: IE <=9 - 11+\n\t\t\t\t\t// focus() and blur() are asynchronous\n\t\t\t\t\tnotAsync = expectSync( this, type );\n\t\t\t\t\tthis[ type ]();\n\t\t\t\t\tresult = dataPriv.get( this, type );\n\t\t\t\t\tif ( saved !== result || notAsync ) {\n\t\t\t\t\t\tdataPriv.set( this, type, false );\n\t\t\t\t\t} else {\n\t\t\t\t\t\tresult = {};\n\t\t\t\t\t}\n\t\t\t\t\tif ( saved !== result ) {\n\n\t\t\t\t\t\t// Cancel the outer synthetic event\n\t\t\t\t\t\tevent.stopImmediatePropagation();\n\t\t\t\t\t\tevent.preventDefault();\n\t\t\t\t\t\treturn result.value;\n\t\t\t\t\t}\n\n\t\t\t\t// If this is an inner synthetic event for an event with a bubbling surrogate\n\t\t\t\t// (focus or blur), assume that the surrogate already propagated from triggering the\n\t\t\t\t// native event and prevent that from happening again here.\n\t\t\t\t// This technically gets the ordering wrong w.r.t. to `.trigger()` (in which the\n\t\t\t\t// bubbling surrogate propagates *after* the non-bubbling base), but that seems\n\t\t\t\t// less bad than duplication.\n\t\t\t\t} else if ( ( jQuery.event.special[ type ] || {} ).delegateType ) {\n\t\t\t\t\tevent.stopPropagation();\n\t\t\t\t}\n\n\t\t\t// If this is a native event triggered above, everything is now in order\n\t\t\t// Fire an inner synthetic event with the original arguments\n\t\t\t} else if ( saved.length ) {\n\n\t\t\t\t// ...and capture the result\n\t\t\t\tdataPriv.set( this, type, {\n\t\t\t\t\tvalue: jQuery.event.trigger(\n\n\t\t\t\t\t\t// Support: IE <=9 - 11+\n\t\t\t\t\t\t// Extend with the prototype to reset the above stopImmediatePropagation()\n\t\t\t\t\t\tjQuery.extend( saved[ 0 ], jQuery.Event.prototype ),\n\t\t\t\t\t\tsaved.slice( 1 ),\n\t\t\t\t\t\tthis\n\t\t\t\t\t)\n\t\t\t\t} );\n\n\t\t\t\t// Abort handling of the native event\n\t\t\t\tevent.stopImmediatePropagation();\n\t\t\t}\n\t\t}\n\t} );\n}\n\njQuery.removeEvent = function( elem, type, handle ) {\n\n\t// This \"if\" is needed for plain objects\n\tif ( elem.removeEventListener ) {\n\t\telem.removeEventListener( type, handle );\n\t}\n};\n\njQuery.Event = function( src, props ) {\n\n\t// Allow instantiation without the 'new' keyword\n\tif ( !( this instanceof jQuery.Event ) ) {\n\t\treturn new jQuery.Event( src, props );\n\t}\n\n\t// Event object\n\tif ( src && src.type ) {\n\t\tthis.originalEvent = src;\n\t\tthis.type = src.type;\n\n\t\t// Events bubbling up the document may have been marked as prevented\n\t\t// by a handler lower down the tree; reflect the correct value.\n\t\tthis.isDefaultPrevented = src.defaultPrevented ||\n\t\t\t\tsrc.defaultPrevented === undefined &&\n\n\t\t\t\t// Support: Android <=2.3 only\n\t\t\t\tsrc.returnValue === false ?\n\t\t\treturnTrue :\n\t\t\treturnFalse;\n\n\t\t// Create target properties\n\t\t// Support: Safari <=6 - 7 only\n\t\t// Target should not be a text node (#504, #13143)\n\t\tthis.target = ( src.target && src.target.nodeType === 3 ) ?\n\t\t\tsrc.target.parentNode :\n\t\t\tsrc.target;\n\n\t\tthis.currentTarget = src.currentTarget;\n\t\tthis.relatedTarget = src.relatedTarget;\n\n\t// Event type\n\t} else {\n\t\tthis.type = src;\n\t}\n\n\t// Put explicitly provided properties onto the event object\n\tif ( props ) {\n\t\tjQuery.extend( this, props );\n\t}\n\n\t// Create a timestamp if incoming event doesn't have one\n\tthis.timeStamp = src && src.timeStamp || Date.now();\n\n\t// Mark it as fixed\n\tthis[ jQuery.expando ] = true;\n};\n\n// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding\n// https://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html\njQuery.Event.prototype = {\n\tconstructor: jQuery.Event,\n\tisDefaultPrevented: returnFalse,\n\tisPropagationStopped: returnFalse,\n\tisImmediatePropagationStopped: returnFalse,\n\tisSimulated: false,\n\n\tpreventDefault: function() {\n\t\tvar e = this.originalEvent;\n\n\t\tthis.isDefaultPrevented = returnTrue;\n\n\t\tif ( e && !this.isSimulated ) {\n\t\t\te.preventDefault();\n\t\t}\n\t},\n\tstopPropagation: function() {\n\t\tvar e = this.originalEvent;\n\n\t\tthis.isPropagationStopped = returnTrue;\n\n\t\tif ( e && !this.isSimulated ) {\n\t\t\te.stopPropagation();\n\t\t}\n\t},\n\tstopImmediatePropagation: function() {\n\t\tvar e = this.originalEvent;\n\n\t\tthis.isImmediatePropagationStopped = returnTrue;\n\n\t\tif ( e && !this.isSimulated ) {\n\t\t\te.stopImmediatePropagation();\n\t\t}\n\n\t\tthis.stopPropagation();\n\t}\n};\n\n// Includes all common event props including KeyEvent and MouseEvent specific props\njQuery.each( {\n\taltKey: true,\n\tbubbles: true,\n\tcancelable: true,\n\tchangedTouches: true,\n\tctrlKey: true,\n\tdetail: true,\n\teventPhase: true,\n\tmetaKey: true,\n\tpageX: true,\n\tpageY: true,\n\tshiftKey: true,\n\tview: true,\n\t\"char\": true,\n\tcode: true,\n\tcharCode: true,\n\tkey: true,\n\tkeyCode: true,\n\tbutton: true,\n\tbuttons: true,\n\tclientX: true,\n\tclientY: true,\n\toffsetX: true,\n\toffsetY: true,\n\tpointerId: true,\n\tpointerType: true,\n\tscreenX: true,\n\tscreenY: true,\n\ttargetTouches: true,\n\ttoElement: true,\n\ttouches: true,\n\n\twhich: function( event ) {\n\t\tvar button = event.button;\n\n\t\t// Add which for key events\n\t\tif ( event.which == null && rkeyEvent.test( event.type ) ) {\n\t\t\treturn event.charCode != null ? event.charCode : event.keyCode;\n\t\t}\n\n\t\t// Add which for click: 1 === left; 2 === middle; 3 === right\n\t\tif ( !event.which && button !== undefined && rmouseEvent.test( event.type ) ) {\n\t\t\tif ( button & 1 ) {\n\t\t\t\treturn 1;\n\t\t\t}\n\n\t\t\tif ( button & 2 ) {\n\t\t\t\treturn 3;\n\t\t\t}\n\n\t\t\tif ( button & 4 ) {\n\t\t\t\treturn 2;\n\t\t\t}\n\n\t\t\treturn 0;\n\t\t}\n\n\t\treturn event.which;\n\t}\n}, jQuery.event.addProp );\n\njQuery.each( { focus: \"focusin\", blur: \"focusout\" }, function( type, delegateType ) {\n\tjQuery.event.special[ type ] = {\n\n\t\t// Utilize native event if possible so blur/focus sequence is correct\n\t\tsetup: function() {\n\n\t\t\t// Claim the first handler\n\t\t\t// dataPriv.set( this, \"focus\", ... )\n\t\t\t// dataPriv.set( this, \"blur\", ... )\n\t\t\tleverageNative( this, type, expectSync );\n\n\t\t\t// Return false to allow normal processing in the caller\n\t\t\treturn false;\n\t\t},\n\t\ttrigger: function() {\n\n\t\t\t// Force setup before trigger\n\t\t\tleverageNative( this, type );\n\n\t\t\t// Return non-false to allow normal event-path propagation\n\t\t\treturn true;\n\t\t},\n\n\t\tdelegateType: delegateType\n\t};\n} );\n\n// Create mouseenter/leave events using mouseover/out and event-time checks\n// so that event delegation works in jQuery.\n// Do the same for pointerenter/pointerleave and pointerover/pointerout\n//\n// Support: Safari 7 only\n// Safari sends mouseenter too often; see:\n// https://bugs.chromium.org/p/chromium/issues/detail?id=470258\n// for the description of the bug (it existed in older Chrome versions as well).\njQuery.each( {\n\tmouseenter: \"mouseover\",\n\tmouseleave: \"mouseout\",\n\tpointerenter: \"pointerover\",\n\tpointerleave: \"pointerout\"\n}, function( orig, fix ) {\n\tjQuery.event.special[ orig ] = {\n\t\tdelegateType: fix,\n\t\tbindType: fix,\n\n\t\thandle: function( event ) {\n\t\t\tvar ret,\n\t\t\t\ttarget = this,\n\t\t\t\trelated = event.relatedTarget,\n\t\t\t\thandleObj = event.handleObj;\n\n\t\t\t// For mouseenter/leave call the handler if related is outside the target.\n\t\t\t// NB: No relatedTarget if the mouse left/entered the browser window\n\t\t\tif ( !related || ( related !== target && !jQuery.contains( target, related ) ) ) {\n\t\t\t\tevent.type = handleObj.origType;\n\t\t\t\tret = handleObj.handler.apply( this, arguments );\n\t\t\t\tevent.type = fix;\n\t\t\t}\n\t\t\treturn ret;\n\t\t}\n\t};\n} );\n\njQuery.fn.extend( {\n\n\ton: function( types, selector, data, fn ) {\n\t\treturn on( this, types, selector, data, fn );\n\t},\n\tone: function( types, selector, data, fn ) {\n\t\treturn on( this, types, selector, data, fn, 1 );\n\t},\n\toff: function( types, selector, fn ) {\n\t\tvar handleObj, type;\n\t\tif ( types && types.preventDefault && types.handleObj ) {\n\n\t\t\t// ( event )  dispatched jQuery.Event\n\t\t\thandleObj = types.handleObj;\n\t\t\tjQuery( types.delegateTarget ).off(\n\t\t\t\thandleObj.namespace ?\n\t\t\t\t\thandleObj.origType + \".\" + handleObj.namespace :\n\t\t\t\t\thandleObj.origType,\n\t\t\t\thandleObj.selector,\n\t\t\t\thandleObj.handler\n\t\t\t);\n\t\t\treturn this;\n\t\t}\n\t\tif ( typeof types === \"object\" ) {\n\n\t\t\t// ( types-object [, selector] )\n\t\t\tfor ( type in types ) {\n\t\t\t\tthis.off( type, selector, types[ type ] );\n\t\t\t}\n\t\t\treturn this;\n\t\t}\n\t\tif ( selector === false || typeof selector === \"function\" ) {\n\n\t\t\t// ( types [, fn] )\n\t\t\tfn = selector;\n\t\t\tselector = undefined;\n\t\t}\n\t\tif ( fn === false ) {\n\t\t\tfn = returnFalse;\n\t\t}\n\t\treturn this.each( function() {\n\t\t\tjQuery.event.remove( this, types, fn, selector );\n\t\t} );\n\t}\n} );\n\n\nvar\n\n\t// Support: IE <=10 - 11, Edge 12 - 13 only\n\t// In IE/Edge using regex groups here causes severe slowdowns.\n\t// See https://connect.microsoft.com/IE/feedback/details/1736512/\n\trnoInnerhtml = /<script|<style|<link/i,\n\n\t// checked=\"checked\" or checked\n\trchecked = /checked\\s*(?:[^=]|=\\s*.checked.)/i,\n\trcleanScript = /^\\s*<!(?:\\[CDATA\\[|--)|(?:\\]\\]|--)>\\s*$/g;\n\n// Prefer a tbody over its parent table for containing new rows\nfunction manipulationTarget( elem, content ) {\n\tif ( nodeName( elem, \"table\" ) &&\n\t\tnodeName( content.nodeType !== 11 ? content : content.firstChild, \"tr\" ) ) {\n\n\t\treturn jQuery( elem ).children( \"tbody\" )[ 0 ] || elem;\n\t}\n\n\treturn elem;\n}\n\n// Replace/restore the type attribute of script elements for safe DOM manipulation\nfunction disableScript( elem ) {\n\telem.type = ( elem.getAttribute( \"type\" ) !== null ) + \"/\" + elem.type;\n\treturn elem;\n}\nfunction restoreScript( elem ) {\n\tif ( ( elem.type || \"\" ).slice( 0, 5 ) === \"true/\" ) {\n\t\telem.type = elem.type.slice( 5 );\n\t} else {\n\t\telem.removeAttribute( \"type\" );\n\t}\n\n\treturn elem;\n}\n\nfunction cloneCopyEvent( src, dest ) {\n\tvar i, l, type, pdataOld, udataOld, udataCur, events;\n\n\tif ( dest.nodeType !== 1 ) {\n\t\treturn;\n\t}\n\n\t// 1. Copy private data: events, handlers, etc.\n\tif ( dataPriv.hasData( src ) ) {\n\t\tpdataOld = dataPriv.get( src );\n\t\tevents = pdataOld.events;\n\n\t\tif ( events ) {\n\t\t\tdataPriv.remove( dest, \"handle events\" );\n\n\t\t\tfor ( type in events ) {\n\t\t\t\tfor ( i = 0, l = events[ type ].length; i < l; i++ ) {\n\t\t\t\t\tjQuery.event.add( dest, type, events[ type ][ i ] );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// 2. Copy user data\n\tif ( dataUser.hasData( src ) ) {\n\t\tudataOld = dataUser.access( src );\n\t\tudataCur = jQuery.extend( {}, udataOld );\n\n\t\tdataUser.set( dest, udataCur );\n\t}\n}\n\n// Fix IE bugs, see support tests\nfunction fixInput( src, dest ) {\n\tvar nodeName = dest.nodeName.toLowerCase();\n\n\t// Fails to persist the checked state of a cloned checkbox or radio button.\n\tif ( nodeName === \"input\" && rcheckableType.test( src.type ) ) {\n\t\tdest.checked = src.checked;\n\n\t// Fails to return the selected option to the default selected state when cloning options\n\t} else if ( nodeName === \"input\" || nodeName === \"textarea\" ) {\n\t\tdest.defaultValue = src.defaultValue;\n\t}\n}\n\nfunction domManip( collection, args, callback, ignored ) {\n\n\t// Flatten any nested arrays\n\targs = flat( args );\n\n\tvar fragment, first, scripts, hasScripts, node, doc,\n\t\ti = 0,\n\t\tl = collection.length,\n\t\tiNoClone = l - 1,\n\t\tvalue = args[ 0 ],\n\t\tvalueIsFunction = isFunction( value );\n\n\t// We can't cloneNode fragments that contain checked, in WebKit\n\tif ( valueIsFunction ||\n\t\t\t( l > 1 && typeof value === \"string\" &&\n\t\t\t\t!support.checkClone && rchecked.test( value ) ) ) {\n\t\treturn collection.each( function( index ) {\n\t\t\tvar self = collection.eq( index );\n\t\t\tif ( valueIsFunction ) {\n\t\t\t\targs[ 0 ] = value.call( this, index, self.html() );\n\t\t\t}\n\t\t\tdomManip( self, args, callback, ignored );\n\t\t} );\n\t}\n\n\tif ( l ) {\n\t\tfragment = buildFragment( args, collection[ 0 ].ownerDocument, false, collection, ignored );\n\t\tfirst = fragment.firstChild;\n\n\t\tif ( fragment.childNodes.length === 1 ) {\n\t\t\tfragment = first;\n\t\t}\n\n\t\t// Require either new content or an interest in ignored elements to invoke the callback\n\t\tif ( first || ignored ) {\n\t\t\tscripts = jQuery.map( getAll( fragment, \"script\" ), disableScript );\n\t\t\thasScripts = scripts.length;\n\n\t\t\t// Use the original fragment for the last item\n\t\t\t// instead of the first because it can end up\n\t\t\t// being emptied incorrectly in certain situations (#8070).\n\t\t\tfor ( ; i < l; i++ ) {\n\t\t\t\tnode = fragment;\n\n\t\t\t\tif ( i !== iNoClone ) {\n\t\t\t\t\tnode = jQuery.clone( node, true, true );\n\n\t\t\t\t\t// Keep references to cloned scripts for later restoration\n\t\t\t\t\tif ( hasScripts ) {\n\n\t\t\t\t\t\t// Support: Android <=4.0 only, PhantomJS 1 only\n\t\t\t\t\t\t// push.apply(_, arraylike) throws on ancient WebKit\n\t\t\t\t\t\tjQuery.merge( scripts, getAll( node, \"script\" ) );\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tcallback.call( collection[ i ], node, i );\n\t\t\t}\n\n\t\t\tif ( hasScripts ) {\n\t\t\t\tdoc = scripts[ scripts.length - 1 ].ownerDocument;\n\n\t\t\t\t// Reenable scripts\n\t\t\t\tjQuery.map( scripts, restoreScript );\n\n\t\t\t\t// Evaluate executable scripts on first document insertion\n\t\t\t\tfor ( i = 0; i < hasScripts; i++ ) {\n\t\t\t\t\tnode = scripts[ i ];\n\t\t\t\t\tif ( rscriptType.test( node.type || \"\" ) &&\n\t\t\t\t\t\t!dataPriv.access( node, \"globalEval\" ) &&\n\t\t\t\t\t\tjQuery.contains( doc, node ) ) {\n\n\t\t\t\t\t\tif ( node.src && ( node.type || \"\" ).toLowerCase()  !== \"module\" ) {\n\n\t\t\t\t\t\t\t// Optional AJAX dependency, but won't run scripts if not present\n\t\t\t\t\t\t\tif ( jQuery._evalUrl && !node.noModule ) {\n\t\t\t\t\t\t\t\tjQuery._evalUrl( node.src, {\n\t\t\t\t\t\t\t\t\tnonce: node.nonce || node.getAttribute( \"nonce\" )\n\t\t\t\t\t\t\t\t}, doc );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tDOMEval( node.textContent.replace( rcleanScript, \"\" ), node, doc );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn collection;\n}\n\nfunction remove( elem, selector, keepData ) {\n\tvar node,\n\t\tnodes = selector ? jQuery.filter( selector, elem ) : elem,\n\t\ti = 0;\n\n\tfor ( ; ( node = nodes[ i ] ) != null; i++ ) {\n\t\tif ( !keepData && node.nodeType === 1 ) {\n\t\t\tjQuery.cleanData( getAll( node ) );\n\t\t}\n\n\t\tif ( node.parentNode ) {\n\t\t\tif ( keepData && isAttached( node ) ) {\n\t\t\t\tsetGlobalEval( getAll( node, \"script\" ) );\n\t\t\t}\n\t\t\tnode.parentNode.removeChild( node );\n\t\t}\n\t}\n\n\treturn elem;\n}\n\njQuery.extend( {\n\thtmlPrefilter: function( html ) {\n\t\treturn html;\n\t},\n\n\tclone: function( elem, dataAndEvents, deepDataAndEvents ) {\n\t\tvar i, l, srcElements, destElements,\n\t\t\tclone = elem.cloneNode( true ),\n\t\t\tinPage = isAttached( elem );\n\n\t\t// Fix IE cloning issues\n\t\tif ( !support.noCloneChecked && ( elem.nodeType === 1 || elem.nodeType === 11 ) &&\n\t\t\t\t!jQuery.isXMLDoc( elem ) ) {\n\n\t\t\t// We eschew Sizzle here for performance reasons: https://jsperf.com/getall-vs-sizzle/2\n\t\t\tdestElements = getAll( clone );\n\t\t\tsrcElements = getAll( elem );\n\n\t\t\tfor ( i = 0, l = srcElements.length; i < l; i++ ) {\n\t\t\t\tfixInput( srcElements[ i ], destElements[ i ] );\n\t\t\t}\n\t\t}\n\n\t\t// Copy the events from the original to the clone\n\t\tif ( dataAndEvents ) {\n\t\t\tif ( deepDataAndEvents ) {\n\t\t\t\tsrcElements = srcElements || getAll( elem );\n\t\t\t\tdestElements = destElements || getAll( clone );\n\n\t\t\t\tfor ( i = 0, l = srcElements.length; i < l; i++ ) {\n\t\t\t\t\tcloneCopyEvent( srcElements[ i ], destElements[ i ] );\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tcloneCopyEvent( elem, clone );\n\t\t\t}\n\t\t}\n\n\t\t// Preserve script evaluation history\n\t\tdestElements = getAll( clone, \"script\" );\n\t\tif ( destElements.length > 0 ) {\n\t\t\tsetGlobalEval( destElements, !inPage && getAll( elem, \"script\" ) );\n\t\t}\n\n\t\t// Return the cloned set\n\t\treturn clone;\n\t},\n\n\tcleanData: function( elems ) {\n\t\tvar data, elem, type,\n\t\t\tspecial = jQuery.event.special,\n\t\t\ti = 0;\n\n\t\tfor ( ; ( elem = elems[ i ] ) !== undefined; i++ ) {\n\t\t\tif ( acceptData( elem ) ) {\n\t\t\t\tif ( ( data = elem[ dataPriv.expando ] ) ) {\n\t\t\t\t\tif ( data.events ) {\n\t\t\t\t\t\tfor ( type in data.events ) {\n\t\t\t\t\t\t\tif ( special[ type ] ) {\n\t\t\t\t\t\t\t\tjQuery.event.remove( elem, type );\n\n\t\t\t\t\t\t\t// This is a shortcut to avoid jQuery.event.remove's overhead\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tjQuery.removeEvent( elem, type, data.handle );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t// Support: Chrome <=35 - 45+\n\t\t\t\t\t// Assign undefined instead of using delete, see Data#remove\n\t\t\t\t\telem[ dataPriv.expando ] = undefined;\n\t\t\t\t}\n\t\t\t\tif ( elem[ dataUser.expando ] ) {\n\n\t\t\t\t\t// Support: Chrome <=35 - 45+\n\t\t\t\t\t// Assign undefined instead of using delete, see Data#remove\n\t\t\t\t\telem[ dataUser.expando ] = undefined;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n} );\n\njQuery.fn.extend( {\n\tdetach: function( selector ) {\n\t\treturn remove( this, selector, true );\n\t},\n\n\tremove: function( selector ) {\n\t\treturn remove( this, selector );\n\t},\n\n\ttext: function( value ) {\n\t\treturn access( this, function( value ) {\n\t\t\treturn value === undefined ?\n\t\t\t\tjQuery.text( this ) :\n\t\t\t\tthis.empty().each( function() {\n\t\t\t\t\tif ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {\n\t\t\t\t\t\tthis.textContent = value;\n\t\t\t\t\t}\n\t\t\t\t} );\n\t\t}, null, value, arguments.length );\n\t},\n\n\tappend: function() {\n\t\treturn domManip( this, arguments, function( elem ) {\n\t\t\tif ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {\n\t\t\t\tvar target = manipulationTarget( this, elem );\n\t\t\t\ttarget.appendChild( elem );\n\t\t\t}\n\t\t} );\n\t},\n\n\tprepend: function() {\n\t\treturn domManip( this, arguments, function( elem ) {\n\t\t\tif ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {\n\t\t\t\tvar target = manipulationTarget( this, elem );\n\t\t\t\ttarget.insertBefore( elem, target.firstChild );\n\t\t\t}\n\t\t} );\n\t},\n\n\tbefore: function() {\n\t\treturn domManip( this, arguments, function( elem ) {\n\t\t\tif ( this.parentNode ) {\n\t\t\t\tthis.parentNode.insertBefore( elem, this );\n\t\t\t}\n\t\t} );\n\t},\n\n\tafter: function() {\n\t\treturn domManip( this, arguments, function( elem ) {\n\t\t\tif ( this.parentNode ) {\n\t\t\t\tthis.parentNode.insertBefore( elem, this.nextSibling );\n\t\t\t}\n\t\t} );\n\t},\n\n\tempty: function() {\n\t\tvar elem,\n\t\t\ti = 0;\n\n\t\tfor ( ; ( elem = this[ i ] ) != null; i++ ) {\n\t\t\tif ( elem.nodeType === 1 ) {\n\n\t\t\t\t// Prevent memory leaks\n\t\t\t\tjQuery.cleanData( getAll( elem, false ) );\n\n\t\t\t\t// Remove any remaining nodes\n\t\t\t\telem.textContent = \"\";\n\t\t\t}\n\t\t}\n\n\t\treturn this;\n\t},\n\n\tclone: function( dataAndEvents, deepDataAndEvents ) {\n\t\tdataAndEvents = dataAndEvents == null ? false : dataAndEvents;\n\t\tdeepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents;\n\n\t\treturn this.map( function() {\n\t\t\treturn jQuery.clone( this, dataAndEvents, deepDataAndEvents );\n\t\t} );\n\t},\n\n\thtml: function( value ) {\n\t\treturn access( this, function( value ) {\n\t\t\tvar elem = this[ 0 ] || {},\n\t\t\t\ti = 0,\n\t\t\t\tl = this.length;\n\n\t\t\tif ( value === undefined && elem.nodeType === 1 ) {\n\t\t\t\treturn elem.innerHTML;\n\t\t\t}\n\n\t\t\t// See if we can take a shortcut and just use innerHTML\n\t\t\tif ( typeof value === \"string\" && !rnoInnerhtml.test( value ) &&\n\t\t\t\t!wrapMap[ ( rtagName.exec( value ) || [ \"\", \"\" ] )[ 1 ].toLowerCase() ] ) {\n\n\t\t\t\tvalue = jQuery.htmlPrefilter( value );\n\n\t\t\t\ttry {\n\t\t\t\t\tfor ( ; i < l; i++ ) {\n\t\t\t\t\t\telem = this[ i ] || {};\n\n\t\t\t\t\t\t// Remove element nodes and prevent memory leaks\n\t\t\t\t\t\tif ( elem.nodeType === 1 ) {\n\t\t\t\t\t\t\tjQuery.cleanData( getAll( elem, false ) );\n\t\t\t\t\t\t\telem.innerHTML = value;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\telem = 0;\n\n\t\t\t\t// If using innerHTML throws an exception, use the fallback method\n\t\t\t\t} catch ( e ) {}\n\t\t\t}\n\n\t\t\tif ( elem ) {\n\t\t\t\tthis.empty().append( value );\n\t\t\t}\n\t\t}, null, value, arguments.length );\n\t},\n\n\treplaceWith: function() {\n\t\tvar ignored = [];\n\n\t\t// Make the changes, replacing each non-ignored context element with the new content\n\t\treturn domManip( this, arguments, function( elem ) {\n\t\t\tvar parent = this.parentNode;\n\n\t\t\tif ( jQuery.inArray( this, ignored ) < 0 ) {\n\t\t\t\tjQuery.cleanData( getAll( this ) );\n\t\t\t\tif ( parent ) {\n\t\t\t\t\tparent.replaceChild( elem, this );\n\t\t\t\t}\n\t\t\t}\n\n\t\t// Force callback invocation\n\t\t}, ignored );\n\t}\n} );\n\njQuery.each( {\n\tappendTo: \"append\",\n\tprependTo: \"prepend\",\n\tinsertBefore: \"before\",\n\tinsertAfter: \"after\",\n\treplaceAll: \"replaceWith\"\n}, function( name, original ) {\n\tjQuery.fn[ name ] = function( selector ) {\n\t\tvar elems,\n\t\t\tret = [],\n\t\t\tinsert = jQuery( selector ),\n\t\t\tlast = insert.length - 1,\n\t\t\ti = 0;\n\n\t\tfor ( ; i <= last; i++ ) {\n\t\t\telems = i === last ? this : this.clone( true );\n\t\t\tjQuery( insert[ i ] )[ original ]( elems );\n\n\t\t\t// Support: Android <=4.0 only, PhantomJS 1 only\n\t\t\t// .get() because push.apply(_, arraylike) throws on ancient WebKit\n\t\t\tpush.apply( ret, elems.get() );\n\t\t}\n\n\t\treturn this.pushStack( ret );\n\t};\n} );\nvar rnumnonpx = new RegExp( \"^(\" + pnum + \")(?!px)[a-z%]+$\", \"i\" );\n\nvar getStyles = function( elem ) {\n\n\t\t// Support: IE <=11 only, Firefox <=30 (#15098, #14150)\n\t\t// IE throws on elements created in popups\n\t\t// FF meanwhile throws on frame elements through \"defaultView.getComputedStyle\"\n\t\tvar view = elem.ownerDocument.defaultView;\n\n\t\tif ( !view || !view.opener ) {\n\t\t\tview = window;\n\t\t}\n\n\t\treturn view.getComputedStyle( elem );\n\t};\n\nvar swap = function( elem, options, callback ) {\n\tvar ret, name,\n\t\told = {};\n\n\t// Remember the old values, and insert the new ones\n\tfor ( name in options ) {\n\t\told[ name ] = elem.style[ name ];\n\t\telem.style[ name ] = options[ name ];\n\t}\n\n\tret = callback.call( elem );\n\n\t// Revert the old values\n\tfor ( name in options ) {\n\t\telem.style[ name ] = old[ name ];\n\t}\n\n\treturn ret;\n};\n\n\nvar rboxStyle = new RegExp( cssExpand.join( \"|\" ), \"i\" );\n\n\n\n( function() {\n\n\t// Executing both pixelPosition & boxSizingReliable tests require only one layout\n\t// so they're executed at the same time to save the second computation.\n\tfunction computeStyleTests() {\n\n\t\t// This is a singleton, we need to execute it only once\n\t\tif ( !div ) {\n\t\t\treturn;\n\t\t}\n\n\t\tcontainer.style.cssText = \"position:absolute;left:-11111px;width:60px;\" +\n\t\t\t\"margin-top:1px;padding:0;border:0\";\n\t\tdiv.style.cssText =\n\t\t\t\"position:relative;display:block;box-sizing:border-box;overflow:scroll;\" +\n\t\t\t\"margin:auto;border:1px;padding:1px;\" +\n\t\t\t\"width:60%;top:1%\";\n\t\tdocumentElement.appendChild( container ).appendChild( div );\n\n\t\tvar divStyle = window.getComputedStyle( div );\n\t\tpixelPositionVal = divStyle.top !== \"1%\";\n\n\t\t// Support: Android 4.0 - 4.3 only, Firefox <=3 - 44\n\t\treliableMarginLeftVal = roundPixelMeasures( divStyle.marginLeft ) === 12;\n\n\t\t// Support: Android 4.0 - 4.3 only, Safari <=9.1 - 10.1, iOS <=7.0 - 9.3\n\t\t// Some styles come back with percentage values, even though they shouldn't\n\t\tdiv.style.right = \"60%\";\n\t\tpixelBoxStylesVal = roundPixelMeasures( divStyle.right ) === 36;\n\n\t\t// Support: IE 9 - 11 only\n\t\t// Detect misreporting of content dimensions for box-sizing:border-box elements\n\t\tboxSizingReliableVal = roundPixelMeasures( divStyle.width ) === 36;\n\n\t\t// Support: IE 9 only\n\t\t// Detect overflow:scroll screwiness (gh-3699)\n\t\t// Support: Chrome <=64\n\t\t// Don't get tricked when zoom affects offsetWidth (gh-4029)\n\t\tdiv.style.position = \"absolute\";\n\t\tscrollboxSizeVal = roundPixelMeasures( div.offsetWidth / 3 ) === 12;\n\n\t\tdocumentElement.removeChild( container );\n\n\t\t// Nullify the div so it wouldn't be stored in the memory and\n\t\t// it will also be a sign that checks already performed\n\t\tdiv = null;\n\t}\n\n\tfunction roundPixelMeasures( measure ) {\n\t\treturn Math.round( parseFloat( measure ) );\n\t}\n\n\tvar pixelPositionVal, boxSizingReliableVal, scrollboxSizeVal, pixelBoxStylesVal,\n\t\treliableTrDimensionsVal, reliableMarginLeftVal,\n\t\tcontainer = document.createElement( \"div\" ),\n\t\tdiv = document.createElement( \"div\" );\n\n\t// Finish early in limited (non-browser) environments\n\tif ( !div.style ) {\n\t\treturn;\n\t}\n\n\t// Support: IE <=9 - 11 only\n\t// Style of cloned element affects source element cloned (#8908)\n\tdiv.style.backgroundClip = \"content-box\";\n\tdiv.cloneNode( true ).style.backgroundClip = \"\";\n\tsupport.clearCloneStyle = div.style.backgroundClip === \"content-box\";\n\n\tjQuery.extend( support, {\n\t\tboxSizingReliable: function() {\n\t\t\tcomputeStyleTests();\n\t\t\treturn boxSizingReliableVal;\n\t\t},\n\t\tpixelBoxStyles: function() {\n\t\t\tcomputeStyleTests();\n\t\t\treturn pixelBoxStylesVal;\n\t\t},\n\t\tpixelPosition: function() {\n\t\t\tcomputeStyleTests();\n\t\t\treturn pixelPositionVal;\n\t\t},\n\t\treliableMarginLeft: function() {\n\t\t\tcomputeStyleTests();\n\t\t\treturn reliableMarginLeftVal;\n\t\t},\n\t\tscrollboxSize: function() {\n\t\t\tcomputeStyleTests();\n\t\t\treturn scrollboxSizeVal;\n\t\t},\n\n\t\t// Support: IE 9 - 11+, Edge 15 - 18+\n\t\t// IE/Edge misreport `getComputedStyle` of table rows with width/height\n\t\t// set in CSS while `offset*` properties report correct values.\n\t\t// Behavior in IE 9 is more subtle than in newer versions & it passes\n\t\t// some versions of this test; make sure not to make it pass there!\n\t\treliableTrDimensions: function() {\n\t\t\tvar table, tr, trChild, trStyle;\n\t\t\tif ( reliableTrDimensionsVal == null ) {\n\t\t\t\ttable = document.createElement( \"table\" );\n\t\t\t\ttr = document.createElement( \"tr\" );\n\t\t\t\ttrChild = document.createElement( \"div\" );\n\n\t\t\t\ttable.style.cssText = \"position:absolute;left:-11111px\";\n\t\t\t\ttr.style.height = \"1px\";\n\t\t\t\ttrChild.style.height = \"9px\";\n\n\t\t\t\tdocumentElement\n\t\t\t\t\t.appendChild( table )\n\t\t\t\t\t.appendChild( tr )\n\t\t\t\t\t.appendChild( trChild );\n\n\t\t\t\ttrStyle = window.getComputedStyle( tr );\n\t\t\t\treliableTrDimensionsVal = parseInt( trStyle.height ) > 3;\n\n\t\t\t\tdocumentElement.removeChild( table );\n\t\t\t}\n\t\t\treturn reliableTrDimensionsVal;\n\t\t}\n\t} );\n} )();\n\n\nfunction curCSS( elem, name, computed ) {\n\tvar width, minWidth, maxWidth, ret,\n\n\t\t// Support: Firefox 51+\n\t\t// Retrieving style before computed somehow\n\t\t// fixes an issue with getting wrong values\n\t\t// on detached elements\n\t\tstyle = elem.style;\n\n\tcomputed = computed || getStyles( elem );\n\n\t// getPropertyValue is needed for:\n\t//   .css('filter') (IE 9 only, #12537)\n\t//   .css('--customProperty) (#3144)\n\tif ( computed ) {\n\t\tret = computed.getPropertyValue( name ) || computed[ name ];\n\n\t\tif ( ret === \"\" && !isAttached( elem ) ) {\n\t\t\tret = jQuery.style( elem, name );\n\t\t}\n\n\t\t// A tribute to the \"awesome hack by Dean Edwards\"\n\t\t// Android Browser returns percentage for some values,\n\t\t// but width seems to be reliably pixels.\n\t\t// This is against the CSSOM draft spec:\n\t\t// https://drafts.csswg.org/cssom/#resolved-values\n\t\tif ( !support.pixelBoxStyles() && rnumnonpx.test( ret ) && rboxStyle.test( name ) ) {\n\n\t\t\t// Remember the original values\n\t\t\twidth = style.width;\n\t\t\tminWidth = style.minWidth;\n\t\t\tmaxWidth = style.maxWidth;\n\n\t\t\t// Put in the new values to get a computed value out\n\t\t\tstyle.minWidth = style.maxWidth = style.width = ret;\n\t\t\tret = computed.width;\n\n\t\t\t// Revert the changed values\n\t\t\tstyle.width = width;\n\t\t\tstyle.minWidth = minWidth;\n\t\t\tstyle.maxWidth = maxWidth;\n\t\t}\n\t}\n\n\treturn ret !== undefined ?\n\n\t\t// Support: IE <=9 - 11 only\n\t\t// IE returns zIndex value as an integer.\n\t\tret + \"\" :\n\t\tret;\n}\n\n\nfunction addGetHookIf( conditionFn, hookFn ) {\n\n\t// Define the hook, we'll check on the first run if it's really needed.\n\treturn {\n\t\tget: function() {\n\t\t\tif ( conditionFn() ) {\n\n\t\t\t\t// Hook not needed (or it's not possible to use it due\n\t\t\t\t// to missing dependency), remove it.\n\t\t\t\tdelete this.get;\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Hook needed; redefine it so that the support test is not executed again.\n\t\t\treturn ( this.get = hookFn ).apply( this, arguments );\n\t\t}\n\t};\n}\n\n\nvar cssPrefixes = [ \"Webkit\", \"Moz\", \"ms\" ],\n\temptyStyle = document.createElement( \"div\" ).style,\n\tvendorProps = {};\n\n// Return a vendor-prefixed property or undefined\nfunction vendorPropName( name ) {\n\n\t// Check for vendor prefixed names\n\tvar capName = name[ 0 ].toUpperCase() + name.slice( 1 ),\n\t\ti = cssPrefixes.length;\n\n\twhile ( i-- ) {\n\t\tname = cssPrefixes[ i ] + capName;\n\t\tif ( name in emptyStyle ) {\n\t\t\treturn name;\n\t\t}\n\t}\n}\n\n// Return a potentially-mapped jQuery.cssProps or vendor prefixed property\nfunction finalPropName( name ) {\n\tvar final = jQuery.cssProps[ name ] || vendorProps[ name ];\n\n\tif ( final ) {\n\t\treturn final;\n\t}\n\tif ( name in emptyStyle ) {\n\t\treturn name;\n\t}\n\treturn vendorProps[ name ] = vendorPropName( name ) || name;\n}\n\n\nvar\n\n\t// Swappable if display is none or starts with table\n\t// except \"table\", \"table-cell\", or \"table-caption\"\n\t// See here for display values: https://developer.mozilla.org/en-US/docs/CSS/display\n\trdisplayswap = /^(none|table(?!-c[ea]).+)/,\n\trcustomProp = /^--/,\n\tcssShow = { position: \"absolute\", visibility: \"hidden\", display: \"block\" },\n\tcssNormalTransform = {\n\t\tletterSpacing: \"0\",\n\t\tfontWeight: \"400\"\n\t};\n\nfunction setPositiveNumber( _elem, value, subtract ) {\n\n\t// Any relative (+/-) values have already been\n\t// normalized at this point\n\tvar matches = rcssNum.exec( value );\n\treturn matches ?\n\n\t\t// Guard against undefined \"subtract\", e.g., when used as in cssHooks\n\t\tMath.max( 0, matches[ 2 ] - ( subtract || 0 ) ) + ( matches[ 3 ] || \"px\" ) :\n\t\tvalue;\n}\n\nfunction boxModelAdjustment( elem, dimension, box, isBorderBox, styles, computedVal ) {\n\tvar i = dimension === \"width\" ? 1 : 0,\n\t\textra = 0,\n\t\tdelta = 0;\n\n\t// Adjustment may not be necessary\n\tif ( box === ( isBorderBox ? \"border\" : \"content\" ) ) {\n\t\treturn 0;\n\t}\n\n\tfor ( ; i < 4; i += 2 ) {\n\n\t\t// Both box models exclude margin\n\t\tif ( box === \"margin\" ) {\n\t\t\tdelta += jQuery.css( elem, box + cssExpand[ i ], true, styles );\n\t\t}\n\n\t\t// If we get here with a content-box, we're seeking \"padding\" or \"border\" or \"margin\"\n\t\tif ( !isBorderBox ) {\n\n\t\t\t// Add padding\n\t\t\tdelta += jQuery.css( elem, \"padding\" + cssExpand[ i ], true, styles );\n\n\t\t\t// For \"border\" or \"margin\", add border\n\t\t\tif ( box !== \"padding\" ) {\n\t\t\t\tdelta += jQuery.css( elem, \"border\" + cssExpand[ i ] + \"Width\", true, styles );\n\n\t\t\t// But still keep track of it otherwise\n\t\t\t} else {\n\t\t\t\textra += jQuery.css( elem, \"border\" + cssExpand[ i ] + \"Width\", true, styles );\n\t\t\t}\n\n\t\t// If we get here with a border-box (content + padding + border), we're seeking \"content\" or\n\t\t// \"padding\" or \"margin\"\n\t\t} else {\n\n\t\t\t// For \"content\", subtract padding\n\t\t\tif ( box === \"content\" ) {\n\t\t\t\tdelta -= jQuery.css( elem, \"padding\" + cssExpand[ i ], true, styles );\n\t\t\t}\n\n\t\t\t// For \"content\" or \"padding\", subtract border\n\t\t\tif ( box !== \"margin\" ) {\n\t\t\t\tdelta -= jQuery.css( elem, \"border\" + cssExpand[ i ] + \"Width\", true, styles );\n\t\t\t}\n\t\t}\n\t}\n\n\t// Account for positive content-box scroll gutter when requested by providing computedVal\n\tif ( !isBorderBox && computedVal >= 0 ) {\n\n\t\t// offsetWidth/offsetHeight is a rounded sum of content, padding, scroll gutter, and border\n\t\t// Assuming integer scroll gutter, subtract the rest and round down\n\t\tdelta += Math.max( 0, Math.ceil(\n\t\t\telem[ \"offset\" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 ) ] -\n\t\t\tcomputedVal -\n\t\t\tdelta -\n\t\t\textra -\n\t\t\t0.5\n\n\t\t// If offsetWidth/offsetHeight is unknown, then we can't determine content-box scroll gutter\n\t\t// Use an explicit zero to avoid NaN (gh-3964)\n\t\t) ) || 0;\n\t}\n\n\treturn delta;\n}\n\nfunction getWidthOrHeight( elem, dimension, extra ) {\n\n\t// Start with computed style\n\tvar styles = getStyles( elem ),\n\n\t\t// To avoid forcing a reflow, only fetch boxSizing if we need it (gh-4322).\n\t\t// Fake content-box until we know it's needed to know the true value.\n\t\tboxSizingNeeded = !support.boxSizingReliable() || extra,\n\t\tisBorderBox = boxSizingNeeded &&\n\t\t\tjQuery.css( elem, \"boxSizing\", false, styles ) === \"border-box\",\n\t\tvalueIsBorderBox = isBorderBox,\n\n\t\tval = curCSS( elem, dimension, styles ),\n\t\toffsetProp = \"offset\" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 );\n\n\t// Support: Firefox <=54\n\t// Return a confounding non-pixel value or feign ignorance, as appropriate.\n\tif ( rnumnonpx.test( val ) ) {\n\t\tif ( !extra ) {\n\t\t\treturn val;\n\t\t}\n\t\tval = \"auto\";\n\t}\n\n\n\t// Support: IE 9 - 11 only\n\t// Use offsetWidth/offsetHeight for when box sizing is unreliable.\n\t// In those cases, the computed value can be trusted to be border-box.\n\tif ( ( !support.boxSizingReliable() && isBorderBox ||\n\n\t\t// Support: IE 10 - 11+, Edge 15 - 18+\n\t\t// IE/Edge misreport `getComputedStyle` of table rows with width/height\n\t\t// set in CSS while `offset*` properties report correct values.\n\t\t// Interestingly, in some cases IE 9 doesn't suffer from this issue.\n\t\t!support.reliableTrDimensions() && nodeName( elem, \"tr\" ) ||\n\n\t\t// Fall back to offsetWidth/offsetHeight when value is \"auto\"\n\t\t// This happens for inline elements with no explicit setting (gh-3571)\n\t\tval === \"auto\" ||\n\n\t\t// Support: Android <=4.1 - 4.3 only\n\t\t// Also use offsetWidth/offsetHeight for misreported inline dimensions (gh-3602)\n\t\t!parseFloat( val ) && jQuery.css( elem, \"display\", false, styles ) === \"inline\" ) &&\n\n\t\t// Make sure the element is visible & connected\n\t\telem.getClientRects().length ) {\n\n\t\tisBorderBox = jQuery.css( elem, \"boxSizing\", false, styles ) === \"border-box\";\n\n\t\t// Where available, offsetWidth/offsetHeight approximate border box dimensions.\n\t\t// Where not available (e.g., SVG), assume unreliable box-sizing and interpret the\n\t\t// retrieved value as a content box dimension.\n\t\tvalueIsBorderBox = offsetProp in elem;\n\t\tif ( valueIsBorderBox ) {\n\t\t\tval = elem[ offsetProp ];\n\t\t}\n\t}\n\n\t// Normalize \"\" and auto\n\tval = parseFloat( val ) || 0;\n\n\t// Adjust for the element's box model\n\treturn ( val +\n\t\tboxModelAdjustment(\n\t\t\telem,\n\t\t\tdimension,\n\t\t\textra || ( isBorderBox ? \"border\" : \"content\" ),\n\t\t\tvalueIsBorderBox,\n\t\t\tstyles,\n\n\t\t\t// Provide the current computed size to request scroll gutter calculation (gh-3589)\n\t\t\tval\n\t\t)\n\t) + \"px\";\n}\n\njQuery.extend( {\n\n\t// Add in style property hooks for overriding the default\n\t// behavior of getting and setting a style property\n\tcssHooks: {\n\t\topacity: {\n\t\t\tget: function( elem, computed ) {\n\t\t\t\tif ( computed ) {\n\n\t\t\t\t\t// We should always get a number back from opacity\n\t\t\t\t\tvar ret = curCSS( elem, \"opacity\" );\n\t\t\t\t\treturn ret === \"\" ? \"1\" : ret;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t},\n\n\t// Don't automatically add \"px\" to these possibly-unitless properties\n\tcssNumber: {\n\t\t\"animationIterationCount\": true,\n\t\t\"columnCount\": true,\n\t\t\"fillOpacity\": true,\n\t\t\"flexGrow\": true,\n\t\t\"flexShrink\": true,\n\t\t\"fontWeight\": true,\n\t\t\"gridArea\": true,\n\t\t\"gridColumn\": true,\n\t\t\"gridColumnEnd\": true,\n\t\t\"gridColumnStart\": true,\n\t\t\"gridRow\": true,\n\t\t\"gridRowEnd\": true,\n\t\t\"gridRowStart\": true,\n\t\t\"lineHeight\": true,\n\t\t\"opacity\": true,\n\t\t\"order\": true,\n\t\t\"orphans\": true,\n\t\t\"widows\": true,\n\t\t\"zIndex\": true,\n\t\t\"zoom\": true\n\t},\n\n\t// Add in properties whose names you wish to fix before\n\t// setting or getting the value\n\tcssProps: {},\n\n\t// Get and set the style property on a DOM Node\n\tstyle: function( elem, name, value, extra ) {\n\n\t\t// Don't set styles on text and comment nodes\n\t\tif ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Make sure that we're working with the right name\n\t\tvar ret, type, hooks,\n\t\t\torigName = camelCase( name ),\n\t\t\tisCustomProp = rcustomProp.test( name ),\n\t\t\tstyle = elem.style;\n\n\t\t// Make sure that we're working with the right name. We don't\n\t\t// want to query the value if it is a CSS custom property\n\t\t// since they are user-defined.\n\t\tif ( !isCustomProp ) {\n\t\t\tname = finalPropName( origName );\n\t\t}\n\n\t\t// Gets hook for the prefixed version, then unprefixed version\n\t\thooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];\n\n\t\t// Check if we're setting a value\n\t\tif ( value !== undefined ) {\n\t\t\ttype = typeof value;\n\n\t\t\t// Convert \"+=\" or \"-=\" to relative numbers (#7345)\n\t\t\tif ( type === \"string\" && ( ret = rcssNum.exec( value ) ) && ret[ 1 ] ) {\n\t\t\t\tvalue = adjustCSS( elem, name, ret );\n\n\t\t\t\t// Fixes bug #9237\n\t\t\t\ttype = \"number\";\n\t\t\t}\n\n\t\t\t// Make sure that null and NaN values aren't set (#7116)\n\t\t\tif ( value == null || value !== value ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// If a number was passed in, add the unit (except for certain CSS properties)\n\t\t\t// The isCustomProp check can be removed in jQuery 4.0 when we only auto-append\n\t\t\t// \"px\" to a few hardcoded values.\n\t\t\tif ( type === \"number\" && !isCustomProp ) {\n\t\t\t\tvalue += ret && ret[ 3 ] || ( jQuery.cssNumber[ origName ] ? \"\" : \"px\" );\n\t\t\t}\n\n\t\t\t// background-* props affect original clone's values\n\t\t\tif ( !support.clearCloneStyle && value === \"\" && name.indexOf( \"background\" ) === 0 ) {\n\t\t\t\tstyle[ name ] = \"inherit\";\n\t\t\t}\n\n\t\t\t// If a hook was provided, use that value, otherwise just set the specified value\n\t\t\tif ( !hooks || !( \"set\" in hooks ) ||\n\t\t\t\t( value = hooks.set( elem, value, extra ) ) !== undefined ) {\n\n\t\t\t\tif ( isCustomProp ) {\n\t\t\t\t\tstyle.setProperty( name, value );\n\t\t\t\t} else {\n\t\t\t\t\tstyle[ name ] = value;\n\t\t\t\t}\n\t\t\t}\n\n\t\t} else {\n\n\t\t\t// If a hook was provided get the non-computed value from there\n\t\t\tif ( hooks && \"get\" in hooks &&\n\t\t\t\t( ret = hooks.get( elem, false, extra ) ) !== undefined ) {\n\n\t\t\t\treturn ret;\n\t\t\t}\n\n\t\t\t// Otherwise just get the value from the style object\n\t\t\treturn style[ name ];\n\t\t}\n\t},\n\n\tcss: function( elem, name, extra, styles ) {\n\t\tvar val, num, hooks,\n\t\t\torigName = camelCase( name ),\n\t\t\tisCustomProp = rcustomProp.test( name );\n\n\t\t// Make sure that we're working with the right name. We don't\n\t\t// want to modify the value if it is a CSS custom property\n\t\t// since they are user-defined.\n\t\tif ( !isCustomProp ) {\n\t\t\tname = finalPropName( origName );\n\t\t}\n\n\t\t// Try prefixed name followed by the unprefixed name\n\t\thooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];\n\n\t\t// If a hook was provided get the computed value from there\n\t\tif ( hooks && \"get\" in hooks ) {\n\t\t\tval = hooks.get( elem, true, extra );\n\t\t}\n\n\t\t// Otherwise, if a way to get the computed value exists, use that\n\t\tif ( val === undefined ) {\n\t\t\tval = curCSS( elem, name, styles );\n\t\t}\n\n\t\t// Convert \"normal\" to computed value\n\t\tif ( val === \"normal\" && name in cssNormalTransform ) {\n\t\t\tval = cssNormalTransform[ name ];\n\t\t}\n\n\t\t// Make numeric if forced or a qualifier was provided and val looks numeric\n\t\tif ( extra === \"\" || extra ) {\n\t\t\tnum = parseFloat( val );\n\t\t\treturn extra === true || isFinite( num ) ? num || 0 : val;\n\t\t}\n\n\t\treturn val;\n\t}\n} );\n\njQuery.each( [ \"height\", \"width\" ], function( _i, dimension ) {\n\tjQuery.cssHooks[ dimension ] = {\n\t\tget: function( elem, computed, extra ) {\n\t\t\tif ( computed ) {\n\n\t\t\t\t// Certain elements can have dimension info if we invisibly show them\n\t\t\t\t// but it must have a current display style that would benefit\n\t\t\t\treturn rdisplayswap.test( jQuery.css( elem, \"display\" ) ) &&\n\n\t\t\t\t\t// Support: Safari 8+\n\t\t\t\t\t// Table columns in Safari have non-zero offsetWidth & zero\n\t\t\t\t\t// getBoundingClientRect().width unless display is changed.\n\t\t\t\t\t// Support: IE <=11 only\n\t\t\t\t\t// Running getBoundingClientRect on a disconnected node\n\t\t\t\t\t// in IE throws an error.\n\t\t\t\t\t( !elem.getClientRects().length || !elem.getBoundingClientRect().width ) ?\n\t\t\t\t\t\tswap( elem, cssShow, function() {\n\t\t\t\t\t\t\treturn getWidthOrHeight( elem, dimension, extra );\n\t\t\t\t\t\t} ) :\n\t\t\t\t\t\tgetWidthOrHeight( elem, dimension, extra );\n\t\t\t}\n\t\t},\n\n\t\tset: function( elem, value, extra ) {\n\t\t\tvar matches,\n\t\t\t\tstyles = getStyles( elem ),\n\n\t\t\t\t// Only read styles.position if the test has a chance to fail\n\t\t\t\t// to avoid forcing a reflow.\n\t\t\t\tscrollboxSizeBuggy = !support.scrollboxSize() &&\n\t\t\t\t\tstyles.position === \"absolute\",\n\n\t\t\t\t// To avoid forcing a reflow, only fetch boxSizing if we need it (gh-3991)\n\t\t\t\tboxSizingNeeded = scrollboxSizeBuggy || extra,\n\t\t\t\tisBorderBox = boxSizingNeeded &&\n\t\t\t\t\tjQuery.css( elem, \"boxSizing\", false, styles ) === \"border-box\",\n\t\t\t\tsubtract = extra ?\n\t\t\t\t\tboxModelAdjustment(\n\t\t\t\t\t\telem,\n\t\t\t\t\t\tdimension,\n\t\t\t\t\t\textra,\n\t\t\t\t\t\tisBorderBox,\n\t\t\t\t\t\tstyles\n\t\t\t\t\t) :\n\t\t\t\t\t0;\n\n\t\t\t// Account for unreliable border-box dimensions by comparing offset* to computed and\n\t\t\t// faking a content-box to get border and padding (gh-3699)\n\t\t\tif ( isBorderBox && scrollboxSizeBuggy ) {\n\t\t\t\tsubtract -= Math.ceil(\n\t\t\t\t\telem[ \"offset\" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 ) ] -\n\t\t\t\t\tparseFloat( styles[ dimension ] ) -\n\t\t\t\t\tboxModelAdjustment( elem, dimension, \"border\", false, styles ) -\n\t\t\t\t\t0.5\n\t\t\t\t);\n\t\t\t}\n\n\t\t\t// Convert to pixels if value adjustment is needed\n\t\t\tif ( subtract && ( matches = rcssNum.exec( value ) ) &&\n\t\t\t\t( matches[ 3 ] || \"px\" ) !== \"px\" ) {\n\n\t\t\t\telem.style[ dimension ] = value;\n\t\t\t\tvalue = jQuery.css( elem, dimension );\n\t\t\t}\n\n\t\t\treturn setPositiveNumber( elem, value, subtract );\n\t\t}\n\t};\n} );\n\njQuery.cssHooks.marginLeft = addGetHookIf( support.reliableMarginLeft,\n\tfunction( elem, computed ) {\n\t\tif ( computed ) {\n\t\t\treturn ( parseFloat( curCSS( elem, \"marginLeft\" ) ) ||\n\t\t\t\telem.getBoundingClientRect().left -\n\t\t\t\t\tswap( elem, { marginLeft: 0 }, function() {\n\t\t\t\t\t\treturn elem.getBoundingClientRect().left;\n\t\t\t\t\t} )\n\t\t\t\t) + \"px\";\n\t\t}\n\t}\n);\n\n// These hooks are used by animate to expand properties\njQuery.each( {\n\tmargin: \"\",\n\tpadding: \"\",\n\tborder: \"Width\"\n}, function( prefix, suffix ) {\n\tjQuery.cssHooks[ prefix + suffix ] = {\n\t\texpand: function( value ) {\n\t\t\tvar i = 0,\n\t\t\t\texpanded = {},\n\n\t\t\t\t// Assumes a single number if not a string\n\t\t\t\tparts = typeof value === \"string\" ? value.split( \" \" ) : [ value ];\n\n\t\t\tfor ( ; i < 4; i++ ) {\n\t\t\t\texpanded[ prefix + cssExpand[ i ] + suffix ] =\n\t\t\t\t\tparts[ i ] || parts[ i - 2 ] || parts[ 0 ];\n\t\t\t}\n\n\t\t\treturn expanded;\n\t\t}\n\t};\n\n\tif ( prefix !== \"margin\" ) {\n\t\tjQuery.cssHooks[ prefix + suffix ].set = setPositiveNumber;\n\t}\n} );\n\njQuery.fn.extend( {\n\tcss: function( name, value ) {\n\t\treturn access( this, function( elem, name, value ) {\n\t\t\tvar styles, len,\n\t\t\t\tmap = {},\n\t\t\t\ti = 0;\n\n\t\t\tif ( Array.isArray( name ) ) {\n\t\t\t\tstyles = getStyles( elem );\n\t\t\t\tlen = name.length;\n\n\t\t\t\tfor ( ; i < len; i++ ) {\n\t\t\t\t\tmap[ name[ i ] ] = jQuery.css( elem, name[ i ], false, styles );\n\t\t\t\t}\n\n\t\t\t\treturn map;\n\t\t\t}\n\n\t\t\treturn value !== undefined ?\n\t\t\t\tjQuery.style( elem, name, value ) :\n\t\t\t\tjQuery.css( elem, name );\n\t\t}, name, value, arguments.length > 1 );\n\t}\n} );\n\n\nfunction Tween( elem, options, prop, end, easing ) {\n\treturn new Tween.prototype.init( elem, options, prop, end, easing );\n}\njQuery.Tween = Tween;\n\nTween.prototype = {\n\tconstructor: Tween,\n\tinit: function( elem, options, prop, end, easing, unit ) {\n\t\tthis.elem = elem;\n\t\tthis.prop = prop;\n\t\tthis.easing = easing || jQuery.easing._default;\n\t\tthis.options = options;\n\t\tthis.start = this.now = this.cur();\n\t\tthis.end = end;\n\t\tthis.unit = unit || ( jQuery.cssNumber[ prop ] ? \"\" : \"px\" );\n\t},\n\tcur: function() {\n\t\tvar hooks = Tween.propHooks[ this.prop ];\n\n\t\treturn hooks && hooks.get ?\n\t\t\thooks.get( this ) :\n\t\t\tTween.propHooks._default.get( this );\n\t},\n\trun: function( percent ) {\n\t\tvar eased,\n\t\t\thooks = Tween.propHooks[ this.prop ];\n\n\t\tif ( this.options.duration ) {\n\t\t\tthis.pos = eased = jQuery.easing[ this.easing ](\n\t\t\t\tpercent, this.options.duration * percent, 0, 1, this.options.duration\n\t\t\t);\n\t\t} else {\n\t\t\tthis.pos = eased = percent;\n\t\t}\n\t\tthis.now = ( this.end - this.start ) * eased + this.start;\n\n\t\tif ( this.options.step ) {\n\t\t\tthis.options.step.call( this.elem, this.now, this );\n\t\t}\n\n\t\tif ( hooks && hooks.set ) {\n\t\t\thooks.set( this );\n\t\t} else {\n\t\t\tTween.propHooks._default.set( this );\n\t\t}\n\t\treturn this;\n\t}\n};\n\nTween.prototype.init.prototype = Tween.prototype;\n\nTween.propHooks = {\n\t_default: {\n\t\tget: function( tween ) {\n\t\t\tvar result;\n\n\t\t\t// Use a property on the element directly when it is not a DOM element,\n\t\t\t// or when there is no matching style property that exists.\n\t\t\tif ( tween.elem.nodeType !== 1 ||\n\t\t\t\ttween.elem[ tween.prop ] != null && tween.elem.style[ tween.prop ] == null ) {\n\t\t\t\treturn tween.elem[ tween.prop ];\n\t\t\t}\n\n\t\t\t// Passing an empty string as a 3rd parameter to .css will automatically\n\t\t\t// attempt a parseFloat and fallback to a string if the parse fails.\n\t\t\t// Simple values such as \"10px\" are parsed to Float;\n\t\t\t// complex values such as \"rotate(1rad)\" are returned as-is.\n\t\t\tresult = jQuery.css( tween.elem, tween.prop, \"\" );\n\n\t\t\t// Empty strings, null, undefined and \"auto\" are converted to 0.\n\t\t\treturn !result || result === \"auto\" ? 0 : result;\n\t\t},\n\t\tset: function( tween ) {\n\n\t\t\t// Use step hook for back compat.\n\t\t\t// Use cssHook if its there.\n\t\t\t// Use .style if available and use plain properties where available.\n\t\t\tif ( jQuery.fx.step[ tween.prop ] ) {\n\t\t\t\tjQuery.fx.step[ tween.prop ]( tween );\n\t\t\t} else if ( tween.elem.nodeType === 1 && (\n\t\t\t\t\tjQuery.cssHooks[ tween.prop ] ||\n\t\t\t\t\ttween.elem.style[ finalPropName( tween.prop ) ] != null ) ) {\n\t\t\t\tjQuery.style( tween.elem, tween.prop, tween.now + tween.unit );\n\t\t\t} else {\n\t\t\t\ttween.elem[ tween.prop ] = tween.now;\n\t\t\t}\n\t\t}\n\t}\n};\n\n// Support: IE <=9 only\n// Panic based approach to setting things on disconnected nodes\nTween.propHooks.scrollTop = Tween.propHooks.scrollLeft = {\n\tset: function( tween ) {\n\t\tif ( tween.elem.nodeType && tween.elem.parentNode ) {\n\t\t\ttween.elem[ tween.prop ] = tween.now;\n\t\t}\n\t}\n};\n\njQuery.easing = {\n\tlinear: function( p ) {\n\t\treturn p;\n\t},\n\tswing: function( p ) {\n\t\treturn 0.5 - Math.cos( p * Math.PI ) / 2;\n\t},\n\t_default: \"swing\"\n};\n\njQuery.fx = Tween.prototype.init;\n\n// Back compat <1.8 extension point\njQuery.fx.step = {};\n\n\n\n\nvar\n\tfxNow, inProgress,\n\trfxtypes = /^(?:toggle|show|hide)$/,\n\trrun = /queueHooks$/;\n\nfunction schedule() {\n\tif ( inProgress ) {\n\t\tif ( document.hidden === false && window.requestAnimationFrame ) {\n\t\t\twindow.requestAnimationFrame( schedule );\n\t\t} else {\n\t\t\twindow.setTimeout( schedule, jQuery.fx.interval );\n\t\t}\n\n\t\tjQuery.fx.tick();\n\t}\n}\n\n// Animations created synchronously will run synchronously\nfunction createFxNow() {\n\twindow.setTimeout( function() {\n\t\tfxNow = undefined;\n\t} );\n\treturn ( fxNow = Date.now() );\n}\n\n// Generate parameters to create a standard animation\nfunction genFx( type, includeWidth ) {\n\tvar which,\n\t\ti = 0,\n\t\tattrs = { height: type };\n\n\t// If we include width, step value is 1 to do all cssExpand values,\n\t// otherwise step value is 2 to skip over Left and Right\n\tincludeWidth = includeWidth ? 1 : 0;\n\tfor ( ; i < 4; i += 2 - includeWidth ) {\n\t\twhich = cssExpand[ i ];\n\t\tattrs[ \"margin\" + which ] = attrs[ \"padding\" + which ] = type;\n\t}\n\n\tif ( includeWidth ) {\n\t\tattrs.opacity = attrs.width = type;\n\t}\n\n\treturn attrs;\n}\n\nfunction createTween( value, prop, animation ) {\n\tvar tween,\n\t\tcollection = ( Animation.tweeners[ prop ] || [] ).concat( Animation.tweeners[ \"*\" ] ),\n\t\tindex = 0,\n\t\tlength = collection.length;\n\tfor ( ; index < length; index++ ) {\n\t\tif ( ( tween = collection[ index ].call( animation, prop, value ) ) ) {\n\n\t\t\t// We're done with this property\n\t\t\treturn tween;\n\t\t}\n\t}\n}\n\nfunction defaultPrefilter( elem, props, opts ) {\n\tvar prop, value, toggle, hooks, oldfire, propTween, restoreDisplay, display,\n\t\tisBox = \"width\" in props || \"height\" in props,\n\t\tanim = this,\n\t\torig = {},\n\t\tstyle = elem.style,\n\t\thidden = elem.nodeType && isHiddenWithinTree( elem ),\n\t\tdataShow = dataPriv.get( elem, \"fxshow\" );\n\n\t// Queue-skipping animations hijack the fx hooks\n\tif ( !opts.queue ) {\n\t\thooks = jQuery._queueHooks( elem, \"fx\" );\n\t\tif ( hooks.unqueued == null ) {\n\t\t\thooks.unqueued = 0;\n\t\t\toldfire = hooks.empty.fire;\n\t\t\thooks.empty.fire = function() {\n\t\t\t\tif ( !hooks.unqueued ) {\n\t\t\t\t\toldfire();\n\t\t\t\t}\n\t\t\t};\n\t\t}\n\t\thooks.unqueued++;\n\n\t\tanim.always( function() {\n\n\t\t\t// Ensure the complete handler is called before this completes\n\t\t\tanim.always( function() {\n\t\t\t\thooks.unqueued--;\n\t\t\t\tif ( !jQuery.queue( elem, \"fx\" ).length ) {\n\t\t\t\t\thooks.empty.fire();\n\t\t\t\t}\n\t\t\t} );\n\t\t} );\n\t}\n\n\t// Detect show/hide animations\n\tfor ( prop in props ) {\n\t\tvalue = props[ prop ];\n\t\tif ( rfxtypes.test( value ) ) {\n\t\t\tdelete props[ prop ];\n\t\t\ttoggle = toggle || value === \"toggle\";\n\t\t\tif ( value === ( hidden ? \"hide\" : \"show\" ) ) {\n\n\t\t\t\t// Pretend to be hidden if this is a \"show\" and\n\t\t\t\t// there is still data from a stopped show/hide\n\t\t\t\tif ( value === \"show\" && dataShow && dataShow[ prop ] !== undefined ) {\n\t\t\t\t\thidden = true;\n\n\t\t\t\t// Ignore all other no-op show/hide data\n\t\t\t\t} else {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t}\n\t\t\torig[ prop ] = dataShow && dataShow[ prop ] || jQuery.style( elem, prop );\n\t\t}\n\t}\n\n\t// Bail out if this is a no-op like .hide().hide()\n\tpropTween = !jQuery.isEmptyObject( props );\n\tif ( !propTween && jQuery.isEmptyObject( orig ) ) {\n\t\treturn;\n\t}\n\n\t// Restrict \"overflow\" and \"display\" styles during box animations\n\tif ( isBox && elem.nodeType === 1 ) {\n\n\t\t// Support: IE <=9 - 11, Edge 12 - 15\n\t\t// Record all 3 overflow attributes because IE does not infer the shorthand\n\t\t// from identically-valued overflowX and overflowY and Edge just mirrors\n\t\t// the overflowX value there.\n\t\topts.overflow = [ style.overflow, style.overflowX, style.overflowY ];\n\n\t\t// Identify a display type, preferring old show/hide data over the CSS cascade\n\t\trestoreDisplay = dataShow && dataShow.display;\n\t\tif ( restoreDisplay == null ) {\n\t\t\trestoreDisplay = dataPriv.get( elem, \"display\" );\n\t\t}\n\t\tdisplay = jQuery.css( elem, \"display\" );\n\t\tif ( display === \"none\" ) {\n\t\t\tif ( restoreDisplay ) {\n\t\t\t\tdisplay = restoreDisplay;\n\t\t\t} else {\n\n\t\t\t\t// Get nonempty value(s) by temporarily forcing visibility\n\t\t\t\tshowHide( [ elem ], true );\n\t\t\t\trestoreDisplay = elem.style.display || restoreDisplay;\n\t\t\t\tdisplay = jQuery.css( elem, \"display\" );\n\t\t\t\tshowHide( [ elem ] );\n\t\t\t}\n\t\t}\n\n\t\t// Animate inline elements as inline-block\n\t\tif ( display === \"inline\" || display === \"inline-block\" && restoreDisplay != null ) {\n\t\t\tif ( jQuery.css( elem, \"float\" ) === \"none\" ) {\n\n\t\t\t\t// Restore the original display value at the end of pure show/hide animations\n\t\t\t\tif ( !propTween ) {\n\t\t\t\t\tanim.done( function() {\n\t\t\t\t\t\tstyle.display = restoreDisplay;\n\t\t\t\t\t} );\n\t\t\t\t\tif ( restoreDisplay == null ) {\n\t\t\t\t\t\tdisplay = style.display;\n\t\t\t\t\t\trestoreDisplay = display === \"none\" ? \"\" : display;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tstyle.display = \"inline-block\";\n\t\t\t}\n\t\t}\n\t}\n\n\tif ( opts.overflow ) {\n\t\tstyle.overflow = \"hidden\";\n\t\tanim.always( function() {\n\t\t\tstyle.overflow = opts.overflow[ 0 ];\n\t\t\tstyle.overflowX = opts.overflow[ 1 ];\n\t\t\tstyle.overflowY = opts.overflow[ 2 ];\n\t\t} );\n\t}\n\n\t// Implement show/hide animations\n\tpropTween = false;\n\tfor ( prop in orig ) {\n\n\t\t// General show/hide setup for this element animation\n\t\tif ( !propTween ) {\n\t\t\tif ( dataShow ) {\n\t\t\t\tif ( \"hidden\" in dataShow ) {\n\t\t\t\t\thidden = dataShow.hidden;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tdataShow = dataPriv.access( elem, \"fxshow\", { display: restoreDisplay } );\n\t\t\t}\n\n\t\t\t// Store hidden/visible for toggle so `.stop().toggle()` \"reverses\"\n\t\t\tif ( toggle ) {\n\t\t\t\tdataShow.hidden = !hidden;\n\t\t\t}\n\n\t\t\t// Show elements before animating them\n\t\t\tif ( hidden ) {\n\t\t\t\tshowHide( [ elem ], true );\n\t\t\t}\n\n\t\t\t/* eslint-disable no-loop-func */\n\n\t\t\tanim.done( function() {\n\n\t\t\t/* eslint-enable no-loop-func */\n\n\t\t\t\t// The final step of a \"hide\" animation is actually hiding the element\n\t\t\t\tif ( !hidden ) {\n\t\t\t\t\tshowHide( [ elem ] );\n\t\t\t\t}\n\t\t\t\tdataPriv.remove( elem, \"fxshow\" );\n\t\t\t\tfor ( prop in orig ) {\n\t\t\t\t\tjQuery.style( elem, prop, orig[ prop ] );\n\t\t\t\t}\n\t\t\t} );\n\t\t}\n\n\t\t// Per-property setup\n\t\tpropTween = createTween( hidden ? dataShow[ prop ] : 0, prop, anim );\n\t\tif ( !( prop in dataShow ) ) {\n\t\t\tdataShow[ prop ] = propTween.start;\n\t\t\tif ( hidden ) {\n\t\t\t\tpropTween.end = propTween.start;\n\t\t\t\tpropTween.start = 0;\n\t\t\t}\n\t\t}\n\t}\n}\n\nfunction propFilter( props, specialEasing ) {\n\tvar index, name, easing, value, hooks;\n\n\t// camelCase, specialEasing and expand cssHook pass\n\tfor ( index in props ) {\n\t\tname = camelCase( index );\n\t\teasing = specialEasing[ name ];\n\t\tvalue = props[ index ];\n\t\tif ( Array.isArray( value ) ) {\n\t\t\teasing = value[ 1 ];\n\t\t\tvalue = props[ index ] = value[ 0 ];\n\t\t}\n\n\t\tif ( index !== name ) {\n\t\t\tprops[ name ] = value;\n\t\t\tdelete props[ index ];\n\t\t}\n\n\t\thooks = jQuery.cssHooks[ name ];\n\t\tif ( hooks && \"expand\" in hooks ) {\n\t\t\tvalue = hooks.expand( value );\n\t\t\tdelete props[ name ];\n\n\t\t\t// Not quite $.extend, this won't overwrite existing keys.\n\t\t\t// Reusing 'index' because we have the correct \"name\"\n\t\t\tfor ( index in value ) {\n\t\t\t\tif ( !( index in props ) ) {\n\t\t\t\t\tprops[ index ] = value[ index ];\n\t\t\t\t\tspecialEasing[ index ] = easing;\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tspecialEasing[ name ] = easing;\n\t\t}\n\t}\n}\n\nfunction Animation( elem, properties, options ) {\n\tvar result,\n\t\tstopped,\n\t\tindex = 0,\n\t\tlength = Animation.prefilters.length,\n\t\tdeferred = jQuery.Deferred().always( function() {\n\n\t\t\t// Don't match elem in the :animated selector\n\t\t\tdelete tick.elem;\n\t\t} ),\n\t\ttick = function() {\n\t\t\tif ( stopped ) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tvar currentTime = fxNow || createFxNow(),\n\t\t\t\tremaining = Math.max( 0, animation.startTime + animation.duration - currentTime ),\n\n\t\t\t\t// Support: Android 2.3 only\n\t\t\t\t// Archaic crash bug won't allow us to use `1 - ( 0.5 || 0 )` (#12497)\n\t\t\t\ttemp = remaining / animation.duration || 0,\n\t\t\t\tpercent = 1 - temp,\n\t\t\t\tindex = 0,\n\t\t\t\tlength = animation.tweens.length;\n\n\t\t\tfor ( ; index < length; index++ ) {\n\t\t\t\tanimation.tweens[ index ].run( percent );\n\t\t\t}\n\n\t\t\tdeferred.notifyWith( elem, [ animation, percent, remaining ] );\n\n\t\t\t// If there's more to do, yield\n\t\t\tif ( percent < 1 && length ) {\n\t\t\t\treturn remaining;\n\t\t\t}\n\n\t\t\t// If this was an empty animation, synthesize a final progress notification\n\t\t\tif ( !length ) {\n\t\t\t\tdeferred.notifyWith( elem, [ animation, 1, 0 ] );\n\t\t\t}\n\n\t\t\t// Resolve the animation and report its conclusion\n\t\t\tdeferred.resolveWith( elem, [ animation ] );\n\t\t\treturn false;\n\t\t},\n\t\tanimation = deferred.promise( {\n\t\t\telem: elem,\n\t\t\tprops: jQuery.extend( {}, properties ),\n\t\t\topts: jQuery.extend( true, {\n\t\t\t\tspecialEasing: {},\n\t\t\t\teasing: jQuery.easing._default\n\t\t\t}, options ),\n\t\t\toriginalProperties: properties,\n\t\t\toriginalOptions: options,\n\t\t\tstartTime: fxNow || createFxNow(),\n\t\t\tduration: options.duration,\n\t\t\ttweens: [],\n\t\t\tcreateTween: function( prop, end ) {\n\t\t\t\tvar tween = jQuery.Tween( elem, animation.opts, prop, end,\n\t\t\t\t\t\tanimation.opts.specialEasing[ prop ] || animation.opts.easing );\n\t\t\t\tanimation.tweens.push( tween );\n\t\t\t\treturn tween;\n\t\t\t},\n\t\t\tstop: function( gotoEnd ) {\n\t\t\t\tvar index = 0,\n\n\t\t\t\t\t// If we are going to the end, we want to run all the tweens\n\t\t\t\t\t// otherwise we skip this part\n\t\t\t\t\tlength = gotoEnd ? animation.tweens.length : 0;\n\t\t\t\tif ( stopped ) {\n\t\t\t\t\treturn this;\n\t\t\t\t}\n\t\t\t\tstopped = true;\n\t\t\t\tfor ( ; index < length; index++ ) {\n\t\t\t\t\tanimation.tweens[ index ].run( 1 );\n\t\t\t\t}\n\n\t\t\t\t// Resolve when we played the last frame; otherwise, reject\n\t\t\t\tif ( gotoEnd ) {\n\t\t\t\t\tdeferred.notifyWith( elem, [ animation, 1, 0 ] );\n\t\t\t\t\tdeferred.resolveWith( elem, [ animation, gotoEnd ] );\n\t\t\t\t} else {\n\t\t\t\t\tdeferred.rejectWith( elem, [ animation, gotoEnd ] );\n\t\t\t\t}\n\t\t\t\treturn this;\n\t\t\t}\n\t\t} ),\n\t\tprops = animation.props;\n\n\tpropFilter( props, animation.opts.specialEasing );\n\n\tfor ( ; index < length; index++ ) {\n\t\tresult = Animation.prefilters[ index ].call( animation, elem, props, animation.opts );\n\t\tif ( result ) {\n\t\t\tif ( isFunction( result.stop ) ) {\n\t\t\t\tjQuery._queueHooks( animation.elem, animation.opts.queue ).stop =\n\t\t\t\t\tresult.stop.bind( result );\n\t\t\t}\n\t\t\treturn result;\n\t\t}\n\t}\n\n\tjQuery.map( props, createTween, animation );\n\n\tif ( isFunction( animation.opts.start ) ) {\n\t\tanimation.opts.start.call( elem, animation );\n\t}\n\n\t// Attach callbacks from options\n\tanimation\n\t\t.progress( animation.opts.progress )\n\t\t.done( animation.opts.done, animation.opts.complete )\n\t\t.fail( animation.opts.fail )\n\t\t.always( animation.opts.always );\n\n\tjQuery.fx.timer(\n\t\tjQuery.extend( tick, {\n\t\t\telem: elem,\n\t\t\tanim: animation,\n\t\t\tqueue: animation.opts.queue\n\t\t} )\n\t);\n\n\treturn animation;\n}\n\njQuery.Animation = jQuery.extend( Animation, {\n\n\ttweeners: {\n\t\t\"*\": [ function( prop, value ) {\n\t\t\tvar tween = this.createTween( prop, value );\n\t\t\tadjustCSS( tween.elem, prop, rcssNum.exec( value ), tween );\n\t\t\treturn tween;\n\t\t} ]\n\t},\n\n\ttweener: function( props, callback ) {\n\t\tif ( isFunction( props ) ) {\n\t\t\tcallback = props;\n\t\t\tprops = [ \"*\" ];\n\t\t} else {\n\t\t\tprops = props.match( rnothtmlwhite );\n\t\t}\n\n\t\tvar prop,\n\t\t\tindex = 0,\n\t\t\tlength = props.length;\n\n\t\tfor ( ; index < length; index++ ) {\n\t\t\tprop = props[ index ];\n\t\t\tAnimation.tweeners[ prop ] = Animation.tweeners[ prop ] || [];\n\t\t\tAnimation.tweeners[ prop ].unshift( callback );\n\t\t}\n\t},\n\n\tprefilters: [ defaultPrefilter ],\n\n\tprefilter: function( callback, prepend ) {\n\t\tif ( prepend ) {\n\t\t\tAnimation.prefilters.unshift( callback );\n\t\t} else {\n\t\t\tAnimation.prefilters.push( callback );\n\t\t}\n\t}\n} );\n\njQuery.speed = function( speed, easing, fn ) {\n\tvar opt = speed && typeof speed === \"object\" ? jQuery.extend( {}, speed ) : {\n\t\tcomplete: fn || !fn && easing ||\n\t\t\tisFunction( speed ) && speed,\n\t\tduration: speed,\n\t\teasing: fn && easing || easing && !isFunction( easing ) && easing\n\t};\n\n\t// Go to the end state if fx are off\n\tif ( jQuery.fx.off ) {\n\t\topt.duration = 0;\n\n\t} else {\n\t\tif ( typeof opt.duration !== \"number\" ) {\n\t\t\tif ( opt.duration in jQuery.fx.speeds ) {\n\t\t\t\topt.duration = jQuery.fx.speeds[ opt.duration ];\n\n\t\t\t} else {\n\t\t\t\topt.duration = jQuery.fx.speeds._default;\n\t\t\t}\n\t\t}\n\t}\n\n\t// Normalize opt.queue - true/undefined/null -> \"fx\"\n\tif ( opt.queue == null || opt.queue === true ) {\n\t\topt.queue = \"fx\";\n\t}\n\n\t// Queueing\n\topt.old = opt.complete;\n\n\topt.complete = function() {\n\t\tif ( isFunction( opt.old ) ) {\n\t\t\topt.old.call( this );\n\t\t}\n\n\t\tif ( opt.queue ) {\n\t\t\tjQuery.dequeue( this, opt.queue );\n\t\t}\n\t};\n\n\treturn opt;\n};\n\njQuery.fn.extend( {\n\tfadeTo: function( speed, to, easing, callback ) {\n\n\t\t// Show any hidden elements after setting opacity to 0\n\t\treturn this.filter( isHiddenWithinTree ).css( \"opacity\", 0 ).show()\n\n\t\t\t// Animate to the value specified\n\t\t\t.end().animate( { opacity: to }, speed, easing, callback );\n\t},\n\tanimate: function( prop, speed, easing, callback ) {\n\t\tvar empty = jQuery.isEmptyObject( prop ),\n\t\t\toptall = jQuery.speed( speed, easing, callback ),\n\t\t\tdoAnimation = function() {\n\n\t\t\t\t// Operate on a copy of prop so per-property easing won't be lost\n\t\t\t\tvar anim = Animation( this, jQuery.extend( {}, prop ), optall );\n\n\t\t\t\t// Empty animations, or finishing resolves immediately\n\t\t\t\tif ( empty || dataPriv.get( this, \"finish\" ) ) {\n\t\t\t\t\tanim.stop( true );\n\t\t\t\t}\n\t\t\t};\n\t\t\tdoAnimation.finish = doAnimation;\n\n\t\treturn empty || optall.queue === false ?\n\t\t\tthis.each( doAnimation ) :\n\t\t\tthis.queue( optall.queue, doAnimation );\n\t},\n\tstop: function( type, clearQueue, gotoEnd ) {\n\t\tvar stopQueue = function( hooks ) {\n\t\t\tvar stop = hooks.stop;\n\t\t\tdelete hooks.stop;\n\t\t\tstop( gotoEnd );\n\t\t};\n\n\t\tif ( typeof type !== \"string\" ) {\n\t\t\tgotoEnd = clearQueue;\n\t\t\tclearQueue = type;\n\t\t\ttype = undefined;\n\t\t}\n\t\tif ( clearQueue ) {\n\t\t\tthis.queue( type || \"fx\", [] );\n\t\t}\n\n\t\treturn this.each( function() {\n\t\t\tvar dequeue = true,\n\t\t\t\tindex = type != null && type + \"queueHooks\",\n\t\t\t\ttimers = jQuery.timers,\n\t\t\t\tdata = dataPriv.get( this );\n\n\t\t\tif ( index ) {\n\t\t\t\tif ( data[ index ] && data[ index ].stop ) {\n\t\t\t\t\tstopQueue( data[ index ] );\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tfor ( index in data ) {\n\t\t\t\t\tif ( data[ index ] && data[ index ].stop && rrun.test( index ) ) {\n\t\t\t\t\t\tstopQueue( data[ index ] );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tfor ( index = timers.length; index--; ) {\n\t\t\t\tif ( timers[ index ].elem === this &&\n\t\t\t\t\t( type == null || timers[ index ].queue === type ) ) {\n\n\t\t\t\t\ttimers[ index ].anim.stop( gotoEnd );\n\t\t\t\t\tdequeue = false;\n\t\t\t\t\ttimers.splice( index, 1 );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Start the next in the queue if the last step wasn't forced.\n\t\t\t// Timers currently will call their complete callbacks, which\n\t\t\t// will dequeue but only if they were gotoEnd.\n\t\t\tif ( dequeue || !gotoEnd ) {\n\t\t\t\tjQuery.dequeue( this, type );\n\t\t\t}\n\t\t} );\n\t},\n\tfinish: function( type ) {\n\t\tif ( type !== false ) {\n\t\t\ttype = type || \"fx\";\n\t\t}\n\t\treturn this.each( function() {\n\t\t\tvar index,\n\t\t\t\tdata = dataPriv.get( this ),\n\t\t\t\tqueue = data[ type + \"queue\" ],\n\t\t\t\thooks = data[ type + \"queueHooks\" ],\n\t\t\t\ttimers = jQuery.timers,\n\t\t\t\tlength = queue ? queue.length : 0;\n\n\t\t\t// Enable finishing flag on private data\n\t\t\tdata.finish = true;\n\n\t\t\t// Empty the queue first\n\t\t\tjQuery.queue( this, type, [] );\n\n\t\t\tif ( hooks && hooks.stop ) {\n\t\t\t\thooks.stop.call( this, true );\n\t\t\t}\n\n\t\t\t// Look for any active animations, and finish them\n\t\t\tfor ( index = timers.length; index--; ) {\n\t\t\t\tif ( timers[ index ].elem === this && timers[ index ].queue === type ) {\n\t\t\t\t\ttimers[ index ].anim.stop( true );\n\t\t\t\t\ttimers.splice( index, 1 );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Look for any animations in the old queue and finish them\n\t\t\tfor ( index = 0; index < length; index++ ) {\n\t\t\t\tif ( queue[ index ] && queue[ index ].finish ) {\n\t\t\t\t\tqueue[ index ].finish.call( this );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Turn off finishing flag\n\t\t\tdelete data.finish;\n\t\t} );\n\t}\n} );\n\njQuery.each( [ \"toggle\", \"show\", \"hide\" ], function( _i, name ) {\n\tvar cssFn = jQuery.fn[ name ];\n\tjQuery.fn[ name ] = function( speed, easing, callback ) {\n\t\treturn speed == null || typeof speed === \"boolean\" ?\n\t\t\tcssFn.apply( this, arguments ) :\n\t\t\tthis.animate( genFx( name, true ), speed, easing, callback );\n\t};\n} );\n\n// Generate shortcuts for custom animations\njQuery.each( {\n\tslideDown: genFx( \"show\" ),\n\tslideUp: genFx( \"hide\" ),\n\tslideToggle: genFx( \"toggle\" ),\n\tfadeIn: { opacity: \"show\" },\n\tfadeOut: { opacity: \"hide\" },\n\tfadeToggle: { opacity: \"toggle\" }\n}, function( name, props ) {\n\tjQuery.fn[ name ] = function( speed, easing, callback ) {\n\t\treturn this.animate( props, speed, easing, callback );\n\t};\n} );\n\njQuery.timers = [];\njQuery.fx.tick = function() {\n\tvar timer,\n\t\ti = 0,\n\t\ttimers = jQuery.timers;\n\n\tfxNow = Date.now();\n\n\tfor ( ; i < timers.length; i++ ) {\n\t\ttimer = timers[ i ];\n\n\t\t// Run the timer and safely remove it when done (allowing for external removal)\n\t\tif ( !timer() && timers[ i ] === timer ) {\n\t\t\ttimers.splice( i--, 1 );\n\t\t}\n\t}\n\n\tif ( !timers.length ) {\n\t\tjQuery.fx.stop();\n\t}\n\tfxNow = undefined;\n};\n\njQuery.fx.timer = function( timer ) {\n\tjQuery.timers.push( timer );\n\tjQuery.fx.start();\n};\n\njQuery.fx.interval = 13;\njQuery.fx.start = function() {\n\tif ( inProgress ) {\n\t\treturn;\n\t}\n\n\tinProgress = true;\n\tschedule();\n};\n\njQuery.fx.stop = function() {\n\tinProgress = null;\n};\n\njQuery.fx.speeds = {\n\tslow: 600,\n\tfast: 200,\n\n\t// Default speed\n\t_default: 400\n};\n\n\n// Based off of the plugin by Clint Helfers, with permission.\n// https://web.archive.org/web/20100324014747/http://blindsignals.com/index.php/2009/07/jquery-delay/\njQuery.fn.delay = function( time, type ) {\n\ttime = jQuery.fx ? jQuery.fx.speeds[ time ] || time : time;\n\ttype = type || \"fx\";\n\n\treturn this.queue( type, function( next, hooks ) {\n\t\tvar timeout = window.setTimeout( next, time );\n\t\thooks.stop = function() {\n\t\t\twindow.clearTimeout( timeout );\n\t\t};\n\t} );\n};\n\n\n( function() {\n\tvar input = document.createElement( \"input\" ),\n\t\tselect = document.createElement( \"select\" ),\n\t\topt = select.appendChild( document.createElement( \"option\" ) );\n\n\tinput.type = \"checkbox\";\n\n\t// Support: Android <=4.3 only\n\t// Default value for a checkbox should be \"on\"\n\tsupport.checkOn = input.value !== \"\";\n\n\t// Support: IE <=11 only\n\t// Must access selectedIndex to make default options select\n\tsupport.optSelected = opt.selected;\n\n\t// Support: IE <=11 only\n\t// An input loses its value after becoming a radio\n\tinput = document.createElement( \"input\" );\n\tinput.value = \"t\";\n\tinput.type = \"radio\";\n\tsupport.radioValue = input.value === \"t\";\n} )();\n\n\nvar boolHook,\n\tattrHandle = jQuery.expr.attrHandle;\n\njQuery.fn.extend( {\n\tattr: function( name, value ) {\n\t\treturn access( this, jQuery.attr, name, value, arguments.length > 1 );\n\t},\n\n\tremoveAttr: function( name ) {\n\t\treturn this.each( function() {\n\t\t\tjQuery.removeAttr( this, name );\n\t\t} );\n\t}\n} );\n\njQuery.extend( {\n\tattr: function( elem, name, value ) {\n\t\tvar ret, hooks,\n\t\t\tnType = elem.nodeType;\n\n\t\t// Don't get/set attributes on text, comment and attribute nodes\n\t\tif ( nType === 3 || nType === 8 || nType === 2 ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Fallback to prop when attributes are not supported\n\t\tif ( typeof elem.getAttribute === \"undefined\" ) {\n\t\t\treturn jQuery.prop( elem, name, value );\n\t\t}\n\n\t\t// Attribute hooks are determined by the lowercase version\n\t\t// Grab necessary hook if one is defined\n\t\tif ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) {\n\t\t\thooks = jQuery.attrHooks[ name.toLowerCase() ] ||\n\t\t\t\t( jQuery.expr.match.bool.test( name ) ? boolHook : undefined );\n\t\t}\n\n\t\tif ( value !== undefined ) {\n\t\t\tif ( value === null ) {\n\t\t\t\tjQuery.removeAttr( elem, name );\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif ( hooks && \"set\" in hooks &&\n\t\t\t\t( ret = hooks.set( elem, value, name ) ) !== undefined ) {\n\t\t\t\treturn ret;\n\t\t\t}\n\n\t\t\telem.setAttribute( name, value + \"\" );\n\t\t\treturn value;\n\t\t}\n\n\t\tif ( hooks && \"get\" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) {\n\t\t\treturn ret;\n\t\t}\n\n\t\tret = jQuery.find.attr( elem, name );\n\n\t\t// Non-existent attributes return null, we normalize to undefined\n\t\treturn ret == null ? undefined : ret;\n\t},\n\n\tattrHooks: {\n\t\ttype: {\n\t\t\tset: function( elem, value ) {\n\t\t\t\tif ( !support.radioValue && value === \"radio\" &&\n\t\t\t\t\tnodeName( elem, \"input\" ) ) {\n\t\t\t\t\tvar val = elem.value;\n\t\t\t\t\telem.setAttribute( \"type\", value );\n\t\t\t\t\tif ( val ) {\n\t\t\t\t\t\telem.value = val;\n\t\t\t\t\t}\n\t\t\t\t\treturn value;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t},\n\n\tremoveAttr: function( elem, value ) {\n\t\tvar name,\n\t\t\ti = 0,\n\n\t\t\t// Attribute names can contain non-HTML whitespace characters\n\t\t\t// https://html.spec.whatwg.org/multipage/syntax.html#attributes-2\n\t\t\tattrNames = value && value.match( rnothtmlwhite );\n\n\t\tif ( attrNames && elem.nodeType === 1 ) {\n\t\t\twhile ( ( name = attrNames[ i++ ] ) ) {\n\t\t\t\telem.removeAttribute( name );\n\t\t\t}\n\t\t}\n\t}\n} );\n\n// Hooks for boolean attributes\nboolHook = {\n\tset: function( elem, value, name ) {\n\t\tif ( value === false ) {\n\n\t\t\t// Remove boolean attributes when set to false\n\t\t\tjQuery.removeAttr( elem, name );\n\t\t} else {\n\t\t\telem.setAttribute( name, name );\n\t\t}\n\t\treturn name;\n\t}\n};\n\njQuery.each( jQuery.expr.match.bool.source.match( /\\w+/g ), function( _i, name ) {\n\tvar getter = attrHandle[ name ] || jQuery.find.attr;\n\n\tattrHandle[ name ] = function( elem, name, isXML ) {\n\t\tvar ret, handle,\n\t\t\tlowercaseName = name.toLowerCase();\n\n\t\tif ( !isXML ) {\n\n\t\t\t// Avoid an infinite loop by temporarily removing this function from the getter\n\t\t\thandle = attrHandle[ lowercaseName ];\n\t\t\tattrHandle[ lowercaseName ] = ret;\n\t\t\tret = getter( elem, name, isXML ) != null ?\n\t\t\t\tlowercaseName :\n\t\t\t\tnull;\n\t\t\tattrHandle[ lowercaseName ] = handle;\n\t\t}\n\t\treturn ret;\n\t};\n} );\n\n\n\n\nvar rfocusable = /^(?:input|select|textarea|button)$/i,\n\trclickable = /^(?:a|area)$/i;\n\njQuery.fn.extend( {\n\tprop: function( name, value ) {\n\t\treturn access( this, jQuery.prop, name, value, arguments.length > 1 );\n\t},\n\n\tremoveProp: function( name ) {\n\t\treturn this.each( function() {\n\t\t\tdelete this[ jQuery.propFix[ name ] || name ];\n\t\t} );\n\t}\n} );\n\njQuery.extend( {\n\tprop: function( elem, name, value ) {\n\t\tvar ret, hooks,\n\t\t\tnType = elem.nodeType;\n\n\t\t// Don't get/set properties on text, comment and attribute nodes\n\t\tif ( nType === 3 || nType === 8 || nType === 2 ) {\n\t\t\treturn;\n\t\t}\n\n\t\tif ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) {\n\n\t\t\t// Fix name and attach hooks\n\t\t\tname = jQuery.propFix[ name ] || name;\n\t\t\thooks = jQuery.propHooks[ name ];\n\t\t}\n\n\t\tif ( value !== undefined ) {\n\t\t\tif ( hooks && \"set\" in hooks &&\n\t\t\t\t( ret = hooks.set( elem, value, name ) ) !== undefined ) {\n\t\t\t\treturn ret;\n\t\t\t}\n\n\t\t\treturn ( elem[ name ] = value );\n\t\t}\n\n\t\tif ( hooks && \"get\" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) {\n\t\t\treturn ret;\n\t\t}\n\n\t\treturn elem[ name ];\n\t},\n\n\tpropHooks: {\n\t\ttabIndex: {\n\t\t\tget: function( elem ) {\n\n\t\t\t\t// Support: IE <=9 - 11 only\n\t\t\t\t// elem.tabIndex doesn't always return the\n\t\t\t\t// correct value when it hasn't been explicitly set\n\t\t\t\t// https://web.archive.org/web/20141116233347/http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/\n\t\t\t\t// Use proper attribute retrieval(#12072)\n\t\t\t\tvar tabindex = jQuery.find.attr( elem, \"tabindex\" );\n\n\t\t\t\tif ( tabindex ) {\n\t\t\t\t\treturn parseInt( tabindex, 10 );\n\t\t\t\t}\n\n\t\t\t\tif (\n\t\t\t\t\trfocusable.test( elem.nodeName ) ||\n\t\t\t\t\trclickable.test( elem.nodeName ) &&\n\t\t\t\t\telem.href\n\t\t\t\t) {\n\t\t\t\t\treturn 0;\n\t\t\t\t}\n\n\t\t\t\treturn -1;\n\t\t\t}\n\t\t}\n\t},\n\n\tpropFix: {\n\t\t\"for\": \"htmlFor\",\n\t\t\"class\": \"className\"\n\t}\n} );\n\n// Support: IE <=11 only\n// Accessing the selectedIndex property\n// forces the browser to respect setting selected\n// on the option\n// The getter ensures a default option is selected\n// when in an optgroup\n// eslint rule \"no-unused-expressions\" is disabled for this code\n// since it considers such accessions noop\nif ( !support.optSelected ) {\n\tjQuery.propHooks.selected = {\n\t\tget: function( elem ) {\n\n\t\t\t/* eslint no-unused-expressions: \"off\" */\n\n\t\t\tvar parent = elem.parentNode;\n\t\t\tif ( parent && parent.parentNode ) {\n\t\t\t\tparent.parentNode.selectedIndex;\n\t\t\t}\n\t\t\treturn null;\n\t\t},\n\t\tset: function( elem ) {\n\n\t\t\t/* eslint no-unused-expressions: \"off\" */\n\n\t\t\tvar parent = elem.parentNode;\n\t\t\tif ( parent ) {\n\t\t\t\tparent.selectedIndex;\n\n\t\t\t\tif ( parent.parentNode ) {\n\t\t\t\t\tparent.parentNode.selectedIndex;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t};\n}\n\njQuery.each( [\n\t\"tabIndex\",\n\t\"readOnly\",\n\t\"maxLength\",\n\t\"cellSpacing\",\n\t\"cellPadding\",\n\t\"rowSpan\",\n\t\"colSpan\",\n\t\"useMap\",\n\t\"frameBorder\",\n\t\"contentEditable\"\n], function() {\n\tjQuery.propFix[ this.toLowerCase() ] = this;\n} );\n\n\n\n\n\t// Strip and collapse whitespace according to HTML spec\n\t// https://infra.spec.whatwg.org/#strip-and-collapse-ascii-whitespace\n\tfunction stripAndCollapse( value ) {\n\t\tvar tokens = value.match( rnothtmlwhite ) || [];\n\t\treturn tokens.join( \" \" );\n\t}\n\n\nfunction getClass( elem ) {\n\treturn elem.getAttribute && elem.getAttribute( \"class\" ) || \"\";\n}\n\nfunction classesToArray( value ) {\n\tif ( Array.isArray( value ) ) {\n\t\treturn value;\n\t}\n\tif ( typeof value === \"string\" ) {\n\t\treturn value.match( rnothtmlwhite ) || [];\n\t}\n\treturn [];\n}\n\njQuery.fn.extend( {\n\taddClass: function( value ) {\n\t\tvar classes, elem, cur, curValue, clazz, j, finalValue,\n\t\t\ti = 0;\n\n\t\tif ( isFunction( value ) ) {\n\t\t\treturn this.each( function( j ) {\n\t\t\t\tjQuery( this ).addClass( value.call( this, j, getClass( this ) ) );\n\t\t\t} );\n\t\t}\n\n\t\tclasses = classesToArray( value );\n\n\t\tif ( classes.length ) {\n\t\t\twhile ( ( elem = this[ i++ ] ) ) {\n\t\t\t\tcurValue = getClass( elem );\n\t\t\t\tcur = elem.nodeType === 1 && ( \" \" + stripAndCollapse( curValue ) + \" \" );\n\n\t\t\t\tif ( cur ) {\n\t\t\t\t\tj = 0;\n\t\t\t\t\twhile ( ( clazz = classes[ j++ ] ) ) {\n\t\t\t\t\t\tif ( cur.indexOf( \" \" + clazz + \" \" ) < 0 ) {\n\t\t\t\t\t\t\tcur += clazz + \" \";\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t// Only assign if different to avoid unneeded rendering.\n\t\t\t\t\tfinalValue = stripAndCollapse( cur );\n\t\t\t\t\tif ( curValue !== finalValue ) {\n\t\t\t\t\t\telem.setAttribute( \"class\", finalValue );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn this;\n\t},\n\n\tremoveClass: function( value ) {\n\t\tvar classes, elem, cur, curValue, clazz, j, finalValue,\n\t\t\ti = 0;\n\n\t\tif ( isFunction( value ) ) {\n\t\t\treturn this.each( function( j ) {\n\t\t\t\tjQuery( this ).removeClass( value.call( this, j, getClass( this ) ) );\n\t\t\t} );\n\t\t}\n\n\t\tif ( !arguments.length ) {\n\t\t\treturn this.attr( \"class\", \"\" );\n\t\t}\n\n\t\tclasses = classesToArray( value );\n\n\t\tif ( classes.length ) {\n\t\t\twhile ( ( elem = this[ i++ ] ) ) {\n\t\t\t\tcurValue = getClass( elem );\n\n\t\t\t\t// This expression is here for better compressibility (see addClass)\n\t\t\t\tcur = elem.nodeType === 1 && ( \" \" + stripAndCollapse( curValue ) + \" \" );\n\n\t\t\t\tif ( cur ) {\n\t\t\t\t\tj = 0;\n\t\t\t\t\twhile ( ( clazz = classes[ j++ ] ) ) {\n\n\t\t\t\t\t\t// Remove *all* instances\n\t\t\t\t\t\twhile ( cur.indexOf( \" \" + clazz + \" \" ) > -1 ) {\n\t\t\t\t\t\t\tcur = cur.replace( \" \" + clazz + \" \", \" \" );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t// Only assign if different to avoid unneeded rendering.\n\t\t\t\t\tfinalValue = stripAndCollapse( cur );\n\t\t\t\t\tif ( curValue !== finalValue ) {\n\t\t\t\t\t\telem.setAttribute( \"class\", finalValue );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn this;\n\t},\n\n\ttoggleClass: function( value, stateVal ) {\n\t\tvar type = typeof value,\n\t\t\tisValidValue = type === \"string\" || Array.isArray( value );\n\n\t\tif ( typeof stateVal === \"boolean\" && isValidValue ) {\n\t\t\treturn stateVal ? this.addClass( value ) : this.removeClass( value );\n\t\t}\n\n\t\tif ( isFunction( value ) ) {\n\t\t\treturn this.each( function( i ) {\n\t\t\t\tjQuery( this ).toggleClass(\n\t\t\t\t\tvalue.call( this, i, getClass( this ), stateVal ),\n\t\t\t\t\tstateVal\n\t\t\t\t);\n\t\t\t} );\n\t\t}\n\n\t\treturn this.each( function() {\n\t\t\tvar className, i, self, classNames;\n\n\t\t\tif ( isValidValue ) {\n\n\t\t\t\t// Toggle individual class names\n\t\t\t\ti = 0;\n\t\t\t\tself = jQuery( this );\n\t\t\t\tclassNames = classesToArray( value );\n\n\t\t\t\twhile ( ( className = classNames[ i++ ] ) ) {\n\n\t\t\t\t\t// Check each className given, space separated list\n\t\t\t\t\tif ( self.hasClass( className ) ) {\n\t\t\t\t\t\tself.removeClass( className );\n\t\t\t\t\t} else {\n\t\t\t\t\t\tself.addClass( className );\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t// Toggle whole class name\n\t\t\t} else if ( value === undefined || type === \"boolean\" ) {\n\t\t\t\tclassName = getClass( this );\n\t\t\t\tif ( className ) {\n\n\t\t\t\t\t// Store className if set\n\t\t\t\t\tdataPriv.set( this, \"__className__\", className );\n\t\t\t\t}\n\n\t\t\t\t// If the element has a class name or if we're passed `false`,\n\t\t\t\t// then remove the whole classname (if there was one, the above saved it).\n\t\t\t\t// Otherwise bring back whatever was previously saved (if anything),\n\t\t\t\t// falling back to the empty string if nothing was stored.\n\t\t\t\tif ( this.setAttribute ) {\n\t\t\t\t\tthis.setAttribute( \"class\",\n\t\t\t\t\t\tclassName || value === false ?\n\t\t\t\t\t\t\"\" :\n\t\t\t\t\t\tdataPriv.get( this, \"__className__\" ) || \"\"\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\t\t} );\n\t},\n\n\thasClass: function( selector ) {\n\t\tvar className, elem,\n\t\t\ti = 0;\n\n\t\tclassName = \" \" + selector + \" \";\n\t\twhile ( ( elem = this[ i++ ] ) ) {\n\t\t\tif ( elem.nodeType === 1 &&\n\t\t\t\t( \" \" + stripAndCollapse( getClass( elem ) ) + \" \" ).indexOf( className ) > -1 ) {\n\t\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\n\t\treturn false;\n\t}\n} );\n\n\n\n\nvar rreturn = /\\r/g;\n\njQuery.fn.extend( {\n\tval: function( value ) {\n\t\tvar hooks, ret, valueIsFunction,\n\t\t\telem = this[ 0 ];\n\n\t\tif ( !arguments.length ) {\n\t\t\tif ( elem ) {\n\t\t\t\thooks = jQuery.valHooks[ elem.type ] ||\n\t\t\t\t\tjQuery.valHooks[ elem.nodeName.toLowerCase() ];\n\n\t\t\t\tif ( hooks &&\n\t\t\t\t\t\"get\" in hooks &&\n\t\t\t\t\t( ret = hooks.get( elem, \"value\" ) ) !== undefined\n\t\t\t\t) {\n\t\t\t\t\treturn ret;\n\t\t\t\t}\n\n\t\t\t\tret = elem.value;\n\n\t\t\t\t// Handle most common string cases\n\t\t\t\tif ( typeof ret === \"string\" ) {\n\t\t\t\t\treturn ret.replace( rreturn, \"\" );\n\t\t\t\t}\n\n\t\t\t\t// Handle cases where value is null/undef or number\n\t\t\t\treturn ret == null ? \"\" : ret;\n\t\t\t}\n\n\t\t\treturn;\n\t\t}\n\n\t\tvalueIsFunction = isFunction( value );\n\n\t\treturn this.each( function( i ) {\n\t\t\tvar val;\n\n\t\t\tif ( this.nodeType !== 1 ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif ( valueIsFunction ) {\n\t\t\t\tval = value.call( this, i, jQuery( this ).val() );\n\t\t\t} else {\n\t\t\t\tval = value;\n\t\t\t}\n\n\t\t\t// Treat null/undefined as \"\"; convert numbers to string\n\t\t\tif ( val == null ) {\n\t\t\t\tval = \"\";\n\n\t\t\t} else if ( typeof val === \"number\" ) {\n\t\t\t\tval += \"\";\n\n\t\t\t} else if ( Array.isArray( val ) ) {\n\t\t\t\tval = jQuery.map( val, function( value ) {\n\t\t\t\t\treturn value == null ? \"\" : value + \"\";\n\t\t\t\t} );\n\t\t\t}\n\n\t\t\thooks = jQuery.valHooks[ this.type ] || jQuery.valHooks[ this.nodeName.toLowerCase() ];\n\n\t\t\t// If set returns undefined, fall back to normal setting\n\t\t\tif ( !hooks || !( \"set\" in hooks ) || hooks.set( this, val, \"value\" ) === undefined ) {\n\t\t\t\tthis.value = val;\n\t\t\t}\n\t\t} );\n\t}\n} );\n\njQuery.extend( {\n\tvalHooks: {\n\t\toption: {\n\t\t\tget: function( elem ) {\n\n\t\t\t\tvar val = jQuery.find.attr( elem, \"value\" );\n\t\t\t\treturn val != null ?\n\t\t\t\t\tval :\n\n\t\t\t\t\t// Support: IE <=10 - 11 only\n\t\t\t\t\t// option.text throws exceptions (#14686, #14858)\n\t\t\t\t\t// Strip and collapse whitespace\n\t\t\t\t\t// https://html.spec.whatwg.org/#strip-and-collapse-whitespace\n\t\t\t\t\tstripAndCollapse( jQuery.text( elem ) );\n\t\t\t}\n\t\t},\n\t\tselect: {\n\t\t\tget: function( elem ) {\n\t\t\t\tvar value, option, i,\n\t\t\t\t\toptions = elem.options,\n\t\t\t\t\tindex = elem.selectedIndex,\n\t\t\t\t\tone = elem.type === \"select-one\",\n\t\t\t\t\tvalues = one ? null : [],\n\t\t\t\t\tmax = one ? index + 1 : options.length;\n\n\t\t\t\tif ( index < 0 ) {\n\t\t\t\t\ti = max;\n\n\t\t\t\t} else {\n\t\t\t\t\ti = one ? index : 0;\n\t\t\t\t}\n\n\t\t\t\t// Loop through all the selected options\n\t\t\t\tfor ( ; i < max; i++ ) {\n\t\t\t\t\toption = options[ i ];\n\n\t\t\t\t\t// Support: IE <=9 only\n\t\t\t\t\t// IE8-9 doesn't update selected after form reset (#2551)\n\t\t\t\t\tif ( ( option.selected || i === index ) &&\n\n\t\t\t\t\t\t\t// Don't return options that are disabled or in a disabled optgroup\n\t\t\t\t\t\t\t!option.disabled &&\n\t\t\t\t\t\t\t( !option.parentNode.disabled ||\n\t\t\t\t\t\t\t\t!nodeName( option.parentNode, \"optgroup\" ) ) ) {\n\n\t\t\t\t\t\t// Get the specific value for the option\n\t\t\t\t\t\tvalue = jQuery( option ).val();\n\n\t\t\t\t\t\t// We don't need an array for one selects\n\t\t\t\t\t\tif ( one ) {\n\t\t\t\t\t\t\treturn value;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Multi-Selects return an array\n\t\t\t\t\t\tvalues.push( value );\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\treturn values;\n\t\t\t},\n\n\t\t\tset: function( elem, value ) {\n\t\t\t\tvar optionSet, option,\n\t\t\t\t\toptions = elem.options,\n\t\t\t\t\tvalues = jQuery.makeArray( value ),\n\t\t\t\t\ti = options.length;\n\n\t\t\t\twhile ( i-- ) {\n\t\t\t\t\toption = options[ i ];\n\n\t\t\t\t\t/* eslint-disable no-cond-assign */\n\n\t\t\t\t\tif ( option.selected =\n\t\t\t\t\t\tjQuery.inArray( jQuery.valHooks.option.get( option ), values ) > -1\n\t\t\t\t\t) {\n\t\t\t\t\t\toptionSet = true;\n\t\t\t\t\t}\n\n\t\t\t\t\t/* eslint-enable no-cond-assign */\n\t\t\t\t}\n\n\t\t\t\t// Force browsers to behave consistently when non-matching value is set\n\t\t\t\tif ( !optionSet ) {\n\t\t\t\t\telem.selectedIndex = -1;\n\t\t\t\t}\n\t\t\t\treturn values;\n\t\t\t}\n\t\t}\n\t}\n} );\n\n// Radios and checkboxes getter/setter\njQuery.each( [ \"radio\", \"checkbox\" ], function() {\n\tjQuery.valHooks[ this ] = {\n\t\tset: function( elem, value ) {\n\t\t\tif ( Array.isArray( value ) ) {\n\t\t\t\treturn ( elem.checked = jQuery.inArray( jQuery( elem ).val(), value ) > -1 );\n\t\t\t}\n\t\t}\n\t};\n\tif ( !support.checkOn ) {\n\t\tjQuery.valHooks[ this ].get = function( elem ) {\n\t\t\treturn elem.getAttribute( \"value\" ) === null ? \"on\" : elem.value;\n\t\t};\n\t}\n} );\n\n\n\n\n// Return jQuery for attributes-only inclusion\n\n\nsupport.focusin = \"onfocusin\" in window;\n\n\nvar rfocusMorph = /^(?:focusinfocus|focusoutblur)$/,\n\tstopPropagationCallback = function( e ) {\n\t\te.stopPropagation();\n\t};\n\njQuery.extend( jQuery.event, {\n\n\ttrigger: function( event, data, elem, onlyHandlers ) {\n\n\t\tvar i, cur, tmp, bubbleType, ontype, handle, special, lastElement,\n\t\t\teventPath = [ elem || document ],\n\t\t\ttype = hasOwn.call( event, \"type\" ) ? event.type : event,\n\t\t\tnamespaces = hasOwn.call( event, \"namespace\" ) ? event.namespace.split( \".\" ) : [];\n\n\t\tcur = lastElement = tmp = elem = elem || document;\n\n\t\t// Don't do events on text and comment nodes\n\t\tif ( elem.nodeType === 3 || elem.nodeType === 8 ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// focus/blur morphs to focusin/out; ensure we're not firing them right now\n\t\tif ( rfocusMorph.test( type + jQuery.event.triggered ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\tif ( type.indexOf( \".\" ) > -1 ) {\n\n\t\t\t// Namespaced trigger; create a regexp to match event type in handle()\n\t\t\tnamespaces = type.split( \".\" );\n\t\t\ttype = namespaces.shift();\n\t\t\tnamespaces.sort();\n\t\t}\n\t\tontype = type.indexOf( \":\" ) < 0 && \"on\" + type;\n\n\t\t// Caller can pass in a jQuery.Event object, Object, or just an event type string\n\t\tevent = event[ jQuery.expando ] ?\n\t\t\tevent :\n\t\t\tnew jQuery.Event( type, typeof event === \"object\" && event );\n\n\t\t// Trigger bitmask: & 1 for native handlers; & 2 for jQuery (always true)\n\t\tevent.isTrigger = onlyHandlers ? 2 : 3;\n\t\tevent.namespace = namespaces.join( \".\" );\n\t\tevent.rnamespace = event.namespace ?\n\t\t\tnew RegExp( \"(^|\\\\.)\" + namespaces.join( \"\\\\.(?:.*\\\\.|)\" ) + \"(\\\\.|$)\" ) :\n\t\t\tnull;\n\n\t\t// Clean up the event in case it is being reused\n\t\tevent.result = undefined;\n\t\tif ( !event.target ) {\n\t\t\tevent.target = elem;\n\t\t}\n\n\t\t// Clone any incoming data and prepend the event, creating the handler arg list\n\t\tdata = data == null ?\n\t\t\t[ event ] :\n\t\t\tjQuery.makeArray( data, [ event ] );\n\n\t\t// Allow special events to draw outside the lines\n\t\tspecial = jQuery.event.special[ type ] || {};\n\t\tif ( !onlyHandlers && special.trigger && special.trigger.apply( elem, data ) === false ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Determine event propagation path in advance, per W3C events spec (#9951)\n\t\t// Bubble up to document, then to window; watch for a global ownerDocument var (#9724)\n\t\tif ( !onlyHandlers && !special.noBubble && !isWindow( elem ) ) {\n\n\t\t\tbubbleType = special.delegateType || type;\n\t\t\tif ( !rfocusMorph.test( bubbleType + type ) ) {\n\t\t\t\tcur = cur.parentNode;\n\t\t\t}\n\t\t\tfor ( ; cur; cur = cur.parentNode ) {\n\t\t\t\teventPath.push( cur );\n\t\t\t\ttmp = cur;\n\t\t\t}\n\n\t\t\t// Only add window if we got to document (e.g., not plain obj or detached DOM)\n\t\t\tif ( tmp === ( elem.ownerDocument || document ) ) {\n\t\t\t\teventPath.push( tmp.defaultView || tmp.parentWindow || window );\n\t\t\t}\n\t\t}\n\n\t\t// Fire handlers on the event path\n\t\ti = 0;\n\t\twhile ( ( cur = eventPath[ i++ ] ) && !event.isPropagationStopped() ) {\n\t\t\tlastElement = cur;\n\t\t\tevent.type = i > 1 ?\n\t\t\t\tbubbleType :\n\t\t\t\tspecial.bindType || type;\n\n\t\t\t// jQuery handler\n\t\t\thandle = (\n\t\t\t\t\tdataPriv.get( cur, \"events\" ) || Object.create( null )\n\t\t\t\t)[ event.type ] &&\n\t\t\t\tdataPriv.get( cur, \"handle\" );\n\t\t\tif ( handle ) {\n\t\t\t\thandle.apply( cur, data );\n\t\t\t}\n\n\t\t\t// Native handler\n\t\t\thandle = ontype && cur[ ontype ];\n\t\t\tif ( handle && handle.apply && acceptData( cur ) ) {\n\t\t\t\tevent.result = handle.apply( cur, data );\n\t\t\t\tif ( event.result === false ) {\n\t\t\t\t\tevent.preventDefault();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tevent.type = type;\n\n\t\t// If nobody prevented the default action, do it now\n\t\tif ( !onlyHandlers && !event.isDefaultPrevented() ) {\n\n\t\t\tif ( ( !special._default ||\n\t\t\t\tspecial._default.apply( eventPath.pop(), data ) === false ) &&\n\t\t\t\tacceptData( elem ) ) {\n\n\t\t\t\t// Call a native DOM method on the target with the same name as the event.\n\t\t\t\t// Don't do default actions on window, that's where global variables be (#6170)\n\t\t\t\tif ( ontype && isFunction( elem[ type ] ) && !isWindow( elem ) ) {\n\n\t\t\t\t\t// Don't re-trigger an onFOO event when we call its FOO() method\n\t\t\t\t\ttmp = elem[ ontype ];\n\n\t\t\t\t\tif ( tmp ) {\n\t\t\t\t\t\telem[ ontype ] = null;\n\t\t\t\t\t}\n\n\t\t\t\t\t// Prevent re-triggering of the same event, since we already bubbled it above\n\t\t\t\t\tjQuery.event.triggered = type;\n\n\t\t\t\t\tif ( event.isPropagationStopped() ) {\n\t\t\t\t\t\tlastElement.addEventListener( type, stopPropagationCallback );\n\t\t\t\t\t}\n\n\t\t\t\t\telem[ type ]();\n\n\t\t\t\t\tif ( event.isPropagationStopped() ) {\n\t\t\t\t\t\tlastElement.removeEventListener( type, stopPropagationCallback );\n\t\t\t\t\t}\n\n\t\t\t\t\tjQuery.event.triggered = undefined;\n\n\t\t\t\t\tif ( tmp ) {\n\t\t\t\t\t\telem[ ontype ] = tmp;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn event.result;\n\t},\n\n\t// Piggyback on a donor event to simulate a different one\n\t// Used only for `focus(in | out)` events\n\tsimulate: function( type, elem, event ) {\n\t\tvar e = jQuery.extend(\n\t\t\tnew jQuery.Event(),\n\t\t\tevent,\n\t\t\t{\n\t\t\t\ttype: type,\n\t\t\t\tisSimulated: true\n\t\t\t}\n\t\t);\n\n\t\tjQuery.event.trigger( e, null, elem );\n\t}\n\n} );\n\njQuery.fn.extend( {\n\n\ttrigger: function( type, data ) {\n\t\treturn this.each( function() {\n\t\t\tjQuery.event.trigger( type, data, this );\n\t\t} );\n\t},\n\ttriggerHandler: function( type, data ) {\n\t\tvar elem = this[ 0 ];\n\t\tif ( elem ) {\n\t\t\treturn jQuery.event.trigger( type, data, elem, true );\n\t\t}\n\t}\n} );\n\n\n// Support: Firefox <=44\n// Firefox doesn't have focus(in | out) events\n// Related ticket - https://bugzilla.mozilla.org/show_bug.cgi?id=687787\n//\n// Support: Chrome <=48 - 49, Safari <=9.0 - 9.1\n// focus(in | out) events fire after focus & blur events,\n// which is spec violation - http://www.w3.org/TR/DOM-Level-3-Events/#events-focusevent-event-order\n// Related ticket - https://bugs.chromium.org/p/chromium/issues/detail?id=449857\nif ( !support.focusin ) {\n\tjQuery.each( { focus: \"focusin\", blur: \"focusout\" }, function( orig, fix ) {\n\n\t\t// Attach a single capturing handler on the document while someone wants focusin/focusout\n\t\tvar handler = function( event ) {\n\t\t\tjQuery.event.simulate( fix, event.target, jQuery.event.fix( event ) );\n\t\t};\n\n\t\tjQuery.event.special[ fix ] = {\n\t\t\tsetup: function() {\n\n\t\t\t\t// Handle: regular nodes (via `this.ownerDocument`), window\n\t\t\t\t// (via `this.document`) & document (via `this`).\n\t\t\t\tvar doc = this.ownerDocument || this.document || this,\n\t\t\t\t\tattaches = dataPriv.access( doc, fix );\n\n\t\t\t\tif ( !attaches ) {\n\t\t\t\t\tdoc.addEventListener( orig, handler, true );\n\t\t\t\t}\n\t\t\t\tdataPriv.access( doc, fix, ( attaches || 0 ) + 1 );\n\t\t\t},\n\t\t\tteardown: function() {\n\t\t\t\tvar doc = this.ownerDocument || this.document || this,\n\t\t\t\t\tattaches = dataPriv.access( doc, fix ) - 1;\n\n\t\t\t\tif ( !attaches ) {\n\t\t\t\t\tdoc.removeEventListener( orig, handler, true );\n\t\t\t\t\tdataPriv.remove( doc, fix );\n\n\t\t\t\t} else {\n\t\t\t\t\tdataPriv.access( doc, fix, attaches );\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\t} );\n}\nvar location = window.location;\n\nvar nonce = { guid: Date.now() };\n\nvar rquery = ( /\\?/ );\n\n\n\n// Cross-browser xml parsing\njQuery.parseXML = function( data ) {\n\tvar xml;\n\tif ( !data || typeof data !== \"string\" ) {\n\t\treturn null;\n\t}\n\n\t// Support: IE 9 - 11 only\n\t// IE throws on parseFromString with invalid input.\n\ttry {\n\t\txml = ( new window.DOMParser() ).parseFromString( data, \"text/xml\" );\n\t} catch ( e ) {\n\t\txml = undefined;\n\t}\n\n\tif ( !xml || xml.getElementsByTagName( \"parsererror\" ).length ) {\n\t\tjQuery.error( \"Invalid XML: \" + data );\n\t}\n\treturn xml;\n};\n\n\nvar\n\trbracket = /\\[\\]$/,\n\trCRLF = /\\r?\\n/g,\n\trsubmitterTypes = /^(?:submit|button|image|reset|file)$/i,\n\trsubmittable = /^(?:input|select|textarea|keygen)/i;\n\nfunction buildParams( prefix, obj, traditional, add ) {\n\tvar name;\n\n\tif ( Array.isArray( obj ) ) {\n\n\t\t// Serialize array item.\n\t\tjQuery.each( obj, function( i, v ) {\n\t\t\tif ( traditional || rbracket.test( prefix ) ) {\n\n\t\t\t\t// Treat each array item as a scalar.\n\t\t\t\tadd( prefix, v );\n\n\t\t\t} else {\n\n\t\t\t\t// Item is non-scalar (array or object), encode its numeric index.\n\t\t\t\tbuildParams(\n\t\t\t\t\tprefix + \"[\" + ( typeof v === \"object\" && v != null ? i : \"\" ) + \"]\",\n\t\t\t\t\tv,\n\t\t\t\t\ttraditional,\n\t\t\t\t\tadd\n\t\t\t\t);\n\t\t\t}\n\t\t} );\n\n\t} else if ( !traditional && toType( obj ) === \"object\" ) {\n\n\t\t// Serialize object item.\n\t\tfor ( name in obj ) {\n\t\t\tbuildParams( prefix + \"[\" + name + \"]\", obj[ name ], traditional, add );\n\t\t}\n\n\t} else {\n\n\t\t// Serialize scalar item.\n\t\tadd( prefix, obj );\n\t}\n}\n\n// Serialize an array of form elements or a set of\n// key/values into a query string\njQuery.param = function( a, traditional ) {\n\tvar prefix,\n\t\ts = [],\n\t\tadd = function( key, valueOrFunction ) {\n\n\t\t\t// If value is a function, invoke it and use its return value\n\t\t\tvar value = isFunction( valueOrFunction ) ?\n\t\t\t\tvalueOrFunction() :\n\t\t\t\tvalueOrFunction;\n\n\t\t\ts[ s.length ] = encodeURIComponent( key ) + \"=\" +\n\t\t\t\tencodeURIComponent( value == null ? \"\" : value );\n\t\t};\n\n\tif ( a == null ) {\n\t\treturn \"\";\n\t}\n\n\t// If an array was passed in, assume that it is an array of form elements.\n\tif ( Array.isArray( a ) || ( a.jquery && !jQuery.isPlainObject( a ) ) ) {\n\n\t\t// Serialize the form elements\n\t\tjQuery.each( a, function() {\n\t\t\tadd( this.name, this.value );\n\t\t} );\n\n\t} else {\n\n\t\t// If traditional, encode the \"old\" way (the way 1.3.2 or older\n\t\t// did it), otherwise encode params recursively.\n\t\tfor ( prefix in a ) {\n\t\t\tbuildParams( prefix, a[ prefix ], traditional, add );\n\t\t}\n\t}\n\n\t// Return the resulting serialization\n\treturn s.join( \"&\" );\n};\n\njQuery.fn.extend( {\n\tserialize: function() {\n\t\treturn jQuery.param( this.serializeArray() );\n\t},\n\tserializeArray: function() {\n\t\treturn this.map( function() {\n\n\t\t\t// Can add propHook for \"elements\" to filter or add form elements\n\t\t\tvar elements = jQuery.prop( this, \"elements\" );\n\t\t\treturn elements ? jQuery.makeArray( elements ) : this;\n\t\t} )\n\t\t.filter( function() {\n\t\t\tvar type = this.type;\n\n\t\t\t// Use .is( \":disabled\" ) so that fieldset[disabled] works\n\t\t\treturn this.name && !jQuery( this ).is( \":disabled\" ) &&\n\t\t\t\trsubmittable.test( this.nodeName ) && !rsubmitterTypes.test( type ) &&\n\t\t\t\t( this.checked || !rcheckableType.test( type ) );\n\t\t} )\n\t\t.map( function( _i, elem ) {\n\t\t\tvar val = jQuery( this ).val();\n\n\t\t\tif ( val == null ) {\n\t\t\t\treturn null;\n\t\t\t}\n\n\t\t\tif ( Array.isArray( val ) ) {\n\t\t\t\treturn jQuery.map( val, function( val ) {\n\t\t\t\t\treturn { name: elem.name, value: val.replace( rCRLF, \"\\r\\n\" ) };\n\t\t\t\t} );\n\t\t\t}\n\n\t\t\treturn { name: elem.name, value: val.replace( rCRLF, \"\\r\\n\" ) };\n\t\t} ).get();\n\t}\n} );\n\n\nvar\n\tr20 = /%20/g,\n\trhash = /#.*$/,\n\trantiCache = /([?&])_=[^&]*/,\n\trheaders = /^(.*?):[ \\t]*([^\\r\\n]*)$/mg,\n\n\t// #7653, #8125, #8152: local protocol detection\n\trlocalProtocol = /^(?:about|app|app-storage|.+-extension|file|res|widget):$/,\n\trnoContent = /^(?:GET|HEAD)$/,\n\trprotocol = /^\\/\\//,\n\n\t/* Prefilters\n\t * 1) They are useful to introduce custom dataTypes (see ajax/jsonp.js for an example)\n\t * 2) These are called:\n\t *    - BEFORE asking for a transport\n\t *    - AFTER param serialization (s.data is a string if s.processData is true)\n\t * 3) key is the dataType\n\t * 4) the catchall symbol \"*\" can be used\n\t * 5) execution will start with transport dataType and THEN continue down to \"*\" if needed\n\t */\n\tprefilters = {},\n\n\t/* Transports bindings\n\t * 1) key is the dataType\n\t * 2) the catchall symbol \"*\" can be used\n\t * 3) selection will start with transport dataType and THEN go to \"*\" if needed\n\t */\n\ttransports = {},\n\n\t// Avoid comment-prolog char sequence (#10098); must appease lint and evade compression\n\tallTypes = \"*/\".concat( \"*\" ),\n\n\t// Anchor tag for parsing the document origin\n\toriginAnchor = document.createElement( \"a\" );\n\toriginAnchor.href = location.href;\n\n// Base \"constructor\" for jQuery.ajaxPrefilter and jQuery.ajaxTransport\nfunction addToPrefiltersOrTransports( structure ) {\n\n\t// dataTypeExpression is optional and defaults to \"*\"\n\treturn function( dataTypeExpression, func ) {\n\n\t\tif ( typeof dataTypeExpression !== \"string\" ) {\n\t\t\tfunc = dataTypeExpression;\n\t\t\tdataTypeExpression = \"*\";\n\t\t}\n\n\t\tvar dataType,\n\t\t\ti = 0,\n\t\t\tdataTypes = dataTypeExpression.toLowerCase().match( rnothtmlwhite ) || [];\n\n\t\tif ( isFunction( func ) ) {\n\n\t\t\t// For each dataType in the dataTypeExpression\n\t\t\twhile ( ( dataType = dataTypes[ i++ ] ) ) {\n\n\t\t\t\t// Prepend if requested\n\t\t\t\tif ( dataType[ 0 ] === \"+\" ) {\n\t\t\t\t\tdataType = dataType.slice( 1 ) || \"*\";\n\t\t\t\t\t( structure[ dataType ] = structure[ dataType ] || [] ).unshift( func );\n\n\t\t\t\t// Otherwise append\n\t\t\t\t} else {\n\t\t\t\t\t( structure[ dataType ] = structure[ dataType ] || [] ).push( func );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t};\n}\n\n// Base inspection function for prefilters and transports\nfunction inspectPrefiltersOrTransports( structure, options, originalOptions, jqXHR ) {\n\n\tvar inspected = {},\n\t\tseekingTransport = ( structure === transports );\n\n\tfunction inspect( dataType ) {\n\t\tvar selected;\n\t\tinspected[ dataType ] = true;\n\t\tjQuery.each( structure[ dataType ] || [], function( _, prefilterOrFactory ) {\n\t\t\tvar dataTypeOrTransport = prefilterOrFactory( options, originalOptions, jqXHR );\n\t\t\tif ( typeof dataTypeOrTransport === \"string\" &&\n\t\t\t\t!seekingTransport && !inspected[ dataTypeOrTransport ] ) {\n\n\t\t\t\toptions.dataTypes.unshift( dataTypeOrTransport );\n\t\t\t\tinspect( dataTypeOrTransport );\n\t\t\t\treturn false;\n\t\t\t} else if ( seekingTransport ) {\n\t\t\t\treturn !( selected = dataTypeOrTransport );\n\t\t\t}\n\t\t} );\n\t\treturn selected;\n\t}\n\n\treturn inspect( options.dataTypes[ 0 ] ) || !inspected[ \"*\" ] && inspect( \"*\" );\n}\n\n// A special extend for ajax options\n// that takes \"flat\" options (not to be deep extended)\n// Fixes #9887\nfunction ajaxExtend( target, src ) {\n\tvar key, deep,\n\t\tflatOptions = jQuery.ajaxSettings.flatOptions || {};\n\n\tfor ( key in src ) {\n\t\tif ( src[ key ] !== undefined ) {\n\t\t\t( flatOptions[ key ] ? target : ( deep || ( deep = {} ) ) )[ key ] = src[ key ];\n\t\t}\n\t}\n\tif ( deep ) {\n\t\tjQuery.extend( true, target, deep );\n\t}\n\n\treturn target;\n}\n\n/* Handles responses to an ajax request:\n * - finds the right dataType (mediates between content-type and expected dataType)\n * - returns the corresponding response\n */\nfunction ajaxHandleResponses( s, jqXHR, responses ) {\n\n\tvar ct, type, finalDataType, firstDataType,\n\t\tcontents = s.contents,\n\t\tdataTypes = s.dataTypes;\n\n\t// Remove auto dataType and get content-type in the process\n\twhile ( dataTypes[ 0 ] === \"*\" ) {\n\t\tdataTypes.shift();\n\t\tif ( ct === undefined ) {\n\t\t\tct = s.mimeType || jqXHR.getResponseHeader( \"Content-Type\" );\n\t\t}\n\t}\n\n\t// Check if we're dealing with a known content-type\n\tif ( ct ) {\n\t\tfor ( type in contents ) {\n\t\t\tif ( contents[ type ] && contents[ type ].test( ct ) ) {\n\t\t\t\tdataTypes.unshift( type );\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\n\t// Check to see if we have a response for the expected dataType\n\tif ( dataTypes[ 0 ] in responses ) {\n\t\tfinalDataType = dataTypes[ 0 ];\n\t} else {\n\n\t\t// Try convertible dataTypes\n\t\tfor ( type in responses ) {\n\t\t\tif ( !dataTypes[ 0 ] || s.converters[ type + \" \" + dataTypes[ 0 ] ] ) {\n\t\t\t\tfinalDataType = type;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tif ( !firstDataType ) {\n\t\t\t\tfirstDataType = type;\n\t\t\t}\n\t\t}\n\n\t\t// Or just use first one\n\t\tfinalDataType = finalDataType || firstDataType;\n\t}\n\n\t// If we found a dataType\n\t// We add the dataType to the list if needed\n\t// and return the corresponding response\n\tif ( finalDataType ) {\n\t\tif ( finalDataType !== dataTypes[ 0 ] ) {\n\t\t\tdataTypes.unshift( finalDataType );\n\t\t}\n\t\treturn responses[ finalDataType ];\n\t}\n}\n\n/* Chain conversions given the request and the original response\n * Also sets the responseXXX fields on the jqXHR instance\n */\nfunction ajaxConvert( s, response, jqXHR, isSuccess ) {\n\tvar conv2, current, conv, tmp, prev,\n\t\tconverters = {},\n\n\t\t// Work with a copy of dataTypes in case we need to modify it for conversion\n\t\tdataTypes = s.dataTypes.slice();\n\n\t// Create converters map with lowercased keys\n\tif ( dataTypes[ 1 ] ) {\n\t\tfor ( conv in s.converters ) {\n\t\t\tconverters[ conv.toLowerCase() ] = s.converters[ conv ];\n\t\t}\n\t}\n\n\tcurrent = dataTypes.shift();\n\n\t// Convert to each sequential dataType\n\twhile ( current ) {\n\n\t\tif ( s.responseFields[ current ] ) {\n\t\t\tjqXHR[ s.responseFields[ current ] ] = response;\n\t\t}\n\n\t\t// Apply the dataFilter if provided\n\t\tif ( !prev && isSuccess && s.dataFilter ) {\n\t\t\tresponse = s.dataFilter( response, s.dataType );\n\t\t}\n\n\t\tprev = current;\n\t\tcurrent = dataTypes.shift();\n\n\t\tif ( current ) {\n\n\t\t\t// There's only work to do if current dataType is non-auto\n\t\t\tif ( current === \"*\" ) {\n\n\t\t\t\tcurrent = prev;\n\n\t\t\t// Convert response if prev dataType is non-auto and differs from current\n\t\t\t} else if ( prev !== \"*\" && prev !== current ) {\n\n\t\t\t\t// Seek a direct converter\n\t\t\t\tconv = converters[ prev + \" \" + current ] || converters[ \"* \" + current ];\n\n\t\t\t\t// If none found, seek a pair\n\t\t\t\tif ( !conv ) {\n\t\t\t\t\tfor ( conv2 in converters ) {\n\n\t\t\t\t\t\t// If conv2 outputs current\n\t\t\t\t\t\ttmp = conv2.split( \" \" );\n\t\t\t\t\t\tif ( tmp[ 1 ] === current ) {\n\n\t\t\t\t\t\t\t// If prev can be converted to accepted input\n\t\t\t\t\t\t\tconv = converters[ prev + \" \" + tmp[ 0 ] ] ||\n\t\t\t\t\t\t\t\tconverters[ \"* \" + tmp[ 0 ] ];\n\t\t\t\t\t\t\tif ( conv ) {\n\n\t\t\t\t\t\t\t\t// Condense equivalence converters\n\t\t\t\t\t\t\t\tif ( conv === true ) {\n\t\t\t\t\t\t\t\t\tconv = converters[ conv2 ];\n\n\t\t\t\t\t\t\t\t// Otherwise, insert the intermediate dataType\n\t\t\t\t\t\t\t\t} else if ( converters[ conv2 ] !== true ) {\n\t\t\t\t\t\t\t\t\tcurrent = tmp[ 0 ];\n\t\t\t\t\t\t\t\t\tdataTypes.unshift( tmp[ 1 ] );\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Apply converter (if not an equivalence)\n\t\t\t\tif ( conv !== true ) {\n\n\t\t\t\t\t// Unless errors are allowed to bubble, catch and return them\n\t\t\t\t\tif ( conv && s.throws ) {\n\t\t\t\t\t\tresponse = conv( response );\n\t\t\t\t\t} else {\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\tresponse = conv( response );\n\t\t\t\t\t\t} catch ( e ) {\n\t\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\t\tstate: \"parsererror\",\n\t\t\t\t\t\t\t\terror: conv ? e : \"No conversion from \" + prev + \" to \" + current\n\t\t\t\t\t\t\t};\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn { state: \"success\", data: response };\n}\n\njQuery.extend( {\n\n\t// Counter for holding the number of active queries\n\tactive: 0,\n\n\t// Last-Modified header cache for next request\n\tlastModified: {},\n\tetag: {},\n\n\tajaxSettings: {\n\t\turl: location.href,\n\t\ttype: \"GET\",\n\t\tisLocal: rlocalProtocol.test( location.protocol ),\n\t\tglobal: true,\n\t\tprocessData: true,\n\t\tasync: true,\n\t\tcontentType: \"application/x-www-form-urlencoded; charset=UTF-8\",\n\n\t\t/*\n\t\ttimeout: 0,\n\t\tdata: null,\n\t\tdataType: null,\n\t\tusername: null,\n\t\tpassword: null,\n\t\tcache: null,\n\t\tthrows: false,\n\t\ttraditional: false,\n\t\theaders: {},\n\t\t*/\n\n\t\taccepts: {\n\t\t\t\"*\": allTypes,\n\t\t\ttext: \"text/plain\",\n\t\t\thtml: \"text/html\",\n\t\t\txml: \"application/xml, text/xml\",\n\t\t\tjson: \"application/json, text/javascript\"\n\t\t},\n\n\t\tcontents: {\n\t\t\txml: /\\bxml\\b/,\n\t\t\thtml: /\\bhtml/,\n\t\t\tjson: /\\bjson\\b/\n\t\t},\n\n\t\tresponseFields: {\n\t\t\txml: \"responseXML\",\n\t\t\ttext: \"responseText\",\n\t\t\tjson: \"responseJSON\"\n\t\t},\n\n\t\t// Data converters\n\t\t// Keys separate source (or catchall \"*\") and destination types with a single space\n\t\tconverters: {\n\n\t\t\t// Convert anything to text\n\t\t\t\"* text\": String,\n\n\t\t\t// Text to html (true = no transformation)\n\t\t\t\"text html\": true,\n\n\t\t\t// Evaluate text as a json expression\n\t\t\t\"text json\": JSON.parse,\n\n\t\t\t// Parse text as xml\n\t\t\t\"text xml\": jQuery.parseXML\n\t\t},\n\n\t\t// For options that shouldn't be deep extended:\n\t\t// you can add your own custom options here if\n\t\t// and when you create one that shouldn't be\n\t\t// deep extended (see ajaxExtend)\n\t\tflatOptions: {\n\t\t\turl: true,\n\t\t\tcontext: true\n\t\t}\n\t},\n\n\t// Creates a full fledged settings object into target\n\t// with both ajaxSettings and settings fields.\n\t// If target is omitted, writes into ajaxSettings.\n\tajaxSetup: function( target, settings ) {\n\t\treturn settings ?\n\n\t\t\t// Building a settings object\n\t\t\tajaxExtend( ajaxExtend( target, jQuery.ajaxSettings ), settings ) :\n\n\t\t\t// Extending ajaxSettings\n\t\t\tajaxExtend( jQuery.ajaxSettings, target );\n\t},\n\n\tajaxPrefilter: addToPrefiltersOrTransports( prefilters ),\n\tajaxTransport: addToPrefiltersOrTransports( transports ),\n\n\t// Main method\n\tajax: function( url, options ) {\n\n\t\t// If url is an object, simulate pre-1.5 signature\n\t\tif ( typeof url === \"object\" ) {\n\t\t\toptions = url;\n\t\t\turl = undefined;\n\t\t}\n\n\t\t// Force options to be an object\n\t\toptions = options || {};\n\n\t\tvar transport,\n\n\t\t\t// URL without anti-cache param\n\t\t\tcacheURL,\n\n\t\t\t// Response headers\n\t\t\tresponseHeadersString,\n\t\t\tresponseHeaders,\n\n\t\t\t// timeout handle\n\t\t\ttimeoutTimer,\n\n\t\t\t// Url cleanup var\n\t\t\turlAnchor,\n\n\t\t\t// Request state (becomes false upon send and true upon completion)\n\t\t\tcompleted,\n\n\t\t\t// To know if global events are to be dispatched\n\t\t\tfireGlobals,\n\n\t\t\t// Loop variable\n\t\t\ti,\n\n\t\t\t// uncached part of the url\n\t\t\tuncached,\n\n\t\t\t// Create the final options object\n\t\t\ts = jQuery.ajaxSetup( {}, options ),\n\n\t\t\t// Callbacks context\n\t\t\tcallbackContext = s.context || s,\n\n\t\t\t// Context for global events is callbackContext if it is a DOM node or jQuery collection\n\t\t\tglobalEventContext = s.context &&\n\t\t\t\t( callbackContext.nodeType || callbackContext.jquery ) ?\n\t\t\t\t\tjQuery( callbackContext ) :\n\t\t\t\t\tjQuery.event,\n\n\t\t\t// Deferreds\n\t\t\tdeferred = jQuery.Deferred(),\n\t\t\tcompleteDeferred = jQuery.Callbacks( \"once memory\" ),\n\n\t\t\t// Status-dependent callbacks\n\t\t\tstatusCode = s.statusCode || {},\n\n\t\t\t// Headers (they are sent all at once)\n\t\t\trequestHeaders = {},\n\t\t\trequestHeadersNames = {},\n\n\t\t\t// Default abort message\n\t\t\tstrAbort = \"canceled\",\n\n\t\t\t// Fake xhr\n\t\t\tjqXHR = {\n\t\t\t\treadyState: 0,\n\n\t\t\t\t// Builds headers hashtable if needed\n\t\t\t\tgetResponseHeader: function( key ) {\n\t\t\t\t\tvar match;\n\t\t\t\t\tif ( completed ) {\n\t\t\t\t\t\tif ( !responseHeaders ) {\n\t\t\t\t\t\t\tresponseHeaders = {};\n\t\t\t\t\t\t\twhile ( ( match = rheaders.exec( responseHeadersString ) ) ) {\n\t\t\t\t\t\t\t\tresponseHeaders[ match[ 1 ].toLowerCase() + \" \" ] =\n\t\t\t\t\t\t\t\t\t( responseHeaders[ match[ 1 ].toLowerCase() + \" \" ] || [] )\n\t\t\t\t\t\t\t\t\t\t.concat( match[ 2 ] );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tmatch = responseHeaders[ key.toLowerCase() + \" \" ];\n\t\t\t\t\t}\n\t\t\t\t\treturn match == null ? null : match.join( \", \" );\n\t\t\t\t},\n\n\t\t\t\t// Raw string\n\t\t\t\tgetAllResponseHeaders: function() {\n\t\t\t\t\treturn completed ? responseHeadersString : null;\n\t\t\t\t},\n\n\t\t\t\t// Caches the header\n\t\t\t\tsetRequestHeader: function( name, value ) {\n\t\t\t\t\tif ( completed == null ) {\n\t\t\t\t\t\tname = requestHeadersNames[ name.toLowerCase() ] =\n\t\t\t\t\t\t\trequestHeadersNames[ name.toLowerCase() ] || name;\n\t\t\t\t\t\trequestHeaders[ name ] = value;\n\t\t\t\t\t}\n\t\t\t\t\treturn this;\n\t\t\t\t},\n\n\t\t\t\t// Overrides response content-type header\n\t\t\t\toverrideMimeType: function( type ) {\n\t\t\t\t\tif ( completed == null ) {\n\t\t\t\t\t\ts.mimeType = type;\n\t\t\t\t\t}\n\t\t\t\t\treturn this;\n\t\t\t\t},\n\n\t\t\t\t// Status-dependent callbacks\n\t\t\t\tstatusCode: function( map ) {\n\t\t\t\t\tvar code;\n\t\t\t\t\tif ( map ) {\n\t\t\t\t\t\tif ( completed ) {\n\n\t\t\t\t\t\t\t// Execute the appropriate callbacks\n\t\t\t\t\t\t\tjqXHR.always( map[ jqXHR.status ] );\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t// Lazy-add the new callbacks in a way that preserves old ones\n\t\t\t\t\t\t\tfor ( code in map ) {\n\t\t\t\t\t\t\t\tstatusCode[ code ] = [ statusCode[ code ], map[ code ] ];\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\treturn this;\n\t\t\t\t},\n\n\t\t\t\t// Cancel the request\n\t\t\t\tabort: function( statusText ) {\n\t\t\t\t\tvar finalText = statusText || strAbort;\n\t\t\t\t\tif ( transport ) {\n\t\t\t\t\t\ttransport.abort( finalText );\n\t\t\t\t\t}\n\t\t\t\t\tdone( 0, finalText );\n\t\t\t\t\treturn this;\n\t\t\t\t}\n\t\t\t};\n\n\t\t// Attach deferreds\n\t\tdeferred.promise( jqXHR );\n\n\t\t// Add protocol if not provided (prefilters might expect it)\n\t\t// Handle falsy url in the settings object (#10093: consistency with old signature)\n\t\t// We also use the url parameter if available\n\t\ts.url = ( ( url || s.url || location.href ) + \"\" )\n\t\t\t.replace( rprotocol, location.protocol + \"//\" );\n\n\t\t// Alias method option to type as per ticket #12004\n\t\ts.type = options.method || options.type || s.method || s.type;\n\n\t\t// Extract dataTypes list\n\t\ts.dataTypes = ( s.dataType || \"*\" ).toLowerCase().match( rnothtmlwhite ) || [ \"\" ];\n\n\t\t// A cross-domain request is in order when the origin doesn't match the current origin.\n\t\tif ( s.crossDomain == null ) {\n\t\t\turlAnchor = document.createElement( \"a\" );\n\n\t\t\t// Support: IE <=8 - 11, Edge 12 - 15\n\t\t\t// IE throws exception on accessing the href property if url is malformed,\n\t\t\t// e.g. http://example.com:80x/\n\t\t\ttry {\n\t\t\t\turlAnchor.href = s.url;\n\n\t\t\t\t// Support: IE <=8 - 11 only\n\t\t\t\t// Anchor's host property isn't correctly set when s.url is relative\n\t\t\t\turlAnchor.href = urlAnchor.href;\n\t\t\t\ts.crossDomain = originAnchor.protocol + \"//\" + originAnchor.host !==\n\t\t\t\t\turlAnchor.protocol + \"//\" + urlAnchor.host;\n\t\t\t} catch ( e ) {\n\n\t\t\t\t// If there is an error parsing the URL, assume it is crossDomain,\n\t\t\t\t// it can be rejected by the transport if it is invalid\n\t\t\t\ts.crossDomain = true;\n\t\t\t}\n\t\t}\n\n\t\t// Convert data if not already a string\n\t\tif ( s.data && s.processData && typeof s.data !== \"string\" ) {\n\t\t\ts.data = jQuery.param( s.data, s.traditional );\n\t\t}\n\n\t\t// Apply prefilters\n\t\tinspectPrefiltersOrTransports( prefilters, s, options, jqXHR );\n\n\t\t// If request was aborted inside a prefilter, stop there\n\t\tif ( completed ) {\n\t\t\treturn jqXHR;\n\t\t}\n\n\t\t// We can fire global events as of now if asked to\n\t\t// Don't fire events if jQuery.event is undefined in an AMD-usage scenario (#15118)\n\t\tfireGlobals = jQuery.event && s.global;\n\n\t\t// Watch for a new set of requests\n\t\tif ( fireGlobals && jQuery.active++ === 0 ) {\n\t\t\tjQuery.event.trigger( \"ajaxStart\" );\n\t\t}\n\n\t\t// Uppercase the type\n\t\ts.type = s.type.toUpperCase();\n\n\t\t// Determine if request has content\n\t\ts.hasContent = !rnoContent.test( s.type );\n\n\t\t// Save the URL in case we're toying with the If-Modified-Since\n\t\t// and/or If-None-Match header later on\n\t\t// Remove hash to simplify url manipulation\n\t\tcacheURL = s.url.replace( rhash, \"\" );\n\n\t\t// More options handling for requests with no content\n\t\tif ( !s.hasContent ) {\n\n\t\t\t// Remember the hash so we can put it back\n\t\t\tuncached = s.url.slice( cacheURL.length );\n\n\t\t\t// If data is available and should be processed, append data to url\n\t\t\tif ( s.data && ( s.processData || typeof s.data === \"string\" ) ) {\n\t\t\t\tcacheURL += ( rquery.test( cacheURL ) ? \"&\" : \"?\" ) + s.data;\n\n\t\t\t\t// #9682: remove data so that it's not used in an eventual retry\n\t\t\t\tdelete s.data;\n\t\t\t}\n\n\t\t\t// Add or update anti-cache param if needed\n\t\t\tif ( s.cache === false ) {\n\t\t\t\tcacheURL = cacheURL.replace( rantiCache, \"$1\" );\n\t\t\t\tuncached = ( rquery.test( cacheURL ) ? \"&\" : \"?\" ) + \"_=\" + ( nonce.guid++ ) +\n\t\t\t\t\tuncached;\n\t\t\t}\n\n\t\t\t// Put hash and anti-cache on the URL that will be requested (gh-1732)\n\t\t\ts.url = cacheURL + uncached;\n\n\t\t// Change '%20' to '+' if this is encoded form body content (gh-2658)\n\t\t} else if ( s.data && s.processData &&\n\t\t\t( s.contentType || \"\" ).indexOf( \"application/x-www-form-urlencoded\" ) === 0 ) {\n\t\t\ts.data = s.data.replace( r20, \"+\" );\n\t\t}\n\n\t\t// Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.\n\t\tif ( s.ifModified ) {\n\t\t\tif ( jQuery.lastModified[ cacheURL ] ) {\n\t\t\t\tjqXHR.setRequestHeader( \"If-Modified-Since\", jQuery.lastModified[ cacheURL ] );\n\t\t\t}\n\t\t\tif ( jQuery.etag[ cacheURL ] ) {\n\t\t\t\tjqXHR.setRequestHeader( \"If-None-Match\", jQuery.etag[ cacheURL ] );\n\t\t\t}\n\t\t}\n\n\t\t// Set the correct header, if data is being sent\n\t\tif ( s.data && s.hasContent && s.contentType !== false || options.contentType ) {\n\t\t\tjqXHR.setRequestHeader( \"Content-Type\", s.contentType );\n\t\t}\n\n\t\t// Set the Accepts header for the server, depending on the dataType\n\t\tjqXHR.setRequestHeader(\n\t\t\t\"Accept\",\n\t\t\ts.dataTypes[ 0 ] && s.accepts[ s.dataTypes[ 0 ] ] ?\n\t\t\t\ts.accepts[ s.dataTypes[ 0 ] ] +\n\t\t\t\t\t( s.dataTypes[ 0 ] !== \"*\" ? \", \" + allTypes + \"; q=0.01\" : \"\" ) :\n\t\t\t\ts.accepts[ \"*\" ]\n\t\t);\n\n\t\t// Check for headers option\n\t\tfor ( i in s.headers ) {\n\t\t\tjqXHR.setRequestHeader( i, s.headers[ i ] );\n\t\t}\n\n\t\t// Allow custom headers/mimetypes and early abort\n\t\tif ( s.beforeSend &&\n\t\t\t( s.beforeSend.call( callbackContext, jqXHR, s ) === false || completed ) ) {\n\n\t\t\t// Abort if not done already and return\n\t\t\treturn jqXHR.abort();\n\t\t}\n\n\t\t// Aborting is no longer a cancellation\n\t\tstrAbort = \"abort\";\n\n\t\t// Install callbacks on deferreds\n\t\tcompleteDeferred.add( s.complete );\n\t\tjqXHR.done( s.success );\n\t\tjqXHR.fail( s.error );\n\n\t\t// Get transport\n\t\ttransport = inspectPrefiltersOrTransports( transports, s, options, jqXHR );\n\n\t\t// If no transport, we auto-abort\n\t\tif ( !transport ) {\n\t\t\tdone( -1, \"No Transport\" );\n\t\t} else {\n\t\t\tjqXHR.readyState = 1;\n\n\t\t\t// Send global event\n\t\t\tif ( fireGlobals ) {\n\t\t\t\tglobalEventContext.trigger( \"ajaxSend\", [ jqXHR, s ] );\n\t\t\t}\n\n\t\t\t// If request was aborted inside ajaxSend, stop there\n\t\t\tif ( completed ) {\n\t\t\t\treturn jqXHR;\n\t\t\t}\n\n\t\t\t// Timeout\n\t\t\tif ( s.async && s.timeout > 0 ) {\n\t\t\t\ttimeoutTimer = window.setTimeout( function() {\n\t\t\t\t\tjqXHR.abort( \"timeout\" );\n\t\t\t\t}, s.timeout );\n\t\t\t}\n\n\t\t\ttry {\n\t\t\t\tcompleted = false;\n\t\t\t\ttransport.send( requestHeaders, done );\n\t\t\t} catch ( e ) {\n\n\t\t\t\t// Rethrow post-completion exceptions\n\t\t\t\tif ( completed ) {\n\t\t\t\t\tthrow e;\n\t\t\t\t}\n\n\t\t\t\t// Propagate others as results\n\t\t\t\tdone( -1, e );\n\t\t\t}\n\t\t}\n\n\t\t// Callback for when everything is done\n\t\tfunction done( status, nativeStatusText, responses, headers ) {\n\t\t\tvar isSuccess, success, error, response, modified,\n\t\t\t\tstatusText = nativeStatusText;\n\n\t\t\t// Ignore repeat invocations\n\t\t\tif ( completed ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tcompleted = true;\n\n\t\t\t// Clear timeout if it exists\n\t\t\tif ( timeoutTimer ) {\n\t\t\t\twindow.clearTimeout( timeoutTimer );\n\t\t\t}\n\n\t\t\t// Dereference transport for early garbage collection\n\t\t\t// (no matter how long the jqXHR object will be used)\n\t\t\ttransport = undefined;\n\n\t\t\t// Cache response headers\n\t\t\tresponseHeadersString = headers || \"\";\n\n\t\t\t// Set readyState\n\t\t\tjqXHR.readyState = status > 0 ? 4 : 0;\n\n\t\t\t// Determine if successful\n\t\t\tisSuccess = status >= 200 && status < 300 || status === 304;\n\n\t\t\t// Get response data\n\t\t\tif ( responses ) {\n\t\t\t\tresponse = ajaxHandleResponses( s, jqXHR, responses );\n\t\t\t}\n\n\t\t\t// Use a noop converter for missing script\n\t\t\tif ( !isSuccess && jQuery.inArray( \"script\", s.dataTypes ) > -1 ) {\n\t\t\t\ts.converters[ \"text script\" ] = function() {};\n\t\t\t}\n\n\t\t\t// Convert no matter what (that way responseXXX fields are always set)\n\t\t\tresponse = ajaxConvert( s, response, jqXHR, isSuccess );\n\n\t\t\t// If successful, handle type chaining\n\t\t\tif ( isSuccess ) {\n\n\t\t\t\t// Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.\n\t\t\t\tif ( s.ifModified ) {\n\t\t\t\t\tmodified = jqXHR.getResponseHeader( \"Last-Modified\" );\n\t\t\t\t\tif ( modified ) {\n\t\t\t\t\t\tjQuery.lastModified[ cacheURL ] = modified;\n\t\t\t\t\t}\n\t\t\t\t\tmodified = jqXHR.getResponseHeader( \"etag\" );\n\t\t\t\t\tif ( modified ) {\n\t\t\t\t\t\tjQuery.etag[ cacheURL ] = modified;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// if no content\n\t\t\t\tif ( status === 204 || s.type === \"HEAD\" ) {\n\t\t\t\t\tstatusText = \"nocontent\";\n\n\t\t\t\t// if not modified\n\t\t\t\t} else if ( status === 304 ) {\n\t\t\t\t\tstatusText = \"notmodified\";\n\n\t\t\t\t// If we have data, let's convert it\n\t\t\t\t} else {\n\t\t\t\t\tstatusText = response.state;\n\t\t\t\t\tsuccess = response.data;\n\t\t\t\t\terror = response.error;\n\t\t\t\t\tisSuccess = !error;\n\t\t\t\t}\n\t\t\t} else {\n\n\t\t\t\t// Extract error from statusText and normalize for non-aborts\n\t\t\t\terror = statusText;\n\t\t\t\tif ( status || !statusText ) {\n\t\t\t\t\tstatusText = \"error\";\n\t\t\t\t\tif ( status < 0 ) {\n\t\t\t\t\t\tstatus = 0;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Set data for the fake xhr object\n\t\t\tjqXHR.status = status;\n\t\t\tjqXHR.statusText = ( nativeStatusText || statusText ) + \"\";\n\n\t\t\t// Success/Error\n\t\t\tif ( isSuccess ) {\n\t\t\t\tdeferred.resolveWith( callbackContext, [ success, statusText, jqXHR ] );\n\t\t\t} else {\n\t\t\t\tdeferred.rejectWith( callbackContext, [ jqXHR, statusText, error ] );\n\t\t\t}\n\n\t\t\t// Status-dependent callbacks\n\t\t\tjqXHR.statusCode( statusCode );\n\t\t\tstatusCode = undefined;\n\n\t\t\tif ( fireGlobals ) {\n\t\t\t\tglobalEventContext.trigger( isSuccess ? \"ajaxSuccess\" : \"ajaxError\",\n\t\t\t\t\t[ jqXHR, s, isSuccess ? success : error ] );\n\t\t\t}\n\n\t\t\t// Complete\n\t\t\tcompleteDeferred.fireWith( callbackContext, [ jqXHR, statusText ] );\n\n\t\t\tif ( fireGlobals ) {\n\t\t\t\tglobalEventContext.trigger( \"ajaxComplete\", [ jqXHR, s ] );\n\n\t\t\t\t// Handle the global AJAX counter\n\t\t\t\tif ( !( --jQuery.active ) ) {\n\t\t\t\t\tjQuery.event.trigger( \"ajaxStop\" );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn jqXHR;\n\t},\n\n\tgetJSON: function( url, data, callback ) {\n\t\treturn jQuery.get( url, data, callback, \"json\" );\n\t},\n\n\tgetScript: function( url, callback ) {\n\t\treturn jQuery.get( url, undefined, callback, \"script\" );\n\t}\n} );\n\njQuery.each( [ \"get\", \"post\" ], function( _i, method ) {\n\tjQuery[ method ] = function( url, data, callback, type ) {\n\n\t\t// Shift arguments if data argument was omitted\n\t\tif ( isFunction( data ) ) {\n\t\t\ttype = type || callback;\n\t\t\tcallback = data;\n\t\t\tdata = undefined;\n\t\t}\n\n\t\t// The url can be an options object (which then must have .url)\n\t\treturn jQuery.ajax( jQuery.extend( {\n\t\t\turl: url,\n\t\t\ttype: method,\n\t\t\tdataType: type,\n\t\t\tdata: data,\n\t\t\tsuccess: callback\n\t\t}, jQuery.isPlainObject( url ) && url ) );\n\t};\n} );\n\njQuery.ajaxPrefilter( function( s ) {\n\tvar i;\n\tfor ( i in s.headers ) {\n\t\tif ( i.toLowerCase() === \"content-type\" ) {\n\t\t\ts.contentType = s.headers[ i ] || \"\";\n\t\t}\n\t}\n} );\n\n\njQuery._evalUrl = function( url, options, doc ) {\n\treturn jQuery.ajax( {\n\t\turl: url,\n\n\t\t// Make this explicit, since user can override this through ajaxSetup (#11264)\n\t\ttype: \"GET\",\n\t\tdataType: \"script\",\n\t\tcache: true,\n\t\tasync: false,\n\t\tglobal: false,\n\n\t\t// Only evaluate the response if it is successful (gh-4126)\n\t\t// dataFilter is not invoked for failure responses, so using it instead\n\t\t// of the default converter is kludgy but it works.\n\t\tconverters: {\n\t\t\t\"text script\": function() {}\n\t\t},\n\t\tdataFilter: function( response ) {\n\t\t\tjQuery.globalEval( response, options, doc );\n\t\t}\n\t} );\n};\n\n\njQuery.fn.extend( {\n\twrapAll: function( html ) {\n\t\tvar wrap;\n\n\t\tif ( this[ 0 ] ) {\n\t\t\tif ( isFunction( html ) ) {\n\t\t\t\thtml = html.call( this[ 0 ] );\n\t\t\t}\n\n\t\t\t// The elements to wrap the target around\n\t\t\twrap = jQuery( html, this[ 0 ].ownerDocument ).eq( 0 ).clone( true );\n\n\t\t\tif ( this[ 0 ].parentNode ) {\n\t\t\t\twrap.insertBefore( this[ 0 ] );\n\t\t\t}\n\n\t\t\twrap.map( function() {\n\t\t\t\tvar elem = this;\n\n\t\t\t\twhile ( elem.firstElementChild ) {\n\t\t\t\t\telem = elem.firstElementChild;\n\t\t\t\t}\n\n\t\t\t\treturn elem;\n\t\t\t} ).append( this );\n\t\t}\n\n\t\treturn this;\n\t},\n\n\twrapInner: function( html ) {\n\t\tif ( isFunction( html ) ) {\n\t\t\treturn this.each( function( i ) {\n\t\t\t\tjQuery( this ).wrapInner( html.call( this, i ) );\n\t\t\t} );\n\t\t}\n\n\t\treturn this.each( function() {\n\t\t\tvar self = jQuery( this ),\n\t\t\t\tcontents = self.contents();\n\n\t\t\tif ( contents.length ) {\n\t\t\t\tcontents.wrapAll( html );\n\n\t\t\t} else {\n\t\t\t\tself.append( html );\n\t\t\t}\n\t\t} );\n\t},\n\n\twrap: function( html ) {\n\t\tvar htmlIsFunction = isFunction( html );\n\n\t\treturn this.each( function( i ) {\n\t\t\tjQuery( this ).wrapAll( htmlIsFunction ? html.call( this, i ) : html );\n\t\t} );\n\t},\n\n\tunwrap: function( selector ) {\n\t\tthis.parent( selector ).not( \"body\" ).each( function() {\n\t\t\tjQuery( this ).replaceWith( this.childNodes );\n\t\t} );\n\t\treturn this;\n\t}\n} );\n\n\njQuery.expr.pseudos.hidden = function( elem ) {\n\treturn !jQuery.expr.pseudos.visible( elem );\n};\njQuery.expr.pseudos.visible = function( elem ) {\n\treturn !!( elem.offsetWidth || elem.offsetHeight || elem.getClientRects().length );\n};\n\n\n\n\njQuery.ajaxSettings.xhr = function() {\n\ttry {\n\t\treturn new window.XMLHttpRequest();\n\t} catch ( e ) {}\n};\n\nvar xhrSuccessStatus = {\n\n\t\t// File protocol always yields status code 0, assume 200\n\t\t0: 200,\n\n\t\t// Support: IE <=9 only\n\t\t// #1450: sometimes IE returns 1223 when it should be 204\n\t\t1223: 204\n\t},\n\txhrSupported = jQuery.ajaxSettings.xhr();\n\nsupport.cors = !!xhrSupported && ( \"withCredentials\" in xhrSupported );\nsupport.ajax = xhrSupported = !!xhrSupported;\n\njQuery.ajaxTransport( function( options ) {\n\tvar callback, errorCallback;\n\n\t// Cross domain only allowed if supported through XMLHttpRequest\n\tif ( support.cors || xhrSupported && !options.crossDomain ) {\n\t\treturn {\n\t\t\tsend: function( headers, complete ) {\n\t\t\t\tvar i,\n\t\t\t\t\txhr = options.xhr();\n\n\t\t\t\txhr.open(\n\t\t\t\t\toptions.type,\n\t\t\t\t\toptions.url,\n\t\t\t\t\toptions.async,\n\t\t\t\t\toptions.username,\n\t\t\t\t\toptions.password\n\t\t\t\t);\n\n\t\t\t\t// Apply custom fields if provided\n\t\t\t\tif ( options.xhrFields ) {\n\t\t\t\t\tfor ( i in options.xhrFields ) {\n\t\t\t\t\t\txhr[ i ] = options.xhrFields[ i ];\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Override mime type if needed\n\t\t\t\tif ( options.mimeType && xhr.overrideMimeType ) {\n\t\t\t\t\txhr.overrideMimeType( options.mimeType );\n\t\t\t\t}\n\n\t\t\t\t// X-Requested-With header\n\t\t\t\t// For cross-domain requests, seeing as conditions for a preflight are\n\t\t\t\t// akin to a jigsaw puzzle, we simply never set it to be sure.\n\t\t\t\t// (it can always be set on a per-request basis or even using ajaxSetup)\n\t\t\t\t// For same-domain requests, won't change header if already provided.\n\t\t\t\tif ( !options.crossDomain && !headers[ \"X-Requested-With\" ] ) {\n\t\t\t\t\theaders[ \"X-Requested-With\" ] = \"XMLHttpRequest\";\n\t\t\t\t}\n\n\t\t\t\t// Set headers\n\t\t\t\tfor ( i in headers ) {\n\t\t\t\t\txhr.setRequestHeader( i, headers[ i ] );\n\t\t\t\t}\n\n\t\t\t\t// Callback\n\t\t\t\tcallback = function( type ) {\n\t\t\t\t\treturn function() {\n\t\t\t\t\t\tif ( callback ) {\n\t\t\t\t\t\t\tcallback = errorCallback = xhr.onload =\n\t\t\t\t\t\t\t\txhr.onerror = xhr.onabort = xhr.ontimeout =\n\t\t\t\t\t\t\t\t\txhr.onreadystatechange = null;\n\n\t\t\t\t\t\t\tif ( type === \"abort\" ) {\n\t\t\t\t\t\t\t\txhr.abort();\n\t\t\t\t\t\t\t} else if ( type === \"error\" ) {\n\n\t\t\t\t\t\t\t\t// Support: IE <=9 only\n\t\t\t\t\t\t\t\t// On a manual native abort, IE9 throws\n\t\t\t\t\t\t\t\t// errors on any property access that is not readyState\n\t\t\t\t\t\t\t\tif ( typeof xhr.status !== \"number\" ) {\n\t\t\t\t\t\t\t\t\tcomplete( 0, \"error\" );\n\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\tcomplete(\n\n\t\t\t\t\t\t\t\t\t\t// File: protocol always yields status 0; see #8605, #14207\n\t\t\t\t\t\t\t\t\t\txhr.status,\n\t\t\t\t\t\t\t\t\t\txhr.statusText\n\t\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tcomplete(\n\t\t\t\t\t\t\t\t\txhrSuccessStatus[ xhr.status ] || xhr.status,\n\t\t\t\t\t\t\t\t\txhr.statusText,\n\n\t\t\t\t\t\t\t\t\t// Support: IE <=9 only\n\t\t\t\t\t\t\t\t\t// IE9 has no XHR2 but throws on binary (trac-11426)\n\t\t\t\t\t\t\t\t\t// For XHR2 non-text, let the caller handle it (gh-2498)\n\t\t\t\t\t\t\t\t\t( xhr.responseType || \"text\" ) !== \"text\"  ||\n\t\t\t\t\t\t\t\t\ttypeof xhr.responseText !== \"string\" ?\n\t\t\t\t\t\t\t\t\t\t{ binary: xhr.response } :\n\t\t\t\t\t\t\t\t\t\t{ text: xhr.responseText },\n\t\t\t\t\t\t\t\t\txhr.getAllResponseHeaders()\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t};\n\t\t\t\t};\n\n\t\t\t\t// Listen to events\n\t\t\t\txhr.onload = callback();\n\t\t\t\terrorCallback = xhr.onerror = xhr.ontimeout = callback( \"error\" );\n\n\t\t\t\t// Support: IE 9 only\n\t\t\t\t// Use onreadystatechange to replace onabort\n\t\t\t\t// to handle uncaught aborts\n\t\t\t\tif ( xhr.onabort !== undefined ) {\n\t\t\t\t\txhr.onabort = errorCallback;\n\t\t\t\t} else {\n\t\t\t\t\txhr.onreadystatechange = function() {\n\n\t\t\t\t\t\t// Check readyState before timeout as it changes\n\t\t\t\t\t\tif ( xhr.readyState === 4 ) {\n\n\t\t\t\t\t\t\t// Allow onerror to be called first,\n\t\t\t\t\t\t\t// but that will not handle a native abort\n\t\t\t\t\t\t\t// Also, save errorCallback to a variable\n\t\t\t\t\t\t\t// as xhr.onerror cannot be accessed\n\t\t\t\t\t\t\twindow.setTimeout( function() {\n\t\t\t\t\t\t\t\tif ( callback ) {\n\t\t\t\t\t\t\t\t\terrorCallback();\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t} );\n\t\t\t\t\t\t}\n\t\t\t\t\t};\n\t\t\t\t}\n\n\t\t\t\t// Create the abort callback\n\t\t\t\tcallback = callback( \"abort\" );\n\n\t\t\t\ttry {\n\n\t\t\t\t\t// Do send the request (this may raise an exception)\n\t\t\t\t\txhr.send( options.hasContent && options.data || null );\n\t\t\t\t} catch ( e ) {\n\n\t\t\t\t\t// #14683: Only rethrow if this hasn't been notified as an error yet\n\t\t\t\t\tif ( callback ) {\n\t\t\t\t\t\tthrow e;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t},\n\n\t\t\tabort: function() {\n\t\t\t\tif ( callback ) {\n\t\t\t\t\tcallback();\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\t}\n} );\n\n\n\n\n// Prevent auto-execution of scripts when no explicit dataType was provided (See gh-2432)\njQuery.ajaxPrefilter( function( s ) {\n\tif ( s.crossDomain ) {\n\t\ts.contents.script = false;\n\t}\n} );\n\n// Install script dataType\njQuery.ajaxSetup( {\n\taccepts: {\n\t\tscript: \"text/javascript, application/javascript, \" +\n\t\t\t\"application/ecmascript, application/x-ecmascript\"\n\t},\n\tcontents: {\n\t\tscript: /\\b(?:java|ecma)script\\b/\n\t},\n\tconverters: {\n\t\t\"text script\": function( text ) {\n\t\t\tjQuery.globalEval( text );\n\t\t\treturn text;\n\t\t}\n\t}\n} );\n\n// Handle cache's special case and crossDomain\njQuery.ajaxPrefilter( \"script\", function( s ) {\n\tif ( s.cache === undefined ) {\n\t\ts.cache = false;\n\t}\n\tif ( s.crossDomain ) {\n\t\ts.type = \"GET\";\n\t}\n} );\n\n// Bind script tag hack transport\njQuery.ajaxTransport( \"script\", function( s ) {\n\n\t// This transport only deals with cross domain or forced-by-attrs requests\n\tif ( s.crossDomain || s.scriptAttrs ) {\n\t\tvar script, callback;\n\t\treturn {\n\t\t\tsend: function( _, complete ) {\n\t\t\t\tscript = jQuery( \"<script>\" )\n\t\t\t\t\t.attr( s.scriptAttrs || {} )\n\t\t\t\t\t.prop( { charset: s.scriptCharset, src: s.url } )\n\t\t\t\t\t.on( \"load error\", callback = function( evt ) {\n\t\t\t\t\t\tscript.remove();\n\t\t\t\t\t\tcallback = null;\n\t\t\t\t\t\tif ( evt ) {\n\t\t\t\t\t\t\tcomplete( evt.type === \"error\" ? 404 : 200, evt.type );\n\t\t\t\t\t\t}\n\t\t\t\t\t} );\n\n\t\t\t\t// Use native DOM manipulation to avoid our domManip AJAX trickery\n\t\t\t\tdocument.head.appendChild( script[ 0 ] );\n\t\t\t},\n\t\t\tabort: function() {\n\t\t\t\tif ( callback ) {\n\t\t\t\t\tcallback();\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\t}\n} );\n\n\n\n\nvar oldCallbacks = [],\n\trjsonp = /(=)\\?(?=&|$)|\\?\\?/;\n\n// Default jsonp settings\njQuery.ajaxSetup( {\n\tjsonp: \"callback\",\n\tjsonpCallback: function() {\n\t\tvar callback = oldCallbacks.pop() || ( jQuery.expando + \"_\" + ( nonce.guid++ ) );\n\t\tthis[ callback ] = true;\n\t\treturn callback;\n\t}\n} );\n\n// Detect, normalize options and install callbacks for jsonp requests\njQuery.ajaxPrefilter( \"json jsonp\", function( s, originalSettings, jqXHR ) {\n\n\tvar callbackName, overwritten, responseContainer,\n\t\tjsonProp = s.jsonp !== false && ( rjsonp.test( s.url ) ?\n\t\t\t\"url\" :\n\t\t\ttypeof s.data === \"string\" &&\n\t\t\t\t( s.contentType || \"\" )\n\t\t\t\t\t.indexOf( \"application/x-www-form-urlencoded\" ) === 0 &&\n\t\t\t\trjsonp.test( s.data ) && \"data\"\n\t\t);\n\n\t// Handle iff the expected data type is \"jsonp\" or we have a parameter to set\n\tif ( jsonProp || s.dataTypes[ 0 ] === \"jsonp\" ) {\n\n\t\t// Get callback name, remembering preexisting value associated with it\n\t\tcallbackName = s.jsonpCallback = isFunction( s.jsonpCallback ) ?\n\t\t\ts.jsonpCallback() :\n\t\t\ts.jsonpCallback;\n\n\t\t// Insert callback into url or form data\n\t\tif ( jsonProp ) {\n\t\t\ts[ jsonProp ] = s[ jsonProp ].replace( rjsonp, \"$1\" + callbackName );\n\t\t} else if ( s.jsonp !== false ) {\n\t\t\ts.url += ( rquery.test( s.url ) ? \"&\" : \"?\" ) + s.jsonp + \"=\" + callbackName;\n\t\t}\n\n\t\t// Use data converter to retrieve json after script execution\n\t\ts.converters[ \"script json\" ] = function() {\n\t\t\tif ( !responseContainer ) {\n\t\t\t\tjQuery.error( callbackName + \" was not called\" );\n\t\t\t}\n\t\t\treturn responseContainer[ 0 ];\n\t\t};\n\n\t\t// Force json dataType\n\t\ts.dataTypes[ 0 ] = \"json\";\n\n\t\t// Install callback\n\t\toverwritten = window[ callbackName ];\n\t\twindow[ callbackName ] = function() {\n\t\t\tresponseContainer = arguments;\n\t\t};\n\n\t\t// Clean-up function (fires after converters)\n\t\tjqXHR.always( function() {\n\n\t\t\t// If previous value didn't exist - remove it\n\t\t\tif ( overwritten === undefined ) {\n\t\t\t\tjQuery( window ).removeProp( callbackName );\n\n\t\t\t// Otherwise restore preexisting value\n\t\t\t} else {\n\t\t\t\twindow[ callbackName ] = overwritten;\n\t\t\t}\n\n\t\t\t// Save back as free\n\t\t\tif ( s[ callbackName ] ) {\n\n\t\t\t\t// Make sure that re-using the options doesn't screw things around\n\t\t\t\ts.jsonpCallback = originalSettings.jsonpCallback;\n\n\t\t\t\t// Save the callback name for future use\n\t\t\t\toldCallbacks.push( callbackName );\n\t\t\t}\n\n\t\t\t// Call if it was a function and we have a response\n\t\t\tif ( responseContainer && isFunction( overwritten ) ) {\n\t\t\t\toverwritten( responseContainer[ 0 ] );\n\t\t\t}\n\n\t\t\tresponseContainer = overwritten = undefined;\n\t\t} );\n\n\t\t// Delegate to script\n\t\treturn \"script\";\n\t}\n} );\n\n\n\n\n// Support: Safari 8 only\n// In Safari 8 documents created via document.implementation.createHTMLDocument\n// collapse sibling forms: the second one becomes a child of the first one.\n// Because of that, this security measure has to be disabled in Safari 8.\n// https://bugs.webkit.org/show_bug.cgi?id=137337\nsupport.createHTMLDocument = ( function() {\n\tvar body = document.implementation.createHTMLDocument( \"\" ).body;\n\tbody.innerHTML = \"<form></form><form></form>\";\n\treturn body.childNodes.length === 2;\n} )();\n\n\n// Argument \"data\" should be string of html\n// context (optional): If specified, the fragment will be created in this context,\n// defaults to document\n// keepScripts (optional): If true, will include scripts passed in the html string\njQuery.parseHTML = function( data, context, keepScripts ) {\n\tif ( typeof data !== \"string\" ) {\n\t\treturn [];\n\t}\n\tif ( typeof context === \"boolean\" ) {\n\t\tkeepScripts = context;\n\t\tcontext = false;\n\t}\n\n\tvar base, parsed, scripts;\n\n\tif ( !context ) {\n\n\t\t// Stop scripts or inline event handlers from being executed immediately\n\t\t// by using document.implementation\n\t\tif ( support.createHTMLDocument ) {\n\t\t\tcontext = document.implementation.createHTMLDocument( \"\" );\n\n\t\t\t// Set the base href for the created document\n\t\t\t// so any parsed elements with URLs\n\t\t\t// are based on the document's URL (gh-2965)\n\t\t\tbase = context.createElement( \"base\" );\n\t\t\tbase.href = document.location.href;\n\t\t\tcontext.head.appendChild( base );\n\t\t} else {\n\t\t\tcontext = document;\n\t\t}\n\t}\n\n\tparsed = rsingleTag.exec( data );\n\tscripts = !keepScripts && [];\n\n\t// Single tag\n\tif ( parsed ) {\n\t\treturn [ context.createElement( parsed[ 1 ] ) ];\n\t}\n\n\tparsed = buildFragment( [ data ], context, scripts );\n\n\tif ( scripts && scripts.length ) {\n\t\tjQuery( scripts ).remove();\n\t}\n\n\treturn jQuery.merge( [], parsed.childNodes );\n};\n\n\n/**\n * Load a url into a page\n */\njQuery.fn.load = function( url, params, callback ) {\n\tvar selector, type, response,\n\t\tself = this,\n\t\toff = url.indexOf( \" \" );\n\n\tif ( off > -1 ) {\n\t\tselector = stripAndCollapse( url.slice( off ) );\n\t\turl = url.slice( 0, off );\n\t}\n\n\t// If it's a function\n\tif ( isFunction( params ) ) {\n\n\t\t// We assume that it's the callback\n\t\tcallback = params;\n\t\tparams = undefined;\n\n\t// Otherwise, build a param string\n\t} else if ( params && typeof params === \"object\" ) {\n\t\ttype = \"POST\";\n\t}\n\n\t// If we have elements to modify, make the request\n\tif ( self.length > 0 ) {\n\t\tjQuery.ajax( {\n\t\t\turl: url,\n\n\t\t\t// If \"type\" variable is undefined, then \"GET\" method will be used.\n\t\t\t// Make value of this field explicit since\n\t\t\t// user can override it through ajaxSetup method\n\t\t\ttype: type || \"GET\",\n\t\t\tdataType: \"html\",\n\t\t\tdata: params\n\t\t} ).done( function( responseText ) {\n\n\t\t\t// Save response for use in complete callback\n\t\t\tresponse = arguments;\n\n\t\t\tself.html( selector ?\n\n\t\t\t\t// If a selector was specified, locate the right elements in a dummy div\n\t\t\t\t// Exclude scripts to avoid IE 'Permission Denied' errors\n\t\t\t\tjQuery( \"<div>\" ).append( jQuery.parseHTML( responseText ) ).find( selector ) :\n\n\t\t\t\t// Otherwise use the full result\n\t\t\t\tresponseText );\n\n\t\t// If the request succeeds, this function gets \"data\", \"status\", \"jqXHR\"\n\t\t// but they are ignored because response was set above.\n\t\t// If it fails, this function gets \"jqXHR\", \"status\", \"error\"\n\t\t} ).always( callback && function( jqXHR, status ) {\n\t\t\tself.each( function() {\n\t\t\t\tcallback.apply( this, response || [ jqXHR.responseText, status, jqXHR ] );\n\t\t\t} );\n\t\t} );\n\t}\n\n\treturn this;\n};\n\n\n\n\njQuery.expr.pseudos.animated = function( elem ) {\n\treturn jQuery.grep( jQuery.timers, function( fn ) {\n\t\treturn elem === fn.elem;\n\t} ).length;\n};\n\n\n\n\njQuery.offset = {\n\tsetOffset: function( elem, options, i ) {\n\t\tvar curPosition, curLeft, curCSSTop, curTop, curOffset, curCSSLeft, calculatePosition,\n\t\t\tposition = jQuery.css( elem, \"position\" ),\n\t\t\tcurElem = jQuery( elem ),\n\t\t\tprops = {};\n\n\t\t// Set position first, in-case top/left are set even on static elem\n\t\tif ( position === \"static\" ) {\n\t\t\telem.style.position = \"relative\";\n\t\t}\n\n\t\tcurOffset = curElem.offset();\n\t\tcurCSSTop = jQuery.css( elem, \"top\" );\n\t\tcurCSSLeft = jQuery.css( elem, \"left\" );\n\t\tcalculatePosition = ( position === \"absolute\" || position === \"fixed\" ) &&\n\t\t\t( curCSSTop + curCSSLeft ).indexOf( \"auto\" ) > -1;\n\n\t\t// Need to be able to calculate position if either\n\t\t// top or left is auto and position is either absolute or fixed\n\t\tif ( calculatePosition ) {\n\t\t\tcurPosition = curElem.position();\n\t\t\tcurTop = curPosition.top;\n\t\t\tcurLeft = curPosition.left;\n\n\t\t} else {\n\t\t\tcurTop = parseFloat( curCSSTop ) || 0;\n\t\t\tcurLeft = parseFloat( curCSSLeft ) || 0;\n\t\t}\n\n\t\tif ( isFunction( options ) ) {\n\n\t\t\t// Use jQuery.extend here to allow modification of coordinates argument (gh-1848)\n\t\t\toptions = options.call( elem, i, jQuery.extend( {}, curOffset ) );\n\t\t}\n\n\t\tif ( options.top != null ) {\n\t\t\tprops.top = ( options.top - curOffset.top ) + curTop;\n\t\t}\n\t\tif ( options.left != null ) {\n\t\t\tprops.left = ( options.left - curOffset.left ) + curLeft;\n\t\t}\n\n\t\tif ( \"using\" in options ) {\n\t\t\toptions.using.call( elem, props );\n\n\t\t} else {\n\t\t\tif ( typeof props.top === \"number\" ) {\n\t\t\t\tprops.top += \"px\";\n\t\t\t}\n\t\t\tif ( typeof props.left === \"number\" ) {\n\t\t\t\tprops.left += \"px\";\n\t\t\t}\n\t\t\tcurElem.css( props );\n\t\t}\n\t}\n};\n\njQuery.fn.extend( {\n\n\t// offset() relates an element's border box to the document origin\n\toffset: function( options ) {\n\n\t\t// Preserve chaining for setter\n\t\tif ( arguments.length ) {\n\t\t\treturn options === undefined ?\n\t\t\t\tthis :\n\t\t\t\tthis.each( function( i ) {\n\t\t\t\t\tjQuery.offset.setOffset( this, options, i );\n\t\t\t\t} );\n\t\t}\n\n\t\tvar rect, win,\n\t\t\telem = this[ 0 ];\n\n\t\tif ( !elem ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Return zeros for disconnected and hidden (display: none) elements (gh-2310)\n\t\t// Support: IE <=11 only\n\t\t// Running getBoundingClientRect on a\n\t\t// disconnected node in IE throws an error\n\t\tif ( !elem.getClientRects().length ) {\n\t\t\treturn { top: 0, left: 0 };\n\t\t}\n\n\t\t// Get document-relative position by adding viewport scroll to viewport-relative gBCR\n\t\trect = elem.getBoundingClientRect();\n\t\twin = elem.ownerDocument.defaultView;\n\t\treturn {\n\t\t\ttop: rect.top + win.pageYOffset,\n\t\t\tleft: rect.left + win.pageXOffset\n\t\t};\n\t},\n\n\t// position() relates an element's margin box to its offset parent's padding box\n\t// This corresponds to the behavior of CSS absolute positioning\n\tposition: function() {\n\t\tif ( !this[ 0 ] ) {\n\t\t\treturn;\n\t\t}\n\n\t\tvar offsetParent, offset, doc,\n\t\t\telem = this[ 0 ],\n\t\t\tparentOffset = { top: 0, left: 0 };\n\n\t\t// position:fixed elements are offset from the viewport, which itself always has zero offset\n\t\tif ( jQuery.css( elem, \"position\" ) === \"fixed\" ) {\n\n\t\t\t// Assume position:fixed implies availability of getBoundingClientRect\n\t\t\toffset = elem.getBoundingClientRect();\n\n\t\t} else {\n\t\t\toffset = this.offset();\n\n\t\t\t// Account for the *real* offset parent, which can be the document or its root element\n\t\t\t// when a statically positioned element is identified\n\t\t\tdoc = elem.ownerDocument;\n\t\t\toffsetParent = elem.offsetParent || doc.documentElement;\n\t\t\twhile ( offsetParent &&\n\t\t\t\t( offsetParent === doc.body || offsetParent === doc.documentElement ) &&\n\t\t\t\tjQuery.css( offsetParent, \"position\" ) === \"static\" ) {\n\n\t\t\t\toffsetParent = offsetParent.parentNode;\n\t\t\t}\n\t\t\tif ( offsetParent && offsetParent !== elem && offsetParent.nodeType === 1 ) {\n\n\t\t\t\t// Incorporate borders into its offset, since they are outside its content origin\n\t\t\t\tparentOffset = jQuery( offsetParent ).offset();\n\t\t\t\tparentOffset.top += jQuery.css( offsetParent, \"borderTopWidth\", true );\n\t\t\t\tparentOffset.left += jQuery.css( offsetParent, \"borderLeftWidth\", true );\n\t\t\t}\n\t\t}\n\n\t\t// Subtract parent offsets and element margins\n\t\treturn {\n\t\t\ttop: offset.top - parentOffset.top - jQuery.css( elem, \"marginTop\", true ),\n\t\t\tleft: offset.left - parentOffset.left - jQuery.css( elem, \"marginLeft\", true )\n\t\t};\n\t},\n\n\t// This method will return documentElement in the following cases:\n\t// 1) For the element inside the iframe without offsetParent, this method will return\n\t//    documentElement of the parent window\n\t// 2) For the hidden or detached element\n\t// 3) For body or html element, i.e. in case of the html node - it will return itself\n\t//\n\t// but those exceptions were never presented as a real life use-cases\n\t// and might be considered as more preferable results.\n\t//\n\t// This logic, however, is not guaranteed and can change at any point in the future\n\toffsetParent: function() {\n\t\treturn this.map( function() {\n\t\t\tvar offsetParent = this.offsetParent;\n\n\t\t\twhile ( offsetParent && jQuery.css( offsetParent, \"position\" ) === \"static\" ) {\n\t\t\t\toffsetParent = offsetParent.offsetParent;\n\t\t\t}\n\n\t\t\treturn offsetParent || documentElement;\n\t\t} );\n\t}\n} );\n\n// Create scrollLeft and scrollTop methods\njQuery.each( { scrollLeft: \"pageXOffset\", scrollTop: \"pageYOffset\" }, function( method, prop ) {\n\tvar top = \"pageYOffset\" === prop;\n\n\tjQuery.fn[ method ] = function( val ) {\n\t\treturn access( this, function( elem, method, val ) {\n\n\t\t\t// Coalesce documents and windows\n\t\t\tvar win;\n\t\t\tif ( isWindow( elem ) ) {\n\t\t\t\twin = elem;\n\t\t\t} else if ( elem.nodeType === 9 ) {\n\t\t\t\twin = elem.defaultView;\n\t\t\t}\n\n\t\t\tif ( val === undefined ) {\n\t\t\t\treturn win ? win[ prop ] : elem[ method ];\n\t\t\t}\n\n\t\t\tif ( win ) {\n\t\t\t\twin.scrollTo(\n\t\t\t\t\t!top ? val : win.pageXOffset,\n\t\t\t\t\ttop ? val : win.pageYOffset\n\t\t\t\t);\n\n\t\t\t} else {\n\t\t\t\telem[ method ] = val;\n\t\t\t}\n\t\t}, method, val, arguments.length );\n\t};\n} );\n\n// Support: Safari <=7 - 9.1, Chrome <=37 - 49\n// Add the top/left cssHooks using jQuery.fn.position\n// Webkit bug: https://bugs.webkit.org/show_bug.cgi?id=29084\n// Blink bug: https://bugs.chromium.org/p/chromium/issues/detail?id=589347\n// getComputedStyle returns percent when specified for top/left/bottom/right;\n// rather than make the css module depend on the offset module, just check for it here\njQuery.each( [ \"top\", \"left\" ], function( _i, prop ) {\n\tjQuery.cssHooks[ prop ] = addGetHookIf( support.pixelPosition,\n\t\tfunction( elem, computed ) {\n\t\t\tif ( computed ) {\n\t\t\t\tcomputed = curCSS( elem, prop );\n\n\t\t\t\t// If curCSS returns percentage, fallback to offset\n\t\t\t\treturn rnumnonpx.test( computed ) ?\n\t\t\t\t\tjQuery( elem ).position()[ prop ] + \"px\" :\n\t\t\t\t\tcomputed;\n\t\t\t}\n\t\t}\n\t);\n} );\n\n\n// Create innerHeight, innerWidth, height, width, outerHeight and outerWidth methods\njQuery.each( { Height: \"height\", Width: \"width\" }, function( name, type ) {\n\tjQuery.each( { padding: \"inner\" + name, content: type, \"\": \"outer\" + name },\n\t\tfunction( defaultExtra, funcName ) {\n\n\t\t// Margin is only for outerHeight, outerWidth\n\t\tjQuery.fn[ funcName ] = function( margin, value ) {\n\t\t\tvar chainable = arguments.length && ( defaultExtra || typeof margin !== \"boolean\" ),\n\t\t\t\textra = defaultExtra || ( margin === true || value === true ? \"margin\" : \"border\" );\n\n\t\t\treturn access( this, function( elem, type, value ) {\n\t\t\t\tvar doc;\n\n\t\t\t\tif ( isWindow( elem ) ) {\n\n\t\t\t\t\t// $( window ).outerWidth/Height return w/h including scrollbars (gh-1729)\n\t\t\t\t\treturn funcName.indexOf( \"outer\" ) === 0 ?\n\t\t\t\t\t\telem[ \"inner\" + name ] :\n\t\t\t\t\t\telem.document.documentElement[ \"client\" + name ];\n\t\t\t\t}\n\n\t\t\t\t// Get document width or height\n\t\t\t\tif ( elem.nodeType === 9 ) {\n\t\t\t\t\tdoc = elem.documentElement;\n\n\t\t\t\t\t// Either scroll[Width/Height] or offset[Width/Height] or client[Width/Height],\n\t\t\t\t\t// whichever is greatest\n\t\t\t\t\treturn Math.max(\n\t\t\t\t\t\telem.body[ \"scroll\" + name ], doc[ \"scroll\" + name ],\n\t\t\t\t\t\telem.body[ \"offset\" + name ], doc[ \"offset\" + name ],\n\t\t\t\t\t\tdoc[ \"client\" + name ]\n\t\t\t\t\t);\n\t\t\t\t}\n\n\t\t\t\treturn value === undefined ?\n\n\t\t\t\t\t// Get width or height on the element, requesting but not forcing parseFloat\n\t\t\t\t\tjQuery.css( elem, type, extra ) :\n\n\t\t\t\t\t// Set width or height on the element\n\t\t\t\t\tjQuery.style( elem, type, value, extra );\n\t\t\t}, type, chainable ? margin : undefined, chainable );\n\t\t};\n\t} );\n} );\n\n\njQuery.each( [\n\t\"ajaxStart\",\n\t\"ajaxStop\",\n\t\"ajaxComplete\",\n\t\"ajaxError\",\n\t\"ajaxSuccess\",\n\t\"ajaxSend\"\n], function( _i, type ) {\n\tjQuery.fn[ type ] = function( fn ) {\n\t\treturn this.on( type, fn );\n\t};\n} );\n\n\n\n\njQuery.fn.extend( {\n\n\tbind: function( types, data, fn ) {\n\t\treturn this.on( types, null, data, fn );\n\t},\n\tunbind: function( types, fn ) {\n\t\treturn this.off( types, null, fn );\n\t},\n\n\tdelegate: function( selector, types, data, fn ) {\n\t\treturn this.on( types, selector, data, fn );\n\t},\n\tundelegate: function( selector, types, fn ) {\n\n\t\t// ( namespace ) or ( selector, types [, fn] )\n\t\treturn arguments.length === 1 ?\n\t\t\tthis.off( selector, \"**\" ) :\n\t\t\tthis.off( types, selector || \"**\", fn );\n\t},\n\n\thover: function( fnOver, fnOut ) {\n\t\treturn this.mouseenter( fnOver ).mouseleave( fnOut || fnOver );\n\t}\n} );\n\njQuery.each( ( \"blur focus focusin focusout resize scroll click dblclick \" +\n\t\"mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave \" +\n\t\"change select submit keydown keypress keyup contextmenu\" ).split( \" \" ),\n\tfunction( _i, name ) {\n\n\t\t// Handle event binding\n\t\tjQuery.fn[ name ] = function( data, fn ) {\n\t\t\treturn arguments.length > 0 ?\n\t\t\t\tthis.on( name, null, data, fn ) :\n\t\t\t\tthis.trigger( name );\n\t\t};\n\t} );\n\n\n\n\n// Support: Android <=4.0 only\n// Make sure we trim BOM and NBSP\nvar rtrim = /^[\\s\\uFEFF\\xA0]+|[\\s\\uFEFF\\xA0]+$/g;\n\n// Bind a function to a context, optionally partially applying any\n// arguments.\n// jQuery.proxy is deprecated to promote standards (specifically Function#bind)\n// However, it is not slated for removal any time soon\njQuery.proxy = function( fn, context ) {\n\tvar tmp, args, proxy;\n\n\tif ( typeof context === \"string\" ) {\n\t\ttmp = fn[ context ];\n\t\tcontext = fn;\n\t\tfn = tmp;\n\t}\n\n\t// Quick check to determine if target is callable, in the spec\n\t// this throws a TypeError, but we will just return undefined.\n\tif ( !isFunction( fn ) ) {\n\t\treturn undefined;\n\t}\n\n\t// Simulated bind\n\targs = slice.call( arguments, 2 );\n\tproxy = function() {\n\t\treturn fn.apply( context || this, args.concat( slice.call( arguments ) ) );\n\t};\n\n\t// Set the guid of unique handler to the same of original handler, so it can be removed\n\tproxy.guid = fn.guid = fn.guid || jQuery.guid++;\n\n\treturn proxy;\n};\n\njQuery.holdReady = function( hold ) {\n\tif ( hold ) {\n\t\tjQuery.readyWait++;\n\t} else {\n\t\tjQuery.ready( true );\n\t}\n};\njQuery.isArray = Array.isArray;\njQuery.parseJSON = JSON.parse;\njQuery.nodeName = nodeName;\njQuery.isFunction = isFunction;\njQuery.isWindow = isWindow;\njQuery.camelCase = camelCase;\njQuery.type = toType;\n\njQuery.now = Date.now;\n\njQuery.isNumeric = function( obj ) {\n\n\t// As of jQuery 3.0, isNumeric is limited to\n\t// strings and numbers (primitives or objects)\n\t// that can be coerced to finite numbers (gh-2662)\n\tvar type = jQuery.type( obj );\n\treturn ( type === \"number\" || type === \"string\" ) &&\n\n\t\t// parseFloat NaNs numeric-cast false positives (\"\")\n\t\t// ...but misinterprets leading-number strings, particularly hex literals (\"0x...\")\n\t\t// subtraction forces infinities to NaN\n\t\t!isNaN( obj - parseFloat( obj ) );\n};\n\njQuery.trim = function( text ) {\n\treturn text == null ?\n\t\t\"\" :\n\t\t( text + \"\" ).replace( rtrim, \"\" );\n};\n\n\n\n// Register as a named AMD module, since jQuery can be concatenated with other\n// files that may use define, but not via a proper concatenation script that\n// understands anonymous AMD modules. A named AMD is safest and most robust\n// way to register. Lowercase jquery is used because AMD module names are\n// derived from file names, and jQuery is normally delivered in a lowercase\n// file name. Do this after creating the global so that if an AMD module wants\n// to call noConflict to hide this version of jQuery, it will work.\n\n// Note that for maximum portability, libraries that are not jQuery should\n// declare themselves as anonymous modules, and avoid setting a global if an\n// AMD loader is present. jQuery is a special case. For more information, see\n// https://github.com/jrburke/requirejs/wiki/Updating-existing-libraries#wiki-anon\n\nif ( typeof define === \"function\" && define.amd ) {\n\tdefine( \"jquery\", [], function() {\n\t\treturn jQuery;\n\t} );\n}\n\n\n\n\nvar\n\n\t// Map over jQuery in case of overwrite\n\t_jQuery = window.jQuery,\n\n\t// Map over the $ in case of overwrite\n\t_$ = window.$;\n\njQuery.noConflict = function( deep ) {\n\tif ( window.$ === jQuery ) {\n\t\twindow.$ = _$;\n\t}\n\n\tif ( deep && window.jQuery === jQuery ) {\n\t\twindow.jQuery = _jQuery;\n\t}\n\n\treturn jQuery;\n};\n\n// Expose jQuery and $ identifiers, even in AMD\n// (#7102#comment:10, https://github.com/jquery/jquery/pull/557)\n// and CommonJS for browser emulators (#13566)\nif ( typeof noGlobal === \"undefined\" ) {\n\twindow.jQuery = window.$ = jQuery;\n}\n\n\n\n\nreturn jQuery;\n} );\n"
  },
  {
    "path": "sample/src/NimblePros.SampleToDo.Web/wwwroot/lib/jquery-validation/LICENSE.md",
    "content": "The MIT License (MIT)\n=====================\n\nCopyright Jörn Zaefferer\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n"
  },
  {
    "path": "sample/src/NimblePros.SampleToDo.Web/wwwroot/lib/jquery-validation/dist/additional-methods.js",
    "content": "/*!\n * jQuery Validation Plugin v1.17.0\n *\n * https://jqueryvalidation.org/\n *\n * Copyright (c) 2017 Jörn Zaefferer\n * Released under the MIT license\n */\n(function( factory ) {\n\tif ( typeof define === \"function\" && define.amd ) {\n\t\tdefine( [\"jquery\", \"./jquery.validate\"], factory );\n\t} else if (typeof module === \"object\" && module.exports) {\n\t\tmodule.exports = factory( require( \"jquery\" ) );\n\t} else {\n\t\tfactory( jQuery );\n\t}\n}(function( $ ) {\n\n( function() {\n\n\tfunction stripHtml( value ) {\n\n\t\t// Remove html tags and space chars\n\t\treturn value.replace( /<.[^<>]*?>/g, \" \" ).replace( /&nbsp;|&#160;/gi, \" \" )\n\n\t\t// Remove punctuation\n\t\t.replace( /[.(),;:!?%#$'\\\"_+=\\/\\-“”’]*/g, \"\" );\n\t}\n\n\t$.validator.addMethod( \"maxWords\", function( value, element, params ) {\n\t\treturn this.optional( element ) || stripHtml( value ).match( /\\b\\w+\\b/g ).length <= params;\n\t}, $.validator.format( \"Please enter {0} words or less.\" ) );\n\n\t$.validator.addMethod( \"minWords\", function( value, element, params ) {\n\t\treturn this.optional( element ) || stripHtml( value ).match( /\\b\\w+\\b/g ).length >= params;\n\t}, $.validator.format( \"Please enter at least {0} words.\" ) );\n\n\t$.validator.addMethod( \"rangeWords\", function( value, element, params ) {\n\t\tvar valueStripped = stripHtml( value ),\n\t\t\tregex = /\\b\\w+\\b/g;\n\t\treturn this.optional( element ) || valueStripped.match( regex ).length >= params[ 0 ] && valueStripped.match( regex ).length <= params[ 1 ];\n\t}, $.validator.format( \"Please enter between {0} and {1} words.\" ) );\n\n}() );\n\n// Accept a value from a file input based on a required mimetype\n$.validator.addMethod( \"accept\", function( value, element, param ) {\n\n\t// Split mime on commas in case we have multiple types we can accept\n\tvar typeParam = typeof param === \"string\" ? param.replace( /\\s/g, \"\" ) : \"image/*\",\n\t\toptionalValue = this.optional( element ),\n\t\ti, file, regex;\n\n\t// Element is optional\n\tif ( optionalValue ) {\n\t\treturn optionalValue;\n\t}\n\n\tif ( $( element ).attr( \"type\" ) === \"file\" ) {\n\n\t\t// Escape string to be used in the regex\n\t\t// see: https://stackoverflow.com/questions/3446170/escape-string-for-use-in-javascript-regex\n\t\t// Escape also \"/*\" as \"/.*\" as a wildcard\n\t\ttypeParam = typeParam\n\t\t\t\t.replace( /[\\-\\[\\]\\/\\{\\}\\(\\)\\+\\?\\.\\\\\\^\\$\\|]/g, \"\\\\$&\" )\n\t\t\t\t.replace( /,/g, \"|\" )\n\t\t\t\t.replace( /\\/\\*/g, \"/.*\" );\n\n\t\t// Check if the element has a FileList before checking each file\n\t\tif ( element.files && element.files.length ) {\n\t\t\tregex = new RegExp( \".?(\" + typeParam + \")$\", \"i\" );\n\t\t\tfor ( i = 0; i < element.files.length; i++ ) {\n\t\t\t\tfile = element.files[ i ];\n\n\t\t\t\t// Grab the mimetype from the loaded file, verify it matches\n\t\t\t\tif ( !file.type.match( regex ) ) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// Either return true because we've validated each file, or because the\n\t// browser does not support element.files and the FileList feature\n\treturn true;\n}, $.validator.format( \"Please enter a value with a valid mimetype.\" ) );\n\n$.validator.addMethod( \"alphanumeric\", function( value, element ) {\n\treturn this.optional( element ) || /^\\w+$/i.test( value );\n}, \"Letters, numbers, and underscores only please\" );\n\n/*\n * Dutch bank account numbers (not 'giro' numbers) have 9 digits\n * and pass the '11 check'.\n * We accept the notation with spaces, as that is common.\n * acceptable: 123456789 or 12 34 56 789\n */\n$.validator.addMethod( \"bankaccountNL\", function( value, element ) {\n\tif ( this.optional( element ) ) {\n\t\treturn true;\n\t}\n\tif ( !( /^[0-9]{9}|([0-9]{2} ){3}[0-9]{3}$/.test( value ) ) ) {\n\t\treturn false;\n\t}\n\n\t// Now '11 check'\n\tvar account = value.replace( / /g, \"\" ), // Remove spaces\n\t\tsum = 0,\n\t\tlen = account.length,\n\t\tpos, factor, digit;\n\tfor ( pos = 0; pos < len; pos++ ) {\n\t\tfactor = len - pos;\n\t\tdigit = account.substring( pos, pos + 1 );\n\t\tsum = sum + factor * digit;\n\t}\n\treturn sum % 11 === 0;\n}, \"Please specify a valid bank account number\" );\n\n$.validator.addMethod( \"bankorgiroaccountNL\", function( value, element ) {\n\treturn this.optional( element ) ||\n\t\t\t( $.validator.methods.bankaccountNL.call( this, value, element ) ) ||\n\t\t\t( $.validator.methods.giroaccountNL.call( this, value, element ) );\n}, \"Please specify a valid bank or giro account number\" );\n\n/**\n * BIC is the business identifier code (ISO 9362). This BIC check is not a guarantee for authenticity.\n *\n * BIC pattern: BBBBCCLLbbb (8 or 11 characters long; bbb is optional)\n *\n * Validation is case-insensitive. Please make sure to normalize input yourself.\n *\n * BIC definition in detail:\n * - First 4 characters - bank code (only letters)\n * - Next 2 characters - ISO 3166-1 alpha-2 country code (only letters)\n * - Next 2 characters - location code (letters and digits)\n *   a. shall not start with '0' or '1'\n *   b. second character must be a letter ('O' is not allowed) or digit ('0' for test (therefore not allowed), '1' denoting passive participant, '2' typically reverse-billing)\n * - Last 3 characters - branch code, optional (shall not start with 'X' except in case of 'XXX' for primary office) (letters and digits)\n */\n$.validator.addMethod( \"bic\", function( value, element ) {\n    return this.optional( element ) || /^([A-Z]{6}[A-Z2-9][A-NP-Z1-9])(X{3}|[A-WY-Z0-9][A-Z0-9]{2})?$/.test( value.toUpperCase() );\n}, \"Please specify a valid BIC code\" );\n\n/*\n * Código de identificación fiscal ( CIF ) is the tax identification code for Spanish legal entities\n * Further rules can be found in Spanish on http://es.wikipedia.org/wiki/C%C3%B3digo_de_identificaci%C3%B3n_fiscal\n *\n * Spanish CIF structure:\n *\n * [ T ][ P ][ P ][ N ][ N ][ N ][ N ][ N ][ C ]\n *\n * Where:\n *\n * T: 1 character. Kind of Organization Letter: [ABCDEFGHJKLMNPQRSUVW]\n * P: 2 characters. Province.\n * N: 5 characters. Secuencial Number within the province.\n * C: 1 character. Control Digit: [0-9A-J].\n *\n * [ T ]: Kind of Organizations. Possible values:\n *\n *   A. Corporations\n *   B. LLCs\n *   C. General partnerships\n *   D. Companies limited partnerships\n *   E. Communities of goods\n *   F. Cooperative Societies\n *   G. Associations\n *   H. Communities of homeowners in horizontal property regime\n *   J. Civil Societies\n *   K. Old format\n *   L. Old format\n *   M. Old format\n *   N. Nonresident entities\n *   P. Local authorities\n *   Q. Autonomous bodies, state or not, and the like, and congregations and religious institutions\n *   R. Congregations and religious institutions (since 2008 ORDER EHA/451/2008)\n *   S. Organs of State Administration and regions\n *   V. Agrarian Transformation\n *   W. Permanent establishments of non-resident in Spain\n *\n * [ C ]: Control Digit. It can be a number or a letter depending on T value:\n * [ T ]  -->  [ C ]\n * ------    ----------\n *   A         Number\n *   B         Number\n *   E         Number\n *   H         Number\n *   K         Letter\n *   P         Letter\n *   Q         Letter\n *   S         Letter\n *\n */\n$.validator.addMethod( \"cifES\", function( value, element ) {\n\t\"use strict\";\n\n\tif ( this.optional( element ) ) {\n\t\treturn true;\n\t}\n\n\tvar cifRegEx = new RegExp( /^([ABCDEFGHJKLMNPQRSUVW])(\\d{7})([0-9A-J])$/gi );\n\tvar letter  = value.substring( 0, 1 ), // [ T ]\n\t\tnumber  = value.substring( 1, 8 ), // [ P ][ P ][ N ][ N ][ N ][ N ][ N ]\n\t\tcontrol = value.substring( 8, 9 ), // [ C ]\n\t\tall_sum = 0,\n\t\teven_sum = 0,\n\t\todd_sum = 0,\n\t\ti, n,\n\t\tcontrol_digit,\n\t\tcontrol_letter;\n\n\tfunction isOdd( n ) {\n\t\treturn n % 2 === 0;\n\t}\n\n\t// Quick format test\n\tif ( value.length !== 9 || !cifRegEx.test( value ) ) {\n\t\treturn false;\n\t}\n\n\tfor ( i = 0; i < number.length; i++ ) {\n\t\tn = parseInt( number[ i ], 10 );\n\n\t\t// Odd positions\n\t\tif ( isOdd( i ) ) {\n\n\t\t\t// Odd positions are multiplied first.\n\t\t\tn *= 2;\n\n\t\t\t// If the multiplication is bigger than 10 we need to adjust\n\t\t\todd_sum += n < 10 ? n : n - 9;\n\n\t\t// Even positions\n\t\t// Just sum them\n\t\t} else {\n\t\t\teven_sum += n;\n\t\t}\n\t}\n\n\tall_sum = even_sum + odd_sum;\n\tcontrol_digit = ( 10 - ( all_sum ).toString().substr( -1 ) ).toString();\n\tcontrol_digit = parseInt( control_digit, 10 ) > 9 ? \"0\" : control_digit;\n\tcontrol_letter = \"JABCDEFGHI\".substr( control_digit, 1 ).toString();\n\n\t// Control must be a digit\n\tif ( letter.match( /[ABEH]/ ) ) {\n\t\treturn control === control_digit;\n\n\t// Control must be a letter\n\t} else if ( letter.match( /[KPQS]/ ) ) {\n\t\treturn control === control_letter;\n\t}\n\n\t// Can be either\n\treturn control === control_digit || control === control_letter;\n\n}, \"Please specify a valid CIF number.\" );\n\n/*\n * Brazillian CPF number (Cadastrado de Pessoas Físicas) is the equivalent of a Brazilian tax registration number.\n * CPF numbers have 11 digits in total: 9 numbers followed by 2 check numbers that are being used for validation.\n */\n$.validator.addMethod( \"cpfBR\", function( value ) {\n\n\t// Removing special characters from value\n\tvalue = value.replace( /([~!@#$%^&*()_+=`{}\\[\\]\\-|\\\\:;'<>,.\\/? ])+/g, \"\" );\n\n\t// Checking value to have 11 digits only\n\tif ( value.length !== 11 ) {\n\t\treturn false;\n\t}\n\n\tvar sum = 0,\n\t\tfirstCN, secondCN, checkResult, i;\n\n\tfirstCN = parseInt( value.substring( 9, 10 ), 10 );\n\tsecondCN = parseInt( value.substring( 10, 11 ), 10 );\n\n\tcheckResult = function( sum, cn ) {\n\t\tvar result = ( sum * 10 ) % 11;\n\t\tif ( ( result === 10 ) || ( result === 11 ) ) {\n\t\t\tresult = 0;\n\t\t}\n\t\treturn ( result === cn );\n\t};\n\n\t// Checking for dump data\n\tif ( value === \"\" ||\n\t\tvalue === \"00000000000\" ||\n\t\tvalue === \"11111111111\" ||\n\t\tvalue === \"22222222222\" ||\n\t\tvalue === \"33333333333\" ||\n\t\tvalue === \"44444444444\" ||\n\t\tvalue === \"55555555555\" ||\n\t\tvalue === \"66666666666\" ||\n\t\tvalue === \"77777777777\" ||\n\t\tvalue === \"88888888888\" ||\n\t\tvalue === \"99999999999\"\n\t) {\n\t\treturn false;\n\t}\n\n\t// Step 1 - using first Check Number:\n\tfor ( i = 1; i <= 9; i++ ) {\n\t\tsum = sum + parseInt( value.substring( i - 1, i ), 10 ) * ( 11 - i );\n\t}\n\n\t// If first Check Number (CN) is valid, move to Step 2 - using second Check Number:\n\tif ( checkResult( sum, firstCN ) ) {\n\t\tsum = 0;\n\t\tfor ( i = 1; i <= 10; i++ ) {\n\t\t\tsum = sum + parseInt( value.substring( i - 1, i ), 10 ) * ( 12 - i );\n\t\t}\n\t\treturn checkResult( sum, secondCN );\n\t}\n\treturn false;\n\n}, \"Please specify a valid CPF number\" );\n\n// https://jqueryvalidation.org/creditcard-method/\n// based on https://en.wikipedia.org/wiki/Luhn_algorithm\n$.validator.addMethod( \"creditcard\", function( value, element ) {\n\tif ( this.optional( element ) ) {\n\t\treturn \"dependency-mismatch\";\n\t}\n\n\t// Accept only spaces, digits and dashes\n\tif ( /[^0-9 \\-]+/.test( value ) ) {\n\t\treturn false;\n\t}\n\n\tvar nCheck = 0,\n\t\tnDigit = 0,\n\t\tbEven = false,\n\t\tn, cDigit;\n\n\tvalue = value.replace( /\\D/g, \"\" );\n\n\t// Basing min and max length on\n\t// https://developer.ean.com/general_info/Valid_Credit_Card_Types\n\tif ( value.length < 13 || value.length > 19 ) {\n\t\treturn false;\n\t}\n\n\tfor ( n = value.length - 1; n >= 0; n-- ) {\n\t\tcDigit = value.charAt( n );\n\t\tnDigit = parseInt( cDigit, 10 );\n\t\tif ( bEven ) {\n\t\t\tif ( ( nDigit *= 2 ) > 9 ) {\n\t\t\t\tnDigit -= 9;\n\t\t\t}\n\t\t}\n\n\t\tnCheck += nDigit;\n\t\tbEven = !bEven;\n\t}\n\n\treturn ( nCheck % 10 ) === 0;\n}, \"Please enter a valid credit card number.\" );\n\n/* NOTICE: Modified version of Castle.Components.Validator.CreditCardValidator\n * Redistributed under the the Apache License 2.0 at http://www.apache.org/licenses/LICENSE-2.0\n * Valid Types: mastercard, visa, amex, dinersclub, enroute, discover, jcb, unknown, all (overrides all other settings)\n */\n$.validator.addMethod( \"creditcardtypes\", function( value, element, param ) {\n\tif ( /[^0-9\\-]+/.test( value ) ) {\n\t\treturn false;\n\t}\n\n\tvalue = value.replace( /\\D/g, \"\" );\n\n\tvar validTypes = 0x0000;\n\n\tif ( param.mastercard ) {\n\t\tvalidTypes |= 0x0001;\n\t}\n\tif ( param.visa ) {\n\t\tvalidTypes |= 0x0002;\n\t}\n\tif ( param.amex ) {\n\t\tvalidTypes |= 0x0004;\n\t}\n\tif ( param.dinersclub ) {\n\t\tvalidTypes |= 0x0008;\n\t}\n\tif ( param.enroute ) {\n\t\tvalidTypes |= 0x0010;\n\t}\n\tif ( param.discover ) {\n\t\tvalidTypes |= 0x0020;\n\t}\n\tif ( param.jcb ) {\n\t\tvalidTypes |= 0x0040;\n\t}\n\tif ( param.unknown ) {\n\t\tvalidTypes |= 0x0080;\n\t}\n\tif ( param.all ) {\n\t\tvalidTypes = 0x0001 | 0x0002 | 0x0004 | 0x0008 | 0x0010 | 0x0020 | 0x0040 | 0x0080;\n\t}\n\tif ( validTypes & 0x0001 && /^(5[12345])/.test( value ) ) { // Mastercard\n\t\treturn value.length === 16;\n\t}\n\tif ( validTypes & 0x0002 && /^(4)/.test( value ) ) { // Visa\n\t\treturn value.length === 16;\n\t}\n\tif ( validTypes & 0x0004 && /^(3[47])/.test( value ) ) { // Amex\n\t\treturn value.length === 15;\n\t}\n\tif ( validTypes & 0x0008 && /^(3(0[012345]|[68]))/.test( value ) ) { // Dinersclub\n\t\treturn value.length === 14;\n\t}\n\tif ( validTypes & 0x0010 && /^(2(014|149))/.test( value ) ) { // Enroute\n\t\treturn value.length === 15;\n\t}\n\tif ( validTypes & 0x0020 && /^(6011)/.test( value ) ) { // Discover\n\t\treturn value.length === 16;\n\t}\n\tif ( validTypes & 0x0040 && /^(3)/.test( value ) ) { // Jcb\n\t\treturn value.length === 16;\n\t}\n\tif ( validTypes & 0x0040 && /^(2131|1800)/.test( value ) ) { // Jcb\n\t\treturn value.length === 15;\n\t}\n\tif ( validTypes & 0x0080 ) { // Unknown\n\t\treturn true;\n\t}\n\treturn false;\n}, \"Please enter a valid credit card number.\" );\n\n/**\n * Validates currencies with any given symbols by @jameslouiz\n * Symbols can be optional or required. Symbols required by default\n *\n * Usage examples:\n *  currency: [\"£\", false] - Use false for soft currency validation\n *  currency: [\"$\", false]\n *  currency: [\"RM\", false] - also works with text based symbols such as \"RM\" - Malaysia Ringgit etc\n *\n *  <input class=\"currencyInput\" name=\"currencyInput\">\n *\n * Soft symbol checking\n *  currencyInput: {\n *     currency: [\"$\", false]\n *  }\n *\n * Strict symbol checking (default)\n *  currencyInput: {\n *     currency: \"$\"\n *     //OR\n *     currency: [\"$\", true]\n *  }\n *\n * Multiple Symbols\n *  currencyInput: {\n *     currency: \"$,£,¢\"\n *  }\n */\n$.validator.addMethod( \"currency\", function( value, element, param ) {\n    var isParamString = typeof param === \"string\",\n        symbol = isParamString ? param : param[ 0 ],\n        soft = isParamString ? true : param[ 1 ],\n        regex;\n\n    symbol = symbol.replace( /,/g, \"\" );\n    symbol = soft ? symbol + \"]\" : symbol + \"]?\";\n    regex = \"^[\" + symbol + \"([1-9]{1}[0-9]{0,2}(\\\\,[0-9]{3})*(\\\\.[0-9]{0,2})?|[1-9]{1}[0-9]{0,}(\\\\.[0-9]{0,2})?|0(\\\\.[0-9]{0,2})?|(\\\\.[0-9]{1,2})?)$\";\n    regex = new RegExp( regex );\n    return this.optional( element ) || regex.test( value );\n\n}, \"Please specify a valid currency\" );\n\n$.validator.addMethod( \"dateFA\", function( value, element ) {\n\treturn this.optional( element ) || /^[1-4]\\d{3}\\/((0?[1-6]\\/((3[0-1])|([1-2][0-9])|(0?[1-9])))|((1[0-2]|(0?[7-9]))\\/(30|([1-2][0-9])|(0?[1-9]))))$/.test( value );\n}, $.validator.messages.date );\n\n/**\n * Return true, if the value is a valid date, also making this formal check dd/mm/yyyy.\n *\n * @example $.validator.methods.date(\"01/01/1900\")\n * @result true\n *\n * @example $.validator.methods.date(\"01/13/1990\")\n * @result false\n *\n * @example $.validator.methods.date(\"01.01.1900\")\n * @result false\n *\n * @example <input name=\"pippo\" class=\"{dateITA:true}\" />\n * @desc Declares an optional input element whose value must be a valid date.\n *\n * @name $.validator.methods.dateITA\n * @type Boolean\n * @cat Plugins/Validate/Methods\n */\n$.validator.addMethod( \"dateITA\", function( value, element ) {\n\tvar check = false,\n\t\tre = /^\\d{1,2}\\/\\d{1,2}\\/\\d{4}$/,\n\t\tadata, gg, mm, aaaa, xdata;\n\tif ( re.test( value ) ) {\n\t\tadata = value.split( \"/\" );\n\t\tgg = parseInt( adata[ 0 ], 10 );\n\t\tmm = parseInt( adata[ 1 ], 10 );\n\t\taaaa = parseInt( adata[ 2 ], 10 );\n\t\txdata = new Date( Date.UTC( aaaa, mm - 1, gg, 12, 0, 0, 0 ) );\n\t\tif ( ( xdata.getUTCFullYear() === aaaa ) && ( xdata.getUTCMonth() === mm - 1 ) && ( xdata.getUTCDate() === gg ) ) {\n\t\t\tcheck = true;\n\t\t} else {\n\t\t\tcheck = false;\n\t\t}\n\t} else {\n\t\tcheck = false;\n\t}\n\treturn this.optional( element ) || check;\n}, $.validator.messages.date );\n\n$.validator.addMethod( \"dateNL\", function( value, element ) {\n\treturn this.optional( element ) || /^(0?[1-9]|[12]\\d|3[01])[\\.\\/\\-](0?[1-9]|1[012])[\\.\\/\\-]([12]\\d)?(\\d\\d)$/.test( value );\n}, $.validator.messages.date );\n\n// Older \"accept\" file extension method. Old docs: http://docs.jquery.com/Plugins/Validation/Methods/accept\n$.validator.addMethod( \"extension\", function( value, element, param ) {\n\tparam = typeof param === \"string\" ? param.replace( /,/g, \"|\" ) : \"png|jpe?g|gif\";\n\treturn this.optional( element ) || value.match( new RegExp( \"\\\\.(\" + param + \")$\", \"i\" ) );\n}, $.validator.format( \"Please enter a value with a valid extension.\" ) );\n\n/**\n * Dutch giro account numbers (not bank numbers) have max 7 digits\n */\n$.validator.addMethod( \"giroaccountNL\", function( value, element ) {\n\treturn this.optional( element ) || /^[0-9]{1,7}$/.test( value );\n}, \"Please specify a valid giro account number\" );\n\n/**\n * IBAN is the international bank account number.\n * It has a country - specific format, that is checked here too\n *\n * Validation is case-insensitive. Please make sure to normalize input yourself.\n */\n$.validator.addMethod( \"iban\", function( value, element ) {\n\n\t// Some quick simple tests to prevent needless work\n\tif ( this.optional( element ) ) {\n\t\treturn true;\n\t}\n\n\t// Remove spaces and to upper case\n\tvar iban = value.replace( / /g, \"\" ).toUpperCase(),\n\t\tibancheckdigits = \"\",\n\t\tleadingZeroes = true,\n\t\tcRest = \"\",\n\t\tcOperator = \"\",\n\t\tcountrycode, ibancheck, charAt, cChar, bbanpattern, bbancountrypatterns, ibanregexp, i, p;\n\n\t// Check for IBAN code length.\n\t// It contains:\n\t// country code ISO 3166-1 - two letters,\n\t// two check digits,\n\t// Basic Bank Account Number (BBAN) - up to 30 chars\n\tvar minimalIBANlength = 5;\n\tif ( iban.length < minimalIBANlength ) {\n\t\treturn false;\n\t}\n\n\t// Check the country code and find the country specific format\n\tcountrycode = iban.substring( 0, 2 );\n\tbbancountrypatterns = {\n\t\t\"AL\": \"\\\\d{8}[\\\\dA-Z]{16}\",\n\t\t\"AD\": \"\\\\d{8}[\\\\dA-Z]{12}\",\n\t\t\"AT\": \"\\\\d{16}\",\n\t\t\"AZ\": \"[\\\\dA-Z]{4}\\\\d{20}\",\n\t\t\"BE\": \"\\\\d{12}\",\n\t\t\"BH\": \"[A-Z]{4}[\\\\dA-Z]{14}\",\n\t\t\"BA\": \"\\\\d{16}\",\n\t\t\"BR\": \"\\\\d{23}[A-Z][\\\\dA-Z]\",\n\t\t\"BG\": \"[A-Z]{4}\\\\d{6}[\\\\dA-Z]{8}\",\n\t\t\"CR\": \"\\\\d{17}\",\n\t\t\"HR\": \"\\\\d{17}\",\n\t\t\"CY\": \"\\\\d{8}[\\\\dA-Z]{16}\",\n\t\t\"CZ\": \"\\\\d{20}\",\n\t\t\"DK\": \"\\\\d{14}\",\n\t\t\"DO\": \"[A-Z]{4}\\\\d{20}\",\n\t\t\"EE\": \"\\\\d{16}\",\n\t\t\"FO\": \"\\\\d{14}\",\n\t\t\"FI\": \"\\\\d{14}\",\n\t\t\"FR\": \"\\\\d{10}[\\\\dA-Z]{11}\\\\d{2}\",\n\t\t\"GE\": \"[\\\\dA-Z]{2}\\\\d{16}\",\n\t\t\"DE\": \"\\\\d{18}\",\n\t\t\"GI\": \"[A-Z]{4}[\\\\dA-Z]{15}\",\n\t\t\"GR\": \"\\\\d{7}[\\\\dA-Z]{16}\",\n\t\t\"GL\": \"\\\\d{14}\",\n\t\t\"GT\": \"[\\\\dA-Z]{4}[\\\\dA-Z]{20}\",\n\t\t\"HU\": \"\\\\d{24}\",\n\t\t\"IS\": \"\\\\d{22}\",\n\t\t\"IE\": \"[\\\\dA-Z]{4}\\\\d{14}\",\n\t\t\"IL\": \"\\\\d{19}\",\n\t\t\"IT\": \"[A-Z]\\\\d{10}[\\\\dA-Z]{12}\",\n\t\t\"KZ\": \"\\\\d{3}[\\\\dA-Z]{13}\",\n\t\t\"KW\": \"[A-Z]{4}[\\\\dA-Z]{22}\",\n\t\t\"LV\": \"[A-Z]{4}[\\\\dA-Z]{13}\",\n\t\t\"LB\": \"\\\\d{4}[\\\\dA-Z]{20}\",\n\t\t\"LI\": \"\\\\d{5}[\\\\dA-Z]{12}\",\n\t\t\"LT\": \"\\\\d{16}\",\n\t\t\"LU\": \"\\\\d{3}[\\\\dA-Z]{13}\",\n\t\t\"MK\": \"\\\\d{3}[\\\\dA-Z]{10}\\\\d{2}\",\n\t\t\"MT\": \"[A-Z]{4}\\\\d{5}[\\\\dA-Z]{18}\",\n\t\t\"MR\": \"\\\\d{23}\",\n\t\t\"MU\": \"[A-Z]{4}\\\\d{19}[A-Z]{3}\",\n\t\t\"MC\": \"\\\\d{10}[\\\\dA-Z]{11}\\\\d{2}\",\n\t\t\"MD\": \"[\\\\dA-Z]{2}\\\\d{18}\",\n\t\t\"ME\": \"\\\\d{18}\",\n\t\t\"NL\": \"[A-Z]{4}\\\\d{10}\",\n\t\t\"NO\": \"\\\\d{11}\",\n\t\t\"PK\": \"[\\\\dA-Z]{4}\\\\d{16}\",\n\t\t\"PS\": \"[\\\\dA-Z]{4}\\\\d{21}\",\n\t\t\"PL\": \"\\\\d{24}\",\n\t\t\"PT\": \"\\\\d{21}\",\n\t\t\"RO\": \"[A-Z]{4}[\\\\dA-Z]{16}\",\n\t\t\"SM\": \"[A-Z]\\\\d{10}[\\\\dA-Z]{12}\",\n\t\t\"SA\": \"\\\\d{2}[\\\\dA-Z]{18}\",\n\t\t\"RS\": \"\\\\d{18}\",\n\t\t\"SK\": \"\\\\d{20}\",\n\t\t\"SI\": \"\\\\d{15}\",\n\t\t\"ES\": \"\\\\d{20}\",\n\t\t\"SE\": \"\\\\d{20}\",\n\t\t\"CH\": \"\\\\d{5}[\\\\dA-Z]{12}\",\n\t\t\"TN\": \"\\\\d{20}\",\n\t\t\"TR\": \"\\\\d{5}[\\\\dA-Z]{17}\",\n\t\t\"AE\": \"\\\\d{3}\\\\d{16}\",\n\t\t\"GB\": \"[A-Z]{4}\\\\d{14}\",\n\t\t\"VG\": \"[\\\\dA-Z]{4}\\\\d{16}\"\n\t};\n\n\tbbanpattern = bbancountrypatterns[ countrycode ];\n\n\t// As new countries will start using IBAN in the\n\t// future, we only check if the countrycode is known.\n\t// This prevents false negatives, while almost all\n\t// false positives introduced by this, will be caught\n\t// by the checksum validation below anyway.\n\t// Strict checking should return FALSE for unknown\n\t// countries.\n\tif ( typeof bbanpattern !== \"undefined\" ) {\n\t\tibanregexp = new RegExp( \"^[A-Z]{2}\\\\d{2}\" + bbanpattern + \"$\", \"\" );\n\t\tif ( !( ibanregexp.test( iban ) ) ) {\n\t\t\treturn false; // Invalid country specific format\n\t\t}\n\t}\n\n\t// Now check the checksum, first convert to digits\n\tibancheck = iban.substring( 4, iban.length ) + iban.substring( 0, 4 );\n\tfor ( i = 0; i < ibancheck.length; i++ ) {\n\t\tcharAt = ibancheck.charAt( i );\n\t\tif ( charAt !== \"0\" ) {\n\t\t\tleadingZeroes = false;\n\t\t}\n\t\tif ( !leadingZeroes ) {\n\t\t\tibancheckdigits += \"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ\".indexOf( charAt );\n\t\t}\n\t}\n\n\t// Calculate the result of: ibancheckdigits % 97\n\tfor ( p = 0; p < ibancheckdigits.length; p++ ) {\n\t\tcChar = ibancheckdigits.charAt( p );\n\t\tcOperator = \"\" + cRest + \"\" + cChar;\n\t\tcRest = cOperator % 97;\n\t}\n\treturn cRest === 1;\n}, \"Please specify a valid IBAN\" );\n\n$.validator.addMethod( \"integer\", function( value, element ) {\n\treturn this.optional( element ) || /^-?\\d+$/.test( value );\n}, \"A positive or negative non-decimal number please\" );\n\n$.validator.addMethod( \"ipv4\", function( value, element ) {\n\treturn this.optional( element ) || /^(25[0-5]|2[0-4]\\d|[01]?\\d\\d?)\\.(25[0-5]|2[0-4]\\d|[01]?\\d\\d?)\\.(25[0-5]|2[0-4]\\d|[01]?\\d\\d?)\\.(25[0-5]|2[0-4]\\d|[01]?\\d\\d?)$/i.test( value );\n}, \"Please enter a valid IP v4 address.\" );\n\n$.validator.addMethod( \"ipv6\", function( value, element ) {\n\treturn this.optional( element ) || /^((([0-9A-Fa-f]{1,4}:){7}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){6}:[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){5}:([0-9A-Fa-f]{1,4}:)?[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){4}:([0-9A-Fa-f]{1,4}:){0,2}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){3}:([0-9A-Fa-f]{1,4}:){0,3}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){2}:([0-9A-Fa-f]{1,4}:){0,4}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){6}((\\b((25[0-5])|(1\\d{2})|(2[0-4]\\d)|(\\d{1,2}))\\b)\\.){3}(\\b((25[0-5])|(1\\d{2})|(2[0-4]\\d)|(\\d{1,2}))\\b))|(([0-9A-Fa-f]{1,4}:){0,5}:((\\b((25[0-5])|(1\\d{2})|(2[0-4]\\d)|(\\d{1,2}))\\b)\\.){3}(\\b((25[0-5])|(1\\d{2})|(2[0-4]\\d)|(\\d{1,2}))\\b))|(::([0-9A-Fa-f]{1,4}:){0,5}((\\b((25[0-5])|(1\\d{2})|(2[0-4]\\d)|(\\d{1,2}))\\b)\\.){3}(\\b((25[0-5])|(1\\d{2})|(2[0-4]\\d)|(\\d{1,2}))\\b))|([0-9A-Fa-f]{1,4}::([0-9A-Fa-f]{1,4}:){0,5}[0-9A-Fa-f]{1,4})|(::([0-9A-Fa-f]{1,4}:){0,6}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){1,7}:))$/i.test( value );\n}, \"Please enter a valid IP v6 address.\" );\n\n$.validator.addMethod( \"lettersonly\", function( value, element ) {\n\treturn this.optional( element ) || /^[a-z]+$/i.test( value );\n}, \"Letters only please\" );\n\n$.validator.addMethod( \"letterswithbasicpunc\", function( value, element ) {\n\treturn this.optional( element ) || /^[a-z\\-.,()'\"\\s]+$/i.test( value );\n}, \"Letters or punctuation only please\" );\n\n$.validator.addMethod( \"mobileNL\", function( value, element ) {\n\treturn this.optional( element ) || /^((\\+|00(\\s|\\s?\\-\\s?)?)31(\\s|\\s?\\-\\s?)?(\\(0\\)[\\-\\s]?)?|0)6((\\s|\\s?\\-\\s?)?[0-9]){8}$/.test( value );\n}, \"Please specify a valid mobile number\" );\n\n/* For UK phone functions, do the following server side processing:\n * Compare original input with this RegEx pattern:\n * ^\\(?(?:(?:00\\)?[\\s\\-]?\\(?|\\+)(44)\\)?[\\s\\-]?\\(?(?:0\\)?[\\s\\-]?\\(?)?|0)([1-9]\\d{1,4}\\)?[\\s\\d\\-]+)$\n * Extract $1 and set $prefix to '+44<space>' if $1 is '44', otherwise set $prefix to '0'\n * Extract $2 and remove hyphens, spaces and parentheses. Phone number is combined $prefix and $2.\n * A number of very detailed GB telephone number RegEx patterns can also be found at:\n * http://www.aa-asterisk.org.uk/index.php/Regular_Expressions_for_Validating_and_Formatting_GB_Telephone_Numbers\n */\n$.validator.addMethod( \"mobileUK\", function( phone_number, element ) {\n\tphone_number = phone_number.replace( /\\(|\\)|\\s+|-/g, \"\" );\n\treturn this.optional( element ) || phone_number.length > 9 &&\n\t\tphone_number.match( /^(?:(?:(?:00\\s?|\\+)44\\s?|0)7(?:[1345789]\\d{2}|624)\\s?\\d{3}\\s?\\d{3})$/ );\n}, \"Please specify a valid mobile number\" );\n\n$.validator.addMethod( \"netmask\", function( value, element ) {\n    return this.optional( element ) || /^(254|252|248|240|224|192|128)\\.0\\.0\\.0|255\\.(254|252|248|240|224|192|128|0)\\.0\\.0|255\\.255\\.(254|252|248|240|224|192|128|0)\\.0|255\\.255\\.255\\.(254|252|248|240|224|192|128|0)/i.test( value );\n}, \"Please enter a valid netmask.\" );\n\n/*\n * The NIE (Número de Identificación de Extranjero) is a Spanish tax identification number assigned by the Spanish\n * authorities to any foreigner.\n *\n * The NIE is the equivalent of a Spaniards Número de Identificación Fiscal (NIF) which serves as a fiscal\n * identification number. The CIF number (Certificado de Identificación Fiscal) is equivalent to the NIF, but applies to\n * companies rather than individuals. The NIE consists of an 'X' or 'Y' followed by 7 or 8 digits then another letter.\n */\n$.validator.addMethod( \"nieES\", function( value, element ) {\n\t\"use strict\";\n\n\tif ( this.optional( element ) ) {\n\t\treturn true;\n\t}\n\n\tvar nieRegEx = new RegExp( /^[MXYZ]{1}[0-9]{7,8}[TRWAGMYFPDXBNJZSQVHLCKET]{1}$/gi );\n\tvar validChars = \"TRWAGMYFPDXBNJZSQVHLCKET\",\n\t\tletter = value.substr( value.length - 1 ).toUpperCase(),\n\t\tnumber;\n\n\tvalue = value.toString().toUpperCase();\n\n\t// Quick format test\n\tif ( value.length > 10 || value.length < 9 || !nieRegEx.test( value ) ) {\n\t\treturn false;\n\t}\n\n\t// X means same number\n\t// Y means number + 10000000\n\t// Z means number + 20000000\n\tvalue = value.replace( /^[X]/, \"0\" )\n\t\t.replace( /^[Y]/, \"1\" )\n\t\t.replace( /^[Z]/, \"2\" );\n\n\tnumber = value.length === 9 ? value.substr( 0, 8 ) : value.substr( 0, 9 );\n\n\treturn validChars.charAt( parseInt( number, 10 ) % 23 ) === letter;\n\n}, \"Please specify a valid NIE number.\" );\n\n/*\n * The Número de Identificación Fiscal ( NIF ) is the way tax identification used in Spain for individuals\n */\n$.validator.addMethod( \"nifES\", function( value, element ) {\n\t\"use strict\";\n\n\tif ( this.optional( element ) ) {\n\t\treturn true;\n\t}\n\n\tvalue = value.toUpperCase();\n\n\t// Basic format test\n\tif ( !value.match( \"((^[A-Z]{1}[0-9]{7}[A-Z0-9]{1}$|^[T]{1}[A-Z0-9]{8}$)|^[0-9]{8}[A-Z]{1}$)\" ) ) {\n\t\treturn false;\n\t}\n\n\t// Test NIF\n\tif ( /^[0-9]{8}[A-Z]{1}$/.test( value ) ) {\n\t\treturn ( \"TRWAGMYFPDXBNJZSQVHLCKE\".charAt( value.substring( 8, 0 ) % 23 ) === value.charAt( 8 ) );\n\t}\n\n\t// Test specials NIF (starts with K, L or M)\n\tif ( /^[KLM]{1}/.test( value ) ) {\n\t\treturn ( value[ 8 ] === \"TRWAGMYFPDXBNJZSQVHLCKE\".charAt( value.substring( 8, 1 ) % 23 ) );\n\t}\n\n\treturn false;\n\n}, \"Please specify a valid NIF number.\" );\n\n/*\n * Numer identyfikacji podatkowej ( NIP ) is the way tax identification used in Poland for companies\n */\n$.validator.addMethod( \"nipPL\", function( value ) {\n\t\"use strict\";\n\n\tvalue = value.replace( /[^0-9]/g, \"\" );\n\n\tif ( value.length !== 10 ) {\n\t\treturn false;\n\t}\n\n\tvar arrSteps = [ 6, 5, 7, 2, 3, 4, 5, 6, 7 ];\n\tvar intSum = 0;\n\tfor ( var i = 0; i < 9; i++ ) {\n\t\tintSum += arrSteps[ i ] * value[ i ];\n\t}\n\tvar int2 = intSum % 11;\n\tvar intControlNr = ( int2 === 10 ) ? 0 : int2;\n\n\treturn ( intControlNr === parseInt( value[ 9 ], 10 ) );\n}, \"Please specify a valid NIP number.\" );\n\n$.validator.addMethod( \"notEqualTo\", function( value, element, param ) {\n\treturn this.optional( element ) || !$.validator.methods.equalTo.call( this, value, element, param );\n}, \"Please enter a different value, values must not be the same.\" );\n\n$.validator.addMethod( \"nowhitespace\", function( value, element ) {\n\treturn this.optional( element ) || /^\\S+$/i.test( value );\n}, \"No white space please\" );\n\n/**\n* Return true if the field value matches the given format RegExp\n*\n* @example $.validator.methods.pattern(\"AR1004\",element,/^AR\\d{4}$/)\n* @result true\n*\n* @example $.validator.methods.pattern(\"BR1004\",element,/^AR\\d{4}$/)\n* @result false\n*\n* @name $.validator.methods.pattern\n* @type Boolean\n* @cat Plugins/Validate/Methods\n*/\n$.validator.addMethod( \"pattern\", function( value, element, param ) {\n\tif ( this.optional( element ) ) {\n\t\treturn true;\n\t}\n\tif ( typeof param === \"string\" ) {\n\t\tparam = new RegExp( \"^(?:\" + param + \")$\" );\n\t}\n\treturn param.test( value );\n}, \"Invalid format.\" );\n\n/**\n * Dutch phone numbers have 10 digits (or 11 and start with +31).\n */\n$.validator.addMethod( \"phoneNL\", function( value, element ) {\n\treturn this.optional( element ) || /^((\\+|00(\\s|\\s?\\-\\s?)?)31(\\s|\\s?\\-\\s?)?(\\(0\\)[\\-\\s]?)?|0)[1-9]((\\s|\\s?\\-\\s?)?[0-9]){8}$/.test( value );\n}, \"Please specify a valid phone number.\" );\n\n/* For UK phone functions, do the following server side processing:\n * Compare original input with this RegEx pattern:\n * ^\\(?(?:(?:00\\)?[\\s\\-]?\\(?|\\+)(44)\\)?[\\s\\-]?\\(?(?:0\\)?[\\s\\-]?\\(?)?|0)([1-9]\\d{1,4}\\)?[\\s\\d\\-]+)$\n * Extract $1 and set $prefix to '+44<space>' if $1 is '44', otherwise set $prefix to '0'\n * Extract $2 and remove hyphens, spaces and parentheses. Phone number is combined $prefix and $2.\n * A number of very detailed GB telephone number RegEx patterns can also be found at:\n * http://www.aa-asterisk.org.uk/index.php/Regular_Expressions_for_Validating_and_Formatting_GB_Telephone_Numbers\n */\n\n// Matches UK landline + mobile, accepting only 01-3 for landline or 07 for mobile to exclude many premium numbers\n$.validator.addMethod( \"phonesUK\", function( phone_number, element ) {\n\tphone_number = phone_number.replace( /\\(|\\)|\\s+|-/g, \"\" );\n\treturn this.optional( element ) || phone_number.length > 9 &&\n\t\tphone_number.match( /^(?:(?:(?:00\\s?|\\+)44\\s?|0)(?:1\\d{8,9}|[23]\\d{9}|7(?:[1345789]\\d{8}|624\\d{6})))$/ );\n}, \"Please specify a valid uk phone number\" );\n\n/* For UK phone functions, do the following server side processing:\n * Compare original input with this RegEx pattern:\n * ^\\(?(?:(?:00\\)?[\\s\\-]?\\(?|\\+)(44)\\)?[\\s\\-]?\\(?(?:0\\)?[\\s\\-]?\\(?)?|0)([1-9]\\d{1,4}\\)?[\\s\\d\\-]+)$\n * Extract $1 and set $prefix to '+44<space>' if $1 is '44', otherwise set $prefix to '0'\n * Extract $2 and remove hyphens, spaces and parentheses. Phone number is combined $prefix and $2.\n * A number of very detailed GB telephone number RegEx patterns can also be found at:\n * http://www.aa-asterisk.org.uk/index.php/Regular_Expressions_for_Validating_and_Formatting_GB_Telephone_Numbers\n */\n$.validator.addMethod( \"phoneUK\", function( phone_number, element ) {\n\tphone_number = phone_number.replace( /\\(|\\)|\\s+|-/g, \"\" );\n\treturn this.optional( element ) || phone_number.length > 9 &&\n\t\tphone_number.match( /^(?:(?:(?:00\\s?|\\+)44\\s?)|(?:\\(?0))(?:\\d{2}\\)?\\s?\\d{4}\\s?\\d{4}|\\d{3}\\)?\\s?\\d{3}\\s?\\d{3,4}|\\d{4}\\)?\\s?(?:\\d{5}|\\d{3}\\s?\\d{3})|\\d{5}\\)?\\s?\\d{4,5})$/ );\n}, \"Please specify a valid phone number\" );\n\n/**\n * Matches US phone number format\n *\n * where the area code may not start with 1 and the prefix may not start with 1\n * allows '-' or ' ' as a separator and allows parens around area code\n * some people may want to put a '1' in front of their number\n *\n * 1(212)-999-2345 or\n * 212 999 2344 or\n * 212-999-0983\n *\n * but not\n * 111-123-5434\n * and not\n * 212 123 4567\n */\n$.validator.addMethod( \"phoneUS\", function( phone_number, element ) {\n\tphone_number = phone_number.replace( /\\s+/g, \"\" );\n\treturn this.optional( element ) || phone_number.length > 9 &&\n\t\tphone_number.match( /^(\\+?1-?)?(\\([2-9]([02-9]\\d|1[02-9])\\)|[2-9]([02-9]\\d|1[02-9]))-?[2-9]([02-9]\\d|1[02-9])-?\\d{4}$/ );\n}, \"Please specify a valid phone number\" );\n\n/*\n* Valida CEPs do brasileiros:\n*\n* Formatos aceitos:\n* 99999-999\n* 99.999-999\n* 99999999\n*/\n$.validator.addMethod( \"postalcodeBR\", function( cep_value, element ) {\n\treturn this.optional( element ) || /^\\d{2}.\\d{3}-\\d{3}?$|^\\d{5}-?\\d{3}?$/.test( cep_value );\n}, \"Informe um CEP válido.\" );\n\n/**\n * Matches a valid Canadian Postal Code\n *\n * @example jQuery.validator.methods.postalCodeCA( \"H0H 0H0\", element )\n * @result true\n *\n * @example jQuery.validator.methods.postalCodeCA( \"H0H0H0\", element )\n * @result false\n *\n * @name jQuery.validator.methods.postalCodeCA\n * @type Boolean\n * @cat Plugins/Validate/Methods\n */\n$.validator.addMethod( \"postalCodeCA\", function( value, element ) {\n\treturn this.optional( element ) || /^[ABCEGHJKLMNPRSTVXY]\\d[ABCEGHJKLMNPRSTVWXYZ] *\\d[ABCEGHJKLMNPRSTVWXYZ]\\d$/i.test( value );\n}, \"Please specify a valid postal code\" );\n\n/* Matches Italian postcode (CAP) */\n$.validator.addMethod( \"postalcodeIT\", function( value, element ) {\n\treturn this.optional( element ) || /^\\d{5}$/.test( value );\n}, \"Please specify a valid postal code\" );\n\n$.validator.addMethod( \"postalcodeNL\", function( value, element ) {\n\treturn this.optional( element ) || /^[1-9][0-9]{3}\\s?[a-zA-Z]{2}$/.test( value );\n}, \"Please specify a valid postal code\" );\n\n// Matches UK postcode. Does not match to UK Channel Islands that have their own postcodes (non standard UK)\n$.validator.addMethod( \"postcodeUK\", function( value, element ) {\n\treturn this.optional( element ) || /^((([A-PR-UWYZ][0-9])|([A-PR-UWYZ][0-9][0-9])|([A-PR-UWYZ][A-HK-Y][0-9])|([A-PR-UWYZ][A-HK-Y][0-9][0-9])|([A-PR-UWYZ][0-9][A-HJKSTUW])|([A-PR-UWYZ][A-HK-Y][0-9][ABEHMNPRVWXY]))\\s?([0-9][ABD-HJLNP-UW-Z]{2})|(GIR)\\s?(0AA))$/i.test( value );\n}, \"Please specify a valid UK postcode\" );\n\n/*\n * Lets you say \"at least X inputs that match selector Y must be filled.\"\n *\n * The end result is that neither of these inputs:\n *\n *\t<input class=\"productinfo\" name=\"partnumber\">\n *\t<input class=\"productinfo\" name=\"description\">\n *\n *\t...will validate unless at least one of them is filled.\n *\n * partnumber:\t{require_from_group: [1,\".productinfo\"]},\n * description: {require_from_group: [1,\".productinfo\"]}\n *\n * options[0]: number of fields that must be filled in the group\n * options[1]: CSS selector that defines the group of conditionally required fields\n */\n$.validator.addMethod( \"require_from_group\", function( value, element, options ) {\n\tvar $fields = $( options[ 1 ], element.form ),\n\t\t$fieldsFirst = $fields.eq( 0 ),\n\t\tvalidator = $fieldsFirst.data( \"valid_req_grp\" ) ? $fieldsFirst.data( \"valid_req_grp\" ) : $.extend( {}, this ),\n\t\tisValid = $fields.filter( function() {\n\t\t\treturn validator.elementValue( this );\n\t\t} ).length >= options[ 0 ];\n\n\t// Store the cloned validator for future validation\n\t$fieldsFirst.data( \"valid_req_grp\", validator );\n\n\t// If element isn't being validated, run each require_from_group field's validation rules\n\tif ( !$( element ).data( \"being_validated\" ) ) {\n\t\t$fields.data( \"being_validated\", true );\n\t\t$fields.each( function() {\n\t\t\tvalidator.element( this );\n\t\t} );\n\t\t$fields.data( \"being_validated\", false );\n\t}\n\treturn isValid;\n}, $.validator.format( \"Please fill at least {0} of these fields.\" ) );\n\n/*\n * Lets you say \"either at least X inputs that match selector Y must be filled,\n * OR they must all be skipped (left blank).\"\n *\n * The end result, is that none of these inputs:\n *\n *\t<input class=\"productinfo\" name=\"partnumber\">\n *\t<input class=\"productinfo\" name=\"description\">\n *\t<input class=\"productinfo\" name=\"color\">\n *\n *\t...will validate unless either at least two of them are filled,\n *\tOR none of them are.\n *\n * partnumber:\t{skip_or_fill_minimum: [2,\".productinfo\"]},\n * description: {skip_or_fill_minimum: [2,\".productinfo\"]},\n * color:\t\t{skip_or_fill_minimum: [2,\".productinfo\"]}\n *\n * options[0]: number of fields that must be filled in the group\n * options[1]: CSS selector that defines the group of conditionally required fields\n *\n */\n$.validator.addMethod( \"skip_or_fill_minimum\", function( value, element, options ) {\n\tvar $fields = $( options[ 1 ], element.form ),\n\t\t$fieldsFirst = $fields.eq( 0 ),\n\t\tvalidator = $fieldsFirst.data( \"valid_skip\" ) ? $fieldsFirst.data( \"valid_skip\" ) : $.extend( {}, this ),\n\t\tnumberFilled = $fields.filter( function() {\n\t\t\treturn validator.elementValue( this );\n\t\t} ).length,\n\t\tisValid = numberFilled === 0 || numberFilled >= options[ 0 ];\n\n\t// Store the cloned validator for future validation\n\t$fieldsFirst.data( \"valid_skip\", validator );\n\n\t// If element isn't being validated, run each skip_or_fill_minimum field's validation rules\n\tif ( !$( element ).data( \"being_validated\" ) ) {\n\t\t$fields.data( \"being_validated\", true );\n\t\t$fields.each( function() {\n\t\t\tvalidator.element( this );\n\t\t} );\n\t\t$fields.data( \"being_validated\", false );\n\t}\n\treturn isValid;\n}, $.validator.format( \"Please either skip these fields or fill at least {0} of them.\" ) );\n\n/* Validates US States and/or Territories by @jdforsythe\n * Can be case insensitive or require capitalization - default is case insensitive\n * Can include US Territories or not - default does not\n * Can include US Military postal abbreviations (AA, AE, AP) - default does not\n *\n * Note: \"States\" always includes DC (District of Colombia)\n *\n * Usage examples:\n *\n *  This is the default - case insensitive, no territories, no military zones\n *  stateInput: {\n *     caseSensitive: false,\n *     includeTerritories: false,\n *     includeMilitary: false\n *  }\n *\n *  Only allow capital letters, no territories, no military zones\n *  stateInput: {\n *     caseSensitive: false\n *  }\n *\n *  Case insensitive, include territories but not military zones\n *  stateInput: {\n *     includeTerritories: true\n *  }\n *\n *  Only allow capital letters, include territories and military zones\n *  stateInput: {\n *     caseSensitive: true,\n *     includeTerritories: true,\n *     includeMilitary: true\n *  }\n *\n */\n$.validator.addMethod( \"stateUS\", function( value, element, options ) {\n\tvar isDefault = typeof options === \"undefined\",\n\t\tcaseSensitive = ( isDefault || typeof options.caseSensitive === \"undefined\" ) ? false : options.caseSensitive,\n\t\tincludeTerritories = ( isDefault || typeof options.includeTerritories === \"undefined\" ) ? false : options.includeTerritories,\n\t\tincludeMilitary = ( isDefault || typeof options.includeMilitary === \"undefined\" ) ? false : options.includeMilitary,\n\t\tregex;\n\n\tif ( !includeTerritories && !includeMilitary ) {\n\t\tregex = \"^(A[KLRZ]|C[AOT]|D[CE]|FL|GA|HI|I[ADLN]|K[SY]|LA|M[ADEINOST]|N[CDEHJMVY]|O[HKR]|PA|RI|S[CD]|T[NX]|UT|V[AT]|W[AIVY])$\";\n\t} else if ( includeTerritories && includeMilitary ) {\n\t\tregex = \"^(A[AEKLPRSZ]|C[AOT]|D[CE]|FL|G[AU]|HI|I[ADLN]|K[SY]|LA|M[ADEINOPST]|N[CDEHJMVY]|O[HKR]|P[AR]|RI|S[CD]|T[NX]|UT|V[AIT]|W[AIVY])$\";\n\t} else if ( includeTerritories ) {\n\t\tregex = \"^(A[KLRSZ]|C[AOT]|D[CE]|FL|G[AU]|HI|I[ADLN]|K[SY]|LA|M[ADEINOPST]|N[CDEHJMVY]|O[HKR]|P[AR]|RI|S[CD]|T[NX]|UT|V[AIT]|W[AIVY])$\";\n\t} else {\n\t\tregex = \"^(A[AEKLPRZ]|C[AOT]|D[CE]|FL|GA|HI|I[ADLN]|K[SY]|LA|M[ADEINOST]|N[CDEHJMVY]|O[HKR]|PA|RI|S[CD]|T[NX]|UT|V[AT]|W[AIVY])$\";\n\t}\n\n\tregex = caseSensitive ? new RegExp( regex ) : new RegExp( regex, \"i\" );\n\treturn this.optional( element ) || regex.test( value );\n}, \"Please specify a valid state\" );\n\n// TODO check if value starts with <, otherwise don't try stripping anything\n$.validator.addMethod( \"strippedminlength\", function( value, element, param ) {\n\treturn $( value ).text().length >= param;\n}, $.validator.format( \"Please enter at least {0} characters\" ) );\n\n$.validator.addMethod( \"time\", function( value, element ) {\n\treturn this.optional( element ) || /^([01]\\d|2[0-3]|[0-9])(:[0-5]\\d){1,2}$/.test( value );\n}, \"Please enter a valid time, between 00:00 and 23:59\" );\n\n$.validator.addMethod( \"time12h\", function( value, element ) {\n\treturn this.optional( element ) || /^((0?[1-9]|1[012])(:[0-5]\\d){1,2}(\\ ?[AP]M))$/i.test( value );\n}, \"Please enter a valid time in 12-hour am/pm format\" );\n\n// Same as url, but TLD is optional\n$.validator.addMethod( \"url2\", function( value, element ) {\n\treturn this.optional( element ) || /^(https?|ftp):\\/\\/(((([a-z]|\\d|-|\\.|_|~|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(%[\\da-f]{2})|[!\\$&'\\(\\)\\*\\+,;=]|:)*@)?(((\\d|[1-9]\\d|1\\d\\d|2[0-4]\\d|25[0-5])\\.(\\d|[1-9]\\d|1\\d\\d|2[0-4]\\d|25[0-5])\\.(\\d|[1-9]\\d|1\\d\\d|2[0-4]\\d|25[0-5])\\.(\\d|[1-9]\\d|1\\d\\d|2[0-4]\\d|25[0-5]))|((([a-z]|\\d|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(([a-z]|\\d|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])([a-z]|\\d|-|\\.|_|~|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])*([a-z]|\\d|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])))\\.)*(([a-z]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(([a-z]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])([a-z]|\\d|-|\\.|_|~|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])*([a-z]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])))\\.?)(:\\d*)?)(\\/((([a-z]|\\d|-|\\.|_|~|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(%[\\da-f]{2})|[!\\$&'\\(\\)\\*\\+,;=]|:|@)+(\\/(([a-z]|\\d|-|\\.|_|~|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(%[\\da-f]{2})|[!\\$&'\\(\\)\\*\\+,;=]|:|@)*)*)?)?(\\?((([a-z]|\\d|-|\\.|_|~|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(%[\\da-f]{2})|[!\\$&'\\(\\)\\*\\+,;=]|:|@)|[\\uE000-\\uF8FF]|\\/|\\?)*)?(#((([a-z]|\\d|-|\\.|_|~|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(%[\\da-f]{2})|[!\\$&'\\(\\)\\*\\+,;=]|:|@)|\\/|\\?)*)?$/i.test( value );\n}, $.validator.messages.url );\n\n/**\n * Return true, if the value is a valid vehicle identification number (VIN).\n *\n * Works with all kind of text inputs.\n *\n * @example <input type=\"text\" size=\"20\" name=\"VehicleID\" class=\"{required:true,vinUS:true}\" />\n * @desc Declares a required input element whose value must be a valid vehicle identification number.\n *\n * @name $.validator.methods.vinUS\n * @type Boolean\n * @cat Plugins/Validate/Methods\n */\n$.validator.addMethod( \"vinUS\", function( v ) {\n\tif ( v.length !== 17 ) {\n\t\treturn false;\n\t}\n\n\tvar LL = [ \"A\", \"B\", \"C\", \"D\", \"E\", \"F\", \"G\", \"H\", \"J\", \"K\", \"L\", \"M\", \"N\", \"P\", \"R\", \"S\", \"T\", \"U\", \"V\", \"W\", \"X\", \"Y\", \"Z\" ],\n\t\tVL = [ 1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 3, 4, 5, 7, 9, 2, 3, 4, 5, 6, 7, 8, 9 ],\n\t\tFL = [ 8, 7, 6, 5, 4, 3, 2, 10, 0, 9, 8, 7, 6, 5, 4, 3, 2 ],\n\t\trs = 0,\n\t\ti, n, d, f, cd, cdv;\n\n\tfor ( i = 0; i < 17; i++ ) {\n\t\tf = FL[ i ];\n\t\td = v.slice( i, i + 1 );\n\t\tif ( i === 8 ) {\n\t\t\tcdv = d;\n\t\t}\n\t\tif ( !isNaN( d ) ) {\n\t\t\td *= f;\n\t\t} else {\n\t\t\tfor ( n = 0; n < LL.length; n++ ) {\n\t\t\t\tif ( d.toUpperCase() === LL[ n ] ) {\n\t\t\t\t\td = VL[ n ];\n\t\t\t\t\td *= f;\n\t\t\t\t\tif ( isNaN( cdv ) && n === 8 ) {\n\t\t\t\t\t\tcdv = LL[ n ];\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\trs += d;\n\t}\n\tcd = rs % 11;\n\tif ( cd === 10 ) {\n\t\tcd = \"X\";\n\t}\n\tif ( cd === cdv ) {\n\t\treturn true;\n\t}\n\treturn false;\n}, \"The specified vehicle identification number (VIN) is invalid.\" );\n\n$.validator.addMethod( \"zipcodeUS\", function( value, element ) {\n\treturn this.optional( element ) || /^\\d{5}(-\\d{4})?$/.test( value );\n}, \"The specified US ZIP Code is invalid\" );\n\n$.validator.addMethod( \"ziprange\", function( value, element ) {\n\treturn this.optional( element ) || /^90[2-5]\\d\\{2\\}-\\d{4}$/.test( value );\n}, \"Your ZIP-code must be in the range 902xx-xxxx to 905xx-xxxx\" );\nreturn $;\n}));"
  },
  {
    "path": "sample/src/NimblePros.SampleToDo.Web/wwwroot/lib/jquery-validation/dist/jquery.validate.js",
    "content": "/*!\n * jQuery Validation Plugin v1.17.0\n *\n * https://jqueryvalidation.org/\n *\n * Copyright (c) 2017 Jörn Zaefferer\n * Released under the MIT license\n */\n(function( factory ) {\n\tif ( typeof define === \"function\" && define.amd ) {\n\t\tdefine( [\"jquery\"], factory );\n\t} else if (typeof module === \"object\" && module.exports) {\n\t\tmodule.exports = factory( require( \"jquery\" ) );\n\t} else {\n\t\tfactory( jQuery );\n\t}\n}(function( $ ) {\n\n$.extend( $.fn, {\n\n\t// https://jqueryvalidation.org/validate/\n\tvalidate: function( options ) {\n\n\t\t// If nothing is selected, return nothing; can't chain anyway\n\t\tif ( !this.length ) {\n\t\t\tif ( options && options.debug && window.console ) {\n\t\t\t\tconsole.warn( \"Nothing selected, can't validate, returning nothing.\" );\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\n\t\t// Check if a validator for this form was already created\n\t\tvar validator = $.data( this[ 0 ], \"validator\" );\n\t\tif ( validator ) {\n\t\t\treturn validator;\n\t\t}\n\n\t\t// Add novalidate tag if HTML5.\n\t\tthis.attr( \"novalidate\", \"novalidate\" );\n\n\t\tvalidator = new $.validator( options, this[ 0 ] );\n\t\t$.data( this[ 0 ], \"validator\", validator );\n\n\t\tif ( validator.settings.onsubmit ) {\n\n\t\t\tthis.on( \"click.validate\", \":submit\", function( event ) {\n\n\t\t\t\t// Track the used submit button to properly handle scripted\n\t\t\t\t// submits later.\n\t\t\t\tvalidator.submitButton = event.currentTarget;\n\n\t\t\t\t// Allow suppressing validation by adding a cancel class to the submit button\n\t\t\t\tif ( $( this ).hasClass( \"cancel\" ) ) {\n\t\t\t\t\tvalidator.cancelSubmit = true;\n\t\t\t\t}\n\n\t\t\t\t// Allow suppressing validation by adding the html5 formnovalidate attribute to the submit button\n\t\t\t\tif ( $( this ).attr( \"formnovalidate\" ) !== undefined ) {\n\t\t\t\t\tvalidator.cancelSubmit = true;\n\t\t\t\t}\n\t\t\t} );\n\n\t\t\t// Validate the form on submit\n\t\t\tthis.on( \"submit.validate\", function( event ) {\n\t\t\t\tif ( validator.settings.debug ) {\n\n\t\t\t\t\t// Prevent form submit to be able to see console output\n\t\t\t\t\tevent.preventDefault();\n\t\t\t\t}\n\t\t\t\tfunction handle() {\n\t\t\t\t\tvar hidden, result;\n\n\t\t\t\t\t// Insert a hidden input as a replacement for the missing submit button\n\t\t\t\t\t// The hidden input is inserted in two cases:\n\t\t\t\t\t//   - A user defined a `submitHandler`\n\t\t\t\t\t//   - There was a pending request due to `remote` method and `stopRequest()`\n\t\t\t\t\t//     was called to submit the form in case it's valid\n\t\t\t\t\tif ( validator.submitButton && ( validator.settings.submitHandler || validator.formSubmitted ) ) {\n\t\t\t\t\t\thidden = $( \"<input type='hidden'/>\" )\n\t\t\t\t\t\t\t.attr( \"name\", validator.submitButton.name )\n\t\t\t\t\t\t\t.val( $( validator.submitButton ).val() )\n\t\t\t\t\t\t\t.appendTo( validator.currentForm );\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( validator.settings.submitHandler ) {\n\t\t\t\t\t\tresult = validator.settings.submitHandler.call( validator, validator.currentForm, event );\n\t\t\t\t\t\tif ( hidden ) {\n\n\t\t\t\t\t\t\t// And clean up afterwards; thanks to no-block-scope, hidden can be referenced\n\t\t\t\t\t\t\thidden.remove();\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif ( result !== undefined ) {\n\t\t\t\t\t\t\treturn result;\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn false;\n\t\t\t\t\t}\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\n\t\t\t\t// Prevent submit for invalid forms or custom submit handlers\n\t\t\t\tif ( validator.cancelSubmit ) {\n\t\t\t\t\tvalidator.cancelSubmit = false;\n\t\t\t\t\treturn handle();\n\t\t\t\t}\n\t\t\t\tif ( validator.form() ) {\n\t\t\t\t\tif ( validator.pendingRequest ) {\n\t\t\t\t\t\tvalidator.formSubmitted = true;\n\t\t\t\t\t\treturn false;\n\t\t\t\t\t}\n\t\t\t\t\treturn handle();\n\t\t\t\t} else {\n\t\t\t\t\tvalidator.focusInvalid();\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t} );\n\t\t}\n\n\t\treturn validator;\n\t},\n\n\t// https://jqueryvalidation.org/valid/\n\tvalid: function() {\n\t\tvar valid, validator, errorList;\n\n\t\tif ( $( this[ 0 ] ).is( \"form\" ) ) {\n\t\t\tvalid = this.validate().form();\n\t\t} else {\n\t\t\terrorList = [];\n\t\t\tvalid = true;\n\t\t\tvalidator = $( this[ 0 ].form ).validate();\n\t\t\tthis.each( function() {\n\t\t\t\tvalid = validator.element( this ) && valid;\n\t\t\t\tif ( !valid ) {\n\t\t\t\t\terrorList = errorList.concat( validator.errorList );\n\t\t\t\t}\n\t\t\t} );\n\t\t\tvalidator.errorList = errorList;\n\t\t}\n\t\treturn valid;\n\t},\n\n\t// https://jqueryvalidation.org/rules/\n\trules: function( command, argument ) {\n\t\tvar element = this[ 0 ],\n\t\t\tsettings, staticRules, existingRules, data, param, filtered;\n\n\t\t// If nothing is selected, return empty object; can't chain anyway\n\t\tif ( element == null ) {\n\t\t\treturn;\n\t\t}\n\n\t\tif ( !element.form && element.hasAttribute( \"contenteditable\" ) ) {\n\t\t\telement.form = this.closest( \"form\" )[ 0 ];\n\t\t\telement.name = this.attr( \"name\" );\n\t\t}\n\n\t\tif ( element.form == null ) {\n\t\t\treturn;\n\t\t}\n\n\t\tif ( command ) {\n\t\t\tsettings = $.data( element.form, \"validator\" ).settings;\n\t\t\tstaticRules = settings.rules;\n\t\t\texistingRules = $.validator.staticRules( element );\n\t\t\tswitch ( command ) {\n\t\t\tcase \"add\":\n\t\t\t\t$.extend( existingRules, $.validator.normalizeRule( argument ) );\n\n\t\t\t\t// Remove messages from rules, but allow them to be set separately\n\t\t\t\tdelete existingRules.messages;\n\t\t\t\tstaticRules[ element.name ] = existingRules;\n\t\t\t\tif ( argument.messages ) {\n\t\t\t\t\tsettings.messages[ element.name ] = $.extend( settings.messages[ element.name ], argument.messages );\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase \"remove\":\n\t\t\t\tif ( !argument ) {\n\t\t\t\t\tdelete staticRules[ element.name ];\n\t\t\t\t\treturn existingRules;\n\t\t\t\t}\n\t\t\t\tfiltered = {};\n\t\t\t\t$.each( argument.split( /\\s/ ), function( index, method ) {\n\t\t\t\t\tfiltered[ method ] = existingRules[ method ];\n\t\t\t\t\tdelete existingRules[ method ];\n\t\t\t\t} );\n\t\t\t\treturn filtered;\n\t\t\t}\n\t\t}\n\n\t\tdata = $.validator.normalizeRules(\n\t\t$.extend(\n\t\t\t{},\n\t\t\t$.validator.classRules( element ),\n\t\t\t$.validator.attributeRules( element ),\n\t\t\t$.validator.dataRules( element ),\n\t\t\t$.validator.staticRules( element )\n\t\t), element );\n\n\t\t// Make sure required is at front\n\t\tif ( data.required ) {\n\t\t\tparam = data.required;\n\t\t\tdelete data.required;\n\t\t\tdata = $.extend( { required: param }, data );\n\t\t}\n\n\t\t// Make sure remote is at back\n\t\tif ( data.remote ) {\n\t\t\tparam = data.remote;\n\t\t\tdelete data.remote;\n\t\t\tdata = $.extend( data, { remote: param } );\n\t\t}\n\n\t\treturn data;\n\t}\n} );\n\n// Custom selectors\n$.extend( $.expr.pseudos || $.expr[ \":\" ], {\t\t// '|| $.expr[ \":\" ]' here enables backwards compatibility to jQuery 1.7. Can be removed when dropping jQ 1.7.x support\n\n\t// https://jqueryvalidation.org/blank-selector/\n\tblank: function( a ) {\n\t\treturn !$.trim( \"\" + $( a ).val() );\n\t},\n\n\t// https://jqueryvalidation.org/filled-selector/\n\tfilled: function( a ) {\n\t\tvar val = $( a ).val();\n\t\treturn val !== null && !!$.trim( \"\" + val );\n\t},\n\n\t// https://jqueryvalidation.org/unchecked-selector/\n\tunchecked: function( a ) {\n\t\treturn !$( a ).prop( \"checked\" );\n\t}\n} );\n\n// Constructor for validator\n$.validator = function( options, form ) {\n\tthis.settings = $.extend( true, {}, $.validator.defaults, options );\n\tthis.currentForm = form;\n\tthis.init();\n};\n\n// https://jqueryvalidation.org/jQuery.validator.format/\n$.validator.format = function( source, params ) {\n\tif ( arguments.length === 1 ) {\n\t\treturn function() {\n\t\t\tvar args = $.makeArray( arguments );\n\t\t\targs.unshift( source );\n\t\t\treturn $.validator.format.apply( this, args );\n\t\t};\n\t}\n\tif ( params === undefined ) {\n\t\treturn source;\n\t}\n\tif ( arguments.length > 2 && params.constructor !== Array  ) {\n\t\tparams = $.makeArray( arguments ).slice( 1 );\n\t}\n\tif ( params.constructor !== Array ) {\n\t\tparams = [ params ];\n\t}\n\t$.each( params, function( i, n ) {\n\t\tsource = source.replace( new RegExp( \"\\\\{\" + i + \"\\\\}\", \"g\" ), function() {\n\t\t\treturn n;\n\t\t} );\n\t} );\n\treturn source;\n};\n\n$.extend( $.validator, {\n\n\tdefaults: {\n\t\tmessages: {},\n\t\tgroups: {},\n\t\trules: {},\n\t\terrorClass: \"error\",\n\t\tpendingClass: \"pending\",\n\t\tvalidClass: \"valid\",\n\t\terrorElement: \"label\",\n\t\tfocusCleanup: false,\n\t\tfocusInvalid: true,\n\t\terrorContainer: $( [] ),\n\t\terrorLabelContainer: $( [] ),\n\t\tonsubmit: true,\n\t\tignore: \":hidden\",\n\t\tignoreTitle: false,\n\t\tonfocusin: function( element ) {\n\t\t\tthis.lastActive = element;\n\n\t\t\t// Hide error label and remove error class on focus if enabled\n\t\t\tif ( this.settings.focusCleanup ) {\n\t\t\t\tif ( this.settings.unhighlight ) {\n\t\t\t\t\tthis.settings.unhighlight.call( this, element, this.settings.errorClass, this.settings.validClass );\n\t\t\t\t}\n\t\t\t\tthis.hideThese( this.errorsFor( element ) );\n\t\t\t}\n\t\t},\n\t\tonfocusout: function( element ) {\n\t\t\tif ( !this.checkable( element ) && ( element.name in this.submitted || !this.optional( element ) ) ) {\n\t\t\t\tthis.element( element );\n\t\t\t}\n\t\t},\n\t\tonkeyup: function( element, event ) {\n\n\t\t\t// Avoid revalidate the field when pressing one of the following keys\n\t\t\t// Shift       => 16\n\t\t\t// Ctrl        => 17\n\t\t\t// Alt         => 18\n\t\t\t// Caps lock   => 20\n\t\t\t// End         => 35\n\t\t\t// Home        => 36\n\t\t\t// Left arrow  => 37\n\t\t\t// Up arrow    => 38\n\t\t\t// Right arrow => 39\n\t\t\t// Down arrow  => 40\n\t\t\t// Insert      => 45\n\t\t\t// Num lock    => 144\n\t\t\t// AltGr key   => 225\n\t\t\tvar excludedKeys = [\n\t\t\t\t16, 17, 18, 20, 35, 36, 37,\n\t\t\t\t38, 39, 40, 45, 144, 225\n\t\t\t];\n\n\t\t\tif ( event.which === 9 && this.elementValue( element ) === \"\" || $.inArray( event.keyCode, excludedKeys ) !== -1 ) {\n\t\t\t\treturn;\n\t\t\t} else if ( element.name in this.submitted || element.name in this.invalid ) {\n\t\t\t\tthis.element( element );\n\t\t\t}\n\t\t},\n\t\tonclick: function( element ) {\n\n\t\t\t// Click on selects, radiobuttons and checkboxes\n\t\t\tif ( element.name in this.submitted ) {\n\t\t\t\tthis.element( element );\n\n\t\t\t// Or option elements, check parent select in that case\n\t\t\t} else if ( element.parentNode.name in this.submitted ) {\n\t\t\t\tthis.element( element.parentNode );\n\t\t\t}\n\t\t},\n\t\thighlight: function( element, errorClass, validClass ) {\n\t\t\tif ( element.type === \"radio\" ) {\n\t\t\t\tthis.findByName( element.name ).addClass( errorClass ).removeClass( validClass );\n\t\t\t} else {\n\t\t\t\t$( element ).addClass( errorClass ).removeClass( validClass );\n\t\t\t}\n\t\t},\n\t\tunhighlight: function( element, errorClass, validClass ) {\n\t\t\tif ( element.type === \"radio\" ) {\n\t\t\t\tthis.findByName( element.name ).removeClass( errorClass ).addClass( validClass );\n\t\t\t} else {\n\t\t\t\t$( element ).removeClass( errorClass ).addClass( validClass );\n\t\t\t}\n\t\t}\n\t},\n\n\t// https://jqueryvalidation.org/jQuery.validator.setDefaults/\n\tsetDefaults: function( settings ) {\n\t\t$.extend( $.validator.defaults, settings );\n\t},\n\n\tmessages: {\n\t\trequired: \"This field is required.\",\n\t\tremote: \"Please fix this field.\",\n\t\temail: \"Please enter a valid email address.\",\n\t\turl: \"Please enter a valid URL.\",\n\t\tdate: \"Please enter a valid date.\",\n\t\tdateISO: \"Please enter a valid date (ISO).\",\n\t\tnumber: \"Please enter a valid number.\",\n\t\tdigits: \"Please enter only digits.\",\n\t\tequalTo: \"Please enter the same value again.\",\n\t\tmaxlength: $.validator.format( \"Please enter no more than {0} characters.\" ),\n\t\tminlength: $.validator.format( \"Please enter at least {0} characters.\" ),\n\t\trangelength: $.validator.format( \"Please enter a value between {0} and {1} characters long.\" ),\n\t\trange: $.validator.format( \"Please enter a value between {0} and {1}.\" ),\n\t\tmax: $.validator.format( \"Please enter a value less than or equal to {0}.\" ),\n\t\tmin: $.validator.format( \"Please enter a value greater than or equal to {0}.\" ),\n\t\tstep: $.validator.format( \"Please enter a multiple of {0}.\" )\n\t},\n\n\tautoCreateRanges: false,\n\n\tprototype: {\n\n\t\tinit: function() {\n\t\t\tthis.labelContainer = $( this.settings.errorLabelContainer );\n\t\t\tthis.errorContext = this.labelContainer.length && this.labelContainer || $( this.currentForm );\n\t\t\tthis.containers = $( this.settings.errorContainer ).add( this.settings.errorLabelContainer );\n\t\t\tthis.submitted = {};\n\t\t\tthis.valueCache = {};\n\t\t\tthis.pendingRequest = 0;\n\t\t\tthis.pending = {};\n\t\t\tthis.invalid = {};\n\t\t\tthis.reset();\n\n\t\t\tvar groups = ( this.groups = {} ),\n\t\t\t\trules;\n\t\t\t$.each( this.settings.groups, function( key, value ) {\n\t\t\t\tif ( typeof value === \"string\" ) {\n\t\t\t\t\tvalue = value.split( /\\s/ );\n\t\t\t\t}\n\t\t\t\t$.each( value, function( index, name ) {\n\t\t\t\t\tgroups[ name ] = key;\n\t\t\t\t} );\n\t\t\t} );\n\t\t\trules = this.settings.rules;\n\t\t\t$.each( rules, function( key, value ) {\n\t\t\t\trules[ key ] = $.validator.normalizeRule( value );\n\t\t\t} );\n\n\t\t\tfunction delegate( event ) {\n\n\t\t\t\t// Set form expando on contenteditable\n\t\t\t\tif ( !this.form && this.hasAttribute( \"contenteditable\" ) ) {\n\t\t\t\t\tthis.form = $( this ).closest( \"form\" )[ 0 ];\n\t\t\t\t\tthis.name = $( this ).attr( \"name\" );\n\t\t\t\t}\n\n\t\t\t\tvar validator = $.data( this.form, \"validator\" ),\n\t\t\t\t\teventType = \"on\" + event.type.replace( /^validate/, \"\" ),\n\t\t\t\t\tsettings = validator.settings;\n\t\t\t\tif ( settings[ eventType ] && !$( this ).is( settings.ignore ) ) {\n\t\t\t\t\tsettings[ eventType ].call( validator, this, event );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t$( this.currentForm )\n\t\t\t\t.on( \"focusin.validate focusout.validate keyup.validate\",\n\t\t\t\t\t\":text, [type='password'], [type='file'], select, textarea, [type='number'], [type='search'], \" +\n\t\t\t\t\t\"[type='tel'], [type='url'], [type='email'], [type='datetime'], [type='date'], [type='month'], \" +\n\t\t\t\t\t\"[type='week'], [type='time'], [type='datetime-local'], [type='range'], [type='color'], \" +\n\t\t\t\t\t\"[type='radio'], [type='checkbox'], [contenteditable], [type='button']\", delegate )\n\n\t\t\t\t// Support: Chrome, oldIE\n\t\t\t\t// \"select\" is provided as event.target when clicking a option\n\t\t\t\t.on( \"click.validate\", \"select, option, [type='radio'], [type='checkbox']\", delegate );\n\n\t\t\tif ( this.settings.invalidHandler ) {\n\t\t\t\t$( this.currentForm ).on( \"invalid-form.validate\", this.settings.invalidHandler );\n\t\t\t}\n\t\t},\n\n\t\t// https://jqueryvalidation.org/Validator.form/\n\t\tform: function() {\n\t\t\tthis.checkForm();\n\t\t\t$.extend( this.submitted, this.errorMap );\n\t\t\tthis.invalid = $.extend( {}, this.errorMap );\n\t\t\tif ( !this.valid() ) {\n\t\t\t\t$( this.currentForm ).triggerHandler( \"invalid-form\", [ this ] );\n\t\t\t}\n\t\t\tthis.showErrors();\n\t\t\treturn this.valid();\n\t\t},\n\n\t\tcheckForm: function() {\n\t\t\tthis.prepareForm();\n\t\t\tfor ( var i = 0, elements = ( this.currentElements = this.elements() ); elements[ i ]; i++ ) {\n\t\t\t\tthis.check( elements[ i ] );\n\t\t\t}\n\t\t\treturn this.valid();\n\t\t},\n\n\t\t// https://jqueryvalidation.org/Validator.element/\n\t\telement: function( element ) {\n\t\t\tvar cleanElement = this.clean( element ),\n\t\t\t\tcheckElement = this.validationTargetFor( cleanElement ),\n\t\t\t\tv = this,\n\t\t\t\tresult = true,\n\t\t\t\trs, group;\n\n\t\t\tif ( checkElement === undefined ) {\n\t\t\t\tdelete this.invalid[ cleanElement.name ];\n\t\t\t} else {\n\t\t\t\tthis.prepareElement( checkElement );\n\t\t\t\tthis.currentElements = $( checkElement );\n\n\t\t\t\t// If this element is grouped, then validate all group elements already\n\t\t\t\t// containing a value\n\t\t\t\tgroup = this.groups[ checkElement.name ];\n\t\t\t\tif ( group ) {\n\t\t\t\t\t$.each( this.groups, function( name, testgroup ) {\n\t\t\t\t\t\tif ( testgroup === group && name !== checkElement.name ) {\n\t\t\t\t\t\t\tcleanElement = v.validationTargetFor( v.clean( v.findByName( name ) ) );\n\t\t\t\t\t\t\tif ( cleanElement && cleanElement.name in v.invalid ) {\n\t\t\t\t\t\t\t\tv.currentElements.push( cleanElement );\n\t\t\t\t\t\t\t\tresult = v.check( cleanElement ) && result;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t} );\n\t\t\t\t}\n\n\t\t\t\trs = this.check( checkElement ) !== false;\n\t\t\t\tresult = result && rs;\n\t\t\t\tif ( rs ) {\n\t\t\t\t\tthis.invalid[ checkElement.name ] = false;\n\t\t\t\t} else {\n\t\t\t\t\tthis.invalid[ checkElement.name ] = true;\n\t\t\t\t}\n\n\t\t\t\tif ( !this.numberOfInvalids() ) {\n\n\t\t\t\t\t// Hide error containers on last error\n\t\t\t\t\tthis.toHide = this.toHide.add( this.containers );\n\t\t\t\t}\n\t\t\t\tthis.showErrors();\n\n\t\t\t\t// Add aria-invalid status for screen readers\n\t\t\t\t$( element ).attr( \"aria-invalid\", !rs );\n\t\t\t}\n\n\t\t\treturn result;\n\t\t},\n\n\t\t// https://jqueryvalidation.org/Validator.showErrors/\n\t\tshowErrors: function( errors ) {\n\t\t\tif ( errors ) {\n\t\t\t\tvar validator = this;\n\n\t\t\t\t// Add items to error list and map\n\t\t\t\t$.extend( this.errorMap, errors );\n\t\t\t\tthis.errorList = $.map( this.errorMap, function( message, name ) {\n\t\t\t\t\treturn {\n\t\t\t\t\t\tmessage: message,\n\t\t\t\t\t\telement: validator.findByName( name )[ 0 ]\n\t\t\t\t\t};\n\t\t\t\t} );\n\n\t\t\t\t// Remove items from success list\n\t\t\t\tthis.successList = $.grep( this.successList, function( element ) {\n\t\t\t\t\treturn !( element.name in errors );\n\t\t\t\t} );\n\t\t\t}\n\t\t\tif ( this.settings.showErrors ) {\n\t\t\t\tthis.settings.showErrors.call( this, this.errorMap, this.errorList );\n\t\t\t} else {\n\t\t\t\tthis.defaultShowErrors();\n\t\t\t}\n\t\t},\n\n\t\t// https://jqueryvalidation.org/Validator.resetForm/\n\t\tresetForm: function() {\n\t\t\tif ( $.fn.resetForm ) {\n\t\t\t\t$( this.currentForm ).resetForm();\n\t\t\t}\n\t\t\tthis.invalid = {};\n\t\t\tthis.submitted = {};\n\t\t\tthis.prepareForm();\n\t\t\tthis.hideErrors();\n\t\t\tvar elements = this.elements()\n\t\t\t\t.removeData( \"previousValue\" )\n\t\t\t\t.removeAttr( \"aria-invalid\" );\n\n\t\t\tthis.resetElements( elements );\n\t\t},\n\n\t\tresetElements: function( elements ) {\n\t\t\tvar i;\n\n\t\t\tif ( this.settings.unhighlight ) {\n\t\t\t\tfor ( i = 0; elements[ i ]; i++ ) {\n\t\t\t\t\tthis.settings.unhighlight.call( this, elements[ i ],\n\t\t\t\t\t\tthis.settings.errorClass, \"\" );\n\t\t\t\t\tthis.findByName( elements[ i ].name ).removeClass( this.settings.validClass );\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\telements\n\t\t\t\t\t.removeClass( this.settings.errorClass )\n\t\t\t\t\t.removeClass( this.settings.validClass );\n\t\t\t}\n\t\t},\n\n\t\tnumberOfInvalids: function() {\n\t\t\treturn this.objectLength( this.invalid );\n\t\t},\n\n\t\tobjectLength: function( obj ) {\n\t\t\t/* jshint unused: false */\n\t\t\tvar count = 0,\n\t\t\t\ti;\n\t\t\tfor ( i in obj ) {\n\n\t\t\t\t// This check allows counting elements with empty error\n\t\t\t\t// message as invalid elements\n\t\t\t\tif ( obj[ i ] !== undefined && obj[ i ] !== null && obj[ i ] !== false ) {\n\t\t\t\t\tcount++;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn count;\n\t\t},\n\n\t\thideErrors: function() {\n\t\t\tthis.hideThese( this.toHide );\n\t\t},\n\n\t\thideThese: function( errors ) {\n\t\t\terrors.not( this.containers ).text( \"\" );\n\t\t\tthis.addWrapper( errors ).hide();\n\t\t},\n\n\t\tvalid: function() {\n\t\t\treturn this.size() === 0;\n\t\t},\n\n\t\tsize: function() {\n\t\t\treturn this.errorList.length;\n\t\t},\n\n\t\tfocusInvalid: function() {\n\t\t\tif ( this.settings.focusInvalid ) {\n\t\t\t\ttry {\n\t\t\t\t\t$( this.findLastActive() || this.errorList.length && this.errorList[ 0 ].element || [] )\n\t\t\t\t\t.filter( \":visible\" )\n\t\t\t\t\t.focus()\n\n\t\t\t\t\t// Manually trigger focusin event; without it, focusin handler isn't called, findLastActive won't have anything to find\n\t\t\t\t\t.trigger( \"focusin\" );\n\t\t\t\t} catch ( e ) {\n\n\t\t\t\t\t// Ignore IE throwing errors when focusing hidden elements\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\n\t\tfindLastActive: function() {\n\t\t\tvar lastActive = this.lastActive;\n\t\t\treturn lastActive && $.grep( this.errorList, function( n ) {\n\t\t\t\treturn n.element.name === lastActive.name;\n\t\t\t} ).length === 1 && lastActive;\n\t\t},\n\n\t\telements: function() {\n\t\t\tvar validator = this,\n\t\t\t\trulesCache = {};\n\n\t\t\t// Select all valid inputs inside the form (no submit or reset buttons)\n\t\t\treturn $( this.currentForm )\n\t\t\t.find( \"input, select, textarea, [contenteditable]\" )\n\t\t\t.not( \":submit, :reset, :image, :disabled\" )\n\t\t\t.not( this.settings.ignore )\n\t\t\t.filter( function() {\n\t\t\t\tvar name = this.name || $( this ).attr( \"name\" ); // For contenteditable\n\t\t\t\tif ( !name && validator.settings.debug && window.console ) {\n\t\t\t\t\tconsole.error( \"%o has no name assigned\", this );\n\t\t\t\t}\n\n\t\t\t\t// Set form expando on contenteditable\n\t\t\t\tif ( this.hasAttribute( \"contenteditable\" ) ) {\n\t\t\t\t\tthis.form = $( this ).closest( \"form\" )[ 0 ];\n\t\t\t\t\tthis.name = name;\n\t\t\t\t}\n\n\t\t\t\t// Select only the first element for each name, and only those with rules specified\n\t\t\t\tif ( name in rulesCache || !validator.objectLength( $( this ).rules() ) ) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\n\t\t\t\trulesCache[ name ] = true;\n\t\t\t\treturn true;\n\t\t\t} );\n\t\t},\n\n\t\tclean: function( selector ) {\n\t\t\treturn $( selector )[ 0 ];\n\t\t},\n\n\t\terrors: function() {\n\t\t\tvar errorClass = this.settings.errorClass.split( \" \" ).join( \".\" );\n\t\t\treturn $( this.settings.errorElement + \".\" + errorClass, this.errorContext );\n\t\t},\n\n\t\tresetInternals: function() {\n\t\t\tthis.successList = [];\n\t\t\tthis.errorList = [];\n\t\t\tthis.errorMap = {};\n\t\t\tthis.toShow = $( [] );\n\t\t\tthis.toHide = $( [] );\n\t\t},\n\n\t\treset: function() {\n\t\t\tthis.resetInternals();\n\t\t\tthis.currentElements = $( [] );\n\t\t},\n\n\t\tprepareForm: function() {\n\t\t\tthis.reset();\n\t\t\tthis.toHide = this.errors().add( this.containers );\n\t\t},\n\n\t\tprepareElement: function( element ) {\n\t\t\tthis.reset();\n\t\t\tthis.toHide = this.errorsFor( element );\n\t\t},\n\n\t\telementValue: function( element ) {\n\t\t\tvar $element = $( element ),\n\t\t\t\ttype = element.type,\n\t\t\t\tval, idx;\n\n\t\t\tif ( type === \"radio\" || type === \"checkbox\" ) {\n\t\t\t\treturn this.findByName( element.name ).filter( \":checked\" ).val();\n\t\t\t} else if ( type === \"number\" && typeof element.validity !== \"undefined\" ) {\n\t\t\t\treturn element.validity.badInput ? \"NaN\" : $element.val();\n\t\t\t}\n\n\t\t\tif ( element.hasAttribute( \"contenteditable\" ) ) {\n\t\t\t\tval = $element.text();\n\t\t\t} else {\n\t\t\t\tval = $element.val();\n\t\t\t}\n\n\t\t\tif ( type === \"file\" ) {\n\n\t\t\t\t// Modern browser (chrome & safari)\n\t\t\t\tif ( val.substr( 0, 12 ) === \"C:\\\\fakepath\\\\\" ) {\n\t\t\t\t\treturn val.substr( 12 );\n\t\t\t\t}\n\n\t\t\t\t// Legacy browsers\n\t\t\t\t// Unix-based path\n\t\t\t\tidx = val.lastIndexOf( \"/\" );\n\t\t\t\tif ( idx >= 0 ) {\n\t\t\t\t\treturn val.substr( idx + 1 );\n\t\t\t\t}\n\n\t\t\t\t// Windows-based path\n\t\t\t\tidx = val.lastIndexOf( \"\\\\\" );\n\t\t\t\tif ( idx >= 0 ) {\n\t\t\t\t\treturn val.substr( idx + 1 );\n\t\t\t\t}\n\n\t\t\t\t// Just the file name\n\t\t\t\treturn val;\n\t\t\t}\n\n\t\t\tif ( typeof val === \"string\" ) {\n\t\t\t\treturn val.replace( /\\r/g, \"\" );\n\t\t\t}\n\t\t\treturn val;\n\t\t},\n\n\t\tcheck: function( element ) {\n\t\t\telement = this.validationTargetFor( this.clean( element ) );\n\n\t\t\tvar rules = $( element ).rules(),\n\t\t\t\trulesCount = $.map( rules, function( n, i ) {\n\t\t\t\t\treturn i;\n\t\t\t\t} ).length,\n\t\t\t\tdependencyMismatch = false,\n\t\t\t\tval = this.elementValue( element ),\n\t\t\t\tresult, method, rule, normalizer;\n\n\t\t\t// Prioritize the local normalizer defined for this element over the global one\n\t\t\t// if the former exists, otherwise user the global one in case it exists.\n\t\t\tif ( typeof rules.normalizer === \"function\" ) {\n\t\t\t\tnormalizer = rules.normalizer;\n\t\t\t} else if (\ttypeof this.settings.normalizer === \"function\" ) {\n\t\t\t\tnormalizer = this.settings.normalizer;\n\t\t\t}\n\n\t\t\t// If normalizer is defined, then call it to retrieve the changed value instead\n\t\t\t// of using the real one.\n\t\t\t// Note that `this` in the normalizer is `element`.\n\t\t\tif ( normalizer ) {\n\t\t\t\tval = normalizer.call( element, val );\n\n\t\t\t\tif ( typeof val !== \"string\" ) {\n\t\t\t\t\tthrow new TypeError( \"The normalizer should return a string value.\" );\n\t\t\t\t}\n\n\t\t\t\t// Delete the normalizer from rules to avoid treating it as a pre-defined method.\n\t\t\t\tdelete rules.normalizer;\n\t\t\t}\n\n\t\t\tfor ( method in rules ) {\n\t\t\t\trule = { method: method, parameters: rules[ method ] };\n\t\t\t\ttry {\n\t\t\t\t\tresult = $.validator.methods[ method ].call( this, val, element, rule.parameters );\n\n\t\t\t\t\t// If a method indicates that the field is optional and therefore valid,\n\t\t\t\t\t// don't mark it as valid when there are no other rules\n\t\t\t\t\tif ( result === \"dependency-mismatch\" && rulesCount === 1 ) {\n\t\t\t\t\t\tdependencyMismatch = true;\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t\tdependencyMismatch = false;\n\n\t\t\t\t\tif ( result === \"pending\" ) {\n\t\t\t\t\t\tthis.toHide = this.toHide.not( this.errorsFor( element ) );\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( !result ) {\n\t\t\t\t\t\tthis.formatAndAdd( element, rule );\n\t\t\t\t\t\treturn false;\n\t\t\t\t\t}\n\t\t\t\t} catch ( e ) {\n\t\t\t\t\tif ( this.settings.debug && window.console ) {\n\t\t\t\t\t\tconsole.log( \"Exception occurred when checking element \" + element.id + \", check the '\" + rule.method + \"' method.\", e );\n\t\t\t\t\t}\n\t\t\t\t\tif ( e instanceof TypeError ) {\n\t\t\t\t\t\te.message += \".  Exception occurred when checking element \" + element.id + \", check the '\" + rule.method + \"' method.\";\n\t\t\t\t\t}\n\n\t\t\t\t\tthrow e;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif ( dependencyMismatch ) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif ( this.objectLength( rules ) ) {\n\t\t\t\tthis.successList.push( element );\n\t\t\t}\n\t\t\treturn true;\n\t\t},\n\n\t\t// Return the custom message for the given element and validation method\n\t\t// specified in the element's HTML5 data attribute\n\t\t// return the generic message if present and no method specific message is present\n\t\tcustomDataMessage: function( element, method ) {\n\t\t\treturn $( element ).data( \"msg\" + method.charAt( 0 ).toUpperCase() +\n\t\t\t\tmethod.substring( 1 ).toLowerCase() ) || $( element ).data( \"msg\" );\n\t\t},\n\n\t\t// Return the custom message for the given element name and validation method\n\t\tcustomMessage: function( name, method ) {\n\t\t\tvar m = this.settings.messages[ name ];\n\t\t\treturn m && ( m.constructor === String ? m : m[ method ] );\n\t\t},\n\n\t\t// Return the first defined argument, allowing empty strings\n\t\tfindDefined: function() {\n\t\t\tfor ( var i = 0; i < arguments.length; i++ ) {\n\t\t\t\tif ( arguments[ i ] !== undefined ) {\n\t\t\t\t\treturn arguments[ i ];\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn undefined;\n\t\t},\n\n\t\t// The second parameter 'rule' used to be a string, and extended to an object literal\n\t\t// of the following form:\n\t\t// rule = {\n\t\t//     method: \"method name\",\n\t\t//     parameters: \"the given method parameters\"\n\t\t// }\n\t\t//\n\t\t// The old behavior still supported, kept to maintain backward compatibility with\n\t\t// old code, and will be removed in the next major release.\n\t\tdefaultMessage: function( element, rule ) {\n\t\t\tif ( typeof rule === \"string\" ) {\n\t\t\t\trule = { method: rule };\n\t\t\t}\n\n\t\t\tvar message = this.findDefined(\n\t\t\t\t\tthis.customMessage( element.name, rule.method ),\n\t\t\t\t\tthis.customDataMessage( element, rule.method ),\n\n\t\t\t\t\t// 'title' is never undefined, so handle empty string as undefined\n\t\t\t\t\t!this.settings.ignoreTitle && element.title || undefined,\n\t\t\t\t\t$.validator.messages[ rule.method ],\n\t\t\t\t\t\"<strong>Warning: No message defined for \" + element.name + \"</strong>\"\n\t\t\t\t),\n\t\t\t\ttheregex = /\\$?\\{(\\d+)\\}/g;\n\t\t\tif ( typeof message === \"function\" ) {\n\t\t\t\tmessage = message.call( this, rule.parameters, element );\n\t\t\t} else if ( theregex.test( message ) ) {\n\t\t\t\tmessage = $.validator.format( message.replace( theregex, \"{$1}\" ), rule.parameters );\n\t\t\t}\n\n\t\t\treturn message;\n\t\t},\n\n\t\tformatAndAdd: function( element, rule ) {\n\t\t\tvar message = this.defaultMessage( element, rule );\n\n\t\t\tthis.errorList.push( {\n\t\t\t\tmessage: message,\n\t\t\t\telement: element,\n\t\t\t\tmethod: rule.method\n\t\t\t} );\n\n\t\t\tthis.errorMap[ element.name ] = message;\n\t\t\tthis.submitted[ element.name ] = message;\n\t\t},\n\n\t\taddWrapper: function( toToggle ) {\n\t\t\tif ( this.settings.wrapper ) {\n\t\t\t\ttoToggle = toToggle.add( toToggle.parent( this.settings.wrapper ) );\n\t\t\t}\n\t\t\treturn toToggle;\n\t\t},\n\n\t\tdefaultShowErrors: function() {\n\t\t\tvar i, elements, error;\n\t\t\tfor ( i = 0; this.errorList[ i ]; i++ ) {\n\t\t\t\terror = this.errorList[ i ];\n\t\t\t\tif ( this.settings.highlight ) {\n\t\t\t\t\tthis.settings.highlight.call( this, error.element, this.settings.errorClass, this.settings.validClass );\n\t\t\t\t}\n\t\t\t\tthis.showLabel( error.element, error.message );\n\t\t\t}\n\t\t\tif ( this.errorList.length ) {\n\t\t\t\tthis.toShow = this.toShow.add( this.containers );\n\t\t\t}\n\t\t\tif ( this.settings.success ) {\n\t\t\t\tfor ( i = 0; this.successList[ i ]; i++ ) {\n\t\t\t\t\tthis.showLabel( this.successList[ i ] );\n\t\t\t\t}\n\t\t\t}\n\t\t\tif ( this.settings.unhighlight ) {\n\t\t\t\tfor ( i = 0, elements = this.validElements(); elements[ i ]; i++ ) {\n\t\t\t\t\tthis.settings.unhighlight.call( this, elements[ i ], this.settings.errorClass, this.settings.validClass );\n\t\t\t\t}\n\t\t\t}\n\t\t\tthis.toHide = this.toHide.not( this.toShow );\n\t\t\tthis.hideErrors();\n\t\t\tthis.addWrapper( this.toShow ).show();\n\t\t},\n\n\t\tvalidElements: function() {\n\t\t\treturn this.currentElements.not( this.invalidElements() );\n\t\t},\n\n\t\tinvalidElements: function() {\n\t\t\treturn $( this.errorList ).map( function() {\n\t\t\t\treturn this.element;\n\t\t\t} );\n\t\t},\n\n\t\tshowLabel: function( element, message ) {\n\t\t\tvar place, group, errorID, v,\n\t\t\t\terror = this.errorsFor( element ),\n\t\t\t\telementID = this.idOrName( element ),\n\t\t\t\tdescribedBy = $( element ).attr( \"aria-describedby\" );\n\n\t\t\tif ( error.length ) {\n\n\t\t\t\t// Refresh error/success class\n\t\t\t\terror.removeClass( this.settings.validClass ).addClass( this.settings.errorClass );\n\n\t\t\t\t// Replace message on existing label\n\t\t\t\terror.html( message );\n\t\t\t} else {\n\n\t\t\t\t// Create error element\n\t\t\t\terror = $( \"<\" + this.settings.errorElement + \">\" )\n\t\t\t\t\t.attr( \"id\", elementID + \"-error\" )\n\t\t\t\t\t.addClass( this.settings.errorClass )\n\t\t\t\t\t.html( message || \"\" );\n\n\t\t\t\t// Maintain reference to the element to be placed into the DOM\n\t\t\t\tplace = error;\n\t\t\t\tif ( this.settings.wrapper ) {\n\n\t\t\t\t\t// Make sure the element is visible, even in IE\n\t\t\t\t\t// actually showing the wrapped element is handled elsewhere\n\t\t\t\t\tplace = error.hide().show().wrap( \"<\" + this.settings.wrapper + \"/>\" ).parent();\n\t\t\t\t}\n\t\t\t\tif ( this.labelContainer.length ) {\n\t\t\t\t\tthis.labelContainer.append( place );\n\t\t\t\t} else if ( this.settings.errorPlacement ) {\n\t\t\t\t\tthis.settings.errorPlacement.call( this, place, $( element ) );\n\t\t\t\t} else {\n\t\t\t\t\tplace.insertAfter( element );\n\t\t\t\t}\n\n\t\t\t\t// Link error back to the element\n\t\t\t\tif ( error.is( \"label\" ) ) {\n\n\t\t\t\t\t// If the error is a label, then associate using 'for'\n\t\t\t\t\terror.attr( \"for\", elementID );\n\n\t\t\t\t\t// If the element is not a child of an associated label, then it's necessary\n\t\t\t\t\t// to explicitly apply aria-describedby\n\t\t\t\t} else if ( error.parents( \"label[for='\" + this.escapeCssMeta( elementID ) + \"']\" ).length === 0 ) {\n\t\t\t\t\terrorID = error.attr( \"id\" );\n\n\t\t\t\t\t// Respect existing non-error aria-describedby\n\t\t\t\t\tif ( !describedBy ) {\n\t\t\t\t\t\tdescribedBy = errorID;\n\t\t\t\t\t} else if ( !describedBy.match( new RegExp( \"\\\\b\" + this.escapeCssMeta( errorID ) + \"\\\\b\" ) ) ) {\n\n\t\t\t\t\t\t// Add to end of list if not already present\n\t\t\t\t\t\tdescribedBy += \" \" + errorID;\n\t\t\t\t\t}\n\t\t\t\t\t$( element ).attr( \"aria-describedby\", describedBy );\n\n\t\t\t\t\t// If this element is grouped, then assign to all elements in the same group\n\t\t\t\t\tgroup = this.groups[ element.name ];\n\t\t\t\t\tif ( group ) {\n\t\t\t\t\t\tv = this;\n\t\t\t\t\t\t$.each( v.groups, function( name, testgroup ) {\n\t\t\t\t\t\t\tif ( testgroup === group ) {\n\t\t\t\t\t\t\t\t$( \"[name='\" + v.escapeCssMeta( name ) + \"']\", v.currentForm )\n\t\t\t\t\t\t\t\t\t.attr( \"aria-describedby\", error.attr( \"id\" ) );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tif ( !message && this.settings.success ) {\n\t\t\t\terror.text( \"\" );\n\t\t\t\tif ( typeof this.settings.success === \"string\" ) {\n\t\t\t\t\terror.addClass( this.settings.success );\n\t\t\t\t} else {\n\t\t\t\t\tthis.settings.success( error, element );\n\t\t\t\t}\n\t\t\t}\n\t\t\tthis.toShow = this.toShow.add( error );\n\t\t},\n\n\t\terrorsFor: function( element ) {\n\t\t\tvar name = this.escapeCssMeta( this.idOrName( element ) ),\n\t\t\t\tdescriber = $( element ).attr( \"aria-describedby\" ),\n\t\t\t\tselector = \"label[for='\" + name + \"'], label[for='\" + name + \"'] *\";\n\n\t\t\t// 'aria-describedby' should directly reference the error element\n\t\t\tif ( describer ) {\n\t\t\t\tselector = selector + \", #\" + this.escapeCssMeta( describer )\n\t\t\t\t\t.replace( /\\s+/g, \", #\" );\n\t\t\t}\n\n\t\t\treturn this\n\t\t\t\t.errors()\n\t\t\t\t.filter( selector );\n\t\t},\n\n\t\t// See https://api.jquery.com/category/selectors/, for CSS\n\t\t// meta-characters that should be escaped in order to be used with JQuery\n\t\t// as a literal part of a name/id or any selector.\n\t\tescapeCssMeta: function( string ) {\n\t\t\treturn string.replace( /([\\\\!\"#$%&'()*+,./:;<=>?@\\[\\]^`{|}~])/g, \"\\\\$1\" );\n\t\t},\n\n\t\tidOrName: function( element ) {\n\t\t\treturn this.groups[ element.name ] || ( this.checkable( element ) ? element.name : element.id || element.name );\n\t\t},\n\n\t\tvalidationTargetFor: function( element ) {\n\n\t\t\t// If radio/checkbox, validate first element in group instead\n\t\t\tif ( this.checkable( element ) ) {\n\t\t\t\telement = this.findByName( element.name );\n\t\t\t}\n\n\t\t\t// Always apply ignore filter\n\t\t\treturn $( element ).not( this.settings.ignore )[ 0 ];\n\t\t},\n\n\t\tcheckable: function( element ) {\n\t\t\treturn ( /radio|checkbox/i ).test( element.type );\n\t\t},\n\n\t\tfindByName: function( name ) {\n\t\t\treturn $( this.currentForm ).find( \"[name='\" + this.escapeCssMeta( name ) + \"']\" );\n\t\t},\n\n\t\tgetLength: function( value, element ) {\n\t\t\tswitch ( element.nodeName.toLowerCase() ) {\n\t\t\tcase \"select\":\n\t\t\t\treturn $( \"option:selected\", element ).length;\n\t\t\tcase \"input\":\n\t\t\t\tif ( this.checkable( element ) ) {\n\t\t\t\t\treturn this.findByName( element.name ).filter( \":checked\" ).length;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn value.length;\n\t\t},\n\n\t\tdepend: function( param, element ) {\n\t\t\treturn this.dependTypes[ typeof param ] ? this.dependTypes[ typeof param ]( param, element ) : true;\n\t\t},\n\n\t\tdependTypes: {\n\t\t\t\"boolean\": function( param ) {\n\t\t\t\treturn param;\n\t\t\t},\n\t\t\t\"string\": function( param, element ) {\n\t\t\t\treturn !!$( param, element.form ).length;\n\t\t\t},\n\t\t\t\"function\": function( param, element ) {\n\t\t\t\treturn param( element );\n\t\t\t}\n\t\t},\n\n\t\toptional: function( element ) {\n\t\t\tvar val = this.elementValue( element );\n\t\t\treturn !$.validator.methods.required.call( this, val, element ) && \"dependency-mismatch\";\n\t\t},\n\n\t\tstartRequest: function( element ) {\n\t\t\tif ( !this.pending[ element.name ] ) {\n\t\t\t\tthis.pendingRequest++;\n\t\t\t\t$( element ).addClass( this.settings.pendingClass );\n\t\t\t\tthis.pending[ element.name ] = true;\n\t\t\t}\n\t\t},\n\n\t\tstopRequest: function( element, valid ) {\n\t\t\tthis.pendingRequest--;\n\n\t\t\t// Sometimes synchronization fails, make sure pendingRequest is never < 0\n\t\t\tif ( this.pendingRequest < 0 ) {\n\t\t\t\tthis.pendingRequest = 0;\n\t\t\t}\n\t\t\tdelete this.pending[ element.name ];\n\t\t\t$( element ).removeClass( this.settings.pendingClass );\n\t\t\tif ( valid && this.pendingRequest === 0 && this.formSubmitted && this.form() ) {\n\t\t\t\t$( this.currentForm ).submit();\n\n\t\t\t\t// Remove the hidden input that was used as a replacement for the\n\t\t\t\t// missing submit button. The hidden input is added by `handle()`\n\t\t\t\t// to ensure that the value of the used submit button is passed on\n\t\t\t\t// for scripted submits triggered by this method\n\t\t\t\tif ( this.submitButton ) {\n\t\t\t\t\t$( \"input:hidden[name='\" + this.submitButton.name + \"']\", this.currentForm ).remove();\n\t\t\t\t}\n\n\t\t\t\tthis.formSubmitted = false;\n\t\t\t} else if ( !valid && this.pendingRequest === 0 && this.formSubmitted ) {\n\t\t\t\t$( this.currentForm ).triggerHandler( \"invalid-form\", [ this ] );\n\t\t\t\tthis.formSubmitted = false;\n\t\t\t}\n\t\t},\n\n\t\tpreviousValue: function( element, method ) {\n\t\t\tmethod = typeof method === \"string\" && method || \"remote\";\n\n\t\t\treturn $.data( element, \"previousValue\" ) || $.data( element, \"previousValue\", {\n\t\t\t\told: null,\n\t\t\t\tvalid: true,\n\t\t\t\tmessage: this.defaultMessage( element, { method: method } )\n\t\t\t} );\n\t\t},\n\n\t\t// Cleans up all forms and elements, removes validator-specific events\n\t\tdestroy: function() {\n\t\t\tthis.resetForm();\n\n\t\t\t$( this.currentForm )\n\t\t\t\t.off( \".validate\" )\n\t\t\t\t.removeData( \"validator\" )\n\t\t\t\t.find( \".validate-equalTo-blur\" )\n\t\t\t\t\t.off( \".validate-equalTo\" )\n\t\t\t\t\t.removeClass( \"validate-equalTo-blur\" );\n\t\t}\n\n\t},\n\n\tclassRuleSettings: {\n\t\trequired: { required: true },\n\t\temail: { email: true },\n\t\turl: { url: true },\n\t\tdate: { date: true },\n\t\tdateISO: { dateISO: true },\n\t\tnumber: { number: true },\n\t\tdigits: { digits: true },\n\t\tcreditcard: { creditcard: true }\n\t},\n\n\taddClassRules: function( className, rules ) {\n\t\tif ( className.constructor === String ) {\n\t\t\tthis.classRuleSettings[ className ] = rules;\n\t\t} else {\n\t\t\t$.extend( this.classRuleSettings, className );\n\t\t}\n\t},\n\n\tclassRules: function( element ) {\n\t\tvar rules = {},\n\t\t\tclasses = $( element ).attr( \"class\" );\n\n\t\tif ( classes ) {\n\t\t\t$.each( classes.split( \" \" ), function() {\n\t\t\t\tif ( this in $.validator.classRuleSettings ) {\n\t\t\t\t\t$.extend( rules, $.validator.classRuleSettings[ this ] );\n\t\t\t\t}\n\t\t\t} );\n\t\t}\n\t\treturn rules;\n\t},\n\n\tnormalizeAttributeRule: function( rules, type, method, value ) {\n\n\t\t// Convert the value to a number for number inputs, and for text for backwards compability\n\t\t// allows type=\"date\" and others to be compared as strings\n\t\tif ( /min|max|step/.test( method ) && ( type === null || /number|range|text/.test( type ) ) ) {\n\t\t\tvalue = Number( value );\n\n\t\t\t// Support Opera Mini, which returns NaN for undefined minlength\n\t\t\tif ( isNaN( value ) ) {\n\t\t\t\tvalue = undefined;\n\t\t\t}\n\t\t}\n\n\t\tif ( value || value === 0 ) {\n\t\t\trules[ method ] = value;\n\t\t} else if ( type === method && type !== \"range\" ) {\n\n\t\t\t// Exception: the jquery validate 'range' method\n\t\t\t// does not test for the html5 'range' type\n\t\t\trules[ method ] = true;\n\t\t}\n\t},\n\n\tattributeRules: function( element ) {\n\t\tvar rules = {},\n\t\t\t$element = $( element ),\n\t\t\ttype = element.getAttribute( \"type\" ),\n\t\t\tmethod, value;\n\n\t\tfor ( method in $.validator.methods ) {\n\n\t\t\t// Support for <input required> in both html5 and older browsers\n\t\t\tif ( method === \"required\" ) {\n\t\t\t\tvalue = element.getAttribute( method );\n\n\t\t\t\t// Some browsers return an empty string for the required attribute\n\t\t\t\t// and non-HTML5 browsers might have required=\"\" markup\n\t\t\t\tif ( value === \"\" ) {\n\t\t\t\t\tvalue = true;\n\t\t\t\t}\n\n\t\t\t\t// Force non-HTML5 browsers to return bool\n\t\t\t\tvalue = !!value;\n\t\t\t} else {\n\t\t\t\tvalue = $element.attr( method );\n\t\t\t}\n\n\t\t\tthis.normalizeAttributeRule( rules, type, method, value );\n\t\t}\n\n\t\t// 'maxlength' may be returned as -1, 2147483647 ( IE ) and 524288 ( safari ) for text inputs\n\t\tif ( rules.maxlength && /-1|2147483647|524288/.test( rules.maxlength ) ) {\n\t\t\tdelete rules.maxlength;\n\t\t}\n\n\t\treturn rules;\n\t},\n\n\tdataRules: function( element ) {\n\t\tvar rules = {},\n\t\t\t$element = $( element ),\n\t\t\ttype = element.getAttribute( \"type\" ),\n\t\t\tmethod, value;\n\n\t\tfor ( method in $.validator.methods ) {\n\t\t\tvalue = $element.data( \"rule\" + method.charAt( 0 ).toUpperCase() + method.substring( 1 ).toLowerCase() );\n\t\t\tthis.normalizeAttributeRule( rules, type, method, value );\n\t\t}\n\t\treturn rules;\n\t},\n\n\tstaticRules: function( element ) {\n\t\tvar rules = {},\n\t\t\tvalidator = $.data( element.form, \"validator\" );\n\n\t\tif ( validator.settings.rules ) {\n\t\t\trules = $.validator.normalizeRule( validator.settings.rules[ element.name ] ) || {};\n\t\t}\n\t\treturn rules;\n\t},\n\n\tnormalizeRules: function( rules, element ) {\n\n\t\t// Handle dependency check\n\t\t$.each( rules, function( prop, val ) {\n\n\t\t\t// Ignore rule when param is explicitly false, eg. required:false\n\t\t\tif ( val === false ) {\n\t\t\t\tdelete rules[ prop ];\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif ( val.param || val.depends ) {\n\t\t\t\tvar keepRule = true;\n\t\t\t\tswitch ( typeof val.depends ) {\n\t\t\t\tcase \"string\":\n\t\t\t\t\tkeepRule = !!$( val.depends, element.form ).length;\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"function\":\n\t\t\t\t\tkeepRule = val.depends.call( element, element );\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tif ( keepRule ) {\n\t\t\t\t\trules[ prop ] = val.param !== undefined ? val.param : true;\n\t\t\t\t} else {\n\t\t\t\t\t$.data( element.form, \"validator\" ).resetElements( $( element ) );\n\t\t\t\t\tdelete rules[ prop ];\n\t\t\t\t}\n\t\t\t}\n\t\t} );\n\n\t\t// Evaluate parameters\n\t\t$.each( rules, function( rule, parameter ) {\n\t\t\trules[ rule ] = $.isFunction( parameter ) && rule !== \"normalizer\" ? parameter( element ) : parameter;\n\t\t} );\n\n\t\t// Clean number parameters\n\t\t$.each( [ \"minlength\", \"maxlength\" ], function() {\n\t\t\tif ( rules[ this ] ) {\n\t\t\t\trules[ this ] = Number( rules[ this ] );\n\t\t\t}\n\t\t} );\n\t\t$.each( [ \"rangelength\", \"range\" ], function() {\n\t\t\tvar parts;\n\t\t\tif ( rules[ this ] ) {\n\t\t\t\tif ( $.isArray( rules[ this ] ) ) {\n\t\t\t\t\trules[ this ] = [ Number( rules[ this ][ 0 ] ), Number( rules[ this ][ 1 ] ) ];\n\t\t\t\t} else if ( typeof rules[ this ] === \"string\" ) {\n\t\t\t\t\tparts = rules[ this ].replace( /[\\[\\]]/g, \"\" ).split( /[\\s,]+/ );\n\t\t\t\t\trules[ this ] = [ Number( parts[ 0 ] ), Number( parts[ 1 ] ) ];\n\t\t\t\t}\n\t\t\t}\n\t\t} );\n\n\t\tif ( $.validator.autoCreateRanges ) {\n\n\t\t\t// Auto-create ranges\n\t\t\tif ( rules.min != null && rules.max != null ) {\n\t\t\t\trules.range = [ rules.min, rules.max ];\n\t\t\t\tdelete rules.min;\n\t\t\t\tdelete rules.max;\n\t\t\t}\n\t\t\tif ( rules.minlength != null && rules.maxlength != null ) {\n\t\t\t\trules.rangelength = [ rules.minlength, rules.maxlength ];\n\t\t\t\tdelete rules.minlength;\n\t\t\t\tdelete rules.maxlength;\n\t\t\t}\n\t\t}\n\n\t\treturn rules;\n\t},\n\n\t// Converts a simple string to a {string: true} rule, e.g., \"required\" to {required:true}\n\tnormalizeRule: function( data ) {\n\t\tif ( typeof data === \"string\" ) {\n\t\t\tvar transformed = {};\n\t\t\t$.each( data.split( /\\s/ ), function() {\n\t\t\t\ttransformed[ this ] = true;\n\t\t\t} );\n\t\t\tdata = transformed;\n\t\t}\n\t\treturn data;\n\t},\n\n\t// https://jqueryvalidation.org/jQuery.validator.addMethod/\n\taddMethod: function( name, method, message ) {\n\t\t$.validator.methods[ name ] = method;\n\t\t$.validator.messages[ name ] = message !== undefined ? message : $.validator.messages[ name ];\n\t\tif ( method.length < 3 ) {\n\t\t\t$.validator.addClassRules( name, $.validator.normalizeRule( name ) );\n\t\t}\n\t},\n\n\t// https://jqueryvalidation.org/jQuery.validator.methods/\n\tmethods: {\n\n\t\t// https://jqueryvalidation.org/required-method/\n\t\trequired: function( value, element, param ) {\n\n\t\t\t// Check if dependency is met\n\t\t\tif ( !this.depend( param, element ) ) {\n\t\t\t\treturn \"dependency-mismatch\";\n\t\t\t}\n\t\t\tif ( element.nodeName.toLowerCase() === \"select\" ) {\n\n\t\t\t\t// Could be an array for select-multiple or a string, both are fine this way\n\t\t\t\tvar val = $( element ).val();\n\t\t\t\treturn val && val.length > 0;\n\t\t\t}\n\t\t\tif ( this.checkable( element ) ) {\n\t\t\t\treturn this.getLength( value, element ) > 0;\n\t\t\t}\n\t\t\treturn value.length > 0;\n\t\t},\n\n\t\t// https://jqueryvalidation.org/email-method/\n\t\temail: function( value, element ) {\n\n\t\t\t// From https://html.spec.whatwg.org/multipage/forms.html#valid-e-mail-address\n\t\t\t// Retrieved 2014-01-14\n\t\t\t// If you have a problem with this implementation, report a bug against the above spec\n\t\t\t// Or use custom methods to implement your own email validation\n\t\t\treturn this.optional( element ) || /^[a-zA-Z0-9.!#$%&'*+\\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/.test( value );\n\t\t},\n\n\t\t// https://jqueryvalidation.org/url-method/\n\t\turl: function( value, element ) {\n\n\t\t\t// Copyright (c) 2010-2013 Diego Perini, MIT licensed\n\t\t\t// https://gist.github.com/dperini/729294\n\t\t\t// see also https://mathiasbynens.be/demo/url-regex\n\t\t\t// modified to allow protocol-relative URLs\n\t\t\treturn this.optional( element ) || /^(?:(?:(?:https?|ftp):)?\\/\\/)(?:\\S+(?::\\S*)?@)?(?:(?!(?:10|127)(?:\\.\\d{1,3}){3})(?!(?:169\\.254|192\\.168)(?:\\.\\d{1,3}){2})(?!172\\.(?:1[6-9]|2\\d|3[0-1])(?:\\.\\d{1,3}){2})(?:[1-9]\\d?|1\\d\\d|2[01]\\d|22[0-3])(?:\\.(?:1?\\d{1,2}|2[0-4]\\d|25[0-5])){2}(?:\\.(?:[1-9]\\d?|1\\d\\d|2[0-4]\\d|25[0-4]))|(?:(?:[a-z\\u00a1-\\uffff0-9]-*)*[a-z\\u00a1-\\uffff0-9]+)(?:\\.(?:[a-z\\u00a1-\\uffff0-9]-*)*[a-z\\u00a1-\\uffff0-9]+)*(?:\\.(?:[a-z\\u00a1-\\uffff]{2,})).?)(?::\\d{2,5})?(?:[/?#]\\S*)?$/i.test( value );\n\t\t},\n\n\t\t// https://jqueryvalidation.org/date-method/\n\t\tdate: function( value, element ) {\n\t\t\treturn this.optional( element ) || !/Invalid|NaN/.test( new Date( value ).toString() );\n\t\t},\n\n\t\t// https://jqueryvalidation.org/dateISO-method/\n\t\tdateISO: function( value, element ) {\n\t\t\treturn this.optional( element ) || /^\\d{4}[\\/\\-](0?[1-9]|1[012])[\\/\\-](0?[1-9]|[12][0-9]|3[01])$/.test( value );\n\t\t},\n\n\t\t// https://jqueryvalidation.org/number-method/\n\t\tnumber: function( value, element ) {\n\t\t\treturn this.optional( element ) || /^(?:-?\\d+|-?\\d{1,3}(?:,\\d{3})+)?(?:\\.\\d+)?$/.test( value );\n\t\t},\n\n\t\t// https://jqueryvalidation.org/digits-method/\n\t\tdigits: function( value, element ) {\n\t\t\treturn this.optional( element ) || /^\\d+$/.test( value );\n\t\t},\n\n\t\t// https://jqueryvalidation.org/minlength-method/\n\t\tminlength: function( value, element, param ) {\n\t\t\tvar length = $.isArray( value ) ? value.length : this.getLength( value, element );\n\t\t\treturn this.optional( element ) || length >= param;\n\t\t},\n\n\t\t// https://jqueryvalidation.org/maxlength-method/\n\t\tmaxlength: function( value, element, param ) {\n\t\t\tvar length = $.isArray( value ) ? value.length : this.getLength( value, element );\n\t\t\treturn this.optional( element ) || length <= param;\n\t\t},\n\n\t\t// https://jqueryvalidation.org/rangelength-method/\n\t\trangelength: function( value, element, param ) {\n\t\t\tvar length = $.isArray( value ) ? value.length : this.getLength( value, element );\n\t\t\treturn this.optional( element ) || ( length >= param[ 0 ] && length <= param[ 1 ] );\n\t\t},\n\n\t\t// https://jqueryvalidation.org/min-method/\n\t\tmin: function( value, element, param ) {\n\t\t\treturn this.optional( element ) || value >= param;\n\t\t},\n\n\t\t// https://jqueryvalidation.org/max-method/\n\t\tmax: function( value, element, param ) {\n\t\t\treturn this.optional( element ) || value <= param;\n\t\t},\n\n\t\t// https://jqueryvalidation.org/range-method/\n\t\trange: function( value, element, param ) {\n\t\t\treturn this.optional( element ) || ( value >= param[ 0 ] && value <= param[ 1 ] );\n\t\t},\n\n\t\t// https://jqueryvalidation.org/step-method/\n\t\tstep: function( value, element, param ) {\n\t\t\tvar type = $( element ).attr( \"type\" ),\n\t\t\t\terrorMessage = \"Step attribute on input type \" + type + \" is not supported.\",\n\t\t\t\tsupportedTypes = [ \"text\", \"number\", \"range\" ],\n\t\t\t\tre = new RegExp( \"\\\\b\" + type + \"\\\\b\" ),\n\t\t\t\tnotSupported = type && !re.test( supportedTypes.join() ),\n\t\t\t\tdecimalPlaces = function( num ) {\n\t\t\t\t\tvar match = ( \"\" + num ).match( /(?:\\.(\\d+))?$/ );\n\t\t\t\t\tif ( !match ) {\n\t\t\t\t\t\treturn 0;\n\t\t\t\t\t}\n\n\t\t\t\t\t// Number of digits right of decimal point.\n\t\t\t\t\treturn match[ 1 ] ? match[ 1 ].length : 0;\n\t\t\t\t},\n\t\t\t\ttoInt = function( num ) {\n\t\t\t\t\treturn Math.round( num * Math.pow( 10, decimals ) );\n\t\t\t\t},\n\t\t\t\tvalid = true,\n\t\t\t\tdecimals;\n\n\t\t\t// Works only for text, number and range input types\n\t\t\t// TODO find a way to support input types date, datetime, datetime-local, month, time and week\n\t\t\tif ( notSupported ) {\n\t\t\t\tthrow new Error( errorMessage );\n\t\t\t}\n\n\t\t\tdecimals = decimalPlaces( param );\n\n\t\t\t// Value can't have too many decimals\n\t\t\tif ( decimalPlaces( value ) > decimals || toInt( value ) % toInt( param ) !== 0 ) {\n\t\t\t\tvalid = false;\n\t\t\t}\n\n\t\t\treturn this.optional( element ) || valid;\n\t\t},\n\n\t\t// https://jqueryvalidation.org/equalTo-method/\n\t\tequalTo: function( value, element, param ) {\n\n\t\t\t// Bind to the blur event of the target in order to revalidate whenever the target field is updated\n\t\t\tvar target = $( param );\n\t\t\tif ( this.settings.onfocusout && target.not( \".validate-equalTo-blur\" ).length ) {\n\t\t\t\ttarget.addClass( \"validate-equalTo-blur\" ).on( \"blur.validate-equalTo\", function() {\n\t\t\t\t\t$( element ).valid();\n\t\t\t\t} );\n\t\t\t}\n\t\t\treturn value === target.val();\n\t\t},\n\n\t\t// https://jqueryvalidation.org/remote-method/\n\t\tremote: function( value, element, param, method ) {\n\t\t\tif ( this.optional( element ) ) {\n\t\t\t\treturn \"dependency-mismatch\";\n\t\t\t}\n\n\t\t\tmethod = typeof method === \"string\" && method || \"remote\";\n\n\t\t\tvar previous = this.previousValue( element, method ),\n\t\t\t\tvalidator, data, optionDataString;\n\n\t\t\tif ( !this.settings.messages[ element.name ] ) {\n\t\t\t\tthis.settings.messages[ element.name ] = {};\n\t\t\t}\n\t\t\tprevious.originalMessage = previous.originalMessage || this.settings.messages[ element.name ][ method ];\n\t\t\tthis.settings.messages[ element.name ][ method ] = previous.message;\n\n\t\t\tparam = typeof param === \"string\" && { url: param } || param;\n\t\t\toptionDataString = $.param( $.extend( { data: value }, param.data ) );\n\t\t\tif ( previous.old === optionDataString ) {\n\t\t\t\treturn previous.valid;\n\t\t\t}\n\n\t\t\tprevious.old = optionDataString;\n\t\t\tvalidator = this;\n\t\t\tthis.startRequest( element );\n\t\t\tdata = {};\n\t\t\tdata[ element.name ] = value;\n\t\t\t$.ajax( $.extend( true, {\n\t\t\t\tmode: \"abort\",\n\t\t\t\tport: \"validate\" + element.name,\n\t\t\t\tdataType: \"json\",\n\t\t\t\tdata: data,\n\t\t\t\tcontext: validator.currentForm,\n\t\t\t\tsuccess: function( response ) {\n\t\t\t\t\tvar valid = response === true || response === \"true\",\n\t\t\t\t\t\terrors, message, submitted;\n\n\t\t\t\t\tvalidator.settings.messages[ element.name ][ method ] = previous.originalMessage;\n\t\t\t\t\tif ( valid ) {\n\t\t\t\t\t\tsubmitted = validator.formSubmitted;\n\t\t\t\t\t\tvalidator.resetInternals();\n\t\t\t\t\t\tvalidator.toHide = validator.errorsFor( element );\n\t\t\t\t\t\tvalidator.formSubmitted = submitted;\n\t\t\t\t\t\tvalidator.successList.push( element );\n\t\t\t\t\t\tvalidator.invalid[ element.name ] = false;\n\t\t\t\t\t\tvalidator.showErrors();\n\t\t\t\t\t} else {\n\t\t\t\t\t\terrors = {};\n\t\t\t\t\t\tmessage = response || validator.defaultMessage( element, { method: method, parameters: value } );\n\t\t\t\t\t\terrors[ element.name ] = previous.message = message;\n\t\t\t\t\t\tvalidator.invalid[ element.name ] = true;\n\t\t\t\t\t\tvalidator.showErrors( errors );\n\t\t\t\t\t}\n\t\t\t\t\tprevious.valid = valid;\n\t\t\t\t\tvalidator.stopRequest( element, valid );\n\t\t\t\t}\n\t\t\t}, param ) );\n\t\t\treturn \"pending\";\n\t\t}\n\t}\n\n} );\n\n// Ajax mode: abort\n// usage: $.ajax({ mode: \"abort\"[, port: \"uniqueport\"]});\n// if mode:\"abort\" is used, the previous request on that port (port can be undefined) is aborted via XMLHttpRequest.abort()\n\nvar pendingRequests = {},\n\tajax;\n\n// Use a prefilter if available (1.5+)\nif ( $.ajaxPrefilter ) {\n\t$.ajaxPrefilter( function( settings, _, xhr ) {\n\t\tvar port = settings.port;\n\t\tif ( settings.mode === \"abort\" ) {\n\t\t\tif ( pendingRequests[ port ] ) {\n\t\t\t\tpendingRequests[ port ].abort();\n\t\t\t}\n\t\t\tpendingRequests[ port ] = xhr;\n\t\t}\n\t} );\n} else {\n\n\t// Proxy ajax\n\tajax = $.ajax;\n\t$.ajax = function( settings ) {\n\t\tvar mode = ( \"mode\" in settings ? settings : $.ajaxSettings ).mode,\n\t\t\tport = ( \"port\" in settings ? settings : $.ajaxSettings ).port;\n\t\tif ( mode === \"abort\" ) {\n\t\t\tif ( pendingRequests[ port ] ) {\n\t\t\t\tpendingRequests[ port ].abort();\n\t\t\t}\n\t\t\tpendingRequests[ port ] = ajax.apply( this, arguments );\n\t\t\treturn pendingRequests[ port ];\n\t\t}\n\t\treturn ajax.apply( this, arguments );\n\t};\n}\nreturn $;\n}));\n"
  },
  {
    "path": "sample/src/NimblePros.SampleToDo.Web/wwwroot/lib/jquery-validation-unobtrusive/LICENSE.txt",
    "content": "Copyright (c) .NET Foundation. All rights reserved.\n\nLicensed under the Apache License, Version 2.0 (the \"License\"); you may not use\nthese files except in compliance with the License. You may obtain a copy of the\nLicense at\n\nhttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software distributed\nunder the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR\nCONDITIONS OF ANY KIND, either express or implied. See the License for the\nspecific language governing permissions and limitations under the License.\n"
  },
  {
    "path": "sample/src/NimblePros.SampleToDo.Web/wwwroot/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.js",
    "content": "// Unobtrusive validation support library for jQuery and jQuery Validate\n// Copyright (c) .NET Foundation. All rights reserved.\n// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.\n// @version v3.2.11\n\n/*jslint white: true, browser: true, onevar: true, undef: true, nomen: true, eqeqeq: true, plusplus: true, bitwise: true, regexp: true, newcap: true, immed: true, strict: false */\n/*global document: false, jQuery: false */\n\n(function (factory) {\n    if (typeof define === 'function' && define.amd) {\n        // AMD. Register as an anonymous module.\n        define(\"jquery.validate.unobtrusive\", ['jquery-validation'], factory);\n    } else if (typeof module === 'object' && module.exports) {\n        // CommonJS-like environments that support module.exports     \n        module.exports = factory(require('jquery-validation'));\n    } else {\n        // Browser global\n        jQuery.validator.unobtrusive = factory(jQuery);\n    }\n}(function ($) {\n    var $jQval = $.validator,\n        adapters,\n        data_validation = \"unobtrusiveValidation\";\n\n    function setValidationValues(options, ruleName, value) {\n        options.rules[ruleName] = value;\n        if (options.message) {\n            options.messages[ruleName] = options.message;\n        }\n    }\n\n    function splitAndTrim(value) {\n        return value.replace(/^\\s+|\\s+$/g, \"\").split(/\\s*,\\s*/g);\n    }\n\n    function escapeAttributeValue(value) {\n        // As mentioned on http://api.jquery.com/category/selectors/\n        return value.replace(/([!\"#$%&'()*+,./:;<=>?@\\[\\\\\\]^`{|}~])/g, \"\\\\$1\");\n    }\n\n    function getModelPrefix(fieldName) {\n        return fieldName.substr(0, fieldName.lastIndexOf(\".\") + 1);\n    }\n\n    function appendModelPrefix(value, prefix) {\n        if (value.indexOf(\"*.\") === 0) {\n            value = value.replace(\"*.\", prefix);\n        }\n        return value;\n    }\n\n    function onError(error, inputElement) {  // 'this' is the form element\n        var container = $(this).find(\"[data-valmsg-for='\" + escapeAttributeValue(inputElement[0].name) + \"']\"),\n            replaceAttrValue = container.attr(\"data-valmsg-replace\"),\n            replace = replaceAttrValue ? $.parseJSON(replaceAttrValue) !== false : null;\n\n        container.removeClass(\"field-validation-valid\").addClass(\"field-validation-error\");\n        error.data(\"unobtrusiveContainer\", container);\n\n        if (replace) {\n            container.empty();\n            error.removeClass(\"input-validation-error\").appendTo(container);\n        }\n        else {\n            error.hide();\n        }\n    }\n\n    function onErrors(event, validator) {  // 'this' is the form element\n        var container = $(this).find(\"[data-valmsg-summary=true]\"),\n            list = container.find(\"ul\");\n\n        if (list && list.length && validator.errorList.length) {\n            list.empty();\n            container.addClass(\"validation-summary-errors\").removeClass(\"validation-summary-valid\");\n\n            $.each(validator.errorList, function () {\n                $(\"<li />\").html(this.message).appendTo(list);\n            });\n        }\n    }\n\n    function onSuccess(error) {  // 'this' is the form element\n        var container = error.data(\"unobtrusiveContainer\");\n\n        if (container) {\n            var replaceAttrValue = container.attr(\"data-valmsg-replace\"),\n                replace = replaceAttrValue ? $.parseJSON(replaceAttrValue) : null;\n\n            container.addClass(\"field-validation-valid\").removeClass(\"field-validation-error\");\n            error.removeData(\"unobtrusiveContainer\");\n\n            if (replace) {\n                container.empty();\n            }\n        }\n    }\n\n    function onReset(event) {  // 'this' is the form element\n        var $form = $(this),\n            key = '__jquery_unobtrusive_validation_form_reset';\n        if ($form.data(key)) {\n            return;\n        }\n        // Set a flag that indicates we're currently resetting the form.\n        $form.data(key, true);\n        try {\n            $form.data(\"validator\").resetForm();\n        } finally {\n            $form.removeData(key);\n        }\n\n        $form.find(\".validation-summary-errors\")\n            .addClass(\"validation-summary-valid\")\n            .removeClass(\"validation-summary-errors\");\n        $form.find(\".field-validation-error\")\n            .addClass(\"field-validation-valid\")\n            .removeClass(\"field-validation-error\")\n            .removeData(\"unobtrusiveContainer\")\n            .find(\">*\")  // If we were using valmsg-replace, get the underlying error\n            .removeData(\"unobtrusiveContainer\");\n    }\n\n    function validationInfo(form) {\n        var $form = $(form),\n            result = $form.data(data_validation),\n            onResetProxy = $.proxy(onReset, form),\n            defaultOptions = $jQval.unobtrusive.options || {},\n            execInContext = function (name, args) {\n                var func = defaultOptions[name];\n                func && $.isFunction(func) && func.apply(form, args);\n            };\n\n        if (!result) {\n            result = {\n                options: {  // options structure passed to jQuery Validate's validate() method\n                    errorClass: defaultOptions.errorClass || \"input-validation-error\",\n                    errorElement: defaultOptions.errorElement || \"span\",\n                    errorPlacement: function () {\n                        onError.apply(form, arguments);\n                        execInContext(\"errorPlacement\", arguments);\n                    },\n                    invalidHandler: function () {\n                        onErrors.apply(form, arguments);\n                        execInContext(\"invalidHandler\", arguments);\n                    },\n                    messages: {},\n                    rules: {},\n                    success: function () {\n                        onSuccess.apply(form, arguments);\n                        execInContext(\"success\", arguments);\n                    }\n                },\n                attachValidation: function () {\n                    $form\n                        .off(\"reset.\" + data_validation, onResetProxy)\n                        .on(\"reset.\" + data_validation, onResetProxy)\n                        .validate(this.options);\n                },\n                validate: function () {  // a validation function that is called by unobtrusive Ajax\n                    $form.validate();\n                    return $form.valid();\n                }\n            };\n            $form.data(data_validation, result);\n        }\n\n        return result;\n    }\n\n    $jQval.unobtrusive = {\n        adapters: [],\n\n        parseElement: function (element, skipAttach) {\n            /// <summary>\n            /// Parses a single HTML element for unobtrusive validation attributes.\n            /// </summary>\n            /// <param name=\"element\" domElement=\"true\">The HTML element to be parsed.</param>\n            /// <param name=\"skipAttach\" type=\"Boolean\">[Optional] true to skip attaching the\n            /// validation to the form. If parsing just this single element, you should specify true.\n            /// If parsing several elements, you should specify false, and manually attach the validation\n            /// to the form when you are finished. The default is false.</param>\n            var $element = $(element),\n                form = $element.parents(\"form\")[0],\n                valInfo, rules, messages;\n\n            if (!form) {  // Cannot do client-side validation without a form\n                return;\n            }\n\n            valInfo = validationInfo(form);\n            valInfo.options.rules[element.name] = rules = {};\n            valInfo.options.messages[element.name] = messages = {};\n\n            $.each(this.adapters, function () {\n                var prefix = \"data-val-\" + this.name,\n                    message = $element.attr(prefix),\n                    paramValues = {};\n\n                if (message !== undefined) {  // Compare against undefined, because an empty message is legal (and falsy)\n                    prefix += \"-\";\n\n                    $.each(this.params, function () {\n                        paramValues[this] = $element.attr(prefix + this);\n                    });\n\n                    this.adapt({\n                        element: element,\n                        form: form,\n                        message: message,\n                        params: paramValues,\n                        rules: rules,\n                        messages: messages\n                    });\n                }\n            });\n\n            $.extend(rules, { \"__dummy__\": true });\n\n            if (!skipAttach) {\n                valInfo.attachValidation();\n            }\n        },\n\n        parse: function (selector) {\n            /// <summary>\n            /// Parses all the HTML elements in the specified selector. It looks for input elements decorated\n            /// with the [data-val=true] attribute value and enables validation according to the data-val-*\n            /// attribute values.\n            /// </summary>\n            /// <param name=\"selector\" type=\"String\">Any valid jQuery selector.</param>\n\n            // $forms includes all forms in selector's DOM hierarchy (parent, children and self) that have at least one\n            // element with data-val=true\n            var $selector = $(selector),\n                $forms = $selector.parents()\n                    .addBack()\n                    .filter(\"form\")\n                    .add($selector.find(\"form\"))\n                    .has(\"[data-val=true]\");\n\n            $selector.find(\"[data-val=true]\").each(function () {\n                $jQval.unobtrusive.parseElement(this, true);\n            });\n\n            $forms.each(function () {\n                var info = validationInfo(this);\n                if (info) {\n                    info.attachValidation();\n                }\n            });\n        }\n    };\n\n    adapters = $jQval.unobtrusive.adapters;\n\n    adapters.add = function (adapterName, params, fn) {\n        /// <summary>Adds a new adapter to convert unobtrusive HTML into a jQuery Validate validation.</summary>\n        /// <param name=\"adapterName\" type=\"String\">The name of the adapter to be added. This matches the name used\n        /// in the data-val-nnnn HTML attribute (where nnnn is the adapter name).</param>\n        /// <param name=\"params\" type=\"Array\" optional=\"true\">[Optional] An array of parameter names (strings) that will\n        /// be extracted from the data-val-nnnn-mmmm HTML attributes (where nnnn is the adapter name, and\n        /// mmmm is the parameter name).</param>\n        /// <param name=\"fn\" type=\"Function\">The function to call, which adapts the values from the HTML\n        /// attributes into jQuery Validate rules and/or messages.</param>\n        /// <returns type=\"jQuery.validator.unobtrusive.adapters\" />\n        if (!fn) {  // Called with no params, just a function\n            fn = params;\n            params = [];\n        }\n        this.push({ name: adapterName, params: params, adapt: fn });\n        return this;\n    };\n\n    adapters.addBool = function (adapterName, ruleName) {\n        /// <summary>Adds a new adapter to convert unobtrusive HTML into a jQuery Validate validation, where\n        /// the jQuery Validate validation rule has no parameter values.</summary>\n        /// <param name=\"adapterName\" type=\"String\">The name of the adapter to be added. This matches the name used\n        /// in the data-val-nnnn HTML attribute (where nnnn is the adapter name).</param>\n        /// <param name=\"ruleName\" type=\"String\" optional=\"true\">[Optional] The name of the jQuery Validate rule. If not provided, the value\n        /// of adapterName will be used instead.</param>\n        /// <returns type=\"jQuery.validator.unobtrusive.adapters\" />\n        return this.add(adapterName, function (options) {\n            setValidationValues(options, ruleName || adapterName, true);\n        });\n    };\n\n    adapters.addMinMax = function (adapterName, minRuleName, maxRuleName, minMaxRuleName, minAttribute, maxAttribute) {\n        /// <summary>Adds a new adapter to convert unobtrusive HTML into a jQuery Validate validation, where\n        /// the jQuery Validate validation has three potential rules (one for min-only, one for max-only, and\n        /// one for min-and-max). The HTML parameters are expected to be named -min and -max.</summary>\n        /// <param name=\"adapterName\" type=\"String\">The name of the adapter to be added. This matches the name used\n        /// in the data-val-nnnn HTML attribute (where nnnn is the adapter name).</param>\n        /// <param name=\"minRuleName\" type=\"String\">The name of the jQuery Validate rule to be used when you only\n        /// have a minimum value.</param>\n        /// <param name=\"maxRuleName\" type=\"String\">The name of the jQuery Validate rule to be used when you only\n        /// have a maximum value.</param>\n        /// <param name=\"minMaxRuleName\" type=\"String\">The name of the jQuery Validate rule to be used when you\n        /// have both a minimum and maximum value.</param>\n        /// <param name=\"minAttribute\" type=\"String\" optional=\"true\">[Optional] The name of the HTML attribute that\n        /// contains the minimum value. The default is \"min\".</param>\n        /// <param name=\"maxAttribute\" type=\"String\" optional=\"true\">[Optional] The name of the HTML attribute that\n        /// contains the maximum value. The default is \"max\".</param>\n        /// <returns type=\"jQuery.validator.unobtrusive.adapters\" />\n        return this.add(adapterName, [minAttribute || \"min\", maxAttribute || \"max\"], function (options) {\n            var min = options.params.min,\n                max = options.params.max;\n\n            if (min && max) {\n                setValidationValues(options, minMaxRuleName, [min, max]);\n            }\n            else if (min) {\n                setValidationValues(options, minRuleName, min);\n            }\n            else if (max) {\n                setValidationValues(options, maxRuleName, max);\n            }\n        });\n    };\n\n    adapters.addSingleVal = function (adapterName, attribute, ruleName) {\n        /// <summary>Adds a new adapter to convert unobtrusive HTML into a jQuery Validate validation, where\n        /// the jQuery Validate validation rule has a single value.</summary>\n        /// <param name=\"adapterName\" type=\"String\">The name of the adapter to be added. This matches the name used\n        /// in the data-val-nnnn HTML attribute(where nnnn is the adapter name).</param>\n        /// <param name=\"attribute\" type=\"String\">[Optional] The name of the HTML attribute that contains the value.\n        /// The default is \"val\".</param>\n        /// <param name=\"ruleName\" type=\"String\" optional=\"true\">[Optional] The name of the jQuery Validate rule. If not provided, the value\n        /// of adapterName will be used instead.</param>\n        /// <returns type=\"jQuery.validator.unobtrusive.adapters\" />\n        return this.add(adapterName, [attribute || \"val\"], function (options) {\n            setValidationValues(options, ruleName || adapterName, options.params[attribute]);\n        });\n    };\n\n    $jQval.addMethod(\"__dummy__\", function (value, element, params) {\n        return true;\n    });\n\n    $jQval.addMethod(\"regex\", function (value, element, params) {\n        var match;\n        if (this.optional(element)) {\n            return true;\n        }\n\n        match = new RegExp(params).exec(value);\n        return (match && (match.index === 0) && (match[0].length === value.length));\n    });\n\n    $jQval.addMethod(\"nonalphamin\", function (value, element, nonalphamin) {\n        var match;\n        if (nonalphamin) {\n            match = value.match(/\\W/g);\n            match = match && match.length >= nonalphamin;\n        }\n        return match;\n    });\n\n    if ($jQval.methods.extension) {\n        adapters.addSingleVal(\"accept\", \"mimtype\");\n        adapters.addSingleVal(\"extension\", \"extension\");\n    } else {\n        // for backward compatibility, when the 'extension' validation method does not exist, such as with versions\n        // of JQuery Validation plugin prior to 1.10, we should use the 'accept' method for\n        // validating the extension, and ignore mime-type validations as they are not supported.\n        adapters.addSingleVal(\"extension\", \"extension\", \"accept\");\n    }\n\n    adapters.addSingleVal(\"regex\", \"pattern\");\n    adapters.addBool(\"creditcard\").addBool(\"date\").addBool(\"digits\").addBool(\"email\").addBool(\"number\").addBool(\"url\");\n    adapters.addMinMax(\"length\", \"minlength\", \"maxlength\", \"rangelength\").addMinMax(\"range\", \"min\", \"max\", \"range\");\n    adapters.addMinMax(\"minlength\", \"minlength\").addMinMax(\"maxlength\", \"minlength\", \"maxlength\");\n    adapters.add(\"equalto\", [\"other\"], function (options) {\n        var prefix = getModelPrefix(options.element.name),\n            other = options.params.other,\n            fullOtherName = appendModelPrefix(other, prefix),\n            element = $(options.form).find(\":input\").filter(\"[name='\" + escapeAttributeValue(fullOtherName) + \"']\")[0];\n\n        setValidationValues(options, \"equalTo\", element);\n    });\n    adapters.add(\"required\", function (options) {\n        // jQuery Validate equates \"required\" with \"mandatory\" for checkbox elements\n        if (options.element.tagName.toUpperCase() !== \"INPUT\" || options.element.type.toUpperCase() !== \"CHECKBOX\") {\n            setValidationValues(options, \"required\", true);\n        }\n    });\n    adapters.add(\"remote\", [\"url\", \"type\", \"additionalfields\"], function (options) {\n        var value = {\n            url: options.params.url,\n            type: options.params.type || \"GET\",\n            data: {}\n        },\n            prefix = getModelPrefix(options.element.name);\n\n        $.each(splitAndTrim(options.params.additionalfields || options.element.name), function (i, fieldName) {\n            var paramName = appendModelPrefix(fieldName, prefix);\n            value.data[paramName] = function () {\n                var field = $(options.form).find(\":input\").filter(\"[name='\" + escapeAttributeValue(paramName) + \"']\");\n                // For checkboxes and radio buttons, only pick up values from checked fields.\n                if (field.is(\":checkbox\")) {\n                    return field.filter(\":checked\").val() || field.filter(\":hidden\").val() || '';\n                }\n                else if (field.is(\":radio\")) {\n                    return field.filter(\":checked\").val() || '';\n                }\n                return field.val();\n            };\n        });\n\n        setValidationValues(options, \"remote\", value);\n    });\n    adapters.add(\"password\", [\"min\", \"nonalphamin\", \"regex\"], function (options) {\n        if (options.params.min) {\n            setValidationValues(options, \"minlength\", options.params.min);\n        }\n        if (options.params.nonalphamin) {\n            setValidationValues(options, \"nonalphamin\", options.params.nonalphamin);\n        }\n        if (options.params.regex) {\n            setValidationValues(options, \"regex\", options.params.regex);\n        }\n    });\n    adapters.add(\"fileextensions\", [\"extensions\"], function (options) {\n        setValidationValues(options, \"extension\", options.params.extensions);\n    });\n\n    $(function () {\n        $jQval.unobtrusive.parse(document);\n    });\n\n    return $jQval.unobtrusive;\n}));\n"
  },
  {
    "path": "sample/tests/NimblePros.SampleToDo.FunctionalTests/Contributors/ContributorCreate.cs",
    "content": "﻿using NimblePros.SampleToDo.Web.Contributors;\nusing Shouldly;\n\nnamespace NimblePros.SampleToDo.FunctionalTests.Contributors;\n\n[Collection(\"Sequential\")]\npublic class ContributorCreate : IClassFixture<CustomWebApplicationFactory<Program>>\n{\n  private readonly HttpClient _client;\n\n  public ContributorCreate(CustomWebApplicationFactory<Program> factory)\n  {\n    _client = factory.CreateClient();\n  }\n\n  [Fact]\n  public async Task ReturnsOneContributor()\n  {\n    var testName = Guid.NewGuid().ToString();\n    var request = new CreateContributorRequest() { Name = testName };\n    var content = StringContentHelpers.FromModelAsJson(request);\n\n    var result = await _client.PostAndDeserializeAsync<CreateContributorResponse>(\n        CreateContributorRequest.Route, content);\n\n    result.Name.ShouldBe(testName);\n    result.Id.ShouldBeGreaterThan(0);\n  }\n}\n"
  },
  {
    "path": "sample/tests/NimblePros.SampleToDo.FunctionalTests/Contributors/ContributorDelete.cs",
    "content": "﻿using NimblePros.SampleToDo.Web;\nusing NimblePros.SampleToDo.Web.Contributors;\n\nnamespace NimblePros.SampleToDo.FunctionalTests.Contributors;\n\n[Collection(\"Sequential\")]\npublic class ContributorDelete : IClassFixture<CustomWebApplicationFactory<Program>>\n{\n  private readonly HttpClient _client;\n\n  public ContributorDelete(CustomWebApplicationFactory<Program> factory)\n  {\n    _client = factory.CreateClient();\n  }\n\n  [Fact]\n  public async Task DeletesExistingContributor()\n  {\n    var deleteRoute = DeleteContributorRequest.BuildRoute(SeedData.Contributor1.Id.Value);\n    _ = await _client.DeleteAndEnsureNoContentAsync(deleteRoute);\n\n    string getRoute = GetContributorByIdRequest.BuildRoute(SeedData.Contributor1.Id.Value);\n    _ = await _client.GetAndEnsureNotFoundAsync(getRoute);\n  }\n\n  [Fact]\n  public async Task ReturnsNotFoundGivenMissingContributorId()\n  {\n    int invalidId = 1000;\n    var deleteRoute = DeleteContributorRequest.BuildRoute(invalidId);\n    _ = await _client.DeleteAndEnsureNotFoundAsync(deleteRoute);\n  }\n}\n"
  },
  {
    "path": "sample/tests/NimblePros.SampleToDo.FunctionalTests/Contributors/ContributorGetById.cs",
    "content": "﻿using NimblePros.SampleToDo.Web;\nusing NimblePros.SampleToDo.Web.Contributors;\n\nnamespace NimblePros.SampleToDo.FunctionalTests.Contributors;\n\n[Collection(\"Sequential\")]\npublic class ContributorGetById : IClassFixture<CustomWebApplicationFactory<Program>>\n{\n  private readonly HttpClient _client;\n\n  public ContributorGetById(CustomWebApplicationFactory<Program> factory)\n  {\n    _client = factory.CreateClient();\n  }\n\n  [Fact]\n  public async Task ReturnsSeedContributorGivenId1()\n  {\n    var result = await _client.GetAndDeserializeAsync<ContributorRecord>(GetContributorByIdRequest.BuildRoute(1));\n\n    Assert.Equal(1, result.Id);\n    Assert.Equal(SeedData.Contributor1.Name.Value, result.Name);\n  }\n\n  [Fact]\n  public async Task ReturnsNotFoundGivenInvalidId1000()\n  {\n    string route = GetContributorByIdRequest.BuildRoute(1000);\n    _ = await _client.GetAndEnsureNotFoundAsync(route);\n  }\n}\n"
  },
  {
    "path": "sample/tests/NimblePros.SampleToDo.FunctionalTests/Contributors/ContributorList.cs",
    "content": "﻿using NimblePros.SampleToDo.Web;\nusing NimblePros.SampleToDo.Web.Contributors;\n\nnamespace NimblePros.SampleToDo.FunctionalTests.Contributors;\n\n[Collection(\"Sequential\")]\npublic class ContributorList : IClassFixture<CustomWebApplicationFactory<Program>>\n{\n  private readonly HttpClient _client;\n\n  public ContributorList(CustomWebApplicationFactory<Program> factory)\n  {\n    _client = factory.CreateClient();\n  }\n\n  [Fact]\n  public async Task ReturnsTwoContributors()\n  {\n    var result = await _client.GetAndDeserializeAsync<ContributorListResponse>(\"/Contributors\");\n\n    Assert.Equal(25, result.TotalCount);\n    Assert.Contains(result.Items, i => i.Name == \"Fake 1\");\n    Assert.Contains(result.Items, i => i.Name == \"Fake 2\");\n  }\n}\n"
  },
  {
    "path": "sample/tests/NimblePros.SampleToDo.FunctionalTests/Contributors/ContributorUpdate.cs",
    "content": "﻿using NimblePros.SampleToDo.Web;\nusing NimblePros.SampleToDo.Web.Contributors;\nusing Shouldly;\n\nnamespace NimblePros.SampleToDo.FunctionalTests.Contributors;\n\n[Collection(\"Sequential\")]\npublic class ContributorUpdate : IClassFixture<CustomWebApplicationFactory<Program>>\n{\n  private readonly HttpClient _client;\n\n  public ContributorUpdate(CustomWebApplicationFactory<Program> factory)\n  {\n    _client = factory.CreateClient();\n  }\n\n  [Fact]\n  public async Task UpdatesContributorNameAndReturnsUpdatedRecord()\n  {\n    var newName = Guid.NewGuid().ToString();\n    var request = new UpdateContributorRequest() { Id = SeedData.Contributor1.Id.Value, Name = newName };\n    var putRoute = UpdateContributorRequest.BuildRoute(SeedData.Contributor1.Id.Value);\n\n    var content = StringContentHelpers.FromModelAsJson(request);\n\n    var result = await _client.PutAndDeserializeAsync<UpdateContributorResponse>(putRoute, content);\n\n    result.Contributor.Name.ShouldBe(newName);\n    result.Contributor.Id.ShouldBeGreaterThan(0);\n  }\n\n  [Fact]\n  public async Task ReturnsNotFoundGivenMissingContributorId()\n  {\n    int invalidId = 1000;\n    var putRoute = UpdateContributorRequest.BuildRoute(invalidId);\n    var request = new UpdateContributorRequest() { Id = invalidId, Name = \"some name\" };\n    var content = StringContentHelpers.FromModelAsJson(request);\n\n    _ = await _client.PutAndEnsureNotFoundAsync(putRoute, content);\n  }\n\n  [Fact]\n  public async Task ReturnsBadRequestIfRouteIdDoesNotMatchBodyId()\n  {\n    int routeId = 1;\n    int bodyId = 2;\n    var putRoute = UpdateContributorRequest.BuildRoute(routeId);\n    var request = new UpdateContributorRequest() { Id = bodyId, Name = \"some name\" };\n    var content = StringContentHelpers.FromModelAsJson(request);\n\n    _ = await _client.PutAndEnsureBadRequestAsync(putRoute, content);\n  }\n}\n"
  },
  {
    "path": "sample/tests/NimblePros.SampleToDo.FunctionalTests/CustomWebApplicationFactory.cs",
    "content": "﻿using NimblePros.SampleToDo.Core.ContributorAggregate;\nusing NimblePros.SampleToDo.Infrastructure;\nusing NimblePros.SampleToDo.Infrastructure.Data;\nusing NimblePros.SampleToDo.UseCases.Contributors.Commands.Create;\nusing NimblePros.SampleToDo.Web;\n\nnamespace NimblePros.SampleToDo.FunctionalTests;\n\npublic class CustomWebApplicationFactory<TProgram> : WebApplicationFactory<TProgram> where TProgram : class\n{\n  /// <summary>\n  /// Overriding CreateHost to avoid creating a separate ServiceProvider per this thread:\n  /// https://github.com/dotnet-architecture/eShopOnWeb/issues/465\n  /// </summary>\n  /// <param name=\"builder\"></param>\n  /// <returns></returns>\n  protected override IHost CreateHost(IHostBuilder builder)\n  {\n    builder.UseEnvironment(\"Testing\"); // will not send real emails\n    var host = builder.Build();\n    host.Start();\n\n    // Get service provider.\n    var serviceProvider = host.Services;\n\n    // Create a scope to obtain a reference to the database\n    // context (AppDbContext).\n    using (var scope = serviceProvider.CreateScope())\n    {\n      var scopedServices = scope.ServiceProvider;\n      var db = scopedServices.GetRequiredService<AppDbContext>();\n\n      var logger = scopedServices\n          .GetRequiredService<ILogger<CustomWebApplicationFactory<TProgram>>>();\n\n      // Ensure the database is created.\n      db.Database.EnsureCreated();\n\n      try\n      {\n        // Can also skip creating the items\n        //if (!db.ToDoItems.Any())\n        //{\n        // Seed the database with test data.\n        SeedData.PopulateTestDataAsync(db).GetAwaiter().GetResult();\n        //}\n      }\n      catch (Exception ex)\n      {\n        logger.LogError(ex, \"An error occurred seeding the \" +\n                            \"database with test messages. Error: {exceptionMessage}\", ex.Message);\n      }\n    }\n\n    return host;\n  }\n\n  protected override void ConfigureWebHost(IWebHostBuilder builder)\n  {\n    builder\n        .ConfigureServices(services =>\n        {\n          // Remove the app's ApplicationDbContext registration.\n          var descriptors = services.Where(\n            d => d.ServiceType == typeof(AppDbContext) ||\n                 d.ServiceType == typeof(DbContextOptions<AppDbContext>))\n                .ToList();\n\n          foreach (var descriptor in descriptors)\n          {\n            services.Remove(descriptor);\n          }\n\n          // This should be set for each individual test run\n          string inMemoryCollectionName = Guid.NewGuid().ToString();\n\n          // Add ApplicationDbContext using an in-memory database for testing.\n          services.AddDbContext<AppDbContext>(options =>\n          {\n            options.UseInMemoryDatabase(inMemoryCollectionName).LogTo(s => Console.WriteLine(s));\n          });\n\n          // Add Mediator\n          services.AddMediator(options =>\n          {\n            options.ServiceLifetime = ServiceLifetime.Scoped;\n            options.Assemblies =\n            [\n              typeof(Contributor),                    // Core\n              typeof(CreateContributorCommand),       // UseCases\n              typeof(InfrastructureServiceExtensions) // Infrastructure\n            ];\n          });\n        });\n  }\n}\n"
  },
  {
    "path": "sample/tests/NimblePros.SampleToDo.FunctionalTests/Fixtures/SmtpServerFixture.cs",
    "content": "﻿namespace NimblePros.SampleToDo.FunctionalTests.ClassFixtures;\n\n/// <summary>\n/// This class ensures that an SMTP server is running and shared between all tests in a specified class.\n/// </summary>\npublic class SmtpServerFixture : IAsyncLifetime\n{\n  private const string SmtpServerImageName = \"jijiechen/papercut:latest\";\n  private const int SmtpServerListenPort = 25;\n\n  private IContainer? _container;\n\n  public async Task InitializeAsync()\n  {\n    _container = new ContainerBuilder()\n        .WithName(Guid.NewGuid().ToString(\"D\"))\n        .WithImage(SmtpServerImageName)\n        .WithPortBinding(SmtpServerListenPort, SmtpServerListenPort)\n        .WithWaitStrategy(\n          Wait\n          .ForUnixContainer()\n          .UntilMessageIsLogged(\"Server Ready\", o => o.WithTimeout(TimeSpan.FromSeconds(30))))\n        .Build();\n\n    await _container.StartAsync().ConfigureAwait(false);\n  }\n\n  public async Task DisposeAsync()\n  {\n    if (_container != null)\n    {\n      await _container.StopAsync().ConfigureAwait(false);\n      await _container.DisposeAsync().ConfigureAwait(false);\n      _container = null;\n    }\n  }\n\n  /// <summary>\n  /// Ensures that the container is running and healthy.\n  /// </summary>\n  /// <exception cref=\"InvalidOperationException\">\n  /// Thrown when the SMTP server container was not created or is not running.\n  /// This could be due to Docker not running or issues with the container image.\n  /// In such cases, verify that Docker is running correctly.\n  /// </exception>\n  public void EnsureContainerIsRunning()\n  {\n    if (_container == null)\n    {\n      throw new InvalidOperationException(\"SMTP server container was not created. Ensure Docker is running and the container image is correct.\");\n    }\n\n    if (_container.State != TestcontainersStates.Running)\n    {\n      throw new InvalidOperationException(\"The SMTP server container is not running. Please verify that the SMTP server image is correctly configured and that Docker is functioning properly.\");\n    }\n  }\n}\n"
  },
  {
    "path": "sample/tests/NimblePros.SampleToDo.FunctionalTests/GlobalUsings.cs",
    "content": "﻿global using System.Text;\nglobal using Ardalis.HttpClientTestExtensions;\nglobal using DotNet.Testcontainers.Builders;\nglobal using DotNet.Testcontainers.Containers;\nglobal using Microsoft.AspNetCore.Hosting;\nglobal using Microsoft.AspNetCore.Mvc.Testing;\nglobal using Microsoft.EntityFrameworkCore;\nglobal using Microsoft.Extensions.DependencyInjection;\nglobal using Microsoft.Extensions.Hosting;\nglobal using Microsoft.Extensions.Logging;\nglobal using Newtonsoft.Json;\nglobal using Xunit;\n"
  },
  {
    "path": "sample/tests/NimblePros.SampleToDo.FunctionalTests/NimblePros.SampleToDo.FunctionalTests.csproj",
    "content": "﻿<Project Sdk=\"Microsoft.NET.Sdk\">\n  <ItemGroup>\n    <PackageReference Include=\"Microsoft.NET.Test.Sdk\" />\n    <PackageReference Include=\"NimblePros.SharedKernel\" />\n    <PackageReference Include=\"Shouldly\" />\n    <PackageReference Include=\"Testcontainers\" />\n    <PackageReference Include=\"xunit\" />\n    <PackageReference Include=\"xunit.runner.visualstudio\">\n      <PrivateAssets>all</PrivateAssets>\n      <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>\n    </PackageReference>\n    <PackageReference Include=\"coverlet.collector\">\n      <PrivateAssets>all</PrivateAssets>\n      <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>\n    </PackageReference>\n    <PackageReference Include=\"Microsoft.AspNetCore.Mvc.Testing\" />\n    <PackageReference Include=\"Microsoft.EntityFrameworkCore.InMemory\" />\n    <PackageReference Include=\"Newtonsoft.Json\" />\n    <PackageReference Include=\"Ardalis.HttpClientTestExtensions\" />\n  </ItemGroup>\n\n  <ItemGroup>\n    <ProjectReference Include=\"..\\..\\src\\NimblePros.SampleToDo.Web\\NimblePros.SampleToDo.Web.csproj\" />\n    <ProjectReference Include=\"..\\NimblePros.SampleToDo.UnitTests\\NimblePros.SampleToDo.UnitTests.csproj\" />\n  </ItemGroup>\n\n</Project>\n"
  },
  {
    "path": "sample/tests/NimblePros.SampleToDo.FunctionalTests/Projects/CreateToDoItemRequestBuilder.cs",
    "content": "﻿using NimblePros.SampleToDo.Web;\nusing NimblePros.SampleToDo.Web.Projects;\n\nnamespace NimblePros.SampleToDo.FunctionalTests.Projects;\n\n/// <summary>\n/// Fluent builder for CreateToDoItemRequest to make tests more readable and maintainable\n/// </summary>\npublic class CreateToDoItemRequestBuilder\n{\n  private readonly CreateToDoItemRequest _request = new();\n\n  public CreateToDoItemRequestBuilder WithProjectId(int projectId)\n  {\n    _request.ProjectId = projectId;\n    return this;\n  }\n\n  public CreateToDoItemRequestBuilder WithTitle(string title)\n  {\n    _request.Title = title;\n    return this;\n  }\n\n  public CreateToDoItemRequestBuilder WithDescription(string description)\n  {\n    _request.Description = description;\n    return this;\n  }\n\n  public CreateToDoItemRequestBuilder WithContributorId(int? contributorId)\n  {\n    _request.ContributorId = contributorId;\n    return this;\n  }\n\n  public CreateToDoItemRequestBuilder WithValidDefaults()\n  {\n    var uniqueId = Guid.NewGuid().ToString()[..8];\n    var timestamp = DateTimeOffset.UtcNow.Ticks.ToString()[^8..]; // Last 8 digits of ticks\n    return WithProjectId(SeedData.TestProject1.Id.Value)\n           .WithTitle($\"Test Todo {uniqueId}-{timestamp}\")\n           .WithDescription($\"Test Description {uniqueId}-{timestamp}\");\n  }\n\n  public CreateToDoItemRequest Build() => _request;\n\n  public static CreateToDoItemRequestBuilder Create() => new();\n}\n"
  },
  {
    "path": "sample/tests/NimblePros.SampleToDo.FunctionalTests/Projects/ProjectAddToDoItem.cs",
    "content": "﻿using NimblePros.SampleToDo.Web;\nusing NimblePros.SampleToDo.Web.Endpoints.Projects;\nusing NimblePros.SampleToDo.Web.Projects;\nusing Shouldly;\n\nnamespace NimblePros.SampleToDo.FunctionalTests.Projects;\n\n[Collection(\"Sequential\")]\npublic class ProjectAddToDoItem : TestBase\n{\n  public ProjectAddToDoItem(CustomWebApplicationFactory<Program> factory) : base(factory)\n  {\n  }\n\n  //[Fact] - Broken due to CachingBehavior without cache invalidation logic\n  private async Task AddsItemAndReturnsRouteToProject()\n  {\n    // Arrange\n    var uniqueId = Guid.NewGuid().ToString();\n    var toDoTitle = $\"AddsItem-{uniqueId}\";\n    var request = CreateToDoItemRequestBuilder.Create()\n      .WithValidDefaults()\n      .WithTitle(toDoTitle)\n      .WithDescription($\"Description for {toDoTitle}\")\n      .Build();\n    \n    var content = StringContentHelpers.FromModelAsJson(request);\n\n    // Act\n    var result = await _client.PostAsync(\n      CreateToDoItemRequest.BuildRoute(request.ProjectId), content);\n\n    // Assert\n    result.EnsureSuccessStatusCode();\n    \n    var expectedRoute = GetProjectByIdRequest.BuildRoute(request.ProjectId);\n    result.Headers!.Location!.ToString().ShouldBe(expectedRoute);\n\n    // Verify the item was actually added\n    var updatedProject = await _client.GetAndDeserializeAsync<GetProjectByIdResponse>(expectedRoute);\n    var addedItem = updatedProject.Items.FirstOrDefault(item => item.Title == toDoTitle);\n    addedItem.ShouldNotBeNull();\n    addedItem.Description.ShouldBe(request.Description);\n    addedItem.IsDone.ShouldBe(false);\n    addedItem.ContributorId.ShouldBeNull();\n  }\n\n  [Fact]\n  public async Task ReturnsBadRequestWhenTitleIsMissing()\n  {\n    // Arrange\n    var request = CreateToDoItemRequestBuilder.Create()\n      .WithValidDefaults()\n      .WithTitle(string.Empty) // Missing required title\n      .Build();\n    \n    var content = StringContentHelpers.FromModelAsJson(request);\n\n    // Act & Assert\n    _ = await _client.PostAndEnsureBadRequestAsync(\n      CreateToDoItemRequest.BuildRoute(request.ProjectId), content);\n  }\n\n  [Fact]\n  public async Task ReturnsBadRequestWhenDescriptionIsMissing()\n  {\n    // Arrange\n    var request = CreateToDoItemRequestBuilder.Create()\n      .WithValidDefaults()\n      .WithDescription(string.Empty) // Missing required description\n      .Build();\n    \n    var content = StringContentHelpers.FromModelAsJson(request);\n\n    // Act & Assert\n    _ = await _client.PostAndEnsureBadRequestAsync(\n      CreateToDoItemRequest.BuildRoute(request.ProjectId), content);\n  }\n\n  [Fact]\n  public async Task ReturnsBadRequestWhenProjectIdIsZero()\n  {\n    // Arrange\n    var request = CreateToDoItemRequestBuilder.Create()\n      .WithValidDefaults()\n      .WithProjectId(0) // Invalid project ID\n      .Build();\n    \n    var content = StringContentHelpers.FromModelAsJson(request);\n\n    // Act & Assert\n    _ = await _client.PostAndEnsureBadRequestAsync(\n      CreateToDoItemRequest.BuildRoute(request.ProjectId), content);\n  }\n\n  [Fact]\n  public async Task ReturnsNotFoundWhenProjectDoesNotExist()\n  {\n    // Arrange\n    int nonExistentProjectId = 9999;\n    var request = CreateToDoItemRequestBuilder.Create()\n      .WithValidDefaults()\n      .WithProjectId(nonExistentProjectId)\n      .Build();\n    \n    var content = StringContentHelpers.FromModelAsJson(request);\n\n    // Act & Assert\n    _ = await _client.PostAndEnsureNotFoundAsync(\n      CreateToDoItemRequest.BuildRoute(nonExistentProjectId), content);\n  }\n\n  [Fact]\n  public async Task AddsItemWithValidContributor()\n  {\n    // Arrange\n    var uniqueId = Guid.NewGuid().ToString();\n    var toDoTitle = $\"WithContributor-{uniqueId}\";\n    var request = CreateToDoItemRequestBuilder.Create()\n      .WithValidDefaults()\n      .WithTitle(toDoTitle)\n      .WithContributorId(SeedData.Contributor1.Id.Value)\n      .Build();\n    \n    var content = StringContentHelpers.FromModelAsJson(request);\n\n    // Act\n    var result = await _client.PostAsync(\n      CreateToDoItemRequest.BuildRoute(request.ProjectId), content);\n\n    // Assert\n    result.EnsureSuccessStatusCode();\n    \n    var expectedRoute = GetProjectByIdRequest.BuildRoute(request.ProjectId);\n    var updatedProject = await _client.GetAndDeserializeAsync<GetProjectByIdResponse>(expectedRoute);\n    var addedItem = updatedProject.Items.FirstOrDefault(item => item.Title == toDoTitle);\n    \n    addedItem.ShouldNotBeNull();\n    addedItem.ContributorId.ShouldBe(SeedData.Contributor1.Id.Value);\n  }\n\n  //[Fact] - Broken due to CachingBehavior without cache invalidation logic\n  private async Task AddsItemWithNullContributor()\n  {\n    // Arrange\n    var uniqueId = Guid.NewGuid().ToString();\n    var toDoTitle = $\"NullContributor-{uniqueId}\";\n    var request = CreateToDoItemRequestBuilder.Create()\n      .WithValidDefaults()\n      .WithTitle(toDoTitle)\n      .WithContributorId(null)\n      .Build();\n    \n    var content = StringContentHelpers.FromModelAsJson(request);\n\n    // Act\n    var result = await _client.PostAsync(\n      CreateToDoItemRequest.BuildRoute(request.ProjectId), content);\n\n    // Assert\n    result.EnsureSuccessStatusCode();\n    \n    var expectedRoute = GetProjectByIdRequest.BuildRoute(request.ProjectId);\n    var updatedProject = await _client.GetAndDeserializeAsync<GetProjectByIdResponse>(expectedRoute);\n    var addedItem = updatedProject.Items.FirstOrDefault(item => item.Title == toDoTitle);\n    \n    addedItem.ShouldNotBeNull();\n    addedItem.ContributorId.ShouldBeNull();\n  }\n\n  //[Fact] - Broken due to CachingBehavior without cache invalidation logic\n  private async Task HandlesSpecialCharactersInTitleAndDescription()\n  {\n    // Arrange\n    var uniqueId = Guid.NewGuid().ToString()[..8];\n    var toDoTitle = $\"Special-{uniqueId}-àáâãäåæçèéêë@#$%^&*()\";\n    var description = $\"Desc-{uniqueId}-ñöø¿¡™£¢∞§¶•ªº\";\n    var request = CreateToDoItemRequestBuilder.Create()\n      .WithValidDefaults()\n      .WithTitle(toDoTitle)\n      .WithDescription(description)\n      .Build();\n    \n    var content = StringContentHelpers.FromModelAsJson(request);\n\n    // Act\n    var result = await _client.PostAsync(\n      CreateToDoItemRequest.BuildRoute(request.ProjectId), content);\n\n    // Assert\n    result.EnsureSuccessStatusCode();\n    \n    var expectedRoute = GetProjectByIdRequest.BuildRoute(request.ProjectId);\n    var updatedProject = await _client.GetAndDeserializeAsync<GetProjectByIdResponse>(expectedRoute);\n    var addedItem = updatedProject.Items.FirstOrDefault(item => item.Title == toDoTitle);\n    \n    addedItem.ShouldNotBeNull();\n    addedItem.Title.ShouldBe(toDoTitle);\n    addedItem.Description.ShouldBe(description);\n  }\n\n  //[Fact] - Broken due to CachingBehavior without cache invalidation logic\n  private async Task HandlesLongTitleAndDescription()\n  {\n    // Arrange - use lengths within the constraints (100 for title, 200 for description)\n    var uniqueId = Guid.NewGuid().ToString()[..8];\n    var longTitle = $\"Long-{uniqueId}-\" + new string('A', 80); // Stay within the 100 character limit\n    var longDescription = $\"LongDesc-{uniqueId}-\" + new string('B', 170); // Stay within the 200 character limit\n    var request = CreateToDoItemRequestBuilder.Create()\n      .WithValidDefaults()\n      .WithTitle(longTitle)\n      .WithDescription(longDescription)\n      .Build();\n    \n    var content = StringContentHelpers.FromModelAsJson(request);\n\n    // Act\n    var result = await _client.PostAsync(\n      CreateToDoItemRequest.BuildRoute(request.ProjectId), content);\n\n    // Assert\n    result.EnsureSuccessStatusCode();\n    \n    var expectedRoute = GetProjectByIdRequest.BuildRoute(request.ProjectId);\n    var updatedProject = await _client.GetAndDeserializeAsync<GetProjectByIdResponse>(expectedRoute);\n    var addedItem = updatedProject.Items.FirstOrDefault(item => item.Title == longTitle);\n    \n    addedItem.ShouldNotBeNull();\n    addedItem.Title.ShouldBe(longTitle);\n    addedItem.Description.ShouldBe(longDescription);\n  }\n\n  [Fact]\n  public async Task ReturnsBadRequestWhenTitleExceedsMaxLength()\n  {\n    // Arrange - exceed the 100 character limit\n    var tooLongTitle = new string('A', 101);\n    var request = CreateToDoItemRequestBuilder.Create()\n      .WithValidDefaults()\n      .WithTitle(tooLongTitle)\n      .Build();\n    \n    var content = StringContentHelpers.FromModelAsJson(request);\n\n    // Act & Assert\n    _ = await _client.PostAndEnsureBadRequestAsync(\n      CreateToDoItemRequest.BuildRoute(request.ProjectId), content);\n  }\n\n  [Fact]\n  public async Task ReturnsBadRequestWhenDescriptionExceedsMaxLength()\n  {\n    // Arrange - exceed the 200 character limit\n    var tooLongDescription = new string('B', 201);\n    var request = CreateToDoItemRequestBuilder.Create()\n      .WithValidDefaults()\n      .WithDescription(tooLongDescription)\n      .Build();\n    \n    var content = StringContentHelpers.FromModelAsJson(request);\n\n    // Act & Assert\n    _ = await _client.PostAndEnsureBadRequestAsync(\n      CreateToDoItemRequest.BuildRoute(request.ProjectId), content);\n  }\n\n  [Fact]\n  public async Task HandlesWhitespaceOnlyTitleAndDescription()\n  {\n    // Arrange\n    var request = CreateToDoItemRequestBuilder.Create()\n      .WithValidDefaults()\n      .WithTitle(\"   \") // Whitespace only\n      .WithDescription(\"   \") // Whitespace only\n      .Build();\n    \n    var content = StringContentHelpers.FromModelAsJson(request);\n\n    // Act & Assert\n    // This should fail validation since whitespace-only strings are typically not valid\n    _ = await _client.PostAndEnsureBadRequestAsync(\n      CreateToDoItemRequest.BuildRoute(request.ProjectId), content);\n  }\n\n  [Fact]\n  public async Task ReturnsCorrectStatusCodeAndContentType()\n  {\n    // Arrange\n    var request = CreateToDoItemRequestBuilder.Create()\n      .WithValidDefaults()\n      .Build();\n    \n    var content = StringContentHelpers.FromModelAsJson(request);\n\n    // Act\n    var result = await _client.PostAsync(\n      CreateToDoItemRequest.BuildRoute(request.ProjectId), content);\n\n    // Assert\n    result.StatusCode.ShouldBe(System.Net.HttpStatusCode.Created);\n    result.Headers.Location.ShouldNotBeNull();\n    \n    // Verify the location header points to the correct project\n    var expectedRoute = GetProjectByIdRequest.BuildRoute(request.ProjectId);\n    result.Headers.Location.ToString().ShouldBe(expectedRoute);\n  }\n\n  [Fact]\n  public async Task DoesNotReturnResponseBodyOnSuccess()\n  {\n    // Arrange\n    var request = CreateToDoItemRequestBuilder.Create()\n      .WithValidDefaults()\n      .Build();\n    \n    var content = StringContentHelpers.FromModelAsJson(request);\n\n    // Act\n    var result = await _client.PostAsync(\n      CreateToDoItemRequest.BuildRoute(request.ProjectId), content);\n\n    // Assert\n    result.EnsureSuccessStatusCode();\n    \n    // According to REST conventions, POST should return 201 Created with Location header\n    // but no response body for this endpoint\n    var responseContent = await result.Content.ReadAsStringAsync();\n    responseContent.ShouldBeNullOrEmpty();\n  }\n\n  //[Fact] - Broken due to CachingBehavior without cache invalidation logic\n  private async Task IncreasesTotalItemCountInProject()\n  {\n    // Arrange\n    var uniqueId = Guid.NewGuid().ToString();\n    var projectId = SeedData.TestProject1.Id.Value;\n    \n    // Get initial count\n    var initialProject = await _client.GetAndDeserializeAsync<GetProjectByIdResponse>(\n      GetProjectByIdRequest.BuildRoute(projectId));\n    var initialCount = initialProject.Items.Count;\n    \n    var toDoTitle = $\"CountTest-{uniqueId}\";\n    var request = CreateToDoItemRequestBuilder.Create()\n      .WithValidDefaults()\n      .WithProjectId(projectId)\n      .WithTitle(toDoTitle)\n      .Build();\n    \n    var content = StringContentHelpers.FromModelAsJson(request);\n\n    // Act\n    var result = await _client.PostAsync(\n      CreateToDoItemRequest.BuildRoute(projectId), content);\n\n    // Assert\n    result.EnsureSuccessStatusCode();\n    \n    var updatedProject = await _client.GetAndDeserializeAsync<GetProjectByIdResponse>(\n      GetProjectByIdRequest.BuildRoute(projectId));\n    \n    // Verify the count increased by exactly 1\n    updatedProject.Items.Count.ShouldBe(initialCount + 1);\n    \n    // Verify our specific item was added\n    var addedItem = updatedProject.Items.FirstOrDefault(item => item.Title == toDoTitle);\n    addedItem.ShouldNotBeNull();\n  }\n}\n"
  },
  {
    "path": "sample/tests/NimblePros.SampleToDo.FunctionalTests/Projects/ProjectCreate.cs",
    "content": "﻿using NimblePros.SampleToDo.Web.Projects;\nusing Shouldly;\n\nnamespace NimblePros.SampleToDo.FunctionalTests.Projects;\n\n[Collection(\"Sequential\")]\npublic class ProjectCreate : IClassFixture<CustomWebApplicationFactory<Program>>\n{\n  private readonly HttpClient _client;\n\n  public ProjectCreate(CustomWebApplicationFactory<Program> factory)\n  {\n    _client = factory.CreateClient();\n  }\n\n  [Fact]\n  public async Task ReturnsOneProject()\n  {\n    var testName = Guid.NewGuid().ToString();\n    var request = new CreateProjectRequest() { Name = testName };\n    var content = StringContentHelpers.FromModelAsJson(request);\n\n    var result = await _client.PostAndDeserializeAsync<CreateProjectResponse>(\n        CreateProjectRequest.Route, content);\n\n    result.Name.ShouldBe(testName);\n    result.Id.ShouldBeGreaterThan(0);\n  }\n}\n"
  },
  {
    "path": "sample/tests/NimblePros.SampleToDo.FunctionalTests/Projects/ProjectGetById.cs",
    "content": "﻿using NimblePros.SampleToDo.Web;\nusing NimblePros.SampleToDo.Web.Endpoints.Projects;\nusing NimblePros.SampleToDo.Web.Projects;\nusing Shouldly;\n\nnamespace NimblePros.SampleToDo.FunctionalTests.Projects;\n\n[Collection(\"Sequential\")]\npublic class ProjectGetById : IClassFixture<CustomWebApplicationFactory<Program>>\n{\n  private readonly HttpClient _client;\n\n  public ProjectGetById(CustomWebApplicationFactory<Program> factory)\n  {\n    _client = factory.CreateClient();\n  }\n\n  [Fact]\n  public async Task ReturnsSeedProjectGivenId1()\n  {\n    var result = await _client.GetAndDeserializeAsync<GetProjectByIdResponse>(GetProjectByIdRequest.BuildRoute(1));\n\n    result.Id.ShouldBe(1);\n    result.Name.ShouldBe(SeedData.TestProject1.Name.Value);\n    result.Items.Count.ShouldBe(3);\n  }\n\n  [Fact]\n  public async Task ReturnsNotFoundGivenInvalidId1000()\n  {\n    var route = GetProjectByIdRequest.BuildRoute(1000);\n    _ = await _client.GetAndEnsureNotFoundAsync(route);\n  }\n}\n"
  },
  {
    "path": "sample/tests/NimblePros.SampleToDo.FunctionalTests/Projects/ProjectItemMarkComplete.cs",
    "content": "﻿using NimblePros.SampleToDo.FunctionalTests.ClassFixtures;\nusing NimblePros.SampleToDo.Web.Endpoints.Projects;\nusing NimblePros.SampleToDo.Web.ProjectEndpoints;\nusing NimblePros.SampleToDo.Web.Projects;\nusing Shouldly;\n\nnamespace NimblePros.SampleToDo.FunctionalTests.Projects;\n\n[Collection(\"Sequential\")]\npublic class ProjectItemMarkComplete : \n  IClassFixture<CustomWebApplicationFactory<Program>>,\n  IClassFixture<SmtpServerFixture>\n{\n  private readonly HttpClient _client;\n\n  public ProjectItemMarkComplete(CustomWebApplicationFactory<Program> factory, SmtpServerFixture smtpServer)\n  {\n    _client = factory.CreateClient();\n    smtpServer.EnsureContainerIsRunning();\n  }\n\n  /// <summary>\n  /// Currently this fails if you don't have a local mailserver running, like papercut\n  /// </summary>\n  /// <returns></returns>\n  [Fact]\n  public async Task MarksIncompleteItemComplete()\n  {\n    // TODO: Arrange to use a fake mail server for this test\n    var projectId = 1;\n    var itemId = 1;\n\n    var jsonContent = new StringContent(JsonConvert.SerializeObject(null), Encoding.UTF8, \"application/json\");\n\n    var route = MarkItemCompleteRequest.BuildRoute(projectId, itemId);\n    var response = await _client.PostAsync(route, jsonContent);\n    response.EnsureSuccessStatusCode();\n\n    var stringResponse = await response.Content.ReadAsStringAsync();\n    stringResponse.ShouldBeEmpty();\n\n    // confirm item is complete\n    var project = await _client.GetAndDeserializeAsync<GetProjectByIdResponse>(GetProjectByIdRequest.BuildRoute(projectId));\n    project.Items.First(i => i.Id == itemId).IsDone.ShouldBeTrue();\n  }\n}\n"
  },
  {
    "path": "sample/tests/NimblePros.SampleToDo.FunctionalTests/Projects/ProjectList.cs",
    "content": "﻿using NimblePros.SampleToDo.Web;\nusing NimblePros.SampleToDo.Web.Projects;\n\nnamespace NimblePros.SampleToDo.FunctionalTests.Projects;\n\n[Collection(\"Sequential\")]\npublic class ProjectList : IClassFixture<CustomWebApplicationFactory<Program>>\n{\n  private readonly HttpClient _client;\n\n  public ProjectList(CustomWebApplicationFactory<Program> factory)\n  {\n    _client = factory.CreateClient();\n  }\n\n  [Fact]\n  public async Task ReturnsOneProject()\n  {\n    var result = await _client.GetAndDeserializeAsync<ProjectListResponse>(\"/Projects\");\n\n    Assert.Single(result.Items);\n    Assert.Contains(result.Items, i => i.Name == SeedData.TestProject1.Name);\n  }\n}\n"
  },
  {
    "path": "sample/tests/NimblePros.SampleToDo.FunctionalTests/TestBase.cs",
    "content": "using NimblePros.SampleToDo.Infrastructure.Data;\nusing NimblePros.SampleToDo.Web;\nusing Microsoft.Extensions.DependencyInjection;\n\nnamespace NimblePros.SampleToDo.FunctionalTests;\n\n/// <summary>\n/// Base class for functional tests that provides database isolation between tests\n/// </summary>\npublic abstract class TestBase : IClassFixture<CustomWebApplicationFactory<Program>>, IAsyncLifetime\n{\n  protected readonly HttpClient _client;\n  protected readonly CustomWebApplicationFactory<Program> _factory;\n\n  protected TestBase(CustomWebApplicationFactory<Program> factory)\n  {\n    _factory = factory;\n    _client = factory.CreateClient();\n  }\n\n  public virtual Task InitializeAsync()\n  {\n    // Override in derived classes if needed for test-specific setup\n    return Task.CompletedTask;\n  }\n\n  public virtual async Task DisposeAsync()\n  {\n    // Reset database to clean seed state after each test\n    await ResetDatabaseAsync();\n  }\n\n  protected async Task ResetDatabaseAsync()\n  {\n    using var scope = _factory.Services.CreateScope();\n    var dbContext = scope.ServiceProvider.GetRequiredService<AppDbContext>();\n    \n    // Clear all data in the correct order to handle foreign key relationships\n    var toDoItems = dbContext.ToDoItems.ToList();\n    var projects = dbContext.Projects.ToList();\n    var contributors = dbContext.Contributors.ToList();\n    \n    dbContext.ToDoItems.RemoveRange(toDoItems);\n    dbContext.Projects.RemoveRange(projects);\n    dbContext.Contributors.RemoveRange(contributors);\n    \n    await dbContext.SaveChangesAsync();\n    \n    // Re-seed with fresh data\n    await SeedData.PopulateTestDataAsync(dbContext);\n  }\n}"
  },
  {
    "path": "sample/tests/NimblePros.SampleToDo.FunctionalTests/xunit.runner.json",
    "content": "﻿{\n  \"shadowCopy\": false,\n  \"parallelizeAssembly\": false,\n  \"parallelizeTestCollections\": false\n}"
  },
  {
    "path": "sample/tests/NimblePros.SampleToDo.IntegrationTests/Data/BaseEfRepoTestFixture.cs",
    "content": "﻿using NimblePros.SampleToDo.Core.ProjectAggregate;\nusing NimblePros.SampleToDo.Infrastructure.Data;\n\nnamespace NimblePros.SampleToDo.IntegrationTests.Data;\n\npublic abstract class BaseEfRepoTestFixture\n{\n  protected AppDbContext _dbContext;\n\n  protected BaseEfRepoTestFixture()\n  {\n    var options = CreateNewContextOptions();\n    _dbContext = new AppDbContext(options);\n  }\n\n  protected static DbContextOptions<AppDbContext> CreateNewContextOptions()\n  {\n    var fakeEventDispatcher = Substitute.For<IDomainEventDispatcher>();\n    // Create a fresh service provider, and therefore a fresh\n    // InMemory database instance.\n    var serviceProvider = new ServiceCollection()\n        .AddEntityFrameworkInMemoryDatabase()\n        .AddScoped<IDomainEventDispatcher>(_ => fakeEventDispatcher)\n        .AddScoped<EventDispatchInterceptor>()\n        .BuildServiceProvider();\n\n    // Create a new options instance telling the context to use an\n    // InMemory database and the new service provider.\n    var interceptor = serviceProvider.GetRequiredService<EventDispatchInterceptor>();\n\n    var builder = new DbContextOptionsBuilder<AppDbContext>();\n    builder.UseInMemoryDatabase(\"cleanarchitecture\")\n           .UseInternalServiceProvider(serviceProvider)\n           .AddInterceptors(interceptor);\n\n    return builder.Options;\n  }\n\n  protected EfRepository<Project> GetRepository()\n  {\n    return new EfRepository<Project>(_dbContext);\n  }\n}\n"
  },
  {
    "path": "sample/tests/NimblePros.SampleToDo.IntegrationTests/Data/EfRepositoryAdd.cs",
    "content": "﻿using NimblePros.SampleToDo.Core.ProjectAggregate;\n\nnamespace NimblePros.SampleToDo.IntegrationTests.Data;\n\npublic class EfRepositoryAdd : BaseEfRepoTestFixture\n{\n  [Fact]\n  public async Task AddsProjectAndSetsId()\n  {\n    var testProjectName = ProjectName.From(\"testProject\");\n    var repository = GetRepository();\n    var project = new Project(testProjectName);\n\n    var item = new ToDoItem();\n    item.UpdateTitle(ToDoItemTitle.From(\"test item title\"));\n    project.AddItem(item);\n\n    await repository.AddAsync(project);\n\n    var newProject = (await repository.ListAsync())\n                    .FirstOrDefault();\n\n    Assert.Equal(testProjectName, newProject?.Name);\n    Assert.True(newProject?.Id.Value > 0);\n  }\n}\n"
  },
  {
    "path": "sample/tests/NimblePros.SampleToDo.IntegrationTests/Data/EfRepositoryDelete.cs",
    "content": "﻿using NimblePros.SampleToDo.Core.ProjectAggregate;\n\nnamespace NimblePros.SampleToDo.IntegrationTests.Data;\n\npublic class EfRepositoryDelete : BaseEfRepoTestFixture\n{\n  [Fact]\n  public async Task DeletesItemAfterAddingIt()\n  {\n    // add a project\n    var repository = GetRepository();\n    var initialName = Guid.NewGuid().ToString();\n    var project = new Project(ProjectName.From(initialName));\n    await repository.AddAsync(project);\n\n    // delete the item\n    await repository.DeleteAsync(project);\n\n    // verify it's no longer there\n    Assert.DoesNotContain(await repository.ListAsync(),\n        project => project.Name == initialName);\n  }\n}\n"
  },
  {
    "path": "sample/tests/NimblePros.SampleToDo.IntegrationTests/Data/EfRepositoryUpdate.cs",
    "content": "﻿using NimblePros.SampleToDo.Core.ProjectAggregate;\n\nnamespace NimblePros.SampleToDo.IntegrationTests.Data;\n\npublic class EfRepositoryUpdate : BaseEfRepoTestFixture\n{\n  [Fact]\n  public async Task UpdatesItemAfterAddingIt()\n  {\n    // add a project\n    var repository = GetRepository();\n    var initialName = Guid.NewGuid().ToString();\n    var project = new Project(ProjectName.From(initialName));\n\n    await repository.AddAsync(project);\n\n    // detach the item so we get a different instance\n    _dbContext.Entry(project).State = EntityState.Detached;\n\n    // fetch the item and update its title\n    var newProject = (await repository.ListAsync())\n        .FirstOrDefault(project => project.Name == initialName);\n    if (newProject == null)\n    {\n      Assert.NotNull(newProject);\n      return;\n    }\n    Assert.NotSame(project, newProject);\n    var newName = Guid.NewGuid().ToString();\n    newProject.UpdateName(ProjectName.From(newName));\n\n    // Update the item\n    await repository.UpdateAsync(newProject);\n\n    // Fetch the updated item\n    var updatedItem = (await repository.ListAsync())\n        .FirstOrDefault(project => project.Name == newName);\n\n    Assert.NotNull(updatedItem);\n    Assert.NotEqual(project.Name, updatedItem?.Name);\n    Assert.Equal(newProject.Id, updatedItem?.Id);\n  }\n}\n"
  },
  {
    "path": "sample/tests/NimblePros.SampleToDo.IntegrationTests/GlobalUsings.cs",
    "content": "﻿global using Microsoft.EntityFrameworkCore;\nglobal using Microsoft.Extensions.DependencyInjection;\nglobal using NimblePros.SharedKernel;\nglobal using NSubstitute;\nglobal using Xunit;\n"
  },
  {
    "path": "sample/tests/NimblePros.SampleToDo.IntegrationTests/NimblePros.SampleToDo.IntegrationTests.csproj",
    "content": "﻿<Project Sdk=\"Microsoft.NET.Sdk\">\n  <ItemGroup>\n    <PackageReference Include=\"Microsoft.NET.Test.Sdk\" />\n    <PackageReference Include=\"NimblePros.SharedKernel\" />\n    <PackageReference Include=\"xunit.runner.visualstudio\">\n      <PrivateAssets>all</PrivateAssets>\n      <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>\n    </PackageReference>\n    <PackageReference Include=\"coverlet.collector\">\n      <PrivateAssets>all</PrivateAssets>\n      <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>\n    </PackageReference>\n    <PackageReference Include=\"xunit\" />\n    <PackageReference Include=\"Microsoft.AspNetCore.Mvc.Testing\" />\n    <PackageReference Include=\"Microsoft.EntityFrameworkCore.InMemory\" />\n  </ItemGroup>\n\n  <ItemGroup>\n    <ProjectReference Include=\"..\\..\\src\\NimblePros.SampleToDo.Infrastructure\\NimblePros.SampleToDo.Infrastructure.csproj\" />\n    <ProjectReference Include=\"..\\NimblePros.SampleToDo.UnitTests\\NimblePros.SampleToDo.UnitTests.csproj\" />\n  </ItemGroup>\n\n  <ItemGroup>\n    <None Update=\"xunit.runner.json\">\n\t  <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>\n    </None>\n  </ItemGroup>\n\n</Project>\n"
  },
  {
    "path": "sample/tests/NimblePros.SampleToDo.UnitTests/Core/ContributorAggregate/ContributorConstructor.cs",
    "content": "﻿using NimblePros.SampleToDo.Core.ContributorAggregate;\n\nnamespace NimblePros.SampleToDo.UnitTests.Core.ContributorAggregate;\n\npublic class ContributorConstructor\n{\n  private readonly string _testName = \"test name\";\n  private Contributor? _testContributor;\n\n  private Contributor CreateContributor()\n  {\n    return new Contributor(ContributorName.From(_testName));\n  }\n\n  [Fact]\n  public void InitializesName()\n  {\n    _testContributor = CreateContributor();\n\n    Assert.Equal(_testName, _testContributor.Name.Value);\n  }\n}\n\npublic class ContributorUpdateName\n{\n  private readonly string _testName = \"new name\";\n  private Contributor? _testContributor;\n\n  private Contributor CreateContributor()\n  {\n    return new Contributor(ContributorName.From(_testName));\n  }\n\n  [Fact]\n  public void DoesNothingGivenSameName()\n  {\n    _testContributor = CreateContributor();\n    var initialEvents = _testContributor.DomainEvents.Count;\n\n    var initialHash = _testContributor.GetHashCode();\n\n    _testContributor.UpdateName(ContributorName.From(_testName));\n\n    Assert.Equal(initialHash, _testContributor.GetHashCode());\n    Assert.Equal(initialEvents, _testContributor.DomainEvents.Count);\n  }\n\n  [Fact]\n  public void UpdatesNameAndRegistersEventGivenNewName()\n  {\n    _testContributor = CreateContributor();\n    var initialEvents = _testContributor.DomainEvents.Count;\n    string newName = \"A whole new name\";\n\n    _testContributor.UpdateName(ContributorName.From(newName));\n\n    Assert.Equal(newName, _testContributor.Name.Value);\n    Assert.Single(_testContributor.DomainEvents);\n  }\n}\n"
  },
  {
    "path": "sample/tests/NimblePros.SampleToDo.UnitTests/Core/ContributorAggregate/ContributorIdFrom.cs",
    "content": "﻿using NimblePros.SampleToDo.Core.ContributorAggregate;\n\nnamespace NimblePros.SampleToDo.UnitTests.Core.ContributorAggregate;\n\npublic class ContributorIdFrom\n{\n  [Fact]\n  public void CreatesGivenValidValue()\n  {\n    int validValue = 1;\n    var contributorId = ContributorId.From(validValue);\n    Assert.Equal(validValue, contributorId.Value);\n  }\n\n  [Theory]\n  [InlineData(0)]\n  [InlineData(-1)]\n  public void ThrowsGivenInvalidValue(int invalidValue)\n  {\n    Assert.Throws<Vogen.ValueObjectValidationException>(() => ContributorId.From(invalidValue));\n  }\n}\n"
  },
  {
    "path": "sample/tests/NimblePros.SampleToDo.UnitTests/Core/Handlers/ItemCompletedEmailNotificationHandlerHandle.cs",
    "content": "﻿using NimblePros.SampleToDo.Core.Interfaces;\nusing NimblePros.SampleToDo.Core.ProjectAggregate;\nusing NimblePros.SampleToDo.Core.ProjectAggregate.Events;\nusing NimblePros.SampleToDo.Core.ProjectAggregate.Handlers;\n\nnamespace NimblePros.SampleToDo.UnitTests.Core.Handlers;\n\npublic class ItemCompletedEmailNotificationHandlerHandle\n{\n  private ItemCompletedEmailNotificationHandler _handler;\n  private IEmailSender _emailSender = Substitute.For<IEmailSender>();\n\n  public ItemCompletedEmailNotificationHandlerHandle()\n  {\n    _handler = new ItemCompletedEmailNotificationHandler(_emailSender);\n  }\n\n  [Fact]\n  public async Task ThrowsExceptionGivenNullEventArgument()\n  {\n#nullable disable\n    Exception ex = await Assert.ThrowsAsync<ArgumentNullException>(\n        () => _handler.Handle(null, CancellationToken.None).AsTask());\n#nullable enable\n  }\n\n  [Fact]\n  public async Task SendsEmailGivenEventInstance()\n  {\n    await _handler.Handle(new ToDoItemCompletedEvent(new ToDoItem()), CancellationToken.None);\n\n    await _emailSender.Received().SendEmailAsync(Arg.Any<string>(), Arg.Any<string>(), Arg.Any<string>(), Arg.Any<string>());\n  }\n}\n"
  },
  {
    "path": "sample/tests/NimblePros.SampleToDo.UnitTests/Core/ProjectAggregate/ProjectConstructor.cs",
    "content": "﻿using System.Globalization;\nusing NimblePros.SampleToDo.Core.ProjectAggregate;\n\nnamespace NimblePros.SampleToDo.UnitTests.Core.ProjectAggregate;\n\npublic class ProjectConstructor\n{\n  private string _testName = \"test name\";\n  private Priority _testPriority = Priority.Backlog;\n  private Project? _testProject;\n\n  private Project CreateProject()\n  {\n    return new Project(ProjectName.From(_testName));\n  }\n\n  [Fact]\n  public void InitializesName()\n  {\n    _testProject = CreateProject();\n\n    Assert.Equal(_testName, _testProject.Name.Value);\n  }\n\n  [Fact]\n  public void InitializesTaskListToEmptyList()\n  {\n    _testProject = CreateProject();\n\n    Assert.NotNull(_testProject.Items);\n  }\n\n  [Fact]\n  public void InitializesStatusToInProgress()\n  {\n    _testProject = CreateProject();\n\n    Assert.Equal(ProjectStatus.Complete, _testProject.Status);\n  }\n  [Fact]\n  public void ProjectName_TooLong_ReturnsLocalizedMessage()\n  {\n    // Arrange: Set a French culture for testing\n    Thread.CurrentThread.CurrentUICulture = new CultureInfo(\"en\");\n\n    // Act\n    var message = ProjectErrorMessages.CoreProjectNameTooLong(100);\n\n    // Assert: Should use fallback or loaded JSON (depending on setup)\n    Assert.Equal(\"Name cannot be longer than 100 characters\", message);\n  }\n}\n"
  },
  {
    "path": "sample/tests/NimblePros.SampleToDo.UnitTests/Core/ProjectAggregate/ProjectNameFrom.cs",
    "content": "﻿using NimblePros.SampleToDo.Core.ProjectAggregate;\nusing Shouldly;\nusing Vogen;\n\nnamespace NimblePros.SampleToDo.UnitTests.Core.ProjectAggregate;\n\npublic class ProjectNameFrom\n{\n  [Theory]\n  [InlineData(\"\")]\n  [InlineData(null!)]\n  public void ThrowsGivenNullOrEmpty(string? name)\n  {\n    Should.Throw<ValueObjectValidationException>(() => ProjectName.From(name!));\n  }\n\n  [Fact]\n  public void DoesNotThrowGivenValidData()\n  {\n    string validName = \"valid name\";\n    var name = ProjectName.From(validName);\n    name.Value.ShouldBe(validName);\n  }\n}\n"
  },
  {
    "path": "sample/tests/NimblePros.SampleToDo.UnitTests/Core/ProjectAggregate/Project_AddItem.cs",
    "content": "﻿using NimblePros.SampleToDo.Core.ProjectAggregate;\n\nnamespace NimblePros.SampleToDo.UnitTests.Core.ProjectAggregate;\n\npublic class Project_AddItem\n{\n  private Project _testProject = new Project(ProjectName.From(\"some name\"));\n\n  [Fact]\n  public void AddsItemToItems()\n  {\n    var _testItem = new ToDoItem(title: ToDoItemTitle.From(\"title\"),\n      description: ToDoItemDescription.From(\"description\"));\n\n    _testProject.AddItem(_testItem);\n\n    Assert.Contains(_testItem, _testProject.Items);\n  }\n\n  [Fact]\n  public void ThrowsExceptionGivenNullItem()\n  {\n#nullable disable\n    Action action = () => _testProject.AddItem(null);\n#nullable enable\n\n    var ex = Assert.Throws<ArgumentNullException>(action);\n    Assert.Equal(\"newItem\", ex.ParamName);\n  }\n}\n"
  },
  {
    "path": "sample/tests/NimblePros.SampleToDo.UnitTests/Core/ProjectAggregate/ToDoItemConstructor.cs",
    "content": "﻿using NimblePros.SampleToDo.Core.ProjectAggregate;\nusing Xunit;\n\nnamespace NimblePros.SampleToDo.UnitTests.Core.ProjectAggregate;\n\npublic class ToDoItemConstructor\n{\n  [Fact]\n  public void InitializesPriority()\n  {\n    var item = new ToDoItemBuilder()\n    .WithDefaultValues()\n    .Build();\n\n    Assert.Equal(item.Priority, Priority.Backlog);\n  }\n}\n"
  },
  {
    "path": "sample/tests/NimblePros.SampleToDo.UnitTests/Core/ProjectAggregate/ToDoItemMarkComplete.cs",
    "content": "﻿using NimblePros.SampleToDo.Core.ProjectAggregate.Events;\n\nnamespace NimblePros.SampleToDo.UnitTests.Core.ProjectAggregate;\n\npublic class ToDoItemMarkComplete\n{\n  [Fact]\n  public void SetsIsDoneToTrue()\n  {\n    var item = new ToDoItemBuilder()\n        .WithDefaultValues()\n        .Description(\"\")\n        .Build();\n\n    item.MarkComplete();\n\n    Assert.True(item.IsDone);\n  }\n\n  [Fact]\n  public void RaisesToDoItemCompletedEvent()\n  {\n    var item = new ToDoItemBuilder().Build();\n\n    item.MarkComplete();\n\n    Assert.Single(item.DomainEvents);\n    Assert.IsType<ToDoItemCompletedEvent>(item.DomainEvents.First());\n  }\n}\n"
  },
  {
    "path": "sample/tests/NimblePros.SampleToDo.UnitTests/Core/Services/DeleteContributorSevice_DeleteContributor.cs",
    "content": "﻿using NimblePros.SampleToDo.Core.ContributorAggregate;\nusing NimblePros.SampleToDo.Core.Services;\n\nnamespace NimblePros.SampleToDo.UnitTests.Core.Services;\n\npublic class DeleteContributorService_DeleteContributor\n{\n  private readonly IRepository<Contributor> _repository = Substitute.For<IRepository<Contributor>>();\n  private readonly IMediator _mediator = Substitute.For<IMediator>();\n  private readonly ILogger<DeleteContributorService> _logger = Substitute.For<ILogger<DeleteContributorService>>();\n\n  private readonly DeleteContributorService _service;\n\n  public DeleteContributorService_DeleteContributor()\n  {\n    _service = new DeleteContributorService(_repository, _mediator, _logger);\n  }\n\n  [Fact]\n  public async Task ReturnsNotFoundGivenCantFindContributor()\n  {\n    var result = await _service.DeleteContributor(ContributorId.From(9999));\n\n    Assert.Equal(ResultStatus.NotFound, result.Status);\n  }\n}\n"
  },
  {
    "path": "sample/tests/NimblePros.SampleToDo.UnitTests/Core/Services/ToDoItemSearchServiceTests.cs",
    "content": "﻿using NimblePros.SampleToDo.Core.Interfaces;\nusing NimblePros.SampleToDo.Core.ProjectAggregate;\nusing NimblePros.SampleToDo.Core.Services;\n\nnamespace NimblePros.SampleToDo.UnitTests.Core.Services;\n\npublic class ToDoItemSearchServiceTests\n{\n  private readonly IToDoItemSearchService _service;\n  private readonly IRepository<Project> _repo = Substitute.For<IRepository<Project>>();\n\n  public ToDoItemSearchServiceTests()\n  {\n    _service = new ToDoItemSearchService(_repo);\n\n  }\n\n  [Fact]\n  public async Task ReturnsValidationErrors()\n  {\n    var projects = await _service.GetAllIncompleteItemsAsync(ProjectId.From(0), string.Empty);\n\n    Assert.NotEmpty(projects.ValidationErrors);\n  }\n\n  [Fact]\n  public async Task ReturnsProjectNotFound()\n  {\n    var projects = await _service.GetAllIncompleteItemsAsync(ProjectId.From(100), \"Hello\");\n\n    Assert.Equal(ResultStatus.NotFound, projects.Status);\n  }\n\n  [Fact]\n  public async Task ReturnsAllIncompleteItems()\n  {\n    var title = \"Some Title\";\n    Project project = new Project(ProjectName.From(\"Cool Project\"));\n\n    project.AddItem(new ToDoItem(title: ToDoItemTitle.From(title), description: ToDoItemDescription.From(\"Some Description\")));\n\n    _repo.FirstOrDefaultAsync(Arg.Any<ISpecification<Project>>(), Arg.Any<CancellationToken>())\n      .Returns(project);\n\n    var projects = await _service.GetAllIncompleteItemsAsync(ProjectId.From(1), title);\n\n    Assert.Empty(projects.ValidationErrors);\n    Assert.Equal(projects.Value.First().Title.Value, title);\n    Assert.Equal(project.Items.Count(), projects.Value.Count);\n  }\n}\n"
  },
  {
    "path": "sample/tests/NimblePros.SampleToDo.UnitTests/Core/Services/ToDoItemSearchService_GetAllIncompleteItems.cs",
    "content": "﻿using System.Linq;\nusing System.Threading.Tasks;\nusing Ardalis.Specification;\nusing Clean.Architecture.Core.ProjectAggregate;\nusing Clean.Architecture.Core.Services;\nusing Clean.Architecture.SharedKernel.Interfaces;\nusing Moq;\nusing Xunit;\n\nnamespace Clean.Architecture.UnitTests.Core.Services\n{\n    public class ToDoItemSearchService_GetAllIncompleteItems\n    {\n        private Mock<IRepository<ToDoItem>> _mockRepo = new Mock<IRepository<ToDoItem>>();\n        private ToDoItemSearchService _searchService;\n\n        public ToDoItemSearchService_GetAllIncompleteItems()\n        {\n            _searchService = new ToDoItemSearchService(_mockRepo.Object);\n        }\n\n        [Fact]\n        public async Task ReturnsInvalidGivenNullSearchString()\n        {\n            var result = await _searchService.GetAllIncompleteItemsAsync(null);\n\n            Assert.Equal(Ardalis.Result.ResultStatus.Invalid, result.Status);\n            Assert.Equal(\"searchString is required.\", result.ValidationErrors.First().ErrorMessage);\n        }\n\n        [Fact]\n        public async Task ReturnsErrorGivenDataAccessException()\n        {\n            string expectedErrorMessage = \"Database not there.\";\n            _mockRepo.Setup(r => r.ListAsync(It.IsAny<ISpecification<ToDoItem>>()))\n                .ThrowsAsync(new System.Exception(expectedErrorMessage));\n\n            var result = await _searchService.GetAllIncompleteItemsAsync(\"something\");\n\n            Assert.Equal(Ardalis.Result.ResultStatus.Error, result.Status);\n            Assert.Equal(expectedErrorMessage, result.Errors.First());\n        }\n\n        [Fact]\n        public async Task ReturnsListGivenSearchString()\n        {\n            var result = await _searchService.GetAllIncompleteItemsAsync(\"foo\");\n\n            Assert.Equal(Ardalis.Result.ResultStatus.Ok, result.Status);\n        }\n    }\n}\n"
  },
  {
    "path": "sample/tests/NimblePros.SampleToDo.UnitTests/Core/Services/ToDoItemSearchService_GetNextIncompleteItem.cs",
    "content": "﻿using System.Collections.Generic;\nusing System.Linq;\nusing System.Threading.Tasks;\nusing Ardalis.Specification;\nusing Clean.Architecture.Core.ProjectAggregate;\nusing Clean.Architecture.Core.Services;\nusing Clean.Architecture.SharedKernel.Interfaces;\nusing Moq;\nusing Xunit;\n\nnamespace Clean.Architecture.UnitTests.Core.Services\n{\n    public class ToDoItemSearchService_GetNextIncompleteItem\n    {\n        [Fact]\n        public async Task ReturnsNotFoundGivenNoRemainingItems()\n        {\n            var repo = new Mock<IRepository<ToDoItem>>();\n            var service = new ToDoItemSearchService(repo.Object);\n            repo.Setup(r => r.ListAsync(It.IsAny<ISpecification<ToDoItem>>()))\n                .ReturnsAsync(new List<ToDoItem>());\n\n            var result = await service.GetNextIncompleteItemAsync();\n\n            Assert.Equal(Ardalis.Result.ResultStatus.NotFound, result.Status);\n        }\n\n        [Fact]\n        public async Task ReturnsFirstItemFromList()\n        {\n            var repo = new Mock<IRepository<ToDoItem>>();\n            var service = new ToDoItemSearchService(repo.Object);\n            var testItems = GetTestItems();\n            repo.Setup(r => r.ListAsync(It.IsAny<ISpecification<ToDoItem>>()))\n                .ReturnsAsync(testItems);\n\n            var result = await service.GetNextIncompleteItemAsync();\n\n            Assert.Equal(testItems.First(), result.Value);\n        }\n\n        private List<ToDoItem> GetTestItems()\n        {\n            // Note: could use AutoFixture\n            var builder = new ToDoItemBuilder();\n\n            var items = new List<ToDoItem>();\n\n            var item1 = builder.WithDefaultValues().Build();\n            items.Add(item1);\n\n            var item2 = builder.WithDefaultValues().Id(2).Build();\n            items.Add(item2);\n\n            var item3 = builder.WithDefaultValues().Id(3).Build();\n            items.Add(item3);\n\n            return items;\n        }\n    }\n}\n"
  },
  {
    "path": "sample/tests/NimblePros.SampleToDo.UnitTests/Core/Specifications/IncompleteItemSpecificationsConstructor.cs",
    "content": "﻿using NimblePros.SampleToDo.Core.ProjectAggregate;\nusing NimblePros.SampleToDo.Core.ProjectAggregate.Specifications;\n\nnamespace NimblePros.SampleToDo.UnitTests.Core.Specifications;\n\npublic class IncompleteItemsSpecificationConstructor\n{\n  [Fact]\n  public void FilterCollectionToOnlyReturnItemsWithIsDoneFalse()\n  {\n    var item1 = new ToDoItem();\n    var item2 = new ToDoItem();\n    var item3 = new ToDoItem();\n    item3.MarkComplete();\n\n    var items = new List<ToDoItem>() { item1, item2, item3 };\n\n    var spec = new IncompleteItemsSpec();\n\n    var filteredList = spec.Evaluate(items);\n\n    Assert.Contains(item1, filteredList);\n    Assert.Contains(item2, filteredList);\n    Assert.DoesNotContain(item3, filteredList);\n  }\n}\n"
  },
  {
    "path": "sample/tests/NimblePros.SampleToDo.UnitTests/GlobalUsings.cs",
    "content": "﻿global using Ardalis.Result;\nglobal using Ardalis.Specification;\nglobal using Mediator;\nglobal using Microsoft.Extensions.Logging;\nglobal using NimblePros.SharedKernel;\nglobal using NSubstitute;\nglobal using NSubstitute.ReturnsExtensions;\nglobal using Xunit;\n"
  },
  {
    "path": "sample/tests/NimblePros.SampleToDo.UnitTests/NimblePros.SampleToDo.UnitTests.csproj",
    "content": "﻿<Project Sdk=\"Microsoft.NET.Sdk\">\n  <ItemGroup>\n    <Compile Remove=\"Core\\Services\\ToDoItemSearchService_GetAllIncompleteItems.cs\" />\n    <Compile Remove=\"Core\\Services\\ToDoItemSearchService_GetNextIncompleteItem.cs\" />\n  </ItemGroup>\n\n  <ItemGroup>\n    <PackageReference Include=\"Microsoft.NET.Test.Sdk\" />\n    <PackageReference Include=\"NimblePros.SharedKernel\" />\n    <PackageReference Include=\"NSubstitute\" />\n    <PackageReference Include=\"Shouldly\" />\n    <PackageReference Include=\"xunit.runner.visualstudio\">\n      <PrivateAssets>all</PrivateAssets>\n      <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>\n    </PackageReference>\n    <PackageReference Include=\"coverlet.collector\">\n      <PrivateAssets>all</PrivateAssets>\n      <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>\n    </PackageReference>\n    <PackageReference Include=\"ReportGenerator\" />\n    <PackageReference Include=\"xunit\" />\n  </ItemGroup>\n\n  <ItemGroup>\n    <None Update=\"xunit.runner.json\">\n\t  <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>\n    </None>\n  </ItemGroup>\n\n  <ItemGroup>\n    <Folder Include=\"Core\\Services\\\" />\n  </ItemGroup>\n\n  <ItemGroup>\n    <ProjectReference Include=\"..\\..\\src\\NimblePros.SampleToDo.Core\\NimblePros.SampleToDo.Core.csproj\" />\n    <ProjectReference Include=\"..\\..\\src\\NimblePros.SampleToDo.UseCases\\NimblePros.SampleToDo.UseCases.csproj\" />\n  </ItemGroup>\n\n</Project>\n"
  },
  {
    "path": "sample/tests/NimblePros.SampleToDo.UnitTests/NoOpMediator.cs",
    "content": "﻿namespace NimblePros.SampleToDo.UnitTests;\n\npublic class NoOpMediator : IMediator\n{\n  public async Task<IAsyncEnumerable<TResponse>> CreateStream<TResponse>(IStreamQuery<TResponse> query, CancellationToken cancellationToken = default)\n  {\n    await Task.Delay(1);\n    return AsyncEnumerable.Empty<TResponse>();\n  }\n\n  public IAsyncEnumerable<TResponse> CreateStream<TResponse>(IStreamRequest<TResponse> request, CancellationToken cancellationToken = default)\n  {\n    return AsyncEnumerable.Empty<TResponse>();\n  }\n\n  public IAsyncEnumerable<TResponse> CreateStream<TResponse>(IStreamCommand<TResponse> command, CancellationToken cancellationToken = default)\n  {\n    return AsyncEnumerable.Empty<TResponse>();\n  }\n\n  public IAsyncEnumerable<object?> CreateStream(object message, CancellationToken cancellationToken = default)\n  {\n    return AsyncEnumerable.Empty<object?>();\n  }\n\n  public ValueTask Publish<TNotification>(TNotification notification, CancellationToken cancellationToken = default) where TNotification : INotification\n  {\n    return ValueTask.CompletedTask;\n  }\n\n  public ValueTask Publish(object notification, CancellationToken cancellationToken = default)\n  {\n    return ValueTask.CompletedTask;\n  }\n\n  public ValueTask<TResponse> Send<TResponse>(IRequest<TResponse> request, CancellationToken cancellationToken = default)\n  {\n    return ValueTask.FromResult(default(TResponse)!);\n  }\n\n  public ValueTask<TResponse> Send<TResponse>(ICommand<TResponse> command, CancellationToken cancellationToken = default)\n  {\n    return ValueTask.FromResult(default(TResponse)!);\n  }\n\n  public ValueTask<TResponse> Send<TResponse>(IQuery<TResponse> query, CancellationToken cancellationToken = default)\n  {\n    return ValueTask.FromResult(default(TResponse)!);\n  }\n\n  public ValueTask<object?> Send(object message, CancellationToken cancellationToken = default)\n  {\n    return ValueTask.FromResult<object?>(null);\n  }\n\n  IAsyncEnumerable<TResponse> ISender.CreateStream<TResponse>(IStreamQuery<TResponse> query, CancellationToken cancellationToken)\n  {\n    return AsyncEnumerable.Empty<TResponse>();\n  }\n}\n"
  },
  {
    "path": "sample/tests/NimblePros.SampleToDo.UnitTests/ToDoItemBuilder.cs",
    "content": "﻿using NimblePros.SampleToDo.Core.ProjectAggregate;\n\nnamespace NimblePros.SampleToDo.UnitTests;\n\n// Learn more about test builders:\n// https://ardalis.com/improve-tests-with-the-builder-pattern-for-test-data\npublic class ToDoItemBuilder\n{\n  private ToDoItem _todo = new ToDoItem();\n\n  public ToDoItemBuilder Id(int id)\n  {\n    _todo.Id = ToDoItemId.From(id);\n    return this;\n  }\n\n  public ToDoItemBuilder Title(String title)\n  {\n    _todo.UpdateTitle(ToDoItemTitle.From(title));\n    return this;\n  }\n\n  public ToDoItemBuilder Description(String description)\n  {\n    _todo.UpdateDescription(ToDoItemDescription.From(description));\n    return this;\n  }\n\n  public ToDoItemBuilder WithDefaultValues()\n  {\n    _todo = new ToDoItem(title: ToDoItemTitle.From(\"Test Item\"), description: ToDoItemDescription.From(\"Test Description\")) { Id = ToDoItemId.From(1) };\n\n    return this;\n  }\n\n  public ToDoItem Build() => _todo;\n}\n"
  },
  {
    "path": "sample/tests/NimblePros.SampleToDo.UnitTests/UseCases/Contributors/CreateContributorHandlerHandle.cs",
    "content": "﻿using NimblePros.SampleToDo.Core.ContributorAggregate;\nusing NimblePros.SampleToDo.UseCases.Contributors.Commands.Create;\nusing Shouldly;\n\nnamespace NimblePros.SampleToDo.UnitTests.UseCases.Contributors;\npublic class CreateContributorHandlerHandle\n{\n  private readonly string _testName = \"test name\";\n  private readonly IRepository<Contributor> _repository = Substitute.For<IRepository<Contributor>>();\n  private CreateContributorHandler _handler;\n\n  public CreateContributorHandlerHandle()\n  {\n    _handler = new CreateContributorHandler(_repository);\n  }\n\n  private Contributor CreateContributor()\n  {\n    return new Contributor(ContributorName.From(_testName)) { Id = ContributorId.From(1) };\n  }\n\n  [Fact]\n  public async Task ReturnsSuccessGivenValidName()\n  {\n    _repository.AddAsync(Arg.Any<Contributor>(), Arg.Any<CancellationToken>())\n      .Returns(Task.FromResult(CreateContributor()));\n    var result = await _handler.Handle(new CreateContributorCommand(ContributorName.From(_testName)), CancellationToken.None);\n\n    result.IsSuccess.ShouldBeTrue();\n  }\n}\n"
  },
  {
    "path": "sample/tests/NimblePros.SampleToDo.UnitTests/UseCases/Contributors/GetContributorHandlerHandle.cs",
    "content": "﻿using NimblePros.SampleToDo.Core.ContributorAggregate;\nusing NimblePros.SampleToDo.Core.ContributorAggregate.Specifications;\nusing NimblePros.SampleToDo.UseCases.Contributors.Queries.Get;\nusing Shouldly;\n\nnamespace NimblePros.SampleToDo.UnitTests.UseCases.Contributors;\n\npublic class GetContributorHandlerHandle\n{\n  private readonly ContributorName _testName = ContributorName.From(\"test name\");\n  private readonly IReadRepository<Contributor> _repository = Substitute.For<IReadRepository<Contributor>>();\n  private GetContributorHandler _handler;\n\n  public GetContributorHandlerHandle()\n  {\n      _handler = new GetContributorHandler(_repository);\n  }\n\n  [Fact]\n  public async Task ReturnsRecordGivenValidId()\n  {\n    ContributorId validId = ContributorId.From(1);\n    _repository.FirstOrDefaultAsync(Arg.Any<ContributorByIdSpec>(), Arg.Any<CancellationToken>())\n      .Returns(new Contributor(_testName));\n    var result = await _handler.Handle(new GetContributorQuery(validId), CancellationToken.None);\n\n    result.IsSuccess.ShouldBeTrue();\n    result.Value.Name.ShouldBe(_testName);\n  }\n\n  [Fact]\n  public async Task ReturnsNotFoundGivenInvalidId()\n  {\n    ContributorId invalidId = ContributorId.From(1000);\n    _repository.FirstOrDefaultAsync(Arg.Any<ContributorByIdSpec>(), Arg.Any<CancellationToken>()).ReturnsNull();\n    var result = await _handler.Handle(new GetContributorQuery(invalidId), CancellationToken.None);\n\n    result.IsSuccess.ShouldBeFalse();\n    result.Status.ShouldBe(ResultStatus.NotFound);\n  }\n}\n"
  },
  {
    "path": "sample/tests/NimblePros.SampleToDo.UnitTests/UseCases/Contributors/UpdateContributorHandlerHandle.cs",
    "content": "﻿using NimblePros.SampleToDo.Core.ContributorAggregate;\nusing NimblePros.SampleToDo.Core.ContributorAggregate.Specifications;\nusing NimblePros.SampleToDo.UseCases.Contributors.Commands.Update;\nusing Shouldly;\n\nnamespace NimblePros.SampleToDo.UnitTests.UseCases.Contributors;\n\npublic class UpdateContributorHandlerHandle\n{\n  private readonly ContributorName _testName = ContributorName.From(\"test name\");\n  private readonly ContributorName _newName = ContributorName.From(Guid.NewGuid().ToString());\n  private readonly IRepository<Contributor> _repository = Substitute.For<IRepository<Contributor>>();\n  private UpdateContributorHandler _handler;\n\n  public UpdateContributorHandlerHandle()\n  {\n      _handler = new UpdateContributorHandler(_repository);\n  }\n\n  [Fact]\n  public async Task ReturnsRecordGivenValidId()\n  {\n    ContributorId validId = ContributorId.From(1);\n    _repository.SingleOrDefaultAsync(Arg.Any<ContributorByIdSpec>(), Arg.Any<CancellationToken>())\n      .Returns(new Contributor(_testName) { Id = ContributorId.From(1)});\n    var result = await _handler.Handle(new UpdateContributorCommand(validId, _newName), CancellationToken.None);\n\n    result.IsSuccess.ShouldBeTrue();\n    result.Value.Name.ShouldBe(_newName);\n  }\n\n  [Fact]\n  public async Task ReturnsNotFoundGivenNonexistentId()\n  {\n    ContributorId nonexistentId = ContributorId.From(1000);\n    _repository.GetByIdAsync(Arg.Any<int>(), Arg.Any<CancellationToken>()).ReturnsNull();\n    var result = await _handler.Handle(new UpdateContributorCommand(nonexistentId, _newName), CancellationToken.None);\n\n    result.IsSuccess.ShouldBeFalse();\n    result.Status.ShouldBe(ResultStatus.NotFound);\n  }\n}\n"
  },
  {
    "path": "sample/tests/NimblePros.SampleToDo.UnitTests/xunit.runner.json",
    "content": "﻿{\n  \"shadowCopy\": false,\n  \"parallelizeAssembly\": false,\n  \"parallelizeTestCollections\": false\n}"
  },
  {
    "path": "src/Clean.Architecture.AspireHost/AppHost.cs",
    "content": "﻿using System.Net.Sockets;\n\nvar builder = DistributedApplication.CreateBuilder(args);\n\n// Add SQL Server container\nvar sqlServer = builder.AddSqlServer(\"sqlserver\")\n  .WithLifetime(ContainerLifetime.Persistent);\n\n// Add the database\nvar cleanArchDb = sqlServer.AddDatabase(\"cleanarchitecture\");\n\n// Papercut SMTP container for email testing\nvar papercut = builder.AddContainer(\"papercut\", \"jijiechen/papercut\", \"latest\")\n  .WithEndpoint(\"smtp\", e =>\n  {\n    e.TargetPort = 25;   // container port\n    e.Port = 25;         // host port\n    e.Protocol = ProtocolType.Tcp;\n    e.UriScheme = \"smtp\";\n  })\n  .WithEndpoint(\"ui\", e =>\n  {\n    e.TargetPort = 37408;\n    e.Port = 37408;\n    e.UriScheme = \"http\";\n  });\n\n// Add the web project with the database connection\nbuilder.AddProject<Projects.Clean_Architecture_Web>(\"web\")\n  .WithReference(cleanArchDb)\n  .WithEnvironment(\"ASPNETCORE_ENVIRONMENT\", builder.Environment.EnvironmentName)\n  .WithEnvironment(\"Papercut__Smtp__Url\", papercut.GetEndpoint(\"smtp\"))\n  .WaitFor(cleanArchDb)\n  .WaitFor(papercut);\n\nbuilder\n  .Build()\n  .Run();\n"
  },
  {
    "path": "src/Clean.Architecture.AspireHost/Clean.Architecture.AspireHost.csproj",
    "content": "<Project Sdk=\"Aspire.AppHost.Sdk/13.0.0\">\n\n  <PropertyGroup>\n    <OutputType>Exe</OutputType>\n    <IsAspireHost>true</IsAspireHost>\n    <UserSecretsId>c540eeb6-e06b-4456-a539-be58dd8b88c7</UserSecretsId>\n  </PropertyGroup>\n\n  <ItemGroup>\n    <PackageReference Include=\"Aspire.Hosting.AppHost\" />\n    <PackageReference Include=\"Aspire.Hosting.SqlServer\" />\n  </ItemGroup>\n\n  <ItemGroup>\n    <ProjectReference Include=\"..\\Clean.Architecture.Web\\Clean.Architecture.Web.csproj\" />\n  </ItemGroup>\n  <ItemGroup>\n    <!-- The IsAspireProjectResource attribute tells .NET Aspire to treat this \n        reference as a standard project reference and not attempt to generate\n        a metadata file -->\n    <ProjectReference Include=\"..\\Clean.Architecture.ServiceDefaults\\Clean.Architecture.ServiceDefaults.csproj\" IsAspireProjectResource=\"false\" />\n  </ItemGroup>\n\n</Project>\n"
  },
  {
    "path": "src/Clean.Architecture.AspireHost/GlobalUsings.cs",
    "content": "﻿global using Aspire.Hosting;\n"
  },
  {
    "path": "src/Clean.Architecture.AspireHost/Properties/launchSettings.json",
    "content": "{\n  \"$schema\": \"https://json.schemastore.org/launchsettings.json\",\n  \"profiles\": {\n    \"https\": {\n      \"commandName\": \"Project\",\n      \"dotnetRunMessages\": true,\n      \"launchBrowser\": true,\n      \"applicationUrl\": \"https://localhost:17143;http://localhost:15258\",\n      \"environmentVariables\": {\n        \"ASPNETCORE_ENVIRONMENT\": \"Development\",\n        \"DOTNET_ENVIRONMENT\": \"Development\",\n        \"DOTNET_DASHBOARD_OTLP_ENDPOINT_URL\": \"https://localhost:21007\",\n        \"DOTNET_RESOURCE_SERVICE_ENDPOINT_URL\": \"https://localhost:22245\"\n      }\n    },\n    \"http\": {\n      \"commandName\": \"Project\",\n      \"dotnetRunMessages\": true,\n      \"launchBrowser\": true,\n      \"applicationUrl\": \"http://localhost:15258\",\n      \"environmentVariables\": {\n        \"ASPNETCORE_ENVIRONMENT\": \"Development\",\n        \"DOTNET_ENVIRONMENT\": \"Development\",\n        \"DOTNET_DASHBOARD_OTLP_ENDPOINT_URL\": \"http://localhost:19187\",\n        \"DOTNET_RESOURCE_SERVICE_ENDPOINT_URL\": \"http://localhost:20134\"\n      }\n    }\n  }\n}\n"
  },
  {
    "path": "src/Clean.Architecture.AspireHost/README.md",
    "content": "# Clean Architecture Aspire Host\n\nThis project uses .NET Aspire to orchestrate the application and its dependencies.\n\n## SQL Server Container\n\nThe Aspire host is configured to run a SQL Server container and automatically provides the connection string to the Web application.\n\n### Running the Application\n\n1. Set `Clean.Architecture.AspireHost` as the startup project\n2. Run the application (F5 or Ctrl+F5)\n3. The Aspire Dashboard will open, showing all running resources including the SQL Server container\n4. The Web application will automatically connect to the SQL Server container\n\n### Connection String\n\nWhen running through Aspire, the connection string is automatically provided by Aspire and will override the `DefaultConnection` in appsettings.json. The connection is named \"cleanarchitecture\" and is referenced in the Web project.\n\n### Running Without Aspire\n\nIf you run the Web project directly (not through AspireHost), it will fall back to using the SQLite connection string from appsettings.json.\n\n### Database Migrations\n\nThe existing migrations were created for SQLite but will work with SQL Server as well. If you need to create a new migration:\n\nFrom the Web project directory:\n```bash\ndotnet ef migrations add MigrationName -c AppDbContext -p ../Clean.Architecture.Infrastructure/Clean.Architecture.Infrastructure.csproj -s Clean.Architecture.Web.csproj -o Data/Migrations\n```\n\nTo update the database:\n```bash\ndotnet ef database update -c AppDbContext -p ../Clean.Architecture.Infrastructure/Clean.Architecture.Infrastructure.csproj -s Clean.Architecture.Web.csproj\n```\n\nNote: When running through Aspire, the database will be automatically created in the SQL Server container if it doesn't exist.\n\n### Container Persistence\n\nThe SQL Server container is configured with `ContainerLifetime.Persistent`, which means the data will persist between application runs. To reset the database, you can:\n1. Delete the container through the Aspire dashboard\n2. Use the Docker CLI: `docker rm <container-name>`\n"
  },
  {
    "path": "src/Clean.Architecture.AspireHost/appsettings.Development.json",
    "content": "{\n  \"Logging\": {\n    \"LogLevel\": {\n      \"Default\": \"Information\",\n      \"Microsoft.AspNetCore\": \"Warning\"\n    }\n  }\n}\n"
  },
  {
    "path": "src/Clean.Architecture.AspireHost/appsettings.json",
    "content": "{\n  \"Logging\": {\n    \"LogLevel\": {\n      \"Default\": \"Information\",\n      \"Microsoft.AspNetCore\": \"Warning\",\n      \"Aspire.Hosting.Dcp\": \"Warning\"\n    }\n  }\n}\n"
  },
  {
    "path": "src/Clean.Architecture.Core/Clean.Architecture.Core.csproj",
    "content": "﻿<Project Sdk=\"Microsoft.NET.Sdk\">\n  <Sdk Name=\"Microsoft.Build.CentralPackageVersions\" Version=\"2.1.3\" />\n  <ItemGroup>\n    <Content Remove=\"C:\\Users\\steve\\.nuget\\packages\\vogen\\8.0.2\\contentFiles\\any\\netstandard2.0\\Vogen.targets\" />\n  </ItemGroup>\n\n  <ItemGroup>\n    <PackageReference Include=\"Ardalis.GuardClauses\" />\n    <PackageReference Include=\"Ardalis.Result\" />\n    <PackageReference Include=\"Ardalis.SharedKernel\" />\n    <PackageReference Include=\"Ardalis.SmartEnum\" />\n    <PackageReference Include=\"Ardalis.Specification\" />\n    <PackageReference Include=\"Mediator.Abstractions\" />\n    <PackageReference Include=\"Microsoft.Extensions.Logging.Abstractions\" />\n    <PackageReference Include=\"Vogen\" />\n  </ItemGroup>\n\n</Project>\n"
  },
  {
    "path": "src/Clean.Architecture.Core/Clean.Architecture.Core.sln",
    "content": "Microsoft Visual Studio Solution File, Format Version 12.00\n# Visual Studio Version 17\nVisualStudioVersion = 17.5.2.0\nMinimumVisualStudioVersion = 10.0.40219.1\nProject(\"{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}\") = \"Clean.Architecture.Core\", \"Clean.Architecture.Core.csproj\", \"{9870518F-D672-E9CD-6676-126851E99FD1}\"\nEndProject\nGlobal\n\tGlobalSection(SolutionConfigurationPlatforms) = preSolution\n\t\tDebug|Any CPU = Debug|Any CPU\n\t\tRelease|Any CPU = Release|Any CPU\n\tEndGlobalSection\n\tGlobalSection(ProjectConfigurationPlatforms) = postSolution\n\t\t{9870518F-D672-E9CD-6676-126851E99FD1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\n\t\t{9870518F-D672-E9CD-6676-126851E99FD1}.Debug|Any CPU.Build.0 = Debug|Any CPU\n\t\t{9870518F-D672-E9CD-6676-126851E99FD1}.Release|Any CPU.ActiveCfg = Release|Any CPU\n\t\t{9870518F-D672-E9CD-6676-126851E99FD1}.Release|Any CPU.Build.0 = Release|Any CPU\n\tEndGlobalSection\n\tGlobalSection(SolutionProperties) = preSolution\n\t\tHideSolutionNode = FALSE\n\tEndGlobalSection\n\tGlobalSection(ExtensibilityGlobals) = postSolution\n\t\tSolutionGuid = {5942B8EC-445E-4783-ACEF-56C707B6266C}\n\tEndGlobalSection\nEndGlobal\n"
  },
  {
    "path": "src/Clean.Architecture.Core/ContributorAggregate/Contributor.cs",
    "content": "﻿using Clean.Architecture.Core.ContributorAggregate.Events;\n\nnamespace Clean.Architecture.Core.ContributorAggregate;\n\npublic class Contributor(ContributorName name) : EntityBase<Contributor, ContributorId>, IAggregateRoot\n{\n  public ContributorName Name { get; private set; } = name;\n  public ContributorStatus Status { get; private set; } = ContributorStatus.NotSet;\n  public PhoneNumber? PhoneNumber { get; private set; }\n\n  public Contributor UpdatePhoneNumber(PhoneNumber newPhoneNumber)\n  {\n    PhoneNumber = newPhoneNumber;\n    return this;\n  }\n\n  public Contributor UpdateName(ContributorName newName)\n  {\n    if (Name == newName) return this;\n    Name = newName;\n    RegisterDomainEvent(new ContributorNameUpdatedEvent(this));\n    return this;\n  }\n}\n"
  },
  {
    "path": "src/Clean.Architecture.Core/ContributorAggregate/ContributorId.cs",
    "content": "﻿using Vogen;\n\n[assembly: VogenDefaults(\n        staticAbstractsGeneration: StaticAbstractsGeneration.MostCommon | StaticAbstractsGeneration.InstanceMethodsAndProperties)]\n\n\nnamespace Clean.Architecture.Core.ContributorAggregate;\n\n[ValueObject<int>]\npublic readonly partial struct ContributorId\n{\n  private static Validation Validate(int value)\n      => value > 0 ? Validation.Ok : Validation.Invalid(\"ContributorId must be positive.\");\n}\n"
  },
  {
    "path": "src/Clean.Architecture.Core/ContributorAggregate/ContributorName.cs",
    "content": "﻿using Vogen;\n\nnamespace Clean.Architecture.Core.ContributorAggregate;\n\n[ValueObject<string>(conversions: Conversions.SystemTextJson)]\npublic partial struct ContributorName\n{\n  public const int MaxLength = 100;\n  private static Validation Validate(in string name) =>\n    string.IsNullOrEmpty(name)\n      ? Validation.Invalid(\"Name cannot be empty\")\n      : name.Length > MaxLength\n        ? Validation.Invalid($\"Name cannot be longer than {MaxLength} characters\")\n        : Validation.Ok;\n}\n"
  },
  {
    "path": "src/Clean.Architecture.Core/ContributorAggregate/ContributorStatus.cs",
    "content": "﻿namespace Clean.Architecture.Core.ContributorAggregate;\n\npublic class ContributorStatus : SmartEnum<ContributorStatus>\n{\n  public static readonly ContributorStatus CoreTeam = new(nameof(CoreTeam), 1);\n  public static readonly ContributorStatus Community = new(nameof(Community), 2);\n  public static readonly ContributorStatus NotSet = new(nameof(NotSet), 3);\n\n  protected ContributorStatus(string name, int value) : base(name, value) { }\n}\n\n"
  },
  {
    "path": "src/Clean.Architecture.Core/ContributorAggregate/Events/ContributorDeletedEvent.cs",
    "content": "﻿namespace Clean.Architecture.Core.ContributorAggregate.Events;\n\n/// <summary>\n/// A domain event that is dispatched whenever a contributor is deleted.\n/// The DeleteContributorService is used to dispatch this event.\n/// NOTE: Would prefer this be internal but Mediator Source Generator needs access to it from elsewhere.\n/// </summary>\npublic sealed class ContributorDeletedEvent(ContributorId contributorId) : DomainEventBase\n{\n  public ContributorId ContributorId { get; init; } = contributorId;\n}\n"
  },
  {
    "path": "src/Clean.Architecture.Core/ContributorAggregate/Events/ContributorNameUpdatedEvent.cs",
    "content": "﻿namespace Clean.Architecture.Core.ContributorAggregate.Events;\n\npublic sealed class ContributorNameUpdatedEvent(Contributor contributor) : DomainEventBase\n{\n  public Contributor Contributor { get; init; } = contributor;\n}\n"
  },
  {
    "path": "src/Clean.Architecture.Core/ContributorAggregate/Handlers/ContributorDeletedHandler.cs",
    "content": "﻿using Clean.Architecture.Core.ContributorAggregate.Events;\nusing Clean.Architecture.Core.Interfaces;\n\nnamespace Clean.Architecture.Core.ContributorAggregate.Handlers;\n\npublic class ContributorDeletedHandler(ILogger<ContributorDeletedHandler> logger,\n  IEmailSender emailSender) : INotificationHandler<ContributorDeletedEvent>\n{\n  public async ValueTask Handle(ContributorDeletedEvent domainEvent, CancellationToken cancellationToken)\n  {\n    logger.LogInformation(\"Handling Contributed Deleted event for {contributorId}\", domainEvent.ContributorId);\n\n    await emailSender.SendEmailAsync(\"to@test.com\",\n                                     \"from@test.com\",\n                                     \"Contributor Deleted\",\n                                     $\"Contributor with id {domainEvent.ContributorId} was deleted.\");\n  }\n}\n"
  },
  {
    "path": "src/Clean.Architecture.Core/ContributorAggregate/Handlers/ContributorNameUpdatedEmailNotificationHandler.cs",
    "content": "﻿using Clean.Architecture.Core.ContributorAggregate.Events;\nusing Clean.Architecture.Core.Interfaces;\n\nnamespace Clean.Architecture.Core.ContributorAggregate.Handlers;\n\npublic class ContributorNameUpdatedEmailNotificationHandler(\n  ILogger<ContributorNameUpdatedEmailNotificationHandler> logger,\n  IEmailSender emailSender) : INotificationHandler<ContributorNameUpdatedEvent>\n{\n  public async ValueTask Handle(ContributorNameUpdatedEvent domainEvent, CancellationToken cancellationToken)\n  {\n    logger.LogInformation(\"Handling Contributor Name Updated event for {contributorId}\", domainEvent.Contributor.Id);\n\n    await emailSender.SendEmailAsync(\"to@test.com\",\n                                     \"from@test.com\",\n                                     $\"Contributor {domainEvent.Contributor.Id} Name Updated\",\n$\"Contributor with id {domainEvent.Contributor.Id} had their name updated to {domainEvent.Contributor.Name}.\");\n  }\n}\n"
  },
  {
    "path": "src/Clean.Architecture.Core/ContributorAggregate/PhoneNumber.cs",
    "content": "﻿namespace Clean.Architecture.Core.ContributorAggregate;\n\npublic class PhoneNumber(string countryCode, string number, string? extension) : ValueObject\n{\n  public static PhoneNumber Unknown { get; } = new PhoneNumber(String.Empty, String.Empty, String.Empty);\n  public string CountryCode { get; private set; } = countryCode;\n  public string Number { get; private set; } = number;\n  public string? Extension { get; private set; } = extension;\n\n  protected override IEnumerable<object> GetEqualityComponents()\n  {\n    yield return CountryCode;\n    yield return Number;\n    yield return Extension ?? String.Empty;\n  }\n\n  public override string ToString()\n  {\n    return $\"{CountryCode} {Number}{(string.IsNullOrEmpty(Extension) ? String.Empty : $\" x{Extension}\")}\";\n  }\n}\n"
  },
  {
    "path": "src/Clean.Architecture.Core/ContributorAggregate/Specifications/ContributorByIdSpec.cs",
    "content": "﻿namespace Clean.Architecture.Core.ContributorAggregate.Specifications;\n\npublic class ContributorByIdSpec : Specification<Contributor>\n{\n  public ContributorByIdSpec(ContributorId contributorId) =>\n    Query\n        .Where(contributor => contributor.Id == contributorId);\n}\n"
  },
  {
    "path": "src/Clean.Architecture.Core/GlobalUsings.cs",
    "content": "﻿global using Ardalis.GuardClauses;\nglobal using Ardalis.Result;\nglobal using Ardalis.SharedKernel;\nglobal using Ardalis.SmartEnum;\nglobal using Ardalis.Specification;\nglobal using Mediator;\nglobal using Microsoft.Extensions.Logging;\n"
  },
  {
    "path": "src/Clean.Architecture.Core/Interfaces/IDeleteContributorService.cs",
    "content": "﻿using Clean.Architecture.Core.ContributorAggregate;\n\nnamespace Clean.Architecture.Core.Interfaces;\n\npublic interface IDeleteContributorService\n{\n  // This service and method exist to provide a place in which to fire domain events\n  // when deleting this aggregate root entity\n  public ValueTask<Result> DeleteContributor(ContributorId contributorId);\n}\n"
  },
  {
    "path": "src/Clean.Architecture.Core/Interfaces/IEmailSender.cs",
    "content": "﻿namespace Clean.Architecture.Core.Interfaces;\n\npublic interface IEmailSender\n{\n  Task SendEmailAsync(string to, string from, string subject, string body);\n}\n"
  },
  {
    "path": "src/Clean.Architecture.Core/README.md",
    "content": "﻿## Core (Domain Model) Project\n\nIn Clean Architecture, the central focus should be on Entities and business rules.\n\nIn Domain-Driven Design, this is the Domain Model.\n\nThis project should contain all of your Entities, Value Objects, and business logic.\n\nEntities that are related and should change together should be grouped into an Aggregate.\n\nAggregate folders provide good top-level folders in this project.\n\nEntities should leverage encapsulation and should minimize public setters.\n\nEntities can leverage Domain Events to communicate changes to other parts of the system.\n\nEntities can define Specifications that can be used to query for them.\n\nValue Objects should be immutable and should implement equality based on their properties.\n\nValue Objects help eliminate primitive obsession in your Entities.\n\nFollow Parse, Don't Validate principle. https://www.youtube.com/watch?v=KQVy0CaB7ds\n\nFor mutable access, Aggregates should be accessed through a Repository interface.\n\nRead-only ad hoc queries can use separate Query Services that don't use the Domain Model.\n\nNeed help? Check out the sample here:\nhttps://github.com/ardalis/CleanArchitecture/tree/main/sample\n\nStill need help?\nContact us at https://nimblepros.com\n"
  },
  {
    "path": "src/Clean.Architecture.Core/Services/DeleteContributorService.cs",
    "content": "﻿using Clean.Architecture.Core.ContributorAggregate;\nusing Clean.Architecture.Core.ContributorAggregate.Events;\nusing Clean.Architecture.Core.Interfaces;\n\nnamespace Clean.Architecture.Core.Services;\n\n/// <summary>\n/// This is here mainly so there's an example of a domain service\n/// and also to demonstrate how to fire domain events from a service.\n/// </summary>\n/// <param name=\"_repository\"></param>\n/// <param name=\"_mediator\"></param>\n/// <param name=\"_logger\"></param>\npublic class DeleteContributorService(IRepository<Contributor> _repository,\n  IMediator _mediator,\n  ILogger<DeleteContributorService> _logger) : IDeleteContributorService\n{\n  public async ValueTask<Result> DeleteContributor(ContributorId contributorId)\n  {\n    _logger.LogInformation(\"Deleting Contributor {contributorId}\", contributorId);\n    Contributor? aggregateToDelete = await _repository.GetByIdAsync(contributorId);\n    if (aggregateToDelete == null) return Result.NotFound();\n\n    await _repository.DeleteAsync(aggregateToDelete);\n    var domainEvent = new ContributorDeletedEvent(contributorId);\n    await _mediator.Publish(domainEvent);\n\n    return Result.Success();\n  }\n}\n"
  },
  {
    "path": "src/Clean.Architecture.Infrastructure/Clean.Architecture.Infrastructure.csproj",
    "content": "﻿<Project Sdk=\"Microsoft.NET.Sdk\">\n  <Sdk Name=\"Microsoft.Build.CentralPackageVersions\" Version=\"2.1.3\" />\n\n  <ItemGroup>\n    <PackageReference Include=\"Ardalis.SharedKernel\" />\n    <PackageReference Include=\"Ardalis.Specification.EntityFrameworkCore\" />\n    <PackageReference Include=\"Azure.Identity\" />\n    <PackageReference Include=\"MailKit\" />\n    <PackageReference Include=\"Microsoft.EntityFrameworkCore.Relational\" />\n    <PackageReference Include=\"Microsoft.EntityFrameworkCore.Design\" \n                      ExcludeAssets=\"contentFiles\" PrivateAssets=\"all\" />\n    <PackageReference Include=\"Microsoft.EntityFrameworkCore.Sqlite\" />\n    <PackageReference Include=\"Microsoft.EntityFrameworkCore.SqlServer\" />\n    <PackageReference Include=\"Microsoft.Extensions.Configuration\" />\n    <PackageReference Include=\"Microsoft.Extensions.Logging\" />\n    <PackageReference Include=\"Microsoft.Extensions.Options.ConfigurationExtensions\" />\n    <PackageReference Include=\"NimblePros.Metronome\" />\n    <PackageReference Include=\"SQLite\" />\n    <PackageReference Include=\"Vogen\" />\n  </ItemGroup>\n  \n  <ItemGroup>\n    <ProjectReference Include=\"..\\Clean.Architecture.Core\\Clean.Architecture.Core.csproj\" />\n    <ProjectReference Include=\"..\\Clean.Architecture.UseCases\\Clean.Architecture.UseCases.csproj\" />\n  </ItemGroup>\n</Project>\n"
  },
  {
    "path": "src/Clean.Architecture.Infrastructure/Data/AppDbContext.cs",
    "content": "﻿using Clean.Architecture.Core.ContributorAggregate;\n\nnamespace Clean.Architecture.Infrastructure.Data;\npublic class AppDbContext(DbContextOptions<AppDbContext> options) : DbContext(options)\n{\n  public DbSet<Contributor> Contributors => Set<Contributor>();\n\n  protected override void OnModelCreating(ModelBuilder modelBuilder)\n  {\n    base.OnModelCreating(modelBuilder);\n    modelBuilder.ApplyConfigurationsFromAssembly(Assembly.GetExecutingAssembly());\n  }\n\n  public override int SaveChanges() =>\n        SaveChangesAsync().GetAwaiter().GetResult();\n}\n"
  },
  {
    "path": "src/Clean.Architecture.Infrastructure/Data/AppDbContextExtensions.cs",
    "content": "﻿namespace Clean.Architecture.Infrastructure.Data;\n\npublic static class AppDbContextExtensions\n{\n  public static void AddApplicationDbContext(this IServiceCollection services, string connectionString) =>\n    services.AddDbContext<AppDbContext>(options =>\n         options.UseSqlite(connectionString));\n\n}\n"
  },
  {
    "path": "src/Clean.Architecture.Infrastructure/Data/Config/ContributorConfiguration.cs",
    "content": "﻿using Clean.Architecture.Core.ContributorAggregate;\n\nnamespace Clean.Architecture.Infrastructure.Data.Config;\n\npublic class ContributorConfiguration : IEntityTypeConfiguration<Contributor>\n{\n  public void Configure(EntityTypeBuilder<Contributor> builder)\n  {\n    builder.Property(entity => entity.Id)\n      .HasValueGenerator<VogenIdValueGenerator<AppDbContext, Contributor, ContributorId>>()\n      .HasVogenConversion()\n      .IsRequired();\n\n    builder.Property(entity => entity.Name)\n      .HasVogenConversion()\n      .HasMaxLength(ContributorName.MaxLength)\n      .IsRequired();\n\n    builder.OwnsOne(builder => builder.PhoneNumber);\n\n    builder.Property(x => x.Status)\n      .HasConversion(\n          x => x.Value,\n          x => ContributorStatus.FromValue(x));\n  }\n}\n"
  },
  {
    "path": "src/Clean.Architecture.Infrastructure/Data/Config/DataSchemaConstants.cs",
    "content": "﻿namespace Clean.Architecture.Infrastructure.Data.Config;\n\npublic static class DataSchemaConstants\n{\n  public const int DEFAULT_NAME_LENGTH = 100;\n}\n"
  },
  {
    "path": "src/Clean.Architecture.Infrastructure/Data/Config/VogenEfCoreConverters.cs",
    "content": "﻿using Clean.Architecture.Core.ContributorAggregate;\nusing Vogen;\n\nnamespace Clean.Architecture.Infrastructure.Data.Config;\n\n[EfCoreConverter<ContributorId>]\n[EfCoreConverter<ContributorName>]\ninternal partial class VogenEfCoreConverters;\n"
  },
  {
    "path": "src/Clean.Architecture.Infrastructure/Data/Config/VogenIdValueGenerator.cs",
    "content": "﻿using Microsoft.EntityFrameworkCore.ChangeTracking;\nusing Microsoft.EntityFrameworkCore.ValueGeneration;\n\nnamespace Clean.Architecture.Infrastructure.Data.Config;\n\ninternal class VogenIdValueGenerator<TContext, TEntityBase, TId> : ValueGenerator<TId>\n    where TContext : DbContext\n    where TEntityBase : EntityBase<TEntityBase, TId>\n    where TId : IVogen<TId, int>\n{\n  private readonly PropertyInfo _matchPropertyGetter;\n\n  public VogenIdValueGenerator()\n  {\n    var matchingProperties =\n        typeof(TContext).GetProperties().Where(p => p!.GetGetMethod()!.IsPublic && p.PropertyType == typeof(DbSet<TEntityBase>)).ToList();\n\n    if (matchingProperties.Count == 0)\n    {\n      throw new InvalidOperationException($\"No properties found in the EFCore context for a DBSet of {nameof(TEntityBase)}\");\n    }\n\n    if (matchingProperties.Count > 1)\n    {\n      throw new InvalidOperationException($\"Multiple properties found in the EFCore context for a DBSet of {nameof(TEntityBase)}\");\n    }\n\n    _matchPropertyGetter = matchingProperties[0];\n  }\n\n  public override TId Next(EntityEntry entry)\n  {\n    TContext ctx = (TContext)entry.Context;\n\n    DbSet<TEntityBase> entities = (DbSet<TEntityBase>)_matchPropertyGetter!.GetValue(ctx)!;\n\n    var next = Math.Max(\n        MaxFrom(entities.Local),\n        MaxFrom(entities)) + 1;\n\n    return TId.From(next);\n\n    static int MaxFrom(IEnumerable<TEntityBase> es) =>\n        es.Any() ? es.Max(e => e.Id.Value) : 0;\n  }\n\n\n  public override bool GeneratesTemporaryValues => false;\n}\n"
  },
  {
    "path": "src/Clean.Architecture.Infrastructure/Data/EfRepository.cs",
    "content": "﻿namespace Clean.Architecture.Infrastructure.Data;\n\n// inherit from Ardalis.Specification type\npublic class EfRepository<T>(AppDbContext dbContext) :\n  RepositoryBase<T>(dbContext), IReadRepository<T>, IRepository<T> where T : class, IAggregateRoot\n{\n}\n"
  },
  {
    "path": "src/Clean.Architecture.Infrastructure/Data/EventDispatcherInterceptor.cs",
    "content": "﻿using Microsoft.EntityFrameworkCore.Diagnostics;\n\nnamespace Clean.Architecture.Infrastructure.Data;\n\n// Intercepts SaveChanges to dispatch domain events after changes are successfully saved\npublic class EventDispatchInterceptor(IDomainEventDispatcher domainEventDispatcher) : SaveChangesInterceptor\n{\n  private readonly IDomainEventDispatcher _domainEventDispatcher = domainEventDispatcher;\n\n  // Called after SaveChangesAsync has completed successfully\n  public override async ValueTask<int> SavedChangesAsync(SaveChangesCompletedEventData eventData, int result,\n    CancellationToken cancellationToken = new CancellationToken())\n  {\n    var context = eventData.Context;\n    if (context is not AppDbContext appDbContext)\n    {\n      return await base.SavedChangesAsync(eventData, result, cancellationToken).ConfigureAwait(false);\n    }\n\n    // Retrieve all tracked entities that have domain events\n    var entitiesWithEvents = appDbContext.ChangeTracker.Entries<HasDomainEventsBase>()\n      .Select(e => e.Entity)\n      .Where(e => e.DomainEvents.Any())\n      .ToArray();\n\n    // Dispatch and clear domain events\n    await _domainEventDispatcher.DispatchAndClearEvents(entitiesWithEvents);\n\n    return await base.SavedChangesAsync(eventData, result, cancellationToken);\n\n  }\n}\n\n"
  },
  {
    "path": "src/Clean.Architecture.Infrastructure/Data/Migrations/20231218143922_PhoneNumber.Designer.cs",
    "content": "﻿// <auto-generated />\nusing Clean.Architecture.Infrastructure.Data;\nusing Microsoft.EntityFrameworkCore;\nusing Microsoft.EntityFrameworkCore.Infrastructure;\nusing Microsoft.EntityFrameworkCore.Migrations;\nusing Microsoft.EntityFrameworkCore.Storage.ValueConversion;\n\n#nullable disable\n\nnamespace Clean.Architecture.Infrastructure.Data.Migrations\n{\n    [DbContext(typeof(AppDbContext))]\n    [Migration(\"20231218143922_PhoneNumber\")]\n    partial class PhoneNumber\n    {\n        /// <inheritdoc />\n        protected override void BuildTargetModel(ModelBuilder modelBuilder)\n        {\n#pragma warning disable 612, 618\n            modelBuilder.HasAnnotation(\"ProductVersion\", \"8.0.0\");\n\n            modelBuilder.Entity(\"Clean.Architecture.Core.ContributorAggregate.Contributor\", b =>\n                {\n                    b.Property<int>(\"Id\")\n                        .ValueGeneratedOnAdd()\n                        .HasColumnType(\"INTEGER\");\n\n                    b.Property<string>(\"Name\")\n                        .IsRequired()\n                        .HasMaxLength(100)\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<int>(\"Status\")\n                        .HasColumnType(\"INTEGER\");\n\n                    b.HasKey(\"Id\");\n\n                    b.ToTable(\"Contributors\");\n                });\n\n            modelBuilder.Entity(\"Clean.Architecture.Core.ContributorAggregate.Contributor\", b =>\n                {\n                    b.OwnsOne(\"Clean.Architecture.Core.ContributorAggregate.PhoneNumber\", \"PhoneNumber\", b1 =>\n                        {\n                            b1.Property<int>(\"ContributorId\")\n                                .HasColumnType(\"INTEGER\");\n\n                            b1.Property<string>(\"CountryCode\")\n                                .IsRequired()\n                                .HasColumnType(\"TEXT\");\n\n                            b1.Property<string>(\"Extension\")\n                                .HasColumnType(\"TEXT\");\n\n                            b1.Property<string>(\"Number\")\n                                .IsRequired()\n                                .HasColumnType(\"TEXT\");\n\n                            b1.HasKey(\"ContributorId\");\n\n                            b1.ToTable(\"Contributors\");\n\n                            b1.WithOwner()\n                                .HasForeignKey(\"ContributorId\");\n                        });\n\n                    b.Navigation(\"PhoneNumber\");\n                });\n#pragma warning restore 612, 618\n        }\n    }\n}\n"
  },
  {
    "path": "src/Clean.Architecture.Infrastructure/Data/Migrations/20231218143922_PhoneNumber.cs",
    "content": "﻿using Microsoft.EntityFrameworkCore.Migrations;\n\n#nullable disable\n\nnamespace Clean.Architecture.Infrastructure.Data.Migrations;\n\n/// <inheritdoc />\npublic partial class PhoneNumber : Migration\n{\n  /// <inheritdoc />\n  protected override void Up(MigrationBuilder migrationBuilder)\n  {\n    migrationBuilder.CreateTable(\n        name: \"Contributors\",\n        columns: table => new\n        {\n          Id = table.Column<int>(type: \"INTEGER\", nullable: false)\n                .Annotation(\"Sqlite:Autoincrement\", true),\n          Name = table.Column<string>(type: \"TEXT\", maxLength: 100, nullable: false),\n          Status = table.Column<int>(type: \"INTEGER\", nullable: false),\n          PhoneNumber_CountryCode = table.Column<string>(type: \"TEXT\", nullable: true),\n          PhoneNumber_Number = table.Column<string>(type: \"TEXT\", nullable: true),\n          PhoneNumber_Extension = table.Column<string>(type: \"TEXT\", nullable: true)\n        },\n        constraints: table =>\n        {\n          table.PrimaryKey(\"PK_Contributors\", x => x.Id);\n        });\n  }\n\n  /// <inheritdoc />\n  protected override void Down(MigrationBuilder migrationBuilder)\n  {\n    migrationBuilder.DropTable(\n        name: \"Contributors\");\n  }\n}\n"
  },
  {
    "path": "src/Clean.Architecture.Infrastructure/Data/Migrations/20251113164108_UpdateForNet10.Designer.cs",
    "content": "﻿// <auto-generated />\nusing Clean.Architecture.Infrastructure.Data;\nusing Microsoft.EntityFrameworkCore;\nusing Microsoft.EntityFrameworkCore.Infrastructure;\nusing Microsoft.EntityFrameworkCore.Metadata;\nusing Microsoft.EntityFrameworkCore.Migrations;\nusing Microsoft.EntityFrameworkCore.Storage.ValueConversion;\n\n#nullable disable\n\nnamespace Clean.Architecture.Infrastructure.Data.Migrations\n{\n    [DbContext(typeof(AppDbContext))]\n    [Migration(\"20251113164108_UpdateForNet10\")]\n    partial class UpdateForNet10\n    {\n        /// <inheritdoc />\n        protected override void BuildTargetModel(ModelBuilder modelBuilder)\n        {\n#pragma warning disable 612, 618\n            modelBuilder\n                .HasAnnotation(\"ProductVersion\", \"10.0.0\")\n                .HasAnnotation(\"Relational:MaxIdentifierLength\", 128);\n\n            SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder);\n\n            modelBuilder.Entity(\"Clean.Architecture.Core.ContributorAggregate.Contributor\", b =>\n                {\n                    b.Property<int>(\"Id\")\n                        .HasColumnType(\"int\");\n\n                    b.Property<string>(\"Name\")\n                        .IsRequired()\n                        .HasMaxLength(100)\n                        .HasColumnType(\"nvarchar(100)\");\n\n                    b.Property<int>(\"Status\")\n                        .HasColumnType(\"int\");\n\n                    b.HasKey(\"Id\");\n\n                    b.ToTable(\"Contributors\");\n                });\n\n            modelBuilder.Entity(\"Clean.Architecture.Core.ContributorAggregate.Contributor\", b =>\n                {\n                    b.OwnsOne(\"Clean.Architecture.Core.ContributorAggregate.PhoneNumber\", \"PhoneNumber\", b1 =>\n                        {\n                            b1.Property<int>(\"ContributorId\")\n                                .HasColumnType(\"int\");\n\n                            b1.Property<string>(\"CountryCode\")\n                                .IsRequired()\n                                .HasColumnType(\"nvarchar(max)\");\n\n                            b1.Property<string>(\"Extension\")\n                                .HasColumnType(\"nvarchar(max)\");\n\n                            b1.Property<string>(\"Number\")\n                                .IsRequired()\n                                .HasColumnType(\"nvarchar(max)\");\n\n                            b1.HasKey(\"ContributorId\");\n\n                            b1.ToTable(\"Contributors\");\n\n                            b1.WithOwner()\n                                .HasForeignKey(\"ContributorId\");\n                        });\n\n                    b.Navigation(\"PhoneNumber\");\n                });\n#pragma warning restore 612, 618\n        }\n    }\n}\n"
  },
  {
    "path": "src/Clean.Architecture.Infrastructure/Data/Migrations/20251113164108_UpdateForNet10.cs",
    "content": "﻿using Microsoft.EntityFrameworkCore.Migrations;\n\n#nullable disable\n\nnamespace Clean.Architecture.Infrastructure.Data.Migrations;\n\n  /// <inheritdoc />\n  public partial class UpdateForNet10 : Migration\n  {\n      /// <inheritdoc />\n      protected override void Up(MigrationBuilder migrationBuilder)\n      {\n          // Only alter columns if using SQL Server\n          // SQLite uses dynamic typing so these changes aren't necessary\n          if (migrationBuilder.ActiveProvider == \"Microsoft.EntityFrameworkCore.SqlServer\")\n          {\n              migrationBuilder.AlterColumn<int>(\n                  name: \"Status\",\n                  table: \"Contributors\",\n                  type: \"int\",\n                  nullable: false,\n                  oldClrType: typeof(int),\n                  oldType: \"INTEGER\");\n\n              migrationBuilder.AlterColumn<string>(\n                  name: \"PhoneNumber_Number\",\n                  table: \"Contributors\",\n                  type: \"nvarchar(max)\",\n                  nullable: true,\n                  oldClrType: typeof(string),\n                  oldType: \"TEXT\",\n                  oldNullable: true);\n\n              migrationBuilder.AlterColumn<string>(\n                  name: \"PhoneNumber_Extension\",\n                  table: \"Contributors\",\n                  type: \"nvarchar(max)\",\n                  nullable: true,\n                  oldClrType: typeof(string),\n                  oldType: \"TEXT\",\n                  oldNullable: true);\n\n              migrationBuilder.AlterColumn<string>(\n                  name: \"PhoneNumber_CountryCode\",\n                  table: \"Contributors\",\n                  type: \"nvarchar(max)\",\n                  nullable: true,\n                  oldClrType: typeof(string),\n                  oldType: \"TEXT\",\n                  oldNullable: true);\n\n              migrationBuilder.AlterColumn<string>(\n                  name: \"Name\",\n                  table: \"Contributors\",\n                  type: \"nvarchar(100)\",\n                  maxLength: 100,\n                  nullable: false,\n                  oldClrType: typeof(string),\n                  oldType: \"TEXT\",\n                  oldMaxLength: 100);\n\n              migrationBuilder.AlterColumn<int>(\n                  name: \"Id\",\n                  table: \"Contributors\",\n                  type: \"int\",\n                  nullable: false,\n                  oldClrType: typeof(int),\n                  oldType: \"INTEGER\");\n          }\n          // For SQLite, no changes needed - it handles both SQLite and SQL Server type names\n      }\n\n      /// <inheritdoc />\n      protected override void Down(MigrationBuilder migrationBuilder)\n      {\n          if (migrationBuilder.ActiveProvider == \"Microsoft.EntityFrameworkCore.SqlServer\")\n          {\n              migrationBuilder.AlterColumn<int>(\n                  name: \"Status\",\n                  table: \"Contributors\",\n                  type: \"INTEGER\",\n                  nullable: false,\n                  oldClrType: typeof(int),\n                  oldType: \"int\");\n\n              migrationBuilder.AlterColumn<string>(\n                  name: \"PhoneNumber_Number\",\n                  table: \"Contributors\",\n                  type: \"TEXT\",\n                  nullable: true,\n                  oldClrType: typeof(string),\n                  oldType: \"nvarchar(max)\",\n                  oldNullable: true);\n\n              migrationBuilder.AlterColumn<string>(\n                  name: \"PhoneNumber_Extension\",\n                  table: \"Contributors\",\n                  type: \"TEXT\",\n                  nullable: true,\n                  oldClrType: typeof(string),\n                  oldType: \"nvarchar(max)\",\n                  oldNullable: true);\n\n              migrationBuilder.AlterColumn<string>(\n                  name: \"PhoneNumber_CountryCode\",\n                  table: \"Contributors\",\n                  type: \"TEXT\",\n                  nullable: true,\n                  oldClrType: typeof(string),\n                  oldType: \"nvarchar(max)\",\n                  oldNullable: true);\n\n              migrationBuilder.AlterColumn<string>(\n                  name: \"Name\",\n                  table: \"Contributors\",\n                  type: \"TEXT\",\n                  maxLength: 100,\n                  nullable: false,\n                  oldClrType: typeof(string),\n                  oldType: \"nvarchar(100)\",\n                  oldMaxLength: 100);\n\n              migrationBuilder.AlterColumn<int>(\n                  name: \"Id\",\n                  table: \"Contributors\",\n                  type: \"INTEGER\",\n                  nullable: false,\n                  oldClrType: typeof(int),\n                  oldType: \"int\");\n          }\n      }\n  }\n"
  },
  {
    "path": "src/Clean.Architecture.Infrastructure/Data/Migrations/AppDbContextModelSnapshot.cs",
    "content": "﻿// <auto-generated />\nusing Clean.Architecture.Infrastructure.Data;\nusing Microsoft.EntityFrameworkCore;\nusing Microsoft.EntityFrameworkCore.Infrastructure;\nusing Microsoft.EntityFrameworkCore.Metadata;\nusing Microsoft.EntityFrameworkCore.Storage.ValueConversion;\n\n#nullable disable\n\nnamespace Clean.Architecture.Infrastructure.Data.Migrations\n{\n    [DbContext(typeof(AppDbContext))]\n    partial class AppDbContextModelSnapshot : ModelSnapshot\n    {\n        protected override void BuildModel(ModelBuilder modelBuilder)\n        {\n#pragma warning disable 612, 618\n            modelBuilder\n                .HasAnnotation(\"ProductVersion\", \"10.0.0\")\n                .HasAnnotation(\"Relational:MaxIdentifierLength\", 128);\n\n            SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder);\n\n            modelBuilder.Entity(\"Clean.Architecture.Core.ContributorAggregate.Contributor\", b =>\n                {\n                    b.Property<int>(\"Id\")\n                        .HasColumnType(\"int\");\n\n                    b.Property<string>(\"Name\")\n                        .IsRequired()\n                        .HasMaxLength(100)\n                        .HasColumnType(\"nvarchar(100)\");\n\n                    b.Property<int>(\"Status\")\n                        .HasColumnType(\"int\");\n\n                    b.HasKey(\"Id\");\n\n                    b.ToTable(\"Contributors\");\n                });\n\n            modelBuilder.Entity(\"Clean.Architecture.Core.ContributorAggregate.Contributor\", b =>\n                {\n                    b.OwnsOne(\"Clean.Architecture.Core.ContributorAggregate.PhoneNumber\", \"PhoneNumber\", b1 =>\n                        {\n                            b1.Property<int>(\"ContributorId\")\n                                .HasColumnType(\"int\");\n\n                            b1.Property<string>(\"CountryCode\")\n                                .IsRequired()\n                                .HasColumnType(\"nvarchar(max)\");\n\n                            b1.Property<string>(\"Extension\")\n                                .HasColumnType(\"nvarchar(max)\");\n\n                            b1.Property<string>(\"Number\")\n                                .IsRequired()\n                                .HasColumnType(\"nvarchar(max)\");\n\n                            b1.HasKey(\"ContributorId\");\n\n                            b1.ToTable(\"Contributors\");\n\n                            b1.WithOwner()\n                                .HasForeignKey(\"ContributorId\");\n                        });\n\n                    b.Navigation(\"PhoneNumber\");\n                });\n#pragma warning restore 612, 618\n        }\n    }\n}\n"
  },
  {
    "path": "src/Clean.Architecture.Infrastructure/Data/Queries/FakeListContributorsQueryService.cs",
    "content": "﻿using Clean.Architecture.Core.ContributorAggregate;\nusing Clean.Architecture.UseCases.Contributors;\nusing Clean.Architecture.UseCases.Contributors.List;\n\nnamespace Clean.Architecture.Infrastructure.Data.Queries;\n\npublic class FakeListContributorsQueryService : IListContributorsQueryService\n{\n  public Task<UseCases.PagedResult<ContributorDto>> ListAsync(int page, int perPage)\n  {\n    var items = new List<ContributorDto>();\n    for (int i = 1; i <= 25; i++)\n    {\n      var phone = new PhoneNumber(\"+1\", \"555\", \"1234567\");\n      items.Add(new ContributorDto(ContributorId.From(i), ContributorName.From($\"Fake {i}\"), phone));\n    }\n\n    int totalPages = (int)Math.Ceiling(items.Count / (double)perPage);\n    var result = new UseCases.PagedResult<ContributorDto>(items, page, perPage, items.Count, totalPages);\n    return Task.FromResult(result);\n  }\n}\n"
  },
  {
    "path": "src/Clean.Architecture.Infrastructure/Data/Queries/ListContributorsQueryService.cs",
    "content": "﻿using Clean.Architecture.Core.ContributorAggregate;\nusing Clean.Architecture.UseCases.Contributors;\nusing Clean.Architecture.UseCases.Contributors.List;\n\nnamespace Clean.Architecture.Infrastructure.Data.Queries;\n\npublic class ListContributorsQueryService : IListContributorsQueryService\n{\n  // You can use EF, Dapper, SqlClient, etc. for queries\n  private readonly AppDbContext _db;\n\n  public ListContributorsQueryService(AppDbContext db)\n  {\n    _db = db;\n  }\n\n  public async Task<UseCases.PagedResult<ContributorDto>> ListAsync(int page, int perPage)\n  {\n    var items = await _db.Contributors.FromSqlRaw(\"SELECT Id, Name, PhoneNumber_CountryCode, PhoneNumber_Number, PhoneNumber_Extension FROM Contributors\") // don't fetch other big columns\n      .OrderBy(c => c.Id)\n      .Skip((page - 1) * perPage)\n      .Take(perPage)\n      .Select(c => new ContributorDto(c.Id, c.Name, c.PhoneNumber ?? PhoneNumber.Unknown))\n      .AsNoTracking()\n      .ToListAsync();\n\n    int totalCount = await _db.Contributors.CountAsync();\n    int totalPages = (int)Math.Ceiling(totalCount / (double)perPage);\n    var result = new UseCases.PagedResult<ContributorDto>(items, page, perPage, totalCount, totalPages);\n\n    return result;\n  }\n}\n"
  },
  {
    "path": "src/Clean.Architecture.Infrastructure/Data/SeedData.cs",
    "content": "﻿using Clean.Architecture.Core.ContributorAggregate;\n\nnamespace Clean.Architecture.Infrastructure.Data;\n\npublic static class SeedData\n{\n  public const int NUMBER_OF_CONTRIBUTORS = 27; // including the 2 below\n  public static readonly Contributor Contributor1 = new(ContributorName.From(\"Ardalis\"));\n  public static readonly Contributor Contributor2 = new(ContributorName.From(\"Ilyana\"));\n\n  public static async Task InitializeAsync(AppDbContext dbContext)\n  {\n    if (await dbContext.Contributors.AnyAsync()) return; // DB has been seeded\n\n    await PopulateTestDataAsync(dbContext);\n  }\n\n  public static async Task PopulateTestDataAsync(AppDbContext dbContext)\n  {\n    dbContext.Contributors.AddRange([Contributor1, Contributor2]);\n    await dbContext.SaveChangesAsync();\n\n    // add a bunch more contributors to support demonstrating paging\n    for (int i = 1; i <= NUMBER_OF_CONTRIBUTORS-2; i++)\n    {\n      dbContext.Contributors.Add(new Contributor(ContributorName.From($\"Contributor {i}\")));\n    }\n    await dbContext.SaveChangesAsync();\n  }\n}\n"
  },
  {
    "path": "src/Clean.Architecture.Infrastructure/Email/FakeEmailSender.cs",
    "content": "﻿using Clean.Architecture.Core.Interfaces;\n\nnamespace Clean.Architecture.Infrastructure.Email;\n\npublic class FakeEmailSender(ILogger<FakeEmailSender> logger) : IEmailSender\n{\n  private readonly ILogger<FakeEmailSender> _logger = logger;\n  public Task SendEmailAsync(string to, string from, string subject, string body)\n  {\n    _logger.LogInformation(\"Not actually sending an email to {to} from {from} with subject {subject}\", to, from, subject);\n    return Task.CompletedTask;\n  }\n}\n"
  },
  {
    "path": "src/Clean.Architecture.Infrastructure/Email/MailserverConfiguration.cs",
    "content": "﻿namespace Clean.Architecture.Infrastructure.Email;\n\npublic class MailserverConfiguration()\n{\n  public string Hostname { get; set; } = \"localhost\";\n  public int Port { get; set; } = 25;\n}\n"
  },
  {
    "path": "src/Clean.Architecture.Infrastructure/Email/MimeKitEmailSender.cs",
    "content": "﻿using Clean.Architecture.Core.Interfaces;\n\nnamespace Clean.Architecture.Infrastructure.Email;\n\npublic class MimeKitEmailSender(ILogger<MimeKitEmailSender> logger,\n  IOptions<MailserverConfiguration> mailserverOptions) : IEmailSender\n{\n  private readonly ILogger<MimeKitEmailSender> _logger = logger;\n  private readonly MailserverConfiguration _mailserverConfiguration = mailserverOptions.Value!;\n\n  public async Task SendEmailAsync(string to, string from, string subject, string body)\n  {\n    _logger.LogWarning(\"Sending email to {to} from {from} with subject {subject} using {type}.\", to, from, subject, this.ToString());\n\n    using var client = new MailKit.Net.Smtp.SmtpClient(); \n    await client.ConnectAsync(_mailserverConfiguration.Hostname, \n      _mailserverConfiguration.Port, false);\n    var message = new MimeMessage();\n    message.From.Add(new MailboxAddress(from, from));\n    message.To.Add(new MailboxAddress(to, to));\n    message.Subject = subject;\n    message.Body = new TextPart(\"plain\") { Text = body };\n\n    await client.SendAsync(message);\n\n    await client.DisconnectAsync(true, \n      new CancellationToken(canceled: true));\n  }\n}\n"
  },
  {
    "path": "src/Clean.Architecture.Infrastructure/GlobalUsings.cs",
    "content": "﻿global using System.Net.Mail;\nglobal using System.Reflection;\nglobal using Ardalis.GuardClauses;\nglobal using Ardalis.SharedKernel;\nglobal using Ardalis.Specification.EntityFrameworkCore;\nglobal using MailKit.Net.Smtp;\nglobal using Microsoft.EntityFrameworkCore;\nglobal using Microsoft.EntityFrameworkCore.Metadata.Builders;\nglobal using Microsoft.Extensions.Configuration;\nglobal using Microsoft.Extensions.DependencyInjection;\nglobal using Microsoft.Extensions.Logging;\nglobal using Microsoft.Extensions.Options;\nglobal using MimeKit;\n"
  },
  {
    "path": "src/Clean.Architecture.Infrastructure/InfrastructureServiceExtensions.cs",
    "content": "﻿using Clean.Architecture.Core.Interfaces;\nusing Clean.Architecture.Core.Services;\nusing Clean.Architecture.Infrastructure.Data;\nusing Clean.Architecture.Infrastructure.Data.Queries;\nusing Clean.Architecture.UseCases.Contributors.List;\n\nnamespace Clean.Architecture.Infrastructure;\npublic static class InfrastructureServiceExtensions\n{\n  public static IServiceCollection AddInfrastructureServices(\n    this IServiceCollection services,\n    ConfigurationManager config,\n    ILogger logger)\n  {\n    // Try to get connection strings in order of priority:\n    // 1. \"cleanarchitecture\" - provided by Aspire when using .WithReference(cleanArchDb)\n    // 2. \"DefaultConnection\" - SQL Server (Windows only by default, can be forced with USE_SQL_SERVER=true)\n    // 3. \"SqliteConnection\" - fallback to SQLite\n    bool isWindows = OperatingSystem.IsWindows();\n    bool forceSqlServer = Environment.GetEnvironmentVariable(\"USE_SQL_SERVER\") == \"true\";\n    \n    string? connectionString = config.GetConnectionString(\"cleanarchitecture\")\n                               ?? ((isWindows || forceSqlServer) ? config.GetConnectionString(\"DefaultConnection\") : null)\n                               ?? config.GetConnectionString(\"SqliteConnection\");\n    Guard.Against.Null(connectionString);\n\n    services.AddScoped<EventDispatchInterceptor>();\n    services.AddScoped<IDomainEventDispatcher, MediatorDomainEventDispatcher>();\n\n    services.AddDbContext<AppDbContext>((provider, options) =>\n    {\n      var eventDispatchInterceptor = provider.GetRequiredService<EventDispatchInterceptor>();\n      \n      // Use SQL Server if Aspire or DefaultConnection (on Windows or forced) is available, otherwise use SQLite\n      if (config.GetConnectionString(\"cleanarchitecture\") != null || \n          ((isWindows || forceSqlServer) && config.GetConnectionString(\"DefaultConnection\") != null))\n      {\n        options.UseSqlServer(connectionString);\n      }\n      else\n      {\n        options.UseSqlite(connectionString);\n      }\n      \n      options.AddInterceptors(eventDispatchInterceptor);\n    });\n\n    services.AddScoped(typeof(IRepository<>), typeof(EfRepository<>))\n           .AddScoped(typeof(IReadRepository<>), typeof(EfRepository<>))\n           .AddScoped<IListContributorsQueryService, ListContributorsQueryService>()\n           .AddScoped<IDeleteContributorService, DeleteContributorService>();\n\n    logger.LogInformation(\"{Project} services registered\", \"Infrastructure\");\n\n    return services;\n  }\n}\n"
  },
  {
    "path": "src/Clean.Architecture.Infrastructure/README.md",
    "content": "﻿## Infrastructure Project\n\nIn Clean Architecture, Infrastructure concerns are kept separate from the core business rules (or domain model in DDD).\n\nThe only project that should have code concerned with EF, Files, Email, Web Services, Azure/AWS/GCP, etc is Infrastructure.\n\nInfrastructure should depend on Core (and, optionally, Use Cases) where abstractions (interfaces) exist.\n\nInfrastructure classes implement interfaces found in the Core (Use Cases) project(s).\n\nThese implementations are wired up at startup using DI.\n\nIn this case using `Microsoft.Extensions.DependencyInjection` and extension methods defined in the project.\n\n## Database Support\n\nThis project supports both **SQL Server** and **SQLite**:\n\n- **SQL Server**: When running through .NET Aspire (AspireHost project), a SQL Server container is automatically provisioned and the connection string is provided via Aspire service discovery (using the \"DefaultConnection\" key).\n- **SQLite**: When running the Web project standalone, it uses the SQLite connection from appsettings.json as a fallback.\n\nThe `InfrastructureServiceExtensions.AddInfrastructureServices()` method automatically detects which connection string is available and configures the appropriate database provider.\n\nNeed help? Check out the larger sample here:\nhttps://github.com/ardalis/CleanArchitecture/tree/main/sample\n\nStill need help?\nContact us at https://nimblepros.com\n"
  },
  {
    "path": "src/Clean.Architecture.ServiceDefaults/Clean.Architecture.ServiceDefaults.csproj",
    "content": "<Project Sdk=\"Microsoft.NET.Sdk\">\n\n  <PropertyGroup>\n    <IsAspireSharedProject>true</IsAspireSharedProject>\n  </PropertyGroup>\n\n  <ItemGroup>\n    <FrameworkReference Include=\"Microsoft.AspNetCore.App\" />\n\n    <PackageReference Include=\"Microsoft.Extensions.Http.Resilience\" />\n    <PackageReference Include=\"Microsoft.Extensions.ServiceDiscovery\" />\n    <PackageReference Include=\"OpenTelemetry.Exporter.OpenTelemetryProtocol\" />\n    <PackageReference Include=\"OpenTelemetry.Extensions.Hosting\" />\n    <PackageReference Include=\"OpenTelemetry.Instrumentation.AspNetCore\" />\n    <PackageReference Include=\"OpenTelemetry.Instrumentation.Http\" />\n    <PackageReference Include=\"OpenTelemetry.Instrumentation.Runtime\" />\n  </ItemGroup>\n\n</Project>\n"
  },
  {
    "path": "src/Clean.Architecture.ServiceDefaults/Extensions.cs",
    "content": "﻿using Microsoft.AspNetCore.Builder;\nusing Microsoft.AspNetCore.Diagnostics.HealthChecks;\nusing Microsoft.Extensions.DependencyInjection;\nusing Microsoft.Extensions.Diagnostics.HealthChecks;\nusing Microsoft.Extensions.Logging;\nusing Microsoft.Extensions.ServiceDiscovery;\nusing OpenTelemetry;\nusing OpenTelemetry.Metrics;\nusing OpenTelemetry.Trace;\n\nnamespace Microsoft.Extensions.Hosting;\n\n// Adds common .NET Aspire services: service discovery, resilience, health checks, and OpenTelemetry.\n// This project should be referenced by each service project in your solution.\n// To learn more about using this project, see https://aka.ms/dotnet/aspire/service-defaults\npublic static class Extensions\n{\n  private const string HealthEndpointPath = \"/health\";\n  private const string AlivenessEndpointPath = \"/alive\";\n\n  public static TBuilder AddServiceDefaults<TBuilder>(this TBuilder builder) where TBuilder : IHostApplicationBuilder\n  {\n    builder.ConfigureOpenTelemetry();\n\n    builder.AddDefaultHealthChecks();\n\n    builder.Services.AddServiceDiscovery();\n\n    builder.Services.ConfigureHttpClientDefaults(http =>\n    {\n      // Turn on resilience by default\n      http.AddStandardResilienceHandler();\n\n      // Turn on service discovery by default\n      http.AddServiceDiscovery();\n    });\n\n    // Uncomment the following to restrict the allowed schemes for service discovery.\n    // builder.Services.Configure<ServiceDiscoveryOptions>(options =>\n    // {\n    //     options.AllowedSchemes = [\"https\"];\n    // });\n\n    return builder;\n  }\n\n  public static TBuilder ConfigureOpenTelemetry<TBuilder>(this TBuilder builder) where TBuilder : IHostApplicationBuilder\n  {\n    builder.Logging.AddOpenTelemetry(logging =>\n    {\n      logging.IncludeFormattedMessage = true;\n      logging.IncludeScopes = true;\n    });\n\n    builder.Services.AddOpenTelemetry()\n        .WithMetrics(metrics =>\n        {\n          metrics.AddAspNetCoreInstrumentation()\n                  .AddHttpClientInstrumentation()\n                  .AddRuntimeInstrumentation();\n        })\n        .WithTracing(tracing =>\n        {\n          tracing.AddSource(builder.Environment.ApplicationName)\n                  .AddAspNetCoreInstrumentation(tracing =>\n                      // Exclude health check requests from tracing\n                      tracing.Filter = context =>\n                          !context.Request.Path.StartsWithSegments(HealthEndpointPath)\n                          && !context.Request.Path.StartsWithSegments(AlivenessEndpointPath)\n                  )\n                  // Uncomment the following line to enable gRPC instrumentation (requires the OpenTelemetry.Instrumentation.GrpcNetClient package)\n                  //.AddGrpcClientInstrumentation()\n                  .AddHttpClientInstrumentation();\n        });\n\n    builder.AddOpenTelemetryExporters();\n\n    return builder;\n  }\n\n  private static TBuilder AddOpenTelemetryExporters<TBuilder>(this TBuilder builder) where TBuilder : IHostApplicationBuilder\n  {\n    var useOtlpExporter = !string.IsNullOrWhiteSpace(builder.Configuration[\"OTEL_EXPORTER_OTLP_ENDPOINT\"]);\n\n    if (useOtlpExporter)\n    {\n      builder.Services.AddOpenTelemetry().UseOtlpExporter();\n    }\n\n    // Uncomment the following lines to enable the Azure Monitor exporter (requires the Azure.Monitor.OpenTelemetry.AspNetCore package)\n    //if (!string.IsNullOrEmpty(builder.Configuration[\"APPLICATIONINSIGHTS_CONNECTION_STRING\"]))\n    //{\n    //    builder.Services.AddOpenTelemetry()\n    //       .UseAzureMonitor();\n    //}\n\n    return builder;\n  }\n\n  public static TBuilder AddDefaultHealthChecks<TBuilder>(this TBuilder builder) where TBuilder : IHostApplicationBuilder\n  {\n    builder.Services.AddHealthChecks()\n        // Add a default liveness check to ensure app is responsive\n        .AddCheck(\"self\", () => HealthCheckResult.Healthy(), [\"live\"]);\n\n    return builder;\n  }\n\n  public static WebApplication MapDefaultEndpoints(this WebApplication app)\n  {\n    // Adding health checks endpoints to applications in non-development environments has security implications.\n    // See https://aka.ms/dotnet/aspire/healthchecks for details before enabling these endpoints in non-development environments.\n    if (app.Environment.IsDevelopment())\n    {\n      // All health checks must pass for app to be considered ready to accept traffic after starting\n      app.MapHealthChecks(HealthEndpointPath);\n\n      // Only health checks tagged with the \"live\" tag must pass for app to be considered alive\n      app.MapHealthChecks(AlivenessEndpointPath, new HealthCheckOptions\n      {\n        Predicate = r => r.Tags.Contains(\"live\")\n      });\n    }\n\n    return app;\n  }\n}\n"
  },
  {
    "path": "src/Clean.Architecture.UseCases/Clean.Architecture.UseCases.csproj",
    "content": "﻿<Project Sdk=\"Microsoft.NET.Sdk\">\n\n  <ItemGroup>\n    <PackageReference Include=\"Ardalis.Result\" />\n  </ItemGroup>\n\n  <ItemGroup>\n    <ProjectReference Include=\"..\\Clean.Architecture.Core\\Clean.Architecture.Core.csproj\" />\n  </ItemGroup>\n\n</Project>\n"
  },
  {
    "path": "src/Clean.Architecture.UseCases/Constants.cs",
    "content": "﻿namespace Clean.Architecture.UseCases;\n\npublic class Constants\n{\n  public const int DEFAULT_PAGE_SIZE = 10;\n  public const int MAX_PAGE_SIZE = 100;\n}\n"
  },
  {
    "path": "src/Clean.Architecture.UseCases/Contributors/ContributorDTO.cs",
    "content": "﻿using Clean.Architecture.Core.ContributorAggregate;\n\nnamespace Clean.Architecture.UseCases.Contributors;\npublic record ContributorDto(ContributorId Id, ContributorName Name, PhoneNumber PhoneNumber);\n"
  },
  {
    "path": "src/Clean.Architecture.UseCases/Contributors/Create/CreateContributorCommand.cs",
    "content": "﻿using Clean.Architecture.Core.ContributorAggregate;\n\nnamespace Clean.Architecture.UseCases.Contributors.Create;\n\n/// <summary>\n/// Create a new Contributor.\n/// </summary>\n/// <param name=\"Name\"></param>\npublic record CreateContributorCommand(ContributorName Name, string? PhoneNumber) : ICommand<Result<ContributorId>>;\n"
  },
  {
    "path": "src/Clean.Architecture.UseCases/Contributors/Create/CreateContributorHandler.cs",
    "content": "﻿using Clean.Architecture.Core.ContributorAggregate;\n\nnamespace Clean.Architecture.UseCases.Contributors.Create;\n\npublic class CreateContributorHandler(IRepository<Contributor> _repository)\n  : ICommandHandler<CreateContributorCommand, Result<ContributorId>>\n{\n  public async ValueTask<Result<ContributorId>> Handle(CreateContributorCommand command,\n    CancellationToken cancellationToken)\n  {\n    var newContributor = new Contributor(command.Name);\n    if (!string.IsNullOrEmpty(command.PhoneNumber))\n    {\n      var phoneNumber = new PhoneNumber(\"+1\", command.PhoneNumber, String.Empty);\n      newContributor.UpdatePhoneNumber(phoneNumber);\n    }\n    var createdItem = await _repository.AddAsync(newContributor, cancellationToken);\n\n    return createdItem.Id;\n  }\n}\n"
  },
  {
    "path": "src/Clean.Architecture.UseCases/Contributors/Delete/DeleteContributorCommand.cs",
    "content": "﻿using Clean.Architecture.Core.ContributorAggregate;\n\nnamespace Clean.Architecture.UseCases.Contributors.Delete;\n\npublic record DeleteContributorCommand(ContributorId ContributorId) : ICommand<Result>;\n"
  },
  {
    "path": "src/Clean.Architecture.UseCases/Contributors/Delete/DeleteContributorHandler.cs",
    "content": "﻿using Clean.Architecture.Core.Interfaces;\n\nnamespace Clean.Architecture.UseCases.Contributors.Delete;\n\npublic class DeleteContributorHandler(IDeleteContributorService _deleteContributorService)\n  : ICommandHandler<DeleteContributorCommand, Result>\n{\n  public async ValueTask<Result> Handle(DeleteContributorCommand request, CancellationToken cancellationToken) =>\n    // This Approach: Keep Domain Events in the Domain Model / Core project; this becomes a pass-through\n    // This is @ardalis's preferred approach\n    await _deleteContributorService.DeleteContributor(request.ContributorId);\n\n    // Another Approach: Do the real work here including dispatching domain events - change the event from internal to public\n    // @ardalis prefers using the service above so that **domain** event behavior remains in the **domain model** (core project)\n    // var aggregateToDelete = await _repository.GetByIdAsync(request.ContributorId);\n    // if (aggregateToDelete == null) return Result.NotFound();\n    // await _repository.DeleteAsync(aggregateToDelete);\n    // var domainEvent = new ContributorDeletedEvent(request.ContributorId);\n    // await _mediator.Publish(domainEvent);// return Result.Success();\n}\n"
  },
  {
    "path": "src/Clean.Architecture.UseCases/Contributors/Get/GetContributorHandler.cs",
    "content": "﻿using Clean.Architecture.Core.ContributorAggregate;\nusing Clean.Architecture.Core.ContributorAggregate.Specifications;\n\nnamespace Clean.Architecture.UseCases.Contributors.Get;\n\n/// <summary>\n/// Queries don't necessarily need to use repository methods, but they can if it's convenient\n/// </summary>\npublic class GetContributorHandler(IReadRepository<Contributor> _repository)\n  : IQueryHandler<GetContributorQuery, Result<ContributorDto>>\n{\n  public async ValueTask<Result<ContributorDto>> Handle(GetContributorQuery request, CancellationToken cancellationToken)\n  {\n    var spec = new ContributorByIdSpec(request.ContributorId);\n    var entity = await _repository.FirstOrDefaultAsync(spec, cancellationToken);\n    if (entity == null) return Result.NotFound();\n\n    return new ContributorDto(entity.Id, entity.Name, entity.PhoneNumber ?? PhoneNumber.Unknown);\n  }\n}\n"
  },
  {
    "path": "src/Clean.Architecture.UseCases/Contributors/Get/GetContributorQuery.cs",
    "content": "﻿using Clean.Architecture.Core.ContributorAggregate;\n\nnamespace Clean.Architecture.UseCases.Contributors.Get;\n\npublic record GetContributorQuery(ContributorId ContributorId) : IQuery<Result<ContributorDto>>;\n"
  },
  {
    "path": "src/Clean.Architecture.UseCases/Contributors/List/IListContributorsQueryService.cs",
    "content": "﻿namespace Clean.Architecture.UseCases.Contributors.List;\n\n/// <summary>\n/// Represents a service that will actually fetch the necessary data\n/// Typically implemented in Infrastructure\n/// </summary>\npublic interface IListContributorsQueryService\n{\n  Task<UseCases.PagedResult<ContributorDto>> ListAsync(int page, int perPage);\n}\n"
  },
  {
    "path": "src/Clean.Architecture.UseCases/Contributors/List/ListContributorsHandler.cs",
    "content": "﻿namespace Clean.Architecture.UseCases.Contributors.List;\n\npublic class ListContributorsHandler : IQueryHandler<ListContributorsQuery, Result<PagedResult<ContributorDto>>>\n{\n  private readonly IListContributorsQueryService _query;\n\n  public ListContributorsHandler(IListContributorsQueryService query)\n  {\n    _query = query;\n  }\n\n  public async ValueTask<Result<PagedResult<ContributorDto>>> Handle(ListContributorsQuery request,\n                                                                     CancellationToken cancellationToken)\n  {\n\n    var result = await _query.ListAsync(request.Page ?? 1, request.PerPage ?? Constants.DEFAULT_PAGE_SIZE);\n\n    return Result.Success(result);\n  }\n}\n"
  },
  {
    "path": "src/Clean.Architecture.UseCases/Contributors/List/ListContributorsQuery.cs",
    "content": "﻿namespace Clean.Architecture.UseCases.Contributors.List;\n\npublic record ListContributorsQuery(int? Page = 1, int? PerPage = Constants.DEFAULT_PAGE_SIZE)\n  : IQuery<Result<PagedResult<ContributorDto>>>;\n"
  },
  {
    "path": "src/Clean.Architecture.UseCases/Contributors/Update/UpdateContributorCommand.cs",
    "content": "﻿using Clean.Architecture.Core.ContributorAggregate;\n\nnamespace Clean.Architecture.UseCases.Contributors.Update;\n\npublic record UpdateContributorCommand(ContributorId ContributorId, ContributorName NewName) : ICommand<Result<ContributorDto>>;\n"
  },
  {
    "path": "src/Clean.Architecture.UseCases/Contributors/Update/UpdateContributorHandler.cs",
    "content": "﻿using Clean.Architecture.Core.ContributorAggregate;\n\nnamespace Clean.Architecture.UseCases.Contributors.Update;\n\npublic class UpdateContributorHandler(IRepository<Contributor> _repository)\n  : ICommandHandler<UpdateContributorCommand, Result<ContributorDto>>\n{\n  public async ValueTask<Result<ContributorDto>> Handle(UpdateContributorCommand command, \n    CancellationToken ct)\n  {\n    var existingContributor = await _repository.GetByIdAsync(command.ContributorId, ct);\n    if (existingContributor == null)\n    {\n      return Result.NotFound();\n    }\n\n    existingContributor.UpdateName(command.NewName);\n\n    await _repository.UpdateAsync(existingContributor, ct);\n\n    return new ContributorDto(existingContributor.Id,\n      existingContributor.Name, existingContributor.PhoneNumber ?? PhoneNumber.Unknown);\n  }\n}\n"
  },
  {
    "path": "src/Clean.Architecture.UseCases/GlobalUsings.cs",
    "content": "﻿global using Ardalis.Result;\nglobal using Ardalis.SharedKernel;\nglobal using Mediator;\n"
  },
  {
    "path": "src/Clean.Architecture.UseCases/PagedResult.cs",
    "content": "﻿namespace Clean.Architecture.UseCases;\n\npublic record PagedResult<T>(\n  IReadOnlyList<T> Items,\n  int Page,\n  int PerPage,\n  int TotalCount,\n  int TotalPages);\n"
  },
  {
    "path": "src/Clean.Architecture.UseCases/README.md",
    "content": "﻿## Use Cases Project\n\nIn Clean Architecture, the Use Cases (or Application Services) project is a relatively thin layer that wraps the domain model.\n\nUse Cases are typically organized by feature. These may be simple CRUD operations or much more complex activities.\n\nUse Cases should not depend directly on infrastructure concerns, making them simple to unit test in most cases.\n\nUse Cases are often grouped into Commands and Queries, following CQRS.\n\nQueries fetch data but do not mutate state. Commands mutate state but do not return data (other than perhaps an acknowledgment or ID).\n\nHaving Use Cases as a separate project can reduce the amount of logic in UI and Infrastructure projects.\n\nUsing Use Case handlers combined with behavior can consolidate cross-cutting concerns like logging, validation, and error handling.\nSee: https://www.youtube.com/watch?v=vagyJdrWLr0\n\nNeed help? Check out the sample here:\nhttps://github.com/ardalis/CleanArchitecture/tree/main/sample\n\nStill need help?\nContact us at https://nimblepros.com\n"
  },
  {
    "path": "src/Clean.Architecture.Web/Clean.Architecture.Web.csproj",
    "content": "﻿<Project Sdk=\"Microsoft.NET.Sdk.Web\">\n  <Sdk Name=\"Microsoft.Build.CentralPackageVersions\" Version=\"2.1.3\" />\n\n  <PropertyGroup>\n    <PreserveCompilationContext>true</PreserveCompilationContext>\n    <OutputType>Exe</OutputType>\n    <WebProjectMode>true</WebProjectMode>\n    <GenerateDocumentationFile>True</GenerateDocumentationFile>\n  </PropertyGroup>\n\n  <ItemGroup>\n    <PackageReference Include=\"Ardalis.ListStartupServices\" />\n    <PackageReference Include=\"Ardalis.Result\" />\n    <PackageReference Include=\"Ardalis.Result.AspNetCore\" />\n    <PackageReference Include=\"FastEndpoints\" />\n    <PackageReference Include=\"FastEndpoints.Swagger\" />\n    <PackageReference Include=\"Mediator.SourceGenerator\">\n      <PrivateAssets>all</PrivateAssets>\n      <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>\n    </PackageReference>\n    <PackageReference Include=\"Microsoft.EntityFrameworkCore.Design\" />\n    <PackageReference Include=\"Scalar.AspNetCore\" />\n    <PackageReference Include=\"Serilog.AspNetCore\" />\n  </ItemGroup>\n\n  <ItemGroup>\n    <ProjectReference Include=\"..\\Clean.Architecture.Infrastructure\\Clean.Architecture.Infrastructure.csproj\" />\n    <ProjectReference Include=\"..\\Clean.Architecture.UseCases\\Clean.Architecture.UseCases.csproj\" />\n    <ProjectReference Include=\"..\\Clean.Architecture.ServiceDefaults\\Clean.Architecture.ServiceDefaults.csproj\" />\n  </ItemGroup>\n\n</Project>\n"
  },
  {
    "path": "src/Clean.Architecture.Web/Configurations/LoggerConfigs.cs",
    "content": "﻿using Serilog;\n\nnamespace Clean.Architecture.Web.Configurations;\n\npublic static class LoggerConfigs\n{\n  public static WebApplicationBuilder AddLoggerConfigs(this WebApplicationBuilder builder)\n  {\n    // Add Serilog as an additional logging provider alongside OpenTelemetry\n    // This allows both Serilog (for console/file) and OpenTelemetry (for Aspire) to work together\n    builder.Logging.AddSerilog(new LoggerConfiguration()\n      .ReadFrom.Configuration(builder.Configuration)\n      .Enrich.FromLogContext()\n      .Enrich.WithProperty(\"Application\", builder.Environment.ApplicationName)\n      .WriteTo.Console()\n      .CreateLogger());\n\n    return builder;\n  }\n}\n"
  },
  {
    "path": "src/Clean.Architecture.Web/Configurations/MediatorConfig.cs",
    "content": "﻿using Ardalis.SharedKernel;\nusing Clean.Architecture.Core.ContributorAggregate;\nusing Clean.Architecture.Infrastructure;\nusing Clean.Architecture.UseCases.Contributors.Create;\n\nnamespace Clean.Architecture.Web.Configurations;\n\npublic static class MediatorConfig\n{\n  // Should be called from ServiceConfigs.cs, not Program.cs\n  public static IServiceCollection AddMediatorSourceGen(this IServiceCollection services,\n    Microsoft.Extensions.Logging.ILogger logger)\n  {\n    logger.LogInformation(\"Registering Mediator SourceGen and Behaviors\");\n    services.AddMediator(options =>\n    {\n      // Lifetime: Singleton is fastest per docs; Scoped/Transient also supported.\n      options.ServiceLifetime = ServiceLifetime.Scoped;\n\n      // Supply any TYPE from each assembly you want scanned (the generator finds the assembly from the type)\n      options.Assemblies =\n      [\n        typeof(Contributor),                       // Core\n        typeof(CreateContributorCommand),         // UseCases\n        typeof(InfrastructureServiceExtensions), // Infrastructure\n        typeof(MediatorConfig)                  // Web\n      ];\n\n      // Register pipeline behaviors here (order matters)\n      options.PipelineBehaviors =\n      [\n        typeof(LoggingBehavior<,>)\n      ];\n\n      // If you have stream behaviors:\n      // options.StreamPipelineBehaviors = [ typeof(YourStreamBehavior<,>) ];\n    });\n\n    // Alternative: register behaviors via DI yourself (useful if not doing AOT):\n    // services.AddScoped(typeof(IPipelineBehavior<,>), typeof(LoggingBehavior<,>));\n    // services.AddScoped(typeof(IPipelineBehavior<,>), typeof(CachingBehavior<,>));\n\n    return services;\n  }\n}\n"
  },
  {
    "path": "src/Clean.Architecture.Web/Configurations/MiddlewareConfig.cs",
    "content": "﻿using Ardalis.ListStartupServices;\nusing Clean.Architecture.Infrastructure.Data;\nusing Scalar.AspNetCore;\n\nnamespace Clean.Architecture.Web.Configurations;\n\npublic static class MiddlewareConfig\n{\n  public static async Task<IApplicationBuilder> UseAppMiddlewareAndSeedDatabase(this WebApplication app)\n  {\n    if (app.Environment.IsDevelopment())\n    {\n      app.UseDeveloperExceptionPage();\n      app.UseShowAllServicesMiddleware(); // see https://github.com/ardalis/AspNetCoreStartupServices\n    }\n    else\n    {   \n      app.UseDefaultExceptionHandler(); // from FastEndpoints\n      app.UseHsts();\n    }\n\n    app.UseFastEndpoints();\n\n    if (app.Environment.IsDevelopment())\n    {\n      app.UseSwaggerGen(options =>\n      {\n        options.Path = \"/openapi/{documentName}.json\";\n      },\n      settings =>\n      {\n        settings.Path = \"/swagger\";\n        settings.DocumentPath = \"/openapi/{documentName}.json\";\n      });\n  \n      app.MapScalarApiReference(options =>\n      {\n        options.WithTitle(\"Clean Architecture API\");\n        options.WithOpenApiRoutePattern(\"/openapi/{documentName}.json\");\n      });\n    }\n\n    app.UseHttpsRedirection(); // Note this will drop Authorization headers\n\n    // Run migrations and seed in Development or when explicitly requested via environment variable\n    var shouldMigrate = app.Environment.IsDevelopment() || \n                        app.Configuration.GetValue<bool>(\"Database:ApplyMigrationsOnStartup\");\n    \n    if (shouldMigrate)\n    {\n      await MigrateDatabaseAsync(app);\n      await SeedDatabaseAsync(app);\n    }\n\n    return app;\n  }\n\n  static async Task MigrateDatabaseAsync(WebApplication app)\n  {\n    using var scope = app.Services.CreateScope();\n    var services = scope.ServiceProvider;\n    var logger = services.GetRequiredService<ILogger<Program>>();\n\n    try\n    {\n      logger.LogInformation(\"Applying database migrations...\");\n      var context = services.GetRequiredService<AppDbContext>();\n      \n      // For SQLite, use EnsureCreated instead of migrations (common for dev/local scenarios)\n      // For SQL Server, use migrations (production scenario)\n      if (context.Database.IsSqlite())\n      {\n        await context.Database.EnsureCreatedAsync();\n        logger.LogInformation(\"SQLite database created successfully\");\n      }\n      else\n      {\n        await context.Database.MigrateAsync();\n        logger.LogInformation(\"Database migrations applied successfully\");\n      }\n    }\n    catch (Exception ex)\n    {\n      logger.LogError(ex, \"An error occurred migrating the DB. {exceptionMessage}\", ex.Message);\n      throw; // Re-throw to make startup fail if migrations fail\n    }\n  }\n\n  static async Task SeedDatabaseAsync(WebApplication app)\n  {\n    using var scope = app.Services.CreateScope();\n    var services = scope.ServiceProvider;\n    var logger = services.GetRequiredService<ILogger<Program>>();\n\n    try\n    {\n      logger.LogInformation(\"Seeding database...\");\n      var context = services.GetRequiredService<AppDbContext>();\n      await SeedData.InitializeAsync(context);\n      logger.LogInformation(\"Database seeded successfully\");\n    }\n    catch (Exception ex)\n    {\n      logger.LogError(ex, \"An error occurred seeding the DB. {exceptionMessage}\", ex.Message);\n      // Don't re-throw for seeding errors - it's not critical\n    }\n  }\n}\n"
  },
  {
    "path": "src/Clean.Architecture.Web/Configurations/OptionConfigs.cs",
    "content": "﻿using Ardalis.ListStartupServices;\nusing Clean.Architecture.Infrastructure.Email;\n\nnamespace Clean.Architecture.Web.Configurations;\n\npublic static class OptionConfigs\n{\n  public static IServiceCollection AddOptionConfigs(this IServiceCollection services,\n                                                    IConfiguration configuration,\n                                                    Microsoft.Extensions.Logging.ILogger logger,\n                                                    WebApplicationBuilder builder)\n  {\n    services.Configure<MailserverConfiguration>(configuration.GetSection(\"Mailserver\"))\n    // Configure Web Behavior\n    .Configure<CookiePolicyOptions>(options =>\n    {\n      options.CheckConsentNeeded = context => true;\n      options.MinimumSameSitePolicy = SameSiteMode.None;\n    });\n\n    if (builder.Environment.IsDevelopment())\n    {\n      // add list services for diagnostic purposes - see https://github.com/ardalis/AspNetCoreStartupServices\n      services.Configure<ServiceConfig>(config =>\n      {\n        config.Services = new List<ServiceDescriptor>(builder.Services);\n\n        // optional - default path to view services is /listallservices - recommended to choose your own path\n        config.Path = \"/listservices\";\n      });\n    }\n\n    logger.LogInformation(\"{Project} were configured\", \"Options\");\n\n    return services;\n  }\n}\n"
  },
  {
    "path": "src/Clean.Architecture.Web/Configurations/ServiceConfigs.cs",
    "content": "﻿using Clean.Architecture.Core.Interfaces;\nusing Clean.Architecture.Infrastructure;\nusing Clean.Architecture.Infrastructure.Email;\n\nnamespace Clean.Architecture.Web.Configurations;\n\npublic static class ServiceConfigs\n{\n  public static IServiceCollection AddServiceConfigs(this IServiceCollection services, Microsoft.Extensions.Logging.ILogger logger, WebApplicationBuilder builder)\n  {\n    services.AddInfrastructureServices(builder.Configuration, logger)\n            .AddMediatorSourceGen(logger);\n\n    if (builder.Environment.IsDevelopment())\n    {\n      // Use a local test email server - configured in Aspire\n      // See: https://ardalis.com/configuring-a-local-test-email-server/\n      services.AddScoped<IEmailSender, MimeKitEmailSender>();\n\n      // Otherwise use this:\n      //builder.Services.AddScoped<IEmailSender, FakeEmailSender>();\n    }\n    else\n    {\n      services.AddScoped<IEmailSender, MimeKitEmailSender>();\n    }\n\n    logger.LogInformation(\"{Project} services registered\", \"Mediator Source Generator and Email Sender\");\n\n    return services;\n  }\n\n\n}\n"
  },
  {
    "path": "src/Clean.Architecture.Web/Contributors/ContributorRecord.cs",
    "content": "﻿namespace Clean.Architecture.Web.Contributors;\n\npublic record ContributorRecord(int Id, string Name, string? PhoneNumber);\n"
  },
  {
    "path": "src/Clean.Architecture.Web/Contributors/Create.cs",
    "content": "﻿using System.ComponentModel.DataAnnotations;\nusing Clean.Architecture.Core.ContributorAggregate;\nusing Clean.Architecture.UseCases.Contributors.Create;\nusing Clean.Architecture.Web.Extensions;\nusing FluentValidation;\nusing Microsoft.AspNetCore.Http.HttpResults;\n\nnamespace Clean.Architecture.Web.Contributors;\n\n// This shows an example of having all related types in one file for simplicity.\n// Fast-Endpoints generally uses one file per class for larger projects, which\n// is the recommended approach. More files, but fewer merge conflicts and easier to \n// see what changed in a given commit or PR.\n\npublic class Create(IMediator mediator)\n  : Endpoint<CreateContributorRequest,\n          Results<Created<CreateContributorResponse>,\n                          ValidationProblem,\n                          ProblemHttpResult>>\n{\n  private readonly IMediator _mediator = mediator;\n\n  public override void Configure()\n  {\n    Post(CreateContributorRequest.Route);\n    AllowAnonymous();\n    Summary(s =>\n    {\n      s.Summary = \"Create a new contributor\";\n      s.Description = \"Creates a new contributor with the provided name. The contributor name must be between 2 and 100 characters long.\";\n      s.ExampleRequest = new CreateContributorRequest { Name = \"John Doe\" };\n      s.ResponseExamples[201] = new CreateContributorResponse(1, \"John Doe\");\n\n      // Document possible responses\n      s.Responses[201] = \"Contributor created successfully\";\n      s.Responses[400] = \"Invalid input data - validation errors\";\n      s.Responses[500] = \"Internal server error\";\n    });\n\n    // Add tags for API grouping\n    Tags(\"Contributors\");\n\n    // Add additional metadata\n    Description(builder => builder\n      .Accepts<CreateContributorRequest>(\"application/json\")\n      .Produces<CreateContributorResponse>(201, \"application/json\")\n      .ProducesProblem(400)\n      .ProducesProblem(500));\n  }\n\n  public override async Task<Results<Created<CreateContributorResponse>, ValidationProblem, ProblemHttpResult>>\n    ExecuteAsync(CreateContributorRequest request, CancellationToken cancellationToken)\n  {\n    var result = await _mediator.Send(new CreateContributorCommand(ContributorName.From(request.Name!), request.PhoneNumber));\n\n    return result.ToCreatedResult(\n      id => $\"/Contributors/{id}\",\n      id => new CreateContributorResponse(id.Value, request.Name!));\n  }\n}\n\npublic class CreateContributorRequest\n{\n  public const string Route = \"/Contributors\";\n\n  [Required]\n  public string Name { get; set; } = String.Empty;\n  public string? PhoneNumber { get; set; } = null;\n}\n\npublic class CreateContributorValidator : Validator<CreateContributorRequest>\n{\n  public CreateContributorValidator()\n  {\n    RuleFor(x => x.Name)\n      .NotEmpty()\n      .WithMessage(\"Name is required.\")\n      .MinimumLength(2)\n      .MaximumLength(ContributorName.MaxLength);\n  }\n}\n\npublic class CreateContributorResponse(int id, string name)\n{\n  public int Id { get; set; } = id;\n  public string Name { get; set; } = name;\n}\n"
  },
  {
    "path": "src/Clean.Architecture.Web/Contributors/Delete.DeleteContributorRequest.cs",
    "content": "﻿namespace Clean.Architecture.Web.Contributors;\n\npublic record DeleteContributorRequest\n{\n  public const string Route = \"/Contributors/{ContributorId:int}\";\n  public static string BuildRoute(int contributorId) => Route.Replace(\"{ContributorId:int}\", contributorId.ToString());\n\n  public int ContributorId { get; set; }\n}\n"
  },
  {
    "path": "src/Clean.Architecture.Web/Contributors/Delete.DeleteContributorValidator.cs",
    "content": "﻿using FluentValidation;\n\nnamespace Clean.Architecture.Web.Contributors;\n\n/// <summary>\n/// See: https://fast-endpoints.com/docs/validation\n/// </summary>\npublic class DeleteContributorValidator : Validator<DeleteContributorRequest>\n{\n  public DeleteContributorValidator()\n  {\n    RuleFor(x => x.ContributorId)\n      .GreaterThan(0);\n  }\n}\n"
  },
  {
    "path": "src/Clean.Architecture.Web/Contributors/Delete.cs",
    "content": "﻿using Clean.Architecture.Core.ContributorAggregate;\nusing Clean.Architecture.UseCases.Contributors.Delete;\nusing Clean.Architecture.Web.Extensions;\nusing Microsoft.AspNetCore.Http.HttpResults;\n\nnamespace Clean.Architecture.Web.Contributors;\n\npublic class Delete\n  : Endpoint<DeleteContributorRequest,\n             Results<NoContent,\n                     NotFound,\n                     ProblemHttpResult>>\n{\n  private readonly IMediator _mediator;\n  public Delete(IMediator mediator) => _mediator = mediator;\n\n  public override void Configure()\n  {\n    Delete(DeleteContributorRequest.Route);\n    AllowAnonymous();\n    Summary(s =>\n    {\n      s.Summary = \"Delete a contributor\";\n      s.Description = \"Deletes an existing contributor by ID. This action cannot be undone.\";\n      s.ExampleRequest = new DeleteContributorRequest { ContributorId = 1 };\n\n      // Document possible responses\n      s.Responses[204] = \"Contributor deleted successfully\";\n      s.Responses[404] = \"Contributor not found\";\n      s.Responses[400] = \"Invalid request or deletion failed\";\n    });\n\n    // Add tags for API grouping\n    Tags(\"Contributors\");\n\n    // Add additional metadata\n    Description(builder => builder\n      .Accepts<DeleteContributorRequest>()\n      .Produces(204)\n      .ProducesProblem(404)\n      .ProducesProblem(400));\n  }\n\n  public override async Task<Results<NoContent, NotFound, ProblemHttpResult>>\n    ExecuteAsync(DeleteContributorRequest req, CancellationToken ct)\n  {\n    var cmd = new DeleteContributorCommand(ContributorId.From(req.ContributorId));\n    var result = await _mediator.Send(cmd, ct);\n\n    return result.ToDeleteResult();\n  }\n}\n"
  },
  {
    "path": "src/Clean.Architecture.Web/Contributors/GetById.GetContributorByIdRequest.cs",
    "content": "﻿namespace Clean.Architecture.Web.Contributors;\n\npublic class GetContributorByIdRequest\n{\n  public const string Route = \"/Contributors/{ContributorId:int}\";\n  public static string BuildRoute(int contributorId) => Route.Replace(\"{ContributorId:int}\", contributorId.ToString());\n\n  public int ContributorId { get; set; }\n}\n"
  },
  {
    "path": "src/Clean.Architecture.Web/Contributors/GetById.GetContributorValidator.cs",
    "content": "﻿using FastEndpoints;\nusing FluentValidation;\n\nnamespace Clean.Architecture.Web.Contributors;\n\n/// <summary>\n/// See: https://fast-endpoints.com/docs/validation\n/// </summary>\npublic class GetContributorValidator : Validator<GetContributorByIdRequest>\n{\n  public GetContributorValidator()\n  {\n    RuleFor(x => x.ContributorId)\n      .GreaterThan(0);\n  }\n}\n"
  },
  {
    "path": "src/Clean.Architecture.Web/Contributors/GetById.cs",
    "content": "﻿using Clean.Architecture.Core.ContributorAggregate;\nusing Clean.Architecture.UseCases.Contributors;\nusing Clean.Architecture.UseCases.Contributors.Get;\nusing Clean.Architecture.Web.Extensions;\nusing Microsoft.AspNetCore.Http.HttpResults;\n\nnamespace Clean.Architecture.Web.Contributors;\n\npublic class GetById(IMediator mediator)\n  : Endpoint<GetContributorByIdRequest,\n             Results<Ok<ContributorRecord>,\n                     NotFound,\n                     ProblemHttpResult>,\n             GetContributorByIdMapper>\n{\n  public override void Configure()\n  {\n    Get(GetContributorByIdRequest.Route);\n    AllowAnonymous();\n\n    // Optional: document statuses for Swagger\n    Summary(s =>\n    {\n      s.Summary = \"Get a contributor by ID\";\n      s.Description = \"Retrieves a specific contributor by their unique identifier. Returns detailed contributor information including ID and name.\";\n      s.ExampleRequest = new GetContributorByIdRequest { ContributorId = 1 };\n      s.ResponseExamples[200] = new ContributorRecord(1, \"John Doe\", \"+1 555-555-5555\");\n\n      // Document possible responses\n      s.Responses[200] = \"Contributor found and returned successfully\";\n      s.Responses[404] = \"Contributor with specified ID not found\";\n    });\n\n    // Add tags for API grouping\n    Tags(\"Contributors\");\n\n    // Add additional metadata\n    Description(builder => builder\n      .Accepts<GetContributorByIdRequest>()\n      .Produces<ContributorRecord>(200, \"application/json\")\n      .ProducesProblem(404));\n  }\n\n  public override async Task<Results<Ok<ContributorRecord>, NotFound, ProblemHttpResult>>\n    ExecuteAsync(GetContributorByIdRequest request, CancellationToken ct)\n  {\n    var result = await mediator.Send(new GetContributorQuery(ContributorId.From(request.ContributorId)), ct);\n\n    return result.ToGetByIdResult(Map.FromEntity);\n  }\n}\npublic sealed class GetContributorByIdMapper\n  : Mapper<GetContributorByIdRequest, ContributorRecord, ContributorDto>\n{\n  public override ContributorRecord FromEntity(ContributorDto e)\n    => new(e.Id.Value, e.Name.Value, e.PhoneNumber.ToString());\n}\n"
  },
  {
    "path": "src/Clean.Architecture.Web/Contributors/List.cs",
    "content": "﻿using Clean.Architecture.Core.ContributorAggregate;\nusing Clean.Architecture.UseCases.Contributors;\nusing Clean.Architecture.UseCases.Contributors.List;\nusing FluentValidation;\n\nnamespace Clean.Architecture.Web.Contributors;\n\npublic class List(IMediator mediator) : Endpoint<ListContributorsRequest, ContributorListResponse, ListContributorsMapper>\n{\n  private readonly IMediator _mediator = mediator;\n\n  public override void Configure()\n  {\n    Get(\"/Contributors\");\n    AllowAnonymous();\n\n    Summary(s =>\n    {\n      s.Summary = \"List contributors with pagination\";\n      s.Description = \"Retrieves a paginated list of all contributors. Supports GitHub-style pagination with 1-based page indexing and configurable page size.\";\n      s.ExampleRequest = new ListContributorsRequest { Page = 1, PerPage = 10 };\n      s.ResponseExamples[200] = new ContributorListResponse(\n        new List<ContributorRecord>\n        {\n          new(1, \"John Doe\", PhoneNumber.Unknown.ToString()),\n          new(2, \"Jane Smith\", PhoneNumber.Unknown.ToString())\n        },\n        1, 10, 2, 1);\n\n      // Document pagination parameters\n      s.Params[\"page\"] = \"1-based page index (default 1)\";\n      s.Params[\"per_page\"] = $\"Page size 1–{UseCases.Constants.MAX_PAGE_SIZE} (default {UseCases.Constants.DEFAULT_PAGE_SIZE})\";\n\n      // Document possible responses\n      s.Responses[200] = \"Paginated list of contributors returned successfully\";\n      s.Responses[400] = \"Invalid pagination parameters\";\n    });\n\n    // Add tags for API grouping\n    Tags(\"Contributors\");\n\n    // Add additional metadata\n    Description(builder => builder\n      .Accepts<ListContributorsRequest>()\n      .Produces<ContributorListResponse>(200, \"application/json\")\n      .ProducesProblem(400));\n  }\n\n  public override async Task HandleAsync(ListContributorsRequest request, CancellationToken cancellationToken)\n  {\n    var result = await _mediator.Send(new ListContributorsQuery(request.Page, request.PerPage));\n    if (!result.IsSuccess)\n    {\n      await Send.ErrorsAsync(statusCode: 400, cancellationToken);\n      return;\n    }\n\n    var pagedResult = result.Value;\n    AddLinkHeader(pagedResult.Page, pagedResult.PerPage, pagedResult.TotalPages);\n\n    var response = Map.FromEntity(pagedResult);\n    await Send.OkAsync(response, cancellationToken);\n  }\n\n  private void AddLinkHeader(int page, int perPage, int totalPages)\n  {\n    var baseUrl = $\"{HttpContext.Request.Scheme}://{HttpContext.Request.Host}{HttpContext.Request.Path}\";\n    string Link(string rel, int p) => $\"<{baseUrl}?page={p}&per_page={perPage}>; rel=\\\"{rel}\\\"\";\n\n    var parts = new List<string>();\n    if (page > 1)\n    {\n      parts.Add(Link(\"first\", 1));\n      parts.Add(Link(\"prev\", page - 1));\n    }\n    if (page < totalPages)\n    {\n      parts.Add(Link(\"next\", page + 1));\n      parts.Add(Link(\"last\", totalPages));\n    }\n\n    if (parts.Count > 0)\n      HttpContext.Response.Headers[\"Link\"] = string.Join(\", \", parts);\n  }\n}\n\npublic sealed class ListContributorsRequest\n{\n  // Bind to ?page=\n  [BindFrom(\"page\")]\n  public int Page { get; init; } = 1;\n\n  // Bind to ?per_page=\n  [BindFrom(\"per_page\")]\n  public int PerPage { get; init; } = UseCases.Constants.DEFAULT_PAGE_SIZE;\n}\n\npublic record ContributorListResponse : UseCases.PagedResult<ContributorRecord>\n{\n  public ContributorListResponse(IReadOnlyList<ContributorRecord> Items, int Page, int PerPage, int TotalCount, int TotalPages)\n    : base(Items, Page, PerPage, TotalCount, TotalPages)\n  {\n  }\n}\n\n\npublic sealed class ListContributorsValidator : Validator<ListContributorsRequest>\n{\n  public ListContributorsValidator()\n  {\n    RuleFor(x => x.Page)\n      .GreaterThanOrEqualTo(1)\n      .WithMessage(\"page must be >= 1\");\n\n    RuleFor(x => x.PerPage)\n      .InclusiveBetween(1, UseCases.Constants.MAX_PAGE_SIZE)\n      .WithMessage($\"per_page must be between 1 and {UseCases.Constants.MAX_PAGE_SIZE}\");\n  }\n}\n\npublic sealed class ListContributorsMapper\n  : Mapper<ListContributorsRequest, ContributorListResponse, UseCases.PagedResult<ContributorDto>>\n{\n  public override ContributorListResponse FromEntity(UseCases.PagedResult<ContributorDto> e)\n  {\n    var items = e.Items\n      .Select(c => new ContributorRecord(c.Id.Value, c.Name.Value, c.PhoneNumber.ToString()))\n      .ToList();\n\n    return new ContributorListResponse(items, e.Page, e.PerPage, e.TotalCount, e.TotalPages);\n  }\n}\n"
  },
  {
    "path": "src/Clean.Architecture.Web/Contributors/Update.UpdateContributorRequest.cs",
    "content": "﻿using System.ComponentModel.DataAnnotations;\n\nnamespace Clean.Architecture.Web.Contributors;\n\npublic class UpdateContributorRequest\n{\n  public const string Route = \"/Contributors/{ContributorId:int}\";\n  public static string BuildRoute(int contributorId) => Route.Replace(\"{ContributorId:int}\", contributorId.ToString());\n\n  public int ContributorId { get; set; }\n\n  [Required]\n  public int Id { get; set; }\n  [Required]\n  public string? Name { get; set; }\n}\n"
  },
  {
    "path": "src/Clean.Architecture.Web/Contributors/Update.UpdateContributorResponse.cs",
    "content": "﻿namespace Clean.Architecture.Web.Contributors;\n\npublic class UpdateContributorResponse(ContributorRecord contributor)\n{\n  public ContributorRecord Contributor { get; set; } = contributor;\n}\n"
  },
  {
    "path": "src/Clean.Architecture.Web/Contributors/Update.UpdateContributorValidator.cs",
    "content": "﻿using Clean.Architecture.Infrastructure.Data.Config;\nusing FastEndpoints;\nusing FluentValidation;\n\nnamespace Clean.Architecture.Web.Contributors;\n\n/// <summary>\n/// See: https://fast-endpoints.com/docs/validation\n/// </summary>\npublic class UpdateContributorValidator : Validator<UpdateContributorRequest>\n{\n  public UpdateContributorValidator()\n  {\n    RuleFor(x => x.Name)\n      .NotEmpty()\n      .WithMessage(\"Name is required.\")\n      .MinimumLength(2)\n      .MaximumLength(DataSchemaConstants.DEFAULT_NAME_LENGTH);\n    RuleFor(x => x.ContributorId)\n      .Must((args, contributorId) => args.Id == contributorId)\n      .WithMessage(\"Route and body Ids must match; cannot update Id of an existing resource.\");\n  }\n}\n"
  },
  {
    "path": "src/Clean.Architecture.Web/Contributors/Update.cs",
    "content": "﻿using Clean.Architecture.Core.ContributorAggregate;\nusing Clean.Architecture.UseCases.Contributors;\nusing Clean.Architecture.UseCases.Contributors.Get;\nusing Clean.Architecture.UseCases.Contributors.Update;\nusing Clean.Architecture.Web.Extensions;\nusing Microsoft.AspNetCore.Http.HttpResults;\n\nnamespace Clean.Architecture.Web.Contributors;\n\npublic class Update(IMediator mediator)\n  : Endpoint<\n        UpdateContributorRequest,\n        Results<Ok<UpdateContributorResponse>, NotFound, ProblemHttpResult>,\n        UpdateContributorMapper>\n{\n  private readonly IMediator _mediator = mediator;\n\n  public override void Configure()\n  {\n    Put(UpdateContributorRequest.Route);\n    AllowAnonymous();\n\n    // Optional but nice: enumerate for Swagger\n    Summary(s =>\n    {\n      s.Summary = \"Update a contributor\";\n      s.Description = \"Updates an existing contributor's information. The contributor name must be between 2 and 100 characters long.\";\n      s.ExampleRequest = new UpdateContributorRequest { Id = 1, Name = \"Updated Name\" };\n      s.ResponseExamples[200] = new UpdateContributorResponse(new ContributorRecord(1, \"Updated Name\", \"\"));\n\n      // Document possible responses\n      s.Responses[200] = \"Contributor updated successfully\";\n      s.Responses[404] = \"Contributor with specified ID not found\";\n      s.Responses[400] = \"Invalid input data or business rule violation\";\n    });\n\n    // Add tags for API grouping\n    Tags(\"Contributors\");\n\n    // Add additional metadata\n    Description(builder => builder\n      .Accepts<UpdateContributorRequest>(\"application/json\")\n      .Produces<UpdateContributorResponse>(200, \"application/json\")\n      .ProducesProblem(404)\n      .ProducesProblem(400));\n  }\n\n  public override async Task<Results<Ok<UpdateContributorResponse>, NotFound, ProblemHttpResult>>\n    ExecuteAsync(UpdateContributorRequest request, CancellationToken ct)\n  {\n    var cmd = new UpdateContributorCommand(\n      ContributorId.From(request.Id),\n      ContributorName.From(request.Name!));\n\n    var result = await _mediator.Send(cmd, ct);\n\n    return result.ToUpdateResult(Map.FromEntity);\n  }\n}\n\npublic sealed class UpdateContributorMapper\n  : Mapper<UpdateContributorRequest, UpdateContributorResponse, ContributorDto>\n{\n  public override UpdateContributorResponse FromEntity(ContributorDto e)\n    => new(new ContributorRecord(e.Id.Value, e.Name.Value, \"\"));\n}\n"
  },
  {
    "path": "src/Clean.Architecture.Web/Extensions/ResultExtensions.cs",
    "content": "﻿using Microsoft.AspNetCore.Http.HttpResults;\n\nnamespace Clean.Architecture.Web.Extensions;\n\npublic static class ResultExtensions\n{\n  /// <summary>\n  /// Maps Result to TypedResults for endpoints that return Created, ValidationProblem, or ProblemHttpResult\n  /// </summary>\n  public static Results<Created<TResponse>, ValidationProblem, ProblemHttpResult> ToCreatedResult<TValue, TResponse>(\n    this Result<TValue> result,\n    Func<TValue, string> locationBuilder,\n    Func<TValue, TResponse> mapResponse)\n  {\n    return result.Status switch\n    {\n      ResultStatus.Ok => TypedResults.Created(locationBuilder(result.Value), mapResponse(result.Value)),\n      ResultStatus.Invalid => TypedResults.ValidationProblem(\n        result.ValidationErrors\n          .GroupBy(e => e.Identifier ?? string.Empty)\n          .ToDictionary(\n            g => g.Key,\n            g => g.Select(e => e.ErrorMessage).ToArray()\n          )\n      ),\n      _ => TypedResults.Problem(\n        title: \"Create failed\",\n        detail: string.Join(\"; \", result.Errors),\n        statusCode: StatusCodes.Status400BadRequest)\n    };\n  }\n\n  /// <summary>\n  /// Maps Result to TypedResults for GetById endpoints that return Ok, NotFound, or ProblemHttpResult\n  /// </summary>\n  public static Results<Ok<TResponse>, NotFound, ProblemHttpResult> ToGetByIdResult<TValue, TResponse>(\n    this Result<TValue> result,\n    Func<TValue, TResponse> mapResponse)\n  {\n    return ToOkOrNotFoundResult(result, mapResponse, \"Get\");\n  }\n\n  /// <summary>\n  /// Maps Result to TypedResults for Update endpoints that return Ok, NotFound, or ProblemHttpResult\n  /// </summary>\n  public static Results<Ok<TResponse>, NotFound, ProblemHttpResult> ToUpdateResult<TValue, TResponse>(\n    this Result<TValue> result,\n    Func<TValue, TResponse> mapResponse)\n  {\n    return ToOkOrNotFoundResult(result, mapResponse, \"Update\");\n  }\n\n  /// <summary>\n  /// Maps Result to TypedResults for Delete endpoints that return NoContent, NotFound, or ProblemHttpResult\n  /// </summary>\n  public static Results<NoContent, NotFound, ProblemHttpResult> ToDeleteResult(\n    this Result result)\n  {\n    return result.Status switch\n    {\n      ResultStatus.Ok => TypedResults.NoContent(),\n      ResultStatus.NotFound => TypedResults.NotFound(),\n      _ => TypedResults.Problem(\n        title: \"Delete failed\",\n        detail: string.Join(\"; \", result.Errors),\n        statusCode: StatusCodes.Status400BadRequest)\n    };\n  }\n\n  /// <summary>\n  /// Private helper method for Ok/NotFound result patterns\n  /// </summary>\n  private static Results<Ok<TResponse>, NotFound, ProblemHttpResult> ToOkOrNotFoundResult<TValue, TResponse>(\n    Result<TValue> result,\n    Func<TValue, TResponse> mapResponse,\n    string operationName)\n  {\n    return result.Status switch\n    {\n      ResultStatus.Ok => TypedResults.Ok(mapResponse(result.Value)),\n      ResultStatus.NotFound => TypedResults.NotFound(),\n      _ => TypedResults.Problem(\n        title: $\"{operationName} failed\",\n        detail: string.Join(\"; \", result.Errors),\n        statusCode: StatusCodes.Status400BadRequest)\n    };\n  }\n\n  /// <summary>\n  /// Maps Result to TypedResults for endpoints that return Ok only (like List endpoints)\n  /// </summary>\n  public static Ok<TResponse> ToOkOnlyResult<TValue, TResponse>(\n    this Result<TValue> result,\n    Func<TValue, TResponse> mapResponse)\n  {\n    return TypedResults.Ok(mapResponse(result.Value));\n  }\n}\n"
  },
  {
    "path": "src/Clean.Architecture.Web/GlobalUsings.cs",
    "content": "﻿global using Ardalis.Result;\nglobal using FastEndpoints;\nglobal using FastEndpoints.Swagger;\nglobal using Mediator;\nglobal using Microsoft.EntityFrameworkCore;\nglobal using Serilog;\nglobal using Serilog.Extensions.Logging;\n"
  },
  {
    "path": "src/Clean.Architecture.Web/Program.cs",
    "content": "﻿using Clean.Architecture.Web.Configurations;\n\nvar builder = WebApplication.CreateBuilder(args);\n\nbuilder.AddServiceDefaults()    // This sets up OpenTelemetry logging\n       .AddLoggerConfigs();     // This adds Serilog for console formatting\n\nusing var loggerFactory = LoggerFactory.Create(config => config.AddConsole());\nvar startupLogger = loggerFactory.CreateLogger<Program>();\n\nstartupLogger.LogInformation(\"Starting web host\");\n\nbuilder.Services.AddOptionConfigs(builder.Configuration, startupLogger, builder);\nbuilder.Services.AddServiceConfigs(startupLogger, builder);\n\nbuilder.Services.AddFastEndpoints()\n                .SwaggerDocument(o =>\n                {\n                  o.DocumentSettings = s =>\n                  {\n                    s.Title = \"Clean Architecture API\";\n                    s.Version = \"v1\";\n                    s.Description = \"HTTP endpoints for the Clean Architecture sample application.\";\n                  };\n                  o.ShortSchemaNames = true;\n                });\n\nvar app = builder.Build();\n\nawait app.UseAppMiddlewareAndSeedDatabase();\n\napp.MapDefaultEndpoints(); // Aspire health checks and metrics\n\napp.Run();\n\n// Make the implicit Program.cs class public, so integration tests can reference the correct assembly for host building\npublic partial class Program { }\n"
  },
  {
    "path": "src/Clean.Architecture.Web/Properties/launchSettings.json",
    "content": "{\n  \"iisSettings\": {\n    \"windowsAuthentication\": false,\n    \"anonymousAuthentication\": true,\n    \"iisExpress\": {\n      \"applicationUrl\": \"http://localhost:57678/\",\n      \"sslPort\": 0\n    }\n  },\n  \"profiles\": {\n    \"https\": {\n      \"commandName\": \"Project\",\n      \"dotnetRunMessages\": true,\n      \"launchUrl\": \"scalar\",\n      \"environmentVariables\": {\n        \"ASPNETCORE_ENVIRONMENT\": \"Development\"\n      },\n      \"applicationUrl\": \"https://localhost:57679/\"\n    },\n    \"IIS Express\": {\n      \"commandName\": \"IISExpress\",\n      \"environmentVariables\": {\n        \"ASPNETCORE_ENVIRONMENT\": \"Development\"\n      }\n    }\n  }\n}"
  },
  {
    "path": "src/Clean.Architecture.Web/api.http",
    "content": "# For more info on HTTP files go to https://aka.ms/vs/httpfile\n@host=https://localhost\n@port=57679\n\n// List all contributors\nGET {{host}}:{{port}}/Contributors\n\n###\n\n// Get a specific contributor\n@id_to_get=1\nGET {{host}}:{{port}}/Contributors/{{id_to_get}}\n\n###\n\n// Add a new contributor\nPOST {{host}}:{{port}}/Contributors\nContent-Type: application/json\n\n{\n  \"name\": \"John Doe 3\",\n  \"email\": \"test@test.com\",\n  \"phoneNumber\": \"1234567890\"\n}\n\n###\n\n// Update a contributor\n@id_to_update=3\nPUT {{host}}:{{port}}/Contributors/{{id_to_update}}\nContent-Type: application/json\n\n{\n  \"id\": {{id_to_update}},\n  \"name\": \"ardalis2\"\n}\n\n###\n\n// Delete a contributor\n@id_to_delete=1\nDELETE {{host}}:{{port}}/Contributors/{{id_to_delete}}\n\n"
  },
  {
    "path": "src/Clean.Architecture.Web/appsettings.Development.json",
    "content": "{\n  \"Logging\": {\n    \"LogLevel\": {\n      \"Default\": \"Information\",\n      \"Microsoft.AspNetCore\": \"Warning\",\n      \"Microsoft.EntityFrameworkCore.Database.Command\": \"Information\"\n    }\n  },\n  \"Database\": {\n    \"ApplyMigrationsOnStartup\": true\n  }\n}\n"
  },
  {
    "path": "src/Clean.Architecture.Web/appsettings.Testing.json",
    "content": "{\n  \"Logging\": {\n    \"LogLevel\": {\n      \"Default\": \"Information\",\n      \"Microsoft.AspNetCore\": \"Warning\",\n      \"Microsoft.EntityFrameworkCore.Database.Command\": \"Information\"\n    }\n  },\n  \"ConnectionStrings\": {\n    \"SqliteConnection\": \":memory:\"\n  },\n  \"Database\": {\n    \"ApplyMigrationsOnStartup\": false\n  }\n}\n"
  },
  {
    "path": "src/Clean.Architecture.Web/appsettings.json",
    "content": "﻿{\n  \"ConnectionStrings\": {\n    // When running through Aspire, the connection string is provided automatically by the AspireHost\n    // This DefaultConnection is used only when running the Web project directly on Windows (without Aspire)\n    // You can configure this to point to your local SQL Server instance\n    // Note: On Linux/macOS, this connection is skipped and SQLite is used instead\n    \"DefaultConnection\": \"Server=(localdb)\\\\mssqllocaldb;Database=cleanarchitecture;Trusted_Connection=True;MultipleActiveResultSets=true\",\n    // SQLite is used as a fallback when running on Linux/macOS or when running standalone on Windows without Aspire\n    \"SqliteConnection\": \"Data Source=database.sqlite\"\n  },\n  \"Database\": {\n    // Set to true to apply migrations on startup (useful for containerized environments)\n    // By default, migrations run automatically in Development environment\n    \"ApplyMigrationsOnStartup\": false\n  },\n  \"Serilog\": {\n    \"MinimumLevel\": {\n      \"Default\": \"Information\"\n    },\n    \"WriteTo\": [\n        {\n            \"Name\": \"Console\"\n        }\n        // uncomment if you want file logging\n        //,\n        //{\n        //  \"Name\": \"File\",\n        //  \"Args\": {\n        //    \"path\": \"log.txt\",\n        //    \"rollingInterval\": \"Day\"\n        //  }\n        //}\n\n        //Uncomment this section if you'd like to push your logs to Azure Application Insights\n        //Full list of Serilog Sinks can be found here: https://github.com/serilog/serilog/wiki/Provided-Sinks\n        //{\n        //  \"Name\": \"ApplicationInsights\",\n        //  \"Args\": {\n        //    \"instrumentationKey\": \"\", //Fill in with your ApplicationInsights InstrumentationKey\n        //    \"telemetryConverter\": \"Serilog.Sinks.ApplicationInsights.Sinks.ApplicationInsights.TelemetryConverters.TraceTelemetryConverter, Serilog.Sinks.ApplicationInsights\"\n        //  }\n        //}\n    ]\n  },\n  \"Mailserver\": {\n    \"Server\": \"localhost\",\n    \"Port\": 25\n  }\n}\n"
  },
  {
    "path": "src/Clean.Architecture.Web/wwwroot/.gitkeep",
    "content": ""
  },
  {
    "path": "tests/Clean.Architecture.AspireTests/AspireIntegrationTests.cs",
    "content": "namespace Clean.Architecture.AspireTests.Tests;\n\npublic class AspireIntegrationTests\n{\n    // Follow the link below to write you tests with Aspire\n    // https://learn.microsoft.com/en-us/dotnet/aspire/testing/write-your-first-test?pivots=xunit\n}\n"
  },
  {
    "path": "tests/Clean.Architecture.AspireTests/Clean.Architecture.AspireTests.csproj",
    "content": "<Project Sdk=\"Microsoft.NET.Sdk\">\n\n  <PropertyGroup>\n    <TargetFramework>net9.0</TargetFramework>\n    <ImplicitUsings>enable</ImplicitUsings>\n    <Nullable>enable</Nullable>\n    <IsPackable>false</IsPackable>\n    <IsTestProject>true</IsTestProject>\n  </PropertyGroup>\n\n  <ItemGroup>\n    <PackageReference Include=\"Aspire.Hosting.Testing\"/>\n    <PackageReference Include=\"coverlet.collector\"/>\n    <PackageReference Include=\"Microsoft.NET.Test.Sdk\"/>\n    <PackageReference Include=\"xunit\"/>\n    <PackageReference Include=\"xunit.runner.visualstudio\"/>\n  </ItemGroup>\n\n  <ItemGroup>\n    <Using Include=\"System.Net\" />\n    <Using Include=\"Microsoft.Extensions.DependencyInjection\" />\n    <Using Include=\"Aspire.Hosting.ApplicationModel\" />\n    <Using Include=\"Aspire.Hosting.Testing\" />\n    <Using Include=\"Xunit\" />\n  </ItemGroup>\n\n  <ItemGroup>\n    <ProjectReference Include=\"..\\..\\src\\Clean.Architecture.AspireHost\\Clean.Architecture.AspireHost.csproj\" />\n  </ItemGroup>\n\n</Project>\n"
  },
  {
    "path": "tests/Clean.Architecture.FunctionalTests/ApiEndpoints/ContributorGetById.cs",
    "content": "﻿using Clean.Architecture.Infrastructure.Data;\nusing Clean.Architecture.Web.Contributors;\n\n\nnamespace Clean.Architecture.FunctionalTests.ApiEndpoints;\n\n[Collection(\"Sequential\")]\npublic class ContributorGetById(CustomWebApplicationFactory<Program> factory) : IClassFixture<CustomWebApplicationFactory<Program>>\n{\n  private readonly HttpClient _client = factory.CreateClient();\n\n  [Fact]\n  public async Task ReturnsSeedContributorGivenId1()\n  {\n    var result = await _client.GetAndDeserializeAsync<ContributorRecord>(GetContributorByIdRequest.BuildRoute(1));\n\n    result.Id.ShouldBe(1);\n    result.Name.ShouldBe(SeedData.Contributor1.Name.Value);\n  }\n\n  [Fact]\n  public async Task ReturnsNotFoundGivenId1000()\n  {\n    string route = GetContributorByIdRequest.BuildRoute(1000);\n    _ = await _client.GetAndEnsureNotFoundAsync(route);\n  }\n}\n"
  },
  {
    "path": "tests/Clean.Architecture.FunctionalTests/ApiEndpoints/ContributorList.cs",
    "content": "﻿using Clean.Architecture.Infrastructure.Data;\nusing Clean.Architecture.Web.Contributors;\n\nnamespace Clean.Architecture.FunctionalTests.ApiEndpoints;\n\n[Collection(\"Sequential\")]\npublic class ContributorList(CustomWebApplicationFactory<Program> factory) : IClassFixture<CustomWebApplicationFactory<Program>>\n{\n  private readonly HttpClient _client = factory.CreateClient();\n\n  [Fact]\n  public async Task ReturnsTwoContributors()\n  {\n    var result = await _client.GetAndDeserializeAsync<ContributorListResponse>(\"/Contributors\");\n\n    Assert.Equal(SeedData.NUMBER_OF_CONTRIBUTORS, result.TotalCount);\n    Assert.Contains(result.Items, i => i.Name == SeedData.Contributor1.Name);\n    Assert.Contains(result.Items, i => i.Name == SeedData.Contributor2.Name);\n  }\n}\n"
  },
  {
    "path": "tests/Clean.Architecture.FunctionalTests/Clean.Architecture.FunctionalTests.csproj",
    "content": "﻿<Project Sdk=\"Microsoft.NET.Sdk\">\n  <Sdk Name=\"Microsoft.Build.CentralPackageVersions\" Version=\"2.1.3\" />\n\n  <ItemGroup>\n    <PackageReference Include=\"Shouldly\" />\n    <PackageReference Include=\"Microsoft.NET.Test.Sdk\" />\n    <PackageReference Include=\"xunit\" />\n    <PackageReference Include=\"xunit.runner.visualstudio\">\n      <PrivateAssets>all</PrivateAssets>\n      <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>\n    </PackageReference>\n    <PackageReference Include=\"coverlet.collector\">\n      <PrivateAssets>all</PrivateAssets>\n      <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>\n    </PackageReference>\n    <PackageReference Include=\"Microsoft.AspNetCore.Mvc.Testing\" />\n    <PackageReference Include=\"Testcontainers\" />\n    <PackageReference Include=\"Testcontainers.MsSql\" />\n    <PackageReference Include=\"Ardalis.HttpClientTestExtensions\" />\n  </ItemGroup>\n\n  <ItemGroup>\n    <ProjectReference Include=\"..\\..\\src\\Clean.Architecture.Infrastructure\\Clean.Architecture.Infrastructure.csproj\" />\n    <ProjectReference Include=\"..\\..\\src\\Clean.Architecture.UseCases\\Clean.Architecture.UseCases.csproj\" />\n    <ProjectReference Include=\"..\\..\\src\\Clean.Architecture.Web\\Clean.Architecture.Web.csproj\" />\n  </ItemGroup>\n\n</Project>\n"
  },
  {
    "path": "tests/Clean.Architecture.FunctionalTests/CustomWebApplicationFactory.cs",
    "content": "﻿using Clean.Architecture.Infrastructure.Data;\nusing Microsoft.EntityFrameworkCore;\nusing Microsoft.Extensions.Configuration;\nusing Testcontainers.MsSql;\n\nnamespace Clean.Architecture.FunctionalTests;\n\npublic class CustomWebApplicationFactory<TProgram> : WebApplicationFactory<TProgram>, IAsyncLifetime where TProgram : class\n{\n  private MsSqlContainer? _dbContainer;\n\n  public async Task InitializeAsync()\n  {\n    try\n    {\n      _dbContainer = new MsSqlBuilder()\n        .WithImage(\"mcr.microsoft.com/mssql/server:2022-latest\")\n        .WithPassword(\"Your_password123!\")\n        .Build();\n      await _dbContainer.StartAsync();\n    }\n    catch (ArgumentException)\n    {\n      // Docker is not available; fall back to SQLite (configured via appsettings.Testing.json)\n      _dbContainer = null;\n    }\n  }\n\n  public new async Task DisposeAsync()\n  {\n    // Clean up environment variable\n    Environment.SetEnvironmentVariable(\"USE_SQL_SERVER\", null);\n    if (_dbContainer != null)\n    {\n      await _dbContainer.DisposeAsync();\n    }\n  }\n\n  /// <summary>\n  /// Overriding CreateHost to avoid creating a separate ServiceProvider per this thread:\n  /// https://github.com/dotnet-architecture/eShopOnWeb/issues/465\n  /// </summary>\n  /// <param name=\"builder\"></param>\n  /// <returns></returns>\n  protected override IHost CreateHost(IHostBuilder builder)\n  {\n    builder.UseEnvironment(\"Testing\"); // will not send real emails\n    var host = builder.Build();\n    host.Start();\n\n    // Get service provider.\n    var serviceProvider = host.Services;\n\n    // Create a scope to obtain a reference to the database\n    // context (AppDbContext).\n    using (var scope = serviceProvider.CreateScope())\n    {\n      var scopedServices = scope.ServiceProvider;\n      var db = scopedServices.GetRequiredService<AppDbContext>();\n\n      var logger = scopedServices\n          .GetRequiredService<ILogger<CustomWebApplicationFactory<TProgram>>>();\n\n      try\n      {\n        if (_dbContainer != null)\n        {\n          // SQL Server via Testcontainers: apply migrations to create the schema\n          db.Database.Migrate();\n        }\n        else\n        {\n          // SQLite fallback: EnsureCreated is used because the migrations use SQL Server syntax\n          db.Database.EnsureCreated();\n        }\n\n        // Seed the database with test data only if it has not been seeded yet.\n        // This is safe for container reuse across test runs and multiple fixture instances.\n        SeedData.InitializeAsync(db).Wait();\n      }\n      catch (Exception ex)\n      {\n        logger.LogError(ex, \"An error occurred seeding the \" +\n                            \"database with test messages. Error: {exceptionMessage}\", ex.Message);\n      }\n    }\n\n    return host;\n  }\n\n  protected override void ConfigureWebHost(IWebHostBuilder builder)\n  {\n    if (_dbContainer != null)\n    {\n      // Force SQL Server mode even on non-Windows platforms for functional tests\n      Environment.SetEnvironmentVariable(\"USE_SQL_SERVER\", \"true\");\n    }\n\n    builder\n        .ConfigureAppConfiguration((context, config) =>\n        {\n          if (_dbContainer != null)\n          {\n            // Set the connection string to use the Testcontainer\n            config.AddInMemoryCollection(new Dictionary<string, string?>\n            {\n              [\"ConnectionStrings:DefaultConnection\"] = _dbContainer.GetConnectionString()\n            });\n          }\n        })\n        .ConfigureServices(services =>\n        {\n          if (_dbContainer != null)\n          {\n            // Remove the app's ApplicationDbContext registration\n            var descriptors = services.Where(\n              d => d.ServiceType == typeof(AppDbContext) ||\n                   d.ServiceType == typeof(DbContextOptions<AppDbContext>))\n                  .ToList();\n\n            foreach (var descriptor in descriptors)\n            {\n              services.Remove(descriptor);\n            }\n\n            // Add ApplicationDbContext using the Testcontainers SQL Server instance\n            services.AddDbContext<AppDbContext>((provider, options) =>\n            {\n              options.UseSqlServer(_dbContainer.GetConnectionString());\n              var interceptor = provider.GetRequiredService<EventDispatchInterceptor>();\n              options.AddInterceptors(interceptor);\n            });\n          }\n        });\n  }\n}\n"
  },
  {
    "path": "tests/Clean.Architecture.FunctionalTests/DockerAvailabilityTests.cs",
    "content": "﻿using Docker.DotNet;\n\nnamespace Clean.Architecture.FunctionalTests;\n\npublic class DockerAvailabilityTests\n{\n  [Fact]\n  public async Task Docker_ShouldBeRunning_ForFullFunctionalTestCoverage()\n  {\n    try\n    {\n      // Ping the Docker daemon directly using the Docker client.\n      // This has no side effects on container lifecycle or Testcontainers internals.\n      using var client = new DockerClientConfiguration().CreateClient();\n      await client.System.PingAsync();\n    }\n    catch (Exception)\n    {\n      Assert.Fail(\n        \"Docker is not running or is misconfigured. \" +\n        \"Functional tests that use SQL Server will fall back to SQLite, which may not catch SQL Server-specific issues. \" +\n        \"For full test coverage, please start Docker Desktop (https://www.docker.com/products/docker-desktop/) and re-run the tests.\");\n    }\n  }\n}\n"
  },
  {
    "path": "tests/Clean.Architecture.FunctionalTests/GlobalUsings.cs",
    "content": "﻿global using Ardalis.HttpClientTestExtensions;\nglobal using Microsoft.AspNetCore.Hosting;\nglobal using Microsoft.AspNetCore.Mvc.Testing;\nglobal using Microsoft.Extensions.DependencyInjection;\nglobal using Microsoft.Extensions.Hosting;\nglobal using Microsoft.Extensions.Logging;\nglobal using Shouldly;\nglobal using Xunit;\n"
  },
  {
    "path": "tests/Clean.Architecture.FunctionalTests/xunit.runner.json",
    "content": "﻿{\n  \"shadowCopy\": false,\n  \"parallelizeAssembly\": true,\n  \"parallelizeTestCollections\": true,\n  \"maxParallelThreads\": 0\n}"
  },
  {
    "path": "tests/Clean.Architecture.IntegrationTests/Clean.Architecture.IntegrationTests.csproj",
    "content": "﻿<Project Sdk=\"Microsoft.NET.Sdk\">\n  <Sdk Name=\"Microsoft.Build.CentralPackageVersions\" Version=\"2.1.3\" />\n\n  <ItemGroup>\n    <PackageReference Include=\"Microsoft.NET.Test.Sdk\" />\n    <PackageReference Include=\"xunit.runner.visualstudio\">\n      <PrivateAssets>all</PrivateAssets>\n      <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>\n    </PackageReference>\n    <PackageReference Include=\"coverlet.collector\">\n      <PrivateAssets>all</PrivateAssets>\n      <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>\n    </PackageReference>\n    <PackageReference Include=\"Shouldly\" />\n    <PackageReference Include=\"NSubstitute\" />\n    <PackageReference Include=\"xunit\" />\n    <PackageReference Include=\"Microsoft.AspNetCore.Mvc.Testing\" />\n    <PackageReference Include=\"Microsoft.EntityFrameworkCore.InMemory\" />\n  </ItemGroup>\n\n  <ItemGroup>\n    <ProjectReference Include=\"..\\..\\src\\Clean.Architecture.Infrastructure\\Clean.Architecture.Infrastructure.csproj\" />\n  </ItemGroup>\n\n  <ItemGroup>\n    <None Update=\"xunit.runner.json\">\n\t  <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>\n    </None>\n  </ItemGroup>\n\n</Project>\n"
  },
  {
    "path": "tests/Clean.Architecture.IntegrationTests/Data/BaseEfRepoTestFixture.cs",
    "content": "﻿using Clean.Architecture.Core.ContributorAggregate;\nusing Clean.Architecture.Infrastructure.Data;\n\nnamespace Clean.Architecture.IntegrationTests.Data;\n\npublic abstract class BaseEfRepoTestFixture\n{\n  protected AppDbContext _dbContext;\n\n  protected BaseEfRepoTestFixture()\n  {\n    var options = CreateNewContextOptions();\n    _dbContext = new AppDbContext(options);\n  }\n\n  protected static DbContextOptions<AppDbContext> CreateNewContextOptions()\n  {\n    var fakeEventDispatcher = Substitute.For<IDomainEventDispatcher>();\n    // Create a fresh service provider, and therefore a fresh\n    // InMemory database instance.\n    var serviceProvider = new ServiceCollection()\n        .AddEntityFrameworkInMemoryDatabase()\n        .AddScoped<IDomainEventDispatcher>(_ => fakeEventDispatcher)\n        .AddScoped<EventDispatchInterceptor>()\n        .BuildServiceProvider();\n\n    // Create a new options instance telling the context to use an\n    // InMemory database and the new service provider.\n    var interceptor = serviceProvider.GetRequiredService<EventDispatchInterceptor>();\n\n    var builder = new DbContextOptionsBuilder<AppDbContext>();\n    builder.UseInMemoryDatabase(\"cleanarchitecture\")\n           .UseInternalServiceProvider(serviceProvider)\n           .AddInterceptors(interceptor);\n\n    return builder.Options;\n  }\n\n  protected EfRepository<Contributor> GetRepository()\n  {\n    return new EfRepository<Contributor>(_dbContext);\n  }\n}\n"
  },
  {
    "path": "tests/Clean.Architecture.IntegrationTests/Data/EfRepositoryAdd.cs",
    "content": "﻿using Clean.Architecture.Core.ContributorAggregate;\n\nnamespace Clean.Architecture.IntegrationTests.Data;\n\npublic class EfRepositoryAdd : BaseEfRepoTestFixture\n{\n  [Fact]\n  public async Task AddsContributorAndSetsId()\n  {\n    var testContributorName = ContributorName.From(\"testContributor\");\n    var testContributorStatus = ContributorStatus.NotSet;\n    var repository = GetRepository();\n    var Contributor = new Contributor(testContributorName);\n\n    await repository.AddAsync(Contributor);\n\n    var newContributor = (await repository.ListAsync())\n                    .FirstOrDefault();\n\n    newContributor.ShouldNotBeNull();\n    testContributorName.ShouldBe(newContributor.Name);\n    testContributorStatus.ShouldBe(newContributor.Status);\n    newContributor.Id.Value.ShouldBeGreaterThan(0);\n  }\n}\n"
  },
  {
    "path": "tests/Clean.Architecture.IntegrationTests/Data/EfRepositoryDelete.cs",
    "content": "﻿using Clean.Architecture.Core.ContributorAggregate;\n\nnamespace Clean.Architecture.IntegrationTests.Data;\n\npublic class EfRepositoryDelete : BaseEfRepoTestFixture\n{\n  [Fact]\n  public async Task DeletesItemAfterAddingIt()\n  {\n    // add a Contributor\n    var repository = GetRepository();\n    var initialName = ContributorName.From(Guid.NewGuid().ToString());\n    var Contributor = new Contributor(initialName);\n    await repository.AddAsync(Contributor);\n\n    // delete the item\n    await repository.DeleteAsync(Contributor);\n\n    // verify it's no longer there\n    (await repository.ListAsync()).ShouldNotContain(Contributor => Contributor.Name == initialName);\n  }\n}\n"
  },
  {
    "path": "tests/Clean.Architecture.IntegrationTests/Data/EfRepositoryUpdate.cs",
    "content": "﻿using Clean.Architecture.Core.ContributorAggregate;\n\nnamespace Clean.Architecture.IntegrationTests.Data;\n\npublic class EfRepositoryUpdate : BaseEfRepoTestFixture\n{\n  [Fact]\n  public async Task UpdatesItemAfterAddingIt()\n  {\n    // add a Contributor\n    var repository = GetRepository();\n    var initialName = ContributorName.From(Guid.NewGuid().ToString());\n    var Contributor = new Contributor(initialName);\n\n    await repository.AddAsync(Contributor);\n\n    // detach the item so we get a different instance\n    _dbContext.Entry(Contributor).State = EntityState.Detached;\n\n    // fetch the item and update its title\n    var newContributor = (await repository.ListAsync())\n        .FirstOrDefault(Contributor => Contributor.Name == initialName);\n    newContributor.ShouldNotBeNull();\n\n    Contributor.ShouldNotBeSameAs(newContributor);\n    var newName = ContributorName.From(Guid.NewGuid().ToString());\n    newContributor.UpdateName(newName);\n\n    // Update the item\n    await repository.UpdateAsync(newContributor);\n\n    // Fetch the updated item\n    var updatedItem = (await repository.ListAsync())\n        .FirstOrDefault(Contributor => Contributor.Name == newName);\n\n    updatedItem.ShouldNotBeNull();\n    Contributor.Name.ShouldNotBe(updatedItem.Name);\n    Contributor.Status.ShouldBe(updatedItem.Status);\n    newContributor.Id.ShouldBe(updatedItem.Id);\n  }\n}\n"
  },
  {
    "path": "tests/Clean.Architecture.IntegrationTests/GlobalUsings.cs",
    "content": "﻿global using Ardalis.SharedKernel;\nglobal using Microsoft.EntityFrameworkCore;\nglobal using Microsoft.Extensions.DependencyInjection;\nglobal using NSubstitute;\nglobal using Shouldly;\nglobal using Xunit;\n"
  },
  {
    "path": "tests/Clean.Architecture.IntegrationTests/xunit.runner.json",
    "content": "{\n  \"shadowCopy\": false,\n  \"parallelizeAssembly\": true,\n  \"parallelizeTestCollections\": true,\n  \"maxParallelThreads\": 0\n}\n"
  },
  {
    "path": "tests/Clean.Architecture.UnitTests/Clean.Architecture.UnitTests.csproj",
    "content": "﻿<Project Sdk=\"Microsoft.NET.Sdk\">\n  <Sdk Name=\"Microsoft.Build.CentralPackageVersions\" Version=\"2.1.3\" />\n\n  <PropertyGroup>\n    <PreserveCompilationContext>true</PreserveCompilationContext>\n  </PropertyGroup>\n\n  <ItemGroup>\n    <Compile Remove=\"Core\\Services\\ToDoItemSearchService_GetAllIncompleteItems.cs\" />\n    <Compile Remove=\"Core\\Services\\ToDoItemSearchService_GetNextIncompleteItem.cs\" />\n  </ItemGroup>\n\n  <ItemGroup>\n    <PackageReference Include=\"Shouldly\" />\n    <PackageReference Include=\"Microsoft.NET.Test.Sdk\" />\n    <PackageReference Include=\"NSubstitute\" />\n    <PackageReference Include=\"xunit.runner.visualstudio\">\n      <PrivateAssets>all</PrivateAssets>\n      <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>\n    </PackageReference>\n    <PackageReference Include=\"coverlet.collector\">\n      <PrivateAssets>all</PrivateAssets>\n      <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>\n    </PackageReference>\n    <PackageReference Include=\"ReportGenerator\" />\n    <PackageReference Include=\"xunit\" />\n    <PackageReference Include=\"Mediator.Abstractions\" />\n    <PackageReference Include=\"Mediator.SourceGenerator\" />\n  </ItemGroup>\n\n  <ItemGroup>\n    <None Update=\"xunit.runner.json\">\n\t  <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>\n    </None>\n  </ItemGroup>\n\n  <ItemGroup>\n    <Folder Include=\"Core\\Services\\\" />\n  </ItemGroup>\n\n  <ItemGroup>\n    <ProjectReference Include=\"..\\..\\src\\Clean.Architecture.Core\\Clean.Architecture.Core.csproj\" />\n    <ProjectReference Include=\"..\\..\\src\\Clean.Architecture.UseCases\\Clean.Architecture.UseCases.csproj\" />\n  </ItemGroup>\n\n</Project>\n"
  },
  {
    "path": "tests/Clean.Architecture.UnitTests/Core/ContributorAggregate/ContributorConstructor.cs",
    "content": "﻿namespace Clean.Architecture.UnitTests.Core.ContributorAggregate;\n\npublic class ContributorConstructor\n{\n  private readonly ContributorName _testName = ContributorName.From(\"test name\");\n  private Contributor? _testContributor;\n\n  private Contributor CreateContributor()\n  {\n    return new Contributor(_testName);\n  }\n\n  [Fact]\n  public void InitializesName()\n  {\n    _testContributor = CreateContributor();\n\n    _testContributor.Name.ShouldBe(_testName);\n  }\n}\n"
  },
  {
    "path": "tests/Clean.Architecture.UnitTests/Core/ContributorAggregate/ContributorIdFrom.cs",
    "content": "﻿namespace Clean.Architecture.UnitTests.Core.ContributorAggregate;\n\npublic class ContributorIdFrom\n{\n  [Fact]\n  public void CreatesGivenValidValue()\n  {\n    int validValue = 1;\n    var contributorId = ContributorId.From(validValue);\n    Assert.Equal(validValue, contributorId.Value);\n  }\n\n  [Theory]\n  [InlineData(0)]\n  [InlineData(-1)]\n  public void ThrowsGivenInvalidValue(int invalidValue)\n  {\n    Assert.Throws<Vogen.ValueObjectValidationException>(() => ContributorId.From(invalidValue));\n  }\n}\n"
  },
  {
    "path": "tests/Clean.Architecture.UnitTests/Core/ContributorAggregate/ContributorNameFrom.cs",
    "content": "﻿namespace Clean.Architecture.UnitTests.Core.ContributorAggregate;\n\npublic class ContributorNameFrom\n{\n  [Fact]\n  public void CreatesGivenValidValue()\n  {\n    string validValue = \"ardalis\";\n    var contributorName = ContributorName.From(validValue);\n    Assert.Equal(validValue, contributorName.Value);\n  }\n\n  [Theory]\n  [InlineData(null)]\n  [InlineData(\"\")]\n  public void ThrowsGivenInvalidValue(string? invalidValue)\n  {\n    Assert.Throws<Vogen.ValueObjectValidationException>(() => ContributorName.From(invalidValue!));\n  }\n}\n"
  },
  {
    "path": "tests/Clean.Architecture.UnitTests/Core/ContributorAggregate/ContributorUpdateName.cs",
    "content": "﻿using Clean.Architecture.Core.ContributorAggregate.Events;\n\nnamespace Clean.Architecture.UnitTests.Core.ContributorAggregate;\n\npublic class ContributorUpdateName\n{\n  private readonly ContributorName _initialName = ContributorName.From(\"initial name\");\n  private readonly ContributorName _newName = ContributorName.From(\"new name\");\n  private Contributor? _testContributor;\n  private Contributor CreateContributor()\n  {\n    return new Contributor(_initialName);\n  }\n\n  [Fact]\n  public void UpdatesName()\n  {\n    _testContributor = CreateContributor();\n    _testContributor.UpdateName(_newName);\n    _testContributor.Name.ShouldBe(_newName);\n  }\n\n  [Fact]\n  public void RegistersDomainEvent()\n  {\n    _testContributor = CreateContributor();\n    _testContributor.UpdateName(_newName);\n    _testContributor.DomainEvents.Count.ShouldBe(1);\n    _testContributor.DomainEvents.First().ShouldBeOfType<ContributorNameUpdatedEvent>();\n  }\n\n  [Fact]\n  public void DoesNotRegisterDomainEventGivenCurrentName()\n  {\n    _testContributor = CreateContributor();\n    _testContributor.UpdateName(_initialName);\n    _testContributor.DomainEvents.Count.ShouldBe(0);\n  }\n\n}\n"
  },
  {
    "path": "tests/Clean.Architecture.UnitTests/Core/Services/DeleteContributorSevice_DeleteContributor.cs",
    "content": "﻿using Clean.Architecture.Core.Services;\n\nnamespace Clean.Architecture.UnitTests.Core.Services;\n\npublic class DeleteContributorService_DeleteContributor\n{\n  private readonly IRepository<Contributor> _repository = Substitute.For<IRepository<Contributor>>();\n  private readonly IMediator _mediator = Substitute.For<IMediator>();\n  private readonly ILogger<DeleteContributorService> _logger = Substitute.For<ILogger<DeleteContributorService>>();\n\n  private readonly DeleteContributorService _service;\n\n  public DeleteContributorService_DeleteContributor()\n  {\n    _service = new DeleteContributorService(_repository, _mediator, _logger);\n  }\n\n  [Fact]\n  public async Task ReturnsNotFoundGivenCantFindContributor()\n  {\n    int missingId = 9999;\n    var result = await _service.DeleteContributor(ContributorId.From(missingId));\n\n    result.Status.ShouldBe(Ardalis.Result.ResultStatus.NotFound);\n  }\n}\n"
  },
  {
    "path": "tests/Clean.Architecture.UnitTests/Core/Services/ToDoItemSearchService_GetAllIncompleteItems.cs",
    "content": "﻿using System.Linq;\nusing System.Threading.Tasks;\nusing Ardalis.Specification;\nusing Clean.Architecture.Core.ProjectAggregate;\nusing Clean.Architecture.Core.Services;\nusing Clean.Architecture.SharedKernel.Interfaces;\nusing Moq;\nusing Xunit;\n\nnamespace Clean.Architecture.UnitTests.Core.Services\n{\n    public class ToDoItemSearchService_GetAllIncompleteItems\n    {\n        private Mock<IRepository<ToDoItem>> _mockRepo = new Mock<IRepository<ToDoItem>>();\n        private ToDoItemSearchService _searchService;\n\n        public ToDoItemSearchService_GetAllIncompleteItems()\n        {\n            _searchService = new ToDoItemSearchService(_mockRepo.Object);\n        }\n\n        [Fact]\n        public async Task ReturnsInvalidGivenNullSearchString()\n        {\n            var result = await _searchService.GetAllIncompleteItemsAsync(null);\n\n            Assert.Equal(Ardalis.Result.ResultStatus.Invalid, result.Status);\n            Assert.Equal(\"searchString is required.\", result.ValidationErrors.First().ErrorMessage);\n        }\n\n        [Fact]\n        public async Task ReturnsErrorGivenDataAccessException()\n        {\n            string expectedErrorMessage = \"Database not there.\";\n            _mockRepo.Setup(r => r.ListAsync(It.IsAny<ISpecification<ToDoItem>>()))\n                .ThrowsAsync(new System.Exception(expectedErrorMessage));\n\n            var result = await _searchService.GetAllIncompleteItemsAsync(\"something\");\n\n            Assert.Equal(Ardalis.Result.ResultStatus.Error, result.Status);\n            Assert.Equal(expectedErrorMessage, result.Errors.First());\n        }\n\n        [Fact]\n        public async Task ReturnsListGivenSearchString()\n        {\n            var result = await _searchService.GetAllIncompleteItemsAsync(\"foo\");\n\n            Assert.Equal(Ardalis.Result.ResultStatus.Ok, result.Status);\n        }\n    }\n}\n"
  },
  {
    "path": "tests/Clean.Architecture.UnitTests/Core/Services/ToDoItemSearchService_GetNextIncompleteItem.cs",
    "content": "﻿using System.Collections.Generic;\nusing System.Linq;\nusing System.Threading.Tasks;\nusing Ardalis.Specification;\nusing Clean.Architecture.Core.ProjectAggregate;\nusing Clean.Architecture.Core.Services;\nusing Clean.Architecture.SharedKernel.Interfaces;\nusing Moq;\nusing Xunit;\n\nnamespace Clean.Architecture.UnitTests.Core.Services\n{\n    public class ToDoItemSearchService_GetNextIncompleteItem\n    {\n        [Fact]\n        public async Task ReturnsNotFoundGivenNoRemainingItems()\n        {\n            var repo = new Mock<IRepository<ToDoItem>>();\n            var service = new ToDoItemSearchService(repo.Object);\n            repo.Setup(r => r.ListAsync(It.IsAny<ISpecification<ToDoItem>>()))\n                .ReturnsAsync(new List<ToDoItem>());\n\n            var result = await service.GetNextIncompleteItemAsync();\n\n            Assert.Equal(Ardalis.Result.ResultStatus.NotFound, result.Status);\n        }\n\n        [Fact]\n        public async Task ReturnsFirstItemFromList()\n        {\n            var repo = new Mock<IRepository<ToDoItem>>();\n            var service = new ToDoItemSearchService(repo.Object);\n            var testItems = GetTestItems();\n            repo.Setup(r => r.ListAsync(It.IsAny<ISpecification<ToDoItem>>()))\n                .ReturnsAsync(testItems);\n\n            var result = await service.GetNextIncompleteItemAsync();\n\n            Assert.Equal(testItems.First(), result.Value);\n        }\n\n        private List<ToDoItem> GetTestItems()\n        {\n            // Note: could use AutoFixture\n            var builder = new ToDoItemBuilder();\n\n            var items = new List<ToDoItem>();\n\n            var item1 = builder.WithDefaultValues().Build();\n            items.Add(item1);\n\n            var item2 = builder.WithDefaultValues().Id(2).Build();\n            items.Add(item2);\n\n            var item3 = builder.WithDefaultValues().Id(3).Build();\n            items.Add(item3);\n\n            return items;\n        }\n    }\n}\n"
  },
  {
    "path": "tests/Clean.Architecture.UnitTests/GlobalUsings.cs",
    "content": "﻿global using System.Runtime.CompilerServices;\nglobal using Ardalis.SharedKernel;\nglobal using Clean.Architecture.Core.ContributorAggregate;\nglobal using Clean.Architecture.UseCases.Contributors.Create;\nglobal using Shouldly;\nglobal using Mediator;\nglobal using Microsoft.Extensions.Logging;\nglobal using NSubstitute;\nglobal using Xunit;\n"
  },
  {
    "path": "tests/Clean.Architecture.UnitTests/NoOpMediator.cs",
    "content": "﻿namespace Clean.Architecture.UnitTests;\n\npublic class NoOpMediator : IMediator\n{\n  public async Task<IAsyncEnumerable<TResponse>> CreateStream<TResponse>(IStreamQuery<TResponse> query, CancellationToken cancellationToken = default)\n  {\n    await Task.Delay(1);\n    return AsyncEnumerable.Empty<TResponse>();\n  }\n\n  public IAsyncEnumerable<TResponse> CreateStream<TResponse>(IStreamRequest<TResponse> request, CancellationToken cancellationToken = default)\n  {\n    return AsyncEnumerable.Empty<TResponse>();\n  }\n\n  public IAsyncEnumerable<TResponse> CreateStream<TResponse>(IStreamCommand<TResponse> command, CancellationToken cancellationToken = default)\n  {\n    return AsyncEnumerable.Empty<TResponse>();\n  }\n\n  public IAsyncEnumerable<object?> CreateStream(object message, CancellationToken cancellationToken = default)\n  {\n    return AsyncEnumerable.Empty<object?>();\n  }\n\n  public ValueTask Publish<TNotification>(TNotification notification, CancellationToken cancellationToken = default) where TNotification : INotification\n  {\n    return ValueTask.CompletedTask;\n  }\n\n  public ValueTask Publish(object notification, CancellationToken cancellationToken = default)\n  {\n    return ValueTask.CompletedTask;\n  }\n\n  public ValueTask<TResponse> Send<TResponse>(IRequest<TResponse> request, CancellationToken cancellationToken = default)\n  {\n    return ValueTask.FromResult(default(TResponse)!);\n  }\n\n  public ValueTask<TResponse> Send<TResponse>(ICommand<TResponse> command, CancellationToken cancellationToken = default)\n  {\n    return ValueTask.FromResult(default(TResponse)!);\n  }\n\n  public ValueTask<TResponse> Send<TResponse>(IQuery<TResponse> query, CancellationToken cancellationToken = default)\n  {\n    return ValueTask.FromResult(default(TResponse)!);\n  }\n\n  public ValueTask<object?> Send(object message, CancellationToken cancellationToken = default)\n  {\n    return ValueTask.FromResult<object?>(null);\n  }\n\n  IAsyncEnumerable<TResponse> ISender.CreateStream<TResponse>(IStreamQuery<TResponse> query, CancellationToken cancellationToken)\n  {\n    return AsyncEnumerable.Empty<TResponse>();\n  }\n}\n"
  },
  {
    "path": "tests/Clean.Architecture.UnitTests/UseCases/Contributors/CreateContributorHandlerHandle.cs",
    "content": "﻿namespace Clean.Architecture.UnitTests.UseCases.Contributors;\n\npublic class CreateContributorHandlerHandle\n{\n  private readonly ContributorName _testName = ContributorName.From(\"test name\");\n  private readonly IRepository<Contributor> _repository = Substitute.For<IRepository<Contributor>>();\n  private CreateContributorHandler _handler;\n\n  public CreateContributorHandlerHandle()\n  {\n    _handler = new CreateContributorHandler(_repository);\n  }\n\n  private Contributor CreateContributor()\n  {\n    return new Contributor(_testName);\n  }\n\n  [Fact]\n  public async Task ReturnsSuccessGivenValidName()\n  {\n    _repository.AddAsync(Arg.Any<Contributor>(), Arg.Any<CancellationToken>())\n      .Returns(Task.FromResult(CreateContributor()));\n    var result = await _handler.Handle(new CreateContributorCommand(_testName, null), CancellationToken.None);\n\n    result.IsSuccess.ShouldBeTrue();\n  }\n}\n"
  },
  {
    "path": "tests/Clean.Architecture.UnitTests/xunit.runner.json",
    "content": "﻿{\n  \"shadowCopy\": false,\n  \"parallelizeAssembly\": true,\n  \"parallelizeTestCollections\": true,\n  \"maxParallelThreads\": 0\n}"
  }
]