import { InjectionToken, Injectable, Optional, Inject, Pipe, APP_INITIALIZER, LOCALE_ID, NgModule } from '@angular/core';
import { __awaiter } from 'tslib';
import { Storage } from '@bravobit/bb-foundation/storage';
import { Languages } from '@bravobit/bb-foundation';
import { HttpClient, HttpClientModule } from '@angular/common/http';

/**
 * @fileoverview added by tsickle
 * Generated from: lib/interfaces/config.interfaces.ts
 * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
 */
//
// The configuration that can be passed when
// the user initializes the localize module.
//
class LocalizeConfig {
    constructor() {
        this.dictionary = [];
    }
}
if (false) {
    /** @type {?} */
    LocalizeConfig.prototype.dictionary;
    /** @type {?} */
    LocalizeConfig.prototype.substitutions;
}

/**
 * @fileoverview added by tsickle
 * Generated from: lib/interfaces/options.interfaces.ts
 * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
 */
//
// These are the options that the user has
// when localizing the token.
//
/**
 * @record
 */
function LocalizeOptions() { }
if (false) {
    /** @type {?|undefined} */
    LocalizeOptions.prototype.optional;
    /** @type {?|undefined} */
    LocalizeOptions.prototype.data;
}
/**
 * @record
 */
function LocalizeOptionsData() { }
/**
 * @record
 */
function LocalizeParams() { }
if (false) {
    /** @type {?} */
    LocalizeParams.prototype.token;
}

/**
 * @fileoverview added by tsickle
 * Generated from: lib/interfaces/functions.interfaces.ts
 * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
 */
/**
 * @record
 */
function LocalizeFunction() { }
if (false) {
    /**
     * @return {?}
     */
    LocalizeFunction.prototype.keyword = function () { };
    /**
     * @param {?} value
     * @return {?}
     */
    LocalizeFunction.prototype.transform = function (value) { };
}
/**
 * @record
 */
function LocalizeFunctionMap() { }
//
// This is the injection token that will be injected
// into the service so that the all localize functions
// can retrieved and used.
//
/** @type {?} */
const LOCALIZE_FUNCTION = new InjectionToken('localize_function');

/**
 * @fileoverview added by tsickle
 * Generated from: lib/interfaces/handlers.interfaces.ts
 * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
 */
/**
 * @record
 */
function LocalizeHandlerProtocol() { }
if (false) {
    /**
     * @param {?} params
     * @param {?} localize
     * @return {?}
     */
    LocalizeHandlerProtocol.prototype.handle = function (params, localize) { };
}

/**
 * @fileoverview added by tsickle
 * Generated from: lib/interfaces/dictionary.interfaces.ts
 * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
 */
/**
 * @record
 */
function LocalizeDictionaryParams() { }
if (false) {
    /** @type {?} */
    LocalizeDictionaryParams.prototype.id;
    /** @type {?|undefined} */
    LocalizeDictionaryParams.prototype.data;
    /** @type {?|undefined} */
    LocalizeDictionaryParams.prototype.locale;
    /** @type {?|undefined} */
    LocalizeDictionaryParams.prototype.supportedLanguages;
}
//
// This is the injection token that will be injected
// into the service so that the all extra dictionaries
// can retrieved and used.
//
/** @type {?} */
const LOCALIZE_EXTRA_DICTIONARY = new InjectionToken('localize_extra_dictionary');

/**
 * @fileoverview added by tsickle
 * Generated from: lib/functions/lowercase.function.ts
 * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
 */
//
// This function transform the value
// to a lowercase variant of the value.
//
class LocalizeLowercaseFunction {
    /**
     * @return {?}
     */
    keyword() {
        return 'lowercase';
    }
    /**
     * @param {?} value
     * @return {?}
     */
    transform(value) {
        return (value || '').toLowerCase();
    }
}

/**
 * @fileoverview added by tsickle
 * Generated from: lib/functions/uppercase.function.ts
 * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
 */
//
// This function transform the value
// to a uppercase variant of the value.
//
class LocalizeUppercaseFunction {
    /**
     * @return {?}
     */
    keyword() {
        return 'uppercase';
    }
    /**
     * @param {?} value
     * @return {?}
     */
    transform(value) {
        return (value || '').toUpperCase();
    }
}

/**
 * @fileoverview added by tsickle
 * Generated from: lib/localizations/english.localization.ts
 * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
 */
const ɵ0 = {
    locale: 'en-US',
    data: {
        'form-control-errors': {
            'unknown': 'The field has an unknown error.',
            'required': 'This field is required.',
            'pattern': 'Invalid format.',
            'email': 'The field does not match a valid email address.',
            'emailTaken': 'The e-mail is already taken.',
            'passwordMatch': 'The passwords don\'t match.',
            'fullNumber': 'The field should be a full number.',
            'min': 'Minimum amount should be {{min}}.',
            'max': 'Maximum amount should be {{max}}.',
            'maxFileSize': 'The file has exceed the maximum amount of {{maxSize}}.',
            'minlength': 'Expected a minimum of {{requiredLength}} characters but got {{actualLength}} characters.',
            'maxlength': 'Expected a maximum of {{requiredLength}} characters but got {{actualLength}} characters.'
        },
        'tables': {
            'search': 'Search...',
            'loading': 'Loading...',
            'empty': 'There is nothing to find here.',
            'page': 'page',
            'error_not_found': 'A not found error occurred while fetching data from the server.',
            'error_server': 'A server error occurred while fetching data from the server.',
            'error_unknown': 'A unknown error occurred while fetching data from the server.'
        },
        'file-picker': {
            'choose': 'Choose file',
            'remove': 'Remove file',
            'drop': 'or drag and drop file here'
        }
    }
};
/** @type {?} */
const LOCALIZATION_EXTRA_ENGLISH = {
    provide: LOCALIZE_EXTRA_DICTIONARY,
    useValue: ɵ0,
    multi: true
};

/**
 * @fileoverview added by tsickle
 * Generated from: lib/localizations/dutch.localization.ts
 * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
 */
const ɵ0$1 = {
    locale: 'nl-NL',
    data: {
        'form-control-errors': {
            'unknown': 'Het veld heeft een onbekende fout.',
            'required': 'Dit veld is verplicht.',
            'pattern': 'Ongeldig formaat.',
            'email': 'Het veld komt niet overeen met een geldig e-mailadres.',
            'emailTaken': 'Het e-mailadres is al bezet.',
            'passwordMatch': 'De wachtwoorden komen niet overeen.',
            'fullNumber': 'Het veld moet een volledig getal zijn.',
            'min': 'Minimum hoeveelheid moet {{min}} zijn.',
            'max': 'Maximum hoeveelheid moet {{max}} zijn.',
            'maxFileSize': 'Het bestand heeft de maximum hoeveelheid van {{maxSize}} overschreden.',
            'minlength': 'Verwachtte minimaal {{requiredLength}} tekens, maar kreeg {{actualLength}} tekens.',
            'maxlength': 'Verwachtte maximaal {{requiredLength}} tekens, maar kreeg {{actualLength}} tekens.'
        },
        'tables': {
            'search': 'Zoeken...',
            'loading': 'Aan het laden...',
            'empty': 'Er is hier niets te vinden.',
            'page': 'pagina',
            'error_not_found': 'Er is een niet-gevonden fout opgetreden tijdens het ophalen van gegevens van de server.',
            'error_server': 'Er is een serverfout opgetreden bij het ophalen van gegevens van de server.',
            'error_unknown': 'Er is een onbekende fout opgetreden bij het ophalen van gegevens van de server.',
        },
        'file-picker': {
            'choose': 'Kies bestand',
            'remove': 'Verwijder bestand',
            'drop': 'of sleep het bestand hiernaartoe'
        }
    }
};
/** @type {?} */
const LOCALIZATION_EXTRA_DUTCH = {
    provide: LOCALIZE_EXTRA_DICTIONARY,
    useValue: ɵ0$1,
    multi: true
};

/**
 * @fileoverview added by tsickle
 * Generated from: lib/handlers/missing.handler.ts
 * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
 */
class LocalizeMissingHandler {
    constructor() {
        this.log = (/**
         * @param {?} message
         * @return {?}
         */
        (message) => {
            console && console.warn && console.warn(message);
        });
    }
    /**
     * @param {?} params
     * @param {?} localize
     * @return {?}
     */
    handle(params, localize) {
        // Log to the console when the token was not found
        // if the user did not mark it as optional.
        if (!params.optional) {
            this.log(`Localize: The token with name: "${params.token}" was not found.`);
        }
        // Return the default token back.
        return params.token;
    }
}
if (false) {
    /**
     * @type {?}
     * @private
     */
    LocalizeMissingHandler.prototype.log;
}

/**
 * @fileoverview added by tsickle
 * Generated from: lib/localize.dictionary.ts
 * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
 */
class LocalizeDictionary {
    /**
     * @param {?} __0
     * @param {?} http
     */
    constructor({ id, data, locale, supportedLanguages }, http) {
        // Dictionary data.
        this._data = {};
        this._url = null;
        this.recursiveSearchValue = (/**
         * @param {?} data
         * @param {?} value
         * @return {?}
         */
        (data, value) => {
            if (typeof data === 'undefined' || typeof data === 'string') {
                return undefined;
            }
            return data[value];
        });
        this._id = id;
        this._locale = locale || 'en-US';
        this._supportedLanguages = supportedLanguages || [];
        this._http = http;
        // Set the correct variable to the url or data.
        if (typeof data === 'string') {
            this._url = data;
        }
        else {
            this._data = data;
        }
    }
    /**
     * @return {?}
     */
    get id() {
        return this._id;
    }
    /**
     * @return {?}
     */
    get locale() {
        return this._locale;
    }
    /**
     * @return {?}
     */
    get supportedLanguages() {
        return this._supportedLanguages;
    }
    /**
     * @return {?}
     */
    load() {
        return __awaiter(this, void 0, void 0, function* () {
            // If the url was not set the data was already loaded
            // return true because it was successful.
            if (!this._url) {
                return true;
            }
            try {
                // Try to load the data via a HTTP request.
                /** @type {?} */
                const result = yield this._http.get(this._url, { headers: { 'X-No-Authorization': 'yes' } })
                    .toPromise();
                // Set the data.
                this._data = result || {};
                this._url = null;
                // Return true because it succeeded.
                return true;
            }
            catch (_a) {
                // Return false because it failed.
                return false;
            }
        });
    }
    /**
     * @param {?} extraDictionary
     * @param {?=} mode
     * @return {?}
     */
    combine(extraDictionary, mode = 'prepend') {
        // Validate that the locale matches.
        if (extraDictionary.locale !== this._locale) {
            return;
        }
        // Extract the extra data.
        /** @type {?} */
        const extraData = extraDictionary.data || {};
        // If the selected mode is prepend
        // add the data in front.
        if (mode === 'prepend') {
            this._data = Object.assign({}, extraData, this._data);
            return;
        }
        // If the selected mode is append
        // add the data in the back.
        this._data = Object.assign({}, this._data, extraData);
    }
    /**
     * @param {?} token
     * @return {?}
     */
    search(token) {
        // Check if the token is present in the
        // data, if so return it.
        if (this._data[token]) {
            return this._data[token];
        }
        // Values might be nested in objects this means we need
        // to split them on the dot and search them recursively
        // in the data.
        /** @type {?} */
        const value = (token || '')
            .split('.')
            .filter((/**
         * @param {?} value
         * @return {?}
         */
        value => !!value))
            .reduce(this.recursiveSearchValue, this._data);
        // Check if the value is a string
        // if this is true it can be returned.
        if (typeof value === 'string') {
            return value;
        }
        // This means the translation was incorrect.
        return null;
    }
}
if (false) {
    /**
     * @type {?}
     * @private
     */
    LocalizeDictionary.prototype._id;
    /**
     * @type {?}
     * @private
     */
    LocalizeDictionary.prototype._locale;
    /**
     * @type {?}
     * @private
     */
    LocalizeDictionary.prototype._supportedLanguages;
    /**
     * @type {?}
     * @private
     */
    LocalizeDictionary.prototype._http;
    /**
     * @type {?}
     * @private
     */
    LocalizeDictionary.prototype._data;
    /**
     * @type {?}
     * @private
     */
    LocalizeDictionary.prototype._url;
    /**
     * @type {?}
     * @private
     */
    LocalizeDictionary.prototype.recursiveSearchValue;
}

/**
 * @fileoverview added by tsickle
 * Generated from: lib/localize.service.ts
 * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
 */
class Localize {
    /**
     * @param {?} _http
     * @param {?} _storage
     * @param {?} _languages
     * @param {?} _config
     * @param {?} _missingHandler
     * @param {?} _functions
     * @param {?} _extras
     */
    constructor(_http, _storage, _languages, _config, _missingHandler, _functions, _extras) {
        this._http = _http;
        this._storage = _storage;
        this._languages = _languages;
        this._config = _config;
        this._missingHandler = _missingHandler;
        this._functions = _functions;
        this._extras = _extras;
        this._storageToken = 'bb-language-dictionary-id';
        this.convertToParams = (/**
         * @param {?} tokenOrParams
         * @return {?}
         */
        (tokenOrParams) => {
            if (typeof tokenOrParams !== 'string') {
                // Destruct the params from the object.
                const { token, optional, data } = tokenOrParams;
                // Make sure all parameters are valid
                // by type safe adding them.
                return { token: token, optional: optional || false, data: data || {} };
            }
            // If the parameter is a string fill in the blanks.
            return { token: tokenOrParams, optional: false, data: {} };
        });
        this.getMatches = (/**
         * @param {?} value
         * @param {?} substitutions
         * @return {?}
         */
        (value, substitutions) => {
            // Get the matching substitutions.
            const { start, end } = substitutions;
            // Compose a regex that will find the matches.
            /** @type {?} */
            const regex = new RegExp(`${start}([^${end}]+)${end}`, 'g');
            // Execute the regex to find matches.
            /** @type {?} */
            let match = regex.exec(value);
            /** @type {?} */
            const matches = [];
            while (match !== null) {
                // Push a new match.
                matches.push({
                    match: match[0],
                    token: match[1]
                });
                // Try to find more matches.
                match = regex.exec(value);
            }
            // Return the processed value.
            return matches.filter((/**
             * @param {?} item
             * @return {?}
             */
            item => !!item));
        });
        this.reload = (/**
         * @return {?}
         */
        () => {
            window && window.location && window.location.reload && window.location.reload();
        });
        // Check if at least one language was passed in the config.
        if (this._config.dictionary.length < 1) {
            throw new Error('Localize: one or more languages should be supplied.');
        }
        // Gather the dictionaries.
        this._dictionaries = this._config.dictionary.map((/**
         * @param {?} item
         * @return {?}
         */
        item => new LocalizeDictionary(item, this._http)));
        // Save the best matching current dictionary.
        this._currentDictionary = this.retrieveBestMatchingDictionary();
        // Gather all the localize functions.
        this._functionMiddleware = this._functions.reduce((/**
         * @param {?} previous
         * @param {?} current
         * @return {?}
         */
        (previous, current) => {
            previous[current.keyword()] = current;
            return previous;
        }), {});
    }
    /**
     * @return {?}
     */
    get dictionaries() {
        return this._dictionaries;
    }
    /**
     * @return {?}
     */
    get current() {
        return this._currentDictionary;
    }
    /**
     * @return {?}
     */
    get locale() {
        return this._currentDictionary.locale;
    }
    /**
     * @return {?}
     */
    initialize() {
        return (/**
         * @return {?}
         */
        () => __awaiter(this, void 0, void 0, function* () { return this.load(this._currentDictionary); }));
    }
    /**
     * @param {?} id
     * @param {?=} reload
     * @return {?}
     */
    change(id, reload = true) {
        // Try to fetch the dictionary.
        /** @type {?} */
        const dictionary = this._dictionaries.find((/**
         * @param {?} item
         * @return {?}
         */
        item => item.id === id));
        // Validate the dictionary exists.
        if (!dictionary) {
            throw new Error(`Localize: Could not find dictionary with id: "${id}"`);
        }
        // Save the language in the storage.
        this._storage.set(this._storageToken, dictionary.id);
        // Just quit if we don't need to reload.
        if (!reload) {
            return;
        }
        // We need to reload the application for the translations.
        return this.reload();
    }
    /**
     * @param {?=} reload
     * @return {?}
     */
    clear(reload = true) {
        // Remove the language in the local storage.
        this._storage.remove(this._storageToken);
        // Just quit if we don't need to reload.
        if (!reload) {
            return;
        }
        // We need to reload the application for the translations.
        return this.reload();
    }
    /**
     * @param {?} tokenOrParams
     * @return {?}
     */
    translate(tokenOrParams) {
        // 1. Convert to the params.
        /** @type {?} */
        const params = this.convertToParams(tokenOrParams);
        // 2. Try to find the translation in the dictionary.
        /** @type {?} */
        const searchResult = this._currentDictionary.search(params.token);
        // 3. Verify the translation was found.
        if (!searchResult) {
            return this._missingHandler.handle(params, this);
        }
        // 4. Find references in the translation that need to be translated as well.
        /** @type {?} */
        const processResult = this.findReferencesInTranslation(searchResult);
        // 5. Parse the interpolation data.
        return this.parseInterpolationData(processResult, params.data);
    }
    /**
     * @private
     * @param {?} value
     * @param {?} data
     * @return {?}
     */
    parseInterpolationData(value, data) {
        // Get the interpolation substitutions.
        /** @type {?} */
        const substitutions = this.getSubstitutions('interpolation', ['{{', '}}']);
        // Get all matches in the value.
        /** @type {?} */
        const matches = this.getMatches(value, substitutions);
        // Replace all matches with the parsed value.
        return matches.reduce((/**
         * @param {?} previous
         * @param {?} current
         * @return {?}
         */
        (previous, current) => {
            // Try to parse the token.
            /** @type {?} */
            const interpolatedToken = this.interpolateFunctionData(current.token, data);
            // Replace the match with the parsed token.
            return previous.replace(current.match, interpolatedToken);
        }), `${value}`);
    }
    /**
     * @private
     * @param {?} value
     * @param {?} interpolationData
     * @return {?}
     */
    interpolateFunctionData(value, interpolationData) {
        // Get the token and the methods by splitting
        // on the pipe symbol.
        const [token, ...methods] = value.split('|').map((/**
         * @param {?} item
         * @return {?}
         */
        item => item.trim()));
        // Get the value for the token from
        // the interpolation data.
        /** @type {?} */
        const interpolationValue = interpolationData[token] || token;
        // Loop through all the middleware methods and try to
        // conform the string to the given parameters.
        return methods.reduce((/**
         * @param {?} string
         * @param {?} middlewareName
         * @return {?}
         */
        (string, middlewareName) => {
            // Try to retrieve the middleware from the collection.
            /** @type {?} */
            const middleware = this._functionMiddleware[middlewareName];
            // If the middleware is missing return an error
            // so that the user knows it was not found.
            if (!middleware) {
                return string;
            }
            // Execute the middleware function with the string.
            return middleware.transform(string);
        }), `${interpolationValue}`);
    }
    /**
     * @private
     * @param {?} value
     * @return {?}
     */
    findReferencesInTranslation(value) {
        // Get the reference substitutions.
        /** @type {?} */
        const substitutions = this.getSubstitutions('references', ['#(', ')']);
        // Get all matches in the value.
        /** @type {?} */
        const matches = this.getMatches(value, substitutions);
        // Replace all matches with the translated value.
        return matches.reduce((/**
         * @param {?} previous
         * @param {?} current
         * @return {?}
         */
        (previous, current) => {
            // Try to translate the token.
            /** @type {?} */
            const translatedToken = this.translate(current.token);
            // Replace the match with the translated token.
            return previous.replace(current.match, translatedToken);
        }), value);
    }
    /**
     * @private
     * @param {?} type
     * @param {?} defaultValue
     * @return {?}
     */
    getSubstitutions(type, defaultValue) {
        /** @type {?} */
        const substitutions = (this._config
            && this._config.substitutions
            && this._config.substitutions[type]);
        // Get the substitutions.
        /** @type {?} */
        const value = (!substitutions || substitutions.length !== 2)
            ? defaultValue
            : substitutions;
        // Escape both substitutions so that they
        // can be used.
        /** @type {?} */
        const escape = /[.*+?^${}()|[\]\\]/g;
        /** @type {?} */
        const start = value[0].replace(escape, '\\$&');
        /** @type {?} */
        const end = value[1].replace(escape, '\\$&');
        // Return the substitutions.
        return { start, end };
    }
    /**
     * @private
     * @return {?}
     */
    retrieveBestMatchingDictionary() {
        // Get the dictionary based on storage.
        /** @type {?} */
        const storageDictionary = this.getDictionaryFromStorage();
        // Get the dictionary based on the supported language.
        /** @type {?} */
        const browserDictionary = this.getBestBrowserMatchDictionary();
        // Get the dictionary based on the first index.
        /** @type {?} */
        const firstDictionary = this._dictionaries[0];
        // Return the best matching dictionary.
        return storageDictionary || browserDictionary || firstDictionary;
    }
    /**
     * @private
     * @return {?}
     */
    getDictionaryFromStorage() {
        // Get dictionary id from the storage..
        /** @type {?} */
        const dictionaryId = this._storage.get(this._storageToken);
        // Return the dictionary based on the storage dictionary id.
        return this._dictionaries.find((/**
         * @param {?} item
         * @return {?}
         */
        item => item.id === dictionaryId));
    }
    /**
     * @private
     * @return {?}
     */
    getBestBrowserMatchDictionary() {
        // Loop through all browser languages and return the
        // best matching dictionary.
        return this._languages.all.map((/**
         * @param {?} __0
         * @return {?}
         */
        ({ code, region }) => {
            /** @type {?} */
            const languageCode = [code, region].filter((/**
             * @param {?} data
             * @return {?}
             */
            data => !!data)).join('-');
            return this._dictionaries.find((/**
             * @param {?} item
             * @return {?}
             */
            item => item.supportedLanguages.includes(languageCode)));
        })).filter((/**
         * @param {?} item
         * @return {?}
         */
        item => !!item)).find((/**
         * @param {?} _
         * @param {?} index
         * @return {?}
         */
        (_, index) => index === 0));
    }
    /**
     * @private
     * @param {?} dictionary
     * @return {?}
     */
    load(dictionary) {
        return __awaiter(this, void 0, void 0, function* () {
            // Try to load the dictionary data.
            /** @type {?} */
            const loaded = yield dictionary.load();
            // Verify the data was loaded.
            if (!loaded) {
                throw new Error(`Localize: Could not correctly fetch the data from: "${dictionary.id}"`);
            }
            // Combine the extra dictionary data.
            (this._extras || []).forEach((/**
             * @param {?} extraDictionary
             * @return {?}
             */
            extraDictionary => dictionary.combine(extraDictionary)));
            // Return the dictionary.
            return dictionary;
        });
    }
}
Localize.decorators = [
    { type: Injectable }
];
/** @nocollapse */
Localize.ctorParameters = () => [
    { type: HttpClient },
    { type: Storage },
    { type: Languages },
    { type: LocalizeConfig, decorators: [{ type: Optional }] },
    { type: LocalizeMissingHandler },
    { type: Array, decorators: [{ type: Optional }, { type: Inject, args: [LOCALIZE_FUNCTION,] }] },
    { type: Array, decorators: [{ type: Optional }, { type: Inject, args: [LOCALIZE_EXTRA_DICTIONARY,] }] }
];
if (false) {
    /**
     * @type {?}
     * @private
     */
    Localize.prototype._dictionaries;
    /**
     * @type {?}
     * @private
     */
    Localize.prototype._currentDictionary;
    /**
     * @type {?}
     * @private
     */
    Localize.prototype._functionMiddleware;
    /**
     * @type {?}
     * @private
     */
    Localize.prototype._storageToken;
    /**
     * @type {?}
     * @private
     */
    Localize.prototype.convertToParams;
    /**
     * @type {?}
     * @private
     */
    Localize.prototype.getMatches;
    /**
     * @type {?}
     * @private
     */
    Localize.prototype.reload;
    /**
     * @type {?}
     * @private
     */
    Localize.prototype._http;
    /**
     * @type {?}
     * @private
     */
    Localize.prototype._storage;
    /**
     * @type {?}
     * @private
     */
    Localize.prototype._languages;
    /**
     * @type {?}
     * @private
     */
    Localize.prototype._config;
    /**
     * @type {?}
     * @private
     */
    Localize.prototype._missingHandler;
    /**
     * @type {?}
     * @private
     */
    Localize.prototype._functions;
    /**
     * @type {?}
     * @private
     */
    Localize.prototype._extras;
}

/**
 * @fileoverview added by tsickle
 * Generated from: lib/localize.pipe.ts
 * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
 */
class BbLocalize {
    /**
     * @param {?} _localize
     */
    constructor(_localize) {
        this._localize = _localize;
    }
    /**
     * @param {?} tokenOrParams
     * @param {?=} args
     * @return {?}
     */
    transform(tokenOrParams, args) {
        // Validate that the localize service
        // exists in the pipe.
        if (!this._localize) {
            return tokenOrParams;
        }
        // Combine the params with the options
        // to form the localize params.
        /** @type {?} */
        const params = this.combineParamsWithOptions(tokenOrParams, args);
        // Try to localize the value.
        return this._localize.translate(params);
    }
    /**
     * @private
     * @param {?} tokenOrParams
     * @param {?=} args
     * @return {?}
     */
    combineParamsWithOptions(tokenOrParams, args) {
        // Gather the extras.
        /** @type {?} */
        const extras = args || {};
        // Loop through all the keys to find the set options.
        /** @type {?} */
        const options = Object.keys(extras).reduce((/**
         * @param {?} previous
         * @param {?} current
         * @return {?}
         */
        (previous, current) => {
            if (typeof extras[current] === 'undefined') {
                return previous;
            }
            previous[current] = extras[current];
            return previous;
        }), {});
        // Convert the string token to a params object.
        /** @type {?} */
        const params = typeof tokenOrParams === 'string'
            ? { token: tokenOrParams, optional: false, data: {} }
            : tokenOrParams;
        // Return the combined params and options.
        return Object.assign({}, params, options);
    }
}
BbLocalize.decorators = [
    { type: Pipe, args: [{
                name: 'bbLocalize'
            },] }
];
/** @nocollapse */
BbLocalize.ctorParameters = () => [
    { type: Localize, decorators: [{ type: Optional }] }
];
if (false) {
    /**
     * @type {?}
     * @private
     */
    BbLocalize.prototype._localize;
}

/**
 * @fileoverview added by tsickle
 * Generated from: lib/localize.module.ts
 * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
 */
class LocalizeModule {
    /**
     * @param {?} config
     * @return {?}
     */
    static forRoot(config) {
        return {
            ngModule: LocalizeModule,
            providers: [
                // Angular providers.
                { provide: APP_INITIALIZER, deps: [Localize], useFactory: initializeLocale, multi: true },
                { provide: LOCALE_ID, deps: [Localize], useFactory: getLocale },
                // Config provider.
                { provide: LocalizeConfig, useValue: config },
                // Function providers.
                { provide: LOCALIZE_FUNCTION, useClass: LocalizeLowercaseFunction, multi: true },
                { provide: LOCALIZE_FUNCTION, useClass: LocalizeUppercaseFunction, multi: true },
                // Handler providers.
                { provide: LocalizeMissingHandler, useClass: LocalizeMissingHandler },
                // Service providers.
                Localize
            ]
        };
    }
}
LocalizeModule.decorators = [
    { type: NgModule, args: [{
                imports: [HttpClientModule],
                declarations: [BbLocalize],
                exports: [BbLocalize]
            },] }
];
/**
 * @param {?} localize
 * @return {?}
 */
function initializeLocale(localize) {
    return localize.initialize();
}
/**
 * @param {?} localize
 * @return {?}
 */
function getLocale(localize) {
    return localize.locale;
}

/**
 * @fileoverview added by tsickle
 * Generated from: public_api.ts
 * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
 */

/**
 * @fileoverview added by tsickle
 * Generated from: bravobit-bb-foundation-localize.ts
 * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
 */

export { BbLocalize, LOCALIZATION_EXTRA_DUTCH, LOCALIZATION_EXTRA_ENGLISH, LOCALIZE_EXTRA_DICTIONARY, LOCALIZE_FUNCTION, Localize, LocalizeConfig, LocalizeLowercaseFunction, LocalizeMissingHandler, LocalizeModule, LocalizeUppercaseFunction, getLocale, initializeLocale };
//# sourceMappingURL=bravobit-bb-foundation-localize.js.map
