/**
 * @license Angular v11.2.14
 * (c) 2010-2021 Google LLC. https://angular.io/
 * License: MIT
 */
!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?e(exports,require("@angular/common"),require("@angular/core")):"function"==typeof define&&define.amd?define("@angular/platform-browser",["exports","@angular/common","@angular/core"],e):e(((t=t||self).ng=t.ng||{},t.ng.platformBrowser={}),t.ng.common,t.ng.core)}(this,(function(t,e,r){"use strict";
/*! *****************************************************************************
    Copyright (c) Microsoft Corporation.

    Permission to use, copy, modify, and/or distribute this software for any
    purpose with or without fee is hereby granted.

    THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
    REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
    AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
    INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
    LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
    OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
    PERFORMANCE OF THIS SOFTWARE.
    ***************************************************************************** */var n=function(t,e){return(n=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,e){t.__proto__=e}||function(t,e){for(var r in e)e.hasOwnProperty(r)&&(t[r]=e[r])})(t,e)};function o(t,e){function r(){this.constructor=t}n(t,e),t.prototype=null===e?Object.create(e):(r.prototype=e.prototype,new r)}var i,a=function(t){function e(){return t.call(this)||this}return o(e,t),e.prototype.supportsDOMEvents=function(){return!0},e}(e.ɵDomAdapter),s=function(t){function r(){return null!==t&&t.apply(this,arguments)||this}return o(r,t),r.makeCurrent=function(){e.ɵsetRootDomAdapter(new r)},r.prototype.getProperty=function(t,e){return t[e]},r.prototype.log=function(t){window.console&&window.console.log&&window.console.log(t)},r.prototype.logGroup=function(t){window.console&&window.console.group&&window.console.group(t)},r.prototype.logGroupEnd=function(){window.console&&window.console.groupEnd&&window.console.groupEnd()},r.prototype.onAndCancel=function(t,e,r){return t.addEventListener(e,r,!1),function(){t.removeEventListener(e,r,!1)}},r.prototype.dispatchEvent=function(t,e){t.dispatchEvent(e)},r.prototype.remove=function(t){return t.parentNode&&t.parentNode.removeChild(t),t},r.prototype.getValue=function(t){return t.value},r.prototype.createElement=function(t,e){return(e=e||this.getDefaultDocument()).createElement(t)},r.prototype.createHtmlDocument=function(){return document.implementation.createHTMLDocument("fakeTitle")},r.prototype.getDefaultDocument=function(){return document},r.prototype.isElementNode=function(t){return t.nodeType===Node.ELEMENT_NODE},r.prototype.isShadowRoot=function(t){return t instanceof DocumentFragment},r.prototype.getGlobalEventTarget=function(t,e){return"window"===e?window:"document"===e?t:"body"===e?t.body:null},r.prototype.getHistory=function(){return window.history},r.prototype.getLocation=function(){return window.location},r.prototype.getBaseHref=function(t){var e=function r(){return u||(u=document.querySelector("base"))?u.getAttribute("href"):null}();return null==e?null:function n(t){return i||(i=document.createElement("a")),i.setAttribute("href",t),"/"===i.pathname.charAt(0)?i.pathname:"/"+i.pathname}
/**
     * @license
     * Copyright Google LLC All Rights Reserved.
     *
     * Use of this source code is governed by an MIT-style license that can be
     * found in the LICENSE file at https://angular.io/license
     */(e)},r.prototype.resetBaseElement=function(){u=null},r.prototype.getUserAgent=function(){return window.navigator.userAgent},r.prototype.performanceNow=function(){return window.performance&&window.performance.now?window.performance.now():(new Date).getTime()},r.prototype.supportsCookies=function(){return!0},r.prototype.getCookie=function(t){return e.ɵparseCookieValue(document.cookie,t)},r}(a),u=null,c=new r.InjectionToken("TRANSITION_ID");function p(t,n,o){return function(){o.get(r.ApplicationInitStatus).donePromise.then((function(){var r=e.ɵgetDOM();Array.prototype.slice.apply(n.querySelectorAll("style[ng-transition]")).filter((function(e){return e.getAttribute("ng-transition")===t})).forEach((function(t){return r.remove(t)}))}))}}var l=[{provide:r.APP_INITIALIZER,useFactory:p,deps:[c,e.DOCUMENT,r.Injector],multi:!0}],d=function(){function t(){}return t.init=function(){r.setTestabilityGetter(new t)},t.prototype.addToWindow=function(t){r.ɵglobal.getAngularTestability=function(e,r){void 0===r&&(r=!0);var n=t.findTestabilityInTree(e,r);if(null==n)throw new Error("Could not find testability for element.");return n},r.ɵglobal.getAllAngularTestabilities=function(){return t.getAllTestabilities()},r.ɵglobal.getAllAngularRootElements=function(){return t.getAllRootElements()},r.ɵglobal.frameworkStabilizers||(r.ɵglobal.frameworkStabilizers=[]),r.ɵglobal.frameworkStabilizers.push((function(t){var e=r.ɵglobal.getAllAngularTestabilities(),n=e.length,o=!1,i=function(e){o=o||e,0==--n&&t(o)};e.forEach((function(t){t.whenStable(i)}))}))},t.prototype.findTestabilityInTree=function(t,r,n){if(null==r)return null;var o=t.getTestability(r);return null!=o?o:n?e.ɵgetDOM().isShadowRoot(r)?this.findTestabilityInTree(t,r.host,!0):this.findTestabilityInTree(t,r.parentElement,!0):null},t}();
/**
     * @license
     * Copyright Google LLC All Rights Reserved.
     *
     * Use of this source code is governed by an MIT-style license that can be
     * found in the LICENSE file at https://angular.io/license
     */function f(t,e){"undefined"!=typeof COMPILED&&COMPILED||((r.ɵglobal.ng=r.ɵglobal.ng||{})[t]=e)}
/**
     * @license
     * Copyright Google LLC All Rights Reserved.
     *
     * Use of this source code is governed by an MIT-style license that can be
     * found in the LICENSE file at https://angular.io/license
     */var y={ApplicationRef:r.ApplicationRef,NgZone:r.NgZone};function h(t){return r.ɵgetDebugNodeR2(t)}function g(t){return f("probe",h),f("coreTokens",Object.assign(Object.assign({},y),function e(t){return t.reduce((function(t,e){return t[e.name]=e.token,t}),{})}(t||[]))),function(){return h}}var m=[{provide:r.APP_INITIALIZER,useFactory:g,deps:[[r.NgProbeToken,new r.Optional]],multi:!0}],v=m,w=new r.InjectionToken("EventManagerPlugins"),_=function(){function t(t,e){var r=this;this._zone=e,this._eventNameToPlugin=new Map,t.forEach((function(t){return t.manager=r})),this._plugins=t.slice().reverse()}return t.prototype.addEventListener=function(t,e,r){return this._findPluginFor(e).addEventListener(t,e,r)},t.prototype.addGlobalEventListener=function(t,e,r){return this._findPluginFor(e).addGlobalEventListener(t,e,r)},t.prototype.getZone=function(){return this._zone},t.prototype._findPluginFor=function(t){var e=this._eventNameToPlugin.get(t);if(e)return e;for(var r=this._plugins,n=0;n<r.length;n++){var o=r[n];if(o.supports(t))return this._eventNameToPlugin.set(t,o),o}throw new Error("No event manager plugin found for event "+t)},t}();_.decorators=[{type:r.Injectable}],_.ctorParameters=function(){return[{type:Array,decorators:[{type:r.Inject,args:[w]}]},{type:r.NgZone}]};var E=function(){function t(t){this._doc=t}return t.prototype.addGlobalEventListener=function(t,r,n){var o=e.ɵgetDOM().getGlobalEventTarget(this._doc,t);if(!o)throw new Error("Unsupported event target "+o+" for event "+r);return this.addEventListener(o,r,n)},t}(),b=function(){function t(){this._stylesSet=new Set}return t.prototype.addStyles=function(t){var e=this,r=new Set;t.forEach((function(t){e._stylesSet.has(t)||(e._stylesSet.add(t),r.add(t))})),this.onStylesAdded(r)},t.prototype.onStylesAdded=function(t){},t.prototype.getAllStyles=function(){return Array.from(this._stylesSet)},t}();b.decorators=[{type:r.Injectable}];var S=function(t){function e(e){var r=t.call(this)||this;return r._doc=e,r._hostNodes=new Map,r._hostNodes.set(e.head,[]),r}return o(e,t),e.prototype._addStylesToHost=function(t,e,r){var n=this;t.forEach((function(t){var o=n._doc.createElement("style");o.textContent=t,r.push(e.appendChild(o))}))},e.prototype.addHost=function(t){var e=[];this._addStylesToHost(this._stylesSet,t,e),this._hostNodes.set(t,e)},e.prototype.removeHost=function(t){var e=this._hostNodes.get(t);e&&e.forEach(T),this._hostNodes.delete(t)},e.prototype.onStylesAdded=function(t){var e=this;this._hostNodes.forEach((function(r,n){e._addStylesToHost(t,n,r)}))},e.prototype.ngOnDestroy=function(){this._hostNodes.forEach((function(t){return t.forEach(T)}))},e}(b);function T(t){e.ɵgetDOM().remove(t)}S.decorators=[{type:r.Injectable}],S.ctorParameters=function(){return[{type:void 0,decorators:[{type:r.Inject,args:[e.DOCUMENT]}]}]};var C={svg:"http://www.w3.org/2000/svg",xhtml:"http://www.w3.org/1999/xhtml",xlink:"http://www.w3.org/1999/xlink",xml:"http://www.w3.org/XML/1998/namespace",xmlns:"http://www.w3.org/2000/xmlns/"},I=/%COMP%/g;function O(t){return"_ngcontent-%COMP%".replace(I,t)}function A(t){return"_nghost-%COMP%".replace(I,t)}function M(t,e,r){for(var n=0;n<e.length;n++){var o=e[n];Array.isArray(o)?M(t,o,r):(o=o.replace(I,t),r.push(o))}return r}function N(t){return function(e){if("__ngUnwrap__"===e)return t;!1===t(e)&&(e.preventDefault(),e.returnValue=!1)}}var R=function(){function t(t,e,r){this.eventManager=t,this.sharedStylesHost=e,this.appId=r,this.rendererByCompId=new Map,this.defaultRenderer=new D(t)}return t.prototype.createRenderer=function(t,e){if(!t||!e)return this.defaultRenderer;switch(e.encapsulation){case r.ViewEncapsulation.Emulated:var n=this.rendererByCompId.get(e.id);return n||(n=new P(this.eventManager,this.sharedStylesHost,e,this.appId),this.rendererByCompId.set(e.id,n)),n.applyToHost(t),n;case 1:case r.ViewEncapsulation.ShadowDom:return new k(this.eventManager,this.sharedStylesHost,t,e);default:if(!this.rendererByCompId.has(e.id)){var o=M(e.id,e.styles,[]);this.sharedStylesHost.addStyles(o),this.rendererByCompId.set(e.id,this.defaultRenderer)}return this.defaultRenderer}},t.prototype.begin=function(){},t.prototype.end=function(){},t}();R.decorators=[{type:r.Injectable}],R.ctorParameters=function(){return[{type:_},{type:S},{type:String,decorators:[{type:r.Inject,args:[r.APP_ID]}]}]};var D=function(){function t(t){this.eventManager=t,this.data=Object.create(null)}return t.prototype.destroy=function(){},t.prototype.createElement=function(t,e){return e?document.createElementNS(C[e]||e,t):document.createElement(t)},t.prototype.createComment=function(t){return document.createComment(t)},t.prototype.createText=function(t){return document.createTextNode(t)},t.prototype.appendChild=function(t,e){t.appendChild(e)},t.prototype.insertBefore=function(t,e,r){t&&t.insertBefore(e,r)},t.prototype.removeChild=function(t,e){t&&t.removeChild(e)},t.prototype.selectRootElement=function(t,e){var r="string"==typeof t?document.querySelector(t):t;if(!r)throw new Error('The selector "'+t+'" did not match any elements');return e||(r.textContent=""),r},t.prototype.parentNode=function(t){return t.parentNode},t.prototype.nextSibling=function(t){return t.nextSibling},t.prototype.setAttribute=function(t,e,r,n){if(n){e=n+":"+e;var o=C[n];o?t.setAttributeNS(o,e,r):t.setAttribute(e,r)}else t.setAttribute(e,r)},t.prototype.removeAttribute=function(t,e,r){if(r){var n=C[r];n?t.removeAttributeNS(n,e):t.removeAttribute(r+":"+e)}else t.removeAttribute(e)},t.prototype.addClass=function(t,e){t.classList.add(e)},t.prototype.removeClass=function(t,e){t.classList.remove(e)},t.prototype.setStyle=function(t,e,n,o){o&(r.RendererStyleFlags2.DashCase|r.RendererStyleFlags2.Important)?t.style.setProperty(e,n,o&r.RendererStyleFlags2.Important?"important":""):t.style[e]=n},t.prototype.removeStyle=function(t,e,n){n&r.RendererStyleFlags2.DashCase?t.style.removeProperty(e):t.style[e]=""},t.prototype.setProperty=function(t,e,r){t[e]=r},t.prototype.setValue=function(t,e){t.nodeValue=e},t.prototype.listen=function(t,e,r){return"string"==typeof t?this.eventManager.addGlobalEventListener(t,e,N(r)):this.eventManager.addEventListener(t,e,N(r))},t}();"@".charCodeAt(0);var P=function(t){function e(e,r,n,o){var i=t.call(this,e)||this;i.component=n;var a=M(o+"-"+n.id,n.styles,[]);return r.addStyles(a),i.contentAttr=O(o+"-"+n.id),i.hostAttr=A(o+"-"+n.id),i}return o(e,t),e.prototype.applyToHost=function(e){t.prototype.setAttribute.call(this,e,this.hostAttr,"")},e.prototype.createElement=function(e,r){var n=t.prototype.createElement.call(this,e,r);return t.prototype.setAttribute.call(this,n,this.contentAttr,""),n},e}(D),k=function(t){function e(e,r,n,o){var i=t.call(this,e)||this;i.sharedStylesHost=r,i.hostEl=n,i.shadowRoot=n.attachShadow({mode:"open"}),i.sharedStylesHost.addHost(i.shadowRoot);for(var a=M(o.id,o.styles,[]),s=0;s<a.length;s++){var u=document.createElement("style");u.textContent=a[s],i.shadowRoot.appendChild(u)}return i}return o(e,t),e.prototype.nodeOrShadowRoot=function(t){return t===this.hostEl?this.shadowRoot:t},e.prototype.destroy=function(){this.sharedStylesHost.removeHost(this.shadowRoot)},e.prototype.appendChild=function(e,r){return t.prototype.appendChild.call(this,this.nodeOrShadowRoot(e),r)},e.prototype.insertBefore=function(e,r,n){return t.prototype.insertBefore.call(this,this.nodeOrShadowRoot(e),r,n)},e.prototype.removeChild=function(e,r){return t.prototype.removeChild.call(this,this.nodeOrShadowRoot(e),r)},e.prototype.parentNode=function(e){return this.nodeOrShadowRoot(t.prototype.parentNode.call(this,this.nodeOrShadowRoot(e)))},e}(D),L=function(t){function e(e){return t.call(this,e)||this}return o(e,t),e.prototype.supports=function(t){return!0},e.prototype.addEventListener=function(t,e,r){var n=this;return t.addEventListener(e,r,!1),function(){return n.removeEventListener(t,e,r)}},e.prototype.removeEventListener=function(t,e,r){return t.removeEventListener(e,r)},e}(E);L.decorators=[{type:r.Injectable}],L.ctorParameters=function(){return[{type:void 0,decorators:[{type:r.Inject,args:[e.DOCUMENT]}]}]};var j={pan:!0,panstart:!0,panmove:!0,panend:!0,pancancel:!0,panleft:!0,panright:!0,panup:!0,pandown:!0,pinch:!0,pinchstart:!0,pinchmove:!0,pinchend:!0,pinchcancel:!0,pinchin:!0,pinchout:!0,press:!0,pressup:!0,rotate:!0,rotatestart:!0,rotatemove:!0,rotateend:!0,rotatecancel:!0,swipe:!0,swipeleft:!0,swiperight:!0,swipeup:!0,swipedown:!0,tap:!0,doubletap:!0},H=new r.InjectionToken("HammerGestureConfig"),x=new r.InjectionToken("HammerLoader"),U=function(){function t(){this.events=[],this.overrides={}}return t.prototype.buildHammer=function(t){var e=new Hammer(t,this.options);for(var r in e.get("pinch").set({enable:!0}),e.get("rotate").set({enable:!0}),this.overrides)e.get(r).set(this.overrides[r]);return e},t}();U.decorators=[{type:r.Injectable}];var B=function(t){function e(e,r,n,o){var i=t.call(this,e)||this;return i._config=r,i.console=n,i.loader=o,i._loaderPromise=null,i}return o(e,t),e.prototype.supports=function(t){return!(!j.hasOwnProperty(t.toLowerCase())&&!this.isCustomEvent(t)||!window.Hammer&&!this.loader)},e.prototype.addEventListener=function(t,e,r){var n=this,o=this.manager.getZone();if(e=e.toLowerCase(),!window.Hammer&&this.loader){this._loaderPromise=this._loaderPromise||this.loader();var i=!1,a=function(){i=!0};return this._loaderPromise.then((function(){window.Hammer?i||(a=n.addEventListener(t,e,r)):a=function(){}})).catch((function(){a=function(){}})),function(){a()}}return o.runOutsideAngular((function(){var i=n._config.buildHammer(t),a=function(t){o.runGuarded((function(){r(t)}))};return i.on(e,a),function(){i.off(e,a),"function"==typeof i.destroy&&i.destroy()}}))},e.prototype.isCustomEvent=function(t){return this._config.events.indexOf(t)>-1},e}(E);B.decorators=[{type:r.Injectable}],B.ctorParameters=function(){return[{type:void 0,decorators:[{type:r.Inject,args:[e.DOCUMENT]}]},{type:U,decorators:[{type:r.Inject,args:[H]}]},{type:r.ɵConsole},{type:void 0,decorators:[{type:r.Optional},{type:r.Inject,args:[x]}]}]};var z,F=[{provide:w,useClass:B,multi:!0,deps:[e.DOCUMENT,H,r.ɵConsole,[new r.Optional,x]]},{provide:H,useClass:U,deps:[]}],V=F;(z=function z(){}).decorators=[{type:r.NgModule,args:[{providers:F}]}];var G,K=["alt","control","meta","shift"],Z={"\b":"Backspace","\t":"Tab","":"Delete","":"Escape",Del:"Delete",Esc:"Escape",Left:"ArrowLeft",Right:"ArrowRight",Up:"ArrowUp",Down:"ArrowDown",Menu:"ContextMenu",Scroll:"ScrollLock",Win:"OS"},q={A:"1",B:"2",C:"3",D:"4",E:"5",F:"6",G:"7",H:"8",I:"9",J:"*",K:"+",M:"-",N:".",O:"/","`":"0","":"NumLock"},W={alt:function(t){return t.altKey},control:function(t){return t.ctrlKey},meta:function(t){return t.metaKey},shift:function(t){return t.shiftKey}},J=function(t){function r(e){return t.call(this,e)||this}return o(r,t),r.prototype.supports=function(t){return null!=r.parseEventName(t)},r.prototype.addEventListener=function(t,n,o){var i=r.parseEventName(n),a=r.eventCallback(i.fullKey,o,this.manager.getZone());return this.manager.getZone().runOutsideAngular((function(){return e.ɵgetDOM().onAndCancel(t,i.domEventName,a)}))},r.parseEventName=function(t){var e=t.toLowerCase().split("."),n=e.shift();if(0===e.length||"keydown"!==n&&"keyup"!==n)return null;var o=r._normalizeKey(e.pop()),i="";if(K.forEach((function(t){var r=e.indexOf(t);r>-1&&(e.splice(r,1),i+=t+".")})),i+=o,0!=e.length||0===o.length)return null;var a={};return a.domEventName=n,a.fullKey=i,a},r.getEventFullKey=function(t){var e="",r=function n(t){var e=t.key;if(null==e){if(null==(e=t.keyIdentifier))return"Unidentified";e.startsWith("U+")&&(e=String.fromCharCode(parseInt(e.substring(2),16)),3===t.location&&q.hasOwnProperty(e)&&(e=q[e]))}return Z[e]||e}(t);return" "===(r=r.toLowerCase())?r="space":"."===r&&(r="dot"),K.forEach((function(n){n!=r&&(0,W[n])(t)&&(e+=n+".")})),e+=r},r.eventCallback=function(t,e,n){return function(o){r.getEventFullKey(o)===t&&n.runGuarded((function(){return e(o)}))}},r._normalizeKey=function(t){switch(t){case"esc":return"escape";default:return t}},r}(E);function X(t){return new Y(t.get(e.DOCUMENT))}J.decorators=[{type:r.Injectable}],J.ctorParameters=function(){return[{type:void 0,decorators:[{type:r.Inject,args:[e.DOCUMENT]}]}]},(G=function G(){}).ɵprov=r.ɵɵdefineInjectable({factory:function t(){return r.ɵɵinject(Y)},token:G,providedIn:"root"}),G.decorators=[{type:r.Injectable,args:[{providedIn:"root",useExisting:r.forwardRef((function(){return Y}))}]}];var Y=function(t){function e(e){var r=t.call(this)||this;return r._doc=e,r}return o(e,t),e.prototype.sanitize=function(t,e){if(null==e)return null;switch(t){case r.SecurityContext.NONE:return e;case r.SecurityContext.HTML:return r.ɵallowSanitizationBypassAndThrow(e,"HTML")?r.ɵunwrapSafeValue(e):r.ɵ_sanitizeHtml(this._doc,String(e)).toString();case r.SecurityContext.STYLE:return r.ɵallowSanitizationBypassAndThrow(e,"Style")?r.ɵunwrapSafeValue(e):e;case r.SecurityContext.SCRIPT:if(r.ɵallowSanitizationBypassAndThrow(e,"Script"))return r.ɵunwrapSafeValue(e);throw new Error("unsafe value used in a script context");case r.SecurityContext.URL:return r.ɵgetSanitizationBypassType(e),r.ɵallowSanitizationBypassAndThrow(e,"URL")?r.ɵunwrapSafeValue(e):r.ɵ_sanitizeUrl(String(e));case r.SecurityContext.RESOURCE_URL:if(r.ɵallowSanitizationBypassAndThrow(e,"ResourceURL"))return r.ɵunwrapSafeValue(e);throw new Error("unsafe value used in a resource URL context (see https://g.co/ng/security#xss)");default:throw new Error("Unexpected SecurityContext "+t+" (see https://g.co/ng/security#xss)")}},e.prototype.bypassSecurityTrustHtml=function(t){return r.ɵbypassSanitizationTrustHtml(t)},e.prototype.bypassSecurityTrustStyle=function(t){return r.ɵbypassSanitizationTrustStyle(t)},e.prototype.bypassSecurityTrustScript=function(t){return r.ɵbypassSanitizationTrustScript(t)},e.prototype.bypassSecurityTrustUrl=function(t){return r.ɵbypassSanitizationTrustUrl(t)},e.prototype.bypassSecurityTrustResourceUrl=function(t){return r.ɵbypassSanitizationTrustResourceUrl(t)},e}(G);
/**
     * @license
     * Copyright Google LLC All Rights Reserved.
     *
     * Use of this source code is governed by an MIT-style license that can be
     * found in the LICENSE file at https://angular.io/license
     */
function Q(){s.makeCurrent(),d.init()}function $(){return new r.ErrorHandler}function tt(){return r.ɵsetDocument(document),document}Y.ɵprov=r.ɵɵdefineInjectable({factory:function t(){return X(r.ɵɵinject(r.INJECTOR))},token:Y,providedIn:"root"}),Y.decorators=[{type:r.Injectable,args:[{providedIn:"root",useFactory:X,deps:[r.Injector]}]}],Y.ctorParameters=function(){return[{type:void 0,decorators:[{type:r.Inject,args:[e.DOCUMENT]}]}]};var et=[{provide:r.PLATFORM_ID,useValue:e.ɵPLATFORM_BROWSER_ID},{provide:r.PLATFORM_INITIALIZER,useValue:Q,multi:!0},{provide:e.DOCUMENT,useFactory:tt,deps:[]}],rt=[{provide:r.Sanitizer,useExisting:G},{provide:G,useClass:Y,deps:[e.DOCUMENT]}],nt=r.createPlatformFactory(r.platformCore,"browser",et),ot=[rt,{provide:r.ɵINJECTOR_SCOPE,useValue:"root"},{provide:r.ErrorHandler,useFactory:$,deps:[]},{provide:w,useClass:L,multi:!0,deps:[e.DOCUMENT,r.NgZone,r.PLATFORM_ID]},{provide:w,useClass:J,multi:!0,deps:[e.DOCUMENT]},V,{provide:R,useClass:R,deps:[_,S,r.APP_ID]},{provide:r.RendererFactory2,useExisting:R},{provide:b,useExisting:S},{provide:S,useClass:S,deps:[e.DOCUMENT]},{provide:r.Testability,useClass:r.Testability,deps:[r.NgZone]},{provide:_,useClass:_,deps:[w,r.NgZone]},v],it=function(){function t(t){if(t)throw new Error("BrowserModule has already been loaded. If you need access to common directives such as NgIf and NgFor from a lazy loaded module, import CommonModule instead.")}return t.withServerTransition=function(e){return{ngModule:t,providers:[{provide:r.APP_ID,useValue:e.appId},{provide:c,useExisting:r.APP_ID},l]}},t}();
/**
     * @license
     * Copyright Google LLC All Rights Reserved.
     *
     * Use of this source code is governed by an MIT-style license that can be
     * found in the LICENSE file at https://angular.io/license
     */
function at(){return new st(r.ɵɵinject(e.DOCUMENT))}it.decorators=[{type:r.NgModule,args:[{providers:ot,exports:[e.CommonModule,r.ApplicationModule]}]}],it.ctorParameters=function(){return[{type:it,decorators:[{type:r.Optional},{type:r.SkipSelf},{type:r.Inject,args:[it]}]}]};var st=function(){function t(t){this._doc=t,this._dom=e.ɵgetDOM()}return t.prototype.addTag=function(t,e){return void 0===e&&(e=!1),t?this._getOrCreateElement(t,e):null},t.prototype.addTags=function(t,e){var r=this;return void 0===e&&(e=!1),t?t.reduce((function(t,n){return n&&t.push(r._getOrCreateElement(n,e)),t}),[]):[]},t.prototype.getTag=function(t){return t&&this._doc.querySelector("meta["+t+"]")||null},t.prototype.getTags=function(t){if(!t)return[];var e=this._doc.querySelectorAll("meta["+t+"]");return e?[].slice.call(e):[]},t.prototype.updateTag=function(t,e){if(!t)return null;e=e||this._parseSelector(t);var r=this.getTag(e);return r?this._setMetaElementAttributes(t,r):this._getOrCreateElement(t,!0)},t.prototype.removeTag=function(t){this.removeTagElement(this.getTag(t))},t.prototype.removeTagElement=function(t){t&&this._dom.remove(t)},t.prototype._getOrCreateElement=function(t,e){if(void 0===e&&(e=!1),!e){var r=this._parseSelector(t),n=this.getTag(r);if(n&&this._containsAttributes(t,n))return n}var o=this._dom.createElement("meta");return this._setMetaElementAttributes(t,o),this._doc.getElementsByTagName("head")[0].appendChild(o),o},t.prototype._setMetaElementAttributes=function(t,e){var r=this;return Object.keys(t).forEach((function(n){return e.setAttribute(r._getMetaKeyMap(n),t[n])})),e},t.prototype._parseSelector=function(t){var e=t.name?"name":"property";return e+'="'+t[e]+'"'},t.prototype._containsAttributes=function(t,e){var r=this;return Object.keys(t).every((function(n){return e.getAttribute(r._getMetaKeyMap(n))===t[n]}))},t.prototype._getMetaKeyMap=function(t){return ut[t]||t},t}();st.ɵprov=r.ɵɵdefineInjectable({factory:at,token:st,providedIn:"root"}),st.decorators=[{type:r.Injectable,args:[{providedIn:"root",useFactory:at,deps:[]}]}],st.ctorParameters=function(){return[{type:void 0,decorators:[{type:r.Inject,args:[e.DOCUMENT]}]}]};var ut={httpEquiv:"http-equiv"};
/**
     * @license
     * Copyright Google LLC All Rights Reserved.
     *
     * Use of this source code is governed by an MIT-style license that can be
     * found in the LICENSE file at https://angular.io/license
     */function ct(){return new pt(r.ɵɵinject(e.DOCUMENT))}var pt=function(){function t(t){this._doc=t}return t.prototype.getTitle=function(){return this._doc.title},t.prototype.setTitle=function(t){this._doc.title=t||""},t}();pt.ɵprov=r.ɵɵdefineInjectable({factory:ct,token:pt,providedIn:"root"}),pt.decorators=[{type:r.Injectable,args:[{providedIn:"root",useFactory:ct,deps:[]}]}],pt.ctorParameters=function(){return[{type:void 0,decorators:[{type:r.Inject,args:[e.DOCUMENT]}]}]};
/**
     * @license
     * Copyright Google LLC All Rights Reserved.
     *
     * Use of this source code is governed by an MIT-style license that can be
     * found in the LICENSE file at https://angular.io/license
     */
var lt,dt="undefined"!=typeof window&&window||{},ft=function ft(t,e){this.msPerTick=t,this.numTicks=e},yt=function(){function t(t){this.appRef=t.injector.get(r.ApplicationRef)}return t.prototype.timeChangeDetection=function(t){var r=t&&t.record,n=null!=dt.console.profile;r&&n&&dt.console.profile("Change Detection");for(var o=e.ɵgetDOM().performanceNow(),i=0;i<5||e.ɵgetDOM().performanceNow()-o<500;)this.appRef.tick(),i++;var a=e.ɵgetDOM().performanceNow();r&&n&&dt.console.profileEnd("Change Detection");var s=(a-o)/i;return dt.console.log("ran "+i+" change detection cycles"),dt.console.log(s.toFixed(2)+" ms per check"),new ft(s,i)},t}(),ht=function(){function t(){this.store={},this.onSerializeCallbacks={}}return t.init=function(e){var r=new t;return r.store=e,r},t.prototype.get=function(t,e){return void 0!==this.store[t]?this.store[t]:e},t.prototype.set=function(t,e){this.store[t]=e},t.prototype.remove=function(t){delete this.store[t]},t.prototype.hasKey=function(t){return this.store.hasOwnProperty(t)},t.prototype.onSerialize=function(t,e){this.onSerializeCallbacks[t]=e},t.prototype.toJson=function(){for(var t in this.onSerializeCallbacks)if(this.onSerializeCallbacks.hasOwnProperty(t))try{this.store[t]=this.onSerializeCallbacks[t]()}catch(t){console.warn("Exception in onSerialize callback: ",t)}return JSON.stringify(this.store)},t}();
/**
     * @license
     * Copyright Google LLC All Rights Reserved.
     *
     * Use of this source code is governed by an MIT-style license that can be
     * found in the LICENSE file at https://angular.io/license
     */function gt(t,e){var r=t.getElementById(e+"-state"),n={};if(r&&r.textContent)try{n=JSON.parse(function o(t){var e={"&a;":"&","&q;":'"',"&s;":"'","&l;":"<","&g;":">"};return t.replace(/&[^;]+;/g,(function(t){return e[t]}))}(r.textContent))}catch(t){console.warn("Exception while restoring TransferState for app "+e,t)}return ht.init(n)}ht.decorators=[{type:r.Injectable}],(lt=function lt(){}).decorators=[{type:r.NgModule,args:[{providers:[{provide:ht,useFactory:gt,deps:[e.DOCUMENT,r.APP_ID]}]}]}];
/**
     * @license
     * Copyright Google LLC All Rights Reserved.
     *
     * Use of this source code is governed by an MIT-style license that can be
     * found in the LICENSE file at https://angular.io/license
     */
var mt=function(){function t(){}return t.all=function(){return function(){return!0}},t.css=function(t){return function(r){return null!=r.nativeElement&&function n(t,r){return!!e.ɵgetDOM().isElementNode(t)&&(t.matches&&t.matches(r)||t.msMatchesSelector&&t.msMatchesSelector(r)||t.webkitMatchesSelector&&t.webkitMatchesSelector(r))}
/**
     * @license
     * Copyright Google LLC All Rights Reserved.
     *
     * Use of this source code is governed by an MIT-style license that can be
     * found in the LICENSE file at https://angular.io/license
     */
/**
     * @license
     * Copyright Google LLC All Rights Reserved.
     *
     * Use of this source code is governed by an MIT-style license that can be
     * found in the LICENSE file at https://angular.io/license
     */(r.nativeElement,t)}},t.directive=function(t){return function(e){return-1!==e.providerTokens.indexOf(t)}},t}(),vt=new r.Version("11.2.14");
/**
     * @license
     * Copyright Google LLC All Rights Reserved.
     *
     * Use of this source code is governed by an MIT-style license that can be
     * found in the LICENSE file at https://angular.io/license
     */
/**
     * @license
     * Copyright Google LLC All Rights Reserved.
     *
     * Use of this source code is governed by an MIT-style license that can be
     * found in the LICENSE file at https://angular.io/license
     */
/**
     * @license
     * Copyright Google LLC All Rights Reserved.
     *
     * Use of this source code is governed by an MIT-style license that can be
     * found in the LICENSE file at https://angular.io/license
     */
Object.defineProperty(t,"ɵgetDOM",{enumerable:!0,get:function(){return e.ɵgetDOM}}),t.BrowserModule=it,t.BrowserTransferStateModule=lt,t.By=mt,t.DomSanitizer=G,t.EVENT_MANAGER_PLUGINS=w,t.EventManager=_,t.HAMMER_GESTURE_CONFIG=H,t.HAMMER_LOADER=x,t.HammerGestureConfig=U,t.HammerModule=z,t.Meta=st,t.Title=pt,t.TransferState=ht,t.VERSION=vt,t.disableDebugTools=function wt(){f("profiler",null)}
/**
     * @license
     * Copyright Google LLC All Rights Reserved.
     *
     * Use of this source code is governed by an MIT-style license that can be
     * found in the LICENSE file at https://angular.io/license
     */,t.enableDebugTools=function _t(t){return f("profiler",new yt(t)),t},t.makeStateKey=function Et(t){return t},t.platformBrowser=nt,t.ɵBROWSER_SANITIZATION_PROVIDERS=rt,t.ɵBROWSER_SANITIZATION_PROVIDERS__POST_R3__=[],t.ɵBrowserDomAdapter=s,t.ɵBrowserGetTestability=d,t.ɵDomEventsPlugin=L,t.ɵDomRendererFactory2=R,t.ɵDomSanitizerImpl=Y,t.ɵDomSharedStylesHost=S,t.ɵELEMENT_PROBE_PROVIDERS=v,t.ɵELEMENT_PROBE_PROVIDERS__POST_R3__=[],t.ɵHAMMER_PROVIDERS__POST_R3__=[],t.ɵHammerGesturesPlugin=B,t.ɵINTERNAL_BROWSER_PLATFORM_PROVIDERS=et,t.ɵKeyEventsPlugin=J,t.ɵNAMESPACE_URIS=C,t.ɵSharedStylesHost=b,t.ɵTRANSITION_ID=c,t.ɵangular_packages_platform_browser_platform_browser_a=$,t.ɵangular_packages_platform_browser_platform_browser_b=tt,t.ɵangular_packages_platform_browser_platform_browser_c=ot,t.ɵangular_packages_platform_browser_platform_browser_d=at,t.ɵangular_packages_platform_browser_platform_browser_e=ct,t.ɵangular_packages_platform_browser_platform_browser_f=gt,t.ɵangular_packages_platform_browser_platform_browser_g=E,t.ɵangular_packages_platform_browser_platform_browser_h=F,t.ɵangular_packages_platform_browser_platform_browser_i=V,t.ɵangular_packages_platform_browser_platform_browser_j=X,t.ɵangular_packages_platform_browser_platform_browser_k=p,t.ɵangular_packages_platform_browser_platform_browser_l=l,t.ɵangular_packages_platform_browser_platform_browser_m=g,t.ɵangular_packages_platform_browser_platform_browser_n=m,t.ɵangular_packages_platform_browser_platform_browser_o=a,t.ɵescapeHtml=function bt(t){var e={"&":"&a;",'"':"&q;","'":"&s;","<":"&l;",">":"&g;"};return t.replace(/[&"'<>]/g,(function(t){return e[t]}))},t.ɵflattenStyles=M,t.ɵinitDomAdapter=Q,t.ɵshimContentAttribute=O,t.ɵshimHostAttribute=A,Object.defineProperty(t,"__esModule",{value:!0})}));