/**
 * @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/compiler")):"function"==typeof define&&define.amd?define("@angular/compiler/testing",["exports","@angular/compiler"],e):e(((t=t||self).ng=t.ng||{},t.ng.compiler=t.ng.compiler||{},t.ng.compiler.testing={}),t.ng.compiler)}(this,(function(t,e){"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 r=function(t,e){return(r=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 o(){this.constructor=t}r(t,e),t.prototype=null===e?Object.create(e):(o.prototype=e.prototype,new o)}function n(t,e){var r="function"==typeof Symbol&&t[Symbol.iterator];if(!r)return t;var o,n,i=r.call(t),s=[];try{for(;(void 0===e||e-- >0)&&!(o=i.next()).done;)s.push(o.value)}catch(t){n={error:t}}finally{try{o&&!o.done&&(r=i.return)&&r.call(i)}finally{if(n)throw n.error}}return s}function i(){for(var t=[],e=0;e<arguments.length;e++)t=t.concat(n(arguments[e]));return t}var s=function(t){function e(){var e=t.apply(this,i(arguments))||this;return e._expectations=[],e._definitions=new Map,e._requests=[],e}return o(e,t),e.prototype.get=function(t){var e=new u(t);return this._requests.push(e),e.getPromise()},e.prototype.hasPendingRequests=function(){return!!this._requests.length},e.prototype.expect=function(t,e){var r=new p(t,e);this._expectations.push(r)},e.prototype.when=function(t,e){this._definitions.set(t,e)},e.prototype.flush=function(){if(0===this._requests.length)throw new Error("No pending requests to flush");do{this._processRequest(this._requests.shift())}while(this._requests.length>0);this.verifyNoOutstandingExpectations()},e.prototype.verifyNoOutstandingExpectations=function(){if(0!==this._expectations.length){for(var t=[],e=0;e<this._expectations.length;e++)t.push(this._expectations[e].url);throw new Error("Unsatisfied requests: "+t.join(", "))}},e.prototype._processRequest=function(t){var e=t.url;if(this._expectations.length>0){var r=this._expectations[0];if(r.url==e)return function o(t,e){var r=t.indexOf(e);r>-1&&t.splice(r,1)}
/**
     * @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
     */(this._expectations,r),void t.complete(r.response)}if(!this._definitions.has(e))throw new Error("Unexpected request "+e);var n=this._definitions.get(e);t.complete(null==n?null:n)},e}(e.ResourceLoader),u=function(){function t(t){var e=this;this.url=t,this.promise=new Promise((function(t,r){e.resolve=t,e.reject=r}))}return t.prototype.complete=function(t){null==t?this.reject("Failed to load "+this.url):this.resolve(t)},t.prototype.getPromise=function(){return this.promise},t}(),p=function p(t,e){this.url=t,this.response=e},c=function(){function t(t,e,r,o,n){this.existingProperties=t,this.attrPropMapping=e,this.existingElements=r,this.invalidProperties=o,this.invalidAttributes=n}return t.prototype.hasProperty=function(t,e,r){var o=this.existingProperties[e];return void 0===o||o},t.prototype.hasElement=function(t,e){var r=this.existingElements[t.toLowerCase()];return void 0===r||r},t.prototype.allKnownElementNames=function(){return Object.keys(this.existingElements)},t.prototype.securityContext=function(t,r,o){return e.core.SecurityContext.NONE},t.prototype.getMappedPropName=function(t){return this.attrPropMapping[t]||t},t.prototype.getDefaultComponentElementName=function(){return"ng-component"},t.prototype.validateProperty=function(t){return this.invalidProperties.indexOf(t)>-1?{error:!0,msg:"Binding to property '"+t+"' is disallowed for security reasons"}:{error:!1}},t.prototype.validateAttribute=function(t){return this.invalidAttributes.indexOf(t)>-1?{error:!0,msg:"Binding to attribute '"+t+"' is disallowed for security reasons"}:{error:!1}},t.prototype.normalizeAnimationStyleProperty=function(t){return t},t.prototype.normalizeAnimationStyleValue=function(t,e,r){return{error:null,value:r.toString()}},t}(),l=function(t){function e(e){var r=t.call(this,e)||this;return r._directives=new Map,r}return o(e,t),e.prototype.resolve=function(e,r){return void 0===r&&(r=!0),this._directives.get(e)||t.prototype.resolve.call(this,e,r)},e.prototype.setDirective=function(t,e){this._directives.set(t,e)},e}(e.DirectiveResolver),a=function(t){function e(e){var r=t.call(this,e)||this;return r._ngModules=new Map,r}return o(e,t),e.prototype.setNgModule=function(t,e){this._ngModules.set(t,e)},e.prototype.resolve=function(e,r){return void 0===r&&(r=!0),this._ngModules.get(e)||t.prototype.resolve.call(this,e,r)},e}(e.NgModuleResolver),f=function(t){function e(e){var r=t.call(this,e)||this;return r._pipes=new Map,r}return o(e,t),e.prototype.setPipe=function(t,e){this._pipes.set(t,e)},e.prototype.resolve=function(e,r){void 0===r&&(r=!0);var o=this._pipes.get(e);return o||(o=t.prototype.resolve.call(this,e,r)),o},e}(e.PipeResolver);
/**
     * @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
     */
t.MockDirectiveResolver=l,t.MockNgModuleResolver=a,t.MockPipeResolver=f,t.MockResourceLoader=s,t.MockSchemaRegistry=c,Object.defineProperty(t,"__esModule",{value:!0})}));