From a22100b341156cc069031df52970a87b1c9e9fa2 Mon Sep 17 00:00:00 2001 From: Steve Sanderson Date: Mon, 29 Apr 2019 11:58:34 +0100 Subject: [PATCH 01/33] Store component/element keys on RenderTreeFrame Also refactored how RenderTreeFrame gets constructed. The previous arrangement of having ad-hoc ctor overloads for different scenarios became intractible (too many combinations to avoid clashes; risk of accidentally losing field values when cloning). There's now one constructor per RenderTreeFrameType, so you always know where to add any new field values, and implicitly guarantees you don't lose other field values because adding a new param forces updates at all the call sites. --- .../dist/Debug/blazor.webassembly.js | 2 +- .../dist/Release/blazor.webassembly.js | 2 +- .../RenderBatch/SharedMemoryRenderBatch.ts | 2 +- .../src/RenderTree/RenderTreeBuilder.cs | 31 +++- .../src/RenderTree/RenderTreeFrame.cs | 144 ++++++++++-------- .../Components/test/RenderTreeBuilderTest.cs | 101 ++++++++++++ 6 files changed, 210 insertions(+), 72 deletions(-) diff --git a/src/Components/Browser.JS/dist/Debug/blazor.webassembly.js b/src/Components/Browser.JS/dist/Debug/blazor.webassembly.js index bae138186598..4d36c8155195 100644 --- a/src/Components/Browser.JS/dist/Debug/blazor.webassembly.js +++ b/src/Components/Browser.JS/dist/Debug/blazor.webassembly.js @@ -2097,7 +2097,7 @@ var editReader = { }; // Keep in sync with memory layout in RenderTreeFrame.cs var frameReader = { - structLength: 28, + structLength: 36, frameType: function (frame) { return Environment_1.platform.readInt32Field(frame, 4); }, subtreeLength: function (frame) { return Environment_1.platform.readInt32Field(frame, 8); }, elementReferenceCaptureId: function (frame) { return Environment_1.platform.readStringField(frame, 16); }, diff --git a/src/Components/Browser.JS/dist/Release/blazor.webassembly.js b/src/Components/Browser.JS/dist/Release/blazor.webassembly.js index 05f2e01ea93f..4f29b34979f8 100644 --- a/src/Components/Browser.JS/dist/Release/blazor.webassembly.js +++ b/src/Components/Browser.JS/dist/Release/blazor.webassembly.js @@ -1 +1 @@ -!function(e){var t={};function n(r){if(t[r])return t[r].exports;var o=t[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)n.d(r,o,function(t){return e[t]}.bind(null,o));return r},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=42)}([,,,,,,,,function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var r=n(23),o=n(9),a={};function i(e,t,n){var o=a[e];o||(o=a[e]=new r.BrowserRenderer(e)),o.attachRootComponentToLogicalElement(n,t)}t.attachRootComponentToLogicalElement=i,t.attachRootComponentToElement=function(e,t,n){var r=document.querySelector(t);if(!r)throw new Error("Could not find any element matching selector '"+t+"'.");i(e,o.toLogicalElement(r,!0),n)},t.renderBatch=function(e,t){var n=a[e];if(!n)throw new Error("There is no browser renderer with ID "+e+".");for(var r=t.arrayRangeReader,o=t.updatedComponents(),i=r.values(o),u=r.count(o),l=t.referenceFrames(),s=r.values(l),c=t.diffReader,f=0;f0&&!t)throw new Error("New logical elements must start empty, or allowExistingContents must be true");return e[r]=[],e}function u(e,t,n){var a=e;if(e instanceof Comment&&(s(a)&&s(a).length>0))throw new Error("Not implemented: inserting non-empty logical container");if(l(a))throw new Error("Not implemented: moving existing logical children");var i=s(t);if(n0;)e(r,0);var a=r;a.parentNode.removeChild(a)},t.getLogicalParent=l,t.getLogicalSiblingEnd=function(e){return e[a]||null},t.getLogicalChild=function(e,t){return s(e)[t]},t.isSvgElement=function(e){return"http://www.w3.org/2000/svg"===function(e){if(e instanceof Element)return e;if(e instanceof Comment)return e.parentNode;throw new Error("Not a valid logical element")}(e).namespaceURI},t.getLogicalChildrenArray=s},,,function(e,t,n){"use strict";var r;!function(e){window.DotNet=e;var t=[],n={},r={},o=1,a=null;function i(e){t.push(e)}function u(e,t){for(var n=[],r=2;r0&&o[o.length-1])&&(6===a[0]||2===a[0])){i=0;continue}if(3===a[0]&&(!o||a[1]>o[0]&&a[1]0&&o[o.length-1])&&(6===a[0]||2===a[0])){i=0;continue}if(3===a[0]&&(!o||a[1]>o[0]&&a[1]0&&o[o.length-1])&&(6===a[0]||2===a[0])){i=0;continue}if(3===a[0]&&(!o||a[1]>o[0]&&a[1]0&&o[o.length-1])&&(6===a[0]||2===a[0])){i=0;continue}if(3===a[0]&&(!o||a[1]>o[0]&&a[1]-1?a.substring(0,u):"",s=u>-1?a.substring(u+1):a,c=t.monoPlatform.findMethod(e,l,s,i);t.monoPlatform.callMethod(c,null,r)},callMethod:function(e,n,r){if(r.length>4)throw new Error("Currently, MonoPlatform supports passing a maximum of 4 arguments from JS to .NET. You tried to pass "+r.length+".");var o=Module.stackSave();try{for(var a=Module.stackAlloc(r.length),u=Module.stackAlloc(4),l=0;l0&&!t)throw new Error("New logical elements must start empty, or allowExistingContents must be true");return e[r]=[],e}function u(e,t,n){var a=e;if(e instanceof Comment&&(s(a)&&s(a).length>0))throw new Error("Not implemented: inserting non-empty logical container");if(l(a))throw new Error("Not implemented: moving existing logical children");var i=s(t);if(n0;)e(r,0);var a=r;a.parentNode.removeChild(a)},t.getLogicalParent=l,t.getLogicalSiblingEnd=function(e){return e[a]||null},t.getLogicalChild=function(e,t){return s(e)[t]},t.isSvgElement=function(e){return"http://www.w3.org/2000/svg"===function(e){if(e instanceof Element)return e;if(e instanceof Comment)return e.parentNode;throw new Error("Not a valid logical element")}(e).namespaceURI},t.getLogicalChildrenArray=s},,,function(e,t,n){"use strict";var r;!function(e){window.DotNet=e;var t=[],n={},r={},o=1,a=null;function i(e){t.push(e)}function u(e,t){for(var n=[],r=2;r0&&o[o.length-1])&&(6===a[0]||2===a[0])){i=0;continue}if(3===a[0]&&(!o||a[1]>o[0]&&a[1]0&&o[o.length-1])&&(6===a[0]||2===a[0])){i=0;continue}if(3===a[0]&&(!o||a[1]>o[0]&&a[1]0&&o[o.length-1])&&(6===a[0]||2===a[0])){i=0;continue}if(3===a[0]&&(!o||a[1]>o[0]&&a[1]0&&o[o.length-1])&&(6===a[0]||2===a[0])){i=0;continue}if(3===a[0]&&(!o||a[1]>o[0]&&a[1]-1?a.substring(0,u):"",s=u>-1?a.substring(u+1):a,c=t.monoPlatform.findMethod(e,l,s,i);t.monoPlatform.callMethod(c,null,r)},callMethod:function(e,n,r){if(r.length>4)throw new Error("Currently, MonoPlatform supports passing a maximum of 4 arguments from JS to .NET. You tried to pass "+r.length+".");var o=Module.stackSave();try{for(var a=Module.stackAlloc(r.length),u=Module.stackAlloc(4),l=0;l platform.readInt32Field(frame as any, 4) as FrameType, subtreeLength: (frame: RenderTreeFrame) => platform.readInt32Field(frame as any, 8), elementReferenceCaptureId: (frame: RenderTreeFrame) => platform.readStringField(frame as any, 16), diff --git a/src/Components/Components/src/RenderTree/RenderTreeBuilder.cs b/src/Components/Components/src/RenderTree/RenderTreeBuilder.cs index 24f07042c43d..9774b33b6e14 100644 --- a/src/Components/Components/src/RenderTree/RenderTreeBuilder.cs +++ b/src/Components/Components/src/RenderTree/RenderTreeBuilder.cs @@ -454,13 +454,30 @@ public void OpenComponent(int sequence, Type componentType) /// The value for the key. public void SetKey(object value) { - // This is just a placeholder to enable work in parallel in the - // aspnetcore-tooling repo. - // - // The real implementation will involve multiple overloads, likely: - // SetKey(int value) -- underlying logic - // SetKey(T value) where T: struct -- avoids boxing 'value' before calling .GetHashCode() - // SetKey(object value) -- performs null check before calling .GetHashCode() + if (value == null) + { + throw new ArgumentNullException(nameof(value)); + } + + var parentFrameIndex = GetCurrentParentFrameIndex(); + if (!parentFrameIndex.HasValue) + { + throw new InvalidOperationException("Cannot set a key outside the scope of a component or element."); + } + + var parentFrameIndexValue = parentFrameIndex.Value; + ref var parentFrame = ref _entries.Buffer[parentFrameIndexValue]; + switch (parentFrame.FrameType) + { + case RenderTreeFrameType.Element: + _entries.Buffer[parentFrameIndexValue] = parentFrame.WithElementKey(value); + break; + case RenderTreeFrameType.Component: + _entries.Buffer[parentFrameIndexValue] = parentFrame.WithComponentKey(value); + break; + default: + throw new InvalidOperationException($"Cannot set a key on a frame of type {parentFrame.FrameType}."); + } } private void OpenComponentUnchecked(int sequence, Type componentType) diff --git a/src/Components/Components/src/RenderTree/RenderTreeFrame.cs b/src/Components/Components/src/RenderTree/RenderTreeFrame.cs index 920d0752bb5f..3e89977db898 100644 --- a/src/Components/Components/src/RenderTree/RenderTreeFrame.cs +++ b/src/Components/Components/src/RenderTree/RenderTreeFrame.cs @@ -3,7 +3,6 @@ using System; using System.Runtime.InteropServices; -using Microsoft.AspNetCore.Components; using Microsoft.AspNetCore.Components.Rendering; namespace Microsoft.AspNetCore.Components.RenderTree @@ -17,13 +16,22 @@ public readonly struct RenderTreeFrame // Note that the struct layout has to be valid in both 32-bit and 64-bit runtime platforms, // which means that all reference-type fields need to take up 8 bytes (except for the last // one, which will be sized as either 4 or 8 bytes depending on the runtime platform). - // This is not optimal for the Mono-WebAssembly case because that's always 32-bit so the - // reference-type fields could be reduced to 4 bytes each. We could use ifdefs to have - // different fields offsets for the 32 and 64 bit compile targets, but then we'd have the - // complexity of needing different binaries when loaded into Mono-WASM vs desktop. - // Eventually we might stop using this shared memory interop altogether (and would have to - // if running as a web worker) so for now to keep things simple, treat reference types as - // 8 bytes here. + + // Although each frame type uses the slots for different purposes, the runtime does not + // allow reference type slots to overlap with each other or with value-type slots. + // Here's the current layout: + // + // Offset Type + // ------ ---- + // 0-3 Int32 (sequence number) + // 4-7 Int32 (frame type) + // 8-15 Value types (usage varies by frame type) + // 16-23 Reference type (usage varies by frame type) + // 24-31 Reference type (usage varies by frame type) + // 32-39 Reference type (usage varies by frame type) + // + // On Mono WebAssembly, because it's 32-bit, the final slot occupies bytes 32-35, + // so the struct length is only 36. // -------------------------------------------------------------------------------- // Common @@ -58,6 +66,12 @@ public readonly struct RenderTreeFrame /// [FieldOffset(16)] public readonly string ElementName; + /// + /// If the property equals , + /// gets the element's diffing key, or null if none was specified. + /// + [FieldOffset(24)] public readonly object ElementKey; + // -------------------------------------------------------------------------------- // RenderTreeFrameType.Text // -------------------------------------------------------------------------------- @@ -119,6 +133,12 @@ public readonly struct RenderTreeFrame /// [FieldOffset(24)] internal readonly ComponentState ComponentState; + /// + /// If the property equals , + /// gets the component's diffing key, or null if none was specified. + /// + [FieldOffset(32)] public readonly object ComponentKey; + /// /// If the property equals , /// gets the child component instance. Otherwise, the value is undefined. @@ -184,66 +204,72 @@ public readonly struct RenderTreeFrame /// [FieldOffset(16)] public readonly string MarkupContent; - private RenderTreeFrame(int sequence, string elementName, int elementSubtreeLength) + // Element constructor + private RenderTreeFrame(int sequence, int elementSubtreeLength, string elementName, object elementKey) : this() { - FrameType = RenderTreeFrameType.Element; Sequence = sequence; - ElementName = elementName; + FrameType = RenderTreeFrameType.Element; ElementSubtreeLength = elementSubtreeLength; + ElementName = elementName; + ElementKey = elementKey; } - private RenderTreeFrame(int sequence, Type componentType, int componentSubtreeLength) + // Component constructor + private RenderTreeFrame(int sequence, int componentSubtreeLength, Type componentType, ComponentState componentState, object componentKey) : this() { - FrameType = RenderTreeFrameType.Component; Sequence = sequence; - ComponentType = componentType; + FrameType = RenderTreeFrameType.Component; ComponentSubtreeLength = componentSubtreeLength; - } + ComponentType = componentType; + ComponentKey = componentKey; - private RenderTreeFrame(int sequence, Type componentType, int subtreeLength, ComponentState componentState) - : this(sequence, componentType, subtreeLength) - { - ComponentId = componentState.ComponentId; - ComponentState = componentState; + if (componentState != null) + { + ComponentState = componentState; + ComponentId = componentState.ComponentId; + } } - private RenderTreeFrame(int sequence, string textContent) + // Region constructor + private RenderTreeFrame(int sequence, int regionSubtreeLength) : this() { - FrameType = RenderTreeFrameType.Text; Sequence = sequence; - TextContent = textContent; + FrameType = RenderTreeFrameType.Region; + RegionSubtreeLength = regionSubtreeLength; } - private RenderTreeFrame(int sequence, string attributeName, object attributeValue) + // Text/markup constructor + private RenderTreeFrame(int sequence, bool isMarkup, string textOrMarkup) : this() { - FrameType = RenderTreeFrameType.Attribute; Sequence = sequence; - AttributeName = attributeName; - AttributeValue = attributeValue; + if (isMarkup) + { + FrameType = RenderTreeFrameType.Markup; + MarkupContent = textOrMarkup; + } + else + { + FrameType = RenderTreeFrameType.Text; + TextContent = textOrMarkup; + } } - private RenderTreeFrame(int sequence, string attributeName, object attributeValue, int eventHandlerId) + // Attribute constructor + private RenderTreeFrame(int sequence, string attributeName, object attributeValue, int attributeEventHandlerId) : this() { FrameType = RenderTreeFrameType.Attribute; Sequence = sequence; AttributeName = attributeName; AttributeValue = attributeValue; - AttributeEventHandlerId = eventHandlerId; - } - - private RenderTreeFrame(int sequence, int regionSubtreeLength) - : this() - { - FrameType = RenderTreeFrameType.Region; - Sequence = sequence; - RegionSubtreeLength = regionSubtreeLength; + AttributeEventHandlerId = attributeEventHandlerId; } + // Element reference capture constructor private RenderTreeFrame(int sequence, Action elementReferenceCaptureAction, string elementReferenceCaptureId) : this() { @@ -253,6 +279,7 @@ private RenderTreeFrame(int sequence, Action elementReferenceCapture ElementReferenceCaptureId = elementReferenceCaptureId; } + // Component reference capture constructor private RenderTreeFrame(int sequence, Action componentReferenceCaptureAction, int parentFrameIndex) : this() { @@ -262,36 +289,23 @@ private RenderTreeFrame(int sequence, Action componentReferenceCaptureAc ComponentReferenceCaptureParentFrameIndex = parentFrameIndex; } - // If we need further constructors whose signatures clash with the patterns above, - // we can add extra args to this general-purpose one. - private RenderTreeFrame(int sequence, RenderTreeFrameType frameType, string markupContent) - : this() - { - FrameType = frameType; - Sequence = sequence; - MarkupContent = markupContent; - } - internal static RenderTreeFrame Element(int sequence, string elementName) - => new RenderTreeFrame(sequence, elementName: elementName, elementSubtreeLength: 0); + => new RenderTreeFrame(sequence, elementSubtreeLength: 0, elementName, null); internal static RenderTreeFrame Text(int sequence, string textContent) - => new RenderTreeFrame(sequence, textContent: textContent); + => new RenderTreeFrame(sequence, isMarkup: false, textOrMarkup: textContent); internal static RenderTreeFrame Markup(int sequence, string markupContent) - => new RenderTreeFrame(sequence, RenderTreeFrameType.Markup, markupContent); - - internal static RenderTreeFrame Attribute(int sequence, string name, MulticastDelegate value) - => new RenderTreeFrame(sequence, attributeName: name, attributeValue: value); + => new RenderTreeFrame(sequence, isMarkup: true, textOrMarkup: markupContent); internal static RenderTreeFrame Attribute(int sequence, string name, object value) - => new RenderTreeFrame(sequence, attributeName: name, attributeValue: value); + => new RenderTreeFrame(sequence, attributeName: name, attributeValue: value, attributeEventHandlerId: 0); internal static RenderTreeFrame ChildComponent(int sequence, Type componentType) - => new RenderTreeFrame(sequence, componentType, 0); + => new RenderTreeFrame(sequence, componentSubtreeLength: 0, componentType, null, null); internal static RenderTreeFrame PlaceholderChildComponentWithSubtreeLength(int subtreeLength) - => new RenderTreeFrame(0, typeof(IComponent), subtreeLength); + => new RenderTreeFrame(0, componentSubtreeLength: subtreeLength, typeof(IComponent), null, null); internal static RenderTreeFrame Region(int sequence) => new RenderTreeFrame(sequence, regionSubtreeLength: 0); @@ -303,25 +317,31 @@ internal static RenderTreeFrame ComponentReferenceCapture(int sequence, Action new RenderTreeFrame(sequence, componentReferenceCaptureAction: componentReferenceCaptureAction, parentFrameIndex: parentFrameIndex); internal RenderTreeFrame WithElementSubtreeLength(int elementSubtreeLength) - => new RenderTreeFrame(Sequence, elementName: ElementName, elementSubtreeLength: elementSubtreeLength); + => new RenderTreeFrame(Sequence, elementSubtreeLength: elementSubtreeLength, ElementName, ElementKey); internal RenderTreeFrame WithComponentSubtreeLength(int componentSubtreeLength) - => new RenderTreeFrame(Sequence, componentType: ComponentType, componentSubtreeLength: componentSubtreeLength); + => new RenderTreeFrame(Sequence, componentSubtreeLength: componentSubtreeLength, ComponentType, ComponentState, ComponentKey); internal RenderTreeFrame WithAttributeSequence(int sequence) - => new RenderTreeFrame(sequence, attributeName: AttributeName, attributeValue: AttributeValue); + => new RenderTreeFrame(sequence, attributeName: AttributeName, AttributeValue, AttributeEventHandlerId); internal RenderTreeFrame WithComponent(ComponentState componentState) - => new RenderTreeFrame(Sequence, ComponentType, ComponentSubtreeLength, componentState); + => new RenderTreeFrame(Sequence, componentSubtreeLength: ComponentSubtreeLength, ComponentType, componentState, ComponentKey); internal RenderTreeFrame WithAttributeEventHandlerId(int eventHandlerId) - => new RenderTreeFrame(Sequence, AttributeName, AttributeValue, eventHandlerId); + => new RenderTreeFrame(Sequence, attributeName: AttributeName, AttributeValue, eventHandlerId); internal RenderTreeFrame WithRegionSubtreeLength(int regionSubtreeLength) => new RenderTreeFrame(Sequence, regionSubtreeLength: regionSubtreeLength); internal RenderTreeFrame WithElementReferenceCaptureId(string elementReferenceCaptureId) - => new RenderTreeFrame(Sequence, ElementReferenceCaptureAction, elementReferenceCaptureId); + => new RenderTreeFrame(Sequence, elementReferenceCaptureAction: ElementReferenceCaptureAction, elementReferenceCaptureId); + + internal RenderTreeFrame WithElementKey(object elementKey) + => new RenderTreeFrame(Sequence, elementSubtreeLength: ElementSubtreeLength, ElementName, elementKey); + + internal RenderTreeFrame WithComponentKey(object componentKey) + => new RenderTreeFrame(Sequence, componentSubtreeLength: ComponentSubtreeLength, ComponentType, ComponentState, componentKey); /// // Just to be nice for debugging and unit tests. diff --git a/src/Components/Components/test/RenderTreeBuilderTest.cs b/src/Components/Components/test/RenderTreeBuilderTest.cs index 75a7616b1e70..ac05e9b195b0 100644 --- a/src/Components/Components/test/RenderTreeBuilderTest.cs +++ b/src/Components/Components/test/RenderTreeBuilderTest.cs @@ -1047,6 +1047,107 @@ public void AddAttribute_Element_ObjectNull_IgnoresFrame() frame => AssertFrame.Element(frame, "elem", 1, 0)); } + [Fact] + public void CanAddKeyToElement() + { + // Arrange + var builder = new RenderTreeBuilder(new TestRenderer()); + var keyValue = new object(); + + // Act + builder.OpenElement(0, "elem"); + builder.AddAttribute(1, "attribute before", "before value"); + builder.SetKey(keyValue); + builder.AddAttribute(2, "attribute after", "after value"); + builder.CloseElement(); + + // Assert + Assert.Collection( + builder.GetFrames().AsEnumerable(), + frame => + { + AssertFrame.Element(frame, "elem", 3, 0); + Assert.Same(keyValue, frame.ElementKey); + }, + frame => AssertFrame.Attribute(frame, "attribute before", "before value", 1), + frame => AssertFrame.Attribute(frame, "attribute after", "after value", 2)); + } + + [Fact] + public void CanAddKeyToComponent() + { + // Arrange + var builder = new RenderTreeBuilder(new TestRenderer()); + var keyValue = new object(); + + // Act + builder.OpenComponent(0); + builder.AddAttribute(1, "param before", 123); + builder.SetKey(keyValue); + builder.AddAttribute(2, "param after", 456); + builder.CloseComponent(); + + // Assert + Assert.Collection( + builder.GetFrames().AsEnumerable(), + frame => + { + AssertFrame.Component(frame, 3, 0); + Assert.Same(keyValue, frame.ComponentKey); + }, + frame => AssertFrame.Attribute(frame, "param before", 123, 1), + frame => AssertFrame.Attribute(frame, "param after", 456, 2)); + } + + [Fact] + public void CannotAddKeyOutsideComponentOrElement_TreeRoot() + { + // Arrange + var builder = new RenderTreeBuilder(new TestRenderer()); + + // Act/Assert + var ex = Assert.Throws(() => + { + builder.SetKey(new object()); + }); + Assert.Equal("Cannot set a key outside the scope of a component or element.", ex.Message); + } + + [Fact] + public void CannotAddKeyOutsideComponentOrElement_RegionRoot() + { + // Arrange + var builder = new RenderTreeBuilder(new TestRenderer()); + + // Act/Assert + builder.OpenElement(0, "some element"); + builder.OpenRegion(1); + var ex = Assert.Throws(() => + { + builder.SetKey(new object()); + }); + Assert.Equal($"Cannot set a key on a frame of type {RenderTreeFrameType.Region}.", ex.Message); + } + + [Fact] + public void CannotAddNullKey() + { + // Although we could translate 'null' into either some default "null key" + // instance, or just no-op the call, it almost certainly indicates a programming + // error so it's better to fail. + + // Arrange + var builder = new RenderTreeBuilder(new TestRenderer()); + + // Act/Assert + var ex = Assert.Throws(() => + { + builder.OpenElement(0, "elem"); + builder.SetKey(null); + }); + Assert.Equal("value", ex.ParamName); + } + private class TestComponent : IComponent { public void Configure(RenderHandle renderHandle) { } From f8768949d32473c43280722361153bd5cbbf6674 Mon Sep 17 00:00:00 2001 From: Steve Sanderson Date: Mon, 29 Apr 2019 14:11:04 +0100 Subject: [PATCH 02/33] Add StackObjectPool, which will be useful momentarily --- .../src/RenderTree/StackObjectPool.cs | 73 +++++++++++ .../Components/test/StackObjectPoolTest.cs | 123 ++++++++++++++++++ 2 files changed, 196 insertions(+) create mode 100644 src/Components/Components/src/RenderTree/StackObjectPool.cs create mode 100644 src/Components/Components/test/StackObjectPoolTest.cs diff --git a/src/Components/Components/src/RenderTree/StackObjectPool.cs b/src/Components/Components/src/RenderTree/StackObjectPool.cs new file mode 100644 index 000000000000..7489eede22f8 --- /dev/null +++ b/src/Components/Components/src/RenderTree/StackObjectPool.cs @@ -0,0 +1,73 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System; + +namespace Microsoft.AspNetCore.Components.RenderTree +{ + // This is a very simple object pool that requires Get and Return calls to be + // balanced as in a stack. It retains up to 'maxPreservedItems' instances in + // memory, then for any further requests it supplies untracked instances. + + internal class StackObjectPool where T : class, new() + { + private readonly int _maxPreservedItems; + private readonly T[] _contents; + private int _numSuppliedItems; + private int _numTrackedItems; + + public StackObjectPool(int maxPreservedItems) + { + _maxPreservedItems = maxPreservedItems; + _contents = new T[_maxPreservedItems]; + } + + public T Get() + { + _numSuppliedItems++; + + if (_numSuppliedItems <= _maxPreservedItems) + { + if (_numTrackedItems < _numSuppliedItems) + { + // Need to allocate a new one + var newItem = new T(); + _contents[_numTrackedItems++] = newItem; + return newItem; + } + else + { + // Can use one that's already in the pool + return _contents[_numSuppliedItems - 1]; + } + } + else + { + // Pool is full; return untracked instance + return new T(); + } + } + + public void Return(T instance) + { + if (_numSuppliedItems <= 0) + { + throw new InvalidOperationException("There are no outstanding instances to return."); + } + else if (_numSuppliedItems <= _maxPreservedItems) + { + // We check you're returning the right instance only as a way of + // catching Get/Return mismatch bugs + var expectedInstance = _contents[_numSuppliedItems - 1]; + if (!ReferenceEquals(instance, expectedInstance)) + { + throw new ArgumentException($"Attempting to return wrong pooled instance. {nameof(Get)}/{nameof(Return)} calls must form a stack."); + } + } + + // It's a valid call. Track that we're no longer "supplying" the top item, + // but keep the instance in the _contents array for future reuse. + _numSuppliedItems--; + } + } +} diff --git a/src/Components/Components/test/StackObjectPoolTest.cs b/src/Components/Components/test/StackObjectPoolTest.cs new file mode 100644 index 000000000000..5804d240bc40 --- /dev/null +++ b/src/Components/Components/test/StackObjectPoolTest.cs @@ -0,0 +1,123 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System; +using System.Linq; +using Xunit; + +namespace Microsoft.AspNetCore.Components.RenderTree +{ + public class StackObjectPoolTest + { + [Fact] + public void CanGetInstances() + { + // Arrange + var stackObjectPool = new StackObjectPool(10); + + // Act + var instance1 = stackObjectPool.Get(); + var instance2 = stackObjectPool.Get(); + + // Assert + Assert.NotNull(instance1); + Assert.NotNull(instance2); + Assert.NotSame(instance1, instance2); + } + + [Fact] + public void CanReturnInstances() + { + // Arrange + var stackObjectPool = new StackObjectPool(10); + var instance1 = stackObjectPool.Get(); + var instance2 = stackObjectPool.Get(); + + // Act/Assert + // No exception means success + stackObjectPool.Return(instance2); + stackObjectPool.Return(instance1); + } + + [Fact] + public void ReusesInstancesInPoolUpToCapacity() + { + // Arrange + var stackObjectPool = new StackObjectPool(10); + var instance1 = stackObjectPool.Get(); + var instance2 = stackObjectPool.Get(); + stackObjectPool.Return(instance2); + stackObjectPool.Return(instance1); + + // Act + var instance1b = stackObjectPool.Get(); + var instance2b = stackObjectPool.Get(); + var instance3 = stackObjectPool.Get(); + + // Assert + Assert.Same(instance1, instance1b); + Assert.Same(instance2, instance2b); + Assert.NotNull(instance3); + Assert.NotSame(instance1, instance3); + Assert.NotSame(instance2, instance3); + } + + [Fact] + public void SuppliesTransientInstancesWhenExceedingCapacity() + { + // Arrange + var stackObjectPool = new StackObjectPool(1); + + // Act 1: Returns distinct instances beyond capacity + var instance1 = stackObjectPool.Get(); + var instance2 = stackObjectPool.Get(); + var instance3 = stackObjectPool.Get(); + Assert.NotNull(instance1); + Assert.NotNull(instance2); + Assert.NotNull(instance3); + Assert.Equal(3, new[] { instance1, instance2, instance3 }.Distinct().Count()); + + // Act 2: Can return all instances, including transient ones + stackObjectPool.Return(instance3); + stackObjectPool.Return(instance2); + stackObjectPool.Return(instance1); + + // Act 3: Reuses only the non-transient instances + var instance1b = stackObjectPool.Get(); + var instance2b = stackObjectPool.Get(); + Assert.Same(instance1, instance1b); + Assert.NotSame(instance2b, instance2); + Assert.Equal(4, new[] { instance1, instance2, instance3, instance2b }.Distinct().Count()); + } + + [Fact] + public void CannotReturnWhenEmpty() + { + // Arrange + var stackObjectPool = new StackObjectPool(10); + + // Act/Assert + var ex = Assert.Throws(() => + { + stackObjectPool.Return(new object()); + }); + Assert.Equal("There are no outstanding instances to return.", ex.Message); + } + + [Fact] + public void CannotReturnMismatchingTrackedItem() + { + // Arrange + var stackObjectPool = new StackObjectPool(10); + var instance1 = stackObjectPool.Get(); + var instance2 = stackObjectPool.Get(); + + // Act/Assert + var ex = Assert.Throws(() => + { + stackObjectPool.Return(instance1); + }); + Assert.Equal("Attempting to return wrong pooled instance. Get/Return calls must form a stack.", ex.Message); + } + } +} From 31264b9cc7f0b9e197a3632eb9513aa1fc9b9ca2 Mon Sep 17 00:00:00 2001 From: Steve Sanderson Date: Mon, 29 Apr 2019 15:21:48 +0100 Subject: [PATCH 03/33] Support keyed insertions/deletions --- .../src/RenderTree/RenderTreeDiffBuilder.cs | 262 ++++++++++++------ .../Components/src/Rendering/KeyedItemInfo.cs | 13 + .../src/Rendering/RenderBatchBuilder.cs | 3 + .../test/RenderTreeDiffBuilderTest.cs | 146 ++++++++++ 4 files changed, 346 insertions(+), 78 deletions(-) create mode 100644 src/Components/Components/src/Rendering/KeyedItemInfo.cs diff --git a/src/Components/Components/src/RenderTree/RenderTreeDiffBuilder.cs b/src/Components/Components/src/RenderTree/RenderTreeDiffBuilder.cs index 6a0514462dea..807f6d9b534f 100644 --- a/src/Components/Components/src/RenderTree/RenderTreeDiffBuilder.cs +++ b/src/Components/Components/src/RenderTree/RenderTreeDiffBuilder.cs @@ -41,101 +41,205 @@ private static void AppendDiffEntriesForRange( var prevNewSeq = -1; var oldTree = diffContext.OldTree; var newTree = diffContext.NewTree; - while (hasMoreOld || hasMoreNew) - { - var oldSeq = hasMoreOld ? oldTree[oldStartIndex].Sequence : int.MaxValue; - var newSeq = hasMoreNew ? newTree[newStartIndex].Sequence : int.MaxValue; + Dictionary keyedItemInfos = null; - if (oldSeq == newSeq) - { - AppendDiffEntriesForFramesWithSameSequence(ref diffContext, oldStartIndex, newStartIndex); - oldStartIndex = NextSiblingIndex(oldTree[oldStartIndex], oldStartIndex); - newStartIndex = NextSiblingIndex(newTree[newStartIndex], newStartIndex); - hasMoreOld = oldEndIndexExcl > oldStartIndex; - hasMoreNew = newEndIndexExcl > newStartIndex; - prevOldSeq = oldSeq; - prevNewSeq = newSeq; - } - else + try + { + while (hasMoreOld || hasMoreNew) { - bool treatAsInsert; - var oldLoopedBack = oldSeq <= prevOldSeq; - var newLoopedBack = newSeq <= prevNewSeq; - if (oldLoopedBack == newLoopedBack) - { - // Both sequences are proceeding through the same loop block, so do a simple - // preordered merge join (picking from whichever side brings us closer to being - // back in sync) - treatAsInsert = newSeq < oldSeq; + var oldSeq = hasMoreOld ? oldTree[oldStartIndex].Sequence : int.MaxValue; + var newSeq = hasMoreNew ? newTree[newStartIndex].Sequence : int.MaxValue; + var isSeqMatch = oldSeq == newSeq; + var isSeqAndKeyMatch = isSeqMatch && IsKeyMatch(ref oldTree[oldStartIndex], ref newTree[newStartIndex]); - if (oldLoopedBack) - { - // If both old and new have now looped back, we must reset their 'looped back' - // tracker so we can treat them as proceeding through the same loop block - prevOldSeq = prevNewSeq = -1; - } + if (isSeqAndKeyMatch) + { + AppendDiffEntriesForFramesWithSameSequence(ref diffContext, oldStartIndex, newStartIndex); + oldStartIndex = NextSiblingIndex(oldTree[oldStartIndex], oldStartIndex); + newStartIndex = NextSiblingIndex(newTree[newStartIndex], newStartIndex); + hasMoreOld = oldEndIndexExcl > oldStartIndex; + hasMoreNew = newEndIndexExcl > newStartIndex; + prevOldSeq = oldSeq; + prevNewSeq = newSeq; } - else if (oldLoopedBack) + else { - // Old sequence looped back but new one didn't - // The new sequence either has some extra trailing elements in the current loop block - // which we should insert, or omits some old trailing loop blocks which we should delete - // TODO: Find a way of not recomputing this next flag on every iteration - var newLoopsBackLater = false; - for (var testIndex = newStartIndex + 1; testIndex < newEndIndexExcl; testIndex++) + bool treatAsInsert; + + if (isSeqMatch) { - if (newTree[testIndex].Sequence < newSeq) + // Mismatched on key only + if (keyedItemInfos == null) { - newLoopsBackLater = true; - break; + keyedItemInfos = BuildKeyToInfoLookup(diffContext, oldStartIndex, oldEndIndexExcl, newStartIndex, newEndIndexExcl); } - } - // If the new sequence loops back later to an earlier point than this, - // then we know it's part of the existing loop block (so should be inserted). - // If not, then it's unrelated to the previous loop block (so we should treat - // the old items as trailing loop blocks to be removed). - treatAsInsert = newLoopsBackLater; - } - else - { - // New sequence looped back but old one didn't - // The old sequence either has some extra trailing elements in the current loop block - // which we should delete, or the new sequence has extra trailing loop blocks which we - // should insert - // TODO: Find a way of not recomputing this next flag on every iteration - var oldLoopsBackLater = false; - for (var testIndex = oldStartIndex + 1; testIndex < oldEndIndexExcl; testIndex++) + var oldKey = KeyValue(ref oldTree[oldStartIndex]); + var newKey = KeyValue(ref newTree[newStartIndex]); + var oldKeyIsInNewTree = oldKey != null && keyedItemInfos[oldKey].NewIndex >= 0; + var newKeyIsInOldTree = newKey != null && keyedItemInfos[newKey].OldIndex >= 0; + if (oldKeyIsInNewTree && newKeyIsInOldTree) + { + // It's a move + throw new NotImplementedException("Not yet supported: moving items by key"); + } + else + { + // It's an insertion or a deletion + treatAsInsert = !newKeyIsInOldTree; + } + } + else { - if (oldTree[testIndex].Sequence < oldSeq) + var oldLoopedBack = oldSeq <= prevOldSeq; + var newLoopedBack = newSeq <= prevNewSeq; + if (oldLoopedBack == newLoopedBack) { - oldLoopsBackLater = true; - break; + // Both sequences are proceeding through the same loop block, so do a simple + // preordered merge join (picking from whichever side brings us closer to being + // back in sync) + treatAsInsert = newSeq < oldSeq; + + if (oldLoopedBack) + { + // If both old and new have now looped back, we must reset their 'looped back' + // tracker so we can treat them as proceeding through the same loop block + prevOldSeq = prevNewSeq = -1; + } + } + else if (oldLoopedBack) + { + // Old sequence looped back but new one didn't + // The new sequence either has some extra trailing elements in the current loop block + // which we should insert, or omits some old trailing loop blocks which we should delete + // TODO: Find a way of not recomputing this next flag on every iteration + var newLoopsBackLater = false; + for (var testIndex = newStartIndex + 1; testIndex < newEndIndexExcl; testIndex++) + { + if (newTree[testIndex].Sequence < newSeq) + { + newLoopsBackLater = true; + break; + } + } + + // If the new sequence loops back later to an earlier point than this, + // then we know it's part of the existing loop block (so should be inserted). + // If not, then it's unrelated to the previous loop block (so we should treat + // the old items as trailing loop blocks to be removed). + treatAsInsert = newLoopsBackLater; + } + else + { + // New sequence looped back but old one didn't + // The old sequence either has some extra trailing elements in the current loop block + // which we should delete, or the new sequence has extra trailing loop blocks which we + // should insert + // TODO: Find a way of not recomputing this next flag on every iteration + var oldLoopsBackLater = false; + for (var testIndex = oldStartIndex + 1; testIndex < oldEndIndexExcl; testIndex++) + { + if (oldTree[testIndex].Sequence < oldSeq) + { + oldLoopsBackLater = true; + break; + } + } + + // If the old sequence loops back later to an earlier point than this, + // then we know it's part of the existing loop block (so should be removed). + // If not, then it's unrelated to the previous loop block (so we should treat + // the new items as trailing loop blocks to be inserted). + treatAsInsert = !oldLoopsBackLater; } } - // If the old sequence loops back later to an earlier point than this, - // then we know it's part of the existing loop block (so should be removed). - // If not, then it's unrelated to the previous loop block (so we should treat - // the new items as trailing loop blocks to be inserted). - treatAsInsert = !oldLoopsBackLater; + if (treatAsInsert) + { + InsertNewFrame(ref diffContext, newStartIndex); + newStartIndex = NextSiblingIndex(newTree[newStartIndex], newStartIndex); + hasMoreNew = newEndIndexExcl > newStartIndex; + prevNewSeq = newSeq; + } + else + { + RemoveOldFrame(ref diffContext, oldStartIndex); + oldStartIndex = NextSiblingIndex(oldTree[oldStartIndex], oldStartIndex); + hasMoreOld = oldEndIndexExcl > oldStartIndex; + prevOldSeq = oldSeq; + } } + } + } + finally + { + if (keyedItemInfos != null) + { + keyedItemInfos.Clear(); + diffContext.KeyedItemInfoDictionaryPool.Return(keyedItemInfos); + } + } + } - if (treatAsInsert) - { - InsertNewFrame(ref diffContext, newStartIndex); - newStartIndex = NextSiblingIndex(newTree[newStartIndex], newStartIndex); - hasMoreNew = newEndIndexExcl > newStartIndex; - prevNewSeq = newSeq; - } - else - { - RemoveOldFrame(ref diffContext, oldStartIndex); - oldStartIndex = NextSiblingIndex(oldTree[oldStartIndex], oldStartIndex); - hasMoreOld = oldEndIndexExcl > oldStartIndex; - prevOldSeq = oldSeq; - } + private static Dictionary BuildKeyToInfoLookup(DiffContext diffContext, int oldStartIndex, int oldEndIndexExcl, int newStartIndex, int newEndIndexExcl) + { + var result = diffContext.KeyedItemInfoDictionaryPool.Get(); + var oldTree = diffContext.OldTree; + var newTree = diffContext.NewTree; + + while (oldStartIndex < oldEndIndexExcl) + { + ref var frame = ref oldTree[oldStartIndex]; + var key = KeyValue(ref frame); + if (key != null) + { + result[key] = new KeyedItemInfo { OldIndex = oldStartIndex, NewIndex = -1 }; } + + oldStartIndex = NextSiblingIndex(frame, oldStartIndex); + } + + while (newStartIndex < newEndIndexExcl) + { + ref var frame = ref newTree[newStartIndex]; + var key = KeyValue(ref frame); + if (key != null) + { + result[key] = result.TryGetValue(key, out var existingEntry) + ? new KeyedItemInfo { OldIndex = existingEntry.OldIndex, NewIndex = newStartIndex } + : new KeyedItemInfo { OldIndex = -1, NewIndex = newStartIndex }; + } + + newStartIndex = NextSiblingIndex(frame, newStartIndex); + } + + return result; + } + + private static bool IsKeyMatch(ref RenderTreeFrame frame1, ref RenderTreeFrame frame2) + { + switch (frame1.FrameType) + { + case RenderTreeFrameType.Element: + return Equals(frame1.ElementKey, frame2.ElementKey); + case RenderTreeFrameType.Component: + return Equals(frame1.ComponentKey, frame2.ComponentKey); + default: + // Other frame types don't have keys, so they are always considered matchable + return true; + } + } + + private static object KeyValue(ref RenderTreeFrame frame) + { + switch (frame.FrameType) + { + case RenderTreeFrameType.Element: + return frame.ElementKey; + case RenderTreeFrameType.Component: + return frame.ComponentKey; + default: + return null; } } @@ -718,6 +822,7 @@ private struct DiffContext public readonly ArrayBuilder Edits; public readonly ArrayBuilder ReferenceFrames; public readonly Dictionary AttributeDiffSet; + public readonly StackObjectPool> KeyedItemInfoDictionaryPool; public readonly int ComponentId; public int SiblingIndex; @@ -736,6 +841,7 @@ public DiffContext( Edits = batchBuilder.EditsBuffer; ReferenceFrames = batchBuilder.ReferenceFramesBuffer; AttributeDiffSet = batchBuilder.AttributeDiffSet; + KeyedItemInfoDictionaryPool = batchBuilder.KeyedItemInfoDictionaryPool; SiblingIndex = 0; } } diff --git a/src/Components/Components/src/Rendering/KeyedItemInfo.cs b/src/Components/Components/src/Rendering/KeyedItemInfo.cs new file mode 100644 index 000000000000..4e85e7dbef40 --- /dev/null +++ b/src/Components/Components/src/Rendering/KeyedItemInfo.cs @@ -0,0 +1,13 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +namespace Microsoft.AspNetCore.Components.Rendering +{ + // Used internally during diffing to track what we know about + // keyed items and their positions + internal struct KeyedItemInfo + { + public int OldIndex; + public int NewIndex; + } +} diff --git a/src/Components/Components/src/Rendering/RenderBatchBuilder.cs b/src/Components/Components/src/Rendering/RenderBatchBuilder.cs index 4bcdd82d0aaf..71a9cad8fa70 100644 --- a/src/Components/Components/src/Rendering/RenderBatchBuilder.cs +++ b/src/Components/Components/src/Rendering/RenderBatchBuilder.cs @@ -30,6 +30,9 @@ internal class RenderBatchBuilder // Scratch data structure for understanding attribute diffs. public Dictionary AttributeDiffSet { get; } = new Dictionary(); + internal StackObjectPool> KeyedItemInfoDictionaryPool { get; } + = new StackObjectPool>(maxPreservedItems: 10); + public void ClearStateForCurrentBatch() { // This method is used to reset the builder back to a default state so it can diff --git a/src/Components/Components/test/RenderTreeDiffBuilderTest.cs b/src/Components/Components/test/RenderTreeDiffBuilderTest.cs index caafa7c7d599..594a51c04c5a 100644 --- a/src/Components/Components/test/RenderTreeDiffBuilderTest.cs +++ b/src/Components/Components/test/RenderTreeDiffBuilderTest.cs @@ -103,6 +103,152 @@ public void RecognizesOldItemsBeingRemoved() entry => AssertEdit(entry, RenderTreeEditType.RemoveFrame, 1)); } + [Fact] + public void RecognizesKeyedElementInsertions() + { + // Arrange + oldTree.OpenElement(0, "container"); + oldTree.SetKey("retained key"); + oldTree.AddContent(1, "Existing"); + oldTree.CloseElement(); + + newTree.OpenElement(0, "container"); + newTree.SetKey("new key"); + newTree.AddContent(1, "Inserted"); + newTree.CloseElement(); + + newTree.OpenElement(0, "container"); + newTree.SetKey("retained key"); + newTree.AddContent(1, "Existing"); + newTree.CloseElement(); + + // Without the key, it would change the text "Existing" to "Inserted", then insert a new "Existing" below it + // With the key, it just inserts a new "Inserted" at the top + + // Act + var (result, referenceFrames) = GetSingleUpdatedComponent(); + + // Assert + Assert.Collection(result.Edits, + entry => + { + AssertEdit(entry, RenderTreeEditType.PrependFrame, 0); + Assert.Equal(0, entry.ReferenceFrameIndex); + Assert.Equal("new key", referenceFrames[entry.ReferenceFrameIndex].ElementKey); + }); + } + + [Fact] + public void RecognizesKeyedElementDeletions() + { + // Arrange + oldTree.OpenElement(0, "container"); + oldTree.SetKey("will delete"); + oldTree.AddContent(1, "First"); + oldTree.CloseElement(); + + oldTree.OpenElement(0, "container"); + oldTree.SetKey("will retain"); + oldTree.AddContent(1, "Second"); + oldTree.CloseElement(); + + newTree.OpenElement(0, "container"); + newTree.SetKey("will retain"); + newTree.AddContent(1, "Second"); + newTree.CloseElement(); + + // Without the key, it changes the text content of "First" to "Second", then deletes the other "Second" + // With the key, it just deletes "First" + + // Act + var (result, referenceFrames) = GetSingleUpdatedComponent(); + + // Assert + Assert.Collection(result.Edits, + entry => AssertEdit(entry, RenderTreeEditType.RemoveFrame, 0)); + } + + [Fact] + public void RecognizesKeyedComponentInsertions() + { + // Arrange + oldTree.OpenComponent(0); + oldTree.SetKey("retained key"); + oldTree.AddAttribute(1, "ParamName", "Param old value"); + oldTree.CloseComponent(); + GetRenderedBatch(new RenderTreeBuilder(renderer), oldTree, false); // Assign initial IDs + var oldComponent = (CaptureSetParametersComponent)oldTree.GetFrames().AsEnumerable().First().Component; + + newTree.OpenComponent(0); + newTree.SetKey("new key"); + newTree.AddAttribute(1, "ParamName", "New component param value"); + newTree.CloseComponent(); + + newTree.OpenComponent(0); + newTree.SetKey("retained key"); + newTree.AddAttribute(1, "ParamName", "Param new value"); + newTree.CloseComponent(); + + // Without the key, it would modify the param on the first component, + // then insert a new second component. + // With the key, it inserts a new first component, then modifies the + // param on the second component. + + // Act + var batch = GetRenderedBatch(initializeFromFrames: false); + var newComponents = newTree.GetFrames().AsEnumerable() + .Where(x => x.FrameType == RenderTreeFrameType.Component) + .Select(x => x.Component).Cast().ToList(); + + // Assert: Inserts new component at position 0 + Assert.Equal(1, batch.UpdatedComponents.Count); + Assert.Collection(batch.UpdatedComponents.Array[0].Edits, + entry => AssertEdit(entry, RenderTreeEditType.PrependFrame, 0)); + + // Assert: Retains old component instance in position 1, and updates its params + Assert.Same(oldComponent, newComponents[1]); + Assert.Equal(2, oldComponent.SetParametersCallCount); + } + + [Fact] + public void RecognizesKeyedComponentDeletions() + { + // Arrange + oldTree.OpenComponent(0); + oldTree.SetKey("will delete"); + oldTree.AddAttribute(1, nameof(FakeComponent.StringProperty), "Anything"); + oldTree.CloseComponent(); + + oldTree.OpenComponent(0); + oldTree.SetKey("will retain"); + oldTree.AddAttribute(1, nameof(FakeComponent.StringProperty), "Retained param value"); + oldTree.CloseComponent(); + + // Instantiate initial components + GetRenderedBatch(new RenderTreeBuilder(renderer), oldTree, false); + var oldComponents = oldTree.GetFrames().AsEnumerable() + .Where(x => x.FrameType == RenderTreeFrameType.Component) + .Select(x => x.Component).ToList(); + + newTree.OpenComponent(0); + newTree.SetKey("will retain"); + newTree.AddAttribute(1, nameof(FakeComponent.StringProperty), "Retained param value"); + newTree.CloseComponent(); + + // Without the key, it updates the param on the first component, then + // deletes the second. + // With the key, it just deletes the first. + + // Act + var (result, referenceFrames) = GetSingleUpdatedComponent(); + var newComponent = newTree.GetFrames().AsEnumerable().First().Component; + + // Assert + Assert.Same(oldComponents[1], newComponent); + Assert.Collection(result.Edits, + entry => AssertEdit(entry, RenderTreeEditType.RemoveFrame, 0)); + } + [Fact] public void RecognizesTrailingSequenceWithinLoopBlockBeingRemoved() { From 4d7d9acec91108827a6c7294bd1f8e49677a1a85 Mon Sep 17 00:00:00 2001 From: Steve Sanderson Date: Mon, 29 Apr 2019 18:44:17 +0100 Subject: [PATCH 04/33] Refactor AppendDiffEntriesForRange to prepare for adding "move" logic --- .../src/RenderTree/RenderTreeDiffBuilder.cs | 195 +++++++++--------- .../test/RenderTreeDiffBuilderTest.cs | 72 +++++++ 2 files changed, 173 insertions(+), 94 deletions(-) diff --git a/src/Components/Components/src/RenderTree/RenderTreeDiffBuilder.cs b/src/Components/Components/src/RenderTree/RenderTreeDiffBuilder.cs index 807f6d9b534f..d79c345fdd8e 100644 --- a/src/Components/Components/src/RenderTree/RenderTreeDiffBuilder.cs +++ b/src/Components/Components/src/RenderTree/RenderTreeDiffBuilder.cs @@ -3,13 +3,14 @@ using System; using System.Collections.Generic; -using Microsoft.AspNetCore.Components; using Microsoft.AspNetCore.Components.Rendering; namespace Microsoft.AspNetCore.Components.RenderTree { internal static class RenderTreeDiffBuilder { + enum DiffAction { Match, Insert, Delete } + public static RenderTreeDiff ComputeDiff( Renderer renderer, RenderBatchBuilder batchBuilder, @@ -35,6 +36,15 @@ private static void AppendDiffEntriesForRange( int oldStartIndex, int oldEndIndexExcl, int newStartIndex, int newEndIndexExcl) { + // This is deliberately a very large method. Parts of it could be factored out + // into other private methods, but doing so comes at a consequential perf cost, + // because it involves so much parameter passing. You can think of the code here + // as being several private methods (delimited by #region) pre-inlined. + // + // A naive "extract methods"-type refactoring will worsen perf by about 10%. So, + // if you plan to refactor this, be sure to benchmark the old and new versions + // on Mono WebAssembly. + var hasMoreOld = oldEndIndexExcl > oldStartIndex; var hasMoreNew = newEndIndexExcl > newStartIndex; var prevOldSeq = -1; @@ -47,35 +57,28 @@ private static void AppendDiffEntriesForRange( { while (hasMoreOld || hasMoreNew) { + DiffAction action; var oldSeq = hasMoreOld ? oldTree[oldStartIndex].Sequence : int.MaxValue; var newSeq = hasMoreNew ? newTree[newStartIndex].Sequence : int.MaxValue; - var isSeqMatch = oldSeq == newSeq; - var isSeqAndKeyMatch = isSeqMatch && IsKeyMatch(ref oldTree[oldStartIndex], ref newTree[newStartIndex]); - if (isSeqAndKeyMatch) + if (oldSeq == newSeq) { - AppendDiffEntriesForFramesWithSameSequence(ref diffContext, oldStartIndex, newStartIndex); - oldStartIndex = NextSiblingIndex(oldTree[oldStartIndex], oldStartIndex); - newStartIndex = NextSiblingIndex(newTree[newStartIndex], newStartIndex); - hasMoreOld = oldEndIndexExcl > oldStartIndex; - hasMoreNew = newEndIndexExcl > newStartIndex; - prevOldSeq = oldSeq; - prevNewSeq = newSeq; - } - else - { - bool treatAsInsert; - - if (isSeqMatch) + #region "Get diff action for matching sequence numbers" + var oldKey = KeyValue(ref oldTree[oldStartIndex]); + var newKey = KeyValue(ref newTree[newStartIndex]); + if (Equals(oldKey, newKey)) { - // Mismatched on key only + // Sequence and keys match + action = DiffAction.Match; + } + else + { + // Sequence matches, but key doesn't if (keyedItemInfos == null) { keyedItemInfos = BuildKeyToInfoLookup(diffContext, oldStartIndex, oldEndIndexExcl, newStartIndex, newEndIndexExcl); } - var oldKey = KeyValue(ref oldTree[oldStartIndex]); - var newKey = KeyValue(ref newTree[newStartIndex]); var oldKeyIsInNewTree = oldKey != null && keyedItemInfos[oldKey].NewIndex >= 0; var newKeyIsInOldTree = newKey != null && keyedItemInfos[newKey].OldIndex >= 0; if (oldKeyIsInNewTree && newKeyIsInOldTree) @@ -85,90 +88,108 @@ private static void AppendDiffEntriesForRange( } else { - // It's an insertion or a deletion - treatAsInsert = !newKeyIsInOldTree; + // It's an insertion or a deletion, or both + // If the new key is in both trees, but the old key isn't, then the old item was deleted + // Otherwise, it's either an insertion or *both* insertion+deletion, so pick insertion and get the deletion on the next iteration if needed + action = newKeyIsInOldTree ? DiffAction.Delete: DiffAction.Insert; } } - else + #endregion + } + else + { + #region "Get diff action for non-matching sequence numbers" + // Sequence doesn't match + var oldLoopedBack = oldSeq <= prevOldSeq; + var newLoopedBack = newSeq <= prevNewSeq; + if (oldLoopedBack == newLoopedBack) { - var oldLoopedBack = oldSeq <= prevOldSeq; - var newLoopedBack = newSeq <= prevNewSeq; - if (oldLoopedBack == newLoopedBack) - { - // Both sequences are proceeding through the same loop block, so do a simple - // preordered merge join (picking from whichever side brings us closer to being - // back in sync) - treatAsInsert = newSeq < oldSeq; + // Both sequences are proceeding through the same loop block, so do a simple + // preordered merge join (picking from whichever side brings us closer to being + // back in sync) + action = newSeq < oldSeq ? DiffAction.Insert : DiffAction.Delete; - if (oldLoopedBack) - { - // If both old and new have now looped back, we must reset their 'looped back' - // tracker so we can treat them as proceeding through the same loop block - prevOldSeq = prevNewSeq = -1; - } + if (oldLoopedBack) + { + // If both old and new have now looped back, we must reset their 'looped back' + // tracker so we can treat them as proceeding through the same loop block + prevOldSeq = prevNewSeq = -1; } - else if (oldLoopedBack) + } + else if (oldLoopedBack) + { + // Old sequence looped back but new one didn't + // The new sequence either has some extra trailing elements in the current loop block + // which we should insert, or omits some old trailing loop blocks which we should delete + // TODO: Find a way of not recomputing this next flag on every iteration + var newLoopsBackLater = false; + for (var testIndex = newStartIndex + 1; testIndex < newEndIndexExcl; testIndex++) { - // Old sequence looped back but new one didn't - // The new sequence either has some extra trailing elements in the current loop block - // which we should insert, or omits some old trailing loop blocks which we should delete - // TODO: Find a way of not recomputing this next flag on every iteration - var newLoopsBackLater = false; - for (var testIndex = newStartIndex + 1; testIndex < newEndIndexExcl; testIndex++) + if (newTree[testIndex].Sequence < newSeq) { - if (newTree[testIndex].Sequence < newSeq) - { - newLoopsBackLater = true; - break; - } + newLoopsBackLater = true; + break; } - - // If the new sequence loops back later to an earlier point than this, - // then we know it's part of the existing loop block (so should be inserted). - // If not, then it's unrelated to the previous loop block (so we should treat - // the old items as trailing loop blocks to be removed). - treatAsInsert = newLoopsBackLater; } - else + + // If the new sequence loops back later to an earlier point than this, + // then we know it's part of the existing loop block (so should be inserted). + // If not, then it's unrelated to the previous loop block (so we should treat + // the old items as trailing loop blocks to be removed). + action = newLoopsBackLater ? DiffAction.Insert : DiffAction.Delete; + } + else + { + // New sequence looped back but old one didn't + // The old sequence either has some extra trailing elements in the current loop block + // which we should delete, or the new sequence has extra trailing loop blocks which we + // should insert + // TODO: Find a way of not recomputing this next flag on every iteration + var oldLoopsBackLater = false; + for (var testIndex = oldStartIndex + 1; testIndex < oldEndIndexExcl; testIndex++) { - // New sequence looped back but old one didn't - // The old sequence either has some extra trailing elements in the current loop block - // which we should delete, or the new sequence has extra trailing loop blocks which we - // should insert - // TODO: Find a way of not recomputing this next flag on every iteration - var oldLoopsBackLater = false; - for (var testIndex = oldStartIndex + 1; testIndex < oldEndIndexExcl; testIndex++) + if (oldTree[testIndex].Sequence < oldSeq) { - if (oldTree[testIndex].Sequence < oldSeq) - { - oldLoopsBackLater = true; - break; - } + oldLoopsBackLater = true; + break; } - - // If the old sequence loops back later to an earlier point than this, - // then we know it's part of the existing loop block (so should be removed). - // If not, then it's unrelated to the previous loop block (so we should treat - // the new items as trailing loop blocks to be inserted). - treatAsInsert = !oldLoopsBackLater; } + + // If the old sequence loops back later to an earlier point than this, + // then we know it's part of the existing loop block (so should be removed). + // If not, then it's unrelated to the previous loop block (so we should treat + // the new items as trailing loop blocks to be inserted). + action = oldLoopsBackLater ? DiffAction.Delete : DiffAction.Insert; } + #endregion + } - if (treatAsInsert) - { + #region "Apply diff action" + switch (action) + { + case DiffAction.Match: + AppendDiffEntriesForFramesWithSameSequence(ref diffContext, oldStartIndex, newStartIndex); + oldStartIndex = NextSiblingIndex(oldTree[oldStartIndex], oldStartIndex); + newStartIndex = NextSiblingIndex(newTree[newStartIndex], newStartIndex); + hasMoreOld = oldEndIndexExcl > oldStartIndex; + hasMoreNew = newEndIndexExcl > newStartIndex; + prevOldSeq = oldSeq; + prevNewSeq = newSeq; + break; + case DiffAction.Insert: InsertNewFrame(ref diffContext, newStartIndex); newStartIndex = NextSiblingIndex(newTree[newStartIndex], newStartIndex); hasMoreNew = newEndIndexExcl > newStartIndex; prevNewSeq = newSeq; - } - else - { + break; + case DiffAction.Delete: RemoveOldFrame(ref diffContext, oldStartIndex); oldStartIndex = NextSiblingIndex(oldTree[oldStartIndex], oldStartIndex); hasMoreOld = oldEndIndexExcl > oldStartIndex; prevOldSeq = oldSeq; - } + break; } + #endregion } } finally @@ -216,20 +237,6 @@ private static Dictionary BuildKeyToInfoLookup(DiffContex return result; } - private static bool IsKeyMatch(ref RenderTreeFrame frame1, ref RenderTreeFrame frame2) - { - switch (frame1.FrameType) - { - case RenderTreeFrameType.Element: - return Equals(frame1.ElementKey, frame2.ElementKey); - case RenderTreeFrameType.Component: - return Equals(frame1.ComponentKey, frame2.ComponentKey); - default: - // Other frame types don't have keys, so they are always considered matchable - return true; - } - } - private static object KeyValue(ref RenderTreeFrame frame) { switch (frame.FrameType) diff --git a/src/Components/Components/test/RenderTreeDiffBuilderTest.cs b/src/Components/Components/test/RenderTreeDiffBuilderTest.cs index 594a51c04c5a..b393d7ac88b6 100644 --- a/src/Components/Components/test/RenderTreeDiffBuilderTest.cs +++ b/src/Components/Components/test/RenderTreeDiffBuilderTest.cs @@ -168,6 +168,37 @@ public void RecognizesKeyedElementDeletions() entry => AssertEdit(entry, RenderTreeEditType.RemoveFrame, 0)); } + [Fact] + public void RecognizesSimultaneousKeyedElementInsertionsAndDeletions() + { + // Arrange + oldTree.OpenElement(0, "container"); + oldTree.SetKey("original key"); + oldTree.AddContent(1, "Original"); + oldTree.CloseElement(); + + newTree.OpenElement(0, "container"); + newTree.SetKey("new key"); + newTree.AddContent(1, "Inserted"); + newTree.CloseElement(); + + // Without the key, it would change the text "Original" to "Inserted" + // With the key, it deletes the old element and inserts the new element + + // Act + var (result, referenceFrames) = GetSingleUpdatedComponent(); + + // Assert + Assert.Collection(result.Edits, + entry => + { + AssertEdit(entry, RenderTreeEditType.PrependFrame, 0); + Assert.Equal(0, entry.ReferenceFrameIndex); + Assert.Equal("new key", referenceFrames[entry.ReferenceFrameIndex].ElementKey); + }, + entry => AssertEdit(entry, RenderTreeEditType.RemoveFrame, 1)); + } + [Fact] public void RecognizesKeyedComponentInsertions() { @@ -249,6 +280,47 @@ public void RecognizesKeyedComponentDeletions() entry => AssertEdit(entry, RenderTreeEditType.RemoveFrame, 0)); } + [Fact] + public void RecognizesSimultaneousKeyedComponentInsertionsAndDeletions() + { + // Arrange + oldTree.OpenComponent(0); + oldTree.SetKey("original key"); + oldTree.CloseComponent(); + + // Instantiate initial component + GetRenderedBatch(new RenderTreeBuilder(renderer), oldTree, false); + var oldComponent = oldTree.GetFrames().AsEnumerable() + .Where(x => x.FrameType == RenderTreeFrameType.Component) + .Select(x => x.Component).Single(); + Assert.NotNull(oldComponent); + + newTree.OpenComponent(0); + newTree.SetKey("new key"); + newTree.CloseComponent(); + + // Without the key, it would retain the component + // With the key, it deletes the old component and inserts the new component + + // Act + var (result, referenceFrames) = GetSingleUpdatedComponent(); + var newComponent = newTree.GetFrames().AsEnumerable() + .Where(x => x.FrameType == RenderTreeFrameType.Component) + .Select(x => x.Component).Single(); + + // Assert + Assert.NotNull(newComponent); + Assert.NotSame(oldComponent, newComponent); + Assert.Collection(result.Edits, + entry => + { + AssertEdit(entry, RenderTreeEditType.PrependFrame, 0); + Assert.Equal(0, entry.ReferenceFrameIndex); + Assert.Equal("new key", referenceFrames[entry.ReferenceFrameIndex].ComponentKey); + }, + entry => AssertEdit(entry, RenderTreeEditType.RemoveFrame, 1)); + } + [Fact] public void RecognizesTrailingSequenceWithinLoopBlockBeingRemoved() { From f9e27c83677d59f1afe875c7bcf1ac471d5838e8 Mon Sep 17 00:00:00 2001 From: Steve Sanderson Date: Tue, 30 Apr 2019 10:57:06 +0100 Subject: [PATCH 05/33] Handle keyed moves by writing a post-edit permutation list --- .../src/RenderTree/RenderTreeDiffBuilder.cs | 49 +++- .../src/RenderTree/RenderTreeEdit.cs | 29 +- .../src/RenderTree/RenderTreeEditType.cs | 13 + .../Components/src/Rendering/KeyedItemInfo.cs | 2 + .../test/RenderTreeDiffBuilderTest.cs | 247 +++++++++++++++++- .../ComponentsApp.App.csproj | 3 +- 6 files changed, 317 insertions(+), 26 deletions(-) diff --git a/src/Components/Components/src/RenderTree/RenderTreeDiffBuilder.cs b/src/Components/Components/src/RenderTree/RenderTreeDiffBuilder.cs index d79c345fdd8e..6e46c4d4f210 100644 --- a/src/Components/Components/src/RenderTree/RenderTreeDiffBuilder.cs +++ b/src/Components/Components/src/RenderTree/RenderTreeDiffBuilder.cs @@ -51,6 +51,7 @@ private static void AppendDiffEntriesForRange( var prevNewSeq = -1; var oldTree = diffContext.OldTree; var newTree = diffContext.NewTree; + var matchWithNewTreeIndex = -1; // Only used when action == DiffAction.Match Dictionary keyedItemInfos = null; try @@ -70,6 +71,7 @@ private static void AppendDiffEntriesForRange( { // Sequence and keys match action = DiffAction.Match; + matchWithNewTreeIndex = newStartIndex; } else { @@ -79,12 +81,27 @@ private static void AppendDiffEntriesForRange( keyedItemInfos = BuildKeyToInfoLookup(diffContext, oldStartIndex, oldEndIndexExcl, newStartIndex, newEndIndexExcl); } - var oldKeyIsInNewTree = oldKey != null && keyedItemInfos[oldKey].NewIndex >= 0; - var newKeyIsInOldTree = newKey != null && keyedItemInfos[newKey].OldIndex >= 0; + var oldKeyItemInfo = keyedItemInfos[oldKey]; + var newKeyItemInfo = keyedItemInfos[newKey]; + var oldKeyIsInNewTree = oldKey != null && oldKeyItemInfo.NewIndex >= 0; + var newKeyIsInOldTree = newKey != null && newKeyItemInfo.OldIndex >= 0; if (oldKeyIsInNewTree && newKeyIsInOldTree) { // It's a move - throw new NotImplementedException("Not yet supported: moving items by key"); + // Since the recipient of the diff script already has the old frame (the one with oldKey) + // at the current siblingIndex, recurse into oldKey and update its descendants in place. + // We re-order the frames afterwards. + action = DiffAction.Match; + matchWithNewTreeIndex = oldKeyItemInfo.NewIndex; + + // Track the post-edit sibling indices of the moved items + // Since diffContext.SiblingIndex only increases, we can be sure the values we + // write at this point will remain correct, because there won't be any further + // insertions/deletions at smaller sibling indices. + oldKeyItemInfo.OldSiblingIndex = diffContext.SiblingIndex; + keyedItemInfos[oldKey] = oldKeyItemInfo; + newKeyItemInfo.NewSiblingIndex = diffContext.SiblingIndex; + keyedItemInfos[newKey] = newKeyItemInfo; } else { @@ -168,7 +185,7 @@ private static void AppendDiffEntriesForRange( switch (action) { case DiffAction.Match: - AppendDiffEntriesForFramesWithSameSequence(ref diffContext, oldStartIndex, newStartIndex); + AppendDiffEntriesForFramesWithSameSequence(ref diffContext, oldStartIndex, matchWithNewTreeIndex); oldStartIndex = NextSiblingIndex(oldTree[oldStartIndex], oldStartIndex); newStartIndex = NextSiblingIndex(newTree[newStartIndex], newStartIndex); hasMoreOld = oldEndIndexExcl > oldStartIndex; @@ -196,6 +213,30 @@ private static void AppendDiffEntriesForRange( { if (keyedItemInfos != null) { + #region "Write permutations list" + var hasPermutations = false; + foreach (var keyValuePair in keyedItemInfos) + { + var value = keyValuePair.Value; + var oldSiblingIndex = value.OldSiblingIndex; + var newSiblingIndex = value.NewSiblingIndex; + if (oldSiblingIndex.HasValue && newSiblingIndex.HasValue) + { + // This item moved + hasPermutations = true; + diffContext.Edits.Append( + RenderTreeEdit.PermutationListEntry(oldSiblingIndex.Value, newSiblingIndex.Value)); + } + } + + if (hasPermutations) + { + // It's much easier for the recipient to handle if we're explicit about + // when the list is finished + diffContext.Edits.Append(RenderTreeEdit.PermutationListEnd()); + } + #endregion + keyedItemInfos.Clear(); diffContext.KeyedItemInfoDictionaryPool.Return(keyedItemInfos); } diff --git a/src/Components/Components/src/RenderTree/RenderTreeEdit.cs b/src/Components/Components/src/RenderTree/RenderTreeEdit.cs index d7c0daa7b160..68222f4f517a 100644 --- a/src/Components/Components/src/RenderTree/RenderTreeEdit.cs +++ b/src/Components/Components/src/RenderTree/RenderTreeEdit.cs @@ -2,36 +2,44 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System; +using System.Runtime.InteropServices; namespace Microsoft.AspNetCore.Components.RenderTree { /// /// Represents a single edit operation on a component's render tree. /// + [StructLayout(LayoutKind.Explicit)] public readonly struct RenderTreeEdit { /// /// Gets the type of the edit operation. /// - public readonly RenderTreeEditType Type; + [FieldOffset(0)] public readonly RenderTreeEditType Type; /// /// Gets the index of the sibling frame that the edit relates to. /// - public readonly int SiblingIndex; + [FieldOffset(4)] public readonly int SiblingIndex; /// /// Gets the index of related data in an associated render frames array. For example, if the /// value is , gets the /// index of the new frame data in an associated render tree. /// - public readonly int ReferenceFrameIndex; + [FieldOffset(8)] public readonly int ReferenceFrameIndex; + + /// + /// If the value is , + /// gets the sibling index to which the frame should be moved. + /// + [FieldOffset(8)] public readonly int MoveToSiblingIndex; /// /// If the value is , /// gets the name of the attribute that is being removed. /// - public readonly string RemovedAttributeName; + [FieldOffset(16)] public readonly string RemovedAttributeName; private RenderTreeEdit(RenderTreeEditType type) : this() { @@ -44,11 +52,14 @@ private RenderTreeEdit(RenderTreeEditType type, int siblingIndex) : this() SiblingIndex = siblingIndex; } - private RenderTreeEdit(RenderTreeEditType type, int siblingIndex, int referenceFrameIndex) : this() + private RenderTreeEdit(RenderTreeEditType type, int siblingIndex, int referenceFrameOrMoveToSiblingIndex) : this() { Type = type; SiblingIndex = siblingIndex; - ReferenceFrameIndex = referenceFrameIndex; + + // MoveToSiblingIndex is stored in the same slot as ReferenceFrameIndex, + // so assigning to either one is equivalent + ReferenceFrameIndex = referenceFrameOrMoveToSiblingIndex; } private RenderTreeEdit(RenderTreeEditType type, int siblingIndex, string removedAttributeName) : this() @@ -81,5 +92,11 @@ internal static RenderTreeEdit StepIn(int siblingIndex) internal static RenderTreeEdit StepOut() => new RenderTreeEdit(RenderTreeEditType.StepOut); + + internal static RenderTreeEdit PermutationListEntry(int fromSiblingIndex, int toSiblingIndex) + => new RenderTreeEdit(RenderTreeEditType.PermutationListEntry, fromSiblingIndex, toSiblingIndex); + + internal static RenderTreeEdit PermutationListEnd() + => new RenderTreeEdit(RenderTreeEditType.PermutationListEnd); } } diff --git a/src/Components/Components/src/RenderTree/RenderTreeEditType.cs b/src/Components/Components/src/RenderTree/RenderTreeEditType.cs index aa7ca3a60428..c2f3e4aba692 100644 --- a/src/Components/Components/src/RenderTree/RenderTreeEditType.cs +++ b/src/Components/Components/src/RenderTree/RenderTreeEditType.cs @@ -51,5 +51,18 @@ public enum RenderTreeEditType: int /// should be updated. /// UpdateMarkup = 8, + + /// + /// An entry in a sparse permutation list. That is, a list of old indices with + /// corresponding new indices, which altogether describe a valid permutation of + /// the children at the current edit position. + /// + PermutationListEntry = 9, + + /// + /// Indicates that the preceding series of entries + /// is now complete. + /// + PermutationListEnd = 10, } } diff --git a/src/Components/Components/src/Rendering/KeyedItemInfo.cs b/src/Components/Components/src/Rendering/KeyedItemInfo.cs index 4e85e7dbef40..4dd08b46d933 100644 --- a/src/Components/Components/src/Rendering/KeyedItemInfo.cs +++ b/src/Components/Components/src/Rendering/KeyedItemInfo.cs @@ -9,5 +9,7 @@ internal struct KeyedItemInfo { public int OldIndex; public int NewIndex; + public int? OldSiblingIndex; + public int? NewSiblingIndex; } } diff --git a/src/Components/Components/test/RenderTreeDiffBuilderTest.cs b/src/Components/Components/test/RenderTreeDiffBuilderTest.cs index b393d7ac88b6..bfcf31a68d88 100644 --- a/src/Components/Components/test/RenderTreeDiffBuilderTest.cs +++ b/src/Components/Components/test/RenderTreeDiffBuilderTest.cs @@ -208,7 +208,7 @@ public void RecognizesKeyedComponentInsertions() oldTree.AddAttribute(1, "ParamName", "Param old value"); oldTree.CloseComponent(); GetRenderedBatch(new RenderTreeBuilder(renderer), oldTree, false); // Assign initial IDs - var oldComponent = (CaptureSetParametersComponent)oldTree.GetFrames().AsEnumerable().First().Component; + var oldComponent = GetComponents(oldTree).Single(); newTree.OpenComponent(0); newTree.SetKey("new key"); @@ -227,9 +227,7 @@ public void RecognizesKeyedComponentInsertions() // Act var batch = GetRenderedBatch(initializeFromFrames: false); - var newComponents = newTree.GetFrames().AsEnumerable() - .Where(x => x.FrameType == RenderTreeFrameType.Component) - .Select(x => x.Component).Cast().ToList(); + var newComponents = GetComponents(newTree); // Assert: Inserts new component at position 0 Assert.Equal(1, batch.UpdatedComponents.Count); @@ -257,9 +255,7 @@ public void RecognizesKeyedComponentDeletions() // Instantiate initial components GetRenderedBatch(new RenderTreeBuilder(renderer), oldTree, false); - var oldComponents = oldTree.GetFrames().AsEnumerable() - .Where(x => x.FrameType == RenderTreeFrameType.Component) - .Select(x => x.Component).ToList(); + var oldComponents = GetComponents(oldTree); newTree.OpenComponent(0); newTree.SetKey("will retain"); @@ -272,7 +268,7 @@ public void RecognizesKeyedComponentDeletions() // Act var (result, referenceFrames) = GetSingleUpdatedComponent(); - var newComponent = newTree.GetFrames().AsEnumerable().First().Component; + var newComponent = GetComponents(newTree).Single(); // Assert Assert.Same(oldComponents[1], newComponent); @@ -290,9 +286,7 @@ public void RecognizesSimultaneousKeyedComponentInsertionsAndDeletions() // Instantiate initial component GetRenderedBatch(new RenderTreeBuilder(renderer), oldTree, false); - var oldComponent = oldTree.GetFrames().AsEnumerable() - .Where(x => x.FrameType == RenderTreeFrameType.Component) - .Select(x => x.Component).Single(); + var oldComponent = GetComponents(oldTree).Single(); Assert.NotNull(oldComponent); newTree.OpenComponent(0); @@ -304,9 +298,7 @@ public void RecognizesSimultaneousKeyedComponentInsertionsAndDeletions() // Act var (result, referenceFrames) = GetSingleUpdatedComponent(); - var newComponent = newTree.GetFrames().AsEnumerable() - .Where(x => x.FrameType == RenderTreeFrameType.Component) - .Select(x => x.Component).Single(); + var newComponent = GetComponents(newTree).Single(); // Assert Assert.NotNull(newComponent); @@ -1710,6 +1702,207 @@ public void DoesNotInvokeAssignerAgainForRetainedComponents() Assert.Empty(referenceFrames); } + [Fact] + public void RecognizesKeyedElementMoves() + { + // Arrange + oldTree.OpenElement(0, "container"); + oldTree.SetKey("first key"); + oldTree.AddContent(1, "First"); + oldTree.CloseElement(); + + oldTree.AddContent(2, "Unkeyed item"); + + oldTree.OpenElement(0, "container"); + oldTree.SetKey("second key"); + oldTree.AddContent(1, "Second"); + oldTree.CloseElement(); + + newTree.OpenElement(0, "container"); + newTree.SetKey("second key"); + newTree.AddContent(1, "Second"); + newTree.CloseElement(); + + newTree.AddContent(2, "Unkeyed item"); + + newTree.OpenElement(0, "container"); + newTree.SetKey("first key"); + newTree.AddContent(1, "First modified"); + newTree.CloseElement(); + + // Without the key, it changes the text contents of both + // With the key, it reorders them and just updates the text content of one + + // Act + var (result, referenceFrames) = GetSingleUpdatedComponent(); + + // Assert + Assert.Collection(result.Edits, + // First we update the modified descendants in place + entry => AssertEdit(entry, RenderTreeEditType.StepIn, 0), + entry => + { + AssertEdit(entry, RenderTreeEditType.UpdateText, 0); + Assert.Equal(0, entry.ReferenceFrameIndex); + Assert.Equal("First modified", referenceFrames[entry.ReferenceFrameIndex].TextContent); + }, + entry => AssertEdit(entry, RenderTreeEditType.StepOut, 0), + + // Then we have the permutation list + entry => AssertPermutationListEntry(entry, 0, 2), + entry => AssertPermutationListEntry(entry, 2, 0), + entry => AssertEdit(entry, RenderTreeEditType.PermutationListEnd, 0)); + } + + [Fact] + public void RecognizesKeyedComponentMoves() + { + // Arrange + oldTree.OpenComponent(0); + oldTree.SetKey("first key"); + oldTree.AddAttribute(1, nameof(FakeComponent.StringProperty), "First param"); + oldTree.CloseComponent(); + + oldTree.AddContent(2, "Unkeyed item"); + + oldTree.OpenComponent(0); + oldTree.SetKey("second key"); + oldTree.AddAttribute(1, nameof(FakeComponent.StringProperty), "Second param"); + oldTree.CloseComponent(); + + GetRenderedBatch(new RenderTreeBuilder(renderer), oldTree, false); // Assign initial IDs + var oldComponents = GetComponents(oldTree); + + newTree.OpenComponent(0); + newTree.SetKey("second key"); + newTree.AddAttribute(1, nameof(FakeComponent.StringProperty), "Second param"); + newTree.CloseComponent(); + + newTree.AddContent(2, "Unkeyed item"); + + newTree.OpenComponent(0); + newTree.SetKey("first key"); + newTree.AddAttribute(1, nameof(FakeComponent.StringProperty), "First param modified"); + newTree.CloseComponent(); + + // Without the key, it changes the parameter on both + // With the key, it reorders them and just updates the parameter of one + + // Act + var (result, referenceFrames) = GetSingleUpdatedComponent(); + var newComponents = GetComponents(newTree); + + // Assert: Retains component instances + Assert.Same(oldComponents[0], newComponents[1]); + Assert.Same(oldComponents[1], newComponents[0]); + + // Assert: Supplies updated params only to (originally) first component + Assert.Equal(2, oldComponents[0].SetParametersCallCount); + Assert.Equal(1, oldComponents[1].SetParametersCallCount); + + // Assert: Correct diff + Assert.Collection(result.Edits, + entry => AssertPermutationListEntry(entry, 0, 2), + entry => AssertPermutationListEntry(entry, 2, 0), + entry => AssertEdit(entry, RenderTreeEditType.PermutationListEnd, 0)); + } + + [Fact] + public void CanMoveBeforeInsertedItem() + { + // Arrange + AddWithKey(oldTree, "will retain"); + AddWithKey(oldTree, "will move"); + + AddWithKey(newTree, "will move"); + AddWithKey(newTree, "newly inserted"); + AddWithKey(newTree, "will retain"); + + // Act + var (result, referenceFrames) = GetSingleUpdatedComponent(); + + // Assert + Assert.Collection(result.Edits, + entry => { + AssertEdit(entry, RenderTreeEditType.PrependFrame, 1); + Assert.Equal(0, entry.ReferenceFrameIndex); + Assert.Equal("newly inserted", referenceFrames[entry.ReferenceFrameIndex].ElementKey); + }, + entry => AssertPermutationListEntry(entry, 0, 2), + entry => AssertPermutationListEntry(entry, 2, 0), + entry => AssertEdit(entry, RenderTreeEditType.PermutationListEnd, 0)); + } + + [Fact] + public void CanMoveBeforeDeletedItem() + { + // Arrange + AddWithKey(oldTree, "will retain"); + AddWithKey(oldTree, "will delete"); + AddWithKey(oldTree, "will move"); + + AddWithKey(newTree, "will move"); + AddWithKey(newTree, "will retain"); + + // Act + var (result, referenceFrames) = GetSingleUpdatedComponent(); + + // Assert + Assert.Collection(result.Edits, + entry => AssertEdit(entry, RenderTreeEditType.RemoveFrame, 1), + entry => AssertPermutationListEntry(entry, 0, 1), + entry => AssertPermutationListEntry(entry, 1, 0), + entry => AssertEdit(entry, RenderTreeEditType.PermutationListEnd, 0)); + } + + [Fact] + public void CanMoveAfterInsertedItem() + { + // Arrange + AddWithKey(oldTree, "will move"); + AddWithKey(oldTree, "will retain"); + + AddWithKey(newTree, "newly inserted"); + AddWithKey(newTree, "will retain"); + AddWithKey(newTree, "will move"); + + // Act + var (result, referenceFrames) = GetSingleUpdatedComponent(); + + // Assert + Assert.Collection(result.Edits, + entry => { + AssertEdit(entry, RenderTreeEditType.PrependFrame, 0); + Assert.Equal(0, entry.ReferenceFrameIndex); + Assert.Equal("newly inserted", referenceFrames[entry.ReferenceFrameIndex].ElementKey); + }, + entry => AssertPermutationListEntry(entry, 1, 2), + entry => AssertPermutationListEntry(entry, 2, 1), + entry => AssertEdit(entry, RenderTreeEditType.PermutationListEnd, 0)); + } + + [Fact] + public void CanMoveAfterDeletedItem() + { + // Arrange + AddWithKey(oldTree, "will move"); + AddWithKey(oldTree, "will delete"); + AddWithKey(oldTree, "will retain"); + + AddWithKey(newTree, "will retain"); + AddWithKey(newTree, "will move"); + + // Act + var (result, referenceFrames) = GetSingleUpdatedComponent(); + + // Assert + Assert.Collection(result.Edits, + entry => AssertEdit(entry, RenderTreeEditType.RemoveFrame, 1), + entry => AssertPermutationListEntry(entry, 0, 1), + entry => AssertPermutationListEntry(entry, 1, 0), + entry => AssertEdit(entry, RenderTreeEditType.PermutationListEnd, 0)); + } + private (RenderTreeDiff, RenderTreeFrame[]) GetSingleUpdatedComponent(bool initializeFromFrames = false) { var result = GetSingleUpdatedComponentWithBatch(initializeFromFrames); @@ -1742,6 +1935,22 @@ private RenderBatch GetRenderedBatch(RenderTreeBuilder from, RenderTreeBuilder t return batchBuilder.ToBatch(); } + private static IList GetComponents(RenderTreeBuilder builder) + => GetComponents(builder); + + private static IList GetComponents(RenderTreeBuilder builder) where T : IComponent + => builder.GetFrames().AsEnumerable() + .Where(x => x.FrameType == RenderTreeFrameType.Component) + .Select(x => (T)x.Component) + .ToList(); + + private static void AddWithKey(RenderTreeBuilder builder, object key) + { + builder.OpenElement(0, "el"); + builder.SetKey(key); + builder.CloseElement(); + } + private class FakeRenderer : Renderer { public FakeRenderer() : base(new TestServiceProvider(), new RendererSynchronizationContext()) @@ -1831,5 +2040,15 @@ private static void AssertEdit( Assert.Equal(type, edit.Type); Assert.Equal(siblingIndex, edit.SiblingIndex); } + + private static void AssertPermutationListEntry( + RenderTreeEdit edit, + int fromSiblingIndex, + int toSiblingIndex) + { + Assert.Equal(RenderTreeEditType.PermutationListEntry, edit.Type); + Assert.Equal(fromSiblingIndex, edit.SiblingIndex); + Assert.Equal(toSiblingIndex, edit.MoveToSiblingIndex); + } } } diff --git a/src/Components/test/testassets/ComponentsApp.App/ComponentsApp.App.csproj b/src/Components/test/testassets/ComponentsApp.App/ComponentsApp.App.csproj index 3e79d4f6a18f..aa193e921049 100644 --- a/src/Components/test/testassets/ComponentsApp.App/ComponentsApp.App.csproj +++ b/src/Components/test/testassets/ComponentsApp.App/ComponentsApp.App.csproj @@ -1,4 +1,4 @@ - + netstandard2.0 @@ -11,4 +11,3 @@ - From b5d1cf001d9c8e0fefee18f99bb97c3ef06eadc2 Mon Sep 17 00:00:00 2001 From: Steve Sanderson Date: Tue, 30 Apr 2019 11:07:29 +0100 Subject: [PATCH 06/33] Shrink KeyedItemInfo struct --- .../src/RenderTree/RenderTreeDiffBuilder.cs | 12 +++++------- .../Components/src/Rendering/KeyedItemInfo.cs | 12 ++++++++++-- 2 files changed, 15 insertions(+), 9 deletions(-) diff --git a/src/Components/Components/src/RenderTree/RenderTreeDiffBuilder.cs b/src/Components/Components/src/RenderTree/RenderTreeDiffBuilder.cs index 6e46c4d4f210..fb557e8743cd 100644 --- a/src/Components/Components/src/RenderTree/RenderTreeDiffBuilder.cs +++ b/src/Components/Components/src/RenderTree/RenderTreeDiffBuilder.cs @@ -218,14 +218,12 @@ private static void AppendDiffEntriesForRange( foreach (var keyValuePair in keyedItemInfos) { var value = keyValuePair.Value; - var oldSiblingIndex = value.OldSiblingIndex; - var newSiblingIndex = value.NewSiblingIndex; - if (oldSiblingIndex.HasValue && newSiblingIndex.HasValue) + if (value.OldSiblingIndex >= 0 && value.NewSiblingIndex >= 0) { // This item moved hasPermutations = true; diffContext.Edits.Append( - RenderTreeEdit.PermutationListEntry(oldSiblingIndex.Value, newSiblingIndex.Value)); + RenderTreeEdit.PermutationListEntry(value.OldSiblingIndex, value.NewSiblingIndex)); } } @@ -255,7 +253,7 @@ private static Dictionary BuildKeyToInfoLookup(DiffContex var key = KeyValue(ref frame); if (key != null) { - result[key] = new KeyedItemInfo { OldIndex = oldStartIndex, NewIndex = -1 }; + result[key] = new KeyedItemInfo(oldStartIndex, -1); } oldStartIndex = NextSiblingIndex(frame, oldStartIndex); @@ -268,8 +266,8 @@ private static Dictionary BuildKeyToInfoLookup(DiffContex if (key != null) { result[key] = result.TryGetValue(key, out var existingEntry) - ? new KeyedItemInfo { OldIndex = existingEntry.OldIndex, NewIndex = newStartIndex } - : new KeyedItemInfo { OldIndex = -1, NewIndex = newStartIndex }; + ? new KeyedItemInfo(existingEntry.OldIndex, newStartIndex) + : new KeyedItemInfo(-1, newStartIndex); } newStartIndex = NextSiblingIndex(frame, newStartIndex); diff --git a/src/Components/Components/src/Rendering/KeyedItemInfo.cs b/src/Components/Components/src/Rendering/KeyedItemInfo.cs index 4dd08b46d933..7bd048d66920 100644 --- a/src/Components/Components/src/Rendering/KeyedItemInfo.cs +++ b/src/Components/Components/src/Rendering/KeyedItemInfo.cs @@ -9,7 +9,15 @@ internal struct KeyedItemInfo { public int OldIndex; public int NewIndex; - public int? OldSiblingIndex; - public int? NewSiblingIndex; + public int OldSiblingIndex; + public int NewSiblingIndex; + + public KeyedItemInfo(int oldIndex, int newIndex) + { + OldIndex = oldIndex; + NewIndex = newIndex; + OldSiblingIndex = -1; + NewSiblingIndex = -1; + } } } From 1d2b0d5a11904fdc7f4c2155f38ba9ae0365d8eb Mon Sep 17 00:00:00 2001 From: Steve Sanderson Date: Thu, 25 Apr 2019 22:43:11 +0100 Subject: [PATCH 07/33] Apply permutations on the JS side --- .../Browser.JS/dist/Debug/blazor.server.js | 87 +++++++++++++++++++ .../dist/Debug/blazor.webassembly.js | 87 ++++++++++++++++++- .../Browser.JS/dist/Release/blazor.server.js | 6 +- .../dist/Release/blazor.webassembly.js | 2 +- .../src/Rendering/BrowserRenderer.ts | 16 +++- .../src/Rendering/LogicalElements.ts | 86 ++++++++++++++++++ .../RenderBatch/OutOfProcessRenderBatch.ts | 4 + .../src/Rendering/RenderBatch/RenderBatch.ts | 3 + .../RenderBatch/SharedMemoryRenderBatch.ts | 3 +- .../src/RenderTree/RenderTreeEdit.cs | 3 + .../Server/src/Circuits/RenderBatchWriter.cs | 4 + 11 files changed, 294 insertions(+), 7 deletions(-) diff --git a/src/Components/Browser.JS/dist/Debug/blazor.server.js b/src/Components/Browser.JS/dist/Debug/blazor.server.js index 51fade0f26f1..a771ac064a74 100644 --- a/src/Components/Browser.JS/dist/Debug/blazor.server.js +++ b/src/Components/Browser.JS/dist/Debug/blazor.server.js @@ -13277,6 +13277,7 @@ var BrowserRenderer = /** @class */ (function () { BrowserRenderer.prototype.applyEdits = function (batch, parent, childIndex, edits, referenceFrames) { var currentDepth = 0; var childIndexAtCurrentDepth = childIndex; + var permutationList; var arraySegmentReader = batch.arraySegmentReader; var editReader = batch.editReader; var frameReader = batch.frameReader; @@ -13365,6 +13366,19 @@ var BrowserRenderer = /** @class */ (function () { childIndexAtCurrentDepth = currentDepth === 0 ? childIndex : 0; // The childIndex is only ever nonzero at zero depth break; } + case RenderBatch_1.EditType.permutationListEntry: { + permutationList = permutationList || []; + permutationList.push({ + fromSiblingIndex: childIndexAtCurrentDepth + editReader.siblingIndex(edit), + toSiblingIndex: childIndexAtCurrentDepth + editReader.moveToSiblingIndex(edit), + }); + break; + } + case RenderBatch_1.EditType.permutationListEnd: { + LogicalElements_1.permuteLogicalChildren(parent, permutationList); + permutationList = undefined; + break; + } default: { var unknownType = editType; // Compile-time verification that the switch was exhaustive throw new Error("Unknown edit type: " + unknownType); @@ -14169,6 +14183,54 @@ function getLogicalChildrenArray(element) { return element[logicalChildrenPropname]; } exports.getLogicalChildrenArray = getLogicalChildrenArray; +function permuteLogicalChildren(parent, permutationList) { + // The permutationList must represent a valid permutation, i.e., the list of 'from' indices + // is distinct, and the list of 'to' indices is a permutation of it. The algorithm here + // relies on that assumption. + // Each of the phases here has to happen separately, because each one is designed not to + // interfere with the indices or DOM entries used by subsequent phases. + // Phase 1: track which nodes we will move + var siblings = getLogicalChildrenArray(parent); + permutationList.forEach(function (listEntry) { + listEntry.moveRangeStart = siblings[listEntry.fromSiblingIndex]; + listEntry.moveRangeEnd = findLastDomNodeInRange(listEntry.moveRangeStart); + }); + // Phase 2: insert markers + permutationList.forEach(function (listEntry) { + var marker = listEntry.moveToBeforeMarker = document.createComment('marker'); + var insertBeforeNode = siblings[listEntry.toSiblingIndex + 1]; + if (insertBeforeNode) { + insertBeforeNode.parentNode.insertBefore(marker, insertBeforeNode); + } + else { + appendDomNode(marker, parent); + } + }); + // Phase 3: move descendants & remove markers + permutationList.forEach(function (listEntry) { + var insertBefore = listEntry.moveToBeforeMarker; + var parentDomNode = insertBefore.parentNode; + var elementToMove = listEntry.moveRangeStart; + var moveEndNode = listEntry.moveRangeEnd; + var nextToMove = elementToMove; + while (nextToMove) { + var nextNext = nextToMove.nextSibling; + parentDomNode.insertBefore(nextToMove, insertBefore); + if (nextToMove === moveEndNode) { + break; + } + else { + nextToMove = nextNext; + } + } + parentDomNode.removeChild(insertBefore); + }); + // Phase 4: update siblings index + permutationList.forEach(function (listEntry) { + siblings[listEntry.toSiblingIndex] = listEntry.moveRangeStart; + }); +} +exports.permuteLogicalChildren = permuteLogicalChildren; function getLogicalNextSibling(element) { var siblings = getLogicalChildrenArray(getLogicalParent(element)); var siblingIndex = Array.prototype.indexOf.call(siblings, element); @@ -14208,6 +14270,26 @@ function appendDomNode(child, parent) { throw new Error("Cannot append node because the parent is not a valid logical element. Parent: " + parent); } } +// Returns the final node (in depth-first evaluation order) that is a descendant of the logical element. +// As such, the entire subtree is between 'element' and 'findLastDomNodeInRange(element)' inclusive. +function findLastDomNodeInRange(element) { + if (element instanceof Element) { + return element; + } + var nextSibling = getLogicalNextSibling(element); + if (nextSibling) { + // Simple case: not the last logical sibling, so take the node before the next sibling + return nextSibling.previousSibling; + } + else { + // Harder case: there's no logical next-sibling, so recurse upwards until we find + // a logical ancestor that does have one, or a physical element + var logicalParent = getLogicalParent(element); + return logicalParent instanceof Element + ? logicalParent.lastChild + : findLastDomNodeInRange(logicalParent); + } +} function createSymbolOrFallback(fallback) { return typeof Symbol === 'function' ? Symbol() : fallback; } @@ -14303,6 +14385,9 @@ var OutOfProcessRenderTreeEditReader = /** @class */ (function () { OutOfProcessRenderTreeEditReader.prototype.newTreeIndex = function (edit) { return readInt32LE(this.batchDataUint8, edit + 8); // 3rd int }; + OutOfProcessRenderTreeEditReader.prototype.moveToSiblingIndex = function (edit) { + return readInt32LE(this.batchDataUint8, edit + 8); // 3rd int + }; OutOfProcessRenderTreeEditReader.prototype.removedAttributeName = function (edit) { var stringIndex = readInt32LE(this.batchDataUint8, edit + 12); // 4th int return this.stringReader.readString(stringIndex); @@ -14458,6 +14543,8 @@ var EditType; EditType[EditType["stepIn"] = 6] = "stepIn"; EditType[EditType["stepOut"] = 7] = "stepOut"; EditType[EditType["updateMarkup"] = 8] = "updateMarkup"; + EditType[EditType["permutationListEntry"] = 9] = "permutationListEntry"; + EditType[EditType["permutationListEnd"] = 10] = "permutationListEnd"; })(EditType = exports.EditType || (exports.EditType = {})); var FrameType; (function (FrameType) { diff --git a/src/Components/Browser.JS/dist/Debug/blazor.webassembly.js b/src/Components/Browser.JS/dist/Debug/blazor.webassembly.js index 4d36c8155195..956f93d6e0d6 100644 --- a/src/Components/Browser.JS/dist/Debug/blazor.webassembly.js +++ b/src/Components/Browser.JS/dist/Debug/blazor.webassembly.js @@ -1037,6 +1037,7 @@ var BrowserRenderer = /** @class */ (function () { BrowserRenderer.prototype.applyEdits = function (batch, parent, childIndex, edits, referenceFrames) { var currentDepth = 0; var childIndexAtCurrentDepth = childIndex; + var permutationList; var arraySegmentReader = batch.arraySegmentReader; var editReader = batch.editReader; var frameReader = batch.frameReader; @@ -1125,6 +1126,19 @@ var BrowserRenderer = /** @class */ (function () { childIndexAtCurrentDepth = currentDepth === 0 ? childIndex : 0; // The childIndex is only ever nonzero at zero depth break; } + case RenderBatch_1.EditType.permutationListEntry: { + permutationList = permutationList || []; + permutationList.push({ + fromSiblingIndex: childIndexAtCurrentDepth + editReader.siblingIndex(edit), + toSiblingIndex: childIndexAtCurrentDepth + editReader.moveToSiblingIndex(edit), + }); + break; + } + case RenderBatch_1.EditType.permutationListEnd: { + LogicalElements_1.permuteLogicalChildren(parent, permutationList); + permutationList = undefined; + break; + } default: { var unknownType = editType; // Compile-time verification that the switch was exhaustive throw new Error("Unknown edit type: " + unknownType); @@ -1929,6 +1943,54 @@ function getLogicalChildrenArray(element) { return element[logicalChildrenPropname]; } exports.getLogicalChildrenArray = getLogicalChildrenArray; +function permuteLogicalChildren(parent, permutationList) { + // The permutationList must represent a valid permutation, i.e., the list of 'from' indices + // is distinct, and the list of 'to' indices is a permutation of it. The algorithm here + // relies on that assumption. + // Each of the phases here has to happen separately, because each one is designed not to + // interfere with the indices or DOM entries used by subsequent phases. + // Phase 1: track which nodes we will move + var siblings = getLogicalChildrenArray(parent); + permutationList.forEach(function (listEntry) { + listEntry.moveRangeStart = siblings[listEntry.fromSiblingIndex]; + listEntry.moveRangeEnd = findLastDomNodeInRange(listEntry.moveRangeStart); + }); + // Phase 2: insert markers + permutationList.forEach(function (listEntry) { + var marker = listEntry.moveToBeforeMarker = document.createComment('marker'); + var insertBeforeNode = siblings[listEntry.toSiblingIndex + 1]; + if (insertBeforeNode) { + insertBeforeNode.parentNode.insertBefore(marker, insertBeforeNode); + } + else { + appendDomNode(marker, parent); + } + }); + // Phase 3: move descendants & remove markers + permutationList.forEach(function (listEntry) { + var insertBefore = listEntry.moveToBeforeMarker; + var parentDomNode = insertBefore.parentNode; + var elementToMove = listEntry.moveRangeStart; + var moveEndNode = listEntry.moveRangeEnd; + var nextToMove = elementToMove; + while (nextToMove) { + var nextNext = nextToMove.nextSibling; + parentDomNode.insertBefore(nextToMove, insertBefore); + if (nextToMove === moveEndNode) { + break; + } + else { + nextToMove = nextNext; + } + } + parentDomNode.removeChild(insertBefore); + }); + // Phase 4: update siblings index + permutationList.forEach(function (listEntry) { + siblings[listEntry.toSiblingIndex] = listEntry.moveRangeStart; + }); +} +exports.permuteLogicalChildren = permuteLogicalChildren; function getLogicalNextSibling(element) { var siblings = getLogicalChildrenArray(getLogicalParent(element)); var siblingIndex = Array.prototype.indexOf.call(siblings, element); @@ -1968,6 +2030,26 @@ function appendDomNode(child, parent) { throw new Error("Cannot append node because the parent is not a valid logical element. Parent: " + parent); } } +// Returns the final node (in depth-first evaluation order) that is a descendant of the logical element. +// As such, the entire subtree is between 'element' and 'findLastDomNodeInRange(element)' inclusive. +function findLastDomNodeInRange(element) { + if (element instanceof Element) { + return element; + } + var nextSibling = getLogicalNextSibling(element); + if (nextSibling) { + // Simple case: not the last logical sibling, so take the node before the next sibling + return nextSibling.previousSibling; + } + else { + // Harder case: there's no logical next-sibling, so recurse upwards until we find + // a logical ancestor that does have one, or a physical element + var logicalParent = getLogicalParent(element); + return logicalParent instanceof Element + ? logicalParent.lastChild + : findLastDomNodeInRange(logicalParent); + } +} function createSymbolOrFallback(fallback) { return typeof Symbol === 'function' ? Symbol() : fallback; } @@ -1996,6 +2078,8 @@ var EditType; EditType[EditType["stepIn"] = 6] = "stepIn"; EditType[EditType["stepOut"] = 7] = "stepOut"; EditType[EditType["updateMarkup"] = 8] = "updateMarkup"; + EditType[EditType["permutationListEntry"] = 9] = "permutationListEntry"; + EditType[EditType["permutationListEnd"] = 10] = "permutationListEnd"; })(EditType = exports.EditType || (exports.EditType = {})); var FrameType; (function (FrameType) { @@ -2093,7 +2177,8 @@ var editReader = { editType: function (edit) { return Environment_1.platform.readInt32Field(edit, 0); }, siblingIndex: function (edit) { return Environment_1.platform.readInt32Field(edit, 4); }, newTreeIndex: function (edit) { return Environment_1.platform.readInt32Field(edit, 8); }, - removedAttributeName: function (edit) { return Environment_1.platform.readStringField(edit, 12); }, + moveToSiblingIndex: function (edit) { return Environment_1.platform.readInt32Field(edit, 8); }, + removedAttributeName: function (edit) { return Environment_1.platform.readStringField(edit, 16); }, }; // Keep in sync with memory layout in RenderTreeFrame.cs var frameReader = { diff --git a/src/Components/Browser.JS/dist/Release/blazor.server.js b/src/Components/Browser.JS/dist/Release/blazor.server.js index a9f6e4c9755c..33c3d56ba8ff 100644 --- a/src/Components/Browser.JS/dist/Release/blazor.server.js +++ b/src/Components/Browser.JS/dist/Release/blazor.server.js @@ -1,15 +1,15 @@ -!function(e){var t={};function n(r){if(t[r])return t[r].exports;var o=t[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)n.d(r,o,function(t){return e[t]}.bind(null,o));return r},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=46)}([function(e,t,n){"use strict";var r;n.d(t,"a",function(){return r}),function(e){e[e.Trace=0]="Trace",e[e.Debug=1]="Debug",e[e.Information=2]="Information",e[e.Warning=3]="Warning",e[e.Error=4]="Error",e[e.Critical=5]="Critical",e[e.None=6]="None"}(r||(r={}))},function(e,t,n){"use strict";n.d(t,"a",function(){return s}),n.d(t,"e",function(){return u}),n.d(t,"f",function(){return c}),n.d(t,"g",function(){return l}),n.d(t,"d",function(){return f}),n.d(t,"c",function(){return h}),n.d(t,"b",function(){return d});var r=n(0),o=n(3),i=function(e,t,n,r){return new(n||(n=Promise))(function(o,i){function a(e){try{u(r.next(e))}catch(e){i(e)}}function s(e){try{u(r.throw(e))}catch(e){i(e)}}function u(e){e.done?o(e.value):new n(function(t){t(e.value)}).then(a,s)}u((r=r.apply(e,t||[])).next())})},a=function(e,t){var n,r,o,i,a={label:0,sent:function(){if(1&o[0])throw o[1];return o[1]},trys:[],ops:[]};return i={next:s(0),throw:s(1),return:s(2)},"function"==typeof Symbol&&(i[Symbol.iterator]=function(){return this}),i;function s(i){return function(s){return function(i){if(n)throw new TypeError("Generator is already executing.");for(;a;)try{if(n=1,r&&(o=2&i[0]?r.return:i[0]?r.throw||((o=r.return)&&o.call(r),0):r.next)&&!(o=o.call(r,i[1])).done)return o;switch(r=0,o&&(i=[2&i[0],o.value]),i[0]){case 0:case 1:o=i;break;case 4:return a.label++,{value:i[1],done:!1};case 5:a.label++,r=i[1],i=[0];continue;case 7:i=a.ops.pop(),a.trys.pop();continue;default:if(!(o=(o=a.trys).length>0&&o[o.length-1])&&(6===i[0]||2===i[0])){a=0;continue}if(3===i[0]&&(!o||i[1]>o[0]&&i[1]-1&&this.subject.observers.splice(e,1),0===this.subject.observers.length&&this.subject.cancelCallback().catch(function(e){})},e}(),d=function(){function e(e){this.minimumLogLevel=e}return e.prototype.log=function(e,t){if(e>=this.minimumLogLevel)switch(e){case r.a.Critical:case r.a.Error:console.error("["+(new Date).toISOString()+"] "+r.a[e]+": "+t);break;case r.a.Warning:console.warn("["+(new Date).toISOString()+"] "+r.a[e]+": "+t);break;case r.a.Information:console.info("["+(new Date).toISOString()+"] "+r.a[e]+": "+t);break;default:console.log("["+(new Date).toISOString()+"] "+r.a[e]+": "+t)}},e}()},function(e,t,n){"use strict";n.r(t);var r,o,i=(r=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(e,t){e.__proto__=t}||function(e,t){for(var n in t)t.hasOwnProperty(n)&&(e[n]=t[n])},function(e,t){function n(){this.constructor=e}r(e,t),e.prototype=null===t?Object.create(t):(n.prototype=t.prototype,new n)}),a=function(e){function t(t,n){var r=this,o=this.constructor.prototype;return(r=e.call(this,t)||this).statusCode=n,r.__proto__=o,r}return i(t,e),t}(Error),s=function(e){function t(t){void 0===t&&(t="A timeout occurred.");var n=this,r=this.constructor.prototype;return(n=e.call(this,t)||this).__proto__=r,n}return i(t,e),t}(Error),u=function(e){function t(t){void 0===t&&(t="An abort occurred.");var n=this,r=this.constructor.prototype;return(n=e.call(this,t)||this).__proto__=r,n}return i(t,e),t}(Error),c=Object.assign||function(e){for(var t,n=1,r=arguments.length;n=200&&o.status<300?n(new l(o.status,o.statusText,o.response||o.responseText)):r(new a(o.statusText,o.status))},o.onerror=function(){t.logger.log(h.a.Warning,"Error from HTTP request. "+o.status+": "+o.statusText+"."),r(new a(o.statusText,o.status))},o.ontimeout=function(){t.logger.log(h.a.Warning,"Timeout from HTTP request."),r(new s)},o.send(e.content||"")}):Promise.reject(new Error("No url defined.")):Promise.reject(new Error("No method defined."))},t}(f),g=function(){var e=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(e,t){e.__proto__=t}||function(e,t){for(var n in t)t.hasOwnProperty(n)&&(e[n]=t[n])};return function(t,n){function r(){this.constructor=t}e(t,n),t.prototype=null===n?Object.create(n):(r.prototype=n.prototype,new r)}}();if("undefined"==typeof XMLHttpRequest){var y=require;o=y("./NodeHttpClient")}var v,b=function(e){function t(t){var n=e.call(this)||this;if("undefined"!=typeof XMLHttpRequest)n.httpClient=new d(t);else{if(void 0===o)throw new Error("No HttpClient could be created.");n.httpClient=new o.NodeHttpClient(t)}return n}return g(t,e),t.prototype.send=function(e){return e.abortSignal&&e.abortSignal.aborted?Promise.reject(new u):e.method?e.url?this.httpClient.send(e):Promise.reject(new Error("No url defined.")):Promise.reject(new Error("No method defined."))},t.prototype.getCookieString=function(e){return this.httpClient.getCookieString(e)},t}(f),m=n(41);!function(e){e[e.Invocation=1]="Invocation",e[e.StreamItem=2]="StreamItem",e[e.Completion=3]="Completion",e[e.StreamInvocation=4]="StreamInvocation",e[e.CancelInvocation=5]="CancelInvocation",e[e.Ping=6]="Ping",e[e.Close=7]="Close"}(v||(v={}));var w,E=n(1),S=function(e,t,n,r){return new(n||(n=Promise))(function(o,i){function a(e){try{u(r.next(e))}catch(e){i(e)}}function s(e){try{u(r.throw(e))}catch(e){i(e)}}function u(e){e.done?o(e.value):new n(function(t){t(e.value)}).then(a,s)}u((r=r.apply(e,t||[])).next())})},_=function(e,t){var n,r,o,i,a={label:0,sent:function(){if(1&o[0])throw o[1];return o[1]},trys:[],ops:[]};return i={next:s(0),throw:s(1),return:s(2)},"function"==typeof Symbol&&(i[Symbol.iterator]=function(){return this}),i;function s(i){return function(s){return function(i){if(n)throw new TypeError("Generator is already executing.");for(;a;)try{if(n=1,r&&(o=2&i[0]?r.return:i[0]?r.throw||((o=r.return)&&o.call(r),0):r.next)&&!(o=o.call(r,i[1])).done)return o;switch(r=0,o&&(i=[2&i[0],o.value]),i[0]){case 0:case 1:o=i;break;case 4:return a.label++,{value:i[1],done:!1};case 5:a.label++,r=i[1],i=[0];continue;case 7:i=a.ops.pop(),a.trys.pop();continue;default:if(!(o=(o=a.trys).length>0&&o[o.length-1])&&(6===i[0]||2===i[0])){a=0;continue}if(3===i[0]&&(!o||i[1]>o[0]&&i[1]0&&o[o.length-1])&&(6===i[0]||2===i[0])){a=0;continue}if(3===i[0]&&(!o||i[1]>o[0]&&i[1]0&&o[o.length-1])&&(6===i[0]||2===i[0])){a=0;continue}if(3===i[0]&&(!o||i[1]>o[0]&&i[1]0&&o[o.length-1])&&(6===i[0]||2===i[0])){a=0;continue}if(3===i[0]&&(!o||i[1]>o[0]&&i[1]0&&o[o.length-1])&&(6===i[0]||2===i[0])){a=0;continue}if(3===i[0]&&(!o||i[1]>o[0]&&i[1]=0){if((r!==C.WebSockets||this.options.WebSocket)&&(r!==C.ServerSentEvents||this.options.EventSource))return this.logger.log(h.a.Debug,"Selecting transport '"+C[r]+"'."),r;this.logger.log(h.a.Debug,"Skipping transport '"+C[r]+"' because it is not supported in your environment.'")}else this.logger.log(h.a.Debug,"Skipping transport '"+C[r]+"' because it does not support the requested transfer format '"+I[n]+"'.");else this.logger.log(h.a.Debug,"Skipping transport '"+C[r]+"' because it was disabled by the client.")}return null},e.prototype.isITransport=function(e){return e&&"object"==typeof e&&"connect"in e},e.prototype.changeState=function(e,t){return this.connectionState===e&&(this.connectionState=t,!0)},e.prototype.stopConnection=function(e){this.transport=void 0,(e=this.stopError||e)?this.logger.log(h.a.Error,"Connection disconnected with error '"+e+"'."):this.logger.log(h.a.Information,"Connection disconnected."),this.connectionState=2,this.onclose&&this.onclose(e)},e.prototype.resolveUrl=function(e){if(0===e.lastIndexOf("https://",0)||0===e.lastIndexOf("http://",0))return e;if("undefined"==typeof window||!window||!window.document)throw new Error("Cannot resolve '"+e+"'.");var t=window.document.createElement("a");return t.href=e,this.logger.log(h.a.Information,"Normalizing '"+e+"' to '"+t.href+"'."),t.href},e.prototype.resolveNegotiateUrl=function(e){var t=e.indexOf("?"),n=e.substring(0,-1===t?e.length:t);return"/"!==n[n.length-1]&&(n+="/"),n+="negotiate",n+=-1===t?"":e.substring(t)},e}();var Y=n(3),K=n(4),J="json",X=function(){function e(){this.name=J,this.version=1,this.transferFormat=I.Text}return e.prototype.parseMessages=function(e,t){if("string"!=typeof e)throw new Error("Invalid input for JSON hub protocol. Expected a string.");if(!e)return[];null===t&&(t=Y.a.instance);for(var n=[],r=0,o=K.a.parse(e);r0&&!t)throw new Error("New logical elements must start empty, or allowExistingContents must be true");return e[r]=[],e}function s(e,t,n){var i=e;if(e instanceof Comment&&(c(i)&&c(i).length>0))throw new Error("Not implemented: inserting non-empty logical container");if(u(i))throw new Error("Not implemented: moving existing logical children");var a=c(t);if(n0;)e(r,0);var i=r;i.parentNode.removeChild(i)},t.getLogicalParent=u,t.getLogicalSiblingEnd=function(e){return e[i]||null},t.getLogicalChild=function(e,t){return c(e)[t]},t.isSvgElement=function(e){return"http://www.w3.org/2000/svg"===function(e){if(e instanceof Element)return e;if(e instanceof Comment)return e.parentNode;throw new Error("Not a valid logical element")}(e).namespaceURI},t.getLogicalChildrenArray=c},function(e,t,n){"use strict";var r=n(18),o=Object.keys||function(e){var t=[];for(var n in e)t.push(n);return t};e.exports=f;var i=n(15);i.inherits=n(7);var a=n(33),s=n(37);i.inherits(f,a);for(var u=o(s.prototype),c=0;c0&&o[o.length-1])&&(6===i[0]||2===i[0])){a=0;continue}if(3===i[0]&&(!o||i[1]>o[0]&&i[1]-1&&this.subject.observers.splice(e,1),0===this.subject.observers.length&&this.subject.cancelCallback().catch(function(e){})},e}(),d=function(){function e(e){this.minimumLogLevel=e}return e.prototype.log=function(e,t){if(e>=this.minimumLogLevel)switch(e){case r.a.Critical:case r.a.Error:console.error("["+(new Date).toISOString()+"] "+r.a[e]+": "+t);break;case r.a.Warning:console.warn("["+(new Date).toISOString()+"] "+r.a[e]+": "+t);break;case r.a.Information:console.info("["+(new Date).toISOString()+"] "+r.a[e]+": "+t);break;default:console.log("["+(new Date).toISOString()+"] "+r.a[e]+": "+t)}},e}()},function(e,t,n){"use strict";n.r(t);var r,o,i=(r=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(e,t){e.__proto__=t}||function(e,t){for(var n in t)t.hasOwnProperty(n)&&(e[n]=t[n])},function(e,t){function n(){this.constructor=e}r(e,t),e.prototype=null===t?Object.create(t):(n.prototype=t.prototype,new n)}),a=function(e){function t(t,n){var r=this,o=this.constructor.prototype;return(r=e.call(this,t)||this).statusCode=n,r.__proto__=o,r}return i(t,e),t}(Error),s=function(e){function t(t){void 0===t&&(t="A timeout occurred.");var n=this,r=this.constructor.prototype;return(n=e.call(this,t)||this).__proto__=r,n}return i(t,e),t}(Error),u=function(e){function t(t){void 0===t&&(t="An abort occurred.");var n=this,r=this.constructor.prototype;return(n=e.call(this,t)||this).__proto__=r,n}return i(t,e),t}(Error),c=Object.assign||function(e){for(var t,n=1,r=arguments.length;n=200&&o.status<300?n(new l(o.status,o.statusText,o.response||o.responseText)):r(new a(o.statusText,o.status))},o.onerror=function(){t.logger.log(h.a.Warning,"Error from HTTP request. "+o.status+": "+o.statusText+"."),r(new a(o.statusText,o.status))},o.ontimeout=function(){t.logger.log(h.a.Warning,"Timeout from HTTP request."),r(new s)},o.send(e.content||"")}):Promise.reject(new Error("No url defined.")):Promise.reject(new Error("No method defined."))},t}(f),g=function(){var e=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(e,t){e.__proto__=t}||function(e,t){for(var n in t)t.hasOwnProperty(n)&&(e[n]=t[n])};return function(t,n){function r(){this.constructor=t}e(t,n),t.prototype=null===n?Object.create(n):(r.prototype=n.prototype,new r)}}();if("undefined"==typeof XMLHttpRequest){var y=require;o=y("./NodeHttpClient")}var v,m=function(e){function t(t){var n=e.call(this)||this;if("undefined"!=typeof XMLHttpRequest)n.httpClient=new d(t);else{if(void 0===o)throw new Error("No HttpClient could be created.");n.httpClient=new o.NodeHttpClient(t)}return n}return g(t,e),t.prototype.send=function(e){return e.abortSignal&&e.abortSignal.aborted?Promise.reject(new u):e.method?e.url?this.httpClient.send(e):Promise.reject(new Error("No url defined.")):Promise.reject(new Error("No method defined."))},t.prototype.getCookieString=function(e){return this.httpClient.getCookieString(e)},t}(f),b=n(41);!function(e){e[e.Invocation=1]="Invocation",e[e.StreamItem=2]="StreamItem",e[e.Completion=3]="Completion",e[e.StreamInvocation=4]="StreamInvocation",e[e.CancelInvocation=5]="CancelInvocation",e[e.Ping=6]="Ping",e[e.Close=7]="Close"}(v||(v={}));var w,E=n(1),S=function(e,t,n,r){return new(n||(n=Promise))(function(o,i){function a(e){try{u(r.next(e))}catch(e){i(e)}}function s(e){try{u(r.throw(e))}catch(e){i(e)}}function u(e){e.done?o(e.value):new n(function(t){t(e.value)}).then(a,s)}u((r=r.apply(e,t||[])).next())})},_=function(e,t){var n,r,o,i,a={label:0,sent:function(){if(1&o[0])throw o[1];return o[1]},trys:[],ops:[]};return i={next:s(0),throw:s(1),return:s(2)},"function"==typeof Symbol&&(i[Symbol.iterator]=function(){return this}),i;function s(i){return function(s){return function(i){if(n)throw new TypeError("Generator is already executing.");for(;a;)try{if(n=1,r&&(o=2&i[0]?r.return:i[0]?r.throw||((o=r.return)&&o.call(r),0):r.next)&&!(o=o.call(r,i[1])).done)return o;switch(r=0,o&&(i=[2&i[0],o.value]),i[0]){case 0:case 1:o=i;break;case 4:return a.label++,{value:i[1],done:!1};case 5:a.label++,r=i[1],i=[0];continue;case 7:i=a.ops.pop(),a.trys.pop();continue;default:if(!(o=(o=a.trys).length>0&&o[o.length-1])&&(6===i[0]||2===i[0])){a=0;continue}if(3===i[0]&&(!o||i[1]>o[0]&&i[1]0&&o[o.length-1])&&(6===i[0]||2===i[0])){a=0;continue}if(3===i[0]&&(!o||i[1]>o[0]&&i[1]0&&o[o.length-1])&&(6===i[0]||2===i[0])){a=0;continue}if(3===i[0]&&(!o||i[1]>o[0]&&i[1]0&&o[o.length-1])&&(6===i[0]||2===i[0])){a=0;continue}if(3===i[0]&&(!o||i[1]>o[0]&&i[1]0&&o[o.length-1])&&(6===i[0]||2===i[0])){a=0;continue}if(3===i[0]&&(!o||i[1]>o[0]&&i[1]=0){if((r!==C.WebSockets||this.options.WebSocket)&&(r!==C.ServerSentEvents||this.options.EventSource))return this.logger.log(h.a.Debug,"Selecting transport '"+C[r]+"'."),r;this.logger.log(h.a.Debug,"Skipping transport '"+C[r]+"' because it is not supported in your environment.'")}else this.logger.log(h.a.Debug,"Skipping transport '"+C[r]+"' because it does not support the requested transfer format '"+I[n]+"'.");else this.logger.log(h.a.Debug,"Skipping transport '"+C[r]+"' because it was disabled by the client.")}return null},e.prototype.isITransport=function(e){return e&&"object"==typeof e&&"connect"in e},e.prototype.changeState=function(e,t){return this.connectionState===e&&(this.connectionState=t,!0)},e.prototype.stopConnection=function(e){this.transport=void 0,(e=this.stopError||e)?this.logger.log(h.a.Error,"Connection disconnected with error '"+e+"'."):this.logger.log(h.a.Information,"Connection disconnected."),this.connectionState=2,this.onclose&&this.onclose(e)},e.prototype.resolveUrl=function(e){if(0===e.lastIndexOf("https://",0)||0===e.lastIndexOf("http://",0))return e;if("undefined"==typeof window||!window||!window.document)throw new Error("Cannot resolve '"+e+"'.");var t=window.document.createElement("a");return t.href=e,this.logger.log(h.a.Information,"Normalizing '"+e+"' to '"+t.href+"'."),t.href},e.prototype.resolveNegotiateUrl=function(e){var t=e.indexOf("?"),n=e.substring(0,-1===t?e.length:t);return"/"!==n[n.length-1]&&(n+="/"),n+="negotiate",n+=-1===t?"":e.substring(t)},e}();var Y=n(3),K=n(4),J="json",X=function(){function e(){this.name=J,this.version=1,this.transferFormat=I.Text}return e.prototype.parseMessages=function(e,t){if("string"!=typeof e)throw new Error("Invalid input for JSON hub protocol. Expected a string.");if(!e)return[];null===t&&(t=Y.a.instance);for(var n=[],r=0,o=K.a.parse(e);r0&&!t)throw new Error("New logical elements must start empty, or allowExistingContents must be true");return e[r]=[],e}function s(e,t,n){var i=e;if(e instanceof Comment&&(c(i)&&c(i).length>0))throw new Error("Not implemented: inserting non-empty logical container");if(u(i))throw new Error("Not implemented: moving existing logical children");var a=c(t);if(n0;)e(r,0);var i=r;i.parentNode.removeChild(i)},t.getLogicalParent=u,t.getLogicalSiblingEnd=function(e){return e[i]||null},t.getLogicalChild=function(e,t){return c(e)[t]},t.isSvgElement=function(e){return"http://www.w3.org/2000/svg"===function(e){if(e instanceof Element)return e;if(e instanceof Comment)return e.parentNode;throw new Error("Not a valid logical element")}(e).namespaceURI},t.getLogicalChildrenArray=c,t.permuteLogicalChildren=function(e,t){var n=c(e);t.forEach(function(e){e.moveRangeStart=n[e.fromSiblingIndex],e.moveRangeEnd=function e(t){if(t instanceof Element)return t;var n=l(t);if(n)return n.previousSibling;var r=u(t);return r instanceof Element?r.lastChild:e(r)}(e.moveRangeStart)}),t.forEach(function(t){var r=t.moveToBeforeMarker=document.createComment("marker"),o=n[t.toSiblingIndex+1];o?o.parentNode.insertBefore(r,o):f(r,e)}),t.forEach(function(e){for(var t=e.moveToBeforeMarker,n=t.parentNode,r=e.moveRangeStart,o=e.moveRangeEnd,i=r;i;){var a=i.nextSibling;if(n.insertBefore(i,t),i===o)break;i=a}n.removeChild(t)}),t.forEach(function(e){n[e.toSiblingIndex]=e.moveRangeStart})}},function(e,t,n){"use strict";var r=n(18),o=Object.keys||function(e){var t=[];for(var n in e)t.push(n);return t};e.exports=f;var i=n(15);i.inherits=n(7);var a=n(33),s=n(37);i.inherits(f,a);for(var u=o(s.prototype),c=0;c * @license MIT */ -var r=n(47),o=n(48),i=n(31);function a(){return u.TYPED_ARRAY_SUPPORT?2147483647:1073741823}function s(e,t){if(a()=a())throw new RangeError("Attempt to allocate Buffer larger than maximum size: 0x"+a().toString(16)+" bytes");return 0|e}function d(e,t){if(u.isBuffer(e))return e.length;if("undefined"!=typeof ArrayBuffer&&"function"==typeof ArrayBuffer.isView&&(ArrayBuffer.isView(e)||e instanceof ArrayBuffer))return e.byteLength;"string"!=typeof e&&(e=""+e);var n=e.length;if(0===n)return 0;for(var r=!1;;)switch(t){case"ascii":case"latin1":case"binary":return n;case"utf8":case"utf-8":case void 0:return F(e).length;case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return 2*n;case"hex":return n>>>1;case"base64":return H(e).length;default:if(r)return F(e).length;t=(""+t).toLowerCase(),r=!0}}function g(e,t,n){var r=e[t];e[t]=e[n],e[n]=r}function y(e,t,n,r,o){if(0===e.length)return-1;if("string"==typeof n?(r=n,n=0):n>2147483647?n=2147483647:n<-2147483648&&(n=-2147483648),n=+n,isNaN(n)&&(n=o?0:e.length-1),n<0&&(n=e.length+n),n>=e.length){if(o)return-1;n=e.length-1}else if(n<0){if(!o)return-1;n=0}if("string"==typeof t&&(t=u.from(t,r)),u.isBuffer(t))return 0===t.length?-1:v(e,t,n,r,o);if("number"==typeof t)return t&=255,u.TYPED_ARRAY_SUPPORT&&"function"==typeof Uint8Array.prototype.indexOf?o?Uint8Array.prototype.indexOf.call(e,t,n):Uint8Array.prototype.lastIndexOf.call(e,t,n):v(e,[t],n,r,o);throw new TypeError("val must be string, number or Buffer")}function v(e,t,n,r,o){var i,a=1,s=e.length,u=t.length;if(void 0!==r&&("ucs2"===(r=String(r).toLowerCase())||"ucs-2"===r||"utf16le"===r||"utf-16le"===r)){if(e.length<2||t.length<2)return-1;a=2,s/=2,u/=2,n/=2}function c(e,t){return 1===a?e[t]:e.readUInt16BE(t*a)}if(o){var l=-1;for(i=n;is&&(n=s-u),i=n;i>=0;i--){for(var f=!0,h=0;ho&&(r=o):r=o;var i=t.length;if(i%2!=0)throw new TypeError("Invalid hex string");r>i/2&&(r=i/2);for(var a=0;a>8,o=n%256,i.push(o),i.push(r);return i}(t,e.length-n),e,n,r)}function T(e,t,n){return 0===t&&n===e.length?r.fromByteArray(e):r.fromByteArray(e.slice(t,n))}function k(e,t,n){n=Math.min(e.length,n);for(var r=[],o=t;o239?4:c>223?3:c>191?2:1;if(o+f<=n)switch(f){case 1:c<128&&(l=c);break;case 2:128==(192&(i=e[o+1]))&&(u=(31&c)<<6|63&i)>127&&(l=u);break;case 3:i=e[o+1],a=e[o+2],128==(192&i)&&128==(192&a)&&(u=(15&c)<<12|(63&i)<<6|63&a)>2047&&(u<55296||u>57343)&&(l=u);break;case 4:i=e[o+1],a=e[o+2],s=e[o+3],128==(192&i)&&128==(192&a)&&128==(192&s)&&(u=(15&c)<<18|(63&i)<<12|(63&a)<<6|63&s)>65535&&u<1114112&&(l=u)}null===l?(l=65533,f=1):l>65535&&(l-=65536,r.push(l>>>10&1023|55296),l=56320|1023&l),r.push(l),o+=f}return function(e){var t=e.length;if(t<=C)return String.fromCharCode.apply(String,e);var n="",r=0;for(;rthis.length)return"";if((void 0===n||n>this.length)&&(n=this.length),n<=0)return"";if((n>>>=0)<=(t>>>=0))return"";for(e||(e="utf8");;)switch(e){case"hex":return R(this,t,n);case"utf8":case"utf-8":return k(this,t,n);case"ascii":return I(this,t,n);case"latin1":case"binary":return x(this,t,n);case"base64":return T(this,t,n);case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return O(this,t,n);default:if(r)throw new TypeError("Unknown encoding: "+e);e=(e+"").toLowerCase(),r=!0}}.apply(this,arguments)},u.prototype.equals=function(e){if(!u.isBuffer(e))throw new TypeError("Argument must be a Buffer");return this===e||0===u.compare(this,e)},u.prototype.inspect=function(){var e="",n=t.INSPECT_MAX_BYTES;return this.length>0&&(e=this.toString("hex",0,n).match(/.{2}/g).join(" "),this.length>n&&(e+=" ... ")),""},u.prototype.compare=function(e,t,n,r,o){if(!u.isBuffer(e))throw new TypeError("Argument must be a Buffer");if(void 0===t&&(t=0),void 0===n&&(n=e?e.length:0),void 0===r&&(r=0),void 0===o&&(o=this.length),t<0||n>e.length||r<0||o>this.length)throw new RangeError("out of range index");if(r>=o&&t>=n)return 0;if(r>=o)return-1;if(t>=n)return 1;if(this===e)return 0;for(var i=(o>>>=0)-(r>>>=0),a=(n>>>=0)-(t>>>=0),s=Math.min(i,a),c=this.slice(r,o),l=e.slice(t,n),f=0;fo)&&(n=o),e.length>0&&(n<0||t<0)||t>this.length)throw new RangeError("Attempt to write outside buffer bounds");r||(r="utf8");for(var i=!1;;)switch(r){case"hex":return b(this,e,t,n);case"utf8":case"utf-8":return m(this,e,t,n);case"ascii":return w(this,e,t,n);case"latin1":case"binary":return E(this,e,t,n);case"base64":return S(this,e,t,n);case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return _(this,e,t,n);default:if(i)throw new TypeError("Unknown encoding: "+r);r=(""+r).toLowerCase(),i=!0}},u.prototype.toJSON=function(){return{type:"Buffer",data:Array.prototype.slice.call(this._arr||this,0)}};var C=4096;function I(e,t,n){var r="";n=Math.min(e.length,n);for(var o=t;or)&&(n=r);for(var o="",i=t;in)throw new RangeError("Trying to access beyond buffer length")}function M(e,t,n,r,o,i){if(!u.isBuffer(e))throw new TypeError('"buffer" argument must be a Buffer instance');if(t>o||te.length)throw new RangeError("Index out of range")}function L(e,t,n,r){t<0&&(t=65535+t+1);for(var o=0,i=Math.min(e.length-n,2);o>>8*(r?o:1-o)}function A(e,t,n,r){t<0&&(t=4294967295+t+1);for(var o=0,i=Math.min(e.length-n,4);o>>8*(r?o:3-o)&255}function B(e,t,n,r,o,i){if(n+r>e.length)throw new RangeError("Index out of range");if(n<0)throw new RangeError("Index out of range")}function D(e,t,n,r,i){return i||B(e,0,n,4),o.write(e,t,n,r,23,4),n+4}function U(e,t,n,r,i){return i||B(e,0,n,8),o.write(e,t,n,r,52,8),n+8}u.prototype.slice=function(e,t){var n,r=this.length;if((e=~~e)<0?(e+=r)<0&&(e=0):e>r&&(e=r),(t=void 0===t?r:~~t)<0?(t+=r)<0&&(t=0):t>r&&(t=r),t0&&(o*=256);)r+=this[e+--t]*o;return r},u.prototype.readUInt8=function(e,t){return t||P(e,1,this.length),this[e]},u.prototype.readUInt16LE=function(e,t){return t||P(e,2,this.length),this[e]|this[e+1]<<8},u.prototype.readUInt16BE=function(e,t){return t||P(e,2,this.length),this[e]<<8|this[e+1]},u.prototype.readUInt32LE=function(e,t){return t||P(e,4,this.length),(this[e]|this[e+1]<<8|this[e+2]<<16)+16777216*this[e+3]},u.prototype.readUInt32BE=function(e,t){return t||P(e,4,this.length),16777216*this[e]+(this[e+1]<<16|this[e+2]<<8|this[e+3])},u.prototype.readIntLE=function(e,t,n){e|=0,t|=0,n||P(e,t,this.length);for(var r=this[e],o=1,i=0;++i=(o*=128)&&(r-=Math.pow(2,8*t)),r},u.prototype.readIntBE=function(e,t,n){e|=0,t|=0,n||P(e,t,this.length);for(var r=t,o=1,i=this[e+--r];r>0&&(o*=256);)i+=this[e+--r]*o;return i>=(o*=128)&&(i-=Math.pow(2,8*t)),i},u.prototype.readInt8=function(e,t){return t||P(e,1,this.length),128&this[e]?-1*(255-this[e]+1):this[e]},u.prototype.readInt16LE=function(e,t){t||P(e,2,this.length);var n=this[e]|this[e+1]<<8;return 32768&n?4294901760|n:n},u.prototype.readInt16BE=function(e,t){t||P(e,2,this.length);var n=this[e+1]|this[e]<<8;return 32768&n?4294901760|n:n},u.prototype.readInt32LE=function(e,t){return t||P(e,4,this.length),this[e]|this[e+1]<<8|this[e+2]<<16|this[e+3]<<24},u.prototype.readInt32BE=function(e,t){return t||P(e,4,this.length),this[e]<<24|this[e+1]<<16|this[e+2]<<8|this[e+3]},u.prototype.readFloatLE=function(e,t){return t||P(e,4,this.length),o.read(this,e,!0,23,4)},u.prototype.readFloatBE=function(e,t){return t||P(e,4,this.length),o.read(this,e,!1,23,4)},u.prototype.readDoubleLE=function(e,t){return t||P(e,8,this.length),o.read(this,e,!0,52,8)},u.prototype.readDoubleBE=function(e,t){return t||P(e,8,this.length),o.read(this,e,!1,52,8)},u.prototype.writeUIntLE=function(e,t,n,r){(e=+e,t|=0,n|=0,r)||M(this,e,t,n,Math.pow(2,8*n)-1,0);var o=1,i=0;for(this[t]=255&e;++i=0&&(i*=256);)this[t+o]=e/i&255;return t+n},u.prototype.writeUInt8=function(e,t,n){return e=+e,t|=0,n||M(this,e,t,1,255,0),u.TYPED_ARRAY_SUPPORT||(e=Math.floor(e)),this[t]=255&e,t+1},u.prototype.writeUInt16LE=function(e,t,n){return e=+e,t|=0,n||M(this,e,t,2,65535,0),u.TYPED_ARRAY_SUPPORT?(this[t]=255&e,this[t+1]=e>>>8):L(this,e,t,!0),t+2},u.prototype.writeUInt16BE=function(e,t,n){return e=+e,t|=0,n||M(this,e,t,2,65535,0),u.TYPED_ARRAY_SUPPORT?(this[t]=e>>>8,this[t+1]=255&e):L(this,e,t,!1),t+2},u.prototype.writeUInt32LE=function(e,t,n){return e=+e,t|=0,n||M(this,e,t,4,4294967295,0),u.TYPED_ARRAY_SUPPORT?(this[t+3]=e>>>24,this[t+2]=e>>>16,this[t+1]=e>>>8,this[t]=255&e):A(this,e,t,!0),t+4},u.prototype.writeUInt32BE=function(e,t,n){return e=+e,t|=0,n||M(this,e,t,4,4294967295,0),u.TYPED_ARRAY_SUPPORT?(this[t]=e>>>24,this[t+1]=e>>>16,this[t+2]=e>>>8,this[t+3]=255&e):A(this,e,t,!1),t+4},u.prototype.writeIntLE=function(e,t,n,r){if(e=+e,t|=0,!r){var o=Math.pow(2,8*n-1);M(this,e,t,n,o-1,-o)}var i=0,a=1,s=0;for(this[t]=255&e;++i>0)-s&255;return t+n},u.prototype.writeIntBE=function(e,t,n,r){if(e=+e,t|=0,!r){var o=Math.pow(2,8*n-1);M(this,e,t,n,o-1,-o)}var i=n-1,a=1,s=0;for(this[t+i]=255&e;--i>=0&&(a*=256);)e<0&&0===s&&0!==this[t+i+1]&&(s=1),this[t+i]=(e/a>>0)-s&255;return t+n},u.prototype.writeInt8=function(e,t,n){return e=+e,t|=0,n||M(this,e,t,1,127,-128),u.TYPED_ARRAY_SUPPORT||(e=Math.floor(e)),e<0&&(e=255+e+1),this[t]=255&e,t+1},u.prototype.writeInt16LE=function(e,t,n){return e=+e,t|=0,n||M(this,e,t,2,32767,-32768),u.TYPED_ARRAY_SUPPORT?(this[t]=255&e,this[t+1]=e>>>8):L(this,e,t,!0),t+2},u.prototype.writeInt16BE=function(e,t,n){return e=+e,t|=0,n||M(this,e,t,2,32767,-32768),u.TYPED_ARRAY_SUPPORT?(this[t]=e>>>8,this[t+1]=255&e):L(this,e,t,!1),t+2},u.prototype.writeInt32LE=function(e,t,n){return e=+e,t|=0,n||M(this,e,t,4,2147483647,-2147483648),u.TYPED_ARRAY_SUPPORT?(this[t]=255&e,this[t+1]=e>>>8,this[t+2]=e>>>16,this[t+3]=e>>>24):A(this,e,t,!0),t+4},u.prototype.writeInt32BE=function(e,t,n){return e=+e,t|=0,n||M(this,e,t,4,2147483647,-2147483648),e<0&&(e=4294967295+e+1),u.TYPED_ARRAY_SUPPORT?(this[t]=e>>>24,this[t+1]=e>>>16,this[t+2]=e>>>8,this[t+3]=255&e):A(this,e,t,!1),t+4},u.prototype.writeFloatLE=function(e,t,n){return D(this,e,t,!0,n)},u.prototype.writeFloatBE=function(e,t,n){return D(this,e,t,!1,n)},u.prototype.writeDoubleLE=function(e,t,n){return U(this,e,t,!0,n)},u.prototype.writeDoubleBE=function(e,t,n){return U(this,e,t,!1,n)},u.prototype.copy=function(e,t,n,r){if(n||(n=0),r||0===r||(r=this.length),t>=e.length&&(t=e.length),t||(t=0),r>0&&r=this.length)throw new RangeError("sourceStart out of bounds");if(r<0)throw new RangeError("sourceEnd out of bounds");r>this.length&&(r=this.length),e.length-t=0;--o)e[o+t]=this[o+n];else if(i<1e3||!u.TYPED_ARRAY_SUPPORT)for(o=0;o>>=0,n=void 0===n?this.length:n>>>0,e||(e=0),"number"==typeof e)for(i=t;i55295&&n<57344){if(!o){if(n>56319){(t-=3)>-1&&i.push(239,191,189);continue}if(a+1===r){(t-=3)>-1&&i.push(239,191,189);continue}o=n;continue}if(n<56320){(t-=3)>-1&&i.push(239,191,189),o=n;continue}n=65536+(o-55296<<10|n-56320)}else o&&(t-=3)>-1&&i.push(239,191,189);if(o=null,n<128){if((t-=1)<0)break;i.push(n)}else if(n<2048){if((t-=2)<0)break;i.push(n>>6|192,63&n|128)}else if(n<65536){if((t-=3)<0)break;i.push(n>>12|224,n>>6&63|128,63&n|128)}else{if(!(n<1114112))throw new Error("Invalid code point");if((t-=4)<0)break;i.push(n>>18|240,n>>12&63|128,n>>6&63|128,63&n|128)}}return i}function H(e){return r.toByteArray(function(e){if((e=function(e){return e.trim?e.trim():e.replace(/^\s+|\s+$/g,"")}(e).replace(N,"")).length<2)return"";for(;e.length%4!=0;)e+="=";return e}(e))}function q(e,t,n,r){for(var o=0;o=t.length||o>=e.length);++o)t[o+n]=e[o];return o}}).call(this,n(5))},function(e,t,n){"use strict";var r;!function(e){window.DotNet=e;var t=[],n={},r={},o=1,i=null;function a(e){t.push(e)}function s(e,t){for(var n=[],r=2;r1)for(var n=1;n0&&o[o.length-1])&&(6===i[0]||2===i[0])){a=0;continue}if(3===i[0]&&(!o||i[1]>o[0]&&i[1]this.length||e<0)){var t=this._offset(e);return this._bufs[t[0]][t[1]]}},a.prototype.slice=function(e,t){return"number"==typeof e&&e<0&&(e+=this.length),"number"==typeof t&&t<0&&(t+=this.length),this.copy(null,0,e,t)},a.prototype.copy=function(e,t,n,r){if(("number"!=typeof n||n<0)&&(n=0),("number"!=typeof r||r>this.length)&&(r=this.length),n>=this.length)return e||i.alloc(0);if(r<=0)return e||i.alloc(0);var o,a,s=!!e,u=this._offset(n),c=r-n,l=c,f=s&&t||0,h=u[1];if(0===n&&r==this.length){if(!s)return 1===this._bufs.length?this._bufs[0]:i.concat(this._bufs,this.length);for(a=0;a(o=this._bufs[a].length-h))){this._bufs[a].copy(e,f,h,h+l);break}this._bufs[a].copy(e,f,h),f+=o,l-=o,h&&(h=0)}return e},a.prototype.shallowSlice=function(e,t){if(e=e||0,t="number"!=typeof t?this.length:t,e<0&&(e+=this.length),t<0&&(t+=this.length),e===t)return new a;var n=this._offset(e),r=this._offset(t),o=this._bufs.slice(n[0],r[0]+1);return 0==r[1]?o.pop():o[o.length-1]=o[o.length-1].slice(0,r[1]),0!=n[1]&&(o[0]=o[0].slice(n[1])),new a(o)},a.prototype.toString=function(e,t,n){return this.slice(t,n).toString(e)},a.prototype.consume=function(e){for(;this._bufs.length;){if(!(e>=this._bufs[0].length)){this._bufs[0]=this._bufs[0].slice(e),this.length-=e;break}e-=this._bufs[0].length,this.length-=this._bufs[0].length,this._bufs.shift()}return this},a.prototype.duplicate=function(){for(var e=0,t=new a;ethis.length?this.length:t;for(var r=this._offset(t),o=r[0],s=r[1];o=e.length){var c=u.indexOf(e,s);if(-1!==c)return this._reverseOffset([o,c]);s=u.length-e.length+1}else{var l=this._reverseOffset([o,s]);if(this._match(l,e))return l;s++}}s=0}return-1},a.prototype._match=function(e,t){if(this.length-e=0,"must have a non-negative type"),o(a,"must have a decode function"),this.registerEncoder(function(e){return e instanceof t},function(t){var o=i(),a=r.allocUnsafe(1);return a.writeInt8(e,0),o.append(a),o.append(n(t)),o}),this.registerDecoder(e,a),this},registerEncoder:function(e,n){return o(e,"must have an encode function"),o(n,"must have an encode function"),t.push({check:e,encode:n}),this},registerDecoder:function(e,t){return o(e>=0,"must have a non-negative type"),o(t,"must have a decode function"),n.push({type:e,decode:t}),this},encoder:a.encoder,decoder:a.decoder,buffer:!0,type:"msgpack5",IncompleteBufferError:s.IncompleteBufferError}}},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var r=n(16),o=n(22),i=n(8);window.Blazor={navigateTo:r.navigateTo,_internal:{attachRootComponentToElement:i.attachRootComponentToElement,http:o.internalFunctions,uriHelper:r.internalFunctions}}},function(e,t,n){"use strict";var r=this&&this.__awaiter||function(e,t,n,r){return new(n||(n=Promise))(function(o,i){function a(e){try{u(r.next(e))}catch(e){i(e)}}function s(e){try{u(r.throw(e))}catch(e){i(e)}}function u(e){e.done?o(e.value):new n(function(t){t(e.value)}).then(a,s)}u((r=r.apply(e,t||[])).next())})},o=this&&this.__generator||function(e,t){var n,r,o,i,a={label:0,sent:function(){if(1&o[0])throw o[1];return o[1]},trys:[],ops:[]};return i={next:s(0),throw:s(1),return:s(2)},"function"==typeof Symbol&&(i[Symbol.iterator]=function(){return this}),i;function s(i){return function(s){return function(i){if(n)throw new TypeError("Generator is already executing.");for(;a;)try{if(n=1,r&&(o=2&i[0]?r.return:i[0]?r.throw||((o=r.return)&&o.call(r),0):r.next)&&!(o=o.call(r,i[1])).done)return o;switch(r=0,o&&(i=[2&i[0],o.value]),i[0]){case 0:case 1:o=i;break;case 4:return a.label++,{value:i[1],done:!1};case 5:a.label++,r=i[1],i=[0];continue;case 7:i=a.ops.pop(),a.trys.pop();continue;default:if(!(o=(o=a.trys).length>0&&o[o.length-1])&&(6===i[0]||2===i[0])){a=0;continue}if(3===i[0]&&(!o||i[1]>o[0]&&i[1]0&&o[o.length-1])&&(6===i[0]||2===i[0])){a=0;continue}if(3===i[0]&&(!o||i[1]>o[0]&&i[1]=i)return e;switch(e){case"%s":return String(r[n++]);case"%d":return Number(r[n++]);case"%j":try{return JSON.stringify(r[n++])}catch(e){return"[Circular]"}default:return e}}),u=r[n];n=3&&(r.depth=arguments[2]),arguments.length>=4&&(r.colors=arguments[3]),d(n)?r.showHidden=n:n&&t._extend(r,n),b(r.showHidden)&&(r.showHidden=!1),b(r.depth)&&(r.depth=2),b(r.colors)&&(r.colors=!1),b(r.customInspect)&&(r.customInspect=!0),r.colors&&(r.stylize=u),l(r,e,r.depth)}function u(e,t){var n=s.styles[t];return n?"["+s.colors[n][0]+"m"+e+"["+s.colors[n][1]+"m":e}function c(e,t){return e}function l(e,n,r){if(e.customInspect&&n&&_(n.inspect)&&n.inspect!==t.inspect&&(!n.constructor||n.constructor.prototype!==n)){var o=n.inspect(r,e);return v(o)||(o=l(e,o,r)),o}var i=function(e,t){if(b(t))return e.stylize("undefined","undefined");if(v(t)){var n="'"+JSON.stringify(t).replace(/^"|"$/g,"").replace(/'/g,"\\'").replace(/\\"/g,'"')+"'";return e.stylize(n,"string")}if(y(t))return e.stylize(""+t,"number");if(d(t))return e.stylize(""+t,"boolean");if(g(t))return e.stylize("null","null")}(e,n);if(i)return i;var a=Object.keys(n),s=function(e){var t={};return e.forEach(function(e,n){t[e]=!0}),t}(a);if(e.showHidden&&(a=Object.getOwnPropertyNames(n)),S(n)&&(a.indexOf("message")>=0||a.indexOf("description")>=0))return f(n);if(0===a.length){if(_(n)){var u=n.name?": "+n.name:"";return e.stylize("[Function"+u+"]","special")}if(m(n))return e.stylize(RegExp.prototype.toString.call(n),"regexp");if(E(n))return e.stylize(Date.prototype.toString.call(n),"date");if(S(n))return f(n)}var c,w="",T=!1,k=["{","}"];(p(n)&&(T=!0,k=["[","]"]),_(n))&&(w=" [Function"+(n.name?": "+n.name:"")+"]");return m(n)&&(w=" "+RegExp.prototype.toString.call(n)),E(n)&&(w=" "+Date.prototype.toUTCString.call(n)),S(n)&&(w=" "+f(n)),0!==a.length||T&&0!=n.length?r<0?m(n)?e.stylize(RegExp.prototype.toString.call(n),"regexp"):e.stylize("[Object]","special"):(e.seen.push(n),c=T?function(e,t,n,r,o){for(var i=[],a=0,s=t.length;a=0&&0,e+t.replace(/\u001b\[\d\d?m/g,"").length+1},0)>60)return n[0]+(""===t?"":t+"\n ")+" "+e.join(",\n ")+" "+n[1];return n[0]+t+" "+e.join(", ")+" "+n[1]}(c,w,k)):k[0]+w+k[1]}function f(e){return"["+Error.prototype.toString.call(e)+"]"}function h(e,t,n,r,o,i){var a,s,u;if((u=Object.getOwnPropertyDescriptor(t,o)||{value:t[o]}).get?s=u.set?e.stylize("[Getter/Setter]","special"):e.stylize("[Getter]","special"):u.set&&(s=e.stylize("[Setter]","special")),I(r,o)||(a="["+o+"]"),s||(e.seen.indexOf(u.value)<0?(s=g(n)?l(e,u.value,null):l(e,u.value,n-1)).indexOf("\n")>-1&&(s=i?s.split("\n").map(function(e){return" "+e}).join("\n").substr(2):"\n"+s.split("\n").map(function(e){return" "+e}).join("\n")):s=e.stylize("[Circular]","special")),b(a)){if(i&&o.match(/^\d+$/))return s;(a=JSON.stringify(""+o)).match(/^"([a-zA-Z_][a-zA-Z_0-9]*)"$/)?(a=a.substr(1,a.length-2),a=e.stylize(a,"name")):(a=a.replace(/'/g,"\\'").replace(/\\"/g,'"').replace(/(^"|"$)/g,"'"),a=e.stylize(a,"string"))}return a+": "+s}function p(e){return Array.isArray(e)}function d(e){return"boolean"==typeof e}function g(e){return null===e}function y(e){return"number"==typeof e}function v(e){return"string"==typeof e}function b(e){return void 0===e}function m(e){return w(e)&&"[object RegExp]"===T(e)}function w(e){return"object"==typeof e&&null!==e}function E(e){return w(e)&&"[object Date]"===T(e)}function S(e){return w(e)&&("[object Error]"===T(e)||e instanceof Error)}function _(e){return"function"==typeof e}function T(e){return Object.prototype.toString.call(e)}function k(e){return e<10?"0"+e.toString(10):e.toString(10)}t.debuglog=function(n){if(b(i)&&(i=e.env.NODE_DEBUG||""),n=n.toUpperCase(),!a[n])if(new RegExp("\\b"+n+"\\b","i").test(i)){var r=e.pid;a[n]=function(){var e=t.format.apply(t,arguments);console.error("%s %d: %s",n,r,e)}}else a[n]=function(){};return a[n]},t.inspect=s,s.colors={bold:[1,22],italic:[3,23],underline:[4,24],inverse:[7,27],white:[37,39],grey:[90,39],black:[30,39],blue:[34,39],cyan:[36,39],green:[32,39],magenta:[35,39],red:[31,39],yellow:[33,39]},s.styles={special:"cyan",number:"yellow",boolean:"yellow",undefined:"grey",null:"bold",string:"green",date:"magenta",regexp:"red"},t.isArray=p,t.isBoolean=d,t.isNull=g,t.isNullOrUndefined=function(e){return null==e},t.isNumber=y,t.isString=v,t.isSymbol=function(e){return"symbol"==typeof e},t.isUndefined=b,t.isRegExp=m,t.isObject=w,t.isDate=E,t.isError=S,t.isFunction=_,t.isPrimitive=function(e){return null===e||"boolean"==typeof e||"number"==typeof e||"string"==typeof e||"symbol"==typeof e||void 0===e},t.isBuffer=n(50);var C=["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"];function I(e,t){return Object.prototype.hasOwnProperty.call(e,t)}t.log=function(){var e,n;console.log("%s - %s",(e=new Date,n=[k(e.getHours()),k(e.getMinutes()),k(e.getSeconds())].join(":"),[e.getDate(),C[e.getMonth()],n].join(" ")),t.format.apply(t,arguments))},t.inherits=n(7),t._extend=function(e,t){if(!t||!w(t))return e;for(var n=Object.keys(t),r=n.length;r--;)e[n[r]]=t[n[r]];return e};var x="undefined"!=typeof Symbol?Symbol("util.promisify.custom"):void 0;function R(e,t){if(!e){var n=new Error("Promise was rejected with a falsy value");n.reason=e,e=n}return t(e)}t.promisify=function(e){if("function"!=typeof e)throw new TypeError('The "original" argument must be of type Function');if(x&&e[x]){var t;if("function"!=typeof(t=e[x]))throw new TypeError('The "util.promisify.custom" argument must be of type Function');return Object.defineProperty(t,x,{value:t,enumerable:!1,writable:!1,configurable:!0}),t}function t(){for(var t,n,r=new Promise(function(e,r){t=e,n=r}),o=[],i=0;i0?("string"==typeof t||a.objectMode||Object.getPrototypeOf(t)===c.prototype||(t=function(e){return c.from(e)}(t)),r?a.endEmitted?e.emit("error",new Error("stream.unshift() after end event")):E(e,a,t,!0):a.ended?e.emit("error",new Error("stream.push() after EOF")):(a.reading=!1,a.decoder&&!n?(t=a.decoder.write(t),a.objectMode||0!==t.length?E(e,a,t,!1):C(e,a)):E(e,a,t,!1))):r||(a.reading=!1));return function(e){return!e.ended&&(e.needReadable||e.lengtht.highWaterMark&&(t.highWaterMark=function(e){return e>=S?e=S:(e--,e|=e>>>1,e|=e>>>2,e|=e>>>4,e|=e>>>8,e|=e>>>16,e++),e}(e)),e<=t.length?e:t.ended?t.length:(t.needReadable=!0,0))}function T(e){var t=e._readableState;t.needReadable=!1,t.emittedReadable||(p("emitReadable",t.flowing),t.emittedReadable=!0,t.sync?o.nextTick(k,e):k(e))}function k(e){p("emit readable"),e.emit("readable"),O(e)}function C(e,t){t.readingMore||(t.readingMore=!0,o.nextTick(I,e,t))}function I(e,t){for(var n=t.length;!t.reading&&!t.flowing&&!t.ended&&t.length=t.length?(n=t.decoder?t.buffer.join(""):1===t.buffer.length?t.buffer.head.data:t.buffer.concat(t.length),t.buffer.clear()):n=function(e,t,n){var r;ei.length?i.length:e;if(a===i.length?o+=i:o+=i.slice(0,e),0===(e-=a)){a===i.length?(++r,n.next?t.head=n.next:t.head=t.tail=null):(t.head=n,n.data=i.slice(a));break}++r}return t.length-=r,o}(e,t):function(e,t){var n=c.allocUnsafe(e),r=t.head,o=1;r.data.copy(n),e-=r.data.length;for(;r=r.next;){var i=r.data,a=e>i.length?i.length:e;if(i.copy(n,n.length-e,0,a),0===(e-=a)){a===i.length?(++o,r.next?t.head=r.next:t.head=t.tail=null):(t.head=r,r.data=i.slice(a));break}++o}return t.length-=o,n}(e,t);return r}(e,t.buffer,t.decoder),n);var n}function M(e){var t=e._readableState;if(t.length>0)throw new Error('"endReadable()" called on non-empty stream');t.endEmitted||(t.ended=!0,o.nextTick(L,t,e))}function L(e,t){e.endEmitted||0!==e.length||(e.endEmitted=!0,t.readable=!1,t.emit("end"))}function A(e,t){for(var n=0,r=e.length;n=t.highWaterMark||t.ended))return p("read: emitReadable",t.length,t.ended),0===t.length&&t.ended?M(this):T(this),null;if(0===(e=_(e,t))&&t.ended)return 0===t.length&&M(this),null;var r,o=t.needReadable;return p("need readable",o),(0===t.length||t.length-e0?P(e,t):null)?(t.needReadable=!0,e=0):t.length-=e,0===t.length&&(t.ended||(t.needReadable=!0),n!==e&&t.ended&&M(this)),null!==r&&this.emit("data",r),r},m.prototype._read=function(e){this.emit("error",new Error("_read() is not implemented"))},m.prototype.pipe=function(e,t){var n=this,i=this._readableState;switch(i.pipesCount){case 0:i.pipes=e;break;case 1:i.pipes=[i.pipes,e];break;default:i.pipes.push(e)}i.pipesCount+=1,p("pipe count=%d opts=%j",i.pipesCount,t);var u=(!t||!1!==t.end)&&e!==r.stdout&&e!==r.stderr?l:m;function c(t,r){p("onunpipe"),t===n&&r&&!1===r.hasUnpiped&&(r.hasUnpiped=!0,p("cleanup"),e.removeListener("close",v),e.removeListener("finish",b),e.removeListener("drain",f),e.removeListener("error",y),e.removeListener("unpipe",c),n.removeListener("end",l),n.removeListener("end",m),n.removeListener("data",g),h=!0,!i.awaitDrain||e._writableState&&!e._writableState.needDrain||f())}function l(){p("onend"),e.end()}i.endEmitted?o.nextTick(u):n.once("end",u),e.on("unpipe",c);var f=function(e){return function(){var t=e._readableState;p("pipeOnDrain",t.awaitDrain),t.awaitDrain&&t.awaitDrain--,0===t.awaitDrain&&s(e,"data")&&(t.flowing=!0,O(e))}}(n);e.on("drain",f);var h=!1;var d=!1;function g(t){p("ondata"),d=!1,!1!==e.write(t)||d||((1===i.pipesCount&&i.pipes===e||i.pipesCount>1&&-1!==A(i.pipes,e))&&!h&&(p("false write response, pause",n._readableState.awaitDrain),n._readableState.awaitDrain++,d=!0),n.pause())}function y(t){p("onerror",t),m(),e.removeListener("error",y),0===s(e,"error")&&e.emit("error",t)}function v(){e.removeListener("finish",b),m()}function b(){p("onfinish"),e.removeListener("close",v),m()}function m(){p("unpipe"),n.unpipe(e)}return n.on("data",g),function(e,t,n){if("function"==typeof e.prependListener)return e.prependListener(t,n);e._events&&e._events[t]?a(e._events[t])?e._events[t].unshift(n):e._events[t]=[n,e._events[t]]:e.on(t,n)}(e,"error",y),e.once("close",v),e.once("finish",b),e.emit("pipe",n),i.flowing||(p("pipe resume"),n.resume()),e},m.prototype.unpipe=function(e){var t=this._readableState,n={hasUnpiped:!1};if(0===t.pipesCount)return this;if(1===t.pipesCount)return e&&e!==t.pipes?this:(e||(e=t.pipes),t.pipes=null,t.pipesCount=0,t.flowing=!1,e&&e.emit("unpipe",this,n),this);if(!e){var r=t.pipes,o=t.pipesCount;t.pipes=null,t.pipesCount=0,t.flowing=!1;for(var i=0;i0&&a.length>o&&!a.warned){a.warned=!0;var u=new Error("Possible EventEmitter memory leak detected. "+a.length+" "+String(t)+" listeners added. Use emitter.setMaxListeners() to increase limit");u.name="MaxListenersExceededWarning",u.emitter=e,u.type=t,u.count=a.length,s=u,console&&console.warn&&console.warn(s)}return e}function f(e,t,n){var r={fired:!1,wrapFn:void 0,target:e,type:t,listener:n},o=function(){for(var e=[],t=0;t0&&(a=t[0]),a instanceof Error)throw a;var s=new Error("Unhandled error."+(a?" ("+a.message+")":""));throw s.context=a,s}var u=o[e];if(void 0===u)return!1;if("function"==typeof u)i(u,this,t);else{var c=u.length,l=d(u,c);for(n=0;n=0;i--)if(n[i]===t||n[i].listener===t){a=n[i].listener,o=i;break}if(o<0)return this;0===o?n.shift():function(e,t){for(;t+1=0;r--)this.removeListener(e,t[r]);return this},s.prototype.listeners=function(e){return h(this,e,!0)},s.prototype.rawListeners=function(e){return h(this,e,!1)},s.listenerCount=function(e,t){return"function"==typeof e.listenerCount?e.listenerCount(t):p.call(e,t)},s.prototype.listenerCount=p,s.prototype.eventNames=function(){return this._eventsCount>0?r(this._events):[]}},function(e,t,n){e.exports=n(34).EventEmitter},function(e,t,n){"use strict";var r=n(18);function o(e,t){e.emit("error",t)}e.exports={destroy:function(e,t){var n=this,i=this._readableState&&this._readableState.destroyed,a=this._writableState&&this._writableState.destroyed;return i||a?(t?t(e):!e||this._writableState&&this._writableState.errorEmitted||r.nextTick(o,this,e),this):(this._readableState&&(this._readableState.destroyed=!0),this._writableState&&(this._writableState.destroyed=!0),this._destroy(e||null,function(e){!t&&e?(r.nextTick(o,n,e),n._writableState&&(n._writableState.errorEmitted=!0)):t&&t(e)}),this)},undestroy:function(){this._readableState&&(this._readableState.destroyed=!1,this._readableState.reading=!1,this._readableState.ended=!1,this._readableState.endEmitted=!1),this._writableState&&(this._writableState.destroyed=!1,this._writableState.ended=!1,this._writableState.ending=!1,this._writableState.finished=!1,this._writableState.errorEmitted=!1)}}},function(e,t,n){"use strict";(function(t,r,o){var i=n(18);function a(e){var t=this;this.next=null,this.entry=null,this.finish=function(){!function(e,t,n){var r=e.entry;e.entry=null;for(;r;){var o=r.callback;t.pendingcb--,o(n),r=r.next}t.corkedRequestsFree?t.corkedRequestsFree.next=e:t.corkedRequestsFree=e}(t,e)}}e.exports=b;var s,u=!t.browser&&["v0.10","v0.9."].indexOf(t.version.slice(0,5))>-1?r:i.nextTick;b.WritableState=v;var c=n(15);c.inherits=n(7);var l={deprecate:n(56)},f=n(35),h=n(6).Buffer,p=o.Uint8Array||function(){};var d,g=n(36);function y(){}function v(e,t){s=s||n(10),e=e||{};var r=t instanceof s;this.objectMode=!!e.objectMode,r&&(this.objectMode=this.objectMode||!!e.writableObjectMode);var o=e.highWaterMark,c=e.writableHighWaterMark,l=this.objectMode?16:16384;this.highWaterMark=o||0===o?o:r&&(c||0===c)?c:l,this.highWaterMark=Math.floor(this.highWaterMark),this.finalCalled=!1,this.needDrain=!1,this.ending=!1,this.ended=!1,this.finished=!1,this.destroyed=!1;var f=!1===e.decodeStrings;this.decodeStrings=!f,this.defaultEncoding=e.defaultEncoding||"utf8",this.length=0,this.writing=!1,this.corked=0,this.sync=!0,this.bufferProcessing=!1,this.onwrite=function(e){!function(e,t){var n=e._writableState,r=n.sync,o=n.writecb;if(function(e){e.writing=!1,e.writecb=null,e.length-=e.writelen,e.writelen=0}(n),t)!function(e,t,n,r,o){--t.pendingcb,n?(i.nextTick(o,r),i.nextTick(T,e,t),e._writableState.errorEmitted=!0,e.emit("error",r)):(o(r),e._writableState.errorEmitted=!0,e.emit("error",r),T(e,t))}(e,n,r,t,o);else{var a=S(n);a||n.corked||n.bufferProcessing||!n.bufferedRequest||E(e,n),r?u(w,e,n,a,o):w(e,n,a,o)}}(t,e)},this.writecb=null,this.writelen=0,this.bufferedRequest=null,this.lastBufferedRequest=null,this.pendingcb=0,this.prefinished=!1,this.errorEmitted=!1,this.bufferedRequestCount=0,this.corkedRequestsFree=new a(this)}function b(e){if(s=s||n(10),!(d.call(b,this)||this instanceof s))return new b(e);this._writableState=new v(e,this),this.writable=!0,e&&("function"==typeof e.write&&(this._write=e.write),"function"==typeof e.writev&&(this._writev=e.writev),"function"==typeof e.destroy&&(this._destroy=e.destroy),"function"==typeof e.final&&(this._final=e.final)),f.call(this)}function m(e,t,n,r,o,i,a){t.writelen=r,t.writecb=a,t.writing=!0,t.sync=!0,n?e._writev(o,t.onwrite):e._write(o,i,t.onwrite),t.sync=!1}function w(e,t,n,r){n||function(e,t){0===t.length&&t.needDrain&&(t.needDrain=!1,e.emit("drain"))}(e,t),t.pendingcb--,r(),T(e,t)}function E(e,t){t.bufferProcessing=!0;var n=t.bufferedRequest;if(e._writev&&n&&n.next){var r=t.bufferedRequestCount,o=new Array(r),i=t.corkedRequestsFree;i.entry=n;for(var s=0,u=!0;n;)o[s]=n,n.isBuf||(u=!1),n=n.next,s+=1;o.allBuffers=u,m(e,t,!0,t.length,o,"",i.finish),t.pendingcb++,t.lastBufferedRequest=null,i.next?(t.corkedRequestsFree=i.next,i.next=null):t.corkedRequestsFree=new a(t),t.bufferedRequestCount=0}else{for(;n;){var c=n.chunk,l=n.encoding,f=n.callback;if(m(e,t,!1,t.objectMode?1:c.length,c,l,f),n=n.next,t.bufferedRequestCount--,t.writing)break}null===n&&(t.lastBufferedRequest=null)}t.bufferedRequest=n,t.bufferProcessing=!1}function S(e){return e.ending&&0===e.length&&null===e.bufferedRequest&&!e.finished&&!e.writing}function _(e,t){e._final(function(n){t.pendingcb--,n&&e.emit("error",n),t.prefinished=!0,e.emit("prefinish"),T(e,t)})}function T(e,t){var n=S(t);return n&&(!function(e,t){t.prefinished||t.finalCalled||("function"==typeof e._final?(t.pendingcb++,t.finalCalled=!0,i.nextTick(_,e,t)):(t.prefinished=!0,e.emit("prefinish")))}(e,t),0===t.pendingcb&&(t.finished=!0,e.emit("finish"))),n}c.inherits(b,f),v.prototype.getBuffer=function(){for(var e=this.bufferedRequest,t=[];e;)t.push(e),e=e.next;return t},function(){try{Object.defineProperty(v.prototype,"buffer",{get:l.deprecate(function(){return this.getBuffer()},"_writableState.buffer is deprecated. Use _writableState.getBuffer instead.","DEP0003")})}catch(e){}}(),"function"==typeof Symbol&&Symbol.hasInstance&&"function"==typeof Function.prototype[Symbol.hasInstance]?(d=Function.prototype[Symbol.hasInstance],Object.defineProperty(b,Symbol.hasInstance,{value:function(e){return!!d.call(this,e)||this===b&&(e&&e._writableState instanceof v)}})):d=function(e){return e instanceof this},b.prototype.pipe=function(){this.emit("error",new Error("Cannot pipe, not readable"))},b.prototype.write=function(e,t,n){var r,o=this._writableState,a=!1,s=!o.objectMode&&(r=e,h.isBuffer(r)||r instanceof p);return s&&!h.isBuffer(e)&&(e=function(e){return h.from(e)}(e)),"function"==typeof t&&(n=t,t=null),s?t="buffer":t||(t=o.defaultEncoding),"function"!=typeof n&&(n=y),o.ended?function(e,t){var n=new Error("write after end");e.emit("error",n),i.nextTick(t,n)}(this,n):(s||function(e,t,n,r){var o=!0,a=!1;return null===n?a=new TypeError("May not write null values to stream"):"string"==typeof n||void 0===n||t.objectMode||(a=new TypeError("Invalid non-string/buffer chunk")),a&&(e.emit("error",a),i.nextTick(r,a),o=!1),o}(this,o,e,n))&&(o.pendingcb++,a=function(e,t,n,r,o,i){if(!n){var a=function(e,t,n){e.objectMode||!1===e.decodeStrings||"string"!=typeof t||(t=h.from(t,n));return t}(t,r,o);r!==a&&(n=!0,o="buffer",r=a)}var s=t.objectMode?1:r.length;t.length+=s;var u=t.length-1))throw new TypeError("Unknown encoding: "+e);return this._writableState.defaultEncoding=e,this},Object.defineProperty(b.prototype,"writableHighWaterMark",{enumerable:!1,get:function(){return this._writableState.highWaterMark}}),b.prototype._write=function(e,t,n){n(new Error("_write() is not implemented"))},b.prototype._writev=null,b.prototype.end=function(e,t,n){var r=this._writableState;"function"==typeof e?(n=e,e=null,t=null):"function"==typeof t&&(n=t,t=null),null!=e&&this.write(e,t),r.corked&&(r.corked=1,this.uncork()),r.ending||r.finished||function(e,t,n){t.ending=!0,T(e,t),n&&(t.finished?i.nextTick(n):e.once("finish",n));t.ended=!0,e.writable=!1}(this,r,n)},Object.defineProperty(b.prototype,"destroyed",{get:function(){return void 0!==this._writableState&&this._writableState.destroyed},set:function(e){this._writableState&&(this._writableState.destroyed=e)}}),b.prototype.destroy=g.destroy,b.prototype._undestroy=g.undestroy,b.prototype._destroy=function(e,t){this.end(),t(e)}}).call(this,n(14),n(54).setImmediate,n(5))},function(e,t,n){"use strict";var r=n(6).Buffer,o=r.isEncoding||function(e){switch((e=""+e)&&e.toLowerCase()){case"hex":case"utf8":case"utf-8":case"ascii":case"binary":case"base64":case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":case"raw":return!0;default:return!1}};function i(e){var t;switch(this.encoding=function(e){var t=function(e){if(!e)return"utf8";for(var t;;)switch(e){case"utf8":case"utf-8":return"utf8";case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return"utf16le";case"latin1":case"binary":return"latin1";case"base64":case"ascii":case"hex":return e;default:if(t)return;e=(""+e).toLowerCase(),t=!0}}(e);if("string"!=typeof t&&(r.isEncoding===o||!o(e)))throw new Error("Unknown encoding: "+e);return t||e}(e),this.encoding){case"utf16le":this.text=u,this.end=c,t=4;break;case"utf8":this.fillLast=s,t=4;break;case"base64":this.text=l,this.end=f,t=3;break;default:return this.write=h,void(this.end=p)}this.lastNeed=0,this.lastTotal=0,this.lastChar=r.allocUnsafe(t)}function a(e){return e<=127?0:e>>5==6?2:e>>4==14?3:e>>3==30?4:e>>6==2?-1:-2}function s(e){var t=this.lastTotal-this.lastNeed,n=function(e,t,n){if(128!=(192&t[0]))return e.lastNeed=0,"�";if(e.lastNeed>1&&t.length>1){if(128!=(192&t[1]))return e.lastNeed=1,"�";if(e.lastNeed>2&&t.length>2&&128!=(192&t[2]))return e.lastNeed=2,"�"}}(this,e);return void 0!==n?n:this.lastNeed<=e.length?(e.copy(this.lastChar,t,0,this.lastNeed),this.lastChar.toString(this.encoding,0,this.lastTotal)):(e.copy(this.lastChar,t,0,e.length),void(this.lastNeed-=e.length))}function u(e,t){if((e.length-t)%2==0){var n=e.toString("utf16le",t);if(n){var r=n.charCodeAt(n.length-1);if(r>=55296&&r<=56319)return this.lastNeed=2,this.lastTotal=4,this.lastChar[0]=e[e.length-2],this.lastChar[1]=e[e.length-1],n.slice(0,-1)}return n}return this.lastNeed=1,this.lastTotal=2,this.lastChar[0]=e[e.length-1],e.toString("utf16le",t,e.length-1)}function c(e){var t=e&&e.length?this.write(e):"";if(this.lastNeed){var n=this.lastTotal-this.lastNeed;return t+this.lastChar.toString("utf16le",0,n)}return t}function l(e,t){var n=(e.length-t)%3;return 0===n?e.toString("base64",t):(this.lastNeed=3-n,this.lastTotal=3,1===n?this.lastChar[0]=e[e.length-1]:(this.lastChar[0]=e[e.length-2],this.lastChar[1]=e[e.length-1]),e.toString("base64",t,e.length-n))}function f(e){var t=e&&e.length?this.write(e):"";return this.lastNeed?t+this.lastChar.toString("base64",0,3-this.lastNeed):t}function h(e){return e.toString(this.encoding)}function p(e){return e&&e.length?this.write(e):""}t.StringDecoder=i,i.prototype.write=function(e){if(0===e.length)return"";var t,n;if(this.lastNeed){if(void 0===(t=this.fillLast(e)))return"";n=this.lastNeed,this.lastNeed=0}else n=0;return n=0)return o>0&&(e.lastNeed=o-1),o;if(--r=0)return o>0&&(e.lastNeed=o-2),o;if(--r=0)return o>0&&(2===o?o=0:e.lastNeed=o-3),o;return 0}(this,e,t);if(!this.lastNeed)return e.toString("utf8",t);this.lastTotal=n;var r=e.length-(n-this.lastNeed);return e.copy(this.lastChar,0,r),e.toString("utf8",t,r)},i.prototype.fillLast=function(e){if(this.lastNeed<=e.length)return e.copy(this.lastChar,this.lastTotal-this.lastNeed,0,this.lastNeed),this.lastChar.toString(this.encoding,0,this.lastTotal);e.copy(this.lastChar,this.lastTotal-this.lastNeed,0,e.length),this.lastNeed-=e.length}},function(e,t,n){"use strict";e.exports=a;var r=n(10),o=n(15);function i(e,t){var n=this._transformState;n.transforming=!1;var r=n.writecb;if(!r)return this.emit("error",new Error("write callback called multiple times"));n.writechunk=null,n.writecb=null,null!=t&&this.push(t),r(e);var o=this._readableState;o.reading=!1,(o.needReadable||o.length0&&o[o.length-1])&&(6===i[0]||2===i[0])){a=0;continue}if(3===i[0]&&(!o||i[1]>o[0]&&i[1]s?a.slice(s).buffer:null}else{var u,c=t;if(-1===(u=c.indexOf(r.a.RecordSeparator)))throw new Error("Message is incomplete.");s=u+1;n=c.substring(0,s),i=c.length>s?c.substring(s):null}var l=r.a.parse(n),f=JSON.parse(l[0]);if(f.type)throw new Error("Expected a handshake response from the server.");return[i,f]},t}()}).call(this,n(11).Buffer)},,,,,function(e,t,n){"use strict";var r=this&&this.__assign||function(){return(r=Object.assign||function(e){for(var t,n=1,r=arguments.length;n0&&o[o.length-1])&&(6===i[0]||2===i[0])){a=0;continue}if(3===i[0]&&(!o||i[1]>o[0]&&i[1]0?r-4:r,f=0;f>16&255,s[u++]=t>>8&255,s[u++]=255&t;2===a&&(t=o[e.charCodeAt(f)]<<2|o[e.charCodeAt(f+1)]>>4,s[u++]=255&t);1===a&&(t=o[e.charCodeAt(f)]<<10|o[e.charCodeAt(f+1)]<<4|o[e.charCodeAt(f+2)]>>2,s[u++]=t>>8&255,s[u++]=255&t);return s},t.fromByteArray=function(e){for(var t,n=e.length,o=n%3,i=[],a=0,s=n-o;as?s:a+16383));1===o?(t=e[n-1],i.push(r[t>>2]+r[t<<4&63]+"==")):2===o&&(t=(e[n-2]<<8)+e[n-1],i.push(r[t>>10]+r[t>>4&63]+r[t<<2&63]+"="));return i.join("")};for(var r=[],o=[],i="undefined"!=typeof Uint8Array?Uint8Array:Array,a="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",s=0,u=a.length;s0)throw new Error("Invalid string. Length must be a multiple of 4");var n=e.indexOf("=");return-1===n&&(n=t),[n,n===t?0:4-n%4]}function l(e,t,n){for(var o,i,a=[],s=t;s>18&63]+r[i>>12&63]+r[i>>6&63]+r[63&i]);return a.join("")}o["-".charCodeAt(0)]=62,o["_".charCodeAt(0)]=63},function(e,t){t.read=function(e,t,n,r,o){var i,a,s=8*o-r-1,u=(1<>1,l=-7,f=n?o-1:0,h=n?-1:1,p=e[t+f];for(f+=h,i=p&(1<<-l)-1,p>>=-l,l+=s;l>0;i=256*i+e[t+f],f+=h,l-=8);for(a=i&(1<<-l)-1,i>>=-l,l+=r;l>0;a=256*a+e[t+f],f+=h,l-=8);if(0===i)i=1-c;else{if(i===u)return a?NaN:1/0*(p?-1:1);a+=Math.pow(2,r),i-=c}return(p?-1:1)*a*Math.pow(2,i-r)},t.write=function(e,t,n,r,o,i){var a,s,u,c=8*i-o-1,l=(1<>1,h=23===o?Math.pow(2,-24)-Math.pow(2,-77):0,p=r?0:i-1,d=r?1:-1,g=t<0||0===t&&1/t<0?1:0;for(t=Math.abs(t),isNaN(t)||t===1/0?(s=isNaN(t)?1:0,a=l):(a=Math.floor(Math.log(t)/Math.LN2),t*(u=Math.pow(2,-a))<1&&(a--,u*=2),(t+=a+f>=1?h/u:h*Math.pow(2,1-f))*u>=2&&(a++,u/=2),a+f>=l?(s=0,a=l):a+f>=1?(s=(t*u-1)*Math.pow(2,o),a+=f):(s=t*Math.pow(2,f-1)*Math.pow(2,o),a=0));o>=8;e[n+p]=255&s,p+=d,s/=256,o-=8);for(a=a<0;e[n+p]=255&a,p+=d,a/=256,c-=8);e[n+p-d]|=128*g}},function(e,t,n){"use strict";(function(t){ +var r=n(47),o=n(48),i=n(31);function a(){return u.TYPED_ARRAY_SUPPORT?2147483647:1073741823}function s(e,t){if(a()=a())throw new RangeError("Attempt to allocate Buffer larger than maximum size: 0x"+a().toString(16)+" bytes");return 0|e}function d(e,t){if(u.isBuffer(e))return e.length;if("undefined"!=typeof ArrayBuffer&&"function"==typeof ArrayBuffer.isView&&(ArrayBuffer.isView(e)||e instanceof ArrayBuffer))return e.byteLength;"string"!=typeof e&&(e=""+e);var n=e.length;if(0===n)return 0;for(var r=!1;;)switch(t){case"ascii":case"latin1":case"binary":return n;case"utf8":case"utf-8":case void 0:return F(e).length;case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return 2*n;case"hex":return n>>>1;case"base64":return H(e).length;default:if(r)return F(e).length;t=(""+t).toLowerCase(),r=!0}}function g(e,t,n){var r=e[t];e[t]=e[n],e[n]=r}function y(e,t,n,r,o){if(0===e.length)return-1;if("string"==typeof n?(r=n,n=0):n>2147483647?n=2147483647:n<-2147483648&&(n=-2147483648),n=+n,isNaN(n)&&(n=o?0:e.length-1),n<0&&(n=e.length+n),n>=e.length){if(o)return-1;n=e.length-1}else if(n<0){if(!o)return-1;n=0}if("string"==typeof t&&(t=u.from(t,r)),u.isBuffer(t))return 0===t.length?-1:v(e,t,n,r,o);if("number"==typeof t)return t&=255,u.TYPED_ARRAY_SUPPORT&&"function"==typeof Uint8Array.prototype.indexOf?o?Uint8Array.prototype.indexOf.call(e,t,n):Uint8Array.prototype.lastIndexOf.call(e,t,n):v(e,[t],n,r,o);throw new TypeError("val must be string, number or Buffer")}function v(e,t,n,r,o){var i,a=1,s=e.length,u=t.length;if(void 0!==r&&("ucs2"===(r=String(r).toLowerCase())||"ucs-2"===r||"utf16le"===r||"utf-16le"===r)){if(e.length<2||t.length<2)return-1;a=2,s/=2,u/=2,n/=2}function c(e,t){return 1===a?e[t]:e.readUInt16BE(t*a)}if(o){var l=-1;for(i=n;is&&(n=s-u),i=n;i>=0;i--){for(var f=!0,h=0;ho&&(r=o):r=o;var i=t.length;if(i%2!=0)throw new TypeError("Invalid hex string");r>i/2&&(r=i/2);for(var a=0;a>8,o=n%256,i.push(o),i.push(r);return i}(t,e.length-n),e,n,r)}function T(e,t,n){return 0===t&&n===e.length?r.fromByteArray(e):r.fromByteArray(e.slice(t,n))}function k(e,t,n){n=Math.min(e.length,n);for(var r=[],o=t;o239?4:c>223?3:c>191?2:1;if(o+f<=n)switch(f){case 1:c<128&&(l=c);break;case 2:128==(192&(i=e[o+1]))&&(u=(31&c)<<6|63&i)>127&&(l=u);break;case 3:i=e[o+1],a=e[o+2],128==(192&i)&&128==(192&a)&&(u=(15&c)<<12|(63&i)<<6|63&a)>2047&&(u<55296||u>57343)&&(l=u);break;case 4:i=e[o+1],a=e[o+2],s=e[o+3],128==(192&i)&&128==(192&a)&&128==(192&s)&&(u=(15&c)<<18|(63&i)<<12|(63&a)<<6|63&s)>65535&&u<1114112&&(l=u)}null===l?(l=65533,f=1):l>65535&&(l-=65536,r.push(l>>>10&1023|55296),l=56320|1023&l),r.push(l),o+=f}return function(e){var t=e.length;if(t<=C)return String.fromCharCode.apply(String,e);var n="",r=0;for(;rthis.length)return"";if((void 0===n||n>this.length)&&(n=this.length),n<=0)return"";if((n>>>=0)<=(t>>>=0))return"";for(e||(e="utf8");;)switch(e){case"hex":return R(this,t,n);case"utf8":case"utf-8":return k(this,t,n);case"ascii":return I(this,t,n);case"latin1":case"binary":return x(this,t,n);case"base64":return T(this,t,n);case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return O(this,t,n);default:if(r)throw new TypeError("Unknown encoding: "+e);e=(e+"").toLowerCase(),r=!0}}.apply(this,arguments)},u.prototype.equals=function(e){if(!u.isBuffer(e))throw new TypeError("Argument must be a Buffer");return this===e||0===u.compare(this,e)},u.prototype.inspect=function(){var e="",n=t.INSPECT_MAX_BYTES;return this.length>0&&(e=this.toString("hex",0,n).match(/.{2}/g).join(" "),this.length>n&&(e+=" ... ")),""},u.prototype.compare=function(e,t,n,r,o){if(!u.isBuffer(e))throw new TypeError("Argument must be a Buffer");if(void 0===t&&(t=0),void 0===n&&(n=e?e.length:0),void 0===r&&(r=0),void 0===o&&(o=this.length),t<0||n>e.length||r<0||o>this.length)throw new RangeError("out of range index");if(r>=o&&t>=n)return 0;if(r>=o)return-1;if(t>=n)return 1;if(this===e)return 0;for(var i=(o>>>=0)-(r>>>=0),a=(n>>>=0)-(t>>>=0),s=Math.min(i,a),c=this.slice(r,o),l=e.slice(t,n),f=0;fo)&&(n=o),e.length>0&&(n<0||t<0)||t>this.length)throw new RangeError("Attempt to write outside buffer bounds");r||(r="utf8");for(var i=!1;;)switch(r){case"hex":return m(this,e,t,n);case"utf8":case"utf-8":return b(this,e,t,n);case"ascii":return w(this,e,t,n);case"latin1":case"binary":return E(this,e,t,n);case"base64":return S(this,e,t,n);case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return _(this,e,t,n);default:if(i)throw new TypeError("Unknown encoding: "+r);r=(""+r).toLowerCase(),i=!0}},u.prototype.toJSON=function(){return{type:"Buffer",data:Array.prototype.slice.call(this._arr||this,0)}};var C=4096;function I(e,t,n){var r="";n=Math.min(e.length,n);for(var o=t;or)&&(n=r);for(var o="",i=t;in)throw new RangeError("Trying to access beyond buffer length")}function M(e,t,n,r,o,i){if(!u.isBuffer(e))throw new TypeError('"buffer" argument must be a Buffer instance');if(t>o||te.length)throw new RangeError("Index out of range")}function L(e,t,n,r){t<0&&(t=65535+t+1);for(var o=0,i=Math.min(e.length-n,2);o>>8*(r?o:1-o)}function A(e,t,n,r){t<0&&(t=4294967295+t+1);for(var o=0,i=Math.min(e.length-n,4);o>>8*(r?o:3-o)&255}function B(e,t,n,r,o,i){if(n+r>e.length)throw new RangeError("Index out of range");if(n<0)throw new RangeError("Index out of range")}function D(e,t,n,r,i){return i||B(e,0,n,4),o.write(e,t,n,r,23,4),n+4}function U(e,t,n,r,i){return i||B(e,0,n,8),o.write(e,t,n,r,52,8),n+8}u.prototype.slice=function(e,t){var n,r=this.length;if((e=~~e)<0?(e+=r)<0&&(e=0):e>r&&(e=r),(t=void 0===t?r:~~t)<0?(t+=r)<0&&(t=0):t>r&&(t=r),t0&&(o*=256);)r+=this[e+--t]*o;return r},u.prototype.readUInt8=function(e,t){return t||P(e,1,this.length),this[e]},u.prototype.readUInt16LE=function(e,t){return t||P(e,2,this.length),this[e]|this[e+1]<<8},u.prototype.readUInt16BE=function(e,t){return t||P(e,2,this.length),this[e]<<8|this[e+1]},u.prototype.readUInt32LE=function(e,t){return t||P(e,4,this.length),(this[e]|this[e+1]<<8|this[e+2]<<16)+16777216*this[e+3]},u.prototype.readUInt32BE=function(e,t){return t||P(e,4,this.length),16777216*this[e]+(this[e+1]<<16|this[e+2]<<8|this[e+3])},u.prototype.readIntLE=function(e,t,n){e|=0,t|=0,n||P(e,t,this.length);for(var r=this[e],o=1,i=0;++i=(o*=128)&&(r-=Math.pow(2,8*t)),r},u.prototype.readIntBE=function(e,t,n){e|=0,t|=0,n||P(e,t,this.length);for(var r=t,o=1,i=this[e+--r];r>0&&(o*=256);)i+=this[e+--r]*o;return i>=(o*=128)&&(i-=Math.pow(2,8*t)),i},u.prototype.readInt8=function(e,t){return t||P(e,1,this.length),128&this[e]?-1*(255-this[e]+1):this[e]},u.prototype.readInt16LE=function(e,t){t||P(e,2,this.length);var n=this[e]|this[e+1]<<8;return 32768&n?4294901760|n:n},u.prototype.readInt16BE=function(e,t){t||P(e,2,this.length);var n=this[e+1]|this[e]<<8;return 32768&n?4294901760|n:n},u.prototype.readInt32LE=function(e,t){return t||P(e,4,this.length),this[e]|this[e+1]<<8|this[e+2]<<16|this[e+3]<<24},u.prototype.readInt32BE=function(e,t){return t||P(e,4,this.length),this[e]<<24|this[e+1]<<16|this[e+2]<<8|this[e+3]},u.prototype.readFloatLE=function(e,t){return t||P(e,4,this.length),o.read(this,e,!0,23,4)},u.prototype.readFloatBE=function(e,t){return t||P(e,4,this.length),o.read(this,e,!1,23,4)},u.prototype.readDoubleLE=function(e,t){return t||P(e,8,this.length),o.read(this,e,!0,52,8)},u.prototype.readDoubleBE=function(e,t){return t||P(e,8,this.length),o.read(this,e,!1,52,8)},u.prototype.writeUIntLE=function(e,t,n,r){(e=+e,t|=0,n|=0,r)||M(this,e,t,n,Math.pow(2,8*n)-1,0);var o=1,i=0;for(this[t]=255&e;++i=0&&(i*=256);)this[t+o]=e/i&255;return t+n},u.prototype.writeUInt8=function(e,t,n){return e=+e,t|=0,n||M(this,e,t,1,255,0),u.TYPED_ARRAY_SUPPORT||(e=Math.floor(e)),this[t]=255&e,t+1},u.prototype.writeUInt16LE=function(e,t,n){return e=+e,t|=0,n||M(this,e,t,2,65535,0),u.TYPED_ARRAY_SUPPORT?(this[t]=255&e,this[t+1]=e>>>8):L(this,e,t,!0),t+2},u.prototype.writeUInt16BE=function(e,t,n){return e=+e,t|=0,n||M(this,e,t,2,65535,0),u.TYPED_ARRAY_SUPPORT?(this[t]=e>>>8,this[t+1]=255&e):L(this,e,t,!1),t+2},u.prototype.writeUInt32LE=function(e,t,n){return e=+e,t|=0,n||M(this,e,t,4,4294967295,0),u.TYPED_ARRAY_SUPPORT?(this[t+3]=e>>>24,this[t+2]=e>>>16,this[t+1]=e>>>8,this[t]=255&e):A(this,e,t,!0),t+4},u.prototype.writeUInt32BE=function(e,t,n){return e=+e,t|=0,n||M(this,e,t,4,4294967295,0),u.TYPED_ARRAY_SUPPORT?(this[t]=e>>>24,this[t+1]=e>>>16,this[t+2]=e>>>8,this[t+3]=255&e):A(this,e,t,!1),t+4},u.prototype.writeIntLE=function(e,t,n,r){if(e=+e,t|=0,!r){var o=Math.pow(2,8*n-1);M(this,e,t,n,o-1,-o)}var i=0,a=1,s=0;for(this[t]=255&e;++i>0)-s&255;return t+n},u.prototype.writeIntBE=function(e,t,n,r){if(e=+e,t|=0,!r){var o=Math.pow(2,8*n-1);M(this,e,t,n,o-1,-o)}var i=n-1,a=1,s=0;for(this[t+i]=255&e;--i>=0&&(a*=256);)e<0&&0===s&&0!==this[t+i+1]&&(s=1),this[t+i]=(e/a>>0)-s&255;return t+n},u.prototype.writeInt8=function(e,t,n){return e=+e,t|=0,n||M(this,e,t,1,127,-128),u.TYPED_ARRAY_SUPPORT||(e=Math.floor(e)),e<0&&(e=255+e+1),this[t]=255&e,t+1},u.prototype.writeInt16LE=function(e,t,n){return e=+e,t|=0,n||M(this,e,t,2,32767,-32768),u.TYPED_ARRAY_SUPPORT?(this[t]=255&e,this[t+1]=e>>>8):L(this,e,t,!0),t+2},u.prototype.writeInt16BE=function(e,t,n){return e=+e,t|=0,n||M(this,e,t,2,32767,-32768),u.TYPED_ARRAY_SUPPORT?(this[t]=e>>>8,this[t+1]=255&e):L(this,e,t,!1),t+2},u.prototype.writeInt32LE=function(e,t,n){return e=+e,t|=0,n||M(this,e,t,4,2147483647,-2147483648),u.TYPED_ARRAY_SUPPORT?(this[t]=255&e,this[t+1]=e>>>8,this[t+2]=e>>>16,this[t+3]=e>>>24):A(this,e,t,!0),t+4},u.prototype.writeInt32BE=function(e,t,n){return e=+e,t|=0,n||M(this,e,t,4,2147483647,-2147483648),e<0&&(e=4294967295+e+1),u.TYPED_ARRAY_SUPPORT?(this[t]=e>>>24,this[t+1]=e>>>16,this[t+2]=e>>>8,this[t+3]=255&e):A(this,e,t,!1),t+4},u.prototype.writeFloatLE=function(e,t,n){return D(this,e,t,!0,n)},u.prototype.writeFloatBE=function(e,t,n){return D(this,e,t,!1,n)},u.prototype.writeDoubleLE=function(e,t,n){return U(this,e,t,!0,n)},u.prototype.writeDoubleBE=function(e,t,n){return U(this,e,t,!1,n)},u.prototype.copy=function(e,t,n,r){if(n||(n=0),r||0===r||(r=this.length),t>=e.length&&(t=e.length),t||(t=0),r>0&&r=this.length)throw new RangeError("sourceStart out of bounds");if(r<0)throw new RangeError("sourceEnd out of bounds");r>this.length&&(r=this.length),e.length-t=0;--o)e[o+t]=this[o+n];else if(i<1e3||!u.TYPED_ARRAY_SUPPORT)for(o=0;o>>=0,n=void 0===n?this.length:n>>>0,e||(e=0),"number"==typeof e)for(i=t;i55295&&n<57344){if(!o){if(n>56319){(t-=3)>-1&&i.push(239,191,189);continue}if(a+1===r){(t-=3)>-1&&i.push(239,191,189);continue}o=n;continue}if(n<56320){(t-=3)>-1&&i.push(239,191,189),o=n;continue}n=65536+(o-55296<<10|n-56320)}else o&&(t-=3)>-1&&i.push(239,191,189);if(o=null,n<128){if((t-=1)<0)break;i.push(n)}else if(n<2048){if((t-=2)<0)break;i.push(n>>6|192,63&n|128)}else if(n<65536){if((t-=3)<0)break;i.push(n>>12|224,n>>6&63|128,63&n|128)}else{if(!(n<1114112))throw new Error("Invalid code point");if((t-=4)<0)break;i.push(n>>18|240,n>>12&63|128,n>>6&63|128,63&n|128)}}return i}function H(e){return r.toByteArray(function(e){if((e=function(e){return e.trim?e.trim():e.replace(/^\s+|\s+$/g,"")}(e).replace(N,"")).length<2)return"";for(;e.length%4!=0;)e+="=";return e}(e))}function q(e,t,n,r){for(var o=0;o=t.length||o>=e.length);++o)t[o+n]=e[o];return o}}).call(this,n(5))},function(e,t,n){"use strict";var r;!function(e){window.DotNet=e;var t=[],n={},r={},o=1,i=null;function a(e){t.push(e)}function s(e,t){for(var n=[],r=2;r1)for(var n=1;n0&&o[o.length-1])&&(6===i[0]||2===i[0])){a=0;continue}if(3===i[0]&&(!o||i[1]>o[0]&&i[1]this.length||e<0)){var t=this._offset(e);return this._bufs[t[0]][t[1]]}},a.prototype.slice=function(e,t){return"number"==typeof e&&e<0&&(e+=this.length),"number"==typeof t&&t<0&&(t+=this.length),this.copy(null,0,e,t)},a.prototype.copy=function(e,t,n,r){if(("number"!=typeof n||n<0)&&(n=0),("number"!=typeof r||r>this.length)&&(r=this.length),n>=this.length)return e||i.alloc(0);if(r<=0)return e||i.alloc(0);var o,a,s=!!e,u=this._offset(n),c=r-n,l=c,f=s&&t||0,h=u[1];if(0===n&&r==this.length){if(!s)return 1===this._bufs.length?this._bufs[0]:i.concat(this._bufs,this.length);for(a=0;a(o=this._bufs[a].length-h))){this._bufs[a].copy(e,f,h,h+l);break}this._bufs[a].copy(e,f,h),f+=o,l-=o,h&&(h=0)}return e},a.prototype.shallowSlice=function(e,t){if(e=e||0,t="number"!=typeof t?this.length:t,e<0&&(e+=this.length),t<0&&(t+=this.length),e===t)return new a;var n=this._offset(e),r=this._offset(t),o=this._bufs.slice(n[0],r[0]+1);return 0==r[1]?o.pop():o[o.length-1]=o[o.length-1].slice(0,r[1]),0!=n[1]&&(o[0]=o[0].slice(n[1])),new a(o)},a.prototype.toString=function(e,t,n){return this.slice(t,n).toString(e)},a.prototype.consume=function(e){for(;this._bufs.length;){if(!(e>=this._bufs[0].length)){this._bufs[0]=this._bufs[0].slice(e),this.length-=e;break}e-=this._bufs[0].length,this.length-=this._bufs[0].length,this._bufs.shift()}return this},a.prototype.duplicate=function(){for(var e=0,t=new a;ethis.length?this.length:t;for(var r=this._offset(t),o=r[0],s=r[1];o=e.length){var c=u.indexOf(e,s);if(-1!==c)return this._reverseOffset([o,c]);s=u.length-e.length+1}else{var l=this._reverseOffset([o,s]);if(this._match(l,e))return l;s++}}s=0}return-1},a.prototype._match=function(e,t){if(this.length-e=0,"must have a non-negative type"),o(a,"must have a decode function"),this.registerEncoder(function(e){return e instanceof t},function(t){var o=i(),a=r.allocUnsafe(1);return a.writeInt8(e,0),o.append(a),o.append(n(t)),o}),this.registerDecoder(e,a),this},registerEncoder:function(e,n){return o(e,"must have an encode function"),o(n,"must have an encode function"),t.push({check:e,encode:n}),this},registerDecoder:function(e,t){return o(e>=0,"must have a non-negative type"),o(t,"must have a decode function"),n.push({type:e,decode:t}),this},encoder:a.encoder,decoder:a.decoder,buffer:!0,type:"msgpack5",IncompleteBufferError:s.IncompleteBufferError}}},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var r=n(16),o=n(22),i=n(8);window.Blazor={navigateTo:r.navigateTo,_internal:{attachRootComponentToElement:i.attachRootComponentToElement,http:o.internalFunctions,uriHelper:r.internalFunctions}}},function(e,t,n){"use strict";var r=this&&this.__awaiter||function(e,t,n,r){return new(n||(n=Promise))(function(o,i){function a(e){try{u(r.next(e))}catch(e){i(e)}}function s(e){try{u(r.throw(e))}catch(e){i(e)}}function u(e){e.done?o(e.value):new n(function(t){t(e.value)}).then(a,s)}u((r=r.apply(e,t||[])).next())})},o=this&&this.__generator||function(e,t){var n,r,o,i,a={label:0,sent:function(){if(1&o[0])throw o[1];return o[1]},trys:[],ops:[]};return i={next:s(0),throw:s(1),return:s(2)},"function"==typeof Symbol&&(i[Symbol.iterator]=function(){return this}),i;function s(i){return function(s){return function(i){if(n)throw new TypeError("Generator is already executing.");for(;a;)try{if(n=1,r&&(o=2&i[0]?r.return:i[0]?r.throw||((o=r.return)&&o.call(r),0):r.next)&&!(o=o.call(r,i[1])).done)return o;switch(r=0,o&&(i=[2&i[0],o.value]),i[0]){case 0:case 1:o=i;break;case 4:return a.label++,{value:i[1],done:!1};case 5:a.label++,r=i[1],i=[0];continue;case 7:i=a.ops.pop(),a.trys.pop();continue;default:if(!(o=(o=a.trys).length>0&&o[o.length-1])&&(6===i[0]||2===i[0])){a=0;continue}if(3===i[0]&&(!o||i[1]>o[0]&&i[1]0&&o[o.length-1])&&(6===i[0]||2===i[0])){a=0;continue}if(3===i[0]&&(!o||i[1]>o[0]&&i[1]=i)return e;switch(e){case"%s":return String(r[n++]);case"%d":return Number(r[n++]);case"%j":try{return JSON.stringify(r[n++])}catch(e){return"[Circular]"}default:return e}}),u=r[n];n=3&&(r.depth=arguments[2]),arguments.length>=4&&(r.colors=arguments[3]),d(n)?r.showHidden=n:n&&t._extend(r,n),m(r.showHidden)&&(r.showHidden=!1),m(r.depth)&&(r.depth=2),m(r.colors)&&(r.colors=!1),m(r.customInspect)&&(r.customInspect=!0),r.colors&&(r.stylize=u),l(r,e,r.depth)}function u(e,t){var n=s.styles[t];return n?"["+s.colors[n][0]+"m"+e+"["+s.colors[n][1]+"m":e}function c(e,t){return e}function l(e,n,r){if(e.customInspect&&n&&_(n.inspect)&&n.inspect!==t.inspect&&(!n.constructor||n.constructor.prototype!==n)){var o=n.inspect(r,e);return v(o)||(o=l(e,o,r)),o}var i=function(e,t){if(m(t))return e.stylize("undefined","undefined");if(v(t)){var n="'"+JSON.stringify(t).replace(/^"|"$/g,"").replace(/'/g,"\\'").replace(/\\"/g,'"')+"'";return e.stylize(n,"string")}if(y(t))return e.stylize(""+t,"number");if(d(t))return e.stylize(""+t,"boolean");if(g(t))return e.stylize("null","null")}(e,n);if(i)return i;var a=Object.keys(n),s=function(e){var t={};return e.forEach(function(e,n){t[e]=!0}),t}(a);if(e.showHidden&&(a=Object.getOwnPropertyNames(n)),S(n)&&(a.indexOf("message")>=0||a.indexOf("description")>=0))return f(n);if(0===a.length){if(_(n)){var u=n.name?": "+n.name:"";return e.stylize("[Function"+u+"]","special")}if(b(n))return e.stylize(RegExp.prototype.toString.call(n),"regexp");if(E(n))return e.stylize(Date.prototype.toString.call(n),"date");if(S(n))return f(n)}var c,w="",T=!1,k=["{","}"];(p(n)&&(T=!0,k=["[","]"]),_(n))&&(w=" [Function"+(n.name?": "+n.name:"")+"]");return b(n)&&(w=" "+RegExp.prototype.toString.call(n)),E(n)&&(w=" "+Date.prototype.toUTCString.call(n)),S(n)&&(w=" "+f(n)),0!==a.length||T&&0!=n.length?r<0?b(n)?e.stylize(RegExp.prototype.toString.call(n),"regexp"):e.stylize("[Object]","special"):(e.seen.push(n),c=T?function(e,t,n,r,o){for(var i=[],a=0,s=t.length;a=0&&0,e+t.replace(/\u001b\[\d\d?m/g,"").length+1},0)>60)return n[0]+(""===t?"":t+"\n ")+" "+e.join(",\n ")+" "+n[1];return n[0]+t+" "+e.join(", ")+" "+n[1]}(c,w,k)):k[0]+w+k[1]}function f(e){return"["+Error.prototype.toString.call(e)+"]"}function h(e,t,n,r,o,i){var a,s,u;if((u=Object.getOwnPropertyDescriptor(t,o)||{value:t[o]}).get?s=u.set?e.stylize("[Getter/Setter]","special"):e.stylize("[Getter]","special"):u.set&&(s=e.stylize("[Setter]","special")),I(r,o)||(a="["+o+"]"),s||(e.seen.indexOf(u.value)<0?(s=g(n)?l(e,u.value,null):l(e,u.value,n-1)).indexOf("\n")>-1&&(s=i?s.split("\n").map(function(e){return" "+e}).join("\n").substr(2):"\n"+s.split("\n").map(function(e){return" "+e}).join("\n")):s=e.stylize("[Circular]","special")),m(a)){if(i&&o.match(/^\d+$/))return s;(a=JSON.stringify(""+o)).match(/^"([a-zA-Z_][a-zA-Z_0-9]*)"$/)?(a=a.substr(1,a.length-2),a=e.stylize(a,"name")):(a=a.replace(/'/g,"\\'").replace(/\\"/g,'"').replace(/(^"|"$)/g,"'"),a=e.stylize(a,"string"))}return a+": "+s}function p(e){return Array.isArray(e)}function d(e){return"boolean"==typeof e}function g(e){return null===e}function y(e){return"number"==typeof e}function v(e){return"string"==typeof e}function m(e){return void 0===e}function b(e){return w(e)&&"[object RegExp]"===T(e)}function w(e){return"object"==typeof e&&null!==e}function E(e){return w(e)&&"[object Date]"===T(e)}function S(e){return w(e)&&("[object Error]"===T(e)||e instanceof Error)}function _(e){return"function"==typeof e}function T(e){return Object.prototype.toString.call(e)}function k(e){return e<10?"0"+e.toString(10):e.toString(10)}t.debuglog=function(n){if(m(i)&&(i=e.env.NODE_DEBUG||""),n=n.toUpperCase(),!a[n])if(new RegExp("\\b"+n+"\\b","i").test(i)){var r=e.pid;a[n]=function(){var e=t.format.apply(t,arguments);console.error("%s %d: %s",n,r,e)}}else a[n]=function(){};return a[n]},t.inspect=s,s.colors={bold:[1,22],italic:[3,23],underline:[4,24],inverse:[7,27],white:[37,39],grey:[90,39],black:[30,39],blue:[34,39],cyan:[36,39],green:[32,39],magenta:[35,39],red:[31,39],yellow:[33,39]},s.styles={special:"cyan",number:"yellow",boolean:"yellow",undefined:"grey",null:"bold",string:"green",date:"magenta",regexp:"red"},t.isArray=p,t.isBoolean=d,t.isNull=g,t.isNullOrUndefined=function(e){return null==e},t.isNumber=y,t.isString=v,t.isSymbol=function(e){return"symbol"==typeof e},t.isUndefined=m,t.isRegExp=b,t.isObject=w,t.isDate=E,t.isError=S,t.isFunction=_,t.isPrimitive=function(e){return null===e||"boolean"==typeof e||"number"==typeof e||"string"==typeof e||"symbol"==typeof e||void 0===e},t.isBuffer=n(50);var C=["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"];function I(e,t){return Object.prototype.hasOwnProperty.call(e,t)}t.log=function(){var e,n;console.log("%s - %s",(e=new Date,n=[k(e.getHours()),k(e.getMinutes()),k(e.getSeconds())].join(":"),[e.getDate(),C[e.getMonth()],n].join(" ")),t.format.apply(t,arguments))},t.inherits=n(7),t._extend=function(e,t){if(!t||!w(t))return e;for(var n=Object.keys(t),r=n.length;r--;)e[n[r]]=t[n[r]];return e};var x="undefined"!=typeof Symbol?Symbol("util.promisify.custom"):void 0;function R(e,t){if(!e){var n=new Error("Promise was rejected with a falsy value");n.reason=e,e=n}return t(e)}t.promisify=function(e){if("function"!=typeof e)throw new TypeError('The "original" argument must be of type Function');if(x&&e[x]){var t;if("function"!=typeof(t=e[x]))throw new TypeError('The "util.promisify.custom" argument must be of type Function');return Object.defineProperty(t,x,{value:t,enumerable:!1,writable:!1,configurable:!0}),t}function t(){for(var t,n,r=new Promise(function(e,r){t=e,n=r}),o=[],i=0;i0?("string"==typeof t||a.objectMode||Object.getPrototypeOf(t)===c.prototype||(t=function(e){return c.from(e)}(t)),r?a.endEmitted?e.emit("error",new Error("stream.unshift() after end event")):E(e,a,t,!0):a.ended?e.emit("error",new Error("stream.push() after EOF")):(a.reading=!1,a.decoder&&!n?(t=a.decoder.write(t),a.objectMode||0!==t.length?E(e,a,t,!1):C(e,a)):E(e,a,t,!1))):r||(a.reading=!1));return function(e){return!e.ended&&(e.needReadable||e.lengtht.highWaterMark&&(t.highWaterMark=function(e){return e>=S?e=S:(e--,e|=e>>>1,e|=e>>>2,e|=e>>>4,e|=e>>>8,e|=e>>>16,e++),e}(e)),e<=t.length?e:t.ended?t.length:(t.needReadable=!0,0))}function T(e){var t=e._readableState;t.needReadable=!1,t.emittedReadable||(p("emitReadable",t.flowing),t.emittedReadable=!0,t.sync?o.nextTick(k,e):k(e))}function k(e){p("emit readable"),e.emit("readable"),O(e)}function C(e,t){t.readingMore||(t.readingMore=!0,o.nextTick(I,e,t))}function I(e,t){for(var n=t.length;!t.reading&&!t.flowing&&!t.ended&&t.length=t.length?(n=t.decoder?t.buffer.join(""):1===t.buffer.length?t.buffer.head.data:t.buffer.concat(t.length),t.buffer.clear()):n=function(e,t,n){var r;ei.length?i.length:e;if(a===i.length?o+=i:o+=i.slice(0,e),0===(e-=a)){a===i.length?(++r,n.next?t.head=n.next:t.head=t.tail=null):(t.head=n,n.data=i.slice(a));break}++r}return t.length-=r,o}(e,t):function(e,t){var n=c.allocUnsafe(e),r=t.head,o=1;r.data.copy(n),e-=r.data.length;for(;r=r.next;){var i=r.data,a=e>i.length?i.length:e;if(i.copy(n,n.length-e,0,a),0===(e-=a)){a===i.length?(++o,r.next?t.head=r.next:t.head=t.tail=null):(t.head=r,r.data=i.slice(a));break}++o}return t.length-=o,n}(e,t);return r}(e,t.buffer,t.decoder),n);var n}function M(e){var t=e._readableState;if(t.length>0)throw new Error('"endReadable()" called on non-empty stream');t.endEmitted||(t.ended=!0,o.nextTick(L,t,e))}function L(e,t){e.endEmitted||0!==e.length||(e.endEmitted=!0,t.readable=!1,t.emit("end"))}function A(e,t){for(var n=0,r=e.length;n=t.highWaterMark||t.ended))return p("read: emitReadable",t.length,t.ended),0===t.length&&t.ended?M(this):T(this),null;if(0===(e=_(e,t))&&t.ended)return 0===t.length&&M(this),null;var r,o=t.needReadable;return p("need readable",o),(0===t.length||t.length-e0?P(e,t):null)?(t.needReadable=!0,e=0):t.length-=e,0===t.length&&(t.ended||(t.needReadable=!0),n!==e&&t.ended&&M(this)),null!==r&&this.emit("data",r),r},b.prototype._read=function(e){this.emit("error",new Error("_read() is not implemented"))},b.prototype.pipe=function(e,t){var n=this,i=this._readableState;switch(i.pipesCount){case 0:i.pipes=e;break;case 1:i.pipes=[i.pipes,e];break;default:i.pipes.push(e)}i.pipesCount+=1,p("pipe count=%d opts=%j",i.pipesCount,t);var u=(!t||!1!==t.end)&&e!==r.stdout&&e!==r.stderr?l:b;function c(t,r){p("onunpipe"),t===n&&r&&!1===r.hasUnpiped&&(r.hasUnpiped=!0,p("cleanup"),e.removeListener("close",v),e.removeListener("finish",m),e.removeListener("drain",f),e.removeListener("error",y),e.removeListener("unpipe",c),n.removeListener("end",l),n.removeListener("end",b),n.removeListener("data",g),h=!0,!i.awaitDrain||e._writableState&&!e._writableState.needDrain||f())}function l(){p("onend"),e.end()}i.endEmitted?o.nextTick(u):n.once("end",u),e.on("unpipe",c);var f=function(e){return function(){var t=e._readableState;p("pipeOnDrain",t.awaitDrain),t.awaitDrain&&t.awaitDrain--,0===t.awaitDrain&&s(e,"data")&&(t.flowing=!0,O(e))}}(n);e.on("drain",f);var h=!1;var d=!1;function g(t){p("ondata"),d=!1,!1!==e.write(t)||d||((1===i.pipesCount&&i.pipes===e||i.pipesCount>1&&-1!==A(i.pipes,e))&&!h&&(p("false write response, pause",n._readableState.awaitDrain),n._readableState.awaitDrain++,d=!0),n.pause())}function y(t){p("onerror",t),b(),e.removeListener("error",y),0===s(e,"error")&&e.emit("error",t)}function v(){e.removeListener("finish",m),b()}function m(){p("onfinish"),e.removeListener("close",v),b()}function b(){p("unpipe"),n.unpipe(e)}return n.on("data",g),function(e,t,n){if("function"==typeof e.prependListener)return e.prependListener(t,n);e._events&&e._events[t]?a(e._events[t])?e._events[t].unshift(n):e._events[t]=[n,e._events[t]]:e.on(t,n)}(e,"error",y),e.once("close",v),e.once("finish",m),e.emit("pipe",n),i.flowing||(p("pipe resume"),n.resume()),e},b.prototype.unpipe=function(e){var t=this._readableState,n={hasUnpiped:!1};if(0===t.pipesCount)return this;if(1===t.pipesCount)return e&&e!==t.pipes?this:(e||(e=t.pipes),t.pipes=null,t.pipesCount=0,t.flowing=!1,e&&e.emit("unpipe",this,n),this);if(!e){var r=t.pipes,o=t.pipesCount;t.pipes=null,t.pipesCount=0,t.flowing=!1;for(var i=0;i0&&a.length>o&&!a.warned){a.warned=!0;var u=new Error("Possible EventEmitter memory leak detected. "+a.length+" "+String(t)+" listeners added. Use emitter.setMaxListeners() to increase limit");u.name="MaxListenersExceededWarning",u.emitter=e,u.type=t,u.count=a.length,s=u,console&&console.warn&&console.warn(s)}return e}function f(e,t,n){var r={fired:!1,wrapFn:void 0,target:e,type:t,listener:n},o=function(){for(var e=[],t=0;t0&&(a=t[0]),a instanceof Error)throw a;var s=new Error("Unhandled error."+(a?" ("+a.message+")":""));throw s.context=a,s}var u=o[e];if(void 0===u)return!1;if("function"==typeof u)i(u,this,t);else{var c=u.length,l=d(u,c);for(n=0;n=0;i--)if(n[i]===t||n[i].listener===t){a=n[i].listener,o=i;break}if(o<0)return this;0===o?n.shift():function(e,t){for(;t+1=0;r--)this.removeListener(e,t[r]);return this},s.prototype.listeners=function(e){return h(this,e,!0)},s.prototype.rawListeners=function(e){return h(this,e,!1)},s.listenerCount=function(e,t){return"function"==typeof e.listenerCount?e.listenerCount(t):p.call(e,t)},s.prototype.listenerCount=p,s.prototype.eventNames=function(){return this._eventsCount>0?r(this._events):[]}},function(e,t,n){e.exports=n(34).EventEmitter},function(e,t,n){"use strict";var r=n(18);function o(e,t){e.emit("error",t)}e.exports={destroy:function(e,t){var n=this,i=this._readableState&&this._readableState.destroyed,a=this._writableState&&this._writableState.destroyed;return i||a?(t?t(e):!e||this._writableState&&this._writableState.errorEmitted||r.nextTick(o,this,e),this):(this._readableState&&(this._readableState.destroyed=!0),this._writableState&&(this._writableState.destroyed=!0),this._destroy(e||null,function(e){!t&&e?(r.nextTick(o,n,e),n._writableState&&(n._writableState.errorEmitted=!0)):t&&t(e)}),this)},undestroy:function(){this._readableState&&(this._readableState.destroyed=!1,this._readableState.reading=!1,this._readableState.ended=!1,this._readableState.endEmitted=!1),this._writableState&&(this._writableState.destroyed=!1,this._writableState.ended=!1,this._writableState.ending=!1,this._writableState.finished=!1,this._writableState.errorEmitted=!1)}}},function(e,t,n){"use strict";(function(t,r,o){var i=n(18);function a(e){var t=this;this.next=null,this.entry=null,this.finish=function(){!function(e,t,n){var r=e.entry;e.entry=null;for(;r;){var o=r.callback;t.pendingcb--,o(n),r=r.next}t.corkedRequestsFree?t.corkedRequestsFree.next=e:t.corkedRequestsFree=e}(t,e)}}e.exports=m;var s,u=!t.browser&&["v0.10","v0.9."].indexOf(t.version.slice(0,5))>-1?r:i.nextTick;m.WritableState=v;var c=n(15);c.inherits=n(7);var l={deprecate:n(56)},f=n(35),h=n(6).Buffer,p=o.Uint8Array||function(){};var d,g=n(36);function y(){}function v(e,t){s=s||n(10),e=e||{};var r=t instanceof s;this.objectMode=!!e.objectMode,r&&(this.objectMode=this.objectMode||!!e.writableObjectMode);var o=e.highWaterMark,c=e.writableHighWaterMark,l=this.objectMode?16:16384;this.highWaterMark=o||0===o?o:r&&(c||0===c)?c:l,this.highWaterMark=Math.floor(this.highWaterMark),this.finalCalled=!1,this.needDrain=!1,this.ending=!1,this.ended=!1,this.finished=!1,this.destroyed=!1;var f=!1===e.decodeStrings;this.decodeStrings=!f,this.defaultEncoding=e.defaultEncoding||"utf8",this.length=0,this.writing=!1,this.corked=0,this.sync=!0,this.bufferProcessing=!1,this.onwrite=function(e){!function(e,t){var n=e._writableState,r=n.sync,o=n.writecb;if(function(e){e.writing=!1,e.writecb=null,e.length-=e.writelen,e.writelen=0}(n),t)!function(e,t,n,r,o){--t.pendingcb,n?(i.nextTick(o,r),i.nextTick(T,e,t),e._writableState.errorEmitted=!0,e.emit("error",r)):(o(r),e._writableState.errorEmitted=!0,e.emit("error",r),T(e,t))}(e,n,r,t,o);else{var a=S(n);a||n.corked||n.bufferProcessing||!n.bufferedRequest||E(e,n),r?u(w,e,n,a,o):w(e,n,a,o)}}(t,e)},this.writecb=null,this.writelen=0,this.bufferedRequest=null,this.lastBufferedRequest=null,this.pendingcb=0,this.prefinished=!1,this.errorEmitted=!1,this.bufferedRequestCount=0,this.corkedRequestsFree=new a(this)}function m(e){if(s=s||n(10),!(d.call(m,this)||this instanceof s))return new m(e);this._writableState=new v(e,this),this.writable=!0,e&&("function"==typeof e.write&&(this._write=e.write),"function"==typeof e.writev&&(this._writev=e.writev),"function"==typeof e.destroy&&(this._destroy=e.destroy),"function"==typeof e.final&&(this._final=e.final)),f.call(this)}function b(e,t,n,r,o,i,a){t.writelen=r,t.writecb=a,t.writing=!0,t.sync=!0,n?e._writev(o,t.onwrite):e._write(o,i,t.onwrite),t.sync=!1}function w(e,t,n,r){n||function(e,t){0===t.length&&t.needDrain&&(t.needDrain=!1,e.emit("drain"))}(e,t),t.pendingcb--,r(),T(e,t)}function E(e,t){t.bufferProcessing=!0;var n=t.bufferedRequest;if(e._writev&&n&&n.next){var r=t.bufferedRequestCount,o=new Array(r),i=t.corkedRequestsFree;i.entry=n;for(var s=0,u=!0;n;)o[s]=n,n.isBuf||(u=!1),n=n.next,s+=1;o.allBuffers=u,b(e,t,!0,t.length,o,"",i.finish),t.pendingcb++,t.lastBufferedRequest=null,i.next?(t.corkedRequestsFree=i.next,i.next=null):t.corkedRequestsFree=new a(t),t.bufferedRequestCount=0}else{for(;n;){var c=n.chunk,l=n.encoding,f=n.callback;if(b(e,t,!1,t.objectMode?1:c.length,c,l,f),n=n.next,t.bufferedRequestCount--,t.writing)break}null===n&&(t.lastBufferedRequest=null)}t.bufferedRequest=n,t.bufferProcessing=!1}function S(e){return e.ending&&0===e.length&&null===e.bufferedRequest&&!e.finished&&!e.writing}function _(e,t){e._final(function(n){t.pendingcb--,n&&e.emit("error",n),t.prefinished=!0,e.emit("prefinish"),T(e,t)})}function T(e,t){var n=S(t);return n&&(!function(e,t){t.prefinished||t.finalCalled||("function"==typeof e._final?(t.pendingcb++,t.finalCalled=!0,i.nextTick(_,e,t)):(t.prefinished=!0,e.emit("prefinish")))}(e,t),0===t.pendingcb&&(t.finished=!0,e.emit("finish"))),n}c.inherits(m,f),v.prototype.getBuffer=function(){for(var e=this.bufferedRequest,t=[];e;)t.push(e),e=e.next;return t},function(){try{Object.defineProperty(v.prototype,"buffer",{get:l.deprecate(function(){return this.getBuffer()},"_writableState.buffer is deprecated. Use _writableState.getBuffer instead.","DEP0003")})}catch(e){}}(),"function"==typeof Symbol&&Symbol.hasInstance&&"function"==typeof Function.prototype[Symbol.hasInstance]?(d=Function.prototype[Symbol.hasInstance],Object.defineProperty(m,Symbol.hasInstance,{value:function(e){return!!d.call(this,e)||this===m&&(e&&e._writableState instanceof v)}})):d=function(e){return e instanceof this},m.prototype.pipe=function(){this.emit("error",new Error("Cannot pipe, not readable"))},m.prototype.write=function(e,t,n){var r,o=this._writableState,a=!1,s=!o.objectMode&&(r=e,h.isBuffer(r)||r instanceof p);return s&&!h.isBuffer(e)&&(e=function(e){return h.from(e)}(e)),"function"==typeof t&&(n=t,t=null),s?t="buffer":t||(t=o.defaultEncoding),"function"!=typeof n&&(n=y),o.ended?function(e,t){var n=new Error("write after end");e.emit("error",n),i.nextTick(t,n)}(this,n):(s||function(e,t,n,r){var o=!0,a=!1;return null===n?a=new TypeError("May not write null values to stream"):"string"==typeof n||void 0===n||t.objectMode||(a=new TypeError("Invalid non-string/buffer chunk")),a&&(e.emit("error",a),i.nextTick(r,a),o=!1),o}(this,o,e,n))&&(o.pendingcb++,a=function(e,t,n,r,o,i){if(!n){var a=function(e,t,n){e.objectMode||!1===e.decodeStrings||"string"!=typeof t||(t=h.from(t,n));return t}(t,r,o);r!==a&&(n=!0,o="buffer",r=a)}var s=t.objectMode?1:r.length;t.length+=s;var u=t.length-1))throw new TypeError("Unknown encoding: "+e);return this._writableState.defaultEncoding=e,this},Object.defineProperty(m.prototype,"writableHighWaterMark",{enumerable:!1,get:function(){return this._writableState.highWaterMark}}),m.prototype._write=function(e,t,n){n(new Error("_write() is not implemented"))},m.prototype._writev=null,m.prototype.end=function(e,t,n){var r=this._writableState;"function"==typeof e?(n=e,e=null,t=null):"function"==typeof t&&(n=t,t=null),null!=e&&this.write(e,t),r.corked&&(r.corked=1,this.uncork()),r.ending||r.finished||function(e,t,n){t.ending=!0,T(e,t),n&&(t.finished?i.nextTick(n):e.once("finish",n));t.ended=!0,e.writable=!1}(this,r,n)},Object.defineProperty(m.prototype,"destroyed",{get:function(){return void 0!==this._writableState&&this._writableState.destroyed},set:function(e){this._writableState&&(this._writableState.destroyed=e)}}),m.prototype.destroy=g.destroy,m.prototype._undestroy=g.undestroy,m.prototype._destroy=function(e,t){this.end(),t(e)}}).call(this,n(14),n(54).setImmediate,n(5))},function(e,t,n){"use strict";var r=n(6).Buffer,o=r.isEncoding||function(e){switch((e=""+e)&&e.toLowerCase()){case"hex":case"utf8":case"utf-8":case"ascii":case"binary":case"base64":case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":case"raw":return!0;default:return!1}};function i(e){var t;switch(this.encoding=function(e){var t=function(e){if(!e)return"utf8";for(var t;;)switch(e){case"utf8":case"utf-8":return"utf8";case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return"utf16le";case"latin1":case"binary":return"latin1";case"base64":case"ascii":case"hex":return e;default:if(t)return;e=(""+e).toLowerCase(),t=!0}}(e);if("string"!=typeof t&&(r.isEncoding===o||!o(e)))throw new Error("Unknown encoding: "+e);return t||e}(e),this.encoding){case"utf16le":this.text=u,this.end=c,t=4;break;case"utf8":this.fillLast=s,t=4;break;case"base64":this.text=l,this.end=f,t=3;break;default:return this.write=h,void(this.end=p)}this.lastNeed=0,this.lastTotal=0,this.lastChar=r.allocUnsafe(t)}function a(e){return e<=127?0:e>>5==6?2:e>>4==14?3:e>>3==30?4:e>>6==2?-1:-2}function s(e){var t=this.lastTotal-this.lastNeed,n=function(e,t,n){if(128!=(192&t[0]))return e.lastNeed=0,"�";if(e.lastNeed>1&&t.length>1){if(128!=(192&t[1]))return e.lastNeed=1,"�";if(e.lastNeed>2&&t.length>2&&128!=(192&t[2]))return e.lastNeed=2,"�"}}(this,e);return void 0!==n?n:this.lastNeed<=e.length?(e.copy(this.lastChar,t,0,this.lastNeed),this.lastChar.toString(this.encoding,0,this.lastTotal)):(e.copy(this.lastChar,t,0,e.length),void(this.lastNeed-=e.length))}function u(e,t){if((e.length-t)%2==0){var n=e.toString("utf16le",t);if(n){var r=n.charCodeAt(n.length-1);if(r>=55296&&r<=56319)return this.lastNeed=2,this.lastTotal=4,this.lastChar[0]=e[e.length-2],this.lastChar[1]=e[e.length-1],n.slice(0,-1)}return n}return this.lastNeed=1,this.lastTotal=2,this.lastChar[0]=e[e.length-1],e.toString("utf16le",t,e.length-1)}function c(e){var t=e&&e.length?this.write(e):"";if(this.lastNeed){var n=this.lastTotal-this.lastNeed;return t+this.lastChar.toString("utf16le",0,n)}return t}function l(e,t){var n=(e.length-t)%3;return 0===n?e.toString("base64",t):(this.lastNeed=3-n,this.lastTotal=3,1===n?this.lastChar[0]=e[e.length-1]:(this.lastChar[0]=e[e.length-2],this.lastChar[1]=e[e.length-1]),e.toString("base64",t,e.length-n))}function f(e){var t=e&&e.length?this.write(e):"";return this.lastNeed?t+this.lastChar.toString("base64",0,3-this.lastNeed):t}function h(e){return e.toString(this.encoding)}function p(e){return e&&e.length?this.write(e):""}t.StringDecoder=i,i.prototype.write=function(e){if(0===e.length)return"";var t,n;if(this.lastNeed){if(void 0===(t=this.fillLast(e)))return"";n=this.lastNeed,this.lastNeed=0}else n=0;return n=0)return o>0&&(e.lastNeed=o-1),o;if(--r=0)return o>0&&(e.lastNeed=o-2),o;if(--r=0)return o>0&&(2===o?o=0:e.lastNeed=o-3),o;return 0}(this,e,t);if(!this.lastNeed)return e.toString("utf8",t);this.lastTotal=n;var r=e.length-(n-this.lastNeed);return e.copy(this.lastChar,0,r),e.toString("utf8",t,r)},i.prototype.fillLast=function(e){if(this.lastNeed<=e.length)return e.copy(this.lastChar,this.lastTotal-this.lastNeed,0,this.lastNeed),this.lastChar.toString(this.encoding,0,this.lastTotal);e.copy(this.lastChar,this.lastTotal-this.lastNeed,0,e.length),this.lastNeed-=e.length}},function(e,t,n){"use strict";e.exports=a;var r=n(10),o=n(15);function i(e,t){var n=this._transformState;n.transforming=!1;var r=n.writecb;if(!r)return this.emit("error",new Error("write callback called multiple times"));n.writechunk=null,n.writecb=null,null!=t&&this.push(t),r(e);var o=this._readableState;o.reading=!1,(o.needReadable||o.length0&&o[o.length-1])&&(6===i[0]||2===i[0])){a=0;continue}if(3===i[0]&&(!o||i[1]>o[0]&&i[1]s?a.slice(s).buffer:null}else{var u,c=t;if(-1===(u=c.indexOf(r.a.RecordSeparator)))throw new Error("Message is incomplete.");s=u+1;n=c.substring(0,s),i=c.length>s?c.substring(s):null}var l=r.a.parse(n),f=JSON.parse(l[0]);if(f.type)throw new Error("Expected a handshake response from the server.");return[i,f]},t}()}).call(this,n(11).Buffer)},,,,,function(e,t,n){"use strict";var r=this&&this.__assign||function(){return(r=Object.assign||function(e){for(var t,n=1,r=arguments.length;n0&&o[o.length-1])&&(6===i[0]||2===i[0])){a=0;continue}if(3===i[0]&&(!o||i[1]>o[0]&&i[1]0?r-4:r,f=0;f>16&255,s[u++]=t>>8&255,s[u++]=255&t;2===a&&(t=o[e.charCodeAt(f)]<<2|o[e.charCodeAt(f+1)]>>4,s[u++]=255&t);1===a&&(t=o[e.charCodeAt(f)]<<10|o[e.charCodeAt(f+1)]<<4|o[e.charCodeAt(f+2)]>>2,s[u++]=t>>8&255,s[u++]=255&t);return s},t.fromByteArray=function(e){for(var t,n=e.length,o=n%3,i=[],a=0,s=n-o;as?s:a+16383));1===o?(t=e[n-1],i.push(r[t>>2]+r[t<<4&63]+"==")):2===o&&(t=(e[n-2]<<8)+e[n-1],i.push(r[t>>10]+r[t>>4&63]+r[t<<2&63]+"="));return i.join("")};for(var r=[],o=[],i="undefined"!=typeof Uint8Array?Uint8Array:Array,a="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",s=0,u=a.length;s0)throw new Error("Invalid string. Length must be a multiple of 4");var n=e.indexOf("=");return-1===n&&(n=t),[n,n===t?0:4-n%4]}function l(e,t,n){for(var o,i,a=[],s=t;s>18&63]+r[i>>12&63]+r[i>>6&63]+r[63&i]);return a.join("")}o["-".charCodeAt(0)]=62,o["_".charCodeAt(0)]=63},function(e,t){t.read=function(e,t,n,r,o){var i,a,s=8*o-r-1,u=(1<>1,l=-7,f=n?o-1:0,h=n?-1:1,p=e[t+f];for(f+=h,i=p&(1<<-l)-1,p>>=-l,l+=s;l>0;i=256*i+e[t+f],f+=h,l-=8);for(a=i&(1<<-l)-1,i>>=-l,l+=r;l>0;a=256*a+e[t+f],f+=h,l-=8);if(0===i)i=1-c;else{if(i===u)return a?NaN:1/0*(p?-1:1);a+=Math.pow(2,r),i-=c}return(p?-1:1)*a*Math.pow(2,i-r)},t.write=function(e,t,n,r,o,i){var a,s,u,c=8*i-o-1,l=(1<>1,h=23===o?Math.pow(2,-24)-Math.pow(2,-77):0,p=r?0:i-1,d=r?1:-1,g=t<0||0===t&&1/t<0?1:0;for(t=Math.abs(t),isNaN(t)||t===1/0?(s=isNaN(t)?1:0,a=l):(a=Math.floor(Math.log(t)/Math.LN2),t*(u=Math.pow(2,-a))<1&&(a--,u*=2),(t+=a+f>=1?h/u:h*Math.pow(2,1-f))*u>=2&&(a++,u/=2),a+f>=l?(s=0,a=l):a+f>=1?(s=(t*u-1)*Math.pow(2,o),a+=f):(s=t*Math.pow(2,f-1)*Math.pow(2,o),a=0));o>=8;e[n+p]=255&s,p+=d,s/=256,o-=8);for(a=a<0;e[n+p]=255&a,p+=d,a/=256,c-=8);e[n+p-d]|=128*g}},function(e,t,n){"use strict";(function(t){ /*! * The buffer module from node.js, for the browser. * * @author Feross Aboukhadijeh * @license MIT */ -function r(e,t){if(e===t)return 0;for(var n=e.length,r=t.length,o=0,i=Math.min(n,r);o=0;c--)if(l[c]!==f[c])return!1;for(c=l.length-1;c>=0;c--)if(u=l[c],!b(e[u],t[u],n,r))return!1;return!0}(e,t,n,a))}return n?e===t:e==t}function m(e){return"[object Arguments]"==Object.prototype.toString.call(e)}function w(e,t){if(!e||!t)return!1;if("[object RegExp]"==Object.prototype.toString.call(t))return t.test(e);try{if(e instanceof t)return!0}catch(e){}return!Error.isPrototypeOf(t)&&!0===t.call({},e)}function E(e,t,n,r){var o;if("function"!=typeof t)throw new TypeError('"block" argument must be a function');"string"==typeof n&&(r=n,n=null),o=function(e){var t;try{e()}catch(e){t=e}return t}(t),r=(n&&n.name?" ("+n.name+").":".")+(r?" "+r:"."),e&&!o&&y(o,n,"Missing expected exception"+r);var a="string"==typeof r,s=!e&&o&&!n;if((!e&&i.isError(o)&&a&&w(o,n)||s)&&y(o,n,"Got unwanted exception"+r),e&&o&&n&&!w(o,n)||!e&&o)throw o}f.AssertionError=function(e){var t;this.name="AssertionError",this.actual=e.actual,this.expected=e.expected,this.operator=e.operator,e.message?(this.message=e.message,this.generatedMessage=!1):(this.message=d(g((t=this).actual),128)+" "+t.operator+" "+d(g(t.expected),128),this.generatedMessage=!0);var n=e.stackStartFunction||y;if(Error.captureStackTrace)Error.captureStackTrace(this,n);else{var r=new Error;if(r.stack){var o=r.stack,i=p(n),a=o.indexOf("\n"+i);if(a>=0){var s=o.indexOf("\n",a+1);o=o.substring(s+1)}this.stack=o}}},i.inherits(f.AssertionError,Error),f.fail=y,f.ok=v,f.equal=function(e,t,n){e!=t&&y(e,t,n,"==",f.equal)},f.notEqual=function(e,t,n){e==t&&y(e,t,n,"!=",f.notEqual)},f.deepEqual=function(e,t,n){b(e,t,!1)||y(e,t,n,"deepEqual",f.deepEqual)},f.deepStrictEqual=function(e,t,n){b(e,t,!0)||y(e,t,n,"deepStrictEqual",f.deepStrictEqual)},f.notDeepEqual=function(e,t,n){b(e,t,!1)&&y(e,t,n,"notDeepEqual",f.notDeepEqual)},f.notDeepStrictEqual=function e(t,n,r){b(t,n,!0)&&y(t,n,r,"notDeepStrictEqual",e)},f.strictEqual=function(e,t,n){e!==t&&y(e,t,n,"===",f.strictEqual)},f.notStrictEqual=function(e,t,n){e===t&&y(e,t,n,"!==",f.notStrictEqual)},f.throws=function(e,t,n){E(!0,e,t,n)},f.doesNotThrow=function(e,t,n){E(!1,e,t,n)},f.ifError=function(e){if(e)throw e};var S=Object.keys||function(e){var t=[];for(var n in e)a.call(e,n)&&t.push(n);return t}}).call(this,n(5))},function(e,t){e.exports=function(e){return e&&"object"==typeof e&&"function"==typeof e.copy&&"function"==typeof e.fill&&"function"==typeof e.readUInt8}},function(e,t){},function(e,t,n){"use strict";var r=n(6).Buffer,o=n(53);e.exports=function(){function e(){!function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,e),this.head=null,this.tail=null,this.length=0}return e.prototype.push=function(e){var t={data:e,next:null};this.length>0?this.tail.next=t:this.head=t,this.tail=t,++this.length},e.prototype.unshift=function(e){var t={data:e,next:this.head};0===this.length&&(this.tail=t),this.head=t,++this.length},e.prototype.shift=function(){if(0!==this.length){var e=this.head.data;return 1===this.length?this.head=this.tail=null:this.head=this.head.next,--this.length,e}},e.prototype.clear=function(){this.head=this.tail=null,this.length=0},e.prototype.join=function(e){if(0===this.length)return"";for(var t=this.head,n=""+t.data;t=t.next;)n+=e+t.data;return n},e.prototype.concat=function(e){if(0===this.length)return r.alloc(0);if(1===this.length)return this.head.data;for(var t,n,o,i=r.allocUnsafe(e>>>0),a=this.head,s=0;a;)t=a.data,n=i,o=s,t.copy(n,o),s+=a.data.length,a=a.next;return i},e}(),o&&o.inspect&&o.inspect.custom&&(e.exports.prototype[o.inspect.custom]=function(){var e=o.inspect({length:this.length});return this.constructor.name+" "+e})},function(e,t){},function(e,t,n){(function(e){var r=void 0!==e&&e||"undefined"!=typeof self&&self||window,o=Function.prototype.apply;function i(e,t){this._id=e,this._clearFn=t}t.setTimeout=function(){return new i(o.call(setTimeout,r,arguments),clearTimeout)},t.setInterval=function(){return new i(o.call(setInterval,r,arguments),clearInterval)},t.clearTimeout=t.clearInterval=function(e){e&&e.close()},i.prototype.unref=i.prototype.ref=function(){},i.prototype.close=function(){this._clearFn.call(r,this._id)},t.enroll=function(e,t){clearTimeout(e._idleTimeoutId),e._idleTimeout=t},t.unenroll=function(e){clearTimeout(e._idleTimeoutId),e._idleTimeout=-1},t._unrefActive=t.active=function(e){clearTimeout(e._idleTimeoutId);var t=e._idleTimeout;t>=0&&(e._idleTimeoutId=setTimeout(function(){e._onTimeout&&e._onTimeout()},t))},n(55),t.setImmediate="undefined"!=typeof self&&self.setImmediate||void 0!==e&&e.setImmediate||this&&this.setImmediate,t.clearImmediate="undefined"!=typeof self&&self.clearImmediate||void 0!==e&&e.clearImmediate||this&&this.clearImmediate}).call(this,n(5))},function(e,t,n){(function(e,t){!function(e,n){"use strict";if(!e.setImmediate){var r,o,i,a,s,u=1,c={},l=!1,f=e.document,h=Object.getPrototypeOf&&Object.getPrototypeOf(e);h=h&&h.setTimeout?h:e,"[object process]"==={}.toString.call(e.process)?r=function(e){t.nextTick(function(){d(e)})}:!function(){if(e.postMessage&&!e.importScripts){var t=!0,n=e.onmessage;return e.onmessage=function(){t=!1},e.postMessage("","*"),e.onmessage=n,t}}()?e.MessageChannel?((i=new MessageChannel).port1.onmessage=function(e){d(e.data)},r=function(e){i.port2.postMessage(e)}):f&&"onreadystatechange"in f.createElement("script")?(o=f.documentElement,r=function(e){var t=f.createElement("script");t.onreadystatechange=function(){d(e),t.onreadystatechange=null,o.removeChild(t),t=null},o.appendChild(t)}):r=function(e){setTimeout(d,0,e)}:(a="setImmediate$"+Math.random()+"$",s=function(t){t.source===e&&"string"==typeof t.data&&0===t.data.indexOf(a)&&d(+t.data.slice(a.length))},e.addEventListener?e.addEventListener("message",s,!1):e.attachEvent("onmessage",s),r=function(t){e.postMessage(a+t,"*")}),h.setImmediate=function(e){"function"!=typeof e&&(e=new Function(""+e));for(var t=new Array(arguments.length-1),n=0;n0?this._transform(null,t,n):n()},e.exports.decoder=u,e.exports.encoder=s},function(e,t,n){"use strict";var r=n(17);function o(e){Error.call(this),Error.captureStackTrace&&Error.captureStackTrace(this,this.constructor),this.name=this.constructor.name,this.message=e||"unable to decode"}n(30).inherits(o,Error),e.exports=function(e){return function(e){e instanceof r||(e=r().append(e));var t=i(e);if(t)return e.consume(t.bytesConsumed),t.value;throw new o};function t(e,t,n){return t>=n+e}function n(e,t){return{value:e,bytesConsumed:t}}function i(e,r){r=void 0===r?0:r;var o=e.length-r;if(o<=0)return null;var i,l,f,h=e.readUInt8(r),p=0;if(!function(e,t){var n=function(e){switch(e){case 196:return 2;case 197:return 3;case 198:return 5;case 199:return 3;case 200:return 4;case 201:return 6;case 202:return 5;case 203:return 9;case 204:return 2;case 205:return 3;case 206:return 5;case 207:return 9;case 208:return 2;case 209:return 3;case 210:return 5;case 211:return 9;case 212:return 3;case 213:return 4;case 214:return 6;case 215:return 10;case 216:return 18;case 217:return 2;case 218:return 3;case 219:return 5;case 222:return 3;default:return-1}}(e);return!(-1!==n&&t=0;f--)p+=e.readUInt8(r+f+1)*Math.pow(2,8*(7-f));return n(p,9);case 208:return n(p=e.readInt8(r+1),2);case 209:return n(p=e.readInt16BE(r+1),3);case 210:return n(p=e.readInt32BE(r+1),5);case 211:return n(p=function(e,t){var n=128==(128&e[t]);if(n)for(var r=1,o=t+7;o>=t;o--){var i=(255^e[o])+r;e[o]=255&i,r=i>>8}var a=e.readUInt32BE(t+0),s=e.readUInt32BE(t+4);return(4294967296*a+s)*(n?-1:1)}(e.slice(r+1,r+9),0),9);case 202:return n(p=e.readFloatBE(r+1),5);case 203:return n(p=e.readDoubleBE(r+1),9);case 217:return t(i=e.readUInt8(r+1),o,2)?n(p=e.toString("utf8",r+2,r+2+i),2+i):null;case 218:return t(i=e.readUInt16BE(r+1),o,3)?n(p=e.toString("utf8",r+3,r+3+i),3+i):null;case 219:return t(i=e.readUInt32BE(r+1),o,5)?n(p=e.toString("utf8",r+5,r+5+i),5+i):null;case 196:return t(i=e.readUInt8(r+1),o,2)?n(p=e.slice(r+2,r+2+i),2+i):null;case 197:return t(i=e.readUInt16BE(r+1),o,3)?n(p=e.slice(r+3,r+3+i),3+i):null;case 198:return t(i=e.readUInt32BE(r+1),o,5)?n(p=e.slice(r+5,r+5+i),5+i):null;case 220:return o<3?null:(i=e.readUInt16BE(r+1),a(e,r,i,3));case 221:return o<5?null:(i=e.readUInt32BE(r+1),a(e,r,i,5));case 222:return i=e.readUInt16BE(r+1),s(e,r,i,3);case 223:return i=e.readUInt32BE(r+1),s(e,r,i,5);case 212:return u(e,r,1);case 213:return u(e,r,2);case 214:return u(e,r,4);case 215:return u(e,r,8);case 216:return u(e,r,16);case 199:return i=e.readUInt8(r+1),l=e.readUInt8(r+2),t(i,o,3)?c(e,r,l,i,3):null;case 200:return i=e.readUInt16BE(r+1),l=e.readUInt8(r+3),t(i,o,4)?c(e,r,l,i,4):null;case 201:return i=e.readUInt32BE(r+1),l=e.readUInt8(r+5),t(i,o,6)?c(e,r,l,i,6):null}if(144==(240&h))return a(e,r,i=15&h,1);if(128==(240&h))return s(e,r,i=15&h,1);if(160==(224&h))return t(i=31&h,o,1)?n(p=e.toString("utf8",r+1,r+i+1),i+1):null;if(h>=224)return n(p=h-256,1);if(h<128)return n(h,1);throw new Error("not implemented yet")}function a(e,t,r,o){var a,s=[],u=0;for(t+=o,a=0;a0&&l.write(u,1)):f<=255&&!n?((l=r.allocUnsafe(2+f))[0]=217,l[1]=f,l.write(u,2)):f<=65535?((l=r.allocUnsafe(3+f))[0]=218,l.writeUInt16BE(f,1),l.write(u,3)):((l=r.allocUnsafe(5+f))[0]=219,l.writeUInt32BE(f,1),l.write(u,5));else if(u&&(u.readUInt32LE||u instanceof Uint8Array))u instanceof Uint8Array&&(u=r.from(u)),u.length<=255?((l=r.allocUnsafe(2))[0]=196,l[1]=u.length):u.length<=65535?((l=r.allocUnsafe(3))[0]=197,l.writeUInt16BE(u.length,1)):((l=r.allocUnsafe(5))[0]=198,l.writeUInt32BE(u.length,1)),l=o([l,u]);else if(Array.isArray(u))u.length<16?(l=r.allocUnsafe(1))[0]=144|u.length:u.length<65536?((l=r.allocUnsafe(3))[0]=220,l.writeUInt16BE(u.length,1)):((l=r.allocUnsafe(5))[0]=221,l.writeUInt32BE(u.length,1)),l=u.reduce(function(e,t){return e.append(s(t,!0)),e},o().append(l));else{if(!a&&"function"==typeof u.getDate)return function(e){var t,n=1*e,i=Math.floor(n/1e3),a=1e6*(n-1e3*i);if(a||i>4294967295){(t=r.allocUnsafe(10))[0]=215,t[1]=-1;var s=4*a,u=i/Math.pow(2,32),c=s+u&4294967295,l=4294967295&i;t.writeInt32BE(c,2),t.writeInt32BE(l,6)}else(t=r.allocUnsafe(6))[0]=214,t[1]=-1,t.writeUInt32BE(Math.floor(n/1e3),2);return o().append(t)}(u);if("object"==typeof u)l=function(t){var n,i,a=-1,s=[];for(n=0;n>8),s.push(255&a)):(s.push(201),s.push(a>>24),s.push(a>>16&255),s.push(a>>8&255),s.push(255&a));return o().append(r.from(s)).append(i)}(u)||function(e){var t,n,i=[],a=0;for(t in e)e.hasOwnProperty(t)&&void 0!==e[t]&&"function"!=typeof e[t]&&(++a,i.push(s(t,!0)),i.push(s(e[t],!0)));a<16?(n=r.allocUnsafe(1))[0]=128|a:a<65535?((n=r.allocUnsafe(3))[0]=222,n.writeUInt16BE(a,1)):((n=r.allocUnsafe(5))[0]=223,n.writeUInt32BE(a,1));return i.unshift(n),i.reduce(function(e,t){return e.append(t)},o())}(u);else if("number"==typeof u){if(function(e){return e%1!=0}(u))return i(u,t);if(u>=0)if(u<128)(l=r.allocUnsafe(1))[0]=u;else if(u<256)(l=r.allocUnsafe(2))[0]=204,l[1]=u;else if(u<65536)(l=r.allocUnsafe(3))[0]=205,l.writeUInt16BE(u,1);else if(u<=4294967295)(l=r.allocUnsafe(5))[0]=206,l.writeUInt32BE(u,1);else{if(!(u<=9007199254740991))return i(u,!0);(l=r.allocUnsafe(9))[0]=207,function(e,t){for(var n=7;n>=0;n--)e[n+1]=255&t,t/=256}(l,u)}else if(u>=-32)(l=r.allocUnsafe(1))[0]=256+u;else if(u>=-128)(l=r.allocUnsafe(2))[0]=208,l.writeInt8(u,1);else if(u>=-32768)(l=r.allocUnsafe(3))[0]=209,l.writeInt16BE(u,1);else if(u>-214748365)(l=r.allocUnsafe(5))[0]=210,l.writeInt32BE(u,1);else{if(!(u>=-9007199254740991))return i(u,!0);(l=r.allocUnsafe(9))[0]=211,function(e,t,n){var r=n<0;r&&(n=Math.abs(n));var o=n%4294967296,i=n/4294967296;if(e.writeUInt32BE(Math.floor(i),t+0),e.writeUInt32BE(o,t+4),r)for(var a=1,s=t+7;s>=t;s--){var u=(255^e[s])+a;e[s]=255&u,a=u>>8}}(l,1,u)}}}if(!l)throw new Error("not implemented yet");return c?l:l.slice()}return s}},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var r=function(){function e(e){this.dialog=e}return e.prototype.show=function(){this.removeClasses(),this.dialog.classList.add(e.ShowClassName)},e.prototype.hide=function(){this.removeClasses(),this.dialog.classList.add(e.HideClassName)},e.prototype.failed=function(){this.removeClasses(),this.dialog.classList.add(e.FailedClassName)},e.prototype.removeClasses=function(){this.dialog.classList.remove(e.ShowClassName,e.HideClassName,e.FailedClassName)},e.ShowClassName="components-reconnect-show",e.HideClassName="components-reconnect-hide",e.FailedClassName="components-reconnect-failed",e}();t.UserSpecifiedDisplay=r},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var r=n(40),o=function(){function e(e){this.document=e,this.addedToDom=!1,this.modal=this.document.createElement("div"),this.modal.id=r.AutoReconnectCircuitHandler.DialogId;this.modal.style.cssText=["position: fixed","top: 0","right: 0","bottom: 0","left: 0","z-index: 1000","display: none","overflow: hidden","background-color: #fff","opacity: 0.8","text-align: center","font-weight: bold"].join(";"),this.modal.innerHTML='
',this.message=this.modal.querySelector("h5"),this.button=this.modal.querySelector("button"),this.button.addEventListener("click",function(){return window.Blazor.reconnect()})}return e.prototype.show=function(){this.addedToDom||(this.addedToDom=!0,this.document.body.appendChild(this.modal)),this.modal.style.display="block",this.button.style.display="none",this.message.textContent="Attempting to reconnect to the server..."},e.prototype.hide=function(){this.modal.style.display="none"},e.prototype.failed=function(){this.button.style.display="block",this.message.textContent="Failed to reconnect to the server."},e}();t.DefaultReconnectDisplay=o},function(e,t,n){"use strict";var r=this&&this.__awaiter||function(e,t,n,r){return new(n||(n=Promise))(function(o,i){function a(e){try{u(r.next(e))}catch(e){i(e)}}function s(e){try{u(r.throw(e))}catch(e){i(e)}}function u(e){e.done?o(e.value):new n(function(t){t(e.value)}).then(a,s)}u((r=r.apply(e,t||[])).next())})},o=this&&this.__generator||function(e,t){var n,r,o,i,a={label:0,sent:function(){if(1&o[0])throw o[1];return o[1]},trys:[],ops:[]};return i={next:s(0),throw:s(1),return:s(2)},"function"==typeof Symbol&&(i[Symbol.iterator]=function(){return this}),i;function s(i){return function(s){return function(i){if(n)throw new TypeError("Generator is already executing.");for(;a;)try{if(n=1,r&&(o=2&i[0]?r.return:i[0]?r.throw||((o=r.return)&&o.call(r),0):r.next)&&!(o=o.call(r,i[1])).done)return o;switch(r=0,o&&(i=[2&i[0],o.value]),i[0]){case 0:case 1:o=i;break;case 4:return a.label++,{value:i[1],done:!1};case 5:a.label++,r=i[1],i=[0];continue;case 7:i=a.ops.pop(),a.trys.pop();continue;default:if(!(o=(o=a.trys).length>0&&o[o.length-1])&&(6===i[0]||2===i[0])){a=0;continue}if(3===i[0]&&(!o||i[1]>o[0]&&i[1]this.nextBatchId)this.logger.log(s.LogLevel.Debug,"Waiting for batch "+this.nextBatchId+". Batch "+e+" not processed.");else try{this.nextBatchId++,this.logger.log(s.LogLevel.Debug,"Applying batch "+e+"."),i.renderBatch(this.browserRendererId,new a.OutOfProcessRenderBatch(t)),this.completeBatch(n,e)}catch(t){throw this.logger.log(s.LogLevel.Error,"There was an error applying batch "+e+"."),n.send("OnRenderCompleted",e,t.toString()),t}},e.prototype.getLastBatchid=function(){return this.nextBatchId-1},e.prototype.completeBatch=function(e,t){return r(this,void 0,void 0,function(){return o(this,function(n){switch(n.label){case 0:return n.trys.push([0,2,,3]),[4,e.send("OnRenderCompleted",t,null)];case 1:return n.sent(),[3,3];case 2:return n.sent(),this.logger.log(s.LogLevel.Warning,"Failed to deliver completion notification for render '"+t+"'."),[3,3];case 3:return[2]}})})},e.renderQueues=new Map,e}();t.default=u},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var r=n(65),o=function(){function e(e){this.batchData=e;var t=new u(e);this.arrayRangeReader=new c(e),this.arraySegmentReader=new l(e),this.diffReader=new i(e),this.editReader=new a(e,t),this.frameReader=new s(e,t)}return e.prototype.updatedComponents=function(){return f(this.batchData,this.batchData.length-20)},e.prototype.referenceFrames=function(){return f(this.batchData,this.batchData.length-16)},e.prototype.disposedComponentIds=function(){return f(this.batchData,this.batchData.length-12)},e.prototype.disposedEventHandlerIds=function(){return f(this.batchData,this.batchData.length-8)},e.prototype.updatedComponentsEntry=function(e,t){var n=e+4*t;return f(this.batchData,n)},e.prototype.referenceFramesEntry=function(e,t){return e+16*t},e.prototype.disposedComponentIdsEntry=function(e,t){var n=e+4*t;return f(this.batchData,n)},e.prototype.disposedEventHandlerIdsEntry=function(e,t){var n=e+4*t;return f(this.batchData,n)},e}();t.OutOfProcessRenderBatch=o;var i=function(){function e(e){this.batchDataUint8=e}return e.prototype.componentId=function(e){return f(this.batchDataUint8,e)},e.prototype.edits=function(e){return e+4},e.prototype.editsEntry=function(e,t){return e+16*t},e}(),a=function(){function e(e,t){this.batchDataUint8=e,this.stringReader=t}return e.prototype.editType=function(e){return f(this.batchDataUint8,e)},e.prototype.siblingIndex=function(e){return f(this.batchDataUint8,e+4)},e.prototype.newTreeIndex=function(e){return f(this.batchDataUint8,e+8)},e.prototype.removedAttributeName=function(e){var t=f(this.batchDataUint8,e+12);return this.stringReader.readString(t)},e}(),s=function(){function e(e,t){this.batchDataUint8=e,this.stringReader=t}return e.prototype.frameType=function(e){return f(this.batchDataUint8,e)},e.prototype.subtreeLength=function(e){return f(this.batchDataUint8,e+4)},e.prototype.elementReferenceCaptureId=function(e){var t=f(this.batchDataUint8,e+4);return this.stringReader.readString(t)},e.prototype.componentId=function(e){return f(this.batchDataUint8,e+8)},e.prototype.elementName=function(e){var t=f(this.batchDataUint8,e+8);return this.stringReader.readString(t)},e.prototype.textContent=function(e){var t=f(this.batchDataUint8,e+4);return this.stringReader.readString(t)},e.prototype.markupContent=function(e){var t=f(this.batchDataUint8,e+4);return this.stringReader.readString(t)},e.prototype.attributeName=function(e){var t=f(this.batchDataUint8,e+4);return this.stringReader.readString(t)},e.prototype.attributeValue=function(e){var t=f(this.batchDataUint8,e+8);return this.stringReader.readString(t)},e.prototype.attributeEventHandlerId=function(e){return f(this.batchDataUint8,e+12)},e}(),u=function(){function e(e){this.batchDataUint8=e,this.stringTableStartIndex=f(e,e.length-4)}return e.prototype.readString=function(e){if(-1===e)return null;var t,n=f(this.batchDataUint8,this.stringTableStartIndex+4*e),o=function(e,t){for(var n=0,r=0,o=0;o<4;o++){var i=e[t+o];if(n|=(127&i)<65535&&(c-=65536,r.push(c>>>10&1023|55296),c=56320|1023&c),r.push(c)}r.length>1024&&(o.push(String.fromCharCode.apply(null,r)),r.length=0)}return o.push(String.fromCharCode.apply(null,r)),o.join("")}},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var r=n(19),o=function(){function e(){}return e.prototype.log=function(e,t){},e.instance=new e,e}();t.NullLogger=o;var i=function(){function e(e){this.minimumLogLevel=e}return e.prototype.log=function(e,t){if(e>=this.minimumLogLevel)switch(e){case r.LogLevel.Critical:case r.LogLevel.Error:console.error("["+(new Date).toISOString()+"] "+r.LogLevel[e]+": "+t);break;case r.LogLevel.Warning:console.warn("["+(new Date).toISOString()+"] "+r.LogLevel[e]+": "+t);break;case r.LogLevel.Information:console.info("["+(new Date).toISOString()+"] "+r.LogLevel[e]+": "+t);break;default:console.log("["+(new Date).toISOString()+"] "+r.LogLevel[e]+": "+t)}},e}();t.ConsoleLogger=i},function(e,t,n){"use strict";var r=this&&this.__awaiter||function(e,t,n,r){return new(n||(n=Promise))(function(o,i){function a(e){try{u(r.next(e))}catch(e){i(e)}}function s(e){try{u(r.throw(e))}catch(e){i(e)}}function u(e){e.done?o(e.value):new n(function(t){t(e.value)}).then(a,s)}u((r=r.apply(e,t||[])).next())})},o=this&&this.__generator||function(e,t){var n,r,o,i,a={label:0,sent:function(){if(1&o[0])throw o[1];return o[1]},trys:[],ops:[]};return i={next:s(0),throw:s(1),return:s(2)},"function"==typeof Symbol&&(i[Symbol.iterator]=function(){return this}),i;function s(i){return function(s){return function(i){if(n)throw new TypeError("Generator is already executing.");for(;a;)try{if(n=1,r&&(o=2&i[0]?r.return:i[0]?r.throw||((o=r.return)&&o.call(r),0):r.next)&&!(o=o.call(r,i[1])).done)return o;switch(r=0,o&&(i=[2&i[0],o.value]),i[0]){case 0:case 1:o=i;break;case 4:return a.label++,{value:i[1],done:!1};case 5:a.label++,r=i[1],i=[0];continue;case 7:i=a.ops.pop(),a.trys.pop();continue;default:if(!(o=(o=a.trys).length>0&&o[o.length-1])&&(6===i[0]||2===i[0])){a=0;continue}if(3===i[0]&&(!o||i[1]>o[0]&&i[1]=e.length&&(e=void 0),{value:e&&e[n++],done:!e}}}},a=this&&this.__read||function(e,t){var n="function"==typeof Symbol&&e[Symbol.iterator];if(!n)return e;var r,o,i=n.call(e),a=[];try{for(;(void 0===t||t-- >0)&&!(r=i.next()).done;)a.push(r.value)}catch(e){o={error:e}}finally{try{r&&!r.done&&(n=i.return)&&n.call(i)}finally{if(o)throw o.error}}return a};Object.defineProperty(t,"__esModule",{value:!0});var s=n(16),u=n(68),c=function(){function e(e,t){this.circuitId=e,this.components=t}return e.prototype.reconnect=function(e){return e.invoke("ConnectCircuit",this.circuitId)},e}();function l(e){if(e.nodeType===Node.COMMENT_NODE&&e.textContent){var t=/\W+M.A.C.Component:[^{]*(.*)$/.exec(e.textContent),n=t&&t[1];if(n)try{var r=JSON.parse(n),o=r.componentId,i=r.circuitId,a=r.rendererId;if(!!o&&!!i&&!!a)return{node:e,circuitId:i,rendererId:Number.parseInt(a),componentId:Number.parseInt(o)};throw new Error("Found malformed start component comment at "+e.textContent)}catch(t){throw new Error("Found malformed start component comment at "+e.textContent)}}}function f(e,t,n,r){for(var o=n;o>=7)>0&&(r|=128),n.push(r)}while(t>0);t=e.byteLength||e.length;var o=new Uint8Array(n.length+t);return o.set(n,0),o.set(e,n.length),o.buffer},e.parse=function(e){for(var t=[],n=new Uint8Array(e),r=[0,7,14,21,28],o=0;o7)throw new Error("Messages bigger than 2GB are not supported.");if(!(n.byteLength>=o+i+a))throw new Error("Incomplete message.");t.push(n.slice?n.slice(o+i,o+i+a):n.subarray(o+i,o+i+a)),o=o+i+a}return t},e}();var s=new Uint8Array([145,i.MessageType.Ping]),u=function(){function e(){this.name="messagepack",this.version=1,this.transferFormat=i.TransferFormat.Binary}return e.prototype.parseMessages=function(e,t){if(!(e instanceof r.Buffer||(n=e,n&&"undefined"!=typeof ArrayBuffer&&(n instanceof ArrayBuffer||n.constructor&&"ArrayBuffer"===n.constructor.name))))throw new Error("Invalid input for MessagePack hub protocol. Expected an ArrayBuffer or Buffer.");var n;null===t&&(t=i.NullLogger.instance);for(var o=[],s=0,u=a.parse(e);s=0;c--)if(l[c]!==f[c])return!1;for(c=l.length-1;c>=0;c--)if(u=l[c],!m(e[u],t[u],n,r))return!1;return!0}(e,t,n,a))}return n?e===t:e==t}function b(e){return"[object Arguments]"==Object.prototype.toString.call(e)}function w(e,t){if(!e||!t)return!1;if("[object RegExp]"==Object.prototype.toString.call(t))return t.test(e);try{if(e instanceof t)return!0}catch(e){}return!Error.isPrototypeOf(t)&&!0===t.call({},e)}function E(e,t,n,r){var o;if("function"!=typeof t)throw new TypeError('"block" argument must be a function');"string"==typeof n&&(r=n,n=null),o=function(e){var t;try{e()}catch(e){t=e}return t}(t),r=(n&&n.name?" ("+n.name+").":".")+(r?" "+r:"."),e&&!o&&y(o,n,"Missing expected exception"+r);var a="string"==typeof r,s=!e&&o&&!n;if((!e&&i.isError(o)&&a&&w(o,n)||s)&&y(o,n,"Got unwanted exception"+r),e&&o&&n&&!w(o,n)||!e&&o)throw o}f.AssertionError=function(e){var t;this.name="AssertionError",this.actual=e.actual,this.expected=e.expected,this.operator=e.operator,e.message?(this.message=e.message,this.generatedMessage=!1):(this.message=d(g((t=this).actual),128)+" "+t.operator+" "+d(g(t.expected),128),this.generatedMessage=!0);var n=e.stackStartFunction||y;if(Error.captureStackTrace)Error.captureStackTrace(this,n);else{var r=new Error;if(r.stack){var o=r.stack,i=p(n),a=o.indexOf("\n"+i);if(a>=0){var s=o.indexOf("\n",a+1);o=o.substring(s+1)}this.stack=o}}},i.inherits(f.AssertionError,Error),f.fail=y,f.ok=v,f.equal=function(e,t,n){e!=t&&y(e,t,n,"==",f.equal)},f.notEqual=function(e,t,n){e==t&&y(e,t,n,"!=",f.notEqual)},f.deepEqual=function(e,t,n){m(e,t,!1)||y(e,t,n,"deepEqual",f.deepEqual)},f.deepStrictEqual=function(e,t,n){m(e,t,!0)||y(e,t,n,"deepStrictEqual",f.deepStrictEqual)},f.notDeepEqual=function(e,t,n){m(e,t,!1)&&y(e,t,n,"notDeepEqual",f.notDeepEqual)},f.notDeepStrictEqual=function e(t,n,r){m(t,n,!0)&&y(t,n,r,"notDeepStrictEqual",e)},f.strictEqual=function(e,t,n){e!==t&&y(e,t,n,"===",f.strictEqual)},f.notStrictEqual=function(e,t,n){e===t&&y(e,t,n,"!==",f.notStrictEqual)},f.throws=function(e,t,n){E(!0,e,t,n)},f.doesNotThrow=function(e,t,n){E(!1,e,t,n)},f.ifError=function(e){if(e)throw e};var S=Object.keys||function(e){var t=[];for(var n in e)a.call(e,n)&&t.push(n);return t}}).call(this,n(5))},function(e,t){e.exports=function(e){return e&&"object"==typeof e&&"function"==typeof e.copy&&"function"==typeof e.fill&&"function"==typeof e.readUInt8}},function(e,t){},function(e,t,n){"use strict";var r=n(6).Buffer,o=n(53);e.exports=function(){function e(){!function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,e),this.head=null,this.tail=null,this.length=0}return e.prototype.push=function(e){var t={data:e,next:null};this.length>0?this.tail.next=t:this.head=t,this.tail=t,++this.length},e.prototype.unshift=function(e){var t={data:e,next:this.head};0===this.length&&(this.tail=t),this.head=t,++this.length},e.prototype.shift=function(){if(0!==this.length){var e=this.head.data;return 1===this.length?this.head=this.tail=null:this.head=this.head.next,--this.length,e}},e.prototype.clear=function(){this.head=this.tail=null,this.length=0},e.prototype.join=function(e){if(0===this.length)return"";for(var t=this.head,n=""+t.data;t=t.next;)n+=e+t.data;return n},e.prototype.concat=function(e){if(0===this.length)return r.alloc(0);if(1===this.length)return this.head.data;for(var t,n,o,i=r.allocUnsafe(e>>>0),a=this.head,s=0;a;)t=a.data,n=i,o=s,t.copy(n,o),s+=a.data.length,a=a.next;return i},e}(),o&&o.inspect&&o.inspect.custom&&(e.exports.prototype[o.inspect.custom]=function(){var e=o.inspect({length:this.length});return this.constructor.name+" "+e})},function(e,t){},function(e,t,n){(function(e){var r=void 0!==e&&e||"undefined"!=typeof self&&self||window,o=Function.prototype.apply;function i(e,t){this._id=e,this._clearFn=t}t.setTimeout=function(){return new i(o.call(setTimeout,r,arguments),clearTimeout)},t.setInterval=function(){return new i(o.call(setInterval,r,arguments),clearInterval)},t.clearTimeout=t.clearInterval=function(e){e&&e.close()},i.prototype.unref=i.prototype.ref=function(){},i.prototype.close=function(){this._clearFn.call(r,this._id)},t.enroll=function(e,t){clearTimeout(e._idleTimeoutId),e._idleTimeout=t},t.unenroll=function(e){clearTimeout(e._idleTimeoutId),e._idleTimeout=-1},t._unrefActive=t.active=function(e){clearTimeout(e._idleTimeoutId);var t=e._idleTimeout;t>=0&&(e._idleTimeoutId=setTimeout(function(){e._onTimeout&&e._onTimeout()},t))},n(55),t.setImmediate="undefined"!=typeof self&&self.setImmediate||void 0!==e&&e.setImmediate||this&&this.setImmediate,t.clearImmediate="undefined"!=typeof self&&self.clearImmediate||void 0!==e&&e.clearImmediate||this&&this.clearImmediate}).call(this,n(5))},function(e,t,n){(function(e,t){!function(e,n){"use strict";if(!e.setImmediate){var r,o,i,a,s,u=1,c={},l=!1,f=e.document,h=Object.getPrototypeOf&&Object.getPrototypeOf(e);h=h&&h.setTimeout?h:e,"[object process]"==={}.toString.call(e.process)?r=function(e){t.nextTick(function(){d(e)})}:!function(){if(e.postMessage&&!e.importScripts){var t=!0,n=e.onmessage;return e.onmessage=function(){t=!1},e.postMessage("","*"),e.onmessage=n,t}}()?e.MessageChannel?((i=new MessageChannel).port1.onmessage=function(e){d(e.data)},r=function(e){i.port2.postMessage(e)}):f&&"onreadystatechange"in f.createElement("script")?(o=f.documentElement,r=function(e){var t=f.createElement("script");t.onreadystatechange=function(){d(e),t.onreadystatechange=null,o.removeChild(t),t=null},o.appendChild(t)}):r=function(e){setTimeout(d,0,e)}:(a="setImmediate$"+Math.random()+"$",s=function(t){t.source===e&&"string"==typeof t.data&&0===t.data.indexOf(a)&&d(+t.data.slice(a.length))},e.addEventListener?e.addEventListener("message",s,!1):e.attachEvent("onmessage",s),r=function(t){e.postMessage(a+t,"*")}),h.setImmediate=function(e){"function"!=typeof e&&(e=new Function(""+e));for(var t=new Array(arguments.length-1),n=0;n0?this._transform(null,t,n):n()},e.exports.decoder=u,e.exports.encoder=s},function(e,t,n){"use strict";var r=n(17);function o(e){Error.call(this),Error.captureStackTrace&&Error.captureStackTrace(this,this.constructor),this.name=this.constructor.name,this.message=e||"unable to decode"}n(30).inherits(o,Error),e.exports=function(e){return function(e){e instanceof r||(e=r().append(e));var t=i(e);if(t)return e.consume(t.bytesConsumed),t.value;throw new o};function t(e,t,n){return t>=n+e}function n(e,t){return{value:e,bytesConsumed:t}}function i(e,r){r=void 0===r?0:r;var o=e.length-r;if(o<=0)return null;var i,l,f,h=e.readUInt8(r),p=0;if(!function(e,t){var n=function(e){switch(e){case 196:return 2;case 197:return 3;case 198:return 5;case 199:return 3;case 200:return 4;case 201:return 6;case 202:return 5;case 203:return 9;case 204:return 2;case 205:return 3;case 206:return 5;case 207:return 9;case 208:return 2;case 209:return 3;case 210:return 5;case 211:return 9;case 212:return 3;case 213:return 4;case 214:return 6;case 215:return 10;case 216:return 18;case 217:return 2;case 218:return 3;case 219:return 5;case 222:return 3;default:return-1}}(e);return!(-1!==n&&t=0;f--)p+=e.readUInt8(r+f+1)*Math.pow(2,8*(7-f));return n(p,9);case 208:return n(p=e.readInt8(r+1),2);case 209:return n(p=e.readInt16BE(r+1),3);case 210:return n(p=e.readInt32BE(r+1),5);case 211:return n(p=function(e,t){var n=128==(128&e[t]);if(n)for(var r=1,o=t+7;o>=t;o--){var i=(255^e[o])+r;e[o]=255&i,r=i>>8}var a=e.readUInt32BE(t+0),s=e.readUInt32BE(t+4);return(4294967296*a+s)*(n?-1:1)}(e.slice(r+1,r+9),0),9);case 202:return n(p=e.readFloatBE(r+1),5);case 203:return n(p=e.readDoubleBE(r+1),9);case 217:return t(i=e.readUInt8(r+1),o,2)?n(p=e.toString("utf8",r+2,r+2+i),2+i):null;case 218:return t(i=e.readUInt16BE(r+1),o,3)?n(p=e.toString("utf8",r+3,r+3+i),3+i):null;case 219:return t(i=e.readUInt32BE(r+1),o,5)?n(p=e.toString("utf8",r+5,r+5+i),5+i):null;case 196:return t(i=e.readUInt8(r+1),o,2)?n(p=e.slice(r+2,r+2+i),2+i):null;case 197:return t(i=e.readUInt16BE(r+1),o,3)?n(p=e.slice(r+3,r+3+i),3+i):null;case 198:return t(i=e.readUInt32BE(r+1),o,5)?n(p=e.slice(r+5,r+5+i),5+i):null;case 220:return o<3?null:(i=e.readUInt16BE(r+1),a(e,r,i,3));case 221:return o<5?null:(i=e.readUInt32BE(r+1),a(e,r,i,5));case 222:return i=e.readUInt16BE(r+1),s(e,r,i,3);case 223:return i=e.readUInt32BE(r+1),s(e,r,i,5);case 212:return u(e,r,1);case 213:return u(e,r,2);case 214:return u(e,r,4);case 215:return u(e,r,8);case 216:return u(e,r,16);case 199:return i=e.readUInt8(r+1),l=e.readUInt8(r+2),t(i,o,3)?c(e,r,l,i,3):null;case 200:return i=e.readUInt16BE(r+1),l=e.readUInt8(r+3),t(i,o,4)?c(e,r,l,i,4):null;case 201:return i=e.readUInt32BE(r+1),l=e.readUInt8(r+5),t(i,o,6)?c(e,r,l,i,6):null}if(144==(240&h))return a(e,r,i=15&h,1);if(128==(240&h))return s(e,r,i=15&h,1);if(160==(224&h))return t(i=31&h,o,1)?n(p=e.toString("utf8",r+1,r+i+1),i+1):null;if(h>=224)return n(p=h-256,1);if(h<128)return n(h,1);throw new Error("not implemented yet")}function a(e,t,r,o){var a,s=[],u=0;for(t+=o,a=0;a0&&l.write(u,1)):f<=255&&!n?((l=r.allocUnsafe(2+f))[0]=217,l[1]=f,l.write(u,2)):f<=65535?((l=r.allocUnsafe(3+f))[0]=218,l.writeUInt16BE(f,1),l.write(u,3)):((l=r.allocUnsafe(5+f))[0]=219,l.writeUInt32BE(f,1),l.write(u,5));else if(u&&(u.readUInt32LE||u instanceof Uint8Array))u instanceof Uint8Array&&(u=r.from(u)),u.length<=255?((l=r.allocUnsafe(2))[0]=196,l[1]=u.length):u.length<=65535?((l=r.allocUnsafe(3))[0]=197,l.writeUInt16BE(u.length,1)):((l=r.allocUnsafe(5))[0]=198,l.writeUInt32BE(u.length,1)),l=o([l,u]);else if(Array.isArray(u))u.length<16?(l=r.allocUnsafe(1))[0]=144|u.length:u.length<65536?((l=r.allocUnsafe(3))[0]=220,l.writeUInt16BE(u.length,1)):((l=r.allocUnsafe(5))[0]=221,l.writeUInt32BE(u.length,1)),l=u.reduce(function(e,t){return e.append(s(t,!0)),e},o().append(l));else{if(!a&&"function"==typeof u.getDate)return function(e){var t,n=1*e,i=Math.floor(n/1e3),a=1e6*(n-1e3*i);if(a||i>4294967295){(t=r.allocUnsafe(10))[0]=215,t[1]=-1;var s=4*a,u=i/Math.pow(2,32),c=s+u&4294967295,l=4294967295&i;t.writeInt32BE(c,2),t.writeInt32BE(l,6)}else(t=r.allocUnsafe(6))[0]=214,t[1]=-1,t.writeUInt32BE(Math.floor(n/1e3),2);return o().append(t)}(u);if("object"==typeof u)l=function(t){var n,i,a=-1,s=[];for(n=0;n>8),s.push(255&a)):(s.push(201),s.push(a>>24),s.push(a>>16&255),s.push(a>>8&255),s.push(255&a));return o().append(r.from(s)).append(i)}(u)||function(e){var t,n,i=[],a=0;for(t in e)e.hasOwnProperty(t)&&void 0!==e[t]&&"function"!=typeof e[t]&&(++a,i.push(s(t,!0)),i.push(s(e[t],!0)));a<16?(n=r.allocUnsafe(1))[0]=128|a:a<65535?((n=r.allocUnsafe(3))[0]=222,n.writeUInt16BE(a,1)):((n=r.allocUnsafe(5))[0]=223,n.writeUInt32BE(a,1));return i.unshift(n),i.reduce(function(e,t){return e.append(t)},o())}(u);else if("number"==typeof u){if(function(e){return e%1!=0}(u))return i(u,t);if(u>=0)if(u<128)(l=r.allocUnsafe(1))[0]=u;else if(u<256)(l=r.allocUnsafe(2))[0]=204,l[1]=u;else if(u<65536)(l=r.allocUnsafe(3))[0]=205,l.writeUInt16BE(u,1);else if(u<=4294967295)(l=r.allocUnsafe(5))[0]=206,l.writeUInt32BE(u,1);else{if(!(u<=9007199254740991))return i(u,!0);(l=r.allocUnsafe(9))[0]=207,function(e,t){for(var n=7;n>=0;n--)e[n+1]=255&t,t/=256}(l,u)}else if(u>=-32)(l=r.allocUnsafe(1))[0]=256+u;else if(u>=-128)(l=r.allocUnsafe(2))[0]=208,l.writeInt8(u,1);else if(u>=-32768)(l=r.allocUnsafe(3))[0]=209,l.writeInt16BE(u,1);else if(u>-214748365)(l=r.allocUnsafe(5))[0]=210,l.writeInt32BE(u,1);else{if(!(u>=-9007199254740991))return i(u,!0);(l=r.allocUnsafe(9))[0]=211,function(e,t,n){var r=n<0;r&&(n=Math.abs(n));var o=n%4294967296,i=n/4294967296;if(e.writeUInt32BE(Math.floor(i),t+0),e.writeUInt32BE(o,t+4),r)for(var a=1,s=t+7;s>=t;s--){var u=(255^e[s])+a;e[s]=255&u,a=u>>8}}(l,1,u)}}}if(!l)throw new Error("not implemented yet");return c?l:l.slice()}return s}},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var r=function(){function e(e){this.dialog=e}return e.prototype.show=function(){this.removeClasses(),this.dialog.classList.add(e.ShowClassName)},e.prototype.hide=function(){this.removeClasses(),this.dialog.classList.add(e.HideClassName)},e.prototype.failed=function(){this.removeClasses(),this.dialog.classList.add(e.FailedClassName)},e.prototype.removeClasses=function(){this.dialog.classList.remove(e.ShowClassName,e.HideClassName,e.FailedClassName)},e.ShowClassName="components-reconnect-show",e.HideClassName="components-reconnect-hide",e.FailedClassName="components-reconnect-failed",e}();t.UserSpecifiedDisplay=r},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var r=n(40),o=function(){function e(e){this.document=e,this.addedToDom=!1,this.modal=this.document.createElement("div"),this.modal.id=r.AutoReconnectCircuitHandler.DialogId;this.modal.style.cssText=["position: fixed","top: 0","right: 0","bottom: 0","left: 0","z-index: 1000","display: none","overflow: hidden","background-color: #fff","opacity: 0.8","text-align: center","font-weight: bold"].join(";"),this.modal.innerHTML='
',this.message=this.modal.querySelector("h5"),this.button=this.modal.querySelector("button"),this.button.addEventListener("click",function(){return window.Blazor.reconnect()})}return e.prototype.show=function(){this.addedToDom||(this.addedToDom=!0,this.document.body.appendChild(this.modal)),this.modal.style.display="block",this.button.style.display="none",this.message.textContent="Attempting to reconnect to the server..."},e.prototype.hide=function(){this.modal.style.display="none"},e.prototype.failed=function(){this.button.style.display="block",this.message.textContent="Failed to reconnect to the server."},e}();t.DefaultReconnectDisplay=o},function(e,t,n){"use strict";var r=this&&this.__awaiter||function(e,t,n,r){return new(n||(n=Promise))(function(o,i){function a(e){try{u(r.next(e))}catch(e){i(e)}}function s(e){try{u(r.throw(e))}catch(e){i(e)}}function u(e){e.done?o(e.value):new n(function(t){t(e.value)}).then(a,s)}u((r=r.apply(e,t||[])).next())})},o=this&&this.__generator||function(e,t){var n,r,o,i,a={label:0,sent:function(){if(1&o[0])throw o[1];return o[1]},trys:[],ops:[]};return i={next:s(0),throw:s(1),return:s(2)},"function"==typeof Symbol&&(i[Symbol.iterator]=function(){return this}),i;function s(i){return function(s){return function(i){if(n)throw new TypeError("Generator is already executing.");for(;a;)try{if(n=1,r&&(o=2&i[0]?r.return:i[0]?r.throw||((o=r.return)&&o.call(r),0):r.next)&&!(o=o.call(r,i[1])).done)return o;switch(r=0,o&&(i=[2&i[0],o.value]),i[0]){case 0:case 1:o=i;break;case 4:return a.label++,{value:i[1],done:!1};case 5:a.label++,r=i[1],i=[0];continue;case 7:i=a.ops.pop(),a.trys.pop();continue;default:if(!(o=(o=a.trys).length>0&&o[o.length-1])&&(6===i[0]||2===i[0])){a=0;continue}if(3===i[0]&&(!o||i[1]>o[0]&&i[1]this.nextBatchId)this.logger.log(s.LogLevel.Debug,"Waiting for batch "+this.nextBatchId+". Batch "+e+" not processed.");else try{this.nextBatchId++,this.logger.log(s.LogLevel.Debug,"Applying batch "+e+"."),i.renderBatch(this.browserRendererId,new a.OutOfProcessRenderBatch(t)),this.completeBatch(n,e)}catch(t){throw this.logger.log(s.LogLevel.Error,"There was an error applying batch "+e+"."),n.send("OnRenderCompleted",e,t.toString()),t}},e.prototype.getLastBatchid=function(){return this.nextBatchId-1},e.prototype.completeBatch=function(e,t){return r(this,void 0,void 0,function(){return o(this,function(n){switch(n.label){case 0:return n.trys.push([0,2,,3]),[4,e.send("OnRenderCompleted",t,null)];case 1:return n.sent(),[3,3];case 2:return n.sent(),this.logger.log(s.LogLevel.Warning,"Failed to deliver completion notification for render '"+t+"'."),[3,3];case 3:return[2]}})})},e.renderQueues=new Map,e}();t.default=u},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var r=n(65),o=function(){function e(e){this.batchData=e;var t=new u(e);this.arrayRangeReader=new c(e),this.arraySegmentReader=new l(e),this.diffReader=new i(e),this.editReader=new a(e,t),this.frameReader=new s(e,t)}return e.prototype.updatedComponents=function(){return f(this.batchData,this.batchData.length-20)},e.prototype.referenceFrames=function(){return f(this.batchData,this.batchData.length-16)},e.prototype.disposedComponentIds=function(){return f(this.batchData,this.batchData.length-12)},e.prototype.disposedEventHandlerIds=function(){return f(this.batchData,this.batchData.length-8)},e.prototype.updatedComponentsEntry=function(e,t){var n=e+4*t;return f(this.batchData,n)},e.prototype.referenceFramesEntry=function(e,t){return e+16*t},e.prototype.disposedComponentIdsEntry=function(e,t){var n=e+4*t;return f(this.batchData,n)},e.prototype.disposedEventHandlerIdsEntry=function(e,t){var n=e+4*t;return f(this.batchData,n)},e}();t.OutOfProcessRenderBatch=o;var i=function(){function e(e){this.batchDataUint8=e}return e.prototype.componentId=function(e){return f(this.batchDataUint8,e)},e.prototype.edits=function(e){return e+4},e.prototype.editsEntry=function(e,t){return e+16*t},e}(),a=function(){function e(e,t){this.batchDataUint8=e,this.stringReader=t}return e.prototype.editType=function(e){return f(this.batchDataUint8,e)},e.prototype.siblingIndex=function(e){return f(this.batchDataUint8,e+4)},e.prototype.newTreeIndex=function(e){return f(this.batchDataUint8,e+8)},e.prototype.moveToSiblingIndex=function(e){return f(this.batchDataUint8,e+8)},e.prototype.removedAttributeName=function(e){var t=f(this.batchDataUint8,e+12);return this.stringReader.readString(t)},e}(),s=function(){function e(e,t){this.batchDataUint8=e,this.stringReader=t}return e.prototype.frameType=function(e){return f(this.batchDataUint8,e)},e.prototype.subtreeLength=function(e){return f(this.batchDataUint8,e+4)},e.prototype.elementReferenceCaptureId=function(e){var t=f(this.batchDataUint8,e+4);return this.stringReader.readString(t)},e.prototype.componentId=function(e){return f(this.batchDataUint8,e+8)},e.prototype.elementName=function(e){var t=f(this.batchDataUint8,e+8);return this.stringReader.readString(t)},e.prototype.textContent=function(e){var t=f(this.batchDataUint8,e+4);return this.stringReader.readString(t)},e.prototype.markupContent=function(e){var t=f(this.batchDataUint8,e+4);return this.stringReader.readString(t)},e.prototype.attributeName=function(e){var t=f(this.batchDataUint8,e+4);return this.stringReader.readString(t)},e.prototype.attributeValue=function(e){var t=f(this.batchDataUint8,e+8);return this.stringReader.readString(t)},e.prototype.attributeEventHandlerId=function(e){return f(this.batchDataUint8,e+12)},e}(),u=function(){function e(e){this.batchDataUint8=e,this.stringTableStartIndex=f(e,e.length-4)}return e.prototype.readString=function(e){if(-1===e)return null;var t,n=f(this.batchDataUint8,this.stringTableStartIndex+4*e),o=function(e,t){for(var n=0,r=0,o=0;o<4;o++){var i=e[t+o];if(n|=(127&i)<65535&&(c-=65536,r.push(c>>>10&1023|55296),c=56320|1023&c),r.push(c)}r.length>1024&&(o.push(String.fromCharCode.apply(null,r)),r.length=0)}return o.push(String.fromCharCode.apply(null,r)),o.join("")}},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var r=n(19),o=function(){function e(){}return e.prototype.log=function(e,t){},e.instance=new e,e}();t.NullLogger=o;var i=function(){function e(e){this.minimumLogLevel=e}return e.prototype.log=function(e,t){if(e>=this.minimumLogLevel)switch(e){case r.LogLevel.Critical:case r.LogLevel.Error:console.error("["+(new Date).toISOString()+"] "+r.LogLevel[e]+": "+t);break;case r.LogLevel.Warning:console.warn("["+(new Date).toISOString()+"] "+r.LogLevel[e]+": "+t);break;case r.LogLevel.Information:console.info("["+(new Date).toISOString()+"] "+r.LogLevel[e]+": "+t);break;default:console.log("["+(new Date).toISOString()+"] "+r.LogLevel[e]+": "+t)}},e}();t.ConsoleLogger=i},function(e,t,n){"use strict";var r=this&&this.__awaiter||function(e,t,n,r){return new(n||(n=Promise))(function(o,i){function a(e){try{u(r.next(e))}catch(e){i(e)}}function s(e){try{u(r.throw(e))}catch(e){i(e)}}function u(e){e.done?o(e.value):new n(function(t){t(e.value)}).then(a,s)}u((r=r.apply(e,t||[])).next())})},o=this&&this.__generator||function(e,t){var n,r,o,i,a={label:0,sent:function(){if(1&o[0])throw o[1];return o[1]},trys:[],ops:[]};return i={next:s(0),throw:s(1),return:s(2)},"function"==typeof Symbol&&(i[Symbol.iterator]=function(){return this}),i;function s(i){return function(s){return function(i){if(n)throw new TypeError("Generator is already executing.");for(;a;)try{if(n=1,r&&(o=2&i[0]?r.return:i[0]?r.throw||((o=r.return)&&o.call(r),0):r.next)&&!(o=o.call(r,i[1])).done)return o;switch(r=0,o&&(i=[2&i[0],o.value]),i[0]){case 0:case 1:o=i;break;case 4:return a.label++,{value:i[1],done:!1};case 5:a.label++,r=i[1],i=[0];continue;case 7:i=a.ops.pop(),a.trys.pop();continue;default:if(!(o=(o=a.trys).length>0&&o[o.length-1])&&(6===i[0]||2===i[0])){a=0;continue}if(3===i[0]&&(!o||i[1]>o[0]&&i[1]=e.length&&(e=void 0),{value:e&&e[n++],done:!e}}}},a=this&&this.__read||function(e,t){var n="function"==typeof Symbol&&e[Symbol.iterator];if(!n)return e;var r,o,i=n.call(e),a=[];try{for(;(void 0===t||t-- >0)&&!(r=i.next()).done;)a.push(r.value)}catch(e){o={error:e}}finally{try{r&&!r.done&&(n=i.return)&&n.call(i)}finally{if(o)throw o.error}}return a};Object.defineProperty(t,"__esModule",{value:!0});var s=n(16),u=n(68),c=function(){function e(e,t){this.circuitId=e,this.components=t}return e.prototype.reconnect=function(e){return e.invoke("ConnectCircuit",this.circuitId)},e}();function l(e){if(e.nodeType===Node.COMMENT_NODE&&e.textContent){var t=/\W+M.A.C.Component:[^{]*(.*)$/.exec(e.textContent),n=t&&t[1];if(n)try{var r=JSON.parse(n),o=r.componentId,i=r.circuitId,a=r.rendererId;if(!!o&&!!i&&!!a)return{node:e,circuitId:i,rendererId:Number.parseInt(a),componentId:Number.parseInt(o)};throw new Error("Found malformed start component comment at "+e.textContent)}catch(t){throw new Error("Found malformed start component comment at "+e.textContent)}}}function f(e,t,n,r){for(var o=n;o>=7)>0&&(r|=128),n.push(r)}while(t>0);t=e.byteLength||e.length;var o=new Uint8Array(n.length+t);return o.set(n,0),o.set(e,n.length),o.buffer},e.parse=function(e){for(var t=[],n=new Uint8Array(e),r=[0,7,14,21,28],o=0;o7)throw new Error("Messages bigger than 2GB are not supported.");if(!(n.byteLength>=o+i+a))throw new Error("Incomplete message.");t.push(n.slice?n.slice(o+i,o+i+a):n.subarray(o+i,o+i+a)),o=o+i+a}return t},e}();var s=new Uint8Array([145,i.MessageType.Ping]),u=function(){function e(){this.name="messagepack",this.version=1,this.transferFormat=i.TransferFormat.Binary}return e.prototype.parseMessages=function(e,t){if(!(e instanceof r.Buffer||(n=e,n&&"undefined"!=typeof ArrayBuffer&&(n instanceof ArrayBuffer||n.constructor&&"ArrayBuffer"===n.constructor.name))))throw new Error("Invalid input for MessagePack hub protocol. Expected an ArrayBuffer or Buffer.");var n;null===t&&(t=i.NullLogger.instance);for(var o=[],s=0,u=a.parse(e);s0&&!t)throw new Error("New logical elements must start empty, or allowExistingContents must be true");return e[r]=[],e}function u(e,t,n){var a=e;if(e instanceof Comment&&(s(a)&&s(a).length>0))throw new Error("Not implemented: inserting non-empty logical container");if(l(a))throw new Error("Not implemented: moving existing logical children");var i=s(t);if(n0;)e(r,0);var a=r;a.parentNode.removeChild(a)},t.getLogicalParent=l,t.getLogicalSiblingEnd=function(e){return e[a]||null},t.getLogicalChild=function(e,t){return s(e)[t]},t.isSvgElement=function(e){return"http://www.w3.org/2000/svg"===function(e){if(e instanceof Element)return e;if(e instanceof Comment)return e.parentNode;throw new Error("Not a valid logical element")}(e).namespaceURI},t.getLogicalChildrenArray=s},,,function(e,t,n){"use strict";var r;!function(e){window.DotNet=e;var t=[],n={},r={},o=1,a=null;function i(e){t.push(e)}function u(e,t){for(var n=[],r=2;r0&&o[o.length-1])&&(6===a[0]||2===a[0])){i=0;continue}if(3===a[0]&&(!o||a[1]>o[0]&&a[1]0&&o[o.length-1])&&(6===a[0]||2===a[0])){i=0;continue}if(3===a[0]&&(!o||a[1]>o[0]&&a[1]0&&o[o.length-1])&&(6===a[0]||2===a[0])){i=0;continue}if(3===a[0]&&(!o||a[1]>o[0]&&a[1]0&&o[o.length-1])&&(6===a[0]||2===a[0])){i=0;continue}if(3===a[0]&&(!o||a[1]>o[0]&&a[1]-1?a.substring(0,u):"",s=u>-1?a.substring(u+1):a,c=t.monoPlatform.findMethod(e,l,s,i);t.monoPlatform.callMethod(c,null,r)},callMethod:function(e,n,r){if(r.length>4)throw new Error("Currently, MonoPlatform supports passing a maximum of 4 arguments from JS to .NET. You tried to pass "+r.length+".");var o=Module.stackSave();try{for(var a=Module.stackAlloc(r.length),u=Module.stackAlloc(4),l=0;l0&&!t)throw new Error("New logical elements must start empty, or allowExistingContents must be true");return e[r]=[],e}function u(e,t,n){var a=e;if(e instanceof Comment&&(s(a)&&s(a).length>0))throw new Error("Not implemented: inserting non-empty logical container");if(l(a))throw new Error("Not implemented: moving existing logical children");var i=s(t);if(n0;)e(r,0);var a=r;a.parentNode.removeChild(a)},t.getLogicalParent=l,t.getLogicalSiblingEnd=function(e){return e[a]||null},t.getLogicalChild=function(e,t){return s(e)[t]},t.isSvgElement=function(e){return"http://www.w3.org/2000/svg"===function(e){if(e instanceof Element)return e;if(e instanceof Comment)return e.parentNode;throw new Error("Not a valid logical element")}(e).namespaceURI},t.getLogicalChildrenArray=s,t.permuteLogicalChildren=function(e,t){var n=s(e);t.forEach(function(e){e.moveRangeStart=n[e.fromSiblingIndex],e.moveRangeEnd=function e(t){if(t instanceof Element)return t;var n=c(t);if(n)return n.previousSibling;var r=l(t);return r instanceof Element?r.lastChild:e(r)}(e.moveRangeStart)}),t.forEach(function(t){var r=t.moveToBeforeMarker=document.createComment("marker"),o=n[t.toSiblingIndex+1];o?o.parentNode.insertBefore(r,o):f(r,e)}),t.forEach(function(e){for(var t=e.moveToBeforeMarker,n=t.parentNode,r=e.moveRangeStart,o=e.moveRangeEnd,a=r;a;){var i=a.nextSibling;if(n.insertBefore(a,t),a===o)break;a=i}n.removeChild(t)}),t.forEach(function(e){n[e.toSiblingIndex]=e.moveRangeStart})}},,,function(e,t,n){"use strict";var r;!function(e){window.DotNet=e;var t=[],n={},r={},o=1,a=null;function i(e){t.push(e)}function u(e,t){for(var n=[],r=2;r0&&o[o.length-1])&&(6===a[0]||2===a[0])){i=0;continue}if(3===a[0]&&(!o||a[1]>o[0]&&a[1]0&&o[o.length-1])&&(6===a[0]||2===a[0])){i=0;continue}if(3===a[0]&&(!o||a[1]>o[0]&&a[1]0&&o[o.length-1])&&(6===a[0]||2===a[0])){i=0;continue}if(3===a[0]&&(!o||a[1]>o[0]&&a[1]0&&o[o.length-1])&&(6===a[0]||2===a[0])){i=0;continue}if(3===a[0]&&(!o||a[1]>o[0]&&a[1]-1?a.substring(0,u):"",s=u>-1?a.substring(u+1):a,c=t.monoPlatform.findMethod(e,l,s,i);t.monoPlatform.callMethod(c,null,r)},callMethod:function(e,n,r){if(r.length>4)throw new Error("Currently, MonoPlatform supports passing a maximum of 4 arguments from JS to .NET. You tried to pass "+r.length+".");var o=Module.stackSave();try{for(var a=Module.stackAlloc(r.length),u=Module.stackAlloc(4),l=0;l, referenceFrames: ArrayValues) { let currentDepth = 0; let childIndexAtCurrentDepth = childIndex; + let permutationList: PermutationListEntry[] | undefined; const arraySegmentReader = batch.arraySegmentReader; const editReader = batch.editReader; @@ -152,6 +153,19 @@ export class BrowserRenderer { childIndexAtCurrentDepth = currentDepth === 0 ? childIndex : 0; // The childIndex is only ever nonzero at zero depth break; } + case EditType.permutationListEntry: { + permutationList = permutationList || []; + permutationList.push({ + fromSiblingIndex: childIndexAtCurrentDepth + editReader.siblingIndex(edit), + toSiblingIndex: childIndexAtCurrentDepth + editReader.moveToSiblingIndex(edit), + }); + break; + } + case EditType.permutationListEnd: { + permuteLogicalChildren(parent, permutationList!); + permutationList = undefined; + break; + } default: { const unknownType: never = editType; // Compile-time verification that the switch was exhaustive throw new Error(`Unknown edit type: ${unknownType}`); diff --git a/src/Components/Browser.JS/src/Rendering/LogicalElements.ts b/src/Components/Browser.JS/src/Rendering/LogicalElements.ts index f52e170fa424..f6591cceab2a 100644 --- a/src/Components/Browser.JS/src/Rendering/LogicalElements.ts +++ b/src/Components/Browser.JS/src/Rendering/LogicalElements.ts @@ -155,6 +155,71 @@ export function getLogicalChildrenArray(element: LogicalElement) { return element[logicalChildrenPropname] as LogicalElement[]; } +export function permuteLogicalChildren(parent: LogicalElement, permutationList: PermutationListEntry[]) { + // The permutationList must represent a valid permutation, i.e., the list of 'from' indices + // is distinct, and the list of 'to' indices is a permutation of it. The algorithm here + // relies on that assumption. + + // Each of the phases here has to happen separately, because each one is designed not to + // interfere with the indices or DOM entries used by subsequent phases. + + // Phase 1: track which nodes we will move + const siblings = getLogicalChildrenArray(parent); + permutationList.forEach((listEntry: PermutationListEntryWithTrackingData) => { + listEntry.moveRangeStart = siblings[listEntry.fromSiblingIndex]; + listEntry.moveRangeEnd = findLastDomNodeInRange(listEntry.moveRangeStart); + }); + + // Phase 2: insert markers + permutationList.forEach((listEntry: PermutationListEntryWithTrackingData) => { + const marker = listEntry.moveToBeforeMarker = document.createComment('marker'); + const insertBeforeNode = siblings[listEntry.toSiblingIndex + 1] as any as Node; + if (insertBeforeNode) { + insertBeforeNode.parentNode!.insertBefore(marker, insertBeforeNode); + } else { + appendDomNode(marker, parent); + } + }); + + // Phase 3: move descendants & remove markers + permutationList.forEach((listEntry: PermutationListEntryWithTrackingData) => { + const insertBefore = listEntry.moveToBeforeMarker!; + const parentDomNode = insertBefore.parentNode!; + const elementToMove = listEntry.moveRangeStart!; + const moveEndNode = listEntry.moveRangeEnd!; + let nextToMove = elementToMove as any as Node | null; + while (nextToMove) { + const nextNext = nextToMove.nextSibling; + parentDomNode.insertBefore(nextToMove, insertBefore); + + if (nextToMove === moveEndNode) { + break; + } else { + nextToMove = nextNext; + } + } + + parentDomNode.removeChild(insertBefore); + }); + + // Phase 4: update siblings index + permutationList.forEach((listEntry: PermutationListEntryWithTrackingData) => { + siblings[listEntry.toSiblingIndex] = listEntry.moveRangeStart!; + }); +} + +export interface PermutationListEntry { + fromSiblingIndex: number, + toSiblingIndex: number, +} + +interface PermutationListEntryWithTrackingData extends PermutationListEntry { + // These extra properties are used internally when processing the permutation list + moveRangeStart?: LogicalElement, + moveRangeEnd?: Node, + moveToBeforeMarker?: Node, +} + function getLogicalNextSibling(element: LogicalElement): LogicalElement | null { const siblings = getLogicalChildrenArray(getLogicalParent(element)!); const siblingIndex = Array.prototype.indexOf.call(siblings, element); @@ -192,6 +257,27 @@ function appendDomNode(child: Node, parent: LogicalElement) { } } +// Returns the final node (in depth-first evaluation order) that is a descendant of the logical element. +// As such, the entire subtree is between 'element' and 'findLastDomNodeInRange(element)' inclusive. +function findLastDomNodeInRange(element: LogicalElement) { + if (element instanceof Element) { + return element; + } + + const nextSibling = getLogicalNextSibling(element); + if (nextSibling) { + // Simple case: not the last logical sibling, so take the node before the next sibling + return (nextSibling as any as Node).previousSibling; + } else { + // Harder case: there's no logical next-sibling, so recurse upwards until we find + // a logical ancestor that does have one, or a physical element + const logicalParent = getLogicalParent(element)!; + return logicalParent instanceof Element + ? logicalParent.lastChild + : findLastDomNodeInRange(logicalParent); + } +} + function createSymbolOrFallback(fallback: string): symbol | string { return typeof Symbol === 'function' ? Symbol() : fallback; } diff --git a/src/Components/Browser.JS/src/Rendering/RenderBatch/OutOfProcessRenderBatch.ts b/src/Components/Browser.JS/src/Rendering/RenderBatch/OutOfProcessRenderBatch.ts index dde028624f4d..b33025e55d6f 100644 --- a/src/Components/Browser.JS/src/Rendering/RenderBatch/OutOfProcessRenderBatch.ts +++ b/src/Components/Browser.JS/src/Rendering/RenderBatch/OutOfProcessRenderBatch.ts @@ -100,6 +100,10 @@ class OutOfProcessRenderTreeEditReader implements RenderTreeEditReader { return readInt32LE(this.batchDataUint8, edit as any + 8); // 3rd int } + moveToSiblingIndex(edit: RenderTreeEdit) { + return readInt32LE(this.batchDataUint8, edit as any + 8); // 3rd int + } + removedAttributeName(edit: RenderTreeEdit) { const stringIndex = readInt32LE(this.batchDataUint8, edit as any + 12); // 4th int return this.stringReader.readString(stringIndex); diff --git a/src/Components/Browser.JS/src/Rendering/RenderBatch/RenderBatch.ts b/src/Components/Browser.JS/src/Rendering/RenderBatch/RenderBatch.ts index 3faddab664e0..88a162a447c2 100644 --- a/src/Components/Browser.JS/src/Rendering/RenderBatch/RenderBatch.ts +++ b/src/Components/Browser.JS/src/Rendering/RenderBatch/RenderBatch.ts @@ -37,6 +37,7 @@ export interface RenderTreeEditReader { editType(edit: RenderTreeEdit): EditType; siblingIndex(edit: RenderTreeEdit): number; newTreeIndex(edit: RenderTreeEdit): number; + moveToSiblingIndex(edit: RenderTreeEdit): number; removedAttributeName(edit: RenderTreeEdit): string | null; } @@ -71,6 +72,8 @@ export enum EditType { stepIn = 6, stepOut = 7, updateMarkup = 8, + permutationListEntry = 9, + permutationListEnd = 10, } export enum FrameType { diff --git a/src/Components/Browser.JS/src/Rendering/RenderBatch/SharedMemoryRenderBatch.ts b/src/Components/Browser.JS/src/Rendering/RenderBatch/SharedMemoryRenderBatch.ts index 5d9399ea93b5..ac37d9162e71 100644 --- a/src/Components/Browser.JS/src/Rendering/RenderBatch/SharedMemoryRenderBatch.ts +++ b/src/Components/Browser.JS/src/Rendering/RenderBatch/SharedMemoryRenderBatch.ts @@ -87,7 +87,8 @@ const editReader = { editType: (edit: RenderTreeEdit) => platform.readInt32Field(edit as any, 0) as EditType, siblingIndex: (edit: RenderTreeEdit) => platform.readInt32Field(edit as any, 4), newTreeIndex: (edit: RenderTreeEdit) => platform.readInt32Field(edit as any, 8), - removedAttributeName: (edit: RenderTreeEdit) => platform.readStringField(edit as any, 12), + moveToSiblingIndex: (edit: RenderTreeEdit) => platform.readInt32Field(edit as any, 8), + removedAttributeName: (edit: RenderTreeEdit) => platform.readStringField(edit as any, 16), }; // Keep in sync with memory layout in RenderTreeFrame.cs diff --git a/src/Components/Components/src/RenderTree/RenderTreeEdit.cs b/src/Components/Components/src/RenderTree/RenderTreeEdit.cs index 68222f4f517a..a055b263b250 100644 --- a/src/Components/Components/src/RenderTree/RenderTreeEdit.cs +++ b/src/Components/Components/src/RenderTree/RenderTreeEdit.cs @@ -33,6 +33,9 @@ public readonly struct RenderTreeEdit /// If the value is , /// gets the sibling index to which the frame should be moved. /// + // NOTE: Other code relies on the assumption that ReferenceFrameIndex and + // MoveToSiblingIndex share a memory slot. If you change this, be sure to + // update affected usages of ReferenceFrameIndex. [FieldOffset(8)] public readonly int MoveToSiblingIndex; /// diff --git a/src/Components/Server/src/Circuits/RenderBatchWriter.cs b/src/Components/Server/src/Circuits/RenderBatchWriter.cs index 321bef10845f..d66c5de2a5dc 100644 --- a/src/Components/Server/src/Circuits/RenderBatchWriter.cs +++ b/src/Components/Server/src/Circuits/RenderBatchWriter.cs @@ -105,7 +105,11 @@ void Write(in RenderTreeEdit edit) // for this specific RenderTreeEditType. _binaryWriter.Write((int)edit.Type); _binaryWriter.Write(edit.SiblingIndex); + + // ReferenceFrameIndex and MoveToSiblingIndex share a slot, so this writes + // whichever one applies to the edit type _binaryWriter.Write(edit.ReferenceFrameIndex); + WriteString(edit.RemovedAttributeName, allowDeduplication: true); } From f53c7ce90188f6176bb8ad9feb8e76e4570edeff Mon Sep 17 00:00:00 2001 From: Steve Sanderson Date: Tue, 30 Apr 2019 13:26:37 +0100 Subject: [PATCH 08/33] Include sourcemaps when building client-side Blazor apps with ReferenceFromSource --- src/Components/Blazor/Build/src/ReferenceFromSource.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Components/Blazor/Build/src/ReferenceFromSource.props b/src/Components/Blazor/Build/src/ReferenceFromSource.props index 209519e93213..c98b209ff8ca 100644 --- a/src/Components/Blazor/Build/src/ReferenceFromSource.props +++ b/src/Components/Blazor/Build/src/ReferenceFromSource.props @@ -11,7 +11,7 @@ true - $(RepositoryRoot)src\Components\Browser.JS\dist\$(Configuration)\blazor.*.js + $(RepositoryRoot)src\Components\Browser.JS\dist\$(Configuration)\blazor.*.js.* From 9791ab41becfa6a311af979039e8fba9b158a6a5 Mon Sep 17 00:00:00 2001 From: Steve Sanderson Date: Tue, 30 Apr 2019 13:32:38 +0100 Subject: [PATCH 09/33] Update struct length of edit frames now it's explicit layout It's longer now because all the reference-type fields, except the last, now have to be 8 bytes for compatibility with 64-bit runtimes. Previously on Mono WebAssembly the reference-type fields were all 4 bytes. --- src/Components/Browser.JS/dist/Debug/blazor.webassembly.js | 2 +- src/Components/Browser.JS/dist/Release/blazor.webassembly.js | 2 +- .../src/Rendering/RenderBatch/SharedMemoryRenderBatch.ts | 2 +- src/Components/Components/src/RenderTree/RenderTreeEdit.cs | 1 - 4 files changed, 3 insertions(+), 4 deletions(-) diff --git a/src/Components/Browser.JS/dist/Debug/blazor.webassembly.js b/src/Components/Browser.JS/dist/Debug/blazor.webassembly.js index 956f93d6e0d6..0f8c9698c61c 100644 --- a/src/Components/Browser.JS/dist/Debug/blazor.webassembly.js +++ b/src/Components/Browser.JS/dist/Debug/blazor.webassembly.js @@ -2173,7 +2173,7 @@ var diffReader = { }; // Keep in sync with memory layout in RenderTreeEdit.cs var editReader = { - structLength: 16, + structLength: 20, editType: function (edit) { return Environment_1.platform.readInt32Field(edit, 0); }, siblingIndex: function (edit) { return Environment_1.platform.readInt32Field(edit, 4); }, newTreeIndex: function (edit) { return Environment_1.platform.readInt32Field(edit, 8); }, diff --git a/src/Components/Browser.JS/dist/Release/blazor.webassembly.js b/src/Components/Browser.JS/dist/Release/blazor.webassembly.js index 11ba93342e5b..d3a550249392 100644 --- a/src/Components/Browser.JS/dist/Release/blazor.webassembly.js +++ b/src/Components/Browser.JS/dist/Release/blazor.webassembly.js @@ -1 +1 @@ -!function(e){var t={};function n(r){if(t[r])return t[r].exports;var o=t[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)n.d(r,o,function(t){return e[t]}.bind(null,o));return r},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=42)}([,,,,,,,,function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var r=n(23),o=n(9),a={};function i(e,t,n){var o=a[e];o||(o=a[e]=new r.BrowserRenderer(e)),o.attachRootComponentToLogicalElement(n,t)}t.attachRootComponentToLogicalElement=i,t.attachRootComponentToElement=function(e,t,n){var r=document.querySelector(t);if(!r)throw new Error("Could not find any element matching selector '"+t+"'.");i(e,o.toLogicalElement(r,!0),n)},t.renderBatch=function(e,t){var n=a[e];if(!n)throw new Error("There is no browser renderer with ID "+e+".");for(var r=t.arrayRangeReader,o=t.updatedComponents(),i=r.values(o),u=r.count(o),l=t.referenceFrames(),s=r.values(l),c=t.diffReader,f=0;f0&&!t)throw new Error("New logical elements must start empty, or allowExistingContents must be true");return e[r]=[],e}function u(e,t,n){var a=e;if(e instanceof Comment&&(s(a)&&s(a).length>0))throw new Error("Not implemented: inserting non-empty logical container");if(l(a))throw new Error("Not implemented: moving existing logical children");var i=s(t);if(n0;)e(r,0);var a=r;a.parentNode.removeChild(a)},t.getLogicalParent=l,t.getLogicalSiblingEnd=function(e){return e[a]||null},t.getLogicalChild=function(e,t){return s(e)[t]},t.isSvgElement=function(e){return"http://www.w3.org/2000/svg"===function(e){if(e instanceof Element)return e;if(e instanceof Comment)return e.parentNode;throw new Error("Not a valid logical element")}(e).namespaceURI},t.getLogicalChildrenArray=s,t.permuteLogicalChildren=function(e,t){var n=s(e);t.forEach(function(e){e.moveRangeStart=n[e.fromSiblingIndex],e.moveRangeEnd=function e(t){if(t instanceof Element)return t;var n=c(t);if(n)return n.previousSibling;var r=l(t);return r instanceof Element?r.lastChild:e(r)}(e.moveRangeStart)}),t.forEach(function(t){var r=t.moveToBeforeMarker=document.createComment("marker"),o=n[t.toSiblingIndex+1];o?o.parentNode.insertBefore(r,o):f(r,e)}),t.forEach(function(e){for(var t=e.moveToBeforeMarker,n=t.parentNode,r=e.moveRangeStart,o=e.moveRangeEnd,a=r;a;){var i=a.nextSibling;if(n.insertBefore(a,t),a===o)break;a=i}n.removeChild(t)}),t.forEach(function(e){n[e.toSiblingIndex]=e.moveRangeStart})}},,,function(e,t,n){"use strict";var r;!function(e){window.DotNet=e;var t=[],n={},r={},o=1,a=null;function i(e){t.push(e)}function u(e,t){for(var n=[],r=2;r0&&o[o.length-1])&&(6===a[0]||2===a[0])){i=0;continue}if(3===a[0]&&(!o||a[1]>o[0]&&a[1]0&&o[o.length-1])&&(6===a[0]||2===a[0])){i=0;continue}if(3===a[0]&&(!o||a[1]>o[0]&&a[1]0&&o[o.length-1])&&(6===a[0]||2===a[0])){i=0;continue}if(3===a[0]&&(!o||a[1]>o[0]&&a[1]0&&o[o.length-1])&&(6===a[0]||2===a[0])){i=0;continue}if(3===a[0]&&(!o||a[1]>o[0]&&a[1]-1?a.substring(0,u):"",s=u>-1?a.substring(u+1):a,c=t.monoPlatform.findMethod(e,l,s,i);t.monoPlatform.callMethod(c,null,r)},callMethod:function(e,n,r){if(r.length>4)throw new Error("Currently, MonoPlatform supports passing a maximum of 4 arguments from JS to .NET. You tried to pass "+r.length+".");var o=Module.stackSave();try{for(var a=Module.stackAlloc(r.length),u=Module.stackAlloc(4),l=0;l0&&!t)throw new Error("New logical elements must start empty, or allowExistingContents must be true");return e[r]=[],e}function u(e,t,n){var a=e;if(e instanceof Comment&&(s(a)&&s(a).length>0))throw new Error("Not implemented: inserting non-empty logical container");if(l(a))throw new Error("Not implemented: moving existing logical children");var i=s(t);if(n0;)e(r,0);var a=r;a.parentNode.removeChild(a)},t.getLogicalParent=l,t.getLogicalSiblingEnd=function(e){return e[a]||null},t.getLogicalChild=function(e,t){return s(e)[t]},t.isSvgElement=function(e){return"http://www.w3.org/2000/svg"===function(e){if(e instanceof Element)return e;if(e instanceof Comment)return e.parentNode;throw new Error("Not a valid logical element")}(e).namespaceURI},t.getLogicalChildrenArray=s,t.permuteLogicalChildren=function(e,t){var n=s(e);t.forEach(function(e){e.moveRangeStart=n[e.fromSiblingIndex],e.moveRangeEnd=function e(t){if(t instanceof Element)return t;var n=c(t);if(n)return n.previousSibling;var r=l(t);return r instanceof Element?r.lastChild:e(r)}(e.moveRangeStart)}),t.forEach(function(t){var r=t.moveToBeforeMarker=document.createComment("marker"),o=n[t.toSiblingIndex+1];o?o.parentNode.insertBefore(r,o):f(r,e)}),t.forEach(function(e){for(var t=e.moveToBeforeMarker,n=t.parentNode,r=e.moveRangeStart,o=e.moveRangeEnd,a=r;a;){var i=a.nextSibling;if(n.insertBefore(a,t),a===o)break;a=i}n.removeChild(t)}),t.forEach(function(e){n[e.toSiblingIndex]=e.moveRangeStart})}},,,function(e,t,n){"use strict";var r;!function(e){window.DotNet=e;var t=[],n={},r={},o=1,a=null;function i(e){t.push(e)}function u(e,t){for(var n=[],r=2;r0&&o[o.length-1])&&(6===a[0]||2===a[0])){i=0;continue}if(3===a[0]&&(!o||a[1]>o[0]&&a[1]0&&o[o.length-1])&&(6===a[0]||2===a[0])){i=0;continue}if(3===a[0]&&(!o||a[1]>o[0]&&a[1]0&&o[o.length-1])&&(6===a[0]||2===a[0])){i=0;continue}if(3===a[0]&&(!o||a[1]>o[0]&&a[1]0&&o[o.length-1])&&(6===a[0]||2===a[0])){i=0;continue}if(3===a[0]&&(!o||a[1]>o[0]&&a[1]-1?a.substring(0,u):"",s=u>-1?a.substring(u+1):a,c=t.monoPlatform.findMethod(e,l,s,i);t.monoPlatform.callMethod(c,null,r)},callMethod:function(e,n,r){if(r.length>4)throw new Error("Currently, MonoPlatform supports passing a maximum of 4 arguments from JS to .NET. You tried to pass "+r.length+".");var o=Module.stackSave();try{for(var a=Module.stackAlloc(r.length),u=Module.stackAlloc(4),l=0;l platform.readInt32Field(edit as any, 0) as EditType, siblingIndex: (edit: RenderTreeEdit) => platform.readInt32Field(edit as any, 4), newTreeIndex: (edit: RenderTreeEdit) => platform.readInt32Field(edit as any, 8), diff --git a/src/Components/Components/src/RenderTree/RenderTreeEdit.cs b/src/Components/Components/src/RenderTree/RenderTreeEdit.cs index a055b263b250..96f661924bbb 100644 --- a/src/Components/Components/src/RenderTree/RenderTreeEdit.cs +++ b/src/Components/Components/src/RenderTree/RenderTreeEdit.cs @@ -1,7 +1,6 @@ // Copyright (c) .NET Foundation. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. -using System; using System.Runtime.InteropServices; namespace Microsoft.AspNetCore.Components.RenderTree From 426c5b4bbc6067e0df68843251dd3e040524f983 Mon Sep 17 00:00:00 2001 From: Steve Sanderson Date: Tue, 30 Apr 2019 20:24:23 +0100 Subject: [PATCH 10/33] Tolerate clashing keys (i.e., produce a valid diff, even if suboptimal) --- .../src/RenderTree/RenderTreeDiffBuilder.cs | 10 +- .../Components/src/Rendering/KeyedItemInfo.cs | 13 ++- .../test/RenderTreeDiffBuilderTest.cs | 91 ++++++++++++++++++- 3 files changed, 107 insertions(+), 7 deletions(-) diff --git a/src/Components/Components/src/RenderTree/RenderTreeDiffBuilder.cs b/src/Components/Components/src/RenderTree/RenderTreeDiffBuilder.cs index fb557e8743cd..f6e47adb4c58 100644 --- a/src/Components/Components/src/RenderTree/RenderTreeDiffBuilder.cs +++ b/src/Components/Components/src/RenderTree/RenderTreeDiffBuilder.cs @@ -83,8 +83,8 @@ private static void AppendDiffEntriesForRange( var oldKeyItemInfo = keyedItemInfos[oldKey]; var newKeyItemInfo = keyedItemInfos[newKey]; - var oldKeyIsInNewTree = oldKey != null && oldKeyItemInfo.NewIndex >= 0; - var newKeyIsInOldTree = newKey != null && newKeyItemInfo.OldIndex >= 0; + var oldKeyIsInNewTree = oldKey != null && oldKeyItemInfo.NewIndex >= 0 && oldKeyItemInfo.IsUnique; + var newKeyIsInOldTree = newKey != null && newKeyItemInfo.OldIndex >= 0 && newKeyItemInfo.IsUnique; if (oldKeyIsInNewTree && newKeyIsInOldTree) { // It's a move @@ -253,7 +253,7 @@ private static Dictionary BuildKeyToInfoLookup(DiffContex var key = KeyValue(ref frame); if (key != null) { - result[key] = new KeyedItemInfo(oldStartIndex, -1); + result[key] = new KeyedItemInfo(oldStartIndex, -1, isUnique: !result.ContainsKey(key)); } oldStartIndex = NextSiblingIndex(frame, oldStartIndex); @@ -266,8 +266,8 @@ private static Dictionary BuildKeyToInfoLookup(DiffContex if (key != null) { result[key] = result.TryGetValue(key, out var existingEntry) - ? new KeyedItemInfo(existingEntry.OldIndex, newStartIndex) - : new KeyedItemInfo(-1, newStartIndex); + ? new KeyedItemInfo(existingEntry.OldIndex, newStartIndex, isUnique: existingEntry.NewIndex < 0) + : new KeyedItemInfo(-1, newStartIndex, isUnique: true); } newStartIndex = NextSiblingIndex(frame, newStartIndex); diff --git a/src/Components/Components/src/Rendering/KeyedItemInfo.cs b/src/Components/Components/src/Rendering/KeyedItemInfo.cs index 7bd048d66920..5d8d53ce65b9 100644 --- a/src/Components/Components/src/Rendering/KeyedItemInfo.cs +++ b/src/Components/Components/src/Rendering/KeyedItemInfo.cs @@ -11,13 +11,24 @@ internal struct KeyedItemInfo public int NewIndex; public int OldSiblingIndex; public int NewSiblingIndex; + public bool IsUnique; - public KeyedItemInfo(int oldIndex, int newIndex) + public KeyedItemInfo(int oldIndex, int newIndex, bool isUnique) { OldIndex = oldIndex; NewIndex = newIndex; OldSiblingIndex = -1; NewSiblingIndex = -1; + + // Non-unique keys are problematic, because there's no way to know which instance + // should match with which other, plus they would force us to keep track of which + // usages have been consumed as we proceed through the diff. Since this is such + // an edge case, we "tolerate" it just by tracking which keys have duplicates, and + // for those ones, we never treat them as moved. Instead for those we fall back on + // insert+delete behavior, i.e., not preserving elements/components. + // + // Guidance for developers is therefore to use distinct keys. + IsUnique = isUnique; } } } diff --git a/src/Components/Components/test/RenderTreeDiffBuilderTest.cs b/src/Components/Components/test/RenderTreeDiffBuilderTest.cs index bfcf31a68d88..5540e33ae90a 100644 --- a/src/Components/Components/test/RenderTreeDiffBuilderTest.cs +++ b/src/Components/Components/test/RenderTreeDiffBuilderTest.cs @@ -313,6 +313,89 @@ public void RecognizesSimultaneousKeyedComponentInsertionsAndDeletions() entry => AssertEdit(entry, RenderTreeEditType.RemoveFrame, 1)); } + [Fact] + public void HandlesClashingKeys_FirstUsage() + { + // This scenario is problematic for the algorithm if it uses a "first key + // usage wins" policy for duplicate keys. It would not end up with attrib1b + // anywhere in the output, because whenever it sees key1 in oldTree, it tries + // to diff against the first usage of key1 in newTree, which has attrib1a. + + // However, because of the actual "duplicated keys are excluded from the + // dictionary match" policy, we don't preserve any of the key1 items, and + // the diff is valid. + + // Arrange + AddWithKey(oldTree, "key3", "attrib3"); + AddWithKey(oldTree, "key1", "attrib1a"); + AddWithKey(oldTree, "key1", "attrib1a"); + AddWithKey(oldTree, "key2", "attrib2"); + + AddWithKey(newTree, "key1", "attrib1a"); + AddWithKey(newTree, "key2", "attrib2"); + AddWithKey(newTree, "key1", "attrib1b"); + + // Act + var (result, referenceFrames) = GetSingleUpdatedComponent(); + + // Assert + Assert.Collection(result.Edits, + // Insert key1+attrib1a at the top + edit => + { + AssertEdit(edit, RenderTreeEditType.PrependFrame, 0); + Assert.Equal("attrib1a", referenceFrames[edit.ReferenceFrameIndex + 1].AttributeValue); + }, + // Delete key3+attrib3 + edit => AssertEdit(edit, RenderTreeEditType.RemoveFrame, 1), + // Delete key1+attrib1a + edit => AssertEdit(edit, RenderTreeEditType.RemoveFrame, 1), + // Delete the other key1+attrib1a + edit => AssertEdit(edit, RenderTreeEditType.RemoveFrame, 1), + // Insert key1+attrib1b at the bottom + edit => + { + AssertEdit(edit, RenderTreeEditType.PrependFrame, 2); + Assert.Equal("attrib1b", referenceFrames[edit.ReferenceFrameIndex + 1].AttributeValue); + }); + } + + [Fact] + public void HandlesClashingKeys_LastUsage() + { + // This scenario is problematic for the algorithm if it uses a "last key + // usage wins" policy for duplicate keys. It would not end up with attrib1b + // anywhere in the output, because when it sees key1 in oldTree, it tries + // to diff against the last usage of key1 in newTree, which has attrib1a. + + // However, because of the actual "duplicated keys are excluded from the + // dictionary match" policy, we don't preserve any of the key1 items, and + // the diff is valid. + + // Arrange + AddWithKey(oldTree, "key1", "attrib1a"); + AddWithKey(oldTree, "key2", "attrib2"); + AddWithKey(oldTree, "key1", "attrib1b"); + + AddWithKey(newTree, "key2", "attrib2"); + AddWithKey(newTree, "key1", "attrib1b"); + AddWithKey(newTree, "key1", "attrib1a"); + + // Act + var (result, referenceFrames) = GetSingleUpdatedComponent(); + + // Assert + Assert.Collection(result.Edits, + // Delete key1+attrib1a + edit => AssertEdit(edit, RenderTreeEditType.RemoveFrame, 0), + // Insert a new key1+attrib1a at the bottom + edit => + { + AssertEdit(edit, RenderTreeEditType.PrependFrame, 2); + Assert.Equal("attrib1a", referenceFrames[edit.ReferenceFrameIndex + 1].AttributeValue); + }); + } + [Fact] public void RecognizesTrailingSequenceWithinLoopBlockBeingRemoved() { @@ -1944,10 +2027,16 @@ private static IList GetComponents(RenderTreeBuilder builder) where T : IC .Select(x => (T)x.Component) .ToList(); - private static void AddWithKey(RenderTreeBuilder builder, object key) + private static void AddWithKey(RenderTreeBuilder builder, object key, string attributeValue = null) { builder.OpenElement(0, "el"); builder.SetKey(key); + + if (attributeValue != null) + { + builder.AddAttribute(1, "attrib", attributeValue); + } + builder.CloseElement(); } From 02e68299dccc81cacf02b574b969c8dd42131607 Mon Sep 17 00:00:00 2001 From: Steve Sanderson Date: Tue, 30 Apr 2019 20:49:35 +0100 Subject: [PATCH 11/33] Tolerate keys being added/removed incorrectly --- .../src/RenderTree/RenderTreeDiffBuilder.cs | 8 +-- .../test/RenderTreeDiffBuilderTest.cs | 56 +++++++++++++++++++ 2 files changed, 60 insertions(+), 4 deletions(-) diff --git a/src/Components/Components/src/RenderTree/RenderTreeDiffBuilder.cs b/src/Components/Components/src/RenderTree/RenderTreeDiffBuilder.cs index f6e47adb4c58..4dd998cfeae4 100644 --- a/src/Components/Components/src/RenderTree/RenderTreeDiffBuilder.cs +++ b/src/Components/Components/src/RenderTree/RenderTreeDiffBuilder.cs @@ -81,10 +81,10 @@ private static void AppendDiffEntriesForRange( keyedItemInfos = BuildKeyToInfoLookup(diffContext, oldStartIndex, oldEndIndexExcl, newStartIndex, newEndIndexExcl); } - var oldKeyItemInfo = keyedItemInfos[oldKey]; - var newKeyItemInfo = keyedItemInfos[newKey]; - var oldKeyIsInNewTree = oldKey != null && oldKeyItemInfo.NewIndex >= 0 && oldKeyItemInfo.IsUnique; - var newKeyIsInOldTree = newKey != null && newKeyItemInfo.OldIndex >= 0 && newKeyItemInfo.IsUnique; + var oldKeyItemInfo = oldKey != null ? keyedItemInfos[oldKey] : new KeyedItemInfo(-1, -1, false); + var newKeyItemInfo = newKey != null ? keyedItemInfos[newKey] : new KeyedItemInfo(-1, -1, false); + var oldKeyIsInNewTree = oldKeyItemInfo.NewIndex >= 0 && oldKeyItemInfo.IsUnique; + var newKeyIsInOldTree = newKeyItemInfo.OldIndex >= 0 && newKeyItemInfo.IsUnique; if (oldKeyIsInNewTree && newKeyIsInOldTree) { // It's a move diff --git a/src/Components/Components/test/RenderTreeDiffBuilderTest.cs b/src/Components/Components/test/RenderTreeDiffBuilderTest.cs index 5540e33ae90a..e8e258c115d3 100644 --- a/src/Components/Components/test/RenderTreeDiffBuilderTest.cs +++ b/src/Components/Components/test/RenderTreeDiffBuilderTest.cs @@ -396,6 +396,62 @@ public void HandlesClashingKeys_LastUsage() }); } + [Fact] + public void HandlesKeyBeingAdded() + { + // This is an anomolous situation that can't occur with .razor components. + // It represents the case where, for the same sequence number, we have an + // old frame without a key and a new frame with a key. + + // Arrange + oldTree.OpenElement(0, "el"); + oldTree.CloseElement(); + + newTree.OpenElement(0, "el"); + newTree.SetKey("some key"); + newTree.CloseElement(); + + // Act + var (result, referenceFrames) = GetSingleUpdatedComponent(); + + // Assert + Assert.Collection(result.Edits, + // Insert new + edit => + { + AssertEdit(edit, RenderTreeEditType.PrependFrame, 0); + Assert.Equal("some key", referenceFrames[edit.ReferenceFrameIndex].ElementKey); + }, + // Delete old + edit => AssertEdit(edit, RenderTreeEditType.RemoveFrame, 1)); + } + + [Fact] + public void HandlesKeyBeingRemoved() + { + // This is an anomolous situation that can't occur with .razor components. + // It represents the case where, for the same sequence number, we have an + // old frame with a key and a new frame without a key. + + // Arrange + oldTree.OpenElement(0, "el"); + oldTree.SetKey("some key"); + oldTree.CloseElement(); + + newTree.OpenElement(0, "el"); + newTree.CloseElement(); + + // Act + var (result, referenceFrames) = GetSingleUpdatedComponent(); + + // Assert + Assert.Collection(result.Edits, + // Insert new + edit => AssertEdit(edit, RenderTreeEditType.PrependFrame, 0), + // Delete old + edit => AssertEdit(edit, RenderTreeEditType.RemoveFrame, 1)); + } + [Fact] public void RecognizesTrailingSequenceWithinLoopBlockBeingRemoved() { From 8265369d5c1bd415fa5904a1e970361681101792 Mon Sep 17 00:00:00 2001 From: Steve Sanderson Date: Wed, 1 May 2019 11:11:30 +0100 Subject: [PATCH 12/33] E2E test harness for 'key' --- .../test/testassets/BasicTestApp/Index.razor | 1 + .../BasicTestApp/KeyCasesComponent.razor | 73 +++++++++++++++++++ .../BasicTestApp/KeyCasesTreeNode.razor | 53 ++++++++++++++ 3 files changed, 127 insertions(+) create mode 100644 src/Components/test/testassets/BasicTestApp/KeyCasesComponent.razor create mode 100644 src/Components/test/testassets/BasicTestApp/KeyCasesTreeNode.razor diff --git a/src/Components/test/testassets/BasicTestApp/Index.razor b/src/Components/test/testassets/BasicTestApp/Index.razor index 76c5881080a4..6e8bb48d4f82 100644 --- a/src/Components/test/testassets/BasicTestApp/Index.razor +++ b/src/Components/test/testassets/BasicTestApp/Index.razor @@ -50,6 +50,7 @@ + @if (SelectedComponentType != null) diff --git a/src/Components/test/testassets/BasicTestApp/KeyCasesComponent.razor b/src/Components/test/testassets/BasicTestApp/KeyCasesComponent.razor new file mode 100644 index 000000000000..d9096c2a7bb0 --- /dev/null +++ b/src/Components/test/testassets/BasicTestApp/KeyCasesComponent.razor @@ -0,0 +1,73 @@ +@using Microsoft.JSInterop +
+
+

Model

+ + +
+
+

Output

+ + + +
+
+ + + +@functions { + string modelJson = @"{ + ""label"": ""root"", + ""children"": [ + { + ""key"": ""a"", + ""label"": ""A"", + ""children"": [ + { ""key"": ""a1"", ""label"": ""A1"" }, + { ""key"": ""a2"", ""label"": ""A2"" }, + { ""key"": ""a3"", ""label"": ""A3"" } + ] + }, + { + ""key"": ""b"", + ""label"": ""B"", + ""children"": [ + { ""key"": ""b1"", ""label"": ""B1"" }, + { ""key"": ""b2"", ""label"": ""B2"" }, + { ""key"": ""b3"", ""label"": ""B3"" } + ] + } + ] +}"; + + KeyCasesTreeNode.Node parsedRootNode; + RenderContext renderContext = new RenderContext(); + + protected override void OnInit() + { + Update(); + } + + void Update() + { + renderContext.UpdateCount++; + parsedRootNode = Json.Deserialize(modelJson); + } + + public class RenderContext + { + // This is so the descendants can detect and display whether they are + // newly-instantiated on any given render + public int UpdateCount { get; set; } + } +} diff --git a/src/Components/test/testassets/BasicTestApp/KeyCasesTreeNode.razor b/src/Components/test/testassets/BasicTestApp/KeyCasesTreeNode.razor new file mode 100644 index 000000000000..16ed8de0eb67 --- /dev/null +++ b/src/Components/test/testassets/BasicTestApp/KeyCasesTreeNode.razor @@ -0,0 +1,53 @@ +
+ @Data.Label +   [ + Instance: @instanceId; + + Is new: + @if (firstCreatedOnUpdateCount == RenderContext.UpdateCount) + { + true + } + else + { + false + } + ] + + @if (Data.Children?.Any() ?? false) + { +
@{ + foreach (var child in Data.Children) + { + if (child.Key != null) + { + + } + else + { + + } + } + }
+ } +
+ +@functions { + public class Node + { + public object Key { get; set; } + public string Label { get; set; } + public List Children { get; set; } + } + + string instanceId = Guid.NewGuid().ToString("D").Substring(0, 6); + int firstCreatedOnUpdateCount; + + [Parameter] Node Data { get; set; } + [CascadingParameter] KeyCasesComponent.RenderContext RenderContext { get; set; } + + protected override void OnInit() + { + firstCreatedOnUpdateCount = RenderContext.UpdateCount; + } +} From b0040762441dda5b014e5f9626708945c088bc74 Mon Sep 17 00:00:00 2001 From: Steve Sanderson Date: Wed, 1 May 2019 12:19:44 +0100 Subject: [PATCH 13/33] Some more unit test cases --- .../test/RenderTreeDiffBuilderTest.cs | 46 +++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/src/Components/Components/test/RenderTreeDiffBuilderTest.cs b/src/Components/Components/test/RenderTreeDiffBuilderTest.cs index e8e258c115d3..46a2ca8876a4 100644 --- a/src/Components/Components/test/RenderTreeDiffBuilderTest.cs +++ b/src/Components/Components/test/RenderTreeDiffBuilderTest.cs @@ -396,6 +396,52 @@ public void HandlesClashingKeys_LastUsage() }); } + [Fact] + public void HandlesInsertionOfUnkeyedItemBeforeKey() + { + // Arrange + oldTree.OpenElement(1, "el"); + oldTree.SetKey("some key"); + oldTree.CloseElement(); + + newTree.OpenElement(0, "other"); + newTree.CloseElement(); + + newTree.OpenElement(1, "el"); + newTree.SetKey("some key"); + newTree.CloseElement(); + + // Act + var (result, referenceFrames) = GetSingleUpdatedComponent(); + + // Assert + Assert.Collection(result.Edits, + edit => AssertEdit(edit, RenderTreeEditType.PrependFrame, 0)); + } + + [Fact] + public void HandlesDeletionOfUnkeyedItemBeforeKey() + { + // Arrange + oldTree.OpenElement(0, "other"); + oldTree.CloseElement(); + + oldTree.OpenElement(1, "el"); + oldTree.SetKey("some key"); + oldTree.CloseElement(); + + newTree.OpenElement(1, "el"); + newTree.SetKey("some key"); + newTree.CloseElement(); + + // Act + var (result, referenceFrames) = GetSingleUpdatedComponent(); + + // Assert + Assert.Collection(result.Edits, + edit => AssertEdit(edit, RenderTreeEditType.RemoveFrame, 0)); + } + [Fact] public void HandlesKeyBeingAdded() { From bd4782a91029545b0ebfa2160ce879d3782f2bb2 Mon Sep 17 00:00:00 2001 From: Steve Sanderson Date: Wed, 1 May 2019 12:43:18 +0100 Subject: [PATCH 14/33] Invert diffing logic to prefer matching by key over sequence Previously it preferred sequence over key, but that's wrong, and surfaces as bugs when you mix keyed and unkeyed items. We need to prefer key over sequence, because key is meant to guarantee preservation, whereas sequence is just best-effort preservation. --- .../src/RenderTree/RenderTreeDiffBuilder.cs | 162 +++++++++++------- 1 file changed, 103 insertions(+), 59 deletions(-) diff --git a/src/Components/Components/src/RenderTree/RenderTreeDiffBuilder.cs b/src/Components/Components/src/RenderTree/RenderTreeDiffBuilder.cs index 4dd998cfeae4..4fb3adea847b 100644 --- a/src/Components/Components/src/RenderTree/RenderTreeDiffBuilder.cs +++ b/src/Components/Components/src/RenderTree/RenderTreeDiffBuilder.cs @@ -59,23 +59,48 @@ private static void AppendDiffEntriesForRange( while (hasMoreOld || hasMoreNew) { DiffAction action; - var oldSeq = hasMoreOld ? oldTree[oldStartIndex].Sequence : int.MaxValue; - var newSeq = hasMoreNew ? newTree[newStartIndex].Sequence : int.MaxValue; - if (oldSeq == newSeq) + #region "Read keys and sequence numbers" + int oldSeq, newSeq; + object oldKey, newKey; + if (hasMoreOld) { - #region "Get diff action for matching sequence numbers" - var oldKey = KeyValue(ref oldTree[oldStartIndex]); - var newKey = KeyValue(ref newTree[newStartIndex]); + ref var oldFrame = ref oldTree[oldStartIndex]; + oldSeq = oldFrame.Sequence; + oldKey = KeyValue(ref oldFrame); + } + else + { + oldSeq = int.MaxValue; + oldKey = null; + } + + if (hasMoreNew) + { + ref var newFrame = ref newTree[newStartIndex]; + newSeq = newFrame.Sequence; + newKey = KeyValue(ref newFrame); + } + else + { + newSeq = int.MaxValue; + newKey = null; + } + #endregion + + // If there's a key on either side, prefer matching by key not sequence + if (oldKey != null || newKey != null) + { + #region "Get diff action by matching on key" if (Equals(oldKey, newKey)) { - // Sequence and keys match + // Keys match action = DiffAction.Match; matchWithNewTreeIndex = newStartIndex; } else { - // Sequence matches, but key doesn't + // Keys don't match if (keyedItemInfos == null) { keyedItemInfos = BuildKeyToInfoLookup(diffContext, oldStartIndex, oldEndIndexExcl, newStartIndex, newEndIndexExcl); @@ -85,6 +110,10 @@ private static void AppendDiffEntriesForRange( var newKeyItemInfo = newKey != null ? keyedItemInfos[newKey] : new KeyedItemInfo(-1, -1, false); var oldKeyIsInNewTree = oldKeyItemInfo.NewIndex >= 0 && oldKeyItemInfo.IsUnique; var newKeyIsInOldTree = newKeyItemInfo.OldIndex >= 0 && newKeyItemInfo.IsUnique; + + // If either key is not in the other tree, we can handle it as an insert or a delete + // on this iteration. We're only forced to use the move logic that's not the case + // (i.e., both keys are in both trees) if (oldKeyIsInNewTree && newKeyIsInOldTree) { // It's a move @@ -103,80 +132,95 @@ private static void AppendDiffEntriesForRange( newKeyItemInfo.NewSiblingIndex = diffContext.SiblingIndex; keyedItemInfos[newKey] = newKeyItemInfo; } + else if (!hasMoreNew) + { + // If we've run out of new items, we must be looking at just an old item, so delete it + action = DiffAction.Delete; + } else { // It's an insertion or a deletion, or both // If the new key is in both trees, but the old key isn't, then the old item was deleted // Otherwise, it's either an insertion or *both* insertion+deletion, so pick insertion and get the deletion on the next iteration if needed - action = newKeyIsInOldTree ? DiffAction.Delete: DiffAction.Insert; + action = newKeyIsInOldTree ? DiffAction.Delete : DiffAction.Insert; } } #endregion } else { - #region "Get diff action for non-matching sequence numbers" - // Sequence doesn't match - var oldLoopedBack = oldSeq <= prevOldSeq; - var newLoopedBack = newSeq <= prevNewSeq; - if (oldLoopedBack == newLoopedBack) + #region "Get diff action by matching on sequence number" + // Neither side is keyed, so match by sequence number + if (oldSeq == newSeq) { - // Both sequences are proceeding through the same loop block, so do a simple - // preordered merge join (picking from whichever side brings us closer to being - // back in sync) - action = newSeq < oldSeq ? DiffAction.Insert : DiffAction.Delete; - - if (oldLoopedBack) - { - // If both old and new have now looped back, we must reset their 'looped back' - // tracker so we can treat them as proceeding through the same loop block - prevOldSeq = prevNewSeq = -1; - } + // Sequences match + action = DiffAction.Match; + matchWithNewTreeIndex = newStartIndex; } - else if (oldLoopedBack) + else { - // Old sequence looped back but new one didn't - // The new sequence either has some extra trailing elements in the current loop block - // which we should insert, or omits some old trailing loop blocks which we should delete - // TODO: Find a way of not recomputing this next flag on every iteration - var newLoopsBackLater = false; - for (var testIndex = newStartIndex + 1; testIndex < newEndIndexExcl; testIndex++) + // Sequences don't match + var oldLoopedBack = oldSeq <= prevOldSeq; + var newLoopedBack = newSeq <= prevNewSeq; + if (oldLoopedBack == newLoopedBack) { - if (newTree[testIndex].Sequence < newSeq) + // Both sequences are proceeding through the same loop block, so do a simple + // preordered merge join (picking from whichever side brings us closer to being + // back in sync) + action = newSeq < oldSeq ? DiffAction.Insert : DiffAction.Delete; + + if (oldLoopedBack) { - newLoopsBackLater = true; - break; + // If both old and new have now looped back, we must reset their 'looped back' + // tracker so we can treat them as proceeding through the same loop block + prevOldSeq = prevNewSeq = -1; } } - - // If the new sequence loops back later to an earlier point than this, - // then we know it's part of the existing loop block (so should be inserted). - // If not, then it's unrelated to the previous loop block (so we should treat - // the old items as trailing loop blocks to be removed). - action = newLoopsBackLater ? DiffAction.Insert : DiffAction.Delete; - } - else - { - // New sequence looped back but old one didn't - // The old sequence either has some extra trailing elements in the current loop block - // which we should delete, or the new sequence has extra trailing loop blocks which we - // should insert - // TODO: Find a way of not recomputing this next flag on every iteration - var oldLoopsBackLater = false; - for (var testIndex = oldStartIndex + 1; testIndex < oldEndIndexExcl; testIndex++) + else if (oldLoopedBack) { - if (oldTree[testIndex].Sequence < oldSeq) + // Old sequence looped back but new one didn't + // The new sequence either has some extra trailing elements in the current loop block + // which we should insert, or omits some old trailing loop blocks which we should delete + // TODO: Find a way of not recomputing this next flag on every iteration + var newLoopsBackLater = false; + for (var testIndex = newStartIndex + 1; testIndex < newEndIndexExcl; testIndex++) { - oldLoopsBackLater = true; - break; + if (newTree[testIndex].Sequence < newSeq) + { + newLoopsBackLater = true; + break; + } } + + // If the new sequence loops back later to an earlier point than this, + // then we know it's part of the existing loop block (so should be inserted). + // If not, then it's unrelated to the previous loop block (so we should treat + // the old items as trailing loop blocks to be removed). + action = newLoopsBackLater ? DiffAction.Insert : DiffAction.Delete; } + else + { + // New sequence looped back but old one didn't + // The old sequence either has some extra trailing elements in the current loop block + // which we should delete, or the new sequence has extra trailing loop blocks which we + // should insert + // TODO: Find a way of not recomputing this next flag on every iteration + var oldLoopsBackLater = false; + for (var testIndex = oldStartIndex + 1; testIndex < oldEndIndexExcl; testIndex++) + { + if (oldTree[testIndex].Sequence < oldSeq) + { + oldLoopsBackLater = true; + break; + } + } - // If the old sequence loops back later to an earlier point than this, - // then we know it's part of the existing loop block (so should be removed). - // If not, then it's unrelated to the previous loop block (so we should treat - // the new items as trailing loop blocks to be inserted). - action = oldLoopsBackLater ? DiffAction.Delete : DiffAction.Insert; + // If the old sequence loops back later to an earlier point than this, + // then we know it's part of the existing loop block (so should be removed). + // If not, then it's unrelated to the previous loop block (so we should treat + // the new items as trailing loop blocks to be inserted). + action = oldLoopsBackLater ? DiffAction.Delete : DiffAction.Insert; + } } #endregion } From 9b74707045f4c37a7cae4c1616ef6cc9d7208e64 Mon Sep 17 00:00:00 2001 From: Steve Sanderson Date: Wed, 1 May 2019 12:54:44 +0100 Subject: [PATCH 15/33] Make unit test cases more adversarial --- .../test/RenderTreeDiffBuilderTest.cs | 28 +++++++++++++++---- 1 file changed, 22 insertions(+), 6 deletions(-) diff --git a/src/Components/Components/test/RenderTreeDiffBuilderTest.cs b/src/Components/Components/test/RenderTreeDiffBuilderTest.cs index 46a2ca8876a4..0c020c151f3b 100644 --- a/src/Components/Components/test/RenderTreeDiffBuilderTest.cs +++ b/src/Components/Components/test/RenderTreeDiffBuilderTest.cs @@ -397,39 +397,54 @@ public void HandlesClashingKeys_LastUsage() } [Fact] - public void HandlesInsertionOfUnkeyedItemBeforeKey() + public void HandlesInsertionOfUnkeyedItemsAroundKey() { + // The fact that the new sequence numbers are descending makes this + // problematic if it prefers matching by sequence over key. + // However, since the policy is to prefer key over sequence, it works OK. + // Arrange oldTree.OpenElement(1, "el"); oldTree.SetKey("some key"); oldTree.CloseElement(); - newTree.OpenElement(0, "other"); + newTree.OpenElement(2, "other"); newTree.CloseElement(); newTree.OpenElement(1, "el"); newTree.SetKey("some key"); newTree.CloseElement(); + newTree.OpenElement(0, "other 2"); + newTree.CloseElement(); + // Act var (result, referenceFrames) = GetSingleUpdatedComponent(); // Assert Assert.Collection(result.Edits, - edit => AssertEdit(edit, RenderTreeEditType.PrependFrame, 0)); + edit => AssertEdit(edit, RenderTreeEditType.PrependFrame, 0), + edit => AssertEdit(edit, RenderTreeEditType.PrependFrame, 2)); } [Fact] - public void HandlesDeletionOfUnkeyedItemBeforeKey() + public void HandlesDeletionOfUnkeyedItemsAroundKey() { + // The fact that the old sequence numbers are descending makes this + // problematic if it prefers matching by sequence over key. + // However, since the policy is to prefer key over sequence, it works OK. + // Arrange - oldTree.OpenElement(0, "other"); + oldTree.OpenElement(2, "other"); oldTree.CloseElement(); oldTree.OpenElement(1, "el"); oldTree.SetKey("some key"); oldTree.CloseElement(); + oldTree.OpenElement(0, "other 2"); + oldTree.CloseElement(); + newTree.OpenElement(1, "el"); newTree.SetKey("some key"); newTree.CloseElement(); @@ -439,7 +454,8 @@ public void HandlesDeletionOfUnkeyedItemBeforeKey() // Assert Assert.Collection(result.Edits, - edit => AssertEdit(edit, RenderTreeEditType.RemoveFrame, 0)); + edit => AssertEdit(edit, RenderTreeEditType.RemoveFrame, 0), + edit => AssertEdit(edit, RenderTreeEditType.RemoveFrame, 1)); } [Fact] From 72bc532e2b49c0a806ff98b4fc490dfbb6989e18 Mon Sep 17 00:00:00 2001 From: Steve Sanderson Date: Wed, 1 May 2019 15:28:03 +0100 Subject: [PATCH 16/33] First actual E2E test --- src/Components/test/E2ETest/Tests/KeyTest.cs | 117 ++++++++++++++++++ .../BasicTestApp/KeyCasesComponent.razor | 2 +- 2 files changed, 118 insertions(+), 1 deletion(-) create mode 100644 src/Components/test/E2ETest/Tests/KeyTest.cs diff --git a/src/Components/test/E2ETest/Tests/KeyTest.cs b/src/Components/test/E2ETest/Tests/KeyTest.cs new file mode 100644 index 000000000000..bc3a0bd559e8 --- /dev/null +++ b/src/Components/test/E2ETest/Tests/KeyTest.cs @@ -0,0 +1,117 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System; +using System.Linq; +using BasicTestApp; +using Microsoft.AspNetCore.Components.E2ETest.Infrastructure; +using Microsoft.AspNetCore.Components.E2ETest.Infrastructure.ServerFixtures; +using Microsoft.AspNetCore.E2ETesting; +using Microsoft.JSInterop; +using OpenQA.Selenium; +using Xunit; +using Xunit.Abstractions; + +namespace Microsoft.AspNetCore.Components.E2ETest.Tests +{ + public class KeyTest : BasicTestAppTestBase + { + public KeyTest( + BrowserFixture browserFixture, + ToggleExecutionModeServerFixture serverFixture, + ITestOutputHelper output) + : base(browserFixture, serverFixture, output) + { + } + + protected override void InitializeAsyncCore() + { + // On WebAssembly, page reloads are expensive so skip if possible + Navigate(ServerPathBase, noReload: !_serverFixture.UsingAspNetHost); + } + + [Fact] + public void CanInsert() + { + PerformTest( + before: new[] + { + new Node("orig1", "A"), + new Node("orig2", "B"), + }, + after: new[] + { + new Node("new1", "Inserted before"), + new Node("orig1", "A"), + new Node("new2", "Inserted between"), + new Node("orig1", "B"), + new Node("new3", "Inserted after"), + }); + } + + private void PerformTest(Node[] before, Node[] after) + { + var rootBefore = new Node(null, "root", before); + var rootAfter = new Node(null, "root", after); + var jsonBefore = Json.Serialize(rootBefore); + var jsonAfter = Json.Serialize(rootAfter); + + var appElem = MountTestComponent(); + var textbox = appElem.FindElement(By.TagName("textarea")); + var updateButton = appElem.FindElement(By.TagName("button")); + + SetTextAreaValueFast(textbox, jsonBefore); + updateButton.Click(); + ValidateRenderedOutput(appElem, rootBefore); + + SetTextAreaValueFast(textbox, jsonAfter); + updateButton.Click(); + ValidateRenderedOutput(appElem, rootAfter); + } + + private static void ValidateRenderedOutput(IWebElement appElem, Node expectedRootNode) + { + var actualRootElem = appElem.FindElement(By.CssSelector(".render-output > .node")); + var actualRootNode = ReadNodeFromDOM(actualRootElem); + AssertNodesEqual(expectedRootNode, actualRootNode); + } + + private static void AssertNodesEqual(Node expectedRootNode, Node actualRootNode) + { + Assert.Equal(expectedRootNode.Label, actualRootNode.Label); + Assert.Collection( + actualRootNode.Children, + expectedRootNode.Children.Select>(expectedChild => + (actualChild => AssertNodesEqual(expectedChild, actualChild))).ToArray()); + } + + private static Node ReadNodeFromDOM(IWebElement nodeElem) + { + var label = nodeElem.FindElement(By.ClassName("label")).Text; + var childNodes = nodeElem + .FindElements(By.XPath("*[@class='children']/*[@class='node']")); + return new Node(key: null, label, childNodes.Select(ReadNodeFromDOM).ToArray()); + } + + private void SetTextAreaValueFast(IWebElement textAreaElementWithId, string value) + { + var javascript = (IJavaScriptExecutor)Browser; + javascript.ExecuteScript($"document.getElementById('{textAreaElementWithId.GetAttribute("id")}').value = {Json.Serialize(value)}"); + textAreaElementWithId.SendKeys(" "); // So it fires the change event + } + + class Node + { + public string Key { get; } + public string Label { get; } + public Node[] Children { get; } + + public Node(string key, string label, params Node[] children) + { + Key = key; + Label = label; + Children = children ?? Array.Empty(); + } + } + } +} diff --git a/src/Components/test/testassets/BasicTestApp/KeyCasesComponent.razor b/src/Components/test/testassets/BasicTestApp/KeyCasesComponent.razor index d9096c2a7bb0..9ef1a5bffae5 100644 --- a/src/Components/test/testassets/BasicTestApp/KeyCasesComponent.razor +++ b/src/Components/test/testassets/BasicTestApp/KeyCasesComponent.razor @@ -2,7 +2,7 @@

Model

- +
From a1b2327f8eb7e825e915f1b2a89d3a0a41405ed4 Mon Sep 17 00:00:00 2001 From: Steve Sanderson Date: Wed, 1 May 2019 15:38:03 +0100 Subject: [PATCH 17/33] In E2E test, verify correct preservation of components --- src/Components/test/E2ETest/Tests/KeyTest.cs | 32 +++++++++++++------- 1 file changed, 21 insertions(+), 11 deletions(-) diff --git a/src/Components/test/E2ETest/Tests/KeyTest.cs b/src/Components/test/E2ETest/Tests/KeyTest.cs index bc3a0bd559e8..d3787f65a2e2 100644 --- a/src/Components/test/E2ETest/Tests/KeyTest.cs +++ b/src/Components/test/E2ETest/Tests/KeyTest.cs @@ -41,11 +41,11 @@ public void CanInsert() }, after: new[] { - new Node("new1", "Inserted before"), + new Node("new1", "Inserted before") { IsNew = true }, new Node("orig1", "A"), - new Node("new2", "Inserted between"), - new Node("orig1", "B"), - new Node("new3", "Inserted after"), + new Node("new2", "Inserted between") { IsNew = true }, + new Node("orig2", "B"), + new Node("new3", "Inserted after") { IsNew = true }, }); } @@ -62,27 +62,33 @@ private void PerformTest(Node[] before, Node[] after) SetTextAreaValueFast(textbox, jsonBefore); updateButton.Click(); - ValidateRenderedOutput(appElem, rootBefore); + ValidateRenderedOutput(appElem, rootBefore, validatePreservation: false); SetTextAreaValueFast(textbox, jsonAfter); updateButton.Click(); - ValidateRenderedOutput(appElem, rootAfter); + ValidateRenderedOutput(appElem, rootAfter, validatePreservation: true); } - private static void ValidateRenderedOutput(IWebElement appElem, Node expectedRootNode) + private static void ValidateRenderedOutput(IWebElement appElem, Node expectedRootNode, bool validatePreservation) { var actualRootElem = appElem.FindElement(By.CssSelector(".render-output > .node")); var actualRootNode = ReadNodeFromDOM(actualRootElem); - AssertNodesEqual(expectedRootNode, actualRootNode); + AssertNodesEqual(expectedRootNode, actualRootNode, validatePreservation); } - private static void AssertNodesEqual(Node expectedRootNode, Node actualRootNode) + private static void AssertNodesEqual(Node expectedRootNode, Node actualRootNode, bool validatePreservation) { Assert.Equal(expectedRootNode.Label, actualRootNode.Label); + + if (validatePreservation) + { + Assert.Equal(expectedRootNode.IsNew, actualRootNode.IsNew); + } + Assert.Collection( actualRootNode.Children, expectedRootNode.Children.Select>(expectedChild => - (actualChild => AssertNodesEqual(expectedChild, actualChild))).ToArray()); + (actualChild => AssertNodesEqual(expectedChild, actualChild, validatePreservation))).ToArray()); } private static Node ReadNodeFromDOM(IWebElement nodeElem) @@ -90,7 +96,10 @@ private static Node ReadNodeFromDOM(IWebElement nodeElem) var label = nodeElem.FindElement(By.ClassName("label")).Text; var childNodes = nodeElem .FindElements(By.XPath("*[@class='children']/*[@class='node']")); - return new Node(key: null, label, childNodes.Select(ReadNodeFromDOM).ToArray()); + return new Node(key: null, label, childNodes.Select(ReadNodeFromDOM).ToArray()) + { + IsNew = nodeElem.FindElement(By.ClassName("is-new")).Text == "true" + }; } private void SetTextAreaValueFast(IWebElement textAreaElementWithId, string value) @@ -105,6 +114,7 @@ class Node public string Key { get; } public string Label { get; } public Node[] Children { get; } + public bool IsNew { get; set; } public Node(string key, string label, params Node[] children) { From de7dbe35ed4c2d1a0bd800c028589fddb1dc4432 Mon Sep 17 00:00:00 2001 From: Steve Sanderson Date: Wed, 1 May 2019 15:49:51 +0100 Subject: [PATCH 18/33] E2E tests for simple insert/delete cases (with and without keys) --- src/Components/test/E2ETest/Tests/KeyTest.cs | 57 ++++++++++++++++++++ 1 file changed, 57 insertions(+) diff --git a/src/Components/test/E2ETest/Tests/KeyTest.cs b/src/Components/test/E2ETest/Tests/KeyTest.cs index d3787f65a2e2..50a41a0778c8 100644 --- a/src/Components/test/E2ETest/Tests/KeyTest.cs +++ b/src/Components/test/E2ETest/Tests/KeyTest.cs @@ -49,6 +49,63 @@ public void CanInsert() }); } + [Fact] + public void CanDelete() + { + PerformTest( + before: new[] + { + new Node("orig1", "A"), // Will delete first + new Node("orig2", "B"), + new Node("orig3", "C"), // Will delete in middle + new Node("orig4", "D"), + new Node("orig5", "E"), // Will delete at end + }, + after: new[] + { + new Node("orig2", "B"), + new Node("orig4", "D"), + }); + } + + [Fact] + public void CanInsertUnkeyed() + { + PerformTest( + before: new[] + { + new Node("orig1", "A"), + new Node("orig2", "B"), + }, + after: new[] + { + new Node(null, "Inserted before") { IsNew = true }, + new Node("orig1", "A"), + new Node(null, "Inserted between") { IsNew = true }, + new Node("orig2", "B"), + new Node(null, "Inserted after") { IsNew = true }, + }); + } + + [Fact] + public void CanDeleteUnkeyed() + { + PerformTest( + before: new[] + { + new Node(null, "A"), // Will delete first + new Node("orig2", "B"), + new Node(null, "C"), // Will delete in middle + new Node("orig4", "D"), + new Node(null, "E"), // Will delete at end + }, + after: new[] + { + new Node("orig2", "B"), + new Node("orig4", "D"), + }); + } + private void PerformTest(Node[] before, Node[] after) { var rootBefore = new Node(null, "root", before); From 0a0afd86ada6f54e4418deb27a7e25d6b6f2a50c Mon Sep 17 00:00:00 2001 From: Steve Sanderson Date: Wed, 1 May 2019 15:58:24 +0100 Subject: [PATCH 19/33] E2E test for reordering. Also extend other tests to verify simultaneous editing. --- src/Components/test/E2ETest/Tests/KeyTest.cs | 49 ++++++++++++++++++-- 1 file changed, 45 insertions(+), 4 deletions(-) diff --git a/src/Components/test/E2ETest/Tests/KeyTest.cs b/src/Components/test/E2ETest/Tests/KeyTest.cs index 50a41a0778c8..4bc649eadd0a 100644 --- a/src/Components/test/E2ETest/Tests/KeyTest.cs +++ b/src/Components/test/E2ETest/Tests/KeyTest.cs @@ -44,7 +44,7 @@ public void CanInsert() new Node("new1", "Inserted before") { IsNew = true }, new Node("orig1", "A"), new Node("new2", "Inserted between") { IsNew = true }, - new Node("orig2", "B"), + new Node("orig2", "B edited"), new Node("new3", "Inserted after") { IsNew = true }, }); } @@ -64,7 +64,7 @@ public void CanDelete() after: new[] { new Node("orig2", "B"), - new Node("orig4", "D"), + new Node("orig4", "D edited"), }); } @@ -80,7 +80,7 @@ public void CanInsertUnkeyed() after: new[] { new Node(null, "Inserted before") { IsNew = true }, - new Node("orig1", "A"), + new Node("orig1", "A edited"), new Node(null, "Inserted between") { IsNew = true }, new Node("orig2", "B"), new Node(null, "Inserted after") { IsNew = true }, @@ -101,11 +101,52 @@ public void CanDeleteUnkeyed() }, after: new[] { - new Node("orig2", "B"), + new Node("orig2", "B edited"), new Node("orig4", "D"), }); } + [Fact] + public void CanReorder() + { + PerformTest( + before: new[] + { + new Node("keyA", "A", + new Node("keyA1", "A1"), + new Node("keyA2", "A2"), + new Node("keyA3", "A3")), + new Node("keyB", "B", + new Node("keyB1", "B1"), + new Node("keyB2", "B2"), + new Node("keyB3", "B3")), + new Node("keyC", "C", + new Node("keyC1", "C1"), + new Node("keyC2", "C2"), + new Node("keyC3", "C3")), + }, + after: new[] + { + // We're implicitly verifying that all the component instances were preserved, + // because we're not marking any with "IsNew = true" + new Node("keyC", "C", // Rotate all three (ABC->CAB) + // Swap first and last + new Node("keyC3", "C3"), + new Node("keyC2", "C2 edited"), + new Node("keyC1", "C1")), + new Node("keyA", "A", + // Swap first two + new Node("keyA2", "A2 edited"), + new Node("keyA1", "A1"), + new Node("keyA3", "A3")), + new Node("keyB", "B edited", + // Swap last two + new Node("keyB1", "B1"), + new Node("keyB3", "B3"), + new Node("keyB2", "B2 edited")), + }); + } + private void PerformTest(Node[] before, Node[] after) { var rootBefore = new Node(null, "root", before); From 06c6a9b2ecd05d38bc2b4be2fdb4bb0d7c78972f Mon Sep 17 00:00:00 2001 From: Steve Sanderson Date: Wed, 1 May 2019 16:13:01 +0100 Subject: [PATCH 20/33] E2E test for many simultaneous changes --- src/Components/test/E2ETest/Tests/KeyTest.cs | 56 ++++++++++++++++++++ 1 file changed, 56 insertions(+) diff --git a/src/Components/test/E2ETest/Tests/KeyTest.cs b/src/Components/test/E2ETest/Tests/KeyTest.cs index 4bc649eadd0a..c54ae1a3b223 100644 --- a/src/Components/test/E2ETest/Tests/KeyTest.cs +++ b/src/Components/test/E2ETest/Tests/KeyTest.cs @@ -147,6 +147,62 @@ public void CanReorder() }); } + [Fact] + public void CanReorderInsertDeleteAndEdit_WithAndWithoutKeys() + { + // This test is a complex bundle of many types of changes happening simultaneously + PerformTest( + before: new[] + { + new Node("keyA", "A", + new Node("keyA1", "A1"), + new Node(null, "A2 unkeyed"), + new Node("keyA3", "A3"), + new Node("keyA4", "A4")), + new Node("keyB", "B", + new Node(null, "B1 unkeyed"), + new Node("keyB2", "B2"), + new Node("keyB3", "B3"), + new Node("keyB4", "B4")), + new Node("keyC", "C", + new Node("keyC1", "C1"), + new Node("keyC2", "C2"), + new Node("keyC3", "C3"), + new Node(null, "C4 unkeyed")), + }, + after: new[] + { + // Swapped A and C + new Node("keyC", "C", + // C1-4 were reordered + // C5 was inserted + new Node("keyC5", "C5 inserted") { IsNew = true }, + new Node("keyC2", "C2"), + // C6 was inserted with no key + new Node(null, "C6 unkeyed inserted") { IsNew = true }, + // C1 was edited + new Node("keyC1", "C1 edited"), + new Node("keyC3", "C3") + // C4 unkeyed was deleted + ), + // B was deleted + // D was inserted + new Node("keyD", "D inserted", + new Node("keyB1", "D1") { IsNew = true }, // Matches an old key, but treated as new because we don't move between parents + new Node("keyD2", "D2") { IsNew = true }, + new Node(null, "D3 unkeyed") { IsNew = true }) + { IsNew = true }, + new Node("keyA", "A", + new Node("keyA1", "A1"), + // A2 (unkeyed) was edited + new Node(null, "A2 unkeyed edited"), + new Node("keyA3", "A3"), + // A4 was deleted + // A5 was inserted + new Node("keyA5", "A5 inserted") { IsNew = true }), + }); + } + private void PerformTest(Node[] before, Node[] after) { var rootBefore = new Node(null, "root", before); From d937401d61a1e9ea9d53ae7ab3a2357f10e5593b Mon Sep 17 00:00:00 2001 From: Steve Sanderson Date: Wed, 1 May 2019 16:14:12 +0100 Subject: [PATCH 21/33] Update reference sources --- .../Microsoft.AspNetCore.Components.netstandard2.0.cs | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/Components/Components/ref/Microsoft.AspNetCore.Components.netstandard2.0.cs b/src/Components/Components/ref/Microsoft.AspNetCore.Components.netstandard2.0.cs index 37431bbb5695..95c356e520e7 100644 --- a/src/Components/Components/ref/Microsoft.AspNetCore.Components.netstandard2.0.cs +++ b/src/Components/Components/ref/Microsoft.AspNetCore.Components.netstandard2.0.cs @@ -771,12 +771,18 @@ public readonly partial struct RenderTreeDiff public readonly int ComponentId; public readonly System.ArraySegment Edits; } - [System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)] + [System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Explicit)] public readonly partial struct RenderTreeEdit { + [System.Runtime.InteropServices.FieldOffsetAttribute(8)] + public readonly int MoveToSiblingIndex; + [System.Runtime.InteropServices.FieldOffsetAttribute(8)] public readonly int ReferenceFrameIndex; + [System.Runtime.InteropServices.FieldOffsetAttribute(16)] public readonly string RemovedAttributeName; + [System.Runtime.InteropServices.FieldOffsetAttribute(4)] public readonly int SiblingIndex; + [System.Runtime.InteropServices.FieldOffsetAttribute(0)] public readonly Microsoft.AspNetCore.Components.RenderTree.RenderTreeEditType Type; } public enum RenderTreeEditType @@ -789,6 +795,8 @@ public enum RenderTreeEditType StepIn = 6, StepOut = 7, UpdateMarkup = 8, + PermutationListEntry = 9, + PermutationListEnd = 10, } public enum RenderTreeFrameType { From 5c3efe6cfc9131162f1c5a532be5bd989dd5e9cf Mon Sep 17 00:00:00 2001 From: Steve Sanderson Date: Wed, 1 May 2019 16:16:32 +0100 Subject: [PATCH 22/33] CR: Avoid x = y = z --- .../Components/src/RenderTree/RenderTreeDiffBuilder.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Components/Components/src/RenderTree/RenderTreeDiffBuilder.cs b/src/Components/Components/src/RenderTree/RenderTreeDiffBuilder.cs index 4fb3adea847b..a561e85c16f1 100644 --- a/src/Components/Components/src/RenderTree/RenderTreeDiffBuilder.cs +++ b/src/Components/Components/src/RenderTree/RenderTreeDiffBuilder.cs @@ -173,7 +173,8 @@ private static void AppendDiffEntriesForRange( { // If both old and new have now looped back, we must reset their 'looped back' // tracker so we can treat them as proceeding through the same loop block - prevOldSeq = prevNewSeq = -1; + prevOldSeq = -1; + prevNewSeq = -1; } } else if (oldLoopedBack) From eef782843e668179453ef8c9e6812af3a6867a8c Mon Sep 17 00:00:00 2001 From: Steve Sanderson Date: Wed, 1 May 2019 16:18:07 +0100 Subject: [PATCH 23/33] CR: Only use 'finally' for actual cleanup --- .../src/RenderTree/RenderTreeDiffBuilder.cs | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/src/Components/Components/src/RenderTree/RenderTreeDiffBuilder.cs b/src/Components/Components/src/RenderTree/RenderTreeDiffBuilder.cs index a561e85c16f1..91c78f8516d7 100644 --- a/src/Components/Components/src/RenderTree/RenderTreeDiffBuilder.cs +++ b/src/Components/Components/src/RenderTree/RenderTreeDiffBuilder.cs @@ -253,12 +253,10 @@ private static void AppendDiffEntriesForRange( } #endregion } - } - finally - { + + #region "Write permutations list" if (keyedItemInfos != null) { - #region "Write permutations list" var hasPermutations = false; foreach (var keyValuePair in keyedItemInfos) { @@ -278,8 +276,13 @@ private static void AppendDiffEntriesForRange( // when the list is finished diffContext.Edits.Append(RenderTreeEdit.PermutationListEnd()); } - #endregion - + } + #endregion + } + finally + { + if (keyedItemInfos != null) + { keyedItemInfos.Clear(); diffContext.KeyedItemInfoDictionaryPool.Return(keyedItemInfos); } From 09201d3b766a5e51033a2322d5ff73559c875266 Mon Sep 17 00:00:00 2001 From: Steve Sanderson Date: Wed, 1 May 2019 16:21:42 +0100 Subject: [PATCH 24/33] CR: Clean up RenderTreeFrame assignment --- src/Components/Components/src/RenderTree/RenderTreeBuilder.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Components/Components/src/RenderTree/RenderTreeBuilder.cs b/src/Components/Components/src/RenderTree/RenderTreeBuilder.cs index 9774b33b6e14..78a174885bf3 100644 --- a/src/Components/Components/src/RenderTree/RenderTreeBuilder.cs +++ b/src/Components/Components/src/RenderTree/RenderTreeBuilder.cs @@ -470,10 +470,10 @@ public void SetKey(object value) switch (parentFrame.FrameType) { case RenderTreeFrameType.Element: - _entries.Buffer[parentFrameIndexValue] = parentFrame.WithElementKey(value); + parentFrame = parentFrame.WithElementKey(value); // It's a ref var, so this writes to the array break; case RenderTreeFrameType.Component: - _entries.Buffer[parentFrameIndexValue] = parentFrame.WithComponentKey(value); + parentFrame = parentFrame.WithComponentKey(value); // It's a ref var, so this writes to the array break; default: throw new InvalidOperationException($"Cannot set a key on a frame of type {parentFrame.FrameType}."); From e1251097b692c35be98478caf315dd6ece017e66 Mon Sep 17 00:00:00 2001 From: Steve Sanderson Date: Wed, 1 May 2019 16:35:43 +0100 Subject: [PATCH 25/33] CR: Include 'key' in RenderTreeFrame.ToString() --- src/Components/Components/src/RenderTree/RenderTreeFrame.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Components/Components/src/RenderTree/RenderTreeFrame.cs b/src/Components/Components/src/RenderTree/RenderTreeFrame.cs index 3e89977db898..7bf18c150dea 100644 --- a/src/Components/Components/src/RenderTree/RenderTreeFrame.cs +++ b/src/Components/Components/src/RenderTree/RenderTreeFrame.cs @@ -353,10 +353,10 @@ public override string ToString() return $"Attribute: (seq={Sequence}, id={AttributeEventHandlerId}) '{AttributeName}'='{AttributeValue}'"; case RenderTreeFrameType.Component: - return $"Component: (seq={Sequence}, len={ComponentSubtreeLength}) {ComponentType}"; + return $"Component: (seq={Sequence}, key={ComponentKey ?? "(none)"}, len={ComponentSubtreeLength}) {ComponentType}"; case RenderTreeFrameType.Element: - return $"Element: (seq={Sequence}, len={ElementSubtreeLength}) {ElementName}"; + return $"Element: (seq={Sequence}, key={ElementKey ?? "(none)"}, len={ElementSubtreeLength}) {ElementName}"; case RenderTreeFrameType.Region: return $"Region: (seq={Sequence}, len={RegionSubtreeLength})"; From c9813f1f511dae82e1d469b2a95bd675d2671379 Mon Sep 17 00:00:00 2001 From: Steve Sanderson Date: Wed, 1 May 2019 16:40:52 +0100 Subject: [PATCH 26/33] CR: Avoid "new T()" in StackObjectPool --- .../Components/src/RenderTree/StackObjectPool.cs | 10 ++++++---- .../Components/src/Rendering/RenderBatchBuilder.cs | 2 +- .../Components/test/StackObjectPoolTest.cs | 12 ++++++------ 3 files changed, 13 insertions(+), 11 deletions(-) diff --git a/src/Components/Components/src/RenderTree/StackObjectPool.cs b/src/Components/Components/src/RenderTree/StackObjectPool.cs index 7489eede22f8..a2c9c1f5241b 100644 --- a/src/Components/Components/src/RenderTree/StackObjectPool.cs +++ b/src/Components/Components/src/RenderTree/StackObjectPool.cs @@ -9,16 +9,18 @@ namespace Microsoft.AspNetCore.Components.RenderTree // balanced as in a stack. It retains up to 'maxPreservedItems' instances in // memory, then for any further requests it supplies untracked instances. - internal class StackObjectPool where T : class, new() + internal class StackObjectPool where T : class { private readonly int _maxPreservedItems; + private readonly Func _instanceFactory; private readonly T[] _contents; private int _numSuppliedItems; private int _numTrackedItems; - public StackObjectPool(int maxPreservedItems) + public StackObjectPool(int maxPreservedItems, Func instanceFactory) { _maxPreservedItems = maxPreservedItems; + _instanceFactory = instanceFactory ?? throw new ArgumentNullException(nameof(instanceFactory)); _contents = new T[_maxPreservedItems]; } @@ -31,7 +33,7 @@ public T Get() if (_numTrackedItems < _numSuppliedItems) { // Need to allocate a new one - var newItem = new T(); + var newItem = _instanceFactory(); _contents[_numTrackedItems++] = newItem; return newItem; } @@ -44,7 +46,7 @@ public T Get() else { // Pool is full; return untracked instance - return new T(); + return _instanceFactory(); } } diff --git a/src/Components/Components/src/Rendering/RenderBatchBuilder.cs b/src/Components/Components/src/Rendering/RenderBatchBuilder.cs index 71a9cad8fa70..bb5daacec41b 100644 --- a/src/Components/Components/src/Rendering/RenderBatchBuilder.cs +++ b/src/Components/Components/src/Rendering/RenderBatchBuilder.cs @@ -31,7 +31,7 @@ internal class RenderBatchBuilder public Dictionary AttributeDiffSet { get; } = new Dictionary(); internal StackObjectPool> KeyedItemInfoDictionaryPool { get; } - = new StackObjectPool>(maxPreservedItems: 10); + = new StackObjectPool>(maxPreservedItems: 10, () => new Dictionary()); public void ClearStateForCurrentBatch() { diff --git a/src/Components/Components/test/StackObjectPoolTest.cs b/src/Components/Components/test/StackObjectPoolTest.cs index 5804d240bc40..33b9becc0549 100644 --- a/src/Components/Components/test/StackObjectPoolTest.cs +++ b/src/Components/Components/test/StackObjectPoolTest.cs @@ -13,7 +13,7 @@ public class StackObjectPoolTest public void CanGetInstances() { // Arrange - var stackObjectPool = new StackObjectPool(10); + var stackObjectPool = new StackObjectPool(10, () => new object()); // Act var instance1 = stackObjectPool.Get(); @@ -29,7 +29,7 @@ public void CanGetInstances() public void CanReturnInstances() { // Arrange - var stackObjectPool = new StackObjectPool(10); + var stackObjectPool = new StackObjectPool(10, () => new object()); var instance1 = stackObjectPool.Get(); var instance2 = stackObjectPool.Get(); @@ -43,7 +43,7 @@ public void CanReturnInstances() public void ReusesInstancesInPoolUpToCapacity() { // Arrange - var stackObjectPool = new StackObjectPool(10); + var stackObjectPool = new StackObjectPool(10, () => new object()); var instance1 = stackObjectPool.Get(); var instance2 = stackObjectPool.Get(); stackObjectPool.Return(instance2); @@ -66,7 +66,7 @@ public void ReusesInstancesInPoolUpToCapacity() public void SuppliesTransientInstancesWhenExceedingCapacity() { // Arrange - var stackObjectPool = new StackObjectPool(1); + var stackObjectPool = new StackObjectPool(1, () => new object()); // Act 1: Returns distinct instances beyond capacity var instance1 = stackObjectPool.Get(); @@ -94,7 +94,7 @@ public void SuppliesTransientInstancesWhenExceedingCapacity() public void CannotReturnWhenEmpty() { // Arrange - var stackObjectPool = new StackObjectPool(10); + var stackObjectPool = new StackObjectPool(10, () => new object()); // Act/Assert var ex = Assert.Throws(() => @@ -108,7 +108,7 @@ public void CannotReturnWhenEmpty() public void CannotReturnMismatchingTrackedItem() { // Arrange - var stackObjectPool = new StackObjectPool(10); + var stackObjectPool = new StackObjectPool(10, () => new object()); var instance1 = stackObjectPool.Get(); var instance2 = stackObjectPool.Get(); From 964b7648d42246396279f181c0c153333ba81e51 Mon Sep 17 00:00:00 2001 From: Steve Sanderson Date: Wed, 1 May 2019 16:51:48 +0100 Subject: [PATCH 27/33] CR: Make KeyedItemInfo readonly --- .../src/RenderTree/RenderTreeDiffBuilder.cs | 6 ++-- .../Components/src/Rendering/KeyedItemInfo.cs | 28 +++++++++++++------ 2 files changed, 22 insertions(+), 12 deletions(-) diff --git a/src/Components/Components/src/RenderTree/RenderTreeDiffBuilder.cs b/src/Components/Components/src/RenderTree/RenderTreeDiffBuilder.cs index 91c78f8516d7..6e04bf67dfc1 100644 --- a/src/Components/Components/src/RenderTree/RenderTreeDiffBuilder.cs +++ b/src/Components/Components/src/RenderTree/RenderTreeDiffBuilder.cs @@ -127,10 +127,8 @@ private static void AppendDiffEntriesForRange( // Since diffContext.SiblingIndex only increases, we can be sure the values we // write at this point will remain correct, because there won't be any further // insertions/deletions at smaller sibling indices. - oldKeyItemInfo.OldSiblingIndex = diffContext.SiblingIndex; - keyedItemInfos[oldKey] = oldKeyItemInfo; - newKeyItemInfo.NewSiblingIndex = diffContext.SiblingIndex; - keyedItemInfos[newKey] = newKeyItemInfo; + keyedItemInfos[oldKey] = oldKeyItemInfo.WithOldSiblingIndex(diffContext.SiblingIndex); + keyedItemInfos[newKey] = newKeyItemInfo.WithNewSiblingIndex(diffContext.SiblingIndex); } else if (!hasMoreNew) { diff --git a/src/Components/Components/src/Rendering/KeyedItemInfo.cs b/src/Components/Components/src/Rendering/KeyedItemInfo.cs index 5d8d53ce65b9..f2a56341e2bb 100644 --- a/src/Components/Components/src/Rendering/KeyedItemInfo.cs +++ b/src/Components/Components/src/Rendering/KeyedItemInfo.cs @@ -3,15 +3,14 @@ namespace Microsoft.AspNetCore.Components.Rendering { - // Used internally during diffing to track what we know about - // keyed items and their positions - internal struct KeyedItemInfo + // Used internally during diffing to track what we know about keyed items and their positions + internal readonly struct KeyedItemInfo { - public int OldIndex; - public int NewIndex; - public int OldSiblingIndex; - public int NewSiblingIndex; - public bool IsUnique; + public readonly int OldIndex; + public readonly int NewIndex; + public readonly int OldSiblingIndex; + public readonly int NewSiblingIndex; + public readonly bool IsUnique; public KeyedItemInfo(int oldIndex, int newIndex, bool isUnique) { @@ -30,5 +29,18 @@ public KeyedItemInfo(int oldIndex, int newIndex, bool isUnique) // Guidance for developers is therefore to use distinct keys. IsUnique = isUnique; } + + private KeyedItemInfo(in KeyedItemInfo copyFrom, int oldSiblingIndex, int newSiblingIndex) + { + this = copyFrom; + OldSiblingIndex = oldSiblingIndex; + NewSiblingIndex = newSiblingIndex; + } + + public KeyedItemInfo WithOldSiblingIndex(int oldSiblingIndex) + => new KeyedItemInfo(this, oldSiblingIndex, NewSiblingIndex); + + public KeyedItemInfo WithNewSiblingIndex(int newSiblingIndex) + => new KeyedItemInfo(this, OldSiblingIndex, newSiblingIndex); } } From 66a56157f3f0480223501622c9254d95167b81b4 Mon Sep 17 00:00:00 2001 From: Steve Sanderson Date: Mon, 6 May 2019 16:53:41 +0100 Subject: [PATCH 28/33] CR: Handle change of frame type with matching keys (and sequence) --- .../src/RenderTree/RenderTreeDiffBuilder.cs | 12 ++++- .../test/RenderTreeDiffBuilderTest.cs | 47 +++++++++++++++++++ 2 files changed, 58 insertions(+), 1 deletion(-) diff --git a/src/Components/Components/src/RenderTree/RenderTreeDiffBuilder.cs b/src/Components/Components/src/RenderTree/RenderTreeDiffBuilder.cs index 6e04bf67dfc1..baaf6097de20 100644 --- a/src/Components/Components/src/RenderTree/RenderTreeDiffBuilder.cs +++ b/src/Components/Components/src/RenderTree/RenderTreeDiffBuilder.cs @@ -511,11 +511,21 @@ private static void AppendDiffEntriesForFramesWithSameSequence( ref var oldFrame = ref oldTree[oldFrameIndex]; ref var newFrame = ref newTree[newFrameIndex]; + // This can't happen for sequence-matched frames from .razor components, but it can happen if you write your + // builder logic manually or if two dissimilar frames matched by key. Treat as completely unrelated. + var newFrameType = newFrame.FrameType; + if (oldFrame.FrameType != newFrameType) + { + InsertNewFrame(ref diffContext, newFrameIndex); + RemoveOldFrame(ref diffContext, oldFrameIndex); + return; + } + // We can assume that the old and new frames are of the same type, because they correspond // to the same sequence number (and if not, the behaviour is undefined). // TODO: Consider supporting dissimilar types at same sequence for custom IComponent implementations. // It should only be a matter of calling RemoveOldFrame+InsertNewFrame - switch (newFrame.FrameType) + switch (newFrameType) { case RenderTreeFrameType.Text: { diff --git a/src/Components/Components/test/RenderTreeDiffBuilderTest.cs b/src/Components/Components/test/RenderTreeDiffBuilderTest.cs index 0c020c151f3b..b1dff6447732 100644 --- a/src/Components/Components/test/RenderTreeDiffBuilderTest.cs +++ b/src/Components/Components/test/RenderTreeDiffBuilderTest.cs @@ -2104,6 +2104,53 @@ public void CanMoveAfterDeletedItem() entry => AssertEdit(entry, RenderTreeEditType.PermutationListEnd, 0)); } + [Fact] + public void CanChangeFrameTypeWithMatchingSequenceNumber() + { + oldTree.OpenElement(0, "some elem"); + oldTree.AddContent(1, "Hello!"); + oldTree.CloseElement(); + + newTree.AddContent(0, "some text"); + + // Act + var (result, referenceFrames) = GetSingleUpdatedComponent(); + + // Assert + Assert.Collection(result.Edits, + entry => + { + AssertEdit(entry, RenderTreeEditType.PrependFrame, 0); + Assert.Equal(0, entry.ReferenceFrameIndex); + Assert.Equal("some text", referenceFrames[entry.ReferenceFrameIndex].TextContent); + }, + entry => AssertEdit(entry, RenderTreeEditType.RemoveFrame, 1)); + } + + [Fact] + public void CanChangeFrameTypeWithMatchingKey() + { + oldTree.OpenComponent(0); + oldTree.CloseComponent(); + + newTree.OpenElement(0, "some elem"); + newTree.SetKey("my key"); + newTree.CloseElement(); + + // Act + var (result, referenceFrames) = GetSingleUpdatedComponent(); + + // Assert + Assert.Collection(result.Edits, + entry => + { + AssertEdit(entry, RenderTreeEditType.PrependFrame, 0); + Assert.Equal(0, entry.ReferenceFrameIndex); + Assert.Equal("some elem", referenceFrames[entry.ReferenceFrameIndex].ElementName); + }, + entry => AssertEdit(entry, RenderTreeEditType.RemoveFrame, 1)); + } + private (RenderTreeDiff, RenderTreeFrame[]) GetSingleUpdatedComponent(bool initializeFromFrames = false) { var result = GetSingleUpdatedComponentWithBatch(initializeFromFrames); From 80f954d1f04daf402cad46292eebdcc12fe88922 Mon Sep 17 00:00:00 2001 From: Steve Sanderson Date: Tue, 7 May 2019 10:04:11 +0100 Subject: [PATCH 29/33] CR: Add E2E test showing form + key scenarios --- .../test/testassets/BasicTestApp/Index.razor | 1 + .../ReorderingFocusComponent.razor | 53 +++++++++++++++++++ 2 files changed, 54 insertions(+) create mode 100644 src/Components/test/testassets/BasicTestApp/ReorderingFocusComponent.razor diff --git a/src/Components/test/testassets/BasicTestApp/Index.razor b/src/Components/test/testassets/BasicTestApp/Index.razor index 6e8bb48d4f82..92f8d65b94d7 100644 --- a/src/Components/test/testassets/BasicTestApp/Index.razor +++ b/src/Components/test/testassets/BasicTestApp/Index.razor @@ -51,6 +51,7 @@ + @if (SelectedComponentType != null) diff --git a/src/Components/test/testassets/BasicTestApp/ReorderingFocusComponent.razor b/src/Components/test/testassets/BasicTestApp/ReorderingFocusComponent.razor new file mode 100644 index 000000000000..6ff9c1052c7e --- /dev/null +++ b/src/Components/test/testassets/BasicTestApp/ReorderingFocusComponent.razor @@ -0,0 +1,53 @@ +

To do

+ +

+ This component will randomly reorder the todo items on each keystroke. + The point of this is to show that focus is correctly preserved even + when items are moved around. Also, by checking the boxes to move items + between the two lists, we show that use of key causes the + form element state to behave as expected. +

+ +
    + @foreach (var item in todoItems.Where(item => !item.IsDone)) + { +
  • + + +
  • + } +
+ +

Done

+ +
    + @foreach (var item in todoItems.Where(item => item.IsDone)) + { +
  • + + +
  • + } +
+ +@functions { + Random rng = new Random(); + TodoItem[] todoItems = new[] + { + new TodoItem { Id = 1, Text = "First" }, + new TodoItem { Id = 2, Text = "Second" }, + new TodoItem { Id = 3, Text = "Third" }, + }; + + void Shuffle() + { + todoItems = todoItems.OrderBy(x => rng.Next()).ToArray(); + } + + class TodoItem + { + public int Id { get; set; } + public string Text { get; set; } + public bool IsDone { get; set; } + } +} From 3fa9345f74cf4cb4814839e6af90e2976e17383f Mon Sep 17 00:00:00 2001 From: Steve Sanderson Date: Tue, 7 May 2019 10:17:53 +0100 Subject: [PATCH 30/33] Preserve focus across edits --- .../Browser.JS/dist/Debug/blazor.server.js | 17 +++++++++++----- .../dist/Debug/blazor.webassembly.js | 17 +++++++++++----- .../Browser.JS/dist/Release/blazor.server.js | 4 ++-- .../dist/Release/blazor.webassembly.js | 2 +- .../src/Rendering/BrowserRenderer.ts | 10 +++++++++- .../src/Rendering/LogicalElements.ts | 20 +++++++++---------- 6 files changed, 46 insertions(+), 24 deletions(-) diff --git a/src/Components/Browser.JS/dist/Debug/blazor.server.js b/src/Components/Browser.JS/dist/Debug/blazor.server.js index a771ac064a74..b8f0eb6fb45e 100644 --- a/src/Components/Browser.JS/dist/Debug/blazor.server.js +++ b/src/Components/Browser.JS/dist/Debug/blazor.server.js @@ -13263,7 +13263,13 @@ var BrowserRenderer = /** @class */ (function () { clearBetween(rootElementToClear, rootElementToClearEnd); } } + var ownerDocument = LogicalElements_1.getClosestDomElement(element).ownerDocument; + var activeElementBefore = ownerDocument && ownerDocument.activeElement; this.applyEdits(batch, element, 0, edits, referenceFrames); + // Try to restore focus in case it was lost due to an element move + if ((activeElementBefore instanceof HTMLElement) && ownerDocument && ownerDocument.activeElement !== activeElementBefore) { + activeElementBefore.focus(); + } }; BrowserRenderer.prototype.disposeComponent = function (componentId) { delete this.childComponentLocations[componentId]; @@ -14231,11 +14237,6 @@ function permuteLogicalChildren(parent, permutationList) { }); } exports.permuteLogicalChildren = permuteLogicalChildren; -function getLogicalNextSibling(element) { - var siblings = getLogicalChildrenArray(getLogicalParent(element)); - var siblingIndex = Array.prototype.indexOf.call(siblings, element); - return siblings[siblingIndex + 1] || null; -} function getClosestDomElement(logicalElement) { if (logicalElement instanceof Element) { return logicalElement; @@ -14247,6 +14248,12 @@ function getClosestDomElement(logicalElement) { throw new Error('Not a valid logical element'); } } +exports.getClosestDomElement = getClosestDomElement; +function getLogicalNextSibling(element) { + var siblings = getLogicalChildrenArray(getLogicalParent(element)); + var siblingIndex = Array.prototype.indexOf.call(siblings, element); + return siblings[siblingIndex + 1] || null; +} function appendDomNode(child, parent) { // This function only puts 'child' into the DOM in the right place relative to 'parent' // It does not update the logical children array of anything diff --git a/src/Components/Browser.JS/dist/Debug/blazor.webassembly.js b/src/Components/Browser.JS/dist/Debug/blazor.webassembly.js index 0f8c9698c61c..7df07ee7b40d 100644 --- a/src/Components/Browser.JS/dist/Debug/blazor.webassembly.js +++ b/src/Components/Browser.JS/dist/Debug/blazor.webassembly.js @@ -1023,7 +1023,13 @@ var BrowserRenderer = /** @class */ (function () { clearBetween(rootElementToClear, rootElementToClearEnd); } } + var ownerDocument = LogicalElements_1.getClosestDomElement(element).ownerDocument; + var activeElementBefore = ownerDocument && ownerDocument.activeElement; this.applyEdits(batch, element, 0, edits, referenceFrames); + // Try to restore focus in case it was lost due to an element move + if ((activeElementBefore instanceof HTMLElement) && ownerDocument && ownerDocument.activeElement !== activeElementBefore) { + activeElementBefore.focus(); + } }; BrowserRenderer.prototype.disposeComponent = function (componentId) { delete this.childComponentLocations[componentId]; @@ -1991,11 +1997,6 @@ function permuteLogicalChildren(parent, permutationList) { }); } exports.permuteLogicalChildren = permuteLogicalChildren; -function getLogicalNextSibling(element) { - var siblings = getLogicalChildrenArray(getLogicalParent(element)); - var siblingIndex = Array.prototype.indexOf.call(siblings, element); - return siblings[siblingIndex + 1] || null; -} function getClosestDomElement(logicalElement) { if (logicalElement instanceof Element) { return logicalElement; @@ -2007,6 +2008,12 @@ function getClosestDomElement(logicalElement) { throw new Error('Not a valid logical element'); } } +exports.getClosestDomElement = getClosestDomElement; +function getLogicalNextSibling(element) { + var siblings = getLogicalChildrenArray(getLogicalParent(element)); + var siblingIndex = Array.prototype.indexOf.call(siblings, element); + return siblings[siblingIndex + 1] || null; +} function appendDomNode(child, parent) { // This function only puts 'child' into the DOM in the right place relative to 'parent' // It does not update the logical children array of anything diff --git a/src/Components/Browser.JS/dist/Release/blazor.server.js b/src/Components/Browser.JS/dist/Release/blazor.server.js index 33c3d56ba8ff..785cfa613a8d 100644 --- a/src/Components/Browser.JS/dist/Release/blazor.server.js +++ b/src/Components/Browser.JS/dist/Release/blazor.server.js @@ -1,11 +1,11 @@ -!function(e){var t={};function n(r){if(t[r])return t[r].exports;var o=t[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)n.d(r,o,function(t){return e[t]}.bind(null,o));return r},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=46)}([function(e,t,n){"use strict";var r;n.d(t,"a",function(){return r}),function(e){e[e.Trace=0]="Trace",e[e.Debug=1]="Debug",e[e.Information=2]="Information",e[e.Warning=3]="Warning",e[e.Error=4]="Error",e[e.Critical=5]="Critical",e[e.None=6]="None"}(r||(r={}))},function(e,t,n){"use strict";n.d(t,"a",function(){return s}),n.d(t,"e",function(){return u}),n.d(t,"f",function(){return c}),n.d(t,"g",function(){return l}),n.d(t,"d",function(){return f}),n.d(t,"c",function(){return h}),n.d(t,"b",function(){return d});var r=n(0),o=n(3),i=function(e,t,n,r){return new(n||(n=Promise))(function(o,i){function a(e){try{u(r.next(e))}catch(e){i(e)}}function s(e){try{u(r.throw(e))}catch(e){i(e)}}function u(e){e.done?o(e.value):new n(function(t){t(e.value)}).then(a,s)}u((r=r.apply(e,t||[])).next())})},a=function(e,t){var n,r,o,i,a={label:0,sent:function(){if(1&o[0])throw o[1];return o[1]},trys:[],ops:[]};return i={next:s(0),throw:s(1),return:s(2)},"function"==typeof Symbol&&(i[Symbol.iterator]=function(){return this}),i;function s(i){return function(s){return function(i){if(n)throw new TypeError("Generator is already executing.");for(;a;)try{if(n=1,r&&(o=2&i[0]?r.return:i[0]?r.throw||((o=r.return)&&o.call(r),0):r.next)&&!(o=o.call(r,i[1])).done)return o;switch(r=0,o&&(i=[2&i[0],o.value]),i[0]){case 0:case 1:o=i;break;case 4:return a.label++,{value:i[1],done:!1};case 5:a.label++,r=i[1],i=[0];continue;case 7:i=a.ops.pop(),a.trys.pop();continue;default:if(!(o=(o=a.trys).length>0&&o[o.length-1])&&(6===i[0]||2===i[0])){a=0;continue}if(3===i[0]&&(!o||i[1]>o[0]&&i[1]-1&&this.subject.observers.splice(e,1),0===this.subject.observers.length&&this.subject.cancelCallback().catch(function(e){})},e}(),d=function(){function e(e){this.minimumLogLevel=e}return e.prototype.log=function(e,t){if(e>=this.minimumLogLevel)switch(e){case r.a.Critical:case r.a.Error:console.error("["+(new Date).toISOString()+"] "+r.a[e]+": "+t);break;case r.a.Warning:console.warn("["+(new Date).toISOString()+"] "+r.a[e]+": "+t);break;case r.a.Information:console.info("["+(new Date).toISOString()+"] "+r.a[e]+": "+t);break;default:console.log("["+(new Date).toISOString()+"] "+r.a[e]+": "+t)}},e}()},function(e,t,n){"use strict";n.r(t);var r,o,i=(r=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(e,t){e.__proto__=t}||function(e,t){for(var n in t)t.hasOwnProperty(n)&&(e[n]=t[n])},function(e,t){function n(){this.constructor=e}r(e,t),e.prototype=null===t?Object.create(t):(n.prototype=t.prototype,new n)}),a=function(e){function t(t,n){var r=this,o=this.constructor.prototype;return(r=e.call(this,t)||this).statusCode=n,r.__proto__=o,r}return i(t,e),t}(Error),s=function(e){function t(t){void 0===t&&(t="A timeout occurred.");var n=this,r=this.constructor.prototype;return(n=e.call(this,t)||this).__proto__=r,n}return i(t,e),t}(Error),u=function(e){function t(t){void 0===t&&(t="An abort occurred.");var n=this,r=this.constructor.prototype;return(n=e.call(this,t)||this).__proto__=r,n}return i(t,e),t}(Error),c=Object.assign||function(e){for(var t,n=1,r=arguments.length;n=200&&o.status<300?n(new l(o.status,o.statusText,o.response||o.responseText)):r(new a(o.statusText,o.status))},o.onerror=function(){t.logger.log(h.a.Warning,"Error from HTTP request. "+o.status+": "+o.statusText+"."),r(new a(o.statusText,o.status))},o.ontimeout=function(){t.logger.log(h.a.Warning,"Timeout from HTTP request."),r(new s)},o.send(e.content||"")}):Promise.reject(new Error("No url defined.")):Promise.reject(new Error("No method defined."))},t}(f),g=function(){var e=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(e,t){e.__proto__=t}||function(e,t){for(var n in t)t.hasOwnProperty(n)&&(e[n]=t[n])};return function(t,n){function r(){this.constructor=t}e(t,n),t.prototype=null===n?Object.create(n):(r.prototype=n.prototype,new r)}}();if("undefined"==typeof XMLHttpRequest){var y=require;o=y("./NodeHttpClient")}var v,m=function(e){function t(t){var n=e.call(this)||this;if("undefined"!=typeof XMLHttpRequest)n.httpClient=new d(t);else{if(void 0===o)throw new Error("No HttpClient could be created.");n.httpClient=new o.NodeHttpClient(t)}return n}return g(t,e),t.prototype.send=function(e){return e.abortSignal&&e.abortSignal.aborted?Promise.reject(new u):e.method?e.url?this.httpClient.send(e):Promise.reject(new Error("No url defined.")):Promise.reject(new Error("No method defined."))},t.prototype.getCookieString=function(e){return this.httpClient.getCookieString(e)},t}(f),b=n(41);!function(e){e[e.Invocation=1]="Invocation",e[e.StreamItem=2]="StreamItem",e[e.Completion=3]="Completion",e[e.StreamInvocation=4]="StreamInvocation",e[e.CancelInvocation=5]="CancelInvocation",e[e.Ping=6]="Ping",e[e.Close=7]="Close"}(v||(v={}));var w,E=n(1),S=function(e,t,n,r){return new(n||(n=Promise))(function(o,i){function a(e){try{u(r.next(e))}catch(e){i(e)}}function s(e){try{u(r.throw(e))}catch(e){i(e)}}function u(e){e.done?o(e.value):new n(function(t){t(e.value)}).then(a,s)}u((r=r.apply(e,t||[])).next())})},_=function(e,t){var n,r,o,i,a={label:0,sent:function(){if(1&o[0])throw o[1];return o[1]},trys:[],ops:[]};return i={next:s(0),throw:s(1),return:s(2)},"function"==typeof Symbol&&(i[Symbol.iterator]=function(){return this}),i;function s(i){return function(s){return function(i){if(n)throw new TypeError("Generator is already executing.");for(;a;)try{if(n=1,r&&(o=2&i[0]?r.return:i[0]?r.throw||((o=r.return)&&o.call(r),0):r.next)&&!(o=o.call(r,i[1])).done)return o;switch(r=0,o&&(i=[2&i[0],o.value]),i[0]){case 0:case 1:o=i;break;case 4:return a.label++,{value:i[1],done:!1};case 5:a.label++,r=i[1],i=[0];continue;case 7:i=a.ops.pop(),a.trys.pop();continue;default:if(!(o=(o=a.trys).length>0&&o[o.length-1])&&(6===i[0]||2===i[0])){a=0;continue}if(3===i[0]&&(!o||i[1]>o[0]&&i[1]0&&o[o.length-1])&&(6===i[0]||2===i[0])){a=0;continue}if(3===i[0]&&(!o||i[1]>o[0]&&i[1]0&&o[o.length-1])&&(6===i[0]||2===i[0])){a=0;continue}if(3===i[0]&&(!o||i[1]>o[0]&&i[1]0&&o[o.length-1])&&(6===i[0]||2===i[0])){a=0;continue}if(3===i[0]&&(!o||i[1]>o[0]&&i[1]0&&o[o.length-1])&&(6===i[0]||2===i[0])){a=0;continue}if(3===i[0]&&(!o||i[1]>o[0]&&i[1]=0){if((r!==C.WebSockets||this.options.WebSocket)&&(r!==C.ServerSentEvents||this.options.EventSource))return this.logger.log(h.a.Debug,"Selecting transport '"+C[r]+"'."),r;this.logger.log(h.a.Debug,"Skipping transport '"+C[r]+"' because it is not supported in your environment.'")}else this.logger.log(h.a.Debug,"Skipping transport '"+C[r]+"' because it does not support the requested transfer format '"+I[n]+"'.");else this.logger.log(h.a.Debug,"Skipping transport '"+C[r]+"' because it was disabled by the client.")}return null},e.prototype.isITransport=function(e){return e&&"object"==typeof e&&"connect"in e},e.prototype.changeState=function(e,t){return this.connectionState===e&&(this.connectionState=t,!0)},e.prototype.stopConnection=function(e){this.transport=void 0,(e=this.stopError||e)?this.logger.log(h.a.Error,"Connection disconnected with error '"+e+"'."):this.logger.log(h.a.Information,"Connection disconnected."),this.connectionState=2,this.onclose&&this.onclose(e)},e.prototype.resolveUrl=function(e){if(0===e.lastIndexOf("https://",0)||0===e.lastIndexOf("http://",0))return e;if("undefined"==typeof window||!window||!window.document)throw new Error("Cannot resolve '"+e+"'.");var t=window.document.createElement("a");return t.href=e,this.logger.log(h.a.Information,"Normalizing '"+e+"' to '"+t.href+"'."),t.href},e.prototype.resolveNegotiateUrl=function(e){var t=e.indexOf("?"),n=e.substring(0,-1===t?e.length:t);return"/"!==n[n.length-1]&&(n+="/"),n+="negotiate",n+=-1===t?"":e.substring(t)},e}();var Y=n(3),K=n(4),J="json",X=function(){function e(){this.name=J,this.version=1,this.transferFormat=I.Text}return e.prototype.parseMessages=function(e,t){if("string"!=typeof e)throw new Error("Invalid input for JSON hub protocol. Expected a string.");if(!e)return[];null===t&&(t=Y.a.instance);for(var n=[],r=0,o=K.a.parse(e);r0&&!t)throw new Error("New logical elements must start empty, or allowExistingContents must be true");return e[r]=[],e}function s(e,t,n){var i=e;if(e instanceof Comment&&(c(i)&&c(i).length>0))throw new Error("Not implemented: inserting non-empty logical container");if(u(i))throw new Error("Not implemented: moving existing logical children");var a=c(t);if(n0;)e(r,0);var i=r;i.parentNode.removeChild(i)},t.getLogicalParent=u,t.getLogicalSiblingEnd=function(e){return e[i]||null},t.getLogicalChild=function(e,t){return c(e)[t]},t.isSvgElement=function(e){return"http://www.w3.org/2000/svg"===function(e){if(e instanceof Element)return e;if(e instanceof Comment)return e.parentNode;throw new Error("Not a valid logical element")}(e).namespaceURI},t.getLogicalChildrenArray=c,t.permuteLogicalChildren=function(e,t){var n=c(e);t.forEach(function(e){e.moveRangeStart=n[e.fromSiblingIndex],e.moveRangeEnd=function e(t){if(t instanceof Element)return t;var n=l(t);if(n)return n.previousSibling;var r=u(t);return r instanceof Element?r.lastChild:e(r)}(e.moveRangeStart)}),t.forEach(function(t){var r=t.moveToBeforeMarker=document.createComment("marker"),o=n[t.toSiblingIndex+1];o?o.parentNode.insertBefore(r,o):f(r,e)}),t.forEach(function(e){for(var t=e.moveToBeforeMarker,n=t.parentNode,r=e.moveRangeStart,o=e.moveRangeEnd,i=r;i;){var a=i.nextSibling;if(n.insertBefore(i,t),i===o)break;i=a}n.removeChild(t)}),t.forEach(function(e){n[e.toSiblingIndex]=e.moveRangeStart})}},function(e,t,n){"use strict";var r=n(18),o=Object.keys||function(e){var t=[];for(var n in e)t.push(n);return t};e.exports=f;var i=n(15);i.inherits=n(7);var a=n(33),s=n(37);i.inherits(f,a);for(var u=o(s.prototype),c=0;c0&&o[o.length-1])&&(6===i[0]||2===i[0])){a=0;continue}if(3===i[0]&&(!o||i[1]>o[0]&&i[1]-1&&this.subject.observers.splice(e,1),0===this.subject.observers.length&&this.subject.cancelCallback().catch(function(e){})},e}(),d=function(){function e(e){this.minimumLogLevel=e}return e.prototype.log=function(e,t){if(e>=this.minimumLogLevel)switch(e){case r.a.Critical:case r.a.Error:console.error("["+(new Date).toISOString()+"] "+r.a[e]+": "+t);break;case r.a.Warning:console.warn("["+(new Date).toISOString()+"] "+r.a[e]+": "+t);break;case r.a.Information:console.info("["+(new Date).toISOString()+"] "+r.a[e]+": "+t);break;default:console.log("["+(new Date).toISOString()+"] "+r.a[e]+": "+t)}},e}()},function(e,t,n){"use strict";n.r(t);var r,o,i=(r=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(e,t){e.__proto__=t}||function(e,t){for(var n in t)t.hasOwnProperty(n)&&(e[n]=t[n])},function(e,t){function n(){this.constructor=e}r(e,t),e.prototype=null===t?Object.create(t):(n.prototype=t.prototype,new n)}),a=function(e){function t(t,n){var r=this,o=this.constructor.prototype;return(r=e.call(this,t)||this).statusCode=n,r.__proto__=o,r}return i(t,e),t}(Error),s=function(e){function t(t){void 0===t&&(t="A timeout occurred.");var n=this,r=this.constructor.prototype;return(n=e.call(this,t)||this).__proto__=r,n}return i(t,e),t}(Error),u=function(e){function t(t){void 0===t&&(t="An abort occurred.");var n=this,r=this.constructor.prototype;return(n=e.call(this,t)||this).__proto__=r,n}return i(t,e),t}(Error),c=Object.assign||function(e){for(var t,n=1,r=arguments.length;n=200&&o.status<300?n(new l(o.status,o.statusText,o.response||o.responseText)):r(new a(o.statusText,o.status))},o.onerror=function(){t.logger.log(h.a.Warning,"Error from HTTP request. "+o.status+": "+o.statusText+"."),r(new a(o.statusText,o.status))},o.ontimeout=function(){t.logger.log(h.a.Warning,"Timeout from HTTP request."),r(new s)},o.send(e.content||"")}):Promise.reject(new Error("No url defined.")):Promise.reject(new Error("No method defined."))},t}(f),g=function(){var e=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(e,t){e.__proto__=t}||function(e,t){for(var n in t)t.hasOwnProperty(n)&&(e[n]=t[n])};return function(t,n){function r(){this.constructor=t}e(t,n),t.prototype=null===n?Object.create(n):(r.prototype=n.prototype,new r)}}();if("undefined"==typeof XMLHttpRequest){var y=require;o=y("./NodeHttpClient")}var v,m=function(e){function t(t){var n=e.call(this)||this;if("undefined"!=typeof XMLHttpRequest)n.httpClient=new d(t);else{if(void 0===o)throw new Error("No HttpClient could be created.");n.httpClient=new o.NodeHttpClient(t)}return n}return g(t,e),t.prototype.send=function(e){return e.abortSignal&&e.abortSignal.aborted?Promise.reject(new u):e.method?e.url?this.httpClient.send(e):Promise.reject(new Error("No url defined.")):Promise.reject(new Error("No method defined."))},t.prototype.getCookieString=function(e){return this.httpClient.getCookieString(e)},t}(f),b=n(41);!function(e){e[e.Invocation=1]="Invocation",e[e.StreamItem=2]="StreamItem",e[e.Completion=3]="Completion",e[e.StreamInvocation=4]="StreamInvocation",e[e.CancelInvocation=5]="CancelInvocation",e[e.Ping=6]="Ping",e[e.Close=7]="Close"}(v||(v={}));var w,E=n(1),S=function(e,t,n,r){return new(n||(n=Promise))(function(o,i){function a(e){try{u(r.next(e))}catch(e){i(e)}}function s(e){try{u(r.throw(e))}catch(e){i(e)}}function u(e){e.done?o(e.value):new n(function(t){t(e.value)}).then(a,s)}u((r=r.apply(e,t||[])).next())})},_=function(e,t){var n,r,o,i,a={label:0,sent:function(){if(1&o[0])throw o[1];return o[1]},trys:[],ops:[]};return i={next:s(0),throw:s(1),return:s(2)},"function"==typeof Symbol&&(i[Symbol.iterator]=function(){return this}),i;function s(i){return function(s){return function(i){if(n)throw new TypeError("Generator is already executing.");for(;a;)try{if(n=1,r&&(o=2&i[0]?r.return:i[0]?r.throw||((o=r.return)&&o.call(r),0):r.next)&&!(o=o.call(r,i[1])).done)return o;switch(r=0,o&&(i=[2&i[0],o.value]),i[0]){case 0:case 1:o=i;break;case 4:return a.label++,{value:i[1],done:!1};case 5:a.label++,r=i[1],i=[0];continue;case 7:i=a.ops.pop(),a.trys.pop();continue;default:if(!(o=(o=a.trys).length>0&&o[o.length-1])&&(6===i[0]||2===i[0])){a=0;continue}if(3===i[0]&&(!o||i[1]>o[0]&&i[1]0&&o[o.length-1])&&(6===i[0]||2===i[0])){a=0;continue}if(3===i[0]&&(!o||i[1]>o[0]&&i[1]0&&o[o.length-1])&&(6===i[0]||2===i[0])){a=0;continue}if(3===i[0]&&(!o||i[1]>o[0]&&i[1]0&&o[o.length-1])&&(6===i[0]||2===i[0])){a=0;continue}if(3===i[0]&&(!o||i[1]>o[0]&&i[1]0&&o[o.length-1])&&(6===i[0]||2===i[0])){a=0;continue}if(3===i[0]&&(!o||i[1]>o[0]&&i[1]=0){if((r!==C.WebSockets||this.options.WebSocket)&&(r!==C.ServerSentEvents||this.options.EventSource))return this.logger.log(h.a.Debug,"Selecting transport '"+C[r]+"'."),r;this.logger.log(h.a.Debug,"Skipping transport '"+C[r]+"' because it is not supported in your environment.'")}else this.logger.log(h.a.Debug,"Skipping transport '"+C[r]+"' because it does not support the requested transfer format '"+I[n]+"'.");else this.logger.log(h.a.Debug,"Skipping transport '"+C[r]+"' because it was disabled by the client.")}return null},e.prototype.isITransport=function(e){return e&&"object"==typeof e&&"connect"in e},e.prototype.changeState=function(e,t){return this.connectionState===e&&(this.connectionState=t,!0)},e.prototype.stopConnection=function(e){this.transport=void 0,(e=this.stopError||e)?this.logger.log(h.a.Error,"Connection disconnected with error '"+e+"'."):this.logger.log(h.a.Information,"Connection disconnected."),this.connectionState=2,this.onclose&&this.onclose(e)},e.prototype.resolveUrl=function(e){if(0===e.lastIndexOf("https://",0)||0===e.lastIndexOf("http://",0))return e;if("undefined"==typeof window||!window||!window.document)throw new Error("Cannot resolve '"+e+"'.");var t=window.document.createElement("a");return t.href=e,this.logger.log(h.a.Information,"Normalizing '"+e+"' to '"+t.href+"'."),t.href},e.prototype.resolveNegotiateUrl=function(e){var t=e.indexOf("?"),n=e.substring(0,-1===t?e.length:t);return"/"!==n[n.length-1]&&(n+="/"),n+="negotiate",n+=-1===t?"":e.substring(t)},e}();var Y=n(3),K=n(4),J="json",X=function(){function e(){this.name=J,this.version=1,this.transferFormat=I.Text}return e.prototype.parseMessages=function(e,t){if("string"!=typeof e)throw new Error("Invalid input for JSON hub protocol. Expected a string.");if(!e)return[];null===t&&(t=Y.a.instance);for(var n=[],r=0,o=K.a.parse(e);r0&&!t)throw new Error("New logical elements must start empty, or allowExistingContents must be true");return e[r]=[],e}function s(e,t,n){var i=e;if(e instanceof Comment&&(c(i)&&c(i).length>0))throw new Error("Not implemented: inserting non-empty logical container");if(u(i))throw new Error("Not implemented: moving existing logical children");var a=c(t);if(n0;)e(r,0);var i=r;i.parentNode.removeChild(i)},t.getLogicalParent=u,t.getLogicalSiblingEnd=function(e){return e[i]||null},t.getLogicalChild=function(e,t){return c(e)[t]},t.isSvgElement=function(e){return"http://www.w3.org/2000/svg"===l(e).namespaceURI},t.getLogicalChildrenArray=c,t.permuteLogicalChildren=function(e,t){var n=c(e);t.forEach(function(e){e.moveRangeStart=n[e.fromSiblingIndex],e.moveRangeEnd=function e(t){if(t instanceof Element)return t;var n=f(t);if(n)return n.previousSibling;var r=u(t);return r instanceof Element?r.lastChild:e(r)}(e.moveRangeStart)}),t.forEach(function(t){var r=t.moveToBeforeMarker=document.createComment("marker"),o=n[t.toSiblingIndex+1];o?o.parentNode.insertBefore(r,o):h(r,e)}),t.forEach(function(e){for(var t=e.moveToBeforeMarker,n=t.parentNode,r=e.moveRangeStart,o=e.moveRangeEnd,i=r;i;){var a=i.nextSibling;if(n.insertBefore(i,t),i===o)break;i=a}n.removeChild(t)}),t.forEach(function(e){n[e.toSiblingIndex]=e.moveRangeStart})},t.getClosestDomElement=l},function(e,t,n){"use strict";var r=n(18),o=Object.keys||function(e){var t=[];for(var n in e)t.push(n);return t};e.exports=f;var i=n(15);i.inherits=n(7);var a=n(33),s=n(37);i.inherits(f,a);for(var u=o(s.prototype),c=0;c * @license MIT */ -var r=n(47),o=n(48),i=n(31);function a(){return u.TYPED_ARRAY_SUPPORT?2147483647:1073741823}function s(e,t){if(a()=a())throw new RangeError("Attempt to allocate Buffer larger than maximum size: 0x"+a().toString(16)+" bytes");return 0|e}function d(e,t){if(u.isBuffer(e))return e.length;if("undefined"!=typeof ArrayBuffer&&"function"==typeof ArrayBuffer.isView&&(ArrayBuffer.isView(e)||e instanceof ArrayBuffer))return e.byteLength;"string"!=typeof e&&(e=""+e);var n=e.length;if(0===n)return 0;for(var r=!1;;)switch(t){case"ascii":case"latin1":case"binary":return n;case"utf8":case"utf-8":case void 0:return F(e).length;case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return 2*n;case"hex":return n>>>1;case"base64":return H(e).length;default:if(r)return F(e).length;t=(""+t).toLowerCase(),r=!0}}function g(e,t,n){var r=e[t];e[t]=e[n],e[n]=r}function y(e,t,n,r,o){if(0===e.length)return-1;if("string"==typeof n?(r=n,n=0):n>2147483647?n=2147483647:n<-2147483648&&(n=-2147483648),n=+n,isNaN(n)&&(n=o?0:e.length-1),n<0&&(n=e.length+n),n>=e.length){if(o)return-1;n=e.length-1}else if(n<0){if(!o)return-1;n=0}if("string"==typeof t&&(t=u.from(t,r)),u.isBuffer(t))return 0===t.length?-1:v(e,t,n,r,o);if("number"==typeof t)return t&=255,u.TYPED_ARRAY_SUPPORT&&"function"==typeof Uint8Array.prototype.indexOf?o?Uint8Array.prototype.indexOf.call(e,t,n):Uint8Array.prototype.lastIndexOf.call(e,t,n):v(e,[t],n,r,o);throw new TypeError("val must be string, number or Buffer")}function v(e,t,n,r,o){var i,a=1,s=e.length,u=t.length;if(void 0!==r&&("ucs2"===(r=String(r).toLowerCase())||"ucs-2"===r||"utf16le"===r||"utf-16le"===r)){if(e.length<2||t.length<2)return-1;a=2,s/=2,u/=2,n/=2}function c(e,t){return 1===a?e[t]:e.readUInt16BE(t*a)}if(o){var l=-1;for(i=n;is&&(n=s-u),i=n;i>=0;i--){for(var f=!0,h=0;ho&&(r=o):r=o;var i=t.length;if(i%2!=0)throw new TypeError("Invalid hex string");r>i/2&&(r=i/2);for(var a=0;a>8,o=n%256,i.push(o),i.push(r);return i}(t,e.length-n),e,n,r)}function T(e,t,n){return 0===t&&n===e.length?r.fromByteArray(e):r.fromByteArray(e.slice(t,n))}function k(e,t,n){n=Math.min(e.length,n);for(var r=[],o=t;o239?4:c>223?3:c>191?2:1;if(o+f<=n)switch(f){case 1:c<128&&(l=c);break;case 2:128==(192&(i=e[o+1]))&&(u=(31&c)<<6|63&i)>127&&(l=u);break;case 3:i=e[o+1],a=e[o+2],128==(192&i)&&128==(192&a)&&(u=(15&c)<<12|(63&i)<<6|63&a)>2047&&(u<55296||u>57343)&&(l=u);break;case 4:i=e[o+1],a=e[o+2],s=e[o+3],128==(192&i)&&128==(192&a)&&128==(192&s)&&(u=(15&c)<<18|(63&i)<<12|(63&a)<<6|63&s)>65535&&u<1114112&&(l=u)}null===l?(l=65533,f=1):l>65535&&(l-=65536,r.push(l>>>10&1023|55296),l=56320|1023&l),r.push(l),o+=f}return function(e){var t=e.length;if(t<=C)return String.fromCharCode.apply(String,e);var n="",r=0;for(;rthis.length)return"";if((void 0===n||n>this.length)&&(n=this.length),n<=0)return"";if((n>>>=0)<=(t>>>=0))return"";for(e||(e="utf8");;)switch(e){case"hex":return R(this,t,n);case"utf8":case"utf-8":return k(this,t,n);case"ascii":return I(this,t,n);case"latin1":case"binary":return x(this,t,n);case"base64":return T(this,t,n);case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return O(this,t,n);default:if(r)throw new TypeError("Unknown encoding: "+e);e=(e+"").toLowerCase(),r=!0}}.apply(this,arguments)},u.prototype.equals=function(e){if(!u.isBuffer(e))throw new TypeError("Argument must be a Buffer");return this===e||0===u.compare(this,e)},u.prototype.inspect=function(){var e="",n=t.INSPECT_MAX_BYTES;return this.length>0&&(e=this.toString("hex",0,n).match(/.{2}/g).join(" "),this.length>n&&(e+=" ... ")),""},u.prototype.compare=function(e,t,n,r,o){if(!u.isBuffer(e))throw new TypeError("Argument must be a Buffer");if(void 0===t&&(t=0),void 0===n&&(n=e?e.length:0),void 0===r&&(r=0),void 0===o&&(o=this.length),t<0||n>e.length||r<0||o>this.length)throw new RangeError("out of range index");if(r>=o&&t>=n)return 0;if(r>=o)return-1;if(t>=n)return 1;if(this===e)return 0;for(var i=(o>>>=0)-(r>>>=0),a=(n>>>=0)-(t>>>=0),s=Math.min(i,a),c=this.slice(r,o),l=e.slice(t,n),f=0;fo)&&(n=o),e.length>0&&(n<0||t<0)||t>this.length)throw new RangeError("Attempt to write outside buffer bounds");r||(r="utf8");for(var i=!1;;)switch(r){case"hex":return m(this,e,t,n);case"utf8":case"utf-8":return b(this,e,t,n);case"ascii":return w(this,e,t,n);case"latin1":case"binary":return E(this,e,t,n);case"base64":return S(this,e,t,n);case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return _(this,e,t,n);default:if(i)throw new TypeError("Unknown encoding: "+r);r=(""+r).toLowerCase(),i=!0}},u.prototype.toJSON=function(){return{type:"Buffer",data:Array.prototype.slice.call(this._arr||this,0)}};var C=4096;function I(e,t,n){var r="";n=Math.min(e.length,n);for(var o=t;or)&&(n=r);for(var o="",i=t;in)throw new RangeError("Trying to access beyond buffer length")}function M(e,t,n,r,o,i){if(!u.isBuffer(e))throw new TypeError('"buffer" argument must be a Buffer instance');if(t>o||te.length)throw new RangeError("Index out of range")}function L(e,t,n,r){t<0&&(t=65535+t+1);for(var o=0,i=Math.min(e.length-n,2);o>>8*(r?o:1-o)}function A(e,t,n,r){t<0&&(t=4294967295+t+1);for(var o=0,i=Math.min(e.length-n,4);o>>8*(r?o:3-o)&255}function B(e,t,n,r,o,i){if(n+r>e.length)throw new RangeError("Index out of range");if(n<0)throw new RangeError("Index out of range")}function D(e,t,n,r,i){return i||B(e,0,n,4),o.write(e,t,n,r,23,4),n+4}function U(e,t,n,r,i){return i||B(e,0,n,8),o.write(e,t,n,r,52,8),n+8}u.prototype.slice=function(e,t){var n,r=this.length;if((e=~~e)<0?(e+=r)<0&&(e=0):e>r&&(e=r),(t=void 0===t?r:~~t)<0?(t+=r)<0&&(t=0):t>r&&(t=r),t0&&(o*=256);)r+=this[e+--t]*o;return r},u.prototype.readUInt8=function(e,t){return t||P(e,1,this.length),this[e]},u.prototype.readUInt16LE=function(e,t){return t||P(e,2,this.length),this[e]|this[e+1]<<8},u.prototype.readUInt16BE=function(e,t){return t||P(e,2,this.length),this[e]<<8|this[e+1]},u.prototype.readUInt32LE=function(e,t){return t||P(e,4,this.length),(this[e]|this[e+1]<<8|this[e+2]<<16)+16777216*this[e+3]},u.prototype.readUInt32BE=function(e,t){return t||P(e,4,this.length),16777216*this[e]+(this[e+1]<<16|this[e+2]<<8|this[e+3])},u.prototype.readIntLE=function(e,t,n){e|=0,t|=0,n||P(e,t,this.length);for(var r=this[e],o=1,i=0;++i=(o*=128)&&(r-=Math.pow(2,8*t)),r},u.prototype.readIntBE=function(e,t,n){e|=0,t|=0,n||P(e,t,this.length);for(var r=t,o=1,i=this[e+--r];r>0&&(o*=256);)i+=this[e+--r]*o;return i>=(o*=128)&&(i-=Math.pow(2,8*t)),i},u.prototype.readInt8=function(e,t){return t||P(e,1,this.length),128&this[e]?-1*(255-this[e]+1):this[e]},u.prototype.readInt16LE=function(e,t){t||P(e,2,this.length);var n=this[e]|this[e+1]<<8;return 32768&n?4294901760|n:n},u.prototype.readInt16BE=function(e,t){t||P(e,2,this.length);var n=this[e+1]|this[e]<<8;return 32768&n?4294901760|n:n},u.prototype.readInt32LE=function(e,t){return t||P(e,4,this.length),this[e]|this[e+1]<<8|this[e+2]<<16|this[e+3]<<24},u.prototype.readInt32BE=function(e,t){return t||P(e,4,this.length),this[e]<<24|this[e+1]<<16|this[e+2]<<8|this[e+3]},u.prototype.readFloatLE=function(e,t){return t||P(e,4,this.length),o.read(this,e,!0,23,4)},u.prototype.readFloatBE=function(e,t){return t||P(e,4,this.length),o.read(this,e,!1,23,4)},u.prototype.readDoubleLE=function(e,t){return t||P(e,8,this.length),o.read(this,e,!0,52,8)},u.prototype.readDoubleBE=function(e,t){return t||P(e,8,this.length),o.read(this,e,!1,52,8)},u.prototype.writeUIntLE=function(e,t,n,r){(e=+e,t|=0,n|=0,r)||M(this,e,t,n,Math.pow(2,8*n)-1,0);var o=1,i=0;for(this[t]=255&e;++i=0&&(i*=256);)this[t+o]=e/i&255;return t+n},u.prototype.writeUInt8=function(e,t,n){return e=+e,t|=0,n||M(this,e,t,1,255,0),u.TYPED_ARRAY_SUPPORT||(e=Math.floor(e)),this[t]=255&e,t+1},u.prototype.writeUInt16LE=function(e,t,n){return e=+e,t|=0,n||M(this,e,t,2,65535,0),u.TYPED_ARRAY_SUPPORT?(this[t]=255&e,this[t+1]=e>>>8):L(this,e,t,!0),t+2},u.prototype.writeUInt16BE=function(e,t,n){return e=+e,t|=0,n||M(this,e,t,2,65535,0),u.TYPED_ARRAY_SUPPORT?(this[t]=e>>>8,this[t+1]=255&e):L(this,e,t,!1),t+2},u.prototype.writeUInt32LE=function(e,t,n){return e=+e,t|=0,n||M(this,e,t,4,4294967295,0),u.TYPED_ARRAY_SUPPORT?(this[t+3]=e>>>24,this[t+2]=e>>>16,this[t+1]=e>>>8,this[t]=255&e):A(this,e,t,!0),t+4},u.prototype.writeUInt32BE=function(e,t,n){return e=+e,t|=0,n||M(this,e,t,4,4294967295,0),u.TYPED_ARRAY_SUPPORT?(this[t]=e>>>24,this[t+1]=e>>>16,this[t+2]=e>>>8,this[t+3]=255&e):A(this,e,t,!1),t+4},u.prototype.writeIntLE=function(e,t,n,r){if(e=+e,t|=0,!r){var o=Math.pow(2,8*n-1);M(this,e,t,n,o-1,-o)}var i=0,a=1,s=0;for(this[t]=255&e;++i>0)-s&255;return t+n},u.prototype.writeIntBE=function(e,t,n,r){if(e=+e,t|=0,!r){var o=Math.pow(2,8*n-1);M(this,e,t,n,o-1,-o)}var i=n-1,a=1,s=0;for(this[t+i]=255&e;--i>=0&&(a*=256);)e<0&&0===s&&0!==this[t+i+1]&&(s=1),this[t+i]=(e/a>>0)-s&255;return t+n},u.prototype.writeInt8=function(e,t,n){return e=+e,t|=0,n||M(this,e,t,1,127,-128),u.TYPED_ARRAY_SUPPORT||(e=Math.floor(e)),e<0&&(e=255+e+1),this[t]=255&e,t+1},u.prototype.writeInt16LE=function(e,t,n){return e=+e,t|=0,n||M(this,e,t,2,32767,-32768),u.TYPED_ARRAY_SUPPORT?(this[t]=255&e,this[t+1]=e>>>8):L(this,e,t,!0),t+2},u.prototype.writeInt16BE=function(e,t,n){return e=+e,t|=0,n||M(this,e,t,2,32767,-32768),u.TYPED_ARRAY_SUPPORT?(this[t]=e>>>8,this[t+1]=255&e):L(this,e,t,!1),t+2},u.prototype.writeInt32LE=function(e,t,n){return e=+e,t|=0,n||M(this,e,t,4,2147483647,-2147483648),u.TYPED_ARRAY_SUPPORT?(this[t]=255&e,this[t+1]=e>>>8,this[t+2]=e>>>16,this[t+3]=e>>>24):A(this,e,t,!0),t+4},u.prototype.writeInt32BE=function(e,t,n){return e=+e,t|=0,n||M(this,e,t,4,2147483647,-2147483648),e<0&&(e=4294967295+e+1),u.TYPED_ARRAY_SUPPORT?(this[t]=e>>>24,this[t+1]=e>>>16,this[t+2]=e>>>8,this[t+3]=255&e):A(this,e,t,!1),t+4},u.prototype.writeFloatLE=function(e,t,n){return D(this,e,t,!0,n)},u.prototype.writeFloatBE=function(e,t,n){return D(this,e,t,!1,n)},u.prototype.writeDoubleLE=function(e,t,n){return U(this,e,t,!0,n)},u.prototype.writeDoubleBE=function(e,t,n){return U(this,e,t,!1,n)},u.prototype.copy=function(e,t,n,r){if(n||(n=0),r||0===r||(r=this.length),t>=e.length&&(t=e.length),t||(t=0),r>0&&r=this.length)throw new RangeError("sourceStart out of bounds");if(r<0)throw new RangeError("sourceEnd out of bounds");r>this.length&&(r=this.length),e.length-t=0;--o)e[o+t]=this[o+n];else if(i<1e3||!u.TYPED_ARRAY_SUPPORT)for(o=0;o>>=0,n=void 0===n?this.length:n>>>0,e||(e=0),"number"==typeof e)for(i=t;i55295&&n<57344){if(!o){if(n>56319){(t-=3)>-1&&i.push(239,191,189);continue}if(a+1===r){(t-=3)>-1&&i.push(239,191,189);continue}o=n;continue}if(n<56320){(t-=3)>-1&&i.push(239,191,189),o=n;continue}n=65536+(o-55296<<10|n-56320)}else o&&(t-=3)>-1&&i.push(239,191,189);if(o=null,n<128){if((t-=1)<0)break;i.push(n)}else if(n<2048){if((t-=2)<0)break;i.push(n>>6|192,63&n|128)}else if(n<65536){if((t-=3)<0)break;i.push(n>>12|224,n>>6&63|128,63&n|128)}else{if(!(n<1114112))throw new Error("Invalid code point");if((t-=4)<0)break;i.push(n>>18|240,n>>12&63|128,n>>6&63|128,63&n|128)}}return i}function H(e){return r.toByteArray(function(e){if((e=function(e){return e.trim?e.trim():e.replace(/^\s+|\s+$/g,"")}(e).replace(N,"")).length<2)return"";for(;e.length%4!=0;)e+="=";return e}(e))}function q(e,t,n,r){for(var o=0;o=t.length||o>=e.length);++o)t[o+n]=e[o];return o}}).call(this,n(5))},function(e,t,n){"use strict";var r;!function(e){window.DotNet=e;var t=[],n={},r={},o=1,i=null;function a(e){t.push(e)}function s(e,t){for(var n=[],r=2;r1)for(var n=1;n0&&o[o.length-1])&&(6===i[0]||2===i[0])){a=0;continue}if(3===i[0]&&(!o||i[1]>o[0]&&i[1]this.length||e<0)){var t=this._offset(e);return this._bufs[t[0]][t[1]]}},a.prototype.slice=function(e,t){return"number"==typeof e&&e<0&&(e+=this.length),"number"==typeof t&&t<0&&(t+=this.length),this.copy(null,0,e,t)},a.prototype.copy=function(e,t,n,r){if(("number"!=typeof n||n<0)&&(n=0),("number"!=typeof r||r>this.length)&&(r=this.length),n>=this.length)return e||i.alloc(0);if(r<=0)return e||i.alloc(0);var o,a,s=!!e,u=this._offset(n),c=r-n,l=c,f=s&&t||0,h=u[1];if(0===n&&r==this.length){if(!s)return 1===this._bufs.length?this._bufs[0]:i.concat(this._bufs,this.length);for(a=0;a(o=this._bufs[a].length-h))){this._bufs[a].copy(e,f,h,h+l);break}this._bufs[a].copy(e,f,h),f+=o,l-=o,h&&(h=0)}return e},a.prototype.shallowSlice=function(e,t){if(e=e||0,t="number"!=typeof t?this.length:t,e<0&&(e+=this.length),t<0&&(t+=this.length),e===t)return new a;var n=this._offset(e),r=this._offset(t),o=this._bufs.slice(n[0],r[0]+1);return 0==r[1]?o.pop():o[o.length-1]=o[o.length-1].slice(0,r[1]),0!=n[1]&&(o[0]=o[0].slice(n[1])),new a(o)},a.prototype.toString=function(e,t,n){return this.slice(t,n).toString(e)},a.prototype.consume=function(e){for(;this._bufs.length;){if(!(e>=this._bufs[0].length)){this._bufs[0]=this._bufs[0].slice(e),this.length-=e;break}e-=this._bufs[0].length,this.length-=this._bufs[0].length,this._bufs.shift()}return this},a.prototype.duplicate=function(){for(var e=0,t=new a;ethis.length?this.length:t;for(var r=this._offset(t),o=r[0],s=r[1];o=e.length){var c=u.indexOf(e,s);if(-1!==c)return this._reverseOffset([o,c]);s=u.length-e.length+1}else{var l=this._reverseOffset([o,s]);if(this._match(l,e))return l;s++}}s=0}return-1},a.prototype._match=function(e,t){if(this.length-e=0,"must have a non-negative type"),o(a,"must have a decode function"),this.registerEncoder(function(e){return e instanceof t},function(t){var o=i(),a=r.allocUnsafe(1);return a.writeInt8(e,0),o.append(a),o.append(n(t)),o}),this.registerDecoder(e,a),this},registerEncoder:function(e,n){return o(e,"must have an encode function"),o(n,"must have an encode function"),t.push({check:e,encode:n}),this},registerDecoder:function(e,t){return o(e>=0,"must have a non-negative type"),o(t,"must have a decode function"),n.push({type:e,decode:t}),this},encoder:a.encoder,decoder:a.decoder,buffer:!0,type:"msgpack5",IncompleteBufferError:s.IncompleteBufferError}}},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var r=n(16),o=n(22),i=n(8);window.Blazor={navigateTo:r.navigateTo,_internal:{attachRootComponentToElement:i.attachRootComponentToElement,http:o.internalFunctions,uriHelper:r.internalFunctions}}},function(e,t,n){"use strict";var r=this&&this.__awaiter||function(e,t,n,r){return new(n||(n=Promise))(function(o,i){function a(e){try{u(r.next(e))}catch(e){i(e)}}function s(e){try{u(r.throw(e))}catch(e){i(e)}}function u(e){e.done?o(e.value):new n(function(t){t(e.value)}).then(a,s)}u((r=r.apply(e,t||[])).next())})},o=this&&this.__generator||function(e,t){var n,r,o,i,a={label:0,sent:function(){if(1&o[0])throw o[1];return o[1]},trys:[],ops:[]};return i={next:s(0),throw:s(1),return:s(2)},"function"==typeof Symbol&&(i[Symbol.iterator]=function(){return this}),i;function s(i){return function(s){return function(i){if(n)throw new TypeError("Generator is already executing.");for(;a;)try{if(n=1,r&&(o=2&i[0]?r.return:i[0]?r.throw||((o=r.return)&&o.call(r),0):r.next)&&!(o=o.call(r,i[1])).done)return o;switch(r=0,o&&(i=[2&i[0],o.value]),i[0]){case 0:case 1:o=i;break;case 4:return a.label++,{value:i[1],done:!1};case 5:a.label++,r=i[1],i=[0];continue;case 7:i=a.ops.pop(),a.trys.pop();continue;default:if(!(o=(o=a.trys).length>0&&o[o.length-1])&&(6===i[0]||2===i[0])){a=0;continue}if(3===i[0]&&(!o||i[1]>o[0]&&i[1]0&&o[o.length-1])&&(6===i[0]||2===i[0])){a=0;continue}if(3===i[0]&&(!o||i[1]>o[0]&&i[1]=i)return e;switch(e){case"%s":return String(r[n++]);case"%d":return Number(r[n++]);case"%j":try{return JSON.stringify(r[n++])}catch(e){return"[Circular]"}default:return e}}),u=r[n];n=3&&(r.depth=arguments[2]),arguments.length>=4&&(r.colors=arguments[3]),d(n)?r.showHidden=n:n&&t._extend(r,n),m(r.showHidden)&&(r.showHidden=!1),m(r.depth)&&(r.depth=2),m(r.colors)&&(r.colors=!1),m(r.customInspect)&&(r.customInspect=!0),r.colors&&(r.stylize=u),l(r,e,r.depth)}function u(e,t){var n=s.styles[t];return n?"["+s.colors[n][0]+"m"+e+"["+s.colors[n][1]+"m":e}function c(e,t){return e}function l(e,n,r){if(e.customInspect&&n&&_(n.inspect)&&n.inspect!==t.inspect&&(!n.constructor||n.constructor.prototype!==n)){var o=n.inspect(r,e);return v(o)||(o=l(e,o,r)),o}var i=function(e,t){if(m(t))return e.stylize("undefined","undefined");if(v(t)){var n="'"+JSON.stringify(t).replace(/^"|"$/g,"").replace(/'/g,"\\'").replace(/\\"/g,'"')+"'";return e.stylize(n,"string")}if(y(t))return e.stylize(""+t,"number");if(d(t))return e.stylize(""+t,"boolean");if(g(t))return e.stylize("null","null")}(e,n);if(i)return i;var a=Object.keys(n),s=function(e){var t={};return e.forEach(function(e,n){t[e]=!0}),t}(a);if(e.showHidden&&(a=Object.getOwnPropertyNames(n)),S(n)&&(a.indexOf("message")>=0||a.indexOf("description")>=0))return f(n);if(0===a.length){if(_(n)){var u=n.name?": "+n.name:"";return e.stylize("[Function"+u+"]","special")}if(b(n))return e.stylize(RegExp.prototype.toString.call(n),"regexp");if(E(n))return e.stylize(Date.prototype.toString.call(n),"date");if(S(n))return f(n)}var c,w="",T=!1,k=["{","}"];(p(n)&&(T=!0,k=["[","]"]),_(n))&&(w=" [Function"+(n.name?": "+n.name:"")+"]");return b(n)&&(w=" "+RegExp.prototype.toString.call(n)),E(n)&&(w=" "+Date.prototype.toUTCString.call(n)),S(n)&&(w=" "+f(n)),0!==a.length||T&&0!=n.length?r<0?b(n)?e.stylize(RegExp.prototype.toString.call(n),"regexp"):e.stylize("[Object]","special"):(e.seen.push(n),c=T?function(e,t,n,r,o){for(var i=[],a=0,s=t.length;a=0&&0,e+t.replace(/\u001b\[\d\d?m/g,"").length+1},0)>60)return n[0]+(""===t?"":t+"\n ")+" "+e.join(",\n ")+" "+n[1];return n[0]+t+" "+e.join(", ")+" "+n[1]}(c,w,k)):k[0]+w+k[1]}function f(e){return"["+Error.prototype.toString.call(e)+"]"}function h(e,t,n,r,o,i){var a,s,u;if((u=Object.getOwnPropertyDescriptor(t,o)||{value:t[o]}).get?s=u.set?e.stylize("[Getter/Setter]","special"):e.stylize("[Getter]","special"):u.set&&(s=e.stylize("[Setter]","special")),I(r,o)||(a="["+o+"]"),s||(e.seen.indexOf(u.value)<0?(s=g(n)?l(e,u.value,null):l(e,u.value,n-1)).indexOf("\n")>-1&&(s=i?s.split("\n").map(function(e){return" "+e}).join("\n").substr(2):"\n"+s.split("\n").map(function(e){return" "+e}).join("\n")):s=e.stylize("[Circular]","special")),m(a)){if(i&&o.match(/^\d+$/))return s;(a=JSON.stringify(""+o)).match(/^"([a-zA-Z_][a-zA-Z_0-9]*)"$/)?(a=a.substr(1,a.length-2),a=e.stylize(a,"name")):(a=a.replace(/'/g,"\\'").replace(/\\"/g,'"').replace(/(^"|"$)/g,"'"),a=e.stylize(a,"string"))}return a+": "+s}function p(e){return Array.isArray(e)}function d(e){return"boolean"==typeof e}function g(e){return null===e}function y(e){return"number"==typeof e}function v(e){return"string"==typeof e}function m(e){return void 0===e}function b(e){return w(e)&&"[object RegExp]"===T(e)}function w(e){return"object"==typeof e&&null!==e}function E(e){return w(e)&&"[object Date]"===T(e)}function S(e){return w(e)&&("[object Error]"===T(e)||e instanceof Error)}function _(e){return"function"==typeof e}function T(e){return Object.prototype.toString.call(e)}function k(e){return e<10?"0"+e.toString(10):e.toString(10)}t.debuglog=function(n){if(m(i)&&(i=e.env.NODE_DEBUG||""),n=n.toUpperCase(),!a[n])if(new RegExp("\\b"+n+"\\b","i").test(i)){var r=e.pid;a[n]=function(){var e=t.format.apply(t,arguments);console.error("%s %d: %s",n,r,e)}}else a[n]=function(){};return a[n]},t.inspect=s,s.colors={bold:[1,22],italic:[3,23],underline:[4,24],inverse:[7,27],white:[37,39],grey:[90,39],black:[30,39],blue:[34,39],cyan:[36,39],green:[32,39],magenta:[35,39],red:[31,39],yellow:[33,39]},s.styles={special:"cyan",number:"yellow",boolean:"yellow",undefined:"grey",null:"bold",string:"green",date:"magenta",regexp:"red"},t.isArray=p,t.isBoolean=d,t.isNull=g,t.isNullOrUndefined=function(e){return null==e},t.isNumber=y,t.isString=v,t.isSymbol=function(e){return"symbol"==typeof e},t.isUndefined=m,t.isRegExp=b,t.isObject=w,t.isDate=E,t.isError=S,t.isFunction=_,t.isPrimitive=function(e){return null===e||"boolean"==typeof e||"number"==typeof e||"string"==typeof e||"symbol"==typeof e||void 0===e},t.isBuffer=n(50);var C=["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"];function I(e,t){return Object.prototype.hasOwnProperty.call(e,t)}t.log=function(){var e,n;console.log("%s - %s",(e=new Date,n=[k(e.getHours()),k(e.getMinutes()),k(e.getSeconds())].join(":"),[e.getDate(),C[e.getMonth()],n].join(" ")),t.format.apply(t,arguments))},t.inherits=n(7),t._extend=function(e,t){if(!t||!w(t))return e;for(var n=Object.keys(t),r=n.length;r--;)e[n[r]]=t[n[r]];return e};var x="undefined"!=typeof Symbol?Symbol("util.promisify.custom"):void 0;function R(e,t){if(!e){var n=new Error("Promise was rejected with a falsy value");n.reason=e,e=n}return t(e)}t.promisify=function(e){if("function"!=typeof e)throw new TypeError('The "original" argument must be of type Function');if(x&&e[x]){var t;if("function"!=typeof(t=e[x]))throw new TypeError('The "util.promisify.custom" argument must be of type Function');return Object.defineProperty(t,x,{value:t,enumerable:!1,writable:!1,configurable:!0}),t}function t(){for(var t,n,r=new Promise(function(e,r){t=e,n=r}),o=[],i=0;i0?("string"==typeof t||a.objectMode||Object.getPrototypeOf(t)===c.prototype||(t=function(e){return c.from(e)}(t)),r?a.endEmitted?e.emit("error",new Error("stream.unshift() after end event")):E(e,a,t,!0):a.ended?e.emit("error",new Error("stream.push() after EOF")):(a.reading=!1,a.decoder&&!n?(t=a.decoder.write(t),a.objectMode||0!==t.length?E(e,a,t,!1):C(e,a)):E(e,a,t,!1))):r||(a.reading=!1));return function(e){return!e.ended&&(e.needReadable||e.lengtht.highWaterMark&&(t.highWaterMark=function(e){return e>=S?e=S:(e--,e|=e>>>1,e|=e>>>2,e|=e>>>4,e|=e>>>8,e|=e>>>16,e++),e}(e)),e<=t.length?e:t.ended?t.length:(t.needReadable=!0,0))}function T(e){var t=e._readableState;t.needReadable=!1,t.emittedReadable||(p("emitReadable",t.flowing),t.emittedReadable=!0,t.sync?o.nextTick(k,e):k(e))}function k(e){p("emit readable"),e.emit("readable"),O(e)}function C(e,t){t.readingMore||(t.readingMore=!0,o.nextTick(I,e,t))}function I(e,t){for(var n=t.length;!t.reading&&!t.flowing&&!t.ended&&t.length=t.length?(n=t.decoder?t.buffer.join(""):1===t.buffer.length?t.buffer.head.data:t.buffer.concat(t.length),t.buffer.clear()):n=function(e,t,n){var r;ei.length?i.length:e;if(a===i.length?o+=i:o+=i.slice(0,e),0===(e-=a)){a===i.length?(++r,n.next?t.head=n.next:t.head=t.tail=null):(t.head=n,n.data=i.slice(a));break}++r}return t.length-=r,o}(e,t):function(e,t){var n=c.allocUnsafe(e),r=t.head,o=1;r.data.copy(n),e-=r.data.length;for(;r=r.next;){var i=r.data,a=e>i.length?i.length:e;if(i.copy(n,n.length-e,0,a),0===(e-=a)){a===i.length?(++o,r.next?t.head=r.next:t.head=t.tail=null):(t.head=r,r.data=i.slice(a));break}++o}return t.length-=o,n}(e,t);return r}(e,t.buffer,t.decoder),n);var n}function M(e){var t=e._readableState;if(t.length>0)throw new Error('"endReadable()" called on non-empty stream');t.endEmitted||(t.ended=!0,o.nextTick(L,t,e))}function L(e,t){e.endEmitted||0!==e.length||(e.endEmitted=!0,t.readable=!1,t.emit("end"))}function A(e,t){for(var n=0,r=e.length;n=t.highWaterMark||t.ended))return p("read: emitReadable",t.length,t.ended),0===t.length&&t.ended?M(this):T(this),null;if(0===(e=_(e,t))&&t.ended)return 0===t.length&&M(this),null;var r,o=t.needReadable;return p("need readable",o),(0===t.length||t.length-e0?P(e,t):null)?(t.needReadable=!0,e=0):t.length-=e,0===t.length&&(t.ended||(t.needReadable=!0),n!==e&&t.ended&&M(this)),null!==r&&this.emit("data",r),r},b.prototype._read=function(e){this.emit("error",new Error("_read() is not implemented"))},b.prototype.pipe=function(e,t){var n=this,i=this._readableState;switch(i.pipesCount){case 0:i.pipes=e;break;case 1:i.pipes=[i.pipes,e];break;default:i.pipes.push(e)}i.pipesCount+=1,p("pipe count=%d opts=%j",i.pipesCount,t);var u=(!t||!1!==t.end)&&e!==r.stdout&&e!==r.stderr?l:b;function c(t,r){p("onunpipe"),t===n&&r&&!1===r.hasUnpiped&&(r.hasUnpiped=!0,p("cleanup"),e.removeListener("close",v),e.removeListener("finish",m),e.removeListener("drain",f),e.removeListener("error",y),e.removeListener("unpipe",c),n.removeListener("end",l),n.removeListener("end",b),n.removeListener("data",g),h=!0,!i.awaitDrain||e._writableState&&!e._writableState.needDrain||f())}function l(){p("onend"),e.end()}i.endEmitted?o.nextTick(u):n.once("end",u),e.on("unpipe",c);var f=function(e){return function(){var t=e._readableState;p("pipeOnDrain",t.awaitDrain),t.awaitDrain&&t.awaitDrain--,0===t.awaitDrain&&s(e,"data")&&(t.flowing=!0,O(e))}}(n);e.on("drain",f);var h=!1;var d=!1;function g(t){p("ondata"),d=!1,!1!==e.write(t)||d||((1===i.pipesCount&&i.pipes===e||i.pipesCount>1&&-1!==A(i.pipes,e))&&!h&&(p("false write response, pause",n._readableState.awaitDrain),n._readableState.awaitDrain++,d=!0),n.pause())}function y(t){p("onerror",t),b(),e.removeListener("error",y),0===s(e,"error")&&e.emit("error",t)}function v(){e.removeListener("finish",m),b()}function m(){p("onfinish"),e.removeListener("close",v),b()}function b(){p("unpipe"),n.unpipe(e)}return n.on("data",g),function(e,t,n){if("function"==typeof e.prependListener)return e.prependListener(t,n);e._events&&e._events[t]?a(e._events[t])?e._events[t].unshift(n):e._events[t]=[n,e._events[t]]:e.on(t,n)}(e,"error",y),e.once("close",v),e.once("finish",m),e.emit("pipe",n),i.flowing||(p("pipe resume"),n.resume()),e},b.prototype.unpipe=function(e){var t=this._readableState,n={hasUnpiped:!1};if(0===t.pipesCount)return this;if(1===t.pipesCount)return e&&e!==t.pipes?this:(e||(e=t.pipes),t.pipes=null,t.pipesCount=0,t.flowing=!1,e&&e.emit("unpipe",this,n),this);if(!e){var r=t.pipes,o=t.pipesCount;t.pipes=null,t.pipesCount=0,t.flowing=!1;for(var i=0;i0&&a.length>o&&!a.warned){a.warned=!0;var u=new Error("Possible EventEmitter memory leak detected. "+a.length+" "+String(t)+" listeners added. Use emitter.setMaxListeners() to increase limit");u.name="MaxListenersExceededWarning",u.emitter=e,u.type=t,u.count=a.length,s=u,console&&console.warn&&console.warn(s)}return e}function f(e,t,n){var r={fired:!1,wrapFn:void 0,target:e,type:t,listener:n},o=function(){for(var e=[],t=0;t0&&(a=t[0]),a instanceof Error)throw a;var s=new Error("Unhandled error."+(a?" ("+a.message+")":""));throw s.context=a,s}var u=o[e];if(void 0===u)return!1;if("function"==typeof u)i(u,this,t);else{var c=u.length,l=d(u,c);for(n=0;n=0;i--)if(n[i]===t||n[i].listener===t){a=n[i].listener,o=i;break}if(o<0)return this;0===o?n.shift():function(e,t){for(;t+1=0;r--)this.removeListener(e,t[r]);return this},s.prototype.listeners=function(e){return h(this,e,!0)},s.prototype.rawListeners=function(e){return h(this,e,!1)},s.listenerCount=function(e,t){return"function"==typeof e.listenerCount?e.listenerCount(t):p.call(e,t)},s.prototype.listenerCount=p,s.prototype.eventNames=function(){return this._eventsCount>0?r(this._events):[]}},function(e,t,n){e.exports=n(34).EventEmitter},function(e,t,n){"use strict";var r=n(18);function o(e,t){e.emit("error",t)}e.exports={destroy:function(e,t){var n=this,i=this._readableState&&this._readableState.destroyed,a=this._writableState&&this._writableState.destroyed;return i||a?(t?t(e):!e||this._writableState&&this._writableState.errorEmitted||r.nextTick(o,this,e),this):(this._readableState&&(this._readableState.destroyed=!0),this._writableState&&(this._writableState.destroyed=!0),this._destroy(e||null,function(e){!t&&e?(r.nextTick(o,n,e),n._writableState&&(n._writableState.errorEmitted=!0)):t&&t(e)}),this)},undestroy:function(){this._readableState&&(this._readableState.destroyed=!1,this._readableState.reading=!1,this._readableState.ended=!1,this._readableState.endEmitted=!1),this._writableState&&(this._writableState.destroyed=!1,this._writableState.ended=!1,this._writableState.ending=!1,this._writableState.finished=!1,this._writableState.errorEmitted=!1)}}},function(e,t,n){"use strict";(function(t,r,o){var i=n(18);function a(e){var t=this;this.next=null,this.entry=null,this.finish=function(){!function(e,t,n){var r=e.entry;e.entry=null;for(;r;){var o=r.callback;t.pendingcb--,o(n),r=r.next}t.corkedRequestsFree?t.corkedRequestsFree.next=e:t.corkedRequestsFree=e}(t,e)}}e.exports=m;var s,u=!t.browser&&["v0.10","v0.9."].indexOf(t.version.slice(0,5))>-1?r:i.nextTick;m.WritableState=v;var c=n(15);c.inherits=n(7);var l={deprecate:n(56)},f=n(35),h=n(6).Buffer,p=o.Uint8Array||function(){};var d,g=n(36);function y(){}function v(e,t){s=s||n(10),e=e||{};var r=t instanceof s;this.objectMode=!!e.objectMode,r&&(this.objectMode=this.objectMode||!!e.writableObjectMode);var o=e.highWaterMark,c=e.writableHighWaterMark,l=this.objectMode?16:16384;this.highWaterMark=o||0===o?o:r&&(c||0===c)?c:l,this.highWaterMark=Math.floor(this.highWaterMark),this.finalCalled=!1,this.needDrain=!1,this.ending=!1,this.ended=!1,this.finished=!1,this.destroyed=!1;var f=!1===e.decodeStrings;this.decodeStrings=!f,this.defaultEncoding=e.defaultEncoding||"utf8",this.length=0,this.writing=!1,this.corked=0,this.sync=!0,this.bufferProcessing=!1,this.onwrite=function(e){!function(e,t){var n=e._writableState,r=n.sync,o=n.writecb;if(function(e){e.writing=!1,e.writecb=null,e.length-=e.writelen,e.writelen=0}(n),t)!function(e,t,n,r,o){--t.pendingcb,n?(i.nextTick(o,r),i.nextTick(T,e,t),e._writableState.errorEmitted=!0,e.emit("error",r)):(o(r),e._writableState.errorEmitted=!0,e.emit("error",r),T(e,t))}(e,n,r,t,o);else{var a=S(n);a||n.corked||n.bufferProcessing||!n.bufferedRequest||E(e,n),r?u(w,e,n,a,o):w(e,n,a,o)}}(t,e)},this.writecb=null,this.writelen=0,this.bufferedRequest=null,this.lastBufferedRequest=null,this.pendingcb=0,this.prefinished=!1,this.errorEmitted=!1,this.bufferedRequestCount=0,this.corkedRequestsFree=new a(this)}function m(e){if(s=s||n(10),!(d.call(m,this)||this instanceof s))return new m(e);this._writableState=new v(e,this),this.writable=!0,e&&("function"==typeof e.write&&(this._write=e.write),"function"==typeof e.writev&&(this._writev=e.writev),"function"==typeof e.destroy&&(this._destroy=e.destroy),"function"==typeof e.final&&(this._final=e.final)),f.call(this)}function b(e,t,n,r,o,i,a){t.writelen=r,t.writecb=a,t.writing=!0,t.sync=!0,n?e._writev(o,t.onwrite):e._write(o,i,t.onwrite),t.sync=!1}function w(e,t,n,r){n||function(e,t){0===t.length&&t.needDrain&&(t.needDrain=!1,e.emit("drain"))}(e,t),t.pendingcb--,r(),T(e,t)}function E(e,t){t.bufferProcessing=!0;var n=t.bufferedRequest;if(e._writev&&n&&n.next){var r=t.bufferedRequestCount,o=new Array(r),i=t.corkedRequestsFree;i.entry=n;for(var s=0,u=!0;n;)o[s]=n,n.isBuf||(u=!1),n=n.next,s+=1;o.allBuffers=u,b(e,t,!0,t.length,o,"",i.finish),t.pendingcb++,t.lastBufferedRequest=null,i.next?(t.corkedRequestsFree=i.next,i.next=null):t.corkedRequestsFree=new a(t),t.bufferedRequestCount=0}else{for(;n;){var c=n.chunk,l=n.encoding,f=n.callback;if(b(e,t,!1,t.objectMode?1:c.length,c,l,f),n=n.next,t.bufferedRequestCount--,t.writing)break}null===n&&(t.lastBufferedRequest=null)}t.bufferedRequest=n,t.bufferProcessing=!1}function S(e){return e.ending&&0===e.length&&null===e.bufferedRequest&&!e.finished&&!e.writing}function _(e,t){e._final(function(n){t.pendingcb--,n&&e.emit("error",n),t.prefinished=!0,e.emit("prefinish"),T(e,t)})}function T(e,t){var n=S(t);return n&&(!function(e,t){t.prefinished||t.finalCalled||("function"==typeof e._final?(t.pendingcb++,t.finalCalled=!0,i.nextTick(_,e,t)):(t.prefinished=!0,e.emit("prefinish")))}(e,t),0===t.pendingcb&&(t.finished=!0,e.emit("finish"))),n}c.inherits(m,f),v.prototype.getBuffer=function(){for(var e=this.bufferedRequest,t=[];e;)t.push(e),e=e.next;return t},function(){try{Object.defineProperty(v.prototype,"buffer",{get:l.deprecate(function(){return this.getBuffer()},"_writableState.buffer is deprecated. Use _writableState.getBuffer instead.","DEP0003")})}catch(e){}}(),"function"==typeof Symbol&&Symbol.hasInstance&&"function"==typeof Function.prototype[Symbol.hasInstance]?(d=Function.prototype[Symbol.hasInstance],Object.defineProperty(m,Symbol.hasInstance,{value:function(e){return!!d.call(this,e)||this===m&&(e&&e._writableState instanceof v)}})):d=function(e){return e instanceof this},m.prototype.pipe=function(){this.emit("error",new Error("Cannot pipe, not readable"))},m.prototype.write=function(e,t,n){var r,o=this._writableState,a=!1,s=!o.objectMode&&(r=e,h.isBuffer(r)||r instanceof p);return s&&!h.isBuffer(e)&&(e=function(e){return h.from(e)}(e)),"function"==typeof t&&(n=t,t=null),s?t="buffer":t||(t=o.defaultEncoding),"function"!=typeof n&&(n=y),o.ended?function(e,t){var n=new Error("write after end");e.emit("error",n),i.nextTick(t,n)}(this,n):(s||function(e,t,n,r){var o=!0,a=!1;return null===n?a=new TypeError("May not write null values to stream"):"string"==typeof n||void 0===n||t.objectMode||(a=new TypeError("Invalid non-string/buffer chunk")),a&&(e.emit("error",a),i.nextTick(r,a),o=!1),o}(this,o,e,n))&&(o.pendingcb++,a=function(e,t,n,r,o,i){if(!n){var a=function(e,t,n){e.objectMode||!1===e.decodeStrings||"string"!=typeof t||(t=h.from(t,n));return t}(t,r,o);r!==a&&(n=!0,o="buffer",r=a)}var s=t.objectMode?1:r.length;t.length+=s;var u=t.length-1))throw new TypeError("Unknown encoding: "+e);return this._writableState.defaultEncoding=e,this},Object.defineProperty(m.prototype,"writableHighWaterMark",{enumerable:!1,get:function(){return this._writableState.highWaterMark}}),m.prototype._write=function(e,t,n){n(new Error("_write() is not implemented"))},m.prototype._writev=null,m.prototype.end=function(e,t,n){var r=this._writableState;"function"==typeof e?(n=e,e=null,t=null):"function"==typeof t&&(n=t,t=null),null!=e&&this.write(e,t),r.corked&&(r.corked=1,this.uncork()),r.ending||r.finished||function(e,t,n){t.ending=!0,T(e,t),n&&(t.finished?i.nextTick(n):e.once("finish",n));t.ended=!0,e.writable=!1}(this,r,n)},Object.defineProperty(m.prototype,"destroyed",{get:function(){return void 0!==this._writableState&&this._writableState.destroyed},set:function(e){this._writableState&&(this._writableState.destroyed=e)}}),m.prototype.destroy=g.destroy,m.prototype._undestroy=g.undestroy,m.prototype._destroy=function(e,t){this.end(),t(e)}}).call(this,n(14),n(54).setImmediate,n(5))},function(e,t,n){"use strict";var r=n(6).Buffer,o=r.isEncoding||function(e){switch((e=""+e)&&e.toLowerCase()){case"hex":case"utf8":case"utf-8":case"ascii":case"binary":case"base64":case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":case"raw":return!0;default:return!1}};function i(e){var t;switch(this.encoding=function(e){var t=function(e){if(!e)return"utf8";for(var t;;)switch(e){case"utf8":case"utf-8":return"utf8";case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return"utf16le";case"latin1":case"binary":return"latin1";case"base64":case"ascii":case"hex":return e;default:if(t)return;e=(""+e).toLowerCase(),t=!0}}(e);if("string"!=typeof t&&(r.isEncoding===o||!o(e)))throw new Error("Unknown encoding: "+e);return t||e}(e),this.encoding){case"utf16le":this.text=u,this.end=c,t=4;break;case"utf8":this.fillLast=s,t=4;break;case"base64":this.text=l,this.end=f,t=3;break;default:return this.write=h,void(this.end=p)}this.lastNeed=0,this.lastTotal=0,this.lastChar=r.allocUnsafe(t)}function a(e){return e<=127?0:e>>5==6?2:e>>4==14?3:e>>3==30?4:e>>6==2?-1:-2}function s(e){var t=this.lastTotal-this.lastNeed,n=function(e,t,n){if(128!=(192&t[0]))return e.lastNeed=0,"�";if(e.lastNeed>1&&t.length>1){if(128!=(192&t[1]))return e.lastNeed=1,"�";if(e.lastNeed>2&&t.length>2&&128!=(192&t[2]))return e.lastNeed=2,"�"}}(this,e);return void 0!==n?n:this.lastNeed<=e.length?(e.copy(this.lastChar,t,0,this.lastNeed),this.lastChar.toString(this.encoding,0,this.lastTotal)):(e.copy(this.lastChar,t,0,e.length),void(this.lastNeed-=e.length))}function u(e,t){if((e.length-t)%2==0){var n=e.toString("utf16le",t);if(n){var r=n.charCodeAt(n.length-1);if(r>=55296&&r<=56319)return this.lastNeed=2,this.lastTotal=4,this.lastChar[0]=e[e.length-2],this.lastChar[1]=e[e.length-1],n.slice(0,-1)}return n}return this.lastNeed=1,this.lastTotal=2,this.lastChar[0]=e[e.length-1],e.toString("utf16le",t,e.length-1)}function c(e){var t=e&&e.length?this.write(e):"";if(this.lastNeed){var n=this.lastTotal-this.lastNeed;return t+this.lastChar.toString("utf16le",0,n)}return t}function l(e,t){var n=(e.length-t)%3;return 0===n?e.toString("base64",t):(this.lastNeed=3-n,this.lastTotal=3,1===n?this.lastChar[0]=e[e.length-1]:(this.lastChar[0]=e[e.length-2],this.lastChar[1]=e[e.length-1]),e.toString("base64",t,e.length-n))}function f(e){var t=e&&e.length?this.write(e):"";return this.lastNeed?t+this.lastChar.toString("base64",0,3-this.lastNeed):t}function h(e){return e.toString(this.encoding)}function p(e){return e&&e.length?this.write(e):""}t.StringDecoder=i,i.prototype.write=function(e){if(0===e.length)return"";var t,n;if(this.lastNeed){if(void 0===(t=this.fillLast(e)))return"";n=this.lastNeed,this.lastNeed=0}else n=0;return n=0)return o>0&&(e.lastNeed=o-1),o;if(--r=0)return o>0&&(e.lastNeed=o-2),o;if(--r=0)return o>0&&(2===o?o=0:e.lastNeed=o-3),o;return 0}(this,e,t);if(!this.lastNeed)return e.toString("utf8",t);this.lastTotal=n;var r=e.length-(n-this.lastNeed);return e.copy(this.lastChar,0,r),e.toString("utf8",t,r)},i.prototype.fillLast=function(e){if(this.lastNeed<=e.length)return e.copy(this.lastChar,this.lastTotal-this.lastNeed,0,this.lastNeed),this.lastChar.toString(this.encoding,0,this.lastTotal);e.copy(this.lastChar,this.lastTotal-this.lastNeed,0,e.length),this.lastNeed-=e.length}},function(e,t,n){"use strict";e.exports=a;var r=n(10),o=n(15);function i(e,t){var n=this._transformState;n.transforming=!1;var r=n.writecb;if(!r)return this.emit("error",new Error("write callback called multiple times"));n.writechunk=null,n.writecb=null,null!=t&&this.push(t),r(e);var o=this._readableState;o.reading=!1,(o.needReadable||o.length0&&o[o.length-1])&&(6===i[0]||2===i[0])){a=0;continue}if(3===i[0]&&(!o||i[1]>o[0]&&i[1]s?a.slice(s).buffer:null}else{var u,c=t;if(-1===(u=c.indexOf(r.a.RecordSeparator)))throw new Error("Message is incomplete.");s=u+1;n=c.substring(0,s),i=c.length>s?c.substring(s):null}var l=r.a.parse(n),f=JSON.parse(l[0]);if(f.type)throw new Error("Expected a handshake response from the server.");return[i,f]},t}()}).call(this,n(11).Buffer)},,,,,function(e,t,n){"use strict";var r=this&&this.__assign||function(){return(r=Object.assign||function(e){for(var t,n=1,r=arguments.length;n0&&o[o.length-1])&&(6===i[0]||2===i[0])){a=0;continue}if(3===i[0]&&(!o||i[1]>o[0]&&i[1]0?r-4:r,f=0;f>16&255,s[u++]=t>>8&255,s[u++]=255&t;2===a&&(t=o[e.charCodeAt(f)]<<2|o[e.charCodeAt(f+1)]>>4,s[u++]=255&t);1===a&&(t=o[e.charCodeAt(f)]<<10|o[e.charCodeAt(f+1)]<<4|o[e.charCodeAt(f+2)]>>2,s[u++]=t>>8&255,s[u++]=255&t);return s},t.fromByteArray=function(e){for(var t,n=e.length,o=n%3,i=[],a=0,s=n-o;as?s:a+16383));1===o?(t=e[n-1],i.push(r[t>>2]+r[t<<4&63]+"==")):2===o&&(t=(e[n-2]<<8)+e[n-1],i.push(r[t>>10]+r[t>>4&63]+r[t<<2&63]+"="));return i.join("")};for(var r=[],o=[],i="undefined"!=typeof Uint8Array?Uint8Array:Array,a="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",s=0,u=a.length;s0)throw new Error("Invalid string. Length must be a multiple of 4");var n=e.indexOf("=");return-1===n&&(n=t),[n,n===t?0:4-n%4]}function l(e,t,n){for(var o,i,a=[],s=t;s>18&63]+r[i>>12&63]+r[i>>6&63]+r[63&i]);return a.join("")}o["-".charCodeAt(0)]=62,o["_".charCodeAt(0)]=63},function(e,t){t.read=function(e,t,n,r,o){var i,a,s=8*o-r-1,u=(1<>1,l=-7,f=n?o-1:0,h=n?-1:1,p=e[t+f];for(f+=h,i=p&(1<<-l)-1,p>>=-l,l+=s;l>0;i=256*i+e[t+f],f+=h,l-=8);for(a=i&(1<<-l)-1,i>>=-l,l+=r;l>0;a=256*a+e[t+f],f+=h,l-=8);if(0===i)i=1-c;else{if(i===u)return a?NaN:1/0*(p?-1:1);a+=Math.pow(2,r),i-=c}return(p?-1:1)*a*Math.pow(2,i-r)},t.write=function(e,t,n,r,o,i){var a,s,u,c=8*i-o-1,l=(1<>1,h=23===o?Math.pow(2,-24)-Math.pow(2,-77):0,p=r?0:i-1,d=r?1:-1,g=t<0||0===t&&1/t<0?1:0;for(t=Math.abs(t),isNaN(t)||t===1/0?(s=isNaN(t)?1:0,a=l):(a=Math.floor(Math.log(t)/Math.LN2),t*(u=Math.pow(2,-a))<1&&(a--,u*=2),(t+=a+f>=1?h/u:h*Math.pow(2,1-f))*u>=2&&(a++,u/=2),a+f>=l?(s=0,a=l):a+f>=1?(s=(t*u-1)*Math.pow(2,o),a+=f):(s=t*Math.pow(2,f-1)*Math.pow(2,o),a=0));o>=8;e[n+p]=255&s,p+=d,s/=256,o-=8);for(a=a<0;e[n+p]=255&a,p+=d,a/=256,c-=8);e[n+p-d]|=128*g}},function(e,t,n){"use strict";(function(t){ +var r=n(47),o=n(48),i=n(31);function a(){return u.TYPED_ARRAY_SUPPORT?2147483647:1073741823}function s(e,t){if(a()=a())throw new RangeError("Attempt to allocate Buffer larger than maximum size: 0x"+a().toString(16)+" bytes");return 0|e}function d(e,t){if(u.isBuffer(e))return e.length;if("undefined"!=typeof ArrayBuffer&&"function"==typeof ArrayBuffer.isView&&(ArrayBuffer.isView(e)||e instanceof ArrayBuffer))return e.byteLength;"string"!=typeof e&&(e=""+e);var n=e.length;if(0===n)return 0;for(var r=!1;;)switch(t){case"ascii":case"latin1":case"binary":return n;case"utf8":case"utf-8":case void 0:return F(e).length;case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return 2*n;case"hex":return n>>>1;case"base64":return H(e).length;default:if(r)return F(e).length;t=(""+t).toLowerCase(),r=!0}}function g(e,t,n){var r=e[t];e[t]=e[n],e[n]=r}function y(e,t,n,r,o){if(0===e.length)return-1;if("string"==typeof n?(r=n,n=0):n>2147483647?n=2147483647:n<-2147483648&&(n=-2147483648),n=+n,isNaN(n)&&(n=o?0:e.length-1),n<0&&(n=e.length+n),n>=e.length){if(o)return-1;n=e.length-1}else if(n<0){if(!o)return-1;n=0}if("string"==typeof t&&(t=u.from(t,r)),u.isBuffer(t))return 0===t.length?-1:v(e,t,n,r,o);if("number"==typeof t)return t&=255,u.TYPED_ARRAY_SUPPORT&&"function"==typeof Uint8Array.prototype.indexOf?o?Uint8Array.prototype.indexOf.call(e,t,n):Uint8Array.prototype.lastIndexOf.call(e,t,n):v(e,[t],n,r,o);throw new TypeError("val must be string, number or Buffer")}function v(e,t,n,r,o){var i,a=1,s=e.length,u=t.length;if(void 0!==r&&("ucs2"===(r=String(r).toLowerCase())||"ucs-2"===r||"utf16le"===r||"utf-16le"===r)){if(e.length<2||t.length<2)return-1;a=2,s/=2,u/=2,n/=2}function c(e,t){return 1===a?e[t]:e.readUInt16BE(t*a)}if(o){var l=-1;for(i=n;is&&(n=s-u),i=n;i>=0;i--){for(var f=!0,h=0;ho&&(r=o):r=o;var i=t.length;if(i%2!=0)throw new TypeError("Invalid hex string");r>i/2&&(r=i/2);for(var a=0;a>8,o=n%256,i.push(o),i.push(r);return i}(t,e.length-n),e,n,r)}function T(e,t,n){return 0===t&&n===e.length?r.fromByteArray(e):r.fromByteArray(e.slice(t,n))}function k(e,t,n){n=Math.min(e.length,n);for(var r=[],o=t;o239?4:c>223?3:c>191?2:1;if(o+f<=n)switch(f){case 1:c<128&&(l=c);break;case 2:128==(192&(i=e[o+1]))&&(u=(31&c)<<6|63&i)>127&&(l=u);break;case 3:i=e[o+1],a=e[o+2],128==(192&i)&&128==(192&a)&&(u=(15&c)<<12|(63&i)<<6|63&a)>2047&&(u<55296||u>57343)&&(l=u);break;case 4:i=e[o+1],a=e[o+2],s=e[o+3],128==(192&i)&&128==(192&a)&&128==(192&s)&&(u=(15&c)<<18|(63&i)<<12|(63&a)<<6|63&s)>65535&&u<1114112&&(l=u)}null===l?(l=65533,f=1):l>65535&&(l-=65536,r.push(l>>>10&1023|55296),l=56320|1023&l),r.push(l),o+=f}return function(e){var t=e.length;if(t<=C)return String.fromCharCode.apply(String,e);var n="",r=0;for(;rthis.length)return"";if((void 0===n||n>this.length)&&(n=this.length),n<=0)return"";if((n>>>=0)<=(t>>>=0))return"";for(e||(e="utf8");;)switch(e){case"hex":return R(this,t,n);case"utf8":case"utf-8":return k(this,t,n);case"ascii":return I(this,t,n);case"latin1":case"binary":return x(this,t,n);case"base64":return T(this,t,n);case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return O(this,t,n);default:if(r)throw new TypeError("Unknown encoding: "+e);e=(e+"").toLowerCase(),r=!0}}.apply(this,arguments)},u.prototype.equals=function(e){if(!u.isBuffer(e))throw new TypeError("Argument must be a Buffer");return this===e||0===u.compare(this,e)},u.prototype.inspect=function(){var e="",n=t.INSPECT_MAX_BYTES;return this.length>0&&(e=this.toString("hex",0,n).match(/.{2}/g).join(" "),this.length>n&&(e+=" ... ")),""},u.prototype.compare=function(e,t,n,r,o){if(!u.isBuffer(e))throw new TypeError("Argument must be a Buffer");if(void 0===t&&(t=0),void 0===n&&(n=e?e.length:0),void 0===r&&(r=0),void 0===o&&(o=this.length),t<0||n>e.length||r<0||o>this.length)throw new RangeError("out of range index");if(r>=o&&t>=n)return 0;if(r>=o)return-1;if(t>=n)return 1;if(this===e)return 0;for(var i=(o>>>=0)-(r>>>=0),a=(n>>>=0)-(t>>>=0),s=Math.min(i,a),c=this.slice(r,o),l=e.slice(t,n),f=0;fo)&&(n=o),e.length>0&&(n<0||t<0)||t>this.length)throw new RangeError("Attempt to write outside buffer bounds");r||(r="utf8");for(var i=!1;;)switch(r){case"hex":return m(this,e,t,n);case"utf8":case"utf-8":return b(this,e,t,n);case"ascii":return w(this,e,t,n);case"latin1":case"binary":return E(this,e,t,n);case"base64":return S(this,e,t,n);case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return _(this,e,t,n);default:if(i)throw new TypeError("Unknown encoding: "+r);r=(""+r).toLowerCase(),i=!0}},u.prototype.toJSON=function(){return{type:"Buffer",data:Array.prototype.slice.call(this._arr||this,0)}};var C=4096;function I(e,t,n){var r="";n=Math.min(e.length,n);for(var o=t;or)&&(n=r);for(var o="",i=t;in)throw new RangeError("Trying to access beyond buffer length")}function M(e,t,n,r,o,i){if(!u.isBuffer(e))throw new TypeError('"buffer" argument must be a Buffer instance');if(t>o||te.length)throw new RangeError("Index out of range")}function L(e,t,n,r){t<0&&(t=65535+t+1);for(var o=0,i=Math.min(e.length-n,2);o>>8*(r?o:1-o)}function A(e,t,n,r){t<0&&(t=4294967295+t+1);for(var o=0,i=Math.min(e.length-n,4);o>>8*(r?o:3-o)&255}function B(e,t,n,r,o,i){if(n+r>e.length)throw new RangeError("Index out of range");if(n<0)throw new RangeError("Index out of range")}function D(e,t,n,r,i){return i||B(e,0,n,4),o.write(e,t,n,r,23,4),n+4}function U(e,t,n,r,i){return i||B(e,0,n,8),o.write(e,t,n,r,52,8),n+8}u.prototype.slice=function(e,t){var n,r=this.length;if((e=~~e)<0?(e+=r)<0&&(e=0):e>r&&(e=r),(t=void 0===t?r:~~t)<0?(t+=r)<0&&(t=0):t>r&&(t=r),t0&&(o*=256);)r+=this[e+--t]*o;return r},u.prototype.readUInt8=function(e,t){return t||P(e,1,this.length),this[e]},u.prototype.readUInt16LE=function(e,t){return t||P(e,2,this.length),this[e]|this[e+1]<<8},u.prototype.readUInt16BE=function(e,t){return t||P(e,2,this.length),this[e]<<8|this[e+1]},u.prototype.readUInt32LE=function(e,t){return t||P(e,4,this.length),(this[e]|this[e+1]<<8|this[e+2]<<16)+16777216*this[e+3]},u.prototype.readUInt32BE=function(e,t){return t||P(e,4,this.length),16777216*this[e]+(this[e+1]<<16|this[e+2]<<8|this[e+3])},u.prototype.readIntLE=function(e,t,n){e|=0,t|=0,n||P(e,t,this.length);for(var r=this[e],o=1,i=0;++i=(o*=128)&&(r-=Math.pow(2,8*t)),r},u.prototype.readIntBE=function(e,t,n){e|=0,t|=0,n||P(e,t,this.length);for(var r=t,o=1,i=this[e+--r];r>0&&(o*=256);)i+=this[e+--r]*o;return i>=(o*=128)&&(i-=Math.pow(2,8*t)),i},u.prototype.readInt8=function(e,t){return t||P(e,1,this.length),128&this[e]?-1*(255-this[e]+1):this[e]},u.prototype.readInt16LE=function(e,t){t||P(e,2,this.length);var n=this[e]|this[e+1]<<8;return 32768&n?4294901760|n:n},u.prototype.readInt16BE=function(e,t){t||P(e,2,this.length);var n=this[e+1]|this[e]<<8;return 32768&n?4294901760|n:n},u.prototype.readInt32LE=function(e,t){return t||P(e,4,this.length),this[e]|this[e+1]<<8|this[e+2]<<16|this[e+3]<<24},u.prototype.readInt32BE=function(e,t){return t||P(e,4,this.length),this[e]<<24|this[e+1]<<16|this[e+2]<<8|this[e+3]},u.prototype.readFloatLE=function(e,t){return t||P(e,4,this.length),o.read(this,e,!0,23,4)},u.prototype.readFloatBE=function(e,t){return t||P(e,4,this.length),o.read(this,e,!1,23,4)},u.prototype.readDoubleLE=function(e,t){return t||P(e,8,this.length),o.read(this,e,!0,52,8)},u.prototype.readDoubleBE=function(e,t){return t||P(e,8,this.length),o.read(this,e,!1,52,8)},u.prototype.writeUIntLE=function(e,t,n,r){(e=+e,t|=0,n|=0,r)||M(this,e,t,n,Math.pow(2,8*n)-1,0);var o=1,i=0;for(this[t]=255&e;++i=0&&(i*=256);)this[t+o]=e/i&255;return t+n},u.prototype.writeUInt8=function(e,t,n){return e=+e,t|=0,n||M(this,e,t,1,255,0),u.TYPED_ARRAY_SUPPORT||(e=Math.floor(e)),this[t]=255&e,t+1},u.prototype.writeUInt16LE=function(e,t,n){return e=+e,t|=0,n||M(this,e,t,2,65535,0),u.TYPED_ARRAY_SUPPORT?(this[t]=255&e,this[t+1]=e>>>8):L(this,e,t,!0),t+2},u.prototype.writeUInt16BE=function(e,t,n){return e=+e,t|=0,n||M(this,e,t,2,65535,0),u.TYPED_ARRAY_SUPPORT?(this[t]=e>>>8,this[t+1]=255&e):L(this,e,t,!1),t+2},u.prototype.writeUInt32LE=function(e,t,n){return e=+e,t|=0,n||M(this,e,t,4,4294967295,0),u.TYPED_ARRAY_SUPPORT?(this[t+3]=e>>>24,this[t+2]=e>>>16,this[t+1]=e>>>8,this[t]=255&e):A(this,e,t,!0),t+4},u.prototype.writeUInt32BE=function(e,t,n){return e=+e,t|=0,n||M(this,e,t,4,4294967295,0),u.TYPED_ARRAY_SUPPORT?(this[t]=e>>>24,this[t+1]=e>>>16,this[t+2]=e>>>8,this[t+3]=255&e):A(this,e,t,!1),t+4},u.prototype.writeIntLE=function(e,t,n,r){if(e=+e,t|=0,!r){var o=Math.pow(2,8*n-1);M(this,e,t,n,o-1,-o)}var i=0,a=1,s=0;for(this[t]=255&e;++i>0)-s&255;return t+n},u.prototype.writeIntBE=function(e,t,n,r){if(e=+e,t|=0,!r){var o=Math.pow(2,8*n-1);M(this,e,t,n,o-1,-o)}var i=n-1,a=1,s=0;for(this[t+i]=255&e;--i>=0&&(a*=256);)e<0&&0===s&&0!==this[t+i+1]&&(s=1),this[t+i]=(e/a>>0)-s&255;return t+n},u.prototype.writeInt8=function(e,t,n){return e=+e,t|=0,n||M(this,e,t,1,127,-128),u.TYPED_ARRAY_SUPPORT||(e=Math.floor(e)),e<0&&(e=255+e+1),this[t]=255&e,t+1},u.prototype.writeInt16LE=function(e,t,n){return e=+e,t|=0,n||M(this,e,t,2,32767,-32768),u.TYPED_ARRAY_SUPPORT?(this[t]=255&e,this[t+1]=e>>>8):L(this,e,t,!0),t+2},u.prototype.writeInt16BE=function(e,t,n){return e=+e,t|=0,n||M(this,e,t,2,32767,-32768),u.TYPED_ARRAY_SUPPORT?(this[t]=e>>>8,this[t+1]=255&e):L(this,e,t,!1),t+2},u.prototype.writeInt32LE=function(e,t,n){return e=+e,t|=0,n||M(this,e,t,4,2147483647,-2147483648),u.TYPED_ARRAY_SUPPORT?(this[t]=255&e,this[t+1]=e>>>8,this[t+2]=e>>>16,this[t+3]=e>>>24):A(this,e,t,!0),t+4},u.prototype.writeInt32BE=function(e,t,n){return e=+e,t|=0,n||M(this,e,t,4,2147483647,-2147483648),e<0&&(e=4294967295+e+1),u.TYPED_ARRAY_SUPPORT?(this[t]=e>>>24,this[t+1]=e>>>16,this[t+2]=e>>>8,this[t+3]=255&e):A(this,e,t,!1),t+4},u.prototype.writeFloatLE=function(e,t,n){return D(this,e,t,!0,n)},u.prototype.writeFloatBE=function(e,t,n){return D(this,e,t,!1,n)},u.prototype.writeDoubleLE=function(e,t,n){return U(this,e,t,!0,n)},u.prototype.writeDoubleBE=function(e,t,n){return U(this,e,t,!1,n)},u.prototype.copy=function(e,t,n,r){if(n||(n=0),r||0===r||(r=this.length),t>=e.length&&(t=e.length),t||(t=0),r>0&&r=this.length)throw new RangeError("sourceStart out of bounds");if(r<0)throw new RangeError("sourceEnd out of bounds");r>this.length&&(r=this.length),e.length-t=0;--o)e[o+t]=this[o+n];else if(i<1e3||!u.TYPED_ARRAY_SUPPORT)for(o=0;o>>=0,n=void 0===n?this.length:n>>>0,e||(e=0),"number"==typeof e)for(i=t;i55295&&n<57344){if(!o){if(n>56319){(t-=3)>-1&&i.push(239,191,189);continue}if(a+1===r){(t-=3)>-1&&i.push(239,191,189);continue}o=n;continue}if(n<56320){(t-=3)>-1&&i.push(239,191,189),o=n;continue}n=65536+(o-55296<<10|n-56320)}else o&&(t-=3)>-1&&i.push(239,191,189);if(o=null,n<128){if((t-=1)<0)break;i.push(n)}else if(n<2048){if((t-=2)<0)break;i.push(n>>6|192,63&n|128)}else if(n<65536){if((t-=3)<0)break;i.push(n>>12|224,n>>6&63|128,63&n|128)}else{if(!(n<1114112))throw new Error("Invalid code point");if((t-=4)<0)break;i.push(n>>18|240,n>>12&63|128,n>>6&63|128,63&n|128)}}return i}function H(e){return r.toByteArray(function(e){if((e=function(e){return e.trim?e.trim():e.replace(/^\s+|\s+$/g,"")}(e).replace(N,"")).length<2)return"";for(;e.length%4!=0;)e+="=";return e}(e))}function q(e,t,n,r){for(var o=0;o=t.length||o>=e.length);++o)t[o+n]=e[o];return o}}).call(this,n(5))},function(e,t,n){"use strict";var r;!function(e){window.DotNet=e;var t=[],n={},r={},o=1,i=null;function a(e){t.push(e)}function s(e,t){for(var n=[],r=2;r1)for(var n=1;n0&&o[o.length-1])&&(6===i[0]||2===i[0])){a=0;continue}if(3===i[0]&&(!o||i[1]>o[0]&&i[1]this.length||e<0)){var t=this._offset(e);return this._bufs[t[0]][t[1]]}},a.prototype.slice=function(e,t){return"number"==typeof e&&e<0&&(e+=this.length),"number"==typeof t&&t<0&&(t+=this.length),this.copy(null,0,e,t)},a.prototype.copy=function(e,t,n,r){if(("number"!=typeof n||n<0)&&(n=0),("number"!=typeof r||r>this.length)&&(r=this.length),n>=this.length)return e||i.alloc(0);if(r<=0)return e||i.alloc(0);var o,a,s=!!e,u=this._offset(n),c=r-n,l=c,f=s&&t||0,h=u[1];if(0===n&&r==this.length){if(!s)return 1===this._bufs.length?this._bufs[0]:i.concat(this._bufs,this.length);for(a=0;a(o=this._bufs[a].length-h))){this._bufs[a].copy(e,f,h,h+l);break}this._bufs[a].copy(e,f,h),f+=o,l-=o,h&&(h=0)}return e},a.prototype.shallowSlice=function(e,t){if(e=e||0,t="number"!=typeof t?this.length:t,e<0&&(e+=this.length),t<0&&(t+=this.length),e===t)return new a;var n=this._offset(e),r=this._offset(t),o=this._bufs.slice(n[0],r[0]+1);return 0==r[1]?o.pop():o[o.length-1]=o[o.length-1].slice(0,r[1]),0!=n[1]&&(o[0]=o[0].slice(n[1])),new a(o)},a.prototype.toString=function(e,t,n){return this.slice(t,n).toString(e)},a.prototype.consume=function(e){for(;this._bufs.length;){if(!(e>=this._bufs[0].length)){this._bufs[0]=this._bufs[0].slice(e),this.length-=e;break}e-=this._bufs[0].length,this.length-=this._bufs[0].length,this._bufs.shift()}return this},a.prototype.duplicate=function(){for(var e=0,t=new a;ethis.length?this.length:t;for(var r=this._offset(t),o=r[0],s=r[1];o=e.length){var c=u.indexOf(e,s);if(-1!==c)return this._reverseOffset([o,c]);s=u.length-e.length+1}else{var l=this._reverseOffset([o,s]);if(this._match(l,e))return l;s++}}s=0}return-1},a.prototype._match=function(e,t){if(this.length-e=0,"must have a non-negative type"),o(a,"must have a decode function"),this.registerEncoder(function(e){return e instanceof t},function(t){var o=i(),a=r.allocUnsafe(1);return a.writeInt8(e,0),o.append(a),o.append(n(t)),o}),this.registerDecoder(e,a),this},registerEncoder:function(e,n){return o(e,"must have an encode function"),o(n,"must have an encode function"),t.push({check:e,encode:n}),this},registerDecoder:function(e,t){return o(e>=0,"must have a non-negative type"),o(t,"must have a decode function"),n.push({type:e,decode:t}),this},encoder:a.encoder,decoder:a.decoder,buffer:!0,type:"msgpack5",IncompleteBufferError:s.IncompleteBufferError}}},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var r=n(16),o=n(22),i=n(8);window.Blazor={navigateTo:r.navigateTo,_internal:{attachRootComponentToElement:i.attachRootComponentToElement,http:o.internalFunctions,uriHelper:r.internalFunctions}}},function(e,t,n){"use strict";var r=this&&this.__awaiter||function(e,t,n,r){return new(n||(n=Promise))(function(o,i){function a(e){try{u(r.next(e))}catch(e){i(e)}}function s(e){try{u(r.throw(e))}catch(e){i(e)}}function u(e){e.done?o(e.value):new n(function(t){t(e.value)}).then(a,s)}u((r=r.apply(e,t||[])).next())})},o=this&&this.__generator||function(e,t){var n,r,o,i,a={label:0,sent:function(){if(1&o[0])throw o[1];return o[1]},trys:[],ops:[]};return i={next:s(0),throw:s(1),return:s(2)},"function"==typeof Symbol&&(i[Symbol.iterator]=function(){return this}),i;function s(i){return function(s){return function(i){if(n)throw new TypeError("Generator is already executing.");for(;a;)try{if(n=1,r&&(o=2&i[0]?r.return:i[0]?r.throw||((o=r.return)&&o.call(r),0):r.next)&&!(o=o.call(r,i[1])).done)return o;switch(r=0,o&&(i=[2&i[0],o.value]),i[0]){case 0:case 1:o=i;break;case 4:return a.label++,{value:i[1],done:!1};case 5:a.label++,r=i[1],i=[0];continue;case 7:i=a.ops.pop(),a.trys.pop();continue;default:if(!(o=(o=a.trys).length>0&&o[o.length-1])&&(6===i[0]||2===i[0])){a=0;continue}if(3===i[0]&&(!o||i[1]>o[0]&&i[1]0&&o[o.length-1])&&(6===i[0]||2===i[0])){a=0;continue}if(3===i[0]&&(!o||i[1]>o[0]&&i[1]=i)return e;switch(e){case"%s":return String(r[n++]);case"%d":return Number(r[n++]);case"%j":try{return JSON.stringify(r[n++])}catch(e){return"[Circular]"}default:return e}}),u=r[n];n=3&&(r.depth=arguments[2]),arguments.length>=4&&(r.colors=arguments[3]),d(n)?r.showHidden=n:n&&t._extend(r,n),m(r.showHidden)&&(r.showHidden=!1),m(r.depth)&&(r.depth=2),m(r.colors)&&(r.colors=!1),m(r.customInspect)&&(r.customInspect=!0),r.colors&&(r.stylize=u),l(r,e,r.depth)}function u(e,t){var n=s.styles[t];return n?"["+s.colors[n][0]+"m"+e+"["+s.colors[n][1]+"m":e}function c(e,t){return e}function l(e,n,r){if(e.customInspect&&n&&_(n.inspect)&&n.inspect!==t.inspect&&(!n.constructor||n.constructor.prototype!==n)){var o=n.inspect(r,e);return v(o)||(o=l(e,o,r)),o}var i=function(e,t){if(m(t))return e.stylize("undefined","undefined");if(v(t)){var n="'"+JSON.stringify(t).replace(/^"|"$/g,"").replace(/'/g,"\\'").replace(/\\"/g,'"')+"'";return e.stylize(n,"string")}if(y(t))return e.stylize(""+t,"number");if(d(t))return e.stylize(""+t,"boolean");if(g(t))return e.stylize("null","null")}(e,n);if(i)return i;var a=Object.keys(n),s=function(e){var t={};return e.forEach(function(e,n){t[e]=!0}),t}(a);if(e.showHidden&&(a=Object.getOwnPropertyNames(n)),S(n)&&(a.indexOf("message")>=0||a.indexOf("description")>=0))return f(n);if(0===a.length){if(_(n)){var u=n.name?": "+n.name:"";return e.stylize("[Function"+u+"]","special")}if(b(n))return e.stylize(RegExp.prototype.toString.call(n),"regexp");if(E(n))return e.stylize(Date.prototype.toString.call(n),"date");if(S(n))return f(n)}var c,w="",T=!1,k=["{","}"];(p(n)&&(T=!0,k=["[","]"]),_(n))&&(w=" [Function"+(n.name?": "+n.name:"")+"]");return b(n)&&(w=" "+RegExp.prototype.toString.call(n)),E(n)&&(w=" "+Date.prototype.toUTCString.call(n)),S(n)&&(w=" "+f(n)),0!==a.length||T&&0!=n.length?r<0?b(n)?e.stylize(RegExp.prototype.toString.call(n),"regexp"):e.stylize("[Object]","special"):(e.seen.push(n),c=T?function(e,t,n,r,o){for(var i=[],a=0,s=t.length;a=0&&0,e+t.replace(/\u001b\[\d\d?m/g,"").length+1},0)>60)return n[0]+(""===t?"":t+"\n ")+" "+e.join(",\n ")+" "+n[1];return n[0]+t+" "+e.join(", ")+" "+n[1]}(c,w,k)):k[0]+w+k[1]}function f(e){return"["+Error.prototype.toString.call(e)+"]"}function h(e,t,n,r,o,i){var a,s,u;if((u=Object.getOwnPropertyDescriptor(t,o)||{value:t[o]}).get?s=u.set?e.stylize("[Getter/Setter]","special"):e.stylize("[Getter]","special"):u.set&&(s=e.stylize("[Setter]","special")),I(r,o)||(a="["+o+"]"),s||(e.seen.indexOf(u.value)<0?(s=g(n)?l(e,u.value,null):l(e,u.value,n-1)).indexOf("\n")>-1&&(s=i?s.split("\n").map(function(e){return" "+e}).join("\n").substr(2):"\n"+s.split("\n").map(function(e){return" "+e}).join("\n")):s=e.stylize("[Circular]","special")),m(a)){if(i&&o.match(/^\d+$/))return s;(a=JSON.stringify(""+o)).match(/^"([a-zA-Z_][a-zA-Z_0-9]*)"$/)?(a=a.substr(1,a.length-2),a=e.stylize(a,"name")):(a=a.replace(/'/g,"\\'").replace(/\\"/g,'"').replace(/(^"|"$)/g,"'"),a=e.stylize(a,"string"))}return a+": "+s}function p(e){return Array.isArray(e)}function d(e){return"boolean"==typeof e}function g(e){return null===e}function y(e){return"number"==typeof e}function v(e){return"string"==typeof e}function m(e){return void 0===e}function b(e){return w(e)&&"[object RegExp]"===T(e)}function w(e){return"object"==typeof e&&null!==e}function E(e){return w(e)&&"[object Date]"===T(e)}function S(e){return w(e)&&("[object Error]"===T(e)||e instanceof Error)}function _(e){return"function"==typeof e}function T(e){return Object.prototype.toString.call(e)}function k(e){return e<10?"0"+e.toString(10):e.toString(10)}t.debuglog=function(n){if(m(i)&&(i=e.env.NODE_DEBUG||""),n=n.toUpperCase(),!a[n])if(new RegExp("\\b"+n+"\\b","i").test(i)){var r=e.pid;a[n]=function(){var e=t.format.apply(t,arguments);console.error("%s %d: %s",n,r,e)}}else a[n]=function(){};return a[n]},t.inspect=s,s.colors={bold:[1,22],italic:[3,23],underline:[4,24],inverse:[7,27],white:[37,39],grey:[90,39],black:[30,39],blue:[34,39],cyan:[36,39],green:[32,39],magenta:[35,39],red:[31,39],yellow:[33,39]},s.styles={special:"cyan",number:"yellow",boolean:"yellow",undefined:"grey",null:"bold",string:"green",date:"magenta",regexp:"red"},t.isArray=p,t.isBoolean=d,t.isNull=g,t.isNullOrUndefined=function(e){return null==e},t.isNumber=y,t.isString=v,t.isSymbol=function(e){return"symbol"==typeof e},t.isUndefined=m,t.isRegExp=b,t.isObject=w,t.isDate=E,t.isError=S,t.isFunction=_,t.isPrimitive=function(e){return null===e||"boolean"==typeof e||"number"==typeof e||"string"==typeof e||"symbol"==typeof e||void 0===e},t.isBuffer=n(50);var C=["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"];function I(e,t){return Object.prototype.hasOwnProperty.call(e,t)}t.log=function(){var e,n;console.log("%s - %s",(e=new Date,n=[k(e.getHours()),k(e.getMinutes()),k(e.getSeconds())].join(":"),[e.getDate(),C[e.getMonth()],n].join(" ")),t.format.apply(t,arguments))},t.inherits=n(7),t._extend=function(e,t){if(!t||!w(t))return e;for(var n=Object.keys(t),r=n.length;r--;)e[n[r]]=t[n[r]];return e};var x="undefined"!=typeof Symbol?Symbol("util.promisify.custom"):void 0;function R(e,t){if(!e){var n=new Error("Promise was rejected with a falsy value");n.reason=e,e=n}return t(e)}t.promisify=function(e){if("function"!=typeof e)throw new TypeError('The "original" argument must be of type Function');if(x&&e[x]){var t;if("function"!=typeof(t=e[x]))throw new TypeError('The "util.promisify.custom" argument must be of type Function');return Object.defineProperty(t,x,{value:t,enumerable:!1,writable:!1,configurable:!0}),t}function t(){for(var t,n,r=new Promise(function(e,r){t=e,n=r}),o=[],i=0;i0?("string"==typeof t||a.objectMode||Object.getPrototypeOf(t)===c.prototype||(t=function(e){return c.from(e)}(t)),r?a.endEmitted?e.emit("error",new Error("stream.unshift() after end event")):E(e,a,t,!0):a.ended?e.emit("error",new Error("stream.push() after EOF")):(a.reading=!1,a.decoder&&!n?(t=a.decoder.write(t),a.objectMode||0!==t.length?E(e,a,t,!1):C(e,a)):E(e,a,t,!1))):r||(a.reading=!1));return function(e){return!e.ended&&(e.needReadable||e.lengtht.highWaterMark&&(t.highWaterMark=function(e){return e>=S?e=S:(e--,e|=e>>>1,e|=e>>>2,e|=e>>>4,e|=e>>>8,e|=e>>>16,e++),e}(e)),e<=t.length?e:t.ended?t.length:(t.needReadable=!0,0))}function T(e){var t=e._readableState;t.needReadable=!1,t.emittedReadable||(p("emitReadable",t.flowing),t.emittedReadable=!0,t.sync?o.nextTick(k,e):k(e))}function k(e){p("emit readable"),e.emit("readable"),O(e)}function C(e,t){t.readingMore||(t.readingMore=!0,o.nextTick(I,e,t))}function I(e,t){for(var n=t.length;!t.reading&&!t.flowing&&!t.ended&&t.length=t.length?(n=t.decoder?t.buffer.join(""):1===t.buffer.length?t.buffer.head.data:t.buffer.concat(t.length),t.buffer.clear()):n=function(e,t,n){var r;ei.length?i.length:e;if(a===i.length?o+=i:o+=i.slice(0,e),0===(e-=a)){a===i.length?(++r,n.next?t.head=n.next:t.head=t.tail=null):(t.head=n,n.data=i.slice(a));break}++r}return t.length-=r,o}(e,t):function(e,t){var n=c.allocUnsafe(e),r=t.head,o=1;r.data.copy(n),e-=r.data.length;for(;r=r.next;){var i=r.data,a=e>i.length?i.length:e;if(i.copy(n,n.length-e,0,a),0===(e-=a)){a===i.length?(++o,r.next?t.head=r.next:t.head=t.tail=null):(t.head=r,r.data=i.slice(a));break}++o}return t.length-=o,n}(e,t);return r}(e,t.buffer,t.decoder),n);var n}function M(e){var t=e._readableState;if(t.length>0)throw new Error('"endReadable()" called on non-empty stream');t.endEmitted||(t.ended=!0,o.nextTick(L,t,e))}function L(e,t){e.endEmitted||0!==e.length||(e.endEmitted=!0,t.readable=!1,t.emit("end"))}function A(e,t){for(var n=0,r=e.length;n=t.highWaterMark||t.ended))return p("read: emitReadable",t.length,t.ended),0===t.length&&t.ended?M(this):T(this),null;if(0===(e=_(e,t))&&t.ended)return 0===t.length&&M(this),null;var r,o=t.needReadable;return p("need readable",o),(0===t.length||t.length-e0?P(e,t):null)?(t.needReadable=!0,e=0):t.length-=e,0===t.length&&(t.ended||(t.needReadable=!0),n!==e&&t.ended&&M(this)),null!==r&&this.emit("data",r),r},b.prototype._read=function(e){this.emit("error",new Error("_read() is not implemented"))},b.prototype.pipe=function(e,t){var n=this,i=this._readableState;switch(i.pipesCount){case 0:i.pipes=e;break;case 1:i.pipes=[i.pipes,e];break;default:i.pipes.push(e)}i.pipesCount+=1,p("pipe count=%d opts=%j",i.pipesCount,t);var u=(!t||!1!==t.end)&&e!==r.stdout&&e!==r.stderr?l:b;function c(t,r){p("onunpipe"),t===n&&r&&!1===r.hasUnpiped&&(r.hasUnpiped=!0,p("cleanup"),e.removeListener("close",v),e.removeListener("finish",m),e.removeListener("drain",f),e.removeListener("error",y),e.removeListener("unpipe",c),n.removeListener("end",l),n.removeListener("end",b),n.removeListener("data",g),h=!0,!i.awaitDrain||e._writableState&&!e._writableState.needDrain||f())}function l(){p("onend"),e.end()}i.endEmitted?o.nextTick(u):n.once("end",u),e.on("unpipe",c);var f=function(e){return function(){var t=e._readableState;p("pipeOnDrain",t.awaitDrain),t.awaitDrain&&t.awaitDrain--,0===t.awaitDrain&&s(e,"data")&&(t.flowing=!0,O(e))}}(n);e.on("drain",f);var h=!1;var d=!1;function g(t){p("ondata"),d=!1,!1!==e.write(t)||d||((1===i.pipesCount&&i.pipes===e||i.pipesCount>1&&-1!==A(i.pipes,e))&&!h&&(p("false write response, pause",n._readableState.awaitDrain),n._readableState.awaitDrain++,d=!0),n.pause())}function y(t){p("onerror",t),b(),e.removeListener("error",y),0===s(e,"error")&&e.emit("error",t)}function v(){e.removeListener("finish",m),b()}function m(){p("onfinish"),e.removeListener("close",v),b()}function b(){p("unpipe"),n.unpipe(e)}return n.on("data",g),function(e,t,n){if("function"==typeof e.prependListener)return e.prependListener(t,n);e._events&&e._events[t]?a(e._events[t])?e._events[t].unshift(n):e._events[t]=[n,e._events[t]]:e.on(t,n)}(e,"error",y),e.once("close",v),e.once("finish",m),e.emit("pipe",n),i.flowing||(p("pipe resume"),n.resume()),e},b.prototype.unpipe=function(e){var t=this._readableState,n={hasUnpiped:!1};if(0===t.pipesCount)return this;if(1===t.pipesCount)return e&&e!==t.pipes?this:(e||(e=t.pipes),t.pipes=null,t.pipesCount=0,t.flowing=!1,e&&e.emit("unpipe",this,n),this);if(!e){var r=t.pipes,o=t.pipesCount;t.pipes=null,t.pipesCount=0,t.flowing=!1;for(var i=0;i0&&a.length>o&&!a.warned){a.warned=!0;var u=new Error("Possible EventEmitter memory leak detected. "+a.length+" "+String(t)+" listeners added. Use emitter.setMaxListeners() to increase limit");u.name="MaxListenersExceededWarning",u.emitter=e,u.type=t,u.count=a.length,s=u,console&&console.warn&&console.warn(s)}return e}function f(e,t,n){var r={fired:!1,wrapFn:void 0,target:e,type:t,listener:n},o=function(){for(var e=[],t=0;t0&&(a=t[0]),a instanceof Error)throw a;var s=new Error("Unhandled error."+(a?" ("+a.message+")":""));throw s.context=a,s}var u=o[e];if(void 0===u)return!1;if("function"==typeof u)i(u,this,t);else{var c=u.length,l=d(u,c);for(n=0;n=0;i--)if(n[i]===t||n[i].listener===t){a=n[i].listener,o=i;break}if(o<0)return this;0===o?n.shift():function(e,t){for(;t+1=0;r--)this.removeListener(e,t[r]);return this},s.prototype.listeners=function(e){return h(this,e,!0)},s.prototype.rawListeners=function(e){return h(this,e,!1)},s.listenerCount=function(e,t){return"function"==typeof e.listenerCount?e.listenerCount(t):p.call(e,t)},s.prototype.listenerCount=p,s.prototype.eventNames=function(){return this._eventsCount>0?r(this._events):[]}},function(e,t,n){e.exports=n(34).EventEmitter},function(e,t,n){"use strict";var r=n(18);function o(e,t){e.emit("error",t)}e.exports={destroy:function(e,t){var n=this,i=this._readableState&&this._readableState.destroyed,a=this._writableState&&this._writableState.destroyed;return i||a?(t?t(e):!e||this._writableState&&this._writableState.errorEmitted||r.nextTick(o,this,e),this):(this._readableState&&(this._readableState.destroyed=!0),this._writableState&&(this._writableState.destroyed=!0),this._destroy(e||null,function(e){!t&&e?(r.nextTick(o,n,e),n._writableState&&(n._writableState.errorEmitted=!0)):t&&t(e)}),this)},undestroy:function(){this._readableState&&(this._readableState.destroyed=!1,this._readableState.reading=!1,this._readableState.ended=!1,this._readableState.endEmitted=!1),this._writableState&&(this._writableState.destroyed=!1,this._writableState.ended=!1,this._writableState.ending=!1,this._writableState.finished=!1,this._writableState.errorEmitted=!1)}}},function(e,t,n){"use strict";(function(t,r,o){var i=n(18);function a(e){var t=this;this.next=null,this.entry=null,this.finish=function(){!function(e,t,n){var r=e.entry;e.entry=null;for(;r;){var o=r.callback;t.pendingcb--,o(n),r=r.next}t.corkedRequestsFree?t.corkedRequestsFree.next=e:t.corkedRequestsFree=e}(t,e)}}e.exports=m;var s,u=!t.browser&&["v0.10","v0.9."].indexOf(t.version.slice(0,5))>-1?r:i.nextTick;m.WritableState=v;var c=n(15);c.inherits=n(7);var l={deprecate:n(56)},f=n(35),h=n(6).Buffer,p=o.Uint8Array||function(){};var d,g=n(36);function y(){}function v(e,t){s=s||n(10),e=e||{};var r=t instanceof s;this.objectMode=!!e.objectMode,r&&(this.objectMode=this.objectMode||!!e.writableObjectMode);var o=e.highWaterMark,c=e.writableHighWaterMark,l=this.objectMode?16:16384;this.highWaterMark=o||0===o?o:r&&(c||0===c)?c:l,this.highWaterMark=Math.floor(this.highWaterMark),this.finalCalled=!1,this.needDrain=!1,this.ending=!1,this.ended=!1,this.finished=!1,this.destroyed=!1;var f=!1===e.decodeStrings;this.decodeStrings=!f,this.defaultEncoding=e.defaultEncoding||"utf8",this.length=0,this.writing=!1,this.corked=0,this.sync=!0,this.bufferProcessing=!1,this.onwrite=function(e){!function(e,t){var n=e._writableState,r=n.sync,o=n.writecb;if(function(e){e.writing=!1,e.writecb=null,e.length-=e.writelen,e.writelen=0}(n),t)!function(e,t,n,r,o){--t.pendingcb,n?(i.nextTick(o,r),i.nextTick(T,e,t),e._writableState.errorEmitted=!0,e.emit("error",r)):(o(r),e._writableState.errorEmitted=!0,e.emit("error",r),T(e,t))}(e,n,r,t,o);else{var a=S(n);a||n.corked||n.bufferProcessing||!n.bufferedRequest||E(e,n),r?u(w,e,n,a,o):w(e,n,a,o)}}(t,e)},this.writecb=null,this.writelen=0,this.bufferedRequest=null,this.lastBufferedRequest=null,this.pendingcb=0,this.prefinished=!1,this.errorEmitted=!1,this.bufferedRequestCount=0,this.corkedRequestsFree=new a(this)}function m(e){if(s=s||n(10),!(d.call(m,this)||this instanceof s))return new m(e);this._writableState=new v(e,this),this.writable=!0,e&&("function"==typeof e.write&&(this._write=e.write),"function"==typeof e.writev&&(this._writev=e.writev),"function"==typeof e.destroy&&(this._destroy=e.destroy),"function"==typeof e.final&&(this._final=e.final)),f.call(this)}function b(e,t,n,r,o,i,a){t.writelen=r,t.writecb=a,t.writing=!0,t.sync=!0,n?e._writev(o,t.onwrite):e._write(o,i,t.onwrite),t.sync=!1}function w(e,t,n,r){n||function(e,t){0===t.length&&t.needDrain&&(t.needDrain=!1,e.emit("drain"))}(e,t),t.pendingcb--,r(),T(e,t)}function E(e,t){t.bufferProcessing=!0;var n=t.bufferedRequest;if(e._writev&&n&&n.next){var r=t.bufferedRequestCount,o=new Array(r),i=t.corkedRequestsFree;i.entry=n;for(var s=0,u=!0;n;)o[s]=n,n.isBuf||(u=!1),n=n.next,s+=1;o.allBuffers=u,b(e,t,!0,t.length,o,"",i.finish),t.pendingcb++,t.lastBufferedRequest=null,i.next?(t.corkedRequestsFree=i.next,i.next=null):t.corkedRequestsFree=new a(t),t.bufferedRequestCount=0}else{for(;n;){var c=n.chunk,l=n.encoding,f=n.callback;if(b(e,t,!1,t.objectMode?1:c.length,c,l,f),n=n.next,t.bufferedRequestCount--,t.writing)break}null===n&&(t.lastBufferedRequest=null)}t.bufferedRequest=n,t.bufferProcessing=!1}function S(e){return e.ending&&0===e.length&&null===e.bufferedRequest&&!e.finished&&!e.writing}function _(e,t){e._final(function(n){t.pendingcb--,n&&e.emit("error",n),t.prefinished=!0,e.emit("prefinish"),T(e,t)})}function T(e,t){var n=S(t);return n&&(!function(e,t){t.prefinished||t.finalCalled||("function"==typeof e._final?(t.pendingcb++,t.finalCalled=!0,i.nextTick(_,e,t)):(t.prefinished=!0,e.emit("prefinish")))}(e,t),0===t.pendingcb&&(t.finished=!0,e.emit("finish"))),n}c.inherits(m,f),v.prototype.getBuffer=function(){for(var e=this.bufferedRequest,t=[];e;)t.push(e),e=e.next;return t},function(){try{Object.defineProperty(v.prototype,"buffer",{get:l.deprecate(function(){return this.getBuffer()},"_writableState.buffer is deprecated. Use _writableState.getBuffer instead.","DEP0003")})}catch(e){}}(),"function"==typeof Symbol&&Symbol.hasInstance&&"function"==typeof Function.prototype[Symbol.hasInstance]?(d=Function.prototype[Symbol.hasInstance],Object.defineProperty(m,Symbol.hasInstance,{value:function(e){return!!d.call(this,e)||this===m&&(e&&e._writableState instanceof v)}})):d=function(e){return e instanceof this},m.prototype.pipe=function(){this.emit("error",new Error("Cannot pipe, not readable"))},m.prototype.write=function(e,t,n){var r,o=this._writableState,a=!1,s=!o.objectMode&&(r=e,h.isBuffer(r)||r instanceof p);return s&&!h.isBuffer(e)&&(e=function(e){return h.from(e)}(e)),"function"==typeof t&&(n=t,t=null),s?t="buffer":t||(t=o.defaultEncoding),"function"!=typeof n&&(n=y),o.ended?function(e,t){var n=new Error("write after end");e.emit("error",n),i.nextTick(t,n)}(this,n):(s||function(e,t,n,r){var o=!0,a=!1;return null===n?a=new TypeError("May not write null values to stream"):"string"==typeof n||void 0===n||t.objectMode||(a=new TypeError("Invalid non-string/buffer chunk")),a&&(e.emit("error",a),i.nextTick(r,a),o=!1),o}(this,o,e,n))&&(o.pendingcb++,a=function(e,t,n,r,o,i){if(!n){var a=function(e,t,n){e.objectMode||!1===e.decodeStrings||"string"!=typeof t||(t=h.from(t,n));return t}(t,r,o);r!==a&&(n=!0,o="buffer",r=a)}var s=t.objectMode?1:r.length;t.length+=s;var u=t.length-1))throw new TypeError("Unknown encoding: "+e);return this._writableState.defaultEncoding=e,this},Object.defineProperty(m.prototype,"writableHighWaterMark",{enumerable:!1,get:function(){return this._writableState.highWaterMark}}),m.prototype._write=function(e,t,n){n(new Error("_write() is not implemented"))},m.prototype._writev=null,m.prototype.end=function(e,t,n){var r=this._writableState;"function"==typeof e?(n=e,e=null,t=null):"function"==typeof t&&(n=t,t=null),null!=e&&this.write(e,t),r.corked&&(r.corked=1,this.uncork()),r.ending||r.finished||function(e,t,n){t.ending=!0,T(e,t),n&&(t.finished?i.nextTick(n):e.once("finish",n));t.ended=!0,e.writable=!1}(this,r,n)},Object.defineProperty(m.prototype,"destroyed",{get:function(){return void 0!==this._writableState&&this._writableState.destroyed},set:function(e){this._writableState&&(this._writableState.destroyed=e)}}),m.prototype.destroy=g.destroy,m.prototype._undestroy=g.undestroy,m.prototype._destroy=function(e,t){this.end(),t(e)}}).call(this,n(14),n(54).setImmediate,n(5))},function(e,t,n){"use strict";var r=n(6).Buffer,o=r.isEncoding||function(e){switch((e=""+e)&&e.toLowerCase()){case"hex":case"utf8":case"utf-8":case"ascii":case"binary":case"base64":case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":case"raw":return!0;default:return!1}};function i(e){var t;switch(this.encoding=function(e){var t=function(e){if(!e)return"utf8";for(var t;;)switch(e){case"utf8":case"utf-8":return"utf8";case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return"utf16le";case"latin1":case"binary":return"latin1";case"base64":case"ascii":case"hex":return e;default:if(t)return;e=(""+e).toLowerCase(),t=!0}}(e);if("string"!=typeof t&&(r.isEncoding===o||!o(e)))throw new Error("Unknown encoding: "+e);return t||e}(e),this.encoding){case"utf16le":this.text=u,this.end=c,t=4;break;case"utf8":this.fillLast=s,t=4;break;case"base64":this.text=l,this.end=f,t=3;break;default:return this.write=h,void(this.end=p)}this.lastNeed=0,this.lastTotal=0,this.lastChar=r.allocUnsafe(t)}function a(e){return e<=127?0:e>>5==6?2:e>>4==14?3:e>>3==30?4:e>>6==2?-1:-2}function s(e){var t=this.lastTotal-this.lastNeed,n=function(e,t,n){if(128!=(192&t[0]))return e.lastNeed=0,"�";if(e.lastNeed>1&&t.length>1){if(128!=(192&t[1]))return e.lastNeed=1,"�";if(e.lastNeed>2&&t.length>2&&128!=(192&t[2]))return e.lastNeed=2,"�"}}(this,e);return void 0!==n?n:this.lastNeed<=e.length?(e.copy(this.lastChar,t,0,this.lastNeed),this.lastChar.toString(this.encoding,0,this.lastTotal)):(e.copy(this.lastChar,t,0,e.length),void(this.lastNeed-=e.length))}function u(e,t){if((e.length-t)%2==0){var n=e.toString("utf16le",t);if(n){var r=n.charCodeAt(n.length-1);if(r>=55296&&r<=56319)return this.lastNeed=2,this.lastTotal=4,this.lastChar[0]=e[e.length-2],this.lastChar[1]=e[e.length-1],n.slice(0,-1)}return n}return this.lastNeed=1,this.lastTotal=2,this.lastChar[0]=e[e.length-1],e.toString("utf16le",t,e.length-1)}function c(e){var t=e&&e.length?this.write(e):"";if(this.lastNeed){var n=this.lastTotal-this.lastNeed;return t+this.lastChar.toString("utf16le",0,n)}return t}function l(e,t){var n=(e.length-t)%3;return 0===n?e.toString("base64",t):(this.lastNeed=3-n,this.lastTotal=3,1===n?this.lastChar[0]=e[e.length-1]:(this.lastChar[0]=e[e.length-2],this.lastChar[1]=e[e.length-1]),e.toString("base64",t,e.length-n))}function f(e){var t=e&&e.length?this.write(e):"";return this.lastNeed?t+this.lastChar.toString("base64",0,3-this.lastNeed):t}function h(e){return e.toString(this.encoding)}function p(e){return e&&e.length?this.write(e):""}t.StringDecoder=i,i.prototype.write=function(e){if(0===e.length)return"";var t,n;if(this.lastNeed){if(void 0===(t=this.fillLast(e)))return"";n=this.lastNeed,this.lastNeed=0}else n=0;return n=0)return o>0&&(e.lastNeed=o-1),o;if(--r=0)return o>0&&(e.lastNeed=o-2),o;if(--r=0)return o>0&&(2===o?o=0:e.lastNeed=o-3),o;return 0}(this,e,t);if(!this.lastNeed)return e.toString("utf8",t);this.lastTotal=n;var r=e.length-(n-this.lastNeed);return e.copy(this.lastChar,0,r),e.toString("utf8",t,r)},i.prototype.fillLast=function(e){if(this.lastNeed<=e.length)return e.copy(this.lastChar,this.lastTotal-this.lastNeed,0,this.lastNeed),this.lastChar.toString(this.encoding,0,this.lastTotal);e.copy(this.lastChar,this.lastTotal-this.lastNeed,0,e.length),this.lastNeed-=e.length}},function(e,t,n){"use strict";e.exports=a;var r=n(10),o=n(15);function i(e,t){var n=this._transformState;n.transforming=!1;var r=n.writecb;if(!r)return this.emit("error",new Error("write callback called multiple times"));n.writechunk=null,n.writecb=null,null!=t&&this.push(t),r(e);var o=this._readableState;o.reading=!1,(o.needReadable||o.length0&&o[o.length-1])&&(6===i[0]||2===i[0])){a=0;continue}if(3===i[0]&&(!o||i[1]>o[0]&&i[1]s?a.slice(s).buffer:null}else{var u,c=t;if(-1===(u=c.indexOf(r.a.RecordSeparator)))throw new Error("Message is incomplete.");s=u+1;n=c.substring(0,s),i=c.length>s?c.substring(s):null}var l=r.a.parse(n),f=JSON.parse(l[0]);if(f.type)throw new Error("Expected a handshake response from the server.");return[i,f]},t}()}).call(this,n(11).Buffer)},,,,,function(e,t,n){"use strict";var r=this&&this.__assign||function(){return(r=Object.assign||function(e){for(var t,n=1,r=arguments.length;n0&&o[o.length-1])&&(6===i[0]||2===i[0])){a=0;continue}if(3===i[0]&&(!o||i[1]>o[0]&&i[1]0?r-4:r,f=0;f>16&255,s[u++]=t>>8&255,s[u++]=255&t;2===a&&(t=o[e.charCodeAt(f)]<<2|o[e.charCodeAt(f+1)]>>4,s[u++]=255&t);1===a&&(t=o[e.charCodeAt(f)]<<10|o[e.charCodeAt(f+1)]<<4|o[e.charCodeAt(f+2)]>>2,s[u++]=t>>8&255,s[u++]=255&t);return s},t.fromByteArray=function(e){for(var t,n=e.length,o=n%3,i=[],a=0,s=n-o;as?s:a+16383));1===o?(t=e[n-1],i.push(r[t>>2]+r[t<<4&63]+"==")):2===o&&(t=(e[n-2]<<8)+e[n-1],i.push(r[t>>10]+r[t>>4&63]+r[t<<2&63]+"="));return i.join("")};for(var r=[],o=[],i="undefined"!=typeof Uint8Array?Uint8Array:Array,a="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",s=0,u=a.length;s0)throw new Error("Invalid string. Length must be a multiple of 4");var n=e.indexOf("=");return-1===n&&(n=t),[n,n===t?0:4-n%4]}function l(e,t,n){for(var o,i,a=[],s=t;s>18&63]+r[i>>12&63]+r[i>>6&63]+r[63&i]);return a.join("")}o["-".charCodeAt(0)]=62,o["_".charCodeAt(0)]=63},function(e,t){t.read=function(e,t,n,r,o){var i,a,s=8*o-r-1,u=(1<>1,l=-7,f=n?o-1:0,h=n?-1:1,p=e[t+f];for(f+=h,i=p&(1<<-l)-1,p>>=-l,l+=s;l>0;i=256*i+e[t+f],f+=h,l-=8);for(a=i&(1<<-l)-1,i>>=-l,l+=r;l>0;a=256*a+e[t+f],f+=h,l-=8);if(0===i)i=1-c;else{if(i===u)return a?NaN:1/0*(p?-1:1);a+=Math.pow(2,r),i-=c}return(p?-1:1)*a*Math.pow(2,i-r)},t.write=function(e,t,n,r,o,i){var a,s,u,c=8*i-o-1,l=(1<>1,h=23===o?Math.pow(2,-24)-Math.pow(2,-77):0,p=r?0:i-1,d=r?1:-1,g=t<0||0===t&&1/t<0?1:0;for(t=Math.abs(t),isNaN(t)||t===1/0?(s=isNaN(t)?1:0,a=l):(a=Math.floor(Math.log(t)/Math.LN2),t*(u=Math.pow(2,-a))<1&&(a--,u*=2),(t+=a+f>=1?h/u:h*Math.pow(2,1-f))*u>=2&&(a++,u/=2),a+f>=l?(s=0,a=l):a+f>=1?(s=(t*u-1)*Math.pow(2,o),a+=f):(s=t*Math.pow(2,f-1)*Math.pow(2,o),a=0));o>=8;e[n+p]=255&s,p+=d,s/=256,o-=8);for(a=a<0;e[n+p]=255&a,p+=d,a/=256,c-=8);e[n+p-d]|=128*g}},function(e,t,n){"use strict";(function(t){ /*! * The buffer module from node.js, for the browser. * diff --git a/src/Components/Browser.JS/dist/Release/blazor.webassembly.js b/src/Components/Browser.JS/dist/Release/blazor.webassembly.js index d3a550249392..fc8845acbeee 100644 --- a/src/Components/Browser.JS/dist/Release/blazor.webassembly.js +++ b/src/Components/Browser.JS/dist/Release/blazor.webassembly.js @@ -1 +1 @@ -!function(e){var t={};function n(r){if(t[r])return t[r].exports;var o=t[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)n.d(r,o,function(t){return e[t]}.bind(null,o));return r},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=42)}([,,,,,,,,function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var r=n(23),o=n(9),a={};function i(e,t,n){var o=a[e];o||(o=a[e]=new r.BrowserRenderer(e)),o.attachRootComponentToLogicalElement(n,t)}t.attachRootComponentToLogicalElement=i,t.attachRootComponentToElement=function(e,t,n){var r=document.querySelector(t);if(!r)throw new Error("Could not find any element matching selector '"+t+"'.");i(e,o.toLogicalElement(r,!0),n)},t.renderBatch=function(e,t){var n=a[e];if(!n)throw new Error("There is no browser renderer with ID "+e+".");for(var r=t.arrayRangeReader,o=t.updatedComponents(),i=r.values(o),u=r.count(o),l=t.referenceFrames(),s=r.values(l),c=t.diffReader,f=0;f0&&!t)throw new Error("New logical elements must start empty, or allowExistingContents must be true");return e[r]=[],e}function u(e,t,n){var a=e;if(e instanceof Comment&&(s(a)&&s(a).length>0))throw new Error("Not implemented: inserting non-empty logical container");if(l(a))throw new Error("Not implemented: moving existing logical children");var i=s(t);if(n0;)e(r,0);var a=r;a.parentNode.removeChild(a)},t.getLogicalParent=l,t.getLogicalSiblingEnd=function(e){return e[a]||null},t.getLogicalChild=function(e,t){return s(e)[t]},t.isSvgElement=function(e){return"http://www.w3.org/2000/svg"===function(e){if(e instanceof Element)return e;if(e instanceof Comment)return e.parentNode;throw new Error("Not a valid logical element")}(e).namespaceURI},t.getLogicalChildrenArray=s,t.permuteLogicalChildren=function(e,t){var n=s(e);t.forEach(function(e){e.moveRangeStart=n[e.fromSiblingIndex],e.moveRangeEnd=function e(t){if(t instanceof Element)return t;var n=c(t);if(n)return n.previousSibling;var r=l(t);return r instanceof Element?r.lastChild:e(r)}(e.moveRangeStart)}),t.forEach(function(t){var r=t.moveToBeforeMarker=document.createComment("marker"),o=n[t.toSiblingIndex+1];o?o.parentNode.insertBefore(r,o):f(r,e)}),t.forEach(function(e){for(var t=e.moveToBeforeMarker,n=t.parentNode,r=e.moveRangeStart,o=e.moveRangeEnd,a=r;a;){var i=a.nextSibling;if(n.insertBefore(a,t),a===o)break;a=i}n.removeChild(t)}),t.forEach(function(e){n[e.toSiblingIndex]=e.moveRangeStart})}},,,function(e,t,n){"use strict";var r;!function(e){window.DotNet=e;var t=[],n={},r={},o=1,a=null;function i(e){t.push(e)}function u(e,t){for(var n=[],r=2;r0&&o[o.length-1])&&(6===a[0]||2===a[0])){i=0;continue}if(3===a[0]&&(!o||a[1]>o[0]&&a[1]0&&o[o.length-1])&&(6===a[0]||2===a[0])){i=0;continue}if(3===a[0]&&(!o||a[1]>o[0]&&a[1]0&&o[o.length-1])&&(6===a[0]||2===a[0])){i=0;continue}if(3===a[0]&&(!o||a[1]>o[0]&&a[1]0&&o[o.length-1])&&(6===a[0]||2===a[0])){i=0;continue}if(3===a[0]&&(!o||a[1]>o[0]&&a[1]-1?a.substring(0,u):"",s=u>-1?a.substring(u+1):a,c=t.monoPlatform.findMethod(e,l,s,i);t.monoPlatform.callMethod(c,null,r)},callMethod:function(e,n,r){if(r.length>4)throw new Error("Currently, MonoPlatform supports passing a maximum of 4 arguments from JS to .NET. You tried to pass "+r.length+".");var o=Module.stackSave();try{for(var a=Module.stackAlloc(r.length),u=Module.stackAlloc(4),l=0;l0&&!t)throw new Error("New logical elements must start empty, or allowExistingContents must be true");return e[r]=[],e}function u(e,t,n){var a=e;if(e instanceof Comment&&(s(a)&&s(a).length>0))throw new Error("Not implemented: inserting non-empty logical container");if(l(a))throw new Error("Not implemented: moving existing logical children");var i=s(t);if(n0;)e(r,0);var a=r;a.parentNode.removeChild(a)},t.getLogicalParent=l,t.getLogicalSiblingEnd=function(e){return e[a]||null},t.getLogicalChild=function(e,t){return s(e)[t]},t.isSvgElement=function(e){return"http://www.w3.org/2000/svg"===c(e).namespaceURI},t.getLogicalChildrenArray=s,t.permuteLogicalChildren=function(e,t){var n=s(e);t.forEach(function(e){e.moveRangeStart=n[e.fromSiblingIndex],e.moveRangeEnd=function e(t){if(t instanceof Element)return t;var n=f(t);if(n)return n.previousSibling;var r=l(t);return r instanceof Element?r.lastChild:e(r)}(e.moveRangeStart)}),t.forEach(function(t){var r=t.moveToBeforeMarker=document.createComment("marker"),o=n[t.toSiblingIndex+1];o?o.parentNode.insertBefore(r,o):d(r,e)}),t.forEach(function(e){for(var t=e.moveToBeforeMarker,n=t.parentNode,r=e.moveRangeStart,o=e.moveRangeEnd,a=r;a;){var i=a.nextSibling;if(n.insertBefore(a,t),a===o)break;a=i}n.removeChild(t)}),t.forEach(function(e){n[e.toSiblingIndex]=e.moveRangeStart})},t.getClosestDomElement=c},,,function(e,t,n){"use strict";var r;!function(e){window.DotNet=e;var t=[],n={},r={},o=1,a=null;function i(e){t.push(e)}function u(e,t){for(var n=[],r=2;r0&&o[o.length-1])&&(6===a[0]||2===a[0])){i=0;continue}if(3===a[0]&&(!o||a[1]>o[0]&&a[1]0&&o[o.length-1])&&(6===a[0]||2===a[0])){i=0;continue}if(3===a[0]&&(!o||a[1]>o[0]&&a[1]0&&o[o.length-1])&&(6===a[0]||2===a[0])){i=0;continue}if(3===a[0]&&(!o||a[1]>o[0]&&a[1]0&&o[o.length-1])&&(6===a[0]||2===a[0])){i=0;continue}if(3===a[0]&&(!o||a[1]>o[0]&&a[1]-1?a.substring(0,u):"",s=u>-1?a.substring(u+1):a,c=t.monoPlatform.findMethod(e,l,s,i);t.monoPlatform.callMethod(c,null,r)},callMethod:function(e,n,r){if(r.length>4)throw new Error("Currently, MonoPlatform supports passing a maximum of 4 arguments from JS to .NET. You tried to pass "+r.length+".");var o=Module.stackSave();try{for(var a=Module.stackAlloc(r.length),u=Module.stackAlloc(4),l=0;l Date: Tue, 7 May 2019 10:18:36 +0100 Subject: [PATCH 31/33] Tweak E2E test case --- .../test/testassets/BasicTestApp/ReorderingFocusComponent.razor | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/Components/test/testassets/BasicTestApp/ReorderingFocusComponent.razor b/src/Components/test/testassets/BasicTestApp/ReorderingFocusComponent.razor index 6ff9c1052c7e..d86e824aac97 100644 --- a/src/Components/test/testassets/BasicTestApp/ReorderingFocusComponent.razor +++ b/src/Components/test/testassets/BasicTestApp/ReorderingFocusComponent.razor @@ -37,6 +37,8 @@ new TodoItem { Id = 1, Text = "First" }, new TodoItem { Id = 2, Text = "Second" }, new TodoItem { Id = 3, Text = "Third" }, + new TodoItem { Id = 4, Text = "Fourth" }, + new TodoItem { Id = 5, Text = "Fifth" }, }; void Shuffle() From 9c4d46c0e92d6efaaa145fa268bd2ed9718d35ec Mon Sep 17 00:00:00 2001 From: Steve Sanderson Date: Tue, 7 May 2019 12:27:52 +0100 Subject: [PATCH 32/33] In client-side Blazor, prevent recursive event handler invocations --- .../src/RendererRegistryEventDispatcher.cs | 78 ++++++++++++++++++- 1 file changed, 75 insertions(+), 3 deletions(-) diff --git a/src/Components/Browser/src/RendererRegistryEventDispatcher.cs b/src/Components/Browser/src/RendererRegistryEventDispatcher.cs index 469a0dcae022..1ddc01f33590 100644 --- a/src/Components/Browser/src/RendererRegistryEventDispatcher.cs +++ b/src/Components/Browser/src/RendererRegistryEventDispatcher.cs @@ -2,6 +2,7 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System; +using System.Collections.Generic; using System.Threading.Tasks; using Microsoft.AspNetCore.Components.Rendering; using Microsoft.JSInterop; @@ -13,6 +14,10 @@ namespace Microsoft.AspNetCore.Components.Browser /// public static class RendererRegistryEventDispatcher { + private static bool isDispatchingEvent; + private static Queue deferredIncomingEvents + = new Queue(); + /// /// For framework use only. /// @@ -20,9 +25,62 @@ public static class RendererRegistryEventDispatcher public static Task DispatchEvent( BrowserEventDescriptor eventDescriptor, string eventArgsJson) { - var eventArgs = ParseEventArgsJson(eventDescriptor.EventArgsType, eventArgsJson); - var renderer = RendererRegistry.Current.Find(eventDescriptor.BrowserRendererId); - return renderer.DispatchEventAsync(eventDescriptor.EventHandlerId, eventArgs); + // Be sure we only run one event handler at once. Although they couldn't run + // simultaneously anyway (there's only one thread), they could run nested on + // the stack if somehow one event handler triggers another event synchronously. + // We need event handlers not to overlap because (a) that's consistent with + // server-side Blazor which uses a sync context, and (b) the rendering logic + // relies completely on the idea that within a given scope it's only building + // or processing one batch at a time. + // + // The only currently known case where this makes a difference is in the E2E + // tests in ReorderingFocusComponent, where we hit what seems like a Chrome bug + // where mutating the DOM cause an element's "change" to fire while its "input" + // handler is still running (i.e., nested on the stack) -- this doesn't happen + // in Firefox. Possibly a future version of Chrome may fix this, but even then, + // it's conceivable that DOM mutation events could trigger this too. + + if (isDispatchingEvent) + { + var info = new IncomingEventInfo(eventDescriptor, eventArgsJson); + deferredIncomingEvents.Enqueue(info); + return info.TaskCompletionSource.Task; + } + else + { + isDispatchingEvent = true; + try + { + var eventArgs = ParseEventArgsJson(eventDescriptor.EventArgsType, eventArgsJson); + var renderer = RendererRegistry.Current.Find(eventDescriptor.BrowserRendererId); + return renderer.DispatchEventAsync(eventDescriptor.EventHandlerId, eventArgs); + } + finally + { + isDispatchingEvent = false; + if (deferredIncomingEvents.Count > 0) + { + ProcessNextDeferredEvent(); + } + } + } + } + + private static void ProcessNextDeferredEvent() + { + var info = deferredIncomingEvents.Dequeue(); + var task = DispatchEvent(info.EventDescriptor, info.EventArgsJson); + task.ContinueWith(_ => + { + if (task.Exception != null) + { + info.TaskCompletionSource.SetException(task.Exception); + } + else + { + info.TaskCompletionSource.SetResult(null); + } + }); } private static UIEventArgs ParseEventArgsJson(string eventArgsType, string eventArgsJson) @@ -78,5 +136,19 @@ public class BrowserEventDescriptor /// public string EventArgsType { get; set; } } + + readonly struct IncomingEventInfo + { + public readonly BrowserEventDescriptor EventDescriptor; + public readonly string EventArgsJson; + public readonly TaskCompletionSource TaskCompletionSource; + + public IncomingEventInfo(BrowserEventDescriptor eventDescriptor, string eventArgsJson) + { + EventDescriptor = eventDescriptor; + EventArgsJson = eventArgsJson; + TaskCompletionSource = new TaskCompletionSource(); + } + } } } From a045b8f54948ccfd3cd22274f5de0df8dc025818 Mon Sep 17 00:00:00 2001 From: Steve Sanderson Date: Tue, 7 May 2019 13:14:01 +0100 Subject: [PATCH 33/33] Actual E2E tests for moving form elements --- src/Components/test/E2ETest/Tests/KeyTest.cs | 70 +++++++++++++++++++ .../ReorderingFocusComponent.razor | 8 +-- 2 files changed, 74 insertions(+), 4 deletions(-) diff --git a/src/Components/test/E2ETest/Tests/KeyTest.cs b/src/Components/test/E2ETest/Tests/KeyTest.cs index c54ae1a3b223..32f3ad5e3f69 100644 --- a/src/Components/test/E2ETest/Tests/KeyTest.cs +++ b/src/Components/test/E2ETest/Tests/KeyTest.cs @@ -2,13 +2,16 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System; +using System.Collections.Generic; using System.Linq; +using System.Threading.Tasks; using BasicTestApp; using Microsoft.AspNetCore.Components.E2ETest.Infrastructure; using Microsoft.AspNetCore.Components.E2ETest.Infrastructure.ServerFixtures; using Microsoft.AspNetCore.E2ETesting; using Microsoft.JSInterop; using OpenQA.Selenium; +using OpenQA.Selenium.Interactions; using Xunit; using Xunit.Abstractions; @@ -203,6 +206,73 @@ public void CanReorderInsertDeleteAndEdit_WithAndWithoutKeys() }); } + [Fact] + public async Task CanRetainFocusWhileMovingTextBox() + { + var appElem = MountTestComponent(); + Func textboxFinder = () => appElem.FindElement(By.CssSelector(".incomplete-items .item-1 input[type=text]")); + var textToType = "Hello this is a long string that should be typed"; + var expectedTextTyped = ""; + + textboxFinder().Clear(); + + // On each keystroke, the boxes will be shuffled. The text will only + // be inserted correctly if focus is retained. + textboxFinder().Click(); + while (textToType.Length > 0) + { + var nextBlockLength = Math.Min(5, textToType.Length); + var nextBlock = textToType.Substring(0, nextBlockLength); + textToType = textToType.Substring(nextBlockLength); + expectedTextTyped += nextBlock; + + // Send keys to whatever has focus + new Actions(Browser).SendKeys(nextBlock).Perform(); + Browser.Equal(expectedTextTyped, () => textboxFinder().GetAttribute("value")); + + // We delay between typings to ensure the events aren't all collapsed into one. + await Task.Delay(100); + } + + // Verify that after all this, we can still move the edited item + // This was broken originally because of unexpected event-handling behavior + // in Chrome (it raised events recursively) + appElem.FindElement( + By.CssSelector(".incomplete-items .item-1 input[type=checkbox]")).Click(); + Browser.Equal(expectedTextTyped, () => appElem + .FindElement(By.CssSelector(".complete-items .item-1 input[type=text]")) + .GetAttribute("value")); + } + + [Fact] + public void CanUpdateCheckboxStateWhileMovingIt() + { + var appElem = MountTestComponent(); + Func checkboxFinder = () => appElem.FindElement(By.CssSelector(".item-2 input[type=checkbox]")); + Func> incompleteItemStates = () => appElem + .FindElements(By.CssSelector(".incomplete-items input[type=checkbox]")) + .Select(elem => elem.Selected); + Func> completeItemStates = () => appElem + .FindElements(By.CssSelector(".complete-items input[type=checkbox]")) + .Select(elem => elem.Selected); + + // Verify initial state + Browser.Equal(new[] { false, false, false, false, false }, incompleteItemStates); + Browser.Equal(Array.Empty(), completeItemStates); + + // Check a box; see it moves and becomes the sole checked item + checkboxFinder().Click(); + Browser.True(() => checkboxFinder().Selected); + Browser.Equal(new[] { false, false, false, false }, incompleteItemStates); + Browser.Equal(new[] { true }, completeItemStates); + + // Also uncheck it; see it moves and becomes unchecked + checkboxFinder().Click(); + Browser.False(() => checkboxFinder().Selected); + Browser.Equal(new[] { false, false, false, false, false }, incompleteItemStates); + Browser.Equal(Array.Empty(), completeItemStates); + } + private void PerformTest(Node[] before, Node[] after) { var rootBefore = new Node(null, "root", before); diff --git a/src/Components/test/testassets/BasicTestApp/ReorderingFocusComponent.razor b/src/Components/test/testassets/BasicTestApp/ReorderingFocusComponent.razor index d86e824aac97..acede2b46572 100644 --- a/src/Components/test/testassets/BasicTestApp/ReorderingFocusComponent.razor +++ b/src/Components/test/testassets/BasicTestApp/ReorderingFocusComponent.razor @@ -11,9 +11,9 @@
    @foreach (var item in todoItems.Where(item => !item.IsDone)) { -
  • +
  • - +
  • }
@@ -23,9 +23,9 @@
    @foreach (var item in todoItems.Where(item => item.IsDone)) { -
  • +
  • - +
  • }