diff --git a/.gitattributes b/.gitattributes index 1b2aae1..ffc9537 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,3 +1,6 @@ *.iss linguist-vendored=true *.isl linguist-vendored=true *.py linguist-vendored=true + +# Preserve the reviewed vendor artifact byte-for-byte on Windows and Unix. +src/Web/vendor/ba-click-fx.iife.js -text diff --git a/.github/workflows/pr-build-check.yml b/.github/workflows/pr-build-check.yml index 39894e6..bf7cb9d 100644 --- a/.github/workflows/pr-build-check.yml +++ b/.github/workflows/pr-build-check.yml @@ -20,6 +20,15 @@ jobs: with: dotnet-version: '8.0.x' + - name: Setup Node.js 20 + uses: actions/setup-node@v4 + with: + node-version: '20' + + - name: Run Web tests + shell: pwsh + run: node --test tests/Web/fx-adapter.test.mjs tests/Web/vendor-contract.test.mjs + - name: Run tests shell: pwsh run: dotnet test BASpark.sln -c Release --verbosity normal diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index aa5a75b..da66f7e 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -23,6 +23,19 @@ jobs: with: dotnet-version: '8.0.x' + - name: Setup Node.js 20 + uses: actions/setup-node@v4 + with: + node-version: '20' + + - name: Run Web tests + shell: pwsh + run: node --test tests/Web/fx-adapter.test.mjs tests/Web/vendor-contract.test.mjs + + - name: Run .NET tests + shell: pwsh + run: dotnet test BASpark.sln -c Release --verbosity normal + - name: Build Packaged Files shell: pwsh run: | @@ -61,4 +74,4 @@ jobs: draft: false prerelease: false env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} \ No newline at end of file + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/pages/guide.md b/pages/guide.md index 112bc09..1ebfdea 100644 --- a/pages/guide.md +++ b/pages/guide.md @@ -52,10 +52,10 @@ In the "Visual Performance" sub-settings menu, you can adjust the following para * **Global Opacity**: Adjusts the overall visual intensity and transparency of the effects. * **Animation Speed**: Adjusts the overall playback speed of the effects. * **Speed Synchronization**: Enabled by default. Unchecking this allows you to independently adjust "Click Speed" and "Trail Speed". -* **Trail Refresh Rate**: Supports up to 240Hz. Higher values offer smoother paths but consume relatively more system resources. +* **Input Sampling Rate Limit**: Accepts `0` (unlimited) or `1`–`1000Hz`, with a default of `40Hz`. Lower rates retain fewer pointer samples and create more angular paths; this setting is independent of animation speed and rendering frame rate. ### Theme Colors -Click the **"Change Color"** button to bring up the color palette and customize the core color of the particles. +Click the **"Change Color"** button to bring up the color palette and customize the effect theme. BASpark uses the recommended relative OKLCH mapping so hue, chroma, and perceptual lightness are adjusted before HDR and Bloom processing. ### Reset to Default Click the **"Restore Default Settings"** button to selectively reset items to their default values. @@ -119,4 +119,4 @@ No need to visit the website manually. In the **"About"** page of the software, * **Auto Comparison**: The system automatically detects version discrepancies between your local build and the server. * **One-Click Upgrade**: Provides automatic pop-up notifications containing update changelogs when a new version is detected. -*Note: The automatic update feature requires an internet connection. Data fetching might fail under strict firewall environments.* \ No newline at end of file +*Note: The automatic update feature requires an internet connection. Data fetching might fail under strict firewall environments.* diff --git a/pages/index.md b/pages/index.md index 9233f87..d9e93a5 100644 --- a/pages/index.md +++ b/pages/index.md @@ -27,9 +27,9 @@ features: - title: 🧠 Smart Environment Filter details: Context-aware detection that auto-pauses in full-screen games/videos. Supports customizable Blacklist and Whitelist modes. - title: 🎨 Precise Visual Tuning - details: Fully customize scale ratio, opacity, animation speed, and trail refresh rates (up to 240Hz) via sliders or precise inputs. + details: Fully customize scale, opacity, animation speed, theme color, and input sampling rates from unlimited through 1000Hz. - title: 🖥️ Multi-Screen Management details: Intelligent monitor hardware ID memory. Independently toggle effects for each screen with dynamic topology refresh. - title: 🌐 Global Optimization details: Built-in network source selection (Mainland China / Global) ensures stable cloud notices and one-click auto-updates worldwide. ---- \ No newline at end of file +--- diff --git a/src/AssemblyInfo.cs b/src/AssemblyInfo.cs index cc29e7f..4b843c8 100644 --- a/src/AssemblyInfo.cs +++ b/src/AssemblyInfo.cs @@ -1,5 +1,7 @@ +using System.Runtime.CompilerServices; using System.Windows; +[assembly: InternalsVisibleTo("BASpark.Tests")] [assembly:ThemeInfo( ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located //(used if a resource is not found in the page, diff --git a/src/BASpark.csproj b/src/BASpark.csproj index 7152faf..e18954b 100644 --- a/src/BASpark.csproj +++ b/src/BASpark.csproj @@ -34,7 +34,21 @@ + + + + + + + + - \ No newline at end of file + diff --git a/src/ConfigManager.cs b/src/ConfigManager.cs index 8e0ded2..11353b8 100644 --- a/src/ConfigManager.cs +++ b/src/ConfigManager.cs @@ -15,7 +15,7 @@ public enum VisualAppearanceResetFlags EffectScale = 1 << 0, EffectOpacity = 1 << 1, UnifiedAnimationSpeed = 1 << 2, - TrailRefreshRate = 1 << 3, + InputSamplingRate = 1 << 3, ParticleColor = 1 << 4, TrailAnimationSpeed = 1 << 5, ClickAnimationSpeed = 1 << 6 @@ -61,6 +61,9 @@ public class ScreenSelectionState public static class ConfigManager { private const string RegPath = @"Software\BASpark"; + public const int DefaultInputSamplingRate = 40; + public const int MinimumInputSamplingRate = 0; + public const int MaximumInputSamplingRate = 1000; public static string ParticleColor { get; set; } = "45,175,255"; public static bool IsEffectEnabled { get; set; } = true; @@ -79,7 +82,7 @@ public static class ConfigManager public static bool ApplyCurveDraw { get; set; } = false; public static double TrailAnimationSpeed { get; set; } = 1.0; public static double ClickAnimationSpeed { get; set; } = 1.0; - public static int TrailRefreshRate { get; set; } = 40; + public static int InputSamplingRate { get; set; } = DefaultInputSamplingRate; public static bool EnableEnvironmentFilter { get; set; } = false; public static bool HideInFullscreen { get; set; } = true; public static bool ShowEffectOnDesktop { get; set; } = true; @@ -141,7 +144,13 @@ public static void Load() ApplyCurveDraw = Convert.ToBoolean(key.GetValue("ApplyCurveDraw", false)); TrailAnimationSpeed = Math.Clamp(Convert.ToDouble(key.GetValue("TrailAnimationSpeed", EffectSpeed), CultureInfo.InvariantCulture), 0.2, 3.0); ClickAnimationSpeed = Math.Clamp(Convert.ToDouble(key.GetValue("ClickAnimationSpeed", EffectSpeed), CultureInfo.InvariantCulture), 0.2, 3.0); - TrailRefreshRate = Math.Clamp(Convert.ToInt32(key.GetValue("TrailRefreshRate", 40), CultureInfo.InvariantCulture), 10, 240); + object legacyInputSamplingRate = key.GetValue( + "TrailRefreshRate", + DefaultInputSamplingRate) ?? DefaultInputSamplingRate; + InputSamplingRate = NormalizeInputSamplingRate( + Convert.ToInt32( + key.GetValue("InputSamplingRate", legacyInputSamplingRate), + CultureInfo.InvariantCulture)); EnableEnvironmentFilter = Convert.ToBoolean(key.GetValue("EnableEnvironmentFilter", false)); HideInFullscreen = Convert.ToBoolean(key.GetValue("HideInFullscreen", true)); ShowEffectOnDesktop = Convert.ToBoolean(key.GetValue("ShowEffectOnDesktop", true)); @@ -262,6 +271,14 @@ public static NetworkRegionOption ParseNetworkRegion(string? raw) return NetworkRegionOption.Auto; } + public static int NormalizeInputSamplingRate(int rateHz) + { + return Math.Clamp( + rateHz, + MinimumInputSamplingRate, + MaximumInputSamplingRate); + } + public static void GetAnimationSpeedsForOverlay(out double trailSpeed, out double clickSpeed) { if (UseLinkedAnimationSpeed) @@ -340,9 +357,9 @@ public static void ApplyVisualAppearanceDefaults(VisualAppearanceResetFlags flag Save("ClickAnimationSpeed", 1.0); } - if (flags.HasFlag(VisualAppearanceResetFlags.TrailRefreshRate)) + if (flags.HasFlag(VisualAppearanceResetFlags.InputSamplingRate)) { - Save("TrailRefreshRate", 40); + Save("InputSamplingRate", DefaultInputSamplingRate); } if (flags.HasFlag(VisualAppearanceResetFlags.ParticleColor)) @@ -576,7 +593,7 @@ public static void ResetAndClear() ApplyCurveDraw = false; TrailAnimationSpeed = 1.0; ClickAnimationSpeed = 1.0; - TrailRefreshRate = 40; + InputSamplingRate = DefaultInputSamplingRate; EnableEnvironmentFilter = false; HideInFullscreen = true; ShowEffectOnDesktop = true; diff --git a/src/ControlPanelWindow.xaml b/src/ControlPanelWindow.xaml index f24ae04..64c3b7f 100644 --- a/src/ControlPanelWindow.xaml +++ b/src/ControlPanelWindow.xaml @@ -522,11 +522,11 @@ - + - + @@ -582,19 +582,21 @@ - + - - + + diff --git a/src/ControlPanelWindow.xaml.cs b/src/ControlPanelWindow.xaml.cs index 11dba50..74534d0 100644 --- a/src/ControlPanelWindow.xaml.cs +++ b/src/ControlPanelWindow.xaml.cs @@ -588,7 +588,7 @@ private void LoadSettingsCore() SliderSpeed.Value = ConfigManager.EffectSpeed; SliderTrailAnimSpeed.Value = ConfigManager.TrailAnimationSpeed; SliderClickAnimSpeed.Value = ConfigManager.ClickAnimationSpeed; - SliderTrailRefresh.Value = ConfigManager.TrailRefreshRate; + SliderInputSamplingRate.Value = ConfigManager.InputSamplingRate; UpdateAnimationSpeedPanelVisibility(); if (ConfigManager.ScrollbarVisibility == PanelScrollbarVisibility.Always) @@ -1231,7 +1231,10 @@ private void RebuildVisualResetItems() VisualResetItems.Add(new VisualResetItem(VisualAppearanceResetFlags.UnifiedAnimationSpeed, Localization.Get("VisualReset_UnifiedSpeed"), Localization.Get("VisualReset_UnifiedSpeed_Sub"))); VisualResetItems.Add(new VisualResetItem(VisualAppearanceResetFlags.TrailAnimationSpeed, Localization.Get("VisualReset_TrailSpeed"), Localization.Get("VisualReset_TrailSpeed_Sub"))); VisualResetItems.Add(new VisualResetItem(VisualAppearanceResetFlags.ClickAnimationSpeed, Localization.Get("VisualReset_ClickSpeed"), Localization.Get("VisualReset_ClickSpeed_Sub"))); - VisualResetItems.Add(new VisualResetItem(VisualAppearanceResetFlags.TrailRefreshRate, Localization.Get("VisualReset_TrailRefresh"), Localization.Get("VisualReset_TrailRefresh_Sub"))); + VisualResetItems.Add(new VisualResetItem( + VisualAppearanceResetFlags.InputSamplingRate, + Localization.Get("VisualReset_InputSamplingRate"), + Localization.Get("VisualReset_InputSamplingRate_Sub"))); VisualResetItems.Add(new VisualResetItem(VisualAppearanceResetFlags.ParticleColor, Localization.Get("VisualReset_Color"), Localization.Get("VisualReset_Color_Sub"))); } @@ -1311,13 +1314,13 @@ private void ConfirmVisualReset_Click(object sender, RoutedEventArgs e) ConfigManager.ApplyVisualAppearanceDefaults(flags); LoadSettings(); - int trailRefreshRate = (int)Math.Round(SliderTrailRefresh.Value); + int inputSamplingRate = (int)Math.Round(SliderInputSamplingRate.Value); ConfigManager.GetAnimationSpeedsForOverlay(out double trailSp, out double clickSp); double effectScale = Math.Round(SliderScale.Value, 2); double effectOpacity = Math.Round(SliderOpacity.Value / 100.0, 2); App.Overlay?.UpdateColor(ConfigManager.ParticleColor); App.Overlay?.UpdateEffectSettings(effectScale, effectOpacity, trailSp, clickSp); - App.Overlay?.UpdateTrailRefreshRate(trailRefreshRate); + App.Overlay?.UpdateInputSamplingRate(inputSamplingRate); App.Overlay?.SetCurveDraw(CheckApplyCurveDraw.IsChecked ?? false); VisualResetOverlay.Visibility = Visibility.Collapsed; @@ -1378,7 +1381,7 @@ private void SaveSettings_Click(object sender, RoutedEventArgs e) effectSpeedForRegistry = clickAnimSpeed; } - int trailRefreshRate = (int)Math.Round(SliderTrailRefresh.Value); + int inputSamplingRate = (int)Math.Round(SliderInputSamplingRate.Value); bool autoStartEnabled = CheckAutoStart.IsChecked ?? false; bool startSilentEnabled = CheckStartSilent.IsChecked ?? false; bool runAsAdminEnabled = CheckRunAsAdmin.IsChecked ?? false; @@ -1409,7 +1412,7 @@ private void SaveSettings_Click(object sender, RoutedEventArgs e) ConfigManager.Save("EffectSpeed", effectSpeedForRegistry); ConfigManager.Save("TrailAnimationSpeed", trailAnimSpeed); ConfigManager.Save("ClickAnimationSpeed", clickAnimSpeed); - ConfigManager.Save("TrailRefreshRate", trailRefreshRate); + ConfigManager.Save("InputSamplingRate", inputSamplingRate); ConfigManager.Save("TotalClicks", ConfigManager.TotalClicks); ConfigManager.Save("EnableAlwaysTrailEffect", CheckAlwaysTrailEffectSwitch.IsChecked ?? false); var scrollbarVisibility = RadioScrollbarAlways.IsChecked == true @@ -1483,7 +1486,7 @@ private void SaveSettings_Click(object sender, RoutedEventArgs e) App.Overlay?.UpdateColor(ConfigManager.ParticleColor); GetUiAnimationSpeeds(out double overlayTrail, out double overlayClick); App.Overlay?.UpdateEffectSettings(effectScale, effectOpacity, overlayTrail, overlayClick); - App.Overlay?.UpdateTrailRefreshRate(trailRefreshRate); + App.Overlay?.UpdateInputSamplingRate(inputSamplingRate); App.Overlay?.RefreshEnvironmentFilterState(); App.Overlay?.UpdateTouchMode(isTouchscreenEnabled); App.Overlay?.UpdateScreenshotCompatibilityMode(screenshotCompatibilityEnabled); diff --git a/src/MainWindow.xaml b/src/MainWindow.xaml index e89f783..13de1b6 100644 --- a/src/MainWindow.xaml +++ b/src/MainWindow.xaml @@ -11,7 +11,7 @@ ResizeMode="NoResize" Left="0" Top="0" IsHitTestVisible="False"> - + - \ No newline at end of file + diff --git a/src/MainWindow.xaml.cs b/src/MainWindow.xaml.cs index 1ef778e..ecbe645 100644 --- a/src/MainWindow.xaml.cs +++ b/src/MainWindow.xaml.cs @@ -4,6 +4,7 @@ using System.Globalization; using System.Linq; using System.Runtime.InteropServices; +using System.Text.Json; using System.Windows; using System.Windows.Forms; using System.Windows.Interop; @@ -80,11 +81,20 @@ private struct RECT private bool? _lastReportedAlwaysTrail; private const string InputModeMouse = "mouse"; private const string InputModeTouch = "touch"; + private const string PrimaryRendererResourcePath = "Web/index.html"; + private const string LegacyRendererResourcePath = "Web/index.legacy.html"; + private const string RendererVendorResourcePath = "Web/vendor/ba-click-fx.iife.js"; + private const string RendererAdapterResourcePath = "Web/fx-adapter.js"; private System.Windows.Threading.DispatcherTimer? _topmostTimer; + private System.Windows.Threading.DispatcherTimer? _rendererReadyTimeoutTimer; + private EventHandler? _navigationStartingHandler; private EventHandler? _navigationCompletedHandler; private EventHandler? _processFailedHandler; + private EventHandler? _webMessageReceivedHandler; private CoreWebView2? _coreWebView; + private ulong? _currentNavigationId; + private string? _rendererGeneration; private WinEventDelegate? _winEventDelegate; private IntPtr _winEventHook = IntPtr.Zero; private long _lastEnsureTopmostTicks; @@ -94,6 +104,13 @@ private struct RECT private bool _hiddenForExternalScreenshotCapture; private bool _hiddenByEnvironmentSuppression; private bool _overlayRuntimePaused; + private bool _rendererReady; + private bool _usingLegacyRenderer; + private int _inputSamplingRate = ConfigManager.DefaultInputSamplingRate; + private long _lastLegacyMoveTicks; + private bool _legacyFallbackAttempted; + private bool _processRecoveryPending; + private readonly WebViewUnresponsiveTracker _unresponsiveTracker = new(); private delegate void WinEventDelegate( IntPtr hWinEventHook, @@ -112,7 +129,7 @@ public MainWindow(Screen screen) InitializeComponent(); webView.DefaultBackgroundColor = System.Drawing.Color.Transparent; - UpdateTrailRefreshRate(ConfigManager.TrailRefreshRate); + UpdateInputSamplingRate(ConfigManager.InputSamplingRate); _ = InitWebView(); } @@ -195,7 +212,9 @@ private void SafeEnsureTopmost() public void UpdateColor(string color) { - ExecuteScript($"if(window.updateColor) window.updateColor('{color}');"); + // JSON serialization keeps registry-backed color text from becoming executable script. + string colorJson = JsonSerializer.Serialize(color); + ExecuteScript($"if(window.updateColor) window.updateColor({colorJson});"); } public void UpdateEffectSettings(double scale, double opacity, double trailSpeed, double clickSpeed) @@ -208,9 +227,19 @@ public void UpdateEffectSettings(double scale, double opacity, double trailSpeed ExecuteScript($"if(window.updateEffectSettings) window.updateEffectSettings({scaleStr}, {opacityStr}, {trailStr}, {clickStr});"); } - public void UpdateTrailRefreshRate(int hz) + public void UpdateInputSamplingRate(int rateHz) { - _ = hz; + _inputSamplingRate = ConfigManager.NormalizeInputSamplingRate(rateHz); + _lastLegacyMoveTicks = 0; + ExecuteScript(BuildInputSamplingRateScript(_inputSamplingRate)); + } + + internal static string BuildInputSamplingRateScript(int rateHz) + { + int normalizedRate = ConfigManager.NormalizeInputSamplingRate(rateHz); + return + "if(window.updateInputSamplingRate) " + + $"window.updateInputSamplingRate({normalizedRate.ToString(CultureInfo.InvariantCulture)});"; } public void SetCurveDraw(bool enabled) @@ -392,7 +421,10 @@ private async System.Threading.Tasks.Task InitWebView() try { var env = await WebView2EnvironmentHolder.GetOrCreateAsync().ConfigureAwait(true); - if (_isClosing) return; + if (_isClosing) + { + return; + } if (webView.CoreWebView2 == null) { @@ -410,55 +442,359 @@ private async System.Threading.Tasks.Task InitWebView() } } - if (_isClosing || !TryGetCoreWebView2(out CoreWebView2? coreWebView)) return; + if (_isClosing || !TryGetCoreWebView2(out CoreWebView2? coreWebView)) + { + return; + } + DetachCoreWebViewEvents(); _coreWebView = coreWebView; coreWebView.Settings.IsZoomControlEnabled = false; coreWebView.Settings.AreDefaultContextMenusEnabled = false; coreWebView.Settings.IsStatusBarEnabled = false; - if (_processFailedHandler == null) + _processFailedHandler = OnWebViewProcessFailed; + _navigationStartingHandler = OnNavigationStarting; + _navigationCompletedHandler = OnNavigationCompleted; + _webMessageReceivedHandler = OnWebMessageReceived; + coreWebView.ProcessFailed += _processFailedHandler; + coreWebView.NavigationStarting += _navigationStartingHandler; + coreWebView.NavigationCompleted += _navigationCompletedHandler; + coreWebView.WebMessageReceived += _webMessageReceivedHandler; + + NavigateCurrentRenderer(coreWebView); + } + catch (Exception ex) when (IsExpectedWebViewShutdownException(ex)) + { + } + catch (Exception ex) + { + System.Windows.MessageBox.Show(Localization.Format("WebView2_InitFailed", ex.Message)); + } + } + + private void NavigateCurrentRenderer(CoreWebView2 coreWebView) + { + StopRendererReadyTimeout(); + _rendererReady = _usingLegacyRenderer; + + if (_usingLegacyRenderer) + { + _rendererGeneration = null; + string legacyHtml = ReadResourceText(LegacyRendererResourcePath); + NavigateHtml(coreWebView, legacyHtml); + return; + } + + _rendererGeneration = null; + try + { + string rendererGeneration = Guid.NewGuid().ToString("N"); + string rendererHtml = BuildPrimaryRendererHtml(rendererGeneration); + _rendererGeneration = rendererGeneration; + NavigateHtml(coreWebView, rendererHtml); + } + catch (Exception ex) when (!IsExpectedWebViewShutdownException(ex)) + { + AppLogger.Error( + $"Failed to prepare BA click renderer on '{_screenDeviceName}'.", + ex); + FallbackToLegacyRenderer("primary renderer resource preparation failed"); + return; + } + + // A renderer that cannot announce readiness must not leave an invisible overlay active. + if (!_rendererReady) + { + StartRendererReadyTimeout(); + } + } + + private static string BuildPrimaryRendererHtml(string rendererGeneration) + { + string generationJson = JsonSerializer.Serialize(rendererGeneration); + string adapterScript = + $"window.__basparkRendererGeneration = {generationJson};\n" + + ReadResourceText(RendererAdapterResourcePath); + + return WebRendererDocumentBuilder.Build( + ReadResourceText(PrimaryRendererResourcePath), + ReadResourceText(RendererVendorResourcePath), + adapterScript); + } + + private static string ReadResourceText(string resourcePath) + { + string assemblyName = typeof(MainWindow).Assembly.GetName().Name ?? "BASpark"; + // Explicit component lookup also works when a diagnostic host references BASpark. + var resourceUri = new Uri( + $"pack://application:,,,/{assemblyName};component/{resourcePath}", + UriKind.Absolute); + var streamInfo = System.Windows.Application.GetResourceStream(resourceUri); + if (streamInfo == null) + { + throw new InvalidOperationException($"Embedded renderer resource '{resourcePath}' was not found."); + } + + using var reader = new System.IO.StreamReader(streamInfo.Stream); + return reader.ReadToEnd(); + } + + private void NavigateHtml(CoreWebView2 coreWebView, string html) + { + // NavigationStarting assigns the authoritative ID before any matching completion event. + _currentNavigationId = null; + coreWebView.NavigateToString(html); + } + + private void OnNavigationStarting(object? sender, CoreWebView2NavigationStartingEventArgs e) + { + if (_isClosing || !ReferenceEquals(sender, _coreWebView)) + { + return; + } + + _currentNavigationId = e.NavigationId; + } + + private void OnNavigationCompleted(object? sender, CoreWebView2NavigationCompletedEventArgs e) + { + if (_isClosing || + !ReferenceEquals(sender, _coreWebView) || + _currentNavigationId != e.NavigationId) + { + return; + } + + if (!e.IsSuccess) + { + if (!_usingLegacyRenderer) { - _processFailedHandler = OnWebViewProcessFailed; - coreWebView.ProcessFailed += _processFailedHandler; + FallbackToLegacyRenderer($"navigation failed: {e.WebErrorStatus}"); } + else if (e.WebErrorStatus != CoreWebView2WebErrorStatus.OperationCanceled) + { + AppLogger.Error( + $"Legacy renderer navigation failed on '{_screenDeviceName}': {e.WebErrorStatus}."); + } + return; + } - if (_navigationCompletedHandler != null) + // Navigation creates a new JS global object, so every page needs the complete host state. + _lastReportedInputMode = null; + _lastReportedAlwaysTrail = null; + UpdateColor(ConfigManager.ParticleColor); + ConfigManager.GetAnimationSpeedsForOverlay(out double trailSp, out double clickSp); + UpdateEffectSettings(ConfigManager.EffectScale, ConfigManager.EffectOpacity, trailSp, clickSp); + UpdateInputSamplingRate(ConfigManager.InputSamplingRate); + SyncInputContext(InputModeMouse); + if (_overlayRuntimePaused) + { + ExecuteScript("if(window.setRenderingPaused) window.setRenderingPaused(true);"); + _ = TrySuspendWebViewAsync(); + } + } + + private void OnWebMessageReceived(object? sender, CoreWebView2WebMessageReceivedEventArgs e) + { + if (_isClosing || _usingLegacyRenderer || !ReferenceEquals(sender, _coreWebView)) + { + return; + } + + string messageJson; + try + { + messageJson = e.TryGetWebMessageAsString(); + } + catch (ArgumentException) + { + // Accept object messages defensively while the documented adapter contract remains JSON text. + messageJson = e.WebMessageAsJson; + } + + try + { + using JsonDocument document = JsonDocument.Parse(messageJson); + JsonElement root = document.RootElement; + if (root.ValueKind != JsonValueKind.Object) + { + return; + } + if (!string.Equals(GetJsonString(root, "source"), "baspark-fx", StringComparison.Ordinal)) + { + return; + } + if (!string.Equals( + GetJsonString(root, "generation"), + _rendererGeneration, + StringComparison.Ordinal)) { - try { coreWebView.NavigationCompleted -= _navigationCompletedHandler; } catch { /* best-effort */ } + return; } - var streamInfo = System.Windows.Application.GetResourceStream(new Uri("pack://application:,,,/Web/index.html")); - if (streamInfo != null) + string? type = GetJsonString(root, "type"); + string requestedEffectBackend = + GetJsonString(root, "requestedEffectBackend") ?? "unknown"; + string resolvedEffectBackend = + GetJsonString(root, "resolvedEffectBackend") ?? "unknown"; + string requestedBloomBackend = + GetJsonString(root, "requestedBloomBackend") ?? "unknown"; + string resolvedBloomBackend = + GetJsonString(root, "resolvedBloomBackend") ?? "unknown"; + string requestedHostCompositing = + GetJsonString(root, "requestedHostCompositing") ?? "unknown"; + string resolvedHostCompositing = + GetJsonString(root, "resolvedHostCompositing") ?? "unknown"; + string hostCompositingSurface = + GetJsonString(root, "hostCompositingSurface") ?? "unknown"; + string? compositingWarning = + GetJsonString(root, "compositingWarning"); + string backend = GetJsonString(root, "backend") ?? + (resolvedEffectBackend == "webgl2" + ? resolvedEffectBackend + : resolvedBloomBackend); + + if (string.Equals(type, "ready", StringComparison.Ordinal)) { - using var reader = new System.IO.StreamReader(streamInfo.Stream); - string htmlContent = reader.ReadToEnd(); - coreWebView.NavigateToString(htmlContent); - _navigationCompletedHandler = (s, e) => + bool firstReadyMessage = !_rendererReady; + _rendererReady = true; + _unresponsiveTracker.Reset(); + StopRendererReadyTimeout(); + if (firstReadyMessage) { - if (_isClosing) return; - - _lastReportedInputMode = null; - _lastReportedAlwaysTrail = null; - UpdateColor(ConfigManager.ParticleColor); - ConfigManager.GetAnimationSpeedsForOverlay(out double trailSp, out double clickSp); - UpdateEffectSettings(ConfigManager.EffectScale, ConfigManager.EffectOpacity, trailSp, clickSp); - SyncInputContext(InputModeMouse); - if (_overlayRuntimePaused) - { - ExecuteScript("if(window.setRenderingPaused) window.setRenderingPaused(true);"); - _ = TrySuspendWebViewAsync(); - } - }; - coreWebView.NavigationCompleted += _navigationCompletedHandler; + AppLogger.Info( + $"BA click renderer ready on '{_screenDeviceName}' " + + $"(effective: {backend}, effect: {resolvedEffectBackend}, " + + $"bloom: {resolvedBloomBackend}, host: " + + $"{resolvedHostCompositing} on {hostCompositingSurface}" + + $"{FormatCompositingWarning(compositingWarning)})."); + } + return; } + + if (string.Equals(type, "backend", StringComparison.Ordinal)) + { + AppLogger.Info( + $"BA click renderer backend on '{_screenDeviceName}': " + + $"effective {backend}; effect {resolvedEffectBackend} " + + $"(requested {requestedEffectBackend}); bloom {resolvedBloomBackend} " + + $"(requested {requestedBloomBackend}); host " + + $"{resolvedHostCompositing} on {hostCompositingSurface} " + + $"(requested {requestedHostCompositing})" + + $"{FormatCompositingWarning(compositingWarning)}."); + return; + } + + if (string.Equals(type, "error", StringComparison.Ordinal)) + { + string phase = GetJsonString(root, "phase") ?? "unknown"; + string message = GetJsonString(root, "message") ?? "unspecified renderer error"; + AppLogger.Error( + $"BA click renderer error on '{_screenDeviceName}' during '{phase}': {message}."); + FallbackToLegacyRenderer($"renderer error during '{phase}'"); + } + } + catch (JsonException ex) + { + AppLogger.Warn( + $"Ignored malformed renderer message on '{_screenDeviceName}': {ex.Message}"); + } + } + + private static string? GetJsonString(JsonElement element, string propertyName) + { + if (!element.TryGetProperty(propertyName, out JsonElement value) || + value.ValueKind != JsonValueKind.String) + { + return null; + } + + return value.GetString(); + } + + private static string FormatCompositingWarning(string? warning) + { + return string.IsNullOrWhiteSpace(warning) + ? string.Empty + : $"; warning: {warning}"; + } + + private void StartRendererReadyTimeout() + { + StopRendererReadyTimeout(); + _rendererReadyTimeoutTimer = new System.Windows.Threading.DispatcherTimer + { + Interval = TimeSpan.FromSeconds(2) + }; + _rendererReadyTimeoutTimer.Tick += OnRendererReadyTimeout; + _rendererReadyTimeoutTimer.Start(); + } + + private void OnRendererReadyTimeout(object? sender, EventArgs e) + { + if (!ReferenceEquals(sender, _rendererReadyTimeoutTimer)) + { + return; + } + + StopRendererReadyTimeout(); + if (_isClosing || _rendererReady || _usingLegacyRenderer) + { + return; + } + + AppLogger.Warn( + $"BA click renderer ready timeout on '{_screenDeviceName}'; switching to legacy renderer."); + FallbackToLegacyRenderer("ready timeout"); + } + + private void StopRendererReadyTimeout() + { + if (_rendererReadyTimeoutTimer == null) + { + return; + } + + _rendererReadyTimeoutTimer.Stop(); + _rendererReadyTimeoutTimer.Tick -= OnRendererReadyTimeout; + _rendererReadyTimeoutTimer = null; + } + + private void FallbackToLegacyRenderer(string reason) + { + if (_isClosing || _usingLegacyRenderer || _legacyFallbackAttempted) + { + return; + } + + if (!TryGetCoreWebView2(out CoreWebView2? coreWebView)) + { + return; + } + + // The one-way fallback prevents a broken primary/legacy pair from navigating forever. + _legacyFallbackAttempted = true; + _usingLegacyRenderer = true; + _rendererReady = true; + _rendererGeneration = null; + StopRendererReadyTimeout(); + AppLogger.Warn( + $"Falling back to legacy renderer on '{_screenDeviceName}' ({reason})."); + + try + { + string legacyHtml = ReadResourceText(LegacyRendererResourcePath); + NavigateHtml(coreWebView, legacyHtml); } catch (Exception ex) when (IsExpectedWebViewShutdownException(ex)) { } - catch (Exception ex) + catch (Exception ex) when (!IsExpectedWebViewShutdownException(ex)) { - System.Windows.MessageBox.Show(Localization.Format("WebView2_InitFailed", ex.Message)); + AppLogger.Error( + $"Failed to load legacy renderer on '{_screenDeviceName}'.", + ex); } } @@ -470,21 +806,174 @@ private static bool IsWebViewEnvironmentConflictException(Exception ex) private void OnWebViewProcessFailed(object? sender, CoreWebView2ProcessFailedEventArgs e) { - if (_isClosing) return; + if (_isClosing || + sender is not CoreWebView2 failedCoreWebView || + !ReferenceEquals(failedCoreWebView, _coreWebView)) + { + return; + } + + CoreWebView2ProcessFailedKind failureKind = e.ProcessFailedKind; + WebViewProcessRecoveryAction recoveryAction = + WebViewProcessFailurePolicy.GetRecoveryAction(failureKind); + if (failureKind == CoreWebView2ProcessFailedKind.RenderProcessUnresponsive) + { + bool shouldRecover = _unresponsiveTracker.Register( + failedCoreWebView, + DateTime.UtcNow.Ticks); + if (!shouldRecover) + { + AppLogger.Warn( + $"WebView2 renderer unresponsive on '{_screenDeviceName}' " + + $"({_unresponsiveTracker.ConsecutiveReports}/3); waiting for runtime recovery."); + return; + } + recoveryAction = WebViewProcessRecoveryAction.RecreateWebViewControl; + } + if (recoveryAction == WebViewProcessRecoveryAction.None) + { + AppLogger.Warn( + $"WebView2 process event on '{_screenDeviceName}' ({failureKind}); runtime recovery is left intact."); + return; + } + + if (_processRecoveryPending) + { + return; + } + + _processRecoveryPending = true; Dispatcher.BeginInvoke(new Action(() => { - if (_isClosing) return; - if (_coreWebView != null && _processFailedHandler != null) + try + { + if (_isClosing || !ReferenceEquals(failedCoreWebView, _coreWebView)) + { + return; + } + + AppLogger.Warn( + $"WebView2 process failed on '{_screenDeviceName}' ({failureKind}); recovering renderer."); + if (recoveryAction == WebViewProcessRecoveryAction.RecreateWebViewControl) + { + RecreateWebViewControl(); + } + else + { + NavigateCurrentRenderer(failedCoreWebView); + } + } + catch (Exception ex) when (IsExpectedWebViewShutdownException(ex)) { - try { _coreWebView.ProcessFailed -= _processFailedHandler; } catch { /* ignore: event unsubscribe is best-effort */ } + // Process-failure recovery races with shutdown and must never escape the UI dispatcher. + if (!_isClosing) + { + AppLogger.Warn( + $"WebView2 recovery was interrupted on '{_screenDeviceName}': {ex.Message}"); + } + } + catch (Exception ex) + { + AppLogger.Error( + $"WebView2 recovery failed on '{_screenDeviceName}'.", + ex); + } + finally + { + _processRecoveryPending = false; } - _processFailedHandler = null; - _coreWebView = null; - _ = InitWebView(); })); } + private void RecreateWebViewControl() + { + StopRendererReadyTimeout(); + // The browser process is already disconnected; Dispose owns native event cleanup. + ClearCoreWebViewEventState(); + _coreWebView = null; + + Microsoft.Web.WebView2.Wpf.WebView2 oldWebView = webView; + webViewHost.Children.Remove(oldWebView); + UnregisterName("webView"); + oldWebView.Dispose(); + + var replacementWebView = new Microsoft.Web.WebView2.Wpf.WebView2 + { + Name = "webView", + DefaultBackgroundColor = System.Drawing.Color.Transparent + }; + + RegisterName("webView", replacementWebView); + webView = replacementWebView; + webViewHost.Children.Add(replacementWebView); + _ = InitWebView(); + } + + private void DetachCoreWebViewEvents() + { + CoreWebView2? coreWebView = _coreWebView; + if (coreWebView != null) + { + if (_navigationCompletedHandler != null) + { + try + { + coreWebView.NavigationCompleted -= _navigationCompletedHandler; + } + catch (Exception ex) when (IsExpectedWebViewShutdownException(ex)) + { + } + } + + if (_navigationStartingHandler != null) + { + try + { + coreWebView.NavigationStarting -= _navigationStartingHandler; + } + catch (Exception ex) when (IsExpectedWebViewShutdownException(ex)) + { + } + } + + if (_processFailedHandler != null) + { + try + { + coreWebView.ProcessFailed -= _processFailedHandler; + } + catch (Exception ex) when (IsExpectedWebViewShutdownException(ex)) + { + } + } + + if (_webMessageReceivedHandler != null) + { + try + { + coreWebView.WebMessageReceived -= _webMessageReceivedHandler; + } + catch (Exception ex) when (IsExpectedWebViewShutdownException(ex)) + { + } + } + } + + ClearCoreWebViewEventState(); + } + + private void ClearCoreWebViewEventState() + { + _navigationStartingHandler = null; + _navigationCompletedHandler = null; + _processFailedHandler = null; + _webMessageReceivedHandler = null; + _currentNavigationId = null; + _rendererGeneration = null; + _unresponsiveTracker.Reset(); + } + private static bool IsCursorVisible() { CURSORINFO pci = new CURSORINFO(); @@ -599,6 +1088,7 @@ public void EmitDown(int x, int y) public void EmitMove(int x, int y, bool touchLike) { + if (_usingLegacyRenderer && !ShouldDispatchLegacyMove()) return; if (!TryConvertScreenToOverlayPoint(x, y, out System.Windows.Point clientPoint)) return; string inputMode = touchLike ? InputModeTouch : InputModeMouse; string px = FormatCoordinate(clientPoint.X); @@ -606,12 +1096,39 @@ public void EmitMove(int x, int y, bool touchLike) ExecuteWithInputContext(inputMode, $"if(window.externalMove) window.externalMove({px}, {py});"); } + private bool ShouldDispatchLegacyMove() + { + // 旧渲染器没有输入采样 API,仅在回退路径保留等价的宿主限频。 + if (_inputSamplingRate == 0) + { + return true; + } + + long currentTicks = DateTime.UtcNow.Ticks; + long intervalTicks = TimeSpan.FromSeconds(1.0 / _inputSamplingRate).Ticks; + if (currentTicks - _lastLegacyMoveTicks < intervalTicks) + { + return false; + } + + _lastLegacyMoveTicks = currentTicks; + return true; + } + public void EmitUp(bool touchLike) { string inputMode = touchLike ? InputModeTouch : InputModeMouse; ExecuteWithInputContext(inputMode, "if(window.externalUp) window.externalUp();"); } + public void EmitCancel() + { + ExecuteScript( + "if(window.externalCancel){window.externalCancel();}" + + "else if(window.spark&&window.spark.clearEffects){window.spark.clearEffects();}" + + "else if(window.externalUp){window.externalUp();}"); + } + private void UpdateOverlayBounds() { Rectangle bounds = GetScreenBounds(); @@ -672,6 +1189,7 @@ private bool TryConvertScreenToOverlayPoint(int screenX, int screenY, out System protected override void OnClosing(System.ComponentModel.CancelEventArgs e) { _isClosing = true; + StopRendererReadyTimeout(); base.OnClosing(e); } @@ -685,32 +1203,8 @@ protected override void OnClosed(EventArgs e) _topmostTimer = null; } - if (_coreWebView != null) - { - if (_navigationCompletedHandler != null) - { - try - { - _coreWebView.NavigationCompleted -= _navigationCompletedHandler; - } - catch (Exception ex) when (IsExpectedWebViewShutdownException(ex)) - { - } - _navigationCompletedHandler = null; - } - - if (_processFailedHandler != null) - { - try - { - _coreWebView.ProcessFailed -= _processFailedHandler; - } - catch (Exception ex) when (IsExpectedWebViewShutdownException(ex)) - { - } - _processFailedHandler = null; - } - } + StopRendererReadyTimeout(); + DetachCoreWebViewEvents(); _coreWebView = null; if (_winEventHook != IntPtr.Zero) diff --git a/src/OverlayManager.cs b/src/OverlayManager.cs index d6f20a3..98871ce 100644 --- a/src/OverlayManager.cs +++ b/src/OverlayManager.cs @@ -82,9 +82,8 @@ private struct MONITORINFO private readonly Dictionary _overlays = new(StringComparer.OrdinalIgnoreCase); private IKeyboardMouseEvents? _globalHook; private MainWindow? _activePointerOverlay; - private long _lastMoveTicks; + private MainWindow? _lastTrailOverlay; private long _lastClickTicks; - private long _moveIntervalTicks = 250000; private bool _isPrimaryPointerDown; private bool _isTouchLikeInput; private bool _isSuppressedByEnvironment; @@ -124,7 +123,7 @@ public void Start() { RebuildWindows(forceRebuild: true); SetupGlobalHooks(); - UpdateTrailRefreshRate(ConfigManager.TrailRefreshRate); + UpdateInputSamplingRate(ConfigManager.InputSamplingRate); RefreshEnvironmentFilterState(); SystemEvents.DisplaySettingsChanged += HandleDisplaySettingsChanged; SystemEvents.PowerModeChanged += HandlePowerModeChanged; @@ -134,11 +133,12 @@ public void Start() public void UpdateColor(string color) => ForEachOverlay(w => w.UpdateColor(color)); public void UpdateEffectSettings(double scale, double opacity, double trailSpeed, double clickSpeed) => ForEachOverlay(w => w.UpdateEffectSettings(scale, opacity, trailSpeed, clickSpeed)); - public void UpdateTrailRefreshRate(int hz) + public void UpdateInputSamplingRate(int rateHz) { - hz = Math.Clamp(hz, 10, 240); - _moveIntervalTicks = TimeSpan.FromSeconds(1.0 / hz).Ticks; - ForEachOverlay(w => w.UpdateTrailRefreshRate(hz)); + int normalizedRate = ConfigManager.NormalizeInputSamplingRate(rateHz); + // ba-click-fx 使用未缩放的真实输入时间采样。宿主只负责转发, + // 避免 C# 与 WebView2 按同一频率连续丢点而让实际频率再次降低。 + ForEachOverlay(w => w.UpdateInputSamplingRate(normalizedRate)); } public void UpdateTouchMode(bool enabled) => ForEachOverlay(w => w.UpdateTouchMode(enabled)); public void UpdateScreenshotCompatibilityMode(bool enabled) @@ -551,7 +551,19 @@ private void OnMouseDownExt(object? sender, MouseEventExtArgs e) } MainWindow? target = ResolveTargetOverlay(cursorX, cursorY); - if (target == null) return; + if (target == null) + { + return; + } + + if (ConfigManager.EnableAlwaysTrailEffect) + { + SwitchAlwaysTrailOverlay(target); + } + else + { + SwitchAlwaysTrailOverlay(null); + } _isPrimaryPointerDown = true; _isTouchLikeInput = !CursorIsVisible(); @@ -568,15 +580,22 @@ private void OnMouseDownExt(object? sender, MouseEventExtArgs e) private void OnMouseMoveExt(object? sender, MouseEventExtArgs e) { // 拖尾仅在点击特效开启或常驻拖尾开启时渲染 - if (!ConfigManager.IsTrailEffectActive) return; - if (!CanRenderEffects()) return; + if (!ConfigManager.IsTrailEffectActive) + { + SwitchAlwaysTrailOverlay(null); + return; + } + if (!CanRenderEffects()) + { + return; + } bool cursorVisible = CursorIsVisible(); - if (!cursorVisible && !_isPrimaryPointerDown) return; - - long currentTicks = DateTime.Now.Ticks; - if (currentTicks - _lastMoveTicks < _moveIntervalTicks) return; - _lastMoveTicks = currentTicks; + if (!cursorVisible && !_isPrimaryPointerDown) + { + SwitchAlwaysTrailOverlay(null); + return; + } if (!TryGetPhysicalCursorPosition(out int cursorX, out int cursorY)) { @@ -584,7 +603,12 @@ private void OnMouseMoveExt(object? sender, MouseEventExtArgs e) cursorY = e.Y; } - var target = _activePointerOverlay ?? ResolveTargetOverlay(cursorX, cursorY); + MainWindow? target = _activePointerOverlay ?? ResolveTargetOverlay(cursorX, cursorY); + if (!_isPrimaryPointerDown) + { + SwitchAlwaysTrailOverlay( + ConfigManager.EnableAlwaysTrailEffect ? target : null); + } target?.EmitMove(cursorX, cursorY, _isTouchLikeInput || !cursorVisible); } @@ -604,9 +628,7 @@ private void OnMouseUpExt(object? sender, MouseEventExtArgs e) } _activePointerOverlay?.EmitUp(_isTouchLikeInput); - _isPrimaryPointerDown = false; - _isTouchLikeInput = false; - _activePointerOverlay = null; + ResetPrimaryPointerState(); } /// @@ -638,9 +660,16 @@ private bool CanRenderEffects(bool skipSuppressionCheck = false) private void ReleasePointerStateSilent() { - _isPrimaryPointerDown = false; - _isTouchLikeInput = false; - _activePointerOverlay = null; + MainWindow? activePointerOverlay = _activePointerOverlay; + activePointerOverlay?.EmitCancel(); + if (_lastTrailOverlay != null && + !ReferenceEquals(_lastTrailOverlay, activePointerOverlay)) + { + _lastTrailOverlay.EmitCancel(); + } + + ResetPrimaryPointerState(); + _lastTrailOverlay = null; } private void ReleasePointerState() @@ -652,7 +681,26 @@ private void ReleasePointerState() } _activePointerOverlay?.EmitUp(_isTouchLikeInput); - ReleasePointerStateSilent(); + ResetPrimaryPointerState(); + } + + private void ResetPrimaryPointerState() + { + _isPrimaryPointerDown = false; + _isTouchLikeInput = false; + _activePointerOverlay = null; + } + + private void SwitchAlwaysTrailOverlay(MainWindow? target) + { + if (ReferenceEquals(_lastTrailOverlay, target)) + { + return; + } + + // The old renderer must forget its last point before coordinates switch to another screen. + _lastTrailOverlay?.EmitCancel(); + _lastTrailOverlay = target; } private MainWindow? ResolveTargetOverlay(int x, int y) @@ -681,6 +729,14 @@ private void RebuildWindows(bool forceRebuild) .Select(item => item.Screen) .ToDictionary(screen => screen.DeviceName, screen => screen, StringComparer.OrdinalIgnoreCase); + bool topologyChanged = forceRebuild || + _overlays.Keys.Except(targetScreens.Keys, StringComparer.OrdinalIgnoreCase).Any() || + targetScreens.Keys.Except(_overlays.Keys, StringComparer.OrdinalIgnoreCase).Any(); + if (topologyChanged) + { + ReleasePointerStateSilent(); + } + if (forceRebuild) { CloseWindows(); @@ -719,7 +775,25 @@ private void CloseOverlay(string deviceName) return; } - try { overlay.Close(); } catch (Exception ex) { AppLogger.Warn($"Failed to close overlay for '{deviceName}': {ex.Message}"); } + // Cancel before disposal because a closed WebView can no longer clear retained trail state. + overlay.EmitCancel(); + if (ReferenceEquals(_activePointerOverlay, overlay)) + { + ResetPrimaryPointerState(); + } + if (ReferenceEquals(_lastTrailOverlay, overlay)) + { + _lastTrailOverlay = null; + } + + try + { + overlay.Close(); + } + catch (Exception ex) + { + AppLogger.Warn($"Failed to close overlay for '{deviceName}': {ex.Message}"); + } _overlays.Remove(deviceName); } @@ -1014,7 +1088,7 @@ private void RecoverAfterSystemResume() { RebuildWindows(forceRebuild: true); SetupGlobalHooks(); - UpdateTrailRefreshRate(ConfigManager.TrailRefreshRate); + UpdateInputSamplingRate(ConfigManager.InputSamplingRate); RefreshEnvironmentFilterState(); } diff --git a/src/Resources/Strings.en.resx b/src/Resources/Strings.en.resx index b9c56b0..6145705 100644 --- a/src/Resources/Strings.en.resx +++ b/src/Resources/Strings.en.resx @@ -547,10 +547,10 @@ Download now? Default 1.50 × - - Trail refresh rate + + Input sampling rate limit - + Default 40 Hz @@ -584,13 +584,13 @@ Download now? Use same animation speed for trail and click - When off, trail and click speeds are independent of trail refresh rate below. + When off, trail and click speeds are independent of the input sampling rate below. Use curved trail lines - Recommended for 60Hz and above + Recommended at input sampling rates of 60 Hz or higher Global opacity @@ -607,8 +607,11 @@ Download now? Trail animation speed - - Trail refresh rate + + Input sampling rate limit + + + 0 means unlimited; lower rates produce more angular trail paths. WebView2 initialization failed: {0} diff --git a/src/Resources/Strings.ja.resx b/src/Resources/Strings.ja.resx index 99781ac..4418cbb 100644 --- a/src/Resources/Strings.ja.resx +++ b/src/Resources/Strings.ja.resx @@ -547,10 +547,10 @@ 既定 1.50 × - - トレイル更新率 + + 入力サンプリングレート上限 - + 既定 40 Hz @@ -584,13 +584,13 @@ トレイルとクリックで同じアニメ速度を使用 - オフにするとトレイルとクリックの速度を個別に設定できます(下の更新率とは別)。 + オフにするとトレイルとクリックの速度を個別に設定できます(下の入力サンプリングレートとは別)。 曲線トレイルを使用 - 60Hz以上のリフレッシュレートでの使用を推奨します + 入力サンプリングレート 60 Hz 以上での使用を推奨します 全体の不透明度 @@ -607,8 +607,11 @@ トレイルのアニメ速度 - - トレイル更新率 + + 入力サンプリングレート上限 + + + 0 は無制限です。低い値ほど折れ線状のトレイルが強調されます。 WebView2 の初期化に失敗しました: {0} diff --git a/src/Resources/Strings.resx b/src/Resources/Strings.resx index 1d36971..66430a3 100644 --- a/src/Resources/Strings.resx +++ b/src/Resources/Strings.resx @@ -547,10 +547,10 @@ 默认 1.50 × - - 拖尾刷新率 + + 输入采样率上限 - + 默认 40 Hz @@ -584,13 +584,13 @@ 拖尾与点击使用同一动画速度 - 关闭此项后可单独加快或减慢拖尾衰减与移动粒子,而不影响点击波纹与爆发粒子,与下方「拖尾刷新率」不同。 + 关闭此项后可单独加快或减慢拖尾衰减与移动粒子,而不影响点击波纹与爆发粒子,与下方「输入采样率上限」不同。 采用曲线拖尾 - 建议在60Hz及以上刷新率开启 + 输入采样率为 60 Hz 及以上时建议开启 全局不透明度 @@ -607,8 +607,11 @@ 拖尾动画速度 - - 拖尾刷新率 + + 输入采样率上限 + + + 0 表示不限频;较低值会形成更明显的折线拖尾。 WebView2 初始化失败: {0} diff --git a/src/UiLocalizer.cs b/src/UiLocalizer.cs index 5d481c7..15222b2 100644 --- a/src/UiLocalizer.cs +++ b/src/UiLocalizer.cs @@ -98,7 +98,8 @@ public static void ApplyControlPanel(ControlPanelWindow w) w.TxtAnimSpeed.Text = Localization.Get("Visual_AnimSpeed"); w.TxtTrailAnimSpeed.Text = Localization.Get("Visual_TrailAnimSpeed"); w.TxtClickAnimSpeed.Text = Localization.Get("Visual_ClickAnimSpeed"); - w.TxtTrailRefresh.Text = Localization.Get("Visual_TrailRefresh"); + w.TxtInputSamplingRate.Text = Localization.Get("Visual_InputSamplingRate"); + w.TxtInputSamplingRateHint.Text = Localization.Get("Visual_InputSamplingRateHint"); w.TxtEffectColor.Text = Localization.Get("Visual_Color"); w.BtnPickColor.Content = Localization.Get("Visual_ChangeColor"); diff --git a/src/Web/fx-adapter.js b/src/Web/fx-adapter.js new file mode 100644 index 0000000..29c274c --- /dev/null +++ b/src/Web/fx-adapter.js @@ -0,0 +1,767 @@ +(function () +{ + 'use strict'; + + const POINTER_ID = 1; + const DEFAULT_COLOR = '#2dafff'; + const DEFAULT_INPUT_SAMPLING_RATE = 40; + const HOST_GENERATION = + typeof window.__basparkRendererGeneration === 'string' + ? window.__basparkRendererGeneration + : ''; + const DEFAULT_SETTINGS = Object.freeze( + { + scale: 1.5, + opacity: 1, + trailSpeed: 1, + clickSpeed: 1, + }); + const DOM_CONTENT_LOADED_OPTIONS = + { + once: true, + }; + const state = + { + fx: null, + initialized: false, + paused: false, + inputMode: 'mouse', + alwaysTrailEnabled: false, + effectiveAlwaysTrail: false, + activePointerKind: null, + color: DEFAULT_COLOR, + inputSamplingRate: DEFAULT_INPUT_SAMPLING_RATE, + settings: + { + ...DEFAULT_SETTINGS, + }, + lastBoomX: -1, + lastBoomY: -1, + lastBoomTime: 0, + lastMoveX: -1, + lastMoveY: -1, + }; + + function clamp(value, minimum, maximum) + { + return Math.max(minimum, Math.min(maximum, value)); + } + + function errorMessage(error) + { + if (error instanceof Error) + { + return error.message; + } + + return String(error); + } + + function postHostMessage(type, detail = null) + { + const message = + { + source: 'baspark-fx', + generation: HOST_GENERATION, + type, + ...(detail || Object.create(null)), + }; + + try + { + if ( + window.chrome && + window.chrome.webview && + typeof window.chrome.webview.postMessage === 'function' + ) + { + // 宿主统一按 JSON 字符串解析,避免 WebView2 对象封送行为随版本变化。 + window.chrome.webview.postMessage(JSON.stringify(message)); + } + } + catch (error) + { + console.error('[BASpark FX] 无法向宿主发送消息:', error); + } + } + + function reportError(phase, error) + { + const message = errorMessage(error); + + console.error(`[BASpark FX] ${phase}:`, error); + postHostMessage( + 'error', + { + phase, + message, + }); + } + + function invokeFx(phase, action) + { + try + { + return action(); + } + catch (error) + { + reportError(phase, error); + return false; + } + } + + function resetInputCache() + { + state.activePointerKind = null; + state.lastBoomX = -1; + state.lastBoomY = -1; + state.lastBoomTime = 0; + state.lastMoveX = -1; + state.lastMoveY = -1; + } + + function pointerType() + { + return state.inputMode === 'touch' ? 'touch' : 'mouse'; + } + + function toCanvasPoint(percentX, percentY) + { + if (!state.fx) + { + return null; + } + + const normalizedX = Number(percentX); + const normalizedY = Number(percentY); + + if (!Number.isFinite(normalizedX) || !Number.isFinite(normalizedY)) + { + return null; + } + + // C# 传入窗口内归一化坐标;公开 API 要求 Canvas 局部 CSS 像素。 + return ( + { + x: clamp(normalizedX, 0, 1) * state.fx.width, + y: clamp(normalizedY, 0, 1) * state.fx.height, + pointerId: POINTER_ID, + pointerType: pointerType(), + }); + } + + function cancelPointerImmediately() + { + const accepted = state.fx.pointerCancel(POINTER_ID); + + // 宿主取消表示输入所有权切换;清除全部拖尾,避免上一所有者的残留。 + state.fx.clearTrail(); + state.activePointerKind = null; + return accepted; + } + + function cancelActivePointer() + { + if (!state.fx || state.activePointerKind === null) + { + return false; + } + + return cancelPointerImmediately(); + } + + function applyInputContext() + { + if (!state.fx) + { + return; + } + + state.fx.updateConfig( + { + trailAlways: state.effectiveAlwaysTrail, + }); + } + + function applyColor() + { + if (!state.fx) + { + return; + } + + state.fx.setThemeColor(state.color); + } + + function applyEffectSettings() + { + if (!state.fx) + { + return; + } + + state.fx.updateConfig( + { + // 旧引擎以 1.5 为默认尺寸,新引擎以 1 为默认尺寸。 + scale: Math.max(0.01, state.settings.scale / 1.5), + opacity: state.settings.opacity, + trailTimeScale: state.settings.trailSpeed, + clickTimeScale: state.settings.clickSpeed, + }); + } + + function parseRgbColor(rgbString) + { + const channels = String(rgbString).split(',').map((channel) => + { + return Number(channel.trim()); + }); + + if ( + channels.length !== 3 || + channels.some((channel) => !Number.isFinite(channel)) + ) + { + return null; + } + + return `#${channels.map((channel) => + { + return Math.round(clamp(channel, 0, 255)) + .toString(16) + .padStart(2, '0'); + }).join('')}`; + } + + function normalizeSpeed(value, fallback) + { + const numeric = Number(value); + + if (!Number.isFinite(numeric)) + { + return fallback; + } + + return clamp(numeric, 0.2, 3); + } + + function parseInputSamplingRate(value) + { + if (typeof value !== 'number') + { + return null; + } + + const numeric = value; + + if ( + numeric !== 0 && + ( + !Number.isFinite(numeric) || + numeric < 1 || + numeric > 1000 + ) + ) + { + return null; + } + + return numeric; + } + + window.externalBoom = function (percentX, percentY) + { + if (state.paused || !state.fx) + { + return false; + } + + const numericX = Number(percentX); + const numericY = Number(percentY); + const now = Date.now(); + + if ( + numericX === state.lastBoomX && + numericY === state.lastBoomY && + now - state.lastBoomTime < 25 + ) + { + return false; + } + + const point = toCanvasPoint(numericX, numericY); + + if (!point) + { + return false; + } + + state.lastBoomX = numericX; + state.lastBoomY = numericY; + state.lastBoomTime = now; + + return invokeFx('externalBoom', function () + { + // 丢失抬起事件时先恢复指针状态,避免后续点击被单指针上限永久拒绝。 + cancelActivePointer(); + const accepted = state.fx.pointerDown(point); + + if (accepted) + { + state.activePointerKind = 'press'; + } + + return accepted; + }); + }; + + window.externalMove = function (percentX, percentY) + { + if (state.paused || !state.fx) + { + return false; + } + + const numericX = Number(percentX); + const numericY = Number(percentY); + + if ( + numericX === state.lastMoveX && + numericY === state.lastMoveY + ) + { + return false; + } + + const point = toCanvasPoint(numericX, numericY); + + if (!point) + { + return false; + } + + state.lastMoveX = numericX; + state.lastMoveY = numericY; + + return invokeFx('externalMove', function () + { + const accepted = state.fx.pointerMove(point); + + if ( + accepted && + state.activePointerKind === null && + state.effectiveAlwaysTrail + ) + { + state.activePointerKind = 'hover'; + } + + return accepted; + }); + }; + + window.externalUp = function () + { + if (state.paused || !state.fx) + { + return false; + } + + return invokeFx('externalUp', function () + { + const accepted = state.fx.pointerUp(POINTER_ID); + + if (accepted) + { + state.activePointerKind = null; + } + + return accepted; + }); + }; + + window.externalCancel = function () + { + if (!state.fx) + { + resetInputCache(); + return false; + } + + return invokeFx('externalCancel', function () + { + const accepted = cancelPointerImmediately(); + + resetInputCache(); + return accepted; + }); + }; + + window.setRenderingPaused = function (paused) + { + state.paused = Boolean(paused); + + if (!state.fx) + { + return; + } + + invokeFx('setRenderingPaused', function () + { + if (state.paused) + { + resetInputCache(); + state.fx.setPaused( + true, + { + clear: true, + }); + return true; + } + + state.fx.setPaused(false); + return true; + }); + }; + + window.setInputContext = function (mode, alwaysTrailEnabled) + { + const nextMode = mode === 'touch' ? 'touch' : 'mouse'; + const nextAlwaysTrailEnabled = Boolean(alwaysTrailEnabled); + const nextEffectiveAlwaysTrail = + nextMode === 'mouse' && nextAlwaysTrailEnabled; + + if ( + nextMode !== state.inputMode || + ( + !nextEffectiveAlwaysTrail && + state.activePointerKind === 'hover' + ) + ) + { + invokeFx('setInputContext.cancel', function () + { + return cancelActivePointer(); + }); + } + + state.inputMode = nextMode; + state.alwaysTrailEnabled = nextAlwaysTrailEnabled; + state.effectiveAlwaysTrail = nextEffectiveAlwaysTrail; + + invokeFx('setInputContext', function () + { + applyInputContext(); + return true; + }); + }; + + window.updateColor = function (rgbString) + { + const color = parseRgbColor(rgbString); + + if (!color) + { + // 配置损坏不代表渲染器失效,保留当前颜色即可继续运行。 + console.warn('[BASpark FX] 忽略非法 RGB 颜色:', rgbString); + return false; + } + + state.color = color; + + return invokeFx('updateColor', function () + { + applyColor(); + return true; + }); + }; + + window.updateInputSamplingRate = function (rateHz) + { + const rate = parseInputSamplingRate(rateHz); + + if (rate === null) + { + console.warn('[BASpark FX] 忽略非法输入采样率:', rateHz); + return false; + } + + state.inputSamplingRate = rate; + + if (!state.fx) + { + return true; + } + + return invokeFx('updateInputSamplingRate', function () + { + return state.fx.setInputSamplingRate(rate); + }); + }; + + window.updateEffectSettings = function ( + scale, + opacity, + trailSpeed, + clickSpeed + ) + { + const numericScale = Number(scale); + const numericOpacity = Number(opacity); + const safeTrailSpeed = normalizeSpeed( + trailSpeed, + DEFAULT_SETTINGS.trailSpeed, + ); + + state.settings = + { + scale: Number.isFinite(numericScale) && numericScale > 0 + ? numericScale + : DEFAULT_SETTINGS.scale, + opacity: Number.isFinite(numericOpacity) + ? clamp(numericOpacity, 0.1, 1) + : DEFAULT_SETTINGS.opacity, + trailSpeed: safeTrailSpeed, + clickSpeed: normalizeSpeed(clickSpeed, safeTrailSpeed), + }; + + return invokeFx('updateEffectSettings', function () + { + applyEffectSettings(); + return true; + }); + }; + + function readBackendState(detail = Object.create(null)) + { + const config = state.fx.getConfig(); + const requestedEffectBackend = + detail.requestedEffectBackend || config.effectBackend; + const resolvedEffectBackend = + detail.resolvedEffectBackend || config.resolvedEffectBackend; + const requestedBloomBackend = + detail.requestedBloomBackend || config.bloomBackend; + const resolvedBloomBackend = + detail.resolvedBloomBackend || config.resolvedBloomBackend; + const requestedHostCompositing = + detail.requestedHostCompositing || + config.hostCompositing || + 'unknown'; + const resolvedHostCompositing = + detail.resolvedHostCompositing || + config.resolvedHostCompositing || + config.hostCompositing || + 'unknown'; + const hostCompositingSurface = + detail.hostCompositingSurface || + config.hostCompositingSurface || + 'unknown'; + const compositingWarning = + detail.compositingWarning ?? config.compositingWarning ?? null; + + return ( + { + backend: resolvedEffectBackend === 'webgl2' + ? resolvedEffectBackend + : resolvedBloomBackend, + requestedEffectBackend, + resolvedEffectBackend, + requestedBloomBackend, + resolvedBloomBackend, + requestedHostCompositing, + resolvedHostCompositing, + hostCompositingSurface, + compositingWarning, + }); + } + + function handleBackendChange(event) + { + const backendState = readBackendState( + event.detail || Object.create(null), + ); + + postHostMessage( + 'backend', + backendState, + ); + + if ( + backendState.resolvedEffectBackend !== 'webgl2' && + backendState.resolvedBloomBackend === 'software' + ) + { + // 全屏 Float32 软件 Bloom 对桌面覆盖层代价过高,GPU 不可用时改用原生辉光。 + state.fx.updateConfig( + { + bloomBackend: 'native', + }); + } + } + + function initialize() + { + if (state.initialized) + { + return; + } + + state.initialized = true; + + try + { + if ( + !window.BAClickFX || + typeof window.BAClickFX.BAClickFX !== 'function' + ) + { + throw new Error('ba-click-fx IIFE 未在适配器之前注入'); + } + + state.fx = new window.BAClickFX.BAClickFX( + { + inputSource: 'manual', + // WebView2 无法读取窗口后的桌面背景;使用 source-over, + // 再以浅色背景补偿和 Alpha 上限提高未知背景上的可见性。 + effectBackend: 'webgl2', + bloomBackend: 'webgl2', + inputSamplingRate: state.inputSamplingRate, + outputCompositing: 'browser-overlay', + overlayAlphaPolicy: 'visual-max', + overlayColorCompensation: 'bright-core', + overlayAlphaLimit: 0.85, + hostCompositing: 'source-over', + hostCompositingSurface: 'transparent-window', + // 公共库为兼容旧像素默认 hue-only;BASpark 的取色器 + // 明确使用上游推荐的相对 OKLCH 完整颜色映射。 + themeColorMode: 'relative-oklch', + isolatedCompositing: false, + lightBackgroundContrastAlpha: 0, + maxDpr: 2, + }); + + const bloomBackendEventName = + window.BAClickFX.BLOOM_BACKEND_CHANGE_EVENT || + 'baclickfxbackendchange'; + const effectBackendEventName = + window.BAClickFX.EFFECT_BACKEND_CHANGE_EVENT || + 'baclickfxeffectbackendchange'; + const hostCompositingEventName = + window.BAClickFX.HOST_COMPOSITING_CHANGE_EVENT || + 'baclickfxhostcompositingchange'; + + state.fx.canvas.addEventListener( + bloomBackendEventName, + handleBackendChange, + ); + state.fx.canvas.addEventListener( + effectBackendEventName, + handleBackendChange, + ); + state.fx.canvas.addEventListener( + hostCompositingEventName, + handleBackendChange, + ); + + applyInputContext(); + applyColor(); + applyEffectSettings(); + + if (state.paused) + { + state.fx.setPaused( + true, + { + clear: true, + }); + } + + postHostMessage( + 'ready', + readBackendState(), + ); + } + catch (error) + { + reportError('initialize', error); + } + } + + function installCompatibilityShims() + { + if (typeof Array.prototype.at !== 'function') + { + Object.defineProperty( + Array.prototype, + 'at', + { + configurable: true, + writable: true, + value: function (index) + { + const length = this.length >>> 0; + const integer = Math.trunc(Number(index) || 0); + const offset = integer < 0 ? length + integer : integer; + + if (offset < 0 || offset >= length) + { + return undefined; + } + + return this[offset]; + }, + }); + } + + if (typeof window.structuredClone !== 'function') + { + // 上游只克隆由数字、布尔值、数组和普通对象组成的配置快照。 + window.structuredClone = function (value) + { + return JSON.parse(JSON.stringify(value)); + }; + } + } + + window.addEventListener('error', function (event) + { + reportError('window.error', event.error || event.message); + }); + + window.addEventListener('unhandledrejection', function (event) + { + reportError('unhandledrejection', event.reason); + }); + + window.addEventListener('beforeunload', function () + { + if (!state.fx) + { + return; + } + + invokeFx('beforeunload', function () + { + state.fx.destroy(); + state.fx = null; + resetInputCache(); + return true; + }); + }); + + installCompatibilityShims(); + + if (document.readyState === 'loading') + { + document.addEventListener( + 'DOMContentLoaded', + initialize, + DOM_CONTENT_LOADED_OPTIONS, + ); + } + else + { + initialize(); + } +})(); diff --git a/src/Web/index.html b/src/Web/index.html index 74b1878..478b3e4 100644 --- a/src/Web/index.html +++ b/src/Web/index.html @@ -3,821 +3,24 @@ + - - + + - \ No newline at end of file + + diff --git a/src/Web/index.legacy.html b/src/Web/index.legacy.html new file mode 100644 index 0000000..80951b4 --- /dev/null +++ b/src/Web/index.legacy.html @@ -0,0 +1,793 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/Web/vendor/ba-click-fx.iife.js b/src/Web/vendor/ba-click-fx.iife.js new file mode 100644 index 0000000..d845bc5 --- /dev/null +++ b/src/Web/vendor/ba-click-fx.iife.js @@ -0,0 +1,1534 @@ +var BAClickFX=(function(e){Object.defineProperties(e,{__esModule:{value:!0},[Symbol.toStringTag]:{value:`Module`}});var t=Object.freeze([`coverage`,`visual-max`]),n=Object.freeze([`none`,`bright-core`]),r=.35;function i(e){return Math.max(0,Math.min(1,Number(e)||0))}function a(e,t,n){let r=i((n-e)/(t-e));return r*r*(3-2*r)}function o(e){return t.includes(e)}function s(e,t=`coverage`){return o(e)?e:t}function c(e){return n.includes(e)}function l(e,t=`none`){return c(e)?e:t}function u(e,t,n=1){let o=i(t);if(o<=1e-6)return[0,0,0];let s=[0,1,2].map(t=>Math.min(o,Math.max(0,Number(e?.[t])||0))),c=Math.max(...s);if(c<=1e-6)return s;let l=Math.max(i(n),1e-6),u=i(o/l),d=c/l,f=r*(a(.25,.75,d/Math.max(u,1e-6))*a(.03125,.25,d));return s.map(e=>e+(c-e)*f)}function d(e,t=`none`,n=1){if(t!==`bright-core`||!e?.data)return e;let r=e.data;for(let e=0;e+3=1?0:Math.max(0,Math.min(1,(r-i)/Math.max(1-i,1e-6))):Math.max(0,r-i):n[e+3]/255;let l=Math.min(Math.max(i,c),s);if(l<=1e-5){o[e]=0,o[e+1]=0,o[e+2]=0,o[e+3]=0;continue}let u=[o[e]/255*r,o[e+1]/255*r,o[e+2]/255*r],d=Math.max(...u),f=Math.min(1,l/Math.max(d,1e-6));o[e]=Math.round(u[0]*f/l*255),o[e+1]=Math.round(u[1]*f/l*255),o[e+2]=Math.round(u[2]*f/l*255),o[e+3]=Math.round(l*255)}return e}var p=Object.freeze({peak:3,brightness:1,colorPreservation:0,whiteCore:.6,whiteStart:1,whiteEnd:5}),m=1080,h=m/2,g=h*.3078824,_=1.0636684,v=`webgl2`,y=new Set([`canvas2d`,`webgl2`,`webgpu`,`auto`]),b=`webgl2`,x=new Set([`auto`,`software`,`webgl2`,`native`]),S=new Set([`dom`,`manual`]),C=`scene`,w=new Set([`scene`,`browser-overlay`]),T=250/255,E=`source-over`,D=new Set([`source-over`,`screen`,`plus-lighter`]),O=`dom-backdrop`,k=new Set([`dom-backdrop`,`transparent-window`,`native`]),A=`coverage`,j=`none`,M=2,ee=4,N=32,te=0,ne=15.99,re=16,ie=.01,ae=`#4ca7ff`,oe=`hue-only`,se=new Set([`hue-only`,`relative-oklch`]),ce=1,P=Object.freeze({referenceHeight:m,rootDurationMs:1e3,hit:{enabled:!1,lifetimeMs:80,radius:24,colorKeys:[[0,[255,255,255]],[.5,[180,220,255]],[1,[61,100,255]]],alphaKeys:[[0,1],[.4,.8],[1,0]]},flare:{enabled:!1,lifetimeMs:150,radius:36,rayCount:6,colorKeys:[[0,[255,255,255]],[.3,[180,220,255]],[1,[61,100,255]]],alphaKeys:[[0,.7],[.5,.3],[1,0]]},disk:{lifetimeMs:200,radius:.12*2*.5*h,colorKeys:[[0,[255,255,255]],[.1205921,[.24056602*255,.39061815*255,255]]],alphaKeys:[[0,1],[.1088273,1],[1,0]],sizeKeys:[[0,.32583582,2.4004734,2.4004734],[.21392822,.7159773,.9115745,.9115745],[1,1,0,0]],textureRadialEnergyKeys:[[0,1],[.84,1],[.88,1],[.885,.127021063],[.89,.029392051],[.895,.010453372],[.9,.003970262],[.905,231299e-9],[.91,26848e-9],[.915,2303e-9],[.92,0],[1,0]]},rings:{count:2,lifetimeMs:600,radiusMin:.12*h*_,radiusMax:.14*h*_,bandToOuterRadius:.0598573766034603,widthStart:1,widthEnd:1,angularVelocityMultiplier:11.170107,angularVelocityMinKeys:[[.14903903,1],[1,.45561826]],angularVelocityMaxKeys:[[.15865384,.79881656],[1,-.06509134]],rotationDirection:-1,hdrIntensity:5.992157,colorKeys:[[.1117723,[255,255,255]],[.5000076,[.2971698*255,.6532865*255,255]],[1,[.2971698*255,.6532865*255,255]]],sizeKeys:[[.007209778,.42050898,2.4004734,2.4004734],[.21392822,.7159773,.9115745,.9115745],[1,1,0,0]],dissolveKeys:[[0,1,0,0],[.2,0,0,2.4249368],[1,1,.27735636,.27735636]],arcSamples:96,radialSamples:8,textureUvMin:.0005000000237487257,textureUvMax:.999500036239624,dissolveDirection:1},shards:{hdrIntensity:5.992157,roundness:0,startColor:[.5377358,.5377358,.5377358],clickCount:4,clickLifetimeMinMs:600,clickLifetimeMaxMs:700,clickRadius:.3*g,clickSpeedMin:.3*g,clickSpeedMax:.4*g,trailLifetimeMinMs:200,trailLifetimeMaxMs:400,trailRadius:.15*g,trailSpeedMin:.2*g,trailSpeedMax:.3*g,sizeMin:.1*g,sizeMax:.2*g,sizeKeys:[[0,0,0,0],[.15445095,1,0,0],[1,0,-2.1621501,-2.1621501]],textureFrames:[[[-.48046875,-.36328125],[.48046875,-.36328125],[0,.45703125]],[[0,-.45703125],[.48046875,.36328125],[-.48046875,.36328125]]],colorKeys:[[0,[255,255,255]],[.1823606,[255,255,255]],[.282353,[.3726415*255,.7731873*255,255]],[.4617685,[.37254903*255,.7725491*255,255]],[.6617685,[.3529412*255,.7294118*255,.9450981*255]],[.8264744,[.37254903*255,.7725491*255,255]],[1,[.37254903*255,.7725491*255,255]]],alphaKeys:[[0,1],[.2882429,1],[.3647059,0],[.4705882,1],[.5735256,0],[.6676432,1],[.7558862,0],[.8529488,1],[1,1]],trailSpacing:h/5,maxCount:50},trail:{lifetimeMs:300,geometryWidth:.005*h,width:.005*h,minVertexDistance:.01*h,numCornerVertices:4,numCapVertices:1,outerGlowWidth:9,trailOpacity:1,gradient:[[0,[0,0,0]],[.5794156,[0,24.191827,72]],[.97941558,[0,99.598249,255]],[1,[0,99.598249,255]]],coverageLongitudinalKeys:[[0,0],[.248532,0],[.97941558,1],[1,1]],textureLongitudinalKeys:[[0,0],[.248532,0],[.311155,.002428251],[.373777,.021219072],[.436399,.068478133],[.499022,.144128269],[.561644,.462077113],[.624266,.672443723],[.686888,.791298368],[.749511,.930109875],[.812133,1],[1,1]],textureTransverseProfileKeys:[[0,[0,0,0,0,0,0,0,0,0]],[.248532,[0,0,0,0,0,0,0,0,0]],[.311155,[1,1,.625,0,0,0,0,0,0]],[.373777,[1,1,.7167,.3534,.1144,0,0,0,0]],[.436399,[1,1,.7956,.5387,.283,.0757,0,0,0]],[.499022,[1,.9605,.8657,.6613,.4191,.1786,.0279,0,0]],[.561644,[1,1,.9277,.4599,.2906,.1564,.0591,.0013,.0026]],[.624266,[1,.9687,.9534,.8881,.6621,.2342,.1006,.0149,.0018]],[.686888,[1,.9804,.9515,.8952,.8188,.5912,.1858,.0382,.0019]],[.749511,[1,1,.9457,.9018,.8341,.723,.4968,.0699,.0016]],[.812133,[1,1,.9734,.9647,.9047,.7991,.6724,.1896,.0015]],[.874755,[1,1,1,1,.9734,.9301,.7991,.4022,.0015]],[.937378,[1,1,1,1,1,1,.9301,.5,.0015]],[1,[1,1,1,1,1,1,.9867,.591,.0015]]]},bloom:{threshold:1,softKnee:0,clamp:65472,intensity:1.7,diffusion:7,resolutionScale:.5,emissionRange:23.968628,diskEmission:2,trailEmission:23.968628,trailCoverageScale:1,trailEmissionAlpha:1,clickEmissionScale:1,ringEmissionAlpha:1,diskEmissionAlpha:1,ringBlur:80,ringAlpha:.35,diskBlur:65,diskAlpha:.65,trailAlpha:.18}}),le=2,ue=Object.freeze({hit:10,flare:20,disk:30,rings:40,shards:50,trail:60,bloom:70}),de=Object.freeze({"hit.enabled":10,"hit.lifetimeMs":20,"hit.radius":30,"flare.enabled":40,"flare.lifetimeMs":50,"flare.radius":60,"flare.rayCount":70,"disk.lifetimeMs":80,"disk.radius":90,"rings.count":100,"rings.lifetimeMs":110,"rings.radiusMin":120,"rings.radiusMax":130,"rings.bandToOuterRadius":140,"rings.widthStart":150,"rings.widthEnd":160,"rings.angularVelocityMultiplier":170,"rings.rotationDirection":180,"rings.hdrIntensity":190,"rings.arcSamples":200,"rings.radialSamples":210,"rings.dissolveDirection":220,"shards.hdrIntensity":230,"shards.clickCount":240,"shards.clickLifetimeMinMs":250,"shards.clickLifetimeMaxMs":260,"shards.clickRadius":270,"shards.clickSpeedMin":280,"shards.clickSpeedMax":290,"shards.roundness":295,"shards.trailLifetimeMinMs":300,"shards.trailLifetimeMaxMs":310,"shards.trailRadius":320,"shards.trailSpeedMin":330,"shards.trailSpeedMax":340,"shards.sizeMin":350,"shards.sizeMax":360,"shards.trailSpacing":370,"shards.maxCount":380,"trail.lifetimeMs":390,"trail.geometryWidth":400,"trail.width":410,"trail.minVertexDistance":420,"trail.numCornerVertices":430,"trail.numCapVertices":440,"trail.outerGlowWidth":450,"trail.trailOpacity":460,"bloom.threshold":470,"bloom.softKnee":480,"bloom.clamp":490,"bloom.intensity":500,"bloom.diffusion":510,"bloom.resolutionScale":520,"bloom.emissionRange":530,"bloom.diskEmission":540,"bloom.trailEmission":550,"bloom.trailCoverageScale":560,"bloom.trailEmissionAlpha":570,"bloom.clickEmissionScale":580,"bloom.ringEmissionAlpha":590,"bloom.diskEmissionAlpha":600,"bloom.ringBlur":610,"bloom.ringAlpha":620,"bloom.diskBlur":630,"bloom.diskAlpha":640,"bloom.trailAlpha":650}),fe=Object.freeze({"trail.width":4,"bloom.trailAlpha":0}),pe=Object.freeze({"hit.lifetimeMs":[20,200,1],"hit.radius":[10,60,.01],"flare.lifetimeMs":[50,300,1],"flare.radius":[10,80,.01],"flare.rayCount":[3,12,1],"disk.lifetimeMs":[50,500,1],"disk.radius":[20,120,.01],"rings.count":[0,6,1],"rings.lifetimeMs":[50,2e3,1],"rings.radiusMin":[20,120,.01],"rings.radiusMax":[20,120,.01],"rings.bandToOuterRadius":[.01,.2,1e-4],"rings.widthStart":[.25,2,.01],"rings.widthEnd":[.25,2,.01],"rings.angularVelocityMultiplier":[1,30,.01],"rings.rotationDirection":[-1,1,2],"rings.hdrIntensity":[0,8,.01],"rings.arcSamples":[24,192,1],"rings.radialSamples":[2,16,1],"rings.dissolveDirection":[-1,1,2],"shards.hdrIntensity":[0,8,.01],"shards.clickCount":[0,12,1],"shards.clickLifetimeMinMs":[100,1e3,1],"shards.clickLifetimeMaxMs":[100,1e3,1],"shards.clickRadius":[0,200,.01],"shards.clickSpeedMin":[0,200,.01],"shards.clickSpeedMax":[0,200,.01],"shards.roundness":[0,1,.01],"shards.trailLifetimeMinMs":[50,500,1],"shards.trailLifetimeMaxMs":[50,500,1],"shards.trailRadius":[0,100,.01],"shards.trailSpeedMin":[0,150,.01],"shards.trailSpeedMax":[0,150,.01],"shards.sizeMin":[0,100,.01],"shards.sizeMax":[0,100,.01],"shards.trailSpacing":[10,500,.01],"shards.maxCount":[0,500,1],"trail.lifetimeMs":[50,2e3,1],"trail.geometryWidth":[1,8,.01],"trail.width":[1,25,.01],"trail.minVertexDistance":[1,20,.01],"trail.numCornerVertices":[0,12,1],"trail.numCapVertices":[0,6,1],"trail.outerGlowWidth":[1,40,.1],"trail.trailOpacity":[0,1,.01],"bloom.threshold":[0,5,.01],"bloom.softKnee":[0,1,.01],"bloom.clamp":[1,65504,1],"bloom.intensity":[0,2,.01],"bloom.diffusion":[0,10,.01],"bloom.resolutionScale":[.1,.75,.01],"bloom.emissionRange":[1,64,.01],"bloom.diskEmission":[0,8,.01],"bloom.trailEmission":[0,64,.01],"bloom.trailCoverageScale":[0,4,.01],"bloom.trailEmissionAlpha":[0,1,.01],"bloom.clickEmissionScale":[0,4,.01],"bloom.ringEmissionAlpha":[0,1,.01],"bloom.diskEmissionAlpha":[0,1,.01],"bloom.ringBlur":[0,200,.1],"bloom.ringAlpha":[0,1,.01],"bloom.diskBlur":[0,200,.1],"bloom.diskAlpha":[0,1,.01],"bloom.trailAlpha":[0,1,.01]}),me=Object.freeze({"rings.radiusMin":[`rings.radiusMax`],"rings.radiusMax":[`rings.radiusMin`],"rings.widthStart":[`rings.widthEnd`],"rings.widthEnd":[`rings.widthStart`],"shards.clickLifetimeMinMs":[`shards.clickLifetimeMaxMs`],"shards.clickLifetimeMaxMs":[`shards.clickLifetimeMinMs`],"shards.clickSpeedMin":[`shards.clickSpeedMax`],"shards.clickSpeedMax":[`shards.clickSpeedMin`],"shards.trailLifetimeMinMs":[`shards.trailLifetimeMaxMs`],"shards.trailLifetimeMaxMs":[`shards.trailLifetimeMinMs`],"shards.trailSpeedMin":[`shards.trailSpeedMax`],"shards.trailSpeedMax":[`shards.trailSpeedMin`],"shards.sizeMin":[`shards.sizeMax`],"shards.sizeMax":[`shards.sizeMin`]});function he(e){if(typeof e!=`object`||!e||Object.isFrozen(e))return e;for(let t of Object.values(e))he(t);return Object.freeze(e)}function F(e,t,n={}){let r=e.split(`.`),i=P;for(let e of r)i=i[e];return{path:e,type:t,default:i,...n}}function ge(e){let t=e.path.split(`.`)[0],n=pe[e.path],r=Object.hasOwn(fe,e.path)?fe[e.path]:e.default,i={...e,order:de[e.path],group:t,groupOrder:ue[t],labelKey:`baClickFx.params.${e.path}`,groupLabelKey:`baClickFx.paramGroups.${t}`,linkedParams:me[e.path]??[],modeDefaults:{enhanced:e.default,legacy:r}};return n&&(i.display={min:n[0],max:n[1],step:n[2]}),i}var _e=he([F(`hit.enabled`,`boolean`,{unit:`boolean`}),F(`hit.lifetimeMs`,`number`,{min:1,max:1e4,step:1,unit:`ms`}),F(`hit.radius`,`number`,{min:1,max:2e3,step:.01,unit:`px`}),F(`flare.enabled`,`boolean`,{unit:`boolean`}),F(`flare.lifetimeMs`,`number`,{min:1,max:1e4,step:1,unit:`ms`}),F(`flare.radius`,`number`,{min:1,max:2e3,step:.01,unit:`px`}),F(`flare.rayCount`,`number`,{min:1,max:64,step:1,unit:`count`}),F(`disk.lifetimeMs`,`number`,{min:1,max:1e4,step:1,unit:`ms`}),F(`disk.radius`,`number`,{min:1,max:2e3,step:.01,unit:`px`}),F(`rings.count`,`number`,{min:0,max:64,step:1,unit:`count`}),F(`rings.lifetimeMs`,`number`,{min:1,max:1e4,step:1,unit:`ms`}),F(`rings.radiusMin`,`number`,{min:0,max:2e3,step:.01,unit:`px`}),F(`rings.radiusMax`,`number`,{min:0,max:2e3,step:.01,unit:`px`}),F(`rings.bandToOuterRadius`,`number`,{min:0,max:1,step:1e-4,unit:`ratio`}),F(`rings.widthStart`,`number`,{min:0,max:8,step:.01,unit:`multiplier`}),F(`rings.widthEnd`,`number`,{min:0,max:8,step:.01,unit:`multiplier`}),F(`rings.angularVelocityMultiplier`,`number`,{min:0,max:100,step:.01,unit:`multiplier`}),F(`rings.rotationDirection`,`number`,{min:-1,max:1,step:2,unit:`direction`}),F(`rings.hdrIntensity`,`number`,{min:0,max:64,step:.01,unit:`linear-hdr`}),F(`rings.arcSamples`,`number`,{min:3,max:1024,step:1,unit:`samples`}),F(`rings.radialSamples`,`number`,{min:1,max:32,step:1,unit:`samples`}),F(`rings.dissolveDirection`,`number`,{min:-1,max:1,step:2,unit:`direction`}),F(`shards.hdrIntensity`,`number`,{min:0,max:64,step:.01,unit:`linear-hdr`}),F(`shards.clickCount`,`number`,{min:0,max:1e3,step:1,unit:`count`}),F(`shards.clickLifetimeMinMs`,`number`,{min:1,max:1e4,step:1,unit:`ms`}),F(`shards.clickLifetimeMaxMs`,`number`,{min:1,max:1e4,step:1,unit:`ms`}),F(`shards.clickRadius`,`number`,{min:0,max:5e3,step:.01,unit:`px`}),F(`shards.clickSpeedMin`,`number`,{min:0,max:5e3,step:.01,unit:`px-per-second`}),F(`shards.clickSpeedMax`,`number`,{min:0,max:5e3,step:.01,unit:`px-per-second`}),F(`shards.roundness`,`number`,{min:0,max:1,step:.01,unit:`ratio`}),F(`shards.trailLifetimeMinMs`,`number`,{min:1,max:1e4,step:1,unit:`ms`}),F(`shards.trailLifetimeMaxMs`,`number`,{min:1,max:1e4,step:1,unit:`ms`}),F(`shards.trailRadius`,`number`,{min:0,max:5e3,step:.01,unit:`px`}),F(`shards.trailSpeedMin`,`number`,{min:0,max:5e3,step:.01,unit:`px-per-second`}),F(`shards.trailSpeedMax`,`number`,{min:0,max:5e3,step:.01,unit:`px-per-second`}),F(`shards.sizeMin`,`number`,{min:0,max:2e3,step:.01,unit:`px`}),F(`shards.sizeMax`,`number`,{min:0,max:2e3,step:.01,unit:`px`}),F(`shards.trailSpacing`,`number`,{min:1,max:5e3,step:.01,unit:`px`}),F(`shards.maxCount`,`number`,{min:0,max:1e4,step:1,unit:`count`}),F(`trail.lifetimeMs`,`number`,{min:1,max:1e4,step:1,unit:`ms`}),F(`trail.geometryWidth`,`number`,{min:0,max:1e3,step:.01,unit:`px`}),F(`trail.width`,`number`,{min:0,max:1e3,step:.01,unit:`px`}),F(`trail.minVertexDistance`,`number`,{min:0,max:5e3,step:.01,unit:`px`}),F(`trail.numCornerVertices`,`number`,{min:0,max:64,step:1,unit:`count`}),F(`trail.numCapVertices`,`number`,{min:0,max:64,step:1,unit:`count`}),F(`trail.outerGlowWidth`,`number`,{min:0,max:1e3,step:.1,unit:`px`}),F(`trail.trailOpacity`,`number`,{min:0,max:1,step:.01,unit:`ratio`}),F(`bloom.threshold`,`number`,{min:0,max:64,step:.01,unit:`gamma-hdr`}),F(`bloom.softKnee`,`number`,{min:0,max:1,step:.01,unit:`ratio`}),F(`bloom.clamp`,`number`,{min:0,max:65504,step:1,unit:`gamma-hdr`}),F(`bloom.intensity`,`number`,{min:0,max:10,step:.01,unit:`scalar`}),F(`bloom.diffusion`,`number`,{min:0,max:10,step:.01,unit:`scalar`}),F(`bloom.resolutionScale`,`number`,{min:.1,max:.75,step:.01,unit:`ratio`}),F(`bloom.emissionRange`,`number`,{min:1,max:65504,step:.01,unit:`linear-hdr`}),F(`bloom.diskEmission`,`number`,{min:0,max:64,step:.01,unit:`linear-hdr`}),F(`bloom.trailEmission`,`number`,{min:0,max:65504,step:.01,unit:`linear-hdr`}),F(`bloom.trailCoverageScale`,`number`,{min:0,max:8,step:.01,unit:`multiplier`}),F(`bloom.trailEmissionAlpha`,`number`,{min:0,max:1,step:.01,unit:`ratio`}),F(`bloom.clickEmissionScale`,`number`,{min:0,max:4,step:.01,unit:`multiplier`}),F(`bloom.ringEmissionAlpha`,`number`,{min:0,max:1,step:.01,unit:`ratio`}),F(`bloom.diskEmissionAlpha`,`number`,{min:0,max:1,step:.01,unit:`ratio`}),F(`bloom.ringBlur`,`number`,{min:0,max:1e3,step:.1,unit:`px`}),F(`bloom.ringAlpha`,`number`,{min:0,max:1,step:.01,unit:`ratio`}),F(`bloom.diskBlur`,`number`,{min:0,max:1e3,step:.1,unit:`px`}),F(`bloom.diskAlpha`,`number`,{min:0,max:1,step:.01,unit:`ratio`}),F(`bloom.trailAlpha`,`number`,{min:0,max:1,step:.01,unit:`ratio`})].map(ge)),ve=he([{fromVersion:0,toVersion:1,changes:[{kind:`replace`,from:`bloom.scatter`,to:`bloom.diffusion`,source:{type:`number`,min:0},value:P.bloom.diffusion}]},{fromVersion:1,toVersion:2,changes:[]}]),I=Object.freeze({scale:1,opacity:1,themeColor:ae,themeColorMode:oe,clickEnabled:!0,trailEnabled:!0,trailAlways:!1,inputSource:`dom`,inputSamplingRate:0,clickTimeScale:1,trailTimeScale:1,outputCompositing:C,overlayAlphaPolicy:A,overlayColorCompensation:j,overlayAlphaLimit:T,hostCompositing:E,hostCompositingSurface:O,effectBackend:v,webgpuPreferHdr:!0,webgpuHdrPeak:p.peak,webgpuHdrBrightness:p.brightness,webgpuHdrColorPreservation:p.colorPreservation,webgpuHdrWhiteCore:p.whiteCore,webgpuHdrWhiteStart:p.whiteStart,webgpuHdrWhiteEnd:p.whiteEnd,renderingMode:`enhanced`,bloomBackend:b,softwareBloomEnabled:!1,isolatedCompositing:!1,lightBackgroundContrastAlpha:0,maxDpr:2,touchAction:`auto`});function ye(e){return y.has(e)}function be(e,t=v){return ye(e)?e:t}function xe(e){return x.has(e)}function Se(e,t=b){return xe(e)?e:t}function Ce(e){return S.has(e)}function we(e){return e===0||Number.isFinite(e)&&e>=1&&e<=1e3}function Te(e,t=0){return we(e)?e:t}function Ee(e){return w.has(e)}function De(e,t=C){return Ee(e)?e:t}function Oe(e,t=A){return s(e,t)}function ke(e,t=j){return l(e,t)}function Ae(e,t=T){let n=Number.isFinite(t)?Math.max(0,Math.min(1,t)):T;return Number.isFinite(e)?Math.max(0,Math.min(1,e)):n}function je(e){return D.has(e)}function Me(e){return e===`screen`||e===`plus-lighter`}function Ne(e,t=E){return je(e)?e:t}function Pe(e){return k.has(e)}function Fe(e,t=O){return Pe(e)?e:t}function Ie({outputCompositing:e=C,requestedHostCompositing:t=E,hostCompositingSurface:n=O,hasCompositingReference:r=!1}={}){let i=Ne(t),a=Fe(n),o=Me(i);return e!==`browser-overlay`||r||!o?{resolvedHostCompositing:`source-over`,compositingWarning:null}:a===`transparent-window`?{resolvedHostCompositing:`source-over`,compositingWarning:`${i}-requires-visible-backdrop`}:{resolvedHostCompositing:i,compositingWarning:null}}function Le(e){return Number.isFinite(e)&&e>=.01}function Re(e,t=1){return Le(e)?e:t}function ze(e,t=ae){return typeof e!=`string`||!/^#[0-9a-f]{6}$/i.test(e)?t:e.toLowerCase()}function Be(e){return se.has(e)}function Ve(e,t=oe){return Be(e)?e:t}function He(e,t,n,r){let i=Number.isFinite(t)?Math.max(n,Math.min(r,t)):n;return Number.isFinite(e)?Math.max(n,Math.min(r,e)):i}function Ue(e={},t=p){let n=He(e.webgpuHdrPeak,t.webgpuHdrPeak??t.peak,M,ee),r=He(e.webgpuHdrWhiteCore,t.webgpuHdrWhiteCore??t.whiteCore,0,1),i=He(e.webgpuHdrBrightness,t.webgpuHdrBrightness??t.brightness,0,N),a=He(e.webgpuHdrColorPreservation,t.webgpuHdrColorPreservation??t.colorPreservation,0,1),o=He(e.webgpuHdrWhiteStart,t.webgpuHdrWhiteStart??t.whiteStart,te,ne),s=He(e.webgpuHdrWhiteEnd,t.webgpuHdrWhiteEnd??t.whiteEnd,.01,re);return{webgpuHdrPeak:n,webgpuHdrBrightness:i,webgpuHdrColorPreservation:a,webgpuHdrWhiteCore:r,webgpuHdrWhiteStart:o,webgpuHdrWhiteEnd:Math.max(o+ie,s)}}function We(e={}){let t={...e};delete t.unknownBackgroundAppearance;let n=I.bloomBackend;xe(e.bloomBackend)?n=e.bloomBackend:typeof e.softwareBloomEnabled==`boolean`&&(n=e.softwareBloomEnabled?`software`:`native`);let r=Ce(e.inputSource)?e.inputSource:I.inputSource,i=Te(e.inputSamplingRate,I.inputSamplingRate),a=xe(e.bloomBackend)||typeof e.softwareBloomEnabled==`boolean`?`canvas2d`:I.effectBackend,o=be(e.effectBackend,a),s=typeof e.webgpuPreferHdr==`boolean`?e.webgpuPreferHdr:I.webgpuPreferHdr,c=Re(e.clickTimeScale,I.clickTimeScale),l=Re(e.trailTimeScale,I.trailTimeScale),u=De(e.outputCompositing,I.outputCompositing),d=Oe(e.overlayAlphaPolicy,I.overlayAlphaPolicy),f=ke(e.overlayColorCompensation,I.overlayColorCompensation),p=Ae(e.overlayAlphaLimit,I.overlayAlphaLimit),m=Ne(e.hostCompositing,I.hostCompositing),h=Fe(e.hostCompositingSurface,I.hostCompositingSurface),g=ze(e.themeColor,I.themeColor),_=Ve(e.themeColorMode,I.themeColorMode),v=Ue(e,I);return{...I,...t,inputSource:r,inputSamplingRate:i,effectBackend:o,webgpuPreferHdr:s,clickTimeScale:c,trailTimeScale:l,outputCompositing:u,overlayAlphaPolicy:d,overlayColorCompensation:f,overlayAlphaLimit:p,hostCompositing:m,hostCompositingSurface:h,themeColor:g,themeColorMode:_,...v,bloomBackend:n,softwareBloomEnabled:n===`software`,isolatedCompositing:typeof e.isolatedCompositing==`boolean`?e.isolatedCompositing:I.isolatedCompositing}}var Ge=1e-5,Ke=1e-7,qe=28,Je=Math.PI*2;function Ye(e){return Math.max(0,Math.min(1,e))}function Xe(e){return e<=.04045?e/12.92:((e+.055)/1.055)**2.4}function Ze(e){return e<=.0031308?e*12.92:1.055*e**(1/2.4)-.055}function Qe(e){if(typeof e!=`string`||!/^#[0-9a-f]{6}$/i.test(e))throw TypeError(`themeColor 必须是 #rrggbb 格式的 sRGB 颜色`);return[Number.parseInt(e.slice(1,3),16),Number.parseInt(e.slice(3,5),16),Number.parseInt(e.slice(5,7),16)]}function $e(e){if(!Array.isArray(e)||e.length!==3)throw TypeError(`rgb 必须是包含三个通道的数组`);for(let t=0;t<3;t++)if(!Number.isFinite(e[t])||e[t]<0||e[t]>255)throw RangeError(`rgb 通道必须是 0 到 255 之间的有限数值`)}function et(e){let[t,n,r]=e,i=Math.cbrt(.4122214708*t+.5363325363*n+.0514459929*r),a=Math.cbrt(.2119034982*t+.6806995451*n+.1073969566*r),o=Math.cbrt(.0883024619*t+.2817188376*n+.6299787005*r);return[.2104542553*i+.793617785*a-.0040720468*o,1.9779984951*i-2.428592205*a+.4505937099*o,.0259040371*i+.7827717662*a-.808675766*o]}function tt(e){let[t,n,r]=e,i=(t+.3963377774*n+.2158037573*r)**3,a=(t-.1055613458*n-.0638541728*r)**3,o=(t-.0894841775*n-1.291485548*r)**3;return[4.0767416621*i-3.3077115913*a+.2309699292*o,-1.2684380046*i+2.6097574011*a-.3413193965*o,-.0041960863*i-.7034186147*a+1.707614701*o]}function nt(e){let[t,n,r]=et(e.map(e=>Xe(e/255))),i=Math.hypot(n,r);return[t,i,i<=Ge?0:Math.atan2(r,n)]}function rt(e){return e-Math.floor(e/Je)*Je}function it(e,t,n){return tt([e,t*Math.cos(n),t*Math.sin(n)])}function at(e){return e.every(e=>Number.isFinite(e)&&e>=-1e-7&&e<=1.0000001)}function ot(e,t,n){let r=Math.max(0,t),i=it(e,r,n);if(!at(i)){let t=0,a=r;for(let r=0;rYe(Ze(Ye(e)))*255)}var st=nt(Qe(ae));function ct(e=ae){let t=Qe(e),n=e.toLowerCase(),[r,i,a]=nt(t),o=i<=Ge;return Object.freeze({color:n,identity:n===ae,invisible:r<=Ke,coverageScale:Math.max(...t)/255,targetLightness:r,chromaScale:o?0:i/st[1],hueShift:o?0:rt(a-st[2])})}function lt(e,t){return t<=st[0]||e<=st[0]?e*t/st[0]:t+(e-st[0])*(1-t)/(1-st[0])}function ut(e,t){if($e(e),!t||typeof t!=`object`)throw TypeError(`theme 必须由 createRelativeOklchTheme 创建`);if(t.identity)return e;if(t.invisible)return[0,0,0];let[n,r,i]=nt(e);return n<=Ke?[0,0,0]:ot(lt(n,t.targetLightness),r<=Ge?0:r*t.chromaScale,rt(i+t.hueShift))}var dt=new Map(_e.map(e=>[e.path,e]));function ft(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function pt(e){return structuredClone(e)}function mt(e,t,n){let r=t.split(`.`),i=e;for(let e=0;ee.max;return n||r?`out-of-range`:null}return typeof t==`boolean`?null:`invalid-type`}function _t(e,t,n){let r=n,i=e,a=t,o=[];for(;r<2;){let e=ve.find(e=>e.fromVersion===r);if(!e||e.toVersion<=r)return{error:`missing-migration`,path:i,normalized:o};for(let t of e.changes)if(t.kind===`rename`&&i===t.from&&(o.push({path:i,from:i,to:t.to,reason:`renamed`}),i=t.to),t.kind===`replace`&&i===t.from){let e=gt(t.source,a);if(e)return{error:e,path:i,normalized:o};o.push({path:i,from:i,to:t.to,reason:`renamed`}),i=t.to,o.push({path:i,from:a,to:t.value,reason:`defaulted`}),a=t.value}r=e.toVersion}return{error:null,path:i,value:a,normalized:o}}function vt(e,t,n){if(e.type===`boolean`){if(typeof n==`boolean`)return{accepted:!0,normalized:[],value:n};if(typeof n==`number`&&Number.isFinite(n)){let e=!!n;return{accepted:!0,normalized:[{path:t,from:n,to:e,reason:`boolean-coercion`}],value:e}}return{accepted:!1,reason:typeof n==`number`?`non-finite-number`:`invalid-type`}}if(e.type!==`number`||typeof n!=`number`)return{accepted:!1,reason:`invalid-type`};if(!Number.isFinite(n))return{accepted:!1,reason:`non-finite-number`};let r=Math.min(e.max,Math.max(e.min,n));return r===n?{accepted:!0,normalized:[],value:n}:{accepted:!0,normalized:[{path:t,from:n,to:r,reason:`clamped`}],value:r}}function yt(e,t,n,r,i,a){return{applied:t,normalized:n,rejected:r,committed:i,schemaVersion:2,nextConfig:i?a:pt(e)}}function bt(e,{baseline:t,reset:n=!1,resetBaseline:r=t,strict:i=!1,schemaVersion:a=2}={}){if(!ft(t))throw TypeError(`baseline must be a configuration object`);if(n&&!ft(r))throw TypeError(`resetBaseline must be a configuration object`);let o=[],s=[],c=[];if(!Number.isInteger(a)||a<0||a>2)return c.push(ht(`$schemaVersion`,a,`unsupported-schema-version`)),yt(t,o,s,c,!1,t);if(!ft(e))return c.push(ht(`$patch`,e,`invalid-patch`)),yt(t,o,s,c,!1,t);let l=[];for(let[t,n]of Object.entries(e)){let e=_t(t,n,a);if(e.error){c.push(ht(t,n,e.error));continue}l.push({sourcePath:t,sourceValue:n,path:e.path,value:e.value,migrations:e.normalized})}let u=new Map;for(let e of l){let t=u.get(e.path)??[];t.push(e),u.set(e.path,t)}let d=[];for(let e of u.values()){let t=e.find(e=>e.sourcePath===e.path)??e[0];d.push(t);for(let n of e)n!==t&&c.push(ht(n.sourcePath,n.sourceValue,n.migrations.length>0?`migration-conflict`:`duplicate-path`,{targetPath:n.path}))}d.sort((e,t)=>(dt.get(e.path)?.order??1/0)-(dt.get(t.path)?.order??1/0)||e.sourcePath.localeCompare(t.sourcePath));for(let e of d){let t=dt.get(e.path);if(!t){c.push(ht(e.sourcePath,e.sourceValue,`unknown-path`));continue}let n=vt(t,e.path,e.value);if(!n.accepted){c.push(ht(e.sourcePath,e.sourceValue,n.reason));continue}o.push({path:e.path,value:n.value}),s.push(...e.migrations,...n.normalized)}if(i&&c.length>0)return yt(t,[],s,c,!1,t);let f=n||o.length>0,p=pt(n?r:t);for(let e of o)mt(p,e.path,e.value);return yt(t,o,s,c,f,p)}var xt=65504,St=65472;function Ct(e){return Math.expm1((Number.isFinite(e)?Math.max(0,e):0)/10*Math.LN2)}function wt(e){let t=Math.max(0,e);return t<=.04045?t/12.92:t<1?((t+.055)/1.055)**2.4:t**2.2}function Tt(e=St){return Math.min(xt,wt(Number.isFinite(e)?e:St))}var L=3,Et=4,Dt=64,Ot=16,kt=7;function R(e,t,n){return Math.max(t,Math.min(n,e))}function z(e){return R(e,0,1)}function At(e,t,n){let r=z((n-e)/(t-e));return r*r*(3-2*r)}function jt(e,t,n){let r=e?.canvas;if(!r||!t||typeof e.getImageData!=`function`||typeof e.putImageData!=`function`)return!1;let i=R(Math.floor(t.minimumX),0,r.width),a=R(Math.floor(t.minimumY),0,r.height),o=R(Math.ceil(t.maximumX+1),i,r.width),s=R(Math.ceil(t.maximumY+1),a,r.height),c=o-i,l=s-a;if(c<=0||l<=0)return!1;try{let t=e.getImageData(i,a,c,l),r=Math.round(z(n??1)*255),o=!1;for(let e=3;er&&(t.data[e]=r,o=!0);return o&&e.putImageData(t,i,a),!0}catch{return!1}}function Mt(e,t,n,r){let i=R(n,.1,.75),a=Math.max(1,Math.floor(e*i),Math.floor(t*i)),o=Math.log2(a)+Math.min(Math.max(0,r),10)-10;return{levelCount:R(Math.floor(o),1,Ot),sampleScale:.5+o-Math.floor(o)}}function B(e){let t=z(e);return t<=.0031308?t*12.92:1.055*t**(1/2.4)-.055}function Nt(e,t,n){let r=Math.max(0,t),i=r*z(n)+1e-5,a=e-r+i;return a=R(a,0,i*2),a=a*a/(i*4),Math.max(e-r,a,0)}function Pt(e,t,n,r,i,a,o){let s=Math.max(e,t,n);if(s<=0)return r[i]=0,r[i+1]=0,r[i+2]=0,0;let c=Nt(s,a,o),l=c/Math.max(s,1e-4);return r[i]=Math.max(0,e*l),r[i+1]=Math.max(0,t*l),r[i+2]=Math.max(0,n*l),c}function Ft(e,t,n,r=0,i=0,a=r,o=0,s=0){let c=Math.max(1,n)/65025,l=r>0&&i>0,u=l?r:e.length/Et,d=l?i:1,f=l?a:u,p=f,m=l?s+i:1,h=-1,g=-1,_=0;t.fill(0);for(let n=0;n0&&r>0,c=s?n:e.length/Et,l=s?r:1,u=s?i:c,d=u,f=s?o+r:1,p=-1,m=-1,h=0;t.fill(0);for(let n=0;n0&&(t[r]=c,s)){let e=a+i,t=o+n;d=Math.min(d,e),f=Math.min(f,t),p=Math.max(p,e),m=Math.max(m,t)}h+=Et,r++}}return p0&&(y=Math.min(y,u),b=Math.min(b,a),x=Math.max(x,u),S=Math.max(S,a))}}return x0&&(c=Math.min(c,s),l=Math.min(l,f),u=Math.max(u,s),d=Math.max(d,f))}}return u{let r=[0,0,0];return n((n,i)=>{let a=(i*t+n)*L;for(let t=0;t{for(let t=a;t<=s;t++)e(t,o)})),i.bottom&&(u.bottom=l(e=>{for(let t=a;t<=s;t++)e(t,c)})),i.left&&(u.left=l(e=>{for(let t=o;t<=c;t++)e(a,t)})),i.right&&(u.right=l(e=>{for(let t=o;t<=c;t++)e(s,t)})),u}var Zt=class{constructor(e){this.createCanvas=e,this.sourceCanvas=e(),this.outputCanvas=e(),this.sourceContext=this.sourceCanvas?.getContext?.(`2d`,{alpha:!0,willReadFrequently:!0}),this.outputContext=this.outputCanvas?.getContext?.(`2d`,{alpha:!0}),this.sourceWidth=0,this.sourceHeight=0,this.width=0,this.height=0,this.originX=0,this.originY=0,this.regionWidth=0,this.regionHeight=0,this.resolutionScale=0,this.diffusion=0,this.sampleScale=1,this.displayWidth=0,this.displayHeight=0,this.displayCssWidth=0,this.displayCssHeight=0,this.sourceLinear=new Float32Array,this.coverageCanvas=null,this.coverageContext=null,this.sourceCoverage=new Float32Array,this.sceneCoverageMip0=new Float32Array,this.coverageLevels=[],this.coverageLevelStorage=[],this.coverageFrameReady=!1,this.levels=[],this.levelStorage=[],this.outputImageData=null,this.outputBounds=null,this.sourceReadBounds=null,this.floatBufferAllocationCount=0,this.available=!!(this.sourceContext&&this.outputContext&&typeof this.sourceContext.getImageData==`function`&&typeof this.outputContext.createImageData==`function`&&typeof this.outputContext.putImageData==`function`)}_resizeFloatBuffer(e,t){let n=e.buffer.byteLength/Float32Array.BYTES_PER_ELEMENT;if(n=t&&e.height>=n||(e.width=Math.max(e.width,t),e.height=Math.max(e.height,n))}_ensureCoverageSurface(){if(this.coverageContext)return!0;let e=this.createCanvas?.(),t=e?.getContext?.(`2d`,{alpha:!0,willReadFrequently:!0});return!e||!t||typeof t.getImageData!=`function`?!1:(this.coverageCanvas=e,this.coverageContext=t,!0)}_ensureCoverageBuffers(){return this.sourceCoverage=this._resizeFloatBuffer(this.sourceCoverage,this.sourceWidth*this.sourceHeight),this.sceneCoverageMip0=this._resizeFloatBuffer(this.sceneCoverageMip0,this.width*this.height),this.coverageLevels=this.levels.map((e,t)=>{let n=e.width*e.height,r=this.coverageLevelStorage[t]??{width:0,height:0,down:new Float32Array,up:new Float32Array,scratch:new Float32Array};return r.width=e.width,r.height=e.height,r.down=this._resizeFloatBuffer(r.down,n),r.up=this._resizeFloatBuffer(r.up,n),r.scratch=this._resizeFloatBuffer(r.scratch,n),this.coverageLevelStorage[t]=r,r}),this.coverageLevels.length===this.levels.length}_resize(e,t,n,r,i,a,o){let s=R(n,.1,.75),c=Math.max(1,Math.round(e*o)),l=Math.max(1,Math.round(t*o)),u=Math.max(1,Math.floor(c*s)),d=Math.max(1,Math.floor(l*s)),f=Mt(r,i,s,a),p=f.levelCount,m=[],h=u,g=d;for(let e=0;e>1),g=Math.max(1,g>>1);let _=c===this.sourceWidth&&l===this.sourceHeight&&u===this.width&&d===this.height&&m.length===this.levels.length&&m.every(([e,t],n)=>this.levels[n]?.width===e&&this.levels[n]?.height===t);if(this.regionWidth=e,this.regionHeight=t,this.resolutionScale=s,this.displayWidth=r,this.displayHeight=i,this.diffusion=a,this.sampleScale=f.sampleScale,_)return!0;this.sourceWidth=c,this.sourceHeight=l,this.width=u,this.height=d,this._ensureCanvasCapacity(this.sourceCanvas,c,l),this._ensureCanvasCapacity(this.outputCanvas,u,d),this.sourceLinear=this._resizeFloatBuffer(this.sourceLinear,c*l*L),this.levels=m.map(([e,t],n)=>{let r=e*t*L,i=this.levelStorage[n]??{width:0,height:0,down:new Float32Array,up:new Float32Array,scratch:new Float32Array};return i.width=e,i.height=t,i.down=this._resizeFloatBuffer(i.down,r),i.up=this._resizeFloatBuffer(i.up,r),i.scratch=this._resizeFloatBuffer(i.scratch,r),this.levelStorage[n]=i,i});try{this.outputImageData=this.outputContext.createImageData(u,d),this.outputContext.clearRect(0,0,this.outputCanvas.width,this.outputCanvas.height),this.outputBounds=null}catch{return this.available=!1,this.outputImageData=null,!1}return!0}beginFrame(e,t,n,r,i=kt,a=1,o=r){if(this.coverageFrameReady=!1,!this.available||!r)return null;let s=R(a,1,4);this.displayCssWidth=e,this.displayCssHeight=t;let c=Math.max(1,Math.round(e*s)),l=Math.max(1,Math.round(t*s)),u=Mt(c,l,n,i).levelCount,d=Math.max(Dt,2**Math.max(0,u-1)),f=R(Math.floor(r.x*s/d)*d,0,c),p=R(Math.floor(r.y*s/d)*d,0,l),m=R(Math.ceil((r.x+r.width)*s/d)*d,0,c),h=R(Math.ceil((r.y+r.height)*s/d)*d,0,l),g=f/s,_=p/s,v=m/s,y=h/s,b=v-g,x=y-_;if(b<=0||x<=0||!this._resize(b,x,n,c,l,i,s))return null;this.originX=g,this.originY=_;let S=this.sourceWidth/b,C=this.sourceHeight/x,w=o??r,T=R(Math.floor((w.x-g)*S)-2,0,this.sourceWidth),E=R(Math.floor((w.y-_)*C)-2,0,this.sourceHeight),D=R(Math.ceil((w.x+w.width-g)*S)+2,T,this.sourceWidth),O=R(Math.ceil((w.y+w.height-_)*C)+2,E,this.sourceHeight);return this.sourceReadBounds={x:T,y:E,width:D-T,height:O-E},this.sourceContext.setTransform(1,0,0,1,0,0),this.sourceContext.clearRect(0,0,this.sourceWidth,this.sourceHeight),this.sourceContext.setTransform(S,0,0,C,-g*S,-_*C),this.sourceContext.globalCompositeOperation=`lighter`,this.sourceContext}beginCoverageFrame(e=`scene`){if(this.coverageFrameReady=!1,e!==`browser-overlay`||!this.available||this.sourceWidth<=0||this.sourceHeight<=0||this.regionWidth<=0||this.regionHeight<=0||!this._ensureCoverageSurface())return null;this._ensureCanvasCapacity(this.coverageCanvas,this.sourceWidth,this.sourceHeight);let t=this.sourceWidth/this.regionWidth,n=this.sourceHeight/this.regionHeight;return this.coverageContext.setTransform(1,0,0,1,0,0),this.coverageContext.clearRect(0,0,this.sourceWidth,this.sourceHeight),this.coverageContext.setTransform(t,0,0,n,-this.originX*t,-this.originY*n),this.coverageContext.globalCompositeOperation=`source-over`,this.coverageFrameReady=!0,this.coverageContext}composite(e,t){if(!this.available||!this.outputImageData||this.levels.length===0)return!1;let n=t.outputCompositing===`browser-overlay`;if(n&&(!this.coverageFrameReady||!this._ensureCoverageBuffers()))return!1;let r=this.sourceReadBounds??{x:0,y:0,width:this.sourceWidth,height:this.sourceHeight},i=null,a=null;if(r.width>0&&r.height>0){let e,o;try{e=this.sourceContext.getImageData(r.x,r.y,r.width,r.height),n&&(o=this.coverageContext.getImageData(r.x,r.y,r.width,r.height))}catch{return this.available=!1,!1}i=Ft(e.data,this.sourceLinear,t.encodingRange,r.width,r.height,this.sourceWidth,r.x,r.y),n&&(a=It(o.data,this.sourceCoverage,r.width,r.height,this.sourceWidth,r.x,r.y))}else this.sourceLinear.fill(0),n&&this.sourceCoverage.fill(0);this.coverageFrameReady=!1;let o=this.levels[0],s=n?this.coverageLevels[0]:null,c=[];if(c[0]=Ht(this.sourceLinear,this.sourceWidth,this.sourceHeight,o.down,o.width,o.height,wt(t.threshold),t.softKnee,Tt(t.clamp),!0,1,i,s?.down),n&&Bt(this.sourceCoverage,this.sourceWidth,this.sourceHeight,this.sceneCoverageMip0,s.width,s.height,1,a),!c[0])return this._clearOutputBounds(),this._drawOutput(e);for(let e=1;e=0;e--){let t=this.levels[e],r=this.levels[e+1];if(u=Kt(t.down,t.width,t.height,l,r.width,r.height,t.up,this.sampleScale,!0,c[e],u),l=t.up,n){let t=this.coverageLevels[e],n=this.coverageLevels[e+1];Vt(t.down,t.width,t.height,d,n.width,n.height,t.up,this.sampleScale),d=t.up}}this._clearOutputBounds();let f=this.levels[0].scratch;Jt(l,this.width,this.height,f,this.sampleScale);let p=null;n&&(p=this.coverageLevels[0].scratch,zt(d,this.width,this.height,p,this.width,this.height,Math.max(0,this.sampleScale)*.5));let m=Xt(f,this.width,this.height,u,{left:u.minimumX>0||this.originX>0,top:u.minimumY>0||this.originY>0,right:u.maximumX=0)}return Math.sqrt(n)*(r?-1:1)}function rn(e,t,n){let r=en(n);if(r>=1)return Math.hypot(e,t)-1;let i=Math.max(1e-6,1-r);return nn(e/i,t/i)*i-r}function an(e,t,n){let r=1+$t*en(n);return[.5+((Number(e)||0)-.5)/r,.5+((Number(t)||0)-.5)/r]}function on(e,t,n,r=1/128){let i=en(n),a=rn((Number(e)||0)*2-1,(Number(t)||0)*2-1,i),o=Math.max(1e-6,Number(r)||0)*2;return 1-tn(-o,o,a)}function sn(e){let t=en(e),n=new Uint8Array(16384);for(let e=0;e<128;e++)for(let r=0;r<128;r++)n[e*128+r]=Math.round(on((r+.5)/128,(e+.5)/128,t)*255);return n}var cn=`AAAAAK2urbT/+/////////f39/+kpKS2OTo5GQAAACSqp6qRpKSkkf///9oQDBAOVVVVbaqqqtpVVVVIpaalpKqrqrYABAAAAAAAFwAEACRlY2VxVVdVbRgYGAj/+//b3t/e3lVTVUiqp6q2qqqqtlVTVSRVVVUkqqqqkRAUEBP38/fsAAAAIVpXWm1SUVJlCAQIAKyrrNrCwcLIWldaSEpFSkGko6S29/P3/6SmpLako6SRpKakkefj5+T39/faWllaWgAEACL3+/fxUlZSZ1JTUm3FxcXl9/P32lJRUktSU1JIp6intvf79/+sq6y2CAQIJAgMCCSnqKeRrKuskQgMCAD3+/fa//v/2mNlY2SlpqWnCAgIJFdVV21aWVptCAgIAFdVV0haWVpIvbq9wD8+Pzavq6+aEAwQFU9PT23v7+//UlJSbe/v79pPT09IUlJSSK2ura8hJCElp6enkaSopJFXV1dtUlZSbcbDxshCQUI5r7CvnBAUEBn38/fzVVZVbVVWVUiqqKq2KSwpK+fr5/tNTk0jrKqskZqcmo/////pa2lraaqrqtpVV1VI9/f396SnpJGEgoSCAAAAElpaWkmkp6S2rKystggICAFPT08k7+/v/VJSUiSfn5+Q////63Nxc3MFBQUFV1ZXSKyqrLaMjoyMn5+fkQAAABRfXV9uEAwQAq+ur9rOy87LCAgICEpKSl+6uLrDMSwxLaSipJFSUVJt1tPW00JFQkTn5+fkTU1NYQ==`,ln=`/wD/AP8A/wD/AP8A/wD/AIsAAQEEAnQDAQQBBQUAAQYEAnQDAQQBBwYAAQgDAnQDAQkIAAEKdQMBCgELCAABDHUDAQwKAAENcwMBDQsAAQ5zAwEODAABDwQCbQMBEAIRCwABEgQCbQMBEwIRDAABFAMCbAMBFQMRDAABFgEXAgJrAwEYBBENAAEZAgJrAwEOEgABGgECagMBGxMAARwBAmoDAR0UAAEIaQMBHhUAAR8BCmcDASABIRYAASJnAwEjFwABJAElZQMBJhgAASQBJ2UDASgYAAIRASkBKmADAgQBKwERGAACEQETASpgAwIEARMBERgAAxEBLGADAQQBLQIRGAAEEQEuXwMBLwMRHAABDl8DATAgAAEbXQMBGyEAAR1dAwEdIgABHlsDAR4hAAIRATEBMlgDAioBEwERIAADEQEzWAMBKgE0AhEgAAQRATVXAwE2AxEgAAQRATdXAwE4AxEkAAEkATkCOlADAwIBOygAASQBPAI6UAMDAgE9KAACJAE+ATpQAwICAT8BQCgAAyQBQVADAQIBQgJAKwABQ1EDAQwuAAENTwMBDS8AAQ5PAwEOMAABG00DAUQwAAEkATwCBEgDAwIBRTAAAiQBRgEESAMCAgFHAUgwAAMkAS9IAwECAUICSDAAAyQBSUgDAQIBSgJINAABGgMCQAMEAgFLNwABHAMCQAMEAgFMOAABCAICQAMDAgFNOQABBwICQAMDAgFOOgABTwFQQAMCBAFRPAABUkADAQQBLz0AAVNAAwEEAVQ+AAFVPwMBBT8AAUUDBDgDBDoBVj8AAUgBVwIEOAMDOgFYQAACSAEvAQQ4AwI6AUEBEUAAAkgBWQEEOAMCOgFaARFDAAFbOQMBDUUAAVw5AwEORgABXTcDAR5HAAFeNgMBXwEHRwABEQFgAgIzAwEiSAACEQFCAQIyAwEKASRIAAIRAWEBAjIDAScBJEgAAxEBYjEDATsCJEsAAWMEAiwDAWQBZU4AAWYDAiwDAWdPAAFIAUICAisDAWhQAAFIAUcCAisDAWlSAAENKwMBagERUgABDisDAWsBEVMAARspAwEQAhFTAAEHAWwoAwETAhFUAAFtAzokAwFuWAABQQI6IwMBCgFvWAABOAI6IwMBcFoAAXEBOiIDAXIBc1oAAXQBdSADAgQBdlwAAXcgAwEEAQldAAEHAXgfAwEEAQdeAAF5HwMBUV8AASQBQQI6GAMDAgFCAXpfAAEkAXsCOhgDAwIBSmAAAiQBOQE6GAMCAgF8AUhgAAIkATwBOhgDAgIBRQFIYwABfRgDAVABfmUAAX8BChcDAVJnAAGAFwMBT2cAAYEBghUDAYNoAAERAWECAhMDASdoAAIRAWIBAhIDATsBJGgAAhEBEwECEgMBPAEkaAADEQFgEQMBIgIkawABhAFCAwIMAwEYbwABGQMCDAMBhXAAARoCAgsDAYZxAAEcAgILAwGHcgABiAEqCgMBPwEkcgABBwE2CQMBCgE8ASRzAAGJCQMBIgIkdAABigcDASUDJHQAATgDOgQCAYt4AAFxAjoDAgF8eQABBwI6AwIBRXoAAW0BOgICAWYBSHsAAYwBKgE2fQABjQEqAYl+AAGI/wD/AMEA`,un=`/wD/AP8A/wD/AP8A/wD/AIsAAa54/wH3AaQFAAEZeP8B9wcAAZF3/wGRCAAB2nX/AdoBDggAAVV1/wFVCgABqnP/AaoLAAFIc/8BSAwAAaRx/wGrDgBx/wEEDgABZW//AVcPAAEIAdtt/wHeEQABSG3/AUgSAAGqa/8BqhMAASRr/wEkFAABkWn/AZEVAAETAdpn/wHsFwABWmf/AVIYAAGsZf8BwhkAAUhl/wFBGgABpAH3YP8C9wGmGwABBAH3YP8C9wEEHAABkWD/AfcBkR4AAeRf/wHaHwABSF//AVogAAGqXf8BqiEAASRd/wEkIgABkVv/AZEjAAEEAfFY/wL3AQQkAAFWWP8B9wFTJgABxVf/AdonAAFLV/8BSCgAAagC+1P/AawpAAEIAvtT/wEMKgABkQH7Uv8BkSwAAdpR/wHaLQABZFH/AVUuAAGqT/8Bqi8AAUhP/wFIMAABqk3/AaYxAAEIAvdL/wEIMgABVwH3Sv8BWjQAAdpJ/wHaNQABSEn/AUg2AAGqR/8BvTcAASRH/wE2OAABkUX/AZo6AEX/ARA6AAFPAe9A/wL3AVI8AAHaQP8B9wHaPQABSED/AfcBSD4AAa4//wGkPwABCAP3OP8E+wEkQAABkQL3OP8D+wGRQgAB2gH3OP8C+wHaQwABVwH3OP8C+wFWRAABxjn/AapFAAE5Of8BSEYAAZw3/wGRRwABFDb/AfNJAAFWNf8BWkoAAdoz/wHaSwABSDP/AUhMAAGqMf8BrE0AASsw/wHrASNOAAGRL/8Bj1AAAdot/wHpUQABWi3/AWlSAAGqK/8Bq1MAAUgr/wFIVAABqin/AatWAAH3KP8BBFYAAZED+yT/AYJYAAHaAvsj/wHaWQABSAL7I/8BSVoAAacB+yL/AawBAVoAASQB7yD/AvcBJFwAAZAg/wH3AZFeAAHrH/8B918AAXMf/wFSYAAB2gL7G/8B2gEFYAABSAL7G/8BSGIAAagB+xr/AaxjAAEIAfsa/wEIZAABjBj/Ae8BkWYAAdoX/wHaZwABXxf/AU9nAAECAa8V/wHLaQABSBX/AUhqAAGqE/8BrGsAAQQT/wEIbAABVhH/AVptAAEIAdoP/wHebwABSA//AUpwAAGqDf8BunEAASQN/wEtcgABkQH3Cv8BkXQAAdoJ/wHaAQh0AAFSCf8BWnYAAdMH/wGsdwABSAP7BP8BRHgAAacC+wP/Aax6AAL7A/8BCHoAAZEB+wL/AZF8AAHkAfcB2n0AAU0B9wFSfgABkf8A/wDBAA==`;function dn(e){let t=globalThis.atob(e),n=new Uint8Array(t.length);for(let e=0;e{let e=V.slice();for(let t=0;tNumber(e?.[1])).filter(e=>Number.isFinite(e));if(t.length<3)return 0;let n=Math.min(...t),r=Math.max(...t),i=Math.max(1e-6,(r-n)*.001);return+(t.filter(e=>Math.abs(e-n)<=i).lengthMath.abs(e-r)<=i).length)}function vn(e){if(typeof e!=`function`)return null;let t=e(),n=e(),r=e(),i=e();t.width=128,t.height=128,n.width=128,n.height=128,r.width=128,r.height=128,i.width=128,i.height=128;let a=t.getContext(`2d`),o=n.getContext(`2d`),s=r.getContext(`2d`),c=i.getContext(`2d`);if(!a||!o||!s||!c||typeof a.createImageData!=`function`||typeof o.createImageData!=`function`||typeof s.createImageData!=`function`||typeof c.createImageData!=`function`)return t.width=0,t.height=0,n.width=0,n.height=0,r.width=0,r.height=0,i.width=0,i.height=0,null;let l=a.createImageData(128,128),u=o.createImageData(128,128),d=s.createImageData(128,128),f=c.createImageData(128,128);for(let e=0;ee+t.length,0),r=new Uint8Array(n),i=0;for(let e of t)r.set(e,i),i+=e.length;return r}function Sn(e,t,n,r,i){let a=(n*512+t)*4;e[a]=r,e[a+1]=i,e[a+2]=r,e[a+3]=255}function Cn(){let e=xn(yn),t=new Uint8Array(512*512*4),n=0,r=0,i=0,a=0;for(let o=0;o<512;o++)for(let s=o;s<512;s++){if(r===0){if(n+2>=e.length)throw Error(`Circle_01 RLE 数据提前结束`);r=e[n],i=e[n+1],a=e[n+2],n+=3}Sn(t,s,o,i,a),s!==o&&Sn(t,o,s,i,a),r--}if(n!==e.length||r!==0)throw Error(`Circle_01 RLE 数据长度不匹配`);return t}function wn(e){let t=e/255,n=t<=.04045?t/12.92:((t+.055)/1.055)**2.4;return Math.round(n*255)}var Tn=Cn();function En(e){if(typeof e!=`function`)return null;let t=e(),n=e(),r=e();t.width=512,t.height=512,n.width=512,n.height=512,r.width=512,r.height=512;let i=t.getContext(`2d`),a=n.getContext(`2d`),o=r.getContext(`2d`);if(!i||!a||!o||typeof i.createImageData!=`function`||typeof a.createImageData!=`function`||typeof o.createImageData!=`function`)return t.width=0,t.height=0,n.width=0,n.height=0,r.width=0,r.height=0,null;let s=i.createImageData(512,512),c=a.createImageData(512,512),l=o.createImageData(512,512);for(let e=0;e>1)];t[a]=o+(a&1?s&15:s>>4)-On}}return t}function Nn(e,t){return Math.max(0,Math.min(t,e))}var Pn=Mn();function Fn(e,t){let n=Math.max(0,Math.min(1,e))*256-.5,r=Math.max(0,Math.min(1,t))*128-.5,i=Math.floor(n),a=Math.floor(r),o=Nn(i,255),s=Nn(i+1,255),c=Nn(a,127),l=Nn(a+1,127),u=n-i,d=r-a,f=Pn[c*256+o],p=Pn[c*256+s],m=Pn[l*256+o],h=Pn[l*256+s],g=f+(p-f)*u;return(g+(m+(h-m)*u-g)*d)/255}var In=3,Ln=512*512*In,Rn=512*512,zn=`LwUAAQD/8BD/BQAPBADkEPwFAA8EAP///////////////////////////////////////////////////////////xUQAwUADwQA.2BD9BQAPBAD//////////////////////wkwCAwIBwAOBAAHGT8Q+AUAMQAA/TwRF/8yEhEBEgAPBAAjCDsAIAL7BgAPBAAdEP4F.AA8EAB4PNgAjDwQA/////8owKSwxBwACBAAH9AUF9gVXAAAA+PgMAAckAAgYADEA+PcHAAAEABf3JAAISAAPBAAeCUgADwQADwlq.AA88AAYJJgAGBAAPMAAGDwQAAwlGAA88AAYJJgAGBAAPMAAGDwQAAzD9AgIHAA0EABf9uUcmBv/ZBghbBw8EAP////8RMCYmJgcA.AgQABzkEJv7/vAQm+vmgCyb4/CUACAAGJv33AAYm+PqMBDD6+/UHAAEEADD9/PoHAAEEABf7SAAm/f4wABcA1AQYACQACBgABy8A.JgAAJAAY+CQABzwACDAAJ/0A8AwW/yQAGP6UBQhIAAc9ABb9CwAnAAM8ABcAPAAHFgAKzAAHPAAZ/c8FBjIACNAFCDwAJv3+JAAP.BAD/////QTAnJicHAAIEAAekBCf7/twFFvqABBf3xAUIAAYm+/YMABf4MAYw9PXyBwABBAAm+/gMBib1+EgAJvr9MAAHzwUnAABs.ABf7nAAJJAAWADwAGPgYAAc8AAgwABj6DQAHeAAX+8QFB/MFCWAABwcBNwAG/WAABzwABxYACkgABzwAF/pDEwkyAAckAA88AAUF.BABY+/39AwFJAAcxAAc8Bg8EAP////8RCQAGBwQAJvj80AUI4Aon9/zoCwcABif49AwABxgAMO/v7wcAAQQAMPj08AcAAQQAJ+/0.SAAPbAAEFwAYABn4GAAABQAEBAAPJAAEFvtgAAhUAAcWAA9gAB4YAxgAF/x8BQcYAAcWAApIAAgMAAklAAYEAAmEDAcMABkDDQYG.BAAY/owZBagGNP4AAwAGDzgGAQ8EAP////8MJ/r+jAoIBAAQBAUAAgQAMAkACQcAAQQAJgMKgARTCwoL+vs/AFMN/Q37+o8EgAsN.CwAAAPX3+gtQAhQT9fQJAFYAAAAICAwGF/A8Bif39DAGB6wRFwiEABEAEBET+GMABiQAUgoE/f78FQBjAP0FDvv7DAAXAOVgNQv/./CQAMPwEDeALAQ8AGAvMHgEwABH9PwBT/QQK+/x/BSANBCQAAjAAQQIFDf4hAACfCxAFGAAAIgAxAAACfAUCYwAg/QT8AAFjAFT+.BQUC+8QMJwsIhAAT/SQAVgAAAAUEFxMRA2wAEf0nADD9BQoTAAIEAAESAAAtAFUFBf3/AEgAI/0AJABQ+/z+AgY8AAANAEP8+wIA.bRIU/sYAAgQAI/oBGAAMBAAHSBgPBAAFDzoABA8EAP///7EjAwPQBUj9/f0CdBwC1AQNGgRCBgYG/RUkAB0kQv0GBQYMAFMABAAG.BwwAEfsMEiALCeYEUPf59wsMCQAANAVw+hAAAADy8QYGJgMHAAYm9Ad4ACD4+V0AIPDwJAAAEAAKBAAgCAanBQocFwY8AFD9/QAF.BSEAAA0AAZ8AAgkAVAD9AAIEGAABZAsRBQ8AFAH8AAGcAADJBhEDPwBxAwMABgQD+pcFFAZMBQAkADH9AAIhAEQAAAACTAVB+/v7.A04AAA0AFgAuAIQFBAP7+f0FBREAEwMdAWMAAAAGAgEKAABjAQMIAFYAAAABAJAAFAM4AEH6+/0GdQAR+nsGD2wAAgAEABAEDgBi./fz7AgQFRgBo/fz9AgQCRwwRA2AAGP3GGAEEAAAWAA9xEgMPBAD////GCegFBwsACQQAAQ8EMAMBAy8EByQANf4A/jMGBQkAEfo9.BQAKAAEEACMLCvEFMvX29QwMAA0AAPkKBgwAJgkLAAYmBQfUBCD49uYEAAoARgAA+/kkAAVIHlP4+fsFBHgAAT8FBgwACBEFIP7+.qAADqwYXAXwFAAUAAwQAI/4BHQVW/fr6AwYkABH96BcSBmYAAgYGAXYFF/pgADIDAgP2ADAFBQV9CyL8+poFBbgRQ/r8/QWKBQAE.AFP7/v0DBGMAAiQAFPpbGANpAAHMAAFIAAAnADIDBP0hADIGBQMUHwIGBiD9Ah4AAjAAA0gAZPz9BQQD/kUABRgAaAMEA/38/dcF.Wf7/A/3+QhgA3QEACAAABAAGFgAPDAb////QBbgFAx8FAQQABRUAAwQAAQAMAy8EBxoADhIMAB8FBz0FAAQAAWQLaAAAAAsKCzwY.AgQAMA4PEQcACGQXFgdgEhf4GAwCrBcg9fZCAAJoEnT3+foIBwUAhAACowsHWAUABgAClwUACgAF1QACBgABBAAUA3sLBboSADkA.B8AANf36+pEFAQQAAwwAJvr8JAYR/WMAFAYPACb4/IQAArQAABQBB0UAJvr6/QUABAABJAAhBgYhAAQsAQD8EghIACMA9yEAAOkL.BAkAOAAA9yQAAkgAAWkAAAoAFAAbAAEYAADYAAEbAAASAAEEAFn7/AADAhIAASkGIQADUAEASwEBFAAAOQADCAAABAAIGAAPBAD/.//+2AxcEEP8fBQkAGAH0BQLiBTACAgJDCwsvBAGlEAY2BgEwAAIEAAI2AAAKADcAAAC4Fwg8GCf6AmwAEAAMDALKEUETEAv63wvx.Afv8+woICPv4+A0MGfv4+PShI+ANAADz9PMIAQDw7/AICE4AIO/wEgYB+wQnAPhIBgJ8HQKXBRECxAoCKxcU/RkMANYXBJwAdAYE.BgL++v6HKiD6/iQAAPMAVQYGAv8COhdBAgf8/jMkRQYEBvp8HQCbBQBgAAAMADEAAAtsABH9MwAg/QaUFxH7VwAwBQD9ggtAAAAI.BogRBmwAEAQkAAJjACACBvkAAhsAFAWoAABsEiL+CxUAAP8FEAQkAADtDDT8/QMVBgCbBwflGBELSgEBOQAh/v1gAAKEGAUYGEH+./vsK+A0CVwAC8AAC5gESAhQBEP7nACAC/hIAAA8ACjAYEv4rBgIEAAf4AQgEAAYuAA8EAP///48EBAsA6gkEHAsc/VwoCScSAjUE.AAoABVULAGwEAwgACwQACQwGD2wAAQA7AAFFBgOPCjH+AAa5CoAGBAb9AP0GCN8dU/r4+AL3+ARHDgwO/VQwFALgBFDt7O0NDNAd.MfP082AeGAifKgE6BQAiBRACCgUAbwA1BQQC0C8A6wUBAQACzwYC/AA8AwMDCAFA/wACA0UAAMAAFv/NAAIkAAKWEgNQBwEEAAJg.ABEFOwEFxBcABAAAZQAACAAASAAC9gABBAACSAAACgAArgADDAAw+/z9mgABjQAFMAAB0BcVAzAAAU0BB1UAAbQSAAkAATAAAhoN.QQUEAgDEBYD9/fsCAgUDARQZAtcBBUgAAGAAIgMCIQAAEAAW/gcaCDAYBTgNCbEwDwQA////pwPgAwFyFgFcBAIOAAHHCgQaBAEF.AAD/AwEfBQUUBAWjCgAoBQE8AALECwM2AAEvBAUcHQAJBhADZgAADQABbwwFUQABvwQAFwAAEgABQgADDQAEBABQBggIBgQJBgAN.AAAEAAAhBgAIAEcAAAUHMAACvAoBBABB+/j7CDwGAFQAAZoFABYARwAA/fwzGAQ7AABhBRD/jQACigAJWCkX/tMFE/54ADL9/foq.AAD5ACIDA5AkBHARAGwAAjMABG8LIgD65wABFQABEQAA/wAC/AAR/kgAARQAA6wXAQsACLgFIQP+fAUBFwA2AAMDJAAFGAAAhwAi.BAaBBgBpAAFUAAAVAEADA/3/wB4AJQAFhwABwwYC6BECGAAJ8AAiAP0hAAAMAAffBQgwGDIDAv7bBgAJBgQkAABbAAAIAA8EAP//./6kDqAUABAAA3QQE2AMCBAACrQQAGAAADgAAKwUBCAADBAAAGAABcBECngoAcwUCEwUBLwQAGQABBAAAAwYHZgAAIQABqgQCDQAC.YwAC/QsCAxIAFgAPBAAEIhESORghAAn/C2Ls6+wTFBOaKaEODA7y9PL+CP73k0I4+Pj4HAUC0BcCWwUAtwAAFAADzwAFDwABaxIA.CQAAEgABFAAi/fshABIGDx4wAwMGzAAAEgABHwABOQAR/UUYAvoFABUAAYQYAnMFEAaIBQEyBQcEAABdAAReNgM2AAHAAAIYACYA./LgFApwwAxgAATIAAjAACagACQwYAPkAABUAAYQAAGYSA/AAAyEABMYAAEUAARsSABUABBIAABUACyEAAiQABd0BNQAA+88MAgkG.AC0AAwgAAjkIDwQA////mQIlKQIBBQh0QALcCwPrERYBBAsDRSIBAhAhAv8lAAIEACIFABMFAAwACFwcASoAUAD/AAMAQQoAGwYB.RBABFgAHMwAFbgQBHQACBgYR/ZQvA5wAABEAAAgAAAQAIv8LiRAA6BEQDL4FgBYbFv7+/vj18RHwCfj3+AkJCff69xAAEPDx8AkM.CQL/Au3t7TkAABwFACQAAlsFAlgFALwEAHsAABIAAhAAFwWUOyH9/h4SBL4jBmQFEP0BAAAJABAAIQAARQAB/yoUAsU1QP79+/0b.GACfAAAeABD9HgAA/wAAuBcDYABB/f7+AnwXAA0ABHIqCPAAAoABBXENQf7+/gXoFwJLGBEKFwACJAAg+gYNAAIMABAF8AYAIQAA.JxgAEQARAIkAIwD6mwBzAAMCCQP/+mkARgAACwaDQwIMGAJ/ABcCEBojBQWBEgANACIACmkAAJ8MBMgZABIAUgICAP7+KgEIMBgF.pB8LBAAHIgAPBAD///9vCHwFBVsFADQXAXoEJv4C8hsgAwIIBAgwAAIEAAjrEQk8BgIEAAIGBgEEAAJEEAA+AAczAAYJBhEBN0cI.MAACbAAELRICDAAIRQAAvhEBJAAC8RER+IpCMAf3Bx8AAQQAFQXREFIAAPv49XUwADwGAUIwAG0jKPr7igAFIRILfBcAHgAE1QAD.AgEBBAAFIQAAKgYEJAwgAgOgNQbAABMBtQUUA7gXAKARIgICDAAAIQABfCMAFQACMAAB8AAC+gUCJAAClTEgAwJIAAOPBxf9JAAB.hAACDAAQAGAqASEAEgCbEgELABD9zAAACQABWgACMwAFDwASAzkAAfITBlQAAXgAAiEAAA8ADZkAABUAASQAAhIAABsBBBgAAMUB.AQgADwQA////jwKeBAK/BADcBQTkFQI5EAIYAAAKAATXAwDzAwEzAAANABP/8RcAFQACNgABkQUCCQACIwQGPAYW/xUMAjYAA2kA.ATMABn8FEQIuAAEFAAYwAAGHAAKrAAEQAAAzAAAJAA8EAAEgCAoGBiAIBgYAABAA5AAA9fT1ExMTAAAA7e3tcioABAAj8vNIHkEI.BgX9HAsDxgYEAgcATC8QAFgFBnsABAQAAesFAxUABbUFAAYAADMGAD0LAMwAAdUGBUQBA7UFAJQRBlQAFAN8FwInAAIVAADjAAQh.AAFIAAMJAAAEACX//kgACAQAF/vQBRIDRAEA7Rgi/QAVABD9CQACbAACewACDAALaQAIDAAA1AEEwAA1AwMDJBgIJAACDAACBgAA.qAAAFAAAMQAAPAACLjIBEgACLgAA3wAACAAPBAD///+EA9IDBLgRAqAFAMYDARgABp0LDQQAAjAAACYEBTMAEgErIgAMAALUBAIP.DAAEAAFkBQAkAAo2AAgJBgAHAAB5DAMIAAIEAAOfAABbBAAwAABCAA4zAA8EAAEREe4FFwlUMCYEAyUeIAMBZwxj9/n6+Pn6yQAB.6QACZB0CJBgAbAAHfgACigAD2AAEBAAIFQAFAAwAGQABBAACHgAGFAEDSxgEEAAFFAEiAwMAGAANAAchAAJXAAMhAADAEgYkAAYV.AABUBgIIAAOHAAELAAC2EwMkGAInAAEMAAMzAAEMAAhCAALHBRr9mx8FIQADSAAEDwACIQAADAAQ/1w3AhsACJoAAGAGAEYBAAwA.AgASAzcACTYODwQA////cgh8BQXIEAAJDAF8FwAZAFIAAAUABRgAAA8ACiQYBeURAAsEAAgAAAQAAiQYADMAGQQkGCP+BC0AAAQA.AVAEA3YFAIcFAPcRDyQYFQIEAAGKABEGTEEAbAABQgAAEwACBAAEdwAy/f795Gah/fz9FBMUAP79CB9BYPj39QUGGCIAcPDwCQsA.7/B4SAO7BgGIBQIkGAIwMAAtMDIAAAWoAAGUIxH7EAsDeAAB7RICnAABewsAkwAAGAAcASQYAMMAMwUDAiQXSAD+/f1EQyAA/ggx.AP8ANP79A1gXAQ8AAIQAAw0AEALMAAAJAAAkGAAkAAJaAAhIGBECRAEACgA2AAAIFwAGtDwASBglBgZlARH79gAg/QIPAAjkThQD.BAJl/f/+BQIFMAAB3wEBCQAHbAAw/v7+Ow0A8jEAZwBQA/z7BQMkBgAcAAEKDgIFAQgYGAQaDgEEAAHOAQIEAAYiAA8EAP///1sA.CQYE/AkAEAAB7AQFmwQGGAAZ/Z0FAuURANsDBcwDBMkDAzMABCwAA1sRAAsAANMFAjkAArwEARQAAE42AggAACUFAZYGAmkAAjYA.CAYGDyQYBgqcAAIEAADMBgGxBAB5F/ABDAMA/AAICgv49vUICgsH+UAFACUAQwAA/wG4AABaNgEhAAANAAQEAAA9LwCJBQAcLwAQ.AAFyAAIxCwIPAAYEACH+/toAAAsABUwLAA0ABAQAAjkSAlkBEAIYJAckABP+MQUmAwJ1GAgkGAFyAAAJAACMAAAdAAAMAAJKAQIk.AAKIFwIMAAEkAAD3EQAlAAENAAJpAAIkACMAAOkTIP3/xgABWgAADwAAWQEALAAQ/YQAAhgGc//9AwECAAKeKgUwAA94AAAEMAAA.GAABJAACcgAAFQABzAACJAAFpAEAPyoAMAAADAAPBAD///9oAoILAnYLABAACgQAC8ADAAoABPMDAAwABeEJAQwMAwkAFP5FEgUb.AAEEAAI2AAL8AwLTBQA1AAFEBAMICgGBBQM8AAGQAAIzAAAPAAo8BgAHAAL9BQRhBQWHAAUzAAGLBAefAAoEABEIlkgCBgAAEAAA.sQQDCAABBAABkABVAAD49vX9TQISAAUcLxf++BAFPQUBCQACEgAABgAFFQAAXwAEDAAANwUBQwUAIgAAzwAAKAUCDAAFJwACDQAF.DAAUAyQAABYGIf/+CwAC2BcABAACVwAAKAAEPwAC3C8BjQAEuBcHABgADwABbB4AOQAB7xkU/jkAAmYABYcAAzAAAE0AAcwGAZsB.AKwBB3cBAgwGAg8AA2wAATAAFAAgAQJUAAUMAADgAQIhAAAEAAAKAA8GBv///24AkAMBJjoAAwYBigMCBAAADwAACAADBAACwAMA.CgAHqAMCYgQACgAAyAQAzAMADAADqAUDIwQCUAoCBAAFQTQADQAECAAAIAQEMwAABAABgBAClgAAFwQKCQYCBAAAVB4ACAAGBAAL.bAAFvQACGAACdQYAEAAPBAABIBERJBgVAd0R9gEAAPj5+AkLC/f19QgLC/nzwGYQ/QweBjMMBQQAA2YAAQ4BAnwFABYAABQBAAgA.Ah4ABSEAAM8AASQAAPkAACAABCkBANwGAAgAAhgAAhUAAgwAADMAAQ8AAB8AJfz7CwAQAJAAACEAC6AdAAcABMQFA7gXAQwAAhRD.AhgAAmwYAmgBAAoAABoAATMABUQBBXsAASQAAPcFAA4AACsCAQgAAGkAATAACegFBzAAA1YAAh4AAiEAAagAAyEAAA0CAfgBAkIw.ABMAAAgAAasNAQkADwQA////VwQPHQP7FgQEACYJ/DQdEv/VXgEZBSAFCQELAltfCIkiUAgBA/v7eSkA6gMQASQAADU0Uvv7BQgF.lzUALC40AQX+BF8FBAAAQQoH9QMR/fheAEAEIPz+vF4BswQIBAALqAAItEgFYBgAJAAHOQAgCwKQABH+1EYR+n0EABYAAQQABSoG.8w4TDhP6+/r7+/sZFhn6/vry8vINDQ3z8/MMBwXt7DwwFfdVTQCTBgAIABH48wAIrEcCCgAiAgSaXwIOAAAEACP7/CgFAPYMEAAe.AAIPABT9uBcACxMApwASAGwwRQL+A/4wBgdsZicDBYwZBwQAAkgAAl0SBZQXAHQBB7gvIwMFPAwABAAHMDAIPBgyAwX7MABTAgIA.+//tAACEAAQMGAAMAAJNNxAE0wUU/ZgNMgMCAkQlAgQAJgMGMBgS+8AAEAS6AAjvWhECVAAAWRJG//79ADAANgEB/g8MBQkAB2MO.DwQA////OwIANgAKAAsEAAeoAxT60SIyCAcIMQUDNgAHnANTAP37BQWbHAC8QAEWUwAnABP/YV8AGAY1/f0CBF8EPABW/vz+BQQk.BgOqWAABRwAsFgATAAIEAACpBAEIAAGzBAAKAAEEAAIiBQNdAAFOEgAWAAJlBQTgBAISABECBgYC9CMAEAABMwACjAoADwDT/gAG.BQYGBQb6+/oIB8kARAAAAAkgAACuYDf1+/IPDABCMAHzAAL6OwMkGAF5AAJ8XwAKAAA6OwMyAQJYBQAkACX+/YRgFAMUAAUEAAW0.ABQC2wAAzwYCzSkADgABpgsBvQAAiwUB8wAR/fcFBQIBAi8NBW8ACTAAAAsAAMqFAHcHDzAAAQItAAA3AADADAAMAAMYAAIkAAGj.BQI8AAAVABQDvwACJAABPAACMAAADwABMwAAswEHMAAARQABDAAIDBggAgF8HgOHAAESAA8VEv///1k4CwsLJVkGBAABgQMCBAAA.O2QACAAABAAR+wFTAAoAAKADAwgAAAQAAfwDAAkAAExxEvt5UwAPAADOAwAIAAAvADEJ/f3IXgAQAAQIAALxBQUkBiD+BOAuAuwE.AvgEABYAAD0AAwgABX0EAA0ABOgFAlwECRgAATsEBM4EAyUABbhHAA0ACgQABbQGIAYFeE4wDg4OFgBEAAAOCskAAGQAE/YJAEYA.APL0CQYCKiQFZ0EAKQABzwACvmsCTjYFrEcABAADjwAAjUgCkAAFGxIBFwAABAACDQUA+ACC/f0DBQP9+/1uDQIUAQgwAAAMACAC.AqAXARIABQUBAiEAAhgSACQAAAAYAFoGAQsYBiEACzAAC7gXBxgAAK0rA5YABMAYACQAAQkAABUAAFQYAJsBAhsAAggTAi4IBUUA.ADAABAwAABUAE//6GQAkBgGJBwAVEisBA2BIA0MADwQA////SQasBQgEAASkBAUEACD3+VZGCS0AB/APAgQAL/r6JAAJNfcA97NY.AcdGAQkAALwuBBUAAG53AFIRAuwEAdRGAQkACgQACAMGCBgkBVkEAAQAAQAGBAQAEgOULwW4RwAUAAeJBAAEABb8twAFqGAABgZQ./PgTFRQ8NjHr7A4BACDy8voFQQP/A/ftAAAHWwgsfwGgBQAKAADYAAZsAAAYYAZvABIDkEgyAwQF+lkJigABBAADQAUB6AUj/v8V.EgAZAAE4AQUwAALZBQArBQ3oBQIPAAAlAAXqAAGQBgILAA88GAsCGAADPBgEBAACLA0F0wUCJAAFCgAABgAT/BIABUgAAjMABfQT.Ah4ACGkAAiEABVQAAg8ABWBIAwYGAAUAByMUDwQA////PQI0QQAKAAqsBTL9Bf3lFwANAAEEACEJBBIYCiQAAAcAJQAAKgAfBiQA.BAIhAAgAYAgEADL8BfwhAABSERb8kAACPAAACgAAVi4DCAAR+9R2IwIEl18CEAsAGQAAWTQGMAACzi4DTBEAmAQD3AUGLgAAWC8A.hQUCDAAU+zwYAPQRB6gAEfzKC5YAAAATGQj+/P7AeEMGCO3rGBgj+PgtDVAGBAD8Av0AAv94EQMAeALMDBQF2BgAFAE0/v0ASBgy.BQL9mRgAGAAlAAInGAEABQMEAAXcFwDvDASQAAAEAGH8/gIDA/5gAAIIAQAaBzH8/QP8AAAhAADkAAA8AAI/ABcFPBgAwDABkRcA.VAABvwALPBgAJDAHMAAFPBhlAgID/gIJGAAALQ0BshEAqQUQBVABAIQGQAIA/f/yYAAiAAD8EgNsBgAkABD/7QAC+hcR+8wAABsA.IgICYxoCngcjBf14AACtWxMCJBIAaAcPGBj///9DBXkRACMEBY4PBcYhDgQAAboDAAkAB/h2DAQAAVAEAgQADyQACwX3BQAqGAAI.AAMYAAIEAAWEAAKaEQAKAAB8NQaxAAsEAAAwHgBwFwBUAAJGBQAWAAc8BgAEAAHQTQAJADEAAAUkABL7awQBChcCGAAFUQQy/v7+.ik5x+vz6BQQFBIV+gAsMC/X09Q0ObGAAJQAxAADyongU805CAO4XAVpIWQH+Af38uBEC2FQAowsFwwwAZF8ALQAAAAYk/v1FGACS.AAJFGAA8AAEpAADcBQCQYAbMVAI7ExQCYAACaQYA5zABphEBiAUDPDADGxgIuBEAQQAJrwsAIQAAcxEDEgAdAlQSAQsAADwYAG8A.AQ0AAxgAAmMABKYFAzMAFPwVDAIkAAEMAACTAAH5AAIkABf+DAACvDEELgIDFQAAHgAAHx4AEwABBAAQ/hISDxgY////PQLgBAAK.AFIAAP4E/kQEAMADF/7QfQgEABMBfQQAJAAEoAUMBAAPxAUBDAQAByQABPYDAQQABAsAYvr6+gYGBvoFAJoRA5gAAAQAAmA8AlgF.BbEAAJAAAQwAAtIGAloWA0cEARgABCUAANQEArkEEQCzBAIGBgJeBQAhAApcCgIEAAImATX+AP7AflH39vcTFlRIQ+rtDg4VAADq.hAQ8EgBQBxb7zBgCBgACSAACwAADJQAEbAAm/f2ZYAIGhAJFeABIAAHMAAAZAAANAAc/cij8+wUBAgwAAHQBAdwRAvwAAjwwBAwA.AEgAAFUFCvQRAh4AAxQBAQQAAhIAAPRfARUAALEGB3gwFP60AAAnAAQESgG4FwA2AANIAAFCAAAuBgCQEgCEAAE8ABsDYBgJDAAE.SAYFjAEBnBIDQwIAGxgUAhISDxgY////OgDLcARQCgBaAwdEBAAHAAcEAASLBQMhAAKSfAAKAAAVAASSBAIEABMCLQAADAABBAAA.wQUACAADBAAFHgAC9wsC4QMAEAAA9woACAAC/QU2/gD+OQAAVxEJqXcCBAAF9QQItAACZwsACgABBAAIJAAIBAAFKBcAA1QCngQC.DgAE4AQAVAArAwNOAADMeCIMCwkGgOzq7BMWE/v2cmwCHAAg+/UXARf6WjwCfgAOnAADbwABiAUBmR5CBQMD/kIeAnhOAA0FBC0A.AgQAADMAAjYAVgAA/fv6FRgxAAD+PQUAMwAHYEgFRgUCJAAD9C8BGwAF3BcFKgACCQACFAECOQAFLQACDwABCwAA0gUANwAHBAAC.vwECBgYFMwADBBQEDAACFQACSAAAEgABJwAAjgABDQAAHgABdAEA5QUcASQGABkAA0kIDxgY////QxYC+BwFaRUIeAMDQxcF5QUD.DgA6AAYGoF8EBAAACAQTBMRxABAAAggEAQQABawvAEsABCAAAEIAAfUEAg0AEP0QFwN2EQLXCgAWAADnAwAMABEGmF4m/P9VAAIG.GAAKAAESBAKNAAA8cgGcAABdACn9/dALAKNeA18EEgA0BQEeAADfFgT/AAIAEgIQFwDzBgGNAABLAAHjBAMmAQEFACAUEhsecfcM.C/j3+ACibBEFWC8g8O8SEgiQojL9BPpFSAJseADJCwFOAAOQMAFabACaCwERBwASACD9/YEAA3sAACoAAAgAAPsEABgAAOwAAGoA.A/CQACEkBKx3AWBIBEUAAPQLAWAAAgQABxgAGAUkGBD8yxMCPwA1AgH92zwFeBgIGBgAw20TAaAXAYcAAxgMABgYAjAwARAAFwa4.Fw8YGAUC9BcCBAACeDAChRMg+/+oAABjAAoYGBQCOaMkAgO0SAFjAAgwMAIwAA8EAP///xsQA1wFAAkAAZMJAHUDAQkAAhIAAzgW.AAsAAAQAACMEBTAAEAKTCQDVAwEsBAASAAPkAwcPABL+P00ADAAALAQCcAUKBAAAaBwIADAHTgACeCoCGwACRgsAFgAyAAAGaAQB.TAsFGAACLQYCuQQAEAABYBIAkAAjAwOxAAFcEABiDAJmBADJBABWBAIMAAB7AAWfAAHYQgX5AAD2AAAIAAHwAAXDPAEFAAIEAPAF.CQoJCQoJ9/b3+Pf4CAYQ7+7wEBHekEjz9Pv1FRgDzwAAXgUBWQEAQwAAVosENQEAhCoE4QwAcxEEBxEJCAEBGQACGAALSDAGNxET.AYRUNQIDBah4AQsBAxgAANUGIgMDnGwAMAABOQAC8AAFqAwMGAAB9gACDwAOGBgBCAADNgAAEAAAHAAEVzABowUBJwABDwAHGBgP.IQADBEwAAg8ACBgYCDAABYwBAw8AAeYABQYGDwQA////HgBWAwAIAACmawJ1AwCeAwFXAwEPAALnAwI6BQCKCQAUAAEmAAQIBACW.AwEkAAwPACICAyQMAoIFAh4AAYkEAwkAAlQAJgD+JDYCuBcACgAB7AoBNwUAGwAJGAAB4xAAxQQiBAa4jwMfLwALAANXAAAoAART.BAYADADqRgAIAABFABf9nAYEtEgAGAAB6QoDOQABpQACAQUCBgYGJwABZgACJwAAFAEEBgYUAMAkRO/u8AsYGDL18/XcFxD7oI8A.QwACWwUB2goG0AUm/f10GQBHDQAIAAAEAAIMAAIjAQgIAQXAABD9FUIAYAAADQAAcBEj/QMXVQDwMAJdAACrABP+GAAAGwAx/PoG.vQABkxIDKQEDKgAIZwUHGAAFDwAOGBgBFwATAFQYAhsAAaAFAAkADxgYCwHEBQAXACIC/iEAAfQXACQAAg8AABsABEtgBfQFATgB.ALMBAg8AAJ0MARYBRQMBAP/sAQ8EAP///xcAawME0wsHBAAC6gMChAMIDAADHwoBCwAIBAAJJAAA5gMADwAAEgABugMCFQACiAUC.KgAACgAEBAAA+AoH6RYFIQADgEwAoQQDHgAA5QUA5xEEGAAFLgsCChcGFxIDPAYBCwAGBAAIiQQBaAQBNgQAhQYADQwCDAACJAAI.JwACDAACH4kAIgABBAAFpQACJwAACgAEBAAFnHgh+P6WCgEEADD9+/UGlgEGBgK0EgJCAAKIFwIMACMDA4Q2ABMAAQQAAxgAAQgB.BTkYABIAARgAAPYLARUADEgwATAAAVQYAPAwAxUAADUFAAkAAgMMAv0FAgMMBiEAADASAEgAAlgFEf7sbQJXAA8YGBgCEAAPTGIE.DBgYByQAAiEAAlQAASMAAA8AAjQCA/UGLP/+VAABDwALMDAPBAD///8dA9hdANkoBgYGAuwKAGADAZMDAn4DAHwFEP70FwCiAwLZ.BAEGAAUtAAswAAIGABEGcJsDBgwBMAACBAAAYgQCLQAAuAMAfEEC6gMFJBgARwAElC8A0BcB6QQADQAxAAD9xBcCAAwC9xEEGAAA.HBcAqABAAAAF+y4LABYAMQAA/tBlALcAAnQEBXgAAQSJAAkAAGcMAAgAAsoLALNsE/7MABL9xF8BIAECzGACJAADyAQC8wAB2AAA.JwAAEBcSDgkAYhESCfX59bAEcAMGA/r2BQuBbAAYGADCBgAyAAAEAAFjLwAwAAJHAQAaGQAXACcA/AkGEf70jxAJSyQk+/18FwBw.XxMA/SkABhgBSQAANQEx/v4CbDAwAgQDGAAIMAAQBLUAAk4SAqd4ALo8Jfz9FLUAHGcQ/B4AA94AMQEAAgwMAAwAAiQAAQ4ADxgY.BQIYAAALAABTBwDPAAAIAC8CA0hIBhMFhHgIGBgRAwxCAB8AAOULIf4FMAACwpER+8JDAK8CMAMCBR9JAiYAAD8OAAgAAN4qAaRP.BnMIA4QAAIcAAV4CDwQA////BQhXFQAQAAKUEQHhAwIPAAYEABACeCcA8gQA8AkDMAACLQAAAAQBwgQAEwACBAACFwABeAMLMwAA./AMBGQUDyQkBQAUCBAACKgACLQAC9hUAWgAl//5AEQAlAAeiAAIWEQIcFwDnAwQYAAjYJAJhEQNaAAGQAAWKAAMVAABwAAACAQRy.AAPEXwLRAA8kAAMBBQACtQUJYAAAbDYBCQAxAAALAQAg9fUDGIANCQft7fATExgYMPXy+DAeAiUAAkIGAgoAAZwAAmAGCaAXANB9.AMwAARIqA10AABgAAaYABCcwCRgAAntCEALiNQZgAAg8MCMABEuiMgAEA/QXAhsAArEqEQMkBiP9/Z6KAK4RAYURAvwAAvAAAoMB.AsAYAnoBA0kCAbcABTkAAJAAAQ0AAnQBAyQABG0CApwAAhsAABUMAQkAAFQAASEAAW8AAAkAAicAAHgSAZkMADoAAKUeAAgAADIA.ACQwE/3OHwBjBgAJAACoYAFYAg8VGP///w4CVBUApQMBuHEDigMBBAAC4QMA4wQF9B0BrQQCJAACkwMCDAACGwAPMAALAgwAABMA.ABcEBBIAAgYGAi4AAPcEADUQAjAAAGAAAAgAABoAAAQAAREEAgYGAi8AAwQAATYAAgYGAFBMATwAABMAEP0eDAAJAFAAAPv++04A.CHgAAb0AAmw2BhUAAUEEADgEAAAeABIAANEAAaIAAKUAAScAAr8EABwAACQAAA0dAPMABAipAgYGAlEABWASIAsLBhgUC9iuMu3t.8KJ4AHUqKPf4OQAJYAYiAP2jEQD2Bhb/9C8AUTYEGAACwDABFQYkAP45PAAZAAAwAAARAQKcAAASAAIEAAAYfgNIAAAbDAJNAQIG.BgXbVAB1qAAYAAFpAAARAAD9BQHRAQL8AAIoCAJsAAXqAALDAAAuAAQPABMAkBIDAwYBDAAHCgIBSwAAfAIBEgAAJQIQ/1EBAAMG.AEwABjweABsAASQAADcAANsGARgAAMkYA1oAAH+RIP8An2YA7gADSh8AXg4AQgABhAAfATA2////DwUzAwAtAwG9AwWoAwLYCQDI.BAAXAAAFBAskAAgMAAIxAAAoFxH/AwYAGQAAEgAOJAAOEgAABAAC9wQHYAAAIAQBIQwAXDQBxBECHy8CIQADLQAAKJUAuQoADQAE.PAADGAAFHhgEFQAABAABCwQIewADMwACGAACXwoIXAoACAAABAAAJwAEJAAABwAEbAAMSwAEAAwIGAAAAwbi/PcUExHs7e8TExDz.8/kwJAADBgFCWgIzAAACEwDmAAD4BAL9BQIDDAjAkAUEAAEzAANISAAQAAQEAA8YAAkAGwAAOTAAEAACMhkBBAAAcAsFLAEBAAwE.CQAAjgABNQAEVBgBIAEPGBgCAfAGASQAAxsAAE4AAjwGCzA2ACQAAdcBAhIAAksAAh8AAAYABA4lA8QFAIwBAQ8ABScAAd0BAPQX.ABcACaQBAAYGAI8AACEAAD8ABzA2Dxge////EQB1AxD+3xEAMAMQA7gjAuoJAAMGBHgtCHllAMwDBA4AAKkFHwIwABMEhwMQ/Wia.AMEDAPsKAKsJABUAAgQAAkgAADAAAD4EACQAAP8DABoAAI4GAGAAAUUABacuAi0wAA8eBzQXAh4YAgoAAlUdA7AWUgIC+vz6qwwA.cAUAIAAAvwQBCAAAOAQAbAAFGAwAwHgADAAAzAAi//5wIwCVBAAKBwClAAQkAAEZAAGwFgD/BgQVEgJgDARLAAAGDCAQE+oq8wIL.DPvv8fIHCgXw8QAI+wXw8T82kAUGAAUAA/v6+G8LArgXAagAMgL++rUXACUABHARAAwAFPy3fgDAGAYYAADqAAQUARIAwBgBCwAA.mw0AohgBGwAAFwABMAAQA9geFQN4JEH9/QAGsQAhAABzBwAVAAAEAAFUGAIYGFD9/gICATYAAIwBEQFBQwG0DAAEAAD6AAAkABIC.jQABQwAFGBgAhBgBCwAALTAATBoBdQABSGAESVpyAAABAwMB+oYNANQBAvCQYP/9AAQCBTF5AiUAIQD+JDAQABFDADMAAjQCABoA.BHMCAGMAAHaSAxgAFPqMAQEEAAMkAAAEAAFMAg8EAP//9hACMBAACQABFQMD6QQFWgMAfgUAvgMCRwQCEgADBAAAFwAGtA8AEgAB.BAACZwUGMAAKYAACBAAAxAUB+BAADQABBAAAjwoCdQACtAMLLQAAZAAADAAFBAAAnwwACAAEHgACBAAQ/44FAAkABTYAAgQABBgS.AMSzARgAAIEGBZgKArYEAQQAAzYABJwAAPIEAlwEAQUAAPMGArURADcAABIABbsRCAMGA0kFAHkGAEg89AQGBAYGBAb19fARDw7v.8fIQDw4AzCoHBgYAHhIA0ioBgQAAnwABsQAF0wsCdQAAGAABzSkC0CMCFQAAjAABoy8AsQYEhAAANAABhAYIjwELMAACFQAAEAAB.BAADHgADljYBYAAADwwDGBggA/1sBgJOADIA//1BQwKQ0gUFAQLFAQMMAAQEFAAzAARpABAC9B0ACQACIQALgAECPwAAGwABoBQC.WwIBGDwE8QsA1zEAIAgADAAW/XwCAhcAABUAAgQAAZwAAScGA1EAABUADwQA///6AqIDBUMFAuMKAgyoAp0dAFoDAFQDAAwAARwA.ABISA0cEAKgKARMAAZMPDzAADwANAAASAANgAAckAAA2AAHAAwANAAJFAAHQIwAPAAGbAAswAANpAAEzAAXDAAK2BAEZBQD0NQVE.BAONEgEEAAVFAAI8MAMtAAGTBgYMAAF4BgUqAAVpAAANAAXDAAG2BAUkAAKQAAG2CgCoAAPzAAcYGAWQDFP6/PoRD11goAAAAO/s.7xAPDvAMBkUN+vr758AFOQAACQABxgACBhIADwAFGAADDhMAVwACewAAOgABBAAC1gUAhAAB9gwAEwABBAALGAADSAAAGgAABAAC.FQACeAAAEAABBAADMzAi//pZJQEYGAAJAAInAAWoHkcFAwP7iAUAmQAIDAAGzwAATQABMgAAQQECFQAAEwABBAAC7hcA7AEC/REA.PwAAKwIAJwAE9BcBSgABVBICCgABMBIGfAIBJAYAMAAQ/RsBAiEAAIUSB5wAD0VO////AgVDBQANAATjBAJcEANaAwFsAwjvBADm.CgvoFw8wAA4E/AkDYAAB7QMACgAEBAAFogMADQAFBAABLQACMAAAHgAH8AMAFQAEMwAAoAsBxgYCewACUAoCbwwC3gYCGAACNEcF.SEgCFQACqAAIDAAAWgABDwACSAAATRYTAdAdABAABAQAAjMACCQABUQ3BUgAA0sAAToRBAYGAOUFAwYGBAAMUAAAAPDyKiQFAwYD.OQAACwAD0Bc/AwQG6C8CAAwABAQAAxsAAQQAC4QAAX8FAB4ABRgAAi0ABRgAAAQCAaQBAw8AAaiKA2AMAQAMBAkAAE4AACEAAIQA.Ff4DBgUxAgCwGQEsDQIUAQswGAIVGABsAAE4AQNsAAGArwIkACkA/+MBAgQAAV0AAPx4AUoAABIAAwQAADiRDCQGAUgAASQGAgoA.ATQCAyEAADECAJwAAAK1AYEADwQA///tAQwJAgQAAkBZC+YEAFoDDxgYGhACfAsACgABMAAX+kynAkAvADAABGMAA/wDBwQAABgY.Ab9SAEsAA14GAAQABXUAADMAAEEEAxsAA1owAZ8AEgK8LgHJBgJvBgC9AAFJAAKABAB7AAFUMAGFBRIAVQUDc18BQgAALAAlAwMe.BgVdMANIAAEEAAWKAABOAALJAA8XKwEvAANQAQMAJAABIHkCKgAgCAwSKiARBK66EfirkALw0hj7vboBA2wD2AQI6C8BbGAB6gAh.+wOsBQBdADD+/QN2BQAsAFb9Av79AzAAEQhqFwDkAAoYABAFEwUQALglEgLbEQMYAAF7FxIAGxgALxgEpBcRBgRWADYGMgIA+ogX.AVQMEgXcXwFXAATERwMYABQFewBE+wAFAAwAAAnBAD0AAakFIAH9fjABNAAX/TQyBk0CAOYHAFQAAkIwAAQAAhYAAExcBGIBIAID.OdMBIQAADwAB/wcAawARAR8BAFaRYAAA//39/UgAAsgBApB4DqQBDwQA///pDAwMAgQAAXJXAAkAAWYPAjwDAg8AAPMDAIMEBzAA.AVQDAzMGAVwEDDAAKQECYAAHMAACBAADTAUEfwUMSAAOMAABHgACcB0FgxYBGQUAZgACTgAAPwAT/RsAAn4AAJfXAZFBABsAABEA.AfUEAeMKABIAArtfBJgKAGYAAZUKCIoAA04AADE2AHsAAAYGASQAAC0ABCcAAiQAAQsGA2AAASsAAzAGIAYI7AQBEQAzABEDOTxi.AAAA8/HzNd8AEAAC1QoCBgABVgcCxxEA0C8BnQsB0L8A/QABlAUAYKgDtQsA3TcAMAAARQAAMgEA6AsCPAACxEcCDAAgAwHEQQHD.BQAWEQDmBwEYAAhEGQBOAAGxAABjAAG5DQLAAADEQQQ/DAEMQgAMAAYyAQQqAAIGAAAsAQE8QgIwAAKeI1D9/wACASoTAt4AAa8L.ATwAAb8TAykAARoAARsAAPwHAtAXABgAAYYBBcoLAEgAADoAAykBABMAAC8BAAgAAGMGBCcwAl0MC8gBCOoADwQA///yArYEAxUD.AAsABLsdAQQAAzwDB5wJDzAAEQWgBQAjAA8wAAUByQMCBAACNgACogMAEAABSAAADwACSB4BkwYCzAMCHgACBAAG9xcBdRIBWQAB.4gsCEwADGgABBAAQ/y7XAGEvB9QWAAQAEQJ/HQLvFhP7GwAC1AQCCQwERxADzAACMwAABgABKQ0FJAAF+QAFJwACkwYIUQAAFgAx.AAAJzMzGCQwJ7+/vERAR7/DvONkCBgYBMwAAUQAIQAUAtwAAPwYB60EPGAAGAQkAABsAAqwpACEAAHoBASoAAgQAAAINAAgAAZoR.BxgABKEAAmslArEAAGMAAGcRAG8AABwAAGEFDAwACAwqADAABz8ABSQAAAkAAaApBb4FA98FC0waATsBBBoAAD0AAAoAAEgSACQA.BewBBtMXAisAAQgBAvAAAzkAAgQAAZsBA38aAWMAABUAAQQABUAUAA0ADwQA///3DtYFAN0dBd0EAWYDBdgDACMADzAACgAQAALV.AwCrAwASAAxgAAF2QQhRAABCAApDBQPzAwA4AADaBQAhAAHVAwxjAAAUAACABAAQAAQEAAGMBAAJAAA/BgBMBAxwXwEcAACQAAIn.GAAOAAGbAAIEAAWZAAU+BAONAAAUAAEEAAKZBgAKAABiBAC3AAQnAAJfAAJwCwLETQCNAACsBQAYAAB1clIICfj8+I2QABgwAcy6.AhwACQkMB2AwBWyoAth4DxgAAgKfAAIbAAUAYAbJAAGLBQIdAAH9BQGLEQckAALhAAIcBQJFAAIYAAI8AAA3AACDEgUMAANgAAFT.BwARAA8YAA4CuEcApjYFAwYAGAAAPgEDYgEBzwUDCQAPJAABB2wYAOgvAAoAACsAADwAACcAAS8ABLMACQQAAqcHAYsBBl4CDwQA.///hAQUDAgQABaAXAJQFB6oQIAIA/wMACgAEBAADPAMBNQMAzAMZ/7hHDvgWAzAAAQUAAAQABDVqAAwAAPkFBGAAADgABB0EBAIW.AgwAAmgQAAoABFQGAPMDAitGATsAAC1OAxcAAIULAmAAAK0cIv/9kAADkwAQBKMFACEGArYeAvYQACRyAEYAAPERAADqABoAADAA.Uv7+BQYFSEIANyMBZQoAeAAh/P3hcUAA/f37BCUR/kRJAh0AAVAAA+gRFAHMAAXwAAEOAAY4GSL+/hQNAgQAFAUYGHERDRH6BvcF.zF50A/36CgYQ87S6IP0EJHgBBgUAzhAC+AoBNgAAVAACwSMAMDAAI0kAcgAB+RYDfgAC5bkDLYoBlC8CMAAAhAAAORIASwACxI8D.GAAQBGG6AbMAIQD6XBkCGAAFFUgFopABgQAAnOoCHgYX/Wx4AOBbBwwAAEcBADsAAAwABSQAAZMBBQwAAFWoAA8IBSQwAX1JANgG.AAgAAAQAQf3//QZwMgJ9ABH6qRgCLgIDJDABogACYHIAIgA0BAAFyCsADwABMAYACQAAZAIACAACOj4FKAIABAACkQIBBAAGCgAP.BAD//+gJqQsFBAABghECCQAAUwQAeQMADgACBAACNQoACgAFBAAPMAAHD2AAAgLhCQAKAAEEAAJrBAg2AAKeCgC2AxD+VAADXQAB.YAADCQABfAsF+QMDkwAFpgsBBBcCvAQIgQAFaQAArQQIMDACEhIDGBgAVAACD6Ig/f5mAAAbAAVpAAFqBQLoCwCWAASmBQKxAAX8.AAAPEiAA/iEAAB0AAI0AAOYEACYjRQP6+ferulbv8PANDwMGAiR4AE5mANEWABIAADEjAVQAAFEAAaMFAWkMAK4AAHIAANwFCAwA.AD8AAgwAAOEAAPYAAfsLAMEAANAFATwAACQADxgAAgIDBgPAAAGIEQEgAAAhAAB4wAEnAAAMlgFcAQIzAAifAAN6BwEMAAgYAAWQ.GACoAAT0CwBGAQc8JAIgQwAMAABFAACDEwLaAQIoAgJaAAIkMAFjAABCAAXLAQQ2AABCAAogDAMEAAAqAARgAAAQAA8EAP///wQI.JQUBEAAGSQUAYAMEbAMAXAQBSAMMMAACmgUEpgUAcgMBMAAADQABBAADoAUACwADBAAC2wMACgAEBAAANgAOqAMAaAAKjQAHOQAF.+QMADQACBAABMAAFSAwABAADLAABBAAIFwAEKgQyBgQGZk4AVAwBYRcCZBEIbAAAaQAAXAQADAAANAACaQYB9gYJJAAH7AQAvQYA.JAEAJAAAHgAERAEC/QVg8vHvDg8R1xYATwAABAAy9fX1HngSBQkMAlkNAngYATwAAA8AAVgFAkgAAlQAA2wAAQwACBgAAwwABREF.AkwpAUgADxgAAgKsBQK4BQM8AAAfAAMbAAUGAAAyAAGwDQCtAQFUWgUYAADETQQMAAUwHgABAQcwAAiQGABLAAFXAAAQAAI+AQfL.AQQPAACDAQAJAAFiAQAZAAGzAALMEgJCAAAweAEeAAAzAAckBgK0AAANAAEEAAW7AgANAA8EAP//0w/xAiAJpgUH4wQADwACbAMB.bDMFVwAGMAABdgUAMAAEpgUDnAMBKQAFMAALBAACPBIFawQCBAAPtwADCmAABXMFAA8AATsEDzMAAAEEAACEAAGjEQAdBASxBgAV.AAAuQQB+AAISKgIVGAMbHgAEHQAYDAIGBgOlAAFvAAI5AAOxAAWTAAT/xgWTAAInAAJsAAMGBgF8EQMUAQELADIODxEDBgEGAEAQ.8vHwslkARhcDRQADBAABK5wCcgAAPgwBVAACTwUKcAUADAAACQAKuAsAhAABIQAC6AsPGAAIAAwAAEgACWAABQwABQAMAycADwwA.JQh3BgLEBQUbAAANAAHLAQtNAQIEAAEVAACkBwcsAAYEAAEeAAAzAAtgAALbAAVgAA9bAgMPBAD//8oC9QQM9AIAFAAACAAA5wsN.GBgD2QsBDAACvAQJTAsBBAACYgQCGBgOMAAIbBUQ/sB1A34ACRwXAAgAAwQAAKUAAQsEAPYDAYkuArQVC3gAAMYAA0EAAQMGAdsD.AA4AATwAADMAEP44FgANAAEEAADjBAAIAACWAABjAAIMAAAgBABjAACHAAcwMAJISAFtFjEA/PtSAABjJDMIAAE4hQByBgGGFgBN.BAgYSAVxFgL6CwF6GAAkAAB3AAQkACL//r4RAA0AAikNAcYG8AgODxH39vUIFRf49/UGAwHv8/QIAADw8C1CAjEvAufqIwL+rF8B.NBcAGAADmqcA7AoAGAAAOAEl/QZ8LwB2IwGvBQAkAAARAAEYAAAzAAGrAAI4AQ8YAAQBQQAGYAABFwABGAABnnkAgwEwAAADhwUA.qQVC/f79/f8SAI1aEv2gFwKrAAEjAA8YAAQB2wAAbwwACAAAkgcApgUHmAEh/QDAwAGQAAwkMAAeKgAMAAO0AADDACAA/vgZACcA.AGxgIvwFXwEBKywAJAAAYpcAzKIAIQAAzwAAwj4GBgYJqDAACAAPBAD//8NPAwED/yVRHAbZCw8EAAIHFQwCBAAPMAAIAnwFBXID.ACYGC4AuBIIECFQAABQECgwSBkgACzAAB40ACOEJCZMACCQABHEKA7oGASQAALsFAgERBRIGARseAA8MADUAAIiJAiQAAJkAAIgA.AYoAAl8uAgMGAQUAACcGAjELASQAAAUAAIkEAGkAAl0ABvwGAZMAFAkMKsIAAAARAwLv8PIQEA0DBgCKlhAIPDYBCQUA1woFWEcC.igAJVAYBBAACGAAA5AAEIA0CEgADBgABjikASS8CqwYBqAAPGAAICLEAAhIAA9gAB8zAJAACDAAASBIPfBEAADMAB/QRCRgAAeAB.BYYBBRsAAB4ABOwBBdALAwQABUkAAAcAAAQAAugLAB5UAEYAAAw8A/kAAAoCALoABdgAATgAABsABB4AAwwAAgQAAicAAAoADwQA.///3BZkDAA0ABQQAAbYEAgkACLEDANYFDzAAAQAQBQSQAwB6CQ8wAAUC0wUFXQAEBAAG9AUADgAABAADugMLMAAB8wkCBAAIMwAD.YwAPoAUKAwQAEAMjBAAKOwSiAAIGBhH7iI8AGUcgBAPAPAfzAAOKAAALAAEEAAKTAAHaBAUkAAByAAonAAC1BQUYHgTAAAIGBiEJ.C38MAQQAMvj4+/0LAMWdIfz4UgUA9wQCugAGwwABBAACuB0A0QAEGAAAIQAGExEAtAAAGAAQ/WSVDusFDxgABQLGAACxAAcDBgBw.AAEMAABdAAEhAABaAAFbBQF6AAKlAANIAAIkAA8YAAUAVAAKHQEIGwACHgABkBgAGwAAFAAFDQYA5BIAkwACDgAGBAABNR8GDBIB.FgIF2AAAUQAIwwAKewAPBAD//9oMuQQPBAAKAOAKAqMFBQQABLYEAEUDB1EDAgQAAPCxCl0AAHMFAQMGDzAABQYDBgQAKgskAA+x.AAMCcAUHjQAIBAAPMwAAAjAADYQACCoAAoAECWBgB6CtAwkSASQAAnQcAmwGA8AABMMACyQAAA8AAThPAJUEAngAAicAAQsABQQA.8AIJCgv4+PoREQ7v7/IREA7w8ZCuAgMGAEIAAfoEAkAFAQ8AA8MAAswADqMFBQkAAFsAARgAAAkAAcRBAgUBAu8QBKgADxgABAEE.AACpEQdgAAATAAUADADkzAAJAAIMAAQMMACrAAAnAAEEAABLAA8YAAUBIAEMRAEBpAcALAEENAICBAAAPwAQ/zcAAA0ABEkAABUA.AwsADAQAAXYCAXgAAdsGABMAAQQAAngAAmAAAXsAAHgAAlYNDwQA//+/AqYXAAoAAAwtBigDOP/+/6MXBQQAAvAPAAoACwQAATsA.A6IDByMAIAP9YAAAUQMoAAAMSBEDFL4DMAABBAACkwkCcAsAMAAPVDAOB4AEAAQAARLSAnQEAB4AASQGAMMDAiQwBAQAA2UFANEE.Bd4DAAkMAgYMAGMABAkMABsAAE0EAA4AAFEAAQH7AwYGEQPrEQEPHgAPABD+JNkACQBDAAAGAtDXAR8LAo9MAGIEFwDgvgIQ3QAE.AAQjDQAWAAHpBAAJAAFWAAN0MQEMAAIUAQIEAIAICBH6/PoNEUhgwhUHC+3u7QsNC+3v7ZpfAhMBAnBfA/ELASIFAhgAEvpEAQEY.AALc7wIqqBH6FAECExEhAATjuwBFEgOKGQLWBQ8YAAcABQAAZQ0EgEkDGAAQBkpIAAkABOwBAIwBAOGEAO4XARgAIv4A5GABSwAJ.DDAJGAAS/UtgAFcACLRIAAsAEv2NAgJgeAIbAAS8YAEVYAAdAAAEAAAzSAfCBxEANIYBCgAhAP3CKwALABP92AAAYAAj//40pAIy.AAEwSAILDhQCPAACBQcPBAD///4PCQwMCIQDAQQADzAACQEZBQTNAwMEAA8wAAsAYwAK1AoAEgANdQADBAAB+Q8CBAAI3wsDYwAC.CQwFXQAFYAABKgAyAgECkWUCEioAnwYL/goBBAABtDYf+iQwBgAFABMAI4QBvQYACQAB0RACJAACkwYAjQAIhwABexgC3njxAfL6.8hMSE+3u7RMRE/Xy8PhpeAKEAAaRCwDvEAD1RgElEQAdAQIYAAL9CwCEvwJyAAAYMAGfAAAlTQAJAAD/AAC9BgBIAAATBRP+fIML.GAAAEgYA6gYATgAEVAAAYAAAqwAB/QYCkAAAWgABJwAFJCQPJDAIDxgAGgBpAAEEAAUPAAKCAQALAASBAAFYDADnAACHAADP2AEh.AAdTAQKlAAK8DQCbAQIEAgIVAAJCAAImAQGYAQIPAAUwEg8EAP///gNABQALAAQEAAe/BAtFAwhsAwMQAAJqBQUwAATVAwANAAEE.AA8wAAsCMwAA3gMEzAMMBAAFcAUABwAGBAALnQUABAAOAwYBBAAIKgACeHgBGQoAGwADKAUBtAAACQYHJzABaxAAKAABAgEHwAAH.ZgAIJAAFYwAA8AAEkwwIigCSBgQGFBIU7O7sAwYRCGZ4ATlCAAYGArkEAusFAPgcAfhMAhElD0AFAggMAAIEAACNAAGyBQ8YAA4C.DAAB8AAGYAAAgwwCzhcBrEEAOQABGwACIQAALQAASCoIDAADDDALVwAACgAPDAABBQYAABkBAGgHAB4AAEsABPgBAPMFAL8NAwMG.ALcABlwBAFABAs8YAkgAADEAAxsAA3cBAhIAADAAAQwSB5gBBmycDwQA//+0AXoEAAkADwQARAElCgDjBAEIAARFAwHyBAfjBAHG.AwCWAwGjEAHsBASmBQDVAwAOBQMtAAATAAgEAAdABQAPAAQEAAJmAA8zAAAHMAAC0QoC2wMAGwABnAAJMwAKjQAIMAACggsAGAAB.kgQCCQAALAAIBgwAmAQY+gMGAj8AARwABzUGCpMAAmAAADAAACoGAwwAAAQAAicAARQBBQQABQMGEfOEqBH4tNgg+PmkHgKEAAAD.DABjAQAMAACrQgQ0BQ98NQUFfgAAgQABHAUCGAADSAABBAACNAUDGAABjAcCDAAAzBgBSAADrAUAgwUACQACMAACUQAFAAwAIQAB.EgADLQAEDAALVDAExE0ADAAIGAAB6DsAMAAIPAABCQAC8AUAFQADBAACnAAEMEgAJAABeE4ACQAQAVIBAr0ABocAC3cBAQQACPsB.AnRDDwYG//+2AIyyAdACCwQAEAGQBAAJAAsEAA8kKgUTAspLAQQAACYDAAgABqkLAR0AAIxGBD4AJ/0EiC8BvBYA6QoPMAAKBQwA.AmgWBX0EAi0ADDAADyQwBAB1AAQwAAKDBQP/AwK4LwGTAAVgAANjAAUOAAAdAABrBAAqAAA6FgBdAACtABD/kwwCSAAAGwABSgQA.oF8xAwL8AzACJDAAGwAAnb8CExkAyQQBPAAAWQAQALUdAcwAAYQGACoAAUUAAS0MA7RaAI0AAgkMBOQAAHAF8QD+/REQEfv++wYE.AfIBAwEiBVMDAfT19BUeFABYFwDBBQJkXwEPAABw1wFXAABMFyIB/ZG/ADEAEwXAGAA+ASL/+lVHARgAA0gAARgAFvswAAgc8gAD.8AGBAAH4nQAYAAEneAacMEH9AP0CrBcBaAERBoQYAmMABMRHAJMAEQIYWiICAQBIAFkAAmwwEQUaMAJ7AABIYA8wAAMA5DAASwAx./f0G4QECngAX/dAXBfxgAA0AIv/+FQAAawEBNAIAwAAQAPA8ABYAAQQABljaEf5gMAALAAC/AQB8AAIMAAIoAgIKAA8EAP//+gK5.BAkbAwHmCgAJAAHpBACOBQINAAEEAA8wACAJLQAKMAACBAAAGgoEFBACRQAABwQCSAAC+QYHMAACNgwARQAPnAwCD10AAgFKBAW9.BgUGBgAEAAE8SAI/TgM2QgEGAAAbAAc8AAIPAABCAAJIYAFmAAatCgGTAAWNAANrZwHxQQAeAAEnAEQFAgUIbKIAAxIBjAcg9fQS.DAAkAAFpAAAMEhACtgQAlBEBeAACgQAPDBILDwwAGgTwCwOEMAIYAADo1wFgYADAABADGAAFMwAFBgAAEgAHhAwCIB8ADzYBSAAA.HgABKgAAbQAEPAAIDAACNQACMAARAJ8SAhsAAuGQAx4AAbkBAmAABWkAArcAAB4IAggAAU4AAAoAASgCAnQBAg8AAwQAANxoAxUA.AHsAAWAAAA0ADwQA////DQDaBAHSAwOpCwELAAIEAA5wBQAmBARMBQYwAAG9AwCiAwEDBggJBgmgBQIiEQFABQAPAAQEAAJmAAUz.AAVIAABgAA95EQECBAADJAAACwABeQUCAIQBaAAIBgYASgQHOAAFK18CBgAFPDwCJDAAIgAEBAADhgQB4DQAEAACBAAHwwAIkwAI.jQAABAACJwABhwAFJwACh8AR8nKuIAsMXXIy9fTzhwAAaQACJgEB+AQAAgEHcAUPDBIFAcAeDwwAAg8wAAACTAUFAwYFeAAPGAAC.AgkADwwSBQItAAQGAABmAAJLAA8MEgUBwAAPYwACAxIACwQAByEAAeRCACp4AxsMBRsAAB4AC3QBAQQADyEADg8EAP//8g4YAwNA.BQALAAHcEQ+BYwEINgAPMAAIAs0FAgYADzAAAAAOBgQwAASoAwIEAAhgAAa9AwFdAABwBQGgFwJjAAMiAAUkAAENAANjAAQwAA9g.AAIBEAUAhwACHAUCMEgCJzAAo7kB63cCCQwAMAAESgQLzAAA8AAASQAADAAKdxYGjQAABAACigAACgAAugACNkECAwYCciQBGgAw.APX4/JYCaQABEQABBAAHrB0ADwABCgUFJAAPGAAIAI0AAQ8AAuEAAhsAAgwAACEAD4gFAQKQSAIYAADXAASEHgAiAAEEAAgPAAUM.AAJFAA7MMA8MAAUPMAAFAhgAABMACgQABSEAAQ0AAf0FEAN0BwAOAAEbAADgAQQfLAD4AQAoAAMEAAg8AAgiAg8EAP//pAJiBAAK.AAoEAAJ0BAAKAAoEAAkYGAQLAAAULgHpFgANADAAAP/5RgMPAAPK4QijBQCwBQAIAAV7AAL07wNIAwEFAAAjAAE7FgQNAADsBADH.FwHeAwkwAAE8GAAjAAtgAAJwKQcwAADbAxAAqTUAEwABBAAAIQALZoQBVgoAERABOQAABAAA8xUBIQAFwwAC2gAAMWYBLQAANwAD.OwQCBAACmQAB0EcAVXcC07MAdZATBbTYAc+oACQAAMEXAn4AAasYAIYEAg0AAYzNApMAAJwMAmEFAM6OAAUHAmAAALMAApgWAgwS.Ef82inD+/QgLDQAC/Rew/QD9+wH+AgX88/MGDAAqAAQqzAAMACcB/mc7ABEAD0wXAwBkFwAzAAAuIwETAgH+BAEwAAEYSAIcRwJL.AAAVBQJgSAD8SAAYAACSBQJgAAIYAABaAAMjJQBCAAEwSAAJABX/ExkA0AsCCAEAtS8BmQUA6gADVg0AGAAAJwAkAQI3AQD8AARg.SABjAAJISAPDAAFgAAJIABQGqQUAPGAByQAA+hoAWwAALAcEDAABtAACPAAALR8CDgAnAAW8MQCiEwHfUACHAAEwGAJkGgKgMgAi.AAQECAIMAA8EAP//1A88SBQJrBENBAAOSwkJMAAC7woBGREADwAEEAsCBgACEgAPMAALAgQAA/QFB2kAA0IACzAAAlMEAQwACDMA.BmMAAjAAARgkACUABTkABJkAASoAAEioAjkjAvcLBrfeAQ8AAKzXEAAYkAAiAAQ5AAIMAAAEAAJjAAVaAAQJAA8nAAMCGwAA7i+B.AA4MDvL08g4DEiD9BioAJPPzDBgEpTwCxSIBzAADCQABYQUAsTYAIQAHTBcCGAAAPAAFgw0BEgACGAAAGAYEPUEDEgACBgABXikO.GAAAsAAClioJpgsKCQACtgsBnAYAUUMEHUkAmAcFJAYB8AACbCoChDACPwALPFoABAADEAADXwEBzgEAHAACDwAAGwAEegEDKQAA.HQAACQADjQAACwADIQABCwAAqwcCLwYFBAAAkAALyBMPBAD///cJOQMBBAADRgsACwADBAACbA8AwAMBBEEFdQMCBAAGMAABBAQD.3BECiQQAzAMKnAMAvQkHMAAC0wUADQAJBAALMwADDwACSQUEZwUABAAEJQUCbAAAJAABDgADkwALMAAKLQABBwAAjAoASQUAjQAB.XQQNBAAy/fz9IRgDJx4CigAAGgABBAAPYwAEA7EAAAsAAQQAAicAAAoAAB0BJgAAAwYw7+7vxuogAAAGDAF1BgBmAEYEAwD60EcE.pgsAWAUPTBcCAOAEAiEAAbMNADg9BRgADxhIBA8wSB0MCQAFggABTQEI7QADIQAACwAELQABNgAEwwAAGQACwwACJBgFSAAAXQAK.OAEBPHIHfAIBNwIHegAAVwACYAACIQAGPAABHgwA/wABdQAAEgALIQAPBAD///oAWgMEQAsAEAAIowUEBAAF0wUAaQME1QMAGQAB.BAAJMAABBgYIMAAAMwABCQYFYwAGMAACLQAZAC0AAgQAD64DAwJJBQVwBQoEAA8zAAAPMAAKAHsACE0EAX8FEAOXuQCcAAUSGAAc.AAEnHjD9/P1bBQHMAAPAAAAsBQljAAX5AA+QkAIIBAADAwZTDg7y8vIDBiL384cMAI0AAQQvAqMFAC4AAUMFAncBAgEFD0wXAQMJ.AAAWAAEPAAAJAA8wSA0FKC8CSAACHgACuAsPAwYFAC4AARAAAHhgAfAAC3oBAEUABJiFAQweAEgAATIAD2BIAQENAAg4AQJ5FAIP.AAASAAQbAAAtAAEEAAX8AAAeAAoANgCAJQALAAEGDAEkAAi3AAuoAA8EAP//qgIkAwAKAASAHAIMAACJBAEIAAAEAAEAAwIEACQB.AZwKKAAADBIR/8V2AccEAYwFBQQAEf1GEQAKAAAmBABdAwBSAwP0dwCnBCD//Y2OBE4DBtMFAAQAAFQAA852AgQXAmAGABcAAg4A.AJyQBTAAMP8A/+YoAAsAAVgXAQkAAHIAFvyuAwalBgrTBQBrBADOBAAMAAKdBQAkAAHDBgDfBAUVJA8wAAMABgAAm9EAWBcB+BYC.5AABvRYADwAyBQP/KwACBAAi//o+ABD9GQYA3gAADQAABAADyQAAcgAA2goBJQAEOAACkAAAhwABfjwAEwAEiwHADgwO9fX1FBMU.9fX1bQUTBAYMAIQAAvUiAgUAATQFA6YLAWsAAoYBIwL9UQAAGAAB4wQCCQACHAIDFgIIGEgBkwACdwER/cnYAhkFAaeQAEsAAD8A.AVoAAF8BBzBIADUBAQwwAp8wAgYBADwAArsFAA4AAEYBAsBIADMAFP/MMAHKAAB/AAB6AAFSAgEkwADSKhMEzHgAMAABQgAFtREI.PGAAyAsB+x8ASgABMAAAGwAA4AEADAAAUQABWhgFPAAAnPAEDQAAfM4BCwAA9wUBDBgAAQILPDABDgEACgAPBAD///8BCtMFDAQA.ApEFAFoDAuAEAJMDDzAADAK6AwANAAEEAA9gAAsCBAAIYAACRQAACAQBoAUA1gUEygUCsAQCBAAIMwADYwAKAwYABAAHDAAFMAAC.hAYA9wUDegQABAAKSDwEKjwgAwWaCwE9BQAZAAgEAAVaAASTAAVgAABlBwJjAAc8WgB7tAAKAAAEABECnN4FDBgFBAAAbAAFqREB.DQsFVAAPqREJASoABQkAALABAE4MAKwXABQBAFkABi0AApwAAksAADMADhgAAhQBAbkRCGwqACUAAioAAEwAAAgAAGkGIAEC134H.GAADrgARAXhCA+1CCa0HBZgrADMABekBAAYGAgIGABcABckAAjYABTkAA2UAAm8AATwABSEAAD8HAQsADyEABg8EAP///w0C2BsC.oMsChwMChAMACgAEBAAITgMDMAAEDwAAbAMHMAAAPRgAzgMDDwAIwAMDEAAErQQCDAACBAAIYAAJBAAO1gUEBAAGPgQFYwAOLQAE.oAUApQAH2BgABgYBsBwFMgQJABgEuI8BDAADIQADRgAFBAAIZgABBAAAkAAEYAAAEAACjQAHJAACBgYRBZSbAAkSIvPzeusCgPcA.LzYEJQEIAwYCtAADoAUHkAAGCQABKgAJCQABTQEApwEBPAAAEgACQBEBMAAF/AAOGAAAbH4BFgACuREFYwAAlAABCQYACQwBZgAG.sAEEGAAAOAAHkgEG8EgNiwUJVwAFHgABzRcDEgAEYwAFTgAD4AEAmwAAPAAC6gAJOQACBgAEIQAARgAFWgACDQAPBAD///8XBUgD.BF8QAmwDABIACN4DDQQABScAAA0AANEQADQiAgwAAFwEKwECOQALMAAPYAAJAkkFBHAFCzkADOQDAJsGATAABDYMDDAACCAEAQwA.CDIEAJCuACxxAwYGEQO4uQghAAMEAAeTAA9gAAgAKhECGCoBDgAAtPBSCwv69PoJGABkcYX3+/r6+gUFBQMGAaJUAAMMAQ8AAREB.BIULAHQHAbsLAg8AAp0LBmwAAQQAAI0AAcABBRcBCJAADwwADwHrEQMJAAFAEQYbAAIEAAK0MAHzAAn8GABgMAAIAAK4BQMYAAFD.AgDYBgC7AAARAAMYAABfAAB4BgDeAAI7AQJ2AgIGAAAQAAzMBgEUAAMEAAD/AARISACEAACMIAE5AAo8MAAKAA8/AAEPBAD//6cC.8BUACgAKBAACJwMACgAE8gQCBAAPDBgFCAQADjBIAKIDBxQAAHUAAZIWAA0ACjxgEQJQXgAwAAAOAAAEAAAtAABtAAAMAACHAzH/.A/qkpgIQAAB9CwCeHAMCBAAhAALSAAEFAAAEABH/eBgBhwAAHgAA2QkADAAAwAMHkwAAXdYBAQUAuQoB/AAC5AMA7woBIAAAkwAP.MAALEQQwAACeBQCpBgAbAADwCwAHCwgwSAAqAAB7fQCsHQBuBABVBAA/AAAwAATIBAADBgFxBAANAARgAAK5AAM8YAJKAAEXAAIE.ACARDEt48AAABwkGDP7v//cICAjw8PCzBAAdAAMEABEC1/cD8QsCxwEAHkIDfBcDGAARAwEFAUsqAuwWAn4AIAMGqQABEAARAIkR.APkAAA4AAoAxAU4AAvQXAi4CA5gxBRgABPIxEQN4kABpABMEnGAARQAARMEQADM8AG6pGP1QYQDUGQC3WgDcpw8YABESAERDAVoA.ADRKAYEAAwcyAQQAAHQBAS0AC9wvAFYBAUh4AFQAANhUBlQADwwYEQDsGAH5AA8EAP///wUFaQ8ADQACBAAB5goACQACVwMEbAMC.BAAPMAAJDzxgFAUEAAECBA4zAA51AAMEAAEwAAIEAAgkAA9jAAYPMAABAi0AAnUAAycGATBIAgwSAAIfAWmQArI1AicAACQAAEMA.AFoGAAwAB/AAAAYADV0AABUABSQAAQQAAkVyAUh4cgjv8O8QEBBvrgAcAAEEAAJpAAP0EQVJEQADBgcYAAEhDAP0BQEwAAKABwAV.BgLJAAEEAAUwAAJUAAIGAAAZAALxEQHrBQVCAAwYAAQPDAUeAAMJAAWTAAftAAAwAA8YAB0AbAAAnjcDVwAC0gATAQg2CAQAACEA.AYMBAE0AAlYBAlQAAB0AClQABEUMADMAAbQAD3UAAAFlGQAKAA8EAP///wQGtgQFBAAHvwQLSwMBTgMPMAAKBNsDAA0AAQQADGAA.By0AAgQACLoDDwQAAA0wAAIEAA6ZAAMEAA8wAA0CkAACdQACBgAAHwABDCoCMEgCM04C/goIIQAAuwoCCwANYwALXQAAuwoKCRIC.AwYy+PryaahlEBAQ8vTyyWYAnwABaQADiwUC7AQATx0DqQUDGAACMQUHAwYDPQABBAACEgACBgAAMAAA3q0ADAAA5wYBigACGwYP.DBghACIAAJMAAn4ABe0AABsAAasADxgAEQRZAADkNgVUZgAqAABtAA/EBQ8ABAANVAADkgECBgAPPwAKAmgfAAoADwQA///3CCED.A7YEAAsAADQqBewWAhEAAioAAgYAABAABeYEAw0ABhwXAA8ABIcDCDAAAMuIBQMGAkwXAaARAA8AAQQAAIwED8w5CARdAAL8AwAK.AAEEAAljAAgEAA8wABMAdQANbJACVHgIAAwD7C4AEQAAXRACWgACwwAFggsALQAEXQADHQEC5wACLQABBABlCQoLAQIDbK4CgR4O.AwYACgAAVgEA7AQCDAAJGAAC1QABDwALGAAFQgACBgACEwACDAAIBgACJwAAtwABEgAAJQAB6gYF+gUACQABQBEFMAAADQADkwAB.fgABfwUA5AACGQAPGAATATxgBWIAAFoAA2AAAr4FAgYABBsAACUADbABAAQAClQAABhCAjkACgwYBSEAAKHHACAlABsADwMG//+2.AnQEAAoABHoEAgwACAQACTBIBwQACBgYCzBIA7YEAA4AAQMGAQkABDVfAFQVIPoDIgUBDgAAXGoPMAAMKgMDPBgvAAAwAAoAjwQA.DQAAvQMAGAABOxAAFQAB5i4DIgAAEAAA4QMADAAEfBcCIwQPDBgYDjAAASVHAkYXAEAXAToBIwMFaX4AUARB/P0AAasYABoAAFQA.AggAAJELAOYWA2MAAGEFAV0AAOAAAu0AAmUAAHcAAAgAAjaK4BAREPj4+BEBEe/v7wgADBgApwAFvBYiAwM3AQFdACEDA7QAAFgv.ABcAAE8AABgAAuYEARsAAP9+AawFAEUAAhIABScYBBgAAPwAEAEy2QANABEB9BcACgAAFAEATAUBawEAWX8g/vqkAQEJEg8MGAYR.BRUAARsACYgXD/QXBAgMGCH9/RgAAk0AAKg8AAoABHgAARQAAPowAAkAAxkgARQBDwwYGABvBwAJAAATAgD5AQEMAACV3wAJAAIE.ABECgEkACgAPBAD///8ECdMFAgQABEkLAEsDBN0EAxAACwYMAgQADzAAKAIEAADaBAJfBAEEAADtBh//GAwBAaYFAgQACGkAD2MA.AAIEAA8wAAoCdQAABgAc/i1IAgkAACsAAQQAAAQFAAgAAAQAADQREQBLrgfDAAO8BARjBgCNAArkAAJ1ugAMGAEGDA8MGDUACQAF.EgABCQAFGAAPACoJBEAdIQACFwEBYAAATAUAZykAyQAAACoESAAAUQABYAAAIQwCEgAHSgEGqwAKYgEPGAADArULAIUAARUAAk4A.AcBmAxgABwQAAHgAAY8NAC8AAbABA1QAAB0AAT8AAlQABQQAEAKvCAK0AABXAAV1AAEEAA8GDP//tg8EAEQCEAUACgAFBAAHvwQO.bAMPMAA7AgQAAPADBL0DAgQABkgADS0AAgQABiEACwQADzAAFgJ1AAA3CwAOAAkEAAsMEgVABQAcAALlEQFmAAWRBQAtAARgAADw.AAL4IgcPGAIDBjL49/gJEg8MGEIKRU4AEgAPDAAEAN4LBQsABRgACgwSBjAABxgAIAP+fgAJSgEBqwAClgAPGAAPBQMGAU0AA2AA.AFoAAxgABnUAD7ABAQ9UAAMHBAAPPwAIDwMG////AgghAwCzBAWjBQfgBAAPAARLAwIGAAISAA8wADsCBAAIvQMCBAADQgACMAAB.0BEC/AMAHAABBAADIQAACwAKBAAEXQAPMAAOABwLAqZTBfoLAS1IBgkMBJYACZ8AApMAAWYACGMADGAAAicAAYoAAnjAPwERAQwY.bwKFBQEGAAISAAIGAAIuAALrBQISAAMdARD+URMCGAAAIwAB8AAP9BcIDxgABhECeAwOeAABEgAFkwYDFQAACwAPsAEADFQABWwA.BAQADj8AAnQ9AI8ADwMG//+1AB8RAAgAAAQABXoEAAQAB+8QAv4EAgQADyQwBQ8MGEsPMAAcAGgEAajwBb0DAgQAAsMDBTAAAjsE.AAoAD9wXCAMLAAEEAA8wABEAjjUAJAAkAwQhWgExAQk8YAGYFgJWAQI8AACeTAAOAAAeAAJjAAK6AAhgAABdAAAIAAAkAAIsAPID.CAgIEA8O+Pf1EQ0J7AH9+PP4fgwCJJAAsUIXAgAwDwwYRwHhAADDAAX8AAKUFwAhAABpDAmoeAJokQGCGgBIMAC4BQAXAA/0FwUP.GAAFANIXD3gABQEYAAUYMABQAQAcVQEMAANQAQAMAAA8ABD/JEgAkAAAPgAPMGAAAzMAArABAbgCBZxIAQQAAD4BAAgADwQA////.BAmjBQIEAAHjCgAJAAJXAwRsAwIEAA8wADsCBAAAvwQBSQUADQABBAAJSAAFMAABMgQCBAAIIQAPYwAAAgQADzAACAGPBABXABAB.TwUs/fwPGABMBQokDAM5AAJpAAWTAAQEAAVgAAMkAAsGDAEVKgA5WgFCSAIkSAL2AALlEQgMAAHvCgIJEgMdBwMYAAE6BQbxBQEy.AQIWCwASAAEJAAUYAA8MGBoACwAPqHgKAB4SBAwAADMAAeoAAA0ABasACmIBBcMAAUcSABUAD3gABQXAAAEYABADP64BDwABKgYD.DIoCxxEIkAAAPwAFbAAPRQwUDwQA////CgOzBAALAAQEAAfgBA5LAw8wADsCBAAAvQMEZwUCBAAJSAANMAAPaQACAwQADy0AAQ8w.AAAHowUC5QUCdZYJGCoBCQAADwAEWQQAzAACPAYBZgAIvwQFYAAAJAACnyQEYAAGAwYQBxhIAiRIAGAAAbMEC3yVAOsFBEAFDwwY.WgEEAAgPAAgMAAIDBgBjAAGFEQLqAAAZAAGrAA8YAAUMYAAPeAAHBQQAAksAAAoAALMBA8cRAgQACDMAA2wAAlEAAgYAClQAAyEA.AAsADwQA////BgghAwOzBAALAACfCQXgBAIRAAIqAAIGAAAQAAvTBQJJBQ8wACgCBAAIMAACBAADEgAHMAAIHQQFaQADDQAIBAAB.LQAAIQAPMAALAVoAADUEB+gLAjlgBg8AAQkADzkAAg6TAA8nAAME5wAAYKgIJEgv8/OvBQgFQAUMGAAE6AUOGAAFEgACBgACEwAC.DAAIBgAD/QUBBgACEgAIBgACRQACeH4CDAAGYwACJB4B8AAJiBcAqwABlgABAwYJGAABPAADWgABcgACfgACEgACBgAAKgAKBAAC.SwAACgAAswEMAwYAzAwBGgEAhAAAVRIAUQAAVwABJwAIVAAMjwEPBAD//7UPDBg1BUhFAAQAD6wXDQ8MGFEADQAEvQMEpwADwwME.MAAPDBg/AbUjAW4QAPoRMPr++pEXASo2JAYADBgBxngAoS4BDwACPAAA0RYCHAABowsAawABugAIYAAGjQAEzwDyAREMEfX19QkE.Cf4I/vT/APhFigG0BAJtHQCILwHERwDuCw8MGF8CtwAAONkBAGABkwAhBgYMGAIYMAWULwBYBQeIFwf0FwgMGADkVAKWAAKQAA94.AAICCTECwAACpQAAJQAhAABQVQB1ACUBAAh5AB4AAMZgAAgAADeRAmwwAg4AACcSACcAAAIBAOIGABQACyRIAJIBAAgADwQA////.BgmjBQIEAAHjCgAJAAQ6BQIMAAIEAA8wADsCBAAAvQMBdwQADQAPBAAIAUoEAgQACGkAD2MAAAIEAA8wAAsBlQoGLa4FZwUC/QsB.rx0CCQAFEgYDOQAPwwACBGAAAyQAABiQABgAAgQAAi1aAHsAAC8FIgDzAwYANwAAYREBCAAABQcD8REAWwsCCRIDoAsDGAABOgUA.MQUEMAAAOQAENwsCQAsFGAAPDBggCyRCAAwAAA4AASEABZMACkoBAO4LDxgAAQKNAAAVAAeQAA94AAIFKgAALQAP5AwBAgkYCxUA.AD8ABGwAA3EBDyEABw8EAP///xEFQgMADQACBAAH4AQOSwMPMAA7AgQAAL0DBGcFDAQADS0AAgQADmkAAwQADzAAFxMDrBEAfgAB.cBcjAAWo8AL0BQISEgAGAARZBADMAAHLCgLDAAm/BAtgAAEhAAAJAAEEAAIDBjL3+fdFfgADBgJqBQIGAAS/BACgBQ8YMG4BBAAG.GAACBAABkwAAYwAB8REG6gAPGAAEAhIAAVYAB0gAD3gAAg8EAAEAtAYZ/QweCzMACGwAAJUBAWECDyEABQ8EAP//+AgVAwgMAAVC.AwENAAEWBQe/BAIqAAIGAAAQAACTAw8wADkCBAAIMAAMBAAELQAFVgQADQAEaQACDAAJBAAPMAAXBFA6BTsEDwwYHQAPAAoEAAPt.AAIkAAGHAAIEAIALCwv6+/ry80V+AA8eI/TzcwUBZBcAbAAEhAAALgABWAUACQAK+AQAJwAB6AUACQAKGAAFEgACBgACEwACDAAI.BgAD/QUCBgAAIwADNgABCwABBAAPkAACAPYAD5QvBACrAA8YAAAAEgABPwADSAACcgABBgACEgACBgAAKwAEBAALEgAF0y8FBAAA.GAYK1xMAFgAHYQIIQgAIIQAPBAD//7kPDBgqB4TADwwYThcCMAAAidYFMAAe/zAAAKEQEAA+BAKxAwIpFgDhAB//JEhPARUAAGoL.FALYSACFFgZ4wABHABD886gCEgYAIQAC8wABAwYIYAACXQAAHQACHQECZQAHNQDwAREQEQYEA/X08v4FBAAJC/NanAA/AAAIBgGf.ACQAA5jBAQYMDwwYCQGcAAN+AAEEAAPhAA8MGBMASAAQAg8AAN4AAQlgARgABGYMDyRIBQ8MGBAFsQEAVhkBjQABSAABkAABigIA.DBgEwwAPwAADAXsABALCAQwAAiTAAQsAAMkAAgkAAUACBYQABQQAADYGBVYAAI4AA5AAAKgAA4ICDwQA////BgnTBQIEAAfjCgXd.BAANAAEEAA8wAAwAYXwPMAANBQQAARoEADYACmYADnUAAwQABDAACzMAD2MABg8wAAsCrAsEfQQCbRECmwQCNwsAngQKDBgDBAAF.8AAEYAAFXQADWgAKFAECBAACS6JS9PjtDQ0DBgAVAAAuCwFACwBAHQXxEQBbCwIJEgCHAAkJEgGrAAkJAAGCCwBMAAEEAAUYAAgM.GAAZAAEEAAVIAAA5AAQqAAARAQUYAACUBgAVAAVIAAMJAAWTAApKAQW0EgE4AAAVAAJjAALYAAhmAAIYAAUSAAIGAAAPAA0qAAAM.AAhjAAE8DAAJAAcEAAmEAAIEAA9UqP///yUCBAAGtgQFBAAHvwQObAMPMAAMDwMGAwcSAActAAUEAA5mAAYEAA8wAAEAaQAPMwAF.DzAAFwIDBgpwFwUDBgAzAAH9BQVsigYzAA1jAAVdAAHtAAGQDAFmGAAcAP4CAAALDA719PILDA4O+vjy8vUDBgAJAAeEAAVYBQCi.DAgYAALdBAHpBAUJAABGAA1IAAIVAAIEAADSAAcMHgUYBgsYAAsMHgxIAAGTAAJmAAXtAAUYAAE4AAkwAAIqAA4YAAUSAAIGAAMT.AAEEAAOQAALGACABAzMMAAsAAFkOBQgBACgADwQABAghAAmiAA8EAP//+ggYAwgMAAO2BAALAA/jBAACKgACBgAAEAAD0wUKEwUA.CgADBAAAXhcKAwYMBAAHXQAFBAAIYAAMBAAEMAAFVgQADQAP0wUCAgQADzAAFw0MGAAVAASkBAAzAAEDBgIVAAMEAALwAAFjAAhg.AAVdAAMdAQInAAGHAAA5eAEDBgJaqA8DBgABewAFdQAAFgAEWAUAIQAIGAAInAAECQADGAAEJBgADQABBAAFKgAAHgAPDAAOBPoF.AAMGAUgSBhsAAgQAAJMAAa4AAbQMAOQAABYAAQMGAScACzAAACoAAQ8ACxgABQQADxgAAgA2AAT5AACGEgQLAAmrAA/LAQIPIQAQ.DwQA//+zDwwYZgfcFwh3AABtAA4wAEb/A/oEMAAyAPwDj7gADQAEzJAAJwAA4gMBDAAKTBcCaxABGAAAzRUACQACBAAP3BcRAnkF.AaAFBuspDzAAAQAtAAA0AADeAAAbAAUMGAEEAAYkSACBLgMoCwAvAACmFwRjAAF0BAAkAAFgAAJdAABAAQJNAQBlAAAdAAI8APAF.BQoI/fYAAwb9ERQI8/TzC/z99fdjqAB7AAS5BACuAAQpARD+cAUAFQAADQAIJBgAEAAGBAACEAID3gABfBcAtBIg//3cFwEpAQDs.AQskeAQYABEA9BcAAzAAL3MfAjBgDwJRGAAaAAmgRwLAEgAwAAJuAQSoAAWRBQDYAAEZAAsYAAAMAATsAQBOAAFgAALJhg8MYAMB.p4oACgABlAIAYBgCDQAC+wECWgAA1U4AFAAC2gcACgAFBAAC9gAPBAD///8HCQMGAgQAAkYFAAoAAG8DCdkRJgEC0wUOBAABawQJ.BAAPMAAdAgQAAQcXAAkACwQABzAABXYFAN0EAsMACAMGACMADwQAAwPwAAItAAE82AA+BAhtEQH9CwBYHQAvAAPjBAELAAEjBwhj.AASQAAWNAANdAAAUAAGVBAFjDAIJKjHy9PIXAE8ACwkIAwYABwEjCQ0LBwQABi0ABQkABCoAAjMAAE0fAEgAAOoGC4cAAAoAAvER.AeQAAO4LAUIADxgABQU2AA8JAAAE7QAADAAFFQABCQAGSAAKBAAFGAACRQAAGAYEKG4FOwEAUQwCzAAFEgAHBAACOQAACgAEzgcC.DAAFBAAAAgEBigAADQACWwIEUAEPBAD///8RCLYEDwQADw7TBQUQBQ+cAwIPMAAKAgQADzYAAAgEAA0wAA8EABUEoAULVgQD8AAF.AwYE3QQAQB0LGDAB2goC4wQAOgAALAUBNgANkwAFYAADXQAAFAAGBAACAwYAYMZD/v/19v0FCwQAAM4iDUuWAmQLC0AFCQkAASoA.CQkAAYoAAO0MATwAABIAAmQXATAAAEsAAagAAusFBUgACxgAAQgAAxsAABUAAQQABS0AAA0ADwQABABIAAGltAIqAAUzAAIYAAhX.AAUyAQA3AAoEAA8bAAIFOQAARQAPIQABBQQAA+xzBN0BDwQA///7D1oDAg8EAAAH4AQAUQ8IAwwAwQUAUFIDDAACBAAIMAAOYwAA.AwYLEgAGMAACBAAPmQAVBwQADzMAAALTBQeNAAgEAA8wAAUAOgUBqQsCXwQMGDABAwYCfwUAMwAENgAPxgYIBQMGCLMEAgMGFAMe.YAsDDAEcUwMDBgAWAAjQBQEhAA9ABQAECQACMAAAEgATAigRBYoABS0AAB4ABQwABOIFAOsFCMzAChgAAAkADQQAApYABWAAASwA.Az8ABkgAAQQABQ8ABQkAABYAAQQABRIACEgAAAQACiRUAkQBABgADwQAAQw8AAeKAAIPAAAEAA2kAQ8EAP//swL8FQAKAA8MGCsE.4xUBBAAIVKgEIAAAhwMB3BcAaUUBXC4GcgMH/zMAUAAIFhEBvQNI/f/9BaIDDzAABQH8FQIEABcGVKgCDBgHDwABLQAB5AMADwAB.aQACIgsCJAAA7woCDhYIXQAPMAAWAOEAAXMFIfr/DBgBkS4GJEgBpF4AQgABDwAAmBYBNgAIaRgAHgAIjAECBAAB6sAAlC8ADQD3.AQAGCAb9CxD3+/8NDwj9//B+9hADuAQBSgAQAFZfACkBBQYMABYAARsAAizZBDAAAGwAAgkAAPcRBIOXAgJ5AC4AI/0Afl8ByrMC.hAAA1QYAJBgARAADOmUBGAACCgIzAv0CFQAABAAAGAADYAAB5AADWwUEoEcAMgEBMB4IHqICCQAFXAECDwAAbQACCQAANjAAMwAA.2SMHqAAASwAACgABwwAEYAABfxkHDBgBPQIAbgEQ/pXaABMAATwABekBAgYAAiEAAAoAAXjwAj8AAJBCABMABCoADwQA////BwW2.CgANAA4EAAFEBgVABQJDBQYwAAQQBQAMAAEEAAKVBA8wAAYPBAAECDAAADgEAg8ABV0ABcADBfYDBGwGAgwAA2MADzAAIwIMGAEe.AAMYAAAKHQAGDAIMGAMMBg8EAAIEYAAIXQAABAABWgAAxwUB7ARiBQUF9wD3LWwA4ARDBwX7+Q8MCCsFAKkGDQkSAlcABpkABzAA.ApkAC3sAAAoFAVhBCEgAABkAAAIBAGYMCBgABTwAD2YMCA8JAAABNgACkwAGFQAEiC8OGAAAugAClBEELwECGAACMAADEAACEgAB.MwACDwAMBAAK9C8AJMkCTgACBgAA1QEEAwYA6gAAogACDAAABAAFJAAPBAD///8HArQDAAoABQQADTMDBSwEAGsDCDAAAewEAAkA.DwQABwZgAAItAAFUBgsEAAhgAADkAwIPAAUwAAWNAAc8AAgzAANjAA8wACMBLQAFHgAMCRILBgYCMwAFYwAEYAAFPwAADQAAYQAA.CAAF1AQgEREzhDAREBEYQgF46g4DBgAMAAEJEgKjBQAcAAG0AADAhAHGJACxAAcwAAtyAAUYAAtIAAXrBSoAAGDABBgAAjwSDwMG.MAEVAACLAAEEAAUYAAANAAI1AQEyAQUYAAJFAAg5AA4bAAAxAAQEAAUeAAANAAJRAAAKAAcEAAtIEgXUrw8EAP///xMCzAMACgAF.BAAF4wQPBAABCzAAAmUEAAoABAQAC8MDBjAAAboDDjAAArQDCDMAAwQAATAAAMcFD40AAQtmAAAEAA8wAAoPBAADFgEQCwJ0EAID.BgAbAAEEAAIJDA8YNhED5AAHBAAFtgQFAwYw+f35GQAPAwYEBQQAApMAAAoADwQADQUFAQJIAAEEBQMDBgAfAAHhEgDeAA8YAAUB.NgAA1wAPAwYHAC4AAQQADhIACCcAAooABuwBDwQABAswAAATAAQEAA8bAAgAFQAEHgAAEAAChgEEzAAFBAAC1QAACgAPIQAEDwQA.//+zDwwYKgcwYAgEAAm3AwDLFQAIAAAEAAE7AAONAwEFAAMEAAVHAAFpAwDPFQESAABcdgSYFgiEAAbALQswAAqcMAAGAAEEAAJL.EgBIAAEwAADbAAEwAADjEADHAAAMAAj8AAbAAAIwAAAKAAEEAAfMAAD4ggKZAAHGBQAJAAEeABH+cQQAYgRB/wP6+gwYEAFRlgJI.kAAhTiAAAzxUBH0EAAwYBQMGAKcAABUAANwRBygvA40AAuoAAAoA9AUACw0L9fj1Ew0Q8v7v/fb1AwQA9VEAAPVGAhBHAhIAIQP+.vokBiS8A8QAA+AQAYRcCRAEBCAEA7cEL9S4DOjsALy8AGAAAuQEBhAAC8REA3PsAUAAAJEgBIQEGBgwBZakAAwYPbBgGAEcAAK0B.AUUAAA0AAB0AAKgwBjAAAUgMAgUAAFoYEf1vYADUAQDYAABmDAA89gAtAAC2SQX0pwEFAAMEAAHYAAA8AAMIAAaQHgJmAAAVAADV.AA/oFwcFwEgBeAACIQAGJAACYAAPBAD///oPZgkCDwQAAg4qAAZwBQA5BAFzBQIQBQETAA8wAB0CBAAONgAPBAAOCDMACWMADV0A.AgQACDAACQQAAjAAAdwdBYVBAgYSAgYAAH0EAQ0FAC0AD8MAIgAqhHAIAPD1+A4PCRI18vHwTrQAHwABBAAASQUBeQUAjiMB3L8C.BAUGGAAIuC8CeQUAV94BhwABjQACEgACBgADnwACBgABMQADGAAACwAJBAAFtwAJRAEEBAAFNgwACQAACAAEeAAL1wEFkAAACQEG.shcBDgABGAAC4kcBBgACKgACBgAIqAADEgABOAAPlgAAByk3Ax4AATYAABAAAgQADiEAAAsAAQQACyoADwQA///0CCQDBmYDDwQA.AQAqAAC+AwAMAAIEAAkwAAUQBQANAAAEAAAwAARaAAIEAAkwAA8EAAQLNgADDwAFXQAFwAMHzAMDJAAACwAEKQQOMAAHBAAIMAAD.BAAHMAAAbwsBeAsAQQQBNmwAAAwBAxIFmAQPBAAYAloAB4cAYA4PEfLx7zl+VQ8Q7PPyAwYF+AQDyC4AfwAAQwUIGAAI0C8I3EcA.zwAC7BABwwAAZwABGAAASAAEGAAFSAAAMwAB0AUICRgCMwAIBAAFMAAAEQEAI1sAMwAAPAAIGAAB0DUCdAEIMAAAeAABCgABxgwK.GAAB/QUA5QsEFAEAOQAj//0mAQHAAAASAAEzAAAfAA4EAA7oFwAWAADkAABCAAAeAQ8DBgcPBAD///8ECCQDAswDAAoABAQACCAE.DpkDDjAACAQADkUwBjAAAhkFAfADAA8ABwQACJAABsMDDjAAAgsQAQQAAyQAAAsADwMGFwGHAA8EAAQA3QQAQQAAJAAIAAwAdxAF.AgECYwAACgAJBAABXQAEJAAAjwQGJwBVBgQG+PwADEnvBgYGVMANXwEABgwIrC8BhAAPDAACCAQADxgACwDbAADEoQDQBQgDBgBx.EwAYBgPZHQUwAAAJAABwBQY8GAUYAAAbAAHtAAIzAAgYAAMEAAFUMAwYAAIDBgdgAAAVAAoEAAUbAAxNAQQEAAK0AAAKAAKGAQGZ.AA8EAAIDJAYCIQAPEAIEDwQA//+qDwwYKgSgRwABvwRTEALMAwAKAAIdABD+y/oACQAC2u4FbgABmBAA3wQFMAABTBcAIL4COQAB.ZHcIewACBAAGYAAOMAACFBYACgAJtAADBAABMAAP7QMFDykEAAEwABEDCi8ACgAAdgQHIQABsC4ACQAACQEBMAYDDQAEOwGwAQAC./wICBgL6/fp9wQK3LwIuBSIA/WwAMP4C/sAAAEIAAB0ABe0GAEwFAAgAAAQAAO0AAJgWA7cA8QQICAj3+PcFBwgLDhH37+wFBAXz.dfwC6BECewAAcEcB/gQD6BEAnB4BfF8RBBYFEwRzRwAbAAEwAAC0MBAA6qgAOgEBmQAEruoQBZMAAwwAAECnAP0FAAgBATwMARgA.EgIYAAFGAgCUFwA+AAFEBwFjAAQwABMGbwwwAQAA9LkD3BcBLAAAHwAACAAA1gUDGAAhAPygFwLDAACxAQNTAQXYAAMMGAQY8AnA.ABAACwAAGQIEJBgARggAIDEAHgADqzAAUAEP6BcAFQAkqBACNQAACQABBAADCEkBBAAAeAAACAAPBAD///8cBzYJD2cFAA4EAA8w.ACgCBAAA/wkBcwsADQAOBAANMAAPBAAJDy0ABA+ZAAgAfgACuRAHhAAADwACFQACwgQBBAAAKAUHMHIAEwAEBAAFYAAAJAAFkAwB.igACRaIAAxIBcuQAEwAEBAAAXQYBxQcCaQAD6xcC1BYAIEkDNAsDGAAExCMAaAEBGAAAQwACBAACMwAKZAsC7gsACgAKGAAIBAAF.GAADtwAAFAADBAAFGwAADQAPBAAcD6gAAwAzBgAIAA8YAAgFBAACfgwGwwAE4QAALwAEawEBjggDIQAIUQAFjAEADQAPBAD///8a.AtQEArkEAgwAABYAA9MFAgYAAREAACG0Bu5HDzAAEQgEAA0wAAIEAA8wAAYHBAAFVgQADQAEaQACDAAJBAAEXQAPMAAVBAQAYgYD.Bvr9+gYAADAAD1MEBQLDAAeOBQAVAA8EAAoFAwYCBAAAMHgACAAABAAARQABZgAIwgQFKE0AewAIGAACdQABDwAJMAAACwUAPxgO.MAAFBAAFGAAGVQUPBAAUBTNCAQQABUgAAK4SAgkAAQQABhgAAQQADKgAAuUFAQYAAhIAAgYAA/0FAQYAAxIAATMAAL4qAEcAA8Aw.AAsACBQBB48BBSEABT8ACyEADwQA////GwI6BQLgBAGfDwIEAAK3DwlUAwDuRwoDBgAKAA8EACoJYAAFBAACXQACmQAC/gQEBQQP.5wMDCjAACwQADzAAAAEEAAg7BJIAAAAGAwb+/v4SAAMTEQCUEQo8AAFjAAiQAAxdAAKKAA+HAAFQDQwN8/AYNgANAAHvBAJsAAIP.AAMEABACeQAPGAAABzAAAAkABH4AAA4BBBgAAAwAB0ALACcADxgABwIGAADHAQQDDAUSAAAJAAJgAAEDBgAPAAQYAAIqAAIDBgkY.AAFIEgAzAAEPAAYYABD/GysD6wUPFAEBAgQABUsAADYAAasAABYABQQACgweAP4pD0sABw8EAP//0Q8MGCkAhwMBCAAA+QMEMBUA.1QMB1wQA0wUKrBcIMHgCsO4AU14CBQQAQwAACAAGJGAlAAMXpgAdABf9YAAAEAAADAAAJwAEMAAAwAAAGwQDDAACbwYACgAC9i0D.PgAAIwoANgAAGAUBnhYBFQAILQADYwAHMAACvgUASSMHIAEAWy8ACAABLQAE4QACygUA/R0BgAQBbNgQ/C1UADkBAxI8ANwvAAgA.AQGPADUAACwBAmMAApAAAgMGAmAAAF0AAAgAACQAAD+cYAkJCQgJA8IEhAPz8/MLDAj1G0gAlJUB+AQQA0wAANBBAckAARsAArIB.DiRgAhgAAREHAgkAAgECAEAFAzB4AVMLABoAEP7IGQKpFzABAP0YeAALAADCDQIk8AG7LxH61AEABhIKPJAFUBkLDB4jBQHcFwt8.CyQFBRgABasAAQQAALDBAUoBAsMAAjAAAO8AEP0VAACsAQQxAgLMGBL9IDEBFgIIDMAAzAADkgABzAABCQABzwYDVwAFPEgAExgF.LCsAEQAHCQAPBAD///ECqgQACgAPBAATDzAAEghsAw8EABENMAAPZgAMDTAADwQAFQFTBAIEAAhjAADvBAXDBgE+BAD+NAGbBAAG.DAd78AWH8AI/AAY5AA2TAAIhAADmBgIkAA0GDCAODSRUMO3u9w0ADwQAAQmjCwKWBgQg6w8JGAgGEgAFCQABigAAjQYBPAAAEgAP.JFofBRgABQkAABsABwQAADAAAZMAAA0ABwQAAhgABTYABQkAAhgAAV8AABIABRgABcAACfwSAcMAAJYAAQ4BABIABDAAAAwABB4A.ACsABQQABzxIDwQA////IADXBAsoxQcMAAXaBAANAAEEAAAwAAIHBQUEAAgwAA8PKggPBAAHDmYADwQADg8zAAYHjQAIBAAPMAAG.BAQABZUEBfcFCw8GDwQAJlAODg7y8iRmZgsICAAAAAMMBRAFAOAQA6YRAxgABBkFAiEABkAFChgAACsADwQABw8kABEPBAAFCzwA.BQ8ABQkAABYAB4cABQkADxgACwUEAA8YAAAAJg0K0w4APQIPAwYVBSEAA3gSCoAHDwQA///4BTwDBQkAABYAAgQAAjoFArwKAgwA.ABYAA28DAgYAAREADwQADACEDwoDBgwEAAddAAUEAA9gAAkEMAAGLwoBBAAPMwAGBDAACwQADzAABQU7BAANAAQEADIGBQYbQgAN.AAR0BADMBgcMJAiQAAIhAAbwBgJHAQSHAAI/qCAD/wMwDgMGFAA8YA8EACkAjQABdwEFigAAFgAEBAAG5AAB4gsDCQAIeDAKGAAB.CAAEGwABBAAFKgAFCQAAFgAHJwAFCQAPGAAUAA0ADwQABAHgEwMUEw8EACcBpAEACQAPBAD//8cPDBgdEf9MCQJWFgJ4LQAWAABg.LQrKawAgAAAIAAbcFxn/MHgC3BcA5gQA8AQB6QQCbAMAFwAAIQAACF4HhgQDEwUACwAEOR4CMAACoRYCBAABjBYCBAAB/wMACQAA.QgAIMAABu0EAGQABoHcAmQABZgAA7xAAPRcHwwABBAAAaxYEAgEIIAEC4hcDkwABBQAAaxEA7wsDKBEwBAEElwsBy14CGwAAGAAA.GgAALQADBAABZQEFYwACshEAsQAAEAABBAACugAEfgD0BAYKBvj7CwD6/f38+AgECP0A+vtvTjH9AQVlAAB/FwU0pwDQBQGNAAIx.BQVEAQsYAAIsAQJ4AAgkYCAF/k4MMAIAA/QBANsFA+4RABgAAW0AABgAASRgAP8YIP/91AEEMHgAQAAARgAABAAJYAABQgACCQAC.VgECkwAACgAFBAAHDGAABgAFBAAHGAACigADBgABYAADYwAAgRgAIwAABAAAAEgAdQABFBMAZgAAawEP6BcFAQYAAiEAAAoAADwA.AVEADxhI////CgwEAAjcIw4EAAVpAw8EAAIC6QQBEAUCBAACNQQIiQoFvwQBDQAMMAACBAAIMAAPBAAgA2MABY0ABbEAB70ACGMA.DzAAAgKVBAIhBgCeBAHfBQBrBAH1BAIJAAA/BQEIAAU2AA8EAA4CqgcgDg8GDAEYPAAPEjIFBAIDBgJ1AADXBACFCwD4CgH1BAZy.AAAJAB/8tTsBBJRfCNgAAhgABUwpCAQAACIFBxgAAEsGBxcHBQQACWAAASEAC2AAABsAARIAApMAACcABDAAAKIAAnwRAa0HBUgA.CBgAAB8IAWMAADkAAcAAA1UAASoAAjMAAg8ADAQAD+gXBQWJAQ9IGAEADQAFIQAPBAD///8LDgMGBzYDAHIJAV8QAA0AAQQAAvwD.AAoABNMFD1AEBQIEAAkwAA8EAAQJtAMFwwMBXQAJbQUHPAYDJAAACwAKfBEPMAApAQQAAJ4EBG4ECAwADwQAAARgAAhdAAAEAAJa.AAAKAAC+HSD7/ugRAgYGbvXx7/r8/QMGASwAAAQADAMGAVoAA7EABzAABXIAAgkABRgAATMAAQMMCkgADBgAAbMBADwAAd0BBmkY.BDAAABsAD2AABgASAAKTAAgYAANQAQFNAQ8YAAUFBAACVwAFTgAACQAEMwAFEgAAKAANBAAA6Bca/bgaDwQAAgUhAAUJAA8EAP//.9A9dAwMOAwYHBAAPAwYMDwQAAQtmAAYwAAELBA8wBgsJBAABMAAP7QMFC2YADwQAJgKtBAIGAAAQAAFnBQCbEAKPBAEMDADAAALR.LgAUAA82BgEIEXMNBAAyDg8O/QsQBsPSAkMAAwQABXgAAqAFABMADwQAIgJIAAE0LwPrBQAWAAHMAADSDA4YAAGGAQI2AADUAQQD.BgAcAAEEAAtfAQUqAAANAAcEAA8YAAUPBAAFBTAAC2AACAQADhsABTYAAA0AAhYCAAoABwQAB0geAxhIABYADwQA///PAmIQAAoA.AW4WAgkACwQACAwwCDB4BzsAIQD8jwoBCwABBAAF4AQCLAACDAAIBAAFUwABfC4ALhcBJAAJJGAH3BcGBAABvQMGMAADYTAAP6cY./aQQAAUAAQQAANUDAAgAAgQAAW8vAAkAAN0VBi8ABAQAAh4ACG4KAhIAAQQACCRgAwQAAh4AAK80AAwBAJkGAQBIAv5qBjyQAb8Q.AI8uEAA5eAAoBQ85DAECkBgBxxcCEO8DIQAgCAQAJML/C//9+/36BAX8AfJU0gBCAADHAAGjBQApAAAJGAEIAADZAAC1EQBbAQHA.qBD9BhIgAP8cLwsYAAAvAAIEAAFzRwCvAAAtEQElFwImBQMGDAC9BgBDBQC5AQQYAAFUGAEeAAA4AAAASAAjcwCHABH9F1UD9wcB.LwAAMAAFuI8BBQADBAABYAAEFwAAeAACfAUCqAAOGAAPSAALAxgADRsAABMCC+gXASIAA+gXAgQAB0gYIQX9IEkACwAEeAAPBAD/.//8NBqMLAAwKAKMFAEEEAb8EAHsDAZAJDpYJAwQAAdMFCDAADwQAIw9gAAYCyhEPXQABDzMABg+NAAQPMAAMABwFAA4ABQQAACUd.AgMGBEkLAgwABQQAADMGApUEB8sQA00BAhcBB4cAMggICIRmMA0NDQMGBXUAByQAAAQADxgABQB6DQC+EQIMAACYAQKTAAGDBwac.DA8EACYAhxgBQwALDCQCigACBgAAFwAPGABIAxIAAB0AAxIAAAsABQkADwQA////TAO2BAALAAS0FQIMAA8EAB8CCgUCBgAAEAAL.BAACXQAP1QMXDzAACg9mAAACMAAACgAPBAAhAsYeAAMMAS1yAGE7ABcAAyQkAQsABCABAZMADwMGAgANAAVKBwG3AAgYSAIYMAYe.AAQ0HQIGAAAiAAoEAA8YAAUOBAACKgACBgADMgEBBgACEgACBgAPGAAGAMEAAD0MAEkACAQADagAASkAAfASDRgAADAADwQAEA8w.AA4A6BcFPB4AEQABBAAP6B0FBAQACFcADyEAAg8EAP///x4HEAsCFgUPVAMGAiMEDzAAIAEcBQUEAA8wAAYPBAAgAeAEAAkACgQA.D2MAAAeNAALNBQK9AAUDBgAkAAHyBAB3EARfBAPDAAELAA8EABQ1CQgJJIoAAwwR9wYSCgQACfgEB1gFAE8RCACEBxgAAM8AAv0L.EQM2AABHAAAYAAhIAAAGAA8YABEACwAABAAIeAAF3gYPBAARA0gABGAACEgACBgACXsGDyRmHAHrAAALAADoFwW1Dg8EAP///geL.BQBaAwEIAADoEAcMGAUhFQUEAAMDDAGHAwDgBAoYSCD9BBwXAAoABYCmAuwWDzAABSUC/WMAAGguAAgAATAAAQkAAzAAFv8NMAIt.AAOgBQGCBQAWAAD/FQY/qBICCS4BBAAFeEgAThgDCwAABAAAYwAEMAAFzDAB7zAB1RAAqgARAmsAAg4AAWpHAhYBAB8dBGwAQP8A.AvkTHbADAQMDBQP6/fr6/cm/AHEZAMMRAckABCoAAJ0FATYXANIAAcAAAgwYCCQAAAYAUAAAERARGEgQAxhINQgECA8GADkABPgE.AKwvBEQBAN4EApwAAPYEAADAAAwAAfUEBSgFIQYB8MATAQEaABgAAQkAAAQXAeoGJv7/GEgAAnMByDEAkRcKAEgDil8BDzAIMAAA.UMER/6YRAQ8ABmAAEQBkFxEBQQEB4gUAhwACMEgC8RcBUR4AMAABYAALGAAAXgAB2wAFJGACVwADCwE4/v0F6BcAIgYALQAABAAG.0wEGiAIFJAAAjAEKnPACugADBAAEWQEPBAD///IDHgMACwAGBAAAAwYBSAMADQAPBAAQDzAAHQwEAAI8BgAKAA8EABMPMAAED8wA.Ag8EACACAAwCOwQAUhcHiE0GLVoBbAAA+QABiAUAXwQKkwAFjQADJAACKgwKJAAyDQ0N4N8IAwYFBAAOqSMACQAE8QUAFgAPBAAB.BioABQkAAYoAAI0GANgRARIADxhIEAERAAMMAABPBQM3BwYEAAZpAAEzAABIAAQmAQgEAA8YAB0FVwAADQAPBAAHCagAAeEAAAoA.CAQAANogBiEAAKACBE0BDwQA///+BaoEAA0ACAQACGcFBwwADzAAHg88KhEHMAACBAAPZgAGDwQAIA1dAAIEAA9jABcCrQQC/QUC.BgAA2AABPwAAzAAC/gYPZgAEDwQAAgIVQiHy8wMYCgQAAtoEAcgoD6wpAAAJAAEhAAKTAAUPAAgJAAAuAA8EAAQIJAAGDAAB+gUA.CQAHBAAAYAAA1gAADAACBAAGMAAPBAAKBScABQkAABYAB58ABQkAAxgACtgAABMABAQAAPMAAToCD6oBDg8hAAIAPwABWgAADQAK.lAIPBAD///8FD0UDAAIzAwK8CgIMAAAWAABRCQARNA4wAA8EAAQApygByQMADQAPBAAWD5AAAAUEAAeNAAgEAA8zAAYPMAAcCDsE.DpgEIAYDbREFIQAIBAAJOQAEXQAAJAYCBhIC4xYAHQAABAAyDg0OG3gARa4HAwwBcAsDGAAPBAApAI0AAXcBD+cABQwEAAB4AAmI.BQgMAADSAAsPAAE8KgAJAAsYAAQPAA8/AAUFCQAAFgAPBAAKAMMAAVABDugXD0UAEQU/AAN9AQAUAA8EAP//zACbFgAIAAAEAAP6.AgIEAA8AFQQJGEgBgRUAFgAQABx3CW8DACAAAAgAD0UDBQBjeAUwAAJsAwJzBQU5ABn/bQUDEwUACwAAfwAGMAABcRYDBAAIdBAF.DBgCVNgEMAACph0AOQAEJhYAJAABYwwADhYFkwAEBAAhBAFhAAD1AAowAAH3QQOTAAEFAAMKXxEDUhcQA6UAMgL//VJ5EPtO0hD9.OYQADgAwAP78HgACwwAAVAABOAAABAACji8E8wAABAACGgEBRQDzBQ4ODvT19AgJCPf69wgLCPj8+AL+0wsAjAEHGEgjAAHsmgbO.BAEbAA88qBUCMwAj/wBnMQHYAADcFwDoLwCSAQEYAAEtSAAlCwEtAAAjAAE8qCD+/lkZAhx6ABkAAeoAFAHGAAGWAAYEAAfoRwAG.AAUEAA8YAA0CtQIAugAHwAADwwAAmRgAJAAALwAQ/6QBCNcBACkHD+gXBQLgqQcwkABRAAHyAQkwMAGBAA8EAP///wUJowUNBAAC.pQMDdQMAEQAAcwUGMAAC6QQFjQMBnwMGpQMBEwAPYAALAgQACDAADwQACQEMBgAJAA9jAAIFjQAF7QMPMAAcAu0AMgD//bs7EAVI.0gMMAAAfAA8EACWhBgUGAAAAEQ8R7zOKAIEAD9YRAQCTAAJwBQRQAQW0AAOxAAEnAAUwAAKxNgUkAAAxAAHnACcAATwkBUsGABsA.AGYSAhgABBIAAzwAAAYSAZAAABYADgQACpwkAIoABKgADxgAHQAGAABSAAAYAALAAAEOAAAEAAYzAATSAAX2AAAfAAsEAAe2AQAE.AActKg8EAP///yMPaQMJDwQAAQ8wACcFcwUADQAPBAAKACh9CQMMABUAALkKAwgACCkEBmMAAjAAAyAADwQAGwJ2CwBUABAAlBEP.9wUGD2MABAA5AASNAAAEAAcnADUGBgb9BVAQDxDy7w8YBXMFBfgEACsABJP2Ao0AAAoADwQAFggzAAJRGALrBQIYAAHbBgY8qBEA.FQAAKwAKBAACLQAAXAEC9BECxgABagUMqAAC0wUB4gUGGAAPBAAQBUgABTIBBQkAAB8ADwQABQ/0QQUFHAIHAwYPUQASDwQA///o.BYEDAA0ADwQABAUIBAANAAEEAA9UAwYBIwQPMABIDwQAIAUUBA8wBhQIMABzAAAGBQP6+ycAAgwADAwGBKYFDwQAGhERMJAU7zCQ.ABMADwQAAgSNAAIjAQC4BQC1BQAVQgCxAAdwBQXPAAUJAAA3AA8EABYGYAAAFx4DLJ0AGQAPBAApAlABAsAABKgAAA0ABxgADwQA.CA7bAAAWAA8EAAUEKQEPBAD//+8CVxUACgAPGEgUIv///lgAYxUBgwoGEAUAHwAAJAAAowUFuEcP6EcBADAAANMDAYQDAd4DA0kX.CjwwCTAAAgMMAA0ACjAABahgMf0AA3IAAgQAAxYAAqoADz4EBAgpBANjAA8wABYDBAACMAABLQAAaBYAeGAAtyhD/v/+BBI2ADAA.FAOVvzD9//0tNgBPCwNjAAAMGAAIAABdAAZmAQAIAQGmCgEkAEAICAj1LahzAwkKCfv6+4euFAJQAQE3AAxYjwDGRwAjAQDIYQEX.AAPhAAHGAAM4AQEYAAEEAAAKAACHRwBZFwFIAAFUAAoYkAEMKgEYAAAhAQUYAAJ1AAD1AAADBgIVAAArYRD/txIALwERARgYAVF4.ACoAAhiQAUYaEv7kqAFtGQMwkAIYAAD6AAOoAAEcAAGGGQXYAAEYAArAAANTBwChAQEKAAAJAAXoFwFEAQDoFwAaAAAMAAXwMAHr.AQBUAAAWAAgwkAIIAAI5AA8EAP///1YHkAkDvQMACwAPBAAHBzAAAgQAAP8JCGcLCwQADTAADwQAOQVdAAFxBAK5BANtBQE5nAAb.QhP8XwcAiAUPDCoUARoHAiQAIAsKS+QAIgUQ+kUAI/X3TuQAYwABiwsACQAEAQsDGQAEBAAAGgEPGAALBdwpDdwjCAQACRgAB70A.CRgADwQABQVjAA8EADcJeAAC2DwHAisAFQACBAAEqwAIMAAPZAILAHgYDzxaEQ8EAP///wICMwMCuQQCDAAAFgAAzAkPDCoDAiQA.DzAABAAKAA8EABkPNgARCyAECDMAAJoFAbUFAA0AB40ACAQACDAACQQACjAAAGUWBBVCCRtODT8AC5AADwQAMwINBQIGAAAQAAQE.AAISAAIGAAAQAAfrBQ+gBQQCBhgACgAPBAAQCUEBAQQABmAACgQABhgACngAAxgAAqIAAgYAABcABKgAAhIAAgYADxgACgAbAALo.FweVAQ8EAA4DTgAACwADahQCCwAPBAD///9oD20FBgKcAwpzBQ8EAAkPMAAKD2YABgEEAA+gBR0FMAACDQUCAwYAGQALmwoPkwAK.BgQAAicAASQAAgMMAVQSAA8ADAMMAUYFCcIEBwQADxgABQ4EAAIqAAMGAAA8GADxHQAGEgISAAEGAAO3AAIGAAA1AASIBQEMAA8E.AAYB6wUFKgAAZAsCLQYBGAAACQAPBAAZBUgAAA0ACgQAAA4BBWgBAqUAAgYABTAGABkAD2QIEAd9AQ8EAP//4QHLEAMEAAcDAwgM.GAByCQEIAACWFwFgRQb/CQAOAAAIAAVYRwtU8ALoRwQwABD/bwkACQAHVPAPMAAcAK1AFwBjDAGFEQAJAAIPAAQwAAB6vgDqFgBE.AAaOBQQEAAK1BQVdAAAEAACBuQFLAADcFwAwAAJjAAArQQAWAAGTAAIpBAFlBADsFgEvAADzFwFJAFD8A/wCAz6oMf39+usEMP76.+hgAAM8AAFhHAJUEADEAEf9FAAQsGQMiAAD6ACIA/nmnAakvkAgHCPf39w0LDSRgAcDwAg8YANoEAs8AEgNuRwALABL+mQAACwAA.HwsCBEcCsQAA7RYBQAUAtxgCSBgQANgAAAkAAeIBAbQSAFoAAA0AAgQABBgAAHskBRkFARUAAAQAAX8LAEEBARYaAJAABWAAABMl.ACMABag8AgQAIwX+iBcBYAYE5AABhBIAHQEPqAAEAsAAAAoAAQQABRgAAB0TEQL1JQAKAAASAA/oFwIAxiQACAAEBAAEYDACBgAA.TgACRwECVEgBPwAPDDD///8XAKwEAkAFAw4AAQQAARYFAAkAAIIEC7UbCtkdDQQAAPwDDzAAFwWJBAsEAAIMKgAKAAoEAAcwAALT.BQAKAA9jAAsPBAA0BRwFAA0ABSABBJAACI0ACwQAC0jYABMAUgAAAgQCAwYCDwABfhgDDwAgAgEHUw7nBg8EAAsIQAsALgUB9CkA.owUHGAADBAAEOM0ADAAPBAAHC9IACf8AAQQAAnQBBRgAAjAAAhUAAB8ACgQABRgACzAACAkAACgADwQABQCiHgMkAACnEwQYBgPV.DABlAg8MKv///xkPHgNBBYcDDwQAFA0wAA+0A0UEoAUL+QADjwQCagsHjQAAngQB9xcGDEgAEkJB+gMDBbUEACQAADcpC1yRDwQA.BABOAAE3AAJF0pUAAAAQEBDt8O1aGABgAAeLBQK4BQAKAAIeEgKsKQAVAA8MKjQC8AABtwAGYAAA3gwGDCoFYAAAJQABBAAOYAAO.EgAIBAACqwAFSAAPLQALCAQADzMACwKxAAAKAAIEAA+AARAPBAD///8aArQDAAoABQQAB2ADD9MLBAkSAAgEAA8wAB0CBAAP9gMC.AwQAB40ACAQADzMABg8wABwFegQADQAHBAAE/QUABgAAPwAPJwAEAgQAAV0AAEMFAA0ADwQAAQIDDAVaHgsDDA8EAAgBWgAGAwYA.EwAPBAABAiIFATQ1D2BOAwANAA8EAAcFAwYADQABBAACeAAACgABBAAPJgEHAxgADzAABQIYAAXAAAsYAAArAA0EAA8bAAgABAAC.yQYACgAHBAALJAwBbAAADQAPBAD//80FvS0A+hQI5wMH+woIDQUIJHgIDBgJjAQEIAAASwMBrBcCuy8k/AO1FQswAAHCLgNmAAI8.AAIMAAkEAAiRAAgwAAIHAAAEAAXLLQsEAAkXAAJgAAIEAAqDAA8EAAMPMAALAh4ABCR4AAwAEwTUFjAEAgQoARABrQRB/QEDABQx.ALcAAkgADwkeASYDArwWAnR/BVcA8wAICgj4+fgJDQnz9fMJCQkJHgETAQLCAQFnAQEVSAAUAAE8AAMYAAFRAAEFAAIEAADvFgDq.BAckeAD6BAAJAACrGBD/YEgAGAATAQwwBksAEf92IwS8AQMVABP+FQACiwEAMxIBaxkDwgcBBQAA8AABRhcAuwUIGAACBAAACRgE.8gcBBQADBAAPGAAFAj5JAu0BAQUAAwQACBgACzMAAvRHBBIADyQYAgAEAAC5AAAIAAAEAAIgAAqhAQ8EAP///wsFnwkADQAOBAAN.7AQJMAAPkAkCDwQAHwD/AwTYAwwEAA2BAAIEAA8zAAYPMAAdBwQAALYEAlgFBAQAA3MFChUAAgQAD14LDASHACAJByFygfj6+AsK.C/X2/QUFNQcCBgADEwABBAACEgACBgAAEAAEBAACEgACBgAAEAABYQUPlgABBQQACAwqD/wABQ8YAAUGBAACcgACBgAAEAAEeAAC.EgACBgAPGAARAKgGAFMaCdwFDwQACAdCAAZFAAEOAA+0AAIIIQAAvAcPlAIxDwQA////GweuAwKfAwIGAAAQAAsEAAIwBgcwAA8E.AAwPMAAdDwQAIA1dAAIQEQv6BQZiBA+TAAQM8wACJwAEJABQCAYIAAoJAAAwogIDDAoEAAZgAAoEAA8YAAUGBAAA+wsGIQAPMAAM.ArcAAgYAABAABgQACDAGC3MFDwQAOwJaAAIGAACBDAQMMAMSAAF7AAAw9gAsAA9oAQAPBAAVDzkAJg8EAP//4gnTCw4EAA1LAwkw.AALpBAHREA8EACkMQAUPBAAQDzMAAAWNAAqxAAIEAA8wABEFhgQADQAEBAAPFQACACUFDwMMCwQEAAMDDBb2D2ADeAABKwsJXQAP.GAAZAAkAAs8AAQMGAA8AARgAAJkAAQYYCNMFD/wAAAEEAA4YAAVIAAAJABb+xHcADwAEGAAA/gEPGAAdAeUFAOsFBZMAEQN7AAIY.AAARAAcEAAXwAAANAAAEAAVOAAA5AA20AAAVAAchAAMvAQELAA8EAP//+AgMMAOcFQ8EABYJVC0OBAABTBcF3C8APDAJbMAAHwAA.AgQADgAIDDACS0YABAAJkAAAEykACAAABAACG2AACgAMPDAACQABBAAJ3C8AcAAADAABYAAPMAAQAaoEAA0ABwMGALWQAYhfAM2/.QAMD+vfMAAARPUMCAwP/ZQQAMR0BjC4IJwwCTAUFYAAgAANmwAMbABoFDDAQ/HV4Ao4XACsAApoBAgwwAYcAALgFAKYjAEXYRQMD.APoMMAAdAAYEAAUUAQP0HQFIAAsMMAmoEgIZBQH2AAkYAAK0AAXUBwQEAAD+GQBC2APhAAATAAEEAAcMMAkzAAL4MQ8YAA4CIcAA.eEgi/QZIAAL1eQDlBQGTAA/oFwIA2x4ACAAEBAABgAEACQAC/AAA4xMBCAAPDDD///8TAqoEAAoABAQACdMLAgQABxMFDzAAQg0E.AA42AA8EAAMEPgQLaQAPYwAGDzAAHAAkABwAdiMPPLomANQEAYV3ABhgAQkkABYAAQQACwkkAJQpBOwEALsLAuZYARExAJMAFv+T.AAJUAAjPAAIJAAjTBQAuBQQMMAAQAAEtAAI/AAIPAAUEAAA8AAEgBwL5EgBXAAVgAAoJAAIGAAA0AAQEAAKTAAUYAABLAAGQAAAc.AAQ2AAA/AAGfAAIVAAAEAALbAAAKAAMEAAU5AAXDAAUSAAAfAAIEAAC3HgMSAADoIwQsAQZ5AgdXAA8/AAAPBAD///+ABbcDDwQA.FA8wAB0PBAAcBXoEC7AEDDy6AdQEACsFDwwwAQg5AAsEAA8MMCAPBAA1CGAAAFANBFsRBRgABakFABYADwQAEw/qAAgPXAcIDhgA.D0gACwsEAAWxAAANAApzCA8EAP///yAOeAMOnAMIYAMPMAA0CRIADgQADjYADwQADg8zAAYHjQAIBAAPMAAGCgQAAY4LA7AQABAA.AT/GEP0JEQ88AA8LBAAIXgUPDDAbAtEKAYoAArcAAUQBADAABVQAAhgAAC0AAQQAAiIFDgwwDwQAFADYBgEMMAZgAAQJAAAfAAfT.CwIPAAUEAAUYAAyQAA8YAAQIJMwLBAAAwwABkAwMMwALBAACzBIACgAHBAALJAwHvwEPBAD//8sC0i0ACgALGGAH+xAIDQUIJHgA.kxsAFAAABAAJjAQBHQACBAACaBYADhYPDDALDwQADwiRAAcwBgKGdwIEAAe/AAwEAAYwAAAFAAMEAA+DABEHzAAJNQQIjwAOqGAR./W8AEAQYAAKvBQAwSBEEtwAA/QABgAQFkwAEBAAPtgQABGYwAAMMhfDvCQkJ8/fz1xYCTgACwgEBZwEATxgAEwACIQABGAAAWDcA.lwAAEQADBAAOZC8A+gQACgAADh4HDDABpgAAYwwAJAACGRcBUwACvAEDeAANDDAAQAUEuwUAFgAAGQAB6gAOeAACBAAPGAAfAAMG.BWgBAAcAAQQAAREABY0ACRsADwwwEwA/BgUDAw2eAQ8EAP///w4FXwoADQAOBAANTgMJMAACkAkNJAAPBAAdD0AFAA8EAA0PMwAG.D40ABA8wABcGEAsBsgsAywQIEwUEBAAJdAQPBAAKIAgIHpYgCwseVCH19QkqAnUAAgYAABAABAQAAhIAAgYAABAABAQAAhIAAgYA.ABAAAWEFApYAAPsFAQkADwQABw/8AAUPGAAFDAQADngAAhIAAgYAABcADxgAJQDABgAPAAwEAAcqAAYtAAEOAA+0AA8ClAIHPwAP.BAD///9cAp8DAgYAABAACwQAApwDCt4DDwQACQ8wAB0PBAAuBWsECRhaB/EjAEAND5MAAQzzAAK6AAQkAAAhbBH5+gUPBAAEBXgA.AA0ABwQADxgABQ8EAAUDMAACnwACBgAAFwAEBAACEgACBgAAEAAGBAAINh4C8wAASAAKxgAPBAAyA6IAAAsABAQAAQYGDxgAAA+e.BwEPBAAFD48HFw8EAP///wIJ0wsOBAANhAMJMAACIwQACgAPBAAqDEAFDwQAEA8zAAACjQANsQACBAAPMAAGAAoADwQAAwW1FwAN.AA0EAA90BBQCMK4gC/wADAAMNiP19XgAARMLCfgEDxgAGQAJAAfPAAAPAAEYAAANAA0EAA/8AAABBAAPGAAFDAQACngAAP4BD5AA.AQ8YABEABgAAUgAAGAAPewACCTAAABEAAAQABU4AAFEAD7QADgUvAQANAA8EAP//0gLSFQAKAAsMGAcEAA8MMEMBaAUBahcCMBgA.nwMPGGAVDwwwAwKFHQAKAAK5FgYwAAQYAA/cLwgAEAAADAAPMAAYBGUKAq8XADkAIgIDuF8Cze4ACKkBigAA7qcT+oYEACESAUcA.AnoBAiQGAkwFARcAAQQABxhgMAEEAcKOkPv6CwYF/fUA+vhfCoEAAHkACgwwBxgABhhgABAABgQABOQAAHgAAAgAATAAMAMEA58A.AgEFCwBaBRkFCxgAAhQBAZAAAGoFAhgAQgIAA/xgAAD/AAEIAAMEAA8MMB0PBAAFBMAABwwwAS8BBWAAAEsAALIAACUAANseAAgA.BAQACAwwAUsCEgN0AAKoeAE/AAO4AgInAA8EAP//+gKqBAAKAAQEAAnTCwIEAAEWBQAJAAFXIQWQAwIEAA8wAAAHBAAArUwHcwUA.GgQPMAAKAgQADpYADwQAAwHmBAIEAAgzAA+TAAYPMAAdDwQAQFAFBQUOEiGEIPLuDyoAEwAEkX0CDAACnAABngUADwAIjhEAEQcA.1iMPDDAAAB8ABwQACdMFDQQADxwjBQAUAQqtAQIEAADbBgF4AAANAAEEAA54AAKTAAUYAABLAARfAQyoAAV7BgcYAAUwAAUJAAAq.AAEEAA4SAAA8HgSoAADMAABPAAAMAAAmBwQsAQ8EAAMHygIPBAD///9LD2YDHQ8wAB0PBABEApgECI0ABLwQAqAFAh5gAgYABdQE.ABsAADcAAC8ACAQAAbYECWQFAjAAAAoABAQAYg4REO/w9QEFABAADwwwBwgYAA8EAAIBbwAAIQAFCQAAFgACBAAC2AABSwAJSAAP.GAABAqUAANUAAfkeABwACgQADmAADhIACAQAAhgGAAoADwQAHAKKAAAKAA8EAAEFsQAADQAOBAAHYCoPnwALDwQA///yDiEDD7QD.AAcWBQ8wAAQJEgAIBAAPAwwECRIADwQAGweNAAgEAA6ZAAMEAA8wAAQPBAApD54ECw8EAA4FAwwFSAAPcwUIDwQAIw8iBQwPBAAT.CEUAC18BBboAAA0ABwQABRgADzAALA8EABgHyQYPBAAGBQQCBQkADwQA///dB/sQCAADCAwwAWobABUADwQAIghhAAGwFgBZAABb.AAARAAIMAAgEAAKEGAUYAAWWAwMHFgAKGAMSAA8EAAsAuQAACAAABAAPPwUcD3EEAAJOAApNBAKhBACgBSAE/gNIIPz9nb8RBMso.AcUAADcBAnsABzYAALQXAkwXAgQAAcgcAloYMAMAAwxaov8DAwgJAPb4/gI9AAN1AABtEQCEMAEwGAJgAABhAANFMACcMAGzAAFE.BwA5AAAVEgAwAAcYYAFIAAIEABIFnGAAOwADsDECYAACbAAAmAcFrI8BGAADQgAHkxICMAACBNoDxwcAFwAArgAAGgECEwABBQAD.BAAI0F8BBQADBAABGAAACQAA3AEAPgECeAAA5nkPMAACAcB4ApAAAFEADySQIAQiAAkkEg8EAP///woDZgMACwAKBAACYAkACgAP.BABXAFwEAUwdAA0ADgQABTAGCgQAD8MABg8EADcPCSQLDwQACQJHAQG3AAIhhFD19/UIB0jeIfj5HlQC1QACBgAHGQsAGwAHBAAP.GAAFDgQAAr4LDxQBHQ9gAA8CogACBgAAEAAEqwABvikApwYPPgAKDwQAGgLDAAAKAAUEAAd4AA8EAAsMPAAPOQAWDwQA////Bgc/.AwJTBAIGAAAQAAsEAALpBA8wABcPBAAEDzAAHQ8EAAkHjQAIBAAPYwAGCjAAA+AECgwwANgABBgAAxAAB0kXAg8ADwQAC1QLCQsA./P0FDwQACA9YBQUCEgACBgAAEAAEiAUBDAAPBAAAAtUAAgYAABAADwQADAVjDAANAAEEAA9gAAwNBAADMAACogACBgAAFwAEqAAC.EgACBgAIGAAACwAMBAADxAsPlQEBAAwAD8gBBQUEAAKUAgAKAA8EAP///3wCjAQCnAMCDAAAFgAPBAANDzAAHQcEAA+gBRoPBAAF.AgMMCIAEAEATD5MAEQK6AAEkAAASbAEMZgkDDAoEAAljAAcEAA8YAAUPBAAdA0gAArcAAgYAABcACVsFDwQAAAXGAAQgHwAVAA8E.ACsPSAAbB6sADwQA////CwK6FQAKAA8MMBQChBUBBAAMaC4ADgAACAAFqC0P6F8IGf/cLwQwABn/DDAmAP2f9gkwAAMUAAD7XgDP.jwXYCQUMMAIPAAQEAAL+FgAKAATcLwLTCwXcLwCWAAfEoQDERwQyAAEvAAOcDA8wAAUFaAQATQECnAABMQEADwAKDDACLhcIYAAC.2NgDwAANBAD3BP39/Q4LDgD8/f369/j5+AgAAPhYBQB+AAAmAAH3CwISABH/DAAFTQAXA3QBC3yPBLQABXsAAuQAAAoABQQAAcYA.AAQAB38LAAQABxgABohrBFEADwQACAOsNQI1AREDNUkEkAAMGAACiwIC2N4EGAAABgAAFgAAMAAGJJAR/7HYAS8AA+gXAawAAFEA.ARQAAO0ADzDABQ8kGBEPBAD///9cAuoDAAoABAQAD6L8ChUA2QUPBAB2AvcLAAoADwQAAQUxHQANAAcEAAOYBAALAAkEADUDAwMt.zGAODxDy8fAKAAQEAA+oDAUPGAAFDwQABQkwAAdgBg8YAB4EoAsAqQsFIQAPBABSAHIAAXsAAA0AAQQADpkSDwQABQg8AA+JAQUP.BAD///gOIQMPaQMAB8cFDzAAEgcEAACkCgWRCQ8EACYBE2UDmwQHjQAI+QkOmQAPMAAADwQAJQK1WQIGMAIGAAAWAA8EABcCigAA.CgABDDYBLboR8jPAABQAAh4AB6UAAPgWAkabAosFABQAAAQAAOQAD00BGQNIAAALAA8EADEHqAAIZAUIqAAPGAAGAWMGDpAABTAA.ANsAAb8BBQkAAB8ADwQA////pw9zBQsOAwwHujMCBAAPBQRQD2MAAAKwBA29AA8DDAIAhhABFU48AgICSAAPBAAKCAMMDwQAIAK3.AAV0Bw9ABQUP0wsDBKseA4gFBxgAAgQAAxgAAAsAAwQABWAAAA0ADwQANQ14AA8EAAIFewAC0gAAEwAFBAAA5RQAGwAC8AALtAAA.FQAEPAAADAAOPwAPBAD//+MHKwsIewMIJJADMEUF0wsHJwAPBAADBFQAADAADwcRAQAEAAWoRQGIBAIJAAGWCwQ9AAGdFRQAiF8G.vhUA2wMCCAAABAADFjsCqgAIPgQCEgABBAAtA/7qAwEeAAXAGADjwAEp1wMNAAgsAAJRAAGVAAZgGACOABD9SgQRAlkWAJMAAFkE.AJIEIAH99xcQBFfqAiRIApMAAstGAHcEAI9fABIAAOAAIP/+PwAEtwDwAAgICPr6C/r8/fv+Af309BMAIgMAFQYAoAUBuQQRBU8B.AvYAEf4tFwAKABD/WHIDIgEBGwAABAABtAAAIgACGAAFLi8BBAAArO8BUQAA0QEC8JABJ2AJGAAEGAYANBcP3O8FEAIv3wAMABAB.PwAA4QABZAUhBQFwRwIzAAKIBQEwAAnwwAIYAAEEAAV4AAYYAAEwAA/AAAMCGwAPBAABBbEAAA0AAicABTYAAQQAAEo9AAgABAQA.AiQACF0ADwQA////EQgKCwcMAAD+BAtnBQ4EAA8wAAoAMAYC/AMPBAAHADYABhIEDwQAKweNAAgEAABjAAqZAAMEAAowAAWJCgAN.AAEEAAL9CwD4BAoYAA8EACAOMMwObwAABAACIw0ACBMADgAA1QsEexgFCgULOQAFGAAADQAC3DUAdwsADgAAwAAEBwcAGAABSAAA.DQAHBAAPGAAFDwQADgV4AA+QAAUPGAAUCAQAD6oBBgIEAAJRDAAKAA8EAAcF1AEFCQAPBAD///99D5YDjgIQBQA6BQH3EQATAAEE.AAAYAAJeIg3DAAW2BAPwBgpa0iAODT/wMO3t7Q0ADQQAD9BxJg4EAAhYBQ8MAAUADwAPiAUED6AFEQ8EAEQAewAIMwEPBAAaCyQS.AKIBAAwADwQA////HgLUBAJgCQIMAAAWAABRAwLaBAEOAA8EAGEHjQAIBAAFcwUADQAIBAAPMAAEDwQALA8TBR4EhwBQDg4O8vIq.3gUADDIFBQUDEgCwBAA0uQMMAAYEAAIDDA+IBWEPBAAFBYoABQkAABYAAtMLAQ8ADxgABQANAA8EABMAMwABfgYADQAKBAAMGwAE.XAEFBAAPIQAODwQA///+AKwjDj0FAjYDAUkXAMMDBEwXOQP/A0wXAER2BC8QDzAGBAIGAAAQAAKNAwMKAAEZGAQ7AAAIFgEIAAA2.ABb9MAADdgABBAADEwABBAAF1xUP2hUUGQF5AAOZAAALAAgXAAH+KAhPAAPIBBABUgqRA/8DAwID+v30po8Am+4JJxEISAAPBAAK.wwUHBQP6AwX5BQYIBiSoBSwZE/888AN1AAQ88ADgRghABQQwAAbpBAUnAQ8YAAIB3ngAVEgAYAAHGAABLQAAuHcLMAAIGAABeAAD.CAEEeAADBgAFBAAPGAAWC0gAD2AACQXQLxf9lQECGHgP9F8CAHoCABQAAAQABTwAAksAAi0ADwQA////iQXeAw8EAA4NYAYPBABa.An4AAAoABwQAAhUADZMABmAGAgQAAicABCQAUQgGCPUA+gUPBAAEAxAFAAsACQQADxgABQ8EACQCtwACBgAAEAAEBAACEgACBgAA.EAAEBAAFxgAPDDw3DwQA////dwywBA8EAAgNFwQD5hYACwAB8wkPbwlkD8MAAAKwBA2xAAIEAA8wAAYACgAGBAAA7DoQ/NeDAlMK.DzzqAw8EABlQCQcJ+PkkrgANACAAAAMMAngAAX4MCVgFDxgAEQG7CwPMAAppGABYCwIYAAMOAAYEAAMwAAALAA8EAC0AIAEB8FQD.kAAEqAAPGAAgAgkAAFUABwQAADAABfTdAgYAABcADwQAHA85ACYPBAD///8mBw0RAlUpD3EEBgLLBA2fAw8wAAYPBABQDY0AABYR.AowAAq4AAAoABwQADxUAAg8EAAo5CAcIJKgPBAA4Ar0AD9w7CA8YAAoOdwEJoAUFOQAPBABEB5AAAH4SBHsAA6gAACIABAQABBQZ.AJkADbQAABUABTwABecAAw0ADwQA///SArBGAAoACwxIB5cFCRAXEwJPRwAsAw/MdRA1AQABMAACBAAEAwwBOAUBQQAIfC8IDEgC.LHYBLQABDEgAcwAAGAAIMAAJXQABPwYACQAAzBUBIxYBDQACcEcACgAlAACQGADSMAQ7AAJjAAUwAAZgAAQ8SAAMAACQGAQiABH/.bRcCFgEjAQDcLwB1AAA+BDD9AP0qSFIAAP37BrfSADzwEQEkMBAANC8JdAEBYAACTAUEXgAAhgQGGHggAwEwALX+AP37/QgECP36.+O4jALUAAoQAEwNYdwPJAAA3AAEIAAgMSAAQAAExBQC6Fwx6Zw8EACYARwEICTAEBAAkBv7EpwEGAAASBgHPAA+4dwIA2QEB8HgA.8S8NSwAIBAAPJKgAAQYAABMAAQQAD2AABQkEAARFAAIOAQADBgISAA8kqP///xMPBAASAlkKAAoADwQAEwcwAABgHgqbBAQwBgAM.AA8EAAUCQAUACgAPBAAiD2MABgIXBAEEAAAgKAEaBAANAA6fPAoEAAJRAAsJKgUEBQANAA8EABYADEIQDgYqABhsEPMPJAAWAAoE.AAD/AAE1AQBpKgdABQBQDQAeKg8YeAQC7AoBegEF0wsCJwAAEwAHBAAB/AAPGAADD0gGLAWQAAUJAAAWAA+oAAcA3h4IpggChAAF.mAEBBAAOEgAIBAAAzAARAL8HAiYHAlcADwQA////ngcwBg8EAHsBMAYOgAQICQYAowUAzwQAGAAIBAABNgAJZAUJBAUHBAAI8S8C.uAUAiwUPLQAEDwQAIQdwBQVgAAANAA8YAAECpQAA1QABeAYCDwAAIgAEBAAB2AAAKgAADQABBAAOEgAPBAAyDnsABgQAAHENDxsA.BAIEAA8kEg0PBAD///sPowsSB6MFDzAABAkSAAgEAA4wAA8EAC0HjQAIBAAP6gMGDzAABA8EABoA5AAALwUKywoPBAAuAvQ1AAoA.DwQABAKLBQWgBQATAA8EAGQLXwEPCAEFBRgAAgkAAsAAABkADwQADQtgAA8EAAsMEQEP4wExDwQA///jAogXAPYVCyQVAgQAAB0A.BDQXAQ0LAGMPD0IVAwIfAAQEAAWQAwEHFgMMAAQEAABMBQtgBgQEABT/JKg2AgACmF4PBAAHCcwYDwQAEQKQAAEEABcFPEgY/kcA.Bb0AAD8KAQgAAiYAARWoAN0EAQkAAHoAAisXAqcABTMABQQABGxgA00HAEokADkM4AMIA/r8+vr++vsA+/TwSGAjAwAMSAAnAAIE.ACD9+8w6B1QAAPIEBVj7AnQHB6MLAKt4AXYFEABODAAJAAAwACn+/XxHASgRAH4YABAAARkXEQNLGAIkMABVCwE0GgCkAAGmEQFb.GQPtDADvDAGZMAENAAAZAAIEAAAdAAQSAAeuAA4EAAKoAA88SAACCTAPSAABADMAAhMAAQUABRgADAQAAskMAAoADwQABwjUAQ8E.AP///4MPnwOUAw0FAlIFAQQAAOAKApocDcMABdEKAKwFAuwEDQQABQw8AA0AAQQAArgFAhgMCBsSDwQAJgBGBQWxAA2lAACcAA/k.ugEDGAAACwADBAAJSAAPBACPAM8GA64AAyQYAAsADwQA////Hw0XBA8EAHUPmQAEBXMFAA0ACAQADzAABA8EABQP+wQFDxgABQ8E.AAMCpwoBhwAjDgwDHjLz/PMABggMQg8EAAsPdQAFDxgABQ8EAEcFcgAFCQAAFgAEkwwFnAwCFQAPBAAIDycAFAsEAAIpBwAKAAIE.AA/jASsPBAD///8dAmcFAgYAABAACwQAAukEB5ADAioAAgYAABAADwQAEw8wAB0PBAAgD2MABge9AA8EAAUPtgQCDJUEDwQAOg9y.AAIPZwUIAI0ADxgAAQIEAA/8AAUFGAAAAwwPtwwEDwQAIwWoAAUJAAAWAAcEAA4YAAISAAIGAAAQAA8EAAUCcwIACgAGBAAA/wAI.jAEP1AEQDwQA//+8BeoVALMQCAkDDwQABCMCArAWAAQAFP2fFQEdIgNdAwVERg4EAAhAFw9mAxEIMAACvQMBnwMIqHgIBAAGygAE.JRYCBAAILgAIdwAHygAAXAABCAAPBAAtAiYZAisXAj/8Ahh4AAMYARoAAGgBAqMXAg4AAQqPAkwFAA8ACgQAjwUFBQMEAwUGDEgA.ALkEAi53AVIABgxIAgYABQQABDAAAwYABQQACBgAAiEBAj8BAegXDusRAxIAAgYAAREAAgQABhAaBDAAA4gFCGAAAAcABAQADxgA.WQ8AqAUI7gEPDEj///8uCf8JAqMFAAoADwQAcAKNAA2wBAIEAAW/CgANAAIEAAIwAAAKAA8EACcA+wQPRAcQDwQADAKKAAS3AAwM.SAUeAAccQQAYAA0EAA8eAAUPGAAFDwQAPA+oAAEArEEP3EEBADAADwQAEA8wABsP+wEEDwQA////UQJNCgEEAACMNA9dLQgCIwQH.MAAPBABvDzUEBA/DAAAFvQAKMAAPFXICDwQAJg8MSAAACAAPBAABApAADlgFDxgAEAAPAA+nAQcPGAAFDwQAOA8YBgULGAAABgAA.LwABIQAU/5DqARIAAgQACTAAABEADwQAIg8EAgQPBAD///9TDzAGFQqfAw8wAAYPBABnAxh+ATDeDzDkJgIEAA8MSEgEBAAASxIF.twwCZQEBcAUPGAALDncBAJcFBLgFBjkADwQATQGvBQV7AAASAAsEAA/oNRoC5wAACgAPBAD//+4HlwsJQC8AbigJQgMMAxIH6I8A.chUgAv3JLQEOAAKwRgCBFQBqqAHFBQERAAgwAA8MSE0CiHcCNgAR/mAAABYAAWMABTAABmAACgxICRiQAjMAAQQAA/QXAQQAAOgX.Ai4BEAS+RwAJAAClFxADcy8BoQQ1/v7+0UYBwAAACQACmAQGRgAIJMAKDEgw+Pz4bgACiwUAKwAABAAD+AoACwAEBAACYwAODEgE.GAAIPwAPBAApAPwAAuEwAA4ABgQADwxIBQAcAAJkBQ+BACsFpAECYAAACgABBAAPDEgbACgCBpwALwX+JBgEDwQA////IAGTCQAJ.AA8EAB8OCTwJYAYPBABED9xHBQcpBAKjBQAKAA8EAA0IKgAPDxIvAnEfAg9IDgxIBbwEAA0ADVgFAFANAbAHD0QBFAAELw8nAAEP.GAAFDwQALw/AAAUPGAAOBWUBBQkAAB8ADwQA////pw8wBigCBAAPBQRjApgED70ABwUhqACI+wARAAPTCwELAA8EAA8C7AQ1AwMD.FXIAFgAPBAAxAy8BAsAAAb0AAtMRAAoAC3AFCxgABAsAAgQAAEgAAa0HAOE2B2k8ABwADwQAXgV7AACWAAsNAgDlJgMSAA/MBkcP.BAD///9aD3MFBw8EAAMNMAAOZgwPBAA+D3MLBQArBQueBAEEAAG2BA8wAAAPBAAjCdAFDwQAOARKAQVgAAV2BQAWAAoEAAHSAABg.VABsBgARAA8EAIcIxgACtwAACgAPBAD///8ECRiQACcKAAkAD+wEAAQpBAAUCgVtBQRPEQAwAAEvCgANAA0EAAWdBQgiAAmEGA8E.AAUIIwAEfgAPBAAFMQMAAzpBAGkAAcwAABUAAwQAB70ABWxIAAQAAywAAQQAAhcAAXIAIQH/BwACBAAClxYCKgACJAACBAAED0gA.KxcCPGACHgABkBgACQAAjBYEWQECTQEIDEij+vr6+/r7/Pv99FRgBhxHAX0AEQUUAAIJQgEWAAQEAAQMSALSAAW4BQ4MSAAMACUA.AAxIA10ABAQADxgABQ8EAAABkAADVJACDAAAOAADGwwO3EcAGAAx/v0FV9kIGAAALwEPMJACAlQABdgAADgBAwgAAjMADwQADwfg.AQUEAAANAgAIAAQEAAhLAA0tAA8EAP///0IPkwMBDwQAGgC3CQYSBA8EAEIAYwAHKwUGBAAPvQAKCwMYAAAMD/wGBw8EAA4ALgUC.EAUPBAAcD3gADgUbBgANAAIYkA8wAAEPGAAFDwQAPgWQAAvzAA8YAAUAEgATAjoIDqoBBTYAAA0AAU4GD7MBCA8EAP///4EOoB0P.cwUKDwQAbgWbBAUDGAAWAAWzBAJhFw/DACUDRQAACwAPBABCC2AABToFDxgACw4YBgIYAAAKAA8EAH0CgAEACgAPBAD///8tDmYJ.DwQABQXTEQANAA8EAGIPbQUlDwQAWQVQAQAgEw3orQIYljD39/cNAAcEAAKIBQ4MVAIYAAWgBQATAA8EAFIFeAAADQAKBAAFigAF.CQAAFgAPBAB0DyQe////Iif/AgwYCIhfArkEAnMFAyAAAAwAAAYGAeAEAhEADwQAAwIwAAHFBAILAAIEAAdeAAkEAA+gFwYCwBUH.HQAPBAACBXMFAA0ACAQAAr0AACgQAkkAAwQABjAACBcACGYABAwAMAMCAxJ4AJmnYf0DAwD3+YgFEfy2OgAgAAQEAAfZADb+AP7b.SARIAAIEAPQADg4O6u3q+//7CAoI8PLwdgEDpQAAcwUBDEgAVQUAZhgDDEgAGAAIZwUBHEcATjAAMkgQ/ZAAAh4ABHQABhIAAHcY.AC0AAAwAAcxIMP3+/fkADxgAChAC7JEACQAAGAACSAACBAABeAAACQACOQAFBAAEGAAFMAADgQAPGAAFAqgAAngAARgAAA8AAs0R.AwoAARsABX4GAjAAAgQAB+hHDwDAEgQBAg8EAP///1QIMAYAEAAAgQkAN00FbQUPBAATBp0FDwQAXwe9AAkEAAEMYBcArQQAiPUB.fN0ADQAC4wQFsAQPBAAKMgsJCwBCABI8DyHMAQ8EABUPqwAFDgQACioAD18BBQ8YAAUPBAA/ApAAAgYAABAABBgGAQwACwQAD8QL.IAyMAQdpAA8EAP///34NMAYPBACVBgweD8MAIlwLCQv39QASDwQATg6lAAISAAIGAAAQAAYEAAii9ga4CwMOAA8EAGwIjQAPtAYP.AqEBAAoADwQA////rAKkBALMAwIMAAAWAAkEAA8LBA8PBABoAroAB1IFAhJOAAoAApE1ByEYD3AFCA8YAAUPBABUBcYAD9xNBQAl.AA8EAP///3ICGhYACgAPGJATJ///ewQLBAAFoRYERwAA/RcI7C4CfEcBog8A3EcBDgAAFwQAEQAADAAA73YmAv5vAAck2AgEAAYx.FwoEAAI6LwAKAAATHQZ4AAgwAAB4AAAIAAAEAAncRwLWcAIwBgYvAAMEAAIwBgIwAADCBAAUAA8EAAMC4I4AEAtAAgMGArgvIf39.mu8BXAECLiMALGEEqgAC8EgPjQYFYAUEBQUDBbKJB6cBAwQAAPQXAAgAAAQAAkzXAlgFDxgABQAQAAAEAAOOBQLqAAHTFwAWAAEB.HQ+HAAUPBAAIACB5ASFOA04ADwQABQGTAAlgAAIYBgEXAQmoAA8YAAUBPwYAugAAGQAHcgACAKgBLwAABAACzGAACgADBAACekkF.IAAMBAAHJBgLOQAPBAD///9jANS+ACIFAAwAAgQADgYqDQQAAp0FAAoADwQAUgmpIwWGBAQEAAC8BAoZKQISAAIGAAAQAA8EABww.BQUFKuQl9vUMGAAWAA8EACACWAUBiAsADwACwAABuwUJBBcFGAAADQAABAAPXwEFDxgABQ8EAEUHawEAyQAFDFoBGAAAEgAC2wAN.wAAPBAAeAVEAAAkADwQA////gALbAw+fA5cPFX4DBBgGCAQAD0wFBQAGfhD7HVUCAwYAEwAPBABWBPRZAAwAALsAAX0BDzAGCgWF.BQAJAAUhAAcEAA+gHSAPBAAwAEpVA40AD2gBBQ8EAP///0oA+xAGYQ8PBABbApsEDzAGlwYEAAK6AAAKAEEABgUGCAAHBAAE060J.iAUHBAAPGAAFDwQASw5oAQLGAAEVAA+TAAsPGAZjBAQAAK4GAbcGAA0AArQAAAoADwQA////BjUBAgFCCQYJMAq9AwCDWAH2AwD+.CiUC/RcEAy4AAUARAZUVBAQABvHXJwD/SHgCMAACWwADuBcBEwAFCF4AYAACCwUPBAAFATAAAmQXAAoACgxgAgUABgQABSYACxgA.BAQAAooAAwQAAQoLAAkAChioA+4XASMBAOgXBANIABUABGUEBC4AAAQAAxMAAQQABYAAAFMBAkxHAY3wkwgQCP0C/fLx8gxgAZMZ.AhABAgQAA0AFArwEDhgAAAsABAQAAngBAlgXAAoADwQALQTwGAkcAQB7AALUARcBVRoFmQAHqAAAGAYEFwEATgIKGAAQA8l3CloA.AsAABxioBs4BAQQADwxgIAAGAAEEAA8MYP///zkPBAAdBzsKDqIPA3AXAAsADwQAaQFMBQSZAA+WGAUIWQQLsBwNDwAPBAAUAgxg.jwAAAAsNC/XzABgiB3AFAgQAA2UBBxgAAHAFDxioHw8EAFQNqAAACgAPBAD////sBzAGAgQAA9EEAAsADwQAdQi3BgD6BQIDMAID.GArhBg8EAAUANgAASzwBSQsPBABZD3AFBQcYAAIEAAB3AQF8CwDVAAHYGAK0AAA5AAQJAAAoAA8EAFIGewAPDQIKD8wGbA8EAP//./2UOMAYPnEhMABkFD4MEBw8EAAIBMwAPmAQeCaAFDwQAWAV4AAV2BQAWAA8EAAEPIQAODwQAUQA+Kw+EABUBiQEPLQAVDwQA///g.CQxgBAiOAOwKAf8JAA0ACwQAAdFeAm0FCiIACiwRBQQACiUABQQABhUwDwQACAgjAArxBQ4EAAAtMAonMAUEAAAbAAAIAAAEAAVI.wADrIgcsAA+nAAQBsy4C9CMCdQYAoE0BADwECRgAGCoCMBgBogAX/2AAIwD/WQEABAABKDUCigCRCQgJ/vn7/gb4FRgIHF8AGJwR.AzUAGvuRAAWgBQKgFwCtAQH1CgAYAAE/AAW0GAsCAQ/0XwUPGAAFDwQAAAKGAQHeAAgEAAIOJQEJAgGyFwDAAABLAAUYAAJgAAHY.AAAYAAAvAQ8MYAICBAAGuk0BaAECCQACewAPBAAOApsBAAoAAwQAAIQAEv5nAAQEAAhLAA3MAA8EAP///xINYwMJBAAPQBcFAQQA.ACsdBtwDDwQAYQ+9AAQPGgoyBSsRAA0ADwQAPg6jEQR/Cwt4AAWXCwASBgEqBgAWAA8EAGoFkwAADQAHexILGAAPBAD////GD3MF.BAIEAABgDA8wBgcPBABvDb0ABbMECwxgDwQAcQWcAAANAAcEAAtwBQswBgUEAA8YAAUPBABWC6gAABMABAQAABsAAToIDqoHABsA.ATYAAA0AAU4MC7MBDwQA////nw5zBR8B0xdLDwQAMgOzBAKmCw3DAA8EAAhQCw8O9fEPfgNCAAAUAA8EAFQFOgULewAFGAAADQAC.2B4KGAYLMAAPBAB4AoABAAoADwQA////OgIwFQ7RBAJ/FgEYAAILAAIEAAkqBAgEAAIlAAEwAAICFgMEAAISAAEEAAMMMAEeAAkM.YA9VAAYPBAAnD3gYBggXAAeDAAKbAACQBiMCAygLdwIAAwYD/fp8XwcEAAhgAAy2CgKnBPAC/wAIAAjy9PICBggACfsD9vqtFgIY.wAf8kFMIAPv9/glmAXYAAUARDW8ADwQADwIUGQJZAAFOAA70XwPkAAQYAAMVACAAAOKRAQkGACcYCBxiBuMACgQADxgABQUEAAJp.AA4EAA8YAAUPBAA3AocCAgQAB8oADwQA////EA/UChkPBABaD5kABAxzBQ8EAJcAGLoQ/AAeAA0ABAQACAxsDwQAiQ8LBwIPBABs.ByQkARYCD/YF////GwwEAAK5CgdzBQFRAwBfNA9tBZYHvQAPBABxBRjAMO327QcADwQAEwJnBQIGAAAQAAoEAA8YAAUPBABoC5MA.BQ8ABQkAABYAD/oXAQ8EAP///64NMAYPBACGAskGAAoACwQAD70ABw+tBDsAEk4BGMYADQAPBAAlD5MACw/kAAUPGAAFDwQAaA7J.AAOTEgALAA8EAA0PswEHDwQA///mDwxgBg8EAAQAqSkOEQQPVwMUB/wVAFRgBHAVAtxHAPguRv8A+wLgECYC/087EAFyagNmAAdH.AAFpMA6QAA8EAE8IkBgCCwACBAACNC8A/adBAAMGAnyPATQXL/j+ynEhIP38Wkhj/wH/AwYDDHIFawEAgME0BQADeDAPGMAlDD0F.AmAAAgYAABAADwQAAwUYBgNoYQFLAAkEAAVCAAIGAAUEAA8YAAUEkAADBgAFBAAPGAARBdBfEf2SAQ4YAA8MeBMA2GACOQAADgAP.BAD///+FBT4EDwQAoQ/zDAQFTAUADQAKBABRCAgI+Pj3BQ8EAG4CtwACBgAAEAAEBAANEgAOoAsPBABoCI0AD2gBAgz/Bg8EAP//./7kPbQUEDwQAkAK6AAe3AAkMcg0EAAjjBA8EAGYOaAEFxgABIAwPBACTArQAAAoADwQA////DA9ICQIABAAPPwOXD8MAAA+9ADoO.GS8PBAAmDAMMAqgAAYpaD/oFcg8EABAFqAAJDHgLnGwPBAD///+AB7cJCLAuAnwvAg9ID5TvAAAXAAZ1FToDAAM8kAAwLgAKAA8E.AAc1Av4CmgUNXgAEBAACdBYNBAAAhGAACAAABAAFRQAAly8FNC8P6L8EAJUEABAAAAwAADAAAZAYAA0ABDAAAjAGAy4AAQQAASbp.AcgEAA4ABwQAEAEPSABRAAWyZQHmBAUYGAATAA+/AAMPBAAAAp4ZDwx4AwKwGQJLAALcXwRYBQKbAACEhBH/iWECGAAAFAAABAAP.dgVIAXgAAAQABZ0XBQQAARsACJUBAwQAARgAAE4wBfR3AhgGApQRAtgAAQsABUoBAw0ADwQADgSTDA8MeAwPBAD///9fDwZICg8E.AJkCiAsEZQQPBACQAlgFBfoFAsAAB70AAuQGAAoACgQADxgABQ8EAFcCZQECBgAAEAAByQAFDHgBEgACBAAAYAwOlAgPBAD///+b.AasJCXEEDzAGEAkwAA8EAHAChwwy/v/+tTsPbQsvDwl4Sw/cdwcPBAALD3cBdQEYBgASBgJoAQ/AABYPBAD///+iAtsDAfADAA8A.DwQAoA8YGB0A+i9D+/r4+BveDwyEKg8EAB0PGAYFCxgADwQAvw9hAqkPBAD//1ABvhsACQABEwQAEhcA7BYDEQADBAAAyi8ACAAA.BAAo+gC5NAH7BAHlCwhjAwJkFwAKAAH7dgFXLwElAALSCQELAAAwMAFzAAANAAEXAAMEAACDAAAIAAAEAAgYAAUtAA/9FRADbFQB.ngAF9BcADQABewAGBAAEMBgABAAHlgwFSBgA5BgHIAEIDHgAFwARA85eEQI8eAT/AAJsAAxMCwJtBQAKAEAABAMERQAXA88ADwQA.DgRdAABcAAc2AAC1BQLSAAJYFwAKAA8EAC4CqwABeBgFGAYACQACvAEFBAABkwAP3HcADxgAHQ8EAAgC2wABOQAJBAAElgAAUQAC.aAECKgAEBAAArgAEIQAPBAD///8RAHA1AFcEAAwAAgQAAz0FAAsADwQAjgr5Aw8EAK0PuQQFBg0RDwQAawUbBg+7HR0PBABoArQA.AAoADwQA////Ng4wBg8EAHQMcwsCMAwPbQoWDwQAIAUYGAANAA8EACkCpAQH6QoP4HYUDzAGBQ8EAF0HwAAPGAaWDwQA////HQ9C.FaoPvQA3D90EMgUMhA8EAA8HWAUCBAAAECMPGAYQDwQAdQfAAA87AQUPGAAFDwQA////Wg7bLQ8EAAsHMAAGCTAX//GnAecVAgkA.AKsXCQyQADAADtoKCGAYD10MEQhEFgLAMAAKAABtAAMIAAYEAABxAAkwGAUwADkCAALwMAHyFgAJADMBAAE5RgbqAA4EAAB8CwIi.8QCWPAdhAA8EAAUA93cAJwCY/gL+CAQI+gL6ZhgPBAAPBJIAAJMAB1gFAgQAD/wMAAEeAA9wFxsPBAAdApMAAWkACQQADxgADgvA.AAEYAA4MkAMUAg8MkAEG5lkOBAAQBAUAAh8ALwX9DJD/////DA8EABIBmwQCBAAPtwA1DwAMGA8EAB0HWAUPWAsLD2ASFA8EAP//.///7DsYGBQQAAAMqDxsABA8EAHUIGAYPMxgKDxgGewT0pw99AQgPBAD///+3BzAMDwQAjwMGNgQMlg8EABcClAsCPwAAEAAPBABu.DxgGFg8EAP////wPHwo0CDAYCQQAAWAAAGYkEf8HXwAOAAEEAAGnBAIEAAV4GA/YFSACeAACYhYAEAAPBAABAwxgDwQAAgJuABH9.jF4BCTAAADYCiI8BNQAFDJAApQAHZQAAbBgR/xoZ4v8ACQgJ+/r7+/n7+wT7XsAAyQABeQsAiAUPuBEHDwQAGwDpABAAr0kAdRMA.EQADbHIBPQEDUKkBwwAA25ABmBMAKQAiAQKOGQAJDAPLAAAEAAP8YAIwAAeiAAIISQXAAAATAAEIAQ8EAAAPGAAFAgQACNQXBCoA.BREADAQAKAIDaAEAgwEEMwAABAABr5IApAcGUgAAtwACCAAABAAILQAPBAD///+kDzAMmgMEAAVtCwGXBQ8EAJUAkAYPGAwTAAgT.Dws9GQ8EAP///3oOYBUP7Bw1DwQA0Q/4BOYFGwYC2BIAEwAPBACCDt8CDwQA////LwCdEQhaDw8EAHYP6gMXD8MAJg8MlkcFSAYP.TwWMDwQADg/AAHIPIg6hDwQA//9kA/CNAVIXBQyoAAQAABcAAAgAAwQAD1EDAQcuAA8EAAcPJQASDwQAJwLQFwAKAA8EAAcAqTsE.vQAn/AA4FgCSEQAMAAsEAA9UAAwQAuIwDz4GIgQEABEEPxgCBgAJSAADDQAAIx4T/VgXCzSnDwyoAAKFCwKEGATvLgIMAAAnAALk.AAF7EgB+GAJmYAATAA8EAA8CpEkCqDACbwAAFgAHBAAAfgACpQAKBAAA5B4BFwAAZQcFwAABVQEODKgCuAAAFAAAbgAADAAFBAAI.FBgLBAADqHgBBAAAaxkEDgACVAAACgAPBAD/////Ew8wDBcPBABuAGoFAugFD14LBAV2CwUqAAAWAA8EAHkFmQAFqwAAFgAHBAAP.jwGYDwQA////AA/WXwoPbREmDwQA/wsFMBIADQAPBACqBOgvAAwADwQA////uQ8wEgEFBAAPYB6ND70ACg8EAP+QAmslAAoADwQA.////NgO+CwFjFQMUFgEwGBcAMBgBRxgACQAB40UBDQABMAADSxcBEQAGLgAP/QVnD9wXBggXAAGuAA8EAA4A5hYT/z0vABAAAQQA.KAH/SQAPBAADAABIsAT6+gX6+wX79Pn0EwAPBAAKApAwAjlCAPQLATIXIP7/AgAAjAECGAAIzEgBBAADY3gR/1GQA3AXAAAwAmzA.IwD/hREy/v7+TBcDnRETABgAD0MFOALAAAKrAAAIMQAUAAAEAAUYACAAAkVhAAoAAXoABRcAAg4ADwQACwCuAARPAgaFAi0CABAB.DwQA/////zAPHEEJD3EKiw9wFwUCBAAPSBKJADMYAXwIDxsY////qw8EAAIPMBgKAgQAAPMDAfwDAA0ADwQA//8NDzKvlQ8EAP//./wwPcxeaD1ILCw8EAJUPxgALPwICAh4ACA8EAP////8aCGAwDzAYEgG1FgC9RQ99BHQBuQADBAAQ/ugRAEYvAbAADAQAAsMGAsYA.CgQADzkSAAJFMAKtXg8EAEoAHAsF9L8BBwACvQAcAQzAAjAYD/QFCA4wBgIzGAAKAA8EAEcAlQABwxgCXwEAEwAMBAAA1hgCHgAC.BgAAFAAAQgIC3gADPAAE5wAPBAD///+YDm4EDwQAcgQGlg8EABEAwxIPthYND+cAgA+TAIAPBAD/////zg9wBf//////Yg8EAF8D.8DACJyQPhhD/NAk1BwJZAQAKAA8EAP///y4PmwQEAPIWBD8VBUBHDwQARAJgMAAKAA8EAH8CfEcAygUADgAPBABBALEWA1UXIP37./kYPDQFfCDAYDbYYAwQABOQYAIUFCv8wAgQAA8MADwQAagA+AQAIAA8EAP///8cJ6hsPBAC6APUuACGuD8I0/////0IPBAD/////.//8UD7AiEQ8EAP5fAwQD/vyqC0UP2jT/EQ8UkZwPBAD//1sC0i0ACgAP9l0ZDwQAlgKGFg8fBWsRAZsuAAoADwQAGcAEAAMCAAYB.AAgAAPcQAAUEAAOkAVcDAgD9/wzYD5UHfQV9EwIGAA0EAADDEgWdHQ8EAP//////////////////////////////////////////.////////////////////UkAD//v9yKYPADb/Dw8EAP///////////0EP/UH/IA8EAE0P/QuKD5wAcwAjPQCXVQAMAA8EAP//////./////wUP9EceAlJHAgQAB94JCACQA/lFDwQAbg+HAGEh/gJoTBT//kYCFGEBFAAPBAAbEPzcWUD6/wD4DQAPBAADMP0BBXcBA3QB.AYABDwQAdwTzAA9hAh4PBAD/////////////7gOhWAGFswAJAA8EAP8xAPcXAAgAAQQAAV4BDwQA/////6oJywQPBAD/////5QOU.pwFVFwZ87w8EAIUGlxcPBAACAcYAAgQABVAlAwB+AAsABAQAEf5IihH84l8AEAAPBABSB5wAAo3YA34ABRgAIP790hgBFAAB8RkA.6AAP5RcID+hfdBAF9sAACQAIVZIAxHgBnAAAf7YEiQEPBAD/////Tgd9BA8EAKIP6AUHAgQAD+sFcQ8EAP///8kPPQWaDwoFsw/G.AAsPFa6GDwQA////1wA9EQB/EAAMAA8EAP//Dg8mN4oPBAD//+IJ0BcBDAAANBcI9KcCECMPBAB6BZwACwQABKoAAJAGAAgABgQA.ALnvIP792qgHE5Ev/wFJAAUGBAAw+Pz4AwBK+/j3+/93DwQAERH/ORgBU6kC/PAPoBcIUP3+/fv+HqcAKQAEmAACMAAABgAAmgEA.EgADdJEB6Ncz/f/7/Y9AAgD/+xgADwDYCA8EACwDKAIAXgAAkwADDAAIBAAS/jkCA0wCDwQAAgCEkAIkAADD8Aa3DAA9eQAIAA8E.AP/////qAOIFAAgADwQA/////2cPsQkHDwQAkA+9AKoPBACmD5AYCw8EAP///6oExA8PBAD/PAXpEA8EAK4BkBIACQAPBAD///9k.IAEChBUD3RYP+AoECACoAs0FAgYAAhIADwQADBMCOQABBsADCQAPugQ4AzzAAQQABlAWDwQAEADDAAY7AAkEAAhUAA8EAAACuy8A.CgAPBAAlIPwARqkCBgAAEAAFBAABaAERABUwBwCoNQEAAc0RMPv/+3IYEP6eLwinADP6//oYAAcVAAF0AQC+FwAbAEEAAPv8DBgB.EQAPwwAtAQQABZYACwQAAcAAAAkAAqIAApgBABUAAsAAABQABhYCD0MAAwEEAA8bAAgDtBgBBAAACBkGDgAPBAD///9GD2ADCg8d.HEEPBAA5D70ACg8EAKoPggUFDwQAcQNVCA8EAP///8EAOgsACAAPBAB+D3EEFw/DACYv/fs5ACQPBAAOBdARAigLAAoADwQAow/A.AHIPFweIDwQA//+ADjcFD9ALjQ8EAHkFuAUPBAA+Av0RDwQAhgV7DA/xBQsPTAJuDt8CDwQA////LQfQFw8EACsIRgAAIBYACAAL.BAAIIwAHBAAIUwQDXBYP0AsKCO4LAtwXApDYADgWABQADwQACgGTFwDjBAL1pgA4AAG71xH5BhgA/y8TAkgAAIkAMQAB/QcAAgQA.B6gABesX8AD9/v33/Pf6/Pf9/PcA/PiSFwK4FwFgAABVBQFBABL7aQAPM1QpATkAA5wAAUgAAsgZAMwAMgAA/ozZARgADwDwBQMY.AAEPADD6/vpqAQEwAAAeAAQQGgDQFwLAAAEPAAAEAAA1ADAA+wLaAAAYAAQqAAA/AAUMAA8EAC4PKEoeD3gANA8EAP////8aD3cK.pAP9BQ8EAIwBqwYACQAAIx8Hj08P5QX///+nD7cDmgD3Ow8lBZIPBAAOB80LAv0LAAoAAQQABdUSDw8Gkw8EAP///8EPPQt6DwQF.CwArBQKsEQ8EABMP2wBgCOgFD8wACg+cAGAPBAAHBZMGD5YAeg8EAP//wAPpCQ8EABYPMAAEAlgXAAoACyxGCQsABA0AJwEAvy0g.AP5KFwEKAAGxLgMJAACuBAMIAA8EAAkBUwAC2hYY+0gADwQABA84FgYCFwAHKwUDBAAASF4AF8cJ1QACLhcQAS8XAEoYDjYAAQQA.CTEABQQAv/0A+Pj4+Pv7+P7+AHgIDwQAIQeHAAOfAA5wFwHnAA9SBQgA5HgCXTACPAABMAAPBAADAhsAC2AAAjYAAwoACgQADioA.AgQAARgAAMAwCzwAAQwAAEgYB9gAAgQADL4ABR4AAUQZADkCBRIADwQA////cAh8HQ8EAHoPBAUAD7AFAw8EAH8OEAUOzAABBAAP.5AAADwQAcQ3AAA8EAP///5APrgP0DwkSCw8EABQAMBIACAAPBAAQBCgFAM0LAAgAAZrjAQkADwQAkwTAAACiBg87AQQPUwEyDwQA.////XA7QCwsZEQ8EAGUJHAUPkwBSP/3//fwAMwcoBQIEAAnMAA8EAAcFGAYPBABsB8AAD9AFcQ+EAHEPBAD//5gy/wD/DS8QAI5G.BKUuBEgVAgQACPQFBS0ABjAADQgWEgMSAAEEACf+/w0AAjwAATQFArgvAyAuCAQAAhIAB04ACQQAB2sEDgQAAV4AAAQAAkQABQQA.Ah4YAAoAGf/MAAUEAADHBRT/9RY/AQD+eukEIQP/HC8R/fovAYhfjwIAAv7+/v0BVAAADwQABQA1ARD8PAAO/AAP0AV1CAQACG4B.B30BD6sABgFEAQ/ABgAPGAAKAAQABFoADwQAEQAaSQAIAAQEAA88AAQDPBgKzQIPBAD///+rDTEFDwQAhgzpBAe6AAOFTQ8EAIYF.5QUCBgAPBAAKDOcADwQAUwd7Bg+BAGMPBAD///84AhYFD2gEEA8EAIYPzRcYAQQAMPr8+gcAggAA9fb19ff1DAAPBABUEf+0JAAK.AAEEAAfoBQkYAAcEAADtDAAIAAGQVAWpCw8EAJ4C5wAPBAD///9lAJ8JCjkEAf0RAAkADwQABw/VCX0F6BcP+jU1L/X2+gVJD+gF.BQ8EAA0PdwF1Aa4ABmgBD8AAFg8EAP///w8HRQMIPF0CEC8P/AMGAPcEB6UVBOBGDjAAANAXAi0AIf8AIwAACwAZ/TsAAP4XAiMA.AXYKEP8QAAEOAC8D/aAXBA1mAAMEAAfAAAgEAAKmBQAKAAIEAAIOAB//dxYBAQQACTAAAlMAAgYACAQAB+gXALEABTIABf0vANgW.ABEADwQAEVH9/P0A/DePCKMFBAQAABgAAvgEFP1aAAIEAAWWAAgYAAiHqAE1AAYPAAEEAA/2AAUPGAAFDwQAGwFsADMDAANgSAUE.AA8YABEBDAACEgACBgAD7gUBDAAIBAADGAAKBAAPF08MEfzzBgAKAAcsAQ8EAP///ywFGR0BwBsAIEwPQQQyDwQAUw8sBAQPBAUp.AMQFAQsBAA0ADwQARwX4CgIGAAIVZg/QCwEDGAAPBAB5A5MAAqgAFP+6AAXDAAQEAAsPAA8EAAwCTgAPBAD///9DDw0FBgrCCQ8E.AIkPwwAAD70AOg/oFwIJPwwPBAAWKvj49jsF0AUHKAUPBACMBagAAwkAD8AAnQ8EAP///6UCbAUCawQPBABkAvoLAAoADwQAGgXi.BQQEAC/3+feJCQ9GBXIKsQAABAAFxgACBgAPBACSAjQCDwQA///cCfwbDwQAECb/AgAwKgD9u0cPBAAODwsEEDUC/gKdCwhdAAMw.GAFCACH8/0gwAQQAABgAAAgAAAQAAzcACAQAAYoSCP8XAFAWEwCqXgOhBA8EADok+wOvKQCmSAGSAEEEAP38Eh4CzgAR/xgwBHcB.D5AAC/QF/v3+AwIDAf8B/fr9BQEFAAAA+wBgAAsEAAXlAAFKAAYEAABfAAAIAAwEAAgYAAE7AACqEwtLBggYAAEMAA6iACwC/6uo.AC0AAAgADwQAHAVaAA/AACAExBcAMBgFjQABxy8FjQAP3C8FAF8xBM8CIQL+CgABgQAL1QAPBAD///9TAvcFAgYAABAACwQAD48D.BA8wAAYPBABlAu41AAoAAwQADgYMD3QHGg/9I0sCmU4BCgADKwUCHwUCBgABBAADGAAKBAAFdwEPKAV6BZYADwQA////kwI3BAdo.BA8EAIYPVgQGD70ACALeAA8EACsR9QEAUwAAAPr6BjAPBAApD8cFAg8EAKEOyQAFwwYPBAAPD7MBCA8EAP///y8C8gQHYAMCNwUC.BgAAEAAPBACPB70ADwQAOw4DDA8EAE0OJQUCBAAPGAAFDwQAaA+TAAULGAALDwAPBAD///9oCNoiCPwPA4gvATwVEf+5pwInGAM4.dgIEAAAXAAAIAAwEAAcjAAcLAA8EAAYChDAACgAAOxcDCAAABAALYAALDwABBAAmAgBgGA8EAB4PUQABAAQABI8AAKQEEP9HLgAJ.AAARAA8EAAQEMAAAv2Af/5AABpL9/f36+/r4+PhOAAIGAADFFgAdAAa4EQIEAAX/FwAEAAJsMAJZYQFRAQAtAA37Fg8EAAMEJAAA.MwAACAAEBAAIGAAIDMAEBAAAGAAACAAEBAABeAADMAABCwADMAANGAACBAAIZDIPBAADD8AACAEPMgBgABMBCRgDBAAEGBgABAAA.jQIACAAJBAAl/v1MAgC2NwYuAA8EAP////8zD/QLFAX9BQCsBQLXHA/mBAEA3QQACAADBAAFPQULGAAPBABWC3gABZAADwQA////./zwHXQwDBAANGQUAPQUDvwkPBACEBgYGAs4ADcMADwQAEQttBQ8EAFAF0AULewAFGAACBAAIDQ4CBAALMAAPBAB4DKoADwQA////.cw8NBSIPBAB1Db0ABfsED/SVRw8EAD4F0AUCvQAO0AUCBAAPGAAFDwQAVguoAAAKAAQEAAUbAA4EAAwbAA2zAQ8EAP///xcP9KcV.BBsAAgwYAgYADzAABQkEABQCXQAAPBcCCAAACREKbQAAhAAACAALBAAIIwAPBAAECGx4CDAwCAQABYEACAQAAMMABjsACQQACFQA.AukAABMXAkUAAmsWQAMAAPnQEQlZFgJ9AAc7AAUEAAP01xMC4wQw+/j793dY9/j39/fcpwIEAAP6RwcYAALYAALyBA7EvwIEAAA0.dwt8jwEJAAaUjwpkFw8YAAUPBAAADx4ACAERSQMJAAAHAAQEABn/3KcDwAAC/AAHGAAABgAPBAAOADUADy0ADBcCHgAEjQENBAAH.JAAPBAD///4OHwUArQQACAAPBAADADoFAAgABgQADzAACw8EAFYOyQAPBAAFDsMADwQAFwCdBQAIAA8EAEUPYAACAv0FAAoACgQA.DxgABQ8EAFAPqAACBegFAw0ADwQAZQ8XAWcPBAD///9UD8wJXg9aBhcFBAAPMwAXAuULDgQADxgABQ8EAEEFSAYPvgUODiEAD+oA.Fw8EADYErgAPBAARD58AYA8EAP///yAN6QQPtAOACOQMDgQFDwQAEQI2AGD9/f3y8vIQAA8EAFYHFRIF6AUABAAHGAACBAAFdwEF.FRgCtAAP1gtiBasABZYADwQAAg8eAAsPBAD///9NCPsWCOQtCCsFBSMAArUWAAoAAR4ABi4AACJHD8MDFgA7AAd4ACUAAOQtDwQA.AwYpAAQEAAESAAbQFwUEAAVfLgiaAAsEAAKsdwEGQjX9/v1CAAUJAAsEAAkIARH8RxkBHC/ABQb98vP19/v1+Pz4hRcCGwEBeAAA.9QQB0QAP9KcJDRUAA4EABxgAAkgAAxgADQQADxgABQBxAALCqAGEAABOAAIJACMAANh4DTAYAHxHADcABxUAAjMABQ8ABQQABRgA.B6gAAAQAAQwAAMAYAh4AAA4AAQQAARgAAGAACzAADQQAB2YBAIl6AK4GCRMADwQA////DA8LBAgGBAAPfgMKDwQACw9qFykPBAAa.D8kAAAIFBA+9ACgPBAAOCeIFDwQAEwX3cQkEAAqlAAPMAA34BAMYAAQEAADlBQAIAA8EAG0HqAAJkwANGAALwAAAGAAPVwxeDwQA.////EQ/UBAsP0AVWDwQAAAKYAARTBA8EAFYOtgQPBAAeAroADwQABQQeAAIlBQAKAAoEAA8YAAUPBABLBzxyAwkACNAFD7gFCg8y.ATAPBAA0D4oAdw8EAP///xUArgMB8T8PBACCAPJ3D/gECgUEAA93BAXv+vz6+/z78vP18vT18/T9U0sMBAAH0AUABAAFzQUPGAAF.DwQAhgeuAA9oAQIJzwAPBAD///gH1QMIrBcCykcACgAAOxUBfF8FqBUCDgQF/BUBBAACoHcEeAMBPAABMAwA5C0ACAABOQACQgAA.vy43/QP+ahcBKgAACQAARhYB9F8BaQAW/ZAAAFEABTAABmwMBSAAAQQACMAACAQAD7oMBg8vAAMDBAADNgABBQAAvQACW0cBDgAA.BAAF4y5x/gD6A/oAAwM2MQQA+66/BcMAAAYAAQQAAT4XD/RfBgAzPHD8AP79AwMC8V8AEwAHBAAD+i8AXwsHLTERACR4AngGD/R3.EQ/QBQ0FXwELBAAPGAAABTkAAvcXAAoADwQADQEzAACsXwB5AAAMAAMEAA4YAAESAAIEAAP2AAISAAEGAAMSAA/AAAMABgAJBAAK.IQAFBAAPPBgRDwQA////DAKqAw/0dwsCPQUPBACAApgAD/wDBAnDAA8EABAFECMCBAAAxwUACAAPBAAnKvj5+nEBvgUG9QQI+AQL.THEFGAAEBAAJHgAHBAAP5AAdDwQALQeoAAMJAAKoAA8YAAUFDwAPBAAHCSEABDYADwQA////4QL5AwKBBQIMAA0EAA/sBEcJgwQP.BAAjCrIFOfj4+PRxCh4ABiUFDQQADxgABQ8EAFQFqAAP0AUHDwQA/////x4P0AUKDwQAkw/DAB8M8X0PBABWDqUAAhIAAgYACAQA.AhIAAgYAAQQAA+UFDwQAcwiNAA/1Bw8CoQEPBAD//9wJ/BUPBAAQNgH+AUgDB/YDDwQAEgj9EQILAAdCAAJXAADEFwQ/Eg8rBQUI.FwAAWncFMAACVAAPBABGCegXCMoFBIEAMP39/QS/BekKAR8ZAG0XCjgACAQAD4RgCwLKF3EB+vj9+foFyxcU+1oSgP3+/QP/+/3+.3l8A+jsFjQALBAADLwAEkwAFBAAFGAAj/v3JAAIgAAQYAAAEAAcYAAlEGQILAAEYAAM8AASyKQIMAAAEAAhIAAgEAA8YACUFYAAD.yQAEGAAABAAF3F8I5BgBZaoDGAACVNgCDAAIIQAKtwAPGEgSDwQA////CAIxAwdCAwLXBAIGAAAQAA8EAHYPkwAGB70ACAQADzAA.Bg8EAAoC9BcDrQQPBAAiD/c7Iw9yAAsPHgALDwQAWQWKAAUJAAIEAAUPAAUJAA8EAA4IxAUPBAAMD+MBBA8EAP///xoPDQUjDwQA.Yw/tA5EFUAEDXQwFNxcBBABx8vPy8/Pz+ksGABAABAQAAvIEAmu0AP0LAAgACQQADz0FFw8EADICkAAACgANBAAFigAFCQAPBAB4.B7cABYkBDwQA////igcZBQ8EAIAF4AQA8SkACAADBAADGAABrAUI3AUPBAAgIvv8RgAPBAA/A6UADQQADxgACwvnJAUYAAMNAA8E.AHoMqgAPBAD///8bCfRfDwQAEQ9sAwYI/wQWAQ0FCDAABBUAEP46eAQNAABTKgCEAAMMAATERw+TABQIoF8AeDAACAAPBAASAI0Y.BjsACZoLCQwAAYYACOoqAv0RAOPAAf1HABMAAgQAArkAAR0ACwQAD/RfCCD9+jwwYf3/AAIBAE95B+IvCgQAAIgLEQH4FgEnAABR.AAAIAAHmFhEBiO8CxF8BHgAA1AEBAQsAfF8PGAANAjgBAhgAACIACwQABDkADwQAAwI1AA4kAA0YAALVAAB4AAAOAAcbABD+RzIB.HQAHFQABBAAFkwAFfQEFBAAFGwABXHkDCQAP3BcIDxgABQ8EAP//8g5dAwVcBAYEAAeZAwA6BQAIAAYEAA8wAAAHBAAOMAAPBABE.DskAAwQAB70AAgQAD5MAHQ9aAAYPBABAAigFAAoADwQAEAgHBQ8EAFwPqAAFBRgADzUBHQ8wAB0PBAD///+6DaAFDwQADA8wAB0P.BAAxD+QGBQAoEQC9IwAMAAgEAA/OBBcP5RcCAKkLBxgAD+gFRQRjAAVgAAW+BQ8EAAUOIQAP6gALDzgBBQ8EAEsEzwABRwEGDAAP.BAD///9XBFYEDwQAJg9TBAsPBABXCskABf0XIv38/0cDDwAPBAAUAjoFD/RfQQMvAQHNEQAJAATlEQIMAAAUEQTJAAwYAAAHAAYE.AANIAALVBgEKAAK0AABGBQQJAA8EADwIkAAKBAAFqwAFlgAGBAAEGwAAmQAOHgAPBAD///8FBAIEDwQAIgBBXgAIAArSFQPZCQHh.CQcXACcA/iRIBSjvAXAEACoAABYAMgEAAQDYAREAD44RGAEwAAY4Rg/0XwQDdAoBBQAAgLIIIwQBFQADkwACJwACBAAP9F8FEQO1.FwHpXmADAQP6/frHFxkDswAASwAACAAMBAADhwACBAAF9F+//P0FBgXy8/L3+/f0XwUAS3gEnRcAFgAEBAABGAAB/gACiUMBMwAP.BAAID5kABQ8YAAUAiQAL9F8ABwAABAAD+EkCGwACeAABJAAAfC8ANwADLQACwAAAYBgFcEcBOwEARAEAIAABBAACGAAACgAD1XgA./JwjAvowAAMRAAMMAABgAAsYAA0EAAI4GQgEAAJXAAA8AAWcAAESAA8EAP///wIOCwQJtgQNBAAJ+QQPBABcApgAD8kDBA7JAA8E.ADgFEAsPBAAUDI0ABz4Ah/r7+vLz8vL0AwwCoQQC/QUAEAAMBAAPGAAdDwQAKgSNAAMGAAgEAAUbAAt7AAcYAAIEAAz/AA8EAFsJ.bAYPBAD///9tDyROAAgEAAIWBQo7BADXBA8wAAUPBABcAZkACE0EAP0LBAYAABAABygRDwQAFAjipzDz9PMHAA8EAEAPnQUDDwxU.BQQYAA6nAQX8AAAJAAHuCwsEAA4zAA8EADABlgAAcgAACAAPBAABAa4AAAkAD9wXEQ+gARsPBAD///8QDm8DDy0MCg8EAG8BTQQO.BAAPOAQAAsgADzAABA4EAA+hBAkPBAAKIPv78SkACgAPBAALB6AFAAYABewEDxgAHQ0EAA8YAAUPBAA8B5AABSwBAwkABBgAAAYA.AQQACRgABwQADxgABQ8EABsPPwAsDwQA//+dAswJAAoADwQABwnwRQL4BAEEAAH6FQPhFQ9IAAI//QAAxF8RAEIAAAoADQQAB3cA.CAQACJAAAEgAAAgAAAQAA2wSAh0ABV0ACjAAAgQAApMACboSBwsADwQABQ8jAAUDeAAQAfoXBeILAPAdARQBMAMBA+i/EwIYAADL.XiX+Ay8BAkQBCfRfBQoFxQAA+/v7+/r7/vn2+/RZBR4ACOBGEf3QBQAKAAEEAAIYAAJiAABfAAAIAAAEAA8YAAoAeg0CQAUFBAAP.GAAQDui/AwQAB6gABj8AAggADxgAAg9EAAEABAAHGAAGMAABPwADCQABfwIACQACBAACXQAHBAAP3BcAAAoABAQABTBIABkwAwgA.DwQA////hAKlAwHMAw8EAI8A/QUErQQA/SMCAzYPwwAlF/cGEg4EAAkWBQ8EACgDSAACnwACBgABBAAPGAAMDQQADxgABQ8EAGIP.jQAbAqEBDwQA////NwJkCwIGAAAQAAsEAAJsAwhQBAEqAA8wAAYPBAAEDzAAHQ8EACAPYwAGB70ADwQAGgX9Cw8EAA4A6b8P6MUc.D/IEBQ8YAAYPjQAWDwQAAg/9CwMPBAAoBagABQkACwQADhgAAhIAAgYAABAADwQABQ+qAAEMjAEP1AElDwQA///qDzMDhg+ZAAQP.0AU+AgQAD4AEDw8EABEHoRAj9fX6BUX4+vr4BhgCHgACBgAPBAAHD40ABQ8YAAUPBAA/AqIAAgYAAQQAA3sAAhIAAgYAAQQAAxgA.DwQADQ8nABQPBAAMB3gADwQA////Ggn0RwhCAwcMAAKtLgK8BAMqAA8EABcPmQkBAQQAAU8AAwQABiRID8QvAgAEAAQhAAsEAA/0.Rx0PMAAGBhcADwQACQP3NRD9fEcC648A5RcC5AANQgAOnBgFBABg+vz69Pj08S80/wMCpwoFcAsCEAUCBgAAEAABBAAAzgoB9EcA.nRcOhgEHXDEADwACBAABpXgGFQABjwAASAAC9EcADgABkwYBGAAUAIcADHgABA8ABhgAAjAADicSDxgABQgEAAIaAAQqAAMEAAHY.AAAJAAIYAAIGAAIEAAEwAAPbAAgYAA/cFw4EzwAAkAAT/4owDwQA////WgirAw0EAAXpBA8EAAgA8AMACAAPBABID2MABg+9AAoD.9E0PBAAxP/Dx8CsFCQ8EAAQCtwAFRAEFQgACGAAACgABBAAFGAACBAAFMAAPBAAUBe0eDwQANQWQAAyoAAepBQsEAAKrBgAkAAoz.AAwEAA+qABEF1AEFCQAPBAD///cLkAMASiEOLAQHNgMDEyMHBAAPXAQLDjAADwQALQeNAAgEAA7JAAMEAA8wAAQPBAAUArkECxAF.BZsEDwQAFQf9ETDv8e8HAAoEAAVgAAJvAAAKAAEEAAIYAA9vABcPBQEGDwQAPQWoAAUJAAIEAAUPAAIJAALAAAAQAAoEAA40Ag+6.ABoMEQEEXAEPBAD///+lD70DhgJbQQAKAAAEAAP9ERAA3OkClQoGxQQNwwAPzgQGASoABQMGAiUFAAoACgQADxgABQ8EAB0LhwAJ.NwUHkwYD/RET/3cABbUFAxAAB9MRBQkACwQABTMADwQANQmrAAsEAA8bAAgCBAAHIQALAgEPBAD//84PNgMGBeoDCjQvA3xHDwQA.CgDBCwUmAAY7AA8EAAEBBAQJMAAHmBYAKxcAEwABVQUCeAAFMAAACAAGBAACMAAACgALBAABMAAGSAAL9EcFjgUCBAACDgAQ/6kF.AAkAAQQABTAAAGMACDAAB/RHBpAAApgWAg4AEf70RxD7rykAIQABWxdjAgAC/v7+EEcNBAAGHgYAVA0DCAAQ+vEdcPj+//719fX3.fQK8FghMRwEEAABgeAKgBQcYAA70RwDvAQHRAAY0RwcYAAAwAAJajwQwAAArAAG6BgIJAAUEAALBAABrMAJgAAFUAABOAAEIAACk.AQLkAA2oAABIGAKfSAEYAAUeBgAYAAFNAQIwAAYYAAoMSAATAAFOAAbAAAAOAAEEAAEYAADcLwdGAQ4EAADIAQAIAAkEAAIYMAkE.AA4SAA8EAP//9ADLBAAIAAYEAAm2BA0EAA8wAB0PBAA5AmgAD8kDBA8IBAIPBAA1At0KAv0FD6mnAwoEAAyNAAA+AAAIAADdTAFF.AAMNAAIEAAf4BAIoBQAGAAIYBgEEAADNBQAIAA8EAAYMbwAPBAApBY0AAgYACAQABRsABw8MAAQABxgADwQAHQlIAA8EAP///7YC.2wkACgAAaAoF/QsBEQAKBAACFgUNOwQPMAAGDwQAUA2NAA8EAAsCGAYACgAPBAATCPRHDwQAPwK9AAL9CwAKAAEEAAWdBQ8YAA0O.dwEFnQUACQACEgwPBABHB5AAAG8MBHsAAKgAAQgABgQAAa4AAAkAD8kMAQk8AA8hAAQPBAD///8pDk4DCf0LBwsADwQAXA6ZAAM4.BAJTBA0EAA8wAAYKBAAASgQNKQACBAAAGwAACAAPBAAeMPv7+/o1AQQAABAAB/gECVQABxgAAAYABcsEBxgACbgFDcAAAxgADQQA.DxgABQ8EACADsQAFkAACDwAFggUPGAAdDQQAAxgABDAAAAYADwQA////QQc4BAH6FQG+CwQUCgAWAAoEAAj0Rwn9BQ8EABECyQMI.BAABEgAJkBgAfwAACQAAFwQEaQAABAACawABKQA/Av8CnwACAiMADwQAFw8wABEAcBcEoQQD/BICDEgCKBcQApgEJwP/9EcBtAAJ.LQsFsgWAAAD4+vj1+PX3TXT/AAUDBfv5+jUBRlkC6I8ADwAIAEgF+wQAWQAKqAYBGAAAYg0v/f0YAAYACwAPBAABASQAAioACQQA.EALuAAAJAAnEAAEEAAItABT9cgYCBAAIeAAIBAAPGAApBNwvABioBWQCBDAYAtwXABgYAjYACywBBDwACWwYAxEADwQA////Mwn8.AwgEAAJ1AweKAwIqAAIGAAAQAAsEAAIwAA0EAA8wAAYHBAAFbQUPBAAjD2MABge9AAB+BgH0BQMNAAX0IwoVAAIEAA+QACAv+vkJ.Ei0F3AUFCQACBAAFjQADGAAC1QACBgAFLQwNBAAPGAAFD/MABQ8EACAPSAAFDxgABQB7AA2WAAktAA9DAgQGBAAPIQAODwQA////.BQQsBAsEAA8jBAgPBABUD5kAHQ8wAAQPBAAsCYMEDwQAEQSHAAXoZQ/9BRoCbwACBgAAEAAPBABlAoAAAgYAAQQAC5MABQ8ABQkA.AgQACw8ABQQADxgABQDRAQTDBg8EAA8EXAEFBAAF/wYDBAANIQAPBAD///97D5wDjgLfHTL9+/39CwATAAEEAAAYAAAaAA9cEBAC.JwAEBABi8vTy8/TzAAYL/REBBgABDAAPVAAODwQAEAleBQ1RAAO5Ew8YAAIFOQAACQAPQhIKDwQARAvBBQ8EABoHPAAAFggOwxIP.BAD//90N4QMCBAAvAQLcpwQHDAAA9EcEDwAg/QHpRgAKAAwEAAQiAAAEAAbERwGtpwRgAAQEAA/ojxQMNwAPBAAmBmsABhEWAmMA.AwoABQQAAh4ACDAAAoUAAhIAAlAWAQwAAwA2AQwAFQBBAQoEABL/WwUFBAAH6I+wBgQGAwED//7/A/3oFwF5SQPojwIZAQ7c1wDO.CgKEMAESAACgBQAIAAEwBgEYAAbIAQEEAAAYAALcRwKULwQcFwMYAAgk8AcYAAAPAAEIAAAbAAHsSQG0ABIDqHgDYwABMAAA8HgT./QcZADYAAQgAAEgAADAAAXgAAhEAAi0ABDwSDhgAAwQAAB0ADBUAAt8XAFQACHgAAgQAAowBAAoADwQAEwg8AA8EAP///xAFXAQP.BAAUDzAAHQ8EAC0PzAMEA54EDwQATwLLBAAKAA8EAAcPjQALMu/x7/c7AtChDwQADgOdBQ8EAEYFYAAP2wAIC9IADyoACA8EABoF.SAALYAAPBAALBbEAAwQADxMCBA8EAP///2YPjQMdDTAADwsEGg8EACMIYwADwAYBBQAJZQoBDAAAOjsBIQAI7mUClQoDOQAPBAAT.AjwAAgYAABAAYAAA8PHwBUgAAg4ADwQAEgK3AAV4AAUHBQIYAAKWAAAGAAQYAAAEAALlCwAKAAPlCwMtAAcYAAIEAAMYAAfAeAiu.AAIEAAUkAAUEAA4SAA8EAAwNeAAPBAACBXsAD2AAAAHGAAAJAALwAAE+DQAEAAVXAAshAAAIAA8EAP///wYOHgMFXAQGBAAFVwMP.TgMBDzAAAAcEAAQhEAYEAA8wAAsPBAADDXUAAwQAD5kABA9jAAYHMAAPBAAmBZgEDwQAIzX+/v79CwAQAAQEAAL9EQldAA0oBQjk.AAgEAA8YAB0PBAAgC0sACagAAQQAAnQBCRgAB8AACRgABwQABRgABWAABQkADwQAGARmAA8EAP//8gLhCQAKAA8EAAcIZC8hA/7k.FQF1AwHGLgCPFwAZAAIjAADUAwrc1x/8MAAFAQcAAREABTAAAOiDDyQwBAD0FwIOAACURwI1vwIEAAFIAAIEAAQ5AAMEAAYwAAoY.AAQEAAhgAAAEAAIOAA8wABcEBAAFtAY2/f79Cgsg+/1MpxMBDgEGQBcAkwABFAEHegECcgADOgACJwAAtb8AJwCQ+vz6+Pv4AAEA.8UcAmC4BHgACKT0CdAECKxcCABgFBAACGwAj/QDERwANAAALAQJhBTADAAN42ARwBQkEAgQVAAA4AQ8YABEHFAEAhwAACAAAkAAh./QNXMAqoAABIGAVYLwoYAA8EAB0AYAAHhgAFewAPuC8CBRgYAwQACA8AAUsCAlYTAzwAApkACCQADwQA///9Aq0EAAoACwQAAUUD.ADwDBJMFANAFD8RBEQQwAA8EACMPYAAGDwQABw8zAAAFjQAABwAMBAAPMAAeAu4dBAQABZ4EBQQACUMFDwQABzL3+Pf3BQANAAIE.AAXdBAcEOwAEAA8YABkDCQACGAAEBAAP5AAAAQQADxgAHQ8EAAgJeAAPkAAFDxgABwAGAAEEAAMYAA0EAAMYAAIwAAQEAAMVAAEE.AA+0AAIMjAEKPwAPBAD///94D3AFCg8EAAAPMAAdDwQAPQL3KQh9BACLBQ+TAAEMlQQFsgUBBAACAAYA6LMBCQAAEwAKBAAJYwAH.BAAPGAAFDwQAJAKTAAIGAAoEAAKKEgwEAAXGAAfQBQ8EACwPSAAbAn4ADwQA////Xwd1AwLXBAIGAAAQAAsEAA2gBQIqAAIGAAAQ.AA8EABMPMAAdDwQACQeNAAgEAA9jAAYKMAAFngQD6ykEBAAFGAAFBAAMcQoPBAAHAv0FJ/f33N0PBAAFAo0AAgYACAQAAhIAAgYA.AQQAA5AAAhIAAgYACAQAAhIAAgYAD+ULBw8YAAUGtQsPBAAWAzAAAnIAAgYAAQQADxgAFwMSAAIEAAESAAUEAAgbAA+0AAgDBAAC.lAIPBAD//+kKPAMFBAAP6HcRA90KDwQACwgwAAgEAA88ABEIBAAE9C8PBAAMBG8ACzwwA8kADwQABwswAAAHAAIEAAYXAAoEAAJQ.AAceAAL9CwB8LwHHFw9yAAgMGwAENwsA06fwAQAA+/779fj1+PT4/f39Av7jFwZgGAHaBAbgBAE2AAVaBgsYAAMwAAIUAAISAAIG.AALHLwEEFwMqAAIGAAIwAAgJSBADEwAAzRdU/f0A/wPyGASEMAAdAAQTAAIEAAOnAANIAAOBAAKQEgoYAAMEAAVIABT+TxkCEgAC.BgAAOQAPGAAEADQAAwgAABUACBgAB/QvA9wXCB4AAQQAAP8AAAgAAQQADR4ADwQA////Tg9vAx0NMAAMPQUPBABAD2MABg2NAACj.BCX//v0LAwMGATgHADkeAokEDzYAAQ8EABEMLgUPBAATCy0GAAkAD88ABAvnAAYwAAEJAABIAAohAAIEAAAYAAAIAAdgAAQJAA8E.ACwLkAADY2wPBAACBBsADDMADwQAEQQ8AAC6AA8/ACAPBAD//9kOXQMA1AQACAAHBAAH3QQPMAASBwQABNwJBgQADzAACw8EAA8H.jQAIBAAOmQADBAAPMAAEDwQAFAhXAAb6BQdfBA8EABIE/QsCBAAS8gEAJfPyXgUOcAUCBAAFGAACBAALHgAPBAAICf4KD6QBDQ8E.ACAFigAFCQACBAAFDwAFCQACBAAPkAAOCGgBDwQAGwpcAQ8EAP///3IPjQMdDzAAHQ8EAFYEmQAIrQQGAwYm//0YAAQqAAUEAA/O.BAYKKgALJQUFBAALGAALPQUOBAAFbwAFCQACBAAMDwAEVwALYAAABAABEgACGAAFdQYCDwAPOQAMAQQABTMACwQADxgABQMEAA/Y.AAgPGwAIAtsSAgoADwQAAgc8AAsCAQ8EAP//zg8YAwwBBAAI9C9EAP8AAiiNAk4uBtQEBQQACC8AL/7/MAAJAQsAAhYvAAoAADAE.AWgWAYQDAjAAABgAAoctAD0AAA4ADiEMD7QDAwI+ADf/AP4eAAgkSAhsqAAEAAIOAAr0LwgwAAm6AA/odwQD3C9TAAD9+/3icRAE.BAUFGAAA1UgHYAAIBAAJYAAECwBg9/n38PPw5mUU9uh3Ar8KARQBBV4FAGBgBxgAAAkAABcADBgAAO8BEAHMAAA0LwgYAAVIAAIk.MAQYAAAGAAL8AAlIAAKoYADOKwNgAAIlAQf4AQDUAQYwAAACAQAWAAJUSAE1AQ8YABUFrBcCGAAEYwAO6HcC2S8D3BcACwAHBAAA.rgAACAACyAEINgACBAACPAAJBAAOEgAPBAD///9HAvMDAAoAAJwDBf0FAREACgQAAhMFD5kDegqNAAW2BAX6FwBxBAD5QQQPAALD.AA0EAAzzAA8nAAQPBAAFAHgAA2QHCQQADxgABQMEAAK9AAIGAAEEAAAwAAKFBQEGAAHlBQAYAAAEAAVtBQv0NQgYAAX/ABD9Nn4A.CgAPBABHB3gAA3IAAA0ADwQA////YAmzCg4EAAKiAwcEAAkwAAcLAA8EACkMPQUPBAAQDzMAAAKNAA2xAAIEAA8wAAYPBAAHBfcR.DwQAKWD3+ff4+fj9CwEEAAATAAf4BAn1BA8YABEBuAUDzAAHwAAJMAANBAADMAANBAAPGAAFDAQAB5AAAwkABZAAAg8ABb4FDxgA.DQAGAAEEAAMYAA0EAAMYAAIwAAUEAAH2AAAJAAL9CwIKAAcEAAM2AAEEAA8hAAIPBAD///9WAnsDAgYAABAACwQAArAEC9sDDwQA.CA8wAB0PBAAuBUcED/0LDA2TAAzzAAWyBQEEACD4+vcvAAoADwQABAZgAAoEAA8YAAUPBAAFAzAAAnsAAgYACAQAAhIAAgYACAQA.AhIAAgYAAQQAA0gACsYADwQAMgNaAAgEAAFjAA8YAAAP+wFbDwQA//+3DzMDBAn0LwIgLgEEAA/NCwABQgAA/BUCMAABXF4AEwAB.BAAPMAAFDwQABg8eAAUBiQACBAAAfBcAngABDAAH6gkIBAAX/mcAJgEAtGACgwAGBAAEJgAL9C8FMAAHFwABBAAFDwACIAAAaRgD.UwAD/QsBdC4P0hIACg4ADwQACPAA+/j4/fb3+/f7+vb6BQEF8XcAFwAABAAj/f3odwCNLwSgXw8FAQADkgAAigYBCAAAb5AACAAF.GAAf/kgABAVVBQIIAAQYAAB/KQIMAAoYAA94AAYEGAADpgUFGAACDwABIwcACQAPGAAOD0gABAAEAAERAAAEAAfAAAIEAAMtAAAs.SQEYGAFFGAISAAMEAAGkAQAJAEEAAPsAhBgPBAD///+JCtsDDwQADw8wAB0PBAAxBf0LAwMGAFUFAfcjArAEDZMABRsGACQAAtcE.BCQAFPLoUw/uiQUCqkwAtQUACAAABAAFhQUF+AQPBAAjBT8ABQkAAwQAD2AABAV4AA8EAI0EXAEFBAAPugCWDwQA//9tBacEBQQA.A7AECAQAB10DDzAAQg0EAAA2AAT9Cw8EABQAMwAACAANBAAHjQAIBAAPMAAUACIjBLEABvoFD1wELoDy8e/z8fD6+kgAC/0LAAcA.DwQADQVMKQWvBQUJAAIEAAL+BA5IBgsEAAVIAAsEAA4YAA9gAAIACQALGAAEDwAMMAAEDwAMGAAPSAAEABIABRsADaoBCS0ADKoA.AAQABZ8AAz8AD0wCHA8EAP///10PngQHDwQAAw8wAB0PBAAmCjAqAgQABgMGD/QvEwMkAAc0FwX9Cw8EAAsItQUFzgQJ+AQPBAAf.BT8ABQkAAwQAAmAABNynBQQABXgADwQADg4wBgIEAA8YAB0PBAAdA7IABywBDwQAAwUhAAUJAA8EAP//xA+xAxEI9C87Af0BxRYD.sAQIBAAGLwAP9C8TCNynByB2AjAAABUABasVAREAAOgXAAgABgQAAjAAAyQACAQAATAAD/QvNQkwAA/0LwEA6F8EJAAn/f30Lx/8.9C8qMP3/ANPpMfX18/dNABsAApUABx8jAOh3BzMGBQkAA5QvAlkrBzAAIfr/nAAEJwAFGAADSAAACwABBAABaQAA0gwLSAAAFwAA.9wALYAAACQABGwAC5GADGwAHrAsP3C8GDxgAEwMMAA3AAAChAQEzAA/0LwYAHQAACwAIMwAFBAAFbwAASAACngEPJwABDwQA////.UA8YYBUABwAPBAAQDzAAHQ8EADcA6SMEUwQFAAwABAACkwANBAAM8wAPJwAEDwQABQC/BANkBwkEAA8YAAUJBAAHIAEAMAAFMgEP.3C8IDxgABAAGAAgEAAUbAA8EADcDogAIBAABYwAPGAAADwQA////SQitBAmzCg4EAAGcAwgEAAkwAAILAALbCQAKAA8EACQIkAAP.BAAUDzMAAAWNAAAHAAwEAA8wABEPgwQICQMGDwQAGQL0LwD9CwHliQATAAVVBQclCwAEAA8YABkDCQACGAAHnQsPBAACD/wAAAEE.AA4YAAVIAAAJAAV/Iw94AAUPGAAfAAYAAQQACRgACwQABfAABQQAB64GDrQABmYAAQQADyEAAg8EAP///0sHqwMCewMCBgAAEAAL.BAANcAUPBAAMDzAAHQ8EACANXQACpBYP/QsMDTYADPMACsIED/QvRQJjAAIGAAEEAAMwAAISAAIGAAgEAAISAAIGAAgEAAISAAIG.AAEEAANIAA8EAEACWgACBgADIwEBBgADEgAL8wABGwAPBAD///8FCdgPCAQADzMDBAn0LwckAA/NCwMEKgADFhcBBQACBAAPMAAA.AgQACAwACAQAB2wACQQAB1QAAmwAAAoABHgAAgwAAAQABD8AD/QvHQsZAAYwAAUhAAoEAACspwHCjgC7vwIQFwIyAAFQLgA/AAW8.FgIEAAIeAA8EAAUHKgAC9C9v9vb5+PX49C8SDtoBBMwAABwFAR0AAJAAB+0AD/QvBiP+/QwAATYAAwwAAscjAgwACxgACHwFAC0B.AwgAAHgAAAgAALEAAAgACJAAAAgABAkADxgADg8AYAUAHAADCAAAFQAIGAAFRQAL9C8IJAABpAEACQAC9C8CIQACEAAPBAD///oD.NQQPBAA7CIcDDwQAEQ8wAB0PBABKB40ABWUEALjFBAwAAMfvBI4FAPkGAsgEBzYAAgQABVkBACQAB+8ECPcjD/QvFwUEAAWTAAIE.AAUPAAVvAA8EABQFOQACBAAA/QUACAAGWAUCBAAFDwAFCQAPBAA7BXgADwQAAA8bAAgOBAANLAEMWgANIQAPBAD///8IA7AECAQA.BzwDBKwJBgQADzAAAAcEAA8wAB0CBAAPzgQJB40ACAQADzMABg8wAB0FBAABOQAAvrMB/REAMwAH9BEPPwALBR4AA+0ACvoRAgMG.D/QvGALLBABUAAAhhABEAQSTAA8EAAUC/gQOSAYCGAAACgABBAAC2BIACgAKBAAPGAAFBQQABagABQkAAgQABQ8ABQkAAgQABQ8A.AgkADmAABTIBDgQADhsAAkUAAAoAAAwBAwgACAQACOcADj8ADwQA///4DxsDQgduBA8EABINMAAPlgBCClkQCGMAA6MFDwQAAQho.BALxFwIGAAAQAAjJBgdaAA8EAA418vHvAAwPBAAICLUFAAQAAbEAApAABT0FAg8AAeIFDAkADwQACwU5AAIEAAIuBQA8AAAIAAaR.LwUnAA4JAAsEAAUzAAsEAAIYAAU2AAUJAAIEAAJ4AAAKAA4EAAQbAACWAAAIAA8EAAMDUQALLAEPBAAIDyoAFw8EAP//xwj0LwXB.LxAAw0cAqwMJCi8BCwAAwQsAJhgADAAPoNcHAAgABREABgQAAH0WBDAACFoAAgQAAREAJ/3/bUgATAABCAAArwUANgADDAAAQAAB.CAAAf0cGGAAIxC8GjgUCBAACDgAK9C8IBAAJMAAH9C8ApyIEfQQABC8BXQAAYwAByQwC9kgI9C8COQAIywQCcgAGYAAR/icAAAoA.oAD3+Pf9/wD9AQPcrQ/0LxYBDAYAl3cAkAAHMAAABgABBAAP6F8FA0gAAAsAAAQABRgAA0gAAFcAAfcXABQAAQQABbQACgQAAPYA.D2AAAgrELw8YAAUADAABBAAGeAACGAABgQAA59IP6F8LAQwABgQABTAYAmMACx4ACqUGAowBACcAAA4ADwQA////HAIKBALDAwAK.AAAHBQX9BQERAAoEAAUwAAAHAAEEAAGZAw8wABgBBAAPMAAGDwQAGg9dAAQCBAAPYwAADzAAAQgnAAlTBAUMAAI2AACvFwQSAA8E.ABAC9CkACgAKBAAFYwADCQACjQAHbQUABAAFJQUHGAADCQAEGAAABgABBAAPGAASBAQACO0AAgQAAycAAjAAAnIGDwQACA+QAAcD.DwANGAAABgABBAAOGAADEgAFJQIPBAAZBjwADwQA////Iw//CQQPBAAmDlYEAwQAAmgAAe0DDwQAEg8wAAoPZgAGDwQAIgUQCwLB.CwDyKQRTBAgMAAObBA2TAAyNAAWyBQH9CwDcawENADDz9PMHAAUeAAIGAAUlBQ0EAA8YAAUOBAACKgACBgAIXQACEgACBgACEgAD.BgAKBAAF34MJBAAHqAADQgAFqwACGAAPBAAfAz8ADwQABwMhAAJgAAIGAAASBgEVAAEEAAxrAQ0EAA8hAA4PBAD///wB7wQACQAA.ZgMBCAAFdQMAkA8ASwMPUQMGAjsABzAAAy8EDwQAHA9gAAYPBAAHDzMABg+BAAQPMAAUAicAA4MEAewEBQwACwQABTAGDwQAETX4.+PjZxQAEAAJ1AAIGAAgEAAISAAIGAAgEAAISAAIGAAEEAAOWAAISAAIGAA8EAB8C7QAACgANBAADYAANBAADGAACcgACBgABBAAP.GAAvAxIAAgQAARIADwQAFwg8AA/VAAgPBAD//7wPgAQGDzwDBAnQvwh7Fw8EAAUC3AUOBAAHSBgAJRIEDgACXQACoxUGOwAAXQYE.IgAABAAIAMAGXRAANAAACAAPBAABBDAAAEoAAAgADwQABwZ2AAEEAAsPAAsEAAIeAAR5vwN0FgATAADcdxH9oCMApwQS/NEABFhf.AgQABJMABQQAFf0YGAUEAAFaABEDdF7C+Pfz9/f1+/z7/fz9ehkDYwwCwgEQ/SQAAxcBAQYAA9oBAQUACBgAADMAAZYwAmsBABMA.BRgAD/QvBQ9UMAEDYAABnPAACQAA0h4CCAAAtAABCAAEBAAApwAACAAAJgEBNQACQgADBgACxwUPGAA7AhUABBgAAAQAAawCAtIk.AKQBAQkACwQAALAxAtUASAAA/gEeMg8EAP///w8CiQQACgAFBAAHPAMHlAMDBAAPMAAABwQADjAADwQAEQbOBA4EAAeNAAgEAA8z.AAACmAAPMAAXAQQAAHcEAAgABgQABeJfAJ4cAu5NAp4EAgoADwQAAQ9dAAIFMwBT7+/y7/D6CwJFJCL+/KwADwQADwJaAAV0AQVU.AAsEAALQBQIiBQDlBQAIAAAEAAIwAA4YAAsEAAKsIwAkAAEwAAgJAAIEAAsPAAUEAAUYAAKoAAAKAAEEAA8YAB0IBAAPGwACAuEA.AAoAA6oACgQAIv795AADWgAGVwgPBAD///wAGwMACAAPBAAKDyYEBw8EAAMPMAALBLkEBgQADTAAD5YAEg8EABQIXQAHDAAIYwAD.TAUBBQAIJgoAmwQQAvoLAEQEAaYFABYACgQAACgFAcrjAA0ADwQACgBOAAAIAAYEADPw8PI8VAQEAAbUBAC2BAAIAAKCFwIYAAC0.AAEPAAOxAA89BQEFCQAPBAAaBmAAAAgAD/QpGwA2AAAIAAkEAAUVAAKrAAU2AAsYAAAKAA8EAAQOMwAPBAAJARcBDwQACQUhAAUJ.AA8EAP///wcPmQMLDs0LDzAAHQ8EAAkPnAMFDwIEBQcwAAgmBAOTAAEFAA8EACYFgAQIBAAFrwUCHgADKAUFhwAECQAIjQALBABW.+/v78vP9CwIEAAv9CwA/AARLAABEAQGdBQMNAA8EABMC0AUACgAAQAUACAADSAYBtwAAVEIHGAAILQAPBAAUAv8AAAoABAQAAnQB.CxgAAhUAAAoACgQABRgABTAAAPMAAAgAD+4FEw/cCwUB0gAABAAH0gAAIQAACAAPBAD//8kPwAMGBQ8DCgQACPQvCZTvAsYiAo0t.ARAAAA8AAKEuAyEAALhZCTAACCEwEgE+AAARLgEWLwKcAwhgAActAAEoMAIOAAdYXwLJAwcwAAQJAAIEAAQwAABjAArzAAIzAAVW.BAAEAAILAALpAAvjWAGZAADAAA8wAAQDOBYAXTABoS4BaxYhAPyoAAHB7wAvABICMQABBAAc/mAAAgQABiIAAfQvABfZ4AAA+Pn4.+Pn9/v8A9fb15acCXQAAUgAS/ZEFAAQAALi/AAgAEgBViQkYAAFWAAE3BRT9PAAAiCQQAxIABDAAEgPJAABeBQEJAAj9BQAKAADY.GABOAAAMAAXNIwAiAAE8kAAIAQAqAAlgAALUAQFgAAgYAAMwAA4YABQDGAAAHU8ACwABDgAQ/ZDAEP39AQD0AQD1GAAbAABgABAD.XgEADQABLAEDCQACrEcADQAJBAAGKQECBAABawAFBAAF5wAAGBgCSAAE5BgPBAD///9LAoQDB2YDApQFAgYAABAACwQADTAADwQA.DAcwAA9tBQIPBAAIDzAAFQFdAACnBAcwAAL6FwKjFwVZBAMEAAeTAAgEAAzzAAdhBQDRiUH19fX2AwAg9/UTAA0EAAxmAAQEAA8Y.AA8ECQACEgACBgAAEAAKBAADGAABBQAAhQUBCAAPSAACDwQASAFiAAJyAAIGAAOKAAIGAA9EMQIERAEDMAABBAAMawEOBAAHfQEP.BAD///8FD0IDAAIwAw3dBAIqAAIGAAAQAAAeAAIlAA8EADYA2wMHcgAMBAAPGwAECZMACAQADzAAHQcEAAAKawQeDAP9BRH84woH.fQQFBAAIrQQFXQADjQwPgAQUB0IABgQAAmwAAAYAA+hHAwQAABIAAAgADwQAFAL9Cw8EAAsAegEACAAH/QUACQAAeAAPGwAAAQQA.DxgAJAEFAA8EAAsFUAEFTQEFBAADRQAPBAAHCSEAAYIBDwQA////HggsBAcMAA6KAw8EAAAPMAAKAxAFCAQABzAADwQAPw9dAAQO.mQADBAAFMAABJEILrgADAwYEXAQA9xcCIAAFNgAPBAAQD/0LBgTvBAVjAABgAAKoAAEPAA8YAAABEwAVAJ25Aw8AAQsAAAkABxgA.CgQACRgABwsAAgQAAGAAAYMTBQQACTAADwQAAgUhAAAJAAd4AAkJAAcYAAASAAMIAAALAA8YAAQADgAF6gAAaggDCAAIBAAPywEG.AQQAA3IAD6EBGQ8EAP//ywj0Fw8EAAIJ8gQR/q7tBZgEAax3ApMDBiUADzAADQKfAwMlAAstAAFLAAAMAAIEAAApAAAIAA8rCwMC.OwAPGwACC0gAAgQAATAADxgAAAIEAAiKAAIEAAIRAAFgAALDAAILAQL6EQLxHQDyRgJ/BQAmAADDAA9gAAIINgwABAAEEBcgAAC+.1xH16zVa/fr3/fvNvxMCHwUAKEcCo0cCxBcA3gAAIAAAGQUBnwAABAAV/5QLAYW/ARgAAY0ABhgAAEgABTQFAQYAARgAB4hHAgYA.AY0wAOQwBRgABXgAADAAGQPcdwBIAAeoAAAxAAIYAAYwAAAYAALAAA8YAAkBKwIAGAAB8QUAVwABTAABGAAEMwAAEQADBAAFIQAB.WAIARQABDQAAGBgArgAADAAFBAAAPAAAoQAADAADbAABCwAPBAD///8RCbYEAQsAAgoFAAoABAQAAWUEAAkAAAQADzAAEA8EAB0J.YAAA+wQBDwABXQAJyQMHDAALMwAABAAOMAAHBAAPMAALAsMACCQAAvcLAAoADpgEDQQACDkAAAQAAloAAQQAAkUGAuhZSPLx8Pr9.BQtaAAIlBQAKAAYYAAJaAAWkAQsYAAAKAAEEAAUYAAsEAA8YABIBAgECewAJGAAPkAABAAQADxgAKAUEAAXAAAYJAAQzAAUSAAgE.AAKhAQAKAAIEAApRAAhvAA8/AAIPBAD///8bD+hNCwSJBAAEAAILAA8wACAABwAGBAAJMAAPBAAsChcEBQQAD2MAAAeNAAJcBAXB.CwL9CwAZAAHIBAhcBAPDAA8EABlv+vz69vHz6FkLA2MAAY0AAOEkAg8AAX4AADcBAZYAAF8BChgAAAkACtgAAxgABEgAAAYAAQQA.DxgADAQEAAUPAAAJAATUAQ8EABEAMAAFWgAPAE4HBRIAAgYAABUABAQADhIACQQAAaEBAAkAAWQCAgkAAAQAAloADwQA////KwLy.BAAKAABpBAMIAA8EACMCZAUCBgAAEAAA8wMNXQAPsQMQA0IADjAABwwAAyQACAQAAjAADwQAJQv9BQDZayL8/foRAB8AAgQAACAA.CpMAAQQADI0AB+8KUfr8+vv8YREAAAwS8AkAC/0LAgYAABAACgQADxgABQ4EAAIqAAIGAAN7AAEGAAISAAIGAA8YABEJBAAFxgAP.0AUHAw8ADwQAFg4wAAs7AQAhAAJdAACcMAMmAQDZiQEIAACBAAgwAAQqAAA2AAAIAAAEAAtRAA8EAP//xQKwCgAKAAsEAAQSAwCe.Awf0FwncdweYFgLyBAAKAAugBQEMAAKULQM2AAIEAA8wAAoPBAABAh8AAgQAAIQAAAgAAIsAAwgAAFJBCWAABwwAAA8AAwgACOED.AD4ABDMACcAABzAAC5AABcMABhcAArQYBFcAMAMC+5cXoAAA+vz9BAEG+vuyETD9AP0MMAWGRgC3EQAIAAAEAAISAAEEAAzoRwQ3.BSH4ANNfwwQA+/379fPw+vv7+HoBA4YAAIg1DYhHAN4ACt0BBeQABQUBAgkABdUAD9x3CA8YAAIITwUABAAEGAACVwAAOQACCQAD.dwAB9AUBEQAABAAHSAAAGAAACAABIQAHBAIDDwAFLQYEGAAABAABEQAABAABaB8ACQACBAAFoHcCdzEACgAGBAAAvQAAtDABaAEC.XwEEhAAABAAFPAACJAACIQACEAAPBAD///oFLwQPBAAJCFcDDwQAEQ8wAC4PlgASDwQAFA1dAAIEAA9jAAAELwQCBAAAiAUH3AUC./QUCtRcAmzQCxQQF4AQPZgAEDwQABbDy8fLy8fL6+fr4+VEAABMABwQAAsg6AuAEAgQABdoHAj0FCyoMCAkADwQAJApgAAAKAAEE.AAUPAAUJAA4EAA9KAQAPSAAZBRIADEgAB9A7DgQABTYAAAQAD9wFDg8hAA4PBAD//+UMcgMBBAAOaQkIBAAE9goGBAAPMAAtD5kD.HQ8wAAQPzAACDwQAIAJZBAIGABH69BEX+vEdAgQAAh4AAMwAIP7+xSINkwAMjQAKgAQg8vH0IwAAJAAABgG/CgQEAAVaAA/9BQgA.CgAPBAANAjMAAkAFDksADBgAARUACNChBWAGDwQABQYrAAoEAAsYAA9IAAUFGAAFMAAMMgEHBAAOGwAFNgAABAADSgAKBAAHPAYA.PwAHYw4PBAD///8ODJ0FCp0LD80FDw8wACANBAAAsQMACAAEBAAN/wMDBAAIaQAHJAAPYwAGDzAACwEFAAi9AAIEAAj9BQL9CwAK.AA8EAAIEPAAIXQADBAAEGwAFYAACAAwP/QUFBQQACKY1BVcADz0FAAUJAAHKBQLlBQAQAADqAAAIAAJIAA8YAAUABAAEXQAAFQAP.YAAIAQkABQ8AABIAATkAAkQBBRgABQkAAgQABQ8ABQkACwQABdsABQkABY0SBhIADwQAAQNRAAXGAA8EAAUFIQAFCQAPBAD//7gI.1QMJBAAP6wIEAvQXAroDIQP9kC0BYwMCwwMAIgACBAACDgAP6EcIDzAAKgcYSAokBgUwAAbUNAIEAAQwAAAzAA/zAAEJYAACCwAC.AgEP6EcREAD3FwB0BHMBAAP+A/r96AVT/v0DAf7+BAAGAAEyAAASHgLgRgEtGALJAAtjAABgAAMIAAEaAQKKABAA30cw8vby8TUR.9cTXAhYAAC4ABuhHAChHAngSCkBHAOhHAngAAcAABRgAAI0SEAISAABVNQD+LgboRwFTKgMMABsDGAABMgAHkKgBxy8BIQACBAAA.DwAACAAAMAAFDAALBAAG5HgBVwAFCQAPAEgGIwL+7gEBOwECVwAAwAAN6EcCvgsPuBcCADYAAi0ABBACAwwABAQAACEAAAgAAAQA.A94ACkIADwQA///yAxgDBA0FAgwADwQAJwGuAwCNAwEIAADtAwFXAA9dAAYNMAAPBAAMDzAACg9mAAYBBAAOmgUPBAADAicAMf/9.+pUEAIEeRP36Af0sBwC9BAAYAAZsAAeTAAhjAAYhAAIEAAe/BCf19t87DwQABAi8BAgEAA8YAA8ECQACEgACBgAAEAAEJAAIBgAD.bQUCBgABBAADGAAOFwcNBAAFKgAFCQAPBAAeATgAAj8AAgYAC5AABlABBz4BAgQAAzAAAQQADGsBAQQADyEADg8EAP//8gUYAwUJ.AAwEAAIEBAd7AwIqAAIGAAAQAA8EAC8HXQACBAAAugMNFQAGBAAEGwAGHQQBBAAPkwAGBDAACwQADzAABg8EAAQAlgAACAAABAAC.PAAAIgUHIAEIkAACIQAAxwoCRgUNvwQi9ff8CwAEAAAQAAIEAAdCAAYEAALIBAAGAACkDQAMAAIEAAASAAAIAA8EACAIzAAFbQUA.KAUEGAAA2wAACAAGBAAJMwAEPxgIMwACBAAPGAAABQkAAQQAAxgAAQUADwQAFAVNAQAEAApHAQ8EAP///0EO+QMIuQQJigMBBAAP.MAAwDwQAMQ5pAAMEAAeNAAgEAA8wAAYCvwQHHgACAxICtgQCBgAAFgAPBAAoAt9HBQAGABMAAgQAAnsAAQQAAmkAAN8XAooAAQ8A.AFABAQkABhgAARMAD+hHFAgMAA8EAB0LPAAP5QUAAQQADxgAAAkJAAmQAA94BgIABAAECwAFTgAGBAAEzgEIMAAPywECBSEAAAkA.BDYADwQA///CDyQDAAIEAA/0AgQJ6EcNuO8ACgALBAAIuEcPIwAEAwQAAR4AAL4VAyoRAJBFDOs7CAQAAjAAFP4VFgCFAAA6AAMw.AAIGAAgEAAEwABX+jQALBAAOVwYBEQADTgAKBAAAFQALMAACDgAARBYB3F8BtwBg/v/+/fv9KqgQ/JoWAa4AAE4ABuwWBKQWBRsA.Ag0AABgYCGAAB+MA8QH4+PgDAgP9/P339vf9+f0FgAEw/fz7hC8L6EcASgcy/QD/FQAA+gsAGAAAFQABTT0DGABJAAAAAwS/AlhH.AI0AQwMA/fvZLwEcRwCMAQAYAADBNgYYAAFYRwNLABP9RQAFpAcCGAAD6EcAEQAEBAABJwAAkAAAvwAADAADCAELGAAV/cAAAKgA.ABgABqgACHgAE/oVAAsYAAEEAACtAQIYAAAOAAEEAAfQLwACYAIIAAcEAAA/AAVBAA8wMAEPBAD///8IDioDCdcECLIJAQQADDAA.D+hBCwj9CwIIAAX2Aw8EAA4PMAAKC2YAAAQADzAACg8EAAMBLQAC8AACwQUF6DsAGQAE4gUGbAACYwABBAACGwAACgAB+QACCQAD.BAAHJwACwadB7/Hv7+tBEf1FJBT9/TsAtgQCCgsCPQUKBAAPGAAFAwQAAb0AAvAAAo0AAYABA+UFAtwjDxgABgFtBQBgAAEPAAWk.AQASAAAIAAcEAAAqAAXQBQcEAAASAA8YAAEPBAAKAjAAAAYAAXgAAIoABAkABQQABm4BDwQADQLMAABFAAFXAAINAA8/ABcPBAD/.//IF+QMPBAACDksDCTAABwsADwQABQkwAA8EAAQOZgAABAACOAAE4QMLBAAPMwAADzAAIwQEAAL9BQAKAAT9BQDrQQQ9BQIYAAME.AAFjAAJYBQAKAA4hAAr3F2L6+/rz9PP9BWvw8fAFAAL9BQAKAAUEAAESAAkYAAVOAA5wQQQEAAqNAAAGAAIZBQ8YAAYBPwAFRQAF.pAEFEgAACQAC1AcBEgAADwAADQABeAACkAYPGAAXBZUBAgYACgQAApYABioAAKgAAwkACQQAC9AvAAgADwQA////MwX5Aw8EAAIO.aQMJMAACCwAEwAMFmQMCBgACEwAPMAALAgQACDAADwQAFA8zAAYNXQACBAAPMAAMAXRACasABwQACTwABCMACFgFDwQACzX09fS7.rRHw6EcF/QUFBAAF+wQCPQUBBgAB0BEACQAGpQAABgABBAADMAAOGAAIqwAHBAAFwwAC/QUPBAAYAmkABAQAA3gAAGoABAkAAQQA.DxgADAJ1AAEGAAISAAIGAAAQAAQEAAUSAAUJAAAwAgWSAQduAQXMAAEhAAMJAAg2AAghAA8EAP//1QFaAw4EAAj0Fw/QjxQG1wQB.JAAOyhEGBAACwC0Q/uEtAA8ADzAAHQVYKQowAAYNAAL7AwTCAAUKBAsEAAYXAAUlCwIEAAYZAADcBQEIAAAEAAMXAAIHAARxFgW4.1wL6EQLlNQAbABcB9BcCwwAKcAUCBAAJJAABCAEEBAAA6EfC+/z27/Ly+fr79fT1egEA9BcACAAAfgADHBcRAvsoAB4AAk8RAMRf.AkoBApkAACkBABgAACcAAhgAADYABIoAAKhCB9BHBeUFDxgABgHmAQFpAAAPAAxjAAUJAAGQAAMYAAERAAP8AAgYAAAQAAQEAAEY.AAIVAAPYAAIvAQI2AAIwAAAdAAEVAAGTAAwYAAEwAAWQAAIEAAAeAAAIAATERwDhMAAnAAEUAAEEAAcYGA8AYAIPBAD///IGNQQH.BAALaQMPBAAOBjAAAQgAAM0FAAgABgQAC2YADzAADg8EAAYBMAAPxgMFC2YAAAQAAjAADwQAFAItAARMEQIGAACfAAH9BQL6EQAh.AAKYBAIKAATDAA6TAA+NAAAHBAAU7+hBHfrlRw9dAAAPBAAQBW8ABgkAAUgAAhwRBUwRDxgACQGGAQIeAAB6AA/rOwcCBAALDwAF.BAAFGAACCQAAnCQADgAPBAAGAicAAGAABLoADgQABdUADwQACQfMAABOABH91a4DDgABBAAKIQAPBAD///8IBp0FBAQADqAFCJAD.DjAADwQACwYwAAIIAAckHgUEAAhgAADMAwIPAAUwAAAHAAEEAAfSAwgzAANjAAEFAA8wABgHBAAClQQFvAQF/QUA+CMBGwAADQAA.OgABCAAFVwAECQAIXQAABAADRwAABABQ/f798vP9Bafv8fLw8fL9+/3760ECeAAACgACXQAFUQAEGAACWgAFsQAJMAAHBAAIGAAC.5QUC5QsCGAAAAAwAAgEAEgADGAAB4wECXQAAegAF+QABMAAOCQACBgAAEAAASAAADAACkwAFGAAFCQACBAAJDwAHkg0FGAAFewAG.CQANGwAIBAAFOQAABAAHUQAPBAACCUIADyoACg8EAP//6TD+//6n0AHGAwAQAA8EAAEBLCIJyhEC9gMACgAANgQBCAAH0AUPMAAM.DwQABAgwAAb/AwI4AAi9AwcMAAMkAAEEAANjAAEFAAkXBAcMAA8wAAsCXAQC/QUy/fv9/QUA9B0EwEIPBAAbB54EI/3+8ekC/QUA.HCkP/QUBAwkAAjYABJAMBSEAA7EABA8ABRgAAAkAB9gAAA8AEP3cIwMNAAcnAAAbAAFdAAj9BQAKAAoEAAUwAAsJAAIGAAMPAAFC.AAKTAAAPAAAOAAEYAAEJAANEAQgwAARlAQMGAAEEAAMYAAcEAA4SAAkEAAexAAkqAARUAAgVAAjsAQ8EAP//xQnAAwQDAwsEAA/0.Fw4M/QUCCwACNQABBgACixUGOQAFOgUCBAACCwABKgACTAUCMAAX+zAABqQ0AHAFASUGAjAABIQAAFtBCCQACAwABwQACN4DAFYE.BCcACZAABWgEBXcEBAQABcMABjAAAoQYAScAAM9BAbYEAFoABazvAWAXAywBACYAADAAAucAAGYACkhIBWAADgQA8AIDAgP19PXw.8/X4+PoA/QD49wkYABkAAaUAApQXAA8AAHgwAAgAAIQABFoAAsYABbQAAg8AACEAAQkACHUABXioMAD/APIvAV0ABpUHATAAEP6o.FwEYAAQpAQIMAAKyBQAQAAoEAAIeAAAKACAAAORgApYAADwYAzAABSEAAgkABUgAAg8ABXgAAzUBAQQACKgACMAAAGgBBicAAyAH.AqsGBkgAAgUAAjYABBsAAgQAAyEABdxfAvcXCiQADwQA///sCWwDDwQAOA9jAwsEuQQGBAAPMAALDgQADzAAHQ8EAAEP/AAAAZgA.AjUEAgYAABAAAWgECA8AAgQABhIAATYAAFkECkALBWAAA6kFB/0LANB3uPLy8vPy9/b3+Pb4/QUCBAAPlBcFAAkAAXgAD1UFBgcE.AAYzAASKAAgkAA8MABECBAAFEgAFCQAFBAACYwAF6gAPBAAIBTwABQkABQQABRIADkgAAmAAAJYADRsADwQADgVXAAYEAAdQAQ8E.AP///wsDsAQIBAAHOQMCzQsACgAEBAAMMAAHLQAAugMLMAALLQAB8wkDCQAHBAAOCwQGBAAKYAAFBAAPMwAGDzAABA8EAAMBLQAC.OwQCZAUL6BcA/REW/FAcACQAD8SnAQWNAAMdAQ/9BQEACgANBAAIbAAFBAAGBwUPHgABCAQABioABQkAAYoAALE8BDwAAGMAAwsA.AEt+BasACxgAAAcABw8GBQkABQQADhIAAG8ABBUAAh4AACABAA4ADAQABRgAAicAADkABIcABgQACsMAAAoAAGoOAggABpkACyEA.DgQAAyoAB4ABDwQA////CwOwBAgEAAc5AwYhBAQEAA8wAAAHBAAMMAAPLQAKBSIFDM8DCw8ABQQABDAACwIED5MABg8wAAsKowUC.BAADOwQEBwUD/QUCEwAFJQUFNgAECQAFXQADWgAI5AYQ//0FAAkAeQAA8/Pz+Pj9CwJmAAAKAACiAAAIAAXsEAi0AAN4AASWAAAb.AAQJAAIEAAYGBgQzAAUEAAUzAAD5AARIAAAqAA8YAAEFLQAPCQAJAWMAAuoABhUABAkAAgQADxgADwFFAAgJAABoWwEIAAYSAACq.AQIIAAY5AAkzAAgEAAQCAQMEAAdHAQ8EAP//vwXtAwAEAA/oAgQL9BcFNgMmA/2UHQPoRwIkFQAGBAAOAABJXwTsHADEHQisXwDX.BAEzAAIEAAILAA/cXwcKBAAP3F8BAZgWBjAABQkAA20AAC0AAA8ACmQXAmkAACMAAYMEAxMAAgsAAvUADzAAEQHcXwJWBAWLNQAc.IyL/+t9rAPcFAikXAaUAA7xeAgQACsSnAl0ABmAAAlcGAooAoAAA9fX1/f718vIDAADcaw/9BQEBeBgACQAABAAH9F8A3F8EmgUL.MAAIgQAABAABMwAASAACTKcBJAAATBcAlS8APzAAwAAFTKcBLQAACQARAMSnAZFfAFcAAuQYATwAIwYBBQ1GAwEA+rhHCfwwBRUA.AHgAD6gABAFgAAAMAADRAQIMPAEYAAU1AQAEAAF4AAICEwO4FwKiAAIGAAEwAAKuAABUAAeSPQUEAANyAAIFAAJaAAQ8AA8EAP//.9QVvAwUJAAYEAAIqAwJTAwIMAAEEAAIqAAIGAAAQAAC7BQIlAAEEAAILAA8wACgCBAAJMAALBAAELQAL7AQPMwAGDzAAFwr0HQAS.AAQJAAL9BQISAAAeAAg8AATDAAtgAAwEAASHAAL9BQH9EQP9BSDz8wYAAhwAAm8AAGMABAkAAAQAB1oABSEAAgQABXUACxgABUIA.AgYAAhMADwwAAAEFAAVGBQ8EAAgCMAACBgACPwAFkAYFFQACGAACCgAIFQAAGAALqAABBQACeAACEgACBgAAEAAHBAAF3gAAKAIE.bwACBAAPMAACCAQACCEAD+wBAA8EAP//8Q8VAwkIbAMHDAAOMwAOdQkIzQUPMAAdAgQACLoDDwQAFA5pAAMEAA1dAAIEAA8wAAAB.oAsCewACBgAFrQQCBgAAiiQC9ykEPAAAzAACzgANZgAFYAAAJAAA9wAADAAIBAAj9fX0BQ/9BQgDfxECBAUAUQADcAsDGAAH0gYC.GAAACgAEBAACGwAIGAAPDAAFAoUFAgQABhgACQkAAfAMBwQABicAACAADwwAAAUJAAIEAAKNAAghAAAEAAgLAAgYAAEEAAAzAAPm.AAqqBw1rAQA/AAghAAEEAAlpAA8EAP///xwAsAQB2hAOBAAJhwMPBAAFB58DDzAAHQIEAA+6AwwNMAAPBAAVBzkACJkAAPAAAqAF.BCEAAoEABaD7APAQATQvCNx3ADIABckGBDkABQQABWAADl0AAv0LANRfWPb19PT1/QUFBAACeAAACgAAPAABDAABUQACGAAP/QUI.BhIAAQkABRgAAMwAAUIAABsAC9wdA00AAKUABT8AABgAAgQCBEIABUsACwQADxgABQIEAABIAA+oAAEAGAAPeAABBQkACAQABU0B.AAQABEcBBUsAAFcACCEADQQAACoABDYADwQA///CCTMDD+gCBA/0FwgFDAAAHAAFnQsCLwABCwAALQQAMgAADAAgA/wICgIwAAMq.AAUEAAIOAAEcTQAJAAEEAAj0Fw8wAAYFjQQAiwABCAABfgAFOQADBAAEMAACSQUJ9gABwwAPYAAFAGMACi0AAgQADDAABPcRCPQX.BYwuAO4dAC8AA88AAzwAAQUAAmkACJAACSQAAAoABI0AAQQAIO/02VOk9/v39Pb0+/f1BSMZF/tMFwAfBQAIAAEEAAPxXwAGAAYY.AAcMGACfBgd+AAK6AAIGAABkFwEUAACAGQVgABL93BcACwAAmQAE+QBT/f79BgLzBiUDAZAAAPIBRAP++gO0wBL6PGABfgAzA//7.jwEW/TgTAMA2BEQBAwQAASQAAAoBD3gABCD9AmYCABgABHMaAhsAA/QXAhUAARgAAwQACMRHIwL7VAAHBAAAPwAFFQAHkDAPBAD/.//UCoQQACgABOgUCCQAAlQMIJwMCCwAPuDsKDAQACKIDAE8cEP23AwINAAsEAAVdAAAHAAkEAA9gAAMKMAAIbQUCmQADCgAFBAAK.MAALBAAPYwACADIEATQFAA0ABwkAAfQRBO41CDkAB2MACJAADF0ACvoLMPf49/cXAc2DAFEABGYAAMQFBCcACHsACOgFDwQAFAI/.AAIGAAAQAATMAAgGAAMxBQEGAAISAAgGAAIJAAV4AAD8HgT9BQAQAAEeAAQJAAgGAAEHAAcJAAIEAAUPAAAJAAToHQgwAAkEAApI.BgMEAASKAAIEAAAeAAJ9AQv7AQE8AAtaAAkhAA8EAP//9AgSAwgMAAkkCQILAAd4AwIqAAIGAAAQAAsEAAIwAAcEAATQCQ8EAAcH.XQACBAAAtwMNFQAGBAAEGwAIbQUA7QMPkwAFDzAAGQB7AAo4BAAqAAEPAAbrOwQ5AAApAQLwAAFjAAhgAAVdAAAkAABRBwz9BQCs.6RP1/QVB8/HzBVwHCHgACAwABfgoAH4ADxgAEQ3tAAshAAgMAAigAQkYAA8zAAECBgACDwAJGAYABgAADAAFBAAFKgACBAAFkAAD.GAABBQAPewAAAQUAAhgAAxIABRsABG8AAgQAAxUAAQQAA24BAQUAAjwABlEAAQQAAyEADwQA////EwOwBAgEAAd4Aw5IAw8wAAwF.jgMEBAAMMAAHLQACBAAItwMPBAAADTAAAgQADpkAAwQADzAAHQQ4BAJhEQCOCwEPAAX9BQUEAAbJAA1jAAVdAAMkAA36CwDiLyX4.+P0FABYACHgAEgFwEQEMAAATAAAYAAEdQw8YAAEBBAACGAAACgABBAAMbQUHBAAAEgAEFAAASAABSgAABAAHfBc1/v7+5REAEAAN.SAAIDwACDAABBQAADwAAmwAKPAAAhwAEWgAJGAAICwAPGAAEBgQABUEBAQkACUgADwQAAQghAAWPAQ8EAP//wgW0AwAEAAEbAw4E.AA/0Fx4CBAABCwAAvgsAMgAADAAIiL8BEAAPMAANH/0wABMACAABBAACKQABrQAINgAABAABLQAARgUCHgAI9gABwwAJWgAEXQAP.MAAYBOMEAGRHAQkAEAJkvwAJAAP3EQEvAAKWAAY8AATQdwhgAA8kAAUCBABA+PjvAbXX0PLv8vL7+fv6/PoCBALQrSP/A08LFAHg.vgBKBwEQdwIYAEAAAwD8rkcCMGsn/gIJQiD8+skBAMMAA/gQAvYABdB3ADA2EP5sAQD1ASAAA0wXAKQAASQABGQRAMMAATYAAroA.APQXAQ8AADMAD/QXBxD94wEA9xEAGJAAgQAA/gEGwAAAMwADtAYAoBcCGAACDgAIuHcLwAAFGAACBQABUAED0gACBAACiAIBdAEA.zAAAJQAAFwADJAABPwAFhEgArBQiAf6xAA8EAP//9QKhBAAKAADJAwYMAAL5AwAKAAK2BACABA/0FwkPMAAzAAcABgQACDAABgQA.Ci0AAtgDAAoAAQQADzMAAA8wAB0AegQAFQAF7gsA6QQK4iMPOQAAAmYACmAADyQAAASHAAD6C4L69wEAAO/x8t9fAFcGIAAA/QUE.gQAAZgAC4AUBCgABBQAGGAAAzQUDDgAADwABCAAACQAGPQUACAAAEgABDwAA3gcO+AQFaQACBAALDwAFpAEFGAAA3BEE/QUAEAAB.WgAECQAGBgABCQAECgACBAABGQAFOQAACQACrmYAKwAA6AUAEgABNgAPwAACAAoADnQBBAQACHQBA1QACgQACCEABQUBAAgHAAgA.DwQA///qCFEDCAwABfkDAAQAAgsABDYDAJMDASoADzAARwIEAAgwAAwEAAQtAAjYAwtjAAkEAA8wABcEyJoIdwQI3ykCpgUCJAAA.EAACBAAPwwAEAgQAA+0AC/cRc/r3+Pv4+PT9BVHw8fMCAPoLAB0AAwQABoQAAgkAAAYAAB4FAhgAAQUAABcAAmQRAM8ABBMAAggA.Gv3MAAL4BAL1BAMSAAEGAAOWAAIGAAEEAAIeAAAKAAoEAAIYAAIGAAI/AAJUAAIMAA+QBgUAwAYEDwACBAADHgABBQACrwUCEgAC.BgABNgABFQAEwAAADQAPrQECACoABmhJACEABSMAAjwMAiEAABAAAAQAACEAAAgAAAQAAggBDwQA////BQOwBAgEAActAwhFAwIE.AA8wADsCBAAItwMMBAANLQACBAAOaQADBAAPMAAXBBEAAn4AIP7+xxAC/QUg+/zADAL9BQAiAAQEAADMAALOAAFmAAhgBgxgAAEh.AAIEAAP9BSX7+P0FABARCtB3BYQAAesXAMkEABYAAAgAAxgAAlQRAP0FAAgABukEAggAAhxBAOcAAhAAAQQACPUEBTAAAAQADxgA.AQDbAAAIAAMEAAUYAAIEAAgPAAIMAAEFAAAPAACTAAH4DQIYAAgWBgBmFAUPAAASAAMIAAALAAQYAAIIAAXAAAIEAANLAAEEAAWZ.AAgVAAluAQQLAA8hAAUICAEPBAD//6QIaAQJBAAP2QIEC/QXBQwDD/QXTg8wABEHHgADDgoIEgAIBAACQwsBywALAgEPxBcAAg4A.D/QXGgF/AAjoLxT66C8AxgAB01MCzAAGPAAH0BcIYwAMYAABsEYCBADzBPj4+AEAAfv0+PXx7/j5+/36+gKnBA0cFwAaBwH0FwAY.AACqAQz0FwSIRwg0FxH9GQYCqAAF9BcAbQECCAEASwANxI8AOQACMAADDwAFvQACkwAP6C8ID/QXAgE4GQMYAASoMAAvAAPYAABH.AAFpAAGdFwE3AAEPAAAKAAPAAAMPGAEqAALMAAWTAAAEAAJQAQMRAAOwAQAEAAGWAABjAAGsAgabAQVIeACCAgIIAA8EAP//5wJO.AwAKAAEEAAgPAAljAwILAA/EFyAPMAAdAAcABgQACDAAAgQAAxIAAjAAAQQACGoFAmkAAwoABQQAAi0AAg4ED/0FAQAHAAUEAAR0.NABxBAAQAAAEAAgMAAD1BCD8+o86AooABQQAAmYAAQQACGMAA7EABQQABycAAkIMMvLx76/RR/36+v1vBgAHAAIJAAIEBQGEAAAP.AAANAAAYAANSBQQPAAAHAAEJAACSBQAJAAIRAAASAAIhAAAwAAEFAQLyCgJLAADEFwAFAQASAAsYAAKPAQWnAQIYAAAKAAIeAAIK.AAcMAAIIAAIGAANCAAELAAISAAQGAAEHAAIJAA/0FwQCeAAADAAEOwECGwAIEgALBAAKcQEABgAIBAAAPwADxQAPQgAGDwQA///y.CBsDBfYDAAQAAgsABJYDAWMDACoADzAARwIEAAgwAAIEAAMSAAcwAAj5AwtjAAkEAAEtAAAhAA8wAAsBVAwA6R0BcQQABCkCkgQE.BgAD/QUPOQACD5MAAQ8nAAABJAACSAACrNcCEAA18vHwYwAFBAAGEgACCQAABgAA3gUCGAABBQAAFwAMZBEACQAACAAP9BcUDxgA.BQEVAAJsAQYSAAAJAAThAAApAQE2AAIzAABgBgMaAAAPAAEIAAAJAAgYAAIEAABFAAA0AAAMAAD9BQAhAAAiAAMYAAEEAAK6AAAm.AAQVAAUSAAkEAArEjxEDCAEBugADCQAPVAACDwQA////DgmdBQIEAATnAw9FAwIPMAA7AgQACLcDAgQACUgADTAAD2kAAgMEAA8t.AAEPMAAAAf0FABgAAXsAC/0FASgLEgP9BQAtAAQEAADMAAApAAQ8AAQcBQAMAARgAAAkAAD3AAMkAAIEAAWs1wEADADEjwAWAAEE.AGL++/sAAQV7AACHAAJIAAEPAABXAAEJAAKQGABWAAJ+AAGlAAQJAAEGAA0YAAAtAAeBAA8YAA4DtwAHBAAFGwAIJwAFDAABBQAA.EgAAOgEBiAUPGAACAhUAABAAABwAAwgAAAsABxgABZsBBS0ABQkACQQADW4BCMwGABUABzYAAiEAAAoADwQA//+yCGUKCQQABPoC.CwQAD/QXrQMSAAEwAAM2AAoCAQxkFwRdAABzBQH7AAsyAQ8wAAABgxAIjF4A9AUE0F8AxQoBUEYCigAGPAAP9BcgEPzEX9L29fby.8fL79fL3+vr4pwQDTEdDAAABBRwXABoHD/QXTggYAAusRwEJAAEYABD++QYC9xcP9BcdCBgAA9gAAFMAAQ4HAsMAAB8AAQ8AACkA.BLoAAjMAAwsAAB4ACVABAh4AAgoAEABHBwCcAADERwERAAIEAAGwAQAJAADapwfEjwIGAA8EAP//6AVgAwIEAAgPAAljAwILAA/0.F30BMAAIagUGIQAIBAAHLQAAIQAPMAALCigRABIABAwAAv0FAa8RBvEdAiEAAAQAAmYAAQQACJMADycACAJCDAKpywH6KS/6+PQX.fwEOAAIJAAQKAA8MAAQCCAACBgAPGAARAAQAAgsAAWAGAhgAAAYAAXgAACoABDsBABUAAAgAAAQADFABC1EAAQQAAs8ABgQAChgS.AJQCCyEADwQA///0CFoDD50FCwIqAAIGAAAQAAA7BAIlAAEEAAILAA8wACgCBAAIMAACBAADEgAEnREAVAAHagUADwACIQAOBAAP.MAAUBFoAAlMEAv0LANoWAQ8AABkAAv0FDzkAAgTDAAhjAA8nAAABJAACBAAA9BcB+gsC4k0F/QUFBAAChwACCgAEBgAA3gUCGAAB.BQAAFwAApwABaAcCGAADKQAA7QADqAACGAACFgUM5QUAzAAAEgAOGAABCQAAFQABCQAAEgADGAAE4QAAGgEBNgACIQAASAYDGgAA.DwABCAAACQAPGAAFAi8BA+YNARgABR4AABIAAboAAAkADxUAAQYEAASNAAAeAA3MBgAEAAghAAI/AAUbAAUJAA8EAP///QmdBQIE.AAcqAw6EAw8wADsCBAAICwQCBAAGSAANLQACBAAGIQALBAAPMAAUAv0FBPFxC/0FAigLAv0FAC0ABAQAAMwAACkAATwAAHMFBiEA.BWAAAyQACocAYvT49Pv8+9xHAgYAABYABwQAAngAAIcAAkgAAQ8AApMAAEQBD/QXTwQIAAFBSAWdEQQEAAgPAAIMAAEFAAAPAACT.AAeQBgEFAAAPAAsYAAEKAAAFAAIEAAYVAAebAQ8VAAIGBAAAmgAACAAAHgABKgAC/QUGBAAIIQALPwALKgAPBAD//50CpAQACgAL.BAAP1gIECPQXCAQAD/QXiQIGAAAQAAIEAAEtAABnBQHLAAsCAQxkFwRdAA8wABcCIQAx/fz9rQUDjvUCoxEAHwAhAABmuQPMAAY8.AA/0FwEPJAAIBfQXMPPy89AvcPr7+vn3/fsSAATcFwAnAAMcFwAaBw/0FyoGSAAA0BEAIwAAMwAAMAAASAAAJwAIrBcBxBcDLwEB.GAACFQAvAALoLyoPGAAFAJkAAsMAAFQAEPoPAABfAAOwAQMzAAISAABvAA2wAQGNAAEKAAA4DQBUAA70FxMA30cwAAD7wAACHgAC.BgAPBAD///cCKQQACgAIswQCtgQAgAQDtAkAaAMPxBcUDzAAHQAHAAYEAAgwAAYEAAotAATVAwMEAA8zAAAPMAAcAKN9BJe5ACEA.Af0FBg8ABGsEDDkAAmYAAQQABWMADyQAAASHAAUEACDv7uUvge/u7/v5+Pr5/QUC7wQBCgAACQABNAUBJgUJGAAA5gQDDgAADwAB.CAAACQAAkgUAIQABEAAACQAAJQAAOQAHSAABCAAACQACzAwBDwAAHQABCQADGAAA/GYACwAAGAAAPwAACAAAGAAAPQUERQADKgAB.CwACFAACBgAPGAAmAAYACgAwAAgAARsAABIAD7ABAgceAAIEAAKQBgUEAAHkAAP9BQCIAhMBsQYPBAD///4IWgMPnQULAioAAgYA.ABAAD80FDQIqAAIGAAAQAA4wAActAAIEAAAIBA0VAAYEAAQbAALVAwAKAAEEAAhjAAkEAA8wABMAdQAACAAD/QUy/vz+IQACDwAA.MAABawQAJwAEUQAAyQACywABEgAIYAACPAAA4AAC7QACVBIACgADBAAy9/n3prkCAwYF/QVl+/n4AAEFbwAAEwACCQAABgAA3gUC.GAABBQAAFwAOTBECCAAL6C8BEwADCQACEgAEBgAAEgAAqAABMAACFQAJGAAKiAUCBgACDwAFSQUBZAUGMwAIJAAPqAYIBA4AAA8A.AhUAAA4AAhUAAgYABRUAAQQAAs8AAAoABQQACHEBAlQABJMAAgQAAj8AApgBAj8ABbQACSEMDwQA///6ANQEAAgABwQAByoDAkUD.AAoABAQADzAALQctAAIEAAK0AwAKAA8EAAINMAACBAAOaQADBAAPMAANApAAAnUAAAYAAA4AMQD+/AcABAkMAMRxAW1xACEAAhkA.CMkADWMAC10ADuQGQff59/jxBQL9BUDw7/AF2wUB/QUAIAAD+AQP9Bc1C0gAAQUAAA4AC0gAAi0AAQ8ABBgAAxEAA0gAAQsAAAQA.CA8AAgwAAQUAAA8AAEsAB5AGAQUAAA8ADxgACwIVAAAQAAAcAAQIAAcVAAVTAQYEAAHWBQAJAABOAAAMAAvcBQhUAAs/AAIhAA8E.AP//pwLQCAAKAAptBQgEAA/oFwUIBAAmAf70LwIEAAOwBAIEAAELAAkhAAfEFwkqAAIEAAERAAmcAATw1QGTAwEfAAUEAAIOAAi4.jwDxAwEIAAEzAAJmAAAKAAIEAAQwAAJRAAlmAAHNBQyQAAIOAA/0FxQB2AAg+vvXFyD+AZTXABUAAOIjABIAADAAIQH9RBYBlRAA.cBcBPAABBQAA3AUKYAACugAGYAAL9BcQ+PcFEfP6C0Lw6uf46ylBAQD7/dwXAfoLBWBIAAQAB/QXAYgvAF0AAGR3AjRHAVIFMwP/.+t8FNAAA+hgAALQwEQIz/AHwAADgXgFIAAMYAAIvABD+rBcFMAAJxHcCSAABBwYP9BcIAAcAAXsAIfsCGAABSwAAqAAArQEPGAAV.AGDYBfcRAehfAxsAAhIAAG8ACrABAh4AAwoAAFQAAvoLCdYFB+gvEv14AAEEAAkkAA8EAP//7gKqBAAKAAEEAAljAwILAActAwG0.DwP9BQAQAAgEAA0tAACYAxMAOC4PBAAADzAAAQIEAA9gABEIbQUAaQAOMwAPMAAWAkcEAuIdABAAAAM1AAwAAvcLAC0AAiEAAvwA.AQwAAicACJMACGAACF0AAAQADfoLAeIpAPQLMPLx7+U1BOsFAooAAmwAABAAAgQAB8R3ACEAAV0AAAkAAMYABBUAAIcADxgABAEE.AAIMAAgGAANqBQEGAAISAAgGAAIJAAJIAAIMAAX9BQITAA8MAC8ABgACYAYAFAABBAAAFwABAwYBcgYIGwAMUwEERQACDAACBAAF.rgADBAAL6C8ACAAPBAD///8PDP0FClEDAnIDD0sDCQswAADKAwAJAAIEAAldAAIEAAowAAAzAACYIgMMAA8EAAAEMAAIbQUANgAP.kwACBC0AACEABzAABcAAApAAA9UAAQYAABYAAfELAo7jABgAIvz9hJwOJwAAIAEAdgUADAAIkAALYAAAJwAHigAg9/nBfQL6CwLf.QQPiOwQEAApjAAEMAABRAAMoBQ9kcQsPDAAdCKABCRgACicAAgwAAgYAAkIABWoFABUAAJ8AAwwAAhgAABUAABoBADAAAgwADxgA.BgEGAAMJAAEkAAKTAAAPAAAIAAMEAAVTAQYEAAhxAQCYBwPzBgbZCwghAA4/AA8EAP///wEDrQQIBAAFSwMCnwMCCgAEBAAPMAAM.AscDBwQADzAACwIEAA5mAAkEAA0wAABpAAfbAw9jAAACBAAHOQAFSgQCLQACcgACBgAA1xAE3ykC+gsCBgAAZgAEIQAFBAAATBcP.rK0fAvEXIPj601kBAwwABgYAGQABBABB+Pv7AnIXAF0AADwAAUsAAVEAAqIAAhgAAgwAACAACOAKIf79mC8CDAAV/hgAD7iPIA9g.BiYAVAAHhHgFSAAPGAAFADoAAQQABg8ABAgABQQAABsABEEBA1MBAEYABigAACEAAHcBAAwAD/0F///FBZwDDAQABe4CCgQAD/QX.EQYhBAEEAAZaAwA8AwEIAAeUFw70EQ8wABoAIAAPMAABADMAB9sABTAABQkAAAQABS0AAQYACwsBAioAD40AAgIGAA8wAAsAyzUE.uF8AGABT/f4EAQSI9QX6BSD+/Sx2BVIBAJ8FAWYAAHEvABEACGMACWAAAvoFBTkAABh4ANBfw/j3+O/x7wH5+Pr6+rwEAlQYUAAA.Av4CKwUCDQAG9BEAOgUGGAAA9F8ANBcAOQAHuAUADwAjAgZRAADQFwMwAADsKAM8GABYEQD0FwAiAABwFwVwXwCQ2AKEqAGIFxD4.kAADYwA1A/r6TAUQ+rSoA0MpCKynEP7sAQAJADgAAQO0GAYMeA8YAAUAlC8AbgECbQAAFQAEADAAGDABkgAQAzAAAAkAAwQAAJwA.BNgeAdAXAjwAFftRAABUAAQhAALcRwIKAAEQAgMJAA8EAP///QOwBAIEAAILAAdOAwKQAwLaBAAQAAXgBAIEAAILAA8wAAoMrKcE.LQACSgQACgALMAAFBAACOAAPMAABAA8ADjMADzAAEAK9AAOlAAEGAAAcAAH0EQhkBQAeAAU/AAQIAATgBg9jAAACXQAA4AABYAAI.5wACBABl9/j3AQABlO9B+vr6+hMFABkFAe4dApMAACsAAEYABgwACRgABF8BAHsABAkABQQAAhsAAgYAABAABC0ACAYABnEjE/1g.Bg4YAAJmHgMYAAnhAAP9BQEMAAAVAAAEAAaoBgRjAAIEAAcNAAcLAACaCwgwAABqAAALAAGAAAT9BQAbAAFGAQAJAAQtAAUEAAKE.AAAKAAQEAAA1AAKYBwFUAAB9AQENAAmoAA8EAP///wcCEAUACgAFBAAHcgMFkAMFBAAPMAAtBy0ABQQAD6gDAwI4AA8wAAEAaQAO.MwAPMAAQAo0AAqUAAgYAABwAAf0FAgkAAAMSAQAMAkQEAjYAAAoAAEMAAwgABWMABYkEBScAAmAAADwABCQAAgQAA7uJEPn6CwHH.cSHwBX4AAP0FACAAAzgBA4EGAlcAAFQAA6ALAxgAB18BBQkAAgQABooAARgAADAABEwFAAYAAAgAAB4AABgAASokAW4FAyEAAKQB.AKARBhgAAQgAAwkAAgQAAuEAAmYAAgwAABYAADoABgwABU4AAAQABwwACRgAAUIAAAkACmMAAgsACBIAAIQACkQBABIAAFU8BAwA.AEw4AQkABzUACEIACagADUsADwQA///1A7AECAQABSoDBPhGAAwABAQADzAAMAUEAAQ5AAmoAwSpBQBDBQFUAAIVAAAEAAQwAADz.AwIkAAEEAANjAAEFAAiNAAAGAAEEAAJRAAMnAAEEAAImBAANBUEAAPz8URABT4MyAwID/RECEgACOQAACgAAcwADCAAOYwAFJwAG.YwAEGwACBAAD/QVA+Pjv8voLAu41AAcRAQAMAFwAB5AAAG0RBFEACKgABScAAgYAAA8ABG4BAncBAIcAAAgAAzAAAicAAgYAACUA.B0gABeUFAgQADhgABTYAAcgTBJIBAQQACAwAAKsAAAgBA04qA6sABDwAA68AAQsAABgAAaUAAA0AAQQABR0ABAgACQQAAB4ABEQB.BdMXABUAAAgAAAQAAocACDwACB4AAMsAASEAAw0ABEIADwQA//+bAtUDAAoACwQAB80CD+gXEQgEAAj0FwatBAQEAANyAAEFAAME.AAdfAA8wAAYBBAADfgMPMAARAQUAAgQAAsYDAAoABfcFAgQAAjsAAU4AA1oABAQABScABmAAAggAAS0AAGYABzAAA3IABAQABc0d.AI8EAAgAAKMEBeI1ALEYEPrHWQANAAqMvgYEAAFIMAZXAAJ1AAEOAANYFwL3EQIYAAEEACH49LiPEPW+gzD4+fv0FwJmKgG8FgGd.OwYsAQBwBQSs1wlA7wTVAAIOAQaBAADsFhD49S4Bc+8R+zkAAwQAAtcGASkABfAAAEsAABgABK8FAEynAPEXBRgAAAkAIP39RhgC.YwBS//36/waQAACxBgUUAQCkJRIDGAABqAALGAAAPAABGAABIgACBAAT/jwSAGcAGQKoMAAHAAGQAAJfEwLjAQX8AAAEAACcAAE6.FAAwMAFsAAAjAAMhMAF3AAHYMARgAA/0F////xEFcQQABAAC1HYEPAMFBAAChwMACgALzQUNMAACTQQACgAEBAAPMAALAgQACGAA.BgQAAjgAD7QDBA8zAAAPMAAKBQQAAkxrACkEBAMGDrQAANlNAk4AC40GAsMABGMABckAAFgdBPgKABAAAvoFAAoABgQAMvX19cpT.Ar6DAfMXBIoAAWwABQoXABIAAUsABVUFAAcAAQQABWMABQkABQQAADAGAFkHAQwADksAAQYABf0FBroABRgAAucAAQ8ABcQLACEA.ASoAAgUBAjYAAgwAAC0AAB8AAAwADxgAGAAaAAZZBwAeAAEqAAMJACICAzkAAQYABjQgBQQAAeQABjwGAAQAAgsAC5BCASEADD8A.BxQBDwQA///4DJ0FBLQDAA8ABAQACEgDDDAAB+gRACcAAwsABgQABjAAAggABzAABQQAADkAAAgAAwQAAw8ABDAAAAYAAgQAB8AD.AyQAAQQAA2MAAQUACXYFBAwACC0AC/0FANBHB9AvAIMKBPQpABUABzkAAAQAC2MABAkAAmAABUIAAEwFAlgXBAQAApq/AgYAAZTp.ANxTBTAAAgQAAv0FAukKCBsADxgAAgIJAAVKAQIPAAAhAAFCDAATAAEEAAIYAAIGAABFAAr9BQC3AAAIAAH9BQAXAABhAAQIAAEZ.AAEJAABRDAHhAAMSAAcMAAGmBQEJAAvlBQ8YAAUBUQACCQAFGwAC9B0DpQAHBgACHgAAtwAC4AEAFwAAEgAGvQAABwABGgAAEQAB.CAABOQAACgAFIQAFBAABQQEPBAD///4DOgUAZAMBCAACJAMBvAQDPwMCEgAEBAAPMAADAQQAAzAABwQABi0ADzAAAQIEAA42AAMS.AA4wAAcMAAMkAAEEAANmAAtwCwQMAAIqAAIkAALxBQAWAAH9BQXrEQI4BAKABAkkAAE8AAAKAAIEAAIvAARaAAVvAAJjAAAKAAEE.AAZMBQIEABD/nb8Do79S9vX39vT9BQAbAAQEADH7+/tPownlBQIGAAJmAA8YAAAExAUFEgACBgAPMAAIBZkAAjkABbcABRgAAnYF.AAoAAAkAAJYFAjwABSoAJv3/AaEAUwEBHgACNgACGAAAFQABcwAADQAOGAAAGgAAFQADDAAEVwAADAABLQAFDQAABgAEBAAPPAAO.AicSABUADyEABQtJAg8EAP//lwKoAwAKAA/BAgcI9BcIrHchAv8NDwEEAAjoFwUEAAVXAwAEAAWUEQGGBALURgABFwROAAjDAwAE.AA8wACMFnwMBMAAOpQMDDwACOAABvwAAYwAEYAACBAADJAABBAADYwABBQAJYAAAuHgDDwADJAABPgQFzUcAkgAAzKUAIQAAxE0E.QgQAMwADLwAAnAAFPAADBAACkwAHNDUMMEgHCwAFsAEy8vLylNc1AAAAncUAaQAAyC4DigxBAAQA/uQAAhgACRBHAlhHAxgAEvoc.XwClDARgAAAQEQEwABEDAgECMAACMwAANC8EMAAFEC8CYwACBgAF+gUCDwAUA3ACAAgxCDAABOQAACRIBxgAA6gAAXgAGv54AAAJ.AAEqAAKKBgAPAAc4AQDAAAEkeAINABD9BMIDPwAyAAD4MwYApAEECQAABAAHuEcMjBkPmAEODwQA///WCBwFDwQACwkeAwELAANq.BQcEAAhOAA8wAAgD+BYHLQAAIwAFMAACCAAHXPoFBAAIYAAAUQACDwAEMAAAEgAEYwAFBAAIMwADkwABBQAAbCQKYAALbwACDwAF./QUAXQABdh0J7gsBJAAACQAHZgAABAACYwAB5gQACQAEBAAIjQAABAACJwABBABB/f79A8hMIPLy6BcCkdcp8vL9BQAoAAUEAAAS.AAZwFwskAAUMAAQIAAFyCwqQAA8MAAICCAACBgAFIAcCBgAApAEK/QUACgABBAAIDwAPDAAmAggAAAYABZ0FAAgAAwQADDsBAQQA.A1ICCPQFBAQAAD8AA60AANwFAQgABgQAAB4AAAgAAwQAD10AAg8EAP//+wM6BQADBAEIAAJyAwHKCwM8AwISAAEEAAYtAA8wAAcC.BgAAEAAO9wsFMAAHBAAIMAACBAADEgACOwABMAADDgQHBAADJAAIYwAL9BEBBAAFDgQC3QoCDwACBgAAFgAE3C8F/REAAAwBABgA.zwAAsCIAFQAGBAACJgAHwAYA4AoK6gwABAAHigAFugAFiO8CAAYI/QUCBgAAsBwCCQALfDUBXQACDAAIGAAAiBcACAAAzjoCgQAC.GAACKgwCDAAPMAACBRIAAgYAAJoBAR0BBRgAAgkAC4hBDgwADRgMABUAAgwAChgAAgkAAAYAAQkAAycAAAwAAasAAw0AAIgAAg8A.CtAdAQQAAHEABLQGABAAAQQAAvYAAAoABAQACCEADh4ADwQA///+BjoFBQQABLcDD5wDAAhqBQUEAA8wACgAMwAHrgMCBAAJRQAK.LQAAMAACHgAHGAAJYwAHGAAALQAEXQAC+gUACgAEfQQCEgAF3C8FBAAPAAwCAgQAAGkAADUACcMAAiQABbQAAyQACCEAAcgEYvv+.+/X09f0FEPMBAAD6BQAfAAEEAAJFAACTAAJIAAEPAAA8AAEJAA4QRwUMAAIIAAXNEwUYAAU8AAINAAUMAAIIAAH7AACwBwIYAAB4.AAAXAAkEAAIbAAkGAAHVAAIMAAhgBgAWAA8MAA0BBQAADwAFEgADCQABVAAADAABUQADMDAMTA4MtAYACgABGwACCQAIBAAFOQAL.LQAPBAD//7cEMAMASAUH6BcPBAAFD/QXCwCtBAAIAAEEAAEdAAXIBAAEAAHsXgISAAkqAAQEAABsAwiDABb8GQUPMAAFAKzXB6ID.AAQAATMAAmYAAAoAAgQAAj4AAUwvAjkAAA8AAQQAAloSD2AAAwrwAwisWQAeAAHZBQWsdwASAET7/fsBOBYw/f0AdBYDbAAA0EcA.CAAAGgAD1QACNQABBgACJAAACgAAhwEACAAGkAAKxF8AcwtAAgPv79Y1Qfj18PjuIyD69gYABZ4EBeI7AAQAA4hHACoSAEwXAhcB.AGBIEgZPCwBwCwcoFwPEEQF6DQa4d0MAAP78QEcAoBcRAhgAAFcABNBHAU4GAJAwAExfAbMZA3gAADMAEgNgAAHkAA/EXwYPGAAd.AfwSAmMAAIRgAJ0FAI0MEfoqAAMEAACLBwEnADH+/QPQFwO0MBACKxoAIQAP0BcNAmAAAiQAAlICDiQADwQA///1CRgDAgsAB4oD.A0gDBxIADgQACAQFDzAAFwIGAAAQAAHDAwIJAAkEAAqNAAgwAABFAAHVAwMNAAIEAAFIHgAbAAKEAAEEAAOQAAQEAAvfKQAJAAob.BgVgCgZvAAQIAAMEAAeWAAYkAA7DAAoOAAIEAAL9BWLv8O/++vbuKQCU9Q/QRwQCOgUDGAABXQACDAAIBgAAGwAEBAACEgACBgAA.5QUFJAACBQACDAABCgACCQACHgACBgACEAAABgAACAADEgAAGwABigABHQAP3BEUDxgAAwJ+HgIMAAN4BgAaAAVtAQ8EAAAFXAEF.qwgDUQAKNAAMdwECYwACCgABBAAOIQAPBAD///sJ/QUCBAACZgMBBAALSwMAmgQNMAAFqAMD3gMDCwADBAAGYAABCAAGtQkHBAAP.ogMDATAAAmcFDgQADzMAAAIwAAeEAAUJAAIEAA76BQDcLwFIAAMSABECBgABNgACdAQJZgAFCwAEkwAF+QAFJwAD7QAH7hcFBAAy.+vr68QWS7/Dv8PDwA//7DwAAHAAEtAADfBECVwAAVAADKAUP9BEIAgQABooAARgAAEgAB3AFACYNAQwAABgAAFcAABYAARsAADMA.ANQBCuhxCNw1AgQACA8ADwwAIw4GAAIJAADjCwAmAAF6AASxDAAhAAEKAQAkAAH0EQEJAAESAAAoAAAIAAExAAD+DQENAAYEAAUL.AQAzAACQBgMMAA8EAP///wIDrQQLBAAFuQQNiDUPMAACBSQAAAQFAwsAAwQACTAAAgsAB9CbAgQAADYAAAgABgQAAxIABTAAAAcA.BwkAAAgEASEAAQQAA2MAAQUAAiQAADsEAVkEAA0AAQQAAPUEB/QFZfv8+wIAAt8dACYEARsAACEAEAY6AAMWAAppAAa2BgFmAAAE.AAQJAAUnAAONAA23AAG7U2D6+/v77/D9CyDw8NBHD/0FCQRRAACvEQIVAAYkAAAGAAOcBgV6AQEJAACHAAAIAANIAAIwAAgGAAIY.AAExAAAPAAAJAAEEAA4YAAIwAAERAA8kYAYFGAAAMGAPGAAQC8AGAFEABA8ABAgAAAQACCQAANIAAAgAAAQAA/oLAgQABCQABSEA.BXoBBY4CCGAAAgQABSQADwQA//+5CNwvDwQABQaFAwoEAA4PAwM8AwEFAAMEAAdfAA8wAAYAqBUACAAC7AQFBAAGMAABlBEFqwMP.rC8FBgwAATAAA78QFP5AdwQEAAUnAAZgABEAMAAE8AMmA/9YrQLcFwMYACIA+3+hAIdfE/0tAACkEAXcIzAB/QBjdwCRCgFQFgMt.DAAEAAeEAAP2AAEEAAxoLgEEAAAAJAH4FgANAAHEXwB83QGsj1D5+fn399xNANB3Ah8AAgQABIIFATwAAFQAAZ4AA6Y1AJwAAMgK.ARMAAecABQ0FAjAAA20AIv39cBcCMAADcBcBNQAJ3C8AEgADNwsFRAEASAAi/gN1AAAnABP/QQEADAAEnAACxwUDCgAPDAAQAHtT.BGAAAPQXAC+QA8cjIQMCYAABhAAAVBgB7AEAfgYBnJAAdQBD/QAD/zsZM/3/ABYAAcAAANgAANsMABEABSABAAQAAqQBATMAAMZf.BH0HCSQADwQA///0BfYDAAQAAQsADpQRAiAEAAoAC7UjAQsADzAAHgVaBAQEAAgwAAkEAAEwAAAzAAEpBAMNAAEEAAgzAAljAAEX.BAUJAAJiBAANAAEPAAIVAAUGAABZNDH8/QE+AAUSAAUJAAIEAAhpAAAEAAEtAAIEAAldAAsnAAEEAAtLACT19tBHAfoLAtZTABkA.CAQAADMABnARAggAAgYAA9AdAQsAAHIAAxYAAwQADxsABQIMAAEFAAIPAAkgBwAJAAG6AAVEAQIYAAgGAAgwAAJ7BQIMAAEyKg8Y.AA8BCAAAFgAFBAAAGwADbgAABAAADwAACAAEBAAKMQACDgACtwgI6gYABwABBAACIQAIBAAAUQABMAAAKgAB3gADDQAPBAD///8B.BfYDAAQAAgsAB5QRAWAnAx0KABAACM0FAggAApADATAAAycAAhIABAQADzAAAwoEAAM5AAQEAAMPAAcwAAhnBQIEAAMkAAEEAAZj.AAEEAAD8AwogBABuCgHrFwVIAAKwiAV8oQItAAMGAAUADABkCwAJAAYEAAJoAA2TAAiNAAAEAAHuFwsUBxH11iMg9fcGAAj3EQAc.AAIVDBEECwAChAABBgACCQAPlC8GBHUAALQMAZMAAxsADxgABA9IAAcG1AEDEgABGwAFJBgFEgAABwABBAAPGAAaBAgAAX4AB0gG.AAoAAQQAAWQCAAkAAxsABLQAAA0ABQwAAQQACM8AAAcAAgkABhUAANgGABIAAA4AAwQADJsBDwQA///6BfYDAwQAAbYEAAkAAQQA.BTkDBQkADDAAATsEAwkACvELAgQADzAACwIEAACuAwcVAAlFAAcYAAIEAAMeAAcYAAhjAABLAAAIAAEUBAEJAAJ6EADHFwAOAAME.AAIVAAL3CwAQAAC4XwGQPAuVBAoPAABpAAI4AAF+AAX9BQOTAAEEAAMkAAEhAAgEADD9/f3fBaAAAPX39fX39ffzvn0F/QUCGwAA.CgACcgACBgAEfAUArgABeAADtgAKNBcPDAAaBAgACSiPAGAAARUACAQAAhsAAwYAAeoAAucAAhIAAhgeAgwAApEFAgwADxgABQh4.BgUVAAINAAJXAAAKAAEEAAYbAAUJAAQEAAARAAFUAABICASgCAUwAAQIAAldAABsAApgAAM8AAMLAA8EAP//zwnbAwQ8AwADAwCl.BAEMAAWyvALOCgQMAAAEAAmsLwhFAwF5Aw8wAAwHeAAEBAAA4EAHwF0InAMFCQADBAACPgAB3C8IMAABShABigwIFAAHUAoO6BcA.GwAo/P3oLwiUjxT7/QsAJwABQgADbwABKBcCtgQAJQwBTwAAGAABUwAEJAAABQAABAAApKYBGQACJwAECwABrgAASAAAo30x8/L4.5AAg8vSXuTL7+fuTBgBsMAl1HgAGAAJqIxf+SBgFlKcA0AsCfgABBAAQ/eowAAkAAGwAAPRfAxsAFPsYAAAtHgLcLwDMAABgQgBI.AAG8ASMGAt8jAKCPD9wvBQKULwInAAEUAQIYABD70hED4gUBMEgDjiMCbBgHGAABKAAA9C8AlwsASwAx/f0DVKgCbgAI3C8B0EcA.OAAADQAhAPjnEgALAAWoGADGAALQFwHAAAIAMABxAQDQXwNgAACxAQFaAABsACj//TR0BgoADwQA///4AioDATkDA9QEAQQAAwsE.BXgDDwQAAQ8wABUBuB0FLQAFCQAANgABVgQDDQAFBAACpgMESwAIMAAPMwACAOEGACkEABgACxwFADAAAWQFAw0AAQQAQfr8+gE5.CgJ/BQATAAEEAADDAAJ7AAFmAAL6BQIPAAJiBAXeAAxjAAL8AAAxBQwCAUH6/PoG0BECuF8C9BcCBgAAP0IKgQAISwAFCQACBAAF.DwAFCQAFBAACEgADBgAHmQADEgABBgAAEAAEXQAPBgAGBLoAAA8ABEgAAFABDxgAAQMPAAELAAAJAASVAQwwAAEMAAFfAAAEAgMV.AAAUAAdcAQ0EAANfAQE8AAkEAAM0AAZACAIMGABXAAItAAMhAAMEAA4rAg8EAP//9QChEAKtBAAOAAAEAAVRAwBLAwpFAwApAAdC.CQIEAA8wABgBCwAIMAACBAALnAMDDwABLQAJQwUHDAADJAABBAAw/v/+rCkE2wwAdwQKhwAO0y8AywoEGAwFFQAACQAcBMMAAmkA.ChQABtkFBcwAACcAAwsAAd0iBCEABQQAAocMAvoFAgYAAvoFEfPHWRMCrgoDG6IFhAACCQAAUQAADgAGnAAGCQAFgQABEgAFGAAC.zBgB5BgAEgAFHAUAcCkB0gADMwADCwABtAAESwAQ/vizBgAMAyoAAwsACQwAABsAAj4BBIiJAAwACjAAACQAAQ8AAQUACRIAAAoA.AAwAAggAAQYGAgcBA4oAA9wFBQwYACEAAsglAwoAAPcLAE4AAdIAAyQAAnoBAiEAAQYABYQGDwQA///+CZoFDQQAANEEAAgABgQA.DzAAKgILAAKKAwBvCwAIAA82AAIDEgAIMAACBAAHDAADJAAHYwAAvwQACAAABAACXAQCEgAA0wUAFAAABAACDAACYQUj/P85EBD7.TSgSAxsAAJAAATwAAwkAB3IABQQAAFYAAsAABB4ABY0AAgQAAngAAAoAAgQAE/8qTgV81wL9BRHwBgAC/QUAJwAAf0EDOQAAewAC.gQAADgABmgUBCQACEgACBgAAogABHAUACQAFEgABCQAFMAAIzBIAjwEEGAAFKgACDQAFMAACBAAA/QUEIQACBgAC6AsR/ScAAkgG.AzMABGAAACA3AbgFAxgAATAAAgwAAjAAAn4AASMAAAQAABoAAkQBAWkAA7gFADUAAAkAAm8AIwD/hJAFXwECjAAABAACCgACBgAA.2BICCQADfhIGBAADIQAGBAABKAgACQAPBAD//90O3C8FNwUDBAAClBEHMAMD+QMHggULMwADnQMCBAACLAAEKgACBAAMMAAExgMA.BAADewUA/QUJECMCQgACOAAExBEADAAECAAAzgoC5BUKBAAAmC4cAOgXAj8ADKxfBugXBkgABv0FCMAYD8QXBACSCgUkAADIFgZI.AAUkAAAEAAckAAJyBiDz7+sFUPD18Pf26x1C+Pb4+I6/AQQAAiQAA7QAAlgXATIBA0AXAxgAAMkAAhAFGf0YAAAwAADUXwARBwcY.AAGRAAIMAAJYXwIMACAD/yovAgwACGAAA3kFAQ8ABUwFABsABMsBAE8TCBgAAWAAAAwAEgEdBgQYAAEwAANTAAEMAAAKACP9/YQA.AWYAAtwvAbkBA/SnA9YLAPQXAvcLGAM4MQBGAAIhAACUAgEYAAAiAiUA+2AAABgAAwgAAFgaFALqAQAUAQIIAAAEAAcuAA8EAP//.5AuXBQPCAwqYWAAHAAcEAAwzAAFsGwIJAAIwAAAoIwGVBAITAAswAAHMAwAJAAgEAALFBAAKAAIEAAgOAAFiBAWQAAUEAAwzAAF7.AAUJAAhmAAI8AAgGAALuEQLoFwAVAATxBQgEAA5CAAAKAALLAAGTAAAYAAckAAAPAAAoEQEMAAsmJQS4XwKvawK+XwLfLwB2+0H2.+Pj3+gUBDBgC1AQBBQAADwAAewAE6gAAyRIEVwABDAADGAACBAAAKgABqwAjAwL9BQB7AAgJAA9IAAQC5R0CDAAFGAACBAAANgAA.CAAABAAPDAArAAYABgQAARsACGIBASQACQ8AAwgBBCQADO8BAR4AAwkAAfoFAAwACAQAADkAAHQBAmYABZ8IC+EADwQA///pC5cF.AAQAC7YEBWMDBAQAAsMPAAoABAQAAl0DAAoAAIkDAwwABasDDmMACDAABmMAB3UACP8LCI0AAgQACzAABWAAAxgABVEAAQQAAl4R.AGYABHUAAQQXFQIYDAXoCwUEAAM/AANWAACQDAmQAAIYAAF+AAXJAAGMFgfsFgtEAQQnAAL6BQUGAAbcLyMBAP0FAC4AAS0AA0sA.A1QAD8RHDgPrBQezBwMSACAAAPPKASokAg8ABTwAAMgBBKAXDmAABScAAgAMAgwAAjcFAgwAAjAGAgwADhgAAg8AAhgAAgwAAhEB.AiMABSQACAQAADECAx8ABjAAAAQAABUAAc4lAA0ABwQAAZkABfUFBAgAAREAAlUSASEACaQBAesHBZYADwQA///sBTcFDAQABR4D.DsRHDfoFAFcDBCQAAKIDAwsAAwQAD2MAAgtUAADqAwAIAAMEAABFAAAIAA0EAAGWAAs8AAVgAAVFAAIJAADaBAAOAAnZHQUVAAL3.CwMKAAQEAAIqAAJ8rQAQAAEEAAuNAANCAAFEBAAEAAGTAAACAQEnAAl7AAckAAK0AAEVQkL++Pf4+gVg9fb19/f3+gUAJQAH/QUA.TwAAMAAADAAEBEcCVAAEYAAABgACGAADWgABBgAAEAACZwUAJAAAHwAQAt+5AxsACBgAAtAFAgwAALsRAQkAAEgAAiQAAQYABSIF.ADkAATAAACEABJAAACcAD6xHFgUMAAQIAAcEAAMTAAzcBQUzAAHLBQAJAAUhAAPyAQR7AAUhAAIEAAYOAAUhAAA5AAZgAAXYAA8E.AP///A/oFx0PMAAdAQQABiQABAQAAIAQFwLnCQUJAAHMIQYwAAQYGA5XAAUkAADYRQDWBQAPAAHpXQP6BQW4RwAlACcBA9AvAxUM.AAQAB2AAAJwwAQgAACQAAnAXAgQACHcAB2QLAChfAAgAAQQACiQAAAYAAQQABbAWAHbFASQAALtrYfLy+/v7/YQMEP2iDAGkEAFX.ABQD5AAAnQUEFAEAcgAExQQAyKcHGAAJ7BYECwAASDYPwAABAHQBAwwAACMLAgYGAkgABdAFACQAB2AABRwvDZAAAxgAAF8ABEgA.ADgBE/usjwBsGBD+VBgCMAAg+wPkAAIMAAK4XwDcF0YAAAP8MyoB9KcAOAACrBcBZwIAGAAFeAAA8QUAGBgCDBgoAAN4AAE3AgAh.AACAAQP8AACKABD+VQACYQAA9AAACAAABAAGOgAPBAD//+kCBAMH0QQFCQAFBAAJcwUCCwAPMAAXAQQADiQABhIABAgAAGERBJ0D.Bh4AAWAAEgPQBQIVAAokAAIGAAAPAAEOBAAFBAH3BQASAAEJAAX5CTL6/P2TCwIYBgAKAAoEAAJQBAAKAARdAAKeBAU6BQBUAAIk.AASMBAAnAAUkAAQVAAInAAXoF1D3+fcBA3oAAP0FIgAA9BcAunFR8/MFBAL6BQAnAABLAAAIAAB7AA/sXgIAEx0H0BcDHgACBgAC.hAADGwAGMAADwAABDwACKjYCGAABjwASAHsGMgABBDAAACoAAR4AAgkAAioAAwoADwwABwcPAADwAAMMAAQyAQBwEQAIAAUkAAYJ.AAIEAAMPAAcwAAAKNwFBAQAPAAEdAAMJAAnMAAQhAAB0EwAQAAIPAAncjwBAgAALAAIEAAEWAA8EAP///wELpBYCPAMHBAAFHQoD.BAAPMAAdDyQAAQwSAAsOAAceAAUqAAIJAAJdAAXQBQIVAAV1ABAC0wsDEgAF4gVW/vz+AgO7QQUYAAUEAANFAABBAAAIAABdAAER.AAMEAAIYAAHzAANiBAQEAAM5AAB/AAoUAQcnAAJ5vyP4+bVNAgAGIPX0/REg8/P0IwX9BQIEAAVUAAB/Cw8MAAEC/QUCBgAJk34H.CQAf/RgAEAP6BQEEAAIVAAIGAAKFCwIMAAIoEQIMAAKsFwIMAAIYAAJTAAIYAAIMAAUYAAIEAABKAQAIAAAbAAEIAAAJAAMuAAEw.AAXkBgMSAAVLAAGEAAAJAAHcBQYjAAUKAAQ3AAJjAAWYAQAPAAILAAEgAAD3CwANAA39KQ8EAP//+wUbAw/oFxMG6QQPMAATBKoD.AAQACAwAAgQAC0IAABS+AdIDAPwDBy0AAFoAB1wABUgAABgAAAgAAwQAAtQuEfsuKQjEEQX9BQK4RwBdAAESAA/oFxgE9gAGJAAB.CAAJJAAAcRADFAECJwAg+vlkBQD9BSL6+PoFAOgdIu/wDAYDMwABBAAR/gYGEf2WNQNUAAFIABH+BgACyAQDWgABBgAAEAABQwUJ.qAAEFwEAoxECFQAAHwADFQARAKAXAy0AASQRAB0AAngAAEwRABcAAFkBBGAAD6xfCAVYvwAQAASHAAIMAABOAAIPAAEyAQIHDgAW.DAonAAIMAAIGAAMzAAEwAAAMAAAzAAesFwMIAAQEAAUzAAQhACH+/9kRBA8ABvAGBAQAD/0F////DACevQZcCgDULgMLAAnRCgBv.AwQkAAgMACID/xA0AAwAAbsEAAkACCEAAAQABAsANf3//dUDCwQABhgAEwHy7gAMAABREQA+BAIMAAIEAAKvIwLELwAQAAJISCIA.AMcvEv6VWQQEAAKHAADfAAfoBQUADABPBQfkAA/EFwIPJAARAAQACCQABOgXAOsFEPOyTQLKOwKQrQC1Xwf9BQGFCwBJAAKiBgAK.AAAXAAKXEQASAAGlHgHHAARWAQIYGAQwAABaBQQYAAB4AA8YAAEAMAACDAAFQBcBZQEAMAACJwAFIgUAJwABYAACGAAFMAAAVAAE.OQYA5AAHYHgW/pQvMAADAhgAAtYLAjwwAo4FAgwAAmYAEQOqAQCyBST+/egXAKcAEQA5YQF4AA9oAQMPDBgIAWAAA4QAA7hfAQQA.AssAB5kCDwQA////AwDzAwAIAAEEAAJBAwIGAAE3AwgeAAgMAAIEAA0RAAD5AwEIAAYEAAbcBQ0EAAhRAAgMAAgEAAavBQQJAAIE.AAYYAADLBAAJAAIEAAVIAAhkxQUEAABAFwStBAAQAAA9BAQMAAHwAAUEAAgkAABmAAJXAAokAAAYAAEnAALoFxH66xEAwNwF4hcB.+gUCAAY1+/n79wsB3wUACQAC3wUDCgAAgUIAHAUCDAACygUACgAHpQAAzAYBcgAADQAPGAATCaARAwsAAwQABScAAh4AAwoADwwA.BADiAAYPAAEOAAEMAAUkDALoFwQhAAArAAIIAAhFAAIEAAirAAIEAAHcBQPZBQkEAAATAABsAAIzAAAOAAAWAAEqAAKMAQAKAAN0.DQBpABT/2BgBHgYCIwAPBAD///8UAOEPAFUJAAwAAgQACLQDCAwAAgQAAjAAAmADAQsADD0RCzMACB4ABRsABQkAAgQAAlQABdkF.AgQACA8ABcQvAOEDBxgAAUYFADoFAJycClQAACoAGf24RwIsBAOQAAEFAAD4ABT+reICJwAAiQAE0gABBQAPJAAFAA8AMf/9/egR.AhAAA/oFAgYAAfoFCMdBCwQAAQkGALEEAu4FAAoAABcAAgAMAAoAAhgABWQFAbQwAAkAAuoSDxgACwCxAAAcAAASAAEIAAE0uQEh.AAAfAAEUDQLMAAKaCwIMAAIwBgIMAAIYAABRAADoIwASAAUQAAAGAAMJAAGgBQg2AAEGAALEHQEhAALfCwMeAAByDgZrEwaMBwId.AAIGAABoAQMKAAPcBQIwAAA2DAAIAAIZAAEKAAMnAAcwEgS0AA8EAP///xcDJgQLBAAB8F0ATgMDYAMDBAALLQAKDgAABAAE5AMD.BAACvQMACgABBAAFHgAFCQAAmAQORgABBAALZHcFDEILGAAFrEcFrgACBgAELwAABAACEgACBgAF0BEAmxYDRAAABAACHgACBgAI.JAAAbAAEogADHgABaQAL2DwAhAZh+fj7+vjy3B0Cl48AtXEH/QUFAAwSArUSAQQAAuIFAAoADwAMBwh3AQLiBQAKAAH3BQIJAAX6.BQINAAgwAADGAAW3AAQkAABWBwGofgKbQQIwBgAqAA/oFwoAQgADDwAG3AUFBQEBUAEDDAAABAABHgAACQAAKQAHDAAEMAAADAAB.bAADQgABBQADBAACPAACBgAHaAEDEQAAnAABoAIEEAAFIQAPBAD///8wBAgEOfr8+mQXDwQACgKUFwWgBQwEAATrBA9UAAlA/AD6.+kUAAHcEBVhHBPVMDtwXAhgAACUFKfr6xB0EbAAIBABI/fz6+3gADSQAAuMECXQWByQABbQAADwSBLwuU/r7+v4DGABBAAAA97g1.Ne/u7fQLkPj29fj39QD/BqUAASABBUgAAMwAEPzdQQ84AQAH4QwX+4QAACcAAS0AAegFBkgAABgAAR0BABgABcUFAA0AAwgAUP39.+gADYAAA8QUAbAACFQAAG2AB1GUAyQYAkAAE8AYACwECNRcBBAAISJAAcNcAKQEAAgECaDEBixcDuEcAIgAAlwUA8AAARQAAeBgD.mQAQ/TDeBiQAIAAA6r8CCgAJdAEGdwADwQACfgwP2DADAdCPANkAAA4AAC8MAQgADwQA////JAV5BQAEAARgAwsEAAI+BAAKAABc.EAYMAAWQAwgEAACtXgHYCQANAAe0AwUEAAJOAAkbDATsBGL7+/sDBwM3IwAQAAQ8AAWIXwANAAQo7wIMAAsEAAJ9BAAKAA8UCgoG.JwABBAAADwACQREKBAAApQABhgQAdAQi/f2yBQMQAAEEAALuBRH0BgAR8AAGMPj5+voFAB0ADGA8AvkAAEsABAkABQQAAvoLGQP3.Cwd8CwTMAAEtKgBMBQMbAAREAQA/ABABVAYDGAACBgABBAAIdQAD/TACAwYEVAACBAAAEgAACAADBAAEDwAAbAAD6AsADwAABAAA.CAcB+gUADQAHBAAAMwAAKQAADAACBAAAPgEACAAGBAAAJAAACAAABAAADAAFdAEAyQAAbAADMwAGdAEEqSQBhAAAwBICIQAEzAYA.JAAEIwAPBAD///8vAGcLBHgDAE8oEAEtBAClA0YAAAMCBFkCbQMALQAB7ygADQAHBAADJwABJAADPgoHVAAArgMCIQAAj0YBHgAC.BAAEAAYALgsE/QUABgYAgwAADAAIOQAFBAADugYANwQACAAABAAElIMAchYSAi4FARcABEgAALwEAbAKBScAAKEGAQoLAs4KBBMA.AAUAA1YQAQUAABQAABARAwwAMvj5+N4AAgAGEfL6BQDxI0Hv7QAB/QAEBAAFAwYF3O8ADQAA6AUDGAAFygQm/fzWBgDNEQhAQQdU.JAIVAAIGABgAOdICEgAANAUAiB0BEgAAHgAAjiMHeAADOQABBAAFDAACagsDDwAC9gACBAACEgAEBAADIQAAWgAACQADDwAEnDYA.DAABBAAEDwAABgADRAEEeDYBDAAH2AAAVwEDDAAD+gUBGxgP6BcAAQkAAgoAAlQAACQAAA4ADwQA////MAPKBQQEAAhkHQUEAAhM.IwJwEQL+BAAQAAUEAAfEBQ8kABEnAAEhAAcYABL8pbgBBAAJjQAGFwAJQQQIVQUFGBIABAABUAQDWC8TApQFANQWEf7aFgAOAAkE.AANOBgIEAAhH0AQIAAIEAALNLwC7TQFwrQIABiPw7wAGAN8pAa99Ag0AIPwAlJsACwELSGAE9AUBzBgDDAABJwAGDAAA0iMCmQYB.4AoCyQAAPAAHr+kD1gAAKRMk+wCI6QAkAAgYBgF1ABH9GgER/TEAAz8AASABAIEFB+gvBQQABEsAACwHAoIFAAQAABIAAT4BBDwA.AGAAAR4AAwkAAwsAAAQAAqYFAAoAAhsAAQoABQkAAngAA/wGAyoAD+gXGwYKAA8EAP///y4GhQUKoAUU+JAtAAQABxgABQQAUPr5.+gYD8BUg9/r4KBIBXcQCBAANMAACBzsCBEEAEAAEbAACfgYKBBcABQALBAAPPBgLAAYAACUEPP0DA+hfAAoAAFUMBgwAAhgAAokE.CFAEAhgAAAoAB1QAANwXEPy6AAINACD49BQBMO/u7OsLEPXZHSD39mndIwH/2AAAxHEACAAABAAh+vxkAAALAAAEACb9/BgGCNwX.BdkFAQAGAwkAAgQAAqUAAAoAASgXAvYSE/5rAAIFEwAYAAEOAAZBGQAEAAcwDAA3BQEMeAAUAQHjAANXAAThBgBpBgEADAIEAAHQ.LwNCJABwLwFPRwEkAAEMBgEEACD+/vgBAkgAA8RHAF4AIf36CCsDDwAW/JAGAjAYAH0NAEQxByQAB6gAEPvsBQAJAAAEAAF+AAC6.AA/oF////zoPBAAFCTgEBJgEAJVMFQR3AwOnCQMEAAcsBAL6BQAKAAuABARIAADDAwdkBQkkAAQXAFb6/PoDBBwLASgLAycAAxMA.CgQAAFYEB4QAApwAABUACiAKAHsABIAEAiQABQQAAi0AAAoAClEECIQAAAcABwQAAnOnEfheuQLoFzX3/f2vUwV1BgBrBgRFAAHK.FwMMAACNAAAPAAUMAAAGAAIEAADIEAWQAAkoKQMJAABwCwTYAABcGQAIAAYEAAIkAAAKAAc8AAAKAAETAAIPAAAKAAEbAALoEQUE.AAgeAAIEAAASAAR8BQIEAAASAAAIAAYEAAASAAo4AAW7EQIEAAAhAACLAAAMAAAIAAs8KgEEAAIzABEDgAEDMAABwAAC6wsCfgYA.PAAHOQAEe9cPBAD///8/DwAMBSf7+RgACDgEBpIDJQD6/AlWAAADAQPfBQhIAAfkCScDBCQAB1QAJPr4FQAABAAAYQACuxcABAAA.EgABBAAJEBcABQADBAAH0BECVgQACgALqB4HCwAFLQAA7wAHbBIIoBcj+PrZBWAAAADx9fHuCwF8iRH47hEADwA27+33OwAB2AAF.AwYERQACBAACyQAACgABBAAA2RcACAAA7AQDbwAQAZk1AAkAAMAGAAgAAucACKgAAyoABAQABg8AAWgTAjAABdwFAA8ACDcFAR4A.AAoABAQAACEAALwZAxgAAH8ABDwABQQAA0oHATwAAjAABWAABQQAAhgAAh0IAjAAAxEAAWwGAMgHBRAAAQQAAjAAAAQAAOoAAQgA.ARIAA6UAAmAAAxIABgwSAB4AAwgADwQA////RQ8ABgUgAAI1WQEKAAoEAAgkACUFAKdwNgUABUsACCQAAOsEAAgAABwLAf0FBicA.BQQACDAAAVAEAxYRFgRAFwAHAAUEAAkwAAwEAAI2GCYCAigXCNsRDwQABQVVBQIJAAJ2lQB8jxD35AwCo18R+KllACUACgQABQAM.Qfv8+wWmCgKESBECzAAAsAYA3B0AGAAAJQAAAAwAGAADrhglAv2oAAL4CgUPAAsEABH+mQAABAAADgABER8BxC8AIgUAnB4JZB0A.FQAHDwACVAACYAAAkAANoF8GMAABiAUD/xgIRAcBBAADJAABBQACBAAIqQUGRQAECQACeAAFVDAAIQAPMAAEAvoLAQoACcgNBgoA.DwQA////RgWVNAwEAApkBQWk9AlYCwBpBQAIAAWjBQbPAwEEAAA4FgfQLwlgBgQEAAszABH4LBYACgAAkAYIDAAABQAAMgQIgQAA.yAoGRAQAwEgACAAABAACegQDGwABBQACBAAItAwPkAACMu3r7cS/IPLv7gsCrFNp9/n3+Pn4SAYW/DgBCNAXAmwwA3gABMwAEP1Y.pwAJAAIEAAMeAALKFyP+/g8AAG82AAgAAg8AA1iPAQQAFP4zBgD/AAARAAHzABIBIB0BEAAKbh8OrC8BDwAHNEcKMAARA4oGAC4A.NwAA+MwAF/6sLwLoFwKuEgOUdwIEAAE8AAAJAAC2LwYMAAEHAQAJAABCAAJOBgEEAAYKAAC3HgY8SBgAKA4CVQwACwABTgcBCQAP.BAD///9NAKUDAAgAAwQAAA8ABwgEAUkEAAkAU/r9+gMBDQAFkgQDBAAHfCkFBAAAhQUEwQMAHgAI/QMEjAQAGAAACAAEBAAIMAAA.CAAEBAAEPAAIHQoApwoIqAAIxCkEBAABdxwCEAUADwAPUQQFIO3r1hcACgAE+gUg8vAGADD6/fr6BQEZAAVFAEn9/f0GbAAAFAEH.DwAEGwAHqwAL0gAGDAABJAACDwAPZBEGBxgAAxIABAQABw8ABPheBz0FAB4AAWAAAA0AAQQAABIAAAgAANMBBC8AAgwABA0AAA4A.BD4TBHgAADYACkgAAJwAASQAAPoAAREAACQAAiA3AVgAAQUAAA4ABQQAA1QAASQeAC0AAIgMABEAAtEBABYAAA4ABr0ADwQA////.VgD/FQ6sAwQEAAKoAwigIwj3BQgMAAXwCQD0BQAIAAMEAAJCAAAvBAKIBQHtAwEZAAAFAAIEAAgzAAIOBAAKAAmVBAZsMAD0BQAI.AA8EAAAFMAAFCQACBAALDwAIBAAFqUFTAAAA7ewDBiDy9BUAAgAGEADrIgAVAEP4+vgCZkcABAACVAADBgAEnAACDwAA2QQB0gAI.ZBEC3AUFDwAG8wACFgUKBAAAJwAKGAAGawEIlEEELAEAEgABYAAABAAADQAACAAIBAACFAAChAAAsQAAlB0FDAAKrHcACAAABAAA.iQEDFwAGBAADSAAACwADphEJPAYCCQACBgACSAYDDAAABgACMAADEQABBAACEgAACgAHtAYPBAD///9fBr0DAQQABg8ABAgADgQA.BowEBwQABtEECgQABlEABfYbAOkQAJSVBSgFAhUACAQACDYAAgQAD/cFCAgEAA45AABcUgKMBAJSBeICAP36+v37+/77+/r/AusF.ZfP08wP8AwAGIPf49BcACgAKDB4JsQABTgADDwAHlAUDEgABBAAA/xIEDwAIfBcABwAHBAAFRVsFoAUCBAAFVAAFXAcy/fz+xC8D.SAABhAADEAAFLQAEBAAAIQAAKAADGAAIoHcADgEDFwADBAAGbAAHpwECBAADuAsCBgAAWR8V/kg8EP4BXAAYAAg/AAAEAAtsAAtR.AAstAA8EAP///20MugMBBAACNBEAqwMC9gMBBQACBAAJtEUPBAABAy8EBAQAA4YECwQAB7UjBmYACAQAAQoFBvQFAWx4AAkAAgQA.AfQRCDYAArMEAgYAABAABzAYAGAAEADEFwINACPw8NAFUO/t7Pj6zAAR94t9Yvnz+/r8+sodEQOARgAlAApIAAIkMAMyAQWcAApM.FwBvAAIhAACcGAMkAAAJBgHSAAMEAAQvAABLAAGgRwI2AAgABgg5JAiUFwX0FwA8AAeEABb4CwADBAAAIQAAmRkGGQACwAAACgAA.GAYDCAABnAAA9gAADQAAmTwDkAAFBAAARUgPzAAHEvssAQKWBgGoAAJ4AAgkAACOMQEIAAAVBgGIdwBIAArTAQ8EAP///3cCvQMA.nwMHXgUADwAEGAAGtQMElAUDMwADHwQDBAAJiwUFBAACJAAHGgQIxAUAZgAHNgAA/QUCMAAAfQQDCAAObAAPaQADDwQAAQKCaxHw.xC8AcI9S7e0AAgNA3QDQOwmEKgAEAANsAAE8DAEJAAD7BAEIAAAJAABYQQMhAAKyHAAVAAMOAAElBQAJAA+cAAEAuDUHFwAEZgAG.BAACEgAFdgABDwAEDgABDQAACQAHBAAEFAABJAABDAAABAAADQAAhwABFgAEYgcBfBcAaAEH+NwFBAAJSAAClQcKwAAEIQADBAAC.DwAE8xcADAALVAAAQgAACAAMBAAKJgAPBAD///91AswDAAoABwQABlsFBAgAAAQABXwFB012CAQABjYAAegRAAkAAjMAB/cFADIE.ApIEAQQADzMAAAIEAAczAAtsAAgzAAIEAA4SAADWBQHfBSD6+eURIPDuxCkR75pfAh8AQfj19fhkvwANAAesQQJYLwClAAd8fQAc.AAXpBAQJAAMGAA2oAALeDAkAGAMIAAMEAAUYABADtx0DDAAFAAwAHgAIzwAELQACBAAAHgAACAAJuBcFIBkBDQABCQABBAAFhQUA.gG0DCwAGBAADLAAISAATApEjAtBlARUAAeILAWAAACEAACESAAwAARsAFf26FwI0DgIhAAAbAAAnAAMMAAL3PQXeAA8EAP///30F.sQMCBAAGDwAErgMBGKUHTC8BzAMFBAAOMAAMxAUEIAADBAAHJwAIsgUJMwAIBAAFMAAHTAUIbAAIRQAAdwQi/P0luTP9/f1kj0D1.9QD99BEg8O8ABlMAAwLw7egXCAQAAsAqAAoAA9cEAAsAADQXAWAACBIAAAcAAAoAABIAAxcBBAAYAw8ABAQAAxUAAQYAAOkoBTgZ.ASYAAmcFAkAFC4hfAgQAAj8AAAoAEAAlBgEJAAEuAAWHAANCAAEEAAYtAAAEAAMhAACYAQkYAAZUAAUIABb+eYkApDEE6SsAGwAf./RQBBARcAAsYAAKYDQJ7AAUkGAAkAAewAQ8EAP///4EBtBUCBAAP3BcFAtIDAMkDDxB3CA0EAAIaBCMD/1AKABMAAQQAArIFBvEF.BEgSAwQAAZAAAjMAJgMC0EcPsRAAAgQAB4gvBtwXIu/vGAACAwYg8/eoAAJD3QCQAAREHQlcXgQEAAC3AAcYAAzcFwWORgSQYAvc.LwIPFwAqAAR8XwAMAEP8/foAyQAABAADOwAC8WUEDQAAEC8HDAAFSQAAhBgHGAABIAECBAAI0BcJABgEJAAAuxcBbgEADQAA2hEA.HQcCDAAV/egRJf363BcLYAAA0i8CCAAAGQADCAALABgFjRMg/f7f3QAKAAEEAAAcegAIAAAEAANvAQ8EAP///4gA8gQACAAEiAUC.0QMBDAADGwACEgAHBAADGAABJAALBAADGwAEBAACygUAaAQHiQQA/QUFVAAETQQDOQAEGAAAsBAFMQsPBAAEYvXy8gsKBtkXAJdB.EPH0BQAABlLw7wYB/v0FVgAAAPT3fAUAEwUACABAAP39+yyOAwwABmkAAMgQD9wvBQScAAYSAAQEAAYPAAUJAAe1NQIEAAYkAA8Y.AAUBbAACEgAIWBcZ/ZQFA2wMAJoAGANjAAExAAJ1AAQhAAUEAAIzAAiCEQUIAQIEAAIhAAAKAAGEAAIPAAOEAAJjAAEFAAAPAAIU.EwTXAQ4EAA8ZAAYPBAD///+FAuoDAOAJBOULAuILBRgAABAFAhQEAsEFAQUABgQABA+QC6ALBT8AAh4AAGAAB2UKAAQABBgACcWO.BzUWDwQABUH6+Pj7SEIA3BFS8vL6+APZFwD3BQEo0QAJBlLw8AsGA0DXADQAARz1ALEMN/v7ArkECXgABAwAAOAQFv8JLwU0BQAS.AAMUAAEEAAeoAAgkAAAqAQAJAACiAAPgTAFABQIQEQBFAAJSBgCpBQHiCwfYEgJIAAQPAAAGAAQMAAAyAAM8SAcwAAIAGADxBQJG.EgEUACT9/AR9AuIFCFQAAFANAQkAAOFhAQIHAg0AB4MBCYQAAWAAAA8AAJ2bABEAAgQAANNrBBsAA2wAATYADwQA////pAXcEQAE.AALGAwEGAAW4CwHeAwAMAAC1CwAjDAcMGAEqAAUEAAM1BAoEAAI2AAAKAAsEAAc8AA85AAIBgBwDABIBKF8hAPurQlD7+Pj6/BEL.EfVAlSQAAdkXQwAA8PQABgAbBgX9BQ2gKQCNBgFuQAJwjwEPAAmlAAgwAAKUFwLzAAAMeATvQC8CA7gvAADJAAg4AQGyBQ98XwAB.GAAACQABagUDFQAEABgEDwAAJAACDAAIAAwAfxEBFQAADQAEbAAb/mxaAvoFAQQAAJMAAAgAAJ0RAmAAAAgHNPz+AjxIADnSB1Rg.BSQAABIABGAAAgQAABIAAAgAA8wGAgQABfwADwQA////rQUmBAIEAABlBAi4RwcEAAIFBAMeBgf8Aw8MGAsDBAAHyAQIWF8IZC8I.BAAm9fSpHRLufF8Q8esRBZQ1Qff19QFCYBL3EgwBnAAAxRwi/P0EjwAVAAEEAAFqFwAJABH4jgUACgAABAAHDAABhAACFhEC+BAR.+vZmBCMGIAD9aQAAEgABDgAxAP75BwABBAAF/AxH/fr6ADgBCbgvIPr2BgABBAAIZBcDygACBAAX/iQAAIkAAAkAAq8FAwoAAAQA.BjgBBUgAC2xgFwDMHgUEAAEUAQAJAAIEABH+/DAACgA0AAD2xBcABAABRAED4AECDAAACgAJBAAP3Bf///+bDwQADgX6BQUJAA4E.AAkbAAATBAAIAAIEAAYbAA0JBAIbAAIGAAAQAEAAAAYCTUECDGYKnwUGBAAX7Z0jJvf1rCkR821fAgAGAgQ1BLsvA4UGQ/j7+wIL.AAAEAAIWEQAKAAAEAAMMAAFVNQN5AACZAAbHBAXHHFcA/f36/eEKAfcFAAkAAgQAAdZfAAkAFQAJAAS4CwUEAAYkAAHlAAJ7BgAK.AAETAACgESMAA8GhAcUXAiEAAAsAARMAAroACPQLAjISAicAEAPndwOcBgW0AAIEAAIhAAVIAAIIBwMKAAEEAAUhAAIkAAACAQEO.AAFMAAQEAAFUAA+GEwUPFgADDwQA////rAUFBAB0CgFYBQINAAgCBAgkAAjQFxcCOBACCQoJKgAB3RACCQACBAAD+gUEBAAEwQUG.AGBl8vHwCQsOAwYw9/b0BwABBAAR9fQLIPDx6xEUCMg0AHBxB6wRASsLBYEABlRmCMgiAqIAAgYAAKAvBRMFBNgAADcFAl4FAQQA.EAFkHQMkAAUWADD6/P3KBgALAIQA+vz7AAIF/YcAAjUvA6wXBRgMAHgGAAkAAQwAA18GAZG/A8QvBJoFABkABLcAAEkAAksGFgFI.AB/6bAYHAAkAAeEGBC4AAQQABIoAAwQAAiEAAEsACPwGFgNUHgXgAQUEAAQZAA8EAP///8YGwQUKBAAGEQQEBAAOKgAIEgACMAAC.BgAAEAABBAAAKRwEEgAAVRcBLwADvhEBshECAwYR/HQEEfPcBTb2+PsABgiIRwHQKQAKACcAALU1MAAABdwdEfh/BTIFAAJ5XwAa.AAUJAAAEAAAeAAAIAAAhBgIIAAEEAAQ8kANvYAYEAAB8BQBOBjP7/QOgBQAhABL95QYARQAAk1kCDAAAHgABfgAAFAdA+/v9/yQA.AocABQBgACQAAYgFAvRfAgwYAvJwFALFEQGEABID5V8A8ykAFAAABAABtKgDFQAA8QUFgSoA3C8ACAALbAALbGAAxgABIQALJAAA.BwAEBAADFgANBAAPGAAFDwQA////vAhYBQkEAAOXBAAEAA+sFwYBjBADBAAHGAAIVAAIYGAR+EZxAAoAMQAA79AXAgwAIPj0+gUA.CgBGAADv7CQACBgAMQAECAcAAAQACVgXEfgGHgEEABf7JAAFUKYBPAYDCQAABAAW+8wAGPVIAAgMAAcwSAE7NgAJAAhJBQAMAAdU.DAqQAAfEFwcYAAdHADYAAPpgAAT/BQAEABT1/QUBBAAGJAAKqAAHSgAHGAACmgACVxIFoC8A/E4BlKcAgQYBqNgAHwAAGgAJBAAF.QL8PZHH///9HDwQA1DDk4+IHADcAAPhkBSb49rAEEfhtUwAKAEMAAPX4mAQA1AoX+OwEEPYYDAAKAEAAAAYFEBECDAAAW5UEu0El.BgZ+EQkEABT1IQAA7wQHvDowBgkLWgAB+kcjCwjiBFD19fUCBxgAAA0ABAQAAloMIAgKAAwR9YvdCPAGRQMGCferAAegZRABGAAB.LQBAAAAJBLQAEvfSEgGOBQAJAAAsNwIIAAEEAAFmHgAJAAAjEwIIAAAEABf6bAAXADA2CAwYAHhIBScGBQgAIv39tR4DVBIEBAAA.xRMD2wUABAAJHAAHBAAPGAAFDwQA////1DDq6eoHAAIEAAgsBAVlBABlFgPdBAEYAAMJAAAMAAFEKDDl5eUQAAcweBf46Bcn9/UA.BgU9BQBMCwA8AAIMAAWVFgAMBhb5GAAgBgfUBAAKAEAAAPL2doMCDAAjCQcABmD19PILCAkKAAKpawd8jxf6eCom/vB4ACb18pwA.IwX8gRIADQAENAsAaQYW94QACAAGJv32bAwFbWUA2AAI5AYHOAEI1GoJuBcHfBcIPDwI6AUJtBgHGAAA0wUACAABBAAEVAAAtDAA.CAADBAAIJAAIoCkGTgEPBAD////6MNTS1AcAAgQAB2gECvQRCOAEAAYAAgQACOgRGADoEQE0dwAKADgAAPfoEQgwAA8EAAUHhAAJ.YAAH3BEm8+8YACf18JQFBwQABiIAAMAAAwgAAQQABpwAEQDEjwEKAAkEAAciAArwEgdUEggYAAcWAA8wABIIBAAHIgALJAAGAAYK.GAAPBAD/////PzDWz84HAAEEAAqMBAYOAAngFgeUBQfzBScAADAGCByDCgQACDEADwQABA88AAYPBAADCVIADzwABgkmAA8EAAMP.PAAGDwQACQLwHgXU1gAVDAUcdxX+Y0cBBAAPIDEECvQLDwQAKATEFwLcKQMKAA8EABMGNg0PBAD////iMNrg3wcAAQQAAMwEAAgA.AQQAB6QQCEQQEvt2Ow8EAAsWBqwLCgQABlQADwQABgdsAA8EAAUA8iME1jsR/QAkABYABBAjDwQAAQ94AAMC+HwACgAPBAAsAYoA.AAkAAAQABwwAB18AAvQjBQQABVMBCCMGDwQA/////2UR7dqIAAoADwQAEw/aBQUIBAAD4ikPBABSAgYGAAoADwQAByoFBH0FDwQA.YQXxBQ8EAP////////////+GBz4RDwQAEg9KEQMKBAAPVAAdDwQAHQiEAA9sABIP6BEECEgADwQATR8DAAz/////////////jg8E.AP///////////////////////////////////////////////xEA`.split(`.`).join(``),Bn=`LwUAAQCHEAEFAAcEABD/BQAPBAAcDEQAVwAAAQABFQAQ9wUADwQA///////////////////2EAMFAA8EADgQ/QUADwQA//////+d.EAgFAAMEABD4BQAPBAD/3RApBQADBAAAAAIEBAAAEAAPHBcVBDAADwQACQ8kABEEPAgACAATBwgAABAADwQA/0oQJgUAgwAAAP4A.AAD6/AEABAAAfAEACAAAFAAADAAb+5ABCAwAACgAAAgAAAQABBgAAFAAAAgAAAQAABQABGgKAAwAAAgAAAQABAwAAAgAAJMZAAgA.ABAADwQA/1oQJwUAB+ABAMwBAAQAAPgBAAgAE/QcABP1CAAEhBsADAAACAAABAAAKAAACAAABAAAOAAACAAIIAAAFAAQBgkAA2QC.AQsAFgEMAAQsAAMkABT6LAIPBAD/UgQAAhP53AEACAAA0AET9gwEF+8IAACoAQAkAgAwAAAUAAAIAAAEAAgMAAQ0BggUAAjQAQUM.AADxAwAIAAN8BAALAAQcAAcQAARvAA8EAP9LANgBAAgAAJMBAHgH8gMCAAAACvsAAA37AAALAPcAAPUoCjDwAAAOAAEQAgAQAAIa.AnMAAAr+AAD9RQCQC/4AAPwA+wALDQAhAP0YAFANAPsAAiQAYAAAAAIA/mgENPsF/CwAkAAABfsAAAQA/BgAADYAIgX9LAAQ+4gA.EwIfAgCYAgAIAAgEAAQwAg8EAP8uQAMAAP1sARH/AgTAAAAG/QAA/QUAAP8G9AVACwD3C5ABEPKQAwEQBhH4CgIAOgAQCKgBAAkA.ATAAAQ0AAEkAIQAFTAJx/QADAAMG+tgFAGEA0wIAAPsDAAEAAgABBvp5IgAcAAAIAAA3AKEEAAD5BwD5AAT8/AMAkgYiAgObAAEg.AgAoAAQIAA8EAP82AF0BAKwBAAwAQP8AAP0MACH/A4ABAZ8HUwsAAPUNpAVACQAAALcBAPYDAO8DQP0AAPgQAAAcAAAsACD+AwEC.EQDwAQDDAwCgAxH9DgARBuwHcAP6AAX+/QMAAhD6FgAR+2gAYPoAAAcAABgAIAP6CgARB0cCQAMA+gZYAEAEAAT8lABC/v0EAC4E.BAgAAHIADwQA/zAA/AMCawcAAAgBswEEXgEAowEAEgQSC3wFEA4FAAEAAgAcCAAVBjD7APcHBhD6PgASA+IBASQAEgPbCQBMABH9.RQAC1AkBCwIw+AMBVAAAFwAAFAABLgIA4AEQ+C4AABYAAGQGAAwAQQAGAPjsAQIFAABkAAAIABEDHgIAEwADpgAPBAD/LQCDAwDM.AwD8BSEC/nkBMAAB/QwCAgQAAJwBABQIACQAAAYE8AAR+wD8CPsN+/UADvQG8AgYChAGHAAA3QEE3AcA1QEA8AdA+gD+AwgARAL+.AAYRAvEECwD+APwA/AAF/QAIAf4AAPkA/hQIAFgCAPgHAPAHAJQCAOIBQAwAAPxQAAAUAAA4AED5AAL+sAQAZwQAlAIACgIBsQAD.XAADCwAPBAD/HwBwAQFYAwBdAQB1BRID/AEAYAEACAADJADwAgD9AAIA/wUABf8IAPgCAAANIACQAgAA7QwA9AAIFQZQAAIAAvvb.AUEA/gMD/gcCUQQSAkAAAGQAAAAIMfwABRAAAFwCAAgAAAQAABwIANwHQAQA/AKUAgAcAAA7ACAE+XMEUP0CBPwCCQQQ/AgAAD0A.AiwABKsEDwQA/ygSAe8HIAD/VQEA5wkQAiIrIgD9rAEBEAgw/wH/wAEBEAAEcQETCKsFAJ0BAQgAIPkIPQACOAoALwIxA/0DNAgB.NQACUAAA1wEAGwBBAAYAATQGMAED/dQBAAsAAegBAGwCAC8AQP8AAPzkA2ADAP0D/QckBBEDJAABUAAAGQQARgAz/QQAPwADkwAP.BAD/JwBrAxADfAED8wEAFAARAxACARAAMAD9/yIAAgsAA8oJACMA8AMAAAARAAAJAOwT+wAO8gr3APi0AQAgAAFFABADPAwANQAQ./agBIwP++gMAsQEhA/ljDADGASEA+8MBEQMEChD4LwAgAANoEhEECwAAQgQgAPoiABL8EAAABgAC9QEBPQgBaQAADwAPAwL/KDEF.AP3sBRABrgMQA+IHAe0BEAD0AwEZBBAAvwEA6gUAJgBRAwD/AAbmBwArBvAD//8AAAr9GP72APgJ+BHxCwDtOwAAuAkAqAECLAwQ./VQIAEgAAVQIIAQAzAcR/A4CABQEAt0NAGwEAIAAABwAAJAAcQoA/gD6AP4lAgBYCKL6AAADBP0AAA38WQoANAAAHAAAswYQBrMA.IwAEihACBAAAbwAACAAPBAD/FADUAQDgAREC0AEAuAUA6gEA+QUAlAEAIgAA/gUCCgYCDgACEAARACkGcf8DAwAIAPYYEgCYAyH7.8iwSACAIIP4F8A8AFQQR/jIAAFgKACMOAg4IMP0AA+AFAKwBAHQAQAH9AgDsDwAMAAAWAgToBwCaABAE8Q0AcwBRBAAA/f0MBgGa.BABdCAA0AAEYBg8EAP8lAHwDAXQBAE0DAPsDAPwJFP17AQMUAgAMAAARAAAgAAIqCAGAARD/nQEARQAgAAr0AVAA9RMA7SYOAAMC.EP3FARIA8A8AIwAABwQQ/rsBEAPsExD9BQABeAAAVwAAwgUAgwAByAEQA1cCRAEA/ASEAAAIACD9BAwAAAQAAGQCQAQA/AMUAgEQ.ABL8aAgANBIAFAoAQwAPBAD/HBADAQoB8gEFRgcAWQEAEQAAgAEC9wMBEgABBQAA9QMBHAABMwAEEAoBDQgAIBIAoAExAwD3zw8B.FBAANQAAZQIB7gcBDAgBCgAiAAFuCAINAAEFAAJRAABOAAb8AQBHAAUjABABFwoB5QESBCQIMAD8AzwCAIAOAHgAAhMAACsADwQA./xgAdAcAqw0ARAMRBaQHIAAAmA8AcgER/vUFACYAABgAABIAAL8BAJcBACIGADgGAKwDAkAIALABYQoA/BQACBQUIQnvtAFQBgD9.APsICHAF+wD9AAH+/BMBRwoAtAMQA3wAAcgHEQEMCAHxAQBuAAB4BgDkBwAEAABUAhP6KAAT+jMCAGwAAKwAAPABAEQAACgAIQQG.igIQ/ggIAMwAAA0AABgAAAgADwQA/w0AeQcBjwMAXQEB1AUAVQEAGgAC5AEABQIQ/6QRARMAAKYHEQDEEwEOAACcAwE0ALAAAAP/.AAQE/gj4CDASQv8AAPAUEBEF8AEA7AUBPwYRAg0OADkCAQwIAPkBcQH9AAME/ADUBQAEAAAmGgDYBwIMAADmARD8pAAw/QT8/gEg./QMABgBNDAAkCAAwEAATBBADIBYw/AACCAYDbwQPBAD/EwYsAQBWAwBmBQKgAwD3BQMcAAAHABABlAEAWAMADQAAKgAAIAAEHQAA.OAIBNQAAEQAhAAgMCAHsATQAAPj5EwMACAAIEAE0ABID8QkgAP5jAADXARAEBBgjAATUDwEMBkMDAP0EPwAANAAgA/7pAQEUDgNE.AmAEAPwE/ARMBAElAgAEAAA9AAAyAABXAAKDAA8EAP8MEAPTBQPgGQBpAQDMBQBcARD8ogMCAAQCbAEEHBoAJQAChwUDYwEBJAAB.sAEBggUBBAARESEAQfkL9QioFQUqACD9AxgAAf4NAQ0KATcAAXwEABQCABcAAQQAEP1MBAD8AwANAAI6AAAEAAL0BwUYAACHAhAE.9AEDEAAALwQgBPoUAgIvEAN2AA8EAP8MEgFUAQAwAQDIASP5BpIRIQj7FAIBqB8RBR0CAykCIQAAkBsDlQEAiAkAKAAQBDgCMQUA./hAAABEA0RH6+xj88g3zDO0AAPf6ExH7MQARAgogABkOEQBwGBH9ZwARAwwAACAAAGUAEQECCCD+BMAHANcHAPwPACQCABAAIgT8.cBgSA7kAACAYAB8AAZ0AMPoAADYOEATUAgAZABMCkQIAWAAACAAPBAD/AgCkEQAIAADAAQCKHTD+AAUIAgG9EVD/+gAF/3QPAHkB.MQAA/qghAXcXADIAALgBANgBAukNEf8PAAHTBQERAGH/Bgb6CgDXEzAA8vIwAAAeAgBuADD9AgIUCgIvAAEwAADuAQAZEgMEBAAC.BjD9A/3wFxD85QEAzQMQ/UAIACAAADAAAIASEAQMChP9/AEAOAAAQAYAnAAw/AAC0AoQ/C0AATAGAHwADwQA/wgQC2EHAdgFAY8B.ATEBAAwCABwAIvkGGAAhA/reBxAD3BcAqQkAHAAAdwEAfAERASAUACgAAJoBBCsGsgAAAvoABv8OAAAMDwAQAAMCEQa/EwCZAUEF.AP4BYQYApwEAywMACAIE5AEQAw8MASkIEADcByH9BPAJARAAAUkEASUCAWoAARQAIAAAGAoAEAIBDAYQBDMCAAQAEPyrAAASAAGA.AA8EAP8HA8kZAOgBAN4lAA8AAgwAArgjAAwAAMUfAXQFAMwHAGUBEATwAQL5AQAwAgD0AQAoAACTAwUQABAGuBkwAA7+FBJSDvIA.A/dgAgA0AgAgAAAhEEAB/QAECRoAUAYADBQAJAoAPgATAQgCAOEHABAAAM4BEwEgDANfAAATAARrAAMMAAELAAIjAAEQAAEJAgIS.BAAaAA8EAP8FAKwLALwBEP7hASEACvADEf67GRMHDAACEAgAXgEAzCcACAAAsAEApBshAQLKCQGFAzD+AP5IEgUQAACdAQAIDlD9.AAAV/EAoEe0QAhAGHCgAtwMgBQFcAAIEKCL9+xgQANgFAEAAACMIAPgjAAwAAIsOAOwPAEAQEgIUCAEMEEAD/QAGPAwRByMGEP33.DQIsCCMAAigQcP0ABvwBA/nJCgCNAAUtAg8EAPsA3AEAiwcEHAEC9AEACgAC5AMAHAAADgAQ/xMCABQoANwDAcgFARcCABsAEADQ.BwBAAAAwAAAHCBAF8CkCKACB/gUA+wQIAAtEJjHzAPNCJgHgAwADHgBBBAAQEEEGAAAB4w8gA/0TAAD8BwAIDgD4BQDgDwANBAC+.AQCAIAAQAAEcBgDYAwQIACAAA/EDAAkCAhAOQPwDAAEsECAEAUcWARgAAakADwQA/wEA5AUASAMA3AcAEAAABAAG9AECBAAEDAAD.5AEQ+tMpABAAE/5ZARH9NAoDhAEAwQEAEAADTBQA8AFQ/wwAAPcIBgM8JgDlAQDYGwNoADL9BQF1DAEwAABlABAD7gUAYAYyBAD9.4w0AoB4S/G4AMAQA/wwGATwGARoCACAIADoAADgqAS0ABAQAUAT8AAT9EA4BDgABIwAPBAD+BKARAHcBANcDAqQJAfsHIAD/HAAC.CwAR+sgBAQACIPoGGCwR/ycAAFsDAT8AAQ0AABEEAMQBAEwAEPlIGgBbAAEaAGAADAwA6xO+ARD9BgYAxBEQAUEAACoAMP0DBGgM.ATYGAEsAEADKEwA8AgLFBQAjAAK/ARAEGgAAEwABDwABCQAAYQAACAARBFYAARgAEQAYAgC2DEAEAAQBcwAGFAIBiwAPBAD8EQaw.BwB9ARD+jCkAvCcQ/RIAUAAA/gEH8AEBDQgBBQIATQEw/v4HjAEBwAMBEAAAGQAAjAcwAAD9/AEA5BcAEwAAmQ0QAfITAWAAAF8A.QBQA+PhGAhHwrB9A/fwABrobAB8CAMsLEv79CUAA/f4ANCgRAwgAAd8BASgMAI8OIAD9cAgB/QVC/gQCAaguAOwNAEgEEQdTHAE3.JAFFAgAUDAQICAA2DED5APwADgIAHAABaQAPBAD0AOghAEQBAwMwEv4QAAAmAQIQAAAkAAAOAAAMAAAAEAAMAADgBwAIAAAsBAGk.CwG0HRD9pAUAowcAAwgCuQEAQwAA/B8A4QEAVDKACvb4CO8RAPJNNjIGAProBxEDsQMCMCgR+ggAAA0KAK8DACAYANELANUBIAf5.6A0AJAgCCAAQBBwmAd0BAFwCEQD9AQAFAAAOAAAXAAQQAAA7DgCwABEEDgYAFAAA0gAPBAD4AMkXA8UBQP0AAALsJQD4IwAQAADx.KQDYEQCMDQEMAAMACgDAKQAIAFD9AAAG/2EBATAEAQgWAFIAACgWBkMAADkaAAgAAYoDYAoK/wAB71QwQAUC+wbsAQAFGhL+xSMA.8iMBSgATAd8XADMAAAgKAEgAQP4HAADcFQAUAALcARAD8AcQA+gDAAAEGQQICAEcABAEUAwBCQCS/AUA/QX7BAX7qBQAJAAPBAD1.AJYBBAgABAQABBAAAHgBADABAfIhAK8TAK0FEQPIDxD6XAMC6C8RBPgBAIQBAzcAEANzDQBHBAIDAgC2BQAZAAHbAWAAABEBAPny.FxD8EBQA7CcCAAQAIgAQBE8AACgoMP0AA/UTAPAfABcGADgoABg0ABQCAIwCQP79AAQjCgEIAgAEAAWxAAcICAAEAABVCgCtDgEM.ABAFfQYB5g4PBAD5IQL/OhMApgUCRQES/X4XAAwAACAAEP0wVwD9BQDQCQEQNgGsAwB3DzQA/v4IAAIEAhD/TCgADAYB/AsR//Af.IP798DUAXjAwAAMCRQSR/QER9QIBBfgBLSgALS4Q/mMKAEACUP4ACf39OSSgAgH+Af0A/gIABsMDAAgAQAD/AAceAgBjCgHIByAA.AbgAARAQAGsIAIEGAKcUAaoCEAX4CxAAHBZAAf0HARAQQPsACPyOAkEABfv8TwgBUAgBgQAPBADtAssfAKYFAA4AAPcBAAcGAeUB.BxEAAaQxAg4AAQgcEP9UBwAVAAQIAABIDADAFQAEAgCFARD/JgAANQAAOAIDVAIBIADAAwEACwv2AAvuEwD2NSgAMAIhAf0hMgED.CAG/AxD93wkAYBQB8QcAAAgCfAAAQCQRBAgGEAQgGAAUMAD0HwDfCxIB4wsABAABCQAASAAARQRgAAUA/vwFVQAAqwIABAQx/AYB.JgQPBADyIQL+hy8BxAEC/AkG8QEDEAAAgwEBFAIQ/vwnApwdEf1JAQEQDhEFACIAFA4AzRcApgEArBsARgAAwAkAzAcAQQABXwoA.vQXB/QAD/gALAAoBAO0IGxwg/QMoBAAEBAAQOAT5BwG5EQEsKAEPAADBBQIJAABEAAAJDgDkAQQEAADoBQDpBwIEAAC0AAIUBDAE.AfzAHAAkAAAHCAAUAEIFAfsFTgoAIQAPBADwAqQDABsBAPwJAOsHAIYDChAAAHkBABIAADsFAIABAbwrALoXAegZAB4AAQgAALsB.AQAEATggAOUTAg0AARQAA0gAIP8DXjawAAv/FesT9An3APfwBzABAP04MAC+AQAkAAEiABMAvg8ACAAD0B8ACAQAKCQAoQBBAAH9.BAgIQQD9BP8HAgEsIgAvDAK1AgAABAQoAgBHAgIIAADfDlD7B/oAB3AGAP8ADwQA8ADoDSAD/v07AM8DAc4BDRAAAJELAMIDABgG.EAPdCxD+DAIA8hcAmAsARgABCABQ/gMB+gIaAAGkGwNAKABGBAA0MAEMAADDD+AAAAH9/wIS/A3wCfAI73YQMPsD/WIEAGYQQP0A.AAEUBgB9AAAEBAAIABAACBQBIyABJkAAFwAAZQAQAk0AEPqaBCAEADEGACwYADQIEP1ANKEAAQAF/AUA+AH7pQgCHxAAtC4gAQSs.BACKFgBEAAC7AA8EAPIA7AMASwEEGQMMEAAA0QEAmAMCvyEBFwIB2AMB3gEUACguADRAEPojBAEcAAAIBABBCgBHBAHZBQANChD/.nwOhAwL8BQX2EPAQ/1tEMAUA+TUAADQAAwgAAPADAH0AAMkTBAgAAtcDAEg0AEUGMAQA/e4hMQYA+hAQEf30DQDMAhEC7AEATAAh.BP0EAgAZAAA6AAACAgIZBg8CBvcAXAEBCAALCAgIGAgAIAABDAAAmQEBEQABxAEBBAIg/QEFBAD8EQGWBQBlBSAG/+gJEv2oAQJA.BgQmIADgGTACAP4EBkAGAPoSWEZREe8R+/tKAACnEwCvFwH2BwDgNQAjKCD+BC4EUAIA/wT8KCAAIAABeAAAMQAA7QVQB/kABvvc.BQBoAADsFwEsBgBsAADyEQEzFgEUGgISAEMABAAEFiQQB2xCANEOAA0ADwQA6QDQAQPoAQBEAQT4BwcQAAHyAwHAAQMSAAA5BQCo.AwHmBSD9ASUIAC0EAHoBAG4NASYAAAQAAAAEIAD9EBACtAEA2wMA/AEBLCwA8gkAAgIwAADwRAwACAgA1wMiAAQ4AiEAAPABALcB.AREEAAQGAEQqASAAAeENAfMrAMkDACgqIgMB8CEA7AEAmggBDwwC7QMASx4ACAAASghQ+wT9AAb7AwH/AQF2DAIbAA8EAOkA6wEA.6AEApQEH+AcATAUC9gEA9gcBwAEAmRMB4xUAFwYBCAgQ/4ktMAAA/50HALgJIP4AIBgQ/CQMAJAPASICAVIAAVMAAckBAD4CAVYA.AApAcAgAEfj6C+9QAABJBAArABD+JCgA3AMA0RPwA/39AP4J/QD+/vwA/gYA/gT9/CsAQAQA/P5cJiD8A8wBAGYwAOwXUQYG/AD6.AAQAGB4ANhIAHx4AEiIAIQQAcgCAAQD/BQICAwEmAABSEiH6AMAOABsADwQA6gMCAgAEAAD9BQCbKQAMAAAvCQG4AQCSIQMRAAHd.AwIvBAEPACAAARIAEAEiAAC0BwA7BCEF+5wRABgAAS0AAPgPAwcIAAcGEAMcEAA8IgDoBQDzCQC8CSPy9nUAIAP9wCcA+EcBDC4B.NwhwA/0C/gT8AjAYQP0E/AKgMgFdABD9BAgA+AcApwIAXAZBBAD+/CAEEANLAADyBQT6ATAEAftoSgOMBBEGFgAgB/kKEADWGAAU.AA8EAOsI0AEABgAIEAAAxQEGEAAA0gMAFgQUAigIADcEAL4LAcADAfgJEAXoSQDUIQClAQIFFgBEAAE3MgAABgAEAAHPCwBIAFAK.AAzvERQYEPZVAgAsAgEwAAD5AQAIAAHwMQE7AgF5AAAPAiAB/AkEAEUeAOoJAPMPIPwDAAYAXQIA7AkSAw8kAAsAAAUmAgwAIP0F.iTQBDAAjBgH4BwIFCg8BAvMAfQEBBQYF9wcB8gEC+AEAEgADCgAAGwACIgAgAv7QAQMXAAC5BQAIAAAuBAHoSQCmSQGpDQEaAADb.EwA6AAAzAiAD/xICEAJPDgAoEEIACvoRSk4AIygQ/vQBAAAYBAgAAXgGANABAO8HATo+EP0BHAQMMgBEBAAEAAEmQAIsAAE6CAHi.AQAVGhD8BwIAFwAg/AUfCgEBAgA1CAIIABEBliYACwAPBADkADIBALQBAMUBAYAFAd4HAbo5BRICACgAAL0BASAAAYQJAs8LAHAP.IQD/rw8A5QMA7Q9D/wH/A9wrALwrQQD+BfpRAFD9BgD9A2gkADMCAKABAFAAAwMo4AAEAf0Q/AUABAzyAAD8JzABJEog/QPgDwDn.AQDgCRD+TCAABAoAPgxlAAMA+QH+FDxAB/0A/CoYIQf8ZhQg/gf8CQGSBAAvCBAA/hUw+wn8JEBR/AAI/QLdAAHVSgH+ASQH+QwY.DwgE7gLxAQAKAAHgAQTeBQAEAAEQAAMgAAEWAAEDBAMFBgAVAAITAhQBLUYAwgEAxDcQ/+gfAacBEAPCAQGWAQBLAAAvAAAgFgFL.AKD+AwP8DwAA8A7yVxYBhwEBzgcAFCgB6EUA5AcRAgQGAOwPAQgAIP0COx4CDDgA8QUAOQYQBBg+AA0QATkAAPkDACccAEgUEAX9.BwAcDCAABY5KIQH5AQwBJQQACgABCAAPBADxA+IBAJUBAYAFCRAAAA0EAQ8AAQECAxIAAdUHAM4BBCMAABAKALAHAOUFAHwLALAz.AM4BASQAASMAASMCADUOEAMWCgANAGAA/Q8A8Q/YATH0+gCzFwPLBRD8NQABWQAA6QEAXwAExQUACQIAGAAB6A8wAwAEbxYDAAoA.KgYACAABQhYALQAARQQAsBgBCAAACgIBTRwQB/oBAQMIAqk6DwQA4gCMAQAIAAUEAALcAQAEAABHNQkDBAHKBwAKABAAyh0AEgAA.kQEA7AUAxAEADAAAAwQBIQAQAwQSAIoNABAQALsBAcQBAQQAQQH9AAEzEAEcDgOPHZADAAAP8Q7yD/EIGAERAAFkGADkFwD8AwA0.GiH9BBwIAPAXAFEAAQA2AfADAuAPAAQAAH8ABQgAACcIAFsgABEAIAAECwIBUgIAHAAAYQBABgD6BhsWAAcOA75MDwQA4gK/AwFv.AwAJAAKOTwCaAQAdAAArBwYQABD+4QsDtAcAEAAAjh0A3QcA8QcA0QEAJwAAyBcBUgADxBcAEBAAnAkAJh4RAsgBIP4BDh4AMgIA.UAIAFg4QAjAA8AIAAA/4CfcG7gnvAAUA+AACAhs8AMwBAEQEAGoAAXIAAm8AAOc3EgIYAADTAQAIADAEAQTzNzD8BvzCOEEA/Af8.kCwAkxwB+wEg/PxbBgDAIFAGAwYBARcwgAb6AQD5BQD7AwQQCIEKALBGAGAADwQA3A8DBAgCBAAFEAACLAICEQIAEAAAFwIA9wMD.NBYBEwAAYAMEDQAD4AUAuA8A2AMgAwC8BRADGAIQAWFKALMHEP8kGgNSAAAwOIAS7hHvAAAI+OgvEf7pCwAaAAAKDADQAwDpBwD4.B0AE/AT+DAAAWgAAJgABlQoAdRAB8BsAOBAACAAAEBQACDAQ/gMEAIkwADgGAE8AEQATGgCZBmAH+gAF+wgEDAIDBA8MDvMDkAEA.BAAAzwEDEwQAGAIJFBgBBAAA1AUAMwIE9AEB6QUA1AUAJBgA4A0AyQUAFgQAAgww/QT+lBUBnhEABAYATQADUgABPAARCgQCUfj4.AAgC7kEB7xcA6w0gAwLoRwATAEAE/AL/4QdQA/0D/gTwKxACAQICigIAKQxBAPwE+g0QMP0E/PoDAdIBAEcAIAAFFAIAZgAgBgEU.AAALHnEA+gcA+QX8EA4CAQIPBADlBb8BAgQABfMDAUwHAOABAA0AABYABxAAAHMBAfQFABIAANEDAQgABBEACOABEQMgIAC/AQBe.EAAANAAkKAC1AQAMEBABEwgBWwRhAAr3Eu4SIi5AA/0E+zwAAOgJAOEHAMQDAeQPAMQFAoUoABYcUAEA/AL/GAABLBAApwYEKQAC.CAAwAf0F3gMBCwoAEAAC+gEF+BcACyAAAgpwBwEA+AgAAZEkABcADwQA1wBRBwB6AQDQAQQQAAAIAABRBQAIAAGKOQAJAAHzAwAe.AAAUCAAoAAAQAACUBwCXBwAQAAEhAACBAQDuDQAMEAAWGAA6AADcHxADjzUAlgFQAf0A/QQEBBT/OAoCagAQAXkssAAAAAn5D/wH.6w3tHAIQ/TIOARBSAOwPAHgAAJleAGcUAOIfApRGAIIAEP1CAAAhHgH4BwB4FLAA/gf8AQAD/AH9B80wcPwA/Qf9AwAEMBAJsU4g.AAD5FQCBAAEKFAj4BwDULgAIAA8EAO8B4wMACQAD2gMGEAAA0gMDAwQADwAC4wMJEQABEgACDBAADwAxA/0BaBkAsCEAZAIA0RsB.PQQBAgICJAQECwBwBwf58xXsExwoBv4HAf8XAeg9ADsAEAIFAAEIDkACAAL8CAgCKAAAEwAAJQAAJBgAEQ4Q/BUOQAT8A/w5AAIP.BBD8o0gALAAB/A0CCCgQB900EfwEDBAJAQQFHQQPBADsAlUBAAQAAsgBBhAAAN4BCfABAc0BAAkABQQAAhIAAjkAAswDAPAtAARI.MP0D/88JEf8EHgFcAgDVFRACFg4CAwJQBwjrFOwcKAf/CRACAwYBBAAwAAAD+REAzQEB5xcgBPwICAIUGgEMEAAsJAATDgIdAAQE.ACAF/CwaAIIEAPcJAfodUAcAAAf6+gchBwH7BwAHChAJewYADQAPBAD7ANQRAPgdAWUBAJEBALsNAwwAAgQAAOIBAAgAAdABAfwB.ASUCAdYDABwAAFUDAKwFAAAIEP9aEgDEDwAoAAExAAALEAEvAAEBAkEAFesUVFYS/RIwAL8DAPMJEP/wGwD5AQDWDQCGAADwEQAU.FgAJAgIZKAD5AQAwAgD+LQASBpEEBQD8BP4A+wT2EQARDAJiAAEBAg0AEAAGDgAEAAAMAA8EANQA0gEArgsADAAABAAEHwEA6gcB.aw8AsAUACQAQ/8YBA48DABAAAM0BAyAAAAsAAKIPADQAAPwXAAwQEP+yIwDxJwDhDyEAA7EbABwYABkeMAL8AKAVEAQ8IAMCBAEi.JgCIAAGAAJH9E/sJBPEABPTUPwDnCRAA+B8BtQ0AeiwAcQAQ/uMBMAAA+jsCAKoSABAWEAMnAED8AAgACCAAsAKxBP37AfwABwAD.APhTPBAEa0BB+g0C+1gCIfr65CQAAAYBqEoT+wkCAJQeACAAAIsADwQA7ABjCQAIAAKnAQDnCQHyAQWrAwIRAgIEAAHxAwcxAAH2.BQEBBAAPAACeAwATDAAUAhAGoiMALwAABAACARQAvwMABAYAOhZBAAP+BQgOAG5oIAT8BxoAwwUCBAYAMwAACAAABAAADAAATAYA.fQIBICAAZQACBAYAABYAaiYANhAAPQAABABQBQD8A//BWgHGXAH9DRD6MgAAAQIACAYAiAATAAQCAwwADwQA7wXiAQIEBgb2BxAB.xwcPCxAGAicAAKEBBQcKANhHMAD/AxAmEQYhIDD/AP0MHgJMAgTQAQENAKAD/QAPAPEADAD0+AUR/skBAAgaAPw/AO0DQAQA/f7r.BQAcFgMBAgDlEQD5EQD8GwBMAAD8KTD7BPwABgAYCkAFAfsEGgIwAAX/VAQAkAAACQhRB//5A/3/DwAEAACADBP3BgoBIgAPBADr.AY8BA/EBAgYAABIAAgoAACAqARMGAyAAABoAA8EBDwECAgAJAAAiAgCGBQEUGBD/sA8AuQEANQIAAwQAMB4BJgAADQAAEBgBrQkR.9BMAEAD0EQJOAADcAQAIAAB8AADXEQHiIQH5ARAEKAgABwIAEgABLQAQBUQQADEAAAQAAP45ADsaAAECA+8NAPQBoAf5A/4AB/kI.+AiiDAL9AQAEAAAgAA8EANAAtAcACAABrgEDBAAAswcAswMR/+EfA8oBAQwAAvMDDxAAAgGDFQGiBQEUBADcBwCnBwHeAQBRKhEC.MwAAOAow/wL+tS0Q/ggWADs0EAM0CAAzAgEBLAHvAQAEACD9CQMYQALyAwCyKwAsFiD9ADkIAPdHAUkYEAP4FwAUSAAIACADAQ0C.MP0AAi4UAGgWABgeABwKEAEdChEAPSxw/AAA/Aj/AwA0oAAC+QD5DgEGAvOLCAArMJAAAAAO+AAA//0DDC8J9wQI7ACPAQAIAAEE.AADQAQAIAADLAwAIAAgQAAEBAgUQAADiAwDBAQIDBAESAACoAyABAAMEAA4AAOIBAywoAAUAIP0DJSoADxIB9wUAIgAAUQABDQBw.AwAP8Q8ACTpOASwMAEoCAOIDIf0C0wEAzAsD/A8ABxYgA/4kEAJSIAAbAAIVFjAAAAUMSABOXgATFgAcBhAFVgQA+yMQ+QAOAfMJ.MgcC+AIKAPgDAYAAMAAJAalGAJAADwQA7AIPAQLjAwD0BQwQAAECBAAKAAARAAEEAAMRAADDAQAPAADyAQApAgUQAFEEAP/9AuIB.AHwEAfk1ATMAABIAACAAAg0AADwGAAECQO0QAPK6BQAtYBABOxQA8xcBFQgA3C8AAF4g/AIcMAEsEAAJAgCMAABNCgL7KwILBgEF.AAAWAmIA/AQF/wWKAAD9BUAAB/r5r1gA8wkABAACAQIBAw4fCgEC9QB4AwBVAQHWAQAfAQAWAAUBAgPyAwEQAAEFAAQiAAHiAQEJ.AAMRAAYQAAERAAGsAQCYAQMwMgCOFQBvAAHOCQEmABAAFCBgD/EQAPYFChgANQAB6AcAHEADJgAC4wEBPUoQAu8dAPoLARAYAQ0Q.ABwAAfQJABAYAixUEgQGHgH/D0AHBgL5AxIAJwCwCPQAAAgB+QAJ/vg6AAAIAg8BAtsAjAMAvwEAfQkAqQEECAAAygkAIAAC4wUA.+gURBOMrAuwBABAAAIgXABEQABACAQQIAEEBAAQIAfEBAAQIAO8RAAMGADIAABY0AMcPAQwQAMwhABUAALMTAAgAAEcAAdsZADwk.AOABkAAP9Bb0/gTyBd0BAEAMEAP/LwA2CgABAgF6AgElGAEsABAEWxgAuABQ/QD+BAHwIwAgABAEW2wAEDAAMCAAEQBAAAb+AVII.MQAA+pwoAAESEfguAABFAACVYGAA/QAJ+ACLHACsQgAWAA8EAPAC8QEABAAD+Q0HEAAABgAGIAADAgQAHAIAAgIAEwAAEQABBwwA.DQABwhMAIQIAHAIAgRkAABYBmgEDHgACQQAAPB4CQFYQBgQIARwEAvAHAB8AADQAAAQCIAADEAgAMAAATAQECAACjQAADgQACQAA.PwgAXwACFwYB+A0gBP2RFDAHAPsyACAI+vwFIQX7+g8A+wMhA/4HDA8CBNsPBAANAIApEv/zBQFHAQDgAQIDBgLkEQAKAAIQAACq.AQAyAAQbAgC7AQD/YwYPABAAMUQgAgEZBAEACAAYJgCiAQEcAAAEAAAbSAMvABAMVAQQ8icAAO4FAAkaEAI4AADPBwHQAQEOBCAD.ASYUAlowAOsdAlMkAPIFAHJSEPsUAgB3AgP5HxAHBwAAAQIwAAf2jCBQB/kIAfh4KKII+Aj4CfcJ9wP9AQIPCRD0BQQAIQH/uAMF.nwUA9AUAEQIBqgEC+wECBgAEIAABGQAALgIAqgEA4wcJEAAAxCEA/z0ADwwA1AEDTQQAGwABIAAADQBQAAAM8hCsBSAG+twbAOcB.ABRIAN8JAAcMAEoAEP4tAAAwAAQEAAIcAgDxAQBrBgBhfgEKAjAFAPxLVkAABgICiFIQBgUOIAf5sQAhB/kADAC7bGMI+An+CfgC.BAAEAADHAA8EANMABAgACAAAwgEAqAEATAcACAAAFAAAHAAA5FcA8gEA5R8A0i0C7gcAGgACLA8DEgQALwAB/wEAIxABRAAApS8g.AAMUIBH//CcAygcBEAAAAgYR/foBEAIQMgCuAQBxAAEAMAAMAgIIAHEQ9g0F7gnuTiYAZAAA8xEg+QH2AQHsNQHsAQAoAAAgBAB4.AAAIABH+KgIwAQT6XFQA9AkBaWBABAAHATcwAYJ0AGkIMQLzBAUeUQj5AAj4iFRRAAgA+fekJgD9AQB/aAAlMAHUAA8EAO8ALAMA.CAAAnAEACAAGEAAAxAEE/gUBBAANEQAB8B0C0gMCBAAhA/9LCBADAgQR+iIuAMkBBTIAAO8BAy4AcAoAABTsEu4LAAEACAH1AwFA.EAQLDiEAAAAQBEEAAAgAAoEAAAcWAQkAAAAcAAgAAB0CAAgAAf8FcgX9B/kAB/xnAAACBAJ8LgD+CSED/QAIAAQAASAWABgADwQA.7wBdAQAIAA8BAhYIBAAMEgAB4gEB+QEhAAb9XwHRBQVDACID/jsWADpSYAD6FOwS8rcHARAmAdsFBAECACwAAOcNACAaEAQQJlAC./QAE/mkWAhoAAAYAIAAFADgADAgADAQB/xFwBvoG/AAF+v0ZIQP9+wkAAQIALQAAAggBBAgA/QEABAAPAQL0AMABBZ4BAbwDCPEB.AskBBhAAByQIBA4CAQUAAhEAAA0EAxUAEACQPRAFigsQA/AvActFAT0AASACAmgCYQoE7RTsB6IXACQCABMAAQgABgECAfkXAAcC.AOYLAO0TAk4CBQECMQT8BcUBEAV4QAIBAgDXAYEI+Af5CPoD/gAIAPIFACQAEAkECID3A/4ACvYL9QQAACoAABkADwQA0wDSBwbH.AQIEAACGAQEQGAPhAQAkAAAECALeUQAGEgCiEwBGVgUQAANBNAAeMAJlfALkHwDqJwE1RAT0H8H/Af4E/QEEAAT7AALLJxMBgnAA.6CMALgAAUABwCRL3FO4J7h8AEAUlAEAEAQAD9D8B7gEAVhgAGw4AKQAA9iEANgggAwEqLDEABAEAEAAEJAMBEDEFBQZAIjAHAPkR.AkEIAAfzIyoAEzQB+BcQ+gcKAAQIUv4AAAr1BAABIAQAXwAPBADvA/EBA6wLCAIEDBAAA/YDALMJAg8AAhEAAicAAgQAARAAADoC.E//OBREBpgEAmBEBHwAAHjACLwBSCgAAE+0ECAAPQAIIAAEQFADiAwA7AADwAwH8BQQADgAuGAIIAAAjAAIJAAA4AAL+LwEEBAEP.AEAI+gAHUEIA/x0R+XMiAAoAAvwNIgv1BAAPAQL/KggSAAIRAAYEAAIQAAD9BwCPCwEIEADIMQFLAAC6BQAEBgJBAnAKAPgT7RLw.uwEHAQIB6BkAKQAADgAACAAAUQAACAAAIAAgBP7VDwH4AQABDiIF+wUKIQf8/QkA/SUBEAAB3gVSAv4ACPr/HQAUACMK9goAAP0B.AAQADwEC9ABfAQJ9AQAEAAwECAwQAACVAQAIAAIQHAAcAAC5HQASAAAEAAIQAAAFADIAAwMPGAPXExL+TAIAyAEBJQABUgBQCgPs.E+1eRgRWAAMIABEEBAIB3wMCMQADBggBDioAGwAAkEQBEQASBQAQQQAG/AbdAUEG+gf9AxgAACADBQoD9wFCAAr2CR0CAP0BQQv1.C/UeAAARAA8EANIA4AcAdQEBwA8A2wMDCAAPBAgJDBAAAd4PAaMBABUkAOwBAIAHAPQHIQH/hK8ALAAABAhwAQD//wMAA/s/AENY.AD4AAB8AALcZAOMTEwFjGGAJE/YT7PlEgDD+BPnpBRAA3AcB/gEAFQAA9REA5wMANwAAJkCg/QAEAgT6AQP9Bz4AATwqAAAQAEdq.EAf7ERAAg2AQ8xlGQAgACPNFSCYACAQIYPYAABD2AYU4Iwv2AwYAhAAPBADzA+EBABgCABUCB/IDALcDDwIEAwAGAAEEAACERwIn.AAIEAACCFQASPAHDHQDUBQDULwIBBAAfAABLCgMIDmEKAAAQAPEoAAFFLgH0AwIANgAFBABBBAQECAQADhAErBQA9wUABAAAEQAC./xsG/AcQ+INaAQ8AAP8FAOUDYAkC9wAG/fgNEQoPHgH9AQAEAAAwAA8EAPQG4QEBmQEH8QEMEAABQgEKEgACEgIGBAABtQMAOAAA.3EkBCAYAUFABJj4A2wEAQQABMDoAkxsiAwABAgAoAgFSAAEQEAbxFQAFCgAxAAHuHQESAAAYAAD9AQAEAAD+HQIBAiQH+QECAgcA.AAECAQgAAOYFAQQGAQECP/YK9gEC/wAAwAEGzwEM9AcMEAAGAQIA4wEBDAAA8gMAEwAEHgQBvAEjAf+wBxADBQADEwAA4QMDJQAA.PgAwAAr5DBgF5QEARQAADAAA/gEBCAAAEBQA7A0BAggAEgARBQoAAIiCAugDBwESAwYMIAf5DxoA+hkADgAAECQDBgpwCgL2AAr+.CiIaAP0BEAz7lAIjAA8EANQANwcAxwEAjAcA1gMECAAAWgUE5AcAJAAI9AcMEAAAhQUACBAAAQIA6i0g/wOYTzMD/QERIAIYEALk.kwDSSzD6/gQGEADZKwAvABAA3DkCKBABLwCzABLzCAz18gAABAL8BwHwaRH+AAYBPA4iA/36AxAEZBAACgYyAAT3+xcABGAABkAg.BghMPACadoD8AAMC+QAH+502UAgBCPIC+SMA1wgR9yIuAUcAUfUDAAX5BAgQDMAaABkCABgADwQA7wPhAQOnAwDgAwMPAA0QAAas.AwUEAAARAAHQAQMEAACYZQHkBRIE4SEgAwEMBAARAAAeAAEwVAMECBAN3wkATnYAGwQCZAAAEAgAYwAAOgYAMAoAFBIB+gEDBAgS.BX+aAAsAABMEA/4/AQQEAQQAEge0kAAADgAECBAGBAoBIiQAAAgA+wMhB/n+AwAEAABFAA8EAPQEVAEPAQIjASMABgQAAiEAIAH/.3AcQAvwBAONBAHEDAB40A9YhACIAgAAADQD4DwDyaAQALAABRwAHAQIAWwAAbDQBaA4TBIIAAEEoAGAAA0UAEAb2GQD/ARD8CQIg.CPgEAgAYAAD9CQEIAFAAAAkD9wgSAAgGBAECT/UAAAwECPMA3wEAsAEG4QEM9AcMEAAKAQIBDAABBQAADgAAzBsAtgEBEAARAccV.EATEBQEhKARMAgAEAAEgBBAAB44Q7wECAF0AA9EBAh4CBQECAjoAAEoAAfwHAPYZAssPAQU4APhBIf0HyAVBB/kH9vcDAAAQAAkA.AP0JAgIIAgMIsQAJA/YAC/cAAAf7AQoPAgTfAGgDAGoBAK0FAIoBAAgAARAAB+QHACQACPQHABAAAJYLBCgQAIUFAAQIADsQCgAg.AgQIAKYFAuQHEABgIhAGFEoA0gEANAABAQIAQQAgBPwOHABPAHEAEwfz/v/zVAIRAVhmMQAAAxAQAvAFAD8KAP4DASUIAEQYMQQA./F8aAAZmIPcE/wkB+yHwAQD8AAcD+gAB/Aj6AAj6BQEAJiAIAwV7AQECAIIYAU8CAfoBEwACDAARIAEaAg8EAPID4QEAEAIAHQIH.8gMCtwMGEAABrgELEwQAA0IBJwACBAAAExwB5QcA3xVQAwD8AwK1AQAaAAEEAAEBAgAJAAADBEAA8g/xUwAAY1ABUwAAEEgABwQA.QgwAEQAACBAARAIAJQACPgYAFAQAPAgFAAwABgAA7AMAtIgACAAAk5ph+Aj4AAn5/QMABAAAOAAE+gEBLwAPAQTfDwQACwbQAQzx.AQwQAAHECQIJAAQEAAKSAQYEAAIQAAAlOhD++GlB/AAF+ywSABYAAIsLBRAgQwz0DRABAgAAKgATAAMcJgD8AwArAAEhXgAJAAAs.eABRDgBxBAGMAAL+ASEABvo/BAAQAP8jAAgAMgAI+/wDoAkE9gAJAPYABP8HEAASACEAAAQKEQ05ZA8EAO8AiAEAsAEG4QEM9AcA.IgAACAAGBAAAIAAACAAABAAA7QMCEwQADgABygEDBQAhAAEMGBAAEB4CsAcAVAAAGwAAAgQADwYAigE1EQPvAQIAJAAC5AMA9gEC.CAABhwAAAAoADwADBAAABwAAAhIAGwAAAQIAKQAD7gcAAwYACAAAEQICCAAA+AEAAAwBBiQDAQQAAAoPAQLgANAHAFABAKwHAGwD.AAgAARAAD/QHAQANAADdBQAIEAAMAAIfAAGZBwAhAjMCAAEECAD4DwL0BwBQAAAhAAIECBD/IAgA7wEALRgQBERQAVUCACgQAAEC.IP8BEDhQB/wEFfKLAQDsDQKzYAQoHAK4BzAE/ASTZgAAIAEWADEEAgWhmmEFBQUJBAQ3YCIACwAQMAj6A/sHQgAI+gP6DREJCUpB.CgD59kRQUAr4AAALFQKA+QAN+PwADfNDBAGZAg8EAPIAnQEACAABqgkIAQQCBAAMEAAQAN8RAgkAACcCAQAgCSsEAuQFAAQIAOQV.ACoKBlUAAQECAMwDZAMQA/AAAAECAPcrA0MAAAAIAAgYEABTIgFIBABEBAAIAAAeAAIIACAH/dALIAb61w1RAAf6AAjmigAaAAH7.D0IIA/cA/BsBAAQJAgQAKDQAcwAADAAPBAD1BJ0BAwQABg8AAMgBBrwBAAQAAoABDwQACAAhAAAfBADaBRECAAoAtxsCXwQAIAAQ.BBMmAAkAVAAQAAAEiwUAeyYAQyAABxAAAQIR/A8UAAYAADicIAX9FRIAFQYDCAABOXwB4REAPQABBAAgBf0DCBD7cXQhCff+MwAW.AAH6AQB/KAYBAgB9CiL99joGDwQA7QLgAQcEAAIRAAbxAQwQAADWAQIIAAUEAAKRAQIpAAAEAAQQAAHEDyAF+9QJAcAFBCIAABAi.AfUDIAAQ9jcBAQQBLAAA2wEC8iUF/AkAHAABKwAAFAIARQAACAAAGgADBAAgBv0AEgACLAAPBiII+AsIIAAJBQQAIABCCfcACmoU.AAQAAP4JAnMEAFEwABIADwQA2QCBAwBDAQCsBwCLAQAIAAAQAAAYAAGhAQDNBQD0BwsECgDQAQQQAAA0AAEQAAJGGADzBwEkKBMB.5ScAJAgBEAAAg5gA200Aqw0S/Th4AF0GASAAACkAAIIggQEACP31EP335QExAAADFTRAAgD//v4BAPo1AQYGAZhuMQAABHNKAhoI.AEEAEAb4UwAJALEH/AD8B/sAB/oFAAcQEPisAAIECAHTnjAAEfYdUBELGRi/CPwC/AAOAAD0D/IDCP8GAuIDBhAADBUMA+0TADtk.Ag8AAjEAAvQHCBAAADMAEQNbbCP9A7Y1AgQAAB8AAOZBYf8ABvUU7MUFAAMIAItCAQcWBg8gAKUFMAQD/BgwAiAQASAAAG8wABuK.AP0HAfsDIAX7AQIAHmhgCPsACP76oAADAAgFCAYBBAAiDPW+VgGYPAdVFA8EAPAArgEACAAABAAAoQEIEAAABAAIEAAAIAAAECQC.BAQA8QEACBIA4AMJEAAAMwAgA/0DEABfiAEUAgAdAAIgAgC1Q3D9ABTsFADyejQA5AUCTDYgAgHkAQD1IQADBgAADiAF+yBAEAEg.EDD9BP0mFAE5hAH7AQAJGkQH+gX9AxgAAAYwBvr+AAgABggBCBIDAwgA/gUAGAQADABfDvIAD/H9AfcABAAArgEACAAEBAABEAAB.BQADsAEACwACEAAA+EcACAAH8gMBGAAGEAAEBAAA1wkR/2YDATxSASQGAC8AAikAAgECEPusJQDyAwATAAAIAgAIAAIEAAAnNiH8.BPgxAE0aAB0AABgGADcIAv4BAAYUACUEAQUSAAgCADYAAQQAAP4BAf8FJAn6BAoA/A8gCfqNAHIAAA7zAAv1CwAPBADZAOwHAKsB.AIkBAIQBBAgAARwAABkAAPIHAIkFABEAAAQAARAQEP/QAwDAAQHGCwANAgEbAAMDBgDUBwBEAABMRAAQAAAEAAAyAgBuTAAUKFD6.AAQE/PCjAJVwA41AABQQEf8UKFAN9RTv/OAfADMAABYGAPUxAUAyAAA4AAQKEvw9BhAEuwcAhlBh+wUDBAT/+QMg+QczSADJBQL7.KwD9EwBUYABIBAEABgJ7DEAACvkAIVRhDAD2APoFd2BBAA8A8uS2AUcsDwQA7gF9AQAJAAEEAALIAwPsAwASAgsQAAPCBQILAAIE.AAARAAkhAAYMAAAIEADKGwE1AAJbAAdBAGAHAPkRAPAECAEVAAFEAADoAwAhACAE/C8AAAAEARcABCQEAEICBAJGEv0IAgLKBwD6.FwD0AwD+NQD0DwACNiAE/PcNIAr2OyIAMgAkDPRGACAAEAS5AnoADwQA7gBvAQJlAQAEAAB/AwjxAQCHAQgQAAYECgKHAQDxAQEl.CgIpAAAEAABRAAASAAKyCxAFxncE8wEFBAACLgBQEe8AEO0bPgEBIAAcYgHrXTADAvxXbAAiAADyTwEgJAFMCAf/OREHBQBw+QAH.AvwF/P4NAPU/AAYCEv74CSAJ/Y0kAAECAA4AAgAYAAYGAFYIBAECAxoADwQA7QCwAQLhAQAGAAAOAAK+AQASAAS6CQYQAAGsAwDL.BQIZAAAEAAAHBgIVSgAOAAD3AQIIAAAcAgAEAADGKwwECgBoAnAH+BEA7wf5AQIBmQMBAQIAAg4B8QEAEgAEsQMA+wcQBQxcMAAB.Biw4AMWSMP0G/QAUUQAH+QX9AgYiAAkAGgD6DwL3BwH5EQMIFGAADPYACfgsBAEOADAQ8ftCAgALAA8EANcAgAcAyQEAfQEAjQED.CAAA3QERAuaHAPQHABgYAwECBDAAAPEDAEAABABIAAwAAOcLAEQAAAwAAdIBAUx2AVAAABMAACICAD0AMAEBBtULM/8C/w0cARMk.A3RmcQn1Bg35BfFSBAE8JgBsWBD8OnwA7B0AF1wSBFyQAOiIEPtgABAF208QBHWIYvoD+gMH+VY6AABSIPoE/AGwAAAF+AEG/wAK.APpcPhD9/BcgC/UdXAB8JFP1AAUAAg8CIQAFxZIBCwAPBAD6AJkBAAgABAQADBAAAMABAggADwQABgIQAgHCCQFACgEECAD/AQAN.AAACBAGofBD/ocIDigUA9g8AKAIANAAAQC4AEAAAFgIA4QkAYX4AOVoDegIQBlgOAwkAAAcACQQAAAoGAA0OAPgVAgAwABYAIQv1.GQQCARQhCfl0AACqaAAcAA8EAPcE6QEM9xECEAAACgAEBAAB1QEACQAAzAEAKAAHIQABCwABBQAADgAArAcA4hEDBSgBIygCGAAC.BAAQC0gUEfH2AQEhAAAUAAEIAAAADgNFAAHhCQAjAAACUgARAAYEAAAAQAAFBgEABgHkASUI+wQKAgAwIQv1z8QBIgACAQIiCvYB.AgF5Ag8EAPkPAQIFDgQAACAAASkAAAECAKcBAhEABEEABXkDAtQBAIsNIgT+BAQCCAIBHwAFLgAQD6DIABcAAA0ABwgAABSIAAgA.IQAFUHQA/h9CAwAG/vQLAP4HAAAMIAj7EIhgB/kI/AAI9gcA/g8Q/wECAEUAAAQAAAIoAAIuAP0ZRvQADQMVGA8EAOIE1AcDjAcB.lAcAwQkAY0cAkgEAIAACsQkCAQIBEAAABQACNwAA6oEBWg8AEwAGBhACFgwBChgArVcAHAIQAM8XANcPUP0AAvwCOR4DgBUAuQ8B./G0ALgCACw4DA/EN9wByYAD8CwAjABABrkwBKgAAbwgAB1wDDQAQ+wEMQAYEBvYBAhEHGwIBAyIQBbK2IAj4BFgB5wMBko5QCvcK.+wcrShEK6AcAHgQw8wEAjk6xCvgAEADyABLuDPqBEgAzAA8EAOoA+AEACAAEBAAMEAAOBAABwQMACQAPBAAFACMGAOABAbsVAbAT.EAccyAVaACUD/kQOERGgGQAKAAAtAFD/BP0DAgsIAgA+AgwYQAX7AwMCfgNtAhAG+W8ABBAAAEgAEQASAAQwABUIEv4CKBAGAEQg.CvYAEgAhAAACPGD7AA30AACneAASAA8EAP8BFQLJGQIIAAIBBAAEAAwQAALoFwIKAAMEAAKNAwYEAAciAiQD/wECAA4ADAQAUBHv.AA4CoB8AKgIARgAACjIAC3wCAX4AIwABBAAE5yEIBAABAAgA/R8BCAADBB4AAgYD5QsE/xUB+SkhCff9ARAObAABAhAwEvvzOAAA.HAAPBADsAasbAwkAAAcAAwMIAQsAAQQAAgECCAQACCAAAQwAALsBAA0ABAQAARUAALgFArgBAW4TIgT8GDoBBQ4DBAwgABHrLQCV.AQDeBQArAAwEABAETSoACQAB/hcAVwAA/BEACAAC8QEA+xsBCAACCGwwAAn8AgQCB88BNwAABiwRAwQCDAQAAZYAAAkADwQA2gG8.BwDuAQMECADYAwAJgADExwQgAAAQKAPzBwEkCACZjQQBBBABIQACKAAFAwgA2gsC8k8BDwABCgAABlYAlHgAI5ZQ/gT9BAFMlgAZ.AADoRwEgAgABAnL8CfYA/Qj9qKwBo1IATAAABgQACAAALggADxIgA/suThAFF0Bj+wAABv78FwwgBwP+TwAEMALLAQFXAACTABD9./hFQCvYLAAFcAgAbAP8GCfkADgD1AA/xCvsA+wAQAwDwE+0HJlj4CuIFCgQAEQHTCwGaRwAPAANhAQMLAAYEAA8MIAMA6C0ABHYB.0QUBEQAAIAAEBABgBAATAwDvswkA9AEgAfw6HCAABGIGAgYQAVkEALQhAC0AAAASBUoGAPpTAAAiAAwAsAj9BvoJ9wAI//r/9hsR.CQwgMQv1ChYCAPoVAAgABgQAAzAILxPumAYGDwQA4gadAQLIAQIQAAIGAAAEAAYKAALgAQAP0AEpAAAEAACpAQIAKAAOAAIhAAEw.YgEPAAAeAAASAAAMAAEEAAENAAAuAGAE/AARAPMIFgETADAAA/86JgMTMAD/NwEJNgAAFgAGAnEG/gX+B/kCGxgA/SEw/AAH/iNB.AAj4BvgNIgb8/VEhBvtNAAAAEBH7/hcAIwYAEgAzAA/zPAQABAAASwYPAQLxAvABBa4BALsDAAgABhAAAc8BAMcNAfgFARIAAgQA.AzoABusHDQQAANoJANIVAFgOAdwLABUABUwgEAAdTADGHwI0BAMmDgoEAAAMOABeAEAFAAb+tAdDB/kG/tu2AfMHBMQDAAECAAgA.BAQAAP4BAgQKAQIaA/4jAB8CABQAQhPtABPKng8EAN8AwwcBQAEDCAgADAAMFAAECAAArh8ABlAFmgEAKBgBrQESAPFRBCgAABwA.AQoAAQkAAiEAANIHUAIAAv/9xRcQADxIASwQACEAAEcAAD4CYQgDEPz6+5ATAxwAAP8TIP4C8gcCRCIAWwIBLgIhBfoWEgQDRAIA.GAALDgMIACEJ/J5QMAoA+1tgAyO1QAQA/QwSDBAFUBBgDwQA9Abwr0ABcAg/FesCAgj5CQEEAsABDwQABw0gAACjAwAIAAQEAAwh.AAAQAAMkAAAHAAFjUgABAkAAAAr6kg0AGQAIBAAAMAAwAAX7AAoADwAMBAABAwIhAAgGXAAJEgEvACAACCsyAAEYAP5FAPsLEPU+.FAAEJgBSDgA4AA8EAP8LAk0BDwQAAAwUDgYEAALDAQAEAADWAQA6AgAMAAsEAEAD/f8FOXAARAAAMQAAKwABUQAADQBRCwABAO8w.BADqBQAvAAxOBgAYAACgBAAABgCjACIH/goyABwAgAb6/wAI/QAI3WQPAgYAAAcAAAQAMwz/+SYEBGwCAP4FHxUCBuUPBAAODPEB.EAGYCQAJAAUEAAogAA8EAAACIQAAsAEBBAgAzAUBlzUA9AEAGgAFBAAAphcTEBMyABygAP4BEAVMOAH9DwA4AAAkGgABAgC4qhH7.pAIBCKAA+BcJKQIADGgQ+g4iQAAKAPkFDoD2C//4/gT/DCgIAiEAAAEiAY1UDwQA8ACuBwC/AwAIAAAQAAAFDgCeAQBrAQA0iAkY.GBD/mhcA4FcC5A8FwDkBNJABwA8RBFygAXLEARAAACcAAVQI0f4CAAH9/QMD/fwCBvk0MAAXGgE0OABfAFAAFQQE8NFBAAAiABpg.AFcAAdgBAAECAL6+AEccgAEEAAAGBfn+DhZCBgAF9QgYUPoHAAEA/CEgBv4FOBD4kVwQ+ggsIAf9P1jUAAAI/AL0AwAN+P4G8zAI.AVGEgPcAEwHvABXrSLkJHgIPBADkAYkBAJwfAA0ABgQACPYPDwQADgq2BQYEAAAbMgBWGgDZAxYEJhABSGADfAIgEP+vGQAKAAAE.DAL6FwAOAAAEABAFBwQAtQEQBriqBgAYAAUoAO/CAP8TAAAWEwZZAAGA3gAjAAMIAAEACgAJAAAEAAAEDAcAICEV60gIDwQA8ASX.AQ8IAAYABQAHIwoPCBgADAQAAyIEAwQAQAP9B/nWEQUrFAYEABARTKIACQAArgkARgIA/mEAMQgBMAAAGQACBAAA9gUAtQ8CWAAA.EhAABVYADAADBAAEABgA/hkA/A0gC/X8JQAhAhH2ACAAJAAA884CbgYgFOwmAg8BAvUD1Q0G8QENAwgABgAIBAADsQ0GBAAAvAMA.CAAEBAAEQQAACAAABAAACRAAEAADMBABFjwCbwAiEfpjugE0Bg8EAAABBZoACQAFBAAC/U8A2wEAvwUAAwoACAASCQBoIgAKCRIA.KQACBABBDvQADfgHAAEEAAgAAAQAJBTuDgoPBADeANQHAL8BAIAFAIIBAAwAAAQAAuIHBgQABBAAAN0TAMMBADgAAhAAAAYAAewH.ASQIALkBAEgABN0DABAAAggAAF4oEAL8rxACQcYAzykA4S0AQUABBQIBcAJQEfEK9gsbaAAhCgA3ABAEUUgAaMIAAQQALggBFhAB.jAAEABgSBDXQEQBwkgAZAAPAAgJcAgAKAAACVHEI9Az0DAAG8QPCCQAF9gAADwD1ABLuE7FQFgDtGOi2CAI1OA8EAPEG4gUCBAwJ.EAAQ/iMKAAwAAgQAACAAAAgABQQAAHoBDggYAhAAAbB9AMAVAA0ADAQAIAjxjQUDBDgCcwACI0QCCwgAWABgAAEG/wT8+A8QBqLY.AB0AAQgCACwAAfpTEAj0tgACBgAIAAACBiH++UkAAgAIIA3zAx4UCu4FAEoUAAgADwQA/wACfgEGBAAPEAANCggYAQQ4BhAABgQA.ANVhAbYJAA0ABCEAAtgBAIYHQRXrABIGEABEBhAC8Q0AIAAHBAAA7gdABv4E/wAYMgf5BQpEAQMGMgX7BvUNMgAF/AgAAhsAAgQA.IAz2/hUAZyQADgABBABVEe8AEvFFKiAY6AYADwQA8QCuAwAIAAAEAALmAQYSAA8QAA0PBAAEAAcGBABQAf4BEQfCAwFzBQEUAAUE.ADEVAOzPFwAMAAAEABEEPJIBNxwACBoG6gMDBABDB/sDAxdgDQQAAAAaAP8HIAf7YAIAEgAAAigx8wAOCgQCBAAPAQTwAMwHAccB.A4UDAOwXAOIFALIHAdkHAhQ4EQLUBwAGAAIrIgIUDhICQCAACwAAPgAEDAAA0gMA4w8EEAAAMQAAIAAA+wkw/AD/BNAASlgAqRcA.QAAAHJoQALyoMArzBLfwADACAAsmAEsEADwQABceAEwQAA0uAH2AIAAE+YkB/AMBUmJwBf4IAgADBvwvIAkAABghCvYIABAEdFwg.+wAGzwIEQIAE/QAN+AAP8TNYAD4AQBPtBgJxCgAMAAl4Ag8EAP8KACUCAAgABgQAAbABDwQAFiAD/UICIAT9EXIEIQIABAAAIAQQ.DZEJAK8hAAIIAx0AAE0CAAgAABm6AAgABdoPAQECAf0FAgkABAcMAwwADAQAAO0pEAXu5AANAFEF+wAR9HgcAA4AXwAAABjqPAAJ.DwQA4gCRAQIIAAPAAwORAQQYAAYEAAIgAAIEAAEMAAC0AQgnAAEVAAAJAAAEADID/AXpNQGYBQArAAAIAA8EAAEEXA4CZRAAAgYA.CAAAFwQBOwAFBAACAwoEwQEEADYiCff/NwEEbgH8BSEN9SoAKw/19wUpF+kQEg8EAP8PD/EDBQbzAQbWAQDqAQAIAAQEAAHwDwCH.AQAZAAYxAANgAhAN8AUAtgEA6w0DRAAGTAAABAAgB/77HVEE/Af+B0YCAPpXABgAAgQAAAJ6IAAJ/jEADgAIBAAF+hEAKYYBwvQA.kGwWE/YBIBHxNQIACgAPBADiANcFAI4BAAgAAOABAKhvABgAACAICAwoACK4ARCYA5IHAe8vAckdEQD7FwAgqAAYAADQAQAbAAEp.GAEcUAJIhgAQjHAAAQMD/v0EwFcB3F8h/AJAAACMvGAECvUR/fo6YAAcvgAAmABJAAACCADwcwBUSAA7sAJhABEHpAgAqOQA/lUQ./gMcABcAIAAAIWpACvYACWcKUQv1AAr8KCxAAA33CfAPAAQiAWigEBILMsAN+Qb4ABcAAO0A8QrnAAB9AgJGAA8EAO0C3gsABAAA.uAEE7gsABAAB2AEBBwoBCQAEBAAGIQAAqBEAuAECDAAPBAAGBtoDBUwAMAf2FZEVARAAADoCAAw+ABgABgQAAOIXAEUWAUMMAjzK.ABcAAAQAAfcNEQkYAHMH/wr4AAv1JQAAGQhQDfoADfUjMgERAAQEACAT8B8aAAoAMQAc5AcADwQA8ALwAQ8EABkBsAEACQAPBAAF.AMMHBAQOAhyeEQP0vQBzAwAUAAIEAIAD/QAV6wAU66YHAFZiACECADQQAOoFAA8YAAM2ACgABAQAIAX8/40zAgb4AIITAAQEAQkC.AAkAUAAH/wv3/A8BDQACBAAhD/EFJgJ3JjEAAAeUAA8EAP8CBtADArgBDBAACPUBAOABAAgABQQAALsBAAgABAQABC0ABAgAARAg.BiUABOsJUAAAABXrM4gDDQACBAABTFAACQAABAAA/lkA2AMACRoAEAABBAACDCgB+AEBBQABACQC/SEBABogCP0GAgUFCAMBAgA4.jgAFBgIMACAc3AYADwQA4ACFAwBAAQDYBQDaAQAMAAQUAAAgAACJBQAMAAAEAAAQAAAAcAAoAAAMAAgEAAA0AA8YAAEGBAACDnBw.Bf8AAgEB/Q4wA0sCBEYSgAIAAAr3DfIMiwkTBBsAAAIwAggAAP7DIAb+BLoQ+TcIMAf8/to/AANEAJggFAiwABIJOAAjAAoIAACn.2AAIAAECIkAFAAAPFgIQBXEuADE2AfS4AB8AAC4QAHgAAgwADwQA8QbxAwIEAAwQAAgEAALAAQcEAAbcAwIEAAghAAIcAAAEEAAI.AArZzTALAfinNQALAA4EAAABFgAIAAAPAgAvgAMMAAd+BAJnAAAASAAIACIL9WsAIAz0ACgACgAEBAAB+xMAACYSFAEEYBnnAAAW.6goADwQA/xICFxoACgAMBAADtQMPBAANA7vMAQ4OABAAAwEEAT4AJQgBtDMCvgEJr1EB9wUAAAYADQAAXBwCCAACIwAE/AUPBAAD.0A31DfMO8gX7EPAAD/dIJgAVAAkEAAE5EAAJAA8EAPMM8QMC9hUPBAADAcABAAkABAQAArwBAdIBAAkAAuEBA/AFAhwAAxMABq0d.AQQAEQuQLQAbAAAHGgEIAAIwOAD0BRAG9iMA/gEQB13CBZQMACYAAf8TQAn9+v//GTEJAPkINBALCBwAAggQ/QAUUAAADf4OXgAB.e0QAAgoV7/YDJRnrCwAPBADtAAgIAAgACAQACBQAEAL4FwAVCADDAwACGgX8LwAcCgA00AIQAAAgYAAUEAArAACpAQAQAAEYAADS.U5D/BAT5APwDA/xeIAANBAAUQAAAqFIBBQr0ER0YASrQAQCQEATWiQNiAAAEAACf4AFMGiIF//t5ABUAAQQAEgbiRyAG/SGSAE3I.EAb3BxEAFDrgDgAA+vIK8QAQ9QACAAZoAhATCQogD/kfGEAdAOkA28wiAAISBg8EAOsCqAMEYAME8wsMEAACeAMCBAAIDAABBAAA.1gMINwIA5AsEEAADDA4AwgEADwAHBAAA9t0RFgQQAGwAAAYCAVkAATAMEQW1BREHA24gB/n0CwSSBBEDICgAAU4x9wAJCDYAKBIF.AwwJBA4RDxYAERAnAgAEAFAW7gAACG0AQAAAIOARAA8EAP9OACgMAB0CAMcBAAhwAnwBAkREAAoAUBbqABXvzwcAJQAABAAAFQAP.BAABAAAmAL/gAP5bACUCABQABAQAAggSAAQAAN8rAAgAEQlmBgMABgQEAABzIgFJBAANAA8EAPkBoAMFYQcE8QMABz4ACAAEEAAH.egsBowcBCQAEBAAMuwEJIQARBLqLEAdFngAPAAYEAAA2AEEW6gb7ExYAEQACBAAQBHyiAgEEAQQIHf65ERIFAggA4AECAQQCBBAA./wUAADoAUQICFgACEgQAABgCDgAHACggINcGAA8EAOAAbQEA7AEAoQUAWQEADAAEFAAEIAAAGKAIwwEPBAAhAWAAAE0AABBsIwP9.UrgAGgAC5AkAooBAABbsDMYBAPQPBIAAAwQAAQEOAP8rIPkF4uxwBwD9AQcC+jaoAIjmEvrIBQAClAOoABMKgwIDUAACBAAEACAR.BhBYACkGEQf8JwD+BQcoBg8EAPIGAQQCBAAMEAAIBAACwAEHBAAAywMACAAEBAAKIQARAgkgA6EBCisAMAr2D0CoAAsADQQAAP1T.AL0PAAwAACcIA1QAClwAAQAUAhMABAQQIg3zaBAkD/HwAwEEECIU9AEeABEAXwAAABnnAQL8DwQABg8EEC0A2TMAlfIA3eMDMQAB.UQABYgIHvGUCvgELJQ4AASIFgAABMgAACQAB0QEwCfcH+DUAEAAPBAAAAlwSIwX78B8AThoACAACBAAAAQQACAAPBAD5BV0BAwQA.BHILDwQAAQSRAQUEAAK0AQYQAgIhAAAEBgAIAAC+AwVeAAIrAAMEAAA6nBEDGVYA1xEABQwECAAiBv+0KQEHEgArAAWDMgJcAAQE.AAD8KyEC+f+BQAsC+P8ADDEN/PpkABEPBgBQAAAS//QwAgD1DwkBBA8EEuYAlwcEVwEHpAEFBAAGqgcCEAgBGCAA0V8AyQEAIDgB.KAgCDTgAGwAAkQEBQygB8MEBEDgAGwABsAETAqyNZvsAAgb9/wQQwAEAAQMB/P8DA/0M+kNsAFMAEALZOwBXBAABAgA9AAK8FwEA.IAAAHgAcAgH5BwIDJiEDAPhPABweAgA4MPwEAwUKAAsAAQQAsPsLAPAAEfgAB/QGGQAQFgsE4xH4CPcAACAA6AAADgIAIQYPBADs.ArgDBgEEDxAAAwh4AwgMAAEEAADUSwALAgAMAAAEAADCAQI3AA8EAAshBg4PNgFQAABAAAALBBADVvgCAAwA/wUB2wEABAAEkgQA.JAAACAARBv4LAuYvEAcCWgHUCSAM/CEwQPwADvr/HREQEQIAABgACABBAAAX8TdqAg0AAR5OAgkADwQA/0QDAgIA6kkAyyEABBAC.EgADzQUC8UEgE+z+AQDdAwAcBgcAUAA42AABBDAABf1QMgD+URD++QMhCPgYBAAjABAKOwAA/w0ADQAAFwQBEAAJBAADAggA/SkJ./i8gJd8GAA8EAPICqAEH8QMABQAOAQQABQAPBAAFAcIDAAkADwQACAAVBAAIAAkEADAYA+0LagALAA8EAAMNABACBAAA6lkBAQQB.BQAA6w8S9f4zAQYEAgJIBv8fBQQABg4CAf4DBCMMDwQA4gDmBwBdAQXoAQ8EAAQEKAABHDAAEQAPBAAQAMsDASEIAA0AAPhzAN9p.AA7AAEkAAFMCABwAYf8DAATx//uPAPMjAsIxEAWsVwACUhEAABYAAx4Q/mS6EAcRqBMDACAXBscFBAkAEwtbAEAM+QP8PmYA/BuR.AAYABhfvABPwSRgAM5Yh7wkEEFMAAAAr2RQADwQA8Q/AAxEHBAACwAUIBAAPQQAOAhICCQQAAFkCRA8E9QrJrwQjAAH+EQUEABEH.gAoACgAEBAAHCRoCdwAE/C0PBAADAgIUA00CAwQAECQFJA/+A+oPBAAJDPQPDxNGIATMAQEEAALZKwQ2AAkbADAAAAzKewILAAQi.AAAmDAAIAAa0AQw8BgICCAT8BQQEACIL9f4FAAAgAAgABQEGIBPzSgAA/zcWGgEGDwcQ/wIPBAALAgkICAQADhIADsIRAwQAIAT6.GQAJMQAADQBCD/IACsgNBjoACgEEBgQAEAgCXgDnCQUBBBIHACAACwANBAAL3wMEAwYPBADyAFMFBNMDAIcFAXURAFoHAPoNAABo.APEvAwIKASwAEgIs0AAQAAArAAARBAH0DwAMBAAVAAL8LwErChD+MQAxAAT8QFgR/jwIEALWESACAhhIEP818AFA4gF4AHIA/BMF./fQIxlMAFQgBCAAQAgMwAAJyIQAGPwACiQAAK7YDCAACLwAFBAAQCl0mAAZSAC8iEA0YhAJDAlAP+gAK7vkBwBTsB/IHABgA8wAd.4ylkAB0APxAAEAIQ9A8EABQEnQUPBAAgBjsAA1UCBewDAB8uAZ4dA+lTAAoKAggABAQAAAYGADYSAPcHIgYB9z0AAAYAAEADMwAP.BAALAgEIChIeAAEIIDDQCgAPBADyALgDDvQRBxAAAAUADgQACBBAABcEBDkADwQAADAD/QfcIQALAAYEAAADBEQHEwHs+QcCIngA.LQQADgAGBAAE/BEOBAAxB/z8AQYwB/v97h1wAAgB+wAN85ASBOENHxIbCggPBAD/HQKlAQIEAAgMAA8EAAIC4QMEQwIDLwAANNQC.CgAFBAAAAQQACAAJBAAwB/8E92cAtzEQB/59AgAiQfsD/wVfFgJsAgAJBAAIAA8EAAEDBDYCBABDEvEAFGMIQQAAHeUIAC8k5gEE.8QCBAwBcAwOmARsCvwMAwgcACAAFmQcOBAAGFhAC4wEIPhgCIQgArQGgAvwBAQAF/f79/kWwARQIAFzIATheUAv59/nyK5gB+zsQ./QG8AQBeCAQAQAX9Av0IqgAIAAABBiAG/Za+AOsVIAYGBB4RBwBAUAAACPQJTypIAAnyCjFCBVAAAAAuA28KECoBFDEQBAB8Bg8E.APYEAQIIxQEABAACGAAI+A8A1wEACAAPBAAGAoUFAwQAAg4EEAT4CQAJAAwEAALLAwAFFgAIAAEEAAAEEgMEfAD6BwASCgEHOALa.CQCSsAIIAAcEAAAAJAD2AQABSABwAAABBgEpDhgA9SsGCgBDAAAQ9H0IDwQA/1AA51sAnQEBuPQAEQAAFjABYRwgABSUKwATAAAG.WgC5AQEMAAkEAAADAgj0FRAJ2AEAAgoAIAIAIQAPBAAKABNqAAgADAQADwEG7w0EAALpAw/JCQgPBAAHAgEGDwQADA8lAABRFOwA.CPfqAwTcAwMAKAILAA8EABAgCv4CIEIAAAz6/FEcDUUCBeUDEBkfAAAxCgP+BwYcHA8EAO4DmgEB+QEAAEAAxDcBwQcAFgAAE04A.L3IADBABEAACrhEAvwMANwAMLwYBBAACMEAA7AcAxhcAFdwxA/oDv4cLJghABwcHCZgBABhGCboBQAf5AAJs7mAI/AAFAvsvbAIY.7hAJHHhA/QAACQBuAIgAAC0ABAgAAkgOsA/xBfsAEPoAEu4NhaAAEhoQ+AswVBwA8yDgLnoxACDnBwAPBAD/KwExAgAJAA8EABUE.MQABAB4BCAIUCakVAlYCAAoAAA8EAAgADgQAA6gCAzMOANgpEvz+AwIPAA8EAP8oBFEBCAQAAa4DAAkADwQAEQJBAATfAQTVDwND.ADAE+wLHPwDJBwAPAAgEAGAN9RAAAPNRCgACCgAIAAD/BQAKAjMH/wX1cQR7CgJUAA8EAAAjCwQAJjH9+/v+HTD99vvwRxMS5BNA.FvII+AsUAAwABwQADwEG+A8EAAsCHGwACgAEBAAAoQEACAAPBAAUANgBAAgAD1wIAAG8lQAJAA8EAAISA/FBAQMQEP8gFAAEFAKN.AAAAKAAIAA8EAAlwDAD5BgAU+AwSAA8ABgA0AAEIHycGHucAvAcAmwMBggUABAAB8QcH8gcABQADFBQAAGgAqFcC3icAoBsFNgAB.5x8BOgACKFwAPzAB+AcAKgAADDgAQQAAEAAAOUgA5pkAYOAAYAgA7AXAAQACAQL9AAMEAPsI4LUAVFQCyg8QACy8AAkAAv8DDwQA.AAGZzgACLjAAB/UAJgI0qABZ0ABviAAiAAAAXGANAPf6BvEdNDMHAAi+AAK0xoAAADAA0BLZE266EuYXAA8EAP8LArYDAngDAgQA.DwEEAgcZAgHsNQI3AAEEABIBDz4IQwACBAA1BxQAiBEAYLQACAAgBQREXgDpFyAF/TkGAFwCABgABEcEBAgACgQAQAz+AA3fEQD+.KyQK9gQUERMfCAb/K1Ag7/QADwkADwQA/1sCLwIAAHwEzAEC6gMCGAAC/z8EAFIPBAABAAgoAD8IAAQWAfaNIwb6+nkC/EMBACYA.CQAPBAABCPYRCAQAIDvFBgAPBADyAqoDAvEFAAQADxAAAw8EAAoO2wMJBAAFgngPBAABArgzAQQAEASUBQAJAA8EABIBzw8EAgxU.DPQADvIUJgIEAAvjCQH+BwIpIg8EAPoEfwEAwQUArAcMAEgAGAADo0EADwAAKQgA1wcBDAAPBAAFAC0ABCUAEAJRAFAB/QEBASJ4.ABIAAQQAAE2gkAAH+Pn87AMF+WQAAgEEAPkFAA0OEAb7iRAABWwxBfgDACgAKZgACAAgAAc4dhIKTmIAMwAJBAAxD/ELSkgjAO4N.AhIWYhACBAAACBgACAAABAAYExkADwQA/04BAQgAAYoADQAAAgoAPgoCDAAB0xU0AAX7/7MNBAADAmgAcyIDMgYAYAgA/xkADAAP.BAAlDwEG+AQEAA/pBRAPBAAFAPEDAAgADwQAAgTpBwslAABvAFAUAAD9+uWHABEAAwQABAMSAABAAAgADwQACxML/HUgDPr+YQAS.AAIEAB0SFggCAQYACgAPBAD/DQ8IKgAJEAABwAMCCQAPBAAFCkEAAgQAAwcCAwcADwQABQUCXANCAAD8GwAIAAaCBhEDAoYACgAP.BAABEg8CjAALAAH/RTYAF+kBDAQBBiEw4gw4AAsADwQA4gCcBwNoAQEEAAEQAAAZYBAAtq8AEgAB3w8CCQADBAAAJAAPCAABAbwH.ACYCAwgADwQAAREBtg9w+wL+AgEA/SEoAewHAAQAQgcGBwm1Ox/6phMAAmQABALYBgMCAgcAAAKMAAgABpACBAgAAFMMAAgAEw1M.rCAR+C0KECB2PgIjPEIAAAAnESIPBAD3D24lBw8EAAYAwwUACAAEmgEGEAAJBAAElwELBAABLgAAoxEBbQwG/gcCtAEACEQCCAAP.BAAHACoAAABMAChqCQFmBf8nBQQAALfoAAgADwQA/xIO9BUPBAAeAkEAAeIBAQYcAA4ADwQAAUAN9BAEt4sADAAAYBQAVJACCAAA.3AEA8w8Giw4CVAAPBAAIEA7xY1AP8QAQAhIIQgAAE/3tAyYXCP8vBwQAAw0GDwQA/xAOEAIP0gMEDwQAByIC/sq3AAwACQQADr6D.CwQAADYAIgYCCE4ADHoE/lMABBgDGQIPBAAJGAcARDMAACUXGlMAAAAzzQkADwQA5wS8BwL7BQJoAwEAUAC0NwAceAPoBwDohxD+.wj8AhQ0DGDgALAAAJQgAkRUAFdAB8y8gAQDVFwHtDQRcAAD/DwDgFwAEGED//AH9EcgA/msABwgA++9SBAD7CfiBAAQDBhACE3gD.ewAAEAANBAABhdwA/jkhAAQEGDUACAMlDggEAED5Bw/q+QUjCe8OEAAQIL8AAADxO8UAFBrNGQAY/xIABAACyAUDdQEPBAAHBPMB.AAQAAqQPBAQAADAEDz8AA1ADABQA6wkAAf8PAAQAAOsbEv8JAAMEAAQIAgBrAgAIAA8EAAMAAyQhCgIFHjAADAIDIgDlJxIWCwYP.BAD/PgDRAQAIAA8EAAwCOQIBBAAA5ysARAQADAAFBABGBPwEFJIFDAQAIQX9/R0ABvoTAAEGARsKIAP+Ag4A0wsADgAPBAAORRfp.ABodCh8qBE7lDwQAbAQcBATEAwDjCQAIAA4EAAEDFgAJAA8EAAEA/k0DA2oADwAkC/nXNQ8EABwA/xMgTbMKAA8EAPEDrAUMAFIE.eAUEEAAPBAAKDxIEAQA2AADoBwJACADKCwBkuAAaAAEEALH+Av8DAAz89/j9+0qwEADWLwA0AAAdAAAAhDEH/gWUAAEAMADQXwP8.CQUEABD1RwLRDPQJAP4E/gAN8wkA/gcoMQvvDkhKACMAADk6AwgAAQQAAx4SAAECUAAgAAAAFhQAEQAPBAD/HQ/vAQEJBAALqgEA.OgoAEgAGVAIHBAAeBL4JANkBAAgAAL8BACckBBEIBdQxDwQAB0AP8QARawBBEvIAFKYAIw/6AGgA/zcFHxQPBAD/IAS8BQ8EACAB.MbABChAPSwQCBwBIDwQAAgEAMAcAVhAKIFQAAQwAEAAAIQAPBAAXAQcYAAkADwQA/AqwAw+mAQIPBAA6EAQVBgFnABAVmBUAAxYA.uEUR+gISAP0RACUADwQACgUGCBAM/TkACQAPBAAcIE2gBgAPBAD0IP8C/BcC2DcArQkIEAIAEAAACAAEBAAAJAAACAAC1gcACgAB.2wMDCQADBAAAFYYDLBAAzT8wA/0E2yUAHYgAHgACfeAACgBRFOD8DOsNACIF+vwJAgYABgxIIgj9ADAxCAD9GUBACf/9B/zPAQRo.BIkG0AX/AA3+AA/xBvoAD/4CLDEAABM2BAAKYhTnFGIAqNYAqtYCDAAPDAT/Bg4EAAwUHA7vAQ8EAA4BIYgAvCEMPAAhEPPG0QAL.AA8EAAgBgAAEQiYPigYQAkUCBQAmHBwDFiY74xMsDwQA/1ggBfs0FAAKAAcEABENqR0PBAAUAQgCAAkAARwEBAAmDwQAFAABCgAA.LgAMAFMAAABAwAkADwQA/ycE6KMABAAK1gMPBAATAj4AALwrAhkMArYDD7lxGQAXEgAAMi7/+0UMDwQA/woAcAEAvgcAegcABAAI.cQEADAABFzAAu1cDiRcBkE0AMQAAHxAAJQACCAABigUAGwAECAAAIwAAUAAAFB4CTggAGgAAFEBA/gEG/ACuIAAADiggAgJO0AAc.ACIHB3R4AQQAIgICxwESAwgAEAc/NAQ8DgARAAUEABr9bgIBP6hADvIACjZQcBDwAAsF8/oAFgA3FBD4/AcCLgokJCFxLg8EAP8j.AqgZAgQAD+8DEgAqggAIAAD0BwDEAQDqlQIQAAcEADUIEPCXIQkEAAAANAASBAAlIAADhgYIAgQIAA8EAA6xFv0A+AgAGfoAFuoB.AgsEAA8BCP9cAwcqAAUABzEMTwn4ABACCBMA7AUACAIAzAMA2nMA/EsAGAAAPQ4HmgIPBAAMBwEIDwQA/wkCmgcPBAAQDykAFg8E.AAIAPgAA3wMB/kkE3RMECAAPBAASVQj8/AAMhAAABFYACAAPBAAPL0y0AQr6EQIC+ALxBwCPBwAJAARW/AAEAADUBwRmAQAgAAPF.AwEGCAAcAAHlXwASAAANAAAIAAMEAAA0AACcBwDDFxL99wcAoJ8BJgABMAhz/QD/FADsCZ4FEwT8HwEmPgNTCAAQAA0EABX8YqIA.LMoAFxRQAPsADv/pd0D6ABD+SzwAHQBBABD5CBVKIAoACiABEwAjAA95Nh8fAg7/GQCpAwDCGQAMAA8EABQAJwICNwADBAAB8gUH.8TMDBAARA7I9AAoACAQAAgI6QAX+Bv38HQBMAAAQAAQIAA8EAA9TDfP/ABRGAg8EAP9DAc4BAAkADwQAFQDMAwDCEQrEAQAF7gAI.AA8EAA0A+QcADEgACAABLgZfB/kAC/kEQhQnHePqAx8w9gX3DwQAWQ20CwAXBgAIAAYEAA/5BxUZCvgBHwuJAh0GBAAgX6EGAA8E.APEDKgUF8QcAgGcACAAEBAACsM8PBAALBOIBAOEDAwsABQQAIAIAGJwQAxJQChsAoP4DAAz2+v37AAT8TQKoXwHcEwT4gwIJBgT8.HxMH+qUKBAAxDAD7SARRDwD68QUsHjEM7gcMIAAMAAEvQAMJAAAEABAQBQBAAEwA0wcqQQAATYAQAA8EAP8DALQFAAgADwQiEgwE.AA8iBgQAHwIACAAPBAAEAgEKAAq8AwgAAAcQAAsADwQAEwH/XSwS7gEwDwQA/zUGEAIPBAAeABRwDxECAw8EAAcA8QcBCAAS+P/z.AAwADyY+GSMV6wAuIxP8AQgB/g8LHD4PBAD/JQ7ABw8EABICAMwACgAFBAAhFvD0MQALAA8EAAsEAJIBBQACMjYPRkgLDwQAAgD4.JQAIAA8EAP8CAcW5AdYPArwfABQAAAQAALEPBBAAAAgAAAQAABQAABAADwQACQAAMAAIAABfOFf+AAEF/AAOASAGkgL+AAXrBAMF.BAUkMA35+vmnBiUABAQAEf0EIDAJAP36EyAACifwEPgFAAAcAA8EAChPMwAAfwAI+wMBAg8EACEPmwkBDwQAFwOhEQDyFwAIAA8E.AB0PRBgDDwQADCBfxwYADwQA/wMOAGgPBABGOxUBAI9DJAf+AEAECAAPBAAWAgEKMPkAElMAHxUeBh8PBAD/OQHhBQAJAAQEAA0R.AAUEAB8IGgADBvwLBFwEBAgADwQAFgIBCgL+CQQEAA8BCvMAzQsI4wMDWwEJ1wcEDQACLAACIhgAFAAABAADMAAPBAAOBFEGEAX8.dy/8/sALAFH8A/8G+/whEPkKcAAJAAcEAAALUgEIAAhwAABHngAHFAdKHAI6DgFCKgEJAAFHEAAPUBH4QSwCB1oAIbIw9QATABgA.JABCAADNgQgADwQA/1kAPQIACAAEuQECxEUBCgAPBAARBHgCAj8ADzwAGwEBXAH+MT8AAGABLPkPBAAoDzIKKADjGwGDBAAEJgAI.AAa+Aw8EABcBJxQACQAPBAAgIGaaBgAPBAD0D/EJLgKaAw8QAgcFXxYMBAAQDJsFALkVBLQFDwQAHWEO9wAOBPb/aQAPAA8EAP8b.Ao8FAAAwAog3AA4AAMMBAAQoBPAHABQAAMJPDL0VABgIAAgABBgAAEeoADEAAtARABXKAAgABAQAACegIAT8HYAAXFgAEgACBAAk.BAAEKED5AAACCAIA2/kCEwAP3gMOAmsAIAAAARgACgAQCkkOaRPtAA0G6/+FAAQAEQ4AWAAKAA8EAP8WD7MDBg8EABcPEAQHDwQA.DwD+AREFVwQBBQAMBgoPBAALAiIUIhcG/S8RIC8IDwQA/yoAIAYIEAIPiwEYAQQAMgT9/65bAA0ACgQAHxCSDQwACAIKGggC/gkP.BAAUEAn/FwAKdAANAA8EAP9wAEkCAAgABAQATwn38xJMAhMAyg0AJAgBAhgAEQAPBAAuEDMFAA8EAPYgAQEGWAFhIwGqAwHZXwMA.iAD+lwQQAAIEAAP+BwgTAAAvCBL/PBgDHgABBAACzAcAVUgAYkgg/gJreAO6DwAnACIGAwiIAiUAAgQAAB7gAL2XBDsADQQAIQcA./GMEOxICNwgAQEYCCAALaBAABjAACAAA8z9PO8UUGgEO/wACqAcI4QUPBABfANwDCAgADwQAEi8IBAM8JA8BDv0KBAAK1wMPBAAS.AhIIAkkCDwQABwSyCwwEAALCAwkcdgD4BwAIAA8EABI/CgT7AQ7/Iw8EAFgB8gUACQAKBAAK5AUCJQAGB5APBAAdMgsF+gGqHQAB.Dg8EAP8KAAIwAAgABAQAAwAEAas/AKEBAvwHBiAIAB0ABAQAAKwBAMkHAAwAAwMIAAsAAcoBAA4EADQAAAgAAxUAAC8AAAsAAQQA.bgH8Af8J+y6aARxkAAKMAQ0ADXMADwQADxIOIKAwEfgTfKoAKLQQDvY9AAMkABgAAAQADwAg/wAPBAAHAtcFDyAIKgAHAgAIAAwE.AA/cAQsACVYGCQYPLAALDwQA/4sBDwQACQAPxAEjAAwyAAEOAAwABHA0DwQAGQAAQAAIAA8EAP9rD/sBAAAYpAAIAA8EABUTBwja.AAwADwQA/0kA7wUPsQUFAgQAJAH9zgEG/AcPBAADAEwAAAgAMAD//xegBA8AIQT8cGhwAwAN/Pn5BhoID/kNCiAGAAxIEfkCWEIH.AP8KUAQxDPQIBBAhCfIf+AATAA8EAAEg6xUGAFQAAADw7AJyEGAFADAAgH+yCAELAA8EAP9jAlgIDwQAJAH6sQAJAAEEAAD7GQAI.AA8EAP8kAu0DD8sDDQ8EADEPZABAAACCAAgADwQAHRCZBQAPBAD/BA+ZAyAEEAYPBAAGAs81DwQABQAENg8BBgkPBAAQDwES/ygC.2g8ACgAPBAADAAQ4DyIACwYEAAzhAwA4AAJOAgASWAAIAAoEADQBAQLQC0IHAAAEChQABnwBAG4ENQIy+v0MIjgFBAAT/D9CAN0P.AwgAAN83AfwXUA3sDQcAAcAADQAkAAD/B3EAEBQAANkZCwAPBAD/TwTVAQ8EAB4AAOYDahAmCADlAQ8EABdAE/MAFAgAAOxrAwgA.DwQA/yQGywMAxQMACAAPBABXAwgEDwQA/3sGEAIPBAD/yQN7BQUEAAC8BwP/AwLrlw8EABgDOAAGBAAeBOwXIAv8O9AACgACBAAQ./hFmEAJ4IAQDBGEIAAD3AwMEoDD2APoHqDEK9f3cTwAeAAwEAED6AAANCAAAHg4DPQYFABAwAAAAAS4fzfoh+w8EAFIF/jkNFAIP.BAARAi14AAQAAeAJDwQAHEAVAAAkCAAPBAD/Lgj/Aw/vDQ4PBACFEDsFAA8EAP9kDzQCLwIAggAEAAPbBQ8EAP9UACAQBLgFAMgF.NQEAAAAYDwQAFgHWJwAJAAUEAAMUYAUAEA8EAAcT/fcFEP3ZLQfrFQLZhxHz8QcPBAAKFdwBBjDFO+cCKGDAQABnmX8RAA8EAP8k.Dc0BDwQADgg+BgAMIgMIAAAEAArgLQ8EABAVCwgEDwQA/7QD3wMPBAD/3Qx3Jg8EAE4QMAB+AAkADwQA/wkApwUMBBAMBAADBAgA.CwAPBAAWD+sBDx/5/S0XEfwMSAAKAAAEAAT/BxDwARgACQAPBAAQEEAFAA8EAP98IAf53gkACgAPBAD///9kD9ELHw8EACIP7A0M.DwIEThY7AEYPBADrAOgHAAgADwQAWwY4KAQEABIBt1cABAAABeIPAQIeB1ECD/8HGA8EAP///////////////////5IfB9hfMA8E.AP///ygNmRMPBABiDwMaTiDFJwYADwQA///yAOQfDwQYAQAYAAAIAA8EAD0CREgASjgADgAGBABE//z9/cwvD/4fFAkEAC/8BAAo.EQ8EAP///4UW/yaCDwQAU1TQMAAA2Rw6DwQA/3of+gEq/5gPsgMnGf3JTyH8BBEIAF5oH/z/LRYiA/kiEGT5/QAHAPgdPg//BxpC.OwAZzQNAP5kAgQEw/ykPBAByEvQBMg8EAP+VD2MQLxX2QgAP3b8BDwQA/1oPzAEvDwQAZB/FATr/HQOlBwAEAA8AQB4HKDAC52cA.GvwDEQAEBABG9fz6+6anAwQAYP4AAgMA+wpAAA4AI/gCAEgAUAAAQUBH/wcEAwBIDwQAAg8eAAQAAm4P/z//YQ8EACkAykEACAAP.BAD//yIS5+oLDwQA/y8PqBFcIgAAzb0DDAAPBAD/TwjYBwAMAACubwAMAAQEAA+pOSET/JkvALQHAAgAPwAA/1sYAjD///7DVwAL.AAEA1nAC+QIA/gX7hwBSAPgI+/3IBwQAWAAMAA0EAAQAGAEAOLQGAO0GAAAG+A8A6QJQBQBIEPD9MT/nAAAWBP8VD/AJHg8EADoR.+DIKDwQAGyDvEQYADwQA/zAGtQMPBAAWDxEODgLTAw8EAAUg/ASv0wAKAA8EACYP/1X/JwTgBw/wA1EPZAALDwEeIQBCghDy32UB.DQAPEhQYH2cBWv8HAQ4CDwQAFADVBwjUAQwQAAAEAAD+v1IAAQEC/wUgABMAAQQAkP8AAPz2/P4A+hl4IPkACAADBHgMBAACABBE.BAD8/QBQcQ8A+AD8APg8EED3Bfv7Fkgf9UlGDAEAWAAJAAMEAB+AAWj/Fg8EAD8E9AkPBAAiBgOUDwQAHgAAUh/mAAr/FQ8EADwv./fzcAwMPBAAYACAGAQB2Q/gAAPRhDA8EAP9jAIYVAAgADwQAFADtZQAIAA44TgDlXQAIAA8EAAsA1wUG/10CTBYPBAAWMOsAAAD0.AAsADwQA/wUMlicADwAEqQcA6gED/6UBEwAAEAAdA+IHDwQAAwQOcDD/A/1TgAC0RwU5AAQY5ED0//39pm8ADAANBAAAKfAG/xUF.PAIQBAgEAAkADwQADLDv9+0AEwD1AAkA8yIKAQqKc+0iABoAAKACaA8EAP8UA6sBDwQAGQLgBw85ACABBAACFgQEMg4BCuIACQAP.BAAWH/IGDBcPBAD/VgIRAg0EAABPBAAIAAIEACD8AAYQFPvoAw8EAB5D9QoAAP91BWXoDwQA/yEDDxAABQAPBAAVAMgBAjcADwQA.CRD8BH4ACQALBAAR+84hCSMCBvcFDwQAED/2CQDd9RoP/337AaYHBJwPAMkBAAkAAw8AAbQnANQPACaIAhIAAAQAEf4YAADCbwAO.AAgEAAesBQBXAAHdfwAsADEC/f4LmAA5+AAQAAAhAFMAAAD8/RNgD9MHFAoEAAAGJAb/fQQ0Gg9OKgUBAHgi7OYAGD/NmgAAkP8w.AeIBDwQAIQHrAwAMFADaCwAMAA8EABoa+QIMBACKDwQAEAD/DwAIAA8EAP9mAP4DAAgABAQAT/cAAO6c4RMA/w01+f0D/9tC9AAA.9BwcDwQAJRDNCFwACQAPBAD/FAAFBgAIAAAEAAKzBQ8EABdB/AAA/Um2AA0ACgQAD7cHDQAICBX6+g0ABAABPAQPBAAVEPf2hRbo.JAYPBAD6AL8FAAQAANwHABAAAAQAAOQHIgEBzO8AEAAA4M8AFAAADAAABAAIigEIBAAAzQUASQgAGwIAkAUKVBAATpABCAAEVwAD.BABC/P0E+lIAEwe47wB5CgISACAA/UwAAApoAQ4AAUoIAQkADAQAA/cHBC8oACkgAQAOMekM+FsEIOAcBgAQAP4HAQkADwQA/w4v./wFrAQYPBAAVD6QDARD8ABIACQAPBAAGAgcME/n9IwD6AwAIAA8EABZA8Qn6Cv8NEO0/AAv/DQAAEgAIAA8EAP8EDJcHDwQAHgIx.AgnzAwkEAAPbAwElBAAJAAUEAAHEmSH7BvgPAAsADwQAHn/yBQDyCPsJ/w0aDwQA/zYP8AEHDgQADhIEAhQCAQnyAAkADwCeAA8E.AA0h+PwxBA8EACIP/ovpAnoBBgQAAQTIAK3XAA0AAwQAANwBBBYEAACYBAwAAMgBAOAHAEQAABQAACgAACBoABwADwQACYD9AAP7.Af///qHPE/1cEH8AAP0FAfoOrw8EAB4AAAgAIAP30AU1AAAD/jMCA7gBOwQJBAAEQgIETBAS7zR4UCDvAAAO/wcg8MUfBhMA+Q8f.MwCI/xUOoZEMEAAPBAANEfxKigrVFwMEAAKilw8EAAdD+AgA94AAA/oNAiQWAAoADwQAFRHgBgoPBAD/WgGgAw8EABBA7/IA+E0E.AAwACgQAEvj0Aw8EACkCAgoB9RsFBAAEHRgPBAD/Ch//DwovDwQAAwQTLg8EAAsT+SEEBAgADwQAFgD/qQAIABDuOwIT6xQuDwQA./xMAwAcAn28A1AcABAAAFAAEBAAMELgPGwIBAa3XAAkABwQAAAAQACwAagIAAPwAAREEAsAHAP4XQff1+wQAqBD5HAJg/v0A/gAC.aI4c+P0BEffSD2AAAPYNBPV8GBD24AFw/AAA9AcA8ui/EPEIKB/7RAoCEOBo0gkADlQfAACh8wcIDwQA/1QGAiQA9wEAU6oEaQIB.wikA/SkADQAPBAAQAf0nAwwIDwQA/1gAHwQACAAABAAPyAUTDAQAK/sDSgQCBAAPTQATE/f48wEFABD57CskAPUODA8EABcg4CUG.AA8EAP9eSPwAAPv+Aw8EABlj+AAA9wD66BkQ+ioEAAkADwQADxTrACIU7fwLAf4VD/8J/wEIaQcADAAN8AcU/8YnDwQADwQHCATf.BwA4ADD+AAL3zzAB/wDy/wAWAAEEAJIC/gL7APb09PK2FyAH+f+rUwID+QL++D9A+QD7/QgAE/r4/xP5CAAPBAAFv/YA+/oOAPQA./wD5HIAGIgATAMgADAA/zQAACervAAQAArYjBI4HBNMhCPAFDwQADgT4AQ8EAAcEEgIPBAAFA7IRAwcAAP2hAQgADwQADgQEEgT8.Cw8EAP+CDR4CCvMHAQAKLwAAuwsCDAQAIvYD/wkCBAAR9f4VD/65IR8A/8X2DwQAIA/MAw0NBAAATAQOxCsy+wD8AewPBAAMIvr9.Dw4ACABAAAD9Av4TKPUECAIPBAAIGO3p5QEDCA8EAP8SBAsYAboDARAGBh8GBgQADCoIBQ4AAa4hAUEAAwQAYP////7+/AneIAEB./AMATgCQ/wQA+gjr9Pf/yNFA+gYA+sYPAC0AAiEWEfvvBxD48AEADwARAAwIAAoABvwvAgkAQ/gF9/scEAIEACHz+isAsvD4+AAL.APYABQD2EYgAAJgBAAowtAAfBwAPBAD0BbYBDwQABA8gAA0Azw8A1AELDQIPBAAAAPYBAAgABQQAAsEBAgQAEvz42REAJiQP/RUa.4vf7AADyDQAA9voAAPAO/QEg7BIGAA8EAP8ZBpwBD8cBDgQEAA8pABUBRQQNBAAGPgAQ/fg7AAkABggADwQADVD1AAD4Ch8iFfTq.Cw8EKhgP/wf/LQ8EACAc/P4TAAcAXwD3+uvt/xsNAgQAAOsBAP8HAP4RH/l/CB4EBAAD/wcQtAUADwQA7waBAwDzDQLkDwAGBFMB.AP0AAq8nAKOfAgwmAsABAQsAEPwwACAA/nADACYAALAFAAgAABsAAEQAAioAAhwIADAAAEQAQAAE+wLtBQAWABL+cA4ACAIR/SkI.AODvAxokEQbgCQEfAED+/f4Cwt0B+AEPBCgABQkAAwQABADaBADYkuoE+AD4C+cTAP/dINz2DEgT8f0PF+EVCg8EAPwC7R8E0QEP.BAAYA3gBCKQBAwQAARAAAt4HDAQAAZwBAvgFACEABAgABv0bATwADwQADkDyAADxPa5A8AAA7zgKA+cBAAQAVOQVAAD1AAoPBAD/.OBH+4AMACgAG0AUPBAADD8IBAwE+ABD1ly0CawIA7QsACAAD4O8PBAAQMPj8BNgbEPNZ2AAQAA8EAP+PBfgFBAQABLwTDwQAEwRI.AgJuAg/+DxMFBAAAAEAD/wcABAAPCNrpAnADBgQAANwnAY4DBwQAAa8lAAkAAw8GAQsAA9TvABAADEQADAQAACgAAAgAACiQdf4A./AD9AP1TIgDeHwIMAEAF+wH64a0wAPsG/RcAEwACBAACDCBjAAD4BQD6iDACCAAA/BESBe45BXYEBPkLBEIEdfoAAO0KAOoQLARk.EhPwIjogxR4GAB8gAgj/BQrwAQ8EABIEiQEEBAAOQQAQ/QPaAAkACQQAB6UHAwQABMMBD+EnHSLzCwAYOvENAFAMEOcFAAUEAAH/.AQ8EAP4OrwEPBABLQvwCAP5QRCLr7ecBI/sAAPQP+AEUAzUKAfwjAEIIAg0ADwQAGB+zEAr/QA8EAAUT/dELEfw8BgAKAAsEAA/y.AQsBvy1AAAAA9/4FUgAAAPYD4BMBAP4ACQAPBAAXD/AF/wIbApYBAKAPAAgABAQAAxAABKcPABUYDO4FDQQAAFAEATYAATAIEAL6.OSQA/l1AAgQAEAIQKJH39PXz/QD7Av3uHwAXAAEEBAEIVMD5Bfv/BQD4APsH+/3oZ38CA/z9CwD38l8MUPEA9QACJCIBAPhhAAAA.8QkA//0D/0kGAPgPDAL2AqkBBs8JAxAAA24DAMEBAggADwQACA8RAgsPHgALAgQAASEEBgQABPsPDwQADgRADB7z8EcQ7ApaAAkA.DwQA/28E9g0T/bIFCgRQBBgmAPkRAf8DDwQABRD9CCYCAygCBAAR9fIBFfMAGB/2HAQLCAQAELMFAA8EAP8lD9ADEQoEAFn7AAD8./wAYAPsVMwD87BECDwQAAFH7Avv9AvQfBABOAhwCIP0BJSIv9gD8HxRF8QAA5hBcFdYKAA8EAPAC5wUPBAAFAg8GAAYAAAhAAMT/.ABAAANgHBpoFAigOA9YBAScIAxAAAegPBD+yRAH9Av2wHwAgAAAIAAAGYIEBAwD6B/D093hAYPsI/PoBAdW7Mvv+Ad9vAwQAARQY.AFEWAwgAFABMAAIVAuEAAPcE/PsH8wAA9/v2AN0HABJEge4ABP358QADJAAQ9zaoATMAEOEFAIEAxQDsBADn5gwADwQA7wKnAQDq.AQAIAA/vBxICBAAGKQAB8AEACQAPBAADBPYBBAQAAQkEAD4AIPjssAEj/gH0Pwb/JQXjAQ8EAAAAAEYACAABKA4AAC4R+C8WBEMA.DwQADw//R/8cDghCD/8FHAA/ABH5qhMACgAAEgAEBAAAogsPqOkLAL4DAO0NAQgAKP0CBjoE7AcBLCIACQAPBAAAIvkKAC4DBAAU.2wNkD/Yr9Q8EAAcGDwQPBAAgAqQBAOEDAAgABAQAAAICAAgABwQAANcBAAgAAQQAAhUKFfsIAAIDJgSJAAJUAA8EAAkw9vwH/wUx.8Ab7GgIi7QIyMDHpDvgIAAsEAAoWFA8EANkEUgEABAAApAEAWgFA/wAB/wA4ALvHAMg3CCQAAAQAABAAAAAQAAgAAJcBAO0HAggA.APAHEf00BgAEAAAsAAAEAAAMAADlBUD+/QD84F9A/QAB+xQAcQP8/gD9AAQPIGAAAPn5/vcFNgAyAAFDAAB3DgENAAAWAAL5ByAC.+UgACABABBXiAAgGAAQkZQL8BgDzBB4SAWsSAFYEIvoASAgCZQIQ4DgQDyYsIg8EAP8wEPwBFCb9AVEaBQQABroVALYBAAgADAQA.BBFKB/oFAAcABQgADwQAFAvtERHZOQ4PBAD/AgLUCwAKAAIEAAwQAA/qHw0AqgsDCAAPBAAACjwAEPD+CQAJAAQEABP6Dw4B/BsH.CAAJBAAEJAoPBAAAIvEI3xtBAAAA7TsAE+kBNgEEAAPzBRDQFyoDDAAPBAD3A38FDwQAIQwhAgkEAAryAQUEAABvAEzwAAD0zQEA.1AsBCAAEzgUPBAAHAncAE/SQAgnbBRPuTjILBAAR9BAGDwQA+QD8FwCLAQCaF1ACAAEA/bE/ABkAAwQAAOgHAAgABAQAAJYBAJAF.ADQAABAADwQABQAkAAAsAAAMAHUA+wD///z9/gUFVAAV9/8DEvvFAQCyBwMBAgT46wEAblH4AAEA/vavAvcFMfYACwgAAwAUMQAA.9AIOCwQAEfkhDlUX6fcABgAQAwQADwIO/xwKzScPcA0JAQQACC0AAgQADhIAAwQAEer3AQgEAAEpDiL6BvsnAQUAAP8NABoABAQA.AtYLDwQAAhPx3iEA/gkACAA3APECAAYI8wU/7QYA/xHzAosDAK8DAAgAApcLAH0LAg4ABBAADwQACg/eAQYABAAh/AD4AwzoAQDc.CwOQAQD+EQAIABH8ASoACgACBAAP/AcCCgQAQPUAAPQgBGP0AADyAPcGGBH2CAAB5DMGBAAB/wkEKxoPBAD/XQD8FyUA/WMCFfys.BRPq6TMBCxgAEQAOBAABvA0ABQAABBgB/gsQ+gAgAAcGE/XUBQL+Ew8EAAIFYAYLBAAP/wXnBIYBANcDAAQACOADAQAQAAkAAwQA.ALkDIQIBpk8ArycAwUcgAASfBQAdACEA/5gNA78BASgEAwgEAQwWADEAACAAADhYIAT5+iUiAv1kCAArAAD+A2UA9/j+8PVrBAAj.DkAAAPv9KQRA+gAA+f8HQvkA/QP4AQI4HDb3A/0bsAIJAPAD+AT7AAD0CgD3/PsAAPELAPX7OQBgAADz+vkEKCg0AvD4WiAQ4CoE.EAABUBYAAEAPBADtAv8BA4QBA9ARBZQBDwQACQIpAAAEAA7UOwkEADH+APmEGQAMAAAEAADhAQEMPAIVAABrABL7GUoH6QcC+xMP.BAAAEfkPAgAgDBL8/EUW+IkABQQAE+8WCg8EAP8wD/0PIA8EAAUMSQAA/BcACAAPBAAEIP0D+SsRAAMeEAcZBAD7HwJEABT25AcP.BAAIcvT5APoI7AwPCgEEAAECCAL/Aw//BecPBAANAk0DAJQDAAgADwQAEgKUAQI5AAAEAAIQAANDACL8/3UFDUcCAMIDMfDw8Qlw.ALIFAiAAAgcOM/kG+w3GBFsEAh4ADwQAAEH1B/wDADIAcAZA8QAA8UA8Q+8AAO45AFbqCPgA+VcEDwQA/wAAqAEUAfwXALwfABEA.ABkABwQABBMABOQBABAAAAwAACgYABAAAAwAAAgABAQACBAAIP4C+C8gAf3obwAwAAL+jwAPJEH18vn/yh8E7QEH/BciBf7yASMD.+sgBBUACEgf4DwGIBAAAIgAwAgARAAQtbARLABLzINwhFuoEGBDkBAhQ9gEAAAQIShLw/1cPBAD/AwCQAwAIAAIEAA//BQsMHAAB.BAAJFQABLgAF8V8JGwAABAAEzAEKBAAT+QA2QPgEAPgzAgZ+EAWdAA85AAMC/SEACgAFABAQ6gUANADnDAoAAQQAEeBJEg8EAPkE.sgMECAAPBAAYBJwBDwQACg8lAAAQ7MwNAAkABQQAGPoBCg8EAA0A/AMDAiYg9Ab8fTMAAPMQDhHwGFAN5AsCNAIA/wcP/wP/CQ8E.AD0x/QD7/QMKAQIB/w0x7u/2oBUT+/YHABkACwQAAiIMAAQABEAAEf3GAQXqHQ8EACIBAwIPBADpBOYDAoAzAvQNAvwXALoPAhQA.AAQAAAsYALw3BG4BHwG4twAMBAAC1UsCTggAHjwAXAAV+9gHAGwAAP9vcf0B+ggD/QQMSABUBgAgAAG1IQH4LwEXAgD4LzAF+/0Q.ACD/AQAwwfcAB/oD+gkA9wAHCSEAAwAkYPQA+AAB+wQEJfcARyYABABB7QcA6ksAAFYEB/8FIQDwpAAPBAD2AY4DAAkAAwQADBAA.DwQACgSZAw8EAAgIIwAGsm8q6en2AwkNAA8EAAAQ9wAOAAkABAg0AQoEDwQAAADiOQQCBgIEAAFoFg8vAAUPBAD/GwjLAQ8EAAIA.xgEQ/owNAA0AAPQVEP0BBAACJAERAAMEACD8AwEqIOsHLgAAEAADBAAT+QCEUPkGAPkD+xkB/Q8zA/0CBBQB+C0CNxAR9uIBAAAS.AAgABAQAGPfZA0HuAwDsJgAABAAl4wwsHA//Be4FBAAAmwEGdA0AnAUACAAHEAAAxQUFfQsFBAAIIAQAEAYAzQ0ADAAPBAAEDUAA.AAQAIv7rkT0R/a0lATIWBWkAABIAAAgAAH8WAAgADQQAAQMCAtADUfkK9QIAPWIESSQA/wM3AADuCAYBBAACLwAPBADrBtoBAuwB.AORHAJQXABIAArIHM/0A/84BALgXBcgDAH0DA9CHARMAEv+TDQDMBQBIAABNAAAQAAB+AwDYLwAjABL+IwAw/PoD4wEAZgAx/AAD.ADqT///+AgP4+AH18xcAHBgBCAAQ/gJAgAAAAAX5+/4GuAcAJQQAAwoAFSQB9AEA+wVRAAD3B/l2ACEA+S0YAQsACQQAMAXw/lB0.AwAgIADoLBQBKgx2ANwK+eAA8BQUDwQA7AKAAQQEAA/xYw8NIAACQQACjgEABAACkAEBJAIBBAABEAACJQABCwAEBAAR9I8DABkA.ALgRAQgAIQcA+CsA/Q8CJQgERgAAHgAICAAFBAAQ9kAKUPUAAPUB/alCAwDzBAVCEfE/AEEAAO0GIl5S6AAAAOMSAAEBOg/+AfYP.BAAmBvABDwQADgL8EQQxAADRAwAtBAC5DxL1kgMA/gsCCAABAAwACQANBAAECgITACR0MPn9AgAeAAsADQQAC94BD0mwTg8EALcM.7BMODwQKIAAPBAAAAOwBAAgAAQQAE/3bAQI2AAELAAUEABL1shEPBAACEfkdHAAKAAH1HQRuCAJHAAICBgMKAAIEABL1ZwAhAPNL.CAAEFAAAZgACFAL+BUMAAADmGhIYAAdYDwQA4wSLAwD4JwBTAQAQAAjnAQP0DwakJw8EAAkAQQAACAAHBAAGQABQ/gACAPzJZwKf.AQQ8FiD/ActhIvLyPAAD+xEU+7oPBPQjEPn4nxAA2glAAvsACAEEAt0BEPfKAQAGPDAJAPY7AADqgwAYABD05A8ACQAABAAT+u4n.EflsGAAyAgI+CAD/BQsgBA8EAP8aBI0bDwQABgHLAQYEACH//PMBDP0NAwQACy0AAh8CAP4HAw4AAAAOgAD5AQD5Avv/DhgBH1AI.BRALBAANUQQS7f0BCgQAENUFAA8EAPIClgEAWgMACAAF/JUABQABBAACIAAA4A0ACAAPBAACAsMDDwQABADgAQD2QwuGAQFXAEHt.8O/9BI4B1QMBZwYKw3UBABoCzgkPBAACBAhoBwAoMQAA90EIBAMaBwQAH+8ANgIPBAD/TgDqAQACBAAIAAAQAAXUVQEEAAELCgD1.AwC/AQQAQgAVIAMDPAG8BwcPBBD4FwAQ+AA6IwD2KwIE3AkPJ1wKAP4LAAgAAgQAH9tTAgcPBADMBukDAJwHAgQACPwRAgoABwYA.APU7A/GfAugDAgYAADkAAjwAA+sXAwwQBCgYADEAAEAAANIHQP4AAvzvawMwAAA7AABRAGD09vL09QQ1AAD/AwAIAAAeAADMD0D6.BfwBH2gz+QAA+CcR/vwTMPgA/dhVABEAAQEmQPYDAPk9EED1AwD4+CdA9AgA92ga1fL6APz6+wADAO8A//Q7IGLp9wD/AAkAOAcQ.JA8EAP8LDA0MDwQAHQDtawDeAwImWgASAAJRAATOCwQEAAAmBggIAAN9AjAA+QHiY0AEAAD7AFoSBgBaAAZsAtoJDwQAB2/1+wD7.A+8mAA0PBAD0AmwBBgQAD3IVBg9/EQECswEE3AMEIQAGEAANPw4DBABR9Pby8fQdAAH/AxAD6j0CPgAi+gUvEAaxJQFTBAAmAAAN.AAUEAAAAKAAS9AD8ERMFACYDZwIE/gch7gVGBgAEAAMAMgD5DRDbCQAPBAD/Eg//AwcCZwEPBAAND/8DBgAFAADTFQAIAAAhAAsI.AAQEABD5H34ACQADDwQDPwAhAPf/BQELAA8EAAACAjgU+/5TD04iGA8EANMEiwEE/A8EXAEAqB8AABgEEAAEBAAEMAAABAACMAAE.wC8CswEAMAAAvwkAIAAAUQAEMAAR/0YYQv0A/v/idwAoAAYMBEH6+vb17ocx/Af7wP8ABAAAGQAQ+2IAcP4AAPkH/gdLACX5BCZ+.EPo4CAHoMQD8DzAGAPZvACL2BvwRwvQFAPMA/AMA8ggA8RcMAhIMdQIA7AgA/vBDCjEA2/S/AAEMAA8EAP9OAPQzMAMA/A8SAA8A.ALABIP4DYAYl7gIOMAL9EQAkDAYeAgYEABT530kD9A8EDQAPBAAdAv8BAP8FAAgADwQA8gBeAwBtAwAMAAAEAA8QAAMEfQcABAAA./wMACAAFBAAAugEACAAEBAAJIQAA8xEA4Q8ADAANBAAw7u/42BEB/AEAEAABBAAAIEISCAAoQfkA+QUAEAAYAAQEEAAbiAP4IQAE.EgAIAAABTgB+BAACkAAKDkDyAADyCAAxAPUC/hUCACgD8AsA8icDADQPBAD/UALaAQDYAwJJAgD+BwDkTQBhAgKaAQMEAAApAAAn.AAAMAAwEACH5AtcfAAsAAeEPCv8DE/niCxP4CAADHEYNBAAR6mIuAAoAAhQGAiMIDwQA3AB4AQAIAAAEAAKSAQCuAwYWAAIKAAMG.ABABwBcB0EcAZQMAuAUhAAIGAAAeAAL0NxEB/gcCKAQAwwEAp/cAwgUA8E8i/gHwRyH6AMoPA9aXBV0EYPX87vHxBlYUAPgBBB0A.AQ0MAPxvEf7cT6D7/P4BAwAA/gP+ACQzAv0CDjCQ9wD6/Qj3AAD6YgBh9gAA+f377gMQ+GoAABw6ACwQUADwAAL1jgAAMgAEQBIy.4wAGAIAADQAPBAD/Dg7wTQQEAAIkFg8EABAAnREAGgICbgIDvgsMPgAE+zsH/hMBBAAQ+QAcALgBABkAAPcDACQgABkAJAD6UAAP.BAAAAtoDI/sF8QUPBAD/CwCPAQORAwUEAACcCQAIAA8EAAEAMAAACAAFBAAA3AEB/wMADQAA3wUBCAACngECHAAAIgwD4AEHBABR.9fbx7/MOAgAAFgEIABIDHgJz/AYA+vwCA7ADAAQABKEAAB4AAQsKEPdiFAH+BwIAIED1A/wCAjAi9AFSPiLzAkQcMgD1+ggABfUx.L+cE+R3vDwQAFgIcDgAKAAwEAALgAQ8EAA4v/gH/AwMABQAAzwMACAAA+gEDCAAAKRAACAAD/W0MACAACAABEAABBQwPBAAGIPMC.ACAQ++AVEPEvFA8QCAQPBADeBEYDBIsBDPwPAeoHBxAAE/+yDQAQAAGPAQCAAQMgAACoBQAeAACuPQEIAAMgAABRAAAgAACnARAC.+w8Q/z4gAAECIAAATwAAOAABKADRAPr68/UE+QMAAPwH/fwPARYAAg0CAb0DMfoK+eI/BgAgAwgAAOIDAPwPAwiOIvYJ/A8i9QkA.SgEGrBD76zcBXSQQAQCkQQL+8gYncgA8ABDgMgQASgAPBADtALkBAAgADwQARDD8BACuCQCSCQD7AQATAACwARD+HAo1AO8B4AUQ./EUCAAkAAd8BADAUAKYBAAwAAwQABAAgAABcAv4FABYADwQABA/ZRQUCbgAPADD/AQCvAwAIAASkBQwQAAAjBAAIAAAEAAgIEAEE.AABUAwAIAAQEAAgtAAHfgwARAAYlAAH8DQJXADHu8PgCAgD+BwAQAAEEAAD+CwAIAADiVwO0KwECGAT3CQQIAAL8JQEHBgD8DwAI.AAAAIBECHw4GUSYCAxgA8Q8CEwoAEwYnAOR5Bg8EAOoCiAEPBAAZAM0BAAgADwQABgAgAgVXAADbDRD9kgUDSQIIBAAm7+4KBgEj.AAD5BQDiOyD8AeybAQoEBAQAAAYCAAsIEPgABgL/AwLoAQMdPAAdBDIG9QLUDRDzOwYACQAA7mUDCABEAADtAyoAAgQABHEqDwQA.5gaSAQLvAwEGAALgRwGfBQAPACQAARIIEQCkGwV8AxD/GwQBABgCvQMD+B8AIAAAMAABQQAA7xkw//0Av48Q+y8AAeUBAA4AAV4k.YPX8/fDxAmgMIfwDJwQQAu8bAEUAAFAAMP37BwAUEPsZAAMAIAQNKAEEACD6/voLIAD6XAol9gL8LyEE+MYAAQAgUgEA8QD/LBgB.FACw8wD+AAQA6QAEAOQoDAATAA8EAP0CDQoACgAEBAAPEAANAwQAAO8BAAgABCEAAxAAAA0AAAQAAAoCAdYJABUABAQAIe/vOgIA.FwAj+wFFEgA9BAD+BwEoNgDxBwLPAQEAIANTIjEA+AYLRgAYAAEEABH282EA6AkwAPYDpQJAAADz/z4yEPIaGgAiAAcEAAP/HQ8E.APoCZAEPBAACAMAFAAgADAQAAp8BAAQAALYBAAgADgQAAfUBAKADAJwDBDEAAA4CAVIEEfWdYwJ7AAREAAQIAAIEACL5BexZMPkF.+d8fABMABSmaAf8DAPgBAVAACgQABfsHAgB6AiwYIgDtOQAABAAW5gsADwQA8QBkAQAIAACvAQ9PAQAJBAANIAAKswEE/wMDBAAQ./YgdAMIFAA0AAeADAQkAAgQAE/aYHw8EAAAR+yICAAoACQQABVwABL4JAfwNAQgKAlwAAQgeIAAAAB4hAvvwCQX3IQMEAAD/Aw/p.U+UE6AEEXAEA8D8FUwEB6wsCGgACBgAFywEAogcACAAFBAAMSAAKCwAABAAC4m9gAgAD+/z/0DcAABAAGAAEJSgAOEAT9ptPIvwA.oAMQ/EwIAQkAEAHpFVIAAPoH/vwPMAf+BwcgQAAD+wCDOAECWAD/AwMACgTsGRP2CAABBjxA/AEA8xAAAWMAYQDuAP7z+m0GEBcB.AgQ/Ag8EAPMEzwEExgECdxMABAAApgkACAAGBAANDwYCeAMCOQAABAADNAID7AMAfgES+dkHAA8ABQoAMP0AAPE7EPsIAgAQAAME.AAAbSgQjADAA+wYABgCyGQAABgETADEAAPvAaQHAAQH5DQH8AwIIHgAGJgAIAAAEDgJSAgBgBgEIABDvEiIACQAB/5MQ6CYAAg4A.DwQA6wa2AQ8EAAkGHwIFEgQPBAAHACACBCfMIP0Cy0UACgASAPRXAgsABUQKEeycBQA+DFH8A/4D/B5AASICACwiABsACQQAYfkC./fwD+wBuQfgGAPfiAQH4AQECAhD5CEwh9gAbhAAaAAEEBiAA8gIEAw8AAW0AAgQAAj8OAAoADwQA8QbgAQK3AQwQAA0EAAYgBBAA.3wcF8AELBAAC5QEAvxEA9jUBDAAA3QEBCAAxAPn18D8BJAAB6c0ABwIADQAFBAAA7auT+gT8A/kA+gb5NkgIBAAC/wMh+gcIAAAn.BgAIAAAAwgEEEBHzZwYDBAAAAFAVAy46CgIwDwQA1QTWAQSrAQAIAADYHQDoZwAQAADgPwAQAAFxCwHgFyAB/wSABLkDAKoBAJsR.AR8AAD0AEP0AQADAPwMoAjD9AAC+RwAMAAAEAKID/P///PwA/v0BJAAA+wEAgAGx//4A/wECAPz2/vK2PxD8awABWhAC5xkQ/CU4.AC0AMAAA+wAsANoBEvwNeEH8BQP7/gUwAwD3wQNA+P8D+QgAQPcIAPvPFSD2CNJPAAB8EPSuADAAAPJ/BgAEDALsIUABAOwCPhIR.+T8GDwQA/w8OCxAEBAAAuAEMHAAMEAAAsAMQ++KBANUBADEABBUAAQ4CRPPy8/J/EwEVAADyPwMIAAAJIkMBAPwFtw0jAPr1ZQcA.KA8EAAgR9AIAEfz/BQBVABEDBFAHZiQQ8FICAAkADwQA7wK0AQCQAQIIAAAQAAHgAw8EAAMd/Q8KDLUFAEEAAAgAAAQAAMERAPkV.A98BAAcAARAQBG8ACAQABFIGCEAAAAQAAAQGAAgAAAQAMPkCACkcAQUCAfQFAAoEAIAAAPw3AEAAEPYEBAAZAAEEAEHyAgDzawAA./wEACAADAFAPDyL+ASUBAf8BAwkAAwQAAu0BDw8CCA4EAAi/AQD/AQDxAyT8A1IGBwQANvPy8v8DEAEBvgAgMAI/AAD/AwAIAAT8.AQa4CQL4GQP+bQAEAAEPBAD/AQAIAATQGxD0WqYAPAAABhICAQYhAO9BBAAEABDrkAgACQAPBADpBPMBAecHAAkAAP0HApYLAqwB.ARAABg8AAAoAAAgAAgQAALxHAAgAAN4BAAgAAgQoAAoAAgQAAATAAPQHAP4FEP75CwQDSAHlBwB8ACH28hIUEP1IKBH+PgAQ/OAn.AA0CACgA4fsBAPsA/QP8/PwE+QD/KGIw+v7+Rh6gAPkB/AD7/QMF+LYgoP0FAPcAAQP6/QT6A2ED+f0FAPXyHwD+BQAsAhH881cw.AADvLDoDARQHDwQPBADwAFwBCOYBAgoAAgYADAQAACAAJwD+WI0CsCcGEAAA/A0CTQAByA8BBAAA9wUAHAADYAAB/Qdg+QAA7+/5.EAAAQAYA0xcB9QkCJCQB5QMENgAA6UkBCAAAPwAQAgsQAvQnAPkDANwpIvcBCTgACAADCTQA/i0QA/0HAP8DBP8bAVUAQe0BAAB1.DA8EAP8CAu0JALwBAA4AAf8DGgG2DwAgAAAIAA8EAAYCIQAAQwBQ/AD9/wF7BQDmAwHzAQAaAAUEACb68/kVALorAfcBAAA8AAgA.AAkGAAkEAhUGIQD6UAIACBoA9SMVBAMuBAQAIPgDBSQAAmYAfwAx9QH1NQoB/iMACQABBAAA/ksD/A0PBAD8AlwBDwQAAAwPAgQE.AAAaNgAIAAAEAAKlAw3eAQAEACD9/8IFAN4DAEoCABIACP8DEPuSBQAQAADvHQAWAAH5AwIJAAEEAAAYAAB8ACL6BP8BMPkF+R8C.ABsAQAD6/gH9GwEJXAEHCgcEAAJTCAECIDT0AgL+UQDyCQD+jUEAAADrsgQPBADeAEQBAAgAAH4BAAQADPQnAJ4XAAwAAAQABBAA.AAgACAQAATAAAw8EAAwAALMBAEwAAxMAAeAB8gL/AAD+BfwAAAX9AfkF+gD9BgUKAfYBAVwAAAkwUf8D/PL4rQkx/QX89CcBrisA./gUA5CdD/P4A/BgANPsG/gGMAQQAAAIyAIKYAQomAPcDAAyIQP0AAPbMnwGUAATsJwAWFgAlACAA8ZcAEvtkYAA/BgA5BgMpAA8E.AOkAkQEACAAPBAAXBF8BDwQABgIhAAHmAQGUoTH6APnlCQ5rADPu7vW5AwDoAwH8AzD8Av4MUgCdEQAYAA0EAAGzDwgAEAMJAAEA.FgD4FwGGAhD1AAoACQABAgQABABQ8QQAAPaJBgANADgAAPJOAg8EAOgDlAEBrQEBBAACEQAPEAAHDwQAAAChAwAIAAwEAAD7CQK0.JwHaAQREAAX8CwCLNxL3/wMQABocAPsTCkwAABYCABIAIPsGAAYAEgAg+gT4GQAKAAAEAAJcAAPDFwQicBD6/DsVAOgzAgICAPwJ.AWsAAP53AAIsAwwADwQA8wSbAQOYAQfvAQwQAAHdBQSPLwIEAAChAQIiEAIEAAD/AwYJDgCjAQAEAAAMAAEEAAAfAAAIAAAEACHu.7ZQBAhMAAP4LAAgOEAEtAgH4GQBaADH7Af3qOSH6BLoLEAANAAIAEiD5AwAsQPgA+gX5MQBCAAD/AwAIAAH8BRwAAAoBAGgACQAA.BAAAR24ACAAPBADZBJMBAtQBALQXAO8BAYQnAREAAOsPAPgXBCgAABAAAFwJAABAABAAAMMHAhAAA8EDAfgXAgsAAAQAABsCAMgP.AQwAUAL+AAL6NwwA9CcAy3EAFgAR/JIHAFgAdAMAAPPx9fP/ARD8cFgS/UsAAP8BAQYOAbQVAmkCQPr8/f9KBAG2BQD+BSH8A0sA.ANx/AP4DQPgHAPn6DyD3BwAOQfUA9ggABADsrwH0BRDyPAIAbQCJAgDvAAEA7QGTAg8EAOYDqSkACwAPBAACAhwKAAoADAQABvED.AKUDAAgAC0sAEf6tSwAdAADHCQLaAQAOAAElAAANAAOVDwEEAAAZAAsIAAD8EwGxA2L8APwE+wX4FxP6Ew4CBAAA9hUACAAMBAAy.9QD2AjJB9AEA+DFYAP4jAAIGAOGpHwL+BfcN/wEP8AEHAwQAAAMEAAgAAQQAASwABLMBBAQAARUABwQAABAAEfzrMwEhHgA/BAMk.HjDy8/WYAQALAAdjBgAGBgAIAAgEAAIpJAFRAgALBgP9CRH4ACIBCDQAxh8AKQQBDBwAHAAEBAAm9f5Hdg8EAP8GBHoBAqQDBooB.DhAADwQAAA//AQUCNQAAAgoMIgADBABC8/L285sJAO8DAvYBIfwB2hUAuwMBNgAA7AMCACYKBAAB+Bcg+AEAIgEMAgD/AQAYAAEH.CgPQMyD8AegdAkwEAGcCAQIGAQN8BwEcDwQA1wKQAQTTAQIIAAAEAAIOAALmAQGlAwYPAAEaEAGYAQHYAQB0AQGeAQH9BwAABgQc.AAAQAAAkCACvOwEUAFH+AAAD/fQjAcgjAewbAYkBAkAEAAQAUfYD/fT6MXgAJAIApwEAxn8AsBlRAgH+/v8gWCAABTUkEvuubwLo.nxD72j8BHAIBHQgANggACACgAPcE9wIA//39AAAYAHQOQPwA9gACsgBaYAMvAAAEABDwoAAEdwIPBADzAhoCAAYAAJgBAvoBABIA.Af8BAwoCARAABgQAAikAAAQAAcwNAU0CAA4ABwQAQP0A/f/2GQH4HQEhAAC2AQFAAgA7AmD5AOztAPwZKhH8+g0AGAAGqAUCLwAA./7kBMyJgAfwE/QD6HDoA/wEAIQAxAPkDAwYyAPkCCAAGBAAg9gH8KQIIygEECgAJAAEEACD2Av4DAHUOAA4ADwQA9QbfAQB2AQ7v.AQgQAAG/AQLNAwIKAAIRAAwQAAEzAADqAwHgiwD4AQHQAQMfAAEuAFD58+0A7doTAh4AASUCAR8AAPcJABIAABgAAPqbAQgAAv8B.AfwJIfoD+w0wAPgDvHUR+f0HEgcEJBD3nAwAPAABAQYR9QBAAQ8ARfMBAPNcAg8EAPwBrAEBBAABmAEH/wEC/wMGEAAEcjMHBAAA.IQAACAAEBAAHEAAA/wEACAAB2QEA7BUBDQAEBAAAfhMAAAQADAAACVoDCAAABwAjAPwLjAR6AAA9AADSBQAMAAMEAAEACBb5AAgB.+AcCADAE+iEAAFISBBa4AgAqABgAAP8XA2g0DwQA4QLiAQLAAwnwLwCRDwcPAAAFAggfAAP8GwEQAAIrAAMFAAEKCAULAAExAAD5.EQDXdwG4HwL9BQEcAAAEAAbhBUH67fvx4AEAEjQBD2ggAfzWNTL8AAUlAHD8BvwC+/3/ABgwAfz95acQ+hIYAAIMIPoD+1kAJgAA.AA4ACABw9wD4AP4A/WwWEPYrCAACPAAABgAaiIAA9AIA/vgA+3JgAFkAAwAgDwQA7gO1AQGFAQcEAAEQAAEFAAHOAQLoEwIQAAQE.AAM6AAXuBQYQAAEEAABxDQAaAAH9BwEEAADwBwAaAAAMAAAIAAF9JQGzAwEeAgpeAAD4HQAAGBD87QUGABYQBCwKEAK8AQG/AQS+.EQACAgUaIAL5CwL4KQICFAMKAAE5BjEAAPEaAABUDAAIAA8EAPICfAECBgAAnwECCgAGBAAIEAAAIAAEmKcBBAAA5CEMEAAC7AEQ./cArAOVPADQABCEAAAwAAew7YP3wAO3u/MgBANsBAGMAAPEbACsCAvwDAgsGAEACEPz7KVAB/QD8BAUGAQAQIPkEAHAQAcEbM/sC.+AhOAAQKAAU4AgAWEfb8GQMIAgDsCxD3UAAADQAyAADwRgACDQAPBADsAKsFAAgAAAQADO0HDBAAAvE9CfQfAiEAChAAAlMAAFIW.H/vSqwIALgBR/fsA7e6FASD8AugxAToAEPzNHQD8CREF/QEC8mUADwIBBwIA5AEC+yMA+wUCAAYwA/sB/gMAFAQA/w8AoC4A6x0A.+AUA/wEAbgADBAAQ9E88EQL+IwABCAATAA8EANsAlAEAegEADAAACAAAtAMArgEAGAACFAACuAEABAAPEAADAaQBBRAAADwAAGwL.ChAAASC4If4EvDMBv28Q/e8pAewTEfwQEAArAACkl1Dz7/b+9uoPEgRBABD88RkABQgACAAA+jcAOQIAPRAACQQRAnYAQvsE/P8F.AgDbJQAKOCD7/twJAdkHIvgE+EcA/AMiAPYXGAAEABD4/rMAAjIAExhyAPIBAPv1AGc4DwQA7ACTAQAIAA8EAAwAeQEACAAPBAAS.AAQCADICAs4RAP8BAtMLAGwAANIDAdwZAA0AUgDw7/T2pAsQ/EUCACUAAQiOADAGAbwBEfzqCQCpAQA5AAAAFAL6GwH4DQEJAAAK.GgAJAAEEAAD+AwAIAADkIwJWCBD1BCYACQAHBAAAAxQDCAgPBAD1BuABAZgBAWkDAQkAAMkDAMwBAQwAAgQAANUBAAgABQQAAQ8G.AAkADAQAAP0FAf8BAL8LAkAKACMEANrPAdUzFPDxJwDdAQIkAgMKAAAEAAIABjD7AP4AHgAgBgAbCAATRADxBwP3AQL7L2MA+AEA.+QECQAAUIAQFHgAEAABgAgAANhgBPd4f8f8B/y0IEgAACxAAzAkADAAABAABEAAENAAA0g8ApEUGRQAB/gMACQAAghMR8f8DAPUB.Ef1WCBH+KAABAh4AEAIB+hUACQADeAAAKQAg/AWyNwD4BxEA/xEgAfv4EwEPAgT/AxD3PG4C/jsBCQYS+AAYCGYcD/8B4QCCAQHQ.AQPYAQDwJwBXAQ/sNwcDEAAADQADggEApgEA4BcAIBgCHAACCEgABAAIEAAA6T8AsAMgA/mXBwJwAAFBAAH/AQFhAEHz/O/wnwEA.JAIANQIA9DcAKAAA/AkAZAAA+QEhBAEIOhD8XAAAAA4wAf0E/wFw+g/6AAfy+cA3APttAO9hEAEIFCD4BgAMAOOnAGIAAQ4CAFh4.AQKOIfT5voAg8gAACg8AAuENBAAF2REAdgECCAAAEAABngEBBAAP+wsAAAUAAwQAABwAASEAAA0ABBwAAQUAIQD/x7kiAPynBQAU.AAVsAAQEAGLzAO/wAPCQCwQaAADgAwAsDAEIAAPwDwIEAAAADAEVAAEEABH6AAwAABYAAwgQAgBQAeATEPgCFAICFgAnACD3ARkC.CgAQAP0HAv4PDwQA7gT2AQKdAwH/AQAJAAbvAQIYAAYQAAzDAQT0AQcEAAIQAAX/ARD9rAcB8wMAFwACMAACUQwBiRUAhA0A/gMA.FwAB5wEAF1wCACgA53kA9QEC/wECPgAAGQQFwwcAWgIA/wcCCgYB/BUC/AMSAOULARYAAV8EAQgGAQIGAXUAAQ4ADwQA+ALSFQX/.AQYEAAwQAAG+AQIJAA8EAAUA/wEg/wEOCDD9AP6IFQHJxQZaABD8Gg4B/wFA8/Pz8/8BAhQCABIAAQZ2APMDAOcBAPoHARoCEQFA.BgBYAAAbAAEIAAABBgEIAAFcAAEEACD7AgMgEgMAFAD+CQAIAAECEgA2AAAGAgYDBAgHCA8EANYAdAEEhgEACAAB/AcBegECyBEA.IAAAbwECCAAACgACmQEIEAAASAMBmAcAMQAA+McDxB8APggAoAcAIAAAEAAAHFAAxA8ArWMAOgAAuA8ABEAA1AEAH1AAcAJA7wP3.8so9AMFBAFwAANsRAGwAAPwBAAgAIAD8rlsA8F8hAPweaPAF+wD8CfwBBfj7AgQGA/0A8gD6AAYdFiD5AdcXAFMAEADMxWAA9wD4.Bfc3OAD5XxEBoAAAwAAAY2oA/RkAKQAAFggAFAAPBADqABkBAHkBAW0BAQQAAu0HAAoAAgQABKA5BgQAAyAAADsAAiwAAQUAAckV.AQkAAhUAAMAFEv3CCxD5/wECQQgADwAAyAEBbgJQAPYA7u6aAwALMAAaAA1QHAT8BwAIAAEKABABCgAgAPv+UQEABBD6uUMBABQB.9gUAABQAGhwD3AEg/QT0AwGEABAAYBIAAHoA+0kAAwIAIAAPBADuAIYBAB4BAJsBABAAAP4FABAAAgwAAAQAACIAAAgABQQABUwD.AAQAAbABBzEAAQsAAQUAALYBAQkAEPxZKwD8BwBkAAASAAD8IwAsBJEAAPb38fAA8QagAQAEAAEvAAAFAAQIAAD6BwEaCgIPAAQX.AAC2C2D7A/oDAPoACgD8EwH4BwT8CQCUACEA+AIUAPxREAJSDgEEBhX1BCoPAQj8AJsBAAgAAP8BAAgADxAABwGsAQEJAAUEAAwS.AAUQAFP9Af4D/fwLA0kAAMIBAHQGAQ4AYPb39u4C8RwEABEuAoAIEPxaDgAmAAINAAQECiL+ARsEQPsCAP1ENgIOGAAyGBD5/g8Q./PsREAAFABH4MAACDwIB+AEAXwAwAPwD/wECGgABAgoP/wHhAMUBAXgBA9cBAIgBAR4BA98BAAYAAv0FAAoAA/UBANEHAgoAARoA.AAkAAQ4AAEEAAhIAAmYBAch/AQD4AhAAALavIPwAkBkQ+gQGAvAHAGo3APw/AAwAAJ8LYPbu+vsC+6M9AkoAYAAAAAT8A+kPEQEI.KAAQAFD9/vz8AkcQAA8CEPuwAPEI+fsBAAUHAgbzA/0ACPoH+fz/+QP9AwH4JSD7A94PoPgAAwgA+P0A9wAMSAFcABAKAIAAiRR/.APUM9AD0DQEC4QwEAADEAQAdAQHRAQEEAAj/AQAEAAwQAAB/AQEIAAA7AAKqAwAhAAJQAgEsAAIFAAAoAADyFQChAwAMAAJyAgAb.AAHABQEuAED1BOzur38AMgAQ/PRdACoOAwAmEf3/AUP8AP0CAAQABgABOwACTQog+wQABAABBgBeBAFhBBH5/QUQBQAEAMTRAAEE.AAQEAwkIAv8FAEYAACwSAQAOBBoADwQA5gCGAQCTAQbfAQzvAQwQAAPLAQMEAAEMAAEFAAIEAAgPAgDAywGeHSIA+hMAAG0AAAgA.AAgEAQwAYPX78O4A7s0BAfIBAWUAEPzrBwD1GQATAAH6swAMDgDyCQEzAAItAAD8IQD/BVD6AwMA+duTAP4VEgQAJgD2ASAA+AkE.MPgA930CA+UBAAQWA/gvAAEOAAIGAxoADwQA7wF6AQEEAAJlAQ8QAAcE3gEHBAABlQcACQADBAACIQABmyFT/gP6AftYeQAnFgE9.AAHEAwAEADD1+/r/AQHfAwHsGwDmAwAcGgX/AQBADAAtNgG2AQAzAAD/AQElCAFFAAABHAFKOgAFkgAADAMAEgL/JwD+CQP8HxH6.BoAB/BMD/AkABAAP/wHYBMEBAs8BAtcBAPAfAWkBA98BAAYACO4DAAYACBAAAAoAAjAAAA4AAEIAAQwAAf+vAswLAfwHAbALAMwF.MPoAAG5vEALuJwO9twHrMwC/AQANAHH3Avbw+PoAsVcBSgBw/AAAAgT8AvwHAClQADgUIAEEsAcx/AAEFSAABiAAjQDg/AAFBfwA.9/4B/RT9B/leCjAH/AcHADIA/QL8BwCEABH3DAwR94IEAF8AAAQAAWgAAP85ABkCAwwADwQA5QCEAQHPAQBbAQARAACkAQ8QAAsE./wEC4CUI7QUABQABCwABmQMR/9k/AhwAEfq0EQL/AQQwAAAnEBD59RcQ+uwHAB06EQAuBhD8z5UA5TkQBCgAEf3oKQAACGH8BPwC./QMUMADCBQD/BQAQEhMG9ikA/hsBABAQ+QxyUgD4AfgCBlYDBRwAAygUAfsXAP4vAP0FAAwADwQA7gCOAQbfAQzvAQwQAAO+AQPw.JQEMAAEEAgAJAAMcAAPsARD9tQcByB0Q+tgBABMAANEFAyUAAD4AMvn69HgnAhQCAWUAAOYHAG8AAe4VEPw4BAAEBAAWAAAIAAHz.qRH+318ABQhQ+/sGAPv5DQACAgIAEBH5A7IC+hkABhIH/wGBAAD2DAAA+gEFAg//AfYABAABegEBBAAAlwEI7wEMEAAAlgEACAAH.EgABzwEHBAABzAcC+wcA2lMS/ZQJAS8CAQgCAAQSAiwGI/r8VpUA4wkCRgIB/AcC4AMA/AEACAABfgAAVQAAZQgAFR4AKAAABQgC.BAAgB/pJFgACagAdJAD4CwAgAAAMAgP/AQAIBgATAAAAGBD1CgYA/wEABAACFQAPBADSAEMBAAgAAXcBAZ4DIQAAwAUAeAMBYQEC.5QEI7gMABgAIEAAACgAG/wEA4E8BDAACCBQD+A8CyQMA5W8Q/RgAMP0C+rMPASxoAPAFAf8BAJABADQAcPgA9PD79fchAALVEUT8.AAAB/AcQBAaCEPwQAAEWBiACBBsSMPwABwkoAOTv8gkBBPz4APwABQAFAPwC+AAJ+Qf5/P76Av34DwAnZgH9BQBXAAD8BwD4ETAC.AArm5QCuAAEAFABnAAENAA8EAOQAhAEBrgEC3wEABAAI7wEABAAMEAAE3gEI/QUABQACyREGEAABzmkADAAAmBUCeBUAMQAAcgEB.IAAA7yVQ+QHv8ADkRwHqBQDxGQC7cwAMCAH/YQEJACD8BRQMwPwA/Ab8Af0E/AL8AgAGAPcDAEsAAAJSEAYCGACysQME+AL4AwDc.MwD/AQXiCQD3DwAABAAMAAAANABHAAAMAA8EAO0AjgEG3wEM7wEMEAABqQEBEgAAzgEAHAAA3gcCGgADHAABBQAB3SEw/gH9DQAB.wlECcQQAtAEAEwACUgBS+/XwAPCeAQLsDQAFAALfBQL8AQAABgBDCAT8BwAGAAAQBgEAghECsCsw+wT79Z8wAPoIAQgSA98hEPlp.GAD6BQADCAJhAAAEAED3C/YBGwgAARIAQgAAjgAAGAAPBADtAY0BAQQAAKQBAYABAA0AAyUGCBAAAKEBAAgABxIAAHABAAgABAQA.ARAAAv8BIAD96D0AkAMDSgAAcQEA/AcCPwAw9Pvw8icACwAA3w0AIwQQ/SgyAvwHAwA8An4AATkAAhokAQsoABAAAvwHAPybAAN6.APMPAAAQAO8FAgAQAPwHFAL+AwAEABH3+xMACgAB/wkAZQABDQAPBADPAEMBAAgAAYUBBdcBAAQAAK4BAh4AAAYACO4DAAYACBAA.AAoAAtYBBEEAAegPAOQHDRAAEAH4AQHkNwCLAQX8BwEEHgIAGACjBTDwAPpmdwD1QwI/AAAJMAH0F1ACBAD8/c3/EALsDQAECAA0.MGD8AAgAAvxTBPAFBgX7APgB/AAF+wX7/QL4Bg38Bvr5DyAH/P2/EfkAEBL/DFQB3zMgAveRkBEJCBQAAQ4gAQv+BwB1AA8EAOwA.1QEC3wEABAAI7wEABAAMEAACpAEG/wEEBQANEAABnSkB/wEE2AUAIgAIDAABZV0i7PwPIADT3QHbAwC9UwAMCAHPCxH9EwAABAQC.+C0w/QD9ABoAETIB+LEADTgABAQBAAYAZggBABBAAgD4AQAQEv4yeAL+AwcGAGH2DPUA9gsABA8EAO8AjwEG3wEM7wEMEAABDwAB.CQAABAABDQABBQACBAABwAsBEAAB6AER/gAKAeQ/APEBAPoDABcAAT80ACUAQPbxAOyiAQDLLwNlAADiBwI1AADtBwQABgD0BwAU.CBD++QEDHQAANQBA+wIA+wAeUPsFAPoL+RcA6JkA/UsANroAcQoACA4B8wEBBAAh9woMAAD8SQAEAAB7AAAQAA8EAO4BegEBBAAC.lwMPEAAHAHsBAQgABgQAAe8BBwQAANwHAPEPEACxNwEBAgB+BQJJAAAdBADsJwIOAED29wDsbKcAygEDZAAU/Bg6AOIBAecBAdtZ.APwBACw2ABgEASAAAFMAABkCAv6vAAYcIQX6r2Uh+gAIAAD2BQP31wADAgBbAAD8AwD/hRABAQgABAAP/wHYAEQBAnQBBNMBAgQA.AKMFBN8BAsgBA9wHAKkBAAgABJgHBBAABA0CAUUAARIAAdYNAlUABhAAMP8C+Z/fADQAAD8wAfEDALMPALwBAPwHACkAcfgA8gDu.9/etaQDLBQDJAQDbFwAAIACoKRD7/CEATQAACAAAiABw/AD8Cf0AAwQEMAYF/OKvIQAF5zsABBggAQYAEACqmzH1AvkAECD/AQEi.IAD4MxIAeSAG/AcCAg4P/gHXDwQABwGyAQHRAQEEABD9IF0ACQADBAAP7CcXAAUAAfoBABAAAVwxAgAIAMwLABMAADEAAAgAAAQA.Aj4AAGlLFvD4DwMIAAAZQgAKAAEIEAAtAAIIAAAKAAAEBgAaBAAWBAAcGAJlAAD/CwIAGAD5AyAA+QFoAfsdA/wHAAIEAggEAAAE.AHkAAAQmAAgADwQA9QbkAQGtBQAJAAMEAAGoAQYfAACgAQIIAAEEAACUAQgxAAALACH8Axw0AAsAALurAK8BASMAAEoAAAgAAMcD.AnAUYfYA9ADw8ZgBABkAAggAANgZAQkCATUACAQAACAAAfQFAA0AAf0ZALqbAAUcEPsCTFD/BfsAAXQEIAD62RcQ+cYEAP0RAQIE.ADcAYgAA9wr3AdVzAgQKDwQA9AbfAQBaAQPeBQEEAAGnAQcQAAaJAQUEAAARAADUDQAMAAAEAADLKQH7BwCEExL9AAQAGAAERQAB.8D0BWABB9vf683A/AK8BARwOATgAAO2BAAgEAOYPAT4AEAL0DQJUBgAECAD5AQIEAAT8AwIpBIAE/AX9BPkC/HgAAPs/AjIAAf4B.AB48AfgLBf4dA/hBDwQA0QR5AQF0AQSoBQMEAAEcAAEFAABpAQP8BQ8QAAQAEQAABAAADwABRAAAHAAD1DcABAACcAEBxVMAmw9A.AP4E+uEPEvwAZgAFAAAYEACWAwAwGADsJ0D37wL52gUBbAAAywEBNBAAHSgAWwAA8RsB0zMBAyQBBAwA6zsBsF9ACAABAPQXAM4B.AG0AAOYFkPkA/AX5AgIA9RUAwQAHAvMA+QAI+gAI9FoCAOZHMAkA8gwAAABqAN0AAFwADwQA8ADQAQAIAACGAQB4AQ8QAAUADAAA.BAAEQwIBDAABBQAA5wEALgABMwAALQ4AFgAAakUAtAEARAABoyMACQA0/AAB/HNw9gHt7wD5+cIHAC8AABMAAQgABZoBANUDAEEA.AAAOAOcDA/wHAfUDAg4CADMCARMkAB8AACkYAfdVAAIQEAf+BwL7SwFfBgf9BwACNhL2YgAPBADyBN8BBHcBDxAABwQSAAL/AQEE.AAIRAAgQABP/NQQAhQMAHAQA4CsCQwAA2QEI+A1S9+8A7wX/AQE6BABTFAEeEAA/AAAqzAAIDhD8ABQChAAA/AUDKAADBAIB9wEB.DAACCQAEAW4BDgQCXzYC+AFi+AEBAPcK/wEAfAAERQAPBADwAVsBAQQAAhIBDxAABwMSAALwGwAKAAIRAATRAQGIAQALAADiBQCg.AwG3QwAEAAVDAAAWEAHCAQT/AQG5KwJmBABNAAAaNiAA/AUeANBTAkgAAOQBBEEAAggAAPwLAPUDAv4DAXcAAUEAMvv/BAJaAAAa.AmcAAPgBEPsqBgD7AwD+AQEPAgD5DQEyAA8EAM8CMgECsQUABAACDgACBAAAHAAABAAA5AEEHAAGEAACIQEGEAAAoAEACgACTAAB.HgAAzwECDwABwgEABAAAlAEAmDEBor8C8QMGIQABOQYF/Ach7vehzwCyXzIA/QQgFAHoFQG/bxEE60kB8gUAUBQACAAASwoAWAJQ.CfwBAPj1EwBbIAAgBABRAAEIACABBEoKAAAQEPLPPwAeEAAcAAB/ABEBNnAy9wn4/QUDjwAPBADtAGoBAtUBAqIBAgoAAAYAAA4A.BBoAAgYAAhIAAs4BAQQAAhEABhAAAYoLAEcAAhkAAgEGAfQBAQkAARcGAv4BUQD08gDuoNEA2AEAHgAE7AcBBwAC/B8ARgAAPxAB.7wMAiwgBOgAAAQIB9k8CKQAABgYHCAAx+wIC+x8B+wUB+w9AAAD5CAIMEPiLAgACUgACNgCPAAEiAA8EAOwC2QECBgAAbwECCgAA.rRMADgAP/wEAAgkEAAoAAhEAB/wFAA8AAcwHIP7+6QEJ/gEACAAB5gUCCAoAb3kg7u4QAAAkABD+2AMAISYAiCEBEAIA8gEAPAAA.9BMAEAAw/AD/FSYAOwAAGA4B2YcBViwB+QEAFwAD4g0A/wk0+gAI+QEBFgAAOtIS+GUAAAEGAAQAAFQAACEADwQA7QLZAQGkAQBT.AQPpAQEQAAAJAAUPAATLAQMIBgELAAESAAb/AQDqCQCCAwG8BQDtHwQ0AAYhAAVKAlL0APT0+F5fIPoEklUA7AkB7AcQ/R8+AfBb.AAgKATICAUQGAUUgADAAAUkAAB8CAAgCAAICATACAXkEAP8XEQT3DwP/AQEWAAEMAAAEAAD9bQB4BgAaAAGZAA8EAM8AbgEEfwEA.CAAAdBMACAAAGAAFjQEA7QMAVQEPEAAFAAoAAhAAAf4BAMgvABkAABEAAP4BAFcDAx8AEP1kPwDtJQK9GQMAIAATyADDAQVWAmAA.8f/wAPPCmwDfLwD2AQC1CwAjHgCMvQAGGkAEAQP9LDADEAAAGwYBGQoRBA6qEAH6EUD9/gD/BHAAUDYQ+0QMABzoALNvIfQB4sMA./g0BT3QAcgAB3isCBQoAXzAADgAPBADiA4ABAwQAAMYBCOUBAgoAAf8BAA8ABxoAAwYAAP8BCDEAAP8BAQkABAUAAPMFApADALUD.ABQAEf/QAwAcAAP/AZL8BQDxAPAA8fIYAAHb0QIfAADVAwAKAAFFBAIEAAFMAAD+AQAKCgAkAAHkBwAEAAANAAAIAAAEAAAmsgAZ.AAHuAQPcFRD6gSoACQAi+QH4AQP9FwEFAA8EAPMCyAEBlwEATgEFDwAP4zEHAcEBAhgAB/kLAR8AABsCACYAAXx1AAMGAKQDASEA.AOkjAMwhAQ0AAKcBYfHyAPEA8rEVAC0AAOQBAfQLMAD8AAQMAegHAwAaADgAAAgAACgAAB8CAAg6AB8AAABEVPwAAfwBABgCOQgA.HvYBLxQCAQQABS4ACAAC9AECAwoACgAPBADyAscBAAQAAsUBDxAABwFxAQgRAAIgAgInAAIdAgAcAACsDwGCAwARAADoAQK3nQEh.AAIuAgGsCVD89vEB8mdLAPAJAy8AAAMGABwAAfQBBT8AAOEHAA0AAPUpAdUDAOILAhgCAEQeBSUAAPoLAgsYAMNlADdGAP8BAAKe.AfopAAQAAgkIA/pJDwQA2ACkAQAEAAAMAAAEAAAMAACsAQTOAQBrAQKBAQAOABAAX9cADwADHgAhAP7AEQQNAgA9AACQAQPYJwG6.AQOCAQC/AwCDAQDAtwCvAQFuAQHzAQDUGQAIAAIgFnEABO0A+fcBBSwBIwAh/QClhyH6/cuXAVIAACkAQPr+AP0w+ADtAQA84ABl.AADYEQDX5QIIAED9AAcA11MA9C8A3ScAtn9A/AT3/ksucAD6BwD6B/TnJyAAAFYoASoYAAASAhcEDwQA7wHQAQEEAAPhAQEEAAAW.AAoQAAAOAAAEAAQWBAEMAAEFAADQAQAJAAAEAADuAQCeBQAYAAD4BwOVQwAyAAAfAAAEAAI/AABQb1Du//UA9AJOABEAAswDAOYL.AUYCAO8BAeDJBDQcACAAAAgAAOgrAGACAOYFAAgAAG4AQQMAAfzzmwD7IwAZAAFCAAD9WwEACgP3AwIHAAECBgH4DQ8EAPIA6QEA.CAABZAEB6QEADgAAFgABrAEC7wMBBQAEIgAEwAEE9QMAEAACowEBWgUA0B8CFgYAzAEACAACRmMAIwATAe0ZALcDUPQA7u8FjQsA.yDEAFQAALQQALwAB/wEA0gcRANSPBOwRAPAXAT4AACQAAAUEDQQAAPYfAQggAPkXABEAALmbFPkAEAMHAABrBAEDAg8EAPID2QEA.BAABVwEDEAAA+AsIEAABBAABEQAB9w0BCQAC8gEB9wsAowEBLQAAewMAnwsAvQMQBPYJALoBBUQABfoHgQAA+fr67gDvaEcA9wEA.FQAA9QUAfgYA1gcG8BcA7SsAaAAAIgACSQAT/fEHABACBgQAEAFSPAL4RwCFAgAIADH7/QPqLQL4AQD/AQAWNAEFNAMECAEYAA8E.ANUEewEABAACSgEAsgEACAAG0wECGAABEAABdQEBEAABCgAC7gEAGAIgAQGwUQL9AwA4AACcEQC0dwD0AzAD+gCNcQErADD5AAH8.CyAA//0vALEBAEcAEgGDqWD3APIA+faCwQACHAAUAADuAQErBgDEDzH9BAQECAEsABD+WQACmAgA9DUA4AMBAQIAnAAAUggDBAAA.OAACFAgQAd4HAPbPcAP9BgEB+fQALCMA+vEBADYAD/0B4A8EAAICDAECBgABswEACQAAaAEC3QEHCgAEBgABwQMGFwAA/wEACQAA.fAMBBAQAKGUAjgEBoQEAGgABMQAB2AEAMAADNwByAPTzAO4A94YFAYsVBNwHAAcABgkAAFIAAAkAADoGAAQGAPQLAhwAAQBAAOwB.AB8AQAD8AAZsBAH7HwMFAABaAEAA+gP69gsA6QkABAAAKwoC/QkBHgAPBADuAsgBAAQAAWIDA+8BAd8JAGYBBhAABLcBARgEAxcA.ABEAA/8BAAsAApLbIP4BqRMCBCQBnOsACQABPAAABAAAIGQAnAFA9AD1AP0FAXxFAeIPAOAZAUACADQMANAJAFgAAAgAANAFAM1x.ACQCAFwGAuwXAB4ACAgAAREGAB8AAJAAAPQdAd8DEPxGYBP5AAoA+SkBCAYP/wH2AscBAAQAAuEVCRAABQ0EAgQAAGYBBxEAAi8C.AP4BAZoDAagHAjIAEPqKNwAdAAEiAAL0DwCdfwAfEgAMAACyAVD4APX29lK/Aaj9APIBAC0AAdMVAgQABdgBAeMBAF0AA3sAABoI.AOAJAPIFAAwEADAMAggAAQAEADgAAAQABt4FIfv/GwIAASAABQIE+wcGIQAPBADdA0kBAOMBAIoLDeQPDBAAAfQPBBAAAB0AABAA.ASIAABEAEf2sfwDPQQAXAAOdzQPIAwCc7wYxAAAAAgAIACACAdk5QfPw+vysWQAeAAFAEAAVNAC7AQDNCQD0AwPoLwD7DSP8B6ON.AAwIAC5EAOr/ADUQAN4hBggAUQH8BQT80iMB+xuhAPwA+AICAgABAdTJEvUCFgECBA/9AeYJBAABdgEFoAECBAAA5gEHEAAHkwME.FgQBDAABBQABQx0B+AcB9QEBPEUBGQAA0AEAwCERAAAGAAAMAEIAAT4AYAD5CADuANw7AKkVAFsAASwIARAaATwAADsSAWwCAOoD.AHoAABgIAAAGAAwGABIEASYIATMEAXYAAPQJA3YCAwcAA0YAAAYAAQQAAPxXA/sDBQcADwQA7gBiAQLUAwJ2AQAKAA8QAAMDEgAC.+QcACgACEQAQ/+QNAGgrAUoLABIAAfgHAbADAUYAABMAAC8AASAGEP+4RQAOAFH5AO4B7/IZABqQAEoAANYLANwHAuABAA4AAOw1.AP4bAX8AAGMAANszAAQGASIAADQAAFMAAQwAAAQAATICABsAAekFARIAAA8iARg6Af8RIPoA5IMAGAAP/gH7AAQAAtUBDxAABwFq.AQESAAIaAAAEAALEDwAkAACuAQBxAQMIAAGXawDwAQMsAAAjAAHaAwBAAAARAAGDnwL/AQETAAEoBgFkBBT9GDYQ/VgCAaAFAD4A.AEUCAAgAAWAAAA0AADIAEP3KBQE/SgIEAAA8DgBOAAHvPwA6ACAA/OodAgUGAA0WCPYDABgSAAgADwQA4gFLAQErAQGjAwIEAAGK.AQQLAAEGAAEhAAEKAAPcFwDiEQCkAwAMAADwAQA+AAL4BxH9SF8G+AcBRwAA9AkAtxcBqQEAGAAAOAAATwBi/gDyAPL3To0A9gsA.nRsAvgMAzA0ACAARA6uTAMQXAlICIwQDCAARAfAxAEsAAAgAAF0IABwQEPwAVgBxAAAWAkIFAP0E2wkA7j8AjAABAAIQ+/wBAA84.MAf5ABYCAK4EABgADwQA5gHdAQasAQP+AQEGAAGQJwEKAAIFAAMiAAIMAAELAAIRAAAGAAH4BwB4AQLwDwATAAAbAAAgAAIgBAM9.AAUNABEC5CdgAO769/gA8DMB9wMQAAZQAdTBAA4AATAiAAcEAORxAAgAANwXAGgAAV0CBAQAAFcAAAgABAQAAQcAACoAAfABABMA.AxYAAOITAP4nAAwAAQRUAAsCAA0ADwQA6ALMAQEEAABIAQn+AQCDAQEKAAIQAALAAQILAAEEAAHUDwIqDgAbAAFaywTwDwUgAAAa.AAAIAAEmAABIsQIECgFRUwD0DxDwdDsBVAAA7HcALgAABAAQACoUAagpEPpoBAEMHhH99CkBWAAANSIA5A0ADAAAEAoAFQACcwQF.6wEE/g0EBgABBAAR/PsPAfYJIvkHCwAPBADqAXgBAwQAAXcBAxEAANQVCxAAAGsBBAoAAQQAASAABP4BAodHAR4AAlYBAKgFAJYB.AAwAABYAAAgAAB4EAgwAoP0C/f/59QD19vDoLQASAAJFAAIEAAIYPAAMAABUBgAIAAH/AQERCgAgAAEVHACTZQDkhwB4BAEVAACB.AAXrAQD+AQARAAEMBAEeAAAWAAAJFAIVBAD/DwIKAA8EAO8AHgEABAAE3QEADAAABAAIEAAAs4EDsQ8AkAMACAABHQABuI8R+rFt.AKwFAHMBAIQBACAAAAQABAwAAEQAAEcAAfwDAJQBgAIA7gEA8fL7EwIAsA8SAOx3AJ4pAAgGADQAABAAAGQAAAgAADwAAGgCANQD.AAgGAN8XACgAAIMAACQAAQwQIAQAC3wA7BMhAATSHxEBAAoAPAAABgIALBBB+QEBAf8tIQf5WCAAaAIARAAPBADpAFgBAAgAA+4B.BKsBC/4BAQkAAJwtABAAAL8TAhYAAZQDAK8DAckBAJc5ABgAARsAAgQAAMoBAAgAAA0AAAwAAfgXEPc8zUDxAPLygdMDACYAxwUR./YxXARBKAQAMABsAAQgAABAKAEIAAGACAQgABAQAAQUAAAlSANs3AgIGAxkAAQ0AA90bAAsAI/wECwAB9wUAaAABDQAPBADwAS8B.A+4BAAQACBAAAgwAAQYAAREAAAoAASECASwzAQYUAEULAAkAAqwFAiUAAhcGAvwDADMAAA4AAAwAAfwNgfcB+PgC7gD25CcBLwAA./E0B0QsAl0EAvisANAAAEAAICAABYgIBShQA8AEAHgwB7gEACAYA4AEADQAADAAA4okA6AUAJQYj/ATzAQAsCAERAgBlIAD4FwAV.AA8EAPQAXAEAzQEADAAABAAIEAAADAAABAAEEQADiwEBJBYA9AEAFAAAXyMAEAAB6BcBxgcC1AEENAAEDAAAbwcAvgGC+QD4+u8B.APCcDQDJIQC/DQDDBwAeAAClAQEmbgERBgEiAAAEjgAACAAbAAHgLQsAEgAFABABsI0ADQAGGAIA9RsACQAARAAQ+2QEBA0AAP4J.AQgADwQA7wBNEwCkEQDAAQA5AQAEAAD0DQC6AQG3AQKYBwEKAAAUAABDAQEsAAH0BwDgAwIIAACXAwAgAAMgAgGBAQQEBAMMAAAL.AACUAwDyDwBlYwD/ARD9iwcAKAAAhqUAAgIC8A8Ama8R+VQIANAPAAAIBfgHA5AAAIkGAMcFAPwXMAUABPgHAQwAIAQA6FcAZhAA.DAgBZdAR+wQIAPEPAAAGEAFdPgD6BwGPAA8EAO4AoQEBpg0BqwEABAACZQEKBgADCQAABAAADwADiQEA5QEBCAADcQMAJgAATAIC.HQAADgAACAAGDQARBHkHANwtM/EA+ywGABIAAAgAAI8HADwCAAwAAAgAAOQBA2cAAOALAmEAAQ4AAgQAAAQoAFYAACQAABwaAwwA.AwUAAARgAQgAAPEPABMAAQYGAAguQAQA+wEICgAQAA8EAPMAagEBUwEBBAAAqAUAcHMBDAABBQAAIAAAkgECDAABXwEAGAAAUgEA.CAAATJMBCAAC6BcCwgUAmGUAVgIIDAACuAMg8gDORRDzNQwAHAABAAQACyQAlw8A0AsCAAQE8BcAMgAC+QUARAAAIQoAqgAGbwIA.BAAAFgAEDwAACAAC5gcA8AcCEgAA+FMACgABDQAAGwADDQAPBADzAWIBAQQAAqwBBQUAAHUBAwsAA/4BAQwAAEYBAJAXAIQBAAgA.AHIBAPQBAAQGAwgAAOwVAA8GAQwAACQAAEAAARgEMAD6+wACAEVrAJUdAOwVBAAECAgAAGkAAF8CAAgAAIIAAEAAAAACANQnAAwA.AsUBAC4AATQAAgkAAJkABQQABRMAAA0AAPYFAREAABwAAAgADwQA/wECiEUFBAABhAMACQAAxAEAGq0CDAAB4BcAFQIC9AcAl50A.OAAADAAAvwEAYAECDAAAlAMCLAAA3AcSA3I5EADgIUDxAPj45gEAwAcT/uRrABgKAPABAA0AAAgAAAAMAQgAA98BAE4AAMobACAE.AF4AACQCAfAPAhsMAQkKEgRDDAHwAQAgAAD5BwANAABYBgATAgAIDABwAgIYAABGAA8EAPMCLAECBAAAjAEABAAADAAANAEG3AEA.fhMBDAAR+6APAuAXAJ0BAB0AAKMBAggAAQQAAUIAAQUAABQCAAQAAmQAU/EA9QDw/gEAFgAASAIAGAAh/QB06QIyAAHwAQB8AAAI.AACqAQBoBADkBwAMAAJxAAEFAAHbCwHsNQApAAASAAMXAAMEAAMHAABCHAILAAAWBgIAAg8EAP4Q++QBAGAFAPgLALwfABAAAFcB.ADsRAQwAAIUBAwwCAzZhAosBAgsAACsAAZSLAL0BAZdpIAD+nxcDJjgBSwQQ+DbFEPPKUQAyAAB7OTD+AAAoGAAKAiL9AadnAOQB.AEQGACMAAEwAAPwLAeQBAEcAABEAAMkBAB0AAAQAANEBAGAAABwAAAgAAEEAACwAAAQAAFUAABRiAQQWAP8BA0gAADgADwQA/ABo.BQRXAQBLARD+LgcD7AEIDAAACwAACAAAKwAABAAADAAAMAAABAAA4QEAzgMAEBAECVQAGgIACQgAKABRAPj6APP4CwJrJwCLWxID.qocBdIkAlx8A8RsAFAAAxQUAlN0A0wEAaAAAzg8AUhAAXAAAEAAAzgEAYAAAEAAAfAAAmwIA5gEADAABEwIBVwAF9AMAFwAACAAB.BAAAOAAPBAD9AOIBAKQBACkBAyQBQfkGAPecMwAYAAA2LwIMAAIUCAIUAAEutQEJAAHgBwMYCAIEAALCAwIMAAFoGwH4BzDyAPZM.cwBYqwC7BwEHFAB8AABUAAAIAAA8DACEBADnAwDQAQBnBgAIAABNAADgBwAAEAAsAAAyCADkPwBAAABqAADUBQAsAAAoADEEAPxL.BgCYAAAUAAA0AAD4AwAkAAAUAA8EAP8CADABEf8ERQHHBQHIAQAwKQMYAAEUAAMMABH6TAEAoQEAOQADCCIANgAAJAAAKQABEAAB.DQACgAMCeAEw7wD2+AcAUVsC4AsATwABAAIAKwAAOAYARAAgAf0oDgPECQMFAADUCQBKAAGYAgEFAAD3BwASAAcMAAEsAAAQFgBy.AAIMAAA4BgIKAAEUAABAcgAPAA8EAP8DAHwDALgBADADAAgAAAQAAFMBAJwHAAwAACAAAFUDAAwAACQAAJgBABQAALADABQAABUE.ADAAAJwDABAAAAgAABAAABACAOwFIfMApIsBuGcAQAIAIAAAHAAAaAgA1AsAogEAyAMAPAAEOAAICAQAwQEAFQAAMiACDAAABgAB.IAAC4gEB6i0A17sCHAABDgAAMQACDwACBAAADAAPBAD/BQDMAQB8AQCZAwAQAAAMAAErqwJZ1QATAAUmNQAcAANfBwFWAQIQAAAE.ABH8kHUGEAABgQFi/QD1APf3AAIBFQAAkwcAc18gAgDAxQCbARL+0TUAMAoAIQAG+AEBCQAAIgAAcAAA7AcCEAAABQABDxICKQID.4wEACwAAJAgADAAABAAAEAAALgAADAAABAAADAAPBAD/BgCkAwAIAAG8AQBkrwAIAAHwBQBsAQLkBQAEAARxAQIEBAAgAAIQAAAG.AAAgAACWAQAIAABwAQEiAmAAAO39APADAgGQxwATAAA8AAPZARD99AkCCgAC4gEAlBUA/QUCIAAAegwC4C8AJ0gAUAAANQYgBACe.lwLpDzADAQQPZgHODwAcAAIAHgBMAABkBgCGAAATgAA8yABlAA8EAP8KAHABAugBAI4BADQJABYAAYcBAbwVBhwAAAUABAgAAPgJ.ACcCABwAAAwGABgAAuQTAgQAABevEPBmiQK0ZxD96B8BCgABBAAALgADBAAC9AMEDQACBgABBQABEgACyQEABMoA8BEBDgAA+yMC.9wMAIgAADAoADAACMwAAFwAABAAAUFYAPwAAFAAPBAD/DABMAwAIAABMAQAIAAI+AQAKAALpBQCQBQTYAQARAAAEAAAPAADcFQAU.AAAEAAAkAAMIAAAHABEAIdUQ7QcAAUpbASwMAOYBAigAEv4sEAA1AgBNAAIyAAD0BQEeAAPaAQBjAAMLAAACDgELAAAUAAAMGgAI.AAFuAAAYFABUCAAmAAIKBgL+BwAhAAAEAAIYAA8EAP8MASgBBJIrAAQAAREAAkgFAAoAAA8AAB8AAG8fABAAAHgBAAgABTAAAAQA.ACUAASwEwP0AAvv9/vrzAPQB7ToOAIwFBFEYAekHAQsAAAkaAMBfABYAABEAAckLAcMLAPwrAdjjARsAADkAAPQXBNQBAQUAAAQA.AAkAEQEQHhL+8gEE/gECBQAATwACQAAPBAD/EAFPAQDcJwBUAQI/AQISAANzAQCwAQToBQERAAKcWwDMLwPgEwH0GQDHAQEeAHDw.AADt+gD1y0EAa08BIgADSwACRgoCCwAQ/QAYA9cBEP39AwAJAAOMCAAPAAEoEgIfAAAGAgAXAAHUMQOnCgDuAQJQHAIQAAD+CQAI.AAAZMAAIYAEMAA8EAP8YAJAFAwgAAOwBAIANAPABAxAAAeABAx0AAAUAAQwCABAAAAgAABEAABkAAgQAEO/JORDvvQECM28CHgAA.XwAA9AUANAACBAAAFgACCQABBQABtwEIEAAFBgAQ/QAKAgsAABIAAfgBAQUAAhIAADgAARAIBrkCBAgADwQA/xcBSQEFYgEH1AEA.BwAB7QMEDQAABAAAIAAEEAACBQAEIgAAKn0Q8MI9AeQZAXkhACcAACQAAAECA+gJAKoDAAwCAeUDA9gJAB8AAA8AAEYAASUAAPIp.A2QAABwAAAgAAg4AAEJGAPR1AEc0AfoFABUAARQwAA0GBPgRDwQA/xoAQQEAWwEA0AkArB8AFAADEAAFBAAEFAAGDQACEAAADwAA.BABQAPz8/v0jkQD+AwGffwT9AQDMBwG+DwIFCAD9AQEYAADSJQDwBwB+AAIYAgIFAAMcAAILAAANAAIIAAIcCAHdAQJEDgEEAAEo.CABeAACeHAAdAAAEAAAkAA8EAP8aAMABBDgBAqIJBksFAA8AAvwLAeQHBfQHAOgvADgAABoAAIQHEfB5yVD1APMA+sxrAfwBA6cB.AgwAAQoAAdwJAAkAAA4AALxXANQBAAwAAfIBASgAAiYCAQQAAgAIAkQAAAyGAAQeAAwAABEAAIgAAKsIAwwAAa8AAAQEAnAWDwQA./x0ARQEBlj8B5AEEtwEABAABCQAAgAUA9wEC8AEBJAAGMw5RAADzC+/VHSDvBh/fAj4AAB8AAQQAANwFARIAAA0AADAAAaoBAPYV.AM4VAbwBBR8AAOAvAQsAAxQGABQAAA8AACEAABgAAAQAAiwABOgrA1EGABMAAhAADwQA/yMAQAUDCAAE1DEA5QMBhAMADwAAGAYC.FQABJAABBAACDgAgAPgW+xL6/QMT8CR5AdAdACQAAFgAACkCA0ACABwAAKYBAdAJAGgAAL0BAPQBAB4AAAwAAhYCAKIpACsAABIA.A+gHAAQAE/kSCAFNAAAJAAAVAAEpOgQMAg8EAP8nAegBAgACAb4nCAQIAAcAAvgDAgQAA8kBAITRAF1jEPvoDQD9AwDzBwD/AQLE.BQDOFQI/AgAQAADQBwAcGAAEAAG/AQC5NQHyFQAEAALNLQAkAADEBwA1AAIQGAA4CAEIAAAEAADkJQBYAgFQAgAQEAGIAAD5HwAF.BgAMAA8EAP8rAk4BBOgBApYBCAQIAQ8EAcgfAKABABIAAJwHAOoLEfoaywDaGwNAKANIeQALAAC+AQPMKwFRAAAgAAQAAhL3+gUA.HAAAByoBDgAAIAACzA8BBAgBmIMCDgACXAAABAAAGFIBQwABBAAP4Bf/Fg8EAAsClAEACgACCQABCAIACQAACAADYwcAENkA2AUA.EwAA2BcA8gEAxi0S/u4BAT91ACgAAEgCAwQAABgAAK8DAg0AA9kBAgwAAO4BAqAXAUwoANgXA2gAADsAADQCACcAABEAAFzjAAwA.ABwAABQIAAgABpoCBAgADwQA/ywAVAEAXAMABAAADAAA8AcABAYABBIEzAEA8AEAxR1T+gAA8gnYFTH3APFAOwECAgLpBQAKAAHK.AQCsAQANAAD3AQDnFwDlLwAs/QBOAADaPQPyYRD9DAAAOQACbAAAl1cB2xsDNRYASgACCwAA/AcB7gEBBQAABAAFCQAPBAD/LwD4.AQAIAACCAQF6BQOEDQJ+AQGIBxD7qC0A7ANT/ADzAPYAAgDzAQH8ASIA+zAgAQwAAvgPA0MAABEAEPvECQB2ZwANAAEUCgAwAAUE.CBD7aCYT/vQHAXynABMEAAwyAAQoAeYBEfsrMgFQAAEQAA/0B/8zBgQAAHABAAgAAPgFAAwAAGkBANAFAAgAAHwDAOQBAAtxAGqz.AAwABAgAADQABAgAASoCBxgAAAwKAAgAAAQAABwAABQCAAQABCAAAFwAAGxjBAwABDAAAuAHAgQAEP6V+QBcKAAbAgBFAADTnwIY.6gAfAA8EAP9QEuTQAQQEAACkAQAQAgAIAAEM0yPyAGDxACKJAKUBABAAYPUACwAA9UACADYAEgg5iyAAAzEEAKwRQfcAAAk+BANx.KAM3BgBYAAApAAAMAAM8BgAzBgAYCgHrAwITAA/4A/88BAQAALfyAAgAAGQBAIgBAAgAMQAA5ZgBAPgBAK4BAAgAAMADABQAACQA.APgBAOMfQAkAAPXwAQBAAAAYAATMAxAFMQAQAAAgABoAAuQBAAoAABcAAAQAAAwAAQAYBSUYABIAAggAAAQAABcEAOwBBAQAABgG.AiIADwQA/0AQ1AUABPRuA+wDBJQBAAwAABgAAAgAAx8AAQQABBAAAAulAPABAAwABBQACAQAADwAAAgABAQADCQAAAMCCCQAABAA.AAgADwQA/1oT1vQBAAwADAgACJwBDwQABQQsAA8EAA8C7gsACgAIBAAAaAIACAAPBAABDPgDD+wP/y4PBAABE9rsAwAMAAAIAA+k.AQEPBAAFAlRxAAoACgQAD6gBEQBsAAB5AA8sABEPBAD/SgDQEQAIAAQEAAAYewAIAAAEAA/cAxEIMAIAEBAACAAPBAARAQACDwQA.////cwy0AwiYAwwcAAwEAAAsAA8kAAEAGAAACAAPBAAJD/gF/24PBAD//////////////////wMA`.split(`.`).join(``);function Vn(e){let t=globalThis.atob(e),n=new Uint8Array(t.length);for(let e=0;e=e.length)throw Error(`[BAClickFX] Trail texture LZ4 length overflow`);r=e[t.offset++],n+=r}return n}function Un(e,t){let n=new Uint8Array(t),r={offset:0},i=0;for(;r.offset>4;if(a===15&&(a+=Hn(e,r)),r.offset+a>e.length||i+a>n.length)throw Error(`[BAClickFX] Trail texture LZ4 literal overflow`);if(n.set(e.subarray(r.offset,r.offset+a),i),r.offset+=a,i+=a,r.offset===e.length)break;if(r.offset+2>e.length)throw Error(`[BAClickFX] Trail texture LZ4 offset overflow`);let o=e[r.offset]|e[r.offset+1]<<8;if(r.offset+=2,o<=0||o>i)throw Error(`[BAClickFX] Trail texture LZ4 offset is invalid`);let s=(t&15)+4;if((t&15)==15&&(s+=Hn(e,r)),i+s>n.length)throw Error(`[BAClickFX] Trail texture LZ4 match overflow`);let c=i-o;for(let e=0;e=n?i[o-n]:0,c=e>0?i[o-a]:0,l=e>0&&t>=n?i[o-a-n]:0;i[o]=r[o]+Wn(s,c,l)&255}return i}var Kn=Gn(zn,Ln,In),qn=Gn(Bn,Rn,1);function Jn(e,t){let n=512*512,r=new Uint8Array(n*4);for(let i=0;i= 0.0; + } + + return sqrt(minimumSquaredDistance) * (inside ? -1.0 : 1.0); +} + +float sdRoundedTriangle(vec2 point, float roundness) +{ + if (roundness >= 1.0) + { + return length(point) - 1.0; + } + + float triangleScale = max(1.0 - roundness, 0.000001); + + // 缩小真实图集三角与圆盘的 Minkowski 和只磨圆角,仍保留直边。 + return sdTriangle(point / triangleScale) * + triangleScale - roundness; +} + +void main() +{ + float roundness = u_roundTriangle + ? clamp(v_coverageFactor, 0.0, 1.0) + : 0.0; + vec2 sampleUv = v_uv; + + if (u_roundTriangle) + { + sampleUv = (v_uv * 2.0 - 1.0) / + (1.0 + 1.16465 * roundness) * 0.5 + 0.5; + } + + vec4 sampleColor = texture(u_texture, sampleUv); + float particleAlpha = clamp(v_particleAlpha, 0.0, 1.0); + float geometryCoverage = 1.0; + vec2 point = v_uv * 2.0 - 1.0; + float distance = sdRoundedTriangle(point, roundness); + float footprint = max(fwidth(distance), 0.000001); + float roundedCoverage = 1.0 - smoothstep( + -footprint, + footprint, + distance + ); + + if (u_roundTriangle && roundness > 0.0) + { + float textureSupport = clamp(sampleColor.a, 0.0, 1.0); + vec3 supportedRgb = mix(vec3(1.0), sampleColor.rgb, textureSupport); + vec3 shapeRgb = mix(supportedRgb, vec3(1.0), roundness); + + // 正数圆角只有一条 Coverage 边界;RGB 在透明区向材质色外推, + // 再随比例淡化纹理细节,避免形成“圆里套三角”的暗边。 + sampleColor = vec4(shapeRgb, roundedCoverage); + } + + if (u_transparentOverlay && u_antialiasGeometryCoverage) + { + float edgeDistance = min(v_uv.y, 1.0 - v_uv.y); + float halfPixelFootprint = max(fwidth(v_uv.y) * 0.5, 0.000001); + + geometryCoverage = smoothstep(0.0, halfPixelFootprint, edgeDistance); + } + + float coverageFactor = u_roundTriangle + ? 1.0 + : clamp(v_coverageFactor, 0.0, 1.0); + float coverage = sampleColor.a * particleAlpha * + coverageFactor * geometryCoverage; + // sRGB 纹理采样会自动把 RGB 解码到线性空间。 + vec3 emission = sampleColor.rgb * + max(v_materialColor, vec3(0.0)) * + (u_alphaModulatesEmission ? coverage : particleAlpha); + float outputAlpha = u_transparentOverlay ? coverage : 1.0; + + outColor = vec4(emission, outputAlpha); +} +`,pr=`#version 300 es +precision highp float; + +layout(location = 0) in vec2 a_position; +layout(location = 1) in vec2 a_uv; +layout(location = 2) in vec3 a_materialColor; +layout(location = 3) in float a_particleAlpha; + +uniform vec2 u_displaySize; + +out vec2 v_uv; +out vec3 v_materialColor; +out float v_particleAlpha; + +void main() +{ + vec2 normalized = a_position / u_displaySize; + gl_Position = vec4( + normalized.x * 2.0 - 1.0, + 1.0 - normalized.y * 2.0, + 0.0, + 1.0 + ); + v_uv = a_uv; + v_materialColor = a_materialColor; + v_particleAlpha = a_particleAlpha; +} +`,mr=`#version 300 es +precision highp float; + +uniform sampler2D u_texture; +uniform float u_emissionScale; + +in vec2 v_uv; +in vec3 v_materialColor; +in float v_particleAlpha; +out vec4 outColor; + +void main() +{ + vec4 sampleColor = texture(u_texture, v_uv); + // Cross2 的 _RGBRGBA=0 读取线性 R 作为透明度,原图 A 恒为 1。 + float textureAlpha = sampleColor.r; + vec3 color = sampleColor.rgb * + max(v_materialColor, vec3(0.0)) * textureAlpha * + max(u_emissionScale, 0.0); + // 生命周期 Alpha 只控制目标颜色衰减,不能再次乘入源 RGB。 + float alpha = textureAlpha * clamp(v_particleAlpha, 0.0, 1.0); + + outColor = vec4( + color, + clamp(alpha, 0.0, 1.0) + ); +} +`,hr=`#version 300 es +precision highp float; + +layout(location = 0) in vec2 a_position; +layout(location = 1) in vec2 a_uv; +layout(location = 2) in vec3 a_materialColor; +layout(location = 3) in float a_dissolveThreshold; +layout(location = 4) in float a_coverageOpacity; + +uniform vec2 u_displaySize; + +out vec2 v_uv; +out vec3 v_materialColor; +out float v_dissolveThreshold; +out float v_coverageOpacity; + +void main() +{ + vec2 normalized = a_position / u_displaySize; + gl_Position = vec4( + normalized.x * 2.0 - 1.0, + 1.0 - normalized.y * 2.0, + 0.0, + 1.0 + ); + v_uv = a_uv; + v_materialColor = a_materialColor; + v_dissolveThreshold = a_dissolveThreshold; + v_coverageOpacity = a_coverageOpacity; +} +`,gr=`#version 300 es +precision highp float; + +in vec2 v_uv; +in vec3 v_materialColor; +in float v_dissolveThreshold; +in float v_coverageOpacity; + +uniform sampler2D u_texture; +uniform bool u_transparentOverlay; +uniform float u_emissionScale; + +out vec4 outColor; + +void main() +{ + // Unity 在片元阶段以 Bilinear + Clamp 采样 Ring3,而不是插值顶点 Alpha。 + float textureAlpha = texture(u_texture, v_uv).r; + + // Unity clip(alpha - threshold) 是硬裁剪,通过的片元保留原纹理 Alpha。 + if (textureAlpha < v_dissolveThreshold) + { + discard; + } + + textureAlpha = clamp(textureAlpha, 0.0, 1.0); + vec3 materialColor = max(v_materialColor, vec3(0.0)) * + max(u_emissionScale, 0.0); + + if (u_transparentOverlay) + { + // RGB 预乘纹理 Alpha 后改用 One/One,结果与 Unity SrcAlpha/One 相同。 + outColor = vec4( + materialColor * textureAlpha, + textureAlpha * clamp(v_coverageOpacity, 0.0, 1.0) + ); + return; + } + + outColor = vec4(materialColor, textureAlpha); +} +`,_r=`#version 300 es +precision highp float; + +uniform sampler2D u_source; +uniform vec2 u_sourceTexel; + +in vec2 v_uv; +out vec4 outColor; + +void main() +{ + vec4 sampleSum = + texture(u_source, v_uv + u_sourceTexel * vec2(-1.0, -1.0)) + + texture(u_source, v_uv + u_sourceTexel * vec2(1.0, -1.0)) + + texture(u_source, v_uv + u_sourceTexel * vec2(-1.0, 1.0)) + + texture(u_source, v_uv + u_sourceTexel * vec2(1.0, 1.0)); + vec4 filtered = sampleSum * 0.25; + + // Alpha 是 HDR 传输上界,必须与 RGB 使用同一线性核且保留大于 1 的值。 + outColor = filtered; +} +`,vr=`#version 300 es +precision highp float; + +uniform sampler2D u_scene; + +in vec2 v_uv; +out vec4 outColor; + +void main() +{ + vec4 scene = texture(u_scene, v_uv); + float coverage = clamp(scene.a, 0.0, 1.0); + float capacity = coverage <= 0.04045 + ? coverage / 12.92 + : pow((coverage + 0.055) / 1.055, 2.4); + float maximumEnergy = max(max(scene.r, scene.g), scene.b); + float scale = min(1.0, capacity / max(maximumEnergy, 0.000001)); + + // 只把清晰 Scene 收敛到 authored Coverage 的预乘容量;原 HDR Scene + // 仍保留在 sourceTarget,供 Bloom Prefilter 与已知背景精确合成使用。 + outColor = vec4(scene.rgb * scale, coverage); +} +`,yr=`#version 300 es +precision highp float; + +uniform sampler2D u_accumulatedCoarse; +uniform sampler2D u_currentFine; +uniform vec2 u_accumulatedCoarseTexel; +uniform float u_sampleScale; + +in vec2 v_uv; +out vec4 outColor; + +vec4 sampleBox(sampler2D source, vec2 uv, vec2 offset) +{ + return ( + texture(source, uv + vec2(-offset.x, -offset.y)) + + texture(source, uv + vec2(offset.x, -offset.y)) + + texture(source, uv + vec2(-offset.x, offset.y)) + + texture(source, uv + vec2(offset.x, offset.y)) + ) * 0.25; +} + +void main() +{ + vec2 offset = u_accumulatedCoarseTexel * (u_sampleScale * 0.5); + vec4 accumulatedCoarse = sampleBox(u_accumulatedCoarse, v_uv, offset); + vec4 currentFine = texture(u_currentFine, v_uv); + + // Unity 对 lastMip(累计粗级)继续扩散,再单点加当前细级。 + // RGB 与传输上界必须走完全相同的加法链,避免透明合成改变光晕轮廓。 + outColor = accumulatedCoarse + currentFine; +} +`,br=`#version 300 es +precision highp float; + +uniform sampler2D u_scene; +uniform sampler2D u_sceneEnergy; +uniform sampler2D u_bloom; +uniform sampler2D u_background; +uniform vec2 u_bloomTexel; +uniform float u_sampleScale; +uniform float u_intensity; +uniform float u_overlayAlphaLimit; +uniform float u_opacity; +uniform bool u_hasScene; +uniform bool u_hasBackground; +uniform bool u_transparentOverlay; +uniform bool u_visualMaxAlpha; +uniform bool u_brightUnknownBackground; +uniform bool u_hostAdditive; + +in vec2 v_uv; +out vec4 outColor; + +float linearToSrgb(float value) +{ + float linear = clamp(value, 0.0, 1.0); + + if (linear <= 0.0031308) + { + return linear * 12.92; + } + + return 1.055 * pow(linear, 1.0 / 2.4) - 0.055; +} + +float solveOverlayAlpha(float background, float target) +{ + if (target > background) + { + return (target - background) / max(1.0 - background, 0.000001); + } + + if (target < background) + { + return (background - target) / max(background, 0.000001); + } + + return 0.0; +} + +void main() +{ + vec2 offset = u_bloomTexel * (u_sampleScale * 0.5); + vec4 bloom = + texture(u_bloom, v_uv + vec2(-offset.x, -offset.y)) + + texture(u_bloom, v_uv + vec2(offset.x, -offset.y)) + + texture(u_bloom, v_uv + vec2(-offset.x, offset.y)) + + texture(u_bloom, v_uv + vec2(offset.x, offset.y)); + vec4 scene = u_hasScene + ? texture(u_scene, v_uv) + : vec4(0.0); + vec4 sceneEnergy = u_hasScene + ? texture(u_sceneEnergy, v_uv) + : vec4(0.0); + vec4 filteredBloom = bloom * 0.25; + vec3 sceneLinear = scene.rgb; + + if (u_transparentOverlay && u_visualMaxAlpha && !u_hostAdditive && u_hasScene) + { + // visual-max 要恢复 v1.2.15 的颜色保留,必须读取未提前按 Coverage + // 收敛的清晰发射;sceneOverlay 只供默认 Coverage 合同使用。 + sceneLinear = sceneEnergy.rgb; + } + + vec3 linear = sceneLinear + + filteredBloom.rgb * max(0.0, u_intensity); + vec3 srgb = vec3( + linearToSrgb(linear.r), + linearToSrgb(linear.g), + linearToSrgb(linear.b) + ); + + if (u_hasBackground) + { + vec3 backgroundLinear = texture(u_background, v_uv).rgb; + vec3 backgroundSrgb = vec3( + linearToSrgb(backgroundLinear.r), + linearToSrgb(backgroundLinear.g), + linearToSrgb(backgroundLinear.b) + ); + vec3 difference = abs(srgb - backgroundSrgb); + + if (max(max(difference.r, difference.g), difference.b) <= 0.00001) + { + outColor = vec4(0.0); + return; + } + + // 求满足 target = premultiplied + background * (1 - alpha) 的最小 + // source-over Alpha;这样 DOM 背景保持可交互,同时逐像素等于 Unity 输出。 + vec3 channelAlpha = vec3( + solveOverlayAlpha(backgroundSrgb.r, srgb.r), + solveOverlayAlpha(backgroundSrgb.g, srgb.g), + solveOverlayAlpha(backgroundSrgb.b, srgb.b) + ); + float overlayAlpha = clamp( + max(max(channelAlpha.r, channelAlpha.g), channelAlpha.b), + 0.0, + 1.0 + ); + vec3 premultiplied = srgb - backgroundSrgb * (1.0 - overlayAlpha); + + outColor = vec4( + clamp(premultiplied, vec3(0.0), vec3(overlayAlpha)), + overlayAlpha + ); + return; + } + + if (u_transparentOverlay) + { + float sceneCoverage = u_hasScene + ? clamp(scene.a, 0.0, 1.0) + : 0.0; + float bloomTransportAlpha = linearToSrgb( + max(0.0, filteredBloom.a) * max(0.0, u_intensity) + ); + float requestedAlpha = u_visualMaxAlpha + ? max(sceneCoverage, bloomTransportAlpha) + : sceneCoverage + bloomTransportAlpha; + // Canvas lighter 与默认帧缓冲都会先把累计 Alpha 饱和到 1。Bloom + // 强度较高时 requestedAlpha 可大于 1;继续用未饱和值归一化会在 + // 预乘容量已经充足时额外压暗 RGB,并与 Canvas 回退产生跳变。 + float transportCapacity = min(requestedAlpha, 1.0); + + if (u_hostAdditive) + { + // CSS/原生宿主使用 One/One 加色时不会以源 Alpha 衰减背景。Alpha + // 仅承担浏览器预乘传输,至少覆盖 RGB,不能再反向限制发射能量。 + float maximumSrgb = max(max(srgb.r, srgb.g), srgb.b); + float transportAlpha = clamp( + max(maximumSrgb, transportCapacity), + 0.0, + 1.0 + ); + + if (transportAlpha <= 0.00001) + { + outColor = vec4(0.0); + return; + } + + outColor = vec4(srgb, transportAlpha); + return; + } + + float alpha = min( + transportCapacity, + clamp(u_overlayAlphaLimit, 0.0, 1.0) + ); + + if (alpha <= 0.00001) + { + outColor = vec4(0.0); + return; + } + + // 默认合同按独立传输和收敛;visual-max 只在最后一步读取 maxRGB + // 约束预乘容量,不能用颜色反向生成 Coverage Alpha。 + float maximumSrgb = max(max(srgb.r, srgb.g), srgb.b); + float capacityScale = u_visualMaxAlpha + ? min(1.0, alpha / max(maximumSrgb, 0.000001)) + : min(1.0, alpha / max(transportCapacity, 0.000001)); + + vec3 premultiplied = srgb * capacityScale; + + if (u_brightUnknownBackground) + { + float safeOpacity = max(u_opacity, 0.000001); + float normalizedCoverage = clamp(alpha / safeOpacity, 0.0, 1.0); + float maximumPremultiplied = max( + max(premultiplied.r, premultiplied.g), + premultiplied.b + ); + float normalizedEnergy = maximumPremultiplied / safeOpacity; + float energyRatio = normalizedEnergy / + max(normalizedCoverage, 0.000001); + float gate = smoothstep(0.25, 0.75, energyRatio) * + smoothstep(0.03125, 0.25, normalizedEnergy); + + // 聚合后只混合一次;峰值不增加,蓝青核心不会再坍缩成纯白。 + premultiplied = mix( + premultiplied, + vec3(maximumPremultiplied), + 0.35 * gate + ); + } + + outColor = vec4(premultiplied, alpha); + return; + } + + float maximumSrgb = max(max(srgb.r, srgb.g), srgb.b); + // Bloom 会扩散到 Cross2 Coverage 之外。无场景背景可用于精确反解时, + // Alpha 至少要覆盖发光 RGB,避免透明桌面合成出现非法的 RGB > Alpha。 + float alpha = u_hasScene + ? max(clamp(scene.a, 0.0, 1.0), maximumSrgb) + : maximumSrgb; + + if (maximumSrgb <= 0.00001 && alpha <= 0.00001) + { + outColor = vec4(0.0); + return; + } + + // WebGL Canvas 以预乘 Alpha 交给页面合成器。 + outColor = vec4(srgb, alpha); +} +`;function H(e,t,n){return Math.max(t,Math.min(n,e))}function xr(e){if(!e)return null;let t,n;try{t=e.naturalWidth??e.videoWidth??e.displayWidth??e.width,n=e.naturalHeight??e.videoHeight??e.displayHeight??e.height}catch{return null}return!Number.isFinite(t)||!Number.isFinite(n)||t<=0||n<=0?null:{width:t,height:n}}function Sr(e,t,n,r){let i=H(n,.1,.75),a=Math.max(1,Math.floor(e*i),Math.floor(t*i)),o=Math.log2(a)+Math.min(Math.max(0,r),10)-10;return{levelCount:H(Math.floor(o),1,nr),sampleScale:.5+o-Math.floor(o)}}function Cr(e,t,n){let r=e.createShader(t);if(!r)throw Error(`WebGL2 无法创建 Shader`);if(e.shaderSource(r,n),e.compileShader(r),!e.getShaderParameter(r,e.COMPILE_STATUS)){let t=e.getShaderInfoLog(r)||`未知 Shader 编译错误`;throw e.deleteShader(r),Error(t)}return r}function wr(e,t,n){let r=null,i=null,a=null;try{if(r=Cr(e,e.VERTEX_SHADER,t),i=Cr(e,e.FRAGMENT_SHADER,n),a=e.createProgram(),!a)throw Error(`WebGL2 无法创建 Program`);if(e.attachShader(a,r),e.attachShader(a,i),e.linkProgram(a),!e.getProgramParameter(a,e.LINK_STATUS))throw Error(e.getProgramInfoLog(a)||`未知 Program 链接错误`);return a}catch(t){throw e.deleteProgram(a),t}finally{e.deleteShader(r),e.deleteShader(i)}}function U(e,t){t&&(e.deleteFramebuffer(t.framebuffer),e.deleteTexture(t.texture))}var Tr=class{get hasSceneBackground(){return this.sceneBackgroundSource!==null}constructor(e,t={}){this.canvas=e,this.sceneEnabled=!0,this.gl=null,this.available=!1,this.contextLost=!1,this.displayWidth=1,this.displayHeight=1,this.sourceWidth=0,this.sourceHeight=0,this.width=0,this.height=0,this.dpr=1,this.resolutionScale=0,this.diffusion=0,this.sampleScale=1,this.maximumTextureSize=0,this.maximumViewportWidth=0,this.maximumViewportHeight=0,this.vertexCount=0,this.vertexData=new Float32Array(tr*Xn),this.sceneDiskVertexCount=0,this.sceneDiskVertexData=new Float32Array(tr*Zn),this.ringVertexCount=0,this.ringVertexData=new Float32Array(tr*Qn),this.triangleVertexCount=0,this.triangleVertexData=new Float32Array(tr*$n),this.trailVertexCount=0,this.trailVertexData=new Float32Array(tr*er),this.sourceTarget=null,this.bloomSourceTarget=null,this.sceneOverlayTarget=null,this.levels=[],this.sceneFrameReady=!1,this.bloomSourceFrameReady=!1,this.sceneOverlayFrameReady=!1,this.sceneBackgroundFrameReady=!1,this.sceneBackgroundSource=null,this.sceneBackgroundWidth=0,this.sceneBackgroundHeight=0,this.sceneBackgroundUploadRetryPending=!1,this.sceneBackgroundTexture=null,this.sceneBackgroundTarget=null,this.failedResizeSignature=null,this.programs=null,this.emissionBuffer=null,this.emissionVao=null,this.sceneDiskBuffer=null,this.sceneDiskVao=null,this.ringBuffer=null,this.ringVao=null,this.ringTexture=null,this.triangleBuffer=null,this.triangleVao=null,this.triangleTexture=null,this.triangleOverlayTexture=null,this.trailTexture=null,this.circleTexture=null,this.fullscreenVao=null,this.stats={vertexCount:0,sceneVertexCount:0,sceneDiskVertexCount:0,sceneRingVertexCount:0,sceneTriangleVertexCount:0,sceneTrailVertexCount:0,diskVertexCount:0,ringVertexCount:0,triangleVertexCount:0,trailVertexCount:0,levelCount:0,bloomPixels:0},this._onContextLost=this._handleContextLost.bind(this),this._onContextRestored=this._handleContextRestored.bind(this),t.initialize!==!1&&(this.canvas?.addEventListener?.(`webglcontextlost`,this._onContextLost),this.canvas?.addEventListener?.(`webglcontextrestored`,this._onContextRestored),this._initialize())}_initialize(){try{let e=this.canvas?.getContext?.(`webgl2`,{alpha:!0,antialias:!1,depth:!1,stencil:!1,premultipliedAlpha:!0,preserveDrawingBuffer:!1,powerPreference:`high-performance`});if(!e||!e.getExtension(`EXT_color_buffer_float`)){this.available=!1;return}this.gl=e,this.maximumTextureSize=e.getParameter(e.MAX_TEXTURE_SIZE);let t=e.getParameter(e.MAX_VIEWPORT_DIMS);if(this.maximumViewportWidth=t?.[0]??this.maximumTextureSize,this.maximumViewportHeight=t?.[1]??this.maximumTextureSize,this.maximumTextureSize<=0||this.maximumViewportWidth<=0||this.maximumViewportHeight<=0)throw Error(`WebGL2 无法查询纹理或视口尺寸上限`);if(this.programs={},this.programs.emission=wr(e,ar,or),this.programs.scene=this.sceneEnabled?wr(e,ar,lr):null,this.programs.sceneDisk=wr(e,pr,mr),this.programs.dissolveRing=wr(e,hr,gr),this.programs.triangle=wr(e,dr,fr),this.programs.sceneBackground=wr(e,sr,ur),this.programs.sceneOverlay=wr(e,sr,vr),this.programs.prefilter=wr(e,sr,cr),this.programs.downsample=wr(e,sr,_r),this.programs.upsample=wr(e,sr,yr),this.programs.final=wr(e,sr,br),this.emissionBuffer=e.createBuffer(),this.emissionVao=e.createVertexArray(),this.sceneDiskBuffer=e.createBuffer(),this.sceneDiskVao=e.createVertexArray(),this.ringBuffer=e.createBuffer(),this.ringVao=e.createVertexArray(),this.ringTexture=e.createTexture(),this.triangleBuffer=e.createBuffer(),this.triangleVao=e.createVertexArray(),this.triangleTexture=e.createTexture(),this.triangleOverlayTexture=e.createTexture(),this.trailTexture=e.createTexture(),this.circleTexture=e.createTexture(),this.fullscreenVao=e.createVertexArray(),!this.emissionBuffer||!this.emissionVao||!this.fullscreenVao||!this.sceneDiskBuffer||!this.sceneDiskVao||!this.ringBuffer||!this.ringVao||!this.ringTexture||!this.triangleBuffer||!this.triangleVao||!this.triangleTexture||!this.triangleOverlayTexture||!this.trailTexture||!this.circleTexture)throw Error(`WebGL2 无法创建几何缓冲`);e.bindVertexArray(this.emissionVao),e.bindBuffer(e.ARRAY_BUFFER,this.emissionBuffer);let n=Xn*Float32Array.BYTES_PER_ELEMENT;e.enableVertexAttribArray(0),e.vertexAttribPointer(0,2,e.FLOAT,!1,n,0),e.enableVertexAttribArray(1),e.vertexAttribPointer(1,3,e.FLOAT,!1,n,2*Float32Array.BYTES_PER_ELEMENT),e.enableVertexAttribArray(2),e.vertexAttribPointer(2,1,e.FLOAT,!1,n,5*Float32Array.BYTES_PER_ELEMENT),e.bindVertexArray(null),e.bindBuffer(e.ARRAY_BUFFER,null),e.bindVertexArray(this.sceneDiskVao),e.bindBuffer(e.ARRAY_BUFFER,this.sceneDiskBuffer);let r=Zn*Float32Array.BYTES_PER_ELEMENT;e.enableVertexAttribArray(0),e.vertexAttribPointer(0,2,e.FLOAT,!1,r,0),e.enableVertexAttribArray(1),e.vertexAttribPointer(1,2,e.FLOAT,!1,r,2*Float32Array.BYTES_PER_ELEMENT),e.enableVertexAttribArray(2),e.vertexAttribPointer(2,3,e.FLOAT,!1,r,4*Float32Array.BYTES_PER_ELEMENT),e.enableVertexAttribArray(3),e.vertexAttribPointer(3,1,e.FLOAT,!1,r,7*Float32Array.BYTES_PER_ELEMENT),e.bindVertexArray(this.ringVao),e.bindBuffer(e.ARRAY_BUFFER,this.ringBuffer);let i=Qn*Float32Array.BYTES_PER_ELEMENT;e.enableVertexAttribArray(0),e.vertexAttribPointer(0,2,e.FLOAT,!1,i,0),e.enableVertexAttribArray(1),e.vertexAttribPointer(1,2,e.FLOAT,!1,i,2*Float32Array.BYTES_PER_ELEMENT),e.enableVertexAttribArray(2),e.vertexAttribPointer(2,3,e.FLOAT,!1,i,4*Float32Array.BYTES_PER_ELEMENT),e.enableVertexAttribArray(3),e.vertexAttribPointer(3,1,e.FLOAT,!1,i,7*Float32Array.BYTES_PER_ELEMENT),e.enableVertexAttribArray(4),e.vertexAttribPointer(4,1,e.FLOAT,!1,i,8*Float32Array.BYTES_PER_ELEMENT),e.bindVertexArray(null),e.bindBuffer(e.ARRAY_BUFFER,null),e.bindVertexArray(this.triangleVao),e.bindBuffer(e.ARRAY_BUFFER,this.triangleBuffer);let a=$n*Float32Array.BYTES_PER_ELEMENT;e.enableVertexAttribArray(0),e.vertexAttribPointer(0,2,e.FLOAT,!1,a,0),e.enableVertexAttribArray(1),e.vertexAttribPointer(1,2,e.FLOAT,!1,a,2*Float32Array.BYTES_PER_ELEMENT),e.enableVertexAttribArray(2),e.vertexAttribPointer(2,3,e.FLOAT,!1,a,4*Float32Array.BYTES_PER_ELEMENT),e.enableVertexAttribArray(3),e.vertexAttribPointer(3,1,e.FLOAT,!1,a,7*Float32Array.BYTES_PER_ELEMENT),e.enableVertexAttribArray(4),e.vertexAttribPointer(4,1,e.FLOAT,!1,a,8*Float32Array.BYTES_PER_ELEMENT),e.bindVertexArray(null),e.bindBuffer(e.ARRAY_BUFFER,null),e.bindTexture(e.TEXTURE_2D,this.ringTexture),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_MIN_FILTER,e.LINEAR),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_MAG_FILTER,e.LINEAR),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_WRAP_S,e.CLAMP_TO_EDGE),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_WRAP_T,e.CLAMP_TO_EDGE),e.texImage2D(e.TEXTURE_2D,0,e.R8,256,128,0,e.RED,e.UNSIGNED_BYTE,Pn),e.bindTexture(e.TEXTURE_2D,this.triangleTexture),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_MIN_FILTER,e.LINEAR),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_MAG_FILTER,e.LINEAR),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_WRAP_S,e.CLAMP_TO_EDGE),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_WRAP_T,e.CLAMP_TO_EDGE),e.texImage2D(e.TEXTURE_2D,0,e.SRGB8_ALPHA8,128,128,0,e.RGBA,e.UNSIGNED_BYTE,V),e.bindTexture(e.TEXTURE_2D,this.triangleOverlayTexture),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_MIN_FILTER,e.LINEAR),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_MAG_FILTER,e.LINEAR),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_WRAP_S,e.CLAMP_TO_EDGE),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_WRAP_T,e.CLAMP_TO_EDGE),e.texImage2D(e.TEXTURE_2D,0,e.SRGB8_ALPHA8,128,128,0,e.RGBA,e.UNSIGNED_BYTE,gn),e.bindTexture(e.TEXTURE_2D,this.trailTexture),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_MIN_FILTER,e.LINEAR),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_MAG_FILTER,e.LINEAR),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_WRAP_S,e.REPEAT),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_WRAP_T,e.REPEAT),e.texImage2D(e.TEXTURE_2D,0,e.SRGB8_ALPHA8,512,512,0,e.RGBA,e.UNSIGNED_BYTE,Yn),e.bindTexture(e.TEXTURE_2D,this.circleTexture),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_MIN_FILTER,e.LINEAR),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_MAG_FILTER,e.LINEAR),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_WRAP_S,e.REPEAT),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_WRAP_T,e.REPEAT),e.texImage2D(e.TEXTURE_2D,0,e.SRGB8_ALPHA8,512,512,0,e.RGBA,e.UNSIGNED_BYTE,Tn),e.bindTexture(e.TEXTURE_2D,null),this.contextLost=!1,this.available=!0,this.sceneBackgroundSource&&(this.sceneBackgroundUploadRetryPending=!this._replaceSceneBackgroundTexture(this.sceneBackgroundSource)),this.width>0&&this.height>0&&this._allocateTargets()}catch(e){console.warn(`[BAClickFX] WebGL2 Scene 初始化失败:`,e),this.available=!1,this._deleteResources()}}_handleContextLost(e){e?.preventDefault?.(),this.contextLost=!0,this.available=!1,this.sceneFrameReady=!1,this.bloomSourceFrameReady=!1,this.sceneOverlayFrameReady=!1,this.sceneBackgroundFrameReady=!1,this.sceneBackgroundUploadRetryPending=this.sceneBackgroundSource!==null}_handleContextRestored(){this._forgetResourceReferences(),this._initialize(),this.failedResizeSignature=null}_forgetResourceReferences(){this.sourceTarget=null,this.bloomSourceTarget=null,this.sceneOverlayTarget=null,this.levels=[],this.sceneFrameReady=!1,this.bloomSourceFrameReady=!1,this.sceneOverlayFrameReady=!1,this.sceneBackgroundFrameReady=!1,this.failedResizeSignature=null,this.programs=null,this.emissionBuffer=null,this.emissionVao=null,this.sceneDiskBuffer=null,this.sceneDiskVao=null,this.ringBuffer=null,this.ringVao=null,this.ringTexture=null,this.triangleBuffer=null,this.triangleVao=null,this.triangleTexture=null,this.triangleOverlayTexture=null,this.trailTexture=null,this.circleTexture=null,this.sceneBackgroundTexture=null,this.sceneBackgroundTarget=null,this.fullscreenVao=null,this.vertexCount=0,this.sceneDiskVertexCount=0,this.ringVertexCount=0,this.triangleVertexCount=0,this.trailVertexCount=0,this.stats.vertexCount=0,this.stats.sceneVertexCount=0,this.stats.sceneDiskVertexCount=0,this.stats.sceneRingVertexCount=0,this.stats.sceneTriangleVertexCount=0,this.stats.sceneTrailVertexCount=0,this.stats.diskVertexCount=0,this.stats.ringVertexCount=0,this.stats.triangleVertexCount=0,this.stats.trailVertexCount=0,this.stats.levelCount=0,this.stats.bloomPixels=0}_createTarget(e,t){let n=this.gl,r=n.createTexture(),i=n.createFramebuffer();if(!r||!i)throw n.deleteTexture(r),n.deleteFramebuffer(i),Error(`WebGL2 无法创建 Bloom RenderTarget`);try{if(n.bindTexture(n.TEXTURE_2D,r),n.texParameteri(n.TEXTURE_2D,n.TEXTURE_MIN_FILTER,n.LINEAR),n.texParameteri(n.TEXTURE_2D,n.TEXTURE_MAG_FILTER,n.LINEAR),n.texParameteri(n.TEXTURE_2D,n.TEXTURE_WRAP_S,n.CLAMP_TO_EDGE),n.texParameteri(n.TEXTURE_2D,n.TEXTURE_WRAP_T,n.CLAMP_TO_EDGE),n.texImage2D(n.TEXTURE_2D,0,n.RGBA16F,e,t,0,n.RGBA,n.HALF_FLOAT,null),n.bindFramebuffer(n.FRAMEBUFFER,i),n.framebufferTexture2D(n.FRAMEBUFFER,n.COLOR_ATTACHMENT0,n.TEXTURE_2D,r,0),n.checkFramebufferStatus(n.FRAMEBUFFER)!==n.FRAMEBUFFER_COMPLETE)throw Error(`WebGL2 浮点 Bloom Framebuffer 不完整`);return n.bindFramebuffer(n.FRAMEBUFFER,null),n.bindTexture(n.TEXTURE_2D,null),{texture:r,framebuffer:i,width:e,height:t}}catch(e){throw n.bindFramebuffer(n.FRAMEBUFFER,null),n.bindTexture(n.TEXTURE_2D,null),n.deleteFramebuffer(i),n.deleteTexture(r),e}}_deleteTargets(){let e=this.gl;if(e&&!this.contextLost){U(e,this.sourceTarget),U(e,this.bloomSourceTarget),U(e,this.sceneOverlayTarget),U(e,this.sceneBackgroundTarget);for(let t of this.levels)U(e,t.down),U(e,t.scratch),U(e,t.up)}this.sourceTarget=null,this.bloomSourceTarget=null,this.sceneOverlayTarget=null,this.sceneBackgroundTarget=null,this.sceneFrameReady=!1,this.bloomSourceFrameReady=!1,this.sceneOverlayFrameReady=!1,this.sceneBackgroundFrameReady=!1,this.levels=[],this.stats.levelCount=0,this.stats.bloomPixels=0}releaseFrameResources(){this._deleteTargets(),this.beginFrame(),this.displayWidth=1,this.displayHeight=1,this.sourceWidth=0,this.sourceHeight=0,this.width=0,this.height=0,this.dpr=1,this.resolutionScale=0,this.diffusion=0,this.sampleScale=1,this.failedResizeSignature=null,this.canvas&&(this.canvas.width!==1||this.canvas.height!==1)&&(this.canvas.width=1,this.canvas.height=1)}_deleteResources(){if(!this.gl)return;let e=this.gl;if(this._deleteTargets(),this.programs)for(let t of Object.values(this.programs))t&&e.deleteProgram(t);e.deleteBuffer(this.emissionBuffer),e.deleteVertexArray(this.emissionVao),e.deleteBuffer(this.sceneDiskBuffer),e.deleteVertexArray(this.sceneDiskVao),e.deleteBuffer(this.ringBuffer),e.deleteVertexArray(this.ringVao),e.deleteTexture(this.ringTexture),e.deleteBuffer(this.triangleBuffer),e.deleteVertexArray(this.triangleVao),e.deleteTexture(this.triangleTexture),e.deleteTexture(this.triangleOverlayTexture),e.deleteTexture(this.trailTexture),e.deleteTexture(this.circleTexture),e.deleteTexture(this.sceneBackgroundTexture),e.deleteVertexArray(this.fullscreenVao),this.programs=null,this.emissionBuffer=null,this.emissionVao=null,this.sceneDiskBuffer=null,this.sceneDiskVao=null,this.ringBuffer=null,this.ringVao=null,this.ringTexture=null,this.triangleBuffer=null,this.triangleVao=null,this.triangleTexture=null,this.triangleOverlayTexture=null,this.trailTexture=null,this.circleTexture=null,this.sceneBackgroundTexture=null,this.sceneBackgroundTarget=null,this.sceneBackgroundFrameReady=!1,this.fullscreenVao=null,this.stats.vertexCount=0,this.stats.sceneVertexCount=0,this.stats.sceneDiskVertexCount=0,this.stats.sceneRingVertexCount=0,this.stats.sceneTriangleVertexCount=0,this.stats.sceneTrailVertexCount=0,this.stats.diskVertexCount=0,this.stats.ringVertexCount=0,this.stats.triangleVertexCount=0,this.stats.trailVertexCount=0,this.stats.levelCount=0,this.stats.bloomPixels=0}_discardPendingErrors(){let e=this.gl;if(!(!e||typeof e.getError!=`function`)){for(let t=0;t<8;t++)if(e.getError()===e.NO_ERROR)return}}_createSceneBackgroundTexture(e){let t=this.gl,n=t?.createTexture();if(!t||!n)return null;let r=t.getParameter(t.TEXTURE_BINDING_2D),i=t.getParameter(t.UNPACK_FLIP_Y_WEBGL),a=t.getParameter(t.UNPACK_PREMULTIPLY_ALPHA_WEBGL);try{this._discardPendingErrors(),t.bindTexture(t.TEXTURE_2D,n),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_MIN_FILTER,t.LINEAR),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_MAG_FILTER,t.LINEAR),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_WRAP_S,t.CLAMP_TO_EDGE),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_WRAP_T,t.CLAMP_TO_EDGE),t.pixelStorei(t.UNPACK_FLIP_Y_WEBGL,!1),t.pixelStorei(t.UNPACK_PREMULTIPLY_ALPHA_WEBGL,!1),t.texImage2D(t.TEXTURE_2D,0,t.SRGB8_ALPHA8,t.RGBA,t.UNSIGNED_BYTE,e);let r=t.getError();if(r!==t.NO_ERROR)throw Error(`WebGL2 背景纹理上传错误码 ${r}`);return n}catch(e){return console.warn(`[BAClickFX] Scene 背景无法上传,保留透明回退:`,e),t.deleteTexture(n),null}finally{t.pixelStorei(t.UNPACK_FLIP_Y_WEBGL,i),t.pixelStorei(t.UNPACK_PREMULTIPLY_ALPHA_WEBGL,a),t.bindTexture(t.TEXTURE_2D,r)}}_replaceSceneBackgroundTexture(e){let t=xr(e);if(!t||!this.gl||this.contextLost)return!1;let n=this._createSceneBackgroundTexture(e);if(!n)return!1;let r=!!this.sourceTarget&&this.sourceWidth>0&&this.sourceHeight>0,i=r?this._createSceneBackgroundTarget(n,t.width,t.height):null;if(r&&!i)return this.gl.deleteTexture(n),!1;let a=this.sceneBackgroundTexture,o=this.sceneBackgroundTarget;return this.sceneBackgroundTexture=n,this.sceneBackgroundTarget=i,this.sceneBackgroundSource=e,this.sceneBackgroundWidth=t.width,this.sceneBackgroundHeight=t.height,this.sceneBackgroundFrameReady=!1,this.sceneBackgroundUploadRetryPending=!1,this.failedResizeSignature=null,this.gl.deleteTexture(a),U(this.gl,o),!0}setCompositingReference(e,t={}){if(e===null)return this.gl?.deleteTexture(this.sceneBackgroundTexture),U(this.gl,this.sceneBackgroundTarget),this.sceneBackgroundSource=null,this.sceneBackgroundWidth=0,this.sceneBackgroundHeight=0,this.sceneBackgroundTexture=null,this.sceneBackgroundTarget=null,this.sceneBackgroundFrameReady=!1,this.sceneBackgroundUploadRetryPending=!1,this.failedResizeSignature=null,!0;if(t.fit!==void 0&&t.fit!==`cover`)return!1;if(this.contextLost||!this.gl){let t=xr(e);return t?(this.sceneBackgroundSource=e,this.sceneBackgroundWidth=t.width,this.sceneBackgroundHeight=t.height,this.sceneBackgroundFrameReady=!1,this.sceneBackgroundUploadRetryPending=!0,!0):!1}return this._replaceSceneBackgroundTexture(e)}_getSceneBackgroundUvScale(e=this.sceneBackgroundWidth,t=this.sceneBackgroundHeight){let n=e/t,r=this.displayWidth/this.displayHeight;return n>r?[r/n,1]:[1,n/r]}_createSceneBackgroundTarget(e,t,n){if(!e||!this.programs?.sceneBackground||!this.sourceTarget||this.sourceWidth<=0||this.sourceHeight<=0)return null;let r=this.gl,i=this.programs.sceneBackground,a=this._getSceneBackgroundUvScale(t,n),o=null;try{o=this._createTarget(this.sourceWidth,this.sourceHeight),r.disable(r.BLEND),r.useProgram(i),this._bindTexture(i,`u_background`,e,0),r.uniform2f(r.getUniformLocation(i,`u_uvScale`),a[0],a[1]),this._drawFullscreen(i,o,this.sourceWidth,this.sourceHeight);let t=r.getError();if(t!==r.NO_ERROR)throw Error(`WebGL2 Scene 背景解析错误码 ${t}`);return o}catch(e){return console.warn(`[BAClickFX] Scene 背景缓冲创建失败,保留现有背景:`,e),U(r,o),this._discardPendingErrors(),null}}_rebuildSceneBackgroundTarget(){let e=this._createSceneBackgroundTarget(this.sceneBackgroundTexture,this.sceneBackgroundWidth,this.sceneBackgroundHeight);return e?(U(this.gl,this.sceneBackgroundTarget),this.sceneBackgroundTarget=e,!0):(U(this.gl,this.sceneBackgroundTarget),this.sceneBackgroundTarget=null,!1)}_copySceneBackgroundToTarget(e){if(!this.sceneBackgroundTarget||!e)return!1;let t=this.gl;return t.bindFramebuffer(t.READ_FRAMEBUFFER,this.sceneBackgroundTarget.framebuffer),t.bindFramebuffer(t.DRAW_FRAMEBUFFER,e.framebuffer),t.blitFramebuffer(0,0,this.sourceWidth,this.sourceHeight,0,0,this.sourceWidth,this.sourceHeight,t.COLOR_BUFFER_BIT,t.NEAREST),t.bindFramebuffer(t.FRAMEBUFFER,e.framebuffer),!0}_ensureBloomSourceTarget(){return this.bloomSourceTarget?.width===this.sourceWidth&&this.bloomSourceTarget?.height===this.sourceHeight?!0:(U(this.gl,this.bloomSourceTarget),this.bloomSourceTarget=this._createTarget(this.sourceWidth,this.sourceHeight),this.bloomSourceTarget!==null)}_allocateTargets(){if(!this.available||!this.gl||this.width<=0||this.height<=0)return!1;try{this._deleteTargets(),this.sourceTarget=this._createTarget(this.sourceWidth,this.sourceHeight),this.sceneOverlayTarget=this._createTarget(this.sourceWidth,this.sourceHeight);let e=Sr(this.sourceWidth,this.sourceHeight,this.resolutionScale,this.diffusion),t=e.levelCount;this.sampleScale=e.sampleScale;let n=this.width,r=this.height;for(let e=0;e>1),r=Math.max(1,r>>1)}if(this.sceneBackgroundTexture&&!this._rebuildSceneBackgroundTarget())throw Error(`WebGL2 Scene 背景目标重建失败`);return this.stats.levelCount=this.levels.length,this.stats.bloomPixels=this.levels.reduce((e,t)=>e+t.width*t.height,0),this.failedResizeSignature=null,!0}catch(e){return console.warn(`[BAClickFX] WebGL2 Scene 缓冲创建失败:`,e),this.failedResizeSignature=this._createResizeSignature(this.sourceWidth,this.sourceHeight,this.width,this.height,this.diffusion),this._deleteTargets(),this._discardPendingErrors(),!1}}_createResizeSignature(e,t,n,r,i){return`${e}:${t}:${n}:${r}:${i}`}resize(e,t,n,r,i){let a=Math.max(1,e),o=Math.max(1,t),s=H(n,1,4),c=H(r,.1,.75),l=Math.max(1,Math.round(a*s)),u=Math.max(1,Math.round(o*s)),d=Math.max(1,Math.floor(l*c)),f=Math.max(1,Math.floor(u*c)),p=H(i,0,10),m=this._createResizeSignature(l,u,d,f,p);if(m===this.failedResizeSignature)return!1;if(l>this.maximumTextureSize||u>this.maximumTextureSize||l>this.maximumViewportWidth||u>this.maximumViewportHeight)return this.failedResizeSignature=m,console.warn(`[BAClickFX] WebGL2 Scene 尺寸超过设备上限`),this._deleteTargets(),!1;if(this.sceneBackgroundUploadRetryPending&&(this.sceneBackgroundUploadRetryPending=!1,!this._replaceSceneBackgroundTexture(this.sceneBackgroundSource)))return!1;let h=l===this.sourceWidth&&u===this.sourceHeight&&d===this.width&&f===this.height&&p===this.diffusion&&this.sourceTarget!==null&&this.sceneOverlayTarget!==null&&this.levels.length>0;return this.displayWidth=a,this.displayHeight=o,this.dpr=s,this.resolutionScale=c,this.diffusion=p,this.sourceWidth=l,this.sourceHeight=u,h?(this.failedResizeSignature=null,this.available):(this.width=d,this.height=f,this.canvas.width=l,this.canvas.height=u,this._allocateTargets())}beginFrame(e={}){this.vertexCount=0,this.sceneDiskVertexCount=0,this.ringVertexCount=0,this.triangleVertexCount=0,this.trailVertexCount=0,this.stats.vertexCount=0,this.stats.diskVertexCount=0,this.stats.ringVertexCount=0,this.stats.triangleVertexCount=0,this.stats.trailVertexCount=0,e.preserveSceneStats!==!0&&(this.sceneFrameReady=!1,this.bloomSourceFrameReady=!1,this.sceneOverlayFrameReady=!1,this.sceneBackgroundFrameReady=!1,this.stats.sceneVertexCount=0,this.stats.sceneDiskVertexCount=0,this.stats.sceneRingVertexCount=0,this.stats.sceneTriangleVertexCount=0,this.stats.sceneTrailVertexCount=0)}_hasGeometry(){return this.vertexCount>0||this.sceneDiskVertexCount>0||this.ringVertexCount>0||this.triangleVertexCount>0||this.trailVertexCount>0}_drawTexturedAdditiveBatch(e,t,n,r,i,a,o=!0,s=!1,c=!1){if(e<=0)return;let l=this.gl,u=this.programs.triangle;a?l.blendFuncSeparate(l.ONE,l.ONE,l.ONE,l.ONE_MINUS_SRC_ALPHA):l.blendFuncSeparate(l.ONE,l.ONE,l.ZERO,l.ONE),l.useProgram(u),l.uniform1i(l.getUniformLocation(u,`u_transparentOverlay`),+!!a),l.uniform1i(l.getUniformLocation(u,`u_alphaModulatesEmission`),+!!o),l.uniform1i(l.getUniformLocation(u,`u_antialiasGeometryCoverage`),+!!s),l.uniform1i(l.getUniformLocation(u,`u_roundTriangle`),+!!c),l.uniform2f(l.getUniformLocation(u,`u_displaySize`),this.displayWidth,this.displayHeight),l.activeTexture(l.TEXTURE0),l.bindTexture(l.TEXTURE_2D,i),l.uniform1i(l.getUniformLocation(u,`u_texture`),0),l.bindVertexArray(r),l.bindBuffer(l.ARRAY_BUFFER,n),l.bufferData(l.ARRAY_BUFFER,t,l.DYNAMIC_DRAW),l.drawArrays(l.TRIANGLES,0,e)}_drawGeometryBatches(e,t=!1,n=null){let r=this.gl,i=Math.max(0,n?.disk??1),a=Math.max(0,n?.ring??1);if(r.enable(r.BLEND),r.blendEquation(r.FUNC_ADD),this.sceneDiskVertexCount>0){let e=this.programs.sceneDisk;r.blendFunc(r.ONE,r.ONE_MINUS_SRC_ALPHA),r.useProgram(e),r.uniform2f(r.getUniformLocation(e,`u_displaySize`),this.displayWidth,this.displayHeight),r.uniform1f(r.getUniformLocation(e,`u_emissionScale`),i),r.activeTexture(r.TEXTURE0),r.bindTexture(r.TEXTURE_2D,this.circleTexture),r.uniform1i(r.getUniformLocation(e,`u_texture`),0),r.bindVertexArray(this.sceneDiskVao),r.bindBuffer(r.ARRAY_BUFFER,this.sceneDiskBuffer),r.bufferData(r.ARRAY_BUFFER,this.sceneDiskVertexData.subarray(0,this.sceneDiskVertexCount*Zn),r.DYNAMIC_DRAW),r.drawArrays(r.TRIANGLES,0,this.sceneDiskVertexCount)}if(this._drawTexturedAdditiveBatch(this.trailVertexCount,this.trailVertexData.subarray(0,this.trailVertexCount*er),this.triangleBuffer,this.triangleVao,this.trailTexture,t,!1,!0),this.vertexCount>0){t?r.blendFuncSeparate(r.ONE,r.ONE,r.ONE,r.ONE_MINUS_SRC_ALPHA):r.blendFuncSeparate(r.ONE,r.ONE,r.ZERO,r.ONE),r.useProgram(e);let n=r.getUniformLocation(e,`u_transparentOverlay`);n!==null&&r.uniform1i(n,+!!t),r.uniform2f(r.getUniformLocation(e,`u_displaySize`),this.displayWidth,this.displayHeight),r.bindVertexArray(this.emissionVao),r.bindBuffer(r.ARRAY_BUFFER,this.emissionBuffer),r.bufferData(r.ARRAY_BUFFER,this.vertexData.subarray(0,this.vertexCount*Xn),r.DYNAMIC_DRAW),r.drawArrays(r.TRIANGLES,0,this.vertexCount)}if(this.triangleVertexCount>0&&this._drawTexturedAdditiveBatch(this.triangleVertexCount,this.triangleVertexData.subarray(0,this.triangleVertexCount*$n),this.triangleBuffer,this.triangleVao,t?this.triangleOverlayTexture:this.triangleTexture,t,!0,!1,!0),this.ringVertexCount>0){let e=this.programs.dissolveRing;t?r.blendFuncSeparate(r.ONE,r.ONE,r.ONE,r.ONE_MINUS_SRC_ALPHA):r.blendFuncSeparate(r.SRC_ALPHA,r.ONE,r.ZERO,r.ONE),r.useProgram(e),r.uniform1i(r.getUniformLocation(e,`u_transparentOverlay`),+!!t),r.uniform1f(r.getUniformLocation(e,`u_emissionScale`),a),r.uniform2f(r.getUniformLocation(e,`u_displaySize`),this.displayWidth,this.displayHeight),r.activeTexture(r.TEXTURE0),r.bindTexture(r.TEXTURE_2D,this.ringTexture),r.uniform1i(r.getUniformLocation(e,`u_texture`),0),r.bindVertexArray(this.ringVao),r.bindBuffer(r.ARRAY_BUFFER,this.ringBuffer),r.bufferData(r.ARRAY_BUFFER,this.ringVertexData.subarray(0,this.ringVertexCount*Qn),r.DYNAMIC_DRAW),r.drawArrays(r.TRIANGLES,0,this.ringVertexCount)}r.disable(r.BLEND)}_renderScaledBloomSource(e){let t=Math.max(0,e.diskEmissionScale??1),n=Math.max(0,e.ringEmissionScale??1);if(this.bloomSourceFrameReady=!1,t===1&&n===1)return U(this.gl,this.bloomSourceTarget),this.bloomSourceTarget=null,!0;if(!this._ensureBloomSourceTarget())return!1;let r=this.gl;return r.bindFramebuffer(r.FRAMEBUFFER,this.bloomSourceTarget.framebuffer),r.viewport(0,0,this.sourceWidth,this.sourceHeight),r.clearColor(0,0,0,0),r.clear(r.COLOR_BUFFER_BIT),this._copySceneBackgroundToTarget(this.bloomSourceTarget),this._drawGeometryBatches(this.programs.scene,e.outputCompositing===`browser-overlay`,{disk:t,ring:n}),this.bloomSourceFrameReady=!0,!0}renderScene(e={}){if(!this.sceneEnabled||!this.available||this.contextLost||!this.programs?.scene||!this.sourceTarget)return!1;let t=this.gl,n=e.outputCompositing===`browser-overlay`&&!Me(e.hostCompositing);try{if(t.bindFramebuffer(t.FRAMEBUFFER,this.sourceTarget.framebuffer),t.viewport(0,0,this.sourceWidth,this.sourceHeight),t.clearColor(0,0,0,0),t.clear(t.COLOR_BUFFER_BIT),this.sceneFrameReady=!1,this.bloomSourceFrameReady=!1,this.sceneOverlayFrameReady=!1,this.sceneBackgroundFrameReady=this._copySceneBackgroundToTarget(this.sourceTarget),this.stats.sceneVertexCount=this.vertexCount+this.triangleVertexCount+this.trailVertexCount,this.stats.sceneDiskVertexCount=this.sceneDiskVertexCount,this.stats.sceneRingVertexCount=this.ringVertexCount,this.stats.sceneTriangleVertexCount=this.triangleVertexCount,this.stats.sceneTrailVertexCount=this.trailVertexCount,!this._hasGeometry())return n&&(this.sceneOverlayFrameReady=this._renderSceneOverlay()),this.sceneFrameReady=!0,!0;if(this._drawGeometryBatches(this.programs.scene,e.outputCompositing===`browser-overlay`),!this._renderScaledBloomSource(e))throw Error(`WebGL2 独立点击 Bloom 源生成失败`);if(n&&(this.sceneOverlayFrameReady=this._renderSceneOverlay(),!this.sceneOverlayFrameReady))throw Error(`WebGL2 Scene 传输上界生成失败`);let r=t.getError();if(r!==t.NO_ERROR)throw Error(`WebGL2 错误码 ${r}`);return this.sceneFrameReady=!0,!0}catch(e){return console.warn(`[BAClickFX] WebGL2 清晰特效渲染失败:`,e),this.clear(),this._deleteTargets(),this.available=!1,!1}}_ensureVertexCapacity(e){let t=(this.vertexCount+e)*Xn;if(t<=this.vertexData.length)return;let n=this.vertexData.length;for(;nthis._ensureVertexCapacity(e),(e,t,n,r)=>{this._appendVertex(e,t,o*r,s*r,c*r,i*n)})}addAlphaBlendDisk(e,t,n,r,i=1,a=1,o=0,s=64){let c=r[0]*i,l=r[1]*i,u=r[2]*i,d=i*a;if(n<=0||Math.max(c,l,u)<=0)return;let f=Number.isFinite(o)?o:0,p=Math.cos(f),m=Math.sin(f),h=(n,r,i,a)=>{this._appendSceneDiskVertex(e+n*p-r*m,t+n*m+r*p,i,a,c,l,u,d)};this._ensureSceneDiskVertexCapacity(6),h(-n,-n,0,0),h(n,-n,1,0),h(n,n,1,1),h(-n,-n,0,0),h(n,n,1,1),h(-n,n,0,1)}addSceneDisk(e,t,n,r,i=1,a=1,o=0,s=64){this.addAlphaBlendDisk(e,t,n,r,i,a,o,s)}addTriangle(e,t,n,r,i,a=1,o=0,s=0){let c=Number.isFinite(a)?H(a,0,1):0,l=Math.max(0,i?.[0]??0),u=Math.max(0,i?.[1]??0),d=Math.max(0,i?.[2]??0);if(n<=0||c<=0||Math.max(l,u,d)<=0)return;let f=Math.cos(r),p=Math.sin(r),m=n*.5,h=(n,r)=>({x:e+n*f-r*p,y:t+n*p+r*f}),g=h(-m,-m),_=h(m,-m),v=h(m,m),y=h(-m,m),b=_n(o),x=+(b===1),S=b===1?0:1;this._ensureTriangleVertexCapacity(6),this._appendTriangleVertex(g.x,g.y,0,x,l,u,d,c,s),this._appendTriangleVertex(_.x,_.y,1,x,l,u,d,c,s),this._appendTriangleVertex(v.x,v.y,1,S,l,u,d,c,s),this._appendTriangleVertex(g.x,g.y,0,x,l,u,d,c,s),this._appendTriangleVertex(v.x,v.y,1,S,l,u,d,c,s),this._appendTriangleVertex(y.x,y.y,0,S,l,u,d,c,s)}addTexturedTrailTriangle(e,t,n,r,i=1,a=1){let o=Array.isArray(r?.[0]),s=o?r[0]:r,c=o?r[1]:r,l=o?r[2]:r,u=Number.isFinite(i)?H(i,0,1):0,d=Array.isArray(a),f=d?a[0]:a,p=d?a[1]:a,m=d?a[2]:a;u<=0||Math.max(f,p,m)<=0||(this._ensureTrailVertexCapacity(3),this._appendTrailVertex(e,e,s,u,f),this._appendTrailVertex(t,t,c,u,p),this._appendTrailVertex(n,n,l,u,m))}addTrailTriangle(e,t,n,r,i=1){let a=Array.isArray(r?.[0]),o=a?r[0]:r,s=a?r[1]:r,c=a?r[2]:r,l=o[0]*i,u=o[1]*i,d=o[2]*i,f=s[0]*i,p=s[1]*i,m=s[2]*i,h=c[0]*i,g=c[1]*i,_=c[2]*i;Math.max(l,u,d,f,p,m,h,g,_)<=0||(this._ensureVertexCapacity(3),this._appendVertex(e.x,e.y,l,u,d,i),this._appendVertex(t.x,t.y,f,p,m,i),this._appendVertex(n.x,n.y,h,g,_,i))}addDissolveRing(e,t,n,r,i,a,o,s,c,l,u,d,f){let p=s[0]*c,m=s[1]*c,h=s[2]*c;if(n<=0||r<=0||Math.max(p,m,h)<=0)return;let g=H(Math.round(a),1,32),_=H(Math.round(o),32,512),v=Math.max(0,n-r*.5),y=r/g,b=new Float64Array(_+1),x=new Float64Array(_+1),S=H(c,0,1),C=Number.isFinite(l)?H(l,0,1):1,w=Number.isFinite(u)?H(u,0,1):0,T=(Number.isFinite(d)?H(d,0,1):1)-w,E=f>=0?1:-1;for(let e=0;e<=_;e++){let t=i+e/_*Math.PI*2;b[e]=Math.cos(t),x[e]=Math.sin(t)}this._ensureRingVertexCapacity(g*_*6);for(let n=0;n0?D:1-D,A=E>0?O:1-O,j=w+T*k,M=w+T*A;this._appendRingVertex(c,l,j,a,p,m,h,C,S),this._appendRingVertex(u,d,M,a,p,m,h,C,S),this._appendRingVertex(v,y,M,o,p,m,h,C,S),this._appendRingVertex(c,l,j,a,p,m,h,C,S),this._appendRingVertex(v,y,M,o,p,m,h,C,S),this._appendRingVertex(f,g,j,o,p,m,h,C,S)}}}addRing(e,t,n,r,i,a,o,s,c,l){if(r<=0||c<=0)return;let u=H(Math.round(a),1,32),d=H(Math.round(o),32,512),f=Math.max(0,n-r*.5),p=r/u,m=s[0]*c,h=s[1]*c,g=s[2]*c,_=Math.PI*2/d,v=Math.cos(_),y=Math.sin(_),b=Math.cos(i),x=Math.sin(i);this._ensureVertexCapacity(u*d*6);for(let n=0;n=2?a:[[0,1],[1,1]],_=n*.5,v={x:-d/f*_,y:u/f*_},y=o??v,b=s??v;this._ensureVertexCapacity((g.length-1)*6+(c?3:0)+(l?3:0));for(let n=1;nMath.max(e,t),0),w=p*C,T=m*C,E=h*C;c&&(this._appendVertex(e.x+y.x,e.y+y.y,w,T,E,i),this._appendVertex(e.x-y.x,e.y-y.y,w,T,E,i),this._appendVertex(e.x-x*_,e.y-S*_,w,T,E,i)),l&&(this._appendVertex(t.x+b.x,t.y+b.y,w,T,E,i),this._appendVertex(t.x+x*_,t.y+S*_,w,T,E,i),this._appendVertex(t.x-b.x,t.y-b.y,w,T,E,i))}_bindTexture(e,t,n,r){let i=this.gl;i.activeTexture(i.TEXTURE0+r),i.bindTexture(i.TEXTURE_2D,n),i.uniform1i(i.getUniformLocation(e,t),r)}_drawFullscreen(e,t,n,r){let i=this.gl;i.bindFramebuffer(i.FRAMEBUFFER,t?.framebuffer??null),i.viewport(0,0,n,r),i.useProgram(e),i.bindVertexArray(this.fullscreenVao),i.drawArrays(i.TRIANGLES,0,3)}_renderEmission(e){let t=this.gl,n=e.outputCompositing===`browser-overlay`;t.bindFramebuffer(t.FRAMEBUFFER,this.sourceTarget.framebuffer),t.viewport(0,0,this.sourceWidth,this.sourceHeight),t.clearColor(0,0,0,0),t.clear(t.COLOR_BUFFER_BIT),this._drawGeometryBatches(this.programs.emission,n)}_renderPrefilter(e){let t=this.gl,n=this.programs.prefilter,r=this.levels[0],i=this.bloomSourceFrameReady?this.bloomSourceTarget:this.sourceTarget,a=Number.isFinite(e.softKnee)?H(e.softKnee,0,1):0,o=Tt(e.clamp);t.useProgram(n),this._bindTexture(n,`u_source`,i.texture,0),t.uniform2f(t.getUniformLocation(n,`u_sourceTexel`),1/this.sourceWidth,1/this.sourceHeight),t.uniform1f(t.getUniformLocation(n,`u_threshold`),wt(e.threshold)),t.uniform1f(t.getUniformLocation(n,`u_softKnee`),a),t.uniform1f(t.getUniformLocation(n,`u_clampMax`),o),this._drawFullscreen(n,r.down,r.width,r.height)}_renderSceneOverlay(){if(!this.sourceTarget||!this.sceneOverlayTarget||!this.programs?.sceneOverlay)return!1;let e=this.programs.sceneOverlay;return this.gl.useProgram(e),this._bindTexture(e,`u_scene`,this.sourceTarget.texture,0),this._drawFullscreen(e,this.sceneOverlayTarget,this.sourceWidth,this.sourceHeight),!0}_renderDownsample(e,t){let n=this.gl,r=this.programs.downsample;n.useProgram(r),this._bindTexture(r,`u_source`,e.down.texture,0),n.uniform2f(n.getUniformLocation(r,`u_sourceTexel`),1/e.width,1/e.height),this._drawFullscreen(r,t.down,t.width,t.height)}_renderUpsample(e,t,n){let r=this.gl,i=this.programs.upsample;return r.useProgram(i),this._bindTexture(i,`u_accumulatedCoarse`,n,0),this._bindTexture(i,`u_currentFine`,e.down.texture,1),r.uniform2f(r.getUniformLocation(i,`u_accumulatedCoarseTexel`),1/t.width,1/t.height),r.uniform1f(r.getUniformLocation(i,`u_sampleScale`),this.sampleScale),this._drawFullscreen(i,e.up,e.width,e.height),e.up.texture}_renderFinal(e,t,n=!1,r=!1,i=!1){let a=this.gl,o=this.programs.final;a.bindFramebuffer(a.FRAMEBUFFER,null),a.viewport(0,0,this.canvas.width,this.canvas.height),a.disable(a.BLEND),a.clearColor(0,0,0,0),a.clear(a.COLOR_BUFFER_BIT),a.useProgram(o),this._bindTexture(o,`u_bloom`,e,0),this._bindTexture(o,`u_scene`,n?i?this.sceneOverlayTarget.texture:this.sourceTarget.texture:e,1),this._bindTexture(o,`u_background`,r?this.sceneBackgroundTarget.texture:e,2),this._bindTexture(o,`u_sceneEnergy`,n?this.sourceTarget.texture:e,3),a.uniform1i(a.getUniformLocation(o,`u_hasScene`),+!!n),a.uniform1i(a.getUniformLocation(o,`u_hasBackground`),+!!r),a.uniform1i(a.getUniformLocation(o,`u_transparentOverlay`),+(t.outputCompositing===`browser-overlay`)),a.uniform1i(a.getUniformLocation(o,`u_visualMaxAlpha`),+(t.overlayAlphaPolicy===`visual-max`)),a.uniform1i(a.getUniformLocation(o,`u_brightUnknownBackground`),+(t.overlayColorCompensation===`bright-core`)),a.uniform1i(a.getUniformLocation(o,`u_hostAdditive`),+!!Me(t.hostCompositing)),a.uniform2f(a.getUniformLocation(o,`u_bloomTexel`),1/this.width,1/this.height),a.uniform1f(a.getUniformLocation(o,`u_sampleScale`),this.sampleScale),a.uniform1f(a.getUniformLocation(o,`u_intensity`),Ct(t.intensity)),a.uniform1f(a.getUniformLocation(o,`u_overlayAlphaLimit`),H(t.overlayAlphaLimit??1,0,1)),a.uniform1f(a.getUniformLocation(o,`u_opacity`),H(t.opacity??1,0,1)),a.bindVertexArray(this.fullscreenVao),a.drawArrays(a.TRIANGLES,0,3)}render(e,t={}){if(!this.available||this.contextLost||!this.sourceTarget||this.levels.length===0)return!1;let n=this.gl,r=t.preserveCanvas===!0,i=r&&this.sceneEnabled&&this.sceneFrameReady,a=i&&this.sceneBackgroundFrameReady,o=i&&!a&&e.outputCompositing===`browser-overlay`&&!Me(e.hostCompositing)&&this.sceneOverlayFrameReady;try{if(!this._hasGeometry()&&!i)return r||this.clear(),!0;i||this._renderEmission(e),this._renderPrefilter(e);for(let e=1;e=0;e--)t=this._renderUpsample(this.levels[e],this.levels[e+1],t);this._renderFinal(t,e,i,a,o),this.stats.vertexCount=this.vertexCount+this.triangleVertexCount+this.trailVertexCount,this.stats.diskVertexCount=this.sceneDiskVertexCount,this.stats.ringVertexCount=this.ringVertexCount,this.stats.triangleVertexCount=this.triangleVertexCount,this.stats.trailVertexCount=this.trailVertexCount;let s=n.getError();if(s!==n.NO_ERROR)throw Error(`WebGL2 错误码 ${s}`);return!0}catch(e){return console.warn(`[BAClickFX] WebGL2 Scene 渲染失败:`,e),this.clear(),this._deleteTargets(),this.available=!1,!1}}clear(){this.sceneFrameReady=!1,this.bloomSourceFrameReady=!1,this.sceneBackgroundFrameReady=!1,this.stats.vertexCount=0,this.stats.diskVertexCount=0,this.stats.ringVertexCount=0,this.stats.triangleVertexCount=0,this.stats.trailVertexCount=0,this.stats.sceneVertexCount=0,this.stats.sceneDiskVertexCount=0,this.stats.sceneRingVertexCount=0,this.stats.sceneTriangleVertexCount=0,this.stats.sceneTrailVertexCount=0,!(!this.gl||this.contextLost)&&(this.gl.bindFramebuffer(this.gl.FRAMEBUFFER,null),this.gl.viewport(0,0,this.canvas.width,this.canvas.height),this.gl.clearColor(0,0,0,0),this.gl.clear(this.gl.COLOR_BUFFER_BIT))}destroy(){this.canvas?.removeEventListener?.(`webglcontextlost`,this._onContextLost),this.canvas?.removeEventListener?.(`webglcontextrestored`,this._onContextRestored),this._deleteResources(),this.available=!1,this.contextLost=!1,this.vertexCount=0,this.vertexData=new Float32Array,this.sceneDiskVertexCount=0,this.sceneDiskVertexData=new Float32Array,this.ringVertexCount=0,this.ringVertexData=new Float32Array,this.triangleVertexCount=0,this.triangleVertexData=new Float32Array,this.trailVertexCount=0,this.trailVertexData=new Float32Array,this.maximumTextureSize=0,this.maximumViewportWidth=0,this.maximumViewportHeight=0,this.failedResizeSignature=null,this.sceneBackgroundSource=null,this.sceneBackgroundWidth=0,this.sceneBackgroundHeight=0,this.sceneBackgroundUploadRetryPending=!1}},Er=`bgra8unorm`,Dr=Object.freeze([`gpuApi`,`context`,`adapter`,`device`,`extendedConfigure`,`standardConfigure`,`deviceLost`,`unconfigure`]),Or=new Set([`extended-configure-failed`,`standard-configure-failed`,`unconfigure-failed`]);function kr(){return{status:`idle`,failureStage:null,error:null}}function Ar(e){return Object.freeze({status:e.status,failureStage:e.failureStage,error:e.error})}function jr(){return globalThis.navigator?.gpu??null}function Mr(e){try{return e?.getPreferredCanvasFormat?.()??Er}catch{return Er}}var Nr=class{constructor(e,t={}){this.canvas=e,this.gpu=t.gpu??jr(),this.powerPreference=t.powerPreference??`high-performance`,this.onStateChange=typeof t.onStateChange==`function`?t.onStateChange:null,this.context=null,this.adapter=null,this.device=null,this.status=`pending`,this.outputMode=`unconfigured`,this.canvasFormat=null,this.preferHdr=null,this.failure=null,this._diagnosticFailureStage=null,this._diagnosticStages=Object.fromEntries(Dr.map(e=>[e,kr()])),this.ready=this._initialize()}get available(){return this.status===`ready`}get hdrOutput(){return this.outputMode===`extended`}get diagnostics(){let e=Object.fromEntries(Dr.map(e=>[e,Ar(this._diagnosticStages[e])]));return Object.freeze({failureStage:this._diagnosticFailureStage,stages:Object.freeze(e)})}_setDiagnosticStage(e,t,n=null,r=null){let i=this._diagnosticStages[e];i&&(i.status=t,i.failureStage=n,i.error=r)}_failDiagnosticStage(e,t,n){this._setDiagnosticStage(e,`failed`,t,n),this._diagnosticFailureStage=t}_resetConfigurationDiagnostics(){this._setDiagnosticStage(`extendedConfigure`,`idle`),this._setDiagnosticStage(`standardConfigure`,`idle`),this._setDiagnosticStage(`unconfigure`,`idle`),Or.has(this._diagnosticFailureStage)&&(this._diagnosticFailureStage=null)}_setStatus(e,t=null){this.status===e&&this.failure===t||(this.status=e,this.failure=t,this.onStateChange?.(e,this))}async _initialize(){try{if(this._setDiagnosticStage(`gpuApi`,`pending`),!this.gpu||typeof this.gpu.requestAdapter!=`function`){let e=Error(`当前环境未提供 WebGPU`);throw this._failDiagnosticStage(`gpuApi`,`webgpu-api-missing`,e),e}this._setDiagnosticStage(`gpuApi`,`succeeded`),this._setDiagnosticStage(`context`,`pending`);try{this.context=this.canvas?.getContext?.(`webgpu`)??null}catch(e){throw this._failDiagnosticStage(`context`,`context-unavailable`,e),e}if(!this.context){let e=Error(`Canvas 无法创建 WebGPU 上下文`);throw this._failDiagnosticStage(`context`,`context-unavailable`,e),e}this._setDiagnosticStage(`context`,`succeeded`),this._setDiagnosticStage(`adapter`,`pending`);try{this.adapter=await this.gpu.requestAdapter({powerPreference:this.powerPreference})}catch(e){throw this._failDiagnosticStage(`adapter`,`adapter-request-failed`,e),e}if(!this.adapter){let e=Error(`浏览器未返回 WebGPU Adapter`);throw this._failDiagnosticStage(`adapter`,`adapter-unavailable`,e),e}this._setDiagnosticStage(`adapter`,`succeeded`),this._setDiagnosticStage(`device`,`pending`);try{this.device=await this.adapter.requestDevice()}catch(e){throw this._failDiagnosticStage(`device`,`device-request-failed`,e),e}if(!this.device){let e=Error(`浏览器未返回 WebGPU Device`);throw this._failDiagnosticStage(`device`,`device-request-failed`,e),e}return this._setDiagnosticStage(`device`,`succeeded`),this._watchDeviceLoss(this.device),this._setStatus(`ready`),!0}catch(e){return this.status!==`destroyed`&&this._setStatus(`unavailable`,e),!1}}_watchDeviceLoss(e){!e?.lost||typeof e.lost.then!=`function`||e.lost.then(t=>{if(this.status===`destroyed`||e!==this.device)return;this.outputMode=`unconfigured`,this.canvasFormat=null,this.preferHdr=null,this._resetConfigurationDiagnostics();let n=t??Error(`WebGPU Device 已丢失`);this._setDiagnosticStage(`device`,`lost`,`device-lost`,n),this._setDiagnosticStage(`deviceLost`,`lost`,`device-lost`,n),this._diagnosticFailureStage=`device-lost`,this._setStatus(`lost`,n)})}_configureExtended(){this.context.configure({device:this.device,format:`rgba16float`,alphaMode:`premultiplied`,toneMapping:{mode:`extended`}}),this.canvasFormat=`rgba16float`,this.outputMode=`extended`}_configureStandard(){let e=Mr(this.gpu);this.context.configure({device:this.device,format:e,alphaMode:`premultiplied`}),this.canvasFormat=e,this.outputMode=`standard`}configure(e={}){if(!this.available||!this.context||!this.device)return!1;let t=e.preferHdr!==!1;if(this.outputMode!==`unconfigured`&&this.preferHdr===t)return!0;if(this._resetConfigurationDiagnostics(),t){this._setDiagnosticStage(`extendedConfigure`,`pending`);try{return this._configureExtended(),this._setDiagnosticStage(`extendedConfigure`,`succeeded`),this._setDiagnosticStage(`standardConfigure`,`skipped`),this.preferHdr=t,!0}catch(e){this._failDiagnosticStage(`extendedConfigure`,`extended-configure-failed`,e)}}else this._setDiagnosticStage(`extendedConfigure`,`skipped`);this._setDiagnosticStage(`standardConfigure`,`pending`);try{return this._configureStandard(),this._setDiagnosticStage(`standardConfigure`,`succeeded`),this.preferHdr=t,!0}catch(e){return this.outputMode=`unconfigured`,this.canvasFormat=null,this.preferHdr=null,this.failure=e,this._failDiagnosticStage(`standardConfigure`,`standard-configure-failed`,e),!1}}unconfigure(){if(this.outputMode===`unconfigured`&&this.canvasFormat===null&&this.preferHdr===null)return!0;this._setDiagnosticStage(`unconfigure`,`pending`);try{this.context?.unconfigure?.()}catch(e){return this.failure=e,this._failDiagnosticStage(`unconfigure`,`unconfigure-failed`,e),!1}return this.outputMode=`unconfigured`,this.canvasFormat=null,this.preferHdr=null,this._setDiagnosticStage(`extendedConfigure`,`idle`),this._setDiagnosticStage(`standardConfigure`,`idle`),this._setDiagnosticStage(`unconfigure`,`succeeded`),Or.has(this._diagnosticFailureStage)&&(this._diagnosticFailureStage=null),!0}destroy(){if(this.status!==`destroyed`){this._setStatus(`destroyed`),this.unconfigure();try{this.device?.destroy?.()}catch{}this.context=null,this.adapter=null,this.device=null,this.outputMode=`unconfigured`,this.canvasFormat=null,this.preferHdr=null}}},Pr=` +struct GeometryUniforms +{ + displaySize: vec2f, + diskEmissionScale: f32, + ringEmissionScale: f32, + transparentOverlay: u32, +} + +@group(0) @binding(0) var geometry: GeometryUniforms; +@group(0) @binding(1) var materialTexture: texture_2d; +@group(0) @binding(2) var materialSampler: sampler; + +struct GenericOutput +{ + @builtin(position) position: vec4f, + @location(0) color: vec3f, + @location(1) coverage: f32, +} + +struct TexturedOutput +{ + @builtin(position) position: vec4f, + @location(0) uv: vec2f, + @location(1) color: vec3f, + @location(2) particleAlpha: f32, + @location(3) coverageFactor: f32, +} + +fn toClip(position: vec2f) -> vec4f +{ + let normalized = position / geometry.displaySize; + return vec4f( + normalized.x * 2.0 - 1.0, + 1.0 - normalized.y * 2.0, + 0.0, + 1.0, + ); +} + +@vertex +fn vertexGeneric( + @location(0) position: vec2f, + @location(1) color: vec3f, + @location(2) coverage: f32, +) -> GenericOutput +{ + var output: GenericOutput; + output.position = toClip(position); + output.color = color; + output.coverage = coverage; + return output; +} + +@fragment +fn fragmentGeneric(input: GenericOutput) -> @location(0) vec4f +{ + let alpha = select(1.0, clamp(input.coverage, 0.0, 1.0), + geometry.transparentOverlay != 0u); + return vec4f(max(input.color, vec3f(0.0)), alpha); +} + +@vertex +fn vertexTextured( + @location(0) position: vec2f, + @location(1) uv: vec2f, + @location(2) color: vec3f, + @location(3) particleAlpha: f32, + @location(4) coverageFactor: f32, +) -> TexturedOutput +{ + var output: TexturedOutput; + output.position = toClip(position); + output.uv = uv; + output.color = color; + output.particleAlpha = particleAlpha; + output.coverageFactor = coverageFactor; + return output; +} + +@vertex +fn vertexDisk( + @location(0) position: vec2f, + @location(1) uv: vec2f, + @location(2) color: vec3f, + @location(3) particleAlpha: f32, +) -> TexturedOutput +{ + var output: TexturedOutput; + output.position = toClip(position); + output.uv = uv; + output.color = color; + output.particleAlpha = particleAlpha; + output.coverageFactor = 1.0; + return output; +} + +fn sdTriangle(point: vec2f) -> f32 +{ + let vertices = array( + vec2f(-0.9609375, -0.7265625), + vec2f(0.9609375, -0.7265625), + vec2f(0.0, 0.9140625), + ); + var minimumSquaredDistance = 1.0e20; + var inside = true; + + for (var index = 0u; index < 3u; index++) + { + let start = vertices[index]; + let end = vertices[(index + 1u) % 3u]; + let edge = end - start; + let offset = point - start; + let progress = clamp( + dot(offset, edge) / max(dot(edge, edge), 1.0e-20), + 0.0, + 1.0, + ); + let nearest = offset - edge * progress; + + minimumSquaredDistance = min( + minimumSquaredDistance, + dot(nearest, nearest), + ); + inside = inside && edge.x * offset.y - edge.y * offset.x >= 0.0; + } + + return sqrt(minimumSquaredDistance) * select(1.0, -1.0, inside); +} + +fn sdRoundedTriangle(point: vec2f, roundness: f32) -> f32 +{ + if (roundness >= 1.0) + { + return length(point) - 1.0; + } + + let triangleScale = max(1.0 - roundness, 0.000001); + + // 缩小真实图集三角与圆盘的 Minkowski 和只磨圆角,仍保留直边。 + return sdTriangle(point / triangleScale) * + triangleScale - roundness; +} + +@fragment +fn fragmentTriangle(input: TexturedOutput) -> @location(0) vec4f +{ + let roundness = clamp(input.coverageFactor, 0.0, 1.0); + let point = input.uv * 2.0 - 1.0; + let samplePoint = point / (1.0 + 1.16465 * roundness); + var sampleColor = textureSample( + materialTexture, + materialSampler, + samplePoint * 0.5 + 0.5, + ); + let particleAlpha = clamp(input.particleAlpha, 0.0, 1.0); + let distance = sdRoundedTriangle(point, roundness); + // 导数必须在一致控制流中计算,否则 WebGPU 验证会拒绝该 Shader。 + let footprint = max(fwidth(distance), 0.000001); + let roundedCoverage = 1.0 - smoothstep(-footprint, footprint, distance); + let textureSupport = clamp(sampleColor.a, 0.0, 1.0); + let supportedRgb = mix(vec3f(1.0), sampleColor.rgb, textureSupport); + let shapeRgb = mix(supportedRgb, vec3f(1.0), roundness); + let shapeAlpha = select( + sampleColor.a, + roundedCoverage, + roundness > 0.0, + ); + + sampleColor = vec4f( + select(sampleColor.rgb, shapeRgb, roundness > 0.0), + shapeAlpha, + ); + + let coverage = sampleColor.a * particleAlpha; + let emission = sampleColor.rgb * max(input.color, vec3f(0.0)) * coverage; + let alpha = select(1.0, coverage, geometry.transparentOverlay != 0u); + return vec4f(emission, alpha); +} + +@fragment +fn fragmentTrail(input: TexturedOutput) -> @location(0) vec4f +{ + let sampleColor = textureSample(materialTexture, materialSampler, input.uv); + let particleAlpha = clamp(input.particleAlpha, 0.0, 1.0); + let edgeDistance = min(input.uv.y, 1.0 - input.uv.y); + let footprint = max(fwidth(input.uv.y) * 0.5, 0.000001); + let geometryCoverage = select( + 1.0, + smoothstep(0.0, footprint, edgeDistance), + geometry.transparentOverlay != 0u, + ); + let coverage = sampleColor.a * particleAlpha * + clamp(input.coverageFactor, 0.0, 1.0) * geometryCoverage; + let emission = sampleColor.rgb * max(input.color, vec3f(0.0)) * particleAlpha; + let alpha = select(1.0, coverage, geometry.transparentOverlay != 0u); + return vec4f(emission, alpha); +} + +@fragment +fn fragmentDisk(input: TexturedOutput) -> @location(0) vec4f +{ + let sampleColor = textureSample(materialTexture, materialSampler, input.uv); + let textureAlpha = sampleColor.r; + let color = sampleColor.rgb * max(input.color, vec3f(0.0)) * + textureAlpha * max(geometry.diskEmissionScale, 0.0); + let alpha = textureAlpha * clamp(input.particleAlpha, 0.0, 1.0); + return vec4f(color, clamp(alpha, 0.0, 1.0)); +} + +struct RingOutput +{ + @builtin(position) position: vec4f, + @location(0) uv: vec2f, + @location(1) color: vec3f, + @location(2) dissolveThreshold: f32, + @location(3) coverageOpacity: f32, +} + +@vertex +fn vertexRing( + @location(0) position: vec2f, + @location(1) uv: vec2f, + @location(2) color: vec3f, + @location(3) dissolveThreshold: f32, + @location(4) coverageOpacity: f32, +) -> RingOutput +{ + var output: RingOutput; + output.position = toClip(position); + output.uv = uv; + output.color = color; + output.dissolveThreshold = dissolveThreshold; + output.coverageOpacity = coverageOpacity; + return output; +} + +@fragment +fn fragmentRing(input: RingOutput) -> @location(0) vec4f +{ + let textureAlpha = textureSample( + materialTexture, + materialSampler, + input.uv, + ).r; + + if (textureAlpha < input.dissolveThreshold) + { + discard; + } + + let alpha = clamp(textureAlpha, 0.0, 1.0); + let color = max(input.color, vec3f(0.0)) * + max(geometry.ringEmissionScale, 0.0); + + if (geometry.transparentOverlay != 0u) + { + return vec4f(color * alpha, alpha * clamp(input.coverageOpacity, 0.0, 1.0)); + } + + return vec4f(color, alpha); +} +`,Fr=` +struct PassUniforms +{ + texelSize: vec2f, + backgroundUvScale: vec2f, + sampleScale: f32, + threshold: f32, + softKnee: f32, + clampMax: f32, + intensity: f32, + overlayAlphaLimit: f32, + opacity: f32, + hasScene: u32, + hasBackground: u32, + transparentOverlay: u32, + visualMaxAlpha: u32, + brightUnknownBackground: u32, + hostAdditive: u32, + extendedOutput: u32, + hdrPeak: f32, + hdrWhiteCore: f32, + hdrWhiteStart: f32, + hdrWhiteEnd: f32, + hdrBrightness: f32, + hdrColorPreservation: f32, +} + +@group(0) @binding(0) var params: PassUniforms; +@group(0) @binding(1) var linearSampler: sampler; +@group(0) @binding(2) var source0: texture_2d; +@group(0) @binding(3) var source1: texture_2d; +@group(0) @binding(4) var source2: texture_2d; +@group(0) @binding(5) var source3: texture_2d; + +struct FullscreenOutput +{ + @builtin(position) position: vec4f, + @location(0) uv: vec2f, +} + +@vertex +fn vertexFullscreen(@builtin(vertex_index) index: u32) -> FullscreenOutput +{ + var positions = array( + vec2f(-1.0, -1.0), + vec2f(3.0, -1.0), + vec2f(-1.0, 3.0), + ); + let position = positions[index]; + var output: FullscreenOutput; + output.position = vec4f(position, 0.0, 1.0); + output.uv = vec2f(position.x * 0.5 + 0.5, 0.5 - position.y * 0.5); + return output; +} + +fn sampleBox(source: texture_2d, uv: vec2f, offset: vec2f) -> vec4f +{ + return ( + textureSampleLevel(source, linearSampler, uv + vec2f(-offset.x, -offset.y), 0.0) + + textureSampleLevel(source, linearSampler, uv + vec2f(offset.x, -offset.y), 0.0) + + textureSampleLevel(source, linearSampler, uv + vec2f(-offset.x, offset.y), 0.0) + + textureSampleLevel(source, linearSampler, uv + vec2f(offset.x, offset.y), 0.0) + ) * 0.25; +} + +@fragment +fn fragmentBackground(input: FullscreenOutput) -> @location(0) vec4f +{ + let uv = (input.uv - vec2f(0.5)) * params.backgroundUvScale + vec2f(0.5); + return vec4f(textureSampleLevel(source0, linearSampler, uv, 0.0).rgb, 1.0); +} + +@fragment +fn fragmentSceneOverlay(input: FullscreenOutput) -> @location(0) vec4f +{ + let scene = textureSampleLevel(source0, linearSampler, input.uv, 0.0); + let coverage = clamp(scene.a, 0.0, 1.0); + let capacity = select( + pow((coverage + 0.055) / 1.055, 2.4), + coverage / 12.92, + coverage <= 0.04045, + ); + let maximumEnergy = max(max(scene.r, scene.g), scene.b); + let scale = min(1.0, capacity / max(maximumEnergy, 0.000001)); + return vec4f(scene.rgb * scale, coverage); +} + +@fragment +fn fragmentPrefilter(input: FullscreenOutput) -> @location(0) vec4f +{ + let filtered = sampleBox(source0, input.uv, params.texelSize); + let color = min(filtered.rgb, vec3f(min(max(params.clampMax, 0.0), 65504.0))); + let brightness = max(max(color.r, color.g), color.b); + + if (brightness <= 0.0) + { + return vec4f(0.0); + } + + let threshold = max(0.0, params.threshold); + let knee = threshold * clamp(params.softKnee, 0.0, 1.0) + 0.00001; + var soft = clamp(brightness - threshold + knee, 0.0, knee * 2.0); + soft = soft * soft / (knee * 4.0); + let contribution = max(max(brightness - threshold, soft), 0.0); + return vec4f(color * contribution / max(brightness, 0.0001), contribution); +} + +@fragment +fn fragmentDownsample(input: FullscreenOutput) -> @location(0) vec4f +{ + return sampleBox(source0, input.uv, params.texelSize); +} + +@fragment +fn fragmentUpsample(input: FullscreenOutput) -> @location(0) vec4f +{ + let offset = params.texelSize * (params.sampleScale * 0.5); + let coarse = sampleBox(source0, input.uv, offset); + let fine = textureSampleLevel(source1, linearSampler, input.uv, 0.0); + return coarse + fine; +} + +fn linearToExtendedSrgb(value: f32) -> f32 +{ + let linear = max(value, 0.0); + return select( + 1.055 * pow(linear, 1.0 / 2.4) - 0.055, + linear * 12.92, + linear <= 0.0031308, + ); +} + +fn linearToSrgb(value: f32) -> f32 +{ + return min(linearToExtendedSrgb(value), 1.0); +} + +fn linearToSrgb3(value: vec3f) -> vec3f +{ + return vec3f( + linearToSrgb(value.r), + linearToSrgb(value.g), + linearToSrgb(value.b), + ); +} + +fn linearToExtendedSrgb3(value: vec3f) -> vec3f +{ + return vec3f( + linearToExtendedSrgb(value.r), + linearToExtendedSrgb(value.g), + linearToExtendedSrgb(value.b), + ); +} + +fn mapExtendedHdrPresentation(linear: vec3f) -> vec3f +{ + let sdrBase = clamp(linear, vec3f(0.0), vec3f(1.0)); + let excess = max(linear - sdrBase, vec3f(0.0)); + let excessPeak = max(max(excess.r, excess.g), excess.b); + + if (excessPeak <= 0.0) + { + return sdrBase; + } + + let capacity = max(params.hdrPeak - 1.0, 0.0); + let mappedPeak = capacity * excessPeak / + max(capacity + excessPeak, 0.000001); + let coloredExtra = excess * mappedPeak / excessPeak; + let whiteStart = max(params.hdrWhiteStart, 0.0); + let whiteEnd = max(params.hdrWhiteEnd, whiteStart + 0.000001); + let whiteMix = smoothstep(whiteStart, whiteEnd, excessPeak) * + clamp(params.hdrWhiteCore, 0.0, 1.0); + + return sdrBase + mix(coloredExtra, vec3f(mappedPeak), whiteMix); +} + +fn solveOverlayAlpha(background: f32, desired: f32) -> f32 +{ + if (desired > background) + { + return (desired - background) / max(1.0 - background, 0.000001); + } + + if (desired < background) + { + return (background - desired) / max(background, 0.000001); + } + + return 0.0; +} + +fn preserveHdrEffectHue( + mapped: vec3f, + source: vec3f, + background: vec3f, +) -> vec3f +{ + let mappedDelta = max(mapped - background, vec3f(0.0)); + let sourceDelta = max(source - background, vec3f(0.0)); + let sourcePeak = max(max(sourceDelta.r, sourceDelta.g), sourceDelta.b); + let targetPeak = max(max(mappedDelta.r, mappedDelta.g), mappedDelta.b); + + if (sourcePeak <= 0.000001 || targetPeak <= 0.000001) + { + return mappedDelta; + } + + // 峰值仍来自 HDR shoulder,只把高亮增量拉回原始线性 RGB 色度方向。 + let preservedDelta = sourceDelta * targetPeak / sourcePeak; + return mix( + mappedDelta, + preservedDelta, + clamp(params.hdrColorPreservation, 0.0, 1.0), + ); +} + +@fragment +fn fragmentFinal(input: FullscreenOutput) -> @location(0) vec4f +{ + let offset = params.texelSize * (params.sampleScale * 0.5); + let filteredBloom = sampleBox(source0, input.uv, offset); + let scene = select( + vec4f(0.0), + textureSampleLevel(source1, linearSampler, input.uv, 0.0), + params.hasScene != 0u, + ); + let sceneEnergy = select( + vec4f(0.0), + textureSampleLevel(source2, linearSampler, input.uv, 0.0), + params.hasScene != 0u, + ); + var sceneLinear = scene.rgb; + + if ( + params.transparentOverlay != 0u && + params.visualMaxAlpha != 0u && + params.hostAdditive == 0u && + params.hasScene != 0u + ) + { + sceneLinear = sceneEnergy.rgb; + } + + let linear = sceneLinear + filteredBloom.rgb * max(0.0, params.intensity); + let sceneCoverage = select(0.0, clamp(scene.a, 0.0, 1.0), params.hasScene != 0u); + let bloomCoverage = linearToSrgb( + max(0.0, filteredBloom.a) * max(0.0, params.intensity), + ); + let requestedCoverage = select( + sceneCoverage + bloomCoverage, + max(sceneCoverage, bloomCoverage), + params.visualMaxAlpha != 0u, + ); + + let backgroundUv = (input.uv - vec2f(0.5)) * + params.backgroundUvScale + vec2f(0.5); + let sampledBackground = textureSampleLevel( + source3, + linearSampler, + backgroundUv, + 0.0, + ).rgb; + // Extended 输出需要独立展示映射;整体增益只放大背景上方的特效增量。 + let mappedExtendedLinear = mapExtendedHdrPresentation(linear); + let presentationBackground = select( + vec3f(0.0), + sampledBackground, + params.hasBackground != 0u, + ); + let extendedEffectDelta = preserveHdrEffectHue( + mappedExtendedLinear, + linear, + presentationBackground, + ); + let extendedDisplayLinear = presentationBackground + + extendedEffectDelta * + clamp(params.hdrBrightness, 0.0, 32.0); + let extendedSrgb = linearToExtendedSrgb3(extendedDisplayLinear); + + if (params.extendedOutput != 0u && params.hasBackground == 0u) + { + var alpha = clamp( + max( + requestedCoverage, + max(max(extendedSrgb.r, extendedSrgb.g), extendedSrgb.b), + ), + 0.0, + 1.0, + ); + + if (params.transparentOverlay != 0u && params.hostAdditive == 0u) + { + alpha = min(alpha, clamp(params.overlayAlphaLimit, 0.0, 1.0)); + } + + if (alpha <= 0.00001) + { + return vec4f(0.0); + } + + // rgba16float Canvas 仍按 sRGB 编码解释;extended 只扩展可显示范围。 + return vec4f(extendedSrgb, alpha); + } + + let srgb = linearToSrgb3(linear); + + if (params.extendedOutput != 0u && params.hasBackground != 0u) + { + let backgroundExtendedSrgb = linearToExtendedSrgb3(sampledBackground); + let difference = abs(extendedSrgb - backgroundExtendedSrgb); + + if (max(max(difference.r, difference.g), difference.b) <= 0.00001) + { + return vec4f(0.0); + } + + let channelAlpha = vec3f( + solveOverlayAlpha(backgroundExtendedSrgb.r, extendedSrgb.r), + solveOverlayAlpha(backgroundExtendedSrgb.g, extendedSrgb.g), + solveOverlayAlpha(backgroundExtendedSrgb.b, extendedSrgb.b), + ); + let alpha = clamp( + max(max(channelAlpha.r, channelAlpha.g), channelAlpha.b), + 0.0, + 1.0, + ); + let premultiplied = extendedSrgb - + backgroundExtendedSrgb * (1.0 - alpha); + + // 在 Canvas 的 sRGB 编码域反解,避免 SDR 中间调在最终合成时变深。 + return vec4f(max(premultiplied, vec3f(0.0)), alpha); + } + + if (params.hasBackground != 0u) + { + let backgroundSrgb = linearToSrgb3(sampledBackground); + let difference = abs(srgb - backgroundSrgb); + + if (max(max(difference.r, difference.g), difference.b) <= 0.00001) + { + return vec4f(0.0); + } + + let channelAlpha = vec3f( + solveOverlayAlpha(backgroundSrgb.r, srgb.r), + solveOverlayAlpha(backgroundSrgb.g, srgb.g), + solveOverlayAlpha(backgroundSrgb.b, srgb.b), + ); + let alpha = clamp(max(max(channelAlpha.r, channelAlpha.g), channelAlpha.b), 0.0, 1.0); + let premultiplied = srgb - backgroundSrgb * (1.0 - alpha); + return vec4f(clamp(premultiplied, vec3f(0.0), vec3f(alpha)), alpha); + } + + if (params.transparentOverlay != 0u) + { + let capacity = min(requestedCoverage, 1.0); + + if (params.hostAdditive != 0u) + { + let alpha = clamp(max(max(max(srgb.r, srgb.g), srgb.b), capacity), 0.0, 1.0); + return select(vec4f(srgb, alpha), vec4f(0.0), alpha <= 0.00001); + } + + let alpha = min(capacity, clamp(params.overlayAlphaLimit, 0.0, 1.0)); + + if (alpha <= 0.00001) + { + return vec4f(0.0); + } + + let maximumSrgb = max(max(srgb.r, srgb.g), srgb.b); + let scale = select( + min(1.0, alpha / max(capacity, 0.000001)), + min(1.0, alpha / max(maximumSrgb, 0.000001)), + params.visualMaxAlpha != 0u, + ); + var premultiplied = srgb * scale; + + if (params.brightUnknownBackground != 0u) + { + let safeOpacity = max(params.opacity, 0.000001); + let normalizedCoverage = clamp(alpha / safeOpacity, 0.0, 1.0); + let maximumPremultiplied = max( + max(premultiplied.r, premultiplied.g), + premultiplied.b, + ); + let normalizedEnergy = maximumPremultiplied / safeOpacity; + let energyRatio = normalizedEnergy / max(normalizedCoverage, 0.000001); + let gate = smoothstep(0.25, 0.75, energyRatio) * + smoothstep(0.03125, 0.25, normalizedEnergy); + + premultiplied = mix( + premultiplied, + vec3f(maximumPremultiplied), + 0.35 * gate, + ); + } + + return vec4f(premultiplied, alpha); + } + + let maximumSrgb = max(max(srgb.r, srgb.g), srgb.b); + let alpha = select( + maximumSrgb, + max(clamp(scene.a, 0.0, 1.0), maximumSrgb), + params.hasScene != 0u, + ); + return select(vec4f(srgb, alpha), vec4f(0.0), maximumSrgb <= 0.00001 && alpha <= 0.00001); +} +`,Ir=Float32Array.BYTES_PER_ELEMENT,Lr=6,Rr=8,zr=9,Br=9,Vr=96,Hr=32,Ur=`rgba16float`,Wr=globalThis.GPUTextureUsage??{COPY_DST:2,TEXTURE_BINDING:4,RENDER_ATTACHMENT:16},Gr=globalThis.GPUBufferUsage??{COPY_DST:8,VERTEX:32,UNIFORM:64};function Kr(e,t,n){return Math.max(t,Math.min(n,e))}function qr(e){if(!e)return null;try{let t=e.naturalWidth??e.videoWidth??e.displayWidth??e.width,n=e.naturalHeight??e.videoHeight??e.displayHeight??e.height;if(Number.isFinite(t)&&Number.isFinite(n)&&t>0&&n>0)return{width:t,height:n}}catch{}return null}function Jr(e){let t=256;for(;t({shaderLocation:e,offset:t*Ir,format:n}))}}var $r=Qr(Lr,[[0,0,`float32x2`],[1,2,`float32x3`],[2,5,`float32`]]),ei=Qr(Br,[[0,0,`float32x2`],[1,2,`float32x2`],[2,4,`float32x3`],[3,7,`float32`],[4,8,`float32`]]),ti=Qr(Rr,[[0,0,`float32x2`],[1,2,`float32x2`],[2,4,`float32x3`],[3,7,`float32`]]),ni=Qr(zr,[[0,0,`float32x2`],[1,2,`float32x2`],[2,4,`float32x3`],[3,7,`float32`],[4,8,`float32`]]),ri=Object.freeze({color:{srcFactor:`one`,dstFactor:`one`,operation:`add`},alpha:{srcFactor:`one`,dstFactor:`one-minus-src-alpha`,operation:`add`}}),ii=Object.freeze({color:{srcFactor:`one`,dstFactor:`one`,operation:`add`},alpha:{srcFactor:`zero`,dstFactor:`one`,operation:`add`}}),ai=Object.freeze({color:{srcFactor:`one`,dstFactor:`one-minus-src-alpha`,operation:`add`},alpha:{srcFactor:`one`,dstFactor:`one-minus-src-alpha`,operation:`add`}}),oi=Object.freeze({color:{srcFactor:`src-alpha`,dstFactor:`one`,operation:`add`},alpha:{srcFactor:`zero`,dstFactor:`one`,operation:`add`}}),si=class extends Tr{constructor(e,t={}){super(e,{initialize:!1}),this.status=`pending`,this.deviceManager=new Nr(e,{gpu:t.gpu,onStateChange:(e,t)=>{t===this.deviceManager&&this._handleDeviceState(e,t)}}),this.onStateChange=typeof t.onStateChange==`function`?t.onStateChange:null,this.preferHdr=t.preferHdr!==!1,this.device=null,this.context=null,this.geometryModule=null,this.fullscreenModule=null,this.sampler=null,this.geometryUniform=null,this.bloomGeometryUniform=null,this.backgroundUniform=null,this.prefilterUniform=null,this.finalUniform=null,this.vertexBuffers={},this.textures={},this.pipelines=null,this.finalPipeline=null,this.finalPipelineFormat=null,this.sceneBackgroundTexture=null,this.sceneBackgroundView=null,this.backgroundBindGroup=null,this.placeholderTexture=null,this.placeholderView=null,this.ready=this.deviceManager.ready.then(e=>e?this._initializeWebGPU():(this._handleDeviceState(this.deviceManager.status,this.deviceManager),!1))}get hdrOutput(){return this.deviceManager.hdrOutput}setPreferHdr(e){let t=e!==!1;return this.preferHdr===t?!1:(this.preferHdr=t,!0)}_setRendererStatus(e,t=null){this.status===e&&this.failure===t||(this.status=e,this.failure=t,this.onStateChange?.(e,this))}_handleDeviceState(e,t=this.deviceManager){e===`lost`?(this.available=!1,this.contextLost=!0,this._setRendererStatus(`lost`,t.failure)):e===`unavailable`&&this._setRendererStatus(`unavailable`,t.failure)}_createUniformBuffer(e,t){return this.device.createBuffer({label:e,size:t,usage:Gr.UNIFORM|Gr.COPY_DST})}_createGeometryPipeline(e,t,n,r){return this.device.createRenderPipeline({layout:`auto`,vertex:{module:this.geometryModule,entryPoint:e,buffers:[n]},fragment:{module:this.geometryModule,entryPoint:t,targets:[{format:Ur,blend:r}]},primitive:{topology:`triangle-list`}})}_createFullscreenPipeline(e,t=Ur){return this.device.createRenderPipeline({layout:`auto`,vertex:{module:this.fullscreenModule,entryPoint:`vertexFullscreen`},fragment:{module:this.fullscreenModule,entryPoint:e,targets:[{format:t}]},primitive:{topology:`triangle-list`}})}async _initializeWebGPU(){if(this.status===`destroyed`)return!1;try{this.device=this.deviceManager.device,this.context=this.deviceManager.context,this.maximumTextureSize=this.device.limits?.maxTextureDimension2D??8192,this.maximumViewportWidth=this.maximumTextureSize,this.maximumViewportHeight=this.maximumTextureSize,this.geometryModule=this.device.createShaderModule({label:`BA Click FX WebGPU geometry`,code:Pr}),this.fullscreenModule=this.device.createShaderModule({label:`BA Click FX WebGPU fullscreen`,code:Fr});let e=(await Promise.all([this.geometryModule.getCompilationInfo?.(),this.fullscreenModule.getCompilationInfo?.()])).flatMap(e=>e?.messages?.filter(e=>e.type===`error`)??[]);if(e.length>0)throw Error(e.map(e=>`${e.lineNum??`?`}:${e.linePos??`?`} `+e.message).join(` +`));this.sampler=this.device.createSampler({magFilter:`linear`,minFilter:`linear`,addressModeU:`clamp-to-edge`,addressModeV:`clamp-to-edge`}),this.geometryUniform=this._createUniformBuffer(`BA Click FX geometry uniforms`,Hr),this.bloomGeometryUniform=this._createUniformBuffer(`BA Click FX scaled bloom geometry uniforms`,Hr),this.backgroundUniform=this._createUniformBuffer(`BA Click FX background uniforms`,Vr),this.prefilterUniform=this._createUniformBuffer(`BA Click FX prefilter uniforms`,Vr),this.finalUniform=this._createUniformBuffer(`BA Click FX final uniforms`,Vr),this._createMaterialTextures(),this.device.pushErrorScope?.(`validation`),this._createPipelines();let t=await this.device.popErrorScope?.();if(t)throw t;return this.available=!0,this.contextLost=!1,this._setRendererStatus(`ready`),this.sceneBackgroundSource!==null&&this._uploadSceneBackground(),!0}catch(e){return console.warn(`[BAClickFX] WebGPU 资源初始化失败:`,e),this.available=!1,this._setRendererStatus(`unavailable`,e),!1}}_createMaterialTextures(){this.textures.ring=Zr(this.device,256,128,`r8unorm`,Pn,`BA Click FX Ring3`),this.textures.circle=Zr(this.device,512,512,`rgba8unorm-srgb`,Tn,`BA Click FX Circle_01`),this.textures.triangle=Zr(this.device,128,128,`rgba8unorm-srgb`,V,`BA Click FX triangle`),this.textures.triangleOverlay=Zr(this.device,128,128,`rgba8unorm-srgb`,gn,`BA Click FX triangle overlay`),this.textures.trail=Zr(this.device,512,512,`rgba8unorm-srgb`,Yn,`BA Click FX Trail_03`),this.placeholderTexture=Zr(this.device,1,1,`rgba8unorm`,new Uint8Array(4),`BA Click FX empty texture`),this.placeholderView=this.placeholderTexture.createView()}_createPipelines(){this.pipelines={genericOverlay:this._createGeometryPipeline(`vertexGeneric`,`fragmentGeneric`,$r,ri),genericScene:this._createGeometryPipeline(`vertexGeneric`,`fragmentGeneric`,$r,ii),triangleOverlay:this._createGeometryPipeline(`vertexTextured`,`fragmentTriangle`,ei,ri),triangleScene:this._createGeometryPipeline(`vertexTextured`,`fragmentTriangle`,ei,ii),trailOverlay:this._createGeometryPipeline(`vertexTextured`,`fragmentTrail`,ei,ri),trailScene:this._createGeometryPipeline(`vertexTextured`,`fragmentTrail`,ei,ii),disk:this._createGeometryPipeline(`vertexDisk`,`fragmentDisk`,ti,ai),ringOverlay:this._createGeometryPipeline(`vertexRing`,`fragmentRing`,ni,ri),ringScene:this._createGeometryPipeline(`vertexRing`,`fragmentRing`,ni,oi),background:this._createFullscreenPipeline(`fragmentBackground`),sceneOverlay:this._createFullscreenPipeline(`fragmentSceneOverlay`),prefilter:this._createFullscreenPipeline(`fragmentPrefilter`),downsample:this._createFullscreenPipeline(`fragmentDownsample`),upsample:this._createFullscreenPipeline(`fragmentUpsample`)}}_createPassUniform(e={}){let t=new ArrayBuffer(Vr),n=new Float32Array(t),r=new Uint32Array(t);return n[0]=e.texelX??1,n[1]=e.texelY??1,n[2]=e.backgroundScaleX??1,n[3]=e.backgroundScaleY??1,n[4]=e.sampleScale??1,n[5]=e.threshold??0,n[6]=e.softKnee??0,n[7]=e.clampMax??65504,n[8]=e.intensity??0,n[9]=e.overlayAlphaLimit??1,n[10]=e.opacity??1,r[11]=+!!e.hasScene,r[12]=+!!e.hasBackground,r[13]=+!!e.transparentOverlay,r[14]=+!!e.visualMaxAlpha,r[15]=+!!e.brightUnknownBackground,r[16]=+!!e.hostAdditive,r[17]=+!!e.extendedOutput,n[18]=e.hdrPeak??p.peak,n[19]=e.hdrWhiteCore??p.whiteCore,n[20]=e.hdrWhiteStart??p.whiteStart,n[21]=e.hdrWhiteEnd??p.whiteEnd,n[22]=e.hdrBrightness??p.brightness,n[23]=e.hdrColorPreservation??p.colorPreservation,t}_getBackgroundUvScale(){if(this.sceneBackgroundWidth<=0||this.sceneBackgroundHeight<=0)return[1,1];let e=this.sceneBackgroundWidth/this.sceneBackgroundHeight,t=this.displayWidth/this.displayHeight;return e>t?[t/e,1]:[1,e/t]}_writeGeometryUniform(e,t,n={}){let r=new ArrayBuffer(Hr),i=new Float32Array(r),a=new Uint32Array(r);i[0]=this.displayWidth,i[1]=this.displayHeight,i[2]=Math.max(0,n.disk??1),i[3]=Math.max(0,n.ring??1),a[4]=+!!t,this.device.queue.writeBuffer(e,0,r)}_ensureVertexBuffer(e,t,n,r){if(n<=0)return null;let i=n*r*Ir,a=this.vertexBuffers[e];if(!a||a.size>1),t=Math.max(1,t>>1)}return this.stats.levelCount=this.levels.length,this.stats.bloomPixels=this.levels.reduce((e,t)=>e+t.width*t.height,0),this.levels.length>0}catch(e){return console.warn(`[BAClickFX] WebGPU Scene 缓冲创建失败:`,e),this._deleteTargets(),!1}}_ensureFinalPipeline(){let e=this.deviceManager.canvasFormat;return this.finalPipeline&&this.finalPipelineFormat===e?!0:(this.finalPipeline=this._createFullscreenPipeline(`fragmentFinal`,e),this.finalPipelineFormat=e,!0)}resize(e,t,n,r,i){if(!this.available||this.contextLost)return!1;let a=Math.max(1,e),o=Math.max(1,t),s=Kr(n,1,4),c=Kr(r,.1,.75),l=Math.max(1,Math.round(a*s)),u=Math.max(1,Math.round(o*s)),d=Math.max(1,Math.floor(l*c)),f=Math.max(1,Math.floor(u*c)),p=Kr(i,0,10);if(l>this.maximumTextureSize||u>this.maximumTextureSize)return!1;let m=l===this.sourceWidth&&u===this.sourceHeight&&d===this.width&&f===this.height&&p===this.diffusion&&this.sourceTarget!==null&&this.levels.length>0;return this.displayWidth=a,this.displayHeight=o,this.dpr=s,this.resolutionScale=c,this.diffusion=p,this.sourceWidth=l,this.sourceHeight=u,this.width=d,this.height=f,(this.canvas.width!==l||this.canvas.height!==u)&&(this.canvas.width=l,this.canvas.height=u),this.deviceManager.configure({preferHdr:this.preferHdr})?(this._ensureFinalPipeline(),m||this._allocateTargets()):!1}_uploadSceneBackground(){if(!this.available||!this.device||!this.sceneBackgroundSource||this.sceneBackgroundWidth<=0||this.sceneBackgroundHeight<=0)return!1;let e=null;try{return e=this.device.createTexture({label:`BA Click FX WebGPU compositing reference`,size:{width:this.sceneBackgroundWidth,height:this.sceneBackgroundHeight},format:`rgba8unorm-srgb`,usage:Wr.COPY_DST|Wr.TEXTURE_BINDING|Wr.RENDER_ATTACHMENT}),this.device.queue.copyExternalImageToTexture({source:this.sceneBackgroundSource},{texture:e},{width:this.sceneBackgroundWidth,height:this.sceneBackgroundHeight}),this.sceneBackgroundTexture?.destroy?.(),this.sceneBackgroundTexture=e,this.sceneBackgroundView=e.createView(),!0}catch(t){return e?.destroy?.(),console.warn(`[BAClickFX] WebGPU 合成参考上传失败:`,t),!1}}setCompositingReference(e,t={}){if(e===null)return this.sceneBackgroundTexture?.destroy?.(),this.sceneBackgroundTexture=null,this.sceneBackgroundView=null,this.sceneBackgroundSource=null,this.sceneBackgroundWidth=0,this.sceneBackgroundHeight=0,!0;if(t.fit!==void 0&&t.fit!==`cover`)return!1;let n=qr(e);if(!n)return!1;let r={source:this.sceneBackgroundSource,width:this.sceneBackgroundWidth,height:this.sceneBackgroundHeight};return this.sceneBackgroundSource=e,this.sceneBackgroundWidth=n.width,this.sceneBackgroundHeight=n.height,!this.available||this._uploadSceneBackground()?!0:(this.sceneBackgroundSource=r.source,this.sceneBackgroundWidth=r.width,this.sceneBackgroundHeight=r.height,!1)}_ensureBloomSourceTarget(){return this.bloomSourceTarget?.width===this.sourceWidth&&this.bloomSourceTarget?.height===this.sourceHeight?!0:(Yr(this.bloomSourceTarget),this.bloomSourceTarget=Xr(this.device,this.sourceWidth,this.sourceHeight,`BA Click FX WebGPU scaled bloom source`),!0)}renderScene(e={}){if(!this.available||this.contextLost||!this.sourceTarget)return!1;try{let t=this.device.createCommandEncoder({label:`BA Click FX WebGPU scene commands`});this.sceneBackgroundFrameReady=this._renderGeometryTarget(t,this.sourceTarget,this.geometryUniform,e);let n=Math.max(0,e.diskEmissionScale??1),r=Math.max(0,e.ringEmissionScale??1);return this.bloomSourceFrameReady=!1,n!==1||r!==1?(this._ensureBloomSourceTarget(),this._renderGeometryTarget(t,this.bloomSourceTarget,this.bloomGeometryUniform,e,{disk:n,ring:r}),this.bloomSourceFrameReady=!0):(Yr(this.bloomSourceTarget),this.bloomSourceTarget=null),this.sceneOverlayFrameReady=!1,e.outputCompositing===`browser-overlay`&&!Me(e.hostCompositing)&&(this._drawFullscreen(t,this.pipelines.sceneOverlay,this.sceneOverlayTarget.view,null,[this.sourceTarget.view],`BA Click FX WebGPU scene coverage`),this.sceneOverlayFrameReady=!0),this.device.queue.submit([t.finish()]),this.sceneFrameReady=!0,this.stats.sceneVertexCount=this.vertexCount+this.triangleVertexCount+this.trailVertexCount,this.stats.sceneDiskVertexCount=this.sceneDiskVertexCount,this.stats.sceneRingVertexCount=this.ringVertexCount,this.stats.sceneTriangleVertexCount=this.triangleVertexCount,this.stats.sceneTrailVertexCount=this.trailVertexCount,!0}catch(e){return console.warn(`[BAClickFX] WebGPU 清晰特效渲染失败:`,e),this.available=!1,this._setRendererStatus(`unavailable`,e),!1}}_renderBloomPasses(e,t){let n=this.bloomSourceFrameReady?this.bloomSourceTarget:this.sourceTarget,r=this.levels[0],i=this._createPassUniform({texelX:1/this.sourceWidth,texelY:1/this.sourceHeight,threshold:wt(t.threshold),softKnee:Kr(t.softKnee??0,0,1),clampMax:Tt(t.clamp)});this.device.queue.writeBuffer(this.prefilterUniform,0,i),this._drawFullscreen(e,this.pipelines.prefilter,r.down.view,this.prefilterUniform,[n.view],`BA Click FX WebGPU bloom prefilter`);for(let t=1;t=0;t--){let n=this.levels[t],r=this.levels[t+1],i=this._createPassUniform({texelX:1/r.width,texelY:1/r.height,sampleScale:this.sampleScale});this.device.queue.writeBuffer(n.upUniform,0,i),this._drawFullscreen(e,this.pipelines.upsample,n.up.view,n.upUniform,[a.view,n.down.view],`BA Click FX WebGPU bloom upsample ${t}`),a=n.up}return a}render(e,t={}){if(!this.available||this.contextLost||!this.sourceTarget||this.levels.length===0||!this.finalPipeline)return!1;try{let n=t.preserveCanvas===!0&&this.sceneFrameReady,r=this.device.createCommandEncoder({label:`BA Click FX WebGPU bloom commands`}),i=this._renderBloomPasses(r,e),[a,o]=this._getBackgroundUvScale(),s=n&&this.sceneBackgroundFrameReady,c=n&&!s&&e.outputCompositing===`browser-overlay`&&!Me(e.hostCompositing)&&this.sceneOverlayFrameReady,l=this._createPassUniform({texelX:1/i.width,texelY:1/i.height,backgroundScaleX:a,backgroundScaleY:o,sampleScale:this.sampleScale,intensity:Ct(e.intensity),overlayAlphaLimit:Kr(e.overlayAlphaLimit??1,0,1),opacity:Kr(e.opacity??1,0,1),hasScene:n,hasBackground:s,transparentOverlay:e.outputCompositing===`browser-overlay`,visualMaxAlpha:e.overlayAlphaPolicy===`visual-max`,brightUnknownBackground:e.overlayColorCompensation===`bright-core`,hostAdditive:Me(e.hostCompositing),extendedOutput:this.hdrOutput,hdrPeak:e.webgpuHdrPeak,hdrBrightness:e.webgpuHdrBrightness,hdrColorPreservation:e.webgpuHdrColorPreservation,hdrWhiteCore:e.webgpuHdrWhiteCore,hdrWhiteStart:e.webgpuHdrWhiteStart,hdrWhiteEnd:e.webgpuHdrWhiteEnd});return this.device.queue.writeBuffer(this.finalUniform,0,l),this._drawFullscreen(r,this.finalPipeline,this.context.getCurrentTexture().createView(),this.finalUniform,[i.view,n?c?this.sceneOverlayTarget.view:this.sourceTarget.view:this.placeholderView,n?this.sourceTarget.view:this.placeholderView,s?this.sceneBackgroundView:this.placeholderView],`BA Click FX WebGPU final`),this.device.queue.submit([r.finish()]),this.stats.vertexCount=this.vertexCount+this.triangleVertexCount+this.trailVertexCount,this.stats.diskVertexCount=this.sceneDiskVertexCount,this.stats.ringVertexCount=this.ringVertexCount,this.stats.triangleVertexCount=this.triangleVertexCount,this.stats.trailVertexCount=this.trailVertexCount,!0}catch(e){return console.warn(`[BAClickFX] WebGPU Scene 渲染失败:`,e),this.available=!1,this._setRendererStatus(`unavailable`,e),!1}}clear(){if(this.sceneFrameReady=!1,this.bloomSourceFrameReady=!1,this.sceneOverlayFrameReady=!1,this.sceneBackgroundFrameReady=!1,!(!this.available||!this.finalPipeline||this.deviceManager.outputMode===`unconfigured`))try{let e=this.device.createCommandEncoder();e.beginRenderPass({colorAttachments:[{view:this.context.getCurrentTexture().createView(),loadOp:`clear`,storeOp:`store`,clearValue:{r:0,g:0,b:0,a:0}}]}).end(),this.device.queue.submit([e.finish()])}catch{}}suspendPresentation(){return this.sceneFrameReady=!1,this.bloomSourceFrameReady=!1,this.sceneOverlayFrameReady=!1,this.sceneBackgroundFrameReady=!1,this.deviceManager.unconfigure()}releaseFrameResources(){let e=this.suspendPresentation();return this._deleteTargets(),this.beginFrame(),e}destroy(){if(this.status!==`destroyed`){this._setRendererStatus(`destroyed`),this._deleteTargets();for(let e of Object.values(this.vertexBuffers))e.buffer?.destroy?.();for(let e of Object.values(this.textures))e?.destroy?.();this.placeholderTexture?.destroy?.(),this.sceneBackgroundTexture?.destroy?.(),this.geometryUniform?.destroy?.(),this.bloomGeometryUniform?.destroy?.(),this.backgroundUniform?.destroy?.(),this.prefilterUniform?.destroy?.(),this.finalUniform?.destroy?.(),this.deviceManager.destroy(),this.available=!1,this.contextLost=!1,this.vertexCount=0,this.sceneDiskVertexCount=0,this.ringVertexCount=0,this.triangleVertexCount=0,this.trailVertexCount=0}}},ci=5,li=48,ui=`#version 300 es +precision highp float; + +out vec2 v_uv; + +void main() +{ + vec2 positions[3] = vec2[]( + vec2(-1.0, -1.0), + vec2(3.0, -1.0), + vec2(-1.0, 3.0) + ); + vec2 position = positions[gl_VertexID]; + + gl_Position = vec4(position, 0.0, 1.0); + v_uv = position * 0.5 + 0.5; +} +`,di=`#version 300 es +precision highp float; + +layout(location = 0) in vec2 a_position; +layout(location = 1) in vec2 a_uv; +layout(location = 2) in float a_particleAlpha; + +uniform vec2 u_displaySize; + +out vec2 v_uv; +out float v_particleAlpha; + +void main() +{ + vec2 normalized = a_position / u_displaySize; + + gl_Position = vec4( + normalized.x * 2.0 - 1.0, + 1.0 - normalized.y * 2.0, + 0.0, + 1.0 + ); + v_uv = a_uv; + v_particleAlpha = a_particleAlpha; +} +`,fi=`#version 300 es +precision highp float; + +uniform sampler2D u_circle; + +in vec2 v_uv; +in float v_particleAlpha; +out vec4 outColor; + +void main() +{ + // Circle_01 以 sRGB 导入;SRGB8_ALPHA8 在采样时恢复 Shader 读取的线性 R。 + float coverage = texture(u_circle, v_uv).r * + clamp(v_particleAlpha, 0.0, 1.0); + + outColor = vec4(coverage, 0.0, 0.0, coverage); +} +`,pi=`#version 300 es +precision highp float; + +uniform sampler2D u_effect; +uniform sampler2D u_coverage; +uniform sampler2D u_background; +uniform vec2 u_backgroundUvScale; + +in vec2 v_uv; +out vec4 outColor; + +float linearToSrgb(float value) +{ + float linear = clamp(value, 0.0, 1.0); + + if (linear <= 0.0031308) + { + return linear * 12.92; + } + + return 1.055 * pow(linear, 1.0 / 2.4) - 0.055; +} + +float solveOverlayAlpha(float background, float target) +{ + if (target > background) + { + return (target - background) / max(1.0 - background, 0.000001); + } + + if (target < background) + { + return (background - target) / max(background, 0.000001); + } + + return 0.0; +} + +void main() +{ + // DOM Canvas 上传保持顶行原点,所有浏览器统一在 Shader 中翻转。 + vec2 canvasUv = vec2(v_uv.x, 1.0 - v_uv.y); + vec3 effectLinear = texture(u_effect, canvasUv).rgb; + float coverage = clamp(texture(u_coverage, v_uv).r, 0.0, 1.0); + vec2 backgroundUv = (v_uv - 0.5) * u_backgroundUvScale + 0.5; + + backgroundUv.y = 1.0 - backgroundUv.y; + + vec3 backgroundLinear = texture(u_background, backgroundUv).rgb; + vec3 linear = effectLinear + backgroundLinear * (1.0 - coverage); + vec3 targetSrgb = vec3( + linearToSrgb(linear.r), + linearToSrgb(linear.g), + linearToSrgb(linear.b) + ); + vec3 backgroundSrgb = vec3( + linearToSrgb(backgroundLinear.r), + linearToSrgb(backgroundLinear.g), + linearToSrgb(backgroundLinear.b) + ); + vec3 difference = abs(targetSrgb - backgroundSrgb); + + if (max(max(difference.r, difference.g), difference.b) <= 0.00001) + { + outColor = vec4(0.0); + return; + } + + vec3 channelAlpha = vec3( + solveOverlayAlpha(backgroundSrgb.r, targetSrgb.r), + solveOverlayAlpha(backgroundSrgb.g, targetSrgb.g), + solveOverlayAlpha(backgroundSrgb.b, targetSrgb.b) + ); + float overlayAlpha = clamp( + max(max(channelAlpha.r, channelAlpha.g), channelAlpha.b), + 0.0, + 1.0 + ); + vec3 premultiplied = targetSrgb - + backgroundSrgb * (1.0 - overlayAlpha); + + outColor = vec4( + clamp(premultiplied, vec3(0.0), vec3(overlayAlpha)), + overlayAlpha + ); +} +`;function mi(e,t,n){return Math.max(t,Math.min(n,e))}function hi(e){if(!e)return null;let t,n;try{t=e.naturalWidth??e.videoWidth??e.displayWidth??e.width,n=e.naturalHeight??e.videoHeight??e.displayHeight??e.height}catch{return null}return!Number.isFinite(t)||!Number.isFinite(n)||t<=0||n<=0?null:{width:t,height:n}}function gi(e,t,n){let r=e.createShader(t);if(!r)throw Error(`Canvas Scene Final Pass 无法创建 Shader`);if(e.shaderSource(r,n),e.compileShader(r),!e.getShaderParameter(r,e.COMPILE_STATUS)){let t=e.getShaderInfoLog(r)||`未知编译错误`;throw e.deleteShader(r),Error(t)}return r}function _i(e,t,n){let r=gi(e,e.VERTEX_SHADER,t),i=gi(e,e.FRAGMENT_SHADER,n),a=e.createProgram();if(!a)throw e.deleteShader(r),e.deleteShader(i),Error(`Canvas Scene Final Pass 无法创建 Program`);if(e.attachShader(a,r),e.attachShader(a,i),e.linkProgram(a),e.deleteShader(r),e.deleteShader(i),!e.getProgramParameter(a,e.LINK_STATUS)){let t=e.getProgramInfoLog(a)||`未知链接错误`;throw e.deleteProgram(a),Error(t)}return a}function vi(e,t,n){e.bindTexture(e.TEXTURE_2D,t),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_MIN_FILTER,n),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_MAG_FILTER,n),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_WRAP_S,e.CLAMP_TO_EDGE),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_WRAP_T,e.CLAMP_TO_EDGE)}var yi=class{constructor(e){this.canvas=e,this.gl=null,this.available=!1,this.contextLost=!1,this.destroyed=!1,this.displayWidth=1,this.displayHeight=1,this.dpr=1,this.width=0,this.height=0,this.maximumTextureSize=0,this.maximumViewportWidth=0,this.maximumViewportHeight=0,this.failedResizeSignature=null,this.finalProgram=null,this.coverageProgram=null,this.fullscreenVao=null,this.coverageVao=null,this.coverageBuffer=null,this.effectTexture=null,this.coverageTexture=null,this.coverageFramebuffer=null,this.circleTexture=null,this.backgroundTexture=null,this.backgroundSource=null,this.backgroundWidth=0,this.backgroundHeight=0,this.backgroundUploadRetryPending=!1,this.coverageVertexCount=0,this.coverageVertexData=new Float32Array(li*ci),this._onContextLost=this._handleContextLost.bind(this),this._onContextRestored=this._handleContextRestored.bind(this),this.canvas?.addEventListener?.(`webglcontextlost`,this._onContextLost),this.canvas?.addEventListener?.(`webglcontextrestored`,this._onContextRestored),this._initialize()}get hasSceneBackground(){return this.backgroundTexture!==null}_discardPendingErrors(){let e=this.gl;if(e){for(let t=0;t<8;t++)if(e.getError()===e.NO_ERROR)return}}_initialize(){if(!this.destroyed)try{let e=this.canvas?.getContext?.(`webgl2`,{alpha:!0,antialias:!1,depth:!1,stencil:!1,premultipliedAlpha:!0,preserveDrawingBuffer:!1,powerPreference:`high-performance`});if(!e){this.available=!1;return}this.gl=e,this.failedResizeSignature=null,this.maximumTextureSize=e.getParameter(e.MAX_TEXTURE_SIZE);let t=e.getParameter(e.MAX_VIEWPORT_DIMS);if(this.maximumViewportWidth=t?.[0]??this.maximumTextureSize,this.maximumViewportHeight=t?.[1]??this.maximumTextureSize,this.finalProgram=_i(e,ui,pi),this.coverageProgram=_i(e,di,fi),this.fullscreenVao=e.createVertexArray(),this.coverageVao=e.createVertexArray(),this.coverageBuffer=e.createBuffer(),this.circleTexture=e.createTexture(),!this.fullscreenVao||!this.coverageVao||!this.coverageBuffer||!this.circleTexture)throw Error(`Canvas Scene Final Pass 资源分配失败`);e.bindVertexArray(this.coverageVao),e.bindBuffer(e.ARRAY_BUFFER,this.coverageBuffer);let n=ci*Float32Array.BYTES_PER_ELEMENT;e.enableVertexAttribArray(0),e.vertexAttribPointer(0,2,e.FLOAT,!1,n,0),e.enableVertexAttribArray(1),e.vertexAttribPointer(1,2,e.FLOAT,!1,n,2*Float32Array.BYTES_PER_ELEMENT),e.enableVertexAttribArray(2),e.vertexAttribPointer(2,1,e.FLOAT,!1,n,4*Float32Array.BYTES_PER_ELEMENT),e.bindVertexArray(null),e.bindBuffer(e.ARRAY_BUFFER,null),vi(e,this.circleTexture,e.LINEAR),e.texImage2D(e.TEXTURE_2D,0,e.SRGB8_ALPHA8,512,512,0,e.RGBA,e.UNSIGNED_BYTE,Tn),e.bindTexture(e.TEXTURE_2D,null),this.contextLost=!1,this.available=!0;let r=this.width,i=this.height;this.width=0,this.height=0,r>0&&i>0&&this._allocateFrameResources(r,i),this.backgroundSource&&(this.backgroundUploadRetryPending=!this._replaceBackgroundTexture(this.backgroundSource))}catch(e){console.warn(`[BAClickFX] Canvas Scene Final Pass 初始化失败:`,e),this.available=!1,this._deleteResources()}}_deleteFrameResources(){let e=this.gl;e&&!this.contextLost&&(e.deleteTexture(this.effectTexture),e.deleteTexture(this.coverageTexture),e.deleteFramebuffer(this.coverageFramebuffer)),this.effectTexture=null,this.coverageTexture=null,this.coverageFramebuffer=null}releaseFrameResources(){this._deleteFrameResources(),this.beginFrame(),this.displayWidth=1,this.displayHeight=1,this.dpr=1,this.width=0,this.height=0,this.failedResizeSignature=null,this.canvas&&(this.canvas.width!==1||this.canvas.height!==1)&&(this.canvas.width=1,this.canvas.height=1)}_deleteResources(){let e=this.gl;this._deleteFrameResources(),e&&!this.contextLost&&(e.deleteProgram(this.finalProgram),e.deleteProgram(this.coverageProgram),e.deleteVertexArray(this.fullscreenVao),e.deleteVertexArray(this.coverageVao),e.deleteBuffer(this.coverageBuffer),e.deleteTexture(this.circleTexture),e.deleteTexture(this.backgroundTexture)),this.finalProgram=null,this.coverageProgram=null,this.fullscreenVao=null,this.coverageVao=null,this.coverageBuffer=null,this.circleTexture=null,this.backgroundTexture=null}_createFrameResources(e,t){let n=this.gl,r=n.createTexture(),i=n.createTexture(),a=n.createFramebuffer();if(!r||!i||!a)return n.deleteTexture(r),n.deleteTexture(i),n.deleteFramebuffer(a),null;try{this._discardPendingErrors(),vi(n,r,n.NEAREST),n.texImage2D(n.TEXTURE_2D,0,n.RGBA8,e,t,0,n.RGBA,n.UNSIGNED_BYTE,null),vi(n,i,n.NEAREST),n.texImage2D(n.TEXTURE_2D,0,n.R8,e,t,0,n.RED,n.UNSIGNED_BYTE,null),n.bindFramebuffer(n.FRAMEBUFFER,a),n.framebufferTexture2D(n.FRAMEBUFFER,n.COLOR_ATTACHMENT0,n.TEXTURE_2D,i,0);let o=n.checkFramebufferStatus(n.FRAMEBUFFER),s=n.getError();if(o!==n.FRAMEBUFFER_COMPLETE||s!==n.NO_ERROR)throw Error(`Coverage FBO 状态 ${o},错误码 ${s}`);return{effectTexture:r,coverageTexture:i,coverageFramebuffer:a}}catch(e){return console.warn(`[BAClickFX] Canvas Scene 帧资源分配失败:`,e),n.deleteTexture(r),n.deleteTexture(i),n.deleteFramebuffer(a),null}finally{n.bindTexture(n.TEXTURE_2D,null),n.bindFramebuffer(n.FRAMEBUFFER,null)}}_allocateFrameResources(e,t){let n=this._createFrameResources(e,t);return n?(this._deleteFrameResources(),this.effectTexture=n.effectTexture,this.coverageTexture=n.coverageTexture,this.coverageFramebuffer=n.coverageFramebuffer,this.width=e,this.height=t,!0):!1}resize(e,t,n){if(!this.available||!this.gl||this.contextLost)return!1;let r=Math.max(1,e),i=Math.max(1,t),a=mi(n,1,4),o=Math.max(1,Math.round(r*a)),s=Math.max(1,Math.round(i*a)),c=`${o}:${s}`;return this.displayWidth=r,this.displayHeight=i,this.dpr=a,c===this.failedResizeSignature?!1:o>this.maximumTextureSize||s>this.maximumTextureSize||o>this.maximumViewportWidth||s>this.maximumViewportHeight?(this.failedResizeSignature=c,!1):this.backgroundUploadRetryPending&&(this.backgroundUploadRetryPending=!1,!this._replaceBackgroundTexture(this.backgroundSource))?!1:o===this.width&&s===this.height&&this.effectTexture&&this.coverageTexture&&this.coverageFramebuffer?(this.failedResizeSignature=null,!0):this._allocateFrameResources(o,s)?(this.canvas.width=o,this.canvas.height=s,this.failedResizeSignature=null,!0):(this.failedResizeSignature=c,!1)}_createBackgroundTexture(e){let t=this.gl,n=t?.createTexture();if(!t||!n)return null;let r=t.getParameter(t.UNPACK_FLIP_Y_WEBGL),i=t.getParameter(t.UNPACK_PREMULTIPLY_ALPHA_WEBGL),a=t.getParameter(t.UNPACK_COLORSPACE_CONVERSION_WEBGL);try{this._discardPendingErrors(),vi(t,n,t.LINEAR),t.pixelStorei(t.UNPACK_FLIP_Y_WEBGL,!1),t.pixelStorei(t.UNPACK_PREMULTIPLY_ALPHA_WEBGL,!1),t.pixelStorei(t.UNPACK_COLORSPACE_CONVERSION_WEBGL,t.NONE),t.texImage2D(t.TEXTURE_2D,0,t.SRGB8_ALPHA8,t.RGBA,t.UNSIGNED_BYTE,e);let r=t.getError();if(r!==t.NO_ERROR)throw Error(`背景纹理上传错误码 ${r}`);return n}catch(e){return console.warn(`[BAClickFX] Canvas Scene 背景上传失败:`,e),t.deleteTexture(n),null}finally{t.pixelStorei(t.UNPACK_FLIP_Y_WEBGL,r),t.pixelStorei(t.UNPACK_PREMULTIPLY_ALPHA_WEBGL,i),t.pixelStorei(t.UNPACK_COLORSPACE_CONVERSION_WEBGL,a),t.bindTexture(t.TEXTURE_2D,null)}}_replaceBackgroundTexture(e){let t=hi(e);if(!t||!this.gl||this.contextLost)return!1;let n=this._createBackgroundTexture(e);return n?(this.gl.deleteTexture(this.backgroundTexture),this.backgroundTexture=n,this.backgroundSource=e,this.backgroundWidth=t.width,this.backgroundHeight=t.height,this.backgroundUploadRetryPending=!1,this.failedResizeSignature=null,!0):!1}setCompositingReference(e,t={}){if(t.fit!==void 0&&t.fit!==`cover`)return!1;if(e===null)return this.gl?.deleteTexture(this.backgroundTexture),this.backgroundTexture=null,this.backgroundSource=null,this.backgroundWidth=0,this.backgroundHeight=0,this.backgroundUploadRetryPending=!1,this.failedResizeSignature=null,!0;let n=hi(e);return n?this.contextLost||!this.gl?(this.backgroundSource=e,this.backgroundWidth=n.width,this.backgroundHeight=n.height,this.backgroundUploadRetryPending=!0,!0):this._replaceBackgroundTexture(e):!1}beginFrame(){this.coverageVertexCount=0}_ensureCoverageVertexCapacity(e){let t=(this.coverageVertexCount+e)*ci;if(t<=this.coverageVertexData.length)return;let n=this.coverageVertexData.length;for(;n{this._appendCoverageVertex(e+n*o-i*s,t+n*s+i*o,a,c,r)};this._ensureCoverageVertexCapacity(6),c(-n,-n,0,0),c(n,-n,1,0),c(n,n,1,1),c(-n,-n,0,0),c(n,n,1,1),c(-n,n,0,1)}_uploadEffectCanvas(e){let t=this.gl,n=t.getParameter(t.UNPACK_FLIP_Y_WEBGL),r=t.getParameter(t.UNPACK_PREMULTIPLY_ALPHA_WEBGL),i=t.getParameter(t.UNPACK_COLORSPACE_CONVERSION_WEBGL);try{return this._discardPendingErrors(),t.bindTexture(t.TEXTURE_2D,this.effectTexture),t.pixelStorei(t.UNPACK_FLIP_Y_WEBGL,!1),t.pixelStorei(t.UNPACK_PREMULTIPLY_ALPHA_WEBGL,!0),t.pixelStorei(t.UNPACK_COLORSPACE_CONVERSION_WEBGL,t.NONE),t.texSubImage2D(t.TEXTURE_2D,0,0,0,t.RGBA,t.UNSIGNED_BYTE,e),t.getError()===t.NO_ERROR}catch{return!1}finally{t.pixelStorei(t.UNPACK_FLIP_Y_WEBGL,n),t.pixelStorei(t.UNPACK_PREMULTIPLY_ALPHA_WEBGL,r),t.pixelStorei(t.UNPACK_COLORSPACE_CONVERSION_WEBGL,i),t.bindTexture(t.TEXTURE_2D,null)}}_drawCoverage(){let e=this.gl;e.bindFramebuffer(e.FRAMEBUFFER,this.coverageFramebuffer),e.viewport(0,0,this.width,this.height),e.disable(e.DEPTH_TEST),e.disable(e.SCISSOR_TEST),e.disable(e.CULL_FACE),e.clearColor(0,0,0,0),e.clear(e.COLOR_BUFFER_BIT),this.coverageVertexCount!==0&&(e.enable(e.BLEND),e.blendEquation(e.FUNC_ADD),e.blendFunc(e.ONE,e.ONE_MINUS_SRC_ALPHA),e.useProgram(this.coverageProgram),e.uniform2f(e.getUniformLocation(this.coverageProgram,`u_displaySize`),this.displayWidth,this.displayHeight),e.activeTexture(e.TEXTURE0),e.bindTexture(e.TEXTURE_2D,this.circleTexture),e.uniform1i(e.getUniformLocation(this.coverageProgram,`u_circle`),0),e.bindVertexArray(this.coverageVao),e.bindBuffer(e.ARRAY_BUFFER,this.coverageBuffer),e.bufferData(e.ARRAY_BUFFER,this.coverageVertexData.subarray(0,this.coverageVertexCount*ci),e.DYNAMIC_DRAW),e.drawArrays(e.TRIANGLES,0,this.coverageVertexCount))}_getBackgroundUvScale(){let e=this.backgroundWidth/this.backgroundHeight,t=this.displayWidth/this.displayHeight;return e>t?[t/e,1]:[1,e/t]}_drawFinal(){let e=this.gl,t=this._getBackgroundUvScale();e.bindFramebuffer(e.FRAMEBUFFER,null),e.viewport(0,0,this.width,this.height),e.disable(e.BLEND),e.disable(e.DEPTH_TEST),e.disable(e.SCISSOR_TEST),e.disable(e.CULL_FACE),e.clearColor(0,0,0,0),e.clear(e.COLOR_BUFFER_BIT),e.useProgram(this.finalProgram),e.activeTexture(e.TEXTURE0),e.bindTexture(e.TEXTURE_2D,this.effectTexture),e.uniform1i(e.getUniformLocation(this.finalProgram,`u_effect`),0),e.activeTexture(e.TEXTURE1),e.bindTexture(e.TEXTURE_2D,this.coverageTexture),e.uniform1i(e.getUniformLocation(this.finalProgram,`u_coverage`),1),e.activeTexture(e.TEXTURE2),e.bindTexture(e.TEXTURE_2D,this.backgroundTexture),e.uniform1i(e.getUniformLocation(this.finalProgram,`u_background`),2),e.uniform2f(e.getUniformLocation(this.finalProgram,`u_backgroundUvScale`),t[0],t[1]),e.bindVertexArray(this.fullscreenVao),e.drawArrays(e.TRIANGLES,0,3)}render(e){if(!this.available||this.contextLost||!this.gl||!this.effectTexture||!this.coverageTexture||!this.coverageFramebuffer||!this.backgroundTexture||e?.width!==this.width||e?.height!==this.height||!this._uploadEffectCanvas(e))return!1;try{return this._discardPendingErrors(),this._drawCoverage(),this._drawFinal(),this.gl.flush(),this.gl.getError()===this.gl.NO_ERROR}catch{return!1}}clear(){!this.gl||this.contextLost||(this.gl.bindFramebuffer(this.gl.FRAMEBUFFER,null),this.gl.viewport(0,0,this.canvas.width,this.canvas.height),this.gl.clearColor(0,0,0,0),this.gl.clear(this.gl.COLOR_BUFFER_BIT))}_handleContextLost(e){e?.preventDefault?.(),this.contextLost=!0,this.available=!1,this.finalProgram=null,this.coverageProgram=null,this.fullscreenVao=null,this.coverageVao=null,this.coverageBuffer=null,this.effectTexture=null,this.coverageTexture=null,this.coverageFramebuffer=null,this.circleTexture=null,this.backgroundTexture=null,this.failedResizeSignature=null,this.backgroundUploadRetryPending=this.backgroundSource!==null}_handleContextRestored(){this.contextLost=!1,this._initialize(),this.failedResizeSignature=null}destroy(){this.destroyed||(this.destroyed=!0,this.canvas?.removeEventListener?.(`webglcontextlost`,this._onContextLost),this.canvas?.removeEventListener?.(`webglcontextrestored`,this._onContextRestored),this._deleteResources(),this.coverageVertexData=new Float32Array,this.coverageVertexCount=0,this.available=!1,this.gl=null,this.backgroundSource=null,this.backgroundWidth=0,this.backgroundHeight=0,this.backgroundUploadRetryPending=!1)}},bi=Math.PI*2;function xi(e){return Math.max(0,Math.min(1,Number(e)||0))}function Si(e,t,n){e.moveTo(t[0][0]*n,t[0][1]*n),e.lineTo(t[1][0]*n,t[1][1]*n),e.lineTo(t[2][0]*n,t[2][1]*n),e.closePath()}function Ci(e){let t=e.reduce((t,n,r)=>{let i=e[(r+1)%e.length];return t+n[0]*i[1]-i[0]*n[1]},0)>=0?1:-1;return{normals:e.map((n,r)=>{let i=e[(r+1)%e.length],a=i[0]-n[0],o=i[1]-n[1],s=Math.max(1e-6,Math.hypot(a,o));return[t*o/s,-t*a/s]}),anticlockwise:t<0}}function wi(e,t,n,r){let i=xi(r);if(i<=0){Si(e,t,n);return}let a=n*i*.5;if(i>=1){e.arc(0,0,a,0,bi,!1),e.closePath();return}let o=n*(1-i),s=t.map(e=>[e[0]*o,e[1]*o]),{normals:c,anticlockwise:l}=Ci(s),u=c.at(-1);e.moveTo(s[0][0]+u[0]*a,s[0][1]+u[1]*a);for(let t=0;t0?(n-r[0])/e:1;return Ei(Di(r[1],i[1],Oi(t)))}}return Ei(e.at(-1)[1])}function Ai(e,t){let n=Ei(e)*511,r=Ei(t)*511,i=Math.floor(n),a=Math.floor(r),o=Math.min(511,i+1),s=Math.min(511,a+1),c=n-i,l=r-a;return Di(Di(qn[a*512+i],qn[a*512+o],c),Di(qn[s*512+i],qn[s*512+o],c),l)/255}function ji(e,t=Ti){let n=Math.max(2,Math.floor(t)),r=1-Ei(e),i=Array(n);for(let e=0;e.5?a/(2-r-i):a/(r+i),c;return c=r===e?(t-n)/a+(t(n<0&&(n+=1),n>1&&--n,n<1/6?e+(t-e)*6*n:n<1/2?t:n<2/3?e+(t-e)*(2/3-n)*6:e);if(t===0)return[n,n,n];let i=n<.5?n*(1+t):n+t-n*t,a=2*n-i;return[r(a,i,e+1/3),r(a,i,e),r(a,i,e-1/3)]}var Gi=0,G=null,Ki=[76,167,255],qi=Ui(Ki[0]/255,Ki[1]/255,Ki[2]/255)[0];function Ji(e){if(!/^#[0-9a-f]{6}$/i.test(e))return 0;let[t,n]=Ui(parseInt(e.slice(1,3),16)/255,parseInt(e.slice(3,5),16)/255,parseInt(e.slice(5,7),16)/255);return n<.02?0:t-qi}function Yi(e){if(Gi===0)return e;let[t,n,r]=Ui(e[0]/255,e[1]/255,e[2]/255);if(n<.02)return e;let i=t+Gi;i-=Math.floor(i);let[a,o,s]=Wi(i,n,r);return[Math.round(a*255),Math.round(o*255),Math.round(s*255)]}function Xi(e){return G?ut(e,G):Yi(e)}function K(e,t,n){return Math.max(t,Math.min(n,e))}function q(e){return K(e,0,1)}function Zi(e,t,n){let r=q((n-e)/(t-e));return r*r*(3-2*r)}function Qi(e,t){let n=e*t;return Number.isFinite(n)?n:Ii}function $i(e,t){return e.x<=t.x+t.width&&t.x<=e.x+e.width&&e.y<=t.y+t.height&&t.y<=e.y+e.height}function ea(e,t){let n=0;for(;n0?(n-r[0])/e:1;return J(r[1],i[1],t)}}return e[e.length-1][1]}function X(e,t){if(!e||e.length===0)return 0;let n=q(t);if(n<=e[0][0])return e[0][1];for(let t=1;t0?(n-r[0])/e:1,a=t*t,o=a*t,s=r[3]??0,c=i[2]??0,l=2*o-3*a+1,u=o-2*a+t,d=-2*o+3*a,f=o-a;return l*r[1]+u*s*e+d*i[1]+f*c*e}}return e[e.length-1][1]}function ia(e,t){if(!e||e.length===0)return 0;let n=q(t);if(n<=e[0][0])return e[0][1];for(let t=1;t0?(n-r[0])/e:1,a=t*t*(3-2*t);return J(r[1],i[1],a)}}return e[e.length-1][1]}function aa(e,t,n=[0,0,0]){if(!e||e.length===0)return n[0]=0,n[1]=0,n[2]=0,n;let r=q(t);if(r<=e[0][0])return n[0]=e[0][1][0],n[1]=e[0][1][1],n[2]=e[0][1][2],n;for(let t=1;t0?(r-i[0])/e:1;return n[0]=J(i[1][0],a[1][0],t),n[1]=J(i[1][1],a[1][1],t),n[2]=J(i[1][2],a[1][2],t),n}}let i=e[e.length-1][1];return n[0]=i[0],n[1]=i[1],n[2]=i[2],n}function oa(e,t=1){let n=Xi(e);return`rgba(${Math.round(K(n[0],0,255))}, ${Math.round(K(n[1],0,255))}, ${Math.round(K(n[2],0,255))}, ${q(t)})`}function sa(e,t){let n=q(e),r=Math.max(0,t);return 1-(1-n)**r}function ca(e){let t=q(e/255);return t<=.04045?t/12.92:((t+.055)/1.055)**2.4}function Z(e,t=1,n=!1){let r=Math.max(0,t);return G&&!G.identity?ut(n?e:e.map(e=>B(q(e/255))*255),G).map(e=>ca(e)*r):(G?.identity?e:Yi(e)).map(e=>(n?ca(e):q(e/255))*r)}function Q(e,t,n,r=null){let i=e.map(([e,t])=>[e,Xi(t).map(ca)]),a=Math.max(0,n),o=r?r.map(e=>ca(e*255)):[1,1,1];return aa(i,t).map((e,t)=>e*o[t]*a)}function la(e,t=1){let n=q(t),r=q(e[0]*n),i=q(e[1]*n),a=q(e[2]*n),o=Math.max(r,i,a);return o<=1e-5?`rgba(0, 0, 0, 0)`:`rgba(${Math.round(r/o*255)}, ${Math.round(i/o*255)}, ${Math.round(a/o*255)}, ${o})`}function ua(e,t=1,n=t){let r=Math.max(0,t),i=B(Math.max(0,e[0])*r),a=B(Math.max(0,e[1])*r),o=B(Math.max(0,e[2])*r),s=q(Math.max(i,a,o,q(n)));return s<=1e-5?[0,0,0,0]:[i/s,a/s,o/s,s]}function da(e,t=1,n=t){let[r,i,a,o]=ua(e,t,n);return o<=1e-5?`rgba(0, 0, 0, 0)`:`rgba(${Math.round(r*255)}, ${Math.round(i*255)}, ${Math.round(a*255)}, ${o})`}function fa(e,t,n,r=`none`,i=1){let a=q(n);if(a<=1e-5)return[0,0,0];let o=Math.max(0,t),s=q(B(Math.max(0,e[0])*o)/a),c=q(B(Math.max(0,e[1])*o)/a),l=q(B(Math.max(0,e[2])*o)/a);if(r===`bright-core`){let e=u([s*a,c*a,l*a],a,i);s=e[0]/a,c=e[1]/a,l=e[2]/a}return[s,c,l]}function pa(e,t,n,r=1){let i=Math.max(q(r),1e-6),a=q(q(n)/i),o=B(Math.max(...e)*Math.max(0,t)/i);return Zi(.25,.75,o/Math.max(a,1e-6))*Zi(.03125,.25,o)}function ma(e,t,n=!1){return n?la(Z(e,1,!0),t):oa(e,t)}function ha(e,t,n,r=`none`,i=1,a=1){let o=q(n),s=Math.min(o,q(i));if(s<=1e-5)return`rgba(0, 0, 0, 0)`;let[c,l,u]=fa(e,t,o,r,a);return`rgba(${Math.round(c*255)}, ${Math.round(l*255)}, ${Math.round(u*255)}, ${s})`}function ga(e,t,n,r,i=`scene`,a=t,o=`none`,s=1){let c=q(t)*Math.max(0,n),l=e.map(e=>Math.max(0,e*c)),u=Math.max(...l);if(u<=0)return`rgba(0, 0, 0, 0)`;let d=Nt(u,wt(r.threshold),r.softKnee);if(d<=0)return`rgba(0, 0, 0, 0)`;let f=d/u,p=l.map(e=>e*f);if(i===`browser-overlay`){let e=q(a);return ha(p,r.trailAlpha,e,o,s,t)}return i===`host-additive`?da(p,r.trailAlpha,a):la(p,r.trailAlpha)}function _a(e,t,n,r=1){let i=q(t)*Math.max(0,r)/Math.max(1,n);return`rgb(${Math.round(K(e[0]*i*255,0,255))}, ${Math.round(K(e[1]*i*255,0,255))}, ${Math.round(K(e[2]*i*255,0,255))})`}function va(e){return e?.tagName?.toLowerCase?.()===`canvas`}function ya(e){if(!e)return null;let t,n;try{t=e.naturalWidth??e.videoWidth??e.displayWidth??e.width,n=e.naturalHeight??e.videoHeight??e.displayHeight??e.height}catch{return null}return!Number.isFinite(t)||!Number.isFinite(n)||t<=0||n<=0?null:{width:t,height:n}}function ba(e){return typeof e==`string`?document.querySelector(e):e??null}function $(){let e=document.createElement(`canvas`);return e.setAttribute(`aria-hidden`,`true`),e}function xa(){if(zi)return zi;if(Bi)return null;let e=vn($),t=$(),n=t.getContext(`2d`);return!e||!n?(Bi=!0,null):(t.width=128,t.height=128,zi={...e,canvas:t,context:n,linearTextureRgba:V,linearTextureCoverage:hn,linearTextureCoverageFromSrgbRed:!1,linearTextureRgb:null,linearTextureEnergyRgb:null,linearTintFrameCount:2,linearTintFrames:null,linearTintUnavailable:!1},zi)}function Sa(){if(Vi)return Vi;if(Hi)return null;let e=En($);if(!e)return Hi=!0,null;let t=$(),n=$(),r=t.getContext(`2d`),i=n.getContext(`2d`);return!r||!i?(Hi=!0,null):(t.width=512,t.height=512,n.width=512,n.height=512,Vi={...e,tintCanvas:t,tintContext:r,outputCanvas:n,outputContext:i,linearTextureRgba:Tn,linearTextureCoverage:null,linearTextureCoverageFromSrgbRed:!0,linearTextureRgb:null,linearTextureEnergyRgb:null,linearTintFrameCount:1,linearTintFrames:null,linearTintUnavailable:!1},Vi)}function Ca(e){if(e.linearTextureEnergyRgb)return;let t=e.linearTextureRgba,n=t.length/4,r=e.linearTextureCoverage??new Uint8Array(n),i=new Float32Array(n*3),a=new Float32Array(n*3);for(let n=0,o=0,s=0;nMath.max(0,Number(n[e])||0)),f=q(Number(s)||0),p=q(Number(c?.roundness)||0),m=c?.coverage??null,h=c?.useTextureAlpha===!0,g=p>0&&m!==null;if(l<=1e-6||u<=1e-6||Math.max(...d)<=1e-6||e.linearTintUnavailable)return null;if(!e.linearTintFrames&&(e.linearTintFrames=Oa(t,e.linearTintFrameCount),!e.linearTintFrames))return e.linearTintUnavailable=!0,null;Ca(e);let _=((Number.isFinite(o)?Math.trunc(o):0)%e.linearTintFrameCount+e.linearTintFrameCount)%e.linearTintFrameCount,v=e.linearTintFrames[_],y=[u,l,...d,f,p,h].join(`,`);if(v.key===y)return v.canvas;let{context:b,image:x}=v,S=e.linearTextureEnergyRgb,C=e.linearTextureRgb,w=e.linearTextureCoverage,T=e.linearTextureRgba,E=Da(),D=_===1,O=(e,t,n)=>{let r=q(S[e+t]*d[t]*l),i=Math.round(r*(Ta-1));return E[i]/n};b.setTransform(1,0,0,1,0,0),b.globalAlpha=1,b.globalCompositeOperation=`source-over`,b.filter=`none`,b.imageSmoothingEnabled=!1;for(let e=0;e{if(p<=0)return O(o,e,k);let n=1+(wa(C,t,3,v,y,e)-1)*q(b),r=q((n+(1-n)*p)*S*d[e]*l),i=Math.round(r*(Ta-1));return E[i]/k},j=A(0),M=A(1),ee=A(2),N=Math.max(j,M,ee),te=r*f*q(N);x.data[c]=Math.round(q(j+(N-j)*te)*255),x.data[c+1]=Math.round(q(M+(N-M)*te)*255),x.data[c+2]=Math.round(q(ee+(N-ee)*te)*255),x.data[c+3]=D}}return b.putImageData(x,0,0),b.globalCompositeOperation=`source-over`,b.filter=`none`,v.key=y,v.canvas}function Aa(e,t=!1){let n=Sa(),r=Math.max(0,...e);if(!n||r<=1e-5)return null;let i=e.map(e=>Math.round(q(e/r)*255)),{tintCanvas:a,tintContext:o,outputCanvas:s,outputContext:c}=n;return o.setTransform(1,0,0,1,0,0),o.globalAlpha=1,o.globalCompositeOperation=`source-over`,o.filter=`none`,o.clearRect(0,0,512,512),o.drawImage(t?n.srgbColorCanvas:n.colorCanvas,0,0),o.globalCompositeOperation=`multiply`,o.fillStyle=`rgb(${i[0]}, ${i[1]}, ${i[2]})`,o.fillRect(0,0,512,512),c.setTransform(1,0,0,1,0,0),c.globalAlpha=1,c.globalCompositeOperation=`source-over`,c.filter=`brightness(${Math.min(r,255)})`,c.clearRect(0,0,512,512),c.drawImage(a,0,0),c.filter=`none`,c.globalCompositeOperation=`destination-in`,c.drawImage(n.coverageCanvas,0,0),s}function ja(e){let t=document.createElement(`div`);return t.setAttribute(`aria-hidden`,`true`),t.style.position=e?`fixed`:`absolute`,t.style.inset=`0`,t.style.width=`100%`,t.style.height=`100%`,t.style.pointerEvents=`none`,t.style.zIndex=`2147483647`,t.style.isolation=`isolate`,t}function Ma(e,t,n=`2147483647`,r=`plus-lighter`){e.style.position=t?`fixed`:`absolute`,e.style.inset=`0`,e.style.width=`100%`,e.style.height=`100%`,e.style.pointerEvents=`none`,e.style.zIndex=n,e.style.mixBlendMode=r}function Na(e,t,n){let r=n.textureUvMax-n.textureUvMin;return Fn(n.textureUvMin+r*q(e),n.textureUvMin+r*q(t))}function Pa(e,t,n,r){let i=Na(e,t,r);return i>=n?i:0}function Fa(e,t){return t>0?e:1-e}function Ia(e,t,n,r,i,a){let o=e,s=t,c=Na(Fa(o,i),n,a)>=r;for(let e=0;e<8;e++){let e=(o+s)*.5;Na(Fa(e,i),n,a)>=r===c?o=e:s=e}return(o+s)*.5}function La(e,t,n,r,i){if(typeof e.createConicGradient!=`function`)return null;let a=e.createConicGradient(0,0,0),o=Math.max(32,t.arcSamples),s=t.dissolveDirection>=0?1:-1,c=null;for(let e=0;e<=o;e++){let l=e/o,u=Pa(Fa(l,s),r,n,t);if(c!==null&&c>0!=u>0){let u=Ia((e-1)/o,l,r,n,s,t),d=i(n),f=i(0);c>0?(a.addColorStop(u,d),a.addColorStop(u,f)):(a.addColorStop(u,f),a.addColorStop(u,d))}a.addColorStop(l,i(u)),c=u}return a}function Ra(e,t,n,r,i,a,o){let s=W*t,c=Math.max(i.arcSamples,Math.ceil(s)),l=i.dissolveDirection>=0?1:-1;for(let s=0;s=0?1:-1;return this.cacheResolution===e&&this.cacheTextureUvMin===t.textureUvMin&&this.cacheTextureUvMax===t.textureUvMax&&this.cacheDissolveDirection===n&&this.cacheBandToOuterRadius===t.bandToOuterRadius&&this.cacheWidthStart===t.widthStart&&this.cacheWidthEnd===t.widthEnd}_ensureSurface(e){this.resolution===e&&this.imageData||(this.canvas.width=e,this.canvas.height=e,this.resolution=e,this.imageData=this.context.createImageData(e,e))}_rebuildSampleCache(e,t){this._ensureSurface(e);let n=t.dissolveDirection>=0?1:-1,r=Math.max(0,t.widthStart,t.widthEnd),i=q(t.bandToOuterRadius*r),a=1-i,o=e*.5,s=0;if(i>0)for(let t=0;t=a&&r<=1&&s++}}this.pixelOffsets=new Uint32Array(s),this.angularProgresses=new Float32Array(s),this.radialDistances=new Float32Array(s),this.sampleAlphas=new Float32Array(s),this.sampleCount=s,this.staticWidth=t.widthStart===t.widthEnd;let c=0;for(let r=0;r1)continue;let f=Math.atan2(s,u)/W;if(f<0&&(f+=1),this.pixelOffsets[c]=(r*e+l)*4,this.angularProgresses[c]=f,this.radialDistances[c]=d,this.staticWidth){let e=i>0?(d-a)/i:0,r=Fa(f,n);this.sampleAlphas[c]=Na(r,e,t)}c++}}this.imageData.data.fill(0),this.cacheResolution=e,this.cacheTextureUvMin=t.textureUvMin,this.cacheTextureUvMax=t.textureUvMax,this.cacheDissolveDirection=n,this.cacheBandToOuterRadius=t.bandToOuterRadius,this.cacheWidthStart=t.widthStart,this.cacheWidthEnd=t.widthEnd,this.cacheRevision++}_clearPixel(e,t){e[t]=0,e[t+1]=0,e[t+2]=0,e[t+3]=0}_writeVisiblePixel(e,t,n,r,i,a,o=`none`,s=1){let c=q(r*i);if(c<=1e-5){this._clearPixel(e,t);return}if(a===`browser-overlay`){if(n.every(e=>e<=0)){this._clearPixel(e,t);return}let[i,a,l]=fa(n,c,c,o,r);e[t]=Math.round(i*255),e[t+1]=Math.round(a*255),e[t+2]=Math.round(l*255),e[t+3]=Math.round(Math.min(c,q(s))*255);return}if(a===`host-additive`){let[r,i,a,o]=ua(n,c,c);e[t]=Math.round(r*255),e[t+1]=Math.round(i*255),e[t+2]=Math.round(a*255),e[t+3]=Math.round(o*255);return}let l=q(n[0]*c),u=q(n[1]*c),d=q(n[2]*c),f=Math.max(l,u,d);if(f<=1e-5){this._clearPixel(e,t);return}e[t]=Math.round(l/f*255),e[t+1]=Math.round(u/f*255),e[t+2]=Math.round(d/f*255),e[t+3]=Math.round(f*255)}_writeMask(e,t,n,r,i,a,o=`none`,s=1){let c=i.dissolveDirection>=0?1:-1,l=J(i.widthStart,i.widthEnd,e),u=q(i.bandToOuterRadius*Math.max(0,l)),d=1-u,f=this.imageData.data;for(let e=0;e{let t=i*e;return c===`browser-overlay`?ha(_,t,t,d,f,i):c===`host-additive`?da(_,t,t):la(_,t)};e.save(),e.translate(t.x,t.y),e.rotate(t.rotation);let y=sa(i*m.ringAlpha,m.clickEmissionScale),b;b=c===`browser-overlay`?ha(Z(g,1,!0),y,y,d,f,i):c===`host-additive`?da(Z(g,1,!0),y,y):ma(g,y,l),za(e,h.radius,h.width,h.threshold,p,v,o?{blur:m.ringBlur*r*u,color:b}:null),e.restore()}function Za(e,t,n,r,i,a=P,o=null){let s=a.rings,c=a.bloom,l=Ba(t,n,r,s);if(l.width<=.001)return;let u=o??Q(s.colorKeys,n,s.hdrIntensity);e.save(),e.translate(t.x,t.y),e.rotate(t.rotation),za(e,l.radius,l.width,l.threshold,s,e=>_a(u,i*e*c.ringEmissionAlpha,c.emissionRange,c.clickEmissionScale)),e.restore()}function Qa(e,t,n,r,i,a=P,o=!0,s=1,c=`scene`,l=`none`,u=1){let d=a.disk,f=a.bloom,p=X(d.sizeKeys,n),m=d.radius*p*r,h=aa(d.colorKeys,n),g=Y(d.alphaKeys,n);if(m<=0||g<=0)return;let _=Q(d.colorKeys,n,f.diskEmission),v=g*i,y=q(v),b;if(c===`browser-overlay`){y=Math.min(y,q(u));let e=Sa(),t=l===`bright-core`?pa(_,i,v,i):0;e&&y>1e-6&&(b=ka(e,512,_,i,v,0,t))}else if(c===`host-additive`){y=ua(_,i,v)[3];let e=Sa();e&&(b=ka(e,512,_,i,y))}else b=Aa(_.map(e=>e/Math.max(g,1e-5)));if(!b)return;e.save(),e.globalCompositeOperation=`source-over`,e.translate(t.x,t.y),e.rotate(t.diskRotation),e.globalAlpha=y;let x=sa(i*f.diskAlpha,f.clickEmissionScale);c===`browser-overlay`?e.shadowColor=ha(Z(h,1,!0),x,x,l,u,i):c===`host-additive`?e.shadowColor=da(Z(h,1,!0),x,x):e.shadowColor=oa(h,x),e.shadowBlur=o?f.diskBlur*r*s:0,e.drawImage(b,0,0,512,512,-m,-m,m*2,m*2),e.restore()}function $a(e,t,n,r,i,a=P,o=1){let s=a.disk,c=a.bloom,l=s.radius*X(s.sizeKeys,n)*r,u=c.diskBlur*r*o;if(l<=0||u<=0)return;let d=aa(s.colorKeys,n),f=sa(i*c.diskAlpha,c.clickEmissionScale);e.save(),e.globalCompositeOperation=`lighter`,e.beginPath(),e.arc(t.x,t.y,l,0,W),e.fillStyle=`rgb(0, 0, 0)`,e.shadowColor=ma(d,f,!0),e.shadowBlur=u,e.fill(),e.restore()}function eo(e,t,n,r,i,a=P){let o=a.disk,s=a.bloom,c=o.radius*X(o.sizeKeys,n)*r,l=Aa(Q(o.colorKeys,n,s.diskEmission).map(e=>e*s.clickEmissionScale/s.emissionRange));c<=0||!l||(e.save(),e.translate(t.x,t.y),e.rotate(t.diskRotation),e.globalAlpha=q(i*s.diskEmissionAlpha),e.drawImage(l,0,0,512,512,-c,-c,c*2,c*2),e.restore())}function to(e,t,n,r,i,a=P){let o=a.disk,s=o.radius*X(o.sizeKeys,n)*r,c=Y(o.alphaKeys,n)*i;if(s<=0||c<=0)return;let l=Sa();l&&(e.save(),e.globalCompositeOperation=`source-over`,e.translate(t.x,t.y),e.rotate(t.diskRotation),e.globalAlpha=q(c),e.shadowBlur=0,e.shadowColor=`transparent`,e.drawImage(l.coverageCanvas,0,0,512,512,-s,-s,s*2,s*2),e.restore())}function no(e,t){let n=t.textureFrames,r=Array.isArray(n)&&n.length>0?n.length:2;return((Number.isInteger(e.textureFrame)?e.textureFrame:0)%r+r)%r}function ro(e,t){let n=t.textureFrames;return!Array.isArray(n)||n.length===0?[[0,-.58],[.52,.45],[-.52,.45]]:n[no(e,t)]}function io(e,t,n){e.save(),n%2==1&&(e.translate(0,128),e.scale(1,-1)),e.drawImage(t,0,0),e.restore()}function ao(e){return q(e.roundness)}function oo(e,t){let n=q(t);if(n<=0)return null;if(e.roundedCoverages||(e.roundedCoverages=new Map),e.roundedCoverages.has(n))return e.roundedCoverages.get(n);e.roundedCoverages.size>=32&&e.roundedCoverages.delete(e.roundedCoverages.keys().next().value);let r=sn(n);return e.roundedCoverages.set(n,r),r}function so(e,t,n,r){let i=q(n),a=oo(e,i);if(!a||(e.roundedSceneFrames||(e.roundedSceneFrames=Oa(128,2)),!e.roundedSceneFrames))return null;let o=(Math.trunc(r)%2+2)%2,s=e.roundedSceneFrames[o],c=t.map(e=>Math.max(0,Number(e)||0)),l=[i,...c].join(`,`);if(s.key===l)return s.canvas;Ca(e);let u=o===1,d=e.linearTextureRgba,f=e.linearTextureRgb;for(let e=0;e<128;e++){let t=u?127-e:e;for(let n=0;n<128;n++){let r=t*128+n,o=(e*128+n)*4,l=a[r]/255,[u,p]=an((n+.5)/128,(t+.5)/128,i),m=wa(d,128,4,u,p,3)/255;for(let e=0;e<3;e++){let t=1+(wa(f,128,3,u,p,e)-1)*q(m),n=t+(1-t)*i;s.image.data[o+e]=Math.round(q(n*c[e])*255)}s.image.data[o+3]=Math.round(q(l)*255)}}return s.context.putImageData(s.image,0,0),s.key=l,s.canvas}function co(e,t,n,r,i,a,o=1,s=`scene`,c=`none`,l=1,u=1,d=0){let f=xa();if(!f)return!1;let p=r.map(e=>e*Math.max(0,o)),m=s===`browser-overlay`||s===`host-additive`,h=oo(f,d),g=h?{coverage:h,roundness:d,useTextureAlpha:s===`scene`}:null,_=q(i),v;if(s===`browser-overlay`){_=Math.min(_,q(l));let e=c===`bright-core`?pa(p,i,i,u):0;_>1e-6&&(v=ka(f,128,p,i,i,a,e,g))}else if(s===`host-additive`)_=ua(p,i,i)[3],v=ka(f,128,p,i,_,a,0,g);else{let e=f.context,t=p.map(e=>Math.round(q(e)*255));d>0&&(v=so(f,p,d,a)),v||(e.setTransform(1,0,0,1,0,0),e.globalAlpha=1,e.globalCompositeOperation=`source-over`,e.imageSmoothingEnabled=!0,e.clearRect(0,0,128,128),io(e,f.colorCanvas,a),e.globalCompositeOperation=`multiply`,e.fillStyle=`rgb(${t[0]}, ${t[1]}, ${t[2]})`,e.fillRect(0,0,128,128),e.globalCompositeOperation=`destination-in`,io(e,f.alphaCanvas,a),v=f.canvas)}return m&&(!v||_<=1e-5)?!0:(e.save(),e.translate(t.x,t.y),e.rotate(t.rotation),e.globalAlpha=_,e.shadowColor=`transparent`,e.shadowBlur=0,e.drawImage(v,-n*.5,-n*.5,n,n),e.restore(),!0)}function lo(e,t,n,r,i=P,a=`scene`,o=`none`,s=1){let c=i.shards,l=q(t.ageMs/t.lifetimeMs),u=t.size*X(c.sizeKeys,l)*n,d=Y(c.alphaKeys,l)*r,f=Q(c.colorKeys,l,c.hdrIntensity,c.startColor),p=no(t,c),m=ro(t,c),h=ao(c);u<=0||d<=0||co(e,t,u,f,d,p,1,a,o,s,r,h)||(e.save(),e.translate(t.x,t.y),e.rotate(t.rotation),e.beginPath(),wi(e,m,u,c.roundness),a===`browser-overlay`?e.fillStyle=ha(f,d,d,o,s,r):a===`host-additive`?e.fillStyle=da(f,d,d):e.fillStyle=la(f,d),e.shadowColor=`transparent`,e.shadowBlur=0,e.fill(),e.restore())}function uo(e,t,n,r,i=P){let a=i.shards,o=q(t.ageMs/t.lifetimeMs),s=t.size*X(a.sizeKeys,o)*n,c=Y(a.alphaKeys,o)*r,l=no(t,a),u=ro(t,a),d=ao(a);s<=0||c<=0||co(e,t,s,[1,1,1],c,l,1,`browser-overlay`,`none`,1,r,d)||(e.save(),e.translate(t.x,t.y),e.rotate(t.rotation),e.beginPath(),wi(e,u,s,a.roundness),e.fillStyle=`rgba(255, 255, 255, ${q(c)})`,e.shadowColor=`transparent`,e.shadowBlur=0,e.fill(),e.restore())}function fo(e,t,n,r,i=P){let a=i.shards,o=i.bloom,s=q(t.ageMs/t.lifetimeMs),c=t.size*X(a.sizeKeys,s)*n,l=Y(a.alphaKeys,s)*r,u=Q(a.colorKeys,s,a.hdrIntensity,a.startColor),d=no(t,a),f=ro(t,a),p=ao(a);c<=0||l<=0||co(e,t,c,u,l,d,1/Math.max(1,o.emissionRange),`scene`,`none`,1,r,p)||(e.save(),e.translate(t.x,t.y),e.rotate(t.rotation),e.beginPath(),wi(e,f,c,a.roundness),e.fillStyle=_a(u,l,o.emissionRange),e.fill(),e.restore())}function po(e,t,n=P.rings){return J(ia(n.angularVelocityMinKeys,t),ia(n.angularVelocityMaxKeys,t),e)*n.angularVelocityMultiplier*n.rotationDirection}function mo(e,t,n,r,i,a,o=!1,s=`scene`,c=`none`,l=1){let u=a.hit,d=u.radius*r,f=Y(u.alphaKeys,n)*i,p=aa(u.colorKeys,n);f<=0||(e.save(),e.beginPath(),e.arc(t.x,t.y,d,0,W),s===`browser-overlay`?e.fillStyle=ha(Z(p,1,!0),f,f,c,l,i):s===`host-additive`?e.fillStyle=da(Z(p,1,!0),f,f):e.fillStyle=ma(p,f,o),e.fill(),e.restore())}function ho(e,t,n,r,i,a,o=!1,s=`scene`,c=`none`,l=1){let u=a.flare,d=u.radius*r,f=Y(u.alphaKeys,n)*i,p=aa(u.colorKeys,n);if(!(f<=0)){e.save(),e.translate(t.x,t.y),s===`browser-overlay`?e.strokeStyle=ha(Z(p,1,!0),f,f,c,l,i):s===`host-additive`?e.strokeStyle=da(Z(p,1,!0),f,f):e.strokeStyle=ma(p,f,o);for(let t=0;t=1))for(let r of this.rings)Xa(e,r,i,t,n,this.fx,!1,[1,1,1],`browser-overlay`)}appendCanvasSceneCoverage(e,t,n){let r=this.ageMs/this.fx.disk.lifetimeMs;if(r>=1)return;let i=this.fx.disk,a=i.radius*X(i.sizeKeys,r)*t,o=Y(i.alphaKeys,r)*n;e.addCoverageDisk(this.x,this.y,a,o,this.diskRotation)}appendWebGLSceneDiskLayer(e,t,n){let r=this.ageMs/this.fx.disk.lifetimeMs;if(r>=1)return;let i=this.fx.disk,a=this.fx.bloom,o=i.radius*X(i.sizeKeys,r)*t,s=Q(i.colorKeys,r,a.diskEmission),c=Y(i.alphaKeys,r);e.addAlphaBlendDisk(this.x,this.y,o,s,n,c,this.diskRotation)}appendWebGLSceneAdditiveLayer(e,t,n){let r=this.ageMs/this.fx.hit.lifetimeMs;if(this.fx.hit.enabled&&r<1){let i=this.fx.hit,a=Y(i.alphaKeys,r)*n;e.addSolidDisk(this.x,this.y,i.radius*t,Z(aa(i.colorKeys,r),1,!0),a)}let i=this.ageMs/this.fx.flare.lifetimeMs;if(this.fx.flare.enabled&&i<1){let r=this.fx.flare,a=Y(r.alphaKeys,i)*n,o=Z(aa(r.colorKeys,i),1,!0),s=r.radius*t;for(let n=0;n=1)return;let o=this.fx.rings,s=Q(o.colorKeys,a,o.hdrIntensity),c=o.dissolveDirection>=0?1:-1;for(let r of this.rings){let i=Ba(r,a,t,o);e.addDissolveRing(r.x,r.y,i.radius,i.width,r.rotation,o.radialSamples,o.arcSamples,s,n,i.threshold,o.textureUvMin,o.textureUvMax,c)}}appendWebGLBloom(e,t,n){if(this.fx.bloom.clickEmissionScale<=0)return;let r=this.ageMs/this.fx.disk.lifetimeMs;if(r<1){let i=this.fx.disk,a=this.fx.bloom,o=i.radius*X(i.sizeKeys,r)*t,s=n*a.diskEmissionAlpha*a.clickEmissionScale,c=Q(i.colorKeys,r,a.diskEmission);e.addDisk(this.x,this.y,o,c,s,this.diskRotation)}let i=this.ageMs/this.fx.rings.lifetimeMs;if(i>=1)return;let a=this.fx.rings,o=this.fx.bloom,s=Q(a.colorKeys,i,a.hdrIntensity),c=a.dissolveDirection>=0?1:-1;for(let r of this.rings){let l=Ba(r,i,t,a);e.addRing(r.x,r.y,l.radius,l.width,r.rotation,a.radialSamples,a.arcSamples,s,n*o.ringEmissionAlpha*o.clickEmissionScale,(e,t)=>Pa(c>0?e:1-e,t,l.threshold,a))}}get dead(){let e=this.fx.disk.lifetimeMs;return this.fx.hit.enabled&&(e=Math.max(e,this.fx.hit.lifetimeMs)),this.fx.flare.enabled&&(e=Math.max(e,this.fx.flare.lifetimeMs)),this.rings.length>0&&(e=Math.max(e,this.fx.rings.lifetimeMs)),this.ageMs>=e}},_o=class{constructor(e){Object.assign(this,e),this.ageMs=0,this.lastUpdateTimeMs=Number.isFinite(e.lastUpdateTimeMs)?e.lastUpdateTimeMs:null}update(e){let t=e/1e3;this.ageMs+=e,this.x+=this.velocityX*t,this.y+=this.velocityY*t}updateTo(e){if(!Number.isFinite(e)||!Number.isFinite(this.lastUpdateTimeMs))return;let t=Math.max(0,e-this.lastUpdateTimeMs);t<=0||(this.lastUpdateTimeMs=e,this.update(t))}draw(e,t,n,r=P,i=`scene`,a=`none`,o=1){lo(e,this,t,n,r,i,a,o)}drawBloom(e,t,n,r=P){fo(e,this,t,n,r)}drawBloomCoverage(e,t,n,r=P){uo(e,this,t,n,r)}appendWebGLScene(e,t,n,r=P){this.appendWebGLBloom(e,t,n,r)}appendWebGLBloom(e,t,n,r=P){let i=r.shards,a=q(this.ageMs/this.lifetimeMs),o=this.size*X(i.sizeKeys,a)*t,s=Y(i.alphaKeys,a)*n,c=Q(i.colorKeys,a,i.hdrIntensity,i.startColor),l=no(this,i);e.addTriangle(this.x,this.y,o,this.rotation,c,s,l,ao(i))}get dead(){return this.ageMs>=this.lifetimeMs}};function vo(e,t,n,r,i,a=P.shards,o=null,s=null){let c=r===`click`,l=(c?a.clickRadius:a.trailRadius)*i,u=(c?na(a.clickSpeedMin,a.clickSpeedMax):na(a.trailSpeedMin,a.trailSpeedMax))*i,d=c?na(a.clickLifetimeMinMs,a.clickLifetimeMaxMs):na(a.trailLifetimeMinMs,a.trailLifetimeMaxMs);return new _o({kind:r,x:e+Math.cos(n)*l,y:t+Math.sin(n)*l,velocityX:Math.cos(n)*u,velocityY:Math.sin(n)*u,rotation:0,textureFrame:Math.random()<.5?0:1,lifetimeMs:d,size:na(a.sizeMin,a.sizeMax),lastUpdateTimeMs:o,ownerId:s})}function yo(e,t,n){return{x:e,y:t,bornAt:n}}function bo(e){for(let t=1;ti.totalLength>0?e/i.totalLength:0),o=Array(Math.max(0,e.length-1));for(let t=1;t0?(i.distances[t-1]+i.distances[t])*.5/i.totalLength:0;let s=t.coverageLongitudinalKeys,c={measurement:i,pointProgresses:a,segmentProgresses:o,pointCoverageFactors:a.map(e=>ki(s,e)),segmentCoverageFactors:o.map(e=>ki(s,e))};if(n===null)return c;let l=[],u=Array(e.length),d=Array(e.length),f=[],p=[],m=[],h=[],g=t.textureLongitudinalKeys;if(i.totalLength<=0)return{...c,pointEnergies:l,pointTransverseProfiles:u,pointCoverageProfiles:d,segmentEnergies:f,segmentMaximumEnergies:p,segmentTransverseProfiles:m,segmentCoverageProfiles:h,textureLongitudinalKeys:g};for(let r=0;re*i)}function To(e,t,n){return Z(xo(e,t),n)}function Eo(e,t,n=t.textureLongitudinalKeys){let r=t.textureTransverseProfileKeys;if(!Array.isArray(r)||r.length===0)return[[0,1],[1,1]];let i=q(e),a=r[0],o=r[0],s=0;for(let e=1;e0?(i-a[0])/t:1;break}a=o,s=0}let c=Y(n,a[0]),l=Y(n,o[0]),u=Y(n,i),d=a[1].map((e,t)=>{let n=J(e*c,o[1][t]*l,q(s));return u>1e-7?q(n/u):0}),f=d.length-1,p=[];for(let e=f;e>=0;e--)p.push([(f-e)/(f*2),d[e]]);for(let e=1;e<=f;e++)p.push([.5+e/(f*2),d[e]]);return p}function Do(e,t,n=0,r=0,i=null){let a=Math.max(0,t)*.5,o=Array(e.length).fill(null),s=[];if(a<=0)return{segments:o,caps:s};for(let t=1;t0?1:-1,d=-u,f={x:l.x+n.normal.x*a*u,y:l.y+n.normal.y*a*u},p={x:l.x+r.normal.x*a*u,y:l.y+r.normal.y*a*u},m=((p.x-f.x)*r.tangent.y-(p.y-f.y)*r.tangent.x)/i,h={x:f.x+n.tangent.x*m,y:f.y+n.tangent.y*m},g=Math.hypot(h.x-l.x,h.y-l.y),_=(h.x-l.x)*n.tangent.x+(h.y-l.y)*n.tangent.y,v=(h.x-l.x)*r.tangent.x+(h.y-l.y)*r.tangent.y;if(!Number.isFinite(g)||g>a*Li||_<-n.length-1e-6||_>1e-6||v<-1e-6||v>r.length+1e-6)continue;let y=Math.atan2(i,s),b=Math.atan2(n.normal.y*d,n.normal.x*d),x=c+1,S=[];for(let e=0;e<=x;e++){let t=b+y*e/x;S.push({x:l.x+Math.cos(t)*a,y:l.y+Math.sin(t)*a})}u>0?(n.toLeft=h,r.fromLeft=h,n.toRight=S[0],r.fromRight=S.at(-1)):(n.toRight=h,r.fromRight=h,n.toLeft=S[0],r.fromLeft=S.at(-1)),n.endJoin={nextSegmentIndex:r.index,inner:h,innerSide:u>0?`left`:`right`,outerArc:S}}if(Math.floor(r)>0){let e=o.find(e=>e),t=null;for(let e=o.length-1;e>=1;e--)if(o[e]){t=o[e];break}e&&s.push({position:`start`,segmentIndex:e.index,pointIndex:e.index-1,points:[e.fromLeft,e.fromRight,{x:e.from.x-e.tangent.x*a,y:e.from.y-e.tangent.y*a}]}),t&&s.push({position:`end`,segmentIndex:t.index,pointIndex:t.index,points:[t.toLeft,{x:t.to.x+t.tangent.x*a,y:t.to.y+t.tangent.y*a},t.toRight]})}return{segments:o,caps:s}}function Oo(e,t,n,r){e.meshCache||(e.meshCache=new Map);let i=Math.max(0,Math.floor(r.numCornerVertices??0)),a=Math.max(0,Math.floor(r.numCapVertices??0)),o=`${n}:${i}:${a}`;return e.meshCache.has(o)||e.meshCache.set(o,Do(t,n,i,a,e.measurement.segmentLengths)),e.meshCache.get(o)}function ko(e){return Array.isArray(e)&&e.length>=2?e:[[0,1],[1,1]]}function Ao(e,t,n,r,i){let a=e.createLinearGradient(t.x,t.y,n.x,n.y);for(let[e,t]of ko(r))a.addColorStop(q(e),i(t,e));return a}function jo(e,t,n,r,i){let a=Ao(e,t.fromLeft,t.fromRight,r,i);if(e.beginPath(),e.moveTo(t.fromLeft.x,t.fromLeft.y),!n)e.lineTo(t.toLeft.x,t.toLeft.y),e.lineTo(t.toRight.x,t.toRight.y);else if(n.innerSide===`left`){e.lineTo(n.inner.x,n.inner.y);for(let t=n.outerArc.length-1;t>=0;t--){let r=n.outerArc[t];e.lineTo(r.x,r.y)}}else{for(let t of n.outerArc)e.lineTo(t.x,t.y);e.lineTo(n.inner.x,n.inner.y)}e.lineTo(t.fromRight.x,t.fromRight.y),e.closePath(),e.fillStyle=a,e.fill()}function Mo(e,t,n,r){let i=t.points[0],a=Ao(e,i,t.position===`start`?t.points[1]:t.points[2],n,r);e.beginPath(),e.moveTo(t.points[0].x,t.points[0].y),e.lineTo(t.points[1].x,t.points[1].y),e.lineTo(t.points[2].x,t.points[2].y),e.closePath(),e.fillStyle=a,e.fill()}function No(e,t,n,r){return e.pointEnergies?.[t]?e.pointEnergies[t]:wo(e.measurement.distances[t]/e.measurement.totalLength,n,r)}function Po(e,t,n){let r=e.pointTransverseProfiles;if(r?.[t])return r[t];let i=Eo(e.measurement.distances[t]/e.measurement.totalLength,n,e.textureLongitudinalKeys);return r&&(r[t]=i),i}function Fo(e,t,n){let r=e.pointCoverageFactors?.[t];if(Number.isFinite(r))return r;let i=e.pointProgresses?.[t]??e.measurement.distances[t]/e.measurement.totalLength;return ki(n.coverageLongitudinalKeys,i)}function Io(e,t){let n=e.pointCoverageProfiles;if(n?.[t])return n[t];let r=ji(e.pointProgresses?.[t]??e.measurement.distances[t]/e.measurement.totalLength);return n&&(n[t]=r),r}function Lo(e,t,n,r,i,a,o,s=1,c=t.length-1){let l=n.measurement;if(l.totalLength<=0)return;e.save(),e.shadowBlur=0,e.shadowColor=`transparent`;let u=Oo(n,t,o.scaledWidth??o.width*r,a),d=K(Math.floor(s),1,t.length-1),f=K(Math.floor(c),d,t.length-1),p=o.colorAtIntensity??((e,t,n,r)=>{let a=o.alpha*i*t,s=o.alpha*i*n*r;return o.outputCompositing===`browser-overlay`?ha(e,a,s,o.overlayColorCompensation,o.overlayAlphaLimit,o.globalOpacity??i):o.outputCompositing===`host-additive`?da(e,a,s):la(e,a)});for(let t=d;t<=f;t++){let r=u.segments[t];if(!r)continue;let i=(l.distances[t-1]+l.distances[t])*.5/l.totalLength,s=n.segmentEnergies?.[t-1]??wo(i,a,o.materialIntensity),c=n.segmentTransverseProfiles?.[t-1]??Eo(i,a),d=n.segmentCoverageProfiles?.[t-1]??ji(i),m=n.segmentCoverageFactors?.[t-1]??ki(a.coverageLongitudinalKeys,i);jo(e,r,r.endJoin?.nextSegmentIndex<=f?r.endJoin:null,c,(e,t)=>p(s,e,Y(d,t),m))}for(let t of u.caps){if(t.segmentIndexf)continue;let r=No(n,t.pointIndex,a,o.materialIntensity),i=Po(n,t.pointIndex,a),s=Io(n,t.pointIndex),c=Fo(n,t.pointIndex,a);Mo(e,t,i,(e,t)=>p(r,e,Y(s,t),c))}e.restore()}function Ro(e){return Array.isArray(e)&&e.some(e=>e>0)}function zo(e,t){let n=e.measurement.segmentLengths,r=e.segmentEnergies;if(!n||!Array.isArray(r)||n.length!==r.length+1)return!0;let i=null,a=null;for(let e=1;e0))return!1;let o=e.pointEnergies?.[i],s=e.pointEnergies?.[a];return!Array.isArray(o)||!Array.isArray(s)?!0:Ro(o)||Ro(s)}function Bo(e,t,n,r,i,a,o,s,c=`scene`,l=`none`,u=1){if(n.measurement.totalLength<=0||i<=0||o.trailAlpha<=0||o.trailEmission<=0||typeof e.filter!=`string`||!s?.context||!zo(n,a))return;let d=n.segmentEnergies.findIndex(e=>e.some(e=>e!==0)),f=n.pointEnergies[0]?.every(e=>e===0)===!0&&d>=0?d+1:1,p=Math.max(0,a.outerGlowWidth*r),m=Math.max(.5,a.geometryWidth*r*.5),h=Math.ceil(p*3+m+2),g=1/0,_=1/0,v=-1/0,y=-1/0,b=f-1;for(let e=b;ega(e,i,t,o,c,i*n*r,l,u)},f),e.save(),e.filter=`blur(${p*T}px)`,e.shadowBlur=0,e.shadowColor=`transparent`,e.drawImage(O,0,0,E,D,x,S,C,w),e.restore()}function Vo(e,t,n,r,i,a,o,s=!1,c=`scene`,l=`none`,u=1){let d=n.measurement,f=o.alpha*i;if(d.totalLength<=0||f<=0)return;if(e.save(),e.lineWidth=Math.max(.5,o.width*r),e.shadowBlur=0,e.shadowColor=`transparent`,o.color&&c===`scene`){e.lineJoin=`round`,e.lineCap=`round`,e.strokeStyle=ma(o.color,f,s),e.beginPath(),e.moveTo(t[0].x,t[0].y);for(let n=1;n`rgba(255, 255, 255, ${q(l*n*r)})`},o,s)}function Wo(e,t,n,r,i=P,a=null,o=1,s=t.length-1){let c=i.trail,l=i.bloom,u=r*(c.trailOpacity??1)*l.trailEmissionAlpha,d=a??Co(t,c,l.trailEmission);if(d.measurement.totalLength<=0||u<=0)return;let f=Math.max(.5,c.geometryWidth*n*l.trailCoverageScale),p=K(Math.floor(o),1,t.length-1),m=K(Math.floor(s),p,t.length-1);Lo(e,t,d,n,1,c,{scaledWidth:f,alpha:1,materialIntensity:l.trailEmission,colorAtIntensity:(e,t)=>_a(e,u*t,l.emissionRange)},p,m)}function Go(e,t,n){return{x:e.x,y:e.y,u:t,v:n}}function Ko(e,t,n,r,i){let a=Go(t.fromLeft,n.u,1),o=Go(t.fromRight,n.u,0),s=Go(t.toLeft,r.u,1),c=Go(t.toRight,r.u,0);e.addTexturedTrailTriangle(a,s,c,[n.color,r.color,r.color],i,[n.coverage,r.coverage,r.coverage]),e.addTexturedTrailTriangle(a,c,o,[n.color,r.color,n.color],i,[n.coverage,r.coverage,n.coverage])}function qo(e,t,n,r){let i=+(t.innerSide===`left`),a=1-i,o=Go(t.inner,n.u,i);for(let i=1;iGo(e,t.u,o[n]));e.addTexturedTrailTriangle(s[0],s[1],s[2],t.color,i,t.coverage)}}function Yo(e,t,n,r,i){for(let a=1;a`u`||typeof window>`u`)throw Error(`BAClickFX 需要浏览器 DOM 环境`);let t=typeof e.softwareBloomEnabled==`boolean`?e.softwareBloomEnabled?`software`:`native`:I.bloomBackend,n=Se(e.bloomBackend,t),r=xe(e.bloomBackend)||typeof e.softwareBloomEnabled==`boolean`?`canvas2d`:I.effectBackend;if(this.config=We({scale:Number.isFinite(e.scale)?Math.max(.01,e.scale):I.scale,opacity:Number.isFinite(e.opacity)?q(e.opacity):I.opacity,themeColor:ze(e.themeColor,I.themeColor),themeColorMode:Ve(e.themeColorMode,I.themeColorMode),clickEnabled:e.clickEnabled??I.clickEnabled,trailEnabled:e.trailEnabled??I.trailEnabled,trailAlways:e.trailAlways??I.trailAlways,inputSource:Ce(e.inputSource)?e.inputSource:I.inputSource,inputSamplingRate:Te(e.inputSamplingRate,I.inputSamplingRate),clickTimeScale:Re(e.clickTimeScale,I.clickTimeScale),trailTimeScale:Re(e.trailTimeScale,I.trailTimeScale),outputCompositing:Ee(e.outputCompositing)?e.outputCompositing:I.outputCompositing,overlayAlphaPolicy:Oe(e.overlayAlphaPolicy,I.overlayAlphaPolicy),overlayColorCompensation:ke(e.overlayColorCompensation,I.overlayColorCompensation),overlayAlphaLimit:Ae(e.overlayAlphaLimit,I.overlayAlphaLimit),hostCompositing:Ne(e.hostCompositing,I.hostCompositing),hostCompositingSurface:Fe(e.hostCompositingSurface,I.hostCompositingSurface),effectBackend:be(e.effectBackend,r),webgpuPreferHdr:typeof e.webgpuPreferHdr==`boolean`?e.webgpuPreferHdr:I.webgpuPreferHdr,webgpuHdrPeak:e.webgpuHdrPeak,webgpuHdrBrightness:e.webgpuHdrBrightness,webgpuHdrColorPreservation:e.webgpuHdrColorPreservation,webgpuHdrWhiteCore:e.webgpuHdrWhiteCore,webgpuHdrWhiteStart:e.webgpuHdrWhiteStart,webgpuHdrWhiteEnd:e.webgpuHdrWhiteEnd,renderingMode:e.renderingMode===`legacy`?`legacy`:I.renderingMode,bloomBackend:n,softwareBloomEnabled:n===`software`,isolatedCompositing:typeof e.isolatedCompositing==`boolean`?e.isolatedCompositing:I.isolatedCompositing,lightBackgroundContrastAlpha:Number.isFinite(e.lightBackgroundContrastAlpha)?q(e.lightBackgroundContrastAlpha):I.lightBackgroundContrastAlpha,maxDpr:Number.isFinite(e.maxDpr)?Math.max(1,e.maxDpr):I.maxDpr,touchAction:e.touchAction??I.touchAction}),this.inputFilter=typeof e.inputFilter==`function`?e.inputFilter:null,this.host=ba(e.target),this.ownsCanvas=!va(this.host),this.ownsCanvas||(this.config.isolatedCompositing=!1),this.canvas=va(this.host)?this.host:$(),this.contrastCanvas=this.ownsCanvas?$():null,this.webglBloomCanvas=null,this.webglBloomRenderer=null,this.webglBloomUnavailable=!1,this.webglBloomVisible=!1,this.webglEffectCanvas=null,this.webglEffectRenderer=null,this.webglEffectUnavailable=!1,this.webglEffectVisible=!1,this.webgpuEffectCanvas=null,this.webgpuEffectRenderer=null,this.webgpuEffectUnavailable=!1,this.webgpuEffectVisible=!1,this.canvasSceneCanvas=null,this.canvasSceneRenderer=null,this.canvasSceneUnavailable=!1,this.canvasSceneVisible=!1,this.compositingReferenceSource=null,this.compositingReferenceFit=`cover`,this.compositingMountPending=!1,this.hostCompositingState=this._resolveHostCompositingState(),!this.canvas)throw Error(`BAClickFX 找不到 target`);if(this.ownsCanvas){let e=this.host??document.body,t=this.config.renderingMode===`legacy`;this.overlayMountParent=e,this.overlayRoot=ja(!this.host),t?(Ma(this.canvas,!1,`2147483647`,``),Ma(this.contrastCanvas,!1,`2147483647`,`darken`),this.contrastCanvas.style.display=`none`):(Ma(this.canvas,!1,`2147483646`,``),Ma(this.contrastCanvas,!1,`2147483647`,`darken`)),this._applyCompositingMount()}else this.overlayMountParent=null,this.overlayRoot=null,this.overlayParent=null,this._applyCompositingMount();if(this.canvas.style.touchAction=this.config.touchAction,this.context=this.canvas.getContext(`2d`),this.contrastContext=this.contrastCanvas?.getContext(`2d`)??null,!this.context)throw Error(`BAClickFX 无法创建 Canvas 2D 上下文`);this.bloomRenderer=new Zt(()=>$()),this.bloomRenderers=[this.bloomRenderer],this.resolvedEffectBackend=this._getRequestedEffectBackendState(),this.resolvedBloomBackend=this._getRequestedBloomBackendState(),this.softwareBloomFrameStats={regionCount:0,processedSourcePixels:0,combinedBoundsPixels:0},this.lastSoftwareBloomFrame=null,this.canvasBloomTransportCanvas=null,this.canvasBloomTransportContext=null,this.canvasNativeSceneAlphaSnapshot=null,this.webglBloomFrameStats={available:!1,vertexCount:0,levelCount:0,bloomPixels:0},this.nativeTrailBloomSurface=void 0,this.legacyRingRasterizer=void 0,this.width=0,this.height=0,this.dpr=1,this.fxConfig=structuredClone(P),this._themeHueShift=Ji(this.config.themeColor),this._relativeOklchTheme=this.config.themeColorMode===`relative-oklch`?ct(this.config.themeColor):null,this.config.renderingMode===`legacy`&&this._applyLegacyParams(),this.waves=[],this.shards=[],this.trailStrokes=[],this.currentTrailStroke=null,this.activeTrailOwnerId=null,this.nextTrailOwnerId=1,this.trailShardCounts=new Map,this.activePointerId=null,this.activePointerSource=null,this.lastPointerPosition=null,this.lastPointerTime=0,this.lastInputSampleSourceTime=null,this.trailDistanceSinceShard=0;let i=performance.now();this.clickTimeMs=0,this.trailTimeMs=0,this.lastClickTimeSource=i,this.lastTrailTimeSource=i,this.animationFrame=null,this.lastFrameTime=null,this.renderingFrame=!1,this.paused=!1,this.destroyed=!1,this.domPointerListenersAttached=!1,this._onResize=this._resize.bind(this),this._onPointerDown=this._handlePointerDown.bind(this),this._onPointerMove=this._handlePointerMove.bind(this),this._onPointerUp=this._handlePointerUp.bind(this),this._onPointerCancel=this._handlePointerCancel.bind(this),this._onBlur=this._cancelPointer.bind(this),this._onFrame=this._renderFrame.bind(this),this._onWebGLContextLost=this._handleWebGLContextLost.bind(this),this._onWebGLContextRestored=this._handleWebGLContextRestored.bind(this),this._onWebGLEffectContextLost=this._handleWebGLEffectContextLost.bind(this),this._onWebGLEffectContextRestored=this._handleWebGLEffectContextRestored.bind(this),this._onCanvasSceneContextLost=this._handleCanvasSceneContextLost.bind(this),this._onCanvasSceneContextRestored=this._handleCanvasSceneContextRestored.bind(this),this._resize(),window.addEventListener(`resize`,this._onResize),this.config.inputSource===`dom`&&this._attachDomPointerListeners(),window.addEventListener(`blur`,this._onBlur),this.host&&!va(this.host)&&typeof ResizeObserver<`u`?(this.resizeObserver=new ResizeObserver(this._onResize),this.resizeObserver.observe(this.host)):this.resizeObserver=null}_attachDomPointerListeners(){this.domPointerListenersAttached||(window.addEventListener(`pointerdown`,this._onPointerDown),window.addEventListener(`pointermove`,this._onPointerMove,{passive:!0}),window.addEventListener(`pointerup`,this._onPointerUp),window.addEventListener(`pointercancel`,this._onPointerCancel),this.domPointerListenersAttached=!0)}_detachDomPointerListeners(){this.domPointerListenersAttached&&(window.removeEventListener(`pointerdown`,this._onPointerDown),window.removeEventListener(`pointermove`,this._onPointerMove),window.removeEventListener(`pointerup`,this._onPointerUp),window.removeEventListener(`pointercancel`,this._onPointerCancel),this.domPointerListenersAttached=!1)}_getOverlayLayers(){return[this.canvas,this.webglBloomCanvas,this.webglEffectCanvas,this.webgpuEffectCanvas,this.canvasSceneCanvas,this.contrastCanvas].filter(Boolean)}_hasActiveCompositingReference(){return this.compositingReferenceSource===null?!1:this.webgpuEffectVisible&&this.webgpuEffectRenderer?.hasSceneBackground===!0||this.webglEffectVisible&&this.webglEffectRenderer?.hasSceneBackground===!0||this.webglBloomVisible&&this.webglBloomRenderer?.hasSceneBackground===!0||this.canvasSceneVisible&&this.canvasSceneRenderer?.hasSceneBackground===!0}_usesUnknownBrowserOverlay(){return this.config.outputCompositing===`browser-overlay`&&!this._hasActiveCompositingReference()}_usesIndependentHostPayload(){return Me(this._getEffectiveHostCompositing())}_getEffectiveHostCompositing(){return this._resolveHostCompositingState().resolvedHostCompositing}getEffectiveHostCompositing(){return this._getEffectiveHostCompositing()}_resolveHostCompositingState(){let e=Ie({outputCompositing:this.config.outputCompositing,requestedHostCompositing:this.config.hostCompositing,hostCompositingSurface:this.config.hostCompositingSurface,hasCompositingReference:this._hasActiveCompositingReference()});return{requestedHostCompositing:this.config.hostCompositing,hostCompositingSurface:this.config.hostCompositingSurface,...e}}_syncHostCompositingState(){let e=this.hostCompositingState,t=this._resolveHostCompositingState(),n=e&&e.requestedHostCompositing===t.requestedHostCompositing&&e.resolvedHostCompositing===t.resolvedHostCompositing&&e.hostCompositingSurface===t.hostCompositingSurface&&e.compositingWarning===t.compositingWarning;if(this.hostCompositingState=t,!(n||typeof CustomEvent!=`function`||typeof this.canvas?.dispatchEvent!=`function`))try{this.canvas.dispatchEvent(new CustomEvent(Fi,{detail:{...t}}))}catch{}}_getCanvasOutputCompositing(){return this._usesIndependentHostPayload()?`host-additive`:this.config.outputCompositing}_getOverlayColorCompensation(){return this._usesUnknownBrowserOverlay()&&!this._usesIndependentHostPayload()?this.config.overlayColorCompensation:`none`}_getOverlayAlphaPolicy(){return this._usesUnknownBrowserOverlay()&&!this._usesIndependentHostPayload()?this.config.overlayAlphaPolicy:`coverage`}_requestCompositingMountRefresh(){if(this._syncHostCompositingState(),this._hasVisibleEffects()){this.compositingMountPending=!0;return}this.compositingMountPending=!1,this._applyCompositingMount()}_flushCompositingMountRefresh(){this.compositingMountPending&&(this.compositingMountPending=!1,this._applyCompositingMount())}_applyCompositingMount(){let e=this._usesIndependentHostPayload(),t=this.config.hostCompositingSurface===`dom-backdrop`;if(!this.ownsCanvas||!this.overlayMountParent||!this.overlayRoot)return;let n=this.config.isolatedCompositing||e,r=n?this.overlayRoot:this.overlayMountParent;this.overlayRoot.style.mixBlendMode=e&&t?this._getEffectiveHostCompositing():``;for(let t of this._getOverlayLayers()){let n=t===this.contrastCanvas&&!e;t.style.mixBlendMode=n?`darken`:``}n&&this.overlayMountParent.appendChild(this.overlayRoot);for(let e of this._getOverlayLayers())e.style.position=n||this.host?`absolute`:`fixed`,r.appendChild(e);n||this.overlayRoot.remove(),this.overlayParent=r}_applyLegacyParams(e=this.fxConfig){e.trail.gradient=structuredClone(Ka),e.trail.coreWidth=Ga,e.trail.width=Wa,e.bloom.trailAlpha=0,e.bloom.ringBlur=80,e.bloom.diskBlur=65,e.bloom.shardBlur=0}_createFxParamResetBaseline(){let e=structuredClone(P);return this.config.renderingMode===`legacy`&&this._applyLegacyParams(e),e}_commitFxParamConfig(e){for(let e of Object.keys(this.fxConfig))delete this.fxConfig[e];Object.assign(this.fxConfig,e)}_resize(){if(this.destroyed)return;let e=this._getCanvasRect(),t=Math.max(1,e.width||window.innerWidth||1),n=Math.max(1,e.height||window.innerHeight||1),r=Math.min(window.devicePixelRatio||1,this.config.maxDpr);this.width=t,this.height=n,this.dpr=r,this.canvas.width=Math.round(t*r),this.canvas.height=Math.round(n*r),this.context.setTransform(r,0,0,r,0,0),this.contrastCanvas&&this.contrastContext&&(this.contrastCanvas.width=this.canvas.width,this.contrastCanvas.height=this.canvas.height,this.contrastContext.setTransform(r,0,0,r,0,0)),this._requestRender()}_getCanvasRect(){return this.host&&!va(this.host)?this.host.getBoundingClientRect():va(this.host)?this.canvas.getBoundingClientRect():{left:0,top:0,width:window.innerWidth,height:window.innerHeight}}_getPointerPosition(e){let t=this._getCanvasRect();return{x:K(e.clientX-t.left,0,this.width),y:K(e.clientY-t.top,0,this.height)}}_normalizePointerInput(e){return!e||!Number.isFinite(e.x)||!Number.isFinite(e.y)||e.pointerId!==void 0&&!Number.isFinite(e.pointerId)||e.pointerType!==void 0&&e.pointerType!==`mouse`&&e.pointerType!==`touch`&&e.pointerType!==`pen`?null:{x:K(e.x,0,this.width),y:K(e.y,0,this.height),pointerId:e.pointerId??1,pointerType:e.pointerType??`mouse`}}_getDomPointerInput(e,t=e){let n=this._getPointerPosition(e),r=e.pointerType||t.pointerType||`mouse`;return{...n,pointerId:e.pointerId??t.pointerId??1,pointerType:r}}_getDomInputSourceTime(e,t){if(!Number.isFinite(e)||e<=0)return t;let n=e;return n>t+1e3&&Number.isFinite(performance.timeOrigin)&&(n-=performance.timeOrigin),n<0||n>t+1e3?t:Math.min(n,t)}_getDomTrailSampleTime(e,t,n){let r=Math.max(0,t-e);return Math.max(0,n-Qi(r,this.config.trailTimeScale))}_getTrailInputTime(e=performance.now()){return this._advanceTrailTime(e),this.trailTimeMs}_getClickInputTime(e=performance.now()){return this._advanceClickTime(e),this.clickTimeMs}_advanceClickTime(e=performance.now()){if(this.paused||!Number.isFinite(e))return 0;if(this.lastClickTimeSource===null)return this.lastClickTimeSource=e,0;let t=e-this.lastClickTimeSource;if(t<=0)return 0;let n=Qi(t,this.config.clickTimeScale);return this.clickTimeMs+=n,this.lastClickTimeSource=e,n}_advanceTrailTime(e=performance.now()){if(this.paused||!Number.isFinite(e))return 0;if(this.lastTrailTimeSource===null)return this.lastTrailTimeSource=e,0;let t=e-this.lastTrailTimeSource;if(t<=0)return 0;let n=Qi(t,this.config.trailTimeScale);return this.trailTimeMs+=n,this.lastTrailTimeSource=e,n}_getScale(){return this.config.scale*(this.height/P.referenceHeight)*1}_getEffectiveOpacity(){return this.config.opacity}_getEffectiveOverlayAlphaLimit(){return!this._usesUnknownBrowserOverlay()||this._usesIndependentHostPayload()?this.config.overlayAlphaLimit:this.config.overlayAlphaLimit*(this._relativeOklchTheme?.coverageScale??1)}_acceptPointerDown(e){return!((e.pointerType||`mouse`)===`mouse`&&e.button>0||this.inputFilter&&!this.inputFilter(e))}_handlePointerDown(e){this.destroyed||this.paused||!this._acceptPointerDown(e)||this.pointerDown(this._getDomPointerInput(e))&&this.config.inputSamplingRate>0&&(this.lastInputSampleSourceTime=this._getDomInputSourceTime(e.timeStamp,performance.now()))}pointerDown(e){if(this.destroyed||this.paused)return!1;let t=this._normalizePointerInput(e);if(!t||this.activePointerId!==null&&this.activePointerSource!==`hover`)return!1;this.activePointerId!==null&&this.currentTrailStroke&&(this.currentTrailStroke.active=!1),this.activePointerId=t.pointerId,this.activePointerSource=`press`,this._beginTrailOwner();let n=performance.now();return this.lastPointerPosition={x:t.x,y:t.y},this.lastPointerTime=this._getTrailInputTime(n),this.lastInputSampleSourceTime=n,this.trailDistanceSinceShard=0,this.config.trailEnabled&&this._startTrailStroke(this.lastPointerPosition,this.lastPointerTime),this.config.clickEnabled&&this._spawnClick(t.x,t.y),this._requestRender(),!0}_handlePointerMove(e){if(this.destroyed||this.paused||!this.config.trailEnabled||this.activePointerId===null&&this.config.trailAlways&&!this._acceptPointerDown(e))return;let t=typeof e.getCoalescedEvents==`function`?e.getCoalescedEvents():[e],n=t.length>0?t:[e],r=performance.now(),i=this._getTrailInputTime(r);for(let t of n){let n=this._getDomInputSourceTime(t.timeStamp??e.timeStamp,r),a=this._getDomTrailSampleTime(n,r,i);this._pointerMoveAtTime(this._getDomPointerInput(t,e),a,n)}}pointerMove(e){let t=performance.now();return this._pointerMoveAtTime(e,this._getTrailInputTime(t),t)}_pointerMoveAtTime(e,t=null,n=null){if(this.destroyed||this.paused||!this.config.trailEnabled)return!1;let r=this._normalizePointerInput(e);if(!r)return!1;let i={x:r.x,y:r.y},a=Number.isFinite(t)?t:this._getTrailInputTime(),o=Number.isFinite(n)?n:performance.now(),s=Math.max(this.lastPointerTime,a);return this.activePointerId===null&&this.config.trailAlways?(this.activePointerId=r.pointerId,this.activePointerSource=`hover`,this._beginTrailOwner(),this.lastPointerPosition=i,this.lastPointerTime=s,this.lastInputSampleSourceTime=o,this.trailDistanceSinceShard=0,this._startTrailStroke(i,s,!0),this._requestRender(),!0):this.activePointerId===null||r.pointerId!==this.activePointerId?!1:this._acceptInputSample(o)?(this._ensureCurrentTrailStroke(s),this._appendPointerSample(i,s),this._requestRender(),!0):!0}_acceptInputSample(e){let t=this.config.inputSamplingRate;if(t<=0)return!0;if(!Number.isFinite(this.lastInputSampleSourceTime))return this.lastInputSampleSourceTime=e,!0;let n=1e3/t;return e-this.lastInputSampleSourceTime=this.fxConfig.trail.lifetimeMs)&&(this.currentTrailStroke.points.length=0,this.currentTrailStroke.points.push(yo(this.lastPointerPosition.x,this.lastPointerPosition.y,e)),this.lastPointerTime=e,this.trailDistanceSinceShard=0):(this._startTrailStroke(this.lastPointerPosition,e),this.lastPointerTime=e,this.trailDistanceSinceShard=0))}_appendPointerSample(e,t){if(!this.currentTrailStroke||!this.lastPointerPosition)return;let n=this.lastPointerPosition,r=ra(n,e),i=this._getScale(),a=Math.max(.5,this.fxConfig.trail.minVertexDistance*i);if(r0?s/a:0,d=J(e.x,t.x,u),f=J(e.y,t.y,u),p=na(0,W);this.shards.push(vo(d,f,p,`trail`,n,this.fxConfig.shards,J(r,i,u),c)),l++,this.trailShardCounts.set(c,l),s+=o}this.trailDistanceSinceShard=(this.trailDistanceSinceShard+a)%o}_handlePointerUp(e){this.pointerUp(e.pointerId??1)}_handlePointerCancel(e){this.pointerCancel(e.pointerId??1)}pointerUp(e=1){return this.destroyed||this.paused||!Number.isFinite(e)||this.activePointerId===null||e!==this.activePointerId?!1:(this._releaseActivePointer(!1),!0)}pointerCancel(e=1){return this.destroyed||this.paused||!Number.isFinite(e)||this.activePointerId===null||e!==this.activePointerId?!1:(this._releaseActivePointer(!0),!0)}_cancelPointer(){this.activePointerId!==null&&this._releaseActivePointer(!0)}_releaseActivePointer(e=!1){let t=this.activeTrailOwnerId;if(this.currentTrailStroke&&(this.currentTrailStroke.active=!1,e||this.currentTrailStroke.points.length<2)){let e=this.trailStrokes.indexOf(this.currentTrailStroke);e>=0&&this.trailStrokes.splice(e,1)}this.currentTrailStroke=null,this.activeTrailOwnerId=null,t!==null&&(this.trailShardCounts.get(t)??0)===0&&this.trailShardCounts.delete(t),this.activePointerId=null,this.activePointerSource=null,this.lastPointerPosition=null,this.lastPointerTime=0,this.lastInputSampleSourceTime=null,this.trailDistanceSinceShard=0,this._requestRender()}_spawnClick(e,t){let n=this._getScale(),r=this._getClickInputTime();this.waves.push(new go(e,t,this.fxConfig,r));for(let i=0;i0?`webgl2`:t}return this.webglBloomUnavailable||!this.ownsCanvas||!this.overlayParent?t:`pending`}_setResolvedEffectBackend(e){if(this.resolvedEffectBackend!==e&&(this.resolvedEffectBackend=e,!(typeof CustomEvent!=`function`||typeof this.canvas?.dispatchEvent!=`function`)))try{this.canvas.dispatchEvent(new CustomEvent(Pi,{detail:{requestedEffectBackend:this.config.effectBackend,resolvedEffectBackend:e}}))}catch{}}_setResolvedBloomBackend(e){if(this.resolvedBloomBackend!==e&&(this.resolvedBloomBackend=e,!(typeof CustomEvent!=`function`||typeof this.canvas?.dispatchEvent!=`function`)))try{this.canvas.dispatchEvent(new CustomEvent(Ni,{detail:{requestedBloomBackend:this.config.bloomBackend,resolvedBloomBackend:e}}))}catch{}}_handleWebGPUEffectStateChange(e,t){if(this.destroyed||e!==this.webgpuEffectRenderer)return;let n=be(this.config.effectBackend);if(t===`ready`){this.webgpuEffectUnavailable=!1,this.config.renderingMode!==`legacy`&&(n===`webgpu`||n===`auto`)&&(this._setResolvedEffectBackend(`pending`),this._requestRender());return}if(t!==`lost`&&t!==`unavailable`)return;let r=this.webgpuEffectVisible;if(this.webgpuEffectUnavailable=!0,this._setWebGPUEffectVisible(!1),r&&(this.paused||!this.renderingFrame)){let e=this._resolveCanvasFallbackBloomBackend();this._restoreCanvasOutputAfterContextLoss(e)}else this._setCanvasOutputVisible(!0);this._setResolvedEffectBackend(this._getRequestedEffectBackendState()),this._setResolvedBloomBackend(this._getRequestedBloomBackendState()),this._requestRender()}_ensureWebGPUEffectRenderer(){if(this.webgpuEffectRenderer)return this.webgpuEffectRenderer.setPreferHdr(this.config.webgpuPreferHdr),this.webgpuEffectRenderer.available;if(this.webgpuEffectUnavailable||!this.ownsCanvas||!this.overlayParent)return!1;let e=$();Ma(e,!this.host&&!this.config.isolatedCompositing,`2147483646`,``),e.style.display=`none`,this.overlayParent.appendChild(e);let t=null;try{t=new si(e,{preferHdr:this.config.webgpuPreferHdr,onStateChange:(e,t)=>this._handleWebGPUEffectStateChange(t,e)});let n=this.compositingReferenceSource;if(n!==null&&!t.setCompositingReference(n,{fit:this.compositingReferenceFit}))throw Error(`WebGPU 无法接入当前合成参考`)}catch(n){return console.warn(`[BAClickFX] WebGPU 创建失败:`,n),this.webgpuEffectUnavailable=!0,t?.destroy(),e.remove(),!1}return this.webgpuEffectCanvas=e,this.webgpuEffectRenderer=t,t.available}_resizeWebGPUEffectRenderer(){return!!this.webgpuEffectRenderer?.resize(this.width,this.height,this.dpr,this.fxConfig.bloom.resolutionScale,this.fxConfig.bloom.diffusion)}_prepareWebGPUEffectBackend(){return this._ensureWebGPUEffectRenderer()&&this._resizeWebGPUEffectRenderer()?(this.resolvedEffectBackend!==`webgpu`&&this._setResolvedEffectBackend(`pending`),!0):((this.webgpuEffectRenderer?.status===`pending`||this.webgpuEffectRenderer?.status===`ready`)&&this._setResolvedEffectBackend(`pending`),!1)}_prepareEffectBackend(){let e=be(this.config.effectBackend);if(this.config.renderingMode===`legacy`||e===`canvas2d`)return this._setResolvedEffectBackend(`canvas2d`),null;if(e===`webgpu`||e===`auto`){if(this._prepareWebGPUEffectBackend())return`webgpu`;if(!this.webgpuEffectUnavailable&&this.webgpuEffectRenderer?.status===`pending`)return null}return this._prepareWebGLEffectBackend()?`webgl2`:null}_setWebGPUEffectVisible(e){if(!e&&this.webgpuEffectRenderer&&!this.webgpuEffectRenderer.suspendPresentation()){let e=this.webgpuEffectVisible;console.warn(`[BAClickFX] WebGPU Canvas 暂停失败,已释放该 Renderer`),this._destroyWebGPUEffectRenderer(),this.webgpuEffectUnavailable=!1,e&&this._requestCompositingMountRefresh();return}if(!this.webgpuEffectCanvas){let e=this.webgpuEffectVisible;this.webgpuEffectVisible=!1,e&&this._requestCompositingMountRefresh();return}this.webgpuEffectVisible!==e&&(this.webgpuEffectVisible=e,this.webgpuEffectCanvas.style.display=e?``:`none`,this._requestCompositingMountRefresh())}_destroyWebGPUEffectRenderer(){let e=this.webgpuEffectRenderer;this.webgpuEffectRenderer=null,this.webgpuEffectCanvas?.remove(),this.webgpuEffectCanvas=null,this.webgpuEffectVisible=!1,e?.destroy()}_handleWebGLContextLost(){if(this.destroyed||!this.webglBloomVisible)return;let e=this._resolveCanvasFallbackBloomBackend();this._setWebGLBloomVisible(!1),this.paused||!this.renderingFrame?this._restoreCanvasOutputAfterContextLoss(e):this._setResolvedBloomBackend(e),this._requestRender()}_handleWebGLContextRestored(){if(this.destroyed||(this.webglBloomRenderer?.available||(this._destroyWebGLBloomRenderer(),this.webglBloomUnavailable=!1),this.paused||!this._hasVisibleEffects()||this.config.renderingMode===`legacy`||be(this.config.effectBackend)!==`canvas2d`))return;let e=Se(this.config.bloomBackend);e!==`webgl2`&&e!==`auto`||(this._setResolvedBloomBackend(`pending`),this._requestRender())}_handleWebGLEffectContextLost(){if(this.destroyed||!this.webglEffectVisible)return;this._setWebGLEffectVisible(!1),this._setResolvedEffectBackend(`canvas2d`);let e=this._resolveCanvasFallbackBloomBackend();this.paused||!this.renderingFrame?this._restoreCanvasOutputAfterContextLoss(e):(this._setResolvedBloomBackend(e),this._setCanvasOutputVisible(!0)),this._requestRender()}_handleWebGLEffectContextRestored(){if(this.destroyed||(this.webglEffectRenderer?.available||(this._destroyWebGLEffectRenderer(),this.webglEffectUnavailable=!1),this.paused||!this._hasVisibleEffects()))return;let e=be(this.config.effectBackend);this.config.renderingMode!==`legacy`&&e!==`canvas2d`&&(this._setResolvedEffectBackend(`pending`),this._requestRender())}_ensureWebGLEffectRenderer(){if(this.webglEffectRenderer)return this.webglEffectRenderer.available;if(this.webglEffectUnavailable||!this.ownsCanvas||!this.overlayParent)return!1;let e=$();Ma(e,!this.host&&!this.config.isolatedCompositing,`2147483646`,``),e.style.display=`none`,this.overlayParent.appendChild(e);let t=null;try{if(t=new Tr(e),!t.available)return this.webglEffectUnavailable=!0,t.destroy(),e.remove(),!1;let n=this.compositingReferenceSource;if(n!==null&&!t.setCompositingReference(n,{fit:this.compositingReferenceFit}))return this.webglEffectUnavailable=!0,t.destroy(),e.remove(),!1}catch(n){return console.warn(`[BAClickFX] 纯 WebGL2 创建失败:`,n),this.webglEffectUnavailable=!0,t?.destroy(),e.remove(),!1}return this.webglEffectCanvas=e,this.webglEffectRenderer=t,e.addEventListener(`webglcontextlost`,this._onWebGLEffectContextLost),e.addEventListener(`webglcontextrestored`,this._onWebGLEffectContextRestored),!0}_resizeWebGLEffectRenderer(){return!!this.webglEffectRenderer?.resize(this.width,this.height,this.dpr,this.fxConfig.bloom.resolutionScale,this.fxConfig.bloom.diffusion)}_prepareWebGLEffectBackend(){let e=be(this.config.effectBackend);if(this.config.renderingMode===`legacy`||e===`canvas2d`)return this._setResolvedEffectBackend(`canvas2d`),!1;let t=this._ensureWebGLEffectRenderer()&&this._resizeWebGLEffectRenderer();return t?this.resolvedEffectBackend!==`webgl2`&&this._setResolvedEffectBackend(`pending`):this._setResolvedEffectBackend(`canvas2d`),t}_setWebGLEffectVisible(e){if(!this.webglEffectCanvas){let e=this.webglEffectVisible;this.webglEffectVisible=!1,e&&this._requestCompositingMountRefresh();return}this.webglEffectVisible!==e&&(this.webglEffectVisible=e,this.webglEffectCanvas.style.display=e?``:`none`,e||this.webglEffectRenderer?.clear(),this._requestCompositingMountRefresh())}_destroyWebGLEffectRenderer(){this.webglEffectCanvas?.removeEventListener(`webglcontextlost`,this._onWebGLEffectContextLost),this.webglEffectCanvas?.removeEventListener(`webglcontextrestored`,this._onWebGLEffectContextRestored),this.webglEffectRenderer?.destroy(),this.webglEffectCanvas?.remove(),this.webglEffectRenderer=null,this.webglEffectCanvas=null,this.webglEffectVisible=!1}_handleCanvasSceneContextLost(){if(this.destroyed||!this.canvasSceneVisible)return;let e=this._isLegacy;this._setCanvasSceneVisible(!1),(this.paused||!this.renderingFrame)&&this._restoreCanvasOutputAfterContextLoss(e?`legacy`:`native`,e),this._requestRender()}_handleCanvasSceneContextRestored(){this.destroyed||(this.canvasSceneRenderer?.available||(this._destroyCanvasSceneRenderer(),this.canvasSceneUnavailable=!1),!(!this._hasCompositingReference()||!this._hasVisibleEffects())&&(this._isLegacy||this.resolvedEffectBackend===`canvas2d`&&this.resolvedBloomBackend===`native`)&&this._requestRender())}_ensureCanvasSceneRenderer(){if(this.canvasSceneRenderer)return this.canvasSceneRenderer.available;if(this.canvasSceneUnavailable||!this.ownsCanvas||!this.overlayParent)return!1;let e=$();Ma(e,!this.host&&!this.config.isolatedCompositing,`2147483646`,``),e.style.display=`none`,this.overlayParent.appendChild(e);let t=null;try{if(t=new yi(e),!t.available)return this.canvasSceneUnavailable=!0,t.destroy(),e.remove(),!1;let n=this.compositingReferenceSource;if(n!==null&&!t.setCompositingReference(n,{fit:this.compositingReferenceFit}))return this.canvasSceneUnavailable=!0,t.destroy(),e.remove(),!1}catch(n){return console.warn(`[BAClickFX] Canvas Scene Final Pass 创建失败:`,n),this.canvasSceneUnavailable=!0,t?.destroy(),e.remove(),!1}return this.canvasSceneCanvas=e,this.canvasSceneRenderer=t,e.addEventListener(`webglcontextlost`,this._onCanvasSceneContextLost),e.addEventListener(`webglcontextrestored`,this._onCanvasSceneContextRestored),!0}_resizeCanvasSceneRenderer(){return!!this.canvasSceneRenderer?.resize(this.width,this.height,this.dpr)}_prepareCanvasSceneBackend(e,t,n){return e||!n&&t!==`native`||!this._hasCompositingReference()?!1:this._ensureCanvasSceneRenderer()&&this._resizeCanvasSceneRenderer()&&this.canvasSceneRenderer.hasSceneBackground}_setCanvasSceneVisible(e){if(!this.canvasSceneCanvas){let e=this.canvasSceneVisible;this.canvasSceneVisible=!1,e&&this._requestCompositingMountRefresh();return}this.canvasSceneVisible!==e&&(this.canvasSceneVisible=e,this.canvasSceneCanvas.style.display=e?``:`none`,e||this.canvasSceneRenderer?.clear(),this._requestCompositingMountRefresh())}_destroyCanvasSceneRenderer(){this.canvasSceneCanvas?.removeEventListener(`webglcontextlost`,this._onCanvasSceneContextLost),this.canvasSceneCanvas?.removeEventListener(`webglcontextrestored`,this._onCanvasSceneContextRestored),this.canvasSceneRenderer?.destroy(),this.canvasSceneCanvas?.remove(),this.canvasSceneRenderer=null,this.canvasSceneCanvas=null,this.canvasSceneVisible=!1}_destroyWebGLBloomRenderer(){this.webglBloomCanvas?.removeEventListener(`webglcontextlost`,this._onWebGLContextLost),this.webglBloomCanvas?.removeEventListener(`webglcontextrestored`,this._onWebGLContextRestored),this.webglBloomRenderer?.destroy(),this.webglBloomCanvas?.remove(),this.webglBloomRenderer=null,this.webglBloomCanvas=null,this.webglBloomVisible=!1}_ensureWebGLBloomRenderer(){if(this.webglBloomRenderer)return this.webglBloomRenderer.available;if(this.webglBloomUnavailable||!this.ownsCanvas||!this.overlayParent)return!1;let e=$();Ma(e,!this.host&&!this.config.isolatedCompositing,`2147483646`,``),e.style.display=`none`,this.overlayParent.appendChild(e);let t=null;try{if(t=new Tr(e),!t.available)return this.webglBloomUnavailable=!0,t.destroy(),e.remove(),!1;let n=this.compositingReferenceSource;if(n!==null&&!t.setCompositingReference(n,{fit:this.compositingReferenceFit}))return this.webglBloomUnavailable=!0,t.destroy(),e.remove(),!1}catch(n){return console.warn(`[BAClickFX] WebGL2 Bloom 创建失败,回退软件 Bloom:`,n),this.webglBloomUnavailable=!0,t?.destroy(),e.remove(),!1}return this.webglBloomCanvas=e,this.webglBloomRenderer=t,e.addEventListener(`webglcontextlost`,this._onWebGLContextLost),e.addEventListener(`webglcontextrestored`,this._onWebGLContextRestored),t.available}_resizeWebGLBloomRenderer(){return!!this.webglBloomRenderer?.resize(this.width,this.height,this.dpr,this.fxConfig.bloom.resolutionScale,this.fxConfig.bloom.diffusion)}_resolveBloomBackend(){let e=Se(this.config.bloomBackend);return e===`native`?`native`:e===`software`?this.bloomRenderer.available?`software`:`native`:this._ensureWebGLBloomRenderer()&&this._resizeWebGLBloomRenderer()?`webgl2`:`native`}_resolveCanvasFallbackBloomBackend(){return Se(this.config.bloomBackend)===`software`&&this.bloomRenderer?.available?`software`:`native`}_setWebGLBloomVisible(e){if(!this.webglBloomCanvas){let e=this.webglBloomVisible;this.webglBloomVisible=!1,e&&this._requestCompositingMountRefresh();return}let t=this.webglBloomVisible;!e&&t&&this._setCanvasOutputVisible(!0),this.webglBloomVisible!==e&&(this.webglBloomVisible=e,this.webglBloomCanvas.style.display=e?``:`none`,e||this.webglBloomRenderer?.clear(),this._requestCompositingMountRefresh())}_setCanvasOutputVisible(e){if(!this.ownsCanvas)return;let t=e?``:`hidden`;if(this.canvas.style.visibility=t,this.contrastCanvas){let t=!this._isLegacy&&this.config.outputCompositing!==`browser-overlay`&&this.config.lightBackgroundContrastAlpha>0;this.contrastCanvas.style.visibility=e||t?``:`hidden`}}_invalidateSceneBackgroundOutputs(){this._setWebGPUEffectVisible(!1),this._setWebGLEffectVisible(!1),this._setWebGLBloomVisible(!1),this._setCanvasSceneVisible(!1),this.webglEffectRenderer?.clear(),this.webglBloomRenderer?.clear(),this.canvasSceneRenderer?.clear(),this.context.save(),this.context.setTransform(this.dpr,0,0,this.dpr,0,0),this.context.clearRect(0,0,this.width,this.height),this.context.restore(),this._clearLightBackgroundContrast(),this._setCanvasOutputVisible(!0)}_releaseBackendFrameResources(){this._setWebGPUEffectVisible(!1),this._setWebGLEffectVisible(!1),this._setWebGLBloomVisible(!1),this._setCanvasSceneVisible(!1),this.webgpuEffectRenderer?.releaseFrameResources(),this.webglEffectRenderer?.releaseFrameResources(),this.webglBloomRenderer?.releaseFrameResources(),this.canvasSceneRenderer?.releaseFrameResources(),this._setCanvasOutputVisible(!0)}_releaseBloomBackendFrameResources(){this._setWebGLBloomVisible(!1),this._setCanvasSceneVisible(!1),this.webglBloomRenderer?.releaseFrameResources(),this.canvasSceneRenderer?.releaseFrameResources(),!this.webglEffectVisible&&!this.webgpuEffectVisible&&this._setCanvasOutputVisible(!0)}_usesSoftwareBloom(){return this._resolveBloomBackend()===`software`}_getBloomRenderer(e){for(;this.bloomRenderers.length<=e;)this.bloomRenderers.push(new Zt(()=>$()));return this.bloomRenderers[e]}_trimBloomRendererPool(e,t=2){let n=e===0?1:Math.max(1,e+t);if(this.bloomRenderers.length<=n)return;let r=this.bloomRenderers.splice(n);for(let e of r)e.destroy()}_getNativeTrailBloomSurface(){if(this.nativeTrailBloomSurface===void 0){let e=$(),t=e.getContext(`2d`);this.nativeTrailBloomSurface=t?{canvas:e,context:t,dpr:this.dpr}:null}return this.nativeTrailBloomSurface&&(this.nativeTrailBloomSurface.dpr=this.dpr),this.nativeTrailBloomSurface}_getLegacyRingRasterizer(){return this.legacyRingRasterizer===void 0&&(this.legacyRingRasterizer=Ua.create()),this.legacyRingRasterizer}get _isLegacy(){return this.config.renderingMode===`legacy`}_renderLightBackgroundContrast(e,t=!1){let n=this.contrastContext;if(!(!n||!this.contrastCanvas)&&(n.setTransform(this.dpr,0,0,this.dpr,0,0),n.clearRect(0,0,this.width,this.height),!(this.config.outputCompositing===`browser-overlay`||this.config.lightBackgroundContrastAlpha<=0))){if(t)n.save(),n.setTransform(1,0,0,1,0,0),n.globalCompositeOperation=`source-over`,n.drawImage(this.canvas,0,0),n.restore();else{n.save(),n.globalCompositeOperation=`lighter`;for(let t of this.trailStrokes)t.points.length>=2&&Ho(n,t.points,e,this._getEffectiveOpacity(),this.fxConfig,!1,!1,null,t.trailFrameData);for(let t of this.waves)t.drawBase(n,e,this._getEffectiveOpacity(),!1,this.config.outputCompositing,this.dpr);for(let t of this.shards)t.draw(n,e,this._getEffectiveOpacity(),this.fxConfig);for(let t of this.waves)t.drawRings(n,e,this._getEffectiveOpacity(),!1,!1,null,this.dpr,this.config.outputCompositing);n.restore()}n.save(),n.setTransform(1,0,0,1,0,0),n.globalCompositeOperation=`source-in`,n.fillStyle=oa(Mi,this.config.lightBackgroundContrastAlpha),n.fillRect(0,0,this.contrastCanvas.width,this.contrastCanvas.height),n.restore()}}_getSoftwareBloomRegions(e){let t=this.fxConfig.bloom,n=2**t.diffusion*e+8,r=[],i=(e,t,i,a,o,s=[],c=[])=>{ea(r,{x:e-n,y:t-n,width:i-e+n*2,height:a-t+n*2,emissionBounds:{x:e,y:t,width:i-e,height:a-t},waves:o?[o]:[],trailBatches:s,shards:c})};for(let t of this.waves){if(t.fx.bloom.clickEmissionScale<=0)continue;let n=t.ageMs/this.fxConfig.disk.lifetimeMs,r=t.ageMs/this.fxConfig.rings.lifetimeMs,a=n<1?this.fxConfig.disk.radius*X(this.fxConfig.disk.sizeKeys,n)*e:0;if(r<1)for(let n of t.rings){let t=Ba(n,r,e,this.fxConfig.rings);a=Math.max(a,t.radius+t.width*.5)}a<=0||i(t.x-a,t.y-a,t.x+a,t.y+a,t,[])}let a=Math.max(1,this.fxConfig.trail.geometryWidth*e*t.trailCoverageScale*.5);for(let e of this.trailStrokes){if(e.points.length<2)continue;let n=e.trailFrameData??Co(e.points,this.fxConfig.trail,t.trailEmission),r=this._getEffectiveOpacity()*(this.fxConfig.trail.trailOpacity??1)*t.trailEmissionAlpha/Math.max(1,t.emissionRange)*255,o=[],s=null;for(let t=1;t0){let t=Math.min(...o.map(e=>e.minimumX)),n=Math.min(...o.map(e=>e.minimumY)),r=Math.max(...o.map(e=>e.maximumX)),s=Math.max(...o.map(e=>e.maximumY));i(t-a,n-a,r+a,s+a,null,o.map(t=>({stroke:e,firstSegment:t.firstSegment,lastSegment:t.lastSegment})))}}for(let t of this.shards){let n=this.fxConfig.shards,r=q(t.ageMs/t.lifetimeMs),a=t.size*X(n.sizeKeys,r)*e;a<=0||i(t.x-a,t.y-a,t.x+a,t.y+a,null,[],[t])}return r.length===0?[]:[{x:0,y:0,width:this.width,height:this.height,emissionBounds:ta(r.map(e=>e.emissionBounds)),waves:r.flatMap(e=>e.waves),trailBatches:r.flatMap(e=>e.trailBatches),shards:r.flatMap(e=>e.shards)}]}_getCanvasOverlayBounds(e){let t=[],n=(e,n,r,i)=>{!Number.isFinite(e)||!Number.isFinite(n)||!Number.isFinite(r)||!Number.isFinite(i)||r0?r.diskBlur*e*3:0;i=Math.max(i,n+a)}if(c<1){let n=r.ringAlpha>0?r.ringBlur*e*3:0;for(let r of t.rings){let a=Ba(r,c,e,t.fx.rings);i=Math.max(i,a.radius+a.width*.5+n)}}i>0&&n(t.x-i,t.y-i,t.x+i,t.y+i)}for(let t of this.shards){let r=q(t.ageMs/t.lifetimeMs),i=t.size*X(this.fxConfig.shards.sizeKeys,r)*e;i>0&&n(t.x-i,t.y-i,t.x+i,t.y+i)}let i=this.fxConfig.trail,a=Math.max(i.width*e*.5,i.outerGlowWidth*e*3+2);for(let e of this.trailStrokes){if(e.points.length<2)continue;let t=1/0,r=1/0,i=-1/0,o=-1/0;for(let n of e.points)t=Math.min(t,n.x),r=Math.min(r,n.y),i=Math.max(i,n.x),o=Math.max(o,n.y);n(t-a,r-a,i+a,o+a)}return ta(t)}_getCanvasOverlayPixelBounds(e){let t=this._getCanvasOverlayBounds(e);if(!t)return null;let n=Math.max(0,Math.floor(t.x*this.dpr)),r=Math.max(0,Math.floor(t.y*this.dpr)),i=Math.min(this.canvas.width,Math.ceil((t.x+t.width)*this.dpr)),a=Math.min(this.canvas.height,Math.ceil((t.y+t.height)*this.dpr));return{minimumX:n,minimumY:r,maximumX:i,maximumY:a,width:Math.max(0,i-n),height:Math.max(0,a-r)}}_captureCanvasOverlayAlpha(e){if(this._getOverlayAlphaPolicy()!==`visual-max`||typeof this.context?.getImageData!=`function`)return null;let t=this._getCanvasOverlayPixelBounds(e);if(!t||t.width<=0||t.height<=0)return null;try{return{...t,data:this.context.getImageData(t.minimumX,t.minimumY,t.width,t.height).data}}catch{return null}}_prepareCanvasBloomTransportContext(){if(this._getOverlayAlphaPolicy()!==`visual-max`)return null;if(!this.canvasBloomTransportCanvas){let e=$(),t=e?.getContext?.(`2d`,{alpha:!0,willReadFrequently:!0});if(!e||!t)return null;this.canvasBloomTransportCanvas=e,this.canvasBloomTransportContext=t}let e=this.canvasBloomTransportCanvas,t=this.canvasBloomTransportContext;return(e.width!==this.canvas.width||e.height!==this.canvas.height)&&(e.width=this.canvas.width,e.height=this.canvas.height),t.setTransform(1,0,0,1,0,0),t.clearRect(0,0,e.width,e.height),t.setTransform(this.dpr,0,0,this.dpr,0,0),t.globalCompositeOperation=`lighter`,t}_limitCanvasOverlayAlpha(e,t=null,n=null,r=`lighter`,i=!0){let a=this._getOverlayAlphaPolicy(),o=this._getOverlayColorCompensation(),s=this._getEffectiveOverlayAlphaLimit(),c=o===`bright-core`,l=a===`visual-max`||s<1;if(!this._usesUnknownBrowserOverlay()||this._usesIndependentHostPayload()||!l&&!c||this.webgpuEffectVisible||this.webglEffectVisible||this.webglBloomVisible||this.canvasSceneVisible||this.ownsCanvas&&this.canvas.style.visibility===`hidden`)return;let u=this._getCanvasOverlayPixelBounds(e);if(!(!u||u.width<=0||u.height<=0)){try{let e=this.context.getImageData(u.minimumX,u.minimumY,u.width,u.height);if(a===`visual-max`)f(e,t&&t.minimumX===u.minimumX&&t.minimumY===u.minimumY&&t.width===u.width&&t.height===u.height?t.data:null,n?n.getImageData(u.minimumX,u.minimumY,u.width,u.height).data:null,s,a,r);else if(s<1){let t=Math.round(q(s)*255);for(let n=3;n{let t=e.points[0],n=e.points.at(-1);return[e.points.length,t?.x,t?.y,t?.bornAt,n?.x,n?.y,n?.bornAt].join(`,`)}).join(`|`),n=this.waves.map(e=>[e.x,e.y,e.ageMs,e.diskRotation,...e.rings.flatMap(e=>[e.radius,e.rotation,e.angularVelocity])].join(`,`)).join(`|`),r=this.shards.map(e=>[e.kind,e.x,e.y,e.ageMs,e.rotation,e.size,e.textureFrame].join(`,`)).join(`|`),i=this.fxConfig.bloom,a=this.fxConfig.trail;return[this.width,this.height,this.dpr,e,this.clickTimeMs,this.trailTimeMs,this._getEffectiveOpacity(),this.config.outputCompositing,this._getOverlayColorCompensation(),this._getEffectiveOverlayAlphaLimit(),this._getEffectiveHostCompositing(),this.compositingReferenceSource===null?`unknown`:`known`,this.config.themeColorMode,this.config.themeColor,this._themeHueShift,i.threshold,i.softKnee,i.intensity,i.diffusion,i.resolutionScale,i.trailEmission,i.trailEmissionAlpha,a.width,a.geometryWidth,JSON.stringify(this.fxConfig),t,n,r].join(`:`)}_cacheSoftwareBloomFrame(e){if(this.config.outputCompositing!==`browser-overlay`||this.canvas.width<=0||this.canvas.height<=0)return;let t=this.lastSoftwareBloomFrame?.canvas,n=t&&t!==this.canvas?t:$(),r=n.getContext?.(`2d`,{alpha:!0});if(!r){this.lastSoftwareBloomFrame=null;return}try{(n.width!==this.canvas.width||n.height!==this.canvas.height)&&(n.width=this.canvas.width,n.height=this.canvas.height),r.setTransform(1,0,0,1,0,0),r.clearRect(0,0,n.width,n.height),r.drawImage(this.canvas,0,0,this.canvas.width,this.canvas.height,0,0,n.width,n.height)}catch{this.lastSoftwareBloomFrame=null;return}this.lastSoftwareBloomFrame={canvas:n,height:n.height,signature:this._getSoftwareBloomFrameSignature(e),width:n.width}}_drawCachedSoftwareBloomFrame(e){let t=this.lastSoftwareBloomFrame;if(!t?.canvas||t.signature!==this._getSoftwareBloomFrameSignature(e))return!1;try{return this.context.save(),this.context.setTransform(1,0,0,1,0,0),this.context.globalAlpha=1,this.context.globalCompositeOperation=`copy`,this.context.drawImage(t.canvas,0,0,t.width,t.height,0,0,this.canvas.width,this.canvas.height),this.context.restore(),!0}catch{return this.context.restore(),!1}}_hasCachedSoftwareBloomFrame(e){return this.config.outputCompositing===`browser-overlay`&&this.lastSoftwareBloomFrame?.canvas!==void 0&&this.lastSoftwareBloomFrame.signature===this._getSoftwareBloomFrameSignature(e)}_renderSoftwareBloom(e){let t=this.fxConfig.bloom,n=t.diffusion,r=this._getSoftwareBloomRegions(e),i=ta(r),a=this._captureCanvasOverlayAlpha(e),o=this._prepareCanvasBloomTransportContext(),s={encodingRange:t.emissionRange,threshold:t.threshold,softKnee:t.softKnee,clamp:t.clamp,intensity:t.intensity,diffusion:n,opacity:this._getEffectiveOpacity(),outputCompositing:this.config.outputCompositing,overlayColorCompensation:`none`,overlayAlphaPolicy:this._getOverlayAlphaPolicy(),overlayAlphaLimit:this._getEffectiveOverlayAlphaLimit(),hostCompositing:this._getEffectiveHostCompositing(),enforceOverlayAlphaLimit:this._usesUnknownBrowserOverlay()},c=0,l=!1;for(let i=0;i=2&&Wo(d,n.points,e,this._getEffectiveOpacity(),this.fxConfig,n.trailFrameData,t.firstSegment,t.lastSegment)}for(let t of a.waves)t.drawBloom(d,e,this._getEffectiveOpacity());for(let t of a.shards)t.drawBloom(d,e,this._getEffectiveOpacity(),this.fxConfig);if(d.restore(),f){f.save();for(let t of a.trailBatches){let n=t.stroke;n.points.length>=2&&Uo(f,n.points,e,this._getEffectiveOpacity(),this.fxConfig,n.trailFrameData,t.firstSegment,t.lastSegment)}for(let t of a.waves)t.drawBloomCoverage(f,e,this._getEffectiveOpacity());for(let t of a.shards)t.drawBloomCoverage(f,e,this._getEffectiveOpacity(),this.fxConfig);f.restore()}let p=!1;this.context.save();try{this.config.outputCompositing===`browser-overlay`&&(this.context.globalCompositeOperation=`lighter`),p=u.composite(this.context,s),p&&o&&u.drawCurrentOutput(o)}finally{this.context.restore()}p||(this.bloomRenderer.available=!1,l=!0)}if(l||(this._limitCanvasOverlayAlpha(e,a,o,`lighter`,!1),this._cacheSoftwareBloomFrame(e)),this.softwareBloomFrameStats={regionCount:r.length,processedSourcePixels:c,combinedBoundsPixels:i?Math.max(1,Math.round(i.width*this.dpr))*Math.max(1,Math.round(i.height*this.dpr)):0},this._trimBloomRendererPool(r.length),l){let t=this._hasCachedSoftwareBloomFrame(e);this._drawCanvasFallbackFrame(e,!0,!1),t&&(this._drawCanvasFallbackFrame(e,!1,!1),this._drawCachedSoftwareBloomFrame(e)||this._drawCanvasFallbackFrame(e,!0,!1)),this._renderLightBackgroundContrast(e,!1),this._setResolvedBloomBackend(`native`)}}_renderWebGL2Scene(e,t){let n=this.fxConfig.bloom;if(!e?.available||e.contextLost)return!1;if(!this.trailStrokes.some(e=>e.points.length>=2)&&this.waves.length===0&&this.shards.length===0)return e.clear(),!0;try{e.beginFrame();for(let n of this.trailStrokes)n.points.length<2||Xo(e,n.points,t,this._getEffectiveOpacity(),this.fxConfig,n.trailFrameData);for(let n of this.waves)n.appendWebGLSceneDiskLayer(e,t,this._getEffectiveOpacity());for(let n of this.shards)n.appendWebGLScene(e,t,this._getEffectiveOpacity(),this.fxConfig);for(let n of this.waves)n.appendWebGLSceneAdditiveLayer(e,t,this._getEffectiveOpacity());if(!e.renderScene({outputCompositing:this.config.outputCompositing,hostCompositing:this._getEffectiveHostCompositing(),diskEmissionScale:n.clickEmissionScale*n.diskEmissionAlpha,ringEmissionScale:n.clickEmissionScale*n.ringEmissionAlpha}))return!1;e.beginFrame({preserveSceneStats:!0});let r=e.render({threshold:n.threshold,softKnee:n.softKnee,clamp:n.clamp,intensity:n.intensity,diffusion:n.diffusion,opacity:this._getEffectiveOpacity(),outputCompositing:this.config.outputCompositing,overlayColorCompensation:this._getOverlayColorCompensation(),overlayAlphaPolicy:this._getOverlayAlphaPolicy(),overlayAlphaLimit:this._getEffectiveOverlayAlphaLimit(),hostCompositing:this._getEffectiveHostCompositing(),webgpuHdrPeak:this.config.webgpuHdrPeak,webgpuHdrBrightness:this.config.webgpuHdrBrightness,webgpuHdrColorPreservation:this.config.webgpuHdrColorPreservation,webgpuHdrWhiteCore:this.config.webgpuHdrWhiteCore,webgpuHdrWhiteStart:this.config.webgpuHdrWhiteStart,webgpuHdrWhiteEnd:this.config.webgpuHdrWhiteEnd},{preserveCanvas:!0});return this.webglBloomFrameStats={available:e.available,...e.stats},r}catch(t){return console.warn(`[BAClickFX] WebGL2 Scene 渲染失败:`,t),e.clear(),!1}}_renderWebGL2ClickEffects(e){return this._renderWebGL2Scene(this.webglEffectRenderer,e)}_renderGPUClickEffects(e,t){return e===`webgl2`?this._renderWebGL2ClickEffects(t):this._renderWebGL2Scene(this.webgpuEffectRenderer,t)}_clearLightBackgroundContrast(){this.contrastContext&&(this.contrastContext.setTransform(this.dpr,0,0,this.dpr,0,0),this.contrastContext.clearRect(0,0,this.width,this.height))}_renderCanvasSceneEffects(e,t,n){let r=this.canvasSceneRenderer;if(!r?.available||r.contextLost)return!1;try{r.beginFrame(),this.context.globalCompositeOperation=`lighter`,this._drawCanvasTrails(e,t,n,!0);for(let t of this.waves)t.drawDiskLayer(this.context,e,this._getEffectiveOpacity(),!1,this.dpr),t.appendCanvasSceneCoverage(r,e,this._getEffectiveOpacity());if(t)for(let t of this.waves)t.drawDiskGlow(this.context,e,this._getEffectiveOpacity(),this.dpr);for(let t of this.shards)t.draw(this.context,e,this._getEffectiveOpacity(),this.fxConfig);for(let t of this.waves)t.drawAdditiveBase(this.context,e,this._getEffectiveOpacity(),!0);return this._drawWaveRings(e,t,n,!0,`scene`,`coverage`,1),r.render(this.canvas)}catch(e){return console.warn(`[BAClickFX] Canvas Scene Final Pass 渲染失败:`,e),r.clear(),!1}}_drawCanvasFallbackPass(e,t,n=!1){this.context.setTransform(this.dpr,0,0,this.dpr,0,0),this.context.clearRect(0,0,this.width,this.height),this.context.globalCompositeOperation=this._getCanvasOutputCompositing()===`browser-overlay`?`source-over`:`lighter`,this._drawCanvasTrails(e,t,n),this._drawCanvasClickEffects(e,t,n)}_drawCanvasFallbackFrame(e,t,n=!1){this.canvasNativeSceneAlphaSnapshot=null,t&&this._usesUnknownBrowserOverlay()&&!this._usesIndependentHostPayload()&&this._getOverlayAlphaPolicy()===`visual-max`&&(this._drawCanvasFallbackPass(e,!1,n),this.canvasNativeSceneAlphaSnapshot=this._captureCanvasOverlayAlpha(e)),this._drawCanvasFallbackPass(e,t,n)}_finalizeCanvasOverlayAlpha(e){let t=this.canvasNativeSceneAlphaSnapshot;this.canvasNativeSceneAlphaSnapshot=null,this._limitCanvasOverlayAlpha(e,t,null,t?`source-over`:`lighter`)}_restoreCanvasOutputAfterContextLoss(e,t=!1){let n=this._getScale(),r=Gi,i=G,a=e;this._setResolvedBloomBackend(a),this.resolvedBloomBackend===`native`&&(a=`native`);let o=!1;try{this.context.save(),o=!0,Gi=this._themeHueShift,G=this._relativeOklchTheme,this._drawCanvasFallbackFrame(n,t||a===`native`,t),t||this._renderLightBackgroundContrast(n,a===`software`),a===`software`&&this._hasVisibleEffects()&&(this._renderSoftwareBloom(n),this.bloomRenderer.available||(a=`native`))}catch(e){console.warn(`[BAClickFX] WebGL Context 丢失回退失败:`,e),a=t?`legacy`:`native`;try{this._drawCanvasFallbackFrame(n,!0,t),t||this._renderLightBackgroundContrast(n,!1)}catch(e){console.warn(`[BAClickFX] 原生 Canvas 回退失败:`,e)}}finally{Gi=r,G=i,o&&this.context.restore()}this._finalizeCanvasOverlayAlpha(n),this._setResolvedBloomBackend(a),this._setCanvasOutputVisible(!0),this._flushCompositingMountRefresh()}_drawCanvasClickEffects(e,t,n=!1){let r=this._getCanvasOutputCompositing(),i=`none`,a=this._getEffectiveOverlayAlphaLimit();for(let n of this.waves)n.drawBase(this.context,e,this._getEffectiveOpacity(),t,r,this.dpr,i,a);for(let t of this.shards)t.draw(this.context,e,this._getEffectiveOpacity(),this.fxConfig,r,i,a);this._drawWaveRings(e,t,n,!1,r,i,a)}_drawCanvasTrails(e,t,n=!1,r=!1){let i=t&&!n?this._getNativeTrailBloomSurface():null,a=r?`scene`:this._getCanvasOutputCompositing(),o=this._getEffectiveOverlayAlphaLimit();for(let s=this.trailStrokes.length-1;s>=0;s--){let c=this.trailStrokes[s];c.points.length<2||(!n&&!Array.isArray(c.trailFrameData?.segmentEnergies)&&(c.trailFrameData=Co(c.points,this.fxConfig.trail,this.fxConfig.bloom.trailEmission)),Ho(this.context,c.points,e,this._getEffectiveOpacity(),this.fxConfig,t,n,i,c.trailFrameData,r,a,`none`,o))}}_renderWebGL2Bloom(e){let t=this.webglBloomRenderer;if(!t||!this._resizeWebGLBloomRenderer()){this._fallbackFromWebGL2(e);return}if(!this._renderWebGL2Scene(t,e)){this._fallbackFromWebGL2(e);return}this._setWebGLBloomVisible(!0),this._setCanvasOutputVisible(!1)}_fallbackFromWebGL2(e){this._setWebGLBloomVisible(!1);let t=this._resolveCanvasFallbackBloomBackend();if(this._setResolvedBloomBackend(t),t=this._resolveCanvasFallbackBloomBackend(),t===`software`){this._drawCanvasFallbackFrame(e,!1,!1),this._renderLightBackgroundContrast(e,!0),this._setResolvedBloomBackend(`software`),this._renderSoftwareBloom(e);return}this._drawCanvasFallbackFrame(e,!0,!1),this._renderLightBackgroundContrast(e,!1),this._setResolvedBloomBackend(`native`)}_updateTrail(e,t,n,r=!1,i=!0,a=!1){let o=this.fxConfig.trail.lifetimeMs;for(let t=this.trailStrokes.length-1;t>=0;t--){let n=this.trailStrokes[t],i=0;for(;i=o;)i++;if(i>0&&n.points.splice(0,i),n.points.length>=2){let e=r||a?null:this.fxConfig.bloom.trailEmission;n.trailFrameData=Co(n.points,this.fxConfig.trail,e,!r)}else n.trailFrameData=null;!n.active&&n.points.length<2&&this.trailStrokes.splice(t,1)}i&&this._drawCanvasTrails(t,n,r)}_updateWaves(e,t,n,r=!0){for(let i=this.waves.length-1;i>=0;i--){let a=this.waves[i];if(a.updateTo(e),a.dead){this.waves.splice(i,1);continue}if(r){let e=this._getCanvasOutputCompositing();a.drawBase(this.context,t,this._getEffectiveOpacity(),n,e,this.dpr,`none`,this._getEffectiveOverlayAlphaLimit())}}}_drawWaveRings(e,t,n=!1,r=!1,i=this._getCanvasOutputCompositing(),a=`none`,o=this._getEffectiveOverlayAlphaLimit()){let s=n&&this.waves.some(e=>e.rings.length>0)?this._getLegacyRingRasterizer():null;for(let c of this.waves)c.drawRings(this.context,e,this._getEffectiveOpacity(),t,n,s,this.dpr,i,r,a,o)}_updateShards(e,t,n,r=!0){for(let i=this.shards.length-1;i>=0;i--){let a=this.shards[i];if(a.kind===`trail`?a.updateTo(t):a.updateTo(e),a.dead){this._releaseTrailShardOwner(a),this.shards.splice(i,1);continue}if(r){let e=this._getCanvasOutputCompositing();a.draw(this.context,n,this._getEffectiveOpacity(),this.fxConfig,e,`none`,this._getEffectiveOverlayAlphaLimit())}}}_hasVisibleEffects(){return this.waves.length>0||this.shards.length>0||this.trailStrokes.some(e=>bo(e.points))}boom(e=this.width/2,t=this.height/2){this.destroyed||this.paused||!this.config.clickEnabled||(this._spawnClick(K(Number(e)||0,0,this.width),K(Number(t)||0,0,this.height)),this._requestRender())}setPaused(e,t={}){if(this.destroyed)return;if(e===!0){if(!this.paused){let e=performance.now();this._advanceClickTime(e),this._advanceTrailTime(e),this.paused=!0,this.activePointerId!==null&&this._releaseActivePointer(),this.animationFrame!==null&&(cancelAnimationFrame(this.animationFrame),this.animationFrame=null),this.lastFrameTime=null,this.lastClickTimeSource=null,this.lastTrailTimeSource=null}t?.clear===!0&&this.clear();return}if(!this.paused)return;let n=performance.now();this.paused=!1,this.lastFrameTime=null,this.lastClickTimeSource=n,this.lastTrailTimeSource=n,this._hasVisibleEffects()?this._requestRender():this._flushCompositingMountRefresh()}setThemeColor(e){this.destroyed||(this._applyThemeColor(e),this._requestRender())}_applyThemeColor(e){let t=ze(e,ae);this.config.themeColor=t,this._themeHueShift=Ji(t),this._relativeOklchTheme=this.config.themeColorMode===`relative-oklch`?ct(t):null}setThemeColorMode(e){return this.destroyed||!Be(e)?!1:(this.config.themeColorMode=e,this._relativeOklchTheme=e===`relative-oklch`?ct(this.config.themeColor):null,this._requestRender(),!0)}setInputSamplingRate(e){return this.destroyed||!we(e)?!1:(this.updateConfig({inputSamplingRate:e}),!0)}updateConfig(e={}){if(this.destroyed)return;let t=this.config.effectBackend,n=this.config.webgpuPreferHdr,r=this.config.renderingMode,i=this.config.bloomBackend,a=this.config.outputCompositing,s=this.config.hostCompositing,l=this.config.hostCompositingSurface,u=!1;if(Ce(e.inputSource)&&e.inputSource!==this.config.inputSource&&(this._cancelPointer(),this.config.inputSource=e.inputSource,e.inputSource===`dom`?this._attachDomPointerListeners():this._detachDomPointerListeners()),we(e.inputSamplingRate)&&e.inputSamplingRate!==this.config.inputSamplingRate&&(this.config.inputSamplingRate=e.inputSamplingRate,this.lastInputSampleSourceTime=null),Le(e.clickTimeScale)&&(this._advanceClickTime(),this.config.clickTimeScale=e.clickTimeScale),Le(e.trailTimeScale)&&(this._advanceTrailTime(),this.config.trailTimeScale=e.trailTimeScale),Number.isFinite(e.scale)&&(this.config.scale=Math.max(.01,e.scale)),Number.isFinite(e.opacity)&&(this.config.opacity=q(e.opacity)),Be(e.themeColorMode)&&(this.config.themeColorMode=Ve(e.themeColorMode,oe)),(e.themeColor!==void 0||Be(e.themeColorMode))&&this._applyThemeColor(e.themeColor===void 0?this.config.themeColor:e.themeColor),Ee(e.outputCompositing)&&(u=u||e.outputCompositing!==this.config.outputCompositing,this.config.outputCompositing=e.outputCompositing),o(e.overlayAlphaPolicy)){let t=Oe(e.overlayAlphaPolicy,this.config.overlayAlphaPolicy);u=u||t!==this.config.overlayAlphaPolicy,this.config.overlayAlphaPolicy=t}if(c(e.overlayColorCompensation)){let t=ke(e.overlayColorCompensation,this.config.overlayColorCompensation);u=u||t!==this.config.overlayColorCompensation,this.config.overlayColorCompensation=t}if(Number.isFinite(e.overlayAlphaLimit)){let t=Ae(e.overlayAlphaLimit,this.config.overlayAlphaLimit);u=u||t!==this.config.overlayAlphaLimit,this.config.overlayAlphaLimit=t}if(je(e.hostCompositing)&&(u=u||e.hostCompositing!==this.config.hostCompositing,this.config.hostCompositing=e.hostCompositing),Pe(e.hostCompositingSurface)&&(u=u||e.hostCompositingSurface!==this.config.hostCompositingSurface,this.config.hostCompositingSurface=e.hostCompositingSurface),typeof e.clickEnabled==`boolean`&&(this.config.clickEnabled=e.clickEnabled),typeof e.trailEnabled==`boolean`&&(this.config.trailEnabled=e.trailEnabled,e.trailEnabled||(this.activePointerSource===`hover`&&this._releaseActivePointer(),this.clearTrail())),typeof e.trailAlways==`boolean`&&(!e.trailAlways&&this.activePointerSource===`hover`&&this._releaseActivePointer(),this.config.trailAlways=e.trailAlways),ye(e.effectBackend)&&(this.config.effectBackend=e.effectBackend),typeof e.webgpuPreferHdr==`boolean`&&(this.config.webgpuPreferHdr=e.webgpuPreferHdr),(e.webgpuHdrPeak!==void 0||e.webgpuHdrBrightness!==void 0||e.webgpuHdrColorPreservation!==void 0||e.webgpuHdrWhiteCore!==void 0||e.webgpuHdrWhiteStart!==void 0||e.webgpuHdrWhiteEnd!==void 0)&&Object.assign(this.config,Ue(e,this.config)),e.renderingMode===`enhanced`||e.renderingMode===`legacy`){let t=this.config.renderingMode===`legacy`,n=e.renderingMode===`legacy`;this.config.renderingMode=e.renderingMode,t!==n&&(n?(this.ownsCanvas&&(this.canvas.style.mixBlendMode=``,this.canvas.style.zIndex=`2147483647`,this._setWebGLBloomVisible(!1),this.contrastCanvas&&(this.contrastCanvas.style.display=`none`)),this._applyLegacyParams()):(this.ownsCanvas&&(this.canvas.style.mixBlendMode=``,this.canvas.style.zIndex=`2147483646`,this.contrastCanvas&&(this.contrastCanvas.style.display=``)),this._commitFxParamConfig(this._createFxParamResetBaseline())))}xe(e.bloomBackend)?(this.config.bloomBackend=e.bloomBackend,this.config.softwareBloomEnabled=e.bloomBackend===`software`):typeof e.softwareBloomEnabled==`boolean`&&(this.config.softwareBloomEnabled=e.softwareBloomEnabled,this.config.bloomBackend=e.softwareBloomEnabled?`software`:`native`);let d=n!==this.config.webgpuPreferHdr&&(t===`webgpu`||t===`auto`||this.config.effectBackend===`webgpu`||this.config.effectBackend===`auto`),f=t!==this.config.effectBackend||r!==this.config.renderingMode||d,p=i!==this.config.bloomBackend;if(f?(d&&this.webgpuEffectRenderer?.setPreferHdr(this.config.webgpuPreferHdr),t!==this.config.effectBackend&&(this.config.effectBackend===`webgpu`||this.config.effectBackend===`auto`)&&(this.webgpuEffectRenderer?.status===`lost`||this.webgpuEffectRenderer?.status===`unavailable`)&&(this._destroyWebGPUEffectRenderer(),this.webgpuEffectUnavailable=!1),this._releaseBackendFrameResources(),this._setResolvedEffectBackend(this._getRequestedEffectBackendState()),this._setResolvedBloomBackend(this._getRequestedBloomBackendState())):p&&this.resolvedEffectBackend!==`webgl2`&&this.resolvedEffectBackend!==`webgpu`&&(this._releaseBloomBackendFrameResources(),this._setResolvedBloomBackend(this._getRequestedBloomBackendState())),Number.isFinite(e.lightBackgroundContrastAlpha)&&(this.config.lightBackgroundContrastAlpha=q(e.lightBackgroundContrastAlpha)),typeof e.isolatedCompositing==`boolean`){let t=this.ownsCanvas?e.isolatedCompositing:!1;t!==this.config.isolatedCompositing&&(this.config.isolatedCompositing=t)}a!==this.config.outputCompositing||s!==this.config.hostCompositing||l!==this.config.hostCompositingSurface?this._requestCompositingMountRefresh():typeof e.isolatedCompositing==`boolean`&&this._applyCompositingMount(),u&&(this.lastSoftwareBloomFrame=null),Number.isFinite(e.maxDpr)&&(this.config.maxDpr=Math.max(1,e.maxDpr),this._resize()),e.touchAction!==void 0&&(this.config.touchAction=e.touchAction,this.canvas.style.touchAction=e.touchAction),this._requestRender()}setFxParams(e,t={}){if(this.destroyed)return{applied:[],normalized:[],rejected:[{path:`$instance`,value:null,reason:`destroyed`}],committed:!1,schemaVersion:2};let{nextConfig:n,...r}=bt(e,{baseline:this.fxConfig,reset:t.reset===!0,resetBaseline:this._createFxParamResetBaseline(),strict:t.strict===!0,schemaVersion:t.schemaVersion??2});return r.committed&&(this._commitFxParamConfig(n),this._requestRender()),r}setFxParam(e,t){let n=this.setFxParams({[e]:t},{strict:!0});return n.committed&&n.applied.length===1}setTriangleRoundness(e){return this.setFxParam(`shards.roundness`,e)}getFxConfig(){return structuredClone(this.fxConfig)}resetFxConfig(){this.setFxParams({},{reset:!0,strict:!0})}clearTrail(){this.trailStrokes.length=0,this.currentTrailStroke=null,this.shards=this.shards.filter(e=>e.kind!==`trail`),this.trailShardCounts.clear(),this.lastInputSampleSourceTime=null,this.activeTrailOwnerId!==null&&this.trailShardCounts.set(this.activeTrailOwnerId,0),this._requestRender()}clear(){this.waves.length=0,this.shards.length=0,this.trailStrokes.length=0,this.currentTrailStroke=null,this.trailShardCounts.clear(),this.lastInputSampleSourceTime=null,this._trimBloomRendererPool(0,0),this.context.clearRect(0,0,this.width,this.height),this.contrastContext?.clearRect(0,0,this.width,this.height),this.webglBloomRenderer?.clear(),this.webgpuEffectRenderer?.clear(),this.webglEffectRenderer?.clear(),this.canvasSceneRenderer?.clear(),this._flushCompositingMountRefresh()}_hasCompositingReference(){return this.compositingReferenceSource!==null}_applyCompositingReferenceToRenderers(e,t,n,r,i){let a=[{name:`WebGPU`,renderer:this.webgpuEffectRenderer,discard:()=>{this._setWebGPUEffectVisible(!1),this._destroyWebGPUEffectRenderer()}},{name:`纯 WebGL2`,renderer:this.webglEffectRenderer,discard:()=>{this._setWebGLEffectVisible(!1),this._destroyWebGLEffectRenderer()}},{name:`WebGL2 Bloom`,renderer:this.webglBloomRenderer,discard:()=>{this._setWebGLBloomVisible(!1),this._destroyWebGLBloomRenderer()}},{name:`Canvas Final Pass`,renderer:this.canvasSceneRenderer,discard:()=>{this._setCanvasSceneVisible(!1),this._destroyCanvasSceneRenderer()}}].filter(e=>e.renderer),o=[],s=null;for(let n of a){let r=!1;try{r=n.renderer.setCompositingReference(e,{fit:t})}catch(e){console.warn(`[BAClickFX] ${n.name} 背景更新失败:`,e)}if(!r){s=n;break}o.push(n)}if(!s)return!0;let c=!1;for(let e=o.length-1;e>=0;e--){let t=o[e],i=!1;try{i=t.renderer.setCompositingReference(n,{fit:r})}catch(e){console.warn(`[BAClickFX] ${t.name} 背景回滚失败:`,e)}i||(t.discard(),c=!0)}return c&&(i&&this._invalidateSceneBackgroundOutputs(),this._requestRender()),!1}setCompositingReference(e,t={}){if(this.destroyed)return!1;let n=t.fit??`cover`;if(n!==`cover`||e!==null&&!ya(e))return!1;let r=this.compositingReferenceSource,i=this.compositingReferenceFit,a=this.webgpuEffectVisible||this.webglEffectVisible||this.webglBloomVisible||this.canvasSceneVisible;return this._applyCompositingReferenceToRenderers(e,n,r,i,a)?(this.compositingReferenceSource=e,this.compositingReferenceFit=n,this.lastSoftwareBloomFrame=null,this._requestCompositingMountRefresh(),e!==null&&(this.webgpuEffectUnavailable=!1,this.webglEffectUnavailable=!1,this.webglBloomUnavailable=!1,this.canvasSceneUnavailable=!1),a&&(this._invalidateSceneBackgroundOutputs(),this._flushCompositingMountRefresh()),e===null&&this.canvasSceneRenderer?.releaseFrameResources(),this._requestRender(),!0):!1}getConfig(){let e=this._resolveHostCompositingState();return{...this.config,...e,resolvedEffectBackend:this.resolvedEffectBackend,resolvedBloomBackend:this.resolvedBloomBackend,resolvedWebGPUOutputMode:this._getResolvedWebGPUOutputMode(),unity:structuredClone(P)}}_getResolvedWebGPUOutputMode(){let e=be(this.config.effectBackend);if(this.config.renderingMode===`legacy`||e!==`webgpu`&&e!==`auto`||!this.ownsCanvas||!this.overlayParent)return`unavailable`;let t=this.webgpuEffectRenderer;return t?.deviceManager.outputMode===`extended`?`extended`:t?.deviceManager.outputMode===`standard`?`standard`:t?.status===`pending`||t?.status===`ready`||!this.webgpuEffectUnavailable&&(e===`webgpu`||e===`auto`)?`pending`:`unavailable`}destroy(){if(!this.destroyed){this.destroyed=!0,window.removeEventListener(`resize`,this._onResize),this._detachDomPointerListeners(),window.removeEventListener(`blur`,this._onBlur),this.resizeObserver?.disconnect(),this.animationFrame!==null&&(cancelAnimationFrame(this.animationFrame),this.animationFrame=null),this.clear();for(let e of this.bloomRenderers)e.destroy();this._destroyWebGLBloomRenderer(),this._destroyWebGPUEffectRenderer(),this._destroyWebGLEffectRenderer(),this._destroyCanvasSceneRenderer(),this.nativeTrailBloomSurface&&(this.nativeTrailBloomSurface.canvas.width=0,this.nativeTrailBloomSurface.canvas.height=0,this.nativeTrailBloomSurface=null),this.legacyRingRasterizer&&(this.legacyRingRasterizer.destroy(),this.legacyRingRasterizer=null),this.canvasBloomTransportCanvas&&(this.canvasBloomTransportCanvas.width=0,this.canvasBloomTransportCanvas.height=0,this.canvasBloomTransportCanvas=null,this.canvasBloomTransportContext=null),this.canvasNativeSceneAlphaSnapshot=null,this.ownsCanvas&&(this.webglBloomCanvas?.remove(),this.contrastCanvas?.remove(),this.canvas.remove(),this.overlayRoot?.remove()),this.webglBloomCanvas=null,this.webglBloomVisible=!1,this.canvasSceneCanvas=null,this.canvasSceneVisible=!1,this.compositingReferenceSource=null,this.overlayParent=null,this.overlayMountParent=null,this.overlayRoot=null}}};function Qo(e,t={}){let{nextConfig:n,...r}=bt(e,{baseline:P,schemaVersion:t.schemaVersion??2,strict:t.strict===!0});return r}return e.BAClickFX=Zo,e.default=Zo,e.BLOOM_BACKEND_CHANGE_EVENT=Ni,e.CONFIG=I,e.DEFAULT_THEME_COLOR=ae,e.DEFAULT_THEME_COLOR_MODE=oe,e.EFFECT_BACKEND_CHANGE_EVENT=Pi,e.FX_PARAM_MIGRATIONS=ve,e.FX_PARAM_SCHEMA=_e,e.FX_PARAM_SCHEMA_VERSION=le,e.HOST_COMPOSITING_CHANGE_EVENT=Fi,e.SIZE_CORRECTION=ce,e.UNITY_FX_TOUCH=P,e.applyFxParamPatch=Qo,e.createConfig=We,e})({}); \ No newline at end of file diff --git a/src/WebRendererDocumentBuilder.cs b/src/WebRendererDocumentBuilder.cs new file mode 100644 index 0000000..6766ac9 --- /dev/null +++ b/src/WebRendererDocumentBuilder.cs @@ -0,0 +1,61 @@ +namespace BASpark +{ + internal static class WebRendererDocumentBuilder + { + internal const string ScriptPlaceholder = ""; + + internal static string Build( + string template, + string vendorScript, + string adapterScript) + { + if (string.IsNullOrWhiteSpace(template)) + { + throw new ArgumentException("Renderer template cannot be empty.", nameof(template)); + } + if (string.IsNullOrWhiteSpace(vendorScript)) + { + throw new ArgumentException("Renderer vendor script cannot be empty.", nameof(vendorScript)); + } + if (string.IsNullOrWhiteSpace(adapterScript)) + { + throw new ArgumentException("Renderer adapter script cannot be empty.", nameof(adapterScript)); + } + + int placeholderIndex = template.IndexOf(ScriptPlaceholder, StringComparison.Ordinal); + if (placeholderIndex < 0) + { + throw new InvalidOperationException( + $"Renderer placeholder '{ScriptPlaceholder}' was not found."); + } + + int nextPlaceholderIndex = template.IndexOf( + ScriptPlaceholder, + placeholderIndex + ScriptPlaceholder.Length, + StringComparison.Ordinal); + if (nextPlaceholderIndex >= 0) + { + // Multiple copies would initialize two renderers and duplicate every host input. + throw new InvalidOperationException( + $"Renderer placeholder '{ScriptPlaceholder}' must occur exactly once."); + } + + string inlineScripts = + $"\n" + + $""; + + return template[..placeholderIndex] + + inlineScripts + + template[(placeholderIndex + ScriptPlaceholder.Length)..]; + } + + internal static string EscapeInlineScript(string script) + { + // HTML parsers terminate inline scripts before JavaScript parsing, even inside JS strings. + return script.Replace( + " + WebViewProcessRecoveryAction.RecreateWebViewControl, + CoreWebView2ProcessFailedKind.RenderProcessExited => + WebViewProcessRecoveryAction.RebuildRendererDocument, + _ => WebViewProcessRecoveryAction.None + }; + } + } +} diff --git a/src/WebViewUnresponsiveTracker.cs b/src/WebViewUnresponsiveTracker.cs new file mode 100644 index 0000000..7f45cc6 --- /dev/null +++ b/src/WebViewUnresponsiveTracker.cs @@ -0,0 +1,38 @@ +namespace BASpark +{ + internal sealed class WebViewUnresponsiveTracker + { + private const int RecoveryThreshold = 3; + private static readonly long ContinuityWindowTicks = + TimeSpan.FromSeconds(15).Ticks; + + private object? _webViewIdentity; + private long _lastReportTicks; + + internal int ConsecutiveReports { get; private set; } + + internal bool Register(object webViewIdentity, long reportTicks) + { + long elapsedTicks = reportTicks - _lastReportTicks; + bool continuesPreviousSequence = + ReferenceEquals(_webViewIdentity, webViewIdentity) && + elapsedTicks >= 0 && + elapsedTicks <= ContinuityWindowTicks; + + ConsecutiveReports = continuesPreviousSequence + ? ConsecutiveReports + 1 + : 1; + _webViewIdentity = webViewIdentity; + _lastReportTicks = reportTicks; + + return ConsecutiveReports >= RecoveryThreshold; + } + + internal void Reset() + { + _webViewIdentity = null; + _lastReportTicks = 0; + ConsecutiveReports = 0; + } + } +} diff --git a/src/licenses/ba-click-fx/LICENSE b/src/licenses/ba-click-fx/LICENSE new file mode 100644 index 0000000..91a508e --- /dev/null +++ b/src/licenses/ba-click-fx/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2026 CialloKing + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/src/licenses/ba-click-fx/THIRD_PARTY_NOTICES.md b/src/licenses/ba-click-fx/THIRD_PARTY_NOTICES.md new file mode 100644 index 0000000..2725243 --- /dev/null +++ b/src/licenses/ba-click-fx/THIRD_PARTY_NOTICES.md @@ -0,0 +1,40 @@ +# Third-Party Notices + +Early versions of **ba-click-fx** were developed with reference to the +implementation, parameters, and visual behavior of the following +MIT-licensed projects: + +- **BASpark**, maintained at `DoomVoss/BASpark` +- **BA-Spark-Cursor**, maintained at `VanillaNahida/BA-Spark-Cursor` + +BA-Spark-Cursor states that its click effect originates from BASpark. + +The current version of ba-click-fx has since been substantially refactored. +This notice is retained to preserve attribution and license information for +the early implementation history. + +Both projects currently distribute the following MIT license notice: + +--- + +MIT License + +Copyright (c) 2026 Doom + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/src/licenses/ba-click-fx/VERSION.txt b/src/licenses/ba-click-fx/VERSION.txt new file mode 100644 index 0000000..fb82761 --- /dev/null +++ b/src/licenses/ba-click-fx/VERSION.txt @@ -0,0 +1,5 @@ +Package: ba-click-fx +Version: v1.2.25 +Commit: cbefdb849a96dae8d418547cf8cc90ab230029e3 +Artifact: dist/ba-click-fx.iife.js +SHA256: F198EEF9B29AE84D7B11B275DC0877D6BDD6C4D79035DDD200943CA8D5C3B764 diff --git a/tests/BASpark.Tests/InputSamplingRateContractTests.cs b/tests/BASpark.Tests/InputSamplingRateContractTests.cs new file mode 100644 index 0000000..aa9701c --- /dev/null +++ b/tests/BASpark.Tests/InputSamplingRateContractTests.cs @@ -0,0 +1,28 @@ +namespace BASpark.Tests; + +public class InputSamplingRateContractTests +{ + [Theory] + [InlineData(-1, 0)] + [InlineData(0, 0)] + [InlineData(40, 40)] + [InlineData(1000, 1000)] + [InlineData(1001, 1000)] + public void NormalizeInputSamplingRate_UsesUpstreamApiRange( + int value, + int expected) + { + Assert.Equal(expected, ConfigManager.NormalizeInputSamplingRate(value)); + } + + [Fact] + public void BuildInputSamplingRateScript_UsesNormalizedInteger() + { + Assert.Equal( + "if(window.updateInputSamplingRate) window.updateInputSamplingRate(40);", + MainWindow.BuildInputSamplingRateScript(40)); + Assert.Equal( + "if(window.updateInputSamplingRate) window.updateInputSamplingRate(1000);", + MainWindow.BuildInputSamplingRateScript(2000)); + } +} diff --git a/tests/BASpark.Tests/PackagedRendererResourcesTests.cs b/tests/BASpark.Tests/PackagedRendererResourcesTests.cs new file mode 100644 index 0000000..d9dc90b --- /dev/null +++ b/tests/BASpark.Tests/PackagedRendererResourcesTests.cs @@ -0,0 +1,68 @@ +using System.Collections; +using System.Reflection; +using System.Resources; + +namespace BASpark.Tests; + +public class PackagedRendererResourcesTests +{ + private static readonly string[] ExpectedWebResources = + { + "web/index.html", + "web/index.legacy.html", + "web/fx-adapter.js", + "web/vendor/ba-click-fx.iife.js" + }; + + private static readonly string[] ExpectedLicenseFiles = + { + "LICENSE", + "THIRD_PARTY_NOTICES.md", + "VERSION.txt" + }; + + [Fact] + public void WebResources_AreEmbeddedAndNonEmpty() + { + Assembly assembly = typeof(WebRendererDocumentBuilder).Assembly; + string generatedResourceName = Assert.Single( + assembly.GetManifestResourceNames(), + name => name.EndsWith(".g.resources", StringComparison.Ordinal)); + + using Stream stream = Assert.IsAssignableFrom( + assembly.GetManifestResourceStream(generatedResourceName)); + using var reader = new ResourceReader(stream); + var resourceNames = reader.Cast() + .Select(entry => Assert.IsType(entry.Key)) + .ToHashSet(StringComparer.Ordinal); + + foreach (string expectedResource in ExpectedWebResources) + { + Assert.Contains(expectedResource, resourceNames); + reader.GetResourceData( + expectedResource, + out string resourceType, + out byte[] resourceData); + + Assert.False(string.IsNullOrWhiteSpace(resourceType)); + Assert.NotEmpty(resourceData); + } + } + + [Fact] + public void ThirdPartyLicenseFiles_AreCopiedToOutput() + { + string licenseDirectory = Path.Combine( + AppContext.BaseDirectory, + "licenses", + "ba-click-fx"); + + foreach (string expectedFile in ExpectedLicenseFiles) + { + var file = new FileInfo(Path.Combine(licenseDirectory, expectedFile)); + + Assert.True(file.Exists, $"Missing third-party file: {file.FullName}"); + Assert.True(file.Length > 0, $"Empty third-party file: {file.FullName}"); + } + } +} diff --git a/tests/BASpark.Tests/WebRendererDocumentBuilderTests.cs b/tests/BASpark.Tests/WebRendererDocumentBuilderTests.cs new file mode 100644 index 0000000..e8abd19 --- /dev/null +++ b/tests/BASpark.Tests/WebRendererDocumentBuilderTests.cs @@ -0,0 +1,89 @@ +namespace BASpark.Tests; + +public class WebRendererDocumentBuilderTests +{ + [Fact] + public void Build_InsertsVendorBeforeAdapterAndRemovesPlaceholder() + { + string template = + $"{WebRendererDocumentBuilder.ScriptPlaceholder}"; + + string result = WebRendererDocumentBuilder.Build( + template, + "window.vendorLoaded = true;", + "window.adapterLoaded = true;"); + + int vendorIndex = result.IndexOf("window.vendorLoaded", StringComparison.Ordinal); + int adapterIndex = result.IndexOf("window.adapterLoaded", StringComparison.Ordinal); + + Assert.True(vendorIndex >= 0); + Assert.True(adapterIndex > vendorIndex); + Assert.DoesNotContain( + WebRendererDocumentBuilder.ScriptPlaceholder, + result, + StringComparison.Ordinal); + } + + [Fact] + public void Build_RejectsMissingPlaceholder() + { + InvalidOperationException exception = Assert.Throws(() => + { + WebRendererDocumentBuilder.Build( + "", + "window.vendorLoaded = true;", + "window.adapterLoaded = true;"); + }); + + Assert.Contains("was not found", exception.Message, StringComparison.Ordinal); + } + + [Fact] + public void Build_RejectsDuplicatePlaceholder() + { + string template = + WebRendererDocumentBuilder.ScriptPlaceholder + + WebRendererDocumentBuilder.ScriptPlaceholder; + + InvalidOperationException exception = Assert.Throws(() => + { + WebRendererDocumentBuilder.Build( + template, + "window.vendorLoaded = true;", + "window.adapterLoaded = true;"); + }); + + Assert.Contains("exactly once", exception.Message, StringComparison.Ordinal); + } + + [Theory] + [InlineData("", "window.adapterLoaded = true;")] + [InlineData(" ", "window.adapterLoaded = true;")] + [InlineData("window.vendorLoaded = true;", "")] + [InlineData("window.vendorLoaded = true;", "\t")] + public void Build_RejectsEmptyScripts(string vendorScript, string adapterScript) + { + Assert.Throws(() => + { + WebRendererDocumentBuilder.Build( + WebRendererDocumentBuilder.ScriptPlaceholder, + vendorScript, + adapterScript); + }); + } + + [Fact] + public void Build_EscapesScriptEndTagsCaseInsensitively() + { + string result = WebRendererDocumentBuilder.Build( + WebRendererDocumentBuilder.ScriptPlaceholder, + "const vendor = '';", + "const adapter = ''; "); + + Assert.DoesNotContain("''", result, StringComparison.Ordinal); + Assert.DoesNotContain("''", result, StringComparison.Ordinal); + Assert.Equal( + 2, + result.Split("<\\/script>", StringSplitOptions.None).Length - 1); + } +} diff --git a/tests/BASpark.Tests/WebViewProcessFailurePolicyTests.cs b/tests/BASpark.Tests/WebViewProcessFailurePolicyTests.cs new file mode 100644 index 0000000..3221361 --- /dev/null +++ b/tests/BASpark.Tests/WebViewProcessFailurePolicyTests.cs @@ -0,0 +1,39 @@ +using Microsoft.Web.WebView2.Core; + +namespace BASpark.Tests; + +public class WebViewProcessFailurePolicyTests +{ + [Theory] + [InlineData( + CoreWebView2ProcessFailedKind.BrowserProcessExited, + (int)WebViewProcessRecoveryAction.RecreateWebViewControl)] + [InlineData( + CoreWebView2ProcessFailedKind.RenderProcessExited, + (int)WebViewProcessRecoveryAction.RebuildRendererDocument)] + public void GetRecoveryAction_RecoversFailuresThatInvalidateTheMainDocument( + CoreWebView2ProcessFailedKind failureKind, + int expectedValue) + { + Assert.Equal( + (WebViewProcessRecoveryAction)expectedValue, + WebViewProcessFailurePolicy.GetRecoveryAction(failureKind)); + } + + [Theory] + [InlineData(CoreWebView2ProcessFailedKind.RenderProcessUnresponsive)] + [InlineData(CoreWebView2ProcessFailedKind.FrameRenderProcessExited)] + [InlineData(CoreWebView2ProcessFailedKind.UtilityProcessExited)] + [InlineData(CoreWebView2ProcessFailedKind.SandboxHelperProcessExited)] + [InlineData(CoreWebView2ProcessFailedKind.GpuProcessExited)] + [InlineData(CoreWebView2ProcessFailedKind.PpapiPluginProcessExited)] + [InlineData(CoreWebView2ProcessFailedKind.PpapiBrokerProcessExited)] + [InlineData(CoreWebView2ProcessFailedKind.UnknownProcessExited)] + public void GetRecoveryAction_PreservesRuntimeManagedFailures( + CoreWebView2ProcessFailedKind failureKind) + { + Assert.Equal( + WebViewProcessRecoveryAction.None, + WebViewProcessFailurePolicy.GetRecoveryAction(failureKind)); + } +} diff --git a/tests/BASpark.Tests/WebViewUnresponsiveTrackerTests.cs b/tests/BASpark.Tests/WebViewUnresponsiveTrackerTests.cs new file mode 100644 index 0000000..681bbcd --- /dev/null +++ b/tests/BASpark.Tests/WebViewUnresponsiveTrackerTests.cs @@ -0,0 +1,56 @@ +namespace BASpark.Tests; + +public class WebViewUnresponsiveTrackerTests +{ + [Fact] + public void Register_RecoversAfterThreeContinuousReports() + { + var tracker = new WebViewUnresponsiveTracker(); + var webView = new object(); + long startTicks = TimeSpan.FromSeconds(10).Ticks; + + Assert.False(tracker.Register(webView, startTicks)); + Assert.False( + tracker.Register(webView, startTicks + TimeSpan.FromSeconds(4).Ticks)); + Assert.True( + tracker.Register(webView, startTicks + TimeSpan.FromSeconds(8).Ticks)); + Assert.Equal(3, tracker.ConsecutiveReports); + } + + [Fact] + public void Register_ResetsSequenceAfterContinuityWindow() + { + var tracker = new WebViewUnresponsiveTracker(); + var webView = new object(); + + Assert.False(tracker.Register(webView, TimeSpan.FromSeconds(1).Ticks)); + Assert.False(tracker.Register(webView, TimeSpan.FromSeconds(17).Ticks)); + Assert.Equal(1, tracker.ConsecutiveReports); + } + + [Fact] + public void Register_ResetsSequenceForAnotherWebView() + { + var tracker = new WebViewUnresponsiveTracker(); + long startTicks = TimeSpan.FromSeconds(1).Ticks; + + Assert.False(tracker.Register(new object(), startTicks)); + Assert.False( + tracker.Register(new object(), startTicks + TimeSpan.FromSeconds(1).Ticks)); + Assert.Equal(1, tracker.ConsecutiveReports); + } + + [Fact] + public void Reset_ClearsSequence() + { + var tracker = new WebViewUnresponsiveTracker(); + var webView = new object(); + + tracker.Register(webView, TimeSpan.FromSeconds(1).Ticks); + tracker.Register(webView, TimeSpan.FromSeconds(2).Ticks); + tracker.Reset(); + + Assert.False(tracker.Register(webView, TimeSpan.FromSeconds(3).Ticks)); + Assert.Equal(1, tracker.ConsecutiveReports); + } +} diff --git a/tests/Web/fx-adapter.test.mjs b/tests/Web/fx-adapter.test.mjs new file mode 100644 index 0000000..5ed03de --- /dev/null +++ b/tests/Web/fx-adapter.test.mjs @@ -0,0 +1,424 @@ +import assert from 'node:assert/strict'; +import { readFileSync } from 'node:fs'; +import test from 'node:test'; +import vm from 'node:vm'; + +const adapterSource = readFileSync( + new URL('../../src/Web/fx-adapter.js', import.meta.url), + 'utf8', +); + +function createHarness(options = {}) +{ + const calls = + { + addEventListener: [], + clearTrail: 0, + destroy: 0, + messages: [], + pointerCancel: [], + pointerDown: [], + pointerMove: [], + pointerUp: [], + setCompositingReference: [], + setInputSamplingRate: [], + setPaused: [], + setThemeColor: [], + updateConfig: [], + }; + const windowListeners = new Map(); + const canvasListeners = new Map(); + + class FakeFx + { + constructor(config) + { + if (options.constructorError) + { + throw options.constructorError; + } + + this.width = 800; + this.height = 600; + this.config = config; + this.resolvedEffectBackend = 'pending'; + this.resolvedBloomBackend = 'pending'; + this.resolvedHostCompositing = 'pending'; + this.compositingWarning = null; + this.canvas = + { + addEventListener(type, listener) + { + calls.addEventListener.push(type); + canvasListeners.set(type, listener); + }, + }; + FakeFx.instance = this; + } + + destroy() + { + calls.destroy++; + } + + clearTrail() + { + calls.clearTrail++; + } + + getConfig() + { + return { + effectBackend: this.config.effectBackend, + bloomBackend: this.config.bloomBackend, + resolvedEffectBackend: this.resolvedEffectBackend, + resolvedBloomBackend: this.resolvedBloomBackend, + hostCompositing: this.config.hostCompositing, + resolvedHostCompositing: this.resolvedHostCompositing, + hostCompositingSurface: this.config.hostCompositingSurface, + compositingWarning: this.compositingWarning, + }; + } + + pointerCancel(pointerId) + { + calls.pointerCancel.push(pointerId); + return true; + } + + pointerDown(input) + { + calls.pointerDown.push(input); + return true; + } + + pointerMove(input) + { + calls.pointerMove.push(input); + return true; + } + + pointerUp(pointerId) + { + calls.pointerUp.push(pointerId); + return true; + } + + setPaused(paused, pauseOptions) + { + calls.setPaused.push({ paused, pauseOptions }); + } + + setCompositingReference(source, referenceOptions) + { + calls.setCompositingReference.push({ source, referenceOptions }); + return true; + } + + setThemeColor(color) + { + calls.setThemeColor.push(color); + } + + setInputSamplingRate(rateHz) + { + calls.setInputSamplingRate.push(rateHz); + this.config.inputSamplingRate = rateHz; + return true; + } + + updateConfig(config) + { + calls.updateConfig.push(config); + Object.assign(this.config, config); + } + } + + const windowMock = + { + __basparkRendererGeneration: 'test-generation', + BAClickFX: + { + BAClickFX: FakeFx, + BLOOM_BACKEND_CHANGE_EVENT: 'baclickfxbackendchange', + EFFECT_BACKEND_CHANGE_EVENT: 'baclickfxeffectbackendchange', + HOST_COMPOSITING_CHANGE_EVENT: 'baclickfxhostcompositingchange', + }, + chrome: + { + webview: + { + postMessage(message) + { + calls.messages.push(JSON.parse(message)); + }, + }, + }, + addEventListener(type, listener) + { + windowListeners.set(type, listener); + }, + }; + const context = + { + console: + { + error() + { + }, + warn() + { + }, + }, + document: + { + readyState: 'complete', + addEventListener() + { + throw new Error('DOMContentLoaded listener is not expected for a complete document.'); + }, + }, + window: windowMock, + }; + + vm.runInNewContext(adapterSource, context, { filename: 'fx-adapter.js' }); + + return { + calls, + canvasListeners, + fx: FakeFx.instance, + window: windowMock, + windowListeners, + }; +} + +test('initializes the vendored renderer in manual WebView2 mode', () => +{ + const harness = createHarness(); + + assert.equal(harness.fx.config.inputSource, 'manual'); + assert.equal(harness.fx.config.effectBackend, 'webgl2'); + assert.equal(harness.fx.config.bloomBackend, 'webgl2'); + assert.equal(harness.fx.config.inputSamplingRate, 40); + assert.equal(harness.fx.config.outputCompositing, 'browser-overlay'); + assert.equal(harness.fx.config.overlayAlphaPolicy, 'visual-max'); + assert.equal(harness.fx.config.overlayColorCompensation, 'bright-core'); + assert.equal(harness.fx.config.overlayAlphaLimit, 0.85); + assert.equal(harness.fx.config.hostCompositing, 'source-over'); + assert.equal(harness.fx.config.hostCompositingSurface, 'transparent-window'); + assert.equal(harness.fx.config.themeColorMode, 'relative-oklch'); + assert.equal(harness.fx.config.isolatedCompositing, false); + assert.equal(harness.fx.config.lightBackgroundContrastAlpha, 0); + assert.equal(harness.fx.config.maxDpr, 2); + assert.equal(harness.calls.setCompositingReference.length, 0); + assert.equal(harness.calls.messages.at(-1).type, 'ready'); + assert.equal(harness.calls.messages.at(-1).generation, 'test-generation'); + assert.equal(harness.calls.messages.at(-1).requestedEffectBackend, 'webgl2'); + assert.equal(harness.calls.messages.at(-1).resolvedEffectBackend, 'pending'); + assert.equal(harness.calls.messages.at(-1).requestedBloomBackend, 'webgl2'); + assert.equal(harness.calls.messages.at(-1).resolvedBloomBackend, 'pending'); + assert.deepEqual( + harness.calls.addEventListener, + [ + 'baclickfxbackendchange', + 'baclickfxeffectbackendchange', + 'baclickfxhostcompositingchange', + ], + ); +}); + +test('maps normalized host input and BASpark settings to BAClickFX', () => +{ + const harness = createHarness(); + + harness.window.updateEffectSettings(1.5, 0.75, 1.2, 0.8); + const settings = harness.calls.updateConfig.at(-1); + assert.equal(settings.scale, 1); + assert.equal(settings.opacity, 0.75); + assert.equal(settings.trailTimeScale, 1.2); + assert.equal(settings.clickTimeScale, 0.8); + + harness.window.updateColor('45,175,255'); + assert.equal(harness.calls.setThemeColor.at(-1), '#2dafff'); + + assert.equal(harness.window.updateInputSamplingRate(60), true); + assert.equal(harness.window.updateInputSamplingRate(1.5), true); + assert.equal(harness.window.updateInputSamplingRate(0), true); + assert.deepEqual(harness.calls.setInputSamplingRate, [60, 1.5, 0]); + assert.equal(harness.fx.config.inputSamplingRate, 0); + + harness.window.setInputContext('mouse', true); + assert.equal(harness.calls.updateConfig.at(-1).trailAlways, true); + + harness.window.externalMove(0.25, 0.5); + assert.equal(harness.calls.pointerMove.at(-1).x, 200); + assert.equal(harness.calls.pointerMove.at(-1).y, 300); + assert.equal(harness.calls.pointerMove.at(-1).pointerType, 'mouse'); + + harness.window.externalBoom(0.5, 0.25); + assert.equal(harness.calls.pointerDown.at(-1).x, 400); + assert.equal(harness.calls.pointerDown.at(-1).y, 150); + assert.equal(harness.calls.pointerDown.at(-1).pointerId, 1); + assert.equal(harness.calls.pointerCancel.length, 1); + assert.equal(harness.calls.clearTrail, 1); + + harness.window.externalUp(); + assert.deepEqual(harness.calls.pointerUp, [1]); + + harness.window.externalCancel(); + assert.equal(harness.calls.pointerCancel.at(-1), 1); + assert.equal(harness.calls.clearTrail, 2); +}); + +test('keeps the current color when host configuration is invalid', () => +{ + const harness = createHarness(); + const colorCallCount = harness.calls.setThemeColor.length; + const errorMessageCount = harness.calls.messages.filter( + (message) => message.type === 'error', + ).length; + + assert.equal(harness.window.updateColor('45,not-a-number,255'), false); + assert.equal(harness.calls.setThemeColor.length, colorCallCount); + assert.equal( + harness.calls.messages.filter((message) => message.type === 'error').length, + errorMessageCount, + ); +}); + +test('keeps the current sampling rate when host configuration is invalid', () => +{ + const harness = createHarness(); + + assert.equal(harness.window.updateInputSamplingRate(-1), false); + assert.equal(harness.window.updateInputSamplingRate(0.5), false); + assert.equal(harness.window.updateInputSamplingRate(1001), false); + assert.equal(harness.window.updateInputSamplingRate('40'), false); + assert.equal(harness.window.updateInputSamplingRate('invalid'), false); + assert.equal(harness.calls.setInputSamplingRate.length, 0); + assert.equal(harness.fx.config.inputSamplingRate, 40); +}); + +test('disables always-trail for touch and blocks input while paused', () => +{ + const harness = createHarness(); + + harness.window.setInputContext('touch', true); + assert.equal(harness.calls.updateConfig.at(-1).trailAlways, false); + + harness.window.externalBoom(0.1, 0.2); + assert.equal(harness.calls.pointerDown.at(-1).pointerType, 'touch'); + + harness.window.setRenderingPaused(true); + assert.equal(harness.calls.setPaused.at(-1).paused, true); + assert.equal(harness.calls.setPaused.at(-1).pauseOptions.clear, true); + + const downCount = harness.calls.pointerDown.length; + assert.equal(harness.window.externalBoom(0.3, 0.4), false); + assert.equal(harness.calls.pointerDown.length, downCount); + + harness.window.setRenderingPaused(false); + assert.equal(harness.calls.setPaused.at(-1).paused, false); + assert.equal(harness.calls.setPaused.at(-1).pauseOptions, undefined); +}); + +test('changes a software Bloom fallback to the bounded native backend', () => +{ + const harness = createHarness(); + const listener = harness.canvasListeners.get('baclickfxbackendchange'); + + harness.fx.resolvedEffectBackend = 'canvas2d'; + harness.fx.resolvedBloomBackend = 'software'; + + listener( + { + detail: + { + requestedBloomBackend: 'webgl2', + resolvedBloomBackend: 'software', + }, + }, + ); + + assert.equal(harness.calls.messages.at(-1).type, 'backend'); + assert.equal(harness.calls.messages.at(-1).resolvedEffectBackend, 'canvas2d'); + assert.equal(harness.calls.messages.at(-1).resolvedBloomBackend, 'software'); + assert.equal(harness.calls.updateConfig.at(-1).bloomBackend, 'native'); +}); + +test('reports Full WebGL backend resolution to the host', () => +{ + const harness = createHarness(); + const listener = harness.canvasListeners.get('baclickfxeffectbackendchange'); + + harness.fx.resolvedEffectBackend = 'webgl2'; + harness.fx.resolvedBloomBackend = 'webgl2'; + listener( + { + detail: + { + requestedEffectBackend: 'webgl2', + resolvedEffectBackend: 'webgl2', + }, + }, + ); + + const message = harness.calls.messages.at(-1); + assert.equal(message.type, 'backend'); + assert.equal(message.backend, 'webgl2'); + assert.equal(message.requestedEffectBackend, 'webgl2'); + assert.equal(message.resolvedEffectBackend, 'webgl2'); + assert.equal(message.requestedBloomBackend, 'webgl2'); + assert.equal(message.resolvedBloomBackend, 'webgl2'); +}); + +test('reports resolved source-over transparent-window compositing to the host', () => +{ + const harness = createHarness(); + const listener = harness.canvasListeners.get( + 'baclickfxhostcompositingchange', + ); + + harness.fx.resolvedHostCompositing = 'source-over'; + harness.fx.compositingWarning = null; + listener( + { + detail: + { + requestedHostCompositing: 'source-over', + resolvedHostCompositing: 'source-over', + hostCompositingSurface: 'transparent-window', + compositingWarning: null, + }, + }, + ); + + const message = harness.calls.messages.at(-1); + assert.equal(message.type, 'backend'); + assert.equal(message.requestedHostCompositing, 'source-over'); + assert.equal(message.resolvedHostCompositing, 'source-over'); + assert.equal(message.hostCompositingSurface, 'transparent-window'); + assert.equal(message.compositingWarning, null); +}); + +test('reports initialization failure without announcing readiness', () => +{ + const harness = createHarness( + { + constructorError: new Error('unsupported runtime'), + }, + ); + + assert.equal(harness.calls.messages.some((message) => message.type === 'ready'), false); + assert.equal(harness.calls.messages.at(-1).type, 'error'); + assert.equal(harness.calls.messages.at(-1).phase, 'initialize'); +}); + +test('destroys renderer-owned resources before the document unloads', () => +{ + const harness = createHarness(); + + harness.windowListeners.get('beforeunload')(); + + assert.equal(harness.calls.destroy, 1); +}); diff --git a/tests/Web/vendor-contract.test.mjs b/tests/Web/vendor-contract.test.mjs new file mode 100644 index 0000000..841e47e --- /dev/null +++ b/tests/Web/vendor-contract.test.mjs @@ -0,0 +1,118 @@ +import assert from 'node:assert/strict'; +import { Buffer } from 'node:buffer'; +import { createHash } from 'node:crypto'; +import { readFileSync } from 'node:fs'; +import test from 'node:test'; +import vm from 'node:vm'; + +const expectedSha256 = + 'F198EEF9B29AE84D7B11B275DC0877D6BDD6C4D79035DDD200943CA8D5C3B764'; +const vendorPath = new URL( + '../../src/Web/vendor/ba-click-fx.iife.js', + import.meta.url, +); +const adapterPath = new URL('../../src/Web/fx-adapter.js', import.meta.url); +const templatePath = new URL('../../src/Web/index.html', import.meta.url); +const versionPath = new URL( + '../../src/licenses/ba-click-fx/VERSION.txt', + import.meta.url, +); + +test('vendored artifact matches the reviewed v1.2.25 build', () => +{ + const bytes = readFileSync(vendorPath); + const actual = createHash('sha256').update(bytes).digest('hex').toUpperCase(); + + assert.equal(actual, expectedSha256); +}); + +test('vendored metadata identifies the exact reviewed artifact', () => +{ + const metadata = readFileSync(versionPath, 'utf8'); + + assert.match(metadata, /^Version: v1\.2\.25$/m); + assert.match( + metadata, + /^Commit: cbefdb849a96dae8d418547cf8cc90ab230029e3$/m, + ); + assert.match(metadata, new RegExp(`^SHA256: ${expectedSha256}$`, 'm')); +}); + +test('vendored IIFE exposes every host API required by BASpark', () => +{ + const source = readFileSync(vendorPath, 'utf8'); + const context = + { + // 当前 IIFE 在模块初始化时解码内嵌纹理,浏览器会原生提供 atob。 + atob(encoded) + { + return Buffer.from(encoded, 'base64').toString('latin1'); + }, + }; + + vm.runInNewContext(source, context, { filename: 'ba-click-fx.iife.js' }); + + assert.equal(typeof context.BAClickFX.BAClickFX, 'function'); + assert.equal(typeof context.BAClickFX.createConfig, 'function'); + assert.equal(context.BAClickFX.BLOOM_BACKEND_CHANGE_EVENT, 'baclickfxbackendchange'); + assert.equal(context.BAClickFX.EFFECT_BACKEND_CHANGE_EVENT, 'baclickfxeffectbackendchange'); + assert.equal(context.BAClickFX.HOST_COMPOSITING_CHANGE_EVENT, 'baclickfxhostcompositingchange'); + + const lightBackgroundConfig = context.BAClickFX.createConfig( + { + outputCompositing: 'browser-overlay', + overlayAlphaPolicy: 'visual-max', + overlayColorCompensation: 'bright-core', + overlayAlphaLimit: 0.85, + hostCompositing: 'source-over', + hostCompositingSurface: 'transparent-window', + themeColorMode: 'relative-oklch', + inputSamplingRate: 40, + }, + ); + + assert.equal(lightBackgroundConfig.outputCompositing, 'browser-overlay'); + assert.equal(lightBackgroundConfig.overlayAlphaPolicy, 'visual-max'); + assert.equal(lightBackgroundConfig.overlayColorCompensation, 'bright-core'); + assert.equal(lightBackgroundConfig.overlayAlphaLimit, 0.85); + assert.equal(lightBackgroundConfig.hostCompositing, 'source-over'); + assert.equal(lightBackgroundConfig.hostCompositingSurface, 'transparent-window'); + assert.equal(lightBackgroundConfig.themeColorMode, 'relative-oklch'); + assert.equal(lightBackgroundConfig.inputSamplingRate, 40); + + const prototype = context.BAClickFX.BAClickFX.prototype; + for (const method of [ + 'pointerDown', + 'pointerMove', + 'pointerUp', + 'pointerCancel', + 'clearTrail', + 'setPaused', + 'updateConfig', + 'setThemeColor', + 'setThemeColorMode', + 'setInputSamplingRate', + 'destroy', + ]) + { + assert.equal(typeof prototype[method], 'function', `${method} must remain public`); + } +}); + +test('inline resources cannot terminate their script element early', () => +{ + const vendor = readFileSync(vendorPath, 'utf8'); + const adapter = readFileSync(adapterPath, 'utf8'); + + assert.equal(/<\/script/i.test(vendor), false); + assert.equal(/<\/script/i.test(adapter), false); + assert.equal(vendor.includes('sourceMappingURL'), false); +}); + +test('renderer template contains one deterministic injection marker', () => +{ + const template = readFileSync(templatePath, 'utf8'); + const marker = ''; + + assert.equal(template.split(marker).length - 1, 1); +});