diff --git a/.gitignore b/.gitignore
index 3da5a0af1..bd5cf3810 100644
--- a/.gitignore
+++ b/.gitignore
@@ -273,9 +273,9 @@ Web/Resgrid.WebCore/wwwroot/lib/*
/Web/Resgrid.Web/wwwroot/lib
.dual-graph/
.claude/settings.local.json
-/Web/Resgrid.Web/wwwroot/js/ng/chunks
opencode.json
.dual-graph-pro/
.mcp.json
/.codex
/.claude
+/Web/Resgrid.Web/wwwroot/js/ng
diff --git a/Core/Resgrid.Localization/Areas/User/Home/EditProfile.ar.resx b/Core/Resgrid.Localization/Areas/User/Home/EditProfile.ar.resx
index 3230aacd5..62285da01 100644
--- a/Core/Resgrid.Localization/Areas/User/Home/EditProfile.ar.resx
+++ b/Core/Resgrid.Localization/Areas/User/Home/EditProfile.ar.resx
@@ -105,6 +105,9 @@
نجح التحقق.
فشل التحقق. يُرجى التحقق من الرمز والمحاولة مجدداً.
محاولات تحقق كثيرة جداً. يُرجى المحاولة لاحقاً.
+ طريقة الاتصال المحددة غير مهيأة.
+ طريقة الاتصال المحددة غير صالحة لإرسال رمز التحقق.
+ تعذر إرسال رمز التحقق. يُرجى المحاولة مرة أخرى.
متطلبات كلمة المرور
على الأقل {0} أحرف
رقم واحد على الأقل
diff --git a/Core/Resgrid.Localization/Areas/User/Home/EditProfile.de.resx b/Core/Resgrid.Localization/Areas/User/Home/EditProfile.de.resx
index f3daf7c67..f0e4ce041 100644
--- a/Core/Resgrid.Localization/Areas/User/Home/EditProfile.de.resx
+++ b/Core/Resgrid.Localization/Areas/User/Home/EditProfile.de.resx
@@ -365,6 +365,15 @@
Too many verification attempts. Please try again later.
+
+ The selected contact method is not configured.
+
+
+ The selected contact method is not valid for verification delivery.
+
+
+ Unable to deliver the verification code. Please try again.
+
Passwortanforderungen
diff --git a/Core/Resgrid.Localization/Areas/User/Home/EditProfile.en.resx b/Core/Resgrid.Localization/Areas/User/Home/EditProfile.en.resx
index bc3df66f8..889e43be8 100644
--- a/Core/Resgrid.Localization/Areas/User/Home/EditProfile.en.resx
+++ b/Core/Resgrid.Localization/Areas/User/Home/EditProfile.en.resx
@@ -420,6 +420,15 @@
Too many verification attempts. Please try again later.
+
+ The selected contact method is not configured.
+
+
+ The selected contact method is not valid for verification delivery.
+
+
+ Unable to deliver the verification code. Please try again.
+
Password Requirements
diff --git a/Core/Resgrid.Localization/Areas/User/Home/EditProfile.es.resx b/Core/Resgrid.Localization/Areas/User/Home/EditProfile.es.resx
index 3c4923b9b..536179197 100644
--- a/Core/Resgrid.Localization/Areas/User/Home/EditProfile.es.resx
+++ b/Core/Resgrid.Localization/Areas/User/Home/EditProfile.es.resx
@@ -411,6 +411,15 @@
Demasiados intentos de verificación. Por favor inténtelo más tarde.
+
+ El método de contacto seleccionado no está configurado.
+
+
+ El método de contacto seleccionado no es válido para recibir la verificación.
+
+
+ No se pudo enviar el código de verificación. Por favor, inténtelo de nuevo.
+
Requisitos de contraseña
diff --git a/Core/Resgrid.Localization/Areas/User/Home/EditProfile.fr.resx b/Core/Resgrid.Localization/Areas/User/Home/EditProfile.fr.resx
index ce77a177d..3dbf98d8c 100644
--- a/Core/Resgrid.Localization/Areas/User/Home/EditProfile.fr.resx
+++ b/Core/Resgrid.Localization/Areas/User/Home/EditProfile.fr.resx
@@ -365,6 +365,15 @@
Too many verification attempts. Please try again later.
+
+ The selected contact method is not configured.
+
+
+ The selected contact method is not valid for verification delivery.
+
+
+ Unable to deliver the verification code. Please try again.
+
Exigences du mot de passe
diff --git a/Core/Resgrid.Localization/Areas/User/Home/EditProfile.it.resx b/Core/Resgrid.Localization/Areas/User/Home/EditProfile.it.resx
index 8cae8ccb2..87490d367 100644
--- a/Core/Resgrid.Localization/Areas/User/Home/EditProfile.it.resx
+++ b/Core/Resgrid.Localization/Areas/User/Home/EditProfile.it.resx
@@ -365,6 +365,15 @@
Too many verification attempts. Please try again later.
+
+ The selected contact method is not configured.
+
+
+ The selected contact method is not valid for verification delivery.
+
+
+ Unable to deliver the verification code. Please try again.
+
Requisiti della password
diff --git a/Core/Resgrid.Localization/Areas/User/Home/EditProfile.pl.resx b/Core/Resgrid.Localization/Areas/User/Home/EditProfile.pl.resx
index 1ac1d80e1..15551c1c3 100644
--- a/Core/Resgrid.Localization/Areas/User/Home/EditProfile.pl.resx
+++ b/Core/Resgrid.Localization/Areas/User/Home/EditProfile.pl.resx
@@ -365,6 +365,15 @@
Too many verification attempts. Please try again later.
+
+ The selected contact method is not configured.
+
+
+ The selected contact method is not valid for verification delivery.
+
+
+ Unable to deliver the verification code. Please try again.
+
Wymagania dotyczące hasła
diff --git a/Core/Resgrid.Localization/Areas/User/Home/EditProfile.sv.resx b/Core/Resgrid.Localization/Areas/User/Home/EditProfile.sv.resx
index 5eef10d52..cb6812b51 100644
--- a/Core/Resgrid.Localization/Areas/User/Home/EditProfile.sv.resx
+++ b/Core/Resgrid.Localization/Areas/User/Home/EditProfile.sv.resx
@@ -365,6 +365,15 @@
Too many verification attempts. Please try again later.
+
+ The selected contact method is not configured.
+
+
+ The selected contact method is not valid for verification delivery.
+
+
+ Unable to deliver the verification code. Please try again.
+
Lösenordskrav
diff --git a/Core/Resgrid.Localization/Areas/User/Home/EditProfile.uk.resx b/Core/Resgrid.Localization/Areas/User/Home/EditProfile.uk.resx
index 620be50f6..3f1d4c5d7 100644
--- a/Core/Resgrid.Localization/Areas/User/Home/EditProfile.uk.resx
+++ b/Core/Resgrid.Localization/Areas/User/Home/EditProfile.uk.resx
@@ -365,6 +365,15 @@
Too many verification attempts. Please try again later.
+
+ The selected contact method is not configured.
+
+
+ The selected contact method is not valid for verification delivery.
+
+
+ Unable to deliver the verification code. Please try again.
+
Вимоги до пароля
diff --git a/Core/Resgrid.Model/ContactVerificationSendStatus.cs b/Core/Resgrid.Model/ContactVerificationSendStatus.cs
new file mode 100644
index 000000000..326f55bf0
--- /dev/null
+++ b/Core/Resgrid.Model/ContactVerificationSendStatus.cs
@@ -0,0 +1,14 @@
+namespace Resgrid.Model
+{
+ ///
+ /// Describes the outcome of a request to send a contact verification code.
+ ///
+ public enum ContactVerificationSendStatus
+ {
+ Sent = 0,
+ ContactNotConfigured = 1,
+ InvalidContact = 2,
+ RateLimited = 3,
+ DeliveryFailed = 4
+ }
+}
diff --git a/Core/Resgrid.Model/Services/IContactVerificationService.cs b/Core/Resgrid.Model/Services/IContactVerificationService.cs
index 616ae89b6..e30119502 100644
--- a/Core/Resgrid.Model/Services/IContactVerificationService.cs
+++ b/Core/Resgrid.Model/Services/IContactVerificationService.cs
@@ -12,25 +12,22 @@ public interface IContactVerificationService
{
///
/// Generates a verification code and sends it to the user's email address.
- /// Returns false if the user has no email, if rate limits are exceeded,
- /// or if the send fails.
+ /// Returns a status describing whether the code was sent or why it could not be sent.
///
- Task SendEmailVerificationCodeAsync(string userId, int departmentId, CancellationToken cancellationToken = default);
+ Task SendEmailVerificationCodeAsync(string userId, int departmentId, CancellationToken cancellationToken = default);
///
/// Generates a verification code and sends it via SMS to the user's mobile number.
- /// Returns false if the user has no mobile number, if rate limits are exceeded,
- /// or if the send fails.
+ /// Returns a status describing whether the code was sent or why it could not be sent.
///
- Task SendMobileVerificationCodeAsync(string userId, int departmentId, string departmentNumber, CancellationToken cancellationToken = default);
+ Task SendMobileVerificationCodeAsync(string userId, int departmentId, string departmentNumber, CancellationToken cancellationToken = default);
///
/// Generates a verification code and delivers it via a Twilio voice call to the
/// user's home number, speaking the digits and repeating multiple times.
- /// Returns false if the user has no home number, if rate limits are exceeded,
- /// or if the call fails.
+ /// Returns a status describing whether the call was placed or why it could not be placed.
///
- Task SendHomeVerificationCodeAsync(string userId, int departmentId, string departmentNumber, CancellationToken cancellationToken = default);
+ Task SendHomeVerificationCodeAsync(string userId, int departmentId, string departmentNumber, CancellationToken cancellationToken = default);
///
/// Validates the supplied against the stored code for the given
diff --git a/Core/Resgrid.Model/UserProfile.cs b/Core/Resgrid.Model/UserProfile.cs
index c3f100026..b5ec04cf5 100644
--- a/Core/Resgrid.Model/UserProfile.cs
+++ b/Core/Resgrid.Model/UserProfile.cs
@@ -205,6 +205,26 @@ public class UserProfile: IEntity
[ProtoMember(53)]
public bool EnableModernApplicationSounds { get; set; }
+ // ── Verification send-window tracking (separate from the daily confirm-attempt counters) ──
+
+ [ProtoMember(54)]
+ public int EmailVerificationSendCount { get; set; }
+
+ [ProtoMember(55)]
+ public int MobileVerificationSendCount { get; set; }
+
+ [ProtoMember(56)]
+ public int HomeVerificationSendCount { get; set; }
+
+ [ProtoMember(57)]
+ public DateTime? EmailVerificationSendWindowStart { get; set; }
+
+ [ProtoMember(58)]
+ public DateTime? MobileVerificationSendWindowStart { get; set; }
+
+ [ProtoMember(59)]
+ public DateTime? HomeVerificationSendWindowStart { get; set; }
+
[NotMapped]
[JsonIgnore]
public object IdValue
diff --git a/Core/Resgrid.Services/ContactVerificationService.cs b/Core/Resgrid.Services/ContactVerificationService.cs
index c4848f80c..482b9a5a5 100644
--- a/Core/Resgrid.Services/ContactVerificationService.cs
+++ b/Core/Resgrid.Services/ContactVerificationService.cs
@@ -44,25 +44,28 @@ public ContactVerificationService(
_phoneNumberProcesser = phoneNumberProcesser;
}
- public async Task SendEmailVerificationCodeAsync(string userId, int departmentId, CancellationToken cancellationToken = default)
+ public async Task SendEmailVerificationCodeAsync(string userId, int departmentId, CancellationToken cancellationToken = default)
{
var profile = await _userProfileService.GetProfileByUserIdAsync(userId, bypassCache: true);
if (profile == null)
- return false;
+ return ContactVerificationSendStatus.ContactNotConfigured;
var user = _usersService.GetUserById(userId);
if (user == null)
- return false;
+ return ContactVerificationSendStatus.ContactNotConfigured;
string emailAddress = !string.IsNullOrWhiteSpace(profile.MembershipEmail)
? profile.MembershipEmail
: user.Email;
if (string.IsNullOrWhiteSpace(emailAddress))
- return false;
+ return ContactVerificationSendStatus.ContactNotConfigured;
- if (!IsWithinHourlySendLimit(profile.EmailVerificationCodeExpiry, profile.EmailVerificationAttempts))
- return false;
+ if (!TryRecordSend(profile.EmailVerificationSendWindowStart, profile.EmailVerificationSendCount, out DateTime emailWindowStart, out int emailSendCount))
+ return ContactVerificationSendStatus.RateLimited;
+
+ profile.EmailVerificationSendWindowStart = emailWindowStart;
+ profile.EmailVerificationSendCount = emailSendCount;
string code = GenerateCode();
profile.EmailVerificationCode = _encryptionService.Encrypt(code);
@@ -74,27 +77,30 @@ public async Task SendEmailVerificationCodeAsync(string userId, int depart
await WriteAuditAsync(userId, departmentId, ContactVerificationType.Email, sent, "Send", null, cancellationToken);
- return sent;
+ return sent ? ContactVerificationSendStatus.Sent : ContactVerificationSendStatus.DeliveryFailed;
}
- public async Task SendMobileVerificationCodeAsync(string userId, int departmentId, string departmentNumber, CancellationToken cancellationToken = default)
+ public async Task SendMobileVerificationCodeAsync(string userId, int departmentId, string departmentNumber, CancellationToken cancellationToken = default)
{
var profile = await _userProfileService.GetProfileByUserIdAsync(userId, bypassCache: true);
if (profile == null || string.IsNullOrWhiteSpace(profile.MobileNumber))
- return false;
+ return ContactVerificationSendStatus.ContactNotConfigured;
// Normalize to E.164 and validate before sending so an invalid/local-format number (e.g. a bare
// "082446..." with no country code) is rejected here instead of throwing a Twilio "Invalid 'To'" error.
- var mobileResult = _phoneNumberProcesser.Process(profile.GetPhoneNumber());
+ var mobileResult = _phoneNumberProcesser.Process(profile.MobileNumber);
if (mobileResult == null || !mobileResult.IsValid || string.IsNullOrWhiteSpace(mobileResult.InternationalNumber))
{
Logging.LogInfo($"Mobile verification SMS skipped for user {userId}: phone number is not a valid sendable number (needs international format, e.g. +).");
await WriteAuditAsync(userId, departmentId, ContactVerificationType.MobileNumber, false, "Send-InvalidNumber", null, cancellationToken);
- return false;
+ return ContactVerificationSendStatus.InvalidContact;
}
- if (!IsWithinHourlySendLimit(profile.MobileVerificationCodeExpiry, profile.MobileVerificationAttempts))
- return false;
+ if (!TryRecordSend(profile.MobileVerificationSendWindowStart, profile.MobileVerificationSendCount, out DateTime mobileWindowStart, out int mobileSendCount))
+ return ContactVerificationSendStatus.RateLimited;
+
+ profile.MobileVerificationSendWindowStart = mobileWindowStart;
+ profile.MobileVerificationSendCount = mobileSendCount;
string code = GenerateCode();
profile.MobileVerificationCode = _encryptionService.Encrypt(code);
@@ -107,26 +113,29 @@ public async Task SendMobileVerificationCodeAsync(string userId, int depar
await WriteAuditAsync(userId, departmentId, ContactVerificationType.MobileNumber, sent, "Send", null, cancellationToken);
- return sent;
+ return sent ? ContactVerificationSendStatus.Sent : ContactVerificationSendStatus.DeliveryFailed;
}
- public async Task SendHomeVerificationCodeAsync(string userId, int departmentId, string departmentNumber, CancellationToken cancellationToken = default)
+ public async Task SendHomeVerificationCodeAsync(string userId, int departmentId, string departmentNumber, CancellationToken cancellationToken = default)
{
var profile = await _userProfileService.GetProfileByUserIdAsync(userId, bypassCache: true);
if (profile == null || string.IsNullOrWhiteSpace(profile.HomeNumber))
- return false;
+ return ContactVerificationSendStatus.ContactNotConfigured;
// Validate/normalize before placing the Twilio voice call so an invalid number doesn't throw "Invalid 'To'".
- var homeResult = _phoneNumberProcesser.Process(profile.GetHomePhoneNumber());
+ var homeResult = _phoneNumberProcesser.Process(profile.HomeNumber);
if (homeResult == null || !homeResult.IsValid || string.IsNullOrWhiteSpace(homeResult.InternationalNumber))
{
Logging.LogInfo($"Home verification call skipped for user {userId}: phone number is not a valid sendable number.");
await WriteAuditAsync(userId, departmentId, ContactVerificationType.HomeNumber, false, "SendVoice-InvalidNumber", null, cancellationToken);
- return false;
+ return ContactVerificationSendStatus.InvalidContact;
}
- if (!IsWithinHourlySendLimit(profile.HomeVerificationCodeExpiry, profile.HomeVerificationAttempts))
- return false;
+ if (!TryRecordSend(profile.HomeVerificationSendWindowStart, profile.HomeVerificationSendCount, out DateTime homeWindowStart, out int homeSendCount))
+ return ContactVerificationSendStatus.RateLimited;
+
+ profile.HomeVerificationSendWindowStart = homeWindowStart;
+ profile.HomeVerificationSendCount = homeSendCount;
string code = GenerateCode();
profile.HomeVerificationCode = _encryptionService.Encrypt(code);
@@ -143,7 +152,7 @@ public async Task SendHomeVerificationCodeAsync(string userId, int departm
await WriteAuditAsync(userId, departmentId, ContactVerificationType.HomeNumber, sent, "SendVoice", null, cancellationToken);
- return sent;
+ return sent ? ContactVerificationSendStatus.Sent : ContactVerificationSendStatus.DeliveryFailed;
}
public async Task ConfirmVerificationCodeAsync(string userId, int departmentId, ContactVerificationType type, string code, string ipAddress = null, CancellationToken cancellationToken = default)
@@ -297,6 +306,8 @@ public Task ResetVerificationForChangedContactAsync(UserProfile existingProfile,
updatedProfile.MobileVerificationVoiceCodeConsumed = false;
updatedProfile.MobileVerificationAttempts = 0;
updatedProfile.MobileVerificationAttemptsResetDate = null;
+ updatedProfile.MobileVerificationSendCount = 0;
+ updatedProfile.MobileVerificationSendWindowStart = null;
}
if (!string.Equals(existingProfile.HomeNumber ?? string.Empty, updatedProfile.HomeNumber ?? string.Empty, StringComparison.OrdinalIgnoreCase))
@@ -307,6 +318,8 @@ public Task ResetVerificationForChangedContactAsync(UserProfile existingProfile,
updatedProfile.HomeVerificationVoiceCodeConsumed = false;
updatedProfile.HomeVerificationAttempts = 0;
updatedProfile.HomeVerificationAttemptsResetDate = null;
+ updatedProfile.HomeVerificationSendCount = 0;
+ updatedProfile.HomeVerificationSendWindowStart = null;
}
if (!string.Equals(existingProfile.MembershipEmail ?? string.Empty, updatedProfile.MembershipEmail ?? string.Empty, StringComparison.OrdinalIgnoreCase))
@@ -316,6 +329,8 @@ public Task ResetVerificationForChangedContactAsync(UserProfile existingProfile,
updatedProfile.EmailVerificationCodeExpiry = null;
updatedProfile.EmailVerificationAttempts = 0;
updatedProfile.EmailVerificationAttemptsResetDate = null;
+ updatedProfile.EmailVerificationSendCount = 0;
+ updatedProfile.EmailVerificationSendWindowStart = null;
}
return Task.CompletedTask;
@@ -336,22 +351,34 @@ private static string GenerateCode()
}
///
- /// Returns true if a new send is allowed, based on the current code expiry window
- /// acting as a proxy for the hourly send count. A new send is blocked if there is already
- /// a valid (non-expired) code and the slot count would exceed the hourly limit.
- /// In practice, with VerificationCodeExpiryMinutes=30 and MaxVerificationSendsPerHour=3,
- /// a user can send up to 3 codes within a 60-minute window.
+ /// Enforces the hourly send cap using dedicated send-window state, kept separate from the
+ /// daily confirm-attempt counters used by .
+ /// Returns false when
+ /// has been reached inside the current one-hour window; otherwise returns true with the
+ /// updated window start and send count, which the caller must persist before delivering the code
+ /// so the send is recorded even if delivery fails.
///
- private static bool IsWithinHourlySendLimit(DateTime? codeExpiry, int existingAttempts)
+ private static bool TryRecordSend(DateTime? windowStart, int sendCount, out DateTime newWindowStart, out int newSendCount)
{
- // If the existing code hasn't expired yet AND we've already reached the send cap, block.
- if (codeExpiry.HasValue
- && DateTime.UtcNow < codeExpiry.Value
- && existingAttempts >= Config.VerificationConfig.MaxVerificationSendsPerHour)
+ DateTime now = DateTime.UtcNow;
+
+ if (!windowStart.HasValue || now - windowStart.Value >= TimeSpan.FromHours(1))
+ {
+ // No window yet, or the previous window has elapsed — start a new one.
+ newWindowStart = now;
+ newSendCount = 1;
+ return true;
+ }
+
+ newWindowStart = windowStart.Value;
+
+ if (sendCount >= Config.VerificationConfig.MaxVerificationSendsPerHour)
{
+ newSendCount = sendCount;
return false;
}
+ newSendCount = sendCount + 1;
return true;
}
diff --git a/Providers/Resgrid.Providers.Migrations/Migrations/M0110_AddingVerificationSendWindows.cs b/Providers/Resgrid.Providers.Migrations/Migrations/M0110_AddingVerificationSendWindows.cs
new file mode 100644
index 000000000..108aab674
--- /dev/null
+++ b/Providers/Resgrid.Providers.Migrations/Migrations/M0110_AddingVerificationSendWindows.cs
@@ -0,0 +1,29 @@
+using FluentMigrator;
+
+namespace Resgrid.Providers.Migrations.Migrations
+{
+ [Migration(110)]
+ public class M0110_AddingVerificationSendWindows : Migration
+ {
+ public override void Up()
+ {
+ Alter.Table("UserProfiles")
+ .AddColumn("EmailVerificationSendCount").AsInt32().NotNullable().WithDefaultValue(0)
+ .AddColumn("MobileVerificationSendCount").AsInt32().NotNullable().WithDefaultValue(0)
+ .AddColumn("HomeVerificationSendCount").AsInt32().NotNullable().WithDefaultValue(0)
+ .AddColumn("EmailVerificationSendWindowStart").AsDateTime().Nullable()
+ .AddColumn("MobileVerificationSendWindowStart").AsDateTime().Nullable()
+ .AddColumn("HomeVerificationSendWindowStart").AsDateTime().Nullable();
+ }
+
+ public override void Down()
+ {
+ Delete.Column("EmailVerificationSendCount").FromTable("UserProfiles");
+ Delete.Column("MobileVerificationSendCount").FromTable("UserProfiles");
+ Delete.Column("HomeVerificationSendCount").FromTable("UserProfiles");
+ Delete.Column("EmailVerificationSendWindowStart").FromTable("UserProfiles");
+ Delete.Column("MobileVerificationSendWindowStart").FromTable("UserProfiles");
+ Delete.Column("HomeVerificationSendWindowStart").FromTable("UserProfiles");
+ }
+ }
+}
diff --git a/Providers/Resgrid.Providers.MigrationsPg/Migrations/M0110_AddingVerificationSendWindowsPg.cs b/Providers/Resgrid.Providers.MigrationsPg/Migrations/M0110_AddingVerificationSendWindowsPg.cs
new file mode 100644
index 000000000..66d0a1de7
--- /dev/null
+++ b/Providers/Resgrid.Providers.MigrationsPg/Migrations/M0110_AddingVerificationSendWindowsPg.cs
@@ -0,0 +1,29 @@
+using FluentMigrator;
+
+namespace Resgrid.Providers.MigrationsPg.Migrations
+{
+ [Migration(110)]
+ public class M0110_AddingVerificationSendWindowsPg : Migration
+ {
+ public override void Up()
+ {
+ Alter.Table("UserProfiles".ToLower())
+ .AddColumn("EmailVerificationSendCount".ToLower()).AsInt32().NotNullable().WithDefaultValue(0)
+ .AddColumn("MobileVerificationSendCount".ToLower()).AsInt32().NotNullable().WithDefaultValue(0)
+ .AddColumn("HomeVerificationSendCount".ToLower()).AsInt32().NotNullable().WithDefaultValue(0)
+ .AddColumn("EmailVerificationSendWindowStart".ToLower()).AsDateTime().Nullable()
+ .AddColumn("MobileVerificationSendWindowStart".ToLower()).AsDateTime().Nullable()
+ .AddColumn("HomeVerificationSendWindowStart".ToLower()).AsDateTime().Nullable();
+ }
+
+ public override void Down()
+ {
+ Delete.Column("EmailVerificationSendCount".ToLower()).FromTable("UserProfiles".ToLower());
+ Delete.Column("MobileVerificationSendCount".ToLower()).FromTable("UserProfiles".ToLower());
+ Delete.Column("HomeVerificationSendCount".ToLower()).FromTable("UserProfiles".ToLower());
+ Delete.Column("EmailVerificationSendWindowStart".ToLower()).FromTable("UserProfiles".ToLower());
+ Delete.Column("MobileVerificationSendWindowStart".ToLower()).FromTable("UserProfiles".ToLower());
+ Delete.Column("HomeVerificationSendWindowStart".ToLower()).FromTable("UserProfiles".ToLower());
+ }
+ }
+}
diff --git a/Tests/Resgrid.Tests/Services/ContactVerificationServiceTests.cs b/Tests/Resgrid.Tests/Services/ContactVerificationServiceTests.cs
index 8ea104bf5..db342859e 100644
--- a/Tests/Resgrid.Tests/Services/ContactVerificationServiceTests.cs
+++ b/Tests/Resgrid.Tests/Services/ContactVerificationServiceTests.cs
@@ -26,7 +26,8 @@ public class with_the_contact_verification_service : TestBase
protected Mock _phoneNumberProcesserMock;
protected IContactVerificationService _contactVerificationService;
- protected with_the_contact_verification_service()
+ [SetUp]
+ public void SetUp()
{
_userProfileServiceMock = new Mock();
_usersServiceMock = new Mock();
@@ -112,21 +113,129 @@ public async Task should_generate_code_and_send_email()
var result = await _contactVerificationService.SendEmailVerificationCodeAsync("user1", 1);
- result.Should().BeTrue();
+ result.Should().Be(ContactVerificationSendStatus.Sent);
savedProfile.Should().NotBeNull();
// The service encrypts the code before persisting; verify the stored value is ciphertext.
savedProfile.EmailVerificationCode.Should().StartWith("ENC:");
savedProfile.EmailVerificationCodeExpiry.Should().NotBeNull();
savedProfile.EmailVerificationCodeExpiry!.Value.Should().BeAfter(DateTime.UtcNow);
+ // The send is recorded in dedicated send-window state, persisted before delivery.
+ savedProfile.EmailVerificationSendCount.Should().Be(1);
+ savedProfile.EmailVerificationSendWindowStart.Should().NotBeNull();
+ }
+
+ [Test]
+ public async Task should_allow_send_and_reset_count_after_window_elapses()
+ {
+ var profile = BuildProfile();
+ profile.EmailVerificationSendWindowStart = DateTime.UtcNow.AddMinutes(-61); // window elapsed
+ profile.EmailVerificationSendCount = Resgrid.Config.VerificationConfig.MaxVerificationSendsPerHour;
+ UserProfile savedProfile = null;
+
+ _userProfileServiceMock
+ .Setup(s => s.GetProfileByUserIdAsync("user1", true))
+ .ReturnsAsync(profile);
+ _usersServiceMock
+ .Setup(s => s.GetUserById("user1", true))
+ .Returns(new IdentityUser { Email = "user@example.com" });
+ _userProfileServiceMock
+ .Setup(s => s.SaveProfileAsync(It.IsAny(), It.IsAny(), It.IsAny()))
+ .Callback((_, p, _) => savedProfile = p)
+ .ReturnsAsync(profile);
+ _emailServiceMock
+ .Setup(e => e.SendEmailVerificationCodeAsync(It.IsAny(), It.IsAny(), It.IsAny()))
+ .ReturnsAsync(true);
+
+ var result = await _contactVerificationService.SendEmailVerificationCodeAsync("user1", 1);
+
+ result.Should().Be(ContactVerificationSendStatus.Sent);
+ savedProfile!.EmailVerificationSendCount.Should().Be(1);
+ savedProfile.EmailVerificationSendWindowStart!.Value.Should().BeAfter(DateTime.UtcNow.AddMinutes(-1));
+ }
+
+ [Test]
+ public async Task should_not_block_sends_based_on_confirm_attempt_counters()
+ {
+ // Confirm-attempt state at its daily cap must not affect the send flow.
+ var profile = BuildProfile();
+ profile.EmailVerificationAttempts = Resgrid.Config.VerificationConfig.MaxVerificationAttemptsPerDay;
+ profile.EmailVerificationCodeExpiry = DateTime.UtcNow.AddMinutes(10);
+
+ _userProfileServiceMock
+ .Setup(s => s.GetProfileByUserIdAsync("user1", true))
+ .ReturnsAsync(profile);
+ _usersServiceMock
+ .Setup(s => s.GetUserById("user1", true))
+ .Returns(new IdentityUser { Email = "user@example.com" });
+ _userProfileServiceMock
+ .Setup(s => s.SaveProfileAsync(It.IsAny(), It.IsAny(), It.IsAny()))
+ .ReturnsAsync(profile);
+ _emailServiceMock
+ .Setup(e => e.SendEmailVerificationCodeAsync(It.IsAny(), It.IsAny(), It.IsAny()))
+ .ReturnsAsync(true);
+
+ var result = await _contactVerificationService.SendEmailVerificationCodeAsync("user1", 1);
+
+ result.Should().Be(ContactVerificationSendStatus.Sent);
}
}
[TestFixture]
public class when_sending_phone_verification : with_the_contact_verification_service
{
+ [Test]
+ public async Task should_preserve_international_mobile_number_when_validating_and_sending()
+ {
+ // Arrange
+ const string phoneNumber = "+447700900123";
+ var profile = BuildProfile(mobile: phoneNumber);
+ _userProfileServiceMock
+ .Setup(s => s.GetProfileByUserIdAsync("user1", true))
+ .ReturnsAsync(profile);
+ _userProfileServiceMock
+ .Setup(s => s.SaveProfileAsync(It.IsAny(), It.IsAny(), It.IsAny()))
+ .ReturnsAsync(profile);
+ _smsServiceMock
+ .Setup(s => s.SendSmsVerificationCodeAsync(phoneNumber, It.IsAny(), It.IsAny()))
+ .ReturnsAsync(true);
+
+ // Act
+ var result = await _contactVerificationService.SendMobileVerificationCodeAsync("user1", 1, "15555550123");
+
+ // Assert
+ result.Should().Be(ContactVerificationSendStatus.Sent);
+ _phoneNumberProcesserMock.Verify(p => p.Process(phoneNumber, null), Times.Once);
+ _smsServiceMock.Verify(s => s.SendSmsVerificationCodeAsync(phoneNumber, It.IsAny(), "15555550123"), Times.Once);
+ }
+
+ [Test]
+ public async Task should_preserve_international_home_number_when_validating_and_calling()
+ {
+ // Arrange
+ const string phoneNumber = "+447700900123";
+ var profile = BuildProfile(home: phoneNumber);
+ _userProfileServiceMock
+ .Setup(s => s.GetProfileByUserIdAsync("user1", true))
+ .ReturnsAsync(profile);
+ _userProfileServiceMock
+ .Setup(s => s.SaveProfileAsync(It.IsAny(), It.IsAny(), It.IsAny()))
+ .ReturnsAsync(profile);
+
+ // Act
+ var result = await _contactVerificationService.SendHomeVerificationCodeAsync("user1", 1, "15555550123");
+
+ // Assert
+ result.Should().Be(ContactVerificationSendStatus.Sent);
+ _phoneNumberProcesserMock.Verify(p => p.Process(phoneNumber, null), Times.Once);
+ _outboundVoiceProviderMock.Verify(
+ v => v.SendVoiceVerificationCallAsync(phoneNumber, "user1", (int)ContactVerificationType.HomeNumber),
+ Times.Once);
+ }
+
[Test]
public async Task should_reset_home_voice_consumption_when_sending_a_new_home_code()
{
+ // Arrange
var profile = BuildProfile();
profile.HomeVerificationVoiceCodeConsumed = true;
UserProfile savedProfile = null;
@@ -139,12 +248,79 @@ public async Task should_reset_home_voice_consumption_when_sending_a_new_home_co
.Callback((_, p, _) => savedProfile = p)
.ReturnsAsync(profile);
+ // Act
var result = await _contactVerificationService.SendHomeVerificationCodeAsync("user1", 1, "15555550123");
- result.Should().BeTrue();
+ // Assert
+ result.Should().Be(ContactVerificationSendStatus.Sent);
savedProfile.Should().NotBeNull();
savedProfile!.HomeVerificationVoiceCodeConsumed.Should().BeFalse();
}
+
+ [Test]
+ public async Task should_return_invalid_contact_when_home_number_cannot_be_parsed()
+ {
+ // Arrange
+ var profile = BuildProfile(home: "+447700900123");
+ _userProfileServiceMock
+ .Setup(s => s.GetProfileByUserIdAsync("user1", true))
+ .ReturnsAsync(profile);
+ _phoneNumberProcesserMock
+ .Setup(p => p.Process(profile.HomeNumber, It.IsAny()))
+ .Returns(new PhoneNumberResult { IsValid = false });
+
+ // Act
+ var result = await _contactVerificationService.SendHomeVerificationCodeAsync("user1", 1, "15555550123");
+
+ // Assert
+ result.Should().Be(ContactVerificationSendStatus.InvalidContact);
+ _outboundVoiceProviderMock.Verify(
+ v => v.SendVoiceVerificationCallAsync(It.IsAny(), It.IsAny(), It.IsAny()),
+ Times.Never);
+ }
+
+ [Test]
+ public async Task should_return_rate_limited_when_home_send_limit_is_reached()
+ {
+ // Arrange
+ var profile = BuildProfile();
+ profile.HomeVerificationSendWindowStart = DateTime.UtcNow.AddMinutes(-10);
+ profile.HomeVerificationSendCount = Resgrid.Config.VerificationConfig.MaxVerificationSendsPerHour;
+ _userProfileServiceMock
+ .Setup(s => s.GetProfileByUserIdAsync("user1", true))
+ .ReturnsAsync(profile);
+
+ // Act
+ var result = await _contactVerificationService.SendHomeVerificationCodeAsync("user1", 1, "15555550123");
+
+ // Assert
+ result.Should().Be(ContactVerificationSendStatus.RateLimited);
+ _outboundVoiceProviderMock.Verify(
+ v => v.SendVoiceVerificationCallAsync(It.IsAny(), It.IsAny(), It.IsAny()),
+ Times.Never);
+ }
+
+ [Test]
+ public async Task should_return_delivery_failed_when_home_call_cannot_be_placed()
+ {
+ // Arrange
+ var profile = BuildProfile();
+ _userProfileServiceMock
+ .Setup(s => s.GetProfileByUserIdAsync("user1", true))
+ .ReturnsAsync(profile);
+ _userProfileServiceMock
+ .Setup(s => s.SaveProfileAsync(It.IsAny(), It.IsAny(), It.IsAny()))
+ .ReturnsAsync(profile);
+ _outboundVoiceProviderMock
+ .Setup(v => v.SendVoiceVerificationCallAsync(It.IsAny(), It.IsAny(), It.IsAny()))
+ .ReturnsAsync(false);
+
+ // Act
+ var result = await _contactVerificationService.SendHomeVerificationCodeAsync("user1", 1, "15555550123");
+
+ // Assert
+ result.Should().Be(ContactVerificationSendStatus.DeliveryFailed);
+ }
}
[TestFixture]
diff --git a/Web/Resgrid.Web.Services/Controllers/v4/ContactVerificationController.cs b/Web/Resgrid.Web.Services/Controllers/v4/ContactVerificationController.cs
index 34f7812ce..d92b2bc85 100644
--- a/Web/Resgrid.Web.Services/Controllers/v4/ContactVerificationController.cs
+++ b/Web/Resgrid.Web.Services/Controllers/v4/ContactVerificationController.cs
@@ -45,36 +45,58 @@ public async Task> SendVerificationCode
if (!ModelState.IsValid)
return BadRequest();
- bool sent;
+ ContactVerificationSendStatus sendStatus;
switch (model.Type)
{
case ContactVerificationType.Email:
- sent = await _contactVerificationService.SendEmailVerificationCodeAsync(UserId, DepartmentId, cancellationToken);
+ sendStatus = await _contactVerificationService.SendEmailVerificationCodeAsync(UserId, DepartmentId, cancellationToken);
break;
case ContactVerificationType.MobileNumber:
var mobileDepNumber = model.DepartmentNumber
?? await _departmentSettingsService.GetTextToCallNumberForDepartmentAsync(DepartmentId);
- sent = await _contactVerificationService.SendMobileVerificationCodeAsync(UserId, DepartmentId, mobileDepNumber, cancellationToken);
+ sendStatus = await _contactVerificationService.SendMobileVerificationCodeAsync(UserId, DepartmentId, mobileDepNumber, cancellationToken);
break;
case ContactVerificationType.HomeNumber:
var homeDepNumber = model.DepartmentNumber
?? await _departmentSettingsService.GetTextToCallNumberForDepartmentAsync(DepartmentId);
- sent = await _contactVerificationService.SendHomeVerificationCodeAsync(UserId, DepartmentId, homeDepNumber, cancellationToken);
+ sendStatus = await _contactVerificationService.SendHomeVerificationCodeAsync(UserId, DepartmentId, homeDepNumber, cancellationToken);
break;
default:
return BadRequest();
}
- if (!sent)
- return Ok(new SendVerificationCodeResult { Successful = false, ErrorMessage = "Unable to send verification code. You may have exceeded the rate limit or the contact method is not set." });
+ if (sendStatus != ContactVerificationSendStatus.Sent)
+ {
+ return Ok(new SendVerificationCodeResult
+ {
+ Successful = false,
+ ErrorCode = sendStatus.ToString(),
+ ErrorMessage = GetSendErrorMessage(sendStatus)
+ });
+ }
return Ok(new SendVerificationCodeResult { Successful = true });
}
+ private static string GetSendErrorMessage(ContactVerificationSendStatus sendStatus)
+ {
+ switch (sendStatus)
+ {
+ case ContactVerificationSendStatus.ContactNotConfigured:
+ return "The selected contact method is not configured.";
+ case ContactVerificationSendStatus.InvalidContact:
+ return "The selected contact method is not valid for verification delivery.";
+ case ContactVerificationSendStatus.RateLimited:
+ return "Too many verification attempts. Please try again later.";
+ default:
+ return "Unable to deliver the verification code. Please try again.";
+ }
+ }
+
///
/// Confirms a verification code previously sent to the specified contact method.
///
diff --git a/Web/Resgrid.Web.Services/Models/v4/ContactVerification/ContactVerificationModels.cs b/Web/Resgrid.Web.Services/Models/v4/ContactVerification/ContactVerificationModels.cs
index 1390ea26d..bc99a8550 100644
--- a/Web/Resgrid.Web.Services/Models/v4/ContactVerification/ContactVerificationModels.cs
+++ b/Web/Resgrid.Web.Services/Models/v4/ContactVerification/ContactVerificationModels.cs
@@ -19,6 +19,7 @@ public class SendVerificationCodeInput
public class SendVerificationCodeResult
{
public bool Successful { get; set; }
+ public string ErrorCode { get; set; }
public string ErrorMessage { get; set; }
}
diff --git a/Web/Resgrid.Web/Areas/User/Controllers/HomeController.cs b/Web/Resgrid.Web/Areas/User/Controllers/HomeController.cs
index 1699e48ed..744dab20e 100644
--- a/Web/Resgrid.Web/Areas/User/Controllers/HomeController.cs
+++ b/Web/Resgrid.Web/Areas/User/Controllers/HomeController.cs
@@ -1138,25 +1138,29 @@ public async Task SendContactVerificationCode([FromBody] SendCont
if (request == null || !Enum.IsDefined(typeof(ContactVerificationType), request.Type))
return BadRequest();
- bool sent;
+ ContactVerificationSendStatus sendStatus;
string departmentNumber = await _departmentSettingsService.GetTextToCallNumberForDepartmentAsync(DepartmentId);
switch (request.Type)
{
case ContactVerificationType.Email:
- sent = await _contactVerificationService.SendEmailVerificationCodeAsync(UserId, DepartmentId, cancellationToken);
+ sendStatus = await _contactVerificationService.SendEmailVerificationCodeAsync(UserId, DepartmentId, cancellationToken);
break;
case ContactVerificationType.MobileNumber:
- sent = await _contactVerificationService.SendMobileVerificationCodeAsync(UserId, DepartmentId, departmentNumber, cancellationToken);
+ sendStatus = await _contactVerificationService.SendMobileVerificationCodeAsync(UserId, DepartmentId, departmentNumber, cancellationToken);
break;
case ContactVerificationType.HomeNumber:
- sent = await _contactVerificationService.SendHomeVerificationCodeAsync(UserId, DepartmentId, departmentNumber, cancellationToken);
+ sendStatus = await _contactVerificationService.SendHomeVerificationCodeAsync(UserId, DepartmentId, departmentNumber, cancellationToken);
break;
default:
return BadRequest();
}
- return Json(new { success = sent });
+ return Json(new
+ {
+ success = sendStatus == ContactVerificationSendStatus.Sent,
+ errorCode = sendStatus == ContactVerificationSendStatus.Sent ? null : sendStatus.ToString()
+ });
}
[HttpPost]
diff --git a/Web/Resgrid.Web/Areas/User/Views/Home/EditUserProfile.cshtml b/Web/Resgrid.Web/Areas/User/Views/Home/EditUserProfile.cshtml
index ab6a9b403..fd369cb52 100644
--- a/Web/Resgrid.Web/Areas/User/Views/Home/EditUserProfile.cshtml
+++ b/Web/Resgrid.Web/Areas/User/Views/Home/EditUserProfile.cshtml
@@ -882,6 +882,9 @@
voiceCallSent: '@Html.Raw(localizer["VerificationCodeVoiceCallSent"].Value)',
success: '@Html.Raw(localizer["VerificationSuccessful"].Value)',
failed: '@Html.Raw(localizer["VerificationFailed"].Value)',
+ contactNotConfigured: '@Html.Raw(localizer["VerificationContactNotConfigured"].Value)',
+ invalidContact: '@Html.Raw(localizer["VerificationInvalidContact"].Value)',
+ deliveryFailed: '@Html.Raw(localizer["VerificationDeliveryFailed"].Value)',
rateLimited: '@Html.Raw(localizer["VerificationRateLimited"].Value)'
};
diff --git a/Web/Resgrid.Web/wwwroot/js/app/internal/home/resgrid.home.edituserprofile.js b/Web/Resgrid.Web/wwwroot/js/app/internal/home/resgrid.home.edituserprofile.js
index 8b3782453..86e8b4dab 100644
--- a/Web/Resgrid.Web/wwwroot/js/app/internal/home/resgrid.home.edituserprofile.js
+++ b/Web/Resgrid.Web/wwwroot/js/app/internal/home/resgrid.home.edituserprofile.js
@@ -67,6 +67,19 @@ var resgrid;
return $('input[name="__RequestVerificationToken"]').val();
}
+ function getSendFailureLabel(errorCode) {
+ switch (errorCode) {
+ case 'ContactNotConfigured':
+ return rgVerifyLabels.contactNotConfigured;
+ case 'InvalidContact':
+ return rgVerifyLabels.invalidContact;
+ case 'RateLimited':
+ return rgVerifyLabels.rateLimited;
+ default:
+ return rgVerifyLabels.deliveryFailed;
+ }
+ }
+
// Send verification code button clicked
$(document).on('click', '.rg-send-code', function () {
var contactType = parseInt($(this).data('contact-type'), 10);
@@ -90,7 +103,7 @@ var resgrid;
$(w.codeEntry).show();
$btn.hide();
} else {
- $(w.msgSpan).text(rgVerifyLabels.rateLimited).css('color', '#a94442').show();
+ $(w.msgSpan).text(getSendFailureLabel(result && result.errorCode)).css('color', '#a94442').show();
$btn.prop('disabled', false).text('Verify');
}
}).fail(function () {
diff --git a/Web/Resgrid.Web/wwwroot/js/ng/react-elements.css b/Web/Resgrid.Web/wwwroot/js/ng/react-elements.css
deleted file mode 100644
index f6a4a1328..000000000
--- a/Web/Resgrid.Web/wwwroot/js/ng/react-elements.css
+++ /dev/null
@@ -1,3466 +0,0 @@
-@charset "UTF-8";.rg-element-root {
- box-sizing: border-box;
-}
-
-.rg-card {
- background: #ffffff;
- border: 1px solid #e5e7eb;
- border-radius: 6px;
- box-shadow: 0 1px 2px rgba(15, 23, 42, 0.08);
-}
-
-.rg-loading {
- display: flex;
- min-height: 120px;
- align-items: center;
- justify-content: center;
- color: #4b5563;
- font-size: 14px;
-}
-
-.rg-loading__stack {
- display: inline-flex;
- align-items: center;
- gap: 12px;
-}
-
-.rg-loading__spinner {
- width: 18px;
- height: 18px;
- border-radius: 50%;
- border: 2px solid rgba(59, 130, 246, 0.2);
- border-top-color: #2563eb;
- animation: rg-spin 0.8s linear infinite;
-}
-
-.rg-error {
- padding: 12px 14px;
- color: #991b1b;
- background: #fef2f2;
- border: 1px solid #fecaca;
- border-radius: 6px;
- font-size: 13px;
-}
-
-@keyframes rg-spin {
- to {
- transform: rotate(360deg);
- }
-}
-.rg-map {
- font-size: 13px;
- color: #111827;
-}
-
-.rg-map__toolbar {
- display: flex;
- flex-wrap: wrap;
- align-items: center;
- justify-content: space-between;
- gap: 12px;
- margin-bottom: 8px;
-}
-
-.rg-map__toolbar-section {
- display: flex;
- flex-wrap: wrap;
- align-items: center;
- gap: 12px;
-}
-
-.rg-map__search {
- width: 220px;
- max-width: 100%;
- padding: 7px 10px;
- border: 1px solid #cbd5e1;
- border-radius: 6px;
- outline: none;
-}
-
-.rg-map__search:focus {
- border-color: #2563eb;
- box-shadow: 0 0 0 3px rgba(37, 99, 235, 0.15);
-}
-
-.rg-map__checkbox,
-.rg-map__layer-toggle {
- display: inline-flex;
- align-items: center;
- gap: 6px;
- font-weight: 400;
-}
-
-.rg-map__message {
- margin-bottom: 8px;
-}
-
-.rg-map__viewport {
- position: relative;
- width: 100%;
- min-height: 320px;
- overflow: hidden;
- border: 1px solid #d1d5db;
- border-radius: 6px;
- background: #f8fafc;
-}
-
-.rg-map__canvas {
- width: 100%;
- height: 100%;
-}
-
-.rg-map__canvas .leaflet-container {
- width: 100%;
- height: 100%;
-}
-
-.rg-map__canvas .mapboxgl-map {
- width: 100%;
- height: 100%;
-}
-
-.rg-map__layers {
- position: absolute;
- top: 12px;
- right: 12px;
- z-index: 450;
- width: 240px;
- max-width: calc(100% - 24px);
- padding: 12px;
-}
-
-.rg-map__layers-title {
- margin-bottom: 8px;
- font-weight: 600;
-}
-
-.rg-map__layer-list {
- display: flex;
- flex-direction: column;
- gap: 6px;
-}
-
-.rg-map__layer-section + .rg-map__layer-section {
- margin-top: 12px;
- padding-top: 12px;
- border-top: 1px solid #e5e7eb;
-}
-
-.rg-map__layer-swatch {
- width: 12px;
- height: 12px;
- border: 1px solid rgba(17, 24, 39, 0.2);
- border-radius: 999px;
- flex: 0 0 auto;
-}
-
-.rg-map__overlay {
- position: absolute;
- inset: 0;
- z-index: 500;
- background: rgba(255, 255, 255, 0.72);
-}
-
-.rg-map__footer {
- display: flex;
- justify-content: flex-end;
- padding-top: 8px;
- color: #6b7280;
- font-size: 12px;
-}
-
-.rg-map__tooltip {
- padding: 2px 6px;
- border: 1px solid #111827;
- color: #111827;
- background: #ffffff;
- font-size: 11px;
- font-weight: 600;
-}
-
-.rg-map__tooltip::before {
- border-top-color: #111827;
-}
-
-.rg-map__marker {
- display: inline-flex;
- flex-direction: column;
- align-items: center;
- gap: 4px;
- cursor: pointer;
-}
-
-.rg-map__marker--poi {
- position: relative;
- width: 36px;
- min-height: 48px;
- justify-content: flex-start;
-}
-
-.rg-map__marker-icon {
- width: 32px;
- height: 37px;
- object-fit: contain;
- pointer-events: none;
-}
-
-.rg-map__poi-marker-wrapper {
- background: transparent;
- border: 0;
-}
-
-.rg-map__poi-marker {
- position: relative;
- width: 36px;
- height: 48px;
-}
-
-.rg-map__poi-marker-shape {
- width: 36px;
- height: 48px;
- fill: var(--rg-map-poi-color, #2563eb);
- filter: drop-shadow(0 1px 2px rgba(17, 24, 39, 0.35));
-}
-
-.rg-map__poi-marker-icon {
- position: absolute;
- top: 10px;
- left: 50%;
- transform: translateX(-50%);
- color: #ffffff;
- font-size: 14px;
- line-height: 1;
- pointer-events: none;
-}
-
-.rg-map__marker--poi .rg-map__poi-marker-shape {
- width: 36px;
- height: 48px;
-}
-
-.rg-map__marker--poi .rg-map__poi-marker-icon {
- top: 10px;
-}
-
-.rg-map__marker-label {
- max-width: 180px;
- padding: 2px 6px;
- border: 1px solid #111827;
- border-radius: 4px;
- color: #111827;
- background: rgba(255, 255, 255, 0.96);
- font-size: 11px;
- font-weight: 600;
- line-height: 1.2;
- text-align: center;
- white-space: nowrap;
-}
-
-@media (max-width: 900px) {
- .rg-map__toolbar {
- align-items: stretch;
- }
-
- .rg-map__layers {
- position: static;
- width: auto;
- max-width: none;
- margin: 12px;
- }
-}
-
-.rbc-btn {
- color: inherit;
- font: inherit;
- margin: 0;
-}
-
-button.rbc-btn {
- overflow: visible;
- text-transform: none;
- -webkit-appearance: button;
- -moz-appearance: button;
- appearance: button;
- cursor: pointer;
-}
-
-button[disabled].rbc-btn {
- cursor: not-allowed;
-}
-
-button.rbc-input::-moz-focus-inner {
- border: 0;
- padding: 0;
-}
-
-.rbc-calendar {
- -webkit-box-sizing: border-box;
- box-sizing: border-box;
- height: 100%;
- display: -webkit-box;
- display: -ms-flexbox;
- display: flex;
- -webkit-box-orient: vertical;
- -webkit-box-direction: normal;
- -ms-flex-direction: column;
- flex-direction: column;
- -webkit-box-align: stretch;
- -ms-flex-align: stretch;
- align-items: stretch;
-}
-
-.rbc-m-b-negative-3 {
- margin-bottom: -3px;
-}
-
-.rbc-h-full {
- height: 100%;
-}
-
-.rbc-calendar *,
-.rbc-calendar *:before,
-.rbc-calendar *:after {
- -webkit-box-sizing: inherit;
- box-sizing: inherit;
-}
-
-.rbc-abs-full, .rbc-row-bg {
- overflow: hidden;
- position: absolute;
- top: 0;
- left: 0;
- right: 0;
- bottom: 0;
-}
-
-.rbc-ellipsis, .rbc-show-more, .rbc-row-segment .rbc-event-content, .rbc-event-label {
- display: block;
- overflow: hidden;
- text-overflow: ellipsis;
- white-space: nowrap;
-}
-
-.rbc-rtl {
- direction: rtl;
-}
-
-.rbc-off-range {
- color: #999999;
-}
-
-.rbc-off-range-bg {
- background: #e6e6e6;
-}
-
-.rbc-header {
- overflow: hidden;
- -webkit-box-flex: 1;
- -ms-flex: 1 0 0%;
- flex: 1 0 0%;
- text-overflow: ellipsis;
- white-space: nowrap;
- padding: 0 3px;
- text-align: center;
- vertical-align: middle;
- font-weight: bold;
- font-size: 90%;
- min-height: 0;
- border-bottom: 1px solid #ddd;
-}
-.rbc-header + .rbc-header {
- border-left: 1px solid #ddd;
-}
-.rbc-rtl .rbc-header + .rbc-header {
- border-left-width: 0;
- border-right: 1px solid #ddd;
-}
-.rbc-header > a, .rbc-header > a:active, .rbc-header > a:visited {
- color: inherit;
- text-decoration: none;
-}
-
-.rbc-button-link {
- color: inherit;
- background: none;
- margin: 0;
- padding: 0;
- border: none;
- cursor: pointer;
- -webkit-user-select: text;
- -moz-user-select: text;
- -ms-user-select: text;
- user-select: text;
-}
-
-.rbc-row-content {
- position: relative;
- -moz-user-select: none;
- -ms-user-select: none;
- user-select: none;
- -webkit-user-select: none;
- z-index: 4;
-}
-
-.rbc-row-content-scrollable {
- display: -webkit-box;
- display: -ms-flexbox;
- display: flex;
- -webkit-box-orient: vertical;
- -webkit-box-direction: normal;
- -ms-flex-direction: column;
- flex-direction: column;
- height: 100%;
-}
-.rbc-row-content-scrollable .rbc-row-content-scroll-container {
- height: 100%;
- overflow-y: scroll;
- -ms-overflow-style: none; /* IE and Edge */
- scrollbar-width: none; /* Firefox */
- -ms-overflow-style: none; /* IE and Edge */
- scrollbar-width: none; /* Firefox */
- /* Hide scrollbar for Chrome, Safari and Opera */
-}
-.rbc-row-content-scrollable .rbc-row-content-scroll-container::-webkit-scrollbar {
- display: none;
-}
-
-.rbc-today {
- background-color: #eaf6ff;
-}
-
-.rbc-toolbar {
- display: -webkit-box;
- display: -ms-flexbox;
- display: flex;
- -ms-flex-wrap: wrap;
- flex-wrap: wrap;
- -webkit-box-pack: center;
- -ms-flex-pack: center;
- justify-content: center;
- -webkit-box-align: center;
- -ms-flex-align: center;
- align-items: center;
- margin-bottom: 10px;
- font-size: 16px;
-}
-.rbc-toolbar .rbc-toolbar-label {
- -webkit-box-flex: 1;
- -ms-flex-positive: 1;
- flex-grow: 1;
- padding: 0 10px;
- text-align: center;
-}
-.rbc-toolbar button {
- color: #373a3c;
- display: inline-block;
- margin: 0;
- text-align: center;
- vertical-align: middle;
- background: none;
- background-image: none;
- border: 1px solid #ccc;
- padding: 0.375rem 1rem;
- border-radius: 4px;
- line-height: normal;
- white-space: nowrap;
-}
-.rbc-toolbar button:active, .rbc-toolbar button.rbc-active {
- background-image: none;
- -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
- box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
- background-color: #e6e6e6;
- border-color: #adadad;
-}
-.rbc-toolbar button:active:hover, .rbc-toolbar button:active:focus, .rbc-toolbar button.rbc-active:hover, .rbc-toolbar button.rbc-active:focus {
- color: #373a3c;
- background-color: #d4d4d4;
- border-color: #8c8c8c;
-}
-.rbc-toolbar button:focus {
- color: #373a3c;
- background-color: #e6e6e6;
- border-color: #adadad;
-}
-.rbc-toolbar button:hover {
- color: #373a3c;
- cursor: pointer;
- background-color: #e6e6e6;
- border-color: #adadad;
-}
-
-.rbc-btn-group {
- display: inline-block;
- white-space: nowrap;
-}
-.rbc-btn-group > button:first-child:not(:last-child) {
- border-top-right-radius: 0;
- border-bottom-right-radius: 0;
-}
-.rbc-btn-group > button:last-child:not(:first-child) {
- border-top-left-radius: 0;
- border-bottom-left-radius: 0;
-}
-.rbc-rtl .rbc-btn-group > button:first-child:not(:last-child) {
- border-radius: 4px;
- border-top-left-radius: 0;
- border-bottom-left-radius: 0;
-}
-.rbc-rtl .rbc-btn-group > button:last-child:not(:first-child) {
- border-radius: 4px;
- border-top-right-radius: 0;
- border-bottom-right-radius: 0;
-}
-.rbc-btn-group > button:not(:first-child):not(:last-child) {
- border-radius: 0;
-}
-.rbc-btn-group button + button {
- margin-left: -1px;
-}
-.rbc-rtl .rbc-btn-group button + button {
- margin-left: 0;
- margin-right: -1px;
-}
-.rbc-btn-group + .rbc-btn-group, .rbc-btn-group + button {
- margin-left: 10px;
-}
-
-@media (max-width: 767px) {
- .rbc-toolbar {
- -webkit-box-orient: vertical;
- -webkit-box-direction: normal;
- -ms-flex-direction: column;
- flex-direction: column;
- }
-}
-.rbc-event, .rbc-day-slot .rbc-background-event {
- border: none;
- -webkit-box-sizing: border-box;
- box-sizing: border-box;
- -webkit-box-shadow: none;
- box-shadow: none;
- margin: 0;
- padding: 2px 5px;
- background-color: #3174ad;
- border-radius: 5px;
- color: #fff;
- cursor: pointer;
- width: 100%;
- text-align: left;
-}
-.rbc-slot-selecting .rbc-event, .rbc-slot-selecting .rbc-day-slot .rbc-background-event, .rbc-day-slot .rbc-slot-selecting .rbc-background-event {
- cursor: inherit;
- pointer-events: none;
-}
-.rbc-event.rbc-selected, .rbc-day-slot .rbc-selected.rbc-background-event {
- background-color: #265985;
-}
-.rbc-event:focus, .rbc-day-slot .rbc-background-event:focus {
- outline: 5px auto #3b99fc;
-}
-
-.rbc-event-label {
- font-size: 80%;
-}
-
-.rbc-event-overlaps {
- -webkit-box-shadow: -1px 1px 5px 0px rgba(51, 51, 51, 0.5);
- box-shadow: -1px 1px 5px 0px rgba(51, 51, 51, 0.5);
-}
-
-.rbc-event-continues-prior {
- border-top-left-radius: 0;
- border-bottom-left-radius: 0;
-}
-
-.rbc-event-continues-after {
- border-top-right-radius: 0;
- border-bottom-right-radius: 0;
-}
-
-.rbc-event-continues-earlier {
- border-top-left-radius: 0;
- border-top-right-radius: 0;
-}
-
-.rbc-event-continues-later {
- border-bottom-left-radius: 0;
- border-bottom-right-radius: 0;
-}
-
-.rbc-row {
- display: -webkit-box;
- display: -ms-flexbox;
- display: flex;
- -webkit-box-orient: horizontal;
- -webkit-box-direction: normal;
- -ms-flex-direction: row;
- flex-direction: row;
-}
-
-.rbc-row-segment {
- padding: 0 1px 1px 1px;
-}
-.rbc-selected-cell {
- background-color: rgba(0, 0, 0, 0.1);
-}
-
-.rbc-show-more {
- background-color: rgba(255, 255, 255, 0.3);
- z-index: 4;
- font-weight: bold;
- font-size: 85%;
- height: auto;
- line-height: normal;
- color: #3174ad;
-}
-.rbc-show-more:hover, .rbc-show-more:focus {
- color: #265985;
-}
-
-.rbc-month-view {
- position: relative;
- border: 1px solid #ddd;
- display: -webkit-box;
- display: -ms-flexbox;
- display: flex;
- -webkit-box-orient: vertical;
- -webkit-box-direction: normal;
- -ms-flex-direction: column;
- flex-direction: column;
- -webkit-box-flex: 1;
- -ms-flex: 1 0 0px;
- flex: 1 0 0;
- width: 100%;
- -moz-user-select: none;
- -ms-user-select: none;
- user-select: none;
- -webkit-user-select: none;
- height: 100%;
-}
-
-.rbc-month-header {
- display: -webkit-box;
- display: -ms-flexbox;
- display: flex;
- -webkit-box-orient: horizontal;
- -webkit-box-direction: normal;
- -ms-flex-direction: row;
- flex-direction: row;
-}
-
-.rbc-month-row {
- display: -webkit-box;
- display: -ms-flexbox;
- display: flex;
- position: relative;
- -webkit-box-orient: vertical;
- -webkit-box-direction: normal;
- -ms-flex-direction: column;
- flex-direction: column;
- -webkit-box-flex: 1;
- -ms-flex: 1 0 0px;
- flex: 1 0 0;
- -ms-flex-preferred-size: 0px;
- flex-basis: 0px;
- overflow: hidden;
- height: 100%;
-}
-.rbc-month-row + .rbc-month-row {
- border-top: 1px solid #ddd;
-}
-
-.rbc-date-cell {
- -webkit-box-flex: 1;
- -ms-flex: 1 1 0px;
- flex: 1 1 0;
- min-width: 0;
- padding-right: 5px;
- text-align: right;
-}
-.rbc-date-cell.rbc-now {
- font-weight: bold;
-}
-.rbc-date-cell > a, .rbc-date-cell > a:active, .rbc-date-cell > a:visited {
- color: inherit;
- text-decoration: none;
-}
-
-.rbc-row-bg {
- display: -webkit-box;
- display: -ms-flexbox;
- display: flex;
- -webkit-box-orient: horizontal;
- -webkit-box-direction: normal;
- -ms-flex-direction: row;
- flex-direction: row;
- -webkit-box-flex: 1;
- -ms-flex: 1 0 0px;
- flex: 1 0 0;
- overflow: hidden;
- right: 1px;
-}
-
-.rbc-day-bg {
- -webkit-box-flex: 1;
- -ms-flex: 1 0 0%;
- flex: 1 0 0%;
-}
-.rbc-day-bg + .rbc-day-bg {
- border-left: 1px solid #ddd;
-}
-.rbc-rtl .rbc-day-bg + .rbc-day-bg {
- border-left-width: 0;
- border-right: 1px solid #ddd;
-}
-
-.rbc-overlay {
- position: absolute;
- z-index: 5;
- border: 1px solid #e5e5e5;
- background-color: #fff;
- -webkit-box-shadow: 0 5px 15px rgba(0, 0, 0, 0.25);
- box-shadow: 0 5px 15px rgba(0, 0, 0, 0.25);
- padding: 10px;
-}
-.rbc-overlay > * + * {
- margin-top: 1px;
-}
-
-.rbc-overlay-header {
- border-bottom: 1px solid #e5e5e5;
- margin: -10px -10px 5px -10px;
- padding: 2px 10px;
-}
-
-.rbc-agenda-view {
- display: -webkit-box;
- display: -ms-flexbox;
- display: flex;
- -webkit-box-orient: vertical;
- -webkit-box-direction: normal;
- -ms-flex-direction: column;
- flex-direction: column;
- -webkit-box-flex: 1;
- -ms-flex: 1 0 0px;
- flex: 1 0 0;
- overflow: auto;
-}
-.rbc-agenda-view table.rbc-agenda-table {
- width: 100%;
- border: 1px solid #ddd;
- border-spacing: 0;
- border-collapse: collapse;
-}
-.rbc-agenda-view table.rbc-agenda-table tbody > tr > td {
- padding: 5px 10px;
- vertical-align: top;
-}
-.rbc-agenda-view table.rbc-agenda-table .rbc-agenda-time-cell {
- padding-left: 15px;
- padding-right: 15px;
- text-transform: lowercase;
-}
-.rbc-agenda-view table.rbc-agenda-table tbody > tr > td + td {
- border-left: 1px solid #ddd;
-}
-.rbc-rtl .rbc-agenda-view table.rbc-agenda-table tbody > tr > td + td {
- border-left-width: 0;
- border-right: 1px solid #ddd;
-}
-.rbc-agenda-view table.rbc-agenda-table tbody > tr + tr {
- border-top: 1px solid #ddd;
-}
-.rbc-agenda-view table.rbc-agenda-table thead > tr > th {
- padding: 3px 5px;
- text-align: left;
- border-bottom: 1px solid #ddd;
-}
-.rbc-rtl .rbc-agenda-view table.rbc-agenda-table thead > tr > th {
- text-align: right;
-}
-
-.rbc-agenda-time-cell {
- text-transform: lowercase;
-}
-.rbc-agenda-time-cell .rbc-continues-after:after {
- content: " »";
-}
-.rbc-agenda-time-cell .rbc-continues-prior:before {
- content: "« ";
-}
-
-.rbc-agenda-date-cell,
-.rbc-agenda-time-cell {
- white-space: nowrap;
-}
-
-.rbc-agenda-event-cell {
- width: 100%;
-}
-
-.rbc-time-column {
- display: -webkit-box;
- display: -ms-flexbox;
- display: flex;
- -webkit-box-orient: vertical;
- -webkit-box-direction: normal;
- -ms-flex-direction: column;
- flex-direction: column;
- min-height: 100%;
-}
-.rbc-time-column .rbc-timeslot-group {
- -webkit-box-flex: 1;
- -ms-flex: 1;
- flex: 1;
-}
-
-.rbc-timeslot-group {
- border-bottom: 1px solid #ddd;
- min-height: 40px;
- display: -webkit-box;
- display: -ms-flexbox;
- display: flex;
- -webkit-box-orient: vertical;
- -webkit-box-direction: normal;
- -ms-flex-flow: column nowrap;
- flex-flow: column nowrap;
-}
-
-.rbc-time-gutter,
-.rbc-header-gutter {
- -webkit-box-flex: 0;
- -ms-flex: none;
- flex: none;
-}
-
-.rbc-label {
- padding: 0 5px;
-}
-
-.rbc-day-slot {
- position: relative;
-}
-.rbc-day-slot .rbc-events-container {
- bottom: 0;
- left: 0;
- position: absolute;
- right: 0;
- margin-right: 10px;
- top: 0;
-}
-.rbc-day-slot .rbc-events-container.rbc-rtl {
- left: 10px;
- right: 0;
-}
-.rbc-day-slot .rbc-event, .rbc-day-slot .rbc-background-event {
- border: 1px solid #265985;
- display: -webkit-box;
- display: -ms-flexbox;
- display: flex;
- max-height: 100%;
- min-height: 20px;
- -webkit-box-orient: vertical;
- -webkit-box-direction: normal;
- -ms-flex-flow: column wrap;
- flex-flow: column wrap;
- -webkit-box-align: start;
- -ms-flex-align: start;
- align-items: flex-start;
- overflow: hidden;
- position: absolute;
-}
-.rbc-day-slot .rbc-background-event {
- opacity: 0.75;
-}
-.rbc-day-slot .rbc-event-label {
- -webkit-box-flex: 0;
- -ms-flex: none;
- flex: none;
- padding-right: 5px;
- width: auto;
-}
-.rbc-day-slot .rbc-event-content {
- width: 100%;
- -webkit-box-flex: 1;
- -ms-flex: 1 1 0px;
- flex: 1 1 0;
- word-wrap: break-word;
- line-height: 1;
- height: 100%;
- min-height: 1em;
-}
-.rbc-day-slot .rbc-time-slot {
- border-top: 1px solid #f7f7f7;
-}
-
-.rbc-time-view-resources .rbc-time-gutter,
-.rbc-time-view-resources .rbc-time-header-gutter {
- position: sticky;
- left: 0;
- background-color: white;
- border-right: 1px solid #ddd;
- z-index: 10;
- margin-right: -1px;
-}
-.rbc-time-view-resources .rbc-time-header {
- overflow: hidden;
-}
-.rbc-time-view-resources .rbc-time-header-content {
- min-width: auto;
- -webkit-box-flex: 1;
- -ms-flex: 1 0 0px;
- flex: 1 0 0;
- -ms-flex-preferred-size: 0px;
- flex-basis: 0px;
-}
-.rbc-time-view-resources .rbc-time-header-cell-single-day {
- display: none;
-}
-.rbc-time-view-resources .rbc-day-slot {
- min-width: 140px;
-}
-.rbc-time-view-resources .rbc-header,
-.rbc-time-view-resources .rbc-day-bg {
- width: 140px;
- -webkit-box-flex: 1;
- -ms-flex: 1 1 0px;
- flex: 1 1 0;
- -ms-flex-preferred-size: 0 px;
- flex-basis: 0 px;
-}
-
-.rbc-time-header-content + .rbc-time-header-content {
- margin-left: -1px;
-}
-
-.rbc-time-slot {
- -webkit-box-flex: 1;
- -ms-flex: 1 0 0px;
- flex: 1 0 0;
-}
-.rbc-time-slot.rbc-now {
- font-weight: bold;
-}
-
-.rbc-day-header {
- text-align: center;
-}
-
-.rbc-slot-selection {
- z-index: 10;
- position: absolute;
- background-color: rgba(0, 0, 0, 0.5);
- color: white;
- font-size: 75%;
- width: 100%;
- padding: 3px;
-}
-
-.rbc-slot-selecting {
- cursor: move;
-}
-
-.rbc-time-view {
- display: -webkit-box;
- display: -ms-flexbox;
- display: flex;
- -webkit-box-orient: vertical;
- -webkit-box-direction: normal;
- -ms-flex-direction: column;
- flex-direction: column;
- -webkit-box-flex: 1;
- -ms-flex: 1;
- flex: 1;
- width: 100%;
- border: 1px solid #ddd;
- min-height: 0;
-}
-.rbc-time-view .rbc-time-gutter {
- white-space: nowrap;
- text-align: right;
-}
-.rbc-time-view .rbc-allday-cell {
- -webkit-box-sizing: content-box;
- box-sizing: content-box;
- width: 100%;
- height: 100%;
- position: relative;
-}
-.rbc-time-view .rbc-allday-cell + .rbc-allday-cell {
- border-left: 1px solid #ddd;
-}
-.rbc-time-view .rbc-allday-events {
- position: relative;
- z-index: 4;
-}
-.rbc-time-view .rbc-row {
- -webkit-box-sizing: border-box;
- box-sizing: border-box;
- min-height: 20px;
-}
-
-.rbc-time-header {
- display: -webkit-box;
- display: -ms-flexbox;
- display: flex;
- -webkit-box-flex: 0;
- -ms-flex: 0 0 auto;
- flex: 0 0 auto;
- -webkit-box-orient: horizontal;
- -webkit-box-direction: normal;
- -ms-flex-direction: row;
- flex-direction: row;
-}
-.rbc-time-header.rbc-overflowing {
- border-right: 1px solid #ddd;
-}
-.rbc-rtl .rbc-time-header.rbc-overflowing {
- border-right-width: 0;
- border-left: 1px solid #ddd;
-}
-.rbc-time-header > .rbc-row:first-child {
- border-bottom: 1px solid #ddd;
-}
-.rbc-time-header > .rbc-row.rbc-row-resource {
- border-bottom: 1px solid #ddd;
-}
-
-.rbc-time-header-cell-single-day {
- display: none;
-}
-
-.rbc-time-header-content {
- -webkit-box-flex: 1;
- -ms-flex: 1;
- flex: 1;
- display: -webkit-box;
- display: -ms-flexbox;
- display: flex;
- min-width: 0;
- -webkit-box-orient: vertical;
- -webkit-box-direction: normal;
- -ms-flex-direction: column;
- flex-direction: column;
- border-left: 1px solid #ddd;
-}
-.rbc-rtl .rbc-time-header-content {
- border-left-width: 0;
- border-right: 1px solid #ddd;
-}
-.rbc-time-header-content > .rbc-row.rbc-row-resource {
- border-bottom: 1px solid #ddd;
- -ms-flex-negative: 0;
- flex-shrink: 0;
-}
-
-.rbc-time-content {
- display: -webkit-box;
- display: -ms-flexbox;
- display: flex;
- -webkit-box-flex: 1;
- -ms-flex: 1 0 0%;
- flex: 1 0 0%;
- -webkit-box-align: start;
- -ms-flex-align: start;
- align-items: flex-start;
- width: 100%;
- border-top: 2px solid #ddd;
- overflow-y: auto;
- position: relative;
-}
-.rbc-time-content > .rbc-time-gutter {
- -webkit-box-flex: 0;
- -ms-flex: none;
- flex: none;
-}
-.rbc-time-content > * + * > * {
- border-left: 1px solid #ddd;
-}
-.rbc-rtl .rbc-time-content > * + * > * {
- border-left-width: 0;
- border-right: 1px solid #ddd;
-}
-.rbc-time-content > .rbc-day-slot {
- width: 100%;
- -moz-user-select: none;
- -ms-user-select: none;
- user-select: none;
- -webkit-user-select: none;
-}
-
-.rbc-current-time-indicator {
- position: absolute;
- z-index: 3;
- left: 0;
- right: 0;
- height: 1px;
- background-color: #74ad31;
- pointer-events: none;
-}
-
-.rbc-resource-grouping.rbc-time-header-content {
- display: -webkit-box;
- display: -ms-flexbox;
- display: flex;
- -webkit-box-orient: vertical;
- -webkit-box-direction: normal;
- -ms-flex-direction: column;
- flex-direction: column;
-}
-.rbc-resource-grouping .rbc-row .rbc-header {
- width: 141px;
-}
-
-/*# sourceMappingURL=react-big-calendar.css.map */.rg-shifts {
- color: #111827;
- font-size: 13px;
-}
-
-.rg-shifts__calendar {
- min-height: 760px;
-}
-
-.rg-shifts .rbc-calendar {
- min-height: 760px;
-}
-
-.rg-shifts .rbc-toolbar {
- gap: 12px;
- margin-bottom: 18px;
-}
-
-.rg-shifts .rbc-toolbar button {
- border: 1px solid #2563eb;
- border-radius: 4px;
- background: #2563eb;
- color: #ffffff;
- padding: 6px 12px;
-}
-
-.rg-shifts .rbc-toolbar button:hover,
-.rg-shifts .rbc-toolbar button:focus {
- border-color: #1d4ed8;
- background: #1d4ed8;
- color: #ffffff;
-}
-
-.rg-shifts .rbc-toolbar button.rbc-active {
- border-color: #1e40af;
- background: #1e40af;
- color: #ffffff;
-}
-
-.rg-shifts .rbc-month-view,
-.rg-shifts .rbc-time-view {
- overflow: hidden;
- border: 1px solid #d1d5db;
- border-radius: 6px;
-}
-
-.rg-shifts .rbc-header {
- padding: 8px 0;
- font-weight: 600;
-}
-
-.rg-shifts .rbc-today {
- background: #eff6ff;
-}
-
-.rg-shifts .rbc-off-range-bg {
- background: #f8fafc;
-}
-
-.rg-shifts .rbc-event {
- box-shadow: none;
-}
-.rg-omnibar {
- display: flex;
- flex-direction: column;
- gap: 12px;
- max-width: 640px;
- color: #111827;
- font-size: 13px;
-}
-
-.rg-omnibar__header {
- display: flex;
- align-items: center;
- justify-content: space-between;
- gap: 12px;
-}
-
-.rg-omnibar__title {
- font-size: 18px;
- font-weight: 600;
-}
-
-.rg-omnibar__count {
- color: #6b7280;
- font-size: 12px;
-}
-
-.rg-omnibar__input {
- width: 100%;
- padding: 10px 12px;
- border: 1px solid #cbd5e1;
- border-radius: 6px;
- outline: none;
-}
-
-.rg-omnibar__input:focus {
- border-color: #2563eb;
- box-shadow: 0 0 0 3px rgba(37, 99, 235, 0.15);
-}
-
-.rg-omnibar__results {
- display: flex;
- flex-direction: column;
- gap: 8px;
-}
-
-.rg-omnibar__item {
- display: flex;
- width: 100%;
- flex-direction: column;
- gap: 4px;
- padding: 12px;
- border: 1px solid #dbe2ea;
- border-radius: 6px;
- background: #ffffff;
- text-align: left;
- transition: border-color 0.15s ease, background 0.15s ease;
-}
-
-.rg-omnibar__item:hover,
-.rg-omnibar__item--active {
- border-color: #2563eb;
- background: #eff6ff;
-}
-
-.rg-omnibar__item-label {
- font-size: 14px;
- font-weight: 600;
-}
-
-.rg-omnibar__item-description,
-.rg-omnibar__empty {
- color: #6b7280;
-}
-/* Chat UI styles. All rules are scoped under the .rgchat- prefix to avoid leaking into the host page. */
-.rgchat-root,
-.rgchat-root * {
- box-sizing: border-box;
-}
-
-.rgchat-root {
- --rgchat-dark: #2f4050;
- --rgchat-accent: #1ab394;
- --rgchat-accent-ink: #0f7a63;
- --rgchat-bg: #f5f7fa;
- --rgchat-panel: #ffffff;
- --rgchat-border: #e3e8ef;
- --rgchat-muted: #5b6b7c;
- --rgchat-ink: #1f2d3d;
- --rgchat-urgent: #d8364c;
- --rgchat-own-bg: #e7f6f2;
- --rgchat-own-ink: #17352d;
- --rgchat-own-border: #bfe6da;
- --rgchat-hover: rgba(47, 64, 80, 0.06);
- --rgchat-bubble-bg: #ffffff;
- --rgchat-input-bg: #ffffff;
- --rgchat-shadow-pop: 0 12px 30px rgba(15, 23, 42, 0.2);
- color: var(--rgchat-ink);
- font-family: 'Open Sans', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
- font-size: 14px;
- line-height: 1.45;
-}
-
-.rgchat-sr-only {
- position: absolute;
- width: 1px;
- height: 1px;
- padding: 0;
- margin: -1px;
- overflow: hidden;
- clip: rect(0 0 0 0);
- white-space: nowrap;
- border: 0;
-}
-
-/* ---- Floating panel ---- */
-.rgchat-fab {
- position: fixed;
- right: 24px;
- bottom: 24px;
- z-index: 12000;
- display: inline-flex;
- align-items: center;
- gap: 8px;
- padding: 12px 18px;
- border: none;
- border-radius: 999px;
- background: var(--rgchat-dark);
- color: #fff;
- font-size: 14px;
- font-weight: 600;
- cursor: pointer;
- box-shadow: 0 10px 30px rgba(15, 23, 42, 0.28);
- transition: transform 160ms ease, box-shadow 160ms ease;
-}
-
-.rgchat-fab:hover {
- transform: translateY(-1px);
- box-shadow: 0 14px 34px rgba(15, 23, 42, 0.34);
-}
-
-.rgchat-fab__badge {
- min-width: 20px;
- height: 20px;
- padding: 0 6px;
- border-radius: 999px;
- background: var(--rgchat-urgent);
- color: #fff;
- font-size: 11px;
- font-weight: 700;
- display: inline-flex;
- align-items: center;
- justify-content: center;
-}
-
-.rgchat-panel {
- position: fixed;
- right: 24px;
- bottom: 24px;
- z-index: 12000;
- width: 384px;
- height: 560px;
- max-height: calc(100vh - 48px);
- display: flex;
- flex-direction: column;
- background: var(--rgchat-panel);
- border: 1px solid var(--rgchat-border);
- border-radius: 16px;
- overflow: hidden;
- box-shadow: 0 18px 48px rgba(15, 23, 42, 0.28);
- animation: rgchat-panel-in 160ms ease;
-}
-
-@keyframes rgchat-panel-in {
- from { opacity: 0; transform: translateY(10px) scale(0.985); }
- to { opacity: 1; transform: translateY(0) scale(1); }
-}
-
-.rgchat-panel__head {
- display: flex;
- align-items: center;
- gap: 8px;
- padding: 12px 16px;
- background: var(--rgchat-dark);
- color: #fff;
-}
-
-.rgchat-panel__title {
- font-size: 15px;
- font-weight: 700;
- flex: 1;
- min-width: 0;
- display: flex;
- align-items: center;
- gap: 8px;
- white-space: nowrap;
- overflow: hidden;
- text-overflow: ellipsis;
-}
-
-.rgchat-iconbtn {
- border: none;
- background: transparent;
- color: inherit;
- cursor: pointer;
- padding: 6px;
- min-width: 32px;
- min-height: 32px;
- border-radius: 8px;
- font-size: 15px;
- line-height: 1;
- display: inline-flex;
- align-items: center;
- justify-content: center;
- transition: background-color 140ms ease;
-}
-
-.rgchat-iconbtn:hover {
- background: rgba(255, 255, 255, 0.16);
-}
-
-.rgchat-iconbtn--inherit {
- color: inherit;
-}
-
-.rgchat-iconbtn--dark {
- color: var(--rgchat-dark);
-}
-
-.rgchat-panel--light .rgchat-iconbtn:hover,
-.rgchat-iconbtn--dark:hover {
- background: var(--rgchat-hover);
-}
-
-.rgchat-panel__body {
- flex: 1;
- min-height: 0;
- display: flex;
- flex-direction: column;
-}
-
-/* ---- Channel list ---- */
-.rgchat-list {
- flex: 1;
- min-height: 0;
- overflow-y: auto;
- background: var(--rgchat-bg);
-}
-
-.rgchat-list__search {
- padding: 8px;
- background: var(--rgchat-panel);
- border-bottom: 1px solid var(--rgchat-border);
-}
-
-.rgchat-input {
- width: 100%;
- padding: 8px 12px;
- border: 1px solid var(--rgchat-border);
- border-radius: 8px;
- font-size: 14px;
- outline: none;
- background: var(--rgchat-input-bg);
- color: var(--rgchat-ink);
- transition: border-color 140ms ease, box-shadow 140ms ease;
-}
-
-.rgchat-input:focus {
- border-color: var(--rgchat-accent);
- box-shadow: 0 0 0 3px rgba(26, 179, 148, 0.15);
-}
-
-.rgchat-group__label {
- padding: 12px 16px 4px;
- font-size: 11px;
- font-weight: 700;
- text-transform: uppercase;
- letter-spacing: 0.05em;
- color: var(--rgchat-muted);
-}
-
-.rgchat-chan {
- display: flex;
- align-items: center;
- gap: 10px;
- width: 100%;
- padding: 8px 12px;
- border: none;
- background: transparent;
- cursor: pointer;
- text-align: left;
- color: var(--rgchat-ink);
- transition: background-color 140ms ease;
-}
-
-.rgchat-chan:hover {
- background: var(--rgchat-hover);
-}
-
-.rgchat-chan--active {
- background: rgba(26, 179, 148, 0.12);
-}
-
-.rgchat-chan__body {
- flex: 1;
- min-width: 0;
-}
-
-.rgchat-chan__name {
- font-weight: 600;
- font-size: 14px;
- white-space: nowrap;
- overflow: hidden;
- text-overflow: ellipsis;
-}
-
-.rgchat-chan__preview {
- color: var(--rgchat-muted);
- font-size: 12px;
- white-space: nowrap;
- overflow: hidden;
- text-overflow: ellipsis;
-}
-
-.rgchat-chan__meta {
- display: flex;
- flex-direction: column;
- align-items: flex-end;
- gap: 4px;
-}
-
-.rgchat-chan__time {
- font-size: 11px;
- color: var(--rgchat-muted);
-}
-
-.rgchat-badge {
- min-width: 18px;
- height: 18px;
- padding: 0 5px;
- border-radius: 999px;
- background: var(--rgchat-accent);
- color: #fff;
- font-size: 11px;
- font-weight: 700;
- display: inline-flex;
- align-items: center;
- justify-content: center;
-}
-
-/* ---- Avatar ---- */
-.rgchat-avatar {
- position: relative;
- width: 38px;
- height: 38px;
- border-radius: 50%;
- color: #fff;
- font-size: 13px;
- font-weight: 700;
- display: inline-flex;
- align-items: center;
- justify-content: center;
- flex-shrink: 0;
- overflow: visible;
-}
-
-.rgchat-avatar--sm {
- width: 30px;
- height: 30px;
- font-size: 11px;
-}
-
-.rgchat-avatar__img {
- width: 100%;
- height: 100%;
- object-fit: cover;
- border-radius: 50%;
-}
-
-.rgchat-avatar__dot {
- position: absolute;
- right: -1px;
- bottom: -1px;
- width: 11px;
- height: 11px;
- border-radius: 50%;
- border: 2px solid var(--rgchat-panel);
- background: #cbd2d9;
-}
-
-.rgchat-avatar__dot--online {
- background: var(--rgchat-accent);
-}
-
-/* ---- Conversation ---- */
-.rgchat-convo {
- flex: 1;
- min-height: 0;
- display: flex;
- flex-direction: column;
- background: var(--rgchat-panel);
- position: relative;
-}
-
-.rgchat-convo__head {
- display: flex;
- align-items: center;
- gap: 10px;
- padding: 8px 12px;
- border-bottom: 1px solid var(--rgchat-border);
-}
-
-.rgchat-convo__head-body {
- flex: 1;
- min-width: 0;
-}
-
-.rgchat-convo__title {
- font-weight: 700;
- font-size: 14px;
- white-space: nowrap;
- overflow: hidden;
- text-overflow: ellipsis;
-}
-
-.rgchat-convo__sub {
- font-size: 12px;
- color: var(--rgchat-muted);
-}
-
-.rgchat-convo__scroll {
- flex: 1;
- min-height: 0;
- overflow-y: auto;
- padding: 12px;
- display: flex;
- flex-direction: column;
- gap: 4px;
- background: var(--rgchat-bg);
-}
-
-.rgchat-loadmore {
- align-self: center;
- margin-bottom: 8px;
- padding: 6px 14px;
- border: 1px solid var(--rgchat-border);
- border-radius: 999px;
- background: var(--rgchat-panel);
- color: var(--rgchat-muted);
- font-size: 12px;
- cursor: pointer;
- transition: background-color 140ms ease;
-}
-
-.rgchat-loadmore:hover {
- background: var(--rgchat-hover);
-}
-
-.rgchat-daydivider {
- align-self: center;
- margin: 8px 0;
- font-size: 11px;
- font-weight: 600;
- color: var(--rgchat-muted);
- background: rgba(47, 64, 80, 0.08);
- padding: 3px 12px;
- border-radius: 999px;
-}
-
-.rgchat-newdivider {
- display: flex;
- align-items: center;
- gap: 8px;
- margin: 8px 0;
- font-size: 11px;
- font-weight: 700;
- color: var(--rgchat-accent-ink);
-}
-
-.rgchat-newdivider::before,
-.rgchat-newdivider::after {
- content: '';
- flex: 1;
- height: 1px;
- background: var(--rgchat-accent);
- opacity: 0.5;
-}
-
-.rgchat-jumppill {
- position: absolute;
- bottom: 64px;
- left: 50%;
- transform: translateX(-50%);
- z-index: 6;
- border: 1px solid var(--rgchat-border);
- background: var(--rgchat-panel);
- color: var(--rgchat-ink);
- font-size: 12px;
- font-weight: 600;
- padding: 7px 14px;
- border-radius: 999px;
- cursor: pointer;
- box-shadow: 0 8px 20px rgba(15, 23, 42, 0.18);
- animation: rgchat-panel-in 140ms ease;
- transition: background-color 140ms ease;
-}
-
-.rgchat-jumppill:hover {
- background: var(--rgchat-hover);
-}
-
-/* ---- Status bars / toasts ---- */
-.rgchat-statusbar {
- padding: 6px 12px;
- font-size: 12px;
- font-weight: 600;
- text-align: center;
- background: rgba(248, 172, 89, 0.16);
- color: #8a5a10;
- border-bottom: 1px solid rgba(248, 172, 89, 0.4);
-}
-
-.rgchat-statusbar--offline {
- background: rgba(216, 54, 76, 0.1);
- color: #a32738;
- border-bottom-color: rgba(216, 54, 76, 0.3);
-}
-
-.rgchat-toast {
- position: fixed;
- right: 24px;
- bottom: 96px;
- z-index: 12200;
- display: flex;
- align-items: center;
- gap: 10px;
- max-width: 320px;
- padding: 10px 14px;
- border-radius: 12px;
- background: var(--rgchat-dark);
- color: #fff;
- font-size: 13px;
- box-shadow: 0 12px 30px rgba(15, 23, 42, 0.3);
- animation: rgchat-panel-in 160ms ease;
-}
-
-.rgchat-toast__close {
- border: none;
- background: transparent;
- color: #fff;
- cursor: pointer;
- font-size: 12px;
- padding: 4px;
-}
-
-/* ---- Message bubbles ---- */
-.rgchat-msg {
- display: flex;
- gap: 8px;
- max-width: 100%;
- animation: rgchat-msg-in 160ms ease;
-}
-
-@keyframes rgchat-msg-in {
- from { opacity: 0; transform: translateY(6px); }
- to { opacity: 1; transform: translateY(0); }
-}
-
-.rgchat-msg--mine {
- flex-direction: row-reverse;
-}
-
-.rgchat-msg__spacer {
- width: 38px;
- flex-shrink: 0;
-}
-
-.rgchat-msg__col {
- display: flex;
- flex-direction: column;
- max-width: 78%;
- min-width: 0;
-}
-
-.rgchat-msg--mine .rgchat-msg__col {
- align-items: flex-end;
-}
-
-.rgchat-msg__meta {
- display: flex;
- gap: 6px;
- align-items: baseline;
- margin: 0 4px 2px;
- font-size: 12px;
- color: var(--rgchat-muted);
-}
-
-.rgchat-msg__author {
- font-weight: 700;
- color: var(--rgchat-ink);
-}
-
-.rgchat-bubble {
- position: relative;
- padding: 8px 12px;
- border-radius: 16px;
- background: var(--rgchat-bubble-bg);
- border: 1px solid var(--rgchat-border);
- word-break: break-word;
- white-space: pre-wrap;
- box-shadow: 0 1px 2px rgba(15, 23, 42, 0.05);
-}
-
-.rgchat-msg--mine .rgchat-bubble {
- background: var(--rgchat-own-bg);
- border-color: var(--rgchat-own-border);
- border-left: 3px solid var(--rgchat-accent);
- color: var(--rgchat-own-ink);
-}
-
-.rgchat-msg--mine .rgchat-bubble a {
- color: var(--rgchat-accent-ink);
- text-decoration: underline;
-}
-
-.rgchat-bubble--urgent {
- border-color: var(--rgchat-urgent);
- box-shadow: 0 0 0 2px rgba(216, 54, 76, 0.22);
-}
-
-.rgchat-bubble--tomb {
- font-style: italic;
- color: var(--rgchat-muted);
- background: transparent;
- border-style: dashed;
- box-shadow: none;
-}
-
-.rgchat-bubble--failed {
- border-color: var(--rgchat-urgent);
- background: rgba(216, 54, 76, 0.06);
-}
-
-.rgchat-bubble--flash {
- animation: rgchat-flash 2.2s ease;
-}
-
-@keyframes rgchat-flash {
- 0%, 55% { background: rgba(248, 172, 89, 0.35); border-color: #f8ac59; }
- 100% { background: inherit; }
-}
-
-.rgchat-bubble__urgent-tag {
- display: inline-block;
- margin-bottom: 4px;
- font-size: 10px;
- font-weight: 700;
- text-transform: uppercase;
- letter-spacing: 0.05em;
- color: var(--rgchat-urgent);
-}
-
-.rgchat-bubble__edited,
-.rgchat-bubble__status {
- font-size: 11px;
- opacity: 0.75;
- margin-left: 6px;
-}
-
-.rgchat-bubble__caption {
- margin-top: 4px;
-}
-
-.rgchat-bubble__editrow {
- display: flex;
- gap: 6px;
- margin-top: 6px;
-}
-
-.rgchat-bubble__img {
- max-width: 240px;
- max-height: 260px;
- border-radius: 10px;
- display: block;
- cursor: pointer;
-}
-
-.rgchat-bubble__img--busy {
- opacity: 0.6;
- cursor: wait;
-}
-
-.rgchat-bubble__location {
- display: block;
- width: 220px;
- text-decoration: none;
- color: inherit;
-}
-
-.rgchat-bubble__location-map {
- width: 100%;
- height: 110px;
- border-radius: 10px;
- background: linear-gradient(135deg, #dfe6ee, #c7d2df);
- display: flex;
- align-items: center;
- justify-content: center;
- font-size: 26px;
-}
-
-.rgchat-link {
- display: block;
- margin-top: 4px;
- border: 1px solid var(--rgchat-border);
- border-radius: 10px;
- overflow: hidden;
- text-decoration: none;
- color: inherit;
- background: var(--rgchat-panel);
-}
-
-.rgchat-link__body {
- padding: 8px 10px;
-}
-
-.rgchat-link__title {
- font-weight: 600;
-}
-
-.rgchat-link__desc {
- color: var(--rgchat-muted);
- font-size: 12px;
-}
-
-/* ---- Failed sends ---- */
-.rgchat-failed {
- display: flex;
- align-items: center;
- gap: 8px;
- margin: 3px 4px 0;
- font-size: 12px;
- color: var(--rgchat-urgent);
-}
-
-.rgchat-failed__label {
- font-weight: 600;
-}
-
-.rgchat-failed__action {
- border: none;
- background: transparent;
- color: var(--rgchat-accent-ink);
- font-weight: 700;
- font-size: 12px;
- cursor: pointer;
- padding: 2px 6px;
- border-radius: 6px;
-}
-
-.rgchat-failed__action:hover {
- background: var(--rgchat-hover);
-}
-
-.rgchat-failed__action--danger {
- color: var(--rgchat-urgent);
-}
-
-/* ---- Reactions ---- */
-.rgchat-reactions {
- display: flex;
- flex-wrap: wrap;
- gap: 4px;
- margin: 4px 2px 0;
-}
-
-.rgchat-reaction {
- display: inline-flex;
- align-items: center;
- gap: 4px;
- padding: 2px 8px;
- border-radius: 999px;
- border: 1px solid var(--rgchat-border);
- background: var(--rgchat-panel);
- color: var(--rgchat-ink);
- font-size: 12px;
- cursor: pointer;
- animation: rgchat-pop-in 140ms ease;
- transition: transform 140ms ease, box-shadow 140ms ease, border-color 140ms ease;
-}
-
-.rgchat-reaction:hover {
- transform: translateY(-1px);
- box-shadow: 0 3px 8px rgba(15, 23, 42, 0.12);
-}
-
-@keyframes rgchat-pop-in {
- from { opacity: 0; transform: scale(0.8); }
- to { opacity: 1; transform: scale(1); }
-}
-
-.rgchat-reaction--mine {
- border-color: var(--rgchat-accent);
- background: rgba(26, 179, 148, 0.12);
-}
-
-/* ---- Hover / keyboard actions ---- */
-.rgchat-msg__actions {
- display: inline-flex;
- gap: 2px;
- align-items: center;
- margin: 0 4px;
- opacity: 0;
- visibility: hidden;
- transition: opacity 140ms ease, visibility 140ms ease;
-}
-
-.rgchat-msg:hover .rgchat-msg__actions,
-.rgchat-msg:focus-within .rgchat-msg__actions,
-.rgchat-msg--actions-open .rgchat-msg__actions {
- opacity: 1;
- visibility: visible;
-}
-
-.rgchat-msg__actionwrap {
- position: relative;
-}
-
-.rgchat-msg__action {
- border: none;
- background: transparent;
- cursor: pointer;
- font-size: 13px;
- padding: 4px;
- min-width: 28px;
- min-height: 28px;
- border-radius: 6px;
- color: var(--rgchat-muted);
- transition: background-color 140ms ease;
-}
-
-.rgchat-msg__action:hover {
- background: var(--rgchat-hover);
-}
-
-.rgchat-msg__overflow {
- display: none;
- border: none;
- background: transparent;
- cursor: pointer;
- font-size: 16px;
- line-height: 1;
- padding: 4px 6px;
- border-radius: 6px;
- color: var(--rgchat-muted);
- align-self: center;
-}
-
-@media (hover: none), (pointer: coarse) {
- .rgchat-msg__overflow {
- display: inline-flex;
- }
-}
-
-.rgchat-thread-link {
- margin: 3px 4px 0;
- font-size: 12px;
- font-weight: 600;
- color: var(--rgchat-accent-ink);
- background: none;
- border: none;
- cursor: pointer;
- padding: 0;
- text-align: left;
-}
-
-.rgchat-thread-link:hover {
- text-decoration: underline;
-}
-
-/* ---- Typing / receipts ---- */
-.rgchat-typing {
- padding: 2px 12px 6px;
- font-size: 12px;
- color: var(--rgchat-muted);
- min-height: 22px;
-}
-
-.rgchat-dots span {
- display: inline-block;
- width: 5px;
- height: 5px;
- margin-right: 2px;
- border-radius: 50%;
- background: var(--rgchat-muted);
- animation: rgchat-blink 1.2s infinite ease-in-out both;
-}
-
-.rgchat-dots span:nth-child(2) {
- animation-delay: 0.2s;
-}
-
-.rgchat-dots span:nth-child(3) {
- animation-delay: 0.4s;
-}
-
-@keyframes rgchat-blink {
- 0%, 80%, 100% { opacity: 0.2; }
- 40% { opacity: 1; }
-}
-
-/* ---- Composer ---- */
-.rgchat-composer {
- border-top: 1px solid var(--rgchat-border);
- padding: 8px 10px;
- background: var(--rgchat-panel);
- position: relative;
- box-shadow: 0 -4px 14px rgba(15, 23, 42, 0.05);
-}
-
-.rgchat-composer__row {
- display: flex;
- align-items: flex-end;
- gap: 6px;
-}
-
-.rgchat-composer__text {
- flex: 1;
- resize: none;
- max-height: 122px;
- min-height: 38px;
- padding: 9px 12px;
- border: 1px solid var(--rgchat-border);
- border-radius: 18px;
- font-family: inherit;
- font-size: 14px;
- outline: none;
- background: var(--rgchat-input-bg);
- color: var(--rgchat-ink);
- overflow-y: auto;
- transition: border-color 140ms ease;
-}
-
-.rgchat-composer__text:focus {
- border-color: var(--rgchat-accent);
-}
-
-.rgchat-send {
- border: none;
- background: var(--rgchat-accent);
- color: #fff;
- width: 38px;
- height: 38px;
- border-radius: 50%;
- cursor: pointer;
- font-size: 16px;
- flex-shrink: 0;
- transition: transform 140ms ease, box-shadow 140ms ease;
-}
-
-.rgchat-send:hover:not(:disabled) {
- transform: translateY(-1px);
- box-shadow: 0 6px 14px rgba(26, 179, 148, 0.4);
-}
-
-.rgchat-send:disabled {
- opacity: 0.5;
- cursor: default;
-}
-
-.rgchat-composer__tools {
- display: flex;
- gap: 2px;
-}
-
-.rgchat-composer__tool {
- color: var(--rgchat-muted);
-}
-
-.rgchat-composer__tool--gif {
- font-weight: 700;
- font-size: 12px;
-}
-
-.rgchat-composer__count {
- align-self: center;
- font-size: 11px;
- font-weight: 600;
- color: var(--rgchat-muted);
- padding: 0 2px;
-}
-
-.rgchat-composer__urgent {
- display: inline-flex;
- align-items: center;
- gap: 4px;
- margin-top: 8px;
- font-size: 12px;
- color: var(--rgchat-urgent);
- cursor: pointer;
- user-select: none;
-}
-
-.rgchat-fileinput {
- display: none;
-}
-
-.rgchat-popover {
- position: absolute;
- bottom: 56px;
- left: 10px;
- right: 10px;
- max-height: 240px;
- overflow-y: auto;
- background: var(--rgchat-panel);
- border: 1px solid var(--rgchat-border);
- border-radius: 12px;
- box-shadow: var(--rgchat-shadow-pop);
- padding: 8px;
- z-index: 5;
- animation: rgchat-pop-in 140ms ease;
-}
-
-.rgchat-popover--reactions {
- left: auto;
- right: 0;
- bottom: 30px;
- display: flex;
- gap: 2px;
- padding: 6px;
- max-height: none;
- overflow: visible;
- width: max-content;
-}
-
-.rgchat-popover__note {
- padding: 8px;
- font-size: 12px;
- color: var(--rgchat-muted);
-}
-
-.rgchat-popover__emoji {
- border: none;
- background: transparent;
- font-size: 18px;
- cursor: pointer;
- padding: 4px;
- border-radius: 6px;
- min-width: 32px;
- min-height: 32px;
- transition: background-color 140ms ease;
-}
-
-.rgchat-popover__emoji:hover {
- background: var(--rgchat-hover);
-}
-
-.rgchat-emojigrid {
- display: grid;
- grid-template-columns: repeat(8, 1fr);
- gap: 2px;
-}
-
-.rgchat-emojigrid button {
- border: none;
- background: transparent;
- font-size: 18px;
- padding: 4px;
- min-width: 32px;
- min-height: 32px;
- border-radius: 6px;
- cursor: pointer;
- transition: background-color 140ms ease;
-}
-
-.rgchat-emojigrid button:hover {
- background: var(--rgchat-hover);
-}
-
-.rgchat-gifgrid {
- display: grid;
- grid-template-columns: repeat(3, 1fr);
- gap: 4px;
- margin-top: 8px;
-}
-
-.rgchat-gifgrid img {
- width: 100%;
- height: 78px;
- object-fit: cover;
- border-radius: 6px;
- cursor: pointer;
-}
-
-/* ---- Urgent ack banner ---- */
-.rgchat-ackbanner {
- display: flex;
- align-items: center;
- gap: 10px;
- padding: 8px 12px;
- background: rgba(216, 54, 76, 0.1);
- border-bottom: 1px solid rgba(216, 54, 76, 0.3);
- color: #a32738;
- font-size: 12px;
- font-weight: 600;
-}
-
-.rgchat-ackbanner button {
- margin-left: auto;
- border: none;
- background: var(--rgchat-urgent);
- color: #fff;
- padding: 6px 12px;
- border-radius: 8px;
- cursor: pointer;
- font-weight: 700;
-}
-
-/* ---- Skeletons ---- */
-.rgchat-skeletons {
- display: flex;
- flex-direction: column;
- gap: 10px;
- padding: 4px 0;
-}
-
-.rgchat-skeletonrow {
- display: flex;
- align-items: center;
- gap: 8px;
-}
-
-.rgchat-skeletonrow--chan {
- padding: 8px 12px;
-}
-
-.rgchat-skeleton {
- display: inline-block;
- border-radius: 8px;
- background: linear-gradient(90deg, rgba(47, 64, 80, 0.08) 25%, rgba(47, 64, 80, 0.16) 50%, rgba(47, 64, 80, 0.08) 75%);
- background-size: 200% 100%;
- animation: rgchat-shimmer 1.4s infinite;
-}
-
-.rgchat-skeleton--avatar {
- width: 38px;
- height: 38px;
- border-radius: 50%;
- flex-shrink: 0;
-}
-
-.rgchat-skeleton--bubble {
- height: 38px;
- border-radius: 14px;
-}
-
-.rgchat-skeleton--line {
- height: 14px;
- width: 60%;
-}
-
-.rgchat-skeleton--img {
- width: 240px;
- height: 160px;
- border-radius: 10px;
-}
-
-@keyframes rgchat-shimmer {
- from { background-position: 200% 0; }
- to { background-position: -200% 0; }
-}
-
-/* ---- Lightbox ---- */
-.rgchat-lightbox {
- position: fixed;
- inset: 0;
- z-index: 12300;
- background: rgba(15, 23, 42, 0.82);
- display: flex;
- align-items: center;
- justify-content: center;
- padding: 24px;
- cursor: zoom-out;
- animation: rgchat-fade-in 140ms ease;
-}
-
-.rgchat-lightbox img {
- max-width: 100%;
- max-height: 100%;
- border-radius: 10px;
- box-shadow: 0 24px 60px rgba(0, 0, 0, 0.5);
-}
-
-@keyframes rgchat-fade-in {
- from { opacity: 0; }
- to { opacity: 1; }
-}
-
-/* ---- Empty / states ---- */
-.rgchat-empty {
- flex: 1;
- display: flex;
- flex-direction: column;
- align-items: center;
- justify-content: center;
- gap: 8px;
- padding: 24px;
- color: var(--rgchat-muted);
- text-align: center;
-}
-
-.rgchat-empty__icon {
- font-size: 40px;
-}
-
-.rgchat-btn {
- border: none;
- border-radius: 8px;
- padding: 8px 14px;
- font-weight: 600;
- cursor: pointer;
- font-size: 13px;
- transition: background-color 140ms ease, opacity 140ms ease;
-}
-
-.rgchat-btn--primary {
- background: var(--rgchat-accent);
- color: #fff;
-}
-
-.rgchat-btn--ghost {
- background: transparent;
- border: 1px solid var(--rgchat-border);
- color: var(--rgchat-ink);
-}
-
-.rgchat-btn--danger {
- background: var(--rgchat-urgent);
- color: #fff;
-}
-
-.rgchat-btn:disabled {
- opacity: 0.55;
- cursor: default;
-}
-
-/* ---- Dialog ---- */
-.rgchat-dialog__backdrop {
- position: fixed;
- inset: 0;
- z-index: 12100;
- background: rgba(15, 23, 42, 0.42);
- display: flex;
- align-items: center;
- justify-content: center;
- padding: 16px;
- animation: rgchat-fade-in 140ms ease;
-}
-
-.rgchat-dialog {
- width: 100%;
- max-width: 424px;
- max-height: 80vh;
- display: flex;
- flex-direction: column;
- background: var(--rgchat-panel);
- color: var(--rgchat-ink);
- border-radius: 16px;
- overflow: hidden;
- outline: none;
- animation: rgchat-panel-in 160ms ease;
-}
-
-.rgchat-dialog__head {
- padding: 14px 16px;
- border-bottom: 1px solid var(--rgchat-border);
- font-weight: 700;
- font-size: 15px;
- display: flex;
- align-items: center;
-}
-
-.rgchat-dialog__body {
- padding: 14px 16px;
- overflow-y: auto;
-}
-
-.rgchat-dialog__foot {
- padding: 12px 16px;
- border-top: 1px solid var(--rgchat-border);
- display: flex;
- justify-content: flex-end;
- gap: 8px;
-}
-
-.rgchat-dialog__field {
- margin-top: 8px;
-}
-
-.rgchat-dialog__select {
- width: 200px;
-}
-
-.rgchat-dialog__list {
- margin-top: 8px;
- max-height: 300px;
- overflow-y: auto;
-}
-
-.rgchat-pick {
- display: flex;
- align-items: center;
- gap: 8px;
- padding: 8px;
- border-radius: 8px;
- cursor: pointer;
- transition: background-color 140ms ease;
-}
-
-.rgchat-pick:hover {
- background: var(--rgchat-hover);
-}
-
-/* ---- Full page (3-pane) ---- */
-.rgchat-page {
- display: flex;
- height: calc(100vh - 190px);
- min-height: 520px;
- border: 1px solid var(--rgchat-border);
- border-radius: 12px;
- overflow: hidden;
- background: var(--rgchat-panel);
-}
-
-.rgchat-page__sidebar {
- width: 280px;
- flex-shrink: 0;
- display: flex;
- flex-direction: column;
- border-right: 1px solid var(--rgchat-border);
- background: var(--rgchat-bg);
-}
-
-.rgchat-page__sidebar-head {
- padding: 12px;
- display: flex;
- gap: 8px;
- align-items: center;
-}
-
-.rgchat-page__center {
- flex: 1;
- min-width: 0;
- display: flex;
- flex-direction: column;
-}
-
-.rgchat-page__aside {
- width: 300px;
- flex-shrink: 0;
- border-left: 1px solid var(--rgchat-border);
- background: var(--rgchat-bg);
- display: flex;
- flex-direction: column;
- overflow-y: auto;
-}
-
-.rgchat-aside__tabs {
- display: flex;
- border-bottom: 1px solid var(--rgchat-border);
-}
-
-.rgchat-aside__tab {
- flex: 1;
- padding: 10px;
- border: none;
- background: transparent;
- cursor: pointer;
- font-weight: 600;
- color: var(--rgchat-muted);
- font-size: 12px;
- transition: color 140ms ease;
-}
-
-.rgchat-aside__tab--active {
- color: var(--rgchat-accent-ink);
- box-shadow: inset 0 -2px 0 var(--rgchat-accent);
-}
-
-.rgchat-aside__section {
- padding: 12px;
-}
-
-.rgchat-member {
- display: flex;
- align-items: center;
- gap: 8px;
- padding: 6px 4px;
-}
-
-.rgchat-member__name {
- flex: 1;
- min-width: 0;
- font-weight: 600;
- white-space: nowrap;
- overflow: hidden;
- text-overflow: ellipsis;
-}
-
-.rgchat-member__actions {
- display: flex;
- gap: 4px;
-}
-
-.rgchat-tag {
- font-size: 10px;
- font-weight: 700;
- padding: 1px 6px;
- border-radius: 999px;
- background: rgba(47, 64, 80, 0.1);
- color: var(--rgchat-dark);
-}
-
-.rgchat-pin {
- margin-bottom: 8px;
-}
-
-.rgchat-pin__meta {
- margin: 0 0 4px;
-}
-
-@media (max-width: 900px) {
- .rgchat-page__aside {
- display: none;
- }
-}
-
-@media (max-width: 680px) {
- .rgchat-page__sidebar {
- width: 220px;
- }
- .rgchat-panel {
- width: calc(100vw - 24px);
- right: 12px;
- }
-}
-
-/* ---- Chatbot ---- */
-.rgchat-botframe {
- height: calc(100vh - 220px);
- min-height: 480px;
- border: 1px solid var(--rgchat-border);
- border-radius: 12px;
- overflow: hidden;
- display: flex;
- flex-direction: column;
-}
-
-.rgchat-botframe .rgchat-convo {
- flex: 1;
-}
-
-.rgchat-bot .rgchat-bubble--bot {
- background: #eef4ff;
- border-color: #d7e3ff;
- color: #1f2d3d;
-}
-
-.rgchat-bot__head {
- background: linear-gradient(135deg, #5b6bc0, #2f4050);
- color: #fff;
-}
-
-.rgchat-bot__head .rgchat-convo__title {
- color: #fff;
-}
-
-.rgchat-bot__head .rgchat-convo__sub {
- color: rgba(255, 255, 255, 0.78);
-}
-
-/* ---- Moderation ---- */
-.rgchat-mod {
- border: 1px solid var(--rgchat-border);
- border-radius: 12px;
- overflow: hidden;
- background: var(--rgchat-panel);
-}
-
-.rgchat-mod__tabs {
- display: flex;
- border-bottom: 1px solid var(--rgchat-border);
- background: var(--rgchat-bg);
-}
-
-.rgchat-mod__tab {
- padding: 12px 18px;
- border: none;
- background: transparent;
- cursor: pointer;
- font-weight: 600;
- color: var(--rgchat-muted);
-}
-
-.rgchat-mod__tab--active {
- color: var(--rgchat-dark);
- background: var(--rgchat-panel);
- box-shadow: inset 0 -2px 0 var(--rgchat-accent);
-}
-
-.rgchat-mod__body {
- padding: 16px;
-}
-
-.rgchat-table {
- width: 100%;
- border-collapse: collapse;
- font-size: 13px;
-}
-
-.rgchat-table th,
-.rgchat-table td {
- text-align: left;
- padding: 9px 10px;
- border-bottom: 1px solid var(--rgchat-border);
- vertical-align: top;
-}
-
-.rgchat-table th {
- color: var(--rgchat-muted);
- font-size: 11px;
- text-transform: uppercase;
- letter-spacing: 0.04em;
-}
-
-.rgchat-form-row {
- display: flex;
- align-items: center;
- gap: 10px;
- padding: 8px 0;
-}
-
-.rgchat-form-row label {
- flex: 1;
- font-weight: 600;
-}
-
-.rgchat-pill {
- display: inline-block;
- padding: 2px 8px;
- border-radius: 999px;
- font-size: 11px;
- font-weight: 700;
-}
-
-.rgchat-pill--open { background: rgba(248, 172, 89, 0.2); color: #8a5a10; }
-.rgchat-pill--done { background: rgba(26, 179, 148, 0.16); color: var(--rgchat-accent-ink); }
-.rgchat-pill--muted { background: rgba(91, 107, 124, 0.16); color: var(--rgchat-muted); }
-
-.rgchat-error {
- padding: 10px 12px;
- border-radius: 8px;
- background: #fef2f2;
- border: 1px solid #fecaca;
- color: #991b1b;
- font-size: 12px;
- margin: 8px 0;
-}
-
-/* ---- Dark mode ---- */
-@media (prefers-color-scheme: dark) {
- .rgchat-root {
- --rgchat-dark: #141c26;
- --rgchat-bg: #131a23;
- --rgchat-panel: #1c2632;
- --rgchat-border: #2c3a4a;
- --rgchat-muted: #9aa8b8;
- --rgchat-ink: #e6edf4;
- --rgchat-own-bg: #123c33;
- --rgchat-own-ink: #d9f3ea;
- --rgchat-own-border: #1f5c4c;
- --rgchat-hover: rgba(255, 255, 255, 0.07);
- --rgchat-bubble-bg: #223041;
- --rgchat-input-bg: #141c26;
- --rgchat-shadow-pop: 0 12px 30px rgba(0, 0, 0, 0.55);
- }
-
- .rgchat-daydivider {
- background: rgba(255, 255, 255, 0.09);
- }
-
- .rgchat-chan--active {
- background: rgba(26, 179, 148, 0.2);
- }
-
- .rgchat-reaction--mine {
- background: rgba(26, 179, 148, 0.22);
- }
-
- .rgchat-skeleton {
- background: linear-gradient(90deg, rgba(255, 255, 255, 0.06) 25%, rgba(255, 255, 255, 0.14) 50%, rgba(255, 255, 255, 0.06) 75%);
- background-size: 200% 100%;
- }
-
- .rgchat-bot .rgchat-bubble--bot {
- background: #223152;
- border-color: #31436e;
- color: #e6edf4;
- }
-
- .rgchat-tag {
- background: rgba(255, 255, 255, 0.12);
- color: #cdd8e4;
- }
-
- .rgchat-error {
- background: rgba(216, 54, 76, 0.14);
- border-color: rgba(216, 54, 76, 0.4);
- color: #f3b4bd;
- }
-}
-
-/* ---- Reduced motion ---- */
-@media (prefers-reduced-motion: reduce) {
- .rgchat-root *,
- .rgchat-root *::before,
- .rgchat-root *::after {
- animation-duration: 0.01ms !important;
- animation-iteration-count: 1 !important;
- transition-duration: 0.01ms !important;
- }
-}
-.mapboxgl-map{font:12px/20px Helvetica Neue,Arial,Helvetica,sans-serif;overflow:hidden;position:relative;-webkit-tap-highlight-color:rgb(0 0 0/0)}.mapboxgl-canvas{left:0;position:absolute;top:0}.mapboxgl-map:-webkit-full-screen{height:100%;width:100%}.mapboxgl-canary{background-color:salmon}.mapboxgl-canvas-container.mapboxgl-interactive,.mapboxgl-ctrl-group button.mapboxgl-ctrl-compass{cursor:grab;-webkit-user-select:none;user-select:none}.mapboxgl-canvas-container.mapboxgl-interactive.mapboxgl-track-pointer{cursor:pointer}.mapboxgl-canvas-container.mapboxgl-interactive:active,.mapboxgl-ctrl-group button.mapboxgl-ctrl-compass:active{cursor:grabbing}.mapboxgl-canvas-container.mapboxgl-touch-zoom-rotate,.mapboxgl-canvas-container.mapboxgl-touch-zoom-rotate .mapboxgl-canvas{touch-action:pan-x pan-y}.mapboxgl-canvas-container.mapboxgl-touch-drag-pan,.mapboxgl-canvas-container.mapboxgl-touch-drag-pan .mapboxgl-canvas{touch-action:pinch-zoom}.mapboxgl-canvas-container.mapboxgl-touch-zoom-rotate.mapboxgl-touch-drag-pan,.mapboxgl-canvas-container.mapboxgl-touch-zoom-rotate.mapboxgl-touch-drag-pan .mapboxgl-canvas{touch-action:none}.mapboxgl-ctrl-bottom,.mapboxgl-ctrl-bottom-left,.mapboxgl-ctrl-bottom-right,.mapboxgl-ctrl-left,.mapboxgl-ctrl-right,.mapboxgl-ctrl-top,.mapboxgl-ctrl-top-left,.mapboxgl-ctrl-top-right{pointer-events:none;position:absolute;z-index:2}.mapboxgl-ctrl-top-left{left:0;top:0}.mapboxgl-ctrl-top{left:50%;top:0;transform:translateX(-50%)}.mapboxgl-ctrl-top-right{right:0;top:0}.mapboxgl-ctrl-right{right:0;top:50%;transform:translateY(-50%)}.mapboxgl-ctrl-bottom-right{bottom:0;right:0}.mapboxgl-ctrl-bottom{bottom:0;left:50%;transform:translateX(-50%)}.mapboxgl-ctrl-bottom-left{bottom:0;left:0}.mapboxgl-ctrl-left{left:0;top:50%;transform:translateY(-50%)}.mapboxgl-ctrl{clear:both;pointer-events:auto;transform:translate(0)}.mapboxgl-ctrl-top-left .mapboxgl-ctrl{float:left;margin:10px 0 0 10px}.mapboxgl-ctrl-top .mapboxgl-ctrl{float:left;margin:10px 0}.mapboxgl-ctrl-top-right .mapboxgl-ctrl{float:right;margin:10px 10px 0 0}.mapboxgl-ctrl-bottom-right .mapboxgl-ctrl,.mapboxgl-ctrl-right .mapboxgl-ctrl{float:right;margin:0 10px 10px 0}.mapboxgl-ctrl-bottom .mapboxgl-ctrl{float:left;margin:10px 0}.mapboxgl-ctrl-bottom-left .mapboxgl-ctrl,.mapboxgl-ctrl-left .mapboxgl-ctrl{float:left;margin:0 0 10px 10px}.mapboxgl-ctrl-group{background:#fff;border-radius:4px}.mapboxgl-ctrl-group:not(:empty){box-shadow:0 0 0 2px #0000001a}@media (-ms-high-contrast:active){.mapboxgl-ctrl-group:not(:empty){box-shadow:0 0 0 2px ButtonText}}.mapboxgl-ctrl-group button{background-color:initial;border:0;box-sizing:border-box;cursor:pointer;display:block;height:32px;outline:none;overflow:hidden;padding:0;width:32px}.mapboxgl-ctrl-group button+button{border-top:1px solid #ddd}.mapboxgl-ctrl button .mapboxgl-ctrl-icon{background-position:50%;background-repeat:no-repeat;display:block;height:100%;width:100%}@media (-ms-high-contrast:active){.mapboxgl-ctrl-icon{background-color:initial}.mapboxgl-ctrl-group button+button{border-top:1px solid ButtonText}}.mapboxgl-ctrl-attrib-button:focus,.mapboxgl-ctrl-group button:focus{box-shadow:0 0 2px 2px #0096ff}.mapboxgl-ctrl button:disabled{cursor:not-allowed}.mapboxgl-ctrl button:disabled .mapboxgl-ctrl-icon{opacity:.25}.mapboxgl-ctrl-group button:first-child{border-radius:4px 4px 0 0}.mapboxgl-ctrl-group button:last-child{border-radius:0 0 4px 4px}.mapboxgl-ctrl-group button:only-child{border-radius:inherit}.mapboxgl-ctrl button:not(:disabled):hover{background-color:#eee}.mapboxgl-ctrl-group button:focus:focus-visible{box-shadow:0 0 2px 2px #0096ff}.mapboxgl-ctrl-group button:focus:not(:focus-visible){box-shadow:none}.mapboxgl-ctrl button.mapboxgl-ctrl-zoom-out .mapboxgl-ctrl-icon{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='%23333' viewBox='0 0 29 29'%3E%3Cpath d='M10 13c-.75 0-1.5.75-1.5 1.5S9.25 16 10 16h9c.75 0 1.5-.75 1.5-1.5S19.75 13 19 13h-9z'/%3E%3C/svg%3E")}.mapboxgl-ctrl button.mapboxgl-ctrl-zoom-in .mapboxgl-ctrl-icon{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='%23333' viewBox='0 0 29 29'%3E%3Cpath d='M14.5 8.5c-.75 0-1.5.75-1.5 1.5v3h-3c-.75 0-1.5.75-1.5 1.5S9.25 16 10 16h3v3c0 .75.75 1.5 1.5 1.5S16 19.75 16 19v-3h3c.75 0 1.5-.75 1.5-1.5S19.75 13 19 13h-3v-3c0-.75-.75-1.5-1.5-1.5z'/%3E%3C/svg%3E")}@media (-ms-high-contrast:active){.mapboxgl-ctrl button.mapboxgl-ctrl-zoom-out .mapboxgl-ctrl-icon{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='%23fff' viewBox='0 0 29 29'%3E%3Cpath d='M10 13c-.75 0-1.5.75-1.5 1.5S9.25 16 10 16h9c.75 0 1.5-.75 1.5-1.5S19.75 13 19 13h-9z'/%3E%3C/svg%3E")}.mapboxgl-ctrl button.mapboxgl-ctrl-zoom-in .mapboxgl-ctrl-icon{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='%23fff' viewBox='0 0 29 29'%3E%3Cpath d='M14.5 8.5c-.75 0-1.5.75-1.5 1.5v3h-3c-.75 0-1.5.75-1.5 1.5S9.25 16 10 16h3v3c0 .75.75 1.5 1.5 1.5S16 19.75 16 19v-3h3c.75 0 1.5-.75 1.5-1.5S19.75 13 19 13h-3v-3c0-.75-.75-1.5-1.5-1.5z'/%3E%3C/svg%3E")}}@media (-ms-high-contrast:black-on-white){.mapboxgl-ctrl button.mapboxgl-ctrl-zoom-out .mapboxgl-ctrl-icon{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='%23000' viewBox='0 0 29 29'%3E%3Cpath d='M10 13c-.75 0-1.5.75-1.5 1.5S9.25 16 10 16h9c.75 0 1.5-.75 1.5-1.5S19.75 13 19 13h-9z'/%3E%3C/svg%3E")}.mapboxgl-ctrl button.mapboxgl-ctrl-zoom-in .mapboxgl-ctrl-icon{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='%23000' viewBox='0 0 29 29'%3E%3Cpath d='M14.5 8.5c-.75 0-1.5.75-1.5 1.5v3h-3c-.75 0-1.5.75-1.5 1.5S9.25 16 10 16h3v3c0 .75.75 1.5 1.5 1.5S16 19.75 16 19v-3h3c.75 0 1.5-.75 1.5-1.5S19.75 13 19 13h-3v-3c0-.75-.75-1.5-1.5-1.5z'/%3E%3C/svg%3E")}}.mapboxgl-ctrl button.mapboxgl-ctrl-fullscreen .mapboxgl-ctrl-icon{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='%23333' viewBox='0 0 29 29'%3E%3Cpath d='M24 16v5.5c0 1.75-.75 2.5-2.5 2.5H16v-1l3-1.5-4-5.5 1-1 5.5 4 1.5-3h1zM6 16l1.5 3 5.5-4 1 1-4 5.5 3 1.5v1H7.5C5.75 24 5 23.25 5 21.5V16h1zm7-11v1l-3 1.5 4 5.5-1 1-5.5-4L6 13H5V7.5C5 5.75 5.75 5 7.5 5H13zm11 2.5c0-1.75-.75-2.5-2.5-2.5H16v1l3 1.5-4 5.5 1 1 5.5-4 1.5 3h1V7.5z'/%3E%3C/svg%3E")}.mapboxgl-ctrl button.mapboxgl-ctrl-shrink .mapboxgl-ctrl-icon{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 29 29'%3E%3Cpath d='M18.5 16c-1.75 0-2.5.75-2.5 2.5V24h1l1.5-3 5.5 4 1-1-4-5.5 3-1.5v-1h-5.5zM13 18.5c0-1.75-.75-2.5-2.5-2.5H5v1l3 1.5L4 24l1 1 5.5-4 1.5 3h1v-5.5zm3-8c0 1.75.75 2.5 2.5 2.5H24v-1l-3-1.5L25 5l-1-1-5.5 4L17 5h-1v5.5zM10.5 13c1.75 0 2.5-.75 2.5-2.5V5h-1l-1.5 3L5 4 4 5l4 5.5L5 12v1h5.5z'/%3E%3C/svg%3E")}@media (-ms-high-contrast:active){.mapboxgl-ctrl button.mapboxgl-ctrl-fullscreen .mapboxgl-ctrl-icon{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='%23fff' viewBox='0 0 29 29'%3E%3Cpath d='M24 16v5.5c0 1.75-.75 2.5-2.5 2.5H16v-1l3-1.5-4-5.5 1-1 5.5 4 1.5-3h1zM6 16l1.5 3 5.5-4 1 1-4 5.5 3 1.5v1H7.5C5.75 24 5 23.25 5 21.5V16h1zm7-11v1l-3 1.5 4 5.5-1 1-5.5-4L6 13H5V7.5C5 5.75 5.75 5 7.5 5H13zm11 2.5c0-1.75-.75-2.5-2.5-2.5H16v1l3 1.5-4 5.5 1 1 5.5-4 1.5 3h1V7.5z'/%3E%3C/svg%3E")}.mapboxgl-ctrl button.mapboxgl-ctrl-shrink .mapboxgl-ctrl-icon{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='%23fff' viewBox='0 0 29 29'%3E%3Cpath d='M18.5 16c-1.75 0-2.5.75-2.5 2.5V24h1l1.5-3 5.5 4 1-1-4-5.5 3-1.5v-1h-5.5zM13 18.5c0-1.75-.75-2.5-2.5-2.5H5v1l3 1.5L4 24l1 1 5.5-4 1.5 3h1v-5.5zm3-8c0 1.75.75 2.5 2.5 2.5H24v-1l-3-1.5L25 5l-1-1-5.5 4L17 5h-1v5.5zM10.5 13c1.75 0 2.5-.75 2.5-2.5V5h-1l-1.5 3L5 4 4 5l4 5.5L5 12v1h5.5z'/%3E%3C/svg%3E")}}@media (-ms-high-contrast:black-on-white){.mapboxgl-ctrl button.mapboxgl-ctrl-fullscreen .mapboxgl-ctrl-icon{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='%23000' viewBox='0 0 29 29'%3E%3Cpath d='M24 16v5.5c0 1.75-.75 2.5-2.5 2.5H16v-1l3-1.5-4-5.5 1-1 5.5 4 1.5-3h1zM6 16l1.5 3 5.5-4 1 1-4 5.5 3 1.5v1H7.5C5.75 24 5 23.25 5 21.5V16h1zm7-11v1l-3 1.5 4 5.5-1 1-5.5-4L6 13H5V7.5C5 5.75 5.75 5 7.5 5H13zm11 2.5c0-1.75-.75-2.5-2.5-2.5H16v1l3 1.5-4 5.5 1 1 5.5-4 1.5 3h1V7.5z'/%3E%3C/svg%3E")}.mapboxgl-ctrl button.mapboxgl-ctrl-shrink .mapboxgl-ctrl-icon{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='%23000' viewBox='0 0 29 29'%3E%3Cpath d='M18.5 16c-1.75 0-2.5.75-2.5 2.5V24h1l1.5-3 5.5 4 1-1-4-5.5 3-1.5v-1h-5.5zM13 18.5c0-1.75-.75-2.5-2.5-2.5H5v1l3 1.5L4 24l1 1 5.5-4 1.5 3h1v-5.5zm3-8c0 1.75.75 2.5 2.5 2.5H24v-1l-3-1.5L25 5l-1-1-5.5 4L17 5h-1v5.5zM10.5 13c1.75 0 2.5-.75 2.5-2.5V5h-1l-1.5 3L5 4 4 5l4 5.5L5 12v1h5.5z'/%3E%3C/svg%3E")}}.mapboxgl-ctrl button.mapboxgl-ctrl-compass .mapboxgl-ctrl-icon{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='%23333' viewBox='0 0 29 29'%3E%3Cpath d='M10.5 14l4-8 4 8h-8z'/%3E%3Cpath id='south' d='M10.5 16l4 8 4-8h-8z' fill='%23ccc'/%3E%3C/svg%3E")}@media (-ms-high-contrast:active){.mapboxgl-ctrl button.mapboxgl-ctrl-compass .mapboxgl-ctrl-icon{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='%23fff' viewBox='0 0 29 29'%3E%3Cpath d='M10.5 14l4-8 4 8h-8z'/%3E%3Cpath id='south' d='M10.5 16l4 8 4-8h-8z' fill='%23999'/%3E%3C/svg%3E")}}@media (-ms-high-contrast:black-on-white){.mapboxgl-ctrl button.mapboxgl-ctrl-compass .mapboxgl-ctrl-icon{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='%23000' viewBox='0 0 29 29'%3E%3Cpath d='M10.5 14l4-8 4 8h-8z'/%3E%3Cpath id='south' d='M10.5 16l4 8 4-8h-8z' fill='%23ccc'/%3E%3C/svg%3E")}}.mapboxgl-ctrl button.mapboxgl-ctrl-arrow-up .mapboxgl-ctrl-icon{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg fill='%23333' xmlns='http://www.w3.org/2000/svg' viewBox='0 0 18 18'%3E%3Cpath fill-rule='evenodd' clip-rule='evenodd' d='M4.29289 11.7071C4.68342 12.0976 5.31658 12.0976 5.70711 11.7071L9 8.41421L12.2929 11.7071C12.6834 12.0976 13.3166 12.0976 13.7071 11.7071C14.0976 11.3166 14.0976 10.6834 13.7071 10.2929L9.70711 6.29289C9.31658 5.90237 8.68342 5.90237 8.29289 6.29289L4.29289 10.2929C3.90237 10.6834 3.90237 11.3166 4.29289 11.7071Z' fill='%23333333'/%3E%3C/svg%3E");background-size:18px 18px}.mapboxgl-ctrl button.mapboxgl-ctrl-arrow-down .mapboxgl-ctrl-icon{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg fill='%23333' xmlns='http://www.w3.org/2000/svg' viewBox='0 0 18 18'%3E%3Cpath fill-rule='evenodd' clip-rule='evenodd' d='M4.29289 6.29289C4.68342 5.90237 5.31658 5.90237 5.70711 6.29289L9 9.58579L12.2929 6.29289C12.6834 5.90237 13.3166 5.90237 13.7071 6.29289C14.0976 6.68342 14.0976 7.31658 13.7071 7.70711L9.70711 11.7071C9.31658 12.0976 8.68342 12.0976 8.29289 11.7071L4.29289 7.70711C3.90237 7.31658 3.90237 6.68342 4.29289 6.29289Z' fill='%23333333'/%3E%3C/svg%3E");background-size:18px 18px}.mapboxgl-ctrl button.mapboxgl-ctrl-indoor-toggle .mapboxgl-ctrl-icon{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg fill='%23333' xmlns='http://www.w3.org/2000/svg' viewBox='0 0 18 18'%3E%3Cpath d='M4.0017 3.0017L4.0017 15.0017L10.0017 15.0017V12.0017H12.0017V15.0017H14.0017L14.0017 3.0017C14.0097 2.86829 13.9894 2.73469 13.9419 2.60973C13.8945 2.48477 13.8211 2.37129 13.7266 2.27678C13.6321 2.18228 13.5186 2.10889 13.3937 2.06147C13.2687 2.01405 13.1351 1.99368 13.0017 2.0017L5.0017 2.0017C4.86829 1.99368 4.73469 2.01405 4.60973 2.06147C4.48477 2.10889 4.37129 2.18228 4.27678 2.27678C4.18228 2.37129 4.10889 2.48477 4.06147 2.60973C4.01405 2.73469 3.99368 2.86829 4.0017 3.0017ZM8.0017 14.0017H6.0017V12.0017H8.0017V14.0017ZM8.0017 10.0017H6.0017L6.0017 8.0017H8.0017V10.0017ZM8.0017 6.0017L6.0017 6.0017V4.0017H8.0017V6.0017ZM12.0017 10.0017H10.0017V8.0017H12.0017V10.0017ZM12.0017 6.0017H10.0017V4.0017L12.0017 4.0017V6.0017Z' fill='%23333333'/%3E%3C/svg%3E");background-size:18px 18px}@media (-ms-high-contrast:active){.mapboxgl-ctrl button.mapboxgl-ctrl-indoor-toggle .mapboxgl-ctrl-icon{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg fill='%23fff' xmlns='http://www.w3.org/2000/svg' viewBox='0 0 18 18'%3E%3Cpath d='M4.0017 3.0017L4.0017 15.0017L10.0017 15.0017V12.0017H12.0017V15.0017H14.0017L14.0017 3.0017C14.0097 2.86829 13.9894 2.73469 13.9419 2.60973C13.8945 2.48477 13.8211 2.37129 13.7266 2.27678C13.6321 2.18228 13.5186 2.10889 13.3937 2.06147C13.2687 2.01405 13.1351 1.99368 13.0017 2.0017L5.0017 2.0017C4.86829 1.99368 4.73469 2.01405 4.60973 2.06147C4.48477 2.10889 4.37129 2.18228 4.27678 2.27678C4.18228 2.37129 4.10889 2.48477 4.06147 2.60973C4.01405 2.73469 3.99368 2.86829 4.0017 3.0017ZM8.0017 14.0017H6.0017V12.0017H8.0017V14.0017ZM8.0017 10.0017H6.0017L6.0017 8.0017H8.0017V10.0017ZM8.0017 6.0017L6.0017 6.0017V4.0017H8.0017V6.0017ZM12.0017 10.0017H10.0017V8.0017H12.0017V10.0017ZM12.0017 6.0017H10.0017V4.0017L12.0017 4.0017V6.0017Z' fill='%23333333'/%3E%3C/svg%3E")}}@media (-ms-high-contrast:black-on-white){.mapboxgl-ctrl button.mapboxgl-ctrl-indoor-toggle .mapboxgl-ctrl-icon{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg fill='%23000' xmlns='http://www.w3.org/2000/svg' viewBox='0 0 18 18'%3E%3Cpath d='M4.0017 3.0017L4.0017 15.0017L10.0017 15.0017V12.0017H12.0017V15.0017H14.0017L14.0017 3.0017C14.0097 2.86829 13.9894 2.73469 13.9419 2.60973C13.8945 2.48477 13.8211 2.37129 13.7266 2.27678C13.6321 2.18228 13.5186 2.10889 13.3937 2.06147C13.2687 2.01405 13.1351 1.99368 13.0017 2.0017L5.0017 2.0017C4.86829 1.99368 4.73469 2.01405 4.60973 2.06147C4.48477 2.10889 4.37129 2.18228 4.27678 2.27678C4.18228 2.37129 4.10889 2.48477 4.06147 2.60973C4.01405 2.73469 3.99368 2.86829 4.0017 3.0017ZM8.0017 14.0017H6.0017V12.0017H8.0017V14.0017ZM8.0017 10.0017H6.0017L6.0017 8.0017H8.0017V10.0017ZM8.0017 6.0017L6.0017 6.0017V4.0017H8.0017V6.0017ZM12.0017 10.0017H10.0017V8.0017H12.0017V10.0017ZM12.0017 6.0017H10.0017V4.0017L12.0017 4.0017V6.0017Z' fill='%23333333'/%3E%3C/svg%3E")}}.mapboxgl-ctrl button.mapboxgl-ctrl-geolocate .mapboxgl-ctrl-icon{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg viewBox='0 0 20 20' xmlns='http://www.w3.org/2000/svg' fill='%23333'%3E%3Cpath d='M10 4C9 4 9 5 9 5v.1A5 5 0 0 0 5.1 9H5s-1 0-1 1 1 1 1 1h.1A5 5 0 0 0 9 14.9v.1s0 1 1 1 1-1 1-1v-.1a5 5 0 0 0 3.9-3.9h.1s1 0 1-1-1-1-1-1h-.1A5 5 0 0 0 11 5.1V5s0-1-1-1zm0 2.5a3.5 3.5 0 1 1 0 7 3.5 3.5 0 1 1 0-7z'/%3E%3Ccircle id='dot' cx='10' cy='10' r='2'/%3E%3Cpath id='stroke' d='M14 5l1 1-9 9-1-1 9-9z' display='none'/%3E%3C/svg%3E")}.mapboxgl-ctrl button.mapboxgl-ctrl-geolocate:disabled .mapboxgl-ctrl-icon{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg viewBox='0 0 20 20' xmlns='http://www.w3.org/2000/svg' fill='%23aaa'%3E%3Cpath d='M10 4C9 4 9 5 9 5v.1A5 5 0 0 0 5.1 9H5s-1 0-1 1 1 1 1 1h.1A5 5 0 0 0 9 14.9v.1s0 1 1 1 1-1 1-1v-.1a5 5 0 0 0 3.9-3.9h.1s1 0 1-1-1-1-1-1h-.1A5 5 0 0 0 11 5.1V5s0-1-1-1zm0 2.5a3.5 3.5 0 1 1 0 7 3.5 3.5 0 1 1 0-7z'/%3E%3Ccircle id='dot' cx='10' cy='10' r='2'/%3E%3Cpath id='stroke' d='M14 5l1 1-9 9-1-1 9-9z' fill='%23f00'/%3E%3C/svg%3E")}.mapboxgl-ctrl button.mapboxgl-ctrl-geolocate.mapboxgl-ctrl-geolocate-active .mapboxgl-ctrl-icon{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg viewBox='0 0 20 20' xmlns='http://www.w3.org/2000/svg' fill='%2333b5e5'%3E%3Cpath d='M10 4C9 4 9 5 9 5v.1A5 5 0 0 0 5.1 9H5s-1 0-1 1 1 1 1 1h.1A5 5 0 0 0 9 14.9v.1s0 1 1 1 1-1 1-1v-.1a5 5 0 0 0 3.9-3.9h.1s1 0 1-1-1-1-1-1h-.1A5 5 0 0 0 11 5.1V5s0-1-1-1zm0 2.5a3.5 3.5 0 1 1 0 7 3.5 3.5 0 1 1 0-7z'/%3E%3Ccircle id='dot' cx='10' cy='10' r='2'/%3E%3Cpath id='stroke' d='M14 5l1 1-9 9-1-1 9-9z' display='none'/%3E%3C/svg%3E")}.mapboxgl-ctrl button.mapboxgl-ctrl-geolocate.mapboxgl-ctrl-geolocate-active-error .mapboxgl-ctrl-icon{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg viewBox='0 0 20 20' xmlns='http://www.w3.org/2000/svg' fill='%23e58978'%3E%3Cpath d='M10 4C9 4 9 5 9 5v.1A5 5 0 0 0 5.1 9H5s-1 0-1 1 1 1 1 1h.1A5 5 0 0 0 9 14.9v.1s0 1 1 1 1-1 1-1v-.1a5 5 0 0 0 3.9-3.9h.1s1 0 1-1-1-1-1-1h-.1A5 5 0 0 0 11 5.1V5s0-1-1-1zm0 2.5a3.5 3.5 0 1 1 0 7 3.5 3.5 0 1 1 0-7z'/%3E%3Ccircle id='dot' cx='10' cy='10' r='2'/%3E%3Cpath id='stroke' d='M14 5l1 1-9 9-1-1 9-9z' display='none'/%3E%3C/svg%3E")}.mapboxgl-ctrl button.mapboxgl-ctrl-geolocate.mapboxgl-ctrl-geolocate-background .mapboxgl-ctrl-icon{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg viewBox='0 0 20 20' xmlns='http://www.w3.org/2000/svg' fill='%2333b5e5'%3E%3Cpath d='M10 4C9 4 9 5 9 5v.1A5 5 0 0 0 5.1 9H5s-1 0-1 1 1 1 1 1h.1A5 5 0 0 0 9 14.9v.1s0 1 1 1 1-1 1-1v-.1a5 5 0 0 0 3.9-3.9h.1s1 0 1-1-1-1-1-1h-.1A5 5 0 0 0 11 5.1V5s0-1-1-1zm0 2.5a3.5 3.5 0 1 1 0 7 3.5 3.5 0 1 1 0-7z'/%3E%3Ccircle id='dot' cx='10' cy='10' r='2' display='none'/%3E%3Cpath id='stroke' d='M14 5l1 1-9 9-1-1 9-9z' display='none'/%3E%3C/svg%3E")}.mapboxgl-ctrl button.mapboxgl-ctrl-geolocate.mapboxgl-ctrl-geolocate-background-error .mapboxgl-ctrl-icon{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg viewBox='0 0 20 20' xmlns='http://www.w3.org/2000/svg' fill='%23e54e33'%3E%3Cpath d='M10 4C9 4 9 5 9 5v.1A5 5 0 0 0 5.1 9H5s-1 0-1 1 1 1 1 1h.1A5 5 0 0 0 9 14.9v.1s0 1 1 1 1-1 1-1v-.1a5 5 0 0 0 3.9-3.9h.1s1 0 1-1-1-1-1-1h-.1A5 5 0 0 0 11 5.1V5s0-1-1-1zm0 2.5a3.5 3.5 0 1 1 0 7 3.5 3.5 0 1 1 0-7z'/%3E%3Ccircle id='dot' cx='10' cy='10' r='2' display='none'/%3E%3Cpath id='stroke' d='M14 5l1 1-9 9-1-1 9-9z' display='none'/%3E%3C/svg%3E")}.mapboxgl-ctrl button.mapboxgl-ctrl-geolocate.mapboxgl-ctrl-geolocate-waiting .mapboxgl-ctrl-icon{animation:mapboxgl-spin 2s linear infinite}@media (-ms-high-contrast:active){.mapboxgl-ctrl button.mapboxgl-ctrl-geolocate .mapboxgl-ctrl-icon{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg viewBox='0 0 20 20' xmlns='http://www.w3.org/2000/svg' fill='%23fff'%3E%3Cpath d='M10 4C9 4 9 5 9 5v.1A5 5 0 0 0 5.1 9H5s-1 0-1 1 1 1 1 1h.1A5 5 0 0 0 9 14.9v.1s0 1 1 1 1-1 1-1v-.1a5 5 0 0 0 3.9-3.9h.1s1 0 1-1-1-1-1-1h-.1A5 5 0 0 0 11 5.1V5s0-1-1-1zm0 2.5a3.5 3.5 0 1 1 0 7 3.5 3.5 0 1 1 0-7z'/%3E%3Ccircle id='dot' cx='10' cy='10' r='2'/%3E%3Cpath id='stroke' d='M14 5l1 1-9 9-1-1 9-9z' display='none'/%3E%3C/svg%3E")}.mapboxgl-ctrl button.mapboxgl-ctrl-geolocate:disabled .mapboxgl-ctrl-icon{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg viewBox='0 0 20 20' xmlns='http://www.w3.org/2000/svg' fill='%23999'%3E%3Cpath d='M10 4C9 4 9 5 9 5v.1A5 5 0 0 0 5.1 9H5s-1 0-1 1 1 1 1 1h.1A5 5 0 0 0 9 14.9v.1s0 1 1 1 1-1 1-1v-.1a5 5 0 0 0 3.9-3.9h.1s1 0 1-1-1-1-1-1h-.1A5 5 0 0 0 11 5.1V5s0-1-1-1zm0 2.5a3.5 3.5 0 1 1 0 7 3.5 3.5 0 1 1 0-7z'/%3E%3Ccircle id='dot' cx='10' cy='10' r='2'/%3E%3Cpath id='stroke' d='M14 5l1 1-9 9-1-1 9-9z' fill='%23f00'/%3E%3C/svg%3E")}.mapboxgl-ctrl button.mapboxgl-ctrl-geolocate.mapboxgl-ctrl-geolocate-active .mapboxgl-ctrl-icon{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg viewBox='0 0 20 20' xmlns='http://www.w3.org/2000/svg' fill='%2333b5e5'%3E%3Cpath d='M10 4C9 4 9 5 9 5v.1A5 5 0 0 0 5.1 9H5s-1 0-1 1 1 1 1 1h.1A5 5 0 0 0 9 14.9v.1s0 1 1 1 1-1 1-1v-.1a5 5 0 0 0 3.9-3.9h.1s1 0 1-1-1-1-1-1h-.1A5 5 0 0 0 11 5.1V5s0-1-1-1zm0 2.5a3.5 3.5 0 1 1 0 7 3.5 3.5 0 1 1 0-7z'/%3E%3Ccircle id='dot' cx='10' cy='10' r='2'/%3E%3Cpath id='stroke' d='M14 5l1 1-9 9-1-1 9-9z' display='none'/%3E%3C/svg%3E")}.mapboxgl-ctrl button.mapboxgl-ctrl-geolocate.mapboxgl-ctrl-geolocate-active-error .mapboxgl-ctrl-icon{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg viewBox='0 0 20 20' xmlns='http://www.w3.org/2000/svg' fill='%23e58978'%3E%3Cpath d='M10 4C9 4 9 5 9 5v.1A5 5 0 0 0 5.1 9H5s-1 0-1 1 1 1 1 1h.1A5 5 0 0 0 9 14.9v.1s0 1 1 1 1-1 1-1v-.1a5 5 0 0 0 3.9-3.9h.1s1 0 1-1-1-1-1-1h-.1A5 5 0 0 0 11 5.1V5s0-1-1-1zm0 2.5a3.5 3.5 0 1 1 0 7 3.5 3.5 0 1 1 0-7z'/%3E%3Ccircle id='dot' cx='10' cy='10' r='2'/%3E%3Cpath id='stroke' d='M14 5l1 1-9 9-1-1 9-9z' display='none'/%3E%3C/svg%3E")}.mapboxgl-ctrl button.mapboxgl-ctrl-geolocate.mapboxgl-ctrl-geolocate-background .mapboxgl-ctrl-icon{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg viewBox='0 0 20 20' xmlns='http://www.w3.org/2000/svg' fill='%2333b5e5'%3E%3Cpath d='M10 4C9 4 9 5 9 5v.1A5 5 0 0 0 5.1 9H5s-1 0-1 1 1 1 1 1h.1A5 5 0 0 0 9 14.9v.1s0 1 1 1 1-1 1-1v-.1a5 5 0 0 0 3.9-3.9h.1s1 0 1-1-1-1-1-1h-.1A5 5 0 0 0 11 5.1V5s0-1-1-1zm0 2.5a3.5 3.5 0 1 1 0 7 3.5 3.5 0 1 1 0-7z'/%3E%3Ccircle id='dot' cx='10' cy='10' r='2' display='none'/%3E%3Cpath id='stroke' d='M14 5l1 1-9 9-1-1 9-9z' display='none'/%3E%3C/svg%3E")}.mapboxgl-ctrl button.mapboxgl-ctrl-geolocate.mapboxgl-ctrl-geolocate-background-error .mapboxgl-ctrl-icon{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg viewBox='0 0 20 20' xmlns='http://www.w3.org/2000/svg' fill='%23e54e33'%3E%3Cpath d='M10 4C9 4 9 5 9 5v.1A5 5 0 0 0 5.1 9H5s-1 0-1 1 1 1 1 1h.1A5 5 0 0 0 9 14.9v.1s0 1 1 1 1-1 1-1v-.1a5 5 0 0 0 3.9-3.9h.1s1 0 1-1-1-1-1-1h-.1A5 5 0 0 0 11 5.1V5s0-1-1-1zm0 2.5a3.5 3.5 0 1 1 0 7 3.5 3.5 0 1 1 0-7z'/%3E%3Ccircle id='dot' cx='10' cy='10' r='2' display='none'/%3E%3Cpath id='stroke' d='M14 5l1 1-9 9-1-1 9-9z' display='none'/%3E%3C/svg%3E")}}@media (-ms-high-contrast:black-on-white){.mapboxgl-ctrl button.mapboxgl-ctrl-geolocate .mapboxgl-ctrl-icon{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg viewBox='0 0 20 20' xmlns='http://www.w3.org/2000/svg' fill='%23000'%3E%3Cpath d='M10 4C9 4 9 5 9 5v.1A5 5 0 0 0 5.1 9H5s-1 0-1 1 1 1 1 1h.1A5 5 0 0 0 9 14.9v.1s0 1 1 1 1-1 1-1v-.1a5 5 0 0 0 3.9-3.9h.1s1 0 1-1-1-1-1-1h-.1A5 5 0 0 0 11 5.1V5s0-1-1-1zm0 2.5a3.5 3.5 0 1 1 0 7 3.5 3.5 0 1 1 0-7z'/%3E%3Ccircle id='dot' cx='10' cy='10' r='2'/%3E%3Cpath id='stroke' d='M14 5l1 1-9 9-1-1 9-9z' display='none'/%3E%3C/svg%3E")}.mapboxgl-ctrl button.mapboxgl-ctrl-geolocate:disabled .mapboxgl-ctrl-icon{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg viewBox='0 0 20 20' xmlns='http://www.w3.org/2000/svg' fill='%23666'%3E%3Cpath d='M10 4C9 4 9 5 9 5v.1A5 5 0 0 0 5.1 9H5s-1 0-1 1 1 1 1 1h.1A5 5 0 0 0 9 14.9v.1s0 1 1 1 1-1 1-1v-.1a5 5 0 0 0 3.9-3.9h.1s1 0 1-1-1-1-1-1h-.1A5 5 0 0 0 11 5.1V5s0-1-1-1zm0 2.5a3.5 3.5 0 1 1 0 7 3.5 3.5 0 1 1 0-7z'/%3E%3Ccircle id='dot' cx='10' cy='10' r='2'/%3E%3Cpath id='stroke' d='M14 5l1 1-9 9-1-1 9-9z' fill='%23f00'/%3E%3C/svg%3E")}}@keyframes mapboxgl-spin{0%{transform:rotate(0deg)}to{transform:rotate(1turn)}}a.mapboxgl-ctrl-logo{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' fill-rule='evenodd' viewBox='0 0 88 23'%3E%3Cdefs%3E%3Cpath id='logo' d='M11.5 2.25c5.105 0 9.25 4.145 9.25 9.25s-4.145 9.25-9.25 9.25-9.25-4.145-9.25-9.25 4.145-9.25 9.25-9.25zM6.997 15.983c-.051-.338-.828-5.802 2.233-8.873a4.395 4.395 0 013.13-1.28c1.27 0 2.49.51 3.39 1.42.91.9 1.42 2.12 1.42 3.39 0 1.18-.449 2.301-1.28 3.13C12.72 16.93 7 16 7 16l-.003-.017zM15.3 10.5l-2 .8-.8 2-.8-2-2-.8 2-.8.8-2 .8 2 2 .8z'/%3E%3Cpath id='text' d='M50.63 8c.13 0 .23.1.23.23V9c.7-.76 1.7-1.18 2.73-1.18 2.17 0 3.95 1.85 3.95 4.17s-1.77 4.19-3.94 4.19c-1.04 0-2.03-.43-2.74-1.18v3.77c0 .13-.1.23-.23.23h-1.4c-.13 0-.23-.1-.23-.23V8.23c0-.12.1-.23.23-.23h1.4zm-3.86.01c.01 0 .01 0 .01-.01.13 0 .22.1.22.22v7.55c0 .12-.1.23-.23.23h-1.4c-.13 0-.23-.1-.23-.23V15c-.7.76-1.69 1.19-2.73 1.19-2.17 0-3.94-1.87-3.94-4.19 0-2.32 1.77-4.19 3.94-4.19 1.03 0 2.02.43 2.73 1.18v-.75c0-.12.1-.23.23-.23h1.4zm26.375-.19a4.24 4.24 0 00-4.16 3.29c-.13.59-.13 1.19 0 1.77a4.233 4.233 0 004.17 3.3c2.35 0 4.26-1.87 4.26-4.19 0-2.32-1.9-4.17-4.27-4.17zM60.63 5c.13 0 .23.1.23.23v3.76c.7-.76 1.7-1.18 2.73-1.18 1.88 0 3.45 1.4 3.84 3.28.13.59.13 1.2 0 1.8-.39 1.88-1.96 3.29-3.84 3.29-1.03 0-2.02-.43-2.73-1.18v.77c0 .12-.1.23-.23.23h-1.4c-.13 0-.23-.1-.23-.23V5.23c0-.12.1-.23.23-.23h1.4zm-34 11h-1.4c-.13 0-.23-.11-.23-.23V8.22c.01-.13.1-.22.23-.22h1.4c.13 0 .22.11.23.22v.68c.5-.68 1.3-1.09 2.16-1.1h.03c1.09 0 2.09.6 2.6 1.55.45-.95 1.4-1.55 2.44-1.56 1.62 0 2.93 1.25 2.9 2.78l.03 5.2c0 .13-.1.23-.23.23h-1.41c-.13 0-.23-.11-.23-.23v-4.59c0-.98-.74-1.71-1.62-1.71-.8 0-1.46.7-1.59 1.62l.01 4.68c0 .13-.11.23-.23.23h-1.41c-.13 0-.23-.11-.23-.23v-4.59c0-.98-.74-1.71-1.62-1.71-.85 0-1.54.79-1.6 1.8v4.5c0 .13-.1.23-.23.23zm53.615 0h-1.61c-.04 0-.08-.01-.12-.03-.09-.06-.13-.19-.06-.28l2.43-3.71-2.39-3.65a.213.213 0 01-.03-.12c0-.12.09-.21.21-.21h1.61c.13 0 .24.06.3.17l1.41 2.37 1.4-2.37a.34.34 0 01.3-.17h1.6c.04 0 .08.01.12.03.09.06.13.19.06.28l-2.37 3.65 2.43 3.7c0 .05.01.09.01.13 0 .12-.09.21-.21.21h-1.61c-.13 0-.24-.06-.3-.17l-1.44-2.42-1.44 2.42a.34.34 0 01-.3.17zm-7.12-1.49c-1.33 0-2.42-1.12-2.42-2.51 0-1.39 1.08-2.52 2.42-2.52 1.33 0 2.42 1.12 2.42 2.51 0 1.39-1.08 2.51-2.42 2.52zm-19.865 0c-1.32 0-2.39-1.11-2.42-2.48v-.07c.02-1.38 1.09-2.49 2.4-2.49 1.32 0 2.41 1.12 2.41 2.51 0 1.39-1.07 2.52-2.39 2.53zm-8.11-2.48c-.01 1.37-1.09 2.47-2.41 2.47s-2.42-1.12-2.42-2.51c0-1.39 1.08-2.52 2.4-2.52 1.33 0 2.39 1.11 2.41 2.48l.02.08zm18.12 2.47c-1.32 0-2.39-1.11-2.41-2.48v-.06c.02-1.38 1.09-2.48 2.41-2.48s2.42 1.12 2.42 2.51c0 1.39-1.09 2.51-2.42 2.51z'/%3E%3C/defs%3E%3Cmask id='clip'%3E%3Crect x='0' y='0' width='100%25' height='100%25' fill='white'/%3E%3Cuse xlink:href='%23logo'/%3E%3Cuse xlink:href='%23text'/%3E%3C/mask%3E%3Cg id='outline' opacity='0.3' stroke='%23000' stroke-width='3'%3E%3Ccircle mask='url(%23clip)' cx='11.5' cy='11.5' r='9.25'/%3E%3Cuse xlink:href='%23text' mask='url(%23clip)'/%3E%3C/g%3E%3Cg id='fill' opacity='0.9' fill='%23fff'%3E%3Cuse xlink:href='%23logo'/%3E%3Cuse xlink:href='%23text'/%3E%3C/g%3E%3C/svg%3E");background-repeat:no-repeat;cursor:pointer;display:block;height:23px;margin:0 0 -4px -4px;overflow:hidden;width:88px}a.mapboxgl-ctrl-logo.mapboxgl-compact{width:23px}@media (-ms-high-contrast:active){a.mapboxgl-ctrl-logo{background-color:initial;background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' fill-rule='evenodd' viewBox='0 0 88 23'%3E%3Cdefs%3E%3Cpath id='logo' d='M11.5 2.25c5.105 0 9.25 4.145 9.25 9.25s-4.145 9.25-9.25 9.25-9.25-4.145-9.25-9.25 4.145-9.25 9.25-9.25zM6.997 15.983c-.051-.338-.828-5.802 2.233-8.873a4.395 4.395 0 013.13-1.28c1.27 0 2.49.51 3.39 1.42.91.9 1.42 2.12 1.42 3.39 0 1.18-.449 2.301-1.28 3.13C12.72 16.93 7 16 7 16l-.003-.017zM15.3 10.5l-2 .8-.8 2-.8-2-2-.8 2-.8.8-2 .8 2 2 .8z'/%3E%3Cpath id='text' d='M50.63 8c.13 0 .23.1.23.23V9c.7-.76 1.7-1.18 2.73-1.18 2.17 0 3.95 1.85 3.95 4.17s-1.77 4.19-3.94 4.19c-1.04 0-2.03-.43-2.74-1.18v3.77c0 .13-.1.23-.23.23h-1.4c-.13 0-.23-.1-.23-.23V8.23c0-.12.1-.23.23-.23h1.4zm-3.86.01c.01 0 .01 0 .01-.01.13 0 .22.1.22.22v7.55c0 .12-.1.23-.23.23h-1.4c-.13 0-.23-.1-.23-.23V15c-.7.76-1.69 1.19-2.73 1.19-2.17 0-3.94-1.87-3.94-4.19 0-2.32 1.77-4.19 3.94-4.19 1.03 0 2.02.43 2.73 1.18v-.75c0-.12.1-.23.23-.23h1.4zm26.375-.19a4.24 4.24 0 00-4.16 3.29c-.13.59-.13 1.19 0 1.77a4.233 4.233 0 004.17 3.3c2.35 0 4.26-1.87 4.26-4.19 0-2.32-1.9-4.17-4.27-4.17zM60.63 5c.13 0 .23.1.23.23v3.76c.7-.76 1.7-1.18 2.73-1.18 1.88 0 3.45 1.4 3.84 3.28.13.59.13 1.2 0 1.8-.39 1.88-1.96 3.29-3.84 3.29-1.03 0-2.02-.43-2.73-1.18v.77c0 .12-.1.23-.23.23h-1.4c-.13 0-.23-.1-.23-.23V5.23c0-.12.1-.23.23-.23h1.4zm-34 11h-1.4c-.13 0-.23-.11-.23-.23V8.22c.01-.13.1-.22.23-.22h1.4c.13 0 .22.11.23.22v.68c.5-.68 1.3-1.09 2.16-1.1h.03c1.09 0 2.09.6 2.6 1.55.45-.95 1.4-1.55 2.44-1.56 1.62 0 2.93 1.25 2.9 2.78l.03 5.2c0 .13-.1.23-.23.23h-1.41c-.13 0-.23-.11-.23-.23v-4.59c0-.98-.74-1.71-1.62-1.71-.8 0-1.46.7-1.59 1.62l.01 4.68c0 .13-.11.23-.23.23h-1.41c-.13 0-.23-.11-.23-.23v-4.59c0-.98-.74-1.71-1.62-1.71-.85 0-1.54.79-1.6 1.8v4.5c0 .13-.1.23-.23.23zm53.615 0h-1.61c-.04 0-.08-.01-.12-.03-.09-.06-.13-.19-.06-.28l2.43-3.71-2.39-3.65a.213.213 0 01-.03-.12c0-.12.09-.21.21-.21h1.61c.13 0 .24.06.3.17l1.41 2.37 1.4-2.37a.34.34 0 01.3-.17h1.6c.04 0 .08.01.12.03.09.06.13.19.06.28l-2.37 3.65 2.43 3.7c0 .05.01.09.01.13 0 .12-.09.21-.21.21h-1.61c-.13 0-.24-.06-.3-.17l-1.44-2.42-1.44 2.42a.34.34 0 01-.3.17zm-7.12-1.49c-1.33 0-2.42-1.12-2.42-2.51 0-1.39 1.08-2.52 2.42-2.52 1.33 0 2.42 1.12 2.42 2.51 0 1.39-1.08 2.51-2.42 2.52zm-19.865 0c-1.32 0-2.39-1.11-2.42-2.48v-.07c.02-1.38 1.09-2.49 2.4-2.49 1.32 0 2.41 1.12 2.41 2.51 0 1.39-1.07 2.52-2.39 2.53zm-8.11-2.48c-.01 1.37-1.09 2.47-2.41 2.47s-2.42-1.12-2.42-2.51c0-1.39 1.08-2.52 2.4-2.52 1.33 0 2.39 1.11 2.41 2.48l.02.08zm18.12 2.47c-1.32 0-2.39-1.11-2.41-2.48v-.06c.02-1.38 1.09-2.48 2.41-2.48s2.42 1.12 2.42 2.51c0 1.39-1.09 2.51-2.42 2.51z'/%3E%3C/defs%3E%3Cmask id='clip'%3E%3Crect x='0' y='0' width='100%25' height='100%25' fill='white'/%3E%3Cuse xlink:href='%23logo'/%3E%3Cuse xlink:href='%23text'/%3E%3C/mask%3E%3Cg id='outline' opacity='1' stroke='%23000' stroke-width='3'%3E%3Ccircle mask='url(%23clip)' cx='11.5' cy='11.5' r='9.25'/%3E%3Cuse xlink:href='%23text' mask='url(%23clip)'/%3E%3C/g%3E%3Cg id='fill' opacity='1' fill='%23fff'%3E%3Cuse xlink:href='%23logo'/%3E%3Cuse xlink:href='%23text'/%3E%3C/g%3E%3C/svg%3E")}}@media (-ms-high-contrast:black-on-white){a.mapboxgl-ctrl-logo{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' fill-rule='evenodd' viewBox='0 0 88 23'%3E%3Cdefs%3E%3Cpath id='logo' d='M11.5 2.25c5.105 0 9.25 4.145 9.25 9.25s-4.145 9.25-9.25 9.25-9.25-4.145-9.25-9.25 4.145-9.25 9.25-9.25zM6.997 15.983c-.051-.338-.828-5.802 2.233-8.873a4.395 4.395 0 013.13-1.28c1.27 0 2.49.51 3.39 1.42.91.9 1.42 2.12 1.42 3.39 0 1.18-.449 2.301-1.28 3.13C12.72 16.93 7 16 7 16l-.003-.017zM15.3 10.5l-2 .8-.8 2-.8-2-2-.8 2-.8.8-2 .8 2 2 .8z'/%3E%3Cpath id='text' d='M50.63 8c.13 0 .23.1.23.23V9c.7-.76 1.7-1.18 2.73-1.18 2.17 0 3.95 1.85 3.95 4.17s-1.77 4.19-3.94 4.19c-1.04 0-2.03-.43-2.74-1.18v3.77c0 .13-.1.23-.23.23h-1.4c-.13 0-.23-.1-.23-.23V8.23c0-.12.1-.23.23-.23h1.4zm-3.86.01c.01 0 .01 0 .01-.01.13 0 .22.1.22.22v7.55c0 .12-.1.23-.23.23h-1.4c-.13 0-.23-.1-.23-.23V15c-.7.76-1.69 1.19-2.73 1.19-2.17 0-3.94-1.87-3.94-4.19 0-2.32 1.77-4.19 3.94-4.19 1.03 0 2.02.43 2.73 1.18v-.75c0-.12.1-.23.23-.23h1.4zm26.375-.19a4.24 4.24 0 00-4.16 3.29c-.13.59-.13 1.19 0 1.77a4.233 4.233 0 004.17 3.3c2.35 0 4.26-1.87 4.26-4.19 0-2.32-1.9-4.17-4.27-4.17zM60.63 5c.13 0 .23.1.23.23v3.76c.7-.76 1.7-1.18 2.73-1.18 1.88 0 3.45 1.4 3.84 3.28.13.59.13 1.2 0 1.8-.39 1.88-1.96 3.29-3.84 3.29-1.03 0-2.02-.43-2.73-1.18v.77c0 .12-.1.23-.23.23h-1.4c-.13 0-.23-.1-.23-.23V5.23c0-.12.1-.23.23-.23h1.4zm-34 11h-1.4c-.13 0-.23-.11-.23-.23V8.22c.01-.13.1-.22.23-.22h1.4c.13 0 .22.11.23.22v.68c.5-.68 1.3-1.09 2.16-1.1h.03c1.09 0 2.09.6 2.6 1.55.45-.95 1.4-1.55 2.44-1.56 1.62 0 2.93 1.25 2.9 2.78l.03 5.2c0 .13-.1.23-.23.23h-1.41c-.13 0-.23-.11-.23-.23v-4.59c0-.98-.74-1.71-1.62-1.71-.8 0-1.46.7-1.59 1.62l.01 4.68c0 .13-.11.23-.23.23h-1.41c-.13 0-.23-.11-.23-.23v-4.59c0-.98-.74-1.71-1.62-1.71-.85 0-1.54.79-1.6 1.8v4.5c0 .13-.1.23-.23.23zm53.615 0h-1.61c-.04 0-.08-.01-.12-.03-.09-.06-.13-.19-.06-.28l2.43-3.71-2.39-3.65a.213.213 0 01-.03-.12c0-.12.09-.21.21-.21h1.61c.13 0 .24.06.3.17l1.41 2.37 1.4-2.37a.34.34 0 01.3-.17h1.6c.04 0 .08.01.12.03.09.06.13.19.06.28l-2.37 3.65 2.43 3.7c0 .05.01.09.01.13 0 .12-.09.21-.21.21h-1.61c-.13 0-.24-.06-.3-.17l-1.44-2.42-1.44 2.42a.34.34 0 01-.3.17zm-7.12-1.49c-1.33 0-2.42-1.12-2.42-2.51 0-1.39 1.08-2.52 2.42-2.52 1.33 0 2.42 1.12 2.42 2.51 0 1.39-1.08 2.51-2.42 2.52zm-19.865 0c-1.32 0-2.39-1.11-2.42-2.48v-.07c.02-1.38 1.09-2.49 2.4-2.49 1.32 0 2.41 1.12 2.41 2.51 0 1.39-1.07 2.52-2.39 2.53zm-8.11-2.48c-.01 1.37-1.09 2.47-2.41 2.47s-2.42-1.12-2.42-2.51c0-1.39 1.08-2.52 2.4-2.52 1.33 0 2.39 1.11 2.41 2.48l.02.08zm18.12 2.47c-1.32 0-2.39-1.11-2.41-2.48v-.06c.02-1.38 1.09-2.48 2.41-2.48s2.42 1.12 2.42 2.51c0 1.39-1.09 2.51-2.42 2.51z'/%3E%3C/defs%3E%3Cmask id='clip'%3E%3Crect x='0' y='0' width='100%25' height='100%25' fill='white'/%3E%3Cuse xlink:href='%23logo'/%3E%3Cuse xlink:href='%23text'/%3E%3C/mask%3E%3Cg id='outline' opacity='1' stroke='%23fff' stroke-width='3' fill='%23fff'%3E%3Ccircle mask='url(%23clip)' cx='11.5' cy='11.5' r='9.25'/%3E%3Cuse xlink:href='%23text' mask='url(%23clip)'/%3E%3C/g%3E%3Cg id='fill' opacity='1' fill='%23000'%3E%3Cuse xlink:href='%23logo'/%3E%3Cuse xlink:href='%23text'/%3E%3C/g%3E%3C/svg%3E")}}.mapboxgl-ctrl.mapboxgl-ctrl-attrib{background-color:#ffffff80;margin:0;padding:0 5px}@media screen{.mapboxgl-ctrl-attrib.mapboxgl-compact{background-color:#fff;border-radius:12px;box-sizing:initial;margin:10px;min-height:20px;padding:2px 24px 2px 0;position:relative}.mapboxgl-ctrl-attrib.mapboxgl-compact-show{padding:2px 28px 2px 8px;visibility:visible}.mapboxgl-ctrl-bottom-left>.mapboxgl-ctrl-attrib.mapboxgl-compact-show,.mapboxgl-ctrl-left>.mapboxgl-ctrl-attrib.mapboxgl-compact-show,.mapboxgl-ctrl-top-left>.mapboxgl-ctrl-attrib.mapboxgl-compact-show{border-radius:12px;padding:2px 8px 2px 28px}.mapboxgl-ctrl-attrib.mapboxgl-compact .mapboxgl-ctrl-attrib-inner{display:none}.mapboxgl-ctrl-attrib-button{background-color:#ffffff80;background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg viewBox='0 0 20 20' xmlns='http://www.w3.org/2000/svg' fill-rule='evenodd'%3E%3Cpath d='M4 10a6 6 0 1 0 12 0 6 6 0 1 0-12 0m5-3a1 1 0 1 0 2 0 1 1 0 1 0-2 0m0 3a1 1 0 1 1 2 0v3a1 1 0 1 1-2 0'/%3E%3C/svg%3E");border:0;border-radius:12px;box-sizing:border-box;cursor:pointer;display:none;height:24px;outline:none;position:absolute;right:0;top:0;width:24px}.mapboxgl-ctrl-bottom-left .mapboxgl-ctrl-attrib-button,.mapboxgl-ctrl-left .mapboxgl-ctrl-attrib-button,.mapboxgl-ctrl-top-left .mapboxgl-ctrl-attrib-button{left:0}.mapboxgl-ctrl-attrib.mapboxgl-compact .mapboxgl-ctrl-attrib-button,.mapboxgl-ctrl-attrib.mapboxgl-compact-show .mapboxgl-ctrl-attrib-inner{display:block}.mapboxgl-ctrl-attrib.mapboxgl-compact-show .mapboxgl-ctrl-attrib-button{background-color:#0000000d}.mapboxgl-ctrl-bottom-right>.mapboxgl-ctrl-attrib.mapboxgl-compact:after{bottom:0;right:0}.mapboxgl-ctrl-right>.mapboxgl-ctrl-attrib.mapboxgl-compact:after{right:0}.mapboxgl-ctrl-top-right>.mapboxgl-ctrl-attrib.mapboxgl-compact:after{right:0;top:0}.mapboxgl-ctrl-top-left>.mapboxgl-ctrl-attrib.mapboxgl-compact:after{left:0;top:0}.mapboxgl-ctrl-bottom-left>.mapboxgl-ctrl-attrib.mapboxgl-compact:after{bottom:0;left:0}.mapboxgl-ctrl-left>.mapboxgl-ctrl-attrib.mapboxgl-compact:after{left:0}}@media screen and (-ms-high-contrast:active){.mapboxgl-ctrl-attrib.mapboxgl-compact:after{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg viewBox='0 0 20 20' xmlns='http://www.w3.org/2000/svg' fill-rule='evenodd' fill='%23fff'%3E%3Cpath d='M4 10a6 6 0 1 0 12 0 6 6 0 1 0-12 0m5-3a1 1 0 1 0 2 0 1 1 0 1 0-2 0m0 3a1 1 0 1 1 2 0v3a1 1 0 1 1-2 0'/%3E%3C/svg%3E")}}@media screen and (-ms-high-contrast:black-on-white){.mapboxgl-ctrl-attrib.mapboxgl-compact:after{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg viewBox='0 0 20 20' xmlns='http://www.w3.org/2000/svg' fill-rule='evenodd'%3E%3Cpath d='M4 10a6 6 0 1 0 12 0 6 6 0 1 0-12 0m5-3a1 1 0 1 0 2 0 1 1 0 1 0-2 0m0 3a1 1 0 1 1 2 0v3a1 1 0 1 1-2 0'/%3E%3C/svg%3E")}}.mapboxgl-ctrl-attrib a{color:#000000bf;text-decoration:none}.mapboxgl-ctrl-attrib a:hover{color:inherit;text-decoration:underline}.mapboxgl-ctrl-attrib .mapbox-improve-map{font-weight:700;margin-left:2px}.mapboxgl-attrib-empty{display:none}.mapboxgl-ctrl-scale{background-color:#ffffffbf;border:2px solid #333;border-top:#333;box-sizing:border-box;color:#333;font-size:10px;padding:0 5px;white-space:nowrap}.mapboxgl-popup{display:flex;left:0;pointer-events:none;position:absolute;top:0;will-change:transform}.mapboxgl-popup-anchor-top,.mapboxgl-popup-anchor-top-left,.mapboxgl-popup-anchor-top-right{flex-direction:column}.mapboxgl-popup-anchor-bottom,.mapboxgl-popup-anchor-bottom-left,.mapboxgl-popup-anchor-bottom-right{flex-direction:column-reverse}.mapboxgl-popup-anchor-left{flex-direction:row}.mapboxgl-popup-anchor-right{flex-direction:row-reverse}.mapboxgl-popup-tip{border:10px solid #0000;height:0;width:0;z-index:1}.mapboxgl-popup-anchor-top .mapboxgl-popup-tip{align-self:center;border-bottom-color:#fff;border-top:none}.mapboxgl-popup-anchor-top-left .mapboxgl-popup-tip{align-self:flex-start;border-bottom-color:#fff;border-left:none;border-top:none}.mapboxgl-popup-anchor-top-right .mapboxgl-popup-tip{align-self:flex-end;border-bottom-color:#fff;border-right:none;border-top:none}.mapboxgl-popup-anchor-bottom .mapboxgl-popup-tip{align-self:center;border-bottom:none;border-top-color:#fff}.mapboxgl-popup-anchor-bottom-left .mapboxgl-popup-tip{align-self:flex-start;border-bottom:none;border-left:none;border-top-color:#fff}.mapboxgl-popup-anchor-bottom-right .mapboxgl-popup-tip{align-self:flex-end;border-bottom:none;border-right:none;border-top-color:#fff}.mapboxgl-popup-anchor-left .mapboxgl-popup-tip{align-self:center;border-left:none;border-right-color:#fff}.mapboxgl-popup-anchor-right .mapboxgl-popup-tip{align-self:center;border-left-color:#fff;border-right:none}.mapboxgl-popup-close-button{background-color:initial;border:0;border-radius:0 3px 0 0;cursor:pointer;position:absolute;right:0;top:0}.mapboxgl-popup-close-button:hover{background-color:#eee}.mapboxgl-popup-content{background:#fff;border-radius:3px;box-shadow:0 1px 2px #0000001a;padding:10px 10px 15px;pointer-events:auto;position:relative}.mapboxgl-popup-anchor-top-left .mapboxgl-popup-content{border-top-left-radius:0}.mapboxgl-popup-anchor-top-right .mapboxgl-popup-content{border-top-right-radius:0}.mapboxgl-popup-anchor-bottom-left .mapboxgl-popup-content{border-bottom-left-radius:0}.mapboxgl-popup-anchor-bottom-right .mapboxgl-popup-content{border-bottom-right-radius:0}.mapboxgl-popup-track-pointer{display:none}.mapboxgl-popup-track-pointer *{pointer-events:none;user-select:none}.mapboxgl-map:hover .mapboxgl-popup-track-pointer{display:flex}.mapboxgl-map:active .mapboxgl-popup-track-pointer{display:none}.mapboxgl-marker{left:0;opacity:1;position:absolute;top:0;transition:opacity .2s;will-change:transform}.mapboxgl-user-location-dot,.mapboxgl-user-location-dot:before{background-color:#1da1f2;border-radius:50%;height:15px;width:15px}.mapboxgl-user-location-dot:before{animation:mapboxgl-user-location-dot-pulse 2s infinite;content:"";position:absolute}.mapboxgl-user-location-dot:after{border:2px solid #fff;border-radius:50%;box-shadow:0 0 3px #00000059;box-sizing:border-box;content:"";height:19px;left:-2px;position:absolute;top:-2px;width:19px}.mapboxgl-user-location-show-heading .mapboxgl-user-location-heading{height:0;width:0}.mapboxgl-user-location-show-heading .mapboxgl-user-location-heading:after,.mapboxgl-user-location-show-heading .mapboxgl-user-location-heading:before{border-bottom:7.5px solid #4aa1eb;content:"";position:absolute}.mapboxgl-user-location-show-heading .mapboxgl-user-location-heading:before{border-left:7.5px solid #0000;transform:translateY(-28px) skewY(-20deg)}.mapboxgl-user-location-show-heading .mapboxgl-user-location-heading:after{border-right:7.5px solid #0000;transform:translate(7.5px,-28px) skewY(20deg)}@keyframes mapboxgl-user-location-dot-pulse{0%{opacity:1;transform:scale(1)}70%{opacity:0;transform:scale(3)}to{opacity:0;transform:scale(1)}}.mapboxgl-user-location-dot-stale{background-color:#aaa}.mapboxgl-user-location-dot-stale:after{display:none}.mapboxgl-user-location-accuracy-circle{background-color:#1da1f233;border-radius:100%;height:1px;width:1px}.mapboxgl-crosshair,.mapboxgl-crosshair .mapboxgl-interactive,.mapboxgl-crosshair .mapboxgl-interactive:active{cursor:crosshair}.mapboxgl-boxzoom{background:#fff;border:2px dotted #202020;height:0;left:0;opacity:.5;position:absolute;top:0;width:0}@media print{.mapbox-improve-map{display:none}}.mapboxgl-scroll-zoom-blocker,.mapboxgl-touch-pan-blocker{align-items:center;background:#000000b3;color:#fff;display:flex;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Helvetica,Arial,sans-serif;height:100%;justify-content:center;left:0;opacity:0;pointer-events:none;position:absolute;text-align:center;top:0;transition:opacity .75s ease-in-out;transition-delay:1s;width:100%}.mapboxgl-scroll-zoom-blocker-show,.mapboxgl-touch-pan-blocker-show{opacity:1;transition:opacity .1s ease-in-out}.mapboxgl-canvas-container.mapboxgl-touch-pan-blocker-override.mapboxgl-scrollable-page,.mapboxgl-canvas-container.mapboxgl-touch-pan-blocker-override.mapboxgl-scrollable-page .mapboxgl-canvas{touch-action:pan-x pan-y}.mapboxgl-ctrl button.mapboxgl-ctrl-level-button{font-size:16px;font-weight:700;text-align:center}.mapboxgl-ctrl button.mapboxgl-ctrl-level-button-selected{background-color:#ccc;color:#000}.mapboxgl-ctrl button.mapboxgl-ctrl-level-button-selected:hover{background-color:#ccc}/* required styles */
-
-.leaflet-pane,
-.leaflet-tile,
-.leaflet-marker-icon,
-.leaflet-marker-shadow,
-.leaflet-tile-container,
-.leaflet-pane > svg,
-.leaflet-pane > canvas,
-.leaflet-zoom-box,
-.leaflet-image-layer,
-.leaflet-layer {
- position: absolute;
- left: 0;
- top: 0;
- }
-.leaflet-container {
- overflow: hidden;
- }
-.leaflet-tile,
-.leaflet-marker-icon,
-.leaflet-marker-shadow {
- -webkit-user-select: none;
- -moz-user-select: none;
- user-select: none;
- -webkit-user-drag: none;
- }
-/* Prevents IE11 from highlighting tiles in blue */
-.leaflet-tile::selection {
- background: transparent;
-}
-/* Safari renders non-retina tile on retina better with this, but Chrome is worse */
-.leaflet-safari .leaflet-tile {
- image-rendering: -webkit-optimize-contrast;
- }
-/* hack that prevents hw layers "stretching" when loading new tiles */
-.leaflet-safari .leaflet-tile-container {
- width: 1600px;
- height: 1600px;
- -webkit-transform-origin: 0 0;
- }
-.leaflet-marker-icon,
-.leaflet-marker-shadow {
- display: block;
- }
-/* .leaflet-container svg: reset svg max-width decleration shipped in Joomla! (joomla.org) 3.x */
-/* .leaflet-container img: map is broken in FF if you have max-width: 100% on tiles */
-.leaflet-container .leaflet-overlay-pane svg {
- max-width: none !important;
- max-height: none !important;
- }
-.leaflet-container .leaflet-marker-pane img,
-.leaflet-container .leaflet-shadow-pane img,
-.leaflet-container .leaflet-tile-pane img,
-.leaflet-container img.leaflet-image-layer,
-.leaflet-container .leaflet-tile {
- max-width: none !important;
- max-height: none !important;
- width: auto;
- padding: 0;
- }
-
-.leaflet-container img.leaflet-tile {
- /* See: https://bugs.chromium.org/p/chromium/issues/detail?id=600120 */
- mix-blend-mode: plus-lighter;
-}
-
-.leaflet-container.leaflet-touch-zoom {
- -ms-touch-action: pan-x pan-y;
- touch-action: pan-x pan-y;
- }
-.leaflet-container.leaflet-touch-drag {
- -ms-touch-action: pinch-zoom;
- /* Fallback for FF which doesn't support pinch-zoom */
- touch-action: none;
- touch-action: pinch-zoom;
-}
-.leaflet-container.leaflet-touch-drag.leaflet-touch-zoom {
- -ms-touch-action: none;
- touch-action: none;
-}
-.leaflet-container {
- -webkit-tap-highlight-color: transparent;
-}
-.leaflet-container a {
- -webkit-tap-highlight-color: rgba(51, 181, 229, 0.4);
-}
-.leaflet-tile {
- filter: inherit;
- visibility: hidden;
- }
-.leaflet-tile-loaded {
- visibility: inherit;
- }
-.leaflet-zoom-box {
- width: 0;
- height: 0;
- -moz-box-sizing: border-box;
- box-sizing: border-box;
- z-index: 800;
- }
-/* workaround for https://bugzilla.mozilla.org/show_bug.cgi?id=888319 */
-.leaflet-overlay-pane svg {
- -moz-user-select: none;
- }
-
-.leaflet-pane { z-index: 400; }
-
-.leaflet-tile-pane { z-index: 200; }
-.leaflet-overlay-pane { z-index: 400; }
-.leaflet-shadow-pane { z-index: 500; }
-.leaflet-marker-pane { z-index: 600; }
-.leaflet-tooltip-pane { z-index: 650; }
-.leaflet-popup-pane { z-index: 700; }
-
-.leaflet-map-pane canvas { z-index: 100; }
-.leaflet-map-pane svg { z-index: 200; }
-
-.leaflet-vml-shape {
- width: 1px;
- height: 1px;
- }
-.lvml {
- behavior: url(#default#VML);
- display: inline-block;
- position: absolute;
- }
-
-
-/* control positioning */
-
-.leaflet-control {
- position: relative;
- z-index: 800;
- pointer-events: visiblePainted; /* IE 9-10 doesn't have auto */
- pointer-events: auto;
- }
-.leaflet-top,
-.leaflet-bottom {
- position: absolute;
- z-index: 1000;
- pointer-events: none;
- }
-.leaflet-top {
- top: 0;
- }
-.leaflet-right {
- right: 0;
- }
-.leaflet-bottom {
- bottom: 0;
- }
-.leaflet-left {
- left: 0;
- }
-.leaflet-control {
- float: left;
- clear: both;
- }
-.leaflet-right .leaflet-control {
- float: right;
- }
-.leaflet-top .leaflet-control {
- margin-top: 10px;
- }
-.leaflet-bottom .leaflet-control {
- margin-bottom: 10px;
- }
-.leaflet-left .leaflet-control {
- margin-left: 10px;
- }
-.leaflet-right .leaflet-control {
- margin-right: 10px;
- }
-
-
-/* zoom and fade animations */
-
-.leaflet-fade-anim .leaflet-popup {
- opacity: 0;
- -webkit-transition: opacity 0.2s linear;
- -moz-transition: opacity 0.2s linear;
- transition: opacity 0.2s linear;
- }
-.leaflet-fade-anim .leaflet-map-pane .leaflet-popup {
- opacity: 1;
- }
-.leaflet-zoom-animated {
- -webkit-transform-origin: 0 0;
- -ms-transform-origin: 0 0;
- transform-origin: 0 0;
- }
-svg.leaflet-zoom-animated {
- will-change: transform;
-}
-
-.leaflet-zoom-anim .leaflet-zoom-animated {
- -webkit-transition: -webkit-transform 0.25s cubic-bezier(0,0,0.25,1);
- -moz-transition: -moz-transform 0.25s cubic-bezier(0,0,0.25,1);
- transition: transform 0.25s cubic-bezier(0,0,0.25,1);
- }
-.leaflet-zoom-anim .leaflet-tile,
-.leaflet-pan-anim .leaflet-tile {
- -webkit-transition: none;
- -moz-transition: none;
- transition: none;
- }
-
-.leaflet-zoom-anim .leaflet-zoom-hide {
- visibility: hidden;
- }
-
-
-/* cursors */
-
-.leaflet-interactive {
- cursor: pointer;
- }
-.leaflet-grab {
- cursor: -webkit-grab;
- cursor: -moz-grab;
- cursor: grab;
- }
-.leaflet-crosshair,
-.leaflet-crosshair .leaflet-interactive {
- cursor: crosshair;
- }
-.leaflet-popup-pane,
-.leaflet-control {
- cursor: auto;
- }
-.leaflet-dragging .leaflet-grab,
-.leaflet-dragging .leaflet-grab .leaflet-interactive,
-.leaflet-dragging .leaflet-marker-draggable {
- cursor: move;
- cursor: -webkit-grabbing;
- cursor: -moz-grabbing;
- cursor: grabbing;
- }
-
-/* marker & overlays interactivity */
-.leaflet-marker-icon,
-.leaflet-marker-shadow,
-.leaflet-image-layer,
-.leaflet-pane > svg path,
-.leaflet-tile-container {
- pointer-events: none;
- }
-
-.leaflet-marker-icon.leaflet-interactive,
-.leaflet-image-layer.leaflet-interactive,
-.leaflet-pane > svg path.leaflet-interactive,
-svg.leaflet-image-layer.leaflet-interactive path {
- pointer-events: visiblePainted; /* IE 9-10 doesn't have auto */
- pointer-events: auto;
- }
-
-/* visual tweaks */
-
-.leaflet-container {
- background: #ddd;
- outline-offset: 1px;
- }
-.leaflet-container a {
- color: #0078A8;
- }
-.leaflet-zoom-box {
- border: 2px dotted #38f;
- background: rgba(255,255,255,0.5);
- }
-
-
-/* general typography */
-.leaflet-container {
- font-family: "Helvetica Neue", Arial, Helvetica, sans-serif;
- font-size: 12px;
- font-size: 0.75rem;
- line-height: 1.5;
- }
-
-
-/* general toolbar styles */
-
-.leaflet-bar {
- box-shadow: 0 1px 5px rgba(0,0,0,0.65);
- border-radius: 4px;
- }
-.leaflet-bar a {
- background-color: #fff;
- border-bottom: 1px solid #ccc;
- width: 26px;
- height: 26px;
- line-height: 26px;
- display: block;
- text-align: center;
- text-decoration: none;
- color: black;
- }
-.leaflet-bar a,
-.leaflet-control-layers-toggle {
- background-position: 50% 50%;
- background-repeat: no-repeat;
- display: block;
- }
-.leaflet-bar a:hover,
-.leaflet-bar a:focus {
- background-color: #f4f4f4;
- }
-.leaflet-bar a:first-child {
- border-top-left-radius: 4px;
- border-top-right-radius: 4px;
- }
-.leaflet-bar a:last-child {
- border-bottom-left-radius: 4px;
- border-bottom-right-radius: 4px;
- border-bottom: none;
- }
-.leaflet-bar a.leaflet-disabled {
- cursor: default;
- background-color: #f4f4f4;
- color: #bbb;
- }
-
-.leaflet-touch .leaflet-bar a {
- width: 30px;
- height: 30px;
- line-height: 30px;
- }
-.leaflet-touch .leaflet-bar a:first-child {
- border-top-left-radius: 2px;
- border-top-right-radius: 2px;
- }
-.leaflet-touch .leaflet-bar a:last-child {
- border-bottom-left-radius: 2px;
- border-bottom-right-radius: 2px;
- }
-
-/* zoom control */
-
-.leaflet-control-zoom-in,
-.leaflet-control-zoom-out {
- font: bold 18px 'Lucida Console', Monaco, monospace;
- text-indent: 1px;
- }
-
-.leaflet-touch .leaflet-control-zoom-in, .leaflet-touch .leaflet-control-zoom-out {
- font-size: 22px;
- }
-
-
-/* layers control */
-
-.leaflet-control-layers {
- box-shadow: 0 1px 5px rgba(0,0,0,0.4);
- background: #fff;
- border-radius: 5px;
- }
-.leaflet-control-layers-toggle {
- background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABoAAAAaCAQAAAADQ4RFAAACf0lEQVR4AY1UM3gkARTePdvdoTxXKc+qTl3aU5U6b2Kbkz3Gtq3Zw6ziLGNPzrYx7946Tr6/ee/XeCQ4D3ykPtL5tHno4n0d/h3+xfuWHGLX81cn7r0iTNzjr7LrlxCqPtkbTQEHeqOrTy4Yyt3VCi/IOB0v7rVC7q45Q3Gr5K6jt+3Gl5nCoDD4MtO+j96Wu8atmhGqcNGHObuf8OM/x3AMx38+4Z2sPqzCxRFK2aF2e5Jol56XTLyggAMTL56XOMoS1W4pOyjUcGGQdZxU6qRh7B9Zp+PfpOFlqt0zyDZckPi1ttmIp03jX8gyJ8a/PG2yutpS/Vol7peZIbZcKBAEEheEIAgFbDkz5H6Zrkm2hVWGiXKiF4Ycw0RWKdtC16Q7qe3X4iOMxruonzegJzWaXFrU9utOSsLUmrc0YjeWYjCW4PDMADElpJSSQ0vQvA1Tm6/JlKnqFs1EGyZiFCqnRZTEJJJiKRYzVYzJck2Rm6P4iH+cmSY0YzimYa8l0EtTODFWhcMIMVqdsI2uiTvKmTisIDHJ3od5GILVhBCarCfVRmo4uTjkhrhzkiBV7SsaqS+TzrzM1qpGGUFt28pIySQHR6h7F6KSwGWm97ay+Z+ZqMcEjEWebE7wxCSQwpkhJqoZA5ivCdZDjJepuJ9IQjGGUmuXJdBFUygxVqVsxFsLMbDe8ZbDYVCGKxs+W080max1hFCarCfV+C1KATwcnvE9gRRuMP2prdbWGowm1KB1y+zwMMENkM755cJ2yPDtqhTI6ED1M/82yIDtC/4j4BijjeObflpO9I9MwXTCsSX8jWAFeHr05WoLTJ5G8IQVS/7vwR6ohirYM7f6HzYpogfS3R2OAAAAAElFTkSuQmCC);
- width: 36px;
- height: 36px;
- }
-.leaflet-retina .leaflet-control-layers-toggle {
- background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADQAAAA0CAQAAABvcdNgAAAEsklEQVR4AWL4TydIhpZK1kpWOlg0w3ZXP6D2soBtG42jeI6ZmQTHzAxiTbSJsYLjO9HhP+WOmcuhciVnmHVQcJnp7DFvScowZorad/+V/fVzMdMT2g9Cv9guXGv/7pYOrXh2U+RRR3dSd9JRx6bIFc/ekqHI29JC6pJ5ZEh1yWkhkbcFeSjxgx3L2m1cb1C7bceyxA+CNjT/Ifff+/kDk2u/w/33/IeCMOSaWZ4glosqT3DNnNZQ7Cs58/3Ce5HL78iZH/vKVIaYlqzfdLu8Vi7dnvUbEza5Idt36tquZFldl6N5Z/POLof0XLK61mZCmJSWjVF9tEjUluu74IUXvgttuVIHE7YxSkaYhJZam7yiM9Pv82JYfl9nptxZaxMJE4YSPty+vF0+Y2up9d3wwijfjZbabqm/3bZ9ecKHsiGmRflnn1MW4pjHf9oLufyn2z3y1D6n8g8TZhxyzipLNPnAUpsOiuWimg52psrTZYnOWYNDTMuWBWa0tJb4rgq1UvmutpaYEbZlwU3CLJm/ayYjHW5/h7xWLn9Hh1vepDkyf7dE7MtT5LR4e7yYpHrkhOUpEfssBLq2pPhAqoSWKUkk7EDqkmK6RrCEzqDjhNDWNE+XSMvkJRDWlZTmCW0l0PHQGRZY5t1L83kT0Y3l2SItk5JAWHl2dCOBm+fPu3fo5/3v61RMCO9Jx2EEYYhb0rmNQMX/vm7gqOEJLcXTGw3CAuRNeyaPWwjR8PRqKQ1PDA/dpv+on9Shox52WFnx0KY8onHayrJzm87i5h9xGw/tfkev0jGsQizqezUKjk12hBMKJ4kbCqGPVNXudyyrShovGw5CgxsRICxF6aRmSjlBnHRzg7Gx8fKqEubI2rahQYdR1YgDIRQO7JvQyD52hoIQx0mxa0ODtW2Iozn1le2iIRdzwWewedyZzewidueOGqlsn1MvcnQpuVwLGG3/IR1hIKxCjelIDZ8ldqWz25jWAsnldEnK0Zxro19TGVb2ffIZEsIO89EIEDvKMPrzmBOQcKQ+rroye6NgRRxqR4U8EAkz0CL6uSGOm6KQCdWjvjRiSP1BPalCRS5iQYiEIvxuBMJEWgzSoHADcVMuN7IuqqTeyUPq22qFimFtxDyBBJEwNyt6TM88blFHao/6tWWhuuOM4SAK4EI4QmFHA+SEyWlp4EQoJ13cYGzMu7yszEIBOm2rVmHUNqwAIQabISNMRstmdhNWcFLsSm+0tjJH1MdRxO5Nx0WDMhCtgD6OKgZeljJqJKc9po8juskR9XN0Y1lZ3mWjLR9JCO1jRDMd0fpYC2VnvjBSEFg7wBENc0R9HFlb0xvF1+TBEpF68d+DHR6IOWVv2BECtxo46hOFUBd/APU57WIoEwJhIi2CdpyZX0m93BZicktMj1AS9dClteUFAUNUIEygRZCtik5zSxI9MubTBH1GOiHsiLJ3OCoSZkILa9PxiN0EbvhsAo8tdAf9Seepd36lGWHmtNANTv5Jd0z4QYyeo/UEJqxKRpg5LZx6btLPsOaEmdMyxYdlc8LMaJnikDlhclqmPiQnTEpLUIZEwkRagjYkEibQErwhkTAKCLQEbUgkzJQWc/0PstHHcfEdQ+UAAAAASUVORK5CYII=);
- background-size: 26px 26px;
- }
-.leaflet-touch .leaflet-control-layers-toggle {
- width: 44px;
- height: 44px;
- }
-.leaflet-control-layers .leaflet-control-layers-list,
-.leaflet-control-layers-expanded .leaflet-control-layers-toggle {
- display: none;
- }
-.leaflet-control-layers-expanded .leaflet-control-layers-list {
- display: block;
- position: relative;
- }
-.leaflet-control-layers-expanded {
- padding: 6px 10px 6px 6px;
- color: #333;
- background: #fff;
- }
-.leaflet-control-layers-scrollbar {
- overflow-y: scroll;
- overflow-x: hidden;
- padding-right: 5px;
- }
-.leaflet-control-layers-selector {
- margin-top: 2px;
- position: relative;
- top: 1px;
- }
-.leaflet-control-layers label {
- display: block;
- font-size: 13px;
- font-size: 1.08333em;
- }
-.leaflet-control-layers-separator {
- height: 0;
- border-top: 1px solid #ddd;
- margin: 5px -10px 5px -6px;
- }
-
-/* Default icon URLs */
-.leaflet-default-icon-path { /* used only in path-guessing heuristic, see L.Icon.Default */
- background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABkAAAApCAYAAADAk4LOAAAFgUlEQVR4Aa1XA5BjWRTN2oW17d3YaZtr2962HUzbDNpjszW24mRt28p47v7zq/bXZtrp/lWnXr337j3nPCe85NcypgSFdugCpW5YoDAMRaIMqRi6aKq5E3YqDQO3qAwjVWrD8Ncq/RBpykd8oZUb/kaJutow8r1aP9II0WmLKLIsJyv1w/kqw9Ch2MYdB++12Onxee/QMwvf4/Dk/Lfp/i4nxTXtOoQ4pW5Aj7wpici1A9erdAN2OH64x8OSP9j3Ft3b7aWkTg/Fm91siTra0f9on5sQr9INejH6CUUUpavjFNq1B+Oadhxmnfa8RfEmN8VNAsQhPqF55xHkMzz3jSmChWU6f7/XZKNH+9+hBLOHYozuKQPxyMPUKkrX/K0uWnfFaJGS1QPRtZsOPtr3NsW0uyh6NNCOkU3Yz+bXbT3I8G3xE5EXLXtCXbbqwCO9zPQYPRTZ5vIDXD7U+w7rFDEoUUf7ibHIR4y6bLVPXrz8JVZEql13trxwue/uDivd3fkWRbS6/IA2bID4uk0UpF1N8qLlbBlXs4Ee7HLTfV1j54APvODnSfOWBqtKVvjgLKzF5YdEk5ewRkGlK0i33Eofffc7HT56jD7/6U+qH3Cx7SBLNntH5YIPvODnyfIXZYRVDPqgHtLs5ABHD3YzLuespb7t79FY34DjMwrVrcTuwlT55YMPvOBnRrJ4VXTdNnYug5ucHLBjEpt30701A3Ts+HEa73u6dT3FNWwflY86eMHPk+Yu+i6pzUpRrW7SNDg5JHR4KapmM5Wv2E8Tfcb1HoqqHMHU+uWDD7zg54mz5/2BSnizi9T1Dg4QQXLToGNCkb6tb1NU+QAlGr1++eADrzhn/u8Q2YZhQVlZ5+CAOtqfbhmaUCS1ezNFVm2imDbPmPng5wmz+gwh+oHDce0eUtQ6OGDIyR0uUhUsoO3vfDmmgOezH0mZN59x7MBi++WDL1g/eEiU3avlidO671bkLfwbw5XV2P8Pzo0ydy4t2/0eu33xYSOMOD8hTf4CrBtGMSoXfPLchX+J0ruSePw3LZeK0juPJbYzrhkH0io7B3k164hiGvawhOKMLkrQLyVpZg8rHFW7E2uHOL888IBPlNZ1FPzstSJM694fWr6RwpvcJK60+0HCILTBzZLFNdtAzJaohze60T8qBzyh5ZuOg5e7uwQppofEmf2++DYvmySqGBuKaicF1blQjhuHdvCIMvp8whTTfZzI7RldpwtSzL+F1+wkdZ2TBOW2gIF88PBTzD/gpeREAMEbxnJcaJHNHrpzji0gQCS6hdkEeYt9DF/2qPcEC8RM28Hwmr3sdNyht00byAut2k3gufWNtgtOEOFGUwcXWNDbdNbpgBGxEvKkOQsxivJx33iow0Vw5S6SVTrpVq11ysA2Rp7gTfPfktc6zhtXBBC+adRLshf6sG2RfHPZ5EAc4sVZ83yCN00Fk/4kggu40ZTvIEm5g24qtU4KjBrx/BTTH8ifVASAG7gKrnWxJDcU7x8X6Ecczhm3o6YicvsLXWfh3Ch1W0k8x0nXF+0fFxgt4phz8QvypiwCCFKMqXCnqXExjq10beH+UUA7+nG6mdG/Pu0f3LgFcGrl2s0kNNjpmoJ9o4B29CMO8dMT4Q5ox8uitF6fqsrJOr8qnwNbRzv6hSnG5wP+64C7h9lp30hKNtKdWjtdkbuPA19nJ7Tz3zR/ibgARbhb4AlhavcBebmTHcFl2fvYEnW0ox9xMxKBS8btJ+KiEbq9zA4RthQXDhPa0T9TEe69gWupwc6uBUphquXgf+/FrIjweHQS4/pduMe5ERUMHUd9xv8ZR98CxkS4F2n3EUrUZ10EYNw7BWm9x1GiPssi3GgiGRDKWRYZfXlON+dfNbM+GgIwYdwAAAAASUVORK5CYII=);
- }
-
-
-/* attribution and scale controls */
-
-.leaflet-container .leaflet-control-attribution {
- background: #fff;
- background: rgba(255, 255, 255, 0.8);
- margin: 0;
- }
-.leaflet-control-attribution,
-.leaflet-control-scale-line {
- padding: 0 5px;
- color: #333;
- line-height: 1.4;
- }
-.leaflet-control-attribution a {
- text-decoration: none;
- }
-.leaflet-control-attribution a:hover,
-.leaflet-control-attribution a:focus {
- text-decoration: underline;
- }
-.leaflet-attribution-flag {
- display: inline !important;
- vertical-align: baseline !important;
- width: 1em;
- height: 0.6669em;
- }
-.leaflet-left .leaflet-control-scale {
- margin-left: 5px;
- }
-.leaflet-bottom .leaflet-control-scale {
- margin-bottom: 5px;
- }
-.leaflet-control-scale-line {
- border: 2px solid #777;
- border-top: none;
- line-height: 1.1;
- padding: 2px 5px 1px;
- white-space: nowrap;
- -moz-box-sizing: border-box;
- box-sizing: border-box;
- background: rgba(255, 255, 255, 0.8);
- text-shadow: 1px 1px #fff;
- }
-.leaflet-control-scale-line:not(:first-child) {
- border-top: 2px solid #777;
- border-bottom: none;
- margin-top: -2px;
- }
-.leaflet-control-scale-line:not(:first-child):not(:last-child) {
- border-bottom: 2px solid #777;
- }
-
-.leaflet-touch .leaflet-control-attribution,
-.leaflet-touch .leaflet-control-layers,
-.leaflet-touch .leaflet-bar {
- box-shadow: none;
- }
-.leaflet-touch .leaflet-control-layers,
-.leaflet-touch .leaflet-bar {
- border: 2px solid rgba(0,0,0,0.2);
- background-clip: padding-box;
- }
-
-
-/* popup */
-
-.leaflet-popup {
- position: absolute;
- text-align: center;
- margin-bottom: 20px;
- }
-.leaflet-popup-content-wrapper {
- padding: 1px;
- text-align: left;
- border-radius: 12px;
- }
-.leaflet-popup-content {
- margin: 13px 24px 13px 20px;
- line-height: 1.3;
- font-size: 13px;
- font-size: 1.08333em;
- min-height: 1px;
- }
-.leaflet-popup-content p {
- margin: 17px 0;
- margin: 1.3em 0;
- }
-.leaflet-popup-tip-container {
- width: 40px;
- height: 20px;
- position: absolute;
- left: 50%;
- margin-top: -1px;
- margin-left: -20px;
- overflow: hidden;
- pointer-events: none;
- }
-.leaflet-popup-tip {
- width: 17px;
- height: 17px;
- padding: 1px;
-
- margin: -10px auto 0;
- pointer-events: auto;
-
- -webkit-transform: rotate(45deg);
- -moz-transform: rotate(45deg);
- -ms-transform: rotate(45deg);
- transform: rotate(45deg);
- }
-.leaflet-popup-content-wrapper,
-.leaflet-popup-tip {
- background: white;
- color: #333;
- box-shadow: 0 3px 14px rgba(0,0,0,0.4);
- }
-.leaflet-container a.leaflet-popup-close-button {
- position: absolute;
- top: 0;
- right: 0;
- border: none;
- text-align: center;
- width: 24px;
- height: 24px;
- font: 16px/24px Tahoma, Verdana, sans-serif;
- color: #757575;
- text-decoration: none;
- background: transparent;
- }
-.leaflet-container a.leaflet-popup-close-button:hover,
-.leaflet-container a.leaflet-popup-close-button:focus {
- color: #585858;
- }
-.leaflet-popup-scrolled {
- overflow: auto;
- }
-
-.leaflet-oldie .leaflet-popup-content-wrapper {
- -ms-zoom: 1;
- }
-.leaflet-oldie .leaflet-popup-tip {
- width: 24px;
- margin: 0 auto;
-
- -ms-filter: "progid:DXImageTransform.Microsoft.Matrix(M11=0.70710678, M12=0.70710678, M21=-0.70710678, M22=0.70710678)";
- filter: progid:DXImageTransform.Microsoft.Matrix(M11=0.70710678, M12=0.70710678, M21=-0.70710678, M22=0.70710678);
- }
-
-.leaflet-oldie .leaflet-control-zoom,
-.leaflet-oldie .leaflet-control-layers,
-.leaflet-oldie .leaflet-popup-content-wrapper,
-.leaflet-oldie .leaflet-popup-tip {
- border: 1px solid #999;
- }
-
-
-/* div icon */
-
-.leaflet-div-icon {
- background: #fff;
- border: 1px solid #666;
- }
-
-
-/* Tooltip */
-/* Base styles for the element that has a tooltip */
-.leaflet-tooltip {
- position: absolute;
- padding: 6px;
- background-color: #fff;
- border: 1px solid #fff;
- border-radius: 3px;
- color: #222;
- white-space: nowrap;
- -webkit-user-select: none;
- -moz-user-select: none;
- -ms-user-select: none;
- user-select: none;
- pointer-events: none;
- box-shadow: 0 1px 3px rgba(0,0,0,0.4);
- }
-.leaflet-tooltip.leaflet-interactive {
- cursor: pointer;
- pointer-events: auto;
- }
-.leaflet-tooltip-top:before,
-.leaflet-tooltip-bottom:before,
-.leaflet-tooltip-left:before,
-.leaflet-tooltip-right:before {
- position: absolute;
- pointer-events: none;
- border: 6px solid transparent;
- background: transparent;
- content: "";
- }
-
-/* Directions */
-
-.leaflet-tooltip-bottom {
- margin-top: 6px;
-}
-.leaflet-tooltip-top {
- margin-top: -6px;
-}
-.leaflet-tooltip-bottom:before,
-.leaflet-tooltip-top:before {
- left: 50%;
- margin-left: -6px;
- }
-.leaflet-tooltip-top:before {
- bottom: 0;
- margin-bottom: -12px;
- border-top-color: #fff;
- }
-.leaflet-tooltip-bottom:before {
- top: 0;
- margin-top: -12px;
- margin-left: -6px;
- border-bottom-color: #fff;
- }
-.leaflet-tooltip-left {
- margin-left: -6px;
-}
-.leaflet-tooltip-right {
- margin-left: 6px;
-}
-.leaflet-tooltip-left:before,
-.leaflet-tooltip-right:before {
- top: 50%;
- margin-top: -6px;
- }
-.leaflet-tooltip-left:before {
- right: 0;
- margin-right: -12px;
- border-left-color: #fff;
- }
-.leaflet-tooltip-right:before {
- left: 0;
- margin-left: -12px;
- border-right-color: #fff;
- }
-
-/* Printing */
-
-@media print {
- /* Prevent printers from removing background-images of controls. */
- .leaflet-control {
- -webkit-print-color-adjust: exact;
- print-color-adjust: exact;
- }
- }
diff --git a/Web/Resgrid.Web/wwwroot/js/ng/react-elements.js b/Web/Resgrid.Web/wwwroot/js/ng/react-elements.js
deleted file mode 100644
index f36e8f687..000000000
--- a/Web/Resgrid.Web/wwwroot/js/ng/react-elements.js
+++ /dev/null
@@ -1,2 +0,0 @@
-import "./chunks/elements-D7P98e6b.min.js";
-//# sourceMappingURL=react-elements.js.map