!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports,require("@angular/cdk/platform"),require("@angular/core"),require("@angular/cdk/coercion"),require("rxjs"),require("rxjs/operators"),require("@angular/common")):"function"==typeof define&&define.amd?define("@angular/cdk/text-field",["exports","@angular/cdk/platform","@angular/core","@angular/cdk/coercion","rxjs","rxjs/operators","@angular/common"],t):t(((e=e||self).ng=e.ng||{},e.ng.cdk=e.ng.cdk||{},e.ng.cdk.textField={}),e.ng.cdk.platform,e.ng.core,e.ng.cdk.coercion,e.rxjs,e.rxjs.operators,e.ng.common)}(this,(function(e,t,i,n,o,r,s){"use strict";
/**
     * @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 a=t.normalizePassiveListenerOptions({passive:!0}),l=function(){function e(e,t){this._platform=e,this._ngZone=t,this._monitoredElements=new Map}return e.prototype.monitor=function(e){var t=this;if(!this._platform.isBrowser)return o.EMPTY;var i=n.coerceElement(e),r=this._monitoredElements.get(i);if(r)return r.subject;var s=new o.Subject,l="cdk-text-field-autofilled",c=function(e){"cdk-text-field-autofill-start"!==e.animationName||i.classList.contains(l)?"cdk-text-field-autofill-end"===e.animationName&&i.classList.contains(l)&&(i.classList.remove(l),t._ngZone.run((function(){return s.next({target:e.target,isAutofilled:!1})}))):(i.classList.add(l),t._ngZone.run((function(){return s.next({target:e.target,isAutofilled:!0})})))};return this._ngZone.runOutsideAngular((function(){i.addEventListener("animationstart",c,a),i.classList.add("cdk-text-field-autofill-monitored")})),this._monitoredElements.set(i,{subject:s,unlisten:function(){i.removeEventListener("animationstart",c,a)}}),s},e.prototype.stopMonitoring=function(e){var t=n.coerceElement(e),i=this._monitoredElements.get(t);i&&(i.unlisten(),i.subject.complete(),t.classList.remove("cdk-text-field-autofill-monitored"),t.classList.remove("cdk-text-field-autofilled"),this._monitoredElements.delete(t))},e.prototype.ngOnDestroy=function(){var e=this;this._monitoredElements.forEach((function(t,i){return e.stopMonitoring(i)}))},e}();l.ɵprov=i.ɵɵdefineInjectable({factory:function e(){return new l(i.ɵɵinject(t.Platform),i.ɵɵinject(i.NgZone))},token:l,providedIn:"root"}),l.decorators=[{type:i.Injectable,args:[{providedIn:"root"}]}],l.ctorParameters=function(){return[{type:t.Platform},{type:i.NgZone}]};var c=function(){function e(e,t){this._elementRef=e,this._autofillMonitor=t,this.cdkAutofill=new i.EventEmitter}return e.prototype.ngOnInit=function(){var e=this;this._autofillMonitor.monitor(this._elementRef).subscribe((function(t){return e.cdkAutofill.emit(t)}))},e.prototype.ngOnDestroy=function(){this._autofillMonitor.stopMonitoring(this._elementRef)},e}();c.decorators=[{type:i.Directive,args:[{selector:"[cdkAutofill]"}]}],c.ctorParameters=function(){return[{type:i.ElementRef},{type:l}]},c.propDecorators={cdkAutofill:[{type:i.Output}]};
/**
     * @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 u,d=function(){function e(e,t,i,n){this._elementRef=e,this._platform=t,this._ngZone=i,this._destroyed=new o.Subject,this._enabled=!0,this._previousMinRows=-1,this._document=n,this._textareaElement=this._elementRef.nativeElement,this._measuringClass=t.FIREFOX?"cdk-textarea-autosize-measuring-firefox":"cdk-textarea-autosize-measuring"}return Object.defineProperty(e.prototype,"minRows",{get:function(){return this._minRows},set:function(e){this._minRows=n.coerceNumberProperty(e),this._setMinHeight()},enumerable:!1,configurable:!0}),Object.defineProperty(e.prototype,"maxRows",{get:function(){return this._maxRows},set:function(e){this._maxRows=n.coerceNumberProperty(e),this._setMaxHeight()},enumerable:!1,configurable:!0}),Object.defineProperty(e.prototype,"enabled",{get:function(){return this._enabled},set:function(e){e=n.coerceBooleanProperty(e),this._enabled!==e&&((this._enabled=e)?this.resizeToFitContent(!0):this.reset())},enumerable:!1,configurable:!0}),e.prototype._setMinHeight=function(){var e=this.minRows&&this._cachedLineHeight?this.minRows*this._cachedLineHeight+"px":null;e&&(this._textareaElement.style.minHeight=e)},e.prototype._setMaxHeight=function(){var e=this.maxRows&&this._cachedLineHeight?this.maxRows*this._cachedLineHeight+"px":null;e&&(this._textareaElement.style.maxHeight=e)},e.prototype.ngAfterViewInit=function(){var e=this;this._platform.isBrowser&&(this._initialHeight=this._textareaElement.style.height,this.resizeToFitContent(),this._ngZone.runOutsideAngular((function(){var t=e._getWindow();o.fromEvent(t,"resize").pipe(r.auditTime(16),r.takeUntil(e._destroyed)).subscribe((function(){return e.resizeToFitContent(!0)}))})))},e.prototype.ngOnDestroy=function(){this._destroyed.next(),this._destroyed.complete()},e.prototype._cacheTextareaLineHeight=function(){if(!this._cachedLineHeight){var e=this._textareaElement.cloneNode(!1);e.rows=1,e.style.position="absolute",e.style.visibility="hidden",e.style.border="none",e.style.padding="0",e.style.height="",e.style.minHeight="",e.style.maxHeight="",e.style.overflow="hidden",this._textareaElement.parentNode.appendChild(e),this._cachedLineHeight=e.clientHeight,this._textareaElement.parentNode.removeChild(e),this._setMinHeight(),this._setMaxHeight()}},e.prototype.ngDoCheck=function(){this._platform.isBrowser&&this.resizeToFitContent()},e.prototype.resizeToFitContent=function(e){var t=this;if(void 0===e&&(e=!1),this._enabled&&(this._cacheTextareaLineHeight(),this._cachedLineHeight)){var i=this._elementRef.nativeElement,n=i.value;if(e||this._minRows!==this._previousMinRows||n!==this._previousValue){var o=i.placeholder;i.classList.add(this._measuringClass),i.placeholder="",i.style.height=i.scrollHeight-4+"px",i.classList.remove(this._measuringClass),i.placeholder=o,this._ngZone.runOutsideAngular((function(){"undefined"!=typeof requestAnimationFrame?requestAnimationFrame((function(){return t._scrollToCaretPosition(i)})):setTimeout((function(){return t._scrollToCaretPosition(i)}))})),this._previousValue=n,this._previousMinRows=this._minRows}}},e.prototype.reset=function(){void 0!==this._initialHeight&&(this._textareaElement.style.height=this._initialHeight)},e.prototype._noopInputHandler=function(){},e.prototype._getDocument=function(){return this._document||document},e.prototype._getWindow=function(){return this._getDocument().defaultView||window},e.prototype._scrollToCaretPosition=function(e){var t=e.selectionStart,i=e.selectionEnd,n=this._getDocument();this._destroyed.isStopped||n.activeElement!==e||e.setSelectionRange(t,i)},e}();d.decorators=[{type:i.Directive,args:[{selector:"textarea[cdkTextareaAutosize]",exportAs:"cdkTextareaAutosize",host:{class:"cdk-textarea-autosize",rows:"1"}}]}],d.ctorParameters=function(){return[{type:i.ElementRef},{type:t.Platform},{type:i.NgZone},{type:void 0,decorators:[{type:i.Optional},{type:i.Inject,args:[s.DOCUMENT]}]}]},d.propDecorators={minRows:[{type:i.Input,args:["cdkAutosizeMinRows"]}],maxRows:[{type:i.Input,args:["cdkAutosizeMaxRows"]}],enabled:[{type:i.Input,args:["cdkTextareaAutosize"]}],_noopInputHandler:[{type:i.HostListener,args:["input"]}]},(u=function u(){}).decorators=[{type:i.NgModule,args:[{declarations:[c,d],imports:[t.PlatformModule],exports:[c,d]}]}],
/**
     * @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.AutofillMonitor=l,e.CdkAutofill=c,e.CdkTextareaAutosize=d,e.TextFieldModule=u,Object.defineProperty(e,"__esModule",{value:!0})}));