UNPKG

ngx-bootstrap

Version:
4,068 lines 218 kB
import * as i0 from '@angular/core';
import { Injectable, EventEmitter, Output, Input, ChangeDetectionStrategy, Component, HostBinding, ViewChild, Directive, forwardRef, HostListener, Host, NgModule } from '@angular/core';
import { filter, map, take, takeUntil, distinctUntilChanged } from 'rxjs/operators';
import { isFirstDayOfWeek, getDay, shiftDate, isBefore, endOf, isAfter, startOf, isArray, isSame, getFirstDayOfMonth, formatDate, getLocale, isSameMonth, isSameDay, isDisabledDay, isSameYear, isDateValid, setFullDate, getFullYear, getMonth, isDate, parseDate, utcAsLocal } from 'ngx-bootstrap/chronos';
import * as i5 from 'ngx-bootstrap/positioning';
import { PositioningService } from 'ngx-bootstrap/positioning';
import * as i6 from 'ngx-bootstrap/timepicker';
import { TimepickerModule } from 'ngx-bootstrap/timepicker';
import { animateExpand } from 'ngx-bootstrap/utils';
import { Subscription, BehaviorSubject, combineLatest, Subject } from 'rxjs';
import { MiniStore, MiniState } from 'ngx-bootstrap/mini-ngrx';
import * as i2 from 'ngx-bootstrap/tooltip';
import { TooltipModule } from 'ngx-bootstrap/tooltip';
import { NgClass, AsyncPipe, CommonModule } from '@angular/common';
import * as i2$1 from 'ngx-bootstrap/component-loader';
import { ComponentLoaderFactory } from 'ngx-bootstrap/component-loader';
import { NG_VALUE_ACCESSOR, NG_VALIDATORS } from '@angular/forms';

/**
 * For date range picker there are `BsDaterangepickerConfig` which inherits all properties,
 * except `displayMonths`, for range picker it default to `2`
 */
class BsDatepickerConfig {
    constructor() {
        /** sets use adaptive position */
        this.adaptivePosition = false;
        /** sets use UTC date time format */
        this.useUtc = false;
        /** turn on/off animation */
        this.isAnimated = false;
        /**
         * The view that the datepicker should start in
         */
        this.startView = 'day';
        /**
         * If true, returns focus to the datepicker / daterangepicker input after date selection
         */
        this.returnFocusToInput = false;
        /** CSS class which will be applied to datepicker container,
         * usually used to set color theme
         */
        this.containerClass = 'theme-green';
        // DatepickerRenderOptions
        this.displayMonths = 1;
        /**
         * Allows to hide week numbers in datepicker
         */
        this.showWeekNumbers = true;
        this.dateInputFormat = 'L';
        // range picker
        this.rangeSeparator = ' - ';
        /**
         * Date format for date range input field
         */
        this.rangeInputFormat = 'L';
        // DatepickerFormatOptions
        this.monthTitle = 'MMMM';
        this.yearTitle = 'YYYY';
        this.dayLabel = 'D';
        this.monthLabel = 'MMMM';
        this.yearLabel = 'YYYY';
        this.weekNumbers = 'w';
        /**
         * Shows 'today' button
         */
        this.showTodayButton = false;
        /**
         * Shows clear button
         */
        this.showClearButton = false;
        /**
         * Positioning of 'today' button
         */
        this.todayPosition = 'center';
        /**
         * Positioning of 'clear' button
         */
        this.clearPosition = 'right';
        /**
         * Label for 'today' button
         */
        this.todayButtonLabel = 'Today';
        /**
         * Label for 'clear' button
         */
        this.clearButtonLabel = 'Clear';
        /**
         * Label for 'custom range' button
         */
        this.customRangeButtonLabel = 'Custom Range';
        /**
         * Shows timepicker under datepicker
         */
        this.withTimepicker = false;
        /**
         * Set allowed positions of container.
         */
        this.allowedPositions = ['top', 'bottom'];
        /**
         * Set rule for datepicker closing. If value is true datepicker closes only if date is changed, if user changes only time datepicker doesn't close. It is available only if property withTimepicker is set true
         * */
        this.keepDatepickerOpened = false;
        /**
         * Allows keep invalid dates in range. Can be used with minDate, maxDate
         * */
        this.keepDatesOutOfRules = false;
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: BsDatepickerConfig, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
    static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: BsDatepickerConfig, providedIn: 'root' }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: BsDatepickerConfig, decorators: [{
            type: Injectable,
            args: [{
                    providedIn: 'root'
                }]
        }] });

const DATEPICKER_ANIMATION_DURATION_MS = 220;
const DATEPICKER_ANIMATION_TIMING = `${DATEPICKER_ANIMATION_DURATION_MS}ms cubic-bezier(0, 0, 0.2, 1)`;

class BsDatepickerAbstractComponent {
    constructor() {
        this.containerClass = '';
        this.customRanges = [];
        this.chosenRange = [];
        this._daysCalendarSub = new Subscription();
        this.selectedTimeSub = new Subscription();
    }
    set minDate(value) {
        this._effects?.setMinDate(value);
    }
    set maxDate(value) {
        this._effects?.setMaxDate(value);
    }
    set daysDisabled(value) {
        this._effects?.setDaysDisabled(value);
    }
    set datesDisabled(value) {
        this._effects?.setDatesDisabled(value);
    }
    set datesEnabled(value) {
        this._effects?.setDatesEnabled(value);
    }
    set isDisabled(value) {
        this._effects?.setDisabled(value);
    }
    set dateCustomClasses(value) {
        this._effects?.setDateCustomClasses(value);
    }
    set dateTooltipTexts(value) {
        this._effects?.setDateTooltipTexts(value);
    }
    set daysCalendar$(value) {
        this._daysCalendar$ = value;
        this._daysCalendarSub.unsubscribe();
        this._daysCalendarSub.add(this._daysCalendar$.subscribe(value => {
            this.multipleCalendars = !!value && value.length > 1;
        }));
    }
    get daysCalendar$() {
        return this._daysCalendar$;
    }
    // todo: valorkin fix
    // eslint-disable-next-line @typescript-eslint/no-unused-vars,@typescript-eslint/no-empty-function
    setViewMode(event) { }
    // eslint-disable-next-line
    navigateTo(event) { }
    // eslint-disable-next-line
    dayHoverHandler(event) { }
    // eslint-disable-next-line
    weekHoverHandler(event) { }
    // eslint-disable-next-line
    monthHoverHandler(event) { }
    // eslint-disable-next-line
    yearHoverHandler(event) { }
    // eslint-disable-next-line
    timeSelectHandler(date, index) { }
    // eslint-disable-next-line
    daySelectHandler(day) { }
    // eslint-disable-next-line
    monthSelectHandler(event) { }
    // eslint-disable-next-line
    yearSelectHandler(event) { }
    // eslint-disable-next-line
    setRangeOnCalendar(dates) { }
    // eslint-disable-next-line
    setToday() { }
    // eslint-disable-next-line
    clearDate() { }
    // eslint-disable-next-line @typescript-eslint/no-explicit-any
    _stopPropagation(event) {
        event.stopPropagation();
    }
}

class BsDatepickerActions {
    static { this.CALCULATE = '[datepicker] calculate dates matrix'; }
    static { this.FORMAT = '[datepicker] format datepicker values'; }
    static { this.FLAG = '[datepicker] set flags'; }
    static { this.SELECT = '[datepicker] select date'; }
    static { this.NAVIGATE_OFFSET = '[datepicker] shift view date'; }
    static { this.NAVIGATE_TO = '[datepicker] change view date'; }
    static { this.SET_OPTIONS = '[datepicker] update render options'; }
    static { this.HOVER = '[datepicker] hover date'; }
    static { this.CHANGE_VIEWMODE = '[datepicker] switch view mode'; }
    static { this.SET_MIN_DATE = '[datepicker] set min date'; }
    static { this.SET_MAX_DATE = '[datepicker] set max date'; }
    static { this.SET_DAYSDISABLED = '[datepicker] set days disabled'; }
    static { this.SET_DATESDISABLED = '[datepicker] set dates disabled'; }
    static { this.SET_DATESENABLED = '[datepicker] set dates enabled'; }
    static { this.SET_IS_DISABLED = '[datepicker] set is disabled'; }
    static { this.SET_DATE_CUSTOM_CLASSES = '[datepicker] set date custom classes'; }
    static { this.SET_DATE_TOOLTIP_TEXTS = '[datepicker] set date tooltip texts'; }
    static { this.SET_LOCALE = '[datepicker] set datepicker locale'; }
    static { this.SELECT_TIME = '[datepicker] select time'; }
    static { this.SELECT_RANGE = '[daterangepicker] select dates range'; }
    calculate() {
        return { type: BsDatepickerActions.CALCULATE };
    }
    format() {
        return { type: BsDatepickerActions.FORMAT };
    }
    flag() {
        return { type: BsDatepickerActions.FLAG };
    }
    select(date) {
        return {
            type: BsDatepickerActions.SELECT,
            payload: date
        };
    }
    selectTime(date, index) {
        return {
            type: BsDatepickerActions.SELECT_TIME,
            payload: { date, index },
        };
    }
    changeViewMode(event) {
        return {
            type: BsDatepickerActions.CHANGE_VIEWMODE,
            payload: event
        };
    }
    navigateTo(event) {
        return {
            type: BsDatepickerActions.NAVIGATE_TO,
            payload: event
        };
    }
    navigateStep(step) {
        return {
            type: BsDatepickerActions.NAVIGATE_OFFSET,
            payload: step
        };
    }
    setOptions(options) {
        return {
            type: BsDatepickerActions.SET_OPTIONS,
            payload: options
        };
    }
    // date range picker
    selectRange(value) {
        return {
            type: BsDatepickerActions.SELECT_RANGE,
            payload: value
        };
    }
    hoverDay(event) {
        return {
            type: BsDatepickerActions.HOVER,
            payload: event.isHovered ? event.cell.date : null
        };
    }
    minDate(date) {
        return {
            type: BsDatepickerActions.SET_MIN_DATE,
            payload: date
        };
    }
    maxDate(date) {
        return {
            type: BsDatepickerActions.SET_MAX_DATE,
            payload: date
        };
    }
    daysDisabled(days) {
        return {
            type: BsDatepickerActions.SET_DAYSDISABLED,
            payload: days
        };
    }
    datesDisabled(dates) {
        return {
            type: BsDatepickerActions.SET_DATESDISABLED,
            payload: dates
        };
    }
    datesEnabled(dates) {
        return {
            type: BsDatepickerActions.SET_DATESENABLED,
            payload: dates
        };
    }
    isDisabled(value) {
        return {
            type: BsDatepickerActions.SET_IS_DISABLED,
            payload: value
        };
    }
    setDateCustomClasses(value) {
        return {
            type: BsDatepickerActions.SET_DATE_CUSTOM_CLASSES,
            payload: value
        };
    }
    setDateTooltipTexts(value) {
        return {
            type: BsDatepickerActions.SET_DATE_TOOLTIP_TEXTS,
            payload: value
        };
    }
    setLocale(locale) {
        return {
            type: BsDatepickerActions.SET_LOCALE,
            payload: locale
        };
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: BsDatepickerActions, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
    static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: BsDatepickerActions, providedIn: 'platform' }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: BsDatepickerActions, decorators: [{
            type: Injectable,
            args: [{ providedIn: 'platform' }]
        }] });

class BsLocaleService {
    constructor() {
        this._defaultLocale = 'en';
        this._locale = new BehaviorSubject(this._defaultLocale);
        this._localeChange = this._locale.asObservable();
    }
    get locale() {
        return this._locale;
    }
    get localeChange() {
        return this._localeChange;
    }
    get currentLocale() {
        return this._locale.getValue();
    }
    use(locale) {
        if (locale === this.currentLocale) {
            return;
        }
        this._locale.next(locale);
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: BsLocaleService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
    static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: BsLocaleService, providedIn: 'platform' }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: BsLocaleService, decorators: [{
            type: Injectable,
            args: [{ providedIn: 'platform' }]
        }] });

class BsDatepickerEffects {
    constructor(_actions, _localeService) {
        this._actions = _actions;
        this._localeService = _localeService;
        this._subs = [];
    }
    init(_bsDatepickerStore) {
        this._store = _bsDatepickerStore;
        return this;
    }
    /** setters */
    setValue(value) {
        this._store?.dispatch(this._actions.select(value));
    }
    setRangeValue(value) {
        this._store?.dispatch(this._actions.selectRange(value));
    }
    setMinDate(value) {
        this._store?.dispatch(this._actions.minDate(value));
        return this;
    }
    setMaxDate(value) {
        this._store?.dispatch(this._actions.maxDate(value));
        return this;
    }
    setDaysDisabled(value) {
        this._store?.dispatch(this._actions.daysDisabled(value));
        return this;
    }
    setDatesDisabled(value) {
        this._store?.dispatch(this._actions.datesDisabled(value));
        return this;
    }
    setDatesEnabled(value) {
        this._store?.dispatch(this._actions.datesEnabled(value));
        return this;
    }
    setDisabled(value) {
        this._store?.dispatch(this._actions.isDisabled(value));
        return this;
    }
    setDateCustomClasses(value) {
        this._store?.dispatch(this._actions.setDateCustomClasses(value));
        return this;
    }
    setDateTooltipTexts(value) {
        this._store?.dispatch(this._actions.setDateTooltipTexts(value));
        return this;
    }
    /* Set rendering options */
    setOptions(_config) {
        const _options = Object.assign({ locale: this._localeService.currentLocale }, _config);
        this._store?.dispatch(this._actions.setOptions(_options));
        return this;
    }
    /** view to mode bindings */
    setBindings(container) {
        if (!this._store) {
            return this;
        }
        container.selectedTime = this._store.select(state => state.selectedTime)
            .pipe(filter(times => !!times));
        container.daysCalendar$ = this._store.select(state => state.flaggedMonths)
            .pipe(filter(months => !!months));
        // month calendar
        container.monthsCalendar = this._store.select(state => state.flaggedMonthsCalendar)
            .pipe(filter(months => !!months));
        // year calendar
        container.yearsCalendar = this._store.select(state => state.yearsCalendarFlagged)
            .pipe(filter(years => !!years));
        container.viewMode = this._store.select(state => state.view?.mode);
        container.options$ = combineLatest([
            this._store.select(state => state.showWeekNumbers),
            this._store.select(state => state.displayMonths)
        ])
            .pipe(map((latest) => ({
            showWeekNumbers: latest[0],
            displayMonths: latest[1]
        })));
        return this;
    }
    /** event handlers */
    setEventHandlers(container) {
        container.setViewMode = (event) => {
            this._store?.dispatch(this._actions.changeViewMode(event));
        };
        container.navigateTo = (event) => {
            this._store?.dispatch(this._actions.navigateStep(event.step));
        };
        container.dayHoverHandler = (event) => {
            const _cell = event.cell;
            if (_cell.isOtherMonth || _cell.isDisabled) {
                return;
            }
            this._store?.dispatch(this._actions.hoverDay(event));
            _cell.isHovered = event.isHovered;
        };
        container.monthHoverHandler = (event) => {
            event.cell.isHovered = event.isHovered;
        };
        container.yearHoverHandler = (event) => {
            event.cell.isHovered = event.isHovered;
        };
        return this;
    }
    registerDatepickerSideEffects() {
        if (!this._store) {
            return this;
        }
        this._subs.push(this._store.select(state => state.view).subscribe(() => {
            this._store?.dispatch(this._actions.calculate());
        }));
        // format calendar values on month model change
        this._subs.push(this._store
            .select(state => state.monthsModel)
            .pipe(filter(monthModel => !!monthModel))
            .subscribe(() => this._store?.dispatch(this._actions.format())));
        // flag day values
        this._subs.push(this._store
            .select(state => state.formattedMonths)
            .pipe(filter(month => !!month))
            .subscribe(() => this._store?.dispatch(this._actions.flag())));
        // flag day values
        this._subs.push(this._store
            .select(state => state.selectedDate)
            .pipe(filter(selectedDate => !!selectedDate))
            .subscribe(() => this._store?.dispatch(this._actions.flag())));
        // flag for date range picker
        this._subs.push(this._store
            .select(state => state.selectedRange)
            .pipe(filter(selectedRange => !!selectedRange))
            .subscribe(() => this._store?.dispatch(this._actions.flag())));
        // monthsCalendar
        this._subs.push(this._store
            .select(state => state.monthsCalendar)
            .subscribe(() => this._store?.dispatch(this._actions.flag())));
        // years calendar
        this._subs.push(this._store
            .select(state => state.yearsCalendarModel)
            .pipe(filter(state => !!state))
            .subscribe(() => this._store?.dispatch(this._actions.flag())));
        // on hover
        this._subs.push(this._store
            .select(state => state.hoveredDate)
            .pipe(filter(hoveredDate => !!hoveredDate))
            .subscribe(() => this._store?.dispatch(this._actions.flag())));
        // date custom classes
        this._subs.push(this._store
            .select(state => state.dateCustomClasses)
            .pipe(filter(dateCustomClasses => !!dateCustomClasses))
            .subscribe(() => this._store?.dispatch(this._actions.flag())));
        // date tooltip texts
        this._subs.push(this._store
            .select(state => state.dateTooltipTexts)
            .pipe(filter(dateTooltipTexts => !!dateTooltipTexts))
            .subscribe(() => this._store?.dispatch(this._actions.flag())));
        // on locale change
        this._subs.push(this._localeService.localeChange
            .subscribe(locale => this._store?.dispatch(this._actions.setLocale(locale))));
        return this;
    }
    destroy() {
        for (const sub of this._subs) {
            sub.unsubscribe();
        }
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: BsDatepickerEffects, deps: [{ token: BsDatepickerActions }, { token: BsLocaleService }], target: i0.ɵɵFactoryTarget.Injectable }); }
    static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: BsDatepickerEffects, providedIn: 'platform' }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: BsDatepickerEffects, decorators: [{
            type: Injectable,
            args: [{ providedIn: 'platform' }]
        }], ctorParameters: () => [{ type: BsDatepickerActions }, { type: BsLocaleService }] });

const defaultMonthOptions = {
    width: 7,
    height: 6
};
const dayInMilliseconds = 24 * 60 * 60 * 1000;

class BsDatepickerState {
    constructor() {
        // DatepickerRenderOptions
        this.showWeekNumbers = true;
        this.displayMonths = 1;
    }
}
const _initialView = { date: new Date(), mode: 'day' };
const initialDatepickerState = Object.assign(new BsDatepickerConfig(), {
    locale: 'en',
    view: _initialView,
    selectedRange: [],
    selectedTime: [],
    monthViewOptions: defaultMonthOptions
});

function getStartingDayOfCalendar(date, options) {
    if (isFirstDayOfWeek(date, options.firstDayOfWeek)) {
        return date;
    }
    const weekDay = getDay(date);
    const offset = calculateDateOffset(weekDay, options.firstDayOfWeek);
    return shiftDate(date, { day: -offset });
}
function calculateDateOffset(weekday, startingDayOffset) {
    const _startingDayOffset = Number(startingDayOffset);
    if (isNaN(_startingDayOffset)) {
        return 0;
    }
    if (_startingDayOffset === 0) {
        return weekday;
    }
    const offset = weekday - _startingDayOffset % 7;
    return offset < 0 ? offset + 7 : offset;
}
function isMonthDisabled(date, min, max) {
    const minBound = min && isBefore(endOf(date, 'month'), min, 'day');
    const maxBound = max && isAfter(startOf(date, 'month'), max, 'day');
    return minBound || maxBound || false;
}
function isYearDisabled(date, min, max) {
    const minBound = min && isBefore(endOf(date, 'year'), min, 'day');
    const maxBound = max && isAfter(startOf(date, 'year'), max, 'day');
    return minBound || maxBound || false;
}
function isDisabledDate(date, datesDisabled, unit) {
    if (!datesDisabled || !isArray(datesDisabled) || !datesDisabled.length) {
        return false;
    }
    if (unit && unit === 'year' && !datesDisabled[0].getDate()) {
        return datesDisabled.some((dateDisabled) => isSame(date, dateDisabled, 'year'));
    }
    return datesDisabled.some((dateDisabled) => isSame(date, dateDisabled, 'date'));
}
function isEnabledDate(date, datesEnabled, unit) {
    if (!datesEnabled || !isArray(datesEnabled) || !datesEnabled.length) {
        return false;
    }
    return !datesEnabled.some((enabledDate) => isSame(date, enabledDate, unit || 'date'));
}
function getYearsCalendarInitialDate(state, calendarIndex = 0) {
    const model = state && state.yearsCalendarModel && state.yearsCalendarModel[calendarIndex];
    return model?.years[0] && model.years[0][0] && model.years[0][0].date;
}
function checkRangesWithMaxDate(ranges, maxDate) {
    if (!ranges)
        return ranges;
    if (!maxDate)
        return ranges;
    if (!ranges.length && !ranges[0].value)
        return ranges;
    ranges.forEach((item) => {
        if (!item || !item.value)
            return ranges;
        if (item.value instanceof Date)
            return ranges;
        if (!(item.value instanceof Array && item.value.length))
            return ranges;
        item.value = compareDateWithMaxDateHelper(item.value, maxDate);
        return ranges;
    });
    return ranges;
}
function checkBsValue(date, maxDate) {
    if (!date)
        return date;
    if (!maxDate)
        return date;
    if (date instanceof Array && !date.length)
        return date;
    if (date instanceof Date)
        return date;
    return compareDateWithMaxDateHelper(date, maxDate);
}
function compareDateWithMaxDateHelper(date, maxDate) {
    if (date instanceof Array) {
        const editedValues = date.map(item => {
            if (!item)
                return item;
            if (isAfter(item, maxDate, 'date'))
                item = maxDate;
            return item;
        });
        return editedValues;
    }
    return date;
}
function setCurrentTimeOnDateSelect(value) {
    if (!value)
        return value;
    return setCurrentTimeHelper(value);
}
function setDateRangesCurrentTimeOnDateSelect(value) {
    if (!value?.length)
        return value;
    value.map((date) => {
        if (!date) {
            return date;
        }
        return setCurrentTimeHelper(date);
    });
    return value;
}
function setCurrentTimeHelper(date) {
    const now = new Date();
    date.setMilliseconds(now.getMilliseconds());
    date.setSeconds(now.getSeconds());
    date.setMinutes(now.getMinutes());
    date.setHours(now.getHours());
    return date;
}

function createMatrix(options, fn) {
    let prevValue = options.initialDate;
    const matrix = new Array(options.height);
    for (let i = 0; i < options.height; i++) {
        matrix[i] = new Array(options.width);
        for (let j = 0; j < options.width; j++) {
            matrix[i][j] = fn(prevValue);
            prevValue = shiftDate(prevValue, options.shift);
        }
    }
    return matrix;
}

// user and model input should handle parsing and validating input values
function calcDaysCalendar(startingDate, options) {
    const firstDay = getFirstDayOfMonth(startingDate);
    const initialDate = getStartingDayOfCalendar(firstDay, options);
    // todo test
    const matrixOptions = {
        width: options.width || 0,
        height: options.height || 0,
        initialDate,
        shift: { day: 1 }
    };
    const daysMatrix = createMatrix(matrixOptions, date => date);
    return {
        daysMatrix,
        month: firstDay
    };
}

function formatDaysCalendar(daysCalendar, formatOptions, monthIndex) {
    return {
        month: daysCalendar.month,
        monthTitle: formatDate(daysCalendar.month, formatOptions.monthTitle, formatOptions.locale),
        yearTitle: formatDate(daysCalendar.month, formatOptions.yearTitle, formatOptions.locale),
        weekNumbers: getWeekNumbers(daysCalendar.daysMatrix, formatOptions.weekNumbers, formatOptions.locale),
        weekdays: getShiftedWeekdays(formatOptions.locale),
        weeks: daysCalendar.daysMatrix.map((week, weekIndex) => ({
            days: week.map((date, dayIndex) => ({
                date,
                label: formatDate(date, formatOptions.dayLabel, formatOptions.locale),
                monthIndex,
                weekIndex,
                dayIndex
            }))
        })),
        hideLeftArrow: false,
        hideRightArrow: false,
        disableLeftArrow: false,
        disableRightArrow: false
    };
}
function getWeekNumbers(daysMatrix, format, locale) {
    return daysMatrix.map((days) => (days[0] ? formatDate(days[0], format, locale) : ''));
}
function getShiftedWeekdays(locale) {
    const _locale = getLocale(locale);
    const weekdays = _locale.weekdaysShort();
    const firstDayOfWeek = _locale.firstDayOfWeek();
    return [...weekdays.slice(firstDayOfWeek), ...weekdays.slice(0, firstDayOfWeek)];
}

function flagDaysCalendar(formattedMonth, options) {
    formattedMonth.weeks.forEach((week) => {
        week.days.forEach((day, dayIndex) => {
            // datepicker
            const isOtherMonth = !isSameMonth(day.date, formattedMonth.month);
            const isHovered = !isOtherMonth && isSameDay(day.date, options.hoveredDate);
            // date range picker
            const isSelectionStart = !isOtherMonth &&
                options.selectedRange &&
                isSameDay(day.date, options.selectedRange[0]);
            const isSelectionEnd = !isOtherMonth &&
                options.selectedRange &&
                isSameDay(day.date, options.selectedRange[1]);
            const isSelected = (!isOtherMonth && isSameDay(day.date, options.selectedDate)) ||
                isSelectionStart ||
                isSelectionEnd;
            const isInRange = !isOtherMonth &&
                options.selectedRange &&
                isDateInRange(day.date, options.selectedRange, options.hoveredDate);
            const isDisabled = options.isDisabled ||
                isBefore(day.date, options.minDate, 'day') ||
                isAfter(day.date, options.maxDate, 'day') ||
                isDisabledDay(day.date, options.daysDisabled) ||
                isDisabledDate(day.date, options.datesDisabled) ||
                isEnabledDate(day.date, options.datesEnabled);
            const currentDate = new Date();
            const isToday = !isOtherMonth && isSameDay(day.date, currentDate);
            const customClasses = options.dateCustomClasses && options.dateCustomClasses
                .map(dcc => isSameDay(day.date, dcc.date) ? dcc.classes : [])
                .reduce((previousValue, currentValue) => previousValue.concat(currentValue), [])
                .join(' ')
                || '';
            const tooltipText = options.dateTooltipTexts && options.dateTooltipTexts
                .map(tt => isSameDay(day.date, tt.date) ? tt.tooltipText : '')
                .filter(text => !!text)
                .join(' ')
                || '';
            // decide update or not
            const newDay = Object.assign({}, day, {
                isOtherMonth,
                isHovered,
                isSelected,
                isSelectionStart,
                isSelectionEnd,
                isInRange,
                isDisabled,
                isToday,
                customClasses,
                tooltipText
            });
            if (day.isOtherMonth !== newDay.isOtherMonth ||
                day.isHovered !== newDay.isHovered ||
                day.isSelected !== newDay.isSelected ||
                day.isSelectionStart !== newDay.isSelectionStart ||
                day.isSelectionEnd !== newDay.isSelectionEnd ||
                day.isDisabled !== newDay.isDisabled ||
                day.isInRange !== newDay.isInRange ||
                day.customClasses !== newDay.customClasses ||
                day.tooltipText !== newDay.tooltipText) {
                week.days[dayIndex] = newDay;
            }
        });
    });
    // todo: add check for linked calendars
    formattedMonth.hideLeftArrow =
        options.isDisabled ||
            (!!options.monthIndex && options.monthIndex > 0 && options.monthIndex !== options.displayMonths);
    formattedMonth.hideRightArrow =
        options.isDisabled ||
            ((!!options.monthIndex || options.monthIndex === 0) && !!options.displayMonths && options.monthIndex < options.displayMonths &&
                options.monthIndex + 1 !== options.displayMonths);
    formattedMonth.disableLeftArrow = isMonthDisabled(shiftDate(formattedMonth.month, { month: -1 }), options.minDate, options.maxDate);
    formattedMonth.disableRightArrow = isMonthDisabled(shiftDate(formattedMonth.month, { month: 1 }), options.minDate, options.maxDate);
    return formattedMonth;
}
function isDateInRange(date, selectedRange, hoveredDate) {
    if (!date || !selectedRange || !selectedRange[0]) {
        return false;
    }
    if (selectedRange[1]) {
        return date > selectedRange[0] && date <= selectedRange[1];
    }
    if (hoveredDate) {
        return date > selectedRange[0] && date <= hoveredDate;
    }
    return false;
}

function canSwitchMode(mode, minMode) {
    return minMode ? mode >= minMode : true;
}

const height$1 = 4;
const width$1 = 3;
const shift$1 = { month: 1 };
function formatMonthsCalendar(viewDate, formatOptions) {
    const initialDate = startOf(viewDate, 'year');
    const matrixOptions = { width: width$1, height: height$1, initialDate, shift: shift$1 };
    const monthMatrix = createMatrix(matrixOptions, date => ({
        date,
        label: formatDate(date, formatOptions.monthLabel, formatOptions.locale)
    }));
    return {
        months: monthMatrix,
        monthTitle: '',
        yearTitle: formatDate(viewDate, formatOptions.yearTitle, formatOptions.locale),
        hideRightArrow: false,
        hideLeftArrow: false,
        disableRightArrow: false,
        disableLeftArrow: false
    };
}

function flagMonthsCalendar(monthCalendar, options) {
    monthCalendar.months.forEach((months, rowIndex) => {
        months.forEach((month, monthIndex) => {
            let isSelected;
            const isHovered = isSameMonth(month.date, options.hoveredMonth);
            const isDisabled = options.isDisabled ||
                isDisabledDate(month.date, options.datesDisabled) ||
                isEnabledDate(month.date, options.datesEnabled, 'month') ||
                isMonthDisabled(month.date, options.minDate, options.maxDate);
            if (!options.selectedDate && options.selectedRange) {
                isSelected = isSameMonth(month.date, options.selectedRange[0]);
                if (!isSelected) {
                    isSelected = isSameMonth(month.date, options.selectedRange[1]);
                }
            }
            else {
                isSelected = isSameMonth(month.date, options.selectedDate);
            }
            const newMonth = Object.assign(/*{},*/ month, {
                isHovered,
                isDisabled,
                isSelected
            });
            if (month.isHovered !== newMonth.isHovered ||
                month.isDisabled !== newMonth.isDisabled ||
                month.isSelected !== newMonth.isSelected) {
                monthCalendar.months[rowIndex][monthIndex] = newMonth;
            }
        });
    });
    // todo: add check for linked calendars
    monthCalendar.hideLeftArrow =
        !!options.monthIndex && options.monthIndex > 0 && options.monthIndex !== options.displayMonths;
    monthCalendar.hideRightArrow =
        (!!options.monthIndex || options.monthIndex === 0)
            && (!!options.displayMonths || options.displayMonths === 0)
            && options.monthIndex < options.displayMonths
            && options.monthIndex + 1 !== options.displayMonths;
    monthCalendar.disableLeftArrow = isYearDisabled(shiftDate(monthCalendar.months[0][0].date, { year: -1 }), options.minDate, options.maxDate);
    monthCalendar.disableRightArrow = isYearDisabled(shiftDate(monthCalendar.months[0][0].date, { year: 1 }), options.minDate, options.maxDate);
    return monthCalendar;
}

const height = 4;
const width = 4;
const yearsPerCalendar = height * width;
const initialYearShift = (Math.floor(yearsPerCalendar / 2) - 1) * -1;
const shift = { year: 1 };
function formatYearsCalendar(viewDate, formatOptions, previousInitialDate) {
    const initialDate = calculateInitialDate(viewDate, previousInitialDate);
    const matrixOptions = { width, height, initialDate, shift };
    const yearsMatrix = createMatrix(matrixOptions, date => ({
        date,
        label: formatDate(date, formatOptions.yearLabel, formatOptions.locale)
    }));
    const yearTitle = formatYearRangeTitle(yearsMatrix, formatOptions);
    return {
        years: yearsMatrix,
        monthTitle: '',
        yearTitle,
        hideLeftArrow: false,
        hideRightArrow: false,
        disableLeftArrow: false,
        disableRightArrow: false
    };
}
function calculateInitialDate(viewDate, previousInitialDate) {
    if (previousInitialDate
        && viewDate.getFullYear() >= previousInitialDate.getFullYear()
        && viewDate.getFullYear() < previousInitialDate.getFullYear() + yearsPerCalendar) {
        return previousInitialDate;
    }
    return shiftDate(viewDate, { year: initialYearShift });
}
function formatYearRangeTitle(yearsMatrix, formatOptions) {
    const from = formatDate(yearsMatrix[0][0].date, formatOptions.yearTitle, formatOptions.locale);
    const to = formatDate(yearsMatrix[height - 1][width - 1].date, formatOptions.yearTitle, formatOptions.locale);
    return `${from} - ${to}`;
}

function flagYearsCalendar(yearsCalendar, options) {
    yearsCalendar.years.forEach((years, rowIndex) => {
        years.forEach((year, yearIndex) => {
            let isSelected;
            const isHovered = isSameYear(year.date, options.hoveredYear);
            const isDisabled = options.isDisabled ||
                isDisabledDate(year.date, options.datesDisabled, 'year') ||
                isEnabledDate(year.date, options.datesEnabled, 'year') ||
                isYearDisabled(year.date, options.minDate, options.maxDate);
            if (!options.selectedDate && options.selectedRange) {
                isSelected = isSameYear(year.date, options.selectedRange[0]);
                if (!isSelected) {
                    isSelected = isSameYear(year.date, options.selectedRange[1]);
                }
            }
            else {
                isSelected = isSameYear(year.date, options.selectedDate);
            }
            const newMonth = Object.assign(/*{},*/ year, { isHovered, isDisabled, isSelected });
            if (year.isHovered !== newMonth.isHovered ||
                year.isDisabled !== newMonth.isDisabled ||
                year.isSelected !== newMonth.isSelected) {
                yearsCalendar.years[rowIndex][yearIndex] = newMonth;
            }
        });
    });
    // todo: add check for linked calendars
    yearsCalendar.hideLeftArrow =
        !!options.yearIndex && options.yearIndex > 0 && options.yearIndex !== options.displayMonths;
    yearsCalendar.hideRightArrow =
        !!options.yearIndex && !!options.displayMonths &&
            options.yearIndex < options.displayMonths &&
            options.yearIndex + 1 !== options.displayMonths;
    yearsCalendar.disableLeftArrow = isYearDisabled(shiftDate(yearsCalendar.years[0][0].date, { year: -1 }), options.minDate, options.maxDate);
    const i = yearsCalendar.years.length - 1;
    const j = yearsCalendar.years[i].length - 1;
    yearsCalendar.disableRightArrow = isYearDisabled(shiftDate(yearsCalendar.years[i][j].date, { year: 1 }), options.minDate, options.maxDate);
    return yearsCalendar;
}

function copyTime(sourceDate, time) {
    if (!sourceDate || !isNaN(sourceDate.getTime())) {
        return;
    }
    sourceDate.setHours(time.getHours());
    sourceDate.setMinutes(time.getMinutes());
    sourceDate.setSeconds(time.getSeconds());
    sourceDate.setMilliseconds(time.getMilliseconds());
}

function bsDatepickerReducer(state = initialDatepickerState, action) {
    switch (action.type) {
        case BsDatepickerActions.CALCULATE: {
            return calculateReducer(state);
        }
        case BsDatepickerActions.FORMAT: {
            return formatReducer(state);
        }
        case BsDatepickerActions.FLAG: {
            return flagReducer(state);
        }
        case BsDatepickerActions.NAVIGATE_OFFSET: {
            return navigateOffsetReducer(state, action);
        }
        case BsDatepickerActions.NAVIGATE_TO: {
            const payload = action.payload;
            if (!state.view || !payload.unit) {
                return state;
            }
            const date = setFullDate(state.view.date, payload.unit);
            let newState;
            let mode;
            if (canSwitchMode(payload.viewMode, state.minMode)) {
                mode = payload.viewMode;
                newState = { view: { date, mode } };
            }
            else {
                mode = state.view.mode;
                newState = { selectedDate: date, view: { date, mode } };
            }
            return Object.assign({}, state, newState);
        }
        case BsDatepickerActions.CHANGE_VIEWMODE: {
            if (!canSwitchMode(action.payload, state.minMode) || !state.view) {
                return state;
            }
            const date = state.view.date;
            const mode = action.payload;
            const newState = { view: { date, mode } };
            return Object.assign({}, state, newState);
        }
        case BsDatepickerActions.HOVER: {
            return Object.assign({}, state, { hoveredDate: action.payload });
        }
        case BsDatepickerActions.SELECT: {
            if (!state.view) {
                return state;
            }
            const newState = {
                selectedDate: action.payload,
                view: state.view
            };
            if (Array.isArray(state.selectedTime)) {
                const _time = state.selectedTime[0];
                if (newState.selectedDate && _time) {
                    copyTime(newState.selectedDate, _time);
                }
            }
            const mode = state.view.mode;
            const _date = action.payload || state.view.date;
            const date = getViewDate(_date, state.minDate, state.maxDate);
            newState.view = { mode, date };
            return Object.assign({}, state, newState);
        }
        case BsDatepickerActions.SELECT_TIME: {
            const { date, index } = action.payload;
            const selectedTime = state.selectedTime ? [...state.selectedTime] : [];
            selectedTime[index] = date;
            return Object.assign({}, state, { selectedTime });
        }
        case BsDatepickerActions.SET_OPTIONS: {
            if (!state.view) {
                return state;
            }
            const newState = action.payload;
            // preserve view mode
            const mode = newState.minMode ? newState.minMode : state.view.mode;
            const _viewDate = isDateValid(newState.value) && newState.value
                || isArray(newState.value) && isDateValid(newState.value[0]) && newState.value[0]
                || state.view.date;
            const date = getViewDate(_viewDate, newState.minDate, newState.maxDate);
            newState.view = { mode, date };
            // update selected value
            if (newState.value) {
                // if new value is array we work with date range
                if (isArray(newState.value)) {
                    newState.selectedRange = newState.value;
                    newState.selectedTime = newState.value.map((i) => i);
                }
                // if new value is a date -> datepicker
                if (newState.value instanceof Date) {
                    newState.selectedDate = newState.value;
                    newState.selectedTime = [newState.value];
                }
                // provided value is not supported :)
                // need to report it somehow
            }
            return Object.assign({}, state, newState);
        }
        // date range picker
        case BsDatepickerActions.SELECT_RANGE: {
            if (!state.view) {
                return state;
            }
            const newState = {
                selectedRange: action.payload,
                view: state.view
            };
            newState.selectedRange?.forEach((dte, index) => {
                if (Array.isArray(state.selectedTime)) {
                    const _time = state.selectedTime[index];
                    if (_time) {
                        copyTime(dte, _time);
                    }
                }
            });
            const mode = state.view.mode;
            const _date = action.payload && action.payload[0] || state.view.date;
            const date = getViewDate(_date, state.minDate, state.maxDate);
            newState.view = { mode, date };
            return Object.assign({}, state, newState);
        }
        case BsDatepickerActions.SET_MIN_DATE: {
            return Object.assign({}, state, {
                minDate: action.payload
            });
        }
        case BsDatepickerActions.SET_MAX_DATE: {
            return Object.assign({}, state, {
                maxDate: action.payload
            });
        }
        case BsDatepickerActions.SET_IS_DISABLED: {
            return Object.assign({}, state, {
                isDisabled: action.payload
            });
        }
        case BsDatepickerActions.SET_DATE_CUSTOM_CLASSES: {
            return Object.assign({}, state, {
                dateCustomClasses: action.payload
            });
        }
        case BsDatepickerActions.SET_DATE_TOOLTIP_TEXTS: {
            return Object.assign({}, state, {
                dateTooltipTexts: action.payload
            });
        }
        default:
            return state;
    }
}
function calculateReducer(state) {
    if (!state.view) {
        return state;
    }
    // how many calendars
    let displayMonths;
    if (state.displayOneMonthRange &&
        isDisplayOneMonth(state.view.date, state.minDate, state.maxDate)) {
        displayMonths = 1;
    }
    else {
        displayMonths = state.displayMonths || 1;
    }
    // use selected date on initial rendering if set
    let viewDate = state.view.date;
    if (state.view.mode === 'day' && state.monthViewOptions) {
        if (state.showPreviousMonth && state.selectedRange && state.selectedRange.length === 0) {
            viewDate = shiftDate(viewDate, { month: -1 });
        }
        state.monthViewOptions.firstDayOfWeek = getLocale(state.locale).firstDayOfWeek();
        let monthsModel = new Array(displayMonths);
        for (let monthIndex = 0; monthIndex < displayMonths; monthIndex++) {
            // todo: for unlinked calendars it will be harder
            monthsModel[monthIndex] = calcDaysCalendar(viewDate, state.monthViewOptions);
            viewDate = shiftDate(viewDate, { month: 1 });
        }
        // Check if parameter enabled and check if it's not months navigation event
        if (state.preventChangeToNextMonth && state.flaggedMonths && state.hoveredDate) {
            const viewMonth = calcDaysCalendar(state.view.date, state.monthViewOptions);
            // Check if viewed right month same as in flaggedMonths state, then override months model with flaggedMonths
            if (state.flaggedMonths.length && state.flaggedMonths[1].month.getMonth() === viewMonth.month.getMonth()) {
                monthsModel = state.flaggedMonths
                    .map(item => {
                    if (state.monthViewOptions) {
                        return calcDaysCalendar(item.month, state.monthViewOptions);
                    }
                    return null;
                })
                    .filter(item => item !== null);
            }
        }
        return Object.assign({}, state, { monthsModel });
    }
    if (state.view.mode === 'month') {
        const monthsCalendar = new Array(displayMonths);
        for (let calendarIndex = 0; calendarIndex < displayMonths; calendarIndex++) {
            // todo: for unlinked calendars it will be harder
            monthsCalendar[calendarIndex] = formatMonthsCalendar(viewDate, getFormatOptions(state));
            viewDate = shiftDate(viewDate, { year: 1 });
        }
        return Object.assign({}, state, { monthsCalendar });
    }
    if (state.view.mode === 'year') {
        const yearsCalendarModel = new Array(displayMonths);
        for (let calendarIndex = 0; calendarIndex < displayMonths; calendarIndex++) {
            // todo: for unlinked calendars it will be harder
            yearsCalendarModel[calendarIndex] = formatYearsCalendar(viewDate, getFormatOptions(state), state.minMode === 'year' ? getYearsCalendarInitialDate(state, calendarIndex) : undefined);
            viewDate = shiftDate(viewDate, { year: yearsPerCalendar });
        }
        return Object.assign({}, state, { yearsCalendarModel });
    }
    return state;
}
function formatReducer(state) {
    if (!state.view) {
        return state;
    }
    if (state.view.mode === 'day' && state.monthsModel) {
        const formattedMonths = state.monthsModel.map((month, monthIndex) => formatDaysCalendar(month, getFormatOptions(state), monthIndex));
        return Object.assign({}, state, { formattedMonths });
    }
    // how many calendars
    const displayMonths = state.displayMonths || 1;
    // check initial rendering
    // use selected date on initial rendering if set
    let viewDate = state.view.date;
    if (state.view.mode === 'month') {
        const monthsCalendar = new Array(displayMonths);
        for (let calendarIndex = 0; calendarIndex < displayMonths; calendarIndex++) {
            // todo: for unlinked calendars it will be harder
            monthsCalendar[calendarIndex] = formatMonthsCalendar(viewDate, getFormatOptions(state));
            viewDate = shiftDate(viewDate, { year: 1 });
        }
        return Object.assign({}, state, { monthsCalendar });
    }
    if (state.view.mode === 'year') {
        const yearsCalendarModel = new Array(displayMonths);
        for (let calendarIndex = 0; calendarIndex < displayMonths; calendarIndex++) {
            // todo: for unlinked calendars it will be harder
            yearsCalendarModel[calendarIndex] = formatYearsCalendar(viewDate, getFormatOptions(state));
            viewDate = shiftDate(viewDate, { year: 16 });
        }
        return Object.assign({}, state, { yearsCalendarModel });
    }
    return state;
}
function flagReducer(state) {
    if (!state.view) {
        return state;
    }
    const displayMonths = isDisplayOneMonth(state.view.date, state.minDate, state.maxDate) ? 1 : state.displayMonths;
    if (state.formattedMonths && state.view.mode === 'day') {
        const flaggedMonths = state.formattedMonths.map((formattedMonth, monthIndex) => flagDaysCalendar(formattedMonth, {
            isDisabled: state.isDisabled,
            minDate: state.minDate,
            maxDate: state.maxDate,
            daysDisabled: state.daysDisabled,
            datesDisabled: state.datesDisabled,
            datesEnabled: state.datesEnabled,
            hoveredDate: state.hoveredDate,
            selectedDate: state.selectedDate,
            selectedRange: state.selectedRange,
            displayMonths,
            dateCustomClasses: state.dateCustomClasses,
            dateTooltipTexts: state.dateTooltipTexts,
            monthIndex
        }));
        return Object.assign({}, state, { flaggedMonths });
    }
    if (state.view.mode === 'month' && state.monthsCalendar) {
        const flaggedMonthsCalendar = state.monthsCalendar.map((formattedMonth, monthIndex) => flagMonthsCalendar(formattedMonth, {
            isDisabled: state.isDisabled,
            minDate: state.minDate,
            maxDate: state.maxDate,
            hoveredMonth: state.hoveredMonth,
            selectedDate: state.selectedDate,
            datesDisabled: state.datesDisabled,
            datesEnabled: state.datesEnabled,
            selectedRange: state.selectedRange,
            displayMonths,
            monthIndex
        }));
        return Object.assign({}, state, { flaggedMonthsCalendar });
    }
    if (state.view.mode === 'year' && state.yearsCalendarModel) {
        const yearsCalendarFlagged = state.yearsCalendarModel.map((formattedMonth, yearIndex) => flagYearsCalendar(formattedMonth, {
            isDisabled: state.isDisabled,
            minDate: state.minDate,
            maxDate: state.maxDate,
            hoveredYear: state.hoveredYear,
            selectedDate: state.selectedDate,
            datesDisabled: state.datesDisabled,
            datesEnabled: state.datesEnabled,
            selectedRange: state.selectedRange,
            displayMonths,
            yearIndex
        }));
        return Object.assign({}, state, { yearsCalendarFlagged });
    }
    return state;
}
function navigateOffsetReducer(state, action) {
    if (!state.view) {
        return state;
    }
    const date = shiftViewDate(state, action);
    if (!date) {
        return state;
    }
    const newState = {
        view: {
            mode: state.view.mode,
            date
        }
    };
    return Object.assign({}, state, newState);
}
function shiftViewDate(state, action) {
    if (!state.view) {
        return undefined;
    }
    if (state.view.mode === 'year' && state.minMode === 'year') {
        const initialDate = getYearsCalendarInitialDate(state, 0);
        if (initialDate) {
            const middleDate = shiftDate(initialDate, { year: -initialYearShift });
            return shiftDate(middleDate, action.payload);
        }
    }
    return shiftDate(startOf(state.view.date, 'month'), action.payload);
}
function getFormatOptions(state) {
    return {
        locale: state.locale,
        monthTitle: state.monthTitle,
        yearTitle: state.yearTitle,
        dayLabel: state.dayLabel,
        monthLabel: state.monthLabel,
        yearLabel: state.yearLabel,
        weekNumbers: state.weekNumbers
    };
}
/**
 * if view date is provided (bsValue|ngModel) it should be shown
 * if view date is not provider:
 * if minDate>currentDate (default view value), show minDate
 * if maxDate<currentDate(default view value) show maxDate
 */
function getViewDate(viewDate, minDate, maxDate) {
    const _date = Array.isArray(viewDate) ? viewDate[0] : viewDate;
    if (minDate && isAfter(minDate, _date, 'day')) {
        return minDate;
    }
    if (maxDate && isBefore(maxDate, _date, 'day')) {
        return maxDate;
    }
    return _date;
}
function isDisplayOneMonth(viewDate, minDate, maxDate) {
    if (maxDate && isSame(maxDate, viewDate, 'day')) {
        return true;
    }
    return minDate && maxDate && minDate.getMonth() === maxDate.getMonth();
}

class BsDatepickerStore extends MiniStore {
    constructor() {
        const _dispatcher = new BehaviorSubject({
            type: '[datepicker] dispatcher init'
        });
        const state = new MiniState(initialDatepickerState, _dispatcher, bsDatepickerReducer);
        super(_dispatcher, bsDatepickerReducer, state);
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: BsDatepickerStore, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
    static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: BsDatepickerStore, providedIn: 'platform' }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: BsDatepickerStore, decorators: [{
            type: Injectable,
            args: [{ providedIn: 'platform' }]
        }], ctorParameters: () => [] });

class BsCustomDatesViewComponent {
    constructor() {
        this.onSelect = new EventEmitter();
    }
    selectFromRanges(range) {
        this.onSelect.emit(range);
    }
    compareRanges(range) {
        const currentRange = range?.value;
        const selectedRange = this.selectedRange;
        if (Array.isArray(currentRange) && Array.isArray(selectedRange)) {
            return new Date(currentRange[0]).setHours(0, 0, 0, 0) === new Date(selectedRange[0]).setHours(0, 0, 0, 0)
                && new Date(currentRange[1]).setHours(0, 0, 0, 0) === new Date(selectedRange[1]).setHours(0, 0, 0, 0);
        }
        return JSON.stringify(currentRange) === JSON.stringify(selectedRange);
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: BsCustomDatesViewComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
    static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.2", type: BsCustomDatesViewComponent, isStandalone: true, selector: "bs-custom-date-view", inputs: { ranges: "ranges", selectedRange: "selectedRange", customRangeLabel: "customRangeLabel" }, outputs: { onSelect: "onSelect" }, ngImport: i0, template: `
    <div class="bs-datepicker-predefined-btns">
      @for (range of ranges; track range) {
        <button
          type="button"
          class="btn"
          (click)="selectFromRanges(range)"
          [class.selected]="compareRanges(range)">
          {{ range.label }}
        </button>
      }
    </div>
    `, isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: BsCustomDatesViewComponent, decorators: [{
            type: Component,
            args: [{
                    selector: 'bs-custom-date-view',
                    template: `
    <div class="bs-datepicker-predefined-btns">
      @for (range of ranges; track range) {
        <button
          type="button"
          class="btn"
          (click)="selectFromRanges(range)"
          [class.selected]="compareRanges(range)">
          {{ range.label }}
        </button>
      }
    </div>
    `,
                    changeDetection: ChangeDetectionStrategy.OnPush,
                    standalone: true,
                    imports: []
                }]
        }], propDecorators: { ranges: [{
                type: Input
            }], selectedRange: [{
                type: Input
            }], customRangeLabel: [{
                type: Input
            }], onSelect: [{
                type: Output
            }] } });

/** *************** */
// events
/** *************** */
var BsNavigationDirection;
(function (BsNavigationDirection) {
    BsNavigationDirection[BsNavigationDirection["UP"] = 0] = "UP";
    BsNavigationDirection[BsNavigationDirection["DOWN"] = 1] = "DOWN";
})(BsNavigationDirection || (BsNavigationDirection = {}));

class BsDatepickerNavigationViewComponent {
    constructor() {
        this.isDisabled = false;
        this.onNavigate = new EventEmitter();
        this.onViewMode = new EventEmitter();
    }
    navTo(down) {
        this.onNavigate.emit(down ? BsNavigationDirection.DOWN : BsNavigationDirection.UP);
    }
    view(viewMode) {
        if (this.isDisabled) {
            return;
        }
        this.onViewMode.emit(viewMode);
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: BsDatepickerNavigationViewComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
    static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.2", type: BsDatepickerNavigationViewComponent, isStandalone: true, selector: "bs-datepicker-navigation-view", inputs: { calendar: "calendar", isDisabled: "isDisabled" }, outputs: { onNavigate: "onNavigate", onViewMode: "onViewMode" }, ngImport: i0, template: `
    <button class="previous"
      [disabled]="calendar.disableLeftArrow"
      [style.visibility]="calendar.hideLeftArrow ? 'hidden' : 'visible'"
      type="button"
      (click)="navTo(true)">
      <span>&lsaquo;</span>
    </button>
    
    @if (calendar && calendar.monthTitle) {
      &#8203;  <!-- zero-width space needed for correct alignment
      with preserveWhitespaces: false in Angular -->
      <button class="current"
        type="button"
        (click)="view('month')"
        [disabled]="isDisabled"
        ><span>{{ calendar.monthTitle }}</span>
      </button>
    }
    
    &#8203;  <!-- zero-width space needed for correct alignment
    with preserveWhitespaces: false in Angular -->
    
    <button
      class="current"
      (click)="view('year')"
      type="button"
      [disabled]="isDisabled"
      >
      <span>{{ calendar.yearTitle }}</span>
    </button>
    
    &#8203;  <!-- zero-width space needed for correct alignment
    with preserveWhitespaces: false in Angular -->
    
    <button class="next"
      [disabled]="calendar.disableRightArrow"
      [style.visibility]="calendar.hideRightArrow ? 'hidden' : 'visible'"
      type="button"
      (click)="navTo(false)"><span>&rsaquo;</span>
    </button>
    `, isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: BsDatepickerNavigationViewComponent, decorators: [{
            type: Component,
            args: [{
                    selector: 'bs-datepicker-navigation-view',
                    changeDetection: ChangeDetectionStrategy.OnPush,
                    template: `
    <button class="previous"
      [disabled]="calendar.disableLeftArrow"
      [style.visibility]="calendar.hideLeftArrow ? 'hidden' : 'visible'"
      type="button"
      (click)="navTo(true)">
      <span>&lsaquo;</span>
    </button>
    
    @if (calendar && calendar.monthTitle) {
      &#8203;  <!-- zero-width space needed for correct alignment
      with preserveWhitespaces: false in Angular -->
      <button class="current"
        type="button"
        (click)="view('month')"
        [disabled]="isDisabled"
        ><span>{{ calendar.monthTitle }}</span>
      </button>
    }
    
    &#8203;  <!-- zero-width space needed for correct alignment
    with preserveWhitespaces: false in Angular -->
    
    <button
      class="current"
      (click)="view('year')"
      type="button"
      [disabled]="isDisabled"
      >
      <span>{{ calendar.yearTitle }}</span>
    </button>
    
    &#8203;  <!-- zero-width space needed for correct alignment
    with preserveWhitespaces: false in Angular -->
    
    <button class="next"
      [disabled]="calendar.disableRightArrow"
      [style.visibility]="calendar.hideRightArrow ? 'hidden' : 'visible'"
      type="button"
      (click)="navTo(false)"><span>&rsaquo;</span>
    </button>
    `,
                    standalone: true,
                    imports: []
                }]
        }], propDecorators: { calendar: [{
                type: Input
            }], isDisabled: [{
                type: Input
            }], onNavigate: [{
                type: Output
            }], onViewMode: [{
                type: Output
            }] } });

class BsTimepickerViewComponent {
    constructor() {
        this.ampm = 'ok';
        this.hours = 0;
        this.minutes = 0;
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: BsTimepickerViewComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
    static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "22.0.2", type: BsTimepickerViewComponent, isStandalone: true, selector: "bs-timepicker", ngImport: i0, template: `
    <div class="bs-timepicker-container">
      <div class="bs-timepicker-controls">
        <button class="bs-decrease" type="button">-</button>
        <input type="text" [value]="hours" placeholder="00">
        <button class="bs-increase" type="button">+</button>
      </div>
      <div class="bs-timepicker-controls">
        <button class="bs-decrease" type="button">-</button>
        <input type="text" [value]="minutes" placeholder="00">
        <button class="bs-increase" type="button">+</button>
      </div>
      <button class="switch-time-format" type="button">{{ ampm }}
        <img
          src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAsAAAAKCAYAAABi8KSDAAABSElEQVQYV3XQPUvDUBQG4HNuagtVqc6KgouCv6GIuIntYBLB9hcIQpLStCAIV7DYmpTcRWcXqZio3Vwc/UCc/QEqfgyKGbr0I7nS1EiHeqYzPO/h5SD0jaxUZjmSLCB+OFb+UFINFwASAEAdpu9gaGXVyAHHFQBkHpKHc6a9dzECvADyY9sqlAMsK9W0jzxDXqeytr3mhQckxSji27TJJ5/rPmIpwJJq3HrtduriYOurv1a4i1p5HnhkG9OFymi0ReoO05cGwb+ayv4dysVygjeFmsP05f8wpZQ8fsdvfmuY9zjWSNqUtgYFVnOVReILYoBFzdQI5/GGFzNHhGbeZnopDGU29sZbscgldmC99w35VOATTycIMMcBXIfpSVGzZhA6C8hh00conln6VQ9TGgV32OEAKQC4DrBq7CJwd0ggR7Vq/rPrfgB+C3sGypY5DAAAAABJRU5ErkJggg=="
          alt="">
      </button>
    </div>
  `, isInline: true, changeDetection: i0.ChangeDetectionStrategy.Eager }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: BsTimepickerViewComponent, decorators: [{
            type: Component,
            args: [{
                    selector: 'bs-timepicker',
                    changeDetection: ChangeDetectionStrategy.Eager,
                    template: `
    <div class="bs-timepicker-container">
      <div class="bs-timepicker-controls">
        <button class="bs-decrease" type="button">-</button>
        <input type="text" [value]="hours" placeholder="00">
        <button class="bs-increase" type="button">+</button>
      </div>
      <div class="bs-timepicker-controls">
        <button class="bs-decrease" type="button">-</button>
        <input type="text" [value]="minutes" placeholder="00">
        <button class="bs-increase" type="button">+</button>
      </div>
      <button class="switch-time-format" type="button">{{ ampm }}
        <img
          src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAsAAAAKCAYAAABi8KSDAAABSElEQVQYV3XQPUvDUBQG4HNuagtVqc6KgouCv6GIuIntYBLB9hcIQpLStCAIV7DYmpTcRWcXqZio3Vwc/UCc/QEqfgyKGbr0I7nS1EiHeqYzPO/h5SD0jaxUZjmSLCB+OFb+UFINFwASAEAdpu9gaGXVyAHHFQBkHpKHc6a9dzECvADyY9sqlAMsK9W0jzxDXqeytr3mhQckxSji27TJJ5/rPmIpwJJq3HrtduriYOurv1a4i1p5HnhkG9OFymi0ReoO05cGwb+ayv4dysVygjeFmsP05f8wpZQ8fsdvfmuY9zjWSNqUtgYFVnOVReILYoBFzdQI5/GGFzNHhGbeZnopDGU29sZbscgldmC99w35VOATTycIMMcBXIfpSVGzZhA6C8hh00conln6VQ9TGgV32OEAKQC4DrBq7CJwd0ggR7Vq/rPrfgB+C3sGypY5DAAAAABJRU5ErkJggg=="
          alt="">
      </button>
    </div>
  `,
                    standalone: true
                }]
        }] });

class BsCurrentDateViewComponent {
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: BsCurrentDateViewComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
    static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "22.0.2", type: BsCurrentDateViewComponent, isStandalone: true, selector: "bs-current-date", inputs: { title: "title" }, ngImport: i0, template: `<div class="current-timedate"><span>{{ title }}</span></div>`, isInline: true, changeDetection: i0.ChangeDetectionStrategy.Eager }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: BsCurrentDateViewComponent, decorators: [{
            type: Component,
            args: [{
                    selector: 'bs-current-date',
                    changeDetection: ChangeDetectionStrategy.Eager,
                    template: `<div class="current-timedate"><span>{{ title }}</span></div>`,
                    standalone: true
                }]
        }], propDecorators: { title: [{
                type: Input
            }] } });

class BsCalendarLayoutComponent {
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: BsCalendarLayoutComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
    static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.2", type: BsCalendarLayoutComponent, isStandalone: true, selector: "bs-calendar-layout", ngImport: i0, template: `
    <!-- current date, will be added in nearest releases -->
    @if (false) {
      <bs-current-date title="hey there"></bs-current-date>
    }
    
    <!--navigation-->
    <div class="bs-datepicker-head">
      <ng-content select="bs-datepicker-navigation-view"></ng-content>
    </div>
    
    <div class="bs-datepicker-body">
      <ng-content></ng-content>
    </div>
    
    <!--timepicker-->
    @if (false) {
      <bs-timepicker></bs-timepicker>
    }
    `, isInline: true, dependencies: [{ kind: "component", type: BsCurrentDateViewComponent, selector: "bs-current-date", inputs: ["title"] }, { kind: "component", type: BsTimepickerViewComponent, selector: "bs-timepicker" }], changeDetection: i0.ChangeDetectionStrategy.Eager }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: BsCalendarLayoutComponent, decorators: [{
            type: Component,
            args: [{
                    selector: 'bs-calendar-layout',
                    changeDetection: ChangeDetectionStrategy.Eager,
                    template: `
    <!-- current date, will be added in nearest releases -->
    @if (false) {
      <bs-current-date title="hey there"></bs-current-date>
    }
    
    <!--navigation-->
    <div class="bs-datepicker-head">
      <ng-content select="bs-datepicker-navigation-view"></ng-content>
    </div>
    
    <div class="bs-datepicker-body">
      <ng-content></ng-content>
    </div>
    
    <!--timepicker-->
    @if (false) {
      <bs-timepicker></bs-timepicker>
    }
    `,
                    standalone: true,
                    imports: [BsCurrentDateViewComponent, BsTimepickerViewComponent]
                }]
        }] });

class BsYearsCalendarViewComponent {
    constructor() {
        this.onNavigate = new EventEmitter();
        this.onViewMode = new EventEmitter();
        this.onSelect = new EventEmitter();
        this.onHover = new EventEmitter();
    }
    navigateTo(event) {
        const step = BsNavigationDirection.DOWN === event ? -1 : 1;
        this.onNavigate.emit({ step: { year: step * yearsPerCalendar } });
    }
    viewYear(year) {
        this.onSelect.emit(year);
    }
    hoverYear(cell, isHovered) {
        this.onHover.emit({ cell, isHovered });
    }
    changeViewMode(event) {
        this.onViewMode.emit(event);
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: BsYearsCalendarViewComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
    static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.2", type: BsYearsCalendarViewComponent, isStandalone: true, selector: "bs-years-calendar-view", inputs: { calendar: "calendar" }, outputs: { onNavigate: "onNavigate", onViewMode: "onViewMode", onSelect: "onSelect", onHover: "onHover" }, ngImport: i0, template: `
    <bs-calendar-layout>
      <bs-datepicker-navigation-view
        [calendar]="calendar"
        (onNavigate)="navigateTo($event)"
        (onViewMode)="changeViewMode($event)"
      ></bs-datepicker-navigation-view>
    
      <table role="grid" class="years">
        <tbody>
          @for (row of calendar?.years; track row) {
            <tr>
              @for (year of row; track year) {
                <td role="gridcell"
                  (click)="viewYear(year)"
                  (mouseenter)="hoverYear(year, true)"
                  (mouseleave)="hoverYear(year, false)"
                  [class.disabled]="year.isDisabled"
                  [class.is-highlighted]="year.isHovered">
                  <span [class.selected]="year.isSelected">{{ year.label }}</span>
                </td>
              }
            </tr>
          }
        </tbody>
      </table>
    </bs-calendar-layout>
    `, isInline: true, dependencies: [{ kind: "component", type: BsCalendarLayoutComponent, selector: "bs-calendar-layout" }, { kind: "component", type: BsDatepickerNavigationViewComponent, selector: "bs-datepicker-navigation-view", inputs: ["calendar", "isDisabled"], outputs: ["onNavigate", "onViewMode"] }], changeDetection: i0.ChangeDetectionStrategy.Eager }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: BsYearsCalendarViewComponent, decorators: [{
            type: Component,
            args: [{
                    selector: 'bs-years-calendar-view',
                    changeDetection: ChangeDetectionStrategy.Eager,
                    template: `
    <bs-calendar-layout>
      <bs-datepicker-navigation-view
        [calendar]="calendar"
        (onNavigate)="navigateTo($event)"
        (onViewMode)="changeViewMode($event)"
      ></bs-datepicker-navigation-view>
    
      <table role="grid" class="years">
        <tbody>
          @for (row of calendar?.years; track row) {
            <tr>
              @for (year of row; track year) {
                <td role="gridcell"
                  (click)="viewYear(year)"
                  (mouseenter)="hoverYear(year, true)"
                  (mouseleave)="hoverYear(year, false)"
                  [class.disabled]="year.isDisabled"
                  [class.is-highlighted]="year.isHovered">
                  <span [class.selected]="year.isSelected">{{ year.label }}</span>
                </td>
              }
            </tr>
          }
        </tbody>
      </table>
    </bs-calendar-layout>
    `,
                    standalone: true,
                    imports: [BsCalendarLayoutComponent, BsDatepickerNavigationViewComponent]
                }]
        }], propDecorators: { calendar: [{
                type: Input
            }], onNavigate: [{
                type: Output
            }], onViewMode: [{
                type: Output
            }], onSelect: [{
                type: Output
            }], onHover: [{
                type: Output
            }] } });

class BsMonthCalendarViewComponent {
    constructor() {
        this.onNavigate = new EventEmitter();
        this.onViewMode = new EventEmitter();
        this.onSelect = new EventEmitter();
        this.onHover = new EventEmitter();
    }
    navigateTo(event) {
        const step = BsNavigationDirection.DOWN === event ? -1 : 1;
        this.onNavigate.emit({ step: { year: step } });
    }
    viewMonth(month) {
        this.onSelect.emit(month);
    }
    hoverMonth(cell, isHovered) {
        this.onHover.emit({ cell, isHovered });
    }
    changeViewMode(event) {
        this.onViewMode.emit(event);
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: BsMonthCalendarViewComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
    static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.2", type: BsMonthCalendarViewComponent, isStandalone: true, selector: "bs-month-calendar-view", inputs: { calendar: "calendar" }, outputs: { onNavigate: "onNavigate", onViewMode: "onViewMode", onSelect: "onSelect", onHover: "onHover" }, ngImport: i0, template: `
    <bs-calendar-layout>
      <bs-datepicker-navigation-view
        [calendar]="calendar"
        (onNavigate)="navigateTo($event)"
        (onViewMode)="changeViewMode($event)"
      ></bs-datepicker-navigation-view>
    
      <table role="grid" class="months">
        <tbody>
          @for (row of calendar?.months; track row) {
            <tr>
              @for (month of row; track month) {
                <td role="gridcell"
                  (click)="viewMonth(month)"
                  (mouseenter)="hoverMonth(month, true)"
                  (mouseleave)="hoverMonth(month, false)"
                  [class.disabled]="month.isDisabled"
                  [class.is-highlighted]="month.isHovered">
                  <span [class.selected]="month.isSelected">{{ month.label }}</span>
                </td>
              }
            </tr>
          }
        </tbody>
      </table>
    </bs-calendar-layout>
    `, isInline: true, dependencies: [{ kind: "component", type: BsCalendarLayoutComponent, selector: "bs-calendar-layout" }, { kind: "component", type: BsDatepickerNavigationViewComponent, selector: "bs-datepicker-navigation-view", inputs: ["calendar", "isDisabled"], outputs: ["onNavigate", "onViewMode"] }], changeDetection: i0.ChangeDetectionStrategy.Eager }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: BsMonthCalendarViewComponent, decorators: [{
            type: Component,
            args: [{
                    selector: 'bs-month-calendar-view',
                    changeDetection: ChangeDetectionStrategy.Eager,
                    template: `
    <bs-calendar-layout>
      <bs-datepicker-navigation-view
        [calendar]="calendar"
        (onNavigate)="navigateTo($event)"
        (onViewMode)="changeViewMode($event)"
      ></bs-datepicker-navigation-view>
    
      <table role="grid" class="months">
        <tbody>
          @for (row of calendar?.months; track row) {
            <tr>
              @for (month of row; track month) {
                <td role="gridcell"
                  (click)="viewMonth(month)"
                  (mouseenter)="hoverMonth(month, true)"
                  (mouseleave)="hoverMonth(month, false)"
                  [class.disabled]="month.isDisabled"
                  [class.is-highlighted]="month.isHovered">
                  <span [class.selected]="month.isSelected">{{ month.label }}</span>
                </td>
              }
            </tr>
          }
        </tbody>
      </table>
    </bs-calendar-layout>
    `,
                    standalone: true,
                    imports: [BsCalendarLayoutComponent, BsDatepickerNavigationViewComponent]
                }]
        }], propDecorators: { calendar: [{
                type: Input
            }], onNavigate: [{
                type: Output
            }], onViewMode: [{
                type: Output
            }], onSelect: [{
                type: Output
            }], onHover: [{
                type: Output
            }] } });

class BsDatepickerDayDecoratorComponent {
    constructor(_config, _elRef, _renderer) {
        this._config = _config;
        this._elRef = _elRef;
        this._renderer = _renderer;
        this.day = { date: new Date(), label: '' };
    }
    ngOnInit() {
        if (this.day?.isToday && this._config && this._config.customTodayClass) {
            this._renderer.addClass(this._elRef.nativeElement, this._config.customTodayClass);
        }
        if (typeof this.day?.customClasses === 'string') {
            this.day?.customClasses.split(' ')
                .filter((className) => className)
                .forEach((className) => {
                this._renderer.addClass(this._elRef.nativeElement, className);
            });
        }
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: BsDatepickerDayDecoratorComponent, deps: [{ token: BsDatepickerConfig }, { token: i0.ElementRef }, { token: i0.Renderer2 }], target: i0.ɵɵFactoryTarget.Component }); }
    static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "22.0.2", type: BsDatepickerDayDecoratorComponent, isStandalone: true, selector: "[bsDatepickerDayDecorator]", inputs: { day: "day" }, host: { properties: { "class.disabled": "day.isDisabled", "class.is-highlighted": "day.isHovered", "class.is-other-month": "day.isOtherMonth", "class.is-active-other-month": "day.isOtherMonthHovered", "class.in-range": "day.isInRange", "class.select-start": "day.isSelectionStart", "class.select-end": "day.isSelectionEnd", "class.selected": "day.isSelected" } }, ngImport: i0, template: `{{ day && day.label || '' }}`, isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: BsDatepickerDayDecoratorComponent, decorators: [{
            type: Component,
            args: [{
                    selector: '[bsDatepickerDayDecorator]',
                    changeDetection: ChangeDetectionStrategy.OnPush,
                    host: {
                        '[class.disabled]': 'day.isDisabled',
                        '[class.is-highlighted]': 'day.isHovered',
                        '[class.is-other-month]': 'day.isOtherMonth',
                        '[class.is-active-other-month]': 'day.isOtherMonthHovered',
                        '[class.in-range]': 'day.isInRange',
                        '[class.select-start]': 'day.isSelectionStart',
                        '[class.select-end]': 'day.isSelectionEnd',
                        '[class.selected]': 'day.isSelected'
                    },
                    template: `{{ day && day.label || '' }}`,
                    standalone: true
                }]
        }], ctorParameters: () => [{ type: BsDatepickerConfig }, { type: i0.ElementRef }, { type: i0.Renderer2 }], propDecorators: { day: [{
                type: Input
            }] } });

class BsDaysCalendarViewComponent {
    constructor(_config) {
        this._config = _config;
        this.onNavigate = new EventEmitter();
        this.onViewMode = new EventEmitter();
        this.onSelect = new EventEmitter();
        this.onHover = new EventEmitter();
        this.onHoverWeek = new EventEmitter();
        this.isiOS = (/iPad|iPhone|iPod/.test(navigator.platform) ||
            (navigator.platform === 'MacIntel' && navigator.maxTouchPoints > 1));
        if (this._config.dateTooltipTexts && this._config.dateTooltipTexts.length > 0) {
            this.isShowTooltip = true;
        }
    }
    navigateTo(event) {
        const step = BsNavigationDirection.DOWN === event ? -1 : 1;
        this.onNavigate.emit({ step: { month: step } });
    }
    changeViewMode(event) {
        this.onViewMode.emit(event);
    }
    selectDay(event) {
        this.onSelect.emit(event);
    }
    selectWeek(week) {
        if (!this._config.selectWeek && !this._config.selectWeekDateRange) {
            return;
        }
        if (week.days.length === 0) {
            return;
        }
        if (this._config.selectWeek && week.days[0]
            && !week.days[0].isDisabled
            && this._config.selectFromOtherMonth) {
            this.onSelect.emit(week.days[0]);
            return;
        }
        const selectedDay = week.days.find((day) => {
            return this._config.selectFromOtherMonth
                ? !day.isDisabled
                : !day.isOtherMonth && !day.isDisabled;
        });
        this.onSelect.emit(selectedDay);
        if (this._config.selectWeekDateRange) {
            const days = week.days.slice(0);
            const lastDayOfRange = days.reverse().find((day) => {
                return this._config.selectFromOtherMonth
                    ? !day.isDisabled
                    : !day.isOtherMonth && !day.isDisabled;
            });
            this.onSelect.emit(lastDayOfRange);
        }
    }
    weekHoverHandler(cell, isHovered) {
        if (!this._config.selectWeek && !this._config.selectWeekDateRange) {
            return;
        }
        const hasActiveDays = cell.days.find((day) => {
            return this._config.selectFromOtherMonth
                ? !day.isDisabled
                : !day.isOtherMonth && !day.isDisabled;
        });
        if (hasActiveDays) {
            cell.isHovered = isHovered;
            this.isWeekHovered = isHovered;
            this.onHoverWeek.emit(cell);
        }
    }
    hoverDay(cell, isHovered) {
        if (this._config.selectFromOtherMonth && cell.isOtherMonth) {
            cell.isOtherMonthHovered = isHovered;
        }
        if (this._config.dateTooltipTexts) {
            cell.tooltipText = '';
            this._config.dateTooltipTexts.forEach((dateData) => {
                if (isSameDay(dateData.date, cell.date)) {
                    cell.tooltipText = dateData.tooltipText;
                    return;
                }
            });
        }
        this.onHover.emit({ cell, isHovered });
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: BsDaysCalendarViewComponent, deps: [{ token: BsDatepickerConfig }], target: i0.ɵɵFactoryTarget.Component }); }
    static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.2", type: BsDaysCalendarViewComponent, isStandalone: true, selector: "bs-days-calendar-view", inputs: { calendar: "calendar", options: "options", isDisabled: "isDisabled" }, outputs: { onNavigate: "onNavigate", onViewMode: "onViewMode", onSelect: "onSelect", onHover: "onHover", onHoverWeek: "onHoverWeek" }, ngImport: i0, template: `
    <bs-calendar-layout>
      <bs-datepicker-navigation-view
        [calendar]="calendar"
        [isDisabled]="!!isDisabled"
        (onNavigate)="navigateTo($event)"
        (onViewMode)="changeViewMode($event)"
      ></bs-datepicker-navigation-view>
      <!--days matrix-->
      <table role="grid" class="days weeks">
        <thead>
          <tr>
            <!--if show weeks-->
            @if (options && options.showWeekNumbers) {
              <th></th>
            }
            @for (weekday of calendar.weekdays; track weekday; let i = $index) {
              <th
                aria-label="weekday">{{ calendar.weekdays[i] }}
              </th>
            }
          </tr>
        </thead>
        <tbody>
          @for (week of calendar.weeks; track week; let i = $index) {
            <tr>
              @if (options && options.showWeekNumbers) {
                <td class="week" [class.active-week]="isWeekHovered" >
                  @if (isiOS) {
                    <span (click)="selectWeek(week)">{{ calendar.weekNumbers[i] }}</span>
                  }
                  @if (!isiOS) {
                    <span
                      (click)="selectWeek(week)"
                      (mouseenter)="weekHoverHandler(week, true)"
                    (mouseleave)="weekHoverHandler(week, false)">{{ calendar.weekNumbers[i] }}</span>
                  }
                </td>
              }
              @for (day of week.days; track day) {
                <td role="gridcell">
                  <!-- When we want to show tooltips for dates -->
                  @if (!isiOS && isShowTooltip) {
                    <span bsDatepickerDayDecorator
                      [day]="day"
                      (click)="selectDay(day)"
                      tooltip="{{day.tooltipText}}"
                      (mouseenter)="hoverDay(day, true)"
                    (mouseleave)="hoverDay(day, false)">{{ day.label }} 3</span>
                  }
                  <!-- When tooltips for dates are disabled -->
                  @if (!isiOS && !isShowTooltip) {
                    <span bsDatepickerDayDecorator
                      [day]="day"
                      (click)="selectDay(day)"
                      (mouseenter)="hoverDay(day, true)"
                    (mouseleave)="hoverDay(day, false)">{{ day.label }} 2</span>
                  }
                  <!-- For mobile iOS view, tooltips are not needed -->
                  @if (isiOS) {
                    <span bsDatepickerDayDecorator
                      [day]="day"
                    (click)="selectDay(day)">{{ day.label }} 1</span>
                  }
                </td>
              }
            </tr>
          }
        </tbody>
      </table>
    
    </bs-calendar-layout>
    `, isInline: true, dependencies: [{ kind: "component", type: BsCalendarLayoutComponent, selector: "bs-calendar-layout" }, { kind: "component", type: BsDatepickerNavigationViewComponent, selector: "bs-datepicker-navigation-view", inputs: ["calendar", "isDisabled"], outputs: ["onNavigate", "onViewMode"] }, { kind: "component", type: BsDatepickerDayDecoratorComponent, selector: "[bsDatepickerDayDecorator]", inputs: ["day"] }, { kind: "ngmodule", type: TooltipModule }, { kind: "directive", type: i2.TooltipDirective, selector: "[tooltip], [tooltipHtml]", inputs: ["adaptivePosition", "tooltip", "placement", "triggers", "container", "containerClass", "boundariesElement", "isDisabled", "delay", "tooltipHtml", "tooltipPlacement", "tooltipIsOpen", "tooltipEnable", "tooltipAppendToBody", "tooltipAnimation", "tooltipClass", "tooltipContext", "tooltipPopupDelay", "tooltipFadeDuration", "tooltipTrigger"], outputs: ["tooltipChange", "tooltipStateChanged"], exportAs: ["bs-tooltip"] }], changeDetection: i0.ChangeDetectionStrategy.Eager }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: BsDaysCalendarViewComponent, decorators: [{
            type: Component,
            args: [{
                    selector: 'bs-days-calendar-view',
                    // changeDetection: ChangeDetectionStrategy.OnPush,
                    template: `
    <bs-calendar-layout>
      <bs-datepicker-navigation-view
        [calendar]="calendar"
        [isDisabled]="!!isDisabled"
        (onNavigate)="navigateTo($event)"
        (onViewMode)="changeViewMode($event)"
      ></bs-datepicker-navigation-view>
      <!--days matrix-->
      <table role="grid" class="days weeks">
        <thead>
          <tr>
            <!--if show weeks-->
            @if (options && options.showWeekNumbers) {
              <th></th>
            }
            @for (weekday of calendar.weekdays; track weekday; let i = $index) {
              <th
                aria-label="weekday">{{ calendar.weekdays[i] }}
              </th>
            }
          </tr>
        </thead>
        <tbody>
          @for (week of calendar.weeks; track week; let i = $index) {
            <tr>
              @if (options && options.showWeekNumbers) {
                <td class="week" [class.active-week]="isWeekHovered" >
                  @if (isiOS) {
                    <span (click)="selectWeek(week)">{{ calendar.weekNumbers[i] }}</span>
                  }
                  @if (!isiOS) {
                    <span
                      (click)="selectWeek(week)"
                      (mouseenter)="weekHoverHandler(week, true)"
                    (mouseleave)="weekHoverHandler(week, false)">{{ calendar.weekNumbers[i] }}</span>
                  }
                </td>
              }
              @for (day of week.days; track day) {
                <td role="gridcell">
                  <!-- When we want to show tooltips for dates -->
                  @if (!isiOS && isShowTooltip) {
                    <span bsDatepickerDayDecorator
                      [day]="day"
                      (click)="selectDay(day)"
                      tooltip="{{day.tooltipText}}"
                      (mouseenter)="hoverDay(day, true)"
                    (mouseleave)="hoverDay(day, false)">{{ day.label }} 3</span>
                  }
                  <!-- When tooltips for dates are disabled -->
                  @if (!isiOS && !isShowTooltip) {
                    <span bsDatepickerDayDecorator
                      [day]="day"
                      (click)="selectDay(day)"
                      (mouseenter)="hoverDay(day, true)"
                    (mouseleave)="hoverDay(day, false)">{{ day.label }} 2</span>
                  }
                  <!-- For mobile iOS view, tooltips are not needed -->
                  @if (isiOS) {
                    <span bsDatepickerDayDecorator
                      [day]="day"
                    (click)="selectDay(day)">{{ day.label }} 1</span>
                  }
                </td>
              }
            </tr>
          }
        </tbody>
      </table>
    
    </bs-calendar-layout>
    `,
                    standalone: true,
                    changeDetection: ChangeDetectionStrategy.Eager,
                    imports: [BsCalendarLayoutComponent, BsDatepickerNavigationViewComponent, BsDatepickerDayDecoratorComponent, TooltipModule]
                }]
        }], ctorParameters: () => [{ type: BsDatepickerConfig }], propDecorators: { calendar: [{
                type: Input
            }], options: [{
                type: Input
            }], isDisabled: [{
                type: Input
            }], onNavigate: [{
                type: Output
            }], onViewMode: [{
                type: Output
            }], onSelect: [{
                type: Output
            }], onHover: [{
                type: Output
            }], onHoverWeek: [{
                type: Output
            }] } });

class BsDatepickerContainerComponent extends BsDatepickerAbstractComponent {
    set value(value) {
        this._effects?.setValue(value);
    }
    get isDatePickerDisabled() {
        return !!this._config.isDisabled;
    }
    get isDatepickerDisabled() {
        return this.isDatePickerDisabled ? '' : null;
    }
    get isDatepickerReadonly() {
        return this.isDatePickerDisabled ? '' : null;
    }
    constructor(_renderer, _config, _store, _element, _actions, _effects, _positionService) {
        super();
        this._renderer = _renderer;
        this._config = _config;
        this._store = _store;
        this._element = _element;
        this._actions = _actions;
        this._positionService = _positionService;
        this.valueChange = new EventEmitter();
        this.isRangePicker = false;
        this._subs = [];
        this._effects = _effects;
        _renderer.setStyle(_element.nativeElement, 'display', 'block');
        _renderer.setStyle(_element.nativeElement, 'position', 'absolute');
    }
    ngOnInit() {
        this._positionService.setOptions({
            modifiers: {
                flip: {
                    enabled: this._config.adaptivePosition
                },
                preventOverflow: {
                    enabled: this._config.adaptivePosition
                }
            },
            allowedPositions: this._config.allowedPositions
        });
        this._positionService.event$?.pipe(take(1)).subscribe(() => {
            this._positionService.disable();
            if (this._config.isAnimated) {
                const containerEl = this._element.nativeElement.querySelector('.bs-datepicker-container');
                if (containerEl) {
                    this._animateExpand(containerEl, () => this.positionServiceEnable());
                }
                else {
                    this.positionServiceEnable();
                }
                return;
            }
            this.positionServiceEnable();
        });
        this.isOtherMonthsActive = this._config.selectFromOtherMonth;
        this.containerClass = this._config.containerClass;
        this.showTodayBtn = this._config.showTodayButton;
        this.todayBtnLbl = this._config.todayButtonLabel;
        this.todayPos = this._config.todayPosition;
        this.showClearBtn = this._config.showClearButton;
        this.clearBtnLbl = this._config.clearButtonLabel;
        this.clearPos = this._config.clearPosition;
        this.customRangeBtnLbl = this._config.customRangeButtonLabel;
        this.withTimepicker = this._config.withTimepicker;
        this._effects
            ?.init(this._store)
            // intial state options
            .setOptions(this._config)
            // data binding view --> model
            .setBindings(this)
            // set event handlers
            .setEventHandlers(this)
            .registerDatepickerSideEffects();
        let currentDate;
        // todo: move it somewhere else
        // on selected date change
        this._subs.push(this._store
            .select((state) => state.selectedDate)
            .subscribe((date) => {
            currentDate = date;
            this.valueChange.emit(date);
        }));
        this._subs.push(this._store
            .select((state) => state.selectedTime)
            .subscribe((time) => {
            if (!time || !time[0] || !(time[0] instanceof Date) || time[0] === currentDate) {
                return;
            }
            this.valueChange.emit(time[0]);
        }));
        this._store.dispatch(this._actions.changeViewMode(this._config.startView));
    }
    ngAfterViewInit() {
        this.selectedTimeSub.add(this.selectedTime?.subscribe((val) => {
            if (Array.isArray(val) && val.length >= 1) {
                this.startTimepicker?.writeValue(val[0]);
            }
        }));
        this.startTimepicker?.registerOnChange((val) => {
            this.timeSelectHandler(val, 0);
        });
    }
    get isTopPosition() {
        return this._element.nativeElement.classList.contains('top');
    }
    positionServiceEnable() {
        this._positionService.enable();
    }
    timeSelectHandler(date, index) {
        this._store.dispatch(this._actions.selectTime(date, index));
    }
    daySelectHandler(day) {
        if (!day) {
            return;
        }
        const isDisabled = this.isOtherMonthsActive ? day.isDisabled : day.isOtherMonth || day.isDisabled;
        if (isDisabled) {
            return;
        }
        this._store.dispatch(this._actions.select(day.date));
    }
    monthSelectHandler(day) {
        if (!day || day.isDisabled) {
            return;
        }
        this._store.dispatch(this._actions.navigateTo({
            unit: {
                month: getMonth(day.date),
                year: getFullYear(day.date)
            },
            viewMode: 'day'
        }));
    }
    yearSelectHandler(day) {
        if (!day || day.isDisabled) {
            return;
        }
        this._store.dispatch(this._actions.navigateTo({
            unit: {
                year: getFullYear(day.date)
            },
            viewMode: 'month'
        }));
    }
    setToday() {
        this._store.dispatch(this._actions.select(new Date()));
    }
    clearDate() {
        this._store.dispatch(this._actions.select(undefined));
    }
    _animateExpand(el, onDone) {
        this._cancelExpandAnimation?.();
        this._cancelExpandAnimation = animateExpand(this._renderer, el, {
            timing: DATEPICKER_ANIMATION_TIMING,
            durationMs: DATEPICKER_ANIMATION_DURATION_MS,
            useRaf: true,
            manageDisplay: true,
            onDone
        });
    }
    ngOnDestroy() {
        this._cancelExpandAnimation?.();
        for (const sub of this._subs) {
            sub.unsubscribe();
        }
        this.selectedTimeSub.unsubscribe();
        this._effects?.destroy();
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: BsDatepickerContainerComponent, deps: [{ token: i0.Renderer2 }, { token: BsDatepickerConfig }, { token: BsDatepickerStore }, { token: i0.ElementRef }, { token: BsDatepickerActions }, { token: BsDatepickerEffects }, { token: i5.PositioningService }], target: i0.ɵɵFactoryTarget.Component }); }
    static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.2", type: BsDatepickerContainerComponent, isStandalone: true, selector: "bs-datepicker-container", host: { attributes: { "role": "dialog", "aria-label": "calendar" }, listeners: { "click": "_stopPropagation($event)" }, properties: { "attr.disabled": "this.isDatepickerDisabled", "attr.readonly": "this.isDatepickerReadonly" }, classAttribute: "bottom" }, providers: [BsDatepickerStore, BsDatepickerEffects, BsDatepickerActions], viewQueries: [{ propertyName: "startTimepicker", first: true, predicate: ["startTP"], descendants: true }], usesInheritance: true, ngImport: i0, template: "<!-- days calendar view mode -->\n@if (viewMode | async) {\n  <div class=\"bs-datepicker\" [ngClass]=\"containerClass\">\n    <div class=\"bs-datepicker-container\">\n      <!--calendars-->\n      <div class=\"bs-calendar-container\" role=\"application\">\n        @switch (viewMode | async) {\n          <!--days calendar-->\n          @case ('day') {\n            <div class=\"bs-media-container\">\n              @for (calendar of daysCalendar$ | async; track calendar) {\n                <bs-days-calendar-view\n                  [class.bs-datepicker-multiple]=\"multipleCalendars\"\n                  [calendar]=\"calendar\"\n                  [isDisabled]=\"isDatePickerDisabled\"\n                  [options]=\"options$ | async\"\n                  (onNavigate)=\"navigateTo($event)\"\n                  (onViewMode)=\"setViewMode($event)\"\n                  (onHover)=\"dayHoverHandler($event)\"\n                  (onHoverWeek)=\"weekHoverHandler($event)\"\n                  (onSelect)=\"daySelectHandler($event)\">\n                </bs-days-calendar-view>\n              }\n            </div>\n            @if (withTimepicker) {\n              <div class=\"bs-timepicker-in-datepicker-container\">\n                <timepicker #startTP [disabled]=\"isDatePickerDisabled\"></timepicker>\n                @if (isRangePicker) {\n                  <timepicker #endTP [disabled]=\"isDatePickerDisabled\"></timepicker>\n                }\n              </div>\n            }\n          }\n          <!--months calendar-->\n          @case ('month') {\n            <div class=\"bs-media-container\">\n              @for (calendar of monthsCalendar | async; track calendar) {\n                <bs-month-calendar-view\n                  [class.bs-datepicker-multiple]=\"multipleCalendars\"\n                  [calendar]=\"calendar\"\n                  (onNavigate)=\"navigateTo($event)\"\n                  (onViewMode)=\"setViewMode($event)\"\n                  (onHover)=\"monthHoverHandler($event)\"\n                  (onSelect)=\"monthSelectHandler($event)\">\n                </bs-month-calendar-view>\n              }\n            </div>\n          }\n          <!--years calendar-->\n          @case ('year') {\n            <div class=\"bs-media-container\">\n              @for (calendar of yearsCalendar | async; track calendar) {\n                <bs-years-calendar-view\n                  [class.bs-datepicker-multiple]=\"multipleCalendars\"\n                  [calendar]=\"calendar\"\n                  (onNavigate)=\"navigateTo($event)\"\n                  (onViewMode)=\"setViewMode($event)\"\n                  (onHover)=\"yearHoverHandler($event)\"\n                  (onSelect)=\"yearSelectHandler($event)\">\n                </bs-years-calendar-view>\n              }\n            </div>\n          }\n        }\n      </div>\n      <!--applycancel buttons-->\n      @if (false) {\n        <div class=\"bs-datepicker-buttons\">\n          <button class=\"btn btn-success\" type=\"button\">Apply</button>\n          <button class=\"btn btn-default\" type=\"button\">Cancel</button>\n        </div>\n      }\n      @if (showTodayBtn || showClearBtn) {\n        <div class=\"bs-datepicker-buttons\">\n          @if (showTodayBtn) {\n            <div class=\"btn-today-wrapper\"\n              [class.today-left]=\"todayPos === 'left'\"\n              [class.today-right]=\"todayPos === 'right'\"\n              [class.today-center]=\"todayPos === 'center'\"\n              >\n              <button class=\"btn btn-success\" (click)=\"setToday()\">{{todayBtnLbl}}</button>\n            </div>\n          }\n          @if (showClearBtn) {\n            <div class=\"btn-clear-wrapper\"\n              [class.clear-left]=\"clearPos === 'left'\"\n              [class.clear-right]=\"clearPos === 'right'\"\n              [class.clear-center]=\"clearPos === 'center'\"\n              >\n              <button class=\"btn btn-success\" (click)=\"clearDate()\">{{clearBtnLbl}}</button>\n            </div>\n          }\n        </div>\n      }\n    </div>\n    <!--custom dates or date ranges picker-->\n    @if (customRanges && customRanges.length > 0) {\n      <div class=\"bs-datepicker-custom-range\">\n        <bs-custom-date-view\n          [selectedRange]=\"chosenRange\"\n          [ranges]=\"customRanges\"\n          [customRangeLabel]=\"customRangeBtnLbl\"\n          (onSelect)=\"setRangeOnCalendar($event)\">\n        </bs-custom-date-view>\n      </div>\n    }\n  </div>\n}\n", dependencies: [{ kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "component", type: BsDaysCalendarViewComponent, selector: "bs-days-calendar-view", inputs: ["calendar", "options", "isDisabled"], outputs: ["onNavigate", "onViewMode", "onSelect", "onHover", "onHoverWeek"] }, { kind: "ngmodule", type: TimepickerModule }, { kind: "component", type: i6.TimepickerComponent, selector: "timepicker", inputs: ["hourStep", "minuteStep", "secondsStep", "readonlyInput", "disabled", "mousewheel", "arrowkeys", "showSpinners", "showMeridian", "showMinutes", "showSeconds", "meridians", "min", "max", "hoursPlaceholder", "minutesPlaceholder", "secondsPlaceholder"], outputs: ["isValid", "meridianChange"] }, { kind: "component", type: BsMonthCalendarViewComponent, selector: "bs-month-calendar-view", inputs: ["calendar"], outputs: ["onNavigate", "onViewMode", "onSelect", "onHover"] }, { kind: "component", type: BsYearsCalendarViewComponent, selector: "bs-years-calendar-view", inputs: ["calendar"], outputs: ["onNavigate", "onViewMode", "onSelect", "onHover"] }, { kind: "component", type: BsCustomDatesViewComponent, selector: "bs-custom-date-view", inputs: ["ranges", "selectedRange", "customRangeLabel"], outputs: ["onSelect"] }, { kind: "pipe", type: AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.Eager }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: BsDatepickerContainerComponent, decorators: [{
            type: Component,
            args: [{ selector: 'bs-datepicker-container', changeDetection: ChangeDetectionStrategy.Eager, providers: [BsDatepickerStore, BsDatepickerEffects, BsDatepickerActions], host: {
                        class: 'bottom',
                        '(click)': '_stopPropagation($event)',
                        role: 'dialog',
                        'aria-label': 'calendar'
                    }, standalone: true, imports: [NgClass, BsDaysCalendarViewComponent, TimepickerModule, BsMonthCalendarViewComponent, BsYearsCalendarViewComponent, BsCustomDatesViewComponent, AsyncPipe], template: "<!-- days calendar view mode -->\n@if (viewMode | async) {\n  <div class=\"bs-datepicker\" [ngClass]=\"containerClass\">\n    <div class=\"bs-datepicker-container\">\n      <!--calendars-->\n      <div class=\"bs-calendar-container\" role=\"application\">\n        @switch (viewMode | async) {\n          <!--days calendar-->\n          @case ('day') {\n            <div class=\"bs-media-container\">\n              @for (calendar of daysCalendar$ | async; track calendar) {\n                <bs-days-calendar-view\n                  [class.bs-datepicker-multiple]=\"multipleCalendars\"\n                  [calendar]=\"calendar\"\n                  [isDisabled]=\"isDatePickerDisabled\"\n                  [options]=\"options$ | async\"\n                  (onNavigate)=\"navigateTo($event)\"\n                  (onViewMode)=\"setViewMode($event)\"\n                  (onHover)=\"dayHoverHandler($event)\"\n                  (onHoverWeek)=\"weekHoverHandler($event)\"\n                  (onSelect)=\"daySelectHandler($event)\">\n                </bs-days-calendar-view>\n              }\n            </div>\n            @if (withTimepicker) {\n              <div class=\"bs-timepicker-in-datepicker-container\">\n                <timepicker #startTP [disabled]=\"isDatePickerDisabled\"></timepicker>\n                @if (isRangePicker) {\n                  <timepicker #endTP [disabled]=\"isDatePickerDisabled\"></timepicker>\n                }\n              </div>\n            }\n          }\n          <!--months calendar-->\n          @case ('month') {\n            <div class=\"bs-media-container\">\n              @for (calendar of monthsCalendar | async; track calendar) {\n                <bs-month-calendar-view\n                  [class.bs-datepicker-multiple]=\"multipleCalendars\"\n                  [calendar]=\"calendar\"\n                  (onNavigate)=\"navigateTo($event)\"\n                  (onViewMode)=\"setViewMode($event)\"\n                  (onHover)=\"monthHoverHandler($event)\"\n                  (onSelect)=\"monthSelectHandler($event)\">\n                </bs-month-calendar-view>\n              }\n            </div>\n          }\n          <!--years calendar-->\n          @case ('year') {\n            <div class=\"bs-media-container\">\n              @for (calendar of yearsCalendar | async; track calendar) {\n                <bs-years-calendar-view\n                  [class.bs-datepicker-multiple]=\"multipleCalendars\"\n                  [calendar]=\"calendar\"\n                  (onNavigate)=\"navigateTo($event)\"\n                  (onViewMode)=\"setViewMode($event)\"\n                  (onHover)=\"yearHoverHandler($event)\"\n                  (onSelect)=\"yearSelectHandler($event)\">\n                </bs-years-calendar-view>\n              }\n            </div>\n          }\n        }\n      </div>\n      <!--applycancel buttons-->\n      @if (false) {\n        <div class=\"bs-datepicker-buttons\">\n          <button class=\"btn btn-success\" type=\"button\">Apply</button>\n          <button class=\"btn btn-default\" type=\"button\">Cancel</button>\n        </div>\n      }\n      @if (showTodayBtn || showClearBtn) {\n        <div class=\"bs-datepicker-buttons\">\n          @if (showTodayBtn) {\n            <div class=\"btn-today-wrapper\"\n              [class.today-left]=\"todayPos === 'left'\"\n              [class.today-right]=\"todayPos === 'right'\"\n              [class.today-center]=\"todayPos === 'center'\"\n              >\n              <button class=\"btn btn-success\" (click)=\"setToday()\">{{todayBtnLbl}}</button>\n            </div>\n          }\n          @if (showClearBtn) {\n            <div class=\"btn-clear-wrapper\"\n              [class.clear-left]=\"clearPos === 'left'\"\n              [class.clear-right]=\"clearPos === 'right'\"\n              [class.clear-center]=\"clearPos === 'center'\"\n              >\n              <button class=\"btn btn-success\" (click)=\"clearDate()\">{{clearBtnLbl}}</button>\n            </div>\n          }\n        </div>\n      }\n    </div>\n    <!--custom dates or date ranges picker-->\n    @if (customRanges && customRanges.length > 0) {\n      <div class=\"bs-datepicker-custom-range\">\n        <bs-custom-date-view\n          [selectedRange]=\"chosenRange\"\n          [ranges]=\"customRanges\"\n          [customRangeLabel]=\"customRangeBtnLbl\"\n          (onSelect)=\"setRangeOnCalendar($event)\">\n        </bs-custom-date-view>\n      </div>\n    }\n  </div>\n}\n" }]
        }], ctorParameters: () => [{ type: i0.Renderer2 }, { type: BsDatepickerConfig }, { type: BsDatepickerStore }, { type: i0.ElementRef }, { type: BsDatepickerActions }, { type: BsDatepickerEffects }, { type: i5.PositioningService }], propDecorators: { startTimepicker: [{
                type: ViewChild,
                args: ['startTP']
            }], isDatepickerDisabled: [{
                type: HostBinding,
                args: ['attr.disabled']
            }], isDatepickerReadonly: [{
                type: HostBinding,
                args: ['attr.readonly']
            }] } });

let previousDate$1;
class BsDatepickerDirective {
    get readonlyValue() {
        return this.isDisabled ? '' : null;
    }
    constructor(_config, _elementRef, _renderer, _viewContainerRef, cis) {
        this._config = _config;
        this._elementRef = _elementRef;
        this._renderer = _renderer;
        /**
         * Placement of a datepicker. Accepts: "top", "bottom", "left", "right"
         */
        this.placement = 'bottom';
        /**
         * Specifies events that should trigger. Supports a space separated list of
         * event names.
         */
        this.triggers = 'click';
        /**
         * Close datepicker on outside click
         */
        this.outsideClick = true;
        /**
         * A selector specifying the element the datepicker should be appended to.
         */
        this.container = 'body';
        this.outsideEsc = true;
        this.isDestroy$ = new Subject();
        /**
         * Indicates whether datepicker's content is enabled or not
         */
        this.isDisabled = false;
        /**
         * Emits when datepicker value has been changed
         */
        this.bsValueChange = new EventEmitter();
        this._subs = [];
        this._dateInputFormat$ = new Subject();
        // todo: assign only subset of fields
        Object.assign(this, this._config);
        this._datepicker = cis.createLoader(_elementRef, _viewContainerRef, _renderer);
        this.onShown = this._datepicker.onShown;
        this.onHidden = this._datepicker.onHidden;
        this.isOpen$ = new BehaviorSubject(this.isOpen);
    }
    /**
     * Returns whether or not the datepicker is currently being shown
     */
    get isOpen() {
        return this._datepicker.isShown;
    }
    set isOpen(value) {
        this.isOpen$.next(value);
    }
    /**
     * Initial value of datepicker
     */
    set bsValue(value) {
        if (this._bsValue && value && this._bsValue.getTime() === value.getTime()) {
            return;
        }
        if (!this._bsValue && value && !this._config.withTimepicker) {
            const now = new Date();
            copyTime(value, now);
        }
        if (value && this.bsConfig?.initCurrentTime) {
            value = setCurrentTimeOnDateSelect(value);
        }
        this.initPreviousValue();
        this._bsValue = value;
        this.bsValueChange.emit(value);
    }
    get dateInputFormat$() {
        return this._dateInputFormat$;
    }
    ngOnInit() {
        this._datepicker.listen({
            outsideClick: this.outsideClick,
            outsideEsc: this.outsideEsc,
            triggers: this.triggers,
            show: () => this.show()
        });
        this.setConfig();
        this.initPreviousValue();
    }
    initPreviousValue() {
        previousDate$1 = this._bsValue;
    }
    ngOnChanges(changes) {
        if (changes["bsConfig"]) {
            if (changes["bsConfig"].currentValue?.initCurrentTime && changes["bsConfig"].currentValue?.initCurrentTime !== changes["bsConfig"].previousValue?.initCurrentTime && this._bsValue) {
                this.initPreviousValue();
                this._bsValue = setCurrentTimeOnDateSelect(this._bsValue);
                this.bsValueChange.emit(this._bsValue);
            }
            this.setConfig();
            this._dateInputFormat$.next(this.bsConfig && this.bsConfig.dateInputFormat);
        }
        if (!this._datepickerRef || !this._datepickerRef.instance) {
            return;
        }
        if (changes["minDate"]) {
            this._datepickerRef.instance.minDate = this.minDate;
        }
        if (changes["maxDate"]) {
            this._datepickerRef.instance.maxDate = this.maxDate;
        }
        if (changes["daysDisabled"]) {
            this._datepickerRef.instance.daysDisabled = this.daysDisabled;
        }
        if (changes["datesDisabled"]) {
            this._datepickerRef.instance.datesDisabled = this.datesDisabled;
        }
        if (changes["datesEnabled"]) {
            this._datepickerRef.instance.datesEnabled = this.datesEnabled;
        }
        if (changes["isDisabled"]) {
            this._datepickerRef.instance.isDisabled = this.isDisabled;
        }
        if (changes["dateCustomClasses"]) {
            this._datepickerRef.instance.dateCustomClasses = this.dateCustomClasses;
        }
        if (changes["dateTooltipTexts"]) {
            this._datepickerRef.instance.dateTooltipTexts = this.dateTooltipTexts;
        }
    }
    initSubscribes() {
        // if date changes from external source (model -> view)
        this._subs.push(this.bsValueChange.subscribe((value) => {
            if (this._datepickerRef) {
                this._datepickerRef.instance.value = value;
            }
        }));
        // if date changes from picker (view -> model)
        if (this._datepickerRef) {
            this._subs.push(this._datepickerRef.instance.valueChange.subscribe((value) => {
                this.initPreviousValue();
                this.bsValue = value;
                if (this.keepDatepickerModalOpened()) {
                    return;
                }
                this.hide();
            }));
        }
    }
    keepDatepickerModalOpened() {
        if (!previousDate$1 || !this.bsConfig?.keepDatepickerOpened || !this._config.withTimepicker) {
            return false;
        }
        return this.isDateSame();
    }
    isDateSame() {
        return (previousDate$1 instanceof Date
            && (this._bsValue?.getDate() === previousDate$1?.getDate())
            && (this._bsValue?.getMonth() === previousDate$1?.getMonth())
            && (this._bsValue?.getFullYear() === previousDate$1?.getFullYear()));
    }
    ngAfterViewInit() {
        this.isOpen$.pipe(filter(isOpen => isOpen !== this.isOpen), takeUntil(this.isDestroy$))
            .subscribe(() => this.toggle());
    }
    /**
     * Opens an element’s datepicker. This is considered a “manual” triggering of
     * the datepicker.
     */
    show() {
        if (this._datepicker.isShown) {
            return;
        }
        this.setConfig();
        this._datepickerRef = this._datepicker
            .provide({ provide: BsDatepickerConfig, useValue: this._config })
            .attach(BsDatepickerContainerComponent)
            .to(this.container)
            .position({ attachment: this.placement })
            .show({ placement: this.placement });
        this.initSubscribes();
    }
    /**
     * Closes an element’s datepicker. This is considered a “manual” triggering of
     * the datepicker.
     */
    hide() {
        if (this.isOpen) {
            this._datepicker.hide();
        }
        for (const sub of this._subs) {
            sub.unsubscribe();
        }
        if (this._config.returnFocusToInput) {
            this._renderer.selectRootElement(this._elementRef.nativeElement).focus();
        }
    }
    /**
     * Toggles an element’s datepicker. This is considered a “manual” triggering
     * of the datepicker.
     */
    toggle() {
        if (this.isOpen) {
            return this.hide();
        }
        this.show();
    }
    /**
     * Set config for datepicker
     */
    setConfig() {
        this._config = Object.assign({}, this._config, this.bsConfig, {
            value: this._config.keepDatesOutOfRules ? this._bsValue : checkBsValue(this._bsValue, this.maxDate || this.bsConfig && this.bsConfig.maxDate),
            isDisabled: this.isDisabled,
            minDate: this.minDate || this.bsConfig && this.bsConfig.minDate,
            maxDate: this.maxDate || this.bsConfig && this.bsConfig.maxDate,
            daysDisabled: this.daysDisabled || this.bsConfig && this.bsConfig.daysDisabled,
            dateCustomClasses: this.dateCustomClasses || this.bsConfig && this.bsConfig.dateCustomClasses,
            dateTooltipTexts: this.dateTooltipTexts || this.bsConfig && this.bsConfig.dateTooltipTexts,
            datesDisabled: this.datesDisabled || this.bsConfig && this.bsConfig.datesDisabled,
            datesEnabled: this.datesEnabled || this.bsConfig && this.bsConfig.datesEnabled,
            minMode: this.minMode || this.bsConfig && this.bsConfig.minMode,
            initCurrentTime: this.bsConfig?.initCurrentTime,
            keepDatepickerOpened: this.bsConfig?.keepDatepickerOpened,
            keepDatesOutOfRules: this.bsConfig?.keepDatesOutOfRules
        });
    }
    unsubscribeSubscriptions() {
        if (this._subs?.length) {
            this._subs.map(sub => sub.unsubscribe());
            this._subs.length = 0;
        }
    }
    ngOnDestroy() {
        this._datepicker.dispose();
        this.isOpen$.next(false);
        if (this.isDestroy$) {
            this.isDestroy$.next(null);
            this.isDestroy$.complete();
        }
        this.unsubscribeSubscriptions();
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: BsDatepickerDirective, deps: [{ token: BsDatepickerConfig }, { token: i0.ElementRef }, { token: i0.Renderer2 }, { token: i0.ViewContainerRef }, { token: i2$1.ComponentLoaderFactory }], target: i0.ɵɵFactoryTarget.Directive }); }
    static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "22.0.2", type: BsDatepickerDirective, isStandalone: true, selector: "[bsDatepicker]", inputs: { placement: "placement", triggers: "triggers", outsideClick: "outsideClick", container: "container", outsideEsc: "outsideEsc", isDisabled: "isDisabled", minDate: "minDate", maxDate: "maxDate", ignoreMinMaxErrors: "ignoreMinMaxErrors", minMode: "minMode", daysDisabled: "daysDisabled", datesDisabled: "datesDisabled", datesEnabled: "datesEnabled", dateCustomClasses: "dateCustomClasses", dateTooltipTexts: "dateTooltipTexts", isOpen: "isOpen", bsValue: "bsValue", bsConfig: "bsConfig" }, outputs: { onShown: "onShown", onHidden: "onHidden", bsValueChange: "bsValueChange" }, host: { properties: { "attr.readonly": "this.readonlyValue" } }, providers: [ComponentLoaderFactory, PositioningService], exportAs: ["bsDatepicker"], usesOnChanges: true, ngImport: i0 }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: BsDatepickerDirective, decorators: [{
            type: Directive,
            args: [{
                    selector: '[bsDatepicker]',
                    exportAs: 'bsDatepicker',
                    providers: [ComponentLoaderFactory, PositioningService],
                    standalone: true
                }]
        }], ctorParameters: () => [{ type: BsDatepickerConfig }, { type: i0.ElementRef }, { type: i0.Renderer2 }, { type: i0.ViewContainerRef }, { type: i2$1.ComponentLoaderFactory }], propDecorators: { placement: [{
                type: Input
            }], triggers: [{
                type: Input
            }], outsideClick: [{
                type: Input
            }], container: [{
                type: Input
            }], outsideEsc: [{
                type: Input
            }], onShown: [{
                type: Output
            }], onHidden: [{
                type: Output
            }], isDisabled: [{
                type: Input
            }], minDate: [{
                type: Input
            }], maxDate: [{
                type: Input
            }], ignoreMinMaxErrors: [{
                type: Input
            }], minMode: [{
                type: Input
            }], daysDisabled: [{
                type: Input
            }], datesDisabled: [{
                type: Input
            }], datesEnabled: [{
                type: Input
            }], dateCustomClasses: [{
                type: Input
            }], dateTooltipTexts: [{
                type: Input
            }], bsValueChange: [{
                type: Output
            }], readonlyValue: [{
                type: HostBinding,
                args: ['attr.readonly']
            }], isOpen: [{
                type: Input
            }], bsValue: [{
                type: Input
            }], bsConfig: [{
                type: Input
            }] } });

class BsDatepickerInlineConfig extends BsDatepickerConfig {
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: BsDatepickerInlineConfig, deps: null, target: i0.ɵɵFactoryTarget.Injectable }); }
    static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: BsDatepickerInlineConfig, providedIn: 'root' }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: BsDatepickerInlineConfig, decorators: [{
            type: Injectable,
            args: [{
                    providedIn: 'root'
                }]
        }] });

class BsDatepickerInlineContainerComponent extends BsDatepickerContainerComponent {
    get disabledValue() {
        return this.isDatePickerDisabled ? '' : null;
    }
    get readonlyValue() {
        return this.isDatePickerDisabled ? '' : null;
    }
    constructor(_renderer, _config, _store, _element, _actions, _effects, _positioningService) {
        super(_renderer, _config, _store, _element, _actions, _effects, _positioningService);
        _renderer.setStyle(_element.nativeElement, 'display', 'inline-block');
        _renderer.setStyle(_element.nativeElement, 'position', 'static');
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: BsDatepickerInlineContainerComponent, deps: [{ token: i0.Renderer2 }, { token: BsDatepickerConfig }, { token: BsDatepickerStore }, { token: i0.ElementRef }, { token: BsDatepickerActions }, { token: BsDatepickerEffects }, { token: i5.PositioningService }], target: i0.ɵɵFactoryTarget.Component }); }
    static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.2", type: BsDatepickerInlineContainerComponent, isStandalone: true, selector: "bs-datepicker-inline-container", host: { listeners: { "click": "_stopPropagation($event)" }, properties: { "attr.disabled": "this.disabledValue", "attr.readonly": "this.readonlyValue" } }, providers: [BsDatepickerStore, BsDatepickerEffects], usesInheritance: true, ngImport: i0, template: "<!-- days calendar view mode -->\n@if (viewMode | async) {\n  <div class=\"bs-datepicker\" [ngClass]=\"containerClass\">\n    <div class=\"bs-datepicker-container\">\n      <!--calendars-->\n      <div class=\"bs-calendar-container\" role=\"application\">\n        @switch (viewMode | async) {\n          <!--days calendar-->\n          @case ('day') {\n            <div class=\"bs-media-container\">\n              @for (calendar of daysCalendar$ | async; track calendar) {\n                <bs-days-calendar-view\n                  [class.bs-datepicker-multiple]=\"multipleCalendars\"\n                  [calendar]=\"calendar\"\n                  [isDisabled]=\"isDatePickerDisabled\"\n                  [options]=\"options$ | async\"\n                  (onNavigate)=\"navigateTo($event)\"\n                  (onViewMode)=\"setViewMode($event)\"\n                  (onHover)=\"dayHoverHandler($event)\"\n                  (onHoverWeek)=\"weekHoverHandler($event)\"\n                  (onSelect)=\"daySelectHandler($event)\">\n                </bs-days-calendar-view>\n              }\n            </div>\n            @if (withTimepicker) {\n              <div class=\"bs-timepicker-in-datepicker-container\">\n                <timepicker #startTP [disabled]=\"isDatePickerDisabled\"></timepicker>\n                @if (isRangePicker) {\n                  <timepicker #endTP [disabled]=\"isDatePickerDisabled\"></timepicker>\n                }\n              </div>\n            }\n          }\n          <!--months calendar-->\n          @case ('month') {\n            <div class=\"bs-media-container\">\n              @for (calendar of monthsCalendar | async; track calendar) {\n                <bs-month-calendar-view\n                  [class.bs-datepicker-multiple]=\"multipleCalendars\"\n                  [calendar]=\"calendar\"\n                  (onNavigate)=\"navigateTo($event)\"\n                  (onViewMode)=\"setViewMode($event)\"\n                  (onHover)=\"monthHoverHandler($event)\"\n                  (onSelect)=\"monthSelectHandler($event)\">\n                </bs-month-calendar-view>\n              }\n            </div>\n          }\n          <!--years calendar-->\n          @case ('year') {\n            <div class=\"bs-media-container\">\n              @for (calendar of yearsCalendar | async; track calendar) {\n                <bs-years-calendar-view\n                  [class.bs-datepicker-multiple]=\"multipleCalendars\"\n                  [calendar]=\"calendar\"\n                  (onNavigate)=\"navigateTo($event)\"\n                  (onViewMode)=\"setViewMode($event)\"\n                  (onHover)=\"yearHoverHandler($event)\"\n                  (onSelect)=\"yearSelectHandler($event)\">\n                </bs-years-calendar-view>\n              }\n            </div>\n          }\n        }\n      </div>\n      <!--applycancel buttons-->\n      @if (false) {\n        <div class=\"bs-datepicker-buttons\">\n          <button class=\"btn btn-success\" type=\"button\">Apply</button>\n          <button class=\"btn btn-default\" type=\"button\">Cancel</button>\n        </div>\n      }\n      @if (showTodayBtn || showClearBtn) {\n        <div class=\"bs-datepicker-buttons\">\n          @if (showTodayBtn) {\n            <div class=\"btn-today-wrapper\"\n              [class.today-left]=\"todayPos === 'left'\"\n              [class.today-right]=\"todayPos === 'right'\"\n              [class.today-center]=\"todayPos === 'center'\"\n              >\n              <button class=\"btn btn-success\" (click)=\"setToday()\">{{todayBtnLbl}}</button>\n            </div>\n          }\n          @if (showClearBtn) {\n            <div class=\"btn-clear-wrapper\"\n              [class.clear-left]=\"clearPos === 'left'\"\n              [class.clear-right]=\"clearPos === 'right'\"\n              [class.clear-center]=\"clearPos === 'center'\"\n              >\n              <button class=\"btn btn-success\" (click)=\"clearDate()\">{{clearBtnLbl}}</button>\n            </div>\n          }\n        </div>\n      }\n    </div>\n    <!--custom dates or date ranges picker-->\n    @if (customRanges && customRanges.length > 0) {\n      <div class=\"bs-datepicker-custom-range\">\n        <bs-custom-date-view\n          [selectedRange]=\"chosenRange\"\n          [ranges]=\"customRanges\"\n          [customRangeLabel]=\"customRangeBtnLbl\"\n          (onSelect)=\"setRangeOnCalendar($event)\">\n        </bs-custom-date-view>\n      </div>\n    }\n  </div>\n}\n", dependencies: [{ kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "component", type: BsDaysCalendarViewComponent, selector: "bs-days-calendar-view", inputs: ["calendar", "options", "isDisabled"], outputs: ["onNavigate", "onViewMode", "onSelect", "onHover", "onHoverWeek"] }, { kind: "ngmodule", type: TimepickerModule }, { kind: "component", type: i6.TimepickerComponent, selector: "timepicker", inputs: ["hourStep", "minuteStep", "secondsStep", "readonlyInput", "disabled", "mousewheel", "arrowkeys", "showSpinners", "showMeridian", "showMinutes", "showSeconds", "meridians", "min", "max", "hoursPlaceholder", "minutesPlaceholder", "secondsPlaceholder"], outputs: ["isValid", "meridianChange"] }, { kind: "component", type: BsMonthCalendarViewComponent, selector: "bs-month-calendar-view", inputs: ["calendar"], outputs: ["onNavigate", "onViewMode", "onSelect", "onHover"] }, { kind: "component", type: BsYearsCalendarViewComponent, selector: "bs-years-calendar-view", inputs: ["calendar"], outputs: ["onNavigate", "onViewMode", "onSelect", "onHover"] }, { kind: "component", type: BsCustomDatesViewComponent, selector: "bs-custom-date-view", inputs: ["ranges", "selectedRange", "customRangeLabel"], outputs: ["onSelect"] }, { kind: "pipe", type: AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.Eager }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: BsDatepickerInlineContainerComponent, decorators: [{
            type: Component,
            args: [{ selector: 'bs-datepicker-inline-container', changeDetection: ChangeDetectionStrategy.Eager, providers: [BsDatepickerStore, BsDatepickerEffects], host: {
                        '(click)': '_stopPropagation($event)'
                    }, standalone: true, imports: [NgClass, BsDaysCalendarViewComponent, TimepickerModule, BsMonthCalendarViewComponent, BsYearsCalendarViewComponent, BsCustomDatesViewComponent, AsyncPipe], template: "<!-- days calendar view mode -->\n@if (viewMode | async) {\n  <div class=\"bs-datepicker\" [ngClass]=\"containerClass\">\n    <div class=\"bs-datepicker-container\">\n      <!--calendars-->\n      <div class=\"bs-calendar-container\" role=\"application\">\n        @switch (viewMode | async) {\n          <!--days calendar-->\n          @case ('day') {\n            <div class=\"bs-media-container\">\n              @for (calendar of daysCalendar$ | async; track calendar) {\n                <bs-days-calendar-view\n                  [class.bs-datepicker-multiple]=\"multipleCalendars\"\n                  [calendar]=\"calendar\"\n                  [isDisabled]=\"isDatePickerDisabled\"\n                  [options]=\"options$ | async\"\n                  (onNavigate)=\"navigateTo($event)\"\n                  (onViewMode)=\"setViewMode($event)\"\n                  (onHover)=\"dayHoverHandler($event)\"\n                  (onHoverWeek)=\"weekHoverHandler($event)\"\n                  (onSelect)=\"daySelectHandler($event)\">\n                </bs-days-calendar-view>\n              }\n            </div>\n            @if (withTimepicker) {\n              <div class=\"bs-timepicker-in-datepicker-container\">\n                <timepicker #startTP [disabled]=\"isDatePickerDisabled\"></timepicker>\n                @if (isRangePicker) {\n                  <timepicker #endTP [disabled]=\"isDatePickerDisabled\"></timepicker>\n                }\n              </div>\n            }\n          }\n          <!--months calendar-->\n          @case ('month') {\n            <div class=\"bs-media-container\">\n              @for (calendar of monthsCalendar | async; track calendar) {\n                <bs-month-calendar-view\n                  [class.bs-datepicker-multiple]=\"multipleCalendars\"\n                  [calendar]=\"calendar\"\n                  (onNavigate)=\"navigateTo($event)\"\n                  (onViewMode)=\"setViewMode($event)\"\n                  (onHover)=\"monthHoverHandler($event)\"\n                  (onSelect)=\"monthSelectHandler($event)\">\n                </bs-month-calendar-view>\n              }\n            </div>\n          }\n          <!--years calendar-->\n          @case ('year') {\n            <div class=\"bs-media-container\">\n              @for (calendar of yearsCalendar | async; track calendar) {\n                <bs-years-calendar-view\n                  [class.bs-datepicker-multiple]=\"multipleCalendars\"\n                  [calendar]=\"calendar\"\n                  (onNavigate)=\"navigateTo($event)\"\n                  (onViewMode)=\"setViewMode($event)\"\n                  (onHover)=\"yearHoverHandler($event)\"\n                  (onSelect)=\"yearSelectHandler($event)\">\n                </bs-years-calendar-view>\n              }\n            </div>\n          }\n        }\n      </div>\n      <!--applycancel buttons-->\n      @if (false) {\n        <div class=\"bs-datepicker-buttons\">\n          <button class=\"btn btn-success\" type=\"button\">Apply</button>\n          <button class=\"btn btn-default\" type=\"button\">Cancel</button>\n        </div>\n      }\n      @if (showTodayBtn || showClearBtn) {\n        <div class=\"bs-datepicker-buttons\">\n          @if (showTodayBtn) {\n            <div class=\"btn-today-wrapper\"\n              [class.today-left]=\"todayPos === 'left'\"\n              [class.today-right]=\"todayPos === 'right'\"\n              [class.today-center]=\"todayPos === 'center'\"\n              >\n              <button class=\"btn btn-success\" (click)=\"setToday()\">{{todayBtnLbl}}</button>\n            </div>\n          }\n          @if (showClearBtn) {\n            <div class=\"btn-clear-wrapper\"\n              [class.clear-left]=\"clearPos === 'left'\"\n              [class.clear-right]=\"clearPos === 'right'\"\n              [class.clear-center]=\"clearPos === 'center'\"\n              >\n              <button class=\"btn btn-success\" (click)=\"clearDate()\">{{clearBtnLbl}}</button>\n            </div>\n          }\n        </div>\n      }\n    </div>\n    <!--custom dates or date ranges picker-->\n    @if (customRanges && customRanges.length > 0) {\n      <div class=\"bs-datepicker-custom-range\">\n        <bs-custom-date-view\n          [selectedRange]=\"chosenRange\"\n          [ranges]=\"customRanges\"\n          [customRangeLabel]=\"customRangeBtnLbl\"\n          (onSelect)=\"setRangeOnCalendar($event)\">\n        </bs-custom-date-view>\n      </div>\n    }\n  </div>\n}\n" }]
        }], ctorParameters: () => [{ type: i0.Renderer2 }, { type: BsDatepickerConfig }, { type: BsDatepickerStore }, { type: i0.ElementRef }, { type: BsDatepickerActions }, { type: BsDatepickerEffects }, { type: i5.PositioningService }], propDecorators: { disabledValue: [{
                type: HostBinding,
                args: ['attr.disabled']
            }], readonlyValue: [{
                type: HostBinding,
                args: ['attr.readonly']
            }] } });

class BsDatepickerInlineDirective {
    constructor(_config, _elementRef, _renderer, _viewContainerRef, cis) {
        this._config = _config;
        this._elementRef = _elementRef;
        /**
         * Indicates whether datepicker is enabled or not
         */
        this.isDisabled = false;
        /**
         * Emits when datepicker value has been changed
         */
        this.bsValueChange = new EventEmitter();
        this._subs = [];
        // todo: assign only subset of fields
        Object.assign(this, this._config);
        this._datepicker = cis.createLoader(_elementRef, _viewContainerRef, _renderer);
    }
    /**
     * Initial value of datepicker
     */
    set bsValue(value) {
        if (this._bsValue === value) {
            return;
        }
        if (!this._bsValue && value && !this._config.withTimepicker) {
            const now = new Date();
            copyTime(value, now);
        }
        if (value && this.bsConfig?.initCurrentTime) {
            value = setCurrentTimeOnDateSelect(value);
        }
        this._bsValue = value;
        this.bsValueChange.emit(value);
    }
    ngOnInit() {
        this.setConfig();
        this.initSubscribes();
    }
    initSubscribes() {
        this.unsubscribeSubscriptions();
        this._subs.push(this.bsValueChange.subscribe((value) => {
            if (this._datepickerRef) {
                this._datepickerRef.instance.value = value;
            }
        }));
        if (this._datepickerRef) {
            this._subs.push(this._datepickerRef.instance.valueChange.subscribe((value) => {
                this.bsValue = value;
            }));
        }
    }
    unsubscribeSubscriptions() {
        if (this._subs?.length) {
            this._subs.map(sub => sub.unsubscribe());
            this._subs.length = 0;
        }
    }
    ngOnChanges(changes) {
        if (changes["bsConfig"]) {
            if (changes["bsConfig"].currentValue?.initCurrentTime && changes["bsConfig"].currentValue?.initCurrentTime !== changes["bsConfig"].previousValue?.initCurrentTime && this._bsValue) {
                this._bsValue = setCurrentTimeOnDateSelect(this._bsValue);
                this.bsValueChange.emit(this._bsValue);
            }
        }
        if (!this._datepickerRef || !this._datepickerRef.instance) {
            return;
        }
        if (changes["minDate"]) {
            this._datepickerRef.instance.minDate = this.minDate;
        }
        if (changes["maxDate"]) {
            this._datepickerRef.instance.maxDate = this.maxDate;
        }
        if (changes["datesDisabled"]) {
            this._datepickerRef.instance.datesDisabled = this.datesDisabled;
        }
        if (changes["datesEnabled"]) {
            this._datepickerRef.instance.datesEnabled = this.datesEnabled;
            this._datepickerRef.instance.value = this._bsValue;
        }
        if (changes["isDisabled"]) {
            this._datepickerRef.instance.isDisabled = this.isDisabled;
        }
        if (changes["dateCustomClasses"]) {
            this._datepickerRef.instance.dateCustomClasses = this.dateCustomClasses;
        }
        if (changes["dateTooltipTexts"]) {
            this._datepickerRef.instance.dateTooltipTexts = this.dateTooltipTexts;
        }
        this.setConfig();
    }
    /**
     * Set config for datepicker
     */
    setConfig() {
        if (this._datepicker) {
            this._datepicker.hide();
        }
        this._config = Object.assign({}, this._config, this.bsConfig, {
            value: checkBsValue(this._bsValue, this.maxDate || this.bsConfig && this.bsConfig.maxDate),
            isDisabled: this.isDisabled,
            minDate: this.minDate || this.bsConfig && this.bsConfig.minDate,
            maxDate: this.maxDate || this.bsConfig && this.bsConfig.maxDate,
            dateCustomClasses: this.dateCustomClasses || this.bsConfig && this.bsConfig.dateCustomClasses,
            dateTooltipTexts: this.dateTooltipTexts || this.bsConfig && this.bsConfig.dateTooltipTexts,
            datesDisabled: this.datesDisabled || this.bsConfig && this.bsConfig.datesDisabled,
            datesEnabled: this.datesEnabled || this.bsConfig && this.bsConfig.datesEnabled,
            initCurrentTime: this.bsConfig?.initCurrentTime
        });
        this._datepickerRef = this._datepicker
            .provide({ provide: BsDatepickerConfig, useValue: this._config })
            .attach(BsDatepickerInlineContainerComponent)
            .to(this._elementRef)
            .show();
        this.initSubscribes();
    }
    ngOnDestroy() {
        this._datepicker.dispose();
        this.unsubscribeSubscriptions();
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: BsDatepickerInlineDirective, deps: [{ token: BsDatepickerInlineConfig }, { token: i0.ElementRef }, { token: i0.Renderer2 }, { token: i0.ViewContainerRef }, { token: i2$1.ComponentLoaderFactory }], target: i0.ɵɵFactoryTarget.Directive }); }
    static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "22.0.2", type: BsDatepickerInlineDirective, isStandalone: true, selector: "bs-datepicker-inline", inputs: { bsConfig: "bsConfig", isDisabled: "isDisabled", minDate: "minDate", maxDate: "maxDate", dateCustomClasses: "dateCustomClasses", dateTooltipTexts: "dateTooltipTexts", datesEnabled: "datesEnabled", datesDisabled: "datesDisabled", bsValue: "bsValue" }, outputs: { bsValueChange: "bsValueChange" }, providers: [ComponentLoaderFactory, PositioningService], exportAs: ["bsDatepickerInline"], usesOnChanges: true, ngImport: i0 }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: BsDatepickerInlineDirective, decorators: [{
            type: Directive,
            args: [{
                    selector: 'bs-datepicker-inline',
                    exportAs: 'bsDatepickerInline',
                    standalone: true,
                    providers: [ComponentLoaderFactory, PositioningService]
                }]
        }], ctorParameters: () => [{ type: BsDatepickerInlineConfig }, { type: i0.ElementRef }, { type: i0.Renderer2 }, { type: i0.ViewContainerRef }, { type: i2$1.ComponentLoaderFactory }], propDecorators: { bsConfig: [{
                type: Input
            }], isDisabled: [{
                type: Input
            }], minDate: [{
                type: Input
            }], maxDate: [{
                type: Input
            }], dateCustomClasses: [{
                type: Input
            }], dateTooltipTexts: [{
                type: Input
            }], datesEnabled: [{
                type: Input
            }], datesDisabled: [{
                type: Input
            }], bsValueChange: [{
                type: Output
            }], bsValue: [{
                type: Input
            }] } });

class BsDaterangepickerInlineConfig extends BsDatepickerConfig {
    constructor() {
        super(...arguments);
        // DatepickerRenderOptions
        this.displayMonths = 2;
        /** turn on/off animation */
        this.isAnimated = false;
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: BsDaterangepickerInlineConfig, deps: null, target: i0.ɵɵFactoryTarget.Injectable }); }
    static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: BsDaterangepickerInlineConfig, providedIn: 'root' }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: BsDaterangepickerInlineConfig, decorators: [{
            type: Injectable,
            args: [{
                    providedIn: 'root'
                }]
        }] });

class BsDaterangepickerContainerComponent extends BsDatepickerAbstractComponent {
    set value(value) {
        this._effects?.setRangeValue(value);
    }
    get isDatePickerDisabled() {
        return !!this._config.isDisabled;
    }
    get isDatepickerDisabled() {
        return this.isDatePickerDisabled ? '' : null;
    }
    get isDatepickerReadonly() {
        return this.isDatePickerDisabled ? '' : null;
    }
    constructor(_renderer, _config, _store, _element, _actions, _effects, _positionService) {
        super();
        this._renderer = _renderer;
        this._config = _config;
        this._store = _store;
        this._element = _element;
        this._actions = _actions;
        this._positionService = _positionService;
        this.valueChange = new EventEmitter();
        this._rangeStack = [];
        this.chosenRange = [];
        this._subs = [];
        this.isRangePicker = true;
        this._effects = _effects;
        this.customRanges = this._config.ranges || [];
        this.customRangeBtnLbl = this._config.customRangeButtonLabel;
        _renderer.setStyle(_element.nativeElement, 'display', 'block');
        _renderer.setStyle(_element.nativeElement, 'position', 'absolute');
    }
    ngOnInit() {
        this._positionService.setOptions({
            modifiers: {
                flip: {
                    enabled: this._config.adaptivePosition
                },
                preventOverflow: {
                    enabled: this._config.adaptivePosition
                }
            },
            allowedPositions: this._config.allowedPositions
        });
        this._positionService.event$?.pipe(take(1)).subscribe(() => {
            this._positionService.disable();
            if (this._config.isAnimated) {
                const containerEl = this._element.nativeElement.querySelector('.bs-datepicker-container');
                if (containerEl) {
                    this._animateExpand(containerEl, () => this.positionServiceEnable());
                }
                else {
                    this.positionServiceEnable();
                }
                return;
            }
            this.positionServiceEnable();
        });
        this.containerClass = this._config.containerClass;
        this.isOtherMonthsActive = this._config.selectFromOtherMonth;
        this.withTimepicker = this._config.withTimepicker;
        this._effects
            ?.init(this._store)
            // intial state options
            // todo: fix this, split configs
            .setOptions(this._config)
            // data binding view --> model
            .setBindings(this)
            // set event handlers
            .setEventHandlers(this)
            .registerDatepickerSideEffects();
        let currentDate;
        // todo: move it somewhere else
        // on selected date change
        this._subs.push(this._store
            .select((state) => state.selectedRange)
            .subscribe((dateRange) => {
            currentDate = dateRange;
            this.valueChange.emit(dateRange);
            this.chosenRange = dateRange || [];
        }));
        this._subs.push(this._store
            .select((state) => state.selectedTime)
            .subscribe((time) => {
            if (!time ||
                !time[0] ||
                !time[1] ||
                !(time[0] instanceof Date) ||
                !(time[1] instanceof Date) ||
                (currentDate && time[0] === currentDate[0] && time[1] === currentDate[1])) {
                return;
            }
            this.valueChange.emit(time);
            this.chosenRange = time || [];
        }));
    }
    ngAfterViewInit() {
        this.selectedTimeSub.add(this.selectedTime?.subscribe((val) => {
            if (Array.isArray(val) && val.length >= 2) {
                this.startTimepicker?.writeValue(val[0]);
                this.endTimepicker?.writeValue(val[1]);
            }
        }));
        this.startTimepicker?.registerOnChange((val) => {
            this.timeSelectHandler(val, 0);
        });
        this.endTimepicker?.registerOnChange((val) => {
            this.timeSelectHandler(val, 1);
        });
    }
    get isTopPosition() {
        return this._element.nativeElement.classList.contains('top');
    }
    positionServiceEnable() {
        this._positionService.enable();
    }
    timeSelectHandler(date, index) {
        this._store.dispatch(this._actions.selectTime(date, index));
    }
    daySelectHandler(day) {
        if (!day) {
            return;
        }
        const isDisabled = this.isOtherMonthsActive ? day.isDisabled : day.isOtherMonth || day.isDisabled;
        if (isDisabled) {
            return;
        }
        this.rangesProcessing(day);
    }
    monthSelectHandler(day) {
        if (!day || day.isDisabled) {
            return;
        }
        day.isSelected = true;
        if (this._config.minMode !== 'month') {
            if (day.isDisabled) {
                return;
            }
            this._store.dispatch(this._actions.navigateTo({
                unit: {
                    month: getMonth(day.date),
                    year: getFullYear(day.date)
                },
                viewMode: 'day'
            }));
            return;
        }
        this.rangesProcessing(day);
    }
    yearSelectHandler(day) {
        if (!day || day.isDisabled) {
            return;
        }
        day.isSelected = true;
        if (this._config.minMode !== 'year') {
            if (day.isDisabled) {
                return;
            }
            this._store.dispatch(this._actions.navigateTo({
                unit: {
                    year: getFullYear(day.date)
                },
                viewMode: 'month'
            }));
            return;
        }
        this.rangesProcessing(day);
    }
    rangesProcessing(day) {
        // if only one date is already selected
        // and user clicks on previous date
        // start selection from new date
        // but if new date is after initial one
        // than finish selection
        if (this._rangeStack.length === 1) {
            this._rangeStack = day.date >= this._rangeStack[0] ? [this._rangeStack[0], day.date] : [day.date];
        }
        if (this._config.maxDateRange) {
            this.setMaxDateRangeOnCalendar(day.date);
        }
        if (this._rangeStack.length === 0) {
            this._rangeStack = [day.date];
            if (this._config.maxDateRange) {
                this.setMaxDateRangeOnCalendar(day.date);
            }
        }
        this._store.dispatch(this._actions.selectRange(this._rangeStack));
        if (this._rangeStack.length === 2) {
            this._rangeStack = [];
        }
    }
    _animateExpand(el, onDone) {
        this._cancelExpandAnimation?.();
        this._cancelExpandAnimation = animateExpand(this._renderer, el, {
            timing: DATEPICKER_ANIMATION_TIMING,
            durationMs: DATEPICKER_ANIMATION_DURATION_MS,
            useRaf: true,
            manageDisplay: true,
            onDone
        });
    }
    ngOnDestroy() {
        this._cancelExpandAnimation?.();
        for (const sub of this._subs) {
            sub.unsubscribe();
        }
        this.selectedTimeSub.unsubscribe();
        this._effects?.destroy();
    }
    setRangeOnCalendar(dates) {
        if (dates) {
            this._rangeStack = dates.value instanceof Date ? [dates.value] : dates.value;
        }
        this._store.dispatch(this._actions.selectRange(this._rangeStack));
    }
    setMaxDateRangeOnCalendar(currentSelection) {
        let maxDateRange = new Date(currentSelection);
        if (this._config.maxDate) {
            const maxDateValueInMilliseconds = this._config.maxDate.getTime();
            const maxDateRangeInMilliseconds = currentSelection.getTime() + (this._config.maxDateRange || 0) * dayInMilliseconds;
            maxDateRange =
                maxDateRangeInMilliseconds > maxDateValueInMilliseconds
                    ? new Date(this._config.maxDate)
                    : new Date(maxDateRangeInMilliseconds);
        }
        else {
            maxDateRange.setDate(currentSelection.getDate() + (this._config.maxDateRange || 0));
        }
        this._effects?.setMaxDate(maxDateRange);
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: BsDaterangepickerContainerComponent, deps: [{ token: i0.Renderer2 }, { token: BsDatepickerConfig }, { token: BsDatepickerStore }, { token: i0.ElementRef }, { token: BsDatepickerActions }, { token: BsDatepickerEffects }, { token: i5.PositioningService }], target: i0.ɵɵFactoryTarget.Component }); }
    static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.2", type: BsDaterangepickerContainerComponent, isStandalone: true, selector: "bs-daterangepicker-container", host: { attributes: { "role": "dialog", "aria-label": "calendar" }, listeners: { "click": "_stopPropagation($event)" }, properties: { "attr.disabled": "this.isDatepickerDisabled", "attr.readonly": "this.isDatepickerReadonly" }, classAttribute: "bottom" }, providers: [BsDatepickerStore, BsDatepickerEffects, BsDatepickerActions], viewQueries: [{ propertyName: "startTimepicker", first: true, predicate: ["startTP"], descendants: true }, { propertyName: "endTimepicker", first: true, predicate: ["endTP"], descendants: true }], usesInheritance: true, ngImport: i0, template: "<!-- days calendar view mode -->\n@if (viewMode | async) {\n  <div class=\"bs-datepicker\" [ngClass]=\"containerClass\">\n    <div class=\"bs-datepicker-container\">\n      <!--calendars-->\n      <div class=\"bs-calendar-container\" role=\"application\">\n        @switch (viewMode | async) {\n          <!--days calendar-->\n          @case ('day') {\n            <div class=\"bs-media-container\">\n              @for (calendar of daysCalendar$ | async; track calendar) {\n                <bs-days-calendar-view\n                  [class.bs-datepicker-multiple]=\"multipleCalendars\"\n                  [calendar]=\"calendar\"\n                  [isDisabled]=\"isDatePickerDisabled\"\n                  [options]=\"options$ | async\"\n                  (onNavigate)=\"navigateTo($event)\"\n                  (onViewMode)=\"setViewMode($event)\"\n                  (onHover)=\"dayHoverHandler($event)\"\n                  (onHoverWeek)=\"weekHoverHandler($event)\"\n                  (onSelect)=\"daySelectHandler($event)\">\n                </bs-days-calendar-view>\n              }\n            </div>\n            @if (withTimepicker) {\n              <div class=\"bs-timepicker-in-datepicker-container\">\n                <timepicker #startTP [disabled]=\"isDatePickerDisabled\"></timepicker>\n                @if (isRangePicker) {\n                  <timepicker #endTP [disabled]=\"isDatePickerDisabled\"></timepicker>\n                }\n              </div>\n            }\n          }\n          <!--months calendar-->\n          @case ('month') {\n            <div class=\"bs-media-container\">\n              @for (calendar of monthsCalendar | async; track calendar) {\n                <bs-month-calendar-view\n                  [class.bs-datepicker-multiple]=\"multipleCalendars\"\n                  [calendar]=\"calendar\"\n                  (onNavigate)=\"navigateTo($event)\"\n                  (onViewMode)=\"setViewMode($event)\"\n                  (onHover)=\"monthHoverHandler($event)\"\n                  (onSelect)=\"monthSelectHandler($event)\">\n                </bs-month-calendar-view>\n              }\n            </div>\n          }\n          <!--years calendar-->\n          @case ('year') {\n            <div class=\"bs-media-container\">\n              @for (calendar of yearsCalendar | async; track calendar) {\n                <bs-years-calendar-view\n                  [class.bs-datepicker-multiple]=\"multipleCalendars\"\n                  [calendar]=\"calendar\"\n                  (onNavigate)=\"navigateTo($event)\"\n                  (onViewMode)=\"setViewMode($event)\"\n                  (onHover)=\"yearHoverHandler($event)\"\n                  (onSelect)=\"yearSelectHandler($event)\">\n                </bs-years-calendar-view>\n              }\n            </div>\n          }\n        }\n      </div>\n      <!--applycancel buttons-->\n      @if (false) {\n        <div class=\"bs-datepicker-buttons\">\n          <button class=\"btn btn-success\" type=\"button\">Apply</button>\n          <button class=\"btn btn-default\" type=\"button\">Cancel</button>\n        </div>\n      }\n      @if (showTodayBtn || showClearBtn) {\n        <div class=\"bs-datepicker-buttons\">\n          @if (showTodayBtn) {\n            <div class=\"btn-today-wrapper\"\n              [class.today-left]=\"todayPos === 'left'\"\n              [class.today-right]=\"todayPos === 'right'\"\n              [class.today-center]=\"todayPos === 'center'\"\n              >\n              <button class=\"btn btn-success\" (click)=\"setToday()\">{{todayBtnLbl}}</button>\n            </div>\n          }\n          @if (showClearBtn) {\n            <div class=\"btn-clear-wrapper\"\n              [class.clear-left]=\"clearPos === 'left'\"\n              [class.clear-right]=\"clearPos === 'right'\"\n              [class.clear-center]=\"clearPos === 'center'\"\n              >\n              <button class=\"btn btn-success\" (click)=\"clearDate()\">{{clearBtnLbl}}</button>\n            </div>\n          }\n        </div>\n      }\n    </div>\n    <!--custom dates or date ranges picker-->\n    @if (customRanges && customRanges.length > 0) {\n      <div class=\"bs-datepicker-custom-range\">\n        <bs-custom-date-view\n          [selectedRange]=\"chosenRange\"\n          [ranges]=\"customRanges\"\n          [customRangeLabel]=\"customRangeBtnLbl\"\n          (onSelect)=\"setRangeOnCalendar($event)\">\n        </bs-custom-date-view>\n      </div>\n    }\n  </div>\n}\n", dependencies: [{ kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "component", type: BsDaysCalendarViewComponent, selector: "bs-days-calendar-view", inputs: ["calendar", "options", "isDisabled"], outputs: ["onNavigate", "onViewMode", "onSelect", "onHover", "onHoverWeek"] }, { kind: "ngmodule", type: TimepickerModule }, { kind: "component", type: i6.TimepickerComponent, selector: "timepicker", inputs: ["hourStep", "minuteStep", "secondsStep", "readonlyInput", "disabled", "mousewheel", "arrowkeys", "showSpinners", "showMeridian", "showMinutes", "showSeconds", "meridians", "min", "max", "hoursPlaceholder", "minutesPlaceholder", "secondsPlaceholder"], outputs: ["isValid", "meridianChange"] }, { kind: "component", type: BsMonthCalendarViewComponent, selector: "bs-month-calendar-view", inputs: ["calendar"], outputs: ["onNavigate", "onViewMode", "onSelect", "onHover"] }, { kind: "component", type: BsYearsCalendarViewComponent, selector: "bs-years-calendar-view", inputs: ["calendar"], outputs: ["onNavigate", "onViewMode", "onSelect", "onHover"] }, { kind: "component", type: BsCustomDatesViewComponent, selector: "bs-custom-date-view", inputs: ["ranges", "selectedRange", "customRangeLabel"], outputs: ["onSelect"] }, { kind: "pipe", type: AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.Eager }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: BsDaterangepickerContainerComponent, decorators: [{
            type: Component,
            args: [{ selector: 'bs-daterangepicker-container', changeDetection: ChangeDetectionStrategy.Eager, providers: [BsDatepickerStore, BsDatepickerEffects, BsDatepickerActions], host: {
                        class: 'bottom',
                        '(click)': '_stopPropagation($event)',
                        role: 'dialog',
                        'aria-label': 'calendar'
                    }, standalone: true, imports: [
                        NgClass,
                        BsDaysCalendarViewComponent,
                        TimepickerModule,
                        BsMonthCalendarViewComponent,
                        BsYearsCalendarViewComponent,
                        BsCustomDatesViewComponent,
                        AsyncPipe
                    ], template: "<!-- days calendar view mode -->\n@if (viewMode | async) {\n  <div class=\"bs-datepicker\" [ngClass]=\"containerClass\">\n    <div class=\"bs-datepicker-container\">\n      <!--calendars-->\n      <div class=\"bs-calendar-container\" role=\"application\">\n        @switch (viewMode | async) {\n          <!--days calendar-->\n          @case ('day') {\n            <div class=\"bs-media-container\">\n              @for (calendar of daysCalendar$ | async; track calendar) {\n                <bs-days-calendar-view\n                  [class.bs-datepicker-multiple]=\"multipleCalendars\"\n                  [calendar]=\"calendar\"\n                  [isDisabled]=\"isDatePickerDisabled\"\n                  [options]=\"options$ | async\"\n                  (onNavigate)=\"navigateTo($event)\"\n                  (onViewMode)=\"setViewMode($event)\"\n                  (onHover)=\"dayHoverHandler($event)\"\n                  (onHoverWeek)=\"weekHoverHandler($event)\"\n                  (onSelect)=\"daySelectHandler($event)\">\n                </bs-days-calendar-view>\n              }\n            </div>\n            @if (withTimepicker) {\n              <div class=\"bs-timepicker-in-datepicker-container\">\n                <timepicker #startTP [disabled]=\"isDatePickerDisabled\"></timepicker>\n                @if (isRangePicker) {\n                  <timepicker #endTP [disabled]=\"isDatePickerDisabled\"></timepicker>\n                }\n              </div>\n            }\n          }\n          <!--months calendar-->\n          @case ('month') {\n            <div class=\"bs-media-container\">\n              @for (calendar of monthsCalendar | async; track calendar) {\n                <bs-month-calendar-view\n                  [class.bs-datepicker-multiple]=\"multipleCalendars\"\n                  [calendar]=\"calendar\"\n                  (onNavigate)=\"navigateTo($event)\"\n                  (onViewMode)=\"setViewMode($event)\"\n                  (onHover)=\"monthHoverHandler($event)\"\n                  (onSelect)=\"monthSelectHandler($event)\">\n                </bs-month-calendar-view>\n              }\n            </div>\n          }\n          <!--years calendar-->\n          @case ('year') {\n            <div class=\"bs-media-container\">\n              @for (calendar of yearsCalendar | async; track calendar) {\n                <bs-years-calendar-view\n                  [class.bs-datepicker-multiple]=\"multipleCalendars\"\n                  [calendar]=\"calendar\"\n                  (onNavigate)=\"navigateTo($event)\"\n                  (onViewMode)=\"setViewMode($event)\"\n                  (onHover)=\"yearHoverHandler($event)\"\n                  (onSelect)=\"yearSelectHandler($event)\">\n                </bs-years-calendar-view>\n              }\n            </div>\n          }\n        }\n      </div>\n      <!--applycancel buttons-->\n      @if (false) {\n        <div class=\"bs-datepicker-buttons\">\n          <button class=\"btn btn-success\" type=\"button\">Apply</button>\n          <button class=\"btn btn-default\" type=\"button\">Cancel</button>\n        </div>\n      }\n      @if (showTodayBtn || showClearBtn) {\n        <div class=\"bs-datepicker-buttons\">\n          @if (showTodayBtn) {\n            <div class=\"btn-today-wrapper\"\n              [class.today-left]=\"todayPos === 'left'\"\n              [class.today-right]=\"todayPos === 'right'\"\n              [class.today-center]=\"todayPos === 'center'\"\n              >\n              <button class=\"btn btn-success\" (click)=\"setToday()\">{{todayBtnLbl}}</button>\n            </div>\n          }\n          @if (showClearBtn) {\n            <div class=\"btn-clear-wrapper\"\n              [class.clear-left]=\"clearPos === 'left'\"\n              [class.clear-right]=\"clearPos === 'right'\"\n              [class.clear-center]=\"clearPos === 'center'\"\n              >\n              <button class=\"btn btn-success\" (click)=\"clearDate()\">{{clearBtnLbl}}</button>\n            </div>\n          }\n        </div>\n      }\n    </div>\n    <!--custom dates or date ranges picker-->\n    @if (customRanges && customRanges.length > 0) {\n      <div class=\"bs-datepicker-custom-range\">\n        <bs-custom-date-view\n          [selectedRange]=\"chosenRange\"\n          [ranges]=\"customRanges\"\n          [customRangeLabel]=\"customRangeBtnLbl\"\n          (onSelect)=\"setRangeOnCalendar($event)\">\n        </bs-custom-date-view>\n      </div>\n    }\n  </div>\n}\n" }]
        }], ctorParameters: () => [{ type: i0.Renderer2 }, { type: BsDatepickerConfig }, { type: BsDatepickerStore }, { type: i0.ElementRef }, { type: BsDatepickerActions }, { type: BsDatepickerEffects }, { type: i5.PositioningService }], propDecorators: { startTimepicker: [{
                type: ViewChild,
                args: ['startTP']
            }], endTimepicker: [{
                type: ViewChild,
                args: ['endTP']
            }], isDatepickerDisabled: [{
                type: HostBinding,
                args: ['attr.disabled']
            }], isDatepickerReadonly: [{
                type: HostBinding,
                args: ['attr.readonly']
            }] } });

class BsDaterangepickerInlineContainerComponent extends BsDaterangepickerContainerComponent {
    get disabledValue() {
        return this.isDatePickerDisabled ? '' : null;
    }
    get readonlyValue() {
        return this.isDatePickerDisabled ? '' : null;
    }
    constructor(_renderer, _config, _store, _element, _actions, _effects, _positioningService) {
        super(_renderer, _config, _store, _element, _actions, _effects, _positioningService);
        _renderer.setStyle(_element.nativeElement, 'display', 'inline-block');
        _renderer.setStyle(_element.nativeElement, 'position', 'static');
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: BsDaterangepickerInlineContainerComponent, deps: [{ token: i0.Renderer2 }, { token: BsDatepickerConfig }, { token: BsDatepickerStore }, { token: i0.ElementRef }, { token: BsDatepickerActions }, { token: BsDatepickerEffects }, { token: i5.PositioningService }], target: i0.ɵɵFactoryTarget.Component }); }
    static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.2", type: BsDaterangepickerInlineContainerComponent, isStandalone: true, selector: "bs-daterangepicker-inline-container", host: { listeners: { "click": "_stopPropagation($event)" }, properties: { "attr.disabled": "this.disabledValue", "attr.readonly": "this.readonlyValue" } }, providers: [BsDatepickerStore, BsDatepickerEffects, BsDatepickerActions], usesInheritance: true, ngImport: i0, template: "<!-- days calendar view mode -->\n@if (viewMode | async) {\n  <div class=\"bs-datepicker\" [ngClass]=\"containerClass\">\n    <div class=\"bs-datepicker-container\">\n      <!--calendars-->\n      <div class=\"bs-calendar-container\" role=\"application\">\n        @switch (viewMode | async) {\n          <!--days calendar-->\n          @case ('day') {\n            <div class=\"bs-media-container\">\n              @for (calendar of daysCalendar$ | async; track calendar) {\n                <bs-days-calendar-view\n                  [class.bs-datepicker-multiple]=\"multipleCalendars\"\n                  [calendar]=\"calendar\"\n                  [isDisabled]=\"isDatePickerDisabled\"\n                  [options]=\"options$ | async\"\n                  (onNavigate)=\"navigateTo($event)\"\n                  (onViewMode)=\"setViewMode($event)\"\n                  (onHover)=\"dayHoverHandler($event)\"\n                  (onHoverWeek)=\"weekHoverHandler($event)\"\n                  (onSelect)=\"daySelectHandler($event)\">\n                </bs-days-calendar-view>\n              }\n            </div>\n            @if (withTimepicker) {\n              <div class=\"bs-timepicker-in-datepicker-container\">\n                <timepicker #startTP [disabled]=\"isDatePickerDisabled\"></timepicker>\n                @if (isRangePicker) {\n                  <timepicker #endTP [disabled]=\"isDatePickerDisabled\"></timepicker>\n                }\n              </div>\n            }\n          }\n          <!--months calendar-->\n          @case ('month') {\n            <div class=\"bs-media-container\">\n              @for (calendar of monthsCalendar | async; track calendar) {\n                <bs-month-calendar-view\n                  [class.bs-datepicker-multiple]=\"multipleCalendars\"\n                  [calendar]=\"calendar\"\n                  (onNavigate)=\"navigateTo($event)\"\n                  (onViewMode)=\"setViewMode($event)\"\n                  (onHover)=\"monthHoverHandler($event)\"\n                  (onSelect)=\"monthSelectHandler($event)\">\n                </bs-month-calendar-view>\n              }\n            </div>\n          }\n          <!--years calendar-->\n          @case ('year') {\n            <div class=\"bs-media-container\">\n              @for (calendar of yearsCalendar | async; track calendar) {\n                <bs-years-calendar-view\n                  [class.bs-datepicker-multiple]=\"multipleCalendars\"\n                  [calendar]=\"calendar\"\n                  (onNavigate)=\"navigateTo($event)\"\n                  (onViewMode)=\"setViewMode($event)\"\n                  (onHover)=\"yearHoverHandler($event)\"\n                  (onSelect)=\"yearSelectHandler($event)\">\n                </bs-years-calendar-view>\n              }\n            </div>\n          }\n        }\n      </div>\n      <!--applycancel buttons-->\n      @if (false) {\n        <div class=\"bs-datepicker-buttons\">\n          <button class=\"btn btn-success\" type=\"button\">Apply</button>\n          <button class=\"btn btn-default\" type=\"button\">Cancel</button>\n        </div>\n      }\n      @if (showTodayBtn || showClearBtn) {\n        <div class=\"bs-datepicker-buttons\">\n          @if (showTodayBtn) {\n            <div class=\"btn-today-wrapper\"\n              [class.today-left]=\"todayPos === 'left'\"\n              [class.today-right]=\"todayPos === 'right'\"\n              [class.today-center]=\"todayPos === 'center'\"\n              >\n              <button class=\"btn btn-success\" (click)=\"setToday()\">{{todayBtnLbl}}</button>\n            </div>\n          }\n          @if (showClearBtn) {\n            <div class=\"btn-clear-wrapper\"\n              [class.clear-left]=\"clearPos === 'left'\"\n              [class.clear-right]=\"clearPos === 'right'\"\n              [class.clear-center]=\"clearPos === 'center'\"\n              >\n              <button class=\"btn btn-success\" (click)=\"clearDate()\">{{clearBtnLbl}}</button>\n            </div>\n          }\n        </div>\n      }\n    </div>\n    <!--custom dates or date ranges picker-->\n    @if (customRanges && customRanges.length > 0) {\n      <div class=\"bs-datepicker-custom-range\">\n        <bs-custom-date-view\n          [selectedRange]=\"chosenRange\"\n          [ranges]=\"customRanges\"\n          [customRangeLabel]=\"customRangeBtnLbl\"\n          (onSelect)=\"setRangeOnCalendar($event)\">\n        </bs-custom-date-view>\n      </div>\n    }\n  </div>\n}\n", dependencies: [{ kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "component", type: BsDaysCalendarViewComponent, selector: "bs-days-calendar-view", inputs: ["calendar", "options", "isDisabled"], outputs: ["onNavigate", "onViewMode", "onSelect", "onHover", "onHoverWeek"] }, { kind: "ngmodule", type: TimepickerModule }, { kind: "component", type: i6.TimepickerComponent, selector: "timepicker", inputs: ["hourStep", "minuteStep", "secondsStep", "readonlyInput", "disabled", "mousewheel", "arrowkeys", "showSpinners", "showMeridian", "showMinutes", "showSeconds", "meridians", "min", "max", "hoursPlaceholder", "minutesPlaceholder", "secondsPlaceholder"], outputs: ["isValid", "meridianChange"] }, { kind: "component", type: BsMonthCalendarViewComponent, selector: "bs-month-calendar-view", inputs: ["calendar"], outputs: ["onNavigate", "onViewMode", "onSelect", "onHover"] }, { kind: "component", type: BsYearsCalendarViewComponent, selector: "bs-years-calendar-view", inputs: ["calendar"], outputs: ["onNavigate", "onViewMode", "onSelect", "onHover"] }, { kind: "component", type: BsCustomDatesViewComponent, selector: "bs-custom-date-view", inputs: ["ranges", "selectedRange", "customRangeLabel"], outputs: ["onSelect"] }, { kind: "pipe", type: AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.Eager }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: BsDaterangepickerInlineContainerComponent, decorators: [{
            type: Component,
            args: [{ selector: 'bs-daterangepicker-inline-container', changeDetection: ChangeDetectionStrategy.Eager, providers: [BsDatepickerStore, BsDatepickerEffects, BsDatepickerActions], host: {
                        '(click)': '_stopPropagation($event)'
                    }, standalone: true, imports: [NgClass, BsDaysCalendarViewComponent, TimepickerModule, BsMonthCalendarViewComponent, BsYearsCalendarViewComponent, BsCustomDatesViewComponent, AsyncPipe], template: "<!-- days calendar view mode -->\n@if (viewMode | async) {\n  <div class=\"bs-datepicker\" [ngClass]=\"containerClass\">\n    <div class=\"bs-datepicker-container\">\n      <!--calendars-->\n      <div class=\"bs-calendar-container\" role=\"application\">\n        @switch (viewMode | async) {\n          <!--days calendar-->\n          @case ('day') {\n            <div class=\"bs-media-container\">\n              @for (calendar of daysCalendar$ | async; track calendar) {\n                <bs-days-calendar-view\n                  [class.bs-datepicker-multiple]=\"multipleCalendars\"\n                  [calendar]=\"calendar\"\n                  [isDisabled]=\"isDatePickerDisabled\"\n                  [options]=\"options$ | async\"\n                  (onNavigate)=\"navigateTo($event)\"\n                  (onViewMode)=\"setViewMode($event)\"\n                  (onHover)=\"dayHoverHandler($event)\"\n                  (onHoverWeek)=\"weekHoverHandler($event)\"\n                  (onSelect)=\"daySelectHandler($event)\">\n                </bs-days-calendar-view>\n              }\n            </div>\n            @if (withTimepicker) {\n              <div class=\"bs-timepicker-in-datepicker-container\">\n                <timepicker #startTP [disabled]=\"isDatePickerDisabled\"></timepicker>\n                @if (isRangePicker) {\n                  <timepicker #endTP [disabled]=\"isDatePickerDisabled\"></timepicker>\n                }\n              </div>\n            }\n          }\n          <!--months calendar-->\n          @case ('month') {\n            <div class=\"bs-media-container\">\n              @for (calendar of monthsCalendar | async; track calendar) {\n                <bs-month-calendar-view\n                  [class.bs-datepicker-multiple]=\"multipleCalendars\"\n                  [calendar]=\"calendar\"\n                  (onNavigate)=\"navigateTo($event)\"\n                  (onViewMode)=\"setViewMode($event)\"\n                  (onHover)=\"monthHoverHandler($event)\"\n                  (onSelect)=\"monthSelectHandler($event)\">\n                </bs-month-calendar-view>\n              }\n            </div>\n          }\n          <!--years calendar-->\n          @case ('year') {\n            <div class=\"bs-media-container\">\n              @for (calendar of yearsCalendar | async; track calendar) {\n                <bs-years-calendar-view\n                  [class.bs-datepicker-multiple]=\"multipleCalendars\"\n                  [calendar]=\"calendar\"\n                  (onNavigate)=\"navigateTo($event)\"\n                  (onViewMode)=\"setViewMode($event)\"\n                  (onHover)=\"yearHoverHandler($event)\"\n                  (onSelect)=\"yearSelectHandler($event)\">\n                </bs-years-calendar-view>\n              }\n            </div>\n          }\n        }\n      </div>\n      <!--applycancel buttons-->\n      @if (false) {\n        <div class=\"bs-datepicker-buttons\">\n          <button class=\"btn btn-success\" type=\"button\">Apply</button>\n          <button class=\"btn btn-default\" type=\"button\">Cancel</button>\n        </div>\n      }\n      @if (showTodayBtn || showClearBtn) {\n        <div class=\"bs-datepicker-buttons\">\n          @if (showTodayBtn) {\n            <div class=\"btn-today-wrapper\"\n              [class.today-left]=\"todayPos === 'left'\"\n              [class.today-right]=\"todayPos === 'right'\"\n              [class.today-center]=\"todayPos === 'center'\"\n              >\n              <button class=\"btn btn-success\" (click)=\"setToday()\">{{todayBtnLbl}}</button>\n            </div>\n          }\n          @if (showClearBtn) {\n            <div class=\"btn-clear-wrapper\"\n              [class.clear-left]=\"clearPos === 'left'\"\n              [class.clear-right]=\"clearPos === 'right'\"\n              [class.clear-center]=\"clearPos === 'center'\"\n              >\n              <button class=\"btn btn-success\" (click)=\"clearDate()\">{{clearBtnLbl}}</button>\n            </div>\n          }\n        </div>\n      }\n    </div>\n    <!--custom dates or date ranges picker-->\n    @if (customRanges && customRanges.length > 0) {\n      <div class=\"bs-datepicker-custom-range\">\n        <bs-custom-date-view\n          [selectedRange]=\"chosenRange\"\n          [ranges]=\"customRanges\"\n          [customRangeLabel]=\"customRangeBtnLbl\"\n          (onSelect)=\"setRangeOnCalendar($event)\">\n        </bs-custom-date-view>\n      </div>\n    }\n  </div>\n}\n" }]
        }], ctorParameters: () => [{ type: i0.Renderer2 }, { type: BsDatepickerConfig }, { type: BsDatepickerStore }, { type: i0.ElementRef }, { type: BsDatepickerActions }, { type: BsDatepickerEffects }, { type: i5.PositioningService }], propDecorators: { disabledValue: [{
                type: HostBinding,
                args: ['attr.disabled']
            }], readonlyValue: [{
                type: HostBinding,
                args: ['attr.readonly']
            }] } });

class BsDaterangepickerInlineDirective {
    /**
     * Initial value of datepicker
     */
    set bsValue(value) {
        if (this._bsValue === value) {
            return;
        }
        if (value && this.bsConfig?.initCurrentTime) {
            value = setDateRangesCurrentTimeOnDateSelect(value);
        }
        this._bsValue = value;
        this.bsValueChange.emit(value);
    }
    constructor(_config, _elementRef, _renderer, _viewContainerRef, cis) {
        this._config = _config;
        this._elementRef = _elementRef;
        /**
         * Indicates whether datepicker is enabled or not
         */
        this.isDisabled = false;
        /**
         * Emits when daterangepicker value has been changed
         */
        this.bsValueChange = new EventEmitter();
        this._subs = [];
        // todo: assign only subset of fields
        Object.assign(this, this._config);
        this._datepicker = cis.createLoader(_elementRef, _viewContainerRef, _renderer);
    }
    ngOnInit() {
        this.setConfig();
        this.initSubscribes();
    }
    ngOnChanges(changes) {
        if (changes["bsConfig"]) {
            if (changes["bsConfig"].currentValue.initCurrentTime && changes["bsConfig"].currentValue.initCurrentTime !== changes["bsConfig"].previousValue.initCurrentTime && this._bsValue) {
                this._bsValue = setDateRangesCurrentTimeOnDateSelect(this._bsValue);
                this.bsValueChange.emit(this._bsValue);
            }
        }
        if (!this._datepickerRef || !this._datepickerRef.instance) {
            return;
        }
        if (changes["minDate"]) {
            this._datepickerRef.instance.minDate = this.minDate;
        }
        if (changes["maxDate"]) {
            this._datepickerRef.instance.maxDate = this.maxDate;
        }
        if (changes["datesEnabled"]) {
            this._datepickerRef.instance.datesEnabled = this.datesEnabled;
            this._datepickerRef.instance.value = this._bsValue;
        }
        if (changes["datesDisabled"]) {
            this._datepickerRef.instance.datesDisabled = this.datesDisabled;
        }
        if (changes["daysDisabled"]) {
            this._datepickerRef.instance.daysDisabled = this.daysDisabled;
        }
        if (changes["isDisabled"]) {
            this._datepickerRef.instance.isDisabled = this.isDisabled;
        }
        if (changes["dateCustomClasses"]) {
            this._datepickerRef.instance.dateCustomClasses = this.dateCustomClasses;
        }
        this.setConfig();
    }
    /**
     * Set config for datepicker
     */
    setConfig() {
        if (this._datepicker) {
            this._datepicker.hide();
        }
        this._config = Object.assign({}, this._config, this.bsConfig, {
            value: checkBsValue(this._bsValue, this.maxDate || this.bsConfig && this.bsConfig.maxDate),
            isDisabled: this.isDisabled,
            minDate: this.minDate || this.bsConfig && this.bsConfig.minDate,
            maxDate: this.maxDate || this.bsConfig && this.bsConfig.maxDate,
            daysDisabled: this.daysDisabled || this.bsConfig && this.bsConfig.daysDisabled,
            dateCustomClasses: this.dateCustomClasses || this.bsConfig && this.bsConfig.dateCustomClasses,
            datesDisabled: this.datesDisabled || this.bsConfig && this.bsConfig.datesDisabled,
            datesEnabled: this.datesEnabled || this.bsConfig && this.bsConfig.datesEnabled,
            ranges: checkRangesWithMaxDate(this.bsConfig && this.bsConfig.ranges, this.maxDate || this.bsConfig && this.bsConfig.maxDate),
            maxDateRange: this.bsConfig && this.bsConfig.maxDateRange,
            initCurrentTime: this.bsConfig?.initCurrentTime
        });
        this._datepickerRef = this._datepicker
            .provide({ provide: BsDatepickerConfig, useValue: this._config })
            .attach(BsDaterangepickerInlineContainerComponent)
            .to(this._elementRef)
            .show();
        this.initSubscribes();
    }
    initSubscribes() {
        this.unsubscribeSubscriptions();
        // if date changes from external source (model -> view)
        this._subs.push(this.bsValueChange.subscribe((value) => {
            if (this._datepickerRef) {
                this._datepickerRef.instance.value = value;
            }
        }));
        // if date changes from picker (view -> model)
        if (this._datepickerRef) {
            this._subs.push(this._datepickerRef.instance.valueChange
                .pipe(filter((range) => range && range[0] && !!range[1]))
                .subscribe((value) => {
                this.bsValue = value;
            }));
        }
    }
    unsubscribeSubscriptions() {
        if (this._subs?.length) {
            this._subs.map(sub => sub.unsubscribe());
            this._subs.length = 0;
        }
    }
    ngOnDestroy() {
        this._datepicker.dispose();
        this.unsubscribeSubscriptions();
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: BsDaterangepickerInlineDirective, deps: [{ token: BsDaterangepickerInlineConfig }, { token: i0.ElementRef }, { token: i0.Renderer2 }, { token: i0.ViewContainerRef }, { token: i2$1.ComponentLoaderFactory }], target: i0.ɵɵFactoryTarget.Directive }); }
    static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "22.0.2", type: BsDaterangepickerInlineDirective, isStandalone: true, selector: "bs-daterangepicker-inline", inputs: { bsValue: "bsValue", bsConfig: "bsConfig", isDisabled: "isDisabled", minDate: "minDate", maxDate: "maxDate", dateCustomClasses: "dateCustomClasses", daysDisabled: "daysDisabled", datesDisabled: "datesDisabled", datesEnabled: "datesEnabled" }, outputs: { bsValueChange: "bsValueChange" }, providers: [ComponentLoaderFactory, PositioningService], exportAs: ["bsDaterangepickerInline"], usesOnChanges: true, ngImport: i0 }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: BsDaterangepickerInlineDirective, decorators: [{
            type: Directive,
            args: [{
                    selector: 'bs-daterangepicker-inline',
                    exportAs: 'bsDaterangepickerInline',
                    standalone: true,
                    providers: [ComponentLoaderFactory, PositioningService]
                }]
        }], ctorParameters: () => [{ type: BsDaterangepickerInlineConfig }, { type: i0.ElementRef }, { type: i0.Renderer2 }, { type: i0.ViewContainerRef }, { type: i2$1.ComponentLoaderFactory }], propDecorators: { bsValue: [{
                type: Input
            }], bsConfig: [{
                type: Input
            }], isDisabled: [{
                type: Input
            }], minDate: [{
                type: Input
            }], maxDate: [{
                type: Input
            }], dateCustomClasses: [{
                type: Input
            }], daysDisabled: [{
                type: Input
            }], datesDisabled: [{
                type: Input
            }], datesEnabled: [{
                type: Input
            }], bsValueChange: [{
                type: Output
            }] } });

const BS_DATEPICKER_VALUE_ACCESSOR = {
    provide: NG_VALUE_ACCESSOR,
    useExisting: forwardRef(() => BsDatepickerInputDirective),
    multi: true
};
const BS_DATEPICKER_VALIDATOR = {
    provide: NG_VALIDATORS,
    useExisting: forwardRef(() => BsDatepickerInputDirective),
    multi: true
};
class BsDatepickerInputDirective {
    constructor(_picker, _localeService, _renderer, _elRef, changeDetection) {
        this._picker = _picker;
        this._localeService = _localeService;
        this._renderer = _renderer;
        this._elRef = _elRef;
        this.changeDetection = changeDetection;
        this._onChange = Function.prototype;
        this._onTouched = Function.prototype;
        this._validatorChange = Function.prototype;
        this._subs = new Subscription();
    }
    onChange(event) {
        // eslint-disable-next-line @typescript-eslint/no-explicit-any
        this.writeValue(event.target.value);
        this._onChange(this._value);
        if (this._picker._config.returnFocusToInput) {
            this._renderer.selectRootElement(this._elRef.nativeElement).focus();
        }
        this._onTouched();
    }
    onBlur() {
        this._onTouched();
    }
    hide() {
        this._picker.hide();
        this._renderer.selectRootElement(this._elRef.nativeElement).blur();
        if (this._picker._config.returnFocusToInput) {
            this._renderer.selectRootElement(this._elRef.nativeElement).focus();
        }
    }
    ngOnInit() {
        const setBsValue = (value) => {
            this._setInputValue(value);
            if (this._value !== value) {
                this._value = value;
                this._onChange(value);
                this._onTouched();
            }
            this.changeDetection.markForCheck();
        };
        // if value set via [bsValue] it will not get into value change
        if (this._picker._bsValue) {
            setBsValue(this._picker._bsValue);
        }
        // update input value on datepicker value update
        this._subs.add(this._picker.bsValueChange.subscribe(setBsValue));
        // update input value on locale change
        this._subs.add(this._localeService.localeChange.subscribe(() => {
            this._setInputValue(this._value);
        }));
        this._subs.add(this._picker.dateInputFormat$.pipe(distinctUntilChanged()).subscribe(() => {
            this._setInputValue(this._value);
        }));
    }
    ngOnDestroy() {
        this._subs.unsubscribe();
    }
    _setInputValue(value) {
        const initialDate = !value
            ? ''
            : formatDate(value, this._picker._config.dateInputFormat, this._localeService.currentLocale);
        this._renderer.setProperty(this._elRef.nativeElement, 'value', initialDate);
    }
    validate(c) {
        const _value = c.value;
        if (_value === null || _value === undefined || _value === '') {
            return null;
        }
        if (isDate(_value)) {
            const _isDateValid = isDateValid(_value);
            if (!_isDateValid) {
                return { bsDate: { invalid: _value } };
            }
            if (this._picker && this._picker.minDate && isBefore(_value, this._picker.minDate, 'date')) {
                this.writeValue(this._picker.minDate);
                return this._picker.ignoreMinMaxErrors ? null : { bsDate: { minDate: this._picker.minDate } };
            }
            if (this._picker && this._picker.maxDate && isAfter(_value, this._picker.maxDate, 'date')) {
                this.writeValue(this._picker.maxDate);
                return this._picker.ignoreMinMaxErrors ? null : { bsDate: { maxDate: this._picker.maxDate } };
            }
        }
        return null;
    }
    registerOnValidatorChange(fn) {
        this._validatorChange = fn;
    }
    writeValue(value) {
        if (!value) {
            this._value = void 0;
        }
        else {
            const _localeKey = this._localeService.currentLocale;
            const _locale = getLocale(_localeKey);
            if (!_locale) {
                throw new Error(`Locale "${_localeKey}" is not defined, please add it with "defineLocale(...)"`);
            }
            this._value = parseDate(value, this._picker._config.dateInputFormat, this._localeService.currentLocale);
            if (this._picker._config.useUtc) {
                const utcValue = utcAsLocal(this._value);
                this._value = utcValue === null ? void 0 : utcValue;
            }
        }
        this._picker.bsValue = this._value;
    }
    setDisabledState(isDisabled) {
        this._picker.isDisabled = isDisabled;
        if (isDisabled) {
            this._renderer.setAttribute(this._elRef.nativeElement, 'disabled', 'disabled');
            return;
        }
        this._renderer.removeAttribute(this._elRef.nativeElement, 'disabled');
    }
    registerOnChange(fn) {
        this._onChange = fn;
    }
    registerOnTouched(fn) {
        this._onTouched = fn;
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: BsDatepickerInputDirective, deps: [{ token: BsDatepickerDirective, host: true }, { token: BsLocaleService }, { token: i0.Renderer2 }, { token: i0.ElementRef }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Directive }); }
    static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "22.0.2", type: BsDatepickerInputDirective, isStandalone: true, selector: "input[bsDatepicker]", host: { listeners: { "change": "onChange($event)", "blur": "onBlur()", "keyup.esc": "hide()", "keydown.enter": "hide()" } }, providers: [
            BS_DATEPICKER_VALUE_ACCESSOR,
            BS_DATEPICKER_VALIDATOR
        ], ngImport: i0 }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: BsDatepickerInputDirective, decorators: [{
            type: Directive,
            args: [{
                    selector: `input[bsDatepicker]`,
                    providers: [
                        BS_DATEPICKER_VALUE_ACCESSOR,
                        BS_DATEPICKER_VALIDATOR
                    ],
                    standalone: true
                }]
        }], ctorParameters: () => [{ type: BsDatepickerDirective, decorators: [{
                    type: Host
                }] }, { type: BsLocaleService }, { type: i0.Renderer2 }, { type: i0.ElementRef }, { type: i0.ChangeDetectorRef }], propDecorators: { onChange: [{
                type: HostListener,
                args: ['change', ['$event']]
            }], onBlur: [{
                type: HostListener,
                args: ['blur']
            }], hide: [{
                type: HostListener,
                args: ['keyup.esc']
            }, {
                type: HostListener,
                args: ['keydown.enter']
            }] } });

class BsDaterangepickerConfig extends BsDatepickerConfig {
    constructor() {
        super(...arguments);
        // DatepickerRenderOptions
        this.displayMonths = 2;
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: BsDaterangepickerConfig, deps: null, target: i0.ɵɵFactoryTarget.Injectable }); }
    static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: BsDaterangepickerConfig, providedIn: 'root' }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: BsDaterangepickerConfig, decorators: [{
            type: Injectable,
            args: [{
                    providedIn: 'root'
                }]
        }] });

let previousDate;
class BsDaterangepickerDirective {
    /**
     * Returns whether or not the daterangepicker is currently being shown
     */
    get isOpen() {
        return this._datepicker.isShown;
    }
    set isOpen(value) {
        this.isOpen$.next(value);
    }
    /**
     * Initial value of daterangepicker
     */
    set bsValue(value) {
        if (this._bsValue === value) {
            return;
        }
        if (value && this.bsConfig?.initCurrentTime) {
            value = setDateRangesCurrentTimeOnDateSelect(value);
        }
        this.initPreviousValue();
        this._bsValue = value;
        this.bsValueChange.emit(value);
    }
    get isDatepickerReadonly() {
        return this.isDisabled ? '' : null;
    }
    get rangeInputFormat$() {
        return this._rangeInputFormat$;
    }
    constructor(_config, _elementRef, _renderer, _viewContainerRef, cis) {
        this._config = _config;
        this._elementRef = _elementRef;
        this._renderer = _renderer;
        /**
         * Placement of a daterangepicker. Accepts: "top", "bottom", "left", "right"
         */
        this.placement = 'bottom';
        /**
         * Specifies events that should trigger. Supports a space separated list of
         * event names.
         */
        this.triggers = 'click';
        /**
         * Close daterangepicker on outside click
         */
        this.outsideClick = true;
        /**
         * A selector specifying the element the daterangepicker should be appended to.
         */
        this.container = 'body';
        this.outsideEsc = true;
        this.isDestroy$ = new Subject();
        /**
         * Indicates whether daterangepicker's content is enabled or not
         */
        this.isDisabled = false;
        /**
         * Emits when daterangepicker value has been changed
         */
        this.bsValueChange = new EventEmitter();
        this._subs = [];
        this._rangeInputFormat$ = new Subject();
        this._datepicker = cis.createLoader(_elementRef, _viewContainerRef, _renderer);
        Object.assign(this, _config);
        this.onShown = this._datepicker.onShown;
        this.onHidden = this._datepicker.onHidden;
        this.isOpen$ = new BehaviorSubject(this.isOpen);
    }
    ngOnInit() {
        this.isDestroy$ = new Subject();
        this._datepicker.listen({
            outsideClick: this.outsideClick,
            outsideEsc: this.outsideEsc,
            triggers: this.triggers,
            show: () => this.show()
        });
        this.initPreviousValue();
        this.setConfig();
    }
    ngOnChanges(changes) {
        if (changes["bsConfig"]) {
            if (changes["bsConfig"].currentValue?.initCurrentTime && changes["bsConfig"].currentValue?.initCurrentTime !== changes["bsConfig"].previousValue?.initCurrentTime && this._bsValue) {
                this.initPreviousValue();
                this._bsValue = setDateRangesCurrentTimeOnDateSelect(this._bsValue);
                this.bsValueChange.emit(this._bsValue);
            }
            this.setConfig();
            this._rangeInputFormat$.next(changes["bsConfig"].currentValue && changes["bsConfig"].currentValue.rangeInputFormat);
        }
        if (!this._datepickerRef || !this._datepickerRef.instance) {
            return;
        }
        if (changes["minDate"]) {
            this._datepickerRef.instance.minDate = this.minDate;
        }
        if (changes["maxDate"]) {
            this._datepickerRef.instance.maxDate = this.maxDate;
        }
        if (changes["datesDisabled"]) {
            this._datepickerRef.instance.datesDisabled = this.datesDisabled;
        }
        if (changes["datesEnabled"]) {
            this._datepickerRef.instance.datesEnabled = this.datesEnabled;
        }
        if (changes["daysDisabled"]) {
            this._datepickerRef.instance.daysDisabled = this.daysDisabled;
        }
        if (changes["isDisabled"]) {
            this._datepickerRef.instance.isDisabled = this.isDisabled;
        }
        if (changes["dateCustomClasses"]) {
            this._datepickerRef.instance.dateCustomClasses = this.dateCustomClasses;
        }
    }
    ngAfterViewInit() {
        this.isOpen$.pipe(filter(isOpen => isOpen !== this.isOpen), takeUntil(this.isDestroy$))
            .subscribe(() => this.toggle());
    }
    /**
     * Opens an element’s datepicker. This is considered a “manual” triggering of
     * the datepicker.
     */
    show() {
        if (this._datepicker.isShown) {
            return;
        }
        this.setConfig();
        this._datepickerRef = this._datepicker
            .provide({ provide: BsDatepickerConfig, useValue: this._config })
            .attach(BsDaterangepickerContainerComponent)
            .to(this.container)
            .position({ attachment: this.placement })
            .show({ placement: this.placement });
        this.initSubscribes();
    }
    initSubscribes() {
        // if date changes from external source (model -> view)
        this._subs.push(this.bsValueChange.subscribe((value) => {
            if (this._datepickerRef) {
                this._datepickerRef.instance.value = value;
            }
        }));
        // if date changes from picker (view -> model)
        if (this._datepickerRef) {
            this._subs.push(this._datepickerRef.instance.valueChange
                .pipe(filter((range) => range && range[0] && !!range[1]))
                .subscribe((value) => {
                this.initPreviousValue();
                this.bsValue = value;
                if (this.keepDatepickerModalOpened()) {
                    return;
                }
                this.hide();
            }));
        }
    }
    initPreviousValue() {
        previousDate = this._bsValue;
    }
    keepDatepickerModalOpened() {
        if (!previousDate || !this.bsConfig?.keepDatepickerOpened || !this._config.withTimepicker) {
            return false;
        }
        return this.isDateSame();
    }
    isDateSame() {
        return ((this._bsValue?.[0]?.getDate() === previousDate?.[0]?.getDate())
            && (this._bsValue?.[0]?.getMonth() === previousDate?.[0]?.getMonth())
            && (this._bsValue?.[0]?.getFullYear() === previousDate?.[0]?.getFullYear())
            && (this._bsValue?.[1]?.getDate() === previousDate?.[1]?.getDate())
            && (this._bsValue?.[1]?.getMonth() === previousDate?.[1]?.getMonth())
            && (this._bsValue?.[1]?.getFullYear() === previousDate?.[1]?.getFullYear()));
    }
    /**
     * Set config for daterangepicker
     */
    setConfig() {
        this._config = Object.assign({}, this._config, this.bsConfig, {
            value: this.bsConfig?.keepDatesOutOfRules ? this._bsValue : checkBsValue(this._bsValue, this.maxDate || this.bsConfig && this.bsConfig.maxDate),
            isDisabled: this.isDisabled,
            minDate: this.minDate || this.bsConfig && this.bsConfig.minDate,
            maxDate: this.maxDate || this.bsConfig && this.bsConfig.maxDate,
            daysDisabled: this.daysDisabled || this.bsConfig && this.bsConfig.daysDisabled,
            dateCustomClasses: this.dateCustomClasses || this.bsConfig && this.bsConfig.dateCustomClasses,
            datesDisabled: this.datesDisabled || this.bsConfig && this.bsConfig.datesDisabled,
            datesEnabled: this.datesEnabled || this.bsConfig && this.bsConfig.datesEnabled,
            ranges: checkRangesWithMaxDate(this.bsConfig && this.bsConfig.ranges, this.maxDate || this.bsConfig && this.bsConfig.maxDate),
            maxDateRange: this.bsConfig && this.bsConfig.maxDateRange,
            initCurrentTime: this.bsConfig?.initCurrentTime,
            keepDatepickerOpened: this.bsConfig?.keepDatepickerOpened,
            keepDatesOutOfRules: this.bsConfig?.keepDatesOutOfRules
        });
    }
    /**
     * Closes an element’s datepicker. This is considered a “manual” triggering of
     * the datepicker.
     */
    hide() {
        if (this.isOpen) {
            this._datepicker.hide();
        }
        for (const sub of this._subs) {
            sub.unsubscribe();
        }
        if (this._config.returnFocusToInput) {
            this._renderer.selectRootElement(this._elementRef.nativeElement).focus();
        }
    }
    /**
     * Toggles an element’s datepicker. This is considered a “manual” triggering
     * of the datepicker.
     */
    toggle() {
        if (this.isOpen) {
            return this.hide();
        }
        this.show();
    }
    unsubscribeSubscriptions() {
        if (this._subs?.length) {
            this._subs.map(sub => sub.unsubscribe());
            this._subs.length = 0;
        }
    }
    ngOnDestroy() {
        this._datepicker.dispose();
        this.isOpen$.next(false);
        if (this.isDestroy$) {
            this.isDestroy$.next(null);
            this.isDestroy$.complete();
        }
        this.unsubscribeSubscriptions();
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: BsDaterangepickerDirective, deps: [{ token: BsDaterangepickerConfig }, { token: i0.ElementRef }, { token: i0.Renderer2 }, { token: i0.ViewContainerRef }, { token: i2$1.ComponentLoaderFactory }], target: i0.ɵɵFactoryTarget.Directive }); }
    static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "22.0.2", type: BsDaterangepickerDirective, isStandalone: true, selector: "[bsDaterangepicker]", inputs: { placement: "placement", triggers: "triggers", outsideClick: "outsideClick", container: "container", outsideEsc: "outsideEsc", isOpen: "isOpen", bsValue: "bsValue", bsConfig: "bsConfig", isDisabled: "isDisabled", minDate: "minDate", maxDate: "maxDate", dateCustomClasses: "dateCustomClasses", daysDisabled: "daysDisabled", datesDisabled: "datesDisabled", datesEnabled: "datesEnabled" }, outputs: { onShown: "onShown", onHidden: "onHidden", bsValueChange: "bsValueChange" }, host: { properties: { "attr.readonly": "this.isDatepickerReadonly" } }, providers: [ComponentLoaderFactory, PositioningService], exportAs: ["bsDaterangepicker"], usesOnChanges: true, ngImport: i0 }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: BsDaterangepickerDirective, decorators: [{
            type: Directive,
            args: [{
                    selector: '[bsDaterangepicker]',
                    exportAs: 'bsDaterangepicker',
                    standalone: true,
                    providers: [ComponentLoaderFactory, PositioningService]
                }]
        }], ctorParameters: () => [{ type: BsDaterangepickerConfig }, { type: i0.ElementRef }, { type: i0.Renderer2 }, { type: i0.ViewContainerRef }, { type: i2$1.ComponentLoaderFactory }], propDecorators: { placement: [{
                type: Input
            }], triggers: [{
                type: Input
            }], outsideClick: [{
                type: Input
            }], container: [{
                type: Input
            }], outsideEsc: [{
                type: Input
            }], isOpen: [{
                type: Input
            }], onShown: [{
                type: Output
            }], onHidden: [{
                type: Output
            }], bsValue: [{
                type: Input
            }], bsConfig: [{
                type: Input
            }], isDisabled: [{
                type: Input
            }], minDate: [{
                type: Input
            }], maxDate: [{
                type: Input
            }], dateCustomClasses: [{
                type: Input
            }], daysDisabled: [{
                type: Input
            }], datesDisabled: [{
                type: Input
            }], datesEnabled: [{
                type: Input
            }], bsValueChange: [{
                type: Output
            }], isDatepickerReadonly: [{
                type: HostBinding,
                args: ['attr.readonly']
            }] } });

const BS_DATERANGEPICKER_VALUE_ACCESSOR = {
    provide: NG_VALUE_ACCESSOR,
    useExisting: forwardRef(() => BsDaterangepickerInputDirective),
    multi: true
};
const BS_DATERANGEPICKER_VALIDATOR = {
    provide: NG_VALIDATORS,
    useExisting: forwardRef(() => BsDaterangepickerInputDirective),
    multi: true
};
class BsDaterangepickerInputDirective {
    constructor(_picker, _localeService, _renderer, _elRef, changeDetection) {
        this._picker = _picker;
        this._localeService = _localeService;
        this._renderer = _renderer;
        this._elRef = _elRef;
        this.changeDetection = changeDetection;
        this._onChange = Function.prototype;
        this._onTouched = Function.prototype;
        this._validatorChange = Function.prototype;
        this._subs = new Subscription();
    }
    ngOnInit() {
        const setBsValue = (value) => {
            this._setInputValue(value);
            if (this._value !== value) {
                this._value = value;
                this._onChange(value);
                this._onTouched();
            }
            this.changeDetection.markForCheck();
        };
        // if value set via [bsValue] it will not get into value change
        if (this._picker._bsValue) {
            setBsValue(this._picker._bsValue);
        }
        // update input value on datepicker value update
        this._subs.add(this._picker.bsValueChange.subscribe((value) => {
            this._setInputValue(value);
            if (this._value !== value) {
                this._value = value;
                this._onChange(value);
                this._onTouched();
            }
            this.changeDetection.markForCheck();
        }));
        // update input value on locale change
        this._subs.add(this._localeService.localeChange.subscribe(() => {
            this._setInputValue(this._value);
        }));
        this._subs.add(
        // update input value on format change
        this._picker.rangeInputFormat$.pipe(distinctUntilChanged()).subscribe(() => {
            this._setInputValue(this._value);
        }));
    }
    ngOnDestroy() {
        this._subs.unsubscribe();
    }
    onKeydownEvent(event) {
        if (event.keyCode === 13 || event.code === 'Enter') {
            this.hide();
        }
    }
    _setInputValue(date) {
        let range = '';
        if (date) {
            const start = !date[0] ? ''
                : formatDate(date[0], this._picker._config.rangeInputFormat, this._localeService.currentLocale);
            const end = !date[1] ? ''
                : formatDate(date[1], this._picker._config.rangeInputFormat, this._localeService.currentLocale);
            range = (start && end) ? start + this._picker._config.rangeSeparator + end : '';
        }
        this._renderer.setProperty(this._elRef.nativeElement, 'value', range);
    }
    onChange(event) {
        // eslint-disable-next-line @typescript-eslint/no-explicit-any
        this.writeValue(event.target.value);
        this._onChange(this._value);
        if (this._picker._config.returnFocusToInput) {
            this._renderer.selectRootElement(this._elRef.nativeElement).focus();
        }
        this._onTouched();
    }
    validate(c) {
        let _value = c.value;
        const errors = [];
        if (_value === null || _value === undefined || !isArray(_value)) {
            return null;
        }
        _value = _value.slice().sort((a, b) => a.getTime() - b.getTime());
        const _isFirstDateValid = isDateValid(_value[0]);
        const _isSecondDateValid = isDateValid(_value[1]);
        if (!_isFirstDateValid) {
            return { bsDate: { invalid: _value[0] } };
        }
        if (!_isSecondDateValid) {
            return { bsDate: { invalid: _value[1] } };
        }
        if (this._picker && this._picker.minDate && isBefore(_value[0], this._picker.minDate, 'date')) {
            _value[0] = this._picker.minDate;
            errors.push({ bsDate: { minDate: this._picker.minDate } });
        }
        if (this._picker && this._picker.maxDate && isAfter(_value[1], this._picker.maxDate, 'date')) {
            _value[1] = this._picker.maxDate;
            errors.push({ bsDate: { maxDate: this._picker.maxDate } });
        }
        if (errors.length > 0) {
            this.writeValue(_value);
            return errors;
        }
        return null;
    }
    registerOnValidatorChange(fn) {
        this._validatorChange = fn;
    }
    writeValue(value) {
        if (!value) {
            this._value = void 0;
        }
        else {
            const _localeKey = this._localeService.currentLocale;
            const _locale = getLocale(_localeKey);
            if (!_locale) {
                throw new Error(`Locale "${_localeKey}" is not defined, please add it with "defineLocale(...)"`);
            }
            let _input = [];
            if (typeof value === 'string') {
                const trimmedSeparator = this._picker._config.rangeSeparator.trim();
                if (value.replace(/[^-]/g, '').length > 1) {
                    _input = value.split(this._picker._config.rangeSeparator);
                }
                else {
                    _input = value
                        .split(trimmedSeparator.length > 0 ? trimmedSeparator : this._picker._config.rangeSeparator)
                        .map(_val => _val.trim());
                }
            }
            if (Array.isArray(value)) {
                _input = value;
            }
            this._value = _input
                .map((_val) => {
                if (this._picker._config.useUtc) {
                    return utcAsLocal(parseDate(_val, this._picker._config.rangeInputFormat, this._localeService.currentLocale));
                }
                return parseDate(_val, this._picker._config.rangeInputFormat, this._localeService.currentLocale);
            })
                .map((date) => (isNaN(date.valueOf()) ? void 0 : date));
        }
        this._picker.bsValue = this._value;
    }
    setDisabledState(isDisabled) {
        this._picker.isDisabled = isDisabled;
        if (isDisabled) {
            this._renderer.setAttribute(this._elRef.nativeElement, 'disabled', 'disabled');
            return;
        }
        this._renderer.removeAttribute(this._elRef.nativeElement, 'disabled');
    }
    // eslint-disable-next-line @typescript-eslint/no-explicit-any
    registerOnChange(fn) {
        this._onChange = fn;
    }
    // eslint-disable-next-line @typescript-eslint/no-explicit-any
    registerOnTouched(fn) {
        this._onTouched = fn;
    }
    onBlur() {
        this._onTouched();
    }
    hide() {
        this._picker.hide();
        this._renderer.selectRootElement(this._elRef.nativeElement).blur();
        if (this._picker._config.returnFocusToInput) {
            this._renderer.selectRootElement(this._elRef.nativeElement).focus();
        }
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: BsDaterangepickerInputDirective, deps: [{ token: BsDaterangepickerDirective, host: true }, { token: BsLocaleService }, { token: i0.Renderer2 }, { token: i0.ElementRef }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Directive }); }
    static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "22.0.2", type: BsDaterangepickerInputDirective, isStandalone: true, selector: "input[bsDaterangepicker]", host: { listeners: { "change": "onChange($event)", "keyup.esc": "hide()", "keydown": "onKeydownEvent($event)", "blur": "onBlur()" } }, providers: [
            BS_DATERANGEPICKER_VALUE_ACCESSOR,
            BS_DATERANGEPICKER_VALIDATOR
        ], ngImport: i0 }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: BsDaterangepickerInputDirective, decorators: [{
            type: Directive,
            args: [{
                    selector: `input[bsDaterangepicker]`,
                    host: {
                        '(change)': 'onChange($event)',
                        '(keyup.esc)': 'hide()',
                        '(keydown)': 'onKeydownEvent($event)',
                        '(blur)': 'onBlur()'
                    },
                    providers: [
                        BS_DATERANGEPICKER_VALUE_ACCESSOR,
                        BS_DATERANGEPICKER_VALIDATOR
                    ],
                    standalone: true
                }]
        }], ctorParameters: () => [{ type: BsDaterangepickerDirective, decorators: [{
                    type: Host
                }] }, { type: BsLocaleService }, { type: i0.Renderer2 }, { type: i0.ElementRef }, { type: i0.ChangeDetectorRef }] });

class BsDatepickerModule {
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: BsDatepickerModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
    static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "22.0.2", ngImport: i0, type: BsDatepickerModule, imports: [CommonModule, TooltipModule, TimepickerModule, BsCalendarLayoutComponent,
            BsCurrentDateViewComponent,
            BsCustomDatesViewComponent,
            BsDatepickerDayDecoratorComponent,
            BsDatepickerNavigationViewComponent,
            BsDaysCalendarViewComponent,
            BsMonthCalendarViewComponent,
            BsTimepickerViewComponent,
            BsYearsCalendarViewComponent,
            BsDatepickerContainerComponent,
            BsDatepickerDirective,
            BsDatepickerInlineContainerComponent,
            BsDatepickerInlineDirective,
            BsDatepickerInputDirective,
            BsDaterangepickerContainerComponent,
            BsDaterangepickerDirective,
            BsDaterangepickerInlineContainerComponent,
            BsDaterangepickerInlineDirective,
            BsDaterangepickerInputDirective], exports: [BsDatepickerContainerComponent,
            BsDatepickerDirective,
            BsDatepickerInlineContainerComponent,
            BsDatepickerInlineDirective,
            BsDatepickerInputDirective,
            BsDaterangepickerContainerComponent,
            BsDaterangepickerDirective,
            BsDaterangepickerInlineContainerComponent,
            BsDaterangepickerInlineDirective,
            BsDaterangepickerInputDirective] }); }
    static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: BsDatepickerModule, imports: [CommonModule, TooltipModule, TimepickerModule,
            BsDaysCalendarViewComponent,
            BsDatepickerContainerComponent,
            BsDatepickerInlineContainerComponent,
            BsDaterangepickerContainerComponent,
            BsDaterangepickerInlineContainerComponent] }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: BsDatepickerModule, decorators: [{
            type: NgModule,
            args: [{
                    imports: [CommonModule, TooltipModule, TimepickerModule, BsCalendarLayoutComponent,
                        BsCurrentDateViewComponent,
                        BsCustomDatesViewComponent,
                        BsDatepickerDayDecoratorComponent,
                        BsDatepickerNavigationViewComponent,
                        BsDaysCalendarViewComponent,
                        BsMonthCalendarViewComponent,
                        BsTimepickerViewComponent,
                        BsYearsCalendarViewComponent,
                        BsDatepickerContainerComponent,
                        BsDatepickerDirective,
                        BsDatepickerInlineContainerComponent,
                        BsDatepickerInlineDirective,
                        BsDatepickerInputDirective,
                        BsDaterangepickerContainerComponent,
                        BsDaterangepickerDirective,
                        BsDaterangepickerInlineContainerComponent,
                        BsDaterangepickerInlineDirective,
                        BsDaterangepickerInputDirective],
                    exports: [
                        BsDatepickerContainerComponent,
                        BsDatepickerDirective,
                        BsDatepickerInlineContainerComponent,
                        BsDatepickerInlineDirective,
                        BsDatepickerInputDirective,
                        BsDaterangepickerContainerComponent,
                        BsDaterangepickerDirective,
                        BsDaterangepickerInlineContainerComponent,
                        BsDaterangepickerInlineDirective,
                        BsDaterangepickerInputDirective
                    ]
                }]
        }] });

/**
 * Generated bundle index. Do not edit.
 */

export { BsDatepickerConfig, BsDatepickerContainerComponent, BsDatepickerDirective, BsDatepickerInlineConfig, BsDatepickerInlineContainerComponent, BsDatepickerInlineDirective, BsDatepickerInputDirective, BsDatepickerModule, BsDaterangepickerConfig, BsDaterangepickerContainerComponent, BsDaterangepickerDirective, BsDaterangepickerInlineConfig, BsDaterangepickerInlineContainerComponent, BsDaterangepickerInlineDirective, BsDaterangepickerInputDirective, BsLocaleService };
//# sourceMappingURL=ngx-bootstrap-datepicker.mjs.map