'use strict';

Object.defineProperty(exports, '__esModule', { value: true });

var core = require('@al/core');

/*! *****************************************************************************
Copyright (c) Microsoft Corporation.

Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted.

THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
***************************************************************************** */

function __awaiter(thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
}

/**
 *  Manages a cardstack view state
 */
class AlCardstackView {
    constructor(characteristics) {
        this.characteristics = undefined; //  Characteristics of the view: fields, types, behaviors, etc.
        this.loading = false; //  Indicates whether or not the view is currently loading
        // pagination common values
        this.itemsPerPage = 50; // items per page default value
        // pagination remote values
        this.continuation = undefined; // continuation for remote pagination
        // pagination values
        this.loadedPages = 0; //  Number of pages currently retrieved
        this.remainingPages = 1; //  Number of pages of data remaining (or 1, if unknown); 0 when load is complete/EOS
        this.rawCards = []; //  All cards loaded,is going to be used to make local pagination
        this.filteredCards = [];
        this.cards = []; //  All cards loaded, both visible and invisible, in current sort order
        this.visibleCards = 0; //  Number of cards currently visible in view
        this.textFilter = null; //  Regular expression to filter results with (deprecated?)
        this.groupingBy = null; //  Grouping property
        this.sortingBy = null; //  Sortation property
        this.sortOrder = "asc"; //  Sortation direction, either "asc" or "desc".  Yes, "sortation" is a real word ;-)
        this.dateRange = [];
        this.checked = false;
        //  Defines which filters are currently "active"
        this.activeFilters = [];
        this.autoIndexProperties = [];
        this.autoDefineCardsChanged = false;
        //  Aggregation data
        this.aggregations = {
            properties: {}
        };
        this.reduceFilters = {};
        this.filtersChanged = core.AlStopwatch.later(() => {
            if (this.onFiltersChanged) {
                this.onFiltersChanged();
            }
        });
        if (characteristics) {
            this.normalizeCharacteristics(characteristics);
        }
    }
    /**
     * Starts loading the view and digesting data
     */
    start() {
        return __awaiter(this, void 0, void 0, function* () {
            this.loadedPages = 0;
            this.remainingPages = 0;
            this.continuation = undefined;
            this.loading = true;
            try {
                if (!this.characteristics) {
                    if (!this.generateCharacteristics) {
                        throw new Error("Usage error: AlCardstackView extensions must either be constructed with characteristics or provide a `generateCharacteristics` method.");
                    }
                    const characteristics = yield this.generateCharacteristics();
                    this.normalizeCharacteristics(characteristics);
                    if (this.characteristics.localPagination) {
                        this.fillPropertiesReduceFilters();
                    }
                }
                let entities = yield this.fetchData(true, this.getRemoteFilters());
                this.rawCards = [];
                this.filteredCards = [];
                this.cards = [];
                let ingestedCards = this.ingest(entities);
                this.rawCards = ingestedCards;
                let sortByApplied = false;
                if (this.sortingBy && this.sortOrder && !this.sortingBy.remote) {
                    this.applySortBy(this.sortingBy, this.sortOrder);
                    sortByApplied = true;
                }
                this.filteredCards = this.rawCards;
                if (this.characteristics.localPagination && !sortByApplied) {
                    this.visibleCards = this.filteredCards.length;
                    this.startPagination(this.filteredCards);
                    this.resetPagination(this.filteredCards.length);
                }
                else {
                    this.applyFiltersAndSearch();
                }
                this.loading = false;
                if (this.onCardsChanged) {
                    this.onCardsChanged();
                }
            }
            catch (error) {
                console.error("A fatal error prevented this view from starting!", error);
                this.error = error;
                this.loading = false;
            }
        });
    }
    updateCharacteristics(characteristics) {
        this.normalizeCharacteristics(Object.assign(this.characteristics, characteristics));
        this.filtersChanged.again();
    }
    /** set the first page of the filteredCards */
    startPagination(filteredCards) {
        this.cards = filteredCards.slice(0, Math.min(this.itemsPerPage, filteredCards.length));
        this.resetPagination(filteredCards.length);
    }
    /**
     * Starts loading next batch data into view
     */
    continue() {
        return __awaiter(this, void 0, void 0, function* () {
            this.loading = true;
            try {
                let entities = [];
                let cardsSection;
                if (this.characteristics.localPagination) {
                    cardsSection = this.filteredCards.slice(this.cards.length, this.cards.length + this.itemsPerPage);
                    this.addNextSection(cardsSection);
                    this.loadedPages++;
                    this.remainingPages--;
                }
                else {
                    entities = yield this.fetchData(false, this.getRemoteFilters());
                    cardsSection = this.ingest(entities);
                    // if paging is remote and rest things are inline
                    this.rawCards = [...this.rawCards, ...cardsSection];
                    this.applyFiltersAndSearch();
                }
                if (this.characteristics && this.characteristics.greedyConsumer && this.remainingPages > 0) {
                    //  In greedy consumer mode, we essentially retrieve the entire dataset sequentially as part of the load cycle
                    yield this.continue();
                }
                this.loading = false;
            }
            catch (e) {
                console.error("A fatal error prevented this view from continuing!", e);
                this.loading = false;
                this.error = e;
            }
        });
    }
    /**
     * calculate the remaining pages
     * @param total items
     */
    resetPagination(total) {
        if (this.itemsPerPage) {
            this.loadedPages = 0;
            this.remainingPages = Math.floor(total / this.itemsPerPage);
        }
    }
    getProperty(propertyId) {
        if (typeof (propertyId) === 'object') {
            return propertyId;
        }
        if (this.characteristics && !this.characteristics.definitions.hasOwnProperty(propertyId)) {
            throw new Error(`Internal error: cannot access undefined property '${propertyId}'`);
        }
        if (this.characteristics) {
            return this.characteristics.definitions[propertyId];
        }
        throw new Error(`Internal error: cannot access undefined property '${propertyId}'`);
    }
    getValue(propertyId, value) {
        let propDescriptor = typeof (propertyId) === 'string' ? this.getProperty(propertyId) : propertyId;
        if (!propDescriptor.hasOwnProperty('values') || propDescriptor.values.length === 0) {
            throw new Error(`The property '${propertyId}' does not have a dictionary of discrete values.`);
        }
        let valueDescriptor;
        if (typeof (value) === 'object') {
            valueDescriptor = propDescriptor.values.find(v => v === value);
        }
        else {
            valueDescriptor = propDescriptor.values.find(v => v.value === value || v.valueKey === value);
        }
        if (!valueDescriptor) {
            throw new Error(`The property '${propertyId}' does not have a discrete value '${value.toString()}'`);
        }
        return valueDescriptor;
    }
    applyFiltersAndSearch() {
        this.filteredCards = [...this.rawCards].filter(c => this.evaluateCardState(c));
        this.visibleCards = this.filteredCards.length;
        if (this.characteristics.localPagination) {
            this.startPagination(this.filteredCards);
            this.resetPagination(this.filteredCards.length);
        }
        else {
            this.cards = this.filteredCards;
        }
        this.recalculateFilterTotals();
        this.recalculateFilterActivation();
        if (this.onCardsChanged) {
            this.onCardsChanged();
        }
    }
    /**
     *  Applies a textual search filter to all properties/entities in the current list, or clears the current filter if `filterPattern` is null.
     *  This should cause the `visibleItem` count to be recalculated, possibly triggering a load of further pages of data.
     */
    applyTextFilter(filterPattern) {
        if (this.textFilter !== filterPattern) {
            this.textFilter = filterPattern;
            if (this.characteristics.remoteSearch) {
                this.start();
            }
            else {
                this.applyFiltersAndSearch();
            }
        }
    }
    /**
     *  Applies grouping logic to the current view, or clears grouping if `property` is null.
     */
    applyGroupingBy(descriptor) {
        return true;
    }
    /**
     *  Applies sorting logic to the current view, or restores default if `property` is null.
     *  This is the default implementation, which can be called if the deriving class doesn't implement OR wants to call into the super class.
     */
    applySortBy(pDescriptor, order = "desc") {
        this.sortingBy = pDescriptor;
        this.sortOrder = order.toLowerCase() === 'asc' ? 'asc' : 'desc';
        if (this.sortingBy.remote) {
            this.start();
            return;
        }
        this.rawCards = this.rawCards.sort((a, b) => {
            let pa = a.properties[pDescriptor.property];
            let pb = b.properties[pDescriptor.property];
            if (typeof (pa) === 'string' || typeof (pb) === 'string') {
                pa = pa ? pa : '';
                pb = pb ? pb : '';
                if (order === 'asc') {
                    return pa.localeCompare(pb);
                }
                else {
                    return pb.localeCompare(pa);
                }
            }
            else if (typeof (pa) === 'number' || typeof (pb) === 'number') {
                a = pa ? pa : 0;
                pb = pb ? pb : 0;
                if (order === 'asc') {
                    return pa - pb;
                }
                else {
                    return pb - pa;
                }
            }
            else {
                if (typeof (pa) === 'undefined' && typeof (pb) === 'undefined') {
                    return 0;
                }
                else {
                    throw new Error("Inconsistent property normalization: properties are not string or number, or are mixed.");
                }
            }
        });
        this.applyFiltersAndSearch();
    }
    /**
     *  Applies a filter to the current view, optionally specifying a custom filter callback.
     */
    applyFilterBy(vDescriptor, resetActiveFilters = false, callback) {
        this.updateActiveFilters(vDescriptor, resetActiveFilters, callback);
        const pDescriptor = this.getProperty(vDescriptor.property);
        if (pDescriptor.remote) {
            this.start(); //  restart view
        }
        else {
            this.applyFiltersAndSearch();
        }
        this.filtersChanged.again();
        return false;
    }
    /**
     *  Applies multiple filter to the current view, optionally specifying a custom filter callback.
     */
    applyMultipleFilterBy(vDescriptors, resetActiveFilters = false, callback) {
        vDescriptors.forEach(vDescriptor => {
            this.updateActiveFilters(vDescriptor, resetActiveFilters, callback);
        });
    }
    /**
     *  Removes a filter from the current view.
     */
    removeFilterBy(vDescriptor) {
        let existing = this.activeFilters.find(filter => filter.propField === vDescriptor.property);
        if (!existing) {
            // could not find existing filter
            return false;
        }
        vDescriptor.activeFilter = false;
        const pDescriptor = this.getProperty(vDescriptor.property);
        existing.values = existing.values.filter(value => value !== vDescriptor);
        if (existing.values.length === 0) {
            this.activeFilters = this.activeFilters.filter(filter => filter.property !== pDescriptor);
            pDescriptor.activeFilter = false;
        }
        else {
            existing.rawValues = existing.values.map(vDescr => vDescr.value);
        }
        if (pDescriptor.remote) {
            this.start(); //  restart view
        }
        else {
            this.applyFiltersAndSearch();
        }
        this.filtersChanged.again();
        return false;
    }
    clearFilters() {
        let remoteFilter = false;
        this.activeFilters.forEach(filter => {
            filter.values.forEach(value => {
                value.activeFilter = false;
            });
            filter.property.activeFilter = false;
            remoteFilter = remoteFilter || filter.property.remote;
        });
        this.activeFilters = [];
        if (remoteFilter) {
            this.start();
        }
        else {
            this.applyFiltersAndSearch();
        }
        this.filtersChanged.again();
    }
    markCardsAsCheck() {
        this.cards = this.cards.map(c => {
            c.checked = this.checked;
            return c;
        });
    }
    /**
     * Allows to mark the all cards as checked or unchecked
     * @param checked
     */
    applySelect(checked) {
        this.checked = checked;
        this.markCardsAsCheck();
    }
    /**
     * Sets the active filters based on the specified query parameters.
     * This function is useful when using deep links.
     *
     * @param {Object} params - The query parameters object.
     * @throws {Error} If `characteristics` is not configured, an error will be thrown.
     * @returns {void}
     */
    setDefaultFiltersByParams(params) {
        if (!this.characteristics) {
            throw new Error("characteristics must be configured to activate filters via query parameters.");
        }
        const filterableBy = this.characteristics.filterableBy;
        if (filterableBy.length > 0) {
            for (let i = 0; i < filterableBy.length; i++) {
                const filterProperty = filterableBy[i];
                if (filterProperty in params && params[filterProperty] && filterProperty in this.characteristics.definitions) {
                    const values = params[filterProperty].split(',');
                    const activeFilters = [];
                    values.forEach(value => {
                        const filter = this.characteristics.definitions[filterProperty].values.find(characteristicValue => characteristicValue.value === value);
                        if (filter) {
                            activeFilters.push(filter);
                        }
                    });
                    this.applyMultipleFilterBy(activeFilters);
                }
            }
        }
    }
    /**
     * Protected Internal Methods
     */
    recalculateFilterTotals() {
        let filtersChanged = false;
        this.characteristics.filterableBy.forEach(propName => {
            const pd = this.getProperty(propName);
            if (!pd.remote) { //  no local aggregation for remotely filtered properties, because no!
                pd.values.forEach(vd => {
                    let count = this.filteredCards.reduce((alpha, card) => card.properties[pd.property] === vd.value ? alpha + 1 : alpha, 0);
                    if (count !== vd.count) {
                        filtersChanged = true;
                    }
                    vd.count = count;
                    vd.prefilterCount = this.rawCards.reduce((alpha, card) => card.properties[pd.property] === vd.value ? alpha + 1 : alpha, 0);
                });
            }
        });
        if (filtersChanged) {
            this.filtersChanged.again();
        }
    }
    recalculateFilterActivation() {
        //  Reset activation state of the filterable taxonomy
        this.characteristics.filterableBy.map(filterable => this.getProperty(filterable)).forEach(filterProperty => {
            filterProperty.activeFilter = false;
            filterProperty.values.forEach(vDescr => {
                vDescr.activeFilter = false;
            });
        });
        this.activeFilters.forEach(filter => {
            filter.property.activeFilter = true;
            filter.values.forEach(vDescr => {
                vDescr.activeFilter = true;
            });
        });
    }
    addNextSection(newData) {
        this.cards = [...this.cards, ...newData];
        this.cards.forEach(c => this.evaluateCardState(c));
        this.visibleCards = this.cards.reduce((count, card) => count + (card.visible ? 1 : 0), 0);
        if (this.characteristics.localPagination && this.checked && newData.length > 0) {
            this.markCardsAsCheck();
        }
    }
    ingest(entities) {
        let discoveredValues = false;
        let results = entities.map(entity => {
            const properties = this.deriveEntityProperties(entity);
            if (properties) {
                let derivedProps = Object.keys(properties);
                if (this.characteristics.sortableBy) {
                    let filteredSortProps = this.characteristics.sortableBy.filter(sortProp => {
                        return !derivedProps.includes(sortProp);
                    });
                    if (filteredSortProps.length) {
                        console.warn('Sorting configuration missing for properties ', filteredSortProps, ' in deriveEntityProperties');
                    }
                }
                if (this.characteristics.filterableBy) {
                    let filteredProps = this.characteristics.filterableBy.filter(filterProp => {
                        const isRemoteFilter = this.getProperty(filterProp).remote;
                        return (!isRemoteFilter && !derivedProps.includes(filterProp));
                    });
                    if (filteredProps.length) {
                        console.warn('Filter configuration missing for property ', filteredProps, ' in deriveEntityProperties');
                    }
                }
                if (!this.characteristics.remoteSearch) {
                    if (this.characteristics.searchableBy && this.characteristics.searchableBy.length) {
                        let filteredSearchProps = this.characteristics.searchableBy.filter(search => {
                            return !derivedProps.includes(search);
                        });
                        if (filteredSearchProps.length) {
                            console.warn('Search configuration missing for property ', filteredSearchProps, ' in deriveEntityProperties');
                        }
                    }
                    else {
                        console.warn('Search configuration missing fileds on which search to be performed, please update searchableBy with fields again search to be performed.');
                    }
                }
            }
            this.autoIndexProperties.forEach(index => {
                if (index.property in properties) {
                    let literalValue = properties[index.property];
                    if (!index.values.find(valueDescriptor => valueDescriptor.value === literalValue)) {
                        let vd = {
                            property: index.property,
                            value: literalValue,
                            valueKey: `${index.property}-${index.values.length + 1}`,
                            caption: index.property,
                            captionPlural: index.property
                        };
                        if (this.decoratePropertyValue) {
                            this.decoratePropertyValue(entity, index, vd);
                        }
                        index.values.push(vd);
                        discoveredValues = true;
                    }
                }
            });
            return {
                properties,
                entity,
                id: properties.id,
                caption: properties.caption
            };
        });
        if (discoveredValues) {
            this.filtersChanged.again();
        }
        return results;
    }
    /**
     * This is the default filter evaluator.
     */
    defaultFilterCb(entity, properties, filter, data) {
        if (filter.property.remote) {
            return true; // Filtering will have been performed by server, no further action required here
        }
        let value = filter.property.property in properties ? properties[filter.property.property] : null;
        return filter.values.find(vDescr => vDescr.value === value) ? true : false;
    }
    /**
     *  Method to determine visibility of an individual card item based on the current set of active filters.
     */
    evaluateCardVisibilityByFilter(card) {
        return this.activeFilters.every(filter => filter.callback(card.entity, card.properties, filter));
    }
    /**
     *  Method to determine visibility of an individual card item based on the current search text
     */
    evaluateCardVisibilityBySearch(card, search) {
        if (search === null || search === '') {
            return true;
        }
        // property search
        // prop=value
        if (typeof search === "string" && search.includes("=")) {
            const lsSource = search.split("=");
            const property = lsSource[0];
            const value = lsSource[1].toLowerCase();
            if (property === '' || value === '') {
                return false;
            }
            if (!card.properties.hasOwnProperty(property)) {
                return false;
            }
            const cardPropValue = card.properties[property].toLowerCase();
            return value.includes(cardPropValue);
        }
        if (!this.characteristics || !this.characteristics.searchableBy) {
            return false;
        }
        if (this.characteristics.searchableBy.length === 0) {
            return true;
        }
        return this.characteristics.searchableBy.some((property) => {
            if (!card.properties.hasOwnProperty(property) || !card.properties[property]) {
                return false;
            }
            let cardPropValue = card.properties[property];
            if (!Array.isArray(cardPropValue)) {
                // force everything to be an array, simplify the logic
                cardPropValue = [cardPropValue];
            }
            return cardPropValue.some((value) => {
                if (typeof value !== 'string') {
                    console.error('cardPropValue must be a string');
                    return false;
                }
                if (search instanceof RegExp) {
                    // regex can control its own case sensitivity
                    return search.test(value);
                }
                if (typeof search === "string") {
                    // everything is a string, toLowerCase for case insensitivity search, US116156
                    return value.toLowerCase().includes(search.toLowerCase());
                }
                console.error("Search should be a string or regex:", search);
                return false;
            });
        });
    }
    evaluateCardState(card) {
        // card.visible = this.evaluateCardVisibilityBySearch(card, this.textFilter) && this.evaluateCardVisibilityByFilter(card);
        if (this.characteristics.remoteSearch) { // if its remote search we dont need inline searching facility
            card.visible = this.evaluateCardVisibilityByFilter(card);
        }
        else {
            card.visible = this.evaluateCardVisibilityBySearch(card, this.textFilter) && this.evaluateCardVisibilityByFilter(card);
        }
        return card.visible;
    }
    /**
     *  Utility method to normalize and validate an input characteristics definitions, and then store it
     *  to the instance's `characteristics` property.
     */
    normalizeCharacteristics(characteristics) {
        try {
            characteristics.groupableBy = characteristics.groupableBy || [];
            characteristics.sortableBy = characteristics.sortableBy || [];
            characteristics.filterableBy = characteristics.filterableBy || [];
            characteristics.definitions = characteristics.definitions || {};
            characteristics.filterValueLimit = characteristics.filterValueLimit || 10;
            characteristics.filterValueIncrement = characteristics.filterValueIncrement || 10;
            characteristics.hideEmptyFilterValues = characteristics.hideEmptyFilterValues || false;
            characteristics.localPagination = characteristics.localPagination || false;
            this.characteristics = characteristics;
            this.autoIndexProperties = [];
            let activeFilters = {};
            const properties = [
                ...characteristics.sortableBy,
                ...characteristics.filterableBy,
                ...characteristics.groupableBy
            ];
            properties.forEach(descriptor => {
                const propDescriptor = this.resolveDescriptor(descriptor);
                if (!propDescriptor.values) {
                    propDescriptor.values = [];
                }
                if (propDescriptor.autoIndex) {
                    this.autoIndexProperties.push(propDescriptor);
                }
                propDescriptor.values.forEach(valDescriptor => {
                    valDescriptor.property = propDescriptor.property;
                    if (!valDescriptor.hasOwnProperty("valueKey")) {
                        valDescriptor.valueKey = `${propDescriptor.property}-${valDescriptor.value.toString()}`;
                    }
                    if (valDescriptor.default) {
                        activeFilters[valDescriptor.valueKey] = valDescriptor;
                    }
                });
            });
        }
        catch (e) {
            throw new core.AlError(`Failed to normalize characteristics object`, e);
        }
    }
    resolveDescriptor(descriptor) {
        if (typeof (descriptor) === 'string') {
            if (this.characteristics && this.characteristics.definitions.hasOwnProperty(descriptor)) {
                return this.characteristics.definitions[descriptor];
            }
            else {
                throw new Error(`sort property descriptor '${descriptor}' not found in definitions dictionary.`);
            }
        }
        else {
            if (this.characteristics && this.characteristics.definitions.hasOwnProperty(descriptor.property)) {
                throw new Error(`there are multiple descriptors for the property '${descriptor.property}'; these should be consolidated into the definitions dictionary.`);
            }
            if (this.characteristics) {
                this.characteristics.definitions[descriptor.property] = descriptor;
            }
        }
        return descriptor;
    }
    getRemoteFilters() {
        return this.activeFilters.filter(filter => filter.property.remote);
    }
    /**
     * Updates the list of active filters based on the provided value descriptor.
     *
     * @param {AlCardstackValueDescriptor} vDescriptor - The value descriptor to apply as a filter.
     * @param {boolean} [resetActiveFilters=false] - If true, clears all filters in the same category as the one being applied, leaving only the new filter active.
     * @param {function} [callback] - An optional callback function to be called when the filter is applied.
     * @returns {void}
     */
    updateActiveFilters(vDescriptor, resetActiveFilters = false, callback) {
        const pDescriptor = this.getProperty(vDescriptor.property);
        const existing = this.activeFilters.find(filter => filter.property === pDescriptor);
        if (existing) {
            if (existing.values.includes(vDescriptor)) {
                return; //  no change
            }
            if (resetActiveFilters) {
                existing.values = [];
                pDescriptor.values.forEach(value => {
                    if (vDescriptor.value !== value.value) {
                        value.activeFilter = false;
                    }
                });
            }
            existing.values.push(vDescriptor);
            existing.rawValues = existing.values.map(vDescr => vDescr.value);
        }
        else {
            this.activeFilters.push({
                property: pDescriptor,
                propField: pDescriptor.property,
                values: [vDescriptor],
                rawValues: [vDescriptor.value],
                callback: callback || this.defaultFilterCb
            });
        }
        pDescriptor.activeFilter = true;
        vDescriptor.activeFilter = true;
    }
    /**
     * Fill the property name of the variable reduceFilter with filterable fields
     */
    fillPropertiesReduceFilters() {
        this.characteristics.filterableBy.forEach((filter) => {
            if (typeof filter === 'string' && !this.characteristics.definitions[filter].avoidReduce) {
                this.reduceFilters[filter] = [];
            }
        });
    }
}

exports.AlCardstackView = AlCardstackView;
//# sourceMappingURL=al-core-cardstack.es5.js.map
