import { Injectable, ɵɵdefineInjectable, Directive, TemplateRef, Input, ContentChildren, EventEmitter, Component, ViewEncapsulation, Output, Optional, Host, NgModule, ChangeDetectionStrategy, Renderer2, ElementRef, forwardRef, ChangeDetectorRef, Inject, PLATFORM_ID, NgZone, HostListener, LOCALE_ID, ɵɵinject, ViewChild, ViewContainerRef, ComponentFactoryResolver, ContentChild, Injector, ApplicationRef, RendererFactory2, INJECTOR, Attribute, InjectionToken } from '@angular/core'; import { CommonModule, isPlatformBrowser, getLocaleDayNames, FormStyle, TranslationWidth, getLocaleMonthNames, formatDate, DOCUMENT, getLocaleDayPeriods } from '@angular/common'; import { NG_VALUE_ACCESSOR, NG_VALIDATORS, FormsModule } from '@angular/forms'; import { Subject, BehaviorSubject, combineLatest, timer, NEVER, fromEvent, merge, race, Observable } from 'rxjs'; import { map, startWith, distinctUntilChanged, switchMap, takeUntil, filter, take, tap, withLatestFrom, delay, share } from 'rxjs/operators'; /** * @fileoverview added by tsickle * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ /** * @param {?} value * @return {?} */ function toInteger(value) { return parseInt(`${value}`, 10); } /** * @param {?} value * @return {?} */ function toString(value) { return (value !== undefined && value !== null) ? `${value}` : ''; } /** * @param {?} value * @param {?} max * @param {?=} min * @return {?} */ function getValueInRange(value, max, min = 0) { return Math.max(Math.min(value, max), min); } /** * @param {?} value * @return {?} */ function isString(value) { return typeof value === 'string'; } /** * @param {?} value * @return {?} */ function isNumber(value) { return !isNaN(toInteger(value)); } /** * @param {?} value * @return {?} */ function isInteger(value) { return typeof value === 'number' && isFinite(value) && Math.floor(value) === value; } /** * @param {?} value * @return {?} */ function isDefined(value) { return value !== undefined && value !== null; } /** * @param {?} value * @return {?} */ function padNumber(value) { if (isNumber(value)) { return `0${value}`.slice(-2); } else { return ''; } } /** * @param {?} text * @return {?} */ function regExpEscape(text) { return text.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&'); } /** * @param {?} element * @param {?} className * @return {?} */ function hasClassName(element, className) { return element && element.className && element.className.split && element.className.split(/\s+/).indexOf(className) >= 0; } if (typeof Element !== 'undefined' && !Element.prototype.closest) { // Polyfill for ie10+ if (!Element.prototype.matches) { // IE uses the non-standard name: msMatchesSelector Element.prototype.matches = ((/** @type {?} */ (Element.prototype))).msMatchesSelector || Element.prototype.webkitMatchesSelector; } Element.prototype.closest = (/** * @param {?} s * @return {?} */ function (s) { /** @type {?} */ let el = this; if (!document.documentElement.contains(el)) { return null; } do { if (el.matches(s)) { return el; } el = el.parentElement || el.parentNode; } while (el !== null && el.nodeType === 1); return null; }); } /** * @param {?} element * @param {?} selector * @return {?} */ function closest(element, selector) { if (!selector) { return null; } return element.closest(selector); } /** * @fileoverview added by tsickle * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ /** * A configuration service for the [NgbAccordion](#/components/accordion/api#NgbAccordion) component. * * You can inject this service, typically in your root component, and customize its properties * to provide default values for all accordions used in the application. */ class NgbAccordionConfig { constructor() { this.closeOthers = false; } } NgbAccordionConfig.decorators = [ { type: Injectable, args: [{ providedIn: 'root' },] } ]; /** @nocollapse */ NgbAccordionConfig.ngInjectableDef = ɵɵdefineInjectable({ factory: function NgbAccordionConfig_Factory() { return new NgbAccordionConfig(); }, token: NgbAccordionConfig, providedIn: "root" }); /** * @fileoverview added by tsickle * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ /** @type {?} */ let nextId = 0; /** * A directive that wraps an accordion panel header with any HTML markup and a toggling button * marked with [`NgbPanelToggle`](#/components/accordion/api#NgbPanelToggle). * See the [header customization demo](#/components/accordion/examples#header) for more details. * * You can also use [`NgbPanelTitle`](#/components/accordion/api#NgbPanelTitle) to customize only the panel title. * * \@since 4.1.0 */ class NgbPanelHeader { /** * @param {?} templateRef */ constructor(templateRef) { this.templateRef = templateRef; } } NgbPanelHeader.decorators = [ { type: Directive, args: [{ selector: 'ng-template[ngbPanelHeader]' },] } ]; /** @nocollapse */ NgbPanelHeader.ctorParameters = () => [ { type: TemplateRef } ]; /** * A directive that wraps only the panel title with HTML markup inside. * * You can also use [`NgbPanelHeader`](#/components/accordion/api#NgbPanelHeader) to customize the full panel header. */ class NgbPanelTitle { /** * @param {?} templateRef */ constructor(templateRef) { this.templateRef = templateRef; } } NgbPanelTitle.decorators = [ { type: Directive, args: [{ selector: 'ng-template[ngbPanelTitle]' },] } ]; /** @nocollapse */ NgbPanelTitle.ctorParameters = () => [ { type: TemplateRef } ]; /** * A directive that wraps the accordion panel content. */ class NgbPanelContent { /** * @param {?} templateRef */ constructor(templateRef) { this.templateRef = templateRef; } } NgbPanelContent.decorators = [ { type: Directive, args: [{ selector: 'ng-template[ngbPanelContent]' },] } ]; /** @nocollapse */ NgbPanelContent.ctorParameters = () => [ { type: TemplateRef } ]; /** * A directive that wraps an individual accordion panel with title and collapsible content. */ class NgbPanel { constructor() { /** * If `true`, the panel is disabled an can't be toggled. */ this.disabled = false; /** * An optional id for the panel that must be unique on the page. * * If not provided, it will be auto-generated in the `ngb-panel-xxx` format. */ this.id = `ngb-panel-${nextId++}`; this.isOpen = false; } /** * @return {?} */ ngAfterContentChecked() { // We are using @ContentChildren instead of @ContentChild as in the Angular version being used // only @ContentChildren allows us to specify the {descendants: false} option. // Without {descendants: false} we are hitting bugs described in: // https://github.com/ng-bootstrap/ng-bootstrap/issues/2240 this.titleTpl = this.titleTpls.first; this.headerTpl = this.headerTpls.first; this.contentTpl = this.contentTpls.first; } } NgbPanel.decorators = [ { type: Directive, args: [{ selector: 'ngb-panel' },] } ]; NgbPanel.propDecorators = { disabled: [{ type: Input }], id: [{ type: Input }], title: [{ type: Input }], type: [{ type: Input }], titleTpls: [{ type: ContentChildren, args: [NgbPanelTitle, { descendants: false },] }], headerTpls: [{ type: ContentChildren, args: [NgbPanelHeader, { descendants: false },] }], contentTpls: [{ type: ContentChildren, args: [NgbPanelContent, { descendants: false },] }] }; /** * Accordion is a collection of collapsible panels (bootstrap cards). * * It can ensure only one panel is opened at a time and allows to customize panel * headers. */ class NgbAccordion { /** * @param {?} config */ constructor(config) { /** * An array or comma separated strings of panel ids that should be opened **initially**. * * For subsequent changes use methods like `expand()`, `collapse()`, etc. and * the `(panelChange)` event. */ this.activeIds = []; /** * If `true`, panel content will be detached from DOM and not simply hidden when the panel is collapsed. */ this.destroyOnHide = true; /** * Event emitted right before the panel toggle happens. * * See [NgbPanelChangeEvent](#/components/accordion/api#NgbPanelChangeEvent) for payload details. */ this.panelChange = new EventEmitter(); this.type = config.type; this.closeOtherPanels = config.closeOthers; } /** * Checks if a panel with a given id is expanded. * @param {?} panelId * @return {?} */ isExpanded(panelId) { return this.activeIds.indexOf(panelId) > -1; } /** * Expands a panel with a given id. * * Has no effect if the panel is already expanded or disabled. * @param {?} panelId * @return {?} */ expand(panelId) { this._changeOpenState(this._findPanelById(panelId), true); } /** * Expands all panels, if `[closeOthers]` is `false`. * * If `[closeOthers]` is `true`, it will expand the first panel, unless there is already a panel opened. * @return {?} */ expandAll() { if (this.closeOtherPanels) { if (this.activeIds.length === 0 && this.panels.length) { this._changeOpenState(this.panels.first, true); } } else { this.panels.forEach((/** * @param {?} panel * @return {?} */ panel => this._changeOpenState(panel, true))); } } /** * Collapses a panel with the given id. * * Has no effect if the panel is already collapsed or disabled. * @param {?} panelId * @return {?} */ collapse(panelId) { this._changeOpenState(this._findPanelById(panelId), false); } /** * Collapses all opened panels. * @return {?} */ collapseAll() { this.panels.forEach((/** * @param {?} panel * @return {?} */ (panel) => { this._changeOpenState(panel, false); })); } /** * Toggles a panel with the given id. * * Has no effect if the panel is disabled. * @param {?} panelId * @return {?} */ toggle(panelId) { /** @type {?} */ const panel = this._findPanelById(panelId); if (panel) { this._changeOpenState(panel, !panel.isOpen); } } /** * @return {?} */ ngAfterContentChecked() { // active id updates if (isString(this.activeIds)) { this.activeIds = this.activeIds.split(/\s*,\s*/); } // update panels open states this.panels.forEach((/** * @param {?} panel * @return {?} */ panel => panel.isOpen = !panel.disabled && this.activeIds.indexOf(panel.id) > -1)); // closeOthers updates if (this.activeIds.length > 1 && this.closeOtherPanels) { this._closeOthers(this.activeIds[0]); this._updateActiveIds(); } } /** * @private * @param {?} panel * @param {?} nextState * @return {?} */ _changeOpenState(panel, nextState) { if (panel && !panel.disabled && panel.isOpen !== nextState) { /** @type {?} */ let defaultPrevented = false; this.panelChange.emit({ panelId: panel.id, nextState: nextState, preventDefault: (/** * @return {?} */ () => { defaultPrevented = true; }) }); if (!defaultPrevented) { panel.isOpen = nextState; if (nextState && this.closeOtherPanels) { this._closeOthers(panel.id); } this._updateActiveIds(); } } } /** * @private * @param {?} panelId * @return {?} */ _closeOthers(panelId) { this.panels.forEach((/** * @param {?} panel * @return {?} */ panel => { if (panel.id !== panelId) { panel.isOpen = false; } })); } /** * @private * @param {?} panelId * @return {?} */ _findPanelById(panelId) { return this.panels.find((/** * @param {?} p * @return {?} */ p => p.id === panelId)); } /** * @private * @return {?} */ _updateActiveIds() { this.activeIds = this.panels.filter((/** * @param {?} panel * @return {?} */ panel => panel.isOpen && !panel.disabled)).map((/** * @param {?} panel * @return {?} */ panel => panel.id)); } } NgbAccordion.decorators = [ { type: Component, args: [{ selector: 'ngb-accordion', exportAs: 'ngbAccordion', encapsulation: ViewEncapsulation.None, host: { 'class': 'accordion', 'role': 'tablist', '[attr.aria-multiselectable]': '!closeOtherPanels' }, template: `
` }] } ]; /** @nocollapse */ NgbAccordion.ctorParameters = () => [ { type: NgbAccordionConfig } ]; NgbAccordion.propDecorators = { panels: [{ type: ContentChildren, args: [NgbPanel,] }], activeIds: [{ type: Input }], closeOtherPanels: [{ type: Input, args: ['closeOthers',] }], destroyOnHide: [{ type: Input }], type: [{ type: Input }], panelChange: [{ type: Output }] }; /** * A directive to put on a button that toggles panel opening and closing. * * To be used inside the [`NgbPanelHeader`](#/components/accordion/api#NgbPanelHeader) * * \@since 4.1.0 */ class NgbPanelToggle { /** * @param {?} accordion * @param {?} panel */ constructor(accordion, panel) { this.accordion = accordion; this.panel = panel; } /** * @param {?} panel * @return {?} */ set ngbPanelToggle(panel) { if (panel) { this.panel = panel; } } } NgbPanelToggle.decorators = [ { type: Directive, args: [{ selector: 'button[ngbPanelToggle]', host: { 'type': 'button', '[disabled]': 'panel.disabled', '[class.collapsed]': '!panel.isOpen', '[attr.aria-expanded]': 'panel.isOpen', '[attr.aria-controls]': 'panel.id', '(click)': 'accordion.toggle(panel.id)' } },] } ]; /** @nocollapse */ NgbPanelToggle.ctorParameters = () => [ { type: NgbAccordion }, { type: NgbPanel, decorators: [{ type: Optional }, { type: Host }] } ]; NgbPanelToggle.propDecorators = { ngbPanelToggle: [{ type: Input }] }; /** * @fileoverview added by tsickle * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ /** @type {?} */ const NGB_ACCORDION_DIRECTIVES = [NgbAccordion, NgbPanel, NgbPanelTitle, NgbPanelContent, NgbPanelHeader, NgbPanelToggle]; class NgbAccordionModule { } NgbAccordionModule.decorators = [ { type: NgModule, args: [{ declarations: NGB_ACCORDION_DIRECTIVES, exports: NGB_ACCORDION_DIRECTIVES, imports: [CommonModule] },] } ]; /** * @fileoverview added by tsickle * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ /** * A configuration service for the [NgbAlert](#/components/alert/api#NgbAlert) component. * * You can inject this service, typically in your root component, and customize its properties * to provide default values for all alerts used in the application. */ class NgbAlertConfig { constructor() { this.dismissible = true; this.type = 'warning'; } } NgbAlertConfig.decorators = [ { type: Injectable, args: [{ providedIn: 'root' },] } ]; /** @nocollapse */ NgbAlertConfig.ngInjectableDef = ɵɵdefineInjectable({ factory: function NgbAlertConfig_Factory() { return new NgbAlertConfig(); }, token: NgbAlertConfig, providedIn: "root" }); /** * @fileoverview added by tsickle * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ /** * Alert is a component to provide contextual feedback messages for user. * * It supports several alert types and can be dismissed. */ class NgbAlert { /** * @param {?} config * @param {?} _renderer * @param {?} _element */ constructor(config, _renderer, _element) { this._renderer = _renderer; this._element = _element; /** * An event emitted when the close button is clicked. It has no payload and only relevant for dismissible alerts. */ this.close = new EventEmitter(); this.dismissible = config.dismissible; this.type = config.type; } /** * @return {?} */ closeHandler() { this.close.emit(null); } /** * @param {?} changes * @return {?} */ ngOnChanges(changes) { /** @type {?} */ const typeChange = changes['type']; if (typeChange && !typeChange.firstChange) { this._renderer.removeClass(this._element.nativeElement, `alert-${typeChange.previousValue}`); this._renderer.addClass(this._element.nativeElement, `alert-${typeChange.currentValue}`); } } /** * @return {?} */ ngOnInit() { this._renderer.addClass(this._element.nativeElement, `alert-${this.type}`); } } NgbAlert.decorators = [ { type: Component, args: [{ selector: 'ngb-alert', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, host: { 'role': 'alert', 'class': 'alert', '[class.alert-dismissible]': 'dismissible' }, template: ` `, styles: ["ngb-alert{display:block}"] }] } ]; /** @nocollapse */ NgbAlert.ctorParameters = () => [ { type: NgbAlertConfig }, { type: Renderer2 }, { type: ElementRef } ]; NgbAlert.propDecorators = { dismissible: [{ type: Input }], type: [{ type: Input }], close: [{ type: Output }] }; /** * @fileoverview added by tsickle * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ class NgbAlertModule { } NgbAlertModule.decorators = [ { type: NgModule, args: [{ declarations: [NgbAlert], exports: [NgbAlert], imports: [CommonModule], entryComponents: [NgbAlert] },] } ]; /** * @fileoverview added by tsickle * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ class NgbButtonLabel { } NgbButtonLabel.decorators = [ { type: Directive, args: [{ selector: '[ngbButtonLabel]', host: { '[class.btn]': 'true', '[class.active]': 'active', '[class.disabled]': 'disabled', '[class.focus]': 'focused' } },] } ]; /** * @fileoverview added by tsickle * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ /** @type {?} */ const NGB_CHECKBOX_VALUE_ACCESSOR = { provide: NG_VALUE_ACCESSOR, useExisting: forwardRef((/** * @return {?} */ () => NgbCheckBox)), multi: true }; /** * Allows to easily create Bootstrap-style checkbox buttons. * * Integrates with forms, so the value of a checked button is bound to the underlying form control * either in a reactive or template-driven way. */ class NgbCheckBox { /** * @param {?} _label * @param {?} _cd */ constructor(_label, _cd) { this._label = _label; this._cd = _cd; /** * If `true`, the checkbox button will be disabled */ this.disabled = false; /** * The form control value when the checkbox is checked. */ this.valueChecked = true; /** * The form control value when the checkbox is unchecked. */ this.valueUnChecked = false; this.onChange = (/** * @param {?} _ * @return {?} */ (_) => { }); this.onTouched = (/** * @return {?} */ () => { }); } /** * @param {?} isFocused * @return {?} */ set focused(isFocused) { this._label.focused = isFocused; if (!isFocused) { this.onTouched(); } } /** * @param {?} $event * @return {?} */ onInputChange($event) { /** @type {?} */ const modelToPropagate = $event.target.checked ? this.valueChecked : this.valueUnChecked; this.onChange(modelToPropagate); this.onTouched(); this.writeValue(modelToPropagate); } /** * @param {?} fn * @return {?} */ registerOnChange(fn) { this.onChange = fn; } /** * @param {?} fn * @return {?} */ registerOnTouched(fn) { this.onTouched = fn; } /** * @param {?} isDisabled * @return {?} */ setDisabledState(isDisabled) { this.disabled = isDisabled; this._label.disabled = isDisabled; } /** * @param {?} value * @return {?} */ writeValue(value) { this.checked = value === this.valueChecked; this._label.active = this.checked; // label won't be updated, if it is inside the OnPush component when [ngModel] changes this._cd.markForCheck(); } } NgbCheckBox.decorators = [ { type: Directive, args: [{ selector: '[ngbButton][type=checkbox]', host: { '[checked]': 'checked', '[disabled]': 'disabled', '(change)': 'onInputChange($event)', '(focus)': 'focused = true', '(blur)': 'focused = false' }, providers: [NGB_CHECKBOX_VALUE_ACCESSOR] },] } ]; /** @nocollapse */ NgbCheckBox.ctorParameters = () => [ { type: NgbButtonLabel }, { type: ChangeDetectorRef } ]; NgbCheckBox.propDecorators = { disabled: [{ type: Input }], valueChecked: [{ type: Input }], valueUnChecked: [{ type: Input }] }; /** * @fileoverview added by tsickle * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ /** @type {?} */ const NGB_RADIO_VALUE_ACCESSOR = { provide: NG_VALUE_ACCESSOR, useExisting: forwardRef((/** * @return {?} */ () => NgbRadioGroup)), multi: true }; /** @type {?} */ let nextId$1 = 0; /** * Allows to easily create Bootstrap-style radio buttons. * * Integrates with forms, so the value of a checked button is bound to the underlying form control * either in a reactive or template-driven way. */ class NgbRadioGroup { constructor() { this._radios = new Set(); this._value = null; /** * Name of the radio group applied to radio input elements. * * Will be applied to all radio input elements inside the group, * unless [`NgbRadio`](#/components/buttons/api#NgbRadio)'s specify names themselves. * * If not provided, will be generated in the `ngb-radio-xx` format. */ this.name = `ngb-radio-${nextId$1++}`; this.onChange = (/** * @param {?} _ * @return {?} */ (_) => { }); this.onTouched = (/** * @return {?} */ () => { }); } /** * @return {?} */ get disabled() { return this._disabled; } /** * @param {?} isDisabled * @return {?} */ set disabled(isDisabled) { this.setDisabledState(isDisabled); } /** * @param {?} radio * @return {?} */ onRadioChange(radio) { this.writeValue(radio.value); this.onChange(radio.value); } /** * @return {?} */ onRadioValueUpdate() { this._updateRadiosValue(); } /** * @param {?} radio * @return {?} */ register(radio) { this._radios.add(radio); } /** * @param {?} fn * @return {?} */ registerOnChange(fn) { this.onChange = fn; } /** * @param {?} fn * @return {?} */ registerOnTouched(fn) { this.onTouched = fn; } /** * @param {?} isDisabled * @return {?} */ setDisabledState(isDisabled) { this._disabled = isDisabled; this._updateRadiosDisabled(); } /** * @param {?} radio * @return {?} */ unregister(radio) { this._radios.delete(radio); } /** * @param {?} value * @return {?} */ writeValue(value) { this._value = value; this._updateRadiosValue(); } /** * @private * @return {?} */ _updateRadiosValue() { this._radios.forEach((/** * @param {?} radio * @return {?} */ (radio) => radio.updateValue(this._value))); } /** * @private * @return {?} */ _updateRadiosDisabled() { this._radios.forEach((/** * @param {?} radio * @return {?} */ (radio) => radio.updateDisabled())); } } NgbRadioGroup.decorators = [ { type: Directive, args: [{ selector: '[ngbRadioGroup]', host: { 'role': 'radiogroup' }, providers: [NGB_RADIO_VALUE_ACCESSOR] },] } ]; NgbRadioGroup.propDecorators = { name: [{ type: Input }] }; /** * A directive that marks an input of type "radio" as a part of the * [`NgbRadioGroup`](#/components/buttons/api#NgbRadioGroup). */ class NgbRadio { /** * @param {?} _group * @param {?} _label * @param {?} _renderer * @param {?} _element * @param {?} _cd */ constructor(_group, _label, _renderer, _element, _cd) { this._group = _group; this._label = _label; this._renderer = _renderer; this._element = _element; this._cd = _cd; this._value = null; this._group.register(this); this.updateDisabled(); } /** * The form control value when current radio button is checked. * @param {?} value * @return {?} */ set value(value) { this._value = value; /** @type {?} */ const stringValue = value ? value.toString() : ''; this._renderer.setProperty(this._element.nativeElement, 'value', stringValue); this._group.onRadioValueUpdate(); } /** * If `true`, current radio button will be disabled. * @param {?} isDisabled * @return {?} */ set disabled(isDisabled) { this._disabled = isDisabled !== false; this.updateDisabled(); } /** * @param {?} isFocused * @return {?} */ set focused(isFocused) { if (this._label) { this._label.focused = isFocused; } if (!isFocused) { this._group.onTouched(); } } /** * @return {?} */ get checked() { return this._checked; } /** * @return {?} */ get disabled() { return this._group.disabled || this._disabled; } /** * @return {?} */ get value() { return this._value; } /** * @return {?} */ get nameAttr() { return this.name || this._group.name; } /** * @return {?} */ ngOnDestroy() { this._group.unregister(this); } /** * @return {?} */ onChange() { this._group.onRadioChange(this); } /** * @param {?} value * @return {?} */ updateValue(value) { // label won't be updated, if it is inside the OnPush component when [ngModel] changes if (this.value !== value) { this._cd.markForCheck(); } this._checked = this.value === value; this._label.active = this._checked; } /** * @return {?} */ updateDisabled() { this._label.disabled = this.disabled; } } NgbRadio.decorators = [ { type: Directive, args: [{ selector: '[ngbButton][type=radio]', host: { '[checked]': 'checked', '[disabled]': 'disabled', '[name]': 'nameAttr', '(change)': 'onChange()', '(focus)': 'focused = true', '(blur)': 'focused = false' } },] } ]; /** @nocollapse */ NgbRadio.ctorParameters = () => [ { type: NgbRadioGroup }, { type: NgbButtonLabel }, { type: Renderer2 }, { type: ElementRef }, { type: ChangeDetectorRef } ]; NgbRadio.propDecorators = { name: [{ type: Input }], value: [{ type: Input, args: ['value',] }], disabled: [{ type: Input, args: ['disabled',] }] }; /** * @fileoverview added by tsickle * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ /** @type {?} */ const NGB_BUTTON_DIRECTIVES = [NgbButtonLabel, NgbCheckBox, NgbRadioGroup, NgbRadio]; class NgbButtonsModule { } NgbButtonsModule.decorators = [ { type: NgModule, args: [{ declarations: NGB_BUTTON_DIRECTIVES, exports: NGB_BUTTON_DIRECTIVES },] } ]; /** * @fileoverview added by tsickle * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ /** * A configuration service for the [NgbCarousel](#/components/carousel/api#NgbCarousel) component. * * You can inject this service, typically in your root component, and customize its properties * to provide default values for all carousels used in the application. */ class NgbCarouselConfig { constructor() { this.interval = 5000; this.wrap = true; this.keyboard = true; this.pauseOnHover = true; this.showNavigationArrows = true; this.showNavigationIndicators = true; } } NgbCarouselConfig.decorators = [ { type: Injectable, args: [{ providedIn: 'root' },] } ]; /** @nocollapse */ NgbCarouselConfig.ngInjectableDef = ɵɵdefineInjectable({ factory: function NgbCarouselConfig_Factory() { return new NgbCarouselConfig(); }, token: NgbCarouselConfig, providedIn: "root" }); /** * @fileoverview added by tsickle * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ /** @type {?} */ let nextId$2 = 0; /** * A directive that wraps the individual carousel slide. */ class NgbSlide { /** * @param {?} tplRef */ constructor(tplRef) { this.tplRef = tplRef; /** * Slide id that must be unique for the entire document. * * If not provided, will be generated in the `ngb-slide-xx` format. */ this.id = `ngb-slide-${nextId$2++}`; } } NgbSlide.decorators = [ { type: Directive, args: [{ selector: 'ng-template[ngbSlide]' },] } ]; /** @nocollapse */ NgbSlide.ctorParameters = () => [ { type: TemplateRef } ]; NgbSlide.propDecorators = { id: [{ type: Input }] }; /** * Carousel is a component to easily create and control slideshows. * * Allows to set intervals, change the way user interacts with the slides and provides a programmatic API. */ class NgbCarousel { /** * @param {?} config * @param {?} _platformId * @param {?} _ngZone * @param {?} _cd */ constructor(config, _platformId, _ngZone, _cd) { this._platformId = _platformId; this._ngZone = _ngZone; this._cd = _cd; this.NgbSlideEventSource = NgbSlideEventSource; this._destroy$ = new Subject(); this._interval$ = new BehaviorSubject(0); this._mouseHover$ = new BehaviorSubject(false); this._pauseOnHover$ = new BehaviorSubject(false); this._pause$ = new BehaviorSubject(false); this._wrap$ = new BehaviorSubject(false); /** * An event emitted right after the slide transition is completed. * * See [`NgbSlideEvent`](#/components/carousel/api#NgbSlideEvent) for payload details. */ this.slide = new EventEmitter(); this.interval = config.interval; this.wrap = config.wrap; this.keyboard = config.keyboard; this.pauseOnHover = config.pauseOnHover; this.showNavigationArrows = config.showNavigationArrows; this.showNavigationIndicators = config.showNavigationIndicators; } /** * Time in milliseconds before the next slide is shown. * @param {?} value * @return {?} */ set interval(value) { this._interval$.next(value); } /** * @return {?} */ get interval() { return this._interval$.value; } /** * If `true`, will 'wrap' the carousel by switching from the last slide back to the first. * @param {?} value * @return {?} */ set wrap(value) { this._wrap$.next(value); } /** * @return {?} */ get wrap() { return this._wrap$.value; } /** * If `true`, will pause slide switching when mouse cursor hovers the slide. * * \@since 2.2.0 * @param {?} value * @return {?} */ set pauseOnHover(value) { this._pauseOnHover$.next(value); } /** * @return {?} */ get pauseOnHover() { return this._pauseOnHover$.value; } /** * @return {?} */ mouseEnter() { this._mouseHover$.next(true); } /** * @return {?} */ mouseLeave() { this._mouseHover$.next(false); } /** * @return {?} */ ngAfterContentInit() { // setInterval() doesn't play well with SSR and protractor, // so we should run it in the browser and outside Angular if (isPlatformBrowser(this._platformId)) { this._ngZone.runOutsideAngular((/** * @return {?} */ () => { /** @type {?} */ const hasNextSlide$ = combineLatest(this.slide.pipe(map((/** * @param {?} slideEvent * @return {?} */ slideEvent => slideEvent.current)), startWith(this.activeId)), this._wrap$, this.slides.changes.pipe(startWith(null))) .pipe(map((/** * @param {?} __0 * @return {?} */ ([currentSlideId, wrap]) => { /** @type {?} */ const slideArr = this.slides.toArray(); /** @type {?} */ const currentSlideIdx = this._getSlideIdxById(currentSlideId); return wrap ? slideArr.length > 1 : currentSlideIdx < slideArr.length - 1; })), distinctUntilChanged()); combineLatest(this._pause$, this._pauseOnHover$, this._mouseHover$, this._interval$, hasNextSlide$) .pipe(map((/** * @param {?} __0 * @return {?} */ ([pause, pauseOnHover, mouseHover, interval, hasNextSlide]) => ((pause || (pauseOnHover && mouseHover) || !hasNextSlide) ? 0 : interval))), distinctUntilChanged(), switchMap((/** * @param {?} interval * @return {?} */ interval => interval > 0 ? timer(interval, interval) : NEVER)), takeUntil(this._destroy$)) .subscribe((/** * @return {?} */ () => this._ngZone.run((/** * @return {?} */ () => this.next(NgbSlideEventSource.TIMER))))); })); } this.slides.changes.pipe(takeUntil(this._destroy$)).subscribe((/** * @return {?} */ () => this._cd.markForCheck())); } /** * @return {?} */ ngAfterContentChecked() { /** @type {?} */ let activeSlide = this._getSlideById(this.activeId); this.activeId = activeSlide ? activeSlide.id : (this.slides.length ? this.slides.first.id : null); } /** * @return {?} */ ngOnDestroy() { this._destroy$.next(); } /** * Navigates to a slide with the specified identifier. * @param {?} slideId * @param {?=} source * @return {?} */ select(slideId, source) { this._cycleToSelected(slideId, this._getSlideEventDirection(this.activeId, slideId), source); } /** * Navigates to the previous slide. * @param {?=} source * @return {?} */ prev(source) { this._cycleToSelected(this._getPrevSlide(this.activeId), NgbSlideEventDirection.RIGHT, source); } /** * Navigates to the next slide. * @param {?=} source * @return {?} */ next(source) { this._cycleToSelected(this._getNextSlide(this.activeId), NgbSlideEventDirection.LEFT, source); } /** * Pauses cycling through the slides. * @return {?} */ pause() { this._pause$.next(true); } /** * Restarts cycling through the slides from left to right. * @return {?} */ cycle() { this._pause$.next(false); } /** * @private * @param {?} slideIdx * @param {?} direction * @param {?=} source * @return {?} */ _cycleToSelected(slideIdx, direction, source) { /** @type {?} */ let selectedSlide = this._getSlideById(slideIdx); if (selectedSlide && selectedSlide.id !== this.activeId) { this.slide.emit({ prev: this.activeId, current: selectedSlide.id, direction: direction, paused: this._pause$.value, source }); this.activeId = selectedSlide.id; } // we get here after the interval fires or any external API call like next(), prev() or select() this._cd.markForCheck(); } /** * @private * @param {?} currentActiveSlideId * @param {?} nextActiveSlideId * @return {?} */ _getSlideEventDirection(currentActiveSlideId, nextActiveSlideId) { /** @type {?} */ const currentActiveSlideIdx = this._getSlideIdxById(currentActiveSlideId); /** @type {?} */ const nextActiveSlideIdx = this._getSlideIdxById(nextActiveSlideId); return currentActiveSlideIdx > nextActiveSlideIdx ? NgbSlideEventDirection.RIGHT : NgbSlideEventDirection.LEFT; } /** * @private * @param {?} slideId * @return {?} */ _getSlideById(slideId) { return this.slides.find((/** * @param {?} slide * @return {?} */ slide => slide.id === slideId)); } /** * @private * @param {?} slideId * @return {?} */ _getSlideIdxById(slideId) { return this.slides.toArray().indexOf(this._getSlideById(slideId)); } /** * @private * @param {?} currentSlideId * @return {?} */ _getNextSlide(currentSlideId) { /** @type {?} */ const slideArr = this.slides.toArray(); /** @type {?} */ const currentSlideIdx = this._getSlideIdxById(currentSlideId); /** @type {?} */ const isLastSlide = currentSlideIdx === slideArr.length - 1; return isLastSlide ? (this.wrap ? slideArr[0].id : slideArr[slideArr.length - 1].id) : slideArr[currentSlideIdx + 1].id; } /** * @private * @param {?} currentSlideId * @return {?} */ _getPrevSlide(currentSlideId) { /** @type {?} */ const slideArr = this.slides.toArray(); /** @type {?} */ const currentSlideIdx = this._getSlideIdxById(currentSlideId); /** @type {?} */ const isFirstSlide = currentSlideIdx === 0; return isFirstSlide ? (this.wrap ? slideArr[slideArr.length - 1].id : slideArr[0].id) : slideArr[currentSlideIdx - 1].id; } } NgbCarousel.decorators = [ { type: Component, args: [{ selector: 'ngb-carousel', exportAs: 'ngbCarousel', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, host: { 'class': 'carousel slide', '[style.display]': '"block"', 'tabIndex': '0', '(keydown.arrowLeft)': 'keyboard && prev(NgbSlideEventSource.ARROW_LEFT)', '(keydown.arrowRight)': 'keyboard && next(NgbSlideEventSource.ARROW_RIGHT)' }, template: ` Previous Next ` }] } ]; /** @nocollapse */ NgbCarousel.ctorParameters = () => [ { type: NgbCarouselConfig }, { type: undefined, decorators: [{ type: Inject, args: [PLATFORM_ID,] }] }, { type: NgZone }, { type: ChangeDetectorRef } ]; NgbCarousel.propDecorators = { slides: [{ type: ContentChildren, args: [NgbSlide,] }], activeId: [{ type: Input }], interval: [{ type: Input }], wrap: [{ type: Input }], keyboard: [{ type: Input }], pauseOnHover: [{ type: Input }], showNavigationArrows: [{ type: Input }], showNavigationIndicators: [{ type: Input }], slide: [{ type: Output }], mouseEnter: [{ type: HostListener, args: ['mouseenter',] }], mouseLeave: [{ type: HostListener, args: ['mouseleave',] }] }; /** @enum {string} */ const NgbSlideEventDirection = { LEFT: (/** @type {?} */ ('left')), RIGHT: (/** @type {?} */ ('right')), }; /** @enum {string} */ const NgbSlideEventSource = { TIMER: 'timer', ARROW_LEFT: 'arrowLeft', ARROW_RIGHT: 'arrowRight', INDICATOR: 'indicator', }; /** @type {?} */ const NGB_CAROUSEL_DIRECTIVES = [NgbCarousel, NgbSlide]; /** * @fileoverview added by tsickle * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ class NgbCarouselModule { } NgbCarouselModule.decorators = [ { type: NgModule, args: [{ declarations: NGB_CAROUSEL_DIRECTIVES, exports: NGB_CAROUSEL_DIRECTIVES, imports: [CommonModule] },] } ]; /** * @fileoverview added by tsickle * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ /** * A directive to provide a simple way of hiding and showing elements on the page. */ class NgbCollapse { constructor() { /** * If `true`, will collapse the element or show it otherwise. */ this.collapsed = false; } } NgbCollapse.decorators = [ { type: Directive, args: [{ selector: '[ngbCollapse]', exportAs: 'ngbCollapse', host: { '[class.collapse]': 'true', '[class.show]': '!collapsed' } },] } ]; NgbCollapse.propDecorators = { collapsed: [{ type: Input, args: ['ngbCollapse',] }] }; /** * @fileoverview added by tsickle * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ class NgbCollapseModule { } NgbCollapseModule.decorators = [ { type: NgModule, args: [{ declarations: [NgbCollapse], exports: [NgbCollapse] },] } ]; /** * @fileoverview added by tsickle * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ /** * A simple class that represents a date that datepicker also uses internally. * * It is the implementation of the `NgbDateStruct` interface that adds some convenience methods, * like `.equals()`, `.before()`, etc. * * All datepicker APIs consume `NgbDateStruct`, but return `NgbDate`. * * In many cases it is simpler to manipulate these objects together with * [`NgbCalendar`](#/components/datepicker/api#NgbCalendar) than native JS Dates. * * See the [date format overview](#/components/datepicker/overview#date-model) for more details. * * \@since 3.0.0 */ class NgbDate { /** * A **static method** that creates a new date object from the `NgbDateStruct`, * * ex. `NgbDate.from({year: 2000, month: 5, day: 1})`. * * If the `date` is already of `NgbDate` type, the method will return the same object. * @param {?} date * @return {?} */ static from(date) { if (date instanceof NgbDate) { return date; } return date ? new NgbDate(date.year, date.month, date.day) : null; } /** * @param {?} year * @param {?} month * @param {?} day */ constructor(year, month, day) { this.year = isInteger(year) ? year : null; this.month = isInteger(month) ? month : null; this.day = isInteger(day) ? day : null; } /** * Checks if the current date is equal to another date. * @param {?} other * @return {?} */ equals(other) { return other && this.year === other.year && this.month === other.month && this.day === other.day; } /** * Checks if the current date is before another date. * @param {?} other * @return {?} */ before(other) { if (!other) { return false; } if (this.year === other.year) { if (this.month === other.month) { return this.day === other.day ? false : this.day < other.day; } else { return this.month < other.month; } } else { return this.year < other.year; } } /** * Checks if the current date is after another date. * @param {?} other * @return {?} */ after(other) { if (!other) { return false; } if (this.year === other.year) { if (this.month === other.month) { return this.day === other.day ? false : this.day > other.day; } else { return this.month > other.month; } } else { return this.year > other.year; } } } /** * @fileoverview added by tsickle * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ /** * @param {?} jsDate * @return {?} */ function fromJSDate(jsDate) { return new NgbDate(jsDate.getFullYear(), jsDate.getMonth() + 1, jsDate.getDate()); } /** * @param {?} date * @return {?} */ function toJSDate(date) { /** @type {?} */ const jsDate = new Date(date.year, date.month - 1, date.day, 12); // this is done avoid 30 -> 1930 conversion if (!isNaN(jsDate.getTime())) { jsDate.setFullYear(date.year); } return jsDate; } /** * @return {?} */ function NGB_DATEPICKER_CALENDAR_FACTORY() { return new NgbCalendarGregorian(); } /** * A service that represents the calendar used by the datepicker. * * The default implementation uses the Gregorian calendar. You can inject it in your own * implementations if necessary to simplify `NgbDate` calculations. * @abstract */ class NgbCalendar { } NgbCalendar.decorators = [ { type: Injectable, args: [{ providedIn: 'root', useFactory: NGB_DATEPICKER_CALENDAR_FACTORY },] } ]; /** @nocollapse */ NgbCalendar.ngInjectableDef = ɵɵdefineInjectable({ factory: NGB_DATEPICKER_CALENDAR_FACTORY, token: NgbCalendar, providedIn: "root" }); class NgbCalendarGregorian extends NgbCalendar { /** * @return {?} */ getDaysPerWeek() { return 7; } /** * @return {?} */ getMonths() { return [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]; } /** * @return {?} */ getWeeksPerMonth() { return 6; } /** * @param {?} date * @param {?=} period * @param {?=} number * @return {?} */ getNext(date, period = 'd', number = 1) { /** @type {?} */ let jsDate = toJSDate(date); /** @type {?} */ let checkMonth = true; /** @type {?} */ let expectedMonth = jsDate.getMonth(); switch (period) { case 'y': jsDate.setFullYear(jsDate.getFullYear() + number); break; case 'm': expectedMonth += number; jsDate.setMonth(expectedMonth); expectedMonth = expectedMonth % 12; if (expectedMonth < 0) { expectedMonth = expectedMonth + 12; } break; case 'd': jsDate.setDate(jsDate.getDate() + number); checkMonth = false; break; default: return date; } if (checkMonth && jsDate.getMonth() !== expectedMonth) { // this means the destination month has less days than the initial month // let's go back to the end of the previous month: jsDate.setDate(0); } return fromJSDate(jsDate); } /** * @param {?} date * @param {?=} period * @param {?=} number * @return {?} */ getPrev(date, period = 'd', number = 1) { return this.getNext(date, period, -number); } /** * @param {?} date * @return {?} */ getWeekday(date) { /** @type {?} */ let jsDate = toJSDate(date); /** @type {?} */ let day = jsDate.getDay(); // in JS Date Sun=0, in ISO 8601 Sun=7 return day === 0 ? 7 : day; } /** * @param {?} week * @param {?} firstDayOfWeek * @return {?} */ getWeekNumber(week, firstDayOfWeek) { // in JS Date Sun=0, in ISO 8601 Sun=7 if (firstDayOfWeek === 7) { firstDayOfWeek = 0; } /** @type {?} */ const thursdayIndex = (4 + 7 - firstDayOfWeek) % 7; /** @type {?} */ let date = week[thursdayIndex]; /** @type {?} */ const jsDate = toJSDate(date); jsDate.setDate(jsDate.getDate() + 4 - (jsDate.getDay() || 7)); // Thursday // Thursday /** @type {?} */ const time = jsDate.getTime(); jsDate.setMonth(0); // Compare with Jan 1 jsDate.setDate(1); return Math.floor(Math.round((time - jsDate.getTime()) / 86400000) / 7) + 1; } /** * @return {?} */ getToday() { return fromJSDate(new Date()); } /** * @param {?} date * @return {?} */ isValid(date) { if (!date || !isInteger(date.year) || !isInteger(date.month) || !isInteger(date.day)) { return false; } // year 0 doesn't exist in Gregorian calendar if (date.year === 0) { return false; } /** @type {?} */ const jsDate = toJSDate(date); return !isNaN(jsDate.getTime()) && jsDate.getFullYear() === date.year && jsDate.getMonth() + 1 === date.month && jsDate.getDate() === date.day; } } NgbCalendarGregorian.decorators = [ { type: Injectable } ]; /** * @fileoverview added by tsickle * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ /** * @param {?} prev * @param {?} next * @return {?} */ function isChangedDate(prev, next) { return !dateComparator(prev, next); } /** * @param {?} prev * @param {?} next * @return {?} */ function isChangedMonth(prev, next) { return !prev && !next ? false : !prev || !next ? true : prev.year !== next.year || prev.month !== next.month; } /** * @param {?} prev * @param {?} next * @return {?} */ function dateComparator(prev, next) { return (!prev && !next) || (!!prev && !!next && prev.equals(next)); } /** * @param {?} minDate * @param {?} maxDate * @return {?} */ function checkMinBeforeMax(minDate, maxDate) { if (maxDate && minDate && maxDate.before(minDate)) { throw new Error(`'maxDate' ${maxDate} should be greater than 'minDate' ${minDate}`); } } /** * @param {?} date * @param {?} minDate * @param {?} maxDate * @return {?} */ function checkDateInRange(date, minDate, maxDate) { if (date && minDate && date.before(minDate)) { return minDate; } if (date && maxDate && date.after(maxDate)) { return maxDate; } return date; } /** * @param {?} date * @param {?} state * @return {?} */ function isDateSelectable(date, state) { const { minDate, maxDate, disabled, markDisabled } = state; // clang-format off return !(!isDefined(date) || disabled || (markDisabled && markDisabled(date, { year: date.year, month: date.month })) || (minDate && date.before(minDate)) || (maxDate && date.after(maxDate))); // clang-format on } /** * @param {?} calendar * @param {?} date * @param {?} minDate * @param {?} maxDate * @return {?} */ function generateSelectBoxMonths(calendar, date, minDate, maxDate) { if (!date) { return []; } /** @type {?} */ let months = calendar.getMonths(date.year); if (minDate && date.year === minDate.year) { /** @type {?} */ const index = months.findIndex((/** * @param {?} month * @return {?} */ month => month === minDate.month)); months = months.slice(index); } if (maxDate && date.year === maxDate.year) { /** @type {?} */ const index = months.findIndex((/** * @param {?} month * @return {?} */ month => month === maxDate.month)); months = months.slice(0, index + 1); } return months; } /** * @param {?} date * @param {?} minDate * @param {?} maxDate * @return {?} */ function generateSelectBoxYears(date, minDate, maxDate) { if (!date) { return []; } /** @type {?} */ const start = minDate ? Math.max(minDate.year, date.year - 500) : date.year - 10; /** @type {?} */ const end = maxDate ? Math.min(maxDate.year, date.year + 500) : date.year + 10; /** @type {?} */ const length = end - start + 1; /** @type {?} */ const numbers = Array(length); for (let i = 0; i < length; i++) { numbers[i] = start + i; } return numbers; } /** * @param {?} calendar * @param {?} date * @param {?} maxDate * @return {?} */ function nextMonthDisabled(calendar, date, maxDate) { /** @type {?} */ const nextDate = Object.assign(calendar.getNext(date, 'm'), { day: 1 }); return maxDate && nextDate.after(maxDate); } /** * @param {?} calendar * @param {?} date * @param {?} minDate * @return {?} */ function prevMonthDisabled(calendar, date, minDate) { /** @type {?} */ const prevDate = Object.assign(calendar.getPrev(date, 'm'), { day: 1 }); return minDate && (prevDate.year === minDate.year && prevDate.month < minDate.month || prevDate.year < minDate.year && minDate.month === 1); } /** * @param {?} calendar * @param {?} date * @param {?} state * @param {?} i18n * @param {?} force * @return {?} */ function buildMonths(calendar, date, state, i18n, force) { const { displayMonths, months } = state; // move old months to a temporary array /** @type {?} */ const monthsToReuse = months.splice(0, months.length); // generate new first dates, nullify or reuse months /** @type {?} */ const firstDates = Array.from({ length: displayMonths }, (/** * @param {?} _ * @param {?} i * @return {?} */ (_, i) => { /** @type {?} */ const firstDate = Object.assign(calendar.getNext(date, 'm', i), { day: 1 }); months[i] = null; if (!force) { /** @type {?} */ const reusedIndex = monthsToReuse.findIndex((/** * @param {?} month * @return {?} */ month => month.firstDate.equals(firstDate))); // move reused month back to months if (reusedIndex !== -1) { months[i] = monthsToReuse.splice(reusedIndex, 1)[0]; } } return firstDate; })); // rebuild nullified months firstDates.forEach((/** * @param {?} firstDate * @param {?} i * @return {?} */ (firstDate, i) => { if (months[i] === null) { months[i] = buildMonth(calendar, firstDate, state, i18n, monthsToReuse.shift() || (/** @type {?} */ ({}))); } })); return months; } /** * @param {?} calendar * @param {?} date * @param {?} state * @param {?} i18n * @param {?=} month * @return {?} */ function buildMonth(calendar, date, state, i18n, month = (/** @type {?} */ ({}))) { const { dayTemplateData, minDate, maxDate, firstDayOfWeek, markDisabled, outsideDays } = state; /** @type {?} */ const calendarToday = calendar.getToday(); month.firstDate = null; month.lastDate = null; month.number = date.month; month.year = date.year; month.weeks = month.weeks || []; month.weekdays = month.weekdays || []; date = getFirstViewDate(calendar, date, firstDayOfWeek); // month has weeks for (let week = 0; week < calendar.getWeeksPerMonth(); week++) { /** @type {?} */ let weekObject = month.weeks[week]; if (!weekObject) { weekObject = month.weeks[week] = { number: 0, days: [], collapsed: true }; } /** @type {?} */ const days = weekObject.days; // week has days for (let day = 0; day < calendar.getDaysPerWeek(); day++) { if (week === 0) { month.weekdays[day] = calendar.getWeekday(date); } /** @type {?} */ const newDate = new NgbDate(date.year, date.month, date.day); /** @type {?} */ const nextDate = calendar.getNext(newDate); /** @type {?} */ const ariaLabel = i18n.getDayAriaLabel(newDate); // marking date as disabled /** @type {?} */ let disabled = !!((minDate && newDate.before(minDate)) || (maxDate && newDate.after(maxDate))); if (!disabled && markDisabled) { disabled = markDisabled(newDate, { month: month.number, year: month.year }); } // today /** @type {?} */ let today = newDate.equals(calendarToday); // adding user-provided data to the context /** @type {?} */ let contextUserData = dayTemplateData ? dayTemplateData(newDate, { month: month.number, year: month.year }) : undefined; // saving first date of the month if (month.firstDate === null && newDate.month === month.number) { month.firstDate = newDate; } // saving last date of the month if (newDate.month === month.number && nextDate.month !== month.number) { month.lastDate = newDate; } /** @type {?} */ let dayObject = days[day]; if (!dayObject) { dayObject = days[day] = (/** @type {?} */ ({})); } dayObject.date = newDate; dayObject.context = Object.assign(dayObject.context || {}, { $implicit: newDate, date: newDate, data: contextUserData, currentMonth: month.number, currentYear: month.year, disabled, focused: false, selected: false, today }); dayObject.tabindex = -1; dayObject.ariaLabel = ariaLabel; dayObject.hidden = false; date = nextDate; } weekObject.number = calendar.getWeekNumber(days.map((/** * @param {?} day * @return {?} */ day => day.date)), firstDayOfWeek); // marking week as collapsed weekObject.collapsed = outsideDays === 'collapsed' && days[0].date.month !== month.number && days[days.length - 1].date.month !== month.number; } return month; } /** * @param {?} calendar * @param {?} date * @param {?} firstDayOfWeek * @return {?} */ function getFirstViewDate(calendar, date, firstDayOfWeek) { /** @type {?} */ const daysPerWeek = calendar.getDaysPerWeek(); /** @type {?} */ const firstMonthDate = new NgbDate(date.year, date.month, 1); /** @type {?} */ const dayOfWeek = calendar.getWeekday(firstMonthDate) % daysPerWeek; return calendar.getPrev(firstMonthDate, 'd', (daysPerWeek + dayOfWeek - firstDayOfWeek) % daysPerWeek); } /** * @fileoverview added by tsickle * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ /** * @param {?} locale * @return {?} */ function NGB_DATEPICKER_18N_FACTORY(locale) { return new NgbDatepickerI18nDefault(locale); } /** * A service supplying i18n data to the datepicker component. * * The default implementation of this service uses the Angular locale and registered locale data for * weekdays and month names (as explained in the Angular i18n guide). * * It also provides a way to i18n data that depends on calendar calculations, like aria labels, day, week and year * numerals. For other static labels the datepicker uses the default Angular i18n. * * See the [i18n demo](#/components/datepicker/examples#i18n) and * [Hebrew calendar demo](#/components/datepicker/calendars#hebrew) on how to extend this class and define * a custom provider for i18n. * @abstract */ class NgbDatepickerI18n { /** * Returns the textual representation of a day that is rendered in a day cell. * * \@since 3.0.0 * @param {?} date * @return {?} */ getDayNumerals(date) { return `${date.day}`; } /** * Returns the textual representation of a week number rendered by datepicker. * * \@since 3.0.0 * @param {?} weekNumber * @return {?} */ getWeekNumerals(weekNumber) { return `${weekNumber}`; } /** * Returns the textual representation of a year that is rendered in the datepicker year select box. * * \@since 3.0.0 * @param {?} year * @return {?} */ getYearNumerals(year) { return `${year}`; } } NgbDatepickerI18n.decorators = [ { type: Injectable, args: [{ providedIn: 'root', useFactory: NGB_DATEPICKER_18N_FACTORY, deps: [LOCALE_ID] },] } ]; /** @nocollapse */ NgbDatepickerI18n.ngInjectableDef = ɵɵdefineInjectable({ factory: function NgbDatepickerI18n_Factory() { return NGB_DATEPICKER_18N_FACTORY(ɵɵinject(LOCALE_ID)); }, token: NgbDatepickerI18n, providedIn: "root" }); class NgbDatepickerI18nDefault extends NgbDatepickerI18n { /** * @param {?} _locale */ constructor(_locale) { super(); this._locale = _locale; /** @type {?} */ const weekdaysStartingOnSunday = getLocaleDayNames(_locale, FormStyle.Standalone, TranslationWidth.Short); this._weekdaysShort = weekdaysStartingOnSunday.map((/** * @param {?} day * @param {?} index * @return {?} */ (day, index) => weekdaysStartingOnSunday[(index + 1) % 7])); this._monthsShort = getLocaleMonthNames(_locale, FormStyle.Standalone, TranslationWidth.Abbreviated); this._monthsFull = getLocaleMonthNames(_locale, FormStyle.Standalone, TranslationWidth.Wide); } /** * @param {?} weekday * @return {?} */ getWeekdayShortName(weekday) { return this._weekdaysShort[weekday - 1]; } /** * @param {?} month * @return {?} */ getMonthShortName(month) { return this._monthsShort[month - 1]; } /** * @param {?} month * @return {?} */ getMonthFullName(month) { return this._monthsFull[month - 1]; } /** * @param {?} date * @return {?} */ getDayAriaLabel(date) { /** @type {?} */ const jsDate = new Date(date.year, date.month - 1, date.day); return formatDate(jsDate, 'fullDate', this._locale); } } NgbDatepickerI18nDefault.decorators = [ { type: Injectable } ]; /** @nocollapse */ NgbDatepickerI18nDefault.ctorParameters = () => [ { type: String, decorators: [{ type: Inject, args: [LOCALE_ID,] }] } ]; /** * @fileoverview added by tsickle * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ class NgbDatepickerService { /** * @param {?} _calendar * @param {?} _i18n */ constructor(_calendar, _i18n) { this._calendar = _calendar; this._i18n = _i18n; this._VALIDATORS = { dayTemplateData: (/** * @param {?} dayTemplateData * @return {?} */ (dayTemplateData) => { if (this._state.dayTemplateData !== dayTemplateData) { return { dayTemplateData }; } }), displayMonths: (/** * @param {?} displayMonths * @return {?} */ (displayMonths) => { displayMonths = toInteger(displayMonths); if (isInteger(displayMonths) && displayMonths > 0 && this._state.displayMonths !== displayMonths) { return { displayMonths }; } }), disabled: (/** * @param {?} disabled * @return {?} */ (disabled) => { if (this._state.disabled !== disabled) { return { disabled }; } }), firstDayOfWeek: (/** * @param {?} firstDayOfWeek * @return {?} */ (firstDayOfWeek) => { firstDayOfWeek = toInteger(firstDayOfWeek); if (isInteger(firstDayOfWeek) && firstDayOfWeek >= 0 && this._state.firstDayOfWeek !== firstDayOfWeek) { return { firstDayOfWeek }; } }), focusVisible: (/** * @param {?} focusVisible * @return {?} */ (focusVisible) => { if (this._state.focusVisible !== focusVisible && !this._state.disabled) { return { focusVisible }; } }), markDisabled: (/** * @param {?} markDisabled * @return {?} */ (markDisabled) => { if (this._state.markDisabled !== markDisabled) { return { markDisabled }; } }), maxDate: (/** * @param {?} date * @return {?} */ (date) => { /** @type {?} */ const maxDate = this.toValidDate(date, null); if (isChangedDate(this._state.maxDate, maxDate)) { return { maxDate }; } }), minDate: (/** * @param {?} date * @return {?} */ (date) => { /** @type {?} */ const minDate = this.toValidDate(date, null); if (isChangedDate(this._state.minDate, minDate)) { return { minDate }; } }), navigation: (/** * @param {?} navigation * @return {?} */ (navigation) => { if (this._state.navigation !== navigation) { return { navigation }; } }), outsideDays: (/** * @param {?} outsideDays * @return {?} */ (outsideDays) => { if (this._state.outsideDays !== outsideDays) { return { outsideDays }; } }) }; this._model$ = new Subject(); this._dateSelect$ = new Subject(); this._state = { disabled: false, displayMonths: 1, firstDayOfWeek: 1, focusVisible: false, months: [], navigation: 'select', outsideDays: 'visible', prevDisabled: false, nextDisabled: false, selectBoxes: { years: [], months: [] }, selectedDate: null }; } /** * @return {?} */ get model$() { return this._model$.pipe(filter((/** * @param {?} model * @return {?} */ model => model.months.length > 0))); } /** * @return {?} */ get dateSelect$() { return this._dateSelect$.pipe(filter((/** * @param {?} date * @return {?} */ date => date !== null))); } /** * @param {?} options * @return {?} */ set(options) { /** @type {?} */ let patch = Object.keys(options) .map((/** * @param {?} key * @return {?} */ key => this._VALIDATORS[key](options[key]))) .reduce((/** * @param {?} obj * @param {?} part * @return {?} */ (obj, part) => (Object.assign({}, obj, part))), {}); if (Object.keys(patch).length > 0) { this._nextState(patch); } } /** * @param {?} date * @return {?} */ focus(date) { if (!this._state.disabled && this._calendar.isValid(date) && isChangedDate(this._state.focusDate, date)) { this._nextState({ focusDate: date }); } } /** * @return {?} */ focusSelect() { if (isDateSelectable(this._state.focusDate, this._state)) { this.select(this._state.focusDate, { emitEvent: true }); } } /** * @param {?} date * @return {?} */ open(date) { /** @type {?} */ const firstDate = this.toValidDate(date, this._calendar.getToday()); if (!this._state.disabled && (!this._state.firstDate || isChangedMonth(this._state.firstDate, date))) { this._nextState({ firstDate }); } } /** * @param {?} date * @param {?=} options * @return {?} */ select(date, options = {}) { /** @type {?} */ const selectedDate = this.toValidDate(date, null); if (!this._state.disabled) { if (isChangedDate(this._state.selectedDate, selectedDate)) { this._nextState({ selectedDate }); } if (options.emitEvent && isDateSelectable(selectedDate, this._state)) { this._dateSelect$.next(selectedDate); } } } /** * @param {?} date * @param {?=} defaultValue * @return {?} */ toValidDate(date, defaultValue) { /** @type {?} */ const ngbDate = NgbDate.from(date); if (defaultValue === undefined) { defaultValue = this._calendar.getToday(); } return this._calendar.isValid(ngbDate) ? ngbDate : defaultValue; } /** * @private * @param {?} patch * @return {?} */ _nextState(patch) { /** @type {?} */ const newState = this._updateState(patch); this._patchContexts(newState); this._state = newState; this._model$.next(this._state); } /** * @private * @param {?} state * @return {?} */ _patchContexts(state) { const { months, displayMonths, selectedDate, focusDate, focusVisible, disabled, outsideDays } = state; state.months.forEach((/** * @param {?} month * @return {?} */ month => { month.weeks.forEach((/** * @param {?} week * @return {?} */ week => { week.days.forEach((/** * @param {?} day * @return {?} */ day => { // patch focus flag if (focusDate) { day.context.focused = focusDate.equals(day.date) && focusVisible; } // calculating tabindex day.tabindex = !disabled && day.date.equals(focusDate) && focusDate.month === month.number ? 0 : -1; // override context disabled if (disabled === true) { day.context.disabled = true; } // patch selection flag if (selectedDate !== undefined) { day.context.selected = selectedDate !== null && selectedDate.equals(day.date); } // visibility if (month.number !== day.date.month) { day.hidden = outsideDays === 'hidden' || outsideDays === 'collapsed' || (displayMonths > 1 && day.date.after(months[0].firstDate) && day.date.before(months[displayMonths - 1].lastDate)); } })); })); })); } /** * @private * @param {?} patch * @return {?} */ _updateState(patch) { // patching fields /** @type {?} */ const state = Object.assign({}, this._state, patch); /** @type {?} */ let startDate = state.firstDate; // min/max dates changed if ('minDate' in patch || 'maxDate' in patch) { checkMinBeforeMax(state.minDate, state.maxDate); state.focusDate = checkDateInRange(state.focusDate, state.minDate, state.maxDate); state.firstDate = checkDateInRange(state.firstDate, state.minDate, state.maxDate); startDate = state.focusDate; } // disabled if ('disabled' in patch) { state.focusVisible = false; } // initial rebuild via 'select()' if ('selectedDate' in patch && this._state.months.length === 0) { startDate = state.selectedDate; } // terminate early if only focus visibility was changed if ('focusVisible' in patch) { return state; } // focus date changed if ('focusDate' in patch) { state.focusDate = checkDateInRange(state.focusDate, state.minDate, state.maxDate); startDate = state.focusDate; // nothing to rebuild if only focus changed and it is still visible if (state.months.length !== 0 && !state.focusDate.before(state.firstDate) && !state.focusDate.after(state.lastDate)) { return state; } } // first date changed if ('firstDate' in patch) { state.firstDate = checkDateInRange(state.firstDate, state.minDate, state.maxDate); startDate = state.firstDate; } // rebuilding months if (startDate) { /** @type {?} */ const forceRebuild = 'dayTemplateData' in patch || 'firstDayOfWeek' in patch || 'markDisabled' in patch || 'minDate' in patch || 'maxDate' in patch || 'disabled' in patch || 'outsideDays' in patch; /** @type {?} */ const months = buildMonths(this._calendar, startDate, state, this._i18n, forceRebuild); // updating months and boundary dates state.months = months; state.firstDate = months.length > 0 ? months[0].firstDate : undefined; state.lastDate = months.length > 0 ? months[months.length - 1].lastDate : undefined; // reset selected date if 'markDisabled' returns true if ('selectedDate' in patch && !isDateSelectable(state.selectedDate, state)) { state.selectedDate = null; } // adjusting focus after months were built if ('firstDate' in patch) { if (state.focusDate === undefined || state.focusDate.before(state.firstDate) || state.focusDate.after(state.lastDate)) { state.focusDate = startDate; } } // adjusting months/years for the select box navigation /** @type {?} */ const yearChanged = !this._state.firstDate || this._state.firstDate.year !== state.firstDate.year; /** @type {?} */ const monthChanged = !this._state.firstDate || this._state.firstDate.month !== state.firstDate.month; if (state.navigation === 'select') { // years -> boundaries (min/max were changed) if ('minDate' in patch || 'maxDate' in patch || state.selectBoxes.years.length === 0 || yearChanged) { state.selectBoxes.years = generateSelectBoxYears(state.firstDate, state.minDate, state.maxDate); } // months -> when current year or boundaries change if ('minDate' in patch || 'maxDate' in patch || state.selectBoxes.months.length === 0 || yearChanged) { state.selectBoxes.months = generateSelectBoxMonths(this._calendar, state.firstDate, state.minDate, state.maxDate); } } else { state.selectBoxes = { years: [], months: [] }; } // updating navigation arrows -> boundaries change (min/max) or month/year changes if ((state.navigation === 'arrows' || state.navigation === 'select') && (monthChanged || yearChanged || 'minDate' in patch || 'maxDate' in patch || 'disabled' in patch)) { state.prevDisabled = state.disabled || prevMonthDisabled(this._calendar, state.firstDate, state.minDate); state.nextDisabled = state.disabled || nextMonthDisabled(this._calendar, state.lastDate, state.maxDate); } } return state; } } NgbDatepickerService.decorators = [ { type: Injectable } ]; /** @nocollapse */ NgbDatepickerService.ctorParameters = () => [ { type: NgbCalendar }, { type: NgbDatepickerI18n } ]; /** * @fileoverview added by tsickle * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ /** @enum {number} */ const Key = { Tab: 9, Enter: 13, Escape: 27, Space: 32, PageUp: 33, PageDown: 34, End: 35, Home: 36, ArrowLeft: 37, ArrowUp: 38, ArrowRight: 39, ArrowDown: 40, }; Key[Key.Tab] = 'Tab'; Key[Key.Enter] = 'Enter'; Key[Key.Escape] = 'Escape'; Key[Key.Space] = 'Space'; Key[Key.PageUp] = 'PageUp'; Key[Key.PageDown] = 'PageDown'; Key[Key.End] = 'End'; Key[Key.Home] = 'Home'; Key[Key.ArrowLeft] = 'ArrowLeft'; Key[Key.ArrowUp] = 'ArrowUp'; Key[Key.ArrowRight] = 'ArrowRight'; Key[Key.ArrowDown] = 'ArrowDown'; /** * @fileoverview added by tsickle * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ /** * A service that represents the keyboard navigation. * * Default keyboard shortcuts [are documented in the overview](#/components/datepicker/overview#keyboard-shortcuts) * * \@since 5.2.0 */ class NgbDatepickerKeyboardService { /** * Processes a keyboard event. * @param {?} event * @param {?} datepicker * @param {?} calendar * @return {?} */ processKey(event, datepicker, calendar) { /** @type {?} */ const state = datepicker.state; // tslint:disable-next-line:deprecation switch (event.which) { case Key.PageUp: datepicker.focusDate(calendar.getPrev(state.focusedDate, event.shiftKey ? 'y' : 'm', 1)); break; case Key.PageDown: datepicker.focusDate(calendar.getNext(state.focusedDate, event.shiftKey ? 'y' : 'm', 1)); break; case Key.End: datepicker.focusDate(event.shiftKey ? state.maxDate : state.lastDate); break; case Key.Home: datepicker.focusDate(event.shiftKey ? state.minDate : state.firstDate); break; case Key.ArrowLeft: datepicker.focusDate(calendar.getPrev(state.focusedDate, 'd', 1)); break; case Key.ArrowUp: datepicker.focusDate(calendar.getPrev(state.focusedDate, 'd', calendar.getDaysPerWeek())); break; case Key.ArrowRight: datepicker.focusDate(calendar.getNext(state.focusedDate, 'd', 1)); break; case Key.ArrowDown: datepicker.focusDate(calendar.getNext(state.focusedDate, 'd', calendar.getDaysPerWeek())); break; case Key.Enter: case Key.Space: datepicker.focusSelect(); break; default: return; } event.preventDefault(); event.stopPropagation(); } } NgbDatepickerKeyboardService.decorators = [ { type: Injectable, args: [{ providedIn: 'root' },] } ]; /** @nocollapse */ NgbDatepickerKeyboardService.ngInjectableDef = ɵɵdefineInjectable({ factory: function NgbDatepickerKeyboardService_Factory() { return new NgbDatepickerKeyboardService(); }, token: NgbDatepickerKeyboardService, providedIn: "root" }); /** * @fileoverview added by tsickle * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ /** @enum {number} */ const NavigationEvent = { PREV: 0, NEXT: 1, }; NavigationEvent[NavigationEvent.PREV] = 'PREV'; NavigationEvent[NavigationEvent.NEXT] = 'NEXT'; /** * @fileoverview added by tsickle * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ /** * A configuration service for the [`NgbDatepicker`](#/components/datepicker/api#NgbDatepicker) component. * * You can inject this service, typically in your root component, and customize the values of its properties in * order to provide default values for all the datepickers used in the application. */ class NgbDatepickerConfig { constructor() { this.displayMonths = 1; this.firstDayOfWeek = 1; this.navigation = 'select'; this.outsideDays = 'visible'; this.showWeekdays = true; this.showWeekNumbers = false; } } NgbDatepickerConfig.decorators = [ { type: Injectable, args: [{ providedIn: 'root' },] } ]; /** @nocollapse */ NgbDatepickerConfig.ngInjectableDef = ɵɵdefineInjectable({ factory: function NgbDatepickerConfig_Factory() { return new NgbDatepickerConfig(); }, token: NgbDatepickerConfig, providedIn: "root" }); /** * @fileoverview added by tsickle * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ /** * @return {?} */ function NGB_DATEPICKER_DATE_ADAPTER_FACTORY() { return new NgbDateStructAdapter(); } /** * An abstract service that does the conversion between the internal datepicker `NgbDateStruct` model and * any provided user date model `D`, ex. a string, a native date, etc. * * The adapter is used **only** for conversion when binding datepicker to a form control, * ex. `[(ngModel)]="userDateModel"`. Here `userDateModel` can be of any type. * * The default datepicker implementation assumes we use `NgbDateStruct` as a user model. * * See the [date format overview](#/components/datepicker/overview#date-model) for more details * and the [custom adapter demo](#/components/datepicker/examples#adapter) for an example. * @abstract * @template D */ class NgbDateAdapter { } NgbDateAdapter.decorators = [ { type: Injectable, args: [{ providedIn: 'root', useFactory: NGB_DATEPICKER_DATE_ADAPTER_FACTORY },] } ]; /** @nocollapse */ NgbDateAdapter.ngInjectableDef = ɵɵdefineInjectable({ factory: NGB_DATEPICKER_DATE_ADAPTER_FACTORY, token: NgbDateAdapter, providedIn: "root" }); class NgbDateStructAdapter extends NgbDateAdapter { /** * Converts a NgbDateStruct value into NgbDateStruct value * @param {?} date * @return {?} */ fromModel(date) { return (date && isInteger(date.year) && isInteger(date.month) && isInteger(date.day)) ? { year: date.year, month: date.month, day: date.day } : null; } /** * Converts a NgbDateStruct value into NgbDateStruct value * @param {?} date * @return {?} */ toModel(date) { return (date && isInteger(date.year) && isInteger(date.month) && isInteger(date.day)) ? { year: date.year, month: date.month, day: date.day } : null; } } NgbDateStructAdapter.decorators = [ { type: Injectable } ]; /** * @fileoverview added by tsickle * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ /** @type {?} */ const NGB_DATEPICKER_VALUE_ACCESSOR = { provide: NG_VALUE_ACCESSOR, useExisting: forwardRef((/** * @return {?} */ () => NgbDatepicker)), multi: true }; /** * A highly configurable component that helps you with selecting calendar dates. * * `NgbDatepicker` is meant to be displayed inline on a page or put inside a popup. */ class NgbDatepicker { /** * @param {?} _service * @param {?} _calendar * @param {?} i18n * @param {?} config * @param {?} _keyboardService * @param {?} cd * @param {?} _elementRef * @param {?} _ngbDateAdapter * @param {?} _ngZone */ constructor(_service, _calendar, i18n, config, _keyboardService, cd, _elementRef, _ngbDateAdapter, _ngZone) { this._service = _service; this._calendar = _calendar; this.i18n = i18n; this._keyboardService = _keyboardService; this._elementRef = _elementRef; this._ngbDateAdapter = _ngbDateAdapter; this._ngZone = _ngZone; this._destroyed$ = new Subject(); this._publicState = (/** @type {?} */ ({})); /** * An event emitted right before the navigation happens and displayed month changes. * * See [`NgbDatepickerNavigateEvent`](#/components/datepicker/api#NgbDatepickerNavigateEvent) for the payload info. */ this.navigate = new EventEmitter(); /** * An event emitted when user selects a date using keyboard or mouse. * * The payload of the event is currently selected `NgbDate`. * * \@since 5.2.0 */ this.dateSelect = new EventEmitter(); /** * An event emitted when user selects a date using keyboard or mouse. * * The payload of the event is currently selected `NgbDate`. * * Please use 'dateSelect' output instead, this will be deprecated in version 6.0 due to collision with native * 'select' event. */ this.select = this.dateSelect; this.onChange = (/** * @param {?} _ * @return {?} */ (_) => { }); this.onTouched = (/** * @return {?} */ () => { }); ['dayTemplate', 'dayTemplateData', 'displayMonths', 'firstDayOfWeek', 'footerTemplate', 'markDisabled', 'minDate', 'maxDate', 'navigation', 'outsideDays', 'showWeekdays', 'showWeekNumbers', 'startDate'] .forEach((/** * @param {?} input * @return {?} */ input => this[input] = config[input])); _service.dateSelect$.pipe(takeUntil(this._destroyed$)).subscribe((/** * @param {?} date * @return {?} */ date => { this.dateSelect.emit(date); })); _service.model$.pipe(takeUntil(this._destroyed$)).subscribe((/** * @param {?} model * @return {?} */ model => { /** @type {?} */ const newDate = model.firstDate; /** @type {?} */ const oldDate = this.model ? this.model.firstDate : null; // update public state this._publicState = { maxDate: model.maxDate, minDate: model.minDate, firstDate: model.firstDate, lastDate: model.lastDate, focusedDate: model.focusDate }; /** @type {?} */ let navigationPrevented = false; // emitting navigation event if the first month changes if (!newDate.equals(oldDate)) { this.navigate.emit({ current: oldDate ? { year: oldDate.year, month: oldDate.month } : null, next: { year: newDate.year, month: newDate.month }, preventDefault: (/** * @return {?} */ () => navigationPrevented = true) }); // can't prevent the very first navigation if (navigationPrevented && oldDate !== null) { this._service.open(oldDate); return; } } /** @type {?} */ const newSelectedDate = model.selectedDate; /** @type {?} */ const newFocusedDate = model.focusDate; /** @type {?} */ const oldFocusedDate = this.model ? this.model.focusDate : null; this.model = model; // handling selection change if (isChangedDate(newSelectedDate, this._controlValue)) { this._controlValue = newSelectedDate; this.onTouched(); this.onChange(this._ngbDateAdapter.toModel(newSelectedDate)); } // handling focus change if (isChangedDate(newFocusedDate, oldFocusedDate) && oldFocusedDate && model.focusVisible) { this.focus(); } cd.markForCheck(); })); } /** * Returns the readonly public state of the datepicker * * \@since 5.2.0 * @return {?} */ get state() { return this._publicState; } /** * Focuses on given date. * @param {?} date * @return {?} */ focusDate(date) { this._service.focus(NgbDate.from(date)); } /** * Selects focused date. * @return {?} */ focusSelect() { this._service.focusSelect(); } /** * @return {?} */ focus() { this._ngZone.onStable.asObservable().pipe(take(1)).subscribe((/** * @return {?} */ () => { /** @type {?} */ const elementToFocus = this._elementRef.nativeElement.querySelector('div.ngb-dp-day[tabindex="0"]'); if (elementToFocus) { elementToFocus.focus(); } })); } /** * Navigates to the provided date. * * With the default calendar we use ISO 8601: 'month' is 1=Jan ... 12=Dec. * If nothing or invalid date provided calendar will open current month. * * Use the `[startDate]` input as an alternative. * @param {?=} date * @return {?} */ navigateTo(date) { this._service.open(NgbDate.from(date ? date.day ? (/** @type {?} */ (date)) : Object.assign({}, date, { day: 1 }) : null)); } /** * @return {?} */ ngAfterViewInit() { this._ngZone.runOutsideAngular((/** * @return {?} */ () => { /** @type {?} */ const focusIns$ = fromEvent(this._monthsEl.nativeElement, 'focusin'); /** @type {?} */ const focusOuts$ = fromEvent(this._monthsEl.nativeElement, 'focusout'); const { nativeElement } = this._elementRef; // we're changing 'focusVisible' only when entering or leaving months view // and ignoring all focus events where both 'target' and 'related' target are day cells merge(focusIns$, focusOuts$) .pipe(filter((/** * @param {?} __0 * @return {?} */ ({ target, relatedTarget }) => !(hasClassName(target, 'ngb-dp-day') && hasClassName(relatedTarget, 'ngb-dp-day') && nativeElement.contains((/** @type {?} */ (target))) && nativeElement.contains((/** @type {?} */ (relatedTarget)))))), takeUntil(this._destroyed$)) .subscribe((/** * @param {?} __0 * @return {?} */ ({ type }) => this._ngZone.run((/** * @return {?} */ () => this._service.set({ focusVisible: type === 'focusin' }))))); })); } /** * @return {?} */ ngOnDestroy() { this._destroyed$.next(); } /** * @return {?} */ ngOnInit() { if (this.model === undefined) { /** @type {?} */ const inputs = {}; ['dayTemplateData', 'displayMonths', 'markDisabled', 'firstDayOfWeek', 'navigation', 'minDate', 'maxDate', 'outsideDays'] .forEach((/** * @param {?} name * @return {?} */ name => inputs[name] = this[name])); this._service.set(inputs); this.navigateTo(this.startDate); } } /** * @param {?} changes * @return {?} */ ngOnChanges(changes) { /** @type {?} */ const inputs = {}; ['dayTemplateData', 'displayMonths', 'markDisabled', 'firstDayOfWeek', 'navigation', 'minDate', 'maxDate', 'outsideDays'] .filter((/** * @param {?} name * @return {?} */ name => name in changes)) .forEach((/** * @param {?} name * @return {?} */ name => inputs[name] = this[name])); this._service.set(inputs); if ('startDate' in changes) { const { currentValue, previousValue } = changes.startDate; if (isChangedMonth(previousValue, currentValue)) { this.navigateTo(this.startDate); } } } /** * @param {?} date * @return {?} */ onDateSelect(date) { this._service.focus(date); this._service.select(date, { emitEvent: true }); } /** * @param {?} event * @return {?} */ onKeyDown(event) { this._keyboardService.processKey(event, this, this._calendar); } /** * @param {?} date * @return {?} */ onNavigateDateSelect(date) { this._service.open(date); } /** * @param {?} event * @return {?} */ onNavigateEvent(event) { switch (event) { case NavigationEvent.PREV: this._service.open(this._calendar.getPrev(this.model.firstDate, 'm', 1)); break; case NavigationEvent.NEXT: this._service.open(this._calendar.getNext(this.model.firstDate, 'm', 1)); break; } } /** * @param {?} fn * @return {?} */ registerOnChange(fn) { this.onChange = fn; } /** * @param {?} fn * @return {?} */ registerOnTouched(fn) { this.onTouched = fn; } /** * @param {?} disabled * @return {?} */ setDisabledState(disabled) { this._service.set({ disabled }); } /** * @param {?} value * @return {?} */ writeValue(value) { this._controlValue = NgbDate.from(this._ngbDateAdapter.fromModel(value)); this._service.select(this._controlValue); } } NgbDatepicker.decorators = [ { type: Component, args: [{ exportAs: 'ngbDatepicker', selector: 'ngb-datepicker', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, template: `
{{ i18n.getMonthFullName(month.number, month.year) }} {{ i18n.getYearNumerals(month.year) }}
`, providers: [NGB_DATEPICKER_VALUE_ACCESSOR, NgbDatepickerService], styles: ["ngb-datepicker{border:1px solid #dfdfdf;border-radius:.25rem;display:inline-block}ngb-datepicker-month-view{pointer-events:auto}ngb-datepicker.dropdown-menu{padding:0}.ngb-dp-body{z-index:1050}.ngb-dp-header{border-bottom:0;border-radius:.25rem .25rem 0 0;padding-top:.25rem;background-color:#f8f9fa;background-color:var(--light)}.ngb-dp-months{display:-ms-flexbox;display:flex}.ngb-dp-month{pointer-events:none}.ngb-dp-month-name{font-size:larger;height:2rem;line-height:2rem;text-align:center;background-color:#f8f9fa;background-color:var(--light)}.ngb-dp-month+.ngb-dp-month .ngb-dp-month-name,.ngb-dp-month+.ngb-dp-month .ngb-dp-week{padding-left:1rem}.ngb-dp-month:last-child .ngb-dp-week{padding-right:.25rem}.ngb-dp-month:first-child .ngb-dp-week{padding-left:.25rem}.ngb-dp-month .ngb-dp-week:last-child{padding-bottom:.25rem}"] }] } ]; /** @nocollapse */ NgbDatepicker.ctorParameters = () => [ { type: NgbDatepickerService }, { type: NgbCalendar }, { type: NgbDatepickerI18n }, { type: NgbDatepickerConfig }, { type: NgbDatepickerKeyboardService }, { type: ChangeDetectorRef }, { type: ElementRef }, { type: NgbDateAdapter }, { type: NgZone } ]; NgbDatepicker.propDecorators = { _monthsEl: [{ type: ViewChild, args: ['months', { static: true },] }], dayTemplate: [{ type: Input }], dayTemplateData: [{ type: Input }], displayMonths: [{ type: Input }], firstDayOfWeek: [{ type: Input }], footerTemplate: [{ type: Input }], markDisabled: [{ type: Input }], maxDate: [{ type: Input }], minDate: [{ type: Input }], navigation: [{ type: Input }], outsideDays: [{ type: Input }], showWeekdays: [{ type: Input }], showWeekNumbers: [{ type: Input }], startDate: [{ type: Input }], navigate: [{ type: Output }], dateSelect: [{ type: Output }], select: [{ type: Output }] }; /** * @fileoverview added by tsickle * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ class NgbDatepickerMonthView { /** * @param {?} i18n */ constructor(i18n) { this.i18n = i18n; this.select = new EventEmitter(); } /** * @param {?} day * @return {?} */ doSelect(day) { if (!day.context.disabled && !day.hidden) { this.select.emit(day.date); } } } NgbDatepickerMonthView.decorators = [ { type: Component, args: [{ selector: 'ngb-datepicker-month-view', host: { 'role': 'grid' }, encapsulation: ViewEncapsulation.None, template: `
{{ i18n.getWeekdayShortName(w) }}
{{ i18n.getWeekNumerals(week.number) }}
`, styles: ["ngb-datepicker-month-view{display:block}.ngb-dp-week-number,.ngb-dp-weekday{line-height:2rem;text-align:center;font-style:italic}.ngb-dp-weekday{color:#5bc0de;color:var(--info)}.ngb-dp-week{border-radius:.25rem;display:-ms-flexbox;display:flex}.ngb-dp-weekdays{border-bottom:1px solid rgba(0,0,0,.125);border-radius:0;background-color:#f8f9fa;background-color:var(--light)}.ngb-dp-day,.ngb-dp-week-number,.ngb-dp-weekday{width:2rem;height:2rem}.ngb-dp-day{cursor:pointer}.ngb-dp-day.disabled,.ngb-dp-day.hidden{cursor:default}.ngb-dp-day[tabindex=\"0\"]{z-index:1}"] }] } ]; /** @nocollapse */ NgbDatepickerMonthView.ctorParameters = () => [ { type: NgbDatepickerI18n } ]; NgbDatepickerMonthView.propDecorators = { dayTemplate: [{ type: Input }], month: [{ type: Input }], showWeekdays: [{ type: Input }], showWeekNumbers: [{ type: Input }], select: [{ type: Output }] }; /** * @fileoverview added by tsickle * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ class NgbDatepickerNavigation { /** * @param {?} i18n */ constructor(i18n) { this.i18n = i18n; this.navigation = NavigationEvent; this.months = []; this.navigate = new EventEmitter(); this.select = new EventEmitter(); } /** * @param {?} event * @return {?} */ onClickPrev(event) { ((/** @type {?} */ (event.currentTarget))).focus(); this.navigate.emit(this.navigation.PREV); } /** * @param {?} event * @return {?} */ onClickNext(event) { ((/** @type {?} */ (event.currentTarget))).focus(); this.navigate.emit(this.navigation.NEXT); } } NgbDatepickerNavigation.decorators = [ { type: Component, args: [{ selector: 'ngb-datepicker-navigation', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, template: `
{{ i18n.getMonthFullName(month.number, month.year) }} {{ i18n.getYearNumerals(month.year) }}
`, styles: ["ngb-datepicker-navigation{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center}.ngb-dp-navigation-chevron{border-style:solid;border-width:.2em .2em 0 0;display:inline-block;width:.75em;height:.75em;margin-left:.25em;margin-right:.15em;-webkit-transform:rotate(-135deg);transform:rotate(-135deg)}.right .ngb-dp-navigation-chevron{-webkit-transform:rotate(45deg);transform:rotate(45deg);margin-left:.15em;margin-right:.25em}.ngb-dp-arrow{display:-ms-flexbox;display:flex;-ms-flex:1 1 auto;flex:1 1 auto;padding-right:0;padding-left:0;margin:0;width:2rem;height:2rem}.ngb-dp-arrow.right{-ms-flex-pack:end;justify-content:flex-end}.ngb-dp-arrow-btn{padding:0 .25rem;margin:0 .5rem;border:none;background-color:transparent;z-index:1}.ngb-dp-arrow-btn:focus{outline-width:1px;outline-style:auto}@media all and (-ms-high-contrast:none),(-ms-high-contrast:active){.ngb-dp-arrow-btn:focus{outline-style:solid}}.ngb-dp-month-name{font-size:larger;height:2rem;line-height:2rem;text-align:center}.ngb-dp-navigation-select{display:-ms-flexbox;display:flex;-ms-flex:1 1 9rem;flex:1 1 9rem}"] }] } ]; /** @nocollapse */ NgbDatepickerNavigation.ctorParameters = () => [ { type: NgbDatepickerI18n } ]; NgbDatepickerNavigation.propDecorators = { date: [{ type: Input }], disabled: [{ type: Input }], months: [{ type: Input }], showSelect: [{ type: Input }], prevDisabled: [{ type: Input }], nextDisabled: [{ type: Input }], selectBoxes: [{ type: Input }], navigate: [{ type: Output }], select: [{ type: Output }] }; /** * @fileoverview added by tsickle * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ /** @type {?} */ const isContainedIn = (/** * @param {?} element * @param {?=} array * @return {?} */ (element, array) => array ? array.some((/** * @param {?} item * @return {?} */ item => item.contains(element))) : false); /** @type {?} */ const matchesSelectorIfAny = (/** * @param {?} element * @param {?=} selector * @return {?} */ (element, selector) => !selector || closest(element, selector) != null); // we'll have to use 'touch' events instead of 'mouse' events on iOS and add a more significant delay // to avoid re-opening when handling (click) on a toggling element // TODO: use proper Angular platform detection when NgbAutoClose becomes a service and we can inject PLATFORM_ID /** @type {?} */ let iOS = false; if (typeof navigator !== 'undefined') { iOS = !!navigator.userAgent && /iPad|iPhone|iPod/.test(navigator.userAgent); } // setting 'ngbAutoClose' synchronously on iOS results in immediate popup closing // when tapping on the triggering element /** @type {?} */ const wrapAsyncForiOS = (/** * @param {?} fn * @return {?} */ fn => iOS ? (/** * @return {?} */ () => setTimeout((/** * @return {?} */ () => fn()), 100)) : fn); /** * @param {?} zone * @param {?} document * @param {?} type * @param {?} close * @param {?} closed$ * @param {?} insideElements * @param {?=} ignoreElements * @param {?=} insideSelector * @return {?} */ function ngbAutoClose(zone, document, type, close, closed$, insideElements, ignoreElements, insideSelector) { // closing on ESC and outside clicks if (type) { zone.runOutsideAngular(wrapAsyncForiOS((/** * @return {?} */ () => { /** @type {?} */ const shouldCloseOnClick = (/** * @param {?} event * @return {?} */ (event) => { /** @type {?} */ const element = (/** @type {?} */ (event.target)); if (event.button === 2 || isContainedIn(element, ignoreElements)) { return false; } if (type === 'inside') { return isContainedIn(element, insideElements) && matchesSelectorIfAny(element, insideSelector); } else if (type === 'outside') { return !isContainedIn(element, insideElements); } else /* if (type === true) */ { return matchesSelectorIfAny(element, insideSelector) || !isContainedIn(element, insideElements); } }); /** @type {?} */ const escapes$ = fromEvent(document, 'keydown') .pipe(takeUntil(closed$), // tslint:disable-next-line:deprecation filter((/** * @param {?} e * @return {?} */ e => e.which === Key.Escape)), tap((/** * @param {?} e * @return {?} */ e => e.preventDefault()))); // we have to pre-calculate 'shouldCloseOnClick' on 'mousedown/touchstart', // because on 'mouseup/touchend' DOM nodes might be detached /** @type {?} */ const mouseDowns$ = fromEvent(document, 'mousedown').pipe(map(shouldCloseOnClick), takeUntil(closed$)); /** @type {?} */ const closeableClicks$ = (/** @type {?} */ (fromEvent(document, 'mouseup') .pipe(withLatestFrom(mouseDowns$), filter((/** * @param {?} __0 * @return {?} */ ([_, shouldClose]) => shouldClose)), delay(0), takeUntil(closed$)))); race([escapes$, closeableClicks$]).subscribe((/** * @return {?} */ () => zone.run(close))); }))); } } /** * @fileoverview added by tsickle * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ /** @type {?} */ const FOCUSABLE_ELEMENTS_SELECTOR = [ 'a[href]', 'button:not([disabled])', 'input:not([disabled]):not([type="hidden"])', 'select:not([disabled])', 'textarea:not([disabled])', '[contenteditable]', '[tabindex]:not([tabindex="-1"])' ].join(', '); /** * Returns first and last focusable elements inside of a given element based on specific CSS selector * @param {?} element * @return {?} */ function getFocusableBoundaryElements(element) { /** @type {?} */ const list = Array.from((/** @type {?} */ (element.querySelectorAll(FOCUSABLE_ELEMENTS_SELECTOR)))) .filter((/** * @param {?} el * @return {?} */ el => el.tabIndex !== -1)); return [list[0], list[list.length - 1]]; } /** * Function that enforces browser focus to be trapped inside a DOM element. * * Works only for clicks inside the element and navigation with 'Tab', ignoring clicks outside of the element * * \@param zone Angular zone * \@param element The element around which focus will be trapped inside * \@param stopFocusTrap$ The observable stream. When completed the focus trap will clean up listeners * and free internal resources * \@param refocusOnClick Put the focus back to the last focused element whenever a click occurs on element (default to * false) * @type {?} */ const ngbFocusTrap = (/** * @param {?} zone * @param {?} element * @param {?} stopFocusTrap$ * @param {?=} refocusOnClick * @return {?} */ (zone, element, stopFocusTrap$, refocusOnClick = false) => { zone.runOutsideAngular((/** * @return {?} */ () => { // last focused element /** @type {?} */ const lastFocusedElement$ = fromEvent(element, 'focusin').pipe(takeUntil(stopFocusTrap$), map((/** * @param {?} e * @return {?} */ e => e.target))); // 'tab' / 'shift+tab' stream fromEvent(element, 'keydown') .pipe(takeUntil(stopFocusTrap$), // tslint:disable:deprecation filter((/** * @param {?} e * @return {?} */ e => e.which === Key.Tab)), // tslint:enable:deprecation withLatestFrom(lastFocusedElement$)) .subscribe((/** * @param {?} __0 * @return {?} */ ([tabEvent, focusedElement]) => { const [first, last] = getFocusableBoundaryElements(element); if ((focusedElement === first || focusedElement === element) && tabEvent.shiftKey) { last.focus(); tabEvent.preventDefault(); } if (focusedElement === last && !tabEvent.shiftKey) { first.focus(); tabEvent.preventDefault(); } })); // inside click if (refocusOnClick) { fromEvent(element, 'click') .pipe(takeUntil(stopFocusTrap$), withLatestFrom(lastFocusedElement$), map((/** * @param {?} arr * @return {?} */ arr => (/** @type {?} */ (arr[1]))))) .subscribe((/** * @param {?} lastFocusedElement * @return {?} */ lastFocusedElement => lastFocusedElement.focus())); } })); }); /** * @fileoverview added by tsickle * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ // previous version: // https://github.com/angular-ui/bootstrap/blob/07c31d0731f7cb068a1932b8e01d2312b796b4ec/src/position/position.js class Positioning { /** * @private * @param {?} element * @return {?} */ getAllStyles(element) { return window.getComputedStyle(element); } /** * @private * @param {?} element * @param {?} prop * @return {?} */ getStyle(element, prop) { return this.getAllStyles(element)[prop]; } /** * @private * @param {?} element * @return {?} */ isStaticPositioned(element) { return (this.getStyle(element, 'position') || 'static') === 'static'; } /** * @private * @param {?} element * @return {?} */ offsetParent(element) { /** @type {?} */ let offsetParentEl = (/** @type {?} */ (element.offsetParent)) || document.documentElement; while (offsetParentEl && offsetParentEl !== document.documentElement && this.isStaticPositioned(offsetParentEl)) { offsetParentEl = (/** @type {?} */ (offsetParentEl.offsetParent)); } return offsetParentEl || document.documentElement; } /** * @param {?} element * @param {?=} round * @return {?} */ position(element, round = true) { /** @type {?} */ let elPosition; /** @type {?} */ let parentOffset = { width: 0, height: 0, top: 0, bottom: 0, left: 0, right: 0 }; if (this.getStyle(element, 'position') === 'fixed') { elPosition = element.getBoundingClientRect(); elPosition = { top: elPosition.top, bottom: elPosition.bottom, left: elPosition.left, right: elPosition.right, height: elPosition.height, width: elPosition.width }; } else { /** @type {?} */ const offsetParentEl = this.offsetParent(element); elPosition = this.offset(element, false); if (offsetParentEl !== document.documentElement) { parentOffset = this.offset(offsetParentEl, false); } parentOffset.top += offsetParentEl.clientTop; parentOffset.left += offsetParentEl.clientLeft; } elPosition.top -= parentOffset.top; elPosition.bottom -= parentOffset.top; elPosition.left -= parentOffset.left; elPosition.right -= parentOffset.left; if (round) { elPosition.top = Math.round(elPosition.top); elPosition.bottom = Math.round(elPosition.bottom); elPosition.left = Math.round(elPosition.left); elPosition.right = Math.round(elPosition.right); } return elPosition; } /** * @param {?} element * @param {?=} round * @return {?} */ offset(element, round = true) { /** @type {?} */ const elBcr = element.getBoundingClientRect(); /** @type {?} */ const viewportOffset = { top: window.pageYOffset - document.documentElement.clientTop, left: window.pageXOffset - document.documentElement.clientLeft }; /** @type {?} */ let elOffset = { height: elBcr.height || element.offsetHeight, width: elBcr.width || element.offsetWidth, top: elBcr.top + viewportOffset.top, bottom: elBcr.bottom + viewportOffset.top, left: elBcr.left + viewportOffset.left, right: elBcr.right + viewportOffset.left }; if (round) { elOffset.height = Math.round(elOffset.height); elOffset.width = Math.round(elOffset.width); elOffset.top = Math.round(elOffset.top); elOffset.bottom = Math.round(elOffset.bottom); elOffset.left = Math.round(elOffset.left); elOffset.right = Math.round(elOffset.right); } return elOffset; } /* Return false if the element to position is outside the viewport */ /** * @param {?} hostElement * @param {?} targetElement * @param {?} placement * @param {?=} appendToBody * @return {?} */ positionElements(hostElement, targetElement, placement, appendToBody) { const [placementPrimary = 'top', placementSecondary = 'center'] = placement.split('-'); /** @type {?} */ const hostElPosition = appendToBody ? this.offset(hostElement, false) : this.position(hostElement, false); /** @type {?} */ const targetElStyles = this.getAllStyles(targetElement); /** @type {?} */ const marginTop = parseFloat(targetElStyles.marginTop); /** @type {?} */ const marginBottom = parseFloat(targetElStyles.marginBottom); /** @type {?} */ const marginLeft = parseFloat(targetElStyles.marginLeft); /** @type {?} */ const marginRight = parseFloat(targetElStyles.marginRight); /** @type {?} */ let topPosition = 0; /** @type {?} */ let leftPosition = 0; switch (placementPrimary) { case 'top': topPosition = (hostElPosition.top - (targetElement.offsetHeight + marginTop + marginBottom)); break; case 'bottom': topPosition = (hostElPosition.top + hostElPosition.height); break; case 'left': leftPosition = (hostElPosition.left - (targetElement.offsetWidth + marginLeft + marginRight)); break; case 'right': leftPosition = (hostElPosition.left + hostElPosition.width); break; } switch (placementSecondary) { case 'top': topPosition = hostElPosition.top; break; case 'bottom': topPosition = hostElPosition.top + hostElPosition.height - targetElement.offsetHeight; break; case 'left': leftPosition = hostElPosition.left; break; case 'right': leftPosition = hostElPosition.left + hostElPosition.width - targetElement.offsetWidth; break; case 'center': if (placementPrimary === 'top' || placementPrimary === 'bottom') { leftPosition = (hostElPosition.left + hostElPosition.width / 2 - targetElement.offsetWidth / 2); } else { topPosition = (hostElPosition.top + hostElPosition.height / 2 - targetElement.offsetHeight / 2); } break; } /// The translate3d/gpu acceleration render a blurry text on chrome, the next line is commented until a browser fix // targetElement.style.transform = `translate3d(${Math.round(leftPosition)}px, ${Math.floor(topPosition)}px, 0px)`; targetElement.style.transform = `translate(${Math.round(leftPosition)}px, ${Math.round(topPosition)}px)`; // Check if the targetElement is inside the viewport /** @type {?} */ const targetElBCR = targetElement.getBoundingClientRect(); /** @type {?} */ const html = document.documentElement; /** @type {?} */ const windowHeight = window.innerHeight || html.clientHeight; /** @type {?} */ const windowWidth = window.innerWidth || html.clientWidth; return targetElBCR.left >= 0 && targetElBCR.top >= 0 && targetElBCR.right <= windowWidth && targetElBCR.bottom <= windowHeight; } } /** @type {?} */ const placementSeparator = /\s+/; /** @type {?} */ const positionService = new Positioning(); /* * Accept the placement array and applies the appropriate placement dependent on the viewport. * Returns the applied placement. * In case of auto placement, placements are selected in order * 'top', 'bottom', 'left', 'right', * 'top-left', 'top-right', * 'bottom-left', 'bottom-right', * 'left-top', 'left-bottom', * 'right-top', 'right-bottom'. * */ /** * @param {?} hostElement * @param {?} targetElement * @param {?} placement * @param {?=} appendToBody * @param {?=} baseClass * @return {?} */ function positionElements(hostElement, targetElement, placement, appendToBody, baseClass) { /** @type {?} */ let placementVals = Array.isArray(placement) ? placement : (/** @type {?} */ (placement.split(placementSeparator))); /** @type {?} */ const allowedPlacements = [ 'top', 'bottom', 'left', 'right', 'top-left', 'top-right', 'bottom-left', 'bottom-right', 'left-top', 'left-bottom', 'right-top', 'right-bottom' ]; /** @type {?} */ const classList = targetElement.classList; /** @type {?} */ const addClassesToTarget = (/** * @param {?} targetPlacement * @return {?} */ (targetPlacement) => { const [primary, secondary] = targetPlacement.split('-'); /** @type {?} */ const classes = []; if (baseClass) { classes.push(`${baseClass}-${primary}`); if (secondary) { classes.push(`${baseClass}-${primary}-${secondary}`); } classes.forEach((/** * @param {?} classname * @return {?} */ (classname) => { classList.add(classname); })); } return classes; }); // Remove old placement classes to avoid issues if (baseClass) { allowedPlacements.forEach((/** * @param {?} placementToRemove * @return {?} */ (placementToRemove) => { classList.remove(`${baseClass}-${placementToRemove}`); })); } // replace auto placement with other placements /** @type {?} */ let hasAuto = placementVals.findIndex((/** * @param {?} val * @return {?} */ val => val === 'auto')); if (hasAuto >= 0) { allowedPlacements.forEach((/** * @param {?} obj * @return {?} */ function (obj) { if (placementVals.find((/** * @param {?} val * @return {?} */ val => val.search('^' + obj) !== -1)) == null) { placementVals.splice(hasAuto++, 1, (/** @type {?} */ (obj))); } })); } // coordinates where to position // Required for transform: /** @type {?} */ const style = targetElement.style; style.position = 'absolute'; style.top = '0'; style.left = '0'; style['will-change'] = 'transform'; /** @type {?} */ let testPlacement; /** @type {?} */ let isInViewport = false; for (testPlacement of placementVals) { /** @type {?} */ let addedClasses = addClassesToTarget(testPlacement); if (positionService.positionElements(hostElement, targetElement, testPlacement, appendToBody)) { isInViewport = true; break; } // Remove the baseClasses for further calculation if (baseClass) { addedClasses.forEach((/** * @param {?} classname * @return {?} */ (classname) => { classList.remove(classname); })); } } if (!isInViewport) { // If nothing match, the first placement is the default one testPlacement = placementVals[0]; addClassesToTarget(testPlacement); positionService.positionElements(hostElement, targetElement, testPlacement, appendToBody); } return testPlacement; } /** * @fileoverview added by tsickle * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ /** * @return {?} */ function NGB_DATEPICKER_PARSER_FORMATTER_FACTORY() { return new NgbDateISOParserFormatter(); } /** * An abstract service for parsing and formatting dates for the * [`NgbInputDatepicker`](#/components/datepicker/api#NgbInputDatepicker) directive. * Converts between the internal `NgbDateStruct` model presentation and a `string` that is displayed in the * input element. * * When user types something in the input this service attempts to parse it into a `NgbDateStruct` object. * And vice versa, when users selects a date in the calendar with the mouse, it must be displayed as a `string` * in the input. * * Default implementation uses the ISO 8601 format, but you can provide another implementation via DI * to use an alternative string format or a custom parsing logic. * * See the [date format overview](#/components/datepicker/overview#date-model) for more details. * @abstract */ class NgbDateParserFormatter { } NgbDateParserFormatter.decorators = [ { type: Injectable, args: [{ providedIn: 'root', useFactory: NGB_DATEPICKER_PARSER_FORMATTER_FACTORY },] } ]; /** @nocollapse */ NgbDateParserFormatter.ngInjectableDef = ɵɵdefineInjectable({ factory: NGB_DATEPICKER_PARSER_FORMATTER_FACTORY, token: NgbDateParserFormatter, providedIn: "root" }); class NgbDateISOParserFormatter extends NgbDateParserFormatter { /** * @param {?} value * @return {?} */ parse(value) { if (value) { /** @type {?} */ const dateParts = value.trim().split('-'); if (dateParts.length === 1 && isNumber(dateParts[0])) { return { year: toInteger(dateParts[0]), month: null, day: null }; } else if (dateParts.length === 2 && isNumber(dateParts[0]) && isNumber(dateParts[1])) { return { year: toInteger(dateParts[0]), month: toInteger(dateParts[1]), day: null }; } else if (dateParts.length === 3 && isNumber(dateParts[0]) && isNumber(dateParts[1]) && isNumber(dateParts[2])) { return { year: toInteger(dateParts[0]), month: toInteger(dateParts[1]), day: toInteger(dateParts[2]) }; } } return null; } /** * @param {?} date * @return {?} */ format(date) { return date ? `${date.year}-${isNumber(date.month) ? padNumber(date.month) : ''}-${isNumber(date.day) ? padNumber(date.day) : ''}` : ''; } } NgbDateISOParserFormatter.decorators = [ { type: Injectable } ]; /** * @fileoverview added by tsickle * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ /** * A configuration service for the [`NgbDatepickerInput`](#/components/datepicker/api#NgbDatepicker) component. * * You can inject this service, typically in your root component, and customize the values of its properties in * order to provide default values for all the datepicker inputs used in the application. * * \@since 5.2.0 */ class NgbInputDatepickerConfig extends NgbDatepickerConfig { constructor() { super(...arguments); this.autoClose = true; this.placement = ['bottom-left', 'bottom-right', 'top-left', 'top-right']; this.restoreFocus = true; } } NgbInputDatepickerConfig.decorators = [ { type: Injectable, args: [{ providedIn: 'root' },] } ]; /** @nocollapse */ NgbInputDatepickerConfig.ngInjectableDef = ɵɵdefineInjectable({ factory: function NgbInputDatepickerConfig_Factory() { return new NgbInputDatepickerConfig(); }, token: NgbInputDatepickerConfig, providedIn: "root" }); /** * @fileoverview added by tsickle * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ /** @type {?} */ const NGB_DATEPICKER_VALUE_ACCESSOR$1 = { provide: NG_VALUE_ACCESSOR, useExisting: forwardRef((/** * @return {?} */ () => NgbInputDatepicker)), multi: true }; /** @type {?} */ const NGB_DATEPICKER_VALIDATOR = { provide: NG_VALIDATORS, useExisting: forwardRef((/** * @return {?} */ () => NgbInputDatepicker)), multi: true }; /** * A directive that allows to stick a datepicker popup to an input field. * * Manages interaction with the input field itself, does value formatting and provides forms integration. */ class NgbInputDatepicker { /** * @param {?} _parserFormatter * @param {?} _elRef * @param {?} _vcRef * @param {?} _renderer * @param {?} _cfr * @param {?} _ngZone * @param {?} _calendar * @param {?} _dateAdapter * @param {?} _document * @param {?} _changeDetector * @param {?} config */ constructor(_parserFormatter, _elRef, _vcRef, _renderer, _cfr, _ngZone, _calendar, _dateAdapter, _document, _changeDetector, config) { this._parserFormatter = _parserFormatter; this._elRef = _elRef; this._vcRef = _vcRef; this._renderer = _renderer; this._cfr = _cfr; this._ngZone = _ngZone; this._calendar = _calendar; this._dateAdapter = _dateAdapter; this._document = _document; this._changeDetector = _changeDetector; this._cRef = null; this._disabled = false; this._elWithFocus = null; /** * An event emitted when user selects a date using keyboard or mouse. * * The payload of the event is currently selected `NgbDate`. * * \@since 1.1.1 */ this.dateSelect = new EventEmitter(); /** * Event emitted right after the navigation happens and displayed month changes. * * See [`NgbDatepickerNavigateEvent`](#/components/datepicker/api#NgbDatepickerNavigateEvent) for the payload info. */ this.navigate = new EventEmitter(); /** * An event fired after closing datepicker window. * * \@since 4.2.0 */ this.closed = new EventEmitter(); this._onChange = (/** * @param {?} _ * @return {?} */ (_) => { }); this._onTouched = (/** * @return {?} */ () => { }); this._validatorChange = (/** * @return {?} */ () => { }); ['autoClose', 'container', 'positionTarget', 'placement'].forEach((/** * @param {?} input * @return {?} */ input => this[input] = config[input])); this._zoneSubscription = _ngZone.onStable.subscribe((/** * @return {?} */ () => this._updatePopupPosition())); } /** * @return {?} */ get disabled() { return this._disabled; } /** * @param {?} value * @return {?} */ set disabled(value) { this._disabled = value === '' || (value && value !== 'false'); if (this.isOpen()) { this._cRef.instance.setDisabledState(this._disabled); } } /** * @param {?} fn * @return {?} */ registerOnChange(fn) { this._onChange = fn; } /** * @param {?} fn * @return {?} */ registerOnTouched(fn) { this._onTouched = fn; } /** * @param {?} fn * @return {?} */ registerOnValidatorChange(fn) { this._validatorChange = fn; } /** * @param {?} isDisabled * @return {?} */ setDisabledState(isDisabled) { this.disabled = isDisabled; } /** * @param {?} c * @return {?} */ validate(c) { /** @type {?} */ const value = c.value; if (value === null || value === undefined) { return null; } /** @type {?} */ const ngbDate = this._fromDateStruct(this._dateAdapter.fromModel(value)); if (!this._calendar.isValid(ngbDate)) { return { 'ngbDate': { invalid: c.value } }; } if (this.minDate && ngbDate.before(NgbDate.from(this.minDate))) { return { 'ngbDate': { requiredBefore: this.minDate } }; } if (this.maxDate && ngbDate.after(NgbDate.from(this.maxDate))) { return { 'ngbDate': { requiredAfter: this.maxDate } }; } } /** * @param {?} value * @return {?} */ writeValue(value) { this._model = this._fromDateStruct(this._dateAdapter.fromModel(value)); this._writeModelValue(this._model); } /** * @param {?} value * @param {?=} updateView * @return {?} */ manualDateChange(value, updateView = false) { /** @type {?} */ const inputValueChanged = value !== this._inputValue; if (inputValueChanged) { this._inputValue = value; this._model = this._fromDateStruct(this._parserFormatter.parse(value)); } if (inputValueChanged || !updateView) { this._onChange(this._model ? this._dateAdapter.toModel(this._model) : (value === '' ? null : value)); } if (updateView && this._model) { this._writeModelValue(this._model); } } /** * @return {?} */ isOpen() { return !!this._cRef; } /** * Opens the datepicker popup. * * If the related form control contains a valid date, the corresponding month will be opened. * @return {?} */ open() { if (!this.isOpen()) { /** @type {?} */ const cf = this._cfr.resolveComponentFactory(NgbDatepicker); this._cRef = this._vcRef.createComponent(cf); this._applyPopupStyling(this._cRef.location.nativeElement); this._applyDatepickerInputs(this._cRef.instance); this._subscribeForDatepickerOutputs(this._cRef.instance); this._cRef.instance.ngOnInit(); this._cRef.instance.writeValue(this._dateAdapter.toModel(this._model)); // date selection event handling this._cRef.instance.registerOnChange((/** * @param {?} selectedDate * @return {?} */ (selectedDate) => { this.writeValue(selectedDate); this._onChange(selectedDate); this._onTouched(); })); this._cRef.changeDetectorRef.detectChanges(); this._cRef.instance.setDisabledState(this.disabled); if (this.container === 'body') { window.document.querySelector(this.container).appendChild(this._cRef.location.nativeElement); } // focus handling this._elWithFocus = this._document.activeElement; ngbFocusTrap(this._ngZone, this._cRef.location.nativeElement, this.closed, true); this._cRef.instance.focus(); ngbAutoClose(this._ngZone, this._document, this.autoClose, (/** * @return {?} */ () => this.close()), this.closed, [], [this._elRef.nativeElement, this._cRef.location.nativeElement]); } } /** * Closes the datepicker popup. * @return {?} */ close() { if (this.isOpen()) { this._vcRef.remove(this._vcRef.indexOf(this._cRef.hostView)); this._cRef = null; this.closed.emit(); this._changeDetector.markForCheck(); // restore focus /** @type {?} */ let elementToFocus = this._elWithFocus; if (isString(this.restoreFocus)) { elementToFocus = this._document.querySelector(this.restoreFocus); } else if (this.restoreFocus !== undefined) { elementToFocus = this.restoreFocus; } // in IE document.activeElement can contain an object without 'focus()' sometimes if (elementToFocus && elementToFocus['focus']) { elementToFocus.focus(); } else { this._document.body.focus(); } } } /** * Toggles the datepicker popup. * @return {?} */ toggle() { if (this.isOpen()) { this.close(); } else { this.open(); } } /** * Navigates to the provided date. * * With the default calendar we use ISO 8601: 'month' is 1=Jan ... 12=Dec. * If nothing or invalid date provided calendar will open current month. * * Use the `[startDate]` input as an alternative. * @param {?=} date * @return {?} */ navigateTo(date) { if (this.isOpen()) { this._cRef.instance.navigateTo(date); } } /** * @return {?} */ onBlur() { this._onTouched(); } /** * @return {?} */ onFocus() { this._elWithFocus = this._elRef.nativeElement; } /** * @param {?} changes * @return {?} */ ngOnChanges(changes) { if (changes['minDate'] || changes['maxDate']) { this._validatorChange(); if (this.isOpen()) { if (changes['minDate']) { this._cRef.instance.minDate = this._dateAdapter.toModel(changes.minDate.currentValue); } if (changes['maxDate']) { this._cRef.instance.maxDate = this._dateAdapter.toModel(changes.maxDate.currentValue); } this._cRef.instance.ngOnChanges(changes); } } } /** * @return {?} */ ngOnDestroy() { this.close(); this._zoneSubscription.unsubscribe(); } /** * @private * @param {?} datepickerInstance * @return {?} */ _applyDatepickerInputs(datepickerInstance) { ['dayTemplate', 'dayTemplateData', 'displayMonths', 'firstDayOfWeek', 'footerTemplate', 'markDisabled', 'minDate', 'maxDate', 'navigation', 'outsideDays', 'showNavigation', 'showWeekdays', 'showWeekNumbers'] .forEach((/** * @param {?} optionName * @return {?} */ (optionName) => { if (this[optionName] !== undefined) { datepickerInstance[optionName] = this[optionName]; } })); datepickerInstance.startDate = this.startDate || this._model; } /** * @private * @param {?} nativeElement * @return {?} */ _applyPopupStyling(nativeElement) { this._renderer.addClass(nativeElement, 'dropdown-menu'); this._renderer.addClass(nativeElement, 'show'); if (this.container === 'body') { this._renderer.addClass(nativeElement, 'ngb-dp-body'); } } /** * @private * @param {?} datepickerInstance * @return {?} */ _subscribeForDatepickerOutputs(datepickerInstance) { datepickerInstance.navigate.subscribe((/** * @param {?} navigateEvent * @return {?} */ navigateEvent => this.navigate.emit(navigateEvent))); datepickerInstance.dateSelect.subscribe((/** * @param {?} date * @return {?} */ date => { this.dateSelect.emit(date); if (this.autoClose === true || this.autoClose === 'inside') { this.close(); } })); } /** * @private * @param {?} model * @return {?} */ _writeModelValue(model) { /** @type {?} */ const value = this._parserFormatter.format(model); this._inputValue = value; this._renderer.setProperty(this._elRef.nativeElement, 'value', value); if (this.isOpen()) { this._cRef.instance.writeValue(this._dateAdapter.toModel(model)); this._onTouched(); } } /** * @private * @param {?} date * @return {?} */ _fromDateStruct(date) { /** @type {?} */ const ngbDate = date ? new NgbDate(date.year, date.month, date.day) : null; return this._calendar.isValid(ngbDate) ? ngbDate : null; } /** * @private * @return {?} */ _updatePopupPosition() { if (!this._cRef) { return; } /** @type {?} */ let hostElement; if (isString(this.positionTarget)) { hostElement = this._document.querySelector(this.positionTarget); } else if (this.positionTarget instanceof HTMLElement) { hostElement = this.positionTarget; } else { hostElement = this._elRef.nativeElement; } if (this.positionTarget && !hostElement) { throw new Error('ngbDatepicker could not find element declared in [positionTarget] to position against.'); } positionElements(hostElement, this._cRef.location.nativeElement, this.placement, this.container === 'body'); } } NgbInputDatepicker.decorators = [ { type: Directive, args: [{ selector: 'input[ngbDatepicker]', exportAs: 'ngbDatepicker', host: { '(input)': 'manualDateChange($event.target.value)', '(change)': 'manualDateChange($event.target.value, true)', '(focus)': 'onFocus()', '(blur)': 'onBlur()', '[disabled]': 'disabled' }, providers: [ NGB_DATEPICKER_VALUE_ACCESSOR$1, NGB_DATEPICKER_VALIDATOR, { provide: NgbDatepickerConfig, useExisting: NgbInputDatepickerConfig } ], },] } ]; /** @nocollapse */ NgbInputDatepicker.ctorParameters = () => [ { type: NgbDateParserFormatter }, { type: ElementRef }, { type: ViewContainerRef }, { type: Renderer2 }, { type: ComponentFactoryResolver }, { type: NgZone }, { type: NgbCalendar }, { type: NgbDateAdapter }, { type: undefined, decorators: [{ type: Inject, args: [DOCUMENT,] }] }, { type: ChangeDetectorRef }, { type: NgbInputDatepickerConfig } ]; NgbInputDatepicker.propDecorators = { autoClose: [{ type: Input }], dayTemplate: [{ type: Input }], dayTemplateData: [{ type: Input }], displayMonths: [{ type: Input }], firstDayOfWeek: [{ type: Input }], footerTemplate: [{ type: Input }], markDisabled: [{ type: Input }], minDate: [{ type: Input }], maxDate: [{ type: Input }], navigation: [{ type: Input }], outsideDays: [{ type: Input }], placement: [{ type: Input }], restoreFocus: [{ type: Input }], showWeekdays: [{ type: Input }], showWeekNumbers: [{ type: Input }], startDate: [{ type: Input }], container: [{ type: Input }], positionTarget: [{ type: Input }], dateSelect: [{ type: Output }], navigate: [{ type: Output }], closed: [{ type: Output }], disabled: [{ type: Input }] }; /** * @fileoverview added by tsickle * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ class NgbDatepickerDayView { /** * @param {?} i18n */ constructor(i18n) { this.i18n = i18n; } /** * @return {?} */ isMuted() { return !this.selected && (this.date.month !== this.currentMonth || this.disabled); } } NgbDatepickerDayView.decorators = [ { type: Component, args: [{ selector: '[ngbDatepickerDayView]', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, host: { 'class': 'btn-light', '[class.bg-primary]': 'selected', '[class.text-white]': 'selected', '[class.text-muted]': 'isMuted()', '[class.outside]': 'isMuted()', '[class.active]': 'focused' }, template: `{{ i18n.getDayNumerals(date) }}`, styles: ["[ngbDatepickerDayView]{text-align:center;width:2rem;height:2rem;line-height:2rem;border-radius:.25rem;background:0 0}[ngbDatepickerDayView].outside{opacity:.5}"] }] } ]; /** @nocollapse */ NgbDatepickerDayView.ctorParameters = () => [ { type: NgbDatepickerI18n } ]; NgbDatepickerDayView.propDecorators = { currentMonth: [{ type: Input }], date: [{ type: Input }], disabled: [{ type: Input }], focused: [{ type: Input }], selected: [{ type: Input }] }; /** * @fileoverview added by tsickle * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ class NgbDatepickerNavigationSelect { /** * @param {?} i18n * @param {?} _renderer */ constructor(i18n, _renderer) { this.i18n = i18n; this._renderer = _renderer; this.select = new EventEmitter(); this._month = -1; this._year = -1; } /** * @param {?} month * @return {?} */ changeMonth(month) { this.select.emit(new NgbDate(this.date.year, toInteger(month), 1)); } /** * @param {?} year * @return {?} */ changeYear(year) { this.select.emit(new NgbDate(toInteger(year), this.date.month, 1)); } /** * @return {?} */ ngAfterViewChecked() { if (this.date) { if (this.date.month !== this._month) { this._month = this.date.month; this._renderer.setProperty(this.monthSelect.nativeElement, 'value', this._month); } if (this.date.year !== this._year) { this._year = this.date.year; this._renderer.setProperty(this.yearSelect.nativeElement, 'value', this._year); } } } } NgbDatepickerNavigationSelect.decorators = [ { type: Component, args: [{ selector: 'ngb-datepicker-navigation-select', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, template: ` `, styles: ["ngb-datepicker-navigation-select>.custom-select{-ms-flex:1 1 auto;flex:1 1 auto;padding:0 .5rem;font-size:.875rem;height:1.85rem}ngb-datepicker-navigation-select>.custom-select:focus{z-index:1}ngb-datepicker-navigation-select>.custom-select::-ms-value{background-color:transparent!important}"] }] } ]; /** @nocollapse */ NgbDatepickerNavigationSelect.ctorParameters = () => [ { type: NgbDatepickerI18n }, { type: Renderer2 } ]; NgbDatepickerNavigationSelect.propDecorators = { date: [{ type: Input }], disabled: [{ type: Input }], months: [{ type: Input }], years: [{ type: Input }], select: [{ type: Output }], monthSelect: [{ type: ViewChild, args: ['month', { static: true, read: ElementRef },] }], yearSelect: [{ type: ViewChild, args: ['year', { static: true, read: ElementRef },] }] }; /** * @fileoverview added by tsickle * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ /** * @abstract */ class NgbCalendarHijri extends NgbCalendar { /** * @return {?} */ getDaysPerWeek() { return 7; } /** * @return {?} */ getMonths() { return [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]; } /** * @return {?} */ getWeeksPerMonth() { return 6; } /** * @param {?} date * @param {?=} period * @param {?=} number * @return {?} */ getNext(date, period = 'd', number = 1) { date = new NgbDate(date.year, date.month, date.day); switch (period) { case 'y': date = this._setYear(date, date.year + number); date.month = 1; date.day = 1; return date; case 'm': date = this._setMonth(date, date.month + number); date.day = 1; return date; case 'd': return this._setDay(date, date.day + number); default: return date; } } /** * @param {?} date * @param {?=} period * @param {?=} number * @return {?} */ getPrev(date, period = 'd', number = 1) { return this.getNext(date, period, -number); } /** * @param {?} date * @return {?} */ getWeekday(date) { /** @type {?} */ const day = this.toGregorian(date).getDay(); // in JS Date Sun=0, in ISO 8601 Sun=7 return day === 0 ? 7 : day; } /** * @param {?} week * @param {?} firstDayOfWeek * @return {?} */ getWeekNumber(week, firstDayOfWeek) { // in JS Date Sun=0, in ISO 8601 Sun=7 if (firstDayOfWeek === 7) { firstDayOfWeek = 0; } /** @type {?} */ const thursdayIndex = (4 + 7 - firstDayOfWeek) % 7; /** @type {?} */ const date = week[thursdayIndex]; /** @type {?} */ const jsDate = this.toGregorian(date); jsDate.setDate(jsDate.getDate() + 4 - (jsDate.getDay() || 7)); // Thursday // Thursday /** @type {?} */ const time = jsDate.getTime(); /** @type {?} */ const MuhDate = this.toGregorian(new NgbDate(date.year, 1, 1)); return Math.floor(Math.round((time - MuhDate.getTime()) / 86400000) / 7) + 1; } /** * @return {?} */ getToday() { return this.fromGregorian(new Date()); } /** * @param {?} date * @return {?} */ isValid(date) { return date && isNumber(date.year) && isNumber(date.month) && isNumber(date.day) && !isNaN(this.toGregorian(date).getTime()); } /** * @private * @param {?} date * @param {?} day * @return {?} */ _setDay(date, day) { day = +day; /** @type {?} */ let mDays = this.getDaysPerMonth(date.month, date.year); if (day <= 0) { while (day <= 0) { date = this._setMonth(date, date.month - 1); mDays = this.getDaysPerMonth(date.month, date.year); day += mDays; } } else if (day > mDays) { while (day > mDays) { day -= mDays; date = this._setMonth(date, date.month + 1); mDays = this.getDaysPerMonth(date.month, date.year); } } date.day = day; return date; } /** * @private * @param {?} date * @param {?} month * @return {?} */ _setMonth(date, month) { month = +month; date.year = date.year + Math.floor((month - 1) / 12); date.month = Math.floor(((month - 1) % 12 + 12) % 12) + 1; return date; } /** * @private * @param {?} date * @param {?} year * @return {?} */ _setYear(date, year) { date.year = +year; return date; } } NgbCalendarHijri.decorators = [ { type: Injectable } ]; /** * @fileoverview added by tsickle * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ /** * Checks if islamic year is a leap year * @param {?} hYear * @return {?} */ function isIslamicLeapYear(hYear) { return (14 + 11 * hYear) % 30 < 11; } /** * Checks if gregorian years is a leap year * @param {?} gDate * @return {?} */ function isGregorianLeapYear(gDate) { /** @type {?} */ const year = gDate.getFullYear(); return year % 4 === 0 && year % 100 !== 0 || year % 400 === 0; } /** * Returns the start of Hijri Month. * `hMonth` is 0 for Muharram, 1 for Safar, etc. * `hYear` is any Hijri hYear. * @param {?} hYear * @param {?} hMonth * @return {?} */ function getIslamicMonthStart(hYear, hMonth) { return Math.ceil(29.5 * hMonth) + (hYear - 1) * 354 + Math.floor((3 + 11 * hYear) / 30.0); } /** * Returns the start of Hijri year. * `year` is any Hijri year. * @param {?} year * @return {?} */ function getIslamicYearStart(year) { return (year - 1) * 354 + Math.floor((3 + 11 * year) / 30.0); } /** * @param {?} a * @param {?} b * @return {?} */ function mod(a, b) { return a - b * Math.floor(a / b); } /** * The civil calendar is one type of Hijri calendars used in islamic countries. * Uses a fixed cycle of alternating 29- and 30-day months, * with a leap day added to the last month of 11 out of every 30 years. * http://cldr.unicode.org/development/development-process/design-proposals/islamic-calendar-types * All the calculations here are based on the equations from "Calendrical Calculations" By Edward M. Reingold, Nachum * Dershowitz. * @type {?} */ const GREGORIAN_EPOCH = 1721425.5; /** @type {?} */ const ISLAMIC_EPOCH = 1948439.5; class NgbCalendarIslamicCivil extends NgbCalendarHijri { /** * Returns the equivalent islamic(civil) date value for a give input Gregorian date. * `gDate` is a JS Date to be converted to Hijri. * @param {?} gDate * @return {?} */ fromGregorian(gDate) { /** @type {?} */ const gYear = gDate.getFullYear(); /** @type {?} */ const gMonth = gDate.getMonth(); /** @type {?} */ const gDay = gDate.getDate(); /** @type {?} */ let julianDay = GREGORIAN_EPOCH - 1 + 365 * (gYear - 1) + Math.floor((gYear - 1) / 4) + -Math.floor((gYear - 1) / 100) + Math.floor((gYear - 1) / 400) + Math.floor((367 * (gMonth + 1) - 362) / 12 + (gMonth + 1 <= 2 ? 0 : isGregorianLeapYear(gDate) ? -1 : -2) + gDay); julianDay = Math.floor(julianDay) + 0.5; /** @type {?} */ const days = julianDay - ISLAMIC_EPOCH; /** @type {?} */ const hYear = Math.floor((30 * days + 10646) / 10631.0); /** @type {?} */ let hMonth = Math.ceil((days - 29 - getIslamicYearStart(hYear)) / 29.5); hMonth = Math.min(hMonth, 11); /** @type {?} */ const hDay = Math.ceil(days - getIslamicMonthStart(hYear, hMonth)) + 1; return new NgbDate(hYear, hMonth + 1, hDay); } /** * Returns the equivalent JS date value for a give input islamic(civil) date. * `hDate` is an islamic(civil) date to be converted to Gregorian. * @param {?} hDate * @return {?} */ toGregorian(hDate) { /** @type {?} */ const hYear = hDate.year; /** @type {?} */ const hMonth = hDate.month - 1; /** @type {?} */ const hDay = hDate.day; /** @type {?} */ const julianDay = hDay + Math.ceil(29.5 * hMonth) + (hYear - 1) * 354 + Math.floor((3 + 11 * hYear) / 30) + ISLAMIC_EPOCH - 1; /** @type {?} */ const wjd = Math.floor(julianDay - 0.5) + 0.5; /** @type {?} */ const depoch = wjd - GREGORIAN_EPOCH; /** @type {?} */ const quadricent = Math.floor(depoch / 146097); /** @type {?} */ const dqc = mod(depoch, 146097); /** @type {?} */ const cent = Math.floor(dqc / 36524); /** @type {?} */ const dcent = mod(dqc, 36524); /** @type {?} */ const quad = Math.floor(dcent / 1461); /** @type {?} */ const dquad = mod(dcent, 1461); /** @type {?} */ const yindex = Math.floor(dquad / 365); /** @type {?} */ let year = quadricent * 400 + cent * 100 + quad * 4 + yindex; if (!(cent === 4 || yindex === 4)) { year++; } /** @type {?} */ const gYearStart = GREGORIAN_EPOCH + 365 * (year - 1) + Math.floor((year - 1) / 4) - Math.floor((year - 1) / 100) + Math.floor((year - 1) / 400); /** @type {?} */ const yearday = wjd - gYearStart; /** @type {?} */ const tjd = GREGORIAN_EPOCH - 1 + 365 * (year - 1) + Math.floor((year - 1) / 4) - Math.floor((year - 1) / 100) + Math.floor((year - 1) / 400) + Math.floor(739 / 12 + (isGregorianLeapYear(new Date(year, 3, 1)) ? -1 : -2) + 1); /** @type {?} */ const leapadj = wjd < tjd ? 0 : isGregorianLeapYear(new Date(year, 3, 1)) ? 1 : 2; /** @type {?} */ const month = Math.floor(((yearday + leapadj) * 12 + 373) / 367); /** @type {?} */ const tjd2 = GREGORIAN_EPOCH - 1 + 365 * (year - 1) + Math.floor((year - 1) / 4) - Math.floor((year - 1) / 100) + Math.floor((year - 1) / 400) + Math.floor((367 * month - 362) / 12 + (month <= 2 ? 0 : isGregorianLeapYear(new Date(year, month - 1, 1)) ? -1 : -2) + 1); /** @type {?} */ const day = wjd - tjd2 + 1; return new Date(year, month - 1, day); } /** * Returns the number of days in a specific Hijri month. * `month` is 1 for Muharram, 2 for Safar, etc. * `year` is any Hijri year. * @param {?} month * @param {?} year * @return {?} */ getDaysPerMonth(month, year) { year = year + Math.floor(month / 13); month = ((month - 1) % 12) + 1; /** @type {?} */ let length = 29 + month % 2; if (month === 12 && isIslamicLeapYear(year)) { length++; } return length; } } NgbCalendarIslamicCivil.decorators = [ { type: Injectable } ]; /** * @fileoverview added by tsickle * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ /** * Umalqura calendar is one type of Hijri calendars used in islamic countries. * This Calendar is used by Saudi Arabia for administrative purpose. * Unlike tabular calendars, the algorithm involves astronomical calculation, but it's still deterministic. * http://cldr.unicode.org/development/development-process/design-proposals/islamic-calendar-types * @type {?} */ const GREGORIAN_FIRST_DATE = new Date(1882, 10, 12); /** @type {?} */ const GREGORIAN_LAST_DATE = new Date(2174, 10, 25); /** @type {?} */ const HIJRI_BEGIN = 1300; /** @type {?} */ const HIJRI_END = 1600; /** @type {?} */ const ONE_DAY = 1000 * 60 * 60 * 24; /** @type {?} */ const MONTH_LENGTH = [ // 1300-1304 '101010101010', '110101010100', '111011001001', '011011010100', '011011101010', // 1305-1309 '001101101100', '101010101101', '010101010101', '011010101001', '011110010010', // 1310-1314 '101110101001', '010111010100', '101011011010', '010101011100', '110100101101', // 1315-1319 '011010010101', '011101001010', '101101010100', '101101101010', '010110101101', // 1320-1324 '010010101110', '101001001111', '010100010111', '011010001011', '011010100101', // 1325-1329 '101011010101', '001011010110', '100101011011', '010010011101', '101001001101', // 1330-1334 '110100100110', '110110010101', '010110101100', '100110110110', '001010111010', // 1335-1339 '101001011011', '010100101011', '101010010101', '011011001010', '101011101001', // 1340-1344 '001011110100', '100101110110', '001010110110', '100101010110', '101011001010', // 1345-1349 '101110100100', '101111010010', '010111011001', '001011011100', '100101101101', // 1350-1354 '010101001101', '101010100101', '101101010010', '101110100101', '010110110100', // 1355-1359 '100110110110', '010101010111', '001010010111', '010101001011', '011010100011', // 1360-1364 '011101010010', '101101100101', '010101101010', '101010101011', '010100101011', // 1365-1369 '110010010101', '110101001010', '110110100101', '010111001010', '101011010110', // 1370-1374 '100101010111', '010010101011', '100101001011', '101010100101', '101101010010', // 1375-1379 '101101101010', '010101110101', '001001110110', '100010110111', '010001011011', // 1380-1384 '010101010101', '010110101001', '010110110100', '100111011010', '010011011101', // 1385-1389 '001001101110', '100100110110', '101010101010', '110101010100', '110110110010', // 1390-1394 '010111010101', '001011011010', '100101011011', '010010101011', '101001010101', // 1395-1399 '101101001001', '101101100100', '101101110001', '010110110100', '101010110101', // 1400-1404 '101001010101', '110100100101', '111010010010', '111011001001', '011011010100', // 1405-1409 '101011101001', '100101101011', '010010101011', '101010010011', '110101001001', // 1410-1414 '110110100100', '110110110010', '101010111001', '010010111010', '101001011011', // 1415-1419 '010100101011', '101010010101', '101100101010', '101101010101', '010101011100', // 1420-1424 '010010111101', '001000111101', '100100011101', '101010010101', '101101001010', // 1425-1429 '101101011010', '010101101101', '001010110110', '100100111011', '010010011011', // 1430-1434 '011001010101', '011010101001', '011101010100', '101101101010', '010101101100', // 1435-1439 '101010101101', '010101010101', '101100101001', '101110010010', '101110101001', // 1440-1444 '010111010100', '101011011010', '010101011010', '101010101011', '010110010101', // 1445-1449 '011101001001', '011101100100', '101110101010', '010110110101', '001010110110', // 1450-1454 '101001010110', '111001001101', '101100100101', '101101010010', '101101101010', // 1455-1459 '010110101101', '001010101110', '100100101111', '010010010111', '011001001011', // 1460-1464 '011010100101', '011010101100', '101011010110', '010101011101', '010010011101', // 1465-1469 '101001001101', '110100010110', '110110010101', '010110101010', '010110110101', // 1470-1474 '001011011010', '100101011011', '010010101101', '010110010101', '011011001010', // 1475-1479 '011011100100', '101011101010', '010011110101', '001010110110', '100101010110', // 1480-1484 '101010101010', '101101010100', '101111010010', '010111011001', '001011101010', // 1485-1489 '100101101101', '010010101101', '101010010101', '101101001010', '101110100101', // 1490-1494 '010110110010', '100110110101', '010011010110', '101010010111', '010101000111', // 1495-1499 '011010010011', '011101001001', '101101010101', '010101101010', '101001101011', // 1500-1504 '010100101011', '101010001011', '110101000110', '110110100011', '010111001010', // 1505-1509 '101011010110', '010011011011', '001001101011', '100101001011', '101010100101', // 1510-1514 '101101010010', '101101101001', '010101110101', '000101110110', '100010110111', // 1515-1519 '001001011011', '010100101011', '010101100101', '010110110100', '100111011010', // 1520-1524 '010011101101', '000101101101', '100010110110', '101010100110', '110101010010', // 1525-1529 '110110101001', '010111010100', '101011011010', '100101011011', '010010101011', // 1530-1534 '011001010011', '011100101001', '011101100010', '101110101001', '010110110010', // 1535-1539 '101010110101', '010101010101', '101100100101', '110110010010', '111011001001', // 1540-1544 '011011010010', '101011101001', '010101101011', '010010101011', '101001010101', // 1545-1549 '110100101001', '110101010100', '110110101010', '100110110101', '010010111010', // 1550-1554 '101000111011', '010010011011', '101001001101', '101010101010', '101011010101', // 1555-1559 '001011011010', '100101011101', '010001011110', '101000101110', '110010011010', // 1560-1564 '110101010101', '011010110010', '011010111001', '010010111010', '101001011101', // 1565-1569 '010100101101', '101010010101', '101101010010', '101110101000', '101110110100', // 1570-1574 '010110111001', '001011011010', '100101011010', '101101001010', '110110100100', // 1575-1579 '111011010001', '011011101000', '101101101010', '010101101101', '010100110101', // 1580-1584 '011010010101', '110101001010', '110110101000', '110111010100', '011011011010', // 1585-1589 '010101011011', '001010011101', '011000101011', '101100010101', '101101001010', // 1590-1594 '101110010101', '010110101010', '101010101110', '100100101110', '110010001111', // 1595-1599 '010100100111', '011010010101', '011010101010', '101011010110', '010101011101', // 1600 '001010011101' ]; /** * @param {?} date1 * @param {?} date2 * @return {?} */ function getDaysDiff(date1, date2) { // Ignores the time part in date1 and date2: /** @type {?} */ const time1 = Date.UTC(date1.getFullYear(), date1.getMonth(), date1.getDate()); /** @type {?} */ const time2 = Date.UTC(date2.getFullYear(), date2.getMonth(), date2.getDate()); /** @type {?} */ const diff = Math.abs(time1 - time2); return Math.round(diff / ONE_DAY); } class NgbCalendarIslamicUmalqura extends NgbCalendarIslamicCivil { /** * Returns the equivalent islamic(Umalqura) date value for a give input Gregorian date. * `gdate` is s JS Date to be converted to Hijri. * @param {?} gDate * @return {?} */ fromGregorian(gDate) { /** @type {?} */ let hDay = 1; /** @type {?} */ let hMonth = 0; /** @type {?} */ let hYear = 1300; /** @type {?} */ let daysDiff = getDaysDiff(gDate, GREGORIAN_FIRST_DATE); if (gDate.getTime() - GREGORIAN_FIRST_DATE.getTime() >= 0 && gDate.getTime() - GREGORIAN_LAST_DATE.getTime() <= 0) { /** @type {?} */ let year = 1300; for (let i = 0; i < MONTH_LENGTH.length; i++, year++) { for (let j = 0; j < 12; j++) { /** @type {?} */ let numOfDays = +MONTH_LENGTH[i][j] + 29; if (daysDiff <= numOfDays) { hDay = daysDiff + 1; if (hDay > numOfDays) { hDay = 1; j++; } if (j > 11) { j = 0; year++; } hMonth = j; hYear = year; return new NgbDate(hYear, hMonth + 1, hDay); } daysDiff = daysDiff - numOfDays; } } } else { return super.fromGregorian(gDate); } } /** * Converts the current Hijri date to Gregorian. * @param {?} hDate * @return {?} */ toGregorian(hDate) { /** @type {?} */ const hYear = hDate.year; /** @type {?} */ const hMonth = hDate.month - 1; /** @type {?} */ const hDay = hDate.day; /** @type {?} */ let gDate = new Date(GREGORIAN_FIRST_DATE); /** @type {?} */ let dayDiff = hDay - 1; if (hYear >= HIJRI_BEGIN && hYear <= HIJRI_END) { for (let y = 0; y < hYear - HIJRI_BEGIN; y++) { for (let m = 0; m < 12; m++) { dayDiff += +MONTH_LENGTH[y][m] + 29; } } for (let m = 0; m < hMonth; m++) { dayDiff += +MONTH_LENGTH[hYear - HIJRI_BEGIN][m] + 29; } gDate.setDate(GREGORIAN_FIRST_DATE.getDate() + dayDiff); } else { gDate = super.toGregorian(hDate); } return gDate; } /** * Returns the number of days in a specific Hijri hMonth. * `hMonth` is 1 for Muharram, 2 for Safar, etc. * `hYear` is any Hijri hYear. * @param {?} hMonth * @param {?} hYear * @return {?} */ getDaysPerMonth(hMonth, hYear) { if (hYear >= HIJRI_BEGIN && hYear <= HIJRI_END) { /** @type {?} */ const pos = hYear - HIJRI_BEGIN; return +MONTH_LENGTH[pos][hMonth - 1] + 29; } return super.getDaysPerMonth(hMonth, hYear); } } NgbCalendarIslamicUmalqura.decorators = [ { type: Injectable } ]; /** * @fileoverview added by tsickle * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ /** * Returns the equivalent JS date value for a give input Jalali date. * `jalaliDate` is an Jalali date to be converted to Gregorian. * @param {?} jalaliDate * @return {?} */ function toGregorian(jalaliDate) { /** @type {?} */ let jdn = jalaliToJulian(jalaliDate.year, jalaliDate.month, jalaliDate.day); /** @type {?} */ let date = julianToGregorian(jdn); date.setHours(6, 30, 3, 200); return date; } /** * Returns the equivalent jalali date value for a give input Gregorian date. * `gdate` is a JS Date to be converted to jalali. * utc to local * @param {?} gdate * @return {?} */ function fromGregorian(gdate) { /** @type {?} */ let g2d = gregorianToJulian(gdate.getFullYear(), gdate.getMonth() + 1, gdate.getDate()); return julianToJalali(g2d); } /** * @param {?} date * @param {?} yearValue * @return {?} */ function setJalaliYear(date, yearValue) { date.year = +yearValue; return date; } /** * @param {?} date * @param {?} month * @return {?} */ function setJalaliMonth(date, month) { month = +month; date.year = date.year + Math.floor((month - 1) / 12); date.month = Math.floor(((month - 1) % 12 + 12) % 12) + 1; return date; } /** * @param {?} date * @param {?} day * @return {?} */ function setJalaliDay(date, day) { /** @type {?} */ let mDays = getDaysPerMonth(date.month, date.year); if (day <= 0) { while (day <= 0) { date = setJalaliMonth(date, date.month - 1); mDays = getDaysPerMonth(date.month, date.year); day += mDays; } } else if (day > mDays) { while (day > mDays) { day -= mDays; date = setJalaliMonth(date, date.month + 1); mDays = getDaysPerMonth(date.month, date.year); } } date.day = day; return date; } /** * @param {?} a * @param {?} b * @return {?} */ function mod$1(a, b) { return a - b * Math.floor(a / b); } /** * @param {?} a * @param {?} b * @return {?} */ function div(a, b) { return Math.trunc(a / b); } /* This function determines if the Jalali (Persian) year is leap (366-day long) or is the common year (365 days), and finds the day in March (Gregorian calendar) of the first day of the Jalali year (jalaliYear). @param jalaliYear Jalali calendar year (-61 to 3177) @return leap: number of years since the last leap year (0 to 4) gYear: Gregorian year of the beginning of Jalali year march: the March day of Farvardin the 1st (1st day of jalaliYear) @see: http://www.astro.uni.torun.pl/~kb/Papers/EMP/PersianC-EMP.htm @see: http://www.fourmilab.ch/documents/calendar/ */ /** * @param {?} jalaliYear * @return {?} */ function jalCal(jalaliYear) { // Jalali years starting the 33-year rule. /** @type {?} */ let breaks = [-61, 9, 38, 199, 426, 686, 756, 818, 1111, 1181, 1210, 1635, 2060, 2097, 2192, 2262, 2324, 2394, 2456, 3178]; /** @type {?} */ const breaksLength = breaks.length; /** @type {?} */ const gYear = jalaliYear + 621; /** @type {?} */ let leapJ = -14; /** @type {?} */ let jp = breaks[0]; if (jalaliYear < jp || jalaliYear >= breaks[breaksLength - 1]) { throw new Error('Invalid Jalali year ' + jalaliYear); } // Find the limiting years for the Jalali year jalaliYear. /** @type {?} */ let jump; for (let i = 1; i < breaksLength; i += 1) { /** @type {?} */ const jm = breaks[i]; jump = jm - jp; if (jalaliYear < jm) { break; } leapJ = leapJ + div(jump, 33) * 8 + div(mod$1(jump, 33), 4); jp = jm; } /** @type {?} */ let n = jalaliYear - jp; // Find the number of leap years from AD 621 to the beginning // of the current Jalali year in the Persian calendar. leapJ = leapJ + div(n, 33) * 8 + div(mod$1(n, 33) + 3, 4); if (mod$1(jump, 33) === 4 && jump - n === 4) { leapJ += 1; } // And the same in the Gregorian calendar (until the year gYear). /** @type {?} */ const leapG = div(gYear, 4) - div((div(gYear, 100) + 1) * 3, 4) - 150; // Determine the Gregorian date of Farvardin the 1st. /** @type {?} */ const march = 20 + leapJ - leapG; // Find how many years have passed since the last leap year. if (jump - n < 6) { n = n - jump + div(jump + 4, 33) * 33; } /** @type {?} */ let leap = mod$1(mod$1(n + 1, 33) - 1, 4); if (leap === -1) { leap = 4; } return { leap: leap, gy: gYear, march: march }; } /* Calculates Gregorian and Julian calendar dates from the Julian Day number (jdn) for the period since jdn=-34839655 (i.e. the year -100100 of both calendars) to some millions years ahead of the present. @param jdn Julian Day number @return gYear: Calendar year (years BC numbered 0, -1, -2, ...) gMonth: Calendar month (1 to 12) gDay: Calendar day of the month M (1 to 28/29/30/31) */ /** * @param {?} julianDayNumber * @return {?} */ function julianToGregorian(julianDayNumber) { /** @type {?} */ let j = 4 * julianDayNumber + 139361631; j = j + div(div(4 * julianDayNumber + 183187720, 146097) * 3, 4) * 4 - 3908; /** @type {?} */ const i = div(mod$1(j, 1461), 4) * 5 + 308; /** @type {?} */ const gDay = div(mod$1(i, 153), 5) + 1; /** @type {?} */ const gMonth = mod$1(div(i, 153), 12) + 1; /** @type {?} */ const gYear = div(j, 1461) - 100100 + div(8 - gMonth, 6); return new Date(gYear, gMonth - 1, gDay); } /* Converts a date of the Jalali calendar to the Julian Day number. @param jy Jalali year (1 to 3100) @param jm Jalali month (1 to 12) @param jd Jalali day (1 to 29/31) @return Julian Day number */ /** * @param {?} gy * @param {?} gm * @param {?} gd * @return {?} */ function gregorianToJulian(gy, gm, gd) { /** @type {?} */ let d = div((gy + div(gm - 8, 6) + 100100) * 1461, 4) + div(153 * mod$1(gm + 9, 12) + 2, 5) + gd - 34840408; d = d - div(div(gy + 100100 + div(gm - 8, 6), 100) * 3, 4) + 752; return d; } /* Converts the Julian Day number to a date in the Jalali calendar. @param julianDayNumber Julian Day number @return jalaliYear: Jalali year (1 to 3100) jalaliMonth: Jalali month (1 to 12) jalaliDay: Jalali day (1 to 29/31) */ /** * @param {?} julianDayNumber * @return {?} */ function julianToJalali(julianDayNumber) { /** @type {?} */ let gy = julianToGregorian(julianDayNumber).getFullYear() // Calculate Gregorian year (gy). ; /** @type {?} */ let jalaliYear = gy - 621; /** @type {?} */ let r = jalCal(jalaliYear); /** @type {?} */ let gregorianDay = gregorianToJulian(gy, 3, r.march); /** @type {?} */ let jalaliDay; /** @type {?} */ let jalaliMonth; /** @type {?} */ let numberOfDays; // Find number of days that passed since 1 Farvardin. numberOfDays = julianDayNumber - gregorianDay; if (numberOfDays >= 0) { if (numberOfDays <= 185) { // The first 6 months. jalaliMonth = 1 + div(numberOfDays, 31); jalaliDay = mod$1(numberOfDays, 31) + 1; return new NgbDate(jalaliYear, jalaliMonth, jalaliDay); } else { // The remaining months. numberOfDays -= 186; } } else { // Previous Jalali year. jalaliYear -= 1; numberOfDays += 179; if (r.leap === 1) { numberOfDays += 1; } } jalaliMonth = 7 + div(numberOfDays, 30); jalaliDay = mod$1(numberOfDays, 30) + 1; return new NgbDate(jalaliYear, jalaliMonth, jalaliDay); } /* Converts a date of the Jalali calendar to the Julian Day number. @param jYear Jalali year (1 to 3100) @param jMonth Jalali month (1 to 12) @param jDay Jalali day (1 to 29/31) @return Julian Day number */ /** * @param {?} jYear * @param {?} jMonth * @param {?} jDay * @return {?} */ function jalaliToJulian(jYear, jMonth, jDay) { /** @type {?} */ let r = jalCal(jYear); return gregorianToJulian(r.gy, 3, r.march) + (jMonth - 1) * 31 - div(jMonth, 7) * (jMonth - 7) + jDay - 1; } /** * Returns the number of days in a specific jalali month. * @param {?} month * @param {?} year * @return {?} */ function getDaysPerMonth(month, year) { if (month <= 6) { return 31; } if (month <= 11) { return 30; } if (jalCal(year).leap === 0) { return 30; } return 29; } /** * @fileoverview added by tsickle * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ class NgbCalendarPersian extends NgbCalendar { /** * @return {?} */ getDaysPerWeek() { return 7; } /** * @return {?} */ getMonths() { return [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]; } /** * @return {?} */ getWeeksPerMonth() { return 6; } /** * @param {?} date * @param {?=} period * @param {?=} number * @return {?} */ getNext(date, period = 'd', number = 1) { date = new NgbDate(date.year, date.month, date.day); switch (period) { case 'y': date = setJalaliYear(date, date.year + number); date.month = 1; date.day = 1; return date; case 'm': date = setJalaliMonth(date, date.month + number); date.day = 1; return date; case 'd': return setJalaliDay(date, date.day + number); default: return date; } } /** * @param {?} date * @param {?=} period * @param {?=} number * @return {?} */ getPrev(date, period = 'd', number = 1) { return this.getNext(date, period, -number); } /** * @param {?} date * @return {?} */ getWeekday(date) { /** @type {?} */ const day = toGregorian(date).getDay(); // in JS Date Sun=0, in ISO 8601 Sun=7 return day === 0 ? 7 : day; } /** * @param {?} week * @param {?} firstDayOfWeek * @return {?} */ getWeekNumber(week, firstDayOfWeek) { // in JS Date Sun=0, in ISO 8601 Sun=7 if (firstDayOfWeek === 7) { firstDayOfWeek = 0; } /** @type {?} */ const thursdayIndex = (4 + 7 - firstDayOfWeek) % 7; /** @type {?} */ const date = week[thursdayIndex]; /** @type {?} */ const jsDate = toGregorian(date); jsDate.setDate(jsDate.getDate() + 4 - (jsDate.getDay() || 7)); // Thursday // Thursday /** @type {?} */ const time = jsDate.getTime(); /** @type {?} */ const startDate = toGregorian(new NgbDate(date.year, 1, 1)); return Math.floor(Math.round((time - startDate.getTime()) / 86400000) / 7) + 1; } /** * @return {?} */ getToday() { return fromGregorian(new Date()); } /** * @param {?} date * @return {?} */ isValid(date) { return date && isInteger(date.year) && isInteger(date.month) && isInteger(date.day) && !isNaN(toGregorian(date).getTime()); } } NgbCalendarPersian.decorators = [ { type: Injectable } ]; /** * @fileoverview added by tsickle * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ /** @type {?} */ const PARTS_PER_HOUR = 1080; /** @type {?} */ const PARTS_PER_DAY = 24 * PARTS_PER_HOUR; /** @type {?} */ const PARTS_FRACTIONAL_MONTH = 12 * PARTS_PER_HOUR + 793; /** @type {?} */ const PARTS_PER_MONTH = 29 * PARTS_PER_DAY + PARTS_FRACTIONAL_MONTH; /** @type {?} */ const BAHARAD = 11 * PARTS_PER_HOUR + 204; /** @type {?} */ const HEBREW_DAY_ON_JAN_1_1970 = 2092591; /** @type {?} */ const GREGORIAN_EPOCH$1 = 1721425.5; /** * @param {?} year * @return {?} */ function isGregorianLeapYear$1(year) { return year % 4 === 0 && year % 100 !== 0 || year % 400 === 0; } /** * @param {?} year * @return {?} */ function numberOfFirstDayInYear(year) { /** @type {?} */ let monthsBeforeYear = Math.floor((235 * year - 234) / 19); /** @type {?} */ let fractionalMonthsBeforeYear = monthsBeforeYear * PARTS_FRACTIONAL_MONTH + BAHARAD; /** @type {?} */ let dayNumber = monthsBeforeYear * 29 + Math.floor(fractionalMonthsBeforeYear / PARTS_PER_DAY); /** @type {?} */ let timeOfDay = fractionalMonthsBeforeYear % PARTS_PER_DAY; /** @type {?} */ let dayOfWeek = dayNumber % 7; if (dayOfWeek === 2 || dayOfWeek === 4 || dayOfWeek === 6) { dayNumber++; dayOfWeek = dayNumber % 7; } if (dayOfWeek === 1 && timeOfDay > 15 * PARTS_PER_HOUR + 204 && !isHebrewLeapYear(year)) { dayNumber += 2; } else if (dayOfWeek === 0 && timeOfDay > 21 * PARTS_PER_HOUR + 589 && isHebrewLeapYear(year - 1)) { dayNumber++; } return dayNumber; } /** * @param {?} month * @param {?} year * @return {?} */ function getDaysInGregorianMonth(month, year) { /** @type {?} */ let days = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]; if (isGregorianLeapYear$1(year)) { days[1]++; } return days[month - 1]; } /** * @param {?} year * @return {?} */ function getHebrewMonths(year) { return isHebrewLeapYear(year) ? 13 : 12; } /** * Returns the number of days in a specific Hebrew year. * `year` is any Hebrew year. * @param {?} year * @return {?} */ function getDaysInHebrewYear(year) { return numberOfFirstDayInYear(year + 1) - numberOfFirstDayInYear(year); } /** * @param {?} year * @return {?} */ function isHebrewLeapYear(year) { /** @type {?} */ let b = (year * 12 + 17) % 19; return b >= ((b < 0) ? -7 : 12); } /** * Returns the number of days in a specific Hebrew month. * `month` is 1 for Nisan, 2 for Iyar etc. Note: Hebrew leap year contains 13 months. * `year` is any Hebrew year. * @param {?} month * @param {?} year * @return {?} */ function getDaysInHebrewMonth(month, year) { /** @type {?} */ let yearLength = numberOfFirstDayInYear(year + 1) - numberOfFirstDayInYear(year); /** @type {?} */ let yearType = (yearLength <= 380 ? yearLength : (yearLength - 30)) - 353; /** @type {?} */ let leapYear = isHebrewLeapYear(year); /** @type {?} */ let daysInMonth = leapYear ? [30, 29, 29, 29, 30, 30, 29, 30, 29, 30, 29, 30, 29] : [30, 29, 29, 29, 30, 29, 30, 29, 30, 29, 30, 29]; if (yearType > 0) { daysInMonth[2]++; // Kislev gets an extra day in normal or complete years. } if (yearType > 1) { daysInMonth[1]++; // Heshvan gets an extra day in complete years only. } return daysInMonth[month - 1]; } /** * @param {?} date * @return {?} */ function getDayNumberInHebrewYear(date) { /** @type {?} */ let numberOfDay = 0; for (let i = 1; i < date.month; i++) { numberOfDay += getDaysInHebrewMonth(i, date.year); } return numberOfDay + date.day; } /** * @param {?} date * @param {?} val * @return {?} */ function setHebrewMonth(date, val) { /** @type {?} */ let after = val >= 0; if (!after) { val = -val; } while (val > 0) { if (after) { if (val > getHebrewMonths(date.year) - date.month) { val -= getHebrewMonths(date.year) - date.month + 1; date.year++; date.month = 1; } else { date.month += val; val = 0; } } else { if (val >= date.month) { date.year--; val -= date.month; date.month = getHebrewMonths(date.year); } else { date.month -= val; val = 0; } } } return date; } /** * @param {?} date * @param {?} val * @return {?} */ function setHebrewDay(date, val) { /** @type {?} */ let after = val >= 0; if (!after) { val = -val; } while (val > 0) { if (after) { if (val > getDaysInHebrewYear(date.year) - getDayNumberInHebrewYear(date)) { val -= getDaysInHebrewYear(date.year) - getDayNumberInHebrewYear(date) + 1; date.year++; date.month = 1; date.day = 1; } else if (val > getDaysInHebrewMonth(date.month, date.year) - date.day) { val -= getDaysInHebrewMonth(date.month, date.year) - date.day + 1; date.month++; date.day = 1; } else { date.day += val; val = 0; } } else { if (val >= date.day) { val -= date.day; date.month--; if (date.month === 0) { date.year--; date.month = getHebrewMonths(date.year); } date.day = getDaysInHebrewMonth(date.month, date.year); } else { date.day -= val; val = 0; } } } return date; } /** * Returns the equivalent Hebrew date value for a give input Gregorian date. * `gdate` is a JS Date to be converted to Hebrew date. * @param {?} gdate * @return {?} */ function fromGregorian$1(gdate) { /** @type {?} */ const date = new Date(gdate); /** @type {?} */ const gYear = date.getFullYear(); /** @type {?} */ const gMonth = date.getMonth(); /** @type {?} */ const gDay = date.getDate(); /** @type {?} */ let julianDay = GREGORIAN_EPOCH$1 - 1 + 365 * (gYear - 1) + Math.floor((gYear - 1) / 4) - Math.floor((gYear - 1) / 100) + Math.floor((gYear - 1) / 400) + Math.floor((367 * (gMonth + 1) - 362) / 12 + (gMonth + 1 <= 2 ? 0 : isGregorianLeapYear$1(gYear) ? -1 : -2) + gDay); julianDay = Math.floor(julianDay + 0.5); /** @type {?} */ let daysSinceHebEpoch = julianDay - 347997; /** @type {?} */ let monthsSinceHebEpoch = Math.floor(daysSinceHebEpoch * PARTS_PER_DAY / PARTS_PER_MONTH); /** @type {?} */ let hYear = Math.floor((monthsSinceHebEpoch * 19 + 234) / 235) + 1; /** @type {?} */ let firstDayOfThisYear = numberOfFirstDayInYear(hYear); /** @type {?} */ let dayOfYear = daysSinceHebEpoch - firstDayOfThisYear; while (dayOfYear < 1) { hYear--; firstDayOfThisYear = numberOfFirstDayInYear(hYear); dayOfYear = daysSinceHebEpoch - firstDayOfThisYear; } /** @type {?} */ let hMonth = 1; /** @type {?} */ let hDay = dayOfYear; while (hDay > getDaysInHebrewMonth(hMonth, hYear)) { hDay -= getDaysInHebrewMonth(hMonth, hYear); hMonth++; } return new NgbDate(hYear, hMonth, hDay); } /** * Returns the equivalent JS date value for a given Hebrew date. * `hebrewDate` is an Hebrew date to be converted to Gregorian. * @param {?} hebrewDate * @return {?} */ function toGregorian$1(hebrewDate) { /** @type {?} */ const hYear = hebrewDate.year; /** @type {?} */ const hMonth = hebrewDate.month; /** @type {?} */ const hDay = hebrewDate.day; /** @type {?} */ let days = numberOfFirstDayInYear(hYear); for (let i = 1; i < hMonth; i++) { days += getDaysInHebrewMonth(i, hYear); } days += hDay; /** @type {?} */ let diffDays = days - HEBREW_DAY_ON_JAN_1_1970; /** @type {?} */ let after = diffDays >= 0; if (!after) { diffDays = -diffDays; } /** @type {?} */ let gYear = 1970; /** @type {?} */ let gMonth = 1; /** @type {?} */ let gDay = 1; while (diffDays > 0) { if (after) { if (diffDays >= (isGregorianLeapYear$1(gYear) ? 366 : 365)) { diffDays -= isGregorianLeapYear$1(gYear) ? 366 : 365; gYear++; } else if (diffDays >= getDaysInGregorianMonth(gMonth, gYear)) { diffDays -= getDaysInGregorianMonth(gMonth, gYear); gMonth++; } else { gDay += diffDays; diffDays = 0; } } else { if (diffDays >= (isGregorianLeapYear$1(gYear - 1) ? 366 : 365)) { diffDays -= isGregorianLeapYear$1(gYear - 1) ? 366 : 365; gYear--; } else { if (gMonth > 1) { gMonth--; } else { gMonth = 12; gYear--; } if (diffDays >= getDaysInGregorianMonth(gMonth, gYear)) { diffDays -= getDaysInGregorianMonth(gMonth, gYear); } else { gDay = getDaysInGregorianMonth(gMonth, gYear) - diffDays + 1; diffDays = 0; } } } } return new Date(gYear, gMonth - 1, gDay); } /** * @param {?} numerals * @return {?} */ function hebrewNumerals(numerals) { if (!numerals) { return ''; } /** @type {?} */ const hArray0_9 = ['', '\u05d0', '\u05d1', '\u05d2', '\u05d3', '\u05d4', '\u05d5', '\u05d6', '\u05d7', '\u05d8']; /** @type {?} */ const hArray10_19 = [ '\u05d9', '\u05d9\u05d0', '\u05d9\u05d1', '\u05d9\u05d2', '\u05d9\u05d3', '\u05d8\u05d5', '\u05d8\u05d6', '\u05d9\u05d6', '\u05d9\u05d7', '\u05d9\u05d8' ]; /** @type {?} */ const hArray20_90 = ['', '', '\u05db', '\u05dc', '\u05de', '\u05e0', '\u05e1', '\u05e2', '\u05e4', '\u05e6']; /** @type {?} */ const hArray100_900 = [ '', '\u05e7', '\u05e8', '\u05e9', '\u05ea', '\u05ea\u05e7', '\u05ea\u05e8', '\u05ea\u05e9', '\u05ea\u05ea', '\u05ea\u05ea\u05e7' ]; /** @type {?} */ const hArray1000_9000 = [ '', '\u05d0', '\u05d1', '\u05d1\u05d0', '\u05d1\u05d1', '\u05d4', '\u05d4\u05d0', '\u05d4\u05d1', '\u05d4\u05d1\u05d0', '\u05d4\u05d1\u05d1' ]; /** @type {?} */ const geresh = '\u05f3'; /** @type {?} */ const gershaim = '\u05f4'; /** @type {?} */ let mem = 0; /** @type {?} */ let result = []; /** @type {?} */ let step = 0; while (numerals > 0) { /** @type {?} */ let m = numerals % 10; if (step === 0) { mem = m; } else if (step === 1) { if (m !== 1) { result.unshift(hArray20_90[m], hArray0_9[mem]); } else { result.unshift(hArray10_19[mem]); } } else if (step === 2) { result.unshift(hArray100_900[m]); } else { if (m !== 5) { result.unshift(hArray1000_9000[m], geresh, ' '); } break; } numerals = Math.floor(numerals / 10); if (step === 0 && numerals === 0) { result.unshift(hArray0_9[m]); } step++; } result = result.join('').split(''); if (result.length === 1) { result.push(geresh); } else if (result.length > 1) { result.splice(result.length - 1, 0, gershaim); } return result.join(''); } /** * @fileoverview added by tsickle * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ /** * \@since 3.2.0 */ class NgbCalendarHebrew extends NgbCalendar { /** * @return {?} */ getDaysPerWeek() { return 7; } /** * @param {?=} year * @return {?} */ getMonths(year) { if (year && isHebrewLeapYear(year)) { return [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]; } else { return [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]; } } /** * @return {?} */ getWeeksPerMonth() { return 6; } /** * @param {?} date * @return {?} */ isValid(date) { /** @type {?} */ let b = date && isNumber(date.year) && isNumber(date.month) && isNumber(date.day); b = b && date.month > 0 && date.month <= (isHebrewLeapYear(date.year) ? 13 : 12); b = b && date.day > 0 && date.day <= getDaysInHebrewMonth(date.month, date.year); return b && !isNaN(toGregorian$1(date).getTime()); } /** * @param {?} date * @param {?=} period * @param {?=} number * @return {?} */ getNext(date, period = 'd', number = 1) { date = new NgbDate(date.year, date.month, date.day); switch (period) { case 'y': date.year += number; date.month = 1; date.day = 1; return date; case 'm': date = setHebrewMonth(date, number); date.day = 1; return date; case 'd': return setHebrewDay(date, number); default: return date; } } /** * @param {?} date * @param {?=} period * @param {?=} number * @return {?} */ getPrev(date, period = 'd', number = 1) { return this.getNext(date, period, -number); } /** * @param {?} date * @return {?} */ getWeekday(date) { /** @type {?} */ const day = toGregorian$1(date).getDay(); // in JS Date Sun=0, in ISO 8601 Sun=7 return day === 0 ? 7 : day; } /** * @param {?} week * @param {?} firstDayOfWeek * @return {?} */ getWeekNumber(week, firstDayOfWeek) { /** @type {?} */ const date = week[week.length - 1]; return Math.ceil(getDayNumberInHebrewYear(date) / 7); } /** * @return {?} */ getToday() { return fromGregorian$1(new Date()); } /** * \@since 3.4.0 * @param {?} date * @return {?} */ toGregorian(date) { return fromJSDate(toGregorian$1(date)); } /** * \@since 3.4.0 * @param {?} date * @return {?} */ fromGregorian(date) { return fromGregorian$1(toJSDate(date)); } } NgbCalendarHebrew.decorators = [ { type: Injectable } ]; /** * @fileoverview added by tsickle * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ /** @type {?} */ const WEEKDAYS = ['שני', 'שלישי', 'רביעי', 'חמישי', 'שישי', 'שבת', 'ראשון']; /** @type {?} */ const MONTHS = ['תשרי', 'חשון', 'כסלו', 'טבת', 'שבט', 'אדר', 'ניסן', 'אייר', 'סיון', 'תמוז', 'אב', 'אלול']; /** @type {?} */ const MONTHS_LEAP = ['תשרי', 'חשון', 'כסלו', 'טבת', 'שבט', 'אדר א׳', 'אדר ב׳', 'ניסן', 'אייר', 'סיון', 'תמוז', 'אב', 'אלול']; /** * \@since 3.2.0 */ class NgbDatepickerI18nHebrew extends NgbDatepickerI18n { /** * @param {?} month * @param {?=} year * @return {?} */ getMonthShortName(month, year) { return this.getMonthFullName(month, year); } /** * @param {?} month * @param {?=} year * @return {?} */ getMonthFullName(month, year) { return isHebrewLeapYear(year) ? MONTHS_LEAP[month - 1] : MONTHS[month - 1]; } /** * @param {?} weekday * @return {?} */ getWeekdayShortName(weekday) { return WEEKDAYS[weekday - 1]; } /** * @param {?} date * @return {?} */ getDayAriaLabel(date) { return `${hebrewNumerals(date.day)} ${this.getMonthFullName(date.month, date.year)} ${hebrewNumerals(date.year)}`; } /** * @param {?} date * @return {?} */ getDayNumerals(date) { return hebrewNumerals(date.day); } /** * @param {?} weekNumber * @return {?} */ getWeekNumerals(weekNumber) { return hebrewNumerals(weekNumber); } /** * @param {?} year * @return {?} */ getYearNumerals(year) { return hebrewNumerals(year); } } NgbDatepickerI18nHebrew.decorators = [ { type: Injectable } ]; /** * @fileoverview added by tsickle * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ /** * [`NgbDateAdapter`](#/components/datepicker/api#NgbDateAdapter) implementation that uses * native javascript dates as a user date model. */ class NgbDateNativeAdapter extends NgbDateAdapter { /** * Converts a native `Date` to a `NgbDateStruct`. * @param {?} date * @return {?} */ fromModel(date) { return (date instanceof Date && !isNaN(date.getTime())) ? this._fromNativeDate(date) : null; } /** * Converts a `NgbDateStruct` to a native `Date`. * @param {?} date * @return {?} */ toModel(date) { return date && isInteger(date.year) && isInteger(date.month) && isInteger(date.day) ? this._toNativeDate(date) : null; } /** * @protected * @param {?} date * @return {?} */ _fromNativeDate(date) { return { year: date.getFullYear(), month: date.getMonth() + 1, day: date.getDate() }; } /** * @protected * @param {?} date * @return {?} */ _toNativeDate(date) { /** @type {?} */ const jsDate = new Date(date.year, date.month - 1, date.day, 12); // avoid 30 -> 1930 conversion jsDate.setFullYear(date.year); return jsDate; } } NgbDateNativeAdapter.decorators = [ { type: Injectable } ]; /** * @fileoverview added by tsickle * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ /** * Same as [`NgbDateNativeAdapter`](#/components/datepicker/api#NgbDateNativeAdapter), but with UTC dates. * * \@since 3.2.0 */ class NgbDateNativeUTCAdapter extends NgbDateNativeAdapter { /** * @protected * @param {?} date * @return {?} */ _fromNativeDate(date) { return { year: date.getUTCFullYear(), month: date.getUTCMonth() + 1, day: date.getUTCDate() }; } /** * @protected * @param {?} date * @return {?} */ _toNativeDate(date) { /** @type {?} */ const jsDate = new Date(Date.UTC(date.year, date.month - 1, date.day)); // avoid 30 -> 1930 conversion jsDate.setUTCFullYear(date.year); return jsDate; } } NgbDateNativeUTCAdapter.decorators = [ { type: Injectable } ]; /** * @fileoverview added by tsickle * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ class NgbDatepickerModule { } NgbDatepickerModule.decorators = [ { type: NgModule, args: [{ declarations: [ NgbDatepicker, NgbDatepickerMonthView, NgbDatepickerNavigation, NgbDatepickerNavigationSelect, NgbDatepickerDayView, NgbInputDatepicker ], exports: [NgbDatepicker, NgbInputDatepicker], imports: [CommonModule, FormsModule], entryComponents: [NgbDatepicker] },] } ]; /** * @fileoverview added by tsickle * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ /** * A configuration service for the [`NgbDropdown`](#/components/dropdown/api#NgbDropdown) component. * * You can inject this service, typically in your root component, and customize the values of its properties in * order to provide default values for all the dropdowns used in the application. */ class NgbDropdownConfig { constructor() { this.autoClose = true; this.placement = ['bottom-left', 'bottom-right', 'top-left', 'top-right']; } } NgbDropdownConfig.decorators = [ { type: Injectable, args: [{ providedIn: 'root' },] } ]; /** @nocollapse */ NgbDropdownConfig.ngInjectableDef = ɵɵdefineInjectable({ factory: function NgbDropdownConfig_Factory() { return new NgbDropdownConfig(); }, token: NgbDropdownConfig, providedIn: "root" }); /** * @fileoverview added by tsickle * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ class NgbNavbar { } NgbNavbar.decorators = [ { type: Directive, args: [{ selector: '.navbar' },] } ]; /** * A directive you should put on a dropdown item to enable keyboard navigation. * Arrow keys will move focus between items marked with this directive. * * \@since 4.1.0 */ class NgbDropdownItem { /** * @param {?} elementRef */ constructor(elementRef) { this.elementRef = elementRef; this._disabled = false; } /** * @param {?} value * @return {?} */ set disabled(value) { this._disabled = (/** @type {?} */ (value)) === '' || value === true; // accept an empty attribute as true } /** * @return {?} */ get disabled() { return this._disabled; } } NgbDropdownItem.decorators = [ { type: Directive, args: [{ selector: '[ngbDropdownItem]', host: { 'class': 'dropdown-item', '[class.disabled]': 'disabled' } },] } ]; /** @nocollapse */ NgbDropdownItem.ctorParameters = () => [ { type: ElementRef } ]; NgbDropdownItem.propDecorators = { disabled: [{ type: Input }] }; /** * A directive that wraps dropdown menu content and dropdown items. */ class NgbDropdownMenu { /** * @param {?} dropdown */ constructor(dropdown) { this.dropdown = dropdown; this.placement = 'bottom'; this.isOpen = false; } } NgbDropdownMenu.decorators = [ { type: Directive, args: [{ selector: '[ngbDropdownMenu]', host: { '[class.dropdown-menu]': 'true', '[class.show]': 'dropdown.isOpen()', '[attr.x-placement]': 'placement', '(keydown.ArrowUp)': 'dropdown.onKeyDown($event)', '(keydown.ArrowDown)': 'dropdown.onKeyDown($event)', '(keydown.Home)': 'dropdown.onKeyDown($event)', '(keydown.End)': 'dropdown.onKeyDown($event)', '(keydown.Enter)': 'dropdown.onKeyDown($event)', '(keydown.Space)': 'dropdown.onKeyDown($event)' } },] } ]; /** @nocollapse */ NgbDropdownMenu.ctorParameters = () => [ { type: undefined, decorators: [{ type: Inject, args: [forwardRef((/** * @return {?} */ () => NgbDropdown)),] }] } ]; NgbDropdownMenu.propDecorators = { menuItems: [{ type: ContentChildren, args: [NgbDropdownItem,] }] }; /** * A directive to mark an element to which dropdown menu will be anchored. * * This is a simple version of the `NgbDropdownToggle` directive. * It plays the same role, but doesn't listen to click events to toggle dropdown menu thus enabling support * for events other than click. * * \@since 1.1.0 */ class NgbDropdownAnchor { /** * @param {?} dropdown * @param {?} _elementRef */ constructor(dropdown, _elementRef) { this.dropdown = dropdown; this._elementRef = _elementRef; this.anchorEl = _elementRef.nativeElement; } /** * @return {?} */ getNativeElement() { return this._elementRef.nativeElement; } } NgbDropdownAnchor.decorators = [ { type: Directive, args: [{ selector: '[ngbDropdownAnchor]', host: { 'class': 'dropdown-toggle', 'aria-haspopup': 'true', '[attr.aria-expanded]': 'dropdown.isOpen()' } },] } ]; /** @nocollapse */ NgbDropdownAnchor.ctorParameters = () => [ { type: undefined, decorators: [{ type: Inject, args: [forwardRef((/** * @return {?} */ () => NgbDropdown)),] }] }, { type: ElementRef } ]; /** * A directive to mark an element that will toggle dropdown via the `click` event. * * You can also use `NgbDropdownAnchor` as an alternative. */ class NgbDropdownToggle extends NgbDropdownAnchor { /** * @param {?} dropdown * @param {?} elementRef */ constructor(dropdown, elementRef) { super(dropdown, elementRef); } } NgbDropdownToggle.decorators = [ { type: Directive, args: [{ selector: '[ngbDropdownToggle]', host: { 'class': 'dropdown-toggle', 'aria-haspopup': 'true', '[attr.aria-expanded]': 'dropdown.isOpen()', '(click)': 'dropdown.toggle()', '(keydown.ArrowUp)': 'dropdown.onKeyDown($event)', '(keydown.ArrowDown)': 'dropdown.onKeyDown($event)', '(keydown.Home)': 'dropdown.onKeyDown($event)', '(keydown.End)': 'dropdown.onKeyDown($event)' }, providers: [{ provide: NgbDropdownAnchor, useExisting: forwardRef((/** * @return {?} */ () => NgbDropdownToggle)) }] },] } ]; /** @nocollapse */ NgbDropdownToggle.ctorParameters = () => [ { type: undefined, decorators: [{ type: Inject, args: [forwardRef((/** * @return {?} */ () => NgbDropdown)),] }] }, { type: ElementRef } ]; /** * A directive that provides contextual overlays for displaying lists of links and more. */ class NgbDropdown { /** * @param {?} _changeDetector * @param {?} config * @param {?} _document * @param {?} _ngZone * @param {?} _elementRef * @param {?} _renderer * @param {?} ngbNavbar */ constructor(_changeDetector, config, _document, _ngZone, _elementRef, _renderer, ngbNavbar) { this._changeDetector = _changeDetector; this._document = _document; this._ngZone = _ngZone; this._elementRef = _elementRef; this._renderer = _renderer; this._closed$ = new Subject(); /** * Defines whether or not the dropdown menu is opened initially. */ this._open = false; /** * An event fired when the dropdown is opened or closed. * * The event payload is a `boolean`: * * `true` - the dropdown was opened * * `false` - the dropdown was closed */ this.openChange = new EventEmitter(); this.placement = config.placement; this.container = config.container; this.autoClose = config.autoClose; this.display = ngbNavbar ? 'static' : 'dynamic'; this._zoneSubscription = _ngZone.onStable.subscribe((/** * @return {?} */ () => { this._positionMenu(); })); } /** * @return {?} */ ngAfterContentInit() { this._ngZone.onStable.pipe(take(1)).subscribe((/** * @return {?} */ () => { this._applyPlacementClasses(); if (this._open) { this._setCloseHandlers(); } })); } /** * @param {?} changes * @return {?} */ ngOnChanges(changes) { if (changes.container && this._open) { this._applyContainer(this.container); } if (changes.placement && !changes.placement.isFirstChange) { this._applyPlacementClasses(); } } /** * Checks if the dropdown menu is open. * @return {?} */ isOpen() { return this._open; } /** * Opens the dropdown menu. * @return {?} */ open() { if (!this._open) { this._open = true; this._applyContainer(this.container); this.openChange.emit(true); this._setCloseHandlers(); } } /** * @private * @return {?} */ _setCloseHandlers() { /** @type {?} */ const anchor = this._anchor; ngbAutoClose(this._ngZone, this._document, this.autoClose, (/** * @return {?} */ () => this.close()), this._closed$, this._menu ? [this._menuElement.nativeElement] : [], anchor ? [anchor.getNativeElement()] : [], '.dropdown-item,.dropdown-divider'); } /** * Closes the dropdown menu. * @return {?} */ close() { if (this._open) { this._open = false; this._resetContainer(); this._closed$.next(); this.openChange.emit(false); this._changeDetector.markForCheck(); } } /** * Toggles the dropdown menu. * @return {?} */ toggle() { if (this.isOpen()) { this.close(); } else { this.open(); } } /** * @return {?} */ ngOnDestroy() { this._resetContainer(); this._closed$.next(); this._zoneSubscription.unsubscribe(); } /** * @param {?} event * @return {?} */ onKeyDown(event) { // tslint:disable-next-line:deprecation /** @type {?} */ const key = event.which; /** @type {?} */ const itemElements = this._getMenuElements(); /** @type {?} */ let position = -1; /** @type {?} */ let isEventFromItems = false; /** @type {?} */ let itemElement = null; /** @type {?} */ const isEventFromToggle = this._isEventFromToggle(event); if (!isEventFromToggle && itemElements.length) { itemElements.forEach((/** * @param {?} item * @param {?} index * @return {?} */ (item, index) => { if (item.contains((/** @type {?} */ (event.target)))) { isEventFromItems = true; itemElement = item; } if (item === this._document.activeElement) { position = index; } })); } // closing on Enter / Space if (key === Key.Space || key === Key.Enter) { if (isEventFromItems && (this.autoClose === true || this.autoClose === 'inside')) { // Item is either a button or a link, so click will be triggered by the browser on Enter or Space. // So we have to register a one-time click handler that will fire after any user defined click handlers // to close the dropdown fromEvent(itemElement, 'click').pipe(take(1)).subscribe((/** * @return {?} */ () => this.close())); } return; } // opening / navigating if (isEventFromToggle || isEventFromItems) { this.open(); if (itemElements.length) { switch (key) { case Key.ArrowDown: position = Math.min(position + 1, itemElements.length - 1); break; case Key.ArrowUp: if (this._isDropup() && position === -1) { position = itemElements.length - 1; break; } position = Math.max(position - 1, 0); break; case Key.Home: position = 0; break; case Key.End: position = itemElements.length - 1; break; } itemElements[position].focus(); } event.preventDefault(); } } /** * @private * @return {?} */ _isDropup() { return this._elementRef.nativeElement.classList.contains('dropup'); } /** * @private * @param {?} event * @return {?} */ _isEventFromToggle(event) { return this._anchor.getNativeElement().contains((/** @type {?} */ (event.target))); } /** * @private * @return {?} */ _getMenuElements() { /** @type {?} */ const menu = this._menu; if (menu == null) { return []; } return menu.menuItems.filter((/** * @param {?} item * @return {?} */ item => !item.disabled)).map((/** * @param {?} item * @return {?} */ item => item.elementRef.nativeElement)); } /** * @private * @return {?} */ _positionMenu() { /** @type {?} */ const menu = this._menu; if (this.isOpen() && menu) { this._applyPlacementClasses(this.display === 'dynamic' ? positionElements(this._anchor.anchorEl, this._bodyContainer || this._menuElement.nativeElement, this.placement, this.container === 'body') : this._getFirstPlacement(this.placement)); } } /** * @private * @param {?} placement * @return {?} */ _getFirstPlacement(placement) { return Array.isArray(placement) ? placement[0] : (/** @type {?} */ (placement.split(' ')[0])); } /** * @private * @return {?} */ _resetContainer() { /** @type {?} */ const renderer = this._renderer; /** @type {?} */ const menuElement = this._menuElement; if (menuElement) { /** @type {?} */ const dropdownElement = this._elementRef.nativeElement; /** @type {?} */ const dropdownMenuElement = menuElement.nativeElement; renderer.appendChild(dropdownElement, dropdownMenuElement); renderer.removeStyle(dropdownMenuElement, 'position'); renderer.removeStyle(dropdownMenuElement, 'transform'); } if (this._bodyContainer) { renderer.removeChild(this._document.body, this._bodyContainer); this._bodyContainer = null; } } /** * @private * @param {?=} container * @return {?} */ _applyContainer(container = null) { this._resetContainer(); if (container === 'body') { /** @type {?} */ const renderer = this._renderer; /** @type {?} */ const dropdownMenuElement = this._menuElement.nativeElement; /** @type {?} */ const bodyContainer = this._bodyContainer = this._bodyContainer || renderer.createElement('div'); // Override some styles to have the positionning working renderer.setStyle(bodyContainer, 'position', 'absolute'); renderer.setStyle(dropdownMenuElement, 'position', 'static'); renderer.setStyle(bodyContainer, 'z-index', '1050'); renderer.appendChild(bodyContainer, dropdownMenuElement); renderer.appendChild(this._document.body, bodyContainer); } } /** * @private * @param {?=} placement * @return {?} */ _applyPlacementClasses(placement) { /** @type {?} */ const menu = this._menu; if (menu) { if (!placement) { placement = this._getFirstPlacement(this.placement); } /** @type {?} */ const renderer = this._renderer; /** @type {?} */ const dropdownElement = this._elementRef.nativeElement; // remove the current placement classes renderer.removeClass(dropdownElement, 'dropup'); renderer.removeClass(dropdownElement, 'dropdown'); menu.placement = this.display === 'static' ? null : placement; /* * apply the new placement * in case of top use up-arrow or down-arrow otherwise */ /** @type {?} */ const dropdownClass = placement.search('^top') !== -1 ? 'dropup' : 'dropdown'; renderer.addClass(dropdownElement, dropdownClass); /** @type {?} */ const bodyContainer = this._bodyContainer; if (bodyContainer) { renderer.removeClass(bodyContainer, 'dropup'); renderer.removeClass(bodyContainer, 'dropdown'); renderer.addClass(bodyContainer, dropdownClass); } } } } NgbDropdown.decorators = [ { type: Directive, args: [{ selector: '[ngbDropdown]', exportAs: 'ngbDropdown', host: { '[class.show]': 'isOpen()' } },] } ]; /** @nocollapse */ NgbDropdown.ctorParameters = () => [ { type: ChangeDetectorRef }, { type: NgbDropdownConfig }, { type: undefined, decorators: [{ type: Inject, args: [DOCUMENT,] }] }, { type: NgZone }, { type: ElementRef }, { type: Renderer2 }, { type: NgbNavbar, decorators: [{ type: Optional }] } ]; NgbDropdown.propDecorators = { _menu: [{ type: ContentChild, args: [NgbDropdownMenu, { static: false },] }], _menuElement: [{ type: ContentChild, args: [NgbDropdownMenu, { read: ElementRef, static: false },] }], _anchor: [{ type: ContentChild, args: [NgbDropdownAnchor, { static: false },] }], autoClose: [{ type: Input }], _open: [{ type: Input, args: ['open',] }], placement: [{ type: Input }], container: [{ type: Input }], display: [{ type: Input }], openChange: [{ type: Output }] }; /** * @fileoverview added by tsickle * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ /** @type {?} */ const NGB_DROPDOWN_DIRECTIVES = [NgbDropdown, NgbDropdownAnchor, NgbDropdownToggle, NgbDropdownMenu, NgbDropdownItem, NgbNavbar]; class NgbDropdownModule { } NgbDropdownModule.decorators = [ { type: NgModule, args: [{ declarations: NGB_DROPDOWN_DIRECTIVES, exports: NGB_DROPDOWN_DIRECTIVES },] } ]; /** * @fileoverview added by tsickle * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ /** * A configuration service for the [`NgbModal`](#/components/modal/api#NgbModal) service. * * You can inject this service, typically in your root component, and customize the values of its properties in * order to provide default values for all modals used in the application. * * \@since 3.1.0 */ class NgbModalConfig { constructor() { this.backdrop = true; this.keyboard = true; } } NgbModalConfig.decorators = [ { type: Injectable, args: [{ providedIn: 'root' },] } ]; /** @nocollapse */ NgbModalConfig.ngInjectableDef = ɵɵdefineInjectable({ factory: function NgbModalConfig_Factory() { return new NgbModalConfig(); }, token: NgbModalConfig, providedIn: "root" }); /** * @fileoverview added by tsickle * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ class ContentRef { /** * @param {?} nodes * @param {?=} viewRef * @param {?=} componentRef */ constructor(nodes, viewRef, componentRef) { this.nodes = nodes; this.viewRef = viewRef; this.componentRef = componentRef; } } /** * @template T */ class PopupService { /** * @param {?} _type * @param {?} _injector * @param {?} _viewContainerRef * @param {?} _renderer * @param {?} _componentFactoryResolver * @param {?} _applicationRef */ constructor(_type, _injector, _viewContainerRef, _renderer, _componentFactoryResolver, _applicationRef) { this._type = _type; this._injector = _injector; this._viewContainerRef = _viewContainerRef; this._renderer = _renderer; this._componentFactoryResolver = _componentFactoryResolver; this._applicationRef = _applicationRef; } /** * @param {?=} content * @param {?=} context * @return {?} */ open(content, context) { if (!this._windowRef) { this._contentRef = this._getContentRef(content, context); this._windowRef = this._viewContainerRef.createComponent(this._componentFactoryResolver.resolveComponentFactory(this._type), 0, this._injector, this._contentRef.nodes); } return this._windowRef; } /** * @return {?} */ close() { if (this._windowRef) { this._viewContainerRef.remove(this._viewContainerRef.indexOf(this._windowRef.hostView)); this._windowRef = null; if (this._contentRef.viewRef) { this._applicationRef.detachView(this._contentRef.viewRef); this._contentRef.viewRef.destroy(); this._contentRef = null; } } } /** * @private * @param {?} content * @param {?=} context * @return {?} */ _getContentRef(content, context) { if (!content) { return new ContentRef([]); } else if (content instanceof TemplateRef) { /** @type {?} */ const viewRef = content.createEmbeddedView(context); this._applicationRef.attachView(viewRef); return new ContentRef([viewRef.rootNodes], viewRef); } else { return new ContentRef([[this._renderer.createText(`${content}`)]]); } } } /** * @fileoverview added by tsickle * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ /** @type {?} */ const noop = (/** * @return {?} */ () => { }); /** * Utility to handle the scrollbar. * * It allows to compensate the lack of a vertical scrollbar by adding an * equivalent padding on the right of the body, and to remove this compensation. */ class ScrollBar { /** * @param {?} _document */ constructor(_document) { this._document = _document; } /** * To be called right before a potential vertical scrollbar would be removed: * * - if there was a scrollbar, adds some compensation padding to the body * to keep the same layout as when the scrollbar is there * - if there was none, there is nothing to do * * @return {?} a callback used to revert the compensation (noop if there was none, * otherwise a function removing the padding) */ compensate() { /** @type {?} */ const width = this._getWidth(); return !this._isPresent(width) ? noop : this._adjustBody(width); } /** * Adds a padding of the given width on the right of the body. * * @private * @param {?} scrollbarWidth * @return {?} a callback used to revert the padding to its previous value */ _adjustBody(scrollbarWidth) { /** @type {?} */ const body = this._document.body; /** @type {?} */ const userSetPaddingStyle = body.style.paddingRight; /** @type {?} */ const actualPadding = parseFloat(window.getComputedStyle(body)['padding-right']); body.style['padding-right'] = `${actualPadding + scrollbarWidth}px`; return (/** * @return {?} */ () => body.style['padding-right'] = userSetPaddingStyle); } /** * Tells whether a scrollbar is currently present on the body. * * @private * @param {?} scrollbarWidth * @return {?} true if scrollbar is present, false otherwise */ _isPresent(scrollbarWidth) { /** @type {?} */ const rect = this._document.body.getBoundingClientRect(); /** @type {?} */ const bodyToViewportGap = window.innerWidth - (rect.left + rect.right); /** @type {?} */ const uncertainty = 0.1 * scrollbarWidth; return bodyToViewportGap >= scrollbarWidth - uncertainty; } /** * Calculates and returns the width of a scrollbar. * * @private * @return {?} the width of a scrollbar on this page */ _getWidth() { /** @type {?} */ const measurer = this._document.createElement('div'); measurer.className = 'modal-scrollbar-measure'; /** @type {?} */ const body = this._document.body; body.appendChild(measurer); /** @type {?} */ const width = measurer.getBoundingClientRect().width - measurer.clientWidth; body.removeChild(measurer); return width; } } ScrollBar.decorators = [ { type: Injectable, args: [{ providedIn: 'root' },] } ]; /** @nocollapse */ ScrollBar.ctorParameters = () => [ { type: undefined, decorators: [{ type: Inject, args: [DOCUMENT,] }] } ]; /** @nocollapse */ ScrollBar.ngInjectableDef = ɵɵdefineInjectable({ factory: function ScrollBar_Factory() { return new ScrollBar(ɵɵinject(DOCUMENT)); }, token: ScrollBar, providedIn: "root" }); /** * @fileoverview added by tsickle * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ class NgbModalBackdrop { } NgbModalBackdrop.decorators = [ { type: Component, args: [{ selector: 'ngb-modal-backdrop', encapsulation: ViewEncapsulation.None, template: '', host: { '[class]': '"modal-backdrop fade show" + (backdropClass ? " " + backdropClass : "")', 'style': 'z-index: 1050' } }] } ]; NgbModalBackdrop.propDecorators = { backdropClass: [{ type: Input }] }; /** * @fileoverview added by tsickle * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ /** * A reference to the currently opened (active) modal. * * Instances of this class can be injected into your component passed as modal content. * So you can `.close()` or `.dismiss()` the modal window from your component. */ class NgbActiveModal { /** * Closes the modal with an optional `result` value. * * The `NgbMobalRef.result` promise will be resolved with the provided value. * @param {?=} result * @return {?} */ close(result) { } /** * Dismisses the modal with an optional `reason` value. * * The `NgbModalRef.result` promise will be rejected with the provided value. * @param {?=} reason * @return {?} */ dismiss(reason) { } } /** * A reference to the newly opened modal returned by the `NgbModal.open()` method. */ class NgbModalRef { /** * @param {?} _windowCmptRef * @param {?} _contentRef * @param {?=} _backdropCmptRef * @param {?=} _beforeDismiss */ constructor(_windowCmptRef, _contentRef, _backdropCmptRef, _beforeDismiss) { this._windowCmptRef = _windowCmptRef; this._contentRef = _contentRef; this._backdropCmptRef = _backdropCmptRef; this._beforeDismiss = _beforeDismiss; _windowCmptRef.instance.dismissEvent.subscribe((/** * @param {?} reason * @return {?} */ (reason) => { this.dismiss(reason); })); this.result = new Promise((/** * @param {?} resolve * @param {?} reject * @return {?} */ (resolve, reject) => { this._resolve = resolve; this._reject = reject; })); this.result.then(null, (/** * @return {?} */ () => { })); } /** * The instance of a component used for the modal content. * * When a `TemplateRef` is used as the content or when the modal is closed, will return `undefined`. * @return {?} */ get componentInstance() { if (this._contentRef && this._contentRef.componentRef) { return this._contentRef.componentRef.instance; } } /** * Closes the modal with an optional `result` value. * * The `NgbMobalRef.result` promise will be resolved with the provided value. * @param {?=} result * @return {?} */ close(result) { if (this._windowCmptRef) { this._resolve(result); this._removeModalElements(); } } /** * @private * @param {?=} reason * @return {?} */ _dismiss(reason) { this._reject(reason); this._removeModalElements(); } /** * Dismisses the modal with an optional `reason` value. * * The `NgbModalRef.result` promise will be rejected with the provided value. * @param {?=} reason * @return {?} */ dismiss(reason) { if (this._windowCmptRef) { if (!this._beforeDismiss) { this._dismiss(reason); } else { /** @type {?} */ const dismiss = this._beforeDismiss(); if (dismiss && dismiss.then) { dismiss.then((/** * @param {?} result * @return {?} */ result => { if (result !== false) { this._dismiss(reason); } }), (/** * @return {?} */ () => { })); } else if (dismiss !== false) { this._dismiss(reason); } } } } /** * @private * @return {?} */ _removeModalElements() { /** @type {?} */ const windowNativeEl = this._windowCmptRef.location.nativeElement; windowNativeEl.parentNode.removeChild(windowNativeEl); this._windowCmptRef.destroy(); if (this._backdropCmptRef) { /** @type {?} */ const backdropNativeEl = this._backdropCmptRef.location.nativeElement; backdropNativeEl.parentNode.removeChild(backdropNativeEl); this._backdropCmptRef.destroy(); } if (this._contentRef && this._contentRef.viewRef) { this._contentRef.viewRef.destroy(); } this._windowCmptRef = null; this._backdropCmptRef = null; this._contentRef = null; } } /** * @fileoverview added by tsickle * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ /** @enum {number} */ const ModalDismissReasons = { BACKDROP_CLICK: 0, ESC: 1, }; ModalDismissReasons[ModalDismissReasons.BACKDROP_CLICK] = 'BACKDROP_CLICK'; ModalDismissReasons[ModalDismissReasons.ESC] = 'ESC'; /** * @fileoverview added by tsickle * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ class NgbModalWindow { /** * @param {?} _document * @param {?} _elRef * @param {?} _zone */ constructor(_document, _elRef, _zone) { this._document = _document; this._elRef = _elRef; this._zone = _zone; this._closed$ = new Subject(); this.backdrop = true; this.keyboard = true; this.dismissEvent = new EventEmitter(); } /** * @param {?} reason * @return {?} */ dismiss(reason) { this.dismissEvent.emit(reason); } /** * @return {?} */ ngOnInit() { this._elWithFocus = this._document.activeElement; } /** * @return {?} */ ngAfterViewInit() { const { nativeElement } = this._elRef; this._zone.runOutsideAngular((/** * @return {?} */ () => { fromEvent(nativeElement, 'keydown') .pipe(takeUntil(this._closed$), // tslint:disable-next-line:deprecation filter((/** * @param {?} e * @return {?} */ e => e.which === Key.Escape && this.keyboard))) .subscribe((/** * @param {?} event * @return {?} */ event => requestAnimationFrame((/** * @return {?} */ () => { if (!event.defaultPrevented) { this._zone.run((/** * @return {?} */ () => this.dismiss(ModalDismissReasons.ESC))); } })))); // We're listening to 'mousedown' and 'mouseup' to prevent modal from closing when pressing the mouse // inside the modal dialog and releasing it outside /** @type {?} */ let preventClose = false; fromEvent(this._dialogEl.nativeElement, 'mousedown') .pipe(takeUntil(this._closed$), tap((/** * @return {?} */ () => preventClose = false)), switchMap((/** * @return {?} */ () => fromEvent(nativeElement, 'mouseup').pipe(takeUntil(this._closed$), take(1)))), filter((/** * @param {?} __0 * @return {?} */ ({ target }) => nativeElement === target))) .subscribe((/** * @return {?} */ () => { preventClose = true; })); // We're listening to 'click' to dismiss modal on modal window click, except when: // 1. clicking on modal dialog itself // 2. closing was prevented by mousedown/up handlers // 3. clicking on scrollbar when the viewport is too small and modal doesn't fit (click is not triggered at all) fromEvent(nativeElement, 'click').pipe(takeUntil(this._closed$)).subscribe((/** * @param {?} __0 * @return {?} */ ({ target }) => { if (this.backdrop === true && nativeElement === target && !preventClose) { this._zone.run((/** * @return {?} */ () => this.dismiss(ModalDismissReasons.BACKDROP_CLICK))); } preventClose = false; })); })); if (!nativeElement.contains(document.activeElement)) { /** @type {?} */ const autoFocusable = (/** @type {?} */ (nativeElement.querySelector(`[ngbAutofocus]`))); /** @type {?} */ const firstFocusable = getFocusableBoundaryElements(nativeElement)[0]; /** @type {?} */ const elementToFocus = autoFocusable || firstFocusable || nativeElement; elementToFocus.focus(); } } /** * @return {?} */ ngOnDestroy() { /** @type {?} */ const body = this._document.body; /** @type {?} */ const elWithFocus = this._elWithFocus; /** @type {?} */ let elementToFocus; if (elWithFocus && elWithFocus['focus'] && body.contains(elWithFocus)) { elementToFocus = elWithFocus; } else { elementToFocus = body; } this._zone.runOutsideAngular((/** * @return {?} */ () => { setTimeout((/** * @return {?} */ () => elementToFocus.focus())); this._elWithFocus = null; })); this._closed$.next(); } } NgbModalWindow.decorators = [ { type: Component, args: [{ selector: 'ngb-modal-window', host: { '[class]': '"modal fade show d-block" + (windowClass ? " " + windowClass : "")', 'role': 'dialog', 'tabindex': '-1', '[attr.aria-modal]': 'true', '[attr.aria-labelledby]': 'ariaLabelledBy', }, template: `
`, encapsulation: ViewEncapsulation.None, styles: ["ngb-modal-window .component-host-scrollable{display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;overflow:hidden}"] }] } ]; /** @nocollapse */ NgbModalWindow.ctorParameters = () => [ { type: undefined, decorators: [{ type: Inject, args: [DOCUMENT,] }] }, { type: ElementRef }, { type: NgZone } ]; NgbModalWindow.propDecorators = { _dialogEl: [{ type: ViewChild, args: ['dialog', { static: true },] }], ariaLabelledBy: [{ type: Input }], backdrop: [{ type: Input }], centered: [{ type: Input }], keyboard: [{ type: Input }], scrollable: [{ type: Input }], size: [{ type: Input }], windowClass: [{ type: Input }], dismissEvent: [{ type: Output, args: ['dismiss',] }] }; /** * @fileoverview added by tsickle * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ class NgbModalStack { /** * @param {?} _applicationRef * @param {?} _injector * @param {?} _document * @param {?} _scrollBar * @param {?} _rendererFactory * @param {?} _ngZone */ constructor(_applicationRef, _injector, _document, _scrollBar, _rendererFactory, _ngZone) { this._applicationRef = _applicationRef; this._injector = _injector; this._document = _document; this._scrollBar = _scrollBar; this._rendererFactory = _rendererFactory; this._ngZone = _ngZone; this._activeWindowCmptHasChanged = new Subject(); this._ariaHiddenValues = new Map(); this._backdropAttributes = ['backdropClass']; this._modalRefs = []; this._windowAttributes = ['ariaLabelledBy', 'backdrop', 'centered', 'keyboard', 'scrollable', 'size', 'windowClass']; this._windowCmpts = []; // Trap focus on active WindowCmpt this._activeWindowCmptHasChanged.subscribe((/** * @return {?} */ () => { if (this._windowCmpts.length) { /** @type {?} */ const activeWindowCmpt = this._windowCmpts[this._windowCmpts.length - 1]; ngbFocusTrap(this._ngZone, activeWindowCmpt.location.nativeElement, this._activeWindowCmptHasChanged); this._revertAriaHidden(); this._setAriaHidden(activeWindowCmpt.location.nativeElement); } })); } /** * @param {?} moduleCFR * @param {?} contentInjector * @param {?} content * @param {?} options * @return {?} */ open(moduleCFR, contentInjector, content, options) { /** @type {?} */ const containerEl = isDefined(options.container) ? this._document.querySelector(options.container) : this._document.body; /** @type {?} */ const renderer = this._rendererFactory.createRenderer(null, null); /** @type {?} */ const revertPaddingForScrollBar = this._scrollBar.compensate(); /** @type {?} */ const removeBodyClass = (/** * @return {?} */ () => { if (!this._modalRefs.length) { renderer.removeClass(this._document.body, 'modal-open'); this._revertAriaHidden(); } }); if (!containerEl) { throw new Error(`The specified modal container "${options.container || 'body'}" was not found in the DOM.`); } /** @type {?} */ const activeModal = new NgbActiveModal(); /** @type {?} */ const contentRef = this._getContentRef(moduleCFR, options.injector || contentInjector, content, activeModal, options); /** @type {?} */ let backdropCmptRef = options.backdrop !== false ? this._attachBackdrop(moduleCFR, containerEl) : null; /** @type {?} */ let windowCmptRef = this._attachWindowComponent(moduleCFR, containerEl, contentRef); /** @type {?} */ let ngbModalRef = new NgbModalRef(windowCmptRef, contentRef, backdropCmptRef, options.beforeDismiss); this._registerModalRef(ngbModalRef); this._registerWindowCmpt(windowCmptRef); ngbModalRef.result.then(revertPaddingForScrollBar, revertPaddingForScrollBar); ngbModalRef.result.then(removeBodyClass, removeBodyClass); activeModal.close = (/** * @param {?} result * @return {?} */ (result) => { ngbModalRef.close(result); }); activeModal.dismiss = (/** * @param {?} reason * @return {?} */ (reason) => { ngbModalRef.dismiss(reason); }); this._applyWindowOptions(windowCmptRef.instance, options); if (this._modalRefs.length === 1) { renderer.addClass(this._document.body, 'modal-open'); } if (backdropCmptRef && backdropCmptRef.instance) { this._applyBackdropOptions(backdropCmptRef.instance, options); } return ngbModalRef; } /** * @param {?=} reason * @return {?} */ dismissAll(reason) { this._modalRefs.forEach((/** * @param {?} ngbModalRef * @return {?} */ ngbModalRef => ngbModalRef.dismiss(reason))); } /** * @return {?} */ hasOpenModals() { return this._modalRefs.length > 0; } /** * @private * @param {?} moduleCFR * @param {?} containerEl * @return {?} */ _attachBackdrop(moduleCFR, containerEl) { /** @type {?} */ let backdropFactory = moduleCFR.resolveComponentFactory(NgbModalBackdrop); /** @type {?} */ let backdropCmptRef = backdropFactory.create(this._injector); this._applicationRef.attachView(backdropCmptRef.hostView); containerEl.appendChild(backdropCmptRef.location.nativeElement); return backdropCmptRef; } /** * @private * @param {?} moduleCFR * @param {?} containerEl * @param {?} contentRef * @return {?} */ _attachWindowComponent(moduleCFR, containerEl, contentRef) { /** @type {?} */ let windowFactory = moduleCFR.resolveComponentFactory(NgbModalWindow); /** @type {?} */ let windowCmptRef = windowFactory.create(this._injector, contentRef.nodes); this._applicationRef.attachView(windowCmptRef.hostView); containerEl.appendChild(windowCmptRef.location.nativeElement); return windowCmptRef; } /** * @private * @param {?} windowInstance * @param {?} options * @return {?} */ _applyWindowOptions(windowInstance, options) { this._windowAttributes.forEach((/** * @param {?} optionName * @return {?} */ (optionName) => { if (isDefined(options[optionName])) { windowInstance[optionName] = options[optionName]; } })); } /** * @private * @param {?} backdropInstance * @param {?} options * @return {?} */ _applyBackdropOptions(backdropInstance, options) { this._backdropAttributes.forEach((/** * @param {?} optionName * @return {?} */ (optionName) => { if (isDefined(options[optionName])) { backdropInstance[optionName] = options[optionName]; } })); } /** * @private * @param {?} moduleCFR * @param {?} contentInjector * @param {?} content * @param {?} activeModal * @param {?} options * @return {?} */ _getContentRef(moduleCFR, contentInjector, content, activeModal, options) { if (!content) { return new ContentRef([]); } else if (content instanceof TemplateRef) { return this._createFromTemplateRef(content, activeModal); } else if (isString(content)) { return this._createFromString(content); } else { return this._createFromComponent(moduleCFR, contentInjector, content, activeModal, options); } } /** * @private * @param {?} content * @param {?} activeModal * @return {?} */ _createFromTemplateRef(content, activeModal) { /** @type {?} */ const context = { $implicit: activeModal, /** * @param {?} result * @return {?} */ close(result) { activeModal.close(result); }, /** * @param {?} reason * @return {?} */ dismiss(reason) { activeModal.dismiss(reason); } }; /** @type {?} */ const viewRef = content.createEmbeddedView(context); this._applicationRef.attachView(viewRef); return new ContentRef([viewRef.rootNodes], viewRef); } /** * @private * @param {?} content * @return {?} */ _createFromString(content) { /** @type {?} */ const component = this._document.createTextNode(`${content}`); return new ContentRef([[component]]); } /** * @private * @param {?} moduleCFR * @param {?} contentInjector * @param {?} content * @param {?} context * @param {?} options * @return {?} */ _createFromComponent(moduleCFR, contentInjector, content, context, options) { /** @type {?} */ const contentCmptFactory = moduleCFR.resolveComponentFactory(content); /** @type {?} */ const modalContentInjector = Injector.create({ providers: [{ provide: NgbActiveModal, useValue: context }], parent: contentInjector }); /** @type {?} */ const componentRef = contentCmptFactory.create(modalContentInjector); /** @type {?} */ const componentNativeEl = componentRef.location.nativeElement; if (options.scrollable) { ((/** @type {?} */ (componentNativeEl))).classList.add('component-host-scrollable'); } this._applicationRef.attachView(componentRef.hostView); // FIXME: we should here get rid of the component nativeElement // and use `[Array.from(componentNativeEl.childNodes)]` instead and remove the above CSS class. return new ContentRef([[componentNativeEl]], componentRef.hostView, componentRef); } /** * @private * @param {?} element * @return {?} */ _setAriaHidden(element) { /** @type {?} */ const parent = element.parentElement; if (parent && element !== this._document.body) { Array.from(parent.children).forEach((/** * @param {?} sibling * @return {?} */ sibling => { if (sibling !== element && sibling.nodeName !== 'SCRIPT') { this._ariaHiddenValues.set(sibling, sibling.getAttribute('aria-hidden')); sibling.setAttribute('aria-hidden', 'true'); } })); this._setAriaHidden(parent); } } /** * @private * @return {?} */ _revertAriaHidden() { this._ariaHiddenValues.forEach((/** * @param {?} value * @param {?} element * @return {?} */ (value, element) => { if (value) { element.setAttribute('aria-hidden', value); } else { element.removeAttribute('aria-hidden'); } })); this._ariaHiddenValues.clear(); } /** * @private * @param {?} ngbModalRef * @return {?} */ _registerModalRef(ngbModalRef) { /** @type {?} */ const unregisterModalRef = (/** * @return {?} */ () => { /** @type {?} */ const index = this._modalRefs.indexOf(ngbModalRef); if (index > -1) { this._modalRefs.splice(index, 1); } }); this._modalRefs.push(ngbModalRef); ngbModalRef.result.then(unregisterModalRef, unregisterModalRef); } /** * @private * @param {?} ngbWindowCmpt * @return {?} */ _registerWindowCmpt(ngbWindowCmpt) { this._windowCmpts.push(ngbWindowCmpt); this._activeWindowCmptHasChanged.next(); ngbWindowCmpt.onDestroy((/** * @return {?} */ () => { /** @type {?} */ const index = this._windowCmpts.indexOf(ngbWindowCmpt); if (index > -1) { this._windowCmpts.splice(index, 1); this._activeWindowCmptHasChanged.next(); } })); } } NgbModalStack.decorators = [ { type: Injectable, args: [{ providedIn: 'root' },] } ]; /** @nocollapse */ NgbModalStack.ctorParameters = () => [ { type: ApplicationRef }, { type: Injector }, { type: undefined, decorators: [{ type: Inject, args: [DOCUMENT,] }] }, { type: ScrollBar }, { type: RendererFactory2 }, { type: NgZone } ]; /** @nocollapse */ NgbModalStack.ngInjectableDef = ɵɵdefineInjectable({ factory: function NgbModalStack_Factory() { return new NgbModalStack(ɵɵinject(ApplicationRef), ɵɵinject(INJECTOR), ɵɵinject(DOCUMENT), ɵɵinject(ScrollBar), ɵɵinject(RendererFactory2), ɵɵinject(NgZone)); }, token: NgbModalStack, providedIn: "root" }); /** * @fileoverview added by tsickle * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ /** * A service for opening modal windows. * * Creating a modal is straightforward: create a component or a template and pass it as an argument to * the `.open()` method. */ class NgbModal { /** * @param {?} _moduleCFR * @param {?} _injector * @param {?} _modalStack * @param {?} _config */ constructor(_moduleCFR, _injector, _modalStack, _config) { this._moduleCFR = _moduleCFR; this._injector = _injector; this._modalStack = _modalStack; this._config = _config; } /** * Opens a new modal window with the specified content and supplied options. * * Content can be provided as a `TemplateRef` or a component type. If you pass a component type as content, * then instances of those components can be injected with an instance of the `NgbActiveModal` class. You can then * use `NgbActiveModal` methods to close / dismiss modals from "inside" of your component. * * Also see the [`NgbModalOptions`](#/components/modal/api#NgbModalOptions) for the list of supported options. * @param {?} content * @param {?=} options * @return {?} */ open(content, options = {}) { /** @type {?} */ const combinedOptions = Object.assign({}, this._config, options); return this._modalStack.open(this._moduleCFR, this._injector, content, combinedOptions); } /** * Dismisses all currently displayed modal windows with the supplied reason. * * \@since 3.1.0 * @param {?=} reason * @return {?} */ dismissAll(reason) { this._modalStack.dismissAll(reason); } /** * Indicates if there are currently any open modal windows in the application. * * \@since 3.3.0 * @return {?} */ hasOpenModals() { return this._modalStack.hasOpenModals(); } } NgbModal.decorators = [ { type: Injectable, args: [{ providedIn: 'root' },] } ]; /** @nocollapse */ NgbModal.ctorParameters = () => [ { type: ComponentFactoryResolver }, { type: Injector }, { type: NgbModalStack }, { type: NgbModalConfig } ]; /** @nocollapse */ NgbModal.ngInjectableDef = ɵɵdefineInjectable({ factory: function NgbModal_Factory() { return new NgbModal(ɵɵinject(ComponentFactoryResolver), ɵɵinject(INJECTOR), ɵɵinject(NgbModalStack), ɵɵinject(NgbModalConfig)); }, token: NgbModal, providedIn: "root" }); /** * @fileoverview added by tsickle * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ class NgbModalModule { } NgbModalModule.decorators = [ { type: NgModule, args: [{ declarations: [NgbModalBackdrop, NgbModalWindow], entryComponents: [NgbModalBackdrop, NgbModalWindow], providers: [NgbModal] },] } ]; /** * @fileoverview added by tsickle * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ /** * A configuration service for the [`NgbNav`](#/components/nav/api#NgbNav) component. * * You can inject this service, typically in your root component, and customize the values of its properties in * order to provide default values for all the navs used in the application. * * \@since 5.2.0 */ class NgbNavConfig { constructor() { this.destroyOnHide = true; this.orientation = 'horizontal'; this.roles = 'tablist'; } } NgbNavConfig.decorators = [ { type: Injectable, args: [{ providedIn: 'root' },] } ]; /** @nocollapse */ NgbNavConfig.ngInjectableDef = ɵɵdefineInjectable({ factory: function NgbNavConfig_Factory() { return new NgbNavConfig(); }, token: NgbNavConfig, providedIn: "root" }); /** * @fileoverview added by tsickle * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ /** @type {?} */ const isValidNavId = (/** * @param {?} id * @return {?} */ (id) => isDefined(id) && id !== ''); /** @type {?} */ let navCounter = 0; /** * This directive must be used to wrap content to be displayed in the nav. * * \@since 5.2.0 */ class NgbNavContent { /** * @param {?} templateRef */ constructor(templateRef) { this.templateRef = templateRef; } } NgbNavContent.decorators = [ { type: Directive, args: [{ selector: 'ng-template[ngbNavContent]' },] } ]; /** @nocollapse */ NgbNavContent.ctorParameters = () => [ { type: TemplateRef } ]; /** * The directive used to group nav link and related nav content. As well as set nav identifier and some options. * * \@since 5.2.0 */ class NgbNavItem { /** * @param {?} nav * @param {?} elementRef */ constructor(nav, elementRef) { this.elementRef = elementRef; /** * If `true`, the current nav item is disabled and can't be toggled by user. * * Nevertheless disabled nav can be selected programmatically via the `.select()` method and the `[activeId]` binding. */ this.disabled = false; // TODO: cf https://github.com/angular/angular/issues/30106 this._nav = nav; } /** * @return {?} */ ngAfterContentChecked() { // We are using @ContentChildren instead of @ContentChild as in the Angular version being used // only @ContentChildren allows us to specify the {descendants: false} option. // Without {descendants: false} we are hitting bugs described in: // https://github.com/ng-bootstrap/ng-bootstrap/issues/2240 this.contentTpl = this.contentTpls.first; } /** * @return {?} */ ngOnInit() { if (!isDefined(this.domId)) { this.domId = `ngb-nav-${navCounter++}`; } } /** * @return {?} */ get active() { return this._nav.activeId === this.id; } /** * @return {?} */ get id() { return isValidNavId(this._id) ? this._id : this.domId; } /** * @return {?} */ get panelDomId() { return `${this.domId}-panel`; } /** * @return {?} */ isPanelInDom() { return (isDefined(this.destroyOnHide) ? !this.destroyOnHide : !this._nav.destroyOnHide) || this.active; } } NgbNavItem.decorators = [ { type: Directive, args: [{ selector: '[ngbNavItem]', exportAs: 'ngbNavItem', host: { '[class.nav-item]': 'true' } },] } ]; /** @nocollapse */ NgbNavItem.ctorParameters = () => [ { type: undefined, decorators: [{ type: Inject, args: [forwardRef((/** * @return {?} */ () => NgbNav)),] }] }, { type: ElementRef } ]; NgbNavItem.propDecorators = { destroyOnHide: [{ type: Input }], disabled: [{ type: Input }], domId: [{ type: Input }], _id: [{ type: Input, args: ['ngbNavItem',] }], contentTpls: [{ type: ContentChildren, args: [NgbNavContent, { descendants: false },] }] }; /** * A nav directive that helps with implementing tabbed navigation components. * * \@since 5.2.0 */ class NgbNav { /** * @param {?} role * @param {?} config * @param {?} _cd */ constructor(role, config, _cd) { this.role = role; this._cd = _cd; /** * The event emitted after the active nav changes * The payload of the event is the newly active nav id * * If you want to prevent nav change, you should use `(navChange)` event */ this.activeIdChange = new EventEmitter(); /** * The nav change event emitted right before the nav change happens on user click. * * This event won't be emitted if nav is changed programmatically via `[activeId]` or `.select()`. * * See [`NgbNavChangeEvent`](#/components/nav/api#NgbNavChangeEvent) for payload details. */ this.navChange = new EventEmitter(); this.destroyOnHide = config.destroyOnHide; this.orientation = config.orientation; this.roles = config.roles; } /** * @param {?} item * @return {?} */ click(item) { if (!item.disabled) { this._updateActiveId(item.id); } } /** * Selects the nav with the given id and shows its associated pane. * Any other nav that was previously selected becomes unselected and its associated pane is hidden. * @param {?} id * @return {?} */ select(id) { this._updateActiveId(id, false); } /** * @return {?} */ ngAfterContentInit() { if (!isDefined(this.activeId)) { /** @type {?} */ const nextId = this.items.first ? this.items.first.id : null; if (isValidNavId(nextId)) { this._updateActiveId(nextId, false); this._cd.detectChanges(); } } } /** * @private * @param {?} nextId * @param {?=} emitNavChange * @return {?} */ _updateActiveId(nextId, emitNavChange = true) { if (this.activeId !== nextId) { /** @type {?} */ let defaultPrevented = false; if (emitNavChange) { this.navChange.emit({ activeId: this.activeId, nextId, preventDefault: (/** * @return {?} */ () => { defaultPrevented = true; }) }); } if (!defaultPrevented) { this.activeId = nextId; this.activeIdChange.emit(nextId); } } } } NgbNav.decorators = [ { type: Directive, args: [{ selector: '[ngbNav]', exportAs: 'ngbNav', host: { '[class.nav]': 'true', '[class.flex-column]': `orientation === 'vertical'`, '[attr.aria-orientation]': `orientation === 'vertical' && roles === 'tablist' ? 'vertical' : undefined`, '[attr.role]': `role ? role : roles ? 'tablist' : undefined`, } },] } ]; /** @nocollapse */ NgbNav.ctorParameters = () => [ { type: String, decorators: [{ type: Attribute, args: ['role',] }] }, { type: NgbNavConfig }, { type: ChangeDetectorRef } ]; NgbNav.propDecorators = { activeId: [{ type: Input }], activeIdChange: [{ type: Output }], destroyOnHide: [{ type: Input }], orientation: [{ type: Input }], roles: [{ type: Input }], items: [{ type: ContentChildren, args: [NgbNavItem,] }], navChange: [{ type: Output }] }; /** * A directive to put on the nav link. * * \@since 5.2.0 */ class NgbNavLink { /** * @param {?} role * @param {?} navItem * @param {?} nav */ constructor(role, navItem, nav) { this.role = role; this.navItem = navItem; this.nav = nav; } /** * @return {?} */ hasNavItemClass() { // with alternative markup we have to add `.nav-item` class, because `ngbNavItem` is on the ng-container return this.navItem.elementRef.nativeElement.nodeType === Node.COMMENT_NODE; } } NgbNavLink.decorators = [ { type: Directive, args: [{ selector: 'a[ngbNavLink]', host: { '[id]': 'navItem.domId', '[class.nav-link]': 'true', '[class.nav-item]': 'hasNavItemClass()', '[attr.role]': `role ? role : nav.roles ? 'tab' : undefined`, 'href': '', '[class.active]': 'navItem.active', '[class.disabled]': 'navItem.disabled', '[attr.tabindex]': 'navItem.disabled ? -1 : undefined', '[attr.aria-controls]': 'navItem.isPanelInDom() ? navItem.panelDomId : null', '[attr.aria-selected]': 'navItem.active', '[attr.aria-disabled]': 'navItem.disabled', '(click)': 'nav.click(navItem); $event.preventDefault()' } },] } ]; /** @nocollapse */ NgbNavLink.ctorParameters = () => [ { type: String, decorators: [{ type: Attribute, args: ['role',] }] }, { type: NgbNavItem }, { type: NgbNav } ]; /** * @fileoverview added by tsickle * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ /** * The outlet where currently active nav content will be displayed. * * \@since 5.2.0 */ class NgbNavOutlet { } NgbNavOutlet.decorators = [ { type: Component, args: [{ selector: '[ngbNavOutlet]', host: { '[class.tab-content]': 'true' }, encapsulation: ViewEncapsulation.None, template: `
` }] } ]; NgbNavOutlet.propDecorators = { paneRole: [{ type: Input }], nav: [{ type: Input, args: ['ngbNavOutlet',] }] }; /** * @fileoverview added by tsickle * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ /** @type {?} */ const NGB_NAV_DIRECTIVES = [NgbNavContent, NgbNav, NgbNavItem, NgbNavLink, NgbNavOutlet]; class NgbNavModule { } NgbNavModule.decorators = [ { type: NgModule, args: [{ declarations: NGB_NAV_DIRECTIVES, exports: NGB_NAV_DIRECTIVES, imports: [CommonModule] },] } ]; /** * @fileoverview added by tsickle * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ /** * A configuration service for the [`NgbPagination`](#/components/pagination/api#NgbPagination) component. * * You can inject this service, typically in your root component, and customize the values of its properties in * order to provide default values for all the paginations used in the application. */ class NgbPaginationConfig { constructor() { this.disabled = false; this.boundaryLinks = false; this.directionLinks = true; this.ellipses = true; this.maxSize = 0; this.pageSize = 10; this.rotate = false; } } NgbPaginationConfig.decorators = [ { type: Injectable, args: [{ providedIn: 'root' },] } ]; /** @nocollapse */ NgbPaginationConfig.ngInjectableDef = ɵɵdefineInjectable({ factory: function NgbPaginationConfig_Factory() { return new NgbPaginationConfig(); }, token: NgbPaginationConfig, providedIn: "root" }); /** * @fileoverview added by tsickle * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ /** * A directive to match the 'ellipsis' link template * * \@since 4.1.0 */ class NgbPaginationEllipsis { /** * @param {?} templateRef */ constructor(templateRef) { this.templateRef = templateRef; } } NgbPaginationEllipsis.decorators = [ { type: Directive, args: [{ selector: 'ng-template[ngbPaginationEllipsis]' },] } ]; /** @nocollapse */ NgbPaginationEllipsis.ctorParameters = () => [ { type: TemplateRef } ]; /** * A directive to match the 'first' link template * * \@since 4.1.0 */ class NgbPaginationFirst { /** * @param {?} templateRef */ constructor(templateRef) { this.templateRef = templateRef; } } NgbPaginationFirst.decorators = [ { type: Directive, args: [{ selector: 'ng-template[ngbPaginationFirst]' },] } ]; /** @nocollapse */ NgbPaginationFirst.ctorParameters = () => [ { type: TemplateRef } ]; /** * A directive to match the 'last' link template * * \@since 4.1.0 */ class NgbPaginationLast { /** * @param {?} templateRef */ constructor(templateRef) { this.templateRef = templateRef; } } NgbPaginationLast.decorators = [ { type: Directive, args: [{ selector: 'ng-template[ngbPaginationLast]' },] } ]; /** @nocollapse */ NgbPaginationLast.ctorParameters = () => [ { type: TemplateRef } ]; /** * A directive to match the 'next' link template * * \@since 4.1.0 */ class NgbPaginationNext { /** * @param {?} templateRef */ constructor(templateRef) { this.templateRef = templateRef; } } NgbPaginationNext.decorators = [ { type: Directive, args: [{ selector: 'ng-template[ngbPaginationNext]' },] } ]; /** @nocollapse */ NgbPaginationNext.ctorParameters = () => [ { type: TemplateRef } ]; /** * A directive to match the page 'number' link template * * \@since 4.1.0 */ class NgbPaginationNumber { /** * @param {?} templateRef */ constructor(templateRef) { this.templateRef = templateRef; } } NgbPaginationNumber.decorators = [ { type: Directive, args: [{ selector: 'ng-template[ngbPaginationNumber]' },] } ]; /** @nocollapse */ NgbPaginationNumber.ctorParameters = () => [ { type: TemplateRef } ]; /** * A directive to match the 'previous' link template * * \@since 4.1.0 */ class NgbPaginationPrevious { /** * @param {?} templateRef */ constructor(templateRef) { this.templateRef = templateRef; } } NgbPaginationPrevious.decorators = [ { type: Directive, args: [{ selector: 'ng-template[ngbPaginationPrevious]' },] } ]; /** @nocollapse */ NgbPaginationPrevious.ctorParameters = () => [ { type: TemplateRef } ]; /** * A component that displays page numbers and allows to customize them in several ways. */ class NgbPagination { /** * @param {?} config */ constructor(config) { this.pageCount = 0; this.pages = []; /** * The current page. * * Page numbers start with `1`. */ this.page = 1; /** * An event fired when the page is changed. Will fire only if collection size is set and all values are valid. * * Event payload is the number of the newly selected page. * * Page numbers start with `1`. */ this.pageChange = new EventEmitter(true); this.disabled = config.disabled; this.boundaryLinks = config.boundaryLinks; this.directionLinks = config.directionLinks; this.ellipses = config.ellipses; this.maxSize = config.maxSize; this.pageSize = config.pageSize; this.rotate = config.rotate; this.size = config.size; } /** * @return {?} */ hasPrevious() { return this.page > 1; } /** * @return {?} */ hasNext() { return this.page < this.pageCount; } /** * @return {?} */ nextDisabled() { return !this.hasNext() || this.disabled; } /** * @return {?} */ previousDisabled() { return !this.hasPrevious() || this.disabled; } /** * @param {?} pageNumber * @return {?} */ selectPage(pageNumber) { this._updatePages(pageNumber); } /** * @param {?} changes * @return {?} */ ngOnChanges(changes) { this._updatePages(this.page); } /** * @param {?} pageNumber * @return {?} */ isEllipsis(pageNumber) { return pageNumber === -1; } /** * Appends ellipses and first/last page number to the displayed pages * @private * @param {?} start * @param {?} end * @return {?} */ _applyEllipses(start, end) { if (this.ellipses) { if (start > 0) { // The first page will always be included. If the displayed range // starts after the third page, then add ellipsis. But if the range // starts on the third page, then add the second page instead of // an ellipsis, because the ellipsis would only hide a single page. if (start > 2) { this.pages.unshift(-1); } else if (start === 2) { this.pages.unshift(2); } this.pages.unshift(1); } if (end < this.pageCount) { // The last page will always be included. If the displayed range // ends before the third-last page, then add ellipsis. But if the range // ends on third-last page, then add the second-last page instead of // an ellipsis, because the ellipsis would only hide a single page. if (end < (this.pageCount - 2)) { this.pages.push(-1); } else if (end === (this.pageCount - 2)) { this.pages.push(this.pageCount - 1); } this.pages.push(this.pageCount); } } } /** * Rotates page numbers based on maxSize items visible. * Currently selected page stays in the middle: * * Ex. for selected page = 6: * [5,*6*,7] for maxSize = 3 * [4,5,*6*,7] for maxSize = 4 * @private * @return {?} */ _applyRotation() { /** @type {?} */ let start = 0; /** @type {?} */ let end = this.pageCount; /** @type {?} */ let leftOffset = Math.floor(this.maxSize / 2); /** @type {?} */ let rightOffset = this.maxSize % 2 === 0 ? leftOffset - 1 : leftOffset; if (this.page <= leftOffset) { // very beginning, no rotation -> [0..maxSize] end = this.maxSize; } else if (this.pageCount - this.page < leftOffset) { // very end, no rotation -> [len-maxSize..len] start = this.pageCount - this.maxSize; } else { // rotate start = this.page - leftOffset - 1; end = this.page + rightOffset; } return [start, end]; } /** * Paginates page numbers based on maxSize items per page. * @private * @return {?} */ _applyPagination() { /** @type {?} */ let page = Math.ceil(this.page / this.maxSize) - 1; /** @type {?} */ let start = page * this.maxSize; /** @type {?} */ let end = start + this.maxSize; return [start, end]; } /** * @private * @param {?} newPageNo * @return {?} */ _setPageInRange(newPageNo) { /** @type {?} */ const prevPageNo = this.page; this.page = getValueInRange(newPageNo, this.pageCount, 1); if (this.page !== prevPageNo && isNumber(this.collectionSize)) { this.pageChange.emit(this.page); } } /** * @private * @param {?} newPage * @return {?} */ _updatePages(newPage) { this.pageCount = Math.ceil(this.collectionSize / this.pageSize); if (!isNumber(this.pageCount)) { this.pageCount = 0; } // fill-in model needed to render pages this.pages.length = 0; for (let i = 1; i <= this.pageCount; i++) { this.pages.push(i); } // set page within 1..max range this._setPageInRange(newPage); // apply maxSize if necessary if (this.maxSize > 0 && this.pageCount > this.maxSize) { /** @type {?} */ let start = 0; /** @type {?} */ let end = this.pageCount; // either paginating or rotating page numbers if (this.rotate) { [start, end] = this._applyRotation(); } else { [start, end] = this._applyPagination(); } this.pages = this.pages.slice(start, end); // adding ellipses this._applyEllipses(start, end); } } } NgbPagination.decorators = [ { type: Component, args: [{ selector: 'ngb-pagination', changeDetection: ChangeDetectionStrategy.OnPush, host: { 'role': 'navigation' }, template: ` ... {{ page }} (current) ` }] } ]; /** @nocollapse */ NgbPagination.ctorParameters = () => [ { type: NgbPaginationConfig } ]; NgbPagination.propDecorators = { tplEllipsis: [{ type: ContentChild, args: [NgbPaginationEllipsis, { static: false },] }], tplFirst: [{ type: ContentChild, args: [NgbPaginationFirst, { static: false },] }], tplLast: [{ type: ContentChild, args: [NgbPaginationLast, { static: false },] }], tplNext: [{ type: ContentChild, args: [NgbPaginationNext, { static: false },] }], tplNumber: [{ type: ContentChild, args: [NgbPaginationNumber, { static: false },] }], tplPrevious: [{ type: ContentChild, args: [NgbPaginationPrevious, { static: false },] }], disabled: [{ type: Input }], boundaryLinks: [{ type: Input }], directionLinks: [{ type: Input }], ellipses: [{ type: Input }], rotate: [{ type: Input }], collectionSize: [{ type: Input }], maxSize: [{ type: Input }], page: [{ type: Input }], pageSize: [{ type: Input }], pageChange: [{ type: Output }], size: [{ type: Input }] }; /** * @fileoverview added by tsickle * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ /** @type {?} */ const DIRECTIVES = [ NgbPagination, NgbPaginationEllipsis, NgbPaginationFirst, NgbPaginationLast, NgbPaginationNext, NgbPaginationNumber, NgbPaginationPrevious ]; class NgbPaginationModule { } NgbPaginationModule.decorators = [ { type: NgModule, args: [{ declarations: DIRECTIVES, exports: DIRECTIVES, imports: [CommonModule] },] } ]; /** * @fileoverview added by tsickle * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ class Trigger { /** * @param {?} open * @param {?=} close */ constructor(open, close) { this.open = open; this.close = close; if (!close) { this.close = open; } } /** * @return {?} */ isManual() { return this.open === 'manual' || this.close === 'manual'; } } /** @type {?} */ const DEFAULT_ALIASES = { 'hover': ['mouseenter', 'mouseleave'], 'focus': ['focusin', 'focusout'], }; /** * @param {?} triggers * @param {?=} aliases * @return {?} */ function parseTriggers(triggers, aliases = DEFAULT_ALIASES) { /** @type {?} */ const trimmedTriggers = (triggers || '').trim(); if (trimmedTriggers.length === 0) { return []; } /** @type {?} */ const parsedTriggers = trimmedTriggers.split(/\s+/).map((/** * @param {?} trigger * @return {?} */ trigger => trigger.split(':'))).map((/** * @param {?} triggerPair * @return {?} */ (triggerPair) => { /** @type {?} */ let alias = aliases[triggerPair[0]] || triggerPair; return new Trigger(alias[0], alias[1]); })); /** @type {?} */ const manualTriggers = parsedTriggers.filter((/** * @param {?} triggerPair * @return {?} */ triggerPair => triggerPair.isManual())); if (manualTriggers.length > 1) { throw 'Triggers parse error: only one manual trigger is allowed'; } if (manualTriggers.length === 1 && parsedTriggers.length > 1) { throw 'Triggers parse error: manual trigger can\'t be mixed with other triggers'; } return parsedTriggers; } /** * @param {?} renderer * @param {?} nativeElement * @param {?} triggers * @param {?} isOpenedFn * @return {?} */ function observeTriggers(renderer, nativeElement, triggers, isOpenedFn) { return new Observable((/** * @param {?} subscriber * @return {?} */ subscriber => { /** @type {?} */ const listeners = []; /** @type {?} */ const openFn = (/** * @return {?} */ () => subscriber.next(true)); /** @type {?} */ const closeFn = (/** * @return {?} */ () => subscriber.next(false)); /** @type {?} */ const toggleFn = (/** * @return {?} */ () => subscriber.next(!isOpenedFn())); triggers.forEach((/** * @param {?} trigger * @return {?} */ (trigger) => { if (trigger.open === trigger.close) { listeners.push(renderer.listen(nativeElement, trigger.open, toggleFn)); } else { listeners.push(renderer.listen(nativeElement, trigger.open, openFn), renderer.listen(nativeElement, trigger.close, closeFn)); } })); return (/** * @return {?} */ () => { listeners.forEach((/** * @param {?} unsubscribeFn * @return {?} */ unsubscribeFn => unsubscribeFn())); }); })); } /** @type {?} */ const delayOrNoop = (/** * @template T * @param {?} time * @return {?} */ (time) => time > 0 ? delay(time) : (/** * @param {?} a * @return {?} */ (a) => a)); /** * @param {?} openDelay * @param {?} closeDelay * @param {?} isOpenedFn * @return {?} */ function triggerDelay(openDelay, closeDelay, isOpenedFn) { return (/** * @param {?} input$ * @return {?} */ (input$) => { /** @type {?} */ let pending = null; /** @type {?} */ const filteredInput$ = input$.pipe(map((/** * @param {?} open * @return {?} */ open => ({ open }))), filter((/** * @param {?} event * @return {?} */ event => { /** @type {?} */ const currentlyOpen = isOpenedFn(); if (currentlyOpen !== event.open && (!pending || pending.open === currentlyOpen)) { pending = event; return true; } if (pending && pending.open !== event.open) { pending = null; } return false; })), share()); /** @type {?} */ const delayedOpen$ = filteredInput$.pipe(filter((/** * @param {?} event * @return {?} */ event => event.open)), delayOrNoop(openDelay)); /** @type {?} */ const delayedClose$ = filteredInput$.pipe(filter((/** * @param {?} event * @return {?} */ event => !event.open)), delayOrNoop(closeDelay)); return merge(delayedOpen$, delayedClose$) .pipe(filter((/** * @param {?} event * @return {?} */ event => { if (event === pending) { pending = null; return event.open !== isOpenedFn(); } return false; })), map((/** * @param {?} event * @return {?} */ event => event.open))); }); } /** * @param {?} renderer * @param {?} nativeElement * @param {?} triggers * @param {?} isOpenedFn * @param {?} openFn * @param {?} closeFn * @param {?=} openDelay * @param {?=} closeDelay * @return {?} */ function listenToTriggers(renderer, nativeElement, triggers, isOpenedFn, openFn, closeFn, openDelay = 0, closeDelay = 0) { /** @type {?} */ const parsedTriggers = parseTriggers(triggers); if (parsedTriggers.length === 1 && parsedTriggers[0].isManual()) { return (/** * @return {?} */ () => { }); } /** @type {?} */ const subscription = observeTriggers(renderer, nativeElement, parsedTriggers, isOpenedFn) .pipe(triggerDelay(openDelay, closeDelay, isOpenedFn)) .subscribe((/** * @param {?} open * @return {?} */ open => (open ? openFn() : closeFn()))); return (/** * @return {?} */ () => subscription.unsubscribe()); } /** * @fileoverview added by tsickle * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ /** * A configuration service for the [`NgbPopover`](#/components/popover/api#NgbPopover) component. * * You can inject this service, typically in your root component, and customize the values of its properties in * order to provide default values for all the popovers used in the application. */ class NgbPopoverConfig { constructor() { this.autoClose = true; this.placement = 'auto'; this.triggers = 'click'; this.disablePopover = false; this.openDelay = 0; this.closeDelay = 0; } } NgbPopoverConfig.decorators = [ { type: Injectable, args: [{ providedIn: 'root' },] } ]; /** @nocollapse */ NgbPopoverConfig.ngInjectableDef = ɵɵdefineInjectable({ factory: function NgbPopoverConfig_Factory() { return new NgbPopoverConfig(); }, token: NgbPopoverConfig, providedIn: "root" }); /** * @fileoverview added by tsickle * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ /** @type {?} */ let nextId$3 = 0; class NgbPopoverWindow { /** * @return {?} */ isTitleTemplate() { return this.title instanceof TemplateRef; } } NgbPopoverWindow.decorators = [ { type: Component, args: [{ selector: 'ngb-popover-window', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, host: { '[class]': '"popover" + (popoverClass ? " " + popoverClass : "")', 'role': 'tooltip', '[id]': 'id' }, template: `

{{title}}

`, styles: ["ngb-popover-window.bs-popover-bottom>.arrow,ngb-popover-window.bs-popover-top>.arrow{left:50%;margin-left:-.5rem}ngb-popover-window.bs-popover-bottom-left>.arrow,ngb-popover-window.bs-popover-top-left>.arrow{left:2em}ngb-popover-window.bs-popover-bottom-right>.arrow,ngb-popover-window.bs-popover-top-right>.arrow{left:auto;right:2em}ngb-popover-window.bs-popover-left>.arrow,ngb-popover-window.bs-popover-right>.arrow{top:50%;margin-top:-.5rem}ngb-popover-window.bs-popover-left-top>.arrow,ngb-popover-window.bs-popover-right-top>.arrow{top:.7em}ngb-popover-window.bs-popover-left-bottom>.arrow,ngb-popover-window.bs-popover-right-bottom>.arrow{top:auto;bottom:.7em}"] }] } ]; NgbPopoverWindow.propDecorators = { title: [{ type: Input }], id: [{ type: Input }], popoverClass: [{ type: Input }], context: [{ type: Input }] }; /** * A lightweight and extensible directive for fancy popover creation. */ class NgbPopover { /** * @param {?} _elementRef * @param {?} _renderer * @param {?} injector * @param {?} componentFactoryResolver * @param {?} viewContainerRef * @param {?} config * @param {?} _ngZone * @param {?} _document * @param {?} _changeDetector * @param {?} applicationRef */ constructor(_elementRef, _renderer, injector, componentFactoryResolver, viewContainerRef, config, _ngZone, _document, _changeDetector, applicationRef) { this._elementRef = _elementRef; this._renderer = _renderer; this._ngZone = _ngZone; this._document = _document; this._changeDetector = _changeDetector; /** * An event emitted when the popover is shown. Contains no payload. */ this.shown = new EventEmitter(); /** * An event emitted when the popover is hidden. Contains no payload. */ this.hidden = new EventEmitter(); this._ngbPopoverWindowId = `ngb-popover-${nextId$3++}`; this.autoClose = config.autoClose; this.placement = config.placement; this.triggers = config.triggers; this.container = config.container; this.disablePopover = config.disablePopover; this.popoverClass = config.popoverClass; this.openDelay = config.openDelay; this.closeDelay = config.closeDelay; this._popupService = new PopupService(NgbPopoverWindow, injector, viewContainerRef, _renderer, componentFactoryResolver, applicationRef); this._zoneSubscription = _ngZone.onStable.subscribe((/** * @return {?} */ () => { if (this._windowRef) { positionElements(this._elementRef.nativeElement, this._windowRef.location.nativeElement, this.placement, this.container === 'body', 'bs-popover'); } })); } /** * @private * @return {?} */ _isDisabled() { if (this.disablePopover) { return true; } if (!this.ngbPopover && !this.popoverTitle) { return true; } return false; } /** * Opens the popover. * * This is considered to be a "manual" triggering. * The `context` is an optional value to be injected into the popover template when it is created. * @param {?=} context * @return {?} */ open(context) { if (!this._windowRef && !this._isDisabled()) { this._windowRef = this._popupService.open(this.ngbPopover, context); this._windowRef.instance.title = this.popoverTitle; this._windowRef.instance.context = context; this._windowRef.instance.popoverClass = this.popoverClass; this._windowRef.instance.id = this._ngbPopoverWindowId; this._renderer.setAttribute(this._elementRef.nativeElement, 'aria-describedby', this._ngbPopoverWindowId); if (this.container === 'body') { this._document.querySelector(this.container).appendChild(this._windowRef.location.nativeElement); } // We need to detect changes, because we don't know where .open() might be called from. // Ex. opening popover from one of lifecycle hooks that run after the CD // (say from ngAfterViewInit) will result in 'ExpressionHasChanged' exception this._windowRef.changeDetectorRef.detectChanges(); // We need to mark for check, because popover won't work inside the OnPush component. // Ex. when we use expression like `{{ popover.isOpen() : 'opened' : 'closed' }}` // inside the template of an OnPush component and we change the popover from // open -> closed, the expression in question won't be updated unless we explicitly // mark the parent component to be checked. this._windowRef.changeDetectorRef.markForCheck(); ngbAutoClose(this._ngZone, this._document, this.autoClose, (/** * @return {?} */ () => this.close()), this.hidden, [this._windowRef.location.nativeElement]); this.shown.emit(); } } /** * Closes the popover. * * This is considered to be a "manual" triggering of the popover. * @return {?} */ close() { if (this._windowRef) { this._renderer.removeAttribute(this._elementRef.nativeElement, 'aria-describedby'); this._popupService.close(); this._windowRef = null; this.hidden.emit(); this._changeDetector.markForCheck(); } } /** * Toggles the popover. * * This is considered to be a "manual" triggering of the popover. * @return {?} */ toggle() { if (this._windowRef) { this.close(); } else { this.open(); } } /** * Returns `true`, if the popover is currently shown. * @return {?} */ isOpen() { return this._windowRef != null; } /** * @return {?} */ ngOnInit() { this._unregisterListenersFn = listenToTriggers(this._renderer, this._elementRef.nativeElement, this.triggers, this.isOpen.bind(this), this.open.bind(this), this.close.bind(this), +this.openDelay, +this.closeDelay); } /** * @param {?} __0 * @return {?} */ ngOnChanges({ ngbPopover, popoverTitle, disablePopover, popoverClass }) { if (popoverClass && this.isOpen()) { this._windowRef.instance.popoverClass = popoverClass.currentValue; } // close popover if title and content become empty, or disablePopover set to true if ((ngbPopover || popoverTitle || disablePopover) && this._isDisabled()) { this.close(); } } /** * @return {?} */ ngOnDestroy() { this.close(); // This check is needed as it might happen that ngOnDestroy is called before ngOnInit // under certain conditions, see: https://github.com/ng-bootstrap/ng-bootstrap/issues/2199 if (this._unregisterListenersFn) { this._unregisterListenersFn(); } this._zoneSubscription.unsubscribe(); } } NgbPopover.decorators = [ { type: Directive, args: [{ selector: '[ngbPopover]', exportAs: 'ngbPopover' },] } ]; /** @nocollapse */ NgbPopover.ctorParameters = () => [ { type: ElementRef }, { type: Renderer2 }, { type: Injector }, { type: ComponentFactoryResolver }, { type: ViewContainerRef }, { type: NgbPopoverConfig }, { type: NgZone }, { type: undefined, decorators: [{ type: Inject, args: [DOCUMENT,] }] }, { type: ChangeDetectorRef }, { type: ApplicationRef } ]; NgbPopover.propDecorators = { autoClose: [{ type: Input }], ngbPopover: [{ type: Input }], popoverTitle: [{ type: Input }], placement: [{ type: Input }], triggers: [{ type: Input }], container: [{ type: Input }], disablePopover: [{ type: Input }], popoverClass: [{ type: Input }], openDelay: [{ type: Input }], closeDelay: [{ type: Input }], shown: [{ type: Output }], hidden: [{ type: Output }] }; /** * @fileoverview added by tsickle * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ class NgbPopoverModule { } NgbPopoverModule.decorators = [ { type: NgModule, args: [{ declarations: [NgbPopover, NgbPopoverWindow], exports: [NgbPopover], imports: [CommonModule], entryComponents: [NgbPopoverWindow] },] } ]; /** * @fileoverview added by tsickle * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ /** * A configuration service for the [`NgbProgressbar`](#/components/progressbar/api#NgbProgressbar) component. * * You can inject this service, typically in your root component, and customize the values of its properties in * order to provide default values for all the progress bars used in the application. */ class NgbProgressbarConfig { constructor() { this.max = 100; this.animated = false; this.striped = false; this.showValue = false; } } NgbProgressbarConfig.decorators = [ { type: Injectable, args: [{ providedIn: 'root' },] } ]; /** @nocollapse */ NgbProgressbarConfig.ngInjectableDef = ɵɵdefineInjectable({ factory: function NgbProgressbarConfig_Factory() { return new NgbProgressbarConfig(); }, token: NgbProgressbarConfig, providedIn: "root" }); /** * @fileoverview added by tsickle * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ /** * A directive that provides feedback on the progress of a workflow or an action. */ class NgbProgressbar { /** * @param {?} config */ constructor(config) { /** * The current value for the progress bar. * * Should be in the `[0, max]` range. */ this.value = 0; this.max = config.max; this.animated = config.animated; this.striped = config.striped; this.textType = config.textType; this.type = config.type; this.showValue = config.showValue; this.height = config.height; } /** * The maximal value to be displayed in the progress bar. * * Should be a positive number. Will default to 100 otherwise. * @param {?} max * @return {?} */ set max(max) { this._max = !isNumber(max) || max <= 0 ? 100 : max; } /** * @return {?} */ get max() { return this._max; } /** * @return {?} */ getValue() { return getValueInRange(this.value, this.max); } /** * @return {?} */ getPercentValue() { return 100 * this.getValue() / this.max; } } NgbProgressbar.decorators = [ { type: Component, args: [{ selector: 'ngb-progressbar', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, template: `
{{getPercentValue()}}%
` }] } ]; /** @nocollapse */ NgbProgressbar.ctorParameters = () => [ { type: NgbProgressbarConfig } ]; NgbProgressbar.propDecorators = { max: [{ type: Input }], animated: [{ type: Input }], striped: [{ type: Input }], showValue: [{ type: Input }], textType: [{ type: Input }], type: [{ type: Input }], value: [{ type: Input }], height: [{ type: Input }] }; /** * @fileoverview added by tsickle * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ class NgbProgressbarModule { } NgbProgressbarModule.decorators = [ { type: NgModule, args: [{ declarations: [NgbProgressbar], exports: [NgbProgressbar], imports: [CommonModule] },] } ]; /** * @fileoverview added by tsickle * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ /** * A configuration service for the [`NgbRating`](#/components/rating/api#NgbRating) component. * * You can inject this service, typically in your root component, and customize the values of its properties in * order to provide default values for all the ratings used in the application. */ class NgbRatingConfig { constructor() { this.max = 10; this.readonly = false; this.resettable = false; } } NgbRatingConfig.decorators = [ { type: Injectable, args: [{ providedIn: 'root' },] } ]; /** @nocollapse */ NgbRatingConfig.ngInjectableDef = ɵɵdefineInjectable({ factory: function NgbRatingConfig_Factory() { return new NgbRatingConfig(); }, token: NgbRatingConfig, providedIn: "root" }); /** * @fileoverview added by tsickle * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ /** @type {?} */ const NGB_RATING_VALUE_ACCESSOR = { provide: NG_VALUE_ACCESSOR, useExisting: forwardRef((/** * @return {?} */ () => NgbRating)), multi: true }; /** * A directive that helps visualising and interacting with a star rating bar. */ class NgbRating { /** * @param {?} config * @param {?} _changeDetectorRef */ constructor(config, _changeDetectorRef) { this._changeDetectorRef = _changeDetectorRef; this.contexts = []; this.disabled = false; /** * An event emitted when the user is hovering over a given rating. * * Event payload equals to the rating being hovered over. */ this.hover = new EventEmitter(); /** * An event emitted when the user stops hovering over a given rating. * * Event payload equals to the rating of the last item being hovered over. */ this.leave = new EventEmitter(); /** * An event emitted when the user selects a new rating. * * Event payload equals to the newly selected rating. */ this.rateChange = new EventEmitter(true); this.onChange = (/** * @param {?} _ * @return {?} */ (_) => { }); this.onTouched = (/** * @return {?} */ () => { }); this.max = config.max; this.readonly = config.readonly; } /** * @return {?} */ ariaValueText() { return `${this.nextRate} out of ${this.max}`; } /** * @param {?} value * @return {?} */ enter(value) { if (!this.readonly && !this.disabled) { this._updateState(value); } this.hover.emit(value); } /** * @return {?} */ handleBlur() { this.onTouched(); } /** * @param {?} value * @return {?} */ handleClick(value) { this.update(this.resettable && this.rate === value ? 0 : value); } /** * @param {?} event * @return {?} */ handleKeyDown(event) { // tslint:disable-next-line:deprecation switch (event.which) { case Key.ArrowDown: case Key.ArrowLeft: this.update(this.rate - 1); break; case Key.ArrowUp: case Key.ArrowRight: this.update(this.rate + 1); break; case Key.Home: this.update(0); break; case Key.End: this.update(this.max); break; default: return; } // note 'return' in default case event.preventDefault(); } /** * @param {?} changes * @return {?} */ ngOnChanges(changes) { if (changes['rate']) { this.update(this.rate); } } /** * @return {?} */ ngOnInit() { this.contexts = Array.from({ length: this.max }, (/** * @param {?} v * @param {?} k * @return {?} */ (v, k) => ({ fill: 0, index: k }))); this._updateState(this.rate); } /** * @param {?} fn * @return {?} */ registerOnChange(fn) { this.onChange = fn; } /** * @param {?} fn * @return {?} */ registerOnTouched(fn) { this.onTouched = fn; } /** * @return {?} */ reset() { this.leave.emit(this.nextRate); this._updateState(this.rate); } /** * @param {?} isDisabled * @return {?} */ setDisabledState(isDisabled) { this.disabled = isDisabled; } /** * @param {?} value * @param {?=} internalChange * @return {?} */ update(value, internalChange = true) { /** @type {?} */ const newRate = getValueInRange(value, this.max, 0); if (!this.readonly && !this.disabled && this.rate !== newRate) { this.rate = newRate; this.rateChange.emit(this.rate); } if (internalChange) { this.onChange(this.rate); this.onTouched(); } this._updateState(this.rate); } /** * @param {?} value * @return {?} */ writeValue(value) { this.update(value, false); this._changeDetectorRef.markForCheck(); } /** * @private * @param {?} index * @return {?} */ _getFillValue(index) { /** @type {?} */ const diff = this.nextRate - index; if (diff >= 1) { return 100; } if (diff < 1 && diff > 0) { return parseInt((diff * 100).toFixed(2), 10); } return 0; } /** * @private * @param {?} nextValue * @return {?} */ _updateState(nextValue) { this.nextRate = nextValue; this.contexts.forEach((/** * @param {?} context * @param {?} index * @return {?} */ (context, index) => context.fill = this._getFillValue(index))); } } NgbRating.decorators = [ { type: Component, args: [{ selector: 'ngb-rating', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, host: { 'class': 'd-inline-flex', 'tabindex': '0', 'role': 'slider', 'aria-valuemin': '0', '[attr.aria-valuemax]': 'max', '[attr.aria-valuenow]': 'nextRate', '[attr.aria-valuetext]': 'ariaValueText()', '[attr.aria-disabled]': 'readonly ? true : null', '(blur)': 'handleBlur()', '(keydown)': 'handleKeyDown($event)', '(mouseleave)': 'reset()' }, template: ` {{ fill === 100 ? '★' : '☆' }} ({{ index < nextRate ? '*' : ' ' }}) `, providers: [NGB_RATING_VALUE_ACCESSOR] }] } ]; /** @nocollapse */ NgbRating.ctorParameters = () => [ { type: NgbRatingConfig }, { type: ChangeDetectorRef } ]; NgbRating.propDecorators = { max: [{ type: Input }], rate: [{ type: Input }], readonly: [{ type: Input }], resettable: [{ type: Input }], starTemplate: [{ type: Input }], starTemplateFromContent: [{ type: ContentChild, args: [TemplateRef, { static: false },] }], hover: [{ type: Output }], leave: [{ type: Output }], rateChange: [{ type: Output }] }; /** * @fileoverview added by tsickle * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ class NgbRatingModule { } NgbRatingModule.decorators = [ { type: NgModule, args: [{ declarations: [NgbRating], exports: [NgbRating], imports: [CommonModule] },] } ]; /** * @fileoverview added by tsickle * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ /** * A configuration service for the [`NgbTabset`](#/components/tabset/api#NgbTabset) component. * * You can inject this service, typically in your root component, and customize the values of its properties in * order to provide default values for all the tabsets used in the application. */ class NgbTabsetConfig { constructor() { this.justify = 'start'; this.orientation = 'horizontal'; this.type = 'tabs'; } } NgbTabsetConfig.decorators = [ { type: Injectable, args: [{ providedIn: 'root' },] } ]; /** @nocollapse */ NgbTabsetConfig.ngInjectableDef = ɵɵdefineInjectable({ factory: function NgbTabsetConfig_Factory() { return new NgbTabsetConfig(); }, token: NgbTabsetConfig, providedIn: "root" }); /** * @fileoverview added by tsickle * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ /** @type {?} */ let nextId$4 = 0; /** * A directive to wrap tab titles that need to contain HTML markup or other directives. * * Alternatively you could use the `NgbTab.title` input for string titles. */ class NgbTabTitle { /** * @param {?} templateRef */ constructor(templateRef) { this.templateRef = templateRef; } } NgbTabTitle.decorators = [ { type: Directive, args: [{ selector: 'ng-template[ngbTabTitle]' },] } ]; /** @nocollapse */ NgbTabTitle.ctorParameters = () => [ { type: TemplateRef } ]; /** * A directive to wrap content to be displayed in a tab. */ class NgbTabContent { /** * @param {?} templateRef */ constructor(templateRef) { this.templateRef = templateRef; } } NgbTabContent.decorators = [ { type: Directive, args: [{ selector: 'ng-template[ngbTabContent]' },] } ]; /** @nocollapse */ NgbTabContent.ctorParameters = () => [ { type: TemplateRef } ]; /** * A directive representing an individual tab. */ class NgbTab { constructor() { /** * The tab identifier. * * Must be unique for the entire document for proper accessibility support. */ this.id = `ngb-tab-${nextId$4++}`; /** * If `true`, the current tab is disabled and can't be toggled. */ this.disabled = false; } /** * @return {?} */ ngAfterContentChecked() { // We are using @ContentChildren instead of @ContentChild as in the Angular version being used // only @ContentChildren allows us to specify the {descendants: false} option. // Without {descendants: false} we are hitting bugs described in: // https://github.com/ng-bootstrap/ng-bootstrap/issues/2240 this.titleTpl = this.titleTpls.first; this.contentTpl = this.contentTpls.first; } } NgbTab.decorators = [ { type: Directive, args: [{ selector: 'ngb-tab' },] } ]; NgbTab.propDecorators = { id: [{ type: Input }], title: [{ type: Input }], disabled: [{ type: Input }], titleTpls: [{ type: ContentChildren, args: [NgbTabTitle, { descendants: false },] }], contentTpls: [{ type: ContentChildren, args: [NgbTabContent, { descendants: false },] }] }; /** * A component that makes it easy to create tabbed interface. */ class NgbTabset { /** * @param {?} config */ constructor(config) { /** * If `true`, non-visible tabs content will be removed from DOM. Otherwise it will just be hidden. */ this.destroyOnHide = true; /** * A tab change event emitted right before the tab change happens. * * See [`NgbTabChangeEvent`](#/components/tabset/api#NgbTabChangeEvent) for payload details. */ this.tabChange = new EventEmitter(); this.type = config.type; this.justify = config.justify; this.orientation = config.orientation; } /** * The horizontal alignment of the tabs with flexbox utilities. * @param {?} className * @return {?} */ set justify(className) { if (className === 'fill' || className === 'justified') { this.justifyClass = `nav-${className}`; } else { this.justifyClass = `justify-content-${className}`; } } /** * Selects the tab with the given id and shows its associated content panel. * * Any other tab that was previously selected becomes unselected and its associated pane is removed from DOM or * hidden depending on the `destroyOnHide` value. * @param {?} tabId * @return {?} */ select(tabId) { /** @type {?} */ let selectedTab = this._getTabById(tabId); if (selectedTab && !selectedTab.disabled && this.activeId !== selectedTab.id) { /** @type {?} */ let defaultPrevented = false; this.tabChange.emit({ activeId: this.activeId, nextId: selectedTab.id, preventDefault: (/** * @return {?} */ () => { defaultPrevented = true; }) }); if (!defaultPrevented) { this.activeId = selectedTab.id; } } } /** * @return {?} */ ngAfterContentChecked() { // auto-correct activeId that might have been set incorrectly as input /** @type {?} */ let activeTab = this._getTabById(this.activeId); this.activeId = activeTab ? activeTab.id : (this.tabs.length ? this.tabs.first.id : null); } /** * @private * @param {?} id * @return {?} */ _getTabById(id) { /** @type {?} */ let tabsWithId = this.tabs.filter((/** * @param {?} tab * @return {?} */ tab => tab.id === id)); return tabsWithId.length ? tabsWithId[0] : null; } } NgbTabset.decorators = [ { type: Component, args: [{ selector: 'ngb-tabset', exportAs: 'ngbTabset', encapsulation: ViewEncapsulation.None, template: `
` }] } ]; /** @nocollapse */ NgbTabset.ctorParameters = () => [ { type: NgbTabsetConfig } ]; NgbTabset.propDecorators = { tabs: [{ type: ContentChildren, args: [NgbTab,] }], activeId: [{ type: Input }], destroyOnHide: [{ type: Input }], justify: [{ type: Input }], orientation: [{ type: Input }], type: [{ type: Input }], tabChange: [{ type: Output }] }; /** * @fileoverview added by tsickle * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ /** @type {?} */ const NGB_TABSET_DIRECTIVES = [NgbTabset, NgbTab, NgbTabContent, NgbTabTitle]; class NgbTabsetModule { } NgbTabsetModule.decorators = [ { type: NgModule, args: [{ declarations: NGB_TABSET_DIRECTIVES, exports: NGB_TABSET_DIRECTIVES, imports: [CommonModule, NgbNavModule] },] } ]; /** * @fileoverview added by tsickle * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ class NgbTime { /** * @param {?=} hour * @param {?=} minute * @param {?=} second */ constructor(hour, minute, second) { this.hour = toInteger(hour); this.minute = toInteger(minute); this.second = toInteger(second); } /** * @param {?=} step * @return {?} */ changeHour(step = 1) { this.updateHour((isNaN(this.hour) ? 0 : this.hour) + step); } /** * @param {?} hour * @return {?} */ updateHour(hour) { if (isNumber(hour)) { this.hour = (hour < 0 ? 24 + hour : hour) % 24; } else { this.hour = NaN; } } /** * @param {?=} step * @return {?} */ changeMinute(step = 1) { this.updateMinute((isNaN(this.minute) ? 0 : this.minute) + step); } /** * @param {?} minute * @return {?} */ updateMinute(minute) { if (isNumber(minute)) { this.minute = minute % 60 < 0 ? 60 + minute % 60 : minute % 60; this.changeHour(Math.floor(minute / 60)); } else { this.minute = NaN; } } /** * @param {?=} step * @return {?} */ changeSecond(step = 1) { this.updateSecond((isNaN(this.second) ? 0 : this.second) + step); } /** * @param {?} second * @return {?} */ updateSecond(second) { if (isNumber(second)) { this.second = second < 0 ? 60 + second % 60 : second % 60; this.changeMinute(Math.floor(second / 60)); } else { this.second = NaN; } } /** * @param {?=} checkSecs * @return {?} */ isValid(checkSecs = true) { return isNumber(this.hour) && isNumber(this.minute) && (checkSecs ? isNumber(this.second) : true); } /** * @return {?} */ toString() { return `${this.hour || 0}:${this.minute || 0}:${this.second || 0}`; } } /** * @fileoverview added by tsickle * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ /** * A configuration service for the [`NgbTimepicker`](#/components/timepicker/api#NgbTimepicker) component. * * You can inject this service, typically in your root component, and customize the values of its properties in * order to provide default values for all the timepickers used in the application. */ class NgbTimepickerConfig { constructor() { this.meridian = false; this.spinners = true; this.seconds = false; this.hourStep = 1; this.minuteStep = 1; this.secondStep = 1; this.disabled = false; this.readonlyInputs = false; this.size = 'medium'; } } NgbTimepickerConfig.decorators = [ { type: Injectable, args: [{ providedIn: 'root' },] } ]; /** @nocollapse */ NgbTimepickerConfig.ngInjectableDef = ɵɵdefineInjectable({ factory: function NgbTimepickerConfig_Factory() { return new NgbTimepickerConfig(); }, token: NgbTimepickerConfig, providedIn: "root" }); /** * @fileoverview added by tsickle * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ /** * @return {?} */ function NGB_DATEPICKER_TIME_ADAPTER_FACTORY() { return new NgbTimeStructAdapter(); } /** * An abstract service that does the conversion between the internal timepicker `NgbTimeStruct` model and * any provided user time model `T`, ex. a string, a native date, etc. * * The adapter is used **only** for conversion when binding timepicker to a form control, * ex. `[(ngModel)]="userTimeModel"`. Here `userTimeModel` can be of any type. * * The default timepicker implementation assumes we use `NgbTimeStruct` as a user model. * * See the [custom time adapter demo](#/components/timepicker/examples#adapter) for an example. * * \@since 2.2.0 * @abstract * @template T */ class NgbTimeAdapter { } NgbTimeAdapter.decorators = [ { type: Injectable, args: [{ providedIn: 'root', useFactory: NGB_DATEPICKER_TIME_ADAPTER_FACTORY },] } ]; /** @nocollapse */ NgbTimeAdapter.ngInjectableDef = ɵɵdefineInjectable({ factory: NGB_DATEPICKER_TIME_ADAPTER_FACTORY, token: NgbTimeAdapter, providedIn: "root" }); class NgbTimeStructAdapter extends NgbTimeAdapter { /** * Converts a NgbTimeStruct value into NgbTimeStruct value * @param {?} time * @return {?} */ fromModel(time) { return (time && isInteger(time.hour) && isInteger(time.minute)) ? { hour: time.hour, minute: time.minute, second: isInteger(time.second) ? time.second : null } : null; } /** * Converts a NgbTimeStruct value into NgbTimeStruct value * @param {?} time * @return {?} */ toModel(time) { return (time && isInteger(time.hour) && isInteger(time.minute)) ? { hour: time.hour, minute: time.minute, second: isInteger(time.second) ? time.second : null } : null; } } NgbTimeStructAdapter.decorators = [ { type: Injectable } ]; /** * @fileoverview added by tsickle * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ /** * @param {?} locale * @return {?} */ function NGB_TIMEPICKER_I18N_FACTORY(locale) { return new NgbTimepickerI18nDefault(locale); } /** * Type of the service supplying day periods (for example, 'AM' and 'PM') to NgbTimepicker component. * The default implementation of this service honors the Angular locale, and uses the registered locale data, * as explained in the Angular i18n guide. * @abstract */ class NgbTimepickerI18n { } NgbTimepickerI18n.decorators = [ { type: Injectable, args: [{ providedIn: 'root', useFactory: NGB_TIMEPICKER_I18N_FACTORY, deps: [LOCALE_ID] },] } ]; /** @nocollapse */ NgbTimepickerI18n.ngInjectableDef = ɵɵdefineInjectable({ factory: function NgbTimepickerI18n_Factory() { return NGB_TIMEPICKER_I18N_FACTORY(ɵɵinject(LOCALE_ID)); }, token: NgbTimepickerI18n, providedIn: "root" }); class NgbTimepickerI18nDefault extends NgbTimepickerI18n { /** * @param {?} locale */ constructor(locale) { super(); this._periods = getLocaleDayPeriods(locale, FormStyle.Standalone, TranslationWidth.Narrow); } /** * @return {?} */ getMorningPeriod() { return this._periods[0]; } /** * @return {?} */ getAfternoonPeriod() { return this._periods[1]; } } NgbTimepickerI18nDefault.decorators = [ { type: Injectable } ]; /** @nocollapse */ NgbTimepickerI18nDefault.ctorParameters = () => [ { type: String, decorators: [{ type: Inject, args: [LOCALE_ID,] }] } ]; /** * @fileoverview added by tsickle * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ /** @type {?} */ const FILTER_REGEX = /[^0-9]/g; /** @type {?} */ const NGB_TIMEPICKER_VALUE_ACCESSOR = { provide: NG_VALUE_ACCESSOR, useExisting: forwardRef((/** * @return {?} */ () => NgbTimepicker)), multi: true }; /** * A directive that helps with wth picking hours, minutes and seconds. */ class NgbTimepicker { /** * @param {?} _config * @param {?} _ngbTimeAdapter * @param {?} _cd * @param {?} i18n */ constructor(_config, _ngbTimeAdapter, _cd, i18n) { this._config = _config; this._ngbTimeAdapter = _ngbTimeAdapter; this._cd = _cd; this.i18n = i18n; this.onChange = (/** * @param {?} _ * @return {?} */ (_) => { }); this.onTouched = (/** * @return {?} */ () => { }); this.meridian = _config.meridian; this.spinners = _config.spinners; this.seconds = _config.seconds; this.hourStep = _config.hourStep; this.minuteStep = _config.minuteStep; this.secondStep = _config.secondStep; this.disabled = _config.disabled; this.readonlyInputs = _config.readonlyInputs; this.size = _config.size; } /** * The number of hours to add/subtract when clicking hour spinners. * @param {?} step * @return {?} */ set hourStep(step) { this._hourStep = isInteger(step) ? step : this._config.hourStep; } /** * @return {?} */ get hourStep() { return this._hourStep; } /** * The number of minutes to add/subtract when clicking minute spinners. * @param {?} step * @return {?} */ set minuteStep(step) { this._minuteStep = isInteger(step) ? step : this._config.minuteStep; } /** * @return {?} */ get minuteStep() { return this._minuteStep; } /** * The number of seconds to add/subtract when clicking second spinners. * @param {?} step * @return {?} */ set secondStep(step) { this._secondStep = isInteger(step) ? step : this._config.secondStep; } /** * @return {?} */ get secondStep() { return this._secondStep; } /** * @param {?} value * @return {?} */ writeValue(value) { /** @type {?} */ const structValue = this._ngbTimeAdapter.fromModel(value); this.model = structValue ? new NgbTime(structValue.hour, structValue.minute, structValue.second) : new NgbTime(); if (!this.seconds && (!structValue || !isNumber(structValue.second))) { this.model.second = 0; } this._cd.markForCheck(); } /** * @param {?} fn * @return {?} */ registerOnChange(fn) { this.onChange = fn; } /** * @param {?} fn * @return {?} */ registerOnTouched(fn) { this.onTouched = fn; } /** * @param {?} isDisabled * @return {?} */ setDisabledState(isDisabled) { this.disabled = isDisabled; } /** * @param {?} step * @return {?} */ changeHour(step) { this.model.changeHour(step); this.propagateModelChange(); } /** * @param {?} step * @return {?} */ changeMinute(step) { this.model.changeMinute(step); this.propagateModelChange(); } /** * @param {?} step * @return {?} */ changeSecond(step) { this.model.changeSecond(step); this.propagateModelChange(); } /** * @param {?} newVal * @return {?} */ updateHour(newVal) { /** @type {?} */ const isPM = this.model.hour >= 12; /** @type {?} */ const enteredHour = toInteger(newVal); if (this.meridian && (isPM && enteredHour < 12 || !isPM && enteredHour === 12)) { this.model.updateHour(enteredHour + 12); } else { this.model.updateHour(enteredHour); } this.propagateModelChange(); } /** * @param {?} newVal * @return {?} */ updateMinute(newVal) { this.model.updateMinute(toInteger(newVal)); this.propagateModelChange(); } /** * @param {?} newVal * @return {?} */ updateSecond(newVal) { this.model.updateSecond(toInteger(newVal)); this.propagateModelChange(); } /** * @return {?} */ toggleMeridian() { if (this.meridian) { this.changeHour(12); } } /** * @param {?} input * @return {?} */ formatInput(input) { input.value = input.value.replace(FILTER_REGEX, ''); } /** * @param {?} value * @return {?} */ formatHour(value) { if (isNumber(value)) { if (this.meridian) { return padNumber(value % 12 === 0 ? 12 : value % 12); } else { return padNumber(value % 24); } } else { return padNumber(NaN); } } /** * @param {?} value * @return {?} */ formatMinSec(value) { return padNumber(value); } /** * @return {?} */ get isSmallSize() { return this.size === 'small'; } /** * @return {?} */ get isLargeSize() { return this.size === 'large'; } /** * @param {?} changes * @return {?} */ ngOnChanges(changes) { if (changes['seconds'] && !this.seconds && this.model && !isNumber(this.model.second)) { this.model.second = 0; this.propagateModelChange(false); } } /** * @private * @param {?=} touched * @return {?} */ propagateModelChange(touched = true) { if (touched) { this.onTouched(); } if (this.model.isValid(this.seconds)) { this.onChange(this._ngbTimeAdapter.toModel({ hour: this.model.hour, minute: this.model.minute, second: this.model.second })); } else { this.onChange(this._ngbTimeAdapter.toModel(null)); } } } NgbTimepicker.decorators = [ { type: Component, args: [{ selector: 'ngb-timepicker', encapsulation: ViewEncapsulation.None, template: `
:
:
`, providers: [NGB_TIMEPICKER_VALUE_ACCESSOR], styles: ["ngb-timepicker{font-size:1rem}.ngb-tp{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center}.ngb-tp-input-container{width:4em}.ngb-tp-chevron::before{border-style:solid;border-width:.29em .29em 0 0;content:\"\";display:inline-block;height:.69em;left:.05em;position:relative;top:.15em;-webkit-transform:rotate(-45deg);transform:rotate(-45deg);vertical-align:middle;width:.69em}.ngb-tp-chevron.bottom:before{top:-.3em;-webkit-transform:rotate(135deg);transform:rotate(135deg)}.ngb-tp-input{text-align:center}.ngb-tp-hour,.ngb-tp-meridian,.ngb-tp-minute,.ngb-tp-second{display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;-ms-flex-align:center;align-items:center;-ms-flex-pack:distribute;justify-content:space-around}.ngb-tp-spacer{width:1em;text-align:center}"] }] } ]; /** @nocollapse */ NgbTimepicker.ctorParameters = () => [ { type: NgbTimepickerConfig }, { type: NgbTimeAdapter }, { type: ChangeDetectorRef }, { type: NgbTimepickerI18n } ]; NgbTimepicker.propDecorators = { meridian: [{ type: Input }], spinners: [{ type: Input }], seconds: [{ type: Input }], hourStep: [{ type: Input }], minuteStep: [{ type: Input }], secondStep: [{ type: Input }], readonlyInputs: [{ type: Input }], size: [{ type: Input }] }; /** * @fileoverview added by tsickle * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ class NgbTimepickerModule { } NgbTimepickerModule.decorators = [ { type: NgModule, args: [{ declarations: [NgbTimepicker], exports: [NgbTimepicker], imports: [CommonModule] },] } ]; /** * @fileoverview added by tsickle * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ /** * Configuration service for the NgbToast component. You can inject this service, typically in your root component, * and customize the values of its properties in order to provide default values for all the toasts used in the * application. * * \@since 5.0.0 */ class NgbToastConfig { constructor() { this.autohide = true; this.delay = 500; this.ariaLive = 'polite'; } } NgbToastConfig.decorators = [ { type: Injectable, args: [{ providedIn: 'root' },] } ]; /** @nocollapse */ NgbToastConfig.ngInjectableDef = ɵɵdefineInjectable({ factory: function NgbToastConfig_Factory() { return new NgbToastConfig(); }, token: NgbToastConfig, providedIn: "root" }); /** * @fileoverview added by tsickle * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ /** * This directive allows the usage of HTML markup or other directives * inside of the toast's header. * * \@since 5.0.0 */ class NgbToastHeader { } NgbToastHeader.decorators = [ { type: Directive, args: [{ selector: '[ngbToastHeader]' },] } ]; /** * Toasts provide feedback messages as notifications to the user. * Goal is to mimic the push notifications available both on mobile and desktop operating systems. * * \@since 5.0.0 */ class NgbToast { /** * @param {?} ariaLive * @param {?} config */ constructor(ariaLive, config) { this.ariaLive = ariaLive; /** * A template like `` can be * used in the projected content to allow markup usage. */ this.contentHeaderTpl = null; /** * An event fired immediately when toast's `hide()` method has been called. * It can only occur in 2 different scenarios: * - `autohide` timeout fires * - user clicks on a closing cross (×) * * Additionally this output is purely informative. The toast won't disappear. It's up to the user to take care of * that. */ this.hideOutput = new EventEmitter(); if (this.ariaLive == null) { this.ariaLive = config.ariaLive; } this.delay = config.delay; this.autohide = config.autohide; } /** * @return {?} */ ngAfterContentInit() { this._init(); } /** * @param {?} changes * @return {?} */ ngOnChanges(changes) { if ('autohide' in changes) { this._clearTimeout(); this._init(); } } /** * @return {?} */ hide() { this._clearTimeout(); this.hideOutput.emit(); } /** * @private * @return {?} */ _init() { if (this.autohide && !this._timeoutID) { this._timeoutID = setTimeout((/** * @return {?} */ () => this.hide()), this.delay); } } /** * @private * @return {?} */ _clearTimeout() { if (this._timeoutID) { clearTimeout(this._timeoutID); this._timeoutID = null; } } } NgbToast.decorators = [ { type: Component, args: [{ selector: 'ngb-toast', exportAs: 'ngbToast', encapsulation: ViewEncapsulation.None, host: { 'role': 'alert', '[attr.aria-live]': 'ariaLive', 'aria-atomic': 'true', '[class.toast]': 'true', '[class.show]': 'true', }, template: ` {{header}}
`, styles: [".ngb-toasts{position:fixed;top:0;right:0;margin:.5em;z-index:1200}ngb-toast .toast-header .close{margin-left:auto;margin-bottom:.25rem}"] }] } ]; /** @nocollapse */ NgbToast.ctorParameters = () => [ { type: String, decorators: [{ type: Attribute, args: ['aria-live',] }] }, { type: NgbToastConfig } ]; NgbToast.propDecorators = { delay: [{ type: Input }], autohide: [{ type: Input }], header: [{ type: Input }], contentHeaderTpl: [{ type: ContentChild, args: [NgbToastHeader, { read: TemplateRef, static: true },] }], hideOutput: [{ type: Output, args: ['hide',] }] }; /** * @fileoverview added by tsickle * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ class NgbToastModule { } NgbToastModule.decorators = [ { type: NgModule, args: [{ declarations: [NgbToast, NgbToastHeader], imports: [CommonModule], exports: [NgbToast, NgbToastHeader] },] } ]; /** * @fileoverview added by tsickle * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ /** * A configuration service for the [`NgbTooltip`](#/components/tooltip/api#NgbTooltip) component. * * You can inject this service, typically in your root component, and customize the values of its properties in * order to provide default values for all the tooltips used in the application. */ class NgbTooltipConfig { constructor() { this.autoClose = true; this.placement = 'auto'; this.triggers = 'hover focus'; this.disableTooltip = false; this.openDelay = 0; this.closeDelay = 0; } } NgbTooltipConfig.decorators = [ { type: Injectable, args: [{ providedIn: 'root' },] } ]; /** @nocollapse */ NgbTooltipConfig.ngInjectableDef = ɵɵdefineInjectable({ factory: function NgbTooltipConfig_Factory() { return new NgbTooltipConfig(); }, token: NgbTooltipConfig, providedIn: "root" }); /** * @fileoverview added by tsickle * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ /** @type {?} */ let nextId$5 = 0; class NgbTooltipWindow { } NgbTooltipWindow.decorators = [ { type: Component, args: [{ selector: 'ngb-tooltip-window', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, host: { '[class]': '"tooltip show" + (tooltipClass ? " " + tooltipClass : "")', 'role': 'tooltip', '[id]': 'id' }, template: `
`, styles: ["ngb-tooltip-window.bs-tooltip-bottom .arrow,ngb-tooltip-window.bs-tooltip-top .arrow{left:calc(50% - .4rem)}ngb-tooltip-window.bs-tooltip-bottom-left .arrow,ngb-tooltip-window.bs-tooltip-top-left .arrow{left:1em}ngb-tooltip-window.bs-tooltip-bottom-right .arrow,ngb-tooltip-window.bs-tooltip-top-right .arrow{left:auto;right:.8rem}ngb-tooltip-window.bs-tooltip-left .arrow,ngb-tooltip-window.bs-tooltip-right .arrow{top:calc(50% - .4rem)}ngb-tooltip-window.bs-tooltip-left-top .arrow,ngb-tooltip-window.bs-tooltip-right-top .arrow{top:.4rem}ngb-tooltip-window.bs-tooltip-left-bottom .arrow,ngb-tooltip-window.bs-tooltip-right-bottom .arrow{top:auto;bottom:.4rem}"] }] } ]; NgbTooltipWindow.propDecorators = { id: [{ type: Input }], tooltipClass: [{ type: Input }] }; /** * A lightweight and extensible directive for fancy tooltip creation. */ class NgbTooltip { /** * @param {?} _elementRef * @param {?} _renderer * @param {?} injector * @param {?} componentFactoryResolver * @param {?} viewContainerRef * @param {?} config * @param {?} _ngZone * @param {?} _document * @param {?} _changeDetector * @param {?} applicationRef */ constructor(_elementRef, _renderer, injector, componentFactoryResolver, viewContainerRef, config, _ngZone, _document, _changeDetector, applicationRef) { this._elementRef = _elementRef; this._renderer = _renderer; this._ngZone = _ngZone; this._document = _document; this._changeDetector = _changeDetector; /** * An event emitted when the tooltip is shown. Contains no payload. */ this.shown = new EventEmitter(); /** * An event emitted when the popover is hidden. Contains no payload. */ this.hidden = new EventEmitter(); this._ngbTooltipWindowId = `ngb-tooltip-${nextId$5++}`; this.autoClose = config.autoClose; this.placement = config.placement; this.triggers = config.triggers; this.container = config.container; this.disableTooltip = config.disableTooltip; this.tooltipClass = config.tooltipClass; this.openDelay = config.openDelay; this.closeDelay = config.closeDelay; this._popupService = new PopupService(NgbTooltipWindow, injector, viewContainerRef, _renderer, componentFactoryResolver, applicationRef); this._zoneSubscription = _ngZone.onStable.subscribe((/** * @return {?} */ () => { if (this._windowRef) { positionElements(this._elementRef.nativeElement, this._windowRef.location.nativeElement, this.placement, this.container === 'body', 'bs-tooltip'); } })); } /** * The string content or a `TemplateRef` for the content to be displayed in the tooltip. * * If the content if falsy, the tooltip won't open. * @param {?} value * @return {?} */ set ngbTooltip(value) { this._ngbTooltip = value; if (!value && this._windowRef) { this.close(); } } /** * @return {?} */ get ngbTooltip() { return this._ngbTooltip; } /** * Opens the tooltip. * * This is considered to be a "manual" triggering. * The `context` is an optional value to be injected into the tooltip template when it is created. * @param {?=} context * @return {?} */ open(context) { if (!this._windowRef && this._ngbTooltip && !this.disableTooltip) { this._windowRef = this._popupService.open(this._ngbTooltip, context); this._windowRef.instance.tooltipClass = this.tooltipClass; this._windowRef.instance.id = this._ngbTooltipWindowId; this._renderer.setAttribute(this._elementRef.nativeElement, 'aria-describedby', this._ngbTooltipWindowId); if (this.container === 'body') { this._document.querySelector(this.container).appendChild(this._windowRef.location.nativeElement); } // We need to detect changes, because we don't know where .open() might be called from. // Ex. opening tooltip from one of lifecycle hooks that run after the CD // (say from ngAfterViewInit) will result in 'ExpressionHasChanged' exception this._windowRef.changeDetectorRef.detectChanges(); // We need to mark for check, because tooltip won't work inside the OnPush component. // Ex. when we use expression like `{{ tooltip.isOpen() : 'opened' : 'closed' }}` // inside the template of an OnPush component and we change the tooltip from // open -> closed, the expression in question won't be updated unless we explicitly // mark the parent component to be checked. this._windowRef.changeDetectorRef.markForCheck(); ngbAutoClose(this._ngZone, this._document, this.autoClose, (/** * @return {?} */ () => this.close()), this.hidden, [this._windowRef.location.nativeElement]); this.shown.emit(); } } /** * Closes the tooltip. * * This is considered to be a "manual" triggering of the tooltip. * @return {?} */ close() { if (this._windowRef != null) { this._renderer.removeAttribute(this._elementRef.nativeElement, 'aria-describedby'); this._popupService.close(); this._windowRef = null; this.hidden.emit(); this._changeDetector.markForCheck(); } } /** * Toggles the tooltip. * * This is considered to be a "manual" triggering of the tooltip. * @return {?} */ toggle() { if (this._windowRef) { this.close(); } else { this.open(); } } /** * Returns `true`, if the popover is currently shown. * @return {?} */ isOpen() { return this._windowRef != null; } /** * @return {?} */ ngOnInit() { this._unregisterListenersFn = listenToTriggers(this._renderer, this._elementRef.nativeElement, this.triggers, this.isOpen.bind(this), this.open.bind(this), this.close.bind(this), +this.openDelay, +this.closeDelay); } /** * @param {?} __0 * @return {?} */ ngOnChanges({ tooltipClass }) { if (tooltipClass && this.isOpen()) { this._windowRef.instance.tooltipClass = tooltipClass.currentValue; } } /** * @return {?} */ ngOnDestroy() { this.close(); // This check is needed as it might happen that ngOnDestroy is called before ngOnInit // under certain conditions, see: https://github.com/ng-bootstrap/ng-bootstrap/issues/2199 if (this._unregisterListenersFn) { this._unregisterListenersFn(); } this._zoneSubscription.unsubscribe(); } } NgbTooltip.decorators = [ { type: Directive, args: [{ selector: '[ngbTooltip]', exportAs: 'ngbTooltip' },] } ]; /** @nocollapse */ NgbTooltip.ctorParameters = () => [ { type: ElementRef }, { type: Renderer2 }, { type: Injector }, { type: ComponentFactoryResolver }, { type: ViewContainerRef }, { type: NgbTooltipConfig }, { type: NgZone }, { type: undefined, decorators: [{ type: Inject, args: [DOCUMENT,] }] }, { type: ChangeDetectorRef }, { type: ApplicationRef } ]; NgbTooltip.propDecorators = { autoClose: [{ type: Input }], placement: [{ type: Input }], triggers: [{ type: Input }], container: [{ type: Input }], disableTooltip: [{ type: Input }], tooltipClass: [{ type: Input }], openDelay: [{ type: Input }], closeDelay: [{ type: Input }], shown: [{ type: Output }], hidden: [{ type: Output }], ngbTooltip: [{ type: Input }] }; /** * @fileoverview added by tsickle * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ class NgbTooltipModule { } NgbTooltipModule.decorators = [ { type: NgModule, args: [{ declarations: [NgbTooltip, NgbTooltipWindow], exports: [NgbTooltip], entryComponents: [NgbTooltipWindow] },] } ]; /** * @fileoverview added by tsickle * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ /** * A component that helps with text highlighting. * * If splits the `result` text into parts that contain the searched `term` and generates the HTML markup to simplify * highlighting: * * Ex. `result="Alaska"` and `term="as"` will produce `Alaska`. */ class NgbHighlight { constructor() { /** * The CSS class for `` elements wrapping the `term` inside the `result`. */ this.highlightClass = 'ngb-highlight'; } /** * @param {?} changes * @return {?} */ ngOnChanges(changes) { /** @type {?} */ const result = toString(this.result); /** @type {?} */ const terms = Array.isArray(this.term) ? this.term : [this.term]; /** @type {?} */ const escapedTerms = terms.map((/** * @param {?} term * @return {?} */ term => regExpEscape(toString(term)))).filter((/** * @param {?} term * @return {?} */ term => term)); this.parts = escapedTerms.length ? result.split(new RegExp(`(${escapedTerms.join('|')})`, 'gmi')) : [result]; } } NgbHighlight.decorators = [ { type: Component, args: [{ selector: 'ngb-highlight', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, template: `` + `{{part}}{{part}}` + ``, styles: [".ngb-highlight{font-weight:700}"] }] } ]; NgbHighlight.propDecorators = { highlightClass: [{ type: Input }], result: [{ type: Input }], term: [{ type: Input }] }; /** * @fileoverview added by tsickle * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ class NgbTypeaheadWindow { constructor() { this.activeIdx = 0; /** * Flag indicating if the first row should be active initially */ this.focusFirst = true; /** * A function used to format a given result before display. This function should return a formatted string without any * HTML markup */ this.formatter = toString; /** * Event raised when user selects a particular result row */ this.selectEvent = new EventEmitter(); this.activeChangeEvent = new EventEmitter(); } /** * @return {?} */ hasActive() { return this.activeIdx > -1 && this.activeIdx < this.results.length; } /** * @return {?} */ getActive() { return this.results[this.activeIdx]; } /** * @param {?} activeIdx * @return {?} */ markActive(activeIdx) { this.activeIdx = activeIdx; this._activeChanged(); } /** * @return {?} */ next() { if (this.activeIdx === this.results.length - 1) { this.activeIdx = this.focusFirst ? (this.activeIdx + 1) % this.results.length : -1; } else { this.activeIdx++; } this._activeChanged(); } /** * @return {?} */ prev() { if (this.activeIdx < 0) { this.activeIdx = this.results.length - 1; } else if (this.activeIdx === 0) { this.activeIdx = this.focusFirst ? this.results.length - 1 : -1; } else { this.activeIdx--; } this._activeChanged(); } /** * @return {?} */ resetActive() { this.activeIdx = this.focusFirst ? 0 : -1; this._activeChanged(); } /** * @param {?} item * @return {?} */ select(item) { this.selectEvent.emit(item); } /** * @return {?} */ ngOnInit() { this.resetActive(); } /** * @private * @return {?} */ _activeChanged() { this.activeChangeEvent.emit(this.activeIdx >= 0 ? this.id + '-' + this.activeIdx : undefined); } } NgbTypeaheadWindow.decorators = [ { type: Component, args: [{ selector: 'ngb-typeahead-window', exportAs: 'ngbTypeaheadWindow', encapsulation: ViewEncapsulation.None, host: { '(mousedown)': '$event.preventDefault()', 'class': 'dropdown-menu show', 'role': 'listbox', '[id]': 'id' }, template: ` ` }] } ]; NgbTypeaheadWindow.propDecorators = { id: [{ type: Input }], focusFirst: [{ type: Input }], results: [{ type: Input }], term: [{ type: Input }], formatter: [{ type: Input }], resultTemplate: [{ type: Input }], selectEvent: [{ type: Output, args: ['select',] }], activeChangeEvent: [{ type: Output, args: ['activeChange',] }] }; /** * @fileoverview added by tsickle * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ /** @type {?} */ const ARIA_LIVE_DELAY = new InjectionToken('live announcer delay', { providedIn: 'root', factory: ARIA_LIVE_DELAY_FACTORY }); /** * @return {?} */ function ARIA_LIVE_DELAY_FACTORY() { return 100; } /** * @param {?} document * @param {?=} lazyCreate * @return {?} */ function getLiveElement(document, lazyCreate = false) { /** @type {?} */ let element = (/** @type {?} */ (document.body.querySelector('#ngb-live'))); if (element == null && lazyCreate) { element = document.createElement('div'); element.setAttribute('id', 'ngb-live'); element.setAttribute('aria-live', 'polite'); element.setAttribute('aria-atomic', 'true'); element.classList.add('sr-only'); document.body.appendChild(element); } return element; } class Live { /** * @param {?} _document * @param {?} _delay */ constructor(_document, _delay) { this._document = _document; this._delay = _delay; } /** * @return {?} */ ngOnDestroy() { /** @type {?} */ const element = getLiveElement(this._document); if (element) { element.parentElement.removeChild(element); } } /** * @param {?} message * @return {?} */ say(message) { /** @type {?} */ const element = getLiveElement(this._document, true); /** @type {?} */ const delay = this._delay; element.textContent = ''; /** @type {?} */ const setText = (/** * @return {?} */ () => element.textContent = message); if (delay === null) { setText(); } else { setTimeout(setText, delay); } } } Live.decorators = [ { type: Injectable, args: [{ providedIn: 'root' },] } ]; /** @nocollapse */ Live.ctorParameters = () => [ { type: undefined, decorators: [{ type: Inject, args: [DOCUMENT,] }] }, { type: undefined, decorators: [{ type: Inject, args: [ARIA_LIVE_DELAY,] }] } ]; /** @nocollapse */ Live.ngInjectableDef = ɵɵdefineInjectable({ factory: function Live_Factory() { return new Live(ɵɵinject(DOCUMENT), ɵɵinject(ARIA_LIVE_DELAY)); }, token: Live, providedIn: "root" }); /** * @fileoverview added by tsickle * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ /** * A configuration service for the [`NgbTypeahead`](#/components/typeahead/api#NgbTypeahead) component. * * You can inject this service, typically in your root component, and customize the values of its properties in * order to provide default values for all the typeaheads used in the application. */ class NgbTypeaheadConfig { constructor() { this.editable = true; this.focusFirst = true; this.showHint = false; this.placement = ['bottom-left', 'bottom-right', 'top-left', 'top-right']; } } NgbTypeaheadConfig.decorators = [ { type: Injectable, args: [{ providedIn: 'root' },] } ]; /** @nocollapse */ NgbTypeaheadConfig.ngInjectableDef = ɵɵdefineInjectable({ factory: function NgbTypeaheadConfig_Factory() { return new NgbTypeaheadConfig(); }, token: NgbTypeaheadConfig, providedIn: "root" }); /** * @fileoverview added by tsickle * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ /** @type {?} */ const NGB_TYPEAHEAD_VALUE_ACCESSOR = { provide: NG_VALUE_ACCESSOR, useExisting: forwardRef((/** * @return {?} */ () => NgbTypeahead)), multi: true }; /** @type {?} */ let nextWindowId = 0; /** * A directive providing a simple way of creating powerful typeaheads from any text input. */ class NgbTypeahead { /** * @param {?} _elementRef * @param {?} viewContainerRef * @param {?} _renderer * @param {?} injector * @param {?} componentFactoryResolver * @param {?} config * @param {?} ngZone * @param {?} _live * @param {?} _document * @param {?} _ngZone * @param {?} _changeDetector * @param {?} applicationRef */ constructor(_elementRef, viewContainerRef, _renderer, injector, componentFactoryResolver, config, ngZone, _live, _document, _ngZone, _changeDetector, applicationRef) { this._elementRef = _elementRef; this._renderer = _renderer; this._live = _live; this._document = _document; this._ngZone = _ngZone; this._changeDetector = _changeDetector; this._closed$ = new Subject(); /** * The value for the `autocomplete` attribute for the `` element. * * Defaults to `"off"` to disable the native browser autocomplete, but you can override it if necessary. * * \@since 2.1.0 */ this.autocomplete = 'off'; /** * The preferred placement of the typeahead. * * Possible values are `"top"`, `"top-left"`, `"top-right"`, `"bottom"`, `"bottom-left"`, * `"bottom-right"`, `"left"`, `"left-top"`, `"left-bottom"`, `"right"`, `"right-top"`, * `"right-bottom"` * * Accepts an array of strings or a string with space separated possible values. * * The default order of preference is `"bottom-left bottom-right top-left top-right"` * * Please see the [positioning overview](#/positioning) for more details. */ this.placement = 'bottom-left'; /** * An event emitted right before an item is selected from the result list. * * Event payload is of type [`NgbTypeaheadSelectItemEvent`](#/components/typeahead/api#NgbTypeaheadSelectItemEvent). */ this.selectItem = new EventEmitter(); this.popupId = `ngb-typeahead-${nextWindowId++}`; this._onTouched = (/** * @return {?} */ () => { }); this._onChange = (/** * @param {?} _ * @return {?} */ (_) => { }); this.container = config.container; this.editable = config.editable; this.focusFirst = config.focusFirst; this.showHint = config.showHint; this.placement = config.placement; this._valueChanges = fromEvent(_elementRef.nativeElement, 'input') .pipe(map((/** * @param {?} $event * @return {?} */ $event => ((/** @type {?} */ ($event.target))).value))); this._resubscribeTypeahead = new BehaviorSubject(null); this._popupService = new PopupService(NgbTypeaheadWindow, injector, viewContainerRef, _renderer, componentFactoryResolver, applicationRef); this._zoneSubscription = ngZone.onStable.subscribe((/** * @return {?} */ () => { if (this.isPopupOpen()) { positionElements(this._elementRef.nativeElement, this._windowRef.location.nativeElement, this.placement, this.container === 'body'); } })); } /** * @return {?} */ ngOnInit() { /** @type {?} */ const inputValues$ = this._valueChanges.pipe(tap((/** * @param {?} value * @return {?} */ value => { this._inputValueBackup = this.showHint ? value : null; this._onChange(this.editable ? value : undefined); }))); /** @type {?} */ const results$ = inputValues$.pipe(this.ngbTypeahead); /** @type {?} */ const userInput$ = this._resubscribeTypeahead.pipe(switchMap((/** * @return {?} */ () => results$))); this._subscription = this._subscribeToUserInput(userInput$); } /** * @return {?} */ ngOnDestroy() { this._closePopup(); this._unsubscribeFromUserInput(); this._zoneSubscription.unsubscribe(); } /** * @param {?} fn * @return {?} */ registerOnChange(fn) { this._onChange = fn; } /** * @param {?} fn * @return {?} */ registerOnTouched(fn) { this._onTouched = fn; } /** * @param {?} value * @return {?} */ writeValue(value) { this._writeInputValue(this._formatItemForInput(value)); if (this.showHint) { this._inputValueBackup = value; } } /** * @param {?} isDisabled * @return {?} */ setDisabledState(isDisabled) { this._renderer.setProperty(this._elementRef.nativeElement, 'disabled', isDisabled); } /** * Dismisses typeahead popup window * @return {?} */ dismissPopup() { if (this.isPopupOpen()) { this._resubscribeTypeahead.next(null); this._closePopup(); if (this.showHint && this._inputValueBackup !== null) { this._writeInputValue(this._inputValueBackup); } this._changeDetector.markForCheck(); } } /** * Returns true if the typeahead popup window is displayed * @return {?} */ isPopupOpen() { return this._windowRef != null; } /** * @return {?} */ handleBlur() { this._resubscribeTypeahead.next(null); this._onTouched(); } /** * @param {?} event * @return {?} */ handleKeyDown(event) { if (!this.isPopupOpen()) { return; } // tslint:disable-next-line:deprecation switch (event.which) { case Key.ArrowDown: event.preventDefault(); this._windowRef.instance.next(); this._showHint(); break; case Key.ArrowUp: event.preventDefault(); this._windowRef.instance.prev(); this._showHint(); break; case Key.Enter: case Key.Tab: /** @type {?} */ const result = this._windowRef.instance.getActive(); if (isDefined(result)) { event.preventDefault(); event.stopPropagation(); this._selectResult(result); } this._closePopup(); break; } } /** * @private * @return {?} */ _openPopup() { if (!this.isPopupOpen()) { this._inputValueBackup = this._elementRef.nativeElement.value; this._windowRef = this._popupService.open(); this._windowRef.instance.id = this.popupId; this._windowRef.instance.selectEvent.subscribe((/** * @param {?} result * @return {?} */ (result) => this._selectResultClosePopup(result))); this._windowRef.instance.activeChangeEvent.subscribe((/** * @param {?} activeId * @return {?} */ (activeId) => this.activeDescendant = activeId)); if (this.container === 'body') { window.document.querySelector(this.container).appendChild(this._windowRef.location.nativeElement); } this._changeDetector.markForCheck(); ngbAutoClose(this._ngZone, this._document, 'outside', (/** * @return {?} */ () => this.dismissPopup()), this._closed$, [this._elementRef.nativeElement, this._windowRef.location.nativeElement]); } } /** * @private * @return {?} */ _closePopup() { this._closed$.next(); this._popupService.close(); this._windowRef = null; this.activeDescendant = undefined; } /** * @private * @param {?} result * @return {?} */ _selectResult(result) { /** @type {?} */ let defaultPrevented = false; this.selectItem.emit({ item: result, preventDefault: (/** * @return {?} */ () => { defaultPrevented = true; }) }); this._resubscribeTypeahead.next(null); if (!defaultPrevented) { this.writeValue(result); this._onChange(result); } } /** * @private * @param {?} result * @return {?} */ _selectResultClosePopup(result) { this._selectResult(result); this._closePopup(); } /** * @private * @return {?} */ _showHint() { if (this.showHint && this._windowRef.instance.hasActive() && this._inputValueBackup != null) { /** @type {?} */ const userInputLowerCase = this._inputValueBackup.toLowerCase(); /** @type {?} */ const formattedVal = this._formatItemForInput(this._windowRef.instance.getActive()); if (userInputLowerCase === formattedVal.substr(0, this._inputValueBackup.length).toLowerCase()) { this._writeInputValue(this._inputValueBackup + formattedVal.substr(this._inputValueBackup.length)); this._elementRef.nativeElement['setSelectionRange'].apply(this._elementRef.nativeElement, [this._inputValueBackup.length, formattedVal.length]); } else { this._writeInputValue(formattedVal); } } } /** * @private * @param {?} item * @return {?} */ _formatItemForInput(item) { return item != null && this.inputFormatter ? this.inputFormatter(item) : toString(item); } /** * @private * @param {?} value * @return {?} */ _writeInputValue(value) { this._renderer.setProperty(this._elementRef.nativeElement, 'value', toString(value)); } /** * @private * @param {?} userInput$ * @return {?} */ _subscribeToUserInput(userInput$) { return userInput$.subscribe((/** * @param {?} results * @return {?} */ (results) => { if (!results || results.length === 0) { this._closePopup(); } else { this._openPopup(); this._windowRef.instance.focusFirst = this.focusFirst; this._windowRef.instance.results = results; this._windowRef.instance.term = this._elementRef.nativeElement.value; if (this.resultFormatter) { this._windowRef.instance.formatter = this.resultFormatter; } if (this.resultTemplate) { this._windowRef.instance.resultTemplate = this.resultTemplate; } this._windowRef.instance.resetActive(); // The observable stream we are subscribing to might have async steps // and if a component containing typeahead is using the OnPush strategy // the change detection turn wouldn't be invoked automatically. this._windowRef.changeDetectorRef.detectChanges(); this._showHint(); } // live announcer /** @type {?} */ const count = results ? results.length : 0; this._live.say(count === 0 ? 'No results available' : `${count} result${count === 1 ? '' : 's'} available`); })); } /** * @private * @return {?} */ _unsubscribeFromUserInput() { if (this._subscription) { this._subscription.unsubscribe(); } this._subscription = null; } } NgbTypeahead.decorators = [ { type: Directive, args: [{ selector: 'input[ngbTypeahead]', exportAs: 'ngbTypeahead', host: { '(blur)': 'handleBlur()', '[class.open]': 'isPopupOpen()', '(keydown)': 'handleKeyDown($event)', '[autocomplete]': 'autocomplete', 'autocapitalize': 'off', 'autocorrect': 'off', 'role': 'combobox', 'aria-multiline': 'false', '[attr.aria-autocomplete]': 'showHint ? "both" : "list"', '[attr.aria-activedescendant]': 'activeDescendant', '[attr.aria-owns]': 'isPopupOpen() ? popupId : null', '[attr.aria-expanded]': 'isPopupOpen()' }, providers: [NGB_TYPEAHEAD_VALUE_ACCESSOR] },] } ]; /** @nocollapse */ NgbTypeahead.ctorParameters = () => [ { type: ElementRef }, { type: ViewContainerRef }, { type: Renderer2 }, { type: Injector }, { type: ComponentFactoryResolver }, { type: NgbTypeaheadConfig }, { type: NgZone }, { type: Live }, { type: undefined, decorators: [{ type: Inject, args: [DOCUMENT,] }] }, { type: NgZone }, { type: ChangeDetectorRef }, { type: ApplicationRef } ]; NgbTypeahead.propDecorators = { autocomplete: [{ type: Input }], container: [{ type: Input }], editable: [{ type: Input }], focusFirst: [{ type: Input }], inputFormatter: [{ type: Input }], ngbTypeahead: [{ type: Input }], resultFormatter: [{ type: Input }], resultTemplate: [{ type: Input }], showHint: [{ type: Input }], placement: [{ type: Input }], selectItem: [{ type: Output }] }; /** * @fileoverview added by tsickle * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ class NgbTypeaheadModule { } NgbTypeaheadModule.decorators = [ { type: NgModule, args: [{ declarations: [NgbTypeahead, NgbHighlight, NgbTypeaheadWindow], exports: [NgbTypeahead, NgbHighlight], imports: [CommonModule], entryComponents: [NgbTypeaheadWindow] },] } ]; /** * @fileoverview added by tsickle * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ /** @type {?} */ const NGB_MODULES = [ NgbAccordionModule, NgbAlertModule, NgbButtonsModule, NgbCarouselModule, NgbCollapseModule, NgbDatepickerModule, NgbDropdownModule, NgbModalModule, NgbNavModule, NgbPaginationModule, NgbPopoverModule, NgbProgressbarModule, NgbRatingModule, NgbTabsetModule, NgbTimepickerModule, NgbToastModule, NgbTooltipModule, NgbTypeaheadModule ]; class NgbModule { } NgbModule.decorators = [ { type: NgModule, args: [{ imports: NGB_MODULES, exports: NGB_MODULES },] } ]; export { ModalDismissReasons, NgbAccordion, NgbAccordionConfig, NgbAccordionModule, NgbActiveModal, NgbAlert, NgbAlertConfig, NgbAlertModule, NgbButtonLabel, NgbButtonsModule, NgbCalendar, NgbCalendarGregorian, NgbCalendarHebrew, NgbCalendarIslamicCivil, NgbCalendarIslamicUmalqura, NgbCalendarPersian, NgbCarousel, NgbCarouselConfig, NgbCarouselModule, NgbCheckBox, NgbCollapse, NgbCollapseModule, NgbDate, NgbDateAdapter, NgbDateNativeAdapter, NgbDateNativeUTCAdapter, NgbDateParserFormatter, NgbDatepicker, NgbDatepickerConfig, NgbDatepickerI18n, NgbDatepickerI18nHebrew, NgbDatepickerKeyboardService, NgbDatepickerModule, NgbDropdown, NgbDropdownAnchor, NgbDropdownConfig, NgbDropdownItem, NgbDropdownMenu, NgbDropdownModule, NgbDropdownToggle, NgbHighlight, NgbInputDatepicker, NgbInputDatepickerConfig, NgbModal, NgbModalConfig, NgbModalModule, NgbModalRef, NgbModule, NgbNav, NgbNavConfig, NgbNavContent, NgbNavItem, NgbNavLink, NgbNavModule, NgbNavOutlet, NgbNavbar, NgbPagination, NgbPaginationConfig, NgbPaginationEllipsis, NgbPaginationFirst, NgbPaginationLast, NgbPaginationModule, NgbPaginationNext, NgbPaginationNumber, NgbPaginationPrevious, NgbPanel, NgbPanelContent, NgbPanelHeader, NgbPanelTitle, NgbPanelToggle, NgbPopover, NgbPopoverConfig, NgbPopoverModule, NgbProgressbar, NgbProgressbarConfig, NgbProgressbarModule, NgbRadio, NgbRadioGroup, NgbRating, NgbRatingConfig, NgbRatingModule, NgbSlide, NgbSlideEventDirection, NgbSlideEventSource, NgbTab, NgbTabContent, NgbTabTitle, NgbTabset, NgbTabsetConfig, NgbTabsetModule, NgbTimeAdapter, NgbTimepicker, NgbTimepickerConfig, NgbTimepickerI18n, NgbTimepickerModule, NgbToast, NgbToastConfig, NgbToastHeader, NgbToastModule, NgbTooltip, NgbTooltipConfig, NgbTooltipModule, NgbTypeahead, NgbTypeaheadConfig, NgbTypeaheadModule, NGB_CAROUSEL_DIRECTIVES as ɵa, NGB_DATEPICKER_CALENDAR_FACTORY as ɵb, Live as ɵba, NgbCalendarHijri as ɵbb, ContentRef as ɵbc, NgbDatepickerMonthView as ɵc, NgbDatepickerDayView as ɵd, NgbDatepickerNavigation as ɵe, NgbDatepickerNavigationSelect as ɵf, NGB_DATEPICKER_18N_FACTORY as ɵg, NgbDatepickerI18nDefault as ɵh, NGB_DATEPICKER_DATE_ADAPTER_FACTORY as ɵi, NgbDateStructAdapter as ɵj, NGB_DATEPICKER_PARSER_FORMATTER_FACTORY as ɵk, NgbDateISOParserFormatter as ɵl, NgbPopoverWindow as ɵm, NGB_DATEPICKER_TIME_ADAPTER_FACTORY as ɵn, NgbTimeStructAdapter as ɵo, NGB_TIMEPICKER_I18N_FACTORY as ɵp, NgbTimepickerI18nDefault as ɵq, NgbTooltipWindow as ɵr, NgbTypeaheadWindow as ɵs, NgbDatepickerService as ɵt, NgbModalBackdrop as ɵu, NgbModalWindow as ɵv, NgbModalStack as ɵw, ScrollBar as ɵx, ARIA_LIVE_DELAY as ɵy, ARIA_LIVE_DELAY_FACTORY as ɵz }; //# sourceMappingURL=ng-bootstrap.js.map