From e95264f2370115bc452890c3d371bb9f7fa4a521 Mon Sep 17 00:00:00 2001 From: Steve Sanderson Date: Thu, 16 Apr 2020 12:14:54 +0100 Subject: [PATCH] Support overriding how boot resources are loaded. Fixes #5462 --- .../Web.JS/dist/Release/blazor.webassembly.js | 2 +- src/Components/Web.JS/src/Boot.Server.ts | 6 +-- src/Components/Web.JS/src/Boot.WebAssembly.ts | 5 +- ...lazorOptions.ts => CircuitStartOptions.ts} | 6 +-- .../Circuits/DefaultReconnectionHandler.ts | 2 +- .../Web.JS/src/Platform/Mono/MonoPlatform.ts | 30 +++++++++--- .../src/Platform/WebAssemblyResourceLoader.ts | 47 +++++++++++++------ .../src/Platform/WebAssemblyStartOptions.ts | 17 +++++++ .../HostedInAspNet.Client/wwwroot/index.html | 16 ++++++- ...equestLog.cs => BootResourceRequestLog.cs} | 2 +- .../HostedInAspNet.Server/Startup.cs | 14 ++++-- .../E2ETest/Tests/BootResourceCachingTest.cs | 6 ++- 12 files changed, 114 insertions(+), 39 deletions(-) rename src/Components/Web.JS/src/Platform/Circuits/{BlazorOptions.ts => CircuitStartOptions.ts} (85%) create mode 100644 src/Components/Web.JS/src/Platform/WebAssemblyStartOptions.ts rename src/Components/WebAssembly/testassets/HostedInAspNet.Server/{RequestLog.cs => BootResourceRequestLog.cs} (94%) diff --git a/src/Components/Web.JS/dist/Release/blazor.webassembly.js b/src/Components/Web.JS/dist/Release/blazor.webassembly.js index 508484ddbf..dcfe4e842d 100644 --- a/src/Components/Web.JS/dist/Release/blazor.webassembly.js +++ b/src/Components/Web.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=54)}([,,,,,,,,function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),n(30),n(23);var r=n(31),o=n(18),i={},a=!1;function u(e,t,n){var o=i[e];o||(o=i[e]=new r.BrowserRenderer(e)),o.attachRootComponentToLogicalElement(n,t)}t.attachRootComponentToLogicalElement=u,t.attachRootComponentToElement=function(e,t,n){var r=document.querySelector(e);if(!r)throw new Error("Could not find any element matching selector '"+e+"'.");u(n||0,o.toLogicalElement(r,!0),t)},t.renderBatch=function(e,t){var n=i[e];if(!n)throw new Error("There is no browser renderer with ID "+e+".");for(var r=t.arrayRangeReader,o=t.updatedComponents(),u=r.values(o),s=r.count(o),c=t.referenceFrames(),l=r.values(c),f=t.diffReader,d=0;d0&&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&&!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 i=e;if(e instanceof Comment&&(c(i)&&c(i).length>0))throw new Error("Not implemented: inserting non-empty logical container");if(s(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=s,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=s(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,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;!function(e){window.DotNet=e;var t=[],n={},r={},o=1,i=null;function a(e){t.push(e)}function u(e,t,n,r){var o=c();if(o.invokeDotNetFromJS){var i=JSON.stringify(r,m),a=o.invokeDotNetFromJS(e,t,n,i);return a?f(a):null}throw new Error("The current dispatcher does not support synchronous calls from JS to .NET. Use invokeMethodAsync instead.")}function s(e,t,r,i){if(e&&r)throw new Error("For instance method calls, assemblyName should be null. Received '"+e+"'.");var a=o++,u=new Promise((function(e,t){n[a]={resolve:e,reject:t}}));try{var s=JSON.stringify(i,m);c().beginInvokeDotNetFromJS(a,e,t,r,s)}catch(e){l(a,!1,e)}return u}function c(){if(null!==i)return i;throw new Error("No .NET call dispatcher has been set.")}function l(e,t,r){if(!n.hasOwnProperty(e))throw new Error("There is no pending async call with ID "+e+".");var o=n[e];delete n[e],t?o.resolve(r):o.reject(r)}function f(e){return e?JSON.parse(e,(function(e,n){return t.reduce((function(t,n){return n(e,t)}),n)})):null}function d(e){return e instanceof Error?e.message+"\n"+e.stack:e?e.toString():"null"}function p(e){if(r.hasOwnProperty(e))return r[e];var t,n=window,o="window";if(e.split(".").forEach((function(e){if(!(e in n))throw new Error("Could not find '"+e+"' in '"+o+"'.");t=n,n=n[e],o+="."+e})),n instanceof Function)return n=n.bind(t),r[e]=n,n;throw new Error("The value '"+o+"' is not a function.")}e.attachDispatcher=function(e){i=e},e.attachReviver=a,e.invokeMethod=function(e,t){for(var n=[],r=2;r0&&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)}t.readInt32LE=function(e,t){return e[t]|e[t+1]<<8|e[t+2]<<16|e[t+3]<<24},t.readUint32LE=i,t.readUint64LE=function(e,t){var n=i(e,t+4);if(n>o)throw new Error("Cannot read uint64 with high order part "+n+", because the result would exceed Number.MAX_SAFE_INTEGER.");return n*r+i(e,t)},t.readLEB128=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}),t.shouldAutoStart=function(){return!(!document||!document.currentScript||"false"===document.currentScript.getAttribute("autostart"))}},,,,,,,,,,,,,,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{s(r.next(e))}catch(e){i(e)}}function u(e){try{s(r.throw(e))}catch(e){i(e)}}function s(e){var t;e.done?o(e.value):(t=e.value,t instanceof n?t:new n((function(e){e(t)}))).then(a,u)}s((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:u(0),throw:u(1),return:u(2)},"function"==typeof Symbol&&(i[Symbol.iterator]=function(){return this}),i;function u(i){return function(u){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=a.trys,(o=o.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)&&!(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}),n(22),n(29);var a=n(23),u=n(55),s=n(8),c=n(58),l=n(40),f=n(24),d=n(59),p=n(60),h=n(61),m=!1;function v(e){return r(this,void 0,void 0,(function(){var e,t,n,l,v,y=this;return o(this,(function(b){switch(b.label){case 0:if(m)throw new Error("Blazor has already started.");return m=!0,f.setEventDispatcher((function(e,t){return DotNet.invokeMethodAsync("Microsoft.AspNetCore.Components.WebAssembly","DispatchEvent",e,JSON.stringify(t))})),e=a.setPlatform(u.monoPlatform),window.Blazor.platform=e,window.Blazor._internal.renderBatch=function(e,t){s.renderBatch(e,new c.SharedMemoryRenderBatch(t))},window.Blazor._internal.navigationManager.listenForNavigationEvents((function(e,t){return r(y,void 0,void 0,(function(){return o(this,(function(n){switch(n.label){case 0:return[4,DotNet.invokeMethodAsync("Microsoft.AspNetCore.Components.WebAssembly","NotifyLocationChanged",e,t)];case 1:return n.sent(),[2]}}))}))})),[4,h.BootConfigResult.initAsync()];case 1:return t=b.sent(),[4,Promise.all([d.WebAssemblyResourceLoader.initAsync(t.bootConfig),p.WebAssemblyConfigLoader.initAsync(t)])];case 2:n=i.apply(void 0,[b.sent(),1]),l=n[0],b.label=3;case 3:return b.trys.push([3,5,,6]),[4,e.start(l)];case 4:return b.sent(),[3,6];case 5:throw v=b.sent(),new Error("Failed to start platform. Reason: "+v);case 6:return e.callEntryPoint(l.bootConfig.entryAssembly),[2]}}))}))}window.Blazor.start=v,l.shouldAutoStart()&&v().catch((function(e){"undefined"!=typeof Module&&Module.printErr?Module.printErr(e):console.error(e)}))},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{s(r.next(e))}catch(e){i(e)}}function u(e){try{s(r.throw(e))}catch(e){i(e)}}function s(e){var t;e.done?o(e.value):(t=e.value,t instanceof n?t:new n((function(e){e(t)}))).then(a,u)}s((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:u(0),throw:u(1),return:u(2)},"function"==typeof Symbol&&(i[Symbol.iterator]=function(){return this}),i;function u(i){return function(u){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=a.trys,(o=o.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]>2]}t.monoPlatform={start:function(e){return new Promise((function(t,n){var c,l;a.attachDebuggerHotkey(e),window.Browser={init:function(){}},c=function(){window.Module=function(e,t,n){var c=this,l=e.bootConfig.resources,f=window.Module||{},p=["DEBUGGING ENABLED"];f.print=function(e){return p.indexOf(e)<0&&console.log(e)},f.printErr=function(e){console.error(e),u.showErrorNotification()},f.preRun=f.preRun||[],f.postRun=f.postRun||[],f.preloadPlugins=[];var v,y=e.loadResources(l.assembly,(function(e){return"_framework/_bin/"+e})),b=e.loadResources(l.pdb||{},(function(e){return"_framework/_bin/"+e})),g=e.loadResource("dotnet.wasm","_framework/wasm/dotnet.wasm",e.bootConfig.resources.runtime["dotnet.wasm"]);return e.bootConfig.resources.runtime.hasOwnProperty("dotnet.timezones.dat")&&(v=e.loadResource("dotnet.timezones.dat","_framework/wasm/dotnet.timezones.dat",e.bootConfig.resources.runtime["dotnet.timezones.dat"])),f.instantiateWasm=function(e,t){return r(c,void 0,void 0,(function(){var n,r;return o(this,(function(o){switch(o.label){case 0:return o.trys.push([0,3,,4]),[4,g];case 1:return[4,m(o.sent(),e)];case 2:return n=o.sent(),[3,4];case 3:throw r=o.sent(),f.printErr(r),r;case 4:return t(n),[2]}}))})),[]},f.preRun.push((function(){i=cwrap("mono_wasm_add_assembly",null,["string","number","number"]),cwrap("mono_wasm_string_get_utf8","number",["number"]),MONO.loaded_files=[],v&&function(e){r(this,void 0,void 0,(function(){var t,n;return o(this,(function(r){switch(r.label){case 0:return t="blazor:timezonedata",addRunDependency(t),[4,e.response];case 1:return[4,r.sent().arrayBuffer()];case 2:return n=r.sent(),s.loadTimezoneData(n),removeRunDependency(t),[2]}}))}))}(v),y.forEach((function(e){return w(e,function(e,t){var n=e.lastIndexOf(".");if(n<0)throw new Error("No extension to replace in '"+e+"'");return e.substr(0,n)+t}(e.name,".dll"))})),b.forEach((function(e){return w(e,e.name)})),window.Blazor._internal.getSatelliteAssemblies=function(t){var n=BINDING.mono_array_to_js_array(t),i=e.bootConfig.resources.satelliteResources;if(i){var a=Promise.all(n.filter((function(e){return i.hasOwnProperty(e)})).map((function(t){return e.loadResources(i[t],(function(e){return"_framework/_bin/"+e}))})).reduce((function(e,t){return e.concat(t)}),new Array).map((function(e){return r(c,void 0,void 0,(function(){return o(this,(function(t){switch(t.label){case 0:return[4,e.response];case 1:return[2,t.sent().arrayBuffer()]}}))}))})));return BINDING.js_to_mono_obj(a.then((function(e){return e.length&&(window.Blazor._internal.readSatelliteAssemblies=function(){for(var t=BINDING.mono_obj_array_new(e.length),n=0;n>1];var n},readInt32Field:function(e,t){return f(e+(t||0))},readUint64Field:function(e,t){return function(e){var t=e>>2,n=Module.HEAPU32[t+1];if(n>l)throw new Error("Cannot read uint64 with high order part "+n+", because the result would exceed Number.MAX_SAFE_INTEGER.");return n*c+Module.HEAPU32[t]}(e+(t||0))},readFloatField:function(e,t){return n=e+(t||0),Module.HEAPF32[n>>2];var n},readObjectField:function(e,t){return f(e+(t||0))},readStringField:function(e,t,n){var r=f(e+(t||0));if(0===r)return null;if(n){var o=BINDING.unbox_mono_obj(r);return"boolean"==typeof o?o?"":null:o}return BINDING.conv_string(r)},readStructField:function(e,t){return e+(t||0)}};var d=document.createElement("a");function p(e){return e+12}function h(e,t,n){var r="["+e+"] "+t+":"+n;return BINDING.bind_static_method(r)}function m(e,t){return r(this,void 0,void 0,(function(){var n,r;return o(this,(function(o){switch(o.label){case 0:if("function"!=typeof WebAssembly.instantiateStreaming)return[3,4];o.label=1;case 1:return o.trys.push([1,3,,4]),[4,WebAssembly.instantiateStreaming(e.response,t)];case 2:return[2,o.sent().instance];case 3:return n=o.sent(),console.info("Streaming compilation failed. Falling back to ArrayBuffer instantiation. ",n),[3,4];case 4:return[4,e.response.then((function(e){return e.arrayBuffer()}))];case 5:return r=o.sent(),[4,WebAssembly.instantiate(r,t)];case 6:return[2,o.sent().instance]}}))}))}},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var r=window.chrome&&navigator.userAgent.indexOf("Edge")<0,o=!1;function i(){return o&&r}t.hasDebuggingEnabled=i,t.attachDebuggerHotkey=function(e){var t=navigator.platform.match(/^Mac/i)?"Cmd":"Alt";i()&&console.info("Debugging hotkey: Shift+"+t+"+D (when application has focus)"),o=!!e.bootConfig.resources.pdb,document.addEventListener("keydown",(function(e){var t;e.shiftKey&&(e.metaKey||e.altKey)&&"KeyD"===e.code&&(o?r?((t=document.createElement("a")).href="_framework/debug?url="+encodeURIComponent(location.href),t.target="_blank",t.rel="noopener noreferrer",t.click()):console.error("Currently, only Edge(Chromium) or Chrome is supported for debugging."):console.error("Cannot start debugging, because the application was not compiled with debugging enabled."))}))}},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{s(r.next(e))}catch(e){i(e)}}function u(e){try{s(r.throw(e))}catch(e){i(e)}}function s(e){var t;e.done?o(e.value):(t=e.value,t instanceof n?t:new n((function(e){e(t)}))).then(a,u)}s((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:u(0),throw:u(1),return:u(2)},"function"==typeof Symbol&&(i[Symbol.iterator]=function(){return this}),i;function u(i){return function(u){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=a.trys,(o=o.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[r++],done:!e}}};throw new TypeError(t?"Object is not iterable.":"Symbol.iterator is not defined.")},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 u=n(38),s=n(39);t.loadTimezoneData=function(e){return r(this,void 0,void 0,(function(){var t,n,r,c,l,f,d,p,h,m,v,y;return o(this,(function(o){t=new Uint8Array(e),n=u.readInt32LE(t,0),t=t.slice(4),r=s.decodeUtf8(t.slice(0,n)),c=JSON.parse(r),t=t.slice(n),Module.FS_createPath("/","zoneinfo",!0,!0),new Set(c.map((function(e){return e[0].split("/")[0]}))).forEach((function(e){return Module.FS_createPath("/zoneinfo",e,!0,!0)}));try{for(l=i(c),f=l.next();!f.done;f=l.next())d=a(f.value,2),p=d[0],h=d[1],m=new Uint8Array(t.slice(0,h)),Module.FS_createDataFile("/zoneinfo/"+p,null,m,!0,!0,!0),t=t.slice(h)}catch(e){v={error:e}}finally{try{f&&!f.done&&(y=l.return)&&y.call(l)}finally{if(v)throw v.error}}return[2]}))}))}},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var r=n(23),o=function(){function e(e){this.batchAddress=e,this.arrayRangeReader=i,this.arrayBuilderSegmentReader=a,this.diffReader=u,this.editReader=s,this.frameReader=c}return e.prototype.updatedComponents=function(){return r.platform.readStructField(this.batchAddress,0)},e.prototype.referenceFrames=function(){return r.platform.readStructField(this.batchAddress,i.structLength)},e.prototype.disposedComponentIds=function(){return r.platform.readStructField(this.batchAddress,2*i.structLength)},e.prototype.disposedEventHandlerIds=function(){return r.platform.readStructField(this.batchAddress,3*i.structLength)},e.prototype.updatedComponentsEntry=function(e,t){return l(e,t,u.structLength)},e.prototype.referenceFramesEntry=function(e,t){return l(e,t,c.structLength)},e.prototype.disposedComponentIdsEntry=function(e,t){var n=l(e,t,4);return r.platform.readInt32Field(n)},e.prototype.disposedEventHandlerIdsEntry=function(e,t){var n=l(e,t,8);return r.platform.readUint64Field(n)},e}();t.SharedMemoryRenderBatch=o;var i={structLength:8,values:function(e){return r.platform.readObjectField(e,0)},count:function(e){return r.platform.readInt32Field(e,4)}},a={structLength:12,values:function(e){var t=r.platform.readObjectField(e,0),n=r.platform.getObjectFieldsBaseAddress(t);return r.platform.readObjectField(n,0)},offset:function(e){return r.platform.readInt32Field(e,4)},count:function(e){return r.platform.readInt32Field(e,8)}},u={structLength:4+a.structLength,componentId:function(e){return r.platform.readInt32Field(e,0)},edits:function(e){return r.platform.readStructField(e,4)},editsEntry:function(e,t){return l(e,t,s.structLength)}},s={structLength:20,editType:function(e){return r.platform.readInt32Field(e,0)},siblingIndex:function(e){return r.platform.readInt32Field(e,4)},newTreeIndex:function(e){return r.platform.readInt32Field(e,8)},moveToSiblingIndex:function(e){return r.platform.readInt32Field(e,8)},removedAttributeName:function(e){return r.platform.readStringField(e,16)}},c={structLength:36,frameType:function(e){return r.platform.readInt16Field(e,4)},subtreeLength:function(e){return r.platform.readInt32Field(e,8)},elementReferenceCaptureId:function(e){return r.platform.readStringField(e,16)},componentId:function(e){return r.platform.readInt32Field(e,12)},elementName:function(e){return r.platform.readStringField(e,16)},textContent:function(e){return r.platform.readStringField(e,16)},markupContent:function(e){return r.platform.readStringField(e,16)},attributeName:function(e){return r.platform.readStringField(e,16)},attributeValue:function(e){return r.platform.readStringField(e,24,!0)},attributeEventHandlerId:function(e){return r.platform.readUint64Field(e,8)}};function l(e,t,n){return r.platform.getArrayEntryPtr(e,t,n)}},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{s(r.next(e))}catch(e){i(e)}}function u(e){try{s(r.throw(e))}catch(e){i(e)}}function s(e){var t;e.done?o(e.value):(t=e.value,t instanceof n?t:new n((function(e){e(t)}))).then(a,u)}s((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:u(0),throw:u(1),return:u(2)},"function"==typeof Symbol&&(i[Symbol.iterator]=function(){return this}),i;function u(i){return function(u){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=a.trys,(o=o.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&&!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 i=e;if(e instanceof Comment&&(c(i)&&c(i).length>0))throw new Error("Not implemented: inserting non-empty logical container");if(s(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=s,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=s(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,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;!function(e){window.DotNet=e;var t=[],n={},r={},o=1,i=null;function a(e){t.push(e)}function u(e,t,n,r){var o=c();if(o.invokeDotNetFromJS){var i=JSON.stringify(r,m),a=o.invokeDotNetFromJS(e,t,n,i);return a?f(a):null}throw new Error("The current dispatcher does not support synchronous calls from JS to .NET. Use invokeMethodAsync instead.")}function s(e,t,r,i){if(e&&r)throw new Error("For instance method calls, assemblyName should be null. Received '"+e+"'.");var a=o++,u=new Promise((function(e,t){n[a]={resolve:e,reject:t}}));try{var s=JSON.stringify(i,m);c().beginInvokeDotNetFromJS(a,e,t,r,s)}catch(e){l(a,!1,e)}return u}function c(){if(null!==i)return i;throw new Error("No .NET call dispatcher has been set.")}function l(e,t,r){if(!n.hasOwnProperty(e))throw new Error("There is no pending async call with ID "+e+".");var o=n[e];delete n[e],t?o.resolve(r):o.reject(r)}function f(e){return e?JSON.parse(e,(function(e,n){return t.reduce((function(t,n){return n(e,t)}),n)})):null}function d(e){return e instanceof Error?e.message+"\n"+e.stack:e?e.toString():"null"}function p(e){if(r.hasOwnProperty(e))return r[e];var t,n=window,o="window";if(e.split(".").forEach((function(e){if(!(e in n))throw new Error("Could not find '"+e+"' in '"+o+"'.");t=n,n=n[e],o+="."+e})),n instanceof Function)return n=n.bind(t),r[e]=n,n;throw new Error("The value '"+o+"' is not a function.")}e.attachDispatcher=function(e){i=e},e.attachReviver=a,e.invokeMethod=function(e,t){for(var n=[],r=2;r0&&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)}t.readInt32LE=function(e,t){return e[t]|e[t+1]<<8|e[t+2]<<16|e[t+3]<<24},t.readUint32LE=i,t.readUint64LE=function(e,t){var n=i(e,t+4);if(n>o)throw new Error("Cannot read uint64 with high order part "+n+", because the result would exceed Number.MAX_SAFE_INTEGER.");return n*r+i(e,t)},t.readLEB128=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}),t.shouldAutoStart=function(){return!(!document||!document.currentScript||"false"===document.currentScript.getAttribute("autostart"))}},,,,,,,,,,,,,,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{s(r.next(e))}catch(e){i(e)}}function u(e){try{s(r.throw(e))}catch(e){i(e)}}function s(e){var t;e.done?o(e.value):(t=e.value,t instanceof n?t:new n((function(e){e(t)}))).then(a,u)}s((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:u(0),throw:u(1),return:u(2)},"function"==typeof Symbol&&(i[Symbol.iterator]=function(){return this}),i;function u(i){return function(u){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=a.trys,(o=o.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)&&!(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}),n(22),n(29);var a=n(23),u=n(55),s=n(8),c=n(58),l=n(40),f=n(24),d=n(59),p=n(60),h=n(61),m=!1;function v(e){return r(this,void 0,void 0,(function(){var t,n,l,v,y,b=this;return o(this,(function(g){switch(g.label){case 0:if(m)throw new Error("Blazor has already started.");return m=!0,f.setEventDispatcher((function(e,t){return DotNet.invokeMethodAsync("Microsoft.AspNetCore.Components.WebAssembly","DispatchEvent",e,JSON.stringify(t))})),t=a.setPlatform(u.monoPlatform),window.Blazor.platform=t,window.Blazor._internal.renderBatch=function(e,t){s.renderBatch(e,new c.SharedMemoryRenderBatch(t))},window.Blazor._internal.navigationManager.listenForNavigationEvents((function(e,t){return r(b,void 0,void 0,(function(){return o(this,(function(n){switch(n.label){case 0:return[4,DotNet.invokeMethodAsync("Microsoft.AspNetCore.Components.WebAssembly","NotifyLocationChanged",e,t)];case 1:return n.sent(),[2]}}))}))})),[4,h.BootConfigResult.initAsync()];case 1:return n=g.sent(),[4,Promise.all([d.WebAssemblyResourceLoader.initAsync(n.bootConfig,e||{}),p.WebAssemblyConfigLoader.initAsync(n)])];case 2:l=i.apply(void 0,[g.sent(),1]),v=l[0],g.label=3;case 3:return g.trys.push([3,5,,6]),[4,t.start(v)];case 4:return g.sent(),[3,6];case 5:throw y=g.sent(),new Error("Failed to start platform. Reason: "+y);case 6:return t.callEntryPoint(v.bootConfig.entryAssembly),[2]}}))}))}window.Blazor.start=v,l.shouldAutoStart()&&v().catch((function(e){"undefined"!=typeof Module&&Module.printErr?Module.printErr(e):console.error(e)}))},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{s(r.next(e))}catch(e){i(e)}}function u(e){try{s(r.throw(e))}catch(e){i(e)}}function s(e){var t;e.done?o(e.value):(t=e.value,t instanceof n?t:new n((function(e){e(t)}))).then(a,u)}s((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:u(0),throw:u(1),return:u(2)},"function"==typeof Symbol&&(i[Symbol.iterator]=function(){return this}),i;function u(i){return function(u){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=a.trys,(o=o.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]>2]}t.monoPlatform={start:function(e){return new Promise((function(t,n){var c,l;a.attachDebuggerHotkey(e),window.Browser={init:function(){}},c=function(){window.Module=function(e,t,n){var c=this,l=e.bootConfig.resources,f=window.Module||{},p=["DEBUGGING ENABLED"];f.print=function(e){return p.indexOf(e)<0&&console.log(e)},f.printErr=function(e){console.error(e),u.showErrorNotification()},f.preRun=f.preRun||[],f.postRun=f.postRun||[],f.preloadPlugins=[];var v,y=e.loadResources(l.assembly,(function(e){return"_framework/_bin/"+e}),"assembly"),b=e.loadResources(l.pdb||{},(function(e){return"_framework/_bin/"+e}),"pdb"),g=e.loadResource("dotnet.wasm","_framework/wasm/dotnet.wasm",e.bootConfig.resources.runtime["dotnet.wasm"],"dotnetwasm");return e.bootConfig.resources.runtime.hasOwnProperty("dotnet.timezones.dat")&&(v=e.loadResource("dotnet.timezones.dat","_framework/wasm/dotnet.timezones.dat",e.bootConfig.resources.runtime["dotnet.timezones.dat"],"timezonedata")),f.instantiateWasm=function(e,t){return r(c,void 0,void 0,(function(){var n,r;return o(this,(function(o){switch(o.label){case 0:return o.trys.push([0,3,,4]),[4,g];case 1:return[4,m(o.sent(),e)];case 2:return n=o.sent(),[3,4];case 3:throw r=o.sent(),f.printErr(r),r;case 4:return t(n),[2]}}))})),[]},f.preRun.push((function(){i=cwrap("mono_wasm_add_assembly",null,["string","number","number"]),cwrap("mono_wasm_string_get_utf8","number",["number"]),MONO.loaded_files=[],v&&function(e){r(this,void 0,void 0,(function(){var t,n;return o(this,(function(r){switch(r.label){case 0:return t="blazor:timezonedata",addRunDependency(t),[4,e.response];case 1:return[4,r.sent().arrayBuffer()];case 2:return n=r.sent(),s.loadTimezoneData(n),removeRunDependency(t),[2]}}))}))}(v),y.forEach((function(e){return w(e,function(e,t){var n=e.lastIndexOf(".");if(n<0)throw new Error("No extension to replace in '"+e+"'");return e.substr(0,n)+t}(e.name,".dll"))})),b.forEach((function(e){return w(e,e.name)})),window.Blazor._internal.getSatelliteAssemblies=function(t){var n=BINDING.mono_array_to_js_array(t),i=e.bootConfig.resources.satelliteResources;if(i){var a=Promise.all(n.filter((function(e){return i.hasOwnProperty(e)})).map((function(t){return e.loadResources(i[t],(function(e){return"_framework/_bin/"+e}),"assembly")})).reduce((function(e,t){return e.concat(t)}),new Array).map((function(e){return r(c,void 0,void 0,(function(){return o(this,(function(t){switch(t.label){case 0:return[4,e.response];case 1:return[2,t.sent().arrayBuffer()]}}))}))})));return BINDING.js_to_mono_obj(a.then((function(e){return e.length&&(window.Blazor._internal.readSatelliteAssemblies=function(){for(var t=BINDING.mono_obj_array_new(e.length),n=0;n>1];var n},readInt32Field:function(e,t){return f(e+(t||0))},readUint64Field:function(e,t){return function(e){var t=e>>2,n=Module.HEAPU32[t+1];if(n>l)throw new Error("Cannot read uint64 with high order part "+n+", because the result would exceed Number.MAX_SAFE_INTEGER.");return n*c+Module.HEAPU32[t]}(e+(t||0))},readFloatField:function(e,t){return n=e+(t||0),Module.HEAPF32[n>>2];var n},readObjectField:function(e,t){return f(e+(t||0))},readStringField:function(e,t,n){var r=f(e+(t||0));if(0===r)return null;if(n){var o=BINDING.unbox_mono_obj(r);return"boolean"==typeof o?o?"":null:o}return BINDING.conv_string(r)},readStructField:function(e,t){return e+(t||0)}};var d=document.createElement("a");function p(e){return e+12}function h(e,t,n){var r="["+e+"] "+t+":"+n;return BINDING.bind_static_method(r)}function m(e,t){return r(this,void 0,void 0,(function(){var n,r;return o(this,(function(o){switch(o.label){case 0:if("function"!=typeof WebAssembly.instantiateStreaming)return[3,4];o.label=1;case 1:return o.trys.push([1,3,,4]),[4,WebAssembly.instantiateStreaming(e.response,t)];case 2:return[2,o.sent().instance];case 3:return n=o.sent(),console.info("Streaming compilation failed. Falling back to ArrayBuffer instantiation. ",n),[3,4];case 4:return[4,e.response.then((function(e){return e.arrayBuffer()}))];case 5:return r=o.sent(),[4,WebAssembly.instantiate(r,t)];case 6:return[2,o.sent().instance]}}))}))}},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var r=window.chrome&&navigator.userAgent.indexOf("Edge")<0,o=!1;function i(){return o&&r}t.hasDebuggingEnabled=i,t.attachDebuggerHotkey=function(e){var t=navigator.platform.match(/^Mac/i)?"Cmd":"Alt";i()&&console.info("Debugging hotkey: Shift+"+t+"+D (when application has focus)"),o=!!e.bootConfig.resources.pdb,document.addEventListener("keydown",(function(e){var t;e.shiftKey&&(e.metaKey||e.altKey)&&"KeyD"===e.code&&(o?r?((t=document.createElement("a")).href="_framework/debug?url="+encodeURIComponent(location.href),t.target="_blank",t.rel="noopener noreferrer",t.click()):console.error("Currently, only Edge(Chromium) or Chrome is supported for debugging."):console.error("Cannot start debugging, because the application was not compiled with debugging enabled."))}))}},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{s(r.next(e))}catch(e){i(e)}}function u(e){try{s(r.throw(e))}catch(e){i(e)}}function s(e){var t;e.done?o(e.value):(t=e.value,t instanceof n?t:new n((function(e){e(t)}))).then(a,u)}s((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:u(0),throw:u(1),return:u(2)},"function"==typeof Symbol&&(i[Symbol.iterator]=function(){return this}),i;function u(i){return function(u){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=a.trys,(o=o.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[r++],done:!e}}};throw new TypeError(t?"Object is not iterable.":"Symbol.iterator is not defined.")},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 u=n(38),s=n(39);t.loadTimezoneData=function(e){return r(this,void 0,void 0,(function(){var t,n,r,c,l,f,d,p,h,m,v,y;return o(this,(function(o){t=new Uint8Array(e),n=u.readInt32LE(t,0),t=t.slice(4),r=s.decodeUtf8(t.slice(0,n)),c=JSON.parse(r),t=t.slice(n),Module.FS_createPath("/","zoneinfo",!0,!0),new Set(c.map((function(e){return e[0].split("/")[0]}))).forEach((function(e){return Module.FS_createPath("/zoneinfo",e,!0,!0)}));try{for(l=i(c),f=l.next();!f.done;f=l.next())d=a(f.value,2),p=d[0],h=d[1],m=new Uint8Array(t.slice(0,h)),Module.FS_createDataFile("/zoneinfo/"+p,null,m,!0,!0,!0),t=t.slice(h)}catch(e){v={error:e}}finally{try{f&&!f.done&&(y=l.return)&&y.call(l)}finally{if(v)throw v.error}}return[2]}))}))}},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var r=n(23),o=function(){function e(e){this.batchAddress=e,this.arrayRangeReader=i,this.arrayBuilderSegmentReader=a,this.diffReader=u,this.editReader=s,this.frameReader=c}return e.prototype.updatedComponents=function(){return r.platform.readStructField(this.batchAddress,0)},e.prototype.referenceFrames=function(){return r.platform.readStructField(this.batchAddress,i.structLength)},e.prototype.disposedComponentIds=function(){return r.platform.readStructField(this.batchAddress,2*i.structLength)},e.prototype.disposedEventHandlerIds=function(){return r.platform.readStructField(this.batchAddress,3*i.structLength)},e.prototype.updatedComponentsEntry=function(e,t){return l(e,t,u.structLength)},e.prototype.referenceFramesEntry=function(e,t){return l(e,t,c.structLength)},e.prototype.disposedComponentIdsEntry=function(e,t){var n=l(e,t,4);return r.platform.readInt32Field(n)},e.prototype.disposedEventHandlerIdsEntry=function(e,t){var n=l(e,t,8);return r.platform.readUint64Field(n)},e}();t.SharedMemoryRenderBatch=o;var i={structLength:8,values:function(e){return r.platform.readObjectField(e,0)},count:function(e){return r.platform.readInt32Field(e,4)}},a={structLength:12,values:function(e){var t=r.platform.readObjectField(e,0),n=r.platform.getObjectFieldsBaseAddress(t);return r.platform.readObjectField(n,0)},offset:function(e){return r.platform.readInt32Field(e,4)},count:function(e){return r.platform.readInt32Field(e,8)}},u={structLength:4+a.structLength,componentId:function(e){return r.platform.readInt32Field(e,0)},edits:function(e){return r.platform.readStructField(e,4)},editsEntry:function(e,t){return l(e,t,s.structLength)}},s={structLength:20,editType:function(e){return r.platform.readInt32Field(e,0)},siblingIndex:function(e){return r.platform.readInt32Field(e,4)},newTreeIndex:function(e){return r.platform.readInt32Field(e,8)},moveToSiblingIndex:function(e){return r.platform.readInt32Field(e,8)},removedAttributeName:function(e){return r.platform.readStringField(e,16)}},c={structLength:36,frameType:function(e){return r.platform.readInt16Field(e,4)},subtreeLength:function(e){return r.platform.readInt32Field(e,8)},elementReferenceCaptureId:function(e){return r.platform.readStringField(e,16)},componentId:function(e){return r.platform.readInt32Field(e,12)},elementName:function(e){return r.platform.readStringField(e,16)},textContent:function(e){return r.platform.readStringField(e,16)},markupContent:function(e){return r.platform.readStringField(e,16)},attributeName:function(e){return r.platform.readStringField(e,16)},attributeValue:function(e){return r.platform.readStringField(e,24,!0)},attributeEventHandlerId:function(e){return r.platform.readUint64Field(e,8)}};function l(e,t,n){return r.platform.getArrayEntryPtr(e,t,n)}},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{s(r.next(e))}catch(e){i(e)}}function u(e){try{s(r.throw(e))}catch(e){i(e)}}function s(e){var t;e.done?o(e.value):(t=e.value,t instanceof n?t:new n((function(e){e(t)}))).then(a,u)}s((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:u(0),throw:u(1),return:u(2)},"function"==typeof Symbol&&(i[Symbol.iterator]=function(){return this}),i;function u(i){return function(u){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=a.trys,(o=o.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]): Promise { +async function boot(userOptions?: Partial): Promise { if (started) { throw new Error('Blazor has already started.'); } @@ -72,7 +72,7 @@ async function boot(userOptions?: Partial): Promise { logger.log(LogLevel.Information, 'Blazor server-side application started.'); } -async function initializeConnection(options: BlazorOptions, logger: Logger, circuit: CircuitDescriptor): Promise { +async function initializeConnection(options: CircuitStartOptions, logger: Logger, circuit: CircuitDescriptor): Promise { const hubProtocol = new MessagePackHubProtocol(); (hubProtocol as unknown as { name: string }).name = 'blazorpack'; diff --git a/src/Components/Web.JS/src/Boot.WebAssembly.ts b/src/Components/Web.JS/src/Boot.WebAssembly.ts index a691a8279d..1353d0a403 100644 --- a/src/Components/Web.JS/src/Boot.WebAssembly.ts +++ b/src/Components/Web.JS/src/Boot.WebAssembly.ts @@ -10,10 +10,11 @@ import { WebAssemblyResourceLoader } from './Platform/WebAssemblyResourceLoader' import { WebAssemblyConfigLoader } from './Platform/WebAssemblyConfigLoader'; import { BootConfigResult } from './Platform/BootConfig'; import { Pointer } from './Platform/Platform'; +import { WebAssemblyStartOptions } from './Platform/WebAssemblyStartOptions'; let started = false; -async function boot(options?: any): Promise { +async function boot(options?: Partial): Promise { if (started) { throw new Error('Blazor has already started.'); @@ -43,7 +44,7 @@ async function boot(options?: any): Promise { const bootConfigResult = await BootConfigResult.initAsync(); const [resourceLoader] = await Promise.all([ - WebAssemblyResourceLoader.initAsync(bootConfigResult.bootConfig), + WebAssemblyResourceLoader.initAsync(bootConfigResult.bootConfig, options || {}), WebAssemblyConfigLoader.initAsync(bootConfigResult)]); try { diff --git a/src/Components/Web.JS/src/Platform/Circuits/BlazorOptions.ts b/src/Components/Web.JS/src/Platform/Circuits/CircuitStartOptions.ts similarity index 85% rename from src/Components/Web.JS/src/Platform/Circuits/BlazorOptions.ts rename to src/Components/Web.JS/src/Platform/Circuits/CircuitStartOptions.ts index 10d0c9a357..f83753e10d 100644 --- a/src/Components/Web.JS/src/Platform/Circuits/BlazorOptions.ts +++ b/src/Components/Web.JS/src/Platform/Circuits/CircuitStartOptions.ts @@ -1,13 +1,13 @@ import { LogLevel } from '../Logging/Logger'; -export interface BlazorOptions { +export interface CircuitStartOptions { configureSignalR: (builder: signalR.HubConnectionBuilder) => void; logLevel: LogLevel; reconnectionOptions: ReconnectionOptions; reconnectionHandler?: ReconnectionHandler; } -export function resolveOptions(userOptions?: Partial): BlazorOptions { +export function resolveOptions(userOptions?: Partial): CircuitStartOptions { const result = { ...defaultOptions, ...userOptions }; // The spread operator can't be used for a deep merge, so do the same for subproperties @@ -29,7 +29,7 @@ export interface ReconnectionHandler { onConnectionUp(): void; } -const defaultOptions: BlazorOptions = { +const defaultOptions: CircuitStartOptions = { configureSignalR: (_) => { }, logLevel: LogLevel.Warning, reconnectionOptions: { diff --git a/src/Components/Web.JS/src/Platform/Circuits/DefaultReconnectionHandler.ts b/src/Components/Web.JS/src/Platform/Circuits/DefaultReconnectionHandler.ts index f1e2848f74..b017bf5da9 100644 --- a/src/Components/Web.JS/src/Platform/Circuits/DefaultReconnectionHandler.ts +++ b/src/Components/Web.JS/src/Platform/Circuits/DefaultReconnectionHandler.ts @@ -1,4 +1,4 @@ -import { ReconnectionHandler, ReconnectionOptions } from './BlazorOptions'; +import { ReconnectionHandler, ReconnectionOptions } from './CircuitStartOptions'; import { ReconnectDisplay } from './ReconnectDisplay'; import { DefaultReconnectDisplay } from './DefaultReconnectDisplay'; import { UserSpecifiedDisplay } from './UserSpecifiedDisplay'; diff --git a/src/Components/Web.JS/src/Platform/Mono/MonoPlatform.ts b/src/Components/Web.JS/src/Platform/Mono/MonoPlatform.ts index dfffb06eca..69cf33979f 100644 --- a/src/Components/Web.JS/src/Platform/Mono/MonoPlatform.ts +++ b/src/Components/Web.JS/src/Platform/Mono/MonoPlatform.ts @@ -3,6 +3,7 @@ import { showErrorNotification } from '../../BootErrors'; import { WebAssemblyResourceLoader, LoadingResource } from '../WebAssemblyResourceLoader'; import { Platform, System_Array, Pointer, System_Object, System_String } from '../Platform'; import { loadTimezoneData } from './TimezoneDataFile'; +import { WebAssemblyBootResourceType } from '../WebAssemblyStartOptions'; let mono_string_get_utf8: (managedString: System_String) => Pointer; let mono_wasm_add_assembly: (name: string, heapAddress: number, length: number) => void; @@ -138,17 +139,30 @@ function addScriptTagsToDocument(resourceLoader: WebAssemblyResourceLoader) { const dotnetJsResourceName = Object .keys(resourceLoader.bootConfig.resources.runtime) .filter(n => n.startsWith('dotnet.') && n.endsWith('.js'))[0]; + const dotnetJsContentHash = resourceLoader.bootConfig.resources.runtime[dotnetJsResourceName]; const scriptElem = document.createElement('script'); scriptElem.src = `_framework/wasm/${dotnetJsResourceName}`; scriptElem.defer = true; // For consistency with WebAssemblyResourceLoader, we only enforce SRI if caching is allowed if (resourceLoader.bootConfig.cacheBootResources) { - const contentHash = resourceLoader.bootConfig.resources.runtime[dotnetJsResourceName]; - scriptElem.integrity = contentHash; + scriptElem.integrity = dotnetJsContentHash; scriptElem.crossOrigin = 'anonymous'; } + // Allow overriding the URI from which the dotnet.*.js file is loaded + if (resourceLoader.startOptions.loadBootResource) { + const resourceType: WebAssemblyBootResourceType = 'dotnetjs'; + const customSrc = resourceLoader.startOptions.loadBootResource( + resourceType, dotnetJsResourceName, scriptElem.src, dotnetJsContentHash); + if (typeof(customSrc) === 'string') { + scriptElem.src = customSrc; + } else if (customSrc) { + // Since we must load this via a - + + + + diff --git a/src/Components/WebAssembly/testassets/HostedInAspNet.Server/RequestLog.cs b/src/Components/WebAssembly/testassets/HostedInAspNet.Server/BootResourceRequestLog.cs similarity index 94% rename from src/Components/WebAssembly/testassets/HostedInAspNet.Server/RequestLog.cs rename to src/Components/WebAssembly/testassets/HostedInAspNet.Server/BootResourceRequestLog.cs index 99b8a2a1c5..5746a4228d 100644 --- a/src/Components/WebAssembly/testassets/HostedInAspNet.Server/RequestLog.cs +++ b/src/Components/WebAssembly/testassets/HostedInAspNet.Server/BootResourceRequestLog.cs @@ -6,7 +6,7 @@ using Microsoft.AspNetCore.Http; namespace HostedInAspNet.Server { - public class RequestLog + public class BootResourceRequestLog { private List _requestPaths = new List(); diff --git a/src/Components/WebAssembly/testassets/HostedInAspNet.Server/Startup.cs b/src/Components/WebAssembly/testassets/HostedInAspNet.Server/Startup.cs index c73d41123c..66b236ddf8 100644 --- a/src/Components/WebAssembly/testassets/HostedInAspNet.Server/Startup.cs +++ b/src/Components/WebAssembly/testassets/HostedInAspNet.Server/Startup.cs @@ -14,16 +14,22 @@ namespace HostedInAspNet.Server // For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940 public void ConfigureServices(IServiceCollection services) { - services.AddSingleton(); + services.AddSingleton(); } // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. - public void Configure(IApplicationBuilder app, IWebHostEnvironment env, RequestLog requestLog) + public void Configure(IApplicationBuilder app, IWebHostEnvironment env, BootResourceRequestLog bootResourceRequestLog) { app.Use((context, next) => { - // This is used by E2E tests to verify that the correct resources were fetched - requestLog.AddRequest(context.Request); + // This is used by E2E tests to verify that the correct resources were fetched, + // and that it was possible to override the loading mechanism + if (context.Request.Query.ContainsKey("customizedbootresource") + || context.Request.Headers.ContainsKey("customizedbootresource") + || context.Request.Path.Value.EndsWith("/blazor.boot.json")) + { + bootResourceRequestLog.AddRequest(context.Request); + } return next(); }); diff --git a/src/Components/test/E2ETest/Tests/BootResourceCachingTest.cs b/src/Components/test/E2ETest/Tests/BootResourceCachingTest.cs index 871058c2fa..ff79143e5f 100644 --- a/src/Components/test/E2ETest/Tests/BootResourceCachingTest.cs +++ b/src/Components/test/E2ETest/Tests/BootResourceCachingTest.cs @@ -46,6 +46,7 @@ namespace Microsoft.AspNetCore.Components.E2ETest.Tests var initialResourcesRequested = GetAndClearRequestedPaths(); Assert.NotEmpty(initialResourcesRequested.Where(path => path.EndsWith("/blazor.boot.json"))); Assert.NotEmpty(initialResourcesRequested.Where(path => path.EndsWith("/dotnet.wasm"))); + Assert.NotEmpty(initialResourcesRequested.Where(path => path.EndsWith("/dotnet.timezones.dat"))); Assert.NotEmpty(initialResourcesRequested.Where(path => path.EndsWith(".js"))); Assert.NotEmpty(initialResourcesRequested.Where(path => path.EndsWith(".dll"))); @@ -57,11 +58,12 @@ namespace Microsoft.AspNetCore.Components.E2ETest.Tests var subsequentResourcesRequested = GetAndClearRequestedPaths(); Assert.NotEmpty(initialResourcesRequested.Where(path => path.EndsWith("/blazor.boot.json"))); Assert.Empty(subsequentResourcesRequested.Where(path => path.EndsWith("/dotnet.wasm"))); + Assert.Empty(subsequentResourcesRequested.Where(path => path.EndsWith("/dotnet.timezones.dat"))); Assert.NotEmpty(subsequentResourcesRequested.Where(path => path.EndsWith(".js"))); Assert.Empty(subsequentResourcesRequested.Where(path => path.EndsWith(".dll"))); } - [Fact(Skip = "https://github.com/dotnet/aspnetcore/issues/20154")] + [Fact] public void IncrementallyUpdatesCache() { // Perform a first load to populate the cache @@ -137,7 +139,7 @@ namespace Microsoft.AspNetCore.Components.E2ETest.Tests private IReadOnlyCollection GetAndClearRequestedPaths() { - var requestLog = _serverFixture.Host.Services.GetRequiredService(); + var requestLog = _serverFixture.Host.Services.GetRequiredService(); var result = requestLog.RequestPaths.ToList(); requestLog.Clear(); return result;