diff --git a/docs/Releases.md b/docs/Releases.md index 1201a8fef..ee1189603 100644 --- a/docs/Releases.md +++ b/docs/Releases.md @@ -12,12 +12,12 @@ This page tracks major changes included in any update starting with version 4.0. - Generally moves to CSS 3 variables, for easier custom themes as well ([#451](https://github.com/MiniProfiler/dotnet/pull/451)) - Added `SqlServerFormatter.IncludeParameterValues` for excluding actual values in output if desired ([#463](https://github.com/MiniProfiler/dotnet/pull/463)) - (**.NET Core only**) Added `MiniProfilerOptions.ResultsAuthorizeAsync` and `MiniProfiler.ResultsAuthorizeListAsync` ([#472](https://github.com/MiniProfiler/dotnet/pull/472)) + - (**.NET Core only**) Added profiling to all diagnostic events (views, filters, etc. - [#475](https://github.com/MiniProfiler/dotnet/pull/475)) - **Fixes/Changes**: - Fix for ['i.Started.toUTCString is not a function'](https://github.com/MiniProfiler/dotnet/pull/462) when global serializer options are changed. - Removed jQuery (built-in) dependency ([#442](https://github.com/MiniProfiler/dotnet/pull/442)) - (**Major**) Drops IE 11 support - Fix for missing `IMemoryCache` depending on config ([#440](https://github.com/MiniProfiler/dotnet/pull/440)) - - MySQL Storage: - Updates `MySqlConnector` to 0.60.1 for misc fixes ([#432](https://github.com/MiniProfiler/dotnet/pull/432)) (thanks [@bgrainger](https://github.com/bgrainger)!) - Redis Storage diff --git a/src/MiniProfiler.AspNetCore.Mvc/MvcDiagnosticListener.cs b/src/MiniProfiler.AspNetCore.Mvc/MvcDiagnosticListener.cs new file mode 100644 index 000000000..5c65400a5 --- /dev/null +++ b/src/MiniProfiler.AspNetCore.Mvc/MvcDiagnosticListener.cs @@ -0,0 +1,183 @@ +#if NETCOREAPP3_0 +using Microsoft.AspNetCore.Mvc; +using Microsoft.AspNetCore.Mvc.Abstractions; +using Microsoft.AspNetCore.Mvc.Diagnostics; +using Microsoft.AspNetCore.Mvc.Filters; +using StackExchange.Profiling.Internal; +using System; +using System.Collections.Concurrent; +using System.Collections.Generic; +using System.Diagnostics; +using System.Threading; + +namespace StackExchange.Profiling.Data +{ + /// + /// Diagnostic listener for Microsoft.AspNetCore.Mvc.* events + /// + /// + /// See: + /// - https://github.com/dotnet/aspnetcore/blob/v3.0.0/src/Mvc/Mvc.Core/src/MvcCoreDiagnosticListenerExtensions.cs + /// - https://github.com/dotnet/aspnetcore/blob/v3.0.0/src/Mvc/Mvc.Core/src/Diagnostics/MvcDiagnostics.cs + /// - https://github.com/dotnet/aspnetcore/blob/v3.0.0/src/Mvc/Mvc.Razor/src/Diagnostics/MvcDiagnostics.cs + /// + public class MvcDiagnosticListener : IMiniProfilerDiagnosticListener + { + /// + /// Diagnostic Listener name to handle. + /// + public string ListenerName => "Microsoft.AspNetCore"; + + /// + /// Notifies the observer that the provider has finished sending push-based notifications. + /// + public void OnCompleted() { } + + /// + /// Notifies the observer that the provider has experienced an error condition. + /// + /// An object that provides additional information about the error. + public void OnError(Exception error) => Trace.WriteLine(error); + + // So we don't keep allocating strings for the same actions over and over + private readonly ConcurrentDictionary<(string, string), string> _descriptorNameCache = new ConcurrentDictionary<(string, string), string>(); + + private string GetName(string label, ActionDescriptor descriptor) + { + var key = (label, descriptor.DisplayName); + if (!_descriptorNameCache.TryGetValue(key, out var result)) + { + // For the "Samples.AspNetCore.Controllers.HomeController.Index (Samples.AspNetCore3)" format, + // ...trim off the assembly on the end. + var assemblyNamePos = descriptor.DisplayName.IndexOf(" ("); + if (assemblyNamePos > 0) + { + result = string.Concat(label, ": ", descriptor.DisplayName.AsSpan().Slice(0, assemblyNamePos)); + } + else + { + result = label + ": " + descriptor.DisplayName; + } + _descriptorNameCache[key] = result; + } + return result; + } + + private static string GetName(IActionResult result) => result switch + { + ViewResult vr => vr.ViewName.HasValue() ? "View: " + vr.ViewName : nameof(ViewResult), + ContentResult cr => cr.ContentType.HasValue() ? "Content: " + cr.ContentType : nameof(ContentResult), + ObjectResult or => or.DeclaredType != null ? "Object: " + or.DeclaredType.Name : nameof(ObjectResult), + StatusCodeResult scr => scr.StatusCode > 0 ? "Status Code: " + scr.StatusCode.ToString() : nameof(StatusCodeResult), + JsonResult jr => jr.ContentType.HasValue() ? "JSON: " + jr.ContentType : nameof(JsonResult), + _ => "Result: " + result.GetType().Name + }; + + private static string GetName(IFilterMetadata filter) => filter.GetType().Name; + + /// + /// Stores the current timing in the tree, on each request. + /// + private readonly AsyncLocal<(object State, Timing Timing)> CurrentTiming = new AsyncLocal<(object, Timing)>(); + + private object Start(T state, string stepName) where T : class + { + CurrentTiming.Value = (state, MiniProfiler.Current.Step(stepName)); + return null; + } + + private object Complete(T state) where T : class + { + if (CurrentTiming.Value.State is T currentState && currentState == state) + { + using (CurrentTiming.Value.Timing) { } + } + return null; + } + + /// + /// Provides the observer with new data. + /// + /// The current notification information. + public void OnNext(KeyValuePair kv) => _ = kv.Value switch + { + // MVC Bits: https://github.com/dotnet/aspnetcore/blob/v3.0.0/src/Mvc/Mvc.Core/src/Diagnostics/MvcDiagnostics.cs + // ActionEvent + BeforeActionEventData data => Start(data.ActionDescriptor, GetName("Action", data.ActionDescriptor)), + AfterActionEventData data => Complete(data.ActionDescriptor), + // ControllerActionMethod + BeforeControllerActionMethodEventData data => Start(data.ActionContext.ActionDescriptor, GetName("Controller Action", data.ActionContext.ActionDescriptor)), + AfterControllerActionMethodEventData data => Complete(data.ActionContext.ActionDescriptor), + // ActionResultEvent + BeforeActionResultEventData data => Start(data.Result, GetName(data.Result)), + AfterActionResultEventData data => Complete(data.Result), + + // AuthorizationFilterOnAuthorization + BeforeAuthorizationFilterOnAuthorizationEventData data => Start(data.Filter, "Auth Filter: " + GetName(data.Filter)), + AfterAuthorizationFilterOnAuthorizationEventData data => Complete(data.Filter), + + // ResourceFilterOnResourceExecution + BeforeResourceFilterOnResourceExecutionEventData data => Start(data.Filter, "Resource Filter (Exec): " + GetName(data.Filter)), + AfterResourceFilterOnResourceExecutionEventData data => Complete(data.Filter), + // ResourceFilterOnResourceExecuting + BeforeResourceFilterOnResourceExecutingEventData data => Start(data.Filter, "Resource Filter (Execing): " + GetName(data.Filter)), + AfterResourceFilterOnResourceExecutingEventData data => Complete(data.Filter), + // ResourceFilterOnResourceExecuted + BeforeResourceFilterOnResourceExecutedEventData data => Start(data.Filter, "Resource Filter (Execed): " + GetName(data.Filter)), + AfterResourceFilterOnResourceExecutedEventData data => Complete(data.Filter), + + // ExceptionFilterOnException + BeforeExceptionFilterOnException data => Start(data.Filter, "Exception Filter: " + GetName(data.Filter)), + AfterExceptionFilterOnExceptionEventData data => Complete(data.Filter), + + // ActionFilterOnActionExecution + BeforeActionFilterOnActionExecutionEventData data => Start(data.Filter, "Action Filter (Exec): " + GetName(data.Filter)), + AfterActionFilterOnActionExecutionEventData data => Complete(data.Filter), + // ActionFilterOnActionExecuting + BeforeActionFilterOnActionExecutingEventData data => Start(data.Filter, "Action Filter (Execing): " + GetName(data.Filter)), + AfterActionFilterOnActionExecutingEventData data => Complete(data.Filter), + // ActionFilterOnActionExecuted + BeforeActionFilterOnActionExecutedEventData data => Start(data.Filter, "Action Filter (Execed): " + GetName(data.Filter)), + AfterActionFilterOnActionExecutedEventData data => Complete(data.Filter), + + // ResultFilterOnResultExecution + BeforeResultFilterOnResultExecutionEventData data => Start(data.Filter, "Result Filter (Exec): " + GetName(data.Filter)), + AfterResultFilterOnResultExecutionEventData data => Complete(data.Filter), + // ResultFilterOnResultExecuting + BeforeResultFilterOnResultExecutingEventData data => Start(data.Filter, "Result Filter (Execing): " + GetName(data.Filter)), + AfterResultFilterOnResultExecutingEventData data => Complete(data.Filter), + // ResultFilterOnResultExecuted + BeforeResultFilterOnResultExecutedEventData data => Start(data.Filter, "Result Filter (Execed): " + GetName(data.Filter)), + AfterResultFilterOnResultExecutedEventData data => Complete(data.Filter), + + // Razor Bits: https://github.com/dotnet/aspnetcore/blob/v3.0.0/src/Mvc/Mvc.Razor/src/Diagnostics/MvcDiagnostics.cs + // ViewPage + BeforeViewPageEventData data => Start(data.Page, "View: " + data.Page.Path), + AfterViewPageEventData data => Complete(data.Page), + + // RazorPage Bits: https://github.com/dotnet/aspnetcore/blob/v3.0.0/src/Mvc/Mvc.RazorPages/src/Diagnostics/MvcDiagnostics.cs + // HandlerMethod + BeforeHandlerMethodEventData data => Start(data.Instance, "Handler: " + data.HandlerMethodDescriptor.Name), + AfterHandlerMethodEventData data => Complete(data.Instance), + + // PageFilterOnPageHandlerExecution + BeforePageFilterOnPageHandlerExecutionEventData data => Start(data.Filter, "Filter (Exec): " + GetName(data.Filter)), + AfterPageFilterOnPageHandlerExecutionEventData data => Complete(data.Filter), + // PageFilterOnPageHandlerExecuting + BeforePageFilterOnPageHandlerExecutingEventData data => Start(data.Filter, "Filter (Execing): " + GetName(data.Filter)), + AfterPageFilterOnPageHandlerExecutingEventData data => Complete(data.Filter), + // PageFilterOnPageHandlerExecuted + BeforePageFilterOnPageHandlerExecutedEventData data => Start(data.Filter, "Filter (Execed): " + GetName(data.Filter)), + AfterPageFilterOnPageHandlerExecutedEventData data => Complete(data.Filter), + + // PageFilterOnPageHandlerSelection + BeforePageFilterOnPageHandlerSelectionEventData data => Start(data.Filter, "Filter (Selection): " + GetName(data.Filter)), + AfterPageFilterOnPageHandlerSelectionEventData data => Complete(data.Filter), + // PageFilterOnPageHandlerSelected + BeforePageFilterOnPageHandlerSelectedEventData data => Start(data.Filter, "Filter (Selected): " + GetName(data.Filter)), + AfterPageFilterOnPageHandlerSelectedEventData data => Complete(data.Filter), + _ => null + }; + } +} +#endif diff --git a/src/MiniProfiler.AspNetCore.Mvc/MvcExtensions.cs b/src/MiniProfiler.AspNetCore.Mvc/MvcExtensions.cs index 1f2e888a9..c71f98472 100644 --- a/src/MiniProfiler.AspNetCore.Mvc/MvcExtensions.cs +++ b/src/MiniProfiler.AspNetCore.Mvc/MvcExtensions.cs @@ -1,12 +1,17 @@ -using Microsoft.AspNetCore.Mvc; -using Microsoft.AspNetCore.Mvc.ViewComponents; -using Microsoft.Extensions.Caching.Memory; +using Microsoft.Extensions.Caching.Memory; using Microsoft.Extensions.Options; using StackExchange.Profiling; using StackExchange.Profiling.Internal; using StackExchange.Profiling.Storage; using System; +#if NETCOREAPP3_0 +using StackExchange.Profiling.Data; +#else +using Microsoft.AspNetCore.Mvc; +using Microsoft.AspNetCore.Mvc.ViewComponents; +#endif + namespace Microsoft.Extensions.DependencyInjection { /// @@ -23,22 +28,22 @@ public static IMiniProfilerBuilder AddMiniProfiler(this IServiceCollection servi { services.AddMemoryCache(); // Unconditionally register an IMemoryCache since it's the most common and default case services.AddSingleton, MiniProfilerOptionsDefaults>(); - services.AddSingleton(); // For any IMiniProfilerDiagnosticListener registration if (configureOptions != null) { services.Configure(configureOptions); } // Set background statics services.Configure(o => MiniProfiler.Configure(o)); + services.AddSingleton(); // For any IMiniProfilerDiagnosticListener registration - // See https://github.com/MiniProfiler/dotnet/issues/162 for plans - // Blocked on https://github.com/aspnet/Mvc/issues/6222 - //services.AddSingleton(); +#if NETCOREAPP3_0 + services.AddSingleton(); // For view and action profiling +#else services.AddTransient, MiniProfilerSetup>() - .AddTransient, MiniProfilerSetup>(); -#if !NETCOREAPP3_0 - services.AddTransient(); + .AddTransient, MiniProfilerSetup>() + .AddTransient(); #endif + return new MiniProfilerBuilder(services); } } @@ -60,6 +65,7 @@ public void Configure(MiniProfilerOptions options) } } +#if !NETCOREAPP3_0 internal class MiniProfilerSetup : IConfigureOptions, IConfigureOptions { public void Configure(MvcViewOptions options) @@ -75,4 +81,5 @@ public void Configure(MvcOptions options) options.Filters.Add(new ProfilingActionFilter()); } } +#endif } diff --git a/src/MiniProfiler.Shared/ui/includes.css b/src/MiniProfiler.Shared/ui/includes.css index a349710d6..94ccc034e 100644 --- a/src/MiniProfiler.Shared/ui/includes.css +++ b/src/MiniProfiler.Shared/ui/includes.css @@ -650,7 +650,10 @@ padding-bottom: 3px; } .mp-results .mp-popup .mp-timings .mp-label { - max-width: 275px; + max-width: 350px; + text-overflow: ellipsis; + white-space: nowrap; + overflow: hidden; } .mp-results .mp-queries { display: none; diff --git a/src/MiniProfiler.Shared/ui/includes.less b/src/MiniProfiler.Shared/ui/includes.less index ad25cb60e..dc08ef70b 100644 --- a/src/MiniProfiler.Shared/ui/includes.less +++ b/src/MiniProfiler.Shared/ui/includes.less @@ -724,7 +724,10 @@ } .mp-label { - max-width: 275px; + max-width: 350px; + text-overflow: ellipsis; + white-space: nowrap; + overflow: hidden; } } } diff --git a/src/MiniProfiler.Shared/ui/includes.min.css b/src/MiniProfiler.Shared/ui/includes.min.css index 0edfc8279..4853ccd58 100644 --- a/src/MiniProfiler.Shared/ui/includes.min.css +++ b/src/MiniProfiler.Shared/ui/includes.min.css @@ -1 +1 @@ -:root{--mp-main-bg-color:#fff;--mp-button-active-bg-color:#207ab7;--mp-button-active-text-color:#fff;--mp-button-warning-bg-color:#c91d2e;--mp-button-warning-text-color:#fff;--mp-duration-color:#111;--mp-warning-color:#c91d2e;--mp-critical-color:#f00;--mp-alt-row-color:#f5f5f5;--mp-muted-color:#aaa;--mp-link-color:#07c;--mp-label-color:#555;--mp-gap-font-color:#444;--mp-gap-bg-color:#e1e5ed;--mp-overlay-bg-color:#000;--mp-shadow-color:#555;--mp-info-border-color:#ddd;--mp-query-border-color:#efefef;--mp-timing-unknown-color:#80ccda;--mp-timing-dns-color:#8baad1;--mp-timing-connect-color:#8cbb4e;--mp-timing-ssl-color:#795892;--mp-timing-request-color:#0099b2;--mp-timing-response-color:#d99d35;--mp-timing-dom-color:#bd4d32;--mp-timing-domcontent-color:#dd4678;--mp-timing-load-color:#1d72aa;--mp-timing-paint-color:#bc41e3;--mp-highlight-fade-color:#ffb;--mp-highlight-default-color:#000;--mp-highlight-string-color:#756bb1;--mp-highlight-comment-color:#636363;--mp-highlight-literal-color:#31a354;--mp-highlight-variable-color:#88f;--mp-highlight-keyword-color:#3182bd;--mp-highlight-attribute-color:#e6550d;--mp-result-border:solid .5px #ababab;--mp-result-border-radius:10px;}@media(prefers-color-scheme:dark){.mp-scheme-auto{--mp-main-bg-color:#222;--mp-duration-color:#eee;--mp-alt-row-color:#333;--mp-muted-color:#888;--mp-label-color:#ccc;--mp-gap-font-color:#d6d6d6;--mp-gap-bg-color:#424448;--mp-link-color:#4db5ff;--mp-query-border-color:#575757;--mp-highlight-fade-color:#884;--mp-highlight-default-color:#eee;--mp-highlight-literal-color:#3fca6a;--mp-highlight-keyword-color:#36a1ef;--mp-result-border:solid .5px #575757;}.mp-scheme-auto body{background-color:var(--mp-main-bg-color);}}.mp-scheme-dark{--mp-main-bg-color:#222;--mp-duration-color:#eee;--mp-alt-row-color:#333;--mp-muted-color:#888;--mp-label-color:#ccc;--mp-gap-font-color:#d6d6d6;--mp-gap-bg-color:#424448;--mp-link-color:#4db5ff;--mp-query-border-color:#575757;--mp-highlight-fade-color:#884;--mp-highlight-default-color:#eee;--mp-highlight-literal-color:#3fca6a;--mp-highlight-keyword-color:#36a1ef;--mp-result-border:solid .5px #575757;}.mp-scheme-dark body{background-color:var(--mp-main-bg-color);}.mp-result,.mp-queries{color:var(--mp-label-color);line-height:1;font-size:12px;}.mp-result pre,.mp-queries pre,.mp-result code,.mp-queries code,.mp-result label,.mp-queries label,.mp-result table,.mp-queries table,.mp-result tbody,.mp-queries tbody,.mp-result thead,.mp-queries thead,.mp-result tfoot,.mp-queries tfoot,.mp-result tr,.mp-queries tr,.mp-result th,.mp-queries th,.mp-result td,.mp-queries td{margin:0;padding:0;border:0;font-size:100%;font:inherit;vertical-align:baseline;background-color:transparent;overflow:visible;max-height:none;}.mp-result pre,.mp-queries pre,.mp-result code,.mp-queries code{font-family:Fira Code,Consolas,monospace,serif;font-variant-ligatures:none;}.mp-result table,.mp-queries table{color:var(--mp-label-color);border-collapse:collapse;border-spacing:0;width:100%;}.mp-result a,.mp-queries a{cursor:pointer;color:var(--mp-link-color);text-decoration:none;}.mp-result a:hover,.mp-queries a:hover{text-decoration:underline;}.mp-result{font-family:sans-serif;}.mp-result.show-columns th.mp-more-columns,.mp-result.show-columns td.mp-more-columns{display:table-cell !important;}.mp-result.show-columns a.mp-more-columns{display:inline-block;}.mp-result.show-columns .mp-links span a:nth-child(1){display:none;}.mp-result.show-trivial tr.mp-trivial{display:table-row !important;}.mp-result.show-trivial a.mp-trivial{display:inline-block;}.mp-result.show-trivial .mp-links span a:nth-child(3){display:none;}.mp-result table.mp-client-timings{margin-top:10px;}.mp-result table.mp-client-timings td:nth-child(2){width:100%;padding:0;}.mp-result table.mp-client-timings td div{height:13px;min-width:1px;}.mp-result table.mp-client-timings .t-point div{height:4px;border-radius:8px;margin-bottom:4px;box-shadow:0 0 2px;}.mp-result table.mp-client-timings .t-unknown div{background:var(--mp-timing-unknown-color);}.mp-result table.mp-client-timings .t-dns div{background:var(--mp-timing-dns-color);}.mp-result table.mp-client-timings .t-connect div{background:var(--mp-timing-connect-color);}.mp-result table.mp-client-timings .t-ssl div{background:var(--mp-timing-ssl-color);}.mp-result table.mp-client-timings .t-request div{background:var(--mp-timing-request-color);}.mp-result table.mp-client-timings .t-response div{background:var(--mp-timing-response-color);}.mp-result table.mp-client-timings .t-dom div{background:var(--mp-timing-dom-color);}.mp-result table.mp-client-timings .t-domcontent div{background:var(--mp-timing-domcontent-color);}.mp-result table.mp-client-timings .t-load div{background:var(--mp-timing-load-color);}.mp-result table.mp-client-timings .t-paint div{background:var(--mp-timing-paint-color);}.mp-result .mp-label{color:var(--mp-label-color);overflow:hidden;text-overflow:ellipsis;}.mp-result .mp-unit{color:var(--mp-muted-color);}.mp-result .mp-more-columns{display:none;}.mp-result .mp-trivial{display:none;}.mp-result .mp-trivial td,.mp-result .mp-trivial td *{color:var(--mp-muted-color) !important;}.mp-result .mp-number{color:var(--mp-duration-color);}.mp-result .mp-info>div{white-space:nowrap;overflow:hidden;}.mp-result .mp-info>div>div{display:inline-block;}.mp-result .mp-info .mp-name{display:inline-block;font-weight:bold;float:left;}.mp-result .mp-info .mp-machine-name,.mp-result .mp-info .mp-started{text-align:right;float:right;}.mp-result .mp-info .mp-server-time{white-space:nowrap;}.mp-result .mp-timings th{background-color:var(--mp-main-bg-color);color:var(--mp-muted-color);text-align:right;}.mp-result .mp-timings th,.mp-result .mp-timings td{white-space:nowrap;}.mp-result .mp-timings .mp-show-more{display:none;}.mp-result .mp-timings .mp-duration{font-family:Consolas,monospace,serif;color:var(--mp-duration-color);text-align:right;}.mp-result .mp-timings .mp-indent{letter-spacing:4px;}.mp-result .mp-timings .mp-queries-show .mp-number,.mp-result .mp-timings .mp-queries-show .mp-unit{color:var(--mp-link-color);}.mp-result .mp-timings .mp-queries-show.mp-queries-warning{color:var(--mp-warning-color);font-weight:bold;}.mp-result .mp-timings .mp-queries-duration{padding-left:6px;}.mp-result .mp-timings:not(.mp-client-timings) .mp-trivial:first-child{display:table-row;}.mp-result .mp-custom-timing-overview{float:right;margin:10px 0;width:auto;}.mp-result .mp-custom-timing-overview td{white-space:nowrap;text-align:right;}.mp-result .mp-custom-timing-overview td:last-child{padding-left:8px;}.mp-result .mp-links{margin-top:10px;clear:both;}.mp-result .mp-links span{float:right;}.mp-result .mp-links a{font-size:95%;margin-left:12px;}.mp-result .mp-links a:first-child{margin-left:0;}.mp-warning{color:var(--mp-critical-color);}@keyframes mp-fadeIn{from{background-color:var(--mp-highlight-fade-color);}to{background-color:none;}}.mp-overlay{z-index:2147483642;}.mp-overlay .mp-overlay-bg{z-index:2147483643;background:var(--mp-overlay-bg-color);opacity:.5;top:0;left:0;min-width:100%;position:fixed;height:calc(100%);}.mp-overlay .mp-queries{display:block;z-index:2147483644;top:25px;left:25px;right:25px;position:fixed;max-height:calc(100vh - 50px);background-color:var(--mp-main-bg-color);border-radius:2px;overflow-y:auto;overflow-x:auto;}.mp-queries{font-family:sans-serif;}.mp-queries pre{white-space:pre-wrap;}.mp-queries div{text-align:left;}.mp-queries table{table-layout:fixed;}.mp-queries td,.mp-queries th{padding:8px;border-bottom:solid 1px var(--mp-query-border-color);}.mp-queries td:first-child,.mp-queries th:first-child{width:250px;text-align:right;}.mp-queries td:first-child div,.mp-queries th:first-child div{text-align:right;margin-bottom:5px;word-break:break-word;}.mp-queries td:last-child,.mp-queries th:last-child{text-align:left;padding-right:15px;}.mp-queries .highlight{animation:mp-fadeIn 2s 1;}.mp-queries .mp-odd{background-color:var(--mp-alt-row-color);}.mp-queries .mp-stack-trace{padding-bottom:1px;color:var(--mp-muted-color);margin-bottom:5px;}.mp-queries .mp-since-start,.mp-queries .mp-duration{text-align:right;}.mp-queries.show-trivial .mp-gap-info.mp-trivial-gap{display:table-row;}.mp-queries .mp-gap-info{background-color:var(--mp-gap-bg-color);opacity:.8;color:var(--mp-gap-font-color);}.mp-queries .mp-gap-info .query{word-break:break-all;}.mp-queries .mp-gap-info .mp-unit{color:var(--mp-muted-color);}.mp-queries .mp-gap-info.mp-trivial-gap{display:none;}.mp-queries .mp-trivial-gap-container{text-align:center;margin:8px 0;}.mp-queries .mp-call-type{font-weight:bold;}.mp-queries .hljs{display:block;overflow-x:auto;padding:.5em;}.mp-queries .hljs,.mp-queries .hljs-subst{color:var(--mp-highlight-default-color);}.mp-queries .hljs-string,.mp-queries .hljs-meta,.mp-queries .hljs-symbol,.mp-queries .hljs-template-tag,.mp-queries .hljs-template-variable,.mp-queries .hljs-addition{color:var(--mp-highlight-string-color);}.mp-queries .hljs-comment,.mp-queries .hljs-quote{color:var(--mp-highlight-comment-color);}.mp-queries .hljs-number,.mp-queries .hljs-regexp,.mp-queries .hljs-literal,.mp-queries .hljs-bullet,.mp-queries .hljs-link{color:var(--mp-highlight-literal-color);}.mp-queries .hljs-deletion,.mp-queries .hljs-variable{color:var(--mp-highlight-variable-color);}.mp-queries .hljs-keyword,.mp-queries .hljs-selector-tag,.mp-queries .hljs-title,.mp-queries .hljs-section,.mp-queries .hljs-built_in,.mp-queries .hljs-doctag,.mp-queries .hljs-type,.mp-queries .hljs-tag,.mp-queries .hljs-name,.mp-queries .hljs-selector-id,.mp-queries .hljs-selector-class,.mp-queries .hljs-strong{color:var(--mp-highlight-keyword-color);}.mp-queries .hljs-emphasis{font-style:italic;}.mp-queries .hljs-attribute{color:var(--mp-highlight-attribute-color);}.mp-results{z-index:2147483641;position:fixed;top:0;}.mp-results.mp-left,.mp-results.mp-bottomleft{left:0;}.mp-results.mp-left .mp-controls,.mp-results.mp-left.mp-no-controls .mp-result:last-child .mp-button{border-bottom-right-radius:var(--mp-result-border-radius);}.mp-results.mp-left .mp-button,.mp-results.mp-left .mp-controls{border-right:var(--mp-result-border);}.mp-results.mp-right{right:0;}.mp-results.mp-right .mp-controls,.mp-results.mp-right.mp-no-controls .mp-result:last-child .mp-button{border-bottom-left-radius:var(--mp-result-border-radius);}.mp-results.mp-right .mp-button,.mp-results.mp-right .mp-controls{border-left:var(--mp-result-border);}.mp-results.mp-bottomleft{top:inherit;bottom:0;}.mp-results.mp-bottomleft .mp-result:first-child .mp-button{border-top-right-radius:var(--mp-result-border-radius);}.mp-results.mp-bottomleft .mp-button,.mp-results.mp-bottomleft .mp-controls{border-right:var(--mp-result-border);}.mp-results.mp-bottomleft .mp-result .mp-button,.mp-results.mp-bottomleft .mp-controls{border-bottom:0;border-top:var(--mp-result-border);}.mp-results.mp-bottomright{top:inherit;bottom:0;right:0;}.mp-results.mp-bottomright .mp-result:first-child .mp-button{border-top-left-radius:var(--mp-result-border-radius);}.mp-results.mp-bottomright .mp-button,.mp-results.mp-bottomright .mp-controls{border-left:var(--mp-result-border);}.mp-results.mp-bottomright .mp-result .mp-button,.mp-results.mp-bottomright .mp-controls{border-bottom:0;border-top:var(--mp-result-border);}.mp-results .mp-button{user-select:none;}.mp-results .mp-button.mp-button-warning{font-weight:bold;background-color:var(--mp-button-warning-bg-color);color:var(--mp-button-warning-text-color);}.mp-results .mp-button.mp-button-warning .mp-number,.mp-results .mp-button.mp-button-warning .mp-unit,.mp-results .mp-button.mp-button-warning .mp-warning{color:var(--mp-button-warning-text-color);}.mp-results .mp-button .mp-warning{font-weight:bold;}.mp-results .mp-button>.mp-number{font-family:Consolas,monospace,serif;}.mp-results .mp-controls{display:none;}.mp-results .mp-button,.mp-results .mp-controls{z-index:2147483640;border-bottom:var(--mp-result-border);background-color:var(--mp-main-bg-color);padding:4px 8px;text-align:right;cursor:pointer;}.mp-results .mp-result{position:relative;}.mp-results .mp-result.active .mp-button{background-color:var(--mp-button-active-bg-color);animation:none;border-radius:0 !important;}.mp-results .mp-result.active .mp-button.mp-button-warning{background-color:var(--mp-button-warning-bg-color);}.mp-results .mp-result.active .mp-button .mp-number,.mp-results .mp-result.active .mp-button .mp-warning{color:var(--mp-button-active-text-color);font-weight:bold;}.mp-results .mp-result.active .mp-button .mp-unit{color:var(--mp-button-active-text-color);font-weight:normal;}.mp-results .mp-result.active .mp-popup{display:block;}.mp-results.new .mp-button{animation:mp-fadeIn 2s 1;}.mp-results .mp-controls{display:block;font-size:12px;font-family:Consolas,monospace,serif;cursor:default;text-align:center;}.mp-results .mp-controls span{border-right:1px solid var(--mp-muted-color);padding-right:5px;margin-right:5px;cursor:pointer;}.mp-results .mp-controls span:last-child{border-right:none;}.mp-results .mp-popup{display:none;z-index:2147483641;position:absolute;background-color:var(--mp-main-bg-color);padding:5px 10px;text-align:left;line-height:18px;overflow:auto;box-shadow:0 1px 10px var(--mp-shadow-color);border-radius:2px;}.mp-results .mp-popup .mp-info{margin-bottom:3px;padding-bottom:2px;border-bottom:1px solid var(--mp-info-border-color);}.mp-results .mp-popup .mp-info .mp-name{font-size:1.1em;}.mp-results .mp-popup .mp-info .mp-overall-duration{color:var(--mp-muted-color);}.mp-results .mp-popup .mp-timings th,.mp-results .mp-popup .mp-timings td{padding:0 6px;}.mp-results .mp-popup .mp-timings th{font-size:95%;padding-bottom:3px;}.mp-results .mp-popup .mp-timings .mp-label{max-width:275px;}.mp-results .mp-queries{display:none;}.mp-results.mp-min .mp-result{display:none;}.mp-results.mp-min .mp-controls span{display:none;}.mp-results.mp-min .mp-controls .mp-min-max{border-right:none;padding:0;margin:0;}.mp-result-full .mp-result{width:950px;margin:25px auto;}.mp-result-full .mp-result .mp-button{display:none;}.mp-result-full .mp-result .mp-popup .mp-info{font-size:18px;border-bottom:1px solid var(--mp-muted-color);padding-bottom:3px;margin-bottom:10px;}.mp-result-full .mp-result .mp-popup .mp-info .mp-name{margin-bottom:5px;}.mp-result-full .mp-result .mp-popup .mp-info .mp-overall-duration,.mp-result-full .mp-result .mp-popup .mp-info .mp-started{font-size:80%;color:var(--mp-muted-color);}.mp-result-full .mp-result .mp-popup .mp-info .mp-overall-duration{padding-right:20px;}.mp-result-full .mp-result .mp-popup .mp-timings td,.mp-result-full .mp-result .mp-popup .mp-timings th{font-size:13px;padding-left:8px;padding-right:8px;}.mp-result-full .mp-result .mp-popup .mp-timings th{padding-bottom:7px;}.mp-result-full .mp-result .mp-popup .mp-timings td{padding-bottom:4px;}.mp-result-full .mp-result .mp-popup .mp-timings td:first-child{padding-left:10px;}.mp-result-full .mp-result .mp-popup .mp-timings .mp-label{max-width:550px;}.mp-result-full .mp-result .mp-queries{margin:20px 0;}.mp-result-full .mp-result .mp-queries th{font-size:16px;}.mp-result-full .mp-share-mp-results{display:none;}table.mp-results-index{border:0;border-spacing:0;font-size:12px;font-family:Arial;}table.mp-results-index a{color:var(--mp-link-color);text-decoration:none;}table.mp-results-index tbody{color:var(--mp-label-color);}table.mp-results-index tbody tr:nth-child(odd){background-color:var(--mp-alt-row-color);}table.mp-results-index tbody tr:nth-child(even){background-color:var(--mp-main-bg-color);}table.mp-results-index tbody td{text-align:center;}table.mp-results-index tbody td:first-child{text-align:left;}table.mp-results-index tbody td[colspan="3"]{color:var(--mp-muted-color);}table.mp-results-index thead tr{color:var(--mp-label-color);}table.mp-results-index thead tr th{padding:5px 15px;}table.mp-results-index td{padding:8px;} \ No newline at end of file +:root{--mp-main-bg-color:#fff;--mp-button-active-bg-color:#207ab7;--mp-button-active-text-color:#fff;--mp-button-warning-bg-color:#c91d2e;--mp-button-warning-text-color:#fff;--mp-duration-color:#111;--mp-warning-color:#c91d2e;--mp-critical-color:#f00;--mp-alt-row-color:#f5f5f5;--mp-muted-color:#aaa;--mp-link-color:#07c;--mp-label-color:#555;--mp-gap-font-color:#444;--mp-gap-bg-color:#e1e5ed;--mp-overlay-bg-color:#000;--mp-shadow-color:#555;--mp-info-border-color:#ddd;--mp-query-border-color:#efefef;--mp-timing-unknown-color:#80ccda;--mp-timing-dns-color:#8baad1;--mp-timing-connect-color:#8cbb4e;--mp-timing-ssl-color:#795892;--mp-timing-request-color:#0099b2;--mp-timing-response-color:#d99d35;--mp-timing-dom-color:#bd4d32;--mp-timing-domcontent-color:#dd4678;--mp-timing-load-color:#1d72aa;--mp-timing-paint-color:#bc41e3;--mp-highlight-fade-color:#ffb;--mp-highlight-default-color:#000;--mp-highlight-string-color:#756bb1;--mp-highlight-comment-color:#636363;--mp-highlight-literal-color:#31a354;--mp-highlight-variable-color:#88f;--mp-highlight-keyword-color:#3182bd;--mp-highlight-attribute-color:#e6550d;--mp-result-border:solid .5px #ababab;--mp-result-border-radius:10px;}@media(prefers-color-scheme:dark){.mp-scheme-auto{--mp-main-bg-color:#222;--mp-duration-color:#eee;--mp-alt-row-color:#333;--mp-muted-color:#888;--mp-label-color:#ccc;--mp-gap-font-color:#d6d6d6;--mp-gap-bg-color:#424448;--mp-link-color:#4db5ff;--mp-query-border-color:#575757;--mp-highlight-fade-color:#884;--mp-highlight-default-color:#eee;--mp-highlight-literal-color:#3fca6a;--mp-highlight-keyword-color:#36a1ef;--mp-result-border:solid .5px #575757;}.mp-scheme-auto body{background-color:var(--mp-main-bg-color);}}.mp-scheme-dark{--mp-main-bg-color:#222;--mp-duration-color:#eee;--mp-alt-row-color:#333;--mp-muted-color:#888;--mp-label-color:#ccc;--mp-gap-font-color:#d6d6d6;--mp-gap-bg-color:#424448;--mp-link-color:#4db5ff;--mp-query-border-color:#575757;--mp-highlight-fade-color:#884;--mp-highlight-default-color:#eee;--mp-highlight-literal-color:#3fca6a;--mp-highlight-keyword-color:#36a1ef;--mp-result-border:solid .5px #575757;}.mp-scheme-dark body{background-color:var(--mp-main-bg-color);}.mp-result,.mp-queries{color:var(--mp-label-color);line-height:1;font-size:12px;}.mp-result pre,.mp-queries pre,.mp-result code,.mp-queries code,.mp-result label,.mp-queries label,.mp-result table,.mp-queries table,.mp-result tbody,.mp-queries tbody,.mp-result thead,.mp-queries thead,.mp-result tfoot,.mp-queries tfoot,.mp-result tr,.mp-queries tr,.mp-result th,.mp-queries th,.mp-result td,.mp-queries td{margin:0;padding:0;border:0;font-size:100%;font:inherit;vertical-align:baseline;background-color:transparent;overflow:visible;max-height:none;}.mp-result pre,.mp-queries pre,.mp-result code,.mp-queries code{font-family:Fira Code,Consolas,monospace,serif;font-variant-ligatures:none;}.mp-result table,.mp-queries table{color:var(--mp-label-color);border-collapse:collapse;border-spacing:0;width:100%;}.mp-result a,.mp-queries a{cursor:pointer;color:var(--mp-link-color);text-decoration:none;}.mp-result a:hover,.mp-queries a:hover{text-decoration:underline;}.mp-result{font-family:sans-serif;}.mp-result.show-columns th.mp-more-columns,.mp-result.show-columns td.mp-more-columns{display:table-cell !important;}.mp-result.show-columns a.mp-more-columns{display:inline-block;}.mp-result.show-columns .mp-links span a:nth-child(1){display:none;}.mp-result.show-trivial tr.mp-trivial{display:table-row !important;}.mp-result.show-trivial a.mp-trivial{display:inline-block;}.mp-result.show-trivial .mp-links span a:nth-child(3){display:none;}.mp-result table.mp-client-timings{margin-top:10px;}.mp-result table.mp-client-timings td:nth-child(2){width:100%;padding:0;}.mp-result table.mp-client-timings td div{height:13px;min-width:1px;}.mp-result table.mp-client-timings .t-point div{height:4px;border-radius:8px;margin-bottom:4px;box-shadow:0 0 2px;}.mp-result table.mp-client-timings .t-unknown div{background:var(--mp-timing-unknown-color);}.mp-result table.mp-client-timings .t-dns div{background:var(--mp-timing-dns-color);}.mp-result table.mp-client-timings .t-connect div{background:var(--mp-timing-connect-color);}.mp-result table.mp-client-timings .t-ssl div{background:var(--mp-timing-ssl-color);}.mp-result table.mp-client-timings .t-request div{background:var(--mp-timing-request-color);}.mp-result table.mp-client-timings .t-response div{background:var(--mp-timing-response-color);}.mp-result table.mp-client-timings .t-dom div{background:var(--mp-timing-dom-color);}.mp-result table.mp-client-timings .t-domcontent div{background:var(--mp-timing-domcontent-color);}.mp-result table.mp-client-timings .t-load div{background:var(--mp-timing-load-color);}.mp-result table.mp-client-timings .t-paint div{background:var(--mp-timing-paint-color);}.mp-result .mp-label{color:var(--mp-label-color);overflow:hidden;text-overflow:ellipsis;}.mp-result .mp-unit{color:var(--mp-muted-color);}.mp-result .mp-more-columns{display:none;}.mp-result .mp-trivial{display:none;}.mp-result .mp-trivial td,.mp-result .mp-trivial td *{color:var(--mp-muted-color) !important;}.mp-result .mp-number{color:var(--mp-duration-color);}.mp-result .mp-info>div{white-space:nowrap;overflow:hidden;}.mp-result .mp-info>div>div{display:inline-block;}.mp-result .mp-info .mp-name{display:inline-block;font-weight:bold;float:left;}.mp-result .mp-info .mp-machine-name,.mp-result .mp-info .mp-started{text-align:right;float:right;}.mp-result .mp-info .mp-server-time{white-space:nowrap;}.mp-result .mp-timings th{background-color:var(--mp-main-bg-color);color:var(--mp-muted-color);text-align:right;}.mp-result .mp-timings th,.mp-result .mp-timings td{white-space:nowrap;}.mp-result .mp-timings .mp-show-more{display:none;}.mp-result .mp-timings .mp-duration{font-family:Consolas,monospace,serif;color:var(--mp-duration-color);text-align:right;}.mp-result .mp-timings .mp-indent{letter-spacing:4px;}.mp-result .mp-timings .mp-queries-show .mp-number,.mp-result .mp-timings .mp-queries-show .mp-unit{color:var(--mp-link-color);}.mp-result .mp-timings .mp-queries-show.mp-queries-warning{color:var(--mp-warning-color);font-weight:bold;}.mp-result .mp-timings .mp-queries-duration{padding-left:6px;}.mp-result .mp-timings:not(.mp-client-timings) .mp-trivial:first-child{display:table-row;}.mp-result .mp-custom-timing-overview{float:right;margin:10px 0;width:auto;}.mp-result .mp-custom-timing-overview td{white-space:nowrap;text-align:right;}.mp-result .mp-custom-timing-overview td:last-child{padding-left:8px;}.mp-result .mp-links{margin-top:10px;clear:both;}.mp-result .mp-links span{float:right;}.mp-result .mp-links a{font-size:95%;margin-left:12px;}.mp-result .mp-links a:first-child{margin-left:0;}.mp-warning{color:var(--mp-critical-color);}@keyframes mp-fadeIn{from{background-color:var(--mp-highlight-fade-color);}to{background-color:none;}}.mp-overlay{z-index:2147483642;}.mp-overlay .mp-overlay-bg{z-index:2147483643;background:var(--mp-overlay-bg-color);opacity:.5;top:0;left:0;min-width:100%;position:fixed;height:calc(100%);}.mp-overlay .mp-queries{display:block;z-index:2147483644;top:25px;left:25px;right:25px;position:fixed;max-height:calc(100vh - 50px);background-color:var(--mp-main-bg-color);border-radius:2px;overflow-y:auto;overflow-x:auto;}.mp-queries{font-family:sans-serif;}.mp-queries pre{white-space:pre-wrap;}.mp-queries div{text-align:left;}.mp-queries table{table-layout:fixed;}.mp-queries td,.mp-queries th{padding:8px;border-bottom:solid 1px var(--mp-query-border-color);}.mp-queries td:first-child,.mp-queries th:first-child{width:250px;text-align:right;}.mp-queries td:first-child div,.mp-queries th:first-child div{text-align:right;margin-bottom:5px;word-break:break-word;}.mp-queries td:last-child,.mp-queries th:last-child{text-align:left;padding-right:15px;}.mp-queries .highlight{animation:mp-fadeIn 2s 1;}.mp-queries .mp-odd{background-color:var(--mp-alt-row-color);}.mp-queries .mp-stack-trace{padding-bottom:1px;color:var(--mp-muted-color);margin-bottom:5px;}.mp-queries .mp-since-start,.mp-queries .mp-duration{text-align:right;}.mp-queries.show-trivial .mp-gap-info.mp-trivial-gap{display:table-row;}.mp-queries .mp-gap-info{background-color:var(--mp-gap-bg-color);opacity:.8;color:var(--mp-gap-font-color);}.mp-queries .mp-gap-info .query{word-break:break-all;}.mp-queries .mp-gap-info .mp-unit{color:var(--mp-muted-color);}.mp-queries .mp-gap-info.mp-trivial-gap{display:none;}.mp-queries .mp-trivial-gap-container{text-align:center;margin:8px 0;}.mp-queries .mp-call-type{font-weight:bold;}.mp-queries .hljs{display:block;overflow-x:auto;padding:.5em;}.mp-queries .hljs,.mp-queries .hljs-subst{color:var(--mp-highlight-default-color);}.mp-queries .hljs-string,.mp-queries .hljs-meta,.mp-queries .hljs-symbol,.mp-queries .hljs-template-tag,.mp-queries .hljs-template-variable,.mp-queries .hljs-addition{color:var(--mp-highlight-string-color);}.mp-queries .hljs-comment,.mp-queries .hljs-quote{color:var(--mp-highlight-comment-color);}.mp-queries .hljs-number,.mp-queries .hljs-regexp,.mp-queries .hljs-literal,.mp-queries .hljs-bullet,.mp-queries .hljs-link{color:var(--mp-highlight-literal-color);}.mp-queries .hljs-deletion,.mp-queries .hljs-variable{color:var(--mp-highlight-variable-color);}.mp-queries .hljs-keyword,.mp-queries .hljs-selector-tag,.mp-queries .hljs-title,.mp-queries .hljs-section,.mp-queries .hljs-built_in,.mp-queries .hljs-doctag,.mp-queries .hljs-type,.mp-queries .hljs-tag,.mp-queries .hljs-name,.mp-queries .hljs-selector-id,.mp-queries .hljs-selector-class,.mp-queries .hljs-strong{color:var(--mp-highlight-keyword-color);}.mp-queries .hljs-emphasis{font-style:italic;}.mp-queries .hljs-attribute{color:var(--mp-highlight-attribute-color);}.mp-results{z-index:2147483641;position:fixed;top:0;}.mp-results.mp-left,.mp-results.mp-bottomleft{left:0;}.mp-results.mp-left .mp-controls,.mp-results.mp-left.mp-no-controls .mp-result:last-child .mp-button{border-bottom-right-radius:var(--mp-result-border-radius);}.mp-results.mp-left .mp-button,.mp-results.mp-left .mp-controls{border-right:var(--mp-result-border);}.mp-results.mp-right{right:0;}.mp-results.mp-right .mp-controls,.mp-results.mp-right.mp-no-controls .mp-result:last-child .mp-button{border-bottom-left-radius:var(--mp-result-border-radius);}.mp-results.mp-right .mp-button,.mp-results.mp-right .mp-controls{border-left:var(--mp-result-border);}.mp-results.mp-bottomleft{top:inherit;bottom:0;}.mp-results.mp-bottomleft .mp-result:first-child .mp-button{border-top-right-radius:var(--mp-result-border-radius);}.mp-results.mp-bottomleft .mp-button,.mp-results.mp-bottomleft .mp-controls{border-right:var(--mp-result-border);}.mp-results.mp-bottomleft .mp-result .mp-button,.mp-results.mp-bottomleft .mp-controls{border-bottom:0;border-top:var(--mp-result-border);}.mp-results.mp-bottomright{top:inherit;bottom:0;right:0;}.mp-results.mp-bottomright .mp-result:first-child .mp-button{border-top-left-radius:var(--mp-result-border-radius);}.mp-results.mp-bottomright .mp-button,.mp-results.mp-bottomright .mp-controls{border-left:var(--mp-result-border);}.mp-results.mp-bottomright .mp-result .mp-button,.mp-results.mp-bottomright .mp-controls{border-bottom:0;border-top:var(--mp-result-border);}.mp-results .mp-button{user-select:none;}.mp-results .mp-button.mp-button-warning{font-weight:bold;background-color:var(--mp-button-warning-bg-color);color:var(--mp-button-warning-text-color);}.mp-results .mp-button.mp-button-warning .mp-number,.mp-results .mp-button.mp-button-warning .mp-unit,.mp-results .mp-button.mp-button-warning .mp-warning{color:var(--mp-button-warning-text-color);}.mp-results .mp-button .mp-warning{font-weight:bold;}.mp-results .mp-button>.mp-number{font-family:Consolas,monospace,serif;}.mp-results .mp-controls{display:none;}.mp-results .mp-button,.mp-results .mp-controls{z-index:2147483640;border-bottom:var(--mp-result-border);background-color:var(--mp-main-bg-color);padding:4px 8px;text-align:right;cursor:pointer;}.mp-results .mp-result{position:relative;}.mp-results .mp-result.active .mp-button{background-color:var(--mp-button-active-bg-color);animation:none;border-radius:0 !important;}.mp-results .mp-result.active .mp-button.mp-button-warning{background-color:var(--mp-button-warning-bg-color);}.mp-results .mp-result.active .mp-button .mp-number,.mp-results .mp-result.active .mp-button .mp-warning{color:var(--mp-button-active-text-color);font-weight:bold;}.mp-results .mp-result.active .mp-button .mp-unit{color:var(--mp-button-active-text-color);font-weight:normal;}.mp-results .mp-result.active .mp-popup{display:block;}.mp-results.new .mp-button{animation:mp-fadeIn 2s 1;}.mp-results .mp-controls{display:block;font-size:12px;font-family:Consolas,monospace,serif;cursor:default;text-align:center;}.mp-results .mp-controls span{border-right:1px solid var(--mp-muted-color);padding-right:5px;margin-right:5px;cursor:pointer;}.mp-results .mp-controls span:last-child{border-right:none;}.mp-results .mp-popup{display:none;z-index:2147483641;position:absolute;background-color:var(--mp-main-bg-color);padding:5px 10px;text-align:left;line-height:18px;overflow:auto;box-shadow:0 1px 10px var(--mp-shadow-color);border-radius:2px;}.mp-results .mp-popup .mp-info{margin-bottom:3px;padding-bottom:2px;border-bottom:1px solid var(--mp-info-border-color);}.mp-results .mp-popup .mp-info .mp-name{font-size:1.1em;}.mp-results .mp-popup .mp-info .mp-overall-duration{color:var(--mp-muted-color);}.mp-results .mp-popup .mp-timings th,.mp-results .mp-popup .mp-timings td{padding:0 6px;}.mp-results .mp-popup .mp-timings th{font-size:95%;padding-bottom:3px;}.mp-results .mp-popup .mp-timings .mp-label{max-width:350px;text-overflow:ellipsis;white-space:nowrap;overflow:hidden;}.mp-results .mp-queries{display:none;}.mp-results.mp-min .mp-result{display:none;}.mp-results.mp-min .mp-controls span{display:none;}.mp-results.mp-min .mp-controls .mp-min-max{border-right:none;padding:0;margin:0;}.mp-result-full .mp-result{width:950px;margin:25px auto;}.mp-result-full .mp-result .mp-button{display:none;}.mp-result-full .mp-result .mp-popup .mp-info{font-size:18px;border-bottom:1px solid var(--mp-muted-color);padding-bottom:3px;margin-bottom:10px;}.mp-result-full .mp-result .mp-popup .mp-info .mp-name{margin-bottom:5px;}.mp-result-full .mp-result .mp-popup .mp-info .mp-overall-duration,.mp-result-full .mp-result .mp-popup .mp-info .mp-started{font-size:80%;color:var(--mp-muted-color);}.mp-result-full .mp-result .mp-popup .mp-info .mp-overall-duration{padding-right:20px;}.mp-result-full .mp-result .mp-popup .mp-timings td,.mp-result-full .mp-result .mp-popup .mp-timings th{font-size:13px;padding-left:8px;padding-right:8px;}.mp-result-full .mp-result .mp-popup .mp-timings th{padding-bottom:7px;}.mp-result-full .mp-result .mp-popup .mp-timings td{padding-bottom:4px;}.mp-result-full .mp-result .mp-popup .mp-timings td:first-child{padding-left:10px;}.mp-result-full .mp-result .mp-popup .mp-timings .mp-label{max-width:550px;}.mp-result-full .mp-result .mp-queries{margin:20px 0;}.mp-result-full .mp-result .mp-queries th{font-size:16px;}.mp-result-full .mp-share-mp-results{display:none;}table.mp-results-index{border:0;border-spacing:0;font-size:12px;font-family:Arial;}table.mp-results-index a{color:var(--mp-link-color);text-decoration:none;}table.mp-results-index tbody{color:var(--mp-label-color);}table.mp-results-index tbody tr:nth-child(odd){background-color:var(--mp-alt-row-color);}table.mp-results-index tbody tr:nth-child(even){background-color:var(--mp-main-bg-color);}table.mp-results-index tbody td{text-align:center;}table.mp-results-index tbody td:first-child{text-align:left;}table.mp-results-index tbody td[colspan="3"]{color:var(--mp-muted-color);}table.mp-results-index thead tr{color:var(--mp-label-color);}table.mp-results-index thead tr th{padding:5px 15px;}table.mp-results-index td{padding:8px;} \ No newline at end of file diff --git a/src/MiniProfiler.Shared/ui/lib/MiniProfiler.ts b/src/MiniProfiler.Shared/ui/lib/MiniProfiler.ts index 8d987a758..2e8f00ac0 100644 --- a/src/MiniProfiler.Shared/ui/lib/MiniProfiler.ts +++ b/src/MiniProfiler.Shared/ui/lib/MiniProfiler.ts @@ -678,8 +678,8 @@ namespace StackExchange.Profiling { const customTimingTypes = p.CustomTimingStats ? Object.keys(p.CustomTimingStats) : []; let str = ` - 0 ? ` style="padding-left:${timing.Depth * 11}px;"` : ''}> - ${encode(timing.Name.slice(0, 45))}${encode(timing.Name && timing.Name.length > 45 ? '...' : '')} + 0 ? ` style="padding-left:${timing.Depth * 11}px;"` : ''}> + ${encode(timing.Name)} ${duration(timing.DurationWithoutChildrenMilliseconds)}