{"version":3,"file":"forms.js","sources":["../../../packages/forms/src/directives/abstract_control_directive.js","../../../packages/forms/src/directives/control_container.js","../../../packages/forms/src/validators.js","../../../packages/forms/src/directives/control_value_accessor.js","../../../packages/forms/src/directives/checkbox_value_accessor.js","../../../packages/forms/src/directives/default_value_accessor.js","../../../packages/forms/src/directives/normalize_validator.js","../../../packages/forms/src/directives/number_value_accessor.js","../../../packages/forms/src/directives/ng_control.js","../../../packages/forms/src/directives/radio_control_value_accessor.js","../../../packages/forms/src/directives/range_value_accessor.js","../../../packages/forms/src/directives/select_control_value_accessor.js","../../../packages/forms/src/directives/select_multiple_control_value_accessor.js","../../../packages/forms/src/directives/shared.js","../../../packages/forms/src/directives/abstract_form_group_directive.js","../../../packages/forms/src/directives/ng_control_status.js","../../../packages/forms/src/model.js","../../../packages/forms/src/directives/ng_form.js","../../../packages/forms/src/directives/error_examples.js","../../../packages/forms/src/directives/template_driven_errors.js","../../../packages/forms/src/directives/ng_model_group.js","../../../packages/forms/src/directives/ng_model.js","../../../packages/forms/src/directives/reactive_errors.js","../../../packages/forms/src/directives/reactive_directives/form_control_directive.js","../../../packages/forms/src/directives/reactive_directives/form_group_directive.js","../../../packages/forms/src/directives/reactive_directives/form_group_name.js","../../../packages/forms/src/directives/reactive_directives/form_control_name.js","../../../packages/forms/src/directives/validators.js","../../../packages/forms/src/form_builder.js","../../../packages/forms/src/version.js","../../../packages/forms/src/directives/ng_no_validate_directive.js","../../../packages/forms/src/directives.js","../../../packages/forms/src/form_providers.js","../../../packages/forms/src/forms.js","../../../packages/forms/public_api.js","../../../packages/forms/forms.js"],"sourcesContent":["/**\n * @fileoverview added by tsickle\n * @suppress {checkTypes} checked by tsc\n */\n/**\n * @license\n * Copyright Google Inc. All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n/**\n * Base class for control directives.\n *\n * Only used internally in the forms module.\n *\n * \\@stable\n * @abstract\n */\nexport class AbstractControlDirective {\n /**\n * The value of the control.\n * @return {?}\n */\n get value() { return this.control ? this.control.value : null; }\n /**\n * A control is `valid` when its `status === VALID`.\n *\n * In order to have this status, the control must have passed all its\n * validation checks.\n * @return {?}\n */\n get valid() { return this.control ? this.control.valid : null; }\n /**\n * A control is `invalid` when its `status === INVALID`.\n *\n * In order to have this status, the control must have failed\n * at least one of its validation checks.\n * @return {?}\n */\n get invalid() { return this.control ? this.control.invalid : null; }\n /**\n * A control is `pending` when its `status === PENDING`.\n *\n * In order to have this status, the control must be in the\n * middle of conducting a validation check.\n * @return {?}\n */\n get pending() { return this.control ? this.control.pending : null; }\n /**\n * A control is `disabled` when its `status === DISABLED`.\n *\n * Disabled controls are exempt from validation checks and\n * are not included in the aggregate value of their ancestor\n * controls.\n * @return {?}\n */\n get disabled() { return this.control ? this.control.disabled : null; }\n /**\n * A control is `enabled` as long as its `status !== DISABLED`.\n *\n * In other words, it has a status of `VALID`, `INVALID`, or\n * `PENDING`.\n * @return {?}\n */\n get enabled() { return this.control ? this.control.enabled : null; }\n /**\n * Returns any errors generated by failing validation. If there\n * are no errors, it will return null.\n * @return {?}\n */\n get errors() { return this.control ? this.control.errors : null; }\n /**\n * A control is `pristine` if the user has not yet changed\n * the value in the UI.\n *\n * Note that programmatic changes to a control's value will\n * *not* mark it dirty.\n * @return {?}\n */\n get pristine() { return this.control ? this.control.pristine : null; }\n /**\n * A control is `dirty` if the user has changed the value\n * in the UI.\n *\n * Note that programmatic changes to a control's value will\n * *not* mark it dirty.\n * @return {?}\n */\n get dirty() { return this.control ? this.control.dirty : null; }\n /**\n * A control is marked `touched` once the user has triggered\n * a `blur` event on it.\n * @return {?}\n */\n get touched() { return this.control ? this.control.touched : null; }\n /**\n * @return {?}\n */\n get status() { return this.control ? this.control.status : null; }\n /**\n * A control is `untouched` if the user has not yet triggered\n * a `blur` event on it.\n * @return {?}\n */\n get untouched() { return this.control ? this.control.untouched : null; }\n /**\n * Emits an event every time the validation status of the control\n * is re-calculated.\n * @return {?}\n */\n get statusChanges() {\n return this.control ? this.control.statusChanges : null;\n }\n /**\n * Emits an event every time the value of the control changes, in\n * the UI or programmatically.\n * @return {?}\n */\n get valueChanges() {\n return this.control ? this.control.valueChanges : null;\n }\n /**\n * Returns an array that represents the path from the top-level form\n * to this control. Each index is the string name of the control on\n * that level.\n * @return {?}\n */\n get path() { return null; }\n /**\n * Resets the form control. This means by default:\n *\n * * it is marked as `pristine`\n * * it is marked as `untouched`\n * * value is set to null\n *\n * For more information, see {\\@link AbstractControl}.\n * @param {?=} value\n * @return {?}\n */\n reset(value = undefined) {\n if (this.control)\n this.control.reset(value);\n }\n /**\n * Returns true if the control with the given path has the error specified. Otherwise\n * returns false.\n *\n * If no path is given, it checks for the error on the present control.\n * @param {?} errorCode\n * @param {?=} path\n * @return {?}\n */\n hasError(errorCode, path) {\n return this.control ? this.control.hasError(errorCode, path) : false;\n }\n /**\n * Returns error data if the control with the given path has the error specified. Otherwise\n * returns null or undefined.\n *\n * If no path is given, it checks for the error on the present control.\n * @param {?} errorCode\n * @param {?=} path\n * @return {?}\n */\n getError(errorCode, path) {\n return this.control ? this.control.getError(errorCode, path) : null;\n }\n}\nfunction AbstractControlDirective_tsickle_Closure_declarations() {\n /**\n * The {\\@link FormControl}, {\\@link FormGroup}, or {\\@link FormArray}\n * that backs this directive. Most properties fall through to that\n * instance.\n * @abstract\n * @return {?}\n */\n AbstractControlDirective.prototype.control = function () { };\n}\n//# sourceMappingURL=abstract_control_directive.js.map","/**\n * @fileoverview added by tsickle\n * @suppress {checkTypes} checked by tsc\n */\n/**\n * @license\n * Copyright Google Inc. All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\nimport { AbstractControlDirective } from './abstract_control_directive';\n/**\n * A directive that contains multiple {\\@link NgControl}s.\n *\n * Only used by the forms module.\n *\n * \\@stable\n * @abstract\n */\nexport class ControlContainer extends AbstractControlDirective {\n /**\n * Get the form to which this container belongs.\n * @return {?}\n */\n get formDirective() { return null; }\n /**\n * Get the path to this container.\n * @return {?}\n */\n get path() { return null; }\n}\nfunction ControlContainer_tsickle_Closure_declarations() {\n /** @type {?} */\n ControlContainer.prototype.name;\n}\n//# sourceMappingURL=control_container.js.map","/**\n * @fileoverview added by tsickle\n * @suppress {checkTypes} checked by tsc\n */\n/**\n * @license\n * Copyright Google Inc. All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\nimport { InjectionToken, ɵisObservable as isObservable, ɵisPromise as isPromise } from '@angular/core';\nimport { forkJoin } from 'rxjs/observable/forkJoin';\nimport { fromPromise } from 'rxjs/observable/fromPromise';\nimport { map } from 'rxjs/operator/map';\n/**\n * @param {?} value\n * @return {?}\n */\nfunction isEmptyInputValue(value) {\n // we don't check for string here so it also works with arrays\n return value == null || value.length === 0;\n}\n/**\n * Providers for validators to be used for {\\@link FormControl}s in a form.\n *\n * Provide this using `multi: true` to add validators.\n *\n * ### Example\n *\n * ```typescript\n * \\@Directive({\n * selector: '[custom-validator]',\n * providers: [{provide: NG_VALIDATORS, useExisting: CustomValidatorDirective, multi: true}]\n * })\n * class CustomValidatorDirective implements Validator {\n * validate(control: AbstractControl): ValidationErrors | null {\n * return {\"custom\": true};\n * }\n * }\n * ```\n *\n * \\@stable\n */\nexport const /** @type {?} */ NG_VALIDATORS = new InjectionToken('NgValidators');\n/**\n * Providers for asynchronous validators to be used for {\\@link FormControl}s\n * in a form.\n *\n * Provide this using `multi: true` to add validators.\n *\n * See {\\@link NG_VALIDATORS} for more details.\n *\n * \\@stable\n */\nexport const /** @type {?} */ NG_ASYNC_VALIDATORS = new InjectionToken('NgAsyncValidators');\nconst /** @type {?} */ EMAIL_REGEXP = /^(?=.{1,254}$)(?=.{1,64}@)[-!#$%&'*+/0-9=?A-Z^_`a-z{|}~]+(\\.[-!#$%&'*+/0-9=?A-Z^_`a-z{|}~]+)*@[A-Za-z0-9]([A-Za-z0-9-]{0,61}[A-Za-z0-9])?(\\.[A-Za-z0-9]([A-Za-z0-9-]{0,61}[A-Za-z0-9])?)*$/;\n/**\n * Provides a set of validators used by form controls.\n *\n * A validator is a function that processes a {\\@link FormControl} or collection of\n * controls and returns a map of errors. A null map means that validation has passed.\n *\n * ### Example\n *\n * ```typescript\n * var loginControl = new FormControl(\"\", Validators.required)\n * ```\n *\n * \\@stable\n */\nexport class Validators {\n /**\n * Validator that requires controls to have a value greater than a number.\n * `min()` exists only as a function, not as a directive. For example,\n * `control = new FormControl('', Validators.min(3));`.\n * @param {?} min\n * @return {?}\n */\n static min(min) {\n return (control) => {\n if (isEmptyInputValue(control.value) || isEmptyInputValue(min)) {\n return null; // don't validate empty values to allow optional controls\n }\n const /** @type {?} */ value = parseFloat(control.value);\n // Controls with NaN values after parsing should be treated as not having a\n // minimum, per the HTML forms spec: https://www.w3.org/TR/html5/forms.html#attr-input-min\n return !isNaN(value) && value < min ? { 'min': { 'min': min, 'actual': control.value } } : null;\n };\n }\n /**\n * Validator that requires controls to have a value less than a number.\n * `max()` exists only as a function, not as a directive. For example,\n * `control = new FormControl('', Validators.max(15));`.\n * @param {?} max\n * @return {?}\n */\n static max(max) {\n return (control) => {\n if (isEmptyInputValue(control.value) || isEmptyInputValue(max)) {\n return null; // don't validate empty values to allow optional controls\n }\n const /** @type {?} */ value = parseFloat(control.value);\n // Controls with NaN values after parsing should be treated as not having a\n // maximum, per the HTML forms spec: https://www.w3.org/TR/html5/forms.html#attr-input-max\n return !isNaN(value) && value > max ? { 'max': { 'max': max, 'actual': control.value } } : null;\n };\n }\n /**\n * Validator that requires controls to have a non-empty value.\n * @param {?} control\n * @return {?}\n */\n static required(control) {\n return isEmptyInputValue(control.value) ? { 'required': true } : null;\n }\n /**\n * Validator that requires control value to be true.\n * @param {?} control\n * @return {?}\n */\n static requiredTrue(control) {\n return control.value === true ? null : { 'required': true };\n }\n /**\n * Validator that performs email validation.\n * @param {?} control\n * @return {?}\n */\n static email(control) {\n return EMAIL_REGEXP.test(control.value) ? null : { 'email': true };\n }\n /**\n * Validator that requires controls to have a value of a minimum length.\n * @param {?} minLength\n * @return {?}\n */\n static minLength(minLength) {\n return (control) => {\n if (isEmptyInputValue(control.value)) {\n return null; // don't validate empty values to allow optional controls\n }\n const /** @type {?} */ length = control.value ? control.value.length : 0;\n return length < minLength ?\n { 'minlength': { 'requiredLength': minLength, 'actualLength': length } } :\n null;\n };\n }\n /**\n * Validator that requires controls to have a value of a maximum length.\n * @param {?} maxLength\n * @return {?}\n */\n static maxLength(maxLength) {\n return (control) => {\n const /** @type {?} */ length = control.value ? control.value.length : 0;\n return length > maxLength ?\n { 'maxlength': { 'requiredLength': maxLength, 'actualLength': length } } :\n null;\n };\n }\n /**\n * Validator that requires a control to match a regex to its value.\n * @param {?} pattern\n * @return {?}\n */\n static pattern(pattern) {\n if (!pattern)\n return Validators.nullValidator;\n let /** @type {?} */ regex;\n let /** @type {?} */ regexStr;\n if (typeof pattern === 'string') {\n regexStr = '';\n if (pattern.charAt(0) !== '^')\n regexStr += '^';\n regexStr += pattern;\n if (pattern.charAt(pattern.length - 1) !== '$')\n regexStr += '$';\n regex = new RegExp(regexStr);\n }\n else {\n regexStr = pattern.toString();\n regex = pattern;\n }\n return (control) => {\n if (isEmptyInputValue(control.value)) {\n return null; // don't validate empty values to allow optional controls\n }\n const /** @type {?} */ value = control.value;\n return regex.test(value) ? null :\n { 'pattern': { 'requiredPattern': regexStr, 'actualValue': value } };\n };\n }\n /**\n * No-op validator.\n * @param {?} c\n * @return {?}\n */\n static nullValidator(c) { return null; }\n /**\n * @param {?} validators\n * @return {?}\n */\n static compose(validators) {\n if (!validators)\n return null;\n const /** @type {?} */ presentValidators = /** @type {?} */ (validators.filter(isPresent));\n if (presentValidators.length == 0)\n return null;\n return function (control) {\n return _mergeErrors(_executeValidators(control, presentValidators));\n };\n }\n /**\n * @param {?} validators\n * @return {?}\n */\n static composeAsync(validators) {\n if (!validators)\n return null;\n const /** @type {?} */ presentValidators = /** @type {?} */ (validators.filter(isPresent));\n if (presentValidators.length == 0)\n return null;\n return function (control) {\n const /** @type {?} */ observables = _executeAsyncValidators(control, presentValidators).map(toObservable);\n return map.call(forkJoin(observables), _mergeErrors);\n };\n }\n}\n/**\n * @param {?} o\n * @return {?}\n */\nfunction isPresent(o) {\n return o != null;\n}\n/**\n * @param {?} r\n * @return {?}\n */\nexport function toObservable(r) {\n const /** @type {?} */ obs = isPromise(r) ? fromPromise(r) : r;\n if (!(isObservable(obs))) {\n throw new Error(`Expected validator to return Promise or Observable.`);\n }\n return obs;\n}\n/**\n * @param {?} control\n * @param {?} validators\n * @return {?}\n */\nfunction _executeValidators(control, validators) {\n return validators.map(v => v(control));\n}\n/**\n * @param {?} control\n * @param {?} validators\n * @return {?}\n */\nfunction _executeAsyncValidators(control, validators) {\n return validators.map(v => v(control));\n}\n/**\n * @param {?} arrayOfErrors\n * @return {?}\n */\nfunction _mergeErrors(arrayOfErrors) {\n const /** @type {?} */ res = arrayOfErrors.reduce((res, errors) => {\n return errors != null ? Object.assign({}, /** @type {?} */ ((res)), errors) : /** @type {?} */ ((res));\n }, {});\n return Object.keys(res).length === 0 ? null : res;\n}\n//# sourceMappingURL=validators.js.map","/**\n * @fileoverview added by tsickle\n * @suppress {checkTypes} checked by tsc\n */\n/**\n * @license\n * Copyright Google Inc. All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\nimport { InjectionToken } from '@angular/core';\n/**\n * A `ControlValueAccessor` acts as a bridge between the Angular forms API and a\n * native element in the DOM.\n *\n * Implement this interface if you want to create a custom form control directive\n * that integrates with Angular forms.\n *\n * \\@stable\n * @record\n */\nexport function ControlValueAccessor() { }\nfunction ControlValueAccessor_tsickle_Closure_declarations() {\n /**\n * Writes a new value to the element.\n *\n * This method will be called by the forms API to write to the view when programmatic\n * (model -> view) changes are requested.\n *\n * Example implementation of `writeValue`:\n *\n * ```ts\n * writeValue(value: any): void {\n * this._renderer.setProperty(this._elementRef.nativeElement, 'value', value);\n * }\n * ```\n * @type {?}\n */\n ControlValueAccessor.prototype.writeValue;\n /**\n * Registers a callback function that should be called when the control's value\n * changes in the UI.\n *\n * This is called by the forms API on initialization so it can update the form\n * model when values propagate from the view (view -> model).\n *\n * If you are implementing `registerOnChange` in your own value accessor, you\n * will typically want to save the given function so your class can call it\n * at the appropriate time.\n *\n * ```ts\n * registerOnChange(fn: (_: any) => void): void {\n * this._onChange = fn;\n * }\n * ```\n *\n * When the value changes in the UI, your class should call the registered\n * function to allow the forms API to update itself:\n *\n * ```ts\n * host: {\n * (change): '_onChange($event.target.value)'\n * }\n * ```\n *\n * @type {?}\n */\n ControlValueAccessor.prototype.registerOnChange;\n /**\n * Registers a callback function that should be called when the control receives\n * a blur event.\n *\n * This is called by the forms API on initialization so it can update the form model\n * on blur.\n *\n * If you are implementing `registerOnTouched` in your own value accessor, you\n * will typically want to save the given function so your class can call it\n * when the control should be considered blurred (a.k.a. \"touched\").\n *\n * ```ts\n * registerOnTouched(fn: any): void {\n * this._onTouched = fn;\n * }\n * ```\n *\n * On blur (or equivalent), your class should call the registered function to allow\n * the forms API to update itself:\n *\n * ```ts\n * host: {\n * '(blur)': '_onTouched()'\n * }\n * ```\n * @type {?}\n */\n ControlValueAccessor.prototype.registerOnTouched;\n /**\n * This function is called by the forms API when the control status changes to\n * or from \"DISABLED\". Depending on the value, it should enable or disable the\n * appropriate DOM element.\n *\n * Example implementation of `setDisabledState`:\n *\n * ```ts\n * setDisabledState(isDisabled: boolean): void {\n * this._renderer.setProperty(this._elementRef.nativeElement, 'disabled', isDisabled);\n * }\n * ```\n *\n * \\@param isDisabled\n * @type {?|undefined}\n */\n ControlValueAccessor.prototype.setDisabledState;\n}\n/**\n * Used to provide a {\\@link ControlValueAccessor} for form controls.\n *\n * See {\\@link DefaultValueAccessor} for how to implement one.\n * \\@stable\n */\nexport const /** @type {?} */ NG_VALUE_ACCESSOR = new InjectionToken('NgValueAccessor');\n//# sourceMappingURL=control_value_accessor.js.map","/**\n * @fileoverview added by tsickle\n * @suppress {checkTypes} checked by tsc\n */\n/**\n * @license\n * Copyright Google Inc. All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\nimport { Directive, ElementRef, Renderer2, forwardRef } from '@angular/core';\nimport { NG_VALUE_ACCESSOR } from './control_value_accessor';\nexport const /** @type {?} */ CHECKBOX_VALUE_ACCESSOR = {\n provide: NG_VALUE_ACCESSOR,\n useExisting: forwardRef(() => CheckboxControlValueAccessor),\n multi: true,\n};\n/**\n * The accessor for writing a value and listening to changes on a checkbox input element.\n *\n * ### Example\n * ```\n * \n * ```\n *\n * \\@stable\n */\nexport class CheckboxControlValueAccessor {\n /**\n * @param {?} _renderer\n * @param {?} _elementRef\n */\n constructor(_renderer, _elementRef) {\n this._renderer = _renderer;\n this._elementRef = _elementRef;\n this.onChange = (_) => { };\n this.onTouched = () => { };\n }\n /**\n * @param {?} value\n * @return {?}\n */\n writeValue(value) {\n this._renderer.setProperty(this._elementRef.nativeElement, 'checked', value);\n }\n /**\n * @param {?} fn\n * @return {?}\n */\n registerOnChange(fn) { this.onChange = fn; }\n /**\n * @param {?} fn\n * @return {?}\n */\n registerOnTouched(fn) { this.onTouched = fn; }\n /**\n * @param {?} isDisabled\n * @return {?}\n */\n setDisabledState(isDisabled) {\n this._renderer.setProperty(this._elementRef.nativeElement, 'disabled', isDisabled);\n }\n}\nCheckboxControlValueAccessor.decorators = [\n { type: Directive, args: [{\n selector: 'input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][ngModel]',\n host: { '(change)': 'onChange($event.target.checked)', '(blur)': 'onTouched()' },\n providers: [CHECKBOX_VALUE_ACCESSOR]\n },] },\n];\n/** @nocollapse */\nCheckboxControlValueAccessor.ctorParameters = () => [\n { type: Renderer2, },\n { type: ElementRef, },\n];\nfunction CheckboxControlValueAccessor_tsickle_Closure_declarations() {\n /** @type {!Array<{type: !Function, args: (undefined|!Array)}>} */\n CheckboxControlValueAccessor.decorators;\n /**\n * @nocollapse\n * @type {function(): !Array<(null|{type: ?, decorators: (undefined|!Array<{type: !Function, args: (undefined|!Array)}>)})>}\n */\n CheckboxControlValueAccessor.ctorParameters;\n /** @type {?} */\n CheckboxControlValueAccessor.prototype.onChange;\n /** @type {?} */\n CheckboxControlValueAccessor.prototype.onTouched;\n /** @type {?} */\n CheckboxControlValueAccessor.prototype._renderer;\n /** @type {?} */\n CheckboxControlValueAccessor.prototype._elementRef;\n}\n//# sourceMappingURL=checkbox_value_accessor.js.map","/**\n * @fileoverview added by tsickle\n * @suppress {checkTypes} checked by tsc\n */\n/**\n * @license\n * Copyright Google Inc. All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\nimport { Directive, ElementRef, Inject, InjectionToken, Optional, Renderer2, forwardRef } from '@angular/core';\nimport { ɵgetDOM as getDOM } from '@angular/platform-browser';\nimport { NG_VALUE_ACCESSOR } from './control_value_accessor';\nexport const /** @type {?} */ DEFAULT_VALUE_ACCESSOR = {\n provide: NG_VALUE_ACCESSOR,\n useExisting: forwardRef(() => DefaultValueAccessor),\n multi: true\n};\n/**\n * We must check whether the agent is Android because composition events\n * behave differently between iOS and Android.\n * @return {?}\n */\nfunction _isAndroid() {\n const /** @type {?} */ userAgent = getDOM() ? getDOM().getUserAgent() : '';\n return /android (\\d+)/.test(userAgent.toLowerCase());\n}\n/**\n * Turn this mode on if you want form directives to buffer IME input until compositionend\n * \\@experimental\n */\nexport const /** @type {?} */ COMPOSITION_BUFFER_MODE = new InjectionToken('CompositionEventMode');\n/**\n * The default accessor for writing a value and listening to changes that is used by the\n * {\\@link NgModel}, {\\@link FormControlDirective}, and {\\@link FormControlName} directives.\n *\n * ### Example\n * ```\n * \n * ```\n *\n * \\@stable\n */\nexport class DefaultValueAccessor {\n /**\n * @param {?} _renderer\n * @param {?} _elementRef\n * @param {?} _compositionMode\n */\n constructor(_renderer, _elementRef, _compositionMode) {\n this._renderer = _renderer;\n this._elementRef = _elementRef;\n this._compositionMode = _compositionMode;\n this.onChange = (_) => { };\n this.onTouched = () => { };\n /**\n * Whether the user is creating a composition string (IME events).\n */\n this._composing = false;\n if (this._compositionMode == null) {\n this._compositionMode = !_isAndroid();\n }\n }\n /**\n * @param {?} value\n * @return {?}\n */\n writeValue(value) {\n const /** @type {?} */ normalizedValue = value == null ? '' : value;\n this._renderer.setProperty(this._elementRef.nativeElement, 'value', normalizedValue);\n }\n /**\n * @param {?} fn\n * @return {?}\n */\n registerOnChange(fn) { this.onChange = fn; }\n /**\n * @param {?} fn\n * @return {?}\n */\n registerOnTouched(fn) { this.onTouched = fn; }\n /**\n * @param {?} isDisabled\n * @return {?}\n */\n setDisabledState(isDisabled) {\n this._renderer.setProperty(this._elementRef.nativeElement, 'disabled', isDisabled);\n }\n /**\n * \\@internal\n * @param {?} value\n * @return {?}\n */\n _handleInput(value) {\n if (!this._compositionMode || (this._compositionMode && !this._composing)) {\n this.onChange(value);\n }\n }\n /**\n * \\@internal\n * @return {?}\n */\n _compositionStart() { this._composing = true; }\n /**\n * \\@internal\n * @param {?} value\n * @return {?}\n */\n _compositionEnd(value) {\n this._composing = false;\n this._compositionMode && this.onChange(value);\n }\n}\nDefaultValueAccessor.decorators = [\n { type: Directive, args: [{\n selector: 'input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]',\n // TODO: vsavkin replace the above selector with the one below it once\n // https://github.com/angular/angular/issues/3011 is implemented\n // selector: '[ngModel],[formControl],[formControlName]',\n host: {\n '(input)': '$any(this)._handleInput($event.target.value)',\n '(blur)': 'onTouched()',\n '(compositionstart)': '$any(this)._compositionStart()',\n '(compositionend)': '$any(this)._compositionEnd($event.target.value)'\n },\n providers: [DEFAULT_VALUE_ACCESSOR]\n },] },\n];\n/** @nocollapse */\nDefaultValueAccessor.ctorParameters = () => [\n { type: Renderer2, },\n { type: ElementRef, },\n { type: undefined, decorators: [{ type: Optional }, { type: Inject, args: [COMPOSITION_BUFFER_MODE,] },] },\n];\nfunction DefaultValueAccessor_tsickle_Closure_declarations() {\n /** @type {!Array<{type: !Function, args: (undefined|!Array)}>} */\n DefaultValueAccessor.decorators;\n /**\n * @nocollapse\n * @type {function(): !Array<(null|{type: ?, decorators: (undefined|!Array<{type: !Function, args: (undefined|!Array)}>)})>}\n */\n DefaultValueAccessor.ctorParameters;\n /** @type {?} */\n DefaultValueAccessor.prototype.onChange;\n /** @type {?} */\n DefaultValueAccessor.prototype.onTouched;\n /**\n * Whether the user is creating a composition string (IME events).\n * @type {?}\n */\n DefaultValueAccessor.prototype._composing;\n /** @type {?} */\n DefaultValueAccessor.prototype._renderer;\n /** @type {?} */\n DefaultValueAccessor.prototype._elementRef;\n /** @type {?} */\n DefaultValueAccessor.prototype._compositionMode;\n}\n//# sourceMappingURL=default_value_accessor.js.map","/**\n * @fileoverview added by tsickle\n * @suppress {checkTypes} checked by tsc\n */\n/**\n * @license\n * Copyright Google Inc. All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n/**\n * @param {?} validator\n * @return {?}\n */\nexport function normalizeValidator(validator) {\n if ((/** @type {?} */ (validator)).validate) {\n return (c) => (/** @type {?} */ (validator)).validate(c);\n }\n else {\n return /** @type {?} */ (validator);\n }\n}\n/**\n * @param {?} validator\n * @return {?}\n */\nexport function normalizeAsyncValidator(validator) {\n if ((/** @type {?} */ (validator)).validate) {\n return (c) => (/** @type {?} */ (validator)).validate(c);\n }\n else {\n return /** @type {?} */ (validator);\n }\n}\n//# sourceMappingURL=normalize_validator.js.map","/**\n * @fileoverview added by tsickle\n * @suppress {checkTypes} checked by tsc\n */\n/**\n * @license\n * Copyright Google Inc. All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\nimport { Directive, ElementRef, Renderer2, forwardRef } from '@angular/core';\nimport { NG_VALUE_ACCESSOR } from './control_value_accessor';\nexport const /** @type {?} */ NUMBER_VALUE_ACCESSOR = {\n provide: NG_VALUE_ACCESSOR,\n useExisting: forwardRef(() => NumberValueAccessor),\n multi: true\n};\n/**\n * The accessor for writing a number value and listening to changes that is used by the\n * {\\@link NgModel}, {\\@link FormControlDirective}, and {\\@link FormControlName} directives.\n *\n * ### Example\n * ```\n * \n * ```\n */\nexport class NumberValueAccessor {\n /**\n * @param {?} _renderer\n * @param {?} _elementRef\n */\n constructor(_renderer, _elementRef) {\n this._renderer = _renderer;\n this._elementRef = _elementRef;\n this.onChange = (_) => { };\n this.onTouched = () => { };\n }\n /**\n * @param {?} value\n * @return {?}\n */\n writeValue(value) {\n // The value needs to be normalized for IE9, otherwise it is set to 'null' when null\n const /** @type {?} */ normalizedValue = value == null ? '' : value;\n this._renderer.setProperty(this._elementRef.nativeElement, 'value', normalizedValue);\n }\n /**\n * @param {?} fn\n * @return {?}\n */\n registerOnChange(fn) {\n this.onChange = (value) => { fn(value == '' ? null : parseFloat(value)); };\n }\n /**\n * @param {?} fn\n * @return {?}\n */\n registerOnTouched(fn) { this.onTouched = fn; }\n /**\n * @param {?} isDisabled\n * @return {?}\n */\n setDisabledState(isDisabled) {\n this._renderer.setProperty(this._elementRef.nativeElement, 'disabled', isDisabled);\n }\n}\nNumberValueAccessor.decorators = [\n { type: Directive, args: [{\n selector: 'input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]',\n host: {\n '(change)': 'onChange($event.target.value)',\n '(input)': 'onChange($event.target.value)',\n '(blur)': 'onTouched()'\n },\n providers: [NUMBER_VALUE_ACCESSOR]\n },] },\n];\n/** @nocollapse */\nNumberValueAccessor.ctorParameters = () => [\n { type: Renderer2, },\n { type: ElementRef, },\n];\nfunction NumberValueAccessor_tsickle_Closure_declarations() {\n /** @type {!Array<{type: !Function, args: (undefined|!Array)}>} */\n NumberValueAccessor.decorators;\n /**\n * @nocollapse\n * @type {function(): !Array<(null|{type: ?, decorators: (undefined|!Array<{type: !Function, args: (undefined|!Array)}>)})>}\n */\n NumberValueAccessor.ctorParameters;\n /** @type {?} */\n NumberValueAccessor.prototype.onChange;\n /** @type {?} */\n NumberValueAccessor.prototype.onTouched;\n /** @type {?} */\n NumberValueAccessor.prototype._renderer;\n /** @type {?} */\n NumberValueAccessor.prototype._elementRef;\n}\n//# sourceMappingURL=number_value_accessor.js.map","/**\n * @fileoverview added by tsickle\n * @suppress {checkTypes} checked by tsc\n */\n/**\n * @license\n * Copyright Google Inc. All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\nimport { AbstractControlDirective } from './abstract_control_directive';\n/**\n * @return {?}\n */\nfunction unimplemented() {\n throw new Error('unimplemented');\n}\n/**\n * A base class that all control directive extend.\n * It binds a {\\@link FormControl} object to a DOM element.\n *\n * Used internally by Angular forms.\n *\n * \\@stable\n * @abstract\n */\nexport class NgControl extends AbstractControlDirective {\n constructor() {\n super(...arguments);\n /**\n * \\@internal\n */\n this._parent = null;\n this.name = null;\n this.valueAccessor = null;\n /**\n * \\@internal\n */\n this._rawValidators = [];\n /**\n * \\@internal\n */\n this._rawAsyncValidators = [];\n }\n /**\n * @return {?}\n */\n get validator() { return /** @type {?} */ (unimplemented()); }\n /**\n * @return {?}\n */\n get asyncValidator() { return /** @type {?} */ (unimplemented()); }\n}\nfunction NgControl_tsickle_Closure_declarations() {\n /**\n * \\@internal\n * @type {?}\n */\n NgControl.prototype._parent;\n /** @type {?} */\n NgControl.prototype.name;\n /** @type {?} */\n NgControl.prototype.valueAccessor;\n /**\n * \\@internal\n * @type {?}\n */\n NgControl.prototype._rawValidators;\n /**\n * \\@internal\n * @type {?}\n */\n NgControl.prototype._rawAsyncValidators;\n /**\n * @abstract\n * @param {?} newValue\n * @return {?}\n */\n NgControl.prototype.viewToModelUpdate = function (newValue) { };\n}\n//# sourceMappingURL=ng_control.js.map","/**\n * @fileoverview added by tsickle\n * @suppress {checkTypes} checked by tsc\n */\n/**\n * @license\n * Copyright Google Inc. All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\nimport { Directive, ElementRef, Injectable, Injector, Input, Renderer2, forwardRef } from '@angular/core';\nimport { NG_VALUE_ACCESSOR } from './control_value_accessor';\nimport { NgControl } from './ng_control';\nexport const /** @type {?} */ RADIO_VALUE_ACCESSOR = {\n provide: NG_VALUE_ACCESSOR,\n useExisting: forwardRef(() => RadioControlValueAccessor),\n multi: true\n};\n/**\n * Internal class used by Angular to uncheck radio buttons with the matching name.\n */\nexport class RadioControlRegistry {\n constructor() {\n this._accessors = [];\n }\n /**\n * @param {?} control\n * @param {?} accessor\n * @return {?}\n */\n add(control, accessor) {\n this._accessors.push([control, accessor]);\n }\n /**\n * @param {?} accessor\n * @return {?}\n */\n remove(accessor) {\n for (let /** @type {?} */ i = this._accessors.length - 1; i >= 0; --i) {\n if (this._accessors[i][1] === accessor) {\n this._accessors.splice(i, 1);\n return;\n }\n }\n }\n /**\n * @param {?} accessor\n * @return {?}\n */\n select(accessor) {\n this._accessors.forEach((c) => {\n if (this._isSameGroup(c, accessor) && c[1] !== accessor) {\n c[1].fireUncheck(accessor.value);\n }\n });\n }\n /**\n * @param {?} controlPair\n * @param {?} accessor\n * @return {?}\n */\n _isSameGroup(controlPair, accessor) {\n if (!controlPair[0].control)\n return false;\n return controlPair[0]._parent === accessor._control._parent &&\n controlPair[1].name === accessor.name;\n }\n}\nRadioControlRegistry.decorators = [\n { type: Injectable },\n];\n/** @nocollapse */\nRadioControlRegistry.ctorParameters = () => [];\nfunction RadioControlRegistry_tsickle_Closure_declarations() {\n /** @type {!Array<{type: !Function, args: (undefined|!Array)}>} */\n RadioControlRegistry.decorators;\n /**\n * @nocollapse\n * @type {function(): !Array<(null|{type: ?, decorators: (undefined|!Array<{type: !Function, args: (undefined|!Array)}>)})>}\n */\n RadioControlRegistry.ctorParameters;\n /** @type {?} */\n RadioControlRegistry.prototype._accessors;\n}\n/**\n * \\@whatItDoes Writes radio control values and listens to radio control changes.\n *\n * Used by {\\@link NgModel}, {\\@link FormControlDirective}, and {\\@link FormControlName}\n * to keep the view synced with the {\\@link FormControl} model.\n *\n * \\@howToUse\n *\n * If you have imported the {\\@link FormsModule} or the {\\@link ReactiveFormsModule}, this\n * value accessor will be active on any radio control that has a form directive. You do\n * **not** need to add a special selector to activate it.\n *\n * ### How to use radio buttons with form directives\n *\n * To use radio buttons in a template-driven form, you'll want to ensure that radio buttons\n * in the same group have the same `name` attribute. Radio buttons with different `name`\n * attributes do not affect each other.\n *\n * {\\@example forms/ts/radioButtons/radio_button_example.ts region='TemplateDriven'}\n *\n * When using radio buttons in a reactive form, radio buttons in the same group should have the\n * same `formControlName`. You can also add a `name` attribute, but it's optional.\n *\n * {\\@example forms/ts/reactiveRadioButtons/reactive_radio_button_example.ts region='Reactive'}\n *\n * * **npm package**: `\\@angular/forms`\n *\n * \\@stable\n */\nexport class RadioControlValueAccessor {\n /**\n * @param {?} _renderer\n * @param {?} _elementRef\n * @param {?} _registry\n * @param {?} _injector\n */\n constructor(_renderer, _elementRef, _registry, _injector) {\n this._renderer = _renderer;\n this._elementRef = _elementRef;\n this._registry = _registry;\n this._injector = _injector;\n this.onChange = () => { };\n this.onTouched = () => { };\n }\n /**\n * @return {?}\n */\n ngOnInit() {\n this._control = this._injector.get(NgControl);\n this._checkName();\n this._registry.add(this._control, this);\n }\n /**\n * @return {?}\n */\n ngOnDestroy() { this._registry.remove(this); }\n /**\n * @param {?} value\n * @return {?}\n */\n writeValue(value) {\n this._state = value === this.value;\n this._renderer.setProperty(this._elementRef.nativeElement, 'checked', this._state);\n }\n /**\n * @param {?} fn\n * @return {?}\n */\n registerOnChange(fn) {\n this._fn = fn;\n this.onChange = () => {\n fn(this.value);\n this._registry.select(this);\n };\n }\n /**\n * @param {?} value\n * @return {?}\n */\n fireUncheck(value) { this.writeValue(value); }\n /**\n * @param {?} fn\n * @return {?}\n */\n registerOnTouched(fn) { this.onTouched = fn; }\n /**\n * @param {?} isDisabled\n * @return {?}\n */\n setDisabledState(isDisabled) {\n this._renderer.setProperty(this._elementRef.nativeElement, 'disabled', isDisabled);\n }\n /**\n * @return {?}\n */\n _checkName() {\n if (this.name && this.formControlName && this.name !== this.formControlName) {\n this._throwNameError();\n }\n if (!this.name && this.formControlName)\n this.name = this.formControlName;\n }\n /**\n * @return {?}\n */\n _throwNameError() {\n throw new Error(`\n If you define both a name and a formControlName attribute on your radio button, their values\n must match. Ex: \n `);\n }\n}\nRadioControlValueAccessor.decorators = [\n { type: Directive, args: [{\n selector: 'input[type=radio][formControlName],input[type=radio][formControl],input[type=radio][ngModel]',\n host: { '(change)': 'onChange()', '(blur)': 'onTouched()' },\n providers: [RADIO_VALUE_ACCESSOR]\n },] },\n];\n/** @nocollapse */\nRadioControlValueAccessor.ctorParameters = () => [\n { type: Renderer2, },\n { type: ElementRef, },\n { type: RadioControlRegistry, },\n { type: Injector, },\n];\nRadioControlValueAccessor.propDecorators = {\n \"name\": [{ type: Input },],\n \"formControlName\": [{ type: Input },],\n \"value\": [{ type: Input },],\n};\nfunction RadioControlValueAccessor_tsickle_Closure_declarations() {\n /** @type {!Array<{type: !Function, args: (undefined|!Array)}>} */\n RadioControlValueAccessor.decorators;\n /**\n * @nocollapse\n * @type {function(): !Array<(null|{type: ?, decorators: (undefined|!Array<{type: !Function, args: (undefined|!Array)}>)})>}\n */\n RadioControlValueAccessor.ctorParameters;\n /** @type {!Object)}>>} */\n RadioControlValueAccessor.propDecorators;\n /**\n * \\@internal\n * @type {?}\n */\n RadioControlValueAccessor.prototype._state;\n /**\n * \\@internal\n * @type {?}\n */\n RadioControlValueAccessor.prototype._control;\n /**\n * \\@internal\n * @type {?}\n */\n RadioControlValueAccessor.prototype._fn;\n /** @type {?} */\n RadioControlValueAccessor.prototype.onChange;\n /** @type {?} */\n RadioControlValueAccessor.prototype.onTouched;\n /** @type {?} */\n RadioControlValueAccessor.prototype.name;\n /** @type {?} */\n RadioControlValueAccessor.prototype.formControlName;\n /** @type {?} */\n RadioControlValueAccessor.prototype.value;\n /** @type {?} */\n RadioControlValueAccessor.prototype._renderer;\n /** @type {?} */\n RadioControlValueAccessor.prototype._elementRef;\n /** @type {?} */\n RadioControlValueAccessor.prototype._registry;\n /** @type {?} */\n RadioControlValueAccessor.prototype._injector;\n}\n//# sourceMappingURL=radio_control_value_accessor.js.map","/**\n * @fileoverview added by tsickle\n * @suppress {checkTypes} checked by tsc\n */\n/**\n * @license\n * Copyright Google Inc. All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\nimport { Directive, ElementRef, Renderer2, forwardRef } from '@angular/core';\nimport { NG_VALUE_ACCESSOR } from './control_value_accessor';\nexport const /** @type {?} */ RANGE_VALUE_ACCESSOR = {\n provide: NG_VALUE_ACCESSOR,\n useExisting: forwardRef(() => RangeValueAccessor),\n multi: true\n};\n/**\n * The accessor for writing a range value and listening to changes that is used by the\n * {\\@link NgModel}, {\\@link FormControlDirective}, and {\\@link FormControlName} directives.\n *\n * ### Example\n * ```\n * \n * ```\n */\nexport class RangeValueAccessor {\n /**\n * @param {?} _renderer\n * @param {?} _elementRef\n */\n constructor(_renderer, _elementRef) {\n this._renderer = _renderer;\n this._elementRef = _elementRef;\n this.onChange = (_) => { };\n this.onTouched = () => { };\n }\n /**\n * @param {?} value\n * @return {?}\n */\n writeValue(value) {\n this._renderer.setProperty(this._elementRef.nativeElement, 'value', parseFloat(value));\n }\n /**\n * @param {?} fn\n * @return {?}\n */\n registerOnChange(fn) {\n this.onChange = (value) => { fn(value == '' ? null : parseFloat(value)); };\n }\n /**\n * @param {?} fn\n * @return {?}\n */\n registerOnTouched(fn) { this.onTouched = fn; }\n /**\n * @param {?} isDisabled\n * @return {?}\n */\n setDisabledState(isDisabled) {\n this._renderer.setProperty(this._elementRef.nativeElement, 'disabled', isDisabled);\n }\n}\nRangeValueAccessor.decorators = [\n { type: Directive, args: [{\n selector: 'input[type=range][formControlName],input[type=range][formControl],input[type=range][ngModel]',\n host: {\n '(change)': 'onChange($event.target.value)',\n '(input)': 'onChange($event.target.value)',\n '(blur)': 'onTouched()'\n },\n providers: [RANGE_VALUE_ACCESSOR]\n },] },\n];\n/** @nocollapse */\nRangeValueAccessor.ctorParameters = () => [\n { type: Renderer2, },\n { type: ElementRef, },\n];\nfunction RangeValueAccessor_tsickle_Closure_declarations() {\n /** @type {!Array<{type: !Function, args: (undefined|!Array)}>} */\n RangeValueAccessor.decorators;\n /**\n * @nocollapse\n * @type {function(): !Array<(null|{type: ?, decorators: (undefined|!Array<{type: !Function, args: (undefined|!Array)}>)})>}\n */\n RangeValueAccessor.ctorParameters;\n /** @type {?} */\n RangeValueAccessor.prototype.onChange;\n /** @type {?} */\n RangeValueAccessor.prototype.onTouched;\n /** @type {?} */\n RangeValueAccessor.prototype._renderer;\n /** @type {?} */\n RangeValueAccessor.prototype._elementRef;\n}\n//# sourceMappingURL=range_value_accessor.js.map","/**\n * @fileoverview added by tsickle\n * @suppress {checkTypes} checked by tsc\n */\n/**\n * @license\n * Copyright Google Inc. All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\nimport { Directive, ElementRef, Host, Input, Optional, Renderer2, forwardRef, ɵlooseIdentical as looseIdentical } from '@angular/core';\nimport { NG_VALUE_ACCESSOR } from './control_value_accessor';\nexport const /** @type {?} */ SELECT_VALUE_ACCESSOR = {\n provide: NG_VALUE_ACCESSOR,\n useExisting: forwardRef(() => SelectControlValueAccessor),\n multi: true\n};\n/**\n * @param {?} id\n * @param {?} value\n * @return {?}\n */\nfunction _buildValueString(id, value) {\n if (id == null)\n return `${value}`;\n if (value && typeof value === 'object')\n value = 'Object';\n return `${id}: ${value}`.slice(0, 50);\n}\n/**\n * @param {?} valueString\n * @return {?}\n */\nfunction _extractId(valueString) {\n return valueString.split(':')[0];\n}\n/**\n * \\@whatItDoes Writes values and listens to changes on a select element.\n *\n * Used by {\\@link NgModel}, {\\@link FormControlDirective}, and {\\@link FormControlName}\n * to keep the view synced with the {\\@link FormControl} model.\n *\n * \\@howToUse\n *\n * If you have imported the {\\@link FormsModule} or the {\\@link ReactiveFormsModule}, this\n * value accessor will be active on any select control that has a form directive. You do\n * **not** need to add a special selector to activate it.\n *\n * ### How to use select controls with form directives\n *\n * To use a select in a template-driven form, simply add an `ngModel` and a `name`\n * attribute to the main `` tag. Like in the former example, you have the\n * choice of binding to the `value` or `ngValue` property on the select's options.\n *\n * {\\@example forms/ts/reactiveSelectControl/reactive_select_control_example.ts region='Component'}\n *\n * ### Caveat: Option selection\n *\n * Angular uses object identity to select option. It's possible for the identities of items\n * to change while the data does not. This can happen, for example, if the items are produced\n * from an RPC to the server, and that RPC is re-run. Even if the data hasn't changed, the\n * second response will produce objects with different identities.\n *\n * To customize the default option comparison algorithm, `\n * \n * \n *\n * compareFn(c1: Country, c2: Country): boolean {\n * return c1 && c2 ? c1.id === c2.id : c1 === c2;\n * }\n * ```\n *\n * Note: We listen to the 'change' event because 'input' events aren't fired\n * for selects in Firefox and IE:\n * https://bugzilla.mozilla.org/show_bug.cgi?id=1024350\n * https://developer.microsoft.com/en-us/microsoft-edge/platform/issues/4660045/\n *\n * * **npm package**: `\\@angular/forms`\n *\n * \\@stable\n */\nexport class SelectControlValueAccessor {\n /**\n * @param {?} _renderer\n * @param {?} _elementRef\n */\n constructor(_renderer, _elementRef) {\n this._renderer = _renderer;\n this._elementRef = _elementRef;\n /**\n * \\@internal\n */\n this._optionMap = new Map();\n /**\n * \\@internal\n */\n this._idCounter = 0;\n this.onChange = (_) => { };\n this.onTouched = () => { };\n this._compareWith = looseIdentical;\n }\n /**\n * @param {?} fn\n * @return {?}\n */\n set compareWith(fn) {\n if (typeof fn !== 'function') {\n throw new Error(`compareWith must be a function, but received ${JSON.stringify(fn)}`);\n }\n this._compareWith = fn;\n }\n /**\n * @param {?} value\n * @return {?}\n */\n writeValue(value) {\n this.value = value;\n const /** @type {?} */ id = this._getOptionId(value);\n if (id == null) {\n this._renderer.setProperty(this._elementRef.nativeElement, 'selectedIndex', -1);\n }\n const /** @type {?} */ valueString = _buildValueString(id, value);\n this._renderer.setProperty(this._elementRef.nativeElement, 'value', valueString);\n }\n /**\n * @param {?} fn\n * @return {?}\n */\n registerOnChange(fn) {\n this.onChange = (valueString) => {\n this.value = this._getOptionValue(valueString);\n fn(this.value);\n };\n }\n /**\n * @param {?} fn\n * @return {?}\n */\n registerOnTouched(fn) { this.onTouched = fn; }\n /**\n * @param {?} isDisabled\n * @return {?}\n */\n setDisabledState(isDisabled) {\n this._renderer.setProperty(this._elementRef.nativeElement, 'disabled', isDisabled);\n }\n /**\n * \\@internal\n * @return {?}\n */\n _registerOption() { return (this._idCounter++).toString(); }\n /**\n * \\@internal\n * @param {?} value\n * @return {?}\n */\n _getOptionId(value) {\n for (const /** @type {?} */ id of Array.from(this._optionMap.keys())) {\n if (this._compareWith(this._optionMap.get(id), value))\n return id;\n }\n return null;\n }\n /**\n * \\@internal\n * @param {?} valueString\n * @return {?}\n */\n _getOptionValue(valueString) {\n const /** @type {?} */ id = _extractId(valueString);\n return this._optionMap.has(id) ? this._optionMap.get(id) : valueString;\n }\n}\nSelectControlValueAccessor.decorators = [\n { type: Directive, args: [{\n selector: 'select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]',\n host: { '(change)': 'onChange($event.target.value)', '(blur)': 'onTouched()' },\n providers: [SELECT_VALUE_ACCESSOR]\n },] },\n];\n/** @nocollapse */\nSelectControlValueAccessor.ctorParameters = () => [\n { type: Renderer2, },\n { type: ElementRef, },\n];\nSelectControlValueAccessor.propDecorators = {\n \"compareWith\": [{ type: Input },],\n};\nfunction SelectControlValueAccessor_tsickle_Closure_declarations() {\n /** @type {!Array<{type: !Function, args: (undefined|!Array)}>} */\n SelectControlValueAccessor.decorators;\n /**\n * @nocollapse\n * @type {function(): !Array<(null|{type: ?, decorators: (undefined|!Array<{type: !Function, args: (undefined|!Array)}>)})>}\n */\n SelectControlValueAccessor.ctorParameters;\n /** @type {!Object)}>>} */\n SelectControlValueAccessor.propDecorators;\n /** @type {?} */\n SelectControlValueAccessor.prototype.value;\n /**\n * \\@internal\n * @type {?}\n */\n SelectControlValueAccessor.prototype._optionMap;\n /**\n * \\@internal\n * @type {?}\n */\n SelectControlValueAccessor.prototype._idCounter;\n /** @type {?} */\n SelectControlValueAccessor.prototype.onChange;\n /** @type {?} */\n SelectControlValueAccessor.prototype.onTouched;\n /** @type {?} */\n SelectControlValueAccessor.prototype._compareWith;\n /** @type {?} */\n SelectControlValueAccessor.prototype._renderer;\n /** @type {?} */\n SelectControlValueAccessor.prototype._elementRef;\n}\n/**\n * \\@whatItDoes Marks `